patch-2.4.0-test2 linux/drivers/sound/i810_audio.c
Next file: linux/drivers/sound/maestro.c
Previous file: linux/drivers/sound/esssolo1.c
Back to the patch index
Back to the overall index
- Lines: 236
- Date:
Tue Jun 20 07:52:36 2000
- Orig file:
v2.4.0-test1/linux/drivers/sound/i810_audio.c
- Orig date:
Thu May 11 15:30:08 2000
diff -u --recursive --new-file v2.4.0-test1/linux/drivers/sound/i810_audio.c linux/drivers/sound/i810_audio.c
@@ -46,6 +46,18 @@
* There is no midi support, no synth support. Use timidity. To get
* esd working you need to use esd -r 48000 as it won't probe 48KHz
* by default. mpg123 can't handle 48Khz only audio so use xmms.
+ *
+ * Fix The Sound On Dell
+ *
+ * Not everyone uses 48KHz. We know of no way to detect this reliably
+ * and certainly not to get the right data. If your i810 audio sounds
+ * stupid you may need to investigate other speeds. According to Analog
+ * they tend to use a 14.318MHz clock which gives you a base rate of
+ * 41194Hz.
+ *
+ * This is available via the 'ftsodell=1' option.
+ *
+ * If you need to force a specific rate set the clocking= option
*/
#include <linux/module.h>
@@ -74,10 +86,17 @@
#ifndef PCI_DEVICE_ID_INTEL_82901
#define PCI_DEVICE_ID_INTEL_82901 0x2425
#endif
+#ifndef PCI_DEVICE_ID_INTEL_ICH2
+#define PCI_DEVICE_ID_INTEL_ICH2 0x2445
+#endif
#ifndef PCI_DEVICE_ID_INTEL_440MX
#define PCI_DEVICE_ID_INTEL_440MX 0x7195
#endif
+static int ftsodell=0;
+static int clocking=48000;
+
+
#define ADC_RUNNING 1
#define DAC_RUNNING 2
@@ -180,13 +199,15 @@
enum {
ICH82801AA = 0,
ICH82901AB,
- INTEL440MX
+ INTEL440MX,
+ INTELICH2,
};
static char * card_names[] = {
"Intel ICH 82801AA",
"Intel ICH 82901AB",
- "Intel 440MX"
+ "Intel 440MX",
+ "Intel ICH2"
};
static struct pci_device_id i810_pci_tbl [] __initdata = {
@@ -196,6 +217,8 @@
PCI_ANY_ID, PCI_ANY_ID, 0, 0, ICH82901AB},
{PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_440MX,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, INTEL440MX},
+ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH2,
+ PCI_ANY_ID, PCI_ANY_ID, 0, 0, INTELICH2},
{0,}
};
@@ -295,7 +318,6 @@
static struct i810_card *devs = NULL;
static int i810_open_mixdev(struct inode *inode, struct file *file);
-static int i810_release_mixdev(struct inode *inode, struct file *file);
static int i810_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg);
static loff_t i810_llseek(struct file *file, loff_t offset, int origin);
@@ -363,12 +385,27 @@
struct ac97_codec *codec=state->card->ac97_codec[0];
if(!(state->card->ac97_features&0x0001))
- return 48000;
+ {
+ dmabuf->rate = clocking;
+ return clocking;
+ }
if (rate > 48000)
rate = 48000;
- if (rate < 4000)
- rate = 4000;
+ if (rate < 8000)
+ rate = 8000;
+
+ /*
+ * Adjust for misclocked crap
+ */
+
+ rate = ( rate * clocking)/48000;
+
+ /* Analog codecs can go lower via magic registers but others
+ might not */
+
+ if(rate < 8000)
+ rate = 8000;
/* Power down the DAC */
dacp=i810_ac97_get(codec, AC97_POWER_CONTROL);
@@ -378,10 +415,10 @@
i810_ac97_set(codec, AC97_PCM_FRONT_DAC_RATE, rate);
rp=i810_ac97_get(codec, AC97_PCM_FRONT_DAC_RATE);
- printk("DAC rate set to %d Returned %d\n",
- rate, (int)rp);
+// printk("DAC rate set to %d Returned %d\n",
+// rate, (int)rp);
- rate=rp;
+ rate=(rp * 48000) / clocking;
/* Power it back up */
i810_ac97_set(codec, AC97_POWER_CONTROL, dacp);
@@ -402,25 +439,41 @@
struct ac97_codec *codec=state->card->ac97_codec[0];
if(!(state->card->ac97_features&0x0001))
- return 48000;
+ {
+ dmabuf->rate = clocking;
+ return clocking;
+ }
if (rate > 48000)
rate = 48000;
- if (rate < 4000)
- rate = 4000;
+ if (rate < 8000)
+ rate = 8000;
+
+ /*
+ * Adjust for misclocked crap
+ */
+
+ rate = ( rate * clocking)/48000;
+
+ /* Analog codecs can go lower via magic registers but others
+ might not */
+
+ if(rate < 8000)
+ rate = 8000;
+
/* Power down the ADC */
dacp=i810_ac97_get(codec, AC97_POWER_CONTROL);
i810_ac97_set(codec, AC97_POWER_CONTROL, dacp|0x0100);
/* Load the rate and read the effective rate */
- i810_ac97_set(codec, AC97_PCM_LR_ADC_RATE, rate);
- rp=i810_ac97_get(codec, AC97_PCM_LR_ADC_RATE);
+ i810_ac97_set(codec, AC97_PCM_LR_DAC_RATE, rate);
+ rp=i810_ac97_get(codec, AC97_PCM_LR_DAC_RATE);
- printk("ADC rate set to %d Returned %d\n",
- rate, (int)rp);
+// printk("ADC rate set to %d Returned %d\n",
+// rate, (int)rp);
- rate=rp;
+ rate = (rp * 48000) / clocking;
/* Power it back up */
i810_ac97_set(codec, AC97_POWER_CONTROL, dacp);
@@ -1547,7 +1600,6 @@
state->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
up(&state->open_sem);
- MOD_INC_USE_COUNT;
return 0;
}
@@ -1582,11 +1634,11 @@
/* we're covered by the open_sem */
up(&state->open_sem);
- MOD_DEC_USE_COUNT;
return 0;
}
static /*const*/ struct file_operations i810_audio_fops = {
+ owner: THIS_MODULE,
llseek: i810_llseek,
read: i810_read,
write: i810_write,
@@ -1640,13 +1692,6 @@
match:
file->private_data = card->ac97_codec[i];
- MOD_INC_USE_COUNT;
- return 0;
-}
-
-static int i810_release_mixdev(struct inode *inode, struct file *file)
-{
- MOD_DEC_USE_COUNT;
return 0;
}
@@ -1659,10 +1704,10 @@
}
static /*const*/ struct file_operations i810_mixer_fops = {
+ owner: THIS_MODULE,
llseek: i810_llseek,
ioctl: i810_ioctl_mixdev,
open: i810_open_mixdev,
- release: i810_release_mixdev,
};
/* AC97 codec initialisation. */
@@ -1828,8 +1873,11 @@
kfree(card);
}
+
MODULE_AUTHOR("");
MODULE_DESCRIPTION("Intel 810 audio support");
+MODULE_PARM(ftsodell, "i");
+MODULE_PARM(clocking, "i");
#define I810_MODULE_NAME "intel810_audio"
@@ -1845,6 +1893,9 @@
if (!pci_present()) /* No PCI bus in this machine! */
return -ENODEV;
+ if(ftsodell==1)
+ clocking=41194;
+
printk(KERN_INFO "Intel 810 + AC97 Audio, version "
DRIVER_VERSION ", " __TIME__ " " __DATE__ "\n");
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)