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