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

Next file: linux/drivers/sound/mad16.c
Previous file: linux/drivers/sound/es1370.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.2.10/linux/drivers/sound/es1371.c linux/drivers/sound/es1371.c
@@ -65,6 +65,11 @@
  *                     reported by "Ivan N. Kokshaysky" <ink@jurassic.park.msu.ru>
  *                     Note: joystick address handling might still be wrong on archs
  *                     other than i386
+ *    15.06.99   0.12  Fix bad allocation bug.
+ *                     Thanks to Deti Fliegl <fliegl@in.tum.de>
+ *    28.06.99   0.13  Add pci_set_master
+ *    21.07.99   0.14  S/PDIF module option for cards revision >= 4. Initial version
+ *                     by Dave Platt <dplatt@snulbug.mtview.ca.us>.
  *
  */
 
@@ -140,6 +145,7 @@
 static const unsigned sample_size[] = { 1, 2, 2, 4 };
 static const unsigned sample_shift[] = { 0, 1, 1, 2 };
 
+#define CTRL_SPDIFEN_B  0x04000000
 #define CTRL_JOY_SHIFT  24
 #define CTRL_JOY_MASK   3
 #define CTRL_JOY_200    0x00000000  /* joystick base address */
@@ -175,6 +181,9 @@
 
 
 #define STAT_INTR       0x80000000  /* wired or of all interrupt bits */
+#define STAT_EN_SPDIF   0x00040000  /* enable S/PDIF circuitry */
+#define STAT_TS_SPDIF   0x00020000  /* test S/PDIF circuitry */
+#define STAT_TESTMODE   0x00010000  /* test ASIC */
 #define STAT_SYNC_ERR   0x00000100  /* 1 = codec sync error */
 #define STAT_VC         0x000000c0  /* CCB int source, 0=DAC1, 1=DAC2, 2=ADC, 3=undef */
 #define STAT_SH_VC      6
@@ -759,8 +768,9 @@
 	db->hwptr = db->swptr = db->total_bytes = db->count = db->error = db->endcleared = 0;
 	if (!db->rawbuf) {
 		db->ready = db->mapped = 0;
-		for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER && !db->rawbuf; order--)
-			db->rawbuf = (void *)__get_free_pages(GFP_KERNEL, order);
+		for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--)
+			if ((db->rawbuf = (void *)__get_free_pages(GFP_KERNEL, order)))
+				break;
 		if (!db->rawbuf)
 			return -ENOMEM;
 		db->buforder = order;
@@ -2697,6 +2707,7 @@
 #else
 static int joystick[NR_DEVICE] = { 0, };
 #endif
+static int spdif[NR_DEVICE] = { 0, };
 
 /* --------------------------------------------------------------------- */
 
@@ -2729,10 +2740,12 @@
 	struct pci_dev *pcidev = NULL;
 	mm_segment_t fs;
 	int i, val, val2, index = 0;
+	u8 revision;
+	unsigned cssr;
 
 	if (!pci_present())   /* No PCI bus in this machine! */
 		return -ENODEV;
-	printk(KERN_INFO "es1371: version v0.11 time " __TIME__ " " __DATE__ "\n");
+	printk(KERN_INFO "es1371: version v0.13 time " __TIME__ " " __DATE__ "\n");
 	while (index < NR_DEVICE && 
 	       (pcidev = pci_find_device(PCI_VENDOR_ID_ENSONIQ, PCI_DEVICE_ID_ENSONIQ_ES1371, pcidev))) {
 		if (pcidev->base_address[0] == 0 || 
@@ -2785,10 +2798,23 @@
 			}
 		}
 		s->sctrl = 0;
+		cssr = 0;
+		/* check to see if s/pdif mode is being requested */
+		pci_read_config_byte(pcidev, PCI_REVISION_ID, &revision);
+		if (spdif[index]) {
+			if (revision >= 4) {
+				printk(KERN_INFO "es1371: enabling S/PDIF output\n");
+				cssr |= STAT_EN_SPDIF;
+				s->ctrl |= CTRL_SPDIFEN_B;
+			} else {
+				printk(KERN_ERR "es1371: revision %d does not support S/PDIF\n", revision);
+			}
+		}
 		/* initialize the chips */
 		outl(s->ctrl, s->io+ES1371_REG_CONTROL);
 		outl(s->sctrl, s->io+ES1371_REG_SERIAL_CONTROL);
 		outl(0, s->io+ES1371_REG_LEGACY);
+		pci_set_master(pcidev);  /* enable bus mastering */
 		/* AC97 warm reset to start the bitclk */
 		outl(s->ctrl | CTRL_SYNCRES, s->io+ES1371_REG_CONTROL);
 		udelay(2);
@@ -2858,6 +2884,8 @@
 			mixer_ioctl(s, initvol[i].mixch, (unsigned long)&val);
 		}
 		set_fs(fs);
+		/* turn on S/PDIF output driver if requested */
+		outl(cssr, s->io+ES1371_REG_STATUS);
 		/* queue it for later freeing */
 		s->next = devs;
 		devs = s;
@@ -2889,6 +2917,8 @@
 
 MODULE_PARM(joystick, "1-" __MODULE_STRING(NR_DEVICE) "i");
 MODULE_PARM_DESC(joystick, "sets address and enables joystick interface (still need separate driver)");
+MODULE_PARM(spdif, "1-" __MODULE_STRING(NR_DEVICE) "i");
+MODULE_PARM_DESC(spdif, "if 1 the output is in S/PDIF digital mode");
 
 MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
 MODULE_DESCRIPTION("ES1371 AudioPCI97 Driver");

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