pinmux.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926
  1. /*
  2. * linux/arch/arm/mach-tegra/pinmux.c
  3. *
  4. * Copyright (C) 2010 Google, Inc.
  5. *
  6. * This software is licensed under the terms of the GNU General Public
  7. * License version 2, as published by the Free Software Foundation, and
  8. * may be copied, distributed, and modified under those terms.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. */
  16. #include <linux/init.h>
  17. #include <linux/module.h>
  18. #include <linux/kernel.h>
  19. #include <linux/errno.h>
  20. #include <linux/spinlock.h>
  21. #include <linux/io.h>
  22. #include <linux/platform_device.h>
  23. #include <mach/iomap.h>
  24. #include <mach/pinmux.h>
  25. #define HSM_EN(reg) (((reg) >> 2) & 0x1)
  26. #define SCHMT_EN(reg) (((reg) >> 3) & 0x1)
  27. #define LPMD(reg) (((reg) >> 4) & 0x3)
  28. #define DRVDN(reg) (((reg) >> 12) & 0x1f)
  29. #define DRVUP(reg) (((reg) >> 20) & 0x1f)
  30. #define SLWR(reg) (((reg) >> 28) & 0x3)
  31. #define SLWF(reg) (((reg) >> 30) & 0x3)
  32. static const struct tegra_pingroup_desc *const pingroups = tegra_soc_pingroups;
  33. static const struct tegra_drive_pingroup_desc *const drive_pingroups = tegra_soc_drive_pingroups;
  34. static char *tegra_mux_names[TEGRA_MAX_MUX] = {
  35. [TEGRA_MUX_AHB_CLK] = "AHB_CLK",
  36. [TEGRA_MUX_APB_CLK] = "APB_CLK",
  37. [TEGRA_MUX_AUDIO_SYNC] = "AUDIO_SYNC",
  38. [TEGRA_MUX_CRT] = "CRT",
  39. [TEGRA_MUX_DAP1] = "DAP1",
  40. [TEGRA_MUX_DAP2] = "DAP2",
  41. [TEGRA_MUX_DAP3] = "DAP3",
  42. [TEGRA_MUX_DAP4] = "DAP4",
  43. [TEGRA_MUX_DAP5] = "DAP5",
  44. [TEGRA_MUX_DISPLAYA] = "DISPLAYA",
  45. [TEGRA_MUX_DISPLAYB] = "DISPLAYB",
  46. [TEGRA_MUX_EMC_TEST0_DLL] = "EMC_TEST0_DLL",
  47. [TEGRA_MUX_EMC_TEST1_DLL] = "EMC_TEST1_DLL",
  48. [TEGRA_MUX_GMI] = "GMI",
  49. [TEGRA_MUX_GMI_INT] = "GMI_INT",
  50. [TEGRA_MUX_HDMI] = "HDMI",
  51. [TEGRA_MUX_I2C] = "I2C",
  52. [TEGRA_MUX_I2C2] = "I2C2",
  53. [TEGRA_MUX_I2C3] = "I2C3",
  54. [TEGRA_MUX_IDE] = "IDE",
  55. [TEGRA_MUX_IRDA] = "IRDA",
  56. [TEGRA_MUX_KBC] = "KBC",
  57. [TEGRA_MUX_MIO] = "MIO",
  58. [TEGRA_MUX_MIPI_HS] = "MIPI_HS",
  59. [TEGRA_MUX_NAND] = "NAND",
  60. [TEGRA_MUX_OSC] = "OSC",
  61. [TEGRA_MUX_OWR] = "OWR",
  62. [TEGRA_MUX_PCIE] = "PCIE",
  63. [TEGRA_MUX_PLLA_OUT] = "PLLA_OUT",
  64. [TEGRA_MUX_PLLC_OUT1] = "PLLC_OUT1",
  65. [TEGRA_MUX_PLLM_OUT1] = "PLLM_OUT1",
  66. [TEGRA_MUX_PLLP_OUT2] = "PLLP_OUT2",
  67. [TEGRA_MUX_PLLP_OUT3] = "PLLP_OUT3",
  68. [TEGRA_MUX_PLLP_OUT4] = "PLLP_OUT4",
  69. [TEGRA_MUX_PWM] = "PWM",
  70. [TEGRA_MUX_PWR_INTR] = "PWR_INTR",
  71. [TEGRA_MUX_PWR_ON] = "PWR_ON",
  72. [TEGRA_MUX_RTCK] = "RTCK",
  73. [TEGRA_MUX_SDIO1] = "SDIO1",
  74. [TEGRA_MUX_SDIO2] = "SDIO2",
  75. [TEGRA_MUX_SDIO3] = "SDIO3",
  76. [TEGRA_MUX_SDIO4] = "SDIO4",
  77. [TEGRA_MUX_SFLASH] = "SFLASH",
  78. [TEGRA_MUX_SPDIF] = "SPDIF",
  79. [TEGRA_MUX_SPI1] = "SPI1",
  80. [TEGRA_MUX_SPI2] = "SPI2",
  81. [TEGRA_MUX_SPI2_ALT] = "SPI2_ALT",
  82. [TEGRA_MUX_SPI3] = "SPI3",
  83. [TEGRA_MUX_SPI4] = "SPI4",
  84. [TEGRA_MUX_TRACE] = "TRACE",
  85. [TEGRA_MUX_TWC] = "TWC",
  86. [TEGRA_MUX_UARTA] = "UARTA",
  87. [TEGRA_MUX_UARTB] = "UARTB",
  88. [TEGRA_MUX_UARTC] = "UARTC",
  89. [TEGRA_MUX_UARTD] = "UARTD",
  90. [TEGRA_MUX_UARTE] = "UARTE",
  91. [TEGRA_MUX_ULPI] = "ULPI",
  92. [TEGRA_MUX_VI] = "VI",
  93. [TEGRA_MUX_VI_SENSOR_CLK] = "VI_SENSOR_CLK",
  94. [TEGRA_MUX_XIO] = "XIO",
  95. [TEGRA_MUX_SAFE] = "<safe>",
  96. };
  97. static const char *tegra_drive_names[TEGRA_MAX_DRIVE] = {
  98. [TEGRA_DRIVE_DIV_8] = "DIV_8",
  99. [TEGRA_DRIVE_DIV_4] = "DIV_4",
  100. [TEGRA_DRIVE_DIV_2] = "DIV_2",
  101. [TEGRA_DRIVE_DIV_1] = "DIV_1",
  102. };
  103. static const char *tegra_slew_names[TEGRA_MAX_SLEW] = {
  104. [TEGRA_SLEW_FASTEST] = "FASTEST",
  105. [TEGRA_SLEW_FAST] = "FAST",
  106. [TEGRA_SLEW_SLOW] = "SLOW",
  107. [TEGRA_SLEW_SLOWEST] = "SLOWEST",
  108. };
  109. static DEFINE_SPINLOCK(mux_lock);
  110. static const char *pingroup_name(enum tegra_pingroup pg)
  111. {
  112. if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
  113. return "<UNKNOWN>";
  114. return pingroups[pg].name;
  115. }
  116. static const char *func_name(enum tegra_mux_func func)
  117. {
  118. if (func == TEGRA_MUX_RSVD1)
  119. return "RSVD1";
  120. if (func == TEGRA_MUX_RSVD2)
  121. return "RSVD2";
  122. if (func == TEGRA_MUX_RSVD3)
  123. return "RSVD3";
  124. if (func == TEGRA_MUX_RSVD4)
  125. return "RSVD4";
  126. if (func == TEGRA_MUX_NONE)
  127. return "NONE";
  128. if (func < 0 || func >= TEGRA_MAX_MUX)
  129. return "<UNKNOWN>";
  130. return tegra_mux_names[func];
  131. }
  132. static const char *tri_name(unsigned long val)
  133. {
  134. return val ? "TRISTATE" : "NORMAL";
  135. }
  136. static const char *pupd_name(unsigned long val)
  137. {
  138. switch (val) {
  139. case 0:
  140. return "NORMAL";
  141. case 1:
  142. return "PULL_DOWN";
  143. case 2:
  144. return "PULL_UP";
  145. default:
  146. return "RSVD";
  147. }
  148. }
  149. static int nbanks;
  150. static void __iomem **regs;
  151. static inline u32 pg_readl(u32 bank, u32 reg)
  152. {
  153. return readl(regs[bank] + reg);
  154. }
  155. static inline void pg_writel(u32 val, u32 bank, u32 reg)
  156. {
  157. writel(val, regs[bank] + reg);
  158. }
  159. static int tegra_pinmux_set_func(const struct tegra_pingroup_config *config)
  160. {
  161. int mux = -1;
  162. int i;
  163. unsigned long reg;
  164. unsigned long flags;
  165. enum tegra_pingroup pg = config->pingroup;
  166. enum tegra_mux_func func = config->func;
  167. if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
  168. return -ERANGE;
  169. if (pingroups[pg].mux_reg < 0)
  170. return -EINVAL;
  171. if (func < 0)
  172. return -ERANGE;
  173. if (func == TEGRA_MUX_SAFE)
  174. func = pingroups[pg].func_safe;
  175. if (func & TEGRA_MUX_RSVD) {
  176. mux = func & 0x3;
  177. } else {
  178. for (i = 0; i < 4; i++) {
  179. if (pingroups[pg].funcs[i] == func) {
  180. mux = i;
  181. break;
  182. }
  183. }
  184. }
  185. if (mux < 0)
  186. return -EINVAL;
  187. spin_lock_irqsave(&mux_lock, flags);
  188. reg = pg_readl(pingroups[pg].mux_bank, pingroups[pg].mux_reg);
  189. reg &= ~(0x3 << pingroups[pg].mux_bit);
  190. reg |= mux << pingroups[pg].mux_bit;
  191. pg_writel(reg, pingroups[pg].mux_bank, pingroups[pg].mux_reg);
  192. spin_unlock_irqrestore(&mux_lock, flags);
  193. return 0;
  194. }
  195. int tegra_pinmux_set_tristate(enum tegra_pingroup pg,
  196. enum tegra_tristate tristate)
  197. {
  198. unsigned long reg;
  199. unsigned long flags;
  200. if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
  201. return -ERANGE;
  202. if (pingroups[pg].tri_reg < 0)
  203. return -EINVAL;
  204. spin_lock_irqsave(&mux_lock, flags);
  205. reg = pg_readl(pingroups[pg].tri_bank, pingroups[pg].tri_reg);
  206. reg &= ~(0x1 << pingroups[pg].tri_bit);
  207. if (tristate)
  208. reg |= 1 << pingroups[pg].tri_bit;
  209. pg_writel(reg, pingroups[pg].tri_bank, pingroups[pg].tri_reg);
  210. spin_unlock_irqrestore(&mux_lock, flags);
  211. return 0;
  212. }
  213. int tegra_pinmux_set_pullupdown(enum tegra_pingroup pg,
  214. enum tegra_pullupdown pupd)
  215. {
  216. unsigned long reg;
  217. unsigned long flags;
  218. if (pg < 0 || pg >= TEGRA_MAX_PINGROUP)
  219. return -ERANGE;
  220. if (pingroups[pg].pupd_reg < 0)
  221. return -EINVAL;
  222. if (pupd != TEGRA_PUPD_NORMAL &&
  223. pupd != TEGRA_PUPD_PULL_DOWN &&
  224. pupd != TEGRA_PUPD_PULL_UP)
  225. return -EINVAL;
  226. spin_lock_irqsave(&mux_lock, flags);
  227. reg = pg_readl(pingroups[pg].pupd_bank, pingroups[pg].pupd_reg);
  228. reg &= ~(0x3 << pingroups[pg].pupd_bit);
  229. reg |= pupd << pingroups[pg].pupd_bit;
  230. pg_writel(reg, pingroups[pg].pupd_bank, pingroups[pg].pupd_reg);
  231. spin_unlock_irqrestore(&mux_lock, flags);
  232. return 0;
  233. }
  234. static void tegra_pinmux_config_pingroup(const struct tegra_pingroup_config *config)
  235. {
  236. enum tegra_pingroup pingroup = config->pingroup;
  237. enum tegra_mux_func func = config->func;
  238. enum tegra_pullupdown pupd = config->pupd;
  239. enum tegra_tristate tristate = config->tristate;
  240. int err;
  241. if (pingroups[pingroup].mux_reg >= 0) {
  242. err = tegra_pinmux_set_func(config);
  243. if (err < 0)
  244. pr_err("pinmux: can't set pingroup %s func to %s: %d\n",
  245. pingroup_name(pingroup), func_name(func), err);
  246. }
  247. if (pingroups[pingroup].pupd_reg >= 0) {
  248. err = tegra_pinmux_set_pullupdown(pingroup, pupd);
  249. if (err < 0)
  250. pr_err("pinmux: can't set pingroup %s pullupdown to %s: %d\n",
  251. pingroup_name(pingroup), pupd_name(pupd), err);
  252. }
  253. if (pingroups[pingroup].tri_reg >= 0) {
  254. err = tegra_pinmux_set_tristate(pingroup, tristate);
  255. if (err < 0)
  256. pr_err("pinmux: can't set pingroup %s tristate to %s: %d\n",
  257. pingroup_name(pingroup), tri_name(func), err);
  258. }
  259. }
  260. void tegra_pinmux_config_table(const struct tegra_pingroup_config *config, int len)
  261. {
  262. int i;
  263. for (i = 0; i < len; i++)
  264. tegra_pinmux_config_pingroup(&config[i]);
  265. }
  266. static const char *drive_pinmux_name(enum tegra_drive_pingroup pg)
  267. {
  268. if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
  269. return "<UNKNOWN>";
  270. return drive_pingroups[pg].name;
  271. }
  272. static const char *enable_name(unsigned long val)
  273. {
  274. return val ? "ENABLE" : "DISABLE";
  275. }
  276. static const char *drive_name(unsigned long val)
  277. {
  278. if (val >= TEGRA_MAX_DRIVE)
  279. return "<UNKNOWN>";
  280. return tegra_drive_names[val];
  281. }
  282. static const char *slew_name(unsigned long val)
  283. {
  284. if (val >= TEGRA_MAX_SLEW)
  285. return "<UNKNOWN>";
  286. return tegra_slew_names[val];
  287. }
  288. static int tegra_drive_pinmux_set_hsm(enum tegra_drive_pingroup pg,
  289. enum tegra_hsm hsm)
  290. {
  291. unsigned long flags;
  292. u32 reg;
  293. if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
  294. return -ERANGE;
  295. if (hsm != TEGRA_HSM_ENABLE && hsm != TEGRA_HSM_DISABLE)
  296. return -EINVAL;
  297. spin_lock_irqsave(&mux_lock, flags);
  298. reg = pg_readl(drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
  299. if (hsm == TEGRA_HSM_ENABLE)
  300. reg |= (1 << 2);
  301. else
  302. reg &= ~(1 << 2);
  303. pg_writel(reg, drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
  304. spin_unlock_irqrestore(&mux_lock, flags);
  305. return 0;
  306. }
  307. static int tegra_drive_pinmux_set_schmitt(enum tegra_drive_pingroup pg,
  308. enum tegra_schmitt schmitt)
  309. {
  310. unsigned long flags;
  311. u32 reg;
  312. if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
  313. return -ERANGE;
  314. if (schmitt != TEGRA_SCHMITT_ENABLE && schmitt != TEGRA_SCHMITT_DISABLE)
  315. return -EINVAL;
  316. spin_lock_irqsave(&mux_lock, flags);
  317. reg = pg_readl(drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
  318. if (schmitt == TEGRA_SCHMITT_ENABLE)
  319. reg |= (1 << 3);
  320. else
  321. reg &= ~(1 << 3);
  322. pg_writel(reg, drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
  323. spin_unlock_irqrestore(&mux_lock, flags);
  324. return 0;
  325. }
  326. static int tegra_drive_pinmux_set_drive(enum tegra_drive_pingroup pg,
  327. enum tegra_drive drive)
  328. {
  329. unsigned long flags;
  330. u32 reg;
  331. if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
  332. return -ERANGE;
  333. if (drive < 0 || drive >= TEGRA_MAX_DRIVE)
  334. return -EINVAL;
  335. spin_lock_irqsave(&mux_lock, flags);
  336. reg = pg_readl(drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
  337. reg &= ~(0x3 << 4);
  338. reg |= drive << 4;
  339. pg_writel(reg, drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
  340. spin_unlock_irqrestore(&mux_lock, flags);
  341. return 0;
  342. }
  343. static int tegra_drive_pinmux_set_pull_down(enum tegra_drive_pingroup pg,
  344. enum tegra_pull_strength pull_down)
  345. {
  346. unsigned long flags;
  347. u32 reg;
  348. if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
  349. return -ERANGE;
  350. if (pull_down < 0 || pull_down >= TEGRA_MAX_PULL)
  351. return -EINVAL;
  352. spin_lock_irqsave(&mux_lock, flags);
  353. reg = pg_readl(drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
  354. reg &= ~(0x1f << 12);
  355. reg |= pull_down << 12;
  356. pg_writel(reg, drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
  357. spin_unlock_irqrestore(&mux_lock, flags);
  358. return 0;
  359. }
  360. static int tegra_drive_pinmux_set_pull_up(enum tegra_drive_pingroup pg,
  361. enum tegra_pull_strength pull_up)
  362. {
  363. unsigned long flags;
  364. u32 reg;
  365. if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
  366. return -ERANGE;
  367. if (pull_up < 0 || pull_up >= TEGRA_MAX_PULL)
  368. return -EINVAL;
  369. spin_lock_irqsave(&mux_lock, flags);
  370. reg = pg_readl(drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
  371. reg &= ~(0x1f << 12);
  372. reg |= pull_up << 12;
  373. pg_writel(reg, drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
  374. spin_unlock_irqrestore(&mux_lock, flags);
  375. return 0;
  376. }
  377. static int tegra_drive_pinmux_set_slew_rising(enum tegra_drive_pingroup pg,
  378. enum tegra_slew slew_rising)
  379. {
  380. unsigned long flags;
  381. u32 reg;
  382. if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
  383. return -ERANGE;
  384. if (slew_rising < 0 || slew_rising >= TEGRA_MAX_SLEW)
  385. return -EINVAL;
  386. spin_lock_irqsave(&mux_lock, flags);
  387. reg = pg_readl(drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
  388. reg &= ~(0x3 << 28);
  389. reg |= slew_rising << 28;
  390. pg_writel(reg, drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
  391. spin_unlock_irqrestore(&mux_lock, flags);
  392. return 0;
  393. }
  394. static int tegra_drive_pinmux_set_slew_falling(enum tegra_drive_pingroup pg,
  395. enum tegra_slew slew_falling)
  396. {
  397. unsigned long flags;
  398. u32 reg;
  399. if (pg < 0 || pg >= TEGRA_MAX_DRIVE_PINGROUP)
  400. return -ERANGE;
  401. if (slew_falling < 0 || slew_falling >= TEGRA_MAX_SLEW)
  402. return -EINVAL;
  403. spin_lock_irqsave(&mux_lock, flags);
  404. reg = pg_readl(drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
  405. reg &= ~(0x3 << 30);
  406. reg |= slew_falling << 30;
  407. pg_writel(reg, drive_pingroups[pg].reg_bank, drive_pingroups[pg].reg);
  408. spin_unlock_irqrestore(&mux_lock, flags);
  409. return 0;
  410. }
  411. static void tegra_drive_pinmux_config_pingroup(enum tegra_drive_pingroup pingroup,
  412. enum tegra_hsm hsm,
  413. enum tegra_schmitt schmitt,
  414. enum tegra_drive drive,
  415. enum tegra_pull_strength pull_down,
  416. enum tegra_pull_strength pull_up,
  417. enum tegra_slew slew_rising,
  418. enum tegra_slew slew_falling)
  419. {
  420. int err;
  421. err = tegra_drive_pinmux_set_hsm(pingroup, hsm);
  422. if (err < 0)
  423. pr_err("pinmux: can't set pingroup %s hsm to %s: %d\n",
  424. drive_pinmux_name(pingroup),
  425. enable_name(hsm), err);
  426. err = tegra_drive_pinmux_set_schmitt(pingroup, schmitt);
  427. if (err < 0)
  428. pr_err("pinmux: can't set pingroup %s schmitt to %s: %d\n",
  429. drive_pinmux_name(pingroup),
  430. enable_name(schmitt), err);
  431. err = tegra_drive_pinmux_set_drive(pingroup, drive);
  432. if (err < 0)
  433. pr_err("pinmux: can't set pingroup %s drive to %s: %d\n",
  434. drive_pinmux_name(pingroup),
  435. drive_name(drive), err);
  436. err = tegra_drive_pinmux_set_pull_down(pingroup, pull_down);
  437. if (err < 0)
  438. pr_err("pinmux: can't set pingroup %s pull down to %d: %d\n",
  439. drive_pinmux_name(pingroup),
  440. pull_down, err);
  441. err = tegra_drive_pinmux_set_pull_up(pingroup, pull_up);
  442. if (err < 0)
  443. pr_err("pinmux: can't set pingroup %s pull up to %d: %d\n",
  444. drive_pinmux_name(pingroup),
  445. pull_up, err);
  446. err = tegra_drive_pinmux_set_slew_rising(pingroup, slew_rising);
  447. if (err < 0)
  448. pr_err("pinmux: can't set pingroup %s rising slew to %s: %d\n",
  449. drive_pinmux_name(pingroup),
  450. slew_name(slew_rising), err);
  451. err = tegra_drive_pinmux_set_slew_falling(pingroup, slew_falling);
  452. if (err < 0)
  453. pr_err("pinmux: can't set pingroup %s falling slew to %s: %d\n",
  454. drive_pinmux_name(pingroup),
  455. slew_name(slew_falling), err);
  456. }
  457. void tegra_drive_pinmux_config_table(struct tegra_drive_pingroup_config *config,
  458. int len)
  459. {
  460. int i;
  461. for (i = 0; i < len; i++)
  462. tegra_drive_pinmux_config_pingroup(config[i].pingroup,
  463. config[i].hsm,
  464. config[i].schmitt,
  465. config[i].drive,
  466. config[i].pull_down,
  467. config[i].pull_up,
  468. config[i].slew_rising,
  469. config[i].slew_falling);
  470. }
  471. void tegra_pinmux_set_safe_pinmux_table(const struct tegra_pingroup_config *config,
  472. int len)
  473. {
  474. int i;
  475. struct tegra_pingroup_config c;
  476. for (i = 0; i < len; i++) {
  477. int err;
  478. c = config[i];
  479. if (c.pingroup < 0 || c.pingroup >= TEGRA_MAX_PINGROUP) {
  480. WARN_ON(1);
  481. continue;
  482. }
  483. c.func = pingroups[c.pingroup].func_safe;
  484. err = tegra_pinmux_set_func(&c);
  485. if (err < 0)
  486. pr_err("%s: tegra_pinmux_set_func returned %d setting "
  487. "%s to %s\n", __func__, err,
  488. pingroup_name(c.pingroup), func_name(c.func));
  489. }
  490. }
  491. void tegra_pinmux_config_pinmux_table(const struct tegra_pingroup_config *config,
  492. int len)
  493. {
  494. int i;
  495. for (i = 0; i < len; i++) {
  496. int err;
  497. if (config[i].pingroup < 0 ||
  498. config[i].pingroup >= TEGRA_MAX_PINGROUP) {
  499. WARN_ON(1);
  500. continue;
  501. }
  502. err = tegra_pinmux_set_func(&config[i]);
  503. if (err < 0)
  504. pr_err("%s: tegra_pinmux_set_func returned %d setting "
  505. "%s to %s\n", __func__, err,
  506. pingroup_name(config[i].pingroup),
  507. func_name(config[i].func));
  508. }
  509. }
  510. void tegra_pinmux_config_tristate_table(const struct tegra_pingroup_config *config,
  511. int len, enum tegra_tristate tristate)
  512. {
  513. int i;
  514. int err;
  515. enum tegra_pingroup pingroup;
  516. for (i = 0; i < len; i++) {
  517. pingroup = config[i].pingroup;
  518. if (pingroups[pingroup].tri_reg >= 0) {
  519. err = tegra_pinmux_set_tristate(pingroup, tristate);
  520. if (err < 0)
  521. pr_err("pinmux: can't set pingroup %s tristate"
  522. " to %s: %d\n", pingroup_name(pingroup),
  523. tri_name(tristate), err);
  524. }
  525. }
  526. }
  527. void tegra_pinmux_config_pullupdown_table(const struct tegra_pingroup_config *config,
  528. int len, enum tegra_pullupdown pupd)
  529. {
  530. int i;
  531. int err;
  532. enum tegra_pingroup pingroup;
  533. for (i = 0; i < len; i++) {
  534. pingroup = config[i].pingroup;
  535. if (pingroups[pingroup].pupd_reg >= 0) {
  536. err = tegra_pinmux_set_pullupdown(pingroup, pupd);
  537. if (err < 0)
  538. pr_err("pinmux: can't set pingroup %s pullupdown"
  539. " to %s: %d\n", pingroup_name(pingroup),
  540. pupd_name(pupd), err);
  541. }
  542. }
  543. }
  544. static int __devinit tegra_pinmux_probe(struct platform_device *pdev)
  545. {
  546. struct resource *res;
  547. int i;
  548. int config_bad = 0;
  549. for (i = 0; ; i++) {
  550. res = platform_get_resource(pdev, IORESOURCE_MEM, i);
  551. if (!res)
  552. break;
  553. }
  554. nbanks = i;
  555. for (i = 0; i < TEGRA_MAX_PINGROUP; i++) {
  556. if (pingroups[i].tri_bank >= nbanks) {
  557. dev_err(&pdev->dev, "pingroup %d: bad tri_bank\n", i);
  558. config_bad = 1;
  559. }
  560. if (pingroups[i].mux_bank >= nbanks) {
  561. dev_err(&pdev->dev, "pingroup %d: bad mux_bank\n", i);
  562. config_bad = 1;
  563. }
  564. if (pingroups[i].pupd_bank >= nbanks) {
  565. dev_err(&pdev->dev, "pingroup %d: bad pupd_bank\n", i);
  566. config_bad = 1;
  567. }
  568. }
  569. for (i = 0; i < TEGRA_MAX_DRIVE_PINGROUP; i++) {
  570. if (drive_pingroups[i].reg_bank >= nbanks) {
  571. dev_err(&pdev->dev,
  572. "drive pingroup %d: bad reg_bank\n", i);
  573. config_bad = 1;
  574. }
  575. }
  576. if (config_bad)
  577. return -ENODEV;
  578. regs = devm_kzalloc(&pdev->dev, nbanks * sizeof(*regs), GFP_KERNEL);
  579. if (!regs) {
  580. dev_err(&pdev->dev, "Can't alloc regs pointer\n");
  581. return -ENODEV;
  582. }
  583. for (i = 0; i < nbanks; i++) {
  584. res = platform_get_resource(pdev, IORESOURCE_MEM, i);
  585. if (!res) {
  586. dev_err(&pdev->dev, "Missing MEM resource\n");
  587. return -ENODEV;
  588. }
  589. if (!devm_request_mem_region(&pdev->dev, res->start,
  590. resource_size(res),
  591. dev_name(&pdev->dev))) {
  592. dev_err(&pdev->dev,
  593. "Couldn't request MEM resource %d\n", i);
  594. return -ENODEV;
  595. }
  596. regs[i] = devm_ioremap(&pdev->dev, res->start,
  597. resource_size(res));
  598. if (!regs) {
  599. dev_err(&pdev->dev, "Couldn't ioremap regs %d\n", i);
  600. return -ENODEV;
  601. }
  602. }
  603. return 0;
  604. }
  605. static struct of_device_id tegra_pinmux_of_match[] __devinitdata = {
  606. { .compatible = "nvidia,tegra20-pinmux", },
  607. { },
  608. };
  609. static struct platform_driver tegra_pinmux_driver = {
  610. .driver = {
  611. .name = "tegra-pinmux",
  612. .owner = THIS_MODULE,
  613. .of_match_table = tegra_pinmux_of_match,
  614. },
  615. .probe = tegra_pinmux_probe,
  616. };
  617. static int __init tegra_pinmux_init(void)
  618. {
  619. return platform_driver_register(&tegra_pinmux_driver);
  620. }
  621. postcore_initcall(tegra_pinmux_init);
  622. #ifdef CONFIG_DEBUG_FS
  623. #include <linux/debugfs.h>
  624. #include <linux/seq_file.h>
  625. static void dbg_pad_field(struct seq_file *s, int len)
  626. {
  627. seq_putc(s, ',');
  628. while (len-- > -1)
  629. seq_putc(s, ' ');
  630. }
  631. static int dbg_pinmux_show(struct seq_file *s, void *unused)
  632. {
  633. int i;
  634. int len;
  635. for (i = 0; i < TEGRA_MAX_PINGROUP; i++) {
  636. unsigned long reg;
  637. unsigned long tri;
  638. unsigned long mux;
  639. unsigned long pupd;
  640. seq_printf(s, "\t{TEGRA_PINGROUP_%s", pingroups[i].name);
  641. len = strlen(pingroups[i].name);
  642. dbg_pad_field(s, 5 - len);
  643. if (pingroups[i].mux_reg < 0) {
  644. seq_printf(s, "TEGRA_MUX_NONE");
  645. len = strlen("NONE");
  646. } else {
  647. reg = pg_readl(pingroups[i].mux_bank,
  648. pingroups[i].mux_reg);
  649. mux = (reg >> pingroups[i].mux_bit) & 0x3;
  650. if (pingroups[i].funcs[mux] == TEGRA_MUX_RSVD) {
  651. seq_printf(s, "TEGRA_MUX_RSVD%1lu", mux+1);
  652. len = 5;
  653. } else {
  654. seq_printf(s, "TEGRA_MUX_%s",
  655. tegra_mux_names[pingroups[i].funcs[mux]]);
  656. len = strlen(tegra_mux_names[pingroups[i].funcs[mux]]);
  657. }
  658. }
  659. dbg_pad_field(s, 13-len);
  660. if (pingroups[i].pupd_reg < 0) {
  661. seq_printf(s, "TEGRA_PUPD_NORMAL");
  662. len = strlen("NORMAL");
  663. } else {
  664. reg = pg_readl(pingroups[i].pupd_bank,
  665. pingroups[i].pupd_reg);
  666. pupd = (reg >> pingroups[i].pupd_bit) & 0x3;
  667. seq_printf(s, "TEGRA_PUPD_%s", pupd_name(pupd));
  668. len = strlen(pupd_name(pupd));
  669. }
  670. dbg_pad_field(s, 9 - len);
  671. if (pingroups[i].tri_reg < 0) {
  672. seq_printf(s, "TEGRA_TRI_NORMAL");
  673. } else {
  674. reg = pg_readl(pingroups[i].tri_bank,
  675. pingroups[i].tri_reg);
  676. tri = (reg >> pingroups[i].tri_bit) & 0x1;
  677. seq_printf(s, "TEGRA_TRI_%s", tri_name(tri));
  678. }
  679. seq_printf(s, "},\n");
  680. }
  681. return 0;
  682. }
  683. static int dbg_pinmux_open(struct inode *inode, struct file *file)
  684. {
  685. return single_open(file, dbg_pinmux_show, &inode->i_private);
  686. }
  687. static const struct file_operations debug_fops = {
  688. .open = dbg_pinmux_open,
  689. .read = seq_read,
  690. .llseek = seq_lseek,
  691. .release = single_release,
  692. };
  693. static int dbg_drive_pinmux_show(struct seq_file *s, void *unused)
  694. {
  695. int i;
  696. int len;
  697. for (i = 0; i < TEGRA_MAX_DRIVE_PINGROUP; i++) {
  698. u32 reg;
  699. seq_printf(s, "\t{TEGRA_DRIVE_PINGROUP_%s",
  700. drive_pingroups[i].name);
  701. len = strlen(drive_pingroups[i].name);
  702. dbg_pad_field(s, 7 - len);
  703. reg = pg_readl(drive_pingroups[i].reg_bank,
  704. drive_pingroups[i].reg);
  705. if (HSM_EN(reg)) {
  706. seq_printf(s, "TEGRA_HSM_ENABLE");
  707. len = 16;
  708. } else {
  709. seq_printf(s, "TEGRA_HSM_DISABLE");
  710. len = 17;
  711. }
  712. dbg_pad_field(s, 17 - len);
  713. if (SCHMT_EN(reg)) {
  714. seq_printf(s, "TEGRA_SCHMITT_ENABLE");
  715. len = 21;
  716. } else {
  717. seq_printf(s, "TEGRA_SCHMITT_DISABLE");
  718. len = 22;
  719. }
  720. dbg_pad_field(s, 22 - len);
  721. seq_printf(s, "TEGRA_DRIVE_%s", drive_name(LPMD(reg)));
  722. len = strlen(drive_name(LPMD(reg)));
  723. dbg_pad_field(s, 5 - len);
  724. seq_printf(s, "TEGRA_PULL_%d", DRVDN(reg));
  725. len = DRVDN(reg) < 10 ? 1 : 2;
  726. dbg_pad_field(s, 2 - len);
  727. seq_printf(s, "TEGRA_PULL_%d", DRVUP(reg));
  728. len = DRVUP(reg) < 10 ? 1 : 2;
  729. dbg_pad_field(s, 2 - len);
  730. seq_printf(s, "TEGRA_SLEW_%s", slew_name(SLWR(reg)));
  731. len = strlen(slew_name(SLWR(reg)));
  732. dbg_pad_field(s, 7 - len);
  733. seq_printf(s, "TEGRA_SLEW_%s", slew_name(SLWF(reg)));
  734. seq_printf(s, "},\n");
  735. }
  736. return 0;
  737. }
  738. static int dbg_drive_pinmux_open(struct inode *inode, struct file *file)
  739. {
  740. return single_open(file, dbg_drive_pinmux_show, &inode->i_private);
  741. }
  742. static const struct file_operations debug_drive_fops = {
  743. .open = dbg_drive_pinmux_open,
  744. .read = seq_read,
  745. .llseek = seq_lseek,
  746. .release = single_release,
  747. };
  748. static int __init tegra_pinmux_debuginit(void)
  749. {
  750. (void) debugfs_create_file("tegra_pinmux", S_IRUGO,
  751. NULL, NULL, &debug_fops);
  752. (void) debugfs_create_file("tegra_pinmux_drive", S_IRUGO,
  753. NULL, NULL, &debug_drive_fops);
  754. return 0;
  755. }
  756. late_initcall(tegra_pinmux_debuginit);
  757. #endif