Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 283692
b: refs/heads/master
c: ee5f387
h: refs/heads/master
v: v3
  • Loading branch information
Mark Brown committed Nov 8, 2011
1 parent 143d69e commit 10350dd
Show file tree
Hide file tree
Showing 2 changed files with 97 additions and 88 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 79172746827d0579900fa382733f5769d32952eb
refs/heads/master: ee5f387226d13535f41bda0e8a2cf3843fc4c080
183 changes: 96 additions & 87 deletions trunk/sound/soc/codecs/wm8996.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ static const char *wm8996_supply_names[WM8996_NUM_SUPPLIES] = {
};

struct wm8996_priv {
struct regmap *regmap;
struct snd_soc_codec *codec;

int ldo1ena;
Expand Down Expand Up @@ -106,7 +107,7 @@ static int wm8996_regulator_event_##n(struct notifier_block *nb, \
struct wm8996_priv *wm8996 = container_of(nb, struct wm8996_priv, \
disable_nb[n]); \
if (event & REGULATOR_EVENT_DISABLE) { \
wm8996->codec->cache_sync = 1; \
regcache_cache_only(wm8996->regmap, true); \
} \
return 0; \
}
Expand Down Expand Up @@ -1713,9 +1714,15 @@ static bool wm8996_volatile_register(struct device *dev, unsigned int reg)
}
}

static int wm8996_reset(struct snd_soc_codec *codec)
static int wm8996_reset(struct wm8996_priv *wm8996)
{
return snd_soc_write(codec, WM8996_SOFTWARE_RESET, 0x8915);
if (wm8996->pdata.ldo_ena > 0) {
gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
return 0;
} else {
return regmap_write(wm8996->regmap, WM8996_SOFTWARE_RESET,
0x8915);
}
}

static const int bclk_divs[] = {
Expand Down Expand Up @@ -2786,40 +2793,18 @@ static int wm8996_probe(struct snd_soc_codec *codec)

dapm->idle_bias_off = true;

codec->control_data = regmap_init_i2c(i2c, &wm8996_regmap);
if (IS_ERR(codec->control_data)) {
ret = PTR_ERR(codec->control_data);
dev_err(codec->dev, "regmap_init() failed: %d\n", ret);
goto err;
}
codec->control_data = wm8996->regmap;

ret = snd_soc_codec_set_cache_io(codec, 16, 16, SND_SOC_REGMAP);
if (ret != 0) {
dev_err(codec->dev, "Failed to set cache I/O: %d\n", ret);
goto err_regmap;
}

for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++)
wm8996->supplies[i].supply = wm8996_supply_names[i];

ret = regulator_bulk_get(codec->dev, ARRAY_SIZE(wm8996->supplies),
wm8996->supplies);
if (ret != 0) {
dev_err(codec->dev, "Failed to request supplies: %d\n", ret);
goto err_regmap;
goto err;
}

wm8996->disable_nb[0].notifier_call = wm8996_regulator_event_0;
wm8996->disable_nb[1].notifier_call = wm8996_regulator_event_1;
wm8996->disable_nb[2].notifier_call = wm8996_regulator_event_2;

wm8996->cpvdd = regulator_get(&i2c->dev, "CPVDD");
if (IS_ERR(wm8996->cpvdd)) {
ret = PTR_ERR(wm8996->cpvdd);
dev_err(&i2c->dev, "Failed to get CPVDD: %d\n", ret);
goto err_get;
}

/* This should really be moved into the regulator core */
for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++) {
ret = regulator_register_notifier(wm8996->supplies[i].consumer,
Expand All @@ -2831,49 +2816,6 @@ static int wm8996_probe(struct snd_soc_codec *codec)
}
}

ret = regulator_bulk_enable(ARRAY_SIZE(wm8996->supplies),
wm8996->supplies);
if (ret != 0) {
dev_err(codec->dev, "Failed to enable supplies: %d\n", ret);
goto err_cpvdd;
}

if (wm8996->pdata.ldo_ena >= 0) {
gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 1);
msleep(5);
}

ret = snd_soc_read(codec, WM8996_SOFTWARE_RESET);
if (ret < 0) {
dev_err(codec->dev, "Failed to read ID register: %d\n", ret);
goto err_enable;
}
if (ret != 0x8915) {
dev_err(codec->dev, "Device is not a WM8996, ID %x\n", ret);
ret = -EINVAL;
goto err_enable;
}

ret = snd_soc_read(codec, WM8996_CHIP_REVISION);
if (ret < 0) {
dev_err(codec->dev, "Failed to read device revision: %d\n",
ret);
goto err_enable;
}

dev_info(codec->dev, "revision %c\n",
(ret & WM8996_CHIP_REV_MASK) + 'A');

if (wm8996->pdata.ldo_ena >= 0) {
gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
} else {
ret = wm8996_reset(codec);
if (ret < 0) {
dev_err(codec->dev, "Failed to issue reset\n");
goto err_enable;
}
}

regcache_cache_only(codec->control_data, true);

