PCI sound update

From: Thomas Sailer (sailer@ife.ee.ethz.ch)
Date: Wed May 24 2000 - 12:57:11 EST


Patch for my PCI sound drivers, against 2.3.99-pre9

Mostly cosmetic, except for es1371, which has SPDIF volume
support.

Tom

--- /usr/ife/t3/sailer/tmp4/linux/drivers/sound/es1370.c Sat May 13 17:19:21 2000
+++ es1370.c Wed May 24 15:32:50 2000
@@ -2455,9 +2455,8 @@
         { SOUND_MIXER_WRITE_OGAIN, 0x4040 }
 };
 
-#define RSRCISIOREGION(dev,num) ((dev)->resource[(num)].start != 0 && \
- ((dev)->resource[(num)].flags & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO)
-#define RSRCADDRESS(dev,num) ((dev)->resource[(num)].start)
+#define RSRCISIOREGION(dev,num) (pci_resource_start((dev), (num)) != 0 && \
+ pci_resource_flags((dev), (num)) & IORESOURCE_IO)
 
 static int __devinit es1370_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid)
 {
@@ -2488,7 +2487,7 @@
         spin_lock_init(&s->lock);
         s->magic = ES1370_MAGIC;
         s->dev = pcidev;
- s->io = RSRCADDRESS(pcidev, 0);
+ s->io = pci_resource_start(pcidev, 0);
         s->irq = pcidev->irq;
         if (!request_region(s->io, ES1370_EXTENT, "es1370")) {
                 printk(KERN_ERR "es1370: io ports %#lx-%#lx in use\n", s->io, s->io+ES1370_EXTENT-1);
@@ -2616,12 +2615,7 @@
         if (!pci_present()) /* No PCI bus in this machine! */
                 return -ENODEV;
         printk(KERN_INFO "es1370: version v0.33 time " __TIME__ " " __DATE__ "\n");
- if (!pci_register_driver(&es1370_driver)) {
- pci_unregister_driver(&es1370_driver);
- return -ENODEV;
- }
- return 0;
-
+ return pci_module_init(&es1370_driver);
 }
 
 static void __exit cleanup_es1370(void)
--- /usr/ife/t3/sailer/tmp4/linux/drivers/sound/es1371.c Sat May 13 17:19:21 2000
+++ es1371.c Wed May 24 15:32:50 2000
@@ -100,6 +100,8 @@
  * Tim Janik's BSE (Bedevilled Sound Engine) found this
  * 07.02.2000 0.24 Use pci_alloc_consistent and pci_register_driver
  * 07.02.2000 0.25 Use ac97_codec
+ * 01.03.2000 0.26 SPDIF patch by Mikael Bouillot <mikael.bouillot@bigfoot.com>
+ * Use pci_module_init
  */
 
 /*****************************************************************************/
@@ -205,6 +207,7 @@
 static const unsigned sample_size[] = { 1, 2, 2, 4 };
 static const unsigned sample_shift[] = { 0, 1, 1, 2 };
 
+#define CTRL_RECEN_B 0x08000000 /* 1 = don't mix analog in to digital out */
 #define CTRL_SPDIFEN_B 0x04000000
 #define CTRL_JOY_SHIFT 24
 #define CTRL_JOY_MASK 3
@@ -344,22 +347,6 @@
 #define SCTRL_P1FMT 0x00000003 /* format mask */
 #define SCTRL_SH_P1FMT 0
 
-/* codec constants */
-
-#define CODEC_ID_DEDICATEDMIC 0x001
-#define CODEC_ID_MODEMCODEC 0x002
-#define CODEC_ID_BASSTREBLE 0x004
-#define CODEC_ID_SIMULATEDSTEREO 0x008
-#define CODEC_ID_HEADPHONEOUT 0x010
-#define CODEC_ID_LOUDNESS 0x020
-#define CODEC_ID_18BITDAC 0x040
-#define CODEC_ID_20BITDAC 0x080
-#define CODEC_ID_18BITADC 0x100
-#define CODEC_ID_20BITADC 0x200
-
-#define CODEC_ID_SESHIFT 10
-#define CODEC_ID_SEMASK 0x1f
-
 
 /* misc stuff */
 #define POLL_COUNT 0x1000
@@ -405,6 +392,9 @@
         u16 device;
         u8 rev; /* the chip revision */
 
+ /* options */
+ int spdif_volume; /* S/PDIF output is enabled if != -1 */
+
 #ifdef ES1371_DEBUG
         /* debug /proc entry */
         struct proc_dir_entry *ps;
@@ -1135,6 +1125,67 @@
 
 /* --------------------------------------------------------------------- */
 
+/* Conversion table for S/PDIF PCM volume emulation through the SRC */
+/* dB-linear table of DAC vol values; -0dB to -46.5dB with mute */
+static const unsigned short DACVolTable[101] =
+{
+ 0x1000, 0x0f2a, 0x0e60, 0x0da0, 0x0cea, 0x0c3e, 0x0b9a, 0x0aff,
+ 0x0a6d, 0x09e1, 0x095e, 0x08e1, 0x086a, 0x07fa, 0x078f, 0x072a,
+ 0x06cb, 0x0670, 0x061a, 0x05c9, 0x057b, 0x0532, 0x04ed, 0x04ab,
+ 0x046d, 0x0432, 0x03fa, 0x03c5, 0x0392, 0x0363, 0x0335, 0x030b,
+ 0x02e2, 0x02bc, 0x0297, 0x0275, 0x0254, 0x0235, 0x0217, 0x01fb,
+ 0x01e1, 0x01c8, 0x01b0, 0x0199, 0x0184, 0x0170, 0x015d, 0x014b,
+ 0x0139, 0x0129, 0x0119, 0x010b, 0x00fd, 0x00f0, 0x00e3, 0x00d7,
+ 0x00cc, 0x00c1, 0x00b7, 0x00ae, 0x00a5, 0x009c, 0x0094, 0x008c,
+ 0x0085, 0x007e, 0x0077, 0x0071, 0x006b, 0x0066, 0x0060, 0x005b,
+ 0x0057, 0x0052, 0x004e, 0x004a, 0x0046, 0x0042, 0x003f, 0x003c,
+ 0x0038, 0x0036, 0x0033, 0x0030, 0x002e, 0x002b, 0x0029, 0x0027,
+ 0x0025, 0x0023, 0x0021, 0x001f, 0x001e, 0x001c, 0x001b, 0x0019,
+ 0x0018, 0x0017, 0x0016, 0x0014, 0x0000
+};
+
+/*
+ * when we are in S/PDIF mode, we want to disable any analog output so
+ * we filter the mixer ioctls
+ */
+static int mixdev_ioctl(struct ac97_codec *codec, unsigned int cmd, unsigned long arg)
+{
+ struct es1371_state *s = (struct es1371_state *)codec->private_data;
+ int val;
+ unsigned long flags;
+ unsigned int left, right;
+
+ VALIDATE_STATE(s);
+ /* filter mixer ioctls to catch PCM and MASTER volume when in S/PDIF mode */
+ if (s->spdif_volume == -1)
+ return codec->mixer_ioctl(codec, cmd, arg);
+ switch (cmd) {
+ case SOUND_MIXER_WRITE_VOLUME:
+ return 0;
+
+ case SOUND_MIXER_WRITE_PCM: /* use SRC for PCM volume */
+ get_user_ret(val, (int *)arg, -EFAULT);
+ right = ((val >> 8) & 0xff);
+ left = (val & 0xff);
+ if (right > 100)
+ right = 100;
+ if (left > 100)
+ left = 100;
+ s->spdif_volume = (right << 8) | left;
+ spin_lock_irqsave(&s->lock, flags);
+ src_write(s, SRCREG_VOL_DAC2, DACVolTable[100 - left]);
+ src_write(s, SRCREG_VOL_DAC2+1, DACVolTable[100 - right]);
+ spin_unlock_irqrestore(&s->lock, flags);
+ return 0;
+
+ case SOUND_MIXER_READ_PCM:
+ return put_user(s->spdif_volume, (int *)arg);
+ }
+ return codec->mixer_ioctl(codec, cmd, arg);
+}
+
+/* --------------------------------------------------------------------- */
+
 /*
  * AC97 Mixer Register to Connections mapping of the Concert 97 board
  *
@@ -1180,8 +1231,10 @@
 
 static int es1371_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
 {
- struct ac97_codec *codec = &((struct es1371_state *)file->private_data)->codec;
- return codec->mixer_ioctl(codec, cmd, arg);
+ struct es1371_state *s = (struct es1371_state *)file->private_data;
+ struct ac97_codec *codec = &s->codec;
+
+ return mixdev_ioctl(codec, cmd, arg);
 }
 
 static /*const*/ struct file_operations es1371_mixer_fops = {
@@ -1778,7 +1831,7 @@
                 return -EINVAL;
                 
         }
- return s->codec.mixer_ioctl(&s->codec, cmd, arg);
+ return mixdev_ioctl(&s->codec, cmd, arg);
 }
 
 static int es1371_open(struct inode *inode, struct file *file)
