Linux Audio

Check our new training course

Loading...
v5.9
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Core MFD support for Cirrus Logic Madera codecs
  4 *
  5 * Copyright (C) 2015-2018 Cirrus Logic
  6 */
  7
  8#include <linux/device.h>
  9#include <linux/delay.h>
 10#include <linux/err.h>
 11#include <linux/gpio.h>
 12#include <linux/mfd/core.h>
 13#include <linux/module.h>
 14#include <linux/mutex.h>
 15#include <linux/notifier.h>
 16#include <linux/of.h>
 17#include <linux/of_gpio.h>
 18#include <linux/platform_device.h>
 19#include <linux/pm_runtime.h>
 20#include <linux/regmap.h>
 21#include <linux/regulator/consumer.h>
 22#include <linux/regulator/machine.h>
 23#include <linux/regulator/of_regulator.h>
 24
 25#include <linux/mfd/madera/core.h>
 26#include <linux/mfd/madera/registers.h>
 27
 28#include "madera.h"
 29
 30#define CS47L15_SILICON_ID	0x6370
 31#define CS47L35_SILICON_ID	0x6360
 32#define CS47L85_SILICON_ID	0x6338
 33#define CS47L90_SILICON_ID	0x6364
 34#define CS47L92_SILICON_ID	0x6371
 35
 36#define MADERA_32KZ_MCLK2	1
 37
 38#define MADERA_RESET_MIN_US	2000
 39#define MADERA_RESET_MAX_US	3000
 40
 
 
 
 41static const char * const madera_core_supplies[] = {
 42	"AVDD",
 43	"DBVDD1",
 44};
 45
 46static const struct mfd_cell madera_ldo1_devs[] = {
 47	{
 48		.name = "madera-ldo1",
 49		.level = MFD_DEP_LEVEL_HIGH,
 50	},
 51};
 52
 53static const char * const cs47l15_supplies[] = {
 54	"MICVDD",
 55	"CPVDD1",
 56	"SPKVDD",
 57};
 58
 59static const struct mfd_cell cs47l15_devs[] = {
 60	{ .name = "madera-pinctrl", },
 61	{ .name = "madera-irq", },
 62	{ .name = "madera-gpio", },
 63	{
 64		.name = "madera-extcon",
 65		.parent_supplies = cs47l15_supplies,
 66		.num_parent_supplies = 1, /* We only need MICVDD */
 67	},
 68	{
 69		.name = "cs47l15-codec",
 70		.parent_supplies = cs47l15_supplies,
 71		.num_parent_supplies = ARRAY_SIZE(cs47l15_supplies),
 72	},
 73};
 74
 75static const char * const cs47l35_supplies[] = {
 76	"MICVDD",
 77	"DBVDD2",
 78	"CPVDD1",
 79	"CPVDD2",
 80	"SPKVDD",
 81};
 82
 83static const struct mfd_cell cs47l35_devs[] = {
 84	{ .name = "madera-pinctrl", },
 85	{ .name = "madera-irq", },
 86	{ .name = "madera-micsupp", },
 87	{ .name = "madera-gpio", },
 88	{
 89		.name = "madera-extcon",
 90		.parent_supplies = cs47l35_supplies,
 91		.num_parent_supplies = 1, /* We only need MICVDD */
 92	},
 93	{
 94		.name = "cs47l35-codec",
 95		.parent_supplies = cs47l35_supplies,
 96		.num_parent_supplies = ARRAY_SIZE(cs47l35_supplies),
 97	},
 98};
 99
