#include <sound/pcm.h>
#include <sound/ac97_codec.h>
#include <sound/info.h>
+#include <sound/control.h>
#include <sound/initval.h>
MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>");
"{Intel,82801CA-ICH3},"
"{Intel,82801DB-ICH4},"
"{Intel,ICH5},"
+ "{Intel,ICH6},"
+ "{Intel,ICH7},"
"{Intel,MX440},"
"{SiS,7013},"
"{NVidia,NForce Modem},"
"{NVidia,NForce3 Modem},"
"{AMD,AMD768}}");
-static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */
+static int index[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = -2}; /* Exclude the first card */
static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */
static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card */
static int ac97_clock[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS - 1)] = 0};
#ifndef PCI_DEVICE_ID_INTEL_ICH5_6
#define PCI_DEVICE_ID_INTEL_ICH5_6 0x24d6
#endif
+#ifndef PCI_DEVICE_ID_INTEL_ICH6_6
+#define PCI_DEVICE_ID_INTEL_ICH6_6 0x266d
+#endif
+#ifndef PCI_DEVICE_ID_INTEL_ICH7_6
+#define PCI_DEVICE_ID_INTEL_ICH7_6 0x27dd
+#endif
#ifndef PCI_DEVICE_ID_SI_7013
#define PCI_DEVICE_ID_SI_7013 0x7013
#endif
snd_pcm_t *pcm[2];
ichdev_t ichd[2];
- int in_ac97_init: 1;
+ unsigned int in_ac97_init: 1;
ac97_bus_t *ac97_bus;
ac97_t *ac97;
{ 0x8086, 0x2486, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* ICH3 */
{ 0x8086, 0x24c6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* ICH4 */
{ 0x8086, 0x24d6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* ICH5 */
+ { 0x8086, 0x266d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* ICH6 */
+ { 0x8086, 0x27dd, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* ICH7 */
{ 0x8086, 0x7196, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* 440MX */
{ 0x1022, 0x7446, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_INTEL }, /* AMD768 */
{ 0x1039, 0x7013, PCI_ANY_ID, PCI_ANY_ID, 0, 0, DEVICE_SIS }, /* SI7013 */
#endif
{ 0, }
};
+static int snd_intel8x0m_switch_default_get(snd_kcontrol_t *kcontrol,
+ snd_ctl_elem_value_t *ucontrol);
+static int snd_intel8x0m_switch_default_put(snd_kcontrol_t *kcontrol,
+ snd_ctl_elem_value_t *ucontrol);
+static int snd_intel8x0m_switch_default_info(snd_kcontrol_t *kcontrol,
+ snd_ctl_elem_info_t *uinfo);
+
+#define PRIVATE_VALUE_INITIALIZER(r,m) (((r) & 0xffff) << 16 | ((m) & 0xffff))
+#define PRIVATE_VALUE_MASK(control) ((control)->private_value & 0xffff)
+#define PRIVATE_VALUE_REG(control) (((control)->private_value >> 16) & 0xffff)
+
+static snd_kcontrol_new_t snd_intel8x0m_mixer_switches[] __devinitdata = {
+ { .name = "Off-hook Switch",
+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+ .info = snd_intel8x0m_switch_default_info,
+ .get = snd_intel8x0m_switch_default_get,
+ .put = snd_intel8x0m_switch_default_put,
+ .private_value = PRIVATE_VALUE_INITIALIZER(AC97_GPIO_STATUS,AC97_GPIO_LINE1_OH)
+ }
+};
MODULE_DEVICE_TABLE(pci, snd_intel8x0m_ids);
+static int snd_intel8x0m_switch_default_info(snd_kcontrol_t *kcontrol,
+ snd_ctl_elem_info_t *uinfo)
+{
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
+ uinfo->count = 1;
+ uinfo->value.integer.min = 0;
+ uinfo->value.integer.max = 1;
+ return 0;
+}
+
+static int snd_intel8x0m_switch_default_get(snd_kcontrol_t *kcontrol,
+ snd_ctl_elem_value_t *ucontrol)
+{
+ unsigned short mask = PRIVATE_VALUE_MASK(kcontrol);
+ unsigned short reg = PRIVATE_VALUE_REG(kcontrol);
+ intel8x0_t *chip = snd_kcontrol_chip(kcontrol);
+ unsigned int status;
+ status = snd_ac97_read(chip->ac97, reg) & mask ? 1 : 0;
+ ucontrol->value.integer.value[0] = status;
+ return 0;
+}
+static int snd_intel8x0m_switch_default_put(snd_kcontrol_t *kcontrol,
+ snd_ctl_elem_value_t *ucontrol)
+{
+ unsigned short mask = PRIVATE_VALUE_MASK(kcontrol);
+ unsigned short reg = PRIVATE_VALUE_REG(kcontrol);
+ intel8x0_t *chip = snd_kcontrol_chip(kcontrol);
+ unsigned short new_status = ucontrol->value.integer.value[0] ? mask : ~mask;
+ return snd_ac97_update_bits(chip->ac97, reg,
+ mask, new_status);
+}
/*
* Lowlevel I/O - busmaster
*/
static int snd_intel8x0m_pcm_trigger(snd_pcm_substream_t *substream, int cmd)
{
- ichdev_t *ichdev = get_ichdev(substream);
/* hook off/on on start/stop */
- /* TODO: move it to ac97 controls */
+ /* Moved this to mixer control */
switch (cmd) {
case SNDRV_PCM_TRIGGER_START:
- snd_ac97_update_bits(ichdev->ac97, AC97_GPIO_STATUS,
- AC97_GPIO_LINE1_OH, AC97_GPIO_LINE1_OH);
break;
case SNDRV_PCM_TRIGGER_STOP:
- snd_ac97_update_bits(ichdev->ac97, AC97_GPIO_STATUS,
- AC97_GPIO_LINE1_OH, ~AC97_GPIO_LINE1_OH);
break;
default:
return -EINVAL;
ac97_t *x97;
int err;
unsigned int glob_sta = 0;
+ unsigned int idx;
static ac97_bus_ops_t ops = {
.write = snd_intel8x0_codec_write,
.read = snd_intel8x0_codec_read,
return err;
}
chip->ac97 = x97;
- if(ac97_is_modem(x97) && !chip->ichd[ICHD_MDMIN].ac97 ) {
+ if(ac97_is_modem(x97) && !chip->ichd[ICHD_MDMIN].ac97) {
chip->ichd[ICHD_MDMIN].ac97 = x97;
chip->ichd[ICHD_MDMOUT].ac97 = x97;
}
+ for (idx = 0; idx < ARRAY_SIZE(snd_intel8x0m_mixer_switches); idx++) {
+ if ((err = snd_ctl_add(chip->card, snd_ctl_new1(&snd_intel8x0m_mixer_switches[idx], chip))) < 0)
+ goto __err;
+ }
chip->in_ac97_init = 0;
return 0;
/*
* power management
*/
-static int intel8x0m_suspend(snd_card_t *card, unsigned int state)
+static int intel8x0m_suspend(snd_card_t *card, pm_message_t state)
{
intel8x0_t *chip = card->pm_private_data;
int i;
return 0;
}
-static int intel8x0m_resume(snd_card_t *card, unsigned int state)
+static int intel8x0m_resume(snd_card_t *card)
{
intel8x0_t *chip = card->pm_private_data;
pci_enable_device(chip->pci);
{ PCI_DEVICE_ID_INTEL_ICH3_6, "Intel 82801CA-ICH3" },
{ PCI_DEVICE_ID_INTEL_ICH4_6, "Intel 82801DB-ICH4" },
{ PCI_DEVICE_ID_INTEL_ICH5_6, "Intel ICH5" },
+ { PCI_DEVICE_ID_INTEL_ICH6_6, "Intel ICH6" },
+ { PCI_DEVICE_ID_INTEL_ICH7_6, "Intel ICH7" },
{ 0x7446, "AMD AMD768" },
{ PCI_DEVICE_ID_SI_7013, "SiS SI7013" },
{ PCI_DEVICE_ID_NVIDIA_MCP_MODEM, "NVidia nForce" },