patch-2.4.22 linux-2.4.22/drivers/sound/es1371.c

Next file: linux-2.4.22/drivers/sound/esssolo1.c
Previous file: linux-2.4.22/drivers/sound/emu10k1/mixer.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.21/drivers/sound/es1371.c linux-2.4.22/drivers/sound/es1371.c
@@ -412,7 +412,7 @@
 	struct proc_dir_entry *ps;
 #endif /* ES1371_DEBUG */
 
-	struct ac97_codec codec;
+	struct ac97_codec *codec;
 
 	/* wave stuff */
 	unsigned ctrl;
@@ -688,10 +688,10 @@
 	unsigned long flags;
 	unsigned t, x;
         
+	spin_lock_irqsave(&s->lock, flags);
 	for (t = 0; t < POLL_COUNT; t++)
 		if (!(inl(s->io+ES1371_REG_CODEC) & CODEC_WIP))
 			break;
-	spin_lock_irqsave(&s->lock, flags);
 
         /* save the current state for later */
         x = wait_src_ready(s);
@@ -730,11 +730,12 @@
 	unsigned long flags;
 	unsigned t, x;
 
+	spin_lock_irqsave(&s->lock, flags);
+	
         /* wait for WIP to go away */
 	for (t = 0; t < 0x1000; t++)
 		if (!(inl(s->io+ES1371_REG_CODEC) & CODEC_WIP))
 			break;
-	spin_lock_irqsave(&s->lock, flags);
 
 	/* save the current state for later */
 	x = (wait_src_ready(s) & (SRC_DIS | SRC_DDAC1 | SRC_DDAC2 | SRC_DADC));
@@ -762,7 +763,6 @@
 	/* restore SRC reg */
 	wait_src_ready(s);
 	outl(x, s->io+ES1371_REG_SRCONV);
-	spin_unlock_irqrestore(&s->lock, flags);
 
         /* wait for WIP again */
 	for (t = 0; t < 0x1000; t++)
@@ -774,6 +774,7 @@
 		if ((x = inl(s->io+ES1371_REG_CODEC)) & CODEC_RDY)
 			break;
         
+	spin_unlock_irqrestore(&s->lock, flags);
 	return ((x & CODEC_PIDAT_MASK) >> CODEC_PIDAT_SHIFT);
 }
 
@@ -1222,7 +1223,7 @@
 		if (list == &devs)
 			return -ENODEV;
 		s = list_entry(list, struct es1371_state, devs);
-		if (s->codec.dev_mixer == minor)
+		if (s->codec->dev_mixer == minor)
 			break;
 	}
        	VALIDATE_STATE(s);
@@ -1241,7 +1242,7 @@
 static int es1371_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
 {
 	struct es1371_state *s = (struct es1371_state *)file->private_data;
-	struct ac97_codec *codec = &s->codec;
+	struct ac97_codec *codec = s->codec;
 
 	return mixdev_ioctl(codec, cmd, arg);
 }
@@ -1909,7 +1910,7 @@
                 return -EINVAL;
 		
 	}
-	return mixdev_ioctl(&s->codec, cmd, arg);
+	return mixdev_ioctl(s->codec, cmd, arg);
 }
 
 static int es1371_open(struct inode *inode, struct file *file)
@@ -2338,7 +2339,7 @@
                 return -EINVAL;
 		
 	}
-	return mixdev_ioctl(&s->codec, cmd, arg);
+	return mixdev_ioctl(s->codec, cmd, arg);
 }
 
 static int es1371_open_dac(struct inode *inode, struct file *file)
@@ -2716,7 +2717,7 @@
         /* print out CODEC state */
         len += sprintf (buf + len, "AC97 CODEC state\n");
 	for (cnt=0; cnt <= 0x7e; cnt = cnt +2)
-                len+= sprintf (buf + len, "reg:0x%02x  val:0x%04x\n", cnt, rdcodec(&s->codec, cnt));
+                len+= sprintf (buf + len, "reg:0x%02x  val:0x%04x\n", cnt, rdcodec(s->codec, cnt));
 
         if (fpos >=len){
                 *start = buf;
@@ -2819,6 +2820,11 @@
 		return -ENOMEM;
 	}
 	memset(s, 0, sizeof(struct es1371_state));
+	
+	s->codec = ac97_alloc_codec();
+	if(s->codec == NULL)
+		goto err_codec;
+		
 	init_waitqueue_head(&s->dma_adc.wait);
 	init_waitqueue_head(&s->dma_dac1.wait);
 	init_waitqueue_head(&s->dma_dac2.wait);
