xref: /openbmc/linux/drivers/mfd/wm8994-core.c (revision e7c248a0)
19e501086SMark Brown /*
29e501086SMark Brown  * wm8994-core.c  --  Device access for Wolfson WM8994
39e501086SMark Brown  *
49e501086SMark Brown  * Copyright 2009 Wolfson Microelectronics PLC.
59e501086SMark Brown  *
69e501086SMark Brown  * Author: Mark Brown <broonie@opensource.wolfsonmicro.com>
79e501086SMark Brown  *
89e501086SMark Brown  *  This program is free software; you can redistribute  it and/or modify it
99e501086SMark Brown  *  under  the terms of  the GNU General  Public License as published by the
109e501086SMark Brown  *  Free Software Foundation;  either version 2 of the  License, or (at your
119e501086SMark Brown  *  option) any later version.
129e501086SMark Brown  *
139e501086SMark Brown  */
149e501086SMark Brown 
159e501086SMark Brown #include <linux/kernel.h>
169e501086SMark Brown #include <linux/module.h>
175a0e3ad6STejun Heo #include <linux/slab.h>
189e501086SMark Brown #include <linux/i2c.h>
19d6c645fcSMark Brown #include <linux/err.h>
209e501086SMark Brown #include <linux/delay.h>
219e501086SMark Brown #include <linux/mfd/core.h>
22d450f19eSMark Brown #include <linux/pm_runtime.h>
23d6c645fcSMark Brown #include <linux/regmap.h>
249e501086SMark Brown #include <linux/regulator/consumer.h>
259e501086SMark Brown #include <linux/regulator/machine.h>
269e501086SMark Brown 
279e501086SMark Brown #include <linux/mfd/wm8994/core.h>
289e501086SMark Brown #include <linux/mfd/wm8994/pdata.h>
299e501086SMark Brown #include <linux/mfd/wm8994/registers.h>
309e501086SMark Brown 
31c3f13861SMark Brown #include "wm8994.h"
329e501086SMark Brown 
339e501086SMark Brown /**
349e501086SMark Brown  * wm8994_reg_read: Read a single WM8994 register.
359e501086SMark Brown  *
369e501086SMark Brown  * @wm8994: Device to read from.
379e501086SMark Brown  * @reg: Register to read.
389e501086SMark Brown  */
399e501086SMark Brown int wm8994_reg_read(struct wm8994 *wm8994, unsigned short reg)
409e501086SMark Brown {
41d6c645fcSMark Brown 	unsigned int val;
429e501086SMark Brown 	int ret;
439e501086SMark Brown 
44d6c645fcSMark Brown 	ret = regmap_read(wm8994->regmap, reg, &val);
459e501086SMark Brown 
469e501086SMark Brown 	if (ret < 0)
479e501086SMark Brown 		return ret;
489e501086SMark Brown 	else
49d6c645fcSMark Brown 		return val;
509e501086SMark Brown }
519e501086SMark Brown EXPORT_SYMBOL_GPL(wm8994_reg_read);
529e501086SMark Brown 
539e501086SMark Brown /**
549e501086SMark Brown  * wm8994_bulk_read: Read multiple WM8994 registers
559e501086SMark Brown  *
569e501086SMark Brown  * @wm8994: Device to read from
579e501086SMark Brown  * @reg: First register
589e501086SMark Brown  * @count: Number of registers
59316b6cc0SMark Brown  * @buf: Buffer to fill.  The data will be returned big endian.
609e501086SMark Brown  */
619e501086SMark Brown int wm8994_bulk_read(struct wm8994 *wm8994, unsigned short reg,
629e501086SMark Brown 		     int count, u16 *buf)
639e501086SMark Brown {
64d6c645fcSMark Brown 	return regmap_bulk_read(wm8994->regmap, reg, buf, count);
659e501086SMark Brown }
669e501086SMark Brown 
679e501086SMark Brown /**
689e501086SMark Brown  * wm8994_reg_write: Write a single WM8994 register.
699e501086SMark Brown  *
709e501086SMark Brown  * @wm8994: Device to write to.
719e501086SMark Brown  * @reg: Register to write to.
729e501086SMark Brown  * @val: Value to write.
739e501086SMark Brown  */
749e501086SMark Brown int wm8994_reg_write(struct wm8994 *wm8994, unsigned short reg,
759e501086SMark Brown 		     unsigned short val)
769e501086SMark Brown {
77d6c645fcSMark Brown 	return regmap_write(wm8994->regmap, reg, val);
789e501086SMark Brown }
799e501086SMark Brown EXPORT_SYMBOL_GPL(wm8994_reg_write);
809e501086SMark Brown 
819e501086SMark Brown /**
82e93c5387SMark Brown  * wm8994_bulk_write: Write multiple WM8994 registers
83e93c5387SMark Brown  *
84e93c5387SMark Brown  * @wm8994: Device to write to
85e93c5387SMark Brown  * @reg: First register
86e93c5387SMark Brown  * @count: Number of registers
874277163cSMark Brown  * @buf: Buffer to write from.  Data must be big-endian formatted.
88e93c5387SMark Brown  */
89e93c5387SMark Brown int wm8994_bulk_write(struct wm8994 *wm8994, unsigned short reg,
9007e73fbbSMark Brown 		      int count, const u16 *buf)
91e93c5387SMark Brown {
92d6c645fcSMark Brown 	return regmap_raw_write(wm8994->regmap, reg, buf, count * sizeof(u16));
93e93c5387SMark Brown }
94e93c5387SMark Brown EXPORT_SYMBOL_GPL(wm8994_bulk_write);
95e93c5387SMark Brown 
96e93c5387SMark Brown /**
979e501086SMark Brown  * wm8994_set_bits: Set the value of a bitfield in a WM8994 register
989e501086SMark Brown  *
999e501086SMark Brown  * @wm8994: Device to write to.
1009e501086SMark Brown  * @reg: Register to write to.
1019e501086SMark Brown  * @mask: Mask of bits to set.
1029e501086SMark Brown  * @val: Value to set (unshifted)
1039e501086SMark Brown  */
1049e501086SMark Brown int wm8994_set_bits(struct wm8994 *wm8994, unsigned short reg,
1059e501086SMark Brown 		    unsigned short mask, unsigned short val)
1069e501086SMark Brown {
107d6c645fcSMark Brown 	return regmap_update_bits(wm8994->regmap, reg, mask, val);
1089e501086SMark Brown }
1099e501086SMark Brown EXPORT_SYMBOL_GPL(wm8994_set_bits);
1109e501086SMark Brown 
1119e501086SMark Brown static struct mfd_cell wm8994_regulator_devs[] = {
112d450f19eSMark Brown 	{
113d450f19eSMark Brown 		.name = "wm8994-ldo",
114d450f19eSMark Brown 		.id = 1,
115d450f19eSMark Brown 		.pm_runtime_no_callbacks = true,
116d450f19eSMark Brown 	},
117d450f19eSMark Brown 	{
118d450f19eSMark Brown 		.name = "wm8994-ldo",
119d450f19eSMark Brown 		.id = 2,
120d450f19eSMark Brown 		.pm_runtime_no_callbacks = true,
121d450f19eSMark Brown 	},
1229e501086SMark Brown };
1239e501086SMark Brown 
124c9fbf7e0SMark Brown static struct resource wm8994_codec_resources[] = {
125c9fbf7e0SMark Brown 	{
126c9fbf7e0SMark Brown 		.start = WM8994_IRQ_TEMP_SHUT,
127c9fbf7e0SMark Brown 		.end   = WM8994_IRQ_TEMP_WARN,
128c9fbf7e0SMark Brown 		.flags = IORESOURCE_IRQ,
129c9fbf7e0SMark Brown 	},
130c9fbf7e0SMark Brown };
131c9fbf7e0SMark Brown 
132c9fbf7e0SMark Brown static struct resource wm8994_gpio_resources[] = {
133c9fbf7e0SMark Brown 	{
134c9fbf7e0SMark Brown 		.start = WM8994_IRQ_GPIO(1),
135c9fbf7e0SMark Brown 		.end   = WM8994_IRQ_GPIO(11),
136c9fbf7e0SMark Brown 		.flags = IORESOURCE_IRQ,
137c9fbf7e0SMark Brown 	},
138c9fbf7e0SMark Brown };
139c9fbf7e0SMark Brown 
1409e501086SMark Brown static struct mfd_cell wm8994_devs[] = {
141c9fbf7e0SMark Brown 	{
142c9fbf7e0SMark Brown 		.name = "wm8994-codec",
143c9fbf7e0SMark Brown 		.num_resources = ARRAY_SIZE(wm8994_codec_resources),
144c9fbf7e0SMark Brown 		.resources = wm8994_codec_resources,
145c9fbf7e0SMark Brown 	},
146c9fbf7e0SMark Brown 
147c9fbf7e0SMark Brown 	{
148c9fbf7e0SMark Brown 		.name = "wm8994-gpio",
149c9fbf7e0SMark Brown 		.num_resources = ARRAY_SIZE(wm8994_gpio_resources),
150c9fbf7e0SMark Brown 		.resources = wm8994_gpio_resources,
151d450f19eSMark Brown 		.pm_runtime_no_callbacks = true,
152c9fbf7e0SMark Brown 	},
1539e501086SMark Brown };
1549e501086SMark Brown 
1559e501086SMark Brown /*
1569e501086SMark Brown  * Supplies for the main bulk of CODEC; the LDO supplies are ignored
1579e501086SMark Brown  * and should be handled via the standard regulator API supply
1589e501086SMark Brown  * management.
1599e501086SMark Brown  */
160b1f43bf3SMark Brown static const char *wm1811_main_supplies[] = {
161b1f43bf3SMark Brown 	"DBVDD1",
162b1f43bf3SMark Brown 	"DBVDD2",
163b1f43bf3SMark Brown 	"DBVDD3",
164b1f43bf3SMark Brown 	"DCVDD",
165b1f43bf3SMark Brown 	"AVDD1",
166b1f43bf3SMark Brown 	"AVDD2",
167b1f43bf3SMark Brown 	"CPVDD",
168b1f43bf3SMark Brown 	"SPKVDD1",
169b1f43bf3SMark Brown 	"SPKVDD2",
170b1f43bf3SMark Brown };
171b1f43bf3SMark Brown 
1729e501086SMark Brown static const char *wm8994_main_supplies[] = {
1739e501086SMark Brown 	"DBVDD",
1749e501086SMark Brown 	"DCVDD",
1759e501086SMark Brown 	"AVDD1",
1769e501086SMark Brown 	"AVDD2",
1779e501086SMark Brown 	"CPVDD",
1789e501086SMark Brown 	"SPKVDD1",
1799e501086SMark Brown 	"SPKVDD2",
1809e501086SMark Brown };
1819e501086SMark Brown 
182559e0df6SMark Brown static const char *wm8958_main_supplies[] = {
183559e0df6SMark Brown 	"DBVDD1",
184559e0df6SMark Brown 	"DBVDD2",
185559e0df6SMark Brown 	"DBVDD3",
186559e0df6SMark Brown 	"DCVDD",
187559e0df6SMark Brown 	"AVDD1",
188559e0df6SMark Brown 	"AVDD2",
189559e0df6SMark Brown 	"CPVDD",
190559e0df6SMark Brown 	"SPKVDD1",
191559e0df6SMark Brown 	"SPKVDD2",
192559e0df6SMark Brown };
193559e0df6SMark Brown 
1949e501086SMark Brown #ifdef CONFIG_PM
195d450f19eSMark Brown static int wm8994_suspend(struct device *dev)
1969e501086SMark Brown {
1979e501086SMark Brown 	struct wm8994 *wm8994 = dev_get_drvdata(dev);
1989e501086SMark Brown 	int ret;
1999e501086SMark Brown 
20077bd70e9SMark Brown 	/* Don't actually go through with the suspend if the CODEC is
20177bd70e9SMark Brown 	 * still active (eg, for audio passthrough from CP. */
20277bd70e9SMark Brown 	ret = wm8994_reg_read(wm8994, WM8994_POWER_MANAGEMENT_1);
20377bd70e9SMark Brown 	if (ret < 0) {
20477bd70e9SMark Brown 		dev_err(dev, "Failed to read power status: %d\n", ret);
20577bd70e9SMark Brown 	} else if (ret & WM8994_VMID_SEL_MASK) {
20677bd70e9SMark Brown 		dev_dbg(dev, "CODEC still active, ignoring suspend\n");
20777bd70e9SMark Brown 		return 0;
20877bd70e9SMark Brown 	}
20977bd70e9SMark Brown 
2105f40c6b6SMark Brown 	ret = wm8994_reg_read(wm8994, WM8994_POWER_MANAGEMENT_4);
2115f40c6b6SMark Brown 	if (ret < 0) {
2125f40c6b6SMark Brown 		dev_err(dev, "Failed to read power status: %d\n", ret);
2135f40c6b6SMark Brown 	} else if (ret & (WM8994_AIF2ADCL_ENA | WM8994_AIF2ADCR_ENA |
2145f40c6b6SMark Brown 			  WM8994_AIF1ADC2L_ENA | WM8994_AIF1ADC2R_ENA |
2155f40c6b6SMark Brown 			  WM8994_AIF1ADC1L_ENA | WM8994_AIF1ADC1R_ENA)) {
2165f40c6b6SMark Brown 		dev_dbg(dev, "CODEC still active, ignoring suspend\n");
2175f40c6b6SMark Brown 		return 0;
2185f40c6b6SMark Brown 	}
2195f40c6b6SMark Brown 
2205f40c6b6SMark Brown 	ret = wm8994_reg_read(wm8994, WM8994_POWER_MANAGEMENT_5);
2215f40c6b6SMark Brown 	if (ret < 0) {
2225f40c6b6SMark Brown 		dev_err(dev, "Failed to read power status: %d\n", ret);
2235f40c6b6SMark Brown 	} else if (ret & (WM8994_AIF2DACL_ENA | WM8994_AIF2DACR_ENA |
2245f40c6b6SMark Brown 			  WM8994_AIF1DAC2L_ENA | WM8994_AIF1DAC2R_ENA |
2255f40c6b6SMark Brown 			  WM8994_AIF1DAC1L_ENA | WM8994_AIF1DAC1R_ENA)) {
2265f40c6b6SMark Brown 		dev_dbg(dev, "CODEC still active, ignoring suspend\n");
2275f40c6b6SMark Brown 		return 0;
2285f40c6b6SMark Brown 	}
2295f40c6b6SMark Brown 
2305f40c6b6SMark Brown 	switch (wm8994->type) {
2315f40c6b6SMark Brown 	case WM8958:
232b5488b6eSMark Brown 	case WM1811:
2335f40c6b6SMark Brown 		ret = wm8994_reg_read(wm8994, WM8958_MIC_DETECT_1);
2345f40c6b6SMark Brown 		if (ret < 0) {
2355f40c6b6SMark Brown 			dev_err(dev, "Failed to read power status: %d\n", ret);
2365f40c6b6SMark Brown 		} else if (ret & WM8958_MICD_ENA) {
2375f40c6b6SMark Brown 			dev_dbg(dev, "CODEC still active, ignoring suspend\n");
2385f40c6b6SMark Brown 			return 0;
2395f40c6b6SMark Brown 		}
2405f40c6b6SMark Brown 		break;
2415f40c6b6SMark Brown 	default:
2425f40c6b6SMark Brown 		break;
2435f40c6b6SMark Brown 	}
2445f40c6b6SMark Brown 
245a3462490SMark Brown 	switch (wm8994->type) {
246a3462490SMark Brown 	case WM1811:
247a3462490SMark Brown 		ret = wm8994_reg_read(wm8994, WM8994_ANTIPOP_2);
248a3462490SMark Brown 		if (ret < 0) {
249a3462490SMark Brown 			dev_err(dev, "Failed to read jackdet: %d\n", ret);
250a3462490SMark Brown 		} else if (ret & WM1811_JACKDET_MODE_MASK) {
251a3462490SMark Brown 			dev_dbg(dev, "CODEC still active, ignoring suspend\n");
252a3462490SMark Brown 			return 0;
253a3462490SMark Brown 		}
254a3462490SMark Brown 		break;
255a3462490SMark Brown 	default:
256a3462490SMark Brown 		break;
257a3462490SMark Brown 	}
258a3462490SMark Brown 
259e7c248a0SMark Brown 	switch (wm8994->type) {
260e7c248a0SMark Brown 	case WM1811:
261e7c248a0SMark Brown 		ret = wm8994_reg_read(wm8994, WM8994_ANTIPOP_2);
262e7c248a0SMark Brown 		if (ret < 0) {
263e7c248a0SMark Brown 			dev_err(dev, "Failed to read jackdet: %d\n", ret);
264e7c248a0SMark Brown 		} else if (ret & WM1811_JACKDET_MODE_MASK) {
265e7c248a0SMark Brown 			dev_dbg(dev, "CODEC still active, ignoring suspend\n");
266e7c248a0SMark Brown 			return 0;
267e7c248a0SMark Brown 		}
268e7c248a0SMark Brown 		break;
269e7c248a0SMark Brown 	default:
270e7c248a0SMark Brown 		break;
271e7c248a0SMark Brown 	}
272e7c248a0SMark Brown 
273881de670SMark Brown 	/* Disable LDO pulldowns while the device is suspended if we
274881de670SMark Brown 	 * don't know that something will be driving them. */
275881de670SMark Brown 	if (!wm8994->ldo_ena_always_driven)
276881de670SMark Brown 		wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2,
277881de670SMark Brown 				WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD,
278881de670SMark Brown 				WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD);
279881de670SMark Brown 
280f40dff9eSMark Brown 	/* Explicitly put the device into reset in case regulators
281f40dff9eSMark Brown 	 * don't get disabled in order to ensure consistent restart.
282f40dff9eSMark Brown 	 */
283be79cf2fSMark Brown 	wm8994_reg_write(wm8994, WM8994_SOFTWARE_RESET,
284be79cf2fSMark Brown 			 wm8994_reg_read(wm8994, WM8994_SOFTWARE_RESET));
285f40dff9eSMark Brown 
2863befc925SMark Brown 	regcache_cache_only(wm8994->regmap, true);
287c3f13861SMark Brown 	regcache_mark_dirty(wm8994->regmap);
2889e501086SMark Brown 
2899e501086SMark Brown 	wm8994->suspended = true;
2909e501086SMark Brown 
2919e501086SMark Brown 	ret = regulator_bulk_disable(wm8994->num_supplies,
2929e501086SMark Brown 				     wm8994->supplies);
2939e501086SMark Brown 	if (ret != 0) {
2949e501086SMark Brown 		dev_err(dev, "Failed to disable supplies: %d\n", ret);
2959e501086SMark Brown 		return ret;
296d450f19eSMark Brown 	}
2979e501086SMark Brown 
2989e501086SMark Brown 	return 0;
2999e501086SMark Brown }
3009e501086SMark Brown 
30177bd70e9SMark Brown static int wm8994_resume(struct device *dev)
30277bd70e9SMark Brown {
30377bd70e9SMark Brown 	struct wm8994 *wm8994 = dev_get_drvdata(dev);
304c3f13861SMark Brown 	int ret;
3059e501086SMark Brown 
30677bd70e9SMark Brown 	/* We may have lied to the PM core about suspending */
30777bd70e9SMark Brown 	if (!wm8994->suspended)
30877bd70e9SMark Brown 		return 0;
30977bd70e9SMark Brown 
310559e0df6SMark Brown 	ret = regulator_bulk_enable(wm8994->num_supplies,
3119e501086SMark Brown 				    wm8994->supplies);
3129e501086SMark Brown 	if (ret != 0) {
3139e501086SMark Brown 		dev_err(dev, "Failed to enable supplies: %d\n", ret);
3149e501086SMark Brown 		return ret;
3159e501086SMark Brown 	}
3169e501086SMark Brown 
3173befc925SMark Brown 	regcache_cache_only(wm8994->regmap, false);
318c3f13861SMark Brown 	ret = regcache_sync(wm8994->regmap);
319c3f13861SMark Brown 	if (ret != 0) {
320c3f13861SMark Brown 		dev_err(dev, "Failed to restore register map: %d\n", ret);
321c3f13861SMark Brown 		goto err_enable;
32298ae1ccaSMark Brown 	}
323c9fbf7e0SMark Brown 
324881de670SMark Brown 	/* Disable LDO pulldowns while the device is active */
325881de670SMark Brown 	wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2,
326881de670SMark Brown 			WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD,
327881de670SMark Brown 			0);
328881de670SMark Brown 
32977bd70e9SMark Brown 	wm8994->suspended = false;
33077bd70e9SMark Brown 
3319e501086SMark Brown 	return 0;
332c3f13861SMark Brown 
333c3f13861SMark Brown err_enable:
334c3f13861SMark Brown 	regulator_bulk_disable(wm8994->num_supplies, wm8994->supplies);
335c3f13861SMark Brown 
336c3f13861SMark Brown 	return ret;
3379e501086SMark Brown }
3389e501086SMark Brown #endif
3399e501086SMark Brown 
3409e501086SMark Brown #ifdef CONFIG_REGULATOR
3419e501086SMark Brown static int wm8994_ldo_in_use(struct wm8994_pdata *pdata, int ldo)
3429e501086SMark Brown {
3439e501086SMark Brown 	struct wm8994_ldo_pdata *ldo_pdata;
3449e501086SMark Brown 
3459e501086SMark Brown 	if (!pdata)
3469e501086SMark Brown 		return 0;
3479e501086SMark Brown 
3489e501086SMark Brown 	ldo_pdata = &pdata->ldo[ldo];
3499e501086SMark Brown 
3509e501086SMark Brown 	if (!ldo_pdata->init_data)
3519e501086SMark Brown 		return 0;
3529e501086SMark Brown 
3539e501086SMark Brown 	return ldo_pdata->init_data->num_consumer_supplies != 0;
3549e501086SMark Brown }
3559e501086SMark Brown #else
3569e501086SMark Brown static int wm8994_ldo_in_use(struct wm8994_pdata *pdata, int ldo)
3579e501086SMark Brown {
3589e501086SMark Brown 	return 0;
3599e501086SMark Brown }
3609e501086SMark Brown #endif
3619e501086SMark Brown 
3629e501086SMark Brown /*
3639e501086SMark Brown  * Instantiate the generic non-control parts of the device.
3649e501086SMark Brown  */
365559e0df6SMark Brown static int wm8994_device_init(struct wm8994 *wm8994, int irq)
3669e501086SMark Brown {
3679e501086SMark Brown 	struct wm8994_pdata *pdata = wm8994->dev->platform_data;
36834697898SMark Brown 	struct regmap_config *regmap_config;
369559e0df6SMark Brown 	const char *devname;
3709e501086SMark Brown 	int ret, i;
37126c34c25SMark Brown 	int pulls = 0;
3729e501086SMark Brown 
3739e501086SMark Brown 	dev_set_drvdata(wm8994->dev, wm8994);
3749e501086SMark Brown 
3759e501086SMark Brown 	/* Add the on-chip regulators first for bootstrapping */
3769e501086SMark Brown 	ret = mfd_add_devices(wm8994->dev, -1,
3779e501086SMark Brown 			      wm8994_regulator_devs,
3789e501086SMark Brown 			      ARRAY_SIZE(wm8994_regulator_devs),
3799e501086SMark Brown 			      NULL, 0);
3809e501086SMark Brown 	if (ret != 0) {
3819e501086SMark Brown 		dev_err(wm8994->dev, "Failed to add children: %d\n", ret);
382d6c645fcSMark Brown 		goto err_regmap;
3839e501086SMark Brown 	}
3849e501086SMark Brown 
385559e0df6SMark Brown 	switch (wm8994->type) {
386b1f43bf3SMark Brown 	case WM1811:
387b1f43bf3SMark Brown 		wm8994->num_supplies = ARRAY_SIZE(wm1811_main_supplies);
388b1f43bf3SMark Brown 		break;
389559e0df6SMark Brown 	case WM8994:
390559e0df6SMark Brown 		wm8994->num_supplies = ARRAY_SIZE(wm8994_main_supplies);
391559e0df6SMark Brown 		break;
392559e0df6SMark Brown 	case WM8958:
393559e0df6SMark Brown 		wm8994->num_supplies = ARRAY_SIZE(wm8958_main_supplies);
394559e0df6SMark Brown 		break;
395559e0df6SMark Brown 	default:
396559e0df6SMark Brown 		BUG();
397d6c645fcSMark Brown 		goto err_regmap;
398559e0df6SMark Brown 	}
399559e0df6SMark Brown 
4002fa33494SMark Brown 	wm8994->supplies = devm_kzalloc(wm8994->dev,
4012fa33494SMark Brown 					sizeof(struct regulator_bulk_data) *
4022fa33494SMark Brown 					wm8994->num_supplies, GFP_KERNEL);
403fccbd21fSAxel Lin 	if (!wm8994->supplies) {
404fccbd21fSAxel Lin 		ret = -ENOMEM;
405d6c645fcSMark Brown 		goto err_regmap;
406fccbd21fSAxel Lin 	}
4079e501086SMark Brown 
408559e0df6SMark Brown 	switch (wm8994->type) {
409b1f43bf3SMark Brown 	case WM1811:
410b1f43bf3SMark Brown 		for (i = 0; i < ARRAY_SIZE(wm1811_main_supplies); i++)
411b1f43bf3SMark Brown 			wm8994->supplies[i].supply = wm1811_main_supplies[i];
412b1f43bf3SMark Brown 		break;
413559e0df6SMark Brown 	case WM8994:
4149e501086SMark Brown 		for (i = 0; i < ARRAY_SIZE(wm8994_main_supplies); i++)
4159e501086SMark Brown 			wm8994->supplies[i].supply = wm8994_main_supplies[i];
416559e0df6SMark Brown 		break;
417559e0df6SMark Brown 	case WM8958:
418559e0df6SMark Brown 		for (i = 0; i < ARRAY_SIZE(wm8958_main_supplies); i++)
419559e0df6SMark Brown 			wm8994->supplies[i].supply = wm8958_main_supplies[i];
420559e0df6SMark Brown 		break;
421559e0df6SMark Brown 	default:
422559e0df6SMark Brown 		BUG();
423d6c645fcSMark Brown 		goto err_regmap;
424559e0df6SMark Brown 	}
4259e501086SMark Brown 
426559e0df6SMark Brown 	ret = regulator_bulk_get(wm8994->dev, wm8994->num_supplies,
4279e501086SMark Brown 				 wm8994->supplies);
4289e501086SMark Brown 	if (ret != 0) {
4299e501086SMark Brown 		dev_err(wm8994->dev, "Failed to get supplies: %d\n", ret);
4302fa33494SMark Brown 		goto err_regmap;
4319e501086SMark Brown 	}
4329e501086SMark Brown 
433559e0df6SMark Brown 	ret = regulator_bulk_enable(wm8994->num_supplies,
4349e501086SMark Brown 				    wm8994->supplies);
4359e501086SMark Brown 	if (ret != 0) {
4369e501086SMark Brown 		dev_err(wm8994->dev, "Failed to enable supplies: %d\n", ret);
4377731074aSJoonyoung Shim 		goto err_get;
4389e501086SMark Brown 	}
4399e501086SMark Brown 
4409e501086SMark Brown 	ret = wm8994_reg_read(wm8994, WM8994_SOFTWARE_RESET);
4419e501086SMark Brown 	if (ret < 0) {
4429e501086SMark Brown 		dev_err(wm8994->dev, "Failed to read ID register\n");
4439e501086SMark Brown 		goto err_enable;
4449e501086SMark Brown 	}
445559e0df6SMark Brown 	switch (ret) {
446b1f43bf3SMark Brown 	case 0x1811:
447b1f43bf3SMark Brown 		devname = "WM1811";
448b1f43bf3SMark Brown 		if (wm8994->type != WM1811)
449b1f43bf3SMark Brown 			dev_warn(wm8994->dev, "Device registered as type %d\n",
450b1f43bf3SMark Brown 				 wm8994->type);
451b1f43bf3SMark Brown 		wm8994->type = WM1811;
452b1f43bf3SMark Brown 		break;
453559e0df6SMark Brown 	case 0x8994:
454559e0df6SMark Brown 		devname = "WM8994";
455559e0df6SMark Brown 		if (wm8994->type != WM8994)
456559e0df6SMark Brown 			dev_warn(wm8994->dev, "Device registered as type %d\n",
457559e0df6SMark Brown 				 wm8994->type);
458559e0df6SMark Brown 		wm8994->type = WM8994;
459559e0df6SMark Brown 		break;
460559e0df6SMark Brown 	case 0x8958:
461559e0df6SMark Brown 		devname = "WM8958";
462559e0df6SMark Brown 		if (wm8994->type != WM8958)
463559e0df6SMark Brown 			dev_warn(wm8994->dev, "Device registered as type %d\n",
464559e0df6SMark Brown 				 wm8994->type);
465559e0df6SMark Brown 		wm8994->type = WM8958;
466559e0df6SMark Brown 		break;
467559e0df6SMark Brown 	default:
4689e501086SMark Brown 		dev_err(wm8994->dev, "Device is not a WM8994, ID is %x\n",
4699e501086SMark Brown 			ret);
4709e501086SMark Brown 		ret = -EINVAL;
4719e501086SMark Brown 		goto err_enable;
4729e501086SMark Brown 	}
4739e501086SMark Brown 
4749e501086SMark Brown 	ret = wm8994_reg_read(wm8994, WM8994_CHIP_REVISION);
4759e501086SMark Brown 	if (ret < 0) {
4769e501086SMark Brown 		dev_err(wm8994->dev, "Failed to read revision register: %d\n",
4779e501086SMark Brown 			ret);
4789e501086SMark Brown 		goto err_enable;
4799e501086SMark Brown 	}
4807ed5849cSMark Brown 	wm8994->revision = ret;
4819e501086SMark Brown 
482a2495bc7SMark Brown 	switch (wm8994->type) {
483a2495bc7SMark Brown 	case WM8994:
4847ed5849cSMark Brown 		switch (wm8994->revision) {
4859e501086SMark Brown 		case 0:
4869e501086SMark Brown 		case 1:
487559e0df6SMark Brown 			dev_warn(wm8994->dev,
488559e0df6SMark Brown 				 "revision %c not fully supported\n",
4897ed5849cSMark Brown 				 'A' + wm8994->revision);
4909e501086SMark Brown 			break;
4919e501086SMark Brown 		default:
4929e501086SMark Brown 			break;
4939e501086SMark Brown 		}
494a2495bc7SMark Brown 		break;
495443e67edSMark Brown 	case WM1811:
496443e67edSMark Brown 		/* Revision C did not change the relevant layer */
4977ed5849cSMark Brown 		if (wm8994->revision > 1)
4987ed5849cSMark Brown 			wm8994->revision++;
499443e67edSMark Brown 		break;
500a2495bc7SMark Brown 	default:
501a2495bc7SMark Brown 		break;
502a2495bc7SMark Brown 	}
5039e501086SMark Brown 
5047ed5849cSMark Brown 	dev_info(wm8994->dev, "%s revision %c\n", devname,
5057ed5849cSMark Brown 		 'A' + wm8994->revision);
5069e501086SMark Brown 
50734697898SMark Brown 	switch (wm8994->type) {
50834697898SMark Brown 	case WM1811:
50934697898SMark Brown 		regmap_config = &wm1811_regmap_config;
51034697898SMark Brown 		break;
51134697898SMark Brown 	case WM8994:
51234697898SMark Brown 		regmap_config = &wm8994_regmap_config;
51334697898SMark Brown 		break;
51434697898SMark Brown 	case WM8958:
51534697898SMark Brown 		regmap_config = &wm8958_regmap_config;
51634697898SMark Brown 		break;
51734697898SMark Brown 	default:
51834697898SMark Brown 		dev_err(wm8994->dev, "Unknown device type %d\n", wm8994->type);
51934697898SMark Brown 		return -EINVAL;
52034697898SMark Brown 	}
52134697898SMark Brown 
52234697898SMark Brown 	ret = regmap_reinit_cache(wm8994->regmap, regmap_config);
52334697898SMark Brown 	if (ret != 0) {
52434697898SMark Brown 		dev_err(wm8994->dev, "Failed to reinit register cache: %d\n",
52534697898SMark Brown 			ret);
52634697898SMark Brown 		return ret;
52734697898SMark Brown 	}
5289e501086SMark Brown 
5299e501086SMark Brown 	if (pdata) {
530c9fbf7e0SMark Brown 		wm8994->irq_base = pdata->irq_base;
5319e501086SMark Brown 		wm8994->gpio_base = pdata->gpio_base;
5329e501086SMark Brown 
5339e501086SMark Brown 		/* GPIO configuration is only applied if it's non-zero */
5349e501086SMark Brown 		for (i = 0; i < ARRAY_SIZE(pdata->gpio_defaults); i++) {
5359e501086SMark Brown 			if (pdata->gpio_defaults[i]) {
5369e501086SMark Brown 				wm8994_set_bits(wm8994, WM8994_GPIO_1 + i,
5379e501086SMark Brown 						0xffff,
5389e501086SMark Brown 						pdata->gpio_defaults[i]);
5399e501086SMark Brown 			}
5409e501086SMark Brown 		}
541881de670SMark Brown 
542881de670SMark Brown 		wm8994->ldo_ena_always_driven = pdata->ldo_ena_always_driven;
54326c34c25SMark Brown 
54426c34c25SMark Brown 		if (pdata->spkmode_pu)
54526c34c25SMark Brown 			pulls |= WM8994_SPKMODE_PU;
5469e501086SMark Brown 	}
5479e501086SMark Brown 
54826c34c25SMark Brown 	/* Disable unneeded pulls */
549881de670SMark Brown 	wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2,
55026c34c25SMark Brown 			WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD |
55126c34c25SMark Brown 			WM8994_SPKMODE_PU | WM8994_CSNADDR_PD,
55226c34c25SMark Brown 			pulls);
553881de670SMark Brown 
5549e501086SMark Brown 	/* In some system designs where the regulators are not in use,
5559e501086SMark Brown 	 * we can achieve a small reduction in leakage currents by
5569e501086SMark Brown 	 * floating LDO outputs.  This bit makes no difference if the
5579e501086SMark Brown 	 * LDOs are enabled, it only affects cases where the LDOs were
5589e501086SMark Brown 	 * in operation and are then disabled.
5599e501086SMark Brown 	 */
5609e501086SMark Brown 	for (i = 0; i < WM8994_NUM_LDO_REGS; i++) {
5619e501086SMark Brown 		if (wm8994_ldo_in_use(pdata, i))
5629e501086SMark Brown 			wm8994_set_bits(wm8994, WM8994_LDO_1 + i,
5639e501086SMark Brown 					WM8994_LDO1_DISCH, WM8994_LDO1_DISCH);
5649e501086SMark Brown 		else
5659e501086SMark Brown 			wm8994_set_bits(wm8994, WM8994_LDO_1 + i,
5669e501086SMark Brown 					WM8994_LDO1_DISCH, 0);
5679e501086SMark Brown 	}
5689e501086SMark Brown 
569c9fbf7e0SMark Brown 	wm8994_irq_init(wm8994);
570c9fbf7e0SMark Brown 
5719e501086SMark Brown 	ret = mfd_add_devices(wm8994->dev, -1,
5729e501086SMark Brown 			      wm8994_devs, ARRAY_SIZE(wm8994_devs),
5739e501086SMark Brown 			      NULL, 0);
5749e501086SMark Brown 	if (ret != 0) {
5759e501086SMark Brown 		dev_err(wm8994->dev, "Failed to add children: %d\n", ret);
576c9fbf7e0SMark Brown 		goto err_irq;
5779e501086SMark Brown 	}
5789e501086SMark Brown 
579d450f19eSMark Brown 	pm_runtime_enable(wm8994->dev);
580d450f19eSMark Brown 	pm_runtime_resume(wm8994->dev);
581d450f19eSMark Brown 
5829e501086SMark Brown 	return 0;
5839e501086SMark Brown 
584c9fbf7e0SMark Brown err_irq:
585c9fbf7e0SMark Brown 	wm8994_irq_exit(wm8994);
5869e501086SMark Brown err_enable:
587559e0df6SMark Brown 	regulator_bulk_disable(wm8994->num_supplies,
5889e501086SMark Brown 			       wm8994->supplies);
5899e501086SMark Brown err_get:
590559e0df6SMark Brown 	regulator_bulk_free(wm8994->num_supplies, wm8994->supplies);
591d6c645fcSMark Brown err_regmap:
592d6c645fcSMark Brown 	regmap_exit(wm8994->regmap);
5939e501086SMark Brown 	mfd_remove_devices(wm8994->dev);
5949e501086SMark Brown 	return ret;
5959e501086SMark Brown }
5969e501086SMark Brown 
5979e501086SMark Brown static void wm8994_device_exit(struct wm8994 *wm8994)
5989e501086SMark Brown {
599d450f19eSMark Brown 	pm_runtime_disable(wm8994->dev);
6009e501086SMark Brown 	mfd_remove_devices(wm8994->dev);
601c9fbf7e0SMark Brown 	wm8994_irq_exit(wm8994);
602559e0df6SMark Brown 	regulator_bulk_disable(wm8994->num_supplies,
6039e501086SMark Brown 			       wm8994->supplies);
604559e0df6SMark Brown 	regulator_bulk_free(wm8994->num_supplies, wm8994->supplies);
605d6c645fcSMark Brown 	regmap_exit(wm8994->regmap);
6069e501086SMark Brown }
6079e501086SMark Brown 
608cf763c2eSMark Brown static const struct of_device_id wm8994_of_match[] = {
609cf763c2eSMark Brown 	{ .compatible = "wlf,wm1811", },
610cf763c2eSMark Brown 	{ .compatible = "wlf,wm8994", },
611cf763c2eSMark Brown 	{ .compatible = "wlf,wm8958", },
612cf763c2eSMark Brown 	{ }
613cf763c2eSMark Brown };
614cf763c2eSMark Brown MODULE_DEVICE_TABLE(of, wm8994_of_match);
615cf763c2eSMark Brown 
6169e501086SMark Brown static int wm8994_i2c_probe(struct i2c_client *i2c,
6179e501086SMark Brown 			    const struct i2c_device_id *id)
6189e501086SMark Brown {
6199e501086SMark Brown 	struct wm8994 *wm8994;
620d6c645fcSMark Brown 	int ret;
6219e501086SMark Brown 
6222fa33494SMark Brown 	wm8994 = devm_kzalloc(&i2c->dev, sizeof(struct wm8994), GFP_KERNEL);
623d0a11693SAxel Lin 	if (wm8994 == NULL)
6249e501086SMark Brown 		return -ENOMEM;
6259e501086SMark Brown 
6269e501086SMark Brown 	i2c_set_clientdata(i2c, wm8994);
6279e501086SMark Brown 	wm8994->dev = &i2c->dev;
628c9fbf7e0SMark Brown 	wm8994->irq = i2c->irq;
629559e0df6SMark Brown 	wm8994->type = id->driver_data;
6309e501086SMark Brown 
63134697898SMark Brown 	wm8994->regmap = regmap_init_i2c(i2c, &wm8994_base_regmap_config);
632d6c645fcSMark Brown 	if (IS_ERR(wm8994->regmap)) {
633d6c645fcSMark Brown 		ret = PTR_ERR(wm8994->regmap);
634d6c645fcSMark Brown 		dev_err(wm8994->dev, "Failed to allocate register map: %d\n",
635d6c645fcSMark Brown 			ret);
636d6c645fcSMark Brown 		return ret;
637d6c645fcSMark Brown 	}
638d6c645fcSMark Brown 
639559e0df6SMark Brown 	return wm8994_device_init(wm8994, i2c->irq);
6409e501086SMark Brown }
6419e501086SMark Brown 
6429e501086SMark Brown static int wm8994_i2c_remove(struct i2c_client *i2c)
6439e501086SMark Brown {
6449e501086SMark Brown 	struct wm8994 *wm8994 = i2c_get_clientdata(i2c);
6459e501086SMark Brown 
6469e501086SMark Brown 	wm8994_device_exit(wm8994);
6479e501086SMark Brown 
6489e501086SMark Brown 	return 0;
6499e501086SMark Brown }
6509e501086SMark Brown 
6519e501086SMark Brown static const struct i2c_device_id wm8994_i2c_id[] = {
652b1f43bf3SMark Brown 	{ "wm1811", WM1811 },
65371d17184SMark Brown 	{ "wm1811a", WM1811 },
654559e0df6SMark Brown 	{ "wm8994", WM8994 },
655559e0df6SMark Brown 	{ "wm8958", WM8958 },
6569e501086SMark Brown 	{ }
6579e501086SMark Brown };
6589e501086SMark Brown MODULE_DEVICE_TABLE(i2c, wm8994_i2c_id);
6599e501086SMark Brown 
660aad34310SMark Brown static UNIVERSAL_DEV_PM_OPS(wm8994_pm_ops, wm8994_suspend, wm8994_resume,
661aad34310SMark Brown 			    NULL);
662d450f19eSMark Brown 
6639e501086SMark Brown static struct i2c_driver wm8994_i2c_driver = {
6649e501086SMark Brown 	.driver = {
6659e501086SMark Brown 		.name = "wm8994",
6669e501086SMark Brown 		.owner = THIS_MODULE,
667d450f19eSMark Brown 		.pm = &wm8994_pm_ops,
668cf763c2eSMark Brown 		.of_match_table = wm8994_of_match,
6699e501086SMark Brown 	},
6709e501086SMark Brown 	.probe = wm8994_i2c_probe,
6719e501086SMark Brown 	.remove = wm8994_i2c_remove,
6729e501086SMark Brown 	.id_table = wm8994_i2c_id,
6739e501086SMark Brown };
6749e501086SMark Brown 
6759e501086SMark Brown static int __init wm8994_i2c_init(void)
6769e501086SMark Brown {
6779e501086SMark Brown 	int ret;
6789e501086SMark Brown 
6799e501086SMark Brown 	ret = i2c_add_driver(&wm8994_i2c_driver);
6809e501086SMark Brown 	if (ret != 0)
6819e501086SMark Brown 		pr_err("Failed to register wm8994 I2C driver: %d\n", ret);
6829e501086SMark Brown 
6839e501086SMark Brown 	return ret;
6849e501086SMark Brown }
6859e501086SMark Brown module_init(wm8994_i2c_init);
6869e501086SMark Brown 
6879e501086SMark Brown static void __exit wm8994_i2c_exit(void)
6889e501086SMark Brown {
6899e501086SMark Brown 	i2c_del_driver(&wm8994_i2c_driver);
6909e501086SMark Brown }
6919e501086SMark Brown module_exit(wm8994_i2c_exit);
6929e501086SMark Brown 
6939e501086SMark Brown MODULE_DESCRIPTION("Core support for the WM8994 audio CODEC");
6949e501086SMark Brown MODULE_LICENSE("GPL");
6959e501086SMark Brown MODULE_AUTHOR("Mark Brown <broonie@opensource.wolfsonmicro.com>");
696