/* Apply platform data settings */
Expand Down Expand Up @@ -3032,8 +2974,6 @@ static int wm8996_probe(struct snd_soc_codec *codec)
WM8996_AIF2TX_LRCLK_MODE,
WM8996_AIF2TX_LRCLK_MODE);

regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);

wm8996_init_gpio(codec);

if (i2c->irq) {
Expand Down Expand Up @@ -3073,17 +3013,6 @@ static int wm8996_probe(struct snd_soc_codec *codec)

return 0;

err_enable:
if (wm8996->pdata.ldo_ena >= 0)
gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);

regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
err_cpvdd:
regulator_put(wm8996->cpvdd);
err_get:
regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
err_regmap:
regmap_exit(codec->control_data);
err:
return ret;
}
Expand All @@ -3107,7 +3036,6 @@ static int wm8996_remove(struct snd_soc_codec *codec)
&wm8996->disable_nb[i]);
regulator_put(wm8996->cpvdd);
regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
regmap_exit(codec->control_data);

return 0;
}
Expand Down Expand Up @@ -3181,7 +3109,8 @@ static __devinit int wm8996_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct wm8996_priv *wm8996;
int ret;
int ret, i;
unsigned int reg;

wm8996 = kzalloc(sizeof(struct wm8996_priv), GFP_KERNEL);
if (wm8996 == NULL)
Expand All @@ -3203,14 +3132,89 @@ static __devinit int wm8996_i2c_probe(struct i2c_client *i2c,
}
}

for (i = 0; i < ARRAY_SIZE(wm8996->supplies); i++)
wm8996->supplies[i].supply = wm8996_supply_names[i];

ret = regulator_bulk_get(&i2c->dev, ARRAY_SIZE(wm8996->supplies),
wm8996->supplies);
if (ret != 0) {
dev_err(&i2c->dev, "Failed to request supplies: %d\n", ret);
goto err_gpio;
}

wm8996->cpvdd = regulator_get(&i2c->dev, "CPVDD");
if (IS_ERR(wm8996->cpvdd)) {
ret = PTR_ERR(wm8996->cpvdd);
dev_err(&i2c->dev, "Failed to get CPVDD: %d\n", ret);
goto err_get;
}

ret = regulator_bulk_enable(ARRAY_SIZE(wm8996->supplies),
wm8996->supplies);
if (ret != 0) {
dev_err(&i2c->dev, "Failed to enable supplies: %d\n", ret);
goto err_cpvdd;
}

if (wm8996->pdata.ldo_ena > 0) {
gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 1);
msleep(5);
}

wm8996->regmap = regmap_init_i2c(i2c, &wm8996_regmap);
if (IS_ERR(wm8996->regmap)) {
ret = PTR_ERR(wm8996->regmap);
dev_err(&i2c->dev, "regmap_init() failed: %d\n", ret);
goto err_enable;
}

ret = regmap_read(wm8996->regmap, WM8996_SOFTWARE_RESET, &reg);
if (ret < 0) {
dev_err(&i2c->dev, "Failed to read ID register: %d\n", ret);
goto err_regmap;
}
if (reg != 0x8915) {
dev_err(&i2c->dev, "Device is not a WM8996, ID %x\n", ret);
ret = -EINVAL;
goto err_regmap;
}

ret = regmap_read(wm8996->regmap, WM8996_CHIP_REVISION, &reg);
if (ret < 0) {
dev_err(&i2c->dev, "Failed to read device revision: %d\n",
ret);
goto err_regmap;
}

dev_info(&i2c->dev, "revision %c\n",
(reg & WM8996_CHIP_REV_MASK) + 'A');

regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);

ret = wm8996_reset(wm8996);
if (ret < 0) {
dev_err(&i2c->dev, "Failed to issue reset\n");
goto err_regmap;
}

ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_wm8996, wm8996_dai,
ARRAY_SIZE(wm8996_dai));
if (ret < 0)
goto err_gpio;
goto err_regmap;

return ret;

err_regmap:
regmap_exit(wm8996->regmap);
err_enable:
if (wm8996->pdata.ldo_ena > 0)
gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
regulator_bulk_disable(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
err_cpvdd:
regulator_put(wm8996->cpvdd);
err_get:
regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
err_gpio:
if (wm8996->pdata.ldo_ena > 0)
gpio_free(wm8996->pdata.ldo_ena);
Expand All @@ -3225,8 +3229,13 @@ static __devexit int wm8996_i2c_remove(struct i2c_client *client)
struct wm8996_priv *wm8996 = i2c_get_clientdata(client);

snd_soc_unregister_codec(&client->dev);
if (wm8996->pdata.ldo_ena > 0)
regulator_put(wm8996->cpvdd);
regulator_bulk_free(ARRAY_SIZE(wm8996->supplies), wm8996->supplies);
regmap_exit(wm8996->regmap);
if (wm8996->pdata.ldo_ena > 0) {
gpio_set_value_cansleep(wm8996->pdata.ldo_ena, 0);
gpio_free(wm8996->pdata.ldo_ena);
}
kfree(wm8996);
return 0;
}
Expand Down

0 comments on commit 10350dd

Please sign in to comment.