Skip to content

Commit

Permalink
ASoC: wm8996: Move register default configuration to I2C probe
Browse files Browse the repository at this point in the history
This gets the registers set up as early as possible, mainly useful for the
GPIOs to ensure that they're in the correct mode.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
  • Loading branch information
Mark Brown committed Jun 25, 2012
1 parent d4b3d0f commit ec8ffe1
Showing 1 changed file with 180 additions and 151 deletions.
331 changes: 180 additions & 151 deletions sound/soc/codecs/wm8996.c
Original file line number Diff line number Diff line change
Expand Up @@ -2619,7 +2619,7 @@ static int wm8996_probe(struct snd_soc_codec *codec)
int ret;
struct wm8996_priv *wm8996 = snd_soc_codec_get_drvdata(codec);
struct i2c_client *i2c = to_i2c_client(codec->dev);
int i, irq_flags;
int irq_flags;

wm8996->codec = codec;

Expand All @@ -2634,162 +2634,12 @@ static int wm8996_probe(struct snd_soc_codec *codec)
goto err;
}

/* Apply platform data settings */
snd_soc_update_bits(codec, WM8996_LINE_INPUT_CONTROL,
WM8996_INL_MODE_MASK | WM8996_INR_MODE_MASK,
wm8996->pdata.inl_mode << WM8996_INL_MODE_SHIFT |
wm8996->pdata.inr_mode);

for (i = 0; i < ARRAY_SIZE(wm8996->pdata.gpio_default); i++) {
if (!wm8996->pdata.gpio_default[i])
continue;

snd_soc_write(codec, WM8996_GPIO_1 + i,
wm8996->pdata.gpio_default[i] & 0xffff);
}

if (wm8996->pdata.spkmute_seq)
snd_soc_update_bits(codec, WM8996_PDM_SPEAKER_MUTE_SEQUENCE,
WM8996_SPK_MUTE_ENDIAN |
WM8996_SPK_MUTE_SEQ1_MASK,
wm8996->pdata.spkmute_seq);

snd_soc_update_bits(codec, WM8996_ACCESSORY_DETECT_MODE_2,
WM8996_MICD_BIAS_SRC | WM8996_HPOUT1FB_SRC |
WM8996_MICD_SRC, wm8996->pdata.micdet_def);

/* Latch volume update bits */
snd_soc_update_bits(codec, WM8996_LEFT_LINE_INPUT_VOLUME,
WM8996_IN1_VU, WM8996_IN1_VU);
snd_soc_update_bits(codec, WM8996_RIGHT_LINE_INPUT_VOLUME,
WM8996_IN1_VU, WM8996_IN1_VU);

snd_soc_update_bits(codec, WM8996_DAC1_LEFT_VOLUME,
WM8996_DAC1_VU, WM8996_DAC1_VU);
snd_soc_update_bits(codec, WM8996_DAC1_RIGHT_VOLUME,
WM8996_DAC1_VU, WM8996_DAC1_VU);
snd_soc_update_bits(codec, WM8996_DAC2_LEFT_VOLUME,
WM8996_DAC2_VU, WM8996_DAC2_VU);
snd_soc_update_bits(codec, WM8996_DAC2_RIGHT_VOLUME,
WM8996_DAC2_VU, WM8996_DAC2_VU);

snd_soc_update_bits(codec, WM8996_OUTPUT1_LEFT_VOLUME,
WM8996_DAC1_VU, WM8996_DAC1_VU);
snd_soc_update_bits(codec, WM8996_OUTPUT1_RIGHT_VOLUME,
WM8996_DAC1_VU, WM8996_DAC1_VU);
snd_soc_update_bits(codec, WM8996_OUTPUT2_LEFT_VOLUME,
WM8996_DAC2_VU, WM8996_DAC2_VU);
snd_soc_update_bits(codec, WM8996_OUTPUT2_RIGHT_VOLUME,
WM8996_DAC2_VU, WM8996_DAC2_VU);

snd_soc_update_bits(codec, WM8996_DSP1_TX_LEFT_VOLUME,
WM8996_DSP1TX_VU, WM8996_DSP1TX_VU);
snd_soc_update_bits(codec, WM8996_DSP1_TX_RIGHT_VOLUME,
WM8996_DSP1TX_VU, WM8996_DSP1TX_VU);
snd_soc_update_bits(codec, WM8996_DSP2_TX_LEFT_VOLUME,
WM8996_DSP2TX_VU, WM8996_DSP2TX_VU);
snd_soc_update_bits(codec, WM8996_DSP2_TX_RIGHT_VOLUME,
WM8996_DSP2TX_VU, WM8996_DSP2TX_VU);

