xref: /openbmc/linux/drivers/mfd/madera-core.c (revision da2ef666)
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");
610