@@ -2834,10 +2840,10 @@
 	s->vendor = pcidev->vendor;
 	s->device = pcidev->device;
 	pci_read_config_byte(pcidev, PCI_REVISION_ID, &s->rev);
-	s->codec.private_data = s;
-	s->codec.id = 0;
-	s->codec.codec_read = rdcodec;
-	s->codec.codec_write = wrcodec;
+	s->codec->private_data = s;
+	s->codec->id = 0;
+	s->codec->codec_read = rdcodec;
+	s->codec->codec_write = wrcodec;
 	printk(KERN_INFO PFX "found chip, vendor id 0x%04x device id 0x%04x revision 0x%02x\n",
 	       s->vendor, s->device, s->rev);
 	if (!request_region(s->io, ES1371_EXTENT, "es1371")) {
@@ -2854,7 +2860,7 @@
 	/* register devices */
 	if ((res=(s->dev_audio = register_sound_dsp(&es1371_audio_fops,-1)))<0)
 		goto err_dev1;
-	if ((res=(s->codec.dev_mixer = register_sound_mixer(&es1371_mixer_fops, -1)) < 0))
+	if ((res=(s->codec->dev_mixer = register_sound_mixer(&es1371_mixer_fops, -1)) < 0))
 		goto err_dev2;
 	if ((res=(s->dev_dac = register_sound_dsp(&es1371_dac_fops, -1))) < 0)
 		goto err_dev3;
@@ -2945,7 +2951,7 @@
 	/* init the sample rate converter */
 	src_init(s);
 	/* codec init */
-	if (!ac97_probe_codec(&s->codec)) {
+	if (!ac97_probe_codec(s->codec)) {
 		res = -ENODEV;
 		goto err_gp;
 	}
@@ -2954,16 +2960,16 @@
 	fs = get_fs();
 	set_fs(KERNEL_DS);
 	val = SOUND_MASK_LINE;
-	mixdev_ioctl(&s->codec, SOUND_MIXER_WRITE_RECSRC, (unsigned long)&val);
+	mixdev_ioctl(s->codec, SOUND_MIXER_WRITE_RECSRC, (unsigned long)&val);
 	for (i = 0; i < sizeof(initvol)/sizeof(initvol[0]); i++) {
 		val = initvol[i].vol;
-		mixdev_ioctl(&s->codec, initvol[i].mixch, (unsigned long)&val);
+		mixdev_ioctl(s->codec, initvol[i].mixch, (unsigned long)&val);
 	}
 	/* mute master and PCM when in S/PDIF mode */
 	if (s->spdif_volume != -1) {
 		val = 0x0000;
-		s->codec.mixer_ioctl(&s->codec, SOUND_MIXER_WRITE_VOLUME, (unsigned long)&val);
-		s->codec.mixer_ioctl(&s->codec, SOUND_MIXER_WRITE_PCM, (unsigned long)&val);
+		s->codec->mixer_ioctl(s->codec, SOUND_MIXER_WRITE_VOLUME, (unsigned long)&val);
+		s->codec->mixer_ioctl(s->codec, SOUND_MIXER_WRITE_PCM, (unsigned long)&val);
 	}
 	set_fs(fs);
 	/* turn on S/PDIF output driver if requested */
@@ -2991,7 +2997,7 @@
  err_dev4:
 	unregister_sound_dsp(s->dev_dac);
  err_dev3:
-	unregister_sound_mixer(s->codec.dev_mixer);
+	unregister_sound_mixer(s->codec->dev_mixer);
  err_dev2:
 	unregister_sound_dsp(s->dev_audio);
  err_dev1:
@@ -3000,6 +3006,8 @@
  err_irq:
 	release_region(s->io, ES1371_EXTENT);
  err_region:
+ err_codec:
+	ac97_release_codec(s->codec);
 	kfree(s);
 	return res;
 }
@@ -3025,9 +3033,10 @@
 	}
 	release_region(s->io, ES1371_EXTENT);
 	unregister_sound_dsp(s->dev_audio);
-	unregister_sound_mixer(s->codec.dev_mixer);
+	unregister_sound_mixer(s->codec->dev_mixer);
 	unregister_sound_dsp(s->dev_dac);
 	unregister_sound_midi(s->dev_midi);
+	ac97_release_codec(s->codec);
 	kfree(s);
 	pci_set_drvdata(dev, NULL);
 }

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