madera-core.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Core MFD support for Cirrus Logic Madera codecs
  4. *
  5. * Copyright (C) 2015-2018 Cirrus Logic
  6. */
  7. #include <linux/device.h>
  8. #include <linux/delay.h>
  9. #include <linux/err.h>
  10. #include <linux/gpio.h>
  11. #include <linux/mfd/core.h>
  12. #include <linux/module.h>
  13. #include <linux/mutex.h>
  14. #include <linux/notifier.h>
  15. #include <linux/of.h>
  16. #include <linux/of_gpio.h>
  17. #include <linux/platform_device.h>
  18. #include <linux/pm_runtime.h>
  19. #include <linux/regmap.h>
  20. #include <linux/regulator/consumer.h>
  21. #include <linux/regulator/machine.h>
  22. #include <linux/regulator/of_regulator.h>
  23. #include <linux/mfd/madera/core.h>
  24. #include <linux/mfd/madera/registers.h>
  25. #include "madera.h"
  26. #define CS47L15_SILICON_ID 0x6370
  27. #define CS47L35_SILICON_ID 0x6360
  28. #define CS47L85_SILICON_ID 0x6338
  29. #define CS47L90_SILICON_ID 0x6364
  30. #define CS47L92_SILICON_ID 0x6371
  31. #define MADERA_32KZ_MCLK2 1
  32. #define MADERA_RESET_MIN_US 2000
  33. #define MADERA_RESET_MAX_US 3000
  34. #define ERRATA_DCVDD_MIN_US 10000
  35. #define ERRATA_DCVDD_MAX_US 15000
  36. static const char * const madera_core_supplies[] = {
  37. "AVDD",
  38. "DBVDD1",
  39. };
  40. static const struct mfd_cell madera_ldo1_devs[] = {
  41. {
  42. .name = "madera-ldo1",
  43. .level = MFD_DEP_LEVEL_HIGH,
  44. },
  45. };
  46. static const char * const cs47l15_supplies[] = {
  47. "MICVDD",
  48. "CPVDD1",
  49. "SPKVDD",
  50. };
  51. static const struct mfd_cell cs47l15_devs[] = {
  52. { .name = "madera-pinctrl", },
  53. { .name = "madera-irq", },
  54. { .name = "madera-gpio", },
  55. {
  56. .name = "madera-extcon",
  57. .parent_supplies = cs47l15_supplies,
  58. .num_parent_supplies = 1, /* We only need MICVDD */
  59. },
  60. {
  61. .name = "cs47l15-codec",
  62. .parent_supplies = cs47l15_supplies,
  63. .num_parent_supplies = ARRAY_SIZE(cs47l15_supplies),
  64. },
  65. };
  66. static const char * const cs47l35_supplies[] = {
  67. "MICVDD",
  68. "DBVDD2",
  69. "CPVDD1",
  70. "CPVDD2",
  71. "SPKVDD",
  72. };
  73. static const struct mfd_cell cs47l35_devs[] = {
  74. { .name = "madera-pinctrl", },
  75. { .name = "madera-irq", },
  76. { .name = "madera-micsupp", },
  77. { .name = "madera-gpio", },
  78. {
  79. .name = "madera-extcon",
  80. .parent_supplies = cs47l35_supplies,
  81. .num_parent_supplies = 1, /* We only need MICVDD */
  82. },
  83. {
  84. .name = "cs47l35-codec",
  85. .parent_supplies = cs47l35_supplies,
  86. .num_parent_supplies = ARRAY_SIZE(cs47l35_supplies),
  87. },
  88. };
  89. static const char * const cs47l85_supplies[] = {
  90. "MICVDD",
  91. "DBVDD2",
  92. "DBVDD3",
  93. "DBVDD4",
  94. "CPVDD1",
  95. "CPVDD2",
  96. "SPKVDDL",
  97. "SPKVDDR",
  98. };
  99. static const struct mfd_cell cs47l85_devs[] = {
  100. { .name = "madera-pinctrl", },
  101. { .name = "madera-irq", },
  102. { .name = "madera-micsupp", },
  103. { .name = "madera-gpio", },
  104. {
  105. .name = "madera-extcon",
  106. .parent_supplies = cs47l85_supplies,
  107. .num_parent_supplies = 1, /* We only need MICVDD */
  108. },
  109. {
  110. .name = "cs47l85-codec",
  111. .parent_supplies = cs47l85_supplies,
  112. .num_parent_supplies = ARRAY_SIZE(cs47l85_supplies),
  113. },
  114. };
  115. static const char * const cs47l90_supplies[] = {
  116. "MICVDD",
  117. "DBVDD2",
  118. "DBVDD3",
  119. "DBVDD4",
  120. "CPVDD1",
  121. "CPVDD2",
  122. };
  123. static const struct mfd_cell cs47l90_devs[] = {
  124. { .name = "madera-pinctrl", },
  125. { .name = "madera-irq", },
  126. { .name = "madera-micsupp", },
  127. { .name = "madera-gpio", },
  128. {
  129. .name = "madera-extcon",
  130. .parent_supplies = cs47l90_supplies,
  131. .num_parent_supplies = 1, /* We only need MICVDD */
  132. },
  133. {
  134. .name = "cs47l90-codec",
  135. .parent_supplies = cs47l90_supplies,
  136. .num_parent_supplies = ARRAY_SIZE(cs47l90_supplies),
  137. },
  138. };
  139. static const char * const cs47l92_supplies[] = {
  140. "MICVDD",
  141. "CPVDD1",
  142. "CPVDD2",
  143. };
  144. static const struct mfd_cell cs47l92_devs[] = {
  145. { .name = "madera-pinctrl", },
  146. { .name = "madera-irq", },
  147. { .name = "madera-micsupp", },
  148. { .name = "madera-gpio", },
  149. {
  150. .name = "madera-extcon",
  151. .parent_supplies = cs47l92_supplies,
  152. .num_parent_supplies = 1, /* We only need MICVDD */
  153. },
  154. {
  155. .name = "cs47l92-codec",
  156. .parent_supplies = cs47l92_supplies,
  157. .num_parent_supplies = ARRAY_SIZE(cs47l92_supplies),
  158. },
  159. };
  160. /* Used by madera-i2c and madera-spi drivers */
  161. const char *madera_name_from_type(enum madera_type type)
  162. {
  163. switch (type) {
  164. case CS47L15:
  165. return "CS47L15";
  166. case CS47L35:
  167. return "CS47L35";
  168. case CS47L85:
  169. return "CS47L85";
  170. case CS47L90:
  171. return "CS47L90";
  172. case CS47L91:
  173. return "CS47L91";
  174. case CS42L92:
  175. return "CS42L92";
  176. case CS47L92:
  177. return "CS47L92";
  178. case CS47L93:
  179. return "CS47L93";
  180. case WM1840:
  181. return "WM1840";
  182. default:
  183. return "Unknown";
  184. }
  185. }
  186. EXPORT_SYMBOL_GPL(madera_name_from_type);
  187. #define MADERA_BOOT_POLL_INTERVAL_USEC 5000
  188. #define MADERA_BOOT_POLL_TIMEOUT_USEC 25000
  189. static int madera_wait_for_boot_noack(struct madera *madera)
  190. {
  191. ktime_t timeout;
  192. unsigned int val = 0;
  193. int ret = 0;
  194. /*
  195. * We can't use an interrupt as we need to runtime resume to do so,
  196. * so we poll the status bit. This won't race with the interrupt
  197. * handler because it will be blocked on runtime resume.
  198. * The chip could NAK a read request while it is booting so ignore
  199. * errors from regmap_read.
  200. */
  201. timeout = ktime_add_us(ktime_get(), MADERA_BOOT_POLL_TIMEOUT_USEC);
  202. regmap_read(madera->regmap, MADERA_IRQ1_RAW_STATUS_1, &val);
  203. while (!(val & MADERA_BOOT_DONE_STS1) &&
  204. !ktime_after(ktime_get(), timeout)) {
  205. usleep_range(MADERA_BOOT_POLL_INTERVAL_USEC / 2,
  206. MADERA_BOOT_POLL_INTERVAL_USEC);
  207. regmap_read(madera->regmap, MADERA_IRQ1_RAW_STATUS_1, &val);
  208. }
  209. if (!(val & MADERA_BOOT_DONE_STS1)) {
  210. dev_err(madera->dev, "Polling BOOT_DONE_STS timed out\n");
  211. ret = -ETIMEDOUT;
  212. }
  213. return ret;
  214. }
  215. static int madera_wait_for_boot(struct madera *madera)
  216. {
  217. int ret = madera_wait_for_boot_noack(madera);
  218. /*
  219. * BOOT_DONE defaults to unmasked on boot so we must ack it.
  220. * Do this even after a timeout to avoid interrupt storms.
  221. */
  222. regmap_write(madera->regmap, MADERA_IRQ1_STATUS_1,
  223. MADERA_BOOT_DONE_EINT1);
  224. pm_runtime_mark_last_busy(madera->dev);
  225. return ret;
  226. }
  227. static int madera_soft_reset(struct madera *madera)
  228. {
  229. int ret;
  230. ret = regmap_write(madera->regmap, MADERA_SOFTWARE_RESET, 0);
  231. if (ret != 0) {
  232. dev_err(madera->dev, "Failed to soft reset device: %d\n", ret);
  233. return ret;
  234. }
  235. /* Allow time for internal clocks to startup after reset */
  236. usleep_range(MADERA_RESET_MIN_US, MADERA_RESET_MAX_US);
  237. return 0;
  238. }
  239. static void madera_enable_hard_reset(struct madera *madera)
  240. {
  241. /*
  242. * There are many existing out-of-tree users of these codecs that we
  243. * can't break so preserve the expected behaviour of setting the line
  244. * low to assert reset.
  245. */
  246. gpiod_set_raw_value_cansleep(madera->pdata.reset, 0);
  247. }
  248. static void madera_disable_hard_reset(struct madera *madera)
  249. {
  250. gpiod_set_raw_value_cansleep(madera->pdata.reset, 1);
  251. usleep_range(MADERA_RESET_MIN_US, MADERA_RESET_MAX_US);
  252. }
  253. static int __maybe_unused madera_runtime_resume(struct device *dev)
  254. {
  255. struct madera *madera = dev_get_drvdata(dev);
  256. int ret;
  257. dev_dbg(dev, "Leaving sleep mode\n");
  258. if (!madera->reset_errata)
  259. madera_enable_hard_reset(madera);
  260. ret = regulator_enable(madera->dcvdd);
  261. if (ret) {
  262. dev_err(dev, "Failed to enable DCVDD: %d\n", ret);
  263. return ret;
  264. }
  265. regcache_cache_only(madera->regmap, false);
  266. regcache_cache_only(madera->regmap_32bit, false);
  267. if (madera->reset_errata)
  268. usleep_range(ERRATA_DCVDD_MIN_US, ERRATA_DCVDD_MAX_US);
  269. else
  270. madera_disable_hard_reset(madera);
  271. if (!madera->pdata.reset || madera->reset_errata) {
  272. ret = madera_wait_for_boot(madera);
  273. if (ret)
  274. goto err;
  275. ret = madera_soft_reset(madera);
  276. if (ret) {
  277. dev_err(dev, "Failed to reset: %d\n", ret);
  278. goto err;
  279. }
  280. }
  281. ret = madera_wait_for_boot(madera);
  282. if (ret)
  283. goto err;
  284. ret = regcache_sync(madera->regmap);
  285. if (ret) {
  286. dev_err(dev, "Failed to restore 16-bit register cache\n");
  287. goto err;
  288. }
  289. ret = regcache_sync(madera->regmap_32bit);
  290. if (ret) {
  291. dev_err(dev, "Failed to restore 32-bit register cache\n");
  292. goto err;
  293. }
  294. return 0;
  295. err:
  296. regcache_cache_only(madera->regmap_32bit, true);
  297. regcache_cache_only(madera->regmap, true);
  298. regulator_disable(madera->dcvdd);
  299. return ret;
  300. }
  301. static int __maybe_unused madera_runtime_suspend(struct device *dev)
  302. {
  303. struct madera *madera = dev_get_drvdata(dev);
  304. dev_dbg(madera->dev, "Entering sleep mode\n");
  305. regcache_cache_only(madera->regmap, true);
  306. regcache_mark_dirty(madera->regmap);
  307. regcache_cache_only(madera->regmap_32bit, true);
  308. regcache_mark_dirty(madera->regmap_32bit);
  309. regulator_disable(madera->dcvdd);
  310. return 0;
  311. }
  312. const struct dev_pm_ops madera_pm_ops = {
  313. SET_RUNTIME_PM_OPS(madera_runtime_suspend,
  314. madera_runtime_resume,
  315. NULL)
  316. };
  317. EXPORT_SYMBOL_GPL(madera_pm_ops);
  318. const struct of_device_id madera_of_match[] = {
  319. { .compatible = "cirrus,cs47l15", .data = (void *)CS47L15 },
  320. { .compatible = "cirrus,cs47l35", .data = (void *)CS47L35 },
  321. { .compatible = "cirrus,cs47l85", .data = (void *)CS47L85 },
  322. { .compatible = "cirrus,cs47l90", .data = (void *)CS47L90 },
  323. { .compatible = "cirrus,cs47l91", .data = (void *)CS47L91 },
  324. { .compatible = "cirrus,cs42l92", .data = (void *)CS42L92 },
  325. { .compatible = "cirrus,cs47l92", .data = (void *)CS47L92 },
  326. { .compatible = "cirrus,cs47l93", .data = (void *)CS47L93 },
  327. { .compatible = "cirrus,wm1840", .data = (void *)WM1840 },
  328. {}
  329. };
  330. MODULE_DEVICE_TABLE(of, madera_of_match);
  331. EXPORT_SYMBOL_GPL(madera_of_match);
  332. static int madera_get_reset_gpio(struct madera *madera)
  333. {
  334. struct gpio_desc *reset;
  335. if (madera->pdata.reset)
  336. return 0;
  337. reset = devm_gpiod_get_optional(madera->dev, "reset", GPIOD_OUT_LOW);
  338. if (IS_ERR(reset))
  339. return dev_err_probe(madera->dev, PTR_ERR(reset),
  340. "Failed to request /RESET");
  341. /*
  342. * A hard reset is needed for full reset of the chip. We allow running
  343. * without hard reset only because it can be useful for early
  344. * prototyping and some debugging, but we need to warn it's not ideal.
  345. */
  346. if (!reset)
  347. dev_warn(madera->dev,
  348. "Running without reset GPIO is not recommended\n");
  349. madera->pdata.reset = reset;
  350. return 0;
  351. }
  352. static void madera_set_micbias_info(struct madera *madera)
  353. {
  354. /*
  355. * num_childbias is an array because future codecs can have different
  356. * childbiases for each micbias. Unspecified values default to 0.
  357. */
  358. switch (madera->type) {
  359. case CS47L15:
  360. madera->num_micbias = 1;
  361. madera->num_childbias[0] = 3;
  362. return;
  363. case CS47L35:
  364. madera->num_micbias = 2;
  365. madera->num_childbias[0] = 2;
  366. madera->num_childbias[1] = 2;
  367. return;
  368. case CS47L85:
  369. case WM1840:
  370. madera->num_micbias = 4;
  371. /* no child biases */
  372. return;
  373. case CS47L90:
  374. case CS47L91:
  375. madera->num_micbias = 2;
  376. madera->num_childbias[0] = 4;
  377. madera->num_childbias[1] = 4;
  378. return;
  379. case CS42L92:
  380. case CS47L92:
  381. case CS47L93:
  382. madera->num_micbias = 2;
  383. madera->num_childbias[0] = 4;
  384. madera->num_childbias[1] = 2;
  385. return;
  386. default:
  387. return;
  388. }
  389. }
  390. int madera_dev_init(struct madera *madera)
  391. {
  392. struct device *dev = madera->dev;
  393. unsigned int hwid;
  394. int (*patch_fn)(struct madera *) = NULL;
  395. const struct mfd_cell *mfd_devs;
  396. int n_devs = 0;
  397. int i, ret;
  398. dev_set_drvdata(madera->dev, madera);
  399. BLOCKING_INIT_NOTIFIER_HEAD(&madera->notifier);
  400. mutex_init(&madera->dapm_ptr_lock);
  401. madera_set_micbias_info(madera);
  402. /*
  403. * We need writable hw config info that all children can share.
  404. * Simplest to take one shared copy of pdata struct.
  405. */
  406. if (dev_get_platdata(madera->dev)) {
  407. memcpy(&madera->pdata, dev_get_platdata(madera->dev),
  408. sizeof(madera->pdata));
  409. }
  410. madera->mclk[MADERA_MCLK1].id = "mclk1";
  411. madera->mclk[MADERA_MCLK2].id = "mclk2";
  412. madera->mclk[MADERA_MCLK3].id = "mclk3";
  413. ret = devm_clk_bulk_get_optional(madera->dev, ARRAY_SIZE(madera->mclk),
  414. madera->mclk);
  415. if (ret) {
  416. dev_err(madera->dev, "Failed to get clocks: %d\n", ret);
  417. return ret;
  418. }
  419. /* Not using devm_clk_get to prevent breakage of existing DTs */
  420. if (!madera->mclk[MADERA_MCLK2].clk)
  421. dev_warn(madera->dev, "Missing MCLK2, requires 32kHz clock\n");
  422. ret = madera_get_reset_gpio(madera);
  423. if (ret)
  424. return ret;
  425. regcache_cache_only(madera->regmap, true);
  426. regcache_cache_only(madera->regmap_32bit, true);
  427. for (i = 0; i < ARRAY_SIZE(madera_core_supplies); i++)
  428. madera->core_supplies[i].supply = madera_core_supplies[i];
  429. madera->num_core_supplies = ARRAY_SIZE(madera_core_supplies);
  430. /*
  431. * On some codecs DCVDD could be supplied by the internal LDO1.
  432. * For those we must add the LDO1 driver before requesting DCVDD
  433. * No devm_ because we need to control shutdown order of children.
  434. */
  435. switch (madera->type) {
  436. case CS47L15:
  437. madera->reset_errata = true;
  438. break;
  439. case CS47L35:
  440. case CS47L90:
  441. case CS47L91:
  442. case CS42L92:
  443. case CS47L92:
  444. case CS47L93:
  445. break;
  446. case CS47L85:
  447. case WM1840:
  448. ret = mfd_add_devices(madera->dev, PLATFORM_DEVID_NONE,
  449. madera_ldo1_devs,
  450. ARRAY_SIZE(madera_ldo1_devs),
  451. NULL, 0, NULL);
  452. if (ret) {
  453. dev_err(dev, "Failed to add LDO1 child: %d\n", ret);
  454. return ret;
  455. }
  456. break;
  457. default:
  458. /* No point continuing if the type is unknown */
  459. dev_err(madera->dev, "Unknown device type %d\n", madera->type);
  460. return -ENODEV;
  461. }
  462. ret = devm_regulator_bulk_get(dev, madera->num_core_supplies,
  463. madera->core_supplies);
  464. if (ret) {
  465. dev_err(dev, "Failed to request core supplies: %d\n", ret);
  466. goto err_devs;
  467. }
  468. /*
  469. * Don't use devres here. If the regulator is one of our children it
  470. * will already have been removed before devres cleanup on this mfd
  471. * driver tries to call put() on it. We need control of shutdown order.
  472. */
  473. madera->dcvdd = regulator_get(madera->dev, "DCVDD");
  474. if (IS_ERR(madera->dcvdd)) {
  475. ret = PTR_ERR(madera->dcvdd);
  476. dev_err(dev, "Failed to request DCVDD: %d\n", ret);
  477. goto err_devs;
  478. }
  479. ret = regulator_bulk_enable(madera->num_core_supplies,
  480. madera->core_supplies);
  481. if (ret) {
  482. dev_err(dev, "Failed to enable core supplies: %d\n", ret);
  483. goto err_dcvdd;
  484. }
  485. if (madera->reset_errata)
  486. madera_disable_hard_reset(madera);
  487. ret = regulator_enable(madera->dcvdd);
  488. if (ret) {
  489. dev_err(dev, "Failed to enable DCVDD: %d\n", ret);
  490. goto err_enable;
  491. }
  492. if (madera->reset_errata)
  493. usleep_range(ERRATA_DCVDD_MIN_US, ERRATA_DCVDD_MAX_US);
  494. else
  495. madera_disable_hard_reset(madera);
  496. regcache_cache_only(madera->regmap, false);
  497. regcache_cache_only(madera->regmap_32bit, false);
  498. ret = madera_wait_for_boot_noack(madera);
  499. if (ret) {
  500. dev_err(madera->dev, "Device failed initial boot: %d\n", ret);
  501. goto err_reset;
  502. }
  503. /*
  504. * Now we can power up and verify that this is a chip we know about
  505. * before we start doing any writes to its registers.
  506. */
  507. ret = regmap_read(madera->regmap, MADERA_SOFTWARE_RESET, &hwid);
  508. if (ret) {
  509. dev_err(dev, "Failed to read ID register: %d\n", ret);
  510. goto err_reset;
  511. }
  512. switch (hwid) {
  513. case CS47L15_SILICON_ID:
  514. if (IS_ENABLED(CONFIG_MFD_CS47L15)) {
  515. switch (madera->type) {
  516. case CS47L15:
  517. patch_fn = &cs47l15_patch;
  518. mfd_devs = cs47l15_devs;
  519. n_devs = ARRAY_SIZE(cs47l15_devs);
  520. break;
  521. default:
  522. break;
  523. }
  524. }
  525. break;
  526. case CS47L35_SILICON_ID:
  527. if (IS_ENABLED(CONFIG_MFD_CS47L35)) {
  528. switch (madera->type) {
  529. case CS47L35:
  530. patch_fn = cs47l35_patch;
  531. mfd_devs = cs47l35_devs;
  532. n_devs = ARRAY_SIZE(cs47l35_devs);
  533. break;
  534. default:
  535. break;
  536. }
  537. }
  538. break;
  539. case CS47L85_SILICON_ID:
  540. if (IS_ENABLED(CONFIG_MFD_CS47L85)) {
  541. switch (madera->type) {
  542. case CS47L85:
  543. case WM1840:
  544. patch_fn = cs47l85_patch;
  545. mfd_devs = cs47l85_devs;
  546. n_devs = ARRAY_SIZE(cs47l85_devs);
  547. break;
  548. default:
  549. break;
  550. }
  551. }
  552. break;
  553. case CS47L90_SILICON_ID:
  554. if (IS_ENABLED(CONFIG_MFD_CS47L90)) {
  555. switch (madera->type) {
  556. case CS47L90:
  557. case CS47L91:
  558. patch_fn = cs47l90_patch;
  559. mfd_devs = cs47l90_devs;
  560. n_devs = ARRAY_SIZE(cs47l90_devs);
  561. break;
  562. default:
  563. break;
  564. }
  565. }
  566. break;
  567. case CS47L92_SILICON_ID:
  568. if (IS_ENABLED(CONFIG_MFD_CS47L92)) {
  569. switch (madera->type) {
  570. case CS42L92:
  571. case CS47L92:
  572. case CS47L93:
  573. patch_fn = cs47l92_patch;
  574. mfd_devs = cs47l92_devs;
  575. n_devs = ARRAY_SIZE(cs47l92_devs);
  576. break;
  577. default:
  578. break;
  579. }
  580. }
  581. break;
  582. default:
  583. dev_err(madera->dev, "Unknown device ID: %x\n", hwid);
  584. ret = -EINVAL;
  585. goto err_reset;
  586. }
  587. if (!n_devs) {
  588. dev_err(madera->dev, "Device ID 0x%x not a %s\n", hwid,
  589. madera->type_name);
  590. ret = -ENODEV;
  591. goto err_reset;
  592. }
  593. /*
  594. * It looks like a device we support. If we don't have a hard reset
  595. * we can now attempt a soft reset.
  596. */
  597. if (!madera->pdata.reset || madera->reset_errata) {
  598. ret = madera_soft_reset(madera);
  599. if (ret)
  600. goto err_reset;
  601. }
  602. ret = madera_wait_for_boot(madera);
  603. if (ret) {
  604. dev_err(madera->dev, "Failed to clear boot done: %d\n", ret);
  605. goto err_reset;
  606. }
  607. ret = regmap_read(madera->regmap, MADERA_HARDWARE_REVISION,
  608. &madera->rev);
  609. if (ret) {
  610. dev_err(dev, "Failed to read revision register: %d\n", ret);
  611. goto err_reset;
  612. }
  613. madera->rev &= MADERA_HW_REVISION_MASK;
  614. dev_info(dev, "%s silicon revision %d\n", madera->type_name,
  615. madera->rev);
  616. /* Apply hardware patch */
  617. if (patch_fn) {
  618. ret = patch_fn(madera);
  619. if (ret) {
  620. dev_err(madera->dev, "Failed to apply patch %d\n", ret);
  621. goto err_reset;
  622. }
  623. }
  624. /* Init 32k clock sourced from MCLK2 */
  625. ret = clk_prepare_enable(madera->mclk[MADERA_MCLK2].clk);
  626. if (ret) {
  627. dev_err(madera->dev, "Failed to enable 32k clock: %d\n", ret);
  628. goto err_reset;
  629. }
  630. ret = regmap_update_bits(madera->regmap,
  631. MADERA_CLOCK_32K_1,
  632. MADERA_CLK_32K_ENA_MASK | MADERA_CLK_32K_SRC_MASK,
  633. MADERA_CLK_32K_ENA | MADERA_32KZ_MCLK2);
  634. if (ret) {
  635. dev_err(madera->dev, "Failed to init 32k clock: %d\n", ret);
  636. goto err_clock;
  637. }
  638. pm_runtime_set_active(madera->dev);
  639. pm_runtime_enable(madera->dev);
  640. pm_runtime_set_autosuspend_delay(madera->dev, 100);
  641. pm_runtime_use_autosuspend(madera->dev);
  642. /* No devm_ because we need to control shutdown order of children */
  643. ret = mfd_add_devices(madera->dev, PLATFORM_DEVID_NONE,
  644. mfd_devs, n_devs,
  645. NULL, 0, NULL);
  646. if (ret) {
  647. dev_err(madera->dev, "Failed to add subdevices: %d\n", ret);
  648. goto err_pm_runtime;
  649. }
  650. return 0;
  651. err_pm_runtime:
  652. pm_runtime_disable(madera->dev);
  653. err_clock:
  654. clk_disable_unprepare(madera->mclk[MADERA_MCLK2].clk);
  655. err_reset:
  656. madera_enable_hard_reset(madera);
  657. regulator_disable(madera->dcvdd);
  658. err_enable:
  659. regulator_bulk_disable(madera->num_core_supplies,
  660. madera->core_supplies);
  661. err_dcvdd:
  662. regulator_put(madera->dcvdd);
  663. err_devs:
  664. mfd_remove_devices(dev);
  665. return ret;
  666. }
  667. EXPORT_SYMBOL_GPL(madera_dev_init);
  668. int madera_dev_exit(struct madera *madera)
  669. {
  670. /* Prevent any IRQs being serviced while we clean up */
  671. disable_irq(madera->irq);
  672. pm_runtime_get_sync(madera->dev);
  673. mfd_remove_devices(madera->dev);
  674. pm_runtime_disable(madera->dev);
  675. regulator_disable(madera->dcvdd);
  676. regulator_put(madera->dcvdd);
  677. mfd_remove_devices_late(madera->dev);
  678. pm_runtime_set_suspended(madera->dev);
  679. pm_runtime_put_noidle(madera->dev);
  680. clk_disable_unprepare(madera->mclk[MADERA_MCLK2].clk);
  681. madera_enable_hard_reset(madera);
  682. regulator_bulk_disable(madera->num_core_supplies,
  683. madera->core_supplies);
  684. return 0;
  685. }
  686. EXPORT_SYMBOL_GPL(madera_dev_exit);
  687. MODULE_DESCRIPTION("Madera core MFD driver");
  688. MODULE_AUTHOR("Richard Fitzgerald <[email protected]>");
  689. MODULE_LICENSE("GPL v2");