@@ -2181,7 +2234,7 @@
                 return -EINVAL;
                 
         }
- return s->codec.mixer_ioctl(&s->codec, cmd, arg);
+ return mixdev_ioctl(&s->codec, cmd, arg);
 }
 
 static int es1371_open_dac(struct inode *inode, struct file *file)
@@ -2581,6 +2634,7 @@
 
 static int joystick[NR_DEVICE] = { 0, };
 static int spdif[NR_DEVICE] = { 0, };
+static int nomix[NR_DEVICE] = { 0, };
 
 static unsigned int devindex = 0;
 
@@ -2588,6 +2642,8 @@
 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_PARM(nomix, "1-" __MODULE_STRING(NR_DEVICE) "i");
+MODULE_PARM_DESC(nomix, "if 1 no analog audio is mixed to the digital output");
 
 MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
 MODULE_DESCRIPTION("ES1371 AudioPCI97 Driver");
@@ -2613,9 +2669,8 @@
         { SOUND_MIXER_WRITE_IGAIN, 0x4040 }
 };
 
-#define RSRCISIOREGION(dev,num) ((dev)->resource[(num)].start != 0 && \
- ((dev)->resource[(num)].flags & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO)
-#define RSRCADDRESS(dev,num) ((dev)->resource[(num)].start)
+#define RSRCISIOREGION(dev,num) (pci_resource_start((dev), (num)) != 0 && \
+ (pci_resource_flags((dev), (num)) & IORESOURCE_IO))
 
 static int __devinit es1371_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid)
 {
@@ -2649,7 +2704,7 @@
         spin_lock_init(&s->lock);
         s->magic = ES1371_MAGIC;
         s->dev = pcidev;
- s->io = RSRCADDRESS(pcidev, 0);
+ s->io = pci_resource_start(pcidev, 0);
         s->irq = pcidev->irq;
         s->vendor = pcidev->vendor;
         s->device = pcidev->device;
@@ -2688,6 +2743,10 @@
         
         /* initialize codec registers */
         s->ctrl = 0;
+ if (pcidev->subsystem_vendor == 0x107b && pcidev->subsystem_device == 0x2150) {
+ s->ctrl |= CTRL_GPIO_OUT0;
+ printk(KERN_INFO PFX "Running On Gateway 2000 Solo 2510 - Amp On \n");
+ }
         if ((joystick[devindex] & ~0x18) == 0x200) {
                 if (check_region(joystick[devindex], JOY_EXTENT))
                         printk(KERN_ERR PFX "joystick address 0x%x already in use\n", joystick[devindex]);
@@ -2697,12 +2756,16 @@
         }
         s->sctrl = 0;
         cssr = 0;
+ s->spdif_volume = -1;
         /* check to see if s/pdif mode is being requested */
         if (spdif[devindex]) {
                 if (s->rev >= 4) {
                         printk(KERN_INFO PFX "enabling S/PDIF output\n");
+ s->spdif_volume = 0;
                         cssr |= STAT_EN_SPDIF;
                         s->ctrl |= CTRL_SPDIFEN_B;
+ if (nomix[devindex]) /* don't mix analog inputs to s/pdif output */
+ s->ctrl |= CTRL_RECEN_B;
                 } else {
                         printk(KERN_ERR PFX "revision %d does not support S/PDIF\n", s->rev);
                 }
@@ -2742,10 +2805,16 @@
         fs = get_fs();
         set_fs(KERNEL_DS);
         val = SOUND_MASK_LINE;
- s->codec.mixer_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;
- s->codec.mixer_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);
         }
         set_fs(fs);
         /* turn on S/PDIF output driver if requested */
