Commit 7445c995 authored by Takashi Iwai's avatar Takashi Iwai

Merge branch 'fix/asoc' into for-linus

parents 1172234c 5f712b2b
...@@ -219,7 +219,6 @@ struct snd_soc_dai { ...@@ -219,7 +219,6 @@ struct snd_soc_dai {
struct snd_soc_codec *codec; struct snd_soc_codec *codec;
unsigned int active; unsigned int active;
unsigned char pop_wait:1; unsigned char pop_wait:1;
void *dma_data;
/* DAI private data */ /* DAI private data */
void *private_data; void *private_data;
...@@ -230,4 +229,21 @@ struct snd_soc_dai { ...@@ -230,4 +229,21 @@ struct snd_soc_dai {
struct list_head list; struct list_head list;
}; };
static inline void *snd_soc_dai_get_dma_data(const struct snd_soc_dai *dai,
const struct snd_pcm_substream *ss)
{
return (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) ?
dai->playback.dma_data : dai->capture.dma_data;
}
static inline void snd_soc_dai_set_dma_data(struct snd_soc_dai *dai,
const struct snd_pcm_substream *ss,
void *data)
{
if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK)
dai->playback.dma_data = data;
else
dai->capture.dma_data = data;
}
#endif #endif
...@@ -375,6 +375,7 @@ struct snd_soc_pcm_stream { ...@@ -375,6 +375,7 @@ struct snd_soc_pcm_stream {
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:1; /* stream is in use */ unsigned int active:1; /* stream is in use */
void *dma_data; /* used by platform code */
}; };
/* SoC audio ops */ /* SoC audio ops */
......
...@@ -180,7 +180,7 @@ static int atmel_pcm_hw_params(struct snd_pcm_substream *substream, ...@@ -180,7 +180,7 @@ static int atmel_pcm_hw_params(struct snd_pcm_substream *substream,
snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
runtime->dma_bytes = params_buffer_bytes(params); runtime->dma_bytes = params_buffer_bytes(params);
prtd->params = rtd->dai->cpu_dai->dma_data; prtd->params = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
prtd->params->dma_intr_handler = atmel_pcm_dma_irq; prtd->params->dma_intr_handler = atmel_pcm_dma_irq;
prtd->dma_buffer = runtime->dma_addr; prtd->dma_buffer = runtime->dma_addr;
......
...@@ -363,12 +363,12 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, ...@@ -363,12 +363,12 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream,
ssc_p->dma_params[dir] = dma_params; ssc_p->dma_params[dir] = dma_params;
/* /*
* The cpu_dai->dma_data field is only used to communicate the * The snd_soc_pcm_stream->dma_data field is only used to communicate
* appropriate DMA parameters to the pcm driver hw_params() * the appropriate DMA parameters to the pcm driver hw_params()
* function. It should not be used for other purposes * function. It should not be used for other purposes
* as it is common to all substreams. * as it is common to all substreams.
*/ */
rtd->dai->cpu_dai->dma_data = dma_params; snd_soc_dai_set_dma_data(rtd->dai->cpu_dai, substream, dma_params);
channels = params_channels(params); channels = params_channels(params);
......
...@@ -80,9 +80,11 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg, ...@@ -80,9 +80,11 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
static int ac97_soc_probe(struct platform_device *pdev) static int ac97_soc_probe(struct platform_device *pdev)
{ {
struct snd_soc_device *socdev = platform_get_drvdata(pdev); struct snd_soc_device *socdev = platform_get_drvdata(pdev);
struct snd_soc_card *card = socdev->card;
struct snd_soc_codec *codec; struct snd_soc_codec *codec;
struct snd_ac97_bus *ac97_bus; struct snd_ac97_bus *ac97_bus;
struct snd_ac97_template ac97_template; struct snd_ac97_template ac97_template;
int i;
int ret = 0; int ret = 0;
printk(KERN_INFO "AC97 SoC Audio Codec %s\n", AC97_VERSION); printk(KERN_INFO "AC97 SoC Audio Codec %s\n", AC97_VERSION);
...@@ -102,12 +104,6 @@ static int ac97_soc_probe(struct platform_device *pdev) ...@@ -102,12 +104,6 @@ static int ac97_soc_probe(struct platform_device *pdev)
INIT_LIST_HEAD(&codec->dapm_widgets); INIT_LIST_HEAD(&codec->dapm_widgets);
INIT_LIST_HEAD(&codec->dapm_paths); INIT_LIST_HEAD(&codec->dapm_paths);
ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0);
if (ret < 0) {
printk(KERN_ERR "ASoC: failed to init gen ac97 glue\n");
goto err;
}
/* register pcms */ /* register pcms */
ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1);
if (ret < 0) if (ret < 0)
...@@ -123,6 +119,13 @@ static int ac97_soc_probe(struct platform_device *pdev) ...@@ -123,6 +119,13 @@ static int ac97_soc_probe(struct platform_device *pdev)
if (ret < 0) if (ret < 0)
goto bus_err; goto bus_err;
for (i = 0; i < card->num_links; i++) {
if (card->dai_link[i].codec_dai->ac97_control) {
snd_ac97_dev_add_pdata(codec->ac97,
card->dai_link[i].cpu_dai->ac97_pdata);
}
}
return 0; return 0;
bus_err: bus_err:
......
...@@ -3007,18 +3007,22 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec, ...@@ -3007,18 +3007,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,
...@@ -3031,10 +3035,11 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec, ...@@ -3031,10 +3035,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;
...@@ -3401,7 +3406,7 @@ struct snd_soc_dai wm8994_dai[] = { ...@@ -3401,7 +3406,7 @@ struct snd_soc_dai wm8994_dai[] = {
.rates = WM8994_RATES, .rates = WM8994_RATES,
.formats = WM8994_FORMATS, .formats = WM8994_FORMATS,
}, },
.playback = { .capture = {
.stream_name = "AIF3 Capture", .stream_name = "AIF3 Capture",
.channels_min = 2, .channels_min = 2,
.channels_max = 2, .channels_max = 2,
...@@ -3730,12 +3735,13 @@ static int wm8994_codec_probe(struct platform_device *pdev) ...@@ -3730,12 +3735,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;
} }
/* Remember if AIFnLRCLK is configured as a GPIO. This should be /* Remember if AIFnLRCLK is configured as a GPIO. This should be
* configured on init - if a system wants to do this dynamically * configured on init - if a system wants to do this dynamically
* at runtime we can deal with that then. * at runtime we can deal with that then.
......
...@@ -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_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, ...@@ -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;
}; };
......
...@@ -585,7 +585,8 @@ static int davinci_i2s_probe(struct platform_device *pdev) ...@@ -585,7 +585,8 @@ static int davinci_i2s_probe(struct platform_device *pdev)
dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel = res->start; dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel = res->start;
davinci_i2s_dai.private_data = dev; davinci_i2s_dai.private_data = dev;
davinci_i2s_dai.dma_data = dev->dma_params; davinci_i2s_dai.capture.dma_data = dev->dma_params;
davinci_i2s_dai.playback.dma_data = dev->dma_params;
ret = snd_soc_register_dai(&davinci_i2s_dai); ret = snd_soc_register_dai(&davinci_i2s_dai);
if (ret != 0) if (ret != 0)
goto err_free_mem; goto err_free_mem;
......
...@@ -917,7 +917,8 @@ static int davinci_mcasp_probe(struct platform_device *pdev) ...@@ -917,7 +917,8 @@ static int davinci_mcasp_probe(struct platform_device *pdev)
dma_data->channel = res->start; dma_data->channel = res->start;
davinci_mcasp_dai[pdata->op_mode].private_data = dev; davinci_mcasp_dai[pdata->op_mode].private_data = dev;
davinci_mcasp_dai[pdata->op_mode].dma_data = dev->dma_params; davinci_mcasp_dai[pdata->op_mode].capture.dma_data = dev->dma_params;
davinci_mcasp_dai[pdata->op_mode].playback.dma_data = dev->dma_params;
davinci_mcasp_dai[pdata->op_mode].dev = &pdev->dev; davinci_mcasp_dai[pdata->op_mode].dev = &pdev->dev;
ret = snd_soc_register_dai(&davinci_mcasp_dai[pdata->op_mode]); ret = snd_soc_register_dai(&davinci_mcasp_dai[pdata->op_mode]);
......
...@@ -649,8 +649,10 @@ static int davinci_pcm_open(struct snd_pcm_substream *substream) ...@@ -649,8 +649,10 @@ static int davinci_pcm_open(struct snd_pcm_substream *substream)
struct snd_pcm_hardware *ppcm; struct snd_pcm_hardware *ppcm;
int ret = 0; int ret = 0;
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct davinci_pcm_dma_params *pa = rtd->dai->cpu_dai->dma_data; struct davinci_pcm_dma_params *pa;
struct davinci_pcm_dma_params *params; struct davinci_pcm_dma_params *params;
pa = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
if (!pa) if (!pa)
return -ENODEV; return -ENODEV;
params = &pa[substream->stream]; params = &pa[substream->stream];
......
...@@ -83,11 +83,13 @@ static void snd_imx_dma_err_callback(int channel, void *data, int err) ...@@ -83,11 +83,13 @@ static void snd_imx_dma_err_callback(int channel, void *data, int err)
static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream) static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream)
{ {
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct imx_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data; struct imx_pcm_dma_params *dma_params;
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
struct imx_pcm_runtime_data *iprtd = runtime->private_data; struct imx_pcm_runtime_data *iprtd = runtime->private_data;
int ret; int ret;
dma_params = snd_soc_get_dma_data(rtd->dai->cpu_dai, substream);
iprtd->dma = imx_dma_request_by_prio(DRV_NAME, DMA_PRIO_HIGH); iprtd->dma = imx_dma_request_by_prio(DRV_NAME, DMA_PRIO_HIGH);
if (iprtd->dma < 0) { if (iprtd->dma < 0) {
pr_err("Failed to claim the audio DMA\n"); pr_err("Failed to claim the audio DMA\n");
...@@ -192,10 +194,12 @@ static int snd_imx_pcm_prepare(struct snd_pcm_substream *substream) ...@@ -192,10 +194,12 @@ static int snd_imx_pcm_prepare(struct snd_pcm_substream *substream)
{ {
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct imx_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data; struct imx_pcm_dma_params *dma_params;
struct imx_pcm_runtime_data *iprtd = runtime->private_data; struct imx_pcm_runtime_data *iprtd = runtime->private_data;
int err; int err;
dma_params = snd_soc_get_dma_data(rtd->dai->cpu_dai, substream);
iprtd->substream = substream; iprtd->substream = substream;
iprtd->buf = (unsigned int *)substream->dma_buffer.area; iprtd->buf = (unsigned int *)substream->dma_buffer.area;
iprtd->period_cnt = 0; iprtd->period_cnt = 0;
......
...@@ -234,17 +234,20 @@ static int imx_ssi_hw_params(struct snd_pcm_substream *substream, ...@@ -234,17 +234,20 @@ static int imx_ssi_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *cpu_dai) struct snd_soc_dai *cpu_dai)
{ {
struct imx_ssi *ssi = cpu_dai->private_data; struct imx_ssi *ssi = cpu_dai->private_data;
struct imx_pcm_dma_params *dma_data;
u32 reg, sccr; u32 reg, sccr;
/* Tx/Rx config */ /* Tx/Rx config */
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
reg = SSI_STCCR; reg = SSI_STCCR;
cpu_dai->dma_data = &ssi->dma_params_tx; dma_data = &ssi->dma_params_tx;
} else { } else {
reg = SSI_SRCCR; reg = SSI_SRCCR;
cpu_dai->dma_data = &ssi->dma_params_rx; dma_data = &ssi->dma_params_rx;
} }
snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
sccr = readl(ssi->base + reg) & ~SSI_STCCR_WL_MASK; sccr = readl(ssi->base + reg) & ~SSI_STCCR_WL_MASK;
/* DAI data (word) size */ /* DAI data (word) size */
......
...@@ -297,7 +297,9 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, ...@@ -297,7 +297,9 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream,
omap_mcbsp_dai_dma_params[id][substream->stream].sync_mode = sync_mode; omap_mcbsp_dai_dma_params[id][substream->stream].sync_mode = sync_mode;
omap_mcbsp_dai_dma_params[id][substream->stream].data_type = omap_mcbsp_dai_dma_params[id][substream->stream].data_type =
OMAP_DMA_DATA_TYPE_S16; OMAP_DMA_DATA_TYPE_S16;
cpu_dai->dma_data = &omap_mcbsp_dai_dma_params[id][substream->stream];
snd_soc_dai_set_dma_data(cpu_dai, substream,
&omap_mcbsp_dai_dma_params[id][substream->stream]);
if (mcbsp_data->configured) { if (mcbsp_data->configured) {
/* McBSP already configured by another stream */ /* McBSP already configured by another stream */
......
...@@ -150,7 +150,8 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream, ...@@ -150,7 +150,8 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream,
int stream = substream->stream; int stream = substream->stream;
int channels, err, link_mask = 0; int channels, err, link_mask = 0;
cpu_dai->dma_data = &omap_mcpdm_dai_dma_params[stream]; snd_soc_dai_set_dma_data(cpu_dai, substream,
&omap_mcpdm_dai_dma_params[stream]);
channels = params_channels(params); channels = params_channels(params);
switch (channels) { switch (channels) {
......
...@@ -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);
...@@ -100,9 +99,11 @@ static int omap_pcm_hw_params(struct snd_pcm_substream *substream, ...@@ -100,9 +99,11 @@ static int omap_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct omap_runtime_data *prtd = runtime->private_data; struct omap_runtime_data *prtd = runtime->private_data;
struct omap_pcm_dma_data *dma_data = rtd->dai->cpu_dai->dma_data; struct omap_pcm_dma_data *dma_data;
int err = 0; int err = 0;
dma_data = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
/* return if this is a bufferless transfer e.g. /* return if this is a bufferless transfer e.g.
* codec <--> BT codec or GSM modem -- lg FIXME */ * codec <--> BT codec or GSM modem -- lg FIXME */
if (!dma_data) if (!dma_data)
...@@ -189,8 +190,7 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream) ...@@ -189,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
...@@ -248,14 +248,15 @@ static snd_pcm_uframes_t omap_pcm_pointer(struct snd_pcm_substream *substream) ...@@ -248,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;
......
...@@ -121,10 +121,9 @@ static int pxa_ssp_startup(struct snd_pcm_substream *substream, ...@@ -121,10 +121,9 @@ static int pxa_ssp_startup(struct snd_pcm_substream *substream,
ssp_disable(ssp); ssp_disable(ssp);
} }
if (cpu_dai->dma_data) { kfree(snd_soc_dai_get_dma_data(cpu_dai, substream));
kfree(cpu_dai->dma_data); snd_soc_dai_set_dma_data(cpu_dai, substream, NULL);
cpu_dai->dma_data = NULL;
}
return ret; return ret;
} }
...@@ -141,10 +140,8 @@ static void pxa_ssp_shutdown(struct snd_pcm_substream *substream, ...@@ -141,10 +140,8 @@ static void pxa_ssp_shutdown(struct snd_pcm_substream *substream,
clk_disable(ssp->clk); clk_disable(ssp->clk);
} }
if (cpu_dai->dma_data) { kfree(snd_soc_dai_get_dma_data(cpu_dai, substream));
kfree(cpu_dai->dma_data); snd_soc_dai_set_dma_data(cpu_dai, substream, NULL);
cpu_dai->dma_data = NULL;
}
} }
#ifdef CONFIG_PM #ifdef CONFIG_PM
...@@ -569,19 +566,23 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream, ...@@ -569,19 +566,23 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream,
u32 sspsp; u32 sspsp;
int width = snd_pcm_format_physical_width(params_format(params)); int width = snd_pcm_format_physical_width(params_format(params));
int ttsa = ssp_read_reg(ssp, SSTSA) & 0xf; int ttsa = ssp_read_reg(ssp, SSTSA) & 0xf;
struct pxa2xx_pcm_dma_params *dma_data;
dma_data = snd_soc_dai_get_dma_data(dai, substream);
/* generate correct DMA params */ /* generate correct DMA params */
if (cpu_dai->dma_data) kfree(dma_data);
kfree(cpu_dai->dma_data);
/* Network mode with one active slot (ttsa == 1) can be used /* Network mode with one active slot (ttsa == 1) can be used
* to force 16-bit frame width on the wire (for S16_LE), even * to force 16-bit frame width on the wire (for S16_LE), even
* with two channels. Use 16-bit DMA transfers for this case. * with two channels. Use 16-bit DMA transfers for this case.
*/ */
cpu_dai->dma_data = ssp_get_dma_params(ssp, dma_data = ssp_get_dma_params(ssp,
((chn == 2) && (ttsa != 1)) || (width == 32), ((chn == 2) && (ttsa != 1)) || (width == 32),
substream->stream == SNDRV_PCM_STREAM_PLAYBACK); substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
snd_soc_dai_set_dma_data(dai, substream, dma_data);
/* we can only change the settings if the port is not in use */ /* we can only change the settings if the port is not in use */
if (ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) if (ssp_read_reg(ssp, SSCR0) & SSCR0_SSE)
return 0; return 0;
......
...@@ -122,11 +122,14 @@ static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream, ...@@ -122,11 +122,14 @@ static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream,
{ {
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
struct pxa2xx_pcm_dma_params *dma_data;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
cpu_dai->dma_data = &pxa2xx_ac97_pcm_stereo_out; dma_data = &pxa2xx_ac97_pcm_stereo_out;
else else
cpu_dai->dma_data = &pxa2xx_ac97_pcm_stereo_in; dma_data = &pxa2xx_ac97_pcm_stereo_in;
snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
return 0; return 0;
} }
...@@ -137,11 +140,14 @@ static int pxa2xx_ac97_hw_aux_params(struct snd_pcm_substream *substream, ...@@ -137,11 +140,14 @@ static int pxa2xx_ac97_hw_aux_params(struct snd_pcm_substream *substream,
{ {
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
struct pxa2xx_pcm_dma_params *dma_data;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
cpu_dai->dma_data = &pxa2xx_ac97_pcm_aux_mono_out; dma_data = &pxa2xx_ac97_pcm_aux_mono_out;
else else
cpu_dai->dma_data = &pxa2xx_ac97_pcm_aux_mono_in; dma_data = &pxa2xx_ac97_pcm_aux_mono_in;
snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
return 0; return 0;
} }
...@@ -156,7 +162,8 @@ static int pxa2xx_ac97_hw_mic_params(struct snd_pcm_substream *substream, ...@@ -156,7 +162,8 @@ static int pxa2xx_ac97_hw_mic_params(struct snd_pcm_substream *substream,
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
return -ENODEV; return -ENODEV;
else else
cpu_dai->dma_data = &pxa2xx_ac97_pcm_mic_mono_in; snd_soc_dai_set_dma_data(cpu_dai, substream,
&pxa2xx_ac97_pcm_mic_mono_in);
return 0; return 0;
} }
......
...@@ -164,6 +164,7 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream, ...@@ -164,6 +164,7 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream,
{ {
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
struct pxa2xx_pcm_dma_params *dma_data;
BUG_ON(IS_ERR(clk_i2s)); BUG_ON(IS_ERR(clk_i2s));
clk_enable(clk_i2s); clk_enable(clk_i2s);
...@@ -171,9 +172,11 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream, ...@@ -171,9 +172,11 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream,
pxa_i2s_wait(); pxa_i2s_wait();
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
cpu_dai->dma_data = &pxa2xx_i2s_pcm_stereo_out; dma_data = &pxa2xx_i2s_pcm_stereo_out;
else else
cpu_dai->dma_data = &pxa2xx_i2s_pcm_stereo_in; dma_data = &pxa2xx_i2s_pcm_stereo_in;
snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
/* is port used by another stream */ /* is port used by another stream */
if (!(SACR0 & SACR0_ENB)) { if (!(SACR0 & SACR0_ENB)) {
......
...@@ -25,9 +25,11 @@ static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream, ...@@ -25,9 +25,11 @@ static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
struct pxa2xx_runtime_data *prtd = runtime->private_data; struct pxa2xx_runtime_data *prtd = runtime->private_data;
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct pxa2xx_pcm_dma_params *dma = rtd->dai->cpu_dai->dma_data; struct pxa2xx_pcm_dma_params *dma;
int ret; int ret;
dma = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
/* return if this is a bufferless transfer e.g. /* return if this is a bufferless transfer e.g.
* codec <--> BT codec or GSM modem -- lg FIXME */ * codec <--> BT codec or GSM modem -- lg FIXME */
if (!dma) if (!dma)
......
...@@ -224,11 +224,14 @@ static int s3c_ac97_hw_params(struct snd_pcm_substream *substream, ...@@ -224,11 +224,14 @@ static int s3c_ac97_hw_params(struct snd_pcm_substream *substream,
{ {
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai;
struct s3c_dma_params *dma_data;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
cpu_dai->dma_data = &s3c_ac97_pcm_out; dma_data = &s3c_ac97_pcm_out;
else else
cpu_dai->dma_data = &s3c_ac97_pcm_in; dma_data = &s3c_ac97_pcm_in;
snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data);
return 0; return 0;
} }
...@@ -238,8 +241,8 @@ static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd, ...@@ -238,8 +241,8 @@ static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
{ {
u32 ac_glbctrl; u32 ac_glbctrl;
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data;
int channel = ((struct s3c_dma_params *) struct s3c_dma_params *dma_data =
rtd->dai->cpu_dai->dma_data)->channel; snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) if (substream->stream == SNDRV_PCM_STREAM_CAPTURE)
...@@ -265,7 +268,7 @@ static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd, ...@@ -265,7 +268,7 @@ static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd,
writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED); s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED);
return 0; return 0;
} }
...@@ -280,7 +283,7 @@ static int s3c_ac97_hw_mic_params(struct snd_pcm_substream *substream, ...@@ -280,7 +283,7 @@ static int s3c_ac97_hw_mic_params(struct snd_pcm_substream *substream,
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
return -ENODEV; return -ENODEV;
else else
cpu_dai->dma_data = &s3c_ac97_mic_in; snd_soc_dai_set_dma_data(cpu_dai, substream, &s3c_ac97_mic_in);
return 0; return 0;
} }
...@@ -290,8 +293,8 @@ static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream, ...@@ -290,8 +293,8 @@ static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream,
{ {
u32 ac_glbctrl; u32 ac_glbctrl;
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data;
int channel = ((struct s3c_dma_params *) struct s3c_dma_params *dma_data =
rtd->dai->cpu_dai->dma_data)->channel; snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL);
ac_glbctrl &= ~S3C_AC97_GLBCTRL_MICINTM_MASK; ac_glbctrl &= ~S3C_AC97_GLBCTRL_MICINTM_MASK;
...@@ -311,7 +314,7 @@ static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream, ...@@ -311,7 +314,7 @@ static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream,
writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL);
s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED); s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED);
return 0; return 0;
} }
......
...@@ -145,10 +145,12 @@ static int s3c_dma_hw_params(struct snd_pcm_substream *substream, ...@@ -145,10 +145,12 @@ static int s3c_dma_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
struct s3c24xx_runtime_data *prtd = runtime->private_data; struct s3c24xx_runtime_data *prtd = runtime->private_data;
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct s3c_dma_params *dma = rtd->dai->cpu_dai->dma_data;
unsigned long totbytes = params_buffer_bytes(params); unsigned long totbytes = params_buffer_bytes(params);
struct s3c_dma_params *dma =
snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
int ret = 0; int ret = 0;
pr_debug("Entered %s\n", __func__); pr_debug("Entered %s\n", __func__);
/* return if this is a bufferless transfer e.g. /* return if this is a bufferless transfer e.g.
......
...@@ -339,14 +339,17 @@ static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream, ...@@ -339,14 +339,17 @@ static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai_link *dai = rtd->dai; struct snd_soc_dai_link *dai = rtd->dai;
struct s3c_i2sv2_info *i2s = to_info(dai->cpu_dai); struct s3c_i2sv2_info *i2s = to_info(dai->cpu_dai);
struct s3c_dma_params *dma_data;
u32 iismod; u32 iismod;
pr_debug("Entered %s\n", __func__); pr_debug("Entered %s\n", __func__);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
dai->cpu_dai->dma_data = i2s->dma_playback; dma_data = i2s->dma_playback;
else else
dai->cpu_dai->dma_data = i2s->dma_capture; dma_data = i2s->dma_capture;
snd_soc_dai_set_dma_data(dai->cpu_dai, substream, dma_data);
/* Working copies of register */ /* Working copies of register */
iismod = readl(i2s->regs + S3C2412_IISMOD); iismod = readl(i2s->regs + S3C2412_IISMOD);
...@@ -394,8 +397,8 @@ static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd, ...@@ -394,8 +397,8 @@ static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE);
unsigned long irqs; unsigned long irqs;
int ret = 0; int ret = 0;
int channel = ((struct s3c_dma_params *) struct s3c_dma_params *dma_data =
rtd->dai->cpu_dai->dma_data)->channel; snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
pr_debug("Entered %s\n", __func__); pr_debug("Entered %s\n", __func__);
...@@ -431,7 +434,7 @@ static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd, ...@@ -431,7 +434,7 @@ static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
* of the auto reload mechanism of S3C24XX. * of the auto reload mechanism of S3C24XX.
* This call won't bother S3C64XX. * This call won't bother S3C64XX.
*/ */
s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED); s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED);
break; break;
......
...@@ -178,6 +178,7 @@ static int s3c_pcm_hw_params(struct snd_pcm_substream *substream, ...@@ -178,6 +178,7 @@ static int s3c_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct snd_soc_dai_link *dai = rtd->dai; struct snd_soc_dai_link *dai = rtd->dai;
struct s3c_pcm_info *pcm = to_info(dai->cpu_dai); struct s3c_pcm_info *pcm = to_info(dai->cpu_dai);
struct s3c_dma_params *dma_data;
void __iomem *regs = pcm->regs; void __iomem *regs = pcm->regs;
struct clk *clk; struct clk *clk;
int sclk_div, sync_div; int sclk_div, sync_div;
...@@ -187,9 +188,11 @@ static int s3c_pcm_hw_params(struct snd_pcm_substream *substream, ...@@ -187,9 +188,11 @@ static int s3c_pcm_hw_params(struct snd_pcm_substream *substream,
dev_dbg(pcm->dev, "Entered %s\n", __func__); dev_dbg(pcm->dev, "Entered %s\n", __func__);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
dai->cpu_dai->dma_data = pcm->dma_playback; dma_data = pcm->dma_playback;
else else
dai->cpu_dai->dma_data = pcm->dma_capture; dma_data = pcm->dma_capture;
snd_soc_dai_set_dma_data(dai->cpu_dai, substream, dma_data);
/* Strictly check for sample size */ /* Strictly check for sample size */
switch (params_format(params)) { switch (params_format(params)) {
......
...@@ -242,14 +242,17 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream, ...@@ -242,14 +242,17 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai) struct snd_soc_dai *dai)
{ {
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct s3c_dma_params *dma_data;
u32 iismod; u32 iismod;
pr_debug("Entered %s\n", __func__); pr_debug("Entered %s\n", __func__);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
rtd->dai->cpu_dai->dma_data = &s3c24xx_i2s_pcm_stereo_out; dma_data = &s3c24xx_i2s_pcm_stereo_out;
else else
rtd->dai->cpu_dai->dma_data = &s3c24xx_i2s_pcm_stereo_in; dma_data = &s3c24xx_i2s_pcm_stereo_in;
snd_soc_dai_set_dma_data(rtd->dai->cpu_dai, substream, dma_data);
/* Working copies of register */ /* Working copies of register */
iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD);
...@@ -258,13 +261,11 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream, ...@@ -258,13 +261,11 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream,
switch (params_format(params)) { switch (params_format(params)) {
case SNDRV_PCM_FORMAT_S8: case SNDRV_PCM_FORMAT_S8:
iismod &= ~S3C2410_IISMOD_16BIT; iismod &= ~S3C2410_IISMOD_16BIT;
((struct s3c_dma_params *) dma_data->dma_size = 1;
rtd->dai->cpu_dai->dma_data)->dma_size = 1;
break; break;
case SNDRV_PCM_FORMAT_S16_LE: case SNDRV_PCM_FORMAT_S16_LE:
iismod |= S3C2410_IISMOD_16BIT; iismod |= S3C2410_IISMOD_16BIT;
((struct s3c_dma_params *) dma_data->dma_size = 2;
rtd->dai->cpu_dai->dma_data)->dma_size = 2;
break; break;
default: default:
return -EINVAL; return -EINVAL;
...@@ -280,8 +281,8 @@ static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd, ...@@ -280,8 +281,8 @@ static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
{ {
int ret = 0; int ret = 0;
struct snd_soc_pcm_runtime *rtd = substream->private_data; struct snd_soc_pcm_runtime *rtd = substream->private_data;
int channel = ((struct s3c_dma_params *) struct s3c_dma_params *dma_data =
rtd->dai->cpu_dai->dma_data)->channel; snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream);
pr_debug("Entered %s\n", __func__); pr_debug("Entered %s\n", __func__);
...@@ -300,7 +301,7 @@ static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd, ...@@ -300,7 +301,7 @@ static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd,
else else
s3c24xx_snd_txctrl(1); s3c24xx_snd_txctrl(1);
s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED); s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED);
break; break;
case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND: case SNDRV_PCM_TRIGGER_SUSPEND:
......
...@@ -518,7 +518,8 @@ static int __devinit s6000_i2s_probe(struct platform_device *pdev) ...@@ -518,7 +518,8 @@ static int __devinit s6000_i2s_probe(struct platform_device *pdev)
s6000_i2s_dai.dev = &pdev->dev; s6000_i2s_dai.dev = &pdev->dev;
s6000_i2s_dai.private_data = dev; s6000_i2s_dai.private_data = dev;
s6000_i2s_dai.dma_data = &dev->dma_params; s6000_i2s_dai.capture.dma_data = &dev->dma_params;
s6000_i2s_dai.playback.dma_data = &dev->dma_params;
dev->sifbase = sifmem->start; dev->sifbase = sifmem->start;
dev->scbbase = mmio; dev->scbbase = mmio;
......
...@@ -58,13 +58,15 @@ static void s6000_pcm_enqueue_dma(struct snd_pcm_substream *substream) ...@@ -58,13 +58,15 @@ static void s6000_pcm_enqueue_dma(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
struct s6000_runtime_data *prtd = runtime->private_data; struct s6000_runtime_data *prtd = runtime->private_data;
struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; struct s6000_pcm_dma_params *par;
int channel; int channel;
unsigned int period_size; unsigned int period_size;
unsigned int dma_offset; unsigned int dma_offset;
dma_addr_t dma_pos; dma_addr_t dma_pos;
dma_addr_t src, dst; dma_addr_t src, dst;
par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
period_size = snd_pcm_lib_period_bytes(substream); period_size = snd_pcm_lib_period_bytes(substream);
dma_offset = prtd->period * period_size; dma_offset = prtd->period * period_size;
dma_pos = runtime->dma_addr + dma_offset; dma_pos = runtime->dma_addr + dma_offset;
...@@ -101,7 +103,8 @@ static irqreturn_t s6000_pcm_irq(int irq, void *data) ...@@ -101,7 +103,8 @@ static irqreturn_t s6000_pcm_irq(int irq, void *data)
{ {
struct snd_pcm *pcm = data; struct snd_pcm *pcm = data;
struct snd_soc_pcm_runtime *runtime = pcm->private_data; struct snd_soc_pcm_runtime *runtime = pcm->private_data;
struct s6000_pcm_dma_params *params = runtime->dai->cpu_dai->dma_data; struct s6000_pcm_dma_params *params =
snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
struct s6000_runtime_data *prtd; struct s6000_runtime_data *prtd;
unsigned int has_xrun; unsigned int has_xrun;
int i, ret = IRQ_NONE; int i, ret = IRQ_NONE;
...@@ -172,11 +175,13 @@ static int s6000_pcm_start(struct snd_pcm_substream *substream) ...@@ -172,11 +175,13 @@ static int s6000_pcm_start(struct snd_pcm_substream *substream)
{ {
struct s6000_runtime_data *prtd = substream->runtime->private_data; struct s6000_runtime_data *prtd = substream->runtime->private_data;
struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; struct s6000_pcm_dma_params *par;
unsigned long flags; unsigned long flags;
int srcinc; int srcinc;
u32 dma; u32 dma;
par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
spin_lock_irqsave(&prtd->lock, flags); spin_lock_irqsave(&prtd->lock, flags);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
...@@ -212,10 +217,12 @@ static int s6000_pcm_stop(struct snd_pcm_substream *substream) ...@@ -212,10 +217,12 @@ static int s6000_pcm_stop(struct snd_pcm_substream *substream)
{ {
struct s6000_runtime_data *prtd = substream->runtime->private_data; struct s6000_runtime_data *prtd = substream->runtime->private_data;
struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; struct s6000_pcm_dma_params *par;
unsigned long flags; unsigned long flags;
u32 channel; u32 channel;
par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
channel = par->dma_out; channel = par->dma_out;
else else
...@@ -236,9 +243,11 @@ static int s6000_pcm_stop(struct snd_pcm_substream *substream) ...@@ -236,9 +243,11 @@ static int s6000_pcm_stop(struct snd_pcm_substream *substream)
static int s6000_pcm_trigger(struct snd_pcm_substream *substream, int cmd) static int s6000_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
{ {
struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; struct s6000_pcm_dma_params *par;
int ret; int ret;
par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
ret = par->trigger(substream, cmd, 0); ret = par->trigger(substream, cmd, 0);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -275,13 +284,15 @@ static int s6000_pcm_prepare(struct snd_pcm_substream *substream) ...@@ -275,13 +284,15 @@ static int s6000_pcm_prepare(struct snd_pcm_substream *substream)
static snd_pcm_uframes_t s6000_pcm_pointer(struct snd_pcm_substream *substream) static snd_pcm_uframes_t s6000_pcm_pointer(struct snd_pcm_substream *substream)
{ {
struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; struct s6000_pcm_dma_params *par;
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
struct s6000_runtime_data *prtd = runtime->private_data; struct s6000_runtime_data *prtd = runtime->private_data;
unsigned long flags; unsigned long flags;
unsigned int offset; unsigned int offset;
dma_addr_t count; dma_addr_t count;
par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
spin_lock_irqsave(&prtd->lock, flags); spin_lock_irqsave(&prtd->lock, flags);
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
...@@ -305,11 +316,12 @@ static snd_pcm_uframes_t s6000_pcm_pointer(struct snd_pcm_substream *substream) ...@@ -305,11 +316,12 @@ static snd_pcm_uframes_t s6000_pcm_pointer(struct snd_pcm_substream *substream)
static int s6000_pcm_open(struct snd_pcm_substream *substream) static int s6000_pcm_open(struct snd_pcm_substream *substream)
{ {
struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; struct s6000_pcm_dma_params *par;
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
struct s6000_runtime_data *prtd; struct s6000_runtime_data *prtd;
int ret; int ret;
par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
snd_soc_set_runtime_hwparams(substream, &s6000_pcm_hardware); snd_soc_set_runtime_hwparams(substream, &s6000_pcm_hardware);
ret = snd_pcm_hw_constraint_step(runtime, 0, ret = snd_pcm_hw_constraint_step(runtime, 0,
...@@ -364,7 +376,7 @@ static int s6000_pcm_hw_params(struct snd_pcm_substream *substream, ...@@ -364,7 +376,7 @@ static int s6000_pcm_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *hw_params) struct snd_pcm_hw_params *hw_params)
{ {
struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; struct s6000_pcm_dma_params *par;
int ret; int ret;
ret = snd_pcm_lib_malloc_pages(substream, ret = snd_pcm_lib_malloc_pages(substream,
params_buffer_bytes(hw_params)); params_buffer_bytes(hw_params));
...@@ -373,6 +385,8 @@ static int s6000_pcm_hw_params(struct snd_pcm_substream *substream, ...@@ -373,6 +385,8 @@ static int s6000_pcm_hw_params(struct snd_pcm_substream *substream,
return ret; return ret;
} }
par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
if (par->same_rate) { if (par->same_rate) {
spin_lock(&par->lock); spin_lock(&par->lock);
if (par->rate == -1 || if (par->rate == -1 ||
...@@ -392,7 +406,8 @@ static int s6000_pcm_hw_params(struct snd_pcm_substream *substream, ...@@ -392,7 +406,8 @@ static int s6000_pcm_hw_params(struct snd_pcm_substream *substream,
static int s6000_pcm_hw_free(struct snd_pcm_substream *substream) static int s6000_pcm_hw_free(struct snd_pcm_substream *substream)
{ {
struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; struct snd_soc_pcm_runtime *soc_runtime = substream->private_data;
struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; struct s6000_pcm_dma_params *par =
snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
spin_lock(&par->lock); spin_lock(&par->lock);
par->in_use &= ~(1 << substream->stream); par->in_use &= ~(1 << substream->stream);
...@@ -417,7 +432,8 @@ static struct snd_pcm_ops s6000_pcm_ops = { ...@@ -417,7 +432,8 @@ static struct snd_pcm_ops s6000_pcm_ops = {
static void s6000_pcm_free(struct snd_pcm *pcm) static void s6000_pcm_free(struct snd_pcm *pcm)
{ {
struct snd_soc_pcm_runtime *runtime = pcm->private_data; struct snd_soc_pcm_runtime *runtime = pcm->private_data;
struct s6000_pcm_dma_params *params = runtime->dai->cpu_dai->dma_data; struct s6000_pcm_dma_params *params =
snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
free_irq(params->irq, pcm); free_irq(params->irq, pcm);
snd_pcm_lib_preallocate_free_for_all(pcm); snd_pcm_lib_preallocate_free_for_all(pcm);
...@@ -429,9 +445,11 @@ static int s6000_pcm_new(struct snd_card *card, ...@@ -429,9 +445,11 @@ static int s6000_pcm_new(struct snd_card *card,
struct snd_soc_dai *dai, struct snd_pcm *pcm) struct snd_soc_dai *dai, struct snd_pcm *pcm)
{ {
struct snd_soc_pcm_runtime *runtime = pcm->private_data; struct snd_soc_pcm_runtime *runtime = pcm->private_data;
struct s6000_pcm_dma_params *params = runtime->dai->cpu_dai->dma_data; struct s6000_pcm_dma_params *params;
int res; int res;
params = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream);
if (!card->dev->dma_mask) if (!card->dev->dma_mask)
card->dev->dma_mask = &s6000_pcm_dmamask; card->dev->dma_mask = &s6000_pcm_dmamask;
if (!card->dev->coherent_dma_mask) if (!card->dev->coherent_dma_mask)
......
...@@ -1548,7 +1548,8 @@ int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid) ...@@ -1548,7 +1548,8 @@ int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid)
mutex_unlock(&codec->mutex); mutex_unlock(&codec->mutex);
return ret; return ret;
} }
if (card->dai_link[i].codec_dai->ac97_control) { /* Check for codec->ac97 to handle the ac97.c fun */
if (card->dai_link[i].codec_dai->ac97_control && codec->ac97) {
snd_ac97_dev_add_pdata(codec->ac97, snd_ac97_dev_add_pdata(codec->ac97,
card->dai_link[i].cpu_dai->ac97_pdata); card->dai_link[i].cpu_dai->ac97_pdata);
} }
......
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