xref: /linux/drivers/mfd/madera-core.c (revision 5aa3709c0a5c026735b0ddd4ec80810a23d65f5b)
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;
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");
621