Commit f7fb77bf authored by Jaroslav Kysela's avatar Jaroslav Kysela Committed by Linus Torvalds

[PATCH] ALSA update [3/10] - 2002/07/03

  - added support for spdif on coexant cx20468 chip
  - fixed compilation without CONFIG_PROC_FS
  - YMFPCI driver
    - fixed GPIO read/write
    - a new module option snd_rear_switch
  - ioctl32 - added support for old hw_params ioctl
  - ES1968 driver
    - enabled hw control IRQ
    - calling es1968_reset() in free()
  - VIA8233 driver - fixes for mono playback
parent 113ba560
...@@ -127,6 +127,14 @@ ...@@ -127,6 +127,14 @@
#define AC97_CSR_SPECF_DATA 0x6e /* Special Feature Data */ #define AC97_CSR_SPECF_DATA 0x6e /* Special Feature Data */
#define AC97_CSR_BDI_STATUS 0x7a /* BDI Status */ #define AC97_CSR_BDI_STATUS 0x7a /* BDI Status */
/* specific - Conexant */
#define AC97_CXR_AUDIO_MISC 0x5c
#define AC97_CXR_SPDIFEN (1<<3)
#define AC97_CXR_COPYRGT (1<<2)
#define AC97_CXR_SPDIF_MASK (3<<0)
#define AC97_CXR_SPDIF_PCM 0x0
#define AC97_CXR_SPDIF_AC3 0x2
/* ac97->scaps */ /* ac97->scaps */
#define AC97_SCAP_SURROUND_DAC (1<<0) /* surround L&R DACs are present */ #define AC97_SCAP_SURROUND_DAC (1<<0) /* surround L&R DACs are present */
#define AC97_SCAP_CENTER_LFE_DAC (1<<1) /* center and LFE DACs are present */ #define AC97_SCAP_CENTER_LFE_DAC (1<<1) /* center and LFE DACs are present */
...@@ -135,6 +143,7 @@ ...@@ -135,6 +143,7 @@
#define AC97_HAS_PC_BEEP (1<<0) /* force PC Speaker usage */ #define AC97_HAS_PC_BEEP (1<<0) /* force PC Speaker usage */
#define AC97_AD_MULTI (1<<1) /* Analog Devices - multi codecs */ #define AC97_AD_MULTI (1<<1) /* Analog Devices - multi codecs */
#define AC97_CS_SPDIF (1<<2) /* Cirrus Logic uses funky SPDIF */ #define AC97_CS_SPDIF (1<<2) /* Cirrus Logic uses funky SPDIF */
#define AC97_CX_SPDIF (1<<3) /* Conexant's spdif interface */
/* /*
......
...@@ -151,8 +151,8 @@ static inline int snd_info_done(void) { return 0; } ...@@ -151,8 +151,8 @@ static inline int snd_info_done(void) { return 0; }
static inline int snd_info_get_line(snd_info_buffer_t * buffer, char *line, int len) { return 0; } static inline int snd_info_get_line(snd_info_buffer_t * buffer, char *line, int len) { return 0; }
static inline char *snd_info_get_str(char *dest, char *src, int len) { return NULL; } static inline char *snd_info_get_str(char *dest, char *src, int len) { return NULL; }
static inline snd_info_entry_t *snd_info_create_module_entry(struct module * module, const char *name) { return NULL; } static inline snd_info_entry_t *snd_info_create_module_entry(struct module * module, const char *name, snd_info_entry_t *parent) { return NULL; }
static inline snd_info_entry_t *snd_info_create_card_entry(snd_card_t * card, const char *name) { return NULL; } static inline snd_info_entry_t *snd_info_create_card_entry(snd_card_t * card, const char *name, snd_info_entry_t *parent) { return NULL; }
static inline void snd_info_free_entry(snd_info_entry_t * entry) { ; } static inline void snd_info_free_entry(snd_info_entry_t * entry) { ; }
static inline snd_info_entry_t *snd_info_create_device(const char *name, static inline snd_info_entry_t *snd_info_create_device(const char *name,
unsigned int number, unsigned int number,
......
/* 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 " (Wed Jun 26 18:12:42 2002 UTC)" #define CONFIG_SND_DATE " (Wed Jul 03 16:51:35 2002 UTC)"
...@@ -358,7 +358,7 @@ int snd_ymfpci_pcm(ymfpci_t *chip, int device, snd_pcm_t **rpcm); ...@@ -358,7 +358,7 @@ int snd_ymfpci_pcm(ymfpci_t *chip, int device, snd_pcm_t **rpcm);
int snd_ymfpci_pcm2(ymfpci_t *chip, int device, snd_pcm_t **rpcm); int snd_ymfpci_pcm2(ymfpci_t *chip, int device, snd_pcm_t **rpcm);
int snd_ymfpci_pcm_spdif(ymfpci_t *chip, int device, snd_pcm_t **rpcm); int snd_ymfpci_pcm_spdif(ymfpci_t *chip, int device, snd_pcm_t **rpcm);
int snd_ymfpci_pcm_4ch(ymfpci_t *chip, int device, snd_pcm_t **rpcm); int snd_ymfpci_pcm_4ch(ymfpci_t *chip, int device, snd_pcm_t **rpcm);
int snd_ymfpci_mixer(ymfpci_t *chip); int snd_ymfpci_mixer(ymfpci_t *chip, int rear_switch);
int snd_ymfpci_joystick(ymfpci_t *chip); int snd_ymfpci_joystick(ymfpci_t *chip);
int snd_ymfpci_voice_alloc(ymfpci_t *chip, ymfpci_voice_type_t type, int pair, ymfpci_voice_t **rvoice); int snd_ymfpci_voice_alloc(ymfpci_t *chip, ymfpci_voice_type_t type, int pair, ymfpci_voice_t **rvoice);
......
...@@ -55,7 +55,9 @@ struct sndrv_interval32 { ...@@ -55,7 +55,9 @@ struct sndrv_interval32 {
struct sndrv_pcm_hw_params32 { struct sndrv_pcm_hw_params32 {
u32 flags; u32 flags;
struct sndrv_mask masks[SNDRV_PCM_HW_PARAM_LAST_MASK - SNDRV_PCM_HW_PARAM_FIRST_MASK + 1]; /* this must be identical */ struct sndrv_mask masks[SNDRV_PCM_HW_PARAM_LAST_MASK - SNDRV_PCM_HW_PARAM_FIRST_MASK + 1]; /* this must be identical */
struct sndrv_mask mres[5]; /* reserved masks */
struct sndrv_interval32 intervals[SNDRV_PCM_HW_PARAM_LAST_INTERVAL - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL + 1]; struct sndrv_interval32 intervals[SNDRV_PCM_HW_PARAM_LAST_INTERVAL - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL + 1];
struct sndrv_interval ires[9]; /* reserved intervals */
u32 rmask; u32 rmask;
u32 cmask; u32 cmask;
u32 info; u32 info;
......
...@@ -68,8 +68,8 @@ static long long snd_gf1_mem_proc_llseek(snd_info_entry_t *entry, ...@@ -68,8 +68,8 @@ static long long snd_gf1_mem_proc_llseek(snd_info_entry_t *entry,
case 1: /* SEEK_CUR */ case 1: /* SEEK_CUR */
file->f_pos += offset; file->f_pos += offset;
break; break;
case 2: /* SEEK_END */ case 2: /* SEEK_END, offset is negative */
file->f_pos = priv->size - offset; file->f_pos = priv->size + offset;
break; break;
default: default:
return -EINVAL; return -EINVAL;
......
...@@ -61,6 +61,7 @@ static int patch_sigmatel_stac9744(ac97_t * ac97); ...@@ -61,6 +61,7 @@ static int patch_sigmatel_stac9744(ac97_t * ac97);
static int patch_sigmatel_stac9756(ac97_t * ac97); static int patch_sigmatel_stac9756(ac97_t * ac97);
static int patch_cirrus_cs4299(ac97_t * ac97); static int patch_cirrus_cs4299(ac97_t * ac97);
static int patch_cirrus_spdif(ac97_t * ac97); static int patch_cirrus_spdif(ac97_t * ac97);
static int patch_conexant(ac97_t * ac97);
static int patch_ad1819(ac97_t * ac97); static int patch_ad1819(ac97_t * ac97);
static int patch_ad1881(ac97_t * ac97); static int patch_ad1881(ac97_t * ac97);
static int patch_ad1886(ac97_t * ac97); static int patch_ad1886(ac97_t * ac97);
...@@ -143,6 +144,7 @@ static const ac97_codec_id_t snd_ac97_codec_ids[] = { ...@@ -143,6 +144,7 @@ static const ac97_codec_id_t snd_ac97_codec_ids[] = {
{ 0x83847644, 0xffffffff, "STAC9744", patch_sigmatel_stac9744 }, { 0x83847644, 0xffffffff, "STAC9744", patch_sigmatel_stac9744 },
{ 0x83847656, 0xffffffff, "STAC9756/57", patch_sigmatel_stac9756 }, { 0x83847656, 0xffffffff, "STAC9756/57", patch_sigmatel_stac9756 },
{ 0x45838308, 0xffffffff, "ESS1988", NULL }, { 0x45838308, 0xffffffff, "ESS1988", NULL },
{ 0x43585429, 0xffffffff, "Cx20468", patch_conexant },
{ 0, 0, NULL, NULL } { 0, 0, NULL, NULL }
}; };
...@@ -766,6 +768,13 @@ static int snd_ac97_spdif_default_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_val ...@@ -766,6 +768,13 @@ static int snd_ac97_spdif_default_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_val
default: x = 0; break; // illegal. default: x = 0; break; // illegal.
} }
change = snd_ac97_update_bits(ac97, AC97_CSR_SPDIF, 0x3fff, ((val & 0xcfff) | (x << 12))); change = snd_ac97_update_bits(ac97, AC97_CSR_SPDIF, 0x3fff, ((val & 0xcfff) | (x << 12)));
} else if (ac97->flags & AC97_CX_SPDIF) {
int v;
v = ucontrol->value.iec958.status[0] & (IEC958_AES0_CON_EMPHASIS_5015|IEC958_AES0_CON_NOT_COPYRIGHT) ? 0 : AC97_CXR_COPYRGT;
v |= ucontrol->value.iec958.status[0] & IEC958_AES0_NONAUDIO ? AC97_CXR_SPDIF_AC3 : AC97_CXR_SPDIF_PCM;
change = snd_ac97_update_bits(ac97, AC97_CXR_AUDIO_MISC,
AC97_CXR_SPDIF_MASK | AC97_CXR_COPYRGT,
v);
} else { } else {
change = snd_ac97_update_bits(ac97, AC97_SPDIF, 0x3fff, val); change = snd_ac97_update_bits(ac97, AC97_SPDIF, 0x3fff, val);
} }
...@@ -808,6 +817,10 @@ static const snd_kcontrol_new_t snd_ac97_cirrus_controls_spdif[2] = { ...@@ -808,6 +817,10 @@ static const snd_kcontrol_new_t snd_ac97_cirrus_controls_spdif[2] = {
AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "AC97-SPSA", AC97_CSR_ACMODE, 0, 3, 0) AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "AC97-SPSA", AC97_CSR_ACMODE, 0, 3, 0)
}; };
static const snd_kcontrol_new_t snd_ac97_conexant_controls_spdif[2] = {
AC97_SINGLE(SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), AC97_CXR_AUDIO_MISC, 3, 1, 0),
};
#define AD18XX_PCM_BITS(xname, codec, shift, mask) \ #define AD18XX_PCM_BITS(xname, codec, shift, mask) \
{ iface: SNDRV_CTL_ELEM_IFACE_MIXER, name: xname, info: snd_ac97_ad18xx_pcm_info_bits, \ { iface: SNDRV_CTL_ELEM_IFACE_MIXER, name: xname, info: snd_ac97_ad18xx_pcm_info_bits, \
get: snd_ac97_ad18xx_pcm_get_bits, put: snd_ac97_ad18xx_pcm_put_bits, \ get: snd_ac97_ad18xx_pcm_get_bits, put: snd_ac97_ad18xx_pcm_put_bits, \
...@@ -1342,6 +1355,17 @@ static int snd_ac97_mixer_build(snd_card_t * card, ac97_t * ac97) ...@@ -1342,6 +1355,17 @@ static int snd_ac97_mixer_build(snd_card_t * card, ac97_t * ac97)
/* set default PCM S/PDIF params */ /* set default PCM S/PDIF params */
/* consumer,PCM audio,no copyright,no preemphasis,PCM coder,original,48000Hz */ /* consumer,PCM audio,no copyright,no preemphasis,PCM coder,original,48000Hz */
snd_ac97_write_cache(ac97, AC97_CSR_SPDIF, 0x0a20); snd_ac97_write_cache(ac97, AC97_CSR_SPDIF, 0x0a20);
} else if (ac97->flags & AC97_CX_SPDIF) {
for (idx = 0; idx < 3; idx++)
if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_spdif[idx], ac97))) < 0)
return err;
if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_conexant_controls_spdif[0], ac97))) < 0)
return err;
/* set default PCM S/PDIF params */
/* consumer,PCM audio,no copyright,no preemphasis,PCM coder,original,48000Hz */
snd_ac97_write_cache(ac97, AC97_CXR_AUDIO_MISC,
snd_ac97_read(ac97, AC97_CXR_AUDIO_MISC) & ~(AC97_CXR_SPDIFEN|AC97_CXR_COPYRGT|AC97_CXR_SPDIF_MASK));
} else { } else {
for (idx = 0; idx < 5; idx++) for (idx = 0; idx < 5; idx++)
if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_spdif[idx], ac97))) < 0) if ((err = snd_ctl_add(card, snd_ac97_cnew(&snd_ac97_controls_spdif[idx], ac97))) < 0)
...@@ -1970,6 +1994,13 @@ static int patch_cirrus_cs4299(ac97_t * ac97) ...@@ -1970,6 +1994,13 @@ static int patch_cirrus_cs4299(ac97_t * ac97)
return patch_cirrus_spdif(ac97); return patch_cirrus_spdif(ac97);
} }
static int patch_conexant(ac97_t * ac97)
{
ac97->flags |= AC97_CX_SPDIF;
ac97->ext_id |= AC97_EA_SPDIF; /* force the detection of spdif */
return 0;
}
static int patch_ad1819(ac97_t * ac97) static int patch_ad1819(ac97_t * ac97)
{ {
// patch for Analog Devices // patch for Analog Devices
......
...@@ -1129,7 +1129,7 @@ static void snd_es1968_playback_setup(es1968_t *chip, esschan_t *es, ...@@ -1129,7 +1129,7 @@ static void snd_es1968_playback_setup(es1968_t *chip, esschan_t *es,
/* clear WP interupts */ /* clear WP interupts */
outw(1, chip->io_port + 0x04); outw(1, chip->io_port + 0x04);
/* enable WP ints */ /* enable WP ints */
outw(inw(chip->io_port + 0x18) | 4, chip->io_port + 0x18); outw(inw(chip->io_port + ESM_PORT_HOST_IRQ) | ESM_HIRQ_DSIE, chip->io_port + ESM_PORT_HOST_IRQ);
spin_unlock_irqrestore(&chip->reg_lock, flags); spin_unlock_irqrestore(&chip->reg_lock, flags);
freq = runtime->rate; freq = runtime->rate;
...@@ -1260,7 +1260,7 @@ static void snd_es1968_capture_setup(es1968_t *chip, esschan_t *es, ...@@ -1260,7 +1260,7 @@ static void snd_es1968_capture_setup(es1968_t *chip, esschan_t *es,
/* clear WP interupts */ /* clear WP interupts */
outw(1, chip->io_port + 0x04); outw(1, chip->io_port + 0x04);
/* enable WP ints */ /* enable WP ints */
outw(inw(chip->io_port + 0x18) | 4, chip->io_port + 0x18); outw(inw(chip->io_port + ESM_PORT_HOST_IRQ) | ESM_HIRQ_DSIE, chip->io_port + ESM_PORT_HOST_IRQ);
spin_unlock_irqrestore(&chip->reg_lock, flags); spin_unlock_irqrestore(&chip->reg_lock, flags);
freq = runtime->rate; freq = runtime->rate;
...@@ -1821,7 +1821,7 @@ static void __devinit es1968_measure_clock(es1968_t *chip) ...@@ -1821,7 +1821,7 @@ static void __devinit es1968_measure_clock(es1968_t *chip)
apu_set_register(chip, apu, 11, 0x0000); apu_set_register(chip, apu, 11, 0x0000);
spin_lock_irqsave(&chip->reg_lock, flags); spin_lock_irqsave(&chip->reg_lock, flags);
outw(1, chip->io_port + 0x04); /* clear WP interupts */ outw(1, chip->io_port + 0x04); /* clear WP interupts */
outw(inw(chip->io_port + 0x18) | 4, chip->io_port + 0x18); /* enable WP ints */ outw(inw(chip->io_port + ESM_PORT_HOST_IRQ) | ESM_HIRQ_DSIE, chip->io_port + ESM_PORT_HOST_IRQ); /* enable WP ints */
spin_unlock_irqrestore(&chip->reg_lock, flags); spin_unlock_irqrestore(&chip->reg_lock, flags);
snd_es1968_apu_set_freq(chip, apu, ((unsigned int)48000 << 16) / chip->clock); /* 48000 Hz */ snd_es1968_apu_set_freq(chip, apu, ((unsigned int)48000 << 16) / chip->clock); /* 48000 Hz */
...@@ -2328,9 +2328,10 @@ static void snd_es1968_chip_init(es1968_t *chip) ...@@ -2328,9 +2328,10 @@ static void snd_es1968_chip_init(es1968_t *chip)
outb(0, iobase + ASSP_CONTROL_C); /* M: Disable ASSP, ASSP IRQ's and FM Port */ outb(0, iobase + ASSP_CONTROL_C); /* M: Disable ASSP, ASSP IRQ's and FM Port */
/* Enable IRQ's */ /* Enable IRQ's */
w = ESM_HIRQ_DSIE | ESM_HIRQ_MPU401; w = ESM_HIRQ_DSIE | ESM_HIRQ_MPU401 | ESM_HIRQ_HW_VOLUME;
outw(w, iobase + ESM_PORT_HOST_IRQ); outw(w, iobase + ESM_PORT_HOST_IRQ);
/* /*
* set up wavecache * set up wavecache
*/ */
...@@ -2502,6 +2503,7 @@ static int snd_es1968_free(es1968_t *chip) ...@@ -2502,6 +2503,7 @@ static int snd_es1968_free(es1968_t *chip)
chip->master_switch = NULL; chip->master_switch = NULL;
chip->master_volume = NULL; chip->master_volume = NULL;
if (chip->res_io_port) { if (chip->res_io_port) {
snd_es1968_reset(chip);
release_resource(chip->res_io_port); release_resource(chip->res_io_port);
kfree_nocheck(chip->res_io_port); kfree_nocheck(chip->res_io_port);
} }
......
...@@ -364,7 +364,7 @@ static void snd_via8233_setup_periods(via8233_t *chip, viadev_t *viadev, ...@@ -364,7 +364,7 @@ static void snd_via8233_setup_periods(via8233_t *chip, viadev_t *viadev,
outb(fmt, chip->port + VIA_REG_MULTPLAY_FORMAT); outb(fmt, chip->port + VIA_REG_MULTPLAY_FORMAT);
/* set sample number to slot 3, 4, 7, 8, 6, 9 */ /* set sample number to slot 3, 4, 7, 8, 6, 9 */
switch (runtime->channels) { switch (runtime->channels) {
case 1: slots = (1<<0); break; case 1: slots = (1<<0) | (1<<4); break;
case 2: slots = (1<<0) | (2<<4); break; case 2: slots = (1<<0) | (2<<4); break;
case 4: slots = (1<<0) | (2<<4) | (3<<8) | (4<<12); break; case 4: slots = (1<<0) | (2<<4) | (3<<8) | (4<<12); break;
case 6: slots = (1<<0) | (2<<4) | (5<<8) | (6<<12) | (3<<16) | (4<<20); break; case 6: slots = (1<<0) | (2<<4) | (5<<8) | (6<<12) | (3<<16) | (4<<20); break;
......
...@@ -46,6 +46,7 @@ static char *snd_id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ ...@@ -46,6 +46,7 @@ static char *snd_id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
static int snd_enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */ static int snd_enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
static long snd_fm_port[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -1}; static long snd_fm_port[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -1};
static long snd_mpu_port[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -1}; static long snd_mpu_port[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -1};
static int snd_rear_switch[SNDRV_CARDS];
MODULE_PARM(snd_index, "1-" __MODULE_STRING(SNDRV_CARDS) "i"); MODULE_PARM(snd_index, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(snd_index, "Index value for the Yamaha DS-XG PCI soundcard."); MODULE_PARM_DESC(snd_index, "Index value for the Yamaha DS-XG PCI soundcard.");
...@@ -62,6 +63,9 @@ MODULE_PARM_SYNTAX(snd_mpu_port, SNDRV_ENABLED); ...@@ -62,6 +63,9 @@ MODULE_PARM_SYNTAX(snd_mpu_port, SNDRV_ENABLED);
MODULE_PARM(snd_fm_port, "1-" __MODULE_STRING(SNDRV_CARDS) "l"); MODULE_PARM(snd_fm_port, "1-" __MODULE_STRING(SNDRV_CARDS) "l");
MODULE_PARM_DESC(snd_fm_port, "FM OPL-3 Port."); MODULE_PARM_DESC(snd_fm_port, "FM OPL-3 Port.");
MODULE_PARM_SYNTAX(snd_fm_port, SNDRV_ENABLED); MODULE_PARM_SYNTAX(snd_fm_port, SNDRV_ENABLED);
MODULE_PARM(snd_rear_switch, "1-" __MODULE_STRING(SNDRV_CARDS) "i");
MODULE_PARM_DESC(snd_rear_switch, "Enable shared rear/line-in switch");
MODULE_PARM_SYNTAX(snd_rear_switch, SNDRV_ENABLED "," SNDRV_BOOLEAN_FALSE_DESC);
static struct pci_device_id snd_ymfpci_ids[] __devinitdata = { static struct pci_device_id snd_ymfpci_ids[] __devinitdata = {
{ 0x1073, 0x0004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* YMF724 */ { 0x1073, 0x0004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0, }, /* YMF724 */
...@@ -189,7 +193,7 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci, ...@@ -189,7 +193,7 @@ static int __devinit snd_card_ymfpci_probe(struct pci_dev *pci,
snd_card_free(card); snd_card_free(card);
return err; return err;
} }
if ((err = snd_ymfpci_mixer(chip)) < 0) { if ((err = snd_ymfpci_mixer(chip, snd_rear_switch[dev])) < 0) {
snd_card_free(card); snd_card_free(card);
return err; return err;
} }
......
...@@ -1560,30 +1560,36 @@ YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0, YDSXGR_SPDIFINCTRL), ...@@ -1560,30 +1560,36 @@ YMFPCI_SINGLE(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0, YDSXGR_SPDIFINCTRL),
static int snd_ymfpci_get_gpio_out(ymfpci_t *chip, int pin) static int snd_ymfpci_get_gpio_out(ymfpci_t *chip, int pin)
{ {
u16 reg, ctrl; u16 reg, mode;
unsigned long flags; unsigned long flags;
reg = ~(1 << pin) & 0xff;
ctrl = 0xff00 | reg;
spin_lock_irqsave(&chip->reg_lock, flags); spin_lock_irqsave(&chip->reg_lock, flags);
snd_ymfpci_writew(chip, YDSXGR_GPIOFUNCENABLE, ctrl); reg = snd_ymfpci_readw(chip, YDSXGR_GPIOFUNCENABLE);
ctrl = snd_ymfpci_readw(chip, YDSXGR_GPIOINSTATUS); reg &= ~(1 << (pin + 8));
reg |= (1 << pin);
snd_ymfpci_writew(chip, YDSXGR_GPIOFUNCENABLE, reg);
/* set the level mode for input line */
mode = snd_ymfpci_readw(chip, YDSXGR_GPIOTYPECONFIG);
mode &= ~(3 << (pin * 2));
snd_ymfpci_writew(chip, YDSXGR_GPIOTYPECONFIG, mode);
snd_ymfpci_writew(chip, YDSXGR_GPIOFUNCENABLE, reg | (1 << (pin + 8)));
mode = snd_ymfpci_readw(chip, YDSXGR_GPIOINSTATUS);
spin_unlock_irqrestore(&chip->reg_lock, flags); spin_unlock_irqrestore(&chip->reg_lock, flags);
return (ctrl >> pin) & 1; return (mode >> pin) & 1;
} }
static int snd_ymfpci_set_gpio_out(ymfpci_t *chip, int pin, int enable) static int snd_ymfpci_set_gpio_out(ymfpci_t *chip, int pin, int enable)
{ {
u16 reg, ctrl; u16 reg;
unsigned long flags; unsigned long flags;
reg = ~(1 << pin) & 0xff;
ctrl = (reg << 8) | reg;
spin_lock_irqsave(&chip->reg_lock, flags); spin_lock_irqsave(&chip->reg_lock, flags);
snd_ymfpci_writew(chip, YDSXGR_GPIOFUNCENABLE, ctrl); reg = snd_ymfpci_readw(chip, YDSXGR_GPIOFUNCENABLE);
reg &= ~(1 << pin);
reg &= ~(1 << (pin + 8));
snd_ymfpci_writew(chip, YDSXGR_GPIOFUNCENABLE, reg);
snd_ymfpci_writew(chip, YDSXGR_GPIOOUTCTRL, enable << pin); snd_ymfpci_writew(chip, YDSXGR_GPIOOUTCTRL, enable << pin);
ctrl = 0xff00 | reg; snd_ymfpci_writew(chip, YDSXGR_GPIOFUNCENABLE, reg | (1 << (pin + 8)));
snd_ymfpci_writew(chip, YDSXGR_GPIOFUNCENABLE, ctrl);
spin_unlock_irqrestore(&chip->reg_lock, flags); spin_unlock_irqrestore(&chip->reg_lock, flags);
return 0; return 0;
...@@ -1639,7 +1645,7 @@ static void snd_ymfpci_mixer_free_ac97(ac97_t *ac97) ...@@ -1639,7 +1645,7 @@ static void snd_ymfpci_mixer_free_ac97(ac97_t *ac97)
chip->ac97 = NULL; chip->ac97 = NULL;
} }
int __devinit snd_ymfpci_mixer(ymfpci_t *chip) int __devinit snd_ymfpci_mixer(ymfpci_t *chip, int rear_switch)
{ {
ac97_t ac97; ac97_t ac97;
snd_kcontrol_t *kctl; snd_kcontrol_t *kctl;
...@@ -1673,10 +1679,11 @@ int __devinit snd_ymfpci_mixer(ymfpci_t *chip) ...@@ -1673,10 +1679,11 @@ int __devinit snd_ymfpci_mixer(ymfpci_t *chip)
/* /*
* shared rear/line-in * shared rear/line-in
* FIXME: should be only on supported models - checking subdevice
*/ */
if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_ymfpci_rear_shared, chip))) < 0) if (rear_switch) {
return err; if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_ymfpci_rear_shared, chip))) < 0)
return err;
}
return 0; return 0;
} }
......
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