snd_soc_update_bits(codec, WM8996_DSP1_RX_LEFT_VOLUME,
WM8996_DSP1RX_VU, WM8996_DSP1RX_VU);
snd_soc_update_bits(codec, WM8996_DSP1_RX_RIGHT_VOLUME,
WM8996_DSP1RX_VU, WM8996_DSP1RX_VU);
snd_soc_update_bits(codec, WM8996_DSP2_RX_LEFT_VOLUME,
WM8996_DSP2RX_VU, WM8996_DSP2RX_VU);
snd_soc_update_bits(codec, WM8996_DSP2_RX_RIGHT_VOLUME,
WM8996_DSP2RX_VU, WM8996_DSP2RX_VU);

/* No support currently for the underclocked TDM modes and
* pick a default TDM layout with each channel pair working with
* slots 0 and 1. */
snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_0_CONFIGURATION,
WM8996_AIF1RX_CHAN0_SLOTS_MASK |
WM8996_AIF1RX_CHAN0_START_SLOT_MASK,
1 << WM8996_AIF1RX_CHAN0_SLOTS_SHIFT | 0);
snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_1_CONFIGURATION,
WM8996_AIF1RX_CHAN1_SLOTS_MASK |
WM8996_AIF1RX_CHAN1_START_SLOT_MASK,
1 << WM8996_AIF1RX_CHAN1_SLOTS_SHIFT | 1);
snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_2_CONFIGURATION,
WM8996_AIF1RX_CHAN2_SLOTS_MASK |
WM8996_AIF1RX_CHAN2_START_SLOT_MASK,
1 << WM8996_AIF1RX_CHAN2_SLOTS_SHIFT | 0);
snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_3_CONFIGURATION,
WM8996_AIF1RX_CHAN3_SLOTS_MASK |
WM8996_AIF1RX_CHAN0_START_SLOT_MASK,
1 << WM8996_AIF1RX_CHAN3_SLOTS_SHIFT | 1);
snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_4_CONFIGURATION,
WM8996_AIF1RX_CHAN4_SLOTS_MASK |
WM8996_AIF1RX_CHAN0_START_SLOT_MASK,
1 << WM8996_AIF1RX_CHAN4_SLOTS_SHIFT | 0);
snd_soc_update_bits(codec, WM8996_AIF1RX_CHANNEL_5_CONFIGURATION,
WM8996_AIF1RX_CHAN5_SLOTS_MASK |
WM8996_AIF1RX_CHAN0_START_SLOT_MASK,
1 << WM8996_AIF1RX_CHAN5_SLOTS_SHIFT | 1);

snd_soc_update_bits(codec, WM8996_AIF2RX_CHANNEL_0_CONFIGURATION,
WM8996_AIF2RX_CHAN0_SLOTS_MASK |
WM8996_AIF2RX_CHAN0_START_SLOT_MASK,
1 << WM8996_AIF2RX_CHAN0_SLOTS_SHIFT | 0);
snd_soc_update_bits(codec, WM8996_AIF2RX_CHANNEL_1_CONFIGURATION,
WM8996_AIF2RX_CHAN1_SLOTS_MASK |
WM8996_AIF2RX_CHAN1_START_SLOT_MASK,
1 << WM8996_AIF2RX_CHAN1_SLOTS_SHIFT | 1);

snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_0_CONFIGURATION,
WM8996_AIF1TX_CHAN0_SLOTS_MASK |
WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
1 << WM8996_AIF1TX_CHAN0_SLOTS_SHIFT | 0);
snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_1_CONFIGURATION,
WM8996_AIF1TX_CHAN1_SLOTS_MASK |
WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
1 << WM8996_AIF1TX_CHAN1_SLOTS_SHIFT | 1);
snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_2_CONFIGURATION,
WM8996_AIF1TX_CHAN2_SLOTS_MASK |
WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
1 << WM8996_AIF1TX_CHAN2_SLOTS_SHIFT | 0);
snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_3_CONFIGURATION,
WM8996_AIF1TX_CHAN3_SLOTS_MASK |
WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
1 << WM8996_AIF1TX_CHAN3_SLOTS_SHIFT | 1);
snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_4_CONFIGURATION,
WM8996_AIF1TX_CHAN4_SLOTS_MASK |
WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
1 << WM8996_AIF1TX_CHAN4_SLOTS_SHIFT | 0);
snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_5_CONFIGURATION,
WM8996_AIF1TX_CHAN5_SLOTS_MASK |
WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
1 << WM8996_AIF1TX_CHAN5_SLOTS_SHIFT | 1);

