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
This commit is contained in:
@@ -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,18 +3015,22 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SND_SOC_BIAS_OFF:
|
case SND_SOC_BIAS_OFF:
|
||||||
|
if (codec->bias_level == SND_SOC_BIAS_STANDBY) {
|
||||||
/* Switch over to startup biases */
|
/* Switch over to startup biases */
|
||||||
snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
|
snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
|
||||||
WM8994_BIAS_SRC | WM8994_STARTUP_BIAS_ENA |
|
WM8994_BIAS_SRC |
|
||||||
|
WM8994_STARTUP_BIAS_ENA |
|
||||||
WM8994_VMID_BUF_ENA |
|
WM8994_VMID_BUF_ENA |
|
||||||
WM8994_VMID_RAMP_MASK,
|
WM8994_VMID_RAMP_MASK,
|
||||||
WM8994_BIAS_SRC | WM8994_STARTUP_BIAS_ENA |
|
WM8994_BIAS_SRC |
|
||||||
|
WM8994_STARTUP_BIAS_ENA |
|
||||||
WM8994_VMID_BUF_ENA |
|
WM8994_VMID_BUF_ENA |
|
||||||
(1 << WM8994_VMID_RAMP_SHIFT));
|
(1 << WM8994_VMID_RAMP_SHIFT));
|
||||||
|
|
||||||
/* Disable main biases */
|
/* Disable main biases */
|
||||||
snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
|
snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1,
|
||||||
WM8994_BIAS_ENA | WM8994_VMID_SEL_MASK, 0);
|
WM8994_BIAS_ENA |
|
||||||
|
WM8994_VMID_SEL_MASK, 0);
|
||||||
|
|
||||||
/* Discharge line */
|
/* Discharge line */
|
||||||
snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
|
snd_soc_update_bits(codec, WM8994_ANTIPOP_1,
|
||||||
@@ -3039,10 +3043,11 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec,
|
|||||||
|
|
||||||
/* Switch off startup biases */
|
/* Switch off startup biases */
|
||||||
snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
|
snd_soc_update_bits(codec, WM8994_ANTIPOP_2,
|
||||||
WM8994_BIAS_SRC | WM8994_STARTUP_BIAS_ENA |
|
WM8994_BIAS_SRC |
|
||||||
|
WM8994_STARTUP_BIAS_ENA |
|
||||||
WM8994_VMID_BUF_ENA |
|
WM8994_VMID_BUF_ENA |
|
||||||
WM8994_VMID_RAMP_MASK, 0);
|
WM8994_VMID_RAMP_MASK, 0);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
codec->bias_level = level;
|
codec->bias_level = level;
|
||||||
@@ -3866,12 +3871,13 @@ 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);
|
||||||
if (ret != 0)
|
if (ret != 0)
|
||||||
|
@@ -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)
|
|||||||
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_1,
|
|
||||||
WM8993_DCS_TRIG_DAC_WR_0 |
|
WM8993_DCS_TRIG_DAC_WR_0 |
|
||||||
WM8993_DCS_TRIG_DAC_WR_1);
|
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,
|
|||||||
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[];
|
|||||||
/* 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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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;
|
||||||
|
Reference in New Issue
Block a user