mux.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753
  1. /*
  2. * linux/arch/arm/mach-omap2/mux.c
  3. *
  4. * OMAP2 and OMAP3 pin multiplexing configurations
  5. *
  6. * Copyright (C) 2004 - 2008 Texas Instruments Inc.
  7. * Copyright (C) 2003 - 2008 Nokia Corporation
  8. *
  9. * Written by Tony Lindgren
  10. *
  11. * This program is free software; you can redistribute it and/or modify
  12. * it under the terms of the GNU General Public License as published by
  13. * the Free Software Foundation; either version 2 of the License, or
  14. * (at your option) any later version.
  15. *
  16. * This program is distributed in the hope that it will be useful,
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  19. * GNU General Public License for more details.
  20. *
  21. * You should have received a copy of the GNU General Public License
  22. * along with this program; if not, write to the Free Software
  23. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  24. *
  25. */
  26. #include <linux/module.h>
  27. #include <linux/init.h>
  28. #include <linux/io.h>
  29. #include <linux/slab.h>
  30. #include <linux/spinlock.h>
  31. #include <linux/list.h>
  32. #include <linux/ctype.h>
  33. #include <linux/debugfs.h>
  34. #include <linux/seq_file.h>
  35. #include <linux/uaccess.h>
  36. #include <asm/system.h>
  37. #include <plat/control.h>
  38. #include "mux.h"
  39. #define OMAP_MUX_BASE_OFFSET 0x30 /* Offset from CTRL_BASE */
  40. #define OMAP_MUX_BASE_SZ 0x5ca
  41. #define MUXABLE_GPIO_MODE3 BIT(0)
  42. struct omap_mux_entry {
  43. struct omap_mux mux;
  44. struct list_head node;
  45. };
  46. static unsigned long mux_phys;
  47. static void __iomem *mux_base;
  48. static u8 omap_mux_flags;
  49. u16 omap_mux_read(u16 reg)
  50. {
  51. if (cpu_is_omap24xx())
  52. return __raw_readb(mux_base + reg);
  53. else
  54. return __raw_readw(mux_base + reg);
  55. }
  56. void omap_mux_write(u16 val, u16 reg)
  57. {
  58. if (cpu_is_omap24xx())
  59. __raw_writeb(val, mux_base + reg);
  60. else
  61. __raw_writew(val, mux_base + reg);
  62. }
  63. void omap_mux_write_array(struct omap_board_mux *board_mux)
  64. {
  65. while (board_mux->reg_offset != OMAP_MUX_TERMINATOR) {
  66. omap_mux_write(board_mux->value, board_mux->reg_offset);
  67. board_mux++;
  68. }
  69. }
  70. static LIST_HEAD(muxmodes);
  71. static DEFINE_MUTEX(muxmode_mutex);
  72. #ifdef CONFIG_OMAP_MUX
  73. static char *omap_mux_options;
  74. int __init omap_mux_init_gpio(int gpio, int val)
  75. {
  76. struct omap_mux_entry *e;
  77. int found = 0;
  78. if (!gpio)
  79. return -EINVAL;
  80. list_for_each_entry(e, &muxmodes, node) {
  81. struct omap_mux *m = &e->mux;
  82. if (gpio == m->gpio) {
  83. u16 old_mode;
  84. u16 mux_mode;
  85. old_mode = omap_mux_read(m->reg_offset);
  86. mux_mode = val & ~(OMAP_MUX_NR_MODES - 1);
  87. if (omap_mux_flags & MUXABLE_GPIO_MODE3)
  88. mux_mode |= OMAP_MUX_MODE3;
  89. else
  90. mux_mode |= OMAP_MUX_MODE4;
  91. printk(KERN_DEBUG "mux: Setting signal "
  92. "%s.gpio%i 0x%04x -> 0x%04x\n",
  93. m->muxnames[0], gpio, old_mode, mux_mode);
  94. omap_mux_write(mux_mode, m->reg_offset);
  95. found++;
  96. }
  97. }
  98. if (found == 1)
  99. return 0;
  100. if (found > 1) {
  101. printk(KERN_ERR "mux: Multiple gpio paths for gpio%i\n", gpio);
  102. return -EINVAL;
  103. }
  104. printk(KERN_ERR "mux: Could not set gpio%i\n", gpio);
  105. return -ENODEV;
  106. }
  107. int __init omap_mux_init_signal(char *muxname, int val)
  108. {
  109. struct omap_mux_entry *e;
  110. char *m0_name = NULL, *mode_name = NULL;
  111. int found = 0;
  112. mode_name = strchr(muxname, '.');
  113. if (mode_name) {
  114. *mode_name = '\0';
  115. mode_name++;
  116. m0_name = muxname;
  117. } else {
  118. mode_name = muxname;
  119. }
  120. list_for_each_entry(e, &muxmodes, node) {
  121. struct omap_mux *m = &e->mux;
  122. char *m0_entry = m->muxnames[0];
  123. int i;
  124. if (m0_name && strcmp(m0_name, m0_entry))
  125. continue;
  126. for (i = 0; i < OMAP_MUX_NR_MODES; i++) {
  127. char *mode_cur = m->muxnames[i];
  128. if (!mode_cur)
  129. continue;
  130. if (!strcmp(mode_name, mode_cur)) {
  131. u16 old_mode;
  132. u16 mux_mode;
  133. old_mode = omap_mux_read(m->reg_offset);
  134. mux_mode = val | i;
  135. printk(KERN_DEBUG "mux: Setting signal "
  136. "%s.%s 0x%04x -> 0x%04x\n",
  137. m0_entry, muxname, old_mode, mux_mode);
  138. omap_mux_write(mux_mode, m->reg_offset);
  139. found++;
  140. }
  141. }
  142. }
  143. if (found == 1)
  144. return 0;
  145. if (found > 1) {
  146. printk(KERN_ERR "mux: Multiple signal paths (%i) for %s\n",
  147. found, muxname);
  148. return -EINVAL;
  149. }
  150. printk(KERN_ERR "mux: Could not set signal %s\n", muxname);
  151. return -ENODEV;
  152. }
  153. #ifdef CONFIG_DEBUG_FS
  154. #define OMAP_MUX_MAX_NR_FLAGS 10
  155. #define OMAP_MUX_TEST_FLAG(val, mask) \
  156. if (((val) & (mask)) == (mask)) { \
  157. i++; \
  158. flags[i] = #mask; \
  159. }
  160. /* REVISIT: Add checking for non-optimal mux settings */
  161. static inline void omap_mux_decode(struct seq_file *s, u16 val)
  162. {
  163. char *flags[OMAP_MUX_MAX_NR_FLAGS];
  164. char mode[sizeof("OMAP_MUX_MODE") + 1];
  165. int i = -1;
  166. sprintf(mode, "OMAP_MUX_MODE%d", val & 0x7);
  167. i++;
  168. flags[i] = mode;
  169. OMAP_MUX_TEST_FLAG(val, OMAP_PIN_OFF_WAKEUPENABLE);
  170. if (val & OMAP_OFF_EN) {
  171. if (!(val & OMAP_OFFOUT_EN)) {
  172. if (!(val & OMAP_OFF_PULL_UP)) {
  173. OMAP_MUX_TEST_FLAG(val,
  174. OMAP_PIN_OFF_INPUT_PULLDOWN);
  175. } else {
  176. OMAP_MUX_TEST_FLAG(val,
  177. OMAP_PIN_OFF_INPUT_PULLUP);
  178. }
  179. } else {
  180. if (!(val & OMAP_OFFOUT_VAL)) {
  181. OMAP_MUX_TEST_FLAG(val,
  182. OMAP_PIN_OFF_OUTPUT_LOW);
  183. } else {
  184. OMAP_MUX_TEST_FLAG(val,
  185. OMAP_PIN_OFF_OUTPUT_HIGH);
  186. }
  187. }
  188. }
  189. if (val & OMAP_INPUT_EN) {
  190. if (val & OMAP_PULL_ENA) {
  191. if (!(val & OMAP_PULL_UP)) {
  192. OMAP_MUX_TEST_FLAG(val,
  193. OMAP_PIN_INPUT_PULLDOWN);
  194. } else {
  195. OMAP_MUX_TEST_FLAG(val, OMAP_PIN_INPUT_PULLUP);
  196. }
  197. } else {
  198. OMAP_MUX_TEST_FLAG(val, OMAP_PIN_INPUT);
  199. }
  200. } else {
  201. i++;
  202. flags[i] = "OMAP_PIN_OUTPUT";
  203. }
  204. do {
  205. seq_printf(s, "%s", flags[i]);
  206. if (i > 0)
  207. seq_printf(s, " | ");
  208. } while (i-- > 0);
  209. }
  210. #define OMAP_MUX_DEFNAME_LEN 16
  211. static int omap_mux_dbg_board_show(struct seq_file *s, void *unused)
  212. {
  213. struct omap_mux_entry *e;
  214. list_for_each_entry(e, &muxmodes, node) {
  215. struct omap_mux *m = &e->mux;
  216. char m0_def[OMAP_MUX_DEFNAME_LEN];
  217. char *m0_name = m->muxnames[0];
  218. u16 val;
  219. int i, mode;
  220. if (!m0_name)
  221. continue;
  222. /* REVISIT: Needs to be updated if mode0 names get longer */
  223. for (i = 0; i < OMAP_MUX_DEFNAME_LEN; i++) {
  224. if (m0_name[i] == '\0') {
  225. m0_def[i] = m0_name[i];
  226. break;
  227. }
  228. m0_def[i] = toupper(m0_name[i]);
  229. }
  230. val = omap_mux_read(m->reg_offset);
  231. mode = val & OMAP_MUX_MODE7;
  232. seq_printf(s, "OMAP%i_MUX(%s, ",
  233. cpu_is_omap34xx() ? 3 : 0, m0_def);
  234. omap_mux_decode(s, val);
  235. seq_printf(s, "),\n");
  236. }
  237. return 0;
  238. }
  239. static int omap_mux_dbg_board_open(struct inode *inode, struct file *file)
  240. {
  241. return single_open(file, omap_mux_dbg_board_show, &inode->i_private);
  242. }
  243. static const struct file_operations omap_mux_dbg_board_fops = {
  244. .open = omap_mux_dbg_board_open,
  245. .read = seq_read,
  246. .llseek = seq_lseek,
  247. .release = single_release,
  248. };
  249. static int omap_mux_dbg_signal_show(struct seq_file *s, void *unused)
  250. {
  251. struct omap_mux *m = s->private;
  252. const char *none = "NA";
  253. u16 val;
  254. int mode;
  255. val = omap_mux_read(m->reg_offset);
  256. mode = val & OMAP_MUX_MODE7;
  257. seq_printf(s, "name: %s.%s (0x%08lx/0x%03x = 0x%04x), b %s, t %s\n",
  258. m->muxnames[0], m->muxnames[mode],
  259. mux_phys + m->reg_offset, m->reg_offset, val,
  260. m->balls[0] ? m->balls[0] : none,
  261. m->balls[1] ? m->balls[1] : none);
  262. seq_printf(s, "mode: ");
  263. omap_mux_decode(s, val);
  264. seq_printf(s, "\n");
  265. seq_printf(s, "signals: %s | %s | %s | %s | %s | %s | %s | %s\n",
  266. m->muxnames[0] ? m->muxnames[0] : none,
  267. m->muxnames[1] ? m->muxnames[1] : none,
  268. m->muxnames[2] ? m->muxnames[2] : none,
  269. m->muxnames[3] ? m->muxnames[3] : none,
  270. m->muxnames[4] ? m->muxnames[4] : none,
  271. m->muxnames[5] ? m->muxnames[5] : none,
  272. m->muxnames[6] ? m->muxnames[6] : none,
  273. m->muxnames[7] ? m->muxnames[7] : none);
  274. return 0;
  275. }
  276. #define OMAP_MUX_MAX_ARG_CHAR 7
  277. static ssize_t omap_mux_dbg_signal_write(struct file *file,
  278. const char __user *user_buf,
  279. size_t count, loff_t *ppos)
  280. {
  281. char buf[OMAP_MUX_MAX_ARG_CHAR];
  282. struct seq_file *seqf;
  283. struct omap_mux *m;
  284. unsigned long val;
  285. int buf_size, ret;
  286. if (count > OMAP_MUX_MAX_ARG_CHAR)
  287. return -EINVAL;
  288. memset(buf, 0, sizeof(buf));
  289. buf_size = min(count, sizeof(buf) - 1);
  290. if (copy_from_user(buf, user_buf, buf_size))
  291. return -EFAULT;
  292. ret = strict_strtoul(buf, 0x10, &val);
  293. if (ret < 0)
  294. return ret;
  295. if (val > 0xffff)
  296. return -EINVAL;
  297. seqf = file->private_data;
  298. m = seqf->private;
  299. omap_mux_write((u16)val, m->reg_offset);
  300. *ppos += count;
  301. return count;
  302. }
  303. static int omap_mux_dbg_signal_open(struct inode *inode, struct file *file)
  304. {
  305. return single_open(file, omap_mux_dbg_signal_show, inode->i_private);
  306. }
  307. static const struct file_operations omap_mux_dbg_signal_fops = {
  308. .open = omap_mux_dbg_signal_open,
  309. .read = seq_read,
  310. .write = omap_mux_dbg_signal_write,
  311. .llseek = seq_lseek,
  312. .release = single_release,
  313. };
  314. static struct dentry *mux_dbg_dir;
  315. static void __init omap_mux_dbg_init(void)
  316. {
  317. struct omap_mux_entry *e;
  318. mux_dbg_dir = debugfs_create_dir("omap_mux", NULL);
  319. if (!mux_dbg_dir)
  320. return;
  321. (void)debugfs_create_file("board", S_IRUGO, mux_dbg_dir,
  322. NULL, &omap_mux_dbg_board_fops);
  323. list_for_each_entry(e, &muxmodes, node) {
  324. struct omap_mux *m = &e->mux;
  325. (void)debugfs_create_file(m->muxnames[0], S_IWUGO, mux_dbg_dir,
  326. m, &omap_mux_dbg_signal_fops);
  327. }
  328. }
  329. #else
  330. static inline void omap_mux_dbg_init(void)
  331. {
  332. }
  333. #endif /* CONFIG_DEBUG_FS */
  334. static void __init omap_mux_free_names(struct omap_mux *m)
  335. {
  336. int i;
  337. for (i = 0; i < OMAP_MUX_NR_MODES; i++)
  338. kfree(m->muxnames[i]);
  339. #ifdef CONFIG_DEBUG_FS
  340. for (i = 0; i < OMAP_MUX_NR_SIDES; i++)
  341. kfree(m->balls[i]);
  342. #endif
  343. }
  344. /* Free all data except for GPIO pins unless CONFIG_DEBUG_FS is set */
  345. static int __init omap_mux_late_init(void)
  346. {
  347. struct omap_mux_entry *e, *tmp;
  348. list_for_each_entry_safe(e, tmp, &muxmodes, node) {
  349. struct omap_mux *m = &e->mux;
  350. u16 mode = omap_mux_read(m->reg_offset);
  351. if (OMAP_MODE_GPIO(mode))
  352. continue;
  353. #ifndef CONFIG_DEBUG_FS
  354. mutex_lock(&muxmode_mutex);
  355. list_del(&e->node);
  356. mutex_unlock(&muxmode_mutex);
  357. omap_mux_free_names(m);
  358. kfree(m);
  359. #endif
  360. }
  361. omap_mux_dbg_init();
  362. return 0;
  363. }
  364. late_initcall(omap_mux_late_init);
  365. static void __init omap_mux_package_fixup(struct omap_mux *p,
  366. struct omap_mux *superset)
  367. {
  368. while (p->reg_offset != OMAP_MUX_TERMINATOR) {
  369. struct omap_mux *s = superset;
  370. int found = 0;
  371. while (s->reg_offset != OMAP_MUX_TERMINATOR) {
  372. if (s->reg_offset == p->reg_offset) {
  373. *s = *p;
  374. found++;
  375. break;
  376. }
  377. s++;
  378. }
  379. if (!found)
  380. printk(KERN_ERR "mux: Unknown entry offset 0x%x\n",
  381. p->reg_offset);
  382. p++;
  383. }
  384. }
  385. #ifdef CONFIG_DEBUG_FS
  386. static void __init omap_mux_package_init_balls(struct omap_ball *b,
  387. struct omap_mux *superset)
  388. {
  389. while (b->reg_offset != OMAP_MUX_TERMINATOR) {
  390. struct omap_mux *s = superset;
  391. int found = 0;
  392. while (s->reg_offset != OMAP_MUX_TERMINATOR) {
  393. if (s->reg_offset == b->reg_offset) {
  394. s->balls[0] = b->balls[0];
  395. s->balls[1] = b->balls[1];
  396. found++;
  397. break;
  398. }
  399. s++;
  400. }
  401. if (!found)
  402. printk(KERN_ERR "mux: Unknown ball offset 0x%x\n",
  403. b->reg_offset);
  404. b++;
  405. }
  406. }
  407. #else /* CONFIG_DEBUG_FS */
  408. static inline void omap_mux_package_init_balls(struct omap_ball *b,
  409. struct omap_mux *superset)
  410. {
  411. }
  412. #endif /* CONFIG_DEBUG_FS */
  413. static int __init omap_mux_setup(char *options)
  414. {
  415. if (!options)
  416. return 0;
  417. omap_mux_options = options;
  418. return 1;
  419. }
  420. __setup("omap_mux=", omap_mux_setup);
  421. /*
  422. * Note that the omap_mux=some.signal1=0x1234,some.signal2=0x1234
  423. * cmdline options only override the bootloader values.
  424. * During development, please enable CONFIG_DEBUG_FS, and use the
  425. * signal specific entries under debugfs.
  426. */
  427. static void __init omap_mux_set_cmdline_signals(void)
  428. {
  429. char *options, *next_opt, *token;
  430. if (!omap_mux_options)
  431. return;
  432. options = kmalloc(strlen(omap_mux_options) + 1, GFP_KERNEL);
  433. if (!options)
  434. return;
  435. strcpy(options, omap_mux_options);
  436. next_opt = options;
  437. while ((token = strsep(&next_opt, ",")) != NULL) {
  438. char *keyval, *name;
  439. unsigned long val;
  440. keyval = token;
  441. name = strsep(&keyval, "=");
  442. if (name) {
  443. int res;
  444. res = strict_strtoul(keyval, 0x10, &val);
  445. if (res < 0)
  446. continue;
  447. omap_mux_init_signal(name, (u16)val);
  448. }
  449. }
  450. kfree(options);
  451. }
  452. static int __init omap_mux_copy_names(struct omap_mux *src,
  453. struct omap_mux *dst)
  454. {
  455. int i;
  456. for (i = 0; i < OMAP_MUX_NR_MODES; i++) {
  457. if (src->muxnames[i]) {
  458. dst->muxnames[i] =
  459. kmalloc(strlen(src->muxnames[i]) + 1,
  460. GFP_KERNEL);
  461. if (!dst->muxnames[i])
  462. goto free;
  463. strcpy(dst->muxnames[i], src->muxnames[i]);
  464. }
  465. }
  466. #ifdef CONFIG_DEBUG_FS
  467. for (i = 0; i < OMAP_MUX_NR_SIDES; i++) {
  468. if (src->balls[i]) {
  469. dst->balls[i] =
  470. kmalloc(strlen(src->balls[i]) + 1,
  471. GFP_KERNEL);
  472. if (!dst->balls[i])
  473. goto free;
  474. strcpy(dst->balls[i], src->balls[i]);
  475. }
  476. }
  477. #endif
  478. return 0;
  479. free:
  480. omap_mux_free_names(dst);
  481. return -ENOMEM;
  482. }
  483. #endif /* CONFIG_OMAP_MUX */
  484. static u16 omap_mux_get_by_gpio(int gpio)
  485. {
  486. struct omap_mux_entry *e;
  487. u16 offset = OMAP_MUX_TERMINATOR;
  488. list_for_each_entry(e, &muxmodes, node) {
  489. struct omap_mux *m = &e->mux;
  490. if (m->gpio == gpio) {
  491. offset = m->reg_offset;
  492. break;
  493. }
  494. }
  495. return offset;
  496. }
  497. /* Needed for dynamic muxing of GPIO pins for off-idle */
  498. u16 omap_mux_get_gpio(int gpio)
  499. {
  500. u16 offset;
  501. offset = omap_mux_get_by_gpio(gpio);
  502. if (offset == OMAP_MUX_TERMINATOR) {
  503. printk(KERN_ERR "mux: Could not get gpio%i\n", gpio);
  504. return offset;
  505. }
  506. return omap_mux_read(offset);
  507. }
  508. /* Needed for dynamic muxing of GPIO pins for off-idle */
  509. void omap_mux_set_gpio(u16 val, int gpio)
  510. {
  511. u16 offset;
  512. offset = omap_mux_get_by_gpio(gpio);
  513. if (offset == OMAP_MUX_TERMINATOR) {
  514. printk(KERN_ERR "mux: Could not set gpio%i\n", gpio);
  515. return;
  516. }
  517. omap_mux_write(val, offset);
  518. }
  519. static struct omap_mux * __init omap_mux_list_add(struct omap_mux *src)
  520. {
  521. struct omap_mux_entry *entry;
  522. struct omap_mux *m;
  523. entry = kzalloc(sizeof(struct omap_mux_entry), GFP_KERNEL);
  524. if (!entry)
  525. return NULL;
  526. m = &entry->mux;
  527. memcpy(m, src, sizeof(struct omap_mux_entry));
  528. #ifdef CONFIG_OMAP_MUX
  529. if (omap_mux_copy_names(src, m)) {
  530. kfree(entry);
  531. return NULL;
  532. }
  533. #endif
  534. mutex_lock(&muxmode_mutex);
  535. list_add_tail(&entry->node, &muxmodes);
  536. mutex_unlock(&muxmode_mutex);
  537. return m;
  538. }
  539. /*
  540. * Note if CONFIG_OMAP_MUX is not selected, we will only initialize
  541. * the GPIO to mux offset mapping that is needed for dynamic muxing
  542. * of GPIO pins for off-idle.
  543. */
  544. static void __init omap_mux_init_list(struct omap_mux *superset)
  545. {
  546. while (superset->reg_offset != OMAP_MUX_TERMINATOR) {
  547. struct omap_mux *entry;
  548. #ifdef CONFIG_OMAP_MUX
  549. if (!superset->muxnames || !superset->muxnames[0]) {
  550. superset++;
  551. continue;
  552. }
  553. #else
  554. /* Skip pins that are not muxed as GPIO by bootloader */
  555. if (!OMAP_MODE_GPIO(omap_mux_read(superset->reg_offset))) {
  556. superset++;
  557. continue;
  558. }
  559. #endif
  560. entry = omap_mux_list_add(superset);
  561. if (!entry) {
  562. printk(KERN_ERR "mux: Could not add entry\n");
  563. return;
  564. }
  565. superset++;
  566. }
  567. }
  568. #ifdef CONFIG_OMAP_MUX
  569. static void omap_mux_init_package(struct omap_mux *superset,
  570. struct omap_mux *package_subset,
  571. struct omap_ball *package_balls)
  572. {
  573. if (package_subset)
  574. omap_mux_package_fixup(package_subset, superset);
  575. if (package_balls)
  576. omap_mux_package_init_balls(package_balls, superset);
  577. }
  578. static void omap_mux_init_signals(struct omap_board_mux *board_mux)
  579. {
  580. omap_mux_set_cmdline_signals();
  581. omap_mux_write_array(board_mux);
  582. }
  583. #else
  584. static void omap_mux_init_package(struct omap_mux *superset,
  585. struct omap_mux *package_subset,
  586. struct omap_ball *package_balls)
  587. {
  588. }
  589. static void omap_mux_init_signals(struct omap_board_mux *board_mux)
  590. {
  591. }
  592. #endif
  593. int __init omap_mux_init(u32 mux_pbase, u32 mux_size,
  594. struct omap_mux *superset,
  595. struct omap_mux *package_subset,
  596. struct omap_board_mux *board_mux,
  597. struct omap_ball *package_balls)
  598. {
  599. if (mux_base)
  600. return -EBUSY;
  601. mux_phys = mux_pbase;
  602. mux_base = ioremap(mux_pbase, mux_size);
  603. if (!mux_base) {
  604. printk(KERN_ERR "mux: Could not ioremap\n");
  605. return -ENODEV;
  606. }
  607. if (cpu_is_omap24xx())
  608. omap_mux_flags = MUXABLE_GPIO_MODE3;
  609. omap_mux_init_package(superset, package_subset, package_balls);
  610. omap_mux_init_list(superset);
  611. omap_mux_init_signals(board_mux);
  612. return 0;
  613. }