diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-12 14:16:27 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-12 14:16:27 -0400 |
commit | e349792a385ed47390d156155b1a1e19af1bf163 (patch) | |
tree | f9dc4e3e42769950230eaa58ecdd056eb27b23e8 /sound/pci/ice1712/ice1724.c | |
parent | 6d21491838a2a9f22843c7530b118596ee9f4d77 (diff) | |
parent | e3f86d3d3ce350144562d9bd035dc8a274fce58e (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6: (290 commits)
ALSA: pcm - Update document about xrun_debug proc file
ALSA: lx6464es - support standard alsa module parameters
ALSA: snd_usb_caiaq: set mixername
ALSA: hda - add quirk for STAC92xx (SigmaTel STAC9205)
ALSA: use card device as parent for jack input-devices
ALSA: sound/ps3: Correct existing and add missing annotations
ALSA: sound/ps3: Restructure driver source
ALSA: sound/ps3: Fix checkpatch issues
ASoC: Fix lm4857 control
ALSA: ctxfi - Clear PCM resources at hw_params and hw_free
ALSA: ctxfi - Check the presence of SRC instance in PCM pointer callbacks
ALSA: ctxfi - Add missing start check in atc_pcm_playback_start()
ALSA: ctxfi - Add use_system_timer module option
ALSA: usb - Add boot quirk for C-Media 6206 USB Audio
ALSA: ctxfi - Fix wrong model id for UAA
ALSA: ctxfi - Clean up probe routines
ALSA: hda - Fix the previous tagra-8ch patch
ALSA: hda - Add 7.1 support for MSI GX620
ALSA: pcm - A helper function to compose PCM stream name for debug prints
ALSA: emu10k1 - Fix minimum periods for efx playback
...
Diffstat (limited to 'sound/pci/ice1712/ice1724.c')
-rw-r--r-- | sound/pci/ice1712/ice1724.c | 96 |
1 files changed, 60 insertions, 36 deletions
diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c index 128510e77a78..36ade77cf371 100644 --- a/sound/pci/ice1712/ice1724.c +++ b/sound/pci/ice1712/ice1724.c | |||
@@ -49,6 +49,7 @@ | |||
49 | #include "prodigy192.h" | 49 | #include "prodigy192.h" |
50 | #include "prodigy_hifi.h" | 50 | #include "prodigy_hifi.h" |
51 | #include "juli.h" | 51 | #include "juli.h" |
52 | #include "maya44.h" | ||
52 | #include "phase.h" | 53 | #include "phase.h" |
53 | #include "wtm.h" | 54 | #include "wtm.h" |
54 | #include "se.h" | 55 | #include "se.h" |
@@ -65,6 +66,7 @@ MODULE_SUPPORTED_DEVICE("{" | |||
65 | PRODIGY192_DEVICE_DESC | 66 | PRODIGY192_DEVICE_DESC |
66 | PRODIGY_HIFI_DEVICE_DESC | 67 | PRODIGY_HIFI_DEVICE_DESC |
67 | JULI_DEVICE_DESC | 68 | JULI_DEVICE_DESC |
69 | MAYA44_DEVICE_DESC | ||
68 | PHASE_DEVICE_DESC | 70 | PHASE_DEVICE_DESC |
69 | WTM_DEVICE_DESC | 71 | WTM_DEVICE_DESC |
70 | SE_DEVICE_DESC | 72 | SE_DEVICE_DESC |
@@ -626,7 +628,7 @@ static unsigned char stdclock_set_mclk(struct snd_ice1712 *ice, | |||
626 | return 0; | 628 | return 0; |
627 | } | 629 | } |
628 | 630 | ||
629 | static void snd_vt1724_set_pro_rate(struct snd_ice1712 *ice, unsigned int rate, | 631 | static int snd_vt1724_set_pro_rate(struct snd_ice1712 *ice, unsigned int rate, |
630 | int force) | 632 | int force) |
631 | { | 633 | { |
632 | unsigned long flags; | 634 | unsigned long flags; |
@@ -634,17 +636,18 @@ static void snd_vt1724_set_pro_rate(struct snd_ice1712 *ice, unsigned int rate, | |||
634 | unsigned int i, old_rate; | 636 | unsigned int i, old_rate; |
635 | 637 | ||
636 | if (rate > ice->hw_rates->list[ice->hw_rates->count - 1]) | 638 | if (rate > ice->hw_rates->list[ice->hw_rates->count - 1]) |
637 | return; | 639 | return -EINVAL; |
640 | |||
638 | spin_lock_irqsave(&ice->reg_lock, flags); | 641 | spin_lock_irqsave(&ice->reg_lock, flags); |
639 | if ((inb(ICEMT1724(ice, DMA_CONTROL)) & DMA_STARTS) || | 642 | if ((inb(ICEMT1724(ice, DMA_CONTROL)) & DMA_STARTS) || |
640 | (inb(ICEMT1724(ice, DMA_PAUSE)) & DMA_PAUSES)) { | 643 | (inb(ICEMT1724(ice, DMA_PAUSE)) & DMA_PAUSES)) { |
641 | /* running? we cannot change the rate now... */ | 644 | /* running? we cannot change the rate now... */ |
642 | spin_unlock_irqrestore(&ice->reg_lock, flags); | 645 | spin_unlock_irqrestore(&ice->reg_lock, flags); |
643 | return; | 646 | return -EBUSY; |
644 | } | 647 | } |
645 | if (!force && is_pro_rate_locked(ice)) { | 648 | if (!force && is_pro_rate_locked(ice)) { |
646 | spin_unlock_irqrestore(&ice->reg_lock, flags); | 649 | spin_unlock_irqrestore(&ice->reg_lock, flags); |
647 | return; | 650 | return (rate == ice->cur_rate) ? 0 : -EBUSY; |
648 | } | 651 | } |
649 | 652 | ||
650 | old_rate = ice->get_rate(ice); | 653 | old_rate = ice->get_rate(ice); |
@@ -652,7 +655,7 @@ static void snd_vt1724_set_pro_rate(struct snd_ice1712 *ice, unsigned int rate, | |||
652 | ice->set_rate(ice, rate); | 655 | ice->set_rate(ice, rate); |
653 | else if (rate == ice->cur_rate) { | 656 | else if (rate == ice->cur_rate) { |
654 | spin_unlock_irqrestore(&ice->reg_lock, flags); | 657 | spin_unlock_irqrestore(&ice->reg_lock, flags); |
655 | return; | 658 | return 0; |
656 | } | 659 | } |
657 | 660 | ||
658 | ice->cur_rate = rate; | 661 | ice->cur_rate = rate; |
@@ -674,13 +677,15 @@ static void snd_vt1724_set_pro_rate(struct snd_ice1712 *ice, unsigned int rate, | |||
674 | } | 677 | } |
675 | if (ice->spdif.ops.setup_rate) | 678 | if (ice->spdif.ops.setup_rate) |
676 | ice->spdif.ops.setup_rate(ice, rate); | 679 | ice->spdif.ops.setup_rate(ice, rate); |
680 | |||
681 | return 0; | ||
677 | } | 682 | } |
678 | 683 | ||
679 | static int snd_vt1724_pcm_hw_params(struct snd_pcm_substream *substream, | 684 | static int snd_vt1724_pcm_hw_params(struct snd_pcm_substream *substream, |
680 | struct snd_pcm_hw_params *hw_params) | 685 | struct snd_pcm_hw_params *hw_params) |
681 | { | 686 | { |
682 | struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); | 687 | struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); |
683 | int i, chs; | 688 | int i, chs, err; |
684 | 689 | ||
685 | chs = params_channels(hw_params); | 690 | chs = params_channels(hw_params); |
686 | mutex_lock(&ice->open_mutex); | 691 | mutex_lock(&ice->open_mutex); |
@@ -715,7 +720,11 @@ static int snd_vt1724_pcm_hw_params(struct snd_pcm_substream *substream, | |||
715 | } | 720 | } |
716 | } | 721 | } |
717 | mutex_unlock(&ice->open_mutex); | 722 | mutex_unlock(&ice->open_mutex); |
718 | snd_vt1724_set_pro_rate(ice, params_rate(hw_params), 0); | 723 | |
724 | err = snd_vt1724_set_pro_rate(ice, params_rate(hw_params), 0); | ||
725 | if (err < 0) | ||
726 | return err; | ||
727 | |||
719 | return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); | 728 | return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); |
720 | } | 729 | } |
721 | 730 | ||
@@ -848,20 +857,39 @@ static snd_pcm_uframes_t snd_vt1724_pcm_pointer(struct snd_pcm_substream *substr | |||
848 | #endif | 857 | #endif |
849 | } | 858 | } |
850 | 859 | ||
851 | static const struct vt1724_pcm_reg vt1724_playback_pro_reg = { | 860 | static const struct vt1724_pcm_reg vt1724_pdma0_reg = { |
852 | .addr = VT1724_MT_PLAYBACK_ADDR, | 861 | .addr = VT1724_MT_PLAYBACK_ADDR, |
853 | .size = VT1724_MT_PLAYBACK_SIZE, | 862 | .size = VT1724_MT_PLAYBACK_SIZE, |
854 | .count = VT1724_MT_PLAYBACK_COUNT, | 863 | .count = VT1724_MT_PLAYBACK_COUNT, |
855 | .start = VT1724_PDMA0_START, | 864 | .start = VT1724_PDMA0_START, |
856 | }; | 865 | }; |
857 | 866 | ||
858 | static const struct vt1724_pcm_reg vt1724_capture_pro_reg = { | 867 | static const struct vt1724_pcm_reg vt1724_pdma4_reg = { |
868 | .addr = VT1724_MT_PDMA4_ADDR, | ||
869 | .size = VT1724_MT_PDMA4_SIZE, | ||
870 | .count = VT1724_MT_PDMA4_COUNT, | ||
871 | .start = VT1724_PDMA4_START, | ||
872 | }; | ||
873 | |||
874 | static const struct vt1724_pcm_reg vt1724_rdma0_reg = { | ||
859 | .addr = VT1724_MT_CAPTURE_ADDR, | 875 | .addr = VT1724_MT_CAPTURE_ADDR, |
860 | .size = VT1724_MT_CAPTURE_SIZE, | 876 | .size = VT1724_MT_CAPTURE_SIZE, |
861 | .count = VT1724_MT_CAPTURE_COUNT, | 877 | .count = VT1724_MT_CAPTURE_COUNT, |
862 | .start = VT1724_RDMA0_START, | 878 | .start = VT1724_RDMA0_START, |
863 | }; | 879 | }; |
864 | 880 | ||
881 | static const struct vt1724_pcm_reg vt1724_rdma1_reg = { | ||
882 | .addr = VT1724_MT_RDMA1_ADDR, | ||
883 | .size = VT1724_MT_RDMA1_SIZE, | ||
884 | .count = VT1724_MT_RDMA1_COUNT, | ||
885 | .start = VT1724_RDMA1_START, | ||
886 | }; | ||
887 | |||
888 | #define vt1724_playback_pro_reg vt1724_pdma0_reg | ||
889 | #define vt1724_playback_spdif_reg vt1724_pdma4_reg | ||
890 | #define vt1724_capture_pro_reg vt1724_rdma0_reg | ||
891 | #define vt1724_capture_spdif_reg vt1724_rdma1_reg | ||
892 | |||
865 | static const struct snd_pcm_hardware snd_vt1724_playback_pro = { | 893 | static const struct snd_pcm_hardware snd_vt1724_playback_pro = { |
866 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | | 894 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | |
867 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | 895 | SNDRV_PCM_INFO_BLOCK_TRANSFER | |
@@ -1077,20 +1105,6 @@ static int __devinit snd_vt1724_pcm_profi(struct snd_ice1712 *ice, int device) | |||
1077 | * SPDIF PCM | 1105 | * SPDIF PCM |
1078 | */ | 1106 | */ |
1079 | 1107 | ||
1080 | static const struct vt1724_pcm_reg vt1724_playback_spdif_reg = { | ||
1081 | .addr = VT1724_MT_PDMA4_ADDR, | ||
1082 | .size = VT1724_MT_PDMA4_SIZE, | ||
1083 | .count = VT1724_MT_PDMA4_COUNT, | ||
1084 | .start = VT1724_PDMA4_START, | ||
1085 | }; | ||
1086 | |||
1087 | static const struct vt1724_pcm_reg vt1724_capture_spdif_reg = { | ||
1088 | .addr = VT1724_MT_RDMA1_ADDR, | ||
1089 | .size = VT1724_MT_RDMA1_SIZE, | ||
1090 | .count = VT1724_MT_RDMA1_COUNT, | ||
1091 | .start = VT1724_RDMA1_START, | ||
1092 | }; | ||
1093 | |||
1094 | /* update spdif control bits; call with reg_lock */ | 1108 | /* update spdif control bits; call with reg_lock */ |
1095 | static void update_spdif_bits(struct snd_ice1712 *ice, unsigned int val) | 1109 | static void update_spdif_bits(struct snd_ice1712 *ice, unsigned int val) |
1096 | { | 1110 | { |
@@ -1963,7 +1977,7 @@ static inline int digital_route_shift(int idx) | |||
1963 | return idx * 3; | 1977 | return idx * 3; |
1964 | } | 1978 | } |
1965 | 1979 | ||
1966 | static int get_route_val(struct snd_ice1712 *ice, int shift) | 1980 | int snd_ice1724_get_route_val(struct snd_ice1712 *ice, int shift) |
1967 | { | 1981 | { |
1968 | unsigned long val; | 1982 | unsigned long val; |
1969 | unsigned char eitem; | 1983 | unsigned char eitem; |
@@ -1982,7 +1996,8 @@ static int get_route_val(struct snd_ice1712 *ice, int shift) | |||
1982 | return eitem; | 1996 | return eitem; |
1983 | } | 1997 | } |
1984 | 1998 | ||
1985 | static int put_route_val(struct snd_ice1712 *ice, unsigned int val, int shift) | 1999 | int snd_ice1724_put_route_val(struct snd_ice1712 *ice, unsigned int val, |
2000 | int shift) | ||
1986 | { | 2001 | { |
1987 | unsigned int old_val, nval; | 2002 | unsigned int old_val, nval; |
1988 | int change; | 2003 | int change; |
@@ -2010,7 +2025,7 @@ static int snd_vt1724_pro_route_analog_get(struct snd_kcontrol *kcontrol, | |||
2010 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); | 2025 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); |
2011 | int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | 2026 | int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); |
2012 | ucontrol->value.enumerated.item[0] = | 2027 | ucontrol->value.enumerated.item[0] = |
2013 | get_route_val(ice, analog_route_shift(idx)); | 2028 | snd_ice1724_get_route_val(ice, analog_route_shift(idx)); |
2014 | return 0; | 2029 | return 0; |
2015 | } | 2030 | } |
2016 | 2031 | ||
@@ -2019,8 +2034,9 @@ static int snd_vt1724_pro_route_analog_put(struct snd_kcontrol *kcontrol, | |||
2019 | { | 2034 | { |
2020 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); | 2035 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); |
2021 | int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | 2036 | int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); |
2022 | return put_route_val(ice, ucontrol->value.enumerated.item[0], | 2037 | return snd_ice1724_put_route_val(ice, |
2023 | analog_route_shift(idx)); | 2038 | ucontrol->value.enumerated.item[0], |
2039 | analog_route_shift(idx)); | ||
2024 | } | 2040 | } |
2025 | 2041 | ||
2026 | static int snd_vt1724_pro_route_spdif_get(struct snd_kcontrol *kcontrol, | 2042 | static int snd_vt1724_pro_route_spdif_get(struct snd_kcontrol *kcontrol, |
@@ -2029,7 +2045,7 @@ static int snd_vt1724_pro_route_spdif_get(struct snd_kcontrol *kcontrol, | |||
2029 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); | 2045 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); |
2030 | int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | 2046 | int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); |
2031 | ucontrol->value.enumerated.item[0] = | 2047 | ucontrol->value.enumerated.item[0] = |
2032 | get_route_val(ice, digital_route_shift(idx)); | 2048 | snd_ice1724_get_route_val(ice, digital_route_shift(idx)); |
2033 | return 0; | 2049 | return 0; |
2034 | } | 2050 | } |
2035 | 2051 | ||
@@ -2038,11 +2054,13 @@ static int snd_vt1724_pro_route_spdif_put(struct snd_kcontrol *kcontrol, | |||
2038 | { | 2054 | { |
2039 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); | 2055 | struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); |
2040 | int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); | 2056 | int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); |
2041 | return put_route_val(ice, ucontrol->value.enumerated.item[0], | 2057 | return snd_ice1724_put_route_val(ice, |
2042 | digital_route_shift(idx)); | 2058 | ucontrol->value.enumerated.item[0], |
2059 | digital_route_shift(idx)); | ||
2043 | } | 2060 | } |
2044 | 2061 | ||
2045 | static struct snd_kcontrol_new snd_vt1724_mixer_pro_analog_route __devinitdata = { | 2062 | static struct snd_kcontrol_new snd_vt1724_mixer_pro_analog_route __devinitdata = |
2063 | { | ||
2046 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 2064 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
2047 | .name = "H/W Playback Route", | 2065 | .name = "H/W Playback Route", |
2048 | .info = snd_vt1724_pro_route_info, | 2066 | .info = snd_vt1724_pro_route_info, |
@@ -2109,6 +2127,7 @@ static struct snd_ice1712_card_info *card_tables[] __devinitdata = { | |||
2109 | snd_vt1724_prodigy_hifi_cards, | 2127 | snd_vt1724_prodigy_hifi_cards, |
2110 | snd_vt1724_prodigy192_cards, | 2128 | snd_vt1724_prodigy192_cards, |
2111 | snd_vt1724_juli_cards, | 2129 | snd_vt1724_juli_cards, |
2130 | snd_vt1724_maya44_cards, | ||
2112 | snd_vt1724_phase_cards, | 2131 | snd_vt1724_phase_cards, |
2113 | snd_vt1724_wtm_cards, | 2132 | snd_vt1724_wtm_cards, |
2114 | snd_vt1724_se_cards, | 2133 | snd_vt1724_se_cards, |
@@ -2246,8 +2265,10 @@ static int __devinit snd_vt1724_read_eeprom(struct snd_ice1712 *ice, | |||
2246 | static void __devinit snd_vt1724_chip_reset(struct snd_ice1712 *ice) | 2265 | static void __devinit snd_vt1724_chip_reset(struct snd_ice1712 *ice) |
2247 | { | 2266 | { |
2248 | outb(VT1724_RESET , ICEREG1724(ice, CONTROL)); | 2267 | outb(VT1724_RESET , ICEREG1724(ice, CONTROL)); |
2268 | inb(ICEREG1724(ice, CONTROL)); /* pci posting flush */ | ||
2249 | msleep(10); | 2269 | msleep(10); |
2250 | outb(0, ICEREG1724(ice, CONTROL)); | 2270 | outb(0, ICEREG1724(ice, CONTROL)); |
2271 | inb(ICEREG1724(ice, CONTROL)); /* pci posting flush */ | ||
2251 | msleep(10); | 2272 | msleep(10); |
2252 | } | 2273 | } |
2253 | 2274 | ||
@@ -2277,9 +2298,12 @@ static int __devinit snd_vt1724_spdif_build_controls(struct snd_ice1712 *ice) | |||
2277 | if (snd_BUG_ON(!ice->pcm)) | 2298 | if (snd_BUG_ON(!ice->pcm)) |
2278 | return -EIO; | 2299 | return -EIO; |
2279 | 2300 | ||
2280 | err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_vt1724_mixer_pro_spdif_route, ice)); | 2301 | if (!ice->own_routing) { |
2281 | if (err < 0) | 2302 | err = snd_ctl_add(ice->card, |
2282 | return err; | 2303 | snd_ctl_new1(&snd_vt1724_mixer_pro_spdif_route, ice)); |
2304 | if (err < 0) | ||
2305 | return err; | ||
2306 | } | ||
2283 | 2307 | ||
2284 | err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_vt1724_spdif_switch, ice)); | 2308 | err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_vt1724_spdif_switch, ice)); |
2285 | if (err < 0) | 2309 | if (err < 0) |
@@ -2326,7 +2350,7 @@ static int __devinit snd_vt1724_build_controls(struct snd_ice1712 *ice) | |||
2326 | if (err < 0) | 2350 | if (err < 0) |
2327 | return err; | 2351 | return err; |
2328 | 2352 | ||
2329 | if (ice->num_total_dacs > 0) { | 2353 | if (!ice->own_routing && ice->num_total_dacs > 0) { |
2330 | struct snd_kcontrol_new tmp = snd_vt1724_mixer_pro_analog_route; | 2354 | struct snd_kcontrol_new tmp = snd_vt1724_mixer_pro_analog_route; |
2331 | tmp.count = ice->num_total_dacs; | 2355 | tmp.count = ice->num_total_dacs; |
2332 | if (ice->vt1720 && tmp.count > 2) | 2356 | if (ice->vt1720 && tmp.count > 2) |