mux.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883
  1. /*
  2. * linux/arch/arm/mach-omap2/mux.c
  3. *
  4. * OMAP2, OMAP3 and OMAP4 pin multiplexing configurations
  5. *
  6. * Copyright (C) 2004 - 2010 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/kernel.h>
  27. #include <linux/init.h>
  28. #include <linux/io.h>
  29. #include <linux/list.h>
  30. #include <linux/slab.h>
  31. #include <linux/ctype.h>
  32. #include <linux/debugfs.h>
  33. #include <linux/seq_file.h>
  34. #include <linux/uaccess.h>
  35. #include <asm/system.h>
  36. #include "control.h"
  37. #include "mux.h"
  38. #define OMAP_MUX_BASE_OFFSET 0x30 /* Offset from CTRL_BASE */
  39. #define OMAP_MUX_BASE_SZ 0x5ca
  40. struct omap_mux_entry {
  41. struct omap_mux mux;
  42. struct list_head node;
  43. };
  44. static LIST_HEAD(mux_partitions);
  45. static DEFINE_MUTEX(muxmode_mutex);
  46. struct omap_mux_partition *omap_mux_get(const char *name)
  47. {
  48. struct omap_mux_partition *partition;
  49. list_for_each_entry(partition, &mux_partitions, node) {
  50. if (!strcmp(name, partition->name))
  51. return partition;
  52. }
  53. return NULL;
  54. }
  55. u16 omap_mux_read(struct omap_mux_partition *partition, u16 reg)
  56. {
  57. if (partition->flags & OMAP_MUX_REG_8BIT)
  58. return __raw_readb(partition->base + reg);
  59. else
  60. return __raw_readw(partition->base + reg);
  61. }
  62. void omap_mux_write(struct omap_mux_partition *partition, u16 val,
  63. u16 reg)
  64. {
  65. if (partition->flags & OMAP_MUX_REG_8BIT)
  66. __raw_writeb(val, partition->base + reg);
  67. else
  68. __raw_writew(val, partition->base + reg);
  69. }
  70. void omap_mux_write_array(struct omap_mux_partition *partition,
  71. struct omap_board_mux *board_mux)
  72. {
  73. while (board_mux->reg_offset != OMAP_MUX_TERMINATOR) {
  74. omap_mux_write(partition, board_mux->value,
  75. board_mux->reg_offset);
  76. board_mux++;
  77. }
  78. }
  79. #ifdef CONFIG_OMAP_MUX
  80. static char *omap_mux_options;
  81. static int __init _omap_mux_init_gpio(struct omap_mux_partition *partition,
  82. int gpio, int val)
  83. {
  84. struct omap_mux_entry *e;
  85. struct omap_mux *gpio_mux = NULL;
  86. u16 old_mode;
  87. u16 mux_mode;
  88. int found = 0;
  89. struct list_head *muxmodes = &partition->muxmodes;
  90. if (!gpio)
  91. return -EINVAL;
  92. list_for_each_entry(e, muxmodes, node) {
  93. struct omap_mux *m = &e->mux;
  94. if (gpio == m->gpio) {
  95. gpio_mux = m;
  96. found++;
  97. }
  98. }
  99. if (found == 0) {
  100. pr_err("%s: Could not set gpio%i\n", __func__, gpio);
  101. return -ENODEV;
  102. }
  103. if (found > 1) {
  104. pr_info("%s: Multiple gpio paths (%d) for gpio%i\n", __func__,
  105. found, gpio);
  106. return -EINVAL;
  107. }
  108. old_mode = omap_mux_read(partition, gpio_mux->reg_offset);
  109. mux_mode = val & ~(OMAP_MUX_NR_MODES - 1);
  110. if (partition->flags & OMAP_MUX_GPIO_IN_MODE3)
  111. mux_mode |= OMAP_MUX_MODE3;
  112. else
  113. mux_mode |= OMAP_MUX_MODE4;
  114. pr_debug("%s: Setting signal %s.gpio%i 0x%04x -> 0x%04x\n", __func__,
  115. gpio_mux->muxnames[0], gpio, old_mode, mux_mode);
  116. omap_mux_write(partition, mux_mode, gpio_mux->reg_offset);
  117. return 0;
  118. }
  119. int __init omap_mux_init_gpio(int gpio, int val)
  120. {
  121. struct omap_mux_partition *partition;
  122. int ret;
  123. list_for_each_entry(partition, &mux_partitions, node) {
  124. ret = _omap_mux_init_gpio(partition, gpio, val);
  125. if (!ret)
  126. return ret;
  127. }
  128. return -ENODEV;
  129. }
  130. static int __init _omap_mux_init_signal(struct omap_mux_partition *partition,
  131. const char *muxname, int val)
  132. {
  133. struct omap_mux_entry *e;
  134. const char *mode_name;
  135. int found = 0, mode0_len = 0;
  136. struct list_head *muxmodes = &partition->muxmodes;
  137. mode_name = strchr(muxname, '.');
  138. if (mode_name) {
  139. mode0_len = strlen(muxname) - strlen(mode_name);
  140. mode_name++;
  141. } else {
  142. mode_name = muxname;
  143. }
  144. list_for_each_entry(e, muxmodes, node) {
  145. struct omap_mux *m = &e->mux;
  146. char *m0_entry = m->muxnames[0];
  147. int i;
  148. /* First check for full name in mode0.muxmode format */
  149. if (mode0_len && strncmp(muxname, m0_entry, mode0_len))
  150. continue;
  151. /* Then check for muxmode only */
  152. for (i = 0; i < OMAP_MUX_NR_MODES; i++) {
  153. char *mode_cur = m->muxnames[i];
  154. if (!mode_cur)
  155. continue;
  156. if (!strcmp(mode_name, mode_cur)) {
  157. u16 old_mode;
  158. u16 mux_mode;
  159. old_mode = omap_mux_read(partition,
  160. m->reg_offset);
  161. mux_mode = val | i;
  162. pr_debug("%s: Setting signal "
  163. "%s.%s 0x%04x -> 0x%04x\n", __func__,
  164. m0_entry, muxname, old_mode, mux_mode);
  165. omap_mux_write(partition, mux_mode,
  166. m->reg_offset);
  167. found++;
  168. }
  169. }
  170. }
  171. if (found == 1)
  172. return 0;
  173. if (found > 1) {
  174. pr_err("%s: Multiple signal paths (%i) for %s\n", __func__,
  175. found, muxname);
  176. return -EINVAL;
  177. }
  178. pr_err("%s: Could not set signal %s\n", __func__, muxname);
  179. return -ENODEV;
  180. }
  181. int __init omap_mux_init_signal(const char *muxname, int val)
  182. {
  183. struct omap_mux_partition *partition;
  184. int ret;
  185. list_for_each_entry(partition, &mux_partitions, node) {
  186. ret = _omap_mux_init_signal(partition, muxname, val);
  187. if (!ret)
  188. return ret;
  189. }
  190. return -ENODEV;
  191. }
  192. #ifdef CONFIG_DEBUG_FS
  193. #define OMAP_MUX_MAX_NR_FLAGS 10
  194. #define OMAP_MUX_TEST_FLAG(val, mask) \
  195. if (((val) & (mask)) == (mask)) { \
  196. i++; \
  197. flags[i] = #mask; \
  198. }
  199. /* REVISIT: Add checking for non-optimal mux settings */
  200. static inline void omap_mux_decode(struct seq_file *s, u16 val)
  201. {
  202. char *flags[OMAP_MUX_MAX_NR_FLAGS];
  203. char mode[sizeof("OMAP_MUX_MODE") + 1];
  204. int i = -1;
  205. sprintf(mode, "OMAP_MUX_MODE%d", val & 0x7);
  206. i++;
  207. flags[i] = mode;
  208. OMAP_MUX_TEST_FLAG(val, OMAP_PIN_OFF_WAKEUPENABLE);
  209. if (val & OMAP_OFF_EN) {
  210. if (!(val & OMAP_OFFOUT_EN)) {
  211. if (!(val & OMAP_OFF_PULL_UP)) {
  212. OMAP_MUX_TEST_FLAG(val,
  213. OMAP_PIN_OFF_INPUT_PULLDOWN);
  214. } else {
  215. OMAP_MUX_TEST_FLAG(val,
  216. OMAP_PIN_OFF_INPUT_PULLUP);
  217. }
  218. } else {
  219. if (!(val & OMAP_OFFOUT_VAL)) {
  220. OMAP_MUX_TEST_FLAG(val,
  221. OMAP_PIN_OFF_OUTPUT_LOW);
  222. } else {
  223. OMAP_MUX_TEST_FLAG(val,
  224. OMAP_PIN_OFF_OUTPUT_HIGH);
  225. }
  226. }
  227. }
  228. if (val & OMAP_INPUT_EN) {
  229. if (val & OMAP_PULL_ENA) {
  230. if (!(val & OMAP_PULL_UP)) {
  231. OMAP_MUX_TEST_FLAG(val,
  232. OMAP_PIN_INPUT_PULLDOWN);
  233. } else {
  234. OMAP_MUX_TEST_FLAG(val, OMAP_PIN_INPUT_PULLUP);
  235. }
  236. } else {
  237. OMAP_MUX_TEST_FLAG(val, OMAP_PIN_INPUT);
  238. }
  239. } else {
  240. i++;
  241. flags[i] = "OMAP_PIN_OUTPUT";
  242. }
  243. do {
  244. seq_printf(s, "%s", flags[i]);
  245. if (i > 0)
  246. seq_printf(s, " | ");
  247. } while (i-- > 0);
  248. }
  249. #define OMAP_MUX_DEFNAME_LEN 32
  250. static int omap_mux_dbg_board_show(struct seq_file *s, void *unused)
  251. {
  252. struct omap_mux_partition *partition = s->private;
  253. struct omap_mux_entry *e;
  254. u8 omap_gen = omap_rev() >> 28;
  255. list_for_each_entry(e, &partition->muxmodes, node) {
  256. struct omap_mux *m = &e->mux;
  257. char m0_def[OMAP_MUX_DEFNAME_LEN];
  258. char *m0_name = m->muxnames[0];
  259. u16 val;
  260. int i, mode;
  261. if (!m0_name)
  262. continue;
  263. /* REVISIT: Needs to be updated if mode0 names get longer */
  264. for (i = 0; i < OMAP_MUX_DEFNAME_LEN; i++) {
  265. if (m0_name[i] == '\0') {
  266. m0_def[i] = m0_name[i];
  267. break;
  268. }
  269. m0_def[i] = toupper(m0_name[i]);
  270. }
  271. val = omap_mux_read(partition, m->reg_offset);
  272. mode = val & OMAP_MUX_MODE7;
  273. if (mode != 0)
  274. seq_printf(s, "/* %s */\n", m->muxnames[mode]);
  275. /*
  276. * XXX: Might be revisited to support differences accross
  277. * same OMAP generation.
  278. */
  279. seq_printf(s, "OMAP%d_MUX(%s, ", omap_gen, m0_def);
  280. omap_mux_decode(s, val);
  281. seq_printf(s, "),\n");
  282. }
  283. return 0;
  284. }
  285. static int omap_mux_dbg_board_open(struct inode *inode, struct file *file)
  286. {
  287. return single_open(file, omap_mux_dbg_board_show, inode->i_private);
  288. }
  289. static const struct file_operations omap_mux_dbg_board_fops = {
  290. .open = omap_mux_dbg_board_open,
  291. .read = seq_read,
  292. .llseek = seq_lseek,
  293. .release = single_release,
  294. };
  295. static struct omap_mux_partition *omap_mux_get_partition(struct omap_mux *mux)
  296. {
  297. struct omap_mux_partition *partition;
  298. list_for_each_entry(partition, &mux_partitions, node) {
  299. struct list_head *muxmodes = &partition->muxmodes;
  300. struct omap_mux_entry *e;
  301. list_for_each_entry(e, muxmodes, node) {
  302. struct omap_mux *m = &e->mux;
  303. if (m == mux)
  304. return partition;
  305. }
  306. }
  307. return NULL;
  308. }
  309. static int omap_mux_dbg_signal_show(struct seq_file *s, void *unused)
  310. {
  311. struct omap_mux *m = s->private;
  312. struct omap_mux_partition *partition;
  313. const char *none = "NA";
  314. u16 val;
  315. int mode;
  316. partition = omap_mux_get_partition(m);
  317. if (!partition)
  318. return 0;
  319. val = omap_mux_read(partition, m->reg_offset);
  320. mode = val & OMAP_MUX_MODE7;
  321. seq_printf(s, "name: %s.%s (0x%08x/0x%03x = 0x%04x), b %s, t %s\n",
  322. m->muxnames[0], m->muxnames[mode],
  323. partition->phys + m->reg_offset, m->reg_offset, val,
  324. m->balls[0] ? m->balls[0] : none,
  325. m->balls[1] ? m->balls[1] : none);
  326. seq_printf(s, "mode: ");
  327. omap_mux_decode(s, val);
  328. seq_printf(s, "\n");
  329. seq_printf(s, "signals: %s | %s | %s | %s | %s | %s | %s | %s\n",
  330. m->muxnames[0] ? m->muxnames[0] : none,
  331. m->muxnames[1] ? m->muxnames[1] : none,
  332. m->muxnames[2] ? m->muxnames[2] : none,
  333. m->muxnames[3] ? m->muxnames[3] : none,
  334. m->muxnames[4] ? m->muxnames[4] : none,
  335. m->muxnames[5] ? m->muxnames[5] : none,
  336. m->muxnames[6] ? m->muxnames[6] : none,
  337. m->muxnames[7] ? m->muxnames[7] : none);
  338. return 0;
  339. }
  340. #define OMAP_MUX_MAX_ARG_CHAR 7
  341. static ssize_t omap_mux_dbg_signal_write(struct file *file,
  342. const char __user *user_buf,
  343. size_t count, loff_t *ppos)
  344. {
  345. char buf[OMAP_MUX_MAX_ARG_CHAR];
  346. struct seq_file *seqf;
  347. struct omap_mux *m;
  348. unsigned long val;
  349. int buf_size, ret;
  350. struct omap_mux_partition *partition;
  351. if (count > OMAP_MUX_MAX_ARG_CHAR)
  352. return -EINVAL;
  353. memset(buf, 0, sizeof(buf));
  354. buf_size = min(count, sizeof(buf) - 1);
  355. if (copy_from_user(buf, user_buf, buf_size))
  356. return -EFAULT;
  357. ret = strict_strtoul(buf, 0x10, &val);
  358. if (ret < 0)
  359. return ret;
  360. if (val > 0xffff)
  361. return -EINVAL;
  362. seqf = file->private_data;
  363. m = seqf->private;
  364. partition = omap_mux_get_partition(m);
  365. if (!partition)
  366. return -ENODEV;
  367. omap_mux_write(partition, (u16)val, m->reg_offset);
  368. *ppos += count;
  369. return count;
  370. }
  371. static int omap_mux_dbg_signal_open(struct inode *inode, struct file *file)
  372. {
  373. return single_open(file, omap_mux_dbg_signal_show, inode->i_private);
  374. }
  375. static const struct file_operations omap_mux_dbg_signal_fops = {
  376. .open = omap_mux_dbg_signal_open,
  377. .read = seq_read,
  378. .write = omap_mux_dbg_signal_write,
  379. .llseek = seq_lseek,
  380. .release = single_release,
  381. };
  382. static struct dentry *mux_dbg_dir;
  383. static void __init omap_mux_dbg_create_entry(
  384. struct omap_mux_partition *partition,
  385. struct dentry *mux_dbg_dir)
  386. {
  387. struct omap_mux_entry *e;
  388. list_for_each_entry(e, &partition->muxmodes, node) {
  389. struct omap_mux *m = &e->mux;
  390. (void)debugfs_create_file(m->muxnames[0], S_IWUGO, mux_dbg_dir,
  391. m, &omap_mux_dbg_signal_fops);
  392. }
  393. }
  394. static void __init omap_mux_dbg_init(void)
  395. {
  396. struct omap_mux_partition *partition;
  397. static struct dentry *mux_dbg_board_dir;
  398. mux_dbg_dir = debugfs_create_dir("omap_mux", NULL);
  399. if (!mux_dbg_dir)
  400. return;
  401. mux_dbg_board_dir = debugfs_create_dir("board", mux_dbg_dir);
  402. if (!mux_dbg_board_dir)
  403. return;
  404. list_for_each_entry(partition, &mux_partitions, node) {
  405. omap_mux_dbg_create_entry(partition, mux_dbg_dir);
  406. (void)debugfs_create_file(partition->name, S_IRUGO,
  407. mux_dbg_board_dir, partition,
  408. &omap_mux_dbg_board_fops);
  409. }
  410. }
  411. #else
  412. static inline void omap_mux_dbg_init(void)
  413. {
  414. }
  415. #endif /* CONFIG_DEBUG_FS */
  416. static void __init omap_mux_free_names(struct omap_mux *m)
  417. {
  418. int i;
  419. for (i = 0; i < OMAP_MUX_NR_MODES; i++)
  420. kfree(m->muxnames[i]);
  421. #ifdef CONFIG_DEBUG_FS
  422. for (i = 0; i < OMAP_MUX_NR_SIDES; i++)
  423. kfree(m->balls[i]);
  424. #endif
  425. }
  426. /* Free all data except for GPIO pins unless CONFIG_DEBUG_FS is set */
  427. static int __init omap_mux_late_init(void)
  428. {
  429. struct omap_mux_partition *partition;
  430. list_for_each_entry(partition, &mux_partitions, node) {
  431. struct omap_mux_entry *e, *tmp;
  432. list_for_each_entry_safe(e, tmp, &partition->muxmodes, node) {
  433. struct omap_mux *m = &e->mux;
  434. u16 mode = omap_mux_read(partition, m->reg_offset);
  435. if (OMAP_MODE_GPIO(mode))
  436. continue;
  437. #ifndef CONFIG_DEBUG_FS
  438. mutex_lock(&muxmode_mutex);
  439. list_del(&e->node);
  440. mutex_unlock(&muxmode_mutex);
  441. omap_mux_free_names(m);
  442. kfree(m);
  443. #endif
  444. }
  445. }
  446. omap_mux_dbg_init();
  447. return 0;
  448. }
  449. late_initcall(omap_mux_late_init);
  450. static void __init omap_mux_package_fixup(struct omap_mux *p,
  451. struct omap_mux *superset)
  452. {
  453. while (p->reg_offset != OMAP_MUX_TERMINATOR) {
  454. struct omap_mux *s = superset;
  455. int found = 0;
  456. while (s->reg_offset != OMAP_MUX_TERMINATOR) {
  457. if (s->reg_offset == p->reg_offset) {
  458. *s = *p;
  459. found++;
  460. break;
  461. }
  462. s++;
  463. }
  464. if (!found)
  465. pr_err("%s: Unknown entry offset 0x%x\n", __func__,
  466. p->reg_offset);
  467. p++;
  468. }
  469. }
  470. #ifdef CONFIG_DEBUG_FS
  471. static void __init omap_mux_package_init_balls(struct omap_ball *b,
  472. struct omap_mux *superset)
  473. {
  474. while (b->reg_offset != OMAP_MUX_TERMINATOR) {
  475. struct omap_mux *s = superset;
  476. int found = 0;
  477. while (s->reg_offset != OMAP_MUX_TERMINATOR) {
  478. if (s->reg_offset == b->reg_offset) {
  479. s->balls[0] = b->balls[0];
  480. s->balls[1] = b->balls[1];
  481. found++;
  482. break;
  483. }
  484. s++;
  485. }
  486. if (!found)
  487. pr_err("%s: Unknown ball offset 0x%x\n", __func__,
  488. b->reg_offset);
  489. b++;
  490. }
  491. }
  492. #else /* CONFIG_DEBUG_FS */
  493. static inline void omap_mux_package_init_balls(struct omap_ball *b,
  494. struct omap_mux *superset)
  495. {
  496. }
  497. #endif /* CONFIG_DEBUG_FS */
  498. static int __init omap_mux_setup(char *options)
  499. {
  500. if (!options)
  501. return 0;
  502. omap_mux_options = options;
  503. return 1;
  504. }
  505. __setup("omap_mux=", omap_mux_setup);
  506. /*
  507. * Note that the omap_mux=some.signal1=0x1234,some.signal2=0x1234
  508. * cmdline options only override the bootloader values.
  509. * During development, please enable CONFIG_DEBUG_FS, and use the
  510. * signal specific entries under debugfs.
  511. */
  512. static void __init omap_mux_set_cmdline_signals(void)
  513. {
  514. char *options, *next_opt, *token;
  515. if (!omap_mux_options)
  516. return;
  517. options = kmalloc(strlen(omap_mux_options) + 1, GFP_KERNEL);
  518. if (!options)
  519. return;
  520. strcpy(options, omap_mux_options);
  521. next_opt = options;
  522. while ((token = strsep(&next_opt, ",")) != NULL) {
  523. char *keyval, *name;
  524. unsigned long val;
  525. keyval = token;
  526. name = strsep(&keyval, "=");
  527. if (name) {
  528. int res;
  529. res = strict_strtoul(keyval, 0x10, &val);
  530. if (res < 0)
  531. continue;
  532. omap_mux_init_signal(name, (u16)val);
  533. }
  534. }
  535. kfree(options);
  536. }
  537. static int __init omap_mux_copy_names(struct omap_mux *src,
  538. struct omap_mux *dst)
  539. {
  540. int i;
  541. for (i = 0; i < OMAP_MUX_NR_MODES; i++) {
  542. if (src->muxnames[i]) {
  543. dst->muxnames[i] =
  544. kmalloc(strlen(src->muxnames[i]) + 1,
  545. GFP_KERNEL);
  546. if (!dst->muxnames[i])
  547. goto free;
  548. strcpy(dst->muxnames[i], src->muxnames[i]);
  549. }
  550. }
  551. #ifdef CONFIG_DEBUG_FS
  552. for (i = 0; i < OMAP_MUX_NR_SIDES; i++) {
  553. if (src->balls[i]) {
  554. dst->balls[i] =
  555. kmalloc(strlen(src->balls[i]) + 1,
  556. GFP_KERNEL);
  557. if (!dst->balls[i])
  558. goto free;
  559. strcpy(dst->balls[i], src->balls[i]);
  560. }
  561. }
  562. #endif
  563. return 0;
  564. free:
  565. omap_mux_free_names(dst);
  566. return -ENOMEM;
  567. }
  568. #endif /* CONFIG_OMAP_MUX */
  569. static struct omap_mux *omap_mux_get_by_gpio(
  570. struct omap_mux_partition *partition,
  571. int gpio)
  572. {
  573. struct omap_mux_entry *e;
  574. struct omap_mux *ret = NULL;
  575. list_for_each_entry(e, &partition->muxmodes, node) {
  576. struct omap_mux *m = &e->mux;
  577. if (m->gpio == gpio) {
  578. ret = m;
  579. break;
  580. }
  581. }
  582. return ret;
  583. }
  584. /* Needed for dynamic muxing of GPIO pins for off-idle */
  585. u16 omap_mux_get_gpio(int gpio)
  586. {
  587. struct omap_mux_partition *partition;
  588. struct omap_mux *m;
  589. list_for_each_entry(partition, &mux_partitions, node) {
  590. m = omap_mux_get_by_gpio(partition, gpio);
  591. if (m)
  592. return omap_mux_read(partition, m->reg_offset);
  593. }
  594. if (!m || m->reg_offset == OMAP_MUX_TERMINATOR)
  595. pr_err("%s: Could not get gpio%i\n", __func__, gpio);
  596. return OMAP_MUX_TERMINATOR;
  597. }
  598. /* Needed for dynamic muxing of GPIO pins for off-idle */
  599. void omap_mux_set_gpio(u16 val, int gpio)
  600. {
  601. struct omap_mux_partition *partition;
  602. struct omap_mux *m = NULL;
  603. list_for_each_entry(partition, &mux_partitions, node) {
  604. m = omap_mux_get_by_gpio(partition, gpio);
  605. if (m) {
  606. omap_mux_write(partition, val, m->reg_offset);
  607. return;
  608. }
  609. }
  610. if (!m || m->reg_offset == OMAP_MUX_TERMINATOR)
  611. pr_err("%s: Could not set gpio%i\n", __func__, gpio);
  612. }
  613. static struct omap_mux * __init omap_mux_list_add(
  614. struct omap_mux_partition *partition,
  615. struct omap_mux *src)
  616. {
  617. struct omap_mux_entry *entry;
  618. struct omap_mux *m;
  619. entry = kzalloc(sizeof(struct omap_mux_entry), GFP_KERNEL);
  620. if (!entry)
  621. return NULL;
  622. m = &entry->mux;
  623. memcpy(m, src, sizeof(struct omap_mux_entry));
  624. #ifdef CONFIG_OMAP_MUX
  625. if (omap_mux_copy_names(src, m)) {
  626. kfree(entry);
  627. return NULL;
  628. }
  629. #endif
  630. mutex_lock(&muxmode_mutex);
  631. list_add_tail(&entry->node, &partition->muxmodes);
  632. mutex_unlock(&muxmode_mutex);
  633. return m;
  634. }
  635. /*
  636. * Note if CONFIG_OMAP_MUX is not selected, we will only initialize
  637. * the GPIO to mux offset mapping that is needed for dynamic muxing
  638. * of GPIO pins for off-idle.
  639. */
  640. static void __init omap_mux_init_list(struct omap_mux_partition *partition,
  641. struct omap_mux *superset)
  642. {
  643. while (superset->reg_offset != OMAP_MUX_TERMINATOR) {
  644. struct omap_mux *entry;
  645. #ifdef CONFIG_OMAP_MUX
  646. if (!superset->muxnames || !superset->muxnames[0]) {
  647. superset++;
  648. continue;
  649. }
  650. #else
  651. /* Skip pins that are not muxed as GPIO by bootloader */
  652. if (!OMAP_MODE_GPIO(omap_mux_read(partition,
  653. superset->reg_offset))) {
  654. superset++;
  655. continue;
  656. }
  657. #endif
  658. entry = omap_mux_list_add(partition, superset);
  659. if (!entry) {
  660. pr_err("%s: Could not add entry\n", __func__);
  661. return;
  662. }
  663. superset++;
  664. }
  665. }
  666. #ifdef CONFIG_OMAP_MUX
  667. static void omap_mux_init_package(struct omap_mux *superset,
  668. struct omap_mux *package_subset,
  669. struct omap_ball *package_balls)
  670. {
  671. if (package_subset)
  672. omap_mux_package_fixup(package_subset, superset);
  673. if (package_balls)
  674. omap_mux_package_init_balls(package_balls, superset);
  675. }
  676. static void omap_mux_init_signals(struct omap_mux_partition *partition,
  677. struct omap_board_mux *board_mux)
  678. {
  679. omap_mux_set_cmdline_signals();
  680. omap_mux_write_array(partition, board_mux);
  681. }
  682. #else
  683. static void omap_mux_init_package(struct omap_mux *superset,
  684. struct omap_mux *package_subset,
  685. struct omap_ball *package_balls)
  686. {
  687. }
  688. static void omap_mux_init_signals(struct omap_mux_partition *partition,
  689. struct omap_board_mux *board_mux)
  690. {
  691. }
  692. #endif
  693. static u32 mux_partitions_cnt;
  694. int __init omap_mux_init(const char *name, u32 flags,
  695. u32 mux_pbase, u32 mux_size,
  696. struct omap_mux *superset,
  697. struct omap_mux *package_subset,
  698. struct omap_board_mux *board_mux,
  699. struct omap_ball *package_balls)
  700. {
  701. struct omap_mux_partition *partition;
  702. partition = kzalloc(sizeof(struct omap_mux_partition), GFP_KERNEL);
  703. if (!partition)
  704. return -ENOMEM;
  705. partition->name = name;
  706. partition->flags = flags;
  707. partition->size = mux_size;
  708. partition->phys = mux_pbase;
  709. partition->base = ioremap(mux_pbase, mux_size);
  710. if (!partition->base) {
  711. pr_err("%s: Could not ioremap mux partition at 0x%08x\n",
  712. __func__, partition->phys);
  713. return -ENODEV;
  714. }
  715. INIT_LIST_HEAD(&partition->muxmodes);
  716. list_add_tail(&partition->node, &mux_partitions);
  717. mux_partitions_cnt++;
  718. pr_info("%s: Add partition: #%d: %s, flags: %x\n", __func__,
  719. mux_partitions_cnt, partition->name, partition->flags);
  720. omap_mux_init_package(superset, package_subset, package_balls);
  721. omap_mux_init_list(partition, superset);
  722. omap_mux_init_signals(partition, board_mux);
  723. return 0;
  724. }