diff options
Diffstat (limited to 'sound/pci')
85 files changed, 4310 insertions, 3596 deletions
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index 1bcfb3aac18d..61e35ecc57b8 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -576,7 +576,7 @@ config SND_INTEL8X0M config SND_KORG1212 tristate "Korg 1212 IO" depends on SND - select FW_LOADER + select FW_LOADER if !SND_KORG1212_FIRMWARE_IN_KERNEL select SND_PCM help Say Y here to include support for Korg 1212IO soundcards. @@ -584,10 +584,19 @@ config SND_KORG1212 To compile this driver as a module, choose M here: the module will be called snd-korg1212. +config SND_KORG1212_FIRMWARE_IN_KERNEL + bool "In-kernel firmware for Korg1212 driver" + depends on SND_KORG1212 + default y + help + Say Y here to include the static firmware built in the kernel + for the Korg1212 driver. If you choose N here, you need to + install the firmware files from the alsa-firmware package. + config SND_MAESTRO3 tristate "ESS Allegro/Maestro3" depends on SND - select FW_LOADER + select FW_LOADER if !SND_MAESTRO3_FIRMWARE_IN_KERNEL select SND_AC97_CODEC help Say Y here to include support for soundcards based on ESS Maestro 3 @@ -596,6 +605,15 @@ config SND_MAESTRO3 To compile this driver as a module, choose M here: the module will be called snd-maestro3. +config SND_MAESTRO3_FIRMWARE_IN_KERNEL + bool "In-kernel firmware for Maestro3 driver" + depends on SND_MAESTRO3 + default y + help + Say Y here to include the static firmware built in the kernel + for the Maestro3 driver. If you choose N here, you need to + install the firmware files from the alsa-firmware package. + config SND_MIXART tristate "Digigram miXart" depends on SND @@ -737,7 +755,7 @@ config SND_VX222 config SND_YMFPCI tristate "Yamaha YMF724/740/744/754" depends on SND - select FW_LOADER + select FW_LOADER if !SND_YMFPCI_FIRMWARE_IN_KERNEL select SND_OPL3_LIB select SND_MPU401_UART select SND_AC97_CODEC @@ -748,6 +766,15 @@ config SND_YMFPCI To compile this driver as a module, choose M here: the module will be called snd-ymfpci. +config SND_YMFPCI_FIRMWARE_IN_KERNEL + bool "In-kernel firmware for YMFPCI driver" + depends on SND_YMFPCI + default y + help + Say Y here to include the static firmware built in the kernel + for the YMFPCI driver. If you choose N here, you need to + install the firmware files from the alsa-firmware package. + config SND_AC97_POWER_SAVE bool "AC97 Power-Saving Mode" depends on SND_AC97_CODEC && EXPERIMENTAL diff --git a/sound/pci/ac97/Makefile b/sound/pci/ac97/Makefile index 3c3222122d8b..f5d471896b95 100644 --- a/sound/pci/ac97/Makefile +++ b/sound/pci/ac97/Makefile @@ -3,7 +3,7 @@ # Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz> # -snd-ac97-codec-objs := ac97_codec.o ac97_pcm.o ac97_patch.o +snd-ac97-codec-objs := ac97_codec.o ac97_pcm.o ifneq ($(CONFIG_PROC_FS),) snd-ac97-codec-objs += ac97_proc.o diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index 3bfb2102fc5d..bbed644bf9c5 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c @@ -35,9 +35,9 @@ #include <sound/ac97_codec.h> #include <sound/asoundef.h> #include <sound/initval.h> -#include "ac97_local.h" #include "ac97_id.h" -#include "ac97_patch.h" + +#include "ac97_patch.c" MODULE_AUTHOR("Jaroslav Kysela <perex@suse.cz>"); MODULE_DESCRIPTION("Universal interface for Audio Codec '97"); @@ -432,7 +432,8 @@ static int snd_ac97_ad18xx_update_pcm_bits(struct snd_ac97 *ac97, int codec, uns * Controls */ -int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +static int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) { struct ac97_enum *e = (struct ac97_enum *)kcontrol->private_value; @@ -446,7 +447,8 @@ int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem return 0; } -int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); struct ac97_enum *e = (struct ac97_enum *)kcontrol->private_value; @@ -462,7 +464,8 @@ int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ return 0; } -int snd_ac97_put_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_ac97_put_enum_double(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); struct ac97_enum *e = (struct ac97_enum *)kcontrol->private_value; @@ -508,7 +511,8 @@ static void snd_ac97_page_restore(struct snd_ac97 *ac97, int page_save) } /* volume and switch controls */ -int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +static int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) { int mask = (kcontrol->private_value >> 16) & 0xff; int shift = (kcontrol->private_value >> 8) & 0x0f; @@ -521,7 +525,8 @@ int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info return 0; } -int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); int reg = kcontrol->private_value & 0xff; @@ -544,7 +549,8 @@ int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value return 0; } -int snd_ac97_put_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_ac97_put_volsw(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); int reg = kcontrol->private_value & 0xff; @@ -646,7 +652,7 @@ AC97_ENUM("Mic Select", std_enum[3]), AC97_SINGLE("ADC/DAC Loopback", AC97_GENERAL_PURPOSE, 7, 1, 0) }; -const struct snd_kcontrol_new snd_ac97_controls_3d[2] = { +static const struct snd_kcontrol_new snd_ac97_controls_3d[2] = { AC97_SINGLE("3D Control - Center", AC97_3D_CONTROL, 8, 15, 0), AC97_SINGLE("3D Control - Depth", AC97_3D_CONTROL, 0, 15, 0) }; @@ -817,7 +823,7 @@ static int snd_ac97_put_spsa(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ return change; } -const struct snd_kcontrol_new snd_ac97_controls_spdif[5] = { +static const struct snd_kcontrol_new snd_ac97_controls_spdif[5] = { { .access = SNDRV_CTL_ELEM_ACCESS_READ, .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -1097,7 +1103,7 @@ static void check_volume_resolution(struct snd_ac97 *ac97, int reg, unsigned cha } } -int snd_ac97_try_bit(struct snd_ac97 * ac97, int reg, int bit) +static int snd_ac97_try_bit(struct snd_ac97 * ac97, int reg, int bit) { unsigned short mask, val, orig, res; @@ -1137,7 +1143,8 @@ static inline int printable(unsigned int x) return x; } -struct snd_kcontrol *snd_ac97_cnew(const struct snd_kcontrol_new *_template, struct snd_ac97 * ac97) +static struct snd_kcontrol *snd_ac97_cnew(const struct snd_kcontrol_new *_template, + struct snd_ac97 * ac97) { struct snd_kcontrol_new template; memcpy(&template, _template, sizeof(template)); @@ -2544,7 +2551,8 @@ static void set_ctl_name(char *dst, const char *src, const char *suffix) } /* remove the control with the given name and optional suffix */ -int snd_ac97_remove_ctl(struct snd_ac97 *ac97, const char *name, const char *suffix) +static int snd_ac97_remove_ctl(struct snd_ac97 *ac97, const char *name, + const char *suffix) { struct snd_ctl_elem_id id; memset(&id, 0, sizeof(id)); @@ -2563,7 +2571,8 @@ static struct snd_kcontrol *ctl_find(struct snd_ac97 *ac97, const char *name, co } /* rename the control with the given name and optional suffix */ -int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src, const char *dst, const char *suffix) +static int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src, + const char *dst, const char *suffix) { struct snd_kcontrol *kctl = ctl_find(ac97, src, suffix); if (kctl) { @@ -2574,14 +2583,16 @@ int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src, const char *dst, } /* rename both Volume and Switch controls - don't check the return value */ -void snd_ac97_rename_vol_ctl(struct snd_ac97 *ac97, const char *src, const char *dst) +static void snd_ac97_rename_vol_ctl(struct snd_ac97 *ac97, const char *src, + const char *dst) { snd_ac97_rename_ctl(ac97, src, dst, "Switch"); snd_ac97_rename_ctl(ac97, src, dst, "Volume"); } /* swap controls */ -int snd_ac97_swap_ctl(struct snd_ac97 *ac97, const char *s1, const char *s2, const char *suffix) +static int snd_ac97_swap_ctl(struct snd_ac97 *ac97, const char *s1, + const char *s2, const char *suffix) { struct snd_kcontrol *kctl1, *kctl2; kctl1 = ctl_find(ac97, s1, suffix); diff --git a/sound/pci/ac97/ac97_local.h b/sound/pci/ac97/ac97_local.h index a6244c720a1d..78745c5c6df8 100644 --- a/sound/pci/ac97/ac97_local.h +++ b/sound/pci/ac97/ac97_local.h @@ -22,59 +22,8 @@ * */ -#define AC97_SINGLE_VALUE(reg,shift,mask,invert) ((reg) | ((shift) << 8) | ((shift) << 12) | ((mask) << 16) | ((invert) << 24)) -#define AC97_PAGE_SINGLE_VALUE(reg,shift,mask,invert,page) (AC97_SINGLE_VALUE(reg,shift,mask,invert) | (1<<25) | ((page) << 26)) -#define AC97_SINGLE(xname, reg, shift, mask, invert) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ac97_info_volsw, \ - .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \ - .private_value = AC97_SINGLE_VALUE(reg, shift, mask, invert) } -#define AC97_PAGE_SINGLE(xname, reg, shift, mask, invert, page) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ac97_info_volsw, \ - .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \ - .private_value = AC97_PAGE_SINGLE_VALUE(reg, shift, mask, invert, page) } -#define AC97_DOUBLE(xname, reg, shift_left, shift_right, mask, invert) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), .info = snd_ac97_info_volsw, \ - .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \ - .private_value = (reg) | ((shift_left) << 8) | ((shift_right) << 12) | ((mask) << 16) | ((invert) << 24) } - -/* enum control */ -struct ac97_enum { - unsigned char reg; - unsigned char shift_l; - unsigned char shift_r; - unsigned short mask; - const char **texts; -}; - -#define AC97_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xtexts) \ -{ .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \ - .mask = xmask, .texts = xtexts } -#define AC97_ENUM_SINGLE(xreg, xshift, xmask, xtexts) \ - AC97_ENUM_DOUBLE(xreg, xshift, xshift, xmask, xtexts) -#define AC97_ENUM(xname, xenum) \ -{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .info = snd_ac97_info_enum_double, \ - .get = snd_ac97_get_enum_double, .put = snd_ac97_put_enum_double, \ - .private_value = (unsigned long)&xenum } - -/* ac97_codec.c */ -extern const struct snd_kcontrol_new snd_ac97_controls_3d[]; -extern const struct snd_kcontrol_new snd_ac97_controls_spdif[]; -struct snd_kcontrol *snd_ac97_cnew(const struct snd_kcontrol_new *_template, struct snd_ac97 * ac97); -void snd_ac97_get_name(struct snd_ac97 *ac97, unsigned int id, char *name, int modem); -int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo); -int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); -int snd_ac97_put_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); -int snd_ac97_try_bit(struct snd_ac97 * ac97, int reg, int bit); -int snd_ac97_remove_ctl(struct snd_ac97 *ac97, const char *name, const char *suffix); -int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src, const char *dst, const char *suffix); -int snd_ac97_swap_ctl(struct snd_ac97 *ac97, const char *s1, const char *s2, const char *suffix); -void snd_ac97_rename_vol_ctl(struct snd_ac97 *ac97, const char *src, const char *dst); -void snd_ac97_restore_status(struct snd_ac97 *ac97); -void snd_ac97_restore_iec958(struct snd_ac97 *ac97); -int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo); -int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); -int snd_ac97_put_enum_double(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); - +void snd_ac97_get_name(struct snd_ac97 *ac97, unsigned int id, char *name, + int modem); int snd_ac97_update_bits_nolock(struct snd_ac97 *ac97, unsigned short reg, unsigned short mask, unsigned short value); diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index b188a4df58cb..3eac0f86266c 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c @@ -23,20 +23,8 @@ * */ -#include <sound/driver.h> -#include <linux/delay.h> -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/mutex.h> - -#include <sound/core.h> -#include <sound/pcm.h> -#include <sound/control.h> -#include <sound/tlv.h> -#include <sound/ac97_codec.h> -#include "ac97_patch.h" -#include "ac97_id.h" #include "ac97_local.h" +#include "ac97_patch.h" /* * Chip specific initialization @@ -390,7 +378,7 @@ static struct snd_ac97_build_ops patch_yamaha_ymf753_ops = { .build_post_spdif = patch_yamaha_ymf753_post_spdif }; -int patch_yamaha_ymf753(struct snd_ac97 * ac97) +static int patch_yamaha_ymf753(struct snd_ac97 * ac97) { /* Patch for Yamaha YMF753, Copyright (c) by David Shust, dshust@shustring.com. This chip has nonstandard and extended behaviour with regard to its S/PDIF output. @@ -436,7 +424,7 @@ static struct snd_ac97_build_ops patch_wolfson_wm9703_ops = { .build_specific = patch_wolfson_wm9703_specific, }; -int patch_wolfson03(struct snd_ac97 * ac97) +static int patch_wolfson03(struct snd_ac97 * ac97) { ac97->build_ops = &patch_wolfson_wm9703_ops; return 0; @@ -467,7 +455,7 @@ static struct snd_ac97_build_ops patch_wolfson_wm9704_ops = { .build_specific = patch_wolfson_wm9704_specific, }; -int patch_wolfson04(struct snd_ac97 * ac97) +static int patch_wolfson04(struct snd_ac97 * ac97) { /* WM9704M/9704Q */ ac97->build_ops = &patch_wolfson_wm9704_ops; @@ -489,7 +477,7 @@ static struct snd_ac97_build_ops patch_wolfson_wm9705_ops = { .build_specific = patch_wolfson_wm9705_specific, }; -int patch_wolfson05(struct snd_ac97 * ac97) +static int patch_wolfson05(struct snd_ac97 * ac97) { /* WM9705, WM9710 */ ac97->build_ops = &patch_wolfson_wm9705_ops; @@ -625,7 +613,7 @@ static struct snd_ac97_build_ops patch_wolfson_wm9711_ops = { .build_specific = patch_wolfson_wm9711_specific, }; -int patch_wolfson11(struct snd_ac97 * ac97) +static int patch_wolfson11(struct snd_ac97 * ac97) { /* WM9711, WM9712 */ ac97->build_ops = &patch_wolfson_wm9711_ops; @@ -824,7 +812,7 @@ static struct snd_ac97_build_ops patch_wolfson_wm9713_ops = { #endif }; -int patch_wolfson13(struct snd_ac97 * ac97) +static int patch_wolfson13(struct snd_ac97 * ac97) { /* WM9713, WM9714 */ ac97->build_ops = &patch_wolfson_wm9713_ops; @@ -844,7 +832,7 @@ int patch_wolfson13(struct snd_ac97 * ac97) /* * Tritech codec */ -int patch_tritech_tr28028(struct snd_ac97 * ac97) +static int patch_tritech_tr28028(struct snd_ac97 * ac97) { snd_ac97_write_cache(ac97, 0x26, 0x0300); snd_ac97_write_cache(ac97, 0x26, 0x0000); @@ -922,7 +910,7 @@ static struct snd_ac97_build_ops patch_sigmatel_stac9700_ops = { .build_specific = patch_sigmatel_stac97xx_specific }; -int patch_sigmatel_stac9700(struct snd_ac97 * ac97) +static int patch_sigmatel_stac9700(struct snd_ac97 * ac97) { ac97->build_ops = &patch_sigmatel_stac9700_ops; return 0; @@ -969,7 +957,7 @@ static struct snd_ac97_build_ops patch_sigmatel_stac9708_ops = { .build_specific = patch_sigmatel_stac9708_specific }; -int patch_sigmatel_stac9708(struct snd_ac97 * ac97) +static int patch_sigmatel_stac9708(struct snd_ac97 * ac97) { unsigned int codec72, codec6c; @@ -995,7 +983,7 @@ int patch_sigmatel_stac9708(struct snd_ac97 * ac97) return 0; } -int patch_sigmatel_stac9721(struct snd_ac97 * ac97) +static int patch_sigmatel_stac9721(struct snd_ac97 * ac97) { ac97->build_ops = &patch_sigmatel_stac9700_ops; if (snd_ac97_read(ac97, AC97_SIGMATEL_ANALOG) == 0) { @@ -1009,7 +997,7 @@ int patch_sigmatel_stac9721(struct snd_ac97 * ac97) return 0; } -int patch_sigmatel_stac9744(struct snd_ac97 * ac97) +static int patch_sigmatel_stac9744(struct snd_ac97 * ac97) { // patch for SigmaTel ac97->build_ops = &patch_sigmatel_stac9700_ops; @@ -1021,7 +1009,7 @@ int patch_sigmatel_stac9744(struct snd_ac97 * ac97) return 0; } -int patch_sigmatel_stac9756(struct snd_ac97 * ac97) +static int patch_sigmatel_stac9756(struct snd_ac97 * ac97) { // patch for SigmaTel ac97->build_ops = &patch_sigmatel_stac9700_ops; @@ -1198,7 +1186,7 @@ static struct snd_ac97_build_ops patch_sigmatel_stac9758_ops = { .build_specific = patch_sigmatel_stac9758_specific }; -int patch_sigmatel_stac9758(struct snd_ac97 * ac97) +static int patch_sigmatel_stac9758(struct snd_ac97 * ac97) { static unsigned short regs[4] = { AC97_SIGMATEL_OUTSEL, @@ -1272,7 +1260,7 @@ static struct snd_ac97_build_ops patch_cirrus_ops = { .build_spdif = patch_cirrus_build_spdif }; -int patch_cirrus_spdif(struct snd_ac97 * ac97) +static int patch_cirrus_spdif(struct snd_ac97 * ac97) { /* Basically, the cs4201/cs4205/cs4297a has non-standard sp/dif registers. WHY CAN'T ANYONE FOLLOW THE BLOODY SPEC? *sigh* @@ -1293,7 +1281,7 @@ int patch_cirrus_spdif(struct snd_ac97 * ac97) return 0; } -int patch_cirrus_cs4299(struct snd_ac97 * ac97) +static int patch_cirrus_cs4299(struct snd_ac97 * ac97) { /* force the detection of PC Beep */ ac97->flags |= AC97_HAS_PC_BEEP; @@ -1329,7 +1317,7 @@ static struct snd_ac97_build_ops patch_conexant_ops = { .build_spdif = patch_conexant_build_spdif }; -int patch_conexant(struct snd_ac97 * ac97) +static int patch_conexant(struct snd_ac97 * ac97) { ac97->build_ops = &patch_conexant_ops; ac97->flags |= AC97_CX_SPDIF; @@ -1338,7 +1326,7 @@ int patch_conexant(struct snd_ac97 * ac97) return 0; } -int patch_cx20551(struct snd_ac97 *ac97) +static int patch_cx20551(struct snd_ac97 *ac97) { snd_ac97_update_bits(ac97, 0x5c, 0x01, 0x01); return 0; @@ -1430,7 +1418,7 @@ static const struct snd_ac97_res_table ad1819_restbl[] = { { } /* terminator */ }; -int patch_ad1819(struct snd_ac97 * ac97) +static int patch_ad1819(struct snd_ac97 * ac97) { unsigned short scfg; @@ -1507,7 +1495,7 @@ static struct snd_ac97_build_ops patch_ad1881_build_ops = { #endif }; -int patch_ad1881(struct snd_ac97 * ac97) +static int patch_ad1881(struct snd_ac97 * ac97) { static const char cfg_idxs[3][2] = { {2, 1}, @@ -1595,7 +1583,7 @@ static struct snd_ac97_build_ops patch_ad1885_build_ops = { #endif }; -int patch_ad1885(struct snd_ac97 * ac97) +static int patch_ad1885(struct snd_ac97 * ac97) { patch_ad1881(ac97); /* This is required to deal with the Intel D815EEAL2 */ @@ -1622,7 +1610,7 @@ static struct snd_ac97_build_ops patch_ad1886_build_ops = { #endif }; -int patch_ad1886(struct snd_ac97 * ac97) +static int patch_ad1886(struct snd_ac97 * ac97) { patch_ad1881(ac97); /* Presario700 workaround */ @@ -1844,7 +1832,7 @@ static void check_ad1981_hp_jack_sense(struct snd_ac97 *ac97) snd_ac97_update_bits(ac97, AC97_AD_JACK_SPDIF, 1<<11, 1<<11); } -int patch_ad1981a(struct snd_ac97 *ac97) +static int patch_ad1981a(struct snd_ac97 *ac97) { patch_ad1881(ac97); ac97->build_ops = &patch_ad1981a_build_ops; @@ -1877,7 +1865,7 @@ static struct snd_ac97_build_ops patch_ad1981b_build_ops = { #endif }; -int patch_ad1981b(struct snd_ac97 *ac97) +static int patch_ad1981b(struct snd_ac97 *ac97) { patch_ad1881(ac97); ac97->build_ops = &patch_ad1981b_build_ops; @@ -2014,7 +2002,7 @@ static struct snd_ac97_build_ops patch_ad1888_build_ops = { .update_jacks = ad1888_update_jacks, }; -int patch_ad1888(struct snd_ac97 * ac97) +static int patch_ad1888(struct snd_ac97 * ac97) { unsigned short misc; @@ -2052,7 +2040,7 @@ static struct snd_ac97_build_ops patch_ad1980_build_ops = { .update_jacks = ad1888_update_jacks, }; -int patch_ad1980(struct snd_ac97 * ac97) +static int patch_ad1980(struct snd_ac97 * ac97) { patch_ad1888(ac97); ac97->build_ops = &patch_ad1980_build_ops; @@ -2168,7 +2156,7 @@ static struct snd_ac97_build_ops patch_ad1985_build_ops = { .update_jacks = ad1985_update_jacks, }; -int patch_ad1985(struct snd_ac97 * ac97) +static int patch_ad1985(struct snd_ac97 * ac97) { unsigned short misc; @@ -2468,7 +2456,7 @@ static struct snd_ac97_build_ops patch_ad1986_build_ops = { .update_jacks = ad1986_update_jacks, }; -int patch_ad1986(struct snd_ac97 * ac97) +static int patch_ad1986(struct snd_ac97 * ac97) { patch_ad1881(ac97); ac97->build_ops = &patch_ad1986_build_ops; @@ -2561,7 +2549,7 @@ static struct snd_ac97_build_ops patch_alc650_ops = { .update_jacks = alc650_update_jacks }; -int patch_alc650(struct snd_ac97 * ac97) +static int patch_alc650(struct snd_ac97 * ac97) { unsigned short val; @@ -2713,7 +2701,7 @@ static struct snd_ac97_build_ops patch_alc655_ops = { .update_jacks = alc655_update_jacks }; -int patch_alc655(struct snd_ac97 * ac97) +static int patch_alc655(struct snd_ac97 * ac97) { unsigned int val; @@ -2739,6 +2727,7 @@ int patch_alc655(struct snd_ac97 * ac97) (ac97->subsystem_device == 0x0131 || /* MSI S270 laptop */ ac97->subsystem_device == 0x0161 || /* LG K1 Express */ ac97->subsystem_device == 0x0351 || /* MSI L725 laptop */ + ac97->subsystem_device == 0x0471 || /* MSI L720 laptop */ ac97->subsystem_device == 0x0061)) /* MSI S250 laptop */ val &= ~(1 << 1); /* Pin 47 is EAPD (for internal speaker) */ else @@ -2815,7 +2804,7 @@ static struct snd_ac97_build_ops patch_alc850_ops = { .update_jacks = alc850_update_jacks }; -int patch_alc850(struct snd_ac97 *ac97) +static int patch_alc850(struct snd_ac97 *ac97) { ac97->build_ops = &patch_alc850_ops; @@ -2875,7 +2864,7 @@ static struct snd_ac97_build_ops patch_cm9738_ops = { .update_jacks = cm9738_update_jacks }; -int patch_cm9738(struct snd_ac97 * ac97) +static int patch_cm9738(struct snd_ac97 * ac97) { ac97->build_ops = &patch_cm9738_ops; /* FIXME: can anyone confirm below? */ @@ -2967,7 +2956,7 @@ static struct snd_ac97_build_ops patch_cm9739_ops = { .update_jacks = cm9739_update_jacks }; -int patch_cm9739(struct snd_ac97 * ac97) +static int patch_cm9739(struct snd_ac97 * ac97) { unsigned short val; @@ -3141,7 +3130,7 @@ static struct snd_ac97_build_ops patch_cm9761_ops = { .update_jacks = cm9761_update_jacks }; -int patch_cm9761(struct snd_ac97 *ac97) +static int patch_cm9761(struct snd_ac97 *ac97) { unsigned short val; @@ -3236,7 +3225,7 @@ static struct snd_ac97_build_ops patch_cm9780_ops = { .build_post_spdif = patch_cm9761_post_spdif /* identical with CM9761 */ }; -int patch_cm9780(struct snd_ac97 *ac97) +static int patch_cm9780(struct snd_ac97 *ac97) { unsigned short val; @@ -3279,7 +3268,7 @@ static struct snd_ac97_build_ops patch_vt1616_ops = { .build_specific = patch_vt1616_specific }; -int patch_vt1616(struct snd_ac97 * ac97) +static int patch_vt1616(struct snd_ac97 * ac97) { ac97->build_ops = &patch_vt1616_ops; return 0; @@ -3288,16 +3277,111 @@ int patch_vt1616(struct snd_ac97 * ac97) /* * VT1617A codec */ + +/* + * unfortunately, the vt1617a stashes the twiddlers required for + * nooding the i/o jacks on 2 different regs. * thameans that we cant + * use the easy way provided by AC97_ENUM_DOUBLE() we have to write + * are own funcs. + * + * NB: this is absolutely and utterly different from the vt1618. dunno + * about the 1616. + */ + +/* copied from ac97_surround_jack_mode_info() */ +static int snd_ac97_vt1617a_smart51_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + /* ordering in this list reflects vt1617a docs for Reg 20 and + * 7a and Table 6 that lays out the matrix NB WRT Table6: SM51 + * is SM51EN *AND* it's Bit14, not Bit15 so the table is very + * counter-intuitive */ + + static const char* texts[] = { "LineIn Mic1", "LineIn Mic1 Mic3", + "Surr LFE/C Mic3", "LineIn LFE/C Mic3", + "LineIn Mic2", "LineIn Mic2 Mic1", + "Surr LFE Mic1", "Surr LFE Mic1 Mic2"}; + return ac97_enum_text_info(kcontrol, uinfo, texts, 8); +} + +static int snd_ac97_vt1617a_smart51_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ushort usSM51, usMS; + + struct snd_ac97 *pac97; + + pac97 = snd_kcontrol_chip(kcontrol); /* grab codec handle */ + + /* grab our desirec bits, then mash them together in a manner + * consistent with Table 6 on page 17 in the 1617a docs */ + + usSM51 = snd_ac97_read(pac97, 0x7a) >> 14; + usMS = snd_ac97_read(pac97, 0x20) >> 8; + + ucontrol->value.enumerated.item[0] = (usSM51 << 1) + usMS; + + return 0; +} + +static int snd_ac97_vt1617a_smart51_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ushort usSM51, usMS, usReg; + + struct snd_ac97 *pac97; + + pac97 = snd_kcontrol_chip(kcontrol); /* grab codec handle */ + + usSM51 = ucontrol->value.enumerated.item[0] >> 1; + usMS = ucontrol->value.enumerated.item[0] & 1; + + /* push our values into the register - consider that things will be left + * in a funky state if the write fails */ + + usReg = snd_ac97_read(pac97, 0x7a); + snd_ac97_write_cache(pac97, 0x7a, (usReg & 0x3FFF) + (usSM51 << 14)); + usReg = snd_ac97_read(pac97, 0x20); + snd_ac97_write_cache(pac97, 0x20, (usReg & 0xFEFF) + (usMS << 8)); + + return 0; +} + +static const struct snd_kcontrol_new snd_ac97_controls_vt1617a[] = { + + AC97_SINGLE("Center/LFE Exchange", 0x5a, 8, 1, 0), + /* + * These are used to enable/disable surround sound on motherboards + * that have 3 bidirectional analog jacks + */ + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Smart 5.1 Select", + .info = snd_ac97_vt1617a_smart51_info, + .get = snd_ac97_vt1617a_smart51_get, + .put = snd_ac97_vt1617a_smart51_put, + }, +}; + int patch_vt1617a(struct snd_ac97 * ac97) { - /* bring analog power consumption to normal, like WinXP driver - * for EPIA SP + int err = 0; + + /* we choose to not fail out at this point, but we tell the + caller when we return */ + + err = patch_build_controls(ac97, &snd_ac97_controls_vt1617a[0], + ARRAY_SIZE(snd_ac97_controls_vt1617a)); + + /* bring analog power consumption to normal by turning off the + * headphone amplifier, like WinXP driver for EPIA SP */ snd_ac97_write_cache(ac97, 0x5c, 0x20); ac97->ext_id |= AC97_EI_SPDIF; /* force the detection of spdif */ ac97->rates[AC97_RATES_SPDIF] = SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_48000; ac97->build_ops = &patch_vt1616_ops; - return 0; + + return err; } /* @@ -3338,7 +3422,7 @@ static struct snd_ac97_build_ops patch_it2646_ops = { .update_jacks = it2646_update_jacks }; -int patch_it2646(struct snd_ac97 * ac97) +static int patch_it2646(struct snd_ac97 * ac97) { ac97->build_ops = &patch_it2646_ops; /* full DAC volume */ @@ -3371,7 +3455,7 @@ static struct snd_ac97_build_ops patch_si3036_ops = { .build_specific = patch_si3036_specific, }; -int mpatch_si3036(struct snd_ac97 * ac97) +static int mpatch_si3036(struct snd_ac97 * ac97) { ac97->build_ops = &patch_si3036_ops; snd_ac97_write_cache(ac97, 0x5c, 0xf210 ); @@ -3403,7 +3487,7 @@ static struct snd_ac97_res_table lm4550_restbl[] = { { } /* terminator */ }; -int patch_lm4550(struct snd_ac97 *ac97) +static int patch_lm4550(struct snd_ac97 *ac97) { ac97->res_table = lm4550_restbl; return 0; @@ -3438,7 +3522,7 @@ static struct snd_ac97_build_ops patch_ucb1400_ops = { .build_specific = patch_ucb1400_specific, }; -int patch_ucb1400(struct snd_ac97 * ac97) +static int patch_ucb1400(struct snd_ac97 * ac97) { ac97->build_ops = &patch_ucb1400_ops; /* enable headphone driver and smart low power mode by default */ diff --git a/sound/pci/ac97/ac97_patch.h b/sound/pci/ac97/ac97_patch.h index 555d1c9a98fd..fd341ce63762 100644 --- a/sound/pci/ac97/ac97_patch.h +++ b/sound/pci/ac97/ac97_patch.h @@ -22,44 +22,72 @@ * */ -int patch_yamaha_ymf753(struct snd_ac97 * ac97); -int patch_wolfson00(struct snd_ac97 * ac97); -int patch_wolfson03(struct snd_ac97 * ac97); -int patch_wolfson04(struct snd_ac97 * ac97); -int patch_wolfson05(struct snd_ac97 * ac97); -int patch_wolfson11(struct snd_ac97 * ac97); -int patch_wolfson13(struct snd_ac97 * ac97); -int patch_tritech_tr28028(struct snd_ac97 * ac97); -int patch_sigmatel_stac9700(struct snd_ac97 * ac97); -int patch_sigmatel_stac9708(struct snd_ac97 * ac97); -int patch_sigmatel_stac9721(struct snd_ac97 * ac97); -int patch_sigmatel_stac9744(struct snd_ac97 * ac97); -int patch_sigmatel_stac9756(struct snd_ac97 * ac97); -int patch_sigmatel_stac9758(struct snd_ac97 * ac97); -int patch_cirrus_cs4299(struct snd_ac97 * ac97); -int patch_cirrus_spdif(struct snd_ac97 * ac97); -int patch_conexant(struct snd_ac97 * ac97); -int patch_cx20551(struct snd_ac97 * ac97); -int patch_ad1819(struct snd_ac97 * ac97); -int patch_ad1881(struct snd_ac97 * ac97); -int patch_ad1885(struct snd_ac97 * ac97); -int patch_ad1886(struct snd_ac97 * ac97); -int patch_ad1888(struct snd_ac97 * ac97); -int patch_ad1980(struct snd_ac97 * ac97); -int patch_ad1981a(struct snd_ac97 * ac97); -int patch_ad1981b(struct snd_ac97 * ac97); -int patch_ad1985(struct snd_ac97 * ac97); -int patch_ad1986(struct snd_ac97 * ac97); -int patch_alc650(struct snd_ac97 * ac97); -int patch_alc655(struct snd_ac97 * ac97); -int patch_alc850(struct snd_ac97 * ac97); -int patch_cm9738(struct snd_ac97 * ac97); -int patch_cm9739(struct snd_ac97 * ac97); -int patch_cm9761(struct snd_ac97 * ac97); -int patch_cm9780(struct snd_ac97 * ac97); -int patch_vt1616(struct snd_ac97 * ac97); -int patch_vt1617a(struct snd_ac97 * ac97); -int patch_it2646(struct snd_ac97 * ac97); -int patch_ucb1400(struct snd_ac97 * ac97); -int mpatch_si3036(struct snd_ac97 * ac97); -int patch_lm4550(struct snd_ac97 * ac97); +#define AC97_SINGLE_VALUE(reg,shift,mask,invert) \ + ((reg) | ((shift) << 8) | ((shift) << 12) | ((mask) << 16) | \ + ((invert) << 24)) +#define AC97_PAGE_SINGLE_VALUE(reg,shift,mask,invert,page) \ + (AC97_SINGLE_VALUE(reg,shift,mask,invert) | (1<<25) | ((page) << 26)) +#define AC97_SINGLE(xname, reg, shift, mask, invert) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ + .info = snd_ac97_info_volsw, \ + .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \ + .private_value = AC97_SINGLE_VALUE(reg, shift, mask, invert) } +#define AC97_PAGE_SINGLE(xname, reg, shift, mask, invert, page) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ + .info = snd_ac97_info_volsw, \ + .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \ + .private_value = AC97_PAGE_SINGLE_VALUE(reg, shift, mask, invert, page) } +#define AC97_DOUBLE(xname, reg, shift_left, shift_right, mask, invert) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = (xname), \ + .info = snd_ac97_info_volsw, \ + .get = snd_ac97_get_volsw, .put = snd_ac97_put_volsw, \ + .private_value = (reg) | ((shift_left) << 8) | ((shift_right) << 12) | ((mask) << 16) | ((invert) << 24) } + +/* enum control */ +struct ac97_enum { + unsigned char reg; + unsigned char shift_l; + unsigned char shift_r; + unsigned short mask; + const char **texts; +}; + +#define AC97_ENUM_DOUBLE(xreg, xshift_l, xshift_r, xmask, xtexts) \ +{ .reg = xreg, .shift_l = xshift_l, .shift_r = xshift_r, \ + .mask = xmask, .texts = xtexts } +#define AC97_ENUM_SINGLE(xreg, xshift, xmask, xtexts) \ + AC97_ENUM_DOUBLE(xreg, xshift, xshift, xmask, xtexts) +#define AC97_ENUM(xname, xenum) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ + .info = snd_ac97_info_enum_double, \ + .get = snd_ac97_get_enum_double, .put = snd_ac97_put_enum_double, \ + .private_value = (unsigned long)&xenum } + +/* ac97_codec.c */ +static const struct snd_kcontrol_new snd_ac97_controls_3d[]; +static const struct snd_kcontrol_new snd_ac97_controls_spdif[]; +static struct snd_kcontrol *snd_ac97_cnew(const struct snd_kcontrol_new *_template, + struct snd_ac97 * ac97); +static int snd_ac97_info_volsw(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo); +static int snd_ac97_get_volsw(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); +static int snd_ac97_put_volsw(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); +static int snd_ac97_try_bit(struct snd_ac97 * ac97, int reg, int bit); +static int snd_ac97_remove_ctl(struct snd_ac97 *ac97, const char *name, + const char *suffix); +static int snd_ac97_rename_ctl(struct snd_ac97 *ac97, const char *src, + const char *dst, const char *suffix); +static int snd_ac97_swap_ctl(struct snd_ac97 *ac97, const char *s1, + const char *s2, const char *suffix); +static void snd_ac97_rename_vol_ctl(struct snd_ac97 *ac97, const char *src, + const char *dst); +static void snd_ac97_restore_status(struct snd_ac97 *ac97); +static void snd_ac97_restore_iec958(struct snd_ac97 *ac97); +static int snd_ac97_info_enum_double(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo); +static int snd_ac97_get_enum_double(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); +static int snd_ac97_put_enum_double(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); diff --git a/sound/pci/ac97/ac97_pcm.c b/sound/pci/ac97/ac97_pcm.c index 3758d07182f8..4281e6d0c5b6 100644 --- a/sound/pci/ac97/ac97_pcm.c +++ b/sound/pci/ac97/ac97_pcm.c @@ -34,7 +34,6 @@ #include <sound/control.h> #include <sound/ac97_codec.h> #include <sound/asoundef.h> -#include "ac97_patch.h" #include "ac97_id.h" #include "ac97_local.h" diff --git a/sound/pci/ali5451/ali5451.c b/sound/pci/ali5451/ali5451.c index ba7fa22b285d..e1ed59549c50 100644 --- a/sound/pci/ali5451/ali5451.c +++ b/sound/pci/ali5451/ali5451.c @@ -69,10 +69,10 @@ module_param(enable, bool, 0444); * Debug part definitions */ -//#define ALI_DEBUG +/* #define ALI_DEBUG */ #ifdef ALI_DEBUG -#define snd_ali_printk(format, args...) printk(format, ##args); +#define snd_ali_printk(format, args...) printk(KERN_DEBUG format, ##args); #else #define snd_ali_printk(format, args...) #endif @@ -105,10 +105,10 @@ module_param(enable, bool, 0444); * Direct Registers */ -#define ALI_LEGACY_DMAR0 0x00 // ADR0 -#define ALI_LEGACY_DMAR4 0x04 // CNT0 -#define ALI_LEGACY_DMAR11 0x0b // MOD -#define ALI_LEGACY_DMAR15 0x0f // MMR +#define ALI_LEGACY_DMAR0 0x00 /* ADR0 */ +#define ALI_LEGACY_DMAR4 0x04 /* CNT0 */ +#define ALI_LEGACY_DMAR11 0x0b /* MOD */ +#define ALI_LEGACY_DMAR15 0x0f /* MMR */ #define ALI_MPUR0 0x20 #define ALI_MPUR1 0x21 #define ALI_MPUR2 0x22 @@ -175,7 +175,7 @@ struct snd_ali; struct snd_ali_voice; struct snd_ali_channel_control { - // register data + /* register data */ struct REGDATA { unsigned int start; unsigned int stop; @@ -183,7 +183,7 @@ struct snd_ali_channel_control { unsigned int ainten; } data; - // register addresses + /* register addresses */ struct REGS { unsigned int start; unsigned int stop; @@ -197,19 +197,18 @@ struct snd_ali_channel_control { struct snd_ali_voice { unsigned int number; - unsigned int use: 1, - pcm: 1, - midi: 1, - mode: 1, - synth: 1; + unsigned int use :1, + pcm :1, + midi :1, + mode :1, + synth :1, + running :1; /* PCM data */ struct snd_ali *codec; struct snd_pcm_substream *substream; struct snd_ali_voice *extra; - unsigned int running: 1; - int eso; /* final ESO value for channel */ int count; /* runtime->period_size */ @@ -231,14 +230,12 @@ struct snd_alidev { }; -#ifdef CONFIG_PM #define ALI_GLOBAL_REGS 56 #define ALI_CHANNEL_REGS 8 struct snd_ali_image { - unsigned long regs[ALI_GLOBAL_REGS]; - unsigned long channel_regs[ALI_CHANNELS][ALI_CHANNEL_REGS]; + u32 regs[ALI_GLOBAL_REGS]; + u32 channel_regs[ALI_CHANNELS][ALI_CHANNEL_REGS]; }; -#endif struct snd_ali { @@ -246,8 +243,8 @@ struct snd_ali { unsigned long port; unsigned char revision; - unsigned int hw_initialized: 1; - unsigned int spdif_support: 1; + unsigned int hw_initialized :1; + unsigned int spdif_support :1; struct pci_dev *pci; struct pci_dev *pci_m1533; @@ -287,108 +284,28 @@ MODULE_DEVICE_TABLE(pci, snd_ali_ids); static void snd_ali_clear_voices(struct snd_ali *, unsigned int, unsigned int); static unsigned short snd_ali_codec_peek(struct snd_ali *, int, unsigned short); -static void snd_ali_codec_poke(struct snd_ali *, int, unsigned short, unsigned short); - -/* - * Debug Part - */ - -#ifdef ALI_DEBUG - -static void ali_read_regs(struct snd_ali *codec, int channel) -{ - int i,j; - unsigned int dwVal; - - printk("channel %d registers map:\n", channel); - outb((unsigned char)(channel & 0x001f), ALI_REG(codec,ALI_GC_CIR)); - - printk(" "); - for(j=0;j<8;j++) - printk("%2.2x ", j*4); - printk("\n"); - - for (i=0; i<=0xf8/4;i++) { - if(i%8 == 0) - printk("%2.2x ", (i*4/0x10)*0x10); - dwVal = inl(ALI_REG(codec,i*4)); - printk("%8.8x ", dwVal); - if ((i+1)%8 == 0) - printk("\n"); - } - printk("\n"); -} -static void ali_read_cfg(unsigned int vendor, unsigned deviceid) -{ - unsigned int dwVal; - struct pci_dev *pci_dev; - int i,j; - - pci_dev = pci_get_device(vendor, deviceid, NULL); - if (pci_dev == NULL) - return ; - - printk("\nM%x PCI CFG\n", deviceid); - printk(" "); - for(j=0;j<8;j++) - printk("%d ",j); - printk("\n"); - - for(i=0;i<8;i++) { - printk("%d ",i); - for(j=0;j<8;j++) - { - pci_read_config_dword(pci_dev, i*0x20+j*4, &dwVal); - printk("%8.8x ", dwVal); - } - printk("\n"); - } - pci_dev_put(pci_dev); - } -static void ali_read_ac97regs(struct snd_ali *codec, int secondary) -{ - unsigned short i,j; - unsigned short wVal; - - printk("\ncodec %d registers map:\n", secondary); - - printk(" "); - for(j=0;j<8;j++) - printk("%2.2x ",j*2); - printk("\n"); - - for (i=0; i<64;i++) { - if(i%8 == 0) - printk("%2.2x ", (i/8)*0x10); - wVal = snd_ali_codec_peek(codec, secondary, i*2); - printk("%4.4x ", wVal); - if ((i+1)%8 == 0) - printk("\n"); - } - printk("\n"); -} - -#endif +static void snd_ali_codec_poke(struct snd_ali *, int, unsigned short, + unsigned short); /* * AC97 ACCESS */ static inline unsigned int snd_ali_5451_peek(struct snd_ali *codec, - unsigned int port ) + unsigned int port) { return (unsigned int)inl(ALI_REG(codec, port)); } -static inline void snd_ali_5451_poke( struct snd_ali *codec, - unsigned int port, - unsigned int val ) +static inline void snd_ali_5451_poke(struct snd_ali *codec, + unsigned int port, + unsigned int val) { outl((unsigned int)val, ALI_REG(codec, port)); } -static int snd_ali_codec_ready( struct snd_ali *codec, - unsigned int port ) +static int snd_ali_codec_ready(struct snd_ali *codec, + unsigned int port) { unsigned long end_time; unsigned int res; @@ -396,7 +313,7 @@ static int snd_ali_codec_ready( struct snd_ali *codec, end_time = jiffies + msecs_to_jiffies(250); do { res = snd_ali_5451_peek(codec,port); - if (! (res & 0x8000)) + if (!(res & 0x8000)) return 0; schedule_timeout_uninterruptible(1); } while (time_after_eq(end_time, jiffies)); @@ -425,11 +342,11 @@ static int snd_ali_stimer_ready(struct snd_ali *codec) } static void snd_ali_codec_poke(struct snd_ali *codec,int secondary, - unsigned short reg, - unsigned short val) + unsigned short reg, + unsigned short val) { - unsigned int dwVal = 0; - unsigned int port = 0; + unsigned int dwVal; + unsigned int port; if (reg >= 0x80) { snd_printk(KERN_ERR "ali_codec_poke: reg(%xh) invalid.\n", reg); @@ -445,20 +362,22 @@ static void snd_ali_codec_poke(struct snd_ali *codec,int secondary, dwVal = (unsigned int) (reg & 0xff); dwVal |= 0x8000 | (val << 16); - if (secondary) dwVal |= 0x0080; - if (codec->revision == ALI_5451_V02) dwVal |= 0x0100; + if (secondary) + dwVal |= 0x0080; + if (codec->revision == ALI_5451_V02) + dwVal |= 0x0100; - snd_ali_5451_poke(codec,port,dwVal); + snd_ali_5451_poke(codec, port, dwVal); return ; } -static unsigned short snd_ali_codec_peek( struct snd_ali *codec, - int secondary, - unsigned short reg) +static unsigned short snd_ali_codec_peek(struct snd_ali *codec, + int secondary, + unsigned short reg) { - unsigned int dwVal = 0; - unsigned int port = 0; + unsigned int dwVal; + unsigned int port; if (reg >= 0x80) { snd_printk(KERN_ERR "ali_codec_peek: reg(%xh) invalid.\n", reg); @@ -474,7 +393,8 @@ static unsigned short snd_ali_codec_peek( struct snd_ali *codec, dwVal = (unsigned int) (reg & 0xff); dwVal |= 0x8000; /* bit 15*/ - if (secondary) dwVal |= 0x0080; + if (secondary) + dwVal |= 0x0080; snd_ali_5451_poke(codec, port, dwVal); @@ -483,7 +403,7 @@ static unsigned short snd_ali_codec_peek( struct snd_ali *codec, if (snd_ali_codec_ready(codec, port) < 0) return ~0; - return (snd_ali_5451_peek(codec, port) & 0xffff0000)>>16; + return (snd_ali_5451_peek(codec, port) & 0xffff0000) >> 16; } static void snd_ali_codec_write(struct snd_ac97 *ac97, @@ -493,9 +413,9 @@ static void snd_ali_codec_write(struct snd_ac97 *ac97, struct snd_ali *codec = ac97->private_data; snd_ali_printk("codec_write: reg=%xh data=%xh.\n", reg, val); - if(reg == AC97_GPIO_STATUS) { - outl((val << ALI_AC97_GPIO_DATA_SHIFT)|ALI_AC97_GPIO_ENABLE, - ALI_REG(codec, ALI_AC97_GPIO)); + if (reg == AC97_GPIO_STATUS) { + outl((val << ALI_AC97_GPIO_DATA_SHIFT) | ALI_AC97_GPIO_ENABLE, + ALI_REG(codec, ALI_AC97_GPIO)); return; } snd_ali_codec_poke(codec, ac97->num, reg, val); @@ -503,12 +423,13 @@ static void snd_ali_codec_write(struct snd_ac97 *ac97, } -static unsigned short snd_ali_codec_read(struct snd_ac97 *ac97, unsigned short reg) +static unsigned short snd_ali_codec_read(struct snd_ac97 *ac97, + unsigned short reg) { struct snd_ali *codec = ac97->private_data; snd_ali_printk("codec_read reg=%xh.\n", reg); - return (snd_ali_codec_peek(codec, ac97->num, reg)); + return snd_ali_codec_peek(codec, ac97->num, reg); } /* @@ -517,11 +438,12 @@ static unsigned short snd_ali_codec_read(struct snd_ac97 *ac97, unsigned short r static int snd_ali_reset_5451(struct snd_ali *codec) { - struct pci_dev *pci_dev = NULL; + struct pci_dev *pci_dev; unsigned short wCount, wReg; unsigned int dwVal; - if ((pci_dev = codec->pci_m1533) != NULL) { + pci_dev = codec->pci_m1533; + if (pci_dev) { pci_read_config_dword(pci_dev, 0x7c, &dwVal); pci_write_config_dword(pci_dev, 0x7c, dwVal | 0x08000000); udelay(5000); @@ -541,7 +463,7 @@ static int snd_ali_reset_5451(struct snd_ali *codec) wCount = 200; while(wCount--) { wReg = snd_ali_codec_peek(codec, 0, AC97_POWERDOWN); - if((wReg & 0x000f) == 0x000f) + if ((wReg & 0x000f) == 0x000f) return 0; udelay(5000); } @@ -555,8 +477,8 @@ static int snd_ali_reset_5451(struct snd_ali *codec) static int snd_ali_reset_codec(struct snd_ali *codec) { - struct pci_dev *pci_dev = NULL; - unsigned char bVal = 0; + struct pci_dev *pci_dev; + unsigned char bVal; unsigned int dwVal; unsigned short wCount, wReg; @@ -579,9 +501,9 @@ static int snd_ali_reset_codec(struct snd_ali *codec) udelay(15000); wCount = 200; - while(wCount--) { + while (wCount--) { wReg = snd_ali_codec_read(codec->ac97, AC97_POWERDOWN); - if((wReg & 0x000f) == 0x000f) + if ((wReg & 0x000f) == 0x000f) return 0; udelay(5000); } @@ -594,25 +516,27 @@ static int snd_ali_reset_codec(struct snd_ali *codec) * ALI 5451 Controller */ -static void snd_ali_enable_special_channel(struct snd_ali *codec, unsigned int channel) +static void snd_ali_enable_special_channel(struct snd_ali *codec, + unsigned int channel) { - unsigned long dwVal = 0; + unsigned long dwVal; - dwVal = inl(ALI_REG(codec,ALI_GLOBAL_CONTROL)); + dwVal = inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)); dwVal |= 1 << (channel & 0x0000001f); - outl(dwVal, ALI_REG(codec,ALI_GLOBAL_CONTROL)); + outl(dwVal, ALI_REG(codec, ALI_GLOBAL_CONTROL)); } -static void snd_ali_disable_special_channel(struct snd_ali *codec, unsigned int channel) +static void snd_ali_disable_special_channel(struct snd_ali *codec, + unsigned int channel) { - unsigned long dwVal = 0; + unsigned long dwVal; - dwVal = inl(ALI_REG(codec,ALI_GLOBAL_CONTROL)); + dwVal = inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)); dwVal &= ~(1 << (channel & 0x0000001f)); - outl(dwVal, ALI_REG(codec,ALI_GLOBAL_CONTROL)); + outl(dwVal, ALI_REG(codec, ALI_GLOBAL_CONTROL)); } -static void snd_ali_enable_address_interrupt(struct snd_ali * codec) +static void snd_ali_enable_address_interrupt(struct snd_ali *codec) { unsigned int gc; @@ -622,7 +546,7 @@ static void snd_ali_enable_address_interrupt(struct snd_ali * codec) outl( gc, ALI_REG(codec, ALI_GC_CIR)); } -static void snd_ali_disable_address_interrupt(struct snd_ali * codec) +static void snd_ali_disable_address_interrupt(struct snd_ali *codec) { unsigned int gc; @@ -632,8 +556,9 @@ static void snd_ali_disable_address_interrupt(struct snd_ali * codec) outl(gc, ALI_REG(codec, ALI_GC_CIR)); } -#if 0 // not used -static void snd_ali_enable_voice_irq(struct snd_ali *codec, unsigned int channel) +#if 0 /* not used */ +static void snd_ali_enable_voice_irq(struct snd_ali *codec, + unsigned int channel) { unsigned int mask; struct snd_ali_channel_control *pchregs = &(codec->chregs); @@ -641,13 +566,14 @@ static void snd_ali_enable_voice_irq(struct snd_ali *codec, unsigned int channel snd_ali_printk("enable_voice_irq channel=%d\n",channel); mask = 1 << (channel & 0x1f); - pchregs->data.ainten = inl(ALI_REG(codec,pchregs->regs.ainten)); + pchregs->data.ainten = inl(ALI_REG(codec, pchregs->regs.ainten)); pchregs->data.ainten |= mask; - outl(pchregs->data.ainten,ALI_REG(codec,pchregs->regs.ainten)); + outl(pchregs->data.ainten, ALI_REG(codec, pchregs->regs.ainten)); } #endif -static void snd_ali_disable_voice_irq(struct snd_ali *codec, unsigned int channel) +static void snd_ali_disable_voice_irq(struct snd_ali *codec, + unsigned int channel) { unsigned int mask; struct snd_ali_channel_control *pchregs = &(codec->chregs); @@ -655,9 +581,9 @@ static void snd_ali_disable_voice_irq(struct snd_ali *codec, unsigned int channe snd_ali_printk("disable_voice_irq channel=%d\n",channel); mask = 1 << (channel & 0x1f); - pchregs->data.ainten = inl(ALI_REG(codec,pchregs->regs.ainten)); + pchregs->data.ainten = inl(ALI_REG(codec, pchregs->regs.ainten)); pchregs->data.ainten &= ~mask; - outl(pchregs->data.ainten,ALI_REG(codec,pchregs->regs.ainten)); + outl(pchregs->data.ainten, ALI_REG(codec, pchregs->regs.ainten)); } static int snd_ali_alloc_pcm_channel(struct snd_ali *codec, int channel) @@ -665,7 +591,8 @@ static int snd_ali_alloc_pcm_channel(struct snd_ali *codec, int channel) unsigned int idx = channel & 0x1f; if (codec->synth.chcnt >= ALI_CHANNELS){ - snd_printk(KERN_ERR "ali_alloc_pcm_channel: no free channels.\n"); + snd_printk(KERN_ERR + "ali_alloc_pcm_channel: no free channels.\n"); return -1; } @@ -685,35 +612,41 @@ static int snd_ali_find_free_channel(struct snd_ali * codec, int rec) snd_ali_printk("find_free_channel: for %s\n",rec ? "rec" : "pcm"); - // recording + /* recording */ if (rec) { if (codec->spdif_support && - (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) & ALI_SPDIF_IN_SUPPORT)) + (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) & + ALI_SPDIF_IN_SUPPORT)) idx = ALI_SPDIF_IN_CHANNEL; else idx = ALI_PCM_IN_CHANNEL; - if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0) { + result = snd_ali_alloc_pcm_channel(codec, idx); + if (result >= 0) return result; - } else { - snd_printk(KERN_ERR "ali_find_free_channel: record channel is busy now.\n"); + else { + snd_printk(KERN_ERR "ali_find_free_channel: " + "record channel is busy now.\n"); return -1; } } - //playback... + /* playback... */ if (codec->spdif_support && - (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) & ALI_SPDIF_OUT_CH_ENABLE)) { + (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) & + ALI_SPDIF_OUT_CH_ENABLE)) { idx = ALI_SPDIF_OUT_CHANNEL; - if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0) { + result = snd_ali_alloc_pcm_channel(codec, idx); + if (result >= 0) return result; - } else { - snd_printk(KERN_ERR "ali_find_free_channel: S/PDIF out channel is in busy now.\n"); - } + else + snd_printk(KERN_ERR "ali_find_free_channel: " + "S/PDIF out channel is in busy now.\n"); } for (idx = 0; idx < ALI_CHANNELS; idx++) { - if ((result = snd_ali_alloc_pcm_channel(codec,idx)) >= 0) + result = snd_ali_alloc_pcm_channel(codec, idx); + if (result >= 0) return result; } snd_printk(KERN_ERR "ali_find_free_channel: no free channels.\n"); @@ -730,7 +663,8 @@ static void snd_ali_free_channel_pcm(struct snd_ali *codec, int channel) return; if (!(codec->synth.chmap & (1 << idx))) { - snd_printk(KERN_ERR "ali_free_channel_pcm: channel %d is not in use.\n",channel); + snd_printk(KERN_ERR "ali_free_channel_pcm: " + "channel %d is not in use.\n", channel); return; } else { codec->synth.chmap &= ~(1 << idx); @@ -738,8 +672,8 @@ static void snd_ali_free_channel_pcm(struct snd_ali *codec, int channel) } } -#if 0 // not used -static void snd_ali_start_voice(struct snd_ali * codec, unsigned int channel) +#if 0 /* not used */ +static void snd_ali_start_voice(struct snd_ali *codec, unsigned int channel) { unsigned int mask = 1 << (channel & 0x1f); @@ -748,7 +682,7 @@ static void snd_ali_start_voice(struct snd_ali * codec, unsigned int channel) } #endif -static void snd_ali_stop_voice(struct snd_ali * codec, unsigned int channel) +static void snd_ali_stop_voice(struct snd_ali *codec, unsigned int channel) { unsigned int mask = 1 << (channel & 0x1f); @@ -768,26 +702,27 @@ static void snd_ali_delay(struct snd_ali *codec,int interval) currenttimer = inl(ALI_REG(codec, ALI_STIMER)); while (currenttimer < begintimer + interval) { - if(snd_ali_stimer_ready(codec) < 0) + if (snd_ali_stimer_ready(codec) < 0) break; currenttimer = inl(ALI_REG(codec, ALI_STIMER)); + cpu_relax(); } } static void snd_ali_detect_spdif_rate(struct snd_ali *codec) { - u16 wval = 0; + u16 wval; u16 count = 0; - u8 bval = 0, R1 = 0, R2 = 0; + u8 bval, R1 = 0, R2; - bval = inb(ALI_REG(codec,ALI_SPDIF_CTRL + 1)); + bval = inb(ALI_REG(codec, ALI_SPDIF_CTRL + 1)); bval |= 0x1F; - outb(bval,ALI_REG(codec,ALI_SPDIF_CTRL + 1)); + outb(bval, ALI_REG(codec, ALI_SPDIF_CTRL + 1)); - while (((R1 < 0x0B )||(R1 > 0x0E)) && (R1 != 0x12) && count <= 50000) { + while ((R1 < 0x0b || R1 > 0x0e) && R1 != 0x12 && count <= 50000) { count ++; snd_ali_delay(codec, 6); - bval = inb(ALI_REG(codec,ALI_SPDIF_CTRL + 1)); + bval = inb(ALI_REG(codec, ALI_SPDIF_CTRL + 1)); R1 = bval & 0x1F; } @@ -801,7 +736,10 @@ static void snd_ali_detect_spdif_rate(struct snd_ali *codec) snd_ali_delay(codec, 6); bval = inb(ALI_REG(codec,ALI_SPDIF_CTRL + 1)); R2 = bval & 0x1F; - if (R2 != R1) R1 = R2; else break; + if (R2 != R1) + R1 = R2; + else + break; } if (count > 50000) { @@ -810,42 +748,45 @@ static void snd_ali_detect_spdif_rate(struct snd_ali *codec) } if (R2 >= 0x0b && R2 <= 0x0e) { - wval = inw(ALI_REG(codec,ALI_SPDIF_CTRL + 2)); - wval &= 0xE0F0; - wval |= (u16)0x09 << 8 | (u16)0x05; - outw(wval,ALI_REG(codec,ALI_SPDIF_CTRL + 2)); + wval = inw(ALI_REG(codec, ALI_SPDIF_CTRL + 2)); + wval &= 0xe0f0; + wval |= (0x09 << 8) | 0x05; + outw(wval, ALI_REG(codec, ALI_SPDIF_CTRL + 2)); - bval = inb(ALI_REG(codec,ALI_SPDIF_CS +3)) & 0xF0; - outb(bval|0x02,ALI_REG(codec,ALI_SPDIF_CS + 3)); + bval = inb(ALI_REG(codec, ALI_SPDIF_CS + 3)) & 0xf0; + outb(bval | 0x02, ALI_REG(codec, ALI_SPDIF_CS + 3)); } else if (R2 == 0x12) { - wval = inw(ALI_REG(codec,ALI_SPDIF_CTRL + 2)); - wval &= 0xE0F0; - wval |= (u16)0x0E << 8 | (u16)0x08; - outw(wval,ALI_REG(codec,ALI_SPDIF_CTRL + 2)); + wval = inw(ALI_REG(codec, ALI_SPDIF_CTRL + 2)); + wval &= 0xe0f0; + wval |= (0x0e << 8) | 0x08; + outw(wval, ALI_REG(codec, ALI_SPDIF_CTRL + 2)); - bval = inb(ALI_REG(codec,ALI_SPDIF_CS +3)) & 0xF0; - outb(bval|0x03,ALI_REG(codec,ALI_SPDIF_CS + 3)); + bval = inb(ALI_REG(codec,ALI_SPDIF_CS + 3)) & 0xf0; + outb(bval | 0x03, ALI_REG(codec, ALI_SPDIF_CS + 3)); } } static unsigned int snd_ali_get_spdif_in_rate(struct snd_ali *codec) { - u32 dwRate = 0; - u8 bval = 0; + u32 dwRate; + u8 bval; - bval = inb(ALI_REG(codec,ALI_SPDIF_CTRL)); - bval &= 0x7F; + bval = inb(ALI_REG(codec, ALI_SPDIF_CTRL)); + bval &= 0x7f; bval |= 0x40; - outb(bval, ALI_REG(codec,ALI_SPDIF_CTRL)); + outb(bval, ALI_REG(codec, ALI_SPDIF_CTRL)); snd_ali_detect_spdif_rate(codec); - bval = inb(ALI_REG(codec,ALI_SPDIF_CS + 3)); - bval &= 0x0F; + bval = inb(ALI_REG(codec, ALI_SPDIF_CS + 3)); + bval &= 0x0f; - if (bval == 0) dwRate = 44100; - if (bval == 1) dwRate = 48000; - if (bval == 2) dwRate = 32000; + switch (bval) { + case 0: dwRate = 44100; break; + case 1: dwRate = 48000; break; + case 2: dwRate = 32000; break; + default: dwRate = 0; break; + } return dwRate; } @@ -880,20 +821,22 @@ static void snd_ali_disable_spdif_in(struct snd_ali *codec) static void snd_ali_set_spdif_out_rate(struct snd_ali *codec, unsigned int rate) { unsigned char bVal; - unsigned int dwRate = 0; + unsigned int dwRate; - if (rate == 32000) dwRate = 0x300; - if (rate == 44100) dwRate = 0; - if (rate == 48000) dwRate = 0x200; + switch (rate) { + case 32000: dwRate = 0x300; break; + case 48000: dwRate = 0x200; break; + default: dwRate = 0; break; + } bVal = inb(ALI_REG(codec, ALI_SPDIF_CTRL)); bVal &= (unsigned char)(~(1<<6)); - bVal |= 0x80; //select right + bVal |= 0x80; /* select right */ outb(bVal, ALI_REG(codec, ALI_SPDIF_CTRL)); outb(dwRate | 0x20, ALI_REG(codec, ALI_SPDIF_CS + 2)); - bVal &= (~0x80); //select left + bVal &= ~0x80; /* select left */ outb(bVal, ALI_REG(codec, ALI_SPDIF_CTRL)); outw(rate | 0x10, ALI_REG(codec, ALI_SPDIF_CS + 2)); } @@ -902,8 +845,7 @@ static void snd_ali_enable_spdif_out(struct snd_ali *codec) { unsigned short wVal; unsigned char bVal; - - struct pci_dev *pci_dev = NULL; + struct pci_dev *pci_dev; pci_dev = codec->pci_m1533; if (pci_dev == NULL) @@ -926,17 +868,15 @@ static void snd_ali_enable_spdif_out(struct snd_ali *codec) bVal = inb(ALI_REG(codec, ALI_SPDIF_CTRL)); outb(bVal & ALI_SPDIF_OUT_CH_STATUS, ALI_REG(codec, ALI_SPDIF_CTRL)); - { - wVal = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL)); - wVal |= ALI_SPDIF_OUT_SEL_PCM; - outw(wVal, ALI_REG(codec, ALI_GLOBAL_CONTROL)); - snd_ali_disable_special_channel(codec,ALI_SPDIF_OUT_CHANNEL); - } + wVal = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL)); + wVal |= ALI_SPDIF_OUT_SEL_PCM; + outw(wVal, ALI_REG(codec, ALI_GLOBAL_CONTROL)); + snd_ali_disable_special_channel(codec, ALI_SPDIF_OUT_CHANNEL); } static void snd_ali_enable_spdif_chnout(struct snd_ali *codec) { - unsigned short wVal = 0; + unsigned short wVal; wVal = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL)); wVal &= ~ALI_SPDIF_OUT_SEL_PCM; @@ -949,12 +889,13 @@ static void snd_ali_enable_spdif_chnout(struct snd_ali *codec) wVal &= (~0x0002); outw(wVal, ALI_REG(codec, ALI_SPDIF_CS)); */ - snd_ali_enable_special_channel(codec,ALI_SPDIF_OUT_CHANNEL); + snd_ali_enable_special_channel(codec, ALI_SPDIF_OUT_CHANNEL); } static void snd_ali_disable_spdif_chnout(struct snd_ali *codec) { - unsigned short wVal = 0; + unsigned short wVal; + wVal = inw(ALI_REG(codec, ALI_GLOBAL_CONTROL)); wVal |= ALI_SPDIF_OUT_SEL_PCM; outw(wVal, ALI_REG(codec, ALI_GLOBAL_CONTROL)); @@ -972,11 +913,11 @@ static void snd_ali_disable_spdif_out(struct snd_ali *codec) snd_ali_disable_spdif_chnout(codec); } -static void snd_ali_update_ptr(struct snd_ali *codec,int channel) +static void snd_ali_update_ptr(struct snd_ali *codec, int channel) { - struct snd_ali_voice *pvoice = NULL; + struct snd_ali_voice *pvoice; struct snd_pcm_runtime *runtime; - struct snd_ali_channel_control *pchregs = NULL; + struct snd_ali_channel_control *pchregs; unsigned int old, mask; #ifdef ALI_DEBUG unsigned int temp, cspf; @@ -984,9 +925,9 @@ static void snd_ali_update_ptr(struct snd_ali *codec,int channel) pchregs = &(codec->chregs); - // check if interrupt occurred for channel + /* check if interrupt occurred for channel */ old = pchregs->data.aint; - mask = ((unsigned int) 1L) << (channel & 0x1f); + mask = 1U << (channel & 0x1f); if (!(old & mask)) return; @@ -1005,7 +946,8 @@ static void snd_ali_update_ptr(struct snd_ali *codec,int channel) cspf = (inl(ALI_REG(codec, ALI_CSPF)) & mask) == mask; #endif if (pvoice->running) { - snd_ali_printk("update_ptr: cso=%4.4x cspf=%d.\n",(u16)temp,cspf); + snd_ali_printk("update_ptr: cso=%4.4x cspf=%d.\n", + (u16)temp, cspf); spin_unlock(&codec->reg_lock); snd_pcm_period_elapsed(pvoice->substream); spin_lock(&codec->reg_lock); @@ -1027,49 +969,47 @@ static void snd_ali_update_ptr(struct snd_ali *codec,int channel) pchregs->data.aint = old & (~mask); } -static void snd_ali_interrupt(struct snd_ali * codec) +static irqreturn_t snd_ali_card_interrupt(int irq, void *dev_id) { + struct snd_ali *codec = dev_id; int channel; unsigned int audio_int; - struct snd_ali_channel_control *pchregs = NULL; - pchregs = &(codec->chregs); + struct snd_ali_channel_control *pchregs; + + if (codec == NULL || !codec->hw_initialized) + return IRQ_NONE; audio_int = inl(ALI_REG(codec, ALI_MISCINT)); + if (!audio_int) + return IRQ_NONE; + + pchregs = &(codec->chregs); if (audio_int & ADDRESS_IRQ) { - // get interrupt status for all channels - pchregs->data.aint = inl(ALI_REG(codec,pchregs->regs.aint)); - for (channel = 0; channel < ALI_CHANNELS; channel++) { + /* get interrupt status for all channels */ + pchregs->data.aint = inl(ALI_REG(codec, pchregs->regs.aint)); + for (channel = 0; channel < ALI_CHANNELS; channel++) snd_ali_update_ptr(codec, channel); - } } outl((TARGET_REACHED | MIXER_OVERFLOW | MIXER_UNDERFLOW), - ALI_REG(codec,ALI_MISCINT)); -} - - -static irqreturn_t snd_ali_card_interrupt(int irq, void *dev_id) -{ - struct snd_ali *codec = dev_id; + ALI_REG(codec, ALI_MISCINT)); - if (codec == NULL) - return IRQ_NONE; - snd_ali_interrupt(codec); return IRQ_HANDLED; } -static struct snd_ali_voice *snd_ali_alloc_voice(struct snd_ali * codec, int type, int rec, int channel) +static struct snd_ali_voice *snd_ali_alloc_voice(struct snd_ali * codec, + int type, int rec, int channel) { - struct snd_ali_voice *pvoice = NULL; + struct snd_ali_voice *pvoice; int idx; - snd_ali_printk("alloc_voice: type=%d rec=%d\n",type,rec); + snd_ali_printk("alloc_voice: type=%d rec=%d\n", type, rec); spin_lock_irq(&codec->voice_alloc); if (type == SNDRV_ALI_VOICE_TYPE_PCM) { idx = channel > 0 ? snd_ali_alloc_pcm_channel(codec, channel) : snd_ali_find_free_channel(codec,rec); - if(idx < 0) { + if (idx < 0) { snd_printk(KERN_ERR "ali_alloc_voice: err.\n"); spin_unlock_irq(&codec->voice_alloc); return NULL; @@ -1087,7 +1027,8 @@ static struct snd_ali_voice *snd_ali_alloc_voice(struct snd_ali * codec, int typ } -static void snd_ali_free_voice(struct snd_ali * codec, struct snd_ali_voice *pvoice) +static void snd_ali_free_voice(struct snd_ali * codec, + struct snd_ali_voice *pvoice) { void (*private_free)(void *); void *private_data; @@ -1101,9 +1042,8 @@ static void snd_ali_free_voice(struct snd_ali * codec, struct snd_ali_voice *pvo private_data = pvoice->private_data; pvoice->private_free = NULL; pvoice->private_data = NULL; - if (pvoice->pcm) { + if (pvoice->pcm) snd_ali_free_channel_pcm(codec, pvoice->number); - } pvoice->use = pvoice->pcm = pvoice->synth = 0; pvoice->substream = NULL; spin_unlock_irq(&codec->voice_alloc); @@ -1112,9 +1052,9 @@ static void snd_ali_free_voice(struct snd_ali * codec, struct snd_ali_voice *pvo } -static void snd_ali_clear_voices(struct snd_ali * codec, - unsigned int v_min, - unsigned int v_max) +static void snd_ali_clear_voices(struct snd_ali *codec, + unsigned int v_min, + unsigned int v_max) { unsigned int i; @@ -1124,7 +1064,7 @@ static void snd_ali_clear_voices(struct snd_ali * codec, } } -static void snd_ali_write_voice_regs(struct snd_ali * codec, +static void snd_ali_write_voice_regs(struct snd_ali *codec, unsigned int Channel, unsigned int LBA, unsigned int CSO, @@ -1139,7 +1079,7 @@ static void snd_ali_write_voice_regs(struct snd_ali * codec, { unsigned int ctlcmds[4]; - outb((unsigned char)(Channel & 0x001f),ALI_REG(codec,ALI_GC_CIR)); + outb((unsigned char)(Channel & 0x001f), ALI_REG(codec, ALI_GC_CIR)); ctlcmds[0] = (CSO << 16) | (ALPHA_FMS & 0x0000ffff); ctlcmds[1] = LBA; @@ -1152,10 +1092,10 @@ static void snd_ali_write_voice_regs(struct snd_ali * codec, outb(Channel, ALI_REG(codec, ALI_GC_CIR)); - outl(ctlcmds[0], ALI_REG(codec,ALI_CSO_ALPHA_FMS)); - outl(ctlcmds[1], ALI_REG(codec,ALI_LBA)); - outl(ctlcmds[2], ALI_REG(codec,ALI_ESO_DELTA)); - outl(ctlcmds[3], ALI_REG(codec,ALI_GVSEL_PAN_VOC_CTRL_EC)); + outl(ctlcmds[0], ALI_REG(codec, ALI_CSO_ALPHA_FMS)); + outl(ctlcmds[1], ALI_REG(codec, ALI_LBA)); + outl(ctlcmds[2], ALI_REG(codec, ALI_ESO_DELTA)); + outl(ctlcmds[3], ALI_REG(codec, ALI_GVSEL_PAN_VOC_CTRL_EC)); outl(0x30000000, ALI_REG(codec, ALI_EBUF1)); /* Still Mode */ outl(0x30000000, ALI_REG(codec, ALI_EBUF2)); /* Still Mode */ @@ -1165,8 +1105,10 @@ static unsigned int snd_ali_convert_rate(unsigned int rate, int rec) { unsigned int delta; - if (rate < 4000) rate = 4000; - if (rate > 48000) rate = 48000; + if (rate < 4000) + rate = 4000; + if (rate > 48000) + rate = 48000; if (rec) { if (rate == 44100) @@ -1201,11 +1143,11 @@ static unsigned int snd_ali_control_mode(struct snd_pcm_substream *substream) */ CTRL = 0x00000001; if (snd_pcm_format_width(runtime->format) == 16) - CTRL |= 0x00000008; // 16-bit data + CTRL |= 0x00000008; /* 16-bit data */ if (!snd_pcm_format_unsigned(runtime->format)) - CTRL |= 0x00000002; // signed data + CTRL |= 0x00000002; /* signed data */ if (runtime->channels > 1) - CTRL |= 0x00000004; // stereo data + CTRL |= 0x00000004; /* stereo data */ return CTRL; } @@ -1213,45 +1155,39 @@ static unsigned int snd_ali_control_mode(struct snd_pcm_substream *substream) * PCM part */ -static int snd_ali_ioctl(struct snd_pcm_substream *substream, - unsigned int cmd, void *arg) -{ - return snd_pcm_lib_ioctl(substream, cmd, arg); -} - static int snd_ali_trigger(struct snd_pcm_substream *substream, int cmd) { struct snd_ali *codec = snd_pcm_substream_chip(substream); - struct list_head *pos; struct snd_pcm_substream *s; unsigned int what, whati, capture_flag; - struct snd_ali_voice *pvoice = NULL, *evoice = NULL; + struct snd_ali_voice *pvoice, *evoice; unsigned int val; int do_start; switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: - do_start = 1; break; + do_start = 1; + break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: - do_start = 0; break; + do_start = 0; + break; default: return -EINVAL; } what = whati = capture_flag = 0; - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if ((struct snd_ali *) snd_pcm_substream_chip(s) == codec) { pvoice = s->runtime->private_data; evoice = pvoice->extra; what |= 1 << (pvoice->number & 0x1f); - if (evoice == NULL) { + if (evoice == NULL) whati |= 1 << (pvoice->number & 0x1f); - } else { + else { whati |= 1 << (evoice->number & 0x1f); what |= 1 << (evoice->number & 0x1f); } @@ -1270,48 +1206,51 @@ static int snd_ali_trigger(struct snd_pcm_substream *substream, } } spin_lock(&codec->reg_lock); - if (! do_start) { + if (!do_start) outl(what, ALI_REG(codec, ALI_STOP)); - } val = inl(ALI_REG(codec, ALI_AINTEN)); - if (do_start) { + if (do_start) val |= whati; - } else { + else val &= ~whati; - } outl(val, ALI_REG(codec, ALI_AINTEN)); - if (do_start) { + if (do_start) outl(what, ALI_REG(codec, ALI_START)); - } - snd_ali_printk("trigger: what=%xh whati=%xh\n",what,whati); + snd_ali_printk("trigger: what=%xh whati=%xh\n", what, whati); spin_unlock(&codec->reg_lock); return 0; } static int snd_ali_playback_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params) + struct snd_pcm_hw_params *hw_params) { struct snd_ali *codec = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; struct snd_ali_voice *pvoice = runtime->private_data; struct snd_ali_voice *evoice = pvoice->extra; int err; - err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); - if (err < 0) return err; + + err = snd_pcm_lib_malloc_pages(substream, + params_buffer_bytes(hw_params)); + if (err < 0) + return err; /* voice management */ - if (params_buffer_size(hw_params)/2 != params_period_size(hw_params)) { - if (evoice == NULL) { - evoice = snd_ali_alloc_voice(codec, SNDRV_ALI_VOICE_TYPE_PCM, 0, -1); - if (evoice == NULL) + if (params_buffer_size(hw_params) / 2 != + params_period_size(hw_params)) { + if (!evoice) { + evoice = snd_ali_alloc_voice(codec, + SNDRV_ALI_VOICE_TYPE_PCM, + 0, -1); + if (!evoice) return -ENOMEM; pvoice->extra = evoice; evoice->substream = substream; } } else { - if (evoice != NULL) { + if (!evoice) { snd_ali_free_voice(codec, evoice); pvoice->extra = evoice = NULL; } @@ -1328,7 +1267,7 @@ static int snd_ali_playback_hw_free(struct snd_pcm_substream *substream) struct snd_ali_voice *evoice = pvoice ? pvoice->extra : NULL; snd_pcm_lib_free_pages(substream); - if (evoice != NULL) { + if (!evoice) { snd_ali_free_voice(codec, evoice); pvoice->extra = NULL; } @@ -1336,9 +1275,10 @@ static int snd_ali_playback_hw_free(struct snd_pcm_substream *substream) } static int snd_ali_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params) + struct snd_pcm_hw_params *hw_params) { - return snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); + return snd_pcm_lib_malloc_pages(substream, + params_buffer_bytes(hw_params)); } static int snd_ali_hw_free(struct snd_pcm_substream *substream) @@ -1369,12 +1309,13 @@ static int snd_ali_playback_prepare(struct snd_pcm_substream *substream) /* set Delta (rate) value */ Delta = snd_ali_convert_rate(runtime->rate, 0); - if ((pvoice->number == ALI_SPDIF_IN_CHANNEL) || - (pvoice->number == ALI_PCM_IN_CHANNEL)) + if (pvoice->number == ALI_SPDIF_IN_CHANNEL || + pvoice->number == ALI_PCM_IN_CHANNEL) snd_ali_disable_special_channel(codec, pvoice->number); else if (codec->spdif_support && - (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) & ALI_SPDIF_OUT_CH_ENABLE) - && (pvoice->number == ALI_SPDIF_OUT_CHANNEL)) { + (inl(ALI_REG(codec, ALI_GLOBAL_CONTROL)) & + ALI_SPDIF_OUT_CH_ENABLE) + && pvoice->number == ALI_SPDIF_OUT_CHANNEL) { snd_ali_set_spdif_out_rate(codec, runtime->rate); Delta = 0x1000; } @@ -1388,7 +1329,8 @@ static int snd_ali_playback_prepare(struct snd_pcm_substream *substream) /* set target ESO for channel */ pvoice->eso = runtime->buffer_size; - snd_ali_printk("playback_prepare: eso=%xh count=%xh\n",pvoice->eso,pvoice->count); + snd_ali_printk("playback_prepare: eso=%xh count=%xh\n", + pvoice->eso, pvoice->count); /* set ESO to capture first MIDLP interrupt */ ESO = pvoice->eso -1; @@ -1399,35 +1341,37 @@ static int snd_ali_playback_prepare(struct snd_pcm_substream *substream) PAN = 0; VOL = 0; EC = 0; - snd_ali_printk("playback_prepare:\n ch=%d, Rate=%d Delta=%xh,GVSEL=%xh,PAN=%xh,CTRL=%xh\n",pvoice->number,runtime->rate,Delta,GVSEL,PAN,CTRL); - snd_ali_write_voice_regs( codec, - pvoice->number, - LBA, - 0, /* cso */ - ESO, - Delta, - 0, /* alpha */ - GVSEL, - PAN, - VOL, - CTRL, - EC); - if (evoice != NULL) { + snd_ali_printk("playback_prepare:\n"); + snd_ali_printk("ch=%d, Rate=%d Delta=%xh,GVSEL=%xh,PAN=%xh,CTRL=%xh\n", + pvoice->number,runtime->rate,Delta,GVSEL,PAN,CTRL); + snd_ali_write_voice_regs(codec, + pvoice->number, + LBA, + 0, /* cso */ + ESO, + Delta, + 0, /* alpha */ + GVSEL, + PAN, + VOL, + CTRL, + EC); + if (!evoice) { evoice->count = pvoice->count; evoice->eso = pvoice->count << 1; ESO = evoice->eso - 1; snd_ali_write_voice_regs(codec, - evoice->number, - LBA, - 0, /* cso */ - ESO, - Delta, - 0, /* alpha */ - GVSEL, - (unsigned int)0x7f, - (unsigned int)0x3ff, - CTRL, - EC); + evoice->number, + LBA, + 0, /* cso */ + ESO, + Delta, + 0, /* alpha */ + GVSEL, + 0x7f, + 0x3ff, + CTRL, + EC); } spin_unlock_irq(&codec->reg_lock); return 0; @@ -1459,7 +1403,7 @@ static int snd_ali_prepare(struct snd_pcm_substream *substream) pvoice->number == ALI_MODEM_OUT_CHANNEL) ? 0x1000 : snd_ali_convert_rate(runtime->rate, pvoice->mode); - // Prepare capture intr channel + /* Prepare capture intr channel */ if (pvoice->number == ALI_SPDIF_IN_CHANNEL) { unsigned int rate; @@ -1470,7 +1414,8 @@ static int snd_ali_prepare(struct snd_pcm_substream *substream) rate = snd_ali_get_spdif_in_rate(codec); if (rate == 0) { - snd_printk(KERN_WARNING "ali_capture_preapre: spdif rate detect err!\n"); + snd_printk(KERN_WARNING "ali_capture_preapre: " + "spdif rate detect err!\n"); rate = 48000; } spin_lock_irq(&codec->reg_lock); @@ -1481,19 +1426,19 @@ static int snd_ali_prepare(struct snd_pcm_substream *substream) } if (rate != 48000) - Delta = ((rate << 12)/runtime->rate)&0x00ffff; + Delta = ((rate << 12) / runtime->rate) & 0x00ffff; } - // set target ESO for channel + /* set target ESO for channel */ pvoice->eso = runtime->buffer_size; - // set interrupt count size + /* set interrupt count size */ pvoice->count = runtime->period_size; - // set Loop Back Address + /* set Loop Back Address */ LBA = runtime->dma_addr; - // set ESO to capture first MIDLP interrupt + /* set ESO to capture first MIDLP interrupt */ ESO = pvoice->eso - 1; CTRL = snd_ali_control_mode(substream); GVSEL = 0; @@ -1514,14 +1459,14 @@ static int snd_ali_prepare(struct snd_pcm_substream *substream) CTRL, EC); - spin_unlock_irq(&codec->reg_lock); return 0; } -static snd_pcm_uframes_t snd_ali_playback_pointer(struct snd_pcm_substream *substream) +static snd_pcm_uframes_t +snd_ali_playback_pointer(struct snd_pcm_substream *substream) { struct snd_ali *codec = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; @@ -1563,14 +1508,14 @@ static snd_pcm_uframes_t snd_ali_pointer(struct snd_pcm_substream *substream) static struct snd_pcm_hardware snd_ali_playback = { - .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_RESUME | - SNDRV_PCM_INFO_SYNC_START), - .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE), - .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, + .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_RESUME | + SNDRV_PCM_INFO_SYNC_START), + .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE), + .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, .rate_min = 4000, .rate_max = 48000, .channels_min = 1, @@ -1589,14 +1534,14 @@ static struct snd_pcm_hardware snd_ali_playback = static struct snd_pcm_hardware snd_ali_capture = { - .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_RESUME | - SNDRV_PCM_INFO_SYNC_START), - .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE), - .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, + .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_RESUME | + SNDRV_PCM_INFO_SYNC_START), + .formats = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U16_LE), + .rates = SNDRV_PCM_RATE_CONTINUOUS | SNDRV_PCM_RATE_8000_48000, .rate_min = 4000, .rate_max = 48000, .channels_min = 1, @@ -1620,15 +1565,16 @@ static void snd_ali_pcm_free_substream(struct snd_pcm_runtime *runtime) } } -static int snd_ali_open(struct snd_pcm_substream *substream, int rec, int channel, - struct snd_pcm_hardware *phw) +static int snd_ali_open(struct snd_pcm_substream *substream, int rec, + int channel, struct snd_pcm_hardware *phw) { struct snd_ali *codec = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; struct snd_ali_voice *pvoice; - pvoice = snd_ali_alloc_voice(codec, SNDRV_ALI_VOICE_TYPE_PCM, rec, channel); - if (pvoice == NULL) + pvoice = snd_ali_alloc_voice(codec, SNDRV_ALI_VOICE_TYPE_PCM, rec, + channel); + if (!pvoice) return -EAGAIN; pvoice->substream = substream; @@ -1637,7 +1583,8 @@ static int snd_ali_open(struct snd_pcm_substream *substream, int rec, int channe runtime->hw = *phw; snd_pcm_set_sync(substream); - snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, 0, 64*1024); + snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, + 0, 64*1024); return 0; } @@ -1669,7 +1616,7 @@ static int snd_ali_close(struct snd_pcm_substream *substream) static struct snd_pcm_ops snd_ali_playback_ops = { .open = snd_ali_playback_open, .close = snd_ali_playback_close, - .ioctl = snd_ali_ioctl, + .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_ali_playback_hw_params, .hw_free = snd_ali_playback_hw_free, .prepare = snd_ali_playback_prepare, @@ -1680,7 +1627,7 @@ static struct snd_pcm_ops snd_ali_playback_ops = { static struct snd_pcm_ops snd_ali_capture_ops = { .open = snd_ali_capture_open, .close = snd_ali_close, - .ioctl = snd_ali_ioctl, + .ioctl = snd_pcm_lib_ioctl, .hw_params = snd_ali_hw_params, .hw_free = snd_ali_hw_free, .prepare = snd_ali_prepare, @@ -1697,20 +1644,22 @@ static int snd_ali_modem_hw_params(struct snd_pcm_substream *substream, { struct snd_ali *chip = snd_pcm_substream_chip(substream); unsigned int modem_num = chip->num_of_codecs - 1; - snd_ac97_write(chip->ac97[modem_num], AC97_LINE1_RATE, params_rate(hw_params)); + snd_ac97_write(chip->ac97[modem_num], AC97_LINE1_RATE, + params_rate(hw_params)); snd_ac97_write(chip->ac97[modem_num], AC97_LINE1_LEVEL, 0); return snd_ali_hw_params(substream, hw_params); } static struct snd_pcm_hardware snd_ali_modem = { - .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_RESUME | - SNDRV_PCM_INFO_SYNC_START), - .formats = SNDRV_PCM_FMTBIT_S16_LE, - .rates = SNDRV_PCM_RATE_KNOT|SNDRV_PCM_RATE_8000|SNDRV_PCM_RATE_16000, + .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_BLOCK_TRANSFER | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_RESUME | + SNDRV_PCM_INFO_SYNC_START), + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rates = (SNDRV_PCM_RATE_KNOT | SNDRV_PCM_RATE_8000 | + SNDRV_PCM_RATE_16000), .rate_min = 8000, .rate_max = 16000, .channels_min = 1, @@ -1723,15 +1672,17 @@ static struct snd_pcm_hardware snd_ali_modem = .fifo_size = 0, }; -static int snd_ali_modem_open(struct snd_pcm_substream *substream, int rec, int channel) +static int snd_ali_modem_open(struct snd_pcm_substream *substream, int rec, + int channel) { - static unsigned int rates [] = {8000,9600,12000,16000}; + static unsigned int rates[] = {8000, 9600, 12000, 16000}; static struct snd_pcm_hw_constraint_list hw_constraint_rates = { .count = ARRAY_SIZE(rates), .list = rates, .mask = 0, }; int err = snd_ali_open(substream, rec, channel, &snd_ali_modem); + if (err) return err; return snd_pcm_hw_constraint_list(substream->runtime, 0, @@ -1788,7 +1739,8 @@ static void snd_ali_pcm_free(struct snd_pcm *pcm) } -static int __devinit snd_ali_pcm(struct snd_ali * codec, int device, struct ali_pcm_description *desc) +static int __devinit snd_ali_pcm(struct snd_ali * codec, int device, + struct ali_pcm_description *desc) { struct snd_pcm *pcm; int err; @@ -1802,12 +1754,15 @@ static int __devinit snd_ali_pcm(struct snd_ali * codec, int device, struct ali_ pcm->private_data = codec; pcm->private_free = snd_ali_pcm_free; if (desc->playback_ops) - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, desc->playback_ops); + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, + desc->playback_ops); if (desc->capture_ops) - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, desc->capture_ops); + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, + desc->capture_ops); snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, - snd_dma_pci_data(codec->pci), 64*1024, 128*1024); + snd_dma_pci_data(codec->pci), + 64*1024, 128*1024); pcm->info_flags = 0; pcm->dev_class = desc->class; @@ -1818,16 +1773,29 @@ static int __devinit snd_ali_pcm(struct snd_ali * codec, int device, struct ali_ } static struct ali_pcm_description ali_pcms[] = { - { "ALI 5451", ALI_CHANNELS, 1, &snd_ali_playback_ops, &snd_ali_capture_ops }, - { "ALI 5451 modem", 1, 1, &snd_ali_modem_playback_ops, &snd_ali_modem_capture_ops, SNDRV_PCM_CLASS_MODEM } + { .name = "ALI 5451", + .playback_num = ALI_CHANNELS, + .capture_num = 1, + .playback_ops = &snd_ali_playback_ops, + .capture_ops = &snd_ali_capture_ops + }, + { .name = "ALI 5451 modem", + .playback_num = 1, + .capture_num = 1, + .playback_ops = &snd_ali_modem_playback_ops, + .capture_ops = &snd_ali_modem_capture_ops, + .class = SNDRV_PCM_CLASS_MODEM + } }; static int __devinit snd_ali_build_pcms(struct snd_ali *codec) { int i, err; - for(i = 0 ; i < codec->num_of_codecs && i < ARRAY_SIZE(ali_pcms) ; i++) - if((err = snd_ali_pcm(codec, i, &ali_pcms[i])) < 0) + for (i = 0; i < codec->num_of_codecs && i < ARRAY_SIZE(ali_pcms); i++) { + err = snd_ali_pcm(codec, i, &ali_pcms[i]); + if (err < 0) return err; + } return 0; } @@ -1837,7 +1805,8 @@ static int __devinit snd_ali_build_pcms(struct snd_ali *codec) .info = snd_ali5451_spdif_info, .get = snd_ali5451_spdif_get, \ .put = snd_ali5451_spdif_put, .private_value = value} -static int snd_ali5451_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +static int snd_ali5451_spdif_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; uinfo->count = 1; @@ -1846,7 +1815,8 @@ static int snd_ali5451_spdif_info(struct snd_kcontrol *kcontrol, struct snd_ctl_ return 0; } -static int snd_ali5451_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_ali5451_spdif_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct snd_ali *codec = kcontrol->private_data; unsigned int enable; @@ -1854,12 +1824,13 @@ static int snd_ali5451_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e enable = ucontrol->value.integer.value[0] ? 1 : 0; spin_lock_irq(&codec->reg_lock); - switch(kcontrol->private_value) { + switch (kcontrol->private_value) { case 0: enable = (codec->spdif_mask & 0x02) ? 1 : 0; break; case 1: - enable = ((codec->spdif_mask & 0x02) && (codec->spdif_mask & 0x04)) ? 1 : 0; + enable = ((codec->spdif_mask & 0x02) && + (codec->spdif_mask & 0x04)) ? 1 : 0; break; case 2: enable = (codec->spdif_mask & 0x01) ? 1 : 0; @@ -1872,7 +1843,8 @@ static int snd_ali5451_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e return 0; } -static int snd_ali5451_spdif_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_ali5451_spdif_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct snd_ali *codec = kcontrol->private_data; unsigned int change = 0, enable = 0; @@ -1939,18 +1911,6 @@ static struct snd_kcontrol_new snd_ali5451_mixer_spdif[] __devinitdata = { ALI5451_SPDIF(SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), 0, 2) }; -static void snd_ali_mixer_free_ac97_bus(struct snd_ac97_bus *bus) -{ - struct snd_ali *codec = bus->private_data; - codec->ac97_bus = NULL; -} - -static void snd_ali_mixer_free_ac97(struct snd_ac97 *ac97) -{ - struct snd_ali *codec = ac97->private_data; - codec->ac97[ac97->num] = NULL; -} - static int __devinit snd_ali_mixer(struct snd_ali * codec) { struct snd_ac97_template ac97; @@ -1961,19 +1921,20 @@ static int __devinit snd_ali_mixer(struct snd_ali * codec) .read = snd_ali_codec_read, }; - if ((err = snd_ac97_bus(codec->card, 0, &ops, codec, &codec->ac97_bus)) < 0) + err = snd_ac97_bus(codec->card, 0, &ops, codec, &codec->ac97_bus); + if (err < 0) return err; - codec->ac97_bus->private_free = snd_ali_mixer_free_ac97_bus; memset(&ac97, 0, sizeof(ac97)); ac97.private_data = codec; - ac97.private_free = snd_ali_mixer_free_ac97; - for ( i = 0 ; i < codec->num_of_codecs ; i++) { + for (i = 0; i < codec->num_of_codecs; i++) { ac97.num = i; - if ((err = snd_ac97_mixer(codec->ac97_bus, &ac97, &codec->ac97[i])) < 0) { - snd_printk(KERN_ERR "ali mixer %d creating error.\n", i); - if(i == 0) + err = snd_ac97_mixer(codec->ac97_bus, &ac97, &codec->ac97[i]); + if (err < 0) { + snd_printk(KERN_ERR + "ali mixer %d creating error.\n", i); + if (i == 0) return err; codec->num_of_codecs = 1; break; @@ -1981,9 +1942,11 @@ static int __devinit snd_ali_mixer(struct snd_ali * codec) } if (codec->spdif_support) { - for(idx = 0; idx < ARRAY_SIZE(snd_ali5451_mixer_spdif); idx++) { - err=snd_ctl_add(codec->card, snd_ctl_new1(&snd_ali5451_mixer_spdif[idx], codec)); - if (err < 0) return err; + for (idx = 0; idx < ARRAY_SIZE(snd_ali5451_mixer_spdif); idx++) { + err = snd_ctl_add(codec->card, + snd_ctl_new1(&snd_ali5451_mixer_spdif[idx], codec)); + if (err < 0) + return err; } } return 0; @@ -1998,11 +1961,11 @@ static int ali_suspend(struct pci_dev *pci, pm_message_t state) int i, j; im = chip->image; - if (! im) + if (!im) return 0; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); - for(i = 0 ; i < chip->num_of_codecs ; i++) { + for (i = 0; i < chip->num_of_codecs; i++) { snd_pcm_suspend_all(chip->pcm[i]); snd_ac97_suspend(chip->ac97[i]); } @@ -2010,10 +1973,10 @@ static int ali_suspend(struct pci_dev *pci, pm_message_t state) spin_lock_irq(&chip->reg_lock); im->regs[ALI_MISCINT >> 2] = inl(ALI_REG(chip, ALI_MISCINT)); - // im->regs[ALI_START >> 2] = inl(ALI_REG(chip, ALI_START)); + /* im->regs[ALI_START >> 2] = inl(ALI_REG(chip, ALI_START)); */ im->regs[ALI_STOP >> 2] = inl(ALI_REG(chip, ALI_STOP)); - // disable all IRQ bits + /* disable all IRQ bits */ outl(0, ALI_REG(chip, ALI_MISCINT)); for (i = 0; i < ALI_GLOBAL_REGS; i++) { @@ -2028,7 +1991,7 @@ static int ali_suspend(struct pci_dev *pci, pm_message_t state) im->channel_regs[i][j] = inl(ALI_REG(chip, j*4 + 0xe0)); } - // stop all HW channel + /* stop all HW channel */ outl(0xffffffff, ALI_REG(chip, ALI_STOP)); spin_unlock_irq(&chip->reg_lock); @@ -2047,7 +2010,7 @@ static int ali_resume(struct pci_dev *pci) int i, j; im = chip->image; - if (! im) + if (!im) return 0; pci_set_power_state(pci, PCI_D0); @@ -2069,19 +2032,20 @@ static int ali_resume(struct pci_dev *pci) } for (i = 0; i < ALI_GLOBAL_REGS; i++) { - if ((i*4 == ALI_MISCINT) || (i*4 == ALI_STOP) || (i*4 == ALI_START)) + if ((i*4 == ALI_MISCINT) || (i*4 == ALI_STOP) || + (i*4 == ALI_START)) continue; outl(im->regs[i], ALI_REG(chip, i*4)); } - // start HW channel + /* start HW channel */ outl(im->regs[ALI_START >> 2], ALI_REG(chip, ALI_START)); - // restore IRQ enable bits + /* restore IRQ enable bits */ outl(im->regs[ALI_MISCINT >> 2], ALI_REG(chip, ALI_MISCINT)); spin_unlock_irq(&chip->reg_lock); - for(i = 0 ; i < chip->num_of_codecs ; i++) + for (i = 0 ; i < chip->num_of_codecs; i++) snd_ac97_resume(chip->ac97[i]); snd_power_change_state(card, SNDRV_CTL_POWER_D0); @@ -2113,7 +2077,7 @@ static int snd_ali_chip_init(struct snd_ali *codec) { unsigned int legacy; unsigned char temp; - struct pci_dev *pci_dev = NULL; + struct pci_dev *pci_dev; snd_ali_printk("chip initializing ... \n"); @@ -2146,7 +2110,8 @@ static int snd_ali_chip_init(struct snd_ali *codec) outb(0x10, ALI_REG(codec, ALI_MPUR2)); codec->ac97_ext_id = snd_ali_codec_peek(codec, 0, AC97_EXTENDED_ID); - codec->ac97_ext_status = snd_ali_codec_peek(codec, 0, AC97_EXTENDED_STATUS); + codec->ac97_ext_status = snd_ali_codec_peek(codec, 0, + AC97_EXTENDED_STATUS); if (codec->spdif_support) { snd_ali_enable_spdif_out(codec); codec->spdif_mask = 0x00000002; @@ -2158,8 +2123,9 @@ static int snd_ali_chip_init(struct snd_ali *codec) if (inl(ALI_REG(codec, ALI_SCTRL)) & ALI_SCTRL_CODEC2_READY) { codec->num_of_codecs++; outl(inl(ALI_REG(codec, ALI_SCTRL)) | - (ALI_SCTRL_LINE_IN2|ALI_SCTRL_GPIO_IN2|ALI_SCTRL_LINE_OUT_EN), - ALI_REG(codec, ALI_SCTRL)); + (ALI_SCTRL_LINE_IN2 | ALI_SCTRL_GPIO_IN2 | + ALI_SCTRL_LINE_OUT_EN), + ALI_REG(codec, ALI_SCTRL)); } snd_ali_printk("chip initialize succeed.\n"); @@ -2168,18 +2134,19 @@ static int snd_ali_chip_init(struct snd_ali *codec) } /* proc for register dump */ -static void snd_ali_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buf) +static void snd_ali_proc_read(struct snd_info_entry *entry, + struct snd_info_buffer *buf) { struct snd_ali *codec = entry->private_data; int i; - for(i = 0 ; i < 256 ; i+= 4) + for (i = 0; i < 256 ; i+= 4) snd_iprintf(buf, "%02x: %08x\n", i, inl(ALI_REG(codec, i))); } static void __devinit snd_ali_proc_init(struct snd_ali *codec) { struct snd_info_entry *entry; - if(!snd_card_proc_new(codec->card, "ali5451", &entry)) + if (!snd_card_proc_new(codec->card, "ali5451", &entry)) snd_info_set_text_ops(entry, codec, snd_ali_proc_read); } @@ -2188,7 +2155,8 @@ static int __devinit snd_ali_resources(struct snd_ali *codec) int err; snd_ali_printk("resouces allocation ...\n"); - if ((err = pci_request_regions(codec->pci, "ALI 5451")) < 0) + err = pci_request_regions(codec->pci, "ALI 5451"); + if (err < 0) return err; codec->port = pci_resource_start(codec->pci, 0); @@ -2201,9 +2169,9 @@ static int __devinit snd_ali_resources(struct snd_ali *codec) snd_ali_printk("resouces allocated.\n"); return 0; } -static int snd_ali_dev_free(struct snd_device *device) +static int snd_ali_dev_free(struct snd_device *device) { - struct snd_ali *codec=device->device_data; + struct snd_ali *codec = device->device_data; snd_ali_free(codec); return 0; } @@ -2226,17 +2194,20 @@ static int __devinit snd_ali_create(struct snd_card *card, snd_ali_printk("creating ...\n"); /* enable PCI device */ - if ((err = pci_enable_device(pci)) < 0) + err = pci_enable_device(pci); + if (err < 0) return err; /* check, if we can restrict PCI DMA transfers to 31 bits */ if (pci_set_dma_mask(pci, DMA_31BIT_MASK) < 0 || pci_set_consistent_dma_mask(pci, DMA_31BIT_MASK) < 0) { - snd_printk(KERN_ERR "architecture does not support 31bit PCI busmaster DMA\n"); + snd_printk(KERN_ERR "architecture does not support " + "31bit PCI busmaster DMA\n"); pci_disable_device(pci); return -ENXIO; } - if ((codec = kzalloc(sizeof(*codec), GFP_KERNEL)) == NULL) { + codec = kzalloc(sizeof(*codec), GFP_KERNEL); + if (!codec) { pci_disable_device(pci); return -ENOMEM; } @@ -2293,21 +2264,22 @@ static int __devinit snd_ali_create(struct snd_card *card, /* M1533: southbridge */ codec->pci_m1533 = pci_get_device(0x10b9, 0x1533, NULL); - if (! codec->pci_m1533) { + if (!codec->pci_m1533) { snd_printk(KERN_ERR "ali5451: cannot find ALi 1533 chip.\n"); snd_ali_free(codec); return -ENODEV; } /* M7101: power management */ codec->pci_m7101 = pci_get_device(0x10b9, 0x7101, NULL); - if (! codec->pci_m7101 && codec->revision == ALI_5451_V02) { + if (!codec->pci_m7101 && codec->revision == ALI_5451_V02) { snd_printk(KERN_ERR "ali5451: cannot find ALi 7101 chip.\n"); snd_ali_free(codec); return -ENODEV; } snd_ali_printk("snd_device_new is called.\n"); - if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, codec, &ops)) < 0) { + err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, codec, &ops); + if (err < 0) { snd_ali_free(codec); return err; } @@ -2315,18 +2287,18 @@ static int __devinit snd_ali_create(struct snd_card *card, snd_card_set_dev(card, &pci->dev); /* initialise synth voices*/ - for (i = 0; i < ALI_CHANNELS; i++ ) { + for (i = 0; i < ALI_CHANNELS; i++) codec->synth.voices[i].number = i; - } - if ((err = snd_ali_chip_init(codec)) < 0) { + err = snd_ali_chip_init(codec); + if (err < 0) { snd_printk(KERN_ERR "ali create: chip init error.\n"); return err; } #ifdef CONFIG_PM codec->image = kmalloc(sizeof(*codec->image), GFP_KERNEL); - if (! codec->image) + if (!codec->image) snd_printk(KERN_WARNING "can't allocate apm buffer\n"); #endif @@ -2348,26 +2320,23 @@ static int __devinit snd_ali_probe(struct pci_dev *pci, snd_ali_printk("probe ...\n"); card = snd_card_new(index, id, THIS_MODULE, 0); - if (card == NULL) + if (!card) return -ENOMEM; - if ((err = snd_ali_create(card, pci, pcm_channels, spdif, &codec)) < 0) { - snd_card_free(card); - return err; - } + err = snd_ali_create(card, pci, pcm_channels, spdif, &codec); + if (err < 0) + goto error; card->private_data = codec; snd_ali_printk("mixer building ...\n"); - if ((err = snd_ali_mixer(codec)) < 0) { - snd_card_free(card); - return err; - } + err = snd_ali_mixer(codec); + if (err < 0) + goto error; snd_ali_printk("pcm building ...\n"); - if ((err = snd_ali_build_pcms(codec)) < 0) { - snd_card_free(card); - return err; - } + err = snd_ali_build_pcms(codec); + if (err < 0) + goto error; snd_ali_proc_init(codec); @@ -2378,12 +2347,16 @@ static int __devinit snd_ali_probe(struct pci_dev *pci, card->shortname, codec->port, codec->irq); snd_ali_printk("register card.\n"); - if ((err = snd_card_register(card)) < 0) { - snd_card_free(card); - return err; - } + err = snd_card_register(card); + if (err < 0) + goto error; + pci_set_drvdata(pci, card); return 0; + + error: + snd_card_free(card); + return err; } static void __devexit snd_ali_remove(struct pci_dev *pci) diff --git a/sound/pci/au88x0/au88x0_sb.h b/sound/pci/au88x0/au88x0_sb.h deleted file mode 100644 index 5a4d8fc2bbfc..000000000000 --- a/sound/pci/au88x0/au88x0_sb.h +++ /dev/null @@ -1,40 +0,0 @@ -/*************************************************************************** - * au88x0_sb.h - * - * Wed Oct 29 22:10:42 2003 - * - ****************************************************************************/ - -#ifdef CHIP_AU8820 -/* AU8820 starting @ 64KiB offset */ -#define SBEMU_BASE 0x10000 -#else -/* AU8810? and AU8830 starting @ 164KiB offset */ -#define SBEMU_BASE 0x29000 -#endif - -#define FM_A_STATUS (SBEMU_BASE + 0x00) /* read */ -#define FM_A_ADDRESS (SBEMU_BASE + 0x00) /* write */ -#define FM_A_DATA (SBEMU_BASE + 0x04) -#define FM_B_STATUS (SBEMU_BASE + 0x08) -#define FM_B_ADDRESS (SBEMU_BASE + 0x08) -#define FM_B_DATA (SBEMU_BASE + 0x0C) -#define SB_MIXER_ADDR (SBEMU_BASE + 0x10) -#define SB_MIXER_DATA (SBEMU_BASE + 0x14) -#define SB_RESET (SBEMU_BASE + 0x18) -#define SB_RESET_ALIAS (SBEMU_BASE + 0x1C) -#define FM_STATUS2 (SBEMU_BASE + 0x20) -#define FM_ADDR2 (SBEMU_BASE + 0x20) -#define FM_DATA2 (SBEMU_BASE + 0x24) -#define SB_DSP_READ (SBEMU_BASE + 0x28) -#define SB_DSP_WRITE (SBEMU_BASE + 0x30) -#define SB_DSP_WRITE_STATUS (SBEMU_BASE + 0x30) /* bit 7 */ -#define SB_DSP_READ_STATUS (SBEMU_BASE + 0x38) /* bit 7 */ -#define SB_LACR (SBEMU_BASE + 0x40) /* ? */ -#define SB_LADCR (SBEMU_BASE + 0x44) /* ? */ -#define SB_LAMR (SBEMU_BASE + 0x48) /* ? */ -#define SB_LARR (SBEMU_BASE + 0x4C) /* ? */ -#define SB_VERSION (SBEMU_BASE + 0x50) -#define SB_CTRLSTAT (SBEMU_BASE + 0x54) -#define SB_TIMERSTAT (SBEMU_BASE + 0x58) -#define FM_RAM (SBEMU_BASE + 0x100) /* 0x40 ULONG */ diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c index 43edd2839b5a..36d3666a5b77 100644 --- a/sound/pci/azt3328.c +++ b/sound/pci/azt3328.c @@ -1,6 +1,6 @@ /* * azt3328.c - driver for Aztech AZF3328 based soundcards (e.g. PCI168). - * Copyright (C) 2002, 2005 by Andreas Mohr <andi AT lisas.de> + * Copyright (C) 2002, 2005, 2006, 2007 by Andreas Mohr <andi AT lisas.de> * * Framework borrowed from Bart Hartgers's als4000.c. * Driver developed on PCI168 AP(W) version (PCI rev. 10, subsystem ID 1801), @@ -52,6 +52,9 @@ * - full duplex 16bit playback/record at independent sampling rate * - MPU401 (+ legacy address support) FIXME: how to enable legacy addr?? * - game port (legacy address support) + * - builtin 3D enhancement (said to be YAMAHA Ymersion) + * - builtin DirectInput support, helps reduce CPU overhead (interrupt-driven + * features supported) * - built-in General DirectX timer having a 20 bits counter * with 1us resolution (see below!) * - I2S serial port for external DAC @@ -94,6 +97,10 @@ * * BUGS * - full-duplex might *still* be problematic, not fully tested recently + * - (non-bug) "Bass/Treble or 3D settings don't work" - they do get evaluated + * if you set PCM output switch to "pre 3D" instead of "post 3D". + * If this can't be set, then get a mixer application that Isn't Stupid (tm) + * (e.g. kmix, gamix) - unfortunately several are!! * * TODO * - test MPU401 MIDI playback etc. @@ -622,7 +629,7 @@ snd_azf3328_put_mixer_enum(struct snd_kcontrol *kcontrol, return (nreg != oreg); } -static const struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata = { +static struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata = { AZF3328_MIXER_SWITCH("Master Playback Switch", IDX_MIXER_PLAY_MASTER, 15, 1), AZF3328_MIXER_VOL_STEREO("Master Playback Volume", IDX_MIXER_PLAY_MASTER, 0x1f, 1), AZF3328_MIXER_SWITCH("Wave Playback Switch", IDX_MIXER_WAVEOUT, 15, 1), @@ -652,7 +659,7 @@ static const struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata AZF3328_MIXER_VOL_MONO("Modem Capture Volume", IDX_MIXER_MODEMIN, 0x1f, 1), AZF3328_MIXER_ENUM("Mic Select", IDX_MIXER_ADVCTL2, 2, 8), AZF3328_MIXER_ENUM("Mono Output Select", IDX_MIXER_ADVCTL2, 2, 9), - AZF3328_MIXER_ENUM("PCM", IDX_MIXER_ADVCTL2, 2, 15), /* PCM Out Path, place in front since it controls *both* 3D and Bass/Treble! */ + AZF3328_MIXER_ENUM("PCM Output Route", IDX_MIXER_ADVCTL2, 2, 15), /* PCM Out Path, place in front since it controls *both* 3D and Bass/Treble! */ AZF3328_MIXER_VOL_SPECIAL("Tone Control - Treble", IDX_MIXER_BASSTREBLE, 0x07, 1, 0), AZF3328_MIXER_VOL_SPECIAL("Tone Control - Bass", IDX_MIXER_BASSTREBLE, 0x07, 9, 0), AZF3328_MIXER_SWITCH("3D Control - Switch", IDX_MIXER_ADVCTL2, 13, 0), @@ -678,7 +685,7 @@ static const struct snd_kcontrol_new snd_azf3328_mixer_controls[] __devinitdata #endif }; -static const u16 __devinitdata snd_azf3328_init_values[][2] = { +static u16 __devinitdata snd_azf3328_init_values[][2] = { { IDX_MIXER_PLAY_MASTER, MIXER_MUTE_MASK|0x1f1f }, { IDX_MIXER_MODEMOUT, MIXER_MUTE_MASK|0x1f1f }, { IDX_MIXER_BASSTREBLE, 0x0000 }, @@ -1369,7 +1376,6 @@ snd_azf3328_playback_close(struct snd_pcm_substream *substream) struct snd_azf3328 *chip = snd_pcm_substream_chip(substream); snd_azf3328_dbgcallenter(); - chip->playback_substream = NULL; snd_azf3328_dbgcallleave(); return 0; @@ -1660,10 +1666,10 @@ snd_azf3328_test_bit(unsigned int reg, int bit) } #endif +#if DEBUG_MISC static void snd_azf3328_debug_show_ports(const struct snd_azf3328 *chip) { -#if DEBUG_MISC u16 tmp; snd_azf3328_dbgmisc("codec_port 0x%lx, io2_port 0x%lx, mpu_port 0x%lx, synth_port 0x%lx, mixer_port 0x%lx, irq %d\n", chip->codec_port, chip->io2_port, chip->mpu_port, chip->synth_port, chip->mixer_port, chip->irq); @@ -1673,10 +1679,16 @@ snd_azf3328_debug_show_ports(const struct snd_azf3328 *chip) for (tmp=0; tmp <= 0x01; tmp += 1) snd_azf3328_dbgmisc("0x%02x: opl 0x%04x, mpu300 0x%04x, mpu310 0x%04x, mpu320 0x%04x, mpu330 0x%04x\n", tmp, inb(0x388 + tmp), inb(0x300 + tmp), inb(0x310 + tmp), inb(0x320 + tmp), inb(0x330 + tmp)); - for (tmp = 0; tmp <= 0x6E; tmp += 2) - snd_azf3328_dbgmisc("0x%02x: 0x%04x\n", tmp, snd_azf3328_codec_inb(chip, tmp)); -#endif + for (tmp = 0; tmp < AZF_IO_SIZE_CODEC; tmp += 2) + snd_azf3328_dbgmisc("codec 0x%02x: 0x%04x\n", tmp, snd_azf3328_codec_inw(chip, tmp)); + + for (tmp = 0; tmp < AZF_IO_SIZE_MIXER; tmp += 2) + snd_azf3328_dbgmisc("mixer 0x%02x: 0x%04x\n", tmp, snd_azf3328_mixer_inw(chip, tmp)); } +#else +static inline void +snd_azf3328_debug_show_ports(const struct snd_azf3328 *chip) {} +#endif static int __devinit snd_azf3328_create(struct snd_card *card, @@ -1842,8 +1854,8 @@ snd_azf3328_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) #ifdef MODULE printk( -"azt3328: Sound driver for Aztech AZF3328-based soundcards such as PCI168\n" -"azt3328: (hardware was completely undocumented - ZERO support from Aztech).\n" +"azt3328: Sound driver for Aztech AZF3328-based soundcards such as PCI168.\n" +"azt3328: Hardware was completely undocumented, unfortunately.\n" "azt3328: Feel free to contact andi AT lisas.de for bug reports etc.!\n" "azt3328: User-scalable sequencer timer set to %dHz (1024000Hz / %d).\n", 1024000 / seqtimer_scaling, seqtimer_scaling); diff --git a/sound/pci/azt3328.h b/sound/pci/azt3328.h index b4f3e3cd006b..679fa992e2bc 100644 --- a/sound/pci/azt3328.h +++ b/sound/pci/azt3328.h @@ -106,8 +106,8 @@ #define IRQ_RECORDING 0x0002 #define IRQ_MPU401 0x0010 #define IRQ_TIMER 0x0020 /* DirectX timer */ - #define IRQ_UNKNOWN1 0x0040 /* probably unused */ - #define IRQ_UNKNOWN2 0x0080 /* probably unused */ + #define IRQ_UNKNOWN1 0x0040 /* probably unused, or possibly I2S port? or gameport IRQ? */ + #define IRQ_UNKNOWN2 0x0080 /* probably unused, or possibly I2S port? or gameport IRQ? */ #define IDX_IO_66H 0x66 /* writing 0xffff returns 0x0000 */ #define IDX_IO_SOME_VALUE 0x68 /* this is set to e.g. 0x3ff or 0x300, and writable; maybe some buffer limit, but I couldn't find out more, PU:0x00ff */ #define IDX_IO_6AH 0x6A /* this WORD can be set to have bits 0x0028 activated (FIXME: correct??); actually inhibits PCM playback!!! maybe power management?? */ diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c index e9b029e1cd6d..6523ba07db96 100644 --- a/sound/pci/bt87x.c +++ b/sound/pci/bt87x.c @@ -781,6 +781,8 @@ static struct pci_device_id snd_bt87x_ids[] = { BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_879, 0x0070, 0x13eb, 32000), /* Viewcast Osprey 200 */ BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x0070, 0xff01, 44100), + /* ATI TV-Wonder */ + BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x1002, 0x0001, 32000), /* Leadtek Winfast tv 2000xp delux */ BT_DEVICE(PCI_DEVICE_ID_BROOKTREE_878, 0x107d, 0x6606, 32000), /* Voodoo TV 200 */ @@ -833,7 +835,7 @@ static int __devinit snd_bt87x_detect_card(struct pci_dev *pci) pci->device, pci->subsystem_vendor, pci->subsystem_device); snd_printk(KERN_DEBUG "please mail id, board name, and, " "if it works, the correct digital_rate option to " - "<alsa-devel@lists.sf.net>\n"); + "<alsa-devel@alsa-project.org>\n"); return 32000; /* default rate */ } diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c index ea6712b63c9f..48f3f17c5170 100644 --- a/sound/pci/ca0106/ca0106_main.c +++ b/sound/pci/ca0106/ca0106_main.c @@ -775,7 +775,6 @@ static int snd_ca0106_pcm_trigger_playback(struct snd_pcm_substream *substream, struct snd_ca0106_pcm *epcm; int channel; int result = 0; - struct list_head *pos; struct snd_pcm_substream *s; u32 basic = 0; u32 extended = 0; @@ -790,8 +789,7 @@ static int snd_ca0106_pcm_trigger_playback(struct snd_pcm_substream *substream, running=0; break; } - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { runtime = s->runtime; epcm = runtime->private_data; channel = epcm->channel_id; diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c index 2ae539b195fd..bef1f6d1859c 100644 --- a/sound/pci/cs46xx/cs46xx_lib.c +++ b/sound/pci/cs46xx/cs46xx_lib.c @@ -3107,7 +3107,7 @@ static int snd_cs46xx_chip_init(struct snd_cs46xx *chip) snd_printk(KERN_ERR "ERROR: snd-cs46xx: never read ISV3 & ISV4 from AC'97\n"); snd_printk(KERN_ERR " Try reloading the ALSA driver, if you find something\n"); snd_printk(KERN_ERR " broken or not working on your soundcard upon\n"); - snd_printk(KERN_ERR " this message please report to alsa-devel@lists.sourceforge.net\n"); + snd_printk(KERN_ERR " this message please report to alsa-devel@alsa-project.org\n"); return -EIO; #endif diff --git a/sound/pci/cs46xx/imgs/cwcemb80.h b/sound/pci/cs46xx/imgs/cwcemb80.h deleted file mode 100644 index a64c6ff9983a..000000000000 --- a/sound/pci/cs46xx/imgs/cwcemb80.h +++ /dev/null @@ -1,1607 +0,0 @@ -/* generated from cwcemb80.osp DO NOT MODIFY */ - -#ifndef __HEADER_cwcemb80_H__ -#define __HEADER_cwcemb80_H__ - -static struct dsp_symbol_entry cwcemb80_symbols[] = { - { 0x0000, "BEGINADDRESS",0x00 }, - { 0x8000, "EXECCHILD",0x03 }, - { 0x8001, "EXECCHILD_98",0x03 }, - { 0x8003, "EXECCHILD_PUSH1IND",0x03 }, - { 0x8008, "EXECSIBLING",0x03 }, - { 0x800a, "EXECSIBLING_298",0x03 }, - { 0x800b, "EXECSIBLING_2IND1",0x03 }, - { 0x8010, "TIMINGMASTER",0x03 }, - { 0x804f, "S16_CODECINPUTTASK",0x03 }, - { 0x805e, "PCMSERIALINPUTTASK",0x03 }, - { 0x806d, "S16_MIX_TO_OSTREAM",0x03 }, - { 0x809a, "S16_MIX",0x03 }, - { 0x80bb, "S16_UPSRC",0x03 }, - { 0x813b, "MIX3_EXP",0x03 }, - { 0x8164, "DECIMATEBYPOW2",0x03 }, - { 0x8197, "VARIDECIMATE",0x03 }, - { 0x81f2, "_3DINPUTTASK",0x03 }, - { 0x820a, "_3DPRLGCINPTASK",0x03 }, - { 0x8227, "_3DSTEREOINPUTTASK",0x03 }, - { 0x8242, "_3DOUTPUTTASK",0x03 }, - { 0x82c4, "HRTF_MORPH_TASK",0x03 }, - { 0x82c6, "WAIT4DATA",0x03 }, - { 0x82fa, "PROLOGIC",0x03 }, - { 0x8496, "DECORRELATOR",0x03 }, - { 0x84a4, "STEREO2MONO",0x03 }, - { 0x0070, "SPOSCB",0x02 }, - { 0x0105, "TASKTREETHREAD",0x03 }, - { 0x0136, "TASKTREEHEADERCODE",0x03 }, - { 0x013f, "FGTASKTREEHEADERCODE",0x03 }, - { 0x0163, "NULLALGORITHM",0x03 }, - { 0x0167, "HFGEXECCHILD",0x03 }, - { 0x0168, "HFGEXECCHILD_98",0x03 }, - { 0x016a, "HFGEXECCHILD_PUSH1IND",0x03 }, - { 0x016d, "HFGEXECSIBLING",0x03 }, - { 0x016f, "HFGEXECSIBLING_298",0x03 }, - { 0x0170, "HFGEXECSIBLING_2IND1",0x03 }, - { 0x0173, "S16_CODECOUTPUTTASK",0x03 }, - { 0x018e, "#CODE_END",0x00 }, -}; /* cwcemb80 symbols */ - -static u32 cwcemb80_code[] = { -/* BEGINADDRESS */ -/* 0000 */ 0x00040730,0x00001002,0x000f619e,0x00001003, -/* 0002 */ 0x00001705,0x00001400,0x000a411e,0x00001003, -/* 0004 */ 0x00040730,0x00001002,0x000f619e,0x00001003, -/* 0006 */ 0x00009705,0x00001400,0x000a411e,0x00001003, -/* 0008 */ 0x00040730,0x00001002,0x000f619e,0x00001003, -/* 000A */ 0x00011705,0x00001400,0x000a411e,0x00001003, -/* 000C */ 0x00040730,0x00001002,0x000f619e,0x00001003, -/* 000E */ 0x00019705,0x00001400,0x000a411e,0x00001003, -/* 0010 */ 0x00040730,0x00001002,0x000f619e,0x00001003, -/* 0012 */ 0x00021705,0x00001400,0x000a411e,0x00001003, -/* 0014 */ 0x00040730,0x00001002,0x000f619e,0x00001003, -/* 0016 */ 0x00029705,0x00001400,0x000a411e,0x00001003, -/* 0018 */ 0x00040730,0x00001002,0x000f619e,0x00001003, -/* 001A */ 0x00031705,0x00001400,0x000a411e,0x00001003, -/* 001C */ 0x00040730,0x00001002,0x000f619e,0x00001003, -/* 001E */ 0x00039705,0x00001400,0x000a411e,0x00001003, -/* 0020 */ 0x000fe19e,0x00001003,0x0009c730,0x00001003, -/* 0022 */ 0x0008e19c,0x00001003,0x000083c1,0x00093040, -/* 0024 */ 0x00098730,0x00001002,0x000ee19e,0x00001003, -/* 0026 */ 0x00009705,0x00001400,0x000a211e,0x00001003, -/* 0028 */ 0x00098730,0x00001002,0x000ee19e,0x00001003, -/* 002A */ 0x00011705,0x00001400,0x000a211e,0x00001003, -/* 002C */ 0x00098730,0x00001002,0x000ee19e,0x00001003, -/* 002E */ 0x00019705,0x00001400,0x000a211e,0x00001003, -/* 0030 */ 0x00098730,0x00001002,0x000ee19e,0x00001003, -/* 0032 */ 0x00021705,0x00001400,0x000a211e,0x00001003, -/* 0034 */ 0x00098730,0x00001002,0x000ee19e,0x00001003, -/* 0036 */ 0x00029705,0x00001400,0x000a211e,0x00001003, -/* 0038 */ 0x00098730,0x00001002,0x000ee19e,0x00001003, -/* 003A */ 0x00031705,0x00001400,0x000a211e,0x00001003, -/* 003C */ 0x00098730,0x00001002,0x000ee19e,0x00001003, -/* 003E */ 0x00039705,0x00001400,0x000a211e,0x00001003, -/* 0040 */ 0x0000a730,0x00001008,0x000e2730,0x00001002, -/* 0042 */ 0x0000a731,0x00001002,0x0000a731,0x00001002, -/* 0044 */ 0x0000a731,0x00001002,0x0000a731,0x00001002, -/* 0046 */ 0x0000a731,0x00001002,0x0000a731,0x00001002, -/* 0048 */ 0x00000000,0x00000000,0x000f619c,0x00001003, -/* 004A */ 0x0007f801,0x000c0000,0x00000037,0x00001000, -/* 004C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 004E */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0050 */ 0x00000000,0x000c0000,0x00000000,0x00000000, -/* 0052 */ 0x0000373c,0x00001000,0x00000000,0x00000000, -/* 0054 */ 0x000ee19c,0x00001003,0x0007f801,0x000c0000, -/* 0056 */ 0x00000037,0x00001000,0x00000000,0x00000000, -/* 0058 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 005A */ 0x00000000,0x00000000,0x0000273c,0x00001000, -/* 005C */ 0x00000033,0x00001000,0x000e679e,0x00001003, -/* 005E */ 0x00007705,0x00001400,0x000ac71e,0x00001003, -/* 0060 */ 0x00087fc1,0x000c3be0,0x0007f801,0x000c0000, -/* 0062 */ 0x00000037,0x00001000,0x00000000,0x00000000, -/* 0064 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0066 */ 0x00000000,0x00000000,0x0000a730,0x00001003, -/* 0068 */ 0x00000033,0x00001000,0x0007f801,0x000c0000, -/* 006A */ 0x00000037,0x00001000,0x00000000,0x00000000, -/* 006C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 006E */ 0x00000000,0x00000000,0x00000000,0x000c0000, -/* 0070 */ 0x00000032,0x00001000,0x0000273d,0x00001000, -/* 0072 */ 0x0004a730,0x00001003,0x00000f41,0x00097140, -/* 0074 */ 0x0000a841,0x0009b240,0x0000a0c1,0x0009f040, -/* 0076 */ 0x0001c641,0x00093540,0x0001cec1,0x0009b5c0, -/* 0078 */ 0x00000000,0x00000000,0x0001bf05,0x0003fc40, -/* 007A */ 0x00002725,0x000aa400,0x00013705,0x00093a00, -/* 007C */ 0x0000002e,0x0009d6c0,0x00038630,0x00001004, -/* 007E */ 0x0004ef0a,0x000eb785,0x0003fc8a,0x00000000, -/* 0080 */ 0x00000000,0x000c70e0,0x0007d182,0x0002c640, -/* 0082 */ 0x00000630,0x00001004,0x000799b8,0x0002c6c0, -/* 0084 */ 0x00031705,0x00092240,0x00039f05,0x000932c0, -/* 0086 */ 0x0003520a,0x00000000,0x00040731,0x0000100b, -/* 0088 */ 0x00010705,0x000b20c0,0x00000000,0x000eba44, -/* 008A */ 0x00032108,0x000c60c4,0x00065208,0x000c2917, -/* 008C */ 0x000406b0,0x00001007,0x00012f05,0x00036880, -/* 008E */ 0x0002818e,0x000c0000,0x0004410a,0x00000000, -/* 0090 */ 0x00040630,0x00001007,0x00029705,0x000c0000, -/* 0092 */ 0x00000000,0x00000000,0x00003fc1,0x0003fc40, -/* 0094 */ 0x000037c1,0x00091b40,0x00003fc1,0x000911c0, -/* 0096 */ 0x000037c1,0x000957c0,0x00003fc1,0x000951c0, -/* 0098 */ 0x000037c1,0x00000000,0x00003fc1,0x000991c0, -/* 009A */ 0x000037c1,0x00000000,0x00003fc1,0x0009d1c0, -/* 009C */ 0x000037c1,0x00000000,0x0001ccc1,0x000915c0, -/* 009E */ 0x0001c441,0x0009d800,0x0009cdc1,0x00091240, -/* 00A0 */ 0x0001c541,0x00091d00,0x0009cfc1,0x00095240, -/* 00A2 */ 0x0001c741,0x00095c80,0x000e8ca9,0x00099240, -/* 00A4 */ 0x000e85ad,0x00095640,0x00069ca9,0x00099d80, -/* 00A6 */ 0x000e952d,0x00099640,0x000eaca9,0x0009d6c0, -/* 00A8 */ 0x000ea5ad,0x00091a40,0x0006bca9,0x0009de80, -/* 00AA */ 0x000eb52d,0x00095a40,0x000ecca9,0x00099ac0, -/* 00AC */ 0x000ec5ad,0x0009da40,0x000edca9,0x0009d300, -/* 00AE */ 0x000a6e0a,0x00001000,0x000ed52d,0x00091e40, -/* 00B0 */ 0x000eeca9,0x00095ec0,0x000ee5ad,0x00099e40, -/* 00B2 */ 0x0006fca9,0x00002500,0x000fb208,0x000c59a0, -/* 00B4 */ 0x000ef52d,0x0009de40,0x00068ca9,0x000912c1, -/* 00B6 */ 0x000683ad,0x00095241,0x00020f05,0x000991c1, -/* 00B8 */ 0x00000000,0x00000000,0x00086f88,0x00001000, -/* 00BA */ 0x0009cf81,0x000b5340,0x0009c701,0x000b92c0, -/* 00BC */ 0x0009de81,0x000bd300,0x0009d601,0x000b1700, -/* 00BE */ 0x0001fd81,0x000b9d80,0x0009f501,0x000b57c0, -/* 00C0 */ 0x000a0f81,0x000bd740,0x00020701,0x000b5c80, -/* 00C2 */ 0x000a1681,0x000b97c0,0x00021601,0x00002500, -/* 00C4 */ 0x000a0701,0x000b9b40,0x000a0f81,0x000b1bc0, -/* 00C6 */ 0x00021681,0x00002d00,0x00020f81,0x000bd800, -/* 00C8 */ 0x000a0701,0x000b5bc0,0x00021601,0x00003500, -/* 00CA */ 0x000a0f81,0x000b5f40,0x000a0701,0x000bdbc0, -/* 00CC */ 0x00021681,0x00003d00,0x00020f81,0x000b1d00, -/* 00CE */ 0x000a0701,0x000b1fc0,0x00021601,0x00020500, -/* 00D0 */ 0x00020f81,0x000b1341,0x000a0701,0x000b9fc0, -/* 00D2 */ 0x00021681,0x00020d00,0x00020f81,0x000bde80, -/* 00D4 */ 0x000a0701,0x000bdfc0,0x00021601,0x00021500, -/* 00D6 */ 0x00020f81,0x000b9341,0x00020701,0x000b53c1, -/* 00D8 */ 0x00021681,0x00021d00,0x000a0f81,0x000d0380, -/* 00DA */ 0x0000b601,0x000b15c0,0x00007b01,0x00000000, -/* 00DC */ 0x00007b81,0x000bd1c0,0x00007b01,0x00000000, -/* 00DE */ 0x00007b81,0x000b91c0,0x00007b01,0x000b57c0, -/* 00E0 */ 0x00007b81,0x000b51c0,0x00007b01,0x000b1b40, -/* 00E2 */ 0x00007b81,0x000b11c0,0x00087b01,0x000c3dc0, -/* 00E4 */ 0x0007e488,0x000d7e45,0x00000000,0x000d7a44, -/* 00E6 */ 0x0007e48a,0x00000000,0x00011f05,0x00084080, -/* 00E8 */ 0x00000000,0x00000000,0x00001705,0x000b3540, -/* 00EA */ 0x00008a01,0x000bf040,0x00007081,0x000bb5c0, -/* 00EC */ 0x00055488,0x00000000,0x0000d482,0x0003fc40, -/* 00EE */ 0x0003fc88,0x00000000,0x0001e401,0x000b3a00, -/* 00F0 */ 0x0001ec81,0x000bd6c0,0x0004ef08,0x000eb784, -/* 00F2 */ 0x000c86b0,0x00001007,0x00008281,0x000bb240, -/* 00F4 */ 0x0000b801,0x000b7140,0x00007888,0x00000000, -/* 00F6 */ 0x0000073c,0x00001000,0x0007f188,0x000c0000, -/* 00F8 */ 0x00000000,0x00000000,0x00055288,0x000c555c, -/* 00FA */ 0x0005528a,0x000c0000,0x0009fa88,0x000c5d00, -/* 00FC */ 0x0000fa88,0x00000000,0x00000032,0x00001000, -/* 00FE */ 0x0000073d,0x00001000,0x0007f188,0x000c0000, -/* 0100 */ 0x00000000,0x00000000,0x0008c01c,0x00001003, -/* 0102 */ 0x00002705,0x00001008,0x0008b201,0x000c1392, -/* 0104 */ 0x0000ba01,0x00000000, -/* TASKTREETHREAD */ -/* 0105 */ 0x00008731,0x00001400,0x0004c108,0x000fe0c4, -/* 0107 */ 0x00057488,0x00000000,0x000a6388,0x00001001, -/* 0109 */ 0x0008b334,0x000bc141,0x0003020e,0x00000000, -/* 010B */ 0x000886b0,0x00001008,0x00003625,0x000c5dfa, -/* 010D */ 0x000a638a,0x00001001,0x0008020e,0x00001002, -/* 010F */ 0x0008a6b0,0x00001008,0x0007f301,0x00000000, -/* 0111 */ 0x00000000,0x00000000,0x00002725,0x000a8c40, -/* 0113 */ 0x000000ae,0x00000000,0x000d8630,0x00001008, -/* 0115 */ 0x00000000,0x000c74e0,0x0007d182,0x0002d640, -/* 0117 */ 0x000a8630,0x00001008,0x000799b8,0x0002d6c0, -/* 0119 */ 0x0000748a,0x000c3ec5,0x0007420a,0x000c0000, -/* 011B */ 0x00062208,0x000c4117,0x00070630,0x00001009, -/* 011D */ 0x00000000,0x000c0000,0x0001022e,0x00000000, -/* 011F */ 0x0003a630,0x00001009,0x00000000,0x000c0000, -/* 0121 */ 0x00000036,0x00001000,0x00000000,0x00000000, -/* 0123 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0125 */ 0x00000000,0x00000000,0x0002a730,0x00001008, -/* 0127 */ 0x0007f801,0x000c0000,0x00000037,0x00001000, -/* 0129 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 012B */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 012D */ 0x0002a730,0x00001008,0x00000033,0x00001000, -/* 012F */ 0x0002a705,0x00001008,0x00007a01,0x000c0000, -/* 0131 */ 0x000e6288,0x000d550a,0x0006428a,0x00000000, -/* 0133 */ 0x00060730,0x0000100a,0x00000000,0x000c0000, -/* 0135 */ 0x00000000,0x00000000, -/* TASKTREEHEADERCODE */ -/* 0136 */ 0x0007aab0,0x00034880,0x00078fb0,0x0000100b, -/* 0138 */ 0x00057488,0x00000000,0x00033b94,0x00081140, -/* 013A */ 0x000183ae,0x00000000,0x000786b0,0x0000100b, -/* 013C */ 0x00022f05,0x000c3545,0x0000eb8a,0x00000000, -/* 013E */ 0x00042731,0x00001003, -/* FGTASKTREEHEADERCODE */ -/* 013F */ 0x0007aab0,0x00034880,0x00048fb0,0x0000100a, -/* 0141 */ 0x00057488,0x00000000,0x00033b94,0x00081140, -/* 0143 */ 0x000183ae,0x00000000,0x000806b0,0x0000100b, -/* 0145 */ 0x00022f05,0x00000000,0x00007401,0x00091140, -/* 0147 */ 0x00048f05,0x000951c0,0x00042731,0x00001003, -/* 0149 */ 0x0000473d,0x00001000,0x000f19b0,0x000bbc47, -/* 014B */ 0x00080000,0x000bffc7,0x000fe19e,0x00001003, -/* 014D */ 0x00000000,0x00000000,0x0008e19c,0x00001003, -/* 014F */ 0x000083c1,0x00093040,0x00000f41,0x00097140, -/* 0151 */ 0x0000a841,0x0009b240,0x0000a0c1,0x0009f040, -/* 0153 */ 0x0001c641,0x00093540,0x0001cec1,0x0009b5c0, -/* 0155 */ 0x00000000,0x000fdc44,0x00055208,0x00000000, -/* 0157 */ 0x00010705,0x000a2880,0x0000a23a,0x00093a00, -/* 0159 */ 0x0003fc8a,0x000df6c5,0x0004ef0a,0x000c0000, -/* 015B */ 0x00012f05,0x00036880,0x00065308,0x000c2997, -/* 015D */ 0x000d86b0,0x0000100a,0x0004410a,0x000d40c7, -/* 015F */ 0x00000000,0x00000000,0x00080730,0x00001004, -/* 0161 */ 0x00056f0a,0x000ea105,0x00000000,0x00000000, -/* NULLALGORITHM */ -/* 0163 */ 0x0000473d,0x00001000,0x000f19b0,0x000bbc47, -/* 0165 */ 0x00080000,0x000bffc7,0x0000273d,0x00001000, -/* HFGEXECCHILD */ -/* 0167 */ 0x00000000,0x000eba44, -/* HFGEXECCHILD_98 */ -/* 0168 */ 0x00048f05,0x0000f440,0x00007401,0x0000f7c0, -/* HFGEXECCHILD_PUSH1IND */ -/* 016A */ 0x00000734,0x00001000,0x00010705,0x000a6880, -/* 016C */ 0x00006a88,0x000c75c4, -/* HFGEXECSIBLING */ -/* 016D */ 0x00000000,0x000e5084,0x00000000,0x000eba44, -/* HFGEXECSIBLING_298 */ -/* 016F */ 0x00087401,0x000e4782, -/* HFGEXECSIBLING_2IND1 */ -/* 0170 */ 0x00000734,0x00001000,0x00010705,0x000a6880, -/* 0172 */ 0x00006a88,0x000c75c4, -/* S16_CODECOUTPUTTASK */ -/* 0173 */ 0x0007c108,0x000c0000,0x0007e721,0x000bed40, -/* 0175 */ 0x00005f25,0x000badc0,0x0003ba97,0x000beb80, -/* 0177 */ 0x00065590,0x000b2e00,0x00033217,0x00003ec0, -/* 0179 */ 0x00065590,0x000b8e40,0x0003ed80,0x000491c0, -/* 017B */ 0x00073fb0,0x00074c80,0x000283a0,0x0000100c, -/* 017D */ 0x000ee388,0x00042970,0x00008301,0x00021ef2, -/* 017F */ 0x000b8f14,0x0000000f,0x000c4d8d,0x0000001b, -/* 0181 */ 0x000d6dc2,0x000e06c6,0x000032ac,0x000c3916, -/* 0183 */ 0x0004edc2,0x00074c80,0x00078898,0x00001000, -/* 0185 */ 0x00038894,0x00000032,0x000c4d8d,0x00092e1b, -/* 0187 */ 0x000d6dc2,0x000e06c6,0x0004edc2,0x000c1956, -/* 0189 */ 0x0000722c,0x00034a00,0x00041705,0x0009ed40, -/* 018B */ 0x00058730,0x00001400,0x000d7488,0x000c3a00, -/* 018D */ 0x00048f05,0x00000000 -}; -/* #CODE_END */ - -static u32 cwcemb80_parameter[] = { -/* 0000 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0004 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0008 */ 0x00000000,0x00000000,0x00000163,0x00000000, -/* 000C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0010 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0014 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0018 */ 0x00000000,0x00200040,0x00008010,0x00000000, -/* 001C */ 0x00000000,0x80000001,0x00000001,0x00060000, -/* 0020 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0024 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0028 */ 0x00000000,0x00900080,0x00000173,0x00000000, -/* 002C */ 0x00000000,0x00000010,0x00800000,0x00900000, -/* 0030 */ 0xf2c0000f,0x00000200,0x00000000,0x00010600, -/* 0034 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0038 */ 0x00000000,0x00000000,0x00000163,0x330300c2, -/* 003C */ 0x06000000,0x00000000,0x80008000,0x80008000, -/* 0040 */ 0x3fc0000f,0x00000301,0x00010400,0x00000000, -/* 0044 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0048 */ 0x00000000,0x00b00000,0x00d0806d,0x330480c3, -/* 004C */ 0x04800000,0x00000001,0x00800001,0x0000ffff, -/* 0050 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0054 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0058 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 005C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0060 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0064 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0068 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 006C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0070 */ 0x066a0600,0x06350070,0x0000929d,0x929d929d, -/* 0074 */ 0x00000000,0x0000735a,0x00000600,0x00000000, -/* 0078 */ 0x929d735a,0x00000000,0x00010000,0x735a735a, -/* 007C */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -/* 0080 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0084 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0088 */ 0x00000000,0x00000000,0x0000804f,0x000000c3, -/* 008C */ 0x05000000,0x00a00010,0x00000000,0x80008000, -/* 0090 */ 0x00000000,0x00000000,0x00000700,0x00000000, -/* 0094 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0098 */ 0x00000080,0x00a00000,0x0000809a,0x000000c2, -/* 009C */ 0x07400000,0x00000000,0x80008000,0xffffffff, -/* 00A0 */ 0x00c80028,0x00005555,0x00000000,0x000107a0, -/* 00A4 */ 0x00c80028,0x000000c2,0x06800000,0x00000000, -/* 00A8 */ 0x06e00080,0x00300000,0x000080bb,0x000000c9, -/* 00AC */ 0x07a00000,0x04000000,0x80008000,0xffffffff, -/* 00B0 */ 0x00c80028,0x00005555,0x00000000,0x00000780, -/* 00B4 */ 0x00c80028,0x000000c5,0xff800000,0x00000000, -/* 00B8 */ 0x00640080,0x00c00000,0x00008197,0x000000c9, -/* 00BC */ 0x07800000,0x04000000,0x80008000,0xffffffff, -/* 00C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00C8 */ 0x00000000,0x00000000,0x0000805e,0x000000c1, -/* 00CC */ 0x00000000,0x00800000,0x80008000,0x80008000, -/* 00D0 */ 0x00020000,0x0000ffff,0x00000000,0x00000000, -/* 00D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0100 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0104 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0108 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 010C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0110 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0114 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0118 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 011C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0120 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0124 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0128 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 012C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0130 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0134 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0138 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 013C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0140 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0144 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0148 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 014C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0150 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0154 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0158 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 015C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0160 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0164 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0168 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 016C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0170 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0174 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0178 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 017C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0180 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0184 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0188 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 018C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0190 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0194 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0198 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 019C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01AC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01BC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01CC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0200 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0204 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0208 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 020C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0210 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0214 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0218 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 021C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0220 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0224 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0228 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 022C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0230 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0234 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0238 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 023C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0240 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0244 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0248 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 024C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0250 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0254 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0258 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 025C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0260 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0264 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0268 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 026C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0270 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0274 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0278 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 027C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0280 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0284 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0288 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 028C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0290 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0294 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0298 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 029C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02AC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02BC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02CC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0300 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0304 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0308 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 030C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0310 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0314 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0318 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 031C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0320 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0324 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0328 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 032C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0330 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0334 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0338 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 033C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0340 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0344 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0348 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 034C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0350 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0354 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0358 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 035C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0360 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0364 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0368 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 036C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0370 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0374 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0378 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 037C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0380 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0384 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0388 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 038C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0390 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0394 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0398 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 039C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03AC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03BC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03CC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0400 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0404 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0408 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 040C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0410 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0414 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0418 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 041C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0420 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0424 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0428 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 042C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0430 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0434 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0438 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 043C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0440 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0444 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0448 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 044C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0450 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0454 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0458 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 045C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0460 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0464 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0468 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 046C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0470 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0474 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0478 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 047C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0480 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0484 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0488 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 048C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0490 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0494 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0498 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 049C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04AC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04BC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04CC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0500 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0504 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0508 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 050C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0510 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0514 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0518 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 051C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0520 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0524 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0528 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 052C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0530 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0534 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0538 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 053C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0540 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0544 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0548 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 054C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0550 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0554 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0558 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 055C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0560 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0564 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0568 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 056C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0570 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0574 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0578 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 057C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0580 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0584 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0588 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 058C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0590 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0594 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0598 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 059C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05AC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05BC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05CC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0600 */ 0x929d0600,0x929d929d,0x929d929d,0x929d0000, -/* 0604 */ 0x929d929d,0x929d929d,0x929d929d,0x929d929d, -/* 0608 */ 0x929d929d,0x00100635,0x060b013f,0x00000004, -/* 060C */ 0x00000001,0x007a0002,0x00000000,0x066e0610, -/* 0610 */ 0x0105929d,0x929d929d,0x929d929d,0x929d929d, -/* 0614 */ 0x929d929d,0xa431ac75,0x0001735a,0xa431ac75, -/* 0618 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -/* 061C */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -/* 0620 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -/* 0624 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -/* 0628 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -/* 062C */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -/* 0630 */ 0xa431ac75,0xa431ac75,0xa431ac75,0x735a0051, -/* 0634 */ 0x00000000,0x929d929d,0x929d929d,0x929d929d, -/* 0638 */ 0x929d929d,0x929d929d,0x929d929d,0x929d929d, -/* 063C */ 0x929d929d,0x929d929d,0x00000000,0x06400136, -/* 0640 */ 0x0000270f,0x00010000,0x007a0000,0x00000000, -/* 0644 */ 0x068e0645,0x0105929d,0x929d929d,0x929d929d, -/* 0648 */ 0x929d929d,0x929d929d,0xa431ac75,0x0001735a, -/* 064C */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -/* 0650 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -/* 0654 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -/* 0658 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -/* 065C */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -/* 0660 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -/* 0664 */ 0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75, -/* 0668 */ 0x735a0100,0x00000000,0x00000000,0x00000000, -/* 066C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0670 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0674 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0678 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 067C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0680 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0684 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0688 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 068C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0690 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0694 */ 0x00000000,0x00000000,0x00000000 -}; /* #PARAMETER_END */ - -static u32 cwcemb80_sample[] = { -/* 0000 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0004 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0008 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 000C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0010 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0014 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0018 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 001C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0020 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0024 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0028 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 002C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0030 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0034 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0038 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 003C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0040 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0044 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0048 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 004C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0050 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0054 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0058 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 005C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0060 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0064 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0068 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 006C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0070 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0074 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0078 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 007C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0080 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0084 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0088 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 008C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0090 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0094 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0098 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 009C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00AC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00BC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00CC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 00FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0100 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0104 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0108 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 010C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0110 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0114 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0118 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 011C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0120 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0124 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0128 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 012C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0130 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0134 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0138 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 013C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0140 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0144 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0148 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 014C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0150 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0154 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0158 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 015C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0160 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0164 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0168 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 016C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0170 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0174 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0178 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 017C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0180 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0184 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0188 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 018C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0190 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0194 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0198 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 019C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01AC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01BC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01CC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 01FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0200 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0204 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0208 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 020C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0210 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0214 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0218 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 021C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0220 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0224 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0228 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 022C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0230 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0234 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0238 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 023C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0240 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0244 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0248 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 024C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0250 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0254 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0258 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 025C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0260 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0264 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0268 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 026C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0270 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0274 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0278 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 027C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0280 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0284 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0288 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 028C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0290 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0294 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0298 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 029C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02AC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02BC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02CC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 02FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0300 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0304 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0308 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 030C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0310 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0314 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0318 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 031C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0320 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0324 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0328 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 032C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0330 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0334 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0338 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 033C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0340 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0344 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0348 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 034C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0350 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0354 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0358 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 035C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0360 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0364 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0368 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 036C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0370 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0374 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0378 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 037C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0380 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0384 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0388 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 038C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0390 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0394 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0398 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 039C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03AC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03BC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03CC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 03FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0400 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0404 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0408 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 040C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0410 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0414 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0418 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 041C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0420 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0424 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0428 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 042C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0430 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0434 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0438 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 043C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0440 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0444 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0448 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 044C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0450 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0454 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0458 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 045C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0460 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0464 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0468 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 046C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0470 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0474 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0478 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 047C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0480 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0484 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0488 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 048C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0490 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0494 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0498 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 049C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04AC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04BC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04CC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 04FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0500 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0504 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0508 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 050C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0510 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0514 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0518 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 051C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0520 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0524 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0528 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 052C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0530 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0534 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0538 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 053C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0540 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0544 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0548 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 054C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0550 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0554 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0558 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 055C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0560 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0564 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0568 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 056C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0570 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0574 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0578 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 057C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0580 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0584 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0588 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 058C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0590 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0594 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0598 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 059C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05AC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05BC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05CC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 05FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0600 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0604 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0608 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 060C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0610 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0614 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0618 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 061C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0620 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0624 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0628 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 062C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0630 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0634 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0638 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 063C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0640 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0644 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0648 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 064C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0650 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0654 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0658 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 065C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0660 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0664 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0668 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 066C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0670 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0674 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0678 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 067C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0680 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0684 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0688 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 068C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0690 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0694 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0698 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 069C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06AC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06BC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06CC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 06FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0700 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0704 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0708 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 070C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0710 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0714 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0718 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 071C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0720 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0724 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0728 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 072C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0730 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0734 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0738 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 073C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0740 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0744 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0748 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 074C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0750 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0754 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0758 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 075C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0760 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0764 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0768 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 076C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0770 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0774 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0778 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 077C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0780 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0784 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0788 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 078C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0790 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0794 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0798 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 079C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07AC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07BC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07CC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 07FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0800 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0804 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0808 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 080C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0810 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0814 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0818 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 081C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0820 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0824 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0828 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 082C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0830 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0834 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0838 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 083C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0840 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0844 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0848 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 084C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0850 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0854 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0858 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 085C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0860 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0864 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0868 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 086C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0870 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0874 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0878 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 087C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0880 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0884 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0888 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 088C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0890 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0894 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0898 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 089C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08AC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08BC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08CC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 08FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0900 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0904 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0908 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 090C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0910 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0914 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0918 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 091C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0920 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0924 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0928 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 092C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0930 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0934 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0938 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 093C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0940 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0944 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0948 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 094C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0950 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0954 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0958 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 095C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0960 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0964 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0968 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 096C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0970 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0974 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0978 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 097C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0980 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0984 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0988 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 098C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0990 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0994 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0998 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 099C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09A0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09A4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09A8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09AC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09B0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09B4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09B8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09BC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09C0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09C4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09C8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09CC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09D0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09D4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09D8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09DC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09E0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09E4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09E8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09EC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09F0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09F4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09F8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 09FC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A00 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A04 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A08 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A0C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A10 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A14 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A18 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A1C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A20 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A24 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A28 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A2C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A30 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A34 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A38 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A3C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A40 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A44 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A48 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A4C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A50 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A54 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A58 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A5C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A60 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A64 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A68 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A6C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A70 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A74 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A78 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A7C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A80 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A84 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A88 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A8C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A90 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A94 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A98 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0A9C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AA0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AA4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AA8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AAC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AB0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AB4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AB8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0ABC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AC0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AC4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AC8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0ACC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AD0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AD4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AD8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0ADC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AE0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AE4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AE8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AEC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AF0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AF4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AF8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0AFC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B00 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B04 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B08 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B0C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B10 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B14 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B18 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B1C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B20 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B24 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B28 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B2C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B30 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B34 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B38 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B3C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B40 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B44 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B48 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B4C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B50 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B54 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B58 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B5C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B60 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B64 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B68 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B6C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B70 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B74 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B78 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B7C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B80 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B84 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B88 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B8C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B90 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B94 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B98 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0B9C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BA0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BA4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BA8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BAC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BB0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BB4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BB8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BBC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BC0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BC4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BC8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BCC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BD0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BD4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BD8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BDC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BE0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BE4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BE8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BEC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BF0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BF4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BF8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0BFC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C00 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C04 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C08 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C0C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C10 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C14 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C18 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C1C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C20 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C24 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C28 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C2C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C30 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C34 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C38 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C3C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C40 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C44 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C48 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C4C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C50 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C54 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C58 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C5C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C60 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C64 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C68 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C6C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C70 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C74 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C78 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C7C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C80 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C84 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C88 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C8C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C90 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C94 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C98 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0C9C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CA0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CA4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CA8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CAC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CB0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CB4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CB8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CBC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CC0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CC4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CC8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CCC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CD0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CD4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CD8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CDC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CE0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CE4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CE8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CEC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CF0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CF4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CF8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0CFC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D00 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D04 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D08 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D0C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D10 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D14 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D18 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D1C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D20 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D24 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D28 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D2C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D30 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D34 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D38 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D3C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D40 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D44 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D48 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D4C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D50 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D54 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D58 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D5C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D60 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D64 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D68 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D6C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D70 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D74 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D78 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D7C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D80 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D84 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D88 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D8C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D90 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D94 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D98 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0D9C */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DA0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DA4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DA8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DAC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DB0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DB4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DB8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DBC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DC0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DC4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DC8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DCC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DD0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DD4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DD8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DDC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DE0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DE4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DE8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DEC */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DF0 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DF4 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DF8 */ 0x00000000,0x00000000,0x00000000,0x00000000, -/* 0DFC */ 0x00000000,0x00000000,0x00000000,0x00010004 -}; /* #SAMPLE_END */ - - -static struct dsp_segment_desc cwcemb80_segments[] = { - { SEGTYPE_SP_PROGRAM, 0x00000000, 0x0000031c, cwcemb80_code }, - { SEGTYPE_SP_PARAMETER, 0x00000000, 0x00000697, cwcemb80_parameter }, - { SEGTYPE_SP_SAMPLE, 0x00000000, 0x00000e00, cwcemb80_sample }, -}; - -static struct dsp_module_desc cwcemb80_module = { - "cwcemb80", - { - 38, - cwcemb80_symbols - }, - 3, - cwcemb80_segments, -}; - -#endif /* __HEADER_cwcemb80_H__ */ diff --git a/sound/pci/echoaudio/darla20.c b/sound/pci/echoaudio/darla20.c index 8e7fe033270f..87078d3a6854 100644 --- a/sound/pci/echoaudio/darla20.c +++ b/sound/pci/echoaudio/darla20.c @@ -56,6 +56,8 @@ #include <asm/atomic.h> #include "echoaudio.h" +MODULE_FIRMWARE("ea/darla20_dsp.fw"); + #define FW_DARLA20_DSP 0 static const struct firmware card_fw[] = { diff --git a/sound/pci/echoaudio/darla24.c b/sound/pci/echoaudio/darla24.c index a13c623eb999..42b48f9d2128 100644 --- a/sound/pci/echoaudio/darla24.c +++ b/sound/pci/echoaudio/darla24.c @@ -60,6 +60,8 @@ #include <asm/atomic.h> #include "echoaudio.h" +MODULE_FIRMWARE("ea/darla24_dsp.fw"); + #define FW_DARLA24_DSP 0 static const struct firmware card_fw[] = { diff --git a/sound/pci/echoaudio/echo3g.c b/sound/pci/echoaudio/echo3g.c index 8fb15823aca5..8dbb7ac865c1 100644 --- a/sound/pci/echoaudio/echo3g.c +++ b/sound/pci/echoaudio/echo3g.c @@ -68,6 +68,10 @@ #include <asm/atomic.h> #include "echoaudio.h" +MODULE_FIRMWARE("ea/loader_dsp.fw"); +MODULE_FIRMWARE("ea/echo3g_dsp.fw"); +MODULE_FIRMWARE("ea/3g_asic.fw"); + #define FW_361_LOADER 0 #define FW_ECHO3G_DSP 1 #define FW_3G_ASIC 2 diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c index e413da00759b..f27b6a733b96 100644 --- a/sound/pci/echoaudio/echoaudio.c +++ b/sound/pci/echoaudio/echoaudio.c @@ -705,11 +705,9 @@ static int pcm_trigger(struct snd_pcm_substream *substream, int cmd) struct audiopipe *pipe = runtime->private_data; int i, err; u32 channelmask = 0; - struct list_head *pos; struct snd_pcm_substream *s; - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { for (i = 0; i < DSP_MAXPIPES; i++) { if (s == chip->substream[i]) { channelmask |= 1 << i; diff --git a/sound/pci/echoaudio/echoaudio_3g.c b/sound/pci/echoaudio/echoaudio_3g.c index 9f439ea459f4..52a933189576 100644 --- a/sound/pci/echoaudio/echoaudio_3g.c +++ b/sound/pci/echoaudio/echoaudio_3g.c @@ -233,8 +233,8 @@ static int load_asic(struct echoaudio *chip) chip->asic_code = &card_fw[FW_3G_ASIC]; - /* Now give the new ASIC a little time to set up */ - mdelay(2); + /* Now give the new ASIC some time to set up */ + msleep(1000); /* See if it worked */ box_type = check_asic_status(chip); diff --git a/sound/pci/echoaudio/gina20.c b/sound/pci/echoaudio/gina20.c index af4d32026e4a..fee2d4831732 100644 --- a/sound/pci/echoaudio/gina20.c +++ b/sound/pci/echoaudio/gina20.c @@ -60,6 +60,8 @@ #include <asm/atomic.h> #include "echoaudio.h" +MODULE_FIRMWARE("ea/gina20_dsp.fw"); + #define FW_GINA20_DSP 0 static const struct firmware card_fw[] = { diff --git a/sound/pci/echoaudio/gina24.c b/sound/pci/echoaudio/gina24.c index 9ff454a947ed..d5eae470fe9a 100644 --- a/sound/pci/echoaudio/gina24.c +++ b/sound/pci/echoaudio/gina24.c @@ -66,6 +66,12 @@ #include <asm/atomic.h> #include "echoaudio.h" +MODULE_FIRMWARE("ea/loader_dsp.fw"); +MODULE_FIRMWARE("ea/gina24_301_dsp.fw"); +MODULE_FIRMWARE("ea/gina24_361_dsp.fw"); +MODULE_FIRMWARE("ea/gina24_301_asic.fw"); +MODULE_FIRMWARE("ea/gina24_361_asic.fw"); + #define FW_361_LOADER 0 #define FW_GINA24_301_DSP 1 #define FW_GINA24_361_DSP 2 diff --git a/sound/pci/echoaudio/indigo.c b/sound/pci/echoaudio/indigo.c index 37eb726fd03d..40f601cd016f 100644 --- a/sound/pci/echoaudio/indigo.c +++ b/sound/pci/echoaudio/indigo.c @@ -58,6 +58,9 @@ #include <asm/atomic.h> #include "echoaudio.h" +MODULE_FIRMWARE("ea/loader_dsp.fw"); +MODULE_FIRMWARE("ea/indigo_dsp.fw"); + #define FW_361_LOADER 0 #define FW_INDIGO_DSP 1 diff --git a/sound/pci/echoaudio/indigodj.c b/sound/pci/echoaudio/indigodj.c index dc8b91824181..771c5383210d 100644 --- a/sound/pci/echoaudio/indigodj.c +++ b/sound/pci/echoaudio/indigodj.c @@ -58,6 +58,9 @@ #include <asm/atomic.h> #include "echoaudio.h" +MODULE_FIRMWARE("ea/loader_dsp.fw"); +MODULE_FIRMWARE("ea/indigo_dj_dsp.fw"); + #define FW_361_LOADER 0 #define FW_INDIGO_DJ_DSP 1 diff --git a/sound/pci/echoaudio/indigoio.c b/sound/pci/echoaudio/indigoio.c index eadf3263453a..49c550defcf9 100644 --- a/sound/pci/echoaudio/indigoio.c +++ b/sound/pci/echoaudio/indigoio.c @@ -59,6 +59,9 @@ #include <asm/atomic.h> #include "echoaudio.h" +MODULE_FIRMWARE("ea/loader_dsp.fw"); +MODULE_FIRMWARE("ea/indigo_io_dsp.fw"); + #define FW_361_LOADER 0 #define FW_INDIGO_IO_DSP 1 diff --git a/sound/pci/echoaudio/layla20.c b/sound/pci/echoaudio/layla20.c index 6cede497579e..8f5483a405ae 100644 --- a/sound/pci/echoaudio/layla20.c +++ b/sound/pci/echoaudio/layla20.c @@ -66,6 +66,9 @@ #include <asm/atomic.h> #include "echoaudio.h" +MODULE_FIRMWARE("ea/layla20_dsp.fw"); +MODULE_FIRMWARE("ea/layla20_asic.fw"); + #define FW_LAYLA20_DSP 0 #define FW_LAYLA20_ASIC 1 diff --git a/sound/pci/echoaudio/layla24.c b/sound/pci/echoaudio/layla24.c index 44f735426aa0..0524667c02f7 100644 --- a/sound/pci/echoaudio/layla24.c +++ b/sound/pci/echoaudio/layla24.c @@ -68,6 +68,12 @@ #include <asm/atomic.h> #include "echoaudio.h" +MODULE_FIRMWARE("ea/loader_dsp.fw"); +MODULE_FIRMWARE("ea/layla24_dsp.fw"); +MODULE_FIRMWARE("ea/layla24_1_asic.fw"); +MODULE_FIRMWARE("ea/layla24_2A_asic.fw"); +MODULE_FIRMWARE("ea/layla24_2S_asic.fw"); + #define FW_361_LOADER 0 #define FW_LAYLA24_DSP 1 #define FW_LAYLA24_1_ASIC 2 diff --git a/sound/pci/echoaudio/mia.c b/sound/pci/echoaudio/mia.c index dc172d03ac3f..893c7c20dd70 100644 --- a/sound/pci/echoaudio/mia.c +++ b/sound/pci/echoaudio/mia.c @@ -66,6 +66,9 @@ #include <asm/atomic.h> #include "echoaudio.h" +MODULE_FIRMWARE("ea/loader_dsp.fw"); +MODULE_FIRMWARE("ea/mia_dsp.fw"); + #define FW_361_LOADER 0 #define FW_MIA_DSP 1 diff --git a/sound/pci/echoaudio/mona.c b/sound/pci/echoaudio/mona.c index c856ed50dd9a..3a5d5b0020df 100644 --- a/sound/pci/echoaudio/mona.c +++ b/sound/pci/echoaudio/mona.c @@ -64,6 +64,15 @@ #include <asm/atomic.h> #include "echoaudio.h" +MODULE_FIRMWARE("ea/loader_dsp.fw"); +MODULE_FIRMWARE("ea/mona_301_dsp.fw"); +MODULE_FIRMWARE("ea/mona_361_dsp.fw"); +MODULE_FIRMWARE("ea/mona_301_1_asic_48.fw"); +MODULE_FIRMWARE("ea/mona_301_1_asic_96.fw"); +MODULE_FIRMWARE("ea/mona_361_1_asic_48.fw"); +MODULE_FIRMWARE("ea/mona_361_1_asic_96.fw"); +MODULE_FIRMWARE("ea/mona_2_asic.fw"); + #define FW_361_LOADER 0 #define FW_MONA_301_DSP 1 #define FW_MONA_361_DSP 2 diff --git a/sound/pci/emu10k1/emu10k1_main.c b/sound/pci/emu10k1/emu10k1_main.c index 80aa585eade4..dbc805c33fc4 100644 --- a/sound/pci/emu10k1/emu10k1_main.c +++ b/sound/pci/emu10k1/emu10k1_main.c @@ -49,6 +49,13 @@ #include "p17v.h" +#define HANA_FILENAME "emu/hana.fw" +#define DOCK_FILENAME "emu/audio_dock.fw" + +MODULE_FIRMWARE(HANA_FILENAME); +MODULE_FIRMWARE(DOCK_FILENAME); + + /************************************************************************* * EMU10K1 init / done *************************************************************************/ @@ -693,8 +700,6 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu) int tmp,tmp2; int reg; int err; - const char *hana_filename = "emu/hana.fw"; - const char *dock_filename = "emu/audio_dock.fw"; snd_printk(KERN_INFO "emu1010: Special config.\n"); /* AC97 2.1, Any 16Meg of 4Gig address, Auto-Mute, EMU32 Slave, @@ -735,8 +740,8 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu) return -ENODEV; } snd_printk(KERN_INFO "emu1010: EMU_HANA_ID=0x%x\n",reg); - if ((err = snd_emu1010_load_firmware(emu, hana_filename)) != 0) { - snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file %s failed\n", hana_filename); + if ((err = snd_emu1010_load_firmware(emu, HANA_FILENAME)) != 0) { + snd_printk(KERN_INFO "emu1010: Loading Hana Firmware file %s failed\n", HANA_FILENAME); return err; } @@ -938,7 +943,7 @@ static int snd_emu10k1_emu1010_init(struct snd_emu10k1 * emu) /* Return to Audio Dock programming mode */ snd_printk(KERN_INFO "emu1010: Loading Audio Dock Firmware\n"); snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, EMU_HANA_FPGA_CONFIG_AUDIODOCK ); - if ((err = snd_emu1010_load_firmware(emu, dock_filename)) != 0) { + if ((err = snd_emu1010_load_firmware(emu, DOCK_FILENAME)) != 0) { return err; } snd_emu1010_fpga_write(emu, EMU_HANA_FPGA_CONFIG, 0 ); @@ -1216,6 +1221,15 @@ static struct snd_emu_chip_details emu_chip_details[] = { .spi_dac = 1, .i2c_adc = 1, .spk71 = 1} , + {.vendor = 0x1102, .device = 0x0008, .subsystem = 0x42011102, + .driver = "Audigy2", .name = "E-mu 1010 Notebook [MAEM8950]", + .id = "EMU1010", + .emu10k2_chip = 1, + .ca0108_chip = 1, + .ca_cardbus_chip = 1, + .spi_dac = 1, + .i2c_adc = 1, + .spk71 = 1} , {.vendor = 0x1102, .device = 0x0008, .driver = "Audigy2", .name = "Audigy 2 Value [Unknown]", .id = "Audigy2", diff --git a/sound/pci/emu10k1/p16v.c b/sound/pci/emu10k1/p16v.c index 465f8d505329..7ee19c63c2c8 100644 --- a/sound/pci/emu10k1/p16v.c +++ b/sound/pci/emu10k1/p16v.c @@ -433,7 +433,6 @@ static int snd_p16v_pcm_trigger_playback(struct snd_pcm_substream *substream, struct snd_emu10k1_pcm *epcm; int channel; int result = 0; - struct list_head *pos; struct snd_pcm_substream *s; u32 basic = 0; u32 inte = 0; @@ -448,8 +447,7 @@ static int snd_p16v_pcm_trigger_playback(struct snd_pcm_substream *substream, running = 0; break; } - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { runtime = s->runtime; epcm = runtime->private_data; channel = substream->pcm->device-emu->p16v_device_offset; diff --git a/sound/pci/ens1370.c b/sound/pci/ens1370.c index 425b167522d5..6a0ddcf00884 100644 --- a/sound/pci/ens1370.c +++ b/sound/pci/ens1370.c @@ -798,10 +798,8 @@ static int snd_ensoniq_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: { unsigned int what = 0; - struct list_head *pos; struct snd_pcm_substream *s; - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if (s == ensoniq->playback1_substream) { what |= ES_P1_PAUSE; snd_pcm_trigger_done(s, substream); @@ -824,10 +822,8 @@ static int snd_ensoniq_trigger(struct snd_pcm_substream *substream, int cmd) case SNDRV_PCM_TRIGGER_STOP: { unsigned int what = 0; - struct list_head *pos; struct snd_pcm_substream *s; - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if (s == ensoniq->playback1_substream) { what |= ES_DAC1_EN; snd_pcm_trigger_done(s, substream); diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c index dc84c189b05f..2faf009076bb 100644 --- a/sound/pci/es1968.c +++ b/sound/pci/es1968.c @@ -1554,10 +1554,7 @@ static int snd_es1968_playback_open(struct snd_pcm_substream *substream) runtime->hw = snd_es1968_playback; runtime->hw.buffer_bytes_max = runtime->hw.period_bytes_max = calc_available_memory_size(chip); -#if 0 - snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, - 1024); -#endif + spin_lock_irq(&chip->substream_lock); list_add(&es->list, &chip->substream_list); spin_unlock_irq(&chip->substream_lock); @@ -1613,10 +1610,8 @@ static int snd_es1968_capture_open(struct snd_pcm_substream *substream) runtime->hw = snd_es1968_capture; runtime->hw.buffer_bytes_max = runtime->hw.period_bytes_max = calc_available_memory_size(chip) - 1024; /* keep MIXBUF size */ -#if 0 - snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES, - 1024); -#endif + snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES); + spin_lock_irq(&chip->substream_lock); list_add(&es->list, &chip->substream_list); spin_unlock_irq(&chip->substream_lock); diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile index 60d7b05a204a..b2484bbdcc1d 100644 --- a/sound/pci/hda/Makefile +++ b/sound/pci/hda/Makefile @@ -1,5 +1,8 @@ snd-hda-intel-objs := hda_intel.o -snd-hda-codec-objs := hda_codec.o \ +# since snd-hda-intel is the only driver using hda-codec, +# merge it into a single module although it was originally +# designed to be individual modules +snd-hda-intel-objs += hda_codec.o \ hda_generic.o \ patch_realtek.o \ patch_cmedia.o \ @@ -10,7 +13,7 @@ snd-hda-codec-objs := hda_codec.o \ patch_conexant.o \ patch_via.o ifdef CONFIG_PROC_FS -snd-hda-codec-objs += hda_proc.o +snd-hda-intel-objs += hda_proc.o endif -obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o snd-hda-codec.o +obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 8f34fb447983..14649d54b493 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -24,7 +24,6 @@ #include <linux/delay.h> #include <linux/slab.h> #include <linux/pci.h> -#include <linux/moduleparam.h> #include <linux/mutex.h> #include <sound/core.h> #include "hda_codec.h" @@ -34,11 +33,6 @@ #include "hda_local.h" -MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>"); -MODULE_DESCRIPTION("Universal interface for High Definition Audio Codec"); -MODULE_LICENSE("GPL"); - - /* * vendor / preset table */ @@ -77,12 +71,13 @@ static struct hda_vendor_id hda_vendor_ids[] = { * * Returns the obtained response value, or -1 for an error. */ -unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, int direct, +unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, + int direct, unsigned int verb, unsigned int parm) { unsigned int res; mutex_lock(&codec->bus->cmd_mutex); - if (! codec->bus->ops.command(codec, nid, direct, verb, parm)) + if (!codec->bus->ops.command(codec, nid, direct, verb, parm)) res = codec->bus->ops.get_response(codec); else res = (unsigned int)-1; @@ -90,8 +85,6 @@ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, int dire return res; } -EXPORT_SYMBOL(snd_hda_codec_read); - /** * snd_hda_codec_write - send a single command without waiting for response * @codec: the HDA codec @@ -114,8 +107,6 @@ int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct, return err; } -EXPORT_SYMBOL(snd_hda_codec_write); - /** * snd_hda_sequence_write - sequence writes * @codec: the HDA codec @@ -130,8 +121,6 @@ void snd_hda_sequence_write(struct hda_codec *codec, const struct hda_verb *seq) snd_hda_codec_write(codec, seq->nid, 0, seq->verb, seq->param); } -EXPORT_SYMBOL(snd_hda_sequence_write); - /** * snd_hda_get_sub_nodes - get the range of sub nodes * @codec: the HDA codec @@ -141,7 +130,8 @@ EXPORT_SYMBOL(snd_hda_sequence_write); * Parse the NID and store the start NID of its sub-nodes. * Returns the number of sub-nodes. */ -int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid, hda_nid_t *start_id) +int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid, + hda_nid_t *start_id) { unsigned int parm; @@ -150,8 +140,6 @@ int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid, hda_nid_t *sta return (int)(parm & 0x7fff); } -EXPORT_SYMBOL(snd_hda_get_sub_nodes); - /** * snd_hda_get_connections - get connection list * @codec: the HDA codec @@ -187,12 +175,13 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, conn_len = parm & AC_CLIST_LENGTH; mask = (1 << (shift-1)) - 1; - if (! conn_len) + if (!conn_len) return 0; /* no connection */ if (conn_len == 1) { /* single connection */ - parm = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_LIST, 0); + parm = snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_CONNECT_LIST, 0); conn_list[0] = parm & mask; return 1; } @@ -207,18 +196,21 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, if (i % num_elems == 0) parm = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONNECT_LIST, i); - range_val = !! (parm & (1 << (shift-1))); /* ranges */ + range_val = !!(parm & (1 << (shift-1))); /* ranges */ val = parm & mask; parm >>= shift; if (range_val) { /* ranges between the previous and this one */ - if (! prev_nid || prev_nid >= val) { - snd_printk(KERN_WARNING "hda_codec: invalid dep_range_val %x:%x\n", prev_nid, val); + if (!prev_nid || prev_nid >= val) { + snd_printk(KERN_WARNING "hda_codec: " + "invalid dep_range_val %x:%x\n", + prev_nid, val); continue; } for (n = prev_nid + 1; n <= val; n++) { if (conns >= max_conns) { - snd_printk(KERN_ERR "Too many connections\n"); + snd_printk(KERN_ERR + "Too many connections\n"); return -EINVAL; } conn_list[conns++] = n; @@ -253,7 +245,8 @@ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex) struct hda_bus_unsolicited *unsol; unsigned int wp; - if ((unsol = bus->unsol) == NULL) + unsol = bus->unsol; + if (!unsol) return 0; wp = (unsol->wp + 1) % HDA_UNSOL_QUEUE_SIZE; @@ -268,8 +261,6 @@ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex) return 0; } -EXPORT_SYMBOL(snd_hda_queue_unsol_event); - /* * process queueud unsolicited events */ @@ -287,7 +278,7 @@ static void process_unsol_events(struct work_struct *work) rp <<= 1; res = unsol->queue[rp]; caddr = unsol->queue[rp + 1]; - if (! (caddr & (1 << 4))) /* no unsolicited event? */ + if (!(caddr & (1 << 4))) /* no unsolicited event? */ continue; codec = bus->caddr_tbl[caddr & 0x0f]; if (codec && codec->patch_ops.unsol_event) @@ -298,7 +289,7 @@ static void process_unsol_events(struct work_struct *work) /* * initialize unsolicited queue */ -static int init_unsol_queue(struct hda_bus *bus) +static int __devinit init_unsol_queue(struct hda_bus *bus) { struct hda_bus_unsolicited *unsol; @@ -306,8 +297,9 @@ static int init_unsol_queue(struct hda_bus *bus) return 0; unsol = kzalloc(sizeof(*unsol), GFP_KERNEL); - if (! unsol) { - snd_printk(KERN_ERR "hda_codec: can't allocate unsolicited queue\n"); + if (!unsol) { + snd_printk(KERN_ERR "hda_codec: " + "can't allocate unsolicited queue\n"); return -ENOMEM; } INIT_WORK(&unsol->work, process_unsol_events); @@ -323,16 +315,15 @@ static void snd_hda_codec_free(struct hda_codec *codec); static int snd_hda_bus_free(struct hda_bus *bus) { - struct list_head *p, *n; + struct hda_codec *codec, *n; - if (! bus) + if (!bus) return 0; if (bus->unsol) { flush_scheduled_work(); kfree(bus->unsol); } - list_for_each_safe(p, n, &bus->codec_list) { - struct hda_codec *codec = list_entry(p, struct hda_codec, list); + list_for_each_entry_safe(codec, n, &bus->codec_list, list) { snd_hda_codec_free(codec); } if (bus->ops.private_free) @@ -355,8 +346,9 @@ static int snd_hda_bus_dev_free(struct snd_device *device) * * Returns 0 if successful, or a negative error code. */ -int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp, - struct hda_bus **busp) +int __devinit snd_hda_bus_new(struct snd_card *card, + const struct hda_bus_template *temp, + struct hda_bus **busp) { struct hda_bus *bus; int err; @@ -385,7 +377,8 @@ int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp, mutex_init(&bus->cmd_mutex); INIT_LIST_HEAD(&bus->codec_list); - if ((err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops)) < 0) { + err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops); + if (err < 0) { snd_hda_bus_free(bus); return err; } @@ -394,22 +387,24 @@ int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp, return 0; } -EXPORT_SYMBOL(snd_hda_bus_new); - /* * find a matching codec preset */ -static const struct hda_codec_preset *find_codec_preset(struct hda_codec *codec) +static const struct hda_codec_preset __devinit * +find_codec_preset(struct hda_codec *codec) { const struct hda_codec_preset **tbl, *preset; + if (codec->bus->modelname && !strcmp(codec->bus->modelname, "generic")) + return NULL; /* use the generic parser */ + for (tbl = hda_preset_tables; *tbl; tbl++) { for (preset = *tbl; preset->id; preset++) { u32 mask = preset->mask; - if (! mask) + if (!mask) mask = ~0; if (preset->id == (codec->vendor_id & mask) && - (! preset->rev || + (!preset->rev || preset->rev == codec->revision_id)) return preset; } @@ -434,27 +429,30 @@ void snd_hda_get_codec_name(struct hda_codec *codec, break; } } - if (! vendor) { + if (!vendor) { sprintf(tmp, "Generic %04x", vendor_id); vendor = tmp; } if (codec->preset && codec->preset->name) snprintf(name, namelen, "%s %s", vendor, codec->preset->name); else - snprintf(name, namelen, "%s ID %x", vendor, codec->vendor_id & 0xffff); + snprintf(name, namelen, "%s ID %x", vendor, + codec->vendor_id & 0xffff); } /* * look for an AFG and MFG nodes */ -static void setup_fg_nodes(struct hda_codec *codec) +static void __devinit setup_fg_nodes(struct hda_codec *codec) { int i, total_nodes; hda_nid_t nid; total_nodes = snd_hda_get_sub_nodes(codec, AC_NODE_ROOT, &nid); for (i = 0; i < total_nodes; i++, nid++) { - switch((snd_hda_param_read(codec, nid, AC_PAR_FUNCTION_TYPE) & 0xff)) { + unsigned int func; + func = snd_hda_param_read(codec, nid, AC_PAR_FUNCTION_TYPE); + switch (func & 0xff) { case AC_GRP_AUDIO_FUNCTION: codec->afg = nid; break; @@ -478,7 +476,7 @@ static int read_widget_caps(struct hda_codec *codec, hda_nid_t fg_node) codec->num_nodes = snd_hda_get_sub_nodes(codec, fg_node, &codec->start_nid); codec->wcaps = kmalloc(codec->num_nodes * 4, GFP_KERNEL); - if (! codec->wcaps) + if (!codec->wcaps) return -ENOMEM; nid = codec->start_nid; for (i = 0; i < codec->num_nodes; i++, nid++) @@ -493,7 +491,7 @@ static int read_widget_caps(struct hda_codec *codec, hda_nid_t fg_node) */ static void snd_hda_codec_free(struct hda_codec *codec) { - if (! codec) + if (!codec) return; list_del(&codec->list); codec->bus->caddr_tbl[codec->addr] = NULL; @@ -514,8 +512,8 @@ static void init_amp_hash(struct hda_codec *codec); * * Returns 0 if successful, or a negative error code. */ -int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, - struct hda_codec **codecp) +int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, + struct hda_codec **codecp) { struct hda_codec *codec; char component[13]; @@ -525,7 +523,8 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, snd_assert(codec_addr <= HDA_MAX_CODEC_ADDRESS, return -EINVAL); if (bus->caddr_tbl[codec_addr]) { - snd_printk(KERN_ERR "hda_codec: address 0x%x is already occupied\n", codec_addr); + snd_printk(KERN_ERR "hda_codec: " + "address 0x%x is already occupied\n", codec_addr); return -EBUSY; } @@ -543,18 +542,21 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, list_add_tail(&codec->list, &bus->codec_list); bus->caddr_tbl[codec_addr] = codec; - codec->vendor_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_VENDOR_ID); + codec->vendor_id = snd_hda_param_read(codec, AC_NODE_ROOT, + AC_PAR_VENDOR_ID); if (codec->vendor_id == -1) /* read again, hopefully the access method was corrected * in the last read... */ codec->vendor_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_VENDOR_ID); - codec->subsystem_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_SUBSYSTEM_ID); - codec->revision_id = snd_hda_param_read(codec, AC_NODE_ROOT, AC_PAR_REV_ID); + codec->subsystem_id = snd_hda_param_read(codec, AC_NODE_ROOT, + AC_PAR_SUBSYSTEM_ID); + codec->revision_id = snd_hda_param_read(codec, AC_NODE_ROOT, + AC_PAR_REV_ID); setup_fg_nodes(codec); - if (! codec->afg && ! codec->mfg) { + if (!codec->afg && !codec->mfg) { snd_printdd("hda_codec: no AFG or MFG node found\n"); snd_hda_codec_free(codec); return -ENODEV; @@ -566,15 +568,16 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, return -ENOMEM; } - if (! codec->subsystem_id) { + if (!codec->subsystem_id) { hda_nid_t nid = codec->afg ? codec->afg : codec->mfg; - codec->subsystem_id = snd_hda_codec_read(codec, nid, 0, - AC_VERB_GET_SUBSYSTEM_ID, - 0); + codec->subsystem_id = + snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_SUBSYSTEM_ID, 0); } codec->preset = find_codec_preset(codec); - if (! *bus->card->mixername) + /* audio codec should override the mixer name */ + if (codec->afg || !*bus->card->mixername) snd_hda_get_codec_name(codec, bus->card->mixername, sizeof(bus->card->mixername)); @@ -600,8 +603,6 @@ int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, return 0; } -EXPORT_SYMBOL(snd_hda_codec_new); - /** * snd_hda_codec_setup_stream - set up the codec for streaming * @codec: the CODEC to set up @@ -610,13 +611,15 @@ EXPORT_SYMBOL(snd_hda_codec_new); * @channel_id: channel id to pass, zero based. * @format: stream format. */ -void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, u32 stream_tag, +void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, + u32 stream_tag, int channel_id, int format) { - if (! nid) + if (!nid) return; - snd_printdd("hda_codec_setup_stream: NID=0x%x, stream=0x%x, channel=%d, format=0x%x\n", + snd_printdd("hda_codec_setup_stream: " + "NID=0x%x, stream=0x%x, channel=%d, format=0x%x\n", nid, stream_tag, channel_id, format); snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID, (stream_tag << 4) | channel_id); @@ -624,8 +627,6 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, u32 stre snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, format); } -EXPORT_SYMBOL(snd_hda_codec_setup_stream); - /* * amp access functions */ @@ -636,7 +637,7 @@ EXPORT_SYMBOL(snd_hda_codec_setup_stream); #define INFO_AMP_VOL(ch) (1 << (1 + (ch))) /* initialize the hash table */ -static void init_amp_hash(struct hda_codec *codec) +static void __devinit init_amp_hash(struct hda_codec *codec) { memset(codec->amp_hash, 0xff, sizeof(codec->amp_hash)); codec->num_amp_entries = 0; @@ -662,15 +663,18 @@ static struct hda_amp_info *get_alloc_amp_hash(struct hda_codec *codec, u32 key) if (codec->num_amp_entries >= codec->amp_info_size) { /* reallocate the array */ int new_size = codec->amp_info_size + 64; - struct hda_amp_info *new_info = kcalloc(new_size, sizeof(struct hda_amp_info), - GFP_KERNEL); - if (! new_info) { - snd_printk(KERN_ERR "hda_codec: can't malloc amp_info\n"); + struct hda_amp_info *new_info; + new_info = kcalloc(new_size, sizeof(struct hda_amp_info), + GFP_KERNEL); + if (!new_info) { + snd_printk(KERN_ERR "hda_codec: " + "can't malloc amp_info\n"); return NULL; } if (codec->amp_info) { memcpy(new_info, codec->amp_info, - codec->amp_info_size * sizeof(struct hda_amp_info)); + codec->amp_info_size * + sizeof(struct hda_amp_info)); kfree(codec->amp_info); } codec->amp_info_size = new_size; @@ -691,15 +695,18 @@ static struct hda_amp_info *get_alloc_amp_hash(struct hda_codec *codec, u32 key) */ static u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction) { - struct hda_amp_info *info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, 0)); + struct hda_amp_info *info; - if (! info) + info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, 0)); + if (!info) return 0; - if (! (info->status & INFO_AMP_CAPS)) { - if (! (get_wcaps(codec, nid) & AC_WCAP_AMP_OVRD)) + if (!(info->status & INFO_AMP_CAPS)) { + if (!(get_wcaps(codec, nid) & AC_WCAP_AMP_OVRD)) nid = codec->afg; - info->amp_caps = snd_hda_param_read(codec, nid, direction == HDA_OUTPUT ? - AC_PAR_AMP_OUT_CAP : AC_PAR_AMP_IN_CAP); + info->amp_caps = snd_hda_param_read(codec, nid, + direction == HDA_OUTPUT ? + AC_PAR_AMP_OUT_CAP : + AC_PAR_AMP_IN_CAP); info->status |= INFO_AMP_CAPS; } return info->amp_caps; @@ -709,8 +716,9 @@ static u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction) * read the current volume to info * if the cache exists, read the cache value. */ -static unsigned int get_vol_mute(struct hda_codec *codec, struct hda_amp_info *info, - hda_nid_t nid, int ch, int direction, int index) +static unsigned int get_vol_mute(struct hda_codec *codec, + struct hda_amp_info *info, hda_nid_t nid, + int ch, int direction, int index) { u32 val, parm; @@ -720,7 +728,8 @@ static unsigned int get_vol_mute(struct hda_codec *codec, struct hda_amp_info *i parm = ch ? AC_AMP_GET_RIGHT : AC_AMP_GET_LEFT; parm |= direction == HDA_OUTPUT ? AC_AMP_GET_OUTPUT : AC_AMP_GET_INPUT; parm |= index; - val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_AMP_GAIN_MUTE, parm); + val = snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_AMP_GAIN_MUTE, parm); info->vol[ch] = val & 0xff; info->status |= INFO_AMP_VOL(ch); return info->vol[ch]; @@ -730,7 +739,8 @@ static unsigned int get_vol_mute(struct hda_codec *codec, struct hda_amp_info *i * write the current volume in info to the h/w and update the cache */ static void put_vol_mute(struct hda_codec *codec, struct hda_amp_info *info, - hda_nid_t nid, int ch, int direction, int index, int val) + hda_nid_t nid, int ch, int direction, int index, + int val) { u32 parm; @@ -748,8 +758,9 @@ static void put_vol_mute(struct hda_codec *codec, struct hda_amp_info *info, int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch, int direction, int index) { - struct hda_amp_info *info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, index)); - if (! info) + struct hda_amp_info *info; + info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, index)); + if (!info) return 0; return get_vol_mute(codec, info, nid, ch, direction, index); } @@ -760,13 +771,14 @@ int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch, int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, int direction, int idx, int mask, int val) { - struct hda_amp_info *info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, idx)); + struct hda_amp_info *info; - if (! info) + info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, idx)); + if (!info) return 0; val &= mask; val |= get_vol_mute(codec, info, nid, ch, direction, idx) & ~mask; - if (info->vol[ch] == val && ! codec->in_resume) + if (info->vol[ch] == val && !codec->in_resume) return 0; put_vol_mute(codec, info, nid, ch, direction, idx, val); return 1; @@ -783,7 +795,8 @@ int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, #define get_amp_index(kc) (((kc)->private_value >> 19) & 0xf) /* volume */ -int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); u16 nid = get_amp_nid(kcontrol); @@ -792,9 +805,11 @@ int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_ u32 caps; caps = query_amp_caps(codec, nid, dir); - caps = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT; /* num steps */ - if (! caps) { - printk(KERN_WARNING "hda_codec: num_steps = 0 for NID=0x%x\n", nid); + /* num steps */ + caps = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT; + if (!caps) { + printk(KERN_WARNING "hda_codec: " + "num_steps = 0 for NID=0x%x\n", nid); return -EINVAL; } uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; @@ -804,7 +819,8 @@ int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_ return 0; } -int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); hda_nid_t nid = get_amp_nid(kcontrol); @@ -820,7 +836,8 @@ int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e return 0; } -int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); hda_nid_t nid = get_amp_nid(kcontrol); @@ -852,7 +869,8 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag, if (size < 4 * sizeof(unsigned int)) return -ENOMEM; caps = query_amp_caps(codec, nid, dir); - val2 = (((caps & AC_AMPCAP_STEP_SIZE) >> AC_AMPCAP_STEP_SIZE_SHIFT) + 1) * 25; + val2 = (caps & AC_AMPCAP_STEP_SIZE) >> AC_AMPCAP_STEP_SIZE_SHIFT; + val2 = (val2 + 1) * 25; val1 = -((caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT); val1 = ((int)val1) * ((int)val2); if (put_user(SNDRV_CTL_TLVT_DB_SCALE, _tlv)) @@ -867,7 +885,8 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag, } /* switch */ -int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) { int chs = get_amp_channels(kcontrol); @@ -878,7 +897,8 @@ int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_ return 0; } -int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); hda_nid_t nid = get_amp_nid(kcontrol); @@ -888,13 +908,16 @@ int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e long *valp = ucontrol->value.integer.value; if (chs & 1) - *valp++ = (snd_hda_codec_amp_read(codec, nid, 0, dir, idx) & 0x80) ? 0 : 1; + *valp++ = (snd_hda_codec_amp_read(codec, nid, 0, dir, idx) & + 0x80) ? 0 : 1; if (chs & 2) - *valp = (snd_hda_codec_amp_read(codec, nid, 1, dir, idx) & 0x80) ? 0 : 1; + *valp = (snd_hda_codec_amp_read(codec, nid, 1, dir, idx) & + 0x80) ? 0 : 1; return 0; } -int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); hda_nid_t nid = get_amp_nid(kcontrol); @@ -925,7 +948,8 @@ int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e #define AMP_VAL_IDX_SHIFT 19 #define AMP_VAL_IDX_MASK (0x0f<<19) -int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); unsigned long pval; @@ -940,7 +964,8 @@ int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_ return err; } -int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); unsigned long pval; @@ -950,7 +975,8 @@ int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ pval = kcontrol->private_value; indices = (pval & AMP_VAL_IDX_MASK) >> AMP_VAL_IDX_SHIFT; for (i = 0; i < indices; i++) { - kcontrol->private_value = (pval & ~AMP_VAL_IDX_MASK) | (i << AMP_VAL_IDX_SHIFT); + kcontrol->private_value = (pval & ~AMP_VAL_IDX_MASK) | + (i << AMP_VAL_IDX_SHIFT); err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); if (err < 0) break; @@ -965,14 +991,16 @@ int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ * SPDIF out controls */ -static int snd_hda_spdif_mask_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +static int snd_hda_spdif_mask_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958; uinfo->count = 1; return 0; } -static int snd_hda_spdif_cmask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_hda_spdif_cmask_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { ucontrol->value.iec958.status[0] = IEC958_AES0_PROFESSIONAL | IEC958_AES0_NONAUDIO | @@ -983,7 +1011,8 @@ static int snd_hda_spdif_cmask_get(struct snd_kcontrol *kcontrol, struct snd_ctl return 0; } -static int snd_hda_spdif_pmask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_hda_spdif_pmask_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { ucontrol->value.iec958.status[0] = IEC958_AES0_PROFESSIONAL | IEC958_AES0_NONAUDIO | @@ -991,7 +1020,8 @@ static int snd_hda_spdif_pmask_get(struct snd_kcontrol *kcontrol, struct snd_ctl return 0; } -static int snd_hda_spdif_default_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_hda_spdif_default_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); @@ -1011,19 +1041,21 @@ static unsigned short convert_from_spdif_status(unsigned int sbits) unsigned short val = 0; if (sbits & IEC958_AES0_PROFESSIONAL) - val |= 1 << 6; + val |= AC_DIG1_PROFESSIONAL; if (sbits & IEC958_AES0_NONAUDIO) - val |= 1 << 5; + val |= AC_DIG1_NONAUDIO; if (sbits & IEC958_AES0_PROFESSIONAL) { - if ((sbits & IEC958_AES0_PRO_EMPHASIS) == IEC958_AES0_PRO_EMPHASIS_5015) - val |= 1 << 3; + if ((sbits & IEC958_AES0_PRO_EMPHASIS) == + IEC958_AES0_PRO_EMPHASIS_5015) + val |= AC_DIG1_EMPHASIS; } else { - if ((sbits & IEC958_AES0_CON_EMPHASIS) == IEC958_AES0_CON_EMPHASIS_5015) - val |= 1 << 3; - if (! (sbits & IEC958_AES0_CON_NOT_COPYRIGHT)) - val |= 1 << 4; + if ((sbits & IEC958_AES0_CON_EMPHASIS) == + IEC958_AES0_CON_EMPHASIS_5015) + val |= AC_DIG1_EMPHASIS; + if (!(sbits & IEC958_AES0_CON_NOT_COPYRIGHT)) + val |= AC_DIG1_COPYRIGHT; if (sbits & (IEC958_AES1_CON_ORIGINAL << 8)) - val |= 1 << 7; + val |= AC_DIG1_LEVEL; val |= sbits & (IEC958_AES1_CON_CATEGORY << 8); } return val; @@ -1035,26 +1067,27 @@ static unsigned int convert_to_spdif_status(unsigned short val) { unsigned int sbits = 0; - if (val & (1 << 5)) + if (val & AC_DIG1_NONAUDIO) sbits |= IEC958_AES0_NONAUDIO; - if (val & (1 << 6)) + if (val & AC_DIG1_PROFESSIONAL) sbits |= IEC958_AES0_PROFESSIONAL; if (sbits & IEC958_AES0_PROFESSIONAL) { - if (sbits & (1 << 3)) + if (sbits & AC_DIG1_EMPHASIS) sbits |= IEC958_AES0_PRO_EMPHASIS_5015; } else { - if (val & (1 << 3)) + if (val & AC_DIG1_EMPHASIS) sbits |= IEC958_AES0_CON_EMPHASIS_5015; - if (! (val & (1 << 4))) + if (!(val & AC_DIG1_COPYRIGHT)) sbits |= IEC958_AES0_CON_NOT_COPYRIGHT; - if (val & (1 << 7)) + if (val & AC_DIG1_LEVEL) sbits |= (IEC958_AES1_CON_ORIGINAL << 8); sbits |= val & (0x7f << 8); } return sbits; } -static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); hda_nid_t nid = kcontrol->private_value; @@ -1072,15 +1105,18 @@ static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol, struct snd_c codec->spdif_ctls = val; if (change || codec->in_resume) { - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, val & 0xff); - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_2, val >> 8); + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, + val & 0xff); + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_2, + val >> 8); } mutex_unlock(&codec->spdif_mutex); return change; } -static int snd_hda_spdif_out_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +static int snd_hda_spdif_out_switch_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; uinfo->count = 1; @@ -1089,15 +1125,17 @@ static int snd_hda_spdif_out_switch_info(struct snd_kcontrol *kcontrol, struct s return 0; } -static int snd_hda_spdif_out_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_hda_spdif_out_switch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - ucontrol->value.integer.value[0] = codec->spdif_ctls & 1; + ucontrol->value.integer.value[0] = codec->spdif_ctls & AC_DIG1_ENABLE; return 0; } -static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); hda_nid_t nid = kcontrol->private_value; @@ -1105,16 +1143,21 @@ static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol, struct sn int change; mutex_lock(&codec->spdif_mutex); - val = codec->spdif_ctls & ~1; + val = codec->spdif_ctls & ~AC_DIG1_ENABLE; if (ucontrol->value.integer.value[0]) - val |= 1; + val |= AC_DIG1_ENABLE; change = codec->spdif_ctls != val; if (change || codec->in_resume) { codec->spdif_ctls = val; - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, val & 0xff); - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, - AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | - AC_AMP_SET_OUTPUT | ((val & 1) ? 0 : 0x80)); + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, + val & 0xff); + /* unmute amp switch (if any) */ + if ((get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) && + (val & AC_DIG1_ENABLE)) + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_AMP_GAIN_MUTE, + AC_AMP_SET_RIGHT | AC_AMP_SET_LEFT | + AC_AMP_SET_OUTPUT); } mutex_unlock(&codec->spdif_mutex); return change; @@ -1162,7 +1205,8 @@ static struct snd_kcontrol_new dig_mixes[] = { * * Returns 0 if successful, or a negative error code. */ -int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid) +int __devinit snd_hda_create_spdif_out_ctls(struct hda_codec *codec, + hda_nid_t nid) { int err; struct snd_kcontrol *kctl; @@ -1171,10 +1215,12 @@ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid) for (dig_mix = dig_mixes; dig_mix->name; dig_mix++) { kctl = snd_ctl_new1(dig_mix, codec); kctl->private_value = nid; - if ((err = snd_ctl_add(codec->bus->card, kctl)) < 0) + err = snd_ctl_add(codec->bus->card, kctl); + if (err < 0) return err; } - codec->spdif_ctls = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DIGI_CONVERT, 0); + codec->spdif_ctls = + snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DIGI_CONVERT, 0); codec->spdif_status = convert_to_spdif_status(codec->spdif_ctls); return 0; } @@ -1185,7 +1231,8 @@ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid) #define snd_hda_spdif_in_switch_info snd_hda_spdif_out_switch_info -static int snd_hda_spdif_in_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_hda_spdif_in_switch_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); @@ -1193,7 +1240,8 @@ static int snd_hda_spdif_in_switch_get(struct snd_kcontrol *kcontrol, struct snd return 0; } -static int snd_hda_spdif_in_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_hda_spdif_in_switch_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); hda_nid_t nid = kcontrol->private_value; @@ -1204,13 +1252,15 @@ static int snd_hda_spdif_in_switch_put(struct snd_kcontrol *kcontrol, struct snd change = codec->spdif_in_enable != val; if (change || codec->in_resume) { codec->spdif_in_enable = val; - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, val); + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, + val); } mutex_unlock(&codec->spdif_mutex); return change; } -static int snd_hda_spdif_in_status_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int snd_hda_spdif_in_status_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); hda_nid_t nid = kcontrol->private_value; @@ -1254,7 +1304,8 @@ static struct snd_kcontrol_new dig_in_ctls[] = { * * Returns 0 if successful, or a negative error code. */ -int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid) +int __devinit snd_hda_create_spdif_in_ctls(struct hda_codec *codec, + hda_nid_t nid) { int err; struct snd_kcontrol *kctl; @@ -1263,10 +1314,13 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid) for (dig_mix = dig_in_ctls; dig_mix->name; dig_mix++) { kctl = snd_ctl_new1(dig_mix, codec); kctl->private_value = nid; - if ((err = snd_ctl_add(codec->bus->card, kctl)) < 0) + err = snd_ctl_add(codec->bus->card, kctl); + if (err < 0) return err; } - codec->spdif_in_enable = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DIGI_CONVERT, 0) & 1; + codec->spdif_in_enable = + snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DIGI_CONVERT, 0) & + AC_DIG1_ENABLE; return 0; } @@ -1304,15 +1358,14 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, * * Returns 0 if successful, otherwise a negative error code. */ -int snd_hda_build_controls(struct hda_bus *bus) +int __devinit snd_hda_build_controls(struct hda_bus *bus) { - struct list_head *p; + struct hda_codec *codec; /* build controls */ - list_for_each(p, &bus->codec_list) { - struct hda_codec *codec = list_entry(p, struct hda_codec, list); + list_for_each_entry(codec, &bus->codec_list, list) { int err; - if (! codec->patch_ops.build_controls) + if (!codec->patch_ops.build_controls) continue; err = codec->patch_ops.build_controls(codec); if (err < 0) @@ -1320,13 +1373,12 @@ int snd_hda_build_controls(struct hda_bus *bus) } /* initialize */ - list_for_each(p, &bus->codec_list) { - struct hda_codec *codec = list_entry(p, struct hda_codec, list); + list_for_each_entry(codec, &bus->codec_list, list) { int err; hda_set_power_state(codec, codec->afg ? codec->afg : codec->mfg, AC_PWRST_D0); - if (! codec->patch_ops.init) + if (!codec->patch_ops.init) continue; err = codec->patch_ops.init(codec); if (err < 0) @@ -1335,8 +1387,6 @@ int snd_hda_build_controls(struct hda_bus *bus) return 0; } -EXPORT_SYMBOL(snd_hda_build_controls); - /* * stream formats */ @@ -1361,6 +1411,11 @@ static struct hda_rate_tbl rate_bits[] = { { 96000, SNDRV_PCM_RATE_96000, 0x0800 }, /* 2 x 48 */ { 176400, SNDRV_PCM_RATE_176400, 0x5800 },/* 4 x 44 */ { 192000, SNDRV_PCM_RATE_192000, 0x1800 }, /* 4 x 48 */ +#define AC_PAR_PCM_RATE_BITS 11 + /* up to bits 10, 384kHZ isn't supported properly */ + + /* not autodetected value */ + { 9600, SNDRV_PCM_RATE_KNOT, 0x0400 }, /* 1/5 x 48 */ { 0 } /* terminator */ }; @@ -1389,7 +1444,7 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate, val = rate_bits[i].hda_fmt; break; } - if (! rate_bits[i].hz) { + if (!rate_bits[i].hz) { snd_printdd("invalid rate %d\n", rate); return 0; } @@ -1414,15 +1469,14 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate, val |= 0x20; break; default: - snd_printdd("invalid format width %d\n", snd_pcm_format_width(format)); + snd_printdd("invalid format width %d\n", + snd_pcm_format_width(format)); return 0; } return val; } -EXPORT_SYMBOL(snd_hda_calc_stream_format); - /** * snd_hda_query_supported_pcm - query the supported PCM rates and formats * @codec: the HDA codec @@ -1449,12 +1503,12 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, if (val == -1) return -EIO; } - if (! val) + if (!val) val = snd_hda_param_read(codec, codec->afg, AC_PAR_PCM); if (ratesp) { u32 rates = 0; - for (i = 0; rate_bits[i].hz; i++) { + for (i = 0; i < AC_PAR_PCM_RATE_BITS; i++) { if (val & (1 << i)) rates |= rate_bits[i].alsa_bits; } @@ -1470,8 +1524,9 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, streams = snd_hda_param_read(codec, nid, AC_PAR_STREAM); if (streams == -1) return -EIO; - if (! streams) { - streams = snd_hda_param_read(codec, codec->afg, AC_PAR_STREAM); + if (!streams) { + streams = snd_hda_param_read(codec, codec->afg, + AC_PAR_STREAM); if (streams == -1) return -EIO; } @@ -1495,7 +1550,8 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, bps = 24; else if (val & AC_SUPPCM_BITS_20) bps = 20; - } else if (val & (AC_SUPPCM_BITS_20|AC_SUPPCM_BITS_24|AC_SUPPCM_BITS_32)) { + } else if (val & (AC_SUPPCM_BITS_20|AC_SUPPCM_BITS_24| + AC_SUPPCM_BITS_32)) { formats |= SNDRV_PCM_FMTBIT_S32_LE; if (val & AC_SUPPCM_BITS_32) bps = 32; @@ -1505,10 +1561,12 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, bps = 20; } } - else if (streams == AC_SUPFMT_FLOAT32) { /* should be exclusive */ + else if (streams == AC_SUPFMT_FLOAT32) { + /* should be exclusive */ formats |= SNDRV_PCM_FMTBIT_FLOAT_LE; bps = 32; - } else if (streams == AC_SUPFMT_AC3) { /* should be exclusive */ + } else if (streams == AC_SUPFMT_AC3) { + /* should be exclusive */ /* temporary hack: we have still no proper support * for the direct AC3 stream... */ @@ -1525,7 +1583,8 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, } /** - * snd_hda_is_supported_format - check whether the given node supports the format val + * snd_hda_is_supported_format - check whether the given node supports + * the format val * * Returns 1 if supported, 0 if not. */ @@ -1541,50 +1600,50 @@ int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid, if (val == -1) return 0; } - if (! val) { + if (!val) { val = snd_hda_param_read(codec, codec->afg, AC_PAR_PCM); if (val == -1) return 0; } rate = format & 0xff00; - for (i = 0; rate_bits[i].hz; i++) + for (i = 0; i < AC_PAR_PCM_RATE_BITS; i++) if (rate_bits[i].hda_fmt == rate) { if (val & (1 << i)) break; return 0; } - if (! rate_bits[i].hz) + if (i >= AC_PAR_PCM_RATE_BITS) return 0; stream = snd_hda_param_read(codec, nid, AC_PAR_STREAM); if (stream == -1) return 0; - if (! stream && nid != codec->afg) + if (!stream && nid != codec->afg) stream = snd_hda_param_read(codec, codec->afg, AC_PAR_STREAM); - if (! stream || stream == -1) + if (!stream || stream == -1) return 0; if (stream & AC_SUPFMT_PCM) { switch (format & 0xf0) { case 0x00: - if (! (val & AC_SUPPCM_BITS_8)) + if (!(val & AC_SUPPCM_BITS_8)) return 0; break; case 0x10: - if (! (val & AC_SUPPCM_BITS_16)) + if (!(val & AC_SUPPCM_BITS_16)) return 0; break; case 0x20: - if (! (val & AC_SUPPCM_BITS_20)) + if (!(val & AC_SUPPCM_BITS_20)) return 0; break; case 0x30: - if (! (val & AC_SUPPCM_BITS_24)) + if (!(val & AC_SUPPCM_BITS_24)) return 0; break; case 0x40: - if (! (val & AC_SUPPCM_BITS_32)) + if (!(val & AC_SUPPCM_BITS_32)) return 0; break; default: @@ -1625,15 +1684,15 @@ static int hda_pcm_default_cleanup(struct hda_pcm_stream *hinfo, return 0; } -static int set_pcm_default_values(struct hda_codec *codec, struct hda_pcm_stream *info) +static int __devinit set_pcm_default_values(struct hda_codec *codec, + struct hda_pcm_stream *info) { - if (info->nid) { - /* query support PCM information from the given NID */ - if (! info->rates || ! info->formats) - snd_hda_query_supported_pcm(codec, info->nid, - info->rates ? NULL : &info->rates, - info->formats ? NULL : &info->formats, - info->maxbps ? NULL : &info->maxbps); + /* query support PCM information from the given NID */ + if (info->nid && (!info->rates || !info->formats)) { + snd_hda_query_supported_pcm(codec, info->nid, + info->rates ? NULL : &info->rates, + info->formats ? NULL : &info->formats, + info->maxbps ? NULL : &info->maxbps); } if (info->ops.open == NULL) info->ops.open = hda_pcm_default_open_close; @@ -1676,15 +1735,14 @@ static int set_pcm_default_values(struct hda_codec *codec, struct hda_pcm_stream * * This function returns 0 if successfull, or a negative error code. */ -int snd_hda_build_pcms(struct hda_bus *bus) +int __devinit snd_hda_build_pcms(struct hda_bus *bus) { - struct list_head *p; + struct hda_codec *codec; - list_for_each(p, &bus->codec_list) { - struct hda_codec *codec = list_entry(p, struct hda_codec, list); + list_for_each_entry(codec, &bus->codec_list, list) { unsigned int pcm, s; int err; - if (! codec->patch_ops.build_pcms) + if (!codec->patch_ops.build_pcms) continue; err = codec->patch_ops.build_pcms(codec); if (err < 0) @@ -1693,7 +1751,7 @@ int snd_hda_build_pcms(struct hda_bus *bus) for (s = 0; s < 2; s++) { struct hda_pcm_stream *info; info = &codec->pcm_info[pcm].stream[s]; - if (! info->substreams) + if (!info->substreams) continue; err = set_pcm_default_values(codec, info); if (err < 0) @@ -1704,8 +1762,6 @@ int snd_hda_build_pcms(struct hda_bus *bus) return 0; } -EXPORT_SYMBOL(snd_hda_build_pcms); - /** * snd_hda_check_board_config - compare the current codec with the config table * @codec: the HDA codec @@ -1719,9 +1775,9 @@ EXPORT_SYMBOL(snd_hda_build_pcms); * * If no entries are matching, the function returns a negative value. */ -int snd_hda_check_board_config(struct hda_codec *codec, - int num_configs, const char **models, - const struct snd_pci_quirk *tbl) +int __devinit snd_hda_check_board_config(struct hda_codec *codec, + int num_configs, const char **models, + const struct snd_pci_quirk *tbl) { if (codec->bus->modelname && models) { int i; @@ -1771,24 +1827,26 @@ int snd_hda_check_board_config(struct hda_codec *codec, * * Returns 0 if successful, or a negative error code. */ -int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew) +int __devinit snd_hda_add_new_ctls(struct hda_codec *codec, + struct snd_kcontrol_new *knew) { int err; for (; knew->name; knew++) { struct snd_kcontrol *kctl; kctl = snd_ctl_new1(knew, codec); - if (! kctl) + if (!kctl) return -ENOMEM; err = snd_ctl_add(codec->bus->card, kctl); if (err < 0) { - if (! codec->addr) + if (!codec->addr) return err; kctl = snd_ctl_new1(knew, codec); - if (! kctl) + if (!kctl) return -ENOMEM; kctl->id.device = codec->addr; - if ((err = snd_ctl_add(codec->bus->card, kctl)) < 0) + err = snd_ctl_add(codec->bus->card, kctl); + if (err < 0) return err; } } @@ -1799,8 +1857,10 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew) /* * Channel mode helper */ -int snd_hda_ch_mode_info(struct hda_codec *codec, struct snd_ctl_elem_info *uinfo, - const struct hda_channel_mode *chmode, int num_chmodes) +int snd_hda_ch_mode_info(struct hda_codec *codec, + struct snd_ctl_elem_info *uinfo, + const struct hda_channel_mode *chmode, + int num_chmodes) { uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->count = 1; @@ -1812,8 +1872,10 @@ int snd_hda_ch_mode_info(struct hda_codec *codec, struct snd_ctl_elem_info *uinf return 0; } -int snd_hda_ch_mode_get(struct hda_codec *codec, struct snd_ctl_elem_value *ucontrol, - const struct hda_channel_mode *chmode, int num_chmodes, +int snd_hda_ch_mode_get(struct hda_codec *codec, + struct snd_ctl_elem_value *ucontrol, + const struct hda_channel_mode *chmode, + int num_chmodes, int max_channels) { int i; @@ -1827,15 +1889,17 @@ int snd_hda_ch_mode_get(struct hda_codec *codec, struct snd_ctl_elem_value *ucon return 0; } -int snd_hda_ch_mode_put(struct hda_codec *codec, struct snd_ctl_elem_value *ucontrol, - const struct hda_channel_mode *chmode, int num_chmodes, +int snd_hda_ch_mode_put(struct hda_codec *codec, + struct snd_ctl_elem_value *ucontrol, + const struct hda_channel_mode *chmode, + int num_chmodes, int *max_channelsp) { unsigned int mode; mode = ucontrol->value.enumerated.item[0]; snd_assert(mode < num_chmodes, return -EINVAL); - if (*max_channelsp == chmode[mode].channels && ! codec->in_resume) + if (*max_channelsp == chmode[mode].channels && !codec->in_resume) return 0; /* change the current channel setting */ *max_channelsp = chmode[mode].channels; @@ -1847,7 +1911,8 @@ int snd_hda_ch_mode_put(struct hda_codec *codec, struct snd_ctl_elem_value *ucon /* * input MUX helper */ -int snd_hda_input_mux_info(const struct hda_input_mux *imux, struct snd_ctl_elem_info *uinfo) +int snd_hda_input_mux_info(const struct hda_input_mux *imux, + struct snd_ctl_elem_info *uinfo) { unsigned int index; @@ -1861,8 +1926,10 @@ int snd_hda_input_mux_info(const struct hda_input_mux *imux, struct snd_ctl_elem return 0; } -int snd_hda_input_mux_put(struct hda_codec *codec, const struct hda_input_mux *imux, - struct snd_ctl_elem_value *ucontrol, hda_nid_t nid, +int snd_hda_input_mux_put(struct hda_codec *codec, + const struct hda_input_mux *imux, + struct snd_ctl_elem_value *ucontrol, + hda_nid_t nid, unsigned int *cur_val) { unsigned int idx; @@ -1870,7 +1937,7 @@ int snd_hda_input_mux_put(struct hda_codec *codec, const struct hda_input_mux *i idx = ucontrol->value.enumerated.item[0]; if (idx >= imux->num_items) idx = imux->num_items - 1; - if (*cur_val == idx && ! codec->in_resume) + if (*cur_val == idx && !codec->in_resume) return 0; snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, imux->items[idx].index); @@ -1883,25 +1950,53 @@ int snd_hda_input_mux_put(struct hda_codec *codec, const struct hda_input_mux *i * Multi-channel / digital-out PCM helper functions */ +/* setup SPDIF output stream */ +static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid, + unsigned int stream_tag, unsigned int format) +{ + /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */ + if (codec->spdif_ctls & AC_DIG1_ENABLE) + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, + codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff); + snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format); + /* turn on again (if needed) */ + if (codec->spdif_ctls & AC_DIG1_ENABLE) + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, + codec->spdif_ctls & 0xff); +} + /* * open the digital out in the exclusive mode */ -int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mout) +int snd_hda_multi_out_dig_open(struct hda_codec *codec, + struct hda_multi_out *mout) { mutex_lock(&codec->spdif_mutex); - if (mout->dig_out_used) { - mutex_unlock(&codec->spdif_mutex); - return -EBUSY; /* already being used */ - } + if (mout->dig_out_used == HDA_DIG_ANALOG_DUP) + /* already opened as analog dup; reset it once */ + snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 0, 0, 0); mout->dig_out_used = HDA_DIG_EXCLUSIVE; mutex_unlock(&codec->spdif_mutex); return 0; } +int snd_hda_multi_out_dig_prepare(struct hda_codec *codec, + struct hda_multi_out *mout, + unsigned int stream_tag, + unsigned int format, + struct snd_pcm_substream *substream) +{ + mutex_lock(&codec->spdif_mutex); + setup_dig_out_stream(codec, mout->dig_out_nid, stream_tag, format); + mutex_unlock(&codec->spdif_mutex); + return 0; +} + /* * release the digital out */ -int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *mout) +int snd_hda_multi_out_dig_close(struct hda_codec *codec, + struct hda_multi_out *mout) { mutex_lock(&codec->spdif_mutex); mout->dig_out_used = 0; @@ -1912,7 +2007,8 @@ int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *m /* * set up more restrictions for analog out */ -int snd_hda_multi_out_analog_open(struct hda_codec *codec, struct hda_multi_out *mout, +int snd_hda_multi_out_analog_open(struct hda_codec *codec, + struct hda_multi_out *mout, struct snd_pcm_substream *substream) { substream->runtime->hw.channels_max = mout->max_channels; @@ -1924,7 +2020,8 @@ int snd_hda_multi_out_analog_open(struct hda_codec *codec, struct hda_multi_out * set up the i/o for analog out * when the digital out is available, copy the front out to digital out, too. */ -int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_out *mout, +int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, + struct hda_multi_out *mout, unsigned int stream_tag, unsigned int format, struct snd_pcm_substream *substream) @@ -1936,24 +2033,27 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_o mutex_lock(&codec->spdif_mutex); if (mout->dig_out_nid && mout->dig_out_used != HDA_DIG_EXCLUSIVE) { if (chs == 2 && - snd_hda_is_supported_format(codec, mout->dig_out_nid, format) && - ! (codec->spdif_status & IEC958_AES0_NONAUDIO)) { + snd_hda_is_supported_format(codec, mout->dig_out_nid, + format) && + !(codec->spdif_status & IEC958_AES0_NONAUDIO)) { mout->dig_out_used = HDA_DIG_ANALOG_DUP; - /* setup digital receiver */ - snd_hda_codec_setup_stream(codec, mout->dig_out_nid, - stream_tag, 0, format); + setup_dig_out_stream(codec, mout->dig_out_nid, + stream_tag, format); } else { mout->dig_out_used = 0; - snd_hda_codec_setup_stream(codec, mout->dig_out_nid, 0, 0, 0); + snd_hda_codec_setup_stream(codec, mout->dig_out_nid, + 0, 0, 0); } } mutex_unlock(&codec->spdif_mutex); /* front */ - snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag, 0, format); + snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag, + 0, format); if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT]) /* headphone out will just decode front left/right (stereo) */ - snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag, 0, format); + snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag, + 0, format); /* extra outputs copied from front */ for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++) if (mout->extra_out_nid[i]) @@ -1964,11 +2064,11 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_o /* surrounds */ for (i = 1; i < mout->num_dacs; i++) { if (chs >= (i + 1) * 2) /* independent out */ - snd_hda_codec_setup_stream(codec, nids[i], stream_tag, i * 2, - format); + snd_hda_codec_setup_stream(codec, nids[i], stream_tag, + i * 2, format); else /* copy front */ - snd_hda_codec_setup_stream(codec, nids[i], stream_tag, 0, - format); + snd_hda_codec_setup_stream(codec, nids[i], stream_tag, + 0, format); } return 0; } @@ -1976,7 +2076,8 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_o /* * clean up the setting for analog out */ -int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, struct hda_multi_out *mout) +int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, + struct hda_multi_out *mout) { hda_nid_t *nids = mout->dac_nids; int i; @@ -2003,7 +2104,7 @@ int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, struct hda_multi_o * Helper for automatic ping configuration */ -static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list) +static int __devinit is_in_nid_list(hda_nid_t nid, hda_nid_t *list) { for (; *list; list++) if (*list == nid) @@ -2011,6 +2112,32 @@ static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list) return 0; } + +/* + * Sort an associated group of pins according to their sequence numbers. + */ +static void sort_pins_by_sequence(hda_nid_t * pins, short * sequences, + int num_pins) +{ + int i, j; + short seq; + hda_nid_t nid; + + for (i = 0; i < num_pins; i++) { + for (j = i + 1; j < num_pins; j++) { + if (sequences[i] > sequences[j]) { + seq = sequences[i]; + sequences[i] = sequences[j]; + sequences[j] = seq; + nid = pins[i]; + pins[i] = pins[j]; + pins[j] = nid; + } + } + } +} + + /* * Parse all pin widgets and store the useful pin nids to cfg * @@ -2028,22 +2155,27 @@ static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list) * The digital input/output pins are assigned to dig_in_pin and dig_out_pin, * respectively. */ -int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *cfg, - hda_nid_t *ignore_nids) +int __devinit snd_hda_parse_pin_def_config(struct hda_codec *codec, + struct auto_pin_cfg *cfg, + hda_nid_t *ignore_nids) { hda_nid_t nid, nid_start; - int i, j, nodes; - short seq, assoc_line_out, sequences[ARRAY_SIZE(cfg->line_out_pins)]; + int nodes; + short seq, assoc_line_out, assoc_speaker; + short sequences_line_out[ARRAY_SIZE(cfg->line_out_pins)]; + short sequences_speaker[ARRAY_SIZE(cfg->speaker_pins)]; memset(cfg, 0, sizeof(*cfg)); - memset(sequences, 0, sizeof(sequences)); - assoc_line_out = 0; + memset(sequences_line_out, 0, sizeof(sequences_line_out)); + memset(sequences_speaker, 0, sizeof(sequences_speaker)); + assoc_line_out = assoc_speaker = 0; nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid_start); for (nid = nid_start; nid < nodes + nid_start; nid++) { unsigned int wid_caps = get_wcaps(codec, nid); - unsigned int wid_type = (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; + unsigned int wid_type = + (wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; unsigned int def_conf; short assoc, loc; @@ -2054,7 +2186,8 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *c if (ignore_nids && is_in_nid_list(nid, ignore_nids)) continue; - def_conf = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONFIG_DEFAULT, 0); + def_conf = snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_CONFIG_DEFAULT, 0); if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) continue; loc = get_defcfg_location(def_conf); @@ -2062,22 +2195,31 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *c case AC_JACK_LINE_OUT: seq = get_defcfg_sequence(def_conf); assoc = get_defcfg_association(def_conf); - if (! assoc) + if (!assoc) continue; - if (! assoc_line_out) + if (!assoc_line_out) assoc_line_out = assoc; else if (assoc_line_out != assoc) continue; if (cfg->line_outs >= ARRAY_SIZE(cfg->line_out_pins)) continue; cfg->line_out_pins[cfg->line_outs] = nid; - sequences[cfg->line_outs] = seq; + sequences_line_out[cfg->line_outs] = seq; cfg->line_outs++; break; case AC_JACK_SPEAKER: + seq = get_defcfg_sequence(def_conf); + assoc = get_defcfg_association(def_conf); + if (! assoc) + continue; + if (! assoc_speaker) + assoc_speaker = assoc; + else if (assoc_speaker != assoc) + continue; if (cfg->speaker_outs >= ARRAY_SIZE(cfg->speaker_pins)) continue; cfg->speaker_pins[cfg->speaker_outs] = nid; + sequences_speaker[cfg->speaker_outs] = seq; cfg->speaker_outs++; break; case AC_JACK_HP_OUT: @@ -2123,34 +2265,45 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *c } /* sort by sequence */ - for (i = 0; i < cfg->line_outs; i++) - for (j = i + 1; j < cfg->line_outs; j++) - if (sequences[i] > sequences[j]) { - seq = sequences[i]; - sequences[i] = sequences[j]; - sequences[j] = seq; - nid = cfg->line_out_pins[i]; - cfg->line_out_pins[i] = cfg->line_out_pins[j]; - cfg->line_out_pins[j] = nid; - } + sort_pins_by_sequence(cfg->line_out_pins, sequences_line_out, + cfg->line_outs); + sort_pins_by_sequence(cfg->speaker_pins, sequences_speaker, + cfg->speaker_outs); + + /* + * FIX-UP: if no line-outs are detected, try to use speaker or HP pin + * as a primary output + */ + if (!cfg->line_outs) { + if (cfg->speaker_outs) { + cfg->line_outs = cfg->speaker_outs; + memcpy(cfg->line_out_pins, cfg->speaker_pins, + sizeof(cfg->speaker_pins)); + cfg->speaker_outs = 0; + memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins)); + cfg->line_out_type = AUTO_PIN_SPEAKER_OUT; + } else if (cfg->hp_outs) { + cfg->line_outs = cfg->hp_outs; + memcpy(cfg->line_out_pins, cfg->hp_pins, + sizeof(cfg->hp_pins)); + cfg->hp_outs = 0; + memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins)); + cfg->line_out_type = AUTO_PIN_HP_OUT; + } + } /* Reorder the surround channels * ALSA sequence is front/surr/clfe/side * HDA sequence is: * 4-ch: front/surr => OK as it is * 6-ch: front/clfe/surr - * 8-ch: front/clfe/side/surr + * 8-ch: front/clfe/rear/side|fc */ switch (cfg->line_outs) { case 3: - nid = cfg->line_out_pins[1]; - cfg->line_out_pins[1] = cfg->line_out_pins[2]; - cfg->line_out_pins[2] = nid; - break; case 4: nid = cfg->line_out_pins[1]; - cfg->line_out_pins[1] = cfg->line_out_pins[3]; - cfg->line_out_pins[3] = cfg->line_out_pins[2]; + cfg->line_out_pins[1] = cfg->line_out_pins[2]; cfg->line_out_pins[2] = nid; break; } @@ -2179,26 +2332,6 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *c cfg->input_pins[AUTO_PIN_CD], cfg->input_pins[AUTO_PIN_AUX]); - /* - * FIX-UP: if no line-outs are detected, try to use speaker or HP pin - * as a primary output - */ - if (! cfg->line_outs) { - if (cfg->speaker_outs) { - cfg->line_outs = cfg->speaker_outs; - memcpy(cfg->line_out_pins, cfg->speaker_pins, - sizeof(cfg->speaker_pins)); - cfg->speaker_outs = 0; - memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins)); - } else if (cfg->hp_outs) { - cfg->line_outs = cfg->hp_outs; - memcpy(cfg->line_out_pins, cfg->hp_pins, - sizeof(cfg->hp_pins)); - cfg->hp_outs = 0; - memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins)); - } - } - return 0; } @@ -2222,11 +2355,10 @@ const char *auto_pin_cfg_labels[AUTO_PIN_LAST] = { */ int snd_hda_suspend(struct hda_bus *bus, pm_message_t state) { - struct list_head *p; + struct hda_codec *codec; /* FIXME: should handle power widget capabilities */ - list_for_each(p, &bus->codec_list) { - struct hda_codec *codec = list_entry(p, struct hda_codec, list); + list_for_each_entry(codec, &bus->codec_list, list) { if (codec->patch_ops.suspend) codec->patch_ops.suspend(codec, state); hda_set_power_state(codec, @@ -2236,8 +2368,6 @@ int snd_hda_suspend(struct hda_bus *bus, pm_message_t state) return 0; } -EXPORT_SYMBOL(snd_hda_suspend); - /** * snd_hda_resume - resume the codecs * @bus: the HDA bus @@ -2247,10 +2377,9 @@ EXPORT_SYMBOL(snd_hda_suspend); */ int snd_hda_resume(struct hda_bus *bus) { - struct list_head *p; + struct hda_codec *codec; - list_for_each(p, &bus->codec_list) { - struct hda_codec *codec = list_entry(p, struct hda_codec, list); + list_for_each_entry(codec, &bus->codec_list, list) { hda_set_power_state(codec, codec->afg ? codec->afg : codec->mfg, AC_PWRST_D0); @@ -2260,8 +2389,6 @@ int snd_hda_resume(struct hda_bus *bus) return 0; } -EXPORT_SYMBOL(snd_hda_resume); - /** * snd_hda_resume_ctls - resume controls in the new control list * @codec: the HDA codec @@ -2276,7 +2403,7 @@ int snd_hda_resume_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew) struct snd_ctl_elem_value *val; val = kmalloc(sizeof(*val), GFP_KERNEL); - if (! val) + if (!val) return -ENOMEM; codec->in_resume = 1; for (; knew->name; knew++) { @@ -2320,19 +2447,3 @@ int snd_hda_resume_spdif_in(struct hda_codec *codec) return snd_hda_resume_ctls(codec, dig_in_ctls); } #endif - -/* - * INIT part - */ - -static int __init alsa_hda_init(void) -{ - return 0; -} - -static void __exit alsa_hda_exit(void) -{ -} - -module_init(alsa_hda_init) -module_exit(alsa_hda_exit) diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index c12bc4e8840f..56c26e7ccdf1 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -233,7 +233,7 @@ enum { */ /* Amp gain/mute */ -#define AC_AMP_MUTE (1<<8) +#define AC_AMP_MUTE (1<<7) #define AC_AMP_GAIN (0x7f) #define AC_AMP_GET_INDEX (0xf<<0) diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 1e5ff0cd3709..000287f7da43 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -133,7 +133,7 @@ static int add_new_node(struct hda_codec *codec, struct hda_gspec *spec, hda_nid return -ENOMEM; } } - memcpy(node->conn_list, conn_list, nconns); + memcpy(node->conn_list, conn_list, nconns * sizeof(hda_nid_t)); node->nconns = nconns; node->wid_caps = get_wcaps(codec, nid); node->type = (node->wid_caps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 1672cace1ae7..2fa281cbef91 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -88,6 +88,8 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6}," "{ATI, SB600}," "{ATI, RS600}," "{ATI, RS690}," + "{ATI, RS780}," + "{ATI, R600}," "{VIA, VT8251}," "{VIA, VT8237A}," "{SiS, SIS966}," @@ -198,6 +200,7 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 }; #define RIRB_INT_MASK 0x05 /* STATESTS int mask: SD2,SD1,SD0 */ +#define AZX_MAX_CODECS 3 #define STATESTS_INT_MASK 0x07 /* SD_CTL bits */ @@ -978,7 +981,7 @@ static unsigned int azx_max_codecs[] __devinitdata = { static int __devinit azx_codec_create(struct azx *chip, const char *model) { struct hda_bus_template bus_temp; - int c, codecs, err; + int c, codecs, audio_codecs, err; memset(&bus_temp, 0, sizeof(bus_temp)); bus_temp.private_data = chip; @@ -990,16 +993,30 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model) if ((err = snd_hda_bus_new(chip->card, &bus_temp, &chip->bus)) < 0) return err; - codecs = 0; - for (c = 0; c < azx_max_codecs[chip->driver_type]; c++) { + codecs = audio_codecs = 0; + for (c = 0; c < AZX_MAX_CODECS; c++) { if ((chip->codec_mask & (1 << c)) & probe_mask) { - err = snd_hda_codec_new(chip->bus, c, NULL); + struct hda_codec *codec; + err = snd_hda_codec_new(chip->bus, c, &codec); if (err < 0) continue; codecs++; + if (codec->afg) + audio_codecs++; } } - if (! codecs) { + if (!audio_codecs) { + /* probe additional slots if no codec is found */ + for (; c < azx_max_codecs[chip->driver_type]; c++) { + if ((chip->codec_mask & (1 << c)) & probe_mask) { + err = snd_hda_codec_new(chip->bus, c, NULL); + if (err < 0) + continue; + codecs++; + } + } + } + if (!codecs) { snd_printk(KERN_ERR SFX "no codecs initialized\n"); return -ENXIO; } @@ -1518,7 +1535,7 @@ static int azx_dev_free(struct snd_device *device) /* * white/black-listing for position_fix */ -static const struct snd_pci_quirk position_fix_list[] __devinitdata = { +static struct snd_pci_quirk position_fix_list[] __devinitdata = { SND_PCI_QUIRK(0x1028, 0x01cc, "Dell D820", POS_FIX_NONE), {} }; @@ -1758,6 +1775,8 @@ static struct pci_device_id azx_ids[] = { { 0x1002, 0x4383, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATI }, /* ATI SB600 */ { 0x1002, 0x793b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RS600 HDMI */ { 0x1002, 0x7919, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RS690 HDMI */ + { 0x1002, 0x960c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI RS780 HDMI */ + { 0x1002, 0xaa00, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ATIHDMI }, /* ATI R600 HDMI */ { 0x1106, 0x3288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_VIA }, /* VIA VT8251/VT8237A */ { 0x1039, 0x7502, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_SIS }, /* SIS966 */ { 0x10b9, 0x5461, PCI_ANY_ID, PCI_ANY_ID, 0, 0, AZX_DRIVER_ULI }, /* ULI M5461 */ diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 39718d6cdadd..be12b8814c39 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h @@ -148,6 +148,11 @@ struct hda_multi_out { int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mout); int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *mout); +int snd_hda_multi_out_dig_prepare(struct hda_codec *codec, + struct hda_multi_out *mout, + unsigned int stream_tag, + unsigned int format, + struct snd_pcm_substream *substream); int snd_hda_multi_out_analog_open(struct hda_codec *codec, struct hda_multi_out *mout, struct snd_pcm_substream *substream); int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_out *mout, @@ -217,6 +222,12 @@ enum { AUTO_PIN_LAST }; +enum { + AUTO_PIN_LINE_OUT, + AUTO_PIN_SPEAKER_OUT, + AUTO_PIN_HP_OUT +}; + extern const char *auto_pin_cfg_labels[AUTO_PIN_LAST]; struct auto_pin_cfg { @@ -225,6 +236,7 @@ struct auto_pin_cfg { int speaker_outs; hda_nid_t speaker_pins[5]; int hp_outs; + int line_out_type; /* AUTO_PIN_XXX_OUT */ hda_nid_t hp_pins[5]; hda_nid_t input_pins[AUTO_PIN_LAST]; hda_nid_t dig_out_pin; diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index f94f1f22889e..0e1a879663fa 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -192,6 +192,17 @@ static int ad198x_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, return snd_hda_multi_out_dig_close(codec, &spec->multiout); } +static int ad198x_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + unsigned int stream_tag, + unsigned int format, + struct snd_pcm_substream *substream) +{ + struct ad198x_spec *spec = codec->spec; + return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag, + format, substream); +} + /* * Analog capture */ @@ -250,7 +261,8 @@ static struct hda_pcm_stream ad198x_pcm_digital_playback = { .nid = 0, /* fill later */ .ops = { .open = ad198x_dig_playback_pcm_open, - .close = ad198x_dig_playback_pcm_close + .close = ad198x_dig_playback_pcm_close, + .prepare = ad198x_dig_playback_pcm_prepare }, }; @@ -739,41 +751,35 @@ static struct hda_verb ad1986a_init_verbs[] = { { } /* end */ }; -/* additional verbs for 3-stack model */ -static struct hda_verb ad1986a_3st_init_verbs[] = { - /* Mic and line-in selectors */ - {0x0f, AC_VERB_SET_CONNECT_SEL, 0x2}, - {0x10, AC_VERB_SET_CONNECT_SEL, 0x1}, - { } /* end */ -}; - static struct hda_verb ad1986a_ch2_init[] = { /* Surround out -> Line In */ - { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, - { 0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, + { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, + /* Line-in selectors */ + { 0x10, AC_VERB_SET_CONNECT_SEL, 0x1 }, /* CLFE -> Mic in */ - { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, - { 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, + { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, + /* Mic selector, mix C/LFE (backmic) and Mic (frontmic) */ + { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x4 }, { } /* end */ }; static struct hda_verb ad1986a_ch4_init[] = { /* Surround out -> Surround */ - { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, - { 0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, + { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, + { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 }, /* CLFE -> Mic in */ - { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, - { 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, + { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, + { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x4 }, { } /* end */ }; static struct hda_verb ad1986a_ch6_init[] = { /* Surround out -> Surround out */ - { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, - { 0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, + { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, + { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 }, /* CLFE -> CLFE */ - { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, - { 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, + { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, + { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x0 }, { } /* end */ }; @@ -828,6 +834,7 @@ static struct snd_pci_quirk ad1986a_cfg_tbl[] = { SND_PCI_QUIRK(0x1043, 0x1297, "ASUS Z62F", AD1986A_LAPTOP_EAPD), SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS V1j", AD1986A_LAPTOP_EAPD), SND_PCI_QUIRK(0x1043, 0x1302, "ASUS W3j", AD1986A_LAPTOP_EAPD), + SND_PCI_QUIRK(0x1043, 0x1447, "ASUS A8J", AD1986A_3STACK), SND_PCI_QUIRK(0x1043, 0x817f, "ASUS P5", AD1986A_3STACK), SND_PCI_QUIRK(0x1043, 0x818f, "ASUS P5", AD1986A_LAPTOP), SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS P5", AD1986A_3STACK), @@ -882,9 +889,8 @@ static int patch_ad1986a(struct hda_codec *codec) case AD1986A_3STACK: spec->num_mixers = 2; spec->mixers[1] = ad1986a_3st_mixers; - spec->num_init_verbs = 3; - spec->init_verbs[1] = ad1986a_3st_init_verbs; - spec->init_verbs[2] = ad1986a_ch2_init; + spec->num_init_verbs = 2; + spec->init_verbs[1] = ad1986a_ch2_init; spec->channel_mode = ad1986a_modes; spec->num_channel_mode = ARRAY_SIZE(ad1986a_modes); spec->need_dac_fix = 1; @@ -1892,8 +1898,9 @@ static int ad1988_spdif_playback_source_get(struct snd_kcontrol *kcontrol, sel = snd_hda_codec_read(codec, 0x02, 0, AC_VERB_GET_CONNECT_SEL, 0); if (sel > 0) { - sel = snd_hda_codec_read(codec, 0x0b, 0, AC_VERB_GET_CONNECT_SEL, 0); - if (sel <= 3) + sel = snd_hda_codec_read(codec, 0x0b, 0, + AC_VERB_GET_CONNECT_SEL, 0); + if (sel < 3) sel++; else sel = 0; @@ -1906,23 +1913,27 @@ static int ad1988_spdif_playback_source_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - unsigned int sel; + unsigned int val, sel; int change; + val = ucontrol->value.enumerated.item[0]; sel = snd_hda_codec_read(codec, 0x02, 0, AC_VERB_GET_CONNECT_SEL, 0); - if (! ucontrol->value.enumerated.item[0]) { + if (!val) { change = sel != 0; - if (change) - snd_hda_codec_write(codec, 0x02, 0, AC_VERB_SET_CONNECT_SEL, 0); + if (change || codec->in_resume) + snd_hda_codec_write(codec, 0x02, 0, + AC_VERB_SET_CONNECT_SEL, 0); } else { change = sel == 0; - if (change) - snd_hda_codec_write(codec, 0x02, 0, AC_VERB_SET_CONNECT_SEL, 1); - sel = snd_hda_codec_read(codec, 0x0b, 0, AC_VERB_GET_CONNECT_SEL, 0) + 1; - change |= sel == ucontrol->value.enumerated.item[0]; - if (change) - snd_hda_codec_write(codec, 0x02, 0, AC_VERB_SET_CONNECT_SEL, - ucontrol->value.enumerated.item[0] - 1); + if (change || codec->in_resume) + snd_hda_codec_write(codec, 0x02, 0, + AC_VERB_SET_CONNECT_SEL, 1); + sel = snd_hda_codec_read(codec, 0x0b, 0, + AC_VERB_GET_CONNECT_SEL, 0) + 1; + change |= sel != val; + if (change || codec->in_resume) + snd_hda_codec_write(codec, 0x0b, 0, + AC_VERB_SET_CONNECT_SEL, val - 1); } return change; } diff --git a/sound/pci/hda/patch_atihdmi.c b/sound/pci/hda/patch_atihdmi.c index 831469d3a923..f8eb4c90f801 100644 --- a/sound/pci/hda/patch_atihdmi.c +++ b/sound/pci/hda/patch_atihdmi.c @@ -94,6 +94,17 @@ static int atihdmi_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, return snd_hda_multi_out_dig_close(codec, &spec->multiout); } +static int atihdmi_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + unsigned int stream_tag, + unsigned int format, + struct snd_pcm_substream *substream) +{ + struct atihdmi_spec *spec = codec->spec; + return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag, + format, substream); +} + static struct hda_pcm_stream atihdmi_pcm_digital_playback = { .substreams = 1, .channels_min = 2, @@ -101,7 +112,8 @@ static struct hda_pcm_stream atihdmi_pcm_digital_playback = { .nid = 0x2, /* NID to query formats and rates and setup streams */ .ops = { .open = atihdmi_dig_playback_pcm_open, - .close = atihdmi_dig_playback_pcm_close + .close = atihdmi_dig_playback_pcm_close, + .prepare = atihdmi_dig_playback_pcm_prepare }, }; @@ -160,6 +172,7 @@ static int patch_atihdmi(struct hda_codec *codec) */ struct hda_codec_preset snd_hda_preset_atihdmi[] = { { .id = 0x1002793c, .name = "ATI RS600 HDMI", .patch = patch_atihdmi }, - { .id = 0x1002791a, .name = "ATI RS690 HDMI", .patch = patch_atihdmi }, + { .id = 0x1002791a, .name = "ATI RS690/780 HDMI", .patch = patch_atihdmi }, + { .id = 0x1002aa01, .name = "ATI R600 HDMI", .patch = patch_atihdmi }, {} /* terminator */ }; diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c index 5b9d3a31a1ae..3c722e667bc8 100644 --- a/sound/pci/hda/patch_cmedia.c +++ b/sound/pci/hda/patch_cmedia.c @@ -497,6 +497,17 @@ static int cmi9880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, return snd_hda_multi_out_dig_close(codec, &spec->multiout); } +static int cmi9880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + unsigned int stream_tag, + unsigned int format, + struct snd_pcm_substream *substream) +{ + struct cmi_spec *spec = codec->spec; + return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag, + format, substream); +} + /* * Analog capture */ @@ -556,7 +567,8 @@ static struct hda_pcm_stream cmi9880_pcm_digital_playback = { /* NID is set in cmi9880_build_pcms */ .ops = { .open = cmi9880_dig_playback_pcm_open, - .close = cmi9880_dig_playback_pcm_close + .close = cmi9880_dig_playback_pcm_close, + .prepare = cmi9880_dig_playback_pcm_prepare }, }; diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 46e93c6b9a42..a5a4b2bddf20 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -136,6 +136,18 @@ static int conexant_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, return snd_hda_multi_out_dig_close(codec, &spec->multiout); } +static int conexant_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + unsigned int stream_tag, + unsigned int format, + struct snd_pcm_substream *substream) +{ + struct conexant_spec *spec = codec->spec; + return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, + stream_tag, + format, substream); +} + /* * Analog capture */ @@ -194,7 +206,8 @@ static struct hda_pcm_stream conexant_pcm_digital_playback = { .nid = 0, /* fill later */ .ops = { .open = conexant_dig_playback_pcm_open, - .close = conexant_dig_playback_pcm_close + .close = conexant_dig_playback_pcm_close, + .prepare = conexant_dig_playback_pcm_prepare }, }; @@ -452,115 +465,6 @@ static int conexant_ch_mode_put(struct snd_kcontrol *kcontrol, .put = conexant_ch_mode_put, \ .private_value = nid | (dir<<16) } -static int cxt_gpio_data_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *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 cxt_gpio_data_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - hda_nid_t nid = kcontrol->private_value & 0xffff; - unsigned char mask = (kcontrol->private_value >> 16) & 0xff; - long *valp = ucontrol->value.integer.value; - unsigned int val = snd_hda_codec_read(codec, nid, 0, - AC_VERB_GET_GPIO_DATA, 0x00); - - *valp = (val & mask) != 0; - return 0; -} - -static int cxt_gpio_data_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - hda_nid_t nid = kcontrol->private_value & 0xffff; - unsigned char mask = (kcontrol->private_value >> 16) & 0xff; - long val = *ucontrol->value.integer.value; - unsigned int gpio_data = snd_hda_codec_read(codec, nid, 0, - AC_VERB_GET_GPIO_DATA, - 0x00); - unsigned int old_data = gpio_data; - - /* Set/unset the masked GPIO bit(s) as needed */ - if (val == 0) - gpio_data &= ~mask; - else - gpio_data |= mask; - if (gpio_data == old_data && !codec->in_resume) - return 0; - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_GPIO_DATA, gpio_data); - return 1; -} - -#define CXT_GPIO_DATA_SWITCH(xname, nid, mask) \ - { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ - .info = cxt_gpio_data_info, \ - .get = cxt_gpio_data_get, \ - .put = cxt_gpio_data_put, \ - .private_value = nid | (mask<<16) } -#if 0 -static int cxt_spdif_ctrl_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *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 cxt_spdif_ctrl_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - hda_nid_t nid = kcontrol->private_value & 0xffff; - unsigned char mask = (kcontrol->private_value >> 16) & 0xff; - long *valp = ucontrol->value.integer.value; - unsigned int val = snd_hda_codec_read(codec, nid, 0, - AC_VERB_GET_DIGI_CONVERT, 0x00); - - *valp = (val & mask) != 0; - return 0; -} - -static int cxt_spdif_ctrl_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - hda_nid_t nid = kcontrol->private_value & 0xffff; - unsigned char mask = (kcontrol->private_value >> 16) & 0xff; - long val = *ucontrol->value.integer.value; - unsigned int ctrl_data = snd_hda_codec_read(codec, nid, 0, - AC_VERB_GET_DIGI_CONVERT, - 0x00); - unsigned int old_data = ctrl_data; - - /* Set/unset the masked control bit(s) as needed */ - if (val == 0) - ctrl_data &= ~mask; - else - ctrl_data |= mask; - if (ctrl_data == old_data && !codec->in_resume) - return 0; - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, - ctrl_data); - return 1; -} - -#define CXT_SPDIF_CTRL_SWITCH(xname, nid, mask) \ - { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ - .info = cxt_spdif_ctrl_info, \ - .get = cxt_spdif_ctrl_get, \ - .put = cxt_spdif_ctrl_put, \ - .private_value = nid | (mask<<16) } -#endif #endif /* CONFIG_SND_DEBUG */ /* Conexant 5045 specific */ @@ -599,6 +503,7 @@ static int cxt5045_hp_master_sw_put(struct snd_kcontrol *kcontrol, bits = (!spec->hp_present && spec->cur_eapd) ? 0 : 0x80; snd_hda_codec_amp_update(codec, 0x10, 0, HDA_OUTPUT, 0, 0x80, bits); snd_hda_codec_amp_update(codec, 0x10, 1, HDA_OUTPUT, 0, 0x80, bits); + bits = spec->cur_eapd ? 0 : 0x80; snd_hda_codec_amp_update(codec, 0x11, 0, HDA_OUTPUT, 0, 0x80, bits); snd_hda_codec_amp_update(codec, 0x11, 1, HDA_OUTPUT, 0, 0x80, bits); @@ -624,6 +529,29 @@ static int cxt5045_hp_master_vol_put(struct snd_kcontrol *kcontrol, return change; } +/* toggle input of built-in and mic jack appropriately */ +static void cxt5045_hp_automic(struct hda_codec *codec) +{ + static struct hda_verb mic_jack_on[] = { + {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, + {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, + {} + }; + static struct hda_verb mic_jack_off[] = { + {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, + {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, + {} + }; + unsigned int present; + + present = snd_hda_codec_read(codec, 0x12, 0, + AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + if (present) + snd_hda_sequence_write(codec, mic_jack_on); + else + snd_hda_sequence_write(codec, mic_jack_off); +} + /* mute internal speaker if HP is plugged */ static void cxt5045_hp_automute(struct hda_codec *codec) @@ -634,7 +562,7 @@ static void cxt5045_hp_automute(struct hda_codec *codec) spec->hp_present = snd_hda_codec_read(codec, 0x11, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - bits = (spec->hp_present || !spec->cur_eapd) ? 0x80 : 0; + bits = (spec->hp_present || !spec->cur_eapd) ? 0x80 : 0; snd_hda_codec_amp_update(codec, 0x10, 0, HDA_OUTPUT, 0, 0x80, bits); snd_hda_codec_amp_update(codec, 0x10, 1, HDA_OUTPUT, 0, 0x80, bits); } @@ -648,6 +576,10 @@ static void cxt5045_hp_unsol_event(struct hda_codec *codec, case CONEXANT_HP_EVENT: cxt5045_hp_automute(codec); break; + case CONEXANT_MIC_EVENT: + cxt5045_hp_automic(codec); + break; + } } @@ -659,12 +591,10 @@ static struct snd_kcontrol_new cxt5045_mixers[] = { .get = conexant_mux_enum_get, .put = conexant_mux_enum_put }, - HDA_CODEC_VOLUME("Int Mic Volume", 0x17, 0x01, HDA_INPUT), - HDA_CODEC_MUTE("Int Mic Switch", 0x17, 0x01, HDA_INPUT), - HDA_CODEC_VOLUME("Ext Mic Volume", 0x17, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("Ext Mic Switch", 0x17, 0x02, HDA_INPUT), - HDA_CODEC_VOLUME("Capture Volume", 0x1a, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Capture Switch", 0x1a, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Int Mic Volume", 0x1a, 0x01, HDA_INPUT), + HDA_CODEC_MUTE("Int Mic Switch", 0x1a, 0x01, HDA_INPUT), + HDA_CODEC_VOLUME("Ext Mic Volume", 0x1a, 0x02, HDA_INPUT), + HDA_CODEC_MUTE("Ext Mic Switch", 0x1a, 0x02, HDA_INPUT), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Volume", @@ -688,7 +618,7 @@ static struct snd_kcontrol_new cxt5045_mixers[] = { static struct hda_verb cxt5045_init_verbs[] = { /* Line in, Mic */ {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 }, + {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, /* HP, Amp */ {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, {0x17, AC_VERB_SET_CONNECT_SEL,0x01}, @@ -701,18 +631,29 @@ static struct hda_verb cxt5045_init_verbs[] = { {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x04}, /* Record selector: Int mic */ - {0x1a, AC_VERB_SET_CONNECT_SEL,0x0}, + {0x1a, AC_VERB_SET_CONNECT_SEL,0x1}, {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17}, /* SPDIF route: PCM */ { 0x13, AC_VERB_SET_CONNECT_SEL, 0x0 }, - /* pin sensing on HP and Mic jacks */ - {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, /* EAPD */ {0x10, AC_VERB_SET_EAPD_BTLENABLE, 0x2 }, /* default on */ { } /* end */ }; + +static struct hda_verb cxt5045_hp_sense_init_verbs[] = { + /* pin sensing on HP jack */ + {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, + { } /* end */ +}; + +static struct hda_verb cxt5045_mic_sense_init_verbs[] = { + /* pin sensing on HP jack */ + {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT}, + { } /* end */ +}; + #ifdef CONFIG_SND_DEBUG /* Test configuration for debugging, modelled after the ALC260 test * configuration. @@ -733,6 +674,10 @@ static struct snd_kcontrol_new cxt5045_test_mixer[] = { /* Output controls */ HDA_CODEC_VOLUME("Speaker Playback Volume", 0x10, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Speaker Playback Switch", 0x10, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Node 11 Playback Volume", 0x11, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Node 11 Playback Switch", 0x11, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Node 12 Playback Volume", 0x12, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Node 12 Playback Switch", 0x12, 0x0, HDA_OUTPUT), /* Modes for retasking pin widgets */ CXT_PIN_MODE("HP-OUT pin mode", 0x11, CXT_PIN_DIR_INOUT), @@ -742,25 +687,17 @@ static struct snd_kcontrol_new cxt5045_test_mixer[] = { CXT_EAPD_SWITCH("External Amplifier", 0x10, 0x0), /* Loopback mixer controls */ - HDA_CODEC_VOLUME("MIC1 Playback Volume", 0x17, 0x01, HDA_INPUT), - HDA_CODEC_MUTE("MIC1 Playback Switch", 0x17, 0x01, HDA_INPUT), - HDA_CODEC_VOLUME("LINE loopback Playback Volume", 0x17, 0x02, HDA_INPUT), - HDA_CODEC_MUTE("LINE loopback Playback Switch", 0x17, 0x02, HDA_INPUT), - HDA_CODEC_VOLUME("HP-OUT loopback Playback Volume", 0x17, 0x03, HDA_INPUT), - HDA_CODEC_MUTE("HP-OUT loopback Playback Switch", 0x17, 0x03, HDA_INPUT), - HDA_CODEC_VOLUME("CD Playback Volume", 0x17, 0x04, HDA_INPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x17, 0x04, HDA_INPUT), - - HDA_CODEC_VOLUME("Capture-1 Volume", 0x17, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("Capture-1 Switch", 0x17, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Capture-2 Volume", 0x17, 0x1, HDA_INPUT), - HDA_CODEC_MUTE("Capture-2 Switch", 0x17, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Capture-3 Volume", 0x17, 0x2, HDA_INPUT), - HDA_CODEC_MUTE("Capture-3 Switch", 0x17, 0x2, HDA_INPUT), - HDA_CODEC_VOLUME("Capture-4 Volume", 0x17, 0x3, HDA_INPUT), - HDA_CODEC_MUTE("Capture-4 Switch", 0x17, 0x3, HDA_INPUT), - HDA_CODEC_VOLUME("Capture-5 Volume", 0x17, 0x4, HDA_INPUT), - HDA_CODEC_MUTE("Capture-5 Switch", 0x17, 0x4, HDA_INPUT), + + HDA_CODEC_VOLUME("Mixer-1 Volume", 0x17, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mixer-1 Switch", 0x17, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Mixer-2 Volume", 0x17, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Mixer-2 Switch", 0x17, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Mixer-3 Volume", 0x17, 0x2, HDA_INPUT), + HDA_CODEC_MUTE("Mixer-3 Switch", 0x17, 0x2, HDA_INPUT), + HDA_CODEC_VOLUME("Mixer-4 Volume", 0x17, 0x3, HDA_INPUT), + HDA_CODEC_MUTE("Mixer-4 Switch", 0x17, 0x3, HDA_INPUT), + HDA_CODEC_VOLUME("Mixer-5 Volume", 0x17, 0x4, HDA_INPUT), + HDA_CODEC_MUTE("Mixer-5 Switch", 0x17, 0x4, HDA_INPUT), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Input Source", @@ -768,14 +705,17 @@ static struct snd_kcontrol_new cxt5045_test_mixer[] = { .get = conexant_mux_enum_get, .put = conexant_mux_enum_put, }, - { } /* end */ }; static struct hda_verb cxt5045_test_init_verbs[] = { + /* Set connections */ + { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 }, + { 0x11, AC_VERB_SET_CONNECT_SEL, 0x0 }, + { 0x12, AC_VERB_SET_CONNECT_SEL, 0x0 }, /* Enable retasking pins as output, initially without power amp */ {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Disable digital (SPDIF) pins initially, but users can enable * them via a mixer switch. In the case of SPDIF-out, this initverb @@ -804,6 +744,7 @@ static struct hda_verb cxt5045_test_init_verbs[] = { * pin) */ {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, + {0x17, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Mute all inputs to mixer widget (even unconnected ones) */ {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* Mixer pin */ @@ -827,7 +768,8 @@ static int cxt5045_init(struct hda_codec *codec) enum { - CXT5045_LAPTOP, /* Laptops w/ EAPD support */ + CXT5045_LAPTOP, /* Laptops w/ EAPD support */ + CXT5045_FUJITSU, /* Laptops w/ EAPD support */ #ifdef CONFIG_SND_DEBUG CXT5045_TEST, #endif @@ -836,6 +778,7 @@ enum { static const char *cxt5045_models[CXT5045_MODELS] = { [CXT5045_LAPTOP] = "laptop", + [CXT5045_FUJITSU] = "fujitsu", #ifdef CONFIG_SND_DEBUG [CXT5045_TEST] = "test", #endif @@ -844,7 +787,11 @@ static const char *cxt5045_models[CXT5045_MODELS] = { static struct snd_pci_quirk cxt5045_cfg_tbl[] = { SND_PCI_QUIRK(0x103c, 0x30b7, "HP DV6000Z", CXT5045_LAPTOP), SND_PCI_QUIRK(0x103c, 0x30bb, "HP DV8000", CXT5045_LAPTOP), - SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_LAPTOP), + SND_PCI_QUIRK(0x103c, 0x30b2, "HP DV Series", CXT5045_LAPTOP), + SND_PCI_QUIRK(0x103c, 0x30b5, "HP DV2120", CXT5045_LAPTOP), + SND_PCI_QUIRK(0x103c, 0x30cd, "HP DV Series", CXT5045_LAPTOP), + SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_FUJITSU), + SND_PCI_QUIRK(0x8086, 0x2111, "Conexant Reference board", CXT5045_LAPTOP), {} }; @@ -877,16 +824,23 @@ static int patch_cxt5045(struct hda_codec *codec) codec->patch_ops = conexant_patch_ops; - codec->patch_ops.unsol_event = cxt5045_hp_unsol_event; board_config = snd_hda_check_board_config(codec, CXT5045_MODELS, cxt5045_models, cxt5045_cfg_tbl); switch (board_config) { case CXT5045_LAPTOP: + codec->patch_ops.unsol_event = cxt5045_hp_unsol_event; + spec->input_mux = &cxt5045_capture_source; + spec->num_init_verbs = 2; + spec->init_verbs[1] = cxt5045_hp_sense_init_verbs; + spec->mixers[0] = cxt5045_mixers; + codec->patch_ops.init = cxt5045_init; + break; + case CXT5045_FUJITSU: spec->input_mux = &cxt5045_capture_source; spec->num_init_verbs = 2; - spec->init_verbs[1] = cxt5045_init_verbs; + spec->init_verbs[1] = cxt5045_mic_sense_init_verbs; spec->mixers[0] = cxt5045_mixers; codec->patch_ops.init = cxt5045_init; break; @@ -913,10 +867,9 @@ static struct hda_channel_mode cxt5047_modes[1] = { }; static struct hda_input_mux cxt5047_capture_source = { - .num_items = 2, + .num_items = 1, .items = { - { "ExtMic", 0x0 }, - { "IntMic", 0x1 }, + { "Mic", 0x2 }, } }; @@ -1009,7 +962,7 @@ static void cxt5047_hp_automic(struct hda_codec *codec) }; unsigned int present; - present = snd_hda_codec_read(codec, 0x08, 0, + present = snd_hda_codec_read(codec, 0x15, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; if (present) snd_hda_sequence_write(codec, mic_jack_on); @@ -1033,37 +986,20 @@ static void cxt5047_hp_unsol_event(struct hda_codec *codec, } static struct snd_kcontrol_new cxt5047_mixers[] = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Capture Source", - .info = conexant_mux_enum_info, - .get = conexant_mux_enum_get, - .put = conexant_mux_enum_put - }, HDA_CODEC_VOLUME("Mic Bypass Capture Volume", 0x19, 0x02, HDA_INPUT), HDA_CODEC_MUTE("Mic Bypass Capture Switch", 0x19, 0x02, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Gain Volume", 0x1a, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Mic Gain Switch", 0x1a, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x03, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x12, 0x03, HDA_INPUT), HDA_CODEC_VOLUME("PCM Volume", 0x10, 0x00, HDA_OUTPUT), HDA_CODEC_MUTE("PCM Switch", 0x10, 0x00, HDA_OUTPUT), HDA_CODEC_VOLUME("PCM-2 Volume", 0x1c, 0x00, HDA_OUTPUT), HDA_CODEC_MUTE("PCM-2 Switch", 0x1c, 0x00, HDA_OUTPUT), - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Master Playback Volume", - .info = snd_hda_mixer_amp_volume_info, - .get = snd_hda_mixer_amp_volume_get, - .put = cxt5047_hp_master_vol_put, - .private_value = HDA_COMPOSE_AMP_VAL(0x13, 3, 0, HDA_OUTPUT), - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Master Playback Switch", - .info = cxt_eapd_info, - .get = cxt_eapd_get, - .put = cxt5047_hp_master_sw_put, - .private_value = 0x13, - }, + HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x00, HDA_OUTPUT), + HDA_CODEC_MUTE("Speaker Playback Switch", 0x1d, 0x00, HDA_OUTPUT), + HDA_CODEC_VOLUME("Headphone Playback Volume", 0x13, 0x00, HDA_OUTPUT), + HDA_CODEC_MUTE("Headphone Playback Switch", 0x13, 0x00, HDA_OUTPUT), {} }; @@ -1133,18 +1069,19 @@ static struct hda_verb cxt5047_init_verbs[] = { {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 }, {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 }, - /* HP, Amp, Speaker */ - {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - {0x1A, AC_VERB_SET_CONNECT_SEL,0x00}, - {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, - AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x00}, - {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, - AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x03}, + /* HP, Speaker */ + {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, + {0x13, AC_VERB_SET_CONNECT_SEL,0x1}, {0x1d, AC_VERB_SET_CONNECT_SEL,0x0}, - /* Record selector: Front mic */ + /* Record selector: Mic */ {0x12, AC_VERB_SET_CONNECT_SEL,0x03}, {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17}, + {0x1A, AC_VERB_SET_CONNECT_SEL,0x02}, + {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, + AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x00}, + {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, + AC_AMP_SET_OUTPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x03}, /* SPDIF route: PCM */ { 0x18, AC_VERB_SET_CONNECT_SEL, 0x0 }, /* Enable unsolicited events */ @@ -1161,8 +1098,6 @@ static struct hda_verb cxt5047_toshiba_init_verbs[] = { {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT}, /* Speaker routing */ {0x1d, AC_VERB_SET_CONNECT_SEL,0x1}, - /* Change default to ExtMic for recording */ - {0x1a, AC_VERB_SET_CONNECT_SEL,0x2}, {} }; @@ -1172,7 +1107,6 @@ static struct hda_verb cxt5047_hp_init_verbs[] = { {0x13, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, /* Record selector: Ext Mic */ {0x12, AC_VERB_SET_CONNECT_SEL,0x03}, - {0x1a, AC_VERB_SET_CONNECT_SEL,0x02}, {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AC_AMP_SET_INPUT|AC_AMP_SET_RIGHT|AC_AMP_SET_LEFT|0x17}, /* Speaker routing */ @@ -1242,14 +1176,6 @@ static struct snd_kcontrol_new cxt5047_test_mixer[] = { .get = conexant_mux_enum_get, .put = conexant_mux_enum_put, }, - /* Controls for GPIO pins, assuming they exist and are configured - * as outputs - */ - CXT_GPIO_DATA_SWITCH("GPIO pin 0", 0x01, 0x01), - CXT_GPIO_DATA_SWITCH("GPIO pin 1", 0x01, 0x02), - CXT_GPIO_DATA_SWITCH("GPIO pin 2", 0x01, 0x04), - CXT_GPIO_DATA_SWITCH("GPIO pin 3", 0x01, 0x08), - { } /* end */ }; diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index fba3cb11bc2a..a4ede27af021 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -74,6 +74,8 @@ enum { ALC260_HP_3013, ALC260_FUJITSU_S702X, ALC260_ACER, + ALC260_WILL, + ALC260_REPLACER_672V, #ifdef CONFIG_SND_DEBUG ALC260_TEST, #endif @@ -115,15 +117,28 @@ enum { ALC861VD_3ST, ALC861VD_3ST_DIG, ALC861VD_6ST_DIG, + ALC861VD_LENOVO, ALC861VD_AUTO, ALC861VD_MODEL_LAST, }; +/* ALC662 models */ +enum { + ALC662_3ST_2ch_DIG, + ALC662_3ST_6ch_DIG, + ALC662_3ST_6ch, + ALC662_5ST_DIG, + ALC662_LENOVO_101E, + ALC662_AUTO, + ALC662_MODEL_LAST, +}; + /* ALC882 models */ enum { ALC882_3ST_DIG, ALC882_6ST_DIG, ALC882_ARIMA, + ALC882_W2JC, ALC882_AUTO, ALC885_MACPRO, ALC882_MODEL_LAST, @@ -141,6 +156,7 @@ enum { ALC883_ACER, ALC883_MEDION, ALC883_LAPTOP_EAPD, + ALC883_LENOVO_101E_2ch, ALC883_AUTO, ALC883_MODEL_LAST, }; @@ -163,7 +179,7 @@ struct alc_spec { struct hda_pcm_stream *stream_analog_playback; struct hda_pcm_stream *stream_analog_capture; - char *stream_name_digital; /* digital PCM stream */ + char *stream_name_digital; /* digital PCM stream */ struct hda_pcm_stream *stream_digital_playback; struct hda_pcm_stream *stream_digital_capture; @@ -401,7 +417,7 @@ static int alc_pin_mode_put(struct snd_kcontrol *kcontrol, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00); - if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir)) + if (val < alc_pin_mode_min(dir) || val > alc_pin_mode_max(dir)) val = alc_pin_mode_min(dir); change = pinctl != alc_pin_mode_values[val]; @@ -460,7 +476,8 @@ static int alc_gpio_data_info(struct snd_kcontrol *kcontrol, uinfo->value.integer.min = 0; uinfo->value.integer.max = 1; return 0; -} +} + static int alc_gpio_data_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -520,7 +537,8 @@ static int alc_spdif_ctrl_info(struct snd_kcontrol *kcontrol, uinfo->value.integer.min = 0; uinfo->value.integer.max = 1; return 0; -} +} + static int alc_spdif_ctrl_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -592,7 +610,7 @@ static void setup_preset(struct alc_spec *spec, spec->multiout.hp_nid = preset->hp_nid; spec->num_mux_defs = preset->num_mux_defs; - if (! spec->num_mux_defs) + if (!spec->num_mux_defs) spec->num_mux_defs = 1; spec->input_mux = preset->input_mux; @@ -604,6 +622,90 @@ static void setup_preset(struct alc_spec *spec, spec->init_hook = preset->init_hook; } +/* Enable GPIO mask and set output */ +static struct hda_verb alc_gpio1_init_verbs[] = { + {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, + {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, + {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, + { } +}; + +static struct hda_verb alc_gpio2_init_verbs[] = { + {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, + {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, + {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, + { } +}; + +static struct hda_verb alc_gpio3_init_verbs[] = { + {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, + {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, + {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, + { } +}; + +/* 32-bit subsystem ID for BIOS loading in HD Audio codec. + * 31 ~ 16 : Manufacture ID + * 15 ~ 8 : SKU ID + * 7 ~ 0 : Assembly ID + * port-A --> pin 39/41, port-E --> pin 14/15, port-D --> pin 35/36 + */ +static void alc_subsystem_id(struct hda_codec *codec, + unsigned int porta, unsigned int porte, + unsigned int portd) +{ + unsigned int ass, tmp; + + ass = codec->subsystem_id; + if (!(ass & 1)) + return; + + /* Override */ + tmp = (ass & 0x38) >> 3; /* external Amp control */ + switch (tmp) { + case 1: + snd_hda_sequence_write(codec, alc_gpio1_init_verbs); + break; + case 3: + snd_hda_sequence_write(codec, alc_gpio2_init_verbs); + break; + case 7: + snd_hda_sequence_write(codec, alc_gpio3_init_verbs); + break; + case 5: + switch (codec->vendor_id) { + case 0x10ec0862: + case 0x10ec0660: + case 0x10ec0662: + case 0x10ec0267: + case 0x10ec0268: + snd_hda_codec_write(codec, 0x14, 0, + AC_VERB_SET_EAPD_BTLENABLE, 2); + snd_hda_codec_write(codec, 0x15, 0, + AC_VERB_SET_EAPD_BTLENABLE, 2); + return; + } + case 6: + if (ass & 4) { /* bit 2 : 0 = Desktop, 1 = Laptop */ + hda_nid_t port = 0; + tmp = (ass & 0x1800) >> 11; + switch (tmp) { + case 0: port = porta; break; + case 1: port = porte; break; + case 2: port = portd; break; + } + if (port) + snd_hda_codec_write(codec, port, 0, + AC_VERB_SET_EAPD_BTLENABLE, + 2); + } + snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); + snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_PROC_COEF, + (tmp == 5 ? 0x3040 : 0x3050)); + break; + } +} + /* * ALC880 3-stack model * @@ -801,7 +903,7 @@ static struct hda_channel_mode alc880_fivestack_modes[2] = { static hda_nid_t alc880_6st_dac_nids[4] = { /* front, rear, clfe, rear_surr */ 0x02, 0x03, 0x04, 0x05 -}; +}; static struct hda_input_mux alc880_6stack_capture_source = { .num_items = 4, @@ -1409,25 +1511,43 @@ static struct hda_verb alc880_beep_init_verbs[] = { }; /* toggle speaker-output according to the hp-jack state */ -static void alc880_uniwill_automute(struct hda_codec *codec) +static void alc880_uniwill_hp_automute(struct hda_codec *codec) { unsigned int present; + unsigned char bits; present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + bits = present ? 0x80 : 0; snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); + 0x80, bits); snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); + 0x80, bits); snd_hda_codec_amp_update(codec, 0x16, 0, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); + 0x80, bits); snd_hda_codec_amp_update(codec, 0x16, 1, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); + 0x80, bits); +} + +/* auto-toggle front mic */ +static void alc880_uniwill_mic_automute(struct hda_codec *codec) +{ + unsigned int present; + unsigned char bits; present = snd_hda_codec_read(codec, 0x18, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - snd_hda_codec_write(codec, 0x0b, 0, AC_VERB_SET_AMP_GAIN_MUTE, - 0x7000 | (0x01 << 8) | (present ? 0x80 : 0)); + bits = present ? 0x80 : 0; + snd_hda_codec_amp_update(codec, 0x0b, 0, HDA_INPUT, 1, + 0x80, bits); + snd_hda_codec_amp_update(codec, 0x0b, 1, HDA_INPUT, 1, + 0x80, bits); +} + +static void alc880_uniwill_automute(struct hda_codec *codec) +{ + alc880_uniwill_hp_automute(codec); + alc880_uniwill_mic_automute(codec); } static void alc880_uniwill_unsol_event(struct hda_codec *codec, @@ -1436,22 +1556,28 @@ static void alc880_uniwill_unsol_event(struct hda_codec *codec, /* Looks like the unsol event is incompatible with the standard * definition. 4bit tag is placed at 28 bit! */ - if ((res >> 28) == ALC880_HP_EVENT || - (res >> 28) == ALC880_MIC_EVENT) - alc880_uniwill_automute(codec); + switch (res >> 28) { + case ALC880_HP_EVENT: + alc880_uniwill_hp_automute(codec); + break; + case ALC880_MIC_EVENT: + alc880_uniwill_mic_automute(codec); + break; + } } static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec) { unsigned int present; + unsigned char bits; present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; - + bits = present ? 0x80 : 0; snd_hda_codec_amp_update(codec, 0x15, 0, HDA_INPUT, 0, - 0x80, present ? 0x80 : 0); + 0x80, bits); snd_hda_codec_amp_update(codec, 0x15, 1, HDA_INPUT, 0, - 0x80, present ? 0x80 : 0); + 0x80, bits); } static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec) @@ -1480,7 +1606,7 @@ static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec, */ if ((res >> 28) == ALC880_HP_EVENT) alc880_uniwill_p53_hp_automute(codec); - if ((res >> 28) == ALC880_DCVOL_EVENT) + if ((res >> 28) == ALC880_DCVOL_EVENT) alc880_uniwill_p53_dcvol_automute(codec); } @@ -1547,22 +1673,8 @@ static struct hda_verb alc880_pin_asus_init_verbs[] = { }; /* Enable GPIO mask and set output */ -static struct hda_verb alc880_gpio1_init_verbs[] = { - {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, - {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, - {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, - - { } -}; - -/* Enable GPIO mask and set output */ -static struct hda_verb alc880_gpio2_init_verbs[] = { - {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, - {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, - {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, - - { } -}; +#define alc880_gpio1_init_verbs alc_gpio1_init_verbs +#define alc880_gpio2_init_verbs alc_gpio2_init_verbs /* Clevo m520g init */ static struct hda_verb alc880_pin_clevo_init_verbs[] = { @@ -1734,13 +1846,15 @@ static struct hda_verb alc880_lg_init_verbs[] = { static void alc880_lg_automute(struct hda_codec *codec) { unsigned int present; + unsigned char bits; present = snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + bits = present ? 0x80 : 0; snd_hda_codec_amp_update(codec, 0x17, 0, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); + 0x80, bits); snd_hda_codec_amp_update(codec, 0x17, 1, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); + 0x80, bits); } static void alc880_lg_unsol_event(struct hda_codec *codec, unsigned int res) @@ -1810,13 +1924,15 @@ static struct hda_verb alc880_lg_lw_init_verbs[] = { static void alc880_lg_lw_automute(struct hda_codec *codec) { unsigned int present; + unsigned char bits; present = snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + bits = present ? 0x80 : 0; snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); + 0x80, bits); snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); + 0x80, bits); } static void alc880_lg_lw_unsol_event(struct hda_codec *codec, unsigned int res) @@ -1916,6 +2032,17 @@ static int alc880_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, return snd_hda_multi_out_dig_open(codec, &spec->multiout); } +static int alc880_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + unsigned int stream_tag, + unsigned int format, + struct snd_pcm_substream *substream) +{ + struct alc_spec *spec = codec->spec; + return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, + stream_tag, format, substream); +} + static int alc880_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, struct hda_codec *codec, struct snd_pcm_substream *substream) @@ -1984,7 +2111,8 @@ static struct hda_pcm_stream alc880_pcm_digital_playback = { /* NID is set in alc_build_pcms */ .ops = { .open = alc880_dig_playback_pcm_open, - .close = alc880_dig_playback_pcm_close + .close = alc880_dig_playback_pcm_close, + .prepare = alc880_dig_playback_pcm_prepare }, }; @@ -2075,7 +2203,7 @@ static void alc_free(struct hda_codec *codec) struct alc_spec *spec = codec->spec; unsigned int i; - if (! spec) + if (!spec) return; if (spec->kctl_alloc) { @@ -2477,7 +2605,8 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = { static struct alc_config_preset alc880_presets[] = { [ALC880_3ST] = { .mixers = { alc880_three_stack_mixer }, - .init_verbs = { alc880_volume_init_verbs, alc880_pin_3stack_init_verbs }, + .init_verbs = { alc880_volume_init_verbs, + alc880_pin_3stack_init_verbs }, .num_dacs = ARRAY_SIZE(alc880_dac_nids), .dac_nids = alc880_dac_nids, .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), @@ -2487,7 +2616,8 @@ static struct alc_config_preset alc880_presets[] = { }, [ALC880_3ST_DIG] = { .mixers = { alc880_three_stack_mixer }, - .init_verbs = { alc880_volume_init_verbs, alc880_pin_3stack_init_verbs }, + .init_verbs = { alc880_volume_init_verbs, + alc880_pin_3stack_init_verbs }, .num_dacs = ARRAY_SIZE(alc880_dac_nids), .dac_nids = alc880_dac_nids, .dig_out_nid = ALC880_DIGOUT_NID, @@ -2509,8 +2639,10 @@ static struct alc_config_preset alc880_presets[] = { .input_mux = &alc880_capture_source, }, [ALC880_5ST] = { - .mixers = { alc880_three_stack_mixer, alc880_five_stack_mixer}, - .init_verbs = { alc880_volume_init_verbs, alc880_pin_5stack_init_verbs }, + .mixers = { alc880_three_stack_mixer, + alc880_five_stack_mixer}, + .init_verbs = { alc880_volume_init_verbs, + alc880_pin_5stack_init_verbs }, .num_dacs = ARRAY_SIZE(alc880_dac_nids), .dac_nids = alc880_dac_nids, .num_channel_mode = ARRAY_SIZE(alc880_fivestack_modes), @@ -2518,8 +2650,10 @@ static struct alc_config_preset alc880_presets[] = { .input_mux = &alc880_capture_source, }, [ALC880_5ST_DIG] = { - .mixers = { alc880_three_stack_mixer, alc880_five_stack_mixer }, - .init_verbs = { alc880_volume_init_verbs, alc880_pin_5stack_init_verbs }, + .mixers = { alc880_three_stack_mixer, + alc880_five_stack_mixer }, + .init_verbs = { alc880_volume_init_verbs, + alc880_pin_5stack_init_verbs }, .num_dacs = ARRAY_SIZE(alc880_dac_nids), .dac_nids = alc880_dac_nids, .dig_out_nid = ALC880_DIGOUT_NID, @@ -2529,7 +2663,8 @@ static struct alc_config_preset alc880_presets[] = { }, [ALC880_6ST] = { .mixers = { alc880_six_stack_mixer }, - .init_verbs = { alc880_volume_init_verbs, alc880_pin_6stack_init_verbs }, + .init_verbs = { alc880_volume_init_verbs, + alc880_pin_6stack_init_verbs }, .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), .dac_nids = alc880_6st_dac_nids, .num_channel_mode = ARRAY_SIZE(alc880_sixstack_modes), @@ -2538,7 +2673,8 @@ static struct alc_config_preset alc880_presets[] = { }, [ALC880_6ST_DIG] = { .mixers = { alc880_six_stack_mixer }, - .init_verbs = { alc880_volume_init_verbs, alc880_pin_6stack_init_verbs }, + .init_verbs = { alc880_volume_init_verbs, + alc880_pin_6stack_init_verbs }, .num_dacs = ARRAY_SIZE(alc880_6st_dac_nids), .dac_nids = alc880_6st_dac_nids, .dig_out_nid = ALC880_DIGOUT_NID, @@ -2548,7 +2684,8 @@ static struct alc_config_preset alc880_presets[] = { }, [ALC880_W810] = { .mixers = { alc880_w810_base_mixer }, - .init_verbs = { alc880_volume_init_verbs, alc880_pin_w810_init_verbs, + .init_verbs = { alc880_volume_init_verbs, + alc880_pin_w810_init_verbs, alc880_gpio2_init_verbs }, .num_dacs = ARRAY_SIZE(alc880_w810_dac_nids), .dac_nids = alc880_w810_dac_nids, @@ -2559,7 +2696,8 @@ static struct alc_config_preset alc880_presets[] = { }, [ALC880_Z71V] = { .mixers = { alc880_z71v_mixer }, - .init_verbs = { alc880_volume_init_verbs, alc880_pin_z71v_init_verbs }, + .init_verbs = { alc880_volume_init_verbs, + alc880_pin_z71v_init_verbs }, .num_dacs = ARRAY_SIZE(alc880_z71v_dac_nids), .dac_nids = alc880_z71v_dac_nids, .dig_out_nid = ALC880_DIGOUT_NID, @@ -2570,7 +2708,8 @@ static struct alc_config_preset alc880_presets[] = { }, [ALC880_F1734] = { .mixers = { alc880_f1734_mixer }, - .init_verbs = { alc880_volume_init_verbs, alc880_pin_f1734_init_verbs }, + .init_verbs = { alc880_volume_init_verbs, + alc880_pin_f1734_init_verbs }, .num_dacs = ARRAY_SIZE(alc880_f1734_dac_nids), .dac_nids = alc880_f1734_dac_nids, .hp_nid = 0x02, @@ -2580,7 +2719,8 @@ static struct alc_config_preset alc880_presets[] = { }, [ALC880_ASUS] = { .mixers = { alc880_asus_mixer }, - .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs, + .init_verbs = { alc880_volume_init_verbs, + alc880_pin_asus_init_verbs, alc880_gpio1_init_verbs }, .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), .dac_nids = alc880_asus_dac_nids, @@ -2591,7 +2731,8 @@ static struct alc_config_preset alc880_presets[] = { }, [ALC880_ASUS_DIG] = { .mixers = { alc880_asus_mixer }, - .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs, + .init_verbs = { alc880_volume_init_verbs, + alc880_pin_asus_init_verbs, alc880_gpio1_init_verbs }, .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), .dac_nids = alc880_asus_dac_nids, @@ -2603,7 +2744,8 @@ static struct alc_config_preset alc880_presets[] = { }, [ALC880_ASUS_DIG2] = { .mixers = { alc880_asus_mixer }, - .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs, + .init_verbs = { alc880_volume_init_verbs, + alc880_pin_asus_init_verbs, alc880_gpio2_init_verbs }, /* use GPIO2 */ .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), .dac_nids = alc880_asus_dac_nids, @@ -2615,7 +2757,8 @@ static struct alc_config_preset alc880_presets[] = { }, [ALC880_ASUS_W1V] = { .mixers = { alc880_asus_mixer, alc880_asus_w1v_mixer }, - .init_verbs = { alc880_volume_init_verbs, alc880_pin_asus_init_verbs, + .init_verbs = { alc880_volume_init_verbs, + alc880_pin_asus_init_verbs, alc880_gpio1_init_verbs }, .num_dacs = ARRAY_SIZE(alc880_asus_dac_nids), .dac_nids = alc880_asus_dac_nids, @@ -2664,7 +2807,7 @@ static struct alc_config_preset alc880_presets[] = { .init_hook = alc880_uniwill_p53_hp_automute, }, [ALC880_FUJITSU] = { - .mixers = { alc880_fujitsu_mixer, + .mixers = { alc880_fujitsu_mixer, alc880_pcbeep_mixer, }, .init_verbs = { alc880_volume_init_verbs, alc880_uniwill_p53_init_verbs, @@ -2707,7 +2850,7 @@ static struct alc_config_preset alc880_presets[] = { .mixers = { alc880_lg_lw_mixer }, .init_verbs = { alc880_volume_init_verbs, alc880_lg_lw_init_verbs }, - .num_dacs = 1, + .num_dacs = 1, .dac_nids = alc880_dac_nids, .dig_out_nid = ALC880_DIGOUT_NID, .num_channel_mode = ARRAY_SIZE(alc880_2_jack_modes), @@ -2749,18 +2892,21 @@ static struct snd_kcontrol_new alc880_control_templates[] = { }; /* add dynamic controls */ -static int add_control(struct alc_spec *spec, int type, const char *name, unsigned long val) +static int add_control(struct alc_spec *spec, int type, const char *name, + unsigned long val) { struct snd_kcontrol_new *knew; if (spec->num_kctl_used >= spec->num_kctl_alloc) { int num = spec->num_kctl_alloc + NUM_CONTROL_ALLOC; - knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); /* array + terminator */ - if (! knew) + /* array + terminator */ + knew = kcalloc(num + 1, sizeof(*knew), GFP_KERNEL); + if (!knew) return -ENOMEM; if (spec->kctl_alloc) { - memcpy(knew, spec->kctl_alloc, sizeof(*knew) * spec->num_kctl_alloc); + memcpy(knew, spec->kctl_alloc, + sizeof(*knew) * spec->num_kctl_alloc); kfree(spec->kctl_alloc); } spec->kctl_alloc = knew; @@ -2770,7 +2916,7 @@ static int add_control(struct alc_spec *spec, int type, const char *name, unsign knew = &spec->kctl_alloc[spec->num_kctl_used]; *knew = alc880_control_templates[type]; knew->name = kstrdup(name, GFP_KERNEL); - if (! knew->name) + if (!knew->name) return -ENOMEM; knew->private_value = val; spec->num_kctl_used++; @@ -2790,7 +2936,8 @@ static int add_control(struct alc_spec *spec, int type, const char *name, unsign #define ALC880_PIN_CD_NID 0x1c /* fill in the dac_nids table from the parsed pin configuration */ -static int alc880_auto_fill_dac_nids(struct alc_spec *spec, const struct auto_pin_cfg *cfg) +static int alc880_auto_fill_dac_nids(struct alc_spec *spec, + const struct auto_pin_cfg *cfg) { hda_nid_t nid; int assigned[4]; @@ -2815,8 +2962,9 @@ static int alc880_auto_fill_dac_nids(struct alc_spec *spec, const struct auto_pi continue; /* search for an empty channel */ for (j = 0; j < cfg->line_outs; j++) { - if (! assigned[j]) { - spec->multiout.dac_nids[i] = alc880_idx_to_dac(j); + if (!assigned[j]) { + spec->multiout.dac_nids[i] = + alc880_idx_to_dac(j); assigned[j] = 1; break; } @@ -2831,36 +2979,54 @@ static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg) { char name[32]; - static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" }; + static const char *chname[4] = { + "Front", "Surround", NULL /*CLFE*/, "Side" + }; hda_nid_t nid; int i, err; for (i = 0; i < cfg->line_outs; i++) { - if (! spec->multiout.dac_nids[i]) + if (!spec->multiout.dac_nids[i]) continue; nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i])); if (i == 2) { /* Center/LFE */ - if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Center Playback Volume", - HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_VOL, + "Center Playback Volume", + HDA_COMPOSE_AMP_VAL(nid, 1, 0, + HDA_OUTPUT)); + if (err < 0) return err; - if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "LFE Playback Volume", - HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_VOL, + "LFE Playback Volume", + HDA_COMPOSE_AMP_VAL(nid, 2, 0, + HDA_OUTPUT)); + if (err < 0) return err; - if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "Center Playback Switch", - HDA_COMPOSE_AMP_VAL(nid, 1, 2, HDA_INPUT))) < 0) + err = add_control(spec, ALC_CTL_BIND_MUTE, + "Center Playback Switch", + HDA_COMPOSE_AMP_VAL(nid, 1, 2, + HDA_INPUT)); + if (err < 0) return err; - if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "LFE Playback Switch", - HDA_COMPOSE_AMP_VAL(nid, 2, 2, HDA_INPUT))) < 0) + err = add_control(spec, ALC_CTL_BIND_MUTE, + "LFE Playback Switch", + HDA_COMPOSE_AMP_VAL(nid, 2, 2, + HDA_INPUT)); + if (err < 0) return err; } else { sprintf(name, "%s Playback Volume", chname[i]); - if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, - HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_VOL, name, + HDA_COMPOSE_AMP_VAL(nid, 3, 0, + HDA_OUTPUT)); + if (err < 0) return err; sprintf(name, "%s Playback Switch", chname[i]); - if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name, - HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0) + err = add_control(spec, ALC_CTL_BIND_MUTE, name, + HDA_COMPOSE_AMP_VAL(nid, 3, 2, + HDA_INPUT)); + if (err < 0) return err; } } @@ -2875,51 +3041,57 @@ static int alc880_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, int err; char name[32]; - if (! pin) + if (!pin) return 0; if (alc880_is_fixed_pin(pin)) { nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); /* specify the DAC as the extra output */ - if (! spec->multiout.hp_nid) + if (!spec->multiout.hp_nid) spec->multiout.hp_nid = nid; else spec->multiout.extra_out_nid[0] = nid; /* control HP volume/switch on the output mixer amp */ nid = alc880_idx_to_mixer(alc880_fixed_pin_idx(pin)); sprintf(name, "%s Playback Volume", pfx); - if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, - HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_VOL, name, + HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); + if (err < 0) return err; sprintf(name, "%s Playback Switch", pfx); - if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name, - HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT))) < 0) + err = add_control(spec, ALC_CTL_BIND_MUTE, name, + HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT)); + if (err < 0) return err; } else if (alc880_is_multi_pin(pin)) { /* set manual connection */ /* we have only a switch on HP-out PIN */ sprintf(name, "%s Playback Switch", pfx); - if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, - HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, + HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); + if (err < 0) return err; } return 0; } /* create input playback/capture controls for the given pin */ -static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, const char *ctlname, +static int new_analog_input(struct alc_spec *spec, hda_nid_t pin, + const char *ctlname, int idx, hda_nid_t mix_nid) { char name[32]; int err; sprintf(name, "%s Playback Volume", ctlname); - if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, - HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_VOL, name, + HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); + if (err < 0) return err; sprintf(name, "%s Playback Switch", ctlname); - if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, - HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, + HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT)); + if (err < 0) return err; return 0; } @@ -2939,8 +3111,10 @@ static int alc880_auto_create_analog_input_ctls(struct alc_spec *spec, idx, 0x0b); if (err < 0) return err; - imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; - imux->items[imux->num_items].index = alc880_input_pin_idx(cfg->input_pins[i]); + imux->items[imux->num_items].label = + auto_pin_cfg_labels[i]; + imux->items[imux->num_items].index = + alc880_input_pin_idx(cfg->input_pins[i]); imux->num_items++; } } @@ -2952,8 +3126,10 @@ static void alc880_auto_set_output_and_unmute(struct hda_codec *codec, int dac_idx) { /* set as output */ - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, + pin_type); + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, + AMP_OUT_UNMUTE); /* need the manual connection? */ if (alc880_is_multi_pin(nid)) { struct alc_spec *spec = codec->spec; @@ -2964,14 +3140,24 @@ static void alc880_auto_set_output_and_unmute(struct hda_codec *codec, } } +static int get_pin_type(int line_out_type) +{ + if (line_out_type == AUTO_PIN_HP_OUT) + return PIN_HP; + else + return PIN_OUT; +} + static void alc880_auto_init_multi_out(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; int i; - + + alc_subsystem_id(codec, 0x15, 0x1b, 0x14); for (i = 0; i < spec->autocfg.line_outs; i++) { hda_nid_t nid = spec->autocfg.line_out_pins[i]; - alc880_auto_set_output_and_unmute(codec, nid, PIN_OUT, i); + int pin_type = get_pin_type(spec->autocfg.line_out_type); + alc880_auto_set_output_and_unmute(codec, nid, pin_type, i); } } @@ -2996,37 +3182,52 @@ static void alc880_auto_init_analog_input(struct hda_codec *codec) for (i = 0; i < AUTO_PIN_LAST; i++) { hda_nid_t nid = spec->autocfg.input_pins[i]; if (alc880_is_input_pin(nid)) { - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, - i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN); + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, + i <= AUTO_PIN_FRONT_MIC ? + PIN_VREF80 : PIN_IN); if (nid != ALC880_PIN_CD_NID) - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); } } } /* parse the BIOS configuration and set up the alc_spec */ -/* return 1 if successful, 0 if the proper config is not found, or a negative error code */ +/* return 1 if successful, 0 if the proper config is not found, + * or a negative error code + */ static int alc880_parse_auto_config(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; int err; static hda_nid_t alc880_ignore[] = { 0x1d, 0 }; - if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, - alc880_ignore)) < 0) + err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, + alc880_ignore); + if (err < 0) return err; - if (! spec->autocfg.line_outs) + if (!spec->autocfg.line_outs) return 0; /* can't find valid BIOS pin config */ - if ((err = alc880_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 || - (err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || - (err = alc880_auto_create_extra_out(spec, - spec->autocfg.speaker_pins[0], - "Speaker")) < 0 || - (err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], - "Headphone")) < 0 || - (err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) + err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); + if (err < 0) + return err; + err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); + if (err < 0) + return err; + err = alc880_auto_create_extra_out(spec, + spec->autocfg.speaker_pins[0], + "Speaker"); + if (err < 0) + return err; + err = alc880_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], + "Headphone"); + if (err < 0) + return err; + err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg); + if (err < 0) return err; spec->multiout.max_channels = spec->multiout.num_dacs * 2; @@ -3086,7 +3287,7 @@ static int patch_alc880(struct hda_codec *codec) if (err < 0) { alc_free(codec); return err; - } else if (! err) { + } else if (!err) { printk(KERN_INFO "hda_codec: Cannot set up configuration " "from BIOS. Using 3-stack mode...\n"); @@ -3105,14 +3306,16 @@ static int patch_alc880(struct hda_codec *codec) spec->stream_digital_playback = &alc880_pcm_digital_playback; spec->stream_digital_capture = &alc880_pcm_digital_capture; - if (! spec->adc_nids && spec->input_mux) { + if (!spec->adc_nids && spec->input_mux) { /* check whether NID 0x07 is valid */ unsigned int wcap = get_wcaps(codec, alc880_adc_nids[0]); - wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */ + /* get type */ + wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; if (wcap != AC_WID_AUD_IN) { spec->adc_nids = alc880_adc_nids_alt; spec->num_adc_nids = ARRAY_SIZE(alc880_adc_nids_alt); - spec->mixers[spec->num_mixers] = alc880_capture_alt_mixer; + spec->mixers[spec->num_mixers] = + alc880_capture_alt_mixer; spec->num_mixers++; } else { spec->adc_nids = alc880_adc_nids; @@ -3254,7 +3457,7 @@ static struct snd_kcontrol_new alc260_base_output_mixer[] = { HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), { } /* end */ -}; +}; static struct snd_kcontrol_new alc260_input_mixer[] = { HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), @@ -3349,6 +3552,42 @@ static struct snd_kcontrol_new alc260_acer_mixer[] = { { } /* end */ }; +/* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12, + * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17. + */ +static struct snd_kcontrol_new alc260_will_mixer[] = { + HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), + ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), + HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), + HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), + ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), + HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), + HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), + HDA_CODEC_VOLUME("Beep Playback Volume", 0x07, 0x05, HDA_INPUT), + HDA_CODEC_MUTE("Beep Playback Switch", 0x07, 0x05, HDA_INPUT), + { } /* end */ +}; + +/* Replacer 672V ALC260 pin usage: Mic jack = 0x12, + * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f. + */ +static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = { + HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x07, 0x0, HDA_INPUT), + ALC_PIN_MODE("Mic Jack Mode", 0x12, ALC_PIN_DIR_IN), + HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x07, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("ATATI Mic Playback Switch", 0x07, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), + HDA_CODEC_MUTE("Line Playback Switch", 0x07, 0x02, HDA_INPUT), + ALC_PIN_MODE("Line Jack Mode", 0x14, ALC_PIN_DIR_INOUT), + { } /* end */ +}; + /* capture mixer elements */ static struct snd_kcontrol_new alc260_capture_mixer[] = { HDA_CODEC_VOLUME("Capture Volume", 0x04, 0x0, HDA_INPUT), @@ -3434,7 +3673,9 @@ static struct hda_verb alc260_init_verbs[] = { {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* unmute LINE-2 out pin */ {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */ + /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & + * Line In 2 = 0x03 + */ /* mute CD */ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, /* mute Line In */ @@ -3482,7 +3723,9 @@ static struct hda_verb alc260_hp_init_verbs[] = { {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, /* mute pin widget amp left and right (no gain on this amp) */ {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, - /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */ + /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & + * Line In 2 = 0x03 + */ /* unmute CD */ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /* unmute Line In */ @@ -3530,7 +3773,9 @@ static struct hda_verb alc260_hp_3013_init_verbs[] = { {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, /* mute pin widget amp left and right (no gain on this amp) */ {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, - /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & Line In 2 = 0x03 */ + /* Amp Indexes: CD = 0x04, Line In 1 = 0x02, Mic 1 = 0x00 & + * Line In 2 = 0x03 + */ /* unmute CD */ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x04 << 8))}, /* unmute Line In */ @@ -3680,7 +3925,9 @@ static struct hda_verb alc260_acer_init_verbs[] = { {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - /* Unmute Line-out pin widget amp left and right (no equiv mixer ctrl) */ + /* Unmute Line-out pin widget amp left and right + * (no equiv mixer ctrl) + */ {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Unmute mono pin widget amp output (no equiv mixer ctrl) */ {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, @@ -3719,6 +3966,55 @@ static struct hda_verb alc260_acer_init_verbs[] = { { } }; +static struct hda_verb alc260_will_verbs[] = { + {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00}, + {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, + {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, + {0x1a, AC_VERB_SET_COEF_INDEX, 0x07}, + {0x1a, AC_VERB_SET_PROC_COEF, 0x3040}, + {} +}; + +static struct hda_verb alc260_replacer_672v_verbs[] = { + {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, + {0x1a, AC_VERB_SET_COEF_INDEX, 0x07}, + {0x1a, AC_VERB_SET_PROC_COEF, 0x3050}, + + {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, + {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, + {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, + + {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, + {} +}; + +/* toggle speaker-output according to the hp-jack state */ +static void alc260_replacer_672v_automute(struct hda_codec *codec) +{ + unsigned int present; + + /* speaker --> GPIO Data 0, hp or spdif --> GPIO data 1 */ + present = snd_hda_codec_read(codec, 0x0f, 0, + AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + if (present) { + snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 1); + snd_hda_codec_write(codec, 0x0f, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP); + } else { + snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0); + snd_hda_codec_write(codec, 0x0f, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); + } +} + +static void alc260_replacer_672v_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + if ((res >> 26) == ALC880_HP_EVENT) + alc260_replacer_672v_automute(codec); +} + /* Test configuration for debugging, modelled after the ALC880 test * configuration. */ @@ -3946,10 +4242,12 @@ static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid, return 0; /* N/A */ snprintf(name, sizeof(name), "%s Playback Volume", pfx); - if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val)) < 0) + err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val); + if (err < 0) return err; snprintf(name, sizeof(name), "%s Playback Switch", pfx); - if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val)) < 0) + err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, sw_val); + if (err < 0) return err; return 1; } @@ -3985,7 +4283,7 @@ static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec, if (err < 0) return err; } - return 0; + return 0; } /* create playback/capture controls for input pins */ @@ -3999,20 +4297,24 @@ static int alc260_auto_create_analog_input_ctls(struct alc_spec *spec, if (cfg->input_pins[i] >= 0x12) { idx = cfg->input_pins[i] - 0x12; err = new_analog_input(spec, cfg->input_pins[i], - auto_pin_cfg_labels[i], idx, 0x07); + auto_pin_cfg_labels[i], idx, + 0x07); if (err < 0) return err; - imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; + imux->items[imux->num_items].label = + auto_pin_cfg_labels[i]; imux->items[imux->num_items].index = idx; imux->num_items++; } - if ((cfg->input_pins[i] >= 0x0f) && (cfg->input_pins[i] <= 0x10)){ + if (cfg->input_pins[i] >= 0x0f && cfg->input_pins[i] <= 0x10){ idx = cfg->input_pins[i] - 0x09; err = new_analog_input(spec, cfg->input_pins[i], - auto_pin_cfg_labels[i], idx, 0x07); + auto_pin_cfg_labels[i], idx, + 0x07); if (err < 0) return err; - imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; + imux->items[imux->num_items].label = + auto_pin_cfg_labels[i]; imux->items[imux->num_items].index = idx; imux->num_items++; } @@ -4025,14 +4327,15 @@ static void alc260_auto_set_output_and_unmute(struct hda_codec *codec, int sel_idx) { /* set as output */ - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, + pin_type); + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, + AMP_OUT_UNMUTE); /* need the manual connection? */ if (nid >= 0x12) { int idx = nid - 0x12; snd_hda_codec_write(codec, idx + 0x0b, 0, AC_VERB_SET_CONNECT_SEL, sel_idx); - } } @@ -4041,9 +4344,12 @@ static void alc260_auto_init_multi_out(struct hda_codec *codec) struct alc_spec *spec = codec->spec; hda_nid_t nid; - nid = spec->autocfg.line_out_pins[0]; - if (nid) - alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0); + alc_subsystem_id(codec, 0x10, 0x15, 0x0f); + nid = spec->autocfg.line_out_pins[0]; + if (nid) { + int pin_type = get_pin_type(spec->autocfg.line_out_type); + alc260_auto_set_output_and_unmute(codec, nid, pin_type, 0); + } nid = spec->autocfg.speaker_pins[0]; if (nid) @@ -4051,8 +4357,8 @@ static void alc260_auto_init_multi_out(struct hda_codec *codec) nid = spec->autocfg.hp_pins[0]; if (nid) - alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0); -} + alc260_auto_set_output_and_unmute(codec, nid, PIN_HP, 0); +} #define ALC260_PIN_CD_NID 0x16 static void alc260_auto_init_analog_input(struct hda_codec *codec) @@ -4063,10 +4369,13 @@ static void alc260_auto_init_analog_input(struct hda_codec *codec) for (i = 0; i < AUTO_PIN_LAST; i++) { hda_nid_t nid = spec->autocfg.input_pins[i]; if (nid >= 0x12) { - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, - i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN); + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, + i <= AUTO_PIN_FRONT_MIC ? + PIN_VREF80 : PIN_IN); if (nid != ALC260_PIN_CD_NID) - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); } } @@ -4086,8 +4395,8 @@ static struct hda_verb alc260_volume_init_verbs[] = { /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback * mixer widget - * Note: PASD motherboards uses the Line In 2 as the input for front panel - * mic (mic 2) + * Note: PASD motherboards uses the Line In 2 as the input for + * front panel mic (mic 2) */ /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, @@ -4122,14 +4431,17 @@ static int alc260_parse_auto_config(struct hda_codec *codec) int err; static hda_nid_t alc260_ignore[] = { 0x17, 0 }; - if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, - alc260_ignore)) < 0) + err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, + alc260_ignore); + if (err < 0) return err; - if ((err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0) + err = alc260_auto_create_multi_out_ctls(spec, &spec->autocfg); + if (err < 0) return err; - if (! spec->kctl_alloc) + if (!spec->kctl_alloc) return 0; /* can't find valid BIOS pin config */ - if ((err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) + err = alc260_auto_create_analog_input_ctls(spec, &spec->autocfg); + if (err < 0) return err; spec->multiout.max_channels = 2; @@ -4177,6 +4489,8 @@ static const char *alc260_models[ALC260_MODEL_LAST] = { [ALC260_HP_3013] = "hp-3013", [ALC260_FUJITSU_S702X] = "fujitsu", [ALC260_ACER] = "acer", + [ALC260_WILL] = "will", + [ALC260_REPLACER_672V] = "replacer", #ifdef CONFIG_SND_DEBUG [ALC260_TEST] = "test", #endif @@ -4200,6 +4514,8 @@ static struct snd_pci_quirk alc260_cfg_tbl[] = { SND_PCI_QUIRK(0x104d, 0x81cd, "Sony VAIO", ALC260_BASIC), SND_PCI_QUIRK(0x10cf, 0x1326, "Fujitsu S702X", ALC260_FUJITSU_S702X), SND_PCI_QUIRK(0x152d, 0x0729, "CTL U553W", ALC260_BASIC), + SND_PCI_QUIRK(0x1631, 0xc017, "PB V7900", ALC260_WILL), + SND_PCI_QUIRK(0x161f, 0x2057, "Replacer 672V", ALC260_REPLACER_672V), {} }; @@ -4270,6 +4586,34 @@ static struct alc_config_preset alc260_presets[] = { .num_mux_defs = ARRAY_SIZE(alc260_acer_capture_sources), .input_mux = alc260_acer_capture_sources, }, + [ALC260_WILL] = { + .mixers = { alc260_will_mixer, + alc260_capture_mixer }, + .init_verbs = { alc260_init_verbs, alc260_will_verbs }, + .num_dacs = ARRAY_SIZE(alc260_dac_nids), + .dac_nids = alc260_dac_nids, + .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), + .adc_nids = alc260_adc_nids, + .dig_out_nid = ALC260_DIGOUT_NID, + .num_channel_mode = ARRAY_SIZE(alc260_modes), + .channel_mode = alc260_modes, + .input_mux = &alc260_capture_source, + }, + [ALC260_REPLACER_672V] = { + .mixers = { alc260_replacer_672v_mixer, + alc260_capture_mixer }, + .init_verbs = { alc260_init_verbs, alc260_replacer_672v_verbs }, + .num_dacs = ARRAY_SIZE(alc260_dac_nids), + .dac_nids = alc260_dac_nids, + .num_adc_nids = ARRAY_SIZE(alc260_adc_nids), + .adc_nids = alc260_adc_nids, + .dig_out_nid = ALC260_DIGOUT_NID, + .num_channel_mode = ARRAY_SIZE(alc260_modes), + .channel_mode = alc260_modes, + .input_mux = &alc260_capture_source, + .unsol_event = alc260_replacer_672v_unsol_event, + .init_hook = alc260_replacer_672v_automute, + }, #ifdef CONFIG_SND_DEBUG [ALC260_TEST] = { .mixers = { alc260_test_mixer, @@ -4313,7 +4657,7 @@ static int patch_alc260(struct hda_codec *codec) if (err < 0) { alc_free(codec); return err; - } else if (! err) { + } else if (!err) { printk(KERN_INFO "hda_codec: Cannot set up configuration " "from BIOS. Using base mode...\n"); @@ -4382,7 +4726,8 @@ static struct hda_input_mux alc882_capture_source = { #define alc882_mux_enum_info alc_mux_enum_info #define alc882_mux_enum_get alc_mux_enum_get -static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct alc_spec *spec = codec->spec; @@ -4396,7 +4741,7 @@ static int alc882_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ele idx = ucontrol->value.enumerated.item[0]; if (idx >= imux->num_items) idx = imux->num_items - 1; - if (*cur_val == idx && ! codec->in_resume) + if (*cur_val == idx && !codec->in_resume) return 0; for (i = 0; i < imux->num_items; i++) { unsigned int v = (i == idx) ? 0x7000 : 0x7080; @@ -4464,6 +4809,21 @@ static struct snd_kcontrol_new alc882_base_mixer[] = { { } /* end */ }; +static struct snd_kcontrol_new alc882_w2jc_mixer[] = { + HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), + HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), + HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), + HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), + HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), + HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), + { } /* end */ +}; + static struct snd_kcontrol_new alc882_chmode_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -4559,7 +4919,7 @@ static struct hda_verb alc882_eapd_verbs[] = { /* change to EAPD mode */ {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, - { } + { } }; /* Mac Pro test */ @@ -4624,6 +4984,7 @@ static struct hda_verb alc882_macpro_init_verbs[] = { { } }; + static void alc882_gpio_mute(struct hda_codec *codec, int pin, int muted) { unsigned int gpiostate, gpiomask, gpiodir; @@ -4672,8 +5033,8 @@ static struct hda_verb alc882_auto_init_verbs[] = { /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback * mixer widget - * Note: PASD motherboards uses the Line In 2 as the input for front panel - * mic (mic 2) + * Note: PASD motherboards uses the Line In 2 as the input for + * front panel mic (mic 2) */ /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, @@ -4782,6 +5143,7 @@ static const char *alc882_models[ALC882_MODEL_LAST] = { [ALC882_3ST_DIG] = "3stack-dig", [ALC882_6ST_DIG] = "6stack-dig", [ALC882_ARIMA] = "arima", + [ALC882_W2JC] = "w2jc", [ALC885_MACPRO] = "macpro", [ALC882_AUTO] = "auto", }; @@ -4792,6 +5154,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = { SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC882_6ST_DIG), SND_PCI_QUIRK(0x161f, 0x2054, "Arima W820", ALC882_ARIMA), SND_PCI_QUIRK(0x1043, 0x81d8, "Asus P5WD", ALC882_6ST_DIG), + SND_PCI_QUIRK(0x1043, 0x1971, "Asus W2JC", ALC882_W2JC), {} }; @@ -4828,6 +5191,18 @@ static struct alc_config_preset alc882_presets[] = { .channel_mode = alc882_sixstack_modes, .input_mux = &alc882_capture_source, }, + [ALC882_W2JC] = { + .mixers = { alc882_w2jc_mixer, alc882_chmode_mixer }, + .init_verbs = { alc882_init_verbs, alc882_eapd_verbs, + alc880_gpio1_init_verbs }, + .num_dacs = ARRAY_SIZE(alc882_dac_nids), + .dac_nids = alc882_dac_nids, + .num_channel_mode = ARRAY_SIZE(alc880_threestack_modes), + .channel_mode = alc880_threestack_modes, + .need_dac_fix = 1, + .input_mux = &alc882_capture_source, + .dig_out_nid = ALC882_DIGOUT_NID, + }, [ALC885_MACPRO] = { .mixers = { alc882_macpro_mixer }, .init_verbs = { alc882_macpro_init_verbs }, @@ -4851,15 +5226,17 @@ static void alc882_auto_set_output_and_unmute(struct hda_codec *codec, { /* set as output */ struct alc_spec *spec = codec->spec; - int idx; - + int idx; + if (spec->multiout.dac_nids[dac_idx] == 0x25) idx = 4; else idx = spec->multiout.dac_nids[dac_idx] - 2; - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, + pin_type); + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, + AMP_OUT_UNMUTE); snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, idx); } @@ -4869,10 +5246,13 @@ static void alc882_auto_init_multi_out(struct hda_codec *codec) struct alc_spec *spec = codec->spec; int i; + alc_subsystem_id(codec, 0x15, 0x1b, 0x14); for (i = 0; i <= HDA_SIDE; i++) { - hda_nid_t nid = spec->autocfg.line_out_pins[i]; + hda_nid_t nid = spec->autocfg.line_out_pins[i]; + int pin_type = get_pin_type(spec->autocfg.line_out_type); if (nid) - alc882_auto_set_output_and_unmute(codec, nid, PIN_OUT, i); + alc882_auto_set_output_and_unmute(codec, nid, pin_type, + i); } } @@ -4883,7 +5263,8 @@ static void alc882_auto_init_hp_out(struct hda_codec *codec) pin = spec->autocfg.hp_pins[0]; if (pin) /* connect to front */ - alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); /* use dac 0 */ + /* use dac 0 */ + alc882_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); } #define alc882_is_input_pin(nid) alc880_is_input_pin(nid) @@ -4897,10 +5278,13 @@ static void alc882_auto_init_analog_input(struct hda_codec *codec) for (i = 0; i < AUTO_PIN_LAST; i++) { hda_nid_t nid = spec->autocfg.input_pins[i]; if (alc882_is_input_pin(nid)) { - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, - i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN); + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, + i <= AUTO_PIN_FRONT_MIC ? + PIN_VREF80 : PIN_IN); if (nid != ALC882_PIN_CD_NID) - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); } } @@ -4962,7 +5346,7 @@ static int patch_alc882(struct hda_codec *codec) if (err < 0) { alc_free(codec); return err; - } else if (! err) { + } else if (!err) { printk(KERN_INFO "hda_codec: Cannot set up configuration " "from BIOS. Using base mode...\n"); @@ -4986,14 +5370,16 @@ static int patch_alc882(struct hda_codec *codec) spec->stream_digital_playback = &alc882_pcm_digital_playback; spec->stream_digital_capture = &alc882_pcm_digital_capture; - if (! spec->adc_nids && spec->input_mux) { + if (!spec->adc_nids && spec->input_mux) { /* check whether NID 0x07 is valid */ unsigned int wcap = get_wcaps(codec, 0x07); - wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */ + /* get type */ + wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; if (wcap != AC_WID_AUD_IN) { spec->adc_nids = alc882_adc_nids_alt; spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt); - spec->mixers[spec->num_mixers] = alc882_capture_alt_mixer; + spec->mixers[spec->num_mixers] = + alc882_capture_alt_mixer; spec->num_mixers++; } else { spec->adc_nids = alc882_adc_nids; @@ -5033,6 +5419,7 @@ static hda_nid_t alc883_adc_nids[2] = { /* ADC1-2 */ 0x08, 0x09, }; + /* input MUX */ /* FIXME: should be a matrix-type input source selection */ @@ -5045,6 +5432,15 @@ static struct hda_input_mux alc883_capture_source = { { "CD", 0x4 }, }, }; + +static struct hda_input_mux alc883_lenovo_101e_capture_source = { + .num_items = 2, + .items = { + { "Mic", 0x1 }, + { "Line", 0x2 }, + }, +}; + #define alc883_mux_enum_info alc_mux_enum_info #define alc883_mux_enum_get alc_mux_enum_get @@ -5063,7 +5459,7 @@ static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol, idx = ucontrol->value.enumerated.item[0]; if (idx >= imux->num_items) idx = imux->num_items - 1; - if (*cur_val == idx && ! codec->in_resume) + if (*cur_val == idx && !codec->in_resume) return 0; for (i = 0; i < imux->num_items; i++) { unsigned int v = (i == idx) ? 0x7000 : 0x7080; @@ -5073,6 +5469,7 @@ static int alc883_mux_enum_put(struct snd_kcontrol *kcontrol, *cur_val = idx; return 1; } + /* * 2ch mode */ @@ -5325,7 +5722,7 @@ static struct snd_kcontrol_new alc883_tagra_mixer[] = { .put = alc883_mux_enum_put, }, { } /* end */ -}; +}; static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), @@ -5350,7 +5747,30 @@ static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = { .put = alc883_mux_enum_put, }, { } /* end */ -}; +}; + +static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = { + HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), + HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("iSpeaker Playback Switch", 0x0d, 2, HDA_INPUT), + HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + /* .name = "Capture Source", */ + .name = "Input Source", + .count = 1, + .info = alc883_mux_enum_info, + .get = alc883_mux_enum_get, + .put = alc883_mux_enum_put, + }, + { } /* end */ +}; static struct snd_kcontrol_new alc883_chmode_mixer[] = { { @@ -5452,10 +5872,17 @@ static struct hda_verb alc883_tagra_verbs[] = { {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, - {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, - {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, - {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, + {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, + {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, + {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, + + { } /* end */ +}; +static struct hda_verb alc883_lenovo_101e_verbs[] = { + {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, + {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN}, + {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN}, { } /* end */ }; @@ -5463,14 +5890,17 @@ static struct hda_verb alc883_tagra_verbs[] = { static void alc883_tagra_automute(struct hda_codec *codec) { unsigned int present; + unsigned char bits; present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + bits = present ? 0x80 : 0; snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); + 0x80, bits); snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0, - 0x80, present ? 0x80 : 0); - snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA, present ? 1 : 3); + 0x80, bits); + snd_hda_codec_write(codec, 1, 0, AC_VERB_SET_GPIO_DATA, + present ? 1 : 3); } static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res) @@ -5479,6 +5909,47 @@ static void alc883_tagra_unsol_event(struct hda_codec *codec, unsigned int res) alc883_tagra_automute(codec); } +static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec) +{ + unsigned int present; + unsigned char bits; + + present = snd_hda_codec_read(codec, 0x14, 0, + AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + bits = present ? 0x80 : 0; + snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, + 0x80, bits); + snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, + 0x80, bits); +} + +static void alc883_lenovo_101e_all_automute(struct hda_codec *codec) +{ + unsigned int present; + unsigned char bits; + + present = snd_hda_codec_read(codec, 0x1b, 0, + AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + bits = present ? 0x80 : 0; + snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, + 0x80, bits); + snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, + 0x80, bits); + snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, + 0x80, bits); + snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, + 0x80, bits); +} + +static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + if ((res >> 26) == ALC880_HP_EVENT) + alc883_lenovo_101e_all_automute(codec); + if ((res >> 26) == ALC880_FRONT_EVENT) + alc883_lenovo_101e_ispeaker_automute(codec); +} + /* * generic initialization of ADC, input mixers and output mixers */ @@ -5493,8 +5964,8 @@ static struct hda_verb alc883_auto_init_verbs[] = { /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback * mixer widget - * Note: PASD motherboards uses the Line In 2 as the input for front panel - * mic (mic 2) + * Note: PASD motherboards uses the Line In 2 as the input for + * front panel mic (mic 2) */ /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, @@ -5530,13 +6001,13 @@ static struct hda_verb alc883_auto_init_verbs[] = { {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, - //{0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, + /* {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */ {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, /* Input mixer2 */ {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, - //{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, + /* {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, */ {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, { } @@ -5584,6 +6055,7 @@ static const char *alc883_models[ALC883_MODEL_LAST] = { [ALC883_ACER] = "acer", [ALC883_MEDION] = "medion", [ALC883_LAPTOP_EAPD] = "laptop-eapd", + [ALC883_LENOVO_101E_2ch] = "lenovo-101e", [ALC883_AUTO] = "auto", }; @@ -5592,6 +6064,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch), SND_PCI_QUIRK(0x1558, 0, "Clevo laptop", ALC883_LAPTOP_EAPD), SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG), + SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG), SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG), SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG), SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG), @@ -5609,6 +6082,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { SND_PCI_QUIRK(0x161f, 0x2054, "Medion laptop", ALC883_MEDION), SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD), SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch), + SND_PCI_QUIRK(0x17aa, 0x101e, "lenovo 101e", ALC883_LENOVO_101E_2ch), {} }; @@ -5639,7 +6113,7 @@ static struct alc_config_preset alc883_presets[] = { .channel_mode = alc883_3ST_6ch_modes, .need_dac_fix = 1, .input_mux = &alc883_capture_source, - }, + }, [ALC883_3ST_6ch] = { .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, .init_verbs = { alc883_init_verbs }, @@ -5651,7 +6125,7 @@ static struct alc_config_preset alc883_presets[] = { .channel_mode = alc883_3ST_6ch_modes, .need_dac_fix = 1, .input_mux = &alc883_capture_source, - }, + }, [ALC883_6ST_DIG] = { .mixers = { alc883_base_mixer, alc883_chmode_mixer }, .init_verbs = { alc883_init_verbs }, @@ -5749,6 +6223,19 @@ static struct alc_config_preset alc883_presets[] = { .channel_mode = alc883_3ST_2ch_modes, .input_mux = &alc883_capture_source, }, + [ALC883_LENOVO_101E_2ch] = { + .mixers = { alc883_lenovo_101e_2ch_mixer}, + .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs}, + .num_dacs = ARRAY_SIZE(alc883_dac_nids), + .dac_nids = alc883_dac_nids, + .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), + .adc_nids = alc883_adc_nids, + .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), + .channel_mode = alc883_3ST_2ch_modes, + .input_mux = &alc883_lenovo_101e_capture_source, + .unsol_event = alc883_lenovo_101e_unsol_event, + .init_hook = alc883_lenovo_101e_all_automute, + }, }; @@ -5761,8 +6248,8 @@ static void alc883_auto_set_output_and_unmute(struct hda_codec *codec, { /* set as output */ struct alc_spec *spec = codec->spec; - int idx; - + int idx; + if (spec->multiout.dac_nids[dac_idx] == 0x25) idx = 4; else @@ -5781,10 +6268,13 @@ static void alc883_auto_init_multi_out(struct hda_codec *codec) struct alc_spec *spec = codec->spec; int i; + alc_subsystem_id(codec, 0x15, 0x1b, 0x14); for (i = 0; i <= HDA_SIDE; i++) { - hda_nid_t nid = spec->autocfg.line_out_pins[i]; + hda_nid_t nid = spec->autocfg.line_out_pins[i]; + int pin_type = get_pin_type(spec->autocfg.line_out_type); if (nid) - alc883_auto_set_output_and_unmute(codec, nid, PIN_OUT, i); + alc883_auto_set_output_and_unmute(codec, nid, pin_type, + i); } } @@ -5833,8 +6323,8 @@ static int alc883_parse_auto_config(struct hda_codec *codec) else if (err > 0) /* hack - override the init verbs */ spec->init_verbs[0] = alc883_auto_init_verbs; - spec->mixers[spec->num_mixers] = alc883_capture_mixer; - spec->num_mixers++; + spec->mixers[spec->num_mixers] = alc883_capture_mixer; + spec->num_mixers++; return err; } @@ -5872,7 +6362,7 @@ static int patch_alc883(struct hda_codec *codec) if (err < 0) { alc_free(codec); return err; - } else if (! err) { + } else if (!err) { printk(KERN_INFO "hda_codec: Cannot set up configuration " "from BIOS. Using base mode...\n"); @@ -5891,7 +6381,7 @@ static int patch_alc883(struct hda_codec *codec) spec->stream_digital_playback = &alc883_pcm_digital_playback; spec->stream_digital_capture = &alc883_pcm_digital_capture; - if (! spec->adc_nids && spec->input_mux) { + if (!spec->adc_nids && spec->input_mux) { spec->adc_nids = alc883_adc_nids; spec->num_adc_nids = ARRAY_SIZE(alc883_adc_nids); } @@ -6028,8 +6518,8 @@ static struct hda_verb alc262_init_verbs[] = { /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback * mixer widget - * Note: PASD motherboards uses the Line In 2 as the input for front panel - * mic (mic 2) + * Note: PASD motherboards uses the Line In 2 as the input for + * front panel mic (mic 2) */ /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, @@ -6086,7 +6576,7 @@ static struct hda_verb alc262_init_verbs[] = { {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x00 << 8))}, {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x03 << 8))}, {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x02 << 8))}, - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x04 << 8))}, { } }; @@ -6113,7 +6603,7 @@ static void alc262_hippo_automute(struct hda_codec *codec, int force) struct alc_spec *spec = codec->spec; unsigned int mute; - if (force || ! spec->sense_updated) { + if (force || !spec->sense_updated) { unsigned int present; /* need to execute and sync at first */ snd_hda_codec_read(codec, 0x15, 0, AC_VERB_SET_PIN_SENSE, 0); @@ -6153,7 +6643,7 @@ static void alc262_hippo1_automute(struct hda_codec *codec, int force) struct alc_spec *spec = codec->spec; unsigned int mute; - if (force || ! spec->sense_updated) { + if (force || !spec->sense_updated) { unsigned int present; /* need to execute and sync at first */ snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0); @@ -6226,7 +6716,7 @@ static void alc262_fujitsu_automute(struct hda_codec *codec, int force) struct alc_spec *spec = codec->spec; unsigned int mute; - if (force || ! spec->sense_updated) { + if (force || !spec->sense_updated) { unsigned int present; /* need to execute and sync at first */ snd_hda_codec_read(codec, 0x14, 0, AC_VERB_SET_PIN_SENSE, 0); @@ -6331,7 +6821,8 @@ static struct hda_verb alc262_EAPD_verbs[] = { }; /* add playback controls from the parsed DAC table */ -static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg) +static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, + const struct auto_pin_cfg *cfg) { hda_nid_t nid; int err; @@ -6342,26 +6833,39 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct nid = cfg->line_out_pins[0]; if (nid) { - if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Front Playback Volume", - HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_VOL, + "Front Playback Volume", + HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT)); + if (err < 0) return err; - if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Front Playback Switch", - HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_MUTE, + "Front Playback Switch", + HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); + if (err < 0) return err; } nid = cfg->speaker_pins[0]; if (nid) { if (nid == 0x16) { - if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Speaker Playback Volume", - HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_VOL, + "Speaker Playback Volume", + HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, + HDA_OUTPUT)); + if (err < 0) return err; - if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Speaker Playback Switch", - HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_MUTE, + "Speaker Playback Switch", + HDA_COMPOSE_AMP_VAL(nid, 2, 0, + HDA_OUTPUT)); + if (err < 0) return err; } else { - if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Speaker Playback Switch", - HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_MUTE, + "Speaker Playback Switch", + HDA_COMPOSE_AMP_VAL(nid, 3, 0, + HDA_OUTPUT)); + if (err < 0) return err; } } @@ -6369,23 +6873,33 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, const struct if (nid) { /* spec->multiout.hp_nid = 2; */ if (nid == 0x16) { - if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, "Headphone Playback Volume", - HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_VOL, + "Headphone Playback Volume", + HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, + HDA_OUTPUT)); + if (err < 0) return err; - if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch", - HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_MUTE, + "Headphone Playback Switch", + HDA_COMPOSE_AMP_VAL(nid, 2, 0, + HDA_OUTPUT)); + if (err < 0) return err; } else { - if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch", - HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_MUTE, + "Headphone Playback Switch", + HDA_COMPOSE_AMP_VAL(nid, 3, 0, + HDA_OUTPUT)); + if (err < 0) return err; } } - return 0; + return 0; } /* identical with ALC880 */ -#define alc262_auto_create_analog_input_ctls alc880_auto_create_analog_input_ctls +#define alc262_auto_create_analog_input_ctls \ + alc880_auto_create_analog_input_ctls /* * generic initialization of ADC, input mixers and output mixers @@ -6403,8 +6917,8 @@ static struct hda_verb alc262_volume_init_verbs[] = { /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback * mixer widget - * Note: PASD motherboards uses the Line In 2 as the input for front panel - * mic (mic 2) + * Note: PASD motherboards uses the Line In 2 as the input for + * front panel mic (mic 2) */ /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, @@ -6464,8 +6978,8 @@ static struct hda_verb alc262_HP_BPC_init_verbs[] = { /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback * mixer widget - * Note: PASD motherboards uses the Line In 2 as the input for front panel - * mic (mic 2) + * Note: PASD motherboards uses the Line In 2 as the input for + * front panel mic (mic 2) */ /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, @@ -6647,13 +7161,17 @@ static int alc262_parse_auto_config(struct hda_codec *codec) int err; static hda_nid_t alc262_ignore[] = { 0x1d, 0 }; - if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, - alc262_ignore)) < 0) + err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, + alc262_ignore); + if (err < 0) return err; - if (! spec->autocfg.line_outs) + if (!spec->autocfg.line_outs) return 0; /* can't find valid BIOS pin config */ - if ((err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || - (err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) + err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg); + if (err < 0) + return err; + err = alc262_auto_create_analog_input_ctls(spec, &spec->autocfg); + if (err < 0) return err; spec->multiout.max_channels = spec->multiout.num_dacs * 2; @@ -6777,7 +7295,7 @@ static struct alc_config_preset alc262_presets[] = { .num_channel_mode = ARRAY_SIZE(alc262_modes), .channel_mode = alc262_modes, .input_mux = &alc262_HP_capture_source, - }, + }, [ALC262_HP_BPC_D7000_WF] = { .mixers = { alc262_HP_BPC_WildWest_mixer }, .init_verbs = { alc262_HP_BPC_WildWest_init_verbs }, @@ -6787,7 +7305,7 @@ static struct alc_config_preset alc262_presets[] = { .num_channel_mode = ARRAY_SIZE(alc262_modes), .channel_mode = alc262_modes, .input_mux = &alc262_HP_capture_source, - }, + }, [ALC262_HP_BPC_D7000_WL] = { .mixers = { alc262_HP_BPC_WildWest_mixer, alc262_HP_BPC_WildWest_option_mixer }, @@ -6798,7 +7316,7 @@ static struct alc_config_preset alc262_presets[] = { .num_channel_mode = ARRAY_SIZE(alc262_modes), .channel_mode = alc262_modes, .input_mux = &alc262_HP_capture_source, - }, + }, [ALC262_BENQ_ED8] = { .mixers = { alc262_base_mixer }, .init_verbs = { alc262_init_verbs, alc262_EAPD_verbs }, @@ -6808,7 +7326,7 @@ static struct alc_config_preset alc262_presets[] = { .num_channel_mode = ARRAY_SIZE(alc262_modes), .channel_mode = alc262_modes, .input_mux = &alc262_capture_source, - }, + }, }; static int patch_alc262(struct hda_codec *codec) @@ -6823,7 +7341,9 @@ static int patch_alc262(struct hda_codec *codec) codec->spec = spec; #if 0 - /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is under-run */ + /* pshou 07/11/05 set a zero PCM sample to DAC when FIFO is + * under-run + */ { int tmp; snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_COEF_INDEX, 7); @@ -6849,7 +7369,7 @@ static int patch_alc262(struct hda_codec *codec) if (err < 0) { alc_free(codec); return err; - } else if (! err) { + } else if (!err) { printk(KERN_INFO "hda_codec: Cannot set up configuration " "from BIOS. Using base mode...\n"); @@ -6868,15 +7388,17 @@ static int patch_alc262(struct hda_codec *codec) spec->stream_digital_playback = &alc262_pcm_digital_playback; spec->stream_digital_capture = &alc262_pcm_digital_capture; - if (! spec->adc_nids && spec->input_mux) { + if (!spec->adc_nids && spec->input_mux) { /* check whether NID 0x07 is valid */ unsigned int wcap = get_wcaps(codec, 0x07); - wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; /* get type */ + /* get type */ + wcap = (wcap & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; if (wcap != AC_WID_AUD_IN) { spec->adc_nids = alc262_adc_nids_alt; spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt); - spec->mixers[spec->num_mixers] = alc262_capture_alt_mixer; + spec->mixers[spec->num_mixers] = + alc262_capture_alt_mixer; spec->num_mixers++; } else { spec->adc_nids = alc262_adc_nids; @@ -6904,7 +7426,9 @@ static int patch_alc262(struct hda_codec *codec) static struct hda_verb alc861_threestack_ch2_init[] = { /* set pin widget 1Ah (line in) for input */ { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, - /* set pin widget 18h (mic1/2) for input, for mic also enable the vref */ + /* set pin widget 18h (mic1/2) for input, for mic also enable + * the vref + */ { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, @@ -6961,7 +7485,9 @@ static struct hda_channel_mode alc861_uniwill_m31_modes[2] = { static struct hda_verb alc861_asus_ch2_init[] = { /* set pin widget 1Ah (line in) for input */ { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, - /* set pin widget 18h (mic1/2) for input, for mic also enable the vref */ + /* set pin widget 18h (mic1/2) for input, for mic also enable + * the vref + */ { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, @@ -7016,7 +7542,7 @@ static struct snd_kcontrol_new alc861_base_mixer[] = { HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), - + /* Capture mixer control */ HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), @@ -7050,7 +7576,7 @@ static struct snd_kcontrol_new alc861_3ST_mixer[] = { HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), - + /* Capture mixer control */ HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), @@ -7092,7 +7618,7 @@ static struct snd_kcontrol_new alc861_toshiba_mixer[] = { }, { } /* end */ -}; +}; static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { /* output mixer control */ @@ -7113,7 +7639,7 @@ static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), - + /* Capture mixer control */ HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), @@ -7134,7 +7660,7 @@ static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { .private_value = ARRAY_SIZE(alc861_uniwill_m31_modes), }, { } /* end */ -}; +}; static struct snd_kcontrol_new alc861_asus_mixer[] = { /* output mixer control */ @@ -7154,8 +7680,8 @@ static struct snd_kcontrol_new alc861_asus_mixer[] = { HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), - HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT), /* was HDA_INPUT (why?) */ - + HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT), + /* Capture mixer control */ HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), @@ -7239,7 +7765,7 @@ static struct hda_verb alc861_base_init_verbs[] = { {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, //Output 0~12 step + {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, @@ -7249,7 +7775,8 @@ static struct hda_verb alc861_base_init_verbs[] = { {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front) + /* hp used DAC 3 (Front) */ + {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, { } @@ -7300,7 +7827,7 @@ static struct hda_verb alc861_threestack_init_verbs[] = { {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, //Output 0~12 step + {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, @@ -7310,7 +7837,8 @@ static struct hda_verb alc861_threestack_init_verbs[] = { {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front) + /* hp used DAC 3 (Front) */ + {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, { } }; @@ -7329,7 +7857,8 @@ static struct hda_verb alc861_uniwill_m31_init_verbs[] = { { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, /* port-E for HP out (front panel) */ - { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, // this has to be set to VREF80 + /* this has to be set to VREF80 */ + { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, /* route front PCM to HP */ { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, /* port-F for mic-in (front panel) with vref */ @@ -7360,7 +7889,7 @@ static struct hda_verb alc861_uniwill_m31_init_verbs[] = { {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, //Output 0~12 step + {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, @@ -7370,7 +7899,8 @@ static struct hda_verb alc861_uniwill_m31_init_verbs[] = { {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, // hp used DAC 3 (Front) + /* hp used DAC 3 (Front) */ + {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, { } }; @@ -7379,7 +7909,9 @@ static struct hda_verb alc861_asus_init_verbs[] = { /* * Unmute ADC0 and set the default input to mic-in */ - /* port-A for surround (rear panel) | according to codec#0 this is the HP jack*/ + /* port-A for surround (rear panel) + * according to codec#0 this is the HP jack + */ { 0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, /* was 0x00 */ /* route front PCM to HP */ { 0x0e, AC_VERB_SET_CONNECT_SEL, 0x01 }, @@ -7391,7 +7923,8 @@ static struct hda_verb alc861_asus_init_verbs[] = { { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, { 0x0b, AC_VERB_SET_CONNECT_SEL, 0x00 }, /* port-E for HP out (front panel) */ - { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, /* this has to be set to VREF80 */ + /* this has to be set to VREF80 */ + { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, /* route front PCM to HP */ { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, /* port-F for mic-in (front panel) with vref */ @@ -7421,7 +7954,7 @@ static struct hda_verb alc861_asus_init_verbs[] = { {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c }, /* Output 0~12 step */ + {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb00c}, /* Output 0~12 step */ {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, @@ -7431,7 +7964,8 @@ static struct hda_verb alc861_asus_init_verbs[] = { {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, /* hp used DAC 3 (Front) */ + /* hp used DAC 3 (Front) */ + {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, { } }; @@ -7450,7 +7984,7 @@ static struct hda_verb alc861_auto_init_verbs[] = { /* * Unmute ADC0 and set the default input to mic-in */ -// {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, + /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */ {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* Unmute DAC0~3 & spdif out*/ @@ -7483,21 +8017,21 @@ static struct hda_verb alc861_auto_init_verbs[] = { {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, - {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, + {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, + {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, - {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, + {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, + {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, - {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, // set Mic 1 + {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* set Mic 1 */ { } }; static struct hda_verb alc861_toshiba_init_verbs[] = { {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, - + { } }; @@ -7521,9 +8055,6 @@ static void alc861_toshiba_automute(struct hda_codec *codec) static void alc861_toshiba_unsol_event(struct hda_codec *codec, unsigned int res) { - /* Looks like the unsol event is incompatible with the standard - * definition. 6bit tag is placed at 26 bit! - */ if ((res >> 26) == ALC880_HP_EVENT) alc861_toshiba_automute(codec); } @@ -7568,7 +8099,8 @@ static struct hda_input_mux alc861_capture_source = { }; /* fill in the dac_nids table from the parsed pin configuration */ -static int alc861_auto_fill_dac_nids(struct alc_spec *spec, const struct auto_pin_cfg *cfg) +static int alc861_auto_fill_dac_nids(struct alc_spec *spec, + const struct auto_pin_cfg *cfg) { int i; hda_nid_t nid; @@ -7591,29 +8123,40 @@ static int alc861_auto_create_multi_out_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg) { char name[32]; - static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" }; + static const char *chname[4] = { + "Front", "Surround", NULL /*CLFE*/, "Side" + }; hda_nid_t nid; int i, idx, err; for (i = 0; i < cfg->line_outs; i++) { nid = spec->multiout.dac_nids[i]; - if (! nid) + if (!nid) continue; if (nid == 0x05) { /* Center/LFE */ - if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "Center Playback Switch", - HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_BIND_MUTE, + "Center Playback Switch", + HDA_COMPOSE_AMP_VAL(nid, 1, 0, + HDA_OUTPUT)); + if (err < 0) return err; - if ((err = add_control(spec, ALC_CTL_BIND_MUTE, "LFE Playback Switch", - HDA_COMPOSE_AMP_VAL(nid, 2, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_BIND_MUTE, + "LFE Playback Switch", + HDA_COMPOSE_AMP_VAL(nid, 2, 0, + HDA_OUTPUT)); + if (err < 0) return err; } else { - for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1; idx++) + for (idx = 0; idx < ARRAY_SIZE(alc861_dac_nids) - 1; + idx++) if (nid == alc861_dac_nids[idx]) break; sprintf(name, "%s Playback Switch", chname[idx]); - if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name, - HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_BIND_MUTE, name, + HDA_COMPOSE_AMP_VAL(nid, 3, 0, + HDA_OUTPUT)); + if (err < 0) return err; } } @@ -7625,13 +8168,15 @@ static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin) int err; hda_nid_t nid; - if (! pin) + if (!pin) return 0; if ((pin >= 0x0b && pin <= 0x10) || pin == 0x1f || pin == 0x20) { nid = 0x03; - if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Headphone Playback Switch", - HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_MUTE, + "Headphone Playback Switch", + HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); + if (err < 0) return err; spec->multiout.hp_nid = nid; } @@ -7639,32 +8184,33 @@ static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin) } /* create playback/capture controls for input pins */ -static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg) +static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, + const struct auto_pin_cfg *cfg) { struct hda_input_mux *imux = &spec->private_imux; int i, err, idx, idx1; for (i = 0; i < AUTO_PIN_LAST; i++) { - switch(cfg->input_pins[i]) { + switch (cfg->input_pins[i]) { case 0x0c: idx1 = 1; - idx = 2; // Line In + idx = 2; /* Line In */ break; case 0x0f: idx1 = 2; - idx = 2; // Line In + idx = 2; /* Line In */ break; case 0x0d: idx1 = 0; - idx = 1; // Mic In + idx = 1; /* Mic In */ break; - case 0x10: + case 0x10: idx1 = 3; - idx = 1; // Mic In + idx = 1; /* Mic In */ break; case 0x11: idx1 = 4; - idx = 0; // CD + idx = 0; /* CD */ break; default: continue; @@ -7677,7 +8223,7 @@ static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, const str imux->items[imux->num_items].label = auto_pin_cfg_labels[i]; imux->items[imux->num_items].index = idx1; - imux->num_items++; + imux->num_items++; } return 0; } @@ -7702,13 +8248,16 @@ static struct snd_kcontrol_new alc861_capture_mixer[] = { { } /* end */ }; -static void alc861_auto_set_output_and_unmute(struct hda_codec *codec, hda_nid_t nid, +static void alc861_auto_set_output_and_unmute(struct hda_codec *codec, + hda_nid_t nid, int pin_type, int dac_idx) { /* set as output */ - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); - snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, + pin_type); + snd_hda_codec_write(codec, dac_idx, 0, AC_VERB_SET_AMP_GAIN_MUTE, + AMP_OUT_UNMUTE); } @@ -7717,10 +8266,13 @@ static void alc861_auto_init_multi_out(struct hda_codec *codec) struct alc_spec *spec = codec->spec; int i; + alc_subsystem_id(codec, 0x0e, 0x0f, 0x0b); for (i = 0; i < spec->autocfg.line_outs; i++) { hda_nid_t nid = spec->autocfg.line_out_pins[i]; + int pin_type = get_pin_type(spec->autocfg.line_out_type); if (nid) - alc861_auto_set_output_and_unmute(codec, nid, PIN_OUT, spec->multiout.dac_nids[i]); + alc861_auto_set_output_and_unmute(codec, nid, pin_type, + spec->multiout.dac_nids[i]); } } @@ -7731,7 +8283,8 @@ static void alc861_auto_init_hp_out(struct hda_codec *codec) pin = spec->autocfg.hp_pins[0]; if (pin) /* connect to front */ - alc861_auto_set_output_and_unmute(codec, pin, PIN_HP, spec->multiout.dac_nids[0]); + alc861_auto_set_output_and_unmute(codec, pin, PIN_HP, + spec->multiout.dac_nids[0]); } static void alc861_auto_init_analog_input(struct hda_codec *codec) @@ -7741,31 +8294,43 @@ static void alc861_auto_init_analog_input(struct hda_codec *codec) for (i = 0; i < AUTO_PIN_LAST; i++) { hda_nid_t nid = spec->autocfg.input_pins[i]; - if ((nid>=0x0c) && (nid <=0x11)) { - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, - i <= AUTO_PIN_FRONT_MIC ? PIN_VREF80 : PIN_IN); + if (nid >= 0x0c && nid <= 0x11) { + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, + i <= AUTO_PIN_FRONT_MIC ? + PIN_VREF80 : PIN_IN); } } } /* parse the BIOS configuration and set up the alc_spec */ -/* return 1 if successful, 0 if the proper config is not found, or a negative error code */ +/* return 1 if successful, 0 if the proper config is not found, + * or a negative error code + */ static int alc861_parse_auto_config(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; int err; static hda_nid_t alc861_ignore[] = { 0x1d, 0 }; - if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, - alc861_ignore)) < 0) + err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, + alc861_ignore); + if (err < 0) return err; - if (! spec->autocfg.line_outs) + if (!spec->autocfg.line_outs) return 0; /* can't find valid BIOS pin config */ - if ((err = alc861_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 || - (err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg)) < 0 || - (err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0])) < 0 || - (err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg)) < 0) + err = alc861_auto_fill_dac_nids(spec, &spec->autocfg); + if (err < 0) + return err; + err = alc861_auto_create_multi_out_ctls(spec, &spec->autocfg); + if (err < 0) + return err; + err = alc861_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); + if (err < 0) + return err; + err = alc861_auto_create_analog_input_ctls(spec, &spec->autocfg); + if (err < 0) return err; spec->multiout.max_channels = spec->multiout.num_dacs * 2; @@ -7817,12 +8382,14 @@ static struct snd_pci_quirk alc861_cfg_tbl[] = { SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST), SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP), SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP), + SND_PCI_QUIRK(0x1043, 0x13d7, "ASUS A9rp", ALC861_ASUS_LAPTOP), SND_PCI_QUIRK(0x1043, 0x1393, "ASUS", ALC861_ASUS), SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660_3ST), SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba", ALC861_TOSHIBA), SND_PCI_QUIRK(0x1179, 0xff10, "Toshiba", ALC861_TOSHIBA), SND_PCI_QUIRK(0x1584, 0x9072, "Uniwill m31", ALC861_UNIWILL_M31), SND_PCI_QUIRK(0x1584, 0x2b01, "Uniwill X40AIx", ALC861_UNIWILL_M31), + SND_PCI_QUIRK(0x1849, 0x0660, "Asrock 939SLI32", ALC660_3ST), SND_PCI_QUIRK(0x8086, 0xd600, "Intel", ALC861_3ST), {} }; @@ -7892,7 +8459,8 @@ static struct alc_config_preset alc861_presets[] = { }, [ALC861_TOSHIBA] = { .mixers = { alc861_toshiba_mixer }, - .init_verbs = { alc861_base_init_verbs, alc861_toshiba_init_verbs }, + .init_verbs = { alc861_base_init_verbs, + alc861_toshiba_init_verbs }, .num_dacs = ARRAY_SIZE(alc861_dac_nids), .dac_nids = alc861_dac_nids, .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), @@ -7944,7 +8512,7 @@ static int patch_alc861(struct hda_codec *codec) if (spec == NULL) return -ENOMEM; - codec->spec = spec; + codec->spec = spec; board_config = snd_hda_check_board_config(codec, ALC861_MODEL_LAST, alc861_models, @@ -7962,7 +8530,7 @@ static int patch_alc861(struct hda_codec *codec) if (err < 0) { alc_free(codec); return err; - } else if (! err) { + } else if (!err) { printk(KERN_INFO "hda_codec: Cannot set up configuration " "from BIOS. Using base mode...\n"); @@ -8049,7 +8617,7 @@ static int alc861vd_mux_enum_put(struct snd_kcontrol *kcontrol, idx = ucontrol->value.enumerated.item[0]; if (idx >= imux->num_items) idx = imux->num_items - 1; - if (*cur_val == idx && ! codec->in_resume) + if (*cur_val == idx && !codec->in_resume) return 0; for (i = 0; i < imux->num_items; i++) { unsigned int v = (i == idx) ? 0x7000 : 0x7080; @@ -8193,6 +8761,27 @@ static struct snd_kcontrol_new alc861vd_3st_mixer[] = { { } /* end */ }; +static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = { + HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), + /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/ + HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), + + HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), + + HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + + HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + + HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), + HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), + + { } /* end */ +}; + /* * generic initialization of ADC, input mixers and output mixers */ @@ -8214,10 +8803,10 @@ static struct hda_verb alc861vd_volume_init_verbs[] = { {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, /* Capture mixer: unmute Mic, F-Mic, Line, CD inputs */ + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)}, - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(6)}, - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(8)}, /* * Set up output mixers (0x02 - 0x05) @@ -8318,6 +8907,68 @@ static struct hda_verb alc861vd_6stack_init_verbs[] = { { } }; +static struct hda_verb alc861vd_eapd_verbs[] = { + {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, + { } +}; + +static struct hda_verb alc861vd_lenovo_unsol_verbs[] = { + {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, + {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, + {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, + {} +}; + +/* toggle speaker-output according to the hp-jack state */ +static void alc861vd_lenovo_hp_automute(struct hda_codec *codec) +{ + unsigned int present; + unsigned char bits; + + present = snd_hda_codec_read(codec, 0x1b, 0, + AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + bits = present ? 0x80 : 0; + snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, + 0x80, bits); + snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, + 0x80, bits); +} + +static void alc861vd_lenovo_mic_automute(struct hda_codec *codec) +{ + unsigned int present; + unsigned char bits; + + present = snd_hda_codec_read(codec, 0x18, 0, + AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + bits = present ? 0x80 : 0; + snd_hda_codec_amp_update(codec, 0x0b, 0, HDA_INPUT, 1, + 0x80, bits); + snd_hda_codec_amp_update(codec, 0x0b, 1, HDA_INPUT, 1, + 0x80, bits); +} + +static void alc861vd_lenovo_automute(struct hda_codec *codec) +{ + alc861vd_lenovo_hp_automute(codec); + alc861vd_lenovo_mic_automute(codec); +} + +static void alc861vd_lenovo_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + switch (res >> 26) { + case ALC880_HP_EVENT: + alc861vd_lenovo_hp_automute(codec); + break; + case ALC880_MIC_EVENT: + alc861vd_lenovo_mic_automute(codec); + break; + } +} + /* pcm configuration: identiacal with ALC880 */ #define alc861vd_pcm_analog_playback alc880_pcm_analog_playback #define alc861vd_pcm_analog_capture alc880_pcm_analog_capture @@ -8332,15 +8983,18 @@ static const char *alc861vd_models[ALC861VD_MODEL_LAST] = { [ALC861VD_3ST] = "3stack", [ALC861VD_3ST_DIG] = "3stack-digout", [ALC861VD_6ST_DIG] = "6stack-digout", + [ALC861VD_LENOVO] = "lenovo", [ALC861VD_AUTO] = "auto", }; static struct snd_pci_quirk alc861vd_cfg_tbl[] = { + SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST), SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST), SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST), SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST), - SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_3ST), + SND_PCI_QUIRK(0x17aa, 0x3802, "Lenovo 3000 C200", ALC861VD_LENOVO), + SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo", ALC861VD_LENOVO), {} }; @@ -8389,6 +9043,22 @@ static struct alc_config_preset alc861vd_presets[] = { .channel_mode = alc861vd_6stack_modes, .input_mux = &alc861vd_capture_source, }, + [ALC861VD_LENOVO] = { + .mixers = { alc861vd_lenovo_mixer }, + .init_verbs = { alc861vd_volume_init_verbs, + alc861vd_3stack_init_verbs, + alc861vd_eapd_verbs, + alc861vd_lenovo_unsol_verbs }, + .num_dacs = ARRAY_SIZE(alc660vd_dac_nids), + .dac_nids = alc660vd_dac_nids, + .num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids), + .adc_nids = alc861vd_adc_nids, + .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), + .channel_mode = alc861vd_3stack_2ch_modes, + .input_mux = &alc861vd_capture_source, + .unsol_event = alc861vd_lenovo_unsol_event, + .init_hook = alc861vd_lenovo_automute, + }, }; /* @@ -8409,11 +9079,13 @@ static void alc861vd_auto_init_multi_out(struct hda_codec *codec) struct alc_spec *spec = codec->spec; int i; + alc_subsystem_id(codec, 0x15, 0x1b, 0x14); for (i = 0; i <= HDA_SIDE; i++) { hda_nid_t nid = spec->autocfg.line_out_pins[i]; + int pin_type = get_pin_type(spec->autocfg.line_out_type); if (nid) alc861vd_auto_set_output_and_unmute(codec, nid, - PIN_OUT, i); + pin_type, i); } } @@ -8466,7 +9138,7 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, int i, err; for (i = 0; i < cfg->line_outs; i++) { - if (! spec->multiout.dac_nids[i]) + if (!spec->multiout.dac_nids[i]) continue; nid_v = alc861vd_idx_to_mixer_vol( alc880_dac_to_idx( @@ -8477,36 +9149,42 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, if (i == 2) { /* Center/LFE */ - if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, - "Center Playback Volume", - HDA_COMPOSE_AMP_VAL(nid_v, 1, - 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_VOL, + "Center Playback Volume", + HDA_COMPOSE_AMP_VAL(nid_v, 1, 0, + HDA_OUTPUT)); + if (err < 0) return err; - if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, - "LFE Playback Volume", - HDA_COMPOSE_AMP_VAL(nid_v, 2, - 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_VOL, + "LFE Playback Volume", + HDA_COMPOSE_AMP_VAL(nid_v, 2, 0, + HDA_OUTPUT)); + if (err < 0) return err; - if ((err = add_control(spec, ALC_CTL_BIND_MUTE, - "Center Playback Switch", - HDA_COMPOSE_AMP_VAL(nid_s, 1, - 2, HDA_INPUT))) < 0) + err = add_control(spec, ALC_CTL_BIND_MUTE, + "Center Playback Switch", + HDA_COMPOSE_AMP_VAL(nid_s, 1, 2, + HDA_INPUT)); + if (err < 0) return err; - if ((err = add_control(spec, ALC_CTL_BIND_MUTE, - "LFE Playback Switch", - HDA_COMPOSE_AMP_VAL(nid_s, 2, - 2, HDA_INPUT))) < 0) + err = add_control(spec, ALC_CTL_BIND_MUTE, + "LFE Playback Switch", + HDA_COMPOSE_AMP_VAL(nid_s, 2, 2, + HDA_INPUT)); + if (err < 0) return err; } else { sprintf(name, "%s Playback Volume", chname[i]); - if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, - HDA_COMPOSE_AMP_VAL(nid_v, 3, - 0, HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_VOL, name, + HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, + HDA_OUTPUT)); + if (err < 0) return err; sprintf(name, "%s Playback Switch", chname[i]); - if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name, - HDA_COMPOSE_AMP_VAL(nid_v, 3, - 2, HDA_INPUT))) < 0) + err = add_control(spec, ALC_CTL_BIND_MUTE, name, + HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, + HDA_INPUT)); + if (err < 0) return err; } } @@ -8523,13 +9201,13 @@ static int alc861vd_auto_create_extra_out(struct alc_spec *spec, int err; char name[32]; - if (! pin) + if (!pin) return 0; if (alc880_is_fixed_pin(pin)) { nid_v = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); /* specify the DAC as the extra output */ - if (! spec->multiout.hp_nid) + if (!spec->multiout.hp_nid) spec->multiout.hp_nid = nid_v; else spec->multiout.extra_out_nid[0] = nid_v; @@ -8540,22 +9218,22 @@ static int alc861vd_auto_create_extra_out(struct alc_spec *spec, alc880_fixed_pin_idx(pin)); sprintf(name, "%s Playback Volume", pfx); - if ((err = add_control(spec, ALC_CTL_WIDGET_VOL, name, - HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, - HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_VOL, name, + HDA_COMPOSE_AMP_VAL(nid_v, 3, 0, HDA_OUTPUT)); + if (err < 0) return err; sprintf(name, "%s Playback Switch", pfx); - if ((err = add_control(spec, ALC_CTL_BIND_MUTE, name, - HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, - HDA_INPUT))) < 0) + err = add_control(spec, ALC_CTL_BIND_MUTE, name, + HDA_COMPOSE_AMP_VAL(nid_s, 3, 2, HDA_INPUT)); + if (err < 0) return err; } else if (alc880_is_multi_pin(pin)) { /* set manual connection */ /* we have only a switch on HP-out PIN */ sprintf(name, "%s Playback Switch", pfx); - if ((err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, - HDA_COMPOSE_AMP_VAL(pin, 3, 0, - HDA_OUTPUT))) < 0) + err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, + HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); + if (err < 0) return err; } return 0; @@ -8572,21 +9250,31 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec) int err; static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; - if ((err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, - alc861vd_ignore)) < 0) + err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, + alc861vd_ignore); + if (err < 0) return err; - if (! spec->autocfg.line_outs) + if (!spec->autocfg.line_outs) return 0; /* can't find valid BIOS pin config */ - if ((err = alc880_auto_fill_dac_nids(spec, &spec->autocfg)) < 0 || - (err = alc861vd_auto_create_multi_out_ctls(spec, - &spec->autocfg)) < 0 || - (err = alc861vd_auto_create_extra_out(spec, - spec->autocfg.speaker_pins[0], "Speaker")) < 0 || - (err = alc861vd_auto_create_extra_out(spec, - spec->autocfg.hp_pins[0], "Headphone")) < 0 || - (err = alc880_auto_create_analog_input_ctls(spec, - &spec->autocfg)) < 0) + err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); + if (err < 0) + return err; + err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg); + if (err < 0) + return err; + err = alc861vd_auto_create_extra_out(spec, + spec->autocfg.speaker_pins[0], + "Speaker"); + if (err < 0) + return err; + err = alc861vd_auto_create_extra_out(spec, + spec->autocfg.hp_pins[0], + "Headphone"); + if (err < 0) + return err; + err = alc880_auto_create_analog_input_ctls(spec, &spec->autocfg); + if (err < 0) return err; spec->multiout.max_channels = spec->multiout.num_dacs * 2; @@ -8641,7 +9329,7 @@ static int patch_alc861vd(struct hda_codec *codec) if (err < 0) { alc_free(codec); return err; - } else if (! err) { + } else if (!err) { printk(KERN_INFO "hda_codec: Cannot set up configuration " "from BIOS. Using base mode...\n"); @@ -8675,16 +9363,875 @@ static int patch_alc861vd(struct hda_codec *codec) } /* + * ALC662 support + * + * ALC662 is almost identical with ALC880 but has cleaner and more flexible + * configuration. Each pin widget can choose any input DACs and a mixer. + * Each ADC is connected from a mixer of all inputs. This makes possible + * 6-channel independent captures. + * + * In addition, an independent DAC for the multi-playback (not used in this + * driver yet). + */ +#define ALC662_DIGOUT_NID 0x06 +#define ALC662_DIGIN_NID 0x0a + +static hda_nid_t alc662_dac_nids[4] = { + /* front, rear, clfe, rear_surr */ + 0x02, 0x03, 0x04 +}; + +static hda_nid_t alc662_adc_nids[1] = { + /* ADC1-2 */ + 0x09, +}; +/* input MUX */ +/* FIXME: should be a matrix-type input source selection */ + +static struct hda_input_mux alc662_capture_source = { + .num_items = 4, + .items = { + { "Mic", 0x0 }, + { "Front Mic", 0x1 }, + { "Line", 0x2 }, + { "CD", 0x4 }, + }, +}; + +static struct hda_input_mux alc662_lenovo_101e_capture_source = { + .num_items = 2, + .items = { + { "Mic", 0x1 }, + { "Line", 0x2 }, + }, +}; +#define alc662_mux_enum_info alc_mux_enum_info +#define alc662_mux_enum_get alc_mux_enum_get + +static int alc662_mux_enum_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct alc_spec *spec = codec->spec; + const struct hda_input_mux *imux = spec->input_mux; + unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); + static hda_nid_t capture_mixers[3] = { 0x24, 0x23, 0x22 }; + hda_nid_t nid = capture_mixers[adc_idx]; + unsigned int *cur_val = &spec->cur_mux[adc_idx]; + unsigned int i, idx; + + idx = ucontrol->value.enumerated.item[0]; + if (idx >= imux->num_items) + idx = imux->num_items - 1; + if (*cur_val == idx && !codec->in_resume) + return 0; + for (i = 0; i < imux->num_items; i++) { + unsigned int v = (i == idx) ? 0x7000 : 0x7080; + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, + v | (imux->items[i].index << 8)); + } + *cur_val = idx; + return 1; +} +/* + * 2ch mode + */ +static struct hda_channel_mode alc662_3ST_2ch_modes[1] = { + { 2, NULL } +}; + +/* + * 2ch mode + */ +static struct hda_verb alc662_3ST_ch2_init[] = { + { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, + { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, + { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, + { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, + { } /* end */ +}; + +/* + * 6ch mode + */ +static struct hda_verb alc662_3ST_ch6_init[] = { + { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, + { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, + { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, + { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, + { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, + { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, + { } /* end */ +}; + +static struct hda_channel_mode alc662_3ST_6ch_modes[2] = { + { 2, alc662_3ST_ch2_init }, + { 6, alc662_3ST_ch6_init }, +}; + +/* + * 2ch mode + */ +static struct hda_verb alc662_sixstack_ch6_init[] = { + { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, + { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, + { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, + { } /* end */ +}; + +/* + * 6ch mode + */ +static struct hda_verb alc662_sixstack_ch8_init[] = { + { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, + { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, + { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, + { } /* end */ +}; + +static struct hda_channel_mode alc662_5stack_modes[2] = { + { 2, alc662_sixstack_ch6_init }, + { 6, alc662_sixstack_ch8_init }, +}; + +/* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 + * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b + */ + +static struct snd_kcontrol_new alc662_base_mixer[] = { + /* output mixer control */ + HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Front Playback Switch", 0x02, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Surround Playback Volume", 0x3, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Surround Playback Switch", 0x03, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT), + HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT), + HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), + + /*Input mixer control */ + HDA_CODEC_VOLUME("CD Playback Volume", 0xb, 0x4, HDA_INPUT), + HDA_CODEC_MUTE("CD Playback Switch", 0xb, 0x4, HDA_INPUT), + HDA_CODEC_VOLUME("Line Playback Volume", 0xb, 0x02, HDA_INPUT), + HDA_CODEC_MUTE("Line Playback Switch", 0xb, 0x02, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0xb, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0xb, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Front Mic Playback Volume", 0xb, 0x01, HDA_INPUT), + HDA_CODEC_MUTE("Front Mic Playback Switch", 0xb, 0x01, HDA_INPUT), + + /* Capture mixer control */ + HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Capture Source", + .count = 1, + .info = alc_mux_enum_info, + .get = alc_mux_enum_get, + .put = alc_mux_enum_put, + }, + { } /* end */ +}; + +static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = { + HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT), + HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), + HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), + HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), + HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), + HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), + HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + /* .name = "Capture Source", */ + .name = "Input Source", + .count = 1, + .info = alc662_mux_enum_info, + .get = alc662_mux_enum_get, + .put = alc662_mux_enum_put, + }, + { } /* end */ +}; + +static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = { + HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT), + HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Surround Playback Switch", 0x03, 2, HDA_INPUT), + HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x04, 1, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x04, 2, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE_MONO("Center Playback Switch", 0x04, 1, 2, HDA_INPUT), + HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x04, 2, 2, HDA_INPUT), + HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), + HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), + HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), + HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x05, HDA_INPUT), + HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), + HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + /* .name = "Capture Source", */ + .name = "Input Source", + .count = 1, + .info = alc662_mux_enum_info, + .get = alc662_mux_enum_get, + .put = alc662_mux_enum_put, + }, + { } /* end */ +}; + +static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = { + HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT), + HDA_CODEC_VOLUME("iSpeaker Playback Volume", 0x03, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("iSpeaker Playback Switch", 0x03, 2, HDA_INPUT), + HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), + HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + /* .name = "Capture Source", */ + .name = "Input Source", + .count = 1, + .info = alc662_mux_enum_info, + .get = alc662_mux_enum_get, + .put = alc662_mux_enum_put, + }, + { } /* end */ +}; + +static struct snd_kcontrol_new alc662_chmode_mixer[] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Channel Mode", + .info = alc_ch_mode_info, + .get = alc_ch_mode_get, + .put = alc_ch_mode_put, + }, + { } /* end */ +}; + +static struct hda_verb alc662_init_verbs[] = { + /* ADC: mute amp left and right */ + {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, + /* Front mixer: unmute input/output amp left and right (volume = 0) */ + + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, + + {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + + /* Front Pin: output 0 (0x0c) */ + {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + + /* Rear Pin: output 1 (0x0d) */ + {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + + /* CLFE Pin: output 2 (0x0e) */ + {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + + /* Mic (rear) pin: input vref at 80% */ + {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, + {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, + /* Front Mic pin: input vref at 80% */ + {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, + {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, + /* Line In pin: input */ + {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, + {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, + /* Line-2 In: Headphone output (output 0 - 0x0c) */ + {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, + /* CD pin widget for input */ + {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, + + /* FIXME: use matrix-type input source selection */ + /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ + /* Input mixer */ + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, + { } +}; + +static struct hda_verb alc662_sue_init_verbs[] = { + {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT}, + {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, + {} +}; + +/* + * generic initialization of ADC, input mixers and output mixers + */ +static struct hda_verb alc662_auto_init_verbs[] = { + /* + * Unmute ADC and set the default input to mic-in + */ + {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, + {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + + /* Unmute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback + * mixer widget + * Note: PASD motherboards uses the Line In 2 as the input for front + * panel mic (mic 2) + */ + /* Amp Indices: Mic1 = 0, Mic2 = 1, Line1 = 2, Line2 = 3, CD = 4 */ + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, + + /* + * Set up output mixers (0x0c - 0x0f) + */ + /* set vol=0 to output mixers */ + {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, + {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, + {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, + + /* set up input amps for analog loopback */ + /* Amp Indices: DAC = 0, mixer = 1 */ + {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + + + /* FIXME: use matrix-type input source selection */ + /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ + /* Input mixer */ + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, + /*{0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)},*/ + {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, + + { } +}; + +/* capture mixer elements */ +static struct snd_kcontrol_new alc662_capture_mixer[] = { + HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + /* The multiple "Capture Source" controls confuse alsamixer + * So call somewhat different.. + * FIXME: the controls appear in the "playback" view! + */ + /* .name = "Capture Source", */ + .name = "Input Source", + .count = 1, + .info = alc882_mux_enum_info, + .get = alc882_mux_enum_get, + .put = alc882_mux_enum_put, + }, + { } /* end */ +}; + +static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec) +{ + unsigned int present; + unsigned char bits; + + present = snd_hda_codec_read(codec, 0x14, 0, + AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + bits = present ? 0x80 : 0; + snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, + 0x80, bits); + snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, + 0x80, bits); +} + +static void alc662_lenovo_101e_all_automute(struct hda_codec *codec) +{ + unsigned int present; + unsigned char bits; + + present = snd_hda_codec_read(codec, 0x1b, 0, + AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + bits = present ? 0x80 : 0; + snd_hda_codec_amp_update(codec, 0x15, 0, HDA_OUTPUT, 0, + 0x80, bits); + snd_hda_codec_amp_update(codec, 0x15, 1, HDA_OUTPUT, 0, + 0x80, bits); + snd_hda_codec_amp_update(codec, 0x14, 0, HDA_OUTPUT, 0, + 0x80, bits); + snd_hda_codec_amp_update(codec, 0x14, 1, HDA_OUTPUT, 0, + 0x80, bits); +} + +static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + if ((res >> 26) == ALC880_HP_EVENT) + alc662_lenovo_101e_all_automute(codec); + if ((res >> 26) == ALC880_FRONT_EVENT) + alc662_lenovo_101e_ispeaker_automute(codec); +} + + +/* pcm configuration: identiacal with ALC880 */ +#define alc662_pcm_analog_playback alc880_pcm_analog_playback +#define alc662_pcm_analog_capture alc880_pcm_analog_capture +#define alc662_pcm_digital_playback alc880_pcm_digital_playback +#define alc662_pcm_digital_capture alc880_pcm_digital_capture + +/* + * configuration and preset + */ +static const char *alc662_models[ALC662_MODEL_LAST] = { + [ALC662_3ST_2ch_DIG] = "3stack-dig", + [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig", + [ALC662_3ST_6ch] = "3stack-6ch", + [ALC662_5ST_DIG] = "6stack-dig", + [ALC662_LENOVO_101E] = "lenovo-101e", + [ALC662_AUTO] = "auto", +}; + +static struct snd_pci_quirk alc662_cfg_tbl[] = { + SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E), + {} +}; + +static struct alc_config_preset alc662_presets[] = { + [ALC662_3ST_2ch_DIG] = { + .mixers = { alc662_3ST_2ch_mixer }, + .init_verbs = { alc662_init_verbs }, + .num_dacs = ARRAY_SIZE(alc662_dac_nids), + .dac_nids = alc662_dac_nids, + .dig_out_nid = ALC662_DIGOUT_NID, + .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), + .adc_nids = alc662_adc_nids, + .dig_in_nid = ALC662_DIGIN_NID, + .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), + .channel_mode = alc662_3ST_2ch_modes, + .input_mux = &alc662_capture_source, + }, + [ALC662_3ST_6ch_DIG] = { + .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, + .init_verbs = { alc662_init_verbs }, + .num_dacs = ARRAY_SIZE(alc662_dac_nids), + .dac_nids = alc662_dac_nids, + .dig_out_nid = ALC662_DIGOUT_NID, + .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), + .adc_nids = alc662_adc_nids, + .dig_in_nid = ALC662_DIGIN_NID, + .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), + .channel_mode = alc662_3ST_6ch_modes, + .need_dac_fix = 1, + .input_mux = &alc662_capture_source, + }, + [ALC662_3ST_6ch] = { + .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, + .init_verbs = { alc662_init_verbs }, + .num_dacs = ARRAY_SIZE(alc662_dac_nids), + .dac_nids = alc662_dac_nids, + .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), + .adc_nids = alc662_adc_nids, + .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), + .channel_mode = alc662_3ST_6ch_modes, + .need_dac_fix = 1, + .input_mux = &alc662_capture_source, + }, + [ALC662_5ST_DIG] = { + .mixers = { alc662_base_mixer, alc662_chmode_mixer }, + .init_verbs = { alc662_init_verbs }, + .num_dacs = ARRAY_SIZE(alc662_dac_nids), + .dac_nids = alc662_dac_nids, + .dig_out_nid = ALC662_DIGOUT_NID, + .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), + .adc_nids = alc662_adc_nids, + .dig_in_nid = ALC662_DIGIN_NID, + .num_channel_mode = ARRAY_SIZE(alc662_5stack_modes), + .channel_mode = alc662_5stack_modes, + .input_mux = &alc662_capture_source, + }, + [ALC662_LENOVO_101E] = { + .mixers = { alc662_lenovo_101e_mixer }, + .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs }, + .num_dacs = ARRAY_SIZE(alc662_dac_nids), + .dac_nids = alc662_dac_nids, + .num_adc_nids = ARRAY_SIZE(alc662_adc_nids), + .adc_nids = alc662_adc_nids, + .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), + .channel_mode = alc662_3ST_2ch_modes, + .input_mux = &alc662_lenovo_101e_capture_source, + .unsol_event = alc662_lenovo_101e_unsol_event, + .init_hook = alc662_lenovo_101e_all_automute, + }, + +}; + + +/* + * BIOS auto configuration + */ + +/* add playback controls from the parsed DAC table */ +static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec, + const struct auto_pin_cfg *cfg) +{ + char name[32]; + static const char *chname[4] = { + "Front", "Surround", NULL /*CLFE*/, "Side" + }; + hda_nid_t nid; + int i, err; + + for (i = 0; i < cfg->line_outs; i++) { + if (!spec->multiout.dac_nids[i]) + continue; + nid = alc880_idx_to_dac(i); + if (i == 2) { + /* Center/LFE */ + err = add_control(spec, ALC_CTL_WIDGET_VOL, + "Center Playback Volume", + HDA_COMPOSE_AMP_VAL(nid, 1, 0, + HDA_OUTPUT)); + if (err < 0) + return err; + err = add_control(spec, ALC_CTL_WIDGET_VOL, + "LFE Playback Volume", + HDA_COMPOSE_AMP_VAL(nid, 2, 0, + HDA_OUTPUT)); + if (err < 0) + return err; + err = add_control(spec, ALC_CTL_BIND_MUTE, + "Center Playback Switch", + HDA_COMPOSE_AMP_VAL(nid, 1, 2, + HDA_INPUT)); + if (err < 0) + return err; + err = add_control(spec, ALC_CTL_BIND_MUTE, + "LFE Playback Switch", + HDA_COMPOSE_AMP_VAL(nid, 2, 2, + HDA_INPUT)); + if (err < 0) + return err; + } else { + sprintf(name, "%s Playback Volume", chname[i]); + err = add_control(spec, ALC_CTL_WIDGET_VOL, name, + HDA_COMPOSE_AMP_VAL(nid, 3, 0, + HDA_OUTPUT)); + if (err < 0) + return err; + sprintf(name, "%s Playback Switch", chname[i]); + err = add_control(spec, ALC_CTL_BIND_MUTE, name, + HDA_COMPOSE_AMP_VAL(nid, 3, 2, + HDA_INPUT)); + if (err < 0) + return err; + } + } + return 0; +} + +/* add playback controls for speaker and HP outputs */ +static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, + const char *pfx) +{ + hda_nid_t nid; + int err; + char name[32]; + + if (!pin) + return 0; + + if (alc880_is_fixed_pin(pin)) { + nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); + /* printk("DAC nid=%x\n",nid); */ + /* specify the DAC as the extra output */ + if (!spec->multiout.hp_nid) + spec->multiout.hp_nid = nid; + else + spec->multiout.extra_out_nid[0] = nid; + /* control HP volume/switch on the output mixer amp */ + nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); + sprintf(name, "%s Playback Volume", pfx); + err = add_control(spec, ALC_CTL_WIDGET_VOL, name, + HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); + if (err < 0) + return err; + sprintf(name, "%s Playback Switch", pfx); + err = add_control(spec, ALC_CTL_BIND_MUTE, name, + HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT)); + if (err < 0) + return err; + } else if (alc880_is_multi_pin(pin)) { + /* set manual connection */ + /* we have only a switch on HP-out PIN */ + sprintf(name, "%s Playback Switch", pfx); + err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, + HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); + if (err < 0) + return err; + } + return 0; +} + +/* create playback/capture controls for input pins */ +static int alc662_auto_create_analog_input_ctls(struct alc_spec *spec, + const struct auto_pin_cfg *cfg) +{ + struct hda_input_mux *imux = &spec->private_imux; + int i, err, idx; + + for (i = 0; i < AUTO_PIN_LAST; i++) { + if (alc880_is_input_pin(cfg->input_pins[i])) { + idx = alc880_input_pin_idx(cfg->input_pins[i]); + err = new_analog_input(spec, cfg->input_pins[i], + auto_pin_cfg_labels[i], + idx, 0x0b); + if (err < 0) + return err; + imux->items[imux->num_items].label = + auto_pin_cfg_labels[i]; + imux->items[imux->num_items].index = + alc880_input_pin_idx(cfg->input_pins[i]); + imux->num_items++; + } + } + return 0; +} + +static void alc662_auto_set_output_and_unmute(struct hda_codec *codec, + hda_nid_t nid, int pin_type, + int dac_idx) +{ + /* set as output */ + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, pin_type); + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); + /* need the manual connection? */ + if (alc880_is_multi_pin(nid)) { + struct alc_spec *spec = codec->spec; + int idx = alc880_multi_pin_idx(nid); + snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0, + AC_VERB_SET_CONNECT_SEL, + alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx])); + } +} + +static void alc662_auto_init_multi_out(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + int i; + + for (i = 0; i <= HDA_SIDE; i++) { + hda_nid_t nid = spec->autocfg.line_out_pins[i]; + int pin_type = get_pin_type(spec->autocfg.line_out_type); + if (nid) + alc662_auto_set_output_and_unmute(codec, nid, pin_type, + i); + } +} + +static void alc662_auto_init_hp_out(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + hda_nid_t pin; + + pin = spec->autocfg.hp_pins[0]; + if (pin) /* connect to front */ + /* use dac 0 */ + alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); +} + +#define alc662_is_input_pin(nid) alc880_is_input_pin(nid) +#define ALC662_PIN_CD_NID ALC880_PIN_CD_NID + +static void alc662_auto_init_analog_input(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + int i; + + for (i = 0; i < AUTO_PIN_LAST; i++) { + hda_nid_t nid = spec->autocfg.input_pins[i]; + if (alc662_is_input_pin(nid)) { + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, + (i <= AUTO_PIN_FRONT_MIC ? + PIN_VREF80 : PIN_IN)); + if (nid != ALC662_PIN_CD_NID) + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_AMP_GAIN_MUTE, + AMP_OUT_MUTE); + } + } +} + +static int alc662_parse_auto_config(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + int err; + static hda_nid_t alc662_ignore[] = { 0x1d, 0 }; + + err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, + alc662_ignore); + if (err < 0) + return err; + if (!spec->autocfg.line_outs) + return 0; /* can't find valid BIOS pin config */ + + err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); + if (err < 0) + return err; + err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg); + if (err < 0) + return err; + err = alc662_auto_create_extra_out(spec, + spec->autocfg.speaker_pins[0], + "Speaker"); + if (err < 0) + return err; + err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], + "Headphone"); + if (err < 0) + return err; + err = alc662_auto_create_analog_input_ctls(spec, &spec->autocfg); + if (err < 0) + return err; + + spec->multiout.max_channels = spec->multiout.num_dacs * 2; + + if (spec->autocfg.dig_out_pin) + spec->multiout.dig_out_nid = ALC880_DIGOUT_NID; + + if (spec->kctl_alloc) + spec->mixers[spec->num_mixers++] = spec->kctl_alloc; + + spec->num_mux_defs = 1; + spec->input_mux = &spec->private_imux; + + if (err < 0) + return err; + else if (err > 0) + /* hack - override the init verbs */ + spec->init_verbs[0] = alc662_auto_init_verbs; + spec->mixers[spec->num_mixers] = alc662_capture_mixer; + spec->num_mixers++; + return err; +} + +/* additional initialization for auto-configuration model */ +static void alc662_auto_init(struct hda_codec *codec) +{ + alc662_auto_init_multi_out(codec); + alc662_auto_init_hp_out(codec); + alc662_auto_init_analog_input(codec); +} + +static int patch_alc662(struct hda_codec *codec) +{ + struct alc_spec *spec; + int err, board_config; + + spec = kzalloc(sizeof(*spec), GFP_KERNEL); + if (!spec) + return -ENOMEM; + + codec->spec = spec; + + board_config = snd_hda_check_board_config(codec, ALC662_MODEL_LAST, + alc662_models, + alc662_cfg_tbl); + if (board_config < 0) { + printk(KERN_INFO "hda_codec: Unknown model for ALC662, " + "trying auto-probe from BIOS...\n"); + board_config = ALC662_AUTO; + } + + if (board_config == ALC662_AUTO) { + /* automatic parse from the BIOS config */ + err = alc662_parse_auto_config(codec); + if (err < 0) { + alc_free(codec); + return err; + } else if (err) { + printk(KERN_INFO + "hda_codec: Cannot set up configuration " + "from BIOS. Using base mode...\n"); + board_config = ALC662_3ST_2ch_DIG; + } + } + + if (board_config != ALC662_AUTO) + setup_preset(spec, &alc662_presets[board_config]); + + spec->stream_name_analog = "ALC662 Analog"; + spec->stream_analog_playback = &alc662_pcm_analog_playback; + spec->stream_analog_capture = &alc662_pcm_analog_capture; + + spec->stream_name_digital = "ALC662 Digital"; + spec->stream_digital_playback = &alc662_pcm_digital_playback; + spec->stream_digital_capture = &alc662_pcm_digital_capture; + + if (!spec->adc_nids && spec->input_mux) { + spec->adc_nids = alc662_adc_nids; + spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids); + } + + codec->patch_ops = alc_patch_ops; + if (board_config == ALC662_AUTO) + spec->init_hook = alc662_auto_init; + + return 0; +} + +/* * patch entries */ struct hda_codec_preset snd_hda_preset_realtek[] = { { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", - .patch = patch_alc861 }, + .patch = patch_alc861 }, { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, { .id = 0x10ec0861, .name = "ALC861", .patch = patch_alc861 }, { .id = 0x10ec0862, .name = "ALC861-VD", .patch = patch_alc861vd }, + { .id = 0x10ec0662, .rev = 0x100002, .name = "ALC662 rev2", + .patch = patch_alc883 }, + { .id = 0x10ec0662, .rev = 0x100101, .name = "ALC662 rev1", + .patch = patch_alc662 }, { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 }, diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index c94291bc5367..93ae9c250767 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -62,6 +62,7 @@ enum { STAC_MACBOOK, STAC_MACBOOK_PRO_V1, STAC_MACBOOK_PRO_V2, + STAC_IMAC_INTEL, STAC_922X_MODELS }; @@ -175,8 +176,8 @@ static hda_nid_t stac9205_mux_nids[2] = { 0x19, 0x1a }; -static hda_nid_t stac9205_dmic_nids[3] = { - 0x17, 0x18, 0 +static hda_nid_t stac9205_dmic_nids[2] = { + 0x17, 0x18, }; static hda_nid_t stac9200_pin_nids[8] = { @@ -524,12 +525,6 @@ static unsigned int d945gtp5_pin_configs[10] = { 0x02a19320, 0x40000100, }; -static unsigned int macbook_pin_configs[10] = { - 0x0321e230, 0x03a1e020, 0x400000fd, 0x9017e110, - 0x400000fe, 0x0381e021, 0x1345e240, 0x13c5e22e, - 0x400000fc, 0x400000fb, -}; - static unsigned int macbook_pro_v1_pin_configs[10] = { 0x0321e230, 0x03a1e020, 0x9017e110, 0x01014010, 0x01a19021, 0x0381e021, 0x1345e240, 0x13c5e22e, @@ -542,14 +537,21 @@ static unsigned int macbook_pro_v2_pin_configs[10] = { 0x400000fc, 0x400000fb, }; +static unsigned int imac_intel_pin_configs[10] = { + 0x0121e230, 0x90a70120, 0x9017e110, 0x400000fe, + 0x400000fd, 0x0181e021, 0x1145e040, 0x400000fa, + 0x400000fc, 0x400000fb, +}; + static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { [STAC_D945_REF] = ref922x_pin_configs, [STAC_D945GTP3] = d945gtp3_pin_configs, [STAC_D945GTP5] = d945gtp5_pin_configs, - [STAC_MACMINI] = d945gtp5_pin_configs, - [STAC_MACBOOK] = macbook_pin_configs, + [STAC_MACMINI] = macbook_pro_v1_pin_configs, + [STAC_MACBOOK] = macbook_pro_v1_pin_configs, [STAC_MACBOOK_PRO_V1] = macbook_pro_v1_pin_configs, [STAC_MACBOOK_PRO_V2] = macbook_pro_v2_pin_configs, + [STAC_IMAC_INTEL] = imac_intel_pin_configs, }; static const char *stac922x_models[STAC_922X_MODELS] = { @@ -560,6 +562,7 @@ static const char *stac922x_models[STAC_922X_MODELS] = { [STAC_MACBOOK] = "macbook", [STAC_MACBOOK_PRO_V1] = "macbook-pro-v1", [STAC_MACBOOK_PRO_V2] = "macbook-pro", + [STAC_IMAC_INTEL] = "imac-intel", }; static struct snd_pci_quirk stac922x_cfg_tbl[] = { @@ -820,6 +823,17 @@ static int stac92xx_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, return snd_hda_multi_out_dig_close(codec, &spec->multiout); } +static int stac92xx_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + unsigned int stream_tag, + unsigned int format, + struct snd_pcm_substream *substream) +{ + struct sigmatel_spec *spec = codec->spec; + return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, + stream_tag, format, substream); +} + /* * Analog capture callbacks @@ -854,7 +868,8 @@ static struct hda_pcm_stream stac92xx_pcm_digital_playback = { /* NID is set in stac92xx_build_pcms */ .ops = { .open = stac92xx_dig_playback_pcm_open, - .close = stac92xx_dig_playback_pcm_close + .close = stac92xx_dig_playback_pcm_close, + .prepare = stac92xx_dig_playback_pcm_prepare }, }; @@ -1055,11 +1070,23 @@ static int stac92xx_add_control(struct sigmatel_spec *spec, int type, const char static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cfg *cfg) { struct sigmatel_spec *spec = codec->spec; + unsigned int wcaps, wtype; + int i, num_dacs = 0; + + /* use the wcaps cache to count all DACs available for line-outs */ + for (i = 0; i < codec->num_nodes; i++) { + wcaps = codec->wcaps[i]; + wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; + if (wtype == AC_WID_AUD_OUT && !(wcaps & AC_WCAP_DIGITAL)) + num_dacs++; + } + snd_printdd("%s: total dac count=%d\n", __func__, num_dacs); + switch (cfg->line_outs) { case 3: /* add line-in as side */ - if (cfg->input_pins[AUTO_PIN_LINE]) { + if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 3) { cfg->line_out_pins[3] = cfg->input_pins[AUTO_PIN_LINE]; spec->line_switch = 1; cfg->line_outs++; @@ -1067,12 +1094,12 @@ static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cf break; case 2: /* add line-in as clfe and mic as side */ - if (cfg->input_pins[AUTO_PIN_LINE]) { + if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 2) { cfg->line_out_pins[2] = cfg->input_pins[AUTO_PIN_LINE]; spec->line_switch = 1; cfg->line_outs++; } - if (cfg->input_pins[AUTO_PIN_MIC]) { + if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 3) { cfg->line_out_pins[3] = cfg->input_pins[AUTO_PIN_MIC]; spec->mic_switch = 1; cfg->line_outs++; @@ -1080,12 +1107,12 @@ static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cf break; case 1: /* add line-in as surr and mic as clfe */ - if (cfg->input_pins[AUTO_PIN_LINE]) { + if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 1) { cfg->line_out_pins[1] = cfg->input_pins[AUTO_PIN_LINE]; spec->line_switch = 1; cfg->line_outs++; } - if (cfg->input_pins[AUTO_PIN_MIC]) { + if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 2) { cfg->line_out_pins[2] = cfg->input_pins[AUTO_PIN_MIC]; spec->mic_switch = 1; cfg->line_outs++; @@ -1096,33 +1123,76 @@ static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cf return 0; } + +static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid) +{ + int i; + + for (i = 0; i < spec->multiout.num_dacs; i++) { + if (spec->multiout.dac_nids[i] == nid) + return 1; + } + + return 0; +} + /* - * XXX The line_out pin widget connection list may not be set to the - * desired DAC nid. This is the case on 927x where ports A and B can - * be routed to several DACs. - * - * This requires an analysis of the line-out/hp pin configuration - * to provide a best fit for pin/DAC configurations that are routable. - * For now, 927x DAC4 is not supported and 927x DAC1 output to ports - * A and B is not supported. + * Fill in the dac_nids table from the parsed pin configuration + * This function only works when every pin in line_out_pins[] + * contains atleast one DAC in its connection list. Some 92xx + * codecs are not connected directly to a DAC, such as the 9200 + * and 9202/925x. For those, dac_nids[] must be hard-coded. */ -/* fill in the dac_nids table from the parsed pin configuration */ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec, const struct auto_pin_cfg *cfg) { struct sigmatel_spec *spec = codec->spec; - hda_nid_t nid; - int i; - - /* check the pins hardwired to audio widget */ + int i, j, conn_len = 0; + hda_nid_t nid, conn[HDA_MAX_CONNECTIONS]; + unsigned int wcaps, wtype; + for (i = 0; i < cfg->line_outs; i++) { nid = cfg->line_out_pins[i]; - spec->multiout.dac_nids[i] = snd_hda_codec_read(codec, nid, 0, - AC_VERB_GET_CONNECT_LIST, 0) & 0xff; - } + conn_len = snd_hda_get_connections(codec, nid, conn, + HDA_MAX_CONNECTIONS); + for (j = 0; j < conn_len; j++) { + wcaps = snd_hda_param_read(codec, conn[j], + AC_PAR_AUDIO_WIDGET_CAP); + wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; + + if (wtype != AC_WID_AUD_OUT || + (wcaps & AC_WCAP_DIGITAL)) + continue; + /* conn[j] is a DAC routed to this line-out */ + if (!is_in_dac_nids(spec, conn[j])) + break; + } + + if (j == conn_len) { + /* error out, no available DAC found */ + snd_printk(KERN_ERR + "%s: No available DAC for pin 0x%x\n", + __func__, nid); + return -ENODEV; + } - spec->multiout.num_dacs = cfg->line_outs; + spec->multiout.dac_nids[i] = conn[j]; + spec->multiout.num_dacs++; + if (conn_len > 1) { + /* select this DAC in the pin's input mux */ + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_CONNECT_SEL, j); + + } + } + snd_printd("dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n", + spec->multiout.num_dacs, + spec->multiout.dac_nids[0], + spec->multiout.dac_nids[1], + spec->multiout.dac_nids[2], + spec->multiout.dac_nids[3], + spec->multiout.dac_nids[4]); return 0; } @@ -1189,12 +1259,8 @@ static int stac92xx_auto_create_multi_out_ctls(struct sigmatel_spec *spec, static int check_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid) { - int i; - - for (i = 0; i < spec->multiout.num_dacs; i++) { - if (spec->multiout.dac_nids[i] == nid) - return 1; - } + if (is_in_dac_nids(spec, nid)) + return 1; if (spec->multiout.hp_nid == nid) return 1; return 0; @@ -1236,12 +1302,10 @@ static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec, add_spec_dacs(spec, nid); } for (i = 0; i < cfg->speaker_outs; i++) { - nid = snd_hda_codec_read(codec, cfg->speaker_pins[0], 0, + nid = snd_hda_codec_read(codec, cfg->speaker_pins[i], 0, AC_VERB_GET_CONNECT_LIST, 0) & 0xff; if (check_in_dac_nids(spec, nid)) nid = 0; - if (check_in_dac_nids(spec, nid)) - nid = 0; if (! nid) continue; add_spec_dacs(spec, nid); @@ -1355,7 +1419,7 @@ static int stac92xx_auto_create_analog_input_ctls(struct hda_codec *codec, const imux->num_items++; } - if (imux->num_items == 1) { + if (imux->num_items) { /* * Set the current input for the muxes. * The STAC9221 has two input muxes with identical source @@ -1675,8 +1739,12 @@ static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid, { unsigned int pin_ctl = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00); - if (flag == AC_PINCTL_OUT_EN && (pin_ctl & AC_PINCTL_IN_EN)) - return; + + /* if setting pin direction bits, clear the current + direction bits first */ + if (flag & (AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN)) + pin_ctl &= ~(AC_PINCTL_IN_EN | AC_PINCTL_OUT_EN); + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, pin_ctl | flag); @@ -1751,6 +1819,7 @@ static int stac92xx_resume(struct hda_codec *codec) stac92xx_init(codec); stac92xx_set_config_regs(codec); + snd_hda_resume_ctls(codec, spec->mixer); for (i = 0; i < spec->num_mixers; i++) snd_hda_resume_ctls(codec, spec->mixers[i]); if (spec->multiout.dig_out_nid) @@ -1905,12 +1974,18 @@ static int patch_stac922x(struct hda_codec *codec) */ printk(KERN_INFO "hda_codec: STAC922x, Apple subsys_id=%x\n", codec->subsystem_id); switch (codec->subsystem_id) { + case 0x106b0a00: /* MacBook First generatoin */ + spec->board_config = STAC_MACBOOK; + break; case 0x106b0200: /* MacBook Pro first generation */ spec->board_config = STAC_MACBOOK_PRO_V1; break; case 0x106b1e00: /* MacBook Pro second generation */ spec->board_config = STAC_MACBOOK_PRO_V2; break; + case 0x106b0700: /* Intel-based iMac */ + spec->board_config = STAC_IMAC_INTEL; + break; } } @@ -1931,7 +2006,7 @@ static int patch_stac922x(struct hda_codec *codec) spec->adc_nids = stac922x_adc_nids; spec->mux_nids = stac922x_mux_nids; - spec->num_muxes = 2; + spec->num_muxes = ARRAY_SIZE(stac922x_mux_nids); spec->num_dmics = 0; spec->init = stac922x_core_init; @@ -1992,7 +2067,7 @@ static int patch_stac927x(struct hda_codec *codec) case STAC_D965_3ST: spec->adc_nids = stac927x_adc_nids; spec->mux_nids = stac927x_mux_nids; - spec->num_muxes = 3; + spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids); spec->num_dmics = 0; spec->init = d965_core_init; spec->mixer = stac9227_mixer; @@ -2000,7 +2075,7 @@ static int patch_stac927x(struct hda_codec *codec) case STAC_D965_5ST: spec->adc_nids = stac927x_adc_nids; spec->mux_nids = stac927x_mux_nids; - spec->num_muxes = 3; + spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids); spec->num_dmics = 0; spec->init = d965_core_init; spec->mixer = stac9227_mixer; @@ -2008,7 +2083,7 @@ static int patch_stac927x(struct hda_codec *codec) default: spec->adc_nids = stac927x_adc_nids; spec->mux_nids = stac927x_mux_nids; - spec->num_muxes = 3; + spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids); spec->num_dmics = 0; spec->init = stac927x_core_init; spec->mixer = stac927x_mixer; @@ -2067,9 +2142,9 @@ static int patch_stac9205(struct hda_codec *codec) spec->adc_nids = stac9205_adc_nids; spec->mux_nids = stac9205_mux_nids; - spec->num_muxes = 2; + spec->num_muxes = ARRAY_SIZE(stac9205_mux_nids); spec->dmic_nids = stac9205_dmic_nids; - spec->num_dmics = 2; + spec->num_dmics = ARRAY_SIZE(stac9205_dmic_nids); spec->dmux_nid = 0x1d; spec->init = stac9205_core_init; @@ -2294,6 +2369,7 @@ static struct snd_pci_quirk stac9872_cfg_tbl[] = { SND_PCI_QUIRK(0x104d, 0x81e6, "Sony VAIO F/S", CXD9872RD_VAIO), SND_PCI_QUIRK(0x104d, 0x81ef, "Sony VAIO F/S", CXD9872RD_VAIO), SND_PCI_QUIRK(0x104d, 0x81fd, "Sony VAIO AR", CXD9872AKD_VAIO), + SND_PCI_QUIRK(0x104d, 0x8205, "Sony VAIO AR", CXD9872AKD_VAIO), {} }; diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 2b11ac8689b9..ba32d1e52cb8 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -377,6 +377,17 @@ static int via_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, return snd_hda_multi_out_dig_close(codec, &spec->multiout); } +static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + unsigned int stream_tag, + unsigned int format, + struct snd_pcm_substream *substream) +{ + struct via_spec *spec = codec->spec; + return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, + stream_tag, format, substream); +} + /* * Analog capture */ @@ -433,7 +444,8 @@ static struct hda_pcm_stream vt1708_pcm_digital_playback = { /* NID is set in via_build_pcms */ .ops = { .open = via_dig_playback_pcm_open, - .close = via_dig_playback_pcm_close + .close = via_dig_playback_pcm_close, + .prepare = via_dig_playback_pcm_prepare }, }; diff --git a/sound/pci/ice1712/amp.c b/sound/pci/ice1712/amp.c index 6e22d326df32..44bbb630b949 100644 --- a/sound/pci/ice1712/amp.c +++ b/sound/pci/ice1712/amp.c @@ -75,7 +75,7 @@ static int __devinit snd_vt1724_amp_add_controls(struct snd_ice1712 *ice) /* entry point */ -const struct snd_ice1712_card_info snd_vt1724_amp_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_vt1724_amp_cards[] __devinitdata = { { .subvendor = VT1724_SUBDEVICE_AV710, .name = "Chaintech AV-710", diff --git a/sound/pci/ice1712/amp.h b/sound/pci/ice1712/amp.h index 7b667bad0c6b..a0fc89b48122 100644 --- a/sound/pci/ice1712/amp.h +++ b/sound/pci/ice1712/amp.h @@ -42,7 +42,7 @@ #define WM_DAC_CTRL 0x02 #define WM_INT_CTRL 0x03 -extern const struct snd_ice1712_card_info snd_vt1724_amp_cards[]; +extern struct snd_ice1712_card_info snd_vt1724_amp_cards[]; #endif /* __SOUND_AMP_H */ diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c index 6941d85dfec9..66bacde1ead3 100644 --- a/sound/pci/ice1712/aureon.c +++ b/sound/pci/ice1712/aureon.c @@ -1411,7 +1411,7 @@ static int aureon_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ctl * mixers */ -static const struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = { +static struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", @@ -1526,7 +1526,7 @@ static const struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = { } }; -static const struct snd_kcontrol_new wm_controls[] __devinitdata = { +static struct snd_kcontrol_new wm_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "PCM Playback Switch", @@ -1592,7 +1592,7 @@ static const struct snd_kcontrol_new wm_controls[] __devinitdata = { } }; -static const struct snd_kcontrol_new ac97_controls[] __devinitdata = { +static struct snd_kcontrol_new ac97_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "AC97 Playback Switch", @@ -1697,7 +1697,7 @@ static const struct snd_kcontrol_new ac97_controls[] __devinitdata = { } }; -static const struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = { +static struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "AC97 Playback Switch", @@ -1829,7 +1829,7 @@ static const struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = { }; -static const struct snd_kcontrol_new cs8415_controls[] __devinitdata = { +static struct snd_kcontrol_new cs8415_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), @@ -2107,7 +2107,7 @@ static int __devinit aureon_init(struct snd_ice1712 *ice) * hence the driver needs to sets up it properly. */ -static const unsigned char aureon51_eeprom[] __devinitdata = { +static unsigned char aureon51_eeprom[] __devinitdata = { [ICE_EEP2_SYSCONF] = 0x0a, /* clock 512, spdif-in/ADC, 3DACs */ [ICE_EEP2_ACLINK] = 0x80, /* I2S */ [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */ @@ -2123,7 +2123,7 @@ static const unsigned char aureon51_eeprom[] __devinitdata = { [ICE_EEP2_GPIO_STATE2] = 0x00, }; -static const unsigned char aureon71_eeprom[] __devinitdata = { +static unsigned char aureon71_eeprom[] __devinitdata = { [ICE_EEP2_SYSCONF] = 0x0b, /* clock 512, spdif-in/ADC, 4DACs */ [ICE_EEP2_ACLINK] = 0x80, /* I2S */ [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */ @@ -2140,7 +2140,7 @@ static const unsigned char aureon71_eeprom[] __devinitdata = { }; #define prodigy71_eeprom aureon71_eeprom -static const unsigned char prodigy71lt_eeprom[] __devinitdata = { +static unsigned char prodigy71lt_eeprom[] __devinitdata = { [ICE_EEP2_SYSCONF] = 0x4b, /* clock 384, spdif-in/ADC, 4DACs */ [ICE_EEP2_ACLINK] = 0x80, /* I2S */ [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */ @@ -2158,7 +2158,7 @@ static const unsigned char prodigy71lt_eeprom[] __devinitdata = { #define prodigy71xt_eeprom prodigy71lt_eeprom /* entry point */ -const struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = { { .subvendor = VT1724_SUBDEVICE_AUREON51_SKY, .name = "Terratec Aureon 5.1-Sky", diff --git a/sound/pci/ice1712/aureon.h b/sound/pci/ice1712/aureon.h index 79e58e88ed47..c253b8e2c789 100644 --- a/sound/pci/ice1712/aureon.h +++ b/sound/pci/ice1712/aureon.h @@ -38,7 +38,7 @@ #define VT1724_SUBDEVICE_PRODIGY71LT 0x32315441 /* PRODIGY 7.1 LT */ #define VT1724_SUBDEVICE_PRODIGY71XT 0x36315441 /* PRODIGY 7.1 XT*/ -extern const struct snd_ice1712_card_info snd_vt1724_aureon_cards[]; +extern struct snd_ice1712_card_info snd_vt1724_aureon_cards[]; /* GPIO bits */ #define AUREON_CS8415_CS (1 << 22) diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c index 3eeb36c6e985..af659800c9b0 100644 --- a/sound/pci/ice1712/delta.c +++ b/sound/pci/ice1712/delta.c @@ -416,7 +416,7 @@ static int snd_ice1712_delta1010lt_wordclock_status_get(struct snd_kcontrol *kco return 0; } -static const struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_status __devinitdata = +static struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_status __devinitdata = { .access = (SNDRV_CTL_ELEM_ACCESS_READ), .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -429,7 +429,7 @@ static const struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_status __ * initialize the chips on M-Audio cards */ -static const struct snd_akm4xxx akm_audiophile __devinitdata = { +static struct snd_akm4xxx akm_audiophile __devinitdata = { .type = SND_AK4528, .num_adcs = 2, .num_dacs = 2, @@ -438,7 +438,7 @@ static const struct snd_akm4xxx akm_audiophile __devinitdata = { } }; -static const struct snd_ak4xxx_private akm_audiophile_priv __devinitdata = { +static struct snd_ak4xxx_private akm_audiophile_priv __devinitdata = { .caddr = 2, .cif = 0, .data_mask = ICE1712_DELTA_AP_DOUT, @@ -450,7 +450,7 @@ static const struct snd_ak4xxx_private akm_audiophile_priv __devinitdata = { .mask_flags = 0, }; -static const struct snd_akm4xxx akm_delta410 __devinitdata = { +static struct snd_akm4xxx akm_delta410 __devinitdata = { .type = SND_AK4529, .num_adcs = 2, .num_dacs = 8, @@ -459,7 +459,7 @@ static const struct snd_akm4xxx akm_delta410 __devinitdata = { } }; -static const struct snd_ak4xxx_private akm_delta410_priv __devinitdata = { +static struct snd_ak4xxx_private akm_delta410_priv __devinitdata = { .caddr = 0, .cif = 0, .data_mask = ICE1712_DELTA_AP_DOUT, @@ -471,7 +471,7 @@ static const struct snd_ak4xxx_private akm_delta410_priv __devinitdata = { .mask_flags = 0, }; -static const struct snd_akm4xxx akm_delta1010lt __devinitdata = { +static struct snd_akm4xxx akm_delta1010lt __devinitdata = { .type = SND_AK4524, .num_adcs = 8, .num_dacs = 8, @@ -481,7 +481,7 @@ static const struct snd_akm4xxx akm_delta1010lt __devinitdata = { } }; -static const struct snd_ak4xxx_private akm_delta1010lt_priv __devinitdata = { +static struct snd_ak4xxx_private akm_delta1010lt_priv __devinitdata = { .caddr = 2, .cif = 0, /* the default level of the CIF pin from AK4524 */ .data_mask = ICE1712_DELTA_1010LT_DOUT, @@ -493,7 +493,7 @@ static const struct snd_ak4xxx_private akm_delta1010lt_priv __devinitdata = { .mask_flags = 0, }; -static const struct snd_akm4xxx akm_delta44 __devinitdata = { +static struct snd_akm4xxx akm_delta44 __devinitdata = { .type = SND_AK4524, .num_adcs = 4, .num_dacs = 4, @@ -503,7 +503,7 @@ static const struct snd_akm4xxx akm_delta44 __devinitdata = { } }; -static const struct snd_ak4xxx_private akm_delta44_priv __devinitdata = { +static struct snd_ak4xxx_private akm_delta44_priv __devinitdata = { .caddr = 2, .cif = 0, /* the default level of the CIF pin from AK4524 */ .data_mask = ICE1712_DELTA_CODEC_SERIAL_DATA, @@ -515,7 +515,7 @@ static const struct snd_ak4xxx_private akm_delta44_priv __devinitdata = { .mask_flags = 0, }; -static const struct snd_akm4xxx akm_vx442 __devinitdata = { +static struct snd_akm4xxx akm_vx442 __devinitdata = { .type = SND_AK4524, .num_adcs = 4, .num_dacs = 4, @@ -525,7 +525,7 @@ static const struct snd_akm4xxx akm_vx442 __devinitdata = { } }; -static const struct snd_ak4xxx_private akm_vx442_priv __devinitdata = { +static struct snd_ak4xxx_private akm_vx442_priv __devinitdata = { .caddr = 2, .cif = 0, .data_mask = ICE1712_VX442_DOUT, @@ -650,15 +650,15 @@ static int __devinit snd_ice1712_delta_init(struct snd_ice1712 *ice) * additional controls for M-Audio cards */ -static const struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_select __devinitdata = +static struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_select __devinitdata = ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_WORD_CLOCK_SELECT, 1, 0); -static const struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_select __devinitdata = +static struct snd_kcontrol_new snd_ice1712_delta1010lt_wordclock_select __devinitdata = ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Sync", 0, ICE1712_DELTA_1010LT_WORDCLOCK, 0, 0); -static const struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_status __devinitdata = +static struct snd_kcontrol_new snd_ice1712_delta1010_wordclock_status __devinitdata = ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Word Clock Status", 0, ICE1712_DELTA_WORD_CLOCK_STATUS, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE); -static const struct snd_kcontrol_new snd_ice1712_deltadio2496_spdif_in_select __devinitdata = +static struct snd_kcontrol_new snd_ice1712_deltadio2496_spdif_in_select __devinitdata = ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "IEC958 Input Optical", 0, ICE1712_DELTA_SPDIF_INPUT_SELECT, 0, 0); -static const struct snd_kcontrol_new snd_ice1712_delta_spdif_in_status __devinitdata = +static struct snd_kcontrol_new snd_ice1712_delta_spdif_in_status __devinitdata = ICE1712_GPIO(SNDRV_CTL_ELEM_IFACE_MIXER, "Delta IEC958 Input Status", 0, ICE1712_DELTA_SPDIF_IN_STAT, 1, SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE); @@ -735,7 +735,7 @@ static int __devinit snd_ice1712_delta_add_controls(struct snd_ice1712 *ice) /* entry point */ -const struct snd_ice1712_card_info snd_ice1712_delta_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_ice1712_delta_cards[] __devinitdata = { { .subvendor = ICE1712_SUBDEVICE_DELTA1010, .name = "M Audio Delta 1010", diff --git a/sound/pci/ice1712/delta.h b/sound/pci/ice1712/delta.h index e47861ccd6e7..2697156607e4 100644 --- a/sound/pci/ice1712/delta.h +++ b/sound/pci/ice1712/delta.h @@ -46,7 +46,7 @@ #define ICE1712_SUBDEVICE_MEDIASTATION 0x694c0100 /* entry point */ -extern const struct snd_ice1712_card_info snd_ice1712_delta_cards[]; +extern struct snd_ice1712_card_info snd_ice1712_delta_cards[]; /* diff --git a/sound/pci/ice1712/ews.c b/sound/pci/ice1712/ews.c index 9b7ff302c072..b135389fec6c 100644 --- a/sound/pci/ice1712/ews.c +++ b/sound/pci/ice1712/ews.c @@ -332,7 +332,7 @@ static void ews88_setup_spdif(struct snd_ice1712 *ice, int rate) /* */ -static const struct snd_akm4xxx akm_ews88mt __devinitdata = { +static struct snd_akm4xxx akm_ews88mt __devinitdata = { .num_adcs = 8, .num_dacs = 8, .type = SND_AK4524, @@ -342,7 +342,7 @@ static const struct snd_akm4xxx akm_ews88mt __devinitdata = { } }; -static const struct snd_ak4xxx_private akm_ews88mt_priv __devinitdata = { +static struct snd_ak4xxx_private akm_ews88mt_priv __devinitdata = { .caddr = 2, .cif = 1, /* CIF high */ .data_mask = ICE1712_EWS88_SERIAL_DATA, @@ -354,7 +354,7 @@ static const struct snd_ak4xxx_private akm_ews88mt_priv __devinitdata = { .mask_flags = 0, }; -static const struct snd_akm4xxx akm_ewx2496 __devinitdata = { +static struct snd_akm4xxx akm_ewx2496 __devinitdata = { .num_adcs = 2, .num_dacs = 2, .type = SND_AK4524, @@ -363,7 +363,7 @@ static const struct snd_akm4xxx akm_ewx2496 __devinitdata = { } }; -static const struct snd_ak4xxx_private akm_ewx2496_priv __devinitdata = { +static struct snd_ak4xxx_private akm_ewx2496_priv __devinitdata = { .caddr = 2, .cif = 1, /* CIF high */ .data_mask = ICE1712_EWS88_SERIAL_DATA, @@ -375,7 +375,7 @@ static const struct snd_ak4xxx_private akm_ewx2496_priv __devinitdata = { .mask_flags = 0, }; -static const struct snd_akm4xxx akm_6fire __devinitdata = { +static struct snd_akm4xxx akm_6fire __devinitdata = { .num_adcs = 6, .num_dacs = 6, .type = SND_AK4524, @@ -384,7 +384,7 @@ static const struct snd_akm4xxx akm_6fire __devinitdata = { } }; -static const struct snd_ak4xxx_private akm_6fire_priv __devinitdata = { +static struct snd_ak4xxx_private akm_6fire_priv __devinitdata = { .caddr = 2, .cif = 1, /* CIF high */ .data_mask = ICE1712_6FIRE_SERIAL_DATA, @@ -578,7 +578,7 @@ static int snd_ice1712_ewx_io_sense_put(struct snd_kcontrol *kcontrol, struct sn return val != nval; } -static const struct snd_kcontrol_new snd_ice1712_ewx2496_controls[] __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_ewx2496_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Input Sensitivity Switch", @@ -678,7 +678,7 @@ static int snd_ice1712_ews88mt_input_sense_put(struct snd_kcontrol *kcontrol, st return ndata != data; } -static const struct snd_kcontrol_new snd_ice1712_ews88mt_input_sense __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_ews88mt_input_sense __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Input Sensitivity Switch", .info = snd_ice1712_ewx_io_sense_info, @@ -687,7 +687,7 @@ static const struct snd_kcontrol_new snd_ice1712_ews88mt_input_sense __devinitda .count = 8, }; -static const struct snd_kcontrol_new snd_ice1712_ews88mt_output_sense __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_ews88mt_output_sense __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Output Sensitivity Switch", .info = snd_ice1712_ewx_io_sense_info, @@ -769,7 +769,7 @@ static int snd_ice1712_ews88d_control_put(struct snd_kcontrol *kcontrol, struct .private_value = xshift | (xinvert << 8),\ } -static const struct snd_kcontrol_new snd_ice1712_ews88d_controls[] __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_ews88d_controls[] __devinitdata = { EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "IEC958 Input Optical", 0, 1, 0), /* inverted */ EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT Output Optical", 1, 0, 0), EWS88D_CONTROL(SNDRV_CTL_ELEM_IFACE_MIXER, "ADAT External Master Clock", 2, 0, 0), @@ -909,7 +909,7 @@ static int snd_ice1712_6fire_select_input_put(struct snd_kcontrol *kcontrol, str .private_value = xshift | (xinvert << 8),\ } -static const struct snd_kcontrol_new snd_ice1712_6fire_controls[] __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_6fire_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Analog Input Select", @@ -989,7 +989,7 @@ static int __devinit snd_ice1712_ews_add_controls(struct snd_ice1712 *ice) /* entry point */ -const struct snd_ice1712_card_info snd_ice1712_ews_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_ice1712_ews_cards[] __devinitdata = { { .subvendor = ICE1712_SUBDEVICE_EWX2496, .name = "TerraTec EWX24/96", diff --git a/sound/pci/ice1712/ews.h b/sound/pci/ice1712/ews.h index df449b4741f6..a12a0b053558 100644 --- a/sound/pci/ice1712/ews.h +++ b/sound/pci/ice1712/ews.h @@ -40,7 +40,7 @@ #define ICE1712_SUBDEVICE_PHASE88 0x3b155111 /* entry point */ -extern const struct snd_ice1712_card_info snd_ice1712_ews_cards[]; +extern struct snd_ice1712_card_info snd_ice1712_ews_cards[]; /* TerraTec EWX 24/96 configuration definitions */ diff --git a/sound/pci/ice1712/hoontech.c b/sound/pci/ice1712/hoontech.c index df97313aaf83..8203562ef7e7 100644 --- a/sound/pci/ice1712/hoontech.c +++ b/sound/pci/ice1712/hoontech.c @@ -239,7 +239,7 @@ static void stdsp24_ak4524_lock(struct snd_akm4xxx *ak, int chip) static int __devinit snd_ice1712_value_init(struct snd_ice1712 *ice) { /* Hoontech STDSP24 with modified hardware */ - static const struct snd_akm4xxx akm_stdsp24_mv __devinitdata = { + static struct snd_akm4xxx akm_stdsp24_mv __devinitdata = { .num_adcs = 2, .num_dacs = 2, .type = SND_AK4524, @@ -248,7 +248,7 @@ static int __devinit snd_ice1712_value_init(struct snd_ice1712 *ice) } }; - static const struct snd_ak4xxx_private akm_stdsp24_mv_priv __devinitdata = { + static struct snd_ak4xxx_private akm_stdsp24_mv_priv __devinitdata = { .caddr = 2, .cif = 1, /* CIF high */ .data_mask = ICE1712_STDSP24_SERIAL_DATA, @@ -298,7 +298,7 @@ static int __devinit snd_ice1712_ez8_init(struct snd_ice1712 *ice) /* entry point */ -const struct snd_ice1712_card_info snd_ice1712_hoontech_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_ice1712_hoontech_cards[] __devinitdata = { { .subvendor = ICE1712_SUBDEVICE_STDSP24, .name = "Hoontech SoundTrack Audio DSP24", diff --git a/sound/pci/ice1712/hoontech.h b/sound/pci/ice1712/hoontech.h index b62d6e4f6c71..1ee538b20fbf 100644 --- a/sound/pci/ice1712/hoontech.h +++ b/sound/pci/ice1712/hoontech.h @@ -35,7 +35,7 @@ #define ICE1712_SUBDEVICE_STDSP24_MEDIA7_1 0x16141217 /* Hoontech ST Audio DSP24 Media 7.1 */ #define ICE1712_SUBDEVICE_EVENT_EZ8 0x00010001 /* A dummy id for EZ8 */ -extern const struct snd_ice1712_card_info snd_ice1712_hoontech_cards[]; +extern struct snd_ice1712_card_info snd_ice1712_hoontech_cards[]; /* Hoontech SoundTrack Audio DSP 24 GPIO definitions */ diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c index 830a1bbd7110..6630a0ae9527 100644 --- a/sound/pci/ice1712/ice1712.c +++ b/sound/pci/ice1712/ice1712.c @@ -287,7 +287,7 @@ static int snd_ice1712_digmix_route_ac97_put(struct snd_kcontrol *kcontrol, stru return val != nval; } -static const struct snd_kcontrol_new snd_ice1712_mixer_digmix_route_ac97 __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_mixer_digmix_route_ac97 __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Digital Mixer To AC97", .info = snd_ice1712_digmix_route_ac97_info, @@ -977,11 +977,9 @@ static int snd_ice1712_pro_trigger(struct snd_pcm_substream *substream, { unsigned int what = 0; unsigned int old; - struct list_head *pos; struct snd_pcm_substream *s; - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if (s == ice->playback_pro_substream) { what |= ICE1712_PLAYBACK_START; snd_pcm_trigger_done(s, substream); @@ -1380,7 +1378,7 @@ static int snd_ice1712_pro_mixer_volume_put(struct snd_kcontrol *kcontrol, struc static const DECLARE_TLV_DB_SCALE(db_scale_playback, -14400, 150, 0); -static const struct snd_kcontrol_new snd_ice1712_multi_playback_ctrls[] __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_multi_playback_ctrls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Multi Playback Switch", @@ -1404,7 +1402,7 @@ static const struct snd_kcontrol_new snd_ice1712_multi_playback_ctrls[] __devini }, }; -static const struct snd_kcontrol_new snd_ice1712_multi_capture_analog_switch __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_switch __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "H/W Multi Capture Switch", .info = snd_ice1712_pro_mixer_switch_info, @@ -1413,7 +1411,7 @@ static const struct snd_kcontrol_new snd_ice1712_multi_capture_analog_switch __d .private_value = 10, }; -static const struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_switch __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_switch __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = SNDRV_CTL_NAME_IEC958("Multi ",CAPTURE,SWITCH), .info = snd_ice1712_pro_mixer_switch_info, @@ -1423,7 +1421,7 @@ static const struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_switch __de .count = 2, }; -static const struct snd_kcontrol_new snd_ice1712_multi_capture_analog_volume __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_volume __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ), @@ -1435,7 +1433,7 @@ static const struct snd_kcontrol_new snd_ice1712_multi_capture_analog_volume __d .tlv = { .p = db_scale_playback } }; -static const struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_volume __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_multi_capture_spdif_volume __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = SNDRV_CTL_NAME_IEC958("Multi ",CAPTURE,VOLUME), .info = snd_ice1712_pro_mixer_volume_info, @@ -1627,7 +1625,7 @@ static int snd_ice1712_eeprom_get(struct snd_kcontrol *kcontrol, return 0; } -static const struct snd_kcontrol_new snd_ice1712_eeprom __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_eeprom __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_CARD, .name = "ICE1712 EEPROM", .access = SNDRV_CTL_ELEM_ACCESS_READ, @@ -1663,7 +1661,7 @@ static int snd_ice1712_spdif_default_put(struct snd_kcontrol *kcontrol, return 0; } -static const struct snd_kcontrol_new snd_ice1712_spdif_default __devinitdata = +static struct snd_kcontrol_new snd_ice1712_spdif_default __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), @@ -1714,7 +1712,7 @@ static int snd_ice1712_spdif_maskp_get(struct snd_kcontrol *kcontrol, return 0; } -static const struct snd_kcontrol_new snd_ice1712_spdif_maskc __devinitdata = +static struct snd_kcontrol_new snd_ice1712_spdif_maskc __devinitdata = { .access = SNDRV_CTL_ELEM_ACCESS_READ, .iface = SNDRV_CTL_ELEM_IFACE_PCM, @@ -1723,7 +1721,7 @@ static const struct snd_kcontrol_new snd_ice1712_spdif_maskc __devinitdata = .get = snd_ice1712_spdif_maskc_get, }; -static const struct snd_kcontrol_new snd_ice1712_spdif_maskp __devinitdata = +static struct snd_kcontrol_new snd_ice1712_spdif_maskp __devinitdata = { .access = SNDRV_CTL_ELEM_ACCESS_READ, .iface = SNDRV_CTL_ELEM_IFACE_PCM, @@ -1750,7 +1748,7 @@ static int snd_ice1712_spdif_stream_put(struct snd_kcontrol *kcontrol, return 0; } -static const struct snd_kcontrol_new snd_ice1712_spdif_stream __devinitdata = +static struct snd_kcontrol_new snd_ice1712_spdif_stream __devinitdata = { .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE), @@ -1891,7 +1889,7 @@ static int snd_ice1712_pro_internal_clock_put(struct snd_kcontrol *kcontrol, return change; } -static const struct snd_kcontrol_new snd_ice1712_pro_internal_clock __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_pro_internal_clock __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Multi Track Internal Clock", .info = snd_ice1712_pro_internal_clock_info, @@ -1962,7 +1960,7 @@ static int snd_ice1712_pro_internal_clock_default_put(struct snd_kcontrol *kcont return change; } -static const struct snd_kcontrol_new snd_ice1712_pro_internal_clock_default __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_pro_internal_clock_default __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Multi Track Internal Clock Default", .info = snd_ice1712_pro_internal_clock_default_info, @@ -2001,7 +1999,7 @@ static int snd_ice1712_pro_rate_locking_put(struct snd_kcontrol *kcontrol, return change; } -static const struct snd_kcontrol_new snd_ice1712_pro_rate_locking __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_pro_rate_locking __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Multi Track Rate Locking", .info = snd_ice1712_pro_rate_locking_info, @@ -2040,7 +2038,7 @@ static int snd_ice1712_pro_rate_reset_put(struct snd_kcontrol *kcontrol, return change; } -static const struct snd_kcontrol_new snd_ice1712_pro_rate_reset __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_pro_rate_reset __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Multi Track Rate Reset", .info = snd_ice1712_pro_rate_reset_info, @@ -2207,7 +2205,7 @@ static int snd_ice1712_pro_route_spdif_put(struct snd_kcontrol *kcontrol, return change; } -static const struct snd_kcontrol_new snd_ice1712_mixer_pro_analog_route __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_mixer_pro_analog_route __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "H/W Playback Route", .info = snd_ice1712_pro_route_info, @@ -2215,7 +2213,7 @@ static const struct snd_kcontrol_new snd_ice1712_mixer_pro_analog_route __devini .put = snd_ice1712_pro_route_analog_put, }; -static const struct snd_kcontrol_new snd_ice1712_mixer_pro_spdif_route __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_mixer_pro_spdif_route __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route", .info = snd_ice1712_pro_route_info, @@ -2257,7 +2255,7 @@ static int snd_ice1712_pro_volume_rate_put(struct snd_kcontrol *kcontrol, return change; } -static const struct snd_kcontrol_new snd_ice1712_mixer_pro_volume_rate __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_mixer_pro_volume_rate __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Multi Track Volume Rate", .info = snd_ice1712_pro_volume_rate_info, @@ -2290,7 +2288,7 @@ static int snd_ice1712_pro_peak_get(struct snd_kcontrol *kcontrol, return 0; } -static const struct snd_kcontrol_new snd_ice1712_mixer_pro_peak __devinitdata = { +static struct snd_kcontrol_new snd_ice1712_mixer_pro_peak __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Multi Track Peak", .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, @@ -2305,7 +2303,7 @@ static const struct snd_kcontrol_new snd_ice1712_mixer_pro_peak __devinitdata = /* * list of available boards */ -static const struct snd_ice1712_card_info *card_tables[] __devinitdata = { +static struct snd_ice1712_card_info *card_tables[] __devinitdata = { snd_ice1712_hoontech_cards, snd_ice1712_delta_cards, snd_ice1712_ews_cards, @@ -2329,7 +2327,7 @@ static int __devinit snd_ice1712_read_eeprom(struct snd_ice1712 *ice, { int dev = 0xa0; /* EEPROM device address */ unsigned int i, size; - const struct snd_ice1712_card_info **tbl, *c; + struct snd_ice1712_card_info * const *tbl, *c; if (! modelname || ! *modelname) { ice->eeprom.subvendor = 0; @@ -2658,7 +2656,7 @@ static int __devinit snd_ice1712_create(struct snd_card *card, * */ -static const struct snd_ice1712_card_info no_matched __devinitdata; +static struct snd_ice1712_card_info no_matched __devinitdata; static int __devinit snd_ice1712_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) @@ -2667,7 +2665,7 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci, struct snd_card *card; struct snd_ice1712 *ice; int pcm_dev = 0, err; - const struct snd_ice1712_card_info **tbl, *c; + struct snd_ice1712_card_info * const *tbl, *c; if (dev >= SNDRV_CARDS) return -ENODEV; diff --git a/sound/pci/ice1712/ice1712.h b/sound/pci/ice1712/ice1712.h index c3d9feaaf57d..6ac486d9c138 100644 --- a/sound/pci/ice1712/ice1712.h +++ b/sound/pci/ice1712/ice1712.h @@ -397,6 +397,9 @@ struct snd_ice1712 { struct ak4114 *ak4114; unsigned int analog: 1; } juli; + struct { + struct ak4114 *ak4114; + } prodigy192; } spec; }; diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c index 1127ebdf5fec..ee620dea7ef3 100644 --- a/sound/pci/ice1712/ice1724.c +++ b/sound/pci/ice1712/ice1724.c @@ -337,13 +337,11 @@ static int snd_vt1724_pcm_trigger(struct snd_pcm_substream *substream, int cmd) struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); unsigned char what; unsigned char old; - struct list_head *pos; struct snd_pcm_substream *s; what = 0; - snd_pcm_group_for_each(pos, substream) { + snd_pcm_group_for_each_entry(s, substream) { const struct vt1724_pcm_reg *reg; - s = snd_pcm_group_substream_entry(pos); reg = s->runtime->private_data; what |= reg->start; snd_pcm_trigger_done(s, substream); @@ -1318,7 +1316,7 @@ static int snd_vt1724_eeprom_get(struct snd_kcontrol *kcontrol, return 0; } -static const struct snd_kcontrol_new snd_vt1724_eeprom __devinitdata = { +static struct snd_kcontrol_new snd_vt1724_eeprom __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_CARD, .name = "ICE1724 EEPROM", .access = SNDRV_CTL_ELEM_ACCESS_READ, @@ -1431,7 +1429,7 @@ static int snd_vt1724_spdif_default_put(struct snd_kcontrol *kcontrol, return (val != old); } -static const struct snd_kcontrol_new snd_vt1724_spdif_default __devinitdata = +static struct snd_kcontrol_new snd_vt1724_spdif_default __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_PCM, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), @@ -1463,7 +1461,7 @@ static int snd_vt1724_spdif_maskp_get(struct snd_kcontrol *kcontrol, return 0; } -static const struct snd_kcontrol_new snd_vt1724_spdif_maskc __devinitdata = +static struct snd_kcontrol_new snd_vt1724_spdif_maskc __devinitdata = { .access = SNDRV_CTL_ELEM_ACCESS_READ, .iface = SNDRV_CTL_ELEM_IFACE_PCM, @@ -1472,7 +1470,7 @@ static const struct snd_kcontrol_new snd_vt1724_spdif_maskc __devinitdata = .get = snd_vt1724_spdif_maskc_get, }; -static const struct snd_kcontrol_new snd_vt1724_spdif_maskp __devinitdata = +static struct snd_kcontrol_new snd_vt1724_spdif_maskp __devinitdata = { .access = SNDRV_CTL_ELEM_ACCESS_READ, .iface = SNDRV_CTL_ELEM_IFACE_PCM, @@ -1517,7 +1515,7 @@ static int snd_vt1724_spdif_sw_put(struct snd_kcontrol *kcontrol, return old != val; } -static const struct snd_kcontrol_new snd_vt1724_spdif_switch __devinitdata = +static struct snd_kcontrol_new snd_vt1724_spdif_switch __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, /* FIXME: the following conflict with IEC958 Playback Route */ @@ -1668,7 +1666,12 @@ static int snd_vt1724_pro_internal_clock_put(struct snd_kcontrol *kcontrol, spin_lock_irq(&ice->reg_lock); oval = inb(ICEMT1724(ice, RATE)); if (ucontrol->value.enumerated.item[0] == spdif) { + unsigned char i2s_oval; outb(oval | VT1724_SPDIF_MASTER, ICEMT1724(ice, RATE)); + /* setting 256fs */ + i2s_oval = inb(ICEMT1724(ice, I2S_FORMAT)); + outb(i2s_oval & ~VT1724_MT_I2S_MCLK_128X, + ICEMT1724(ice, I2S_FORMAT)); } else { rate = rates[ucontrol->value.integer.value[0] % 15]; if (rate <= get_max_rate(ice)) { @@ -1695,7 +1698,7 @@ static int snd_vt1724_pro_internal_clock_put(struct snd_kcontrol *kcontrol, return change; } -static const struct snd_kcontrol_new snd_vt1724_pro_internal_clock __devinitdata = { +static struct snd_kcontrol_new snd_vt1724_pro_internal_clock __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Multi Track Internal Clock", .info = snd_vt1724_pro_internal_clock_info, @@ -1734,7 +1737,7 @@ static int snd_vt1724_pro_rate_locking_put(struct snd_kcontrol *kcontrol, return change; } -static const struct snd_kcontrol_new snd_vt1724_pro_rate_locking __devinitdata = { +static struct snd_kcontrol_new snd_vt1724_pro_rate_locking __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Multi Track Rate Locking", .info = snd_vt1724_pro_rate_locking_info, @@ -1773,7 +1776,7 @@ static int snd_vt1724_pro_rate_reset_put(struct snd_kcontrol *kcontrol, return change; } -static const struct snd_kcontrol_new snd_vt1724_pro_rate_reset __devinitdata = { +static struct snd_kcontrol_new snd_vt1724_pro_rate_reset __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Multi Track Rate Reset", .info = snd_vt1724_pro_rate_reset_info, @@ -1892,7 +1895,7 @@ static int snd_vt1724_pro_route_spdif_put(struct snd_kcontrol *kcontrol, digital_route_shift(idx)); } -static const struct snd_kcontrol_new snd_vt1724_mixer_pro_analog_route __devinitdata = { +static struct snd_kcontrol_new snd_vt1724_mixer_pro_analog_route __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "H/W Playback Route", .info = snd_vt1724_pro_route_info, @@ -1900,7 +1903,7 @@ static const struct snd_kcontrol_new snd_vt1724_mixer_pro_analog_route __devinit .put = snd_vt1724_pro_route_analog_put, }; -static const struct snd_kcontrol_new snd_vt1724_mixer_pro_spdif_route __devinitdata = { +static struct snd_kcontrol_new snd_vt1724_mixer_pro_spdif_route __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Route", .info = snd_vt1724_pro_route_info, @@ -1936,7 +1939,7 @@ static int snd_vt1724_pro_peak_get(struct snd_kcontrol *kcontrol, return 0; } -static const struct snd_kcontrol_new snd_vt1724_mixer_pro_peak __devinitdata = { +static struct snd_kcontrol_new snd_vt1724_mixer_pro_peak __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Multi Track Peak", .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, @@ -1948,9 +1951,9 @@ static const struct snd_kcontrol_new snd_vt1724_mixer_pro_peak __devinitdata = { * */ -static const struct snd_ice1712_card_info no_matched __devinitdata; +static struct snd_ice1712_card_info no_matched __devinitdata; -static const struct snd_ice1712_card_info *card_tables[] __devinitdata = { +static struct snd_ice1712_card_info *card_tables[] __devinitdata = { snd_vt1724_revo_cards, snd_vt1724_amp_cards, snd_vt1724_aureon_cards, @@ -2009,7 +2012,7 @@ static int __devinit snd_vt1724_read_eeprom(struct snd_ice1712 *ice, { const int dev = 0xa0; /* EEPROM device address */ unsigned int i, size; - const struct snd_ice1712_card_info **tbl, *c; + struct snd_ice1712_card_info * const *tbl, *c; if (! modelname || ! *modelname) { ice->eeprom.subvendor = 0; @@ -2308,7 +2311,7 @@ static int __devinit snd_vt1724_probe(struct pci_dev *pci, struct snd_card *card; struct snd_ice1712 *ice; int pcm_dev = 0, err; - const struct snd_ice1712_card_info **tbl, *c; + struct snd_ice1712_card_info * const *tbl, *c; if (dev >= SNDRV_CARDS) return -ENODEV; @@ -2347,6 +2350,14 @@ static int __devinit snd_vt1724_probe(struct pci_dev *pci, } c = &no_matched; __found: + /* + * VT1724 has separate DMAs for the analog and the SPDIF streams while + * ICE1712 has only one for both (mixed up). + * + * Confusingly the analog PCM is named "professional" here because it + * was called so in ice1712 driver, and vt1724 driver is derived from + * ice1712 driver. + */ if ((err = snd_vt1724_pcm_profi(ice, pcm_dev++)) < 0) { snd_card_free(card); diff --git a/sound/pci/ice1712/juli.c b/sound/pci/ice1712/juli.c index d88172fa95da..3d8e74e493d7 100644 --- a/sound/pci/ice1712/juli.c +++ b/sound/pci/ice1712/juli.c @@ -125,7 +125,7 @@ static void juli_akm_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate) snd_akm4xxx_reset(ak, 0); } -static const struct snd_akm4xxx akm_juli_dac __devinitdata = { +static struct snd_akm4xxx akm_juli_dac __devinitdata = { .type = SND_AK4358, .num_dacs = 2, .ops = { @@ -138,7 +138,16 @@ static const struct snd_akm4xxx akm_juli_dac __devinitdata = { static int __devinit juli_add_controls(struct snd_ice1712 *ice) { - return snd_ice1712_akm4xxx_build_controls(ice); + int err; + err = snd_ice1712_akm4xxx_build_controls(ice); + if (err < 0) + return err; + /* only capture SPDIF over AK4114 */ + err = snd_ak4114_build(ice->spec.juli.ak4114, NULL, + ice->pcm_pro->streams[SNDRV_PCM_STREAM_CAPTURE].substream); + if (err < 0) + return err; + return 0; } /* @@ -160,13 +169,6 @@ static int __devinit juli_init(struct snd_ice1712 *ice) int err; struct snd_akm4xxx *ak; -#if 0 - for (err = 0; err < 0x20; err++) - juli_ak4114_read(ice, err); - juli_ak4114_write(ice, 0, 0x0f); - juli_ak4114_read(ice, 0); - juli_ak4114_read(ice, 1); -#endif err = snd_ak4114_create(ice->card, juli_ak4114_read, juli_ak4114_write, @@ -206,7 +208,7 @@ static int __devinit juli_init(struct snd_ice1712 *ice) * hence the driver needs to sets up it properly. */ -static const unsigned char juli_eeprom[] __devinitdata = { +static unsigned char juli_eeprom[] __devinitdata = { [ICE_EEP2_SYSCONF] = 0x20, /* clock 512, mpu401, 1xADC, 1xDACs */ [ICE_EEP2_ACLINK] = 0x80, /* I2S */ [ICE_EEP2_I2S] = 0xf8, /* vol, 96k, 24bit, 192k */ @@ -223,7 +225,7 @@ static const unsigned char juli_eeprom[] __devinitdata = { }; /* entry point */ -const struct snd_ice1712_card_info snd_vt1724_juli_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_vt1724_juli_cards[] __devinitdata = { { .subvendor = VT1724_SUBDEVICE_JULI, .name = "ESI Juli@", diff --git a/sound/pci/ice1712/juli.h b/sound/pci/ice1712/juli.h index 1b9294f8bce3..d9f8534fd92e 100644 --- a/sound/pci/ice1712/juli.h +++ b/sound/pci/ice1712/juli.h @@ -5,6 +5,6 @@ #define VT1724_SUBDEVICE_JULI 0x31305345 /* Juli@ */ -extern const struct snd_ice1712_card_info snd_vt1724_juli_cards[]; +extern struct snd_ice1712_card_info snd_vt1724_juli_cards[]; #endif /* __SOUND_JULI_H */ diff --git a/sound/pci/ice1712/phase.c b/sound/pci/ice1712/phase.c index 0751718f4d7b..40a9098af777 100644 --- a/sound/pci/ice1712/phase.c +++ b/sound/pci/ice1712/phase.c @@ -89,13 +89,13 @@ static const unsigned char wm_vol[256] = { #define WM_VOL_MAX (sizeof(wm_vol) - 1) #define WM_VOL_MUTE 0x8000 -static const struct snd_akm4xxx akm_phase22 __devinitdata = { +static struct snd_akm4xxx akm_phase22 __devinitdata = { .type = SND_AK4524, .num_dacs = 2, .num_adcs = 2, }; -static const struct snd_ak4xxx_private akm_phase22_priv __devinitdata = { +static struct snd_ak4xxx_private akm_phase22_priv __devinitdata = { .caddr = 2, .cif = 1, .data_mask = 1 << 4, @@ -152,7 +152,7 @@ static int __devinit phase22_add_controls(struct snd_ice1712 *ice) return 0; } -static const unsigned char phase22_eeprom[] __devinitdata = { +static unsigned char phase22_eeprom[] __devinitdata = { [ICE_EEP2_SYSCONF] = 0x00, /* 1xADC, 1xDACs */ [ICE_EEP2_ACLINK] = 0x80, /* I2S */ [ICE_EEP2_I2S] = 0xf8, /* vol, 96k, 24bit */ @@ -168,7 +168,7 @@ static const unsigned char phase22_eeprom[] __devinitdata = { [ICE_EEP2_GPIO_STATE2] = 0x00, }; -static const unsigned char phase28_eeprom[] __devinitdata = { +static unsigned char phase28_eeprom[] __devinitdata = { [ICE_EEP2_SYSCONF] = 0x0b, /* clock 512, spdif-in/ADC, 4DACs */ [ICE_EEP2_ACLINK] = 0x80, /* I2S */ [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */ @@ -700,7 +700,7 @@ static int phase28_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ct static const DECLARE_TLV_DB_SCALE(db_scale_wm_dac, -12700, 100, 1); static const DECLARE_TLV_DB_SCALE(db_scale_wm_pcm, -6400, 50, 1); -static const struct snd_kcontrol_new phase28_dac_controls[] __devinitdata = { +static struct snd_kcontrol_new phase28_dac_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", @@ -815,7 +815,7 @@ static const struct snd_kcontrol_new phase28_dac_controls[] __devinitdata = { } }; -static const struct snd_kcontrol_new wm_controls[] __devinitdata = { +static struct snd_kcontrol_new wm_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "PCM Playback Switch", @@ -870,7 +870,7 @@ static int __devinit phase28_add_controls(struct snd_ice1712 *ice) return 0; } -const struct snd_ice1712_card_info snd_vt1724_phase_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_vt1724_phase_cards[] __devinitdata = { { .subvendor = VT1724_SUBDEVICE_PHASE22, .name = "Terratec PHASE 22", diff --git a/sound/pci/ice1712/phase.h b/sound/pci/ice1712/phase.h index ad379a99bf92..13e841b55488 100644 --- a/sound/pci/ice1712/phase.h +++ b/sound/pci/ice1712/phase.h @@ -31,7 +31,7 @@ #define VT1724_SUBDEVICE_PHASE28 0x3b154911 /* entry point */ -extern const struct snd_ice1712_card_info snd_vt1724_phase_cards[]; +extern struct snd_ice1712_card_info snd_vt1724_phase_cards[]; /* PHASE28 GPIO bits */ #define PHASE28_SPI_MISO (1 << 21) diff --git a/sound/pci/ice1712/pontis.c b/sound/pci/ice1712/pontis.c index 9552497f0765..01c69453ddeb 100644 --- a/sound/pci/ice1712/pontis.c +++ b/sound/pci/ice1712/pontis.c @@ -571,7 +571,7 @@ static const DECLARE_TLV_DB_SCALE(db_scale_volume, -6400, 50, 1); * mixers */ -static const struct snd_kcontrol_new pontis_controls[] __devinitdata = { +static struct snd_kcontrol_new pontis_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | @@ -826,7 +826,7 @@ static int __devinit pontis_init(struct snd_ice1712 *ice) * hence the driver needs to sets up it properly. */ -static const unsigned char pontis_eeprom[] __devinitdata = { +static unsigned char pontis_eeprom[] __devinitdata = { [ICE_EEP2_SYSCONF] = 0x08, /* clock 256, mpu401, spdif-in/ADC, 1DAC */ [ICE_EEP2_ACLINK] = 0x80, /* I2S */ [ICE_EEP2_I2S] = 0xf8, /* vol, 96k, 24bit, 192k */ @@ -843,7 +843,7 @@ static const unsigned char pontis_eeprom[] __devinitdata = { }; /* entry point */ -const struct snd_ice1712_card_info snd_vt1720_pontis_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_vt1720_pontis_cards[] __devinitdata = { { .subvendor = VT1720_SUBDEVICE_PONTIS_MS300, .name = "Pontis MS300", diff --git a/sound/pci/ice1712/pontis.h b/sound/pci/ice1712/pontis.h index 1a418255c19e..d0d1378b935c 100644 --- a/sound/pci/ice1712/pontis.h +++ b/sound/pci/ice1712/pontis.h @@ -28,6 +28,6 @@ #define VT1720_SUBDEVICE_PONTIS_MS300 0x00020002 /* a dummy id for MS300 */ -extern const struct snd_ice1712_card_info snd_vt1720_pontis_cards[]; +extern struct snd_ice1712_card_info snd_vt1720_pontis_cards[]; #endif /* __SOUND_PONTIS_H */ diff --git a/sound/pci/ice1712/prodigy192.c b/sound/pci/ice1712/prodigy192.c index 31cc66eb9f8f..f03c02c07743 100644 --- a/sound/pci/ice1712/prodigy192.c +++ b/sound/pci/ice1712/prodigy192.c @@ -2,6 +2,37 @@ * ALSA driver for ICEnsemble VT1724 (Envy24HT) * * Lowlevel functions for AudioTrak Prodigy 192 cards + * Supported IEC958 input from optional MI/ODI/O add-on card. + * + * Specifics (SW, HW): + * ------------------- + * * 49.5MHz crystal + * * SPDIF-OUT on the card: + * - coax (through isolation transformer)/toslink supplied by + * 74HC04 gates - 3 in parallel + * - output switched between on-board CD drive dig-out connector + * and ice1724 SPDTX pin, using 74HC02 NOR gates, controlled + * by GPIO20 (0 = CD dig-out, 1 = SPDTX) + * * SPDTX goes straight to MI/ODI/O card's SPDIF-OUT coax + * + * * MI/ODI/O card: AK4114 based, used for iec958 input only + * - toslink input -> RX0 + * - coax input -> RX1 + * - 4wire protocol: + * AK4114 ICE1724 + * ------------------------------ + * CDTO (pin 32) -- GPIO11 pin 86 + * CDTI (pin 33) -- GPIO10 pin 77 + * CCLK (pin 34) -- GPIO9 pin 76 + * CSN (pin 35) -- GPIO8 pin 75 + * - output data Mode 7 (24bit, I2S, slave) + * - both MCKO1 and MCKO2 of ak4114 are fed to FPGA, which + * outputs master clock to SPMCLKIN of ice1724. + * Experimentally I found out that only a combination of + * OCKS0=1, OCKS1=1 (128fs, 64fs output) and ice1724 - + * VT1724_MT_I2S_MCLK_128X=0 (256fs input) yields correct + * sampling rate. That means the the FPGA doubles the + * MCK01 rate. * * Copyright (c) 2003 Takashi Iwai <tiwai@suse.de> * Copyright (c) 2003 Dimitromanolakis Apostolos <apostol@cs.utoronto.ca> @@ -356,6 +387,47 @@ static int aureon_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ctl return 0; } #endif +static int stac9460_mic_sw_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + static char *texts[2] = { "Line In", "Mic" }; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->count = 1; + uinfo->value.enumerated.items = 2; + + if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) + uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; + strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); + + return 0; +} + + +static int stac9460_mic_sw_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); + unsigned char val; + + val = stac9460_get(ice, STAC946X_GENERAL_PURPOSE); + ucontrol->value.enumerated.item[0] = (val >> 7) & 0x1; + return 0; +} + +static int stac9460_mic_sw_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); + unsigned char new, old; + int change; + old = stac9460_get(ice, STAC946X_GENERAL_PURPOSE); + new = (ucontrol->value.enumerated.item[0] << 7 & 0x80) | (old & ~0x80); + change = (new != old); + if (change) + stac9460_put(ice, STAC946X_GENERAL_PURPOSE, new); + return change; +} static const DECLARE_TLV_DB_SCALE(db_scale_dac, -19125, 75, 0); static const DECLARE_TLV_DB_SCALE(db_scale_adc, 0, 150, 0); @@ -364,7 +436,7 @@ static const DECLARE_TLV_DB_SCALE(db_scale_adc, 0, 150, 0); * mixers */ -static const struct snd_kcontrol_new stac_controls[] __devinitdata = { +static struct snd_kcontrol_new stac_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", @@ -406,7 +478,7 @@ static const struct snd_kcontrol_new stac_controls[] __devinitdata = { }, { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "ADC Switch", + .name = "ADC Capture Switch", .count = 1, .info = stac9460_adc_mute_info, .get = stac9460_adc_mute_get, @@ -417,13 +489,21 @@ static const struct snd_kcontrol_new stac_controls[] __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "ADC Volume", + .name = "ADC Capture Volume", .count = 1, .info = stac9460_adc_vol_info, .get = stac9460_adc_vol_get, .put = stac9460_adc_vol_put, .tlv = { .p = db_scale_adc } }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Analog Capture Input", + .info = stac9460_mic_sw_info, + .get = stac9460_mic_sw_get, + .put = stac9460_mic_sw_put, + + }, #if 0 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -456,19 +536,261 @@ static const struct snd_kcontrol_new stac_controls[] __devinitdata = { #endif }; + +/* AK4114 - ICE1724 connections on Prodigy192 + MI/ODI/O */ +/* CDTO (pin 32) -- GPIO11 pin 86 + * CDTI (pin 33) -- GPIO10 pin 77 + * CCLK (pin 34) -- GPIO9 pin 76 + * CSN (pin 35) -- GPIO8 pin 75 + */ +#define AK4114_ADDR 0x00 /* C1-C0: Chip Address + * (According to datasheet fixed to “00”) + */ + +/* + * 4wire ak4114 protocol - writing data + */ +static void write_data(struct snd_ice1712 *ice, unsigned int gpio, + unsigned int data, int idx) +{ + for (; idx >= 0; idx--) { + /* drop clock */ + gpio &= ~VT1724_PRODIGY192_CCLK; + snd_ice1712_gpio_write(ice, gpio); + udelay(1); + /* set data */ + if (data & (1 << idx)) + gpio |= VT1724_PRODIGY192_CDOUT; + else + gpio &= ~VT1724_PRODIGY192_CDOUT; + snd_ice1712_gpio_write(ice, gpio); + udelay(1); + /* raise clock */ + gpio |= VT1724_PRODIGY192_CCLK; + snd_ice1712_gpio_write(ice, gpio); + udelay(1); + } +} + +/* + * 4wire ak4114 protocol - reading data + */ +static unsigned char read_data(struct snd_ice1712 *ice, unsigned int gpio, + int idx) +{ + unsigned char data = 0; + + for (; idx >= 0; idx--) { + /* drop clock */ + gpio &= ~VT1724_PRODIGY192_CCLK; + snd_ice1712_gpio_write(ice, gpio); + udelay(1); + /* read data */ + if (snd_ice1712_gpio_read(ice) & VT1724_PRODIGY192_CDIN) + data |= (1 << idx); + udelay(1); + /* raise clock */ + gpio |= VT1724_PRODIGY192_CCLK; + snd_ice1712_gpio_write(ice, gpio); + udelay(1); + } + return data; +} +/* + * 4wire ak4114 protocol - starting sequence + */ +static unsigned int prodigy192_4wire_start(struct snd_ice1712 *ice) +{ + unsigned int tmp; + + snd_ice1712_save_gpio_status(ice); + tmp = snd_ice1712_gpio_read(ice); + + tmp |= VT1724_PRODIGY192_CCLK; /* high at init */ + tmp &= ~VT1724_PRODIGY192_CS; /* drop chip select */ + snd_ice1712_gpio_write(ice, tmp); + udelay(1); + return tmp; +} + +/* + * 4wire ak4114 protocol - final sequence + */ +static void prodigy192_4wire_finish(struct snd_ice1712 *ice, unsigned int tmp) +{ + tmp |= VT1724_PRODIGY192_CS; /* raise chip select */ + snd_ice1712_gpio_write(ice, tmp); + udelay(1); + snd_ice1712_restore_gpio_status(ice); +} + +/* + * Write data to addr register of ak4114 + */ +static void prodigy192_ak4114_write(void *private_data, unsigned char addr, + unsigned char data) +{ + struct snd_ice1712 *ice = private_data; + unsigned int tmp, addrdata; + tmp = prodigy192_4wire_start(ice); + addrdata = (AK4114_ADDR << 6) | 0x20 | (addr & 0x1f); + addrdata = (addrdata << 8) | data; + write_data(ice, tmp, addrdata, 15); + prodigy192_4wire_finish(ice, tmp); +} + +/* + * Read data from addr register of ak4114 + */ +static unsigned char prodigy192_ak4114_read(void *private_data, + unsigned char addr) +{ + struct snd_ice1712 *ice = private_data; + unsigned int tmp; + unsigned char data; + + tmp = prodigy192_4wire_start(ice); + write_data(ice, tmp, (AK4114_ADDR << 6) | (addr & 0x1f), 7); + data = read_data(ice, tmp, 7); + prodigy192_4wire_finish(ice, tmp); + return data; +} + + +static int ak4114_input_sw_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + static char *texts[2] = { "Toslink", "Coax" }; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->count = 1; + uinfo->value.enumerated.items = 2; + if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) + uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; + strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); + return 0; +} + + +static int ak4114_input_sw_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); + unsigned char val; + + val = prodigy192_ak4114_read(ice, AK4114_REG_IO1); + /* AK4114_IPS0 bit = 0 -> RX0 = Toslink + * AK4114_IPS0 bit = 1 -> RX1 = Coax + */ + ucontrol->value.enumerated.item[0] = (val & AK4114_IPS0) ? 1 : 0; + return 0; +} + +static int ak4114_input_sw_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); + unsigned char new, old, itemvalue; + int change; + + old = prodigy192_ak4114_read(ice, AK4114_REG_IO1); + /* AK4114_IPS0 could be any bit */ + itemvalue = (ucontrol->value.enumerated.item[0]) ? 0xff : 0x00; + + new = (itemvalue & AK4114_IPS0) | (old & ~AK4114_IPS0); + change = (new != old); + if (change) + prodigy192_ak4114_write(ice, AK4114_REG_IO1, new); + return change; +} + + +static const struct snd_kcontrol_new ak4114_controls[] __devinitdata = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "MIODIO IEC958 Capture Input", + .info = ak4114_input_sw_info, + .get = ak4114_input_sw_get, + .put = ak4114_input_sw_put, + + } +}; + + +static int prodigy192_ak4114_init(struct snd_ice1712 *ice) +{ + static const unsigned char ak4114_init_vals[] = { + AK4114_RST | AK4114_PWN | AK4114_OCKS0 | AK4114_OCKS1, + /* ice1724 expects I2S and provides clock, + * DEM0 disables the deemphasis filter + */ + AK4114_DIF_I24I2S | AK4114_DEM0 , + AK4114_TX1E, + AK4114_EFH_1024 | AK4114_DIT, /* default input RX0 */ + 0, + 0 + }; + static const unsigned char ak4114_init_txcsb[] = { + 0x41, 0x02, 0x2c, 0x00, 0x00 + }; + + return snd_ak4114_create(ice->card, + prodigy192_ak4114_read, + prodigy192_ak4114_write, + ak4114_init_vals, ak4114_init_txcsb, + ice, &ice->spec.prodigy192.ak4114); +} + static int __devinit prodigy192_add_controls(struct snd_ice1712 *ice) { unsigned int i; int err; for (i = 0; i < ARRAY_SIZE(stac_controls); i++) { - err = snd_ctl_add(ice->card, snd_ctl_new1(&stac_controls[i], ice)); + err = snd_ctl_add(ice->card, + snd_ctl_new1(&stac_controls[i], ice)); + if (err < 0) + return err; + } + if (ice->spec.prodigy192.ak4114) { + /* ak4114 is connected */ + for (i = 0; i < ARRAY_SIZE(ak4114_controls); i++) { + err = snd_ctl_add(ice->card, + snd_ctl_new1(&ak4114_controls[i], + ice)); + if (err < 0) + return err; + } + err = snd_ak4114_build(ice->spec.prodigy192.ak4114, + NULL, /* ak4114 in MIO/DI/O handles no IEC958 output */ + ice->pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream); if (err < 0) return err; } return 0; } +/* + * check for presence of MI/ODI/O add-on card with digital inputs + */ +static int prodigy192_miodio_exists(struct snd_ice1712 *ice) +{ + + unsigned char orig_value; + const unsigned char test_data = 0xd1; /* random value */ + unsigned char addr = AK4114_REG_INT0_MASK; /* random SAFE address */ + int exists = 0; + + orig_value = prodigy192_ak4114_read(ice, addr); + prodigy192_ak4114_write(ice, addr, test_data); + if (prodigy192_ak4114_read(ice, addr) == test_data) { + /* ak4114 seems to communicate, apparently exists */ + /* writing back original value */ + prodigy192_ak4114_write(ice, addr, orig_value); + exists = 1; + } + return exists; +} /* * initialize the chip @@ -487,16 +809,30 @@ static int __devinit prodigy192_init(struct snd_ice1712 *ice) (unsigned short)-1 }; const unsigned short *p; + int err = 0; /* prodigy 192 */ ice->num_total_dacs = 6; ice->num_total_adcs = 2; + ice->vt1720 = 0; /* ice1724, e.g. 23 GPIOs */ /* initialize codec */ p = stac_inits_prodigy; for (; *p != (unsigned short)-1; p += 2) stac9460_put(ice, p[0], p[1]); + /* MI/ODI/O add on card with AK4114 */ + if (prodigy192_miodio_exists(ice)) { + err = prodigy192_ak4114_init(ice); + /* from this moment if err = 0 then + * ice->spec.prodigy192.ak4114 should not be null + */ + snd_printdd("AK4114 initialized with status %d\n", err); + } else + snd_printdd("AK4114 not found\n"); + if (err < 0) + return err; + return 0; } @@ -506,25 +842,31 @@ static int __devinit prodigy192_init(struct snd_ice1712 *ice) * hence the driver needs to sets up it properly. */ -static const unsigned char prodigy71_eeprom[] __devinitdata = { - [ICE_EEP2_SYSCONF] = 0x2b, /* clock 512, mpu401, spdif-in/ADC, 4DACs */ +static unsigned char prodigy71_eeprom[] __devinitdata = { + [ICE_EEP2_SYSCONF] = 0x6a, /* 49MHz crystal, mpu401, + * spdif-in+ 1 stereo ADC, + * 3 stereo DACs + */ [ICE_EEP2_ACLINK] = 0x80, /* I2S */ [ICE_EEP2_I2S] = 0xf8, /* vol, 96k, 24bit, 192k */ [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */ [ICE_EEP2_GPIO_DIR] = 0xff, - [ICE_EEP2_GPIO_DIR1] = 0xff, + [ICE_EEP2_GPIO_DIR1] = ~(VT1724_PRODIGY192_CDIN >> 8) , [ICE_EEP2_GPIO_DIR2] = 0xbf, [ICE_EEP2_GPIO_MASK] = 0x00, [ICE_EEP2_GPIO_MASK1] = 0x00, [ICE_EEP2_GPIO_MASK2] = 0x00, [ICE_EEP2_GPIO_STATE] = 0x00, [ICE_EEP2_GPIO_STATE1] = 0x00, - [ICE_EEP2_GPIO_STATE2] = 0x00, + [ICE_EEP2_GPIO_STATE2] = 0x10, /* GPIO20: 0 = CD drive dig. input + * passthrough, + * 1 = SPDIF-OUT from ice1724 + */ }; /* entry point */ -const struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[] __devinitdata = { { .subvendor = VT1724_SUBDEVICE_PRODIGY192VE, .name = "Audiotrak Prodigy 192", diff --git a/sound/pci/ice1712/prodigy192.h b/sound/pci/ice1712/prodigy192.h index 2fa2e62b9e04..16a53b459c72 100644 --- a/sound/pci/ice1712/prodigy192.h +++ b/sound/pci/ice1712/prodigy192.h @@ -5,7 +5,15 @@ #define PRODIGY192_STAC9460_ADDR 0x54 #define VT1724_SUBDEVICE_PRODIGY192VE 0x34495345 /* PRODIGY 192 VE */ +/* + * AudioTrak Prodigy192 GPIO definitions for MI/ODI/O card with + * AK4114 (SPDIF-IN) + */ +#define VT1724_PRODIGY192_CS (1 << 8) /* GPIO8, pin 75 */ +#define VT1724_PRODIGY192_CCLK (1 << 9) /* GPIO9, pin 76 */ +#define VT1724_PRODIGY192_CDOUT (1 << 10) /* GPIO10, pin 77 */ +#define VT1724_PRODIGY192_CDIN (1 << 11) /* GPIO11, pin 86 */ -extern const struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[]; +extern struct snd_ice1712_card_info snd_vt1724_prodigy192_cards[]; #endif /* __SOUND_PRODIGY192_H */ diff --git a/sound/pci/ice1712/revo.c b/sound/pci/ice1712/revo.c index 025a7e8497c3..690ceb340644 100644 --- a/sound/pci/ice1712/revo.c +++ b/sound/pci/ice1712/revo.c @@ -219,7 +219,7 @@ static const struct snd_akm4xxx_adc_channel revo51_adc[] = { }, }; -static const struct snd_akm4xxx akm_revo_front __devinitdata = { +static struct snd_akm4xxx akm_revo_front __devinitdata = { .type = SND_AK4381, .num_dacs = 2, .ops = { @@ -228,7 +228,7 @@ static const struct snd_akm4xxx akm_revo_front __devinitdata = { .dac_info = revo71_front, }; -static const struct snd_ak4xxx_private akm_revo_front_priv __devinitdata = { +static struct snd_ak4xxx_private akm_revo_front_priv __devinitdata = { .caddr = 1, .cif = 0, .data_mask = VT1724_REVO_CDOUT, @@ -240,7 +240,7 @@ static const struct snd_ak4xxx_private akm_revo_front_priv __devinitdata = { .mask_flags = 0, }; -static const struct snd_akm4xxx akm_revo_surround __devinitdata = { +static struct snd_akm4xxx akm_revo_surround __devinitdata = { .type = SND_AK4355, .idx_offset = 1, .num_dacs = 6, @@ -250,7 +250,7 @@ static const struct snd_akm4xxx akm_revo_surround __devinitdata = { .dac_info = revo71_surround, }; -static const struct snd_ak4xxx_private akm_revo_surround_priv __devinitdata = { +static struct snd_ak4xxx_private akm_revo_surround_priv __devinitdata = { .caddr = 3, .cif = 0, .data_mask = VT1724_REVO_CDOUT, @@ -262,7 +262,7 @@ static const struct snd_ak4xxx_private akm_revo_surround_priv __devinitdata = { .mask_flags = 0, }; -static const struct snd_akm4xxx akm_revo51 __devinitdata = { +static struct snd_akm4xxx akm_revo51 __devinitdata = { .type = SND_AK4358, .num_dacs = 6, .ops = { @@ -271,7 +271,7 @@ static const struct snd_akm4xxx akm_revo51 __devinitdata = { .dac_info = revo51_dac, }; -static const struct snd_ak4xxx_private akm_revo51_priv __devinitdata = { +static struct snd_ak4xxx_private akm_revo51_priv __devinitdata = { .caddr = 2, .cif = 0, .data_mask = VT1724_REVO_CDOUT, @@ -283,13 +283,13 @@ static const struct snd_ak4xxx_private akm_revo51_priv __devinitdata = { .mask_flags = 0, }; -static const struct snd_akm4xxx akm_revo51_adc __devinitdata = { +static struct snd_akm4xxx akm_revo51_adc __devinitdata = { .type = SND_AK5365, .num_adcs = 2, .adc_info = revo51_adc, }; -static const struct snd_ak4xxx_private akm_revo51_adc_priv __devinitdata = { +static struct snd_ak4xxx_private akm_revo51_adc_priv __devinitdata = { .caddr = 2, .cif = 0, .data_mask = VT1724_REVO_CDOUT, @@ -324,7 +324,7 @@ static const struct snd_akm4xxx_dac_channel ap192_dac[] = { AK_DAC("PCM Playback Volume", 2) }; -static const struct snd_akm4xxx akm_ap192 __devinitdata = { +static struct snd_akm4xxx akm_ap192 __devinitdata = { .type = SND_AK4358, .num_dacs = 2, .ops = { @@ -333,7 +333,7 @@ static const struct snd_akm4xxx akm_ap192 __devinitdata = { .dac_info = ap192_dac, }; -static const struct snd_ak4xxx_private akm_ap192_priv __devinitdata = { +static struct snd_ak4xxx_private akm_ap192_priv __devinitdata = { .caddr = 2, .cif = 0, .data_mask = VT1724_REVO_CDOUT, @@ -405,7 +405,7 @@ static unsigned char read_data(struct snd_ice1712 *ice, unsigned int gpio, return data; } -static unsigned char ap192_4wire_start(struct snd_ice1712 *ice) +static unsigned int ap192_4wire_start(struct snd_ice1712 *ice) { unsigned int tmp; @@ -454,7 +454,7 @@ static unsigned char ap192_ak4114_read(void *private_data, unsigned char addr) return data; } -static int ap192_ak4114_init(struct snd_ice1712 *ice) +static int __devinit ap192_ak4114_init(struct snd_ice1712 *ice) { static const unsigned char ak4114_init_vals[] = { AK4114_RST | AK4114_PWN | AK4114_OCKS0 | AK4114_OCKS1, @@ -582,7 +582,7 @@ static int __devinit revo_add_controls(struct snd_ice1712 *ice) } /* entry point */ -const struct snd_ice1712_card_info snd_vt1724_revo_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_vt1724_revo_cards[] __devinitdata = { { .subvendor = VT1724_SUBDEVICE_REVOLUTION71, .name = "M Audio Revolution-7.1", diff --git a/sound/pci/ice1712/revo.h b/sound/pci/ice1712/revo.h index 2a24488fad80..a3ba425911cc 100644 --- a/sound/pci/ice1712/revo.h +++ b/sound/pci/ice1712/revo.h @@ -34,7 +34,7 @@ #define VT1724_SUBDEVICE_AUDIOPHILE192 0x12143236 /* entry point */ -extern const struct snd_ice1712_card_info snd_vt1724_revo_cards[]; +extern struct snd_ice1712_card_info snd_vt1724_revo_cards[]; /* diff --git a/sound/pci/ice1712/vt1720_mobo.c b/sound/pci/ice1712/vt1720_mobo.c index 72b060d63c29..239524158fe7 100644 --- a/sound/pci/ice1712/vt1720_mobo.c +++ b/sound/pci/ice1712/vt1720_mobo.c @@ -56,7 +56,7 @@ static int __devinit k8x800_add_controls(struct snd_ice1712 *ice) /* EEPROM image */ -static const unsigned char k8x800_eeprom[] __devinitdata = { +static unsigned char k8x800_eeprom[] __devinitdata = { [ICE_EEP2_SYSCONF] = 0x01, /* clock 256, 1ADC, 2DACs */ [ICE_EEP2_ACLINK] = 0x02, /* ACLINK, packed */ [ICE_EEP2_I2S] = 0x00, /* - */ @@ -72,7 +72,7 @@ static const unsigned char k8x800_eeprom[] __devinitdata = { [ICE_EEP2_GPIO_STATE2] = 0x00, /* - */ }; -static const unsigned char sn25p_eeprom[] __devinitdata = { +static unsigned char sn25p_eeprom[] __devinitdata = { [ICE_EEP2_SYSCONF] = 0x01, /* clock 256, 1ADC, 2DACs */ [ICE_EEP2_ACLINK] = 0x02, /* ACLINK, packed */ [ICE_EEP2_I2S] = 0x00, /* - */ @@ -90,7 +90,7 @@ static const unsigned char sn25p_eeprom[] __devinitdata = { /* entry point */ -const struct snd_ice1712_card_info snd_vt1720_mobo_cards[] __devinitdata = { +struct snd_ice1712_card_info snd_vt1720_mobo_cards[] __devinitdata = { { .subvendor = VT1720_SUBDEVICE_K8X800, .name = "Albatron K8X800 Pro II", diff --git a/sound/pci/ice1712/vt1720_mobo.h b/sound/pci/ice1712/vt1720_mobo.h index 70af3ad64a5d..0b1b0ee1bea7 100644 --- a/sound/pci/ice1712/vt1720_mobo.h +++ b/sound/pci/ice1712/vt1720_mobo.h @@ -36,6 +36,6 @@ #define VT1720_SUBDEVICE_9CJS 0x0f272327 #define VT1720_SUBDEVICE_SN25P 0x97123650 -extern const struct snd_ice1712_card_info snd_vt1720_mobo_cards[]; +extern struct snd_ice1712_card_info snd_vt1720_mobo_cards[]; #endif /* __SOUND_VT1720_MOBO_H */ diff --git a/sound/pci/ice1712/wtm.c b/sound/pci/ice1712/wtm.c index 4a706b16a0b9..04e535c8542b 100644 --- a/sound/pci/ice1712/wtm.c +++ b/sound/pci/ice1712/wtm.c @@ -409,7 +409,7 @@ static int stac9460_mic_sw_put(struct snd_kcontrol *kcontrol, /* * Control tabs */ -static const struct snd_kcontrol_new stac9640_controls[] __devinitdata = { +static struct snd_kcontrol_new stac9640_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 7cf2dcb9d8d4..202f720b34b9 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c @@ -2493,6 +2493,7 @@ static int intel8x0_resume(struct pci_dev *pci) return -EIO; } pci_set_master(pci); + snd_intel8x0_chip_init(chip, 0); if (request_irq(pci->irq, snd_intel8x0_interrupt, IRQF_SHARED, card->shortname, chip)) { printk(KERN_ERR "intel8x0: unable to grab IRQ %d, " @@ -2502,7 +2503,6 @@ static int intel8x0_resume(struct pci_dev *pci) } chip->irq = pci->irq; synchronize_irq(chip->irq); - snd_intel8x0_chip_init(chip, 0); /* re-initialize mixer stuff */ if (chip->device_type == DEVICE_INTEL_ICH4 && !spdif_aclink) { @@ -2862,16 +2862,7 @@ static int __devinit snd_intel8x0_create(struct snd_card *card, ICH_REG_ALI_INTERRUPTSR : ICH_REG_GLOB_STA; chip->int_sta_mask = int_sta_masks; - /* request irq after initializaing int_sta_mask, etc */ - if (request_irq(pci->irq, snd_intel8x0_interrupt, - IRQF_SHARED, card->shortname, chip)) { - snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); - snd_intel8x0_free(chip); - return -EBUSY; - } - chip->irq = pci->irq; pci_set_master(pci); - synchronize_irq(chip->irq); switch(chip->device_type) { case DEVICE_INTEL_ICH4: @@ -2901,6 +2892,15 @@ static int __devinit snd_intel8x0_create(struct snd_card *card, return err; } + /* request irq after initializaing int_sta_mask, etc */ + if (request_irq(pci->irq, snd_intel8x0_interrupt, + IRQF_SHARED, card->shortname, chip)) { + snd_printk(KERN_ERR "unable to grab IRQ %d\n", pci->irq); + snd_intel8x0_free(chip); + return -EBUSY; + } + chip->irq = pci->irq; + if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops)) < 0) { snd_intel8x0_free(chip); return err; diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c index 21d0899ac382..5338243fb035 100644 --- a/sound/pci/korg1212/korg1212.c +++ b/sound/pci/korg1212/korg1212.c @@ -264,9 +264,7 @@ enum MonitorModeSelector { #define COMMAND_ACK_DELAY 13 // number of RTC ticks to wait for an acknowledgement // from the card after sending a command. -#define FIRMWARE_IN_THE_KERNEL - -#ifdef FIRMWARE_IN_THE_KERNEL +#ifdef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL #include "korg1212-firmware.h" static const struct firmware static_dsp_code = { .data = (u8 *)dspCode, @@ -418,6 +416,9 @@ struct snd_korg1212 { MODULE_DESCRIPTION("korg1212"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{KORG,korg1212}}"); +#ifndef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL +MODULE_FIRMWARE("korg/k1212.dsp"); +#endif static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ @@ -2342,26 +2343,25 @@ static int __devinit snd_korg1212_create(struct snd_card *card, struct pci_dev * korg1212->AdatTimeCodePhy = korg1212->sharedBufferPhy + offsetof(struct KorgSharedBuffer, AdatTimeCode); +#ifdef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL + dsp_code = &static_dsp_code; +#else err = request_firmware(&dsp_code, "korg/k1212.dsp", &pci->dev); if (err < 0) { release_firmware(dsp_code); -#ifdef FIRMWARE_IN_THE_KERNEL - dsp_code = &static_dsp_code; -#else snd_printk(KERN_ERR "firmware not available\n"); snd_korg1212_free(korg1212); return err; -#endif } +#endif if (snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, snd_dma_pci_data(pci), dsp_code->size, &korg1212->dma_dsp) < 0) { snd_printk(KERN_ERR "korg1212: cannot allocate dsp code memory (%zd bytes)\n", dsp_code->size); snd_korg1212_free(korg1212); -#ifdef FIRMWARE_IN_THE_KERNEL - if (dsp_code != &static_dsp_code) +#ifndef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL + release_firmware(dsp_code); #endif - release_firmware(dsp_code); return -ENOMEM; } @@ -2371,10 +2371,9 @@ static int __devinit snd_korg1212_create(struct snd_card *card, struct pci_dev * memcpy(korg1212->dma_dsp.area, dsp_code->data, dsp_code->size); -#ifdef FIRMWARE_IN_THE_KERNEL - if (dsp_code != &static_dsp_code) +#ifndef CONFIG_SND_KORG1212_FIRMWARE_IN_KERNEL + release_firmware(dsp_code); #endif - release_firmware(dsp_code); rc = snd_korg1212_Send1212Command(korg1212, K1212_DB_RebootCard, 0, 0, 0, 0); diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c index 4526904e3f86..8a5ff1cb5362 100644 --- a/sound/pci/maestro3.c +++ b/sound/pci/maestro3.c @@ -59,6 +59,10 @@ MODULE_SUPPORTED_DEVICE("{{ESS,Maestro3 PCI}," "{ESS,Allegro PCI}," "{ESS,Allegro-1 PCI}," "{ESS,Canyon3D-2/LE PCI}}"); +#ifndef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL +MODULE_FIRMWARE("ess/maestro3_assp_kernel.fw"); +MODULE_FIRMWARE("ess/maestro3_assp_minisrc.fw"); +#endif static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* Index 0-MAX */ static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; /* ID for this card */ @@ -2101,9 +2105,7 @@ static int __devinit snd_m3_mixer(struct snd_m3 *chip) } -#define FIRMWARE_IN_THE_KERNEL - -#ifdef FIRMWARE_IN_THE_KERNEL +#ifdef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL /* * DSP Code images @@ -2242,7 +2244,7 @@ static const struct firmware assp_minisrc = { .size = sizeof assp_minisrc_image }; -#endif /* FIRMWARE_IN_THE_KERNEL */ +#else /* CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL */ #ifdef __LITTLE_ENDIAN static inline void snd_m3_convert_from_le(const struct firmware *fw) { } @@ -2257,6 +2259,8 @@ static void snd_m3_convert_from_le(const struct firmware *fw) } #endif +#endif /* CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL */ + /* * initialize ASSP @@ -2550,14 +2554,10 @@ static int snd_m3_free(struct snd_m3 *chip) if (chip->iobase) pci_release_regions(chip->pci); -#ifdef FIRMWARE_IN_THE_KERNEL - if (chip->assp_kernel_image != &assp_kernel) +#ifndef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL + release_firmware(chip->assp_kernel_image); + release_firmware(chip->assp_minisrc_image); #endif - release_firmware(chip->assp_kernel_image); -#ifdef FIRMWARE_IN_THE_KERNEL - if (chip->assp_minisrc_image != &assp_minisrc) -#endif - release_firmware(chip->assp_minisrc_image); pci_disable_device(chip->pci); kfree(chip); @@ -2747,29 +2747,29 @@ snd_m3_create(struct snd_card *card, struct pci_dev *pci, return -ENOMEM; } +#ifdef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL + chip->assp_kernel_image = &assp_kernel; +#else err = request_firmware(&chip->assp_kernel_image, "ess/maestro3_assp_kernel.fw", &pci->dev); if (err < 0) { -#ifdef FIRMWARE_IN_THE_KERNEL - chip->assp_kernel_image = &assp_kernel; -#else snd_m3_free(chip); return err; -#endif } else snd_m3_convert_from_le(chip->assp_kernel_image); +#endif +#ifdef CONFIG_SND_MAESTRO3_FIRMWARE_IN_KERNEL + chip->assp_minisrc_image = &assp_minisrc; +#else err = request_firmware(&chip->assp_minisrc_image, "ess/maestro3_assp_minisrc.fw", &pci->dev); if (err < 0) { -#ifdef FIRMWARE_IN_THE_KERNEL - chip->assp_minisrc_image = &assp_minisrc; -#else snd_m3_free(chip); return err; -#endif } else snd_m3_convert_from_le(chip->assp_minisrc_image); +#endif if ((err = pci_request_regions(pci, card->driver)) < 0) { snd_m3_free(chip); diff --git a/sound/pci/mixart/mixart_hwdep.c b/sound/pci/mixart/mixart_hwdep.c index ca05075c67c6..1d9232d2db34 100644 --- a/sound/pci/mixart/mixart_hwdep.c +++ b/sound/pci/mixart/mixart_hwdep.c @@ -565,6 +565,9 @@ int snd_mixart_setup_firmware(struct mixart_mgr *mgr) return 0; } +MODULE_FIRMWARE("mixart/miXart8.xlx"); +MODULE_FIRMWARE("mixart/miXart8.elf"); +MODULE_FIRMWARE("mixart/miXart8AES.xlx"); #else /* old style firmware loading */ diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c index d97413484ae9..f7f6a687f033 100644 --- a/sound/pci/pcxhr/pcxhr.c +++ b/sound/pci/pcxhr/pcxhr.c @@ -638,22 +638,22 @@ static void pcxhr_trigger_tasklet(unsigned long arg) static int pcxhr_trigger(struct snd_pcm_substream *subs, int cmd) { struct pcxhr_stream *stream; - struct list_head *pos; struct snd_pcm_substream *s; - int i; switch (cmd) { case SNDRV_PCM_TRIGGER_START: snd_printdd("SNDRV_PCM_TRIGGER_START\n"); - i = 0; - snd_pcm_group_for_each(pos, subs) { - s = snd_pcm_group_substream_entry(pos); - stream = s->runtime->private_data; - stream->status = PCXHR_STREAM_STATUS_SCHEDULE_RUN; - snd_pcm_trigger_done(s, subs); - i++; - } - if (i==1) { + if (snd_pcm_stream_linked(subs)) { + struct snd_pcxhr *chip = snd_pcm_substream_chip(subs); + snd_pcm_group_for_each_entry(s, subs) { + stream = s->runtime->private_data; + stream->status = + PCXHR_STREAM_STATUS_SCHEDULE_RUN; + snd_pcm_trigger_done(s, subs); + } + tasklet_hi_schedule(&chip->mgr->trigger_taskq); + } else { + stream = subs->runtime->private_data; snd_printdd("Only one Substream %c %d\n", stream->pipe->is_capture ? 'C' : 'P', stream->pipe->first_audio); @@ -665,15 +665,11 @@ static int pcxhr_trigger(struct snd_pcm_substream *subs, int cmd) if (pcxhr_set_stream_state(stream)) return -EINVAL; stream->status = PCXHR_STREAM_STATUS_RUNNING; - } else { - struct snd_pcxhr *chip = snd_pcm_substream_chip(subs); - tasklet_hi_schedule(&chip->mgr->trigger_taskq); } break; case SNDRV_PCM_TRIGGER_STOP: snd_printdd("SNDRV_PCM_TRIGGER_STOP\n"); - snd_pcm_group_for_each(pos, subs) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, subs) { stream = s->runtime->private_data; stream->status = PCXHR_STREAM_STATUS_SCHEDULE_STOP; if (pcxhr_set_stream_state(stream)) diff --git a/sound/pci/pcxhr/pcxhr_hwdep.c b/sound/pci/pcxhr/pcxhr_hwdep.c index 369c19fea985..d55d8bc90eee 100644 --- a/sound/pci/pcxhr/pcxhr_hwdep.c +++ b/sound/pci/pcxhr/pcxhr_hwdep.c @@ -356,6 +356,12 @@ int pcxhr_setup_firmware(struct pcxhr_mgr *mgr) return 0; } +MODULE_FIRMWARE("pcxhr/xi_1_882.dat"); +MODULE_FIRMWARE("pcxhr/xc_1_882.dat"); +MODULE_FIRMWARE("pcxhr/e321_512.e56"); +MODULE_FIRMWARE("pcxhr/b321_512.b56"); +MODULE_FIRMWARE("pcxhr/d321_512.d56"); + #else /* old style firmware loading */ /* pcxhr hwdep interface id string */ diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c index 952625dead58..8e5410483e67 100644 --- a/sound/pci/riptide/riptide.c +++ b/sound/pci/riptide/riptide.c @@ -117,6 +117,7 @@ MODULE_AUTHOR("Peter Gruber <nokos@gmx.net>"); MODULE_DESCRIPTION("riptide"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{Conexant,Riptide}}"); +MODULE_FIRMWARE("riptide.hex"); static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; diff --git a/sound/pci/rme32.c b/sound/pci/rme32.c index 6bb7ac650ec4..618653e22561 100644 --- a/sound/pci/rme32.c +++ b/sound/pci/rme32.c @@ -1078,12 +1078,10 @@ static int snd_rme32_pcm_trigger(struct snd_pcm_substream *substream, int cmd) { struct rme32 *rme32 = snd_pcm_substream_chip(substream); - struct list_head *pos; struct snd_pcm_substream *s; spin_lock(&rme32->lock); - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if (s != rme32->playback_substream && s != rme32->capture_substream) continue; @@ -1110,8 +1108,7 @@ snd_rme32_pcm_trigger(struct snd_pcm_substream *substream, int cmd) /* prefill playback buffer */ if (cmd == SNDRV_PCM_TRIGGER_START && rme32->fullduplex_mode) { - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if (s == rme32->playback_substream) { s->ops->ack(s); break; diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index 89b3c7ff5037..3b3ef657f73e 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c @@ -60,6 +60,12 @@ MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{RME Hammerfall-DSP}," "{RME HDSP-9652}," "{RME HDSP-9632}}"); +#ifdef HDSP_FW_LOADER +MODULE_FIRMWARE("multiface_firmware.bin"); +MODULE_FIRMWARE("multiface_firmware_rev11.bin"); +MODULE_FIRMWARE("digiface_firmware.bin"); +MODULE_FIRMWARE("digiface_firmware_rev11.bin"); +#endif #define HDSP_MAX_CHANNELS 26 #define HDSP_MAX_DS_CHANNELS 14 @@ -275,6 +281,11 @@ MODULE_SUPPORTED_DEVICE("{{RME Hammerfall-DSP}," #define HDSP_Frequency128KHz (HDSP_QuadSpeed|HDSP_DoubleSpeed|HDSP_Frequency0) #define HDSP_Frequency176_4KHz (HDSP_QuadSpeed|HDSP_DoubleSpeed|HDSP_Frequency1) #define HDSP_Frequency192KHz (HDSP_QuadSpeed|HDSP_DoubleSpeed|HDSP_Frequency1|HDSP_Frequency0) +/* RME says n = 104857600000000, but in the windows MADI driver, I see: + return 104857600000000 / rate; // 100 MHz + return 110100480000000 / rate; // 105 MHz +*/ +#define DDS_NUMERATOR 104857600000000ULL; /* = 2^20 * 10^8 */ #define hdsp_encode_latency(x) (((x)<<1) & HDSP_LatencyMask) #define hdsp_decode_latency(x) (((x) & HDSP_LatencyMask)>>1) @@ -1001,11 +1012,7 @@ static void hdsp_set_dds_value(struct hdsp *hdsp, int rate) else if (rate >= 56000) rate /= 2; - /* RME says n = 104857600000000, but in the windows MADI driver, I see: -// return 104857600000000 / rate; // 100 MHz - return 110100480000000 / rate; // 105 MHz - */ - n = 104857600000000ULL; /* = 2^20 * 10^8 */ + n = DDS_NUMERATOR; div64_32(&n, rate, &r); /* n should be less than 2^32 for being written to FREQ register */ snd_assert((n >> 32) == 0); @@ -3085,11 +3092,83 @@ static int snd_hdsp_get_adat_sync_check(struct snd_kcontrol *kcontrol, struct sn return 0; } +#define HDSP_DDS_OFFSET(xname, xindex) \ +{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .name = xname, \ + .index = xindex, \ + .info = snd_hdsp_info_dds_offset, \ + .get = snd_hdsp_get_dds_offset, \ + .put = snd_hdsp_put_dds_offset \ +} + +static int hdsp_dds_offset(struct hdsp *hdsp) +{ + u64 n; + u32 r; + unsigned int dds_value = hdsp->dds_value; + int system_sample_rate = hdsp->system_sample_rate; + + n = DDS_NUMERATOR; + /* + * dds_value = n / rate + * rate = n / dds_value + */ + div64_32(&n, dds_value, &r); + if (system_sample_rate >= 112000) + n *= 4; + else if (system_sample_rate >= 56000) + n *= 2; + return ((int)n) - system_sample_rate; +} + +static int hdsp_set_dds_offset(struct hdsp *hdsp, int offset_hz) +{ + int rate = hdsp->system_sample_rate + offset_hz; + hdsp_set_dds_value(hdsp, rate); + return 0; +} + +static int snd_hdsp_info_dds_offset(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 1; + uinfo->value.integer.min = -5000; + uinfo->value.integer.max = 5000; + return 0; +} + +static int snd_hdsp_get_dds_offset(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); + + ucontrol->value.enumerated.item[0] = hdsp_dds_offset(hdsp); + return 0; +} + +static int snd_hdsp_put_dds_offset(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ + struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); + int change; + int val; + + if (!snd_hdsp_use_is_exclusive(hdsp)) + return -EBUSY; + val = ucontrol->value.enumerated.item[0]; + spin_lock_irq(&hdsp->lock); + if (val != hdsp_dds_offset(hdsp)) + change = (hdsp_set_dds_offset(hdsp, val) == 0) ? 1 : 0; + else + change = 0; + spin_unlock_irq(&hdsp->lock); + return change; +} + static struct snd_kcontrol_new snd_hdsp_9632_controls[] = { HDSP_DA_GAIN("DA Gain", 0), HDSP_AD_GAIN("AD Gain", 0), HDSP_PHONE_GAIN("Phones Gain", 0), -HDSP_XLR_BREAKOUT_CABLE("XLR Breakout Cable", 0) +HDSP_XLR_BREAKOUT_CABLE("XLR Breakout Cable", 0), +HDSP_DDS_OFFSET("DDS Sample Rate Offset", 0) }; static struct snd_kcontrol_new snd_hdsp_controls[] = { @@ -3780,11 +3859,9 @@ static int snd_hdsp_reset(struct snd_pcm_substream *substream) else runtime->status->hw_ptr = 0; if (other) { - struct list_head *pos; struct snd_pcm_substream *s; struct snd_pcm_runtime *oruntime = other->runtime; - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if (s == other) { oruntime->status->hw_ptr = runtime->status->hw_ptr; break; @@ -3933,10 +4010,8 @@ static int snd_hdsp_trigger(struct snd_pcm_substream *substream, int cmd) other = hdsp->playback_substream; if (other) { - struct list_head *pos; struct snd_pcm_substream *s; - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if (s == other) { snd_pcm_trigger_done(s, substream); if (cmd == SNDRV_PCM_TRIGGER_START) diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index 6e95857e4e67..143185e7e4dc 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c @@ -91,8 +91,10 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); #define HDSPM_controlRegister 64 #define HDSPM_interruptConfirmation 96 #define HDSPM_control2Reg 256 /* not in specs ???????? */ +#define HDSPM_freqReg 256 /* for AES32 */ #define HDSPM_midiDataOut0 352 /* just believe in old code */ #define HDSPM_midiDataOut1 356 +#define HDSPM_eeprom_wr 384 /* for AES32 */ /* DMA enable for 64 channels, only Bit 0 is relevant */ #define HDSPM_outputEnableBase 512 /* 512-767 input DMA */ @@ -389,9 +391,8 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}"); size is the same regardless of the number of channels, and also the latency to use. for one direction !!! - => need to mupltiply by 2!! */ -#define HDSPM_DMA_AREA_BYTES (2 * HDSPM_MAX_CHANNELS * HDSPM_CHANNEL_BUFFER_BYTES) +#define HDSPM_DMA_AREA_BYTES (HDSPM_MAX_CHANNELS * HDSPM_CHANNEL_BUFFER_BYTES) #define HDSPM_DMA_AREA_KILOBYTES (HDSPM_DMA_AREA_BYTES/1024) /* revisions >= 230 indicate AES32 card */ @@ -484,28 +485,6 @@ static char channel_map_madi_ss[HDSPM_MAX_CHANNELS] = { 56, 57, 58, 59, 60, 61, 62, 63 }; -static char channel_map_madi_ds[HDSPM_MAX_CHANNELS] = { - 0, 2, 4, 6, 8, 10, 12, 14, - 16, 18, 20, 22, 24, 26, 28, 30, - 32, 34, 36, 38, 40, 42, 44, 46, - 48, 50, 52, 54, 56, 58, 60, 62, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1 -}; - -static char channel_map_madi_qs[HDSPM_MAX_CHANNELS] = { - 0, 4, 8, 12, 16, 20, 24, 28, - 32, 36, 40, 44, 48, 52, 56, 60 - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1 -}; - static struct pci_device_id snd_hdspm_ids[] __devinitdata = { { @@ -818,6 +797,27 @@ static int hdspm_set_interrupt_interval(struct hdspm * s, unsigned int frames) return 0; } +static void hdspm_set_dds_value(struct hdspm *hdspm, int rate) +{ + u64 n; + u32 r; + + if (rate >= 112000) + rate /= 4; + else if (rate >= 56000) + rate /= 2; + + /* RME says n = 104857600000000, but in the windows MADI driver, I see: +// return 104857600000000 / rate; // 100 MHz + return 110100480000000 / rate; // 105 MHz + */ + //n = 104857600000000ULL; /* = 2^20 * 10^8 */ + n = 110100480000000ULL; /* Value checked for AES32 and MADI */ + div64_32(&n, rate, &r); + /* n should be less than 2^32 for being written to FREQ register */ + snd_assert((n >> 32) == 0); + hdspm_write(hdspm, HDSPM_freqReg, (u32)n); +} /* dummy set rate lets see what happens */ static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally) @@ -943,12 +943,16 @@ static int hdspm_set_rate(struct hdspm * hdspm, int rate, int called_internally) hdspm->control_register |= rate_bits; hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); - if (rate > 96000 /* 64000*/) - hdspm->channel_map = channel_map_madi_qs; - else if (rate > 48000) - hdspm->channel_map = channel_map_madi_ds; - else - hdspm->channel_map = channel_map_madi_ss; + /* For AES32, need to set DDS value in FREQ register + For MADI, also apparently */ + hdspm_set_dds_value(hdspm, rate); + + if (hdspm->is_aes32 && rate != current_rate) + hdspm_write(hdspm, HDSPM_eeprom_wr, 0); + + /* For AES32 and for MADI (at least rev 204), channel_map needs to + * always be channel_map_madi_ss, whatever the sample rate */ + hdspm->channel_map = channel_map_madi_ss; hdspm->system_sample_rate = rate; @@ -3184,8 +3188,8 @@ snd_hdspm_proc_read_aes32(struct snd_info_entry * entry, hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xFF, hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xFF); snd_iprintf(buffer, - "Register: ctrl1=0x%x, ctrl2=0x%x, status1=0x%x, status2=0x%x, timecode=0x%x\n", - hdspm->control_register, hdspm->control2_register, + "Register: ctrl1=0x%x, status1=0x%x, status2=0x%x, timecode=0x%x\n", + hdspm->control_register, status, status2, timecode); snd_iprintf(buffer, "--- Settings ---\n"); @@ -3377,13 +3381,16 @@ static int snd_hdspm_set_defaults(struct hdspm * hdspm) hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); + if (!hdspm->is_aes32) { + /* No control2 register for AES32 */ #ifdef SNDRV_BIG_ENDIAN - hdspm->control2_register = HDSPM_BIGENDIAN_MODE; + hdspm->control2_register = HDSPM_BIGENDIAN_MODE; #else - hdspm->control2_register = 0; + hdspm->control2_register = 0; #endif - hdspm_write(hdspm, HDSPM_control2Reg, hdspm->control2_register); + hdspm_write(hdspm, HDSPM_control2Reg, hdspm->control2_register); + } hdspm_compute_period_size(hdspm); /* silence everything */ @@ -3575,11 +3582,9 @@ static int snd_hdspm_reset(struct snd_pcm_substream *substream) else runtime->status->hw_ptr = 0; if (other) { - struct list_head *pos; struct snd_pcm_substream *s; struct snd_pcm_runtime *oruntime = other->runtime; - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if (s == other) { oruntime->status->hw_ptr = runtime->status->hw_ptr; @@ -3658,11 +3663,10 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream, /* Memory allocation, takashi's method, dont know if we should spinlock */ /* malloc all buffer even if not enabled to get sure */ - /* malloc only needed bytes */ + /* Update for MADI rev 204: we need to allocate for all channels, + * otherwise it doesn't work at 96kHz */ err = - snd_pcm_lib_malloc_pages(substream, - HDSPM_CHANNEL_BUFFER_BYTES * - params_channels(params)); + snd_pcm_lib_malloc_pages(substream, HDSPM_DMA_AREA_BYTES); if (err < 0) return err; @@ -3698,6 +3702,13 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream, "playback" : "capture", snd_pcm_sgbuf_get_addr(sgbuf, 0)); */ + /* + snd_printdd("set_hwparams: %s %d Hz, %d channels, bs = %d\n", + substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? + "playback" : "capture", + params_rate(params), params_channels(params), + params_buffer_size(params)); + */ return 0; } @@ -3791,10 +3802,8 @@ static int snd_hdspm_trigger(struct snd_pcm_substream *substream, int cmd) other = hdspm->playback_substream; if (other) { - struct list_head *pos; struct snd_pcm_substream *s; - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if (s == other) { snd_pcm_trigger_done(s, substream); if (cmd == SNDRV_PCM_TRIGGER_START) @@ -3904,16 +3913,16 @@ static int snd_hdspm_hw_rule_channels_rate(struct snd_pcm_hw_params *params, struct snd_interval *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); - if (r->min > 48000) { + if (r->min > 48000 && r->max <= 96000) { struct snd_interval t = { - .min = 1, + .min = hdspm->ds_channels, .max = hdspm->ds_channels, .integer = 1, }; return snd_interval_refine(c, &t); } else if (r->max < 64000) { struct snd_interval t = { - .min = 1, + .min = hdspm->ss_channels, .max = hdspm->ss_channels, .integer = 1, }; @@ -3931,14 +3940,14 @@ static int snd_hdspm_hw_rule_rate_channels(struct snd_pcm_hw_params *params, struct snd_interval *r = hw_param_interval(params, SNDRV_PCM_HW_PARAM_RATE); - if (c->min <= hdspm->ss_channels) { + if (c->min >= hdspm->ss_channels) { struct snd_interval t = { .min = 32000, .max = 48000, .integer = 1, }; return snd_interval_refine(r, &t); - } else if (c->max > hdspm->ss_channels) { + } else if (c->max <= hdspm->ds_channels) { struct snd_interval t = { .min = 64000, .max = 96000, @@ -3950,13 +3959,39 @@ static int snd_hdspm_hw_rule_rate_channels(struct snd_pcm_hw_params *params, return 0; } +static int snd_hdspm_hw_rule_channels(struct snd_pcm_hw_params *params, + struct snd_pcm_hw_rule *rule) +{ + unsigned int list[3]; + struct hdspm *hdspm = rule->private; + struct snd_interval *c = hw_param_interval(params, + SNDRV_PCM_HW_PARAM_CHANNELS); + if (hdspm->is_aes32) { + list[0] = hdspm->qs_channels; + list[1] = hdspm->ds_channels; + list[2] = hdspm->ss_channels; + return snd_interval_list(c, 3, list, 0); + } else { + list[0] = hdspm->ds_channels; + list[1] = hdspm->ss_channels; + return snd_interval_list(c, 2, list, 0); + } +} + + +static unsigned int hdspm_aes32_sample_rates[] = { 32000, 44100, 48000, 64000, 88200, 96000, 128000, 176400, 192000 }; + +static struct snd_pcm_hw_constraint_list hdspm_hw_constraints_aes32_sample_rates = { + .count = ARRAY_SIZE(hdspm_aes32_sample_rates), + .list = hdspm_aes32_sample_rates, + .mask = 0 +}; + static int snd_hdspm_playback_open(struct snd_pcm_substream *substream) { struct hdspm *hdspm = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; - snd_printdd("Open device substream %d\n", substream->stream); - spin_lock_irq(&hdspm->lock); snd_pcm_set_sync(substream); @@ -3977,14 +4012,21 @@ static int snd_hdspm_playback_open(struct snd_pcm_substream *substream) SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hw_constraints_period_sizes); - snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, - snd_hdspm_hw_rule_channels_rate, hdspm, - SNDRV_PCM_HW_PARAM_RATE, -1); - - snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, - snd_hdspm_hw_rule_rate_channels, hdspm, - SNDRV_PCM_HW_PARAM_CHANNELS, -1); - + if (hdspm->is_aes32) { + snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, + &hdspm_hw_constraints_aes32_sample_rates); + } else { + snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, + snd_hdspm_hw_rule_channels, hdspm, + SNDRV_PCM_HW_PARAM_CHANNELS, -1); + snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, + snd_hdspm_hw_rule_channels_rate, hdspm, + SNDRV_PCM_HW_PARAM_RATE, -1); + + snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, + snd_hdspm_hw_rule_rate_channels, hdspm, + SNDRV_PCM_HW_PARAM_CHANNELS, -1); + } return 0; } @@ -4024,14 +4066,21 @@ static int snd_hdspm_capture_open(struct snd_pcm_substream *substream) snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, &hw_constraints_period_sizes); - - snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, - snd_hdspm_hw_rule_channels_rate, hdspm, - SNDRV_PCM_HW_PARAM_RATE, -1); - - snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, - snd_hdspm_hw_rule_rate_channels, hdspm, - SNDRV_PCM_HW_PARAM_CHANNELS, -1); + if (hdspm->is_aes32) { + snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, + &hdspm_hw_constraints_aes32_sample_rates); + } else { + snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, + snd_hdspm_hw_rule_channels, hdspm, + SNDRV_PCM_HW_PARAM_CHANNELS, -1); + snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, + snd_hdspm_hw_rule_channels_rate, hdspm, + SNDRV_PCM_HW_PARAM_RATE, -1); + + snd_pcm_hw_rule_add(runtime, 0, SNDRV_PCM_HW_PARAM_RATE, + snd_hdspm_hw_rule_rate_channels, hdspm, + SNDRV_PCM_HW_PARAM_CHANNELS, -1); + } return 0; } diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c index cc3bdececce7..bd7dbd267ed1 100644 --- a/sound/pci/rme9652/rme9652.c +++ b/sound/pci/rme9652/rme9652.c @@ -1992,11 +1992,9 @@ static int snd_rme9652_reset(struct snd_pcm_substream *substream) else runtime->status->hw_ptr = 0; if (other) { - struct list_head *pos; struct snd_pcm_substream *s; struct snd_pcm_runtime *oruntime = other->runtime; - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if (s == other) { oruntime->status->hw_ptr = runtime->status->hw_ptr; break; @@ -2140,10 +2138,8 @@ static int snd_rme9652_trigger(struct snd_pcm_substream *substream, other = rme9652->playback_substream; if (other) { - struct list_head *pos; struct snd_pcm_substream *s; - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if (s == other) { snd_pcm_trigger_done(s, substream); if (cmd == SNDRV_PCM_TRIGGER_START) diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c index 3bff32167f66..7ca606272460 100644 --- a/sound/pci/trident/trident_main.c +++ b/sound/pci/trident/trident_main.c @@ -1540,7 +1540,6 @@ static int snd_trident_trigger(struct snd_pcm_substream *substream, { struct snd_trident *trident = snd_pcm_substream_chip(substream); - struct list_head *pos; struct snd_pcm_substream *s; unsigned int what, whati, capture_flag, spdif_flag; struct snd_trident_voice *voice, *evoice; @@ -1563,8 +1562,7 @@ static int snd_trident_trigger(struct snd_pcm_substream *substream, what = whati = capture_flag = spdif_flag = 0; spin_lock(&trident->reg_lock); val = inl(TRID_REG(trident, T4D_STIMER)) & 0x00ffffff; - snd_pcm_group_for_each(pos, substream) { - s = snd_pcm_group_substream_entry(pos); + snd_pcm_group_for_each_entry(s, substream) { if ((struct snd_trident *) snd_pcm_substream_chip(s) == trident) { voice = s->runtime->private_data; evoice = voice->extra; diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c index fd12674d0394..ea861bceaddf 100644 --- a/sound/pci/ymfpci/ymfpci_main.c +++ b/sound/pci/ymfpci/ymfpci_main.c @@ -1998,9 +1998,7 @@ static void snd_ymfpci_disable_dsp(struct snd_ymfpci *chip) } } -#define FIRMWARE_IN_THE_KERNEL - -#ifdef FIRMWARE_IN_THE_KERNEL +#ifdef CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL #include "ymfpci_image.h" @@ -2018,6 +2016,24 @@ static struct firmware snd_ymfpci_controller_1e_microcode = { }; #endif +#ifdef CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL +static int snd_ymfpci_request_firmware(struct snd_ymfpci *chip) +{ + chip->dsp_microcode = &snd_ymfpci_dsp_microcode; + if (chip->device_id == PCI_DEVICE_ID_YAMAHA_724F || + chip->device_id == PCI_DEVICE_ID_YAMAHA_740C || + chip->device_id == PCI_DEVICE_ID_YAMAHA_744 || + chip->device_id == PCI_DEVICE_ID_YAMAHA_754) + chip->controller_microcode = + &snd_ymfpci_controller_1e_microcode; + else + chip->controller_microcode = + &snd_ymfpci_controller_microcode; + return 0; +} + +#else /* use fw_loader */ + #ifdef __LITTLE_ENDIAN static inline void snd_ymfpci_convert_from_le(const struct firmware *fw) { } #else @@ -2046,13 +2062,8 @@ static int snd_ymfpci_request_firmware(struct snd_ymfpci *chip) err = -EINVAL; } } - if (err < 0) { -#ifdef FIRMWARE_IN_THE_KERNEL - chip->dsp_microcode = &snd_ymfpci_dsp_microcode; -#else + if (err < 0) return err; -#endif - } is_1e = chip->device_id == PCI_DEVICE_ID_YAMAHA_724F || chip->device_id == PCI_DEVICE_ID_YAMAHA_740C || chip->device_id == PCI_DEVICE_ID_YAMAHA_744 || @@ -2069,18 +2080,17 @@ static int snd_ymfpci_request_firmware(struct snd_ymfpci *chip) err = -EINVAL; } } - if (err < 0) { -#ifdef FIRMWARE_IN_THE_KERNEL - chip->controller_microcode = - is_1e ? &snd_ymfpci_controller_1e_microcode - : &snd_ymfpci_controller_microcode; -#else + if (err < 0) return err; -#endif - } return 0; } +MODULE_FIRMWARE("yamaha/ds1_dsp.fw"); +MODULE_FIRMWARE("yamaha/ds1_ctrl.fw"); +MODULE_FIRMWARE("yamaha/ds1e_ctrl.fw"); + +#endif + static void snd_ymfpci_download_image(struct snd_ymfpci *chip) { int i; @@ -2259,15 +2269,10 @@ static int snd_ymfpci_free(struct snd_ymfpci *chip) pci_write_config_word(chip->pci, 0x40, chip->old_legacy_ctrl); pci_disable_device(chip->pci); -#ifdef FIRMWARE_IN_THE_KERNEL - if (chip->dsp_microcode != &snd_ymfpci_dsp_microcode) -#endif - release_firmware(chip->dsp_microcode); -#ifdef FIRMWARE_IN_THE_KERNEL - if (chip->controller_microcode != &snd_ymfpci_controller_microcode && - chip->controller_microcode != &snd_ymfpci_controller_1e_microcode) +#ifndef CONFIG_SND_YMFPCI_FIRMWARE_IN_KERNEL + release_firmware(chip->dsp_microcode); + release_firmware(chip->controller_microcode); #endif - release_firmware(chip->controller_microcode); kfree(chip); return 0; } |