diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2010-04-07 11:42:25 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-04-07 11:42:25 -0400 |
commit | 84db18bbeb5c9c1a9c86e38a89d76ee526fd2c6f (patch) | |
tree | 49d3959eb24cd7c0754ed50e05fb96b0fb8d04aa /sound | |
parent | 6948ec70355ae6cf6082519e3d76b280373dade1 (diff) | |
parent | 55b371d4ac5ed6f3338a398fbf9f2eb9ace78799 (diff) |
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
Diffstat (limited to 'sound')
32 files changed, 377 insertions, 206 deletions
diff --git a/sound/i2c/other/ak4113.c b/sound/i2c/other/ak4113.c index fff62cc8607..971a84a4fa7 100644 --- a/sound/i2c/other/ak4113.c +++ b/sound/i2c/other/ak4113.c | |||
@@ -70,7 +70,7 @@ static int snd_ak4113_dev_free(struct snd_device *device) | |||
70 | } | 70 | } |
71 | 71 | ||
72 | int snd_ak4113_create(struct snd_card *card, ak4113_read_t *read, | 72 | int snd_ak4113_create(struct snd_card *card, ak4113_read_t *read, |
73 | ak4113_write_t *write, const unsigned char pgm[5], | 73 | ak4113_write_t *write, const unsigned char *pgm, |
74 | void *private_data, struct ak4113 **r_ak4113) | 74 | void *private_data, struct ak4113 **r_ak4113) |
75 | { | 75 | { |
76 | struct ak4113 *chip; | 76 | struct ak4113 *chip; |
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c index 8dab82d7d19..668a5ec0449 100644 --- a/sound/pci/echoaudio/echoaudio.c +++ b/sound/pci/echoaudio/echoaudio.c | |||
@@ -2184,10 +2184,9 @@ static int __devinit snd_echo_probe(struct pci_dev *pci, | |||
2184 | goto ctl_error; | 2184 | goto ctl_error; |
2185 | #endif | 2185 | #endif |
2186 | 2186 | ||
2187 | if ((err = snd_card_register(card)) < 0) { | 2187 | err = snd_card_register(card); |
2188 | snd_card_free(card); | 2188 | if (err < 0) |
2189 | goto ctl_error; | 2189 | goto ctl_error; |
2190 | } | ||
2191 | snd_printk(KERN_INFO "Card registered: %s\n", card->longname); | 2190 | snd_printk(KERN_INFO "Card registered: %s\n", card->longname); |
2192 | 2191 | ||
2193 | pci_set_drvdata(pci, chip); | 2192 | pci_set_drvdata(pci, chip); |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 4bb90675f70..f8fd586ae02 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -2362,6 +2362,7 @@ static struct snd_pci_quirk msi_black_list[] __devinitdata = { | |||
2362 | SND_PCI_QUIRK(0x1043, 0x81f6, "ASUS", 0), /* nvidia */ | 2362 | SND_PCI_QUIRK(0x1043, 0x81f6, "ASUS", 0), /* nvidia */ |
2363 | SND_PCI_QUIRK(0x1043, 0x822d, "ASUS", 0), /* Athlon64 X2 + nvidia MCP55 */ | 2363 | SND_PCI_QUIRK(0x1043, 0x822d, "ASUS", 0), /* Athlon64 X2 + nvidia MCP55 */ |
2364 | SND_PCI_QUIRK(0x1849, 0x0888, "ASRock", 0), /* Athlon64 X2 + nvidia */ | 2364 | SND_PCI_QUIRK(0x1849, 0x0888, "ASRock", 0), /* Athlon64 X2 + nvidia */ |
2365 | SND_PCI_QUIRK(0xa0a0, 0x0575, "Aopen MZ915-M", 0), /* ICH6 */ | ||
2365 | {} | 2366 | {} |
2366 | }; | 2367 | }; |
2367 | 2368 | ||
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index e6d1bdff1b6..af34606c30c 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
@@ -1896,6 +1896,14 @@ static int patch_ad1981(struct hda_codec *codec) | |||
1896 | case AD1981_THINKPAD: | 1896 | case AD1981_THINKPAD: |
1897 | spec->mixers[0] = ad1981_thinkpad_mixers; | 1897 | spec->mixers[0] = ad1981_thinkpad_mixers; |
1898 | spec->input_mux = &ad1981_thinkpad_capture_source; | 1898 | spec->input_mux = &ad1981_thinkpad_capture_source; |
1899 | /* set the upper-limit for mixer amp to 0dB for avoiding the | ||
1900 | * possible damage by overloading | ||
1901 | */ | ||
1902 | snd_hda_override_amp_caps(codec, 0x11, HDA_INPUT, | ||
1903 | (0x17 << AC_AMPCAP_OFFSET_SHIFT) | | ||
1904 | (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) | | ||
1905 | (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) | | ||
1906 | (1 << AC_AMPCAP_MUTE_SHIFT)); | ||
1899 | break; | 1907 | break; |
1900 | case AD1981_TOSHIBA: | 1908 | case AD1981_TOSHIBA: |
1901 | spec->mixers[0] = ad1981_hp_mixers; | 1909 | spec->mixers[0] = ad1981_hp_mixers; |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 9a23444e9e7..c7730dbb9dd 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -1621,6 +1621,11 @@ static struct hda_verb alc888_acer_aspire_4930g_verbs[] = { | |||
1621 | */ | 1621 | */ |
1622 | 1622 | ||
1623 | static struct hda_verb alc888_acer_aspire_6530g_verbs[] = { | 1623 | static struct hda_verb alc888_acer_aspire_6530g_verbs[] = { |
1624 | /* Route to built-in subwoofer as well as speakers */ | ||
1625 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
1626 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
1627 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
1628 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
1624 | /* Bias voltage on for external mic port */ | 1629 | /* Bias voltage on for external mic port */ |
1625 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80}, | 1630 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80}, |
1626 | /* Front Mic: set to PIN_IN (empty by default) */ | 1631 | /* Front Mic: set to PIN_IN (empty by default) */ |
@@ -1632,10 +1637,12 @@ static struct hda_verb alc888_acer_aspire_6530g_verbs[] = { | |||
1632 | /* Enable speaker output */ | 1637 | /* Enable speaker output */ |
1633 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 1638 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
1634 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 1639 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
1640 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, | ||
1635 | /* Enable headphone output */ | 1641 | /* Enable headphone output */ |
1636 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP}, | 1642 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP}, |
1637 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 1643 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
1638 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, | 1644 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, |
1645 | {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, | ||
1639 | { } | 1646 | { } |
1640 | }; | 1647 | }; |
1641 | 1648 | ||
@@ -4984,6 +4991,70 @@ static void set_capture_mixer(struct hda_codec *codec) | |||
4984 | } | 4991 | } |
4985 | } | 4992 | } |
4986 | 4993 | ||
4994 | /* fill adc_nids (and capsrc_nids) containing all active input pins */ | ||
4995 | static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids, | ||
4996 | int num_nids) | ||
4997 | { | ||
4998 | struct alc_spec *spec = codec->spec; | ||
4999 | int n; | ||
5000 | hda_nid_t fallback_adc = 0, fallback_cap = 0; | ||
5001 | |||
5002 | for (n = 0; n < num_nids; n++) { | ||
5003 | hda_nid_t adc, cap; | ||
5004 | hda_nid_t conn[HDA_MAX_NUM_INPUTS]; | ||
5005 | int nconns, i, j; | ||
5006 | |||
5007 | adc = nids[n]; | ||
5008 | if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN) | ||
5009 | continue; | ||
5010 | cap = adc; | ||
5011 | nconns = snd_hda_get_connections(codec, cap, conn, | ||
5012 | ARRAY_SIZE(conn)); | ||
5013 | if (nconns == 1) { | ||
5014 | cap = conn[0]; | ||
5015 | nconns = snd_hda_get_connections(codec, cap, conn, | ||
5016 | ARRAY_SIZE(conn)); | ||
5017 | } | ||
5018 | if (nconns <= 0) | ||
5019 | continue; | ||
5020 | if (!fallback_adc) { | ||
5021 | fallback_adc = adc; | ||
5022 | fallback_cap = cap; | ||
5023 | } | ||
5024 | for (i = 0; i < AUTO_PIN_LAST; i++) { | ||
5025 | hda_nid_t nid = spec->autocfg.input_pins[i]; | ||
5026 | if (!nid) | ||
5027 | continue; | ||
5028 | for (j = 0; j < nconns; j++) { | ||
5029 | if (conn[j] == nid) | ||
5030 | break; | ||
5031 | } | ||
5032 | if (j >= nconns) | ||
5033 | break; | ||
5034 | } | ||
5035 | if (i >= AUTO_PIN_LAST) { | ||
5036 | int num_adcs = spec->num_adc_nids; | ||
5037 | spec->private_adc_nids[num_adcs] = adc; | ||
5038 | spec->private_capsrc_nids[num_adcs] = cap; | ||
5039 | spec->num_adc_nids++; | ||
5040 | spec->adc_nids = spec->private_adc_nids; | ||
5041 | if (adc != cap) | ||
5042 | spec->capsrc_nids = spec->private_capsrc_nids; | ||
5043 | } | ||
5044 | } | ||
5045 | if (!spec->num_adc_nids) { | ||
5046 | printk(KERN_WARNING "hda_codec: %s: no valid ADC found;" | ||
5047 | " using fallback 0x%x\n", | ||
5048 | codec->chip_name, fallback_adc); | ||
5049 | spec->private_adc_nids[0] = fallback_adc; | ||
5050 | spec->adc_nids = spec->private_adc_nids; | ||
5051 | if (fallback_adc != fallback_cap) { | ||
5052 | spec->private_capsrc_nids[0] = fallback_cap; | ||
5053 | spec->capsrc_nids = spec->private_adc_nids; | ||
5054 | } | ||
5055 | } | ||
5056 | } | ||
5057 | |||
4987 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | 5058 | #ifdef CONFIG_SND_HDA_INPUT_BEEP |
4988 | #define set_beep_amp(spec, nid, idx, dir) \ | 5059 | #define set_beep_amp(spec, nid, idx, dir) \ |
4989 | ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) | 5060 | ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) |
@@ -8398,9 +8469,7 @@ static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { | |||
8398 | 8469 | ||
8399 | static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = { | 8470 | static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = { |
8400 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 8471 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
8401 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | ||
8402 | HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT), | 8472 | HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT), |
8403 | HDA_BIND_MUTE("LFE Playback Switch", 0x0f, 2, HDA_INPUT), | ||
8404 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | 8473 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), |
8405 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | 8474 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), |
8406 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | 8475 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), |
@@ -10041,13 +10110,12 @@ static void alc882_auto_set_output_and_unmute(struct hda_codec *codec, | |||
10041 | int idx; | 10110 | int idx; |
10042 | 10111 | ||
10043 | alc_set_pin_output(codec, nid, pin_type); | 10112 | alc_set_pin_output(codec, nid, pin_type); |
10113 | if (dac_idx >= spec->multiout.num_dacs) | ||
10114 | return; | ||
10044 | if (spec->multiout.dac_nids[dac_idx] == 0x25) | 10115 | if (spec->multiout.dac_nids[dac_idx] == 0x25) |
10045 | idx = 4; | 10116 | idx = 4; |
10046 | else { | 10117 | else |
10047 | if (spec->multiout.num_dacs >= dac_idx) | ||
10048 | return; | ||
10049 | idx = spec->multiout.dac_nids[dac_idx] - 2; | 10118 | idx = spec->multiout.dac_nids[dac_idx] - 2; |
10050 | } | ||
10051 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); | 10119 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); |
10052 | 10120 | ||
10053 | } | 10121 | } |
@@ -12459,11 +12527,11 @@ static void alc268_aspire_one_speaker_automute(struct hda_codec *codec) | |||
12459 | unsigned char bits; | 12527 | unsigned char bits; |
12460 | 12528 | ||
12461 | present = snd_hda_jack_detect(codec, 0x15); | 12529 | present = snd_hda_jack_detect(codec, 0x15); |
12462 | bits = present ? AMP_IN_MUTE(0) : 0; | 12530 | bits = present ? HDA_AMP_MUTE : 0; |
12463 | snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0, | 12531 | snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0, |
12464 | AMP_IN_MUTE(0), bits); | 12532 | HDA_AMP_MUTE, bits); |
12465 | snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1, | 12533 | snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1, |
12466 | AMP_IN_MUTE(0), bits); | 12534 | HDA_AMP_MUTE, bits); |
12467 | } | 12535 | } |
12468 | 12536 | ||
12469 | static void alc268_acer_lc_unsol_event(struct hda_codec *codec, | 12537 | static void alc268_acer_lc_unsol_event(struct hda_codec *codec, |
@@ -13333,9 +13401,9 @@ static hda_nid_t alc269vb_capsrc_nids[1] = { | |||
13333 | 0x22, | 13401 | 0x22, |
13334 | }; | 13402 | }; |
13335 | 13403 | ||
13336 | /* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24), | 13404 | static hda_nid_t alc269_adc_candidates[] = { |
13337 | * not a mux! | 13405 | 0x08, 0x09, 0x07, |
13338 | */ | 13406 | }; |
13339 | 13407 | ||
13340 | #define alc269_modes alc260_modes | 13408 | #define alc269_modes alc260_modes |
13341 | #define alc269_capture_source alc880_lg_lw_capture_source | 13409 | #define alc269_capture_source alc880_lg_lw_capture_source |
@@ -13482,11 +13550,11 @@ static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec) | |||
13482 | unsigned char bits; | 13550 | unsigned char bits; |
13483 | 13551 | ||
13484 | present = snd_hda_jack_detect(codec, 0x15); | 13552 | present = snd_hda_jack_detect(codec, 0x15); |
13485 | bits = present ? AMP_IN_MUTE(0) : 0; | 13553 | bits = present ? HDA_AMP_MUTE : 0; |
13486 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, | 13554 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, |
13487 | AMP_IN_MUTE(0), bits); | 13555 | HDA_AMP_MUTE, bits); |
13488 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, | 13556 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, |
13489 | AMP_IN_MUTE(0), bits); | 13557 | HDA_AMP_MUTE, bits); |
13490 | 13558 | ||
13491 | snd_hda_codec_write(codec, 0x20, 0, | 13559 | snd_hda_codec_write(codec, 0x20, 0, |
13492 | AC_VERB_SET_COEF_INDEX, 0x0c); | 13560 | AC_VERB_SET_COEF_INDEX, 0x0c); |
@@ -13511,11 +13579,11 @@ static void alc269_lifebook_speaker_automute(struct hda_codec *codec) | |||
13511 | /* Check port replicator headphone socket */ | 13579 | /* Check port replicator headphone socket */ |
13512 | present |= snd_hda_jack_detect(codec, 0x1a); | 13580 | present |= snd_hda_jack_detect(codec, 0x1a); |
13513 | 13581 | ||
13514 | bits = present ? AMP_IN_MUTE(0) : 0; | 13582 | bits = present ? HDA_AMP_MUTE : 0; |
13515 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, | 13583 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, |
13516 | AMP_IN_MUTE(0), bits); | 13584 | HDA_AMP_MUTE, bits); |
13517 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, | 13585 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, |
13518 | AMP_IN_MUTE(0), bits); | 13586 | HDA_AMP_MUTE, bits); |
13519 | 13587 | ||
13520 | snd_hda_codec_write(codec, 0x20, 0, | 13588 | snd_hda_codec_write(codec, 0x20, 0, |
13521 | AC_VERB_SET_COEF_INDEX, 0x0c); | 13589 | AC_VERB_SET_COEF_INDEX, 0x0c); |
@@ -13646,11 +13714,11 @@ static void alc269_speaker_automute(struct hda_codec *codec) | |||
13646 | unsigned char bits; | 13714 | unsigned char bits; |
13647 | 13715 | ||
13648 | present = snd_hda_jack_detect(codec, nid); | 13716 | present = snd_hda_jack_detect(codec, nid); |
13649 | bits = present ? AMP_IN_MUTE(0) : 0; | 13717 | bits = present ? HDA_AMP_MUTE : 0; |
13650 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, | 13718 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, |
13651 | AMP_IN_MUTE(0), bits); | 13719 | HDA_AMP_MUTE, bits); |
13652 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, | 13720 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, |
13653 | AMP_IN_MUTE(0), bits); | 13721 | HDA_AMP_MUTE, bits); |
13654 | } | 13722 | } |
13655 | 13723 | ||
13656 | /* unsolicited event for HP jack sensing */ | 13724 | /* unsolicited event for HP jack sensing */ |
@@ -13842,7 +13910,6 @@ static int alc269_parse_auto_config(struct hda_codec *codec) | |||
13842 | struct alc_spec *spec = codec->spec; | 13910 | struct alc_spec *spec = codec->spec; |
13843 | int err; | 13911 | int err; |
13844 | static hda_nid_t alc269_ignore[] = { 0x1d, 0 }; | 13912 | static hda_nid_t alc269_ignore[] = { 0x1d, 0 }; |
13845 | hda_nid_t real_capsrc_nids; | ||
13846 | 13913 | ||
13847 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | 13914 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, |
13848 | alc269_ignore); | 13915 | alc269_ignore); |
@@ -13866,18 +13933,19 @@ static int alc269_parse_auto_config(struct hda_codec *codec) | |||
13866 | 13933 | ||
13867 | if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010) { | 13934 | if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010) { |
13868 | add_verb(spec, alc269vb_init_verbs); | 13935 | add_verb(spec, alc269vb_init_verbs); |
13869 | real_capsrc_nids = alc269vb_capsrc_nids[0]; | ||
13870 | alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21); | 13936 | alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21); |
13871 | } else { | 13937 | } else { |
13872 | add_verb(spec, alc269_init_verbs); | 13938 | add_verb(spec, alc269_init_verbs); |
13873 | real_capsrc_nids = alc269_capsrc_nids[0]; | ||
13874 | alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); | 13939 | alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); |
13875 | } | 13940 | } |
13876 | 13941 | ||
13877 | spec->num_mux_defs = 1; | 13942 | spec->num_mux_defs = 1; |
13878 | spec->input_mux = &spec->private_imux[0]; | 13943 | spec->input_mux = &spec->private_imux[0]; |
13944 | fillup_priv_adc_nids(codec, alc269_adc_candidates, | ||
13945 | sizeof(alc269_adc_candidates)); | ||
13946 | |||
13879 | /* set default input source */ | 13947 | /* set default input source */ |
13880 | snd_hda_codec_write_cache(codec, real_capsrc_nids, | 13948 | snd_hda_codec_write_cache(codec, spec->capsrc_nids[0], |
13881 | 0, AC_VERB_SET_CONNECT_SEL, | 13949 | 0, AC_VERB_SET_CONNECT_SEL, |
13882 | spec->input_mux->items[0].index); | 13950 | spec->input_mux->items[0].index); |
13883 | 13951 | ||
@@ -14156,14 +14224,16 @@ static int patch_alc269(struct hda_codec *codec) | |||
14156 | spec->stream_digital_playback = &alc269_pcm_digital_playback; | 14224 | spec->stream_digital_playback = &alc269_pcm_digital_playback; |
14157 | spec->stream_digital_capture = &alc269_pcm_digital_capture; | 14225 | spec->stream_digital_capture = &alc269_pcm_digital_capture; |
14158 | 14226 | ||
14159 | if (!is_alc269vb) { | 14227 | if (!spec->adc_nids) { /* wasn't filled automatically? use default */ |
14160 | spec->adc_nids = alc269_adc_nids; | 14228 | if (!is_alc269vb) { |
14161 | spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids); | 14229 | spec->adc_nids = alc269_adc_nids; |
14162 | spec->capsrc_nids = alc269_capsrc_nids; | 14230 | spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids); |
14163 | } else { | 14231 | spec->capsrc_nids = alc269_capsrc_nids; |
14164 | spec->adc_nids = alc269vb_adc_nids; | 14232 | } else { |
14165 | spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids); | 14233 | spec->adc_nids = alc269vb_adc_nids; |
14166 | spec->capsrc_nids = alc269vb_capsrc_nids; | 14234 | spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids); |
14235 | spec->capsrc_nids = alc269vb_capsrc_nids; | ||
14236 | } | ||
14167 | } | 14237 | } |
14168 | 14238 | ||
14169 | if (!spec->cap_mixer) | 14239 | if (!spec->cap_mixer) |
@@ -17115,9 +17185,9 @@ static void alc663_m51va_speaker_automute(struct hda_codec *codec) | |||
17115 | present = snd_hda_jack_detect(codec, 0x21); | 17185 | present = snd_hda_jack_detect(codec, 0x21); |
17116 | bits = present ? HDA_AMP_MUTE : 0; | 17186 | bits = present ? HDA_AMP_MUTE : 0; |
17117 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, | 17187 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, |
17118 | AMP_IN_MUTE(0), bits); | 17188 | HDA_AMP_MUTE, bits); |
17119 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, | 17189 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, |
17120 | AMP_IN_MUTE(0), bits); | 17190 | HDA_AMP_MUTE, bits); |
17121 | } | 17191 | } |
17122 | 17192 | ||
17123 | static void alc663_21jd_two_speaker_automute(struct hda_codec *codec) | 17193 | static void alc663_21jd_two_speaker_automute(struct hda_codec *codec) |
@@ -17128,13 +17198,13 @@ static void alc663_21jd_two_speaker_automute(struct hda_codec *codec) | |||
17128 | present = snd_hda_jack_detect(codec, 0x21); | 17198 | present = snd_hda_jack_detect(codec, 0x21); |
17129 | bits = present ? HDA_AMP_MUTE : 0; | 17199 | bits = present ? HDA_AMP_MUTE : 0; |
17130 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, | 17200 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, |
17131 | AMP_IN_MUTE(0), bits); | 17201 | HDA_AMP_MUTE, bits); |
17132 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, | 17202 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, |
17133 | AMP_IN_MUTE(0), bits); | 17203 | HDA_AMP_MUTE, bits); |
17134 | snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0, | 17204 | snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0, |
17135 | AMP_IN_MUTE(0), bits); | 17205 | HDA_AMP_MUTE, bits); |
17136 | snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1, | 17206 | snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1, |
17137 | AMP_IN_MUTE(0), bits); | 17207 | HDA_AMP_MUTE, bits); |
17138 | } | 17208 | } |
17139 | 17209 | ||
17140 | static void alc663_15jd_two_speaker_automute(struct hda_codec *codec) | 17210 | static void alc663_15jd_two_speaker_automute(struct hda_codec *codec) |
@@ -17145,13 +17215,13 @@ static void alc663_15jd_two_speaker_automute(struct hda_codec *codec) | |||
17145 | present = snd_hda_jack_detect(codec, 0x15); | 17215 | present = snd_hda_jack_detect(codec, 0x15); |
17146 | bits = present ? HDA_AMP_MUTE : 0; | 17216 | bits = present ? HDA_AMP_MUTE : 0; |
17147 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, | 17217 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, |
17148 | AMP_IN_MUTE(0), bits); | 17218 | HDA_AMP_MUTE, bits); |
17149 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, | 17219 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, |
17150 | AMP_IN_MUTE(0), bits); | 17220 | HDA_AMP_MUTE, bits); |
17151 | snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0, | 17221 | snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0, |
17152 | AMP_IN_MUTE(0), bits); | 17222 | HDA_AMP_MUTE, bits); |
17153 | snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1, | 17223 | snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1, |
17154 | AMP_IN_MUTE(0), bits); | 17224 | HDA_AMP_MUTE, bits); |
17155 | } | 17225 | } |
17156 | 17226 | ||
17157 | static void alc662_f5z_speaker_automute(struct hda_codec *codec) | 17227 | static void alc662_f5z_speaker_automute(struct hda_codec *codec) |
@@ -17190,14 +17260,14 @@ static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec) | |||
17190 | 17260 | ||
17191 | if (present1 || present2) { | 17261 | if (present1 || present2) { |
17192 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, | 17262 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, |
17193 | AMP_IN_MUTE(0), AMP_IN_MUTE(0)); | 17263 | HDA_AMP_MUTE, HDA_AMP_MUTE); |
17194 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, | 17264 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, |
17195 | AMP_IN_MUTE(0), AMP_IN_MUTE(0)); | 17265 | HDA_AMP_MUTE, HDA_AMP_MUTE); |
17196 | } else { | 17266 | } else { |
17197 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, | 17267 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, |
17198 | AMP_IN_MUTE(0), 0); | 17268 | HDA_AMP_MUTE, 0); |
17199 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, | 17269 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, |
17200 | AMP_IN_MUTE(0), 0); | 17270 | HDA_AMP_MUTE, 0); |
17201 | } | 17271 | } |
17202 | } | 17272 | } |
17203 | 17273 | ||
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c index 55e9315d4cc..3be8f97c8bc 100644 --- a/sound/pci/mixart/mixart.c +++ b/sound/pci/mixart/mixart.c | |||
@@ -1162,13 +1162,15 @@ static long snd_mixart_BA0_read(struct snd_info_entry *entry, void *file_private | |||
1162 | unsigned long count, unsigned long pos) | 1162 | unsigned long count, unsigned long pos) |
1163 | { | 1163 | { |
1164 | struct mixart_mgr *mgr = entry->private_data; | 1164 | struct mixart_mgr *mgr = entry->private_data; |
1165 | unsigned long maxsize; | ||
1165 | 1166 | ||
1166 | count = count & ~3; /* make sure the read size is a multiple of 4 bytes */ | 1167 | if (pos >= MIXART_BA0_SIZE) |
1167 | if(count <= 0) | ||
1168 | return 0; | 1168 | return 0; |
1169 | if(pos + count > MIXART_BA0_SIZE) | 1169 | maxsize = MIXART_BA0_SIZE - pos; |
1170 | count = (long)(MIXART_BA0_SIZE - pos); | 1170 | if (count > maxsize) |
1171 | if(copy_to_user_fromio(buf, MIXART_MEM( mgr, pos ), count)) | 1171 | count = maxsize; |
1172 | count = count & ~3; /* make sure the read size is a multiple of 4 bytes */ | ||
1173 | if (copy_to_user_fromio(buf, MIXART_MEM(mgr, pos), count)) | ||
1172 | return -EFAULT; | 1174 | return -EFAULT; |
1173 | return count; | 1175 | return count; |
1174 | } | 1176 | } |
@@ -1181,13 +1183,15 @@ static long snd_mixart_BA1_read(struct snd_info_entry *entry, void *file_private | |||
1181 | unsigned long count, unsigned long pos) | 1183 | unsigned long count, unsigned long pos) |
1182 | { | 1184 | { |
1183 | struct mixart_mgr *mgr = entry->private_data; | 1185 | struct mixart_mgr *mgr = entry->private_data; |
1186 | unsigned long maxsize; | ||
1184 | 1187 | ||
1185 | count = count & ~3; /* make sure the read size is a multiple of 4 bytes */ | 1188 | if (pos > MIXART_BA1_SIZE) |
1186 | if(count <= 0) | ||
1187 | return 0; | 1189 | return 0; |
1188 | if(pos + count > MIXART_BA1_SIZE) | 1190 | maxsize = MIXART_BA1_SIZE - pos; |
1189 | count = (long)(MIXART_BA1_SIZE - pos); | 1191 | if (count > maxsize) |
1190 | if(copy_to_user_fromio(buf, MIXART_REG( mgr, pos ), count)) | 1192 | count = maxsize; |
1193 | count = count & ~3; /* make sure the read size is a multiple of 4 bytes */ | ||
1194 | if (copy_to_user_fromio(buf, MIXART_REG(mgr, pos), count)) | ||
1191 | return -EFAULT; | 1195 | return -EFAULT; |
1192 | return count; | 1196 | return count; |
1193 | } | 1197 | } |
diff --git a/sound/soc/atmel/atmel-pcm.c b/sound/soc/atmel/atmel-pcm.c index 9ef6b96373f..3e6628c8e66 100644 --- a/sound/soc/atmel/atmel-pcm.c +++ b/sound/soc/atmel/atmel-pcm.c | |||
@@ -180,7 +180,7 @@ static int atmel_pcm_hw_params(struct snd_pcm_substream *substream, | |||
180 | snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); | 180 | snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); |
181 | runtime->dma_bytes = params_buffer_bytes(params); | 181 | runtime->dma_bytes = params_buffer_bytes(params); |
182 | 182 | ||
183 | prtd->params = rtd->dai->cpu_dai->dma_data; | 183 | prtd->params = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); |
184 | prtd->params->dma_intr_handler = atmel_pcm_dma_irq; | 184 | prtd->params->dma_intr_handler = atmel_pcm_dma_irq; |
185 | 185 | ||
186 | prtd->dma_buffer = runtime->dma_addr; | 186 | prtd->dma_buffer = runtime->dma_addr; |
diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c index e588e63f18d..0b59806905d 100644 --- a/sound/soc/atmel/atmel_ssc_dai.c +++ b/sound/soc/atmel/atmel_ssc_dai.c | |||
@@ -363,12 +363,12 @@ static int atmel_ssc_hw_params(struct snd_pcm_substream *substream, | |||
363 | ssc_p->dma_params[dir] = dma_params; | 363 | ssc_p->dma_params[dir] = dma_params; |
364 | 364 | ||
365 | /* | 365 | /* |
366 | * The cpu_dai->dma_data field is only used to communicate the | 366 | * The snd_soc_pcm_stream->dma_data field is only used to communicate |
367 | * appropriate DMA parameters to the pcm driver hw_params() | 367 | * the appropriate DMA parameters to the pcm driver hw_params() |
368 | * function. It should not be used for other purposes | 368 | * function. It should not be used for other purposes |
369 | * as it is common to all substreams. | 369 | * as it is common to all substreams. |
370 | */ | 370 | */ |
371 | rtd->dai->cpu_dai->dma_data = dma_params; | 371 | snd_soc_dai_set_dma_data(rtd->dai->cpu_dai, substream, dma_params); |
372 | 372 | ||
373 | channels = params_channels(params); | 373 | channels = params_channels(params); |
374 | 374 | ||
diff --git a/sound/soc/codecs/ac97.c b/sound/soc/codecs/ac97.c index fd101d450d5..1f5e57a4bb7 100644 --- a/sound/soc/codecs/ac97.c +++ b/sound/soc/codecs/ac97.c | |||
@@ -81,9 +81,11 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg, | |||
81 | static int ac97_soc_probe(struct platform_device *pdev) | 81 | static int ac97_soc_probe(struct platform_device *pdev) |
82 | { | 82 | { |
83 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); | 83 | struct snd_soc_device *socdev = platform_get_drvdata(pdev); |
84 | struct snd_soc_card *card = socdev->card; | ||
84 | struct snd_soc_codec *codec; | 85 | struct snd_soc_codec *codec; |
85 | struct snd_ac97_bus *ac97_bus; | 86 | struct snd_ac97_bus *ac97_bus; |
86 | struct snd_ac97_template ac97_template; | 87 | struct snd_ac97_template ac97_template; |
88 | int i; | ||
87 | int ret = 0; | 89 | int ret = 0; |
88 | 90 | ||
89 | printk(KERN_INFO "AC97 SoC Audio Codec %s\n", AC97_VERSION); | 91 | 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 | INIT_LIST_HEAD(&codec->dapm_widgets); | 105 | INIT_LIST_HEAD(&codec->dapm_widgets); |
104 | INIT_LIST_HEAD(&codec->dapm_paths); | 106 | INIT_LIST_HEAD(&codec->dapm_paths); |
105 | 107 | ||
106 | ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); | ||
107 | if (ret < 0) { | ||
108 | printk(KERN_ERR "ASoC: failed to init gen ac97 glue\n"); | ||
109 | goto err; | ||
110 | } | ||
111 | |||
112 | /* register pcms */ | 108 | /* register pcms */ |
113 | ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); | 109 | ret = snd_soc_new_pcms(socdev, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1); |
114 | if (ret < 0) | 110 | if (ret < 0) |
@@ -124,6 +120,13 @@ static int ac97_soc_probe(struct platform_device *pdev) | |||
124 | if (ret < 0) | 120 | if (ret < 0) |
125 | goto bus_err; | 121 | goto bus_err; |
126 | 122 | ||
123 | for (i = 0; i < card->num_links; i++) { | ||
124 | if (card->dai_link[i].codec_dai->ac97_control) { | ||
125 | snd_ac97_dev_add_pdata(codec->ac97, | ||
126 | card->dai_link[i].cpu_dai->ac97_pdata); | ||
127 | } | ||
128 | } | ||
129 | |||
127 | return 0; | 130 | return 0; |
128 | 131 | ||
129 | bus_err: | 132 | bus_err: |
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 8d1c63754be..9da0724cd47 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c | |||
@@ -3008,34 +3008,39 @@ static int wm8994_set_bias_level(struct snd_soc_codec *codec, | |||
3008 | break; | 3008 | break; |
3009 | 3009 | ||
3010 | case SND_SOC_BIAS_OFF: | 3010 | case SND_SOC_BIAS_OFF: |
3011 | /* Switch over to startup biases */ | 3011 | if (codec->bias_level == SND_SOC_BIAS_STANDBY) { |
3012 | snd_soc_update_bits(codec, WM8994_ANTIPOP_2, | 3012 | /* Switch over to startup biases */ |
3013 | WM8994_BIAS_SRC | WM8994_STARTUP_BIAS_ENA | | 3013 | snd_soc_update_bits(codec, WM8994_ANTIPOP_2, |
3014 | WM8994_VMID_BUF_ENA | | 3014 | WM8994_BIAS_SRC | |
3015 | WM8994_VMID_RAMP_MASK, | 3015 | WM8994_STARTUP_BIAS_ENA | |
3016 | WM8994_BIAS_SRC | WM8994_STARTUP_BIAS_ENA | | 3016 | WM8994_VMID_BUF_ENA | |
3017 | WM8994_VMID_BUF_ENA | | 3017 | WM8994_VMID_RAMP_MASK, |
3018 | (1 << WM8994_VMID_RAMP_SHIFT)); | 3018 | WM8994_BIAS_SRC | |
3019 | 3019 | WM8994_STARTUP_BIAS_ENA | | |
3020 | /* Disable main biases */ | 3020 | WM8994_VMID_BUF_ENA | |
3021 | snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, | 3021 | (1 << WM8994_VMID_RAMP_SHIFT)); |
3022 | WM8994_BIAS_ENA | WM8994_VMID_SEL_MASK, 0); | ||
3023 | 3022 | ||
3024 | /* Discharge line */ | 3023 | /* Disable main biases */ |
3025 | snd_soc_update_bits(codec, WM8994_ANTIPOP_1, | 3024 | snd_soc_update_bits(codec, WM8994_POWER_MANAGEMENT_1, |
3026 | WM8994_LINEOUT1_DISCH | | 3025 | WM8994_BIAS_ENA | |
3027 | WM8994_LINEOUT2_DISCH, | 3026 | WM8994_VMID_SEL_MASK, 0); |
3028 | WM8994_LINEOUT1_DISCH | | ||
3029 | WM8994_LINEOUT2_DISCH); | ||
3030 | 3027 | ||
3031 | msleep(5); | 3028 | /* Discharge line */ |
3029 | snd_soc_update_bits(codec, WM8994_ANTIPOP_1, | ||
3030 | WM8994_LINEOUT1_DISCH | | ||
3031 | WM8994_LINEOUT2_DISCH, | ||
3032 | WM8994_LINEOUT1_DISCH | | ||
3033 | WM8994_LINEOUT2_DISCH); | ||
3032 | 3034 | ||
3033 | /* Switch off startup biases */ | 3035 | msleep(5); |
3034 | snd_soc_update_bits(codec, WM8994_ANTIPOP_2, | ||
3035 | WM8994_BIAS_SRC | WM8994_STARTUP_BIAS_ENA | | ||
3036 | WM8994_VMID_BUF_ENA | | ||
3037 | WM8994_VMID_RAMP_MASK, 0); | ||
3038 | 3036 | ||
3037 | /* Switch off startup biases */ | ||
3038 | snd_soc_update_bits(codec, WM8994_ANTIPOP_2, | ||
3039 | WM8994_BIAS_SRC | | ||
3040 | WM8994_STARTUP_BIAS_ENA | | ||
3041 | WM8994_VMID_BUF_ENA | | ||
3042 | WM8994_VMID_RAMP_MASK, 0); | ||
3043 | } | ||
3039 | break; | 3044 | break; |
3040 | } | 3045 | } |
3041 | codec->bias_level = level; | 3046 | codec->bias_level = level; |
@@ -3402,7 +3407,7 @@ struct snd_soc_dai wm8994_dai[] = { | |||
3402 | .rates = WM8994_RATES, | 3407 | .rates = WM8994_RATES, |
3403 | .formats = WM8994_FORMATS, | 3408 | .formats = WM8994_FORMATS, |
3404 | }, | 3409 | }, |
3405 | .playback = { | 3410 | .capture = { |
3406 | .stream_name = "AIF3 Capture", | 3411 | .stream_name = "AIF3 Capture", |
3407 | .channels_min = 2, | 3412 | .channels_min = 2, |
3408 | .channels_max = 2, | 3413 | .channels_max = 2, |
@@ -3731,11 +3736,12 @@ static int wm8994_codec_probe(struct platform_device *pdev) | |||
3731 | case 3: | 3736 | case 3: |
3732 | wm8994->hubs.dcs_codes = -5; | 3737 | wm8994->hubs.dcs_codes = -5; |
3733 | wm8994->hubs.hp_startup_mode = 1; | 3738 | wm8994->hubs.hp_startup_mode = 1; |
3739 | wm8994->hubs.dcs_readback_mode = 1; | ||
3734 | break; | 3740 | break; |
3735 | default: | 3741 | default: |
3742 | wm8994->hubs.dcs_readback_mode = 1; | ||
3736 | break; | 3743 | break; |
3737 | } | 3744 | } |
3738 | |||
3739 | 3745 | ||
3740 | /* Remember if AIFnLRCLK is configured as a GPIO. This should be | 3746 | /* Remember if AIFnLRCLK is configured as a GPIO. This should be |
3741 | * configured on init - if a system wants to do this dynamically | 3747 | * configured on init - if a system wants to do this dynamically |
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c index 486bdd21a98..e1f225a3ac4 100644 --- a/sound/soc/codecs/wm_hubs.c +++ b/sound/soc/codecs/wm_hubs.c | |||
@@ -62,21 +62,27 @@ static const char *speaker_mode_text[] = { | |||
62 | static const struct soc_enum speaker_mode = | 62 | static const struct soc_enum speaker_mode = |
63 | SOC_ENUM_SINGLE(WM8993_SPKMIXR_ATTENUATION, 8, 2, speaker_mode_text); | 63 | SOC_ENUM_SINGLE(WM8993_SPKMIXR_ATTENUATION, 8, 2, speaker_mode_text); |
64 | 64 | ||
65 | static void wait_for_dc_servo(struct snd_soc_codec *codec) | 65 | static void wait_for_dc_servo(struct snd_soc_codec *codec, unsigned int op) |
66 | { | 66 | { |
67 | unsigned int reg; | 67 | unsigned int reg; |
68 | int count = 0; | 68 | int count = 0; |
69 | unsigned int val; | ||
70 | |||
71 | val = op | WM8993_DCS_ENA_CHAN_0 | WM8993_DCS_ENA_CHAN_1; | ||
72 | |||
73 | /* Trigger the command */ | ||
74 | snd_soc_write(codec, WM8993_DC_SERVO_0, val); | ||
69 | 75 | ||
70 | dev_dbg(codec->dev, "Waiting for DC servo...\n"); | 76 | dev_dbg(codec->dev, "Waiting for DC servo...\n"); |
71 | 77 | ||
72 | do { | 78 | do { |
73 | count++; | 79 | count++; |
74 | msleep(1); | 80 | msleep(1); |
75 | reg = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_0); | 81 | reg = snd_soc_read(codec, WM8993_DC_SERVO_0); |
76 | dev_dbg(codec->dev, "DC servo: %x\n", reg); | 82 | dev_dbg(codec->dev, "DC servo: %x\n", reg); |
77 | } while (reg & WM8993_DCS_DATAPATH_BUSY && count < 400); | 83 | } while (reg & op && count < 400); |
78 | 84 | ||
79 | if (reg & WM8993_DCS_DATAPATH_BUSY) | 85 | if (reg & op) |
80 | dev_err(codec->dev, "Timed out waiting for DC Servo\n"); | 86 | dev_err(codec->dev, "Timed out waiting for DC Servo\n"); |
81 | } | 87 | } |
82 | 88 | ||
@@ -86,51 +92,58 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec) | |||
86 | static void calibrate_dc_servo(struct snd_soc_codec *codec) | 92 | static void calibrate_dc_servo(struct snd_soc_codec *codec) |
87 | { | 93 | { |
88 | struct wm_hubs_data *hubs = codec->private_data; | 94 | struct wm_hubs_data *hubs = codec->private_data; |
89 | u16 reg, dcs_cfg; | 95 | u16 reg, reg_l, reg_r, dcs_cfg; |
90 | 96 | ||
91 | /* Set for 32 series updates */ | 97 | /* Set for 32 series updates */ |
92 | snd_soc_update_bits(codec, WM8993_DC_SERVO_1, | 98 | snd_soc_update_bits(codec, WM8993_DC_SERVO_1, |
93 | WM8993_DCS_SERIES_NO_01_MASK, | 99 | WM8993_DCS_SERIES_NO_01_MASK, |
94 | 32 << WM8993_DCS_SERIES_NO_01_SHIFT); | 100 | 32 << WM8993_DCS_SERIES_NO_01_SHIFT); |
95 | 101 | wait_for_dc_servo(codec, | |
96 | /* Enable the DC servo. Write all bits to avoid triggering startup | 102 | WM8993_DCS_TRIG_SERIES_0 | WM8993_DCS_TRIG_SERIES_1); |
97 | * or write calibration. | ||
98 | */ | ||
99 | snd_soc_update_bits(codec, WM8993_DC_SERVO_0, | ||
100 | 0xFFFF, | ||
101 | WM8993_DCS_ENA_CHAN_0 | | ||
102 | WM8993_DCS_ENA_CHAN_1 | | ||
103 | WM8993_DCS_TRIG_SERIES_1 | | ||
104 | WM8993_DCS_TRIG_SERIES_0); | ||
105 | |||
106 | wait_for_dc_servo(codec); | ||
107 | 103 | ||
108 | /* Apply correction to DC servo result */ | 104 | /* Apply correction to DC servo result */ |
109 | if (hubs->dcs_codes) { | 105 | if (hubs->dcs_codes) { |
110 | dev_dbg(codec->dev, "Applying %d code DC servo correction\n", | 106 | dev_dbg(codec->dev, "Applying %d code DC servo correction\n", |
111 | hubs->dcs_codes); | 107 | hubs->dcs_codes); |
112 | 108 | ||
109 | /* Different chips in the family support different | ||
110 | * readback methods. | ||
111 | */ | ||
112 | switch (hubs->dcs_readback_mode) { | ||
113 | case 0: | ||
114 | reg_l = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1) | ||
115 | & WM8993_DCS_INTEG_CHAN_0_MASK;; | ||
116 | reg_r = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2) | ||
117 | & WM8993_DCS_INTEG_CHAN_1_MASK; | ||
118 | break; | ||
119 | case 1: | ||
120 | reg = snd_soc_read(codec, WM8993_DC_SERVO_3); | ||
121 | reg_l = (reg & WM8993_DCS_DAC_WR_VAL_1_MASK) | ||
122 | >> WM8993_DCS_DAC_WR_VAL_1_SHIFT; | ||
123 | reg_r = reg & WM8993_DCS_DAC_WR_VAL_0_MASK; | ||
124 | break; | ||
125 | default: | ||
126 | WARN(1, "Unknown DCS readback method"); | ||
127 | break; | ||
128 | } | ||
129 | |||
113 | /* HPOUT1L */ | 130 | /* HPOUT1L */ |
114 | reg = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_1) & | 131 | if (reg_l + hubs->dcs_codes > 0 && |
115 | WM8993_DCS_INTEG_CHAN_0_MASK;; | 132 | reg_l + hubs->dcs_codes < 0xff) |
116 | reg += hubs->dcs_codes; | 133 | reg_l += hubs->dcs_codes; |
117 | dcs_cfg = reg << WM8993_DCS_DAC_WR_VAL_1_SHIFT; | 134 | dcs_cfg = reg_l << WM8993_DCS_DAC_WR_VAL_1_SHIFT; |
118 | 135 | ||
119 | /* HPOUT1R */ | 136 | /* HPOUT1R */ |
120 | reg = snd_soc_read(codec, WM8993_DC_SERVO_READBACK_2) & | 137 | if (reg_r + hubs->dcs_codes > 0 && |
121 | WM8993_DCS_INTEG_CHAN_1_MASK; | 138 | reg_r + hubs->dcs_codes < 0xff) |
122 | reg += hubs->dcs_codes; | 139 | reg_r += hubs->dcs_codes; |
123 | dcs_cfg |= reg; | 140 | dcs_cfg |= reg_r; |
124 | 141 | ||
125 | /* Do it */ | 142 | /* Do it */ |
126 | snd_soc_write(codec, WM8993_DC_SERVO_3, dcs_cfg); | 143 | snd_soc_write(codec, WM8993_DC_SERVO_3, dcs_cfg); |
127 | snd_soc_update_bits(codec, WM8993_DC_SERVO_0, | 144 | wait_for_dc_servo(codec, |
128 | WM8993_DCS_TRIG_DAC_WR_0 | | 145 | WM8993_DCS_TRIG_DAC_WR_0 | |
129 | WM8993_DCS_TRIG_DAC_WR_1, | 146 | WM8993_DCS_TRIG_DAC_WR_1); |
130 | WM8993_DCS_TRIG_DAC_WR_0 | | ||
131 | WM8993_DCS_TRIG_DAC_WR_1); | ||
132 | |||
133 | wait_for_dc_servo(codec); | ||
134 | } | 147 | } |
135 | } | 148 | } |
136 | 149 | ||
@@ -141,10 +154,16 @@ static int wm8993_put_dc_servo(struct snd_kcontrol *kcontrol, | |||
141 | struct snd_ctl_elem_value *ucontrol) | 154 | struct snd_ctl_elem_value *ucontrol) |
142 | { | 155 | { |
143 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 156 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
157 | struct wm_hubs_data *hubs = codec->private_data; | ||
144 | int ret; | 158 | int ret; |
145 | 159 | ||
146 | ret = snd_soc_put_volsw_2r(kcontrol, ucontrol); | 160 | ret = snd_soc_put_volsw_2r(kcontrol, ucontrol); |
147 | 161 | ||
162 | /* If we're applying an offset correction then updating the | ||
163 | * callibration would be likely to introduce further offsets. */ | ||
164 | if (hubs->dcs_codes) | ||
165 | return ret; | ||
166 | |||
148 | /* Only need to do this if the outputs are active */ | 167 | /* Only need to do this if the outputs are active */ |
149 | if (snd_soc_read(codec, WM8993_POWER_MANAGEMENT_1) | 168 | if (snd_soc_read(codec, WM8993_POWER_MANAGEMENT_1) |
150 | & (WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA)) | 169 | & (WM8993_HPOUT1L_ENA | WM8993_HPOUT1R_ENA)) |
diff --git a/sound/soc/codecs/wm_hubs.h b/sound/soc/codecs/wm_hubs.h index 420104fe9c9..e51c1668358 100644 --- a/sound/soc/codecs/wm_hubs.h +++ b/sound/soc/codecs/wm_hubs.h | |||
@@ -21,6 +21,7 @@ extern const unsigned int wm_hubs_spkmix_tlv[]; | |||
21 | /* This *must* be the first element of the codec->private_data struct */ | 21 | /* This *must* be the first element of the codec->private_data struct */ |
22 | struct wm_hubs_data { | 22 | struct wm_hubs_data { |
23 | int dcs_codes; | 23 | int dcs_codes; |
24 | int dcs_readback_mode; | ||
24 | int hp_startup_mode; | 25 | int hp_startup_mode; |
25 | }; | 26 | }; |
26 | 27 | ||
diff --git a/sound/soc/davinci/davinci-i2s.c b/sound/soc/davinci/davinci-i2s.c index 62af7e025e7..adadcd3aa1b 100644 --- a/sound/soc/davinci/davinci-i2s.c +++ b/sound/soc/davinci/davinci-i2s.c | |||
@@ -586,7 +586,8 @@ static int davinci_i2s_probe(struct platform_device *pdev) | |||
586 | dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel = res->start; | 586 | dev->dma_params[SNDRV_PCM_STREAM_CAPTURE].channel = res->start; |
587 | 587 | ||
588 | davinci_i2s_dai.private_data = dev; | 588 | davinci_i2s_dai.private_data = dev; |
589 | davinci_i2s_dai.dma_data = dev->dma_params; | 589 | davinci_i2s_dai.capture.dma_data = dev->dma_params; |
590 | davinci_i2s_dai.playback.dma_data = dev->dma_params; | ||
590 | ret = snd_soc_register_dai(&davinci_i2s_dai); | 591 | ret = snd_soc_register_dai(&davinci_i2s_dai); |
591 | if (ret != 0) | 592 | if (ret != 0) |
592 | goto err_free_mem; | 593 | goto err_free_mem; |
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 6c80cc35eca..79f0f4ad242 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c | |||
@@ -918,7 +918,8 @@ static int davinci_mcasp_probe(struct platform_device *pdev) | |||
918 | 918 | ||
919 | dma_data->channel = res->start; | 919 | dma_data->channel = res->start; |
920 | davinci_mcasp_dai[pdata->op_mode].private_data = dev; | 920 | davinci_mcasp_dai[pdata->op_mode].private_data = dev; |
921 | davinci_mcasp_dai[pdata->op_mode].dma_data = dev->dma_params; | 921 | davinci_mcasp_dai[pdata->op_mode].capture.dma_data = dev->dma_params; |
922 | davinci_mcasp_dai[pdata->op_mode].playback.dma_data = dev->dma_params; | ||
922 | davinci_mcasp_dai[pdata->op_mode].dev = &pdev->dev; | 923 | davinci_mcasp_dai[pdata->op_mode].dev = &pdev->dev; |
923 | ret = snd_soc_register_dai(&davinci_mcasp_dai[pdata->op_mode]); | 924 | ret = snd_soc_register_dai(&davinci_mcasp_dai[pdata->op_mode]); |
924 | 925 | ||
diff --git a/sound/soc/davinci/davinci-pcm.c b/sound/soc/davinci/davinci-pcm.c index 80c7fdf2f52..2dc406f42fe 100644 --- a/sound/soc/davinci/davinci-pcm.c +++ b/sound/soc/davinci/davinci-pcm.c | |||
@@ -649,8 +649,10 @@ static int davinci_pcm_open(struct snd_pcm_substream *substream) | |||
649 | struct snd_pcm_hardware *ppcm; | 649 | struct snd_pcm_hardware *ppcm; |
650 | int ret = 0; | 650 | int ret = 0; |
651 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 651 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
652 | struct davinci_pcm_dma_params *pa = rtd->dai->cpu_dai->dma_data; | 652 | struct davinci_pcm_dma_params *pa; |
653 | struct davinci_pcm_dma_params *params; | 653 | struct davinci_pcm_dma_params *params; |
654 | |||
655 | pa = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); | ||
654 | if (!pa) | 656 | if (!pa) |
655 | return -ENODEV; | 657 | return -ENODEV; |
656 | params = &pa[substream->stream]; | 658 | params = &pa[substream->stream]; |
diff --git a/sound/soc/imx/imx-pcm-dma-mx2.c b/sound/soc/imx/imx-pcm-dma-mx2.c index 86668ab3f4d..2e79d713629 100644 --- a/sound/soc/imx/imx-pcm-dma-mx2.c +++ b/sound/soc/imx/imx-pcm-dma-mx2.c | |||
@@ -84,11 +84,13 @@ static void snd_imx_dma_err_callback(int channel, void *data, int err) | |||
84 | static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream) | 84 | static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream) |
85 | { | 85 | { |
86 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 86 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
87 | struct imx_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data; | 87 | struct imx_pcm_dma_params *dma_params; |
88 | struct snd_pcm_runtime *runtime = substream->runtime; | 88 | struct snd_pcm_runtime *runtime = substream->runtime; |
89 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; | 89 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; |
90 | int ret; | 90 | int ret; |
91 | 91 | ||
92 | dma_params = snd_soc_get_dma_data(rtd->dai->cpu_dai, substream); | ||
93 | |||
92 | iprtd->dma = imx_dma_request_by_prio(DRV_NAME, DMA_PRIO_HIGH); | 94 | iprtd->dma = imx_dma_request_by_prio(DRV_NAME, DMA_PRIO_HIGH); |
93 | if (iprtd->dma < 0) { | 95 | if (iprtd->dma < 0) { |
94 | pr_err("Failed to claim the audio DMA\n"); | 96 | 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 | { | 195 | { |
194 | struct snd_pcm_runtime *runtime = substream->runtime; | 196 | struct snd_pcm_runtime *runtime = substream->runtime; |
195 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 197 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
196 | struct imx_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data; | 198 | struct imx_pcm_dma_params *dma_params; |
197 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; | 199 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; |
198 | int err; | 200 | int err; |
199 | 201 | ||
202 | dma_params = snd_soc_get_dma_data(rtd->dai->cpu_dai, substream); | ||
203 | |||
200 | iprtd->substream = substream; | 204 | iprtd->substream = substream; |
201 | iprtd->buf = (unsigned int *)substream->dma_buffer.area; | 205 | iprtd->buf = (unsigned int *)substream->dma_buffer.area; |
202 | iprtd->period_cnt = 0; | 206 | iprtd->period_cnt = 0; |
diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c index 6546b06cbd2..0bcc6d7d947 100644 --- a/sound/soc/imx/imx-ssi.c +++ b/sound/soc/imx/imx-ssi.c | |||
@@ -235,17 +235,20 @@ static int imx_ssi_hw_params(struct snd_pcm_substream *substream, | |||
235 | struct snd_soc_dai *cpu_dai) | 235 | struct snd_soc_dai *cpu_dai) |
236 | { | 236 | { |
237 | struct imx_ssi *ssi = cpu_dai->private_data; | 237 | struct imx_ssi *ssi = cpu_dai->private_data; |
238 | struct imx_pcm_dma_params *dma_data; | ||
238 | u32 reg, sccr; | 239 | u32 reg, sccr; |
239 | 240 | ||
240 | /* Tx/Rx config */ | 241 | /* Tx/Rx config */ |
241 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 242 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
242 | reg = SSI_STCCR; | 243 | reg = SSI_STCCR; |
243 | cpu_dai->dma_data = &ssi->dma_params_tx; | 244 | dma_data = &ssi->dma_params_tx; |
244 | } else { | 245 | } else { |
245 | reg = SSI_SRCCR; | 246 | reg = SSI_SRCCR; |
246 | cpu_dai->dma_data = &ssi->dma_params_rx; | 247 | dma_data = &ssi->dma_params_rx; |
247 | } | 248 | } |
248 | 249 | ||
250 | snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data); | ||
251 | |||
249 | sccr = readl(ssi->base + reg) & ~SSI_STCCR_WL_MASK; | 252 | sccr = readl(ssi->base + reg) & ~SSI_STCCR_WL_MASK; |
250 | 253 | ||
251 | /* DAI data (word) size */ | 254 | /* DAI data (word) size */ |
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index e814a9591f7..8ad9dc90100 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c | |||
@@ -297,7 +297,9 @@ static int omap_mcbsp_dai_hw_params(struct snd_pcm_substream *substream, | |||
297 | omap_mcbsp_dai_dma_params[id][substream->stream].sync_mode = sync_mode; | 297 | omap_mcbsp_dai_dma_params[id][substream->stream].sync_mode = sync_mode; |
298 | omap_mcbsp_dai_dma_params[id][substream->stream].data_type = | 298 | omap_mcbsp_dai_dma_params[id][substream->stream].data_type = |
299 | OMAP_DMA_DATA_TYPE_S16; | 299 | OMAP_DMA_DATA_TYPE_S16; |
300 | cpu_dai->dma_data = &omap_mcbsp_dai_dma_params[id][substream->stream]; | 300 | |
301 | snd_soc_dai_set_dma_data(cpu_dai, substream, | ||
302 | &omap_mcbsp_dai_dma_params[id][substream->stream]); | ||
301 | 303 | ||
302 | if (mcbsp_data->configured) { | 304 | if (mcbsp_data->configured) { |
303 | /* McBSP already configured by another stream */ | 305 | /* McBSP already configured by another stream */ |
diff --git a/sound/soc/omap/omap-mcpdm.c b/sound/soc/omap/omap-mcpdm.c index 25f19e4728b..b7f4f7e015f 100644 --- a/sound/soc/omap/omap-mcpdm.c +++ b/sound/soc/omap/omap-mcpdm.c | |||
@@ -150,7 +150,8 @@ static int omap_mcpdm_dai_hw_params(struct snd_pcm_substream *substream, | |||
150 | int stream = substream->stream; | 150 | int stream = substream->stream; |
151 | int channels, err, link_mask = 0; | 151 | int channels, err, link_mask = 0; |
152 | 152 | ||
153 | cpu_dai->dma_data = &omap_mcpdm_dai_dma_params[stream]; | 153 | snd_soc_dai_set_dma_data(cpu_dai, substream, |
154 | &omap_mcpdm_dai_dma_params[stream]); | ||
154 | 155 | ||
155 | channels = params_channels(params); | 156 | channels = params_channels(params); |
156 | switch (channels) { | 157 | switch (channels) { |
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c index ba8acbb0a7f..1e521904ea6 100644 --- a/sound/soc/omap/omap-pcm.c +++ b/sound/soc/omap/omap-pcm.c | |||
@@ -61,12 +61,11 @@ static void omap_pcm_dma_irq(int ch, u16 stat, void *data) | |||
61 | struct omap_runtime_data *prtd = runtime->private_data; | 61 | struct omap_runtime_data *prtd = runtime->private_data; |
62 | unsigned long flags; | 62 | unsigned long flags; |
63 | 63 | ||
64 | if ((cpu_is_omap1510()) && | 64 | if ((cpu_is_omap1510())) { |
65 | (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)) { | ||
66 | /* | 65 | /* |
67 | * OMAP1510 doesn't fully support DMA progress counter | 66 | * OMAP1510 doesn't fully support DMA progress counter |
68 | * and there is no software emulation implemented yet, | 67 | * and there is no software emulation implemented yet, |
69 | * so have to maintain our own playback progress counter | 68 | * so have to maintain our own progress counters |
70 | * that can be used by omap_pcm_pointer() instead. | 69 | * that can be used by omap_pcm_pointer() instead. |
71 | */ | 70 | */ |
72 | spin_lock_irqsave(&prtd->lock, flags); | 71 | spin_lock_irqsave(&prtd->lock, flags); |
@@ -101,9 +100,11 @@ static int omap_pcm_hw_params(struct snd_pcm_substream *substream, | |||
101 | struct snd_pcm_runtime *runtime = substream->runtime; | 100 | struct snd_pcm_runtime *runtime = substream->runtime; |
102 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 101 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
103 | struct omap_runtime_data *prtd = runtime->private_data; | 102 | struct omap_runtime_data *prtd = runtime->private_data; |
104 | struct omap_pcm_dma_data *dma_data = rtd->dai->cpu_dai->dma_data; | 103 | struct omap_pcm_dma_data *dma_data; |
105 | int err = 0; | 104 | int err = 0; |
106 | 105 | ||
106 | dma_data = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); | ||
107 | |||
107 | /* return if this is a bufferless transfer e.g. | 108 | /* return if this is a bufferless transfer e.g. |
108 | * codec <--> BT codec or GSM modem -- lg FIXME */ | 109 | * codec <--> BT codec or GSM modem -- lg FIXME */ |
109 | if (!dma_data) | 110 | if (!dma_data) |
@@ -190,8 +191,7 @@ static int omap_pcm_prepare(struct snd_pcm_substream *substream) | |||
190 | dma_params.frame_count = runtime->periods; | 191 | dma_params.frame_count = runtime->periods; |
191 | omap_set_dma_params(prtd->dma_ch, &dma_params); | 192 | omap_set_dma_params(prtd->dma_ch, &dma_params); |
192 | 193 | ||
193 | if ((cpu_is_omap1510()) && | 194 | if ((cpu_is_omap1510())) |
194 | (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)) | ||
195 | omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ | | 195 | omap_enable_dma_irq(prtd->dma_ch, OMAP_DMA_FRAME_IRQ | |
196 | OMAP_DMA_LAST_IRQ | OMAP_DMA_BLOCK_IRQ); | 196 | OMAP_DMA_LAST_IRQ | OMAP_DMA_BLOCK_IRQ); |
197 | else | 197 | else |
@@ -249,14 +249,15 @@ static snd_pcm_uframes_t omap_pcm_pointer(struct snd_pcm_substream *substream) | |||
249 | dma_addr_t ptr; | 249 | dma_addr_t ptr; |
250 | snd_pcm_uframes_t offset; | 250 | snd_pcm_uframes_t offset; |
251 | 251 | ||
252 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { | 252 | if (cpu_is_omap1510()) { |
253 | offset = prtd->period_index * runtime->period_size; | ||
254 | } else if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { | ||
253 | ptr = omap_get_dma_dst_pos(prtd->dma_ch); | 255 | ptr = omap_get_dma_dst_pos(prtd->dma_ch); |
254 | offset = bytes_to_frames(runtime, ptr - runtime->dma_addr); | 256 | offset = bytes_to_frames(runtime, ptr - runtime->dma_addr); |
255 | } else if (!(cpu_is_omap1510())) { | 257 | } else { |
256 | ptr = omap_get_dma_src_pos(prtd->dma_ch); | 258 | ptr = omap_get_dma_src_pos(prtd->dma_ch); |
257 | offset = bytes_to_frames(runtime, ptr - runtime->dma_addr); | 259 | offset = bytes_to_frames(runtime, ptr - runtime->dma_addr); |
258 | } else | 260 | } |
259 | offset = prtd->period_index * runtime->period_size; | ||
260 | 261 | ||
261 | if (offset >= runtime->buffer_size) | 262 | if (offset >= runtime->buffer_size) |
262 | offset = 0; | 263 | offset = 0; |
diff --git a/sound/soc/pxa/pxa-ssp.c b/sound/soc/pxa/pxa-ssp.c index d5fc52d0a3c..544fd9566f4 100644 --- a/sound/soc/pxa/pxa-ssp.c +++ b/sound/soc/pxa/pxa-ssp.c | |||
@@ -122,10 +122,9 @@ static int pxa_ssp_startup(struct snd_pcm_substream *substream, | |||
122 | ssp_disable(ssp); | 122 | ssp_disable(ssp); |
123 | } | 123 | } |
124 | 124 | ||
125 | if (cpu_dai->dma_data) { | 125 | kfree(snd_soc_dai_get_dma_data(cpu_dai, substream)); |
126 | kfree(cpu_dai->dma_data); | 126 | snd_soc_dai_set_dma_data(cpu_dai, substream, NULL); |
127 | cpu_dai->dma_data = NULL; | 127 | |
128 | } | ||
129 | return ret; | 128 | return ret; |
130 | } | 129 | } |
131 | 130 | ||
@@ -142,10 +141,8 @@ static void pxa_ssp_shutdown(struct snd_pcm_substream *substream, | |||
142 | clk_disable(ssp->clk); | 141 | clk_disable(ssp->clk); |
143 | } | 142 | } |
144 | 143 | ||
145 | if (cpu_dai->dma_data) { | 144 | kfree(snd_soc_dai_get_dma_data(cpu_dai, substream)); |
146 | kfree(cpu_dai->dma_data); | 145 | snd_soc_dai_set_dma_data(cpu_dai, substream, NULL); |
147 | cpu_dai->dma_data = NULL; | ||
148 | } | ||
149 | } | 146 | } |
150 | 147 | ||
151 | #ifdef CONFIG_PM | 148 | #ifdef CONFIG_PM |
@@ -570,19 +567,23 @@ static int pxa_ssp_hw_params(struct snd_pcm_substream *substream, | |||
570 | u32 sspsp; | 567 | u32 sspsp; |
571 | int width = snd_pcm_format_physical_width(params_format(params)); | 568 | int width = snd_pcm_format_physical_width(params_format(params)); |
572 | int ttsa = ssp_read_reg(ssp, SSTSA) & 0xf; | 569 | int ttsa = ssp_read_reg(ssp, SSTSA) & 0xf; |
570 | struct pxa2xx_pcm_dma_params *dma_data; | ||
571 | |||
572 | dma_data = snd_soc_dai_get_dma_data(dai, substream); | ||
573 | 573 | ||
574 | /* generate correct DMA params */ | 574 | /* generate correct DMA params */ |
575 | if (cpu_dai->dma_data) | 575 | kfree(dma_data); |
576 | kfree(cpu_dai->dma_data); | ||
577 | 576 | ||
578 | /* Network mode with one active slot (ttsa == 1) can be used | 577 | /* Network mode with one active slot (ttsa == 1) can be used |
579 | * to force 16-bit frame width on the wire (for S16_LE), even | 578 | * to force 16-bit frame width on the wire (for S16_LE), even |
580 | * with two channels. Use 16-bit DMA transfers for this case. | 579 | * with two channels. Use 16-bit DMA transfers for this case. |
581 | */ | 580 | */ |
582 | cpu_dai->dma_data = ssp_get_dma_params(ssp, | 581 | dma_data = ssp_get_dma_params(ssp, |
583 | ((chn == 2) && (ttsa != 1)) || (width == 32), | 582 | ((chn == 2) && (ttsa != 1)) || (width == 32), |
584 | substream->stream == SNDRV_PCM_STREAM_PLAYBACK); | 583 | substream->stream == SNDRV_PCM_STREAM_PLAYBACK); |
585 | 584 | ||
585 | snd_soc_dai_set_dma_data(dai, substream, dma_data); | ||
586 | |||
586 | /* we can only change the settings if the port is not in use */ | 587 | /* we can only change the settings if the port is not in use */ |
587 | if (ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) | 588 | if (ssp_read_reg(ssp, SSCR0) & SSCR0_SSE) |
588 | return 0; | 589 | return 0; |
diff --git a/sound/soc/pxa/pxa2xx-ac97.c b/sound/soc/pxa/pxa2xx-ac97.c index e9ae7b3a7e0..d314115e3dd 100644 --- a/sound/soc/pxa/pxa2xx-ac97.c +++ b/sound/soc/pxa/pxa2xx-ac97.c | |||
@@ -122,11 +122,14 @@ static int pxa2xx_ac97_hw_params(struct snd_pcm_substream *substream, | |||
122 | { | 122 | { |
123 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 123 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
124 | struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; | 124 | struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; |
125 | struct pxa2xx_pcm_dma_params *dma_data; | ||
125 | 126 | ||
126 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 127 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
127 | cpu_dai->dma_data = &pxa2xx_ac97_pcm_stereo_out; | 128 | dma_data = &pxa2xx_ac97_pcm_stereo_out; |
128 | else | 129 | else |
129 | cpu_dai->dma_data = &pxa2xx_ac97_pcm_stereo_in; | 130 | dma_data = &pxa2xx_ac97_pcm_stereo_in; |
131 | |||
132 | snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data); | ||
130 | 133 | ||
131 | return 0; | 134 | return 0; |
132 | } | 135 | } |
@@ -137,11 +140,14 @@ static int pxa2xx_ac97_hw_aux_params(struct snd_pcm_substream *substream, | |||
137 | { | 140 | { |
138 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 141 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
139 | struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; | 142 | struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; |
143 | struct pxa2xx_pcm_dma_params *dma_data; | ||
140 | 144 | ||
141 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 145 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
142 | cpu_dai->dma_data = &pxa2xx_ac97_pcm_aux_mono_out; | 146 | dma_data = &pxa2xx_ac97_pcm_aux_mono_out; |
143 | else | 147 | else |
144 | cpu_dai->dma_data = &pxa2xx_ac97_pcm_aux_mono_in; | 148 | dma_data = &pxa2xx_ac97_pcm_aux_mono_in; |
149 | |||
150 | snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data); | ||
145 | 151 | ||
146 | return 0; | 152 | return 0; |
147 | } | 153 | } |
@@ -156,7 +162,8 @@ static int pxa2xx_ac97_hw_mic_params(struct snd_pcm_substream *substream, | |||
156 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 162 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
157 | return -ENODEV; | 163 | return -ENODEV; |
158 | else | 164 | else |
159 | cpu_dai->dma_data = &pxa2xx_ac97_pcm_mic_mono_in; | 165 | snd_soc_dai_set_dma_data(cpu_dai, substream, |
166 | &pxa2xx_ac97_pcm_mic_mono_in); | ||
160 | 167 | ||
161 | return 0; | 168 | return 0; |
162 | } | 169 | } |
diff --git a/sound/soc/pxa/pxa2xx-i2s.c b/sound/soc/pxa/pxa2xx-i2s.c index 6b8f655d1ad..c1a5275721e 100644 --- a/sound/soc/pxa/pxa2xx-i2s.c +++ b/sound/soc/pxa/pxa2xx-i2s.c | |||
@@ -164,6 +164,7 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream, | |||
164 | { | 164 | { |
165 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 165 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
166 | struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; | 166 | struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; |
167 | struct pxa2xx_pcm_dma_params *dma_data; | ||
167 | 168 | ||
168 | BUG_ON(IS_ERR(clk_i2s)); | 169 | BUG_ON(IS_ERR(clk_i2s)); |
169 | clk_enable(clk_i2s); | 170 | clk_enable(clk_i2s); |
@@ -171,9 +172,11 @@ static int pxa2xx_i2s_hw_params(struct snd_pcm_substream *substream, | |||
171 | pxa_i2s_wait(); | 172 | pxa_i2s_wait(); |
172 | 173 | ||
173 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 174 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
174 | cpu_dai->dma_data = &pxa2xx_i2s_pcm_stereo_out; | 175 | dma_data = &pxa2xx_i2s_pcm_stereo_out; |
175 | else | 176 | else |
176 | cpu_dai->dma_data = &pxa2xx_i2s_pcm_stereo_in; | 177 | dma_data = &pxa2xx_i2s_pcm_stereo_in; |
178 | |||
179 | snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data); | ||
177 | 180 | ||
178 | /* is port used by another stream */ | 181 | /* is port used by another stream */ |
179 | if (!(SACR0 & SACR0_ENB)) { | 182 | if (!(SACR0 & SACR0_ENB)) { |
diff --git a/sound/soc/pxa/pxa2xx-pcm.c b/sound/soc/pxa/pxa2xx-pcm.c index d38e39575f5..adc7e6f15f9 100644 --- a/sound/soc/pxa/pxa2xx-pcm.c +++ b/sound/soc/pxa/pxa2xx-pcm.c | |||
@@ -25,9 +25,11 @@ static int pxa2xx_pcm_hw_params(struct snd_pcm_substream *substream, | |||
25 | struct snd_pcm_runtime *runtime = substream->runtime; | 25 | struct snd_pcm_runtime *runtime = substream->runtime; |
26 | struct pxa2xx_runtime_data *prtd = runtime->private_data; | 26 | struct pxa2xx_runtime_data *prtd = runtime->private_data; |
27 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 27 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
28 | struct pxa2xx_pcm_dma_params *dma = rtd->dai->cpu_dai->dma_data; | 28 | struct pxa2xx_pcm_dma_params *dma; |
29 | int ret; | 29 | int ret; |
30 | 30 | ||
31 | dma = snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); | ||
32 | |||
31 | /* return if this is a bufferless transfer e.g. | 33 | /* return if this is a bufferless transfer e.g. |
32 | * codec <--> BT codec or GSM modem -- lg FIXME */ | 34 | * codec <--> BT codec or GSM modem -- lg FIXME */ |
33 | if (!dma) | 35 | if (!dma) |
diff --git a/sound/soc/s3c24xx/s3c-ac97.c b/sound/soc/s3c24xx/s3c-ac97.c index ee8ed9d7e70..ecf4fd04ae9 100644 --- a/sound/soc/s3c24xx/s3c-ac97.c +++ b/sound/soc/s3c24xx/s3c-ac97.c | |||
@@ -224,11 +224,14 @@ static int s3c_ac97_hw_params(struct snd_pcm_substream *substream, | |||
224 | { | 224 | { |
225 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 225 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
226 | struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; | 226 | struct snd_soc_dai *cpu_dai = rtd->dai->cpu_dai; |
227 | struct s3c_dma_params *dma_data; | ||
227 | 228 | ||
228 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 229 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
229 | cpu_dai->dma_data = &s3c_ac97_pcm_out; | 230 | dma_data = &s3c_ac97_pcm_out; |
230 | else | 231 | else |
231 | cpu_dai->dma_data = &s3c_ac97_pcm_in; | 232 | dma_data = &s3c_ac97_pcm_in; |
233 | |||
234 | snd_soc_dai_set_dma_data(cpu_dai, substream, dma_data); | ||
232 | 235 | ||
233 | return 0; | 236 | return 0; |
234 | } | 237 | } |
@@ -238,8 +241,8 @@ static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd, | |||
238 | { | 241 | { |
239 | u32 ac_glbctrl; | 242 | u32 ac_glbctrl; |
240 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 243 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
241 | int channel = ((struct s3c_dma_params *) | 244 | struct s3c_dma_params *dma_data = |
242 | rtd->dai->cpu_dai->dma_data)->channel; | 245 | snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); |
243 | 246 | ||
244 | ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); | 247 | ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); |
245 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) | 248 | if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) |
@@ -265,7 +268,7 @@ static int s3c_ac97_trigger(struct snd_pcm_substream *substream, int cmd, | |||
265 | 268 | ||
266 | writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); | 269 | writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); |
267 | 270 | ||
268 | s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED); | 271 | s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED); |
269 | 272 | ||
270 | return 0; | 273 | return 0; |
271 | } | 274 | } |
@@ -280,7 +283,7 @@ static int s3c_ac97_hw_mic_params(struct snd_pcm_substream *substream, | |||
280 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 283 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
281 | return -ENODEV; | 284 | return -ENODEV; |
282 | else | 285 | else |
283 | cpu_dai->dma_data = &s3c_ac97_mic_in; | 286 | snd_soc_dai_set_dma_data(cpu_dai, substream, &s3c_ac97_mic_in); |
284 | 287 | ||
285 | return 0; | 288 | return 0; |
286 | } | 289 | } |
@@ -290,8 +293,8 @@ static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream, | |||
290 | { | 293 | { |
291 | u32 ac_glbctrl; | 294 | u32 ac_glbctrl; |
292 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 295 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
293 | int channel = ((struct s3c_dma_params *) | 296 | struct s3c_dma_params *dma_data = |
294 | rtd->dai->cpu_dai->dma_data)->channel; | 297 | snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); |
295 | 298 | ||
296 | ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); | 299 | ac_glbctrl = readl(s3c_ac97.regs + S3C_AC97_GLBCTRL); |
297 | ac_glbctrl &= ~S3C_AC97_GLBCTRL_MICINTM_MASK; | 300 | ac_glbctrl &= ~S3C_AC97_GLBCTRL_MICINTM_MASK; |
@@ -311,7 +314,7 @@ static int s3c_ac97_mic_trigger(struct snd_pcm_substream *substream, | |||
311 | 314 | ||
312 | writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); | 315 | writel(ac_glbctrl, s3c_ac97.regs + S3C_AC97_GLBCTRL); |
313 | 316 | ||
314 | s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED); | 317 | s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED); |
315 | 318 | ||
316 | return 0; | 319 | return 0; |
317 | } | 320 | } |
diff --git a/sound/soc/s3c24xx/s3c-dma.c b/sound/soc/s3c24xx/s3c-dma.c index 7725e26d6c9..1b61c23ff30 100644 --- a/sound/soc/s3c24xx/s3c-dma.c +++ b/sound/soc/s3c24xx/s3c-dma.c | |||
@@ -145,10 +145,12 @@ static int s3c_dma_hw_params(struct snd_pcm_substream *substream, | |||
145 | struct snd_pcm_runtime *runtime = substream->runtime; | 145 | struct snd_pcm_runtime *runtime = substream->runtime; |
146 | struct s3c24xx_runtime_data *prtd = runtime->private_data; | 146 | struct s3c24xx_runtime_data *prtd = runtime->private_data; |
147 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 147 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
148 | struct s3c_dma_params *dma = rtd->dai->cpu_dai->dma_data; | ||
149 | unsigned long totbytes = params_buffer_bytes(params); | 148 | unsigned long totbytes = params_buffer_bytes(params); |
149 | struct s3c_dma_params *dma = | ||
150 | snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); | ||
150 | int ret = 0; | 151 | int ret = 0; |
151 | 152 | ||
153 | |||
152 | pr_debug("Entered %s\n", __func__); | 154 | pr_debug("Entered %s\n", __func__); |
153 | 155 | ||
154 | /* return if this is a bufferless transfer e.g. | 156 | /* return if this is a bufferless transfer e.g. |
diff --git a/sound/soc/s3c24xx/s3c-i2s-v2.c b/sound/soc/s3c24xx/s3c-i2s-v2.c index e994d8374fe..88515946b6c 100644 --- a/sound/soc/s3c24xx/s3c-i2s-v2.c +++ b/sound/soc/s3c24xx/s3c-i2s-v2.c | |||
@@ -339,14 +339,17 @@ static int s3c2412_i2s_hw_params(struct snd_pcm_substream *substream, | |||
339 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 339 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
340 | struct snd_soc_dai_link *dai = rtd->dai; | 340 | struct snd_soc_dai_link *dai = rtd->dai; |
341 | struct s3c_i2sv2_info *i2s = to_info(dai->cpu_dai); | 341 | struct s3c_i2sv2_info *i2s = to_info(dai->cpu_dai); |
342 | struct s3c_dma_params *dma_data; | ||
342 | u32 iismod; | 343 | u32 iismod; |
343 | 344 | ||
344 | pr_debug("Entered %s\n", __func__); | 345 | pr_debug("Entered %s\n", __func__); |
345 | 346 | ||
346 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 347 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
347 | dai->cpu_dai->dma_data = i2s->dma_playback; | 348 | dma_data = i2s->dma_playback; |
348 | else | 349 | else |
349 | dai->cpu_dai->dma_data = i2s->dma_capture; | 350 | dma_data = i2s->dma_capture; |
351 | |||
352 | snd_soc_dai_set_dma_data(dai->cpu_dai, substream, dma_data); | ||
350 | 353 | ||
351 | /* Working copies of register */ | 354 | /* Working copies of register */ |
352 | iismod = readl(i2s->regs + S3C2412_IISMOD); | 355 | iismod = readl(i2s->regs + S3C2412_IISMOD); |
@@ -394,8 +397,8 @@ static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd, | |||
394 | int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); | 397 | int capture = (substream->stream == SNDRV_PCM_STREAM_CAPTURE); |
395 | unsigned long irqs; | 398 | unsigned long irqs; |
396 | int ret = 0; | 399 | int ret = 0; |
397 | int channel = ((struct s3c_dma_params *) | 400 | struct s3c_dma_params *dma_data = |
398 | rtd->dai->cpu_dai->dma_data)->channel; | 401 | snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); |
399 | 402 | ||
400 | pr_debug("Entered %s\n", __func__); | 403 | pr_debug("Entered %s\n", __func__); |
401 | 404 | ||
@@ -431,7 +434,7 @@ static int s3c2412_i2s_trigger(struct snd_pcm_substream *substream, int cmd, | |||
431 | * of the auto reload mechanism of S3C24XX. | 434 | * of the auto reload mechanism of S3C24XX. |
432 | * This call won't bother S3C64XX. | 435 | * This call won't bother S3C64XX. |
433 | */ | 436 | */ |
434 | s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED); | 437 | s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED); |
435 | 438 | ||
436 | break; | 439 | break; |
437 | 440 | ||
diff --git a/sound/soc/s3c24xx/s3c-pcm.c b/sound/soc/s3c24xx/s3c-pcm.c index a98f40c3cd2..326f0a9e7e3 100644 --- a/sound/soc/s3c24xx/s3c-pcm.c +++ b/sound/soc/s3c24xx/s3c-pcm.c | |||
@@ -178,6 +178,7 @@ static int s3c_pcm_hw_params(struct snd_pcm_substream *substream, | |||
178 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 178 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
179 | struct snd_soc_dai_link *dai = rtd->dai; | 179 | struct snd_soc_dai_link *dai = rtd->dai; |
180 | struct s3c_pcm_info *pcm = to_info(dai->cpu_dai); | 180 | struct s3c_pcm_info *pcm = to_info(dai->cpu_dai); |
181 | struct s3c_dma_params *dma_data; | ||
181 | void __iomem *regs = pcm->regs; | 182 | void __iomem *regs = pcm->regs; |
182 | struct clk *clk; | 183 | struct clk *clk; |
183 | int sclk_div, sync_div; | 184 | int sclk_div, sync_div; |
@@ -187,9 +188,11 @@ static int s3c_pcm_hw_params(struct snd_pcm_substream *substream, | |||
187 | dev_dbg(pcm->dev, "Entered %s\n", __func__); | 188 | dev_dbg(pcm->dev, "Entered %s\n", __func__); |
188 | 189 | ||
189 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 190 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
190 | dai->cpu_dai->dma_data = pcm->dma_playback; | 191 | dma_data = pcm->dma_playback; |
191 | else | 192 | else |
192 | dai->cpu_dai->dma_data = pcm->dma_capture; | 193 | dma_data = pcm->dma_capture; |
194 | |||
195 | snd_soc_dai_set_dma_data(dai->cpu_dai, substream, dma_data); | ||
193 | 196 | ||
194 | /* Strictly check for sample size */ | 197 | /* Strictly check for sample size */ |
195 | switch (params_format(params)) { | 198 | switch (params_format(params)) { |
diff --git a/sound/soc/s3c24xx/s3c24xx-i2s.c b/sound/soc/s3c24xx/s3c24xx-i2s.c index 0bc5950b9f0..c3ac890a398 100644 --- a/sound/soc/s3c24xx/s3c24xx-i2s.c +++ b/sound/soc/s3c24xx/s3c24xx-i2s.c | |||
@@ -242,14 +242,17 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream, | |||
242 | struct snd_soc_dai *dai) | 242 | struct snd_soc_dai *dai) |
243 | { | 243 | { |
244 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 244 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
245 | struct s3c_dma_params *dma_data; | ||
245 | u32 iismod; | 246 | u32 iismod; |
246 | 247 | ||
247 | pr_debug("Entered %s\n", __func__); | 248 | pr_debug("Entered %s\n", __func__); |
248 | 249 | ||
249 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 250 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
250 | rtd->dai->cpu_dai->dma_data = &s3c24xx_i2s_pcm_stereo_out; | 251 | dma_data = &s3c24xx_i2s_pcm_stereo_out; |
251 | else | 252 | else |
252 | rtd->dai->cpu_dai->dma_data = &s3c24xx_i2s_pcm_stereo_in; | 253 | dma_data = &s3c24xx_i2s_pcm_stereo_in; |
254 | |||
255 | snd_soc_dai_set_dma_data(rtd->dai->cpu_dai, substream, dma_data); | ||
253 | 256 | ||
254 | /* Working copies of register */ | 257 | /* Working copies of register */ |
255 | iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); | 258 | iismod = readl(s3c24xx_i2s.regs + S3C2410_IISMOD); |
@@ -258,13 +261,11 @@ static int s3c24xx_i2s_hw_params(struct snd_pcm_substream *substream, | |||
258 | switch (params_format(params)) { | 261 | switch (params_format(params)) { |
259 | case SNDRV_PCM_FORMAT_S8: | 262 | case SNDRV_PCM_FORMAT_S8: |
260 | iismod &= ~S3C2410_IISMOD_16BIT; | 263 | iismod &= ~S3C2410_IISMOD_16BIT; |
261 | ((struct s3c_dma_params *) | 264 | dma_data->dma_size = 1; |
262 | rtd->dai->cpu_dai->dma_data)->dma_size = 1; | ||
263 | break; | 265 | break; |
264 | case SNDRV_PCM_FORMAT_S16_LE: | 266 | case SNDRV_PCM_FORMAT_S16_LE: |
265 | iismod |= S3C2410_IISMOD_16BIT; | 267 | iismod |= S3C2410_IISMOD_16BIT; |
266 | ((struct s3c_dma_params *) | 268 | dma_data->dma_size = 2; |
267 | rtd->dai->cpu_dai->dma_data)->dma_size = 2; | ||
268 | break; | 269 | break; |
269 | default: | 270 | default: |
270 | return -EINVAL; | 271 | return -EINVAL; |
@@ -280,8 +281,8 @@ static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd, | |||
280 | { | 281 | { |
281 | int ret = 0; | 282 | int ret = 0; |
282 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 283 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
283 | int channel = ((struct s3c_dma_params *) | 284 | struct s3c_dma_params *dma_data = |
284 | rtd->dai->cpu_dai->dma_data)->channel; | 285 | snd_soc_dai_get_dma_data(rtd->dai->cpu_dai, substream); |
285 | 286 | ||
286 | pr_debug("Entered %s\n", __func__); | 287 | pr_debug("Entered %s\n", __func__); |
287 | 288 | ||
@@ -300,7 +301,7 @@ static int s3c24xx_i2s_trigger(struct snd_pcm_substream *substream, int cmd, | |||
300 | else | 301 | else |
301 | s3c24xx_snd_txctrl(1); | 302 | s3c24xx_snd_txctrl(1); |
302 | 303 | ||
303 | s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STARTED); | 304 | s3c2410_dma_ctrl(dma_data->channel, S3C2410_DMAOP_STARTED); |
304 | break; | 305 | break; |
305 | case SNDRV_PCM_TRIGGER_STOP: | 306 | case SNDRV_PCM_TRIGGER_STOP: |
306 | case SNDRV_PCM_TRIGGER_SUSPEND: | 307 | case SNDRV_PCM_TRIGGER_SUSPEND: |
diff --git a/sound/soc/s6000/s6000-i2s.c b/sound/soc/s6000/s6000-i2s.c index 0664fac7612..5b9ac1759bd 100644 --- a/sound/soc/s6000/s6000-i2s.c +++ b/sound/soc/s6000/s6000-i2s.c | |||
@@ -519,7 +519,8 @@ static int __devinit s6000_i2s_probe(struct platform_device *pdev) | |||
519 | 519 | ||
520 | s6000_i2s_dai.dev = &pdev->dev; | 520 | s6000_i2s_dai.dev = &pdev->dev; |
521 | s6000_i2s_dai.private_data = dev; | 521 | s6000_i2s_dai.private_data = dev; |
522 | s6000_i2s_dai.dma_data = &dev->dma_params; | 522 | s6000_i2s_dai.capture.dma_data = &dev->dma_params; |
523 | s6000_i2s_dai.playback.dma_data = &dev->dma_params; | ||
523 | 524 | ||
524 | dev->sifbase = sifmem->start; | 525 | dev->sifbase = sifmem->start; |
525 | dev->scbbase = mmio; | 526 | dev->scbbase = mmio; |
diff --git a/sound/soc/s6000/s6000-pcm.c b/sound/soc/s6000/s6000-pcm.c index 1d61109e09f..9c7f7f00ceb 100644 --- a/sound/soc/s6000/s6000-pcm.c +++ b/sound/soc/s6000/s6000-pcm.c | |||
@@ -58,13 +58,15 @@ static void s6000_pcm_enqueue_dma(struct snd_pcm_substream *substream) | |||
58 | struct snd_pcm_runtime *runtime = substream->runtime; | 58 | struct snd_pcm_runtime *runtime = substream->runtime; |
59 | struct s6000_runtime_data *prtd = runtime->private_data; | 59 | struct s6000_runtime_data *prtd = runtime->private_data; |
60 | struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; | 60 | struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; |
61 | struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; | 61 | struct s6000_pcm_dma_params *par; |
62 | int channel; | 62 | int channel; |
63 | unsigned int period_size; | 63 | unsigned int period_size; |
64 | unsigned int dma_offset; | 64 | unsigned int dma_offset; |
65 | dma_addr_t dma_pos; | 65 | dma_addr_t dma_pos; |
66 | dma_addr_t src, dst; | 66 | dma_addr_t src, dst; |
67 | 67 | ||
68 | par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream); | ||
69 | |||
68 | period_size = snd_pcm_lib_period_bytes(substream); | 70 | period_size = snd_pcm_lib_period_bytes(substream); |
69 | dma_offset = prtd->period * period_size; | 71 | dma_offset = prtd->period * period_size; |
70 | dma_pos = runtime->dma_addr + dma_offset; | 72 | dma_pos = runtime->dma_addr + dma_offset; |
@@ -101,7 +103,8 @@ static irqreturn_t s6000_pcm_irq(int irq, void *data) | |||
101 | { | 103 | { |
102 | struct snd_pcm *pcm = data; | 104 | struct snd_pcm *pcm = data; |
103 | struct snd_soc_pcm_runtime *runtime = pcm->private_data; | 105 | struct snd_soc_pcm_runtime *runtime = pcm->private_data; |
104 | struct s6000_pcm_dma_params *params = runtime->dai->cpu_dai->dma_data; | 106 | struct s6000_pcm_dma_params *params = |
107 | snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream); | ||
105 | struct s6000_runtime_data *prtd; | 108 | struct s6000_runtime_data *prtd; |
106 | unsigned int has_xrun; | 109 | unsigned int has_xrun; |
107 | int i, ret = IRQ_NONE; | 110 | int i, ret = IRQ_NONE; |
@@ -172,11 +175,13 @@ static int s6000_pcm_start(struct snd_pcm_substream *substream) | |||
172 | { | 175 | { |
173 | struct s6000_runtime_data *prtd = substream->runtime->private_data; | 176 | struct s6000_runtime_data *prtd = substream->runtime->private_data; |
174 | struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; | 177 | struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; |
175 | struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; | 178 | struct s6000_pcm_dma_params *par; |
176 | unsigned long flags; | 179 | unsigned long flags; |
177 | int srcinc; | 180 | int srcinc; |
178 | u32 dma; | 181 | u32 dma; |
179 | 182 | ||
183 | par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream); | ||
184 | |||
180 | spin_lock_irqsave(&prtd->lock, flags); | 185 | spin_lock_irqsave(&prtd->lock, flags); |
181 | 186 | ||
182 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 187 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
@@ -212,10 +217,12 @@ static int s6000_pcm_stop(struct snd_pcm_substream *substream) | |||
212 | { | 217 | { |
213 | struct s6000_runtime_data *prtd = substream->runtime->private_data; | 218 | struct s6000_runtime_data *prtd = substream->runtime->private_data; |
214 | struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; | 219 | struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; |
215 | struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; | 220 | struct s6000_pcm_dma_params *par; |
216 | unsigned long flags; | 221 | unsigned long flags; |
217 | u32 channel; | 222 | u32 channel; |
218 | 223 | ||
224 | par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream); | ||
225 | |||
219 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 226 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
220 | channel = par->dma_out; | 227 | channel = par->dma_out; |
221 | else | 228 | else |
@@ -236,9 +243,11 @@ static int s6000_pcm_stop(struct snd_pcm_substream *substream) | |||
236 | static int s6000_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | 243 | static int s6000_pcm_trigger(struct snd_pcm_substream *substream, int cmd) |
237 | { | 244 | { |
238 | struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; | 245 | struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; |
239 | struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; | 246 | struct s6000_pcm_dma_params *par; |
240 | int ret; | 247 | int ret; |
241 | 248 | ||
249 | par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream); | ||
250 | |||
242 | ret = par->trigger(substream, cmd, 0); | 251 | ret = par->trigger(substream, cmd, 0); |
243 | if (ret < 0) | 252 | if (ret < 0) |
244 | return ret; | 253 | return ret; |
@@ -275,13 +284,15 @@ static int s6000_pcm_prepare(struct snd_pcm_substream *substream) | |||
275 | static snd_pcm_uframes_t s6000_pcm_pointer(struct snd_pcm_substream *substream) | 284 | static snd_pcm_uframes_t s6000_pcm_pointer(struct snd_pcm_substream *substream) |
276 | { | 285 | { |
277 | struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; | 286 | struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; |
278 | struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; | 287 | struct s6000_pcm_dma_params *par; |
279 | struct snd_pcm_runtime *runtime = substream->runtime; | 288 | struct snd_pcm_runtime *runtime = substream->runtime; |
280 | struct s6000_runtime_data *prtd = runtime->private_data; | 289 | struct s6000_runtime_data *prtd = runtime->private_data; |
281 | unsigned long flags; | 290 | unsigned long flags; |
282 | unsigned int offset; | 291 | unsigned int offset; |
283 | dma_addr_t count; | 292 | dma_addr_t count; |
284 | 293 | ||
294 | par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream); | ||
295 | |||
285 | spin_lock_irqsave(&prtd->lock, flags); | 296 | spin_lock_irqsave(&prtd->lock, flags); |
286 | 297 | ||
287 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 298 | 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 | static int s6000_pcm_open(struct snd_pcm_substream *substream) | 316 | static int s6000_pcm_open(struct snd_pcm_substream *substream) |
306 | { | 317 | { |
307 | struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; | 318 | struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; |
308 | struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; | 319 | struct s6000_pcm_dma_params *par; |
309 | struct snd_pcm_runtime *runtime = substream->runtime; | 320 | struct snd_pcm_runtime *runtime = substream->runtime; |
310 | struct s6000_runtime_data *prtd; | 321 | struct s6000_runtime_data *prtd; |
311 | int ret; | 322 | int ret; |
312 | 323 | ||
324 | par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream); | ||
313 | snd_soc_set_runtime_hwparams(substream, &s6000_pcm_hardware); | 325 | snd_soc_set_runtime_hwparams(substream, &s6000_pcm_hardware); |
314 | 326 | ||
315 | ret = snd_pcm_hw_constraint_step(runtime, 0, | 327 | ret = snd_pcm_hw_constraint_step(runtime, 0, |
@@ -364,7 +376,7 @@ static int s6000_pcm_hw_params(struct snd_pcm_substream *substream, | |||
364 | struct snd_pcm_hw_params *hw_params) | 376 | struct snd_pcm_hw_params *hw_params) |
365 | { | 377 | { |
366 | struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; | 378 | struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; |
367 | struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; | 379 | struct s6000_pcm_dma_params *par; |
368 | int ret; | 380 | int ret; |
369 | ret = snd_pcm_lib_malloc_pages(substream, | 381 | ret = snd_pcm_lib_malloc_pages(substream, |
370 | params_buffer_bytes(hw_params)); | 382 | params_buffer_bytes(hw_params)); |
@@ -373,6 +385,8 @@ static int s6000_pcm_hw_params(struct snd_pcm_substream *substream, | |||
373 | return ret; | 385 | return ret; |
374 | } | 386 | } |
375 | 387 | ||
388 | par = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream); | ||
389 | |||
376 | if (par->same_rate) { | 390 | if (par->same_rate) { |
377 | spin_lock(&par->lock); | 391 | spin_lock(&par->lock); |
378 | if (par->rate == -1 || | 392 | if (par->rate == -1 || |
@@ -392,7 +406,8 @@ static int s6000_pcm_hw_params(struct snd_pcm_substream *substream, | |||
392 | static int s6000_pcm_hw_free(struct snd_pcm_substream *substream) | 406 | static int s6000_pcm_hw_free(struct snd_pcm_substream *substream) |
393 | { | 407 | { |
394 | struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; | 408 | struct snd_soc_pcm_runtime *soc_runtime = substream->private_data; |
395 | struct s6000_pcm_dma_params *par = soc_runtime->dai->cpu_dai->dma_data; | 409 | struct s6000_pcm_dma_params *par = |
410 | snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream); | ||
396 | 411 | ||
397 | spin_lock(&par->lock); | 412 | spin_lock(&par->lock); |
398 | par->in_use &= ~(1 << substream->stream); | 413 | par->in_use &= ~(1 << substream->stream); |
@@ -417,7 +432,8 @@ static struct snd_pcm_ops s6000_pcm_ops = { | |||
417 | static void s6000_pcm_free(struct snd_pcm *pcm) | 432 | static void s6000_pcm_free(struct snd_pcm *pcm) |
418 | { | 433 | { |
419 | struct snd_soc_pcm_runtime *runtime = pcm->private_data; | 434 | struct snd_soc_pcm_runtime *runtime = pcm->private_data; |
420 | struct s6000_pcm_dma_params *params = runtime->dai->cpu_dai->dma_data; | 435 | struct s6000_pcm_dma_params *params = |
436 | snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream); | ||
421 | 437 | ||
422 | free_irq(params->irq, pcm); | 438 | free_irq(params->irq, pcm); |
423 | snd_pcm_lib_preallocate_free_for_all(pcm); | 439 | snd_pcm_lib_preallocate_free_for_all(pcm); |
@@ -429,9 +445,11 @@ static int s6000_pcm_new(struct snd_card *card, | |||
429 | struct snd_soc_dai *dai, struct snd_pcm *pcm) | 445 | struct snd_soc_dai *dai, struct snd_pcm *pcm) |
430 | { | 446 | { |
431 | struct snd_soc_pcm_runtime *runtime = pcm->private_data; | 447 | struct snd_soc_pcm_runtime *runtime = pcm->private_data; |
432 | struct s6000_pcm_dma_params *params = runtime->dai->cpu_dai->dma_data; | 448 | struct s6000_pcm_dma_params *params; |
433 | int res; | 449 | int res; |
434 | 450 | ||
451 | params = snd_soc_dai_get_dma_data(soc_runtime->dai->cpu_dai, substream); | ||
452 | |||
435 | if (!card->dev->dma_mask) | 453 | if (!card->dev->dma_mask) |
436 | card->dev->dma_mask = &s6000_pcm_dmamask; | 454 | card->dev->dma_mask = &s6000_pcm_dmamask; |
437 | if (!card->dev->coherent_dma_mask) | 455 | if (!card->dev->coherent_dma_mask) |
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index 2320153bd92..ad7f9528d75 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
@@ -1549,7 +1549,8 @@ int snd_soc_new_pcms(struct snd_soc_device *socdev, int idx, const char *xid) | |||
1549 | mutex_unlock(&codec->mutex); | 1549 | mutex_unlock(&codec->mutex); |
1550 | return ret; | 1550 | return ret; |
1551 | } | 1551 | } |
1552 | if (card->dai_link[i].codec_dai->ac97_control) { | 1552 | /* Check for codec->ac97 to handle the ac97.c fun */ |
1553 | if (card->dai_link[i].codec_dai->ac97_control && codec->ac97) { | ||
1553 | snd_ac97_dev_add_pdata(codec->ac97, | 1554 | snd_ac97_dev_add_pdata(codec->ac97, |
1554 | card->dai_link[i].cpu_dai->ac97_pdata); | 1555 | card->dai_link[i].cpu_dai->ac97_pdata); |
1555 | } | 1556 | } |