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