Commit 53a61d96 authored by Mark Brown's avatar Mark Brown

Merge branch 'for-2.6.34' into for-2.6.35

Conflicts due to context changes next to the backported DMA data change:
	include/sound/soc.h
parents 88766984 5f712b2b
...@@ -381,7 +381,7 @@ struct snd_soc_pcm_stream { ...@@ -381,7 +381,7 @@ struct snd_soc_pcm_stream {
unsigned int rate_max; /* max rate */ unsigned int rate_max; /* max rate */
unsigned int channels_min; /* min channels */ unsigned int channels_min; /* min channels */
unsigned int channels_max; /* max channels */ unsigned int channels_max; /* max channels */
unsigned int active; /* num of active users of the stream */ unsigned int active; /* stream is in use */
void *dma_data; /* used by platform code */ void *dma_data; /* used by platform code */
}; };
......
...@@ -3015,34 +3015,39 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec, ...@@ -3015,34 +3015,39 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
break; break;
case SND_SOC_BIAS_OFF: case SND_SOC_BIAS_OFF:
/* Switch over to startup biases */ if (codec->bias_level == SND_SOC_BIAS_STANDBY) {
snd_soc_update_bits(codec, WM8994_ANTIPOP_2, /* Switch over to startup biases */
WM8994_BIAS_SRC | WM8994_STARTUP_BIAS_ENA | snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
WM8994_VMID_BUF_ENA | WM8994_BIAS_SRC |
WM8994_VMID_RAMP_MASK, WM8994_STARTUP_BIAS_ENA |
WM8994_BIAS_SRC | WM8994_STARTUP_BIAS_ENA | WM8994_VMID_BUF_ENA |
WM8994_VMID_BUF_ENA | WM8994_VMID_RAMP_MASK,
(1 << WM8994_VMID_RAMP_SHIFT)); WM8994_BIAS_SRC |
WM8994_STARTUP_BIAS_ENA |
/* Disable main biases */ WM8994_VMID_BUF_ENA |
snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, (1 << WM8994_VMID_RAMP_SHIFT));
WM8994_BIAS_ENA | WM8994_VMID_SEL_MASK, 0);
/* Discharge line */ /* Disable main biases */
snd_soc_update_bits(codec, WM8994_ANTIPOP_1, snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
WM8994_LINEOUT1_DISCH | WM8994_BIAS_ENA |
WM8994_LINEOUT2_DISCH, WM8994_VMID_SEL_MASK, 0);
WM8994_LINEOUT1_DISCH |
WM8994_LINEOUT2_DISCH);
msleep(5); /* Discharge line */
snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
WM8994_LINEOUT1_DISCH |
WM8994_LINEOUT2_DISCH,
WM8994_LINEOUT1_DISCH |
WM8994_LINEOUT2_DISCH);
/* Switch off startup biases */ msleep(5);
snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
WM8994_BIAS_SRC | WM8994_STARTUP_BIAS_ENA |
WM8994_VMID_BUF_ENA |
WM8994_VMID_RAMP_MASK, 0);
/* Switch off startup biases */
snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
WM8994_BIAS_SRC |
WM8994_STARTUP_BIAS_ENA |
WM8994_VMID_BUF_ENA |
WM8994_VMID_RAMP_MASK, 0);
}
break; break;
} }
codec->bias_level = level; codec->bias_level = level;
...@@ -3866,11 +3871,12 @@ static int wm8994_codec_probe(struct platform_device *pdev) ...@@ -3866,11 +3871,12 @@ static int wm8994_codec_probe(struct platform_device *pdev)
case 3: case 3:
wm8994->hubs.dcs_codes = -5; wm8994->hubs.dcs_codes = -5;
wm8994->hubs.hp_startup_mode = 1; wm8994->hubs.hp_startup_mode = 1;
wm8994->hubs.dcs_readback_mode = 1;
break; break;
default: default:
wm8994->hubs.dcs_readback_mode = 1;
break; break;
} }
ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC1_DET, ret = wm8994_request_irq(codec->control_data, WM8994_IRQ_MIC1_DET,
wm8994_mic_irq, "Mic 1 detect", wm8994); wm8994_mic_irq, "Mic 1 detect", wm8994);
......
...@@ -62,21 +62,27 @@ static const char *speaker_mode_text[] = { ...@@ -62,21 +62,27 @@ static const char *speaker_mode_text[] = {
static const struct soc_enum speaker_mode = static const struct soc_enum speaker_mode =
SOC_ENUM_SINGLE(WM8993_SPKMIXR_ATTENUATION, 8, 2, speaker_mode_text); SOC_ENUM_SINGLE(WM8993_SPKMIXR_ATTENUATION, 8, 2, speaker_mode_text);
static void wait_for_dc_servo(struct snd_soc_codec *codec) static void wait_for_dc_servo(struct snd_soc_codec *codec, unsigned int op)
{ {
unsigned int reg; unsigned int reg;
int count = 0; int count = 0;
unsigned int val;
val = op | WM8993_DCS_ENA_CHAN_0 | WM8993_DCS_ENA_CHAN_1;
/* Trigger the command */
snd_soc_write(codec, WM8993_DC_SERVO_0, val);
dev_dbg(codec->dev, "Waiting for DC servo...\n"); dev_dbg(codec->dev, "Waiting for DC servo...\n");
do { do {
count++; count++;
msleep(1); msleep(1);
reg = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_0); reg = snd_soc_read(codec, WM8993_DC_SERVO_0);
dev_dbg(codec->dev, "DC servo: %x\n", reg); dev_dbg(codec->dev, "DC servo: %x\n", reg);
} while (reg & WM8993_DCS_DATAPATH_BUSY && count < 400); } while (reg & op && count < 400);
if (reg & WM8993_DCS_DATAPATH_BUSY) if (reg & op)
dev_err(codec->dev, "Timed out waiting for DC Servo\n"); dev_err(codec->dev, "Timed out waiting for DC Servo\n");
} }
...@@ -86,51 +92,58 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec) ...@@ -86,51 +92,58 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec)
static void calibrate_dc_servo(struct snd_soc_codec *codec) static void calibrate_dc_servo(struct snd_soc_codec *codec)
{ {
struct wm_hubs_data *hubs = codec->private_data; struct wm_hubs_data *hubs = codec->private_data;
u16 reg, dcs_cfg; u16 reg, reg_l, reg_r, dcs_cfg;
/* Set for 32 series updates */ /* Set for 32 series updates */
snd_soc_update_bits(codec, WM8993_DC_SERVO_1, snd_soc_update_bits(codec, WM8993_DC_SERVO_1,
WM8993_DCS_SERIES_NO_01_MASK, WM8993_DCS_SERIES_NO_01_MASK,
32 << WM8993_DCS_SERIES_NO_01_SHIFT); 32 << WM8993_DCS_SERIES_NO_01_SHIFT);
wait_for_dc_servo(codec,
/* Enable the DC servo. Write all bits to avoid triggering startup WM8993_DCS_TRIG_SERIES_0 | WM8993_DCS_TRIG_SERIES_1);
* or write calibration.
*/
snd_soc_update_bits(codec, WM8993_DC_SERVO_0,
0xFFFF,
WM8993_DCS_ENA_CHAN_0 |
WM8993_DCS_ENA_CHAN_1 |
WM8993_DCS_TRIG_SERIES_1 |
WM8993_DCS_TRIG_SERIES_0);
wait_for_dc_servo(codec);
/* Apply correction to DC servo result */ /* Apply correction to DC servo result */
if (hubs->dcs_codes) { if (hubs->dcs_codes) {
dev_dbg(codec->dev, "Applying %d code DC servo correction\n", dev_dbg(codec->dev, "Applying %d code DC servo correction\n",
hubs->dcs_codes); hubs->dcs_codes);
/* Different chips in the family support different
* readback methods.
*/
switch (hubs->dcs_readback_mode) {
case 0:
reg_l = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1)
& WM8993_DCS_INTEG_CHAN_0_MASK;;
reg_r = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2)
& WM8993_DCS_INTEG_CHAN_1_MASK;
break;
case 1:
reg = snd_soc_read(codec, WM8993_DC_SERVO_3);
reg_l = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK)
>> WM8993_DCS_DAC_WR_VAL_1_SHIFT;
reg_r = reg & WM8993_DCS_DAC_WR_VAL_0_MASK;
break;
default:
WARN(1, "Unknown DCS readback method");
break;
}
/* HPOUT1L */ /* HPOUT1L */
reg = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1) & if (reg_l + hubs->dcs_codes > 0 &&
WM8993_DCS_INTEG_CHAN_0_MASK;; reg_l + hubs->dcs_codes < 0xff)
reg += hubs->dcs_codes; reg_l += hubs->dcs_codes;
dcs_cfg = reg << WM8993_DCS_DAC_WR_VAL_1_SHIFT; dcs_cfg = reg_l << WM8993_DCS_DAC_WR_VAL_1_SHIFT;
/* HPOUT1R */ /* HPOUT1R */
reg = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2) & if (reg_r + hubs->dcs_codes > 0 &&
WM8993_DCS_INTEG_CHAN_1_MASK; reg_r + hubs->dcs_codes < 0xff)
reg += hubs->dcs_codes; reg_r += hubs->dcs_codes;
dcs_cfg |= reg; dcs_cfg |= reg_r;
/* Do it */ /* Do it */
snd_soc_write(codec, WM8993_DC_SERVO_3, dcs_cfg); snd_soc_write(codec, WM8993_DC_SERVO_3, dcs_cfg);
snd_soc_update_bits(codec, WM8993_DC_SERVO_0, wait_for_dc_servo(codec,
WM8993_DCS_TRIG_DAC_WR_0 | WM8993_DCS_TRIG_DAC_WR_0 |
WM8993_DCS_TRIG_DAC_WR_1, WM8993_DCS_TRIG_DAC_WR_1);
WM8993_DCS_TRIG_DAC_WR_0 |
WM8993_DCS_TRIG_DAC_WR_1);
wait_for_dc_servo(codec);
} }
} }
...@@ -141,10 +154,16 @@ static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol, ...@@ -141,10 +154,16 @@ static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol) struct snd_ctl_elem_value *ucontrol)
{ {
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
struct wm_hubs_data *hubs = codec->private_data;
int ret; int ret;
ret = snd_soc_put_volsw_2r(kcontrol, ucontrol); ret = snd_soc_put_volsw_2r(kcontrol, ucontrol);
/* If we're applying an offset correction then updating the
* callibration would be likely to introduce further offsets. */
if (hubs->dcs_codes)
return ret;
/* Only need to do this if the outputs are active */ /* Only need to do this if the outputs are active */
if (snd_soc_read(codec, WM8993_POWER_MANAGEMENT_1) if (snd_soc_read(codec, WM8993_POWER_MANAGEMENT_1)
& (WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA)) & (WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA))
......
...@@ -21,6 +21,7 @@ extern const unsigned int wm_hubs_spkmix_tlv[]; ...@@ -21,6 +21,7 @@ extern const unsigned int wm_hubs_spkmix_tlv[];
/* This *must* be the first element of the codec->private_data struct */ /* This *must* be the first element of the codec->private_data struct */
struct wm_hubs_data { struct wm_hubs_data {
int dcs_codes; int dcs_codes;
int dcs_readback_mode;
int hp_startup_mode; int hp_startup_mode;
}; };
......
...@@ -60,12 +60,11 @@ static void omap_pcm_dma_irq(int ch, u16 stat, void *data) ...@@ -60,12 +60,11 @@ static void omap_pcm_dma_irq(int ch, u16 stat, void *data)
struct omap_runtime_data *prtd = runtime->private_data; struct omap_runtime_data *prtd = runtime->private_data;
unsigned long flags; unsigned long flags;
if ((cpu_is_omap1510()) && if ((cpu_is_omap1510())) {
(substream->stream == SNDRV_PCM_STREAM_PLAYBACK)) {
/* /*
* OMAP1510 doesn't fully support DMA progress counter * OMAP1510 doesn't fully support DMA progress counter
* and there is no software emulation implemented yet, * and there is no software emulation implemented yet,
* so have to maintain our own playback progress counter * so have to maintain our own progress counters
* that can be used by omap_pcm_pointer() instead. * that can be used by omap_pcm_pointer() instead.
*/ */
spin_lock_irqsave(&prtd->lock, flags); spin_lock_irqsave(&prtd->lock, flags);
...@@ -191,8 +190,7 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream) ...@@ -191,8 +190,7 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream)
dma_params.frame_count = runtime->periods; dma_params.frame_count = runtime->periods;
omap_set_dma_params(prtd->dma_ch, &dma_params); omap_set_dma_params(prtd->dma_ch, &dma_params);
if ((cpu_is_omap1510()) && if ((cpu_is_omap1510()))
(substream->stream == SNDRV_PCM_STREAM_PLAYBACK))
omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ | omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ |
OMAP_DMA_LAST_IRQ | OMAP_DMA_BLOCK_IRQ); OMAP_DMA_LAST_IRQ | OMAP_DMA_BLOCK_IRQ);
else else
...@@ -250,14 +248,15 @@ static snd_pcm_uframes_t omap_pcm_pointer(struct snd_pcm_substream *substream) ...@@ -250,14 +248,15 @@ static snd_pcm_uframes_t omap_pcm_pointer(struct snd_pcm_substream *substream)
dma_addr_t ptr; dma_addr_t ptr;
snd_pcm_uframes_t offset; snd_pcm_uframes_t offset;
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { if (cpu_is_omap1510()) {
offset = prtd->period_index * runtime->period_size;
} else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) {
ptr = omap_get_dma_dst_pos(prtd->dma_ch); ptr = omap_get_dma_dst_pos(prtd->dma_ch);
offset = bytes_to_frames(runtime, ptr - runtime->dma_addr); offset = bytes_to_frames(runtime, ptr - runtime->dma_addr);
} else if (!(cpu_is_omap1510())) { } else {
ptr = omap_get_dma_src_pos(prtd->dma_ch); ptr = omap_get_dma_src_pos(prtd->dma_ch);
offset = bytes_to_frames(runtime, ptr - runtime->dma_addr); offset = bytes_to_frames(runtime, ptr - runtime->dma_addr);
} else }
offset = prtd->period_index * runtime->period_size;
if (offset >= runtime->buffer_size) if (offset >= runtime->buffer_size)
offset = 0; offset = 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment