diff options
Diffstat (limited to 'sound/pci/ac97/ac97_codec.c')
-rw-r--r-- | sound/pci/ac97/ac97_codec.c | 56 |
1 files changed, 9 insertions, 47 deletions
diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index 41fc290149ed..9bde76c4c6a2 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c | |||
@@ -220,12 +220,6 @@ const char *snd_ac97_stereo_enhancements[] = | |||
220 | /* 31 */ "Reserved 31" | 220 | /* 31 */ "Reserved 31" |
221 | }; | 221 | }; |
222 | 222 | ||
223 | /* | ||
224 | * Shared AC97 controllers (ICH, ATIIXP...) | ||
225 | */ | ||
226 | static DECLARE_MUTEX(shared_codec_mutex); | ||
227 | static ac97_t *shared_codec[AC97_SHARED_TYPES][4]; | ||
228 | |||
229 | 223 | ||
230 | /* | 224 | /* |
231 | * I/O routines | 225 | * I/O routines |
@@ -996,14 +990,8 @@ static int snd_ac97_free(ac97_t *ac97) | |||
996 | { | 990 | { |
997 | if (ac97) { | 991 | if (ac97) { |
998 | snd_ac97_proc_done(ac97); | 992 | snd_ac97_proc_done(ac97); |
999 | if (ac97->bus) { | 993 | if (ac97->bus) |
1000 | ac97->bus->codec[ac97->num] = NULL; | 994 | ac97->bus->codec[ac97->num] = NULL; |
1001 | if (ac97->bus->shared_type) { | ||
1002 | down(&shared_codec_mutex); | ||
1003 | shared_codec[ac97->bus->shared_type-1][ac97->num] = NULL; | ||
1004 | up(&shared_codec_mutex); | ||
1005 | } | ||
1006 | } | ||
1007 | if (ac97->private_free) | 995 | if (ac97->private_free) |
1008 | ac97->private_free(ac97); | 996 | ac97->private_free(ac97); |
1009 | kfree(ac97); | 997 | kfree(ac97); |
@@ -1139,7 +1127,6 @@ snd_kcontrol_t *snd_ac97_cnew(const snd_kcontrol_new_t *_template, ac97_t * ac97 | |||
1139 | { | 1127 | { |
1140 | snd_kcontrol_new_t template; | 1128 | snd_kcontrol_new_t template; |
1141 | memcpy(&template, _template, sizeof(template)); | 1129 | memcpy(&template, _template, sizeof(template)); |
1142 | snd_runtime_check(!template.index, return NULL); | ||
1143 | template.index = ac97->num; | 1130 | template.index = ac97->num; |
1144 | return snd_ctl_new1(&template, ac97); | 1131 | return snd_ctl_new1(&template, ac97); |
1145 | } | 1132 | } |
@@ -1758,8 +1745,7 @@ static int ac97_reset_wait(ac97_t *ac97, int timeout, int with_modem) | |||
1758 | if ((snd_ac97_read(ac97, AC97_REC_GAIN) & 0x7fff) == 0x0a05) | 1745 | if ((snd_ac97_read(ac97, AC97_REC_GAIN) & 0x7fff) == 0x0a05) |
1759 | return 0; | 1746 | return 0; |
1760 | } | 1747 | } |
1761 | set_current_state(TASK_UNINTERRUPTIBLE); | 1748 | schedule_timeout_uninterruptible(1); |
1762 | schedule_timeout(1); | ||
1763 | } while (time_after_eq(end_time, jiffies)); | 1749 | } while (time_after_eq(end_time, jiffies)); |
1764 | return -ENODEV; | 1750 | return -ENODEV; |
1765 | } | 1751 | } |
@@ -1889,21 +1875,6 @@ int snd_ac97_mixer(ac97_bus_t *bus, ac97_template_t *template, ac97_t **rac97) | |||
1889 | snd_assert(bus != NULL && template != NULL, return -EINVAL); | 1875 | snd_assert(bus != NULL && template != NULL, return -EINVAL); |
1890 | snd_assert(template->num < 4 && bus->codec[template->num] == NULL, return -EINVAL); | 1876 | snd_assert(template->num < 4 && bus->codec[template->num] == NULL, return -EINVAL); |
1891 | 1877 | ||
1892 | snd_assert(bus->shared_type <= AC97_SHARED_TYPES, return -EINVAL); | ||
1893 | if (bus->shared_type) { | ||
1894 | /* already shared? */ | ||
1895 | down(&shared_codec_mutex); | ||
1896 | ac97 = shared_codec[bus->shared_type-1][template->num]; | ||
1897 | if (ac97) { | ||
1898 | if ((ac97_is_audio(ac97) && (template->scaps & AC97_SCAP_SKIP_AUDIO)) || | ||
1899 | (ac97_is_modem(ac97) && (template->scaps & AC97_SCAP_SKIP_MODEM))) { | ||
1900 | up(&shared_codec_mutex); | ||
1901 | return -EACCES; /* skip this */ | ||
1902 | } | ||
1903 | } | ||
1904 | up(&shared_codec_mutex); | ||
1905 | } | ||
1906 | |||
1907 | card = bus->card; | 1878 | card = bus->card; |
1908 | ac97 = kzalloc(sizeof(*ac97), GFP_KERNEL); | 1879 | ac97 = kzalloc(sizeof(*ac97), GFP_KERNEL); |
1909 | if (ac97 == NULL) | 1880 | if (ac97 == NULL) |
@@ -2020,8 +1991,7 @@ int snd_ac97_mixer(ac97_bus_t *bus, ac97_template_t *template, ac97_t **rac97) | |||
2020 | do { | 1991 | do { |
2021 | if ((snd_ac97_read(ac97, AC97_POWERDOWN) & 0x0f) == 0x0f) | 1992 | if ((snd_ac97_read(ac97, AC97_POWERDOWN) & 0x0f) == 0x0f) |
2022 | goto __ready_ok; | 1993 | goto __ready_ok; |
2023 | set_current_state(TASK_UNINTERRUPTIBLE); | 1994 | schedule_timeout_uninterruptible(1); |
2024 | schedule_timeout(1); | ||
2025 | } while (time_after_eq(end_time, jiffies)); | 1995 | } while (time_after_eq(end_time, jiffies)); |
2026 | snd_printk(KERN_WARNING "AC'97 %d analog subsections not ready\n", ac97->num); | 1996 | snd_printk(KERN_WARNING "AC'97 %d analog subsections not ready\n", ac97->num); |
2027 | } | 1997 | } |
@@ -2053,8 +2023,7 @@ int snd_ac97_mixer(ac97_bus_t *bus, ac97_template_t *template, ac97_t **rac97) | |||
2053 | do { | 2023 | do { |
2054 | if ((snd_ac97_read(ac97, AC97_EXTENDED_MSTATUS) & tmp) == tmp) | 2024 | if ((snd_ac97_read(ac97, AC97_EXTENDED_MSTATUS) & tmp) == tmp) |
2055 | goto __ready_ok; | 2025 | goto __ready_ok; |
2056 | set_current_state(TASK_UNINTERRUPTIBLE); | 2026 | schedule_timeout_uninterruptible(1); |
2057 | schedule_timeout(1); | ||
2058 | } while (time_after_eq(end_time, jiffies)); | 2027 | } while (time_after_eq(end_time, jiffies)); |
2059 | snd_printk(KERN_WARNING "MC'97 %d converters and GPIO not ready (0x%x)\n", ac97->num, snd_ac97_read(ac97, AC97_EXTENDED_MSTATUS)); | 2028 | snd_printk(KERN_WARNING "MC'97 %d converters and GPIO not ready (0x%x)\n", ac97->num, snd_ac97_read(ac97, AC97_EXTENDED_MSTATUS)); |
2060 | } | 2029 | } |
@@ -2077,6 +2046,8 @@ int snd_ac97_mixer(ac97_bus_t *bus, ac97_template_t *template, ac97_t **rac97) | |||
2077 | snd_ac97_update_bits(ac97, AC97_GENERAL_PURPOSE, AC97_GP_DRSS_MASK, AC97_GP_DRSS_78); | 2046 | snd_ac97_update_bits(ac97, AC97_GENERAL_PURPOSE, AC97_GP_DRSS_MASK, AC97_GP_DRSS_78); |
2078 | if ((snd_ac97_read(ac97, AC97_GENERAL_PURPOSE) & AC97_GP_DRSS_MASK) == AC97_GP_DRSS_78) | 2047 | if ((snd_ac97_read(ac97, AC97_GENERAL_PURPOSE) & AC97_GP_DRSS_MASK) == AC97_GP_DRSS_78) |
2079 | ac97->flags |= AC97_DOUBLE_RATE; | 2048 | ac97->flags |= AC97_DOUBLE_RATE; |
2049 | /* restore to slots 10/11 to avoid the confliction with surrounds */ | ||
2050 | snd_ac97_update_bits(ac97, AC97_GENERAL_PURPOSE, AC97_GP_DRSS_MASK, 0); | ||
2080 | } | 2051 | } |
2081 | if (ac97->ext_id & AC97_EI_VRA) { /* VRA support */ | 2052 | if (ac97->ext_id & AC97_EI_VRA) { /* VRA support */ |
2082 | snd_ac97_determine_rates(ac97, AC97_PCM_FRONT_DAC_RATE, 0, &ac97->rates[AC97_RATES_FRONT_DAC]); | 2053 | snd_ac97_determine_rates(ac97, AC97_PCM_FRONT_DAC_RATE, 0, &ac97->rates[AC97_RATES_FRONT_DAC]); |
@@ -2153,7 +2124,7 @@ int snd_ac97_mixer(ac97_bus_t *bus, ac97_template_t *template, ac97_t **rac97) | |||
2153 | } | 2124 | } |
2154 | } | 2125 | } |
2155 | /* make sure the proper powerdown bits are cleared */ | 2126 | /* make sure the proper powerdown bits are cleared */ |
2156 | if (ac97->scaps) { | 2127 | if (ac97->scaps && ac97_is_audio(ac97)) { |
2157 | reg = snd_ac97_read(ac97, AC97_EXTENDED_STATUS); | 2128 | reg = snd_ac97_read(ac97, AC97_EXTENDED_STATUS); |
2158 | if (ac97->scaps & AC97_SCAP_SURROUND_DAC) | 2129 | if (ac97->scaps & AC97_SCAP_SURROUND_DAC) |
2159 | reg &= ~AC97_EA_PRJ; | 2130 | reg &= ~AC97_EA_PRJ; |
@@ -2167,13 +2138,6 @@ int snd_ac97_mixer(ac97_bus_t *bus, ac97_template_t *template, ac97_t **rac97) | |||
2167 | return err; | 2138 | return err; |
2168 | } | 2139 | } |
2169 | *rac97 = ac97; | 2140 | *rac97 = ac97; |
2170 | |||
2171 | if (bus->shared_type) { | ||
2172 | down(&shared_codec_mutex); | ||
2173 | shared_codec[bus->shared_type-1][ac97->num] = ac97; | ||
2174 | up(&shared_codec_mutex); | ||
2175 | } | ||
2176 | |||
2177 | return 0; | 2141 | return 0; |
2178 | } | 2142 | } |
2179 | 2143 | ||
@@ -2295,8 +2259,7 @@ void snd_ac97_resume(ac97_t *ac97) | |||
2295 | do { | 2259 | do { |
2296 | if (snd_ac97_read(ac97, AC97_MASTER) == 0x8101) | 2260 | if (snd_ac97_read(ac97, AC97_MASTER) == 0x8101) |
2297 | break; | 2261 | break; |
2298 | set_current_state(TASK_UNINTERRUPTIBLE); | 2262 | schedule_timeout_uninterruptible(1); |
2299 | schedule_timeout(1); | ||
2300 | } while (time_after_eq(end_time, jiffies)); | 2263 | } while (time_after_eq(end_time, jiffies)); |
2301 | /* FIXME: extra delay */ | 2264 | /* FIXME: extra delay */ |
2302 | ac97->bus->ops->write(ac97, AC97_MASTER, 0x8000); | 2265 | ac97->bus->ops->write(ac97, AC97_MASTER, 0x8000); |
@@ -2308,8 +2271,7 @@ void snd_ac97_resume(ac97_t *ac97) | |||
2308 | unsigned short val = snd_ac97_read(ac97, AC97_EXTENDED_MID); | 2271 | unsigned short val = snd_ac97_read(ac97, AC97_EXTENDED_MID); |
2309 | if (val != 0xffff && (val & 1) != 0) | 2272 | if (val != 0xffff && (val & 1) != 0) |
2310 | break; | 2273 | break; |
2311 | set_current_state(TASK_UNINTERRUPTIBLE); | 2274 | schedule_timeout_uninterruptible(1); |
2312 | schedule_timeout(1); | ||
2313 | } while (time_after_eq(end_time, jiffies)); | 2275 | } while (time_after_eq(end_time, jiffies)); |
2314 | } | 2276 | } |
2315 | __reset_ready: | 2277 | __reset_ready: |