Commit 84db18bb authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6:
  ALSA: mixart: range checking proc file
  ALSA: hda - Fix a wrong array range check in patch_realtek.c
  ALSA: ASoC: move dma_data from snd_soc_dai to snd_soc_pcm_stream
  ALSA: hda - Enable amplifiers on Acer Inspire 6530G
  ASoC: Only do WM8994 bias off transition from standby
  ASoC: Don't use DCS_DATAPATH_BUSY for WM hubs devices
  ASoC: Don't do runtime wm_hubs DC servo updates if using offset correction
  ASoC: Support second DC servo readback method for wm_hubs
  ASoC: Avoid wraparound in wm_hubs DC servo correction
  ALSA: echoaudio - Eliminate use after free
  ALSA: i2c: cleanup: change parameter to pointer
  ALSA: hda - Add MSI blacklist for Aopen MZ915-M
  ASoC: OMAP: Fix capture pointer handling for OMAP1510 to work correctly with recent ALSA PCM code
  ALSA: hda - Update document about MSI and interrupts
  ALSA: hda: Fix 0 dB offset for Lenovo Thinkpad models using AD1981
  ALSA: hda - Add missing printk argument in previous patch
  ASoC: Fix passing platform_data to ac97 bus users and fix a leak
  ALSA: hda - Fix ADC/MUX assignment of ALC269 codec
  ALSA: hda - Fix invalid bit values passed to snd_hda_codec_amp_stereo()
  ASoC: wm8994: playback => capture
