Skip to content

Commit

Permalink
ASoC: Initial WM8903 microphone bias and short detection
Browse files Browse the repository at this point in the history
Provide support for WM8903 microphone presence and short detection
using the GPIOs to route out a logic signal suitable for handling
using snd_soc_jack_add_gpios() on the processor GPIOs.

Signed-off-by: Mark Brown <broonie@opensource.wolfsonmicro.com>
Acked-by: Liam Girdwood <lrg@slimlogic.co.uk>
  • Loading branch information
Mark Brown committed Mar 16, 2010
1 parent 73b34ea commit 37f88e8
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 30 deletions.
29 changes: 29 additions & 0 deletions include/sound/wm8903.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,28 @@
/* Used to enable configuration of a GPIO to all zeros */
#define WM8903_GPIO_NO_CONFIG 0x8000

/*
* R6 (0x06) - Mic Bias Control 0
*/
#define WM8903_MICDET_HYST_ENA 0x0080 /* MICDET_HYST_ENA */
#define WM8903_MICDET_HYST_ENA_MASK 0x0080 /* MICDET_HYST_ENA */
#define WM8903_MICDET_HYST_ENA_SHIFT 7 /* MICDET_HYST_ENA */
#define WM8903_MICDET_HYST_ENA_WIDTH 1 /* MICDET_HYST_ENA */
#define WM8903_MICDET_THR_MASK 0x0070 /* MICDET_THR - [6:4] */
#define WM8903_MICDET_THR_SHIFT 4 /* MICDET_THR - [6:4] */
#define WM8903_MICDET_THR_WIDTH 3 /* MICDET_THR - [6:4] */
#define WM8903_MICSHORT_THR_MASK 0x000C /* MICSHORT_THR - [3:2] */
#define WM8903_MICSHORT_THR_SHIFT 2 /* MICSHORT_THR - [3:2] */
#define WM8903_MICSHORT_THR_WIDTH 2 /* MICSHORT_THR - [3:2] */
#define WM8903_MICDET_ENA 0x0002 /* MICDET_ENA */
#define WM8903_MICDET_ENA_MASK 0x0002 /* MICDET_ENA */
#define WM8903_MICDET_ENA_SHIFT 1 /* MICDET_ENA */
#define WM8903_MICDET_ENA_WIDTH 1 /* MICDET_ENA */
#define WM8903_MICBIAS_ENA 0x0001 /* MICBIAS_ENA */
#define WM8903_MICBIAS_ENA_MASK 0x0001 /* MICBIAS_ENA */
#define WM8903_MICBIAS_ENA_SHIFT 0 /* MICBIAS_ENA */
#define WM8903_MICBIAS_ENA_WIDTH 1 /* MICBIAS_ENA */

/*
* R116 (0x74) - GPIO Control 1
*/
Expand Down Expand Up @@ -210,6 +232,13 @@
#define WM8903_GP5_DB_WIDTH 1 /* GP5_DB */

struct wm8903_platform_data {
/* Default register value for R6 (Mic bias), used to configure
* microphone detection. In conjunction with gpio_cfg this
* can be used to route the microphone status signals out onto
* the GPIOs for use with snd_soc_jack_add_gpios().
*/
u16 micdet_cfg;

u32 gpio_cfg[5]; /* Default register values for GPIO pin mux */
};

Expand Down
24 changes: 16 additions & 8 deletions sound/soc/codecs/wm8903.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
*
* TODO:
* - TDM mode configuration.
* - Mic detect.
* - Digital microphone support.
* - Interrupt support (mic detect and sequencer).
*/
Expand Down Expand Up @@ -246,10 +245,10 @@ static int wm8903_run_sequence(struct snd_soc_codec *codec, unsigned int start)

BUG_ON(start > 48);

/* Enable the sequencer */
/* Enable the sequencer if it's not already on */
reg[0] = snd_soc_read(codec, WM8903_WRITE_SEQUENCER_0);
reg[0] |= WM8903_WSEQ_ENA;
snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0, reg[0]);
snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0,
reg[0] | WM8903_WSEQ_ENA);

