mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-09-22 12:44:11 +08:00
[ALSA] maestro3: Add hardware volume control quirk list
Maestro3 driver Add a hardware volume quirk list to the maestro3 driver. Details were taken from the Windows driver. Hardware volume control is enabled only for the systems in the list. Signed-off-by: Ville Syrjala <syrjala@sci.fi> Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
parent
58c1f8acde
commit
82f008c2b6
@ -779,6 +779,12 @@ struct m3_quirk {
|
|||||||
(e.g. for IrDA on Dell Inspirons) */
|
(e.g. for IrDA on Dell Inspirons) */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct m3_hv_quirk {
|
||||||
|
u16 vendor, device, subsystem_vendor, subsystem_device;
|
||||||
|
u32 config; /* ALLEGRO_CONFIG hardware volume bits */
|
||||||
|
int is_omnibook; /* Do HP OmniBook GPIO magic? */
|
||||||
|
};
|
||||||
|
|
||||||
struct m3_list {
|
struct m3_list {
|
||||||
int curlen;
|
int curlen;
|
||||||
int mem_addr;
|
int mem_addr;
|
||||||
@ -828,6 +834,7 @@ struct snd_m3 {
|
|||||||
|
|
||||||
struct pci_dev *pci;
|
struct pci_dev *pci;
|
||||||
struct m3_quirk *quirk;
|
struct m3_quirk *quirk;
|
||||||
|
struct m3_hv_quirk *hv_quirk;
|
||||||
|
|
||||||
int dacs_active;
|
int dacs_active;
|
||||||
int timer_users;
|
int timer_users;
|
||||||
@ -856,7 +863,7 @@ struct snd_m3 {
|
|||||||
snd_kcontrol_t *master_switch;
|
snd_kcontrol_t *master_switch;
|
||||||
snd_kcontrol_t *master_volume;
|
snd_kcontrol_t *master_volume;
|
||||||
struct tasklet_struct hwvol_tq;
|
struct tasklet_struct hwvol_tq;
|
||||||
|
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
u16 *suspend_mem;
|
u16 *suspend_mem;
|
||||||
#endif
|
#endif
|
||||||
@ -973,6 +980,71 @@ static struct m3_quirk m3_quirk_list[] = {
|
|||||||
{ NULL }
|
{ NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* These values came from the Windows driver. */
|
||||||
|
static struct m3_hv_quirk m3_hv_quirk_list[] = {
|
||||||
|
/* Allegro chips */
|
||||||
|
{ 0x125D, 0x1988, 0x0E11, 0x002E, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
|
||||||
|
{ 0x125D, 0x1988, 0x0E11, 0x0094, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
|
||||||
|
{ 0x125D, 0x1988, 0x0E11, 0xB112, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
|
||||||
|
{ 0x125D, 0x1988, 0x0E11, 0xB114, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
|
||||||
|
{ 0x125D, 0x1988, 0x103C, 0x0012, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
|
||||||
|
{ 0x125D, 0x1988, 0x103C, 0x0018, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
|
||||||
|
{ 0x125D, 0x1988, 0x103C, 0x001C, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
|
||||||
|
{ 0x125D, 0x1988, 0x103C, 0x001D, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
|
||||||
|
{ 0x125D, 0x1988, 0x103C, 0x001E, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
|
||||||
|
{ 0x125D, 0x1988, 0x107B, 0x3350, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
|
||||||
|
{ 0x125D, 0x1988, 0x10F7, 0x8338, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
|
||||||
|
{ 0x125D, 0x1988, 0x10F7, 0x833C, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
|
||||||
|
{ 0x125D, 0x1988, 0x10F7, 0x833D, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
|
||||||
|
{ 0x125D, 0x1988, 0x10F7, 0x833E, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
|
||||||
|
{ 0x125D, 0x1988, 0x10F7, 0x833F, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
|
||||||
|
{ 0x125D, 0x1988, 0x13BD, 0x1018, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
|
||||||
|
{ 0x125D, 0x1988, 0x13BD, 0x1019, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
|
||||||
|
{ 0x125D, 0x1988, 0x13BD, 0x101A, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
|
||||||
|
{ 0x125D, 0x1988, 0x14FF, 0x0F03, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
|
||||||
|
{ 0x125D, 0x1988, 0x14FF, 0x0F04, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
|
||||||
|
{ 0x125D, 0x1988, 0x14FF, 0x0F05, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
|
||||||
|
{ 0x125D, 0x1988, 0x156D, 0xB400, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
|
||||||
|
{ 0x125D, 0x1988, 0x156D, 0xB795, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
|
||||||
|
{ 0x125D, 0x1988, 0x156D, 0xB797, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
|
||||||
|
{ 0x125D, 0x1988, 0x156D, 0xC700, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD, 0 },
|
||||||
|
{ 0x125D, 0x1988, 0x1033, 0x80F1, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 },
|
||||||
|
{ 0x125D, 0x1988, 0x103C, 0x001A, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 }, /* HP OmniBook 6100 */
|
||||||
|
{ 0x125D, 0x1988, 0x107B, 0x340A, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 },
|
||||||
|
{ 0x125D, 0x1988, 0x107B, 0x3450, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 },
|
||||||
|
{ 0x125D, 0x1988, 0x109F, 0x3134, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 },
|
||||||
|
{ 0x125D, 0x1988, 0x109F, 0x3161, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 },
|
||||||
|
{ 0x125D, 0x1988, 0x144D, 0x3280, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 },
|
||||||
|
{ 0x125D, 0x1988, 0x144D, 0x3281, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 },
|
||||||
|
{ 0x125D, 0x1988, 0x144D, 0xC002, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 },
|
||||||
|
{ 0x125D, 0x1988, 0x144D, 0xC003, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 },
|
||||||
|
{ 0x125D, 0x1988, 0x1509, 0x1740, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 },
|
||||||
|
{ 0x125D, 0x1988, 0x1610, 0x0010, HV_CTRL_ENABLE | HV_BUTTON_FROM_GD | REDUCED_DEBOUNCE, 0 },
|
||||||
|
{ 0x125D, 0x1988, 0x1042, 0x1042, HV_CTRL_ENABLE, 0 },
|
||||||
|
{ 0x125D, 0x1988, 0x107B, 0x9500, HV_CTRL_ENABLE, 0 },
|
||||||
|
{ 0x125D, 0x1988, 0x14FF, 0x0F06, HV_CTRL_ENABLE, 0 },
|
||||||
|
{ 0x125D, 0x1988, 0x1558, 0x8586, HV_CTRL_ENABLE, 0 },
|
||||||
|
{ 0x125D, 0x1988, 0x161F, 0x2011, HV_CTRL_ENABLE, 0 },
|
||||||
|
/* Maestro3 chips */
|
||||||
|
{ 0x125D, 0x1998, 0x103C, 0x000E, HV_CTRL_ENABLE, 0 },
|
||||||
|
{ 0x125D, 0x1998, 0x103C, 0x0010, HV_CTRL_ENABLE, 1 }, /* HP OmniBook 6000 */
|
||||||
|
{ 0x125D, 0x1998, 0x103C, 0x0011, HV_CTRL_ENABLE, 1 }, /* HP OmniBook 500 */
|
||||||
|
{ 0x125D, 0x1998, 0x103C, 0x001B, HV_CTRL_ENABLE, 0 },
|
||||||
|
{ 0x125D, 0x1998, 0x104D, 0x80A6, HV_CTRL_ENABLE, 0 },
|
||||||
|
{ 0x125D, 0x1998, 0x104D, 0x80AA, HV_CTRL_ENABLE, 0 },
|
||||||
|
{ 0x125D, 0x1998, 0x107B, 0x5300, HV_CTRL_ENABLE, 0 },
|
||||||
|
{ 0x125D, 0x1998, 0x110A, 0x1998, HV_CTRL_ENABLE, 0 },
|
||||||
|
{ 0x125D, 0x1998, 0x13BD, 0x1015, HV_CTRL_ENABLE, 0 },
|
||||||
|
{ 0x125D, 0x1998, 0x13BD, 0x101C, HV_CTRL_ENABLE, 0 },
|
||||||
|
{ 0x125D, 0x1998, 0x13BD, 0x1802, HV_CTRL_ENABLE, 0 },
|
||||||
|
{ 0x125D, 0x1998, 0x1599, 0x0715, HV_CTRL_ENABLE, 0 },
|
||||||
|
{ 0x125D, 0x1998, 0x5643, 0x5643, HV_CTRL_ENABLE, 0 },
|
||||||
|
{ 0x125D, 0x199A, 0x144D, 0x3260, HV_CTRL_ENABLE | REDUCED_DEBOUNCE, 0 },
|
||||||
|
{ 0x125D, 0x199A, 0x144D, 0x3261, HV_CTRL_ENABLE | REDUCED_DEBOUNCE, 0 },
|
||||||
|
{ 0x125D, 0x199A, 0x144D, 0xC000, HV_CTRL_ENABLE | REDUCED_DEBOUNCE, 0 },
|
||||||
|
{ 0x125D, 0x199A, 0x144D, 0xC001, HV_CTRL_ENABLE | REDUCED_DEBOUNCE, 0 },
|
||||||
|
{ 0 }
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* lowlevel functions
|
* lowlevel functions
|
||||||
@ -2392,21 +2464,27 @@ snd_m3_chip_init(m3_t *chip)
|
|||||||
DISABLE_LEGACY);
|
DISABLE_LEGACY);
|
||||||
pci_write_config_word(pcidev, PCI_LEGACY_AUDIO_CTRL, w);
|
pci_write_config_word(pcidev, PCI_LEGACY_AUDIO_CTRL, w);
|
||||||
|
|
||||||
/*
|
if (chip->hv_quirk && chip->hv_quirk->is_omnibook) {
|
||||||
* Volume buttons on some HP OmniBook laptops (500 and 6000 at least)
|
/*
|
||||||
* don't work correctly. This makes them work for the most part.
|
* Volume buttons on some HP OmniBook laptops don't work
|
||||||
* Volume up and down buttons on the laptop side work perfectly.
|
* correctly. This makes them work for the most part.
|
||||||
* Fn+cursor_up (volme up) works, Fn+cursor_down (volume down) doesn't,
|
*
|
||||||
* Fn+F8 (mute) works acts as volume up.
|
* Volume up and down buttons on the laptop side work.
|
||||||
*/
|
* Fn+cursor_up (volme up) works.
|
||||||
outw(~(GPI_VOL_DOWN|GPI_VOL_UP), io + GPIO_MASK);
|
* Fn+cursor_down (volume down) doesn't work.
|
||||||
outw(inw(io + GPIO_DIRECTION) & ~(GPI_VOL_DOWN|GPI_VOL_UP), io + GPIO_DIRECTION);
|
* Fn+F7 (mute) works acts as volume up.
|
||||||
outw((GPI_VOL_DOWN|GPI_VOL_UP), io + GPIO_DATA);
|
*/
|
||||||
outw(0xffff, io + GPIO_MASK);
|
outw(~(GPI_VOL_DOWN|GPI_VOL_UP), io + GPIO_MASK);
|
||||||
|
outw(inw(io + GPIO_DIRECTION) & ~(GPI_VOL_DOWN|GPI_VOL_UP), io + GPIO_DIRECTION);
|
||||||
|
outw((GPI_VOL_DOWN|GPI_VOL_UP), io + GPIO_DATA);
|
||||||
|
outw(0xffff, io + GPIO_MASK);
|
||||||
|
}
|
||||||
pci_read_config_dword(pcidev, PCI_ALLEGRO_CONFIG, &n);
|
pci_read_config_dword(pcidev, PCI_ALLEGRO_CONFIG, &n);
|
||||||
n &= ~HV_BUTTON_FROM_GD;
|
n &= ~(HV_CTRL_ENABLE | REDUCED_DEBOUNCE | HV_BUTTON_FROM_GD);
|
||||||
n |= HV_CTRL_ENABLE | REDUCED_DEBOUNCE;
|
if (chip->hv_quirk)
|
||||||
|
n |= chip->hv_quirk->config;
|
||||||
|
/* For some reason we must always use reduced debounce. */
|
||||||
|
n |= REDUCED_DEBOUNCE;
|
||||||
n |= PM_CTRL_ENABLE | CLK_DIV_BY_49 | USE_PCI_TIMING;
|
n |= PM_CTRL_ENABLE | CLK_DIV_BY_49 | USE_PCI_TIMING;
|
||||||
pci_write_config_dword(pcidev, PCI_ALLEGRO_CONFIG, n);
|
pci_write_config_dword(pcidev, PCI_ALLEGRO_CONFIG, n);
|
||||||
|
|
||||||
@ -2594,7 +2672,7 @@ 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;
|
struct m3_quirk *quirk;
|
||||||
u16 subsystem_vendor, subsystem_device;
|
struct m3_hv_quirk *hv_quirk;
|
||||||
static snd_device_ops_t ops = {
|
static snd_device_ops_t ops = {
|
||||||
.dev_free = snd_m3_dev_free,
|
.dev_free = snd_m3_dev_free,
|
||||||
};
|
};
|
||||||
@ -2632,18 +2710,25 @@ snd_m3_create(snd_card_t *card, struct pci_dev *pci,
|
|||||||
chip->pci = pci;
|
chip->pci = pci;
|
||||||
chip->irq = -1;
|
chip->irq = -1;
|
||||||
|
|
||||||
pci_read_config_word(pci, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vendor);
|
|
||||||
pci_read_config_word(pci, PCI_SUBSYSTEM_ID, &subsystem_device);
|
|
||||||
|
|
||||||
for (quirk = m3_quirk_list; quirk->vendor; quirk++) {
|
for (quirk = m3_quirk_list; quirk->vendor; quirk++) {
|
||||||
if (subsystem_vendor == quirk->vendor &&
|
if (pci->subsystem_vendor == quirk->vendor &&
|
||||||
subsystem_device == quirk->device) {
|
pci->subsystem_device == quirk->device) {
|
||||||
printk(KERN_INFO "maestro3: enabled hack for '%s'\n", quirk->name);
|
printk(KERN_INFO "maestro3: enabled hack for '%s'\n", quirk->name);
|
||||||
chip->quirk = quirk;
|
chip->quirk = quirk;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (hv_quirk = m3_hv_quirk_list; hv_quirk->vendor; hv_quirk++) {
|
||||||
|
if (pci->vendor == hv_quirk->vendor &&
|
||||||
|
pci->device == hv_quirk->device &&
|
||||||
|
pci->subsystem_vendor == hv_quirk->subsystem_vendor &&
|
||||||
|
pci->subsystem_device == hv_quirk->subsystem_device) {
|
||||||
|
chip->hv_quirk = hv_quirk;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
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;
|
||||||
|
Loading…
Reference in New Issue
Block a user