Commit b35a6301 authored by Jaroslav Kysela's avatar Jaroslav Kysela Committed by Jaroslav Kysela

[PATCH] ALSA update [1/12] - 2002/08/09

  - Corrections for PCM sample silence (24-bits)
  - OPL3 code fixes (delays)
  - CS4281
    - added the power management code
    - added mixer controls for internal FM and PCM volumes
  - EMU10K1
    - fixed the dma mask
  - ICE1712
    - replaced EREMOTE with EIO
    - check the return value from ews88mt_chip_select()
  - Maestro3
    - corrected the wrong pci id for inspiron 8000
    - use the quirk list for gpio workarounds
parent 1d819b9d
/* include/version.h. Generated automatically by configure. */ /* include/version.h. Generated automatically by configure. */
#define CONFIG_SND_VERSION "0.9.0rc2" #define CONFIG_SND_VERSION "0.9.0rc2"
#define CONFIG_SND_DATE " (Mon Aug 05 14:24:05 2002 UTC)" #define CONFIG_SND_DATE " (Fri Aug 09 11:49:03 2002 UTC)"
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
* 2002-04-04 Tomas Kasparek better rates handling (allow non-standard rates) * 2002-04-04 Tomas Kasparek better rates handling (allow non-standard rates)
*/ */
/* $Id: sa11xx-uda1341.c,v 1.3 2002/05/25 10:26:06 perex Exp $ */ /* $Id: sa11xx-uda1341.c,v 1.4 2002/08/06 18:03:25 perex Exp $ */
#include <sound/driver.h> #include <sound/driver.h>
#include <linux/module.h> #include <linux/module.h>
......
...@@ -460,7 +460,6 @@ static int __init snd_ioctl32_init(void) ...@@ -460,7 +460,6 @@ static int __init snd_ioctl32_init(void)
return err; return err;
} }
#endif #endif
return 0; return 0;
} }
......
...@@ -329,6 +329,18 @@ u_int64_t snd_pcm_format_silence_64(snd_pcm_format_t format) ...@@ -329,6 +329,18 @@ u_int64_t snd_pcm_format_silence_64(snd_pcm_format_t format)
return 0x0000800000008000ULL; return 0x0000800000008000ULL;
case SNDRV_PCM_FORMAT_U32_BE: case SNDRV_PCM_FORMAT_U32_BE:
return 0x0000008000000080ULL; return 0x0000008000000080ULL;
case SNDRV_PCM_FORMAT_U24_3LE:
return 0x0000800000800000ULL;
case SNDRV_PCM_FORMAT_U24_3BE:
return 0x0080000080000080ULL;
case SNDRV_PCM_FORMAT_U20_3LE:
return 0x0000080000080000ULL;
case SNDRV_PCM_FORMAT_U20_3BE:
return 0x0008000008000008ULL;
case SNDRV_PCM_FORMAT_U18_3LE:
return 0x0000020000020000ULL;
case SNDRV_PCM_FORMAT_U18_3BE:
return 0x0002000002000002ULL;
#else #else
case SNDRV_PCM_FORMAT_U16_LE: case SNDRV_PCM_FORMAT_U16_LE:
return 0x0080008000800080ULL; return 0x0080008000800080ULL;
...@@ -342,16 +354,19 @@ u_int64_t snd_pcm_format_silence_64(snd_pcm_format_t format) ...@@ -342,16 +354,19 @@ u_int64_t snd_pcm_format_silence_64(snd_pcm_format_t format)
return 0x0080000000800000ULL; return 0x0080000000800000ULL;
case SNDRV_PCM_FORMAT_U32_BE: case SNDRV_PCM_FORMAT_U32_BE:
return 0x8000000080000000ULL; return 0x8000000080000000ULL;
#endif
case SNDRV_PCM_FORMAT_U24_3LE: case SNDRV_PCM_FORMAT_U24_3LE:
return 0x0080000080000080ULL;
case SNDRV_PCM_FORMAT_U24_3BE: case SNDRV_PCM_FORMAT_U24_3BE:
return 0x0000800000800000ULL; return 0x0000800000800000ULL;
case SNDRV_PCM_FORMAT_U20_3LE: case SNDRV_PCM_FORMAT_U20_3LE:
return 0x0008000008000008ULL;
case SNDRV_PCM_FORMAT_U20_3BE: case SNDRV_PCM_FORMAT_U20_3BE:
return 0x0000080000080000ULL; return 0x0000080000080000ULL;
case SNDRV_PCM_FORMAT_U18_3LE: case SNDRV_PCM_FORMAT_U18_3LE:
return 0x0002000002000002ULL;
case SNDRV_PCM_FORMAT_U18_3BE: case SNDRV_PCM_FORMAT_U18_3BE:
return 0x0000020000020000ULL; return 0x0000020000020000ULL;
#endif
case SNDRV_PCM_FORMAT_FLOAT_LE: case SNDRV_PCM_FORMAT_FLOAT_LE:
{ {
union { union {
...@@ -471,11 +486,16 @@ int snd_pcm_format_set_silence(snd_pcm_format_t format, void *data, unsigned int ...@@ -471,11 +486,16 @@ int snd_pcm_format_set_silence(snd_pcm_format_t format, void *data, unsigned int
if (! silence) if (! silence)
memset(data, 0, samples * 3); memset(data, 0, samples * 3);
else { else {
/* FIXME: rewrite in the more better way.. */
int i;
while (samples-- > 0) { while (samples-- > 0) {
for (i = 0; i < 3; i++) #ifdef SNDRV_LITTLE_ENDIAN
*((u_int8_t *)data)++ = silence >> (i * 8); *((u_int8_t *)data)++ = silence >> 0;
*((u_int8_t *)data)++ = silence >> 8;
*((u_int8_t *)data)++ = silence >> 16;
#else
*((u_int8_t *)data)++ = silence >> 16;
*((u_int8_t *)data)++ = silence >> 8;
*((u_int8_t *)data)++ = silence >> 0;
#endif
} }
} }
} }
......
...@@ -1616,7 +1616,6 @@ int snd_pcm_hw_constraints_complete(snd_pcm_substream_t *substream) ...@@ -1616,7 +1616,6 @@ int snd_pcm_hw_constraints_complete(snd_pcm_substream_t *substream)
snd_assert(err >= 0, return -EINVAL); snd_assert(err >= 0, return -EINVAL);
err = snd_pcm_hw_constraint_mask64(runtime, SNDRV_PCM_HW_PARAM_FORMAT, hw->formats); err = snd_pcm_hw_constraint_mask64(runtime, SNDRV_PCM_HW_PARAM_FORMAT, hw->formats);
//err = snd_pcm_hw_constraint_mask(runtime, SNDRV_PCM_HW_PARAM_FORMAT, hw->formats);
snd_assert(err >= 0, return -EINVAL); snd_assert(err >= 0, return -EINVAL);
err = snd_pcm_hw_constraint_mask(runtime, SNDRV_PCM_HW_PARAM_SUBFORMAT, 1 << SNDRV_PCM_SUBFORMAT_STD); err = snd_pcm_hw_constraint_mask(runtime, SNDRV_PCM_HW_PARAM_SUBFORMAT, 1 << SNDRV_PCM_SUBFORMAT_STD);
......
...@@ -101,8 +101,10 @@ void snd_opl3_cs4281_command(opl3_t * opl3, unsigned short cmd, unsigned char va ...@@ -101,8 +101,10 @@ void snd_opl3_cs4281_command(opl3_t * opl3, unsigned short cmd, unsigned char va
spin_lock_irqsave(&opl3->reg_lock, flags); spin_lock_irqsave(&opl3->reg_lock, flags);
writel((unsigned int)cmd, port << 2); writel((unsigned int)cmd, port << 2);
udelay(10);
writel((unsigned int)val, (port + 1) << 2); writel((unsigned int)val, (port + 1) << 2);
udelay(30);
spin_unlock_irqrestore(&opl3->reg_lock, flags); spin_unlock_irqrestore(&opl3->reg_lock, flags);
} }
......
...@@ -6,7 +6,7 @@ comment 'PCI devices' ...@@ -6,7 +6,7 @@ comment 'PCI devices'
dep_tristate 'ALi PCI Audio M5451' CONFIG_SND_ALI5451 $CONFIG_SND dep_tristate 'ALi PCI Audio M5451' CONFIG_SND_ALI5451 $CONFIG_SND
dep_tristate 'Cirrus Logic (Sound Fusion) CS4280/CS461x/CS462x/CS463x' CONFIG_SND_CS46XX $CONFIG_SND dep_tristate 'Cirrus Logic (Sound Fusion) CS4280/CS461x/CS462x/CS463x' CONFIG_SND_CS46XX $CONFIG_SND
dep_mbool ' Cirrus Logic (Sound Fusion) New DSP support (EXPERIMENTAL)' CONFIG_SND_CS46XX_NEW_DSP $CONFIG_SND_CS46XX $CONFIG_EXPERIMENTAL dep_mbool ' Cirrus Logic (Sound Fusion) New DSP support (EXPERIMENTAL)' CONFIG_SND_CS46XX_NEW_DSP $CONFIG_SND_CS46XX $CONFIG_EXPERIMENTAL
dep_tristate 'Cirrus Logic CS4281' CONFIG_SND_CS4281 $CONFIG_SND dep_tristate 'Cirrus Logic (Sound Fusion) CS4281' CONFIG_SND_CS4281 $CONFIG_SND
dep_tristate 'EMU10K1 (SB Live!, E-mu APS)' CONFIG_SND_EMU10K1 $CONFIG_SND dep_tristate 'EMU10K1 (SB Live!, E-mu APS)' CONFIG_SND_EMU10K1 $CONFIG_SND
dep_tristate 'Korg 1212 IO' CONFIG_SND_KORG1212 $CONFIG_SND dep_tristate 'Korg 1212 IO' CONFIG_SND_KORG1212 $CONFIG_SND
dep_tristate 'NeoMagic NM256AV/ZX' CONFIG_SND_NM256 $CONFIG_SND dep_tristate 'NeoMagic NM256AV/ZX' CONFIG_SND_NM256 $CONFIG_SND
......
This diff is collapsed.
...@@ -534,24 +534,31 @@ int __devinit snd_emu10k1_create(snd_card_t * card, ...@@ -534,24 +534,31 @@ int __devinit snd_emu10k1_create(snd_card_t * card,
{ {
emu10k1_t *emu; emu10k1_t *emu;
int err; int err;
int is_audigy;
static snd_device_ops_t ops = { static snd_device_ops_t ops = {
dev_free: snd_emu10k1_dev_free, dev_free: snd_emu10k1_dev_free,
}; };
*remu = NULL; *remu = NULL;
// is_audigy = (int)pci->driver_data;
is_audigy = (pci->device == 0x0004);
/* enable PCI device */ /* enable PCI device */
if ((err = pci_enable_device(pci)) < 0) if ((err = pci_enable_device(pci)) < 0)
return err; return err;
/* check, if we can restrict PCI DMA transfers to 31 bits */ /* set the DMA transfer mask */
if (!pci_dma_supported(pci, 0x7fffffff)) { if (is_audigy) {
snd_printk("architecture does not support 31bit PCI busmaster DMA\n"); if (pci_set_dma_mask(pci, 0xffffffff) < 0) {
return -ENXIO; snd_printk(KERN_ERR "architecture does not support 32bit PCI busmaster DMA\n");
return -ENXIO;
}
} else {
if (pci_set_dma_mask(pci, 0x1fffffff) < 0) {
snd_printk(KERN_ERR "architecture does not support 29bit PCI busmaster DMA\n");
return -ENXIO;
}
} }
if (pci_get_drvdata(pci))
pci_set_dma_mask(pci, 0xffffffff); /* audigy */
else
pci_set_dma_mask(pci, 0x7fffffff);
emu = snd_magic_kcalloc(emu10k1_t, 0, GFP_KERNEL); emu = snd_magic_kcalloc(emu10k1_t, 0, GFP_KERNEL);
if (emu == NULL) if (emu == NULL)
...@@ -572,11 +579,8 @@ int __devinit snd_emu10k1_create(snd_card_t * card, ...@@ -572,11 +579,8 @@ int __devinit snd_emu10k1_create(snd_card_t * card,
emu->get_synth_voice = NULL; emu->get_synth_voice = NULL;
emu->port = pci_resource_start(pci, 0); emu->port = pci_resource_start(pci, 0);
// emu->audigy = (int)pci->driver_data; emu->audigy = is_audigy;
if (pci->device == 0x0004) if (is_audigy)
emu->audigy = 1;
if (emu->audigy)
emu->gpr_base = A_FXGPREGBASE; emu->gpr_base = A_FXGPREGBASE;
else else
emu->gpr_base = FXGPREGBASE; emu->gpr_base = FXGPREGBASE;
......
...@@ -960,17 +960,25 @@ static snd_i2c_bit_ops_t snd_ice1712_ewx_cs8427_bit_ops = { ...@@ -960,17 +960,25 @@ static snd_i2c_bit_ops_t snd_ice1712_ewx_cs8427_bit_ops = {
}; };
/* AK4524 chip select; address 0x48 bit 0-3 */ /* AK4524 chip select; address 0x48 bit 0-3 */
static void snd_ice1712_ews88mt_chip_select(ice1712_t *ice, int chip_mask) static int snd_ice1712_ews88mt_chip_select(ice1712_t *ice, int chip_mask)
{ {
unsigned char data, ndata; unsigned char data, ndata;
snd_assert(chip_mask >= 0 && chip_mask <= 0x0f, return); snd_assert(chip_mask >= 0 && chip_mask <= 0x0f, return -EINVAL);
snd_i2c_lock(ice->i2c); snd_i2c_lock(ice->i2c);
snd_runtime_check(snd_i2c_readbytes(ice->pcf8574[1], &data, 1) == 1, snd_i2c_unlock(ice->i2c); return); if (snd_i2c_readbytes(ice->pcf8574[1], &data, 1) != 1)
goto __error;
ndata = (data & 0xf0) | chip_mask; ndata = (data & 0xf0) | chip_mask;
if (ndata != data) if (ndata != data)
snd_runtime_check(snd_i2c_sendbytes(ice->pcf8574[1], &ndata, 1) == 1, snd_i2c_unlock(ice->i2c); return); if (snd_i2c_sendbytes(ice->pcf8574[1], &ndata, 1) != 1)
goto __error;
snd_i2c_unlock(ice->i2c); snd_i2c_unlock(ice->i2c);
return 0;
__error:
snd_i2c_unlock(ice->i2c);
snd_printk(KERN_ERR "AK4524 chip select failed, check cable to the front module\n");
return -EIO;
} }
/* /*
...@@ -988,7 +996,8 @@ static void snd_ice1712_ak4524_write(ice1712_t *ice, int chip, ...@@ -988,7 +996,8 @@ static void snd_ice1712_ak4524_write(ice1712_t *ice, int chip,
if (ice->eeprom.subvendor == ICE1712_SUBDEVICE_EWS88MT) { if (ice->eeprom.subvendor == ICE1712_SUBDEVICE_EWS88MT) {
/* assert AK4524 CS */ /* assert AK4524 CS */
snd_ice1712_ews88mt_chip_select(ice, ~(1 << chip) & 0x0f); if (snd_ice1712_ews88mt_chip_select(ice, ~(1 << chip) & 0x0f) < 0)
return;
//snd_ice1712_ews88mt_chip_select(ice, 0x0f); //snd_ice1712_ews88mt_chip_select(ice, 0x0f);
} }
...@@ -1147,11 +1156,11 @@ static int snd_ice1712_cs8427_set_input_clock(ice1712_t *ice, int spdif_clock) ...@@ -1147,11 +1156,11 @@ static int snd_ice1712_cs8427_set_input_clock(ice1712_t *ice, int spdif_clock)
snd_i2c_lock(ice->i2c); snd_i2c_lock(ice->i2c);
if (snd_i2c_sendbytes(ice->cs8427, reg, 1) != 1) { if (snd_i2c_sendbytes(ice->cs8427, reg, 1) != 1) {
snd_i2c_unlock(ice->i2c); snd_i2c_unlock(ice->i2c);
return -EREMOTE; return -EIO;
} }
if (snd_i2c_readbytes(ice->cs8427, &val, 1) != 1) { if (snd_i2c_readbytes(ice->cs8427, &val, 1) != 1) {
snd_i2c_unlock(ice->i2c); snd_i2c_unlock(ice->i2c);
return -EREMOTE; return -EIO;
} }
nval = val & 0xf0; nval = val & 0xf0;
if (spdif_clock) if (spdif_clock)
...@@ -1161,7 +1170,7 @@ static int snd_ice1712_cs8427_set_input_clock(ice1712_t *ice, int spdif_clock) ...@@ -1161,7 +1170,7 @@ static int snd_ice1712_cs8427_set_input_clock(ice1712_t *ice, int spdif_clock)
if (val != nval) { if (val != nval) {
reg[1] = nval; reg[1] = nval;
if (snd_i2c_sendbytes(ice->cs8427, reg, 2) != 2) { if (snd_i2c_sendbytes(ice->cs8427, reg, 2) != 2) {
res = -EREMOTE; res = -EIO;
} else { } else {
res++; res++;
} }
...@@ -3187,7 +3196,7 @@ static int snd_ice1712_ews88mt_output_sense_get(snd_kcontrol_t *kcontrol, snd_ct ...@@ -3187,7 +3196,7 @@ static int snd_ice1712_ews88mt_output_sense_get(snd_kcontrol_t *kcontrol, snd_ct
snd_i2c_lock(ice->i2c); snd_i2c_lock(ice->i2c);
if (snd_i2c_readbytes(ice->pcf8574[1], &data, 1) != 1) { if (snd_i2c_readbytes(ice->pcf8574[1], &data, 1) != 1) {
snd_i2c_unlock(ice->i2c); snd_i2c_unlock(ice->i2c);
return -EREMOTE; return -EIO;
} }
snd_i2c_unlock(ice->i2c); snd_i2c_unlock(ice->i2c);
ucontrol->value.enumerated.item[0] = data & ICE1712_EWS88MT_OUTPUT_SENSE ? 1 : 0; /* high = -10dBV, low = +4dBu */ ucontrol->value.enumerated.item[0] = data & ICE1712_EWS88MT_OUTPUT_SENSE ? 1 : 0; /* high = -10dBV, low = +4dBu */
...@@ -3203,12 +3212,12 @@ static int snd_ice1712_ews88mt_output_sense_put(snd_kcontrol_t *kcontrol, snd_ct ...@@ -3203,12 +3212,12 @@ static int snd_ice1712_ews88mt_output_sense_put(snd_kcontrol_t *kcontrol, snd_ct
snd_i2c_lock(ice->i2c); snd_i2c_lock(ice->i2c);
if (snd_i2c_readbytes(ice->pcf8574[1], &data, 1) != 1) { if (snd_i2c_readbytes(ice->pcf8574[1], &data, 1) != 1) {
snd_i2c_unlock(ice->i2c); snd_i2c_unlock(ice->i2c);
return -EREMOTE; return -EIO;
} }
ndata = (data & ~ICE1712_EWS88MT_OUTPUT_SENSE) | (ucontrol->value.enumerated.item[0] ? ICE1712_EWS88MT_OUTPUT_SENSE : 0); ndata = (data & ~ICE1712_EWS88MT_OUTPUT_SENSE) | (ucontrol->value.enumerated.item[0] ? ICE1712_EWS88MT_OUTPUT_SENSE : 0);
if (ndata != data && snd_i2c_sendbytes(ice->pcf8574[1], &ndata, 1) != 1) { if (ndata != data && snd_i2c_sendbytes(ice->pcf8574[1], &ndata, 1) != 1) {
snd_i2c_unlock(ice->i2c); snd_i2c_unlock(ice->i2c);
return -EREMOTE; return -EIO;
} }
snd_i2c_unlock(ice->i2c); snd_i2c_unlock(ice->i2c);
return ndata != data; return ndata != data;
...@@ -3225,7 +3234,7 @@ static int snd_ice1712_ews88mt_input_sense_get(snd_kcontrol_t *kcontrol, snd_ctl ...@@ -3225,7 +3234,7 @@ static int snd_ice1712_ews88mt_input_sense_get(snd_kcontrol_t *kcontrol, snd_ctl
snd_i2c_lock(ice->i2c); snd_i2c_lock(ice->i2c);
if (snd_i2c_readbytes(ice->pcf8574[0], &data, 1) != 1) { if (snd_i2c_readbytes(ice->pcf8574[0], &data, 1) != 1) {
snd_i2c_unlock(ice->i2c); snd_i2c_unlock(ice->i2c);
return -EREMOTE; return -EIO;
} }
/* reversed; high = +4dBu, low = -10dBV */ /* reversed; high = +4dBu, low = -10dBV */
ucontrol->value.enumerated.item[0] = data & (1 << channel) ? 0 : 1; ucontrol->value.enumerated.item[0] = data & (1 << channel) ? 0 : 1;
...@@ -3243,12 +3252,12 @@ static int snd_ice1712_ews88mt_input_sense_put(snd_kcontrol_t *kcontrol, snd_ctl ...@@ -3243,12 +3252,12 @@ static int snd_ice1712_ews88mt_input_sense_put(snd_kcontrol_t *kcontrol, snd_ctl
snd_i2c_lock(ice->i2c); snd_i2c_lock(ice->i2c);
if (snd_i2c_readbytes(ice->pcf8574[0], &data, 1) != 1) { if (snd_i2c_readbytes(ice->pcf8574[0], &data, 1) != 1) {
snd_i2c_unlock(ice->i2c); snd_i2c_unlock(ice->i2c);
return -EREMOTE; return -EIO;
} }
ndata = (data & ~(1 << channel)) | (ucontrol->value.enumerated.item[0] ? 0 : (1 << channel)); ndata = (data & ~(1 << channel)) | (ucontrol->value.enumerated.item[0] ? 0 : (1 << channel));
if (ndata != data && snd_i2c_sendbytes(ice->pcf8574[0], &ndata, 1) != 1) { if (ndata != data && snd_i2c_sendbytes(ice->pcf8574[0], &ndata, 1) != 1) {
snd_i2c_unlock(ice->i2c); snd_i2c_unlock(ice->i2c);
return -EREMOTE; return -EIO;
} }
snd_i2c_unlock(ice->i2c); snd_i2c_unlock(ice->i2c);
return ndata != data; return ndata != data;
...@@ -3294,7 +3303,7 @@ static int snd_ice1712_ews88d_control_get(snd_kcontrol_t *kcontrol, snd_ctl_elem ...@@ -3294,7 +3303,7 @@ static int snd_ice1712_ews88d_control_get(snd_kcontrol_t *kcontrol, snd_ctl_elem
snd_i2c_lock(ice->i2c); snd_i2c_lock(ice->i2c);
if (snd_i2c_readbytes(ice->pcf8575, data, 2) != 2) { if (snd_i2c_readbytes(ice->pcf8575, data, 2) != 2) {
snd_i2c_unlock(ice->i2c); snd_i2c_unlock(ice->i2c);
return -EREMOTE; return -EIO;
} }
snd_i2c_unlock(ice->i2c); snd_i2c_unlock(ice->i2c);
data[0] = (data[shift >> 3] >> (shift & 7)) & 0x01; data[0] = (data[shift >> 3] >> (shift & 7)) & 0x01;
...@@ -3315,7 +3324,7 @@ static int snd_ice1712_ews88d_control_put(snd_kcontrol_t * kcontrol, snd_ctl_ele ...@@ -3315,7 +3324,7 @@ static int snd_ice1712_ews88d_control_put(snd_kcontrol_t * kcontrol, snd_ctl_ele
snd_i2c_lock(ice->i2c); snd_i2c_lock(ice->i2c);
if (snd_i2c_readbytes(ice->pcf8575, data, 2) != 2) { if (snd_i2c_readbytes(ice->pcf8575, data, 2) != 2) {
snd_i2c_unlock(ice->i2c); snd_i2c_unlock(ice->i2c);
return -EREMOTE; return -EIO;
} }
ndata[shift >> 3] = data[shift >> 3] & ~(1 << (shift & 7)); ndata[shift >> 3] = data[shift >> 3] & ~(1 << (shift & 7));
if (invert) { if (invert) {
...@@ -3328,7 +3337,7 @@ static int snd_ice1712_ews88d_control_put(snd_kcontrol_t * kcontrol, snd_ctl_ele ...@@ -3328,7 +3337,7 @@ static int snd_ice1712_ews88d_control_put(snd_kcontrol_t * kcontrol, snd_ctl_ele
change = (data[shift >> 3] != ndata[shift >> 3]); change = (data[shift >> 3] != ndata[shift >> 3]);
if (change && snd_i2c_sendbytes(ice->pcf8575, data, 2) != 2) { if (change && snd_i2c_sendbytes(ice->pcf8575, data, 2) != 2) {
snd_i2c_unlock(ice->i2c); snd_i2c_unlock(ice->i2c);
return -EREMOTE; return -EIO;
} }
snd_i2c_unlock(ice->i2c); snd_i2c_unlock(ice->i2c);
return change; return change;
...@@ -3366,7 +3375,7 @@ static int snd_ice1712_6fire_read_pca(ice1712_t *ice) ...@@ -3366,7 +3375,7 @@ static int snd_ice1712_6fire_read_pca(ice1712_t *ice)
snd_i2c_sendbytes(ice->pcf8575, &byte, 1); snd_i2c_sendbytes(ice->pcf8575, &byte, 1);
if (snd_i2c_readbytes(ice->pcf8575, &byte, 1) != 1) { if (snd_i2c_readbytes(ice->pcf8575, &byte, 1) != 1) {
snd_i2c_unlock(ice->i2c); snd_i2c_unlock(ice->i2c);
return -EREMOTE; return -EIO;
} }
snd_i2c_unlock(ice->i2c); snd_i2c_unlock(ice->i2c);
return byte; return byte;
...@@ -3380,7 +3389,7 @@ static int snd_ice1712_6fire_write_pca(ice1712_t *ice, unsigned char data) ...@@ -3380,7 +3389,7 @@ static int snd_ice1712_6fire_write_pca(ice1712_t *ice, unsigned char data)
bytes[1] = data; bytes[1] = data;
if (snd_i2c_sendbytes(ice->pcf8575, bytes, 2) != 2) { if (snd_i2c_sendbytes(ice->pcf8575, bytes, 2) != 2) {
snd_i2c_unlock(ice->i2c); snd_i2c_unlock(ice->i2c);
return -EREMOTE; return -EIO;
} }
snd_i2c_unlock(ice->i2c); snd_i2c_unlock(ice->i2c);
return 0; return 0;
...@@ -3836,11 +3845,15 @@ static int __devinit snd_ice1712_chip_init(ice1712_t *ice) ...@@ -3836,11 +3845,15 @@ static int __devinit snd_ice1712_chip_init(ice1712_t *ice)
} }
/* second stage of initialization, analog parts and others */ /* second stage of initialization, analog parts and others */
switch (ice->eeprom.subvendor) { switch (ice->eeprom.subvendor) {
case ICE1712_SUBDEVICE_EWS88MT:
/* Check if the front module is connected */
if ((err = snd_ice1712_ews88mt_chip_select(ice, 0x0f)) < 0)
return err;
/* Fall through */
case ICE1712_SUBDEVICE_DELTA66: case ICE1712_SUBDEVICE_DELTA66:
case ICE1712_SUBDEVICE_DELTA44: case ICE1712_SUBDEVICE_DELTA44:
case ICE1712_SUBDEVICE_AUDIOPHILE: case ICE1712_SUBDEVICE_AUDIOPHILE:
case ICE1712_SUBDEVICE_EWX2496: case ICE1712_SUBDEVICE_EWX2496:
case ICE1712_SUBDEVICE_EWS88MT:
case ICE1712_SUBDEVICE_DMX6FIRE: case ICE1712_SUBDEVICE_DMX6FIRE:
snd_ice1712_ak4524_init(ice); snd_ice1712_ak4524_init(ice);
break; break;
......
...@@ -776,6 +776,14 @@ typedef struct snd_m3 m3_t; ...@@ -776,6 +776,14 @@ typedef struct snd_m3 m3_t;
#define chip_t m3_t #define chip_t m3_t
/* quirk lists */
struct m3_quirk {
u16 vendor, device; /* subsystem ids */
int amp_gpio; /* gpio pin # for external amp, -1 = default */
int irda_workaround; /* non-zero if avoid to touch 0x10 on GPIO_DIRECTION
(e.g. for IrDA on Dell Inspirons) */
};
struct m3_list { struct m3_list {
int curlen; int curlen;
int mem_addr; int mem_addr;
...@@ -825,9 +833,7 @@ struct snd_m3 { ...@@ -825,9 +833,7 @@ struct snd_m3 {
snd_pcm_t *pcm; snd_pcm_t *pcm;
struct pci_dev *pci; struct pci_dev *pci;
/* pci_dev in 2.2 kernel doesn't have them, so we keep them private */ struct m3_quirk *quirk;
u16 subsystem_vendor;
u16 subsystem_device;
int dacs_active; int dacs_active;
int timer_users; int timer_users;
...@@ -908,6 +914,33 @@ static struct pci_device_id snd_m3_ids[] __devinitdata = { ...@@ -908,6 +914,33 @@ static struct pci_device_id snd_m3_ids[] __devinitdata = {
MODULE_DEVICE_TABLE(pci, snd_m3_ids); MODULE_DEVICE_TABLE(pci, snd_m3_ids);
static struct m3_quirk m3_quirk_list[] = {
/* panasonic CF-28 "toughbook" */
{
vendor: 0x10f7,
device: 0x833e,
amp_gpio: 0x0d,
},
/* Dell Inspiron 4000 */
{
vendor: 0x1028,
device: 0x00b0,
amp_gpio: -1,
irda_workaround: 1,
},
/* Dell Inspiron 8000 */
{
vendor: 0x1028,
device: 0x00a4,
amp_gpio: -1,
irda_workaround: 1,
},
/* FIXME: Inspiron 8100 and 8200 ids should be here, too */
/* END */
{ 0 }
};
/* /*
* lowlevel functions * lowlevel functions
*/ */
...@@ -1859,10 +1892,7 @@ static void snd_m3_ac97_reset(m3_t *chip, int busywait) ...@@ -1859,10 +1892,7 @@ static void snd_m3_ac97_reset(m3_t *chip, int busywait)
for (i = 0; i < 5; i++) { for (i = 0; i < 5; i++) {
dir = inw(io + GPIO_DIRECTION); dir = inw(io + GPIO_DIRECTION);
if (chip->subsystem_vendor == 0x1028 && if (! chip->quirk || ! chip->quirk->irda_workaround)
chip->subsystem_device == 0x00b0) /* Dell Inspiron 4000 */
; /* seems conflicting with IrDA */
else
dir |= 0x10; /* assuming pci bus master? */ dir |= 0x10; /* assuming pci bus master? */
snd_m3_remote_codec_config(io, 0); snd_m3_remote_codec_config(io, 0);
...@@ -2470,6 +2500,8 @@ snd_m3_create(snd_card_t *card, struct pci_dev *pci, ...@@ -2470,6 +2500,8 @@ snd_m3_create(snd_card_t *card, struct pci_dev *pci,
{ {
m3_t *chip; m3_t *chip;
int i, err; int i, err;
struct m3_quirk *quirk;
u16 subsystem_vendor, subsystem_device;
static snd_device_ops_t ops = { static snd_device_ops_t ops = {
dev_free: snd_m3_dev_free, dev_free: snd_m3_dev_free,
}; };
...@@ -2500,29 +2532,35 @@ snd_m3_create(snd_card_t *card, struct pci_dev *pci, ...@@ -2500,29 +2532,35 @@ snd_m3_create(snd_card_t *card, struct pci_dev *pci,
break; break;
} }
chip->card = card;
chip->pci = pci;
chip->irq = -1;
#ifndef LINUX_2_2 #ifndef LINUX_2_2
chip->subsystem_vendor = pci->subsystem_vendor; subsystem_vendor = pci->subsystem_vendor;
chip->subsystem_device = pci->subsystem_device; subsystem_device = pci->subsystem_device;
#else #else
pci_read_config_word(pci, PCI_SUBSYSTEM_VENDOR_ID, &chip->subsystem_vendor); pci_read_config_word(pci, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vendor);
pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &chip->subsystem_device); pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &subsystem_device);
#endif #endif
for (quirk = m3_quirk_list; quirk->vendor; quirk++) {
if (subsystem_vendor == quirk->vendor &&
subsystem_device == quirk->device) {
chip->quirk = quirk;
break;
}
}
chip->card = card;
chip->pci = pci;
chip->irq = -1;
chip->external_amp = enable_amp; chip->external_amp = enable_amp;
if (amp_gpio >= 0 && amp_gpio <= 0x0f) if (amp_gpio >= 0 && amp_gpio <= 0x0f)
chip->amp_gpio = amp_gpio; chip->amp_gpio = amp_gpio;
else if (chip->allegro_flag) { else if (chip->quirk && chip->quirk->amp_gpio >= 0)
/* panasonic CF-28 "toughbook" has different GPIO connection.. */ chip->amp_gpio = chip->quirk->amp_gpio;
if (chip->subsystem_vendor == 0x10f7 && else if (chip->allegro_flag)
chip->subsystem_device == 0x833e) chip->amp_gpio = GPO_EXT_AMP_ALLEGRO;
chip->amp_gpio = 0x0d; else /* presumably this is for all 'maestro3's.. */
else chip->amp_gpio = GPO_EXT_AMP_M3;
chip->amp_gpio = GPO_EXT_AMP_ALLEGRO;
} else
chip->amp_gpio = GPO_EXT_AMP_M3; /* presumably this is for all 'maestro3's.. */
chip->num_substreams = NR_DSPS; chip->num_substreams = NR_DSPS;
chip->substreams = kmalloc(sizeof(m3_dma_t) * chip->num_substreams, GFP_KERNEL); chip->substreams = kmalloc(sizeof(m3_dma_t) * chip->num_substreams, GFP_KERNEL);
if (chip->substreams == NULL) { if (chip->substreams == NULL) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment