mach-crag6410-module.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468
  1. // SPDX-License-Identifier: GPL-2.0
  2. //
  3. // Speyside modules for Cragganmore - board data probing
  4. //
  5. // Copyright 2011 Wolfson Microelectronics plc
  6. // Mark Brown <broonie@opensource.wolfsonmicro.com>
  7. #include <linux/export.h>
  8. #include <linux/interrupt.h>
  9. #include <linux/i2c.h>
  10. #include <linux/spi/spi.h>
  11. #include <linux/gpio/machine.h>
  12. #include <linux/mfd/wm831x/irq.h>
  13. #include <linux/mfd/wm831x/gpio.h>
  14. #include <linux/mfd/wm8994/pdata.h>
  15. #include <linux/mfd/arizona/pdata.h>
  16. #include <linux/regulator/machine.h>
  17. #include <sound/wm0010.h>
  18. #include <sound/wm2200.h>
  19. #include <sound/wm5100.h>
  20. #include <sound/wm8996.h>
  21. #include <sound/wm8962.h>
  22. #include <sound/wm9081.h>
  23. #include <linux/platform_data/spi-s3c64xx.h>
  24. #include "cpu.h"
  25. #include "irqs.h"
  26. #include "crag6410.h"
  27. static struct gpiod_lookup_table wm0010_gpiod_table = {
  28. .dev_id = "spi0.0", /* SPI device name */
  29. .table = {
  30. /* Active high for Glenfarclas Rev 2 */
  31. GPIO_LOOKUP("GPION", 6,
  32. "reset", GPIO_ACTIVE_HIGH),
  33. { },
  34. },
  35. };
  36. static struct wm0010_pdata wm0010_pdata = {
  37. /* Intentionally left blank */
  38. };
  39. static struct spi_board_info wm1253_devs[] = {
  40. [0] = {
  41. .modalias = "wm0010",
  42. .max_speed_hz = 26 * 1000 * 1000,
  43. .bus_num = 0,
  44. .chip_select = 0,
  45. .mode = SPI_MODE_0,
  46. .irq = S3C_EINT(4),
  47. .platform_data = &wm0010_pdata,
  48. },
  49. };
  50. static struct spi_board_info balblair_devs[] = {
  51. [0] = {
  52. .modalias = "wm0010",
  53. .max_speed_hz = 26 * 1000 * 1000,
  54. .bus_num = 0,
  55. .chip_select = 0,
  56. .mode = SPI_MODE_0,
  57. .irq = S3C_EINT(4),
  58. .platform_data = &wm0010_pdata,
  59. },
  60. };
  61. static struct gpiod_lookup_table wm5100_gpiod_table = {
  62. .dev_id = "1-001a", /* Device 001a on I2C bus 1 */
  63. .table = {
  64. GPIO_LOOKUP("GPION", 7,
  65. "wlf,ldo1ena", GPIO_ACTIVE_HIGH),
  66. GPIO_LOOKUP("wm5100", 3,
  67. "hp-pol", GPIO_ACTIVE_HIGH),
  68. { },
  69. },
  70. };
  71. static struct wm5100_pdata wm5100_pdata = {
  72. .irq_flags = IRQF_TRIGGER_HIGH,
  73. .in_mode = {
  74. WM5100_IN_DIFF,
  75. WM5100_IN_DIFF,
  76. WM5100_IN_DIFF,
  77. WM5100_IN_SE,
  78. },
  79. .jack_modes = {
  80. { WM5100_MICDET_MICBIAS3, 0, 0 },
  81. { WM5100_MICDET_MICBIAS2, 1, 1 },
  82. },
  83. .gpio_defaults = {
  84. 0,
  85. 0,
  86. 0,
  87. 0,
  88. 0x2, /* IRQ: CMOS output */
  89. 0x3, /* CLKOUT: CMOS output */
  90. },
  91. };
  92. static struct wm8996_retune_mobile_config wm8996_retune[] = {
  93. {
  94. .name = "Sub LPF",
  95. .rate = 48000,
  96. .regs = {
  97. 0x6318, 0x6300, 0x1000, 0x0000, 0x0004, 0x2000, 0xF000,
  98. 0x0000, 0x0004, 0x2000, 0xF000, 0x0000, 0x0004, 0x2000,
  99. 0xF000, 0x0000, 0x0004, 0x1000, 0x0800, 0x4000
  100. },
  101. },
  102. {
  103. .name = "Sub HPF",
  104. .rate = 48000,
  105. .regs = {
  106. 0x000A, 0x6300, 0x1000, 0x0000, 0x0004, 0x2000, 0xF000,
  107. 0x0000, 0x0004, 0x2000, 0xF000, 0x0000, 0x0004, 0x2000,
  108. 0xF000, 0x0000, 0x0004, 0x1000, 0x0800, 0x4000
  109. },
  110. },
  111. };
  112. static struct gpiod_lookup_table wm8996_gpiod_table = {
  113. .dev_id = "1-001a", /* Device 001a on I2C bus 1 */
  114. .table = {
  115. GPIO_LOOKUP("GPION", 7,
  116. "wlf,ldo1ena", GPIO_ACTIVE_HIGH),
  117. { },
  118. },
  119. };
  120. static struct wm8996_pdata wm8996_pdata __initdata = {
  121. .micdet_def = 1,
  122. .inl_mode = WM8996_DIFFERRENTIAL_1,
  123. .inr_mode = WM8996_DIFFERRENTIAL_1,
  124. .irq_flags = IRQF_TRIGGER_RISING,
  125. .gpio_default = {
  126. 0x8001, /* GPIO1 == ADCLRCLK1 */
  127. 0x8001, /* GPIO2 == ADCLRCLK2, input due to CPU */
  128. 0x0141, /* GPIO3 == HP_SEL */
  129. 0x0002, /* GPIO4 == IRQ */
  130. 0x020e, /* GPIO5 == CLKOUT */
  131. },
  132. .retune_mobile_cfgs = wm8996_retune,
  133. .num_retune_mobile_cfgs = ARRAY_SIZE(wm8996_retune),
  134. };
  135. static struct wm8962_pdata wm8962_pdata __initdata = {
  136. .gpio_init = {
  137. 0,
  138. WM8962_GPIO_FN_OPCLK,
  139. WM8962_GPIO_FN_DMICCLK,
  140. 0,
  141. 0x8000 | WM8962_GPIO_FN_DMICDAT,
  142. WM8962_GPIO_FN_IRQ, /* Open drain mode */
  143. },
  144. .in4_dc_measure = true,
  145. };
  146. static struct wm9081_pdata wm9081_pdata __initdata = {
  147. .irq_high = false,
  148. .irq_cmos = false,
  149. };
  150. static const struct i2c_board_info wm1254_devs[] = {
  151. { I2C_BOARD_INFO("wm8996", 0x1a),
  152. .platform_data = &wm8996_pdata,
  153. .irq = GLENFARCLAS_PMIC_IRQ_BASE + WM831X_IRQ_GPIO_2,
  154. },
  155. { I2C_BOARD_INFO("wm9081", 0x6c),
  156. .platform_data = &wm9081_pdata, },
  157. };
  158. static const struct i2c_board_info wm1255_devs[] = {
  159. { I2C_BOARD_INFO("wm5100", 0x1a),
  160. .platform_data = &wm5100_pdata,
  161. .irq = GLENFARCLAS_PMIC_IRQ_BASE + WM831X_IRQ_GPIO_2,
  162. },
  163. { I2C_BOARD_INFO("wm9081", 0x6c),
  164. .platform_data = &wm9081_pdata, },
  165. };
  166. static const struct i2c_board_info wm1259_devs[] = {
  167. { I2C_BOARD_INFO("wm8962", 0x1a),
  168. .platform_data = &wm8962_pdata,
  169. .irq = GLENFARCLAS_PMIC_IRQ_BASE + WM831X_IRQ_GPIO_2,
  170. },
  171. };
  172. static struct regulator_init_data wm8994_ldo1 = {
  173. .supply_regulator = "WALLVDD",
  174. };
  175. static struct regulator_init_data wm8994_ldo2 = {
  176. .supply_regulator = "WALLVDD",
  177. };
  178. static struct wm8994_pdata wm8994_pdata = {
  179. .gpio_base = CODEC_GPIO_BASE,
  180. .micb2_delay = 150,
  181. .gpio_defaults = {
  182. 0x3, /* IRQ out, active high, CMOS */
  183. },
  184. .ldo = {
  185. { .init_data = &wm8994_ldo1, },
  186. { .init_data = &wm8994_ldo2, },
  187. },
  188. };
  189. static const struct i2c_board_info wm1277_devs[] = {
  190. { I2C_BOARD_INFO("wm8958", 0x1a), /* WM8958 is the superset */
  191. .platform_data = &wm8994_pdata,
  192. .irq = GLENFARCLAS_PMIC_IRQ_BASE + WM831X_IRQ_GPIO_2,
  193. .dev_name = "wm8958",
  194. },
  195. };
  196. static struct gpiod_lookup_table wm8994_gpiod_table = {
  197. .dev_id = "i2c-wm8958", /* I2C device name */
  198. .table = {
  199. GPIO_LOOKUP("GPION", 6,
  200. "wlf,ldo1ena", GPIO_ACTIVE_HIGH),
  201. GPIO_LOOKUP("GPION", 4,
  202. "wlf,ldo2ena", GPIO_ACTIVE_HIGH),
  203. { },
  204. },
  205. };
  206. static struct arizona_pdata wm5102_reva_pdata = {
  207. .gpio_base = CODEC_GPIO_BASE,
  208. .irq_flags = IRQF_TRIGGER_HIGH,
  209. .micd_pol_gpio = CODEC_GPIO_BASE + 4,
  210. .micd_rate = 6,
  211. .gpio_defaults = {
  212. [2] = 0x10000, /* AIF3TXLRCLK */
  213. [3] = 0x4, /* OPCLK */
  214. },
  215. };
  216. static struct spi_board_info wm5102_reva_spi_devs[] = {
  217. [0] = {
  218. .modalias = "wm5102",
  219. .max_speed_hz = 10 * 1000 * 1000,
  220. .bus_num = 0,
  221. .chip_select = 1,
  222. .mode = SPI_MODE_0,
  223. .irq = GLENFARCLAS_PMIC_IRQ_BASE +
  224. WM831X_IRQ_GPIO_2,
  225. .platform_data = &wm5102_reva_pdata,
  226. },
  227. };
  228. static struct gpiod_lookup_table wm5102_reva_gpiod_table = {
  229. .dev_id = "spi0.1", /* SPI device name */
  230. .table = {
  231. GPIO_LOOKUP("GPION", 7,
  232. "wlf,ldoena", GPIO_ACTIVE_HIGH),
  233. { },
  234. },
  235. };
  236. static struct arizona_pdata wm5102_pdata = {
  237. .gpio_base = CODEC_GPIO_BASE,
  238. .irq_flags = IRQF_TRIGGER_HIGH,
  239. .micd_pol_gpio = CODEC_GPIO_BASE + 2,
  240. .gpio_defaults = {
  241. [2] = 0x10000, /* AIF3TXLRCLK */
  242. [3] = 0x4, /* OPCLK */
  243. },
  244. };
  245. static struct spi_board_info wm5102_spi_devs[] = {
  246. [0] = {
  247. .modalias = "wm5102",
  248. .max_speed_hz = 10 * 1000 * 1000,
  249. .bus_num = 0,
  250. .chip_select = 1,
  251. .mode = SPI_MODE_0,
  252. .irq = GLENFARCLAS_PMIC_IRQ_BASE +
  253. WM831X_IRQ_GPIO_2,
  254. .platform_data = &wm5102_pdata,
  255. },
  256. };
  257. static struct gpiod_lookup_table wm5102_gpiod_table = {
  258. .dev_id = "spi0.1", /* SPI device name */
  259. .table = {
  260. GPIO_LOOKUP("GPION", 7,
  261. "wlf,ldo1ena", GPIO_ACTIVE_HIGH),
  262. { },
  263. },
  264. };
  265. static struct spi_board_info wm5110_spi_devs[] = {
  266. [0] = {
  267. .modalias = "wm5110",
  268. .max_speed_hz = 10 * 1000 * 1000,
  269. .bus_num = 0,
  270. .chip_select = 1,
  271. .mode = SPI_MODE_0,
  272. .irq = GLENFARCLAS_PMIC_IRQ_BASE +
  273. WM831X_IRQ_GPIO_2,
  274. .platform_data = &wm5102_reva_pdata,
  275. },
  276. };
  277. static const struct i2c_board_info wm6230_i2c_devs[] = {
  278. { I2C_BOARD_INFO("wm9081", 0x6c),
  279. .platform_data = &wm9081_pdata, },
  280. };
  281. static struct wm2200_pdata wm2200_pdata = {
  282. .gpio_defaults = {
  283. [2] = 0x0005, /* GPIO3 24.576MHz output clock */
  284. },
  285. };
  286. static struct gpiod_lookup_table wm2200_gpiod_table = {
  287. .dev_id = "1-003a", /* Device 003a on I2C bus 1 */
  288. .table = {
  289. GPIO_LOOKUP("GPION", 7,
  290. "wlf,ldo1ena", GPIO_ACTIVE_HIGH),
  291. { },
  292. },
  293. };
  294. static const struct i2c_board_info wm2200_i2c[] = {
  295. { I2C_BOARD_INFO("wm2200", 0x3a),
  296. .platform_data = &wm2200_pdata, },
  297. };
  298. static const struct {
  299. u8 id;
  300. u8 rev;
  301. const char *name;
  302. const struct i2c_board_info *i2c_devs;
  303. int num_i2c_devs;
  304. const struct spi_board_info *spi_devs;
  305. int num_spi_devs;
  306. struct gpiod_lookup_table *gpiod_table;
  307. } gf_mods[] = {
  308. { .id = 0x01, .rev = 0xff, .name = "1250-EV1 Springbank" },
  309. { .id = 0x02, .rev = 0xff, .name = "1251-EV1 Jura" },
  310. { .id = 0x03, .rev = 0xff, .name = "1252-EV1 Glenlivet" },
  311. { .id = 0x06, .rev = 0xff, .name = "WM8997-6721-CS96-EV1 Lapraoig" },
  312. { .id = 0x07, .rev = 0xff, .name = "WM5110-6271 Deanston",
  313. .spi_devs = wm5110_spi_devs,
  314. .num_spi_devs = ARRAY_SIZE(wm5110_spi_devs) },
  315. { .id = 0x08, .rev = 0xff, .name = "WM8903-6102 Tamdhu" },
  316. { .id = 0x09, .rev = 0xff, .name = "WM1811A-6305 Adelphi" },
  317. { .id = 0x0a, .rev = 0xff, .name = "WM8996-6272 Blackadder" },
  318. { .id = 0x0b, .rev = 0xff, .name = "WM8994-6235 Benromach" },
  319. { .id = 0x11, .rev = 0xff, .name = "6249-EV2 Glenfarclas", },
  320. { .id = 0x14, .rev = 0xff, .name = "6271-EV1 Lochnagar" },
  321. { .id = 0x15, .rev = 0xff, .name = "6320-EV1 Bells",
  322. .i2c_devs = wm6230_i2c_devs,
  323. .num_i2c_devs = ARRAY_SIZE(wm6230_i2c_devs) },
  324. { .id = 0x21, .rev = 0xff, .name = "1275-EV1 Mortlach" },
  325. { .id = 0x25, .rev = 0xff, .name = "1274-EV1 Glencadam" },
  326. { .id = 0x31, .rev = 0xff, .name = "1253-EV1 Tomatin",
  327. .spi_devs = wm1253_devs, .num_spi_devs = ARRAY_SIZE(wm1253_devs),
  328. .gpiod_table = &wm0010_gpiod_table },
  329. { .id = 0x32, .rev = 0xff, .name = "XXXX-EV1 Caol Illa" },
  330. { .id = 0x33, .rev = 0xff, .name = "XXXX-EV1 Oban" },
  331. { .id = 0x34, .rev = 0xff, .name = "WM0010-6320-CS42 Balblair",
  332. .spi_devs = balblair_devs,
  333. .num_spi_devs = ARRAY_SIZE(balblair_devs) },
  334. { .id = 0x39, .rev = 0xff, .name = "1254-EV1 Dallas Dhu",
  335. .i2c_devs = wm1254_devs, .num_i2c_devs = ARRAY_SIZE(wm1254_devs),
  336. .gpiod_table = &wm8996_gpiod_table },
  337. { .id = 0x3a, .rev = 0xff, .name = "1259-EV1 Tobermory",
  338. .i2c_devs = wm1259_devs, .num_i2c_devs = ARRAY_SIZE(wm1259_devs) },
  339. { .id = 0x3b, .rev = 0xff, .name = "1255-EV1 Kilchoman",
  340. .i2c_devs = wm1255_devs, .num_i2c_devs = ARRAY_SIZE(wm1255_devs),
  341. .gpiod_table = &wm5100_gpiod_table },
  342. { .id = 0x3c, .rev = 0xff, .name = "1273-EV1 Longmorn" },
  343. { .id = 0x3d, .rev = 0xff, .name = "1277-EV1 Littlemill",
  344. .i2c_devs = wm1277_devs, .num_i2c_devs = ARRAY_SIZE(wm1277_devs),
  345. .gpiod_table = &wm8994_gpiod_table },
  346. { .id = 0x3e, .rev = 0, .name = "WM5102-6271-EV1-CS127 Amrut",
  347. .spi_devs = wm5102_reva_spi_devs,
  348. .num_spi_devs = ARRAY_SIZE(wm5102_reva_spi_devs),
  349. .gpiod_table = &wm5102_reva_gpiod_table },
  350. { .id = 0x3e, .rev = -1, .name = "WM5102-6271-EV1-CS127 Amrut",
  351. .spi_devs = wm5102_spi_devs,
  352. .num_spi_devs = ARRAY_SIZE(wm5102_spi_devs),
  353. .gpiod_table = &wm5102_gpiod_table },
  354. { .id = 0x3f, .rev = -1, .name = "WM2200-6271-CS90-M-REV1",
  355. .i2c_devs = wm2200_i2c, .num_i2c_devs = ARRAY_SIZE(wm2200_i2c),
  356. .gpiod_table = &wm2200_gpiod_table },
  357. };
  358. static int wlf_gf_module_probe(struct i2c_client *i2c)
  359. {
  360. int ret, i, j, id, rev;
  361. ret = i2c_smbus_read_byte_data(i2c, 0);
  362. if (ret < 0) {
  363. dev_err(&i2c->dev, "Failed to read ID: %d\n", ret);
  364. return ret;
  365. }
  366. id = (ret & 0xfe) >> 2;
  367. rev = ret & 0x3;
  368. for (i = 0; i < ARRAY_SIZE(gf_mods); i++)
  369. if (id == gf_mods[i].id && (gf_mods[i].rev == 0xff ||
  370. rev == gf_mods[i].rev))
  371. break;
  372. gpiod_add_lookup_table(&wm5102_reva_gpiod_table);
  373. gpiod_add_lookup_table(&wm5102_gpiod_table);
  374. gpiod_add_lookup_table(&wm8994_gpiod_table);
  375. if (i < ARRAY_SIZE(gf_mods)) {
  376. dev_info(&i2c->dev, "%s revision %d\n",
  377. gf_mods[i].name, rev + 1);
  378. for (j = 0; j < gf_mods[i].num_i2c_devs; j++) {
  379. if (IS_ERR(i2c_new_client_device(i2c->adapter,
  380. &(gf_mods[i].i2c_devs[j]))))
  381. dev_err(&i2c->dev, "Failed to register\n");
  382. }
  383. spi_register_board_info(gf_mods[i].spi_devs,
  384. gf_mods[i].num_spi_devs);
  385. if (gf_mods[i].gpiod_table)
  386. gpiod_add_lookup_table(gf_mods[i].gpiod_table);
  387. } else {
  388. dev_warn(&i2c->dev, "Unknown module ID 0x%x revision %d\n",
  389. id, rev + 1);
  390. }
  391. return 0;
  392. }
  393. static const struct i2c_device_id wlf_gf_module_id[] = {
  394. { "wlf-gf-module" },
  395. { }
  396. };
  397. static struct i2c_driver wlf_gf_module_driver = {
  398. .driver = {
  399. .name = "wlf-gf-module"
  400. },
  401. .probe = wlf_gf_module_probe,
  402. .id_table = wlf_gf_module_id,
  403. };
  404. static int __init wlf_gf_module_register(void)
  405. {
  406. if (!soc_is_s3c64xx())
  407. return 0;
  408. return i2c_add_driver(&wlf_gf_module_driver);
  409. }
  410. device_initcall(wlf_gf_module_register);