aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorAndreas Mohr <andi@lisas.de>2006-03-28 05:56:14 -0500
committerJaroslav Kysela <perex@suse.cz>2006-03-31 10:59:00 -0500
commit0b2dcd5d6a9a3e27fdd67053e526388f9f2ea33b (patch)
treed380fb45aa120b2499aa03753717f3ecbf0ad099 /sound/pci
parenta1e8d2da03b3a1017aab01d49666ec9b67927de5 (diff)
[ALSA] maestro3.c: fix BUG, optimization
- fix brown-paper-bag locking bug (lock() / return / unlock()) - improve central function snd_m3_update_ptr() (avoid expensive integer divisions) - add cpu_relax() to busy-wait I/O loop as recommended (does this require special macro support in ALSA for older kernels??) - constify several structs - spelling updates Signed-off-by: Andreas Mohr <andi@lisas.de> Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/maestro3.c57
1 files changed, 37 insertions, 20 deletions
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c
index 44393e190929..9c90d901e6b9 100644
--- a/sound/pci/maestro3.c
+++ b/sound/pci/maestro3.c
@@ -831,8 +831,8 @@ struct snd_m3 {
831 struct snd_pcm *pcm; 831 struct snd_pcm *pcm;
832 832
833 struct pci_dev *pci; 833 struct pci_dev *pci;
834 struct m3_quirk *quirk; 834 const struct m3_quirk *quirk;
835 struct m3_hv_quirk *hv_quirk; 835 const struct m3_hv_quirk *hv_quirk;
836 836
837 int dacs_active; 837 int dacs_active;
838 int timer_users; 838 int timer_users;
@@ -892,7 +892,7 @@ static struct pci_device_id snd_m3_ids[] = {
892 892
893MODULE_DEVICE_TABLE(pci, snd_m3_ids); 893MODULE_DEVICE_TABLE(pci, snd_m3_ids);
894 894
895static struct m3_quirk m3_quirk_list[] = { 895static const struct m3_quirk m3_quirk_list[] = {
896 /* panasonic CF-28 "toughbook" */ 896 /* panasonic CF-28 "toughbook" */
897 { 897 {
898 .name = "Panasonic CF-28", 898 .name = "Panasonic CF-28",
@@ -950,7 +950,7 @@ static struct m3_quirk m3_quirk_list[] = {
950}; 950};
951 951
952/* These values came from the Windows driver. */ 952/* These values came from the Windows driver. */
953static struct m3_hv_quirk m3_hv_quirk_list[] = { 953static const struct m3_hv_quirk m3_hv_quirk_list[] = {
954 /* Allegro chips */ 954 /* Allegro chips */
955 { 0x125D, 0x1988, 0x0E11, 0x002E, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, 955 { 0x125D, 0x1988, 0x0E11, 0x002E, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
956 { 0x125D, 0x1988, 0x0E11, 0x0094, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 }, 956 { 0x125D, 0x1988, 0x0E11, 0x0094, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
@@ -1361,7 +1361,7 @@ static void snd_m3_pcm_setup2(struct snd_m3 *chip, struct m3_dma *s,
1361} 1361}
1362 1362
1363 1363
1364static struct play_vals { 1364static const struct play_vals {
1365 u16 addr, val; 1365 u16 addr, val;
1366} pv[] = { 1366} pv[] = {
1367 {CDATA_LEFT_VOLUME, ARB_VOLUME}, 1367 {CDATA_LEFT_VOLUME, ARB_VOLUME},
@@ -1428,7 +1428,7 @@ snd_m3_playback_setup(struct snd_m3 *chip, struct m3_dma *s,
1428/* 1428/*
1429 * Native record driver 1429 * Native record driver
1430 */ 1430 */
1431static struct rec_vals { 1431static const struct rec_vals {
1432 u16 addr, val; 1432 u16 addr, val;
1433} rv[] = { 1433} rv[] = {
1434 {CDATA_LEFT_VOLUME, ARB_VOLUME}, 1434 {CDATA_LEFT_VOLUME, ARB_VOLUME},
@@ -1598,12 +1598,26 @@ static void snd_m3_update_ptr(struct snd_m3 *chip, struct m3_dma *s)
1598 if (! s->running) 1598 if (! s->running)
1599 return; 1599 return;
1600 1600
1601 hwptr = snd_m3_get_pointer(chip, s, subs) % s->dma_size; 1601 hwptr = snd_m3_get_pointer(chip, s, subs);
1602 diff = (s->dma_size + hwptr - s->hwptr) % s->dma_size; 1602
1603 /* try to avoid expensive modulo divisions */
1604 if (hwptr >= s->dma_size)
1605 hwptr %= s->dma_size;
1606
1607 diff = s->dma_size + hwptr - s->hwptr;
1608 if (diff >= s->dma_size)
1609 diff %= s->dma_size;
1610
1603 s->hwptr = hwptr; 1611 s->hwptr = hwptr;
1604 s->count += diff; 1612 s->count += diff;
1613
1605 if (s->count >= (signed)s->period_size) { 1614 if (s->count >= (signed)s->period_size) {
1606 s->count %= s->period_size; 1615
1616 if (s->count < 2 * (signed)s->period_size)
1617 s->count -= (signed)s->period_size;
1618 else
1619 s->count %= s->period_size;
1620
1607 spin_unlock(&chip->reg_lock); 1621 spin_unlock(&chip->reg_lock);
1608 snd_pcm_period_elapsed(subs); 1622 snd_pcm_period_elapsed(subs);
1609 spin_lock(&chip->reg_lock); 1623 spin_lock(&chip->reg_lock);
@@ -1942,6 +1956,7 @@ static int snd_m3_ac97_wait(struct snd_m3 *chip)
1942 do { 1956 do {
1943 if (! (snd_m3_inb(chip, 0x30) & 1)) 1957 if (! (snd_m3_inb(chip, 0x30) & 1))
1944 return 0; 1958 return 0;
1959 cpu_relax();
1945 } while (i-- > 0); 1960 } while (i-- > 0);
1946 1961
1947 snd_printk(KERN_ERR "ac97 serial bus busy\n"); 1962 snd_printk(KERN_ERR "ac97 serial bus busy\n");
@@ -1953,16 +1968,18 @@ snd_m3_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
1953{ 1968{
1954 struct snd_m3 *chip = ac97->private_data; 1969 struct snd_m3 *chip = ac97->private_data;
1955 unsigned long flags; 1970 unsigned long flags;
1956 unsigned short data; 1971 unsigned short data = 0xffff;
1957 1972
1958 if (snd_m3_ac97_wait(chip)) 1973 if (snd_m3_ac97_wait(chip))
1959 return 0xffff; 1974 goto fail;
1960 spin_lock_irqsave(&chip->ac97_lock, flags); 1975 spin_lock_irqsave(&chip->ac97_lock, flags);
1961 snd_m3_outb(chip, 0x80 | (reg & 0x7f), CODEC_COMMAND); 1976 snd_m3_outb(chip, 0x80 | (reg & 0x7f), CODEC_COMMAND);
1962 if (snd_m3_ac97_wait(chip)) 1977 if (snd_m3_ac97_wait(chip))
1963 return 0xffff; 1978 goto fail_unlock;
1964 data = snd_m3_inw(chip, CODEC_DATA); 1979 data = snd_m3_inw(chip, CODEC_DATA);
1980fail_unlock:
1965 spin_unlock_irqrestore(&chip->ac97_lock, flags); 1981 spin_unlock_irqrestore(&chip->ac97_lock, flags);
1982fail:
1966 return data; 1983 return data;
1967} 1984}
1968 1985
@@ -2121,7 +2138,7 @@ static int __devinit snd_m3_mixer(struct snd_m3 *chip)
2121 * DSP Code images 2138 * DSP Code images
2122 */ 2139 */
2123 2140
2124static u16 assp_kernel_image[] __devinitdata = { 2141static const u16 assp_kernel_image[] __devinitdata = {
2125 0x7980, 0x0030, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x00FB, 0x7980, 0x00DD, 0x7980, 0x03B4, 2142 0x7980, 0x0030, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x00FB, 0x7980, 0x00DD, 0x7980, 0x03B4,
2126 0x7980, 0x0332, 0x7980, 0x0287, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4, 2143 0x7980, 0x0332, 0x7980, 0x0287, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4,
2127 0x7980, 0x031A, 0x7980, 0x03B4, 0x7980, 0x022F, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4, 2144 0x7980, 0x031A, 0x7980, 0x03B4, 0x7980, 0x022F, 0x7980, 0x03B4, 0x7980, 0x03B4, 0x7980, 0x03B4,
@@ -2208,7 +2225,7 @@ static u16 assp_kernel_image[] __devinitdata = {
2208 * Mini sample rate converter code image 2225 * Mini sample rate converter code image
2209 * that is to be loaded at 0x400 on the DSP. 2226 * that is to be loaded at 0x400 on the DSP.
2210 */ 2227 */
2211static u16 assp_minisrc_image[] __devinitdata = { 2228static const u16 assp_minisrc_image[] __devinitdata = {
2212 2229
2213 0xBF80, 0x101E, 0x906E, 0x006E, 0x8B88, 0x6980, 0xEF88, 0x906F, 0x0D6F, 0x6900, 0xEB08, 0x0412, 2230 0xBF80, 0x101E, 0x906E, 0x006E, 0x8B88, 0x6980, 0xEF88, 0x906F, 0x0D6F, 0x6900, 0xEB08, 0x0412,
2214 0xBC20, 0x696E, 0xB801, 0x906E, 0x7980, 0x0403, 0xB90E, 0x8807, 0xBE43, 0xBF01, 0xBE47, 0xBE41, 2231 0xBC20, 0x696E, 0xB801, 0x906E, 0x7980, 0x0403, 0xB90E, 0x8807, 0xBE43, 0xBF01, 0xBE47, 0xBE41,
@@ -2251,7 +2268,7 @@ static u16 assp_minisrc_image[] __devinitdata = {
2251 */ 2268 */
2252 2269
2253#define MINISRC_LPF_LEN 10 2270#define MINISRC_LPF_LEN 10
2254static u16 minisrc_lpf[MINISRC_LPF_LEN] __devinitdata = { 2271static const u16 minisrc_lpf[MINISRC_LPF_LEN] __devinitdata = {
2255 0X0743, 0X1104, 0X0A4C, 0XF88D, 0X242C, 2272 0X0743, 0X1104, 0X0A4C, 0XF88D, 0X242C,
2256 0X1023, 0X1AA9, 0X0B60, 0XEFDD, 0X186F 2273 0X1023, 0X1AA9, 0X0B60, 0XEFDD, 0X186F
2257}; 2274};
@@ -2358,7 +2375,7 @@ static int __devinit snd_m3_assp_client_init(struct snd_m3 *chip, struct m3_dma
2358 */ 2375 */
2359 2376
2360 /* 2377 /*
2361 * align instance address to 256 bytes so that it's 2378 * align instance address to 256 bytes so that its
2362 * shifted list address is aligned. 2379 * shifted list address is aligned.
2363 * list address = (mem address >> 1) >> 7; 2380 * list address = (mem address >> 1) >> 7;
2364 */ 2381 */
@@ -2647,8 +2664,8 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci,
2647{ 2664{
2648 struct snd_m3 *chip; 2665 struct snd_m3 *chip;
2649 int i, err; 2666 int i, err;
2650 struct m3_quirk *quirk; 2667 const struct m3_quirk *quirk;
2651 struct m3_hv_quirk *hv_quirk; 2668 const struct m3_hv_quirk *hv_quirk;
2652 static struct snd_device_ops ops = { 2669 static struct snd_device_ops ops = {
2653 .dev_free = snd_m3_dev_free, 2670 .dev_free = snd_m3_dev_free,
2654 }; 2671 };
@@ -2843,12 +2860,12 @@ snd_m3_probe(struct pci_dev *pci, const struct pci_device_id *pci_id)
2843 } 2860 }
2844 2861
2845#if 0 /* TODO: not supported yet */ 2862#if 0 /* TODO: not supported yet */
2846 /* TODO enable midi irq and i/o */ 2863 /* TODO enable MIDI IRQ and I/O */
2847 err = snd_mpu401_uart_new(chip->card, 0, MPU401_HW_MPU401, 2864 err = snd_mpu401_uart_new(chip->card, 0, MPU401_HW_MPU401,
2848 chip->iobase + MPU401_DATA_PORT, 1, 2865 chip->iobase + MPU401_DATA_PORT, 1,
2849 chip->irq, 0, &chip->rmidi); 2866 chip->irq, 0, &chip->rmidi);
2850 if (err < 0) 2867 if (err < 0)
2851 printk(KERN_WARNING "maestro3: no midi support.\n"); 2868 printk(KERN_WARNING "maestro3: no MIDI support.\n");
2852#endif 2869#endif
2853 2870
2854 pci_set_drvdata(pci, card); 2871 pci_set_drvdata(pci, card);