dev_dbg(&i2c->dev, "Starting sequence at %d\n", start);

Expand All @@ -268,9 +267,8 @@ static int wm8903_run_sequence(struct snd_soc_codec *codec, unsigned int start)

dev_dbg(&i2c->dev, "Sequence complete\n");

/* Disable the sequencer again */
snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0,
reg[0] & ~WM8903_WSEQ_ENA);
/* Disable the sequencer again if we enabled it */
snd_soc_write(codec, WM8903_WRITE_SEQUENCER_0, reg[0]);

return 0;
}
Expand Down Expand Up @@ -1578,7 +1576,7 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,

wm8903_reset(codec);

/* Set up GPIOs */
/* Set up GPIOs and microphone detection */
if (pdata) {
for (i = 0; i < ARRAY_SIZE(pdata->gpio_cfg); i++) {
if (!pdata->gpio_cfg[i])
Expand All @@ -1587,6 +1585,16 @@ static __devinit int wm8903_i2c_probe(struct i2c_client *i2c,
snd_soc_write(codec, WM8903_GPIO_CONTROL_1 + i,
pdata->gpio_cfg[i] & 0xffff);
}

snd_soc_write(codec, WM8903_MIC_BIAS_CONTROL_0,
pdata->micdet_cfg);

/* Microphone detection needs the WSEQ clock */
if (pdata->micdet_cfg)
snd_soc_update_bits(codec, WM8903_WRITE_SEQUENCER_0,
WM8903_WSEQ_ENA, WM8903_WSEQ_ENA);

wm8903->mic_delay = pdata->micdet_delay;
}

/* power on device */
Expand Down
22 changes: 0 additions & 22 deletions sound/soc/codecs/wm8903.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,28 +172,6 @@ extern struct snd_soc_codec_device soc_codec_dev_wm8903;
#define WM8903_VMID_RES_250K 3
#define WM8903_VMID_RES_5K 4

/*
* R6 (0x06) - Mic Bias Control 0
*/
#define WM8903_MICDET_HYST_ENA 0x0080 /* MICDET_HYST_ENA */
#define WM8903_MICDET_HYST_ENA_MASK 0x0080 /* MICDET_HYST_ENA */
#define WM8903_MICDET_HYST_ENA_SHIFT 7 /* MICDET_HYST_ENA */
#define WM8903_MICDET_HYST_ENA_WIDTH 1 /* MICDET_HYST_ENA */
#define WM8903_MICDET_THR_MASK 0x0070 /* MICDET_THR - [6:4] */
#define WM8903_MICDET_THR_SHIFT 4 /* MICDET_THR - [6:4] */
#define WM8903_MICDET_THR_WIDTH 3 /* MICDET_THR - [6:4] */
#define WM8903_MICSHORT_THR_MASK 0x000C /* MICSHORT_THR - [3:2] */
#define WM8903_MICSHORT_THR_SHIFT 2 /* MICSHORT_THR - [3:2] */
#define WM8903_MICSHORT_THR_WIDTH 2 /* MICSHORT_THR - [3:2] */
#define WM8903_MICDET_ENA 0x0002 /* MICDET_ENA */
#define WM8903_MICDET_ENA_MASK 0x0002 /* MICDET_ENA */
#define WM8903_MICDET_ENA_SHIFT 1 /* MICDET_ENA */
#define WM8903_MICDET_ENA_WIDTH 1 /* MICDET_ENA */
#define WM8903_MICBIAS_ENA 0x0001 /* MICBIAS_ENA */
#define WM8903_MICBIAS_ENA_MASK 0x0001 /* MICBIAS_ENA */
#define WM8903_MICBIAS_ENA_SHIFT 0 /* MICBIAS_ENA */
#define WM8903_MICBIAS_ENA_WIDTH 1 /* MICBIAS_ENA */

/*
* R8 (0x08) - Analogue DAC 0
*/
Expand Down

0 comments on commit 37f88e8

Please sign in to comment.