ASoC: Add platform data for WM9081 IRQ pin configuration

The WM9081 IRQ output can be either active high or active low and can
support either CMOS or open drain modes.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>
This commit is contained in:
Mark Brown 2011-03-01 20:10:46 +00:00
parent 49542656ad
commit 4a5f7bda8f
2 changed files with 25 additions and 13 deletions

View file

@ -17,9 +17,12 @@ struct wm9081_retune_mobile_setting {
u16 config[20]; u16 config[20];
}; };
struct wm9081_retune_mobile_config { struct wm9081_pdata {
struct wm9081_retune_mobile_setting *configs; bool irq_high; /* IRQ is active high */
int num_configs; bool irq_cmos; /* IRQ is in CMOS mode */
struct wm9081_retune_mobile_setting *retune_configs;
int num_retune_configs;
}; };
#endif #endif

View file

@ -167,7 +167,7 @@ struct wm9081_priv {
int fll_fref; int fll_fref;
int fll_fout; int fll_fout;
int tdm_width; int tdm_width;
struct wm9081_retune_mobile_config *retune; struct wm9081_pdata pdata;
}; };
static int wm9081_volatile_register(struct snd_soc_codec *codec, unsigned int reg) static int wm9081_volatile_register(struct snd_soc_codec *codec, unsigned int reg)
@ -1082,21 +1082,22 @@ static int wm9081_hw_params(struct snd_pcm_substream *substream,
aif4 |= wm9081->bclk / wm9081->fs; aif4 |= wm9081->bclk / wm9081->fs;
/* Apply a ReTune Mobile configuration if it's in use */ /* Apply a ReTune Mobile configuration if it's in use */
if (wm9081->retune) { if (wm9081->pdata.num_retune_configs) {
struct wm9081_retune_mobile_config *retune = wm9081->retune; struct wm9081_pdata *pdata = &wm9081->pdata;
struct wm9081_retune_mobile_setting *s; struct wm9081_retune_mobile_setting *s;
int eq1; int eq1;
best = 0; best = 0;
best_val = abs(retune->configs[0].rate - wm9081->fs); best_val = abs(pdata->retune_configs[0].rate - wm9081->fs);
for (i = 0; i < retune->num_configs; i++) { for (i = 0; i < pdata->num_retune_configs; i++) {
cur_val = abs(retune->configs[i].rate - wm9081->fs); cur_val = abs(pdata->retune_configs[i].rate -
wm9081->fs);
if (cur_val < best_val) { if (cur_val < best_val) {
best_val = cur_val; best_val = cur_val;
best = i; best = i;
} }
} }
s = &retune->configs[best]; s = &pdata->retune_configs[best];
dev_dbg(codec->dev, "ReTune Mobile %s tuned for %dHz\n", dev_dbg(codec->dev, "ReTune Mobile %s tuned for %dHz\n",
s->name, s->rate); s->name, s->rate);
@ -1255,6 +1256,14 @@ static int wm9081_probe(struct snd_soc_codec *codec)
return ret; return ret;
} }
reg = 0;
if (wm9081->pdata.irq_high)
reg |= WM9081_IRQ_POL;
if (!wm9081->pdata.irq_cmos)
reg |= WM9081_IRQ_OP_CTRL;
snd_soc_update_bits(codec, WM9081_INTERRUPT_CONTROL,
WM9081_IRQ_POL | WM9081_IRQ_OP_CTRL, reg);
wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY); wm9081_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
/* Enable zero cross by default */ /* Enable zero cross by default */
@ -1266,7 +1275,7 @@ static int wm9081_probe(struct snd_soc_codec *codec)
snd_soc_add_controls(codec, wm9081_snd_controls, snd_soc_add_controls(codec, wm9081_snd_controls,
ARRAY_SIZE(wm9081_snd_controls)); ARRAY_SIZE(wm9081_snd_controls));
if (!wm9081->retune) { if (!wm9081->pdata.num_retune_configs) {
dev_dbg(codec->dev, dev_dbg(codec->dev,
"No ReTune Mobile data, using normal EQ\n"); "No ReTune Mobile data, using normal EQ\n");
snd_soc_add_controls(codec, wm9081_eq_controls, snd_soc_add_controls(codec, wm9081_eq_controls,
@ -1343,8 +1352,8 @@ static __devinit int wm9081_i2c_probe(struct i2c_client *i2c,
wm9081->control_data = i2c; wm9081->control_data = i2c;
if (dev_get_platdata(&i2c->dev)) if (dev_get_platdata(&i2c->dev))
memcpy(&wm9081->retune, dev_get_platdata(&i2c->dev), memcpy(&wm9081->pdata, dev_get_platdata(&i2c->dev),
sizeof(wm9081->retune)); sizeof(wm9081->pdata));
ret = snd_soc_register_codec(&i2c->dev, ret = snd_soc_register_codec(&i2c->dev,
&soc_codec_dev_wm9081, &wm9081_dai, 1); &soc_codec_dev_wm9081, &wm9081_dai, 1);