xref: /openbmc/linux/drivers/mfd/madera-core.c (revision a61127c2)
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 EXPORT_SYMBOL_GPL(madera_of_match);
290 
291 static int madera_get_reset_gpio(struct madera *madera)
292 {
293 	struct gpio_desc *reset;
294 	int ret;
295 
296 	if (madera->pdata.reset)
297 		return 0;
298 
299 	reset = devm_gpiod_get_optional(madera->dev, "reset", GPIOD_OUT_LOW);
300 	if (IS_ERR(reset)) {
301 		ret = PTR_ERR(reset);
302 		if (ret != -EPROBE_DEFER)
303 			dev_err(madera->dev, "Failed to request /RESET: %d\n",
304 				ret);
305 		return ret;
306 	}
307 
308 	/*
309 	 * A hard reset is needed for full reset of the chip. We allow running
310 	 * without hard reset only because it can be useful for early
311 	 * prototyping and some debugging, but we need to warn it's not ideal.
312 	 */
313 	if (!reset)
314 		dev_warn(madera->dev,
315 			 "Running without reset GPIO is not recommended\n");
316 
317 	madera->pdata.reset = reset;
318 
319 	return 0;
320 }
321 
322 static void madera_set_micbias_info(struct madera *madera)
323 {
324 	/*
325 	 * num_childbias is an array because future codecs can have different
326 	 * childbiases for each micbias. Unspecified values default to 0.
327 	 */
328 	switch (madera->type) {
329 	case CS47L35:
330 		madera->num_micbias = 2;
331 		madera->num_childbias[0] = 2;
332 		madera->num_childbias[1] = 2;
333 		return;
334 	case CS47L85:
335 	case WM1840:
336 		madera->num_micbias = 4;
337 		/* no child biases */
338 		return;
339 	case CS47L90:
340 	case CS47L91:
341 		madera->num_micbias = 2;
342 		madera->num_childbias[0] = 4;
343 		madera->num_childbias[1] = 4;
344 		return;
345 	default:
346 		return;
347 	}
348 }
349 
350 int madera_dev_init(struct madera *madera)
351 {
352 	struct device *dev = madera->dev;
353 	unsigned int hwid;
354 	int (*patch_fn)(struct madera *) = NULL;
355 	const struct mfd_cell *mfd_devs;
356 	int n_devs = 0;
357 	int i, ret;
358 
359 	dev_set_drvdata(madera->dev, madera);
360 	BLOCKING_INIT_NOTIFIER_HEAD(&madera->notifier);
361 	mutex_init(&madera->dapm_ptr_lock);
362 
363 	madera_set_micbias_info(madera);
364 
365 	/*
366 	 * We need writable hw config info that all children can share.
367 	 * Simplest to take one shared copy of pdata struct.
368 	 */
369 	if (dev_get_platdata(madera->dev)) {
370 		memcpy(&madera->pdata, dev_get_platdata(madera->dev),
371 		       sizeof(madera->pdata));
372 	}
373 
374 	ret = madera_get_reset_gpio(madera);
375 	if (ret)
376 		return ret;
377 
378 	regcache_cache_only(madera->regmap, true);
379 	regcache_cache_only(madera->regmap_32bit, true);
380 
381 	for (i = 0; i < ARRAY_SIZE(madera_core_supplies); i++)
382 		madera->core_supplies[i].supply = madera_core_supplies[i];
383 
384 	madera->num_core_supplies = ARRAY_SIZE(madera_core_supplies);
385 
386 	/*
387 	 * On some codecs DCVDD could be supplied by the internal LDO1.
388 	 * For those we must add the LDO1 driver before requesting DCVDD
389 	 * No devm_ because we need to control shutdown order of children.
390 	 */
391 	switch (madera->type) {
392 	case CS47L35:
393 	case CS47L90:
394 	case CS47L91:
395 		break;
396 	case CS47L85:
397 	case WM1840:
398 		ret = mfd_add_devices(madera->dev, PLATFORM_DEVID_NONE,
399 				      madera_ldo1_devs,
400 				      ARRAY_SIZE(madera_ldo1_devs),
401 				      NULL, 0, NULL);
402 		if (ret) {
403 			dev_err(dev, "Failed to add LDO1 child: %d\n", ret);
404 			return ret;
405 		}
406 		break;
407 	default:
408 		/* No point continuing if the type is unknown */
409 		dev_err(madera->dev, "Unknown device type %d\n", madera->type);
410 		return -ENODEV;
411 	}
412 
413 	ret = devm_regulator_bulk_get(dev, madera->num_core_supplies,
414 				      madera->core_supplies);
415 	if (ret) {
416 		dev_err(dev, "Failed to request core supplies: %d\n", ret);
417 		goto err_devs;
418 	}
419 
420 	/*
421 	 * Don't use devres here. If the regulator is one of our children it
422 	 * will already have been removed before devres cleanup on this mfd
423 	 * driver tries to call put() on it. We need control of shutdown order.
424 	 */
425 	madera->dcvdd = regulator_get(madera->dev, "DCVDD");
426 	if (IS_ERR(madera->dcvdd)) {
427 		ret = PTR_ERR(madera->dcvdd);
428 		dev_err(dev, "Failed to request DCVDD: %d\n", ret);
429 		goto err_devs;
430 	}
431 
432 	ret = regulator_bulk_enable(madera->num_core_supplies,
433 				    madera->core_supplies);
434 	if (ret) {
435 		dev_err(dev, "Failed to enable core supplies: %d\n", ret);
436 		goto err_dcvdd;
437 	}
438 
439 	ret = regulator_enable(madera->dcvdd);
440 	if (ret) {
441 		dev_err(dev, "Failed to enable DCVDD: %d\n", ret);
442 		goto err_enable;
443 	}
444 
445 	madera_disable_hard_reset(madera);
446 
447 	regcache_cache_only(madera->regmap, false);
448 	regcache_cache_only(madera->regmap_32bit, false);
449 
450 	/*
451 	 * Now we can power up and verify that this is a chip we know about
452 	 * before we start doing any writes to its registers.
453 	 */
454 	ret = regmap_read(madera->regmap, MADERA_SOFTWARE_RESET, &hwid);
455 	if (ret) {
456 		dev_err(dev, "Failed to read ID register: %d\n", ret);
457 		goto err_reset;
458 	}
459 
460 	switch (hwid) {
461 	case CS47L35_SILICON_ID:
462 		if (IS_ENABLED(CONFIG_MFD_CS47L35)) {
463 			switch (madera->type) {
464 			case CS47L35:
465 				patch_fn = cs47l35_patch;
466 				mfd_devs = cs47l35_devs;
467 				n_devs = ARRAY_SIZE(cs47l35_devs);
468 				break;
469 			default:
470 				break;
471 			}
472 		}
473 		break;
474 	case CS47L85_SILICON_ID:
475 		if (IS_ENABLED(CONFIG_MFD_CS47L85)) {
476 			switch (madera->type) {
477 			case CS47L85:
478 			case WM1840:
479 				patch_fn = cs47l85_patch;
480 				mfd_devs = cs47l85_devs;
481 				n_devs = ARRAY_SIZE(cs47l85_devs);
482 				break;
483 			default:
484 				break;
485 			}
486 		}
487 		break;
488 	case CS47L90_SILICON_ID:
489 		if (IS_ENABLED(CONFIG_MFD_CS47L90)) {
490 			switch (madera->type) {
491 			case CS47L90:
492 			case CS47L91:
493 				patch_fn = cs47l90_patch;
494 				mfd_devs = cs47l90_devs;
495 				n_devs = ARRAY_SIZE(cs47l90_devs);
496 				break;
497 			default:
498 				break;
499 			}
500 		}
501 		break;
502 	default:
503 		dev_err(madera->dev, "Unknown device ID: %x\n", hwid);
504 		ret = -EINVAL;
505 		goto err_reset;
506 	}
507 
508 	if (!n_devs) {
509 		dev_err(madera->dev, "Device ID 0x%x not a %s\n", hwid,
510 			madera->type_name);
511 		ret = -ENODEV;
512 		goto err_reset;
513 	}
514 
515 	/*
516 	 * It looks like a device we support. If we don't have a hard reset
517 	 * we can now attempt a soft reset.
518 	 */
519 	if (!madera->pdata.reset) {
520 		ret = madera_soft_reset(madera);
521 		if (ret)
522 			goto err_reset;
523 	}
524 
525 	ret = madera_wait_for_boot(madera);
526 	if (ret) {
527 		dev_err(madera->dev, "Device failed initial boot: %d\n", ret);
528 		goto err_reset;
529 	}
530 
531 	ret = regmap_read(madera->regmap, MADERA_HARDWARE_REVISION,
532 			  &madera->rev);
533 	if (ret) {
534 		dev_err(dev, "Failed to read revision register: %d\n", ret);
535 		goto err_reset;
536 	}
537 	madera->rev &= MADERA_HW_REVISION_MASK;
538 
539 	dev_info(dev, "%s silicon revision %d\n", madera->type_name,
540 		 madera->rev);
541 
542 	/* Apply hardware patch */
543 	if (patch_fn) {
544 		ret = patch_fn(madera);
545 		if (ret) {
546 			dev_err(madera->dev, "Failed to apply patch %d\n", ret);
547 			goto err_reset;
548 		}
549 	}
550 
551 	/* Init 32k clock sourced from MCLK2 */
552 	ret = regmap_update_bits(madera->regmap,
553 			MADERA_CLOCK_32K_1,
554 			MADERA_CLK_32K_ENA_MASK | MADERA_CLK_32K_SRC_MASK,
555 			MADERA_CLK_32K_ENA | MADERA_32KZ_MCLK2);
556 	if (ret) {
557 		dev_err(madera->dev, "Failed to init 32k clock: %d\n", ret);
558 		goto err_reset;
559 	}
560 
561 	pm_runtime_set_active(madera->dev);
562 	pm_runtime_enable(madera->dev);
563 	pm_runtime_set_autosuspend_delay(madera->dev, 100);
564 	pm_runtime_use_autosuspend(madera->dev);
565 
566 	/* No devm_ because we need to control shutdown order of children */
567 	ret = mfd_add_devices(madera->dev, PLATFORM_DEVID_NONE,
568 			      mfd_devs, n_devs,
569 			      NULL, 0, NULL);
570 	if (ret) {
571 		dev_err(madera->dev, "Failed to add subdevices: %d\n", ret);
572 		goto err_pm_runtime;
573 	}
574 
575 	return 0;
576 
577 err_pm_runtime:
578 	pm_runtime_disable(madera->dev);
579 err_reset:
580 	madera_enable_hard_reset(madera);
581 	regulator_disable(madera->dcvdd);
582 err_enable:
583 	regulator_bulk_disable(madera->num_core_supplies,
584 			       madera->core_supplies);
585 err_dcvdd:
586 	regulator_put(madera->dcvdd);
587 err_devs:
588 	mfd_remove_devices(dev);
589 
590 	return ret;
591 }
592 EXPORT_SYMBOL_GPL(madera_dev_init);
593 
594 int madera_dev_exit(struct madera *madera)
595 {
596 	/* Prevent any IRQs being serviced while we clean up */
597 	disable_irq(madera->irq);
598 
599 	/*
600 	 * DCVDD could be supplied by a child node, we must disable it before
601 	 * removing the children, and prevent PM runtime from turning it back on
602 	 */
603 	pm_runtime_disable(madera->dev);
604 
605 	regulator_disable(madera->dcvdd);
606 	regulator_put(madera->dcvdd);
607 
608 	mfd_remove_devices(madera->dev);
609 	madera_enable_hard_reset(madera);
610 
611 	regulator_bulk_disable(madera->num_core_supplies,
612 			       madera->core_supplies);
613 	return 0;
614 }
615 EXPORT_SYMBOL_GPL(madera_dev_exit);
616 
617 MODULE_DESCRIPTION("Madera core MFD driver");
618 MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
619 MODULE_LICENSE("GPL v2");
620