diff options
Diffstat (limited to 'sound/sparc/dbri.c')
-rw-r--r-- | sound/sparc/dbri.c | 96 |
1 files changed, 44 insertions, 52 deletions
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c index bfc3930a6465..12d11fc5f825 100644 --- a/sound/sparc/dbri.c +++ b/sound/sparc/dbri.c | |||
@@ -233,12 +233,12 @@ static struct { | |||
233 | ****************************************************************************/ | 233 | ****************************************************************************/ |
234 | 234 | ||
235 | /* DBRI main registers */ | 235 | /* DBRI main registers */ |
236 | #define REG0 0x00UL /* Status and Control */ | 236 | #define REG0 0x00 /* Status and Control */ |
237 | #define REG1 0x04UL /* Mode and Interrupt */ | 237 | #define REG1 0x04 /* Mode and Interrupt */ |
238 | #define REG2 0x08UL /* Parallel IO */ | 238 | #define REG2 0x08 /* Parallel IO */ |
239 | #define REG3 0x0cUL /* Test */ | 239 | #define REG3 0x0c /* Test */ |
240 | #define REG8 0x20UL /* Command Queue Pointer */ | 240 | #define REG8 0x20 /* Command Queue Pointer */ |
241 | #define REG9 0x24UL /* Interrupt Queue Pointer */ | 241 | #define REG9 0x24 /* Interrupt Queue Pointer */ |
242 | 242 | ||
243 | #define DBRI_NO_CMDS 64 | 243 | #define DBRI_NO_CMDS 64 |
244 | #define DBRI_INT_BLK 64 | 244 | #define DBRI_INT_BLK 64 |
@@ -565,7 +565,7 @@ struct snd_dbri { | |||
565 | /* Translate the ALSA direction into the array index */ | 565 | /* Translate the ALSA direction into the array index */ |
566 | #define DBRI_STREAMNO(substream) \ | 566 | #define DBRI_STREAMNO(substream) \ |
567 | (substream->stream == \ | 567 | (substream->stream == \ |
568 | SNDRV_PCM_STREAM_PLAYBACK? DBRI_PLAY: DBRI_REC) | 568 | SNDRV_PCM_STREAM_PLAYBACK ? DBRI_PLAY: DBRI_REC) |
569 | 569 | ||
570 | /* Return a pointer to dbri_streaminfo */ | 570 | /* Return a pointer to dbri_streaminfo */ |
571 | #define DBRI_STREAM(dbri, substream) \ | 571 | #define DBRI_STREAM(dbri, substream) \ |
@@ -611,8 +611,8 @@ The list is terminated with a WAIT command, which generates a | |||
611 | CPU interrupt to signal completion. | 611 | CPU interrupt to signal completion. |
612 | 612 | ||
613 | Since the DBRI can run in parallel with the CPU, several means of | 613 | Since the DBRI can run in parallel with the CPU, several means of |
614 | synchronization present themselves. The method implemented here is only | 614 | synchronization present themselves. The method implemented here uses |
615 | use of the dbri_cmdwait() to wait for execution of batch of sent commands. | 615 | the dbri_cmdwait() to wait for execution of batch of sent commands. |
616 | 616 | ||
617 | A circular command buffer is used here. A new command is being added | 617 | A circular command buffer is used here. A new command is being added |
618 | while another can be executed. The scheme works by adding two WAIT commands | 618 | while another can be executed. The scheme works by adding two WAIT commands |
@@ -648,15 +648,14 @@ static void dbri_cmdwait(struct snd_dbri *dbri) | |||
648 | } | 648 | } |
649 | spin_unlock_irqrestore(&dbri->lock, flags); | 649 | spin_unlock_irqrestore(&dbri->lock, flags); |
650 | 650 | ||
651 | if (maxloops == 0) { | 651 | if (maxloops == 0) |
652 | printk(KERN_ERR "DBRI: Chip never completed command buffer\n"); | 652 | printk(KERN_ERR "DBRI: Chip never completed command buffer\n"); |
653 | } else { | 653 | else |
654 | dprintk(D_CMD, "Chip completed command buffer (%d)\n", | 654 | dprintk(D_CMD, "Chip completed command buffer (%d)\n", |
655 | MAXLOOPS - maxloops - 1); | 655 | MAXLOOPS - maxloops - 1); |
656 | } | ||
657 | } | 656 | } |
658 | /* | 657 | /* |
659 | * Lock the command queue and returns pointer to a space for len cmd words | 658 | * Lock the command queue and return pointer to space for len cmd words |
660 | * It locks the cmdlock spinlock. | 659 | * It locks the cmdlock spinlock. |
661 | */ | 660 | */ |
662 | static s32 *dbri_cmdlock(struct snd_dbri *dbri, int len) | 661 | static s32 *dbri_cmdlock(struct snd_dbri *dbri, int len) |
@@ -749,7 +748,7 @@ static void dbri_reset(struct snd_dbri *dbri) | |||
749 | } | 748 | } |
750 | 749 | ||
751 | /* Lock must not be held before calling this */ | 750 | /* Lock must not be held before calling this */ |
752 | static void dbri_initialize(struct snd_dbri *dbri) | 751 | static void __init dbri_initialize(struct snd_dbri *dbri) |
753 | { | 752 | { |
754 | s32 *cmd; | 753 | s32 *cmd; |
755 | u32 dma_addr; | 754 | u32 dma_addr; |
@@ -804,7 +803,7 @@ list ordering, among other things. The transmit and receive functions | |||
804 | here interface closely with the transmit and receive interrupt code. | 803 | here interface closely with the transmit and receive interrupt code. |
805 | 804 | ||
806 | */ | 805 | */ |
807 | static int pipe_active(struct snd_dbri *dbri, int pipe) | 806 | static inline int pipe_active(struct snd_dbri *dbri, int pipe) |
808 | { | 807 | { |
809 | return ((pipe >= 0) && (dbri->pipes[pipe].desc != -1)); | 808 | return ((pipe >= 0) && (dbri->pipes[pipe].desc != -1)); |
810 | } | 809 | } |
@@ -1148,6 +1147,7 @@ static int setup_descs(struct snd_dbri *dbri, int streamno, unsigned int period) | |||
1148 | if (!dbri->dma->desc[desc].ba) | 1147 | if (!dbri->dma->desc[desc].ba) |
1149 | break; | 1148 | break; |
1150 | } | 1149 | } |
1150 | |||
1151 | if (desc == DBRI_NO_DESCS) { | 1151 | if (desc == DBRI_NO_DESCS) { |
1152 | printk(KERN_ERR "DBRI: setup_descs: No descriptors\n"); | 1152 | printk(KERN_ERR "DBRI: setup_descs: No descriptors\n"); |
1153 | return -1; | 1153 | return -1; |
@@ -1308,7 +1308,7 @@ to the DBRI via the CHI interface and few of the DBRI's PIO pins. | |||
1308 | * Lock must not be held before calling it. | 1308 | * Lock must not be held before calling it. |
1309 | 1309 | ||
1310 | */ | 1310 | */ |
1311 | static void cs4215_setup_pipes(struct snd_dbri *dbri) | 1311 | static __init void cs4215_setup_pipes(struct snd_dbri *dbri) |
1312 | { | 1312 | { |
1313 | unsigned long flags; | 1313 | unsigned long flags; |
1314 | 1314 | ||
@@ -1341,7 +1341,7 @@ static void cs4215_setup_pipes(struct snd_dbri *dbri) | |||
1341 | dbri_cmdwait(dbri); | 1341 | dbri_cmdwait(dbri); |
1342 | } | 1342 | } |
1343 | 1343 | ||
1344 | static int cs4215_init_data(struct cs4215 *mm) | 1344 | static __init int cs4215_init_data(struct cs4215 *mm) |
1345 | { | 1345 | { |
1346 | /* | 1346 | /* |
1347 | * No action, memory resetting only. | 1347 | * No action, memory resetting only. |
@@ -1633,7 +1633,7 @@ static int cs4215_prepare(struct snd_dbri *dbri, unsigned int rate, | |||
1633 | /* | 1633 | /* |
1634 | * | 1634 | * |
1635 | */ | 1635 | */ |
1636 | static int cs4215_init(struct snd_dbri *dbri) | 1636 | static __init int cs4215_init(struct snd_dbri *dbri) |
1637 | { | 1637 | { |
1638 | u32 reg2 = sbus_readl(dbri->regs + REG2); | 1638 | u32 reg2 = sbus_readl(dbri->regs + REG2); |
1639 | dprintk(D_MM, "cs4215_init: reg2=0x%x\n", reg2); | 1639 | dprintk(D_MM, "cs4215_init: reg2=0x%x\n", reg2); |
@@ -1771,13 +1771,10 @@ static void xmit_descs(struct snd_dbri *dbri) | |||
1771 | 1771 | ||
1772 | static void transmission_complete_intr(struct snd_dbri *dbri, int pipe) | 1772 | static void transmission_complete_intr(struct snd_dbri *dbri, int pipe) |
1773 | { | 1773 | { |
1774 | struct dbri_streaminfo *info; | 1774 | struct dbri_streaminfo *info = &dbri->stream_info[DBRI_PLAY]; |
1775 | int td; | 1775 | int td = dbri->pipes[pipe].desc; |
1776 | int status; | 1776 | int status; |
1777 | 1777 | ||
1778 | info = &dbri->stream_info[DBRI_PLAY]; | ||
1779 | |||
1780 | td = dbri->pipes[pipe].desc; | ||
1781 | while (td >= 0) { | 1778 | while (td >= 0) { |
1782 | if (td >= DBRI_NO_DESCS) { | 1779 | if (td >= DBRI_NO_DESCS) { |
1783 | printk(KERN_ERR "DBRI: invalid td on pipe %d\n", pipe); | 1780 | printk(KERN_ERR "DBRI: invalid td on pipe %d\n", pipe); |
@@ -1798,12 +1795,9 @@ static void transmission_complete_intr(struct snd_dbri *dbri, int pipe) | |||
1798 | } | 1795 | } |
1799 | 1796 | ||
1800 | /* Notify ALSA */ | 1797 | /* Notify ALSA */ |
1801 | if (spin_is_locked(&dbri->lock)) { | 1798 | spin_unlock(&dbri->lock); |
1802 | spin_unlock(&dbri->lock); | 1799 | snd_pcm_period_elapsed(info->substream); |
1803 | snd_pcm_period_elapsed(info->substream); | 1800 | spin_lock(&dbri->lock); |
1804 | spin_lock(&dbri->lock); | ||
1805 | } else | ||
1806 | snd_pcm_period_elapsed(info->substream); | ||
1807 | } | 1801 | } |
1808 | 1802 | ||
1809 | static void reception_complete_intr(struct snd_dbri *dbri, int pipe) | 1803 | static void reception_complete_intr(struct snd_dbri *dbri, int pipe) |
@@ -1830,12 +1824,9 @@ static void reception_complete_intr(struct snd_dbri *dbri, int pipe) | |||
1830 | rd, DBRI_RD_STATUS(status), DBRI_RD_CNT(status)); | 1824 | rd, DBRI_RD_STATUS(status), DBRI_RD_CNT(status)); |
1831 | 1825 | ||
1832 | /* Notify ALSA */ | 1826 | /* Notify ALSA */ |
1833 | if (spin_is_locked(&dbri->lock)) { | 1827 | spin_unlock(&dbri->lock); |
1834 | spin_unlock(&dbri->lock); | 1828 | snd_pcm_period_elapsed(info->substream); |
1835 | snd_pcm_period_elapsed(info->substream); | 1829 | spin_lock(&dbri->lock); |
1836 | spin_lock(&dbri->lock); | ||
1837 | } else | ||
1838 | snd_pcm_period_elapsed(info->substream); | ||
1839 | } | 1830 | } |
1840 | 1831 | ||
1841 | static void dbri_process_one_interrupt(struct snd_dbri *dbri, int x) | 1832 | static void dbri_process_one_interrupt(struct snd_dbri *dbri, int x) |
@@ -1986,10 +1977,10 @@ static irqreturn_t snd_dbri_interrupt(int irq, void *dev_id) | |||
1986 | PCM Interface | 1977 | PCM Interface |
1987 | ****************************************************************************/ | 1978 | ****************************************************************************/ |
1988 | static struct snd_pcm_hardware snd_dbri_pcm_hw = { | 1979 | static struct snd_pcm_hardware snd_dbri_pcm_hw = { |
1989 | .info = (SNDRV_PCM_INFO_MMAP | | 1980 | .info = SNDRV_PCM_INFO_MMAP | |
1990 | SNDRV_PCM_INFO_INTERLEAVED | | 1981 | SNDRV_PCM_INFO_INTERLEAVED | |
1991 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | 1982 | SNDRV_PCM_INFO_BLOCK_TRANSFER | |
1992 | SNDRV_PCM_INFO_MMAP_VALID), | 1983 | SNDRV_PCM_INFO_MMAP_VALID, |
1993 | .formats = SNDRV_PCM_FMTBIT_MU_LAW | | 1984 | .formats = SNDRV_PCM_FMTBIT_MU_LAW | |
1994 | SNDRV_PCM_FMTBIT_A_LAW | | 1985 | SNDRV_PCM_FMTBIT_A_LAW | |
1995 | SNDRV_PCM_FMTBIT_U8 | | 1986 | SNDRV_PCM_FMTBIT_U8 | |
@@ -1999,7 +1990,7 @@ static struct snd_pcm_hardware snd_dbri_pcm_hw = { | |||
1999 | .rate_max = 48000, | 1990 | .rate_max = 48000, |
2000 | .channels_min = 1, | 1991 | .channels_min = 1, |
2001 | .channels_max = 2, | 1992 | .channels_max = 2, |
2002 | .buffer_bytes_max = (64 * 1024), | 1993 | .buffer_bytes_max = 64 * 1024, |
2003 | .period_bytes_min = 1, | 1994 | .period_bytes_min = 1, |
2004 | .period_bytes_max = DBRI_TD_MAXCNT, | 1995 | .period_bytes_max = DBRI_TD_MAXCNT, |
2005 | .periods_min = 1, | 1996 | .periods_min = 1, |
@@ -2266,11 +2257,10 @@ static int snd_cs4215_info_volume(struct snd_kcontrol *kcontrol, | |||
2266 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | 2257 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; |
2267 | uinfo->count = 2; | 2258 | uinfo->count = 2; |
2268 | uinfo->value.integer.min = 0; | 2259 | uinfo->value.integer.min = 0; |
2269 | if (kcontrol->private_value == DBRI_PLAY) { | 2260 | if (kcontrol->private_value == DBRI_PLAY) |
2270 | uinfo->value.integer.max = DBRI_MAX_VOLUME; | 2261 | uinfo->value.integer.max = DBRI_MAX_VOLUME; |
2271 | } else { | 2262 | else |
2272 | uinfo->value.integer.max = DBRI_MAX_GAIN; | 2263 | uinfo->value.integer.max = DBRI_MAX_GAIN; |
2273 | } | ||
2274 | return 0; | 2264 | return 0; |
2275 | } | 2265 | } |
2276 | 2266 | ||
@@ -2304,7 +2294,7 @@ static int snd_cs4215_put_volume(struct snd_kcontrol *kcontrol, | |||
2304 | info->right_gain = ucontrol->value.integer.value[1]; | 2294 | info->right_gain = ucontrol->value.integer.value[1]; |
2305 | changed = 1; | 2295 | changed = 1; |
2306 | } | 2296 | } |
2307 | if (changed == 1) { | 2297 | if (changed) { |
2308 | /* First mute outputs, and wait 1/8000 sec (125 us) | 2298 | /* First mute outputs, and wait 1/8000 sec (125 us) |
2309 | * to make sure this takes. This avoids clicking noises. | 2299 | * to make sure this takes. This avoids clicking noises. |
2310 | */ | 2300 | */ |
@@ -2443,8 +2433,9 @@ static int __init snd_dbri_mixer(struct snd_dbri *dbri) | |||
2443 | strcpy(card->mixername, card->shortname); | 2433 | strcpy(card->mixername, card->shortname); |
2444 | 2434 | ||
2445 | for (idx = 0; idx < ARRAY_SIZE(dbri_controls); idx++) { | 2435 | for (idx = 0; idx < ARRAY_SIZE(dbri_controls); idx++) { |
2446 | if ((err = snd_ctl_add(card, | 2436 | err = snd_ctl_add(card, |
2447 | snd_ctl_new1(&dbri_controls[idx], dbri))) < 0) | 2437 | snd_ctl_new1(&dbri_controls[idx], dbri)); |
2438 | if (err < 0) | ||
2448 | return err; | 2439 | return err; |
2449 | } | 2440 | } |
2450 | 2441 | ||
@@ -2485,8 +2476,8 @@ static void dbri_debug_read(struct snd_info_entry *entry, | |||
2485 | "Pipe %d: %s SDP=0x%x desc=%d, " | 2476 | "Pipe %d: %s SDP=0x%x desc=%d, " |
2486 | "len=%d next %d\n", | 2477 | "len=%d next %d\n", |
2487 | pipe, | 2478 | pipe, |
2488 | ((pptr->sdp & D_SDP_TO_SER) ? "output" : | 2479 | (pptr->sdp & D_SDP_TO_SER) ? "output" : |
2489 | "input"), | 2480 | "input", |
2490 | pptr->sdp, pptr->desc, | 2481 | pptr->sdp, pptr->desc, |
2491 | pptr->length, pptr->nextpipe); | 2482 | pptr->length, pptr->nextpipe); |
2492 | } | 2483 | } |
@@ -2502,7 +2493,7 @@ void snd_dbri_proc(struct snd_dbri *dbri) | |||
2502 | snd_info_set_text_ops(entry, dbri, dbri_regs_read); | 2493 | snd_info_set_text_ops(entry, dbri, dbri_regs_read); |
2503 | 2494 | ||
2504 | #ifdef DBRI_DEBUG | 2495 | #ifdef DBRI_DEBUG |
2505 | if (! snd_card_proc_new(dbri->card, "debug", &entry)) { | 2496 | if (!snd_card_proc_new(dbri->card, "debug", &entry)) { |
2506 | snd_info_set_text_ops(entry, dbri, dbri_debug_read); | 2497 | snd_info_set_text_ops(entry, dbri, dbri_debug_read); |
2507 | entry->mode = S_IFREG | S_IRUGO; /* Readable only. */ | 2498 | entry->mode = S_IFREG | S_IRUGO; /* Readable only. */ |
2508 | } | 2499 | } |
@@ -2633,11 +2624,12 @@ static int __init dbri_attach(int prom_node, struct sbus_dev *sdev) | |||
2633 | } | 2624 | } |
2634 | 2625 | ||
2635 | dbri = card->private_data; | 2626 | dbri = card->private_data; |
2636 | if ((err = snd_dbri_pcm(dbri)) < 0) | 2627 | err = snd_dbri_pcm(dbri); |
2628 | if (err < 0) | ||
2637 | goto _err; | 2629 | goto _err; |
2638 | 2630 | ||
2639 | if ((err = snd_dbri_mixer(dbri)) < 0) | 2631 | err = snd_dbri_mixer(dbri); |
2640 | if ((err = snd_dbri_mixer(dbri)) < 0) | 2632 | if (err < 0) |
2641 | goto _err; | 2633 | goto _err; |
2642 | 2634 | ||
2643 | /* /proc file handling */ | 2635 | /* /proc file handling */ |