snd_soc_update_bits(codec, WM8996_AIF2TX_CHANNEL_0_CONFIGURATION,
WM8996_AIF2TX_CHAN0_SLOTS_MASK |
WM8996_AIF2TX_CHAN0_START_SLOT_MASK,
1 << WM8996_AIF2TX_CHAN0_SLOTS_SHIFT | 0);
snd_soc_update_bits(codec, WM8996_AIF1TX_CHANNEL_1_CONFIGURATION,
WM8996_AIF2TX_CHAN1_SLOTS_MASK |
WM8996_AIF2TX_CHAN1_START_SLOT_MASK,
1 << WM8996_AIF1TX_CHAN1_SLOTS_SHIFT | 1);

if (wm8996->pdata.num_retune_mobile_cfgs)
wm8996_retune_mobile_pdata(codec);
else
snd_soc_add_codec_controls(codec, wm8996_eq_controls,
ARRAY_SIZE(wm8996_eq_controls));

/* If the TX LRCLK pins are not in LRCLK mode configure the
* AIFs to source their clocks from the RX LRCLKs.
*/
if ((snd_soc_read(codec, WM8996_GPIO_1)))
snd_soc_update_bits(codec, WM8996_AIF1_TX_LRCLK_2,
WM8996_AIF1TX_LRCLK_MODE,
WM8996_AIF1TX_LRCLK_MODE);

if ((snd_soc_read(codec, WM8996_GPIO_2)))
snd_soc_update_bits(codec, WM8996_AIF2_TX_LRCLK_2,
WM8996_AIF2TX_LRCLK_MODE,
WM8996_AIF2TX_LRCLK_MODE);

