Index: forte.c =================================================================== RCS file: /home/mkp/Repository/forte/forte.c,v retrieving revision 1.51 retrieving revision 1.53 diff -u -u -r1.51 -r1.53 --- forte.c 26 Aug 2002 18:10:41 -0000 1.51 +++ forte.c 24 Sep 2002 23:31:01 -0000 1.53 @@ -53,7 +53,7 @@ #include #define DRIVER_NAME "forte" -#define DRIVER_VERSION "$Id: forte.c,v 1.51 2002/08/26 18:10:41 mkp Exp $" +#define DRIVER_VERSION "$Id: forte.c,v 1.53 2002/09/24 23:31:01 mkp Exp $" #define PFX DRIVER_NAME ": " #undef M_DEBUG @@ -64,11 +64,18 @@ #define DPRINTK(args...) #endif +/* Codec I/F is buggy in 8-bit mode. Force chip to 16-bit only mode. */ +#define FORTE_16BIT_ONLY + /* Card capabilities */ #define FORTE_CAPS (DSP_CAP_MMAP | DSP_CAP_TRIGGER) /* Supported audio formats */ -#define FORTE_FMTS (AFMT_U8 | AFMT_S16_LE) +#ifdef FORTE_16BIT_ONLY + #define FORTE_FMTS (AFMT_S16_LE) +#else + #define FORTE_FMTS (AFMT_U8 | AFMT_S16_LE) +#endif /* Buffers */ #define FORTE_MIN_FRAG_SIZE 256 @@ -462,49 +469,33 @@ static int forte_channel_rate (struct forte_channel *channel, unsigned int rate) { - int new_rate, ret; + int new_rate; if (!channel || !channel->iobase) return -EINVAL; - if (rate == 0 || channel->rate == rate) { - ret = channel->rate; - goto out; - } - - if (rate > 48000) - rate = 48000; - - if (rate < 5500) - rate = 5500; - - switch (rate) { - case 5500: new_rate = 0; break; - case 8000: new_rate = 1; break; - case 9600: new_rate = 2; break; - case 11025: new_rate = 3; break; - case 16000: new_rate = 4; break; - case 19200: new_rate = 5; break; - case 22050: new_rate = 6; break; - case 32000: new_rate = 7; break; - case 38400: new_rate = 8; break; - case 44100: new_rate = 9; break; - case 48000: new_rate = 10; break; - - default: - DPRINTK ("Unsupported rate: %d", rate); - ret = -EINVAL; - goto out; - } + /* The FM801 only supports a handful of fixed frequencies. + * We find the value closest to what userland requested. + */ + if (rate <= 6250) { rate = 5500; new_rate = 0; } + else if (rate <= 8800) { rate = 8000; new_rate = 1; } + else if (rate <= 10312) { rate = 9600; new_rate = 2; } + else if (rate <= 13512) { rate = 11025; new_rate = 3; } + else if (rate <= 17600) { rate = 16000; new_rate = 4; } + else if (rate <= 20625) { rate = 19200; new_rate = 5; } + else if (rate <= 27025) { rate = 22050; new_rate = 6; } + else if (rate <= 35200) { rate = 32000; new_rate = 7; } + else if (rate <= 41250) { rate = 38400; new_rate = 8; } + else if (rate <= 46050) { rate = 44100; new_rate = 9; } + else { rate = 48000; new_rate = 10; } channel->ctrl &= ~FORTE_RATE_MASK; channel->ctrl |= new_rate << FORTE_RATE_SHIFT; - channel->rate = ret = rate; + channel->rate = rate; - out: DPRINTK ("%s: %s rate = %d\n", __FUNCTION__, channel->name, rate); - return ret; + return rate; } @@ -519,38 +510,32 @@ static int forte_channel_format (struct forte_channel *channel, int format) { - int ret; - if (!channel || !channel->iobase) return -EINVAL; - DPRINTK ("%s: %s format = %d\n", __FUNCTION__, channel->name, format); - switch (format) { case AFMT_QUERY: - ret = channel->format; break; +#ifndef FORTE_16BIT_ONLY case AFMT_U8: channel->ctrl &= ~FORTE_16BIT; - channel->format = format; - ret = format; + channel->format = AFMT_U8; break; +#endif case AFMT_S16_LE: - channel->ctrl |= FORTE_16BIT; - channel->format = format; - ret = format; - break; - default: - DPRINTK ("Unsupported audio format"); - ret = -EINVAL; + channel->ctrl |= FORTE_16BIT; + channel->format = AFMT_S16_LE; break; } - return ret; + DPRINTK ("%s: %s want %d format, got %d\n", __FUNCTION__, channel->name, + format, channel->format); + + return channel->format; } @@ -669,14 +654,14 @@ channel->buf_pages * PAGE_SIZE, &channel->buf_handle); + if (!channel->buf || !channel->buf_handle) + BUG(); + page = virt_to_page (channel->buf); for (i = 0 ; i < channel->buf_pages ; i++) mem_map_reserve (page++); - if (!channel->buf || !channel->buf_handle) - BUG(); - /* Prep buffer registers */ outw (channel->frag_sz - 1, channel->iobase + FORTE_PLY_COUNT); outl (channel->buf_handle, channel->iobase + FORTE_PLY_BUF1); @@ -777,9 +762,9 @@ init_waitqueue_head (&channel->wait); - /* Defaults: 48kHz, 16-bit, mono */ + /* Defaults: 48kHz, 16-bit, stereo */ forte_channel_reset (channel); - forte_channel_stereo (channel, 0); + forte_channel_stereo (channel, 1); forte_channel_format (channel, AFMT_S16_LE); forte_channel_rate (channel, 48000); forte_channel_buffer (channel, FORTE_DEF_FRAG_SIZE, @@ -830,7 +815,6 @@ unsigned long arg) { int ival, ret, rval, rd, wr, count; - unsigned long flags; struct forte_chip *chip; struct audio_buf_info abi; struct count_info cinfo; @@ -1183,6 +1167,18 @@ return 0; + case SOUND_PCM_READ_RATE: + DPRINTK ("%s: PCM_READ_RATE\n", __FUNCTION__); + return put_user (chip->play.rate, (int *) arg); + + case SOUND_PCM_READ_CHANNELS: + DPRINTK ("%s: PCM_READ_CHANNELS\n", __FUNCTION__); + return put_user (chip->play.stereo, (int *) arg); + + case SOUND_PCM_READ_BITS: + DPRINTK ("%s: PCM_READ_BITS\n", __FUNCTION__); + return put_user (chip->play.format, (int *) arg); + default: DPRINTK ("Unsupported ioctl: %x (%p)\n", cmd, (void *) arg); break; @@ -1200,7 +1196,6 @@ forte_dsp_open (struct inode *inode, struct file *file) { struct forte_chip *chip = forte; /* FIXME: HACK FROM HELL! */ - struct forte_channel *channel; if (down_interruptible (&chip->open_sem)) { DPRINTK ("%s: returning -ERESTARTSYS\n", __FUNCTION__); @@ -1252,7 +1247,6 @@ forte_channel_free (chip, &chip->rec); } - out: up (&chip->open_sem); return ret; @@ -1484,7 +1478,7 @@ { struct forte_chip *chip; struct forte_channel *channel; - unsigned int i = bytes, sz, ret; + unsigned int i = bytes, sz; unsigned long flags; if (ppos != &file->f_pos)