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