#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/regmap.h>
+#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
{ NAU8822_REG_OUTPUT_TIEOFF, 0x0000 },
};
+static const char * const nau8822_supply_names[NAU8822_NUM_SUPPLIES] = {
+ "vdda", "vddb", "vddc", "vddspk",
+};
+
static bool nau8822_readable_reg(struct device *dev, unsigned int reg)
{
switch (reg) {
struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
snd_soc_dapm_force_bias_level(dapm, SND_SOC_BIAS_OFF);
+ regulator_bulk_disable(NAU8822_NUM_SUPPLIES, nau8822->supplies);
regcache_mark_dirty(nau8822->regmap);
{
struct nau8822 *nau8822 = snd_soc_component_get_drvdata(component);
struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
+ int ret = regulator_bulk_enable(NAU8822_NUM_SUPPLIES, nau8822->supplies);
+
+ if (ret) {
+ dev_err(component->dev,
+ "Failed to enable regulators: %d\n", ret);
+ return ret;
+ }
+
+ fsleep(100);
regcache_sync(nau8822->regmap);
{
struct device *dev = &i2c->dev;
struct nau8822 *nau8822 = dev_get_platdata(dev);
- int ret;
+ int ret, i;
if (!nau8822) {
nau8822 = devm_kzalloc(dev, sizeof(*nau8822), GFP_KERNEL);
return dev_err_probe(&i2c->dev, PTR_ERR(nau8822->mclk),
"Error getting mclk\n");
+ for (i = 0; i < NAU8822_NUM_SUPPLIES; i++)
+ nau8822->supplies[i].supply = nau8822_supply_names[i];
+
+ ret = devm_regulator_bulk_get(dev, NAU8822_NUM_SUPPLIES, nau8822->supplies);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to get regulators\n");
+
nau8822->regmap = devm_regmap_init_i2c(i2c, &nau8822_regmap_config);
if (IS_ERR(nau8822->regmap)) {
ret = PTR_ERR(nau8822->regmap);
}
nau8822->dev = dev;
+ ret = regulator_bulk_enable(NAU8822_NUM_SUPPLIES, nau8822->supplies);
+ if (ret)
+ return dev_err_probe(dev, ret, "Failed to enable regulators\n");
+
+ fsleep(100);
+
/* Reset the codec */
ret = regmap_write(nau8822->regmap, NAU8822_REG_RESET, 0x00);
if (ret != 0) {
dev_err(&i2c->dev, "Failed to issue reset: %d\n", ret);
- return ret;
+ goto err_reg;
}
ret = devm_snd_soc_register_component(dev, &soc_component_dev_nau8822,
&nau8822_dai, 1);
if (ret != 0) {
dev_err(&i2c->dev, "Failed to register CODEC: %d\n", ret);
- return ret;
+ goto err_reg;
}
return 0;
+
+err_reg:
+ regulator_bulk_disable(NAU8822_NUM_SUPPLIES, nau8822->supplies);
+ return ret;
+}
+
+static void nau8822_i2c_remove(struct i2c_client *i2c)
+{
+ struct nau8822 *nau8822 = i2c_get_clientdata(i2c);
+
+ regulator_bulk_disable(NAU8822_NUM_SUPPLIES, nau8822->supplies);
}
static const struct i2c_device_id nau8822_i2c_id[] = {
.of_match_table = of_match_ptr(nau8822_of_match),
},
.probe = nau8822_i2c_probe,
+ .remove = nau8822_i2c_remove,
.id_table = nau8822_i2c_id,
};
module_i2c_driver(nau8822_i2c_driver);