diff options
Diffstat (limited to 'sound')
-rw-r--r-- | sound/isa/es18xx.c | 91 |
1 files changed, 41 insertions, 50 deletions
diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c index 5cf42b4d65fd..06e871e66c97 100644 --- a/sound/isa/es18xx.c +++ b/sound/isa/es18xx.c | |||
@@ -102,8 +102,6 @@ | |||
102 | 102 | ||
103 | struct snd_es18xx { | 103 | struct snd_es18xx { |
104 | unsigned long port; /* port of ESS chip */ | 104 | unsigned long port; /* port of ESS chip */ |
105 | unsigned long mpu_port; /* MPU-401 port of ESS chip */ | ||
106 | unsigned long fm_port; /* FM port */ | ||
107 | unsigned long ctrl_port; /* Control port of ESS chip */ | 105 | unsigned long ctrl_port; /* Control port of ESS chip */ |
108 | struct resource *res_port; | 106 | struct resource *res_port; |
109 | struct resource *res_mpu_port; | 107 | struct resource *res_mpu_port; |
@@ -116,8 +114,6 @@ struct snd_es18xx { | |||
116 | unsigned short audio2_vol; /* volume level of audio2 */ | 114 | unsigned short audio2_vol; /* volume level of audio2 */ |
117 | 115 | ||
118 | unsigned short active; /* active channel mask */ | 116 | unsigned short active; /* active channel mask */ |
119 | unsigned int dma1_size; | ||
120 | unsigned int dma2_size; | ||
121 | unsigned int dma1_shift; | 117 | unsigned int dma1_shift; |
122 | unsigned int dma2_shift; | 118 | unsigned int dma2_shift; |
123 | 119 | ||
@@ -135,7 +131,6 @@ struct snd_es18xx { | |||
135 | 131 | ||
136 | spinlock_t reg_lock; | 132 | spinlock_t reg_lock; |
137 | spinlock_t mixer_lock; | 133 | spinlock_t mixer_lock; |
138 | spinlock_t ctrl_lock; | ||
139 | #ifdef CONFIG_PM | 134 | #ifdef CONFIG_PM |
140 | unsigned char pm_reg; | 135 | unsigned char pm_reg; |
141 | #endif | 136 | #endif |
@@ -354,7 +349,7 @@ static inline int snd_es18xx_mixer_writable(struct snd_es18xx *chip, unsigned ch | |||
354 | } | 349 | } |
355 | 350 | ||
356 | 351 | ||
357 | static int snd_es18xx_reset(struct snd_es18xx *chip) | 352 | static int __devinit snd_es18xx_reset(struct snd_es18xx *chip) |
358 | { | 353 | { |
359 | int i; | 354 | int i; |
360 | outb(0x03, chip->port + 0x06); | 355 | outb(0x03, chip->port + 0x06); |
@@ -490,8 +485,6 @@ static int snd_es18xx_playback1_prepare(struct snd_es18xx *chip, | |||
490 | unsigned int size = snd_pcm_lib_buffer_bytes(substream); | 485 | unsigned int size = snd_pcm_lib_buffer_bytes(substream); |
491 | unsigned int count = snd_pcm_lib_period_bytes(substream); | 486 | unsigned int count = snd_pcm_lib_period_bytes(substream); |
492 | 487 | ||
493 | chip->dma2_size = size; | ||
494 | |||
495 | snd_es18xx_rate_set(chip, substream, DAC2); | 488 | snd_es18xx_rate_set(chip, substream, DAC2); |
496 | 489 | ||
497 | /* Transfer Count Reload */ | 490 | /* Transfer Count Reload */ |
@@ -591,8 +584,6 @@ static int snd_es18xx_capture_prepare(struct snd_pcm_substream *substream) | |||
591 | unsigned int size = snd_pcm_lib_buffer_bytes(substream); | 584 | unsigned int size = snd_pcm_lib_buffer_bytes(substream); |
592 | unsigned int count = snd_pcm_lib_period_bytes(substream); | 585 | unsigned int count = snd_pcm_lib_period_bytes(substream); |
593 | 586 | ||
594 | chip->dma1_size = size; | ||
595 | |||
596 | snd_es18xx_reset_fifo(chip); | 587 | snd_es18xx_reset_fifo(chip); |
597 | 588 | ||
598 | /* Set stereo/mono */ | 589 | /* Set stereo/mono */ |
@@ -659,8 +650,6 @@ static int snd_es18xx_playback2_prepare(struct snd_es18xx *chip, | |||
659 | unsigned int size = snd_pcm_lib_buffer_bytes(substream); | 650 | unsigned int size = snd_pcm_lib_buffer_bytes(substream); |
660 | unsigned int count = snd_pcm_lib_period_bytes(substream); | 651 | unsigned int count = snd_pcm_lib_period_bytes(substream); |
661 | 652 | ||
662 | chip->dma1_size = size; | ||
663 | |||
664 | snd_es18xx_reset_fifo(chip); | 653 | snd_es18xx_reset_fifo(chip); |
665 | 654 | ||
666 | /* Set stereo/mono */ | 655 | /* Set stereo/mono */ |
@@ -821,17 +810,18 @@ static irqreturn_t snd_es18xx_interrupt(int irq, void *dev_id) | |||
821 | static snd_pcm_uframes_t snd_es18xx_playback_pointer(struct snd_pcm_substream *substream) | 810 | static snd_pcm_uframes_t snd_es18xx_playback_pointer(struct snd_pcm_substream *substream) |
822 | { | 811 | { |
823 | struct snd_es18xx *chip = snd_pcm_substream_chip(substream); | 812 | struct snd_es18xx *chip = snd_pcm_substream_chip(substream); |
813 | unsigned int size = snd_pcm_lib_buffer_bytes(substream); | ||
824 | int pos; | 814 | int pos; |
825 | 815 | ||
826 | if (substream->number == 0 && (chip->caps & ES18XX_PCM2)) { | 816 | if (substream->number == 0 && (chip->caps & ES18XX_PCM2)) { |
827 | if (!(chip->active & DAC2)) | 817 | if (!(chip->active & DAC2)) |
828 | return 0; | 818 | return 0; |
829 | pos = snd_dma_pointer(chip->dma2, chip->dma2_size); | 819 | pos = snd_dma_pointer(chip->dma2, size); |
830 | return pos >> chip->dma2_shift; | 820 | return pos >> chip->dma2_shift; |
831 | } else { | 821 | } else { |
832 | if (!(chip->active & DAC1)) | 822 | if (!(chip->active & DAC1)) |
833 | return 0; | 823 | return 0; |
834 | pos = snd_dma_pointer(chip->dma1, chip->dma1_size); | 824 | pos = snd_dma_pointer(chip->dma1, size); |
835 | return pos >> chip->dma1_shift; | 825 | return pos >> chip->dma1_shift; |
836 | } | 826 | } |
837 | } | 827 | } |
@@ -839,11 +829,12 @@ static snd_pcm_uframes_t snd_es18xx_playback_pointer(struct snd_pcm_substream *s | |||
839 | static snd_pcm_uframes_t snd_es18xx_capture_pointer(struct snd_pcm_substream *substream) | 829 | static snd_pcm_uframes_t snd_es18xx_capture_pointer(struct snd_pcm_substream *substream) |
840 | { | 830 | { |
841 | struct snd_es18xx *chip = snd_pcm_substream_chip(substream); | 831 | struct snd_es18xx *chip = snd_pcm_substream_chip(substream); |
832 | unsigned int size = snd_pcm_lib_buffer_bytes(substream); | ||
842 | int pos; | 833 | int pos; |
843 | 834 | ||
844 | if (!(chip->active & ADC1)) | 835 | if (!(chip->active & ADC1)) |
845 | return 0; | 836 | return 0; |
846 | pos = snd_dma_pointer(chip->dma1, chip->dma1_size); | 837 | pos = snd_dma_pointer(chip->dma1, size); |
847 | return pos >> chip->dma1_shift; | 838 | return pos >> chip->dma1_shift; |
848 | } | 839 | } |
849 | 840 | ||
@@ -974,9 +965,6 @@ static int snd_es18xx_capture_close(struct snd_pcm_substream *substream) | |||
974 | 965 | ||
975 | static int snd_es18xx_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 966 | static int snd_es18xx_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
976 | { | 967 | { |
977 | static char *texts4Source[4] = { | ||
978 | "Mic", "CD", "Line", "Master" | ||
979 | }; | ||
980 | static char *texts5Source[5] = { | 968 | static char *texts5Source[5] = { |
981 | "Mic", "CD", "Line", "Master", "Mix" | 969 | "Mic", "CD", "Line", "Master", "Mix" |
982 | }; | 970 | }; |
@@ -994,7 +982,8 @@ static int snd_es18xx_info_mux(struct snd_kcontrol *kcontrol, struct snd_ctl_ele | |||
994 | uinfo->value.enumerated.items = 4; | 982 | uinfo->value.enumerated.items = 4; |
995 | if (uinfo->value.enumerated.item > 3) | 983 | if (uinfo->value.enumerated.item > 3) |
996 | uinfo->value.enumerated.item = 3; | 984 | uinfo->value.enumerated.item = 3; |
997 | strcpy(uinfo->value.enumerated.name, texts4Source[uinfo->value.enumerated.item]); | 985 | strcpy(uinfo->value.enumerated.name, |
986 | texts5Source[uinfo->value.enumerated.item]); | ||
998 | break; | 987 | break; |
999 | case 0x1887: | 988 | case 0x1887: |
1000 | case 0x1888: | 989 | case 0x1888: |
@@ -1378,11 +1367,9 @@ ES18XX_SINGLE("Hardware Master Volume Split", 0, 0x64, 7, 1, 0), | |||
1378 | static int __devinit snd_es18xx_config_read(struct snd_es18xx *chip, unsigned char reg) | 1367 | static int __devinit snd_es18xx_config_read(struct snd_es18xx *chip, unsigned char reg) |
1379 | { | 1368 | { |
1380 | int data; | 1369 | int data; |
1381 | unsigned long flags; | 1370 | |
1382 | spin_lock_irqsave(&chip->ctrl_lock, flags); | ||
1383 | outb(reg, chip->ctrl_port); | 1371 | outb(reg, chip->ctrl_port); |
1384 | data = inb(chip->ctrl_port + 1); | 1372 | data = inb(chip->ctrl_port + 1); |
1385 | spin_unlock_irqrestore(&chip->ctrl_lock, flags); | ||
1386 | return data; | 1373 | return data; |
1387 | } | 1374 | } |
1388 | 1375 | ||
@@ -1398,7 +1385,9 @@ static void __devinit snd_es18xx_config_write(struct snd_es18xx *chip, | |||
1398 | #endif | 1385 | #endif |
1399 | } | 1386 | } |
1400 | 1387 | ||
1401 | static int __devinit snd_es18xx_initialize(struct snd_es18xx *chip) | 1388 | static int __devinit snd_es18xx_initialize(struct snd_es18xx *chip, |
1389 | unsigned long mpu_port, | ||
1390 | unsigned long fm_port) | ||
1402 | { | 1391 | { |
1403 | int mask = 0; | 1392 | int mask = 0; |
1404 | 1393 | ||
@@ -1412,15 +1401,15 @@ static int __devinit snd_es18xx_initialize(struct snd_es18xx *chip) | |||
1412 | if (chip->caps & ES18XX_CONTROL) { | 1401 | if (chip->caps & ES18XX_CONTROL) { |
1413 | /* Hardware volume IRQ */ | 1402 | /* Hardware volume IRQ */ |
1414 | snd_es18xx_config_write(chip, 0x27, chip->irq); | 1403 | snd_es18xx_config_write(chip, 0x27, chip->irq); |
1415 | if (chip->fm_port > 0 && chip->fm_port != SNDRV_AUTO_PORT) { | 1404 | if (fm_port > 0 && fm_port != SNDRV_AUTO_PORT) { |
1416 | /* FM I/O */ | 1405 | /* FM I/O */ |
1417 | snd_es18xx_config_write(chip, 0x62, chip->fm_port >> 8); | 1406 | snd_es18xx_config_write(chip, 0x62, fm_port >> 8); |
1418 | snd_es18xx_config_write(chip, 0x63, chip->fm_port & 0xff); | 1407 | snd_es18xx_config_write(chip, 0x63, fm_port & 0xff); |
1419 | } | 1408 | } |
1420 | if (chip->mpu_port > 0 && chip->mpu_port != SNDRV_AUTO_PORT) { | 1409 | if (mpu_port > 0 && mpu_port != SNDRV_AUTO_PORT) { |
1421 | /* MPU-401 I/O */ | 1410 | /* MPU-401 I/O */ |
1422 | snd_es18xx_config_write(chip, 0x64, chip->mpu_port >> 8); | 1411 | snd_es18xx_config_write(chip, 0x64, mpu_port >> 8); |
1423 | snd_es18xx_config_write(chip, 0x65, chip->mpu_port & 0xff); | 1412 | snd_es18xx_config_write(chip, 0x65, mpu_port & 0xff); |
1424 | /* MPU-401 IRQ */ | 1413 | /* MPU-401 IRQ */ |
1425 | snd_es18xx_config_write(chip, 0x28, chip->irq); | 1414 | snd_es18xx_config_write(chip, 0x28, chip->irq); |
1426 | } | 1415 | } |
@@ -1507,11 +1496,12 @@ static int __devinit snd_es18xx_initialize(struct snd_es18xx *chip) | |||
1507 | snd_es18xx_mixer_write(chip, 0x7A, 0x68); | 1496 | snd_es18xx_mixer_write(chip, 0x7A, 0x68); |
1508 | /* Enable and set hardware volume interrupt */ | 1497 | /* Enable and set hardware volume interrupt */ |
1509 | snd_es18xx_mixer_write(chip, 0x64, 0x06); | 1498 | snd_es18xx_mixer_write(chip, 0x64, 0x06); |
1510 | if (chip->mpu_port > 0 && chip->mpu_port != SNDRV_AUTO_PORT) { | 1499 | if (mpu_port > 0 && mpu_port != SNDRV_AUTO_PORT) { |
1511 | /* MPU401 share irq with audio | 1500 | /* MPU401 share irq with audio |
1512 | Joystick enabled | 1501 | Joystick enabled |
1513 | FM enabled */ | 1502 | FM enabled */ |
1514 | snd_es18xx_mixer_write(chip, 0x40, 0x43 | (chip->mpu_port & 0xf0) >> 1); | 1503 | snd_es18xx_mixer_write(chip, 0x40, |
1504 | 0x43 | (mpu_port & 0xf0) >> 1); | ||
1515 | } | 1505 | } |
1516 | snd_es18xx_mixer_write(chip, 0x7f, ((irqmask + 1) << 1) | 0x01); | 1506 | snd_es18xx_mixer_write(chip, 0x7f, ((irqmask + 1) << 1) | 0x01); |
1517 | } | 1507 | } |
@@ -1629,7 +1619,9 @@ static int __devinit snd_es18xx_identify(struct snd_es18xx *chip) | |||
1629 | return 0; | 1619 | return 0; |
1630 | } | 1620 | } |
1631 | 1621 | ||
1632 | static int __devinit snd_es18xx_probe(struct snd_es18xx *chip) | 1622 | static int __devinit snd_es18xx_probe(struct snd_es18xx *chip, |
1623 | unsigned long mpu_port, | ||
1624 | unsigned long fm_port) | ||
1633 | { | 1625 | { |
1634 | if (snd_es18xx_identify(chip) < 0) { | 1626 | if (snd_es18xx_identify(chip) < 0) { |
1635 | snd_printk(KERN_ERR PFX "[0x%lx] ESS chip not found\n", chip->port); | 1627 | snd_printk(KERN_ERR PFX "[0x%lx] ESS chip not found\n", chip->port); |
@@ -1650,8 +1642,6 @@ static int __devinit snd_es18xx_probe(struct snd_es18xx *chip) | |||
1650 | chip->caps = ES18XX_PCM2 | ES18XX_SPATIALIZER | ES18XX_RECMIX | ES18XX_NEW_RATE | ES18XX_AUXB | ES18XX_I2S | ES18XX_CONTROL | ES18XX_HWV; | 1642 | chip->caps = ES18XX_PCM2 | ES18XX_SPATIALIZER | ES18XX_RECMIX | ES18XX_NEW_RATE | ES18XX_AUXB | ES18XX_I2S | ES18XX_CONTROL | ES18XX_HWV; |
1651 | break; | 1643 | break; |
1652 | case 0x1887: | 1644 | case 0x1887: |
1653 | chip->caps = ES18XX_PCM2 | ES18XX_RECMIX | ES18XX_AUXB | ES18XX_DUPLEX_SAME; | ||
1654 | break; | ||
1655 | case 0x1888: | 1645 | case 0x1888: |
1656 | chip->caps = ES18XX_PCM2 | ES18XX_RECMIX | ES18XX_AUXB | ES18XX_DUPLEX_SAME; | 1646 | chip->caps = ES18XX_PCM2 | ES18XX_RECMIX | ES18XX_AUXB | ES18XX_DUPLEX_SAME; |
1657 | break; | 1647 | break; |
@@ -1666,7 +1656,7 @@ static int __devinit snd_es18xx_probe(struct snd_es18xx *chip) | |||
1666 | if (chip->dma1 == chip->dma2) | 1656 | if (chip->dma1 == chip->dma2) |
1667 | chip->caps &= ~(ES18XX_PCM2 | ES18XX_DUPLEX_SAME); | 1657 | chip->caps &= ~(ES18XX_PCM2 | ES18XX_DUPLEX_SAME); |
1668 | 1658 | ||
1669 | return snd_es18xx_initialize(chip); | 1659 | return snd_es18xx_initialize(chip, mpu_port, fm_port); |
1670 | } | 1660 | } |
1671 | 1661 | ||
1672 | static struct snd_pcm_ops snd_es18xx_playback_ops = { | 1662 | static struct snd_pcm_ops snd_es18xx_playback_ops = { |
@@ -1802,10 +1792,7 @@ static int __devinit snd_es18xx_new_device(struct snd_card *card, | |||
1802 | 1792 | ||
1803 | spin_lock_init(&chip->reg_lock); | 1793 | spin_lock_init(&chip->reg_lock); |
1804 | spin_lock_init(&chip->mixer_lock); | 1794 | spin_lock_init(&chip->mixer_lock); |
1805 | spin_lock_init(&chip->ctrl_lock); | ||
1806 | chip->port = port; | 1795 | chip->port = port; |
1807 | chip->mpu_port = mpu_port; | ||
1808 | chip->fm_port = fm_port; | ||
1809 | chip->irq = -1; | 1796 | chip->irq = -1; |
1810 | chip->dma1 = -1; | 1797 | chip->dma1 = -1; |
1811 | chip->dma2 = -1; | 1798 | chip->dma2 = -1; |
@@ -1841,11 +1828,11 @@ static int __devinit snd_es18xx_new_device(struct snd_card *card, | |||
1841 | } | 1828 | } |
1842 | chip->dma2 = dma2; | 1829 | chip->dma2 = dma2; |
1843 | 1830 | ||
1844 | if (snd_es18xx_probe(chip) < 0) { | 1831 | if (snd_es18xx_probe(chip, mpu_port, fm_port) < 0) { |
1845 | snd_es18xx_free(card); | 1832 | snd_es18xx_free(card); |
1846 | return -ENODEV; | 1833 | return -ENODEV; |
1847 | } | 1834 | } |
1848 | err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, NULL, &ops); | 1835 | err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); |
1849 | if (err < 0) { | 1836 | if (err < 0) { |
1850 | snd_es18xx_free(card); | 1837 | snd_es18xx_free(card); |
1851 | return err; | 1838 | return err; |
@@ -1980,7 +1967,7 @@ static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ | |||
1980 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ | 1967 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ |
1981 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */ | 1968 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; /* Enable this card */ |
1982 | #ifdef CONFIG_PNP | 1969 | #ifdef CONFIG_PNP |
1983 | static int isapnp[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 1}; | 1970 | static int isapnp[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_ISAPNP; |
1984 | #endif | 1971 | #endif |
1985 | static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260,0x280 */ | 1972 | static long port[SNDRV_CARDS] = SNDRV_DEFAULT_PORT; /* 0x220,0x240,0x260,0x280 */ |
1986 | #ifndef CONFIG_PNP | 1973 | #ifndef CONFIG_PNP |
@@ -2160,19 +2147,23 @@ static int __devinit snd_audiodrive_probe(struct snd_card *card, int dev) | |||
2160 | return err; | 2147 | return err; |
2161 | 2148 | ||
2162 | if (fm_port[dev] > 0 && fm_port[dev] != SNDRV_AUTO_PORT) { | 2149 | if (fm_port[dev] > 0 && fm_port[dev] != SNDRV_AUTO_PORT) { |
2163 | if (snd_opl3_create(card, chip->fm_port, chip->fm_port + 2, OPL3_HW_OPL3, 0, &opl3) < 0) { | 2150 | if (snd_opl3_create(card, fm_port[dev], fm_port[dev] + 2, |
2164 | snd_printk(KERN_WARNING PFX "opl3 not detected at 0x%lx\n", chip->fm_port); | 2151 | OPL3_HW_OPL3, 0, &opl3) < 0) { |
2152 | snd_printk(KERN_WARNING PFX | ||
2153 | "opl3 not detected at 0x%lx\n", | ||
2154 | fm_port[dev]); | ||
2165 | } else { | 2155 | } else { |
2166 | if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) | 2156 | err = snd_opl3_hwdep_new(opl3, 0, 1, NULL); |
2157 | if (err < 0) | ||
2167 | return err; | 2158 | return err; |
2168 | } | 2159 | } |
2169 | } | 2160 | } |
2170 | 2161 | ||
2171 | if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) { | 2162 | if (mpu_port[dev] > 0 && mpu_port[dev] != SNDRV_AUTO_PORT) { |
2172 | if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_ES18XX, | 2163 | err = snd_mpu401_uart_new(card, 0, MPU401_HW_ES18XX, |
2173 | chip->mpu_port, 0, | 2164 | mpu_port[dev], 0, |
2174 | irq[dev], 0, | 2165 | irq[dev], 0, &chip->rmidi); |
2175 | &chip->rmidi)) < 0) | 2166 | if (err < 0) |
2176 | return err; | 2167 | return err; |
2177 | } | 2168 | } |
2178 | 2169 | ||