patch-2.4.9 linux/drivers/sound/cs46xx.c

Next file: linux/drivers/sound/dmasound/dmasound.h
Previous file: linux/drivers/sound/cs4281/cs4281m.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.8/linux/drivers/sound/cs46xx.c linux/drivers/sound/cs46xx.c
@@ -51,6 +51,11 @@
  *	20010420-tw	cleanup powerdown/up code.
  *	20010521-tw	eliminate pops, and fixes for powerdown.
  *	20010525-tw	added fixes for thinkpads with powerdown logic.
+ *	20010723-sh     patch from Horms (Simon Horman) -
+ *	                SOUND_PCM_READ_BITS returns bits as set in driver
+ *	                rather than a logical or of the possible values.
+ *	                Various ioctls handle the case where the device
+ *	                is open for reading or writing but not both better.
  *
  *	Status:
  *	Playback/Capture supported from 8k-48k.
@@ -378,7 +383,6 @@
 static int cs_release_mixdev(struct inode *inode, struct file *file);
 static int cs_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd,
 				unsigned long arg);
-static loff_t cs_llseek(struct file *file, loff_t offset, int origin);
 static int cs_hardware_init(struct cs_card *card);
 static int cs46xx_powerup(struct cs_card *card, unsigned int type);
 static int cs461x_powerdown(struct cs_card *card, unsigned int type, int suspendflag);
@@ -997,7 +1001,7 @@
 /* get current playback/recording dma buffer pointer (byte offset from LBA),
    called with spinlock held! */
    
-extern __inline__ unsigned cs_get_dma_addr(struct cs_state *state)
+static inline unsigned cs_get_dma_addr(struct cs_state *state)
 {
 	struct dmabuf *dmabuf = &state->dmabuf;
 	u32 offset;
@@ -1044,7 +1048,7 @@
 }
 	
 /* Stop recording (lock held) */
-extern __inline__ void __stop_adc(struct cs_state *state)
+static inline void __stop_adc(struct cs_state *state)
 {
 	struct dmabuf *dmabuf = &state->dmabuf;
 	struct cs_card *card = state->card;
@@ -1931,7 +1935,7 @@
  */
 static /*const*/ struct file_operations cs_midi_fops = {
 	CS_OWNER	CS_THIS_MODULE
-	llseek:		cs_llseek,
+	llseek:		no_llseek,
 	read:		cs_midi_read,
 	write:		cs_midi_write,
 	poll:		cs_midi_poll,
@@ -1939,11 +1943,6 @@
 	release:	cs_midi_release,
 };
 
-static loff_t cs_llseek(struct file *file, loff_t offset, int origin)
-{
-	return -ESPIPE;
-}
-
 /*
  *
  * CopySamples copies 16-bit stereo signed samples from the source to the
@@ -2846,6 +2845,8 @@
 		return 0;
 
 	case SNDCTL_DSP_GETOSPACE:
+		if (!(file->f_mode & FMODE_WRITE))
+			return -EINVAL;
 		state = (struct cs_state *)card->states[1];
 		if(state)
 		{
@@ -2869,6 +2870,8 @@
 		return -ENODEV;
 
 	case SNDCTL_DSP_GETISPACE:
+		if (!(file->f_mode & FMODE_READ))
+			return -EINVAL;
 		state = (struct cs_state *)card->states[0];
 		if(state)
 		{
@@ -2950,6 +2953,8 @@
 		return 0;
 
 	case SNDCTL_DSP_GETIPTR:
+		if (!(file->f_mode & FMODE_READ))
+			return -EINVAL;
 		state = (struct cs_state *)card->states[0];
 		if(state)
 		{
@@ -2965,6 +2970,8 @@
 		return -ENODEV;
 
 	case SNDCTL_DSP_GETOPTR:
+		if (!(file->f_mode & FMODE_WRITE))
+			return -EINVAL;
 		state = (struct cs_state *)card->states[1];
 		if(state)
 		{
@@ -3015,7 +3022,10 @@
 		return put_user(val, (int *)arg);
 
 	case SOUND_PCM_READ_RATE:
-		state = (struct cs_state *)card->states[0];
+		if(file->f_mode & FMODE_READ)
+			state = (struct cs_state *)card->states[0];
+		else 
+			state = (struct cs_state *)card->states[1];
 		if(state)
 		{
 			dmabuf = &state->dmabuf;
@@ -3025,7 +3035,10 @@
 		
 
 	case SOUND_PCM_READ_CHANNELS:
-		state = (struct cs_state *)card->states[0];
+		if(file->f_mode & FMODE_READ)
+			state = (struct cs_state *)card->states[0];
+		else 
+			state = (struct cs_state *)card->states[1];
 		if(state)
 		{
 			dmabuf = &state->dmabuf;
@@ -3035,11 +3048,16 @@
 		return put_user(0, (int *)arg);
 
 	case SOUND_PCM_READ_BITS:
-		state = (struct cs_state *)card->states[0];
+		if(file->f_mode & FMODE_READ)
+			state = (struct cs_state *)card->states[0];
+		else 
+			state = (struct cs_state *)card->states[1];
 		if(state)
 		{
 			dmabuf = &state->dmabuf;
-			return put_user(AFMT_S16_LE | AFMT_U8, (int *)arg);
+			return put_user((dmabuf->fmt & CS_FMT_16BIT) ? 
+			  	AFMT_S16_LE : AFMT_U8, (int *)arg);
+
 		}
 		return put_user(0, (int *)arg);
 
@@ -3799,7 +3817,7 @@
 
 static /*const*/ struct file_operations cs461x_fops = {
 	CS_OWNER	CS_THIS_MODULE
-	llseek:		cs_llseek,
+	llseek:		no_llseek,
 	read:		cs_read,
 	write:		cs_write,
 	poll:		cs_poll,
@@ -4206,7 +4224,7 @@
 
 static /*const*/ struct file_operations cs_mixer_fops = {
 	CS_OWNER	CS_THIS_MODULE
-	llseek:		cs_llseek,
+	llseek:		no_llseek,
 	ioctl:		cs_ioctl_mixdev,
 	open:		cs_open_mixdev,
 	release:	cs_release_mixdev,

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)