@@ -2820,12 +2889,8 @@
 {
         if (!pci_present()) /* No PCI bus in this machine! */
                 return -ENODEV;
- printk(KERN_INFO "es1371: version v0.25 time " __TIME__ " " __DATE__ "\n");
- if (!pci_register_driver(&es1371_driver)) {
- pci_unregister_driver(&es1371_driver);
- return -ENODEV;
- }
- return 0;
+ printk(KERN_INFO PFX "version v0.26 time " __TIME__ " " __DATE__ "\n");
+ return pci_module_init(&es1371_driver);
 }
 
 static void __exit cleanup_es1371(void)
--- /usr/ife/t3/sailer/tmp4/linux/drivers/sound/esssolo1.c Sat May 13 17:19:21 2000
+++ esssolo1.c Wed May 24 15:32:50 2000
@@ -68,6 +68,7 @@
  * Integrated (aka redid 8-)) APM support patch by Zach Brown
  * 07.02.2000 0.13 Use pci_alloc_consistent and pci_register_driver
  * 19.02.2000 0.14 Use pci_dma_supported to determine if recording should be disabled
+ * 13.03.2000 0.15 Reintroduce initialization of a couple of PCI config space registers
  */
 
 /*****************************************************************************/
@@ -2130,6 +2131,14 @@
         mm_segment_t fs;
         int i, val;
 