parents 6948ec70 55b371d4
...@@ -119,10 +119,18 @@ the codec slots 0 and 1 no matter what the hardware reports. ...@@ -119,10 +119,18 @@ the codec slots 0 and 1 no matter what the hardware reports.
Interrupt Handling Interrupt Handling
~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~
In rare but some cases, the interrupt isn't properly handled as HD-audio driver uses MSI as default (if available) since 2.6.33
default. You would notice this by the DMA transfer error reported by kernel as MSI works better on some machines, and in general, it's
ALSA PCM core, for example. Using MSI might help in such a case. better for performance. However, Nvidia controllers showed bad
Pass `enable_msi=1` option for enabling MSI. regressions with MSI (especially in a combination with AMD chipset),
thus we disabled MSI for them.
There seem also still other devices that don't work with MSI. If you
see a regression wrt the sound quality (stuttering, etc) or a lock-up
in the recent kernel, try to pass `enable_msi=0` option to disable
MSI. If it works, you can add the known bad device to the blacklist
defined in hda_intel.c. In such a case, please report and give the
patch back to the upstream developer.
HD-AUDIO CODEC HD-AUDIO CODEC
......
...@@ -307,7 +307,7 @@ struct ak4113 { ...@@ -307,7 +307,7 @@ struct ak4113 {
int snd_ak4113_create(struct snd_card *card, ak4113_read_t *read, int snd_ak4113_create(struct snd_card *card, ak4113_read_t *read,
ak4113_write_t *write, ak4113_write_t *write,
const unsigned char pgm[AK4113_WRITABLE_REGS], const unsigned char *pgm,
void *private_data, struct ak4113 **r_ak4113); void *private_data, struct ak4113 **r_ak4113);
void snd_ak4113_reg_write(struct ak4113 *ak4113, unsigned char reg, void snd_ak4113_reg_write(struct ak4113 *ak4113, unsigned char reg,
unsigned char mask, unsigned char val); unsigned char mask, unsigned char val);
......
...@@ -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 */
......
...@@ -70,7 +70,7 @@ static int snd_ak4113_dev_free(struct snd_device *device) ...@@ -70,7 +70,7 @@ static int snd_ak4113_dev_free(struct snd_device *device)
} }
int snd_ak4113_create(struct snd_card *card, ak4113_read_t *read, int snd_ak4113_create(struct snd_card *card, ak4113_read_t *read,
ak4113_write_t *write, const unsigned char pgm[5], ak4113_write_t *write, const unsigned char *pgm,
void *private_data, struct ak4113 **r_ak4113) void *private_data, struct ak4113 **r_ak4113)
{ {
struct ak4113 *chip; struct ak4113 *chip;
......
...@@ -2184,10 +2184,9 @@ static int __devinit snd_echo_probe(struct pci_dev *pci, ...@@ -2184,10 +2184,9 @@ static int __devinit snd_echo_probe(struct pci_dev *pci,
goto ctl_error; goto ctl_error;
#endif #endif
if ((err = snd_card_register(card)) < 0) { err = snd_card_register(card);
snd_card_free(card); if (err < 0)
goto ctl_error; goto ctl_error;
}
snd_printk(KERN_INFO "Card registered: %s\n", card->longname); snd_printk(KERN_INFO "Card registered: %s\n", card->longname);
pci_set_drvdata(pci, chip); pci_set_drvdata(pci, chip);
......
...@@ -2362,6 +2362,7 @@ static struct snd_pci_quirk msi_black_list[] __devinitdata = { ...@@ -2362,6 +2362,7 @@ static struct snd_pci_quirk msi_black_list[] __devinitdata = {
SND_PCI_QUIRK(0x1043, 0x81f6, "ASUS", 0), /* nvidia */ SND_PCI_QUIRK(0x1043, 0x81f6, "ASUS", 0), /* nvidia */
SND_PCI_QUIRK(0x1043, 0x822d, "ASUS", 0), /* Athlon64 X2 + nvidia MCP55 */ SND_PCI_QUIRK(0x1043, 0x822d, "ASUS", 0), /* Athlon64 X2 + nvidia MCP55 */
SND_PCI_QUIRK(0x1849, 0x0888, "ASRock", 0), /* Athlon64 X2 + nvidia */ SND_PCI_QUIRK(0x1849, 0x0888, "ASRock", 0), /* Athlon64 X2 + nvidia */
SND_PCI_QUIRK(0xa0a0, 0x0575, "Aopen MZ915-M", 0), /* ICH6 */
{} {}
}; };
......
...@@ -1896,6 +1896,14 @@ static int patch_ad1981(struct hda_codec *codec) ...@@ -1896,6 +1896,14 @@ static int patch_ad1981(struct hda_codec *codec)
case AD1981_THINKPAD: case AD1981_THINKPAD:
spec->mixers[0] = ad1981_thinkpad_mixers; spec->mixers[0] = ad1981_thinkpad_mixers;
spec->input_mux = &ad1981_thinkpad_capture_source; spec->input_mux = &ad1981_thinkpad_capture_source;
/* set the upper-limit for mixer amp to 0dB for avoiding the
* possible damage by overloading
*/
snd_hda_override_amp_caps(codec, 0x11, HDA_INPUT,
(0x17 << AC_AMPCAP_OFFSET_SHIFT) |
(0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
(0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
(1 << AC_AMPCAP_MUTE_SHIFT));
break; break;
case AD1981_TOSHIBA: case AD1981_TOSHIBA:
spec->mixers[0] = ad1981_hp_mixers; spec->mixers[0] = ad1981_hp_mixers;
......
This diff is collapsed.
...@@ -1162,13 +1162,15 @@ static long snd_mixart_BA0_read(struct snd_info_entry *entry, void *file_private ...@@ -1162,13 +1162,15 @@ static long snd_mixart_BA0_read(struct snd_info_entry *entry, void *file_private
unsigned long count, unsigned long pos) unsigned long count, unsigned long pos)
{ {
struct mixart_mgr *mgr = entry->private_data; struct mixart_mgr *mgr = entry->private_data;
unsigned long maxsize;
count = count & ~3; /* make sure the read size is a multiple of 4 bytes */ if (pos >= MIXART_BA0_SIZE)
if(count <= 0)
return 0; return 0;
if(pos + count > MIXART_BA0_SIZE) maxsize = MIXART_BA0_SIZE - pos;
count = (long)(MIXART_BA0_SIZE - pos); if (count > maxsize)
if(copy_to_user_fromio(buf, MIXART_MEM( mgr, pos ), count)) count = maxsize;
count = count & ~3; /* make sure the read size is a multiple of 4 bytes */
if (copy_to_user_fromio(buf, MIXART_MEM(mgr, pos), count))
return -EFAULT; return -EFAULT;
return count; return count;
} }
...@@ -1181,13 +1183,15 @@ static long snd_mixart_BA1_read(struct snd_info_entry *entry, void *file_private ...@@ -1181,13 +1183,15 @@ static long snd_mixart_BA1_read(struct snd_info_entry *entry, void *file_private
unsigned long count, unsigned long pos) unsigned long count, unsigned long pos)
{ {
struct mixart_mgr *mgr = entry->private_data; struct mixart_mgr *mgr = entry->private_data;
unsigned long maxsize;
count = count & ~3; /* make sure the read size is a multiple of 4 bytes */ if (pos > MIXART_BA1_SIZE)
if(count <= 0)
return 0; return 0;
if(pos + count > MIXART_BA1_SIZE) maxsize = MIXART_BA1_SIZE - pos;
count = (long)(MIXART_BA1_SIZE - pos); if (count > maxsize)
if(copy_to_user_fromio(buf, MIXART_REG( mgr, pos ), count)) count = maxsize;
count = count & ~3; /* make sure the read size is a multiple of 4 bytes */
if (copy_to_user_fromio(buf, MIXART_REG(mgr, pos), count))
return -EFAULT; return -EFAULT;
return count; return count;
} }
......
...@@ -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);
......
...@@ -81,9 +81,11 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg, ...@@ -81,9 +81,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);
...@@ -103,12 +105,6 @@ static int ac97_soc_probe(struct platform_device *pdev) ...@@ -103,12 +105,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)
...@@ -124,6 +120,13 @@ static int ac97_soc_probe(struct platform_device *pdev) ...@@ -124,6 +120,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:
......
...@@ -3008,34 +3008,39 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec, ...@@ -3008,34 +3008,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;
...@@ -3402,7 +3407,7 @@ struct snd_soc_dai wm8994_dai[] = { ...@@ -3402,7 +3407,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,
...@@ -3731,11 +3736,12 @@ static int wm8994_codec_probe(struct platform_device *pdev) ...@@ -3731,11 +3736,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;
} }
/* 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
......
...@@ -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;
}; };
......
...@@ -586,7 +586,8 @@ static int davinci_i2s_probe(struct platform_device *pdev) ...@@ -586,7 +586,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;
......
...@@ -918,7 +918,8 @@ static int davinci_mcasp_probe(struct platform_device *pdev) ...@@ -918,7 +918,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];
......
...@@ -84,11 +84,13 @@ static void snd_imx_dma_err_callback(int channel, void *data, int err) ...@@ -84,11 +84,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");
...@@ -193,10 +195,12 @@ static int snd_imx_pcm_prepare(struct snd_pcm_substream *substream) ...@@ -193,10 +195,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;
......
...@@ -235,17 +235,20 @@ static int imx_ssi_hw_params(struct snd_pcm_substream *substream, ...@@ -235,17 +235,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) {
......
...@@ -61,12 +61,11 @@ static void omap_pcm_dma_irq(int ch, u16 stat, void *data) ...@@ -61,12 +61,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);
...@@ -101,9 +100,11 @@ static int omap_pcm_hw_params(struct snd_pcm_substream *substream, ...@@ -101,9 +100,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)
...@@ -190,8 +191,7 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream) ...@@ -190,8 +191,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
...@@ -249,14 +249,15 @@ static snd_pcm_uframes_t omap_pcm_pointer(struct snd_pcm_substream *substream) ...@@ -249,14 +249,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;
......
...@@ -122,10 +122,9 @@ static int pxa_ssp_startup(struct snd_pcm_substream *substream, ...@@ -122,10 +122,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;
} }
...@@ -142,10 +141,8 @@ static void pxa_ssp_shutdown(struct snd_pcm_substream *substream, ...@@ -142,10 +141,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
...@@ -570,19 +567,23 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream, ...@@ -570,19 +567,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:
......
...@@ -519,7 +519,8 @@ static int __devinit s6000_i2s_probe(struct platform_device *pdev) ...@@ -519,7 +519,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)
......
...@@ -1549,7 +1549,8 @@ int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid) ...@@ -1549,7 +1549,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