aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKrzysztof Helt <krzysztof.h1@wp.pl>2006-08-23 05:37:36 -0400
committerJaroslav Kysela <perex@suse.cz>2006-09-23 04:42:38 -0400
commitab93c7ae54a81bcecb77608ca89eea140f1d45ad (patch)
treef9db7fbc303e6f18e54bcaea3d1e9039fe8561d0
parent1be54c824be9b5e163cd83dabdf0ad3ac81c72a8 (diff)
[ALSA] sparc dbri: hardware constrains added
This patch adds ALSA hardware constrains so stereo is possible only with 16-bit format. It contains small cleanups to ring buffered code as well. Signed-off-by: Krzysztof Helt <krzysztof.h1@wp.pl> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Jaroslav Kysela <perex@suse.cz>
-rw-r--r--sound/sparc/dbri.c81
1 files changed, 62 insertions, 19 deletions
diff --git a/sound/sparc/dbri.c b/sound/sparc/dbri.c
index 3fb2ede80eaf..3e6ad507849d 100644
--- a/sound/sparc/dbri.c
+++ b/sound/sparc/dbri.c
@@ -85,7 +85,7 @@ MODULE_PARM_DESC(id, "ID string for Sun DBRI soundcard.");
85module_param_array(enable, bool, NULL, 0444); 85module_param_array(enable, bool, NULL, 0444);
86MODULE_PARM_DESC(enable, "Enable Sun DBRI soundcard."); 86MODULE_PARM_DESC(enable, "Enable Sun DBRI soundcard.");
87 87
88#define DBRI_DEBUG 88#undef DBRI_DEBUG
89 89
90#define D_INT (1<<0) 90#define D_INT (1<<0)
91#define D_GEN (1<<1) 91#define D_GEN (1<<1)
@@ -160,7 +160,7 @@ static struct {
160 /* { NA, (1 << 4), (5 << 3) }, */ 160 /* { NA, (1 << 4), (5 << 3) }, */
161 { 48000, (1 << 4), (6 << 3) }, 161 { 48000, (1 << 4), (6 << 3) },
162 { 9600, (1 << 4), (7 << 3) }, 162 { 9600, (1 << 4), (7 << 3) },
163 { 5513, (2 << 4), (0 << 3) }, /* Actually 5512.5 */ 163 { 5512, (2 << 4), (0 << 3) }, /* Actually 5512.5 */
164 { 11025, (2 << 4), (1 << 3) }, 164 { 11025, (2 << 4), (1 << 3) },
165 { 18900, (2 << 4), (2 << 3) }, 165 { 18900, (2 << 4), (2 << 3) },
166 { 22050, (2 << 4), (3 << 3) }, 166 { 22050, (2 << 4), (3 << 3) },
@@ -628,8 +628,6 @@ to send them to the DBRI.
628 628
629*/ 629*/
630 630
631static void dbri_process_interrupt_buffer(struct snd_dbri * dbri);
632
633#define MAXLOOPS 10 631#define MAXLOOPS 10
634/* 632/*
635 * Wait for the current command string to execute 633 * Wait for the current command string to execute
@@ -669,15 +667,15 @@ static s32 *dbri_cmdlock(struct snd_dbri * dbri, int len)
669} 667}
670 668
671/* 669/*
672 * Send prepared cmd string. It works by writting a JMP cmd into 670 * Send prepared cmd string. It works by writting a JUMP cmd into
673 * the last WAIT cmd and force DBRI to reread the cmd. 671 * the last WAIT cmd and force DBRI to reread the cmd.
674 * The JMP cmd points to the new cmd string. 672 * The JUMP cmd points to the new cmd string.
675 * It also releases the cmdlock spinlock. 673 * It also releases the cmdlock spinlock.
676 */ 674 */
677static void dbri_cmdsend(struct snd_dbri * dbri, s32 * cmd,int len) 675static void dbri_cmdsend(struct snd_dbri * dbri, s32 * cmd,int len)
678{ 676{
679 s32 *ptr;
680 s32 tmp, addr; 677 s32 tmp, addr;
678 unsigned long flags;
681 static int wait_id = 0; 679 static int wait_id = 0;
682 680
683 wait_id++; 681 wait_id++;
@@ -691,14 +689,17 @@ static void dbri_cmdsend(struct snd_dbri * dbri, s32 * cmd,int len)
691 *(dbri->cmdptr) = DBRI_CMD(D_JUMP, 0, 0); 689 *(dbri->cmdptr) = DBRI_CMD(D_JUMP, 0, 0);
692 690
693#ifdef DBRI_DEBUG 691#ifdef DBRI_DEBUG
694 if (cmd > dbri->cmdptr ) 692 if (cmd > dbri->cmdptr) {
693 s32 *ptr;
694
695 for (ptr = dbri->cmdptr; ptr < cmd+2; ptr++) { 695 for (ptr = dbri->cmdptr; ptr < cmd+2; ptr++) {
696 dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr); 696 dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr);
697 } 697 }
698 else { 698 } else {
699 ptr = dbri->cmdptr; 699 s32 *ptr = dbri->cmdptr;
700
700 dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr); 701 dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr);
701 ptr = dbri->cmdptr+1; 702 ptr++;
702 dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr); 703 dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr);
703 for (ptr = dbri->dma->cmd; ptr < cmd+2; ptr++) { 704 for (ptr = dbri->dma->cmd; ptr < cmd+2; ptr++) {
704 dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr); 705 dprintk(D_CMD, "cmd: %lx:%08x\n", (unsigned long)ptr, *ptr);
@@ -706,10 +707,12 @@ static void dbri_cmdsend(struct snd_dbri * dbri, s32 * cmd,int len)
706 } 707 }
707#endif 708#endif
708 709
710 spin_lock_irqsave(&dbri->lock, flags);
709 /* Reread the last command */ 711 /* Reread the last command */
710 tmp = sbus_readl(dbri->regs + REG0); 712 tmp = sbus_readl(dbri->regs + REG0);
711 tmp |= D_P; 713 tmp |= D_P;
712 sbus_writel(tmp, dbri->regs + REG0); 714 sbus_writel(tmp, dbri->regs + REG0);
715 spin_unlock_irqrestore(&dbri->lock, flags);
713 716
714 dbri->cmdptr = cmd; 717 dbri->cmdptr = cmd;
715 spin_unlock(&dbri->cmdlock); 718 spin_unlock(&dbri->cmdlock);
@@ -1549,8 +1552,7 @@ static int cs4215_prepare(struct snd_dbri * dbri, unsigned int rate,
1549 CS4215_BSEL_128 | CS4215_FREQ[freq_idx].xtal; 1552 CS4215_BSEL_128 | CS4215_FREQ[freq_idx].xtal;
1550 1553
1551 dbri->mm.channels = channels; 1554 dbri->mm.channels = channels;
1552 /* Stereo bit: 8 bit stereo not working yet. */ 1555 if (channels == 2)
1553 if ((channels > 1) && (dbri->mm.precision == 16))
1554 dbri->mm.ctrl[1] |= CS4215_DFR_STEREO; 1556 dbri->mm.ctrl[1] |= CS4215_DFR_STEREO;
1555 1557
1556 ret = cs4215_setctrl(dbri); 1558 ret = cs4215_setctrl(dbri);
@@ -1624,7 +1626,7 @@ interrupts are disabled.
1624 1626
1625/* xmit_descs() 1627/* xmit_descs()
1626 * 1628 *
1627 * Transmit the current TD's for recording/playing, if needed. 1629 * Starts transmiting the current TD's for recording/playing.
1628 * For playback, ALSA has filled the DMA memory with new data (we hope). 1630 * For playback, ALSA has filled the DMA memory with new data (we hope).
1629 */ 1631 */
1630static void xmit_descs(struct snd_dbri *dbri) 1632static void xmit_descs(struct snd_dbri *dbri)
@@ -1699,9 +1701,9 @@ play:
1699 * them as available. Stops when the first descriptor is found without 1701 * them as available. Stops when the first descriptor is found without
1700 * TBC (Transmit Buffer Complete) set, or we've run through them all. 1702 * TBC (Transmit Buffer Complete) set, or we've run through them all.
1701 * 1703 *
1702 * The DMA buffers are not released, but re-used. Since the transmit buffer 1704 * The DMA buffers are not released. They form a ring buffer and
1703 * descriptors are not clobbered, they can be re-submitted as is. This is 1705 * they are filled by ALSA while others are transmitted by DMA.
1704 * done by the xmit_descs() tasklet above since that could take longer. 1706 *
1705 */ 1707 */
1706 1708
1707static void transmission_complete_intr(struct snd_dbri * dbri, int pipe) 1709static void transmission_complete_intr(struct snd_dbri * dbri, int pipe)
@@ -1944,8 +1946,8 @@ static struct snd_pcm_hardware snd_dbri_pcm_hw = {
1944 SNDRV_PCM_FMTBIT_A_LAW | 1946 SNDRV_PCM_FMTBIT_A_LAW |
1945 SNDRV_PCM_FMTBIT_U8 | 1947 SNDRV_PCM_FMTBIT_U8 |
1946 SNDRV_PCM_FMTBIT_S16_BE, 1948 SNDRV_PCM_FMTBIT_S16_BE,
1947 .rates = SNDRV_PCM_RATE_8000_48000, 1949 .rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_5512,
1948 .rate_min = 8000, 1950 .rate_min = 5512,
1949 .rate_max = 48000, 1951 .rate_max = 48000,
1950 .channels_min = 1, 1952 .channels_min = 1,
1951 .channels_max = 2, 1953 .channels_max = 2,
@@ -1956,6 +1958,39 @@ static struct snd_pcm_hardware snd_dbri_pcm_hw = {
1956 .periods_max = 1024, 1958 .periods_max = 1024,
1957}; 1959};
1958 1960
1961static int snd_hw_rule_format(struct snd_pcm_hw_params *params,
1962 struct snd_pcm_hw_rule *rule)
1963{
1964 struct snd_interval *c = hw_param_interval(params,
1965 SNDRV_PCM_HW_PARAM_CHANNELS);
1966 struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
1967 struct snd_mask fmt;
1968
1969 snd_mask_any(&fmt);
1970 if (c->min > 1) {
1971 fmt.bits[0] &= SNDRV_PCM_FMTBIT_S16_BE;
1972 return snd_mask_refine(f, &fmt);
1973 }
1974 return 0;
1975}
1976
1977static int snd_hw_rule_channels(struct snd_pcm_hw_params *params,
1978 struct snd_pcm_hw_rule *rule)
1979{
1980 struct snd_interval *c = hw_param_interval(params,
1981 SNDRV_PCM_HW_PARAM_CHANNELS);
1982 struct snd_mask *f = hw_param_mask(params, SNDRV_PCM_HW_PARAM_FORMAT);
1983 struct snd_interval ch;
1984
1985 snd_interval_any(&ch);
1986 if (!(f->bits[0] & SNDRV_PCM_FMTBIT_S16_BE)) {
1987 ch.min = ch.max = 1;
1988 ch.integer = 1;
1989 return snd_interval_refine(c, &ch);
1990 }
1991 return 0;
1992}
1993
1959static int snd_dbri_open(struct snd_pcm_substream *substream) 1994static int snd_dbri_open(struct snd_pcm_substream *substream)
1960{ 1995{
1961 struct snd_dbri *dbri = snd_pcm_substream_chip(substream); 1996 struct snd_dbri *dbri = snd_pcm_substream_chip(substream);
@@ -1973,6 +2008,14 @@ static int snd_dbri_open(struct snd_pcm_substream *substream)
1973 info->pipe = -1; 2008 info->pipe = -1;
1974 spin_unlock_irqrestore(&dbri->lock, flags); 2009 spin_unlock_irqrestore(&dbri->lock, flags);
1975 2010
2011 snd_pcm_hw_rule_add(runtime,0,SNDRV_PCM_HW_PARAM_CHANNELS,
2012 snd_hw_rule_format, 0, SNDRV_PCM_HW_PARAM_FORMAT,
2013 -1);
2014 snd_pcm_hw_rule_add(runtime,0,SNDRV_PCM_HW_PARAM_FORMAT,
2015 snd_hw_rule_channels, 0,
2016 SNDRV_PCM_HW_PARAM_CHANNELS,
2017 -1);
2018
1976 cs4215_open(dbri); 2019 cs4215_open(dbri);
1977 2020
1978 return 0; 2021 return 0;