+ /* initialize DDMA base address */
+ printk(KERN_DEBUG "solo1: ddma base address: 0x%lx\n", s->ddmabase);
+ pci_write_config_word(pcidev, 0x60, (s->ddmabase & (~0xf)) | 1);
+ /* set DMA policy to DDMA, IRQ emulation off (CLKRUN disabled for now) */
+ pci_write_config_dword(pcidev, 0x50, 0);
+ /* disable legacy audio address decode */
+ pci_write_config_word(pcidev, 0x40, 0x907f);
+
         /* initialize the chips */
         if (!reset_ctrl(s)) {
                 printk(KERN_ERR "esssolo1: cannot reset controller\n");
@@ -2190,9 +2199,8 @@
 }
 
 
-#define RSRCISIOREGION(dev,num) ((dev)->resource[(num)].start != 0 && \
- ((dev)->resource[(num)].flags & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO)
-#define RSRCADDRESS(dev,num) ((dev)->resource[(num)].start)
+#define RSRCISIOREGION(dev,num) (pci_resource_start((dev), (num)) != 0 && \
+ (pci_resource_flags((dev), (num)) & IORESOURCE_IO))
 
 static int __devinit solo1_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid)
 {
@@ -2229,12 +2237,12 @@
         spin_lock_init(&s->lock);
         s->magic = SOLO1_MAGIC;
         s->dev = pcidev;
- s->iobase = RSRCADDRESS(pcidev, 0);
- s->sbbase = RSRCADDRESS(pcidev, 1);
- s->vcbase = RSRCADDRESS(pcidev, 2);
+ s->iobase = pci_resource_start(pcidev, 0);
+ s->sbbase = pci_resource_start(pcidev, 1);
+ s->vcbase = pci_resource_start(pcidev, 2);
         s->ddmabase = s->vcbase + DDMABASE_OFFSET;
- s->mpubase = RSRCADDRESS(pcidev, 3);
- s->gpbase = RSRCADDRESS(pcidev, 4);
+ s->mpubase = pci_resource_start(pcidev, 3);
+ s->gpbase = pci_resource_start(pcidev, 4);
         s->irq = pcidev->irq;
         if (!request_region(s->iobase, IOBASE_EXTENT, "ESS Solo1")) {
                 printk(KERN_ERR "solo1: io ports in use\n");
@@ -2252,13 +2260,12 @@
                 printk(KERN_ERR "solo1: io ports in use\n");
                 goto err_region4;
         }
- if (pci_enable_device(pcidev))
- goto err_irq;
         if (request_irq(s->irq, solo1_interrupt, SA_SHIRQ, "ESS Solo1", s)) {
                 printk(KERN_ERR "solo1: irq %u in use\n", s->irq);
                 goto err_irq;
         }
- printk(KERN_DEBUG "solo1: ddma base address: 0x%lx\n", s->ddmabase);
+ if (pci_enable_device(pcidev))
+ goto err_irq;
         printk(KERN_INFO "solo1: joystick port at %#lx\n", s->gpbase+1);
         /* register devices */
         if ((s->dev_audio = register_sound_dsp(&solo1_audio_fops, -1)) < 0)
@@ -2352,7 +2359,7 @@
 {
         if (!pci_present()) /* No PCI bus in this machine! */
                 return -ENODEV;
- printk(KERN_INFO "solo1: version v0.14 time " __TIME__ " " __DATE__ "\n");
+ printk(KERN_INFO "solo1: version v0.15 time " __TIME__ " " __DATE__ "\n");
         if (!pci_register_driver(&solo1_driver)) {
                 pci_unregister_driver(&solo1_driver);
                 return -ENODEV;
--- /usr/ife/t3/sailer/tmp4/linux/drivers/sound/sonicvibes.c Sat May 13 17:19:21 2000
+++ sonicvibes.c Wed May 24 15:32:50 2000
@@ -2428,9 +2428,8 @@
         { SOUND_MIXER_WRITE_PCM, 0x4040 }
 };
 
-#define RSRCISIOREGION(dev,num) ((dev)->resource[(num)].start != 0 && \
- ((dev)->resource[(num)].flags & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO)
-#define RSRCADDRESS(dev,num) ((dev)->resource[(num)].start)
+#define RSRCISIOREGION(dev,num) (pci_resource_start((dev), (num)) != 0 && \
+ (pci_resource_flags((dev), (num)) & IORESOURCE_IO))
 
 static int __devinit sv_probe(struct pci_dev *pcidev, const struct pci_device_id *pciid)
 {
@@ -2484,13 +2483,13 @@
         spin_lock_init(&s->lock);
         s->magic = SV_MAGIC;
         s->dev = pcidev;
- s->iosb = RSRCADDRESS(pcidev, RESOURCE_SB);
- s->ioenh = RSRCADDRESS(pcidev, RESOURCE_ENH);
- s->iosynth = RSRCADDRESS(pcidev, RESOURCE_SYNTH);
- s->iomidi = RSRCADDRESS(pcidev, RESOURCE_MIDI);
- s->iogame = RSRCADDRESS(pcidev, RESOURCE_GAME);
- s->iodmaa = RSRCADDRESS(pcidev, RESOURCE_DDMA);
- s->iodmac = RSRCADDRESS(pcidev, RESOURCE_DDMA) + SV_EXTENT_DMA;
+ s->iosb = pci_resource_start(pcidev, RESOURCE_SB);
+ s->ioenh = pci_resource_start(pcidev, RESOURCE_ENH);
+ s->iosynth = pci_resource_start(pcidev, RESOURCE_SYNTH);
+ s->iomidi = pci_resource_start(pcidev, RESOURCE_MIDI);
+ s->iogame = pci_resource_start(pcidev, RESOURCE_GAME);
+ s->iodmaa = pci_resource_start(pcidev, RESOURCE_DDMA);
+ s->iodmac = pci_resource_start(pcidev, RESOURCE_DDMA) + SV_EXTENT_DMA;
         pci_write_config_dword(pcidev, 0x40, s->iodmaa | 9); /* enable and use extended mode */
         pci_write_config_dword(pcidev, 0x48, s->iodmac | 9); /* enable */
         printk(KERN_DEBUG "sv: io ports: %#lx %#lx %#lx %#lx %#lx %#x %#x\n",
@@ -2655,11 +2654,7 @@
         if (!(wavetable_mem = __get_free_pages(GFP_KERNEL, 20-PAGE_SHIFT)))
                 printk(KERN_INFO "sv: cannot allocate 1MB of contiguous nonpageable memory for wavetable data\n");
 #endif
- if (!pci_register_driver(&sv_driver)) {
- pci_unregister_driver(&sv_driver);
- return -ENODEV;
- }
- return 0;
+ return pci_module_init(&sv_driver);
 }
 
 static void __exit cleanup_sonicvibes(void)

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Wed May 31 2000 - 21:00:12 EST