aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/ac97/ac97_codec.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/ac97/ac97_codec.c')
-rw-r--r--sound/pci/ac97/ac97_codec.c56
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 */
226static DECLARE_MUTEX(shared_codec_mutex);
227static 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: