diff options
author | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2010-05-06 21:29:25 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2010-05-06 21:29:25 -0400 |
commit | 1ed31d6db90d51010545921e59d369d2f92b7ac2 (patch) | |
tree | 358a0b346bc8135cd5e53700eb44308b1a7c8c5b /sound | |
parent | ceba1abcb00b0ef0b1efcd715285f6e05523edef (diff) | |
parent | 722154e4cacf015161efe60009ae9be23d492296 (diff) |
Merge commit 'origin/master' into next
Diffstat (limited to 'sound')
45 files changed, 652 insertions, 292 deletions
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c index 656e474dca47..91acc9a243ec 100644 --- a/sound/arm/aaci.c +++ b/sound/arm/aaci.c | |||
@@ -863,7 +863,6 @@ static int __devinit aaci_probe_ac97(struct aaci *aaci) | |||
863 | struct snd_ac97 *ac97; | 863 | struct snd_ac97 *ac97; |
864 | int ret; | 864 | int ret; |
865 | 865 | ||
866 | writel(0, aaci->base + AC97_POWERDOWN); | ||
867 | /* | 866 | /* |
868 | * Assert AACIRESET for 2us | 867 | * Assert AACIRESET for 2us |
869 | */ | 868 | */ |
@@ -1047,7 +1046,11 @@ static int __devinit aaci_probe(struct amba_device *dev, struct amba_id *id) | |||
1047 | 1046 | ||
1048 | writel(0x1fff, aaci->base + AACI_INTCLR); | 1047 | writel(0x1fff, aaci->base + AACI_INTCLR); |
1049 | writel(aaci->maincr, aaci->base + AACI_MAINCR); | 1048 | writel(aaci->maincr, aaci->base + AACI_MAINCR); |
1050 | 1049 | /* | |
1050 | * Fix: ac97 read back fail errors by reading | ||
1051 | * from any arbitrary aaci register. | ||
1052 | */ | ||
1053 | readl(aaci->base + AACI_CSCH1); | ||
1051 | ret = aaci_probe_ac97(aaci); | 1054 | ret = aaci_probe_ac97(aaci); |
1052 | if (ret) | 1055 | if (ret) |
1053 | goto out; | 1056 | goto out; |
diff --git a/sound/core/timer.c b/sound/core/timer.c index 73943651caed..5040c7b862fe 100644 --- a/sound/core/timer.c +++ b/sound/core/timer.c | |||
@@ -1160,6 +1160,7 @@ static void snd_timer_user_ccallback(struct snd_timer_instance *timeri, | |||
1160 | { | 1160 | { |
1161 | struct snd_timer_user *tu = timeri->callback_data; | 1161 | struct snd_timer_user *tu = timeri->callback_data; |
1162 | struct snd_timer_tread r1; | 1162 | struct snd_timer_tread r1; |
1163 | unsigned long flags; | ||
1163 | 1164 | ||
1164 | if (event >= SNDRV_TIMER_EVENT_START && | 1165 | if (event >= SNDRV_TIMER_EVENT_START && |
1165 | event <= SNDRV_TIMER_EVENT_PAUSE) | 1166 | event <= SNDRV_TIMER_EVENT_PAUSE) |
@@ -1169,9 +1170,9 @@ static void snd_timer_user_ccallback(struct snd_timer_instance *timeri, | |||
1169 | r1.event = event; | 1170 | r1.event = event; |
1170 | r1.tstamp = *tstamp; | 1171 | r1.tstamp = *tstamp; |
1171 | r1.val = resolution; | 1172 | r1.val = resolution; |
1172 | spin_lock(&tu->qlock); | 1173 | spin_lock_irqsave(&tu->qlock, flags); |
1173 | snd_timer_user_append_to_tqueue(tu, &r1); | 1174 | snd_timer_user_append_to_tqueue(tu, &r1); |
1174 | spin_unlock(&tu->qlock); | 1175 | spin_unlock_irqrestore(&tu->qlock, flags); |
1175 | kill_fasync(&tu->fasync, SIGIO, POLL_IN); | 1176 | kill_fasync(&tu->fasync, SIGIO, POLL_IN); |
1176 | wake_up(&tu->qchange_sleep); | 1177 | wake_up(&tu->qchange_sleep); |
1177 | } | 1178 | } |
diff --git a/sound/i2c/other/ak4113.c b/sound/i2c/other/ak4113.c index fff62cc8607c..971a84a4fa77 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/isa/sb/es968.c b/sound/isa/sb/es968.c index cafc3a7316a8..ff18286fef9d 100644 --- a/sound/isa/sb/es968.c +++ b/sound/isa/sb/es968.c | |||
@@ -93,7 +93,7 @@ static int __devinit snd_card_es968_pnp(int dev, struct snd_card_es968 *acard, | |||
93 | return err; | 93 | return err; |
94 | } | 94 | } |
95 | port[dev] = pnp_port_start(pdev, 0); | 95 | port[dev] = pnp_port_start(pdev, 0); |
96 | dma8[dev] = pnp_dma(pdev, 1); | 96 | dma8[dev] = pnp_dma(pdev, 0); |
97 | irq[dev] = pnp_irq(pdev, 0); | 97 | irq[dev] = pnp_irq(pdev, 0); |
98 | 98 | ||
99 | return 0; | 99 | return 0; |
diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c index 8dab82d7d19d..668a5ec04499 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 4bb90675f70f..cec68152dcb1 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -2272,6 +2272,8 @@ static struct snd_pci_quirk position_fix_list[] __devinitdata = { | |||
2272 | SND_PCI_QUIRK(0x1458, 0xa022, "ga-ma770-ud3", POS_FIX_LPIB), | 2272 | SND_PCI_QUIRK(0x1458, 0xa022, "ga-ma770-ud3", POS_FIX_LPIB), |
2273 | SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB), | 2273 | SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB), |
2274 | SND_PCI_QUIRK(0x1565, 0x820f, "Biostar Microtech", POS_FIX_LPIB), | 2274 | SND_PCI_QUIRK(0x1565, 0x820f, "Biostar Microtech", POS_FIX_LPIB), |
2275 | SND_PCI_QUIRK(0x1565, 0x8218, "Biostar Microtech", POS_FIX_LPIB), | ||
2276 | SND_PCI_QUIRK(0x8086, 0x2503, "DG965OT AAD63733-203", POS_FIX_LPIB), | ||
2275 | SND_PCI_QUIRK(0x8086, 0xd601, "eMachines T5212", POS_FIX_LPIB), | 2277 | SND_PCI_QUIRK(0x8086, 0xd601, "eMachines T5212", POS_FIX_LPIB), |
2276 | {} | 2278 | {} |
2277 | }; | 2279 | }; |
@@ -2362,6 +2364,7 @@ static struct snd_pci_quirk msi_black_list[] __devinitdata = { | |||
2362 | SND_PCI_QUIRK(0x1043, 0x81f6, "ASUS", 0), /* nvidia */ | 2364 | SND_PCI_QUIRK(0x1043, 0x81f6, "ASUS", 0), /* nvidia */ |
2363 | SND_PCI_QUIRK(0x1043, 0x822d, "ASUS", 0), /* Athlon64 X2 + nvidia MCP55 */ | 2365 | SND_PCI_QUIRK(0x1043, 0x822d, "ASUS", 0), /* Athlon64 X2 + nvidia MCP55 */ |
2364 | SND_PCI_QUIRK(0x1849, 0x0888, "ASRock", 0), /* Athlon64 X2 + nvidia */ | 2366 | SND_PCI_QUIRK(0x1849, 0x0888, "ASRock", 0), /* Athlon64 X2 + nvidia */ |
2367 | SND_PCI_QUIRK(0xa0a0, 0x0575, "Aopen MZ915-M", 0), /* ICH6 */ | ||
2365 | {} | 2368 | {} |
2366 | }; | 2369 | }; |
2367 | 2370 | ||
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index e6d1bdff1b6e..e9fdfc4b1c57 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
@@ -519,14 +519,6 @@ static int ad198x_suspend(struct hda_codec *codec, pm_message_t state) | |||
519 | ad198x_power_eapd(codec); | 519 | ad198x_power_eapd(codec); |
520 | return 0; | 520 | return 0; |
521 | } | 521 | } |
522 | |||
523 | static int ad198x_resume(struct hda_codec *codec) | ||
524 | { | ||
525 | ad198x_init(codec); | ||
526 | snd_hda_codec_resume_amp(codec); | ||
527 | snd_hda_codec_resume_cache(codec); | ||
528 | return 0; | ||
529 | } | ||
530 | #endif | 522 | #endif |
531 | 523 | ||
532 | static struct hda_codec_ops ad198x_patch_ops = { | 524 | static struct hda_codec_ops ad198x_patch_ops = { |
@@ -539,7 +531,6 @@ static struct hda_codec_ops ad198x_patch_ops = { | |||
539 | #endif | 531 | #endif |
540 | #ifdef SND_HDA_NEEDS_RESUME | 532 | #ifdef SND_HDA_NEEDS_RESUME |
541 | .suspend = ad198x_suspend, | 533 | .suspend = ad198x_suspend, |
542 | .resume = ad198x_resume, | ||
543 | #endif | 534 | #endif |
544 | .reboot_notify = ad198x_shutup, | 535 | .reboot_notify = ad198x_shutup, |
545 | }; | 536 | }; |
@@ -1896,6 +1887,14 @@ static int patch_ad1981(struct hda_codec *codec) | |||
1896 | case AD1981_THINKPAD: | 1887 | case AD1981_THINKPAD: |
1897 | spec->mixers[0] = ad1981_thinkpad_mixers; | 1888 | spec->mixers[0] = ad1981_thinkpad_mixers; |
1898 | spec->input_mux = &ad1981_thinkpad_capture_source; | 1889 | spec->input_mux = &ad1981_thinkpad_capture_source; |
1890 | /* set the upper-limit for mixer amp to 0dB for avoiding the | ||
1891 | * possible damage by overloading | ||
1892 | */ | ||
1893 | snd_hda_override_amp_caps(codec, 0x11, HDA_INPUT, | ||
1894 | (0x17 << AC_AMPCAP_OFFSET_SHIFT) | | ||
1895 | (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) | | ||
1896 | (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) | | ||
1897 | (1 << AC_AMPCAP_MUTE_SHIFT)); | ||
1899 | break; | 1898 | break; |
1900 | case AD1981_TOSHIBA: | 1899 | case AD1981_TOSHIBA: |
1901 | spec->mixers[0] = ad1981_hp_mixers; | 1900 | spec->mixers[0] = ad1981_hp_mixers; |
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index 7de782a5b8f4..350ee8ac4153 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c | |||
@@ -766,7 +766,7 @@ static int build_input(struct hda_codec *codec) | |||
766 | for (n = 0; n < AUTO_PIN_LAST; n++) { | 766 | for (n = 0; n < AUTO_PIN_LAST; n++) { |
767 | if (!spec->adc_nid[n]) | 767 | if (!spec->adc_nid[n]) |
768 | continue; | 768 | continue; |
769 | err = snd_hda_add_nid(codec, kctl, 0, spec->adc_nid[i]); | 769 | err = snd_hda_add_nid(codec, kctl, 0, spec->adc_nid[n]); |
770 | if (err < 0) | 770 | if (err < 0) |
771 | return err; | 771 | return err; |
772 | } | 772 | } |
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 61682e1d09da..56e52071c769 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -1195,9 +1195,10 @@ static int patch_cxt5045(struct hda_codec *codec) | |||
1195 | 1195 | ||
1196 | switch (codec->subsystem_id >> 16) { | 1196 | switch (codec->subsystem_id >> 16) { |
1197 | case 0x103c: | 1197 | case 0x103c: |
1198 | case 0x1631: | ||
1198 | case 0x1734: | 1199 | case 0x1734: |
1199 | /* HP & Fujitsu-Siemens laptops have really bad sound over 0dB | 1200 | /* HP, Packard Bell, & Fujitsu-Siemens laptops have really bad |
1200 | * on NID 0x17. Fix max PCM level to 0 dB | 1201 | * sound over 0dB on NID 0x17. Fix max PCM level to 0 dB |
1201 | * (originally it has 0x2b steps with 0dB offset 0x14) | 1202 | * (originally it has 0x2b steps with 0dB offset 0x14) |
1202 | */ | 1203 | */ |
1203 | snd_hda_override_amp_caps(codec, 0x17, HDA_INPUT, | 1204 | snd_hda_override_amp_caps(codec, 0x17, HDA_INPUT, |
@@ -2842,6 +2843,9 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = { | |||
2842 | CXT5066_DELL_LAPTOP), | 2843 | CXT5066_DELL_LAPTOP), |
2843 | SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5), | 2844 | SND_PCI_QUIRK(0x152d, 0x0833, "OLPC XO-1.5", CXT5066_OLPC_XO_1_5), |
2844 | SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTO), | 2845 | SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTO), |
2846 | SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD), | ||
2847 | SND_PCI_QUIRK(0x1179, 0xff50, "Toshiba Satellite P500-PSPGSC-01800T", CXT5066_OLPC_XO_1_5), | ||
2848 | SND_PCI_QUIRK(0x1179, 0xffe0, "Toshiba Satellite Pro T130-15F", CXT5066_OLPC_XO_1_5), | ||
2845 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "ideapad", CXT5066_IDEAPAD), | 2849 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "ideapad", CXT5066_IDEAPAD), |
2846 | {} | 2850 | {} |
2847 | }; | 2851 | }; |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 9a23444e9e7a..7404dba16f83 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -230,6 +230,7 @@ enum { | |||
230 | ALC888_ACER_ASPIRE_7730G, | 230 | ALC888_ACER_ASPIRE_7730G, |
231 | ALC883_MEDION, | 231 | ALC883_MEDION, |
232 | ALC883_MEDION_MD2, | 232 | ALC883_MEDION_MD2, |
233 | ALC883_MEDION_WIM2160, | ||
233 | ALC883_LAPTOP_EAPD, | 234 | ALC883_LAPTOP_EAPD, |
234 | ALC883_LENOVO_101E_2ch, | 235 | ALC883_LENOVO_101E_2ch, |
235 | ALC883_LENOVO_NB0763, | 236 | ALC883_LENOVO_NB0763, |
@@ -1389,22 +1390,31 @@ struct alc_fixup { | |||
1389 | 1390 | ||
1390 | static void alc_pick_fixup(struct hda_codec *codec, | 1391 | static void alc_pick_fixup(struct hda_codec *codec, |
1391 | const struct snd_pci_quirk *quirk, | 1392 | const struct snd_pci_quirk *quirk, |
1392 | const struct alc_fixup *fix) | 1393 | const struct alc_fixup *fix, |
1394 | int pre_init) | ||
1393 | { | 1395 | { |
1394 | const struct alc_pincfg *cfg; | 1396 | const struct alc_pincfg *cfg; |
1395 | 1397 | ||
1396 | quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk); | 1398 | quirk = snd_pci_quirk_lookup(codec->bus->pci, quirk); |
1397 | if (!quirk) | 1399 | if (!quirk) |
1398 | return; | 1400 | return; |
1399 | |||
1400 | fix += quirk->value; | 1401 | fix += quirk->value; |
1401 | cfg = fix->pins; | 1402 | cfg = fix->pins; |
1402 | if (cfg) { | 1403 | if (pre_init && cfg) { |
1404 | #ifdef CONFIG_SND_DEBUG_VERBOSE | ||
1405 | snd_printdd(KERN_INFO "hda_codec: %s: Apply pincfg for %s\n", | ||
1406 | codec->chip_name, quirk->name); | ||
1407 | #endif | ||
1403 | for (; cfg->nid; cfg++) | 1408 | for (; cfg->nid; cfg++) |
1404 | snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val); | 1409 | snd_hda_codec_set_pincfg(codec, cfg->nid, cfg->val); |
1405 | } | 1410 | } |
1406 | if (fix->verbs) | 1411 | if (!pre_init && fix->verbs) { |
1412 | #ifdef CONFIG_SND_DEBUG_VERBOSE | ||
1413 | snd_printdd(KERN_INFO "hda_codec: %s: Apply fix-verbs for %s\n", | ||
1414 | codec->chip_name, quirk->name); | ||
1415 | #endif | ||
1407 | add_verb(codec->spec, fix->verbs); | 1416 | add_verb(codec->spec, fix->verbs); |
1417 | } | ||
1408 | } | 1418 | } |
1409 | 1419 | ||
1410 | static int alc_read_coef_idx(struct hda_codec *codec, | 1420 | static int alc_read_coef_idx(struct hda_codec *codec, |
@@ -1621,6 +1631,11 @@ static struct hda_verb alc888_acer_aspire_4930g_verbs[] = { | |||
1621 | */ | 1631 | */ |
1622 | 1632 | ||
1623 | static struct hda_verb alc888_acer_aspire_6530g_verbs[] = { | 1633 | static struct hda_verb alc888_acer_aspire_6530g_verbs[] = { |
1634 | /* Route to built-in subwoofer as well as speakers */ | ||
1635 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
1636 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
1637 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
1638 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
1624 | /* Bias voltage on for external mic port */ | 1639 | /* Bias voltage on for external mic port */ |
1625 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80}, | 1640 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80}, |
1626 | /* Front Mic: set to PIN_IN (empty by default) */ | 1641 | /* Front Mic: set to PIN_IN (empty by default) */ |
@@ -1632,10 +1647,12 @@ static struct hda_verb alc888_acer_aspire_6530g_verbs[] = { | |||
1632 | /* Enable speaker output */ | 1647 | /* Enable speaker output */ |
1633 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 1648 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
1634 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 1649 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
1650 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, | ||
1635 | /* Enable headphone output */ | 1651 | /* Enable headphone output */ |
1636 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP}, | 1652 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | PIN_HP}, |
1637 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 1653 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
1638 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, | 1654 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, |
1655 | {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, | ||
1639 | { } | 1656 | { } |
1640 | }; | 1657 | }; |
1641 | 1658 | ||
@@ -4126,7 +4143,7 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = { | |||
4126 | SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG), | 4143 | SND_PCI_QUIRK(0x1695, 0x4012, "EPox EP-5LDA", ALC880_5ST_DIG), |
4127 | SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734), | 4144 | SND_PCI_QUIRK(0x1734, 0x107c, "FSC F1734", ALC880_F1734), |
4128 | SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU), | 4145 | SND_PCI_QUIRK(0x1734, 0x1094, "FSC Amilo M1451G", ALC880_FUJITSU), |
4129 | SND_PCI_QUIRK(0x1734, 0x10ac, "FSC", ALC880_UNIWILL), | 4146 | SND_PCI_QUIRK(0x1734, 0x10ac, "FSC AMILO Xi 1526", ALC880_F1734), |
4130 | SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU), | 4147 | SND_PCI_QUIRK(0x1734, 0x10b0, "Fujitsu", ALC880_FUJITSU), |
4131 | SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW), | 4148 | SND_PCI_QUIRK(0x1854, 0x0018, "LG LW20", ALC880_LG_LW), |
4132 | SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG), | 4149 | SND_PCI_QUIRK(0x1854, 0x003b, "LG", ALC880_LG), |
@@ -4801,6 +4818,25 @@ static void alc880_auto_init_analog_input(struct hda_codec *codec) | |||
4801 | } | 4818 | } |
4802 | } | 4819 | } |
4803 | 4820 | ||
4821 | static void alc880_auto_init_input_src(struct hda_codec *codec) | ||
4822 | { | ||
4823 | struct alc_spec *spec = codec->spec; | ||
4824 | int c; | ||
4825 | |||
4826 | for (c = 0; c < spec->num_adc_nids; c++) { | ||
4827 | unsigned int mux_idx; | ||
4828 | const struct hda_input_mux *imux; | ||
4829 | mux_idx = c >= spec->num_mux_defs ? 0 : c; | ||
4830 | imux = &spec->input_mux[mux_idx]; | ||
4831 | if (!imux->num_items && mux_idx > 0) | ||
4832 | imux = &spec->input_mux[0]; | ||
4833 | if (imux) | ||
4834 | snd_hda_codec_write(codec, spec->adc_nids[c], 0, | ||
4835 | AC_VERB_SET_CONNECT_SEL, | ||
4836 | imux->items[0].index); | ||
4837 | } | ||
4838 | } | ||
4839 | |||
4804 | /* parse the BIOS configuration and set up the alc_spec */ | 4840 | /* parse the BIOS configuration and set up the alc_spec */ |
4805 | /* return 1 if successful, 0 if the proper config is not found, | 4841 | /* return 1 if successful, 0 if the proper config is not found, |
4806 | * or a negative error code | 4842 | * or a negative error code |
@@ -4879,6 +4915,7 @@ static void alc880_auto_init(struct hda_codec *codec) | |||
4879 | alc880_auto_init_multi_out(codec); | 4915 | alc880_auto_init_multi_out(codec); |
4880 | alc880_auto_init_extra_out(codec); | 4916 | alc880_auto_init_extra_out(codec); |
4881 | alc880_auto_init_analog_input(codec); | 4917 | alc880_auto_init_analog_input(codec); |
4918 | alc880_auto_init_input_src(codec); | ||
4882 | if (spec->unsol_event) | 4919 | if (spec->unsol_event) |
4883 | alc_inithook(codec); | 4920 | alc_inithook(codec); |
4884 | } | 4921 | } |
@@ -4984,6 +5021,70 @@ static void set_capture_mixer(struct hda_codec *codec) | |||
4984 | } | 5021 | } |
4985 | } | 5022 | } |
4986 | 5023 | ||
5024 | /* fill adc_nids (and capsrc_nids) containing all active input pins */ | ||
5025 | static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids, | ||
5026 | int num_nids) | ||
5027 | { | ||
5028 | struct alc_spec *spec = codec->spec; | ||
5029 | int n; | ||
5030 | hda_nid_t fallback_adc = 0, fallback_cap = 0; | ||
5031 | |||
5032 | for (n = 0; n < num_nids; n++) { | ||
5033 | hda_nid_t adc, cap; | ||
5034 | hda_nid_t conn[HDA_MAX_NUM_INPUTS]; | ||
5035 | int nconns, i, j; | ||
5036 | |||
5037 | adc = nids[n]; | ||
5038 | if (get_wcaps_type(get_wcaps(codec, adc)) != AC_WID_AUD_IN) | ||
5039 | continue; | ||
5040 | cap = adc; | ||
5041 | nconns = snd_hda_get_connections(codec, cap, conn, | ||
5042 | ARRAY_SIZE(conn)); | ||
5043 | if (nconns == 1) { | ||
5044 | cap = conn[0]; | ||
5045 | nconns = snd_hda_get_connections(codec, cap, conn, | ||
5046 | ARRAY_SIZE(conn)); | ||
5047 | } | ||
5048 | if (nconns <= 0) | ||
5049 | continue; | ||
5050 | if (!fallback_adc) { | ||
5051 | fallback_adc = adc; | ||
5052 | fallback_cap = cap; | ||
5053 | } | ||
5054 | for (i = 0; i < AUTO_PIN_LAST; i++) { | ||
5055 | hda_nid_t nid = spec->autocfg.input_pins[i]; | ||
5056 | if (!nid) | ||
5057 | continue; | ||
5058 | for (j = 0; j < nconns; j++) { | ||
5059 | if (conn[j] == nid) | ||
5060 | break; | ||
5061 | } | ||
5062 | if (j >= nconns) | ||
5063 | break; | ||
5064 | } | ||
5065 | if (i >= AUTO_PIN_LAST) { | ||
5066 | int num_adcs = spec->num_adc_nids; | ||
5067 | spec->private_adc_nids[num_adcs] = adc; | ||
5068 | spec->private_capsrc_nids[num_adcs] = cap; | ||
5069 | spec->num_adc_nids++; | ||
5070 | spec->adc_nids = spec->private_adc_nids; | ||
5071 | if (adc != cap) | ||
5072 | spec->capsrc_nids = spec->private_capsrc_nids; | ||
5073 | } | ||
5074 | } | ||
5075 | if (!spec->num_adc_nids) { | ||
5076 | printk(KERN_WARNING "hda_codec: %s: no valid ADC found;" | ||
5077 | " using fallback 0x%x\n", | ||
5078 | codec->chip_name, fallback_adc); | ||
5079 | spec->private_adc_nids[0] = fallback_adc; | ||
5080 | spec->adc_nids = spec->private_adc_nids; | ||
5081 | if (fallback_adc != fallback_cap) { | ||
5082 | spec->private_capsrc_nids[0] = fallback_cap; | ||
5083 | spec->capsrc_nids = spec->private_adc_nids; | ||
5084 | } | ||
5085 | } | ||
5086 | } | ||
5087 | |||
4987 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | 5088 | #ifdef CONFIG_SND_HDA_INPUT_BEEP |
4988 | #define set_beep_amp(spec, nid, idx, dir) \ | 5089 | #define set_beep_amp(spec, nid, idx, dir) \ |
4989 | ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) | 5090 | ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) |
@@ -6326,6 +6427,8 @@ static void alc260_auto_init_analog_input(struct hda_codec *codec) | |||
6326 | } | 6427 | } |
6327 | } | 6428 | } |
6328 | 6429 | ||
6430 | #define alc260_auto_init_input_src alc880_auto_init_input_src | ||
6431 | |||
6329 | /* | 6432 | /* |
6330 | * generic initialization of ADC, input mixers and output mixers | 6433 | * generic initialization of ADC, input mixers and output mixers |
6331 | */ | 6434 | */ |
@@ -6412,6 +6515,7 @@ static void alc260_auto_init(struct hda_codec *codec) | |||
6412 | struct alc_spec *spec = codec->spec; | 6515 | struct alc_spec *spec = codec->spec; |
6413 | alc260_auto_init_multi_out(codec); | 6516 | alc260_auto_init_multi_out(codec); |
6414 | alc260_auto_init_analog_input(codec); | 6517 | alc260_auto_init_analog_input(codec); |
6518 | alc260_auto_init_input_src(codec); | ||
6415 | if (spec->unsol_event) | 6519 | if (spec->unsol_event) |
6416 | alc_inithook(codec); | 6520 | alc_inithook(codec); |
6417 | } | 6521 | } |
@@ -8384,6 +8488,42 @@ static struct snd_kcontrol_new alc883_medion_md2_mixer[] = { | |||
8384 | { } /* end */ | 8488 | { } /* end */ |
8385 | }; | 8489 | }; |
8386 | 8490 | ||
8491 | static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = { | ||
8492 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | ||
8493 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | ||
8494 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT), | ||
8495 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT), | ||
8496 | HDA_CODEC_VOLUME("Line Playback Volume", 0x08, 0x0, HDA_INPUT), | ||
8497 | HDA_CODEC_MUTE("Line Playback Switch", 0x08, 0x0, HDA_INPUT), | ||
8498 | { } /* end */ | ||
8499 | }; | ||
8500 | |||
8501 | static struct hda_verb alc883_medion_wim2160_verbs[] = { | ||
8502 | /* Unmute front mixer */ | ||
8503 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
8504 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
8505 | |||
8506 | /* Set speaker pin to front mixer */ | ||
8507 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
8508 | |||
8509 | /* Init headphone pin */ | ||
8510 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | ||
8511 | {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
8512 | {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, | ||
8513 | {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, | ||
8514 | |||
8515 | { } /* end */ | ||
8516 | }; | ||
8517 | |||
8518 | /* toggle speaker-output according to the hp-jack state */ | ||
8519 | static void alc883_medion_wim2160_setup(struct hda_codec *codec) | ||
8520 | { | ||
8521 | struct alc_spec *spec = codec->spec; | ||
8522 | |||
8523 | spec->autocfg.hp_pins[0] = 0x1a; | ||
8524 | spec->autocfg.speaker_pins[0] = 0x15; | ||
8525 | } | ||
8526 | |||
8387 | static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { | 8527 | static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { |
8388 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 8528 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
8389 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 8529 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
@@ -8398,9 +8538,7 @@ static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { | |||
8398 | 8538 | ||
8399 | static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = { | 8539 | static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = { |
8400 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 8540 | 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), | 8541 | 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), | 8542 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), |
8405 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), | 8543 | HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), |
8406 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | 8544 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), |
@@ -9095,6 +9233,7 @@ static const char *alc882_models[ALC882_MODEL_LAST] = { | |||
9095 | [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g", | 9233 | [ALC888_ACER_ASPIRE_7730G] = "acer-aspire-7730g", |
9096 | [ALC883_MEDION] = "medion", | 9234 | [ALC883_MEDION] = "medion", |
9097 | [ALC883_MEDION_MD2] = "medion-md2", | 9235 | [ALC883_MEDION_MD2] = "medion-md2", |
9236 | [ALC883_MEDION_WIM2160] = "medion-wim2160", | ||
9098 | [ALC883_LAPTOP_EAPD] = "laptop-eapd", | 9237 | [ALC883_LAPTOP_EAPD] = "laptop-eapd", |
9099 | [ALC883_LENOVO_101E_2ch] = "lenovo-101e", | 9238 | [ALC883_LENOVO_101E_2ch] = "lenovo-101e", |
9100 | [ALC883_LENOVO_NB0763] = "lenovo-nb0763", | 9239 | [ALC883_LENOVO_NB0763] = "lenovo-nb0763", |
@@ -9211,6 +9350,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = { | |||
9211 | SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG), | 9350 | SND_PCI_QUIRK(0x1462, 0xaa08, "MSI", ALC883_TARGA_2ch_DIG), |
9212 | 9351 | ||
9213 | SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG), | 9352 | SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG), |
9353 | SND_PCI_QUIRK(0x1558, 0x0571, "Clevo laptop M570U", ALC883_3ST_6ch_DIG), | ||
9214 | SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720), | 9354 | SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720), |
9215 | SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720), | 9355 | SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720), |
9216 | SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R), | 9356 | SND_PCI_QUIRK(0x1558, 0x5409, "Clevo laptop M540R", ALC883_CLEVO_M540R), |
@@ -9749,6 +9889,21 @@ static struct alc_config_preset alc882_presets[] = { | |||
9749 | .setup = alc883_medion_md2_setup, | 9889 | .setup = alc883_medion_md2_setup, |
9750 | .init_hook = alc_automute_amp, | 9890 | .init_hook = alc_automute_amp, |
9751 | }, | 9891 | }, |
9892 | [ALC883_MEDION_WIM2160] = { | ||
9893 | .mixers = { alc883_medion_wim2160_mixer }, | ||
9894 | .init_verbs = { alc883_init_verbs, alc883_medion_wim2160_verbs }, | ||
9895 | .num_dacs = ARRAY_SIZE(alc883_dac_nids), | ||
9896 | .dac_nids = alc883_dac_nids, | ||
9897 | .dig_out_nid = ALC883_DIGOUT_NID, | ||
9898 | .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), | ||
9899 | .adc_nids = alc883_adc_nids, | ||
9900 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), | ||
9901 | .channel_mode = alc883_3ST_2ch_modes, | ||
9902 | .input_mux = &alc883_capture_source, | ||
9903 | .unsol_event = alc_automute_amp_unsol_event, | ||
9904 | .setup = alc883_medion_wim2160_setup, | ||
9905 | .init_hook = alc_automute_amp, | ||
9906 | }, | ||
9752 | [ALC883_LAPTOP_EAPD] = { | 9907 | [ALC883_LAPTOP_EAPD] = { |
9753 | .mixers = { alc883_base_mixer }, | 9908 | .mixers = { alc883_base_mixer }, |
9754 | .init_verbs = { alc883_init_verbs, alc882_eapd_verbs }, | 9909 | .init_verbs = { alc883_init_verbs, alc882_eapd_verbs }, |
@@ -10041,13 +10196,12 @@ static void alc882_auto_set_output_and_unmute(struct hda_codec *codec, | |||
10041 | int idx; | 10196 | int idx; |
10042 | 10197 | ||
10043 | alc_set_pin_output(codec, nid, pin_type); | 10198 | alc_set_pin_output(codec, nid, pin_type); |
10199 | if (dac_idx >= spec->multiout.num_dacs) | ||
10200 | return; | ||
10044 | if (spec->multiout.dac_nids[dac_idx] == 0x25) | 10201 | if (spec->multiout.dac_nids[dac_idx] == 0x25) |
10045 | idx = 4; | 10202 | idx = 4; |
10046 | else { | 10203 | else |
10047 | if (spec->multiout.num_dacs >= dac_idx) | ||
10048 | return; | ||
10049 | idx = spec->multiout.dac_nids[dac_idx] - 2; | 10204 | idx = spec->multiout.dac_nids[dac_idx] - 2; |
10050 | } | ||
10051 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); | 10205 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); |
10052 | 10206 | ||
10053 | } | 10207 | } |
@@ -10295,7 +10449,8 @@ static int patch_alc882(struct hda_codec *codec) | |||
10295 | board_config = ALC882_AUTO; | 10449 | board_config = ALC882_AUTO; |
10296 | } | 10450 | } |
10297 | 10451 | ||
10298 | alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups); | 10452 | if (board_config == ALC882_AUTO) |
10453 | alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 1); | ||
10299 | 10454 | ||
10300 | if (board_config == ALC882_AUTO) { | 10455 | if (board_config == ALC882_AUTO) { |
10301 | /* automatic parse from the BIOS config */ | 10456 | /* automatic parse from the BIOS config */ |
@@ -10368,6 +10523,9 @@ static int patch_alc882(struct hda_codec *codec) | |||
10368 | set_capture_mixer(codec); | 10523 | set_capture_mixer(codec); |
10369 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 10524 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
10370 | 10525 | ||
10526 | if (board_config == ALC882_AUTO) | ||
10527 | alc_pick_fixup(codec, alc882_fixup_tbl, alc882_fixups, 0); | ||
10528 | |||
10371 | spec->vmaster_nid = 0x0c; | 10529 | spec->vmaster_nid = 0x0c; |
10372 | 10530 | ||
10373 | codec->patch_ops = alc_patch_ops; | 10531 | codec->patch_ops = alc_patch_ops; |
@@ -12459,11 +12617,11 @@ static void alc268_aspire_one_speaker_automute(struct hda_codec *codec) | |||
12459 | unsigned char bits; | 12617 | unsigned char bits; |
12460 | 12618 | ||
12461 | present = snd_hda_jack_detect(codec, 0x15); | 12619 | present = snd_hda_jack_detect(codec, 0x15); |
12462 | bits = present ? AMP_IN_MUTE(0) : 0; | 12620 | bits = present ? HDA_AMP_MUTE : 0; |
12463 | snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0, | 12621 | snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0, |
12464 | AMP_IN_MUTE(0), bits); | 12622 | HDA_AMP_MUTE, bits); |
12465 | snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1, | 12623 | snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1, |
12466 | AMP_IN_MUTE(0), bits); | 12624 | HDA_AMP_MUTE, bits); |
12467 | } | 12625 | } |
12468 | 12626 | ||
12469 | static void alc268_acer_lc_unsol_event(struct hda_codec *codec, | 12627 | static void alc268_acer_lc_unsol_event(struct hda_codec *codec, |
@@ -12748,6 +12906,7 @@ static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid, | |||
12748 | dac = 0x02; | 12906 | dac = 0x02; |
12749 | break; | 12907 | break; |
12750 | case 0x15: | 12908 | case 0x15: |
12909 | case 0x21: /* ALC269vb has this pin, too */ | ||
12751 | dac = 0x03; | 12910 | dac = 0x03; |
12752 | break; | 12911 | break; |
12753 | default: | 12912 | default: |
@@ -13333,9 +13492,9 @@ static hda_nid_t alc269vb_capsrc_nids[1] = { | |||
13333 | 0x22, | 13492 | 0x22, |
13334 | }; | 13493 | }; |
13335 | 13494 | ||
13336 | /* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24), | 13495 | static hda_nid_t alc269_adc_candidates[] = { |
13337 | * not a mux! | 13496 | 0x08, 0x09, 0x07, |
13338 | */ | 13497 | }; |
13339 | 13498 | ||
13340 | #define alc269_modes alc260_modes | 13499 | #define alc269_modes alc260_modes |
13341 | #define alc269_capture_source alc880_lg_lw_capture_source | 13500 | #define alc269_capture_source alc880_lg_lw_capture_source |
@@ -13482,11 +13641,11 @@ static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec) | |||
13482 | unsigned char bits; | 13641 | unsigned char bits; |
13483 | 13642 | ||
13484 | present = snd_hda_jack_detect(codec, 0x15); | 13643 | present = snd_hda_jack_detect(codec, 0x15); |
13485 | bits = present ? AMP_IN_MUTE(0) : 0; | 13644 | bits = present ? HDA_AMP_MUTE : 0; |
13486 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, | 13645 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, |
13487 | AMP_IN_MUTE(0), bits); | 13646 | HDA_AMP_MUTE, bits); |
13488 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, | 13647 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, |
13489 | AMP_IN_MUTE(0), bits); | 13648 | HDA_AMP_MUTE, bits); |
13490 | 13649 | ||
13491 | snd_hda_codec_write(codec, 0x20, 0, | 13650 | snd_hda_codec_write(codec, 0x20, 0, |
13492 | AC_VERB_SET_COEF_INDEX, 0x0c); | 13651 | AC_VERB_SET_COEF_INDEX, 0x0c); |
@@ -13511,11 +13670,11 @@ static void alc269_lifebook_speaker_automute(struct hda_codec *codec) | |||
13511 | /* Check port replicator headphone socket */ | 13670 | /* Check port replicator headphone socket */ |
13512 | present |= snd_hda_jack_detect(codec, 0x1a); | 13671 | present |= snd_hda_jack_detect(codec, 0x1a); |
13513 | 13672 | ||
13514 | bits = present ? AMP_IN_MUTE(0) : 0; | 13673 | bits = present ? HDA_AMP_MUTE : 0; |
13515 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, | 13674 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, |
13516 | AMP_IN_MUTE(0), bits); | 13675 | HDA_AMP_MUTE, bits); |
13517 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, | 13676 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, |
13518 | AMP_IN_MUTE(0), bits); | 13677 | HDA_AMP_MUTE, bits); |
13519 | 13678 | ||
13520 | snd_hda_codec_write(codec, 0x20, 0, | 13679 | snd_hda_codec_write(codec, 0x20, 0, |
13521 | AC_VERB_SET_COEF_INDEX, 0x0c); | 13680 | AC_VERB_SET_COEF_INDEX, 0x0c); |
@@ -13646,11 +13805,11 @@ static void alc269_speaker_automute(struct hda_codec *codec) | |||
13646 | unsigned char bits; | 13805 | unsigned char bits; |
13647 | 13806 | ||
13648 | present = snd_hda_jack_detect(codec, nid); | 13807 | present = snd_hda_jack_detect(codec, nid); |
13649 | bits = present ? AMP_IN_MUTE(0) : 0; | 13808 | bits = present ? HDA_AMP_MUTE : 0; |
13650 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, | 13809 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, |
13651 | AMP_IN_MUTE(0), bits); | 13810 | HDA_AMP_MUTE, bits); |
13652 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, | 13811 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, |
13653 | AMP_IN_MUTE(0), bits); | 13812 | HDA_AMP_MUTE, bits); |
13654 | } | 13813 | } |
13655 | 13814 | ||
13656 | /* unsolicited event for HP jack sensing */ | 13815 | /* unsolicited event for HP jack sensing */ |
@@ -13667,19 +13826,19 @@ static void alc269_laptop_unsol_event(struct hda_codec *codec, | |||
13667 | } | 13826 | } |
13668 | } | 13827 | } |
13669 | 13828 | ||
13670 | static void alc269_laptop_dmic_setup(struct hda_codec *codec) | 13829 | static void alc269_laptop_amic_setup(struct hda_codec *codec) |
13671 | { | 13830 | { |
13672 | struct alc_spec *spec = codec->spec; | 13831 | struct alc_spec *spec = codec->spec; |
13673 | spec->autocfg.hp_pins[0] = 0x15; | 13832 | spec->autocfg.hp_pins[0] = 0x15; |
13674 | spec->autocfg.speaker_pins[0] = 0x14; | 13833 | spec->autocfg.speaker_pins[0] = 0x14; |
13675 | spec->ext_mic.pin = 0x18; | 13834 | spec->ext_mic.pin = 0x18; |
13676 | spec->ext_mic.mux_idx = 0; | 13835 | spec->ext_mic.mux_idx = 0; |
13677 | spec->int_mic.pin = 0x12; | 13836 | spec->int_mic.pin = 0x19; |
13678 | spec->int_mic.mux_idx = 5; | 13837 | spec->int_mic.mux_idx = 1; |
13679 | spec->auto_mic = 1; | 13838 | spec->auto_mic = 1; |
13680 | } | 13839 | } |
13681 | 13840 | ||
13682 | static void alc269vb_laptop_dmic_setup(struct hda_codec *codec) | 13841 | static void alc269_laptop_dmic_setup(struct hda_codec *codec) |
13683 | { | 13842 | { |
13684 | struct alc_spec *spec = codec->spec; | 13843 | struct alc_spec *spec = codec->spec; |
13685 | spec->autocfg.hp_pins[0] = 0x15; | 13844 | spec->autocfg.hp_pins[0] = 0x15; |
@@ -13687,14 +13846,14 @@ static void alc269vb_laptop_dmic_setup(struct hda_codec *codec) | |||
13687 | spec->ext_mic.pin = 0x18; | 13846 | spec->ext_mic.pin = 0x18; |
13688 | spec->ext_mic.mux_idx = 0; | 13847 | spec->ext_mic.mux_idx = 0; |
13689 | spec->int_mic.pin = 0x12; | 13848 | spec->int_mic.pin = 0x12; |
13690 | spec->int_mic.mux_idx = 6; | 13849 | spec->int_mic.mux_idx = 5; |
13691 | spec->auto_mic = 1; | 13850 | spec->auto_mic = 1; |
13692 | } | 13851 | } |
13693 | 13852 | ||
13694 | static void alc269_laptop_amic_setup(struct hda_codec *codec) | 13853 | static void alc269vb_laptop_amic_setup(struct hda_codec *codec) |
13695 | { | 13854 | { |
13696 | struct alc_spec *spec = codec->spec; | 13855 | struct alc_spec *spec = codec->spec; |
13697 | spec->autocfg.hp_pins[0] = 0x15; | 13856 | spec->autocfg.hp_pins[0] = 0x21; |
13698 | spec->autocfg.speaker_pins[0] = 0x14; | 13857 | spec->autocfg.speaker_pins[0] = 0x14; |
13699 | spec->ext_mic.pin = 0x18; | 13858 | spec->ext_mic.pin = 0x18; |
13700 | spec->ext_mic.mux_idx = 0; | 13859 | spec->ext_mic.mux_idx = 0; |
@@ -13703,6 +13862,18 @@ static void alc269_laptop_amic_setup(struct hda_codec *codec) | |||
13703 | spec->auto_mic = 1; | 13862 | spec->auto_mic = 1; |
13704 | } | 13863 | } |
13705 | 13864 | ||
13865 | static void alc269vb_laptop_dmic_setup(struct hda_codec *codec) | ||
13866 | { | ||
13867 | struct alc_spec *spec = codec->spec; | ||
13868 | spec->autocfg.hp_pins[0] = 0x21; | ||
13869 | spec->autocfg.speaker_pins[0] = 0x14; | ||
13870 | spec->ext_mic.pin = 0x18; | ||
13871 | spec->ext_mic.mux_idx = 0; | ||
13872 | spec->int_mic.pin = 0x12; | ||
13873 | spec->int_mic.mux_idx = 6; | ||
13874 | spec->auto_mic = 1; | ||
13875 | } | ||
13876 | |||
13706 | static void alc269_laptop_inithook(struct hda_codec *codec) | 13877 | static void alc269_laptop_inithook(struct hda_codec *codec) |
13707 | { | 13878 | { |
13708 | alc269_speaker_automute(codec); | 13879 | alc269_speaker_automute(codec); |
@@ -13842,7 +14013,6 @@ static int alc269_parse_auto_config(struct hda_codec *codec) | |||
13842 | struct alc_spec *spec = codec->spec; | 14013 | struct alc_spec *spec = codec->spec; |
13843 | int err; | 14014 | int err; |
13844 | static hda_nid_t alc269_ignore[] = { 0x1d, 0 }; | 14015 | static hda_nid_t alc269_ignore[] = { 0x1d, 0 }; |
13845 | hda_nid_t real_capsrc_nids; | ||
13846 | 14016 | ||
13847 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | 14017 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, |
13848 | alc269_ignore); | 14018 | alc269_ignore); |
@@ -13866,18 +14036,19 @@ static int alc269_parse_auto_config(struct hda_codec *codec) | |||
13866 | 14036 | ||
13867 | if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010) { | 14037 | if ((alc_read_coef_idx(codec, 0) & 0x00f0) == 0x0010) { |
13868 | add_verb(spec, alc269vb_init_verbs); | 14038 | add_verb(spec, alc269vb_init_verbs); |
13869 | real_capsrc_nids = alc269vb_capsrc_nids[0]; | ||
13870 | alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21); | 14039 | alc_ssid_check(codec, 0, 0x1b, 0x14, 0x21); |
13871 | } else { | 14040 | } else { |
13872 | add_verb(spec, alc269_init_verbs); | 14041 | add_verb(spec, alc269_init_verbs); |
13873 | real_capsrc_nids = alc269_capsrc_nids[0]; | ||
13874 | alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); | 14042 | alc_ssid_check(codec, 0x15, 0x1b, 0x14, 0); |
13875 | } | 14043 | } |
13876 | 14044 | ||
13877 | spec->num_mux_defs = 1; | 14045 | spec->num_mux_defs = 1; |
13878 | spec->input_mux = &spec->private_imux[0]; | 14046 | spec->input_mux = &spec->private_imux[0]; |
14047 | fillup_priv_adc_nids(codec, alc269_adc_candidates, | ||
14048 | sizeof(alc269_adc_candidates)); | ||
14049 | |||
13879 | /* set default input source */ | 14050 | /* set default input source */ |
13880 | snd_hda_codec_write_cache(codec, real_capsrc_nids, | 14051 | snd_hda_codec_write_cache(codec, spec->capsrc_nids[0], |
13881 | 0, AC_VERB_SET_CONNECT_SEL, | 14052 | 0, AC_VERB_SET_CONNECT_SEL, |
13882 | spec->input_mux->items[0].index); | 14053 | spec->input_mux->items[0].index); |
13883 | 14054 | ||
@@ -13907,6 +14078,27 @@ static void alc269_auto_init(struct hda_codec *codec) | |||
13907 | alc_inithook(codec); | 14078 | alc_inithook(codec); |
13908 | } | 14079 | } |
13909 | 14080 | ||
14081 | enum { | ||
14082 | ALC269_FIXUP_SONY_VAIO, | ||
14083 | }; | ||
14084 | |||
14085 | const static struct hda_verb alc269_sony_vaio_fixup_verbs[] = { | ||
14086 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREFGRD}, | ||
14087 | {} | ||
14088 | }; | ||
14089 | |||
14090 | static const struct alc_fixup alc269_fixups[] = { | ||
14091 | [ALC269_FIXUP_SONY_VAIO] = { | ||
14092 | .verbs = alc269_sony_vaio_fixup_verbs | ||
14093 | }, | ||
14094 | }; | ||
14095 | |||
14096 | static struct snd_pci_quirk alc269_fixup_tbl[] = { | ||
14097 | SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), | ||
14098 | {} | ||
14099 | }; | ||
14100 | |||
14101 | |||
13910 | /* | 14102 | /* |
13911 | * configuration and preset | 14103 | * configuration and preset |
13912 | */ | 14104 | */ |
@@ -13966,7 +14158,7 @@ static struct snd_pci_quirk alc269_cfg_tbl[] = { | |||
13966 | ALC269_DMIC), | 14158 | ALC269_DMIC), |
13967 | SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC), | 14159 | SND_PCI_QUIRK(0x1043, 0x8398, "ASUS P1005HA", ALC269_DMIC), |
13968 | SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC), | 14160 | SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS P1005HA", ALC269_DMIC), |
13969 | SND_PCI_QUIRK(0x104d, 0x9071, "SONY XTB", ALC269_DMIC), | 14161 | SND_PCI_QUIRK(0x104d, 0x9071, "Sony VAIO", ALC269_AUTO), |
13970 | SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK), | 14162 | SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook ICH9M-based", ALC269_LIFEBOOK), |
13971 | SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC), | 14163 | SND_PCI_QUIRK(0x152d, 0x1778, "Quanta ON1", ALC269_DMIC), |
13972 | SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU), | 14164 | SND_PCI_QUIRK(0x1734, 0x115d, "FSC Amilo", ALC269_FUJITSU), |
@@ -14040,7 +14232,7 @@ static struct alc_config_preset alc269_presets[] = { | |||
14040 | .num_channel_mode = ARRAY_SIZE(alc269_modes), | 14232 | .num_channel_mode = ARRAY_SIZE(alc269_modes), |
14041 | .channel_mode = alc269_modes, | 14233 | .channel_mode = alc269_modes, |
14042 | .unsol_event = alc269_laptop_unsol_event, | 14234 | .unsol_event = alc269_laptop_unsol_event, |
14043 | .setup = alc269_laptop_amic_setup, | 14235 | .setup = alc269vb_laptop_amic_setup, |
14044 | .init_hook = alc269_laptop_inithook, | 14236 | .init_hook = alc269_laptop_inithook, |
14045 | }, | 14237 | }, |
14046 | [ALC269VB_DMIC] = { | 14238 | [ALC269VB_DMIC] = { |
@@ -14120,6 +14312,9 @@ static int patch_alc269(struct hda_codec *codec) | |||
14120 | board_config = ALC269_AUTO; | 14312 | board_config = ALC269_AUTO; |
14121 | } | 14313 | } |
14122 | 14314 | ||
14315 | if (board_config == ALC269_AUTO) | ||
14316 | alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 1); | ||
14317 | |||
14123 | if (board_config == ALC269_AUTO) { | 14318 | if (board_config == ALC269_AUTO) { |
14124 | /* automatic parse from the BIOS config */ | 14319 | /* automatic parse from the BIOS config */ |
14125 | err = alc269_parse_auto_config(codec); | 14320 | err = alc269_parse_auto_config(codec); |
@@ -14156,20 +14351,25 @@ static int patch_alc269(struct hda_codec *codec) | |||
14156 | spec->stream_digital_playback = &alc269_pcm_digital_playback; | 14351 | spec->stream_digital_playback = &alc269_pcm_digital_playback; |
14157 | spec->stream_digital_capture = &alc269_pcm_digital_capture; | 14352 | spec->stream_digital_capture = &alc269_pcm_digital_capture; |
14158 | 14353 | ||
14159 | if (!is_alc269vb) { | 14354 | if (!spec->adc_nids) { /* wasn't filled automatically? use default */ |
14160 | spec->adc_nids = alc269_adc_nids; | 14355 | if (!is_alc269vb) { |
14161 | spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids); | 14356 | spec->adc_nids = alc269_adc_nids; |
14162 | spec->capsrc_nids = alc269_capsrc_nids; | 14357 | spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids); |
14163 | } else { | 14358 | spec->capsrc_nids = alc269_capsrc_nids; |
14164 | spec->adc_nids = alc269vb_adc_nids; | 14359 | } else { |
14165 | spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids); | 14360 | spec->adc_nids = alc269vb_adc_nids; |
14166 | spec->capsrc_nids = alc269vb_capsrc_nids; | 14361 | spec->num_adc_nids = ARRAY_SIZE(alc269vb_adc_nids); |
14362 | spec->capsrc_nids = alc269vb_capsrc_nids; | ||
14363 | } | ||
14167 | } | 14364 | } |
14168 | 14365 | ||
14169 | if (!spec->cap_mixer) | 14366 | if (!spec->cap_mixer) |
14170 | set_capture_mixer(codec); | 14367 | set_capture_mixer(codec); |
14171 | set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); | 14368 | set_beep_amp(spec, 0x0b, 0x04, HDA_INPUT); |
14172 | 14369 | ||
14370 | if (board_config == ALC269_AUTO) | ||
14371 | alc_pick_fixup(codec, alc269_fixup_tbl, alc269_fixups, 0); | ||
14372 | |||
14173 | spec->vmaster_nid = 0x02; | 14373 | spec->vmaster_nid = 0x02; |
14174 | 14374 | ||
14175 | codec->patch_ops = alc_patch_ops; | 14375 | codec->patch_ops = alc_patch_ops; |
@@ -15258,7 +15458,8 @@ static int patch_alc861(struct hda_codec *codec) | |||
15258 | board_config = ALC861_AUTO; | 15458 | board_config = ALC861_AUTO; |
15259 | } | 15459 | } |
15260 | 15460 | ||
15261 | alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups); | 15461 | if (board_config == ALC861_AUTO) |
15462 | alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 1); | ||
15262 | 15463 | ||
15263 | if (board_config == ALC861_AUTO) { | 15464 | if (board_config == ALC861_AUTO) { |
15264 | /* automatic parse from the BIOS config */ | 15465 | /* automatic parse from the BIOS config */ |
@@ -15295,6 +15496,9 @@ static int patch_alc861(struct hda_codec *codec) | |||
15295 | 15496 | ||
15296 | spec->vmaster_nid = 0x03; | 15497 | spec->vmaster_nid = 0x03; |
15297 | 15498 | ||
15499 | if (board_config == ALC861_AUTO) | ||
15500 | alc_pick_fixup(codec, alc861_fixup_tbl, alc861_fixups, 0); | ||
15501 | |||
15298 | codec->patch_ops = alc_patch_ops; | 15502 | codec->patch_ops = alc_patch_ops; |
15299 | if (board_config == ALC861_AUTO) { | 15503 | if (board_config == ALC861_AUTO) { |
15300 | spec->init_hook = alc861_auto_init; | 15504 | spec->init_hook = alc861_auto_init; |
@@ -16229,7 +16433,8 @@ static int patch_alc861vd(struct hda_codec *codec) | |||
16229 | board_config = ALC861VD_AUTO; | 16433 | board_config = ALC861VD_AUTO; |
16230 | } | 16434 | } |
16231 | 16435 | ||
16232 | alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups); | 16436 | if (board_config == ALC861VD_AUTO) |
16437 | alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 1); | ||
16233 | 16438 | ||
16234 | if (board_config == ALC861VD_AUTO) { | 16439 | if (board_config == ALC861VD_AUTO) { |
16235 | /* automatic parse from the BIOS config */ | 16440 | /* automatic parse from the BIOS config */ |
@@ -16277,6 +16482,9 @@ static int patch_alc861vd(struct hda_codec *codec) | |||
16277 | 16482 | ||
16278 | spec->vmaster_nid = 0x02; | 16483 | spec->vmaster_nid = 0x02; |
16279 | 16484 | ||
16485 | if (board_config == ALC861VD_AUTO) | ||
16486 | alc_pick_fixup(codec, alc861vd_fixup_tbl, alc861vd_fixups, 0); | ||
16487 | |||
16280 | codec->patch_ops = alc_patch_ops; | 16488 | codec->patch_ops = alc_patch_ops; |
16281 | 16489 | ||
16282 | if (board_config == ALC861VD_AUTO) | 16490 | if (board_config == ALC861VD_AUTO) |
@@ -17115,9 +17323,9 @@ static void alc663_m51va_speaker_automute(struct hda_codec *codec) | |||
17115 | present = snd_hda_jack_detect(codec, 0x21); | 17323 | present = snd_hda_jack_detect(codec, 0x21); |
17116 | bits = present ? HDA_AMP_MUTE : 0; | 17324 | bits = present ? HDA_AMP_MUTE : 0; |
17117 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, | 17325 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, |
17118 | AMP_IN_MUTE(0), bits); | 17326 | HDA_AMP_MUTE, bits); |
17119 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, | 17327 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, |
17120 | AMP_IN_MUTE(0), bits); | 17328 | HDA_AMP_MUTE, bits); |
17121 | } | 17329 | } |
17122 | 17330 | ||
17123 | static void alc663_21jd_two_speaker_automute(struct hda_codec *codec) | 17331 | static void alc663_21jd_two_speaker_automute(struct hda_codec *codec) |
@@ -17128,13 +17336,13 @@ static void alc663_21jd_two_speaker_automute(struct hda_codec *codec) | |||
17128 | present = snd_hda_jack_detect(codec, 0x21); | 17336 | present = snd_hda_jack_detect(codec, 0x21); |
17129 | bits = present ? HDA_AMP_MUTE : 0; | 17337 | bits = present ? HDA_AMP_MUTE : 0; |
17130 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, | 17338 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, |
17131 | AMP_IN_MUTE(0), bits); | 17339 | HDA_AMP_MUTE, bits); |
17132 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, | 17340 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, |
17133 | AMP_IN_MUTE(0), bits); | 17341 | HDA_AMP_MUTE, bits); |
17134 | snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0, | 17342 | snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0, |
17135 | AMP_IN_MUTE(0), bits); | 17343 | HDA_AMP_MUTE, bits); |
17136 | snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1, | 17344 | snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1, |
17137 | AMP_IN_MUTE(0), bits); | 17345 | HDA_AMP_MUTE, bits); |
17138 | } | 17346 | } |
17139 | 17347 | ||
17140 | static void alc663_15jd_two_speaker_automute(struct hda_codec *codec) | 17348 | static void alc663_15jd_two_speaker_automute(struct hda_codec *codec) |
@@ -17145,13 +17353,13 @@ static void alc663_15jd_two_speaker_automute(struct hda_codec *codec) | |||
17145 | present = snd_hda_jack_detect(codec, 0x15); | 17353 | present = snd_hda_jack_detect(codec, 0x15); |
17146 | bits = present ? HDA_AMP_MUTE : 0; | 17354 | bits = present ? HDA_AMP_MUTE : 0; |
17147 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, | 17355 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, |
17148 | AMP_IN_MUTE(0), bits); | 17356 | HDA_AMP_MUTE, bits); |
17149 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, | 17357 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, |
17150 | AMP_IN_MUTE(0), bits); | 17358 | HDA_AMP_MUTE, bits); |
17151 | snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0, | 17359 | snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0, |
17152 | AMP_IN_MUTE(0), bits); | 17360 | HDA_AMP_MUTE, bits); |
17153 | snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1, | 17361 | snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1, |
17154 | AMP_IN_MUTE(0), bits); | 17362 | HDA_AMP_MUTE, bits); |
17155 | } | 17363 | } |
17156 | 17364 | ||
17157 | static void alc662_f5z_speaker_automute(struct hda_codec *codec) | 17365 | static void alc662_f5z_speaker_automute(struct hda_codec *codec) |
@@ -17190,14 +17398,14 @@ static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec) | |||
17190 | 17398 | ||
17191 | if (present1 || present2) { | 17399 | if (present1 || present2) { |
17192 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, | 17400 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, |
17193 | AMP_IN_MUTE(0), AMP_IN_MUTE(0)); | 17401 | HDA_AMP_MUTE, HDA_AMP_MUTE); |
17194 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, | 17402 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, |
17195 | AMP_IN_MUTE(0), AMP_IN_MUTE(0)); | 17403 | HDA_AMP_MUTE, HDA_AMP_MUTE); |
17196 | } else { | 17404 | } else { |
17197 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, | 17405 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, |
17198 | AMP_IN_MUTE(0), 0); | 17406 | HDA_AMP_MUTE, 0); |
17199 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, | 17407 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, |
17200 | AMP_IN_MUTE(0), 0); | 17408 | HDA_AMP_MUTE, 0); |
17201 | } | 17409 | } |
17202 | } | 17410 | } |
17203 | 17411 | ||
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index c4be3fab94e5..7fb7d017a347 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -1607,6 +1607,10 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = { | |||
1607 | "Dell Studio 1555", STAC_DELL_M6_DMIC), | 1607 | "Dell Studio 1555", STAC_DELL_M6_DMIC), |
1608 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02bd, | 1608 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02bd, |
1609 | "Dell Studio 1557", STAC_DELL_M6_DMIC), | 1609 | "Dell Studio 1557", STAC_DELL_M6_DMIC), |
1610 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02fe, | ||
1611 | "Dell Studio XPS 1645", STAC_DELL_M6_BOTH), | ||
1612 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0413, | ||
1613 | "Dell Studio 1558", STAC_DELL_M6_BOTH), | ||
1610 | {} /* terminator */ | 1614 | {} /* terminator */ |
1611 | }; | 1615 | }; |
1612 | 1616 | ||
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 9ddc37300f6b..73453814e098 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c | |||
@@ -476,7 +476,7 @@ static struct snd_kcontrol_new *via_clone_control(struct via_spec *spec, | |||
476 | knew->name = kstrdup(tmpl->name, GFP_KERNEL); | 476 | knew->name = kstrdup(tmpl->name, GFP_KERNEL); |
477 | if (!knew->name) | 477 | if (!knew->name) |
478 | return NULL; | 478 | return NULL; |
479 | return 0; | 479 | return knew; |
480 | } | 480 | } |
481 | 481 | ||
482 | static void via_free_kctls(struct hda_codec *codec) | 482 | static void via_free_kctls(struct hda_codec *codec) |
@@ -1215,14 +1215,13 @@ static struct snd_kcontrol_new via_hp_mixer[2] = { | |||
1215 | }, | 1215 | }, |
1216 | }; | 1216 | }; |
1217 | 1217 | ||
1218 | static int via_hp_build(struct via_spec *spec) | 1218 | static int via_hp_build(struct hda_codec *codec) |
1219 | { | 1219 | { |
1220 | struct via_spec *spec = codec->spec; | ||
1220 | struct snd_kcontrol_new *knew; | 1221 | struct snd_kcontrol_new *knew; |
1221 | hda_nid_t nid; | 1222 | hda_nid_t nid; |
1222 | 1223 | int nums; | |
1223 | knew = via_clone_control(spec, &via_hp_mixer[0]); | 1224 | hda_nid_t conn[HDA_MAX_CONNECTIONS]; |
1224 | if (knew == NULL) | ||
1225 | return -ENOMEM; | ||
1226 | 1225 | ||
1227 | switch (spec->codec_type) { | 1226 | switch (spec->codec_type) { |
1228 | case VT1718S: | 1227 | case VT1718S: |
@@ -1239,6 +1238,14 @@ static int via_hp_build(struct via_spec *spec) | |||
1239 | break; | 1238 | break; |
1240 | } | 1239 | } |
1241 | 1240 | ||
1241 | nums = snd_hda_get_connections(codec, nid, conn, HDA_MAX_CONNECTIONS); | ||
1242 | if (nums <= 1) | ||
1243 | return 0; | ||
1244 | |||
1245 | knew = via_clone_control(spec, &via_hp_mixer[0]); | ||
1246 | if (knew == NULL) | ||
1247 | return -ENOMEM; | ||
1248 | |||
1242 | knew->subdevice = HDA_SUBDEV_NID_FLAG | nid; | 1249 | knew->subdevice = HDA_SUBDEV_NID_FLAG | nid; |
1243 | knew->private_value = nid; | 1250 | knew->private_value = nid; |
1244 | 1251 | ||
@@ -2561,7 +2568,7 @@ static int vt1708_parse_auto_config(struct hda_codec *codec) | |||
2561 | spec->input_mux = &spec->private_imux[0]; | 2568 | spec->input_mux = &spec->private_imux[0]; |
2562 | 2569 | ||
2563 | if (spec->hp_mux) | 2570 | if (spec->hp_mux) |
2564 | via_hp_build(spec); | 2571 | via_hp_build(codec); |
2565 | 2572 | ||
2566 | via_smart51_build(spec); | 2573 | via_smart51_build(spec); |
2567 | return 1; | 2574 | return 1; |
@@ -3087,7 +3094,7 @@ static int vt1709_parse_auto_config(struct hda_codec *codec) | |||
3087 | spec->input_mux = &spec->private_imux[0]; | 3094 | spec->input_mux = &spec->private_imux[0]; |
3088 | 3095 | ||
3089 | if (spec->hp_mux) | 3096 | if (spec->hp_mux) |
3090 | via_hp_build(spec); | 3097 | via_hp_build(codec); |
3091 | 3098 | ||
3092 | via_smart51_build(spec); | 3099 | via_smart51_build(spec); |
3093 | return 1; | 3100 | return 1; |
@@ -3654,7 +3661,7 @@ static int vt1708B_parse_auto_config(struct hda_codec *codec) | |||
3654 | spec->input_mux = &spec->private_imux[0]; | 3661 | spec->input_mux = &spec->private_imux[0]; |
3655 | 3662 | ||
3656 | if (spec->hp_mux) | 3663 | if (spec->hp_mux) |
3657 | via_hp_build(spec); | 3664 | via_hp_build(codec); |
3658 | 3665 | ||
3659 | via_smart51_build(spec); | 3666 | via_smart51_build(spec); |
3660 | return 1; | 3667 | return 1; |
@@ -4140,7 +4147,7 @@ static int vt1708S_parse_auto_config(struct hda_codec *codec) | |||
4140 | spec->input_mux = &spec->private_imux[0]; | 4147 | spec->input_mux = &spec->private_imux[0]; |
4141 | 4148 | ||
4142 | if (spec->hp_mux) | 4149 | if (spec->hp_mux) |
4143 | via_hp_build(spec); | 4150 | via_hp_build(codec); |
4144 | 4151 | ||
4145 | via_smart51_build(spec); | 4152 | via_smart51_build(spec); |
4146 | return 1; | 4153 | return 1; |
@@ -4510,7 +4517,7 @@ static int vt1702_parse_auto_config(struct hda_codec *codec) | |||
4510 | spec->input_mux = &spec->private_imux[0]; | 4517 | spec->input_mux = &spec->private_imux[0]; |
4511 | 4518 | ||
4512 | if (spec->hp_mux) | 4519 | if (spec->hp_mux) |
4513 | via_hp_build(spec); | 4520 | via_hp_build(codec); |
4514 | 4521 | ||
4515 | return 1; | 4522 | return 1; |
4516 | } | 4523 | } |
@@ -4930,7 +4937,7 @@ static int vt1718S_parse_auto_config(struct hda_codec *codec) | |||
4930 | spec->input_mux = &spec->private_imux[0]; | 4937 | spec->input_mux = &spec->private_imux[0]; |
4931 | 4938 | ||
4932 | if (spec->hp_mux) | 4939 | if (spec->hp_mux) |
4933 | via_hp_build(spec); | 4940 | via_hp_build(codec); |
4934 | 4941 | ||
4935 | via_smart51_build(spec); | 4942 | via_smart51_build(spec); |
4936 | 4943 | ||
@@ -5425,7 +5432,7 @@ static int vt1716S_parse_auto_config(struct hda_codec *codec) | |||
5425 | spec->input_mux = &spec->private_imux[0]; | 5432 | spec->input_mux = &spec->private_imux[0]; |
5426 | 5433 | ||
5427 | if (spec->hp_mux) | 5434 | if (spec->hp_mux) |
5428 | via_hp_build(spec); | 5435 | via_hp_build(codec); |
5429 | 5436 | ||
5430 | via_smart51_build(spec); | 5437 | via_smart51_build(spec); |
5431 | 5438 | ||
@@ -5781,7 +5788,7 @@ static int vt2002P_parse_auto_config(struct hda_codec *codec) | |||
5781 | spec->input_mux = &spec->private_imux[0]; | 5788 | spec->input_mux = &spec->private_imux[0]; |
5782 | 5789 | ||
5783 | if (spec->hp_mux) | 5790 | if (spec->hp_mux) |
5784 | via_hp_build(spec); | 5791 | via_hp_build(codec); |
5785 | 5792 | ||
5786 | return 1; | 5793 | return 1; |
5787 | } | 5794 | } |
@@ -6000,12 +6007,12 @@ static int vt1812_auto_create_multi_out_ctls(struct via_spec *spec, | |||
6000 | 6007 | ||
6001 | /* Line-Out: PortE */ | 6008 | /* Line-Out: PortE */ |
6002 | err = via_add_control(spec, VIA_CTL_WIDGET_VOL, | 6009 | err = via_add_control(spec, VIA_CTL_WIDGET_VOL, |
6003 | "Master Front Playback Volume", | 6010 | "Front Playback Volume", |
6004 | HDA_COMPOSE_AMP_VAL(0x8, 3, 0, HDA_OUTPUT)); | 6011 | HDA_COMPOSE_AMP_VAL(0x8, 3, 0, HDA_OUTPUT)); |
6005 | if (err < 0) | 6012 | if (err < 0) |
6006 | return err; | 6013 | return err; |
6007 | err = via_add_control(spec, VIA_CTL_WIDGET_BIND_PIN_MUTE, | 6014 | err = via_add_control(spec, VIA_CTL_WIDGET_BIND_PIN_MUTE, |
6008 | "Master Front Playback Switch", | 6015 | "Front Playback Switch", |
6009 | HDA_COMPOSE_AMP_VAL(0x28, 3, 0, HDA_OUTPUT)); | 6016 | HDA_COMPOSE_AMP_VAL(0x28, 3, 0, HDA_OUTPUT)); |
6010 | if (err < 0) | 6017 | if (err < 0) |
6011 | return err; | 6018 | return err; |
@@ -6130,7 +6137,7 @@ static int vt1812_parse_auto_config(struct hda_codec *codec) | |||
6130 | spec->input_mux = &spec->private_imux[0]; | 6137 | spec->input_mux = &spec->private_imux[0]; |
6131 | 6138 | ||
6132 | if (spec->hp_mux) | 6139 | if (spec->hp_mux) |
6133 | via_hp_build(spec); | 6140 | via_hp_build(codec); |
6134 | 6141 | ||
6135 | return 1; | 6142 | return 1; |
6136 | } | 6143 | } |
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c index b64e78139d63..b56e33676780 100644 --- a/sound/pci/maestro3.c +++ b/sound/pci/maestro3.c | |||
@@ -849,6 +849,7 @@ struct snd_m3 { | |||
849 | struct snd_kcontrol *master_switch; | 849 | struct snd_kcontrol *master_switch; |
850 | struct snd_kcontrol *master_volume; | 850 | struct snd_kcontrol *master_volume; |
851 | struct tasklet_struct hwvol_tq; | 851 | struct tasklet_struct hwvol_tq; |
852 | unsigned int in_suspend; | ||
852 | 853 | ||
853 | #ifdef CONFIG_PM | 854 | #ifdef CONFIG_PM |
854 | u16 *suspend_mem; | 855 | u16 *suspend_mem; |
@@ -884,6 +885,7 @@ static DEFINE_PCI_DEVICE_TABLE(snd_m3_ids) = { | |||
884 | MODULE_DEVICE_TABLE(pci, snd_m3_ids); | 885 | MODULE_DEVICE_TABLE(pci, snd_m3_ids); |
885 | 886 | ||
886 | static struct snd_pci_quirk m3_amp_quirk_list[] __devinitdata = { | 887 | static struct snd_pci_quirk m3_amp_quirk_list[] __devinitdata = { |
888 | SND_PCI_QUIRK(0x0E11, 0x0094, "Compaq Evo N600c", 0x0c), | ||
887 | SND_PCI_QUIRK(0x10f7, 0x833e, "Panasonic CF-28", 0x0d), | 889 | SND_PCI_QUIRK(0x10f7, 0x833e, "Panasonic CF-28", 0x0d), |
888 | SND_PCI_QUIRK(0x10f7, 0x833d, "Panasonic CF-72", 0x0d), | 890 | SND_PCI_QUIRK(0x10f7, 0x833d, "Panasonic CF-72", 0x0d), |
889 | SND_PCI_QUIRK(0x1033, 0x80f1, "NEC LM800J/7", 0x03), | 891 | SND_PCI_QUIRK(0x1033, 0x80f1, "NEC LM800J/7", 0x03), |
@@ -1613,6 +1615,11 @@ static void snd_m3_update_hw_volume(unsigned long private_data) | |||
1613 | outb(0x88, chip->iobase + SHADOW_MIX_REG_MASTER); | 1615 | outb(0x88, chip->iobase + SHADOW_MIX_REG_MASTER); |
1614 | outb(0x88, chip->iobase + HW_VOL_COUNTER_MASTER); | 1616 | outb(0x88, chip->iobase + HW_VOL_COUNTER_MASTER); |
1615 | 1617 | ||
1618 | /* Ignore spurious HV interrupts during suspend / resume, this avoids | ||
1619 | mistaking them for a mute button press. */ | ||
1620 | if (chip->in_suspend) | ||
1621 | return; | ||
1622 | |||
1616 | if (!chip->master_switch || !chip->master_volume) | 1623 | if (!chip->master_switch || !chip->master_volume) |
1617 | return; | 1624 | return; |
1618 | 1625 | ||
@@ -2424,6 +2431,7 @@ static int m3_suspend(struct pci_dev *pci, pm_message_t state) | |||
2424 | if (chip->suspend_mem == NULL) | 2431 | if (chip->suspend_mem == NULL) |
2425 | return 0; | 2432 | return 0; |
2426 | 2433 | ||
2434 | chip->in_suspend = 1; | ||
2427 | snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); | 2435 | snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); |
2428 | snd_pcm_suspend_all(chip->pcm); | 2436 | snd_pcm_suspend_all(chip->pcm); |
2429 | snd_ac97_suspend(chip->ac97); | 2437 | snd_ac97_suspend(chip->ac97); |
@@ -2497,6 +2505,7 @@ static int m3_resume(struct pci_dev *pci) | |||
2497 | snd_m3_hv_init(chip); | 2505 | snd_m3_hv_init(chip); |
2498 | 2506 | ||
2499 | snd_power_change_state(card, SNDRV_CTL_POWER_D0); | 2507 | snd_power_change_state(card, SNDRV_CTL_POWER_D0); |
2508 | chip->in_suspend = 0; | ||
2500 | return 0; | 2509 | return 0; |
2501 | } | 2510 | } |
2502 | #endif /* CONFIG_PM */ | 2511 | #endif /* CONFIG_PM */ |
diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c index 55e9315d4ccd..3be8f97c8bc0 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 9ef6b96373f5..3e6628c8e665 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 e588e63f18d2..0b59806905d1 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 fd101d450d56..1f5e57a4bb7a 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/wm2000.c b/sound/soc/codecs/wm2000.c index a34cbcf7904f..002e289d1255 100644 --- a/sound/soc/codecs/wm2000.c +++ b/sound/soc/codecs/wm2000.c | |||
@@ -23,7 +23,6 @@ | |||
23 | 23 | ||
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <linux/moduleparam.h> | 25 | #include <linux/moduleparam.h> |
26 | #include <linux/version.h> | ||
27 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
28 | #include <linux/init.h> | 27 | #include <linux/init.h> |
29 | #include <linux/firmware.h> | 28 | #include <linux/firmware.h> |
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 8d1c63754be4..9da0724cd47a 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 486bdd21a98a..e1f225a3ac46 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 420104fe9c90..e51c16683589 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 62af7e025e7f..adadcd3aa1b1 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 6c80cc35ecad..79f0f4ad242c 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 80c7fdf2f521..2dc406f42fe7 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 86668ab3f4d4..2b31ac673ea4 100644 --- a/sound/soc/imx/imx-pcm-dma-mx2.c +++ b/sound/soc/imx/imx-pcm-dma-mx2.c | |||
@@ -71,7 +71,12 @@ static void imx_ssi_dma_callback(int channel, void *data) | |||
71 | 71 | ||
72 | static void snd_imx_dma_err_callback(int channel, void *data, int err) | 72 | static void snd_imx_dma_err_callback(int channel, void *data, int err) |
73 | { | 73 | { |
74 | pr_err("DMA error callback called\n"); | 74 | struct snd_pcm_substream *substream = data; |
75 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
76 | struct imx_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data; | ||
77 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
78 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; | ||
79 | int ret; | ||
75 | 80 | ||
76 | pr_err("DMA timeout on channel %d -%s%s%s%s\n", | 81 | pr_err("DMA timeout on channel %d -%s%s%s%s\n", |
77 | channel, | 82 | channel, |
@@ -79,16 +84,26 @@ static void snd_imx_dma_err_callback(int channel, void *data, int err) | |||
79 | err & IMX_DMA_ERR_REQUEST ? " request" : "", | 84 | err & IMX_DMA_ERR_REQUEST ? " request" : "", |
80 | err & IMX_DMA_ERR_TRANSFER ? " transfer" : "", | 85 | err & IMX_DMA_ERR_TRANSFER ? " transfer" : "", |
81 | err & IMX_DMA_ERR_BUFFER ? " buffer" : ""); | 86 | err & IMX_DMA_ERR_BUFFER ? " buffer" : ""); |
87 | |||
88 | imx_dma_disable(iprtd->dma); | ||
89 | ret = imx_dma_setup_sg(iprtd->dma, iprtd->sg_list, iprtd->sg_count, | ||
90 | IMX_DMA_LENGTH_LOOP, dma_params->dma_addr, | ||
91 | substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? | ||
92 | DMA_MODE_WRITE : DMA_MODE_READ); | ||
93 | if (!ret) | ||
94 | imx_dma_enable(iprtd->dma); | ||
82 | } | 95 | } |
83 | 96 | ||
84 | static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream) | 97 | static int imx_ssi_dma_alloc(struct snd_pcm_substream *substream) |
85 | { | 98 | { |
86 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 99 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
87 | struct imx_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data; | 100 | struct imx_pcm_dma_params *dma_params; |
88 | struct snd_pcm_runtime *runtime = substream->runtime; | 101 | struct snd_pcm_runtime *runtime = substream->runtime; |
89 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; | 102 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; |
90 | int ret; | 103 | int ret; |
91 | 104 | ||
105 | dma_params = snd_soc_get_dma_data(rtd->dai->cpu_dai, substream); | ||
106 | |||
92 | iprtd->dma = imx_dma_request_by_prio(DRV_NAME, DMA_PRIO_HIGH); | 107 | iprtd->dma = imx_dma_request_by_prio(DRV_NAME, DMA_PRIO_HIGH); |
93 | if (iprtd->dma < 0) { | 108 | if (iprtd->dma < 0) { |
94 | pr_err("Failed to claim the audio DMA\n"); | 109 | pr_err("Failed to claim the audio DMA\n"); |
@@ -193,10 +208,12 @@ static int snd_imx_pcm_prepare(struct snd_pcm_substream *substream) | |||
193 | { | 208 | { |
194 | struct snd_pcm_runtime *runtime = substream->runtime; | 209 | struct snd_pcm_runtime *runtime = substream->runtime; |
195 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | 210 | struct snd_soc_pcm_runtime *rtd = substream->private_data; |
196 | struct imx_pcm_dma_params *dma_params = rtd->dai->cpu_dai->dma_data; | 211 | struct imx_pcm_dma_params *dma_params; |
197 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; | 212 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; |
198 | int err; | 213 | int err; |
199 | 214 | ||
215 | dma_params = snd_soc_get_dma_data(rtd->dai->cpu_dai, substream); | ||
216 | |||
200 | iprtd->substream = substream; | 217 | iprtd->substream = substream; |
201 | iprtd->buf = (unsigned int *)substream->dma_buffer.area; | 218 | iprtd->buf = (unsigned int *)substream->dma_buffer.area; |
202 | iprtd->period_cnt = 0; | 219 | iprtd->period_cnt = 0; |
diff --git a/sound/soc/imx/imx-pcm-fiq.c b/sound/soc/imx/imx-pcm-fiq.c index f96a373699cf..6b518e07eea9 100644 --- a/sound/soc/imx/imx-pcm-fiq.c +++ b/sound/soc/imx/imx-pcm-fiq.c | |||
@@ -39,23 +39,24 @@ struct imx_pcm_runtime_data { | |||
39 | unsigned long offset; | 39 | unsigned long offset; |
40 | unsigned long last_offset; | 40 | unsigned long last_offset; |
41 | unsigned long size; | 41 | unsigned long size; |
42 | struct timer_list timer; | 42 | struct hrtimer hrt; |
43 | int poll_time; | 43 | int poll_time_ns; |
44 | struct snd_pcm_substream *substream; | ||
45 | atomic_t running; | ||
44 | }; | 46 | }; |
45 | 47 | ||
46 | static inline void imx_ssi_set_next_poll(struct imx_pcm_runtime_data *iprtd) | 48 | static enum hrtimer_restart snd_hrtimer_callback(struct hrtimer *hrt) |
47 | { | 49 | { |
48 | iprtd->timer.expires = jiffies + iprtd->poll_time; | 50 | struct imx_pcm_runtime_data *iprtd = |
49 | } | 51 | container_of(hrt, struct imx_pcm_runtime_data, hrt); |
50 | 52 | struct snd_pcm_substream *substream = iprtd->substream; | |
51 | static void imx_ssi_timer_callback(unsigned long data) | ||
52 | { | ||
53 | struct snd_pcm_substream *substream = (void *)data; | ||
54 | struct snd_pcm_runtime *runtime = substream->runtime; | 53 | struct snd_pcm_runtime *runtime = substream->runtime; |
55 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; | ||
56 | struct pt_regs regs; | 54 | struct pt_regs regs; |
57 | unsigned long delta; | 55 | unsigned long delta; |
58 | 56 | ||
57 | if (!atomic_read(&iprtd->running)) | ||
58 | return HRTIMER_NORESTART; | ||
59 | |||
59 | get_fiq_regs(®s); | 60 | get_fiq_regs(®s); |
60 | 61 | ||
61 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) | 62 | if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
@@ -72,16 +73,14 @@ static void imx_ssi_timer_callback(unsigned long data) | |||
72 | 73 | ||
73 | /* If we've transferred at least a period then report it and | 74 | /* If we've transferred at least a period then report it and |
74 | * reset our poll time */ | 75 | * reset our poll time */ |
75 | if (delta >= runtime->period_size) { | 76 | if (delta >= iprtd->period) { |
76 | snd_pcm_period_elapsed(substream); | 77 | snd_pcm_period_elapsed(substream); |
77 | iprtd->last_offset = iprtd->offset; | 78 | iprtd->last_offset = iprtd->offset; |
78 | |||
79 | imx_ssi_set_next_poll(iprtd); | ||
80 | } | 79 | } |
81 | 80 | ||
82 | /* Restart the timer; if we didn't report we'll run on the next tick */ | 81 | hrtimer_forward_now(hrt, ns_to_ktime(iprtd->poll_time_ns)); |
83 | add_timer(&iprtd->timer); | ||
84 | 82 | ||
83 | return HRTIMER_RESTART; | ||
85 | } | 84 | } |
86 | 85 | ||
87 | static struct fiq_handler fh = { | 86 | static struct fiq_handler fh = { |
@@ -99,8 +98,8 @@ static int snd_imx_pcm_hw_params(struct snd_pcm_substream *substream, | |||
99 | iprtd->period = params_period_bytes(params) ; | 98 | iprtd->period = params_period_bytes(params) ; |
100 | iprtd->offset = 0; | 99 | iprtd->offset = 0; |
101 | iprtd->last_offset = 0; | 100 | iprtd->last_offset = 0; |
102 | iprtd->poll_time = HZ / (params_rate(params) / params_period_size(params)); | 101 | iprtd->poll_time_ns = 1000000000 / params_rate(params) * |
103 | 102 | params_period_size(params); | |
104 | snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); | 103 | snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); |
105 | 104 | ||
106 | return 0; | 105 | return 0; |
@@ -135,8 +134,9 @@ static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | |||
135 | case SNDRV_PCM_TRIGGER_START: | 134 | case SNDRV_PCM_TRIGGER_START: |
136 | case SNDRV_PCM_TRIGGER_RESUME: | 135 | case SNDRV_PCM_TRIGGER_RESUME: |
137 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | 136 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
138 | imx_ssi_set_next_poll(iprtd); | 137 | atomic_set(&iprtd->running, 1); |
139 | add_timer(&iprtd->timer); | 138 | hrtimer_start(&iprtd->hrt, ns_to_ktime(iprtd->poll_time_ns), |
139 | HRTIMER_MODE_REL); | ||
140 | if (++fiq_enable == 1) | 140 | if (++fiq_enable == 1) |
141 | enable_fiq(imx_pcm_fiq); | 141 | enable_fiq(imx_pcm_fiq); |
142 | 142 | ||
@@ -145,11 +145,11 @@ static int snd_imx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | |||
145 | case SNDRV_PCM_TRIGGER_STOP: | 145 | case SNDRV_PCM_TRIGGER_STOP: |
146 | case SNDRV_PCM_TRIGGER_SUSPEND: | 146 | case SNDRV_PCM_TRIGGER_SUSPEND: |
147 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | 147 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
148 | del_timer(&iprtd->timer); | 148 | atomic_set(&iprtd->running, 0); |
149 | |||
149 | if (--fiq_enable == 0) | 150 | if (--fiq_enable == 0) |
150 | disable_fiq(imx_pcm_fiq); | 151 | disable_fiq(imx_pcm_fiq); |
151 | 152 | ||
152 | |||
153 | break; | 153 | break; |
154 | default: | 154 | default: |
155 | return -EINVAL; | 155 | return -EINVAL; |
@@ -180,7 +180,7 @@ static struct snd_pcm_hardware snd_imx_hardware = { | |||
180 | .buffer_bytes_max = IMX_SSI_DMABUF_SIZE, | 180 | .buffer_bytes_max = IMX_SSI_DMABUF_SIZE, |
181 | .period_bytes_min = 128, | 181 | .period_bytes_min = 128, |
182 | .period_bytes_max = 16 * 1024, | 182 | .period_bytes_max = 16 * 1024, |
183 | .periods_min = 2, | 183 | .periods_min = 4, |
184 | .periods_max = 255, | 184 | .periods_max = 255, |
185 | .fifo_size = 0, | 185 | .fifo_size = 0, |
186 | }; | 186 | }; |
@@ -194,9 +194,11 @@ static int snd_imx_open(struct snd_pcm_substream *substream) | |||
194 | iprtd = kzalloc(sizeof(*iprtd), GFP_KERNEL); | 194 | iprtd = kzalloc(sizeof(*iprtd), GFP_KERNEL); |
195 | runtime->private_data = iprtd; | 195 | runtime->private_data = iprtd; |
196 | 196 | ||
197 | init_timer(&iprtd->timer); | 197 | iprtd->substream = substream; |
198 | iprtd->timer.data = (unsigned long)substream; | 198 | |
199 | iprtd->timer.function = imx_ssi_timer_callback; | 199 | atomic_set(&iprtd->running, 0); |
200 | hrtimer_init(&iprtd->hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL); | ||
201 | iprtd->hrt.function = snd_hrtimer_callback; | ||
200 | 202 | ||
201 | ret = snd_pcm_hw_constraint_integer(substream->runtime, | 203 | ret = snd_pcm_hw_constraint_integer(substream->runtime, |
202 | SNDRV_PCM_HW_PARAM_PERIODS); | 204 | SNDRV_PCM_HW_PARAM_PERIODS); |
@@ -212,7 +214,8 @@ static int snd_imx_close(struct snd_pcm_substream *substream) | |||
212 | struct snd_pcm_runtime *runtime = substream->runtime; | 214 | struct snd_pcm_runtime *runtime = substream->runtime; |
213 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; | 215 | struct imx_pcm_runtime_data *iprtd = runtime->private_data; |
214 | 216 | ||
215 | del_timer_sync(&iprtd->timer); | 217 | hrtimer_cancel(&iprtd->hrt); |
218 | |||
216 | kfree(iprtd); | 219 | kfree(iprtd); |
217 | 220 | ||
218 | return 0; | 221 | return 0; |
diff --git a/sound/soc/imx/imx-ssi.c b/sound/soc/imx/imx-ssi.c index 6546b06cbd2a..80b4fee2442b 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 */ |
@@ -653,7 +656,8 @@ static int imx_ssi_probe(struct platform_device *pdev) | |||
653 | dai->private_data = ssi; | 656 | dai->private_data = ssi; |
654 | 657 | ||
655 | if ((cpu_is_mx27() || cpu_is_mx21()) && | 658 | if ((cpu_is_mx27() || cpu_is_mx21()) && |
656 | !(ssi->flags & IMX_SSI_USE_AC97)) { | 659 | !(ssi->flags & IMX_SSI_USE_AC97) && |
660 | (ssi->flags & IMX_SSI_DMA)) { | ||
657 | ssi->flags |= IMX_SSI_DMA; | 661 | ssi->flags |= IMX_SSI_DMA; |
658 | platform = imx_ssi_dma_mx2_init(pdev, ssi); | 662 | platform = imx_ssi_dma_mx2_init(pdev, ssi); |
659 | } else | 663 | } else |
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index e814a9591f78..8ad9dc901007 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 25f19e4728bf..b7f4f7e015f3 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 ba8acbb0a7fa..1e521904ea64 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 d5fc52d0a3c4..544fd9566f4d 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 e9ae7b3a7e00..d314115e3dd7 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 6b8f655d1ad8..c1a5275721e4 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 d38e39575f51..adc7e6f15f93 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 ee8ed9d7e703..ecf4fd04ae96 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 7725e26d6c91..1b61c23ff300 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 e994d8374fe6..88515946b6c0 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 a98f40c3cd29..326f0a9e7e30 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 0bc5950b9f02..c3ac890a3986 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 0664fac7612a..5b9ac1759bd2 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 1d61109e09fa..9c7f7f00cebb 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 2320153bd923..ad7f9528d751 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 | } |
diff --git a/sound/soc/txx9/txx9aclc-ac97.c b/sound/soc/txx9/txx9aclc-ac97.c index 612e18b4bf4e..0ec20b68e8cb 100644 --- a/sound/soc/txx9/txx9aclc-ac97.c +++ b/sound/soc/txx9/txx9aclc-ac97.c | |||
@@ -254,3 +254,4 @@ module_exit(txx9aclc_ac97_exit); | |||
254 | MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>"); | 254 | MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>"); |
255 | MODULE_DESCRIPTION("TXx9 ACLC AC97 driver"); | 255 | MODULE_DESCRIPTION("TXx9 ACLC AC97 driver"); |
256 | MODULE_LICENSE("GPL"); | 256 | MODULE_LICENSE("GPL"); |
257 | MODULE_ALIAS("platform:txx9aclc-ac97"); | ||
diff --git a/sound/soc/txx9/txx9aclc-generic.c b/sound/soc/txx9/txx9aclc-generic.c index 3175de9a92cb..95b17f731aec 100644 --- a/sound/soc/txx9/txx9aclc-generic.c +++ b/sound/soc/txx9/txx9aclc-generic.c | |||
@@ -96,3 +96,4 @@ module_exit(txx9aclc_generic_exit); | |||
96 | MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>"); | 96 | MODULE_AUTHOR("Atsushi Nemoto <anemo@mba.ocn.ne.jp>"); |
97 | MODULE_DESCRIPTION("Generic TXx9 ACLC ALSA SoC audio driver"); | 97 | MODULE_DESCRIPTION("Generic TXx9 ACLC ALSA SoC audio driver"); |
98 | MODULE_LICENSE("GPL"); | 98 | MODULE_LICENSE("GPL"); |
99 | MODULE_ALIAS("platform:txx9aclc-generic"); | ||
diff --git a/sound/usb/usbmidi.c b/sound/usb/usbmidi.c index 2c59afd99611..9e28b20cb2ce 100644 --- a/sound/usb/usbmidi.c +++ b/sound/usb/usbmidi.c | |||
@@ -986,6 +986,8 @@ static void snd_usbmidi_output_drain(struct snd_rawmidi_substream *substream) | |||
986 | DEFINE_WAIT(wait); | 986 | DEFINE_WAIT(wait); |
987 | long timeout = msecs_to_jiffies(50); | 987 | long timeout = msecs_to_jiffies(50); |
988 | 988 | ||
989 | if (ep->umidi->disconnected) | ||
990 | return; | ||
989 | /* | 991 | /* |
990 | * The substream buffer is empty, but some data might still be in the | 992 | * The substream buffer is empty, but some data might still be in the |
991 | * currently active URBs, so we have to wait for those to complete. | 993 | * currently active URBs, so we have to wait for those to complete. |
@@ -1123,14 +1125,21 @@ static int snd_usbmidi_in_endpoint_create(struct snd_usb_midi* umidi, | |||
1123 | * Frees an output endpoint. | 1125 | * Frees an output endpoint. |
1124 | * May be called when ep hasn't been initialized completely. | 1126 | * May be called when ep hasn't been initialized completely. |
1125 | */ | 1127 | */ |
1126 | static void snd_usbmidi_out_endpoint_delete(struct snd_usb_midi_out_endpoint* ep) | 1128 | static void snd_usbmidi_out_endpoint_clear(struct snd_usb_midi_out_endpoint *ep) |
1127 | { | 1129 | { |
1128 | unsigned int i; | 1130 | unsigned int i; |
1129 | 1131 | ||
1130 | for (i = 0; i < OUTPUT_URBS; ++i) | 1132 | for (i = 0; i < OUTPUT_URBS; ++i) |
1131 | if (ep->urbs[i].urb) | 1133 | if (ep->urbs[i].urb) { |
1132 | free_urb_and_buffer(ep->umidi, ep->urbs[i].urb, | 1134 | free_urb_and_buffer(ep->umidi, ep->urbs[i].urb, |
1133 | ep->max_transfer); | 1135 | ep->max_transfer); |
1136 | ep->urbs[i].urb = NULL; | ||
1137 | } | ||
1138 | } | ||
1139 | |||
1140 | static void snd_usbmidi_out_endpoint_delete(struct snd_usb_midi_out_endpoint *ep) | ||
1141 | { | ||
1142 | snd_usbmidi_out_endpoint_clear(ep); | ||
1134 | kfree(ep); | 1143 | kfree(ep); |
1135 | } | 1144 | } |
1136 | 1145 | ||
@@ -1262,15 +1271,18 @@ void snd_usbmidi_disconnect(struct list_head* p) | |||
1262 | usb_kill_urb(ep->out->urbs[j].urb); | 1271 | usb_kill_urb(ep->out->urbs[j].urb); |
1263 | if (umidi->usb_protocol_ops->finish_out_endpoint) | 1272 | if (umidi->usb_protocol_ops->finish_out_endpoint) |
1264 | umidi->usb_protocol_ops->finish_out_endpoint(ep->out); | 1273 | umidi->usb_protocol_ops->finish_out_endpoint(ep->out); |
1274 | ep->out->active_urbs = 0; | ||
1275 | if (ep->out->drain_urbs) { | ||
1276 | ep->out->drain_urbs = 0; | ||
1277 | wake_up(&ep->out->drain_wait); | ||
1278 | } | ||
1265 | } | 1279 | } |
1266 | if (ep->in) | 1280 | if (ep->in) |
1267 | for (j = 0; j < INPUT_URBS; ++j) | 1281 | for (j = 0; j < INPUT_URBS; ++j) |
1268 | usb_kill_urb(ep->in->urbs[j]); | 1282 | usb_kill_urb(ep->in->urbs[j]); |
1269 | /* free endpoints here; later call can result in Oops */ | 1283 | /* free endpoints here; later call can result in Oops */ |
1270 | if (ep->out) { | 1284 | if (ep->out) |
1271 | snd_usbmidi_out_endpoint_delete(ep->out); | 1285 | snd_usbmidi_out_endpoint_clear(ep->out); |
1272 | ep->out = NULL; | ||
1273 | } | ||
1274 | if (ep->in) { | 1286 | if (ep->in) { |
1275 | snd_usbmidi_in_endpoint_delete(ep->in); | 1287 | snd_usbmidi_in_endpoint_delete(ep->in); |
1276 | ep->in = NULL; | 1288 | ep->in = NULL; |