if (i2c->irq) {
if (wm8996->pdata.irq_flags)
irq_flags = wm8996->pdata.irq_flags;
Expand Down Expand Up @@ -3023,6 +2873,185 @@ static __devinit int wm8996_i2c_probe(struct i2c_client *i2c,

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

/* Apply platform data settings */
regmap_update_bits(wm8996->regmap, WM8996_LINE_INPUT_CONTROL,
WM8996_INL_MODE_MASK | WM8996_INR_MODE_MASK,
wm8996->pdata.inl_mode << WM8996_INL_MODE_SHIFT |
wm8996->pdata.inr_mode);

for (i = 0; i < ARRAY_SIZE(wm8996->pdata.gpio_default); i++) {
if (!wm8996->pdata.gpio_default[i])
continue;

regmap_write(wm8996->regmap, WM8996_GPIO_1 + i,
wm8996->pdata.gpio_default[i] & 0xffff);
}

if (wm8996->pdata.spkmute_seq)
regmap_update_bits(wm8996->regmap,
WM8996_PDM_SPEAKER_MUTE_SEQUENCE,
WM8996_SPK_MUTE_ENDIAN |
WM8996_SPK_MUTE_SEQ1_MASK,
wm8996->pdata.spkmute_seq);

regmap_update_bits(wm8996->regmap, WM8996_ACCESSORY_DETECT_MODE_2,
WM8996_MICD_BIAS_SRC | WM8996_HPOUT1FB_SRC |
WM8996_MICD_SRC, wm8996->pdata.micdet_def);

/* Latch volume update bits */
regmap_update_bits(wm8996->regmap, WM8996_LEFT_LINE_INPUT_VOLUME,
WM8996_IN1_VU, WM8996_IN1_VU);
regmap_update_bits(wm8996->regmap, WM8996_RIGHT_LINE_INPUT_VOLUME,
WM8996_IN1_VU, WM8996_IN1_VU);

regmap_update_bits(wm8996->regmap, WM8996_DAC1_LEFT_VOLUME,
WM8996_DAC1_VU, WM8996_DAC1_VU);
regmap_update_bits(wm8996->regmap, WM8996_DAC1_RIGHT_VOLUME,
WM8996_DAC1_VU, WM8996_DAC1_VU);
regmap_update_bits(wm8996->regmap, WM8996_DAC2_LEFT_VOLUME,
WM8996_DAC2_VU, WM8996_DAC2_VU);
regmap_update_bits(wm8996->regmap, WM8996_DAC2_RIGHT_VOLUME,
WM8996_DAC2_VU, WM8996_DAC2_VU);

regmap_update_bits(wm8996->regmap, WM8996_OUTPUT1_LEFT_VOLUME,
WM8996_DAC1_VU, WM8996_DAC1_VU);
regmap_update_bits(wm8996->regmap, WM8996_OUTPUT1_RIGHT_VOLUME,
WM8996_DAC1_VU, WM8996_DAC1_VU);
regmap_update_bits(wm8996->regmap, WM8996_OUTPUT2_LEFT_VOLUME,
WM8996_DAC2_VU, WM8996_DAC2_VU);
regmap_update_bits(wm8996->regmap, WM8996_OUTPUT2_RIGHT_VOLUME,
WM8996_DAC2_VU, WM8996_DAC2_VU);

regmap_update_bits(wm8996->regmap, WM8996_DSP1_TX_LEFT_VOLUME,
WM8996_DSP1TX_VU, WM8996_DSP1TX_VU);
regmap_update_bits(wm8996->regmap, WM8996_DSP1_TX_RIGHT_VOLUME,
WM8996_DSP1TX_VU, WM8996_DSP1TX_VU);
regmap_update_bits(wm8996->regmap, WM8996_DSP2_TX_LEFT_VOLUME,
WM8996_DSP2TX_VU, WM8996_DSP2TX_VU);
regmap_update_bits(wm8996->regmap, WM8996_DSP2_TX_RIGHT_VOLUME,
WM8996_DSP2TX_VU, WM8996_DSP2TX_VU);

regmap_update_bits(wm8996->regmap, WM8996_DSP1_RX_LEFT_VOLUME,
WM8996_DSP1RX_VU, WM8996_DSP1RX_VU);
regmap_update_bits(wm8996->regmap, WM8996_DSP1_RX_RIGHT_VOLUME,
WM8996_DSP1RX_VU, WM8996_DSP1RX_VU);
regmap_update_bits(wm8996->regmap, WM8996_DSP2_RX_LEFT_VOLUME,
WM8996_DSP2RX_VU, WM8996_DSP2RX_VU);
regmap_update_bits(wm8996->regmap, WM8996_DSP2_RX_RIGHT_VOLUME,
WM8996_DSP2RX_VU, WM8996_DSP2RX_VU);

/* No support currently for the underclocked TDM modes and
* pick a default TDM layout with each channel pair working with
* slots 0 and 1. */
regmap_update_bits(wm8996->regmap,
WM8996_AIF1RX_CHANNEL_0_CONFIGURATION,
WM8996_AIF1RX_CHAN0_SLOTS_MASK |
WM8996_AIF1RX_CHAN0_START_SLOT_MASK,
1 << WM8996_AIF1RX_CHAN0_SLOTS_SHIFT | 0);
regmap_update_bits(wm8996->regmap,
WM8996_AIF1RX_CHANNEL_1_CONFIGURATION,
WM8996_AIF1RX_CHAN1_SLOTS_MASK |
WM8996_AIF1RX_CHAN1_START_SLOT_MASK,
1 << WM8996_AIF1RX_CHAN1_SLOTS_SHIFT | 1);
regmap_update_bits(wm8996->regmap,
WM8996_AIF1RX_CHANNEL_2_CONFIGURATION,
WM8996_AIF1RX_CHAN2_SLOTS_MASK |
WM8996_AIF1RX_CHAN2_START_SLOT_MASK,
1 << WM8996_AIF1RX_CHAN2_SLOTS_SHIFT | 0);
regmap_update_bits(wm8996->regmap,
WM8996_AIF1RX_CHANNEL_3_CONFIGURATION,
WM8996_AIF1RX_CHAN3_SLOTS_MASK |
WM8996_AIF1RX_CHAN0_START_SLOT_MASK,
1 << WM8996_AIF1RX_CHAN3_SLOTS_SHIFT | 1);
regmap_update_bits(wm8996->regmap,
WM8996_AIF1RX_CHANNEL_4_CONFIGURATION,
WM8996_AIF1RX_CHAN4_SLOTS_MASK |
WM8996_AIF1RX_CHAN0_START_SLOT_MASK,
1 << WM8996_AIF1RX_CHAN4_SLOTS_SHIFT | 0);
regmap_update_bits(wm8996->regmap,
WM8996_AIF1RX_CHANNEL_5_CONFIGURATION,
WM8996_AIF1RX_CHAN5_SLOTS_MASK |
WM8996_AIF1RX_CHAN0_START_SLOT_MASK,
1 << WM8996_AIF1RX_CHAN5_SLOTS_SHIFT | 1);

regmap_update_bits(wm8996->regmap,
WM8996_AIF2RX_CHANNEL_0_CONFIGURATION,
WM8996_AIF2RX_CHAN0_SLOTS_MASK |
WM8996_AIF2RX_CHAN0_START_SLOT_MASK,
1 << WM8996_AIF2RX_CHAN0_SLOTS_SHIFT | 0);
regmap_update_bits(wm8996->regmap,
WM8996_AIF2RX_CHANNEL_1_CONFIGURATION,
WM8996_AIF2RX_CHAN1_SLOTS_MASK |
WM8996_AIF2RX_CHAN1_START_SLOT_MASK,
1 << WM8996_AIF2RX_CHAN1_SLOTS_SHIFT | 1);

regmap_update_bits(wm8996->regmap,
WM8996_AIF1TX_CHANNEL_0_CONFIGURATION,
WM8996_AIF1TX_CHAN0_SLOTS_MASK |
WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
1 << WM8996_AIF1TX_CHAN0_SLOTS_SHIFT | 0);
regmap_update_bits(wm8996->regmap,
WM8996_AIF1TX_CHANNEL_1_CONFIGURATION,
WM8996_AIF1TX_CHAN1_SLOTS_MASK |
WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
1 << WM8996_AIF1TX_CHAN1_SLOTS_SHIFT | 1);
regmap_update_bits(wm8996->regmap,
WM8996_AIF1TX_CHANNEL_2_CONFIGURATION,
WM8996_AIF1TX_CHAN2_SLOTS_MASK |
WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
1 << WM8996_AIF1TX_CHAN2_SLOTS_SHIFT | 0);
regmap_update_bits(wm8996->regmap,
WM8996_AIF1TX_CHANNEL_3_CONFIGURATION,
WM8996_AIF1TX_CHAN3_SLOTS_MASK |
WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
1 << WM8996_AIF1TX_CHAN3_SLOTS_SHIFT | 1);
regmap_update_bits(wm8996->regmap,
WM8996_AIF1TX_CHANNEL_4_CONFIGURATION,
WM8996_AIF1TX_CHAN4_SLOTS_MASK |
WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
1 << WM8996_AIF1TX_CHAN4_SLOTS_SHIFT | 0);
regmap_update_bits(wm8996->regmap,
WM8996_AIF1TX_CHANNEL_5_CONFIGURATION,
WM8996_AIF1TX_CHAN5_SLOTS_MASK |
WM8996_AIF1TX_CHAN0_START_SLOT_MASK,
1 << WM8996_AIF1TX_CHAN5_SLOTS_SHIFT | 1);

regmap_update_bits(wm8996->regmap,
WM8996_AIF2TX_CHANNEL_0_CONFIGURATION,
WM8996_AIF2TX_CHAN0_SLOTS_MASK |
WM8996_AIF2TX_CHAN0_START_SLOT_MASK,
1 << WM8996_AIF2TX_CHAN0_SLOTS_SHIFT | 0);
regmap_update_bits(wm8996->regmap,
WM8996_AIF1TX_CHANNEL_1_CONFIGURATION,
WM8996_AIF2TX_CHAN1_SLOTS_MASK |
WM8996_AIF2TX_CHAN1_START_SLOT_MASK,
1 << WM8996_AIF1TX_CHAN1_SLOTS_SHIFT | 1);

/* If the TX LRCLK pins are not in LRCLK mode configure the
* AIFs to source their clocks from the RX LRCLKs.
*/
ret = regmap_read(wm8996->regmap, WM8996_GPIO_1, &reg);
if (ret != 0) {
dev_err(&i2c->dev, "Failed to read GPIO1: %d\n", ret);
goto err_regmap;
}

if (reg & WM8996_GP1_FN_MASK)
regmap_update_bits(wm8996->regmap, WM8996_AIF1_TX_LRCLK_2,
WM8996_AIF1TX_LRCLK_MODE,
WM8996_AIF1TX_LRCLK_MODE);

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

if (reg & WM8996_GP2_FN_MASK)
regmap_update_bits(wm8996->regmap, WM8996_AIF2_TX_LRCLK_2,
WM8996_AIF2TX_LRCLK_MODE,
WM8996_AIF2TX_LRCLK_MODE);

wm8996_init_gpio(wm8996);

ret = snd_soc_register_codec(&i2c->dev,
Expand Down

0 comments on commit ec8ffe1

Please sign in to comment.