100static const char * const cs47l85_supplies[] = {
101	"MICVDD",
102	"DBVDD2",
103	"DBVDD3",
104	"DBVDD4",
105	"CPVDD1",
106	"CPVDD2",
107	"SPKVDDL",
108	"SPKVDDR",
109};
110
111static const struct mfd_cell cs47l85_devs[] = {
112	{ .name = "madera-pinctrl", },
113	{ .name = "madera-irq", },
114	{ .name = "madera-micsupp", },
115	{ .name = "madera-gpio", },
116	{
117		.name = "madera-extcon",
118		.parent_supplies = cs47l85_supplies,
119		.num_parent_supplies = 1, /* We only need MICVDD */
120	},
121	{
122		.name = "cs47l85-codec",
123		.parent_supplies = cs47l85_supplies,
124		.num_parent_supplies = ARRAY_SIZE(cs47l85_supplies),
125	},
126};
127
128static const char * const cs47l90_supplies[] = {
129	"MICVDD",
130	"DBVDD2",
131	"DBVDD3",
132	"DBVDD4",
133	"CPVDD1",
134	"CPVDD2",
135};
136
137static const struct mfd_cell cs47l90_devs[] = {
138	{ .name = "madera-pinctrl", },
139	{ .name = "madera-irq", },
140	{ .name = "madera-micsupp", },
141	{ .name = "madera-gpio", },
142	{
143		.name = "madera-extcon",
144		.parent_supplies = cs47l90_supplies,
145		.num_parent_supplies = 1, /* We only need MICVDD */
146	},
147	{
148		.name = "cs47l90-codec",
149		.parent_supplies = cs47l90_supplies,
150		.num_parent_supplies = ARRAY_SIZE(cs47l90_supplies),
151	},
152};
153
154static const char * const cs47l92_supplies[] = {
155	"MICVDD",
156	"CPVDD1",
157	"CPVDD2",
158};
159
160static const struct mfd_cell cs47l92_devs[] = {
161	{ .name = "madera-pinctrl", },
162	{ .name = "madera-irq", },
163	{ .name = "madera-micsupp", },
164	{ .name = "madera-gpio", },
165	{
166		.name = "madera-extcon",
167		.parent_supplies = cs47l92_supplies,
168		.num_parent_supplies = 1, /* We only need MICVDD */
169	},
170	{
171		.name = "cs47l92-codec",
172		.parent_supplies = cs47l92_supplies,
173		.num_parent_supplies = ARRAY_SIZE(cs47l92_supplies),
174	},
175};
176
177/* Used by madera-i2c and madera-spi drivers */
178const char *madera_name_from_type(enum madera_type type)
179{
180	switch (type) {
181	case CS47L15:
182		return "CS47L15";
183	case CS47L35:
184		return "CS47L35";
185	case CS47L85:
186		return "CS47L85";
187	case CS47L90:
188		return "CS47L90";
189	case CS47L91:
190		return "CS47L91";
191	case CS42L92:
192		return "CS42L92";
193	case CS47L92:
194		return "CS47L92";
195	case CS47L93:
196		return "CS47L93";
197	case WM1840:
198		return "WM1840";
199	default:
200		return "Unknown";
201	}
202}
203EXPORT_SYMBOL_GPL(madera_name_from_type);
204
205#define MADERA_BOOT_POLL_INTERVAL_USEC		5000
206#define MADERA_BOOT_POLL_TIMEOUT_USEC		25000
207
208static int madera_wait_for_boot_noack(struct madera *madera)
209{
210	ktime_t timeout;
211	unsigned int val = 0;
212	int ret = 0;
213
214	/*
215	 * We can't use an interrupt as we need to runtime resume to do so,
216	 * so we poll the status bit. This won't race with the interrupt
217	 * handler because it will be blocked on runtime resume.
218	 * The chip could NAK a read request while it is booting so ignore
219	 * errors from regmap_read.
220	 */
221	timeout = ktime_add_us(ktime_get(), MADERA_BOOT_POLL_TIMEOUT_USEC);
222	regmap_read(madera->regmap, MADERA_IRQ1_RAW_STATUS_1, &val);
223	while (!(val & MADERA_BOOT_DONE_STS1) &&
224	       !ktime_after(ktime_get(), timeout)) {
225		usleep_range(MADERA_BOOT_POLL_INTERVAL_USEC / 2,
226			     MADERA_BOOT_POLL_INTERVAL_USEC);
227		regmap_read(madera->regmap, MADERA_IRQ1_RAW_STATUS_1, &val);
228	}
229
230	if (!(val & MADERA_BOOT_DONE_STS1)) {
231		dev_err(madera->dev, "Polling BOOT_DONE_STS timed out\n");
232		ret = -ETIMEDOUT;
233	}
234
235	return ret;
236}
237
238static int madera_wait_for_boot(struct madera *madera)
239{
240	int ret = madera_wait_for_boot_noack(madera);
241
242	/*
243	 * BOOT_DONE defaults to unmasked on boot so we must ack it.
244	 * Do this even after a timeout to avoid interrupt storms.
245	 */
246	regmap_write(madera->regmap, MADERA_IRQ1_STATUS_1,
247		     MADERA_BOOT_DONE_EINT1);
248
249	pm_runtime_mark_last_busy(madera->dev);
250
251	return ret;
252}
253
254static int madera_soft_reset(struct madera *madera)
255{
256	int ret;
257
258	ret = regmap_write(madera->regmap, MADERA_SOFTWARE_RESET, 0);
259	if (ret != 0) {
260		dev_err(madera->dev, "Failed to soft reset device: %d\n", ret);
261		return ret;
262	}
263
264	/* Allow time for internal clocks to startup after reset */
265	usleep_range(MADERA_RESET_MIN_US, MADERA_RESET_MAX_US);
266
267	return 0;
268}
269
270static void madera_enable_hard_reset(struct madera *madera)
271{
272	/*
273	 * There are many existing out-of-tree users of these codecs that we
274	 * can't break so preserve the expected behaviour of setting the line
275	 * low to assert reset.
276	 */
277	gpiod_set_raw_value_cansleep(madera->pdata.reset, 0);
278}
279
280static void madera_disable_hard_reset(struct madera *madera)
281{
282	gpiod_set_raw_value_cansleep(madera->pdata.reset, 1);
283
284	usleep_range(MADERA_RESET_MIN_US, MADERA_RESET_MAX_US);
285}
286
287static int __maybe_unused madera_runtime_resume(struct device *dev)
288{
289	struct madera *madera = dev_get_drvdata(dev);
290	int ret;
291
292	dev_dbg(dev, "Leaving sleep mode\n");
293
 
 
 
294	ret = regulator_enable(madera->dcvdd);
295	if (ret) {
296		dev_err(dev, "Failed to enable DCVDD: %d\n", ret);
297		return ret;
298	}
299
300	regcache_cache_only(madera->regmap, false);
301	regcache_cache_only(madera->regmap_32bit, false);
302
303	usleep_range(MADERA_RESET_MIN_US, MADERA_RESET_MAX_US);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
304
305	ret = madera_wait_for_boot(madera);
306	if (ret)
307		goto err;
308
309	ret = regcache_sync(madera->regmap);
310	if (ret) {
311		dev_err(dev, "Failed to restore 16-bit register cache\n");
312		goto err;
313	}
314
315	ret = regcache_sync(madera->regmap_32bit);
316	if (ret) {
317		dev_err(dev, "Failed to restore 32-bit register cache\n");
318		goto err;
319	}
320
321	return 0;
322
323err:
324	regcache_cache_only(madera->regmap_32bit, true);
325	regcache_cache_only(madera->regmap, true);
326	regulator_disable(madera->dcvdd);
327
328	return ret;
329}
330
331static int __maybe_unused madera_runtime_suspend(struct device *dev)
332{
333	struct madera *madera = dev_get_drvdata(dev);
334
335	dev_dbg(madera->dev, "Entering sleep mode\n");
336
337	regcache_cache_only(madera->regmap, true);
338	regcache_mark_dirty(madera->regmap);
339	regcache_cache_only(madera->regmap_32bit, true);
340	regcache_mark_dirty(madera->regmap_32bit);
341
342	regulator_disable(madera->dcvdd);
343
344	return 0;
345}
346
347const struct dev_pm_ops madera_pm_ops = {
348	SET_RUNTIME_PM_OPS(madera_runtime_suspend,
349			   madera_runtime_resume,
350			   NULL)
351};
352EXPORT_SYMBOL_GPL(madera_pm_ops);
353
354const struct of_device_id madera_of_match[] = {
355	{ .compatible = "cirrus,cs47l15", .data = (void *)CS47L15 },
356	{ .compatible = "cirrus,cs47l35", .data = (void *)CS47L35 },
357	{ .compatible = "cirrus,cs47l85", .data = (void *)CS47L85 },
358	{ .compatible = "cirrus,cs47l90", .data = (void *)CS47L90 },
359	{ .compatible = "cirrus,cs47l91", .data = (void *)CS47L91 },
360	{ .compatible = "cirrus,cs42l92", .data = (void *)CS42L92 },
361	{ .compatible = "cirrus,cs47l92", .data = (void *)CS47L92 },
362	{ .compatible = "cirrus,cs47l93", .data = (void *)CS47L93 },
363	{ .compatible = "cirrus,wm1840", .data = (void *)WM1840 },
364	{}
365};
366MODULE_DEVICE_TABLE(of, madera_of_match);
367EXPORT_SYMBOL_GPL(madera_of_match);
368
369static int madera_get_reset_gpio(struct madera *madera)
370{
371	struct gpio_desc *reset;
372	int ret;
373
374	if (madera->pdata.reset)
375		return 0;
376
377	reset = devm_gpiod_get_optional(madera->dev, "reset", GPIOD_OUT_LOW);
378	if (IS_ERR(reset)) {
379		ret = PTR_ERR(reset);
380		if (ret != -EPROBE_DEFER)
381			dev_err(madera->dev, "Failed to request /RESET: %d\n",
382				ret);
383		return ret;
384	}
385
386	/*
387	 * A hard reset is needed for full reset of the chip. We allow running
388	 * without hard reset only because it can be useful for early
389	 * prototyping and some debugging, but we need to warn it's not ideal.
390	 */
391	if (!reset)
392		dev_warn(madera->dev,
393			 "Running without reset GPIO is not recommended\n");
394
395	madera->pdata.reset = reset;
396
397	return 0;
398}
399
400static void madera_set_micbias_info(struct madera *madera)
401{
402	/*
403	 * num_childbias is an array because future codecs can have different
404	 * childbiases for each micbias. Unspecified values default to 0.
405	 */
406	switch (madera->type) {
407	case CS47L15:
408		madera->num_micbias = 1;
409		madera->num_childbias[0] = 3;
410		return;
411	case CS47L35:
412		madera->num_micbias = 2;
413		madera->num_childbias[0] = 2;
414		madera->num_childbias[1] = 2;
415		return;
416	case CS47L85:
417	case WM1840:
418		madera->num_micbias = 4;
419		/* no child biases */
420		return;
421	case CS47L90:
422	case CS47L91:
423		madera->num_micbias = 2;
424		madera->num_childbias[0] = 4;
425		madera->num_childbias[1] = 4;
426		return;
427	case CS42L92:
428	case CS47L92:
429	case CS47L93:
430		madera->num_micbias = 2;
431		madera->num_childbias[0] = 4;
432		madera->num_childbias[1] = 2;
433		return;
434	default:
435		return;
436	}
437}
438
439int madera_dev_init(struct madera *madera)
440{
441	struct device *dev = madera->dev;
442	unsigned int hwid;
443	int (*patch_fn)(struct madera *) = NULL;
444	const struct mfd_cell *mfd_devs;
445	int n_devs = 0;
446	int i, ret;
447
448	dev_set_drvdata(madera->dev, madera);
449	BLOCKING_INIT_NOTIFIER_HEAD(&madera->notifier);
450	mutex_init(&madera->dapm_ptr_lock);
451
452	madera_set_micbias_info(madera);
453
454	/*
455	 * We need writable hw config info that all children can share.
456	 * Simplest to take one shared copy of pdata struct.
457	 */
458	if (dev_get_platdata(madera->dev)) {
459		memcpy(&madera->pdata, dev_get_platdata(madera->dev),
460		       sizeof(madera->pdata));
461	}
462
463	madera->mclk[MADERA_MCLK1].id = "mclk1";
464	madera->mclk[MADERA_MCLK2].id = "mclk2";
465	madera->mclk[MADERA_MCLK3].id = "mclk3";
466
467	ret = devm_clk_bulk_get_optional(madera->dev, ARRAY_SIZE(madera->mclk),
468					 madera->mclk);
469	if (ret) {
470		dev_err(madera->dev, "Failed to get clocks: %d\n", ret);
471		return ret;
472	}
473
474	/* Not using devm_clk_get to prevent breakage of existing DTs */
475	if (!madera->mclk[MADERA_MCLK2].clk)
476		dev_warn(madera->dev, "Missing MCLK2, requires 32kHz clock\n");
477
478	ret = madera_get_reset_gpio(madera);
479	if (ret)
480		return ret;
481
482	regcache_cache_only(madera->regmap, true);
483	regcache_cache_only(madera->regmap_32bit, true);
484
485	for (i = 0; i < ARRAY_SIZE(madera_core_supplies); i++)
486		madera->core_supplies[i].supply = madera_core_supplies[i];
487
488	madera->num_core_supplies = ARRAY_SIZE(madera_core_supplies);
489
490	/*
491	 * On some codecs DCVDD could be supplied by the internal LDO1.
492	 * For those we must add the LDO1 driver before requesting DCVDD
493	 * No devm_ because we need to control shutdown order of children.
494	 */
495	switch (madera->type) {
496	case CS47L15:
 
 
497	case CS47L35:
498	case CS47L90:
499	case CS47L91:
500	case CS42L92:
501	case CS47L92:
502	case CS47L93:
503		break;
504	case CS47L85:
505	case WM1840:
506		ret = mfd_add_devices(madera->dev, PLATFORM_DEVID_NONE,
507				      madera_ldo1_devs,
508				      ARRAY_SIZE(madera_ldo1_devs),
509				      NULL, 0, NULL);
510		if (ret) {
511			dev_err(dev, "Failed to add LDO1 child: %d\n", ret);
512			return ret;
513		}
514		break;
515	default:
516		/* No point continuing if the type is unknown */
517		dev_err(madera->dev, "Unknown device type %d\n", madera->type);
518		return -ENODEV;
519	}
520
521	ret = devm_regulator_bulk_get(dev, madera->num_core_supplies,
522				      madera->core_supplies);
523	if (ret) {
524		dev_err(dev, "Failed to request core supplies: %d\n", ret);
525		goto err_devs;
526	}
527
528	/*
529	 * Don't use devres here. If the regulator is one of our children it
530	 * will already have been removed before devres cleanup on this mfd
531	 * driver tries to call put() on it. We need control of shutdown order.
532	 */
533	madera->dcvdd = regulator_get(madera->dev, "DCVDD");
534	if (IS_ERR(madera->dcvdd)) {
535		ret = PTR_ERR(madera->dcvdd);
536		dev_err(dev, "Failed to request DCVDD: %d\n", ret);
537		goto err_devs;
538	}
539
540	ret = regulator_bulk_enable(madera->num_core_supplies,
541				    madera->core_supplies);
542	if (ret) {
543		dev_err(dev, "Failed to enable core supplies: %d\n", ret);
544		goto err_dcvdd;
545	}
546
 
 
 
547	ret = regulator_enable(madera->dcvdd);
548	if (ret) {
549		dev_err(dev, "Failed to enable DCVDD: %d\n", ret);
550		goto err_enable;
551	}
552
553	madera_disable_hard_reset(madera);
 
 
 
554
555	regcache_cache_only(madera->regmap, false);
556	regcache_cache_only(madera->regmap_32bit, false);
557
558	ret = madera_wait_for_boot_noack(madera);
559	if (ret) {
560		dev_err(madera->dev, "Device failed initial boot: %d\n", ret);
561		goto err_reset;
562	}
563
564	/*
565	 * Now we can power up and verify that this is a chip we know about
566	 * before we start doing any writes to its registers.
567	 */
568	ret = regmap_read(madera->regmap, MADERA_SOFTWARE_RESET, &hwid);
569	if (ret) {
570		dev_err(dev, "Failed to read ID register: %d\n", ret);
571		goto err_reset;
572	}
573
574	switch (hwid) {
575	case CS47L15_SILICON_ID:
576		if (IS_ENABLED(CONFIG_MFD_CS47L15)) {
577			switch (madera->type) {
578			case CS47L15:
579				patch_fn = &cs47l15_patch;
580				mfd_devs = cs47l15_devs;
581				n_devs = ARRAY_SIZE(cs47l15_devs);
582				break;
583			default:
584				break;
585			}
586		}
587		break;
588	case CS47L35_SILICON_ID:
589		if (IS_ENABLED(CONFIG_MFD_CS47L35)) {
590			switch (madera->type) {
591			case CS47L35:
592				patch_fn = cs47l35_patch;
593				mfd_devs = cs47l35_devs;
594				n_devs = ARRAY_SIZE(cs47l35_devs);
595				break;
596			default:
597				break;
598			}
599		}
600		break;
601	case CS47L85_SILICON_ID:
602		if (IS_ENABLED(CONFIG_MFD_CS47L85)) {
603			switch (madera->type) {
604			case CS47L85:
605			case WM1840:
606				patch_fn = cs47l85_patch;
607				mfd_devs = cs47l85_devs;
608				n_devs = ARRAY_SIZE(cs47l85_devs);
609				break;
610			default:
611				break;
612			}
613		}
614		break;
615	case CS47L90_SILICON_ID:
616		if (IS_ENABLED(CONFIG_MFD_CS47L90)) {
617			switch (madera->type) {
618			case CS47L90:
619			case CS47L91:
620				patch_fn = cs47l90_patch;
621				mfd_devs = cs47l90_devs;
622				n_devs = ARRAY_SIZE(cs47l90_devs);
623				break;
624			default:
625				break;
626			}
627		}
628		break;
629	case CS47L92_SILICON_ID:
630		if (IS_ENABLED(CONFIG_MFD_CS47L92)) {
631			switch (madera->type) {
632			case CS42L92:
633			case CS47L92:
634			case CS47L93:
635				patch_fn = cs47l92_patch;
636				mfd_devs = cs47l92_devs;
637				n_devs = ARRAY_SIZE(cs47l92_devs);
638				break;
639			default:
640				break;
641			}
642		}
643		break;
644	default:
645		dev_err(madera->dev, "Unknown device ID: %x\n", hwid);
646		ret = -EINVAL;
647		goto err_reset;
648	}
649
650	if (!n_devs) {
651		dev_err(madera->dev, "Device ID 0x%x not a %s\n", hwid,
652			madera->type_name);
653		ret = -ENODEV;
654		goto err_reset;
655	}
656
657	/*
658	 * It looks like a device we support. If we don't have a hard reset
659	 * we can now attempt a soft reset.
660	 */
661	if (!madera->pdata.reset) {
662		ret = madera_soft_reset(madera);
663		if (ret)
664			goto err_reset;
665	}
666
667	ret = madera_wait_for_boot(madera);
668	if (ret) {
669		dev_err(madera->dev, "Failed to clear boot done: %d\n", ret);
670		goto err_reset;
671	}
672
673	ret = regmap_read(madera->regmap, MADERA_HARDWARE_REVISION,
674			  &madera->rev);
675	if (ret) {
676		dev_err(dev, "Failed to read revision register: %d\n", ret);
677		goto err_reset;
678	}
679	madera->rev &= MADERA_HW_REVISION_MASK;
680
681	dev_info(dev, "%s silicon revision %d\n", madera->type_name,
682		 madera->rev);
683
684	/* Apply hardware patch */
685	if (patch_fn) {
686		ret = patch_fn(madera);
687		if (ret) {
688			dev_err(madera->dev, "Failed to apply patch %d\n", ret);
689			goto err_reset;
690		}
691	}
692
693	/* Init 32k clock sourced from MCLK2 */
694	ret = clk_prepare_enable(madera->mclk[MADERA_MCLK2].clk);
695	if (ret) {
696		dev_err(madera->dev, "Failed to enable 32k clock: %d\n", ret);
697		goto err_reset;
698	}
699
700	ret = regmap_update_bits(madera->regmap,
701			MADERA_CLOCK_32K_1,
702			MADERA_CLK_32K_ENA_MASK | MADERA_CLK_32K_SRC_MASK,
703			MADERA_CLK_32K_ENA | MADERA_32KZ_MCLK2);
704	if (ret) {
705		dev_err(madera->dev, "Failed to init 32k clock: %d\n", ret);
706		goto err_clock;
707	}
708
709	pm_runtime_set_active(madera->dev);
710	pm_runtime_enable(madera->dev);
711	pm_runtime_set_autosuspend_delay(madera->dev, 100);
712	pm_runtime_use_autosuspend(madera->dev);
713
714	/* No devm_ because we need to control shutdown order of children */
715	ret = mfd_add_devices(madera->dev, PLATFORM_DEVID_NONE,
716			      mfd_devs, n_devs,
717			      NULL, 0, NULL);
718	if (ret) {
719		dev_err(madera->dev, "Failed to add subdevices: %d\n", ret);
720		goto err_pm_runtime;
721	}
722
723	return 0;
724
725err_pm_runtime:
726	pm_runtime_disable(madera->dev);
727err_clock:
728	clk_disable_unprepare(madera->mclk[MADERA_MCLK2].clk);
729err_reset:
730	madera_enable_hard_reset(madera);
731	regulator_disable(madera->dcvdd);
732err_enable:
733	regulator_bulk_disable(madera->num_core_supplies,
734			       madera->core_supplies);
735err_dcvdd:
736	regulator_put(madera->dcvdd);
737err_devs:
738	mfd_remove_devices(dev);
739
740	return ret;
741}
742EXPORT_SYMBOL_GPL(madera_dev_init);
743
744int madera_dev_exit(struct madera *madera)
745{
746	/* Prevent any IRQs being serviced while we clean up */
747	disable_irq(madera->irq);
748
749	pm_runtime_get_sync(madera->dev);
750
751	mfd_remove_devices(madera->dev);
752
753	pm_runtime_disable(madera->dev);
754
755	regulator_disable(madera->dcvdd);
756	regulator_put(madera->dcvdd);
757
758	mfd_remove_devices_late(madera->dev);
759
760	pm_runtime_set_suspended(madera->dev);
761	pm_runtime_put_noidle(madera->dev);
762
763	clk_disable_unprepare(madera->mclk[MADERA_MCLK2].clk);
764
765	madera_enable_hard_reset(madera);
766
767	regulator_bulk_disable(madera->num_core_supplies,
768			       madera->core_supplies);
769	return 0;
770}
771EXPORT_SYMBOL_GPL(madera_dev_exit);
772
773MODULE_DESCRIPTION("Madera core MFD driver");
774MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
775MODULE_LICENSE("GPL v2");
v6.9.4
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Core MFD support for Cirrus Logic Madera codecs
  4 *
  5 * Copyright (C) 2015-2018 Cirrus Logic
  6 */
  7
  8#include <linux/device.h>
  9#include <linux/delay.h>
 10#include <linux/err.h>
 11#include <linux/gpio/consumer.h>
 12#include <linux/mfd/core.h>
 13#include <linux/module.h>
 14#include <linux/mutex.h>
 15#include <linux/notifier.h>
 16#include <linux/of.h>
 
 17#include <linux/platform_device.h>
 18#include <linux/pm_runtime.h>
 19#include <linux/regmap.h>
 20#include <linux/regulator/consumer.h>
 21#include <linux/regulator/machine.h>
 22#include <linux/regulator/of_regulator.h>
 23
 24#include <linux/mfd/madera/core.h>
 25#include <linux/mfd/madera/registers.h>
 26
 27#include "madera.h"
 28
 29#define CS47L15_SILICON_ID	0x6370
 30#define CS47L35_SILICON_ID	0x6360
 31#define CS47L85_SILICON_ID	0x6338
 32#define CS47L90_SILICON_ID	0x6364
 33#define CS47L92_SILICON_ID	0x6371
 34
 35#define MADERA_32KZ_MCLK2	1
 36
 37#define MADERA_RESET_MIN_US	2000
 38#define MADERA_RESET_MAX_US	3000
 39
 40#define ERRATA_DCVDD_MIN_US	10000
 41#define ERRATA_DCVDD_MAX_US	15000
 42
 43static const char * const madera_core_supplies[] = {
 44	"AVDD",
 45	"DBVDD1",
 46};
 47
 48static const struct mfd_cell madera_ldo1_devs[] = {
 49	{
 50		.name = "madera-ldo1",
 51		.level = MFD_DEP_LEVEL_HIGH,
 52	},
 53};
 54
 55static const char * const cs47l15_supplies[] = {
 56	"MICVDD",
 57	"CPVDD1",
 58	"SPKVDD",
 59};
 60
 61static const struct mfd_cell cs47l15_devs[] = {
 62	{ .name = "madera-pinctrl", },
 63	{ .name = "madera-irq", },
 64	{ .name = "madera-gpio", },
 65	{
 66		.name = "madera-extcon",
 67		.parent_supplies = cs47l15_supplies,
 68		.num_parent_supplies = 1, /* We only need MICVDD */
 69	},
 70	{
 71		.name = "cs47l15-codec",
 72		.parent_supplies = cs47l15_supplies,
 73		.num_parent_supplies = ARRAY_SIZE(cs47l15_supplies),
 74	},
 75};
 76
 77static const char * const cs47l35_supplies[] = {
 78	"MICVDD",
 79	"DBVDD2",
 80	"CPVDD1",
 81	"CPVDD2",
 82	"SPKVDD",
 83};
 84
 85static const struct mfd_cell cs47l35_devs[] = {
 86	{ .name = "madera-pinctrl", },
 87	{ .name = "madera-irq", },
 88	{ .name = "madera-micsupp", },
 89	{ .name = "madera-gpio", },
 90	{
 91		.name = "madera-extcon",
 92		.parent_supplies = cs47l35_supplies,
 93		.num_parent_supplies = 1, /* We only need MICVDD */
 94	},
 95	{
 96		.name = "cs47l35-codec",
 97		.parent_supplies = cs47l35_supplies,
 98		.num_parent_supplies = ARRAY_SIZE(cs47l35_supplies),
 99	},
100};
101
102static const char * const cs47l85_supplies[] = {
103	"MICVDD",
104	"DBVDD2",
105	"DBVDD3",
106	"DBVDD4",
107	"CPVDD1",
108	"CPVDD2",
109	"SPKVDDL",
110	"SPKVDDR",
111};
112
113static const struct mfd_cell cs47l85_devs[] = {
114	{ .name = "madera-pinctrl", },
115	{ .name = "madera-irq", },
116	{ .name = "madera-micsupp", },
117	{ .name = "madera-gpio", },
118	{
119		.name = "madera-extcon",
120		.parent_supplies = cs47l85_supplies,
121		.num_parent_supplies = 1, /* We only need MICVDD */
122	},
123	{
124		.name = "cs47l85-codec",
125		.parent_supplies = cs47l85_supplies,
126		.num_parent_supplies = ARRAY_SIZE(cs47l85_supplies),
127	},
128};
129
130static const char * const cs47l90_supplies[] = {
131	"MICVDD",
132	"DBVDD2",
133	"DBVDD3",
134	"DBVDD4",
135	"CPVDD1",
136	"CPVDD2",
137};
138
139static const struct mfd_cell cs47l90_devs[] = {
140	{ .name = "madera-pinctrl", },
141	{ .name = "madera-irq", },
142	{ .name = "madera-micsupp", },
143	{ .name = "madera-gpio", },
144	{
145		.name = "madera-extcon",
146		.parent_supplies = cs47l90_supplies,
147		.num_parent_supplies = 1, /* We only need MICVDD */
148	},
149	{
150		.name = "cs47l90-codec",
151		.parent_supplies = cs47l90_supplies,
152		.num_parent_supplies = ARRAY_SIZE(cs47l90_supplies),
153	},
154};
155
156static const char * const cs47l92_supplies[] = {
157	"MICVDD",
158	"CPVDD1",
159	"CPVDD2",
160};
161
162static const struct mfd_cell cs47l92_devs[] = {
163	{ .name = "madera-pinctrl", },
164	{ .name = "madera-irq", },
165	{ .name = "madera-micsupp", },
166	{ .name = "madera-gpio", },
167	{
168		.name = "madera-extcon",
169		.parent_supplies = cs47l92_supplies,
170		.num_parent_supplies = 1, /* We only need MICVDD */
171	},
172	{
173		.name = "cs47l92-codec",
174		.parent_supplies = cs47l92_supplies,
175		.num_parent_supplies = ARRAY_SIZE(cs47l92_supplies),
176	},
177};
178
179/* Used by madera-i2c and madera-spi drivers */
180const char *madera_name_from_type(enum madera_type type)
181{
182	switch (type) {
183	case CS47L15:
184		return "CS47L15";
185	case CS47L35:
186		return "CS47L35";
187	case CS47L85:
188		return "CS47L85";
189	case CS47L90:
190		return "CS47L90";
191	case CS47L91:
192		return "CS47L91";
193	case CS42L92:
194		return "CS42L92";
195	case CS47L92:
196		return "CS47L92";
197	case CS47L93:
198		return "CS47L93";
199	case WM1840:
200		return "WM1840";
201	default:
202		return "Unknown";
203	}
204}
205EXPORT_SYMBOL_GPL(madera_name_from_type);
206
207#define MADERA_BOOT_POLL_INTERVAL_USEC		5000
208#define MADERA_BOOT_POLL_TIMEOUT_USEC		25000
209
210static int madera_wait_for_boot_noack(struct madera *madera)
211{
212	ktime_t timeout;
213	unsigned int val = 0;
214	int ret = 0;
215
216	/*
217	 * We can't use an interrupt as we need to runtime resume to do so,
218	 * so we poll the status bit. This won't race with the interrupt
219	 * handler because it will be blocked on runtime resume.
220	 * The chip could NAK a read request while it is booting so ignore
221	 * errors from regmap_read.
222	 */
223	timeout = ktime_add_us(ktime_get(), MADERA_BOOT_POLL_TIMEOUT_USEC);
224	regmap_read(madera->regmap, MADERA_IRQ1_RAW_STATUS_1, &val);
225	while (!(val & MADERA_BOOT_DONE_STS1) &&
226	       !ktime_after(ktime_get(), timeout)) {
227		usleep_range(MADERA_BOOT_POLL_INTERVAL_USEC / 2,
228			     MADERA_BOOT_POLL_INTERVAL_USEC);
229		regmap_read(madera->regmap, MADERA_IRQ1_RAW_STATUS_1, &val);
230	}
231
232	if (!(val & MADERA_BOOT_DONE_STS1)) {
233		dev_err(madera->dev, "Polling BOOT_DONE_STS timed out\n");
234		ret = -ETIMEDOUT;
235	}
236
237	return ret;
238}
239
240static int madera_wait_for_boot(struct madera *madera)
241{
242	int ret = madera_wait_for_boot_noack(madera);
243
244	/*
245	 * BOOT_DONE defaults to unmasked on boot so we must ack it.
246	 * Do this even after a timeout to avoid interrupt storms.
247	 */
248	regmap_write(madera->regmap, MADERA_IRQ1_STATUS_1,
249		     MADERA_BOOT_DONE_EINT1);
250
251	pm_runtime_mark_last_busy(madera->dev);
252
253	return ret;
254}
255
256static int madera_soft_reset(struct madera *madera)
257{
258	int ret;
259
260	ret = regmap_write(madera->regmap, MADERA_SOFTWARE_RESET, 0);
261	if (ret != 0) {
262		dev_err(madera->dev, "Failed to soft reset device: %d\n", ret);
263		return ret;
264	}
265
266	/* Allow time for internal clocks to startup after reset */
267	usleep_range(MADERA_RESET_MIN_US, MADERA_RESET_MAX_US);
268
269	return 0;
270}
271
272static void madera_enable_hard_reset(struct madera *madera)
273{
274	/*
275	 * There are many existing out-of-tree users of these codecs that we
276	 * can't break so preserve the expected behaviour of setting the line
277	 * low to assert reset.
278	 */
279	gpiod_set_raw_value_cansleep(madera->pdata.reset, 0);
280}
281
282static void madera_disable_hard_reset(struct madera *madera)
283{
284	gpiod_set_raw_value_cansleep(madera->pdata.reset, 1);
285
286	usleep_range(MADERA_RESET_MIN_US, MADERA_RESET_MAX_US);
287}
288
289static int __maybe_unused madera_runtime_resume(struct device *dev)
290{
291	struct madera *madera = dev_get_drvdata(dev);
292	int ret;
293
294	dev_dbg(dev, "Leaving sleep mode\n");
295
296	if (!madera->reset_errata)
297		madera_enable_hard_reset(madera);
298
299	ret = regulator_enable(madera->dcvdd);
300	if (ret) {
301		dev_err(dev, "Failed to enable DCVDD: %d\n", ret);
302		return ret;
303	}
304
305	regcache_cache_only(madera->regmap, false);
306	regcache_cache_only(madera->regmap_32bit, false);
307
308	if (madera->reset_errata)
309		usleep_range(ERRATA_DCVDD_MIN_US, ERRATA_DCVDD_MAX_US);
310	else
311		madera_disable_hard_reset(madera);
312
313	if (!madera->pdata.reset || madera->reset_errata) {
314		ret = madera_wait_for_boot(madera);
315		if (ret)
316			goto err;
317
318		ret = madera_soft_reset(madera);
319		if (ret) {
320			dev_err(dev, "Failed to reset: %d\n", ret);
321			goto err;
322		}
323	}
324
325	ret = madera_wait_for_boot(madera);
326	if (ret)
327		goto err;
328
329	ret = regcache_sync(madera->regmap);
330	if (ret) {
331		dev_err(dev, "Failed to restore 16-bit register cache\n");
332		goto err;
333	}
334
335	ret = regcache_sync(madera->regmap_32bit);
336	if (ret) {
337		dev_err(dev, "Failed to restore 32-bit register cache\n");
338		goto err;
339	}
340
341	return 0;
342
343err:
344	regcache_cache_only(madera->regmap_32bit, true);
345	regcache_cache_only(madera->regmap, true);
346	regulator_disable(madera->dcvdd);
347
348	return ret;
349}
350
351static int __maybe_unused madera_runtime_suspend(struct device *dev)
352{
353	struct madera *madera = dev_get_drvdata(dev);
354
355	dev_dbg(madera->dev, "Entering sleep mode\n");
356
357	regcache_cache_only(madera->regmap, true);
358	regcache_mark_dirty(madera->regmap);
359	regcache_cache_only(madera->regmap_32bit, true);
360	regcache_mark_dirty(madera->regmap_32bit);
361
362	regulator_disable(madera->dcvdd);
363
364	return 0;
365}
366
367const struct dev_pm_ops madera_pm_ops = {
368	SET_RUNTIME_PM_OPS(madera_runtime_suspend,
369			   madera_runtime_resume,
370			   NULL)
371};
372EXPORT_SYMBOL_GPL(madera_pm_ops);
373
374const struct of_device_id madera_of_match[] = {
375	{ .compatible = "cirrus,cs47l15", .data = (void *)CS47L15 },
376	{ .compatible = "cirrus,cs47l35", .data = (void *)CS47L35 },
377	{ .compatible = "cirrus,cs47l85", .data = (void *)CS47L85 },
378	{ .compatible = "cirrus,cs47l90", .data = (void *)CS47L90 },
379	{ .compatible = "cirrus,cs47l91", .data = (void *)CS47L91 },
380	{ .compatible = "cirrus,cs42l92", .data = (void *)CS42L92 },
381	{ .compatible = "cirrus,cs47l92", .data = (void *)CS47L92 },
382	{ .compatible = "cirrus,cs47l93", .data = (void *)CS47L93 },
383	{ .compatible = "cirrus,wm1840", .data = (void *)WM1840 },
384	{}
385};
386MODULE_DEVICE_TABLE(of, madera_of_match);
387EXPORT_SYMBOL_GPL(madera_of_match);
388
389static int madera_get_reset_gpio(struct madera *madera)
390{
391	struct gpio_desc *reset;
 
392
393	if (madera->pdata.reset)
394		return 0;
395
396	reset = devm_gpiod_get_optional(madera->dev, "reset", GPIOD_OUT_LOW);
397	if (IS_ERR(reset))
398		return dev_err_probe(madera->dev, PTR_ERR(reset),
399				"Failed to request /RESET");
 
 
 
 
400
401	/*
402	 * A hard reset is needed for full reset of the chip. We allow running
403	 * without hard reset only because it can be useful for early
404	 * prototyping and some debugging, but we need to warn it's not ideal.
405	 */
406	if (!reset)
407		dev_warn(madera->dev,
408			 "Running without reset GPIO is not recommended\n");
409
410	madera->pdata.reset = reset;
411
412	return 0;
413}
414
415static void madera_set_micbias_info(struct madera *madera)
416{
417	/*
418	 * num_childbias is an array because future codecs can have different
419	 * childbiases for each micbias. Unspecified values default to 0.
420	 */
421	switch (madera->type) {
422	case CS47L15:
423		madera->num_micbias = 1;
424		madera->num_childbias[0] = 3;
425		return;
426	case CS47L35:
427		madera->num_micbias = 2;
428		madera->num_childbias[0] = 2;
429		madera->num_childbias[1] = 2;
430		return;
431	case CS47L85:
432	case WM1840:
433		madera->num_micbias = 4;
434		/* no child biases */
435		return;
436	case CS47L90:
437	case CS47L91:
438		madera->num_micbias = 2;
439		madera->num_childbias[0] = 4;
440		madera->num_childbias[1] = 4;
441		return;
442	case CS42L92:
443	case CS47L92:
444	case CS47L93:
445		madera->num_micbias = 2;
446		madera->num_childbias[0] = 4;
447		madera->num_childbias[1] = 2;
448		return;
449	default:
450		return;
451	}
452}
453
454int madera_dev_init(struct madera *madera)
455{
456	struct device *dev = madera->dev;
457	unsigned int hwid;
458	int (*patch_fn)(struct madera *) = NULL;
459	const struct mfd_cell *mfd_devs;
460	int n_devs = 0;
461	int i, ret;
462
463	dev_set_drvdata(madera->dev, madera);
464	BLOCKING_INIT_NOTIFIER_HEAD(&madera->notifier);
465	mutex_init(&madera->dapm_ptr_lock);
466
467	madera_set_micbias_info(madera);
468
469	/*
470	 * We need writable hw config info that all children can share.
471	 * Simplest to take one shared copy of pdata struct.
472	 */
473	if (dev_get_platdata(madera->dev)) {
474		memcpy(&madera->pdata, dev_get_platdata(madera->dev),
475		       sizeof(madera->pdata));
476	}
477
478	madera->mclk[MADERA_MCLK1].id = "mclk1";
479	madera->mclk[MADERA_MCLK2].id = "mclk2";
480	madera->mclk[MADERA_MCLK3].id = "mclk3";
481
482	ret = devm_clk_bulk_get_optional(madera->dev, ARRAY_SIZE(madera->mclk),
483					 madera->mclk);
484	if (ret) {
485		dev_err(madera->dev, "Failed to get clocks: %d\n", ret);
486		return ret;
487	}
488
489	/* Not using devm_clk_get to prevent breakage of existing DTs */
490	if (!madera->mclk[MADERA_MCLK2].clk)
491		dev_warn(madera->dev, "Missing MCLK2, requires 32kHz clock\n");
492
493	ret = madera_get_reset_gpio(madera);
494	if (ret)
495		return ret;
496
497	regcache_cache_only(madera->regmap, true);
498	regcache_cache_only(madera->regmap_32bit, true);
499
500	for (i = 0; i < ARRAY_SIZE(madera_core_supplies); i++)
501		madera->core_supplies[i].supply = madera_core_supplies[i];
502
503	madera->num_core_supplies = ARRAY_SIZE(madera_core_supplies);
504
505	/*
506	 * On some codecs DCVDD could be supplied by the internal LDO1.
507	 * For those we must add the LDO1 driver before requesting DCVDD
508	 * No devm_ because we need to control shutdown order of children.
509	 */
510	switch (madera->type) {
511	case CS47L15:
512		madera->reset_errata = true;
513		break;
514	case CS47L35:
515	case CS47L90:
516	case CS47L91:
517	case CS42L92:
518	case CS47L92:
519	case CS47L93:
520		break;
521	case CS47L85:
522	case WM1840:
523		ret = mfd_add_devices(madera->dev, PLATFORM_DEVID_NONE,
524				      madera_ldo1_devs,
525				      ARRAY_SIZE(madera_ldo1_devs),
526				      NULL, 0, NULL);
527		if (ret) {
528			dev_err(dev, "Failed to add LDO1 child: %d\n", ret);
529			return ret;
530		}
531		break;
532	default:
533		/* No point continuing if the type is unknown */
534		dev_err(madera->dev, "Unknown device type %d\n", madera->type);
535		return -ENODEV;
536	}
537
538	ret = devm_regulator_bulk_get(dev, madera->num_core_supplies,
539				      madera->core_supplies);
540	if (ret) {
541		dev_err(dev, "Failed to request core supplies: %d\n", ret);
542		goto err_devs;
543	}
544
545	/*
546	 * Don't use devres here. If the regulator is one of our children it
547	 * will already have been removed before devres cleanup on this mfd
548	 * driver tries to call put() on it. We need control of shutdown order.
549	 */
550	madera->dcvdd = regulator_get(madera->dev, "DCVDD");
551	if (IS_ERR(madera->dcvdd)) {
552		ret = PTR_ERR(madera->dcvdd);
553		dev_err(dev, "Failed to request DCVDD: %d\n", ret);
554		goto err_devs;
555	}
556
557	ret = regulator_bulk_enable(madera->num_core_supplies,
558				    madera->core_supplies);
559	if (ret) {
560		dev_err(dev, "Failed to enable core supplies: %d\n", ret);
561		goto err_dcvdd;
562	}
563
564	if (madera->reset_errata)
565		madera_disable_hard_reset(madera);
566
567	ret = regulator_enable(madera->dcvdd);
568	if (ret) {
569		dev_err(dev, "Failed to enable DCVDD: %d\n", ret);
570		goto err_enable;
571	}
572
573	if (madera->reset_errata)
574		usleep_range(ERRATA_DCVDD_MIN_US, ERRATA_DCVDD_MAX_US);
575	else
576		madera_disable_hard_reset(madera);
577
578	regcache_cache_only(madera->regmap, false);
579	regcache_cache_only(madera->regmap_32bit, false);
580
581	ret = madera_wait_for_boot_noack(madera);
582	if (ret) {
583		dev_err(madera->dev, "Device failed initial boot: %d\n", ret);
584		goto err_reset;
585	}
586
587	/*
588	 * Now we can power up and verify that this is a chip we know about
589	 * before we start doing any writes to its registers.
590	 */
591	ret = regmap_read(madera->regmap, MADERA_SOFTWARE_RESET, &hwid);
592	if (ret) {
593		dev_err(dev, "Failed to read ID register: %d\n", ret);
594		goto err_reset;
595	}
596
597	switch (hwid) {
598	case CS47L15_SILICON_ID:
599		if (IS_ENABLED(CONFIG_MFD_CS47L15)) {
600			switch (madera->type) {
601			case CS47L15:
602				patch_fn = &cs47l15_patch;
603				mfd_devs = cs47l15_devs;
604				n_devs = ARRAY_SIZE(cs47l15_devs);
605				break;
606			default:
607				break;
608			}
609		}
610		break;
611	case CS47L35_SILICON_ID:
612		if (IS_ENABLED(CONFIG_MFD_CS47L35)) {
613			switch (madera->type) {
614			case CS47L35:
615				patch_fn = cs47l35_patch;
616				mfd_devs = cs47l35_devs;
617				n_devs = ARRAY_SIZE(cs47l35_devs);
618				break;
619			default:
620				break;
621			}
622		}
623		break;
624	case CS47L85_SILICON_ID:
625		if (IS_ENABLED(CONFIG_MFD_CS47L85)) {
626			switch (madera->type) {
627			case CS47L85:
628			case WM1840:
629				patch_fn = cs47l85_patch;
630				mfd_devs = cs47l85_devs;
631				n_devs = ARRAY_SIZE(cs47l85_devs);
632				break;
633			default:
634				break;
635			}
636		}
637		break;
638	case CS47L90_SILICON_ID:
639		if (IS_ENABLED(CONFIG_MFD_CS47L90)) {
640			switch (madera->type) {
641			case CS47L90:
642			case CS47L91:
643				patch_fn = cs47l90_patch;
644				mfd_devs = cs47l90_devs;
645				n_devs = ARRAY_SIZE(cs47l90_devs);
646				break;
647			default:
648				break;
649			}
650		}
651		break;
652	case CS47L92_SILICON_ID:
653		if (IS_ENABLED(CONFIG_MFD_CS47L92)) {
654			switch (madera->type) {
655			case CS42L92:
656			case CS47L92:
657			case CS47L93:
658				patch_fn = cs47l92_patch;
659				mfd_devs = cs47l92_devs;
660				n_devs = ARRAY_SIZE(cs47l92_devs);
661				break;
662			default:
663				break;
664			}
665		}
666		break;
667	default:
668		dev_err(madera->dev, "Unknown device ID: %x\n", hwid);
669		ret = -EINVAL;
670		goto err_reset;
671	}
672
673	if (!n_devs) {
674		dev_err(madera->dev, "Device ID 0x%x not a %s\n", hwid,
675			madera->type_name);
676		ret = -ENODEV;
677		goto err_reset;
678	}
679
680	/*
681	 * It looks like a device we support. If we don't have a hard reset
682	 * we can now attempt a soft reset.
683	 */
684	if (!madera->pdata.reset || madera->reset_errata) {
685		ret = madera_soft_reset(madera);
686		if (ret)
687			goto err_reset;
688	}
689
690	ret = madera_wait_for_boot(madera);
691	if (ret) {
692		dev_err(madera->dev, "Failed to clear boot done: %d\n", ret);
693		goto err_reset;
694	}
695
696	ret = regmap_read(madera->regmap, MADERA_HARDWARE_REVISION,
697			  &madera->rev);
698	if (ret) {
699		dev_err(dev, "Failed to read revision register: %d\n", ret);
700		goto err_reset;
701	}
702	madera->rev &= MADERA_HW_REVISION_MASK;
703
704	dev_info(dev, "%s silicon revision %d\n", madera->type_name,
705		 madera->rev);
706
707	/* Apply hardware patch */
708	if (patch_fn) {
709		ret = patch_fn(madera);
710		if (ret) {
711			dev_err(madera->dev, "Failed to apply patch %d\n", ret);
712			goto err_reset;
713		}
714	}
715
716	/* Init 32k clock sourced from MCLK2 */
717	ret = clk_prepare_enable(madera->mclk[MADERA_MCLK2].clk);
718	if (ret) {
719		dev_err(madera->dev, "Failed to enable 32k clock: %d\n", ret);
720		goto err_reset;
721	}
722
723	ret = regmap_update_bits(madera->regmap,
724			MADERA_CLOCK_32K_1,
725			MADERA_CLK_32K_ENA_MASK | MADERA_CLK_32K_SRC_MASK,
726			MADERA_CLK_32K_ENA | MADERA_32KZ_MCLK2);
727	if (ret) {
728		dev_err(madera->dev, "Failed to init 32k clock: %d\n", ret);
729		goto err_clock;
730	}
731
732	pm_runtime_set_active(madera->dev);
733	pm_runtime_enable(madera->dev);
734	pm_runtime_set_autosuspend_delay(madera->dev, 100);
735	pm_runtime_use_autosuspend(madera->dev);
736
737	/* No devm_ because we need to control shutdown order of children */
738	ret = mfd_add_devices(madera->dev, PLATFORM_DEVID_NONE,
739			      mfd_devs, n_devs,
740			      NULL, 0, NULL);
741	if (ret) {
742		dev_err(madera->dev, "Failed to add subdevices: %d\n", ret);
743		goto err_pm_runtime;
744	}
745
746	return 0;
747
748err_pm_runtime:
749	pm_runtime_disable(madera->dev);
750err_clock:
751	clk_disable_unprepare(madera->mclk[MADERA_MCLK2].clk);
752err_reset:
753	madera_enable_hard_reset(madera);
754	regulator_disable(madera->dcvdd);
755err_enable:
756	regulator_bulk_disable(madera->num_core_supplies,
757			       madera->core_supplies);
758err_dcvdd:
759	regulator_put(madera->dcvdd);
760err_devs:
761	mfd_remove_devices(dev);
762
763	return ret;
764}
765EXPORT_SYMBOL_GPL(madera_dev_init);
766
767int madera_dev_exit(struct madera *madera)
768{
769	/* Prevent any IRQs being serviced while we clean up */
770	disable_irq(madera->irq);
771
772	pm_runtime_get_sync(madera->dev);
773
774	mfd_remove_devices(madera->dev);
775
776	pm_runtime_disable(madera->dev);
777
778	regulator_disable(madera->dcvdd);
779	regulator_put(madera->dcvdd);
780
781	mfd_remove_devices_late(madera->dev);
782
783	pm_runtime_set_suspended(madera->dev);
784	pm_runtime_put_noidle(madera->dev);
785
786	clk_disable_unprepare(madera->mclk[MADERA_MCLK2].clk);
787
788	madera_enable_hard_reset(madera);
789
790	regulator_bulk_disable(madera->num_core_supplies,
791			       madera->core_supplies);
792	return 0;
793}
794EXPORT_SYMBOL_GPL(madera_dev_exit);
795
796MODULE_DESCRIPTION("Madera core MFD driver");
797MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>");
798MODULE_LICENSE("GPL v2");