From 24918b61b55c21e09a3e07cd82e1b3a8154782dc Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 30 Sep 2008 12:58:54 +0200 Subject: ALSA: hda - Fix model for Dell Inspiron 1525 Dell Inspiron 1525 seems to have a buggy BIOS setup and screws up the recent codec parser, as reported by Oleksandr Natalenko: http://lkml.org/lkml/2008/9/12/203 This patch adds the working model, dell-3stack, statically. Signed-off-by: Takashi Iwai Cc: --- sound/pci/hda/patch_sigmatel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index ad994fcab72..f3da621f25c 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -1683,8 +1683,8 @@ static struct snd_pci_quirk stac927x_cfg_tbl[] = { /* Dell 3 stack systems with verb table in BIOS */ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f3, "Dell Inspiron 1420", STAC_DELL_BIOS), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0227, "Dell Vostro 1400 ", STAC_DELL_BIOS), - SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022f, "Dell ", STAC_DELL_BIOS), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022e, "Dell ", STAC_DELL_BIOS), + SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x022f, "Dell Inspiron 1525", STAC_DELL_3ST), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0242, "Dell ", STAC_DELL_BIOS), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0243, "Dell ", STAC_DELL_BIOS), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ff, "Dell ", STAC_DELL_BIOS), -- cgit v1.2.3 From 68c072388d2339af504c033a51886ea7c6b8d806 Mon Sep 17 00:00:00 2001 From: Rene Herman Date: Tue, 15 Jul 2008 16:24:50 +0200 Subject: ALSA: re-order AC97 codec ID table. Signed-off-by: Rene Herman Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/ac97/ac97_codec.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index 8c49a00a5e3..f6a7d721649 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c @@ -67,8 +67,8 @@ struct ac97_codec_id { }; static const struct ac97_codec_id snd_ac97_codec_id_vendors[] = { -{ 0x414b4d00, 0xffffff00, "Asahi Kasei", NULL, NULL }, { 0x41445300, 0xffffff00, "Analog Devices", NULL, NULL }, +{ 0x414b4d00, 0xffffff00, "Asahi Kasei", NULL, NULL }, { 0x414c4300, 0xffffff00, "Realtek", NULL, NULL }, { 0x414c4700, 0xffffff00, "Realtek", NULL, NULL }, { 0x434d4900, 0xffffff00, "C-Media Electronics", NULL, NULL }, @@ -94,11 +94,6 @@ static const struct ac97_codec_id snd_ac97_codec_id_vendors[] = { }; static const struct ac97_codec_id snd_ac97_codec_ids[] = { -{ 0x414b4d00, 0xffffffff, "AK4540", NULL, NULL }, -{ 0x414b4d01, 0xffffffff, "AK4542", NULL, NULL }, -{ 0x414b4d02, 0xffffffff, "AK4543", NULL, NULL }, -{ 0x414b4d06, 0xffffffff, "AK4544A", NULL, NULL }, -{ 0x414b4d07, 0xffffffff, "AK4545", NULL, NULL }, { 0x41445303, 0xffffffff, "AD1819", patch_ad1819, NULL }, { 0x41445340, 0xffffffff, "AD1881", patch_ad1881, NULL }, { 0x41445348, 0xffffffff, "AD1881A", patch_ad1881, NULL }, @@ -112,20 +107,25 @@ static const struct ac97_codec_id snd_ac97_codec_ids[] = { { 0x41445374, 0xffffffff, "AD1981B", patch_ad1981b, NULL }, { 0x41445375, 0xffffffff, "AD1985", patch_ad1985, NULL }, { 0x41445378, 0xffffffff, "AD1986", patch_ad1986, NULL }, +{ 0x414b4d00, 0xffffffff, "AK4540", NULL, NULL }, +{ 0x414b4d01, 0xffffffff, "AK4542", NULL, NULL }, +{ 0x414b4d02, 0xffffffff, "AK4543", NULL, NULL }, +{ 0x414b4d06, 0xffffffff, "AK4544A", NULL, NULL }, +{ 0x414b4d07, 0xffffffff, "AK4545", NULL, NULL }, { 0x414c4300, 0xffffff00, "ALC100,100P", NULL, NULL }, { 0x414c4710, 0xfffffff0, "ALC200,200P", NULL, NULL }, { 0x414c4721, 0xffffffff, "ALC650D", NULL, NULL }, /* already patched */ { 0x414c4722, 0xffffffff, "ALC650E", NULL, NULL }, /* already patched */ { 0x414c4723, 0xffffffff, "ALC650F", NULL, NULL }, /* already patched */ { 0x414c4720, 0xfffffff0, "ALC650", patch_alc650, NULL }, -{ 0x414c4760, 0xfffffff0, "ALC655", patch_alc655, NULL }, -{ 0x414c4781, 0xffffffff, "ALC658D", NULL, NULL }, /* already patched */ -{ 0x414c4780, 0xfffffff0, "ALC658", patch_alc655, NULL }, -{ 0x414c4790, 0xfffffff0, "ALC850", patch_alc850, NULL }, { 0x414c4730, 0xffffffff, "ALC101", NULL, NULL }, { 0x414c4740, 0xfffffff0, "ALC202", NULL, NULL }, { 0x414c4750, 0xfffffff0, "ALC250", NULL, NULL }, +{ 0x414c4760, 0xfffffff0, "ALC655", patch_alc655, NULL }, { 0x414c4770, 0xfffffff0, "ALC203", NULL, NULL }, +{ 0x414c4781, 0xffffffff, "ALC658D", NULL, NULL }, /* already patched */ +{ 0x414c4780, 0xfffffff0, "ALC658", patch_alc655, NULL }, +{ 0x414c4790, 0xfffffff0, "ALC850", patch_alc850, NULL }, { 0x434d4941, 0xffffffff, "CMI9738", patch_cm9738, NULL }, { 0x434d4961, 0xffffffff, "CMI9739", patch_cm9739, NULL }, { 0x434d4969, 0xffffffff, "CMI9780", patch_cm9780, NULL }, -- cgit v1.2.3 From 1cd2224cd01898a13138f4ab476932cfb689839e Mon Sep 17 00:00:00 2001 From: Matthew Ranostay Date: Fri, 18 Jul 2008 18:20:52 +0200 Subject: ALSA: hda: digital pc-beep support hd-audio codecs Added digital pc-beep support using linear tone generation for hd-codecs along with initial support for several IDT codecs. Signed-off-by: Matthew Ranostay Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/Kconfig | 8 +++ sound/pci/hda/Makefile | 1 + sound/pci/hda/hda_beep.c | 134 +++++++++++++++++++++++++++++++++++++++++ sound/pci/hda/hda_beep.h | 44 ++++++++++++++ sound/pci/hda/hda_codec.h | 4 ++ sound/pci/hda/patch_sigmatel.c | 63 +++++++++++++++++++ 6 files changed, 254 insertions(+) create mode 100644 sound/pci/hda/hda_beep.c create mode 100644 sound/pci/hda/hda_beep.h (limited to 'sound/pci') diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index 31f52d3fc21..db9e31fd061 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -517,6 +517,14 @@ config SND_HDA_HWDEP This interface can be used for out-of-band communication with codecs for debugging purposes. +config SND_HDA_INPUT_BEEP + bool "Support digital beep via input layer" + depends on SND_HDA_INTEL + depends on INPUT=y || INPUT=SND_HDA_INTEL + help + Say Y here to build a digital beep interface for HD-audio + driver. This interface is used to generate digital beeps. + config SND_HDA_CODEC_REALTEK bool "Build Realtek HD-audio codec support" depends on SND_HDA_INTEL diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile index ab0c726d648..6db92fd954d 100644 --- a/sound/pci/hda/Makefile +++ b/sound/pci/hda/Makefile @@ -5,6 +5,7 @@ snd-hda-intel-y := hda_intel.o snd-hda-intel-y += hda_codec.o snd-hda-intel-$(CONFIG_PROC_FS) += hda_proc.o snd-hda-intel-$(CONFIG_SND_HDA_HWDEP) += hda_hwdep.o +snd-hda-intel-$(CONFIG_SND_HDA_INPUT_BEEP) += hda_beep.o snd-hda-intel-$(CONFIG_SND_HDA_GENERIC) += hda_generic.o snd-hda-intel-$(CONFIG_SND_HDA_CODEC_REALTEK) += patch_realtek.o snd-hda-intel-$(CONFIG_SND_HDA_CODEC_CMEDIA) += patch_cmedia.o diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c new file mode 100644 index 00000000000..5a764c48139 --- /dev/null +++ b/sound/pci/hda/hda_beep.c @@ -0,0 +1,134 @@ +/* + * Digital Beep Input Interface for HD-audio codec + * + * Author: Matthew Ranostay + * Copyright (c) 2008 Embedded Alley Solutions Inc + * + * This driver is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This driver is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include "hda_beep.h" + +enum { + DIGBEEP_HZ_STEP = 46875, /* 46.875 Hz */ + DIGBEEP_HZ_MIN = 93750, /* 93.750 Hz */ + DIGBEEP_HZ_MAX = 12000000, /* 12 KHz */ +}; + +static void snd_hda_generate_beep(struct work_struct *work) +{ + struct hda_beep *beep = + container_of(work, struct hda_beep, beep_work); + struct hda_codec *codec = beep->codec; + + /* generate tone */ + snd_hda_codec_write_cache(codec, beep->nid, 0, + AC_VERB_SET_BEEP_CONTROL, beep->tone); +} + +static int snd_hda_beep_event(struct input_dev *dev, unsigned int type, + unsigned int code, int hz) +{ + struct hda_beep *beep = input_get_drvdata(dev); + + switch (code) { + case SND_BELL: + if (hz) + hz = 1000; + case SND_TONE: + hz *= 1000; /* fixed point */ + hz = hz - DIGBEEP_HZ_MIN; + if (hz < 0) + hz = 0; /* turn off PC beep*/ + else if (hz >= (DIGBEEP_HZ_MAX - DIGBEEP_HZ_MIN)) + hz = 0xff; + else { + hz /= DIGBEEP_HZ_STEP; + hz++; + } + break; + default: + return -1; + } + beep->tone = hz; + + /* schedule beep event */ + schedule_work(&beep->beep_work); + return 0; +} + +int snd_hda_attach_beep_device(struct hda_codec *codec, int nid) +{ + struct input_dev *input_dev; + struct hda_beep *beep; + int err; + + beep = kzalloc(sizeof(*beep), GFP_KERNEL); + if (beep == NULL) + return -ENOMEM; + snprintf(beep->phys, sizeof(beep->phys), + "card%d/codec#%d/beep0", codec->bus->card->number, codec->addr); + input_dev = input_allocate_device(); + + /* setup digital beep device */ + input_dev->name = "HDA Digital PCBeep"; + input_dev->phys = beep->phys; + input_dev->id.bustype = BUS_PCI; + + input_dev->id.vendor = codec->vendor_id >> 16; + input_dev->id.product = codec->vendor_id & 0xffff; + input_dev->id.version = 0x01; + + input_dev->evbit[0] = BIT_MASK(EV_SND); + input_dev->sndbit[0] = BIT_MASK(SND_BELL) | BIT_MASK(SND_TONE); + input_dev->event = snd_hda_beep_event; + input_dev->dev.parent = &codec->bus->pci->dev; + input_set_drvdata(input_dev, beep); + + err = input_register_device(input_dev); + if (err < 0) { + kfree(input_dev); + kfree(beep); + return err; + } + + /* enable linear scale */ + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_DIGI_CONVERT_2, 0x01); + + beep->nid = nid; + beep->dev = input_dev; + beep->codec = codec; + codec->beep = beep; + + INIT_WORK(&beep->beep_work, &snd_hda_generate_beep); + return 0; +} + +void snd_hda_detach_beep_device(struct hda_codec *codec) +{ + struct hda_beep *beep = codec->beep; + if (beep) { + cancel_work_sync(&beep->beep_work); + flush_scheduled_work(); + + input_unregister_device(beep->dev); + kfree(beep); + } +} diff --git a/sound/pci/hda/hda_beep.h b/sound/pci/hda/hda_beep.h new file mode 100644 index 00000000000..de4036e6e71 --- /dev/null +++ b/sound/pci/hda/hda_beep.h @@ -0,0 +1,44 @@ +/* + * Digital Beep Input Interface for HD-audio codec + * + * Author: Matthew Ranostay + * Copyright (c) 2008 Embedded Alley Solutions Inc + * + * This driver is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This driver is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __SOUND_HDA_BEEP_H +#define __SOUND_HDA_BEEP_H + +#include "hda_codec.h" + +/* beep information */ +struct hda_beep { + struct input_dev *dev; + struct hda_codec *codec; + char phys[32]; + int tone; + int nid; + struct work_struct beep_work; /* scheduled task for beep event */ +}; + +#ifdef CONFIG_SND_HDA_INPUT_BEEP +int snd_hda_attach_beep_device(struct hda_codec *codec, int nid); +void snd_hda_detach_beep_device(struct hda_codec *codec); +#else +#define snd_hda_attach_beep_device(...) +#define snd_hda_detach_beep_device(...) +#endif +#endif diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index efc682888b3..3a63c445d36 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -449,6 +449,7 @@ enum { */ struct hda_bus; +struct hda_beep; struct hda_codec; struct hda_pcm; struct hda_pcm_stream; @@ -634,6 +635,9 @@ struct hda_codec { /* codec specific info */ void *spec; + /* beep device */ + struct hda_beep *beep; + /* widget capabilities cache */ unsigned int num_nodes; hda_nid_t start_nid; diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index f3da621f25c..6ee73ed23dd 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -33,6 +33,7 @@ #include "hda_codec.h" #include "hda_local.h" #include "hda_patch.h" +#include "hda_beep.h" #define NUM_CONTROL_ALLOC 32 #define STAC_PWR_EVENT 0x20 @@ -164,6 +165,8 @@ struct sigmatel_spec { unsigned int num_dmuxes; hda_nid_t dig_in_nid; hda_nid_t mono_nid; + hda_nid_t anabeep_nid; + hda_nid_t digbeep_nid; /* pin widgets */ hda_nid_t *pin_nids; @@ -690,6 +693,8 @@ static struct hda_verb d965_core_init[] = { static struct hda_verb stac927x_core_init[] = { /* set master volume and direct control */ { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, + /* enable analog pc beep path */ + { 0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5}, {} }; @@ -829,8 +834,11 @@ static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = { HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1d, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME_IDX("Capture Mux Volume", 0x1, 0x1b, 0x0, HDA_OUTPUT), + /* analog pc-beep replaced with digital beep support */ + /* HDA_CODEC_VOLUME("PC Beep Volume", 0x17, 0x2, HDA_INPUT), HDA_CODEC_MUTE("PC Beep Switch", 0x17, 0x2, HDA_INPUT), + */ HDA_CODEC_MUTE("Analog Loopback 1", 0x17, 0x3, HDA_INPUT), HDA_CODEC_MUTE("Analog Loopback 2", 0x17, 0x4, HDA_INPUT), @@ -2609,6 +2617,34 @@ static int stac92xx_auto_create_mono_output_ctls(struct hda_codec *codec) "Mono Mux", spec->mono_nid); } +/* create PC beep volume controls */ +static int stac92xx_auto_create_beep_ctls(struct hda_codec *codec, + hda_nid_t nid) +{ + struct sigmatel_spec *spec = codec->spec; + u32 caps = query_amp_caps(codec, nid, HDA_OUTPUT); + int err; + + /* check for mute support for the the amp */ + if ((caps & AC_AMPCAP_MUTE) >> AC_AMPCAP_MUTE_SHIFT) { + err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, + "PC Beep Playback Switch", + HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT)); + if (err < 0) + return err; + } + + /* check to see if there is volume support for the amp */ + if ((caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT) { + err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, + "PC Beep Playback Volume", + HDA_COMPOSE_AMP_VAL(nid, 1, 0, HDA_OUTPUT)); + if (err < 0) + return err; + } + return 0; +} + /* labels for dmic mux inputs */ static const char *stac92xx_dmic_labels[5] = { "Analog Inputs", "Digital Mic 1", "Digital Mic 2", @@ -2844,6 +2880,28 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out if (err < 0) return err; + /* setup analog beep controls */ + if (spec->anabeep_nid > 0) { + err = stac92xx_auto_create_beep_ctls(codec, + spec->anabeep_nid); + if (err < 0) + return err; + } + + /* setup digital beep controls and input device */ +#ifdef CONFIG_SND_HDA_INPUT_BEEP + if (spec->digbeep_nid > 0) { + hda_nid_t nid = spec->digbeep_nid; + + err = stac92xx_auto_create_beep_ctls(codec, nid); + if (err < 0) + return err; + err = snd_hda_attach_beep_device(codec, nid); + if (err < 0) + return err; + } +#endif + if (hp_speaker_swap == 1) { /* Restore the hp_outs and line_outs */ memcpy(spec->autocfg.hp_pins, spec->autocfg.line_out_pins, @@ -3158,6 +3216,7 @@ static void stac92xx_free(struct hda_codec *codec) kfree(spec->bios_pin_configs); kfree(spec); + snd_hda_detach_beep_device(codec); } static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid, @@ -3546,6 +3605,7 @@ again: spec->aloopback_mask = 0x01; spec->aloopback_shift = 8; + spec->digbeep_nid = 0x1c; spec->mux_nids = stac92hd73xx_mux_nids; spec->adc_nids = stac92hd73xx_adc_nids; spec->dmic_nids = stac92hd73xx_dmic_nids; @@ -3680,6 +3740,7 @@ again: spec->gpio_dir = 0x01; spec->gpio_data = 0x01; + spec->digbeep_nid = 0x26; spec->mux_nids = stac92hd71bxx_mux_nids; spec->adc_nids = stac92hd71bxx_adc_nids; spec->dmic_nids = stac92hd71bxx_dmic_nids; @@ -3854,6 +3915,7 @@ static int patch_stac927x(struct hda_codec *codec) stac92xx_set_config_regs(codec); } + spec->digbeep_nid = 0x23; spec->adc_nids = stac927x_adc_nids; spec->num_adcs = ARRAY_SIZE(stac927x_adc_nids); spec->mux_nids = stac927x_mux_nids; @@ -3974,6 +4036,7 @@ static int patch_stac9205(struct hda_codec *codec) stac92xx_set_config_regs(codec); } + spec->digbeep_nid = 0x23; spec->adc_nids = stac9205_adc_nids; spec->num_adcs = ARRAY_SIZE(stac9205_adc_nids); spec->mux_nids = stac9205_mux_nids; -- cgit v1.2.3 From d0513fc6c37b009004cf5c7a8e90af0adb3755bc Mon Sep 17 00:00:00 2001 From: Matthew Ranostay Date: Sun, 27 Jul 2008 10:30:30 +0200 Subject: ALSA: hda: added 92HD81/83 support Added support for 92HD81/83 family of codecs. This also includes a pwr_mapping array for pins that have more than one amp to power down. Signed-off-by: Matthew Ranostay Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_codec.h | 1 + sound/pci/hda/patch_sigmatel.c | 248 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 227 insertions(+), 22 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 3a63c445d36..2f112626f24 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -121,6 +121,7 @@ enum { #define AC_VERB_SET_CONFIG_DEFAULT_BYTES_1 0x71d #define AC_VERB_SET_CONFIG_DEFAULT_BYTES_2 0x71e #define AC_VERB_SET_CONFIG_DEFAULT_BYTES_3 0x71f +#define AC_VERB_SET_EAPD 0x788 #define AC_VERB_SET_CODEC_RESET 0x7ff /* diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 6ee73ed23dd..23a7b2228e3 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -71,6 +71,11 @@ enum { STAC_92HD73XX_MODELS }; +enum { + STAC_92HD83XXX_REF, + STAC_92HD83XXX_MODELS +}; + enum { STAC_92HD71BXX_REF, STAC_DELL_M4_1, @@ -145,6 +150,7 @@ struct sigmatel_spec { /* power management */ unsigned int num_pwrs; + unsigned int *pwr_mapping; hda_nid_t *pwr_nids; hda_nid_t *dac_list; @@ -240,6 +246,33 @@ static hda_nid_t stac92hd73xx_dmux_nids[2] = { 0x20, 0x21, }; +#define STAC92HD83XXX_NUM_DMICS 2 +static hda_nid_t stac92hd83xxx_dmic_nids[STAC92HD83XXX_NUM_DMICS + 1] = { + 0x11, 0x12, 0 +}; + +#define STAC92HD81_DAC_COUNT 2 +#define STAC92HD83_DAC_COUNT 3 +static hda_nid_t stac92hd83xxx_dac_nids[STAC92HD73_DAC_COUNT] = { + 0x13, 0x14, 0x22, +}; + +static hda_nid_t stac92hd83xxx_dmux_nids[2] = { + 0x17, 0x18, +}; + +static hda_nid_t stac92hd83xxx_adc_nids[2] = { + 0x15, 0x16, +}; + +static hda_nid_t stac92hd83xxx_pwr_nids[4] = { + 0xa, 0xb, 0xd, 0xe, +}; + +static unsigned int stac92hd83xxx_pwr_mapping[4] = { + 0x03, 0x0c, 0x10, 0x40, +}; + static hda_nid_t stac92hd71bxx_pwr_nids[3] = { 0x0a, 0x0d, 0x0f }; @@ -353,6 +386,11 @@ static hda_nid_t stac92hd73xx_pin_nids[13] = { 0x14, 0x1e, 0x22 }; +static hda_nid_t stac92hd83xxx_pin_nids[14] = { + 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, + 0x0f, 0x10, 0x11, 0x12, 0x13, + 0x1d, 0x1e, 0x1f, 0x20 +}; static hda_nid_t stac92hd71bxx_pin_nids[10] = { 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x14, 0x18, 0x19, 0x1e, @@ -631,6 +669,19 @@ static struct hda_verb stac92hd73xx_10ch_core_init[] = { {} }; +static struct hda_verb stac92hd83xxx_core_init[] = { + /* start of config #1 */ + { 0xe, AC_VERB_SET_CONNECT_SEL, 0x3}, + + /* start of config #2 */ + { 0xa, AC_VERB_SET_CONNECT_SEL, 0x0}, + { 0xb, AC_VERB_SET_CONNECT_SEL, 0x0}, + { 0xd, AC_VERB_SET_CONNECT_SEL, 0x1}, + + /* power state controls amps */ + { 0x01, AC_VERB_SET_EAPD, 1 << 2}, +}; + static struct hda_verb stac92hd71bxx_core_init[] = { /* set master volume and direct control */ { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, @@ -701,6 +752,8 @@ static struct hda_verb stac927x_core_init[] = { static struct hda_verb stac9205_core_init[] = { /* set master volume and direct control */ { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, + /* enable analog pc beep path */ + { 0x01, AC_VERB_SET_DIGI_CONVERT_2, 1 << 5}, {} }; @@ -823,6 +876,33 @@ static struct snd_kcontrol_new stac92hd73xx_10ch_mixer[] = { { } /* end */ }; + +static struct snd_kcontrol_new stac92hd83xxx_mixer[] = { + HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_OUTPUT), + + HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x18, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x18, 0x0, HDA_OUTPUT), + + HDA_CODEC_VOLUME("DAC0 Capture Volume", 0x1b, 0, HDA_INPUT), + HDA_CODEC_MUTE("DAC0 Capture Switch", 0x1b, 0, HDA_INPUT), + + HDA_CODEC_VOLUME("DAC1 Capture Volume", 0x1b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("DAC1 Capture Switch", 0x1b, 0x1, HDA_INPUT), + + HDA_CODEC_VOLUME("Front Mic Capture Volume", 0x1b, 0x2, HDA_INPUT), + HDA_CODEC_MUTE("Front Mic Capture Switch", 0x1b, 0x2, HDA_INPUT), + + HDA_CODEC_VOLUME("Line In Capture Volume", 0x1b, 0x3, HDA_INPUT), + HDA_CODEC_MUTE("Line In Capture Switch", 0x1b, 0x3, HDA_INPUT), + + /* + HDA_CODEC_VOLUME("Mic Capture Volume", 0x1b, 0x4, HDA_INPUT), + HDA_CODEC_MUTE("Mic Capture Switch", 0x1b 0x4, HDA_INPUT), + */ + { } /* end */ +}; + static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = { STAC_INPUT_SOURCE(2), @@ -1333,6 +1413,27 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = { {} /* terminator */ }; +static unsigned int ref92hd83xxx_pin_configs[14] = { + 0x02214030, 0x02211010, 0x02a19020, 0x02170130, + 0x01014050, 0x01819040, 0x01014020, 0x90a3014e, + 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x40f000f0, + 0x01451160, 0x98560170, +}; + +static unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = { + [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs, +}; + +static const char *stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = { + [STAC_92HD83XXX_REF] = "ref", +}; + +static struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { + /* SigmaTel reference board */ + SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, + "DFI LanParty", STAC_92HD71BXX_REF), +}; + static unsigned int ref92hd71bxx_pin_configs[10] = { 0x02214030, 0x02a19040, 0x01a19020, 0x01014010, 0x0181302e, 0x01114010, 0x01019020, 0x90a000f0, @@ -2587,8 +2688,8 @@ static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec, } /* labels for mono mux outputs */ -static const char *stac92xx_mono_labels[3] = { - "DAC0", "DAC1", "Mixer" +static const char *stac92xx_mono_labels[4] = { + "DAC0", "DAC1", "Mixer", "DAC2" }; /* create mono mux for mono out on capable codecs */ @@ -2692,16 +2793,19 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, } continue; found: - wcaps = get_wcaps(codec, nid); + wcaps = get_wcaps(codec, nid) & + (AC_WCAP_OUT_AMP | AC_WCAP_IN_AMP); - if (wcaps & AC_WCAP_OUT_AMP) { + if (wcaps) { sprintf(name, "%s Capture Volume", stac92xx_dmic_labels[dimux->num_items]); err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, name, - HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); + HDA_COMPOSE_AMP_VAL(nid, 3, 0, + (wcaps & AC_WCAP_OUT_AMP) ? + HDA_OUTPUT : HDA_INPUT)); if (err < 0) return err; } @@ -2825,8 +2929,8 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out hp_speaker_swap = 1; } if (spec->autocfg.mono_out_pin) { - int dir = (get_wcaps(codec, spec->autocfg.mono_out_pin) - & AC_WCAP_OUT_AMP) ? HDA_OUTPUT : HDA_INPUT; + int dir = get_wcaps(codec, spec->autocfg.mono_out_pin) & + (AC_WCAP_OUT_AMP | AC_WCAP_IN_AMP); u32 caps = query_amp_caps(codec, spec->autocfg.mono_out_pin, dir); hda_nid_t conn_list[1]; @@ -2848,21 +2952,26 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out !(wcaps & AC_WCAP_LR_SWAP)) spec->mono_nid = conn_list[0]; } - /* all mono outs have a least a mute/unmute switch */ - err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, - "Mono Playback Switch", - HDA_COMPOSE_AMP_VAL(spec->autocfg.mono_out_pin, - 1, 0, dir)); - if (err < 0) - return err; - /* check to see if there is volume support for the amp */ - if ((caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT) { - err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, - "Mono Playback Volume", - HDA_COMPOSE_AMP_VAL(spec->autocfg.mono_out_pin, - 1, 0, dir)); + if (dir) { + hda_nid_t nid = spec->autocfg.mono_out_pin; + + /* most mono outs have a least a mute/unmute switch */ + dir = (dir & AC_WCAP_OUT_AMP) ? HDA_OUTPUT : HDA_INPUT; + err = stac92xx_add_control(spec, STAC_CTL_WIDGET_MUTE, + "Mono Playback Switch", + HDA_COMPOSE_AMP_VAL(nid, 1, 0, dir)); if (err < 0) return err; + /* check for volume support for the amp */ + if ((caps & AC_AMPCAP_NUM_STEPS) + >> AC_AMPCAP_NUM_STEPS_SHIFT) { + err = stac92xx_add_control(spec, + STAC_CTL_WIDGET_VOL, + "Mono Playback Volume", + HDA_COMPOSE_AMP_VAL(nid, 1, 0, dir)); + if (err < 0) + return err; + } } stac92xx_auto_set_pinctl(codec, spec->autocfg.mono_out_pin, @@ -2942,7 +3051,7 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out if (spec->autocfg.dig_out_pin) spec->multiout.dig_out_nid = dig_out; - if (spec->autocfg.dig_in_pin) + if (dig_in && spec->autocfg.dig_in_pin) spec->dig_in_nid = dig_in; if (spec->kctl_alloc) @@ -3338,7 +3447,12 @@ static void stac92xx_pin_sense(struct hda_codec *codec, int idx) val = snd_hda_codec_read(codec, codec->afg, 0, 0x0fec, 0x0) & 0x000000ff; presence = get_hp_pin_presence(codec, nid); - idx = 1 << idx; + + /* several codecs have two power down bits */ + if (spec->pwr_mapping) + idx = spec->pwr_mapping[idx]; + else + idx = 1 << idx; if (presence) val &= ~idx; @@ -3674,6 +3788,94 @@ again: return 0; } +static struct hda_input_mux stac92hd83xxx_dmux = { + .num_items = 3, + .items = { + { "Analog Inputs", 0x03 }, + { "Digital Mic 1", 0x04 }, + { "Digital Mic 2", 0x05 }, + } +}; + +static int patch_stac92hd83xxx(struct hda_codec *codec) +{ + struct sigmatel_spec *spec; + int err; + + spec = kzalloc(sizeof(*spec), GFP_KERNEL); + if (spec == NULL) + return -ENOMEM; + + codec->spec = spec; + spec->mono_nid = 0x19; + spec->digbeep_nid = 0x21; + spec->dmic_nids = stac92hd83xxx_dmic_nids; + spec->dmux_nids = stac92hd83xxx_dmux_nids; + spec->adc_nids = stac92hd83xxx_adc_nids; + spec->pwr_nids = stac92hd83xxx_pwr_nids; + spec->pwr_mapping = stac92hd83xxx_pwr_mapping; + spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids); + spec->multiout.dac_nids = stac92hd83xxx_dac_nids; + + spec->init = stac92hd83xxx_core_init; + switch (codec->vendor_id) { + case 0x111d7605: + spec->multiout.num_dacs = STAC92HD81_DAC_COUNT; + break; + default: + spec->num_pwrs--; + spec->init++; /* switch to config #2 */ + spec->multiout.num_dacs = STAC92HD83_DAC_COUNT; + } + + spec->mixer = stac92hd83xxx_mixer; + spec->num_pins = ARRAY_SIZE(stac92hd83xxx_pin_nids); + spec->num_dmuxes = ARRAY_SIZE(stac92hd83xxx_dmux_nids); + spec->num_adcs = ARRAY_SIZE(stac92hd83xxx_adc_nids); + spec->num_dmics = STAC92HD83XXX_NUM_DMICS; + spec->dinput_mux = &stac92hd83xxx_dmux; + spec->pin_nids = stac92hd83xxx_pin_nids; + spec->board_config = snd_hda_check_board_config(codec, + STAC_92HD83XXX_MODELS, + stac92hd83xxx_models, + stac92hd83xxx_cfg_tbl); +again: + if (spec->board_config < 0) { + snd_printdd(KERN_INFO "hda_codec: Unknown model for" + " STAC92HD83XXX, using BIOS defaults\n"); + err = stac92xx_save_bios_config_regs(codec); + if (err < 0) { + stac92xx_free(codec); + return err; + } + spec->pin_configs = spec->bios_pin_configs; + } else { + spec->pin_configs = stac92hd83xxx_brd_tbl[spec->board_config]; + stac92xx_set_config_regs(codec); + } + + err = stac92xx_parse_auto_config(codec, 0x1d, 0); + if (!err) { + if (spec->board_config < 0) { + printk(KERN_WARNING "hda_codec: No auto-config is " + "available, default to model=ref\n"); + spec->board_config = STAC_92HD83XXX_REF; + goto again; + } + err = -EINVAL; + } + + if (err < 0) { + stac92xx_free(codec); + return err; + } + + codec->patch_ops = stac92xx_patch_ops; + + return 0; +} + + static int patch_stac92hd71bxx(struct hda_codec *codec) { struct sigmatel_spec *spec; @@ -4395,6 +4597,8 @@ struct hda_codec_preset snd_hda_preset_sigmatel[] = { { .id = 0x838476a6, .name = "STAC9254", .patch = patch_stac9205 }, { .id = 0x838476a7, .name = "STAC9254D", .patch = patch_stac9205 }, { .id = 0x111d7603, .name = "92HD75B3X5", .patch = patch_stac92hd71bxx}, + { .id = 0x111d7604, .name = "92HD83C1X5", .patch = patch_stac92hd83xxx}, + { .id = 0x111d7605, .name = "92HD81B1X5", .patch = patch_stac92hd83xxx}, { .id = 0x111d7608, .name = "92HD75B2X5", .patch = patch_stac92hd71bxx}, { .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx }, { .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx }, -- cgit v1.2.3 From 0b18cb1854152a62492aae088cb80cbeb5c0288d Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Mon, 28 Jul 2008 17:07:07 +0200 Subject: ALSA: Fix commit: Add automatic model setting for the Acer Aspire 5920G laptop There is a whitespace at the end of added line. Remove it. Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 66025161bd6..38017a129ba 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -7942,7 +7942,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE), SND_PCI_QUIRK(0x1025, 0x0110, "Acer Aspire", ALC883_ACER_ASPIRE), SND_PCI_QUIRK(0x1025, 0x0112, "Acer Aspire 9303", ALC883_ACER_ASPIRE), - SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE), + SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE), SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */ SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL), SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG), -- cgit v1.2.3 From f6154d6d007c69a330acc9021ec77cca5da9dc4c Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 29 Jul 2008 12:08:16 +0200 Subject: ALSA: hda - use input_free_device() Use input_free_devce() correctly instead of kfree() at error path. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_beep.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c index 5a764c48139..9b77b3e0fa9 100644 --- a/sound/pci/hda/hda_beep.c +++ b/sound/pci/hda/hda_beep.c @@ -103,7 +103,7 @@ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid) err = input_register_device(input_dev); if (err < 0) { - kfree(input_dev); + input_free_device(input_dev); kfree(beep); return err; } -- cgit v1.2.3 From 740dc9c4766b462ae88a630e969ddd3ef83a6125 Mon Sep 17 00:00:00 2001 From: Misha Zhilin Date: Fri, 1 Aug 2008 12:45:14 +0200 Subject: ALSA: ice1724 - Support for Terrasoniq/MUSONIK TS22 PCI card Added support for Terrasoniq/MUSONIK TS22 PCI card. Signed-off-by: Misha Zhilin Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/ice1712/phase.c | 12 ++++++++++++ sound/pci/ice1712/phase.h | 4 +++- 2 files changed, 15 insertions(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/ice1712/phase.c b/sound/pci/ice1712/phase.c index 5a158b73dca..f5acdeef443 100644 --- a/sound/pci/ice1712/phase.c +++ b/sound/pci/ice1712/phase.c @@ -120,6 +120,7 @@ static int __devinit phase22_init(struct snd_ice1712 *ice) // Configure DAC/ADC description for generic part of ice1724 switch (ice->eeprom.subvendor) { case VT1724_SUBDEVICE_PHASE22: + case VT1724_SUBDEVICE_TS22: ice->num_total_dacs = 2; ice->num_total_adcs = 2; ice->vt1720 = 1; // Envy24HT-S have 16 bit wide GPIO @@ -136,6 +137,7 @@ static int __devinit phase22_init(struct snd_ice1712 *ice) ice->akm_codecs = 1; switch (ice->eeprom.subvendor) { case VT1724_SUBDEVICE_PHASE22: + case VT1724_SUBDEVICE_TS22: if ((err = snd_ice1712_akm4xxx_init(ak, &akm_phase22, &akm_phase22_priv, ice)) < 0) return err; break; @@ -150,6 +152,7 @@ static int __devinit phase22_add_controls(struct snd_ice1712 *ice) switch (ice->eeprom.subvendor) { case VT1724_SUBDEVICE_PHASE22: + case VT1724_SUBDEVICE_TS22: err = snd_ice1712_akm4xxx_build_controls(ice); if (err < 0) return err; @@ -904,5 +907,14 @@ struct snd_ice1712_card_info snd_vt1724_phase_cards[] __devinitdata = { .eeprom_size = sizeof(phase28_eeprom), .eeprom_data = phase28_eeprom, }, + { + .subvendor = VT1724_SUBDEVICE_TS22, + .name = "Terrasoniq TS22 PCI", + .model = "TS22", + .chip_init = phase22_init, + .build_controls = phase22_add_controls, + .eeprom_size = sizeof(phase22_eeprom), + .eeprom_data = phase22_eeprom, + }, { } /* terminator */ }; diff --git a/sound/pci/ice1712/phase.h b/sound/pci/ice1712/phase.h index 13e841b5548..5f0c4dbf30d 100644 --- a/sound/pci/ice1712/phase.h +++ b/sound/pci/ice1712/phase.h @@ -25,10 +25,12 @@ */ #define PHASE_DEVICE_DESC "{Terratec,Phase 22},"\ - "{Terratec,Phase 28}," + "{Terratec,Phase 28},"\ + "{Terrasoniq,TS22}," #define VT1724_SUBDEVICE_PHASE22 0x3b155011 #define VT1724_SUBDEVICE_PHASE28 0x3b154911 +#define VT1724_SUBDEVICE_TS22 0x3b157b11 /* entry point */ extern struct snd_ice1712_card_info snd_vt1724_phase_cards[]; -- cgit v1.2.3 From e8f9ae2a4a0654e7798b8c0ae956e3f0fdc23c8d Mon Sep 17 00:00:00 2001 From: Pascal Terjan Date: Mon, 4 Aug 2008 14:36:05 +0200 Subject: ALSA: hda - Fix sound on NEC Versa S9100 This patch adds sound support for NEC Versa S9100 With it, we get sound on the internal speaker and headphone (with automute working) while there is no sound by default. External mic also works fine but I don't know if there is an internal one (if there is an internal mic it does not work currently), and I had to send back the hardware. Signed-off-by: Pascal Terjan Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 48 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 38017a129ba..4bd26725355 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -100,6 +100,7 @@ enum { ALC262_BENQ_T31, ALC262_ULTRA, ALC262_LENOVO_3000, + ALC262_NEC, ALC262_AUTO, ALC262_MODEL_LAST /* last tag */ }; @@ -8947,6 +8948,41 @@ static void alc262_hippo1_unsol_event(struct hda_codec *codec, alc262_hippo1_automute(codec); } +/* + * nec model + * 0x15 = headphone + * 0x16 = internal speaker + * 0x18 = external mic + */ + +static struct snd_kcontrol_new alc262_nec_mixer[] = { + HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT), + + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + + HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), + { } /* end */ +}; + +static struct hda_verb alc262_nec_verbs[] = { + /* Unmute Speaker */ + {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + + /* Headphone */ + {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, + {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + + /* External mic to headphone */ + {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + /* External mic to speaker */ + {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {} +}; + /* * fujitsu model * 0x14 = headphone/spdif-out, 0x15 = internal speaker, @@ -9731,11 +9767,13 @@ static const char *alc262_models[ALC262_MODEL_LAST] = { [ALC262_SONY_ASSAMD] = "sony-assamd", [ALC262_ULTRA] = "ultra", [ALC262_LENOVO_3000] = "lenovo-3000", + [ALC262_NEC] = "nec", [ALC262_AUTO] = "auto", }; static struct snd_pci_quirk alc262_cfg_tbl[] = { SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO), + SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC), SND_PCI_QUIRK(0x103c, 0x12fe, "HP xw9400", ALC262_HP_BPC), SND_PCI_QUIRK(0x103c, 0x12ff, "HP xw4550", ALC262_HP_BPC), SND_PCI_QUIRK(0x103c, 0x1306, "HP xw8600", ALC262_HP_BPC), @@ -9946,6 +9984,16 @@ static struct alc_config_preset alc262_presets[] = { .input_mux = &alc262_fujitsu_capture_source, .unsol_event = alc262_lenovo_3000_unsol_event, }, + [ALC262_NEC] = { + .mixers = { alc262_nec_mixer }, + .init_verbs = { alc262_nec_verbs }, + .num_dacs = ARRAY_SIZE(alc262_dac_nids), + .dac_nids = alc262_dac_nids, + .hp_nid = 0x03, + .num_channel_mode = ARRAY_SIZE(alc262_modes), + .channel_mode = alc262_modes, + .input_mux = &alc262_capture_source, + }, }; static int patch_alc262(struct hda_codec *codec) -- cgit v1.2.3 From 8c650087992f1d7a3a7be2e632f4e85a52d20619 Mon Sep 17 00:00:00 2001 From: Mauro Carvalho Chehab Date: Mon, 4 Aug 2008 10:39:59 -0300 Subject: ALSA: hda: Add support for ECS/PC Chips boards with Sigmatel codecs Thanks to Sistema Fenix (http://www.sistemafenix.com.br/) and CDI Brasil (www.cdibrasil.com.br/) for sponsoring this development. Signed-off-by: Gilberto Signed-off-by: Mauro Carvalho Chehab Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 23a7b2228e3..fac6b3ca5fe 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -110,6 +110,7 @@ enum { STAC_MACBOOK_PRO_V2, STAC_IMAC_INTEL, STAC_IMAC_INTEL_20, + STAC_ECS_202, STAC_922X_DELL_D81, STAC_922X_DELL_D82, STAC_922X_DELL_M81, @@ -1586,6 +1587,11 @@ static unsigned int intel_mac_v5_pin_configs[10] = { 0x400000fc, 0x400000fb, }; +static unsigned int ecs202_pin_configs[10] = { + 0x0221401f, 0x02a19020, 0x01a19020, 0x01114010, + 0x408000f0, 0x01813022, 0x074510a0, 0x40c400f1, + 0x9037012e, 0x40e000f2, +}; static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { [STAC_D945_REF] = ref922x_pin_configs, @@ -1604,6 +1610,7 @@ static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { [STAC_MACBOOK_PRO_V2] = intel_mac_v3_pin_configs, [STAC_IMAC_INTEL] = intel_mac_v2_pin_configs, [STAC_IMAC_INTEL_20] = intel_mac_v3_pin_configs, + [STAC_ECS_202] = ecs202_pin_configs, [STAC_922X_DELL_D81] = dell_922x_d81_pin_configs, [STAC_922X_DELL_D82] = dell_922x_d82_pin_configs, [STAC_922X_DELL_M81] = dell_922x_m81_pin_configs, @@ -1627,6 +1634,7 @@ static const char *stac922x_models[STAC_922X_MODELS] = { [STAC_MACBOOK_PRO_V2] = "macbook-pro", [STAC_IMAC_INTEL] = "imac-intel", [STAC_IMAC_INTEL_20] = "imac-intel-20", + [STAC_ECS_202] = "ecs202", [STAC_922X_DELL_D81] = "dell-d81", [STAC_922X_DELL_D82] = "dell-d82", [STAC_922X_DELL_M81] = "dell-m81", @@ -1713,6 +1721,33 @@ static struct snd_pci_quirk stac922x_cfg_tbl[] = { "unknown Dell", STAC_922X_DELL_D81), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d7, "Dell XPS M1210", STAC_922X_DELL_M82), + /* ECS/PC Chips boards */ + SND_PCI_QUIRK(0x1019, 0x2144, + "ECS/PC chips", STAC_ECS_202), + SND_PCI_QUIRK(0x1019, 0x2608, + "ECS/PC chips", STAC_ECS_202), + SND_PCI_QUIRK(0x1019, 0x2633, + "ECS/PC chips P17G/1333", STAC_ECS_202), + SND_PCI_QUIRK(0x1019, 0x2811, + "ECS/PC chips", STAC_ECS_202), + SND_PCI_QUIRK(0x1019, 0x2812, + "ECS/PC chips", STAC_ECS_202), + SND_PCI_QUIRK(0x1019, 0x2813, + "ECS/PC chips", STAC_ECS_202), + SND_PCI_QUIRK(0x1019, 0x2814, + "ECS/PC chips", STAC_ECS_202), + SND_PCI_QUIRK(0x1019, 0x2815, + "ECS/PC chips", STAC_ECS_202), + SND_PCI_QUIRK(0x1019, 0x2816, + "ECS/PC chips", STAC_ECS_202), + SND_PCI_QUIRK(0x1019, 0x2817, + "ECS/PC chips", STAC_ECS_202), + SND_PCI_QUIRK(0x1019, 0x2818, + "ECS/PC chips", STAC_ECS_202), + SND_PCI_QUIRK(0x1019, 0x2819, + "ECS/PC chips", STAC_ECS_202), + SND_PCI_QUIRK(0x1019, 0x2820, + "ECS/PC chips", STAC_ECS_202), {} /* terminator */ }; -- cgit v1.2.3 From 8f4f4ef6fed55a3636db3146a3e50b7febcbd7de Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Tue, 5 Aug 2008 15:45:45 +0200 Subject: ALSA: ac97 - Enable mono-out on ALC203 codec as default Use pin 37 for mono-out as default on ALC203. Reported-by: george pee Tested-by: george pee Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/ac97/ac97_codec.c | 2 +- sound/pci/ac97/ac97_patch.c | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index f6a7d721649..171559c19b3 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c @@ -122,7 +122,7 @@ static const struct ac97_codec_id snd_ac97_codec_ids[] = { { 0x414c4740, 0xfffffff0, "ALC202", NULL, NULL }, { 0x414c4750, 0xfffffff0, "ALC250", NULL, NULL }, { 0x414c4760, 0xfffffff0, "ALC655", patch_alc655, NULL }, -{ 0x414c4770, 0xfffffff0, "ALC203", NULL, NULL }, +{ 0x414c4770, 0xfffffff0, "ALC203", patch_alc203, NULL }, { 0x414c4781, 0xffffffff, "ALC658D", NULL, NULL }, /* already patched */ { 0x414c4780, 0xfffffff0, "ALC658", patch_alc655, NULL }, { 0x414c4790, 0xfffffff0, "ALC850", patch_alc850, NULL }, diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index f4fbc795ee8..bb028f8f9a2 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c @@ -2560,6 +2560,14 @@ static int patch_ad1986(struct snd_ac97 * ac97) return 0; } +/* + * realtek ALC203: use mono-out for pin 37 + */ +static int patch_alc203(struct snd_ac97 *ac97) +{ + snd_ac97_update_bits(ac97, 0x7a, 0x400, 0x400); + return 0; +} /* * realtek ALC65x/850 codecs -- cgit v1.2.3 From c534cc849097b84aae70c349770d982e20d0b16a Mon Sep 17 00:00:00 2001 From: roel kluin Date: Thu, 7 Aug 2008 15:56:22 -0400 Subject: ALSA: au88x0: clipping ceiling loop wrong in comment As is the clipping ceiling loop appears wrong anyways Signed-off-by: Roel Kluin Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/au88x0/au88x0_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c index 333c62de862..1900fa6bc51 100644 --- a/sound/pci/au88x0/au88x0_core.c +++ b/sound/pci/au88x0/au88x0_core.c @@ -427,7 +427,7 @@ static void vortex_mixer_init(vortex_t * vortex) /* Set clipping ceiling (this may be all wrong). */ /* - for (x = 0; x > 0x80; x++) { + for (x = 0; x < 0x80; x++) { hwwrite(vortex->mmio, VORTEX_MIXER_CLIP + (x << 2), 0x3ffff); } */ -- cgit v1.2.3 From da3cec35dd3c31d8706db4bf379372ce70d92118 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 8 Aug 2008 17:12:14 +0200 Subject: ALSA: Kill snd_assert() in sound/pci/* Kill snd_assert() in sound/pci/*, either removed or replaced with if () with snd_BUG_ON(). Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/ac97/ac97_codec.c | 19 +++--- sound/pci/ad1889.c | 6 +- sound/pci/ak4531_codec.c | 10 +-- sound/pci/atiixp.c | 10 ++- sound/pci/atiixp_modem.c | 10 ++- sound/pci/azt3328.c | 6 +- sound/pci/ca0106/ca_midi.c | 20 ++++-- sound/pci/cmipci.c | 9 ++- sound/pci/cs4281.c | 13 ++-- sound/pci/cs46xx/cs46xx_lib.c | 72 +++++++++++++--------- sound/pci/cs46xx/dsp_spos.c | 51 ++++++++++------ sound/pci/cs46xx/dsp_spos_scb_lib.c | 115 +++++++++++++++++++++-------------- sound/pci/echoaudio/darla20_dsp.c | 3 +- sound/pci/echoaudio/darla24_dsp.c | 8 ++- sound/pci/echoaudio/echo3g_dsp.c | 9 ++- sound/pci/echoaudio/echoaudio.c | 8 ++- sound/pci/echoaudio/echoaudio_3g.c | 11 ++-- sound/pci/echoaudio/echoaudio_dsp.c | 21 ++++--- sound/pci/echoaudio/echoaudio_gml.c | 6 +- sound/pci/echoaudio/gina20_dsp.c | 6 +- sound/pci/echoaudio/gina24_dsp.c | 11 ++-- sound/pci/echoaudio/indigo_dsp.c | 8 ++- sound/pci/echoaudio/indigodj_dsp.c | 8 ++- sound/pci/echoaudio/indigoio_dsp.c | 8 ++- sound/pci/echoaudio/layla20_dsp.c | 9 ++- sound/pci/echoaudio/layla24_dsp.c | 11 ++-- sound/pci/echoaudio/mia_dsp.c | 13 ++-- sound/pci/echoaudio/midi.c | 6 +- sound/pci/echoaudio/mona_dsp.c | 6 +- sound/pci/emu10k1/emu10k1_callback.c | 6 +- sound/pci/emu10k1/emu10k1_patch.c | 23 ++++--- sound/pci/emu10k1/emu10k1x.c | 18 ++++-- sound/pci/emu10k1/emufx.c | 6 +- sound/pci/emu10k1/emumpu401.c | 18 ++++-- sound/pci/emu10k1/memory.c | 19 ++++-- sound/pci/emu10k1/voice.c | 9 ++- sound/pci/es1938.c | 3 +- sound/pci/es1968.c | 6 +- sound/pci/hda/hda_codec.c | 21 ++++--- sound/pci/hda/hda_generic.c | 3 +- sound/pci/hda/hda_intel.c | 3 +- sound/pci/hda/patch_realtek.c | 6 +- sound/pci/ice1712/ak4xxx.c | 3 +- sound/pci/ice1712/ews.c | 9 ++- sound/pci/ice1712/ice1712.c | 3 +- sound/pci/ice1712/ice1724.c | 3 +- sound/pci/ice1712/juli.c | 3 +- sound/pci/intel8x0.c | 4 +- sound/pci/intel8x0m.c | 3 +- sound/pci/korg1212/korg1212.c | 9 ++- sound/pci/maestro3.c | 10 ++- sound/pci/mixart/mixart.c | 4 +- sound/pci/mixart/mixart_core.c | 18 ++++-- sound/pci/mixart/mixart_hwdep.c | 19 ++++-- sound/pci/mixart/mixart_mixer.c | 8 +-- sound/pci/nm256/nm256.c | 15 +++-- sound/pci/pcxhr/pcxhr.c | 6 +- sound/pci/pcxhr/pcxhr_core.c | 27 +++++--- sound/pci/pcxhr/pcxhr_hwdep.c | 15 +++-- sound/pci/riptide/riptide.c | 18 ++++-- sound/pci/rme9652/hdsp.c | 25 +++++--- sound/pci/rme9652/hdspm.c | 34 ++++++----- sound/pci/rme9652/rme9652.c | 23 ++++--- sound/pci/sonicvibes.c | 10 +-- sound/pci/trident/trident_main.c | 22 ++++--- sound/pci/trident/trident_memory.c | 24 +++++--- sound/pci/via82xx.c | 8 ++- sound/pci/via82xx_modem.c | 3 +- sound/pci/vx222/vx222_ops.c | 12 ++-- sound/pci/ymfpci/ymfpci_main.c | 21 ++++--- 70 files changed, 632 insertions(+), 361 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index 171559c19b3..d0023e99bdf 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c @@ -1890,8 +1890,8 @@ int snd_ac97_bus(struct snd_card *card, int num, struct snd_ac97_bus_ops *ops, .dev_free = snd_ac97_bus_dev_free, }; - snd_assert(card != NULL, return -EINVAL); - snd_assert(rbus != NULL, return -EINVAL); + if (snd_BUG_ON(!card)) + return -EINVAL; bus = kzalloc(sizeof(*bus), GFP_KERNEL); if (bus == NULL) return -ENOMEM; @@ -1906,7 +1906,8 @@ int snd_ac97_bus(struct snd_card *card, int num, struct snd_ac97_bus_ops *ops, snd_ac97_bus_free(bus); return err; } - *rbus = bus; + if (rbus) + *rbus = bus; return 0; } @@ -1991,10 +1992,14 @@ int snd_ac97_mixer(struct snd_ac97_bus *bus, struct snd_ac97_template *template, .dev_disconnect = snd_ac97_dev_disconnect, }; - snd_assert(rac97 != NULL, return -EINVAL); - *rac97 = NULL; - snd_assert(bus != NULL && template != NULL, return -EINVAL); - snd_assert(template->num < 4 && bus->codec[template->num] == NULL, return -EINVAL); + if (rac97) + *rac97 = NULL; + if (snd_BUG_ON(!bus || !template)) + return -EINVAL; + if (snd_BUG_ON(template->num >= 4)) + return -EINVAL; + if (bus->codec[template->num]) + return -EBUSY; card = bus->card; ac97 = kzalloc(sizeof(*ac97), GFP_KERNEL); diff --git a/sound/pci/ad1889.c b/sound/pci/ad1889.c index 39ec55b57b1..92f3a976ef2 100644 --- a/sound/pci/ad1889.c +++ b/sound/pci/ad1889.c @@ -549,7 +549,8 @@ snd_ad1889_playback_pointer(struct snd_pcm_substream *ss) ptr = ad1889_readl(chip, AD_DMA_WAVCA); ptr -= chip->wave.addr; - snd_assert((ptr >= 0) && (ptr < chip->wave.size), return 0); + if (snd_BUG_ON(ptr >= chip->wave.size)) + return 0; return bytes_to_frames(ss->runtime, ptr); } @@ -567,7 +568,8 @@ snd_ad1889_capture_pointer(struct snd_pcm_substream *ss) ptr = ad1889_readl(chip, AD_DMA_ADCCA); ptr -= chip->ramc.addr; - snd_assert((ptr >= 0) && (ptr < chip->ramc.size), return 0); + if (snd_BUG_ON(ptr >= chip->ramc.size)) + return 0; return bytes_to_frames(ss->runtime, ptr); } diff --git a/sound/pci/ak4531_codec.c b/sound/pci/ak4531_codec.c index 33d37b1c42f..0f819ddb3eb 100644 --- a/sound/pci/ak4531_codec.c +++ b/sound/pci/ak4531_codec.c @@ -392,9 +392,10 @@ int __devinit snd_ak4531_mixer(struct snd_card *card, .dev_free = snd_ak4531_dev_free, }; - snd_assert(rak4531 != NULL, return -EINVAL); - *rak4531 = NULL; - snd_assert(card != NULL && _ak4531 != NULL, return -EINVAL); + if (snd_BUG_ON(!card || !_ak4531)) + return -EINVAL; + if (rak4531) + *rak4531 = NULL; ak4531 = kzalloc(sizeof(*ak4531), GFP_KERNEL); if (ak4531 == NULL) return -ENOMEM; @@ -428,7 +429,8 @@ int __devinit snd_ak4531_mixer(struct snd_card *card, #if 0 snd_ak4531_dump(ak4531); #endif - *rak4531 = ak4531; + if (rak4531) + *rak4531 = ak4531; return 0; } diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c index 457228fb22a..ce1eb12768f 100644 --- a/sound/pci/atiixp.c +++ b/sound/pci/atiixp.c @@ -722,7 +722,9 @@ static int snd_atiixp_pcm_trigger(struct snd_pcm_substream *substream, int cmd) struct atiixp_dma *dma = substream->runtime->private_data; int err = 0; - snd_assert(dma->ops->enable_transfer && dma->ops->flush_dma, return -EINVAL); + if (snd_BUG_ON(!dma->ops->enable_transfer || + !dma->ops->flush_dma)) + return -EINVAL; spin_lock(&chip->reg_lock); switch (cmd) { @@ -1032,7 +1034,8 @@ static int snd_atiixp_pcm_open(struct snd_pcm_substream *substream, struct snd_pcm_runtime *runtime = substream->runtime; int err; - snd_assert(dma->ops && dma->ops->enable_dma, return -EINVAL); + if (snd_BUG_ON(!dma->ops || !dma->ops->enable_dma)) + return -EINVAL; if (dma->opened) return -EBUSY; @@ -1064,7 +1067,8 @@ static int snd_atiixp_pcm_close(struct snd_pcm_substream *substream, { struct atiixp *chip = snd_pcm_substream_chip(substream); /* disable DMA bits */ - snd_assert(dma->ops && dma->ops->enable_dma, return -EINVAL); + if (snd_BUG_ON(!dma->ops || !dma->ops->enable_dma)) + return -EINVAL; spin_lock_irq(&chip->reg_lock); dma->ops->enable_dma(chip, 0); spin_unlock_irq(&chip->reg_lock); diff --git a/sound/pci/atiixp_modem.c b/sound/pci/atiixp_modem.c index d457a32a793..2f106306c7f 100644 --- a/sound/pci/atiixp_modem.c +++ b/sound/pci/atiixp_modem.c @@ -674,7 +674,9 @@ static int snd_atiixp_pcm_trigger(struct snd_pcm_substream *substream, int cmd) struct atiixp_dma *dma = substream->runtime->private_data; int err = 0; - snd_assert(dma->ops->enable_transfer && dma->ops->flush_dma, return -EINVAL); + if (snd_BUG_ON(!dma->ops->enable_transfer || + !dma->ops->flush_dma)) + return -EINVAL; spin_lock(&chip->reg_lock); switch(cmd) { @@ -865,7 +867,8 @@ static int snd_atiixp_pcm_open(struct snd_pcm_substream *substream, .mask = 0, }; - snd_assert(dma->ops && dma->ops->enable_dma, return -EINVAL); + if (snd_BUG_ON(!dma->ops || !dma->ops->enable_dma)) + return -EINVAL; if (dma->opened) return -EBUSY; @@ -895,7 +898,8 @@ static int snd_atiixp_pcm_close(struct snd_pcm_substream *substream, { struct atiixp_modem *chip = snd_pcm_substream_chip(substream); /* disable DMA bits */ - snd_assert(dma->ops && dma->ops->enable_dma, return -EINVAL); + if (snd_BUG_ON(!dma->ops || !dma->ops->enable_dma)) + return -EINVAL; spin_lock_irq(&chip->reg_lock); dma->ops->enable_dma(chip, 0); spin_unlock_irq(&chip->reg_lock); diff --git a/sound/pci/azt3328.c b/sound/pci/azt3328.c index 22f18f3cfbc..333007c523a 100644 --- a/sound/pci/azt3328.c +++ b/sound/pci/azt3328.c @@ -816,7 +816,8 @@ snd_azf3328_mixer_new(struct snd_azf3328 *chip) int err; snd_azf3328_dbgcallenter(); - snd_assert(chip != NULL && chip->card != NULL, return -EINVAL); + if (snd_BUG_ON(!chip || !chip->card)) + return -EINVAL; card = chip->card; @@ -1471,7 +1472,8 @@ snd_azf3328_gameport_cooked_read(struct gameport *gameport, u8 val; unsigned long flags; - snd_assert(chip, return 0); + if (snd_BUG_ON(!chip)) + return 0; spin_lock_irqsave(&chip->reg_lock, flags); val = snd_azf3328_game_inb(chip, IDX_GAME_LEGACY_COMPATIBLE); diff --git a/sound/pci/ca0106/ca_midi.c b/sound/pci/ca0106/ca_midi.c index 893ee4f1ea7..c7885117da3 100644 --- a/sound/pci/ca0106/ca_midi.c +++ b/sound/pci/ca0106/ca_midi.c @@ -125,7 +125,8 @@ static int ca_midi_input_open(struct snd_rawmidi_substream *substream) struct snd_ca_midi *midi = substream->rmidi->private_data; unsigned long flags; - snd_assert(midi->dev_id, return -ENXIO); + if (snd_BUG_ON(!midi->dev_id)) + return -ENXIO; spin_lock_irqsave(&midi->open_lock, flags); midi->midi_mode |= CA_MIDI_MODE_INPUT; midi->substream_input = substream; @@ -144,7 +145,8 @@ static int ca_midi_output_open(struct snd_rawmidi_substream *substream) struct snd_ca_midi *midi = substream->rmidi->private_data; unsigned long flags; - snd_assert(midi->dev_id, return -ENXIO); + if (snd_BUG_ON(!midi->dev_id)) + return -ENXIO; spin_lock_irqsave(&midi->open_lock, flags); midi->midi_mode |= CA_MIDI_MODE_OUTPUT; midi->substream_output = substream; @@ -163,7 +165,8 @@ static int ca_midi_input_close(struct snd_rawmidi_substream *substream) struct snd_ca_midi *midi = substream->rmidi->private_data; unsigned long flags; - snd_assert(midi->dev_id, return -ENXIO); + if (snd_BUG_ON(!midi->dev_id)) + return -ENXIO; spin_lock_irqsave(&midi->open_lock, flags); midi->interrupt_disable(midi,midi->rx_enable); midi->midi_mode &= ~CA_MIDI_MODE_INPUT; @@ -181,7 +184,9 @@ static int ca_midi_output_close(struct snd_rawmidi_substream *substream) { struct snd_ca_midi *midi = substream->rmidi->private_data; unsigned long flags; - snd_assert(midi->dev_id, return -ENXIO); + + if (snd_BUG_ON(!midi->dev_id)) + return -ENXIO; spin_lock_irqsave(&midi->open_lock, flags); @@ -201,7 +206,9 @@ static int ca_midi_output_close(struct snd_rawmidi_substream *substream) static void ca_midi_input_trigger(struct snd_rawmidi_substream *substream, int up) { struct snd_ca_midi *midi = substream->rmidi->private_data; - snd_assert(midi->dev_id, return); + + if (snd_BUG_ON(!midi->dev_id)) + return; if (up) { midi->interrupt_enable(midi,midi->rx_enable); @@ -215,7 +222,8 @@ static void ca_midi_output_trigger(struct snd_rawmidi_substream *substream, int struct snd_ca_midi *midi = substream->rmidi->private_data; unsigned long flags; - snd_assert(midi->dev_id, return); + if (snd_BUG_ON(!midi->dev_id)) + return; if (up) { int max = 4; diff --git a/sound/pci/cmipci.c b/sound/pci/cmipci.c index 9971b5b7735..1a74ca62c31 100644 --- a/sound/pci/cmipci.c +++ b/sound/pci/cmipci.c @@ -2357,7 +2357,8 @@ static int snd_cmipci_uswitch_get(struct snd_kcontrol *kcontrol, { struct cmipci_switch_args *args; args = (struct cmipci_switch_args *)kcontrol->private_value; - snd_assert(args != NULL, return -EINVAL); + if (snd_BUG_ON(!args)) + return -EINVAL; return _snd_cmipci_uswitch_get(kcontrol, ucontrol, args); } @@ -2401,7 +2402,8 @@ static int snd_cmipci_uswitch_put(struct snd_kcontrol *kcontrol, { struct cmipci_switch_args *args; args = (struct cmipci_switch_args *)kcontrol->private_value; - snd_assert(args != NULL, return -EINVAL); + if (snd_BUG_ON(!args)) + return -EINVAL; return _snd_cmipci_uswitch_put(kcontrol, ucontrol, args); } @@ -2662,7 +2664,8 @@ static int __devinit snd_cmipci_mixer_new(struct cmipci *cm, int pcm_spdif_devic unsigned int idx; int err; - snd_assert(cm != NULL && cm->card != NULL, return -EINVAL); + if (snd_BUG_ON(!cm || !cm->card)) + return -EINVAL; card = cm->card; diff --git a/sound/pci/cs4281.c b/sound/pci/cs4281.c index 7556fd90d0e..ef9308f7c45 100644 --- a/sound/pci/cs4281.c +++ b/sound/pci/cs4281.c @@ -766,13 +766,13 @@ static void snd_cs4281_mode(struct cs4281 *chip, struct cs4281_dma *dma, if (!capture) { if (dma->left_slot == chip->src_left_play_slot) { unsigned int val = snd_cs4281_rate(runtime->rate, NULL); - snd_assert(dma->right_slot == chip->src_right_play_slot, ); + snd_BUG_ON(dma->right_slot != chip->src_right_play_slot); snd_cs4281_pokeBA0(chip, BA0_DACSR, val); } } else { if (dma->left_slot == chip->src_left_rec_slot) { unsigned int val = snd_cs4281_rate(runtime->rate, NULL); - snd_assert(dma->right_slot == chip->src_right_rec_slot, ); + snd_BUG_ON(dma->right_slot != chip->src_right_rec_slot); snd_cs4281_pokeBA0(chip, BA0_ADCSR, val); } } @@ -1209,7 +1209,8 @@ static void snd_cs4281_gameport_trigger(struct gameport *gameport) { struct cs4281 *chip = gameport_get_port_data(gameport); - snd_assert(chip, return); + if (snd_BUG_ON(!chip)) + return; snd_cs4281_pokeBA0(chip, BA0_JSPT, 0xff); } @@ -1217,7 +1218,8 @@ static unsigned char snd_cs4281_gameport_read(struct gameport *gameport) { struct cs4281 *chip = gameport_get_port_data(gameport); - snd_assert(chip, return 0); + if (snd_BUG_ON(!chip)) + return 0; return snd_cs4281_peekBA0(chip, BA0_JSPT); } @@ -1228,7 +1230,8 @@ static int snd_cs4281_gameport_cooked_read(struct gameport *gameport, struct cs4281 *chip = gameport_get_port_data(gameport); unsigned js1, js2, jst; - snd_assert(chip, return 0); + if (snd_BUG_ON(!chip)) + return 0; js1 = snd_cs4281_peekBA0(chip, BA0_JSC1); js2 = snd_cs4281_peekBA0(chip, BA0_JSC2); diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c index e214e567dec..a10ab8283f9 100644 --- a/sound/pci/cs46xx/cs46xx_lib.c +++ b/sound/pci/cs46xx/cs46xx_lib.c @@ -90,9 +90,10 @@ static unsigned short snd_cs46xx_codec_read(struct snd_cs46xx *chip, int count; unsigned short result,tmp; u32 offset = 0; - snd_assert ( (codec_index == CS46XX_PRIMARY_CODEC_INDEX) || - (codec_index == CS46XX_SECONDARY_CODEC_INDEX), - return -EINVAL); + + if (snd_BUG_ON(codec_index != CS46XX_PRIMARY_CODEC_INDEX && + codec_index != CS46XX_SECONDARY_CODEC_INDEX)) + return -EINVAL; chip->active_ctrl(chip, 1); @@ -212,9 +213,9 @@ static unsigned short snd_cs46xx_ac97_read(struct snd_ac97 * ac97, unsigned short val; int codec_index = ac97->num; - snd_assert(codec_index == CS46XX_PRIMARY_CODEC_INDEX || - codec_index == CS46XX_SECONDARY_CODEC_INDEX, - return 0xffff); + if (snd_BUG_ON(codec_index != CS46XX_PRIMARY_CODEC_INDEX && + codec_index != CS46XX_SECONDARY_CODEC_INDEX)) + return 0xffff; val = snd_cs46xx_codec_read(chip, reg, codec_index); @@ -229,9 +230,9 @@ static void snd_cs46xx_codec_write(struct snd_cs46xx *chip, { int count; - snd_assert ((codec_index == CS46XX_PRIMARY_CODEC_INDEX) || - (codec_index == CS46XX_SECONDARY_CODEC_INDEX), - return); + if (snd_BUG_ON(codec_index != CS46XX_PRIMARY_CODEC_INDEX && + codec_index != CS46XX_SECONDARY_CODEC_INDEX)) + return; chip->active_ctrl(chip, 1); @@ -294,9 +295,9 @@ static void snd_cs46xx_ac97_write(struct snd_ac97 *ac97, struct snd_cs46xx *chip = ac97->private_data; int codec_index = ac97->num; - snd_assert(codec_index == CS46XX_PRIMARY_CODEC_INDEX || - codec_index == CS46XX_SECONDARY_CODEC_INDEX, - return); + if (snd_BUG_ON(codec_index != CS46XX_PRIMARY_CODEC_INDEX && + codec_index != CS46XX_SECONDARY_CODEC_INDEX)) + return; snd_cs46xx_codec_write(chip, reg, val, codec_index); } @@ -315,7 +316,8 @@ int snd_cs46xx_download(struct snd_cs46xx *chip, unsigned int bank = offset >> 16; offset = offset & 0xffff; - snd_assert(!(offset & 3) && !(len & 3), return -EINVAL); + if (snd_BUG_ON((offset & 3) || (len & 3))) + return -EINVAL; dst = chip->region.idx[bank+1].remap_addr + offset; len /= sizeof(u32); @@ -343,7 +345,8 @@ int snd_cs46xx_clear_BA1(struct snd_cs46xx *chip, unsigned int bank = offset >> 16; offset = offset & 0xffff; - snd_assert(!(offset & 3) && !(len & 3), return -EINVAL); + if (snd_BUG_ON((offset & 3) || (len & 3))) + return -EINVAL; dst = chip->region.idx[bank+1].remap_addr + offset; len /= sizeof(u32); @@ -722,7 +725,9 @@ static snd_pcm_uframes_t snd_cs46xx_playback_direct_pointer(struct snd_pcm_subst struct snd_cs46xx *chip = snd_pcm_substream_chip(substream); size_t ptr; struct snd_cs46xx_pcm *cpcm = substream->runtime->private_data; - snd_assert (cpcm->pcm_channel,return -ENXIO); + + if (snd_BUG_ON(!cpcm->pcm_channel)) + return -ENXIO; #ifdef CONFIG_SND_CS46XX_NEW_DSP ptr = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 2) << 2); @@ -740,7 +745,8 @@ static snd_pcm_uframes_t snd_cs46xx_playback_indirect_pointer(struct snd_pcm_sub struct snd_cs46xx_pcm *cpcm = substream->runtime->private_data; #ifdef CONFIG_SND_CS46XX_NEW_DSP - snd_assert (cpcm->pcm_channel,return -ENXIO); + if (snd_BUG_ON(!cpcm->pcm_channel)) + return -ENXIO; ptr = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 2) << 2); #else ptr = snd_cs46xx_peek(chip, BA1_PBA); @@ -908,7 +914,8 @@ static int snd_cs46xx_playback_hw_params(struct snd_pcm_substream *substream, cpcm = runtime->private_data; #ifdef CONFIG_SND_CS46XX_NEW_DSP - snd_assert (sample_rate != 0, return -ENXIO); + if (snd_BUG_ON(!sample_rate)) + return -ENXIO; mutex_lock(&chip->spos_mutex); @@ -917,7 +924,7 @@ static int snd_cs46xx_playback_hw_params(struct snd_pcm_substream *substream, return -ENXIO; } - snd_assert (cpcm->pcm_channel != NULL); + snd_BUG_ON(!cpcm->pcm_channel); if (!cpcm->pcm_channel) { mutex_unlock(&chip->spos_mutex); return -ENXIO; @@ -952,7 +959,7 @@ static int snd_cs46xx_playback_hw_params(struct snd_pcm_substream *substream, } else if (cpcm->pcm_channel_id == DSP_IEC958_CHANNEL) { substream->ops = &snd_cs46xx_playback_iec958_ops; } else { - snd_assert(0); + snd_BUG(); } #else substream->ops = &snd_cs46xx_playback_ops; @@ -981,7 +988,7 @@ static int snd_cs46xx_playback_hw_params(struct snd_pcm_substream *substream, } else if (cpcm->pcm_channel_id == DSP_IEC958_CHANNEL) { substream->ops = &snd_cs46xx_playback_indirect_iec958_ops; } else { - snd_assert(0); + snd_BUG(); } #else substream->ops = &snd_cs46xx_playback_indirect_ops; @@ -1029,7 +1036,8 @@ static int snd_cs46xx_playback_prepare(struct snd_pcm_substream *substream) cpcm = runtime->private_data; #ifdef CONFIG_SND_CS46XX_NEW_DSP - snd_assert (cpcm->pcm_channel != NULL, return -ENXIO); + if (snd_BUG_ON(!cpcm->pcm_channel)) + return -ENXIO; pfie = snd_cs46xx_peek(chip, (cpcm->pcm_channel->pcm_reader_scb->address + 1) << 2 ); pfie &= ~0x0000f03f; @@ -1714,9 +1722,9 @@ static void snd_cs46xx_mixer_free_ac97(struct snd_ac97 *ac97) { struct snd_cs46xx *chip = ac97->private_data; - snd_assert ((ac97 == chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]) || - (ac97 == chip->ac97[CS46XX_SECONDARY_CODEC_INDEX]), - return); + if (snd_BUG_ON(ac97 != chip->ac97[CS46XX_PRIMARY_CODEC_INDEX] && + ac97 != chip->ac97[CS46XX_SECONDARY_CODEC_INDEX])) + return; if (ac97 == chip->ac97[CS46XX_PRIMARY_CODEC_INDEX]) { chip->ac97[CS46XX_PRIMARY_CODEC_INDEX] = NULL; @@ -1864,7 +1872,7 @@ static int snd_cs46xx_iec958_put(struct snd_kcontrol *kcontrol, break; default: res = -EINVAL; - snd_assert(0, (void)0); + snd_BUG(); /* should never happen ... */ } return res; @@ -2236,7 +2244,7 @@ static void snd_cs46xx_codec_reset (struct snd_ac97 * ac97) snd_printdd("cs46xx: CODOEC2 mode %04x\n",0x3); snd_cs46xx_ac97_write(ac97,AC97_CSR_ACMODE,0x3); } else { - snd_assert(0); /* should never happen ... */ + snd_BUG(); /* should never happen ... */ } udelay(50); @@ -2553,7 +2561,8 @@ static void snd_cs46xx_gameport_trigger(struct gameport *gameport) { struct snd_cs46xx *chip = gameport_get_port_data(gameport); - snd_assert(chip, return); + if (snd_BUG_ON(!chip)) + return; snd_cs46xx_pokeBA0(chip, BA0_JSPT, 0xFF); //outb(gameport->io, 0xFF); } @@ -2561,7 +2570,8 @@ static unsigned char snd_cs46xx_gameport_read(struct gameport *gameport) { struct snd_cs46xx *chip = gameport_get_port_data(gameport); - snd_assert(chip, return 0); + if (snd_BUG_ON(!chip)) + return 0; return snd_cs46xx_peekBA0(chip, BA0_JSPT); //inb(gameport->io); } @@ -2570,7 +2580,8 @@ static int snd_cs46xx_gameport_cooked_read(struct gameport *gameport, int *axes, struct snd_cs46xx *chip = gameport_get_port_data(gameport); unsigned js1, js2, jst; - snd_assert(chip, return 0); + if (snd_BUG_ON(!chip)) + return 0; js1 = snd_cs46xx_peekBA0(chip, BA0_JSC1); js2 = snd_cs46xx_peekBA0(chip, BA0_JSC2); @@ -2754,7 +2765,8 @@ static int snd_cs46xx_free(struct snd_cs46xx *chip) { int idx; - snd_assert(chip != NULL, return -EINVAL); + if (snd_BUG_ON(!chip)) + return -EINVAL; if (chip->active_ctrl) chip->active_ctrl(chip, 1); diff --git a/sound/pci/cs46xx/dsp_spos.c b/sound/pci/cs46xx/dsp_spos.c index ccc8bedb5b1..f4f0c8f5dad 100644 --- a/sound/pci/cs46xx/dsp_spos.c +++ b/sound/pci/cs46xx/dsp_spos.c @@ -63,7 +63,8 @@ static int shadow_and_reallocate_code (struct snd_cs46xx * chip, u32 * data, u32 u32 mop_operands,mop_type,wide_op; struct dsp_spos_instance * ins = chip->dsp_spos_instance; - snd_assert( ((size % 2) == 0), return -EINVAL); + if (snd_BUG_ON(size %2)) + return -EINVAL; while (i < size) { loval = data[i++]; @@ -289,7 +290,8 @@ void cs46xx_dsp_spos_destroy (struct snd_cs46xx * chip) int i; struct dsp_spos_instance * ins = chip->dsp_spos_instance; - snd_assert(ins != NULL, return); + if (snd_BUG_ON(!ins)) + return; mutex_lock(&chip->spos_mutex); for (i = 0; i < ins->nscb; ++i) { @@ -404,7 +406,8 @@ int cs46xx_dsp_load_module (struct snd_cs46xx * chip, struct dsp_module_desc * m /* if module has a code segment it must have symbol table */ - snd_assert(module->symbol_table.symbols != NULL ,return -ENOMEM); + if (snd_BUG_ON(!module->symbol_table.symbols)) + return -ENOMEM; if (add_symbols(chip,module)) { snd_printk(KERN_ERR "dsp_spos: failed to load symbol table\n"); return -ENOMEM; @@ -1369,7 +1372,8 @@ int cs46xx_dsp_scb_and_task_init (struct snd_cs46xx *chip) valid_slots = snd_cs46xx_peekBA0(chip, BA0_ACOSV); - snd_assert (chip->nr_ac97_codecs == 1 || chip->nr_ac97_codecs == 2); + if (snd_BUG_ON(chip->nr_ac97_codecs != 1 && chip->nr_ac97_codecs != 2)) + goto _fail_end; if (chip->nr_ac97_codecs == 1) { /* output on slot 5 and 11 @@ -1609,11 +1613,14 @@ static int cs46xx_dsp_async_init (struct snd_cs46xx *chip, spdifo_scb_desc = cs46xx_dsp_create_scb(chip,"SPDIFOSCB",(u32 *)&spdifo_scb,SPDIFO_SCB_INST); - snd_assert(spdifo_scb_desc, return -EIO); + if (snd_BUG_ON(!spdifo_scb_desc)) + return -EIO; spdifi_scb_desc = cs46xx_dsp_create_scb(chip,"SPDIFISCB",(u32 *)&spdifi_scb,SPDIFI_SCB_INST); - snd_assert(spdifi_scb_desc, return -EIO); + if (snd_BUG_ON(!spdifi_scb_desc)) + return -EIO; async_codec_scb_desc = cs46xx_dsp_create_scb(chip,"AsynCodecInputSCB",(u32 *)&async_codec_input_scb, HFG_TREE_SCB); - snd_assert(async_codec_scb_desc, return -EIO); + if (snd_BUG_ON(!async_codec_scb_desc)) + return -EIO; async_codec_scb_desc->parent_scb_ptr = NULL; async_codec_scb_desc->next_scb_ptr = spdifi_scb_desc; @@ -1698,8 +1705,10 @@ int cs46xx_dsp_enable_spdif_in (struct snd_cs46xx *chip) chip->active_ctrl(chip, 1); chip->amplifier_ctrl(chip, 1); - snd_assert (ins->asynch_rx_scb == NULL,return -EINVAL); - snd_assert (ins->spdif_in_src != NULL,return -EINVAL); + if (snd_BUG_ON(ins->asynch_rx_scb)) + return -EINVAL; + if (snd_BUG_ON(!ins->spdif_in_src)) + return -EINVAL; mutex_lock(&chip->spos_mutex); @@ -1754,8 +1763,10 @@ int cs46xx_dsp_disable_spdif_in (struct snd_cs46xx *chip) { struct dsp_spos_instance * ins = chip->dsp_spos_instance; - snd_assert (ins->asynch_rx_scb != NULL, return -EINVAL); - snd_assert (ins->spdif_in_src != NULL,return -EINVAL); + if (snd_BUG_ON(!ins->asynch_rx_scb)) + return -EINVAL; + if (snd_BUG_ON(!ins->spdif_in_src)) + return -EINVAL; mutex_lock(&chip->spos_mutex); @@ -1780,8 +1791,10 @@ int cs46xx_dsp_enable_pcm_capture (struct snd_cs46xx *chip) { struct dsp_spos_instance * ins = chip->dsp_spos_instance; - snd_assert (ins->pcm_input == NULL,return -EINVAL); - snd_assert (ins->ref_snoop_scb != NULL,return -EINVAL); + if (snd_BUG_ON(ins->pcm_input)) + return -EINVAL; + if (snd_BUG_ON(!ins->ref_snoop_scb)) + return -EINVAL; mutex_lock(&chip->spos_mutex); ins->pcm_input = cs46xx_add_record_source(chip,ins->ref_snoop_scb,PCMSERIALIN_PCM_SCB_ADDR, @@ -1795,7 +1808,8 @@ int cs46xx_dsp_disable_pcm_capture (struct snd_cs46xx *chip) { struct dsp_spos_instance * ins = chip->dsp_spos_instance; - snd_assert (ins->pcm_input != NULL,return -EINVAL); + if (snd_BUG_ON(!ins->pcm_input)) + return -EINVAL; mutex_lock(&chip->spos_mutex); cs46xx_dsp_remove_scb (chip,ins->pcm_input); @@ -1809,8 +1823,10 @@ int cs46xx_dsp_enable_adc_capture (struct snd_cs46xx *chip) { struct dsp_spos_instance * ins = chip->dsp_spos_instance; - snd_assert (ins->adc_input == NULL,return -EINVAL); - snd_assert (ins->codec_in_scb != NULL,return -EINVAL); + if (snd_BUG_ON(ins->adc_input)) + return -EINVAL; + if (snd_BUG_ON(!ins->codec_in_scb)) + return -EINVAL; mutex_lock(&chip->spos_mutex); ins->adc_input = cs46xx_add_record_source(chip,ins->codec_in_scb,PCMSERIALIN_SCB_ADDR, @@ -1824,7 +1840,8 @@ int cs46xx_dsp_disable_adc_capture (struct snd_cs46xx *chip) { struct dsp_spos_instance * ins = chip->dsp_spos_instance; - snd_assert (ins->adc_input != NULL,return -EINVAL); + if (snd_BUG_ON(!ins->adc_input)) + return -EINVAL; mutex_lock(&chip->spos_mutex); cs46xx_dsp_remove_scb (chip,ins->adc_input); diff --git a/sound/pci/cs46xx/dsp_spos_scb_lib.c b/sound/pci/cs46xx/dsp_spos_scb_lib.c index 2873cfe48c3..dd7c41b037b 100644 --- a/sound/pci/cs46xx/dsp_spos_scb_lib.c +++ b/sound/pci/cs46xx/dsp_spos_scb_lib.c @@ -46,8 +46,11 @@ static void remove_symbol (struct snd_cs46xx * chip, struct dsp_symbol_entry * s struct dsp_spos_instance * ins = chip->dsp_spos_instance; int symbol_index = (int)(symbol - ins->symbol_table.symbols); - snd_assert(ins->symbol_table.nsymbols > 0,return); - snd_assert(symbol_index >= 0 && symbol_index < ins->symbol_table.nsymbols, return); + if (snd_BUG_ON(ins->symbol_table.nsymbols <= 0)) + return; + if (snd_BUG_ON(symbol_index < 0 || + symbol_index >= ins->symbol_table.nsymbols)) + return; ins->symbol_table.symbols[symbol_index].deleted = 1; @@ -116,8 +119,9 @@ static void _dsp_unlink_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor if ( scb->parent_scb_ptr ) { /* unlink parent SCB */ - snd_assert ((scb->parent_scb_ptr->sub_list_ptr == scb || - scb->parent_scb_ptr->next_scb_ptr == scb),return); + if (snd_BUG_ON(scb->parent_scb_ptr->sub_list_ptr != scb && + scb->parent_scb_ptr->next_scb_ptr != scb)) + return; if (scb->parent_scb_ptr->sub_list_ptr == scb) { @@ -140,7 +144,6 @@ static void _dsp_unlink_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor scb->next_scb_ptr = ins->the_null_scb; } } else { - /* snd_assert ( (scb->sub_list_ptr == ins->the_null_scb), return); */ scb->parent_scb_ptr->next_scb_ptr = scb->next_scb_ptr; if (scb->next_scb_ptr != ins->the_null_scb) { @@ -181,16 +184,17 @@ void cs46xx_dsp_remove_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor * unsigned long flags; /* check integrety */ - snd_assert ( (scb->index >= 0 && - scb->index < ins->nscb && - (ins->scbs + scb->index) == scb), return ); + if (snd_BUG_ON(scb->index < 0 || + scb->index >= ins->nscb || + (ins->scbs + scb->index) != scb)) + return; #if 0 /* can't remove a SCB with childs before removing childs first */ - snd_assert ( (scb->sub_list_ptr == ins->the_null_scb && - scb->next_scb_ptr == ins->the_null_scb), - goto _end); + if (snd_BUG_ON(scb->sub_list_ptr != ins->the_null_scb || + scb->next_scb_ptr != ins->the_null_scb)) + goto _end; #endif spin_lock_irqsave(&scb->lock, flags); @@ -198,7 +202,8 @@ void cs46xx_dsp_remove_scb (struct snd_cs46xx *chip, struct dsp_scb_descriptor * spin_unlock_irqrestore(&scb->lock, flags); cs46xx_dsp_proc_free_scb_desc(scb); - snd_assert (scb->scb_symbol != NULL, return ); + if (snd_BUG_ON(!scb->scb_symbol)) + return; remove_symbol (chip,scb->scb_symbol); ins->scbs[scb->index].deleted = 1; @@ -234,7 +239,6 @@ void cs46xx_dsp_proc_free_scb_desc (struct dsp_scb_descriptor * scb) snd_info_free_entry(scb->proc_info); scb->proc_info = NULL; - snd_assert (scb_info != NULL, return); kfree (scb_info); } } @@ -291,7 +295,8 @@ _dsp_create_generic_scb (struct snd_cs46xx *chip, char * name, u32 * scb_data, u unsigned long flags; - snd_assert (ins->the_null_scb != NULL,return NULL); + if (snd_BUG_ON(!ins->the_null_scb)) + return NULL; /* fill the data that will be wroten to DSP */ scb_data[SCBsubListPtr] = @@ -321,18 +326,20 @@ _dsp_create_generic_scb (struct snd_cs46xx *chip, char * name, u32 * scb_data, u #endif /* link to parent SCB */ if (scb_child_type == SCB_ON_PARENT_NEXT_SCB) { - snd_assert ( (scb->parent_scb_ptr->next_scb_ptr == ins->the_null_scb), - return NULL); + if (snd_BUG_ON(scb->parent_scb_ptr->next_scb_ptr != + ins->the_null_scb)) + return NULL; scb->parent_scb_ptr->next_scb_ptr = scb; } else if (scb_child_type == SCB_ON_PARENT_SUBLIST_SCB) { - snd_assert ( (scb->parent_scb_ptr->sub_list_ptr == ins->the_null_scb), - return NULL); + if (snd_BUG_ON(scb->parent_scb_ptr->sub_list_ptr != + ins->the_null_scb)) + return NULL; scb->parent_scb_ptr->sub_list_ptr = scb; } else { - snd_assert (0,return NULL); + snd_BUG(); } spin_lock_irqsave(&chip->reg_lock, flags); @@ -675,7 +682,7 @@ cs46xx_dsp_create_src_task_scb(struct snd_cs46xx * chip, char * scb_name, if (pass_through) { /* wont work with any other rate than the native DSP rate */ - snd_assert (rate == 48000); + snd_BUG_ON(rate != 48000); scb = cs46xx_dsp_create_generic_scb(chip,scb_name,(u32 *)&src_task_scb, dest,"DMAREADER",parent_scb, @@ -1142,7 +1149,8 @@ find_next_free_scb (struct snd_cs46xx * chip, struct dsp_scb_descriptor * from) struct dsp_scb_descriptor * scb = from; while (scb->next_scb_ptr != ins->the_null_scb) { - snd_assert (scb->next_scb_ptr != NULL, return NULL); + if (snd_BUG_ON(!scb->next_scb_ptr)) + return NULL; scb = scb->next_scb_ptr; } @@ -1246,10 +1254,11 @@ cs46xx_dsp_create_pcm_channel (struct snd_cs46xx * chip, break; case DSP_PCM_S71_CHANNEL: /* TODO */ - snd_assert(0); + snd_BUG(); break; case DSP_IEC958_CHANNEL: - snd_assert (ins->asynch_tx_scb != NULL, return NULL); + if (snd_BUG_ON(!ins->asynch_tx_scb)) + return NULL; mixer_scb = ins->asynch_tx_scb; /* if sample rate is set to 48khz we pass @@ -1262,7 +1271,7 @@ cs46xx_dsp_create_pcm_channel (struct snd_cs46xx * chip, } break; default: - snd_assert (0); + snd_BUG(); return NULL; } /* default sample rate is 44100 */ @@ -1308,7 +1317,8 @@ cs46xx_dsp_create_pcm_channel (struct snd_cs46xx * chip, break; } } - snd_assert (src_index != -1,return NULL); + if (snd_BUG_ON(src_index == -1)) + return NULL; /* we need to create a new SRC SCB */ if (mixer_scb->sub_list_ptr == ins->the_null_scb) { @@ -1462,9 +1472,10 @@ void cs46xx_dsp_destroy_pcm_channel (struct snd_cs46xx * chip, struct dsp_spos_instance * ins = chip->dsp_spos_instance; unsigned long flags; - snd_assert(pcm_channel->active, return ); - snd_assert(ins->npcm_channels > 0, return ); - snd_assert(pcm_channel->src_scb->ref_count > 0, return ); + if (snd_BUG_ON(!pcm_channel->active || + ins->npcm_channels <= 0 || + pcm_channel->src_scb->ref_count <= 0)) + return; spin_lock_irqsave(&chip->reg_lock, flags); pcm_channel->unlinked = 1; @@ -1479,8 +1490,9 @@ void cs46xx_dsp_destroy_pcm_channel (struct snd_cs46xx * chip, if (!pcm_channel->src_scb->ref_count) { cs46xx_dsp_remove_scb(chip,pcm_channel->src_scb); - snd_assert (pcm_channel->src_slot >= 0 && pcm_channel->src_slot < DSP_MAX_SRC_NR, - return ); + if (snd_BUG_ON(pcm_channel->src_slot < 0 || + pcm_channel->src_slot >= DSP_MAX_SRC_NR)) + return; ins->src_scb_slots[pcm_channel->src_slot] = 0; ins->nsrc_scb --; @@ -1490,11 +1502,11 @@ void cs46xx_dsp_destroy_pcm_channel (struct snd_cs46xx * chip, int cs46xx_dsp_pcm_unlink (struct snd_cs46xx * chip, struct dsp_pcm_channel_descriptor * pcm_channel) { - struct dsp_spos_instance * ins = chip->dsp_spos_instance; unsigned long flags; - snd_assert(pcm_channel->active,return -EIO); - snd_assert(ins->npcm_channels > 0,return -EIO); + if (snd_BUG_ON(!pcm_channel->active || + chip->dsp_spos_instance->npcm_channels <= 0)) + return -EIO; spin_lock(&pcm_channel->src_scb->lock); @@ -1537,7 +1549,7 @@ int cs46xx_dsp_pcm_link (struct snd_cs46xx * chip, src_scb->sub_list_ptr = pcm_channel->pcm_reader_scb; - snd_assert (pcm_channel->pcm_reader_scb->parent_scb_ptr == NULL, ; ); + snd_BUG_ON(pcm_channel->pcm_reader_scb->parent_scb_ptr); pcm_channel->pcm_reader_scb->parent_scb_ptr = parent_scb; spin_lock_irqsave(&chip->reg_lock, flags); @@ -1564,7 +1576,8 @@ cs46xx_add_record_source (struct snd_cs46xx *chip, struct dsp_scb_descriptor * s struct dsp_scb_descriptor * pcm_input; int insert_point; - snd_assert (ins->record_mixer_scb != NULL,return NULL); + if (snd_BUG_ON(!ins->record_mixer_scb)) + return NULL; if (ins->record_mixer_scb->sub_list_ptr != ins->the_null_scb) { parent = find_next_free_scb (chip,ins->record_mixer_scb->sub_list_ptr); @@ -1583,7 +1596,8 @@ cs46xx_add_record_source (struct snd_cs46xx *chip, struct dsp_scb_descriptor * s int cs46xx_src_unlink(struct snd_cs46xx *chip, struct dsp_scb_descriptor * src) { - snd_assert (src->parent_scb_ptr != NULL, return -EINVAL ); + if (snd_BUG_ON(!src->parent_scb_ptr)) + return -EINVAL; /* mute SCB */ cs46xx_dsp_scb_set_volume (chip,src,0,0); @@ -1598,8 +1612,10 @@ int cs46xx_src_link(struct snd_cs46xx *chip, struct dsp_scb_descriptor * src) struct dsp_spos_instance * ins = chip->dsp_spos_instance; struct dsp_scb_descriptor * parent_scb; - snd_assert (src->parent_scb_ptr == NULL, return -EINVAL ); - snd_assert(ins->master_mix_scb !=NULL, return -EINVAL ); + if (snd_BUG_ON(src->parent_scb_ptr)) + return -EINVAL; + if (snd_BUG_ON(!ins->master_mix_scb)) + return -EINVAL; if (ins->master_mix_scb->sub_list_ptr != ins->the_null_scb) { parent_scb = find_next_free_scb (chip,ins->master_mix_scb->sub_list_ptr); @@ -1635,8 +1651,11 @@ int cs46xx_dsp_enable_spdif_out (struct snd_cs46xx *chip) return -EBUSY; } - snd_assert (ins->asynch_tx_scb == NULL, return -EINVAL); - snd_assert (ins->master_mix_scb->next_scb_ptr == ins->the_null_scb, return -EINVAL); + if (snd_BUG_ON(ins->asynch_tx_scb)) + return -EINVAL; + if (snd_BUG_ON(ins->master_mix_scb->next_scb_ptr != + ins->the_null_scb)) + return -EINVAL; /* reset output snooper sample buffer pointer */ snd_cs46xx_poke (chip, (ins->ref_snoop_scb->address + 2) << 2, @@ -1676,10 +1695,15 @@ int cs46xx_dsp_disable_spdif_out (struct snd_cs46xx *chip) } /* check integrety */ - snd_assert (ins->asynch_tx_scb != NULL, return -EINVAL); - snd_assert (ins->spdif_pcm_input_scb != NULL,return -EINVAL); - snd_assert (ins->master_mix_scb->next_scb_ptr == ins->asynch_tx_scb, return -EINVAL); - snd_assert (ins->asynch_tx_scb->parent_scb_ptr == ins->master_mix_scb, return -EINVAL); + if (snd_BUG_ON(!ins->asynch_tx_scb)) + return -EINVAL; + if (snd_BUG_ON(!ins->spdif_pcm_input_scb)) + return -EINVAL; + if (snd_BUG_ON(ins->master_mix_scb->next_scb_ptr != ins->asynch_tx_scb)) + return -EINVAL; + if (snd_BUG_ON(ins->asynch_tx_scb->parent_scb_ptr != + ins->master_mix_scb)) + return -EINVAL; cs46xx_dsp_remove_scb (chip,ins->spdif_pcm_input_scb); cs46xx_dsp_remove_scb (chip,ins->asynch_tx_scb); @@ -1734,7 +1758,8 @@ int cs46xx_iec958_post_close (struct snd_cs46xx *chip) { struct dsp_spos_instance * ins = chip->dsp_spos_instance; - snd_assert (ins->asynch_tx_scb != NULL, return -EINVAL); + if (snd_BUG_ON(!ins->asynch_tx_scb)) + return -EINVAL; ins->spdif_status_out &= ~DSP_SPDIF_STATUS_PLAYBACK_OPEN; diff --git a/sound/pci/echoaudio/darla20_dsp.c b/sound/pci/echoaudio/darla20_dsp.c index 4159e3bc186..29043301ebb 100644 --- a/sound/pci/echoaudio/darla20_dsp.c +++ b/sound/pci/echoaudio/darla20_dsp.c @@ -34,7 +34,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) int err; DE_INIT(("init_hw() - Darla20\n")); - snd_assert((subdevice_id & 0xfff0) == DARLA20, return -ENODEV); + if (snd_BUG_ON((subdevice_id & 0xfff0) != DARLA20)) + return -ENODEV; if ((err = init_dsp_comm_page(chip))) { DE_INIT(("init_hw - could not initialize DSP comm page\n")); diff --git a/sound/pci/echoaudio/darla24_dsp.c b/sound/pci/echoaudio/darla24_dsp.c index 79938eed7e9..60228731841 100644 --- a/sound/pci/echoaudio/darla24_dsp.c +++ b/sound/pci/echoaudio/darla24_dsp.c @@ -34,7 +34,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) int err; DE_INIT(("init_hw() - Darla24\n")); - snd_assert((subdevice_id & 0xfff0) == DARLA24, return -ENODEV); + if (snd_BUG_ON((subdevice_id & 0xfff0) != DARLA24)) + return -ENODEV; if ((err = init_dsp_comm_page(chip))) { DE_INIT(("init_hw - could not initialize DSP comm page\n")); @@ -148,8 +149,9 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate) static int set_input_clock(struct echoaudio *chip, u16 clock) { - snd_assert(clock == ECHO_CLOCK_INTERNAL || - clock == ECHO_CLOCK_ESYNC, return -EINVAL); + if (snd_BUG_ON(clock != ECHO_CLOCK_INTERNAL && + clock != ECHO_CLOCK_ESYNC)) + return -EINVAL; chip->input_clock = clock; return set_sample_rate(chip, chip->sample_rate); } diff --git a/sound/pci/echoaudio/echo3g_dsp.c b/sound/pci/echoaudio/echo3g_dsp.c index 48eb7c59911..417e25add82 100644 --- a/sound/pci/echoaudio/echo3g_dsp.c +++ b/sound/pci/echoaudio/echo3g_dsp.c @@ -47,7 +47,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) local_irq_enable(); DE_INIT(("init_hw() - Echo3G\n")); - snd_assert((subdevice_id & 0xfff0) == ECHO3G, return -ENODEV); + if (snd_BUG_ON((subdevice_id & 0xfff0) != ECHO3G)) + return -ENODEV; if ((err = init_dsp_comm_page(chip))) { DE_INIT(("init_hw - could not initialize DSP comm page\n")); @@ -104,9 +105,11 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) if ((err = init_line_levels(chip)) < 0) return err; err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA); - snd_assert(err >= 0, return err); + if (err < 0) + return err; err = set_phantom_power(chip, 0); - snd_assert(err >= 0, return err); + if (err < 0) + return err; err = set_professional_spdif(chip, TRUE); DE_INIT(("init_hw done\n")); diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c index e16dc92e82f..160d4705492 100644 --- a/sound/pci/echoaudio/echoaudio.c +++ b/sound/pci/echoaudio/echoaudio.c @@ -503,7 +503,7 @@ static int init_engine(struct snd_pcm_substream *substream, if (pipe->index >= 0) { DE_HWP(("hwp_ie free(%d)\n", pipe->index)); err = free_pipes(chip, pipe); - snd_assert(!err); + snd_BUG_ON(err); chip->substream[pipe->index] = NULL; } @@ -690,8 +690,10 @@ static int pcm_prepare(struct snd_pcm_substream *substream) return -EINVAL; } - snd_assert(pipe_index < px_num(chip), return -EINVAL); - snd_assert(is_pipe_allocated(chip, pipe_index), return -EINVAL); + if (snd_BUG_ON(pipe_index >= px_num(chip))) + return -EINVAL; + if (snd_BUG_ON(!is_pipe_allocated(chip, pipe_index))) + return -EINVAL; set_audio_format(chip, pipe_index, &format); return 0; } diff --git a/sound/pci/echoaudio/echoaudio_3g.c b/sound/pci/echoaudio/echoaudio_3g.c index 52a93318957..c3736bbd819 100644 --- a/sound/pci/echoaudio/echoaudio_3g.c +++ b/sound/pci/echoaudio/echoaudio_3g.c @@ -103,9 +103,11 @@ static int set_digital_mode(struct echoaudio *chip, u8 mode) int err, i, o; /* All audio channels must be closed before changing the digital mode */ - snd_assert(!chip->pipe_alloc_mask, return -EAGAIN); + if (snd_BUG_ON(chip->pipe_alloc_mask)) + return -EAGAIN; - snd_assert(chip->digital_modes & (1 << mode), return -EINVAL); + if (snd_BUG_ON(!(chip->digital_modes & (1 << mode)))) + return -EINVAL; previous_mode = chip->digital_mode; err = dsp_set_digital_mode(chip, mode); @@ -267,8 +269,9 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate) return 0; } - snd_assert(rate < 50000 || chip->digital_mode != DIGITAL_MODE_ADAT, - return -EINVAL); + if (snd_BUG_ON(rate >= 50000 && + chip->digital_mode == DIGITAL_MODE_ADAT)) + return -EINVAL; clock = 0; control_reg = le32_to_cpu(chip->comm_page->control_register); diff --git a/sound/pci/echoaudio/echoaudio_dsp.c b/sound/pci/echoaudio/echoaudio_dsp.c index e6c10077039..be0e18192de 100644 --- a/sound/pci/echoaudio/echoaudio_dsp.c +++ b/sound/pci/echoaudio/echoaudio_dsp.c @@ -474,7 +474,8 @@ static int load_firmware(struct echoaudio *chip) const struct firmware *fw; int box_type, err; - snd_assert(chip->dsp_code_to_load && chip->comm_page, return -EPERM); + if (snd_BUG_ON(!chip->dsp_code_to_load || !chip->comm_page)) + return -EPERM; /* See if the ASIC is present and working - only if the DSP is already loaded */ if (chip->dsp_code) { @@ -512,8 +513,8 @@ static int load_firmware(struct echoaudio *chip) /* Set the nominal level for an input or output bus (true = -10dBV, false = +4dBu) */ static int set_nominal_level(struct echoaudio *chip, u16 index, char consumer) { - snd_assert(index < num_busses_out(chip) + num_busses_in(chip), - return -EINVAL); + if (snd_BUG_ON(index >= num_busses_out(chip) + num_busses_in(chip))) + return -EINVAL; /* Wait for the handshake (OK even if ASIC is not loaded) */ if (wait_handshake(chip)) @@ -536,7 +537,8 @@ static int set_nominal_level(struct echoaudio *chip, u16 index, char consumer) /* Set the gain for a single physical output channel (dB). */ static int set_output_gain(struct echoaudio *chip, u16 channel, s8 gain) { - snd_assert(channel < num_busses_out(chip), return -EINVAL); + if (snd_BUG_ON(channel >= num_busses_out(chip))) + return -EINVAL; if (wait_handshake(chip)) return -EIO; @@ -554,8 +556,9 @@ static int set_output_gain(struct echoaudio *chip, u16 channel, s8 gain) static int set_monitor_gain(struct echoaudio *chip, u16 output, u16 input, s8 gain) { - snd_assert(output < num_busses_out(chip) && - input < num_busses_in(chip), return -EINVAL); + if (snd_BUG_ON(output >= num_busses_out(chip) || + input >= num_busses_in(chip))) + return -EINVAL; if (wait_handshake(chip)) return -EIO; @@ -1065,8 +1068,10 @@ static int free_pipes(struct echoaudio *chip, struct audiopipe *pipe) int i; DE_ACT(("free_pipes: Pipe %d\n", pipe->index)); - snd_assert(is_pipe_allocated(chip, pipe->index), return -EINVAL); - snd_assert(pipe->state == PIPE_STATE_STOPPED, return -EINVAL); + if (snd_BUG_ON(!is_pipe_allocated(chip, pipe->index))) + return -EINVAL; + if (snd_BUG_ON(pipe->state != PIPE_STATE_STOPPED)) + return -EINVAL; for (channel_mask = i = 0; i < pipe->interleave; i++) channel_mask |= 1 << (pipe->index + i); diff --git a/sound/pci/echoaudio/echoaudio_gml.c b/sound/pci/echoaudio/echoaudio_gml.c index 3aa37e76eba..afa273330e8 100644 --- a/sound/pci/echoaudio/echoaudio_gml.c +++ b/sound/pci/echoaudio/echoaudio_gml.c @@ -112,9 +112,11 @@ static int set_digital_mode(struct echoaudio *chip, u8 mode) return -EIO; /* All audio channels must be closed before changing the digital mode */ - snd_assert(!chip->pipe_alloc_mask, return -EAGAIN); + if (snd_BUG_ON(chip->pipe_alloc_mask)) + return -EAGAIN; - snd_assert(chip->digital_modes & (1 << mode), return -EINVAL); + if (snd_BUG_ON(!(chip->digital_modes & (1 << mode)))) + return -EINVAL; previous_mode = chip->digital_mode; err = dsp_set_digital_mode(chip, mode); diff --git a/sound/pci/echoaudio/gina20_dsp.c b/sound/pci/echoaudio/gina20_dsp.c index 2757c896084..db6c952e9d7 100644 --- a/sound/pci/echoaudio/gina20_dsp.c +++ b/sound/pci/echoaudio/gina20_dsp.c @@ -38,7 +38,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) int err; DE_INIT(("init_hw() - Gina20\n")); - snd_assert((subdevice_id & 0xfff0) == GINA20, return -ENODEV); + if (snd_BUG_ON((subdevice_id & 0xfff0) != GINA20)) + return -ENODEV; if ((err = init_dsp_comm_page(chip))) { DE_INIT(("init_hw - could not initialize DSP comm page\n")); @@ -177,7 +178,8 @@ static int set_input_clock(struct echoaudio *chip, u16 clock) /* Set input bus gain (one unit is 0.5dB !) */ static int set_input_gain(struct echoaudio *chip, u16 input, int gain) { - snd_assert(input < num_busses_in(chip), return -EINVAL); + if (snd_BUG_ON(input >= num_busses_in(chip))) + return -EINVAL; if (wait_handshake(chip)) return -EIO; diff --git a/sound/pci/echoaudio/gina24_dsp.c b/sound/pci/echoaudio/gina24_dsp.c index 144fc567bec..2fef37a2a5b 100644 --- a/sound/pci/echoaudio/gina24_dsp.c +++ b/sound/pci/echoaudio/gina24_dsp.c @@ -43,7 +43,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) int err; DE_INIT(("init_hw() - Gina24\n")); - snd_assert((subdevice_id & 0xfff0) == GINA24, return -ENODEV); + if (snd_BUG_ON((subdevice_id & 0xfff0) != GINA24)) + return -ENODEV; if ((err = init_dsp_comm_page(chip))) { DE_INIT(("init_hw - could not initialize DSP comm page\n")); @@ -84,7 +85,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) if ((err = init_line_levels(chip)) < 0) return err; err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA); - snd_assert(err >= 0, return err); + if (err < 0) + return err; err = set_professional_spdif(chip, TRUE); DE_INIT(("init_hw done\n")); @@ -163,8 +165,9 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate) { u32 control_reg, clock; - snd_assert(rate < 50000 || chip->digital_mode != DIGITAL_MODE_ADAT, - return -EINVAL); + if (snd_BUG_ON(rate >= 50000 && + chip->digital_mode == DIGITAL_MODE_ADAT)) + return -EINVAL; /* Only set the clock for internal mode. */ if (chip->input_clock != ECHO_CLOCK_INTERNAL) { diff --git a/sound/pci/echoaudio/indigo_dsp.c b/sound/pci/echoaudio/indigo_dsp.c index d6ac7734609..f05e39f7aad 100644 --- a/sound/pci/echoaudio/indigo_dsp.c +++ b/sound/pci/echoaudio/indigo_dsp.c @@ -39,7 +39,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) int err; DE_INIT(("init_hw() - Indigo\n")); - snd_assert((subdevice_id & 0xfff0) == INDIGO, return -ENODEV); + if (snd_BUG_ON((subdevice_id & 0xfff0) != INDIGO)) + return -ENODEV; if ((err = init_dsp_comm_page(chip))) { DE_INIT(("init_hw - could not initialize DSP comm page\n")); @@ -143,8 +144,9 @@ static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, { int index; - snd_assert(pipe < num_pipes_out(chip) && - output < num_busses_out(chip), return -EINVAL); + if (snd_BUG_ON(pipe >= num_pipes_out(chip) || + output >= num_busses_out(chip))) + return -EINVAL; if (wait_handshake(chip)) return -EIO; diff --git a/sound/pci/echoaudio/indigodj_dsp.c b/sound/pci/echoaudio/indigodj_dsp.c index 500e150b49f..90730a5ecb4 100644 --- a/sound/pci/echoaudio/indigodj_dsp.c +++ b/sound/pci/echoaudio/indigodj_dsp.c @@ -39,7 +39,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) int err; DE_INIT(("init_hw() - Indigo DJ\n")); - snd_assert((subdevice_id & 0xfff0) == INDIGO_DJ, return -ENODEV); + if (snd_BUG_ON((subdevice_id & 0xfff0) != INDIGO_DJ)) + return -ENODEV; if ((err = init_dsp_comm_page(chip))) { DE_INIT(("init_hw - could not initialize DSP comm page\n")); @@ -143,8 +144,9 @@ static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, { int index; - snd_assert(pipe < num_pipes_out(chip) && - output < num_busses_out(chip), return -EINVAL); + if (snd_BUG_ON(pipe >= num_pipes_out(chip) || + output >= num_busses_out(chip))) + return -EINVAL; if (wait_handshake(chip)) return -EIO; diff --git a/sound/pci/echoaudio/indigoio_dsp.c b/sound/pci/echoaudio/indigoio_dsp.c index f3ad13d06be..a7e09ec2107 100644 --- a/sound/pci/echoaudio/indigoio_dsp.c +++ b/sound/pci/echoaudio/indigoio_dsp.c @@ -39,7 +39,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) int err; DE_INIT(("init_hw() - Indigo IO\n")); - snd_assert((subdevice_id & 0xfff0) == INDIGO_IO, return -ENODEV); + if (snd_BUG_ON((subdevice_id & 0xfff0) != INDIGO_IO)) + return -ENODEV; if ((err = init_dsp_comm_page(chip))) { DE_INIT(("init_hw - could not initialize DSP comm page\n")); @@ -114,8 +115,9 @@ static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, { int index; - snd_assert(pipe < num_pipes_out(chip) && - output < num_busses_out(chip), return -EINVAL); + if (snd_BUG_ON(pipe >= num_pipes_out(chip) || + output >= num_busses_out(chip))) + return -EINVAL; if (wait_handshake(chip)) return -EIO; diff --git a/sound/pci/echoaudio/layla20_dsp.c b/sound/pci/echoaudio/layla20_dsp.c index 990c9a60a0a..ede75c6ca0f 100644 --- a/sound/pci/echoaudio/layla20_dsp.c +++ b/sound/pci/echoaudio/layla20_dsp.c @@ -42,7 +42,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) int err; DE_INIT(("init_hw() - Layla20\n")); - snd_assert((subdevice_id & 0xfff0) == LAYLA20, return -ENODEV); + if (snd_BUG_ON((subdevice_id & 0xfff0) != LAYLA20)) + return -ENODEV; if ((err = init_dsp_comm_page(chip))) { DE_INIT(("init_hw - could not initialize DSP comm page\n")); @@ -155,7 +156,8 @@ static int load_asic(struct echoaudio *chip) static int set_sample_rate(struct echoaudio *chip, u32 rate) { - snd_assert(rate >= 8000 && rate <= 50000, return -EINVAL); + if (snd_BUG_ON(rate < 8000 || rate > 50000)) + return -EINVAL; /* Only set the clock for internal mode. Do not return failure, simply treat it as a non-event. */ @@ -252,7 +254,8 @@ static int set_output_clock(struct echoaudio *chip, u16 clock) /* Set input bus gain (one unit is 0.5dB !) */ static int set_input_gain(struct echoaudio *chip, u16 input, int gain) { - snd_assert(input < num_busses_in(chip), return -EINVAL); + if (snd_BUG_ON(input >= num_busses_in(chip))) + return -EINVAL; if (wait_handshake(chip)) return -EIO; diff --git a/sound/pci/echoaudio/layla24_dsp.c b/sound/pci/echoaudio/layla24_dsp.c index 97e42e11514..d61b5cbccca 100644 --- a/sound/pci/echoaudio/layla24_dsp.c +++ b/sound/pci/echoaudio/layla24_dsp.c @@ -42,7 +42,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) int err; DE_INIT(("init_hw() - Layla24\n")); - snd_assert((subdevice_id & 0xfff0) == LAYLA24, return -ENODEV); + if (snd_BUG_ON((subdevice_id & 0xfff0) != LAYLA24)) + return -ENODEV; if ((err = init_dsp_comm_page(chip))) { DE_INIT(("init_hw - could not initialize DSP comm page\n")); @@ -73,7 +74,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) return err; err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA); - snd_assert(err >= 0, return err); + if (err < 0) + return err; err = set_professional_spdif(chip, TRUE); DE_INIT(("init_hw done\n")); @@ -158,8 +160,9 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate) { u32 control_reg, clock, base_rate; - snd_assert(rate < 50000 || chip->digital_mode != DIGITAL_MODE_ADAT, - return -EINVAL); + if (snd_BUG_ON(rate >= 50000 && + chip->digital_mode == DIGITAL_MODE_ADAT)) + return -EINVAL; /* Only set the clock for internal mode. */ if (chip->input_clock != ECHO_CLOCK_INTERNAL) { diff --git a/sound/pci/echoaudio/mia_dsp.c b/sound/pci/echoaudio/mia_dsp.c index 891c7051909..227386602f9 100644 --- a/sound/pci/echoaudio/mia_dsp.c +++ b/sound/pci/echoaudio/mia_dsp.c @@ -42,7 +42,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) int err; DE_INIT(("init_hw() - Mia\n")); - snd_assert((subdevice_id & 0xfff0) == MIA, return -ENODEV); + if (snd_BUG_ON((subdevice_id & 0xfff0) != MIA)) + return -ENODEV; if ((err = init_dsp_comm_page(chip))) { DE_INIT(("init_hw - could not initialize DSP comm page\n")); @@ -161,8 +162,9 @@ static int set_sample_rate(struct echoaudio *chip, u32 rate) static int set_input_clock(struct echoaudio *chip, u16 clock) { DE_ACT(("set_input_clock(%d)\n", clock)); - snd_assert(clock == ECHO_CLOCK_INTERNAL || clock == ECHO_CLOCK_SPDIF, - return -EINVAL); + if (snd_BUG_ON(clock != ECHO_CLOCK_INTERNAL && + clock != ECHO_CLOCK_SPDIF)) + return -EINVAL; chip->input_clock = clock; return set_sample_rate(chip, chip->sample_rate); @@ -176,8 +178,9 @@ static int set_vmixer_gain(struct echoaudio *chip, u16 output, u16 pipe, { int index; - snd_assert(pipe < num_pipes_out(chip) && - output < num_busses_out(chip), return -EINVAL); + if (snd_BUG_ON(pipe >= num_pipes_out(chip) || + output >= num_busses_out(chip))) + return -EINVAL; if (wait_handshake(chip)) return -EIO; diff --git a/sound/pci/echoaudio/midi.c b/sound/pci/echoaudio/midi.c index 91f5bff66d3..77bf2a83d99 100644 --- a/sound/pci/echoaudio/midi.c +++ b/sound/pci/echoaudio/midi.c @@ -59,7 +59,8 @@ static int enable_midi_input(struct echoaudio *chip, char enable) Returns how many actually written or < 0 on error */ static int write_midi(struct echoaudio *chip, u8 *data, int bytes) { - snd_assert(bytes > 0 && bytes < MIDI_OUT_BUFFER_SIZE, return -EINVAL); + if (snd_BUG_ON(bytes <= 0 || bytes >= MIDI_OUT_BUFFER_SIZE)) + return -EINVAL; if (wait_handshake(chip)) return -EIO; @@ -119,7 +120,8 @@ static int midi_service_irq(struct echoaudio *chip) /* The count is at index 0, followed by actual data */ count = le16_to_cpu(chip->comm_page->midi_input[0]); - snd_assert(count < MIDI_IN_BUFFER_SIZE, return 0); + if (snd_BUG_ON(count >= MIDI_IN_BUFFER_SIZE)) + return 0; /* Get the MIDI data from the comm page */ i = 1; diff --git a/sound/pci/echoaudio/mona_dsp.c b/sound/pci/echoaudio/mona_dsp.c index c0b4bf0be7d..eaa619bd2a0 100644 --- a/sound/pci/echoaudio/mona_dsp.c +++ b/sound/pci/echoaudio/mona_dsp.c @@ -43,7 +43,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) int err; DE_INIT(("init_hw() - Mona\n")); - snd_assert((subdevice_id & 0xfff0) == MONA, return -ENODEV); + if (snd_BUG_ON((subdevice_id & 0xfff0) != MONA)) + return -ENODEV; if ((err = init_dsp_comm_page(chip))) { DE_INIT(("init_hw - could not initialize DSP comm page\n")); @@ -79,7 +80,8 @@ static int init_hw(struct echoaudio *chip, u16 device_id, u16 subdevice_id) return err; err = set_digital_mode(chip, DIGITAL_MODE_SPDIF_RCA); - snd_assert(err >= 0, return err); + if (err < 0) + return err; err = set_professional_spdif(chip, TRUE); DE_INIT(("init_hw done\n")); diff --git a/sound/pci/emu10k1/emu10k1_callback.c b/sound/pci/emu10k1/emu10k1_callback.c index 45088ebcce5..0e649dcdbf6 100644 --- a/sound/pci/emu10k1/emu10k1_callback.c +++ b/sound/pci/emu10k1/emu10k1_callback.c @@ -145,7 +145,8 @@ terminate_voice(struct snd_emux_voice *vp) { struct snd_emu10k1 *hw; - snd_assert(vp, return); + if (snd_BUG_ON(!vp)) + return; hw = vp->hw; snd_emu10k1_ptr_write(hw, DCYSUSV, vp->ch, 0x807f | DCYSUSV_CHANNELENABLE_MASK); if (vp->block) { @@ -325,7 +326,8 @@ start_voice(struct snd_emux_voice *vp) hw = vp->hw; ch = vp->ch; - snd_assert(ch >= 0, return -EINVAL); + if (snd_BUG_ON(ch < 0)) + return -EINVAL; chan = vp->chan; emem = (struct snd_emu10k1_memblk *)vp->block; diff --git a/sound/pci/emu10k1/emu10k1_patch.c b/sound/pci/emu10k1/emu10k1_patch.c index 42bae6f7e9a..e10f027bde0 100644 --- a/sound/pci/emu10k1/emu10k1_patch.c +++ b/sound/pci/emu10k1/emu10k1_patch.c @@ -46,8 +46,8 @@ snd_emu10k1_sample_new(struct snd_emux *rec, struct snd_sf_sample *sp, struct snd_emu10k1 *emu; emu = rec->hw; - snd_assert(sp != NULL, return -EINVAL); - snd_assert(hdr != NULL, return -EINVAL); + if (snd_BUG_ON(!sp || !hdr)) + return -EINVAL; if (sp->v.size == 0) { snd_printd("emu: rom font for sample %d\n", sp->v.sample); @@ -104,7 +104,8 @@ snd_emu10k1_sample_new(struct snd_emux *rec, struct snd_sf_sample *sp, size = BLANK_HEAD_SIZE; if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS)) size *= 2; - snd_assert(offset + size <= blocksize, return -EINVAL); + if (offset + size > blocksize) + return -EINVAL; snd_emu10k1_synth_bzero(emu, sp->block, offset, size); offset += size; @@ -112,7 +113,8 @@ snd_emu10k1_sample_new(struct snd_emux *rec, struct snd_sf_sample *sp, size = loopend; if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS)) size *= 2; - snd_assert(offset + size <= blocksize, return -EINVAL); + if (offset + size > blocksize) + return -EINVAL; if (snd_emu10k1_synth_copy_from_user(emu, sp->block, offset, data, size)) { snd_emu10k1_synth_free(emu, sp->block); sp->block = NULL; @@ -129,12 +131,14 @@ snd_emu10k1_sample_new(struct snd_emux *rec, struct snd_sf_sample *sp, int woffset; unsigned short *wblock = (unsigned short*)block; woffset = offset / 2; - snd_assert(offset + loopsize*2 <= blocksize, return -EINVAL); + if (offset + loopsize * 2 > blocksize) + return -EINVAL; for (i = 0; i < loopsize; i++) wblock[woffset + i] = wblock[woffset - i -1]; offset += loopsize * 2; } else { - snd_assert(offset + loopsize <= blocksize, return -EINVAL); + if (offset + loopsize > blocksize) + return -EINVAL; for (i = 0; i < loopsize; i++) block[offset + i] = block[offset - i -1]; offset += loopsize; @@ -154,7 +158,8 @@ snd_emu10k1_sample_new(struct snd_emux *rec, struct snd_sf_sample *sp, /* loopend -> sample end */ size = sp->v.size - loopend; - snd_assert(size >= 0, return -EINVAL); + if (size < 0) + return -EINVAL; if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS)) size *= 2; if (snd_emu10k1_synth_copy_from_user(emu, sp->block, offset, data, size)) { @@ -212,8 +217,8 @@ snd_emu10k1_sample_free(struct snd_emux *rec, struct snd_sf_sample *sp, struct snd_emu10k1 *emu; emu = rec->hw; - snd_assert(sp != NULL, return -EINVAL); - snd_assert(hdr != NULL, return -EINVAL); + if (snd_BUG_ON(!sp || !hdr)) + return -EINVAL; if (sp->block) { snd_emu10k1_synth_free(emu, sp->block); diff --git a/sound/pci/emu10k1/emu10k1x.c b/sound/pci/emu10k1/emu10k1x.c index 491a4a50f86..5ff4dbb62da 100644 --- a/sound/pci/emu10k1/emu10k1x.c +++ b/sound/pci/emu10k1/emu10k1x.c @@ -1319,7 +1319,8 @@ static int snd_emu10k1x_midi_input_open(struct snd_rawmidi_substream *substream) unsigned long flags; emu = midi->emu; - snd_assert(emu, return -ENXIO); + if (snd_BUG_ON(!emu)) + return -ENXIO; spin_lock_irqsave(&midi->open_lock, flags); midi->midi_mode |= EMU10K1X_MIDI_MODE_INPUT; midi->substream_input = substream; @@ -1345,7 +1346,8 @@ static int snd_emu10k1x_midi_output_open(struct snd_rawmidi_substream *substream unsigned long flags; emu = midi->emu; - snd_assert(emu, return -ENXIO); + if (snd_BUG_ON(!emu)) + return -ENXIO; spin_lock_irqsave(&midi->open_lock, flags); midi->midi_mode |= EMU10K1X_MIDI_MODE_OUTPUT; midi->substream_output = substream; @@ -1372,7 +1374,8 @@ static int snd_emu10k1x_midi_input_close(struct snd_rawmidi_substream *substream int err = 0; emu = midi->emu; - snd_assert(emu, return -ENXIO); + if (snd_BUG_ON(!emu)) + return -ENXIO; spin_lock_irqsave(&midi->open_lock, flags); snd_emu10k1x_intr_disable(emu, midi->rx_enable); midi->midi_mode &= ~EMU10K1X_MIDI_MODE_INPUT; @@ -1394,7 +1397,8 @@ static int snd_emu10k1x_midi_output_close(struct snd_rawmidi_substream *substrea int err = 0; emu = midi->emu; - snd_assert(emu, return -ENXIO); + if (snd_BUG_ON(!emu)) + return -ENXIO; spin_lock_irqsave(&midi->open_lock, flags); snd_emu10k1x_intr_disable(emu, midi->tx_enable); midi->midi_mode &= ~EMU10K1X_MIDI_MODE_OUTPUT; @@ -1413,7 +1417,8 @@ static void snd_emu10k1x_midi_input_trigger(struct snd_rawmidi_substream *substr struct emu10k1x *emu; struct emu10k1x_midi *midi = substream->rmidi->private_data; emu = midi->emu; - snd_assert(emu, return); + if (snd_BUG_ON(!emu)) + return; if (up) snd_emu10k1x_intr_enable(emu, midi->rx_enable); @@ -1428,7 +1433,8 @@ static void snd_emu10k1x_midi_output_trigger(struct snd_rawmidi_substream *subst unsigned long flags; emu = midi->emu; - snd_assert(emu, return); + if (snd_BUG_ON(!emu)) + return; if (up) { int max = 4; diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c index 71dc4c8865b..7dba08f0ab8 100644 --- a/sound/pci/emu10k1/emufx.c +++ b/sound/pci/emu10k1/emufx.c @@ -487,7 +487,8 @@ static void snd_emu10k1_write_op(struct snd_emu10k1_fx8010_code *icode, u32 op, u32 r, u32 a, u32 x, u32 y) { u_int32_t *code; - snd_assert(*ptr < 512, return); + if (snd_BUG_ON(*ptr >= 512)) + return; code = (u_int32_t __force *)icode->code + (*ptr) * 2; set_bit(*ptr, icode->code_valid); code[0] = ((x & 0x3ff) << 10) | (y & 0x3ff); @@ -503,7 +504,8 @@ static void snd_emu10k1_audigy_write_op(struct snd_emu10k1_fx8010_code *icode, u32 op, u32 r, u32 a, u32 x, u32 y) { u_int32_t *code; - snd_assert(*ptr < 1024, return); + if (snd_BUG_ON(*ptr >= 1024)) + return; code = (u_int32_t __force *)icode->code + (*ptr) * 2; set_bit(*ptr, icode->code_valid); code[0] = ((x & 0x7ff) << 12) | (y & 0x7ff); diff --git a/sound/pci/emu10k1/emumpu401.c b/sound/pci/emu10k1/emumpu401.c index c4d76d16661..8578c70c61f 100644 --- a/sound/pci/emu10k1/emumpu401.c +++ b/sound/pci/emu10k1/emumpu401.c @@ -157,7 +157,8 @@ static int snd_emu10k1_midi_input_open(struct snd_rawmidi_substream *substream) unsigned long flags; emu = midi->emu; - snd_assert(emu, return -ENXIO); + if (snd_BUG_ON(!emu)) + return -ENXIO; spin_lock_irqsave(&midi->open_lock, flags); midi->midi_mode |= EMU10K1_MIDI_MODE_INPUT; midi->substream_input = substream; @@ -183,7 +184,8 @@ static int snd_emu10k1_midi_output_open(struct snd_rawmidi_substream *substream) unsigned long flags; emu = midi->emu; - snd_assert(emu, return -ENXIO); + if (snd_BUG_ON(!emu)) + return -ENXIO; spin_lock_irqsave(&midi->open_lock, flags); midi->midi_mode |= EMU10K1_MIDI_MODE_OUTPUT; midi->substream_output = substream; @@ -210,7 +212,8 @@ static int snd_emu10k1_midi_input_close(struct snd_rawmidi_substream *substream) int err = 0; emu = midi->emu; - snd_assert(emu, return -ENXIO); + if (snd_BUG_ON(!emu)) + return -ENXIO; spin_lock_irqsave(&midi->open_lock, flags); snd_emu10k1_intr_disable(emu, midi->rx_enable); midi->midi_mode &= ~EMU10K1_MIDI_MODE_INPUT; @@ -232,7 +235,8 @@ static int snd_emu10k1_midi_output_close(struct snd_rawmidi_substream *substream int err = 0; emu = midi->emu; - snd_assert(emu, return -ENXIO); + if (snd_BUG_ON(!emu)) + return -ENXIO; spin_lock_irqsave(&midi->open_lock, flags); snd_emu10k1_intr_disable(emu, midi->tx_enable); midi->midi_mode &= ~EMU10K1_MIDI_MODE_OUTPUT; @@ -251,7 +255,8 @@ static void snd_emu10k1_midi_input_trigger(struct snd_rawmidi_substream *substre struct snd_emu10k1 *emu; struct snd_emu10k1_midi *midi = (struct snd_emu10k1_midi *)substream->rmidi->private_data; emu = midi->emu; - snd_assert(emu, return); + if (snd_BUG_ON(!emu)) + return; if (up) snd_emu10k1_intr_enable(emu, midi->rx_enable); @@ -266,7 +271,8 @@ static void snd_emu10k1_midi_output_trigger(struct snd_rawmidi_substream *substr unsigned long flags; emu = midi->emu; - snd_assert(emu, return); + if (snd_BUG_ON(!emu)) + return; if (up) { int max = 4; diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c index 7d379f5131f..e8ad56ed34f 100644 --- a/sound/pci/emu10k1/memory.c +++ b/sound/pci/emu10k1/memory.c @@ -107,7 +107,8 @@ static int search_empty_map_area(struct snd_emu10k1 *emu, int npages, struct lis list_for_each (pos, &emu->mapped_link_head) { struct snd_emu10k1_memblk *blk = get_emu10k1_memblk(pos, mapped_link); - snd_assert(blk->mapped_page >= 0, continue); + if (blk->mapped_page < 0) + continue; size = blk->mapped_page - page; if (size == npages) { *nextp = pos; @@ -300,10 +301,14 @@ snd_emu10k1_alloc_pages(struct snd_emu10k1 *emu, struct snd_pcm_substream *subst struct snd_emu10k1_memblk *blk; int page, err, idx; - snd_assert(emu, return NULL); - snd_assert(runtime->dma_bytes > 0 && runtime->dma_bytes < MAXPAGES * EMUPAGESIZE, return NULL); + if (snd_BUG_ON(!emu)) + return NULL; + if (snd_BUG_ON(runtime->dma_bytes <= 0 || + runtime->dma_bytes >= MAXPAGES * EMUPAGESIZE)) + return NULL; hdr = emu->memhdr; - snd_assert(hdr, return NULL); + if (snd_BUG_ON(!hdr)) + return NULL; mutex_lock(&hdr->block_mutex); blk = search_empty(emu, runtime->dma_bytes); @@ -353,7 +358,8 @@ snd_emu10k1_alloc_pages(struct snd_emu10k1 *emu, struct snd_pcm_substream *subst */ int snd_emu10k1_free_pages(struct snd_emu10k1 *emu, struct snd_util_memblk *blk) { - snd_assert(emu && blk, return -EINVAL); + if (snd_BUG_ON(!emu || !blk)) + return -EINVAL; return snd_emu10k1_synth_free(emu, blk); } @@ -498,7 +504,8 @@ static int synth_free_pages(struct snd_emu10k1 *emu, struct snd_emu10k1_memblk * static inline void *offset_ptr(struct snd_emu10k1 *emu, int page, int offset) { char *ptr; - snd_assert(page >= 0 && page < emu->max_cache_pages, return NULL); + if (snd_BUG_ON(page < 0 || page >= emu->max_cache_pages)) + return NULL; ptr = emu->page_ptr_table[page]; if (! ptr) { printk(KERN_ERR "emu10k1: access to NULL ptr: page = %d\n", page); diff --git a/sound/pci/emu10k1/voice.c b/sound/pci/emu10k1/voice.c index 958cb2a65a4..d7300a1aa26 100644 --- a/sound/pci/emu10k1/voice.c +++ b/sound/pci/emu10k1/voice.c @@ -111,8 +111,10 @@ int snd_emu10k1_voice_alloc(struct snd_emu10k1 *emu, int type, int number, unsigned long flags; int result; - snd_assert(rvoice != NULL, return -EINVAL); - snd_assert(number, return -EINVAL); + if (snd_BUG_ON(!rvoice)) + return -EINVAL; + if (snd_BUG_ON(!number)) + return -EINVAL; spin_lock_irqsave(&emu->voice_lock, flags); for (;;) { @@ -145,7 +147,8 @@ int snd_emu10k1_voice_free(struct snd_emu10k1 *emu, { unsigned long flags; - snd_assert(pvoice != NULL, return -EINVAL); + if (snd_BUG_ON(!pvoice)) + return -EINVAL; spin_lock_irqsave(&emu->voice_lock, flags); pvoice->interrupt = NULL; pvoice->use = pvoice->pcm = pvoice->synth = pvoice->midi = pvoice->efx = 0; diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c index 84fac1fbf10..4cd9a1faaec 100644 --- a/sound/pci/es1938.c +++ b/sound/pci/es1938.c @@ -860,7 +860,8 @@ static int snd_es1938_capture_copy(struct snd_pcm_substream *substream, struct es1938 *chip = snd_pcm_substream_chip(substream); pos <<= chip->dma1_shift; count <<= chip->dma1_shift; - snd_assert(pos + count <= chip->dma1_size, return -EINVAL); + if (snd_BUG_ON(pos + count > chip->dma1_size)) + return -EINVAL; if (pos + count < chip->dma1_size) { if (copy_to_user(dst, runtime->dma_area + pos + 1, count)) return -EFAULT; diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c index 1bf298d214b..20ee7599600 100644 --- a/sound/pci/es1968.c +++ b/sound/pci/es1968.c @@ -692,7 +692,8 @@ static void apu_data_set(struct es1968 *chip, u16 data) /* no spinlock */ static void __apu_set_register(struct es1968 *chip, u16 channel, u8 reg, u16 data) { - snd_assert(channel < NR_APUS, return); + if (snd_BUG_ON(channel >= NR_APUS)) + return; #ifdef CONFIG_PM chip->apu_map[channel][reg] = data; #endif @@ -711,7 +712,8 @@ static void apu_set_register(struct es1968 *chip, u16 channel, u8 reg, u16 data) static u16 __apu_get_register(struct es1968 *chip, u16 channel, u8 reg) { - snd_assert(channel < NR_APUS, return 0); + if (snd_BUG_ON(channel >= NR_APUS)) + return 0; reg |= (channel << 4); apu_index_set(chip, reg); return __maestro_read(chip, IDR0_DATA_PORT); diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index d2e1093f8e9..77fbcd4a69b 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -211,7 +211,8 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, unsigned int shift, num_elems, mask; hda_nid_t prev_nid; - snd_assert(conn_list && max_conns > 0, return -EINVAL); + if (snd_BUG_ON(!conn_list || max_conns <= 0)) + return -EINVAL; parm = snd_hda_param_read(codec, nid, AC_PAR_CONNLIST_LEN); if (parm & AC_CLIST_LONG) { @@ -407,8 +408,10 @@ int __devinit snd_hda_bus_new(struct snd_card *card, .dev_free = snd_hda_bus_dev_free, }; - snd_assert(temp, return -EINVAL); - snd_assert(temp->ops.command && temp->ops.get_response, return -EINVAL); + if (snd_BUG_ON(!temp)) + return -EINVAL; + if (snd_BUG_ON(!temp->ops.command || !temp->ops.get_response)) + return -EINVAL; if (busp) *busp = NULL; @@ -588,8 +591,10 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, char component[13]; int err; - snd_assert(bus, return -EINVAL); - snd_assert(codec_addr <= HDA_MAX_CODEC_ADDRESS, return -EINVAL); + if (snd_BUG_ON(!bus)) + return -EINVAL; + if (snd_BUG_ON(codec_addr > HDA_MAX_CODEC_ADDRESS)) + return -EINVAL; if (bus->caddr_tbl[codec_addr]) { snd_printk(KERN_ERR "hda_codec: " @@ -2236,11 +2241,13 @@ static int __devinit set_pcm_default_values(struct hda_codec *codec, if (info->ops.close == NULL) info->ops.close = hda_pcm_default_open_close; if (info->ops.prepare == NULL) { - snd_assert(info->nid, return -EINVAL); + if (snd_BUG_ON(!info->nid)) + return -EINVAL; info->ops.prepare = hda_pcm_default_prepare; } if (info->ops.cleanup == NULL) { - snd_assert(info->nid, return -EINVAL); + if (snd_BUG_ON(!info->nid)) + return -EINVAL; info->ops.cleanup = hda_pcm_default_cleanup; } return 0; diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 59e4389c94a..0ca30894f7c 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -174,7 +174,8 @@ static int build_afg_tree(struct hda_codec *codec) int i, nodes, err; hda_nid_t nid; - snd_assert(spec, return -EINVAL); + if (snd_BUG_ON(!spec)) + return -EINVAL; spec->def_amp_out_caps = snd_hda_param_read(codec, codec->afg, AC_PAR_AMP_OUT_CAP); spec->def_amp_in_caps = snd_hda_param_read(codec, codec->afg, AC_PAR_AMP_IN_CAP); diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 1c53e337ecb..b2bcd94cf7a 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -1646,7 +1646,8 @@ static int __devinit create_codec_pcm(struct azx *chip, struct hda_codec *codec, if (!cpcm->stream[0].substreams && !cpcm->stream[1].substreams) return 0; - snd_assert(cpcm->name, return -EINVAL); + if (snd_BUG_ON(!cpcm->name)) + return -EINVAL; err = snd_pcm_new(chip->card, cpcm->name, cpcm->device, cpcm->stream[0].substreams, diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 4bd26725355..7e5422f64ca 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -2633,12 +2633,14 @@ static int alc_build_pcms(struct hda_codec *codec) info->name = spec->stream_name_analog; if (spec->stream_analog_playback) { - snd_assert(spec->multiout.dac_nids, return -EINVAL); + if (snd_BUG_ON(!spec->multiout.dac_nids)) + return -EINVAL; info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *(spec->stream_analog_playback); info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0]; } if (spec->stream_analog_capture) { - snd_assert(spec->adc_nids, return -EINVAL); + if (snd_BUG_ON(!spec->adc_nids)) + return -EINVAL; info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_analog_capture); info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; } diff --git a/sound/pci/ice1712/ak4xxx.c b/sound/pci/ice1712/ak4xxx.c index dab31b2756a..03391da8c8c 100644 --- a/sound/pci/ice1712/ak4xxx.c +++ b/sound/pci/ice1712/ak4xxx.c @@ -59,7 +59,8 @@ static void snd_ice1712_akm4xxx_write(struct snd_akm4xxx *ak, int chip, struct snd_ak4xxx_private *priv = (void *)ak->private_value[0]; struct snd_ice1712 *ice = ak->private_data[0]; - snd_assert(chip >= 0 && chip < 4, return); + if (snd_BUG_ON(chip < 0 || chip >= 4)) + return; tmp = snd_ice1712_gpio_read(ice); tmp |= priv->add_flags; diff --git a/sound/pci/ice1712/ews.c b/sound/pci/ice1712/ews.c index 013fc4f0482..6fe35b81204 100644 --- a/sound/pci/ice1712/ews.c +++ b/sound/pci/ice1712/ews.c @@ -149,7 +149,8 @@ static int snd_ice1712_ews88mt_chip_select(struct snd_ice1712 *ice, int chip_mas struct ews_spec *spec = ice->spec; unsigned char data, ndata; - snd_assert(chip_mask >= 0 && chip_mask <= 0x0f, return -EINVAL); + if (snd_BUG_ON(chip_mask < 0 || chip_mask > 0x0f)) + return -EINVAL; snd_i2c_lock(ice->i2c); if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_PCF2], &data, 1) != 1) goto __error; @@ -685,7 +686,8 @@ static int snd_ice1712_ews88mt_input_sense_get(struct snd_kcontrol *kcontrol, st int channel = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); unsigned char data; - snd_assert(channel >= 0 && channel <= 7, return 0); + if (snd_BUG_ON(channel < 0 || channel > 7)) + return 0; snd_i2c_lock(ice->i2c); if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_PCF1], &data, 1) != 1) { snd_i2c_unlock(ice->i2c); @@ -705,7 +707,8 @@ static int snd_ice1712_ews88mt_input_sense_put(struct snd_kcontrol *kcontrol, st int channel = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); unsigned char data, ndata; - snd_assert(channel >= 0 && channel <= 7, return 0); + if (snd_BUG_ON(channel < 0 || channel > 7)) + return 0; snd_i2c_lock(ice->i2c); if (snd_i2c_readbytes(spec->i2cdevs[EWS_I2C_PCF1], &data, 1) != 1) { snd_i2c_unlock(ice->i2c); diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c index 29d449d73c9..05ffab65d16 100644 --- a/sound/pci/ice1712/ice1712.c +++ b/sound/pci/ice1712/ice1712.c @@ -2416,7 +2416,8 @@ int __devinit snd_ice1712_spdif_build_controls(struct snd_ice1712 *ice) int err; struct snd_kcontrol *kctl; - snd_assert(ice->pcm_pro != NULL, return -EIO); + if (snd_BUG_ON(!ice->pcm_pro)) + return -EIO; err = snd_ctl_add(ice->card, kctl = snd_ctl_new1(&snd_ice1712_spdif_default, ice)); if (err < 0) return err; diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c index e596d777d9d..60119d220a6 100644 --- a/sound/pci/ice1712/ice1724.c +++ b/sound/pci/ice1712/ice1724.c @@ -2250,7 +2250,8 @@ static int __devinit snd_vt1724_spdif_build_controls(struct snd_ice1712 *ice) int err; struct snd_kcontrol *kctl; - snd_assert(ice->pcm != NULL, return -EIO); + if (snd_BUG_ON(!ice->pcm)) + return -EIO; err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_vt1724_mixer_pro_spdif_route, ice)); if (err < 0) diff --git a/sound/pci/ice1712/juli.c b/sound/pci/ice1712/juli.c index b4e0c16852a..21ff4de890b 100644 --- a/sound/pci/ice1712/juli.c +++ b/sound/pci/ice1712/juli.c @@ -208,7 +208,8 @@ static void juli_akm_write(struct snd_akm4xxx *ak, int chip, { struct snd_ice1712 *ice = ak->private_data[0]; - snd_assert(chip == 0, return); + if (snd_BUG_ON(chip)) + return; snd_vt1724_write_i2c(ice, AK4358_ADDR, addr, data); } diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 048d99e25ab..78760996632 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c @@ -2132,8 +2132,8 @@ static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock, snd_intel8x0_codec_read_test(chip, codecs); chip->ac97_sdin[codecs] = igetbyte(chip, ICHREG(SDM)) & ICH_LDI_MASK; - snd_assert(chip->ac97_sdin[codecs] < 3, - chip->ac97_sdin[codecs] = 0); + if (snd_BUG_ON(chip->ac97_sdin[codecs] >= 3)) + chip->ac97_sdin[codecs] = 0; } else chip->ac97_sdin[codecs] = i; codecs++; diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c index faf674e671a..93449e46456 100644 --- a/sound/pci/intel8x0m.c +++ b/sound/pci/intel8x0m.c @@ -306,7 +306,8 @@ static unsigned int get_ich_codec_bit(struct intel8x0m *chip, unsigned int codec static unsigned int codec_bit[3] = { ICH_PCR, ICH_SCR, ICH_TCR }; - snd_assert(codec < 3, return ICH_PCR); + if (snd_BUG_ON(codec >= 3)) + return ICH_PCR; return codec_bit[codec]; } diff --git a/sound/pci/korg1212/korg1212.c b/sound/pci/korg1212/korg1212.c index 4a44c0f20f7..5f8006b4275 100644 --- a/sound/pci/korg1212/korg1212.c +++ b/sound/pci/korg1212/korg1212.c @@ -1281,7 +1281,8 @@ static int snd_korg1212_silence(struct snd_korg1212 *korg1212, int pos, int coun K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_silence pos=%d offset=%d size=%d count=%d\n", pos, offset, size, count); - snd_assert(pos + count <= K1212_MAX_SAMPLES, return -EINVAL); + if (snd_BUG_ON(pos + count > K1212_MAX_SAMPLES)) + return -EINVAL; for (i=0; i < count; i++) { #if K1212_DEBUG_LEVEL > 0 @@ -1306,7 +1307,8 @@ static int snd_korg1212_copy_to(struct snd_korg1212 *korg1212, void __user *dst, K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_copy_to pos=%d offset=%d size=%d\n", pos, offset, size); - snd_assert(pos + count <= K1212_MAX_SAMPLES, return -EINVAL); + if (snd_BUG_ON(pos + count > K1212_MAX_SAMPLES)) + return -EINVAL; for (i=0; i < count; i++) { #if K1212_DEBUG_LEVEL > 0 @@ -1336,7 +1338,8 @@ static int snd_korg1212_copy_from(struct snd_korg1212 *korg1212, void __user *sr K1212_DEBUG_PRINTK_VERBOSE("K1212_DEBUG: snd_korg1212_copy_from pos=%d offset=%d size=%d count=%d\n", pos, offset, size, count); - snd_assert(pos + count <= K1212_MAX_SAMPLES, return -EINVAL); + if (snd_BUG_ON(pos + count > K1212_MAX_SAMPLES)) + return -EINVAL; for (i=0; i < count; i++) { #if K1212_DEBUG_LEVEL > 0 diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c index 0037be74fde..9ff3f9e3440 100644 --- a/sound/pci/maestro3.c +++ b/sound/pci/maestro3.c @@ -1175,7 +1175,8 @@ snd_m3_pcm_trigger(struct snd_pcm_substream *subs, int cmd) struct m3_dma *s = subs->runtime->private_data; int err = -EINVAL; - snd_assert(s != NULL, return -ENXIO); + if (snd_BUG_ON(!s)) + return -ENXIO; spin_lock(&chip->reg_lock); switch (cmd) { @@ -1487,7 +1488,8 @@ snd_m3_pcm_prepare(struct snd_pcm_substream *subs) struct snd_pcm_runtime *runtime = subs->runtime; struct m3_dma *s = runtime->private_data; - snd_assert(s != NULL, return -ENXIO); + if (snd_BUG_ON(!s)) + return -ENXIO; if (runtime->format != SNDRV_PCM_FORMAT_U8 && runtime->format != SNDRV_PCM_FORMAT_S16_LE) @@ -1546,7 +1548,9 @@ snd_m3_pcm_pointer(struct snd_pcm_substream *subs) struct snd_m3 *chip = snd_pcm_substream_chip(subs); unsigned int ptr; struct m3_dma *s = subs->runtime->private_data; - snd_assert(s != NULL, return 0); + + if (snd_BUG_ON(!s)) + return 0; spin_lock(&chip->reg_lock); ptr = snd_m3_get_pointer(chip, s, subs); diff --git a/sound/pci/mixart/mixart.c b/sound/pci/mixart/mixart.c index 3dd0c796327..2d0dce649a6 100644 --- a/sound/pci/mixart/mixart.c +++ b/sound/pci/mixart/mixart.c @@ -708,7 +708,7 @@ static int snd_mixart_playback_open(struct snd_pcm_substream *subs) pcm_number = MIXART_PCM_ANALOG; runtime->hw = snd_mixart_analog_caps; } else { - snd_assert ( pcm == chip->pcm_dig ); + snd_BUG_ON(pcm != chip->pcm_dig); pcm_number = MIXART_PCM_DIGITAL; runtime->hw = snd_mixart_digital_caps; } @@ -783,7 +783,7 @@ static int snd_mixart_capture_open(struct snd_pcm_substream *subs) pcm_number = MIXART_PCM_ANALOG; runtime->hw = snd_mixart_analog_caps; } else { - snd_assert ( pcm == chip->pcm_dig ); + snd_BUG_ON(pcm != chip->pcm_dig); pcm_number = MIXART_PCM_DIGITAL; runtime->hw = snd_mixart_digital_caps; } diff --git a/sound/pci/mixart/mixart_core.c b/sound/pci/mixart/mixart_core.c index 785085e4835..b9a06c27939 100644 --- a/sound/pci/mixart/mixart_core.c +++ b/sound/pci/mixart/mixart_core.c @@ -56,8 +56,10 @@ static int retrieve_msg_frame(struct mixart_mgr *mgr, u32 *msg_frame) if (tailptr == headptr) return 0; /* no message posted */ - snd_assert( tailptr >= MSG_OUTBOUND_POST_STACK, return 0); /* error */ - snd_assert( tailptr < (MSG_OUTBOUND_POST_STACK+MSG_BOUND_STACK_SIZE), return 0); /* error */ + if (tailptr < MSG_OUTBOUND_POST_STACK) + return 0; /* error */ + if (tailptr >= MSG_OUTBOUND_POST_STACK + MSG_BOUND_STACK_SIZE) + return 0; /* error */ *msg_frame = readl_be(MIXART_MEM(mgr, tailptr)); @@ -149,7 +151,8 @@ static int send_msg( struct mixart_mgr *mgr, u32 msg_frame_address; int err, i; - snd_assert(msg->size % 4 == 0, return -EINVAL); + if (snd_BUG_ON(msg->size % 4)) + return -EINVAL; err = 0; @@ -289,9 +292,12 @@ int snd_mixart_send_msg_wait_notif(struct mixart_mgr *mgr, wait_queue_t wait; long timeout; - snd_assert(notif_event != 0, return -EINVAL); - snd_assert((notif_event & MSG_TYPE_MASK) == MSG_TYPE_NOTIFY, return -EINVAL); - snd_assert((notif_event & MSG_CANCEL_NOTIFY_MASK) == 0, return -EINVAL); + if (snd_BUG_ON(!notif_event)) + return -EINVAL; + if (snd_BUG_ON((notif_event & MSG_TYPE_MASK) != MSG_TYPE_NOTIFY)) + return -EINVAL; + if (snd_BUG_ON(notif_event & MSG_CANCEL_NOTIFY_MASK)) + return -EINVAL; mutex_lock(&mgr->msg_mutex); diff --git a/sound/pci/mixart/mixart_hwdep.c b/sound/pci/mixart/mixart_hwdep.c index f9860314613..3782b52bc0e 100644 --- a/sound/pci/mixart/mixart_hwdep.c +++ b/sound/pci/mixart/mixart_hwdep.c @@ -288,7 +288,9 @@ static int mixart_enum_physio(struct mixart_mgr *mgr) return -EINVAL; } - snd_assert(phys_io.nb_uid >= (MIXART_MAX_CARDS * 2), return -EINVAL); /* min 2 phys io per card (analog in + analog out) */ + /* min 2 phys io per card (analog in + analog out) */ + if (phys_io.nb_uid < MIXART_MAX_CARDS * 2) + return -EINVAL; for(k=0; knum_cards; k++) { mgr->chip[k]->uid_in_analog_physio = phys_io.uid[k]; @@ -363,8 +365,10 @@ static int mixart_dsp_load(struct mixart_mgr* mgr, int index, const struct firmw } /* check xilinx validity */ - snd_assert(((u32*)(dsp->data))[0]==0xFFFFFFFF, return -EINVAL); - snd_assert(dsp->size % 4 == 0, return -EINVAL); + if (((u32*)(dsp->data))[0] == 0xffffffff) + return -EINVAL; + if (dsp->size % 4) + return -EINVAL; /* set xilinx status to copying */ writel_be( 1, MIXART_MEM( mgr, MIXART_PSEUDOREG_MXLX_STATUS_OFFSET )); @@ -462,8 +466,10 @@ static int mixart_dsp_load(struct mixart_mgr* mgr, int index, const struct firmw } /* check daughterboard xilinx validity */ - snd_assert(((u32*)(dsp->data))[0]==0xFFFFFFFF, return -EINVAL); - snd_assert(dsp->size % 4 == 0, return -EINVAL); + if (((u32*)(dsp->data))[0] == 0xffffffff) + return -EINVAL; + if (dsp->size % 4) + return -EINVAL; /* inform mixart about the size of the file */ writel_be( dsp->size, MIXART_MEM( mgr, MIXART_PSEUDOREG_DXLX_SIZE_OFFSET )); @@ -480,7 +486,8 @@ static int mixart_dsp_load(struct mixart_mgr* mgr, int index, const struct firmw /* get the address where to write the file */ val = readl_be( MIXART_MEM( mgr, MIXART_PSEUDOREG_DXLX_BASE_ADDR_OFFSET )); - snd_assert(val != 0, return -EINVAL); + if (!val) + return -EINVAL; /* copy daughterboard xilinx code */ memcpy_toio( MIXART_MEM( mgr, val), dsp->data, dsp->size); diff --git a/sound/pci/mixart/mixart_mixer.c b/sound/pci/mixart/mixart_mixer.c index 6fdda1f70b2..3ba6174c3df 100644 --- a/sound/pci/mixart/mixart_mixer.c +++ b/sound/pci/mixart/mixart_mixer.c @@ -837,7 +837,7 @@ static int mixart_pcm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem if(is_aes) stored_volume = chip->digital_capture_volume[1]; /* AES capture */ else stored_volume = chip->digital_capture_volume[0]; /* analog capture */ } else { - snd_assert ( idx < MIXART_PLAYBACK_STREAMS ); + snd_BUG_ON(idx >= MIXART_PLAYBACK_STREAMS); if(is_aes) stored_volume = chip->digital_playback_volume[MIXART_PLAYBACK_STREAMS + idx]; /* AES playback */ else stored_volume = chip->digital_playback_volume[idx]; /* analog playback */ } @@ -863,7 +863,7 @@ static int mixart_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem else /* analog capture */ stored_volume = chip->digital_capture_volume[0]; } else { - snd_assert ( idx < MIXART_PLAYBACK_STREAMS ); + snd_BUG_ON(idx >= MIXART_PLAYBACK_STREAMS); if (is_aes) /* AES playback */ stored_volume = chip->digital_playback_volume[MIXART_PLAYBACK_STREAMS + idx]; else /* analog playback */ @@ -909,7 +909,7 @@ static int mixart_pcm_sw_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ { struct snd_mixart *chip = snd_kcontrol_chip(kcontrol); int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */ - snd_assert ( idx < MIXART_PLAYBACK_STREAMS ); + snd_BUG_ON(idx >= MIXART_PLAYBACK_STREAMS); mutex_lock(&chip->mgr->mixer_mutex); if(kcontrol->private_value & MIXART_VOL_AES_MASK) /* AES playback */ idx += MIXART_PLAYBACK_STREAMS; @@ -926,7 +926,7 @@ static int mixart_pcm_sw_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ int is_aes = kcontrol->private_value & MIXART_VOL_AES_MASK; int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); /* index */ int i, j; - snd_assert ( idx < MIXART_PLAYBACK_STREAMS ); + snd_BUG_ON(idx >= MIXART_PLAYBACK_STREAMS); mutex_lock(&chip->mgr->mixer_mutex); j = idx; if (is_aes) diff --git a/sound/pci/nm256/nm256.c b/sound/pci/nm256/nm256.c index 06d13e71711..50c9f8a0508 100644 --- a/sound/pci/nm256/nm256.c +++ b/sound/pci/nm256/nm256.c @@ -562,7 +562,8 @@ snd_nm256_playback_trigger(struct snd_pcm_substream *substream, int cmd) struct nm256_stream *s = substream->runtime->private_data; int err = 0; - snd_assert(s != NULL, return -ENXIO); + if (snd_BUG_ON(!s)) + return -ENXIO; spin_lock(&chip->reg_lock); switch (cmd) { @@ -599,7 +600,8 @@ snd_nm256_capture_trigger(struct snd_pcm_substream *substream, int cmd) struct nm256_stream *s = substream->runtime->private_data; int err = 0; - snd_assert(s != NULL, return -ENXIO); + if (snd_BUG_ON(!s)) + return -ENXIO; spin_lock(&chip->reg_lock); switch (cmd) { @@ -635,7 +637,8 @@ static int snd_nm256_pcm_prepare(struct snd_pcm_substream *substream) struct snd_pcm_runtime *runtime = substream->runtime; struct nm256_stream *s = runtime->private_data; - snd_assert(s, return -ENXIO); + if (snd_BUG_ON(!s)) + return -ENXIO; s->dma_size = frames_to_bytes(runtime, substream->runtime->buffer_size); s->period_size = frames_to_bytes(runtime, substream->runtime->period_size); s->periods = substream->runtime->periods; @@ -660,7 +663,8 @@ snd_nm256_playback_pointer(struct snd_pcm_substream *substream) struct nm256_stream *s = substream->runtime->private_data; unsigned long curp; - snd_assert(s, return 0); + if (snd_BUG_ON(!s)) + return 0; curp = snd_nm256_readl(chip, NM_PBUFFER_CURRP) - (unsigned long)s->buf; curp %= s->dma_size; return bytes_to_frames(substream->runtime, curp); @@ -673,7 +677,8 @@ snd_nm256_capture_pointer(struct snd_pcm_substream *substream) struct nm256_stream *s = substream->runtime->private_data; unsigned long curp; - snd_assert(s != NULL, return 0); + if (snd_BUG_ON(!s)) + return 0; curp = snd_nm256_readl(chip, NM_RBUFFER_CURRP) - (unsigned long)s->buf; curp %= s->dma_size; return bytes_to_frames(substream->runtime, curp); diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c index 2c7e2533679..0e06c6c9fcc 100644 --- a/sound/pci/pcxhr/pcxhr.c +++ b/sound/pci/pcxhr/pcxhr.c @@ -464,7 +464,8 @@ static int pcxhr_update_r_buffer(struct pcxhr_stream *stream) pcxhr_init_rmh(&rmh, CMD_UPDATE_R_BUFFERS); pcxhr_set_pipe_cmd_params(&rmh, is_capture, stream->pipe->first_audio, stream_num, 0); - snd_assert(subs->runtime->dma_bytes < 0x200000); /* max buffer size is 2 MByte */ + /* max buffer size is 2 MByte */ + snd_BUG_ON(subs->runtime->dma_bytes >= 0x200000); rmh.cmd[1] = subs->runtime->dma_bytes * 8; /* size in bits */ rmh.cmd[2] = subs->runtime->dma_addr >> 24; /* most significant byte */ rmh.cmd[2] |= 1<<19; /* this is a circular buffer */ @@ -1228,7 +1229,8 @@ static int __devinit pcxhr_probe(struct pci_dev *pci, const struct pci_device_id return -ENOMEM; } - snd_assert(pci_id->driver_data < PCI_ID_LAST, return -ENODEV); + if (snd_BUG_ON(pci_id->driver_data >= PCI_ID_LAST)) + return -ENODEV; card_name = pcxhr_board_params[pci_id->driver_data].board_name; mgr->playback_chips = pcxhr_board_params[pci_id->driver_data].playback_chips; mgr->capture_chips = pcxhr_board_params[pci_id->driver_data].capture_chips; diff --git a/sound/pci/pcxhr/pcxhr_core.c b/sound/pci/pcxhr/pcxhr_core.c index 000e6fed6e3..7143259cfe3 100644 --- a/sound/pci/pcxhr/pcxhr_core.c +++ b/sound/pci/pcxhr/pcxhr_core.c @@ -319,16 +319,20 @@ static int pcxhr_download_dsp(struct pcxhr_mgr *mgr, const struct firmware *dsp) const unsigned char *data; unsigned char dummy; /* check the length of boot image */ - snd_assert(dsp->size > 0, return -EINVAL); - snd_assert(dsp->size % 3 == 0, return -EINVAL); - snd_assert(dsp->data, return -EINVAL); + if (dsp->size <= 0) + return -EINVAL; + if (dsp->size % 3) + return -EINVAL; + if (snd_BUG_ON(!dsp->data)) + return -EINVAL; /* transfert data buffer from PC to DSP */ for (i = 0; i < dsp->size; i += 3) { data = dsp->data + i; if (i == 0) { /* test data header consistency */ len = (unsigned int)((data[0]<<16) + (data[1]<<8) + data[2]); - snd_assert((len==0) || (dsp->size == (len+2)*3), return -EINVAL); + if (len && dsp->size != (len + 2) * 3) + return -EINVAL; } /* wait DSP ready for new transfer */ err = pcxhr_check_reg_bit(mgr, PCXHR_DSP_ISR, PCXHR_ISR_HI08_TRDY, @@ -389,7 +393,8 @@ int pcxhr_load_boot_binary(struct pcxhr_mgr *mgr, const struct firmware *boot) unsigned char dummy; /* send the hostport address to the DSP (only the upper 24 bit !) */ - snd_assert((physaddr & 0xff) == 0, return -EINVAL); + if (snd_BUG_ON(physaddr & 0xff)) + return -EINVAL; PCXHR_OUTPL(mgr, PCXHR_PLX_MBOX1, (physaddr >> 8)); err = pcxhr_send_it_dsp(mgr, PCXHR_IT_DOWNLOAD_BOOT, 0); @@ -570,7 +575,8 @@ static int pcxhr_send_msg_nolock(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh) u32 data; unsigned char reg; - snd_assert(rmh->cmd_lencmd_len >= PCXHR_SIZE_MAX_CMD)) + return -EINVAL; err = pcxhr_send_it_dsp(mgr, PCXHR_IT_MESSAGE, 1); if (err) { snd_printk(KERN_ERR "pcxhr_send_message : ED_DSP_CRASHED\n"); @@ -677,7 +683,8 @@ static int pcxhr_send_msg_nolock(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh) */ void pcxhr_init_rmh(struct pcxhr_rmh *rmh, int cmd) { - snd_assert(cmd < CMD_LAST_INDEX, return); + if (snd_BUG_ON(cmd >= CMD_LAST_INDEX)) + return; rmh->cmd[0] = pcxhr_dsp_cmds[cmd].opcode; rmh->cmd_len = 1; rmh->stat_len = pcxhr_dsp_cmds[cmd].st_length; @@ -690,17 +697,17 @@ void pcxhr_set_pipe_cmd_params(struct pcxhr_rmh *rmh, int capture, unsigned int param1, unsigned int param2, unsigned int param3) { - snd_assert(param1 <= MASK_FIRST_FIELD); + snd_BUG_ON(param1 > MASK_FIRST_FIELD); if (capture) rmh->cmd[0] |= 0x800; /* COMMAND_RECORD_MASK */ if (param1) rmh->cmd[0] |= (param1 << FIELD_SIZE); if (param2) { - snd_assert(param2 <= MASK_FIRST_FIELD); + snd_BUG_ON(param2 > MASK_FIRST_FIELD); rmh->cmd[0] |= param2; } if(param3) { - snd_assert(param3 <= MASK_DSP_WORD); + snd_BUG_ON(param3 > MASK_DSP_WORD); rmh->cmd[1] = param3; rmh->cmd_len = 2; } diff --git a/sound/pci/pcxhr/pcxhr_hwdep.c b/sound/pci/pcxhr/pcxhr_hwdep.c index d2f043278cf..96640d9c227 100644 --- a/sound/pci/pcxhr/pcxhr_hwdep.c +++ b/sound/pci/pcxhr/pcxhr_hwdep.c @@ -65,15 +65,18 @@ static int pcxhr_init_board(struct pcxhr_mgr *mgr) if (err) return err; /* test 8 or 12 phys out */ - snd_assert((rmh.stat[0] & MASK_FIRST_FIELD) == mgr->playback_chips*2, - return -EINVAL); + if ((rmh.stat[0] & MASK_FIRST_FIELD) != mgr->playback_chips * 2) + return -EINVAL; /* test 8 or 2 phys in */ - snd_assert(((rmh.stat[0] >> (2*FIELD_SIZE)) & MASK_FIRST_FIELD) == - mgr->capture_chips * 2, return -EINVAL); + if (((rmh.stat[0] >> (2 * FIELD_SIZE)) & MASK_FIRST_FIELD) != + mgr->capture_chips * 2) + return -EINVAL; /* test max nb substream per board */ - snd_assert((rmh.stat[1] & 0x5F) >= card_streams, return -EINVAL); + if ((rmh.stat[1] & 0x5F) < card_streams) + return -EINVAL; /* test max nb substream per pipe */ - snd_assert(((rmh.stat[1]>>7)&0x5F) >= PCXHR_PLAYBACK_STREAMS, return -EINVAL); + if (((rmh.stat[1] >> 7) & 0x5F) < PCXHR_PLAYBACK_STREAMS) + return -EINVAL; pcxhr_init_rmh(&rmh, CMD_VERSION); /* firmware num for DSP */ diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c index 6a359624734..124f9a2f153 100644 --- a/sound/pci/riptide/riptide.c +++ b/sound/pci/riptide/riptide.c @@ -865,7 +865,8 @@ static int sendcmd(struct cmdif *cif, u32 flags, u32 cmd, u32 parm, struct riptideport *hwport; struct cmdport *cmdport = NULL; - snd_assert(cif, return -EINVAL); + if (snd_BUG_ON(!cif)) + return -EINVAL; hwport = cif->hwport; if (cif->errcnt > MAX_ERROR_COUNT) { @@ -1490,7 +1491,8 @@ static int snd_riptide_prepare(struct snd_pcm_substream *substream) int err = 0; snd_pcm_format_t format; - snd_assert(cif && data, return -EINVAL); + if (snd_BUG_ON(!cif || !data)) + return -EINVAL; snd_printdd("prepare id %d ch: %d f:0x%x r:%d\n", data->id, runtime->channels, runtime->format, runtime->rate); @@ -1772,7 +1774,8 @@ snd_riptide_codec_write(struct snd_ac97 *ac97, unsigned short reg, union cmdret rptr = CMDRET_ZERO; int i = 0; - snd_assert(cif, return); + if (snd_BUG_ON(!cif)) + return; snd_printdd("Write AC97 reg 0x%x 0x%x\n", reg, val); do { @@ -1790,7 +1793,8 @@ static unsigned short snd_riptide_codec_read(struct snd_ac97 *ac97, struct cmdif *cif = chip->cif; union cmdret rptr = CMDRET_ZERO; - snd_assert(cif, return 0); + if (snd_BUG_ON(!cif)) + return 0; if (SEND_RACR(cif, reg, &rptr) != 0) SEND_RACR(cif, reg, &rptr); @@ -1804,7 +1808,8 @@ static int snd_riptide_initialize(struct snd_riptide *chip) unsigned int device_id; int err; - snd_assert(chip, return -EINVAL); + if (snd_BUG_ON(!chip)) + return -EINVAL; cif = chip->cif; if (!cif) { @@ -1836,7 +1841,8 @@ static int snd_riptide_free(struct snd_riptide *chip) { struct cmdif *cif; - snd_assert(chip, return 0); + if (!chip) + return 0; if ((cif = chip->cif)) { SET_GRESET(cif->hwport); diff --git a/sound/pci/rme9652/hdsp.c b/sound/pci/rme9652/hdsp.c index 4d6fbb36ab8..d723543bead 100644 --- a/sound/pci/rme9652/hdsp.c +++ b/sound/pci/rme9652/hdsp.c @@ -1036,7 +1036,7 @@ static void hdsp_set_dds_value(struct hdsp *hdsp, int rate) 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); + snd_BUG_ON(n >> 32); /* HDSP_freqReg and HDSP_resetPointer are the same, so keep the DDS value to write it after a reset */ hdsp->dds_value = n; @@ -3043,7 +3043,7 @@ static int snd_hdsp_get_adat_sync_check(struct snd_kcontrol *kcontrol, struct sn struct hdsp *hdsp = snd_kcontrol_chip(kcontrol); offset = ucontrol->id.index - 1; - snd_assert(offset >= 0); + snd_BUG_ON(offset < 0); switch (hdsp->io_type) { case Digiface: @@ -3767,7 +3767,8 @@ static char *hdsp_channel_buffer_location(struct hdsp *hdsp, { int mapped_channel; - snd_assert(channel >= 0 && channel < hdsp->max_channels, return NULL); + if (snd_BUG_ON(channel < 0 || channel >= hdsp->max_channels)) + return NULL; if ((mapped_channel = hdsp->channel_map[channel]) < 0) return NULL; @@ -3784,10 +3785,12 @@ static int snd_hdsp_playback_copy(struct snd_pcm_substream *substream, int chann struct hdsp *hdsp = snd_pcm_substream_chip(substream); char *channel_buf; - snd_assert(pos + count <= HDSP_CHANNEL_BUFFER_BYTES / 4, return -EINVAL); + if (snd_BUG_ON(pos + count > HDSP_CHANNEL_BUFFER_BYTES / 4)) + return -EINVAL; channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel); - snd_assert(channel_buf != NULL, return -EIO); + if (snd_BUG_ON(!channel_buf)) + return -EIO; if (copy_from_user(channel_buf + pos * 4, src, count * 4)) return -EFAULT; return count; @@ -3799,10 +3802,12 @@ static int snd_hdsp_capture_copy(struct snd_pcm_substream *substream, int channe struct hdsp *hdsp = snd_pcm_substream_chip(substream); char *channel_buf; - snd_assert(pos + count <= HDSP_CHANNEL_BUFFER_BYTES / 4, return -EINVAL); + if (snd_BUG_ON(pos + count > HDSP_CHANNEL_BUFFER_BYTES / 4)) + return -EINVAL; channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel); - snd_assert(channel_buf != NULL, return -EIO); + if (snd_BUG_ON(!channel_buf)) + return -EIO; if (copy_to_user(dst, channel_buf + pos * 4, count * 4)) return -EFAULT; return count; @@ -3815,7 +3820,8 @@ static int snd_hdsp_hw_silence(struct snd_pcm_substream *substream, int channel, char *channel_buf; channel_buf = hdsp_channel_buffer_location (hdsp, substream->pstr->stream, channel); - snd_assert(channel_buf != NULL, return -EIO); + if (snd_BUG_ON(!channel_buf)) + return -EIO; memset(channel_buf + pos * 4, 0, count * 4); return count; } @@ -3927,7 +3933,8 @@ static int snd_hdsp_channel_info(struct snd_pcm_substream *substream, struct hdsp *hdsp = snd_pcm_substream_chip(substream); int mapped_channel; - snd_assert(info->channel < hdsp->max_channels, return -EINVAL); + if (snd_BUG_ON(info->channel >= hdsp->max_channels)) + return -EINVAL; if ((mapped_channel = hdsp->channel_map[info->channel]) < 0) return -EINVAL; diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index ab423bc8234..83c92e6082a 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c @@ -845,7 +845,7 @@ static void hdspm_set_dds_value(struct hdspm *hdspm, int rate) 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); + snd_BUG_ON(n >> 32); hdspm_write(hdspm, HDSPM_freqReg, (u32)n); } @@ -2617,8 +2617,8 @@ static int snd_hdspm_get_playback_mixer(struct snd_kcontrol *kcontrol, channel = ucontrol->id.index - 1; - snd_assert(channel >= 0 - || channel < HDSPM_MAX_CHANNELS, return -EINVAL); + if (snd_BUG_ON(channel < 0 || channel >= HDSPM_MAX_CHANNELS)) + return -EINVAL; mapped_channel = hdspm->channel_map[channel]; if (mapped_channel < 0) @@ -2652,8 +2652,8 @@ static int snd_hdspm_put_playback_mixer(struct snd_kcontrol *kcontrol, channel = ucontrol->id.index - 1; - snd_assert(channel >= 0 - || channel < HDSPM_MAX_CHANNELS, return -EINVAL); + if (snd_BUG_ON(channel < 0 || channel >= HDSPM_MAX_CHANNELS)) + return -EINVAL; mapped_channel = hdspm->channel_map[channel]; if (mapped_channel < 0) @@ -3496,8 +3496,8 @@ static char *hdspm_channel_buffer_location(struct hdspm * hdspm, { int mapped_channel; - snd_assert(channel >= 0 - || channel < HDSPM_MAX_CHANNELS, return NULL); + if (snd_BUG_ON(channel < 0 || channel >= HDSPM_MAX_CHANNELS)) + return NULL; mapped_channel = hdspm->channel_map[channel]; if (mapped_channel < 0) @@ -3520,14 +3520,15 @@ static int snd_hdspm_playback_copy(struct snd_pcm_substream *substream, struct hdspm *hdspm = snd_pcm_substream_chip(substream); char *channel_buf; - snd_assert(pos + count <= HDSPM_CHANNEL_BUFFER_BYTES / 4, - return -EINVAL); + if (snd_BUG_ON(pos + count > HDSPM_CHANNEL_BUFFER_BYTES / 4)) + return -EINVAL; channel_buf = hdspm_channel_buffer_location(hdspm, substream->pstr->stream, channel); - snd_assert(channel_buf != NULL, return -EIO); + if (snd_BUG_ON(!channel_buf)) + return -EIO; return copy_from_user(channel_buf + pos * 4, src, count * 4); } @@ -3539,13 +3540,14 @@ static int snd_hdspm_capture_copy(struct snd_pcm_substream *substream, struct hdspm *hdspm = snd_pcm_substream_chip(substream); char *channel_buf; - snd_assert(pos + count <= HDSPM_CHANNEL_BUFFER_BYTES / 4, - return -EINVAL); + if (snd_BUG_ON(pos + count > HDSPM_CHANNEL_BUFFER_BYTES / 4)) + return -EINVAL; channel_buf = hdspm_channel_buffer_location(hdspm, substream->pstr->stream, channel); - snd_assert(channel_buf != NULL, return -EIO); + if (snd_BUG_ON(!channel_buf)) + return -EIO; return copy_to_user(dst, channel_buf + pos * 4, count * 4); } @@ -3559,7 +3561,8 @@ static int snd_hdspm_hw_silence(struct snd_pcm_substream *substream, channel_buf = hdspm_channel_buffer_location(hdspm, substream->pstr->stream, channel); - snd_assert(channel_buf != NULL, return -EIO); + if (snd_BUG_ON(!channel_buf)) + return -EIO; memset(channel_buf + pos * 4, 0, count * 4); return 0; } @@ -3744,7 +3747,8 @@ static int snd_hdspm_channel_info(struct snd_pcm_substream *substream, struct hdspm *hdspm = snd_pcm_substream_chip(substream); int mapped_channel; - snd_assert(info->channel < HDSPM_MAX_CHANNELS, return -EINVAL); + if (snd_BUG_ON(info->channel >= HDSPM_MAX_CHANNELS)) + return -EINVAL; mapped_channel = hdspm->channel_map[info->channel]; if (mapped_channel < 0) diff --git a/sound/pci/rme9652/rme9652.c b/sound/pci/rme9652/rme9652.c index a123f0e6ba2..2570907134d 100644 --- a/sound/pci/rme9652/rme9652.c +++ b/sound/pci/rme9652/rme9652.c @@ -595,8 +595,6 @@ static void rme9652_set_thru(struct snd_rme9652 *rme9652, int channel, int enabl } else { int mapped_channel; - snd_assert(channel == RME9652_NCHANNELS, return); - mapped_channel = rme9652->channel_map[channel]; if (enable) { @@ -1893,7 +1891,8 @@ static char *rme9652_channel_buffer_location(struct snd_rme9652 *rme9652, { int mapped_channel; - snd_assert(channel >= 0 || channel < RME9652_NCHANNELS, return NULL); + if (snd_BUG_ON(channel < 0 || channel >= RME9652_NCHANNELS)) + return NULL; if ((mapped_channel = rme9652->channel_map[channel]) < 0) { return NULL; @@ -1914,12 +1913,14 @@ static int snd_rme9652_playback_copy(struct snd_pcm_substream *substream, int ch struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream); char *channel_buf; - snd_assert(pos + count <= RME9652_CHANNEL_BUFFER_BYTES / 4, return -EINVAL); + if (snd_BUG_ON(pos + count > RME9652_CHANNEL_BUFFER_BYTES / 4)) + return -EINVAL; channel_buf = rme9652_channel_buffer_location (rme9652, substream->pstr->stream, channel); - snd_assert(channel_buf != NULL, return -EIO); + if (snd_BUG_ON(!channel_buf)) + return -EIO; if (copy_from_user(channel_buf + pos * 4, src, count * 4)) return -EFAULT; return count; @@ -1931,12 +1932,14 @@ static int snd_rme9652_capture_copy(struct snd_pcm_substream *substream, int cha struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream); char *channel_buf; - snd_assert(pos + count <= RME9652_CHANNEL_BUFFER_BYTES / 4, return -EINVAL); + if (snd_BUG_ON(pos + count > RME9652_CHANNEL_BUFFER_BYTES / 4)) + return -EINVAL; channel_buf = rme9652_channel_buffer_location (rme9652, substream->pstr->stream, channel); - snd_assert(channel_buf != NULL, return -EIO); + if (snd_BUG_ON(!channel_buf)) + return -EIO; if (copy_to_user(dst, channel_buf + pos * 4, count * 4)) return -EFAULT; return count; @@ -1951,7 +1954,8 @@ static int snd_rme9652_hw_silence(struct snd_pcm_substream *substream, int chann channel_buf = rme9652_channel_buffer_location (rme9652, substream->pstr->stream, channel); - snd_assert(channel_buf != NULL, return -EIO); + if (snd_BUG_ON(!channel_buf)) + return -EIO; memset(channel_buf + pos * 4, 0, count * 4); return count; } @@ -2053,7 +2057,8 @@ static int snd_rme9652_channel_info(struct snd_pcm_substream *substream, struct snd_rme9652 *rme9652 = snd_pcm_substream_chip(substream); int chn; - snd_assert(info->channel < RME9652_NCHANNELS, return -EINVAL); + if (snd_BUG_ON(info->channel >= RME9652_NCHANNELS)) + return -EINVAL; if ((chn = rme9652->channel_map[info->channel]) < 0) { return -EINVAL; diff --git a/sound/pci/sonicvibes.c b/sound/pci/sonicvibes.c index 0d3d305b0a0..cd408b86c83 100644 --- a/sound/pci/sonicvibes.c +++ b/sound/pci/sonicvibes.c @@ -534,8 +534,8 @@ static int snd_sonicvibes_hw_constraint_dac_rate(struct snd_pcm_hw_params *param params->rate_den = 1; } else { snd_sonicvibes_pll(rate, &r, &m, &n); - snd_assert((SV_REFFREQUENCY % 16) == 0, return -EINVAL); - snd_assert((SV_ADCMULT % 512) == 0, return -EINVAL); + snd_BUG_ON(SV_REFFREQUENCY % 16); + snd_BUG_ON(SV_ADCMULT % 512); params->rate_num = (SV_REFFREQUENCY/16) * (n+2) * r; params->rate_den = (SV_ADCMULT/512) * (m+2); } @@ -849,7 +849,8 @@ static int __devinit snd_sonicvibes_pcm(struct sonicvibes * sonic, int device, s if ((err = snd_pcm_new(sonic->card, "s3_86c617", device, 1, 1, &pcm)) < 0) return err; - snd_assert(pcm != NULL, return -EINVAL); + if (snd_BUG_ON(!pcm)) + return -EINVAL; snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_sonicvibes_playback_ops); snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_sonicvibes_capture_ops); @@ -1089,7 +1090,8 @@ static int __devinit snd_sonicvibes_mixer(struct sonicvibes * sonic) unsigned int idx; int err; - snd_assert(sonic != NULL && sonic->card != NULL, return -EINVAL); + if (snd_BUG_ON(!sonic || !sonic->card)) + return -EINVAL; card = sonic->card; strcpy(card->mixername, "S3 SonicVibes"); diff --git a/sound/pci/trident/trident_main.c b/sound/pci/trident/trident_main.c index a69b4206c69..c612b435ca2 100644 --- a/sound/pci/trident/trident_main.c +++ b/sound/pci/trident/trident_main.c @@ -2931,7 +2931,8 @@ static int snd_trident_pcm_mixer_build(struct snd_trident *trident, { struct snd_trident_pcm_mixer *tmix; - snd_assert(trident != NULL && voice != NULL && substream != NULL, return -EINVAL); + if (snd_BUG_ON(!trident || !voice || !substream)) + return -EINVAL; tmix = &trident->pcm_mixer[substream->number]; tmix->voice = voice; tmix->vol = T4D_DEFAULT_PCM_VOL; @@ -2946,7 +2947,8 @@ static int snd_trident_pcm_mixer_free(struct snd_trident *trident, struct snd_tr { struct snd_trident_pcm_mixer *tmix; - snd_assert(trident != NULL && substream != NULL, return -EINVAL); + if (snd_BUG_ON(!trident || !substream)) + return -EINVAL; tmix = &trident->pcm_mixer[substream->number]; tmix->voice = NULL; snd_trident_notify_pcm_change(trident, tmix, substream->number, 0); @@ -3131,7 +3133,8 @@ static unsigned char snd_trident_gameport_read(struct gameport *gameport) { struct snd_trident *chip = gameport_get_port_data(gameport); - snd_assert(chip, return 0); + if (snd_BUG_ON(!chip)) + return 0; return inb(TRID_REG(chip, GAMEPORT_LEGACY)); } @@ -3139,7 +3142,8 @@ static void snd_trident_gameport_trigger(struct gameport *gameport) { struct snd_trident *chip = gameport_get_port_data(gameport); - snd_assert(chip, return); + if (snd_BUG_ON(!chip)) + return; outb(0xff, TRID_REG(chip, GAMEPORT_LEGACY)); } @@ -3148,7 +3152,8 @@ static int snd_trident_gameport_cooked_read(struct gameport *gameport, int *axes struct snd_trident *chip = gameport_get_port_data(gameport); int i; - snd_assert(chip, return 0); + if (snd_BUG_ON(!chip)) + return 0; *buttons = (~inb(TRID_REG(chip, GAMEPORT_LEGACY)) >> 4) & 0xf; @@ -3164,7 +3169,8 @@ static int snd_trident_gameport_open(struct gameport *gameport, int mode) { struct snd_trident *chip = gameport_get_port_data(gameport); - snd_assert(chip, return 0); + if (snd_BUG_ON(!chip)) + return 0; switch (mode) { case GAMEPORT_MODE_COOKED: @@ -3891,8 +3897,8 @@ static void snd_trident_clear_voices(struct snd_trident * trident, unsigned shor { unsigned int i, val, mask[2] = { 0, 0 }; - snd_assert(v_min <= 63, return); - snd_assert(v_max <= 63, return); + if (snd_BUG_ON(v_min > 63 || v_max > 63)) + return; for (i = v_min; i <= v_max; i++) mask[i >> 5] |= 1 << (i & 0x1f); if (mask[0]) { diff --git a/sound/pci/trident/trident_memory.c b/sound/pci/trident/trident_memory.c index 3fd7f1b29b0..2fe3b1fab53 100644 --- a/sound/pci/trident/trident_memory.c +++ b/sound/pci/trident/trident_memory.c @@ -196,9 +196,13 @@ snd_trident_alloc_sg_pages(struct snd_trident *trident, int idx, page; struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream); - snd_assert(runtime->dma_bytes > 0 && runtime->dma_bytes <= SNDRV_TRIDENT_MAX_PAGES * SNDRV_TRIDENT_PAGE_SIZE, return NULL); + if (snd_BUG_ON(runtime->dma_bytes <= 0 || + runtime->dma_bytes > SNDRV_TRIDENT_MAX_PAGES * + SNDRV_TRIDENT_PAGE_SIZE)) + return NULL; hdr = trident->tlb.memhdr; - snd_assert(hdr != NULL, return NULL); + if (snd_BUG_ON(!hdr)) + return NULL; @@ -245,9 +249,13 @@ snd_trident_alloc_cont_pages(struct snd_trident *trident, dma_addr_t addr; unsigned long ptr; - snd_assert(runtime->dma_bytes> 0 && runtime->dma_bytes <= SNDRV_TRIDENT_MAX_PAGES * SNDRV_TRIDENT_PAGE_SIZE, return NULL); + if (snd_BUG_ON(runtime->dma_bytes <= 0 || + runtime->dma_bytes > SNDRV_TRIDENT_MAX_PAGES * + SNDRV_TRIDENT_PAGE_SIZE)) + return NULL; hdr = trident->tlb.memhdr; - snd_assert(hdr != NULL, return NULL); + if (snd_BUG_ON(!hdr)) + return NULL; mutex_lock(&hdr->block_mutex); blk = search_empty(hdr, runtime->dma_bytes); @@ -279,8 +287,8 @@ struct snd_util_memblk * snd_trident_alloc_pages(struct snd_trident *trident, struct snd_pcm_substream *substream) { - snd_assert(trident != NULL, return NULL); - snd_assert(substream != NULL, return NULL); + if (snd_BUG_ON(!trident || !substream)) + return NULL; if (substream->dma_buffer.dev.type == SNDRV_DMA_TYPE_DEV_SG) return snd_trident_alloc_sg_pages(trident, substream); else @@ -297,8 +305,8 @@ int snd_trident_free_pages(struct snd_trident *trident, struct snd_util_memhdr *hdr; int page; - snd_assert(trident != NULL, return -EINVAL); - snd_assert(blk != NULL, return -EINVAL); + if (snd_BUG_ON(!trident || !blk)) + return -EINVAL; hdr = trident->tlb.memhdr; mutex_lock(&hdr->block_mutex); diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c index 6781be9e307..84ea35d8b25 100644 --- a/sound/pci/via82xx.c +++ b/sound/pci/via82xx.c @@ -824,7 +824,8 @@ static snd_pcm_uframes_t snd_via686_pcm_pointer(struct snd_pcm_substream *substr struct viadev *viadev = substream->runtime->private_data; unsigned int idx, ptr, count, res; - snd_assert(viadev->tbl_entries, return 0); + if (snd_BUG_ON(!viadev->tbl_entries)) + return 0; if (!(inb(VIADEV_REG(viadev, OFFSET_STATUS)) & VIA_REG_STAT_ACTIVE)) return 0; @@ -855,7 +856,8 @@ static snd_pcm_uframes_t snd_via8233_pcm_pointer(struct snd_pcm_substream *subst unsigned int idx, count, res; int status; - snd_assert(viadev->tbl_entries, return 0); + if (snd_BUG_ON(!viadev->tbl_entries)) + return 0; spin_lock(&chip->reg_lock); count = inl(VIADEV_REG(viadev, OFFSET_CURR_COUNT)); @@ -1037,7 +1039,7 @@ static int snd_via8233_playback_prepare(struct snd_pcm_substream *substream) else rbits = (0x100000 / 48000) * runtime->rate + ((0x100000 % 48000) * runtime->rate) / 48000; - snd_assert((rbits & ~0xfffff) == 0, return -EINVAL); + snd_BUG_ON(rbits & ~0xfffff); snd_via82xx_channel_reset(chip, viadev); snd_via82xx_set_table_ptr(chip, viadev); outb(chip->playback_volume[viadev->reg_offset / 0x10][0], diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c index 31f64ee3988..640c338ce0a 100644 --- a/sound/pci/via82xx_modem.c +++ b/sound/pci/via82xx_modem.c @@ -612,7 +612,8 @@ static snd_pcm_uframes_t snd_via686_pcm_pointer(struct snd_pcm_substream *substr struct viadev *viadev = substream->runtime->private_data; unsigned int idx, ptr, count, res; - snd_assert(viadev->tbl_entries, return 0); + if (snd_BUG_ON(!viadev->tbl_entries)) + return 0; if (!(inb(VIADEV_REG(viadev, OFFSET_STATUS)) & VIA_REG_STAT_ACTIVE)) return 0; diff --git a/sound/pci/vx222/vx222_ops.c b/sound/pci/vx222/vx222_ops.c index 631f3a63999..7e87f398ff0 100644 --- a/sound/pci/vx222/vx222_ops.c +++ b/sound/pci/vx222/vx222_ops.c @@ -253,7 +253,8 @@ static void vx2_dma_write(struct vx_core *chip, struct snd_pcm_runtime *runtime, int offset = pipe->hw_ptr; u32 *addr = (u32 *)(runtime->dma_area + offset); - snd_assert(count % 4 == 0, return); + if (snd_BUG_ON(count % 4)) + return; vx2_setup_pseudo_dma(chip, 1); @@ -291,7 +292,8 @@ static void vx2_dma_read(struct vx_core *chip, struct snd_pcm_runtime *runtime, u32 *addr = (u32 *)(runtime->dma_area + offset); unsigned long port = vx2_reg_addr(chip, VX_DMA); - snd_assert(count % 4 == 0, return); + if (snd_BUG_ON(count % 4)) + return; vx2_setup_pseudo_dma(chip, 0); /* Transfer using pseudo-dma. @@ -675,7 +677,8 @@ static void vx2_write_akm(struct vx_core *chip, int reg, unsigned int data) a look up table, as there is no linear matching between the driver codec values and the real dBu value */ - snd_assert(data < sizeof(vx2_akm_gains_lut), return); + if (snd_BUG_ON(data >= sizeof(vx2_akm_gains_lut))) + return; switch (reg) { case XX_CODEC_LEVEL_LEFT_REGISTER: @@ -823,7 +826,8 @@ static void vx2_set_input_level(struct snd_vx222 *chip) preamp++; /* raise pre ampli + 18dB */ miclevel -= (18 * 2); /* lower level 18 dB (*2 because of 0.5 dB steps !) */ } - snd_assert(preamp < 4, return); + if (snd_BUG_ON(preamp >= 4)) + return; /* set pre-amp level */ chip->regSELMIC &= ~MICRO_SELECT_PREAMPLI_MASK; diff --git a/sound/pci/ymfpci/ymfpci_main.c b/sound/pci/ymfpci/ymfpci_main.c index 92d49aadf57..90d0d62bd0b 100644 --- a/sound/pci/ymfpci/ymfpci_main.c +++ b/sound/pci/ymfpci/ymfpci_main.c @@ -259,8 +259,10 @@ static int snd_ymfpci_voice_alloc(struct snd_ymfpci *chip, unsigned long flags; int result; - snd_assert(rvoice != NULL, return -EINVAL); - snd_assert(!pair || type == YMFPCI_PCM, return -EINVAL); + if (snd_BUG_ON(!rvoice)) + return -EINVAL; + if (snd_BUG_ON(pair && type != YMFPCI_PCM)) + return -EINVAL; spin_lock_irqsave(&chip->voice_lock, flags); for (;;) { @@ -278,7 +280,8 @@ static int snd_ymfpci_voice_free(struct snd_ymfpci *chip, struct snd_ymfpci_voic { unsigned long flags; - snd_assert(pvoice != NULL, return -EINVAL); + if (snd_BUG_ON(!pvoice)) + return -EINVAL; snd_ymfpci_hw_stop(chip); spin_lock_irqsave(&chip->voice_lock, flags); if (pvoice->number == chip->src441_used) { @@ -494,7 +497,8 @@ static void snd_ymfpci_pcm_init_voice(struct snd_ymfpci_pcm *ypcm, unsigned int u8 use_left, use_right; unsigned long flags; - snd_assert(voice != NULL, return); + if (snd_BUG_ON(!voice)) + return; if (runtime->channels == 1) { use_left = 1; use_right = 1; @@ -1813,7 +1817,8 @@ int __devinit snd_ymfpci_mixer(struct snd_ymfpci *chip, int rear_switch) } /* add S/PDIF control */ - snd_assert(chip->pcm_spdif != NULL, return -EIO); + if (snd_BUG_ON(!chip->pcm_spdif)) + return -ENXIO; if ((err = snd_ctl_add(chip->card, kctl = snd_ctl_new1(&snd_ymfpci_spdif_default, chip))) < 0) return err; kctl->id.device = chip->pcm_spdif->device; @@ -2133,7 +2138,8 @@ static int __devinit snd_ymfpci_memalloc(struct snd_ymfpci *chip) chip->work_base = ptr; chip->work_base_addr = ptr_addr; - snd_assert(ptr + chip->work_size == chip->work_ptr.area + chip->work_ptr.bytes, ); + snd_BUG_ON(ptr + chip->work_size != + chip->work_ptr.area + chip->work_ptr.bytes); snd_ymfpci_writel(chip, YDSXGR_PLAYCTRLBASE, chip->bank_base_playback_addr); snd_ymfpci_writel(chip, YDSXGR_RECCTRLBASE, chip->bank_base_capture_addr); @@ -2168,7 +2174,8 @@ static int snd_ymfpci_free(struct snd_ymfpci *chip) { u16 ctrl; - snd_assert(chip != NULL, return -EINVAL); + if (snd_BUG_ON(!chip)) + return -EINVAL; if (chip->res_reg_area) { /* don't touch busy hardware */ snd_ymfpci_writel(chip, YDSXGR_NATIVEDACOUTVOL, 0); -- cgit v1.2.3 From faa09c932c5e1daf5fa40a0ff3d895ad57c5a61d Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Mon, 11 Aug 2008 02:09:04 +0400 Subject: ALSA: ice1724/revo: simple clean up ice1724/revo: simple clean up Signed-off-by: Alexander Beregalov Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/ice1712/revo.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/ice1712/revo.c b/sound/pci/ice1712/revo.c index 4d2631434dc..5e1b156bfaa 100644 --- a/sound/pci/ice1712/revo.c +++ b/sound/pci/ice1712/revo.c @@ -524,16 +524,20 @@ static int __devinit revo_init(struct snd_ice1712 *ice) ak = ice->akm = kcalloc(2, sizeof(struct snd_akm4xxx), GFP_KERNEL); if (! ak) return -ENOMEM; - ice->akm_codecs = 2; switch (ice->eeprom.subvendor) { case VT1724_SUBDEVICE_REVOLUTION71: ice->akm_codecs = 2; - if ((err = snd_ice1712_akm4xxx_init(ak, &akm_revo_front, &akm_revo_front_priv, ice)) < 0) + err = snd_ice1712_akm4xxx_init(ak, &akm_revo_front, + &akm_revo_front_priv, ice); + if (err < 0) return err; - if ((err = snd_ice1712_akm4xxx_init(ak + 1, &akm_revo_surround, &akm_revo_surround_priv, ice)) < 0) + err = snd_ice1712_akm4xxx_init(ak+1, &akm_revo_surround, + &akm_revo_surround_priv, ice); + if (err < 0) return err; /* unmute all codecs */ - snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE, VT1724_REVO_MUTE); + snd_ice1712_gpio_write_bits(ice, VT1724_REVO_MUTE, + VT1724_REVO_MUTE); break; case VT1724_SUBDEVICE_REVOLUTION51: ice->akm_codecs = 2; -- cgit v1.2.3 From 6e8d90cd3418f18f3913c8ae558eee1ba21e4d6c Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Mon, 11 Aug 2008 02:52:42 +0400 Subject: ALSA: sound/pci/Kconfig: update for ice1712/24 sound/pci/Kconfig: update for ice1712/24 Signed-off-by: Alexander Beregalov Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/Kconfig | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index db9e31fd061..4a7ebbc9676 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -657,8 +657,9 @@ config SND_ICE1712 Currently supported hardware is: M-Audio Delta 1010(LT), DiO 2496, 66, 44, 410, Audiophile 24/96; Digigram VX442; - TerraTec EWX 24/96, EWS 88MT, 88D, DMX 6Fire, Phase 88; - Hoontech SoundTrack DSP 24/Value/Media7.1; Event EZ8. + TerraTec EWX 24/96, EWS 88MT/D, DMX 6Fire, Phase 88; + Hoontech SoundTrack DSP 24/Value/Media7.1; Event EZ8; + Lionstracs Mediastation, Terrasoniq TS 88. To compile this driver as a module, choose M here: the module will be called snd-ice1712. @@ -673,9 +674,12 @@ config SND_ICE1724 ICE/VT1724/1720 (Envy24HT/PT) chips. Currently supported hardware is: AMP AUDIO2000; M-Audio - Revolution 7.1; TerraTec Aureon 5.1 Sky, 7.1 Space/Universe; - AudioTrak Prodigy 7.1; Pontis MS300; Albatron K8X800 Pro II; - Chaintech ZNF3-150/250. + Revolution 5.1, 7.1, Audiophile 192; TerraTec Aureon 5.1 Sky, + 7.1 Space/Universe, Phase 22/28; Onkyo SE-90PCI, SE-200PCI; + AudioTrak Prodigy 192, 7.1 (HIFI/LT/XT), HD2; Hercules + Fortissimo IV; ESI Juli@; Pontis MS300; EGO-SYS WaveTerminal + 192M; Albatron K8X800 Pro II; Chaintech ZNF3-150/250, 9CJS, + AV-710; Shuttle SN25P. To compile this driver as a module, choose M here: the module will be called snd-ice1724. -- cgit v1.2.3 From 963f803fb1bbce87f6049c22c737ae379e1047d3 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 11 Aug 2008 10:04:40 +0200 Subject: ALSA: hda - Don't reset SPDIF in each status change The SPDIF output is toggled at each time any SPDIF status bits are changed because of the known problems on some codecs. But, this also results in loosing the sync, and the problem is more obvious on HDMI output over SPDIF. Since the toggle is necessary only for some codecs, we should check whether this workaround is needed and skip if unnecessary. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_codec.c | 4 ++-- sound/pci/hda/hda_codec.h | 5 +++++ sound/pci/hda/patch_realtek.c | 2 ++ 3 files changed, 9 insertions(+), 2 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 77fbcd4a69b..529bd5f6521 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -2590,12 +2590,12 @@ 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) + if (codec->spdif_status_reset && (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) + if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, codec->spdif_ctls & 0xff); } diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 2f112626f24..aeee5816153 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -654,6 +654,11 @@ struct hda_codec { struct snd_hwdep *hwdep; /* assigned hwdep device */ + /* misc flags */ + unsigned int spdif_status_reset :1; /* needs to toggle SPDIF for each + * status change + * (e.g. Realtek codecs) + */ #ifdef CONFIG_SND_HDA_POWER_SAVE unsigned int power_on :1; /* current (global) power-state */ unsigned int power_transition :1; /* power-state in transition */ diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 7e5422f64ca..8bff732958e 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -2670,6 +2670,8 @@ static int alc_build_pcms(struct hda_codec *codec) info->stream[SNDRV_PCM_STREAM_CAPTURE] = *(spec->stream_digital_capture); info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid; } + /* FIXME: do we need this for all Realtek codec models? */ + codec->spdif_status_reset = 1; } /* If the use of more than one ADC is requested for the current -- cgit v1.2.3 From db3da6c135c6f5fffed7cca53381b52f2f2d7b53 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 11 Aug 2008 18:08:54 +0200 Subject: ALSA: hda - initialize node 0x21 properly on AD1988 codecs The widget node 0x21 should be initialized as unmuted/full (0dB) as default. This will reduce additional manual work by user at the first time use. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_analog.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index e8003d99f0b..b6d64cc0787 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -2207,6 +2207,8 @@ static struct hda_verb ad1988_6stack_init_verbs[] = { {0x34, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Analog CD Input */ {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, + /* Analog Mix output amp */ + {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */ { } }; @@ -2336,6 +2338,8 @@ static struct hda_verb ad1988_3stack_init_verbs[] = { {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, + /* Analog Mix output amp */ + {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */ { } }; @@ -2409,6 +2413,8 @@ static struct hda_verb ad1988_laptop_init_verbs[] = { {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, + /* Analog Mix output amp */ + {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */ { } }; -- cgit v1.2.3 From a2854dc5f0e1145a38e10c67064a776d84e56f5d Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Wed, 13 Aug 2008 12:36:21 +0400 Subject: ALSA: sound/pci: supported cards update sound/pci: supported cards update Signed-off-by: Alexander Beregalov Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/ice1712/delta.h | 1 + sound/pci/intel8x0.c | 6 ++++++ 2 files changed, 7 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/ice1712/delta.h b/sound/pci/ice1712/delta.h index ea7116c304c..f7f14df81f2 100644 --- a/sound/pci/ice1712/delta.h +++ b/sound/pci/ice1712/delta.h @@ -31,6 +31,7 @@ "{MidiMan M Audio,Delta DiO 2496},"\ "{MidiMan M Audio,Delta 66},"\ "{MidiMan M Audio,Delta 44},"\ + "{MidiMan M Audio,Delta 410},"\ "{MidiMan M Audio,Audiophile 24/96},"\ "{Digigram,VX442},"\ "{Lionstracs,Mediastation}," diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 78760996632..73ad5899536 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c @@ -59,6 +59,12 @@ MODULE_SUPPORTED_DEVICE("{{Intel,82801AA-ICH}," "{SiS,SI7012}," "{NVidia,nForce Audio}," "{NVidia,nForce2 Audio}," + "{NVidia,nForce3 Audio}," + "{NVidia,MCP04}," + "{NVidia,MCP501}," + "{NVidia,CK804}," + "{NVidia,CK8}," + "{NVidia,CK8S}," "{AMD,AMD768}," "{AMD,AMD8111}," "{ALI,M5455}}"); -- cgit v1.2.3 From ba443687f2eb70d23e0466d4b7c0c3366b5cb5fb Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Wed, 13 Aug 2008 20:55:32 +0200 Subject: ALSA: hda - put all HDA codec IDs to components for precise hw detection Export HDA codec subvendor ID and revision ID to user space via the components variable. Our alsactl utility requires these values for the perfect hardware identification. Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_codec.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 529bd5f6521..4f329115080 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -588,7 +588,7 @@ 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]; + char component[31]; int err; if (snd_BUG_ON(!bus)) @@ -693,7 +693,7 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, snd_hda_create_hwdep(codec); #endif - sprintf(component, "HDA:%08x", codec->vendor_id); + sprintf(component, "HDA:%08x,%08x,%08x", codec->vendor_id, codec->subsystem_id, codec->revision_id); snd_component_add(codec->bus->card, component); if (codecp) -- cgit v1.2.3 From 4682eee0ed64a50668c8645f136972e53fcf5a0a Mon Sep 17 00:00:00 2001 From: Matthew Ranostay Date: Fri, 15 Aug 2008 07:43:24 +0200 Subject: ALSA: hda: dynamically create capture mux controls Dynamically create capture mux volume controls when a output amp is detected. Signed-off-by: Matthew Ranostay Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 52 +++++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 16 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index fac6b3ca5fe..75112e4b796 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -795,7 +795,6 @@ static struct snd_kcontrol_new stac9200_mixer[] = { STAC_INPUT_SOURCE(1), HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT), HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Capture Mux Volume", 0x0c, 0, HDA_OUTPUT), { } /* end */ }; @@ -909,12 +908,9 @@ static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = { HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_IDX("Capture Mux Volume", 0x0, 0x1a, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1d, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1d, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_IDX("Capture Mux Volume", 0x1, 0x1b, 0x0, HDA_OUTPUT), - /* analog pc-beep replaced with digital beep support */ /* HDA_CODEC_VOLUME("PC Beep Volume", 0x17, 0x2, HDA_INPUT), @@ -932,11 +928,9 @@ static struct snd_kcontrol_new stac92hd71bxx_mixer[] = { HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_IDX("Capture Mux Volume", 0x0, 0x1a, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1d, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1d, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_IDX("Capture Mux Volume", 0x1, 0x1b, 0x0, HDA_OUTPUT), { } /* end */ }; @@ -944,7 +938,6 @@ static struct snd_kcontrol_new stac925x_mixer[] = { STAC_INPUT_SOURCE(1), HDA_CODEC_VOLUME("Capture Volume", 0x09, 0, HDA_OUTPUT), HDA_CODEC_MUTE("Capture Switch", 0x14, 0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Capture Mux Volume", 0x0f, 0, HDA_OUTPUT), { } /* end */ }; @@ -954,12 +947,9 @@ static struct snd_kcontrol_new stac9205_mixer[] = { HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1b, 0x0, HDA_INPUT), HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1d, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x0, 0x19, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x1c, 0x0, HDA_INPUT), HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1e, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x1, 0x1A, 0x0, HDA_OUTPUT), - { } /* end */ }; @@ -968,11 +958,9 @@ static struct snd_kcontrol_new stac922x_mixer[] = { STAC_INPUT_SOURCE(2), HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_INPUT), HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x0, 0x12, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x18, 0x0, HDA_INPUT), HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x18, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x1, 0x13, 0x0, HDA_OUTPUT), { } /* end */ }; @@ -983,15 +971,12 @@ static struct snd_kcontrol_new stac927x_mixer[] = { HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x18, 0x0, HDA_INPUT), HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1b, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x0, 0x15, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x19, 0x0, HDA_INPUT), HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x1c, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x1, 0x16, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME_IDX("Capture Volume", 0x2, 0x1A, 0x0, HDA_INPUT), HDA_CODEC_MUTE_IDX("Capture Switch", 0x2, 0x1d, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME_IDX("Mux Capture Volume", 0x2, 0x17, 0x0, HDA_OUTPUT), { } /* end */ }; @@ -2352,7 +2337,8 @@ static struct snd_kcontrol_new stac92xx_control_templates[] = { }; /* add dynamic controls */ -static int stac92xx_add_control(struct sigmatel_spec *spec, int type, const char *name, unsigned long val) +static int stac92xx_add_control_idx(struct sigmatel_spec *spec, int type, + int idx, const char *name, unsigned long val) { struct snd_kcontrol_new *knew; @@ -2372,6 +2358,7 @@ static int stac92xx_add_control(struct sigmatel_spec *spec, int type, const char knew = &spec->kctl_alloc[spec->num_kctl_used]; *knew = stac92xx_control_templates[type]; + knew->index = idx; knew->name = kstrdup(name, GFP_KERNEL); if (! knew->name) return -ENOMEM; @@ -2380,6 +2367,14 @@ static int stac92xx_add_control(struct sigmatel_spec *spec, int type, const char return 0; } + +/* add dynamic controls */ +static int stac92xx_add_control(struct sigmatel_spec *spec, int type, + const char *name, unsigned long val) +{ + return stac92xx_add_control_idx(spec, type, 0, name, val); +} + /* flag inputs as additional dynamic lineouts */ static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cfg *cfg) { @@ -2781,6 +2776,26 @@ static int stac92xx_auto_create_beep_ctls(struct hda_codec *codec, return 0; } +static int stac92xx_auto_create_mux_input_ctls(struct hda_codec *codec) +{ + struct sigmatel_spec *spec = codec->spec; + int wcaps, nid, i, err = 0; + + for (i = 0; i < spec->num_muxes; i++) { + nid = spec->mux_nids[i]; + wcaps = get_wcaps(codec, nid); + + if (wcaps & AC_WCAP_OUT_AMP) { + err = stac92xx_add_control_idx(spec, + STAC_CTL_WIDGET_VOL, i, "Mux Capture Volume", + HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); + if (err < 0) + return err; + } + } + return 0; +}; + /* labels for dmic mux inputs */ static const char *stac92xx_dmic_labels[5] = { "Analog Inputs", "Digital Mic 1", "Digital Mic 2", @@ -3079,6 +3094,11 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out if ((err = stac92xx_auto_create_dmic_input_ctls(codec, &spec->autocfg)) < 0) return err; + if (spec->num_muxes > 0) { + err = stac92xx_auto_create_mux_input_ctls(codec); + if (err < 0) + return err; + } spec->multiout.max_channels = spec->multiout.num_dacs * 2; if (spec->multiout.max_channels > 2) -- cgit v1.2.3 From 8daaaa97d6420c7e8b02c12ce591bb29fd959c62 Mon Sep 17 00:00:00 2001 From: Matthew Ranostay Date: Fri, 15 Aug 2008 07:45:52 +0200 Subject: ALSA: hda: 92HD75xx fixes Fixed several noise issues with DACs and ADCs on some 92HD75xxx based codecs with certain revision id's. Signed-off-by: Matthew Ranostay Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 87 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 82 insertions(+), 5 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 75112e4b796..c72c748322a 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -145,6 +145,9 @@ struct sigmatel_spec { unsigned int gpio_data; unsigned int gpio_mute; + /* stream */ + unsigned int stream_delay; + /* analog loopback */ unsigned char aloopback_mask; unsigned char aloopback_shift; @@ -190,6 +193,7 @@ struct sigmatel_spec { unsigned int cur_dmux[2]; struct hda_input_mux *input_mux; unsigned int cur_mux[3]; + unsigned int powerdown_adcs; /* i/o switches */ unsigned int io_switch[2]; @@ -1996,6 +2000,8 @@ static int stac92xx_playback_pcm_open(struct hda_pcm_stream *hinfo, struct snd_pcm_substream *substream) { struct sigmatel_spec *spec = codec->spec; + if (spec->stream_delay) + msleep(spec->stream_delay); return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, hinfo); } @@ -2059,9 +2065,14 @@ static int stac92xx_capture_pcm_prepare(struct hda_pcm_stream *hinfo, struct snd_pcm_substream *substream) { struct sigmatel_spec *spec = codec->spec; + hda_nid_t nid = spec->adc_nids[substream->number]; - snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], - stream_tag, 0, format); + if (spec->powerdown_adcs) { + msleep(40); + snd_hda_codec_write_cache(codec, nid, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D0); + } + snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format); return 0; } @@ -2070,8 +2081,12 @@ static int stac92xx_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, struct snd_pcm_substream *substream) { struct sigmatel_spec *spec = codec->spec; + hda_nid_t nid = spec->adc_nids[substream->number]; - snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]); + snd_hda_codec_cleanup_stream(codec, nid); + if (spec->powerdown_adcs) + snd_hda_codec_write_cache(codec, nid, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D3); return 0; } @@ -3296,6 +3311,12 @@ static int stac92xx_init(struct hda_codec *codec) snd_hda_sequence_write(codec, spec->init); + /* power down adcs initially */ + if (spec->powerdown_adcs) + for (i = 0; i < spec->num_adcs; i++) + snd_hda_codec_write_cache(codec, + spec->adc_nids[i], 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D3); /* set up pins */ if (spec->hp_detect) { /* Enable unsolicited responses on the HP widget */ @@ -3930,6 +3951,47 @@ again: return 0; } +#ifdef SND_HDA_NEEDS_RESUME +static void stac92hd71xx_set_power_state(struct hda_codec *codec, int pwr) +{ + struct sigmatel_spec *spec = codec->spec; + int i; + snd_hda_codec_write_cache(codec, codec->afg, 0, + AC_VERB_SET_POWER_STATE, pwr); + + msleep(1); + for (i = 0; i < spec->num_adcs; i++) { + snd_hda_codec_write_cache(codec, + spec->adc_nids[i], 0, + AC_VERB_SET_POWER_STATE, pwr); + } +}; + +static int stac92hd71xx_resume(struct hda_codec *codec) +{ + stac92hd71xx_set_power_state(codec, AC_PWRST_D0); + return stac92xx_resume(codec); +} + +static int stac92hd71xx_suspend(struct hda_codec *codec, pm_message_t state) +{ + stac92hd71xx_set_power_state(codec, AC_PWRST_D3); + return 0; +}; + +#endif + +static struct hda_codec_ops stac92hd71bxx_patch_ops = { + .build_controls = stac92xx_build_controls, + .build_pcms = stac92xx_build_pcms, + .init = stac92xx_init, + .free = stac92xx_free, + .unsol_event = stac92xx_unsol_event, +#ifdef SND_HDA_NEEDS_RESUME + .resume = stac92hd71xx_resume, + .suspend = stac92hd71xx_suspend, +#endif +}; static int patch_stac92hd71bxx(struct hda_codec *codec) { @@ -3941,6 +4003,7 @@ static int patch_stac92hd71bxx(struct hda_codec *codec) return -ENOMEM; codec->spec = spec; + codec->patch_ops = stac92xx_patch_ops; spec->num_pins = ARRAY_SIZE(stac92hd71bxx_pin_nids); spec->num_pwrs = ARRAY_SIZE(stac92hd71bxx_pwr_nids); spec->pin_nids = stac92hd71bxx_pin_nids; @@ -3972,6 +4035,14 @@ again: spec->init = stac92hd71bxx_core_init; break; case 0x111d7608: /* 5 Port with Analog Mixer */ + if ((codec->revision_id & 0xf) == 0 || + (codec->revision_id & 0xf) == 1) { +#ifdef SND_HDA_NEEDS_RESUME + codec->patch_ops = stac92hd71bxx_patch_ops; +#endif + spec->stream_delay = 40; /* 40 milliseconds */ + } + /* no output amps */ spec->num_pwrs = 0; spec->mixer = stac92hd71bxx_analog_mixer; @@ -3981,6 +4052,13 @@ again: stac92xx_set_config_reg(codec, 0xf, 0x40f000f0); break; case 0x111d7603: /* 6 Port with Analog Mixer */ + if ((codec->revision_id & 0xf) == 1) { +#ifdef SND_HDA_NEEDS_RESUME + codec->patch_ops = stac92hd71bxx_patch_ops; +#endif + spec->stream_delay = 40; /* 40 milliseconds */ + } + /* no output amps */ spec->num_pwrs = 0; /* fallthru */ @@ -3997,6 +4075,7 @@ again: spec->gpio_dir = 0x01; spec->gpio_data = 0x01; + spec->powerdown_adcs = 1; spec->digbeep_nid = 0x26; spec->mux_nids = stac92hd71bxx_mux_nids; spec->adc_nids = stac92hd71bxx_adc_nids; @@ -4029,8 +4108,6 @@ again: return err; } - codec->patch_ops = stac92xx_patch_ops; - return 0; }; -- cgit v1.2.3 From 955d24881e13a08b9f523f36ae61a58245b8968e Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 30 Jul 2008 15:13:28 +0200 Subject: ALSA: hda - Add definitions of HDMI-related verbs Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_codec.h | 82 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 78 insertions(+), 4 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index aeee5816153..780e2fffae3 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -90,6 +90,14 @@ enum { #define AC_VERB_GET_CONFIG_DEFAULT 0x0f1c /* f20: AFG/MFG */ #define AC_VERB_GET_SUBSYSTEM_ID 0x0f20 +#define AC_VERB_GET_CVT_CHAN_COUNT 0x0f2d +#define AC_VERB_GET_HDMI_DIP_SIZE 0x0f2e +#define AC_VERB_GET_HDMI_ELDD 0x0f2f +#define AC_VERB_GET_HDMI_DIP_INDEX 0x0f30 +#define AC_VERB_GET_HDMI_DIP_DATA 0x0f31 +#define AC_VERB_GET_HDMI_DIP_XMIT 0x0f32 +#define AC_VERB_GET_HDMI_CP_CTRL 0x0f33 +#define AC_VERB_GET_HDMI_CHAN_SLOT 0x0f34 /* * SET verbs @@ -123,6 +131,12 @@ enum { #define AC_VERB_SET_CONFIG_DEFAULT_BYTES_3 0x71f #define AC_VERB_SET_EAPD 0x788 #define AC_VERB_SET_CODEC_RESET 0x7ff +#define AC_VERB_SET_CVT_CHAN_COUNT 0x72d +#define AC_VERB_SET_HDMI_DIP_INDEX 0x730 +#define AC_VERB_SET_HDMI_DIP_DATA 0x731 +#define AC_VERB_SET_HDMI_DIP_XMIT 0x732 +#define AC_VERB_SET_HDMI_CP_CTRL 0x733 +#define AC_VERB_SET_HDMI_CHAN_SLOT 0x734 /* * Parameter IDs @@ -144,6 +158,7 @@ enum { #define AC_PAR_GPIO_CAP 0x11 #define AC_PAR_AMP_OUT_CAP 0x12 #define AC_PAR_VOL_KNB_CAP 0x13 +#define AC_PAR_HDMI_LPCM_CAP 0x20 /* * AC_VERB_PARAMETERS results (32bit) @@ -172,6 +187,8 @@ enum { #define AC_WCAP_DIGITAL (1<<9) /* digital I/O */ #define AC_WCAP_POWER (1<<10) /* power control */ #define AC_WCAP_LR_SWAP (1<<11) /* L/R swap */ +#define AC_WCAP_CP_CAPS (1<<12) /* content protection */ +#define AC_WCAP_CHAN_CNT_EXT (7<<13) /* channel count ext */ #define AC_WCAP_DELAY (0xf<<16) #define AC_WCAP_DELAY_SHIFT 16 #define AC_WCAP_TYPE (0xf<<20) @@ -207,9 +224,20 @@ enum { /* Input converter SDI select */ #define AC_SDI_SELECT (0xf<<0) -/* Unsolicited response */ +/* Unsolicited response control */ #define AC_UNSOL_TAG (0x3f<<0) #define AC_UNSOL_ENABLED (1<<7) +#define AC_USRSP_EN AC_UNSOL_ENABLED + +/* Unsolicited responses */ +#define AC_UNSOL_RES_TAG (0x3f<<26) +#define AC_UNSOL_RES_TAG_SHIFT 26 +#define AC_UNSOL_RES_SUBTAG (0x1f<<21) +#define AC_UNSOL_RES_SUBTAG_SHIFT 21 +#define AC_UNSOL_RES_ELDV (1<<1) /* ELD Data valid (for HDMI) */ +#define AC_UNSOL_RES_PD (1<<0) /* pinsense detect */ +#define AC_UNSOL_RES_CP_STATE (1<<1) /* content protection */ +#define AC_UNSOL_RES_CP_READY (1<<0) /* content protection */ /* Pin widget capabilies */ #define AC_PINCAP_IMP_SENSE (1<<0) /* impedance sense capable */ @@ -223,6 +251,10 @@ enum { * but is marked reserved in the Intel HDA specification. */ #define AC_PINCAP_LR_SWAP (1<<7) /* L/R swap */ +/* Note: The same bit as LR_SWAP is newly defined as HDMI capability + * in HD-audio specification + */ +#define AC_PINCAP_HDMI (1<<7) /* HDMI pin */ #define AC_PINCAP_VREF (0x37<<8) #define AC_PINCAP_VREF_SHIFT 8 #define AC_PINCAP_EAPD (1<<16) /* EAPD capable */ @@ -273,6 +305,22 @@ enum { #define AC_KNBCAP_NUM_STEPS (0x7f<<0) #define AC_KNBCAP_DELTA (1<<7) +/* HDMI LPCM capabilities */ +#define AC_LPCMCAP_48K_CP_CHNS (0x0f<<0) /* max channels w/ CP-on */ +#define AC_LPCMCAP_48K_NO_CHNS (0x0f<<4) /* max channels w/o CP-on */ +#define AC_LPCMCAP_48K_20BIT (1<<8) /* 20b bitrate supported */ +#define AC_LPCMCAP_48K_24BIT (1<<9) /* 24b bitrate supported */ +#define AC_LPCMCAP_96K_CP_CHNS (0x0f<<10) /* max channels w/ CP-on */ +#define AC_LPCMCAP_96K_NO_CHNS (0x0f<<14) /* max channels w/o CP-on */ +#define AC_LPCMCAP_96K_20BIT (1<<18) /* 20b bitrate supported */ +#define AC_LPCMCAP_96K_24BIT (1<<19) /* 24b bitrate supported */ +#define AC_LPCMCAP_192K_CP_CHNS (0x0f<<20) /* max channels w/ CP-on */ +#define AC_LPCMCAP_192K_NO_CHNS (0x0f<<24) /* max channels w/o CP-on */ +#define AC_LPCMCAP_192K_20BIT (1<<28) /* 20b bitrate supported */ +#define AC_LPCMCAP_192K_24BIT (1<<29) /* 24b bitrate supported */ +#define AC_LPCMCAP_44K (1<<30) /* 44.1kHz support */ +#define AC_LPCMCAP_44K_MS (1<<31) /* 44.1kHz-multiplies support */ + /* * Control Parameters */ @@ -318,18 +366,44 @@ enum { #define AC_PINCTL_OUT_EN (1<<6) #define AC_PINCTL_HP_EN (1<<7) -/* Unsolicited response - 8bit */ -#define AC_USRSP_EN (1<<7) - /* Pin sense - 32bit */ #define AC_PINSENSE_IMPEDANCE_MASK (0x7fffffff) #define AC_PINSENSE_PRESENCE (1<<31) +#define AC_PINSENSE_ELDV (1<<30) /* ELD valid (HDMI) */ /* EAPD/BTL enable - 32bit */ #define AC_EAPDBTL_BALANCED (1<<0) #define AC_EAPDBTL_EAPD (1<<1) #define AC_EAPDBTL_LR_SWAP (1<<2) +/* HDMI ELD data */ +#define AC_ELDD_ELD_VALID (1<<31) +#define AC_ELDD_ELD_DATA 0xff + +/* HDMI DIP size */ +#define AC_DIPSIZE_ELD_BUF (1<<3) /* ELD buf size of packet size */ +#define AC_DIPSIZE_PACK_IDX (0x07<<0) /* packet index */ + +/* HDMI DIP index */ +#define AC_DIPIDX_PACK_IDX (0x07<<5) /* packet idnex */ +#define AC_DIPIDX_BYTE_IDX (0x1f<<0) /* byte index */ + +/* HDMI DIP xmit (transmit) control */ +#define AC_DIPXMIT_MASK (0x3<<6) +#define AC_DIPXMIT_DISABLE (0x0<<6) /* disable xmit */ +#define AC_DIPXMIT_ONCE (0x2<<6) /* xmit once then disable */ +#define AC_DIPXMIT_BEST (0x3<<6) /* best effort */ + +/* HDMI content protection (CP) control */ +#define AC_CPCTRL_CES (1<<9) /* current encryption state */ +#define AC_CPCTRL_READY (1<<8) /* ready bit */ +#define AC_CPCTRL_SUBTAG (0x1f<<3) /* subtag for unsol-resp */ +#define AC_CPCTRL_STATE (3<<0) /* current CP request state */ + +/* Converter channel <-> HDMI slot mapping */ +#define AC_CVTMAP_HDMI_SLOT (0xf<<0) /* HDMI slot number */ +#define AC_CVTMAP_CHAN (0xf<<4) /* converter channel number */ + /* configuration default - 32bit */ #define AC_DEFCFG_SEQUENCE (0xf<<0) #define AC_DEFCFG_DEF_ASSOC (0xf<<4) -- cgit v1.2.3 From c4920606757224d0c480f25839f1cef6901a2167 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 30 Jul 2008 15:13:29 +0200 Subject: ALSA: hda - print a few HDMI information in proc Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_proc.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c index 1e5aff5c48d..4927c4b6bf6 100644 --- a/sound/pci/hda/hda_proc.c +++ b/sound/pci/hda/hda_proc.c @@ -229,8 +229,13 @@ static void print_pin_caps(struct snd_info_buffer *buffer, snd_iprintf(buffer, " Detect"); if (caps & AC_PINCAP_BALANCE) snd_iprintf(buffer, " Balanced"); - if (caps & AC_PINCAP_LR_SWAP) - snd_iprintf(buffer, " R/L"); + if (caps & AC_PINCAP_HDMI) { + /* Realtek uses this bit as a different meaning */ + if ((codec->vendor_id >> 16) == 0x10ec) + snd_iprintf(buffer, " R/L"); + else + snd_iprintf(buffer, " HDMI"); + } if (caps & AC_PINCAP_TRIG_REQ) snd_iprintf(buffer, " Trigger"); if (caps & AC_PINCAP_IMP_SENSE) @@ -552,9 +557,15 @@ static void print_codec_info(struct snd_info_entry *entry, snd_iprintf(buffer, "Node 0x%02x [%s] wcaps 0x%x:", nid, get_wid_type_name(wid_type), wid_caps); - if (wid_caps & AC_WCAP_STEREO) - snd_iprintf(buffer, " Stereo"); - else + if (wid_caps & AC_WCAP_STEREO) { + unsigned int chans; + chans = (wid_caps & AC_WCAP_CHAN_CNT_EXT) >> 13; + chans = ((chans << 1) | 1) + 1; + if (chans == 2) + snd_iprintf(buffer, " Stereo"); + else + snd_iprintf(buffer, " %d-Channels", chans); + } else snd_iprintf(buffer, " Mono"); if (wid_caps & AC_WCAP_DIGITAL) snd_iprintf(buffer, " Digital"); @@ -566,6 +577,8 @@ static void print_codec_info(struct snd_info_entry *entry, snd_iprintf(buffer, " Stripe"); if (wid_caps & AC_WCAP_LR_SWAP) snd_iprintf(buffer, " R/L"); + if (wid_caps & AC_WCAP_CP_CAPS) + snd_iprintf(buffer, " CP"); snd_iprintf(buffer, "\n"); /* volume knob is a special widget that always have connection -- cgit v1.2.3 From 862f76f86d64c2cf34a7ff5ddf0a175073b76534 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 30 Jul 2008 15:13:29 +0200 Subject: ALSA: hda - set up HDMI channels Set up channel information for HDMI widgets. This will allow LPCM with multiple channels supported on some HDMI devices. TODO: It still doesn't check ELD and doesn't change PCM parameters dynamically. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_atihdmi.c | 45 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 8 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_atihdmi.c b/sound/pci/hda/patch_atihdmi.c index 12272508b11..ba61575983f 100644 --- a/sound/pci/hda/patch_atihdmi.c +++ b/sound/pci/hda/patch_atihdmi.c @@ -35,6 +35,9 @@ struct atihdmi_spec { struct hda_pcm pcm_rec; }; +#define CVT_NID 0x02 /* audio converter */ +#define PIN_NID 0x03 /* HDMI output pin */ + static struct hda_verb atihdmi_basic_init[] = { /* enable digital output on pin widget */ { 0x03, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, @@ -60,8 +63,9 @@ static int atihdmi_init(struct hda_codec *codec) { snd_hda_sequence_write(codec, atihdmi_basic_init); /* SI codec requires to unmute the pin */ - if (get_wcaps(codec, 0x03) & AC_WCAP_OUT_AMP) - snd_hda_codec_write(codec, 0x03, 0, AC_VERB_SET_AMP_GAIN_MUTE, + if (get_wcaps(codec, PIN_NID) & AC_WCAP_OUT_AMP) + snd_hda_codec_write(codec, PIN_NID, 0, + AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE); return 0; } @@ -92,15 +96,29 @@ static int atihdmi_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 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); + int chans = substream->runtime->channels; + int i, err; + + err = snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag, + format, substream); + if (err < 0) + return err; + snd_hda_codec_write(codec, CVT_NID, 0, AC_VERB_SET_CVT_CHAN_COUNT, + chans - 1); + /* FIXME: XXX */ + for (i = 0; i < chans; i++) { + snd_hda_codec_write(codec, CVT_NID, 0, + AC_VERB_SET_HDMI_CHAN_SLOT, + (i << 4) | i); + } + return 0; } static struct hda_pcm_stream atihdmi_pcm_digital_playback = { .substreams = 1, .channels_min = 2, .channels_max = 2, - .nid = 0x2, /* NID to query formats and rates and setup streams */ + .nid = CVT_NID, /* NID to query formats and rates and setup streams */ .ops = { .open = atihdmi_dig_playback_pcm_open, .close = atihdmi_dig_playback_pcm_close, @@ -112,6 +130,7 @@ static int atihdmi_build_pcms(struct hda_codec *codec) { struct atihdmi_spec *spec = codec->spec; struct hda_pcm *info = &spec->pcm_rec; + unsigned int chans; codec->num_pcms = 1; codec->pcm_info = info; @@ -120,6 +139,13 @@ static int atihdmi_build_pcms(struct hda_codec *codec) info->pcm_type = HDA_PCM_TYPE_HDMI; info->stream[SNDRV_PCM_STREAM_PLAYBACK] = atihdmi_pcm_digital_playback; + /* FIXME: we must check ELD and change the PCM parameters dynamically + */ + chans = get_wcaps(codec, CVT_NID); + chans = (chans & AC_WCAP_CHAN_CNT_EXT) >> 13; + chans = ((chans << 1) | 1) + 1; + info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = chans; + return 0; } @@ -147,9 +173,11 @@ static int patch_atihdmi(struct hda_codec *codec) spec->multiout.num_dacs = 0; /* no analog */ spec->multiout.max_channels = 2; - spec->multiout.dig_out_nid = 0x2; /* NID for copying analog to digital, - * seems to be unused in pure-digital - * case. */ + /* NID for copying analog to digital, + * seems to be unused in pure-digital + * case. + */ + spec->multiout.dig_out_nid = CVT_NID; codec->patch_ops = atihdmi_patch_ops; @@ -164,6 +192,7 @@ struct hda_codec_preset snd_hda_preset_atihdmi[] = { { .id = 0x10027919, .name = "ATI RS600 HDMI", .patch = patch_atihdmi }, { .id = 0x1002791a, .name = "ATI RS690/780 HDMI", .patch = patch_atihdmi }, { .id = 0x1002aa01, .name = "ATI R6xx HDMI", .patch = patch_atihdmi }, + { .id = 0x10951390, .name = "SiI1390 HDMI", .patch = patch_atihdmi }, { .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_atihdmi }, { .id = 0x17e80047, .name = "Chrontel HDMI", .patch = patch_atihdmi }, {} /* terminator */ -- cgit v1.2.3 From 9e44c6e40fb383e6b1d0df0c9e375a98e11828d1 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 18 Aug 2008 13:53:07 +0200 Subject: ALSA: hda - Add AD1882A codec support Added the basic support of AD1882A codec chip. It's almost compatible with AD1882, but with a digital mic and some differences in connections. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_analog.c | 74 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 57 insertions(+), 17 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index b6d64cc0787..0899b6b3886 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -3917,7 +3917,7 @@ static int patch_ad1884a(struct hda_codec *codec) /* - * AD1882 + * AD1882 / AD1882A * * port-A - front hp-out * port-B - front mic-in @@ -3954,6 +3954,18 @@ static struct hda_input_mux ad1882_capture_source = { }, }; +/* list: 0x11, 0x39, 0x3a, 0x3c, 0x18, 0x1f, 0x12, 0x20 */ +static struct hda_input_mux ad1882a_capture_source = { + .num_items = 5, + .items = { + { "Front Mic", 0x1 }, + { "Mic", 0x4}, + { "Line", 0x2 }, + { "Digital Mic", 0x06 }, + { "Mix", 0x7 }, + }, +}; + static struct snd_kcontrol_new ad1882_base_mixers[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), @@ -3963,16 +3975,7 @@ static struct snd_kcontrol_new ad1882_base_mixers[] = { HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT), - HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT), - HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT), - HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT), - HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x04, HDA_INPUT), - HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x04, HDA_INPUT), - HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT), - HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT), - HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x07, HDA_INPUT), - HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x07, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost", 0x3c, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Front Mic Boost", 0x39, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Line-In Boost", 0x3a, 0x0, HDA_OUTPUT), @@ -4005,6 +4008,35 @@ static struct snd_kcontrol_new ad1882_base_mixers[] = { { } /* end */ }; +static struct snd_kcontrol_new ad1882_loopback_mixers[] = { + HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT), + HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT), + HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x04, HDA_INPUT), + HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x04, HDA_INPUT), + HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT), + HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT), + HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x07, HDA_INPUT), + HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x07, HDA_INPUT), + { } /* end */ +}; + +static struct snd_kcontrol_new ad1882a_loopback_mixers[] = { + HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT), + HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x04, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x04, HDA_INPUT), + HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x01, HDA_INPUT), + HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x01, HDA_INPUT), + HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT), + HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT), + HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x07, HDA_INPUT), + HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x07, HDA_INPUT), + HDA_CODEC_VOLUME("Digital Mic Boost", 0x1f, 0x0, HDA_INPUT), + { } /* end */ +}; + static struct snd_kcontrol_new ad1882_3stack_mixers[] = { HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x17, 1, 0x0, HDA_OUTPUT), @@ -4174,9 +4206,16 @@ static int patch_ad1882(struct hda_codec *codec) spec->num_adc_nids = ARRAY_SIZE(ad1882_adc_nids); spec->adc_nids = ad1882_adc_nids; spec->capsrc_nids = ad1882_capsrc_nids; - spec->input_mux = &ad1882_capture_source; - spec->num_mixers = 1; + if (codec->vendor_id == 0x11d1882) + spec->input_mux = &ad1882_capture_source; + else + spec->input_mux = &ad1882a_capture_source; + spec->num_mixers = 2; spec->mixers[0] = ad1882_base_mixers; + if (codec->vendor_id == 0x11d1882) + spec->mixers[1] = ad1882_loopback_mixers; + else + spec->mixers[1] = ad1882a_loopback_mixers; spec->num_init_verbs = 1; spec->init_verbs[0] = ad1882_init_verbs; spec->spdif_route = 0; @@ -4193,8 +4232,8 @@ static int patch_ad1882(struct hda_codec *codec) switch (board_config) { default: case AD1882_3STACK: - spec->num_mixers = 2; - spec->mixers[1] = ad1882_3stack_mixers; + spec->num_mixers = 3; + spec->mixers[2] = ad1882_3stack_mixers; spec->channel_mode = ad1882_modes; spec->num_channel_mode = ARRAY_SIZE(ad1882_modes); spec->need_dac_fix = 1; @@ -4202,8 +4241,8 @@ static int patch_ad1882(struct hda_codec *codec) spec->multiout.num_dacs = 1; break; case AD1882_6STACK: - spec->num_mixers = 2; - spec->mixers[1] = ad1882_6stack_mixers; + spec->num_mixers = 3; + spec->mixers[2] = ad1882_6stack_mixers; break; } return 0; @@ -4226,6 +4265,7 @@ struct hda_codec_preset snd_hda_preset_analog[] = { { .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a }, { .id = 0x11d41988, .name = "AD1988", .patch = patch_ad1988 }, { .id = 0x11d4198b, .name = "AD1988B", .patch = patch_ad1988 }, + { .id = 0x11d4882a, .name = "AD1882A", .patch = patch_ad1882 }, { .id = 0x11d4989a, .name = "AD1989A", .patch = patch_ad1988 }, { .id = 0x11d4989b, .name = "AD1989B", .patch = patch_ad1988 }, {} /* terminator */ -- cgit v1.2.3 From a62741cf77f41338033553d7cc3fd3145a64ae53 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 18 Aug 2008 17:11:09 +0200 Subject: ALSA: hda - disable delayed period-ack with bdl_pos_adj=0 When bdl_pos_adj=0 is given, disable the position-check and the delayed period update mechanism. Usually bdl_pos_adj=0 is set only for the debugging purpose on really broken hardwares. It's better to disable the extra complexity in such a case. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_intel.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index b2bcd94cf7a..39f22318803 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -1559,6 +1559,8 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev) chip->position_fix = POS_FIX_POSBUF; } + if (!bdl_pos_adj[chip->dev_index]) + return 1; /* no delayed ack */ if (pos % azx_dev->period_bytes > azx_dev->period_bytes / 2) return 0; /* NG - it's below the period boundary */ return 1; /* OK, it's fine */ -- cgit v1.2.3 From c08744498491759168119255fae2a1bd9532a268 Mon Sep 17 00:00:00 2001 From: Andreas Mohr Date: Wed, 20 Aug 2008 10:04:56 +0200 Subject: ALSA: als4000 - Code clean up - use specs-derived register name enums instead of open-coded numeric values, for better understanding of things - fix naming confusion ("gcr" was _NOT_ the GCR register stuff, but instead the io _base_ which has multiplexed _access_ to GCR config space, at _sub_ registers 0x08 and 0x0c) - add FIXME comments about a race condition and MPU401 features Signed-off-by: Andreas Mohr Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/als4000.c | 206 +++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 148 insertions(+), 58 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c index 27ce6136ab0..92d8c47cd3b 100644 --- a/sound/pci/als4000.c +++ b/sound/pci/als4000.c @@ -60,6 +60,7 @@ * * ToDo: * - Proper shared IRQ handling? + * - by default, don't enable legacy game and use PCI game I/O * - power management? (card can do voice wakeup according to datasheet!!) */ @@ -107,7 +108,7 @@ MODULE_PARM_DESC(joystick_port, "Joystick port address for ALS4000 soundcard. (0 struct snd_card_als4000 { /* most frequent access first */ - unsigned long gcr; + unsigned long iobase; struct pci_dev *pci; struct snd_sb *chip; #ifdef SUPPORT_JOYSTICK @@ -122,24 +123,89 @@ static struct pci_device_id snd_als4000_ids[] = { MODULE_DEVICE_TABLE(pci, snd_als4000_ids); -static inline void snd_als4000_gcr_write_addr(unsigned long port, u32 reg, u32 val) +enum als4k_iobase_t { + /* IOx: B == Byte, W = Word, D = DWord */ + ALS4K_IOD_00_AC97_ACCESS = 0x00, + ALS4K_IOW_04_AC97_READ = 0x04, + ALS4K_IOB_06_AC97_STATUS = 0x06, + ALS4K_IOB_07_IRQSTATUS = 0x07, + ALS4K_IOD_08_GCR_DATA = 0x08, + ALS4K_IOB_0C_GCR_INDEX = 0x0c, + ALS4K_IOB_0E_SB_MPU_IRQ = 0x0e, + ALS4K_IOB_10_ADLIB_ADDR0 = 0x10, + ALS4K_IOB_11_ADLIB_ADDR1 = 0x11, + ALS4K_IOB_12_ADLIB_ADDR2 = 0x12, + ALS4K_IOB_13_ADLIB_ADDR3 = 0x13, + ALS4K_IOB_14_MIXER_INDEX = 0x14, + ALS4K_IOB_15_MIXER_DATA = 0x15, + ALS4K_IOB_16_ESP_RST_PORT = 0x16, + ALS4K_IOB_16_CR1E_ACK_PORT = 0x16, /* 2nd function */ + ALS4K_IOB_18_OPL_ADDR0 = 0x18, + ALS4K_IOB_19_OPL_ADDR1 = 0x19, + ALS4K_IOB_1A_ESP_RD_DATA = 0x1a, + ALS4K_IOB_1C_ESP_CMD_DATA = 0x1c, + ALS4K_IOB_1C_ESP_WR_STATUS = 0x1c, /* 2nd function */ + ALS4K_IOB_1E_ESP_RD_STATUS8 = 0x1e, + ALS4K_IOB_1F_ESP_RD_STATUS16 = 0x1f, + ALS4K_IOB_20_ESP_GAMEPORT_200 = 0x20, + ALS4K_IOB_21_ESP_GAMEPORT_201 = 0x21, + ALS4K_IOB_30_MIDI_DATA = 0x30, + ALS4K_IOB_31_MIDI_STATUS = 0x31, + ALS4K_IOB_31_MIDI_COMMAND = 0x31, /* 2nd function */ +}; + +enum als4k_gcr_t { + /* all registers 32bit wide */ + ALS4K_GCR_8C_MISC_CTRL = 0x8c, + ALS4K_GCR_90_TEST_MODE_REG = 0x90, + ALS4K_GCR_91_DMA0_ADDR = 0x91, + ALS4K_GCR_92_DMA0_MODE_COUNT = 0x92, + ALS4K_GCR_93_DMA1_ADDR = 0x93, + ALS4K_GCR_94_DMA1_MODE_COUNT = 0x94, + ALS4K_GCR_95_DMA3_ADDR = 0x95, + ALS4K_GCR_96_DMA3_MODE_COUNT = 0x96, + ALS4K_GCR_99_DMA_EMULATION_CTRL = 0x99, + ALS4K_GCR_A0_FIFO1_CURRENT_ADDR = 0xa0, + ALS4K_GCR_A1_FIFO1_STATUS_BYTECOUNT = 0xa1, + ALS4K_GCR_A2_FIFO2_PCIADDR = 0xa2, + ALS4K_GCR_A3_FIFO2_COUNT = 0xa3, + ALS4K_GCR_A4_FIFO2_CURRENT_ADDR = 0xa4, + ALS4K_GCR_A5_FIFO1_STATUS_BYTECOUNT = 0xa5, + ALS4K_GCR_A6_PM_CTRL = 0xa6, + ALS4K_GCR_A7_PCI_ACCESS_STORAGE = 0xa7, + ALS4K_GCR_A8_LEGACY_CFG1 = 0xa8, + ALS4K_GCR_A9_LEGACY_CFG2 = 0xa9, + ALS4K_GCR_FF_DUMMY_SCRATCH = 0xff, +}; + +enum als4k_gcr_8c_t { + ALS4K_GCR_8C_IRQ_MASK_CTRL_ENABLE = 0x8000, + ALS4K_GCR_8C_CHIP_REV_MASK = 0xf0000 +}; + +static inline void snd_als4000_gcr_write_addr(unsigned long iobase, + enum als4k_gcr_t reg, + u32 val) { - outb(reg, port+0x0c); - outl(val, port+0x08); + outb(reg, iobase + ALS4K_IOB_0C_GCR_INDEX); + outl(val, iobase + ALS4K_IOD_08_GCR_DATA); } -static inline void snd_als4000_gcr_write(struct snd_sb *sb, u32 reg, u32 val) +static inline void snd_als4000_gcr_write(struct snd_sb *sb, + enum als4k_gcr_t reg, + u32 val) { snd_als4000_gcr_write_addr(sb->alt_port, reg, val); } -static inline u32 snd_als4000_gcr_read_addr(unsigned long port, u32 reg) +static inline u32 snd_als4000_gcr_read_addr(unsigned long iobase, + enum als4k_gcr_t reg) { - outb(reg, port+0x0c); - return inl(port+0x08); + outb(reg, iobase + ALS4K_IOB_0C_GCR_INDEX); + return inl(iobase + ALS4K_IOD_08_GCR_DATA); } -static inline u32 snd_als4000_gcr_read(struct snd_sb *sb, u32 reg) +static inline u32 snd_als4000_gcr_read(struct snd_sb *sb, enum als4k_gcr_t reg) { return snd_als4000_gcr_read_addr(sb->alt_port, reg); } @@ -156,15 +222,17 @@ static void snd_als4000_set_rate(struct snd_sb *chip, unsigned int rate) static inline void snd_als4000_set_capture_dma(struct snd_sb *chip, dma_addr_t addr, unsigned size) { - snd_als4000_gcr_write(chip, 0xa2, addr); - snd_als4000_gcr_write(chip, 0xa3, (size-1)); + snd_als4000_gcr_write(chip, ALS4K_GCR_A2_FIFO2_PCIADDR, addr); + snd_als4000_gcr_write(chip, ALS4K_GCR_A3_FIFO2_COUNT, (size-1)); } static inline void snd_als4000_set_playback_dma(struct snd_sb *chip, - dma_addr_t addr, unsigned size) + dma_addr_t addr, + unsigned size) { - snd_als4000_gcr_write(chip, 0x91, addr); - snd_als4000_gcr_write(chip, 0x92, (size-1)|0x180000); + snd_als4000_gcr_write(chip, ALS4K_GCR_91_DMA0_ADDR, addr); + snd_als4000_gcr_write(chip, ALS4K_GCR_92_DMA0_MODE_COUNT, + (size-1)|0x180000); } #define ALS4000_FORMAT_SIGNED (1<<0) @@ -305,6 +373,12 @@ static int snd_als4000_capture_trigger(struct snd_pcm_substream *substream, int struct snd_sb *chip = snd_pcm_substream_chip(substream); int result = 0; + /* FIXME race condition in here!!! + chip->mode non-atomic update gets consistently protected + by reg_lock always, _except_ for this place!! + Probably need to take reg_lock as outer (or inner??) lock, too. + (or serialize both lock operations? probably not, though... - racy?) + */ spin_lock(&chip->mixer_lock); switch (cmd) { case SNDRV_PCM_TRIGGER_START: @@ -356,7 +430,8 @@ static snd_pcm_uframes_t snd_als4000_capture_pointer(struct snd_pcm_substream *s unsigned int result; spin_lock(&chip->reg_lock); - result = snd_als4000_gcr_read(chip, 0xa4) & 0xffff; + result = snd_als4000_gcr_read(chip, ALS4K_GCR_A4_FIFO2_CURRENT_ADDR); + result &= 0xffff; spin_unlock(&chip->reg_lock); return bytes_to_frames( substream->runtime, result ); } @@ -367,7 +442,8 @@ static snd_pcm_uframes_t snd_als4000_playback_pointer(struct snd_pcm_substream * unsigned result; spin_lock(&chip->reg_lock); - result = snd_als4000_gcr_read(chip, 0xa0) & 0xffff; + result = snd_als4000_gcr_read(chip, ALS4K_GCR_A0_FIFO1_CURRENT_ADDR); + result &= 0xffff; spin_unlock(&chip->reg_lock); return bytes_to_frames( substream->runtime, result ); } @@ -376,12 +452,13 @@ static snd_pcm_uframes_t snd_als4000_playback_pointer(struct snd_pcm_substream * * return IRQ_HANDLED no matter whether we actually had an IRQ flag or not). * ALS4000a.PDF writes that while ACKing IRQ in PCI block will *not* ACK * the IRQ in the SB core, ACKing IRQ in SB block *will* ACK the PCI IRQ - * register (alt_port + 0x0e). Probably something could be optimized here to - * query/write one register only... + * register (alt_port + ALS4K_IOB_0E_SB_MPU_IRQ). Probably something + * could be optimized here to query/write one register only... * And even if both registers need to be queried, then there's still the * question of whether it's actually correct to ACK PCI IRQ before reading * SB IRQ like we do now, since ALS4000a.PDF mentions that PCI IRQ will *clear* * SB IRQ status. + * (hmm, page 38 mentions it the other way around!) * And do we *really* need the lock here for *reading* SB_DSP4_IRQSTATUS?? * */ static irqreturn_t snd_als4000_interrupt(int irq, void *dev_id) @@ -391,7 +468,7 @@ static irqreturn_t snd_als4000_interrupt(int irq, void *dev_id) unsigned sb_status; /* find out which bit of the ALS4000 produced the interrupt */ - gcr_status = inb(chip->alt_port + 0xe); + gcr_status = inb(chip->alt_port + ALS4K_IOB_0E_SB_MPU_IRQ); if ((gcr_status & 0x80) && (chip->playback_substream)) /* playback */ snd_pcm_period_elapsed(chip->playback_substream); @@ -400,7 +477,7 @@ static irqreturn_t snd_als4000_interrupt(int irq, void *dev_id) if ((gcr_status & 0x10) && (chip->rmidi)) /* MPU401 interrupt */ snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data); /* release the gcr */ - outb(gcr_status, chip->alt_port + 0xe); + outb(gcr_status, chip->alt_port + ALS4K_IOB_0E_SB_MPU_IRQ); spin_lock(&chip->mixer_lock); sb_status = snd_sbmixer_read(chip, SB_DSP4_IRQSTATUS); @@ -543,25 +620,25 @@ static int __devinit snd_als4000_pcm(struct snd_sb *chip, int device) /******************************************************************/ -static void snd_als4000_set_addr(unsigned long gcr, - unsigned int sb, - unsigned int mpu, - unsigned int opl, - unsigned int game) +static void snd_als4000_set_addr(unsigned long iobase, + unsigned int sb_io, + unsigned int mpu_io, + unsigned int opl_io, + unsigned int game_io) { - u32 confA = 0; - u32 confB = 0; + u32 cfg1 = 0; + u32 cfg2 = 0; - if (mpu > 0) - confB |= (mpu | 1) << 16; - if (sb > 0) - confB |= (sb | 1); - if (game > 0) - confA |= (game | 1) << 16; - if (opl > 0) - confA |= (opl | 1); - snd_als4000_gcr_write_addr(gcr, 0xa8, confA); - snd_als4000_gcr_write_addr(gcr, 0xa9, confB); + if (mpu_io > 0) + cfg2 |= (mpu_io | 1) << 16; + if (sb_io > 0) + cfg2 |= (sb_io | 1); + if (game_io > 0) + cfg1 |= (game_io | 1) << 16; + if (opl_io > 0) + cfg1 |= (opl_io | 1); + snd_als4000_gcr_write_addr(iobase, ALS4K_GCR_A8_LEGACY_CFG1, cfg1); + snd_als4000_gcr_write_addr(iobase, ALS4K_GCR_A9_LEGACY_CFG2, cfg2); } static void snd_als4000_configure(struct snd_sb *chip) @@ -579,12 +656,15 @@ static void snd_als4000_configure(struct snd_sb *chip) spin_unlock_irq(&chip->mixer_lock); spin_lock_irq(&chip->reg_lock); - /* magic number. Enables interrupts(?) */ - snd_als4000_gcr_write(chip, 0x8c, 0x28000); - for(i = 0x91; i <= 0x96; ++i) + /* enable interrupts */ + snd_als4000_gcr_write(chip, ALS4K_GCR_8C_MISC_CTRL, + ALS4K_GCR_8C_IRQ_MASK_CTRL_ENABLE); + + for (i = ALS4K_GCR_91_DMA0_ADDR; i <= ALS4K_GCR_96_DMA3_MODE_COUNT; ++i) snd_als4000_gcr_write(chip, i, 0); - snd_als4000_gcr_write(chip, 0x99, snd_als4000_gcr_read(chip, 0x99)); + snd_als4000_gcr_write(chip, ALS4K_GCR_99_DMA_EMULATION_CTRL, + snd_als4000_gcr_read(chip, ALS4K_GCR_99_DMA_EMULATION_CTRL)); spin_unlock_irq(&chip->reg_lock); } @@ -628,7 +708,7 @@ static int __devinit snd_als4000_create_gameport(struct snd_card_als4000 *acard, gameport_set_port_data(gp, r); /* Enable legacy joystick port */ - snd_als4000_set_addr(acard->gcr, 0, 0, 0, 1); + snd_als4000_set_addr(acard->iobase, 0, 0, 0, 1); gameport_register_port(acard->gameport); @@ -643,7 +723,9 @@ static void snd_als4000_free_gameport(struct snd_card_als4000 *acard) gameport_unregister_port(acard->gameport); acard->gameport = NULL; - snd_als4000_set_addr(acard->gcr, 0, 0, 0, 0); /* disable joystick */ + /* disable joystick */ + snd_als4000_set_addr(acard->iobase, 0, 0, 0, 0); + release_and_free_resource(r); } } @@ -654,10 +736,10 @@ static inline void snd_als4000_free_gameport(struct snd_card_als4000 *acard) { } static void snd_card_als4000_free( struct snd_card *card ) { - struct snd_card_als4000 * acard = (struct snd_card_als4000 *)card->private_data; + struct snd_card_als4000 *acard = card->private_data; /* make sure that interrupts are disabled */ - snd_als4000_gcr_write_addr( acard->gcr, 0x8c, 0); + snd_als4000_gcr_write_addr(acard->iobase, ALS4K_GCR_8C_MISC_CTRL, 0); /* free resources */ snd_als4000_free_gameport(acard); pci_release_regions(acard->pci); @@ -670,7 +752,7 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci, static int dev; struct snd_card *card; struct snd_card_als4000 *acard; - unsigned long gcr; + unsigned long iobase; struct snd_sb *chip; struct snd_opl3 *opl3; unsigned short word; @@ -699,7 +781,7 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci, pci_disable_device(pci); return err; } - gcr = pci_resource_start(pci, 0); + iobase = pci_resource_start(pci, 0); pci_read_config_word(pci, PCI_COMMAND, &word); pci_write_config_word(pci, PCI_COMMAND, word | PCI_COMMAND_IO); @@ -713,16 +795,16 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci, return -ENOMEM; } - acard = (struct snd_card_als4000 *)card->private_data; + acard = card->private_data; acard->pci = pci; - acard->gcr = gcr; + acard->iobase = iobase; card->private_free = snd_card_als4000_free; /* disable all legacy ISA stuff */ - snd_als4000_set_addr(acard->gcr, 0, 0, 0, 0); + snd_als4000_set_addr(acard->iobase, 0, 0, 0, 0); if ((err = snd_sbdsp_create(card, - gcr + 0x10, + iobase + ALS4K_IOB_10_ADLIB_ADDR0, pci->irq, snd_als4000_interrupt, -1, @@ -734,7 +816,7 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci, acard->chip = chip; chip->pci = pci; - chip->alt_port = gcr; + chip->alt_port = iobase; snd_card_set_dev(card, &pci->dev); snd_als4000_configure(chip); @@ -745,11 +827,16 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci, card->shortname, chip->alt_port, chip->irq); if ((err = snd_mpu401_uart_new( card, 0, MPU401_HW_ALS4000, - gcr+0x30, MPU401_INFO_INTEGRATED, + iobase + ALS4K_IOB_30_MIDI_DATA, + MPU401_INFO_INTEGRATED, pci->irq, 0, &chip->rmidi)) < 0) { - printk(KERN_ERR "als4000: no MPU-401 device at 0x%lx?\n", gcr+0x30); + printk(KERN_ERR "als4000: no MPU-401 device at 0x%lx?\n", + iobase + ALS4K_IOB_30_MIDI_DATA); goto out_err; } + /* FIXME: ALS4000 has interesting MPU401 configuration features + * at CR 0x1A (pass-thru / UART switching, fast MIDI clock, etc.), + * however there doesn't seem to be an ALSA API for this... */ if ((err = snd_als4000_pcm(chip, 0)) < 0) { goto out_err; @@ -758,10 +845,13 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci, goto out_err; } - if (snd_opl3_create(card, gcr+0x10, gcr+0x12, + if (snd_opl3_create(card, + iobase + ALS4K_IOB_10_ADLIB_ADDR0, + iobase + ALS4K_IOB_12_ADLIB_ADDR2, OPL3_HW_AUTO, 1, &opl3) < 0) { printk(KERN_ERR "als4000: no OPL device at 0x%lx-0x%lx?\n", - gcr+0x10, gcr+0x12 ); + iobase + ALS4K_IOB_10_ADLIB_ADDR0, + iobase + ALS4K_IOB_12_ADLIB_ADDR2); } else { if ((err = snd_opl3_hwdep_new(opl3, 0, 1, NULL)) < 0) { goto out_err; @@ -831,13 +921,13 @@ static int snd_als4000_resume(struct pci_dev *pci) #ifdef SUPPORT_JOYSTICK if (acard->gameport) - snd_als4000_set_addr(acard->gcr, 0, 0, 0, 1); + snd_als4000_set_addr(acard->iobase, 0, 0, 0, 1); #endif snd_power_change_state(card, SNDRV_CTL_POWER_D0); return 0; } -#endif +#endif /* CONFIG_PM */ static struct pci_driver driver = { -- cgit v1.2.3 From 2005af24b17a44a977ce58d918db72f442b89521 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 20 Aug 2008 18:38:26 +0200 Subject: ALSA: hda - Create beep control on ALC269 codec ALC269 codec has a beep, but it was not used, so far. Create a beep control appropriately. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 8bff732958e..9cb6b73ef95 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -11068,6 +11068,8 @@ static struct snd_kcontrol_new alc269_base_mixer[] = { 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("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT), + HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT), HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), @@ -11120,6 +11122,13 @@ static struct snd_kcontrol_new alc269_epc_capture_mixer[] = { { } /* end */ }; +/* beep control */ +static struct snd_kcontrol_new alc269_beep_mixer[] = { + HDA_CODEC_VOLUME("Beep Playback Volume", 0x0b, 0x4, HDA_INPUT), + HDA_CODEC_MUTE("Beep Playback Switch", 0x0b, 0x4, HDA_INPUT), + { } /* end */ +}; + /* * generic initialization of ADC, input mixers and output mixers */ @@ -11382,7 +11391,7 @@ static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec, static int alc269_parse_auto_config(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; - int err; + int i, err; static hda_nid_t alc269_ignore[] = { 0x1d, 0 }; err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, @@ -11405,6 +11414,13 @@ static int alc269_parse_auto_config(struct hda_codec *codec) if (spec->kctl_alloc) spec->mixers[spec->num_mixers++] = spec->kctl_alloc; + /* create a beep mixer control if the pin 0x1d isn't assigned */ + for (i = 0; i < ARRAY_SIZE(spec->autocfg.input_pins); i++) + if (spec->autocfg.input_pins[i] == 0x1d) + break; + if (i >= ARRAY_SIZE(spec->autocfg.input_pins)) + spec->mixers[spec->num_mixers++] = alc269_beep_mixer; + spec->init_verbs[spec->num_init_verbs++] = alc269_init_verbs; spec->num_mux_defs = 1; spec->input_mux = &spec->private_imux; -- cgit v1.2.3 From 46480b3a5f88f20dbf25d95fe74d7b4798d5bc86 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Thu, 21 Aug 2008 08:28:42 +0400 Subject: ALSA: revo51: add headphone output It is ALSA bug #1754. D6 bit in 02 register is PW4. Signed-off-by: Alexander Beregalov Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/ice1712/revo.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/ice1712/revo.c b/sound/pci/ice1712/revo.c index 5e1b156bfaa..d2193913d70 100644 --- a/sound/pci/ice1712/revo.c +++ b/sound/pci/ice1712/revo.c @@ -216,6 +216,7 @@ static const struct snd_akm4xxx_dac_channel revo51_dac[] = { AK_DAC("PCM Center Playback Volume", 1), AK_DAC("PCM LFE Playback Volume", 1), AK_DAC("PCM Rear Playback Volume", 2), + AK_DAC("PCM Headphone Volume", 2), }; static const char *revo51_adc_input_names[] = { @@ -279,7 +280,7 @@ static struct snd_ak4xxx_private akm_revo_surround_priv __devinitdata = { static struct snd_akm4xxx akm_revo51 __devinitdata = { .type = SND_AK4358, - .num_dacs = 6, + .num_dacs = 8, .ops = { .set_rate_val = revo_set_rate_val }, @@ -508,7 +509,7 @@ static int __devinit revo_init(struct snd_ice1712 *ice) ice->gpio.i2s_mclk_changed = revo_i2s_mclk_changed; break; case VT1724_SUBDEVICE_REVOLUTION51: - ice->num_total_dacs = 6; + ice->num_total_dacs = 8; ice->num_total_adcs = 2; break; case VT1724_SUBDEVICE_AUDIOPHILE192: -- cgit v1.2.3 From 77a23f2695bb2de0cd74599400dc55109c531b72 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 21 Aug 2008 13:00:13 +0200 Subject: ALSA: Clean up SG-buffer helper functions and macros Clean up SG-buffer helper functions and macros. Helpers take substream as arguments now. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/au88x0/au88x0.h | 7 ++----- sound/pci/au88x0/au88x0_core.c | 38 +++++++++++++++++--------------------- sound/pci/au88x0/au88x0_pcm.c | 14 ++------------ sound/pci/bt87x.c | 5 +++-- sound/pci/echoaudio/echoaudio.c | 14 ++++---------- sound/pci/emu10k1/memory.c | 12 ++---------- sound/pci/hda/hda_intel.c | 3 +-- sound/pci/riptide/riptide.c | 13 +++++++------ sound/pci/rme9652/hdspm.c | 18 ++++++++---------- sound/pci/trident/trident_memory.c | 13 ++++--------- sound/pci/via82xx.c | 5 +++-- sound/pci/via82xx_modem.c | 5 +++-- 12 files changed, 56 insertions(+), 91 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/au88x0/au88x0.h b/sound/pci/au88x0/au88x0.h index 4aad35bba11..cf46bba563c 100644 --- a/sound/pci/au88x0/au88x0.h +++ b/sound/pci/au88x0/au88x0.h @@ -125,7 +125,6 @@ typedef struct { /* Virtual page extender stuff */ int nr_periods; int period_bytes; - struct snd_sg_buf *sgbuf; /* DMA Scatter Gather struct */ int period_real; int period_virt; @@ -195,16 +194,14 @@ static void vortex_adb_setsrc(vortex_t * vortex, int adbdma, /* DMA Engines. */ static void vortex_adbdma_setbuffers(vortex_t * vortex, int adbdma, - struct snd_sg_buf * sgbuf, int size, - int count); + int size, int count); static void vortex_adbdma_setmode(vortex_t * vortex, int adbdma, int ie, int dir, int fmt, int d, u32 offset); static void vortex_adbdma_setstartbuffer(vortex_t * vortex, int adbdma, int sb); #ifndef CHIP_AU8810 static void vortex_wtdma_setbuffers(vortex_t * vortex, int wtdma, - struct snd_sg_buf * sgbuf, int size, - int count); + int size, int count); static void vortex_wtdma_setmode(vortex_t * vortex, int wtdma, int ie, int fmt, int d, /*int e, */ u32 offset); static void vortex_wtdma_setstartbuffer(vortex_t * vortex, int wtdma, int sb); diff --git a/sound/pci/au88x0/au88x0_core.c b/sound/pci/au88x0/au88x0_core.c index 1900fa6bc51..b070e571451 100644 --- a/sound/pci/au88x0/au88x0_core.c +++ b/sound/pci/au88x0/au88x0_core.c @@ -1097,19 +1097,12 @@ static void vortex_adbdma_setstartbuffer(vortex_t * vortex, int adbdma, int sb) static void vortex_adbdma_setbuffers(vortex_t * vortex, int adbdma, - struct snd_sg_buf * sgbuf, int psize, int count) + int psize, int count) { stream_t *dma = &vortex->dma_adb[adbdma]; - if (sgbuf == NULL) { - printk(KERN_INFO "vortex: FATAL: sgbuf is NULL!\n"); - return; - } - //printk(KERN_INFO "vortex: page count = %d, tblcount = %d\n", count, sgbuf->tblsize); - dma->period_bytes = psize; dma->nr_periods = count; - dma->sgbuf = sgbuf; dma->cfg0 = 0; dma->cfg1 = 0; @@ -1120,26 +1113,26 @@ vortex_adbdma_setbuffers(vortex_t * vortex, int adbdma, dma->cfg1 |= 0x88000000 | 0x44000000 | 0x30000000 | (psize - 1); hwwrite(vortex->mmio, VORTEX_ADBDMA_BUFBASE + (adbdma << 4) + 0xc, - snd_sgbuf_get_addr(sgbuf, psize * 3)); + snd_pcm_sgbuf_get_addr(dma->substream, psize * 3)); /* 3 pages */ case 3: dma->cfg0 |= 0x12000000; dma->cfg1 |= 0x80000000 | 0x40000000 | ((psize - 1) << 0xc); hwwrite(vortex->mmio, VORTEX_ADBDMA_BUFBASE + (adbdma << 4) + 0x8, - snd_sgbuf_get_addr(sgbuf, psize * 2)); + snd_pcm_sgbuf_get_addr(dma->substream, psize * 2)); /* 2 pages */ case 2: dma->cfg0 |= 0x88000000 | 0x44000000 | 0x10000000 | (psize - 1); hwwrite(vortex->mmio, VORTEX_ADBDMA_BUFBASE + (adbdma << 4) + 0x4, - snd_sgbuf_get_addr(sgbuf, psize)); + snd_pcm_sgbuf_get_addr(dma->substream, psize)); /* 1 page */ case 1: dma->cfg0 |= 0x80000000 | 0x40000000 | ((psize - 1) << 0xc); hwwrite(vortex->mmio, VORTEX_ADBDMA_BUFBASE + (adbdma << 4), - snd_sgbuf_get_addr(sgbuf, 0)); + snd_pcm_sgbuf_get_addr(dma->substream, 0)); break; } //printk("vortex: cfg0 = 0x%x\nvortex: cfg1=0x%x\n", dma->cfg0, dma->cfg1); @@ -1205,7 +1198,7 @@ static int vortex_adbdma_bufshift(vortex_t * vortex, int adbdma) //hwwrite(vortex->mmio, VORTEX_ADBDMA_BUFBASE+(((adbdma << 2)+pp) << 2), dma->table[p].addr); hwwrite(vortex->mmio, VORTEX_ADBDMA_BUFBASE + (((adbdma << 2) + pp) << 2), - snd_sgbuf_get_addr(dma->sgbuf, + snd_pcm_sgbuf_get_addr(dma->substream, dma->period_bytes * p)); /* Force write thru cache. */ hwread(vortex->mmio, VORTEX_ADBDMA_BUFBASE + @@ -1244,7 +1237,10 @@ static void vortex_adbdma_resetup(vortex_t *vortex, int adbdma) { if (pp >= 4) pp -= 4; } - hwwrite(vortex->mmio, VORTEX_ADBDMA_BUFBASE+(((adbdma << 2)+pp) << 2), snd_sgbuf_get_addr(dma->sgbuf, dma->period_bytes * p)); + hwwrite(vortex->mmio, + VORTEX_ADBDMA_BUFBASE + (((adbdma << 2) + pp) << 2), + snd_pcm_sgbuf_get_addr(dma->substream, + dma->period_bytes * p)); /* Force write thru cache. */ hwread(vortex->mmio, VORTEX_ADBDMA_BUFBASE + (((adbdma << 2)+pp) << 2)); } @@ -1367,13 +1363,12 @@ static void vortex_wtdma_setstartbuffer(vortex_t * vortex, int wtdma, int sb) static void vortex_wtdma_setbuffers(vortex_t * vortex, int wtdma, - struct snd_sg_buf * sgbuf, int psize, int count) + int psize, int count) { stream_t *dma = &vortex->dma_wt[wtdma]; dma->period_bytes = psize; dma->nr_periods = count; - dma->sgbuf = sgbuf; dma->cfg0 = 0; dma->cfg1 = 0; @@ -1383,23 +1378,23 @@ vortex_wtdma_setbuffers(vortex_t * vortex, int wtdma, case 4: dma->cfg1 |= 0x88000000 | 0x44000000 | 0x30000000 | (psize-1); hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4) + 0xc, - snd_sgbuf_get_addr(sgbuf, psize * 3)); + snd_pcm_sgbuf_get_addr(dma->substream, psize * 3)); /* 3 pages */ case 3: dma->cfg0 |= 0x12000000; dma->cfg1 |= 0x80000000 | 0x40000000 | ((psize-1) << 0xc); hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4) + 0x8, - snd_sgbuf_get_addr(sgbuf, psize * 2)); + snd_pcm_sgbuf_get_addr(dma->substream, psize * 2)); /* 2 pages */ case 2: dma->cfg0 |= 0x88000000 | 0x44000000 | 0x10000000 | (psize-1); hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4) + 0x4, - snd_sgbuf_get_addr(sgbuf, psize)); + snd_pcm_sgbuf_get_addr(dma->substream, psize)); /* 1 page */ case 1: dma->cfg0 |= 0x80000000 | 0x40000000 | ((psize-1) << 0xc); hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (wtdma << 4), - snd_sgbuf_get_addr(sgbuf, 0)); + snd_pcm_sgbuf_get_addr(dma->substream, 0)); break; } hwwrite(vortex->mmio, VORTEX_WTDMA_BUFCFG0 + (wtdma << 3), dma->cfg0); @@ -1465,7 +1460,8 @@ static int vortex_wtdma_bufshift(vortex_t * vortex, int wtdma) hwwrite(vortex->mmio, VORTEX_WTDMA_BUFBASE + (((wtdma << 2) + pp) << 2), - snd_sgbuf_get_addr(dma->sgbuf, dma->period_bytes * p)); + snd_pcm_sgbuf_get_addr(dma->substream, + dma->period_bytes * p)); /* Force write thru cache. */ hwread(vortex->mmio, VORTEX_WTDMA_BUFBASE + (((wtdma << 2) + pp) << 2)); diff --git a/sound/pci/au88x0/au88x0_pcm.c b/sound/pci/au88x0/au88x0_pcm.c index f9a58b4a30e..b9d2f202cf9 100644 --- a/sound/pci/au88x0/au88x0_pcm.c +++ b/sound/pci/au88x0/au88x0_pcm.c @@ -189,7 +189,6 @@ snd_vortex_pcm_hw_params(struct snd_pcm_substream *substream, { vortex_t *chip = snd_pcm_substream_chip(substream); stream_t *stream = (stream_t *) (substream->runtime->private_data); - struct snd_sg_buf *sgbuf; int err; // Alloc buffer memory. @@ -199,8 +198,6 @@ snd_vortex_pcm_hw_params(struct snd_pcm_substream *substream, printk(KERN_ERR "Vortex: pcm page alloc failed!\n"); return err; } - //sgbuf = (struct snd_sg_buf *) substream->runtime->dma_private; - sgbuf = snd_pcm_substream_sgbuf(substream); /* printk(KERN_INFO "Vortex: periods %d, period_bytes %d, channels = %d\n", params_periods(hw_params), params_period_bytes(hw_params), params_channels(hw_params)); @@ -226,7 +223,7 @@ snd_vortex_pcm_hw_params(struct snd_pcm_substream *substream, stream = substream->runtime->private_data = &chip->dma_adb[dma]; stream->substream = substream; /* Setup Buffers. */ - vortex_adbdma_setbuffers(chip, dma, sgbuf, + vortex_adbdma_setbuffers(chip, dma, params_period_bytes(hw_params), params_periods(hw_params)); } @@ -240,7 +237,7 @@ snd_vortex_pcm_hw_params(struct snd_pcm_substream *substream, &chip->dma_wt[substream->number]; stream->dma = substream->number; stream->substream = substream; - vortex_wtdma_setbuffers(chip, substream->number, sgbuf, + vortex_wtdma_setbuffers(chip, substream->number, params_period_bytes(hw_params), params_periods(hw_params)); } @@ -392,13 +389,6 @@ static snd_pcm_uframes_t snd_vortex_pcm_pointer(struct snd_pcm_substream *substr return (bytes_to_frames(substream->runtime, current_ptr)); } -/* Page callback. */ -/* -static struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream, unsigned long offset) { - - -} -*/ /* operators */ static struct snd_pcm_ops snd_vortex_playback_ops = { .open = snd_vortex_pcm_open, diff --git a/sound/pci/bt87x.c b/sound/pci/bt87x.c index 4ecdd635ed1..3aa8d973540 100644 --- a/sound/pci/bt87x.c +++ b/sound/pci/bt87x.c @@ -227,7 +227,6 @@ static inline void snd_bt87x_writel(struct snd_bt87x *chip, u32 reg, u32 value) static int snd_bt87x_create_risc(struct snd_bt87x *chip, struct snd_pcm_substream *substream, unsigned int periods, unsigned int period_bytes) { - struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream); unsigned int i, offset; u32 *risc; @@ -246,6 +245,7 @@ static int snd_bt87x_create_risc(struct snd_bt87x *chip, struct snd_pcm_substrea rest = period_bytes; do { u32 cmd, len; + unsigned int addr; len = PAGE_SIZE - (offset % PAGE_SIZE); if (len > rest) @@ -260,7 +260,8 @@ static int snd_bt87x_create_risc(struct snd_bt87x *chip, struct snd_pcm_substrea if (len == rest) cmd |= RISC_EOL | RISC_IRQ; *risc++ = cpu_to_le32(cmd); - *risc++ = cpu_to_le32((u32)snd_pcm_sgbuf_get_addr(sgbuf, offset)); + addr = snd_pcm_sgbuf_get_addr(substream, offset); + *risc++ = cpu_to_le32(addr); offset += len; rest -= len; } while (rest > 0); diff --git a/sound/pci/echoaudio/echoaudio.c b/sound/pci/echoaudio/echoaudio.c index 160d4705492..8dbc5c4ba42 100644 --- a/sound/pci/echoaudio/echoaudio.c +++ b/sound/pci/echoaudio/echoaudio.c @@ -490,7 +490,6 @@ static int init_engine(struct snd_pcm_substream *substream, { struct echoaudio *chip; int err, per, rest, page, edge, offs; - struct snd_sg_buf *sgbuf; struct audiopipe *pipe; chip = snd_pcm_substream_chip(substream); @@ -531,10 +530,6 @@ static int init_engine(struct snd_pcm_substream *substream, return err; } - sgbuf = snd_pcm_substream_sgbuf(substream); - - DE_HWP(("pcm_hw_params table size=%d pages=%d\n", - sgbuf->size, sgbuf->pages)); sglist_init(chip, pipe); edge = PAGE_SIZE; for (offs = page = per = 0; offs < params_buffer_bytes(hw_params); @@ -543,16 +538,15 @@ static int init_engine(struct snd_pcm_substream *substream, if (offs + rest > params_buffer_bytes(hw_params)) rest = params_buffer_bytes(hw_params) - offs; while (rest) { + dma_addr_t addr; + addr = snd_pcm_sgbuf_get_addr(substream, offs); if (rest <= edge - offs) { - sglist_add_mapping(chip, pipe, - snd_sgbuf_get_addr(sgbuf, offs), - rest); + sglist_add_mapping(chip, pipe, addr, rest); sglist_add_irq(chip, pipe); offs += rest; rest = 0; } else { - sglist_add_mapping(chip, pipe, - snd_sgbuf_get_addr(sgbuf, offs), + sglist_add_mapping(chip, pipe, addr, edge - offs); rest -= edge - offs; offs = edge; diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c index e8ad56ed34f..6a47672f930 100644 --- a/sound/pci/emu10k1/memory.c +++ b/sound/pci/emu10k1/memory.c @@ -296,7 +296,6 @@ struct snd_util_memblk * snd_emu10k1_alloc_pages(struct snd_emu10k1 *emu, struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream); struct snd_util_memhdr *hdr; struct snd_emu10k1_memblk *blk; int page, err, idx; @@ -321,16 +320,9 @@ snd_emu10k1_alloc_pages(struct snd_emu10k1 *emu, struct snd_pcm_substream *subst */ idx = 0; for (page = blk->first_page; page <= blk->last_page; page++, idx++) { + unsigned long ofs = idx << PAGE_SHIFT; dma_addr_t addr; -#ifdef CONFIG_SND_DEBUG - if (idx >= sgbuf->pages) { - printk(KERN_ERR "emu: pages overflow! (%d-%d) for %d\n", - blk->first_page, blk->last_page, sgbuf->pages); - mutex_unlock(&hdr->block_mutex); - return NULL; - } -#endif - addr = sgbuf->table[idx].addr; + addr = snd_pcm_sgbuf_get_addr(substream, ofs); if (! is_valid_page(emu, addr)) { printk(KERN_ERR "emu: failure page = %d\n", idx); mutex_unlock(&hdr->block_mutex); diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 39f22318803..e4d038f423f 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -998,7 +998,6 @@ static int setup_bdle(struct snd_pcm_substream *substream, struct azx_dev *azx_dev, u32 **bdlp, int ofs, int size, int with_ioc) { - struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream); u32 *bdl = *bdlp; while (size > 0) { @@ -1008,7 +1007,7 @@ static int setup_bdle(struct snd_pcm_substream *substream, if (azx_dev->frags >= AZX_MAX_BDL_ENTRIES) return -EINVAL; - addr = snd_pcm_sgbuf_get_addr(sgbuf, ofs); + addr = snd_pcm_sgbuf_get_addr(substream, ofs); /* program the address field of the BDL entry */ bdl[0] = cpu_to_le32((u32)addr); bdl[1] = cpu_to_le32(upper_32_bits(addr)); diff --git a/sound/pci/riptide/riptide.c b/sound/pci/riptide/riptide.c index 124f9a2f153..e9f0706ed3e 100644 --- a/sound/pci/riptide/riptide.c +++ b/sound/pci/riptide/riptide.c @@ -1483,7 +1483,6 @@ static int snd_riptide_prepare(struct snd_pcm_substream *substream) { struct snd_riptide *chip = snd_pcm_substream_chip(substream); struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream); struct pcmhw *data = get_pcmhwdev(substream); struct cmdif *cif = chip->cif; unsigned char *lbuspath = NULL; @@ -1515,9 +1514,9 @@ static int snd_riptide_prepare(struct snd_pcm_substream *substream) lbuspath = data->paths.stereo; break; } - snd_printdd("use sgdlist at 0x%p and buffer at 0x%p\n", - data->sgdlist.area, sgbuf); - if (data->sgdlist.area && sgbuf) { + snd_printdd("use sgdlist at 0x%p\n", + data->sgdlist.area); + if (data->sgdlist.area) { unsigned int i, j, size, pages, f, pt, period; struct sgd *c, *p = NULL; @@ -1535,6 +1534,7 @@ static int snd_riptide_prepare(struct snd_pcm_substream *substream) pt = 0; j = 0; for (i = 0; i < pages; i++) { + unsigned int ofs, addr; c = &data->sgdbuf[i]; if (p) p->dwNextLink = cpu_to_le32(data->sgdlist.addr + @@ -1542,8 +1542,9 @@ static int snd_riptide_prepare(struct snd_pcm_substream *substream) sizeof(struct sgd))); c->dwNextLink = cpu_to_le32(data->sgdlist.addr); - c->dwSegPtrPhys = - cpu_to_le32(sgbuf->table[j].addr + pt); + ofs = j << PAGE_SHIFT; + addr = snd_pcm_sgbuf_get_addr(substream, ofs) + pt; + c->dwSegPtrPhys = cpu_to_le32(addr); pt = (pt + f) % PAGE_SIZE; if (pt == 0) j++; diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index 83c92e6082a..98762f909d6 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c @@ -535,7 +535,8 @@ static inline void snd_hdspm_initialize_midi_flush(struct hdspm * hdspm); static int hdspm_update_simple_mixer_controls(struct hdspm * hdspm); static int hdspm_autosync_ref(struct hdspm * hdspm); static int snd_hdspm_set_defaults(struct hdspm * hdspm); -static void hdspm_set_sgbuf(struct hdspm * hdspm, struct snd_sg_buf *sgbuf, +static void hdspm_set_sgbuf(struct hdspm * hdspm, + struct snd_pcm_substream *substream, unsigned int reg, int channels); static inline int HDSPM_bit2freq(int n) @@ -3604,8 +3605,6 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream, int i; pid_t this_pid; pid_t other_pid; - struct snd_sg_buf *sgbuf; - spin_lock_irq(&hdspm->lock); @@ -3673,11 +3672,9 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream, if (err < 0) return err; - sgbuf = snd_pcm_substream_sgbuf(substream); - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - hdspm_set_sgbuf(hdspm, sgbuf, HDSPM_pageAddressBufferOut, + hdspm_set_sgbuf(hdspm, substream, HDSPM_pageAddressBufferOut, params_channels(params)); for (i = 0; i < params_channels(params); ++i) @@ -3688,7 +3685,7 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream, snd_printdd("Allocated sample buffer for playback at %p\n", hdspm->playback_buffer); } else { - hdspm_set_sgbuf(hdspm, sgbuf, HDSPM_pageAddressBufferIn, + hdspm_set_sgbuf(hdspm, substream, HDSPM_pageAddressBufferIn, params_channels(params)); for (i = 0; i < params_channels(params); ++i) @@ -3703,7 +3700,7 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream, snd_printdd("Allocated sample buffer for %s at 0x%08X\n", substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? "playback" : "capture", - snd_pcm_sgbuf_get_addr(sgbuf, 0)); + snd_pcm_sgbuf_get_addr(substream, 0)); */ /* snd_printdd("set_hwparams: %s %d Hz, %d channels, bs = %d\n", @@ -4253,13 +4250,14 @@ static int __devinit snd_hdspm_preallocate_memory(struct hdspm * hdspm) return 0; } -static void hdspm_set_sgbuf(struct hdspm * hdspm, struct snd_sg_buf *sgbuf, +static void hdspm_set_sgbuf(struct hdspm * hdspm, + struct snd_pcm_substream *substream, unsigned int reg, int channels) { int i; for (i = 0; i < (channels * 16); i++) hdspm_write(hdspm, reg + 4 * i, - snd_pcm_sgbuf_get_addr(sgbuf, (size_t) 4096 * i)); + snd_pcm_sgbuf_get_addr(substream, 4096 * i)); } /* ------------- ALSA Devices ---------------------------- */ diff --git a/sound/pci/trident/trident_memory.c b/sound/pci/trident/trident_memory.c index 2fe3b1fab53..f9779e23fe5 100644 --- a/sound/pci/trident/trident_memory.c +++ b/sound/pci/trident/trident_memory.c @@ -194,7 +194,6 @@ snd_trident_alloc_sg_pages(struct snd_trident *trident, struct snd_util_memblk *blk; struct snd_pcm_runtime *runtime = substream->runtime; int idx, page; - struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream); if (snd_BUG_ON(runtime->dma_bytes <= 0 || runtime->dma_bytes > SNDRV_TRIDENT_MAX_PAGES * @@ -212,18 +211,14 @@ snd_trident_alloc_sg_pages(struct snd_trident *trident, mutex_unlock(&hdr->block_mutex); return NULL; } - if (lastpg(blk) - firstpg(blk) >= sgbuf->pages) { - snd_printk(KERN_ERR "page calculation doesn't match: allocated pages = %d, trident = %d/%d\n", sgbuf->pages, firstpg(blk), lastpg(blk)); - __snd_util_mem_free(hdr, blk); - mutex_unlock(&hdr->block_mutex); - return NULL; - } /* set TLB entries */ idx = 0; for (page = firstpg(blk); page <= lastpg(blk); page++, idx++) { - dma_addr_t addr = sgbuf->table[idx].addr; - unsigned long ptr = (unsigned long)sgbuf->table[idx].buf; + unsigned long ofs = idx << PAGE_SHIFT; + dma_addr_t addr = snd_pcm_sgbuf_get_addr(substream, ofs); + unsigned long ptr = (unsigned long) + snd_pcm_sgbuf_get_ptr(substream, ofs); if (! is_valid_page(addr)) { __snd_util_mem_free(hdr, blk); mutex_unlock(&hdr->block_mutex); diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c index 84ea35d8b25..8766848bbe6 100644 --- a/sound/pci/via82xx.c +++ b/sound/pci/via82xx.c @@ -420,7 +420,6 @@ static int build_via_table(struct viadev *dev, struct snd_pcm_substream *substre { unsigned int i, idx, ofs, rest; struct via82xx *chip = snd_pcm_substream_chip(substream); - struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream); if (dev->table.area == NULL) { /* the start of each lists must be aligned to 8 bytes, @@ -449,12 +448,14 @@ static int build_via_table(struct viadev *dev, struct snd_pcm_substream *substre do { unsigned int r; unsigned int flag; + unsigned int addr; if (idx >= VIA_TABLE_SIZE) { snd_printk(KERN_ERR "via82xx: too much table size!\n"); return -EINVAL; } - ((u32 *)dev->table.area)[idx << 1] = cpu_to_le32((u32)snd_pcm_sgbuf_get_addr(sgbuf, ofs)); + addr = snd_pcm_sgbuf_get_addr(substream, ofs); + ((u32 *)dev->table.area)[idx << 1] = cpu_to_le32(addr); r = PAGE_SIZE - (ofs % PAGE_SIZE); if (rest < r) r = rest; diff --git a/sound/pci/via82xx_modem.c b/sound/pci/via82xx_modem.c index 640c338ce0a..5bd79d2a5a1 100644 --- a/sound/pci/via82xx_modem.c +++ b/sound/pci/via82xx_modem.c @@ -281,7 +281,6 @@ static int build_via_table(struct viadev *dev, struct snd_pcm_substream *substre { unsigned int i, idx, ofs, rest; struct via82xx_modem *chip = snd_pcm_substream_chip(substream); - struct snd_sg_buf *sgbuf = snd_pcm_substream_sgbuf(substream); if (dev->table.area == NULL) { /* the start of each lists must be aligned to 8 bytes, @@ -310,12 +309,14 @@ static int build_via_table(struct viadev *dev, struct snd_pcm_substream *substre do { unsigned int r; unsigned int flag; + unsigned int addr; if (idx >= VIA_TABLE_SIZE) { snd_printk(KERN_ERR "via82xx: too much table size!\n"); return -EINVAL; } - ((u32 *)dev->table.area)[idx << 1] = cpu_to_le32((u32)snd_pcm_sgbuf_get_addr(sgbuf, ofs)); + addr = snd_pcm_sgbuf_get_addr(substream, ofs); + ((u32 *)dev->table.area)[idx << 1] = cpu_to_le32(addr); r = PAGE_SIZE - (ofs % PAGE_SIZE); if (rest < r) r = rest; -- cgit v1.2.3 From fc4abee8112ada7b1b66017f620d3de3954759f3 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 30 Jul 2008 15:13:34 +0200 Subject: ALSA: hda - check page continuity Check the continuity of allocated pages to reduce the BDL size as much as possible so that it can use more than 1MB buffers. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_intel.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index e4d038f423f..4f80248837e 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -1012,9 +1012,7 @@ static int setup_bdle(struct snd_pcm_substream *substream, bdl[0] = cpu_to_le32((u32)addr); bdl[1] = cpu_to_le32(upper_32_bits(addr)); /* program the size field of the BDL entry */ - chunk = PAGE_SIZE - (ofs % PAGE_SIZE); - if (size < chunk) - chunk = size; + chunk = snd_pcm_sgbuf_get_chunk_size(substream, ofs, size); bdl[2] = cpu_to_le32(chunk); /* program the IOC to enable interrupt * only when the whole fragment is processed @@ -1672,7 +1670,7 @@ static int __devinit create_codec_pcm(struct azx *chip, struct hda_codec *codec, snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &azx_pcm_ops); snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, snd_dma_pci_data(chip->pci), - 1024 * 64, 1024 * 1024); + 1024 * 64, 32 * 1024 * 1024); chip->pcm[cpcm->device] = pcm; return 0; } -- cgit v1.2.3 From a2e3961d0a26870eb23b70edab6814c7f08ce2e0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 21 Aug 2008 14:17:38 +0200 Subject: ALSA: via82xx - ignore buffer preallocation errors The errors at buffer preallocations aren't fatal and safe to ignore. The buffer will be allocated dynamically when opened. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/via82xx.c | 38 +++++++++++++++----------------------- 1 file changed, 15 insertions(+), 23 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c index 8766848bbe6..57e33d7df5f 100644 --- a/sound/pci/via82xx.c +++ b/sound/pci/via82xx.c @@ -1401,10 +1401,9 @@ static int __devinit snd_via8233_pcm_new(struct via82xx *chip) /* capture */ init_viadev(chip, chip->capture_devno, VIA_REG_CAPTURE_8233_STATUS, 6, 1); - if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, - snd_dma_pci_data(chip->pci), - 64*1024, 128*1024)) < 0) - return err; + snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, + snd_dma_pci_data(chip->pci), + 64*1024, 128*1024); /* PCM #1: multi-channel playback and 2nd capture */ err = snd_pcm_new(chip->card, chip->card->shortname, 1, 1, 1, &pcm); @@ -1420,11 +1419,9 @@ static int __devinit snd_via8233_pcm_new(struct via82xx *chip) /* set up capture */ init_viadev(chip, chip->capture_devno + 1, VIA_REG_CAPTURE_8233_STATUS + 0x10, 7, 1); - if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, - snd_dma_pci_data(chip->pci), - 64*1024, 128*1024)) < 0) - return err; - + snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, + snd_dma_pci_data(chip->pci), + 64*1024, 128*1024); return 0; } @@ -1456,10 +1453,9 @@ static int __devinit snd_via8233a_pcm_new(struct via82xx *chip) /* capture */ init_viadev(chip, chip->capture_devno, VIA_REG_CAPTURE_8233_STATUS, 6, 1); - if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, - snd_dma_pci_data(chip->pci), - 64*1024, 128*1024)) < 0) - return err; + snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, + snd_dma_pci_data(chip->pci), + 64*1024, 128*1024); /* SPDIF supported? */ if (! ac97_can_spdif(chip->ac97)) @@ -1476,11 +1472,9 @@ static int __devinit snd_via8233a_pcm_new(struct via82xx *chip) /* set up playback */ init_viadev(chip, chip->playback_devno, 0x30, 3, 0); - if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, - snd_dma_pci_data(chip->pci), - 64*1024, 128*1024)) < 0) - return err; - + snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, + snd_dma_pci_data(chip->pci), + 64*1024, 128*1024) return 0; } @@ -1508,11 +1502,9 @@ static int __devinit snd_via686_pcm_new(struct via82xx *chip) init_viadev(chip, 0, VIA_REG_PLAYBACK_STATUS, 0, 0); init_viadev(chip, 1, VIA_REG_CAPTURE_STATUS, 0, 1); - if ((err = snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, - snd_dma_pci_data(chip->pci), - 64*1024, 128*1024)) < 0) - return err; - + snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, + snd_dma_pci_data(chip->pci), + 64*1024, 128*1024); return 0; } -- cgit v1.2.3 From 5503600a1c5c2c11e14ff428b5d07a1018927bd6 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 30 Jul 2008 15:23:06 +0200 Subject: ALSA: via82xx - check continuous pages in buffer setup Check continuous pages in the buffer set up so that the number of BDL is reduced. Also increased the max buffer size. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/via82xx.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/via82xx.c b/sound/pci/via82xx.c index 57e33d7df5f..1aafe956ee2 100644 --- a/sound/pci/via82xx.c +++ b/sound/pci/via82xx.c @@ -313,6 +313,7 @@ struct snd_via_sg_table { } ; #define VIA_TABLE_SIZE 255 +#define VIA_MAX_BUFSIZE (1<<24) struct viadev { unsigned int reg_offset; @@ -456,9 +457,7 @@ static int build_via_table(struct viadev *dev, struct snd_pcm_substream *substre } addr = snd_pcm_sgbuf_get_addr(substream, ofs); ((u32 *)dev->table.area)[idx << 1] = cpu_to_le32(addr); - r = PAGE_SIZE - (ofs % PAGE_SIZE); - if (rest < r) - r = rest; + r = snd_pcm_sgbuf_get_chunk_size(substream, ofs, rest); rest -= r; if (! rest) { if (i == periods - 1) @@ -1147,9 +1146,9 @@ static struct snd_pcm_hardware snd_via82xx_hw = .rate_max = 48000, .channels_min = 1, .channels_max = 2, - .buffer_bytes_max = 128 * 1024, + .buffer_bytes_max = VIA_MAX_BUFSIZE, .period_bytes_min = 32, - .period_bytes_max = 128 * 1024, + .period_bytes_max = VIA_MAX_BUFSIZE / 2, .periods_min = 2, .periods_max = VIA_TABLE_SIZE / 2, .fifo_size = 0, @@ -1403,7 +1402,7 @@ static int __devinit snd_via8233_pcm_new(struct via82xx *chip) snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, snd_dma_pci_data(chip->pci), - 64*1024, 128*1024); + 64*1024, VIA_MAX_BUFSIZE); /* PCM #1: multi-channel playback and 2nd capture */ err = snd_pcm_new(chip->card, chip->card->shortname, 1, 1, 1, &pcm); @@ -1421,7 +1420,7 @@ static int __devinit snd_via8233_pcm_new(struct via82xx *chip) snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, snd_dma_pci_data(chip->pci), - 64*1024, 128*1024); + 64*1024, VIA_MAX_BUFSIZE); return 0; } @@ -1455,7 +1454,7 @@ static int __devinit snd_via8233a_pcm_new(struct via82xx *chip) snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, snd_dma_pci_data(chip->pci), - 64*1024, 128*1024); + 64*1024, VIA_MAX_BUFSIZE); /* SPDIF supported? */ if (! ac97_can_spdif(chip->ac97)) @@ -1474,7 +1473,7 @@ static int __devinit snd_via8233a_pcm_new(struct via82xx *chip) snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, snd_dma_pci_data(chip->pci), - 64*1024, 128*1024) + 64*1024, VIA_MAX_BUFSIZE); return 0; } @@ -1504,7 +1503,7 @@ static int __devinit snd_via686_pcm_new(struct via82xx *chip) snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, snd_dma_pci_data(chip->pci), - 64*1024, 128*1024); + 64*1024, VIA_MAX_BUFSIZE); return 0; } -- cgit v1.2.3 From e01bf5091f044011823aefa1882eb3fba0434918 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 21 Aug 2008 16:25:07 +0200 Subject: ALSA: hda - Fix ALC269 capture source ALC269 capture source wasn't properly set up. It's an independent MUX (0x23), not a source of ADC. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 9cb6b73ef95..f2049365e23 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -11042,6 +11042,14 @@ static hda_nid_t alc269_adc_nids[1] = { 0x08, }; +static hda_nid_t alc269_capsrc_nids[1] = { + 0x23, +}; + +/* NOTE: ADC2 (0x07) is connected from a recording *MIXER* (0x24), + * not a mux! + */ + static struct hda_input_mux alc269_eeepc_dmic_capture_source = { .num_items = 2, .items = { @@ -11424,6 +11432,10 @@ static int alc269_parse_auto_config(struct hda_codec *codec) spec->init_verbs[spec->num_init_verbs++] = alc269_init_verbs; spec->num_mux_defs = 1; spec->input_mux = &spec->private_imux; + /* set default input source */ + snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0], + 0, AC_VERB_SET_CONNECT_SEL, + spec->input_mux->items[0].index); err = alc_auto_add_mic_boost(codec); if (err < 0) @@ -11556,6 +11568,7 @@ static int patch_alc269(struct hda_codec *codec) spec->adc_nids = alc269_adc_nids; spec->num_adc_nids = ARRAY_SIZE(alc269_adc_nids); + spec->capsrc_nids = alc269_capsrc_nids; codec->patch_ops = alc_patch_ops; if (board_config == ALC269_AUTO) -- cgit v1.2.3 From cb780cdd85b8ae408245883ae44172ed1ed34439 Mon Sep 17 00:00:00 2001 From: Andreas Mohr Date: Thu, 21 Aug 2008 21:55:57 +0200 Subject: ALSA: ALS4000 driver work, step 2 - more register naming work - finally figured out that weird CR register stuff (and did I mention that I hate _really_ undecipherable open-coded values?) - fix handling of IRQ sharing in interrupt handler (hopefully properly, otherwise I'd be grateful to hear your pedantic comments ;) - add handy SPECS_PAGE references wherever useful - comments, cleanup - add me as module author Signed-off-by: Andreas Mohr Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/als4000.c | 305 +++++++++++++++++++++++++++++++++++----------------- 1 file changed, 205 insertions(+), 100 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/als4000.c b/sound/pci/als4000.c index 92d8c47cd3b..ba570053d4d 100644 --- a/sound/pci/als4000.c +++ b/sound/pci/als4000.c @@ -2,7 +2,7 @@ * card-als4000.c - driver for Avance Logic ALS4000 based soundcards. * Copyright (C) 2000 by Bart Hartgers , * Jaroslav Kysela - * Copyright (C) 2002 by Andreas Mohr + * Copyright (C) 2002, 2008 by Andreas Mohr * * Framework borrowed from Massimo Piccioni's card-als100.c. * @@ -27,8 +27,10 @@ * bought an ALS4000 based soundcard, I was forced to base this driver * on reverse engineering. * - * Note: this is no longer true. Pretty verbose chip docu (ALS4000a.PDF) - * can be found on the ALSA web site. + * Note: this is no longer true (thank you!): + * pretty verbose chip docu (ALS4000a.PDF) can be found on the ALSA web site. + * Page numbers stated anywhere below with the "SPECS_PAGE:" tag + * refer to: ALS4000a.PDF specs Ver 1.0, May 28th, 1998. * * The ALS4000 seems to be the PCI-cousin of the ALS100. It contains an * ALS100-like SB DSP/mixer, an OPL3 synth, a MPU401 and a gameport @@ -59,7 +61,6 @@ * - value -> some port 0x0c0d * * ToDo: - * - Proper shared IRQ handling? * - by default, don't enable legacy game and use PCI game I/O * - power management? (card can do voice wakeup according to datasheet!!) */ @@ -79,7 +80,7 @@ #include #include -MODULE_AUTHOR("Bart Hartgers "); +MODULE_AUTHOR("Bart Hartgers , Andreas Mohr"); MODULE_DESCRIPTION("Avance Logic ALS4000"); MODULE_LICENSE("GPL"); MODULE_SUPPORTED_DEVICE("{{Avance Logic,ALS4000}}"); @@ -124,22 +125,22 @@ static struct pci_device_id snd_als4000_ids[] = { MODULE_DEVICE_TABLE(pci, snd_als4000_ids); enum als4k_iobase_t { - /* IOx: B == Byte, W = Word, D = DWord */ + /* IOx: B == Byte, W = Word, D = DWord; SPECS_PAGE: 37 */ ALS4K_IOD_00_AC97_ACCESS = 0x00, ALS4K_IOW_04_AC97_READ = 0x04, ALS4K_IOB_06_AC97_STATUS = 0x06, ALS4K_IOB_07_IRQSTATUS = 0x07, ALS4K_IOD_08_GCR_DATA = 0x08, ALS4K_IOB_0C_GCR_INDEX = 0x0c, - ALS4K_IOB_0E_SB_MPU_IRQ = 0x0e, + ALS4K_IOB_0E_IRQTYPE_SB_CR1E_MPU = 0x0e, ALS4K_IOB_10_ADLIB_ADDR0 = 0x10, ALS4K_IOB_11_ADLIB_ADDR1 = 0x11, ALS4K_IOB_12_ADLIB_ADDR2 = 0x12, ALS4K_IOB_13_ADLIB_ADDR3 = 0x13, ALS4K_IOB_14_MIXER_INDEX = 0x14, ALS4K_IOB_15_MIXER_DATA = 0x15, - ALS4K_IOB_16_ESP_RST_PORT = 0x16, - ALS4K_IOB_16_CR1E_ACK_PORT = 0x16, /* 2nd function */ + ALS4K_IOB_16_ESP_RESET = 0x16, + ALS4K_IOB_16_ACK_FOR_CR1E = 0x16, /* 2nd function */ ALS4K_IOB_18_OPL_ADDR0 = 0x18, ALS4K_IOB_19_OPL_ADDR1 = 0x19, ALS4K_IOB_1A_ESP_RD_DATA = 0x1a, @@ -154,62 +155,137 @@ enum als4k_iobase_t { ALS4K_IOB_31_MIDI_COMMAND = 0x31, /* 2nd function */ }; -enum als4k_gcr_t { - /* all registers 32bit wide */ - ALS4K_GCR_8C_MISC_CTRL = 0x8c, - ALS4K_GCR_90_TEST_MODE_REG = 0x90, - ALS4K_GCR_91_DMA0_ADDR = 0x91, - ALS4K_GCR_92_DMA0_MODE_COUNT = 0x92, - ALS4K_GCR_93_DMA1_ADDR = 0x93, - ALS4K_GCR_94_DMA1_MODE_COUNT = 0x94, - ALS4K_GCR_95_DMA3_ADDR = 0x95, - ALS4K_GCR_96_DMA3_MODE_COUNT = 0x96, - ALS4K_GCR_99_DMA_EMULATION_CTRL = 0x99, - ALS4K_GCR_A0_FIFO1_CURRENT_ADDR = 0xa0, - ALS4K_GCR_A1_FIFO1_STATUS_BYTECOUNT = 0xa1, - ALS4K_GCR_A2_FIFO2_PCIADDR = 0xa2, - ALS4K_GCR_A3_FIFO2_COUNT = 0xa3, - ALS4K_GCR_A4_FIFO2_CURRENT_ADDR = 0xa4, - ALS4K_GCR_A5_FIFO1_STATUS_BYTECOUNT = 0xa5, - ALS4K_GCR_A6_PM_CTRL = 0xa6, - ALS4K_GCR_A7_PCI_ACCESS_STORAGE = 0xa7, - ALS4K_GCR_A8_LEGACY_CFG1 = 0xa8, - ALS4K_GCR_A9_LEGACY_CFG2 = 0xa9, - ALS4K_GCR_FF_DUMMY_SCRATCH = 0xff, +enum als4k_iobase_0e_t { + ALS4K_IOB_0E_MPU_IRQ = 0x10, + ALS4K_IOB_0E_CR1E_IRQ = 0x40, + ALS4K_IOB_0E_SB_DMA_IRQ = 0x80, }; -enum als4k_gcr_8c_t { - ALS4K_GCR_8C_IRQ_MASK_CTRL_ENABLE = 0x8000, - ALS4K_GCR_8C_CHIP_REV_MASK = 0xf0000 +enum als4k_gcr_t { /* all registers 32bit wide; SPECS_PAGE: 38 to 42 */ + ALS4K_GCR8C_MISC_CTRL = 0x8c, + ALS4K_GCR90_TEST_MODE_REG = 0x90, + ALS4K_GCR91_DMA0_ADDR = 0x91, + ALS4K_GCR92_DMA0_MODE_COUNT = 0x92, + ALS4K_GCR93_DMA1_ADDR = 0x93, + ALS4K_GCR94_DMA1_MODE_COUNT = 0x94, + ALS4K_GCR95_DMA3_ADDR = 0x95, + ALS4K_GCR96_DMA3_MODE_COUNT = 0x96, + ALS4K_GCR99_DMA_EMULATION_CTRL = 0x99, + ALS4K_GCRA0_FIFO1_CURRENT_ADDR = 0xa0, + ALS4K_GCRA1_FIFO1_STATUS_BYTECOUNT = 0xa1, + ALS4K_GCRA2_FIFO2_PCIADDR = 0xa2, + ALS4K_GCRA3_FIFO2_COUNT = 0xa3, + ALS4K_GCRA4_FIFO2_CURRENT_ADDR = 0xa4, + ALS4K_GCRA5_FIFO1_STATUS_BYTECOUNT = 0xa5, + ALS4K_GCRA6_PM_CTRL = 0xa6, + ALS4K_GCRA7_PCI_ACCESS_STORAGE = 0xa7, + ALS4K_GCRA8_LEGACY_CFG1 = 0xa8, + ALS4K_GCRA9_LEGACY_CFG2 = 0xa9, + ALS4K_GCRFF_DUMMY_SCRATCH = 0xff, }; -static inline void snd_als4000_gcr_write_addr(unsigned long iobase, - enum als4k_gcr_t reg, - u32 val) +enum als4k_gcr8c_t { + ALS4K_GCR8C_IRQ_MASK_CTRL_ENABLE = 0x8000, + ALS4K_GCR8C_CHIP_REV_MASK = 0xf0000 +}; + +static inline void snd_als4k_iobase_writeb(unsigned long iobase, + enum als4k_iobase_t reg, + u8 val) { - outb(reg, iobase + ALS4K_IOB_0C_GCR_INDEX); - outl(val, iobase + ALS4K_IOD_08_GCR_DATA); + outb(val, iobase + reg); } -static inline void snd_als4000_gcr_write(struct snd_sb *sb, +static inline void snd_als4k_iobase_writel(unsigned long iobase, + enum als4k_iobase_t reg, + u32 val) +{ + outl(val, iobase + reg); +} + +static inline u8 snd_als4k_iobase_readb(unsigned long iobase, + enum als4k_iobase_t reg) +{ + return inb(iobase + reg); +} + +static inline u32 snd_als4k_iobase_readl(unsigned long iobase, + enum als4k_iobase_t reg) +{ + return inl(iobase + reg); +} + +static inline void snd_als4k_gcr_write_addr(unsigned long iobase, enum als4k_gcr_t reg, u32 val) { - snd_als4000_gcr_write_addr(sb->alt_port, reg, val); + snd_als4k_iobase_writeb(iobase, ALS4K_IOB_0C_GCR_INDEX, reg); + snd_als4k_iobase_writel(iobase, ALS4K_IOD_08_GCR_DATA, val); +} + +static inline void snd_als4k_gcr_write(struct snd_sb *sb, + enum als4k_gcr_t reg, + u32 val) +{ + snd_als4k_gcr_write_addr(sb->alt_port, reg, val); } -static inline u32 snd_als4000_gcr_read_addr(unsigned long iobase, +static inline u32 snd_als4k_gcr_read_addr(unsigned long iobase, enum als4k_gcr_t reg) { - outb(reg, iobase + ALS4K_IOB_0C_GCR_INDEX); - return inl(iobase + ALS4K_IOD_08_GCR_DATA); + /* SPECS_PAGE: 37/38 */ + snd_als4k_iobase_writeb(iobase, ALS4K_IOB_0C_GCR_INDEX, reg); + return snd_als4k_iobase_readl(iobase, ALS4K_IOD_08_GCR_DATA); +} + +static inline u32 snd_als4k_gcr_read(struct snd_sb *sb, enum als4k_gcr_t reg) +{ + return snd_als4k_gcr_read_addr(sb->alt_port, reg); +} + +enum als4k_cr_t { /* all registers 8bit wide; SPECS_PAGE: 20 to 23 */ + ALS4K_CR0_SB_CONFIG = 0x00, + ALS4K_CR2_MISC_CONTROL = 0x02, + ALS4K_CR3_CONFIGURATION = 0x03, + ALS4K_CR17_FIFO_STATUS = 0x17, + ALS4K_CR18_ESP_MAJOR_VERSION = 0x18, + ALS4K_CR19_ESP_MINOR_VERSION = 0x19, + ALS4K_CR1A_MPU401_UART_MODE_CONTROL = 0x1a, + ALS4K_CR1C_FIFO2_BLOCK_LENGTH_LO = 0x1c, + ALS4K_CR1D_FIFO2_BLOCK_LENGTH_HI = 0x1d, + ALS4K_CR1E_FIFO2_CONTROL = 0x1e, /* secondary PCM FIFO (recording) */ + ALS4K_CR3A_MISC_CONTROL = 0x3a, + ALS4K_CR3B_CRC32_BYTE0 = 0x3b, /* for testing, activate via CR3A */ + ALS4K_CR3C_CRC32_BYTE1 = 0x3c, + ALS4K_CR3D_CRC32_BYTE2 = 0x3d, + ALS4K_CR3E_CRC32_BYTE3 = 0x3e, +}; + +enum als4k_cr0_t { + ALS4K_CR0_DMA_CONTIN_MODE_CTRL = 0x02, /* IRQ/FIFO controlled for 0/1 */ + ALS4K_CR0_DMA_90H_MODE_CTRL = 0x04, /* IRQ/FIFO controlled for 0/1 */ + ALS4K_CR0_MX80_81_REG_WRITE_ENABLE = 0x80, +}; + +static inline void snd_als4_cr_write(struct snd_sb *chip, + enum als4k_cr_t reg, + u8 data) +{ + /* Control Register is reg | 0xc0 (bit 7, 6 set) on sbmixer_index + * NOTE: assumes chip->mixer_lock to be locked externally already! + * SPECS_PAGE: 6 */ + snd_sbmixer_write(chip, reg | 0xc0, data); } -static inline u32 snd_als4000_gcr_read(struct snd_sb *sb, enum als4k_gcr_t reg) +static inline u8 snd_als4_cr_read(struct snd_sb *chip, + enum als4k_cr_t reg) { - return snd_als4000_gcr_read_addr(sb->alt_port, reg); + /* NOTE: assumes chip->mixer_lock to be locked externally already! */ + return snd_sbmixer_read(chip, reg | 0xc0); } + + static void snd_als4000_set_rate(struct snd_sb *chip, unsigned int rate) { if (!(chip->mode & SB_RATE_LOCK)) { @@ -222,16 +298,18 @@ static void snd_als4000_set_rate(struct snd_sb *chip, unsigned int rate) static inline void snd_als4000_set_capture_dma(struct snd_sb *chip, dma_addr_t addr, unsigned size) { - snd_als4000_gcr_write(chip, ALS4K_GCR_A2_FIFO2_PCIADDR, addr); - snd_als4000_gcr_write(chip, ALS4K_GCR_A3_FIFO2_COUNT, (size-1)); + /* SPECS_PAGE: 40 */ + snd_als4k_gcr_write(chip, ALS4K_GCRA2_FIFO2_PCIADDR, addr); + snd_als4k_gcr_write(chip, ALS4K_GCRA3_FIFO2_COUNT, (size-1)); } static inline void snd_als4000_set_playback_dma(struct snd_sb *chip, dma_addr_t addr, unsigned size) { - snd_als4000_gcr_write(chip, ALS4K_GCR_91_DMA0_ADDR, addr); - snd_als4000_gcr_write(chip, ALS4K_GCR_92_DMA0_MODE_COUNT, + /* SPECS_PAGE: 38 */ + snd_als4k_gcr_write(chip, ALS4K_GCR91_DMA0_ADDR, addr); + snd_als4k_gcr_write(chip, ALS4K_GCR92_DMA0_MODE_COUNT, (size-1)|0x180000); } @@ -316,7 +394,7 @@ static int snd_als4000_capture_prepare(struct snd_pcm_substream *substream) count = snd_pcm_lib_period_bytes(substream); if (chip->capture_format & ALS4000_FORMAT_16BIT) - count >>=1; + count >>= 1; count--; spin_lock_irq(&chip->reg_lock); @@ -324,8 +402,8 @@ static int snd_als4000_capture_prepare(struct snd_pcm_substream *substream) snd_als4000_set_capture_dma(chip, runtime->dma_addr, size); spin_unlock_irq(&chip->reg_lock); spin_lock_irq(&chip->mixer_lock); - snd_sbmixer_write(chip, 0xdc, count); - snd_sbmixer_write(chip, 0xdd, count>>8); + snd_als4_cr_write(chip, ALS4K_CR1C_FIFO2_BLOCK_LENGTH_LO, count & 0xff); + snd_als4_cr_write(chip, ALS4K_CR1D_FIFO2_BLOCK_LENGTH_HI, count >> 8); spin_unlock_irq(&chip->mixer_lock); return 0; } @@ -343,7 +421,7 @@ static int snd_als4000_playback_prepare(struct snd_pcm_substream *substream) count = snd_pcm_lib_period_bytes(substream); if (chip->playback_format & ALS4000_FORMAT_16BIT) - count >>=1; + count >>= 1; count--; /* FIXME: from second playback on, there's a lot more clicks and pops @@ -360,8 +438,8 @@ static int snd_als4000_playback_prepare(struct snd_pcm_substream *substream) /* snd_sbdsp_command(chip, SB_DSP_SPEAKER_ON); */ snd_sbdsp_command(chip, playback_cmd(chip).dsp_cmd); snd_sbdsp_command(chip, playback_cmd(chip).format); - snd_sbdsp_command(chip, count); - snd_sbdsp_command(chip, count>>8); + snd_sbdsp_command(chip, count & 0xff); + snd_sbdsp_command(chip, count >> 8); snd_sbdsp_command(chip, playback_cmd(chip).dma_off); spin_unlock_irq(&chip->reg_lock); @@ -384,12 +462,14 @@ static int snd_als4000_capture_trigger(struct snd_pcm_substream *substream, int case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: chip->mode |= SB_RATE_LOCK_CAPTURE; - snd_sbmixer_write(chip, 0xde, capture_cmd(chip)); + snd_als4_cr_write(chip, ALS4K_CR1E_FIFO2_CONTROL, + capture_cmd(chip)); break; case SNDRV_PCM_TRIGGER_STOP: case SNDRV_PCM_TRIGGER_SUSPEND: chip->mode &= ~SB_RATE_LOCK_CAPTURE; - snd_sbmixer_write(chip, 0xde, 0); + snd_als4_cr_write(chip, ALS4K_CR1E_FIFO2_CONTROL, + capture_cmd(chip)); break; default: result = -EINVAL; @@ -430,9 +510,9 @@ static snd_pcm_uframes_t snd_als4000_capture_pointer(struct snd_pcm_substream *s unsigned int result; spin_lock(&chip->reg_lock); - result = snd_als4000_gcr_read(chip, ALS4K_GCR_A4_FIFO2_CURRENT_ADDR); - result &= 0xffff; + result = snd_als4k_gcr_read(chip, ALS4K_GCRA4_FIFO2_CURRENT_ADDR); spin_unlock(&chip->reg_lock); + result &= 0xffff; return bytes_to_frames( substream->runtime, result ); } @@ -442,9 +522,9 @@ static snd_pcm_uframes_t snd_als4000_playback_pointer(struct snd_pcm_substream * unsigned result; spin_lock(&chip->reg_lock); - result = snd_als4000_gcr_read(chip, ALS4K_GCR_A0_FIFO1_CURRENT_ADDR); - result &= 0xffff; + result = snd_als4k_gcr_read(chip, ALS4K_GCRA0_FIFO1_CURRENT_ADDR); spin_unlock(&chip->reg_lock); + result &= 0xffff; return bytes_to_frames( substream->runtime, result ); } @@ -452,46 +532,63 @@ static snd_pcm_uframes_t snd_als4000_playback_pointer(struct snd_pcm_substream * * return IRQ_HANDLED no matter whether we actually had an IRQ flag or not). * ALS4000a.PDF writes that while ACKing IRQ in PCI block will *not* ACK * the IRQ in the SB core, ACKing IRQ in SB block *will* ACK the PCI IRQ - * register (alt_port + ALS4K_IOB_0E_SB_MPU_IRQ). Probably something + * register (alt_port + ALS4K_IOB_0E_IRQTYPE_SB_CR1E_MPU). Probably something * could be optimized here to query/write one register only... * And even if both registers need to be queried, then there's still the * question of whether it's actually correct to ACK PCI IRQ before reading * SB IRQ like we do now, since ALS4000a.PDF mentions that PCI IRQ will *clear* * SB IRQ status. - * (hmm, page 38 mentions it the other way around!) + * (hmm, SPECS_PAGE: 38 mentions it the other way around!) * And do we *really* need the lock here for *reading* SB_DSP4_IRQSTATUS?? * */ static irqreturn_t snd_als4000_interrupt(int irq, void *dev_id) { struct snd_sb *chip = dev_id; - unsigned gcr_status; - unsigned sb_status; - - /* find out which bit of the ALS4000 produced the interrupt */ - gcr_status = inb(chip->alt_port + ALS4K_IOB_0E_SB_MPU_IRQ); - - if ((gcr_status & 0x80) && (chip->playback_substream)) /* playback */ + unsigned pci_irqstatus; + unsigned sb_irqstatus; + + /* find out which bit of the ALS4000 PCI block produced the interrupt, + SPECS_PAGE: 38, 5 */ + pci_irqstatus = snd_als4k_iobase_readb(chip->alt_port, + ALS4K_IOB_0E_IRQTYPE_SB_CR1E_MPU); + if ((pci_irqstatus & ALS4K_IOB_0E_SB_DMA_IRQ) + && (chip->playback_substream)) /* playback */ snd_pcm_period_elapsed(chip->playback_substream); - if ((gcr_status & 0x40) && (chip->capture_substream)) /* capturing */ + if ((pci_irqstatus & ALS4K_IOB_0E_CR1E_IRQ) + && (chip->capture_substream)) /* capturing */ snd_pcm_period_elapsed(chip->capture_substream); - if ((gcr_status & 0x10) && (chip->rmidi)) /* MPU401 interrupt */ + if ((pci_irqstatus & ALS4K_IOB_0E_MPU_IRQ) + && (chip->rmidi)) /* MPU401 interrupt */ snd_mpu401_uart_interrupt(irq, chip->rmidi->private_data); - /* release the gcr */ - outb(gcr_status, chip->alt_port + ALS4K_IOB_0E_SB_MPU_IRQ); + /* ACK the PCI block IRQ */ + snd_als4k_iobase_writeb(chip->alt_port, + ALS4K_IOB_0E_IRQTYPE_SB_CR1E_MPU, pci_irqstatus); spin_lock(&chip->mixer_lock); - sb_status = snd_sbmixer_read(chip, SB_DSP4_IRQSTATUS); + /* SPECS_PAGE: 20 */ + sb_irqstatus = snd_sbmixer_read(chip, SB_DSP4_IRQSTATUS); spin_unlock(&chip->mixer_lock); - if (sb_status & SB_IRQTYPE_8BIT) + if (sb_irqstatus & SB_IRQTYPE_8BIT) snd_sb_ack_8bit(chip); - if (sb_status & SB_IRQTYPE_16BIT) + if (sb_irqstatus & SB_IRQTYPE_16BIT) snd_sb_ack_16bit(chip); - if (sb_status & SB_IRQTYPE_MPUIN) + if (sb_irqstatus & SB_IRQTYPE_MPUIN) inb(chip->mpu_port); - if (sb_status & 0x20) - inb(SBP(chip, RESET)); - return IRQ_HANDLED; + if (sb_irqstatus & ALS4K_IRQTYPE_CR1E_DMA) + snd_als4k_iobase_readb(chip->alt_port, + ALS4K_IOB_16_ACK_FOR_CR1E); + + /* printk(KERN_INFO "als4000: irq 0x%04x 0x%04x\n", + pci_irqstatus, sb_irqstatus); */ + + /* only ack the things we actually handled above */ + return IRQ_RETVAL( + (pci_irqstatus & (ALS4K_IOB_0E_SB_DMA_IRQ|ALS4K_IOB_0E_CR1E_IRQ| + ALS4K_IOB_0E_MPU_IRQ)) + || (sb_irqstatus & (SB_IRQTYPE_8BIT|SB_IRQTYPE_16BIT| + SB_IRQTYPE_MPUIN|ALS4K_IRQTYPE_CR1E_DMA)) + ); } /*****************************************************************/ @@ -603,7 +700,8 @@ static int __devinit snd_als4000_pcm(struct snd_sb *chip, int device) struct snd_pcm *pcm; int err; - if ((err = snd_pcm_new(chip->card, "ALS4000 DSP", device, 1, 1, &pcm)) < 0) + err = snd_pcm_new(chip->card, "ALS4000 DSP", device, 1, 1, &pcm); + if (err < 0) return err; pcm->private_data = chip; pcm->info_flags = SNDRV_PCM_INFO_JOINT_DUPLEX; @@ -637,34 +735,38 @@ static void snd_als4000_set_addr(unsigned long iobase, cfg1 |= (game_io | 1) << 16; if (opl_io > 0) cfg1 |= (opl_io | 1); - snd_als4000_gcr_write_addr(iobase, ALS4K_GCR_A8_LEGACY_CFG1, cfg1); - snd_als4000_gcr_write_addr(iobase, ALS4K_GCR_A9_LEGACY_CFG2, cfg2); + snd_als4k_gcr_write_addr(iobase, ALS4K_GCRA8_LEGACY_CFG1, cfg1); + snd_als4k_gcr_write_addr(iobase, ALS4K_GCRA9_LEGACY_CFG2, cfg2); } static void snd_als4000_configure(struct snd_sb *chip) { - unsigned tmp; + u8 tmp; int i; /* do some more configuration */ spin_lock_irq(&chip->mixer_lock); - tmp = snd_sbmixer_read(chip, 0xc0); - snd_sbmixer_write(chip, 0xc0, tmp|0x80); - /* always select DMA channel 0, since we do not actually use DMA */ + tmp = snd_als4_cr_read(chip, ALS4K_CR0_SB_CONFIG); + snd_als4_cr_write(chip, ALS4K_CR0_SB_CONFIG, + tmp|ALS4K_CR0_MX80_81_REG_WRITE_ENABLE); + /* always select DMA channel 0, since we do not actually use DMA + * SPECS_PAGE: 19/20 */ snd_sbmixer_write(chip, SB_DSP4_DMASETUP, SB_DMASETUP_DMA0); - snd_sbmixer_write(chip, 0xc0, tmp&0x7f); + snd_als4_cr_write(chip, ALS4K_CR0_SB_CONFIG, + tmp & ~ALS4K_CR0_MX80_81_REG_WRITE_ENABLE); spin_unlock_irq(&chip->mixer_lock); spin_lock_irq(&chip->reg_lock); /* enable interrupts */ - snd_als4000_gcr_write(chip, ALS4K_GCR_8C_MISC_CTRL, - ALS4K_GCR_8C_IRQ_MASK_CTRL_ENABLE); + snd_als4k_gcr_write(chip, ALS4K_GCR8C_MISC_CTRL, + ALS4K_GCR8C_IRQ_MASK_CTRL_ENABLE); - for (i = ALS4K_GCR_91_DMA0_ADDR; i <= ALS4K_GCR_96_DMA3_MODE_COUNT; ++i) - snd_als4000_gcr_write(chip, i, 0); + /* SPECS_PAGE: 39 */ + for (i = ALS4K_GCR91_DMA0_ADDR; i <= ALS4K_GCR96_DMA3_MODE_COUNT; ++i) + snd_als4k_gcr_write(chip, i, 0); - snd_als4000_gcr_write(chip, ALS4K_GCR_99_DMA_EMULATION_CTRL, - snd_als4000_gcr_read(chip, ALS4K_GCR_99_DMA_EMULATION_CTRL)); + snd_als4k_gcr_write(chip, ALS4K_GCR99_DMA_EMULATION_CTRL, + snd_als4k_gcr_read(chip, ALS4K_GCR99_DMA_EMULATION_CTRL)); spin_unlock_irq(&chip->reg_lock); } @@ -739,7 +841,7 @@ static void snd_card_als4000_free( struct snd_card *card ) struct snd_card_als4000 *acard = card->private_data; /* make sure that interrupts are disabled */ - snd_als4000_gcr_write_addr(acard->iobase, ALS4K_GCR_8C_MISC_CTRL, 0); + snd_als4k_gcr_write_addr(acard->iobase, ALS4K_GCR8C_MISC_CTRL, 0); /* free resources */ snd_als4000_free_gameport(acard); pci_release_regions(acard->pci); @@ -788,7 +890,7 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci, pci_set_master(pci); card = snd_card_new(index[dev], id[dev], THIS_MODULE, - sizeof( struct snd_card_als4000 ) ); + sizeof(*acard) /* private_data: acard */); if (card == NULL) { pci_release_regions(pci); pci_disable_device(pci); @@ -806,6 +908,7 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci, if ((err = snd_sbdsp_create(card, iobase + ALS4K_IOB_10_ADLIB_ADDR0, pci->irq, + /* internally registered as IRQF_SHARED in case of ALS4000 SB */ snd_als4000_interrupt, -1, -1, @@ -835,8 +938,10 @@ static int __devinit snd_card_als4000_probe(struct pci_dev *pci, goto out_err; } /* FIXME: ALS4000 has interesting MPU401 configuration features - * at CR 0x1A (pass-thru / UART switching, fast MIDI clock, etc.), - * however there doesn't seem to be an ALSA API for this... */ + * at ALS4K_CR1A_MPU401_UART_MODE_CONTROL + * (pass-thru / UART switching, fast MIDI clock, etc.), + * however there doesn't seem to be an ALSA API for this... + * SPECS_PAGE: 21 */ if ((err = snd_als4000_pcm(chip, 0)) < 0) { goto out_err; -- cgit v1.2.3 From d67f49b0211ff6cc2192bef884cb7b27acb32c56 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Mon, 25 Aug 2008 08:11:50 +0200 Subject: ALSA: Cosmetic change: CA0106 on MSI K8N Diamond PLUS Motherboard Make ',' delimited with space as for other entries in table. Signed-off-by: Jaroslav Kysela --- sound/pci/ca0106/ca0106_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/ca0106/ca0106_main.c b/sound/pci/ca0106/ca0106_main.c index 6abe8a3bd36..a7d89662acf 100644 --- a/sound/pci/ca0106/ca0106_main.c +++ b/sound/pci/ca0106/ca0106_main.c @@ -254,7 +254,7 @@ static struct snd_ca0106_details ca0106_chip_details[] = { .name = "MSI K8N Diamond MB", .gpio_type = 2, .i2c_adc = 1, - .spi_dac = 2 }, + .spi_dac = 2 } , /* Shuttle XPC SD31P which has an onboard Creative Labs * Sound Blaster Live! 24-bit EAX * high-definition 7.1 audio processor". -- cgit v1.2.3 From ea1fb29ac95dea6b3063d6bce512faae9fec6a89 Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Tue, 26 Aug 2008 12:58:38 +0200 Subject: ALSA: hda - fix spaces in patch_realtek.c Signed-off-by: Kailang Yang Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 176 +++++++++++++++++++++--------------------- 1 file changed, 88 insertions(+), 88 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index f2049365e23..3e594b2e193 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -201,12 +201,12 @@ enum { ALC883_ACER, ALC883_ACER_ASPIRE, ALC883_MEDION, - ALC883_MEDION_MD2, + ALC883_MEDION_MD2, ALC883_LAPTOP_EAPD, ALC883_LENOVO_101E_2ch, ALC883_LENOVO_NB0763, ALC888_LENOVO_MS7195_DIG, - ALC883_HAIER_W66, + ALC883_HAIER_W66, ALC888_3ST_HP, ALC888_6ST_DELL, ALC883_MITAC, @@ -399,7 +399,7 @@ static int alc_ch_mode_put(struct snd_kcontrol *kcontrol, /* * Control the mode of pin widget settings via the mixer. "pc" is used - * instead of "%" to avoid consequences of accidently treating the % as + * instead of "%" to avoid consequences of accidently treating the % as * being part of a format specifier. Maximum allowed length of a value is * 63 characters plus NULL terminator. * @@ -430,7 +430,7 @@ static unsigned char alc_pin_mode_values[] = { #define ALC_PIN_DIR_IN_NOMICBIAS 0x03 #define ALC_PIN_DIR_INOUT_NOMICBIAS 0x04 -/* Info about the pin modes supported by the different pin direction modes. +/* Info about the pin modes supported by the different pin direction modes. * For each direction the minimum and maximum values are given. */ static signed char alc_pin_mode_dir_info[5][2] = { @@ -503,7 +503,7 @@ static int alc_pin_mode_put(struct snd_kcontrol *kcontrol, AC_VERB_SET_PIN_WIDGET_CONTROL, alc_pin_mode_values[val]); - /* Also enable the retasking pin's input/output as required + /* Also enable the retasking pin's input/output as required * for the requested pin mode. Enum values of 2 or less are * input modes. * @@ -708,7 +708,7 @@ static void setup_preset(struct alc_spec *spec, i++) spec->init_verbs[spec->num_init_verbs++] = preset->init_verbs[i]; - + spec->channel_mode = preset->channel_mode; spec->num_channel_mode = preset->num_channel_mode; spec->need_dac_fix = preset->need_dac_fix; @@ -719,7 +719,7 @@ static void setup_preset(struct alc_spec *spec, spec->multiout.dac_nids = preset->dac_nids; spec->multiout.dig_out_nid = preset->dig_out_nid; spec->multiout.hp_nid = preset->hp_nid; - + spec->num_mux_defs = preset->num_mux_defs; if (!spec->num_mux_defs) spec->num_mux_defs = 1; @@ -856,7 +856,7 @@ static void alc_subsystem_id(struct hda_codec *codec, if ((ass != codec->bus->pci->subsystem_device) && (ass & 1)) goto do_sku; - /* + /* * 31~30 : port conetcivity * 29~21 : reserve * 20 : PCBEEP input @@ -947,7 +947,7 @@ do_sku: tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); snd_hda_codec_write(codec, 0x20, 0, - AC_VERB_SET_COEF_INDEX, 7); + AC_VERB_SET_COEF_INDEX, 7); snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp | 0x2010); @@ -962,7 +962,7 @@ do_sku: tmp = snd_hda_codec_read(codec, 0x20, 0, AC_VERB_GET_PROC_COEF, 0); snd_hda_codec_write(codec, 0x20, 0, - AC_VERB_SET_COEF_INDEX, 7); + AC_VERB_SET_COEF_INDEX, 7); snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_PROC_COEF, tmp | 0x3000); @@ -971,7 +971,7 @@ do_sku: default: break; } - + /* is laptop or Desktop and enable the function "Mute internal speaker * when the external headphone out jack is plugged" */ @@ -1007,6 +1007,7 @@ do_sku: snd_hda_codec_write(codec, spec->autocfg.hp_pins[0], 0, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT); + spec->unsol_event = alc_sku_unsol_event; } @@ -1297,7 +1298,7 @@ static struct snd_kcontrol_new alc880_six_stack_mixer[] = { * * The system also has a pair of internal speakers, and a headphone jack. * These are both connected to Line2 on the codec, hence to DAC 02. - * + * * There is a variable resistor to control the speaker or headphone * volume. This is a hardware-only device without a software API. * @@ -1825,7 +1826,7 @@ static struct hda_verb alc880_pin_6stack_init_verbs[] = { {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, - + { } }; @@ -1870,7 +1871,7 @@ static struct hda_verb alc880_uniwill_init_verbs[] = { /* * Uniwill P53 -* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19, +* HP = 0x14, InternalSpeaker = 0x15, mic = 0x19, */ static struct hda_verb alc880_uniwill_p53_init_verbs[] = { {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ @@ -1969,7 +1970,7 @@ static void alc880_uniwill_p53_hp_automute(struct hda_codec *codec) static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec) { unsigned int present; - + present = snd_hda_codec_read(codec, 0x21, 0, AC_VERB_GET_VOLUME_KNOB_CONTROL, 0); present &= HDA_AMP_VOLMASK; @@ -2051,7 +2052,7 @@ static struct hda_verb alc880_pin_asus_init_verbs[] = { {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, - + { } }; @@ -3688,7 +3689,7 @@ 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]; @@ -4483,7 +4484,7 @@ static struct hda_verb alc260_fujitsu_init_verbs[] = { {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, - /* Ensure Line1 pin widget takes its input from the OUT1 sum bus + /* Ensure Line1 pin widget takes its input from the OUT1 sum bus * when acting as an output. */ {0x0d, AC_VERB_SET_CONNECT_SEL, 0}, @@ -4508,14 +4509,14 @@ static struct hda_verb alc260_fujitsu_init_verbs[] = { * stage. */ {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - /* Unmute input buffer of pin widget used for Line-in (no equiv + /* Unmute input buffer of pin widget used for Line-in (no equiv * mixer ctrl) */ {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* Mute capture amp left and right */ {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - /* Set ADC connection select to match default mixer setting - line + /* Set ADC connection select to match default mixer setting - line * in (on mic1 pin) */ {0x04, AC_VERB_SET_CONNECT_SEL, 0x00}, @@ -4569,7 +4570,7 @@ static struct hda_verb alc260_acer_init_verbs[] = { {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, - /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum + /* Ensure Mic1 and Line1 pin widgets take input from the OUT1 sum * bus when acting as outputs. */ {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, @@ -4691,7 +4692,7 @@ static hda_nid_t alc260_test_adc_nids[2] = { 0x04, 0x05, }; /* For testing the ALC260, each input MUX needs its own definition since - * the signal assignments are different. This assumes that the first ADC + * the signal assignments are different. This assumes that the first ADC * is NID 0x04. */ static struct hda_input_mux alc260_test_capture_sources[2] = { @@ -4774,7 +4775,7 @@ static struct snd_kcontrol_new alc260_test_mixer[] = { /* Switches to allow the digital IO pins to be enabled. The datasheet * is ambigious as to which NID is which; testing on laptops which - * make this output available should provide clarification. + * make this output available should provide clarification. */ ALC_SPDIF_CTRL_SWITCH("SPDIF Playback Switch", 0x03, 0x01), ALC_SPDIF_CTRL_SWITCH("SPDIF Capture Switch", 0x06, 0x01), @@ -4810,7 +4811,7 @@ static struct hda_verb alc260_test_init_verbs[] = { {0x03, AC_VERB_SET_DIGI_CONVERT_1, 0}, {0x06, AC_VERB_SET_DIGI_CONVERT_1, 0}, - /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the + /* Ensure mic1, mic2, line1 and line2 pin widgets take input from the * OUT1 sum bus when acting as an output. */ {0x0b, AC_VERB_SET_CONNECT_SEL, 0}, @@ -4902,7 +4903,7 @@ static int alc260_add_playback_controls(struct alc_spec *spec, hda_nid_t nid, sw_val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); } else return 0; /* N/A */ - + snprintf(name, sizeof(name), "%s Playback Volume", pfx); err = add_control(spec, ALC_CTL_WIDGET_VOL, name, vol_val); if (err < 0) @@ -5008,7 +5009,7 @@ static void alc260_auto_init_multi_out(struct hda_codec *codec) 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) alc260_auto_set_output_and_unmute(codec, nid, PIN_OUT, 0); @@ -5050,7 +5051,7 @@ static struct hda_verb alc260_volume_init_verbs[] = { {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x05, AC_VERB_SET_CONNECT_SEL, 0x00}, {0x05, 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 @@ -5079,7 +5080,7 @@ static struct hda_verb alc260_volume_init_verbs[] = { {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - + { } }; @@ -5938,7 +5939,7 @@ static struct hda_verb alc882_targa_verbs[] = { {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - + {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ @@ -5954,7 +5955,7 @@ static struct hda_verb alc882_targa_verbs[] = { static void alc882_targa_automute(struct hda_codec *codec) { unsigned int present; - + present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0, @@ -5980,7 +5981,7 @@ static struct hda_verb alc882_asus_a7j_verbs[] = { {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - + {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ @@ -5998,7 +5999,7 @@ static struct hda_verb alc882_asus_a7m_verbs[] = { {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - + {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front */ @@ -6324,7 +6325,7 @@ static struct alc_config_preset alc882_presets[] = { .channel_mode = alc882_3ST_6ch_modes, .need_dac_fix = 1, .input_mux = &alc882_capture_source, - }, + }, [ALC882_ASUS_A7M] = { .mixers = { alc882_asus_a7m_mixer, alc882_chmode_mixer }, .init_verbs = { alc882_init_verbs, alc882_eapd_verbs, @@ -6337,14 +6338,14 @@ static struct alc_config_preset alc882_presets[] = { .channel_mode = alc880_threestack_modes, .need_dac_fix = 1, .input_mux = &alc882_capture_source, - }, + }, }; /* * Pin config fixes */ -enum { +enum { PINFIX_ABIT_AW9D_MAX }; @@ -7261,7 +7262,7 @@ static struct snd_kcontrol_new alc883_medion_md2_mixer[] = { .put = alc883_mux_enum_put, }, { } /* end */ -}; +}; static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), @@ -7473,7 +7474,7 @@ static struct hda_verb alc883_tagra_verbs[] = { {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - + {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line/surround */ {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ @@ -7560,7 +7561,7 @@ static struct hda_channel_mode alc888_3st_hp_modes[2] = { static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec) { unsigned int present; - + present = snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, @@ -7573,7 +7574,7 @@ static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec) static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec) { unsigned int present; - + present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, @@ -7603,7 +7604,7 @@ static struct hda_verb alc883_medion_md2_verbs[] = { static void alc883_medion_md2_automute(struct hda_codec *codec) { unsigned int present; - + present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, @@ -7758,7 +7759,7 @@ static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec, static void alc883_acer_aspire_automute(struct hda_codec *codec) { unsigned int present; - + present = snd_hda_codec_read(codec, 0x14, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, @@ -7795,7 +7796,7 @@ static struct hda_verb alc883_acer_eapd_verbs[] = { static void alc888_6st_dell_front_automute(struct hda_codec *codec) { unsigned int present; - + present = snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, @@ -8133,7 +8134,7 @@ static struct alc_config_preset alc883_presets[] = { .input_mux = &alc883_capture_source, .unsol_event = alc883_medion_md2_unsol_event, .init_hook = alc883_medion_md2_automute, - }, + }, [ALC883_LAPTOP_EAPD] = { .mixers = { alc883_base_mixer }, .init_verbs = { alc883_init_verbs, alc882_eapd_verbs }, @@ -8838,10 +8839,10 @@ static struct hda_verb alc262_init_verbs[] = { {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, {0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, - + {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, - + /* FIXME: use matrix-type input source selection */ /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ @@ -9467,7 +9468,7 @@ static struct hda_verb alc262_volume_init_verbs[] = { {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, - + /* set up input amps for analog loopback */ /* Amp Indices: DAC = 0, mixer = 1 */ {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, @@ -9522,7 +9523,7 @@ static struct hda_verb alc262_HP_BPC_init_verbs[] = { {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, - + /* * Set up output mixers (0x0c - 0x0e) */ @@ -9960,7 +9961,7 @@ static struct alc_config_preset alc262_presets[] = { .input_mux = &alc262_capture_source, .unsol_event = alc262_hippo_unsol_event, .init_hook = alc262_hippo_automute, - }, + }, [ALC262_ULTRA] = { .mixers = { alc262_ultra_mixer, alc262_ultra_capture_mixer }, .init_verbs = { alc262_ultra_verbs }, @@ -10056,7 +10057,7 @@ static int patch_alc262(struct hda_codec *codec) spec->stream_name_analog = "ALC262 Analog"; spec->stream_analog_playback = &alc262_pcm_analog_playback; spec->stream_analog_capture = &alc262_pcm_analog_capture; - + spec->stream_name_digital = "ALC262 Digital"; spec->stream_digital_playback = &alc262_pcm_digital_playback; spec->stream_digital_capture = &alc262_pcm_digital_capture; @@ -10092,7 +10093,7 @@ static int patch_alc262(struct hda_codec *codec) if (!spec->loopback.amplist) spec->loopback.amplist = alc262_loopbacks; #endif - + return 0; } @@ -10101,7 +10102,7 @@ static int patch_alc262(struct hda_codec *codec) */ #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID #define alc268_modes alc260_modes - + static hda_nid_t alc268_dac_nids[2] = { /* front, hp */ 0x02, 0x03 @@ -10237,7 +10238,6 @@ static struct hda_verb alc268_acer_verbs[] = { {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, - {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, { } }; @@ -10412,7 +10412,7 @@ static struct hda_verb alc268_base_init_verbs[] = { {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, /* Unmute Selector 23h,24h and set the default input to mic-in */ - + {0x23, AC_VERB_SET_CONNECT_SEL, 0x00}, {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, {0x24, AC_VERB_SET_CONNECT_SEL, 0x00}, @@ -10611,7 +10611,7 @@ static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec, nid = cfg->line_out_pins[0]; if (nid) - alc268_new_analog_output(spec, nid, "Front", 0); + alc268_new_analog_output(spec, nid, "Front", 0); nid = cfg->speaker_pins[0]; if (nid == 0x1d) { @@ -10633,7 +10633,7 @@ static int alc268_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 */ @@ -10654,7 +10654,7 @@ static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec, case 0x1a: idx1 = 2; /* Line In */ break; - case 0x1c: + case 0x1c: idx1 = 3; /* CD */ break; case 0x12: @@ -10666,7 +10666,7 @@ static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec, } 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; } @@ -10696,11 +10696,11 @@ static void alc268_auto_init_mono_speaker_out(struct hda_codec *codec) } dac_vol1 = dac_vol2 = 0xb000 | 0x40; /* set max volume */ - if (line_nid == 0x14) + if (line_nid == 0x14) dac_vol2 = AMP_OUT_ZERO; else if (line_nid == 0x15) dac_vol1 = AMP_OUT_ZERO; - if (hp_nid == 0x14) + if (hp_nid == 0x14) dac_vol2 = AMP_OUT_ZERO; else if (hp_nid == 0x15) dac_vol1 = AMP_OUT_ZERO; @@ -11026,7 +11026,7 @@ static int patch_alc268(struct hda_codec *codec) codec->patch_ops = alc_patch_ops; if (board_config == ALC268_AUTO) spec->init_hook = alc268_auto_init; - + return 0; } @@ -11284,7 +11284,7 @@ static void alc269_eeepc_dmic_inithook(struct hda_codec *codec) /* unsolicited event for HP jack sensing */ static void alc269_eeepc_amic_unsol_event(struct hda_codec *codec, - unsigned int res) + unsigned int res) { if ((res >> 26) == ALC880_HP_EVENT) alc269_speaker_automute(codec); @@ -11770,7 +11770,7 @@ static struct snd_kcontrol_new alc861_toshiba_mixer[] = { HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), - + /*Capture mixer control */ HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), @@ -11913,20 +11913,20 @@ static struct hda_verb alc861_base_init_verbs[] = { /* route front mic to ADC1*/ {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - + /* Unmute DAC0~3 & spdif out*/ {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - + /* Unmute Mixer 14 (mic) 1c (Line in)*/ {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - + /* Unmute Stereo Mixer 15 */ {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, @@ -11982,13 +11982,13 @@ static struct hda_verb alc861_threestack_init_verbs[] = { {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - + /* Unmute Mixer 14 (mic) 1c (Line in)*/ {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - + /* Unmute Stereo Mixer 15 */ {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, @@ -12044,13 +12044,13 @@ static struct hda_verb alc861_uniwill_m31_init_verbs[] = { {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - + /* Unmute Mixer 14 (mic) 1c (Line in)*/ {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - + /* Unmute Stereo Mixer 15 */ {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, @@ -12115,7 +12115,7 @@ static struct hda_verb alc861_asus_init_verbs[] = { {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - + /* Unmute Stereo Mixer 15 */ {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, @@ -12152,20 +12152,20 @@ static struct hda_verb alc861_auto_init_verbs[] = { */ /* {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, */ {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - + /* Unmute DAC0~3 & spdif out*/ {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - + /* Unmute Mixer 14 (mic) 1c (Line in)*/ {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x014, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x01c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - + /* Unmute Stereo Mixer 15 */ {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, @@ -12740,7 +12740,7 @@ static int patch_alc861(struct hda_codec *codec) if (!spec->loopback.amplist) spec->loopback.amplist = alc861_loopbacks; #endif - + return 0; } @@ -12994,7 +12994,7 @@ static struct snd_kcontrol_new alc861vd_hp_mixer[] = { HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("ATAPI Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), HDA_CODEC_MUTE("ATAPI Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), - + { } /* end */ }; @@ -13139,7 +13139,7 @@ static struct hda_verb alc861vd_lenovo_unsol_verbs[] = { {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}, + {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, {} }; @@ -13201,7 +13201,7 @@ static struct hda_verb alc861vd_dallas_verbs[] = { {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - + {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, @@ -13226,7 +13226,7 @@ static struct hda_verb alc861vd_dallas_verbs[] = { {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, - {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, + {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, { } /* end */ @@ -13385,7 +13385,7 @@ static struct alc_config_preset alc861vd_presets[] = { .input_mux = &alc861vd_hp_capture_source, .unsol_event = alc861vd_dallas_unsol_event, .init_hook = alc861vd_dallas_automute, - }, + }, }; /* @@ -14290,12 +14290,12 @@ static void alc662_eeepc_ep20_automute(struct hda_codec *codec) if (present) { /* mute internal speaker */ snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0, - HDA_AMP_MUTE, HDA_AMP_MUTE); + HDA_AMP_MUTE, HDA_AMP_MUTE); } else { /* unmute internal speaker if necessary */ mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0); snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0, - HDA_AMP_MUTE, mute); + HDA_AMP_MUTE, mute); } } @@ -14330,16 +14330,16 @@ static void alc663_m51va_mic_automute(struct hda_codec *codec) unsigned int present; present = snd_hda_codec_read(codec, 0x18, 0, - AC_VERB_GET_PIN_SENSE, 0) - & AC_PINSENSE_PRESENCE; + AC_VERB_GET_PIN_SENSE, 0) + & AC_PINSENSE_PRESENCE; snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE, - 0x7000 | (0x00 << 8) | (present ? 0 : 0x80)); + 0x7000 | (0x00 << 8) | (present ? 0 : 0x80)); snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE, - 0x7000 | (0x00 << 8) | (present ? 0 : 0x80)); + 0x7000 | (0x00 << 8) | (present ? 0 : 0x80)); snd_hda_codec_write_cache(codec, 0x22, 0, AC_VERB_SET_AMP_GAIN_MUTE, - 0x7000 | (0x09 << 8) | (present ? 0x80 : 0)); + 0x7000 | (0x09 << 8) | (present ? 0x80 : 0)); snd_hda_codec_write_cache(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE, - 0x7000 | (0x09 << 8) | (present ? 0x80 : 0)); + 0x7000 | (0x09 << 8) | (present ? 0x80 : 0)); } static void alc663_m51va_unsol_event(struct hda_codec *codec, @@ -14858,7 +14858,7 @@ static int alc662_parse_auto_config(struct hda_codec *codec) spec->num_mux_defs = 1; spec->input_mux = &spec->private_imux; - + spec->init_verbs[spec->num_init_verbs++] = alc662_auto_init_verbs; if (codec->vendor_id == 0x10ec0663) spec->init_verbs[spec->num_init_verbs++] = -- cgit v1.2.3 From 3f8783084aa03d04e7757ced337fa415744489a5 Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Tue, 26 Aug 2008 13:02:23 +0200 Subject: ALSA: hda - Add support of HP DC7600 Fixed the support of HP DC7600 with ALC260, which was formerly handled as model=hp-3013. Signed-off-by: Kailang Yang Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 85 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 83 insertions(+), 2 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 3e594b2e193..834dae74d7e 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -72,6 +72,7 @@ enum { enum { ALC260_BASIC, ALC260_HP, + ALC260_HP_DC7600, ALC260_HP_3013, ALC260_FUJITSU_S702X, ALC260_ACER, @@ -4130,6 +4131,33 @@ static struct snd_kcontrol_new alc260_hp_3013_mixer[] = { { } /* end */ }; +static struct hda_bind_ctls alc260_dc7600_bind_master_vol = { + .ops = &snd_hda_bind_vol, + .values = { + HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT), + HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT), + HDA_COMPOSE_AMP_VAL(0x0a, 3, 0, HDA_OUTPUT), + 0 + }, +}; + +static struct hda_bind_ctls alc260_dc7600_bind_switch = { + .ops = &snd_hda_bind_sw, + .values = { + HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT), + HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), + 0 + }, +}; + +static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = { + HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol), + HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch), + HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Headphone Playback Switch", 0x10, 0x0, HDA_OUTPUT), + { } /* end */ +}; + static struct hda_verb alc260_hp_3013_unsol_verbs[] = { {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, {}, @@ -4153,7 +4181,30 @@ static void alc260_hp_3013_unsol_event(struct hda_codec *codec, alc260_hp_3013_automute(codec); } -/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12, +static void alc260_hp_3012_automute(struct hda_codec *codec) +{ + unsigned int present, bits; + + present = snd_hda_codec_read(codec, 0x10, 0, + AC_VERB_GET_PIN_SENSE, 0) & AC_PINSENSE_PRESENCE; + + bits = present ? 0 : PIN_OUT; + snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, + bits); + snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, + bits); + snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, + bits); +} + +static void alc260_hp_3012_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + if ((res >> 26) == ALC880_HP_EVENT) + alc260_hp_3012_automute(codec); +} + +/* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12, * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10. */ static struct snd_kcontrol_new alc260_fujitsu_mixer[] = { @@ -4681,6 +4732,20 @@ static void alc260_replacer_672v_unsol_event(struct hda_codec *codec, alc260_replacer_672v_automute(codec); } +static struct hda_verb alc260_hp_dc7600_verbs[] = { + {0x05, AC_VERB_SET_CONNECT_SEL, 0x01}, + {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, + {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, + {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, + {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, + {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, + {} +}; + /* Test configuration for debugging, modelled after the ALC880 test * configuration. */ @@ -5178,7 +5243,7 @@ static struct snd_pci_quirk alc260_cfg_tbl[] = { SND_PCI_QUIRK(0x103c, 0x280a, "HP d5750", ALC260_HP_3013), SND_PCI_QUIRK(0x103c, 0x3010, "HP", ALC260_HP_3013), SND_PCI_QUIRK(0x103c, 0x3011, "HP", ALC260_HP_3013), - SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_3013), + SND_PCI_QUIRK(0x103c, 0x3012, "HP", ALC260_HP_DC7600), SND_PCI_QUIRK(0x103c, 0x3013, "HP", ALC260_HP_3013), SND_PCI_QUIRK(0x103c, 0x3014, "HP", ALC260_HP), SND_PCI_QUIRK(0x103c, 0x3015, "HP", ALC260_HP), @@ -5224,6 +5289,22 @@ static struct alc_config_preset alc260_presets[] = { .unsol_event = alc260_hp_unsol_event, .init_hook = alc260_hp_automute, }, + [ALC260_HP_DC7600] = { + .mixers = { alc260_hp_dc7600_mixer, + alc260_input_mixer, + alc260_capture_alt_mixer }, + .init_verbs = { alc260_init_verbs, + alc260_hp_dc7600_verbs }, + .num_dacs = ARRAY_SIZE(alc260_dac_nids), + .dac_nids = alc260_dac_nids, + .num_adc_nids = ARRAY_SIZE(alc260_hp_adc_nids), + .adc_nids = alc260_hp_adc_nids, + .num_channel_mode = ARRAY_SIZE(alc260_modes), + .channel_mode = alc260_modes, + .input_mux = &alc260_capture_source, + .unsol_event = alc260_hp_3012_unsol_event, + .init_hook = alc260_hp_3012_automute, + }, [ALC260_HP_3013] = { .mixers = { alc260_hp_3013_mixer, alc260_input_mixer, -- cgit v1.2.3 From 4e555fe5475437f5c05b9e1812959bf6d5cd50b9 Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Tue, 26 Aug 2008 13:05:55 +0200 Subject: ALSA: hda - Add support of Toshiba S06 Added the support of Toshiba S06 with ALC262 codec chip. Signed-off-by: Kailang Yang Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 115 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 834dae74d7e..e558264d1f5 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -102,6 +102,7 @@ enum { ALC262_ULTRA, ALC262_LENOVO_3000, ALC262_NEC, + ALC262_TOSHIBA_S06, ALC262_AUTO, ALC262_MODEL_LAST /* last tag */ }; @@ -8539,6 +8540,13 @@ static int patch_alc883(struct hda_codec *codec) #define alc262_modes alc260_modes #define alc262_capture_source alc882_capture_source +static hda_nid_t alc262_dmic_adc_nids[1] = { + /* ADC0 */ + 0x09 +}; + +static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 }; + static struct snd_kcontrol_new alc262_base_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), @@ -8945,6 +8953,12 @@ static struct hda_verb alc262_init_verbs[] = { { } }; +static struct hda_verb alc262_eapd_verbs[] = { + {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, + {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, + { } +}; + static struct hda_verb alc262_hippo_unsol_verbs[] = { {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, @@ -8971,6 +8985,91 @@ static struct hda_verb alc262_sony_unsol_verbs[] = { {} }; +static struct hda_input_mux alc262_dmic_capture_source = { + .num_items = 2, + .items = { + { "Int DMic", 0x9 }, + { "Mic", 0x0 }, + }, +}; + +static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = { + HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, 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, + /* The multiple "Capture Source" controls confuse alsamixer + * So call somewhat different.. + */ + /* .name = "Capture Source", */ + .name = "Input Source", + .count = 1, + .info = alc_mux_enum_info, + .get = alc_mux_enum_get, + .put = alc_mux_enum_put, + }, + { } /* end */ +}; + +static struct hda_verb alc262_toshiba_s06_verbs[] = { + {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, + {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, + {0x22, AC_VERB_SET_CONNECT_SEL, 0x09}, + {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, + {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, + {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, + {} +}; + +static void alc262_dmic_automute(struct hda_codec *codec) +{ + unsigned int present; + + present = snd_hda_codec_read(codec, 0x18, 0, + AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + snd_hda_codec_write(codec, 0x22, 0, + AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x09); +} + +/* toggle speaker-output according to the hp-jack state */ +static void alc262_toshiba_s06_speaker_automute(struct hda_codec *codec) +{ + unsigned int present; + unsigned char bits; + + present = snd_hda_codec_read(codec, 0x15, 0, + AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + bits = present ? 0 : PIN_OUT; + snd_hda_codec_write(codec, 0x14, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, bits); +} + + + +/* unsolicited event for HP jack sensing */ +static void alc262_toshiba_s06_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + if ((res >> 26) == ALC880_HP_EVENT) + alc262_toshiba_s06_speaker_automute(codec); + if ((res >> 26) == ALC880_MIC_EVENT) + alc262_dmic_automute(codec); + +} + +static void alc262_toshiba_s06_init_hook(struct hda_codec *codec) +{ + alc262_toshiba_s06_speaker_automute(codec); + alc262_dmic_automute(codec); +} + /* mute/unmute internal speaker according to the hp jack and mute state */ static void alc262_hippo_automute(struct hda_codec *codec) { @@ -9889,6 +9988,7 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = { SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD), SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1", ALC262_SONY_ASSAMD), + SND_PCI_QUIRK(0x1179, 0x0268, "Toshiba S06", ALC262_TOSHIBA_S06), SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU), SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU), SND_PCI_QUIRK(0x144d, 0xc032, "Samsung Q1 Ultra", ALC262_ULTRA), @@ -10080,6 +10180,21 @@ static struct alc_config_preset alc262_presets[] = { .channel_mode = alc262_modes, .input_mux = &alc262_capture_source, }, + [ALC262_TOSHIBA_S06] = { + .mixers = { alc262_toshiba_s06_mixer }, + .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs, + alc262_eapd_verbs }, + .num_dacs = ARRAY_SIZE(alc262_dac_nids), + .capsrc_nids = alc262_dmic_capsrc_nids, + .dac_nids = alc262_dac_nids, + .adc_nids = alc262_dmic_adc_nids, /* ADC0 */ + .dig_out_nid = ALC262_DIGOUT_NID, + .num_channel_mode = ARRAY_SIZE(alc262_modes), + .channel_mode = alc262_modes, + .input_mux = &alc262_dmic_capture_source, + .unsol_event = alc262_toshiba_s06_unsol_event, + .init_hook = alc262_toshiba_s06_init_hook, + }, }; static int patch_alc262(struct hda_codec *codec) -- cgit v1.2.3 From 8ef355da64ff087b6f26c4c28a14753861e83e4b Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Tue, 26 Aug 2008 13:10:22 +0200 Subject: ALSA: hda - Add support of Acer Aspire One Added the support of Acer Aspire One with ALC269 codec chip. Signed-off-by: Kailang Yang Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 95 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 95 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index e558264d1f5..99c1de639e9 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -113,6 +113,7 @@ enum { ALC268_3ST, ALC268_TOSHIBA, ALC268_ACER, + ALC268_ACER_ASPIRE_ONE, ALC268_DELL, ALC268_ZEPTO, #ifdef CONFIG_SND_DEBUG @@ -10358,6 +10359,14 @@ static struct hda_verb alc268_toshiba_verbs[] = { { } /* end */ }; +static struct hda_input_mux alc268_acer_lc_capture_source = { + .num_items = 2, + .items = { + { "i-Mic", 0x6 }, + { "E-Mic", 0x0 }, + }, +}; + /* Acer specific */ /* bind volumes of both NID 0x02 and 0x03 */ static struct hda_bind_ctls alc268_acer_bind_master_vol = { @@ -10410,6 +10419,21 @@ static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol, return change; } +static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = { + /* output mixer control */ + HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Master Playback Switch", + .info = snd_hda_mixer_amp_switch_info, + .get = snd_hda_mixer_amp_switch_get, + .put = alc268_acer_master_sw_put, + .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), + }, + HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT), + { } +}; + static struct snd_kcontrol_new alc268_acer_mixer[] = { /* output mixer control */ HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), @@ -10427,6 +10451,16 @@ static struct snd_kcontrol_new alc268_acer_mixer[] = { { } }; +static struct hda_verb alc268_acer_aspire_one_verbs[] = { + {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, + {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, + {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, + {0x23, AC_VERB_SET_CONNECT_SEL, 0x06}, + {0x23, AC_VERB_SET_AMP_GAIN_MUTE, 0xa017}, + { } +}; + static struct hda_verb alc268_acer_verbs[] = { {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */ {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, @@ -10460,6 +10494,47 @@ static void alc268_acer_init_hook(struct hda_codec *codec) alc268_acer_automute(codec, 1); } +/* toggle speaker-output according to the hp-jack state */ +static void alc268_aspire_one_speaker_automute(struct hda_codec *codec) +{ + unsigned int present; + unsigned char bits; + + present = snd_hda_codec_read(codec, 0x15, 0, + AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + bits = present ? AMP_IN_MUTE(0) : 0; + snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0, + AMP_IN_MUTE(0), bits); + snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1, + AMP_IN_MUTE(0), bits); +} + + +static void alc268_acer_mic_automute(struct hda_codec *codec) +{ + unsigned int present; + + present = snd_hda_codec_read(codec, 0x18, 0, + AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL, + present ? 0x0 : 0x6); +} + +static void alc268_acer_lc_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + if ((res >> 26) == ALC880_HP_EVENT) + alc268_aspire_one_speaker_automute(codec); + if ((res >> 26) == ALC880_MIC_EVENT) + alc268_acer_mic_automute(codec); +} + +static void alc268_acer_lc_init_hook(struct hda_codec *codec) +{ + alc268_aspire_one_speaker_automute(codec); + alc268_acer_mic_automute(codec); +} + static struct snd_kcontrol_new alc268_dell_mixer[] = { /* output mixer control */ HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), @@ -10987,6 +11062,7 @@ static const char *alc268_models[ALC268_MODEL_LAST] = { [ALC268_3ST] = "3stack", [ALC268_TOSHIBA] = "toshiba", [ALC268_ACER] = "acer", + [ALC268_ACER_ASPIRE_ONE] = "acer-aspire", [ALC268_DELL] = "dell", [ALC268_ZEPTO] = "zepto", #ifdef CONFIG_SND_DEBUG @@ -11001,6 +11077,8 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = { SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER), SND_PCI_QUIRK(0x1025, 0x0130, "Acer Extensa 5210", ALC268_ACER), SND_PCI_QUIRK(0x1025, 0x0136, "Acer Aspire 5315", ALC268_ACER), + SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One", + ALC268_ACER_ASPIRE_ONE), SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL), SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA), SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST), @@ -11078,6 +11156,23 @@ static struct alc_config_preset alc268_presets[] = { .unsol_event = alc268_acer_unsol_event, .init_hook = alc268_acer_init_hook, }, + [ALC268_ACER_ASPIRE_ONE] = { + .mixers = { alc268_acer_aspire_one_mixer, + alc268_capture_alt_mixer }, + .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, + alc268_acer_aspire_one_verbs }, + .num_dacs = ARRAY_SIZE(alc268_dac_nids), + .dac_nids = alc268_dac_nids, + .num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt), + .adc_nids = alc268_adc_nids_alt, + .capsrc_nids = alc268_capsrc_nids, + .hp_nid = 0x03, + .num_channel_mode = ARRAY_SIZE(alc268_modes), + .channel_mode = alc268_modes, + .input_mux = &alc268_acer_lc_capture_source, + .unsol_event = alc268_acer_lc_unsol_event, + .init_hook = alc268_acer_lc_init_hook, + }, [ALC268_DELL] = { .mixers = { alc268_dell_mixer, alc268_beep_mixer }, .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, -- cgit v1.2.3 From 60db6b53fb43421beb2ff3fe3e63412bf81620aa Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Tue, 26 Aug 2008 13:13:00 +0200 Subject: ALSA: hda - Add support of Quanta FL1 Added the support of Quanta FL1 with ALC269 code chip. Also a bit space clean-ups. Signed-off-by: Kailang Yang Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 250 +++++++++++++++++++++++++++++------------- 1 file changed, 175 insertions(+), 75 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 99c1de639e9..538d85440a3 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -126,6 +126,7 @@ enum { /* ALC269 models */ enum { ALC269_BASIC, + ALC269_QUANTA_FL1, ALC269_ASUS_EEEPC_P703, ALC269_ASUS_EEEPC_P901, ALC269_AUTO, @@ -11378,6 +11379,28 @@ static struct snd_kcontrol_new alc269_base_mixer[] = { { } /* end */ }; +static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = { + /* output mixer control */ + HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Master Playback Switch", + .info = snd_hda_mixer_amp_switch_info, + .get = snd_hda_mixer_amp_switch_get, + .put = alc268_acer_master_sw_put, + .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), + }, + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), + HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), + HDA_CODEC_VOLUME("Internal Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("PC Speaker Playback Volume", 0x0b, 0x04, HDA_INPUT), + HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x04, HDA_INPUT), + { } +}; + /* bind volumes of both NID 0x0c and 0x0d */ static struct hda_bind_ctls alc269_epc_bind_vol = { .ops = &snd_hda_bind_vol, @@ -11428,75 +11451,65 @@ static struct snd_kcontrol_new alc269_beep_mixer[] = { { } /* end */ }; -/* - * generic initialization of ADC, input mixers and output mixers - */ -static struct hda_verb alc269_init_verbs[] = { - /* - * Unmute ADC0 and set the default input to mic-in - */ - {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, +static struct hda_verb alc269_quanta_fl1_verbs[] = { + {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, + {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, + {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, + {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, + {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, + { } +}; - /* Mute input amps (PCBeep, 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_MUTE(0)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, +/* toggle speaker-output according to the hp-jack state */ +static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec) +{ + unsigned int present; + unsigned char bits; - /* - * Set up output mixers (0x0c - 0x0e) - */ - /* 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}, + present = snd_hda_codec_read(codec, 0x15, 0, + AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + bits = present ? AMP_IN_MUTE(0) : 0; + snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, + AMP_IN_MUTE(0), bits); + snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, + AMP_IN_MUTE(0), bits); - /* set up input amps for analog loopback */ - /* Amp Indices: DAC = 0, mixer = 1 */ - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + snd_hda_codec_write(codec, 0x20, 0, + AC_VERB_SET_COEF_INDEX, 0x0c); + snd_hda_codec_write(codec, 0x20, 0, + AC_VERB_SET_PROC_COEF, 0x680); - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, - {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, - {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, - {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, - {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, + snd_hda_codec_write(codec, 0x20, 0, + AC_VERB_SET_COEF_INDEX, 0x0c); + snd_hda_codec_write(codec, 0x20, 0, + AC_VERB_SET_PROC_COEF, 0x480); +} - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, +static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec) +{ + unsigned int present; - {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, - {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, + present = snd_hda_codec_read(codec, 0x18, 0, + AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + snd_hda_codec_write(codec, 0x23, 0, + AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1); +} - /* FIXME: use matrix-type input source selection */ - /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */ - /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, +static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + if ((res >> 26) == ALC880_HP_EVENT) + alc269_quanta_fl1_speaker_automute(codec); + if ((res >> 26) == ALC880_MIC_EVENT) + alc269_quanta_fl1_mic_automute(codec); +} - /* set EAPD */ - {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, - {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, - { } -}; +static void alc269_quanta_fl1_init_hook(struct hda_codec *codec) +{ + alc269_quanta_fl1_speaker_automute(codec); + alc269_quanta_fl1_mic_automute(codec); +} static struct hda_verb alc269_eeepc_dmic_init_verbs[] = { {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, @@ -11523,42 +11536,42 @@ static struct hda_verb alc269_eeepc_amic_init_verbs[] = { static void alc269_speaker_automute(struct hda_codec *codec) { unsigned int present; - unsigned int bits; + unsigned char bits; present = snd_hda_codec_read(codec, 0x15, 0, - AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; bits = present ? AMP_IN_MUTE(0) : 0; snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, - AMP_IN_MUTE(0), bits); + AMP_IN_MUTE(0), bits); snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, - AMP_IN_MUTE(0), bits); + AMP_IN_MUTE(0), bits); } static void alc269_eeepc_dmic_automute(struct hda_codec *codec) { unsigned int present; - present = snd_hda_codec_read(codec, 0x18, 0, AC_VERB_GET_PIN_SENSE, 0) - & AC_PINSENSE_PRESENCE; - snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_CONNECT_SEL, - present ? 0 : 5); + present = snd_hda_codec_read(codec, 0x18, 0, + AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + snd_hda_codec_write(codec, 0x23, 0, + AC_VERB_SET_CONNECT_SEL, (present ? 0 : 5)); } static void alc269_eeepc_amic_automute(struct hda_codec *codec) { unsigned int present; - present = snd_hda_codec_read(codec, 0x18, 0, AC_VERB_GET_PIN_SENSE, 0) - & AC_PINSENSE_PRESENCE; + present = snd_hda_codec_read(codec, 0x18, 0, + AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE, - present ? AMP_IN_UNMUTE(0) : AMP_IN_MUTE(0)); + 0x7000 | (0x00 << 8) | (present ? 0 : 0x80)); snd_hda_codec_write(codec, 0x24, 0, AC_VERB_SET_AMP_GAIN_MUTE, - present ? AMP_IN_MUTE(1) : AMP_IN_UNMUTE(1)); + 0x7000 | (0x01 << 8) | (present ? 0x80 : 0)); } /* unsolicited event for HP jack sensing */ static void alc269_eeepc_dmic_unsol_event(struct hda_codec *codec, - unsigned int res) + unsigned int res) { if ((res >> 26) == ALC880_HP_EVENT) alc269_speaker_automute(codec); @@ -11590,6 +11603,76 @@ static void alc269_eeepc_amic_inithook(struct hda_codec *codec) alc269_eeepc_amic_automute(codec); } +/* + * generic initialization of ADC, input mixers and output mixers + */ +static struct hda_verb alc269_init_verbs[] = { + /* + * Unmute ADC0 and set the default input to mic-in + */ + {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + + /* Mute input amps (PCBeep, 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_MUTE(0)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, + {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, + + /* + * Set up output mixers (0x0c - 0x0e) + */ + /* 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}, + + /* set up input amps for analog loopback */ + /* Amp Indices: DAC = 0, mixer = 1 */ + {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + + {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, + {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, + {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, + {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, + + {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, + {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, + {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, + {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, + {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, + + {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, + {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, + + /* FIXME: use matrix-type input source selection */ + /* Mixer elements: 0x18, 19, 1a, 1b, 1d, 0b */ + /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ + {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, + {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, + + /* set EAPD */ + {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, + {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, + { } +}; + /* add playback controls from the parsed DAC table */ static int alc269_auto_create_multi_out_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg) @@ -11758,14 +11841,19 @@ static void alc269_auto_init(struct hda_codec *codec) * configuration and preset */ static const char *alc269_models[ALC269_MODEL_LAST] = { - [ALC269_BASIC] = "basic", + [ALC269_BASIC] = "basic", + [ALC269_QUANTA_FL1] = "Quanta", + [ALC269_ASUS_EEEPC_P901] = "Asus_Epc_Dmic" }; static struct snd_pci_quirk alc269_cfg_tbl[] = { + SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1), SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", ALC269_ASUS_EEEPC_P703), SND_PCI_QUIRK(0x1043, 0x831a, "ASUS Eeepc P901", ALC269_ASUS_EEEPC_P901), + SND_PCI_QUIRK(0x1043, 0x834a, "ASUS Eeepc S101", + ALC269_ASUS_EEEPC_P901), {} }; @@ -11780,6 +11868,18 @@ static struct alc_config_preset alc269_presets[] = { .channel_mode = alc269_modes, .input_mux = &alc269_capture_source, }, + [ALC269_QUANTA_FL1] = { + .mixers = { alc269_quanta_fl1_mixer }, + .init_verbs = { alc269_init_verbs, alc269_quanta_fl1_verbs }, + .num_dacs = ARRAY_SIZE(alc269_dac_nids), + .dac_nids = alc269_dac_nids, + .hp_nid = 0x03, + .num_channel_mode = ARRAY_SIZE(alc269_modes), + .channel_mode = alc269_modes, + .input_mux = &alc269_capture_source, + .unsol_event = alc269_quanta_fl1_unsol_event, + .init_hook = alc269_quanta_fl1_init_hook, + }, [ALC269_ASUS_EEEPC_P703] = { .mixers = { alc269_eeepc_mixer, alc269_epc_capture_mixer }, .init_verbs = { alc269_init_verbs, -- cgit v1.2.3 From e2757d5efad01dae6986e1f84590898e47231964 Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Tue, 26 Aug 2008 13:17:46 +0200 Subject: ALSA: hda - support more ALC888 devices - Add Lenovo Sky support (17aa:101d) - Add ASUS M90V support (1043:8317) - Add ASUS Eee 1601 support (1043:835f) Signed-off-by: Kailang Yang Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 322 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 312 insertions(+), 10 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 538d85440a3..d748d19f163 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -210,6 +210,7 @@ enum { ALC883_LENOVO_101E_2ch, ALC883_LENOVO_NB0763, ALC888_LENOVO_MS7195_DIG, + ALC888_LENOVO_SKY, ALC883_HAIER_W66, ALC888_3ST_HP, ALC888_6ST_DELL, @@ -217,6 +218,8 @@ enum { ALC883_CLEVO_M720, ALC883_FUJITSU_PI2515, ALC883_3ST_6ch_INTEL, + ALC888_ASUS_M90V, + ALC888_ASUS_EEE1601, ALC883_AUTO, ALC883_MODEL_LAST, }; @@ -6808,6 +6811,23 @@ static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = { }, }; +static struct hda_input_mux alc883_lenovo_sky_capture_source = { + .num_items = 3, + .items = { + { "Mic", 0x0 }, + { "Front Mic", 0x1 }, + { "Line", 0x4 }, + }, +}; + +static struct hda_input_mux alc883_asus_eee1601_capture_source = { + .num_items = 2, + .items = { + { "Mic", 0x0 }, + { "Line", 0x2 }, + }, +}; + #define alc883_mux_enum_info alc_mux_enum_info #define alc883_mux_enum_get alc_mux_enum_get /* ALC883 has the ALC882-type input selection */ @@ -7122,13 +7142,11 @@ static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = { HDA_CODEC_MUTE("PC Speaker Playback Switch", 0x0b, 0x05, HDA_INPUT), HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), - HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, /* .name = "Capture Source", */ .name = "Input Source", - .count = 2, + .count = 1, .info = alc883_mux_enum_info, .get = alc883_mux_enum_get, .put = alc883_mux_enum_put, @@ -7373,6 +7391,87 @@ static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { { } /* end */ }; +static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = { + HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), + HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Surround Playback Switch", 0x0e, 2, HDA_INPUT), + HDA_CODEC_VOLUME_MONO("Center Playback Volume", + 0x0d, 1, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0d, 2, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE_MONO("Center Playback Switch", 0x0d, 1, 2, HDA_INPUT), + HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x0d, 2, 2, HDA_INPUT), + HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), + HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("iSpeaker Playback Switch", 0x1a, 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_VOLUME("Mic Boost", 0x18, 0, 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_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_MUTE("Front 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), + HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x09, 0x0, HDA_INPUT), + HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x09, 0x0, HDA_INPUT), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + /* .name = "Capture Source", */ + .name = "Input Source", + .count = 2, + .info = alc883_mux_enum_info, + .get = alc883_mux_enum_get, + .put = alc883_mux_enum_put, + }, + { } /* end */ +}; + +static struct hda_bind_ctls alc883_bind_cap_vol = { + .ops = &snd_hda_bind_vol, + .values = { + HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), + HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), + 0 + }, +}; + +static struct hda_bind_ctls alc883_bind_cap_switch = { + .ops = &snd_hda_bind_sw, + .values = { + HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), + HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), + 0 + }, +}; + +static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = { + HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), + HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), + HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 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, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol), + HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch), + { + .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[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -7386,7 +7485,7 @@ static struct snd_kcontrol_new alc883_chmode_mixer[] = { static struct hda_verb alc883_init_verbs[] = { /* ADC1: mute amp left and right */ - {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x08, AC_VERB_SET_CONNECT_SEL, 0x00}, /* ADC2: mute amp left and right */ {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, @@ -7451,14 +7550,14 @@ static struct hda_verb alc883_init_verbs[] = { /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ /* Input mixer2 */ {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(4)}, + {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, + {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, + {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, /* Input mixer3 */ {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_MUTE(1)}, + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, { } }; @@ -7608,6 +7707,18 @@ static struct hda_verb alc883_haier_w66_verbs[] = { { } /* end */ }; +static struct hda_verb alc888_lenovo_sky_verbs[] = { + {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x0e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, + {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, + { } /* end */ +}; + static struct hda_verb alc888_3st_hp_verbs[] = { {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */ {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */ @@ -7904,6 +8015,50 @@ static void alc888_6st_dell_unsol_event(struct hda_codec *codec, } } +static void alc888_lenovo_sky_front_automute(struct hda_codec *codec) +{ + unsigned int mute; + unsigned int present; + + snd_hda_codec_read(codec, 0x1b, 0, AC_VERB_SET_PIN_SENSE, 0); + present = snd_hda_codec_read(codec, 0x1b, 0, + AC_VERB_GET_PIN_SENSE, 0); + present = (present & 0x80000000) != 0; + if (present) { + /* mute internal speaker */ + snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, + HDA_AMP_MUTE, HDA_AMP_MUTE); + snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, + HDA_AMP_MUTE, HDA_AMP_MUTE); + snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, + HDA_AMP_MUTE, HDA_AMP_MUTE); + snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0, + HDA_AMP_MUTE, HDA_AMP_MUTE); + snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0, + HDA_AMP_MUTE, HDA_AMP_MUTE); + } else { + /* unmute internal speaker if necessary */ + mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0); + snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, + HDA_AMP_MUTE, mute); + snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, + HDA_AMP_MUTE, mute); + snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, + HDA_AMP_MUTE, mute); + snd_hda_codec_amp_stereo(codec, 0x17, HDA_OUTPUT, 0, + HDA_AMP_MUTE, mute); + snd_hda_codec_amp_stereo(codec, 0x1a, HDA_OUTPUT, 0, + HDA_AMP_MUTE, mute); + } +} + +static void alc883_lenovo_sky_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + if ((res >> 26) == ALC880_HP_EVENT) + alc888_lenovo_sky_front_automute(codec); +} + /* * generic initialization of ADC, input mixers and output mixers */ @@ -7988,6 +8143,105 @@ static struct snd_kcontrol_new alc883_capture_mixer[] = { { } /* end */ }; +static struct hda_verb alc888_asus_m90v_verbs[] = { + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + /* enable unsolicited event */ + {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, + {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, + { } /* end */ +}; + +static void alc883_nb_mic_automute(struct hda_codec *codec) +{ + unsigned int present; + + present = snd_hda_codec_read(codec, 0x18, 0, + AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE, + 0x7000 | (0x00 << 8) | (present ? 0 : 0x80)); + snd_hda_codec_write(codec, 0x23, 0, AC_VERB_SET_AMP_GAIN_MUTE, + 0x7000 | (0x01 << 8) | (present ? 0x80 : 0)); +} + +static void alc883_M90V_speaker_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) + & AC_PINSENSE_PRESENCE; + bits = present ? 0 : PIN_OUT; + snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, + bits); + snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, + bits); + snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, + bits); +} + +static void alc883_mode2_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + switch (res >> 26) { + case ALC880_HP_EVENT: + alc883_M90V_speaker_automute(codec); + break; + case ALC880_MIC_EVENT: + alc883_nb_mic_automute(codec); + break; + } +} + +static void alc883_mode2_inithook(struct hda_codec *codec) +{ + alc883_M90V_speaker_automute(codec); + alc883_nb_mic_automute(codec); +} + +static struct hda_verb alc888_asus_eee1601_verbs[] = { + {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, + {0x20, AC_VERB_SET_COEF_INDEX, 0x0b}, + {0x20, AC_VERB_SET_PROC_COEF, 0x0838}, + /* enable unsolicited event */ + {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, + { } /* end */ +}; + +static void alc883_eee1601_speaker_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) + & AC_PINSENSE_PRESENCE; + bits = present ? 0 : PIN_OUT; + snd_hda_codec_write(codec, 0x1b, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, + bits); +} + +static void alc883_eee1601_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + switch (res >> 26) { + case ALC880_HP_EVENT: + alc883_eee1601_speaker_automute(codec); + break; + } +} + +static void alc883_eee1601_inithook(struct hda_codec *codec) +{ + alc883_eee1601_speaker_automute(codec); +} + #ifdef CONFIG_SND_HDA_POWER_SAVE #define alc883_loopbacks alc880_loopbacks #endif @@ -8017,6 +8271,7 @@ static const char *alc883_models[ALC883_MODEL_LAST] = { [ALC883_LENOVO_101E_2ch] = "lenovo-101e", [ALC883_LENOVO_NB0763] = "lenovo-nb0763", [ALC888_LENOVO_MS7195_DIG] = "lenovo-ms7195-dig", + [ALC888_LENOVO_SKY] = "lenovo-sky", [ALC883_HAIER_W66] = "haier-w66", [ALC888_3ST_HP] = "3stack-hp", [ALC888_6ST_DELL] = "6stack-dell", @@ -8040,10 +8295,13 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP), SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG), SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG), + SND_PCI_QUIRK(0x1043, 0x8317, "Asus M90V", ALC888_ASUS_M90V), + SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601), SND_PCI_QUIRK(0x105b, 0x0ce8, "Foxconn P35AX-S", ALC883_6ST_DIG), SND_PCI_QUIRK(0x105b, 0x6668, "Foxconn", ALC883_6ST_DIG), SND_PCI_QUIRK(0x1071, 0x8253, "Mitac 8252d", ALC883_MITAC), SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD), + SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL), SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch), SND_PCI_QUIRK(0x1458, 0xa002, "MSI", ALC883_6ST_DIG), SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG), @@ -8079,6 +8337,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763), SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763), SND_PCI_QUIRK(0x17aa, 0x3bfd, "Lenovo NB0763", ALC883_LENOVO_NB0763), + SND_PCI_QUIRK(0x17aa, 0x101d, "Lenovo Sky", ALC888_LENOVO_SKY), SND_PCI_QUIRK(0x17c0, 0x4071, "MEDION MD2", ALC883_MEDION_MD2), SND_PCI_QUIRK(0x17f2, 0x5000, "Albatron KI690-AM2", ALC883_6ST_DIG), SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66), @@ -8335,6 +8594,49 @@ static struct alc_config_preset alc883_presets[] = { .unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event, .init_hook = alc883_2ch_fujitsu_pi2515_automute, }, + [ALC888_LENOVO_SKY] = { + .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer }, + .init_verbs = { alc883_init_verbs, alc888_lenovo_sky_verbs}, + .num_dacs = ARRAY_SIZE(alc883_dac_nids), + .dac_nids = alc883_dac_nids, + .dig_out_nid = ALC883_DIGOUT_NID, + .num_adc_nids = ARRAY_SIZE(alc883_adc_nids), + .adc_nids = alc883_adc_nids, + .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), + .channel_mode = alc883_sixstack_modes, + .need_dac_fix = 1, + .input_mux = &alc883_lenovo_sky_capture_source, + .unsol_event = alc883_lenovo_sky_unsol_event, + .init_hook = alc888_lenovo_sky_front_automute, + }, + [ALC888_ASUS_M90V] = { + .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, + .init_verbs = { alc883_init_verbs, alc888_asus_m90v_verbs }, + .num_dacs = ARRAY_SIZE(alc883_dac_nids), + .dac_nids = alc883_dac_nids, + .dig_out_nid = ALC883_DIGOUT_NID, + .dig_in_nid = ALC883_DIGIN_NID, + .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_modes), + .channel_mode = alc883_3ST_6ch_modes, + .need_dac_fix = 1, + .input_mux = &alc883_fujitsu_pi2515_capture_source, + .unsol_event = alc883_mode2_unsol_event, + .init_hook = alc883_mode2_inithook, + }, + [ALC888_ASUS_EEE1601] = { + .mixers = { alc883_asus_eee1601_mixer }, + .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs }, + .num_dacs = ARRAY_SIZE(alc883_dac_nids), + .dac_nids = alc883_dac_nids, + .dig_out_nid = ALC883_DIGOUT_NID, + .dig_in_nid = ALC883_DIGIN_NID, + .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), + .channel_mode = alc883_3ST_2ch_modes, + .need_dac_fix = 1, + .input_mux = &alc883_asus_eee1601_capture_source, + .unsol_event = alc883_eee1601_unsol_event, + .init_hook = alc883_eee1601_inithook, + }, }; -- cgit v1.2.3 From f1d4e28b2dbd35191cc5097b716ec7fa49540b0b Mon Sep 17 00:00:00 2001 From: Kailang Yang Date: Tue, 26 Aug 2008 14:03:29 +0200 Subject: ALSA: hda - Add more ALC662/663 codec support - Add support for ECS (1019:9087) - Delete G71V record from alc662_cfg_tbl[] The PCI SubsystemID was the same with M70V - Add more ASUS notebook support Signed-off-by: Kailang Yang Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 599 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 591 insertions(+), 8 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index d748d19f163..a5047322174 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -174,6 +174,13 @@ enum { ALC663_ASUS_G71V, ALC663_ASUS_H13, ALC663_ASUS_G50V, + ALC662_ECS, + ALC663_ASUS_MODE1, + ALC662_ASUS_MODE2, + ALC663_ASUS_MODE3, + ALC663_ASUS_MODE4, + ALC663_ASUS_MODE5, + ALC663_ASUS_MODE6, ALC662_AUTO, ALC662_MODEL_LAST, }; @@ -14657,13 +14664,120 @@ static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = { { } /* end */ }; +static struct hda_bind_ctls alc663_asus_bind_master_vol = { + .ops = &snd_hda_bind_vol, + .values = { + HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), + HDA_COMPOSE_AMP_VAL(0x03, 3, 0, HDA_OUTPUT), + 0 + }, +}; + +static struct hda_bind_ctls alc663_asus_one_bind_switch = { + .ops = &snd_hda_bind_sw, + .values = { + HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), + HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), + 0 + }, +}; + static struct snd_kcontrol_new alc663_m51va_mixer[] = { + HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), + HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + { } /* end */ +}; + +static struct hda_bind_ctls alc663_asus_tree_bind_switch = { + .ops = &snd_hda_bind_sw, + .values = { + HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), + HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), + HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), + 0 + }, +}; + +static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = { + HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), + HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + + { } /* end */ +}; + +static struct hda_bind_ctls alc663_asus_four_bind_switch = { + .ops = &snd_hda_bind_sw, + .values = { + HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), + HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), + HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), + 0 + }, +}; + +static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = { + HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), + HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + { } /* end */ +}; + +static struct snd_kcontrol_new alc662_1bjd_mixer[] = { HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("F-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("F-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + { } /* end */ +}; + +static struct hda_bind_ctls alc663_asus_two_bind_master_vol = { + .ops = &snd_hda_bind_vol, + .values = { + HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), + HDA_COMPOSE_AMP_VAL(0x04, 3, 0, HDA_OUTPUT), + 0 + }, +}; + +static struct hda_bind_ctls alc663_asus_two_bind_switch = { + .ops = &snd_hda_bind_sw, + .values = { + HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), + HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT), + 0 + }, +}; + +static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = { + HDA_BIND_VOL("Master Playback Volume", + &alc663_asus_two_bind_master_vol), + HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch), + HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), - HDA_CODEC_MUTE("DMic Playback Switch", 0x23, 0x9, HDA_INPUT), + { } /* end */ +}; + +static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = { + HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), + HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch), + HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), { } /* end */ }; @@ -14848,14 +14962,81 @@ static struct hda_verb alc663_auto_init_verbs[] = { }; static struct hda_verb alc663_m51va_init_verbs[] = { + {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, + {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */ + {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, + {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, + {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, + {} +}; + +static struct hda_verb alc663_21jd_amic_init_verbs[] = { + {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, + {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, + {} +}; + +static struct hda_verb alc662_1bjd_amic_init_verbs[] = { + {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, + {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}, /* Headphone */ + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, + {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, + {} +}; - {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(9)}, +static struct hda_verb alc663_15jd_amic_init_verbs[] = { + {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, + {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, + {} +}; +static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = { + {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, + {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x21, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */ + {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, /* Headphone */ + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, {0x21, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, + {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, + {} +}; + +static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = { + {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, + {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, 0x01}, /* Headphone */ + {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, + {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, + {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, + {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, + {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, {} }; @@ -14884,6 +15065,14 @@ static struct hda_verb alc663_g50v_init_verbs[] = { {} }; +static struct hda_verb alc662_ecs_init_verbs[] = { + {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f}, + {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, + {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, + {} +}; + /* capture mixer elements */ static struct snd_kcontrol_new alc662_capture_mixer[] = { HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), @@ -14903,6 +15092,12 @@ static struct snd_kcontrol_new alc662_capture_mixer[] = { { } /* end */ }; +static struct snd_kcontrol_new alc662_auto_capture_mixer[] = { + HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), + { } /* end */ +}; + static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec) { unsigned int present; @@ -15011,11 +15206,108 @@ static void alc663_m51va_speaker_automute(struct hda_codec *codec) unsigned char bits; present = snd_hda_codec_read(codec, 0x21, 0, - AC_VERB_GET_PIN_SENSE, 0) - & AC_PINSENSE_PRESENCE; + AC_VERB_GET_PIN_SENSE, 0) + & AC_PINSENSE_PRESENCE; bits = present ? HDA_AMP_MUTE : 0; - snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, - HDA_AMP_MUTE, bits); + snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, + AMP_IN_MUTE(0), bits); + snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, + AMP_IN_MUTE(0), bits); +} + +static void alc663_21jd_two_speaker_automute(struct hda_codec *codec) +{ + unsigned int present; + unsigned char bits; + + present = snd_hda_codec_read(codec, 0x21, 0, + AC_VERB_GET_PIN_SENSE, 0) + & AC_PINSENSE_PRESENCE; + bits = present ? HDA_AMP_MUTE : 0; + snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, + AMP_IN_MUTE(0), bits); + snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, + AMP_IN_MUTE(0), bits); + snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0, + AMP_IN_MUTE(0), bits); + snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1, + AMP_IN_MUTE(0), bits); +} + +static void alc663_15jd_two_speaker_automute(struct hda_codec *codec) +{ + unsigned int present; + unsigned char bits; + + present = snd_hda_codec_read(codec, 0x15, 0, + AC_VERB_GET_PIN_SENSE, 0) + & AC_PINSENSE_PRESENCE; + bits = present ? HDA_AMP_MUTE : 0; + snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, + AMP_IN_MUTE(0), bits); + snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, + AMP_IN_MUTE(0), bits); + snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0, + AMP_IN_MUTE(0), bits); + snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1, + AMP_IN_MUTE(0), bits); +} + +static void alc662_f5z_speaker_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) + & AC_PINSENSE_PRESENCE; + bits = present ? 0 : PIN_OUT; + snd_hda_codec_write(codec, 0x14, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, bits); +} + +static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec) +{ + unsigned int present1, present2; + + present1 = snd_hda_codec_read(codec, 0x21, 0, + AC_VERB_GET_PIN_SENSE, 0) + & AC_PINSENSE_PRESENCE; + present2 = snd_hda_codec_read(codec, 0x15, 0, + AC_VERB_GET_PIN_SENSE, 0) + & AC_PINSENSE_PRESENCE; + + if (present1 || present2) { + snd_hda_codec_write_cache(codec, 0x14, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, 0); + } else { + snd_hda_codec_write_cache(codec, 0x14, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); + } +} + +static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec) +{ + unsigned int present1, present2; + + present1 = snd_hda_codec_read(codec, 0x1b, 0, + AC_VERB_GET_PIN_SENSE, 0) + & AC_PINSENSE_PRESENCE; + present2 = snd_hda_codec_read(codec, 0x15, 0, + AC_VERB_GET_PIN_SENSE, 0) + & AC_PINSENSE_PRESENCE; + + if (present1 || present2) { + snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, + AMP_IN_MUTE(0), AMP_IN_MUTE(0)); + snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, + AMP_IN_MUTE(0), AMP_IN_MUTE(0)); + } else { + snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, + AMP_IN_MUTE(0), 0); + snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, + AMP_IN_MUTE(0), 0); + } } static void alc663_m51va_mic_automute(struct hda_codec *codec) @@ -15054,6 +15346,121 @@ static void alc663_m51va_inithook(struct hda_codec *codec) alc663_m51va_mic_automute(codec); } +/* ***************** Mode1 ******************************/ +static void alc663_mode1_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + switch (res >> 26) { + case ALC880_HP_EVENT: + alc663_m51va_speaker_automute(codec); + break; + case ALC880_MIC_EVENT: + alc662_eeepc_mic_automute(codec); + break; + } +} + +static void alc663_mode1_inithook(struct hda_codec *codec) +{ + alc663_m51va_speaker_automute(codec); + alc662_eeepc_mic_automute(codec); +} +/* ***************** Mode2 ******************************/ +static void alc662_mode2_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + switch (res >> 26) { + case ALC880_HP_EVENT: + alc662_f5z_speaker_automute(codec); + break; + case ALC880_MIC_EVENT: + alc662_eeepc_mic_automute(codec); + break; + } +} + +static void alc662_mode2_inithook(struct hda_codec *codec) +{ + alc662_f5z_speaker_automute(codec); + alc662_eeepc_mic_automute(codec); +} +/* ***************** Mode3 ******************************/ +static void alc663_mode3_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + switch (res >> 26) { + case ALC880_HP_EVENT: + alc663_two_hp_m1_speaker_automute(codec); + break; + case ALC880_MIC_EVENT: + alc662_eeepc_mic_automute(codec); + break; + } +} + +static void alc663_mode3_inithook(struct hda_codec *codec) +{ + alc663_two_hp_m1_speaker_automute(codec); + alc662_eeepc_mic_automute(codec); +} +/* ***************** Mode4 ******************************/ +static void alc663_mode4_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + switch (res >> 26) { + case ALC880_HP_EVENT: + alc663_21jd_two_speaker_automute(codec); + break; + case ALC880_MIC_EVENT: + alc662_eeepc_mic_automute(codec); + break; + } +} + +static void alc663_mode4_inithook(struct hda_codec *codec) +{ + alc663_21jd_two_speaker_automute(codec); + alc662_eeepc_mic_automute(codec); +} +/* ***************** Mode5 ******************************/ +static void alc663_mode5_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + switch (res >> 26) { + case ALC880_HP_EVENT: + alc663_15jd_two_speaker_automute(codec); + break; + case ALC880_MIC_EVENT: + alc662_eeepc_mic_automute(codec); + break; + } +} + +static void alc663_mode5_inithook(struct hda_codec *codec) +{ + alc663_15jd_two_speaker_automute(codec); + alc662_eeepc_mic_automute(codec); +} +/* ***************** Mode6 ******************************/ +static void alc663_mode6_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + switch (res >> 26) { + case ALC880_HP_EVENT: + alc663_two_hp_m2_speaker_automute(codec); + break; + case ALC880_MIC_EVENT: + alc662_eeepc_mic_automute(codec); + break; + } +} + +static void alc663_mode6_inithook(struct hda_codec *codec) +{ + alc663_two_hp_m2_speaker_automute(codec); + alc662_eeepc_mic_automute(codec); +} + static void alc663_g71v_hp_automute(struct hda_codec *codec) { unsigned int present; @@ -15124,6 +15531,46 @@ static void alc663_g50v_inithook(struct hda_codec *codec) alc662_eeepc_mic_automute(codec); } +/* bind hp and internal speaker mute (with plug check) */ +static int alc662_ecs_master_sw_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + long *valp = ucontrol->value.integer.value; + int change; + + change = snd_hda_codec_amp_update(codec, 0x1b, 0, HDA_OUTPUT, 0, + HDA_AMP_MUTE, + valp[0] ? 0 : HDA_AMP_MUTE); + change |= snd_hda_codec_amp_update(codec, 0x1b, 1, HDA_OUTPUT, 0, + HDA_AMP_MUTE, + valp[1] ? 0 : HDA_AMP_MUTE); + if (change) + alc262_hippo1_automute(codec); + return change; +} + +static struct snd_kcontrol_new alc662_ecs_mixer[] = { + HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Master Playback Switch", + .info = snd_hda_mixer_amp_switch_info, + .get = snd_hda_mixer_amp_switch_get, + .put = alc662_ecs_master_sw_put, + .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), + }, + + HDA_CODEC_VOLUME("e-Mic/LineIn Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("e-Mic/LineIn Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("e-Mic/LineIn Playback Switch", 0x0b, 0x0, HDA_INPUT), + + HDA_CODEC_VOLUME("i-Mic Boost", 0x19, 0, HDA_INPUT), + HDA_CODEC_VOLUME("i-Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("i-Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), + { } /* end */ +}; + #ifdef CONFIG_SND_HDA_POWER_SAVE #define alc662_loopbacks alc880_loopbacks #endif @@ -15146,21 +15593,60 @@ static const char *alc662_models[ALC662_MODEL_LAST] = { [ALC662_LENOVO_101E] = "lenovo-101e", [ALC662_ASUS_EEEPC_P701] = "eeepc-p701", [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20", + [ALC662_ECS] = "ecs", [ALC663_ASUS_M51VA] = "m51va", [ALC663_ASUS_G71V] = "g71v", [ALC663_ASUS_H13] = "h13", [ALC663_ASUS_G50V] = "g50v", + [ALC663_ASUS_MODE1] = "asus-mode1", + [ALC662_ASUS_MODE2] = "asus-mode2", + [ALC663_ASUS_MODE3] = "asus-mode3", + [ALC663_ASUS_MODE4] = "asus-mode4", + [ALC663_ASUS_MODE5] = "asus-mode5", + [ALC663_ASUS_MODE6] = "asus-mode6", [ALC662_AUTO] = "auto", }; static struct snd_pci_quirk alc662_cfg_tbl[] = { - SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS G71V", ALC663_ASUS_G71V), SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M51VA", ALC663_ASUS_M51VA), SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS M51VA", ALC663_ASUS_G50V), SND_PCI_QUIRK(0x1043, 0x8290, "ASUS P5GC-MX", ALC662_3ST_6ch_DIG), SND_PCI_QUIRK(0x1043, 0x82a1, "ASUS Eeepc", ALC662_ASUS_EEEPC_P701), SND_PCI_QUIRK(0x1043, 0x82d1, "ASUS Eeepc EP20", ALC662_ASUS_EEEPC_EP20), + SND_PCI_QUIRK(0x1043, 0x1903, "ASUS F5GL", ALC663_ASUS_MODE1), + SND_PCI_QUIRK(0x1043, 0x1878, "ASUS M50Vr", ALC663_ASUS_MODE1), + SND_PCI_QUIRK(0x1043, 0x1000, "ASUS N50Vm", ALC663_ASUS_MODE1), + SND_PCI_QUIRK(0x1043, 0x19b3, "ASUS F7Z", ALC663_ASUS_MODE1), + SND_PCI_QUIRK(0x1043, 0x1953, "ASUS NB", ALC663_ASUS_MODE1), + SND_PCI_QUIRK(0x1043, 0x19a3, "ASUS NB", ALC663_ASUS_MODE1), + SND_PCI_QUIRK(0x1043, 0x11d3, "ASUS NB", ALC663_ASUS_MODE1), + SND_PCI_QUIRK(0x1043, 0x1203, "ASUS NB", ALC663_ASUS_MODE1), + SND_PCI_QUIRK(0x1043, 0x19e3, "ASUS NB", ALC663_ASUS_MODE1), + SND_PCI_QUIRK(0x1043, 0x19c3, "ASUS F5Z/F6x", ALC662_ASUS_MODE2), + SND_PCI_QUIRK(0x1043, 0x1339, "ASUS NB", ALC662_ASUS_MODE2), + SND_PCI_QUIRK(0x1043, 0x1913, "ASUS NB", ALC662_ASUS_MODE2), + SND_PCI_QUIRK(0x1043, 0x1843, "ASUS NB", ALC662_ASUS_MODE2), + SND_PCI_QUIRK(0x1043, 0x1813, "ASUS NB", ALC662_ASUS_MODE2), + SND_PCI_QUIRK(0x1043, 0x11f3, "ASUS NB", ALC662_ASUS_MODE2), + SND_PCI_QUIRK(0x1043, 0x1876, "ASUS NB", ALC662_ASUS_MODE2), + SND_PCI_QUIRK(0x1043, 0x1864, "ASUS NB", ALC662_ASUS_MODE2), + SND_PCI_QUIRK(0x1043, 0x1783, "ASUS NB", ALC662_ASUS_MODE2), + SND_PCI_QUIRK(0x1043, 0x1753, "ASUS NB", ALC662_ASUS_MODE2), + SND_PCI_QUIRK(0x1043, 0x16c3, "ASUS NB", ALC662_ASUS_MODE2), + SND_PCI_QUIRK(0x1043, 0x1933, "ASUS F80Q", ALC662_ASUS_MODE2), + SND_PCI_QUIRK(0x1043, 0x1893, "ASUS M50Vm", ALC663_ASUS_MODE3), + SND_PCI_QUIRK(0x1043, 0x11c3, "ASUS M70V", ALC663_ASUS_MODE3), + SND_PCI_QUIRK(0x1043, 0x1963, "ASUS X71C", ALC663_ASUS_MODE3), + SND_PCI_QUIRK(0x1043, 0x1894, "ASUS X55", ALC663_ASUS_MODE3), + SND_PCI_QUIRK(0x1043, 0x1092, "ASUS NB", ALC663_ASUS_MODE3), + SND_PCI_QUIRK(0x1043, 0x19f3, "ASUS NB", ALC663_ASUS_MODE4), + SND_PCI_QUIRK(0x1043, 0x1823, "ASUS NB", ALC663_ASUS_MODE5), + SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6), + SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6), + SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6), SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E), + SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS), + SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS), SND_PCI_QUIRK(0x1854, 0x2000, "ASUS H13-2000", ALC663_ASUS_H13), SND_PCI_QUIRK(0x1854, 0x2001, "ASUS H13-2001", ALC663_ASUS_H13), SND_PCI_QUIRK(0x1854, 0x2002, "ASUS H13-2002", ALC663_ASUS_H13), @@ -15251,6 +15737,18 @@ static struct alc_config_preset alc662_presets[] = { .unsol_event = alc662_eeepc_ep20_unsol_event, .init_hook = alc662_eeepc_ep20_inithook, }, + [ALC662_ECS] = { + .mixers = { alc662_ecs_mixer, alc662_capture_mixer }, + .init_verbs = { alc662_init_verbs, + alc662_ecs_init_verbs }, + .num_dacs = ARRAY_SIZE(alc662_dac_nids), + .dac_nids = alc662_dac_nids, + .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), + .channel_mode = alc662_3ST_2ch_modes, + .input_mux = &alc662_eeepc_capture_source, + .unsol_event = alc662_eeepc_unsol_event, + .init_hook = alc662_eeepc_inithook, + }, [ALC663_ASUS_M51VA] = { .mixers = { alc663_m51va_mixer, alc662_capture_mixer}, .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs }, @@ -15298,6 +15796,91 @@ static struct alc_config_preset alc662_presets[] = { .unsol_event = alc663_g50v_unsol_event, .init_hook = alc663_g50v_inithook, }, + [ALC663_ASUS_MODE1] = { + .mixers = { alc663_m51va_mixer, alc662_auto_capture_mixer }, + .init_verbs = { alc662_init_verbs, + alc663_21jd_amic_init_verbs }, + .num_dacs = ARRAY_SIZE(alc662_dac_nids), + .hp_nid = 0x03, + .dac_nids = alc662_dac_nids, + .dig_out_nid = ALC662_DIGOUT_NID, + .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), + .channel_mode = alc662_3ST_2ch_modes, + .input_mux = &alc662_eeepc_capture_source, + .unsol_event = alc663_mode1_unsol_event, + .init_hook = alc663_mode1_inithook, + }, + [ALC662_ASUS_MODE2] = { + .mixers = { alc662_1bjd_mixer, alc662_auto_capture_mixer }, + .init_verbs = { alc662_init_verbs, + alc662_1bjd_amic_init_verbs }, + .num_dacs = ARRAY_SIZE(alc662_dac_nids), + .dac_nids = alc662_dac_nids, + .dig_out_nid = ALC662_DIGOUT_NID, + .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), + .channel_mode = alc662_3ST_2ch_modes, + .input_mux = &alc662_eeepc_capture_source, + .unsol_event = alc662_mode2_unsol_event, + .init_hook = alc662_mode2_inithook, + }, + [ALC663_ASUS_MODE3] = { + .mixers = { alc663_two_hp_m1_mixer, alc662_auto_capture_mixer }, + .init_verbs = { alc662_init_verbs, + alc663_two_hp_amic_m1_init_verbs }, + .num_dacs = ARRAY_SIZE(alc662_dac_nids), + .hp_nid = 0x03, + .dac_nids = alc662_dac_nids, + .dig_out_nid = ALC662_DIGOUT_NID, + .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), + .channel_mode = alc662_3ST_2ch_modes, + .input_mux = &alc662_eeepc_capture_source, + .unsol_event = alc663_mode3_unsol_event, + .init_hook = alc663_mode3_inithook, + }, + [ALC663_ASUS_MODE4] = { + .mixers = { alc663_asus_21jd_clfe_mixer, + alc662_auto_capture_mixer}, + .init_verbs = { alc662_init_verbs, + alc663_21jd_amic_init_verbs}, + .num_dacs = ARRAY_SIZE(alc662_dac_nids), + .hp_nid = 0x03, + .dac_nids = alc662_dac_nids, + .dig_out_nid = ALC662_DIGOUT_NID, + .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), + .channel_mode = alc662_3ST_2ch_modes, + .input_mux = &alc662_eeepc_capture_source, + .unsol_event = alc663_mode4_unsol_event, + .init_hook = alc663_mode4_inithook, + }, + [ALC663_ASUS_MODE5] = { + .mixers = { alc663_asus_15jd_clfe_mixer, + alc662_auto_capture_mixer }, + .init_verbs = { alc662_init_verbs, + alc663_15jd_amic_init_verbs }, + .num_dacs = ARRAY_SIZE(alc662_dac_nids), + .hp_nid = 0x03, + .dac_nids = alc662_dac_nids, + .dig_out_nid = ALC662_DIGOUT_NID, + .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), + .channel_mode = alc662_3ST_2ch_modes, + .input_mux = &alc662_eeepc_capture_source, + .unsol_event = alc663_mode5_unsol_event, + .init_hook = alc663_mode5_inithook, + }, + [ALC663_ASUS_MODE6] = { + .mixers = { alc663_two_hp_m2_mixer, alc662_auto_capture_mixer }, + .init_verbs = { alc662_init_verbs, + alc663_two_hp_amic_m2_init_verbs }, + .num_dacs = ARRAY_SIZE(alc662_dac_nids), + .hp_nid = 0x03, + .dac_nids = alc662_dac_nids, + .dig_out_nid = ALC662_DIGOUT_NID, + .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), + .channel_mode = alc662_3ST_2ch_modes, + .input_mux = &alc662_eeepc_capture_source, + .unsol_event = alc663_mode6_unsol_event, + .init_hook = alc663_mode6_inithook, + }, }; -- cgit v1.2.3 From 0e153474f47aee906107a5c1da0ae83553e5ba6a Mon Sep 17 00:00:00 2001 From: Joseph Chan Date: Tue, 26 Aug 2008 14:38:03 +0200 Subject: ALSA: hda - Fix VIA recording problem Add a workaround for bad DMA-position reporting on VIA chipset. Signed-off-by: Joseph Chan [modified and cleaned up by tiwai] Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_intel.c | 91 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 88 insertions(+), 3 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 4f80248837e..52a3adfac7f 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -286,6 +286,11 @@ enum { #define INTEL_SCH_HDA_DEVC 0x78 #define INTEL_SCH_HDA_DEVC_NOSNOOP (0x1<<11) +/* Define IN stream 0 FIFO size offset in VIA controller */ +#define VIA_IN_STREAM0_FIFO_SIZE_OFFSET 0x90 +/* Define VIA HD Audio Device ID*/ +#define VIA_HDAC_DEVICE_ID 0x3288 + /* */ @@ -317,6 +322,12 @@ struct azx_dev { unsigned int running :1; unsigned int irq_pending :1; unsigned int irq_ignore :1; + /* + * For VIA: + * A flag to ensure DMA position is 0 + * when link position is not greater than FIFO size + */ + unsigned int insufficient :1; }; /* CORB/RIRB */ @@ -379,6 +390,7 @@ struct azx { unsigned int polling_mode :1; unsigned int msi :1; unsigned int irq_pending_warned :1; + unsigned int via_dmapos_patch :1; /* enable DMA-position fix for VIA */ /* for debugging */ unsigned int last_cmd; /* last issued command (to sync) */ @@ -818,6 +830,11 @@ static void azx_int_clear(struct azx *chip) /* start a stream */ static void azx_stream_start(struct azx *chip, struct azx_dev *azx_dev) { + /* + * Before stream start, initialize parameter + */ + azx_dev->insufficient = 1; + /* enable SIE */ azx_writeb(chip, INTCTL, azx_readb(chip, INTCTL) | (1 << azx_dev->index)); @@ -1148,7 +1165,8 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev) /* enable the position buffer */ if (chip->position_fix == POS_FIX_POSBUF || - chip->position_fix == POS_FIX_AUTO) { + chip->position_fix == POS_FIX_AUTO || + chip->via_dmapos_patch) { if (!(azx_readl(chip, DPLBASE) & ICH6_DPLBASE_ENABLE)) azx_writel(chip, DPLBASE, (u32)chip->posbuf.addr | ICH6_DPLBASE_ENABLE); @@ -1504,13 +1522,71 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) return 0; } +/* get the current DMA position with correction on VIA chips */ +static unsigned int azx_via_get_position(struct azx *chip, + struct azx_dev *azx_dev) +{ + unsigned int link_pos, mini_pos, bound_pos; + unsigned int mod_link_pos, mod_dma_pos, mod_mini_pos; + unsigned int fifo_size; + + link_pos = azx_sd_readl(azx_dev, SD_LPIB); + if (azx_dev->index >= 4) { + /* Playback, no problem using link position */ + return link_pos; + } + + /* Capture */ + /* For new chipset, + * use mod to get the DMA position just like old chipset + */ + mod_dma_pos = le32_to_cpu(*azx_dev->posbuf); + mod_dma_pos %= azx_dev->period_bytes; + + /* azx_dev->fifo_size can't get FIFO size of in stream. + * Get from base address + offset. + */ + fifo_size = readw(chip->remap_addr + VIA_IN_STREAM0_FIFO_SIZE_OFFSET); + + if (azx_dev->insufficient) { + /* Link position never gather than FIFO size */ + if (link_pos <= fifo_size) + return 0; + + azx_dev->insufficient = 0; + } + + if (link_pos <= fifo_size) + mini_pos = azx_dev->bufsize + link_pos - fifo_size; + else + mini_pos = link_pos - fifo_size; + + /* Find nearest previous boudary */ + mod_mini_pos = mini_pos % azx_dev->period_bytes; + mod_link_pos = link_pos % azx_dev->period_bytes; + if (mod_link_pos >= fifo_size) + bound_pos = link_pos - mod_link_pos; + else if (mod_dma_pos >= mod_mini_pos) + bound_pos = mini_pos - mod_mini_pos; + else { + bound_pos = mini_pos - mod_mini_pos + azx_dev->period_bytes; + if (bound_pos >= azx_dev->bufsize) + bound_pos = 0; + } + + /* Calculate real DMA position we want */ + return bound_pos + mod_dma_pos; +} + static unsigned int azx_get_position(struct azx *chip, struct azx_dev *azx_dev) { unsigned int pos; - if (chip->position_fix == POS_FIX_POSBUF || - chip->position_fix == POS_FIX_AUTO) { + if (chip->via_dmapos_patch) + pos = azx_via_get_position(chip, azx_dev); + else if (chip->position_fix == POS_FIX_POSBUF || + chip->position_fix == POS_FIX_AUTO) { /* use the position buffer */ pos = le32_to_cpu(*azx_dev->posbuf); } else { @@ -1946,6 +2022,15 @@ static int __devinit check_position_fix(struct azx *chip, int fix) { const struct snd_pci_quirk *q; + /* Check VIA HD Audio Controller exist */ + if (chip->pci->vendor == PCI_VENDOR_ID_VIA && + chip->pci->device == VIA_HDAC_DEVICE_ID) { + chip->via_dmapos_patch = 1; + /* Use link position directly, avoid any transfer problem. */ + return POS_FIX_LPIB; + } + chip->via_dmapos_patch = 0; + if (fix == POS_FIX_AUTO) { q = snd_pci_quirk_lookup(chip->pci, position_fix_list); if (q) { -- cgit v1.2.3 From 2922c9aff22ea65f33a891af894331f0f883d127 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 27 Aug 2008 18:12:42 +0200 Subject: ALSA: hda - Add descriptions of missing model values Added the descriptions of missing model values. Also, fixed the model strings of a few new models to a standard style. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index a5047322174..d1f5a766c3b 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -5239,6 +5239,7 @@ static const char *alc260_models[ALC260_MODEL_LAST] = { [ALC260_BASIC] = "basic", [ALC260_HP] = "hp", [ALC260_HP_3013] = "hp-3013", + [ALC260_HP_DC7600] = "hp-dc7600", [ALC260_FUJITSU_S702X] = "fujitsu", [ALC260_ACER] = "acer", [ALC260_WILL] = "will", @@ -10261,6 +10262,7 @@ static const char *alc262_models[ALC262_MODEL_LAST] = { [ALC262_BENQ_ED8] = "benq", [ALC262_BENQ_T31] = "benq-t31", [ALC262_SONY_ASSAMD] = "sony-assamd", + [ALC262_TOSHIBA_S06] = "toshiba-s06", [ALC262_ULTRA] = "ultra", [ALC262_LENOVO_3000] = "lenovo-3000", [ALC262_NEC] = "nec", @@ -12151,8 +12153,9 @@ static void alc269_auto_init(struct hda_codec *codec) */ static const char *alc269_models[ALC269_MODEL_LAST] = { [ALC269_BASIC] = "basic", - [ALC269_QUANTA_FL1] = "Quanta", - [ALC269_ASUS_EEEPC_P901] = "Asus_Epc_Dmic" + [ALC269_QUANTA_FL1] = "quanta", + [ALC269_ASUS_EEEPC_P703] = "eeepc-p703", + [ALC269_ASUS_EEEPC_P901] = "eeepc-p901" }; static struct snd_pci_quirk alc269_cfg_tbl[] = { -- cgit v1.2.3 From 9e285e1a58bcf957cde9c0c559a1b9b0f708bb2f Mon Sep 17 00:00:00 2001 From: "John L. Utz III" Date: Thu, 28 Aug 2008 16:04:40 +0200 Subject: ALSA: ac97 - vt1618 7.1 Audio Support 1. Implement 7.1 Output for vt1618 codec. 2. Fix typos in comments from my previous 1617a patch. Signed-off-by: John L. Utz III Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/ac97/ac97_codec.c | 2 +- sound/pci/ac97/ac97_patch.c | 198 +++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 197 insertions(+), 3 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/ac97/ac97_codec.c b/sound/pci/ac97/ac97_codec.c index d0023e99bdf..6704acbca8c 100644 --- a/sound/pci/ac97/ac97_codec.c +++ b/sound/pci/ac97/ac97_codec.c @@ -168,7 +168,7 @@ static const struct ac97_codec_id snd_ac97_codec_ids[] = { { 0x54584e20, 0xffffffff, "TLC320AD9xC", NULL, NULL }, { 0x56494161, 0xffffffff, "VIA1612A", NULL, NULL }, // modified ICE1232 with S/PDIF { 0x56494170, 0xffffffff, "VIA1617A", patch_vt1617a, NULL }, // modified VT1616 with S/PDIF -{ 0x56494182, 0xffffffff, "VIA1618", NULL, NULL }, +{ 0x56494182, 0xffffffff, "VIA1618", patch_vt1618, NULL }, { 0x57454301, 0xffffffff, "W83971D", NULL, NULL }, { 0x574d4c00, 0xffffffff, "WM9701,WM9701A", NULL, NULL }, { 0x574d4C03, 0xffffffff, "WM9703,WM9707,WM9708,WM9717", patch_wolfson03, NULL}, diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index bb028f8f9a2..d0cab1d3878 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c @@ -3465,7 +3465,7 @@ static int patch_vt1616(struct snd_ac97 * ac97) /* * unfortunately, the vt1617a stashes the twiddlers required for - * nooding the i/o jacks on 2 different regs. * thameans that we cant + * noodling the i/o jacks on 2 different regs. that means that we can't * use the easy way provided by AC97_ENUM_DOUBLE() we have to write * are own funcs. * @@ -3498,7 +3498,7 @@ static int snd_ac97_vt1617a_smart51_get(struct snd_kcontrol *kcontrol, pac97 = snd_kcontrol_chip(kcontrol); /* grab codec handle */ - /* grab our desirec bits, then mash them together in a manner + /* grab our desired 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; @@ -3576,6 +3576,200 @@ int patch_vt1617a(struct snd_ac97 * ac97) return err; } +/* VIA VT1618 8 CHANNEL AC97 CODEC + * + * VIA implements 'Smart 5.1' completely differently on the 1618 than + * it does on the 1617a. awesome! They seem to have sourced this + * particular revision of the technology from somebody else, it's + * called Universal Audio Jack and it shows up on some other folk's chips + * as well. + * + * ordering in this list reflects vt1618 docs for Reg 60h and + * the block diagram, DACs are as follows: + * + * OUT_O -> Front, + * OUT_1 -> Surround, + * OUT_2 -> C/LFE + * + * Unlike the 1617a, each OUT has a consistent set of mappings + * for all bitpatterns other than 00: + * + * 01 Unmixed Output + * 10 Line In + * 11 Mic In + * + * Special Case of 00: + * + * OUT_0 Mixed Output + * OUT_1 Reserved + * OUT_2 Reserved + * + * I have no idea what the hell Reserved does, but on an MSI + * CN700T, i have to set it to get 5.1 output - YMMV, bad + * shit may happen. + * + * If other chips use Universal Audio Jack, then this code might be applicable + * to them. + */ + +struct vt1618_uaj_item { + unsigned short mask; + unsigned short shift; + const char *items[4]; +}; + +/* This list reflects the vt1618 docs for Vendor Defined Register 0x60. */ + +static struct vt1618_uaj_item vt1618_uaj[3] = { + { + /* speaker jack */ + .mask = 0x03, + .shift = 0, + .items = { + "Speaker Out", "DAC Unmixed Out", "Line In", "Mic In" + } + }, + { + /* line jack */ + .mask = 0x0c, + .shift = 2, + .items = { + "Surround Out", "DAC Unmixed Out", "Line In", "Mic In" + } + }, + { + /* mic jack */ + .mask = 0x30, + .shift = 4, + .items = { + "Center LFE Out", "DAC Unmixed Out", "Line In", "Mic In" + }, + }, +}; + +static int snd_ac97_vt1618_UAJ_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + return ac97_enum_text_info(kcontrol, uinfo, + vt1618_uaj[kcontrol->private_value].items, + 4); +} + +/* All of the vt1618 Universal Audio Jack twiddlers are on + * Vendor Defined Register 0x60, page 0. The bits, and thus + * the mask, are the only thing that changes + */ +static int snd_ac97_vt1618_UAJ_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + unsigned short datpag, uaj; + struct snd_ac97 *pac97 = snd_kcontrol_chip(kcontrol); + + mutex_lock(&pac97->page_mutex); + + datpag = snd_ac97_read(pac97, AC97_INT_PAGING) & AC97_PAGE_MASK; + snd_ac97_update_bits(pac97, AC97_INT_PAGING, AC97_PAGE_MASK, 0); + + uaj = snd_ac97_read(pac97, 0x60) & + vt1618_uaj[kcontrol->private_value].mask; + + snd_ac97_update_bits(pac97, AC97_INT_PAGING, AC97_PAGE_MASK, datpag); + mutex_unlock(&pac97->page_mutex); + + ucontrol->value.enumerated.item[0] = uaj >> + vt1618_uaj[kcontrol->private_value].shift; + + return 0; +} + +static int snd_ac97_vt1618_UAJ_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + return ac97_update_bits_page(snd_kcontrol_chip(kcontrol), 0x60, + vt1618_uaj[kcontrol->private_value].mask, + ucontrol->value.enumerated.item[0]<< + vt1618_uaj[kcontrol->private_value].shift, + 0); +} + +/* config aux in jack - not found on 3 jack motherboards or soundcards */ + +static int snd_ac97_vt1618_aux_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + static const char *txt_aux[] = {"Aux In", "Back Surr Out"}; + + return ac97_enum_text_info(kcontrol, uinfo, txt_aux, 2); +} + +static int snd_ac97_vt1618_aux_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.enumerated.item[0] = + (snd_ac97_read(snd_kcontrol_chip(kcontrol), 0x5c) & 0x0008)>>3; + return 0; +} + +static int snd_ac97_vt1618_aux_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + /* toggle surround rear dac power */ + + snd_ac97_update_bits(snd_kcontrol_chip(kcontrol), 0x5c, 0x0008, + ucontrol->value.enumerated.item[0] << 3); + + /* toggle aux in surround rear out jack */ + + return snd_ac97_update_bits(snd_kcontrol_chip(kcontrol), 0x76, 0x0008, + ucontrol->value.enumerated.item[0] << 3); +} + +static const struct snd_kcontrol_new snd_ac97_controls_vt1618[] = { + AC97_SINGLE("Exchange Center/LFE", 0x5a, 8, 1, 0), + AC97_SINGLE("DC Offset", 0x5a, 10, 1, 0), + AC97_SINGLE("Soft Mute", 0x5c, 0, 1, 1), + AC97_SINGLE("Headphone Amp", 0x5c, 5, 1, 1), + AC97_DOUBLE("Back Surr Volume", 0x5e, 8, 0, 31, 1), + AC97_SINGLE("Back Surr Switch", 0x5e, 15, 1, 1), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Speaker Jack Mode", + .info = snd_ac97_vt1618_UAJ_info, + .get = snd_ac97_vt1618_UAJ_get, + .put = snd_ac97_vt1618_UAJ_put, + .private_value = 0 + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Line Jack Mode", + .info = snd_ac97_vt1618_UAJ_info, + .get = snd_ac97_vt1618_UAJ_get, + .put = snd_ac97_vt1618_UAJ_put, + .private_value = 1 + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Mic Jack Mode", + .info = snd_ac97_vt1618_UAJ_info, + .get = snd_ac97_vt1618_UAJ_get, + .put = snd_ac97_vt1618_UAJ_put, + .private_value = 2 + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Aux Jack Mode", + .info = snd_ac97_vt1618_aux_info, + .get = snd_ac97_vt1618_aux_get, + .put = snd_ac97_vt1618_aux_put, + } +}; + +int patch_vt1618(struct snd_ac97 *ac97) +{ + return patch_build_controls(ac97, snd_ac97_controls_vt1618, + ARRAY_SIZE(snd_ac97_controls_vt1618)); +} + /* */ static void it2646_update_jacks(struct snd_ac97 *ac97) -- cgit v1.2.3 From 9f99a6386eb1ad1197a401495669315de2f19039 Mon Sep 17 00:00:00 2001 From: Hiroshi Miura Date: Thu, 28 Aug 2008 16:09:06 +0200 Subject: ALSA: hda - Add support of Toshiba RX1 Added the support of Toshiba RX1 laptop with ALC262 codec chip. Related ALSA bug#3386: https://bugtrack.alsa-project.org/alsa-bug/view.php?id=3386 Signed-off-by: Hiroshi Miura Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 53 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 52 insertions(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index d1f5a766c3b..4cfea551cab 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -103,6 +103,7 @@ enum { ALC262_LENOVO_3000, ALC262_NEC, ALC262_TOSHIBA_S06, + ALC262_TOSHIBA_RX1, ALC262_AUTO, ALC262_MODEL_LAST /* last tag */ }; @@ -9712,6 +9713,25 @@ static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = { { } /* end */ }; +static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = { + HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Master Playback Switch", + .info = snd_hda_mixer_amp_switch_info, + .get = snd_hda_mixer_amp_switch_get, + .put = alc262_sony_master_sw_put, + .private_value = HDA_COMPOSE_AMP_VAL(0x15, 3, 0, HDA_OUTPUT), + }, + HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), + HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), + HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x01, HDA_INPUT), + HDA_CODEC_VOLUME("Front Mic Boost", 0x19, 0, HDA_INPUT), + { } /* end */ +}; + /* additional init verbs for Benq laptops */ static struct hda_verb alc262_EAPD_verbs[] = { {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, @@ -10176,6 +10196,24 @@ static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = { { } }; +static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = { + + {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */ + {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, + {0x14, AC_VERB_SET_CONNECT_SEL, 0x01}, + + {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* MIC jack */ + {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Front MIC */ + {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) }, + {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) }, + + {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP jack */ + {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, + {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, + {} +}; + + #ifdef CONFIG_SND_HDA_POWER_SAVE #define alc262_loopbacks alc880_loopbacks #endif @@ -10263,6 +10301,7 @@ static const char *alc262_models[ALC262_MODEL_LAST] = { [ALC262_BENQ_T31] = "benq-t31", [ALC262_SONY_ASSAMD] = "sony-assamd", [ALC262_TOSHIBA_S06] = "toshiba-s06", + [ALC262_TOSHIBA_RX1] = "toshiba-rx1", [ALC262_ULTRA] = "ultra", [ALC262_LENOVO_3000] = "lenovo-3000", [ALC262_NEC] = "nec", @@ -10300,7 +10339,7 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = { SND_PCI_QUIRK(0x104d, 0x900e, "Sony ASSAMD", ALC262_SONY_ASSAMD), SND_PCI_QUIRK(0x104d, 0x9015, "Sony 0x9015", ALC262_SONY_ASSAMD), SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba dynabook SS RX1", - ALC262_SONY_ASSAMD), + ALC262_TOSHIBA_RX1), SND_PCI_QUIRK(0x1179, 0x0268, "Toshiba S06", ALC262_TOSHIBA_S06), SND_PCI_QUIRK(0x10cf, 0x1397, "Fujitsu", ALC262_FUJITSU), SND_PCI_QUIRK(0x10cf, 0x142d, "Fujitsu Lifebook E8410", ALC262_FUJITSU), @@ -10508,6 +10547,18 @@ static struct alc_config_preset alc262_presets[] = { .unsol_event = alc262_toshiba_s06_unsol_event, .init_hook = alc262_toshiba_s06_init_hook, }, + [ALC262_TOSHIBA_RX1] = { + .mixers = { alc262_toshiba_rx1_mixer }, + .init_verbs = { alc262_init_verbs, alc262_toshiba_rx1_unsol_verbs }, + .num_dacs = ARRAY_SIZE(alc262_dac_nids), + .dac_nids = alc262_dac_nids, + .hp_nid = 0x03, + .num_channel_mode = ARRAY_SIZE(alc262_modes), + .channel_mode = alc262_modes, + .input_mux = &alc262_capture_source, + .unsol_event = alc262_hippo_unsol_event, + .init_hook = alc262_hippo_automute, + }, }; static int patch_alc262(struct hda_codec *codec) -- cgit v1.2.3 From 2b3b5485aa96d18b0025dfb2bc92c824dc81a780 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Fri, 29 Aug 2008 11:29:39 +0200 Subject: ALSA: intel8x0: implement ac97_clock whitelist The AC97 clock detection is not accurate in some cases. This patch adds an initial whitelist for audio devices gathered from RedHat's bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=441087 As a side effect, white-listing might speedup kernel booting (AC97 clock measuring code is not activated). Signed-off-by: Jaroslav Kysela --- sound/pci/intel8x0.c | 44 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 3 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index 73ad5899536..c8f51489684 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c @@ -83,7 +83,7 @@ MODULE_PARM_DESC(index, "Index value for Intel i8x0 soundcard."); module_param(id, charp, 0444); MODULE_PARM_DESC(id, "ID string for Intel i8x0 soundcard."); module_param(ac97_clock, int, 0444); -MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (0 = auto-detect)."); +MODULE_PARM_DESC(ac97_clock, "AC'97 codec clock (0 = whitelist + auto-detect, 1 = force autodetect)."); module_param(ac97_quirk, charp, 0444); MODULE_PARM_DESC(ac97_quirk, "AC'97 workaround for strange hardware."); module_param(buggy_semaphore, bool, 0444); @@ -2692,6 +2692,38 @@ static void __devinit intel8x0_measure_ac97_clock(struct intel8x0 *chip) snd_ac97_update_power(chip->ac97[0], AC97_PCM_FRONT_DAC_RATE, 0); } +struct intel8x0_clock_list { + unsigned short subvendor; + unsigned short subdevice; + unsigned int rate; +}; + +static struct intel8x0_clock_list intel8x0_clock_list[] __devinitdata = { + { 0x0e11, 0x008a, 41000 }, /* Analog Devices AD1885 */ + { 0x1028, 0x00be, 44100 }, /* Analog Devices AD1885 */ + { 0x1028, 0x0177, 48000 }, /* Analog Devices AD1980 */ + { 0x1043, 0x80f3, 48000 }, /* Analog Devices AD1985 */ + { 0x0000, 0x0000, 00000 } /* terminator */ +}; + +static int __devinit intel8x0_in_clock_list(struct intel8x0 *chip) +{ + struct pci_dev *pci = chip->pci; + struct intel8x0_clock_list *wl; + + for (wl = intel8x0_clock_list; wl->subvendor; wl++) { + if (wl->subvendor == pci->subsystem_vendor && + wl->subdevice == pci->subsystem_device) { + printk(KERN_INFO "intel8x0: white list rate for %04x:%04x is %i\n", + pci->subsystem_vendor, + pci->subsystem_device, wl->rate); + chip->ac97_bus->clock = wl->rate; + return 1; + } + } + return 0; +} + #ifdef CONFIG_PROC_FS static void snd_intel8x0_proc_read(struct snd_info_entry * entry, struct snd_info_buffer *buffer) @@ -3087,8 +3119,14 @@ static int __devinit snd_intel8x0_probe(struct pci_dev *pci, "%s with %s at irq %i", card->shortname, snd_ac97_get_short_name(chip->ac97[0]), chip->irq); - if (! ac97_clock) - intel8x0_measure_ac97_clock(chip); + if (ac97_clock == 0 || ac97_clock == 1) { + if (ac97_clock == 0) { + if (intel8x0_in_clock_list(chip) == 0) + intel8x0_measure_ac97_clock(chip); + } else { + intel8x0_measure_ac97_clock(chip); + } + } if ((err = snd_card_register(card)) < 0) { snd_card_free(card); -- cgit v1.2.3 From c1805dddc9fbd65e831963f671bfb79384e8b3b8 Mon Sep 17 00:00:00 2001 From: Maximilian Rehkopf Date: Fri, 29 Aug 2008 14:11:10 +0200 Subject: ALSA: ice1724: enable MIDI on Terratec Aureon 7.1 Universe This enables MIDI on Terratec Aureon 7.1 Universe cards specifically. Apparently the other envy24ht-based Aureon cards do not have MIDI ports, hence I added a Universe specific eeprom array. The newer cards (Aureon 7.1 PCI / 5.1 PCI/Fun) have MIDI but use a CMI DSP so this driver does not concern them at all. Signed-off-by: Maximilian Rehkopf Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/ice1712/aureon.c | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c index 868ae291b96..a137fc12e34 100644 --- a/sound/pci/ice1712/aureon.c +++ b/sound/pci/ice1712/aureon.c @@ -2158,6 +2158,24 @@ static unsigned char aureon71_eeprom[] __devinitdata = { }; #define prodigy71_eeprom aureon71_eeprom +static unsigned char aureon71_universe_eeprom[] __devinitdata = { + [ICE_EEP2_SYSCONF] = 0x2b, /* clock 512, mpu401, spdif-in/ADC, + * 4DACs + */ + [ICE_EEP2_ACLINK] = 0x80, /* I2S */ + [ICE_EEP2_I2S] = 0xfc, /* 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_DIR2] = 0x5f, + [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, +}; + static unsigned char prodigy71lt_eeprom[] __devinitdata = { [ICE_EEP2_SYSCONF] = 0x4b, /* clock 384, spdif-in/ADC, 4DACs */ [ICE_EEP2_ACLINK] = 0x80, /* I2S */ @@ -2203,8 +2221,8 @@ struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = { .model = "universe", .chip_init = aureon_init, .build_controls = aureon_add_controls, - .eeprom_size = sizeof(aureon71_eeprom), - .eeprom_data = aureon71_eeprom, + .eeprom_size = sizeof(aureon71_universe_eeprom), + .eeprom_data = aureon71_universe_eeprom, .driver = "Aureon71Univ", /* keep in 15 letters */ }, { -- cgit v1.2.3 From eee75a6ca77a729c26258649abe992c15a6c76f6 Mon Sep 17 00:00:00 2001 From: Vedran Miletic Date: Fri, 29 Aug 2008 18:31:13 +0200 Subject: ALSA: ice1724: Enable MIDI on TerraTec PHASE 22 and PHASE 28 Even though MIDI was fixed on ice1724 chips a while ago, it wasn't yet enabled for some cards as it didn't get enough testing. This was tested with MIDI keyboard on PHASE 22 and with looping back output to input and it works stable, so it's safe to enable it. Besides this, there are some more minor fixes, not exactly user visible: * added info about PHASE 28 (collected, as I don't have a card) * added info about TS22PCI and new revisions of PHASE 22 * disable 192k on PHASE 22 as AK4524 I2S doesn't support it * enable SPDIF reciever on PHASE 22 Signed-off-by: Vedran Miletic Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/ice1712/phase.c | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/ice1712/phase.c b/sound/pci/ice1712/phase.c index f5acdeef443..6a614729280 100644 --- a/sound/pci/ice1712/phase.c +++ b/sound/pci/ice1712/phase.c @@ -22,15 +22,24 @@ */ /* PHASE 22 overview: - * Audio controller: VIA Envy24HT-S (slightly trimmed down version of Envy24HT) + * Audio controller: VIA Envy24HT-S (slightly trimmed down Envy24HT, 4in/4out) * Analog chip: AK4524 (partially via Philip's 74HCT125) - * Digital receiver: CS8414-CS (not supported in this release) + * Digital receiver: CS8414-CS (supported in this release) + * PHASE 22 revision 2.0 and Terrasoniq/Musonik TS22PCI have CS8416 + * (support status unknown, please test and report) * * Envy connects to AK4524 * - CS directly from GPIO 10 * - CCLK via 74HCT125's gate #4 from GPIO 4 * - CDTI via 74HCT125's gate #2 from GPIO 5 - * CDTI may be completely blocked by 74HCT125's gate #1 controlled by GPIO 3 + * CDTI may be completely blocked by 74HCT125's gate #1 + * controlled by GPIO 3 + */ + +/* PHASE 28 overview: + * Audio controller: VIA Envy24HT (full untrimmed version, 8in/8out) + * Analog chip: WM8770 (8 channel 192k DAC, 2 channel 96k ADC) + * Digital receiver: CS8414-CS (supported in this release) */ #include @@ -161,9 +170,10 @@ static int __devinit phase22_add_controls(struct snd_ice1712 *ice) } static unsigned char phase22_eeprom[] __devinitdata = { - [ICE_EEP2_SYSCONF] = 0x00, /* 1xADC, 1xDACs */ + [ICE_EEP2_SYSCONF] = 0x28, /* clock 512, mpu 401, + spdif-in/1xADC, 1xDACs */ [ICE_EEP2_ACLINK] = 0x80, /* I2S */ - [ICE_EEP2_I2S] = 0xf8, /* vol, 96k, 24bit */ + [ICE_EEP2_I2S] = 0xf0, /* vol, 96k, 24bit */ [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */ [ICE_EEP2_GPIO_DIR] = 0xff, [ICE_EEP2_GPIO_DIR1] = 0xff, @@ -177,7 +187,8 @@ static unsigned char phase22_eeprom[] __devinitdata = { }; static unsigned char phase28_eeprom[] __devinitdata = { - [ICE_EEP2_SYSCONF] = 0x0b, /* clock 512, spdif-in/ADC, 4DACs */ + [ICE_EEP2_SYSCONF] = 0x2b, /* clock 512, mpu401, + spdif-in/1xADC, 4xDACs */ [ICE_EEP2_ACLINK] = 0x80, /* I2S */ [ICE_EEP2_I2S] = 0xfc, /* vol, 96k, 24bit, 192k */ [ICE_EEP2_SPDIF] = 0xc3, /* out-en, out-int, spdif-in */ -- cgit v1.2.3 From a6b936b956a2b70b6f49741403b5f8b90a8acc7f Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Fri, 29 Aug 2008 16:17:25 +0200 Subject: ALSA: ice1724 - limit channels for multi-channel playback Limit the available channels for multi-channel playback device to the real number of channels. Until now, always up to 8 channels are created, which are simply useless without the real outputs. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/ice1712/ice1724.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c index 60119d220a6..7bb99df44fd 100644 --- a/sound/pci/ice1712/ice1724.c +++ b/sound/pci/ice1712/ice1724.c @@ -942,7 +942,7 @@ static int snd_vt1724_playback_pro_open(struct snd_pcm_substream *substream) { struct snd_pcm_runtime *runtime = substream->runtime; struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - int chs; + int chs, num_indeps; runtime->private_data = (void *)&vt1724_playback_pro_reg; ice->playback_pro_substream = substream; @@ -952,7 +952,8 @@ static int snd_vt1724_playback_pro_open(struct snd_pcm_substream *substream) set_rate_constraints(ice, substream); mutex_lock(&ice->open_mutex); /* calculate the currently available channels */ - for (chs = 0; chs < 3; chs++) { + num_indeps = ice->num_total_dacs / 2 - 1; + for (chs = 0; chs < num_indeps; chs++) { if (ice->pcm_reserved[chs]) break; } -- cgit v1.2.3 From f4446ea046cf719a6d79449bb9175d50a64d963b Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 1 Sep 2008 08:21:49 +0200 Subject: ALSA: atiixp - Add PCI ID for SB600 (1002:4382) Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/atiixp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/atiixp.c b/sound/pci/atiixp.c index ce1eb12768f..085a52b8c80 100644 --- a/sound/pci/atiixp.c +++ b/sound/pci/atiixp.c @@ -37,7 +37,7 @@ MODULE_AUTHOR("Takashi Iwai "); MODULE_DESCRIPTION("ATI IXP AC97 controller"); MODULE_LICENSE("GPL"); -MODULE_SUPPORTED_DEVICE("{{ATI,IXP150/200/250/300/400}}"); +MODULE_SUPPORTED_DEVICE("{{ATI,IXP150/200/250/300/400/600}}"); static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */ static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ @@ -290,6 +290,7 @@ static struct pci_device_id snd_atiixp_ids[] = { { 0x1002, 0x4341, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB200 */ { 0x1002, 0x4361, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB300 */ { 0x1002, 0x4370, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB400 */ + { 0x1002, 0x4382, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, /* SB600 */ { 0, } }; -- cgit v1.2.3 From b03671a826ba9873724164c6c96e82d0f9f5988d Mon Sep 17 00:00:00 2001 From: Harvey Harrison Date: Fri, 29 Aug 2008 13:32:00 -0700 Subject: ALSA: ac97_patch make functions static Only used in ac97_codec by including ac97_patch.c directly, effectively static Found by sparse: sound/pci/ac97/ac97_patch.c:3551:5: warning: symbol 'patch_vt1617a' was not declared. Should it be static? sound/pci/ac97/ac97_patch.c:3767:5: warning: symbol 'patch_vt1618' was not declared. Should it be static? Signed-off-by: Harvey Harrison Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/ac97/ac97_patch.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c index d0cab1d3878..6ce3cbe98a6 100644 --- a/sound/pci/ac97/ac97_patch.c +++ b/sound/pci/ac97/ac97_patch.c @@ -3548,7 +3548,7 @@ static const struct snd_kcontrol_new snd_ac97_controls_vt1617a[] = { }, }; -int patch_vt1617a(struct snd_ac97 * ac97) +static int patch_vt1617a(struct snd_ac97 * ac97) { int err = 0; int val; @@ -3764,7 +3764,7 @@ static const struct snd_kcontrol_new snd_ac97_controls_vt1618[] = { } }; -int patch_vt1618(struct snd_ac97 *ac97) +static int patch_vt1618(struct snd_ac97 *ac97) { return patch_build_controls(ac97, snd_ac97_controls_vt1618, ARRAY_SIZE(snd_ac97_controls_vt1618)); -- cgit v1.2.3 From 2346d0cde544179a8d235375f1bfbca5c141a31b Mon Sep 17 00:00:00 2001 From: Travis Place Date: Mon, 1 Sep 2008 08:24:00 +0200 Subject: ALSA: hda - Add model for Toshiba L305 laptop Added Subsystem IDs (0x1179, 0xff64) for the Toshiba Satellite L305 laptop, so it automatically uses the ALC268_TOSHIBA quirk. Signed-off-by: Travis Place Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 4cfea551cab..5c80a27bfc8 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -11447,6 +11447,7 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = { SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST), SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA), SND_PCI_QUIRK(0x1179, 0xff50, "TOSHIBA A305", ALC268_TOSHIBA), + SND_PCI_QUIRK(0x1179, 0xff64, "TOSHIBA L305", ALC268_TOSHIBA), SND_PCI_QUIRK(0x14c0, 0x0025, "COMPAL IFL90/JFL-92", ALC268_TOSHIBA), SND_PCI_QUIRK(0x152d, 0x0763, "Diverse (CPR2000)", ALC268_ACER), SND_PCI_QUIRK(0x152d, 0x0771, "Quanta IL1", ALC267_QUANTA_IL1), -- cgit v1.2.3 From d695e4ea860fc1cbe1e4b101af4e0450219f2db9 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Mon, 1 Sep 2008 14:25:08 +0200 Subject: ALSA: intel8x0 - use snd_pci_quirk for clock list Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/intel8x0.c | 40 +++++++++++++++------------------------- 1 file changed, 15 insertions(+), 25 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index c8f51489684..f7b4d0c5d49 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c @@ -2692,36 +2692,26 @@ static void __devinit intel8x0_measure_ac97_clock(struct intel8x0 *chip) snd_ac97_update_power(chip->ac97[0], AC97_PCM_FRONT_DAC_RATE, 0); } -struct intel8x0_clock_list { - unsigned short subvendor; - unsigned short subdevice; - unsigned int rate; -}; - -static struct intel8x0_clock_list intel8x0_clock_list[] __devinitdata = { - { 0x0e11, 0x008a, 41000 }, /* Analog Devices AD1885 */ - { 0x1028, 0x00be, 44100 }, /* Analog Devices AD1885 */ - { 0x1028, 0x0177, 48000 }, /* Analog Devices AD1980 */ - { 0x1043, 0x80f3, 48000 }, /* Analog Devices AD1985 */ - { 0x0000, 0x0000, 00000 } /* terminator */ +static struct snd_pci_quirk intel8x0_clock_list[] __devinitdata = { + SND_PCI_QUIRK(0x0e11, 0x008a, "AD1885", 41000), + SND_PCI_QUIRK(0x1028, 0x00be, "AD1885", 44100), + SND_PCI_QUIRK(0x1028, 0x0177, "AD1980", 48000), + SND_PCI_QUIRK(0x1043, 0x80f3, "AD1985", 48000), + { } /* terminator */ }; static int __devinit intel8x0_in_clock_list(struct intel8x0 *chip) { struct pci_dev *pci = chip->pci; - struct intel8x0_clock_list *wl; - - for (wl = intel8x0_clock_list; wl->subvendor; wl++) { - if (wl->subvendor == pci->subsystem_vendor && - wl->subdevice == pci->subsystem_device) { - printk(KERN_INFO "intel8x0: white list rate for %04x:%04x is %i\n", - pci->subsystem_vendor, - pci->subsystem_device, wl->rate); - chip->ac97_bus->clock = wl->rate; - return 1; - } - } - return 0; + const struct snd_pci_quirk *wl; + + wl = snd_pci_quirk_lookup(pci, intel8x0_clock_list); + if (!wl) + return 0; + printk(KERN_INFO "intel8x0: white list rate for %04x:%04x is %i\n", + pci->subsystem_vendor, pci->subsystem_device, wl->value); + chip->ac97_bus->clock = wl->value; + return 1; } #ifdef CONFIG_PROC_FS -- cgit v1.2.3 From 2f5983f2aaffbc92addc4ec378989a1c200cf3dd Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 3 Sep 2008 16:00:44 +0200 Subject: ALSA: hda - allow probing of 4 codecs Allow probing of 4 codecs on known good situations. On some known bad situations, it should be avoided. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_intel.c | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 52a3adfac7f..60cc44abf58 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -222,9 +222,9 @@ enum { SDI0, SDI1, SDI2, SDI3, SDO0, SDO1, SDO2, SDO3 }; #define RIRB_INT_OVERRUN 0x04 #define RIRB_INT_MASK 0x05 -/* STATESTS int mask: SD2,SD1,SD0 */ -#define AZX_MAX_CODECS 3 -#define STATESTS_INT_MASK 0x07 +/* STATESTS int mask: S3,SD2,SD1,SD0 */ +#define AZX_MAX_CODECS 4 +#define STATESTS_INT_MASK 0x0f /* SD_CTL bits */ #define SD_CTL_STREAM_RESET 0x01 /* stream reset bit */ @@ -410,6 +410,7 @@ enum { AZX_DRIVER_ULI, AZX_DRIVER_NVIDIA, AZX_DRIVER_TERA, + AZX_NUM_DRIVERS, /* keep this as last entry */ }; static char *driver_short_names[] __devinitdata = { @@ -1184,23 +1185,26 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev) * Codec initialization */ -static unsigned int azx_max_codecs[] __devinitdata = { - [AZX_DRIVER_ICH] = 4, /* Some ICH9 boards use SD3 */ - [AZX_DRIVER_SCH] = 3, - [AZX_DRIVER_ATI] = 4, - [AZX_DRIVER_ATIHDMI] = 4, - [AZX_DRIVER_VIA] = 3, /* FIXME: correct? */ - [AZX_DRIVER_SIS] = 3, /* FIXME: correct? */ - [AZX_DRIVER_ULI] = 3, /* FIXME: correct? */ - [AZX_DRIVER_NVIDIA] = 3, /* FIXME: correct? */ +/* number of codec slots for each chipset: 0 = default slots (i.e. 4) */ +static unsigned int azx_max_codecs[AZX_NUM_DRIVERS] __devinitdata = { [AZX_DRIVER_TERA] = 1, }; +/* number of slots to probe as default + * this can be different from azx_max_codecs[] -- e.g. some boards + * report wrongly the non-existing 4th slot availability + */ +static unsigned int azx_default_codecs[AZX_NUM_DRIVERS] __devinitdata = { + [AZX_DRIVER_ICH] = 3, + [AZX_DRIVER_ATI] = 3, +}; + static int __devinit azx_codec_create(struct azx *chip, const char *model, unsigned int codec_probe_mask) { struct hda_bus_template bus_temp; int c, codecs, audio_codecs, err; + int def_slots, max_slots; memset(&bus_temp, 0, sizeof(bus_temp)); bus_temp.private_data = chip; @@ -1217,7 +1221,13 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model, return err; codecs = audio_codecs = 0; - for (c = 0; c < AZX_MAX_CODECS; c++) { + max_slots = azx_max_codecs[chip->driver_type]; + if (!max_slots) + max_slots = AZX_MAX_CODECS; + def_slots = azx_default_codecs[chip->driver_type]; + if (!def_slots) + def_slots = max_slots; + for (c = 0; c < def_slots; c++) { if ((chip->codec_mask & (1 << c)) & codec_probe_mask) { struct hda_codec *codec; err = snd_hda_codec_new(chip->bus, c, &codec); @@ -1230,7 +1240,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model, } if (!audio_codecs) { /* probe additional slots if no codec is found */ - for (; c < azx_max_codecs[chip->driver_type]; c++) { + for (; c < max_slots; c++) { if ((chip->codec_mask & (1 << c)) & codec_probe_mask) { err = snd_hda_codec_new(chip->bus, c, NULL); if (err < 0) -- cgit v1.2.3 From 1ce211a9dbf2a40b16132789735a127696bb6699 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Sun, 7 Sep 2008 01:19:00 +0400 Subject: ALSA: ice1712/aureon.c: fix coding style before: total: 304 errors, 137 warnings, 2259 lines checked after: total: 0 errors, 121 warnings, 2284 lines checked Compile tested, size is different because of include was changed, but without that change md5sum is different because of cmp cx,dx/cmp dx,cx swap and __LINE__ was changed in printk function. Signed-off-by: Alexander Beregalov Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/ice1712/aureon.c | 677 +++++++++++++++++++++++---------------------- 1 file changed, 351 insertions(+), 326 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/ice1712/aureon.c b/sound/pci/ice1712/aureon.c index a137fc12e34..110d16e5273 100644 --- a/sound/pci/ice1712/aureon.c +++ b/sound/pci/ice1712/aureon.c @@ -44,10 +44,9 @@ * not working: prety much everything else, at least i could verify that * we have no digital output, no capture, pretty bad clicks and poops * on mixer switch and other coll stuff. - * - */ + */ -#include +#include #include #include #include @@ -131,7 +130,7 @@ static void aureon_pca9554_write(struct snd_ice1712 *ice, unsigned char reg, snd_ice1712_gpio_write(ice, tmp); udelay(50); - /* + /* * send i2c stop condition and start condition * to obtain sane state */ @@ -152,10 +151,16 @@ static void aureon_pca9554_write(struct snd_ice1712 *ice, unsigned char reg, * skipping ack cycles inbetween */ for (j = 0; j < 3; j++) { - switch(j) { - case 0: val = dev; break; - case 1: val = reg; break; - case 2: val = data; break; + switch (j) { + case 0: + val = dev; + break; + case 1: + val = reg; + break; + case 2: + val = data; + break; } for (i = 7; i >= 0; i--) { tmp &= ~AUREON_SPI_CLK; @@ -171,7 +176,7 @@ static void aureon_pca9554_write(struct snd_ice1712 *ice, unsigned char reg, snd_ice1712_gpio_write(ice, tmp); udelay(40); } - tmp &= ~AUREON_SPI_CLK; + tmp &= ~AUREON_SPI_CLK; snd_ice1712_gpio_write(ice, tmp); udelay(40); tmp |= AUREON_SPI_CLK; @@ -203,7 +208,7 @@ static int aureon_universe_inmux_info(struct snd_kcontrol *kcontrol, uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->count = 1; uinfo->value.enumerated.items = 3; - if(uinfo->value.enumerated.item >= uinfo->value.enumerated.items) + 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; @@ -231,12 +236,12 @@ static int aureon_universe_inmux_put(struct snd_kcontrol *kcontrol, return -EINVAL; snd_ice1712_save_gpio_status(ice); oval = spec->pca9554_out; - if ((change = (oval != nval))) { + change = (oval != nval); + if (change) { aureon_pca9554_write(ice, PCA9554_OUT, nval); spec->pca9554_out = nval; } snd_ice1712_restore_gpio_status(ice); - return change; } @@ -256,7 +261,7 @@ static void aureon_ac97_write(struct snd_ice1712 *ice, unsigned short reg, udelay(10); tmp &= ~AUREON_AC97_ADDR; snd_ice1712_gpio_write(ice, tmp); - udelay(10); + udelay(10); /* Send low-order byte to XILINX chip */ tmp &= ~AUREON_AC97_DATA_MASK; @@ -269,7 +274,7 @@ static void aureon_ac97_write(struct snd_ice1712 *ice, unsigned short reg, tmp &= ~AUREON_AC97_DATA_LOW; snd_ice1712_gpio_write(ice, tmp); udelay(10); - + /* Send high-order byte to XILINX chip */ tmp &= ~AUREON_AC97_DATA_MASK; tmp |= (val >> 8) & AUREON_AC97_DATA_MASK; @@ -282,7 +287,7 @@ static void aureon_ac97_write(struct snd_ice1712 *ice, unsigned short reg, tmp &= ~AUREON_AC97_DATA_HIGH; snd_ice1712_gpio_write(ice, tmp); udelay(10); - + /* Instruct XILINX chip to parse the data to the STAC9744 chip */ tmp |= AUREON_AC97_COMMIT; snd_ice1712_gpio_write(ice, tmp); @@ -290,7 +295,7 @@ static void aureon_ac97_write(struct snd_ice1712 *ice, unsigned short reg, tmp &= ~AUREON_AC97_COMMIT; snd_ice1712_gpio_write(ice, tmp); udelay(10); - + /* Store the data in out private buffer */ spec->stac9744[(reg & 0x7F) >> 1] = val; } @@ -304,7 +309,7 @@ static unsigned short aureon_ac97_read(struct snd_ice1712 *ice, unsigned short r /* * Initialize STAC9744 chip */ -static int aureon_ac97_init (struct snd_ice1712 *ice) +static int aureon_ac97_init(struct snd_ice1712 *ice) { struct aureon_spec *spec = ice->spec; int i; @@ -335,20 +340,21 @@ static int aureon_ac97_init (struct snd_ice1712 *ice) tmp = (snd_ice1712_gpio_read(ice) | AUREON_AC97_RESET) & ~AUREON_AC97_DATA_MASK; snd_ice1712_gpio_write(ice, tmp); udelay(3); - + tmp &= ~AUREON_AC97_RESET; snd_ice1712_gpio_write(ice, tmp); udelay(3); - + tmp |= AUREON_AC97_RESET; snd_ice1712_gpio_write(ice, tmp); udelay(3); - + memset(&spec->stac9744, 0, sizeof(spec->stac9744)); - for (i=0; ac97_defaults[i] != (unsigned short)-1; i+=2) + for (i = 0; ac97_defaults[i] != (unsigned short)-1; i += 2) spec->stac9744[(ac97_defaults[i]) >> 1] = ac97_defaults[i+1]; - - aureon_ac97_write(ice, AC97_MASTER, 0x0000); // Unmute AC'97 master volume permanently - muting is done by WM8770 + + /* Unmute AC'97 master volume permanently - muting is done by WM8770 */ + aureon_ac97_write(ice, AC97_MASTER, 0x0000); return 0; } @@ -388,7 +394,7 @@ static int aureon_ac97_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ele struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); unsigned short ovol, nvol; int change; - + snd_ice1712_save_gpio_status(ice); ovol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F); @@ -396,13 +402,14 @@ static int aureon_ac97_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ele if (kcontrol->private_value & AUREON_AC97_STEREO) nvol |= ((0x1F - ucontrol->value.integer.value[1]) << 8) & 0x1F00; nvol |= ovol & ~0x1F1F; - - if ((change = (ovol != nvol))) + + change = (ovol != nvol); + if (change) aureon_ac97_write(ice, kcontrol->private_value & 0x7F, nvol); snd_ice1712_restore_gpio_status(ice); - return change; + return change; } /* @@ -416,7 +423,8 @@ static int aureon_ac97_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_el mutex_lock(&ice->gpio_mutex); - ucontrol->value.integer.value[0] = aureon_ac97_read(ice, kcontrol->private_value & 0x7F) & 0x8000 ? 0 : 1; + ucontrol->value.integer.value[0] = aureon_ac97_read(ice, + kcontrol->private_value & 0x7F) & 0x8000 ? 0 : 1; mutex_unlock(&ice->gpio_mutex); return 0; @@ -429,13 +437,14 @@ static int aureon_ac97_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_el int change; snd_ice1712_save_gpio_status(ice); - + ovol = aureon_ac97_read(ice, kcontrol->private_value & 0x7F); - nvol = (ucontrol->value.integer.value[0] ? 0x0000 : 0x8000) | (ovol & ~ 0x8000); - - if ((change = (ovol != nvol))) + nvol = (ucontrol->value.integer.value[0] ? 0x0000 : 0x8000) | (ovol & ~0x8000); + + change = (ovol != nvol); + if (change) aureon_ac97_write(ice, kcontrol->private_value & 0x7F, nvol); - + snd_ice1712_restore_gpio_status(ice); return change; @@ -465,13 +474,14 @@ static int aureon_ac97_micboost_put(struct snd_kcontrol *kcontrol, struct snd_ct int change; snd_ice1712_save_gpio_status(ice); - + ovol = aureon_ac97_read(ice, AC97_MIC); nvol = (ucontrol->value.integer.value[0] ? 0x0000 : 0x0020) | (ovol & ~0x0020); - - if ((change = (ovol != nvol))) + + change = (ovol != nvol); + if (change) aureon_ac97_write(ice, AC97_MIC, nvol); - + snd_ice1712_restore_gpio_status(ice); return change; @@ -493,16 +503,15 @@ static void aureon_spi_write(struct snd_ice1712 *ice, unsigned int cs, unsigned snd_ice1712_gpio_set_mask(ice, ~(PRODIGY_SPI_MOSI|PRODIGY_SPI_CLK|PRODIGY_WM_CS)); mosi = PRODIGY_SPI_MOSI; clk = PRODIGY_SPI_CLK; - } - else { + } else { snd_ice1712_gpio_set_mask(ice, ~(AUREON_WM_RW|AUREON_SPI_MOSI|AUREON_SPI_CLK| AUREON_WM_CS|AUREON_CS8415_CS)); mosi = AUREON_SPI_MOSI; clk = AUREON_SPI_CLK; - + tmp |= AUREON_WM_RW; } - + tmp &= ~cs; snd_ice1712_gpio_write(ice, tmp); udelay(1); @@ -534,7 +543,9 @@ static void aureon_spi_write(struct snd_ice1712 *ice, unsigned int cs, unsigned /* * Read data in SPI mode */ -static void aureon_spi_read(struct snd_ice1712 *ice, unsigned int cs, unsigned int data, int bits, unsigned char *buffer, int size) { +static void aureon_spi_read(struct snd_ice1712 *ice, unsigned int cs, + unsigned int data, int bits, unsigned char *buffer, int size) +{ int i, j; unsigned int tmp; @@ -544,7 +555,7 @@ static void aureon_spi_read(struct snd_ice1712 *ice, unsigned int cs, unsigned i snd_ice1712_gpio_write(ice, tmp); udelay(1); - for (i=bits-1; i>=0; i--) { + for (i = bits-1; i >= 0; i--) { if (data & (1 << i)) tmp |= AUREON_SPI_MOSI; else @@ -561,9 +572,9 @@ static void aureon_spi_read(struct snd_ice1712 *ice, unsigned int cs, unsigned i udelay(1); } - for (j=0; j=0; i--) { + for (i = 7; i >= 0; i--) { tmp = snd_ice1712_gpio_read(ice); outdata <<= 1; outdata |= (tmp & AUREON_SPI_MISO) ? 1 : 0; @@ -584,19 +595,24 @@ static void aureon_spi_read(struct snd_ice1712 *ice, unsigned int cs, unsigned i snd_ice1712_gpio_write(ice, tmp); } -static unsigned char aureon_cs8415_get(struct snd_ice1712 *ice, int reg) { +static unsigned char aureon_cs8415_get(struct snd_ice1712 *ice, int reg) +{ unsigned char val; aureon_spi_write(ice, AUREON_CS8415_CS, 0x2000 | reg, 16); aureon_spi_read(ice, AUREON_CS8415_CS, 0x21, 8, &val, 1); return val; } -static void aureon_cs8415_read(struct snd_ice1712 *ice, int reg, unsigned char *buffer, int size) { +static void aureon_cs8415_read(struct snd_ice1712 *ice, int reg, + unsigned char *buffer, int size) +{ aureon_spi_write(ice, AUREON_CS8415_CS, 0x2000 | reg, 16); aureon_spi_read(ice, AUREON_CS8415_CS, 0x21, 8, buffer, size); } -static void aureon_cs8415_put(struct snd_ice1712 *ice, int reg, unsigned char val) { +static void aureon_cs8415_put(struct snd_ice1712 *ice, int reg, + unsigned char val) +{ aureon_spi_write(ice, AUREON_CS8415_CS, 0x200000 | (reg << 8) | val, 24); } @@ -654,18 +670,20 @@ static int aureon_ac97_mmute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e return 0; } -static int aureon_ac97_mmute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { +static int aureon_ac97_mmute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); unsigned short ovol, nvol; int change; - + snd_ice1712_save_gpio_status(ice); - + ovol = wm_get(ice, WM_OUT_MUX1); nvol = (ovol & ~0x02) | (ucontrol->value.integer.value[0] ? 0x02 : 0x00); - if ((change = (ovol != nvol))) + change = (ovol != nvol); + if (change) wm_put(ice, WM_OUT_MUX1, nvol); - + snd_ice1712_restore_gpio_status(ice); return change; @@ -702,12 +720,12 @@ static const unsigned char wm_vol[256] = { static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned short vol, unsigned short master) { unsigned char nvol; - + if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE)) nvol = 0; else nvol = 127 - wm_vol[(((vol & ~WM_VOL_MUTE) * (master & ~WM_VOL_MUTE)) / 127) & WM_VOL_MAX]; - + wm_put(ice, index, nvol); wm_put_nocache(ice, index, 0x180 | nvol); } @@ -736,7 +754,8 @@ static int wm_pcm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_va snd_ice1712_save_gpio_status(ice); oval = wm_get(ice, WM_MUTE); nval = (oval & ~0x10) | (ucontrol->value.integer.value[0] ? 0 : 0x10); - if ((change = (nval != oval))) + change = (oval != nval); + if (change) wm_put(ice, WM_MUTE, nval); snd_ice1712_restore_gpio_status(ice); @@ -760,7 +779,7 @@ static int wm_master_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); struct aureon_spec *spec = ice->spec; int i; - for (i=0; i<2; i++) + for (i = 0; i < 2; i++) ucontrol->value.integer.value[i] = spec->master[i] & ~WM_VOL_MUTE; return 0; @@ -849,7 +868,8 @@ static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value * /* * WM8770 mute control */ -static int wm_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { +static int wm_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +{ uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; uinfo->count = kcontrol->private_value >> 8; uinfo->value.integer.min = 0; @@ -862,7 +882,7 @@ static int wm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); struct aureon_spec *spec = ice->spec; int voices, ofs, i; - + voices = kcontrol->private_value >> 8; ofs = kcontrol->private_value & 0xFF; @@ -907,7 +927,7 @@ static int wm_master_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); struct aureon_spec *spec = ice->spec; - + ucontrol->value.integer.value[0] = (spec->master[0] & WM_VOL_MUTE) ? 0 : 1; ucontrol->value.integer.value[1] = @@ -1083,21 +1103,21 @@ static int wm_adc_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val static int wm_adc_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { static const char * const texts[] = { - "CD", //AIN1 - "Aux", //AIN2 - "Line", //AIN3 - "Mic", //AIN4 - "AC97" //AIN5 + "CD", /* AIN1 */ + "Aux", /* AIN2 */ + "Line", /* AIN3 */ + "Mic", /* AIN4 */ + "AC97" /* AIN5 */ }; static const char * const universe_texts[] = { - "Aux1", //AIN1 - "CD", //AIN2 - "Phono", //AIN3 - "Line", //AIN4 - "Aux2", //AIN5 - "Mic", //AIN6 - "Aux3", //AIN7 - "AC97" //AIN8 + "Aux1", /* AIN1 */ + "CD", /* AIN2 */ + "Phono", /* AIN3 */ + "Line", /* AIN4 */ + "Aux2", /* AIN5 */ + "Mic", /* AIN6 */ + "Aux3", /* AIN7 */ + "AC97" /* AIN8 */ }; struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); @@ -1108,8 +1128,7 @@ static int wm_adc_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_in if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; strcpy(uinfo->value.enumerated.name, universe_texts[uinfo->value.enumerated.item]); - } - else { + } else { uinfo->value.enumerated.items = 5; if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; @@ -1156,8 +1175,8 @@ static int aureon_cs8415_mux_info(struct snd_kcontrol *kcontrol, struct snd_ctl_ { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); static const char * const aureon_texts[] = { - "CD", //RXP0 - "Optical" //RXP1 + "CD", /* RXP0 */ + "Optical" /* RXP1 */ }; static const char * const prodigy_texts[] = { "CD", @@ -1180,10 +1199,10 @@ static int aureon_cs8415_mux_get(struct snd_kcontrol *kcontrol, struct snd_ctl_e struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); struct aureon_spec *spec = ice->spec; - //snd_ice1712_save_gpio_status(ice); - //val = aureon_cs8415_get(ice, CS8415_CTRL2); + /* snd_ice1712_save_gpio_status(ice); */ + /* val = aureon_cs8415_get(ice, CS8415_CTRL2); */ ucontrol->value.enumerated.item[0] = spec->cs8415_mux; - //snd_ice1712_restore_gpio_status(ice); + /* snd_ice1712_restore_gpio_status(ice); */ return 0; } @@ -1206,7 +1225,7 @@ static int aureon_cs8415_mux_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e return change; } -static int aureon_cs8415_rate_info (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +static int aureon_cs8415_rate_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; uinfo->count = 1; @@ -1215,7 +1234,7 @@ static int aureon_cs8415_rate_info (struct snd_kcontrol *kcontrol, struct snd_ct return 0; } -static int aureon_cs8415_rate_get (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int aureon_cs8415_rate_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); unsigned char ratio; @@ -1229,7 +1248,7 @@ static int aureon_cs8415_rate_get (struct snd_kcontrol *kcontrol, struct snd_ctl */ #define aureon_cs8415_mute_info snd_ctl_boolean_mono_info -static int aureon_cs8415_mute_get (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int aureon_cs8415_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); snd_ice1712_save_gpio_status(ice); @@ -1238,7 +1257,7 @@ static int aureon_cs8415_mute_get (struct snd_kcontrol *kcontrol, struct snd_ctl return 0; } -static int aureon_cs8415_mute_put (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int aureon_cs8415_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); unsigned char oval, nval; @@ -1249,7 +1268,8 @@ static int aureon_cs8415_mute_put (struct snd_kcontrol *kcontrol, struct snd_ctl nval = oval & ~0x20; else nval = oval | 0x20; - if ((change = (oval != nval))) + change = (oval != nval); + if (change) aureon_cs8415_put(ice, CS8415_CTRL1, nval); snd_ice1712_restore_gpio_status(ice); return change; @@ -1258,15 +1278,17 @@ static int aureon_cs8415_mute_put (struct snd_kcontrol *kcontrol, struct snd_ctl /* * CS8415A Q-Sub info */ -static int aureon_cs8415_qsub_info (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { +static int aureon_cs8415_qsub_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +{ uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; uinfo->count = 10; return 0; } -static int aureon_cs8415_qsub_get (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { +static int aureon_cs8415_qsub_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - + snd_ice1712_save_gpio_status(ice); aureon_cs8415_read(ice, CS8415_QSUB, ucontrol->value.bytes.data, 10); snd_ice1712_restore_gpio_status(ice); @@ -1274,18 +1296,21 @@ static int aureon_cs8415_qsub_get (struct snd_kcontrol *kcontrol, struct snd_ctl return 0; } -static int aureon_cs8415_spdif_info (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { +static int aureon_cs8415_spdif_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 aureon_cs8415_mask_get (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { +static int aureon_cs8415_mask_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ memset(ucontrol->value.iec958.status, 0xFF, 24); return 0; } -static int aureon_cs8415_spdif_get (struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { +static int aureon_cs8415_spdif_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +{ struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); snd_ice1712_save_gpio_status(ice); @@ -1311,9 +1336,9 @@ static int aureon_set_headphone_amp(struct snd_ice1712 *ice, int enable) else if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT && ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) - tmp &= ~ AUREON_HP_SEL; + tmp &= ~AUREON_HP_SEL; else - tmp &= ~ PRODIGY_HP_SEL; + tmp &= ~PRODIGY_HP_SEL; if (tmp != tmp2) { snd_ice1712_gpio_write(ice, tmp); return 1; @@ -1325,7 +1350,7 @@ static int aureon_get_headphone_amp(struct snd_ice1712 *ice) { unsigned int tmp = snd_ice1712_gpio_read(ice); - return ( tmp & AUREON_HP_SEL )!= 0; + return (tmp & AUREON_HP_SEL) != 0; } #define aureon_hpamp_info snd_ctl_boolean_mono_info @@ -1343,7 +1368,7 @@ static int aureon_hpamp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - return aureon_set_headphone_amp(ice,ucontrol->value.integer.value[0]); + return aureon_set_headphone_amp(ice, ucontrol->value.integer.value[0]); } /* @@ -1390,7 +1415,7 @@ static int aureon_oversampling_info(struct snd_kcontrol *k, struct snd_ctl_elem_ uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); - return 0; + return 0; } static int aureon_oversampling_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -1434,7 +1459,7 @@ static struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), + SNDRV_CTL_ELEM_ACCESS_TLV_READ), .name = "Master Playback Volume", .info = wm_master_vol_info, .get = wm_master_vol_get, @@ -1452,7 +1477,7 @@ static struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), + SNDRV_CTL_ELEM_ACCESS_TLV_READ), .name = "Front Playback Volume", .info = wm_vol_info, .get = wm_vol_get, @@ -1471,7 +1496,7 @@ static struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), + SNDRV_CTL_ELEM_ACCESS_TLV_READ), .name = "Rear Playback Volume", .info = wm_vol_info, .get = wm_vol_get, @@ -1490,7 +1515,7 @@ static struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), + SNDRV_CTL_ELEM_ACCESS_TLV_READ), .name = "Center Playback Volume", .info = wm_vol_info, .get = wm_vol_get, @@ -1509,7 +1534,7 @@ static struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), + SNDRV_CTL_ELEM_ACCESS_TLV_READ), .name = "LFE Playback Volume", .info = wm_vol_info, .get = wm_vol_get, @@ -1528,7 +1553,7 @@ static struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), + SNDRV_CTL_ELEM_ACCESS_TLV_READ), .name = "Side Playback Volume", .info = wm_vol_info, .get = wm_vol_get, @@ -1539,23 +1564,23 @@ static struct snd_kcontrol_new aureon_dac_controls[] __devinitdata = { }; static struct snd_kcontrol_new wm_controls[] __devinitdata = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "PCM Playback Switch", .info = wm_pcm_mute_info, .get = wm_pcm_mute_get, .put = wm_pcm_mute_put - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), + SNDRV_CTL_ELEM_ACCESS_TLV_READ), .name = "PCM Playback Volume", .info = wm_pcm_vol_info, .get = wm_pcm_vol_get, .put = wm_pcm_vol_put, .tlv = { .p = db_scale_wm_pcm } - }, + }, { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Capture Switch", @@ -1566,7 +1591,7 @@ static struct snd_kcontrol_new wm_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), + SNDRV_CTL_ELEM_ACCESS_TLV_READ), .name = "Capture Volume", .info = wm_adc_vol_info, .get = wm_adc_vol_get, @@ -1605,232 +1630,232 @@ static struct snd_kcontrol_new wm_controls[] __devinitdata = { }; static struct snd_kcontrol_new ac97_controls[] __devinitdata = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "AC97 Playback Switch", .info = aureon_ac97_mmute_info, .get = aureon_ac97_mmute_get, .put = aureon_ac97_mmute_put, .private_value = AC97_MASTER - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "AC97 Playback Volume", - .info = aureon_ac97_vol_info, - .get = aureon_ac97_vol_get, - .put = aureon_ac97_vol_put, - .private_value = AC97_MASTER|AUREON_AC97_STEREO, + SNDRV_CTL_ELEM_ACCESS_TLV_READ), + .name = "AC97 Playback Volume", + .info = aureon_ac97_vol_info, + .get = aureon_ac97_vol_get, + .put = aureon_ac97_vol_put, + .private_value = AC97_MASTER|AUREON_AC97_STEREO, .tlv = { .p = db_scale_ac97_master } - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "CD Playback Switch", - .info = aureon_ac97_mute_info, - .get = aureon_ac97_mute_get, - .put = aureon_ac97_mute_put, - .private_value = AC97_CD - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "CD Playback Switch", + .info = aureon_ac97_mute_info, + .get = aureon_ac97_mute_get, + .put = aureon_ac97_mute_put, + .private_value = AC97_CD + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "CD Playback Volume", - .info = aureon_ac97_vol_info, - .get = aureon_ac97_vol_get, - .put = aureon_ac97_vol_put, - .private_value = AC97_CD|AUREON_AC97_STEREO, + SNDRV_CTL_ELEM_ACCESS_TLV_READ), + .name = "CD Playback Volume", + .info = aureon_ac97_vol_info, + .get = aureon_ac97_vol_get, + .put = aureon_ac97_vol_put, + .private_value = AC97_CD|AUREON_AC97_STEREO, .tlv = { .p = db_scale_ac97_gain } - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Aux Playback Switch", - .info = aureon_ac97_mute_info, - .get = aureon_ac97_mute_get, - .put = aureon_ac97_mute_put, - .private_value = AC97_AUX, - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Aux Playback Switch", + .info = aureon_ac97_mute_info, + .get = aureon_ac97_mute_get, + .put = aureon_ac97_mute_put, + .private_value = AC97_AUX, + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "Aux Playback Volume", - .info = aureon_ac97_vol_info, - .get = aureon_ac97_vol_get, - .put = aureon_ac97_vol_put, - .private_value = AC97_AUX|AUREON_AC97_STEREO, + SNDRV_CTL_ELEM_ACCESS_TLV_READ), + .name = "Aux Playback Volume", + .info = aureon_ac97_vol_info, + .get = aureon_ac97_vol_get, + .put = aureon_ac97_vol_put, + .private_value = AC97_AUX|AUREON_AC97_STEREO, .tlv = { .p = db_scale_ac97_gain } - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Line Playback Switch", - .info = aureon_ac97_mute_info, - .get = aureon_ac97_mute_get, - .put = aureon_ac97_mute_put, - .private_value = AC97_LINE - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Line Playback Switch", + .info = aureon_ac97_mute_info, + .get = aureon_ac97_mute_get, + .put = aureon_ac97_mute_put, + .private_value = AC97_LINE + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "Line Playback Volume", - .info = aureon_ac97_vol_info, - .get = aureon_ac97_vol_get, - .put = aureon_ac97_vol_put, - .private_value = AC97_LINE|AUREON_AC97_STEREO, + SNDRV_CTL_ELEM_ACCESS_TLV_READ), + .name = "Line Playback Volume", + .info = aureon_ac97_vol_info, + .get = aureon_ac97_vol_get, + .put = aureon_ac97_vol_put, + .private_value = AC97_LINE|AUREON_AC97_STEREO, .tlv = { .p = db_scale_ac97_gain } - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Mic Playback Switch", - .info = aureon_ac97_mute_info, - .get = aureon_ac97_mute_get, - .put = aureon_ac97_mute_put, - .private_value = AC97_MIC - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Mic Playback Switch", + .info = aureon_ac97_mute_info, + .get = aureon_ac97_mute_get, + .put = aureon_ac97_mute_put, + .private_value = AC97_MIC + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "Mic Playback Volume", - .info = aureon_ac97_vol_info, - .get = aureon_ac97_vol_get, - .put = aureon_ac97_vol_put, - .private_value = AC97_MIC, + SNDRV_CTL_ELEM_ACCESS_TLV_READ), + .name = "Mic Playback Volume", + .info = aureon_ac97_vol_info, + .get = aureon_ac97_vol_get, + .put = aureon_ac97_vol_put, + .private_value = AC97_MIC, .tlv = { .p = db_scale_ac97_gain } - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Mic Boost (+20dB)", - .info = aureon_ac97_micboost_info, - .get = aureon_ac97_micboost_get, - .put = aureon_ac97_micboost_put - } + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Mic Boost (+20dB)", + .info = aureon_ac97_micboost_info, + .get = aureon_ac97_micboost_get, + .put = aureon_ac97_micboost_put + } }; static struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = { - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "AC97 Playback Switch", .info = aureon_ac97_mmute_info, .get = aureon_ac97_mmute_get, .put = aureon_ac97_mmute_put, .private_value = AC97_MASTER - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "AC97 Playback Volume", - .info = aureon_ac97_vol_info, - .get = aureon_ac97_vol_get, - .put = aureon_ac97_vol_put, - .private_value = AC97_MASTER|AUREON_AC97_STEREO, + SNDRV_CTL_ELEM_ACCESS_TLV_READ), + .name = "AC97 Playback Volume", + .info = aureon_ac97_vol_info, + .get = aureon_ac97_vol_get, + .put = aureon_ac97_vol_put, + .private_value = AC97_MASTER|AUREON_AC97_STEREO, .tlv = { .p = db_scale_ac97_master } - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "CD Playback Switch", - .info = aureon_ac97_mute_info, - .get = aureon_ac97_mute_get, - .put = aureon_ac97_mute_put, - .private_value = AC97_AUX - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "CD Playback Switch", + .info = aureon_ac97_mute_info, + .get = aureon_ac97_mute_get, + .put = aureon_ac97_mute_put, + .private_value = AC97_AUX + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "CD Playback Volume", - .info = aureon_ac97_vol_info, - .get = aureon_ac97_vol_get, - .put = aureon_ac97_vol_put, - .private_value = AC97_AUX|AUREON_AC97_STEREO, + SNDRV_CTL_ELEM_ACCESS_TLV_READ), + .name = "CD Playback Volume", + .info = aureon_ac97_vol_info, + .get = aureon_ac97_vol_get, + .put = aureon_ac97_vol_put, + .private_value = AC97_AUX|AUREON_AC97_STEREO, .tlv = { .p = db_scale_ac97_gain } - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Phono Playback Switch", - .info = aureon_ac97_mute_info, - .get = aureon_ac97_mute_get, - .put = aureon_ac97_mute_put, - .private_value = AC97_CD - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Phono Playback Switch", + .info = aureon_ac97_mute_info, + .get = aureon_ac97_mute_get, + .put = aureon_ac97_mute_put, + .private_value = AC97_CD + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "Phono Playback Volume", - .info = aureon_ac97_vol_info, - .get = aureon_ac97_vol_get, - .put = aureon_ac97_vol_put, - .private_value = AC97_CD|AUREON_AC97_STEREO, + SNDRV_CTL_ELEM_ACCESS_TLV_READ), + .name = "Phono Playback Volume", + .info = aureon_ac97_vol_info, + .get = aureon_ac97_vol_get, + .put = aureon_ac97_vol_put, + .private_value = AC97_CD|AUREON_AC97_STEREO, .tlv = { .p = db_scale_ac97_gain } - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Line Playback Switch", - .info = aureon_ac97_mute_info, - .get = aureon_ac97_mute_get, - .put = aureon_ac97_mute_put, - .private_value = AC97_LINE - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Line Playback Switch", + .info = aureon_ac97_mute_info, + .get = aureon_ac97_mute_get, + .put = aureon_ac97_mute_put, + .private_value = AC97_LINE + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "Line Playback Volume", - .info = aureon_ac97_vol_info, - .get = aureon_ac97_vol_get, - .put = aureon_ac97_vol_put, - .private_value = AC97_LINE|AUREON_AC97_STEREO, + SNDRV_CTL_ELEM_ACCESS_TLV_READ), + .name = "Line Playback Volume", + .info = aureon_ac97_vol_info, + .get = aureon_ac97_vol_get, + .put = aureon_ac97_vol_put, + .private_value = AC97_LINE|AUREON_AC97_STEREO, .tlv = { .p = db_scale_ac97_gain } - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Mic Playback Switch", - .info = aureon_ac97_mute_info, - .get = aureon_ac97_mute_get, - .put = aureon_ac97_mute_put, - .private_value = AC97_MIC - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Mic Playback Switch", + .info = aureon_ac97_mute_info, + .get = aureon_ac97_mute_get, + .put = aureon_ac97_mute_put, + .private_value = AC97_MIC + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "Mic Playback Volume", - .info = aureon_ac97_vol_info, - .get = aureon_ac97_vol_get, - .put = aureon_ac97_vol_put, - .private_value = AC97_MIC, + SNDRV_CTL_ELEM_ACCESS_TLV_READ), + .name = "Mic Playback Volume", + .info = aureon_ac97_vol_info, + .get = aureon_ac97_vol_get, + .put = aureon_ac97_vol_put, + .private_value = AC97_MIC, .tlv = { .p = db_scale_ac97_gain } - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Mic Boost (+20dB)", - .info = aureon_ac97_micboost_info, - .get = aureon_ac97_micboost_get, - .put = aureon_ac97_micboost_put - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Aux Playback Switch", - .info = aureon_ac97_mute_info, - .get = aureon_ac97_mute_get, - .put = aureon_ac97_mute_put, - .private_value = AC97_VIDEO, - }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Mic Boost (+20dB)", + .info = aureon_ac97_micboost_info, + .get = aureon_ac97_micboost_get, + .put = aureon_ac97_micboost_put + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Aux Playback Switch", + .info = aureon_ac97_mute_info, + .get = aureon_ac97_mute_get, + .put = aureon_ac97_mute_put, + .private_value = AC97_VIDEO, + }, + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | - SNDRV_CTL_ELEM_ACCESS_TLV_READ), - .name = "Aux Playback Volume", - .info = aureon_ac97_vol_info, - .get = aureon_ac97_vol_get, - .put = aureon_ac97_vol_put, - .private_value = AC97_VIDEO|AUREON_AC97_STEREO, + SNDRV_CTL_ELEM_ACCESS_TLV_READ), + .name = "Aux Playback Volume", + .info = aureon_ac97_vol_info, + .get = aureon_ac97_vol_get, + .put = aureon_ac97_vol_put, + .private_value = AC97_VIDEO|AUREON_AC97_STEREO, .tlv = { .p = db_scale_ac97_gain } - }, + }, { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Aux Source", @@ -1844,43 +1869,43 @@ static struct snd_kcontrol_new universe_ac97_controls[] __devinitdata = { static struct snd_kcontrol_new cs8415_controls[] __devinitdata = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH), + .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, SWITCH), .info = aureon_cs8415_mute_info, .get = aureon_cs8415_mute_get, .put = aureon_cs8415_mute_put }, - { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Source", + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, NONE) "Source", .info = aureon_cs8415_mux_info, .get = aureon_cs8415_mux_get, .put = aureon_cs8415_mux_put, }, { .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = SNDRV_CTL_NAME_IEC958("Q-subcode ",CAPTURE,DEFAULT), + .name = SNDRV_CTL_NAME_IEC958("Q-subcode ", CAPTURE, DEFAULT), .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, .info = aureon_cs8415_qsub_info, .get = aureon_cs8415_qsub_get, }, { .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,MASK), + .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, MASK), .access = SNDRV_CTL_ELEM_ACCESS_READ, .info = aureon_cs8415_spdif_info, .get = aureon_cs8415_mask_get }, { .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,DEFAULT), + .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, DEFAULT), .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, .info = aureon_cs8415_spdif_info, .get = aureon_cs8415_spdif_get }, { .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,NONE) "Rate", - .access =SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, + .name = SNDRV_CTL_NAME_IEC958("", CAPTURE, NONE) "Rate", + .access = SNDRV_CTL_ELEM_ACCESS_READ | SNDRV_CTL_ELEM_ACCESS_VOLATILE, .info = aureon_cs8415_rate_info, .get = aureon_cs8415_rate_get } @@ -1905,15 +1930,14 @@ static int __devinit aureon_add_controls(struct snd_ice1712 *ice) if (err < 0) return err; } - + if (ice->eeprom.subvendor == VT1724_SUBDEVICE_AUREON71_UNIVERSE) { for (i = 0; i < ARRAY_SIZE(universe_ac97_controls); i++) { err = snd_ctl_add(ice->card, snd_ctl_new1(&universe_ac97_controls[i], ice)); if (err < 0) return err; } - } - else if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT && + } else if (ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71LT && ice->eeprom.subvendor != VT1724_SUBDEVICE_PRODIGY71XT) { for (i = 0; i < ARRAY_SIZE(ac97_controls); i++) { err = snd_ctl_add(ice->card, snd_ctl_new1(&ac97_controls[i], ice)); @@ -1932,7 +1956,7 @@ static int __devinit aureon_add_controls(struct snd_ice1712 *ice) else if ((id & 0x0F) != 0x01) snd_printk(KERN_INFO "Detected unsupported CS8415 rev. (%c)\n", (char)((id & 0x0F) + 'A' - 1)); else { - for (i = 0; i< ARRAY_SIZE(cs8415_controls); i++) { + for (i = 0; i < ARRAY_SIZE(cs8415_controls); i++) { struct snd_kcontrol *kctl; err = snd_ctl_add(ice->card, (kctl = snd_ctl_new1(&cs8415_controls[i], ice))); if (err < 0) @@ -1943,7 +1967,7 @@ static int __devinit aureon_add_controls(struct snd_ice1712 *ice) } snd_ice1712_restore_gpio_status(ice); } - + return 0; } @@ -2059,11 +2083,12 @@ static int __devinit aureon_init(struct snd_ice1712 *ice) /* to remeber the register values of CS8415 */ ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); - if (! ice->akm) + if (!ice->akm) return -ENOMEM; ice->akm_codecs = 1; - - if ((err = aureon_ac97_init(ice)) != 0) + + err = aureon_ac97_init(ice); + if (err != 0) return err; snd_ice1712_gpio_set_dir(ice, 0x5fffff); /* fix this for the time being */ @@ -2086,7 +2111,7 @@ static int __devinit aureon_init(struct snd_ice1712 *ice) /* initialize WM8770 codec */ if (ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71 || ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71LT || - ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71XT) + ice->eeprom.subvendor == VT1724_SUBDEVICE_PRODIGY71XT) p = wm_inits_prodigy; else p = wm_inits_aureon; @@ -2105,10 +2130,10 @@ static int __devinit aureon_init(struct snd_ice1712 *ice) snd_ice1712_restore_gpio_status(ice); - /* initialize PCA9554 pin directions & set default input*/ + /* initialize PCA9554 pin directions & set default input */ aureon_pca9554_write(ice, PCA9554_DIR, 0x00); aureon_pca9554_write(ice, PCA9554_OUT, 0x00); /* internal AUX */ - + spec->master[0] = WM_VOL_MUTE; spec->master[1] = WM_VOL_MUTE; for (i = 0; i < ice->num_total_dacs; i++) { @@ -2215,12 +2240,12 @@ struct snd_ice1712_card_info snd_vt1724_aureon_cards[] __devinitdata = { .eeprom_data = aureon71_eeprom, .driver = "Aureon71", }, - { - .subvendor = VT1724_SUBDEVICE_AUREON71_UNIVERSE, - .name = "Terratec Aureon 7.1-Universe", + { + .subvendor = VT1724_SUBDEVICE_AUREON71_UNIVERSE, + .name = "Terratec Aureon 7.1-Universe", .model = "universe", - .chip_init = aureon_init, - .build_controls = aureon_add_controls, + .chip_init = aureon_init, + .build_controls = aureon_add_controls, .eeprom_size = sizeof(aureon71_universe_eeprom), .eeprom_data = aureon71_universe_eeprom, .driver = "Aureon71Univ", /* keep in 15 letters */ -- cgit v1.2.3 From f14d8e975054ae186eba229485a213dfcc7a25da Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Sun, 7 Sep 2008 01:54:27 +0400 Subject: ALSA: ice1712/wtm: fix coding style before: total: 2 errors, 0 warnings, 20 lines checked total: 49 errors, 2 warnings, 518 lines checked after: total: 0 errors, 0 warnings, 20 lines checked total: 0 errors, 0 warnings, 518 lines checked Compile tested, size and code are equal. Signed-off-by: Alexander Beregalov Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/ice1712/wtm.c | 104 ++++++++++++++++++++++++------------------------ sound/pci/ice1712/wtm.h | 4 +- 2 files changed, 54 insertions(+), 54 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/ice1712/wtm.c b/sound/pci/ice1712/wtm.c index a08d17c7e65..5af9e84456d 100644 --- a/sound/pci/ice1712/wtm.c +++ b/sound/pci/ice1712/wtm.c @@ -1,12 +1,12 @@ /* * ALSA driver for ICEnsemble VT1724 (Envy24HT) - * + * * Lowlevel functions for Ego Sys Waveterminal 192M * * Copyright (c) 2006 Guedez Clement * Some functions are taken from the Prodigy192 driver * source - * + * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or @@ -20,12 +20,12 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - */ + * + */ -#include +#include #include #include #include @@ -39,9 +39,9 @@ /* - * 2*ADC 6*DAC no1 ringbuffer r/w on i2c bus + * 2*ADC 6*DAC no1 ringbuffer r/w on i2c bus */ -static inline void stac9460_put(struct snd_ice1712 *ice, int reg, +static inline void stac9460_put(struct snd_ice1712 *ice, int reg, unsigned char val) { snd_vt1724_write_i2c(ice, STAC9460_I2C_ADDR, reg, val); @@ -73,7 +73,7 @@ static inline unsigned char stac9460_2_get(struct snd_ice1712 *ice, int reg) #define stac9460_dac_mute_info snd_ctl_boolean_mono_info static int stac9460_dac_mute_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) + struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); unsigned char val; @@ -88,14 +88,14 @@ static int stac9460_dac_mute_get(struct snd_kcontrol *kcontrol, } if (id < 6) val = stac9460_get(ice, idx); - else - val = stac9460_2_get(ice,idx - 6); + else + val = stac9460_2_get(ice, idx - 6); ucontrol->value.integer.value[0] = (~val >> 7) & 0x1; return 0; } static int stac9460_dac_mute_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) + struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); unsigned char new, old; @@ -105,8 +105,8 @@ static int stac9460_dac_mute_put(struct snd_kcontrol *kcontrol, if (kcontrol->private_value) { idx = STAC946X_MASTER_VOLUME; old = stac9460_get(ice, idx); - new = (~ucontrol->value.integer.value[0]<< 7 & 0x80) | - (old & ~0x80); + new = (~ucontrol->value.integer.value[0] << 7 & 0x80) | + (old & ~0x80); change = (new != old); if (change) { stac9460_put(ice, idx, new); @@ -117,16 +117,16 @@ static int stac9460_dac_mute_put(struct snd_kcontrol *kcontrol, idx = id + STAC946X_LF_VOLUME; if (id < 6) old = stac9460_get(ice, idx); - else + else old = stac9460_2_get(ice, idx - 6); - new = (~ucontrol->value.integer.value[0]<< 7 & 0x80) | + new = (~ucontrol->value.integer.value[0] << 7 & 0x80) | (old & ~0x80); change = (new != old); if (change) { if (id < 6) - stac9460_put(ice, idx, new); + stac9460_put(ice, idx, new); else - stac9460_2_put(ice, idx - 6, new); + stac9460_2_put(ice, idx - 6, new); } } return change; @@ -136,7 +136,7 @@ static int stac9460_dac_mute_put(struct snd_kcontrol *kcontrol, * DAC volume attenuation mixer control */ static int stac9460_dac_vol_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) + struct snd_ctl_elem_info *uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; uinfo->count = 1; @@ -146,7 +146,7 @@ static int stac9460_dac_vol_info(struct snd_kcontrol *kcontrol, } static int stac9460_dac_vol_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) + struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); int idx, id; @@ -161,14 +161,14 @@ static int stac9460_dac_vol_get(struct snd_kcontrol *kcontrol, } if (id < 6) vol = stac9460_get(ice, idx) & 0x7f; - else + else vol = stac9460_2_get(ice, idx - 6) & 0x7f; ucontrol->value.integer.value[0] = 0x7f - vol; return 0; } static int stac9460_dac_vol_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) + struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); int idx, id; @@ -182,8 +182,8 @@ static int stac9460_dac_vol_put(struct snd_kcontrol *kcontrol, ovol = 0x7f - (tmp & 0x7f); change = (ovol != nvol); if (change) { - stac9460_put(ice, idx, (0x7f - nvol) | (tmp & 0x80)); - stac9460_2_put(ice, idx, (0x7f - nvol) | (tmp & 0x80)); + stac9460_put(ice, idx, (0x7f - nvol) | (tmp & 0x80)); + stac9460_2_put(ice, idx, (0x7f - nvol) | (tmp & 0x80)); } } else { id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); @@ -191,17 +191,17 @@ static int stac9460_dac_vol_put(struct snd_kcontrol *kcontrol, nvol = ucontrol->value.integer.value[0] & 0x7f; if (id < 6) tmp = stac9460_get(ice, idx); - else + else tmp = stac9460_2_get(ice, idx - 6); ovol = 0x7f - (tmp & 0x7f); change = (ovol != nvol); if (change) { if (id < 6) stac9460_put(ice, idx, (0x7f - nvol) | - (tmp & 0x80)); - else + (tmp & 0x80)); + else stac9460_2_put(ice, idx-6, (0x7f - nvol) | - (tmp & 0x80)); + (tmp & 0x80)); } } return change; @@ -213,12 +213,12 @@ static int stac9460_dac_vol_put(struct snd_kcontrol *kcontrol, #define stac9460_adc_mute_info snd_ctl_boolean_stereo_info static int stac9460_adc_mute_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) + struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); unsigned char val; int i, id; - + id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); if (id == 0) { for (i = 0; i < 2; ++i) { @@ -235,20 +235,20 @@ static int stac9460_adc_mute_get(struct snd_kcontrol *kcontrol, } static int stac9460_adc_mute_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) + struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); unsigned char new, old; int i, reg, id; int change; - + id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); if (id == 0) { for (i = 0; i < 2; ++i) { reg = STAC946X_MIC_L_VOLUME + i; old = stac9460_get(ice, reg); new = (~ucontrol->value.integer.value[i]<<7&0x80) | - (old&~0x80); + (old&~0x80); change = (new != old); if (change) stac9460_put(ice, reg, new); @@ -258,7 +258,7 @@ static int stac9460_adc_mute_put(struct snd_kcontrol *kcontrol, reg = STAC946X_MIC_L_VOLUME + i; old = stac9460_2_get(ice, reg); new = (~ucontrol->value.integer.value[i]<<7&0x80) | - (old&~0x80); + (old&~0x80); change = (new != old); if (change) stac9460_2_put(ice, reg, new); @@ -271,7 +271,7 @@ static int stac9460_adc_mute_put(struct snd_kcontrol *kcontrol, *ADC gain mixer control */ static int stac9460_adc_vol_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) + struct snd_ctl_elem_info *uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; uinfo->count = 2; @@ -281,12 +281,12 @@ static int stac9460_adc_vol_info(struct snd_kcontrol *kcontrol, } static int stac9460_adc_vol_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) + struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); int i, reg, id; unsigned char vol; - + id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); if (id == 0) { for (i = 0; i < 2; ++i) { @@ -305,13 +305,13 @@ static int stac9460_adc_vol_get(struct snd_kcontrol *kcontrol, } static int stac9460_adc_vol_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) + struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); int i, reg, id; unsigned char ovol, nvol; int change; - + id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); if (id == 0) { for (i = 0; i < 2; ++i) { @@ -321,7 +321,7 @@ static int stac9460_adc_vol_put(struct snd_kcontrol *kcontrol, change = ((ovol & 0x0f) != nvol); if (change) stac9460_put(ice, reg, (0x0f - nvol) | - (ovol & ~0x0f)); + (ovol & ~0x0f)); } } else { for (i = 0; i < 2; ++i) { @@ -331,7 +331,7 @@ static int stac9460_adc_vol_put(struct snd_kcontrol *kcontrol, change = ((ovol & 0x0f) != nvol); if (change) stac9460_2_put(ice, reg, (0x0f - nvol) | - (ovol & ~0x0f)); + (ovol & ~0x0f)); } } return change; @@ -344,23 +344,23 @@ static int stac9460_adc_vol_put(struct snd_kcontrol *kcontrol, #define stac9460_mic_sw_info snd_ctl_boolean_mono_info static int stac9460_mic_sw_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) + struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); unsigned char val; int id; - + id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); if (id == 0) - val = stac9460_get(ice, STAC946X_GENERAL_PURPOSE); + val = stac9460_get(ice, STAC946X_GENERAL_PURPOSE); else - val = stac9460_2_get(ice, STAC946X_GENERAL_PURPOSE); + val = stac9460_2_get(ice, STAC946X_GENERAL_PURPOSE); ucontrol->value.integer.value[0] = ~val>>7 & 0x1; return 0; } static int stac9460_mic_sw_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) + struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); unsigned char new, old; @@ -368,16 +368,16 @@ static int stac9460_mic_sw_put(struct snd_kcontrol *kcontrol, id = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); if (id == 0) - old = stac9460_get(ice, STAC946X_GENERAL_PURPOSE); + old = stac9460_get(ice, STAC946X_GENERAL_PURPOSE); else - old = stac9460_2_get(ice, STAC946X_GENERAL_PURPOSE); - new = (~ucontrol->value.integer.value[0]<< 7 & 0x80) | (old & ~0x80); + old = stac9460_2_get(ice, STAC946X_GENERAL_PURPOSE); + new = (~ucontrol->value.integer.value[0] << 7 & 0x80) | (old & ~0x80); change = (new != old); if (change) { if (id == 0) - stac9460_put(ice, STAC946X_GENERAL_PURPOSE, new); + stac9460_put(ice, STAC946X_GENERAL_PURPOSE, new); else - stac9460_2_put(ice, STAC946X_GENERAL_PURPOSE, new); + stac9460_2_put(ice, STAC946X_GENERAL_PURPOSE, new); } return change; } @@ -443,7 +443,7 @@ static struct snd_kcontrol_new stac9640_controls[] __devinitdata = { .get = stac9460_adc_vol_get, .put = stac9460_adc_vol_put, - } + } }; @@ -470,7 +470,7 @@ static int __devinit wtm_init(struct snd_ice1712 *ice) (unsigned short)-1 }; unsigned short *p; - + /*WTM 192M*/ ice->num_total_dacs = 8; ice->num_total_adcs = 4; diff --git a/sound/pci/ice1712/wtm.h b/sound/pci/ice1712/wtm.h index 03a394e442f..423c1a204c0 100644 --- a/sound/pci/ice1712/wtm.h +++ b/sound/pci/ice1712/wtm.h @@ -10,8 +10,8 @@ */ #define AK4114_ADDR 0x20 /*S/PDIF receiver*/ -#define STAC9460_I2C_ADDR 0x54 /* ADC*2 | DAC*6 */ -#define STAC9460_2_I2C_ADDR 0x56 /* ADC|DAC *2 */ +#define STAC9460_I2C_ADDR 0x54 /* ADC*2 | DAC*6 */ +#define STAC9460_2_I2C_ADDR 0x56 /* ADC|DAC *2 */ extern struct snd_ice1712_card_info snd_vt1724_wtm_cards[]; -- cgit v1.2.3 From d9737751eb7f2f3f6e973834ea9f215e855d46ea Mon Sep 17 00:00:00 2001 From: Matthew Ranostay Date: Sun, 7 Sep 2008 12:03:41 +0200 Subject: ALSA: hda: SPDIF mux controls Dynamically create mux controls for SPDIF outs on certain IDT/Sigmatel codecs. Signed-off-by: Matthew Ranostay Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 114 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 112 insertions(+), 2 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index c72c748322a..8ff7b95c34e 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -173,6 +173,9 @@ struct sigmatel_spec { unsigned int num_dmics; hda_nid_t *dmux_nids; unsigned int num_dmuxes; + hda_nid_t *smux_nids; + unsigned int num_smuxes; + hda_nid_t dig_in_nid; hda_nid_t mono_nid; hda_nid_t anabeep_nid; @@ -193,6 +196,8 @@ struct sigmatel_spec { unsigned int cur_dmux[2]; struct hda_input_mux *input_mux; unsigned int cur_mux[3]; + struct hda_input_mux *sinput_mux; + unsigned int cur_smux[2]; unsigned int powerdown_adcs; /* i/o switches */ @@ -209,6 +214,7 @@ struct sigmatel_spec { struct snd_kcontrol_new *kctl_alloc; struct hda_input_mux private_dimux; struct hda_input_mux private_imux; + struct hda_input_mux private_smux; struct hda_input_mux private_mono_mux; }; @@ -251,6 +257,10 @@ static hda_nid_t stac92hd73xx_dmux_nids[2] = { 0x20, 0x21, }; +static hda_nid_t stac92hd73xx_smux_nids[2] = { + 0x22, 0x23, +}; + #define STAC92HD83XXX_NUM_DMICS 2 static hda_nid_t stac92hd83xxx_dmic_nids[STAC92HD83XXX_NUM_DMICS + 1] = { 0x11, 0x12, 0 @@ -294,6 +304,10 @@ static hda_nid_t stac92hd71bxx_dmux_nids[1] = { 0x1c, }; +static hda_nid_t stac92hd71bxx_smux_nids[2] = { + 0x24, 0x25, +}; + static hda_nid_t stac92hd71bxx_dac_nids[1] = { 0x10, /*0x11, */ }; @@ -340,6 +354,10 @@ static hda_nid_t stac927x_mux_nids[3] = { 0x15, 0x16, 0x17 }; +static hda_nid_t stac927x_smux_nids[1] = { + 0x21, +}; + static hda_nid_t stac927x_dac_nids[6] = { 0x02, 0x03, 0x04, 0x05, 0x06, 0 }; @@ -365,6 +383,10 @@ static hda_nid_t stac9205_dmux_nids[1] = { 0x1d, }; +static hda_nid_t stac9205_smux_nids[1] = { + 0x21, +}; + #define STAC9205_NUM_DMICS 2 static hda_nid_t stac9205_dmic_nids[STAC9205_NUM_DMICS + 1] = { 0x17, 0x18, 0 @@ -388,7 +410,7 @@ static hda_nid_t stac922x_pin_nids[10] = { static hda_nid_t stac92hd73xx_pin_nids[13] = { 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, - 0x14, 0x1e, 0x22 + 0x14, 0x22, 0x23 }; static hda_nid_t stac92hd83xxx_pin_nids[14] = { @@ -443,6 +465,36 @@ static int stac92xx_dmux_enum_put(struct snd_kcontrol *kcontrol, spec->dmux_nids[dmux_idx], &spec->cur_dmux[dmux_idx]); } +static int stac92xx_smux_enum_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct sigmatel_spec *spec = codec->spec; + return snd_hda_input_mux_info(spec->sinput_mux, uinfo); +} + +static int stac92xx_smux_enum_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct sigmatel_spec *spec = codec->spec; + unsigned int smux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); + + ucontrol->value.enumerated.item[0] = spec->cur_smux[smux_idx]; + return 0; +} + +static int stac92xx_smux_enum_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct sigmatel_spec *spec = codec->spec; + unsigned int smux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); + + return snd_hda_input_mux_put(codec, spec->sinput_mux, ucontrol, + spec->smux_nids[smux_idx], &spec->cur_smux[smux_idx]); +} + static int stac92xx_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); @@ -993,6 +1045,15 @@ static struct snd_kcontrol_new stac_dmux_mixer = { .put = stac92xx_dmux_enum_put, }; +static struct snd_kcontrol_new stac_smux_mixer = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "IEC958 Mux", + /* count set later */ + .info = stac92xx_smux_enum_info, + .get = stac92xx_smux_enum_get, + .put = stac92xx_smux_enum_put, +}; + static const char *slave_vols[] = { "Front Playback Volume", "Surround Playback Volume", @@ -1044,6 +1105,13 @@ static int stac92xx_build_controls(struct hda_codec *codec) if (err < 0) return err; } + if (spec->num_smuxes > 0) { + stac_smux_mixer.count = spec->num_smuxes; + err = snd_ctl_add(codec->bus->card, + snd_ctl_new1(&stac_smux_mixer, codec)); + if (err < 0) + return err; + } if (spec->multiout.dig_out_nid) { err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); @@ -2811,6 +2879,34 @@ static int stac92xx_auto_create_mux_input_ctls(struct hda_codec *codec) return 0; }; +static const char *stac92xx_spdif_labels[3] = { + "Digital Playback", "Analog Mux 1", "Analog Mux 2" +}; + +static int stac92xx_auto_create_spdif_mux_ctls(struct hda_codec *codec) +{ + struct sigmatel_spec *spec = codec->spec; + struct hda_input_mux *spdif_mux = &spec->private_smux; + int i, num_cons; + hda_nid_t con_lst[ARRAY_SIZE(stac92xx_spdif_labels)]; + + num_cons = snd_hda_get_connections(codec, + spec->smux_nids[0], + con_lst, + HDA_MAX_NUM_INPUTS); + if (!num_cons || num_cons > ARRAY_SIZE(stac92xx_spdif_labels)) + return -EINVAL; + + for (i = 0; i < num_cons; i++) { + spdif_mux->items[spdif_mux->num_items].label = + stac92xx_spdif_labels[i]; + spdif_mux->items[spdif_mux->num_items].index = i; + spdif_mux->num_items++; + } + + return 0; +} + /* labels for dmic mux inputs */ static const char *stac92xx_dmic_labels[5] = { "Analog Inputs", "Digital Mic 1", "Digital Mic 2", @@ -3114,6 +3210,11 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out if (err < 0) return err; } + if (spec->num_smuxes > 0) { + err = stac92xx_auto_create_spdif_mux_ctls(codec); + if (err < 0) + return err; + } spec->multiout.max_channels = spec->multiout.num_dacs * 2; if (spec->multiout.max_channels > 2) @@ -3130,6 +3231,7 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out spec->input_mux = &spec->private_imux; if (!spec->dinput_mux) spec->dinput_mux = &spec->private_dimux; + spec->sinput_mux = &spec->private_smux; spec->mono_mux = &spec->private_mono_mux; return 1; @@ -3800,10 +3902,12 @@ again: spec->adc_nids = stac92hd73xx_adc_nids; spec->dmic_nids = stac92hd73xx_dmic_nids; spec->dmux_nids = stac92hd73xx_dmux_nids; + spec->smux_nids = stac92hd73xx_smux_nids; spec->num_muxes = ARRAY_SIZE(stac92hd73xx_mux_nids); spec->num_adcs = ARRAY_SIZE(stac92hd73xx_adc_nids); spec->num_dmuxes = ARRAY_SIZE(stac92hd73xx_dmux_nids); + spec->num_smuxes = ARRAY_SIZE(stac92hd73xx_smux_nids); spec->dinput_mux = &stac92hd73xx_dmux; /* GPIO0 High = Enable EAPD */ spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1; @@ -3842,7 +3946,7 @@ again: spec->num_pwrs = ARRAY_SIZE(stac92hd73xx_pwr_nids); spec->pwr_nids = stac92hd73xx_pwr_nids; - err = stac92xx_parse_auto_config(codec, 0x22, 0x24); + err = stac92xx_parse_auto_config(codec, 0x25, 0x27); if (!err) { if (spec->board_config < 0) { @@ -4081,11 +4185,13 @@ again: spec->adc_nids = stac92hd71bxx_adc_nids; spec->dmic_nids = stac92hd71bxx_dmic_nids; spec->dmux_nids = stac92hd71bxx_dmux_nids; + spec->smux_nids = stac92hd71bxx_smux_nids; spec->pwr_nids = stac92hd71bxx_pwr_nids; spec->num_muxes = ARRAY_SIZE(stac92hd71bxx_mux_nids); spec->num_adcs = ARRAY_SIZE(stac92hd71bxx_adc_nids); spec->num_dmics = STAC92HD71BXX_NUM_DMICS; + spec->num_smuxes = ARRAY_SIZE(stac92hd71bxx_smux_nids); spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); spec->multiout.num_dacs = 1; @@ -4254,6 +4360,8 @@ static int patch_stac927x(struct hda_codec *codec) spec->num_adcs = ARRAY_SIZE(stac927x_adc_nids); spec->mux_nids = stac927x_mux_nids; spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids); + spec->smux_nids = stac927x_smux_nids; + spec->num_smuxes = ARRAY_SIZE(stac927x_smux_nids); spec->dac_list = stac927x_dac_nids; spec->multiout.dac_nids = spec->dac_nids; @@ -4375,6 +4483,8 @@ static int patch_stac9205(struct hda_codec *codec) spec->num_adcs = ARRAY_SIZE(stac9205_adc_nids); spec->mux_nids = stac9205_mux_nids; spec->num_muxes = ARRAY_SIZE(stac9205_mux_nids); + spec->smux_nids = stac9205_smux_nids; + spec->num_smuxes = ARRAY_SIZE(stac9205_smux_nids); spec->dmic_nids = stac9205_dmic_nids; spec->num_dmics = STAC9205_NUM_DMICS; spec->dmux_nids = stac9205_dmux_nids; -- cgit v1.2.3 From 07f455f779acfb3eba4921fd1399761559b10fa9 Mon Sep 17 00:00:00 2001 From: Matthew Ranostay Date: Sun, 7 Sep 2008 12:04:17 +0200 Subject: ALSA: hda: removed unneeded hp_nid references Removed unneeded hp_nid references for 92hd73xx codec family. Signed-off-by: Matthew Ranostay Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 8ff7b95c34e..4da53689618 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -3878,17 +3878,14 @@ again: switch (spec->multiout.num_dacs) { case 0x3: /* 6 Channel */ - spec->multiout.hp_nid = 0x17; spec->mixer = stac92hd73xx_6ch_mixer; spec->init = stac92hd73xx_6ch_core_init; break; case 0x4: /* 8 Channel */ - spec->multiout.hp_nid = 0x18; spec->mixer = stac92hd73xx_8ch_mixer; spec->init = stac92hd73xx_8ch_core_init; break; case 0x5: /* 10 Channel */ - spec->multiout.hp_nid = 0x19; spec->mixer = stac92hd73xx_10ch_mixer; spec->init = stac92hd73xx_10ch_core_init; }; -- cgit v1.2.3 From cc67b7f737103a2985e65e00edfdd1a5f89c3af5 Mon Sep 17 00:00:00 2001 From: Vedran Miletic Date: Sun, 7 Sep 2008 12:00:02 +0200 Subject: ALSA: ice1712/ice1724: Coding style fixes part 1 (more coming up) Inspired by Alexander Beregalov's patches for wtm and aureon.c, I decided to run checkpatch on some more files. After some work checkpatch.pl-0.23 --no-tree --file --strict reports 0 errors, 0 warnings, 0 checks, n lines checked for: phase.c phase.h juli.c (1 check about unused code, maybe we should comment it) juli.h (no changes necessary) In other files I have just fixed // comments and long lines along the way (but not all of them), more coming up. Signed-off-by: Vedran Miletic Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/ice1712/delta.c | 2 +- sound/pci/ice1712/juli.c | 44 ++++---- sound/pci/ice1712/phase.c | 244 ++++++++++++++++++++++++++------------------- sound/pci/ice1712/phase.h | 8 +- sound/pci/ice1712/pontis.c | 5 +- sound/pci/ice1712/revo.c | 8 +- 6 files changed, 183 insertions(+), 128 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/ice1712/delta.c b/sound/pci/ice1712/delta.c index 0ed96c17805..d216362626d 100644 --- a/sound/pci/ice1712/delta.c +++ b/sound/pci/ice1712/delta.c @@ -400,7 +400,7 @@ static void delta_setup_spdif(struct snd_ice1712 *ice, int rate) static int snd_ice1712_delta1010lt_wordclock_status_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { - char reg = 0x10; // cs8427 receiver error register + char reg = 0x10; /* CS8427 receiver error register */ struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); if (snd_i2c_sendbytes(ice->cs8427, ®, 1) != 1) diff --git a/sound/pci/ice1712/juli.c b/sound/pci/ice1712/juli.c index 21ff4de890b..c51659b9caf 100644 --- a/sound/pci/ice1712/juli.c +++ b/sound/pci/ice1712/juli.c @@ -21,7 +21,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - */ + */ #include #include @@ -34,9 +34,10 @@ #include "ice1712.h" #include "envy24ht.h" #include "juli.h" + struct juli_spec { struct ak4114 *ak4114; - unsigned int analog: 1; + unsigned int analog:1; }; /* @@ -160,14 +161,17 @@ static int get_gpio_val(int rate) return 0; } -static void juli_ak4114_write(void *private_data, unsigned char reg, unsigned char val) +static void juli_ak4114_write(void *private_data, unsigned char reg, + unsigned char val) { - snd_vt1724_write_i2c((struct snd_ice1712 *)private_data, AK4114_ADDR, reg, val); + snd_vt1724_write_i2c((struct snd_ice1712 *)private_data, AK4114_ADDR, + reg, val); } - + static unsigned char juli_ak4114_read(void *private_data, unsigned char reg) { - return snd_vt1724_read_i2c((struct snd_ice1712 *)private_data, AK4114_ADDR, reg); + return snd_vt1724_read_i2c((struct snd_ice1712 *)private_data, + AK4114_ADDR, reg); } /* @@ -175,7 +179,7 @@ static unsigned char juli_ak4114_read(void *private_data, unsigned char reg) * to the external rate */ static void juli_spdif_in_open(struct snd_ice1712 *ice, - struct snd_pcm_substream *substream) + struct snd_pcm_substream *substream) { struct juli_spec *spec = ice->spec; struct snd_pcm_runtime *runtime = substream->runtime; @@ -572,10 +576,12 @@ static void juli_ak4114_change(struct ak4114 *ak4114, unsigned char c0, static int __devinit juli_init(struct snd_ice1712 *ice) { static const unsigned char ak4114_init_vals[] = { - /* AK4117_REG_PWRDN */ AK4114_RST | AK4114_PWN | AK4114_OCKS0 | AK4114_OCKS1, + /* AK4117_REG_PWRDN */ AK4114_RST | AK4114_PWN | + AK4114_OCKS0 | AK4114_OCKS1, /* AK4114_REQ_FORMAT */ AK4114_DIF_I24I2S, /* AK4114_REG_IO0 */ AK4114_TX1E, - /* AK4114_REG_IO1 */ AK4114_EFH_1024 | AK4114_DIT | AK4114_IPS(1), + /* AK4114_REG_IO1 */ AK4114_EFH_1024 | AK4114_DIT | + AK4114_IPS(1), /* AK4114_REG_INT0_MASK */ 0, /* AK4114_REG_INT1_MASK */ 0 }; @@ -605,12 +611,14 @@ static int __devinit juli_init(struct snd_ice1712 *ice) spec->ak4114->check_flags = 0; #if 0 - /* it seems that the analog doughter board detection does not work - reliably, so force the analog flag; it should be very rare - to use Juli@ without the analog doughter board */ +/* + * it seems that the analog doughter board detection does not work reliably, so + * force the analog flag; it should be very rare (if ever) to come at Juli@ + * used without the analog daughter board + */ spec->analog = (ice->gpio.get_data(ice) & GPIO_ANALOG_PRESENT) ? 0 : 1; #else - spec->analog = 1; + spec->analog = 1; #endif if (spec->analog) { @@ -618,14 +626,16 @@ static int __devinit juli_init(struct snd_ice1712 *ice) ice->num_total_dacs = 2; ice->num_total_adcs = 2; - ak = ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); - if (! ak) + ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); + ak = ice->akm; + if (!ak) return -ENOMEM; ice->akm_codecs = 1; - if ((err = snd_ice1712_akm4xxx_init(ak, &akm_juli_dac, NULL, ice)) < 0) + err = snd_ice1712_akm4xxx_init(ak, &akm_juli_dac, NULL, ice); + if (err < 0) return err; } - + /* juli is clocked by Xilinx array */ ice->hw_rates = &juli_rates_info; ice->is_spdif_master = juli_is_spdif_master; diff --git a/sound/pci/ice1712/phase.c b/sound/pci/ice1712/phase.c index 6a614729280..de29be8c965 100644 --- a/sound/pci/ice1712/phase.c +++ b/sound/pci/ice1712/phase.c @@ -37,7 +37,7 @@ */ /* PHASE 28 overview: - * Audio controller: VIA Envy24HT (full untrimmed version, 8in/8out) + * Audio controller: VIA Envy24HT (full untrimmed version, 4in/8out) * Analog chip: WM8770 (8 channel 192k DAC, 2 channel 96k ADC) * Digital receiver: CS8414-CS (supported in this release) */ @@ -86,18 +86,18 @@ struct phase28_spec { * Computed as 20 * Log10(255 / x) */ static const unsigned char wm_vol[256] = { - 127, 48, 42, 39, 36, 34, 33, 31, 30, 29, 28, 27, 27, 26, 25, 25, 24, 24, 23, - 23, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18, 17, 17, 17, - 17, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, 14, 13, 13, 13, - 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, 11, 11, 11, 11, 11, - 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 8, 8, - 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, - 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0 + 127, 48, 42, 39, 36, 34, 33, 31, 30, 29, 28, 27, 27, 26, 25, 25, 24, + 24, 23, 23, 22, 22, 21, 21, 21, 20, 20, 20, 19, 19, 19, 18, 18, 18, 18, + 17, 17, 17, 17, 16, 16, 16, 16, 15, 15, 15, 15, 15, 15, 14, 14, 14, 14, + 14, 13, 13, 13, 13, 13, 13, 13, 12, 12, 12, 12, 12, 12, 12, 11, 11, 11, + 11, 11, 11, 11, 11, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 9, 9, 9, 9, + 9, 9, 9, 9, 9, 9, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 7, 7, 7, 7, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, + 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; #define WM_VOL_MAX (sizeof(wm_vol) - 1) @@ -126,28 +126,31 @@ static int __devinit phase22_init(struct snd_ice1712 *ice) struct snd_akm4xxx *ak; int err; - // Configure DAC/ADC description for generic part of ice1724 + /* Configure DAC/ADC description for generic part of ice1724 */ switch (ice->eeprom.subvendor) { case VT1724_SUBDEVICE_PHASE22: case VT1724_SUBDEVICE_TS22: ice->num_total_dacs = 2; ice->num_total_adcs = 2; - ice->vt1720 = 1; // Envy24HT-S have 16 bit wide GPIO + ice->vt1720 = 1; /* Envy24HT-S have 16 bit wide GPIO */ break; default: snd_BUG(); return -EINVAL; } - // Initialize analog chips - ak = ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); - if (! ak) + /* Initialize analog chips */ + ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); + ak = ice->akm; + if (!ak) return -ENOMEM; ice->akm_codecs = 1; switch (ice->eeprom.subvendor) { case VT1724_SUBDEVICE_PHASE22: case VT1724_SUBDEVICE_TS22: - if ((err = snd_ice1712_akm4xxx_init(ak, &akm_phase22, &akm_phase22_priv, ice)) < 0) + err = snd_ice1712_akm4xxx_init(ak, &akm_phase22, + &akm_phase22_priv, ice); + if (err < 0) return err; break; } @@ -206,15 +209,16 @@ static unsigned char phase28_eeprom[] __devinitdata = { /* * write data in the SPI mode */ -static void phase28_spi_write(struct snd_ice1712 *ice, unsigned int cs, unsigned int data, int bits) +static void phase28_spi_write(struct snd_ice1712 *ice, unsigned int cs, + unsigned int data, int bits) { unsigned int tmp; int i; tmp = snd_ice1712_gpio_read(ice); - snd_ice1712_gpio_set_mask(ice, ~(PHASE28_WM_RW|PHASE28_SPI_MOSI|PHASE28_SPI_CLK| - PHASE28_WM_CS)); + snd_ice1712_gpio_set_mask(ice, ~(PHASE28_WM_RW|PHASE28_SPI_MOSI| + PHASE28_SPI_CLK|PHASE28_WM_CS)); tmp |= PHASE28_WM_RW; tmp &= ~cs; snd_ice1712_gpio_write(ice, tmp); @@ -273,14 +277,16 @@ static void wm_put(struct snd_ice1712 *ice, int reg, unsigned short val) ice->akm[0].images[reg + 1] = val; } -static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned short vol, unsigned short master) +static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, + unsigned short vol, unsigned short master) { unsigned char nvol; if ((master & WM_VOL_MUTE) || (vol & WM_VOL_MUTE)) nvol = 0; else - nvol = 127 - wm_vol[(((vol & ~WM_VOL_MUTE) * (master & ~WM_VOL_MUTE)) / 127) & WM_VOL_MAX]; + nvol = 127 - wm_vol[(((vol & ~WM_VOL_MUTE) * + (master & ~WM_VOL_MUTE)) / 127) & WM_VOL_MAX]; wm_put(ice, index, nvol); wm_put_nocache(ice, index, 0x180 | nvol); @@ -291,17 +297,20 @@ static void wm_set_vol(struct snd_ice1712 *ice, unsigned int index, unsigned sho */ #define wm_pcm_mute_info snd_ctl_boolean_mono_info -static int wm_pcm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int wm_pcm_mute_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); mutex_lock(&ice->gpio_mutex); - ucontrol->value.integer.value[0] = (wm_get(ice, WM_MUTE) & 0x10) ? 0 : 1; + ucontrol->value.integer.value[0] = (wm_get(ice, WM_MUTE) & 0x10) ? + 0 : 1; mutex_unlock(&ice->gpio_mutex); return 0; } -static int wm_pcm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int wm_pcm_mute_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); unsigned short nval, oval; @@ -310,7 +319,8 @@ static int wm_pcm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_va snd_ice1712_save_gpio_status(ice); oval = wm_get(ice, WM_MUTE); nval = (oval & ~0x10) | (ucontrol->value.integer.value[0] ? 0 : 0x10); - if ((change = (nval != oval))) + change = (nval != oval); + if (change) wm_put(ice, WM_MUTE, nval); snd_ice1712_restore_gpio_status(ice); @@ -320,7 +330,8 @@ static int wm_pcm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_va /* * Master volume attenuation mixer control */ -static int wm_master_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +static int wm_master_vol_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; uinfo->count = 2; @@ -329,17 +340,20 @@ static int wm_master_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem return 0; } -static int wm_master_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int wm_master_vol_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); struct phase28_spec *spec = ice->spec; int i; - for (i=0; i<2; i++) - ucontrol->value.integer.value[i] = spec->master[i] & ~WM_VOL_MUTE; + for (i = 0; i < 2; i++) + ucontrol->value.integer.value[i] = spec->master[i] & + ~WM_VOL_MUTE; return 0; } -static int wm_master_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int wm_master_vol_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); struct phase28_spec *spec = ice->spec; @@ -369,38 +383,38 @@ static int __devinit phase28_init(struct snd_ice1712 *ice) { static const unsigned short wm_inits_phase28[] = { /* These come first to reduce init pop noise */ - 0x1b, 0x044, /* ADC Mux (AC'97 source) */ - 0x1c, 0x00B, /* Out Mux1 (VOUT1 = DAC+AUX, VOUT2 = DAC) */ - 0x1d, 0x009, /* Out Mux2 (VOUT2 = DAC, VOUT3 = DAC) */ - - 0x18, 0x000, /* All power-up */ - - 0x16, 0x122, /* I2S, normal polarity, 24bit */ - 0x17, 0x022, /* 256fs, slave mode */ - 0x00, 0, /* DAC1 analog mute */ - 0x01, 0, /* DAC2 analog mute */ - 0x02, 0, /* DAC3 analog mute */ - 0x03, 0, /* DAC4 analog mute */ - 0x04, 0, /* DAC5 analog mute */ - 0x05, 0, /* DAC6 analog mute */ - 0x06, 0, /* DAC7 analog mute */ - 0x07, 0, /* DAC8 analog mute */ - 0x08, 0x100, /* master analog mute */ - 0x09, 0xff, /* DAC1 digital full */ - 0x0a, 0xff, /* DAC2 digital full */ - 0x0b, 0xff, /* DAC3 digital full */ - 0x0c, 0xff, /* DAC4 digital full */ - 0x0d, 0xff, /* DAC5 digital full */ - 0x0e, 0xff, /* DAC6 digital full */ - 0x0f, 0xff, /* DAC7 digital full */ - 0x10, 0xff, /* DAC8 digital full */ - 0x11, 0x1ff, /* master digital full */ - 0x12, 0x000, /* phase normal */ - 0x13, 0x090, /* unmute DAC L/R */ - 0x14, 0x000, /* all unmute */ - 0x15, 0x000, /* no deemphasis, no ZFLG */ - 0x19, 0x000, /* -12dB ADC/L */ - 0x1a, 0x000, /* -12dB ADC/R */ + 0x1b, 0x044, /* ADC Mux (AC'97 source) */ + 0x1c, 0x00B, /* Out Mux1 (VOUT1 = DAC+AUX, VOUT2 = DAC) */ + 0x1d, 0x009, /* Out Mux2 (VOUT2 = DAC, VOUT3 = DAC) */ + + 0x18, 0x000, /* All power-up */ + + 0x16, 0x122, /* I2S, normal polarity, 24bit */ + 0x17, 0x022, /* 256fs, slave mode */ + 0x00, 0, /* DAC1 analog mute */ + 0x01, 0, /* DAC2 analog mute */ + 0x02, 0, /* DAC3 analog mute */ + 0x03, 0, /* DAC4 analog mute */ + 0x04, 0, /* DAC5 analog mute */ + 0x05, 0, /* DAC6 analog mute */ + 0x06, 0, /* DAC7 analog mute */ + 0x07, 0, /* DAC8 analog mute */ + 0x08, 0x100, /* master analog mute */ + 0x09, 0xff, /* DAC1 digital full */ + 0x0a, 0xff, /* DAC2 digital full */ + 0x0b, 0xff, /* DAC3 digital full */ + 0x0c, 0xff, /* DAC4 digital full */ + 0x0d, 0xff, /* DAC5 digital full */ + 0x0e, 0xff, /* DAC6 digital full */ + 0x0f, 0xff, /* DAC7 digital full */ + 0x10, 0xff, /* DAC8 digital full */ + 0x11, 0x1ff, /* master digital full */ + 0x12, 0x000, /* phase normal */ + 0x13, 0x090, /* unmute DAC L/R */ + 0x14, 0x000, /* all unmute */ + 0x15, 0x000, /* no deemphasis, no ZFLG */ + 0x19, 0x000, /* -12dB ADC/L */ + 0x1a, 0x000, /* -12dB ADC/R */ (unsigned short)-1 }; @@ -418,17 +432,19 @@ static int __devinit phase28_init(struct snd_ice1712 *ice) return -ENOMEM; ice->spec = spec; - // Initialize analog chips - ak = ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); + /* Initialize analog chips */ + ice->akm = kzalloc(sizeof(struct snd_akm4xxx), GFP_KERNEL); + ak = ice->akm; if (!ak) return -ENOMEM; ice->akm_codecs = 1; - snd_ice1712_gpio_set_dir(ice, 0x5fffff); /* fix this for the time being */ + snd_ice1712_gpio_set_dir(ice, 0x5fffff); /* fix this for time being */ /* reset the wm codec as the SPI mode */ snd_ice1712_save_gpio_status(ice); - snd_ice1712_gpio_set_mask(ice, ~(PHASE28_WM_RESET|PHASE28_WM_CS|PHASE28_HP_SEL)); + snd_ice1712_gpio_set_mask(ice, ~(PHASE28_WM_RESET|PHASE28_WM_CS| + PHASE28_HP_SEL)); tmp = snd_ice1712_gpio_read(ice); tmp &= ~PHASE28_WM_RESET; @@ -460,7 +476,8 @@ static int __devinit phase28_init(struct snd_ice1712 *ice) /* * DAC volume attenuation mixer control */ -static int wm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +static int wm_vol_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) { int voices = kcontrol->private_value >> 8; uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; @@ -470,7 +487,8 @@ static int wm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info * return 0; } -static int wm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int wm_vol_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); struct phase28_spec *spec = ice->spec; @@ -484,7 +502,8 @@ static int wm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value * return 0; } -static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int wm_vol_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); struct phase28_spec *spec = ice->spec; @@ -515,7 +534,8 @@ static int wm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value * /* * WM8770 mute control */ -static int wm_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { +static int wm_mute_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; uinfo->count = kcontrol->private_value >> 8; uinfo->value.integer.min = 0; @@ -523,7 +543,8 @@ static int wm_mute_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info return 0; } -static int wm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int wm_mute_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); struct phase28_spec *spec = ice->spec; @@ -538,7 +559,8 @@ static int wm_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value return 0; } -static int wm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int wm_mute_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); struct phase28_spec *spec = ice->spec; @@ -553,9 +575,10 @@ static int wm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value if (ucontrol->value.integer.value[i] != val) { spec->vol[ofs + i] &= ~WM_VOL_MUTE; spec->vol[ofs + i] |= - ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE; + ucontrol->value.integer.value[i] ? 0 : + WM_VOL_MUTE; wm_set_vol(ice, ofs + i, spec->vol[ofs + i], - spec->master[i]); + spec->master[i]); change = 1; } } @@ -569,7 +592,8 @@ static int wm_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value */ #define wm_master_mute_info snd_ctl_boolean_stereo_info -static int wm_master_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int wm_master_mute_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); struct phase28_spec *spec = ice->spec; @@ -581,7 +605,8 @@ static int wm_master_mute_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem return 0; } -static int wm_master_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int wm_master_mute_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); struct phase28_spec *spec = ice->spec; @@ -594,11 +619,12 @@ static int wm_master_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem int dac; spec->master[i] &= ~WM_VOL_MUTE; spec->master[i] |= - ucontrol->value.integer.value[i] ? 0 : WM_VOL_MUTE; + ucontrol->value.integer.value[i] ? 0 : + WM_VOL_MUTE; for (dac = 0; dac < ice->num_total_dacs; dac += 2) wm_set_vol(ice, WM_DAC_ATTEN + dac + i, - spec->vol[dac + i], - spec->master[i]); + spec->vol[dac + i], + spec->master[i]); change = 1; } } @@ -611,7 +637,8 @@ static int wm_master_mute_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem #define PCM_0dB 0xff #define PCM_RES 128 /* -64dB */ #define PCM_MIN (PCM_0dB - PCM_RES) -static int wm_pcm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) +static int wm_pcm_vol_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) { uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; uinfo->count = 1; @@ -620,7 +647,8 @@ static int wm_pcm_vol_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_in return 0; } -static int wm_pcm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int wm_pcm_vol_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); unsigned short val; @@ -633,7 +661,8 @@ static int wm_pcm_vol_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val return 0; } -static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); unsigned short ovol, nvol; @@ -647,7 +676,8 @@ static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val ovol = wm_get(ice, WM_DAC_DIG_MASTER_ATTEN) & 0xff; if (ovol != nvol) { wm_put(ice, WM_DAC_DIG_MASTER_ATTEN, nvol); /* prelatch */ - wm_put_nocache(ice, WM_DAC_DIG_MASTER_ATTEN, nvol | 0x100); /* update */ + /* update */ + wm_put_nocache(ice, WM_DAC_DIG_MASTER_ATTEN, nvol | 0x100); change = 1; } snd_ice1712_restore_gpio_status(ice); @@ -659,18 +689,22 @@ static int wm_pcm_vol_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_val */ #define phase28_deemp_info snd_ctl_boolean_mono_info -static int phase28_deemp_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int phase28_deemp_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL2) & 0xf) == 0xf; + ucontrol->value.integer.value[0] = (wm_get(ice, WM_DAC_CTRL2) & 0xf) == + 0xf; return 0; } -static int phase28_deemp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int phase28_deemp_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); int temp, temp2; - temp2 = temp = wm_get(ice, WM_DAC_CTRL2); + temp = wm_get(ice, WM_DAC_CTRL2); + temp2 = temp; if (ucontrol->value.integer.value[0]) temp |= 0xf; else @@ -685,7 +719,8 @@ static int phase28_deemp_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_ /* * ADC Oversampling */ -static int phase28_oversampling_info(struct snd_kcontrol *k, struct snd_ctl_elem_info *uinfo) +static int phase28_oversampling_info(struct snd_kcontrol *k, + struct snd_ctl_elem_info *uinfo) { static char *texts[2] = { "128x", "64x" }; @@ -694,25 +729,31 @@ static int phase28_oversampling_info(struct snd_kcontrol *k, struct snd_ctl_elem 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]); + uinfo->value.enumerated.item = uinfo->value.enumerated.items - + 1; + strcpy(uinfo->value.enumerated.name, + texts[uinfo->value.enumerated.item]); - return 0; + return 0; } -static int phase28_oversampling_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int phase28_oversampling_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - ucontrol->value.enumerated.item[0] = (wm_get(ice, WM_MASTER) & 0x8) == 0x8; + ucontrol->value.enumerated.item[0] = (wm_get(ice, WM_MASTER) & 0x8) == + 0x8; return 0; } -static int phase28_oversampling_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) +static int phase28_oversampling_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) { int temp, temp2; struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - temp2 = temp = wm_get(ice, WM_MASTER); + temp = wm_get(ice, WM_MASTER); + temp2 = temp; if (ucontrol->value.enumerated.item[0]) temp |= 0x8; @@ -885,13 +926,16 @@ static int __devinit phase28_add_controls(struct snd_ice1712 *ice) counts = ARRAY_SIZE(phase28_dac_controls); for (i = 0; i < counts; i++) { - err = snd_ctl_add(ice->card, snd_ctl_new1(&phase28_dac_controls[i], ice)); + err = snd_ctl_add(ice->card, + snd_ctl_new1(&phase28_dac_controls[i], + ice)); if (err < 0) return err; } for (i = 0; i < ARRAY_SIZE(wm_controls); i++) { - err = snd_ctl_add(ice->card, snd_ctl_new1(&wm_controls[i], ice)); + err = snd_ctl_add(ice->card, + snd_ctl_new1(&wm_controls[i], ice)); if (err < 0) return err; } diff --git a/sound/pci/ice1712/phase.h b/sound/pci/ice1712/phase.h index 5f0c4dbf30d..7fc22d9d442 100644 --- a/sound/pci/ice1712/phase.h +++ b/sound/pci/ice1712/phase.h @@ -22,11 +22,11 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - */ + */ -#define PHASE_DEVICE_DESC "{Terratec,Phase 22},"\ - "{Terratec,Phase 28},"\ - "{Terrasoniq,TS22}," +#define PHASE_DEVICE_DESC "{Terratec,Phase 22},"\ + "{Terratec,Phase 28},"\ + "{Terrasoniq,TS22}," #define VT1724_SUBDEVICE_PHASE22 0x3b155011 #define VT1724_SUBDEVICE_PHASE28 0x3b154911 diff --git a/sound/pci/ice1712/pontis.c b/sound/pci/ice1712/pontis.c index 203cdc1bf8d..6bc3f91b728 100644 --- a/sound/pci/ice1712/pontis.c +++ b/sound/pci/ice1712/pontis.c @@ -43,7 +43,8 @@ /* WM8776 registers */ #define WM_HP_ATTEN_L 0x00 /* headphone left attenuation */ #define WM_HP_ATTEN_R 0x01 /* headphone left attenuation */ -#define WM_HP_MASTER 0x02 /* headphone master (both channels), override LLR */ +#define WM_HP_MASTER 0x02 /* headphone master (both channels) */ + /* override LLR */ #define WM_DAC_ATTEN_L 0x03 /* digital left attenuation */ #define WM_DAC_ATTEN_R 0x04 #define WM_DAC_MASTER 0x05 @@ -740,7 +741,7 @@ static int __devinit pontis_init(struct snd_ice1712 *ice) WM_DAC_ATTEN_L, 0x0100, /* DAC 0dB */ WM_DAC_ATTEN_R, 0x0000, /* DAC 0dB */ WM_DAC_ATTEN_R, 0x0100, /* DAC 0dB */ - // WM_DAC_MASTER, 0x0100, /* DAC master muted */ + /* WM_DAC_MASTER, 0x0100, */ /* DAC master muted */ WM_PHASE_SWAP, 0x0000, /* phase normal */ WM_DAC_CTRL2, 0x0000, /* no deemphasis, no ZFLG */ WM_ADC_ATTEN_L, 0x0000, /* ADC muted */ diff --git a/sound/pci/ice1712/revo.c b/sound/pci/ice1712/revo.c index d2193913d70..b508bb360b9 100644 --- a/sound/pci/ice1712/revo.c +++ b/sound/pci/ice1712/revo.c @@ -1,7 +1,7 @@ /* * ALSA driver for ICEnsemble ICE1712 (Envy24) * - * Lowlevel functions for M-Audio Revolution 7.1 + * Lowlevel functions for M-Audio Audiophile 192, Revolution 7.1 and 5.1 * * Copyright (c) 2003 Takashi Iwai * @@ -48,7 +48,7 @@ static void revo_i2s_mclk_changed(struct snd_ice1712 *ice) } /* - * change the rate of envy24HT, AK4355 and AK4381 + * change the rate of Envy24HT, AK4355 and AK4381 */ static void revo_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate) { @@ -83,8 +83,8 @@ static void revo_set_rate_val(struct snd_akm4xxx *ak, unsigned int rate) tmp = snd_akm4xxx_get(ak, 0, reg); tmp &= ~(0x03 << shift); tmp |= dfs << shift; - // snd_akm4xxx_write(ak, 0, reg, tmp); - snd_akm4xxx_set(ak, 0, reg, tmp); /* the value is written in reset(0) */ + /* snd_akm4xxx_write(ak, 0, reg, tmp); */ + snd_akm4xxx_set(ak, 0, reg, tmp); /* value is written in reset(0) */ snd_akm4xxx_reset(ak, 0); } -- cgit v1.2.3 From 1de9fdc24b01869e70ef9c576c3978506748db85 Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Sun, 7 Sep 2008 14:11:04 +0400 Subject: ALSA: ice1724.c: fix coding style before: total: 96 errors, 66 warnings, 2612 lines checked after: total: 11 errors, 64 warnings, 2624 lines checked Compile tested only. Signed-off-by: Alexander Beregalov Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/ice1712/ice1724.c | 180 +++++++++++++++++++++++--------------------- 1 file changed, 96 insertions(+), 84 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/ice1712/ice1724.c b/sound/pci/ice1712/ice1724.c index 7bb99df44fd..1b3f1170271 100644 --- a/sound/pci/ice1712/ice1724.c +++ b/sound/pci/ice1712/ice1724.c @@ -20,9 +20,9 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - */ + */ -#include +#include #include #include #include @@ -105,7 +105,7 @@ static unsigned int PRO_RATE_DEFAULT = 44100; /* * Basic I/O */ - + /* * default rates, default clock routines */ @@ -198,7 +198,7 @@ static void snd_vt1724_set_gpio_dir(struct snd_ice1712 *ice, unsigned int data) static void snd_vt1724_set_gpio_mask(struct snd_ice1712 *ice, unsigned int data) { outw(data, ICEREG1724(ice, GPIO_WRITE_MASK)); - if (! ice->vt1720) /* VT1720 supports only 16 GPIO bits */ + if (!ice->vt1720) /* VT1720 supports only 16 GPIO bits */ outb((data >> 16) & 0xff, ICEREG1724(ice, GPIO_WRITE_MASK_22)); inw(ICEREG1724(ice, GPIO_WRITE_MASK)); /* dummy read for pci-posting */ } @@ -206,7 +206,7 @@ static void snd_vt1724_set_gpio_mask(struct snd_ice1712 *ice, unsigned int data) static void snd_vt1724_set_gpio_data(struct snd_ice1712 *ice, unsigned int data) { outw(data, ICEREG1724(ice, GPIO_DATA)); - if (! ice->vt1720) + if (!ice->vt1720) outb(data >> 16, ICEREG1724(ice, GPIO_DATA_22)); inw(ICEREG1724(ice, GPIO_DATA)); /* dummy read for pci-posting */ } @@ -214,7 +214,7 @@ static void snd_vt1724_set_gpio_data(struct snd_ice1712 *ice, unsigned int data) static unsigned int snd_vt1724_get_gpio_data(struct snd_ice1712 *ice) { unsigned int data; - if (! ice->vt1720) + if (!ice->vt1720) data = (unsigned int)inb(ICEREG1724(ice, GPIO_DATA_22)); else data = 0; @@ -399,7 +399,7 @@ static irqreturn_t snd_vt1724_interrupt(int irq, void *dev_id) break; } #endif - handled = 1; + handled = 1; if (status & VT1724_IRQ_MPU_TX) { spin_lock(&ice->reg_lock); if (ice->midi_output) @@ -468,8 +468,8 @@ static irqreturn_t snd_vt1724_interrupt(int irq, void *dev_id) /* ought to really handle this properly */ if (mtstat & VT1724_MULTI_FIFO_ERR) { unsigned char fstat = inb(ICEMT1724(ice, DMA_FIFO_ERR)); - outb(fstat, ICEMT1724(ice, DMA_FIFO_ERR)); - outb(VT1724_MULTI_FIFO_ERR | inb(ICEMT1724(ice, DMA_INT_MASK)), ICEMT1724(ice, DMA_INT_MASK)); + outb(fstat, ICEMT1724(ice, DMA_FIFO_ERR)); + outb(VT1724_MULTI_FIFO_ERR | inb(ICEMT1724(ice, DMA_INT_MASK)), ICEMT1724(ice, DMA_INT_MASK)); /* If I don't do this, I get machine lockup due to continual interrupts */ } @@ -733,17 +733,17 @@ static int snd_vt1724_playback_pro_prepare(struct snd_pcm_substream *substream) outl(substream->runtime->dma_addr, ICEMT1724(ice, PLAYBACK_ADDR)); size = (snd_pcm_lib_buffer_bytes(substream) >> 2) - 1; - // outl(size, ICEMT1724(ice, PLAYBACK_SIZE)); + /* outl(size, ICEMT1724(ice, PLAYBACK_SIZE)); */ outw(size, ICEMT1724(ice, PLAYBACK_SIZE)); outb(size >> 16, ICEMT1724(ice, PLAYBACK_SIZE) + 2); size = (snd_pcm_lib_period_bytes(substream) >> 2) - 1; - // outl(size, ICEMT1724(ice, PLAYBACK_COUNT)); + /* outl(size, ICEMT1724(ice, PLAYBACK_COUNT)); */ outw(size, ICEMT1724(ice, PLAYBACK_COUNT)); outb(size >> 16, ICEMT1724(ice, PLAYBACK_COUNT) + 2); spin_unlock_irq(&ice->reg_lock); - // printk("pro prepare: ch = %d, addr = 0x%x, buffer = 0x%x, period = 0x%x\n", substream->runtime->channels, (unsigned int)substream->runtime->dma_addr, snd_pcm_lib_buffer_bytes(substream), snd_pcm_lib_period_bytes(substream)); + /* printk("pro prepare: ch = %d, addr = 0x%x, buffer = 0x%x, period = 0x%x\n", substream->runtime->channels, (unsigned int)substream->runtime->dma_addr, snd_pcm_lib_buffer_bytes(substream), snd_pcm_lib_period_bytes(substream)); */ return 0; } @@ -771,7 +771,7 @@ static snd_pcm_uframes_t snd_vt1724_playback_pro_pointer(struct snd_pcm_substrea ptr = inl(ICEMT1724(ice, PLAYBACK_SIZE)) & 0xffffff; ptr = (ptr + 1) << 2; ptr = bytes_to_frames(substream->runtime, ptr); - if (! ptr) + if (!ptr) ; else if (ptr <= substream->runtime->buffer_size) ptr = substream->runtime->buffer_size - ptr; @@ -815,7 +815,7 @@ static snd_pcm_uframes_t snd_vt1724_pcm_pointer(struct snd_pcm_substream *substr ptr = inw(ice->profi_port + reg->size); ptr = (ptr + 1) << 2; ptr = bytes_to_frames(substream->runtime, ptr); - if (! ptr) + if (!ptr) ; else if (ptr <= substream->runtime->buffer_size) ptr = substream->runtime->buffer_size - ptr; @@ -842,8 +842,7 @@ static const struct vt1724_pcm_reg vt1724_capture_pro_reg = { .start = VT1724_RDMA0_START, }; -static const struct snd_pcm_hardware snd_vt1724_playback_pro = -{ +static const struct snd_pcm_hardware snd_vt1724_playback_pro = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID | @@ -861,8 +860,7 @@ static const struct snd_pcm_hardware snd_vt1724_playback_pro = .periods_max = 1024, }; -static const struct snd_pcm_hardware snd_vt1724_spdif = -{ +static const struct snd_pcm_hardware snd_vt1724_spdif = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID | @@ -883,8 +881,7 @@ static const struct snd_pcm_hardware snd_vt1724_spdif = .periods_max = 1024, }; -static const struct snd_pcm_hardware snd_vt1724_2ch_stereo = -{ +static const struct snd_pcm_hardware snd_vt1724_2ch_stereo = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID | @@ -1030,7 +1027,7 @@ static struct snd_pcm_ops snd_vt1724_capture_pro_ops = { .pointer = snd_vt1724_pcm_pointer, }; -static int __devinit snd_vt1724_pcm_profi(struct snd_ice1712 * ice, int device) +static int __devinit snd_vt1724_pcm_profi(struct snd_ice1712 *ice, int device) { struct snd_pcm *pcm; int err; @@ -1115,7 +1112,7 @@ static void update_spdif_rate(struct snd_ice1712 *ice, unsigned int rate) static int snd_vt1724_playback_spdif_prepare(struct snd_pcm_substream *substream) { struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); - if (! ice->force_pdma4) + if (!ice->force_pdma4) update_spdif_rate(ice, substream->runtime->rate); return snd_vt1724_pcm_prepare(substream); } @@ -1215,7 +1212,7 @@ static struct snd_pcm_ops snd_vt1724_capture_spdif_ops = { }; -static int __devinit snd_vt1724_pcm_spdif(struct snd_ice1712 * ice, int device) +static int __devinit snd_vt1724_pcm_spdif(struct snd_ice1712 *ice, int device) { char *name; struct snd_pcm *pcm; @@ -1234,7 +1231,7 @@ static int __devinit snd_vt1724_pcm_spdif(struct snd_ice1712 * ice, int device) ice->has_spdif = 1; } else capt = 0; - if (! play && ! capt) + if (!play && !capt) return 0; /* no spdif device */ if (ice->force_pdma4 || ice->force_rdma1) @@ -1349,7 +1346,7 @@ static struct snd_pcm_ops snd_vt1724_playback_indep_ops = { }; -static int __devinit snd_vt1724_pcm_indep(struct snd_ice1712 * ice, int device) +static int __devinit snd_vt1724_pcm_indep(struct snd_ice1712 *ice, int device) { struct snd_pcm *pcm; int play; @@ -1384,11 +1381,11 @@ static int __devinit snd_vt1724_pcm_indep(struct snd_ice1712 * ice, int device) * Mixer section */ -static int __devinit snd_vt1724_ac97_mixer(struct snd_ice1712 * ice) +static int __devinit snd_vt1724_ac97_mixer(struct snd_ice1712 *ice) { int err; - if (! (ice->eeprom.data[ICE_EEP2_ACLINK] & VT1724_CFG_PRO_I2S)) { + if (!(ice->eeprom.data[ICE_EEP2_ACLINK] & VT1724_CFG_PRO_I2S)) { struct snd_ac97_bus *pbus; struct snd_ac97_template ac97; static struct snd_ac97_bus_ops ops = { @@ -1401,11 +1398,13 @@ static int __devinit snd_vt1724_ac97_mixer(struct snd_ice1712 * ice) mdelay(5); /* FIXME */ outb(inb(ICEMT1724(ice, AC97_CMD)) & ~0x80, ICEMT1724(ice, AC97_CMD)); - if ((err = snd_ac97_bus(ice->card, 0, &ops, NULL, &pbus)) < 0) + err = snd_ac97_bus(ice->card, 0, &ops, NULL, &pbus); + if (err < 0) return err; memset(&ac97, 0, sizeof(ac97)); ac97.private_data = ice; - if ((err = snd_ac97_mixer(pbus, &ac97, &ice->ac97)) < 0) + err = snd_ac97_mixer(pbus, &ac97, &ice->ac97); + if (err < 0) printk(KERN_WARNING "ice1712: cannot initialize pro ac97, skipped\n"); else return 0; @@ -1426,7 +1425,7 @@ static inline unsigned int eeprom_triple(struct snd_ice1712 *ice, int idx) ((unsigned int)ice->eeprom.data[idx + 2] << 16); } -static void snd_vt1724_proc_read(struct snd_info_entry *entry, +static void snd_vt1724_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) { struct snd_ice1712 *ice = entry->private_data; @@ -1468,11 +1467,11 @@ static void snd_vt1724_proc_read(struct snd_info_entry *entry, idx, inb(ice->profi_port+idx)); } -static void __devinit snd_vt1724_proc_init(struct snd_ice1712 * ice) +static void __devinit snd_vt1724_proc_init(struct snd_ice1712 *ice) { struct snd_info_entry *entry; - if (! snd_card_proc_new(ice->card, "ice1724", &entry)) + if (!snd_card_proc_new(ice->card, "ice1724", &entry)) snd_info_set_text_ops(entry, ice, snd_vt1724_proc_read); } @@ -1492,7 +1491,7 @@ static int snd_vt1724_eeprom_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - + memcpy(ucontrol->value.bytes.data, &ice->eeprom, sizeof(ice->eeprom)); return 0; } @@ -1607,13 +1606,13 @@ static int snd_vt1724_spdif_default_put(struct snd_kcontrol *kcontrol, if (val != old) update_spdif_bits(ice, val); spin_unlock_irq(&ice->reg_lock); - return (val != old); + return val != old; } static struct snd_kcontrol_new snd_vt1724_spdif_default __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), + .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT), .info = snd_vt1724_spdif_info, .get = snd_vt1724_spdif_default_get, .put = snd_vt1724_spdif_default_put @@ -1646,7 +1645,7 @@ static struct snd_kcontrol_new snd_vt1724_spdif_maskc __devinitdata = { .access = SNDRV_CTL_ELEM_ACCESS_READ, .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK), + .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, CON_MASK), .info = snd_vt1724_spdif_info, .get = snd_vt1724_spdif_maskc_get, }; @@ -1655,7 +1654,7 @@ static struct snd_kcontrol_new snd_vt1724_spdif_maskp __devinitdata = { .access = SNDRV_CTL_ELEM_ACCESS_READ, .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK), + .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PRO_MASK), .info = snd_vt1724_spdif_info, .get = snd_vt1724_spdif_maskp_get, }; @@ -1692,8 +1691,8 @@ static struct snd_kcontrol_new snd_vt1724_spdif_switch __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, /* FIXME: the following conflict with IEC958 Playback Route */ - // .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH), - .name = SNDRV_CTL_NAME_IEC958("Output ",NONE,SWITCH), + /* .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, SWITCH), */ + .name = SNDRV_CTL_NAME_IEC958("Output ", NONE, SWITCH), .info = snd_vt1724_spdif_sw_info, .get = snd_vt1724_spdif_sw_get, .put = snd_vt1724_spdif_sw_put @@ -1713,7 +1712,7 @@ int snd_vt1724_gpio_get(struct snd_kcontrol *kcontrol, struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); int shift = kcontrol->private_value & 0xff; int invert = (kcontrol->private_value & (1<<24)) ? 1 : 0; - + snd_ice1712_save_gpio_status(ice); ucontrol->value.integer.value[0] = (snd_ice1712_gpio_read(ice) & (1 << shift) ? 1 : 0) ^ invert; @@ -1768,7 +1767,7 @@ static int snd_vt1724_pro_internal_clock_get(struct snd_kcontrol *kcontrol, { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); unsigned int i, rate; - + spin_lock_irq(&ice->reg_lock); if (ice->is_spdif_master(ice)) { ucontrol->value.enumerated.item[0] = ice->hw_rates->count; @@ -1924,7 +1923,7 @@ static int snd_vt1724_pro_route_info(struct snd_kcontrol *kcontrol, "H/W In 0", "H/W In 1", /* 1-2 */ "IEC958 In L", "IEC958 In R", /* 3-4 */ }; - + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->count = 1; uinfo->value.enumerated.items = 5; @@ -1954,7 +1953,7 @@ static int get_route_val(struct snd_ice1712 *ice, int shift) val = inl(ICEMT1724(ice, ROUTE_PLAYBACK)); val >>= shift; - val &= 7; //we now have 3 bits per output + val &= 7; /* we now have 3 bits per output */ eitem = xlate[val]; if (eitem == 255) { snd_BUG(); @@ -2033,7 +2032,7 @@ static struct snd_kcontrol_new snd_vt1724_mixer_pro_analog_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", + .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, NONE) "Route", .info = snd_vt1724_pro_route_info, .get = snd_vt1724_pro_route_spdif_get, .put = snd_vt1724_pro_route_spdif_put, @@ -2056,7 +2055,7 @@ static int snd_vt1724_pro_peak_get(struct snd_kcontrol *kcontrol, { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); int idx; - + spin_lock_irq(&ice->reg_lock); for (idx = 0; idx < 22; idx++) { outb(idx, ICEMT1724(ice, MONITOR_PEAKINDEX)); @@ -2083,7 +2082,7 @@ static struct snd_ice1712_card_info no_matched __devinitdata; static struct snd_ice1712_card_info *card_tables[] __devinitdata = { snd_vt1724_revo_cards, - snd_vt1724_amp_cards, + snd_vt1724_amp_cards, snd_vt1724_aureon_cards, snd_vt1720_mobo_cards, snd_vt1720_pontis_cards, @@ -2121,7 +2120,7 @@ unsigned char snd_vt1724_read_i2c(struct snd_ice1712 *ice, wait_i2c_busy(ice); val = inb(ICEREG1724(ice, I2C_DATA)); mutex_unlock(&ice->i2c_mutex); - //printk("i2c_read: [0x%x,0x%x] = 0x%x\n", dev, addr, val); + /* printk("i2c_read: [0x%x,0x%x] = 0x%x\n", dev, addr, val); */ return val; } @@ -2130,7 +2129,7 @@ void snd_vt1724_write_i2c(struct snd_ice1712 *ice, { mutex_lock(&ice->i2c_mutex); wait_i2c_busy(ice); - //printk("i2c_write: [0x%x,0x%x] = 0x%x\n", dev, addr, data); + /* printk("i2c_write: [0x%x,0x%x] = 0x%x\n", dev, addr, data); */ outb(addr, ICEREG1724(ice, I2C_BYTE_ADDR)); outb(data, ICEREG1724(ice, I2C_DATA)); outb(dev | VT1724_I2C_WRITE, ICEREG1724(ice, I2C_DEV_ADDR)); @@ -2145,13 +2144,13 @@ static int __devinit snd_vt1724_read_eeprom(struct snd_ice1712 *ice, unsigned int i, size; struct snd_ice1712_card_info * const *tbl, *c; - if (! modelname || ! *modelname) { + if (!modelname || !*modelname) { ice->eeprom.subvendor = 0; if ((inb(ICEREG1724(ice, I2C_CTRL)) & VT1724_I2C_EEPROM) != 0) ice->eeprom.subvendor = (snd_vt1724_read_i2c(ice, dev, 0x00) << 0) | - (snd_vt1724_read_i2c(ice, dev, 0x01) << 8) | - (snd_vt1724_read_i2c(ice, dev, 0x02) << 16) | + (snd_vt1724_read_i2c(ice, dev, 0x01) << 8) | + (snd_vt1724_read_i2c(ice, dev, 0x02) << 16) | (snd_vt1724_read_i2c(ice, dev, 0x03) << 24); if (ice->eeprom.subvendor == 0 || ice->eeprom.subvendor == (unsigned int)-1) { @@ -2174,13 +2173,13 @@ static int __devinit snd_vt1724_read_eeprom(struct snd_ice1712 *ice, for (tbl = card_tables; *tbl; tbl++) { for (c = *tbl; c->subvendor; c++) { if (modelname && c->model && - ! strcmp(modelname, c->model)) { + !strcmp(modelname, c->model)) { printk(KERN_INFO "ice1724: Using board model %s\n", c->name); ice->eeprom.subvendor = c->subvendor; } else if (c->subvendor != ice->eeprom.subvendor) continue; - if (! c->eeprom_size || ! c->eeprom_data) + if (!c->eeprom_size || !c->eeprom_data) goto found; /* if the EEPROM is given by the driver, use it */ snd_printdd("using the defined eeprom..\n"); @@ -2322,13 +2321,13 @@ static int __devinit snd_vt1724_build_controls(struct snd_ice1712 *ice) static int snd_vt1724_free(struct snd_ice1712 *ice) { - if (! ice->port) + if (!ice->port) goto __hw_end; /* mask all interrupts */ outb(0xff, ICEMT1724(ice, DMA_INT_MASK)); outb(0xff, ICEREG1724(ice, IRQMASK)); /* --- */ - __hw_end: +__hw_end: if (ice->irq >= 0) free_irq(ice->irq, ice); pci_release_regions(ice->pci); @@ -2348,7 +2347,7 @@ static int snd_vt1724_dev_free(struct snd_device *device) static int __devinit snd_vt1724_create(struct snd_card *card, struct pci_dev *pci, const char *modelname, - struct snd_ice1712 ** r_ice1712) + struct snd_ice1712 **r_ice1712) { struct snd_ice1712 *ice; int err; @@ -2359,8 +2358,9 @@ static int __devinit snd_vt1724_create(struct snd_card *card, *r_ice1712 = NULL; - /* enable PCI device */ - if ((err = pci_enable_device(pci)) < 0) + /* enable PCI device */ + err = pci_enable_device(pci); + if (err < 0) return err; ice = kzalloc(sizeof(*ice), GFP_KERNEL); @@ -2384,7 +2384,8 @@ static int __devinit snd_vt1724_create(struct snd_card *card, snd_vt1724_proc_init(ice); synchronize_irq(pci->irq); - if ((err = pci_request_regions(pci, "ICE1724")) < 0) { + err = pci_request_regions(pci, "ICE1724"); + if (err < 0) { kfree(ice); pci_disable_device(pci); return err; @@ -2419,9 +2420,10 @@ static int __devinit snd_vt1724_create(struct snd_card *card, */ outb(VT1724_MULTI_FIFO_ERR, ICEMT1724(ice, DMA_INT_MASK)); - if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ice, &ops)) < 0) { + err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ice, &ops); + if (err < 0) { snd_vt1724_free(ice); - return err; + return err; } snd_card_set_dev(card, &pci->dev); @@ -2459,8 +2461,9 @@ static int __devinit snd_vt1724_probe(struct pci_dev *pci, strcpy(card->driver, "ICE1724"); strcpy(card->shortname, "ICEnsemble ICE1724"); - - if ((err = snd_vt1724_create(card, pci, model[dev], &ice)) < 0) { + + err = snd_vt1724_create(card, pci, model[dev], &ice); + if (err < 0) { snd_card_free(card); return err; } @@ -2472,7 +2475,8 @@ static int __devinit snd_vt1724_probe(struct pci_dev *pci, if (c->driver) /* specific driver? */ strcpy(card->driver, c->driver); if (c->chip_init) { - if ((err = c->chip_init(ice)) < 0) { + err = c->chip_init(ice); + if (err < 0) { snd_card_free(card); return err; } @@ -2482,15 +2486,15 @@ 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. - */ +__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. + */ ice->pro_rate_default = PRO_RATE_DEFAULT; if (!ice->is_spdif_master) ice->is_spdif_master = stdclock_is_spdif_master; @@ -2505,46 +2509,53 @@ static int __devinit snd_vt1724_probe(struct pci_dev *pci, if (!ice->hw_rates) set_std_hw_rates(ice); - if ((err = snd_vt1724_pcm_profi(ice, pcm_dev++)) < 0) { + err = snd_vt1724_pcm_profi(ice, pcm_dev++); + if (err < 0) { snd_card_free(card); return err; } - - if ((err = snd_vt1724_pcm_spdif(ice, pcm_dev++)) < 0) { + + err = snd_vt1724_pcm_spdif(ice, pcm_dev++); + if (err < 0) { snd_card_free(card); return err; } - - if ((err = snd_vt1724_pcm_indep(ice, pcm_dev++)) < 0) { + + err = snd_vt1724_pcm_indep(ice, pcm_dev++); + if (err < 0) { snd_card_free(card); return err; } - if ((err = snd_vt1724_ac97_mixer(ice)) < 0) { + err = snd_vt1724_ac97_mixer(ice); + if (err < 0) { snd_card_free(card); return err; } - if ((err = snd_vt1724_build_controls(ice)) < 0) { + err = snd_vt1724_build_controls(ice); + if (err < 0) { snd_card_free(card); return err; } if (ice->pcm && ice->has_spdif) { /* has SPDIF I/O */ - if ((err = snd_vt1724_spdif_build_controls(ice)) < 0) { + err = snd_vt1724_spdif_build_controls(ice); + if (err < 0) { snd_card_free(card); return err; } } if (c->build_controls) { - if ((err = c->build_controls(ice)) < 0) { + err = c->build_controls(ice); + if (err < 0) { snd_card_free(card); return err; } } - if (! c->no_mpu401) { + if (!c->no_mpu401) { if (ice->eeprom.data[ICE_EEP2_SYSCONF] & VT1724_CFG_MPU401) { struct snd_rawmidi *rmidi; @@ -2576,7 +2587,8 @@ static int __devinit snd_vt1724_probe(struct pci_dev *pci, sprintf(card->longname, "%s at 0x%lx, irq %i", card->shortname, ice->port, ice->irq); - if ((err = snd_card_register(card)) < 0) { + err = snd_card_register(card); + if (err < 0) { snd_card_free(card); return err; } -- cgit v1.2.3 From 3d8cb466a885cb5a0fb53ef3d39c36432d67fcbb Mon Sep 17 00:00:00 2001 From: Alexander Beregalov Date: Sun, 7 Sep 2008 14:17:02 +0400 Subject: ALSA: ice1712.c: fix coding style before: total: 113 errors, 169 warnings, 2786 lines checked total: 26 errors, 24 warnings, 504 lines checked after: total: 14 errors, 163 warnings, 2799 lines checked total: 0 errors, 24 warnings, 504 lines checked Compile tested only. Signed-off-by: Alexander Beregalov Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/ice1712/ice1712.c | 237 +++++++++++++++++++++++--------------------- sound/pci/ice1712/ice1712.h | 52 +++++----- 2 files changed, 151 insertions(+), 138 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/ice1712/ice1712.c b/sound/pci/ice1712/ice1712.c index 05ffab65d16..5b442383fcd 100644 --- a/sound/pci/ice1712/ice1712.c +++ b/sound/pci/ice1712/ice1712.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - */ + */ /* NOTES: @@ -35,7 +35,7 @@ * * 2002.11.26 James Stafford * Added support for VT1724 (Envy24HT) - * I have left out support for 176.4 and 192 KHz for the moment. + * I have left out support for 176.4 and 192 KHz for the moment. * I also haven't done anything with the internal S/PDIF transmitter or the MPU-401 * * 2003.02.20 Taksahi Iwai @@ -47,7 +47,7 @@ */ -#include +#include #include #include #include @@ -123,7 +123,7 @@ static unsigned int PRO_RATE_DEFAULT = 44100; /* * Basic I/O */ - + /* check whether the clock mode is spdif-in */ static inline int is_spdif_master(struct snd_ice1712 *ice) { @@ -135,13 +135,13 @@ static inline int is_pro_rate_locked(struct snd_ice1712 *ice) return is_spdif_master(ice) || PRO_RATE_LOCKED; } -static inline void snd_ice1712_ds_write(struct snd_ice1712 * ice, u8 channel, u8 addr, u32 data) +static inline void snd_ice1712_ds_write(struct snd_ice1712 *ice, u8 channel, u8 addr, u32 data) { outb((channel << 4) | addr, ICEDS(ice, INDEX)); outl(data, ICEDS(ice, DATA)); } -static inline u32 snd_ice1712_ds_read(struct snd_ice1712 * ice, u8 channel, u8 addr) +static inline u32 snd_ice1712_ds_read(struct snd_ice1712 *ice, u8 channel, u8 addr) { outb((channel << 4) | addr, ICEDS(ice, INDEX)); return inl(ICEDS(ice, DATA)); @@ -260,7 +260,7 @@ static unsigned short snd_ice1712_pro_ac97_read(struct snd_ac97 *ac97, static int snd_ice1712_digmix_route_ac97_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - + ucontrol->value.integer.value[0] = inb(ICEMT(ice, MONITOR_ROUTECTRL)) & ICE1712_ROUTE_AC97 ? 1 : 0; return 0; } @@ -269,11 +269,12 @@ static int snd_ice1712_digmix_route_ac97_put(struct snd_kcontrol *kcontrol, stru { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); unsigned char val, nval; - + spin_lock_irq(&ice->reg_lock); val = inb(ICEMT(ice, MONITOR_ROUTECTRL)); nval = val & ~ICE1712_ROUTE_AC97; - if (ucontrol->value.integer.value[0]) nval |= ICE1712_ROUTE_AC97; + if (ucontrol->value.integer.value[0]) + nval |= ICE1712_ROUTE_AC97; outb(nval, ICEMT(ice, MONITOR_ROUTECTRL)); spin_unlock_irq(&ice->reg_lock); return val != nval; @@ -329,7 +330,7 @@ static int snd_ice1712_cs8427_set_input_clock(struct snd_ice1712 *ice, int spdif unsigned char reg[2] = { 0x80 | 4, 0 }; /* CS8427 auto increment | register number 4 + data */ unsigned char val, nval; int res = 0; - + snd_i2c_lock(ice->i2c); if (snd_i2c_sendbytes(ice->cs8427, reg, 1) != 1) { snd_i2c_unlock(ice->i2c); @@ -381,9 +382,9 @@ int __devinit snd_ice1712_init_cs8427(struct snd_ice1712 *ice, int addr) { int err; - if ((err = snd_cs8427_create(ice->i2c, addr, - (ice->cs8427_timeout * HZ) / 1000, - &ice->cs8427)) < 0) { + err = snd_cs8427_create(ice->i2c, addr, + (ice->cs8427_timeout * HZ) / 1000, &ice->cs8427); + if (err < 0) { snd_printk(KERN_ERR "CS8427 initialization failed\n"); return err; } @@ -395,9 +396,9 @@ int __devinit snd_ice1712_init_cs8427(struct snd_ice1712 *ice, int addr) static void snd_ice1712_set_input_clock_source(struct snd_ice1712 *ice, int spdif_is_master) { - /* change CS8427 clock source too */ - if (ice->cs8427) - snd_ice1712_cs8427_set_input_clock(ice, spdif_is_master); + /* change CS8427 clock source too */ + if (ice->cs8427) + snd_ice1712_cs8427_set_input_clock(ice, spdif_is_master); /* notify ak4524 chip as well */ if (spdif_is_master) { unsigned int i; @@ -457,11 +458,12 @@ static irqreturn_t snd_ice1712_interrupt(int irq, void *dev_id) u16 pbkstatus; struct snd_pcm_substream *substream; pbkstatus = inw(ICEDS(ice, INTSTAT)); - //printk("pbkstatus = 0x%x\n", pbkstatus); + /* printk("pbkstatus = 0x%x\n", pbkstatus); */ for (idx = 0; idx < 6; idx++) { if ((pbkstatus & (3 << (idx * 2))) == 0) continue; - if ((substream = ice->playback_con_substream_ds[idx]) != NULL) + substream = ice->playback_con_substream_ds[idx]; + if (substream != NULL) snd_pcm_period_elapsed(substream); outw(3 << (idx * 2), ICEDS(ice, INTSTAT)); } @@ -507,7 +509,7 @@ static int snd_ice1712_playback_trigger(struct snd_pcm_substream *substream, struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); int result = 0; u32 tmp; - + spin_lock(&ice->reg_lock); tmp = snd_ice1712_read(ice, ICE1712_IREG_PBK_CTRL); if (cmd == SNDRV_PCM_TRIGGER_START) { @@ -532,7 +534,7 @@ static int snd_ice1712_playback_ds_trigger(struct snd_pcm_substream *substream, struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); int result = 0; u32 tmp; - + spin_lock(&ice->reg_lock); tmp = snd_ice1712_ds_read(ice, substream->number * 2, ICE1712_DSC_CONTROL); if (cmd == SNDRV_PCM_TRIGGER_START) { @@ -557,7 +559,7 @@ static int snd_ice1712_capture_trigger(struct snd_pcm_substream *substream, struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); int result = 0; u8 tmp; - + spin_lock(&ice->reg_lock); tmp = snd_ice1712_read(ice, ICE1712_IREG_CAP_CTRL); if (cmd == SNDRV_PCM_TRIGGER_START) { @@ -711,8 +713,7 @@ static snd_pcm_uframes_t snd_ice1712_capture_pointer(struct snd_pcm_substream *s return bytes_to_frames(substream->runtime, ptr); } -static const struct snd_pcm_hardware snd_ice1712_playback = -{ +static const struct snd_pcm_hardware snd_ice1712_playback = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID | @@ -731,8 +732,7 @@ static const struct snd_pcm_hardware snd_ice1712_playback = .fifo_size = 0, }; -static const struct snd_pcm_hardware snd_ice1712_playback_ds = -{ +static const struct snd_pcm_hardware snd_ice1712_playback_ds = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID | @@ -751,8 +751,7 @@ static const struct snd_pcm_hardware snd_ice1712_playback_ds = .fifo_size = 0, }; -static const struct snd_pcm_hardware snd_ice1712_capture = -{ +static const struct snd_pcm_hardware snd_ice1712_capture = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID), @@ -788,7 +787,7 @@ static int snd_ice1712_playback_ds_open(struct snd_pcm_substream *substream) ice->playback_con_substream_ds[substream->number] = substream; runtime->hw = snd_ice1712_playback_ds; - spin_lock_irq(&ice->reg_lock); + spin_lock_irq(&ice->reg_lock); tmp = inw(ICEDS(ice, INTMASK)) & ~(1 << (substream->number * 2)); outw(tmp, ICEDS(ice, INTMASK)); spin_unlock_irq(&ice->reg_lock); @@ -821,7 +820,7 @@ static int snd_ice1712_playback_ds_close(struct snd_pcm_substream *substream) struct snd_ice1712 *ice = snd_pcm_substream_chip(substream); u32 tmp; - spin_lock_irq(&ice->reg_lock); + spin_lock_irq(&ice->reg_lock); tmp = inw(ICEDS(ice, INTMASK)) | (3 << (substream->number * 2)); outw(tmp, ICEDS(ice, INTMASK)); spin_unlock_irq(&ice->reg_lock); @@ -870,7 +869,7 @@ static struct snd_pcm_ops snd_ice1712_capture_ops = { .pointer = snd_ice1712_capture_pointer, }; -static int __devinit snd_ice1712_pcm(struct snd_ice1712 * ice, int device, struct snd_pcm ** rpcm) +static int __devinit snd_ice1712_pcm(struct snd_ice1712 *ice, int device, struct snd_pcm **rpcm) { struct snd_pcm *pcm; int err; @@ -900,7 +899,7 @@ static int __devinit snd_ice1712_pcm(struct snd_ice1712 * ice, int device, struc return 0; } -static int __devinit snd_ice1712_pcm_ds(struct snd_ice1712 * ice, int device, struct snd_pcm ** rpcm) +static int __devinit snd_ice1712_pcm_ds(struct snd_ice1712 *ice, int device, struct snd_pcm **rpcm) { struct snd_pcm *pcm; int err; @@ -1029,14 +1028,14 @@ static void snd_ice1712_set_pro_rate(struct snd_ice1712 *ice, unsigned int rate, if (inb(ICEMT(ice, PLAYBACK_CONTROL)) & (ICE1712_CAPTURE_START_SHADOW| ICE1712_PLAYBACK_PAUSE| ICE1712_PLAYBACK_START)) { - __out: +__out: spin_unlock_irqrestore(&ice->reg_lock, flags); return; } if (!force && is_pro_rate_locked(ice)) goto __out; - old = inb(ICEMT(ice, RATE)); + old = inb(ICEMT(ice, RATE)); if (!force && old == val) goto __out; outb(val, ICEMT(ice, RATE)); @@ -1123,8 +1122,7 @@ static snd_pcm_uframes_t snd_ice1712_capture_pro_pointer(struct snd_pcm_substrea return bytes_to_frames(substream->runtime, ptr); } -static const struct snd_pcm_hardware snd_ice1712_playback_pro = -{ +static const struct snd_pcm_hardware snd_ice1712_playback_pro = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID | @@ -1143,8 +1141,7 @@ static const struct snd_pcm_hardware snd_ice1712_playback_pro = .fifo_size = 0, }; -static const struct snd_pcm_hardware snd_ice1712_capture_pro = -{ +static const struct snd_pcm_hardware snd_ice1712_capture_pro = { .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID | @@ -1238,7 +1235,7 @@ static struct snd_pcm_ops snd_ice1712_capture_pro_ops = { .pointer = snd_ice1712_capture_pro_pointer, }; -static int __devinit snd_ice1712_pcm_profi(struct snd_ice1712 * ice, int device, struct snd_pcm ** rpcm) +static int __devinit snd_ice1712_pcm_profi(struct snd_ice1712 *ice, int device, struct snd_pcm **rpcm) { struct snd_pcm *pcm; int err; @@ -1262,7 +1259,7 @@ static int __devinit snd_ice1712_pcm_profi(struct snd_ice1712 * ice, int device, ice->pcm_pro = pcm; if (rpcm) *rpcm = pcm; - + if (ice->cs8427) { /* assign channels to iec958 */ err = snd_cs8427_iec958_build(ice->cs8427, @@ -1272,7 +1269,8 @@ static int __devinit snd_ice1712_pcm_profi(struct snd_ice1712 * ice, int device, return err; } - if ((err = snd_ice1712_build_pro_mixer(ice)) < 0) + err = snd_ice1712_build_pro_mixer(ice); + if (err < 0) return err; return 0; } @@ -1299,7 +1297,7 @@ static int snd_ice1712_pro_mixer_switch_get(struct snd_kcontrol *kcontrol, struc struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); int priv_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + kcontrol->private_value; - + spin_lock_irq(&ice->reg_lock); ucontrol->value.integer.value[0] = !((ice->pro_volumes[priv_idx] >> 15) & 1); @@ -1341,7 +1339,7 @@ static int snd_ice1712_pro_mixer_volume_get(struct snd_kcontrol *kcontrol, struc struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); int priv_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + kcontrol->private_value; - + spin_lock_irq(&ice->reg_lock); ucontrol->value.integer.value[0] = (ice->pro_volumes[priv_idx] >> 0) & 127; @@ -1406,7 +1404,7 @@ static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_switch __devinit 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), + .name = SNDRV_CTL_NAME_IEC958("Multi ", CAPTURE, SWITCH), .info = snd_ice1712_pro_mixer_switch_info, .get = snd_ice1712_pro_mixer_switch_get, .put = snd_ice1712_pro_mixer_switch_put, @@ -1428,7 +1426,7 @@ static struct snd_kcontrol_new snd_ice1712_multi_capture_analog_volume __devinit 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), + .name = SNDRV_CTL_NAME_IEC958("Multi ", CAPTURE, VOLUME), .info = snd_ice1712_pro_mixer_volume_info, .get = snd_ice1712_pro_mixer_volume_get, .put = snd_ice1712_pro_mixer_volume_put, @@ -1448,7 +1446,7 @@ static int __devinit snd_ice1712_build_pro_mixer(struct snd_ice1712 *ice) if (err < 0) return err; } - + if (ice->num_total_adcs > 0) { struct snd_kcontrol_new tmp = snd_ice1712_multi_capture_analog_switch; tmp.count = ice->num_total_adcs; @@ -1495,7 +1493,7 @@ static void snd_ice1712_mixer_free_ac97(struct snd_ac97 *ac97) ice->ac97 = NULL; } -static int __devinit snd_ice1712_ac97_mixer(struct snd_ice1712 * ice) +static int __devinit snd_ice1712_ac97_mixer(struct snd_ice1712 *ice) { int err, bus_num = 0; struct snd_ac97_template ac97; @@ -1510,27 +1508,32 @@ static int __devinit snd_ice1712_ac97_mixer(struct snd_ice1712 * ice) }; if (ice_has_con_ac97(ice)) { - if ((err = snd_ac97_bus(ice->card, bus_num++, &con_ops, NULL, &pbus)) < 0) + err = snd_ac97_bus(ice->card, bus_num++, &con_ops, NULL, &pbus); + if (err < 0) return err; memset(&ac97, 0, sizeof(ac97)); ac97.private_data = ice; ac97.private_free = snd_ice1712_mixer_free_ac97; - if ((err = snd_ac97_mixer(pbus, &ac97, &ice->ac97)) < 0) + err = snd_ac97_mixer(pbus, &ac97, &ice->ac97); + if (err < 0) printk(KERN_WARNING "ice1712: cannot initialize ac97 for consumer, skipped\n"); else { - if ((err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_mixer_digmix_route_ac97, ice))) < 0) + err = snd_ctl_add(ice->card, snd_ctl_new1(&snd_ice1712_mixer_digmix_route_ac97, ice)); + if (err < 0) return err; return 0; } } - if (! (ice->eeprom.data[ICE_EEP1_ACLINK] & ICE1712_CFG_PRO_I2S)) { - if ((err = snd_ac97_bus(ice->card, bus_num, &pro_ops, NULL, &pbus)) < 0) + if (!(ice->eeprom.data[ICE_EEP1_ACLINK] & ICE1712_CFG_PRO_I2S)) { + err = snd_ac97_bus(ice->card, bus_num, &pro_ops, NULL, &pbus); + if (err < 0) return err; memset(&ac97, 0, sizeof(ac97)); ac97.private_data = ice; ac97.private_free = snd_ice1712_mixer_free_ac97; - if ((err = snd_ac97_mixer(pbus, &ac97, &ice->ac97)) < 0) + err = snd_ac97_mixer(pbus, &ac97, &ice->ac97); + if (err < 0) printk(KERN_WARNING "ice1712: cannot initialize pro ac97, skipped\n"); else return 0; @@ -1549,7 +1552,7 @@ static inline unsigned int eeprom_double(struct snd_ice1712 *ice, int idx) return (unsigned int)ice->eeprom.data[idx] | ((unsigned int)ice->eeprom.data[idx + 1] << 8); } -static void snd_ice1712_proc_read(struct snd_info_entry *entry, +static void snd_ice1712_proc_read(struct snd_info_entry *entry, struct snd_info_buffer *buffer) { struct snd_ice1712 *ice = entry->private_data; @@ -1585,15 +1588,15 @@ static void snd_ice1712_proc_read(struct snd_info_entry *entry, snd_iprintf(buffer, " SPDOUT : 0x%04x\n", (unsigned)inw(ICEMT(ice, ROUTE_SPDOUT))); snd_iprintf(buffer, " RATE : 0x%02x\n", (unsigned)inb(ICEMT(ice, RATE))); snd_iprintf(buffer, " GPIO_DATA : 0x%02x\n", (unsigned)snd_ice1712_get_gpio_data(ice)); - snd_iprintf(buffer, " GPIO_WRITE_MASK : 0x%02x\n", (unsigned)snd_ice1712_read(ice, ICE1712_IREG_GPIO_WRITE_MASK)); + snd_iprintf(buffer, " GPIO_WRITE_MASK : 0x%02x\n", (unsigned)snd_ice1712_read(ice, ICE1712_IREG_GPIO_WRITE_MASK)); snd_iprintf(buffer, " GPIO_DIRECTION : 0x%02x\n", (unsigned)snd_ice1712_read(ice, ICE1712_IREG_GPIO_DIRECTION)); } -static void __devinit snd_ice1712_proc_init(struct snd_ice1712 * ice) +static void __devinit snd_ice1712_proc_init(struct snd_ice1712 *ice) { struct snd_info_entry *entry; - if (! snd_card_proc_new(ice->card, "ice1712", &entry)) + if (!snd_card_proc_new(ice->card, "ice1712", &entry)) snd_info_set_text_ops(entry, ice, snd_ice1712_proc_read); } @@ -1613,7 +1616,7 @@ static int snd_ice1712_eeprom_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - + memcpy(ucontrol->value.bytes.data, &ice->eeprom, sizeof(ice->eeprom)); return 0; } @@ -1641,7 +1644,7 @@ static int snd_ice1712_spdif_default_get(struct snd_kcontrol *kcontrol, { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); if (ice->spdif.ops.default_get) - ice->spdif.ops.default_get(ice, ucontrol); + ice->spdif.ops.default_get(ice, ucontrol); return 0; } @@ -1657,7 +1660,7 @@ static int snd_ice1712_spdif_default_put(struct snd_kcontrol *kcontrol, static struct snd_kcontrol_new snd_ice1712_spdif_default __devinitdata = { .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT), + .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT), .info = snd_ice1712_spdif_info, .get = snd_ice1712_spdif_default_get, .put = snd_ice1712_spdif_default_put @@ -1709,7 +1712,7 @@ static struct snd_kcontrol_new snd_ice1712_spdif_maskc __devinitdata = { .access = SNDRV_CTL_ELEM_ACCESS_READ, .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK), + .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, CON_MASK), .info = snd_ice1712_spdif_info, .get = snd_ice1712_spdif_maskc_get, }; @@ -1718,7 +1721,7 @@ static struct snd_kcontrol_new snd_ice1712_spdif_maskp __devinitdata = { .access = SNDRV_CTL_ELEM_ACCESS_READ, .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK), + .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PRO_MASK), .info = snd_ice1712_spdif_info, .get = snd_ice1712_spdif_maskp_get, }; @@ -1746,7 +1749,7 @@ static struct snd_kcontrol_new snd_ice1712_spdif_stream __devinitdata = .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | SNDRV_CTL_ELEM_ACCESS_INACTIVE), .iface = SNDRV_CTL_ELEM_IFACE_PCM, - .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PCM_STREAM), + .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PCM_STREAM), .info = snd_ice1712_spdif_info, .get = snd_ice1712_spdif_stream_get, .put = snd_ice1712_spdif_stream_put @@ -1758,7 +1761,7 @@ int snd_ice1712_gpio_get(struct snd_kcontrol *kcontrol, struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); unsigned char mask = kcontrol->private_value & 0xff; int invert = (kcontrol->private_value & (1<<24)) ? 1 : 0; - + snd_ice1712_save_gpio_status(ice); ucontrol->value.integer.value[0] = (snd_ice1712_gpio_read(ice) & mask ? 1 : 0) ^ invert; @@ -1825,7 +1828,7 @@ static int snd_ice1712_pro_internal_clock_get(struct snd_kcontrol *kcontrol, 9, 6, 3, 1, 7, 4, 0, 12, 8, 5, 2, 11, 255, 255, 255, 10 }; unsigned char val; - + spin_lock_irq(&ice->reg_lock); if (is_spdif_master(ice)) { ucontrol->value.enumerated.item[0] = 13; @@ -1867,7 +1870,7 @@ static int snd_ice1712_pro_internal_clock_put(struct snd_kcontrol *kcontrol, if ((oval & ICE1712_SPDIF_MASTER) != (inb(ICEMT(ice, RATE)) & ICE1712_SPDIF_MASTER)) - snd_ice1712_set_input_clock_source(ice, is_spdif_master(ice)); + snd_ice1712_set_input_clock_source(ice, is_spdif_master(ice)); return change; } @@ -1897,7 +1900,7 @@ static int snd_ice1712_pro_internal_clock_default_info(struct snd_kcontrol *kcon "64000", /* 10: 15 */ "88200", /* 11: 11 */ "96000", /* 12: 7 */ - // "IEC958 Input", /* 13: -- */ + /* "IEC958 Input", 13: -- */ }; uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->count = 1; @@ -2026,7 +2029,7 @@ static int snd_ice1712_pro_route_info(struct snd_kcontrol *kcontrol, "IEC958 In L", "IEC958 In R", /* 9-10 */ "Digital Mixer", /* 11 - optional */ }; - + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->count = 1; uinfo->value.enumerated.items = @@ -2070,7 +2073,7 @@ static int snd_ice1712_pro_route_analog_put(struct snd_kcontrol *kcontrol, int change, shift; int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); unsigned int val, old_val, nval; - + /* update PSDOUT */ if (ucontrol->value.enumerated.item[0] >= 11) nval = idx < 2 ? 1 : 0; /* dig mixer (or pcm) */ @@ -2140,7 +2143,7 @@ static int snd_ice1712_pro_route_spdif_put(struct snd_kcontrol *kcontrol, int change, shift; int idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); unsigned int val, old_val, nval; - + /* update SPDOUT */ spin_lock_irq(&ice->reg_lock); val = old_val = inw(ICEMT(ice, ROUTE_SPDOUT)); @@ -2182,7 +2185,7 @@ static struct snd_kcontrol_new snd_ice1712_mixer_pro_analog_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", + .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, NONE) "Route", .info = snd_ice1712_pro_route_info, .get = snd_ice1712_pro_route_spdif_get, .put = snd_ice1712_pro_route_spdif_put, @@ -2204,7 +2207,7 @@ static int snd_ice1712_pro_volume_rate_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); - + ucontrol->value.integer.value[0] = inb(ICEMT(ice, MONITOR_RATE)); return 0; } @@ -2245,7 +2248,7 @@ static int snd_ice1712_pro_peak_get(struct snd_kcontrol *kcontrol, { struct snd_ice1712 *ice = snd_kcontrol_chip(kcontrol); int idx; - + spin_lock_irq(&ice->reg_lock); for (idx = 0; idx < 22; idx++) { outb(idx, ICEMT(ice, MONITOR_PEAKINDEX)); @@ -2296,12 +2299,12 @@ static int __devinit snd_ice1712_read_eeprom(struct snd_ice1712 *ice, unsigned int i, size; struct snd_ice1712_card_info * const *tbl, *c; - if (! modelname || ! *modelname) { + if (!modelname || !*modelname) { ice->eeprom.subvendor = 0; if ((inb(ICEREG(ice, I2C_CTRL)) & ICE1712_I2C_EEPROM) != 0) ice->eeprom.subvendor = (snd_ice1712_read_i2c(ice, dev, 0x00) << 0) | - (snd_ice1712_read_i2c(ice, dev, 0x01) << 8) | - (snd_ice1712_read_i2c(ice, dev, 0x02) << 16) | + (snd_ice1712_read_i2c(ice, dev, 0x01) << 8) | + (snd_ice1712_read_i2c(ice, dev, 0x02) << 16) | (snd_ice1712_read_i2c(ice, dev, 0x03) << 24); if (ice->eeprom.subvendor == 0 || ice->eeprom.subvendor == (unsigned int)-1) { @@ -2318,12 +2321,12 @@ static int __devinit snd_ice1712_read_eeprom(struct snd_ice1712 *ice, } for (tbl = card_tables; *tbl; tbl++) { for (c = *tbl; c->subvendor; c++) { - if (modelname && c->model && ! strcmp(modelname, c->model)) { + if (modelname && c->model && !strcmp(modelname, c->model)) { printk(KERN_INFO "ice1712: Using board model %s\n", c->name); ice->eeprom.subvendor = c->subvendor; } else if (c->subvendor != ice->eeprom.subvendor) continue; - if (! c->eeprom_size || ! c->eeprom_data) + if (!c->eeprom_size || !c->eeprom_data) goto found; /* if the EEPROM is given by the driver, use it */ snd_printdd("using the defined eeprom..\n"); @@ -2484,13 +2487,13 @@ static int __devinit snd_ice1712_build_controls(struct snd_ice1712 *ice) static int snd_ice1712_free(struct snd_ice1712 *ice) { - if (! ice->port) + if (!ice->port) goto __hw_end; /* mask all interrupts */ outb(0xc0, ICEMT(ice, IRQ)); outb(0xff, ICEREG(ice, IRQMASK)); /* --- */ - __hw_end: +__hw_end: if (ice->irq >= 0) free_irq(ice->irq, ice); @@ -2515,7 +2518,7 @@ static int __devinit snd_ice1712_create(struct snd_card *card, int omni, int cs8427_timeout, int dxr_enable, - struct snd_ice1712 ** r_ice1712) + struct snd_ice1712 **r_ice1712) { struct snd_ice1712 *ice; int err; @@ -2525,8 +2528,9 @@ static int __devinit snd_ice1712_create(struct snd_card *card, *r_ice1712 = NULL; - /* enable PCI device */ - if ((err = pci_enable_device(pci)) < 0) + /* enable PCI device */ + err = pci_enable_device(pci); + if (err < 0) return err; /* check, if we can restrict PCI DMA transfers to 28 bits */ if (pci_set_dma_mask(pci, DMA_28BIT_MASK) < 0 || @@ -2570,7 +2574,8 @@ static int __devinit snd_ice1712_create(struct snd_card *card, snd_ice1712_proc_init(ice); synchronize_irq(pci->irq); - if ((err = pci_request_regions(pci, "ICE1712")) < 0) { + err = pci_request_regions(pci, "ICE1712"); + if (err < 0) { kfree(ice); pci_disable_device(pci); return err; @@ -2586,7 +2591,7 @@ static int __devinit snd_ice1712_create(struct snd_card *card, snd_ice1712_free(ice); return -EIO; } - + ice->irq = pci->irq; if (snd_ice1712_read_eeprom(ice, modelname) < 0) { @@ -2606,9 +2611,10 @@ static int __devinit snd_ice1712_create(struct snd_card *card, ICEREG(ice, IRQMASK)); outb(0x00, ICEMT(ice, IRQ)); - if ((err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ice, &ops)) < 0) { + err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, ice, &ops); + if (err < 0) { snd_ice1712_free(ice); - return err; + return err; } snd_card_set_dev(card, &pci->dev); @@ -2648,10 +2654,10 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci, strcpy(card->driver, "ICE1712"); strcpy(card->shortname, "ICEnsemble ICE1712"); - - if ((err = snd_ice1712_create(card, pci, model[dev], omni[dev], - cs8427_timeout[dev], dxr_enable[dev], - &ice)) < 0) { + + err = snd_ice1712_create(card, pci, model[dev], omni[dev], + cs8427_timeout[dev], dxr_enable[dev], &ice); + if (err < 0) { snd_card_free(card); return err; } @@ -2663,7 +2669,8 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci, if (c->driver) /* specific driver? */ strcpy(card->driver, c->driver); if (c->chip_init) { - if ((err = c->chip_init(ice)) < 0) { + err = c->chip_init(ice); + if (err < 0) { snd_card_free(card); return err; } @@ -2675,47 +2682,52 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci, c = &no_matched; __found: - if ((err = snd_ice1712_pcm_profi(ice, pcm_dev++, NULL)) < 0) { + err = snd_ice1712_pcm_profi(ice, pcm_dev++, NULL); + if (err < 0) { snd_card_free(card); return err; } - + if (ice_has_con_ac97(ice)) - if ((err = snd_ice1712_pcm(ice, pcm_dev++, NULL)) < 0) { + err = snd_ice1712_pcm(ice, pcm_dev++, NULL); + if (err < 0) { snd_card_free(card); return err; } - if ((err = snd_ice1712_ac97_mixer(ice)) < 0) { + err = snd_ice1712_ac97_mixer(ice); + if (err < 0) { snd_card_free(card); return err; } - if ((err = snd_ice1712_build_controls(ice)) < 0) { + err = snd_ice1712_build_controls(ice); + if (err < 0) { snd_card_free(card); return err; } if (c->build_controls) { - if ((err = c->build_controls(ice)) < 0) { + err = c->build_controls(ice); + if (err < 0) { snd_card_free(card); return err; } } if (ice_has_con_ac97(ice)) - if ((err = snd_ice1712_pcm_ds(ice, pcm_dev++, NULL)) < 0) { + err = snd_ice1712_pcm_ds(ice, pcm_dev++, NULL); + if (err < 0) { snd_card_free(card); return err; } - if (! c->no_mpu401) { - if ((err = snd_mpu401_uart_new(card, 0, MPU401_HW_ICE1712, - ICEREG(ice, MPU1_CTRL), - (c->mpu401_1_info_flags | - MPU401_INFO_INTEGRATED), - ice->irq, 0, - &ice->rmidi[0])) < 0) { + if (!c->no_mpu401) { + err = snd_mpu401_uart_new(card, 0, MPU401_HW_ICE1712, + ICEREG(ice, MPU1_CTRL), + (c->mpu401_1_info_flags | MPU401_INFO_INTEGRATED), + ice->irq, 0, &ice->rmidi[0]); + if (err < 0) { snd_card_free(card); return err; } @@ -2727,12 +2739,12 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci, if (ice->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_2xMPU401) { /* 2nd port used */ - if ((err = snd_mpu401_uart_new(card, 1, MPU401_HW_ICE1712, - ICEREG(ice, MPU2_CTRL), - (c->mpu401_2_info_flags | - MPU401_INFO_INTEGRATED), - ice->irq, 0, - &ice->rmidi[1])) < 0) { + err = snd_mpu401_uart_new(card, 1, MPU401_HW_ICE1712, + ICEREG(ice, MPU2_CTRL), + (c->mpu401_2_info_flags | MPU401_INFO_INTEGRATED), + ice->irq, 0, &ice->rmidi[1]); + + if (err < 0) { snd_card_free(card); return err; } @@ -2750,7 +2762,8 @@ static int __devinit snd_ice1712_probe(struct pci_dev *pci, sprintf(card->longname, "%s at 0x%lx, irq %i", card->shortname, ice->port, ice->irq); - if ((err = snd_card_register(card)) < 0) { + err = snd_card_register(card); + if (err < 0) { snd_card_free(card); return err; } diff --git a/sound/pci/ice1712/ice1712.h b/sound/pci/ice1712/ice1712.h index 762fbd7a750..fdae6deba16 100644 --- a/sound/pci/ice1712/ice1712.h +++ b/sound/pci/ice1712/ice1712.h @@ -20,7 +20,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * - */ + */ #include #include @@ -112,7 +112,7 @@ */ #define ICEDS(ice, x) ((ice)->dmapath_port + ICE1712_DS_##x) - + #define ICE1712_DS_INTMASK 0x00 /* word - interrupt mask */ #define ICE1712_DS_INTSTAT 0x02 /* word - interrupt status */ #define ICE1712_DS_DATA 0x04 /* dword - channel data */ @@ -121,7 +121,7 @@ /* * Consumer section channel registers */ - + #define ICE1712_DSC_ADDR0 0x00 /* dword - base address 0 */ #define ICE1712_DSC_COUNT0 0x01 /* word - count 0 */ #define ICE1712_DSC_ADDR1 0x02 /* dword - base address 1 */ @@ -138,7 +138,7 @@ #define ICE1712_DSC_RATE 0x05 /* dword - rate */ #define ICE1712_DSC_VOLUME 0x06 /* word - volume control */ -/* +/* * Professional multi-track direct control registers */ @@ -214,7 +214,7 @@ /* - * + * */ struct snd_ice1712; @@ -253,12 +253,12 @@ enum { ICE_EEP1_ADC_ID2, ICE_EEP1_ADC_ID3 }; - + #define ice_has_con_ac97(ice) (!((ice)->eeprom.data[ICE_EEP1_CODEC] & ICE1712_CFG_NO_CON_AC97)) struct snd_ak4xxx_private { - unsigned int cif: 1; /* CIF mode */ + unsigned int cif:1; /* CIF mode */ unsigned char caddr; /* C0 and C1 bits */ unsigned int data_mask; /* DATA gpio bit */ unsigned int clk_mask; /* CLK gpio bit */ @@ -306,11 +306,11 @@ struct snd_ice1712 { struct snd_pcm *pcm; struct snd_pcm *pcm_ds; struct snd_pcm *pcm_pro; - struct snd_pcm_substream *playback_con_substream; - struct snd_pcm_substream *playback_con_substream_ds[6]; - struct snd_pcm_substream *capture_con_substream; - struct snd_pcm_substream *playback_pro_substream; - struct snd_pcm_substream *capture_pro_substream; + struct snd_pcm_substream *playback_con_substream; + struct snd_pcm_substream *playback_con_substream_ds[6]; + struct snd_pcm_substream *capture_con_substream; + struct snd_pcm_substream *playback_pro_substream; + struct snd_pcm_substream *capture_pro_substream; unsigned int playback_pro_size; unsigned int capture_pro_size; unsigned int playback_con_virt_addr[6]; @@ -326,15 +326,15 @@ struct snd_ice1712 { struct snd_ice1712_eeprom eeprom; unsigned int pro_volumes[20]; - unsigned int omni: 1; /* Delta Omni I/O */ - unsigned int dxr_enable: 1; /* Terratec DXR enable for DMX6FIRE */ - unsigned int vt1724: 1; - unsigned int vt1720: 1; - unsigned int has_spdif: 1; /* VT1720/4 - has SPDIF I/O */ - unsigned int force_pdma4: 1; /* VT1720/4 - PDMA4 as non-spdif */ - unsigned int force_rdma1: 1; /* VT1720/4 - RDMA1 as non-spdif */ - unsigned int midi_output: 1; /* VT1720/4: MIDI output triggered */ - unsigned int midi_input: 1; /* VT1720/4: MIDI input triggered */ + unsigned int omni:1; /* Delta Omni I/O */ + unsigned int dxr_enable:1; /* Terratec DXR enable for DMX6FIRE */ + unsigned int vt1724:1; + unsigned int vt1720:1; + unsigned int has_spdif:1; /* VT1720/4 - has SPDIF I/O */ + unsigned int force_pdma4:1; /* VT1720/4 - PDMA4 as non-spdif */ + unsigned int force_rdma1:1; /* VT1720/4 - RDMA1 as non-spdif */ + unsigned int midi_output:1; /* VT1720/4: MIDI output triggered */ + unsigned int midi_input:1; /* VT1720/4: MIDI input triggered */ unsigned int num_total_dacs; /* total DACs */ unsigned int num_total_adcs; /* total ADCs */ unsigned int cur_rate; /* current rate */ @@ -351,7 +351,7 @@ struct snd_ice1712 { struct snd_i2c_bus *i2c; /* I2C bus */ struct snd_i2c_device *cs8427; /* CS8427 I2C device */ unsigned int cs8427_timeout; /* CS8427 reset timeout in HZ/100 */ - + struct ice1712_gpio { unsigned int direction; /* current direction bits */ unsigned int write_mask; /* current mask bits */ @@ -455,7 +455,7 @@ static inline int snd_ice1712_gpio_read_bits(struct snd_ice1712 *ice, { ice->gpio.direction &= ~mask; snd_ice1712_gpio_set_dir(ice, ice->gpio.direction); - return (snd_ice1712_gpio_read(ice) & mask); + return snd_ice1712_gpio_read(ice) & mask; } int snd_ice1712_spdif_build_controls(struct snd_ice1712 *ice); @@ -467,13 +467,13 @@ int snd_ice1712_akm4xxx_build_controls(struct snd_ice1712 *ice); int snd_ice1712_init_cs8427(struct snd_ice1712 *ice, int addr); -static inline void snd_ice1712_write(struct snd_ice1712 * ice, u8 addr, u8 data) +static inline void snd_ice1712_write(struct snd_ice1712 *ice, u8 addr, u8 data) { outb(addr, ICEREG(ice, INDEX)); outb(data, ICEREG(ice, DATA)); } -static inline u8 snd_ice1712_read(struct snd_ice1712 * ice, u8 addr) +static inline u8 snd_ice1712_read(struct snd_ice1712 *ice, u8 addr) { outb(addr, ICEREG(ice, INDEX)); return inb(ICEREG(ice, DATA)); @@ -491,7 +491,7 @@ struct snd_ice1712_card_info { char *driver; int (*chip_init)(struct snd_ice1712 *); int (*build_controls)(struct snd_ice1712 *); - unsigned int no_mpu401: 1; + unsigned int no_mpu401:1; unsigned int mpu401_1_info_flags; unsigned int mpu401_2_info_flags; const char *mpu401_1_name; -- cgit v1.2.3 From de51ca1267b523d82644b0b752899de693e7190b Mon Sep 17 00:00:00 2001 From: Matthew Ranostay Date: Sun, 7 Sep 2008 14:31:40 -0400 Subject: ALSA: hda: slave digital out support Added support for playing a stream on multiple digital outs. This is done by defining codec->slave_dig_outs as array of hda_nid_t with a null-terminated entry to set the slave SPDIF outs, in which the slave outs have cloned settings of the master out (e.g. dig_out_nid). Signed-off-by: Matthew Ranostay Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_codec.c | 52 +++++++++++++++++++++++++++++++++++++++++++++-- sound/pci/hda/hda_codec.h | 1 + 2 files changed, 51 insertions(+), 2 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 4f329115080..696d77e575e 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -1454,12 +1454,22 @@ static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol, codec->spdif_ctls = val; if (change) { + hda_nid_t *d; snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, val & 0xff); snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_2, val >> 8); + + for (d = codec->slave_dig_outs; *d; d++) { + snd_hda_codec_write_cache(codec, *d, 0, + AC_VERB_SET_DIGI_CONVERT_1, + val & 0xff); + snd_hda_codec_write_cache(codec, *d, 0, + AC_VERB_SET_DIGI_CONVERT_2, + val >> 8); + } } mutex_unlock(&codec->spdif_mutex); @@ -1491,10 +1501,16 @@ static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol, val |= AC_DIG1_ENABLE; change = codec->spdif_ctls != val; if (change) { + hda_nid_t *d; codec->spdif_ctls = val; snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, val & 0xff); + + for (d = codec->slave_dig_outs; *d; d++) + snd_hda_codec_write_cache(codec, *d, 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)) @@ -1643,9 +1659,14 @@ static int snd_hda_spdif_in_switch_put(struct snd_kcontrol *kcontrol, mutex_lock(&codec->spdif_mutex); change = codec->spdif_in_enable != val; if (change) { + hda_nid_t *d; codec->spdif_in_enable = val; snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, val); + + for (d = codec->slave_dig_outs; *d; d++) + snd_hda_codec_write_cache(codec, *d, 0, + AC_VERB_SET_DIGI_CONVERT_1, val); } mutex_unlock(&codec->spdif_mutex); return change; @@ -2589,15 +2610,30 @@ int snd_hda_input_mux_put(struct hda_codec *codec, static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid, unsigned int stream_tag, unsigned int format) { + hda_nid_t *d; + /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */ - if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) + if (codec->spdif_status_reset && (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); + + for (d = codec->slave_dig_outs; *d; d++) + snd_hda_codec_write(codec, *d, 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_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) + if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) { snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, codec->spdif_ctls & 0xff); + + for (d = codec->slave_dig_outs; *d; d++) + snd_hda_codec_write(codec, *d, 0, + AC_VERB_SET_DIGI_CONVERT_1, + codec->spdif_ctls & 0xff); + } + } /* @@ -2621,8 +2657,12 @@ int snd_hda_multi_out_dig_prepare(struct hda_codec *codec, unsigned int format, struct snd_pcm_substream *substream) { + hda_nid_t *nid; mutex_lock(&codec->spdif_mutex); setup_dig_out_stream(codec, mout->dig_out_nid, stream_tag, format); + if (codec->slave_dig_outs) + for (nid = codec->slave_dig_outs; *nid; nid++) + setup_dig_out_stream(codec, *nid, stream_tag, format); mutex_unlock(&codec->spdif_mutex); return 0; } @@ -2689,6 +2729,7 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct snd_pcm_substream *substream) { hda_nid_t *nids = mout->dac_nids; + hda_nid_t *d; int chs = substream->runtime->channels; int i; @@ -2702,9 +2743,16 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, mout->dig_out_used = HDA_DIG_ANALOG_DUP; setup_dig_out_stream(codec, mout->dig_out_nid, stream_tag, format); + if (codec->slave_dig_outs) + for (d = codec->slave_dig_outs; *d; d++) + setup_dig_out_stream(codec, *d, + stream_tag, format); } else { mout->dig_out_used = 0; snd_hda_codec_cleanup_stream(codec, mout->dig_out_nid); + if (codec->slave_dig_outs) + for (d = codec->slave_dig_outs; *d; d++) + snd_hda_codec_cleanup_stream(codec, *d); } } mutex_unlock(&codec->spdif_mutex); diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 780e2fffae3..60468f56240 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -725,6 +725,7 @@ struct hda_codec { unsigned int spdif_status; /* IEC958 status bits */ unsigned short spdif_ctls; /* SPDIF control bits */ unsigned int spdif_in_enable; /* SPDIF input enable? */ + hda_nid_t *slave_dig_outs; /* optional digital out slave widgets */ struct snd_hwdep *hwdep; /* assigned hwdep device */ -- cgit v1.2.3 From 0ffa9807592171ad7421c1ffce7abde04b1622c0 Mon Sep 17 00:00:00 2001 From: Matthew Ranostay Date: Mon, 8 Sep 2008 11:20:05 -0400 Subject: ALSA: hda: digital slave support for IDT codecs Added slave_dig_outs entries for several IDT codecs that have multiple SPDIF outs, and enabled these SPDIF outs in several pin configs. Signed-off-by: Matthew Ranostay Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 4da53689618..1440175e100 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -235,6 +235,10 @@ static hda_nid_t stac92hd73xx_pwr_nids[8] = { 0x0f, 0x10, 0x11 }; +static hda_nid_t stac92hd73xx_slave_dig_outs[2] = { + 0x26, 0, +}; + static hda_nid_t stac92hd73xx_adc_nids[2] = { 0x1a, 0x1b }; @@ -284,6 +288,10 @@ static hda_nid_t stac92hd83xxx_pwr_nids[4] = { 0xa, 0xb, 0xd, 0xe, }; +static hda_nid_t stac92hd83xxx_slave_dig_outs[2] = { + 0x1e, 0, +}; + static unsigned int stac92hd83xxx_pwr_mapping[4] = { 0x03, 0x0c, 0x10, 0x40, }; @@ -317,6 +325,10 @@ static hda_nid_t stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS + 1] = { 0x18, 0x19, 0 }; +static hda_nid_t stac92hd71bxx_slave_dig_outs[2] = { + 0x22, 0 +}; + static hda_nid_t stac925x_adc_nids[1] = { 0x03, }; @@ -418,9 +430,10 @@ static hda_nid_t stac92hd83xxx_pin_nids[14] = { 0x0f, 0x10, 0x11, 0x12, 0x13, 0x1d, 0x1e, 0x1f, 0x20 }; -static hda_nid_t stac92hd71bxx_pin_nids[10] = { +static hda_nid_t stac92hd71bxx_pin_nids[11] = { 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x14, 0x18, 0x19, 0x1e, + 0x1f, }; static hda_nid_t stac927x_pin_nids[14] = { @@ -1492,22 +1505,22 @@ static struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { "DFI LanParty", STAC_92HD71BXX_REF), }; -static unsigned int ref92hd71bxx_pin_configs[10] = { +static unsigned int ref92hd71bxx_pin_configs[11] = { 0x02214030, 0x02a19040, 0x01a19020, 0x01014010, 0x0181302e, 0x01114010, 0x01019020, 0x90a000f0, - 0x90a000f0, 0x01452050, + 0x90a000f0, 0x01452050, 0x01452050, }; -static unsigned int dell_m4_1_pin_configs[10] = { +static unsigned int dell_m4_1_pin_configs[11] = { 0x0421101f, 0x04a11221, 0x40f000f0, 0x90170110, 0x23a1902e, 0x23014250, 0x40f000f0, 0x90a000f0, - 0x40f000f0, 0x4f0000f0, + 0x40f000f0, 0x4f0000f0, 0x4f0000f0, }; -static unsigned int dell_m4_2_pin_configs[10] = { +static unsigned int dell_m4_2_pin_configs[11] = { 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110, 0x23a1902e, 0x23014250, 0x40f000f0, 0x40f000f0, - 0x40f000f0, 0x044413b0, + 0x40f000f0, 0x044413b0, 0x044413b0, }; static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = { @@ -3984,6 +3997,7 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) return -ENOMEM; codec->spec = spec; + codec->slave_dig_outs = stac92hd83xxx_slave_dig_outs; spec->mono_nid = 0x19; spec->digbeep_nid = 0x21; spec->dmic_nids = stac92hd83xxx_dmic_nids; @@ -4134,6 +4148,7 @@ again: case 0x111d76b5: spec->mixer = stac92hd71bxx_mixer; spec->init = stac92hd71bxx_core_init; + codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; break; case 0x111d7608: /* 5 Port with Analog Mixer */ if ((codec->revision_id & 0xf) == 0 || @@ -4166,6 +4181,7 @@ again: default: spec->mixer = stac92hd71bxx_analog_mixer; spec->init = stac92hd71bxx_analog_core_init; + codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; } spec->aloopback_mask = 0x20; -- cgit v1.2.3 From e348797018528249e525b40f0270aca42ac44a97 Mon Sep 17 00:00:00 2001 From: Matthew Ranostay Date: Mon, 8 Sep 2008 11:36:59 -0400 Subject: ALSA: hda: SPDIF mux name change Changed the mux naming scheme from "IEC9258 Mux" to "IEC958 Playback Source" to match the coding style. Signed-by-off: Matthew Ranostay Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 1440175e100..80bdee4880d 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -1060,7 +1060,7 @@ static struct snd_kcontrol_new stac_dmux_mixer = { static struct snd_kcontrol_new stac_smux_mixer = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "IEC958 Mux", + .name = "IEC958 Playback Source", /* count set later */ .info = stac92xx_smux_enum_info, .get = stac92xx_smux_enum_get, -- cgit v1.2.3 From e99d32b325ac68bd2ffbbe8edc44cbaf5d91e4be Mon Sep 17 00:00:00 2001 From: Matthew Ranostay Date: Tue, 9 Sep 2008 10:46:38 +0200 Subject: ALSA: hda - add missing slave_dig_outs for 92HD73bxx Signed-off-by: Matthew Ranostay Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 80bdee4880d..4343d5fe5f7 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -3859,6 +3859,7 @@ static int patch_stac92hd73xx(struct hda_codec *codec) return -ENOMEM; codec->spec = spec; + codec->slave_dig_outs = stac92hd73xx_slave_dig_outs; spec->num_pins = ARRAY_SIZE(stac92hd73xx_pin_nids); spec->pin_nids = stac92hd73xx_pin_nids; spec->board_config = snd_hda_check_board_config(codec, -- cgit v1.2.3 From eb14a46cf974c59aadef8c120b7dfcb27bc81f24 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Tue, 9 Sep 2008 15:40:38 +0800 Subject: ALSA: HDA patch_via.c: cleanup * add extra parenthesis to make code more readable * use kzalloc() for alloc+zero rather than kcalloc() * ensure that AUTO_SEQ_* starts at 0 Signed-off-by: Harald Welte Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_via.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index e7e43524f8c..3e148373334 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -77,7 +77,7 @@ enum { }; enum { - AUTO_SEQ_FRONT, + AUTO_SEQ_FRONT = 0, AUTO_SEQ_SURROUND, AUTO_SEQ_CENLFE, AUTO_SEQ_SIDE @@ -283,11 +283,11 @@ static int via_mux_enum_put(struct snd_kcontrol *kcontrol, return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, 0x18, &spec->cur_mux[adc_idx]); else if ((IS_VT1709_10CH_VENDORID(vendor_id) || - IS_VT1709_6CH_VENDORID(vendor_id)) && adc_idx == 0) + IS_VT1709_6CH_VENDORID(vendor_id)) && (adc_idx == 0)) return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, 0x19, &spec->cur_mux[adc_idx]); else if ((IS_VT1708B_8CH_VENDORID(vendor_id) || - IS_VT1708B_4CH_VENDORID(vendor_id)) && adc_idx == 0) + IS_VT1708B_4CH_VENDORID(vendor_id)) && (adc_idx == 0)) return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, 0x17, &spec->cur_mux[adc_idx]); else @@ -897,7 +897,7 @@ static int patch_vt1708(struct hda_codec *codec) int err; /* create a codec specific record */ - spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); + spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (spec == NULL) return -ENOMEM; @@ -1360,7 +1360,7 @@ static int patch_vt1709_10ch(struct hda_codec *codec) int err; /* create a codec specific record */ - spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); + spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (spec == NULL) return -ENOMEM; @@ -1451,7 +1451,7 @@ static int patch_vt1709_6ch(struct hda_codec *codec) int err; /* create a codec specific record */ - spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); + spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (spec == NULL) return -ENOMEM; @@ -1890,7 +1890,7 @@ static int patch_vt1708B_8ch(struct hda_codec *codec) int err; /* create a codec specific record */ - spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); + spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (spec == NULL) return -ENOMEM; @@ -1939,7 +1939,7 @@ static int patch_vt1708B_4ch(struct hda_codec *codec) int err; /* create a codec specific record */ - spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); + spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (spec == NULL) return -ENOMEM; -- cgit v1.2.3 From 76d9b0dd78197c473892e44b1fbf6be4592cc440 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Tue, 9 Sep 2008 15:50:37 +0800 Subject: ALSA: HDA patch_via.c: HP and CD pin connect config Signed-off-by: Harald Welte Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_via.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 3e148373334..d397f528cb5 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -3,8 +3,8 @@ * * HD audio interface patch for VIA VT1708 codec * - * Copyright (c) 2006 Lydia Wang - * Takashi Iwai + * Copyright (c) 2006-2008 Lydia Wang + * Takashi Iwai * * This driver is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -29,6 +29,7 @@ /* 2006-09-08 Lydia Wang Fix internal loopback recording source select bug */ /* 2007-09-12 Lydia Wang Add EAPD enable during driver initialization */ /* 2007-09-17 Lydia Wang Add VT1708B codec support */ +/* 2007-11-14 Lydia Wang Add VT1708A codec HP and CD pin connect config */ /* */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ @@ -53,6 +54,8 @@ #define VT1708_DIGOUT_NID 0x14 #define VT1708_DIGIN_NID 0x16 #define VT1708_DIGIN_PIN 0x26 +#define VT1708_HP_PIN_NID 0x20 +#define VT1708_CD_PIN_NID 0x24 #define VT1709_HP_DAC_NID 0x28 #define VT1709_DIGOUT_NID 0x13 @@ -840,11 +843,36 @@ static struct hda_amp_list vt1708_loopbacks[] = { }; #endif +static void vt1708_set_pinconfig_connect(struct hda_codec *codec, hda_nid_t nid) +{ + unsigned int def_conf; + unsigned char seqassoc; + + def_conf = snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_CONFIG_DEFAULT, 0); + seqassoc = (unsigned char) get_defcfg_association(def_conf); + seqassoc = (seqassoc << 4) | get_defcfg_sequence(def_conf); + if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) { + if (seqassoc == 0xff) { + def_conf = def_conf & (~(AC_JACK_PORT_BOTH << 30)); + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_CONFIG_DEFAULT_BYTES_3, + def_conf >> 24); + } + } + + return; +} + static int vt1708_parse_auto_config(struct hda_codec *codec) { struct via_spec *spec = codec->spec; int err; + /* Add HP and CD pin config connect bit re-config action */ + vt1708_set_pinconfig_connect(codec, VT1708_HP_PIN_NID); + vt1708_set_pinconfig_connect(codec, VT1708_CD_PIN_NID); + err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, NULL); if (err < 0) return err; -- cgit v1.2.3 From fb4cb772c0b22f7bce0b151ef5712e80d434bc97 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Tue, 9 Sep 2008 15:53:36 +0800 Subject: ALSA: HDA patch_via.c: Fix inversion of surround and side channels In the current driver, there is a consistent mistake between the SURROUND and the SIDE channels. This patch fixes it. Signed-off-by: Harald Welte Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_via.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index d397f528cb5..bae6273eeb1 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -30,6 +30,7 @@ /* 2007-09-12 Lydia Wang Add EAPD enable during driver initialization */ /* 2007-09-17 Lydia Wang Add VT1708B codec support */ /* 2007-11-14 Lydia Wang Add VT1708A codec HP and CD pin connect config */ +/* 2008-02-03 Lydia Wang Fix Rear channels and Back channels inverse issue */ /* */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ @@ -660,10 +661,10 @@ static int vt1708_auto_fill_dac_nids(struct via_spec *spec, spec->multiout.dac_nids[i] = 0x12; break; case AUTO_SEQ_SURROUND: - spec->multiout.dac_nids[i] = 0x13; + spec->multiout.dac_nids[i] = 0x11; break; case AUTO_SEQ_SIDE: - spec->multiout.dac_nids[i] = 0x11; + spec->multiout.dac_nids[i] = 0x13; break; } } @@ -688,7 +689,7 @@ static int vt1708_auto_create_multi_out_ctls(struct via_spec *spec, continue; if (i != AUTO_SEQ_FRONT) - nid_vol = 0x1b - i + 1; + nid_vol = 0x18 + i; if (i == AUTO_SEQ_CENLFE) { /* Center/LFE */ @@ -1118,11 +1119,11 @@ static int vt1709_auto_fill_dac_nids(struct via_spec *spec, break; case AUTO_SEQ_SURROUND: /* AOW3 */ - spec->multiout.dac_nids[i] = 0x27; + spec->multiout.dac_nids[i] = 0x11; break; case AUTO_SEQ_SIDE: /* AOW1 */ - spec->multiout.dac_nids[i] = 0x11; + spec->multiout.dac_nids[i] = 0x27; break; default: break; @@ -1231,26 +1232,26 @@ static int vt1709_auto_create_multi_out_ctls(struct via_spec *spec, } else if (i == AUTO_SEQ_SURROUND) { sprintf(name, "%s Playback Volume", chname[i]); err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, - HDA_COMPOSE_AMP_VAL(0x29, 3, 0, + HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT)); if (err < 0) return err; sprintf(name, "%s Playback Switch", chname[i]); err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, - HDA_COMPOSE_AMP_VAL(0x29, 3, 0, + HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT)); if (err < 0) return err; } else if (i == AUTO_SEQ_SIDE) { sprintf(name, "%s Playback Volume", chname[i]); err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, - HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, + HDA_COMPOSE_AMP_VAL(0x29, 3, 0, HDA_OUTPUT)); if (err < 0) return err; sprintf(name, "%s Playback Switch", chname[i]); err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, - HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, + HDA_COMPOSE_AMP_VAL(0x29, 3, 0, HDA_OUTPUT)); if (err < 0) return err; @@ -1690,10 +1691,10 @@ static int vt1708B_auto_fill_dac_nids(struct via_spec *spec, spec->multiout.dac_nids[i] = 0x24; break; case AUTO_SEQ_SURROUND: - spec->multiout.dac_nids[i] = 0x25; + spec->multiout.dac_nids[i] = 0x11; break; case AUTO_SEQ_SIDE: - spec->multiout.dac_nids[i] = 0x11; + spec->multiout.dac_nids[i] = 0x25; break; } } @@ -1708,7 +1709,7 @@ static int vt1708B_auto_create_multi_out_ctls(struct via_spec *spec, { char name[32]; static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" }; - hda_nid_t nid_vols[] = {0x16, 0x27, 0x26, 0x18}; + hda_nid_t nid_vols[] = {0x16, 0x18, 0x26, 0x27}; hda_nid_t nid, nid_vol = 0; int i, err; -- cgit v1.2.3 From d949cac1ea8596f61942437ad741a3fbb412846f Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Tue, 9 Sep 2008 15:56:01 +0800 Subject: ALSA: HDA patch_via.c: Add VT1708S and VT1702 support The VT1702 and VT1708S codecs are new HDA codecs by VIA. This patch adds support for them to the patch_via.c file for HDA Signed-off-by: Harald Welte Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_via.c | 762 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 758 insertions(+), 4 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index bae6273eeb1..91b72add1a8 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -1,7 +1,7 @@ /* * Universal Interface for Intel High Definition Audio Codec * - * HD audio interface patch for VIA VT1708 codec + * HD audio interface patch for VIA VT1702/VT1708/VT1709 codec * * Copyright (c) 2006-2008 Lydia Wang * Takashi Iwai @@ -31,6 +31,7 @@ /* 2007-09-17 Lydia Wang Add VT1708B codec support */ /* 2007-11-14 Lydia Wang Add VT1708A codec HP and CD pin connect config */ /* 2008-02-03 Lydia Wang Fix Rear channels and Back channels inverse issue */ +/* 2008-03-06 Lydia Wang Add VT1702 codec and VT1708S codec support */ /* */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ @@ -55,8 +56,8 @@ #define VT1708_DIGOUT_NID 0x14 #define VT1708_DIGIN_NID 0x16 #define VT1708_DIGIN_PIN 0x26 -#define VT1708_HP_PIN_NID 0x20 -#define VT1708_CD_PIN_NID 0x24 +#define VT1708_HP_PIN_NID 0x20 +#define VT1708_CD_PIN_NID 0x24 #define VT1709_HP_DAC_NID 0x28 #define VT1709_DIGOUT_NID 0x13 @@ -68,12 +69,19 @@ #define VT1708B_DIGIN_NID 0x15 #define VT1708B_DIGIN_PIN 0x21 +#define VT1708S_HP_NID 0x25 +#define VT1708S_DIGOUT_NID 0x12 + +#define VT1702_HP_NID 0x17 +#define VT1702_DIGOUT_NID 0x11 + #define IS_VT1708_VENDORID(x) ((x) >= 0x11061708 && (x) <= 0x1106170b) #define IS_VT1709_10CH_VENDORID(x) ((x) >= 0x1106e710 && (x) <= 0x1106e713) #define IS_VT1709_6CH_VENDORID(x) ((x) >= 0x1106e714 && (x) <= 0x1106e717) #define IS_VT1708B_8CH_VENDORID(x) ((x) >= 0x1106e720 && (x) <= 0x1106e723) #define IS_VT1708B_4CH_VENDORID(x) ((x) >= 0x1106e724 && (x) <= 0x1106e727) - +#define IS_VT1708S_VENDORID(x) ((x) >= 0x11060397 && (x) <= 0x11067397) +#define IS_VT1702_VENDORID(x) ((x) >= 0x11060398 && (x) <= 0x11067398) enum { VIA_CTL_WIDGET_VOL, @@ -150,6 +158,16 @@ static hda_nid_t vt1708B_adc_nids[2] = { 0x13, 0x14 }; +static hda_nid_t vt1708S_adc_nids[2] = { + /* ADC1-2 */ + 0x13, 0x14 +}; + +static hda_nid_t vt1702_adc_nids[3] = { + /* ADC1-2 */ + 0x12, 0x20, 0x1F +}; + /* add dynamic controls */ static int via_add_control(struct via_spec *spec, int type, const char *name, unsigned long val) @@ -294,6 +312,9 @@ static int via_mux_enum_put(struct snd_kcontrol *kcontrol, IS_VT1708B_4CH_VENDORID(vendor_id)) && (adc_idx == 0)) return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, 0x17, &spec->cur_mux[adc_idx]); + else if (IS_VT1702_VENDORID(vendor_id) && (adc_idx == 0)) + return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, + 0x13, &spec->cur_mux[adc_idx]); else return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, spec->adc_nids[adc_idx], @@ -2011,6 +2032,707 @@ static int patch_vt1708B_4ch(struct hda_codec *codec) return 0; } +/* Patch for VT1708S */ + +/* capture mixer elements */ +static struct snd_kcontrol_new vt1708S_capture_mixer[] = { + HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT), + HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Mic Boost", 0x1A, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Front Mic Boost", 0x1E, 0x0, HDA_INPUT), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + /* The multiple "Capture Source" controls confuse alsamixer + * So call somewhat different.. + */ + /* .name = "Capture Source", */ + .name = "Input Source", + .count = 1, + .info = via_mux_enum_info, + .get = via_mux_enum_get, + .put = via_mux_enum_put, + }, + { } /* end */ +}; + +static struct hda_verb vt1708S_volume_init_verbs[] = { + /* Unmute ADC0-1 and set the default input to mic-in */ + {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x14, 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 */ + /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */ + {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, + {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, + {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, + + /* Setup default input of PW4 to MW0 */ + {0x1d, AC_VERB_SET_CONNECT_SEL, 0x0}, + /* PW9 Output enable */ + {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, + { } +}; + +static struct hda_pcm_stream vt1708S_pcm_analog_playback = { + .substreams = 2, + .channels_min = 2, + .channels_max = 8, + .nid = 0x10, /* NID to query formats and rates */ + .ops = { + .open = via_playback_pcm_open, + .prepare = via_playback_pcm_prepare, + .cleanup = via_playback_pcm_cleanup + }, +}; + +static struct hda_pcm_stream vt1708S_pcm_analog_capture = { + .substreams = 2, + .channels_min = 2, + .channels_max = 2, + .nid = 0x13, /* NID to query formats and rates */ + .ops = { + .prepare = via_capture_pcm_prepare, + .cleanup = via_capture_pcm_cleanup + }, +}; + +static struct hda_pcm_stream vt1708S_pcm_digital_playback = { + .substreams = 1, + .channels_min = 2, + .channels_max = 2, + /* NID is set in via_build_pcms */ + .ops = { + .open = via_dig_playback_pcm_open, + .close = via_dig_playback_pcm_close, + .prepare = via_dig_playback_pcm_prepare + }, +}; + +/* fill in the dac_nids table from the parsed pin configuration */ +static int vt1708S_auto_fill_dac_nids(struct via_spec *spec, + const struct auto_pin_cfg *cfg) +{ + int i; + hda_nid_t nid; + + spec->multiout.num_dacs = cfg->line_outs; + + spec->multiout.dac_nids = spec->private_dac_nids; + + for (i = 0; i < 4; i++) { + nid = cfg->line_out_pins[i]; + if (nid) { + /* config dac list */ + switch (i) { + case AUTO_SEQ_FRONT: + spec->multiout.dac_nids[i] = 0x10; + break; + case AUTO_SEQ_CENLFE: + spec->multiout.dac_nids[i] = 0x24; + break; + case AUTO_SEQ_SURROUND: + spec->multiout.dac_nids[i] = 0x11; + break; + case AUTO_SEQ_SIDE: + spec->multiout.dac_nids[i] = 0x25; + break; + } + } + } + + return 0; +} + +/* add playback controls from the parsed DAC table */ +static int vt1708S_auto_create_multi_out_ctls(struct via_spec *spec, + const struct auto_pin_cfg *cfg) +{ + char name[32]; + static const char *chname[4] = { "Front", "Surround", "C/LFE", "Side" }; + hda_nid_t nid_vols[] = {0x10, 0x11, 0x24, 0x25}; + hda_nid_t nid_mutes[] = {0x1C, 0x18, 0x26, 0x27}; + hda_nid_t nid, nid_vol, nid_mute; + int i, err; + + for (i = 0; i <= AUTO_SEQ_SIDE; i++) { + nid = cfg->line_out_pins[i]; + + if (!nid) + continue; + + nid_vol = nid_vols[i]; + nid_mute = nid_mutes[i]; + + if (i == AUTO_SEQ_CENLFE) { + /* Center/LFE */ + err = via_add_control(spec, VIA_CTL_WIDGET_VOL, + "Center Playback Volume", + HDA_COMPOSE_AMP_VAL(nid_vol, 1, 0, + HDA_OUTPUT)); + if (err < 0) + return err; + err = via_add_control(spec, VIA_CTL_WIDGET_VOL, + "LFE Playback Volume", + HDA_COMPOSE_AMP_VAL(nid_vol, 2, 0, + HDA_OUTPUT)); + if (err < 0) + return err; + err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, + "Center Playback Switch", + HDA_COMPOSE_AMP_VAL(nid_mute, + 1, 0, + HDA_OUTPUT)); + if (err < 0) + return err; + err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, + "LFE Playback Switch", + HDA_COMPOSE_AMP_VAL(nid_mute, + 2, 0, + HDA_OUTPUT)); + if (err < 0) + return err; + } else if (i == AUTO_SEQ_FRONT) { + /* add control to mixer index 0 */ + err = via_add_control(spec, VIA_CTL_WIDGET_VOL, + "Master Front Playback Volume", + HDA_COMPOSE_AMP_VAL(0x16, 3, 0, + HDA_INPUT)); + if (err < 0) + return err; + err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, + "Master Front Playback Switch", + HDA_COMPOSE_AMP_VAL(0x16, 3, 0, + HDA_INPUT)); + if (err < 0) + return err; + + /* Front */ + sprintf(name, "%s Playback Volume", chname[i]); + err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, + HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, + HDA_OUTPUT)); + if (err < 0) + return err; + sprintf(name, "%s Playback Switch", chname[i]); + err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, + HDA_COMPOSE_AMP_VAL(nid_mute, + 3, 0, + HDA_OUTPUT)); + if (err < 0) + return err; + } else { + sprintf(name, "%s Playback Volume", chname[i]); + err = via_add_control(spec, VIA_CTL_WIDGET_VOL, name, + HDA_COMPOSE_AMP_VAL(nid_vol, 3, 0, + HDA_OUTPUT)); + if (err < 0) + return err; + sprintf(name, "%s Playback Switch", chname[i]); + err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, name, + HDA_COMPOSE_AMP_VAL(nid_mute, + 3, 0, + HDA_OUTPUT)); + if (err < 0) + return err; + } + } + + return 0; +} + +static int vt1708S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) +{ + int err; + + if (!pin) + return 0; + + spec->multiout.hp_nid = VT1708S_HP_NID; /* AOW3 */ + + err = via_add_control(spec, VIA_CTL_WIDGET_VOL, + "Headphone Playback Volume", + HDA_COMPOSE_AMP_VAL(0x25, 3, 0, HDA_OUTPUT)); + if (err < 0) + return err; + + err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, + "Headphone Playback Switch", + 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 vt1708S_auto_create_analog_input_ctls(struct via_spec *spec, + const struct auto_pin_cfg *cfg) +{ + static char *labels[] = { + "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL + }; + struct hda_input_mux *imux = &spec->private_imux; + int i, err, idx = 0; + + /* for internal loopback recording select */ + imux->items[imux->num_items].label = "Stereo Mixer"; + imux->items[imux->num_items].index = 5; + imux->num_items++; + + for (i = 0; i < AUTO_PIN_LAST; i++) { + if (!cfg->input_pins[i]) + continue; + + switch (cfg->input_pins[i]) { + case 0x1a: /* Mic */ + idx = 2; + break; + + case 0x1b: /* Line In */ + idx = 3; + break; + + case 0x1e: /* Front Mic */ + idx = 4; + break; + + case 0x1f: /* CD */ + idx = 1; + break; + } + err = via_new_analog_input(spec, cfg->input_pins[i], labels[i], + idx, 0x16); + if (err < 0) + return err; + imux->items[imux->num_items].label = labels[i]; + imux->items[imux->num_items].index = idx-1; + imux->num_items++; + } + return 0; +} + +static int vt1708S_parse_auto_config(struct hda_codec *codec) +{ + struct via_spec *spec = codec->spec; + int err; + static hda_nid_t vt1708s_ignore[] = {0x21, 0}; + + err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, + vt1708s_ignore); + if (err < 0) + return err; + err = vt1708S_auto_fill_dac_nids(spec, &spec->autocfg); + if (err < 0) + return err; + if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0]) + return 0; /* can't find valid BIOS pin config */ + + err = vt1708S_auto_create_multi_out_ctls(spec, &spec->autocfg); + if (err < 0) + return err; + err = vt1708S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); + if (err < 0) + return err; + err = vt1708S_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 = VT1708S_DIGOUT_NID; + + if (spec->kctl_alloc) + spec->mixers[spec->num_mixers++] = spec->kctl_alloc; + + spec->input_mux = &spec->private_imux; + + return 1; +} + +#ifdef CONFIG_SND_HDA_POWER_SAVE +static struct hda_amp_list vt1708S_loopbacks[] = { + { 0x16, HDA_INPUT, 1 }, + { 0x16, HDA_INPUT, 2 }, + { 0x16, HDA_INPUT, 3 }, + { 0x16, HDA_INPUT, 4 }, + { } /* end */ +}; +#endif + +static int patch_vt1708S(struct hda_codec *codec) +{ + struct via_spec *spec; + int err; + + /* create a codec specific record */ + spec = kzalloc(sizeof(*spec), GFP_KERNEL); + if (spec == NULL) + return -ENOMEM; + + codec->spec = spec; + + /* automatic parse from the BIOS config */ + err = vt1708S_parse_auto_config(codec); + if (err < 0) { + via_free(codec); + return err; + } else if (!err) { + printk(KERN_INFO "hda_codec: Cannot set up configuration " + "from BIOS. Using genenic mode...\n"); + } + + spec->init_verbs = vt1708S_volume_init_verbs; + + spec->stream_name_analog = "VT1708S Analog"; + spec->stream_analog_playback = &vt1708S_pcm_analog_playback; + spec->stream_analog_capture = &vt1708S_pcm_analog_capture; + + spec->stream_name_digital = "VT1708S Digital"; + spec->stream_digital_playback = &vt1708S_pcm_digital_playback; + + if (!spec->adc_nids && spec->input_mux) { + spec->adc_nids = vt1708S_adc_nids; + spec->num_adc_nids = ARRAY_SIZE(vt1708S_adc_nids); + spec->mixers[spec->num_mixers] = vt1708S_capture_mixer; + spec->num_mixers++; + } + + codec->patch_ops = via_patch_ops; + + codec->patch_ops.init = via_auto_init; + +#ifdef CONFIG_SND_HDA_POWER_SAVE + spec->loopback.amplist = vt1708S_loopbacks; +#endif + + return 0; +} + +/* Patch for VT1702 */ + +/* capture mixer elements */ +static struct snd_kcontrol_new vt1702_capture_mixer[] = { + HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x20, 0x0, HDA_INPUT), + HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x20, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x1F, 0x0, HDA_INPUT), + HDA_CODEC_MUTE("Digital Mic Capture Switch", 0x1F, 0x0, HDA_INPUT), + HDA_CODEC_VOLUME("Digital Mic Boost Capture Volume", 0x1E, 0x0, + HDA_INPUT), + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + /* The multiple "Capture Source" controls confuse alsamixer + * So call somewhat different.. + */ + /* .name = "Capture Source", */ + .name = "Input Source", + .count = 1, + .info = via_mux_enum_info, + .get = via_mux_enum_get, + .put = via_mux_enum_put, + }, + { } /* end */ +}; + +static struct hda_verb vt1702_volume_init_verbs[] = { + /* + * Unmute ADC0-1 and set the default input to mic-in + */ + {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x1F, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x20, 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 + */ + /* Amp Indices: Mic1 = 1, Line = 1, Mic2 = 3 */ + {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x1A, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(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_MUTE(4)}, + + /* Setup default input of PW4 to MW0 */ + {0x17, AC_VERB_SET_CONNECT_SEL, 0x1}, + /* PW6 PW7 Output enable */ + {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, + {0x1C, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, + { } +}; + +static struct hda_pcm_stream vt1702_pcm_analog_playback = { + .substreams = 1, + .channels_min = 2, + .channels_max = 2, + .nid = 0x10, /* NID to query formats and rates */ + .ops = { + .open = via_playback_pcm_open, + .prepare = via_playback_pcm_prepare, + .cleanup = via_playback_pcm_cleanup + }, +}; + +static struct hda_pcm_stream vt1702_pcm_analog_capture = { + .substreams = 3, + .channels_min = 2, + .channels_max = 2, + .nid = 0x12, /* NID to query formats and rates */ + .ops = { + .prepare = via_capture_pcm_prepare, + .cleanup = via_capture_pcm_cleanup + }, +}; + +static struct hda_pcm_stream vt1702_pcm_digital_playback = { + .substreams = 1, + .channels_min = 2, + .channels_max = 2, + /* NID is set in via_build_pcms */ + .ops = { + .open = via_dig_playback_pcm_open, + .close = via_dig_playback_pcm_close, + .prepare = via_dig_playback_pcm_prepare + }, +}; + +/* fill in the dac_nids table from the parsed pin configuration */ +static int vt1702_auto_fill_dac_nids(struct via_spec *spec, + const struct auto_pin_cfg *cfg) +{ + spec->multiout.num_dacs = 1; + spec->multiout.dac_nids = spec->private_dac_nids; + + if (cfg->line_out_pins[0]) { + /* config dac list */ + spec->multiout.dac_nids[0] = 0x10; + } + + return 0; +} + +/* add playback controls from the parsed DAC table */ +static int vt1702_auto_create_line_out_ctls(struct via_spec *spec, + const struct auto_pin_cfg *cfg) +{ + int err; + + if (!cfg->line_out_pins[0]) + return -1; + + /* add control to mixer index 0 */ + err = via_add_control(spec, VIA_CTL_WIDGET_VOL, + "Master Front Playback Volume", + HDA_COMPOSE_AMP_VAL(0x1A, 3, 0, HDA_INPUT)); + if (err < 0) + return err; + err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, + "Master Front Playback Switch", + HDA_COMPOSE_AMP_VAL(0x1A, 3, 0, HDA_INPUT)); + if (err < 0) + return err; + + /* Front */ + err = via_add_control(spec, VIA_CTL_WIDGET_VOL, + "Front Playback Volume", + HDA_COMPOSE_AMP_VAL(0x10, 3, 0, HDA_OUTPUT)); + if (err < 0) + return err; + err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, + "Front Playback Switch", + HDA_COMPOSE_AMP_VAL(0x16, 3, 0, HDA_OUTPUT)); + if (err < 0) + return err; + + return 0; +} + +static int vt1702_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) +{ + int err; + + if (!pin) + return 0; + + spec->multiout.hp_nid = 0x1D; + + err = via_add_control(spec, VIA_CTL_WIDGET_VOL, + "Headphone Playback Volume", + HDA_COMPOSE_AMP_VAL(0x1D, 3, 0, HDA_OUTPUT)); + if (err < 0) + return err; + + err = via_add_control(spec, VIA_CTL_WIDGET_MUTE, + "Headphone Playback Switch", + 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 vt1702_auto_create_analog_input_ctls(struct via_spec *spec, + const struct auto_pin_cfg *cfg) +{ + static char *labels[] = { + "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL + }; + struct hda_input_mux *imux = &spec->private_imux; + int i, err, idx = 0; + + /* for internal loopback recording select */ + imux->items[imux->num_items].label = "Stereo Mixer"; + imux->items[imux->num_items].index = 3; + imux->num_items++; + + for (i = 0; i < AUTO_PIN_LAST; i++) { + if (!cfg->input_pins[i]) + continue; + + switch (cfg->input_pins[i]) { + case 0x14: /* Mic */ + idx = 1; + break; + + case 0x15: /* Line In */ + idx = 2; + break; + + case 0x18: /* Front Mic */ + idx = 3; + break; + } + err = via_new_analog_input(spec, cfg->input_pins[i], + labels[i], idx, 0x1A); + if (err < 0) + return err; + imux->items[imux->num_items].label = labels[i]; + imux->items[imux->num_items].index = idx-1; + imux->num_items++; + } + return 0; +} + +static int vt1702_parse_auto_config(struct hda_codec *codec) +{ + struct via_spec *spec = codec->spec; + int err; + static hda_nid_t vt1702_ignore[] = {0x1C, 0}; + + err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, + vt1702_ignore); + if (err < 0) + return err; + err = vt1702_auto_fill_dac_nids(spec, &spec->autocfg); + if (err < 0) + return err; + if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0]) + return 0; /* can't find valid BIOS pin config */ + + err = vt1702_auto_create_line_out_ctls(spec, &spec->autocfg); + if (err < 0) + return err; + err = vt1702_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); + if (err < 0) + return err; + err = vt1702_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 = VT1702_DIGOUT_NID; + + if (spec->kctl_alloc) + spec->mixers[spec->num_mixers++] = spec->kctl_alloc; + + spec->input_mux = &spec->private_imux; + + return 1; +} + +#ifdef CONFIG_SND_HDA_POWER_SAVE +static struct hda_amp_list vt1702_loopbacks[] = { + { 0x1A, HDA_INPUT, 1 }, + { 0x1A, HDA_INPUT, 2 }, + { 0x1A, HDA_INPUT, 3 }, + { 0x1A, HDA_INPUT, 4 }, + { } /* end */ +}; +#endif + +static int patch_vt1702(struct hda_codec *codec) +{ + struct via_spec *spec; + int err; + unsigned int response; + unsigned char control; + + /* create a codec specific record */ + spec = kzalloc(sizeof(*spec), GFP_KERNEL); + if (spec == NULL) + return -ENOMEM; + + codec->spec = spec; + + /* automatic parse from the BIOS config */ + err = vt1702_parse_auto_config(codec); + if (err < 0) { + via_free(codec); + return err; + } else if (!err) { + printk(KERN_INFO "hda_codec: Cannot set up configuration " + "from BIOS. Using genenic mode...\n"); + } + + spec->init_verbs = vt1702_volume_init_verbs; + + spec->stream_name_analog = "VT1702 Analog"; + spec->stream_analog_playback = &vt1702_pcm_analog_playback; + spec->stream_analog_capture = &vt1702_pcm_analog_capture; + + spec->stream_name_digital = "VT1702 Digital"; + spec->stream_digital_playback = &vt1702_pcm_digital_playback; + + if (!spec->adc_nids && spec->input_mux) { + spec->adc_nids = vt1702_adc_nids; + spec->num_adc_nids = ARRAY_SIZE(vt1702_adc_nids); + spec->mixers[spec->num_mixers] = vt1702_capture_mixer; + spec->num_mixers++; + } + + codec->patch_ops = via_patch_ops; + + codec->patch_ops.init = via_auto_init; + +#ifdef CONFIG_SND_HDA_POWER_SAVE + spec->loopback.amplist = vt1702_loopbacks; +#endif + + /* Open backdoor */ + response = snd_hda_codec_read(codec, codec->afg, 0, 0xF8C, 0); + control = (unsigned char)(response & 0xff); + control |= 0x3; + snd_hda_codec_write(codec, codec->afg, 0, 0xF88, control); + + /* Enable GPIO 0&1 for volume&mute control */ + /* Enable GPIO 2 for DMIC-DATA */ + response = snd_hda_codec_read(codec, codec->afg, 0, 0xF84, 0); + control = (unsigned char)((response >> 16) & 0x3f); + snd_hda_codec_write(codec, codec->afg, 0, 0xF82, control); + + return 0; +} + /* * patch entries */ @@ -2051,5 +2773,37 @@ struct hda_codec_preset snd_hda_preset_via[] = { .patch = patch_vt1708B_4ch}, { .id = 0x1106E727, .name = "VIA VT1708B 4-Ch", .patch = patch_vt1708B_4ch}, + { .id = 0x11060397, .name = "VIA VT1708S", + .patch = patch_vt1708S}, + { .id = 0x11061397, .name = "VIA VT1708S", + .patch = patch_vt1708S}, + { .id = 0x11062397, .name = "VIA VT1708S", + .patch = patch_vt1708S}, + { .id = 0x11063397, .name = "VIA VT1708S", + .patch = patch_vt1708S}, + { .id = 0x11064397, .name = "VIA VT1708S", + .patch = patch_vt1708S}, + { .id = 0x11065397, .name = "VIA VT1708S", + .patch = patch_vt1708S}, + { .id = 0x11066397, .name = "VIA VT1708S", + .patch = patch_vt1708S}, + { .id = 0x11067397, .name = "VIA VT1708S", + .patch = patch_vt1708S}, + { .id = 0x11060398, .name = "VIA VT1702", + .patch = patch_vt1702}, + { .id = 0x11061398, .name = "VIA VT1702", + .patch = patch_vt1702}, + { .id = 0x11062398, .name = "VIA VT1702", + .patch = patch_vt1702}, + { .id = 0x11063398, .name = "VIA VT1702", + .patch = patch_vt1702}, + { .id = 0x11064398, .name = "VIA VT1702", + .patch = patch_vt1702}, + { .id = 0x11065398, .name = "VIA VT1702", + .patch = patch_vt1702}, + { .id = 0x11066398, .name = "VIA VT1702", + .patch = patch_vt1702}, + { .id = 0x11067398, .name = "VIA VT1702", + .patch = patch_vt1702}, {} /* terminator */ }; -- cgit v1.2.3 From 69e52a80916b39dcdc3667894040c187179fbf2e Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Tue, 9 Sep 2008 15:57:32 +0800 Subject: ALSA: HDA patch_via.c: Mute on headphone plug-in Signed-off-by: Harald Welte Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_via.c | 133 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 122 insertions(+), 11 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 91b72add1a8..4cad16c532c 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -32,6 +32,7 @@ /* 2007-11-14 Lydia Wang Add VT1708A codec HP and CD pin connect config */ /* 2008-02-03 Lydia Wang Fix Rear channels and Back channels inverse issue */ /* 2008-03-06 Lydia Wang Add VT1702 codec and VT1708S codec support */ +/* 2008-04-09 Lydia Wang Add mute front speaker when HP plugin */ /* */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ @@ -83,6 +84,9 @@ #define IS_VT1708S_VENDORID(x) ((x) >= 0x11060397 && (x) <= 0x11067397) #define IS_VT1702_VENDORID(x) ((x) >= 0x11060398 && (x) <= 0x11067398) +#define VIA_HP_EVENT 0x01 +#define VIA_GPIO_EVENT 0x02 + enum { VIA_CTL_WIDGET_VOL, VIA_CTL_WIDGET_MUTE, @@ -106,7 +110,8 @@ struct via_spec { struct snd_kcontrol_new *mixers[3]; unsigned int num_mixers; - struct hda_verb *init_verbs; + struct hda_verb *init_verbs[5]; + unsigned int num_iverbs; char *stream_name_analog; struct hda_pcm_stream *stream_analog_playback; @@ -605,10 +610,85 @@ static void via_free(struct hda_codec *codec) kfree(codec->spec); } +/* mute internal speaker if HP is plugged */ +static void via_hp_automute(struct hda_codec *codec) +{ + unsigned int present; + struct via_spec *spec = codec->spec; + + present = snd_hda_codec_read(codec, spec->autocfg.hp_pins[0], 0, + AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; + snd_hda_codec_amp_stereo(codec, spec->autocfg.line_out_pins[0], + HDA_OUTPUT, 0, HDA_AMP_MUTE, + present ? HDA_AMP_MUTE : 0); +} + +static void via_gpio_control(struct hda_codec *codec) +{ + unsigned int gpio_data; + unsigned int vol_counter; + unsigned int vol; + unsigned int master_vol; + + struct via_spec *spec = codec->spec; + + gpio_data = snd_hda_codec_read(codec, codec->afg, 0, + AC_VERB_GET_GPIO_DATA, 0) & 0x03; + + vol_counter = (snd_hda_codec_read(codec, codec->afg, 0, + 0xF84, 0) & 0x3F0000) >> 16; + + vol = vol_counter & 0x1F; + master_vol = snd_hda_codec_read(codec, 0x1A, 0, + AC_VERB_GET_AMP_GAIN_MUTE, + AC_AMP_GET_INPUT); + + if (gpio_data == 0x02) { + /* unmute line out */ + snd_hda_codec_amp_stereo(codec, spec->autocfg.line_out_pins[0], + HDA_OUTPUT, 0, HDA_AMP_MUTE, 0); + + if (vol_counter & 0x20) { + /* decrease volume */ + if (vol > master_vol) + vol = master_vol; + snd_hda_codec_amp_stereo(codec, 0x1A, HDA_INPUT, + 0, HDA_AMP_VOLMASK, + master_vol-vol); + } else { + /* increase volume */ + snd_hda_codec_amp_stereo(codec, 0x1A, HDA_INPUT, 0, + HDA_AMP_VOLMASK, + ((master_vol+vol) > 0x2A) ? 0x2A : + (master_vol+vol)); + } + } else if (!(gpio_data & 0x02)) { + /* mute line out */ + snd_hda_codec_amp_stereo(codec, + spec->autocfg.line_out_pins[0], + HDA_OUTPUT, 0, HDA_AMP_MUTE, + HDA_AMP_MUTE); + } +} + +/* unsolicited event for jack sensing */ +static void via_unsol_event(struct hda_codec *codec, + unsigned int res) +{ + res >>= 26; + if (res == VIA_HP_EVENT) + via_hp_automute(codec); + else if (res == VIA_GPIO_EVENT) + via_gpio_control(codec); +} + static int via_init(struct hda_codec *codec) { struct via_spec *spec = codec->spec; - snd_hda_sequence_write(codec, spec->init_verbs); + int i; + for (i = 0; i < spec->num_iverbs; i++) + snd_hda_sequence_write(codec, spec->init_verbs[i]); + /* Lydia Add for EAPD enable */ if (!spec->dig_in_nid) { /* No Digital In connection */ if (IS_VT1708_VENDORID(codec->vendor_id)) { @@ -924,7 +1004,7 @@ static int vt1708_parse_auto_config(struct hda_codec *codec) if (spec->kctl_alloc) spec->mixers[spec->num_mixers++] = spec->kctl_alloc; - spec->init_verbs = vt1708_volume_init_verbs; + spec->init_verbs[spec->num_iverbs++] = vt1708_volume_init_verbs; spec->input_mux = &spec->private_imux; @@ -1016,6 +1096,11 @@ static struct snd_kcontrol_new vt1709_capture_mixer[] = { { } /* end */ }; +static struct hda_verb vt1709_uniwill_init_verbs[] = { + {0x20, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_HP_EVENT}, + { } +}; + /* * generic initialization of ADC, input mixers and output mixers */ @@ -1425,7 +1510,8 @@ static int patch_vt1709_10ch(struct hda_codec *codec) "Using genenic mode...\n"); } - spec->init_verbs = vt1709_10ch_volume_init_verbs; + spec->init_verbs[spec->num_iverbs++] = vt1709_10ch_volume_init_verbs; + spec->init_verbs[spec->num_iverbs++] = vt1709_uniwill_init_verbs; spec->stream_name_analog = "VT1709 Analog"; spec->stream_analog_playback = &vt1709_10ch_pcm_analog_playback; @@ -1446,6 +1532,7 @@ static int patch_vt1709_10ch(struct hda_codec *codec) codec->patch_ops = via_patch_ops; codec->patch_ops.init = via_auto_init; + codec->patch_ops.unsol_event = via_unsol_event; #ifdef CONFIG_SND_HDA_POWER_SAVE spec->loopback.amplist = vt1709_loopbacks; #endif @@ -1516,7 +1603,8 @@ static int patch_vt1709_6ch(struct hda_codec *codec) "Using genenic mode...\n"); } - spec->init_verbs = vt1709_6ch_volume_init_verbs; + spec->init_verbs[spec->num_iverbs++] = vt1709_6ch_volume_init_verbs; + spec->init_verbs[spec->num_iverbs++] = vt1709_uniwill_init_verbs; spec->stream_name_analog = "VT1709 Analog"; spec->stream_analog_playback = &vt1709_6ch_pcm_analog_playback; @@ -1537,6 +1625,7 @@ static int patch_vt1709_6ch(struct hda_codec *codec) codec->patch_ops = via_patch_ops; codec->patch_ops.init = via_auto_init; + codec->patch_ops.unsol_event = via_unsol_event; #ifdef CONFIG_SND_HDA_POWER_SAVE spec->loopback.amplist = vt1709_loopbacks; #endif @@ -1636,6 +1725,11 @@ static struct hda_verb vt1708B_4ch_volume_init_verbs[] = { { } }; +static struct hda_verb vt1708B_uniwill_init_verbs[] = { + {0x1D, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_HP_EVENT}, + { } +}; + static struct hda_pcm_stream vt1708B_8ch_pcm_analog_playback = { .substreams = 1, .channels_min = 2, @@ -1956,7 +2050,8 @@ static int patch_vt1708B_8ch(struct hda_codec *codec) "from BIOS. Using genenic mode...\n"); } - spec->init_verbs = vt1708B_8ch_volume_init_verbs; + spec->init_verbs[spec->num_iverbs++] = vt1708B_8ch_volume_init_verbs; + spec->init_verbs[spec->num_iverbs++] = vt1708B_uniwill_init_verbs; spec->stream_name_analog = "VT1708B Analog"; spec->stream_analog_playback = &vt1708B_8ch_pcm_analog_playback; @@ -1976,6 +2071,7 @@ static int patch_vt1708B_8ch(struct hda_codec *codec) codec->patch_ops = via_patch_ops; codec->patch_ops.init = via_auto_init; + codec->patch_ops.unsol_event = via_unsol_event; #ifdef CONFIG_SND_HDA_POWER_SAVE spec->loopback.amplist = vt1708B_loopbacks; #endif @@ -2005,7 +2101,8 @@ static int patch_vt1708B_4ch(struct hda_codec *codec) "from BIOS. Using genenic mode...\n"); } - spec->init_verbs = vt1708B_4ch_volume_init_verbs; + spec->init_verbs[spec->num_iverbs++] = vt1708B_4ch_volume_init_verbs; + spec->init_verbs[spec->num_iverbs++] = vt1708B_uniwill_init_verbs; spec->stream_name_analog = "VT1708B Analog"; spec->stream_analog_playback = &vt1708B_4ch_pcm_analog_playback; @@ -2025,6 +2122,7 @@ static int patch_vt1708B_4ch(struct hda_codec *codec) codec->patch_ops = via_patch_ops; codec->patch_ops.init = via_auto_init; + codec->patch_ops.unsol_event = via_unsol_event; #ifdef CONFIG_SND_HDA_POWER_SAVE spec->loopback.amplist = vt1708B_loopbacks; #endif @@ -2078,6 +2176,11 @@ static struct hda_verb vt1708S_volume_init_verbs[] = { { } }; +static struct hda_verb vt1708S_uniwill_init_verbs[] = { + {0x1D, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_HP_EVENT}, + { } +}; + static struct hda_pcm_stream vt1708S_pcm_analog_playback = { .substreams = 2, .channels_min = 2, @@ -2387,7 +2490,8 @@ static int patch_vt1708S(struct hda_codec *codec) "from BIOS. Using genenic mode...\n"); } - spec->init_verbs = vt1708S_volume_init_verbs; + spec->init_verbs[spec->num_iverbs++] = vt1708S_volume_init_verbs; + spec->init_verbs[spec->num_iverbs++] = vt1708S_uniwill_init_verbs; spec->stream_name_analog = "VT1708S Analog"; spec->stream_analog_playback = &vt1708S_pcm_analog_playback; @@ -2406,7 +2510,7 @@ static int patch_vt1708S(struct hda_codec *codec) codec->patch_ops = via_patch_ops; codec->patch_ops.init = via_auto_init; - + codec->patch_ops.unsol_event = via_unsol_event; #ifdef CONFIG_SND_HDA_POWER_SAVE spec->loopback.amplist = vt1708S_loopbacks; #endif @@ -2468,6 +2572,12 @@ static struct hda_verb vt1702_volume_init_verbs[] = { { } }; +static struct hda_verb vt1702_uniwill_init_verbs[] = { + {0x01, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_GPIO_EVENT}, + {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_HP_EVENT}, + { } +}; + static struct hda_pcm_stream vt1702_pcm_analog_playback = { .substreams = 1, .channels_min = 2, @@ -2694,7 +2804,8 @@ static int patch_vt1702(struct hda_codec *codec) "from BIOS. Using genenic mode...\n"); } - spec->init_verbs = vt1702_volume_init_verbs; + spec->init_verbs[spec->num_iverbs++] = vt1702_volume_init_verbs; + spec->init_verbs[spec->num_iverbs++] = vt1702_uniwill_init_verbs; spec->stream_name_analog = "VT1702 Analog"; spec->stream_analog_playback = &vt1702_pcm_analog_playback; @@ -2713,7 +2824,7 @@ static int patch_vt1702(struct hda_codec *codec) codec->patch_ops = via_patch_ops; codec->patch_ops.init = via_auto_init; - + codec->patch_ops.unsol_event = via_unsol_event; #ifdef CONFIG_SND_HDA_POWER_SAVE spec->loopback.amplist = vt1702_loopbacks; #endif -- cgit v1.2.3 From 0aa62aef611006704226095bad9cd80246ce00c9 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Tue, 9 Sep 2008 15:58:27 +0800 Subject: ALSA: HDA patch_via.c: Independent DAC for headphone This mode allows an output stream to have two substreams, one for the speakers and one for the headphone. Each of the substreams has independent PCM data and uses a different DAC. Signed-off-by: Harald Welte Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_via.c | 304 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 281 insertions(+), 23 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 4cad16c532c..4e4d2c5b261 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -33,6 +33,7 @@ /* 2008-02-03 Lydia Wang Fix Rear channels and Back channels inverse issue */ /* 2008-03-06 Lydia Wang Add VT1702 codec and VT1708S codec support */ /* 2008-04-09 Lydia Wang Add mute front speaker when HP plugin */ +/* 2008-04-09 Lydia Wang Add Independent HP feature */ /* */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ @@ -41,6 +42,7 @@ #include #include #include +#include #include "hda_codec.h" #include "hda_local.h" #include "hda_patch.h" @@ -140,9 +142,13 @@ struct via_spec { struct auto_pin_cfg autocfg; unsigned int num_kctl_alloc, num_kctl_used; struct snd_kcontrol_new *kctl_alloc; - struct hda_input_mux private_imux; + struct hda_input_mux private_imux[2]; hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; + /* HP mode source */ + const struct hda_input_mux *hp_mux; + unsigned int hp_independent_mode; + #ifdef CONFIG_SND_HDA_POWER_SAVE struct hda_loopback_check loopback; #endif @@ -326,6 +332,92 @@ static int via_mux_enum_put(struct snd_kcontrol *kcontrol, &spec->cur_mux[adc_idx]); } +static int via_independent_hp_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct via_spec *spec = codec->spec; + return snd_hda_input_mux_info(spec->hp_mux, uinfo); +} + +static int via_independent_hp_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct via_spec *spec = codec->spec; + hda_nid_t nid = spec->autocfg.hp_pins[0]; + unsigned int pinsel = snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_CONNECT_SEL, + 0x00); + + ucontrol->value.enumerated.item[0] = pinsel; + + return 0; +} + +static int via_independent_hp_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct via_spec *spec = codec->spec; + hda_nid_t nid = spec->autocfg.hp_pins[0]; + unsigned int pinsel = ucontrol->value.enumerated.item[0]; + unsigned int con_nid = snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_CONNECT_LIST, 0) & 0xff; + + if (con_nid == spec->multiout.hp_nid) { + if (pinsel == 0) { + if (!spec->hp_independent_mode) { + if (spec->multiout.num_dacs > 1) + spec->multiout.num_dacs -= 1; + spec->hp_independent_mode = 1; + } + } else if (pinsel == 1) { + if (spec->hp_independent_mode) { + if (spec->multiout.num_dacs > 1) + spec->multiout.num_dacs += 1; + spec->hp_independent_mode = 0; + } + } + } else { + if (pinsel == 0) { + if (spec->hp_independent_mode) { + if (spec->multiout.num_dacs > 1) + spec->multiout.num_dacs += 1; + spec->hp_independent_mode = 0; + } + } else if (pinsel == 1) { + if (!spec->hp_independent_mode) { + if (spec->multiout.num_dacs > 1) + spec->multiout.num_dacs -= 1; + spec->hp_independent_mode = 1; + } + } + } + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, + pinsel); + + if (spec->multiout.hp_nid && + spec->multiout.hp_nid != spec->multiout.dac_nids[HDA_FRONT]) + snd_hda_codec_setup_stream(codec, + spec->multiout.hp_nid, + 0, 0, 0); + + return 0; +} + +static struct snd_kcontrol_new via_hp_mixer[] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Independent HP", + .count = 1, + .info = via_independent_hp_info, + .get = via_independent_hp_get, + .put = via_independent_hp_put, + }, + { } /* end */ +}; + /* capture mixer elements */ static struct snd_kcontrol_new vt1708_capture_mixer[] = { HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT), @@ -410,6 +502,138 @@ static int via_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); } + +static void playback_multi_pcm_prep_0(struct hda_codec *codec, + unsigned int stream_tag, + unsigned int format, + struct snd_pcm_substream *substream) +{ + struct via_spec *spec = codec->spec; + struct hda_multi_out *mout = &spec->multiout; + hda_nid_t *nids = mout->dac_nids; + int chs = substream->runtime->channels; + int i; + + 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)) { + mout->dig_out_used = HDA_DIG_ANALOG_DUP; + /* turn off SPDIF once; otherwise the IEC958 bits won't + * be updated */ + if (codec->spdif_ctls & AC_DIG1_ENABLE) + snd_hda_codec_write(codec, mout->dig_out_nid, 0, + AC_VERB_SET_DIGI_CONVERT_1, + codec->spdif_ctls & + ~AC_DIG1_ENABLE & 0xff); + snd_hda_codec_setup_stream(codec, mout->dig_out_nid, + stream_tag, 0, format); + /* turn on again (if needed) */ + if (codec->spdif_ctls & AC_DIG1_ENABLE) + snd_hda_codec_write(codec, mout->dig_out_nid, 0, + AC_VERB_SET_DIGI_CONVERT_1, + codec->spdif_ctls & 0xff); + } else { + mout->dig_out_used = 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); + + if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT] && + !spec->hp_independent_mode) + /* headphone out will just decode front left/right (stereo) */ + 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]) + snd_hda_codec_setup_stream(codec, + mout->extra_out_nid[i], + stream_tag, 0, format); + + /* 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); + else /* copy front */ + snd_hda_codec_setup_stream(codec, nids[i], stream_tag, + 0, format); + } +} + +static int via_playback_multi_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; + struct hda_multi_out *mout = &spec->multiout; + hda_nid_t *nids = mout->dac_nids; + + if (substream->number == 0) + playback_multi_pcm_prep_0(codec, stream_tag, format, + substream); + else { + if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT] && + spec->hp_independent_mode) + snd_hda_codec_setup_stream(codec, mout->hp_nid, + stream_tag, 0, format); + } + + return 0; +} + +static int via_playback_multi_pcm_cleanup(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + struct snd_pcm_substream *substream) +{ + struct via_spec *spec = codec->spec; + struct hda_multi_out *mout = &spec->multiout; + hda_nid_t *nids = mout->dac_nids; + int i; + + if (substream->number == 0) { + for (i = 0; i < mout->num_dacs; i++) + snd_hda_codec_setup_stream(codec, nids[i], 0, 0, 0); + + if (mout->hp_nid && !spec->hp_independent_mode) + snd_hda_codec_setup_stream(codec, mout->hp_nid, + 0, 0, 0); + + for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++) + if (mout->extra_out_nid[i]) + snd_hda_codec_setup_stream(codec, + mout->extra_out_nid[i], + 0, 0, 0); + mutex_lock(&codec->spdif_mutex); + if (mout->dig_out_nid && + mout->dig_out_used == HDA_DIG_ANALOG_DUP) { + snd_hda_codec_setup_stream(codec, mout->dig_out_nid, + 0, 0, 0); + mout->dig_out_used = 0; + } + mutex_unlock(&codec->spdif_mutex); + } else { + if (mout->hp_nid && mout->hp_nid != nids[HDA_FRONT] && + spec->hp_independent_mode) + snd_hda_codec_setup_stream(codec, mout->hp_nid, + 0, 0, 0); + } + + return 0; +} + /* * Digital out */ @@ -466,14 +690,14 @@ static int via_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, } static struct hda_pcm_stream vt1708_pcm_analog_playback = { - .substreams = 1, + .substreams = 2, .channels_min = 2, .channels_max = 8, .nid = 0x10, /* NID to query formats and rates */ .ops = { .open = via_playback_pcm_open, - .prepare = via_playback_pcm_prepare, - .cleanup = via_playback_pcm_cleanup + .prepare = via_playback_multi_pcm_prepare, + .cleanup = via_playback_multi_pcm_cleanup }, }; @@ -865,6 +1089,24 @@ static int vt1708_auto_create_multi_out_ctls(struct via_spec *spec, return 0; } +static void create_hp_imux(struct via_spec *spec) +{ + int i; + struct hda_input_mux *imux = &spec->private_imux[1]; + static const char *texts[] = { "OFF", "ON", NULL}; + + /* for hp mode select */ + i = 0; + while (texts[i] != NULL) { + imux->items[imux->num_items].label = texts[i]; + imux->items[imux->num_items].index = i; + imux->num_items++; + i++; + } + + spec->hp_mux = &spec->private_imux[1]; +} + static int vt1708_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) { int err; @@ -885,6 +1127,8 @@ static int vt1708_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) if (err < 0) return err; + create_hp_imux(spec); + return 0; } @@ -895,7 +1139,7 @@ static int vt1708_auto_create_analog_input_ctls(struct via_spec *spec, static char *labels[] = { "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL }; - struct hda_input_mux *imux = &spec->private_imux; + struct hda_input_mux *imux = &spec->private_imux[0]; int i, err, idx = 0; /* for internal loopback recording select */ @@ -1006,7 +1250,9 @@ static int vt1708_parse_auto_config(struct hda_codec *codec) spec->init_verbs[spec->num_iverbs++] = vt1708_volume_init_verbs; - spec->input_mux = &spec->private_imux; + spec->input_mux = &spec->private_imux[0]; + + spec->mixers[spec->num_mixers++] = via_hp_mixer; return 1; } @@ -1400,7 +1646,7 @@ static int vt1709_auto_create_analog_input_ctls(struct via_spec *spec, static char *labels[] = { "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL }; - struct hda_input_mux *imux = &spec->private_imux; + struct hda_input_mux *imux = &spec->private_imux[0]; int i, err, idx = 0; /* for internal loopback recording select */ @@ -1474,7 +1720,7 @@ static int vt1709_parse_auto_config(struct hda_codec *codec) if (spec->kctl_alloc) spec->mixers[spec->num_mixers++] = spec->kctl_alloc; - spec->input_mux = &spec->private_imux; + spec->input_mux = &spec->private_imux[0]; return 1; } @@ -1731,26 +1977,26 @@ static struct hda_verb vt1708B_uniwill_init_verbs[] = { }; static struct hda_pcm_stream vt1708B_8ch_pcm_analog_playback = { - .substreams = 1, + .substreams = 2, .channels_min = 2, .channels_max = 8, .nid = 0x10, /* NID to query formats and rates */ .ops = { .open = via_playback_pcm_open, - .prepare = via_playback_pcm_prepare, - .cleanup = via_playback_pcm_cleanup + .prepare = via_playback_multi_pcm_prepare, + .cleanup = via_playback_multi_pcm_cleanup }, }; static struct hda_pcm_stream vt1708B_4ch_pcm_analog_playback = { - .substreams = 1, + .substreams = 2, .channels_min = 2, .channels_max = 4, .nid = 0x10, /* NID to query formats and rates */ .ops = { .open = via_playback_pcm_open, - .prepare = via_playback_pcm_prepare, - .cleanup = via_playback_pcm_cleanup + .prepare = via_playback_multi_pcm_prepare, + .cleanup = via_playback_multi_pcm_cleanup }, }; @@ -1929,6 +2175,8 @@ static int vt1708B_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) if (err < 0) return err; + create_hp_imux(spec); + return 0; } @@ -1939,7 +2187,7 @@ static int vt1708B_auto_create_analog_input_ctls(struct via_spec *spec, static char *labels[] = { "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL }; - struct hda_input_mux *imux = &spec->private_imux; + struct hda_input_mux *imux = &spec->private_imux[0]; int i, err, idx = 0; /* for internal loopback recording select */ @@ -2013,7 +2261,9 @@ static int vt1708B_parse_auto_config(struct hda_codec *codec) if (spec->kctl_alloc) spec->mixers[spec->num_mixers++] = spec->kctl_alloc; - spec->input_mux = &spec->private_imux; + spec->input_mux = &spec->private_imux[0]; + + spec->mixers[spec->num_mixers++] = via_hp_mixer; return 1; } @@ -2369,6 +2619,8 @@ static int vt1708S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) if (err < 0) return err; + create_hp_imux(spec); + return 0; } @@ -2379,7 +2631,7 @@ static int vt1708S_auto_create_analog_input_ctls(struct via_spec *spec, static char *labels[] = { "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL }; - struct hda_input_mux *imux = &spec->private_imux; + struct hda_input_mux *imux = &spec->private_imux[0]; int i, err, idx = 0; /* for internal loopback recording select */ @@ -2453,7 +2705,9 @@ static int vt1708S_parse_auto_config(struct hda_codec *codec) if (spec->kctl_alloc) spec->mixers[spec->num_mixers++] = spec->kctl_alloc; - spec->input_mux = &spec->private_imux; + spec->input_mux = &spec->private_imux[0]; + + spec->mixers[spec->num_mixers++] = via_hp_mixer; return 1; } @@ -2579,14 +2833,14 @@ static struct hda_verb vt1702_uniwill_init_verbs[] = { }; static struct hda_pcm_stream vt1702_pcm_analog_playback = { - .substreams = 1, + .substreams = 2, .channels_min = 2, .channels_max = 2, .nid = 0x10, /* NID to query formats and rates */ .ops = { .open = via_playback_pcm_open, - .prepare = via_playback_pcm_prepare, - .cleanup = via_playback_pcm_cleanup + .prepare = via_playback_multi_pcm_prepare, + .cleanup = via_playback_multi_pcm_cleanup }, }; @@ -2685,6 +2939,8 @@ static int vt1702_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) if (err < 0) return err; + create_hp_imux(spec); + return 0; } @@ -2695,7 +2951,7 @@ static int vt1702_auto_create_analog_input_ctls(struct via_spec *spec, static char *labels[] = { "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux", NULL }; - struct hda_input_mux *imux = &spec->private_imux; + struct hda_input_mux *imux = &spec->private_imux[0]; int i, err, idx = 0; /* for internal loopback recording select */ @@ -2765,7 +3021,9 @@ static int vt1702_parse_auto_config(struct hda_codec *codec) if (spec->kctl_alloc) spec->mixers[spec->num_mixers++] = spec->kctl_alloc; - spec->input_mux = &spec->private_imux; + spec->input_mux = &spec->private_imux[0]; + + spec->mixers[spec->num_mixers++] = via_hp_mixer; return 1; } -- cgit v1.2.3 From 98aa34c0501f78bf7d3de82d96d27f4a2b450477 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Tue, 9 Sep 2008 16:02:09 +0800 Subject: ALSA: HDA patch_via.c: Second S/PDIF (HDMI) support The VT1702 and VT1708S have a second S/PDIF output which is used to connect to a HDMI transmitter. This patch adds support for it. Signed-off-by: Harald Welte Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_via.c | 81 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 80 insertions(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 4e4d2c5b261..6e360d39c02 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -34,6 +34,7 @@ /* 2008-03-06 Lydia Wang Add VT1702 codec and VT1708S codec support */ /* 2008-04-09 Lydia Wang Add mute front speaker when HP plugin */ /* 2008-04-09 Lydia Wang Add Independent HP feature */ +/* 2008-05-28 Lydia Wang Add second S/PDIF Out support for VT1702 */ /* */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ @@ -122,9 +123,11 @@ struct via_spec { char *stream_name_digital; struct hda_pcm_stream *stream_digital_playback; struct hda_pcm_stream *stream_digital_capture; + struct hda_pcm_stream *stream_extra_digital_playback; /* playback */ struct hda_multi_out multiout; + hda_nid_t extra_dig_out_nid; /* capture */ unsigned int num_adc_nids; @@ -136,7 +139,7 @@ struct via_spec { unsigned int cur_mux[3]; /* PCM information */ - struct hda_pcm pcm_rec[2]; + struct hda_pcm pcm_rec[3]; /* dynamic controls, init_verbs and input_mux */ struct auto_pin_cfg autocfg; @@ -664,6 +667,36 @@ static int via_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, stream_tag, format, substream); } +/* setup SPDIF output stream */ +static void setup_dig_playback_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); +} + +static int via_extra_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; + + mutex_lock(&codec->spdif_mutex); + setup_dig_playback_stream(codec, spec->extra_dig_out_nid, stream_tag, + format); + mutex_unlock(&codec->spdif_mutex); + return 0; +} + /* * Analog capture */ @@ -769,6 +802,13 @@ static int via_build_controls(struct hda_codec *codec) if (err < 0) return err; spec->multiout.share_spdif = 1; + + if (spec->extra_dig_out_nid) { + err = snd_hda_create_spdif_out_ctls(codec, + spec->extra_dig_out_nid); + if (err < 0) + return err; + } } if (spec->dig_in_nid) { err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); @@ -814,6 +854,17 @@ static int via_build_pcms(struct hda_codec *codec) } } + if (spec->extra_dig_out_nid) { + codec->num_pcms++; + info++; + info->name = spec->stream_name_digital; + info->pcm_type = HDA_PCM_TYPE_HDMI; + info->stream[SNDRV_PCM_STREAM_PLAYBACK] = + *(spec->stream_extra_digital_playback); + info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = + spec->extra_dig_out_nid; + } + return 0; } @@ -2466,6 +2517,16 @@ static struct hda_pcm_stream vt1708S_pcm_digital_playback = { }, }; +static struct hda_pcm_stream vt1708S_pcm_extra_digital_playback = { + .substreams = 1, + .channels_min = 2, + .channels_max = 2, + /* NID is set in via_build_pcms */ + .ops = { + .prepare = via_extra_dig_playback_pcm_prepare + }, +}; + /* fill in the dac_nids table from the parsed pin configuration */ static int vt1708S_auto_fill_dac_nids(struct via_spec *spec, const struct auto_pin_cfg *cfg) @@ -2702,6 +2763,8 @@ static int vt1708S_parse_auto_config(struct hda_codec *codec) if (spec->autocfg.dig_out_pin) spec->multiout.dig_out_nid = VT1708S_DIGOUT_NID; + spec->extra_dig_out_nid = 0x15; + if (spec->kctl_alloc) spec->mixers[spec->num_mixers++] = spec->kctl_alloc; @@ -2753,6 +2816,8 @@ static int patch_vt1708S(struct hda_codec *codec) spec->stream_name_digital = "VT1708S Digital"; spec->stream_digital_playback = &vt1708S_pcm_digital_playback; + spec->stream_extra_digital_playback = + &vt1708S_pcm_extra_digital_playback; if (!spec->adc_nids && spec->input_mux) { spec->adc_nids = vt1708S_adc_nids; @@ -2867,6 +2932,16 @@ static struct hda_pcm_stream vt1702_pcm_digital_playback = { }, }; +static struct hda_pcm_stream vt1702_pcm_extra_digital_playback = { + .substreams = 1, + .channels_min = 2, + .channels_max = 2, + /* NID is set in via_build_pcms */ + .ops = { + .prepare = via_extra_dig_playback_pcm_prepare + }, +}; + /* fill in the dac_nids table from the parsed pin configuration */ static int vt1702_auto_fill_dac_nids(struct via_spec *spec, const struct auto_pin_cfg *cfg) @@ -3018,6 +3093,8 @@ static int vt1702_parse_auto_config(struct hda_codec *codec) if (spec->autocfg.dig_out_pin) spec->multiout.dig_out_nid = VT1702_DIGOUT_NID; + spec->extra_dig_out_nid = 0x1B; + if (spec->kctl_alloc) spec->mixers[spec->num_mixers++] = spec->kctl_alloc; @@ -3071,6 +3148,8 @@ static int patch_vt1702(struct hda_codec *codec) spec->stream_name_digital = "VT1702 Digital"; spec->stream_digital_playback = &vt1702_pcm_digital_playback; + spec->stream_extra_digital_playback = + &vt1702_pcm_extra_digital_playback; if (!spec->adc_nids && spec->input_mux) { spec->adc_nids = vt1702_adc_nids; -- cgit v1.2.3 From 6627bea10e8b31cdedd3a59a311d9ad1e010059a Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 22 Sep 2008 08:53:31 +0200 Subject: ALSA: oxygen: use SPDIF channel status symbols When setting the SPDIF channel status sample rate field, use the recently defined symbols instead of magic numbers. Signed-off-by: Clemens Ladisch --- sound/pci/oxygen/oxygen_mixer.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c index 05eb8994c14..99c422ceb20 100644 --- a/sound/pci/oxygen/oxygen_mixer.c +++ b/sound/pci/oxygen/oxygen_mixer.c @@ -211,13 +211,13 @@ static unsigned int oxygen_spdif_rate(unsigned int oxygen_rate) case OXYGEN_RATE_64000: return 0xb << OXYGEN_SPDIF_CS_RATE_SHIFT; case OXYGEN_RATE_88200: - return 0x8 << OXYGEN_SPDIF_CS_RATE_SHIFT; + return IEC958_AES3_CON_FS_88200 << OXYGEN_SPDIF_CS_RATE_SHIFT; case OXYGEN_RATE_96000: - return 0xa << OXYGEN_SPDIF_CS_RATE_SHIFT; + return IEC958_AES3_CON_FS_96000 << OXYGEN_SPDIF_CS_RATE_SHIFT; case OXYGEN_RATE_176400: - return 0xc << OXYGEN_SPDIF_CS_RATE_SHIFT; + return IEC958_AES3_CON_FS_176400 << OXYGEN_SPDIF_CS_RATE_SHIFT; case OXYGEN_RATE_192000: - return 0xe << OXYGEN_SPDIF_CS_RATE_SHIFT; + return IEC958_AES3_CON_FS_192000 << OXYGEN_SPDIF_CS_RATE_SHIFT; } } -- cgit v1.2.3 From 9bd6a73aef955216816fd6e28f371a868ed073d5 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 22 Sep 2008 08:55:19 +0200 Subject: ALSA: oxygen: use a copy of the model struct Put a copy of the model structure into the chip structure so that model- specific drivers can modify it depending on a particular device instance. Signed-off-by: Clemens Ladisch --- sound/pci/oxygen/oxygen.h | 72 ++++++++++++++++++++--------------------- sound/pci/oxygen/oxygen_lib.c | 54 +++++++++++++++---------------- sound/pci/oxygen/oxygen_mixer.c | 40 +++++++++++------------ sound/pci/oxygen/oxygen_pcm.c | 42 ++++++++++++------------ 4 files changed, 104 insertions(+), 104 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h index 74a64488007..5f3fbf80222 100644 --- a/sound/pci/oxygen/oxygen.h +++ b/sound/pci/oxygen/oxygen.h @@ -51,42 +51,7 @@ struct snd_pcm_hardware; struct snd_pcm_hw_params; struct snd_kcontrol_new; struct snd_rawmidi; -struct oxygen_model; - -struct oxygen { - unsigned long addr; - spinlock_t reg_lock; - struct mutex mutex; - struct snd_card *card; - struct pci_dev *pci; - struct snd_rawmidi *midi; - int irq; - const struct oxygen_model *model; - void *model_data; - unsigned int interrupt_mask; - u8 dac_volume[8]; - u8 dac_mute; - u8 pcm_active; - u8 pcm_running; - u8 dac_routing; - u8 spdif_playback_enable; - u8 revision; - u8 has_ac97_0; - u8 has_ac97_1; - u32 spdif_bits; - u32 spdif_pcm_bits; - struct snd_pcm_substream *streams[PCM_COUNT]; - struct snd_kcontrol *controls[CONTROL_COUNT]; - struct work_struct spdif_input_bits_work; - struct work_struct gpio_work; - wait_queue_head_t ac97_waitqueue; - union { - u8 _8[OXYGEN_IO_SIZE]; - __le16 _16[OXYGEN_IO_SIZE / 2]; - __le32 _32[OXYGEN_IO_SIZE / 4]; - } saved_registers; - u16 saved_ac97_registers[2][0x40]; -}; +struct oxygen; struct oxygen_model { const char *shortname; @@ -122,6 +87,41 @@ struct oxygen_model { u16 adc_i2s_format; }; +struct oxygen { + unsigned long addr; + spinlock_t reg_lock; + struct mutex mutex; + struct snd_card *card; + struct pci_dev *pci; + struct snd_rawmidi *midi; + int irq; + void *model_data; + unsigned int interrupt_mask; + u8 dac_volume[8]; + u8 dac_mute; + u8 pcm_active; + u8 pcm_running; + u8 dac_routing; + u8 spdif_playback_enable; + u8 revision; + u8 has_ac97_0; + u8 has_ac97_1; + u32 spdif_bits; + u32 spdif_pcm_bits; + struct snd_pcm_substream *streams[PCM_COUNT]; + struct snd_kcontrol *controls[CONTROL_COUNT]; + struct work_struct spdif_input_bits_work; + struct work_struct gpio_work; + wait_queue_head_t ac97_waitqueue; + union { + u8 _8[OXYGEN_IO_SIZE]; + __le16 _16[OXYGEN_IO_SIZE / 2]; + __le32 _32[OXYGEN_IO_SIZE / 4]; + } saved_registers; + u16 saved_ac97_registers[2][0x40]; + struct oxygen_model model; +}; + /* oxygen_lib.c */ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id, diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c index 22f37851045..07b0563cc90 100644 --- a/sound/pci/oxygen/oxygen_lib.c +++ b/sound/pci/oxygen/oxygen_lib.c @@ -161,8 +161,8 @@ static void oxygen_gpio_changed(struct work_struct *work) { struct oxygen *chip = container_of(work, struct oxygen, gpio_work); - if (chip->model->gpio_changed) - chip->model->gpio_changed(chip); + if (chip->model.gpio_changed) + chip->model.gpio_changed(chip); } #ifdef CONFIG_PROC_FS @@ -221,7 +221,7 @@ static void oxygen_init(struct oxygen *chip) chip->dac_routing = 1; for (i = 0; i < 8; ++i) - chip->dac_volume[i] = chip->model->dac_volume_min; + chip->dac_volume[i] = chip->model.dac_volume_min; chip->dac_mute = 1; chip->spdif_playback_enable = 1; chip->spdif_bits = OXYGEN_SPDIF_C | OXYGEN_SPDIF_ORIGINAL | @@ -243,7 +243,7 @@ static void oxygen_init(struct oxygen *chip) oxygen_write8_masked(chip, OXYGEN_FUNCTION, OXYGEN_FUNCTION_RESET_CODEC | - chip->model->function_flags, + chip->model.function_flags, OXYGEN_FUNCTION_RESET_CODEC | OXYGEN_FUNCTION_2WIRE_SPI_MASK | OXYGEN_FUNCTION_ENABLE_SPI_4_5); @@ -255,7 +255,7 @@ static void oxygen_init(struct oxygen *chip) OXYGEN_DMA_MULTICH_BURST_8); oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, 0); oxygen_write8_masked(chip, OXYGEN_MISC, - chip->model->misc_flags, + chip->model.misc_flags, OXYGEN_MISC_WRITE_PCI_SUBID | OXYGEN_MISC_REC_C_FROM_SPDIF | OXYGEN_MISC_REC_B_FROM_AC97 | @@ -270,21 +270,21 @@ static void oxygen_init(struct oxygen *chip) (OXYGEN_FORMAT_16 << OXYGEN_MULTICH_FORMAT_SHIFT)); oxygen_write8(chip, OXYGEN_REC_CHANNELS, OXYGEN_REC_CHANNELS_2_2_2); oxygen_write16(chip, OXYGEN_I2S_MULTICH_FORMAT, - OXYGEN_RATE_48000 | chip->model->dac_i2s_format | + OXYGEN_RATE_48000 | chip->model.dac_i2s_format | OXYGEN_I2S_MCLK_256 | OXYGEN_I2S_BITS_16 | OXYGEN_I2S_MASTER | OXYGEN_I2S_BCLK_64); - if (chip->model->pcm_dev_cfg & CAPTURE_0_FROM_I2S_1) + if (chip->model.pcm_dev_cfg & CAPTURE_0_FROM_I2S_1) oxygen_write16(chip, OXYGEN_I2S_A_FORMAT, - OXYGEN_RATE_48000 | chip->model->adc_i2s_format | + OXYGEN_RATE_48000 | chip->model.adc_i2s_format | OXYGEN_I2S_MCLK_256 | OXYGEN_I2S_BITS_16 | OXYGEN_I2S_MASTER | OXYGEN_I2S_BCLK_64); else oxygen_write16(chip, OXYGEN_I2S_A_FORMAT, OXYGEN_I2S_MASTER | OXYGEN_I2S_MUTE_MCLK); - if (chip->model->pcm_dev_cfg & (CAPTURE_0_FROM_I2S_2 | - CAPTURE_2_FROM_I2S_2)) + if (chip->model.pcm_dev_cfg & (CAPTURE_0_FROM_I2S_2 | + CAPTURE_2_FROM_I2S_2)) oxygen_write16(chip, OXYGEN_I2S_B_FORMAT, - OXYGEN_RATE_48000 | chip->model->adc_i2s_format | + OXYGEN_RATE_48000 | chip->model.adc_i2s_format | OXYGEN_I2S_MCLK_256 | OXYGEN_I2S_BITS_16 | OXYGEN_I2S_MASTER | OXYGEN_I2S_BCLK_64); else @@ -295,7 +295,7 @@ static void oxygen_init(struct oxygen *chip) oxygen_clear_bits32(chip, OXYGEN_SPDIF_CONTROL, OXYGEN_SPDIF_OUT_ENABLE | OXYGEN_SPDIF_LOOPBACK); - if (chip->model->pcm_dev_cfg & CAPTURE_1_FROM_SPDIF) + if (chip->model.pcm_dev_cfg & CAPTURE_1_FROM_SPDIF) oxygen_write32_masked(chip, OXYGEN_SPDIF_CONTROL, OXYGEN_SPDIF_SENSE_MASK | OXYGEN_SPDIF_LOCK_MASK | @@ -417,7 +417,7 @@ static void oxygen_card_free(struct snd_card *card) if (chip->irq >= 0) free_irq(chip->irq, chip); flush_scheduled_work(); - chip->model->cleanup(chip); + chip->model.cleanup(chip); mutex_destroy(&chip->mutex); pci_release_regions(chip->pci); pci_disable_device(chip->pci); @@ -439,7 +439,7 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id, chip->card = card; chip->pci = pci; chip->irq = -1; - chip->model = model; + chip->model = *model; chip->model_data = chip + 1; spin_lock_init(&chip->reg_lock); mutex_init(&chip->mutex); @@ -471,22 +471,22 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id, card->private_free = oxygen_card_free; oxygen_init(chip); - model->init(chip); + chip->model.init(chip); err = request_irq(pci->irq, oxygen_interrupt, IRQF_SHARED, - model->chip, chip); + chip->model.chip, chip); if (err < 0) { snd_printk(KERN_ERR "cannot grab interrupt %d\n", pci->irq); goto err_card; } chip->irq = pci->irq; - strcpy(card->driver, model->chip); - strcpy(card->shortname, model->shortname); + strcpy(card->driver, chip->model.chip); + strcpy(card->shortname, chip->model.shortname); sprintf(card->longname, "%s (rev %u) at %#lx, irq %i", - model->longname, chip->revision, chip->addr, chip->irq); - strcpy(card->mixername, model->chip); - snd_component_add(card, model->chip); + chip->model.longname, chip->revision, chip->addr, chip->irq); + strcpy(card->mixername, chip->model.chip); + snd_component_add(card, chip->model.chip); err = oxygen_pcm_init(chip); if (err < 0) @@ -496,7 +496,7 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id, if (err < 0) goto err_card; - if (model->misc_flags & OXYGEN_MISC_MIDI) { + if (chip->model.misc_flags & OXYGEN_MISC_MIDI) { err = snd_mpu401_uart_new(card, 0, MPU401_HW_CMIPCI, chip->addr + OXYGEN_MPU401, MPU401_INFO_INTEGRATED, 0, 0, @@ -508,7 +508,7 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id, oxygen_proc_init(chip); spin_lock_irq(&chip->reg_lock); - if (chip->model->pcm_dev_cfg & CAPTURE_1_FROM_SPDIF) + if (chip->model.pcm_dev_cfg & CAPTURE_1_FROM_SPDIF) chip->interrupt_mask |= OXYGEN_INT_SPDIF_IN_DETECT; if (chip->has_ac97_0 | chip->has_ac97_1) chip->interrupt_mask |= OXYGEN_INT_AC97; @@ -552,8 +552,8 @@ int oxygen_pci_suspend(struct pci_dev *pci, pm_message_t state) if (chip->streams[i]) snd_pcm_suspend(chip->streams[i]); - if (chip->model->suspend) - chip->model->suspend(chip); + if (chip->model.suspend) + chip->model.suspend(chip); spin_lock_irq(&chip->reg_lock); saved_interrupt_mask = chip->interrupt_mask; @@ -624,8 +624,8 @@ int oxygen_pci_resume(struct pci_dev *pci) if (chip->has_ac97_1) oxygen_restore_ac97(chip, 1); - if (chip->model->resume) - chip->model->resume(chip); + if (chip->model.resume) + chip->model.resume(chip); oxygen_write16(chip, OXYGEN_INTERRUPT_MASK, chip->interrupt_mask); diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c index 99c422ceb20..b7226b60eab 100644 --- a/sound/pci/oxygen/oxygen_mixer.c +++ b/sound/pci/oxygen/oxygen_mixer.c @@ -31,9 +31,9 @@ static int dac_volume_info(struct snd_kcontrol *ctl, struct oxygen *chip = ctl->private_data; info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - info->count = chip->model->dac_channels; - info->value.integer.min = chip->model->dac_volume_min; - info->value.integer.max = chip->model->dac_volume_max; + info->count = chip->model.dac_channels; + info->value.integer.min = chip->model.dac_volume_min; + info->value.integer.max = chip->model.dac_volume_max; return 0; } @@ -44,7 +44,7 @@ static int dac_volume_get(struct snd_kcontrol *ctl, unsigned int i; mutex_lock(&chip->mutex); - for (i = 0; i < chip->model->dac_channels; ++i) + for (i = 0; i < chip->model.dac_channels; ++i) value->value.integer.value[i] = chip->dac_volume[i]; mutex_unlock(&chip->mutex); return 0; @@ -59,13 +59,13 @@ static int dac_volume_put(struct snd_kcontrol *ctl, changed = 0; mutex_lock(&chip->mutex); - for (i = 0; i < chip->model->dac_channels; ++i) + for (i = 0; i < chip->model.dac_channels; ++i) if (value->value.integer.value[i] != chip->dac_volume[i]) { chip->dac_volume[i] = value->value.integer.value[i]; changed = 1; } if (changed) - chip->model->update_dac_volume(chip); + chip->model.update_dac_volume(chip); mutex_unlock(&chip->mutex); return changed; } @@ -91,7 +91,7 @@ static int dac_mute_put(struct snd_kcontrol *ctl, changed = !value->value.integer.value[0] != chip->dac_mute; if (changed) { chip->dac_mute = !value->value.integer.value[0]; - chip->model->update_dac_mute(chip); + chip->model.update_dac_mute(chip); } mutex_unlock(&chip->mutex); return changed; @@ -103,7 +103,7 @@ static int upmix_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info) "Front", "Front+Surround", "Front+Surround+Back" }; struct oxygen *chip = ctl->private_data; - unsigned int count = 2 + (chip->model->dac_channels == 8); + unsigned int count = 2 + (chip->model.dac_channels == 8); info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; info->count = 1; @@ -172,7 +172,7 @@ void oxygen_update_dac_routing(struct oxygen *chip) static int upmix_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) { struct oxygen *chip = ctl->private_data; - unsigned int count = 2 + (chip->model->dac_channels == 8); + unsigned int count = 2 + (chip->model.dac_channels == 8); int changed; mutex_lock(&chip->mutex); @@ -521,8 +521,8 @@ static void mute_ac97_ctl(struct oxygen *chip, unsigned int control) value = oxygen_read_ac97(chip, 0, priv_idx); if (!(value & 0x8000)) { oxygen_write_ac97(chip, 0, priv_idx, value | 0x8000); - if (chip->model->ac97_switch) - chip->model->ac97_switch(chip, priv_idx, 0x8000); + if (chip->model.ac97_switch) + chip->model.ac97_switch(chip, priv_idx, 0x8000); snd_ctl_notify(chip->card, SNDRV_CTL_EVENT_MASK_VALUE, &chip->controls[control]->id); } @@ -549,8 +549,8 @@ static int ac97_switch_put(struct snd_kcontrol *ctl, change = newreg != oldreg; if (change) { oxygen_write_ac97(chip, codec, index, newreg); - if (codec == 0 && chip->model->ac97_switch) - chip->model->ac97_switch(chip, index, newreg & 0x8000); + if (codec == 0 && chip->model.ac97_switch) + chip->model.ac97_switch(chip, index, newreg & 0x8000); if (index == AC97_LINE) { oxygen_write_ac97_masked(chip, 0, CM9780_GPIO_STATUS, newreg & 0x8000 ? @@ -939,16 +939,16 @@ static int add_controls(struct oxygen *chip, for (i = 0; i < count; ++i) { template = controls[i]; - if (chip->model->control_filter) { - err = chip->model->control_filter(&template); + if (chip->model.control_filter) { + err = chip->model.control_filter(&template); if (err < 0) return err; if (err == 1) continue; } if (!strcmp(template.name, "Master Playback Volume") && - chip->model->dac_tlv) { - template.tlv.p = chip->model->dac_tlv; + chip->model.dac_tlv) { + template.tlv.p = chip->model.dac_tlv; template.access |= SNDRV_CTL_ELEM_ACCESS_TLV_READ; } ctl = snd_ctl_new1(&template, chip); @@ -974,14 +974,14 @@ int oxygen_mixer_init(struct oxygen *chip) err = add_controls(chip, controls, ARRAY_SIZE(controls)); if (err < 0) return err; - if (chip->model->pcm_dev_cfg & CAPTURE_1_FROM_SPDIF) { + if (chip->model.pcm_dev_cfg & CAPTURE_1_FROM_SPDIF) { err = add_controls(chip, spdif_input_controls, ARRAY_SIZE(spdif_input_controls)); if (err < 0) return err; } for (i = 0; i < ARRAY_SIZE(monitor_controls); ++i) { - if (!(chip->model->pcm_dev_cfg & monitor_controls[i].pcm_dev)) + if (!(chip->model.pcm_dev_cfg & monitor_controls[i].pcm_dev)) continue; err = add_controls(chip, monitor_controls[i].controls, ARRAY_SIZE(monitor_controls[i].controls)); @@ -1000,5 +1000,5 @@ int oxygen_mixer_init(struct oxygen *chip) if (err < 0) return err; } - return chip->model->mixer_init ? chip->model->mixer_init(chip) : 0; + return chip->model.mixer_init ? chip->model.mixer_init(chip) : 0; } diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c index c4ad65a3406..5e8071ac766 100644 --- a/sound/pci/oxygen/oxygen_pcm.c +++ b/sound/pci/oxygen/oxygen_pcm.c @@ -129,7 +129,7 @@ static int oxygen_open(struct snd_pcm_substream *substream, runtime->private_data = (void *)(uintptr_t)channel; if (channel == PCM_B && chip->has_ac97_1 && - (chip->model->pcm_dev_cfg & CAPTURE_2_FROM_AC97_1)) + (chip->model.pcm_dev_cfg & CAPTURE_2_FROM_AC97_1)) runtime->hw = oxygen_ac97_hardware; else runtime->hw = *oxygen_hardware[channel]; @@ -140,11 +140,11 @@ static int oxygen_open(struct snd_pcm_substream *substream, runtime->hw.rate_min = 44100; break; case PCM_MULTICH: - runtime->hw.channels_max = chip->model->dac_channels; + runtime->hw.channels_max = chip->model.dac_channels; break; } - if (chip->model->pcm_hardware_filter) - chip->model->pcm_hardware_filter(channel, &runtime->hw); + if (chip->model.pcm_hardware_filter) + chip->model.pcm_hardware_filter(channel, &runtime->hw); err = snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_BYTES, 32); if (err < 0) @@ -355,7 +355,7 @@ static int oxygen_rec_a_hw_params(struct snd_pcm_substream *substream, oxygen_write16_masked(chip, OXYGEN_I2S_A_FORMAT, oxygen_rate(hw_params) | oxygen_i2s_mclk(hw_params) | - chip->model->adc_i2s_format | + chip->model.adc_i2s_format | oxygen_i2s_bits(hw_params), OXYGEN_I2S_RATE_MASK | OXYGEN_I2S_FORMAT_MASK | @@ -364,7 +364,7 @@ static int oxygen_rec_a_hw_params(struct snd_pcm_substream *substream, spin_unlock_irq(&chip->reg_lock); mutex_lock(&chip->mutex); - chip->model->set_adc_params(chip, hw_params); + chip->model.set_adc_params(chip, hw_params); mutex_unlock(&chip->mutex); return 0; } @@ -381,7 +381,7 @@ static int oxygen_rec_b_hw_params(struct snd_pcm_substream *substream, return err; is_ac97 = chip->has_ac97_1 && - (chip->model->pcm_dev_cfg & CAPTURE_2_FROM_AC97_1); + (chip->model.pcm_dev_cfg & CAPTURE_2_FROM_AC97_1); spin_lock_irq(&chip->reg_lock); oxygen_write8_masked(chip, OXYGEN_REC_FORMAT, @@ -391,7 +391,7 @@ static int oxygen_rec_b_hw_params(struct snd_pcm_substream *substream, oxygen_write16_masked(chip, OXYGEN_I2S_B_FORMAT, oxygen_rate(hw_params) | oxygen_i2s_mclk(hw_params) | - chip->model->adc_i2s_format | + chip->model.adc_i2s_format | oxygen_i2s_bits(hw_params), OXYGEN_I2S_RATE_MASK | OXYGEN_I2S_FORMAT_MASK | @@ -401,7 +401,7 @@ static int oxygen_rec_b_hw_params(struct snd_pcm_substream *substream, if (!is_ac97) { mutex_lock(&chip->mutex); - chip->model->set_adc_params(chip, hw_params); + chip->model.set_adc_params(chip, hw_params); mutex_unlock(&chip->mutex); } return 0; @@ -468,7 +468,7 @@ static int oxygen_multich_hw_params(struct snd_pcm_substream *substream, OXYGEN_MULTICH_FORMAT_MASK); oxygen_write16_masked(chip, OXYGEN_I2S_MULTICH_FORMAT, oxygen_rate(hw_params) | - chip->model->dac_i2s_format | + chip->model.dac_i2s_format | oxygen_i2s_bits(hw_params), OXYGEN_I2S_RATE_MASK | OXYGEN_I2S_FORMAT_MASK | @@ -478,7 +478,7 @@ static int oxygen_multich_hw_params(struct snd_pcm_substream *substream, spin_unlock_irq(&chip->reg_lock); mutex_lock(&chip->mutex); - chip->model->set_dac_params(chip, hw_params); + chip->model.set_dac_params(chip, hw_params); mutex_unlock(&chip->mutex); return 0; } @@ -657,9 +657,9 @@ int oxygen_pcm_init(struct oxygen *chip) int outs, ins; int err; - outs = !!(chip->model->pcm_dev_cfg & PLAYBACK_0_TO_I2S); - ins = !!(chip->model->pcm_dev_cfg & (CAPTURE_0_FROM_I2S_1 | - CAPTURE_0_FROM_I2S_2)); + outs = !!(chip->model.pcm_dev_cfg & PLAYBACK_0_TO_I2S); + ins = !!(chip->model.pcm_dev_cfg & (CAPTURE_0_FROM_I2S_1 | + CAPTURE_0_FROM_I2S_2)); if (outs | ins) { err = snd_pcm_new(chip->card, "Analog", 0, outs, ins, &pcm); if (err < 0) @@ -667,10 +667,10 @@ int oxygen_pcm_init(struct oxygen *chip) if (outs) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &oxygen_multich_ops); - if (chip->model->pcm_dev_cfg & CAPTURE_0_FROM_I2S_1) + if (chip->model.pcm_dev_cfg & CAPTURE_0_FROM_I2S_1) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &oxygen_rec_a_ops); - else if (chip->model->pcm_dev_cfg & CAPTURE_0_FROM_I2S_2) + else if (chip->model.pcm_dev_cfg & CAPTURE_0_FROM_I2S_2) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &oxygen_rec_b_ops); pcm->private_data = chip; @@ -690,8 +690,8 @@ int oxygen_pcm_init(struct oxygen *chip) BUFFER_BYTES_MAX); } - outs = !!(chip->model->pcm_dev_cfg & PLAYBACK_1_TO_SPDIF); - ins = !!(chip->model->pcm_dev_cfg & CAPTURE_1_FROM_SPDIF); + outs = !!(chip->model.pcm_dev_cfg & PLAYBACK_1_TO_SPDIF); + ins = !!(chip->model.pcm_dev_cfg & CAPTURE_1_FROM_SPDIF); if (outs | ins) { err = snd_pcm_new(chip->card, "Digital", 1, outs, ins, &pcm); if (err < 0) @@ -712,11 +712,11 @@ int oxygen_pcm_init(struct oxygen *chip) } if (chip->has_ac97_1) { - outs = !!(chip->model->pcm_dev_cfg & PLAYBACK_2_TO_AC97_1); - ins = !!(chip->model->pcm_dev_cfg & CAPTURE_2_FROM_AC97_1); + outs = !!(chip->model.pcm_dev_cfg & PLAYBACK_2_TO_AC97_1); + ins = !!(chip->model.pcm_dev_cfg & CAPTURE_2_FROM_AC97_1); } else { outs = 0; - ins = !!(chip->model->pcm_dev_cfg & CAPTURE_2_FROM_I2S_2); + ins = !!(chip->model.pcm_dev_cfg & CAPTURE_2_FROM_I2S_2); } if (outs | ins) { err = snd_pcm_new(chip->card, outs ? "AC97" : "Analog2", -- cgit v1.2.3 From 568c59e722da22c9b0a485c2f1aaf28cb1b36b79 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 22 Sep 2008 08:56:01 +0200 Subject: ALSA: oxygen: add probe callback Add a probe callback to the model structure so that model-specific drivers can refine their model detection before the card is initialized. Signed-off-by: Clemens Ladisch --- sound/pci/oxygen/hifier.c | 2 +- sound/pci/oxygen/oxygen.c | 3 ++- sound/pci/oxygen/oxygen.h | 4 +++- sound/pci/oxygen/oxygen_lib.c | 8 +++++++- sound/pci/oxygen/virtuoso.c | 2 +- 5 files changed, 14 insertions(+), 5 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/hifier.c b/sound/pci/oxygen/hifier.c index dad393ae040..173d6dddc93 100644 --- a/sound/pci/oxygen/hifier.c +++ b/sound/pci/oxygen/hifier.c @@ -180,7 +180,7 @@ static int __devinit hifier_probe(struct pci_dev *pci, ++dev; return -ENOENT; } - err = oxygen_pci_probe(pci, index[dev], id[dev], &model_hifier); + err = oxygen_pci_probe(pci, index[dev], id[dev], &model_hifier, 0); if (err >= 0) ++dev; return err; diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index c5829d30ef8..4722fe08dca 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -354,7 +354,8 @@ static int __devinit generic_oxygen_probe(struct pci_dev *pci, } is_meridian = pci_id->driver_data; err = oxygen_pci_probe(pci, index[dev], id[dev], - is_meridian ? &model_meridian : &model_generic); + is_meridian ? &model_meridian : &model_generic, + 0); if (err >= 0) ++dev; return err; diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h index 5f3fbf80222..914b8f406b1 100644 --- a/sound/pci/oxygen/oxygen.h +++ b/sound/pci/oxygen/oxygen.h @@ -58,6 +58,7 @@ struct oxygen_model { const char *longname; const char *chip; struct module *owner; + int (*probe)(struct oxygen *chip, unsigned long driver_data); void (*init)(struct oxygen *chip); int (*control_filter)(struct snd_kcontrol_new *template); int (*mixer_init)(struct oxygen *chip); @@ -125,7 +126,8 @@ struct oxygen { /* oxygen_lib.c */ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id, - const struct oxygen_model *model); + const struct oxygen_model *model, + unsigned long driver_data); void oxygen_pci_remove(struct pci_dev *pci); #ifdef CONFIG_PM int oxygen_pci_suspend(struct pci_dev *pci, pm_message_t state); diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c index 07b0563cc90..58bbc010ed8 100644 --- a/sound/pci/oxygen/oxygen_lib.c +++ b/sound/pci/oxygen/oxygen_lib.c @@ -424,7 +424,8 @@ static void oxygen_card_free(struct snd_card *card) } int oxygen_pci_probe(struct pci_dev *pci, int index, char *id, - const struct oxygen_model *model) + const struct oxygen_model *model, + unsigned long driver_data) { struct snd_card *card; struct oxygen *chip; @@ -470,6 +471,11 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id, snd_card_set_dev(card, &pci->dev); card->private_free = oxygen_card_free; + if (chip->model.probe) { + err = chip->model.probe(chip, driver_data); + if (err < 0) + goto err_card; + } oxygen_init(chip); chip->model.init(chip); diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c index 01d7b75f918..4aa2857a1b0 100644 --- a/sound/pci/oxygen/virtuoso.c +++ b/sound/pci/oxygen/virtuoso.c @@ -696,7 +696,7 @@ static int __devinit xonar_probe(struct pci_dev *pci, return -ENOENT; } err = oxygen_pci_probe(pci, index[dev], id[dev], - &xonar_models[pci_id->driver_data]); + &xonar_models[pci_id->driver_data], 0); if (err >= 0) ++dev; return err; -- cgit v1.2.3 From 2f1b0ec715a1d804b53b45f2555527c27247d1e1 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 22 Sep 2008 08:57:24 +0200 Subject: ALSA: oxygen: remove X-Meridian magic number Introduce symbols that indicate the two models handled by the snd-oxygen driver, instead of using a magic number. Signed-off-by: Clemens Ladisch --- sound/pci/oxygen/oxygen.c | 27 ++++++++++++++++----------- 1 file changed, 16 insertions(+), 11 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index 4722fe08dca..cf05fd56bc7 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -58,17 +58,22 @@ MODULE_PARM_DESC(id, "ID string"); module_param_array(enable, bool, NULL, 0444); MODULE_PARM_DESC(enable, "enable card"); +enum { + MODEL_CMEDIA_REF, /* C-Media's reference design */ + MODEL_MERIDIAN, /* AuzenTech X-Meridian */ +}; + static struct pci_device_id oxygen_ids[] __devinitdata = { - { OXYGEN_PCI_SUBID(0x10b0, 0x0216) }, - { OXYGEN_PCI_SUBID(0x10b0, 0x0218) }, - { OXYGEN_PCI_SUBID(0x10b0, 0x0219) }, - { OXYGEN_PCI_SUBID(0x13f6, 0x0001) }, - { OXYGEN_PCI_SUBID(0x13f6, 0x0010) }, - { OXYGEN_PCI_SUBID(0x13f6, 0x8788) }, - { OXYGEN_PCI_SUBID(0x147a, 0xa017) }, - { OXYGEN_PCI_SUBID(0x1a58, 0x0910) }, - { OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = 1 }, - { OXYGEN_PCI_SUBID(0x7284, 0x9761) }, + { OXYGEN_PCI_SUBID(0x10b0, 0x0216), .driver_data = MODEL_CMEDIA_REF }, + { OXYGEN_PCI_SUBID(0x10b0, 0x0218), .driver_data = MODEL_CMEDIA_REF }, + { OXYGEN_PCI_SUBID(0x10b0, 0x0219), .driver_data = MODEL_CMEDIA_REF }, + { OXYGEN_PCI_SUBID(0x13f6, 0x0001), .driver_data = MODEL_CMEDIA_REF }, + { OXYGEN_PCI_SUBID(0x13f6, 0x0010), .driver_data = MODEL_CMEDIA_REF }, + { OXYGEN_PCI_SUBID(0x13f6, 0x8788), .driver_data = MODEL_CMEDIA_REF }, + { OXYGEN_PCI_SUBID(0x147a, 0xa017), .driver_data = MODEL_CMEDIA_REF }, + { OXYGEN_PCI_SUBID(0x1a58, 0x0910), .driver_data = MODEL_CMEDIA_REF }, + { OXYGEN_PCI_SUBID(0x415a, 0x5431), .driver_data = MODEL_MERIDIAN }, + { OXYGEN_PCI_SUBID(0x7284, 0x9761), .driver_data = MODEL_CMEDIA_REF }, { } }; MODULE_DEVICE_TABLE(pci, oxygen_ids); @@ -352,7 +357,7 @@ static int __devinit generic_oxygen_probe(struct pci_dev *pci, ++dev; return -ENOENT; } - is_meridian = pci_id->driver_data; + is_meridian = pci_id->driver_data == MODEL_MERIDIAN; err = oxygen_pci_probe(pci, index[dev], id[dev], is_meridian ? &model_meridian : &model_generic, 0); -- cgit v1.2.3 From 4bd0c3a690594b4037c3edc49e6475f1df13c59d Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 22 Sep 2008 08:59:18 +0200 Subject: ALSA: oxygen: handle X-Meridian dynamically Handle the differences between the X-Meridian and the other models in the probe callback instead of using a second model structure. Signed-off-by: Clemens Ladisch --- sound/pci/oxygen/oxygen.c | 50 ++++++++++++++++------------------------------- 1 file changed, 17 insertions(+), 33 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index cf05fd56bc7..043fe281358 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -286,11 +286,27 @@ static void set_ak5385_params(struct oxygen *chip, static const DECLARE_TLV_DB_LINEAR(ak4396_db_scale, TLV_DB_GAIN_MUTE, 0); +static int generic_probe(struct oxygen *chip, unsigned long driver_data) +{ + if (driver_data == MODEL_MERIDIAN) { + chip->model.init = meridian_init; + chip->model.resume = ak4396_registers_init; + chip->model.set_adc_params = set_ak5385_params; + chip->model.pcm_dev_cfg = PLAYBACK_0_TO_I2S | + PLAYBACK_1_TO_SPDIF | + CAPTURE_0_FROM_I2S_2 | + CAPTURE_1_FROM_SPDIF; + chip->model.misc_flags = OXYGEN_MISC_MIDI; + } + return 0; +} + static const struct oxygen_model model_generic = { .shortname = "C-Media CMI8788", .longname = "C-Media Oxygen HD Audio", .chip = "CMI8788", .owner = THIS_MODULE, + .probe = generic_probe, .init = generic_init, .cleanup = generic_cleanup, .resume = generic_resume, @@ -314,41 +330,11 @@ static const struct oxygen_model model_generic = { .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, }; -static const struct oxygen_model model_meridian = { - .shortname = "C-Media CMI8788", - .longname = "C-Media Oxygen HD Audio", - .chip = "CMI8788", - .owner = THIS_MODULE, - .init = meridian_init, - .cleanup = generic_cleanup, - .resume = ak4396_registers_init, - .set_dac_params = set_ak4396_params, - .set_adc_params = set_ak5385_params, - .update_dac_volume = update_ak4396_volume, - .update_dac_mute = update_ak4396_mute, - .dac_tlv = ak4396_db_scale, - .model_data_size = sizeof(struct generic_data), - .pcm_dev_cfg = PLAYBACK_0_TO_I2S | - PLAYBACK_1_TO_SPDIF | - PLAYBACK_2_TO_AC97_1 | - CAPTURE_0_FROM_I2S_2 | - CAPTURE_1_FROM_SPDIF | - CAPTURE_2_FROM_AC97_1, - .dac_channels = 8, - .dac_volume_min = 0, - .dac_volume_max = 255, - .misc_flags = OXYGEN_MISC_MIDI, - .function_flags = OXYGEN_FUNCTION_SPI | - OXYGEN_FUNCTION_ENABLE_SPI_4_5, - .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, - .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, -}; static int __devinit generic_oxygen_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) { static int dev; - int is_meridian; int err; if (dev >= SNDRV_CARDS) @@ -357,10 +343,8 @@ static int __devinit generic_oxygen_probe(struct pci_dev *pci, ++dev; return -ENOENT; } - is_meridian = pci_id->driver_data == MODEL_MERIDIAN; err = oxygen_pci_probe(pci, index[dev], id[dev], - is_meridian ? &model_meridian : &model_generic, - 0); + &model_generic, pci_id->driver_data); if (err >= 0) ++dev; return err; -- cgit v1.2.3 From fe10662c3c7e1a77cac7949a4b269622da663c2e Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 22 Sep 2008 09:00:30 +0200 Subject: ALSA: virtuoso: handle D2X/DX dynamically The Xonar D2X and DX are very similar to the D2 and D1, respectively, so we can handle the differences dynamically instead of using a separate model structure for each one. Signed-off-by: Clemens Ladisch --- sound/pci/oxygen/virtuoso.c | 241 ++++++++++++++++++-------------------------- 1 file changed, 99 insertions(+), 142 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c index 4aa2857a1b0..c4ac91f8023 100644 --- a/sound/pci/oxygen/virtuoso.c +++ b/sound/pci/oxygen/virtuoso.c @@ -128,6 +128,7 @@ MODULE_DEVICE_TABLE(pci, xonar_ids); #define I2C_DEVICE_CS4362A 0x30 /* 001100, AD0=0, /W=0 */ struct xonar_data { + unsigned int model; unsigned int anti_pop_delay; u16 output_enable_bit; u8 ext_power_reg; @@ -139,6 +140,8 @@ struct xonar_data { u8 cs4362a_fm; }; +static void xonar_gpio_changed(struct oxygen *chip); + static void pcm1796_write(struct oxygen *chip, unsigned int codec, u8 reg, u8 value) { @@ -180,6 +183,7 @@ static void xonar_common_init(struct oxygen *chip) oxygen_set_bits8(chip, data->ext_power_int_reg, data->ext_power_bit); chip->interrupt_mask |= OXYGEN_INT_GPIO; + chip->model.gpio_changed = xonar_gpio_changed; data->has_power = !!(oxygen_read8(chip, data->ext_power_reg) & data->ext_power_bit); } @@ -234,6 +238,13 @@ static void xonar_d2_init(struct oxygen *chip) data->anti_pop_delay = 300; data->output_enable_bit = GPIO_D2_OUTPUT_ENABLE; data->pcm1796_oversampling = PCM1796_OS_64; + if (data->model == MODEL_D2X) { + data->ext_power_reg = OXYGEN_GPIO_DATA; + data->ext_power_int_reg = OXYGEN_GPIO_INTERRUPT_MASK; + data->ext_power_bit = GPIO_D2X_EXT_POWER; + oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL, + GPIO_D2X_EXT_POWER); + } pcm1796_init(chip); @@ -246,17 +257,6 @@ static void xonar_d2_init(struct oxygen *chip) snd_component_add(chip->card, "CS5381"); } -static void xonar_d2x_init(struct oxygen *chip) -{ - struct xonar_data *data = chip->model_data; - - data->ext_power_reg = OXYGEN_GPIO_DATA; - data->ext_power_int_reg = OXYGEN_GPIO_INTERRUPT_MASK; - data->ext_power_bit = GPIO_D2X_EXT_POWER; - oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_D2X_EXT_POWER); - xonar_d2_init(chip); -} - static void update_cs4362a_volumes(struct oxygen *chip) { u8 mute; @@ -324,6 +324,11 @@ static void xonar_d1_init(struct oxygen *chip) data->cs4398_fm = CS4398_FM_SINGLE | CS4398_DEM_NONE | CS4398_DIF_LJUST; data->cs4362a_fm = CS4362A_FM_SINGLE | CS4362A_ATAPI_B_R | CS4362A_ATAPI_A_L; + if (data->model == MODEL_DX) { + data->ext_power_reg = OXYGEN_GPI_DATA; + data->ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK; + data->ext_power_bit = GPI_DX_EXT_POWER; + } oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS, OXYGEN_2WIRE_LENGTH_8 | @@ -344,16 +349,6 @@ static void xonar_d1_init(struct oxygen *chip) snd_component_add(chip->card, "CS5361"); } -static void xonar_dx_init(struct oxygen *chip) -{ - struct xonar_data *data = chip->model_data; - - data->ext_power_reg = OXYGEN_GPI_DATA; - data->ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK; - data->ext_power_bit = GPI_DX_EXT_POWER; - xonar_d1_init(chip); -} - static void xonar_cleanup(struct oxygen *chip) { struct xonar_data *data = chip->model_data; @@ -552,7 +547,7 @@ static int xonar_d1_control_filter(struct snd_kcontrol_new *template) return 0; } -static int xonar_mixer_init(struct oxygen *chip) +static int xonar_d2_mixer_init(struct oxygen *chip) { return snd_ctl_add(chip->card, snd_ctl_new1(&alt_switch, chip)); } @@ -562,130 +557,90 @@ static int xonar_d1_mixer_init(struct oxygen *chip) return snd_ctl_add(chip->card, snd_ctl_new1(&front_panel_switch, chip)); } -static const struct oxygen_model xonar_models[] = { - [MODEL_D2] = { - .shortname = "Xonar D2", - .longname = "Asus Virtuoso 200", - .chip = "AV200", - .owner = THIS_MODULE, - .init = xonar_d2_init, - .control_filter = xonar_d2_control_filter, - .mixer_init = xonar_mixer_init, - .cleanup = xonar_cleanup, - .suspend = xonar_cleanup, - .resume = xonar_d2_resume, - .set_dac_params = set_pcm1796_params, - .set_adc_params = set_cs53x1_params, - .update_dac_volume = update_pcm1796_volume, - .update_dac_mute = update_pcm1796_mute, - .dac_tlv = pcm1796_db_scale, - .model_data_size = sizeof(struct xonar_data), - .pcm_dev_cfg = PLAYBACK_0_TO_I2S | - PLAYBACK_1_TO_SPDIF | - CAPTURE_0_FROM_I2S_2 | - CAPTURE_1_FROM_SPDIF, - .dac_channels = 8, - .dac_volume_min = 0x0f, - .dac_volume_max = 0xff, - .misc_flags = OXYGEN_MISC_MIDI, - .function_flags = OXYGEN_FUNCTION_SPI | - OXYGEN_FUNCTION_ENABLE_SPI_4_5, - .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, - .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, - }, - [MODEL_D2X] = { - .shortname = "Xonar D2X", - .longname = "Asus Virtuoso 200", - .chip = "AV200", - .owner = THIS_MODULE, - .init = xonar_d2x_init, - .control_filter = xonar_d2_control_filter, - .mixer_init = xonar_mixer_init, - .cleanup = xonar_cleanup, - .suspend = xonar_cleanup, - .resume = xonar_d2_resume, - .set_dac_params = set_pcm1796_params, - .set_adc_params = set_cs53x1_params, - .update_dac_volume = update_pcm1796_volume, - .update_dac_mute = update_pcm1796_mute, - .gpio_changed = xonar_gpio_changed, - .dac_tlv = pcm1796_db_scale, - .model_data_size = sizeof(struct xonar_data), - .pcm_dev_cfg = PLAYBACK_0_TO_I2S | - PLAYBACK_1_TO_SPDIF | - CAPTURE_0_FROM_I2S_2 | - CAPTURE_1_FROM_SPDIF, - .dac_channels = 8, - .dac_volume_min = 0x0f, - .dac_volume_max = 0xff, - .misc_flags = OXYGEN_MISC_MIDI, - .function_flags = OXYGEN_FUNCTION_SPI | - OXYGEN_FUNCTION_ENABLE_SPI_4_5, - .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, - .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, - }, - [MODEL_D1] = { - .shortname = "Xonar D1", - .longname = "Asus Virtuoso 100", - .chip = "AV200", - .owner = THIS_MODULE, - .init = xonar_d1_init, - .control_filter = xonar_d1_control_filter, - .mixer_init = xonar_d1_mixer_init, - .cleanup = xonar_d1_cleanup, - .suspend = xonar_d1_cleanup, - .resume = xonar_d1_resume, - .set_dac_params = set_cs43xx_params, - .set_adc_params = set_cs53x1_params, - .update_dac_volume = update_cs43xx_volume, - .update_dac_mute = update_cs43xx_mute, - .ac97_switch = xonar_d1_ac97_switch, - .dac_tlv = cs4362a_db_scale, - .model_data_size = sizeof(struct xonar_data), - .pcm_dev_cfg = PLAYBACK_0_TO_I2S | - PLAYBACK_1_TO_SPDIF | - CAPTURE_0_FROM_I2S_2, - .dac_channels = 8, - .dac_volume_min = 0, - .dac_volume_max = 127, - .function_flags = OXYGEN_FUNCTION_2WIRE, - .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, - .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, - }, - [MODEL_DX] = { - .shortname = "Xonar DX", - .longname = "Asus Virtuoso 100", - .chip = "AV200", - .owner = THIS_MODULE, - .init = xonar_dx_init, - .control_filter = xonar_d1_control_filter, - .mixer_init = xonar_d1_mixer_init, - .cleanup = xonar_d1_cleanup, - .suspend = xonar_d1_cleanup, - .resume = xonar_d1_resume, - .set_dac_params = set_cs43xx_params, - .set_adc_params = set_cs53x1_params, - .update_dac_volume = update_cs43xx_volume, - .update_dac_mute = update_cs43xx_mute, - .gpio_changed = xonar_gpio_changed, - .ac97_switch = xonar_d1_ac97_switch, - .dac_tlv = cs4362a_db_scale, - .model_data_size = sizeof(struct xonar_data), - .pcm_dev_cfg = PLAYBACK_0_TO_I2S | - PLAYBACK_1_TO_SPDIF | - CAPTURE_0_FROM_I2S_2, - .dac_channels = 8, - .dac_volume_min = 0, - .dac_volume_max = 127, - .function_flags = OXYGEN_FUNCTION_2WIRE, - .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, - .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, - }, +static int xonar_model_probe(struct oxygen *chip, unsigned long driver_data) +{ + static const char *const names[] = { + [MODEL_D1] = "Xonar D1", + [MODEL_DX] = "Xonar DX", + [MODEL_D2] = "Xonar D2", + [MODEL_D2X] = "Xonar D2X", + }; + struct xonar_data *data = chip->model_data; + + data->model = driver_data; + chip->model.shortname = names[data->model]; + return 0; +} + +static const struct oxygen_model model_xonar_d2 = { + .longname = "Asus Virtuoso 200", + .chip = "AV200", + .owner = THIS_MODULE, + .probe = xonar_model_probe, + .init = xonar_d2_init, + .control_filter = xonar_d2_control_filter, + .mixer_init = xonar_d2_mixer_init, + .cleanup = xonar_cleanup, + .suspend = xonar_cleanup, + .resume = xonar_d2_resume, + .set_dac_params = set_pcm1796_params, + .set_adc_params = set_cs53x1_params, + .update_dac_volume = update_pcm1796_volume, + .update_dac_mute = update_pcm1796_mute, + .dac_tlv = pcm1796_db_scale, + .model_data_size = sizeof(struct xonar_data), + .pcm_dev_cfg = PLAYBACK_0_TO_I2S | + PLAYBACK_1_TO_SPDIF | + CAPTURE_0_FROM_I2S_2 | + CAPTURE_1_FROM_SPDIF, + .dac_channels = 8, + .dac_volume_min = 0x0f, + .dac_volume_max = 0xff, + .misc_flags = OXYGEN_MISC_MIDI, + .function_flags = OXYGEN_FUNCTION_SPI | + OXYGEN_FUNCTION_ENABLE_SPI_4_5, + .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, + .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, +}; + +static const struct oxygen_model model_xonar_d1 = { + .longname = "Asus Virtuoso 100", + .chip = "AV200", + .owner = THIS_MODULE, + .probe = xonar_model_probe, + .init = xonar_d1_init, + .control_filter = xonar_d1_control_filter, + .mixer_init = xonar_d1_mixer_init, + .cleanup = xonar_d1_cleanup, + .suspend = xonar_d1_cleanup, + .resume = xonar_d1_resume, + .set_dac_params = set_cs43xx_params, + .set_adc_params = set_cs53x1_params, + .update_dac_volume = update_cs43xx_volume, + .update_dac_mute = update_cs43xx_mute, + .ac97_switch = xonar_d1_ac97_switch, + .dac_tlv = cs4362a_db_scale, + .model_data_size = sizeof(struct xonar_data), + .pcm_dev_cfg = PLAYBACK_0_TO_I2S | + PLAYBACK_1_TO_SPDIF | + CAPTURE_0_FROM_I2S_2, + .dac_channels = 8, + .dac_volume_min = 0, + .dac_volume_max = 127, + .function_flags = OXYGEN_FUNCTION_2WIRE, + .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, + .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, }; static int __devinit xonar_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) { + static const struct oxygen_model *const models[] = { + [MODEL_D1] = &model_xonar_d1, + [MODEL_DX] = &model_xonar_d1, + [MODEL_D2] = &model_xonar_d2, + [MODEL_D2X] = &model_xonar_d2, + }; static int dev; int err; @@ -695,8 +650,10 @@ static int __devinit xonar_probe(struct pci_dev *pci, ++dev; return -ENOENT; } + BUG_ON(pci_id->driver_data >= ARRAY_SIZE(models)); err = oxygen_pci_probe(pci, index[dev], id[dev], - &xonar_models[pci_id->driver_data], 0); + models[pci_id->driver_data], + pci_id->driver_data); if (err >= 0) ++dev; return err; -- cgit v1.2.3 From c3f00739c5e45b4bf6f759172a5318256b92f2b2 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 22 Sep 2008 09:01:11 +0200 Subject: ALSA: virtuoso: create common functions for GPIO bit switch controls Factor out the common code of the mixer callbacks that handle controls that just switch a single GPIO bit. Signed-off-by: Clemens Ladisch --- sound/pci/oxygen/virtuoso.c | 53 +++++++++++++-------------------------------- 1 file changed, 15 insertions(+), 38 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c index c4ac91f8023..34baff19ad3 100644 --- a/sound/pci/oxygen/virtuoso.c +++ b/sound/pci/oxygen/virtuoso.c @@ -444,29 +444,31 @@ static void xonar_gpio_changed(struct oxygen *chip) } } -static int alt_switch_get(struct snd_kcontrol *ctl, - struct snd_ctl_elem_value *value) +static int gpio_bit_switch_get(struct snd_kcontrol *ctl, + struct snd_ctl_elem_value *value) { struct oxygen *chip = ctl->private_data; + u16 bit = ctl->private_value; value->value.integer.value[0] = - !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) & GPIO_D2_ALT); + !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) & bit); return 0; } -static int alt_switch_put(struct snd_kcontrol *ctl, - struct snd_ctl_elem_value *value) +static int gpio_bit_switch_put(struct snd_kcontrol *ctl, + struct snd_ctl_elem_value *value) { struct oxygen *chip = ctl->private_data; + u16 bit = ctl->private_value; u16 old_bits, new_bits; int changed; spin_lock_irq(&chip->reg_lock); old_bits = oxygen_read16(chip, OXYGEN_GPIO_DATA); if (value->value.integer.value[0]) - new_bits = old_bits | GPIO_D2_ALT; + new_bits = old_bits | bit; else - new_bits = old_bits & ~GPIO_D2_ALT; + new_bits = old_bits & ~bit; changed = new_bits != old_bits; if (changed) oxygen_write16(chip, OXYGEN_GPIO_DATA, new_bits); @@ -478,43 +480,18 @@ static const struct snd_kcontrol_new alt_switch = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Analog Loopback Switch", .info = snd_ctl_boolean_mono_info, - .get = alt_switch_get, - .put = alt_switch_put, + .get = gpio_bit_switch_get, + .put = gpio_bit_switch_put, + .private_value = GPIO_D2_ALT, }; -static int front_panel_get(struct snd_kcontrol *ctl, - struct snd_ctl_elem_value *value) -{ - struct oxygen *chip = ctl->private_data; - - value->value.integer.value[0] = - !!(oxygen_read16(chip, OXYGEN_GPIO_DATA) & GPIO_DX_FRONT_PANEL); - return 0; -} - -static int front_panel_put(struct snd_kcontrol *ctl, - struct snd_ctl_elem_value *value) -{ - struct oxygen *chip = ctl->private_data; - u16 old_reg, new_reg; - - spin_lock_irq(&chip->reg_lock); - old_reg = oxygen_read16(chip, OXYGEN_GPIO_DATA); - if (value->value.integer.value[0]) - new_reg = old_reg | GPIO_DX_FRONT_PANEL; - else - new_reg = old_reg & ~GPIO_DX_FRONT_PANEL; - oxygen_write16(chip, OXYGEN_GPIO_DATA, new_reg); - spin_unlock_irq(&chip->reg_lock); - return old_reg != new_reg; -} - static const struct snd_kcontrol_new front_panel_switch = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Front Panel Switch", .info = snd_ctl_boolean_mono_info, - .get = front_panel_get, - .put = front_panel_put, + .get = gpio_bit_switch_get, + .put = gpio_bit_switch_put, + .private_value = GPIO_DX_FRONT_PANEL, }; static void xonar_d1_ac97_switch(struct oxygen *chip, -- cgit v1.2.3 From d76596b1ee7f5cdbd0b73d374ba72372a2c8b725 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 22 Sep 2008 09:02:08 +0200 Subject: ALSA: oxygen: rename pcm_dev_cfg Rename the pcm_dev_cfg field to device_config because there will be additional flags that do not describe PCM devices. Signed-off-by: Clemens Ladisch --- sound/pci/oxygen/hifier.c | 6 +++--- sound/pci/oxygen/oxygen.c | 20 ++++++++++---------- sound/pci/oxygen/oxygen.h | 2 +- sound/pci/oxygen/oxygen_lib.c | 10 +++++----- sound/pci/oxygen/oxygen_mixer.c | 4 ++-- sound/pci/oxygen/oxygen_pcm.c | 24 ++++++++++++------------ sound/pci/oxygen/virtuoso.c | 14 +++++++------- 7 files changed, 40 insertions(+), 40 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/hifier.c b/sound/pci/oxygen/hifier.c index 173d6dddc93..088939903ee 100644 --- a/sound/pci/oxygen/hifier.c +++ b/sound/pci/oxygen/hifier.c @@ -157,9 +157,9 @@ static const struct oxygen_model model_hifier = { .update_dac_mute = update_ak4396_mute, .dac_tlv = ak4396_db_scale, .model_data_size = sizeof(struct hifier_data), - .pcm_dev_cfg = PLAYBACK_0_TO_I2S | - PLAYBACK_1_TO_SPDIF | - CAPTURE_0_FROM_I2S_1, + .device_config = PLAYBACK_0_TO_I2S | + PLAYBACK_1_TO_SPDIF | + CAPTURE_0_FROM_I2S_1, .dac_channels = 2, .dac_volume_min = 0, .dac_volume_max = 255, diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index 043fe281358..bb2e7d82d83 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -292,10 +292,10 @@ static int generic_probe(struct oxygen *chip, unsigned long driver_data) chip->model.init = meridian_init; chip->model.resume = ak4396_registers_init; chip->model.set_adc_params = set_ak5385_params; - chip->model.pcm_dev_cfg = PLAYBACK_0_TO_I2S | - PLAYBACK_1_TO_SPDIF | - CAPTURE_0_FROM_I2S_2 | - CAPTURE_1_FROM_SPDIF; + chip->model.device_config = PLAYBACK_0_TO_I2S | + PLAYBACK_1_TO_SPDIF | + CAPTURE_0_FROM_I2S_2 | + CAPTURE_1_FROM_SPDIF; chip->model.misc_flags = OXYGEN_MISC_MIDI; } return 0; @@ -316,12 +316,12 @@ static const struct oxygen_model model_generic = { .update_dac_mute = update_ak4396_mute, .dac_tlv = ak4396_db_scale, .model_data_size = sizeof(struct generic_data), - .pcm_dev_cfg = PLAYBACK_0_TO_I2S | - PLAYBACK_1_TO_SPDIF | - PLAYBACK_2_TO_AC97_1 | - CAPTURE_0_FROM_I2S_1 | - CAPTURE_1_FROM_SPDIF | - CAPTURE_2_FROM_AC97_1, + .device_config = PLAYBACK_0_TO_I2S | + PLAYBACK_1_TO_SPDIF | + PLAYBACK_2_TO_AC97_1 | + CAPTURE_0_FROM_I2S_1 | + CAPTURE_1_FROM_SPDIF | + CAPTURE_2_FROM_AC97_1, .dac_channels = 8, .dac_volume_min = 0, .dac_volume_max = 255, diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h index 914b8f406b1..30cd996d366 100644 --- a/sound/pci/oxygen/oxygen.h +++ b/sound/pci/oxygen/oxygen.h @@ -78,7 +78,7 @@ struct oxygen_model { unsigned int reg, unsigned int mute); const unsigned int *dac_tlv; size_t model_data_size; - unsigned int pcm_dev_cfg; + unsigned int device_config; u8 dac_channels; u8 dac_volume_min; u8 dac_volume_max; diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c index 58bbc010ed8..02191c6a4e7 100644 --- a/sound/pci/oxygen/oxygen_lib.c +++ b/sound/pci/oxygen/oxygen_lib.c @@ -273,7 +273,7 @@ static void oxygen_init(struct oxygen *chip) OXYGEN_RATE_48000 | chip->model.dac_i2s_format | OXYGEN_I2S_MCLK_256 | OXYGEN_I2S_BITS_16 | OXYGEN_I2S_MASTER | OXYGEN_I2S_BCLK_64); - if (chip->model.pcm_dev_cfg & CAPTURE_0_FROM_I2S_1) + if (chip->model.device_config & CAPTURE_0_FROM_I2S_1) oxygen_write16(chip, OXYGEN_I2S_A_FORMAT, OXYGEN_RATE_48000 | chip->model.adc_i2s_format | OXYGEN_I2S_MCLK_256 | OXYGEN_I2S_BITS_16 | @@ -281,8 +281,8 @@ static void oxygen_init(struct oxygen *chip) else oxygen_write16(chip, OXYGEN_I2S_A_FORMAT, OXYGEN_I2S_MASTER | OXYGEN_I2S_MUTE_MCLK); - if (chip->model.pcm_dev_cfg & (CAPTURE_0_FROM_I2S_2 | - CAPTURE_2_FROM_I2S_2)) + if (chip->model.device_config & (CAPTURE_0_FROM_I2S_2 | + CAPTURE_2_FROM_I2S_2)) oxygen_write16(chip, OXYGEN_I2S_B_FORMAT, OXYGEN_RATE_48000 | chip->model.adc_i2s_format | OXYGEN_I2S_MCLK_256 | OXYGEN_I2S_BITS_16 | @@ -295,7 +295,7 @@ static void oxygen_init(struct oxygen *chip) oxygen_clear_bits32(chip, OXYGEN_SPDIF_CONTROL, OXYGEN_SPDIF_OUT_ENABLE | OXYGEN_SPDIF_LOOPBACK); - if (chip->model.pcm_dev_cfg & CAPTURE_1_FROM_SPDIF) + if (chip->model.device_config & CAPTURE_1_FROM_SPDIF) oxygen_write32_masked(chip, OXYGEN_SPDIF_CONTROL, OXYGEN_SPDIF_SENSE_MASK | OXYGEN_SPDIF_LOCK_MASK | @@ -514,7 +514,7 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id, oxygen_proc_init(chip); spin_lock_irq(&chip->reg_lock); - if (chip->model.pcm_dev_cfg & CAPTURE_1_FROM_SPDIF) + if (chip->model.device_config & CAPTURE_1_FROM_SPDIF) chip->interrupt_mask |= OXYGEN_INT_SPDIF_IN_DETECT; if (chip->has_ac97_0 | chip->has_ac97_1) chip->interrupt_mask |= OXYGEN_INT_AC97; diff --git a/sound/pci/oxygen/oxygen_mixer.c b/sound/pci/oxygen/oxygen_mixer.c index b7226b60eab..304da169bfd 100644 --- a/sound/pci/oxygen/oxygen_mixer.c +++ b/sound/pci/oxygen/oxygen_mixer.c @@ -974,14 +974,14 @@ int oxygen_mixer_init(struct oxygen *chip) err = add_controls(chip, controls, ARRAY_SIZE(controls)); if (err < 0) return err; - if (chip->model.pcm_dev_cfg & CAPTURE_1_FROM_SPDIF) { + if (chip->model.device_config & CAPTURE_1_FROM_SPDIF) { err = add_controls(chip, spdif_input_controls, ARRAY_SIZE(spdif_input_controls)); if (err < 0) return err; } for (i = 0; i < ARRAY_SIZE(monitor_controls); ++i) { - if (!(chip->model.pcm_dev_cfg & monitor_controls[i].pcm_dev)) + if (!(chip->model.device_config & monitor_controls[i].pcm_dev)) continue; err = add_controls(chip, monitor_controls[i].controls, ARRAY_SIZE(monitor_controls[i].controls)); diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c index 5e8071ac766..87b60071b61 100644 --- a/sound/pci/oxygen/oxygen_pcm.c +++ b/sound/pci/oxygen/oxygen_pcm.c @@ -129,7 +129,7 @@ static int oxygen_open(struct snd_pcm_substream *substream, runtime->private_data = (void *)(uintptr_t)channel; if (channel == PCM_B && chip->has_ac97_1 && - (chip->model.pcm_dev_cfg & CAPTURE_2_FROM_AC97_1)) + (chip->model.device_config & CAPTURE_2_FROM_AC97_1)) runtime->hw = oxygen_ac97_hardware; else runtime->hw = *oxygen_hardware[channel]; @@ -381,7 +381,7 @@ static int oxygen_rec_b_hw_params(struct snd_pcm_substream *substream, return err; is_ac97 = chip->has_ac97_1 && - (chip->model.pcm_dev_cfg & CAPTURE_2_FROM_AC97_1); + (chip->model.device_config & CAPTURE_2_FROM_AC97_1); spin_lock_irq(&chip->reg_lock); oxygen_write8_masked(chip, OXYGEN_REC_FORMAT, @@ -657,9 +657,9 @@ int oxygen_pcm_init(struct oxygen *chip) int outs, ins; int err; - outs = !!(chip->model.pcm_dev_cfg & PLAYBACK_0_TO_I2S); - ins = !!(chip->model.pcm_dev_cfg & (CAPTURE_0_FROM_I2S_1 | - CAPTURE_0_FROM_I2S_2)); + outs = !!(chip->model.device_config & PLAYBACK_0_TO_I2S); + ins = !!(chip->model.device_config & (CAPTURE_0_FROM_I2S_1 | + CAPTURE_0_FROM_I2S_2)); if (outs | ins) { err = snd_pcm_new(chip->card, "Analog", 0, outs, ins, &pcm); if (err < 0) @@ -667,10 +667,10 @@ int oxygen_pcm_init(struct oxygen *chip) if (outs) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &oxygen_multich_ops); - if (chip->model.pcm_dev_cfg & CAPTURE_0_FROM_I2S_1) + if (chip->model.device_config & CAPTURE_0_FROM_I2S_1) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &oxygen_rec_a_ops); - else if (chip->model.pcm_dev_cfg & CAPTURE_0_FROM_I2S_2) + else if (chip->model.device_config & CAPTURE_0_FROM_I2S_2) snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &oxygen_rec_b_ops); pcm->private_data = chip; @@ -690,8 +690,8 @@ int oxygen_pcm_init(struct oxygen *chip) BUFFER_BYTES_MAX); } - outs = !!(chip->model.pcm_dev_cfg & PLAYBACK_1_TO_SPDIF); - ins = !!(chip->model.pcm_dev_cfg & CAPTURE_1_FROM_SPDIF); + outs = !!(chip->model.device_config & PLAYBACK_1_TO_SPDIF); + ins = !!(chip->model.device_config & CAPTURE_1_FROM_SPDIF); if (outs | ins) { err = snd_pcm_new(chip->card, "Digital", 1, outs, ins, &pcm); if (err < 0) @@ -712,11 +712,11 @@ int oxygen_pcm_init(struct oxygen *chip) } if (chip->has_ac97_1) { - outs = !!(chip->model.pcm_dev_cfg & PLAYBACK_2_TO_AC97_1); - ins = !!(chip->model.pcm_dev_cfg & CAPTURE_2_FROM_AC97_1); + outs = !!(chip->model.device_config & PLAYBACK_2_TO_AC97_1); + ins = !!(chip->model.device_config & CAPTURE_2_FROM_AC97_1); } else { outs = 0; - ins = !!(chip->model.pcm_dev_cfg & CAPTURE_2_FROM_I2S_2); + ins = !!(chip->model.device_config & CAPTURE_2_FROM_I2S_2); } if (outs | ins) { err = snd_pcm_new(chip->card, outs ? "AC97" : "Analog2", diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c index 34baff19ad3..f416e68338e 100644 --- a/sound/pci/oxygen/virtuoso.c +++ b/sound/pci/oxygen/virtuoso.c @@ -566,10 +566,10 @@ static const struct oxygen_model model_xonar_d2 = { .update_dac_mute = update_pcm1796_mute, .dac_tlv = pcm1796_db_scale, .model_data_size = sizeof(struct xonar_data), - .pcm_dev_cfg = PLAYBACK_0_TO_I2S | - PLAYBACK_1_TO_SPDIF | - CAPTURE_0_FROM_I2S_2 | - CAPTURE_1_FROM_SPDIF, + .device_config = PLAYBACK_0_TO_I2S | + PLAYBACK_1_TO_SPDIF | + CAPTURE_0_FROM_I2S_2 | + CAPTURE_1_FROM_SPDIF, .dac_channels = 8, .dac_volume_min = 0x0f, .dac_volume_max = 0xff, @@ -598,9 +598,9 @@ static const struct oxygen_model model_xonar_d1 = { .ac97_switch = xonar_d1_ac97_switch, .dac_tlv = cs4362a_db_scale, .model_data_size = sizeof(struct xonar_data), - .pcm_dev_cfg = PLAYBACK_0_TO_I2S | - PLAYBACK_1_TO_SPDIF | - CAPTURE_0_FROM_I2S_2, + .device_config = PLAYBACK_0_TO_I2S | + PLAYBACK_1_TO_SPDIF | + CAPTURE_0_FROM_I2S_2, .dac_channels = 8, .dac_volume_min = 0, .dac_volume_max = 127, -- cgit v1.2.3 From dbbbd6744439d95d2b0dc23c5cdca2c477377f76 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 22 Sep 2008 09:03:42 +0200 Subject: ALSA: oxygen: configure MIDI via device_config To enable the MIDI port, model drivers must now set flags in device_config, not only in misc_flags. This allows model drivers to enable the UART without creating an ALSA MIDI device. Signed-off-by: Clemens Ladisch --- sound/pci/oxygen/oxygen.c | 1 + sound/pci/oxygen/oxygen.h | 21 +++++++++++++-------- sound/pci/oxygen/oxygen_lib.c | 9 +++++++-- sound/pci/oxygen/virtuoso.c | 4 +++- 4 files changed, 24 insertions(+), 11 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index bb2e7d82d83..62888c7b61d 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -297,6 +297,7 @@ static int generic_probe(struct oxygen *chip, unsigned long driver_data) CAPTURE_0_FROM_I2S_2 | CAPTURE_1_FROM_SPDIF; chip->model.misc_flags = OXYGEN_MISC_MIDI; + chip->model.device_config |= MIDI_OUTPUT | MIDI_INPUT; } return 0; } diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h index 30cd996d366..f82a96290f7 100644 --- a/sound/pci/oxygen/oxygen.h +++ b/sound/pci/oxygen/oxygen.h @@ -19,14 +19,19 @@ #define OXYGEN_IO_SIZE 0x100 /* model-specific configuration of outputs/inputs */ -#define PLAYBACK_0_TO_I2S 0x001 -#define PLAYBACK_1_TO_SPDIF 0x004 -#define PLAYBACK_2_TO_AC97_1 0x008 -#define CAPTURE_0_FROM_I2S_1 0x010 -#define CAPTURE_0_FROM_I2S_2 0x020 -#define CAPTURE_1_FROM_SPDIF 0x080 -#define CAPTURE_2_FROM_I2S_2 0x100 -#define CAPTURE_2_FROM_AC97_1 0x200 +#define PLAYBACK_0_TO_I2S 0x0001 + /* PLAYBACK_0_TO_AC97_0 not implemented */ +#define PLAYBACK_1_TO_SPDIF 0x0004 +#define PLAYBACK_2_TO_AC97_1 0x0008 +#define CAPTURE_0_FROM_I2S_1 0x0010 +#define CAPTURE_0_FROM_I2S_2 0x0020 + /* CAPTURE_0_FROM_AC97_0 not implemented */ +#define CAPTURE_1_FROM_SPDIF 0x0080 +#define CAPTURE_2_FROM_I2S_2 0x0100 +#define CAPTURE_2_FROM_AC97_1 0x0200 + /* CAPTURE_3_FROM_I2S_3 not implemented */ +#define MIDI_OUTPUT 0x0800 +#define MIDI_INPUT 0x1000 enum { CONTROL_SPDIF_PCM, diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c index 02191c6a4e7..b1997216b4a 100644 --- a/sound/pci/oxygen/oxygen_lib.c +++ b/sound/pci/oxygen/oxygen_lib.c @@ -502,10 +502,15 @@ int oxygen_pci_probe(struct pci_dev *pci, int index, char *id, if (err < 0) goto err_card; - if (chip->model.misc_flags & OXYGEN_MISC_MIDI) { + if (chip->model.device_config & (MIDI_OUTPUT | MIDI_INPUT)) { + unsigned int info_flags = MPU401_INFO_INTEGRATED; + if (chip->model.device_config & MIDI_OUTPUT) + info_flags |= MPU401_INFO_OUTPUT; + if (chip->model.device_config & MIDI_INPUT) + info_flags |= MPU401_INFO_INPUT; err = snd_mpu401_uart_new(card, 0, MPU401_HW_CMIPCI, chip->addr + OXYGEN_MPU401, - MPU401_INFO_INTEGRATED, 0, 0, + info_flags, 0, 0, &chip->midi); if (err < 0) goto err_card; diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c index f416e68338e..befada742ae 100644 --- a/sound/pci/oxygen/virtuoso.c +++ b/sound/pci/oxygen/virtuoso.c @@ -569,7 +569,9 @@ static const struct oxygen_model model_xonar_d2 = { .device_config = PLAYBACK_0_TO_I2S | PLAYBACK_1_TO_SPDIF | CAPTURE_0_FROM_I2S_2 | - CAPTURE_1_FROM_SPDIF, + CAPTURE_1_FROM_SPDIF | + MIDI_OUTPUT | + MIDI_INPUT, .dac_channels = 8, .dac_volume_min = 0x0f, .dac_volume_max = 0xff, -- cgit v1.2.3 From 397b1dcc449082ce3f720c548da9c59db01cb739 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 22 Sep 2008 09:04:43 +0200 Subject: ALSA: oxygen: add UART I/O functions Add functions to allow model drivers to communicate with external chips by doing I/O with the not-used-for-MIDI UART. Signed-off-by: Clemens Ladisch --- sound/pci/oxygen/oxygen.h | 6 ++++++ sound/pci/oxygen/oxygen_io.c | 21 +++++++++++++++++++++ sound/pci/oxygen/oxygen_lib.c | 32 ++++++++++++++++++++++++++++++-- 3 files changed, 57 insertions(+), 2 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/oxygen.h b/sound/pci/oxygen/oxygen.h index f82a96290f7..19107c6307e 100644 --- a/sound/pci/oxygen/oxygen.h +++ b/sound/pci/oxygen/oxygen.h @@ -79,6 +79,7 @@ struct oxygen_model { void (*update_dac_volume)(struct oxygen *chip); void (*update_dac_mute)(struct oxygen *chip); void (*gpio_changed)(struct oxygen *chip); + void (*uart_input)(struct oxygen *chip); void (*ac97_switch)(struct oxygen *chip, unsigned int reg, unsigned int mute); const unsigned int *dac_tlv; @@ -125,6 +126,8 @@ struct oxygen { __le32 _32[OXYGEN_IO_SIZE / 4]; } saved_registers; u16 saved_ac97_registers[2][0x40]; + unsigned int uart_input_count; + u8 uart_input[32]; struct oxygen_model model; }; @@ -174,6 +177,9 @@ void oxygen_write_ac97_masked(struct oxygen *chip, unsigned int codec, void oxygen_write_spi(struct oxygen *chip, u8 control, unsigned int data); void oxygen_write_i2c(struct oxygen *chip, u8 device, u8 map, u8 data); +void oxygen_reset_uart(struct oxygen *chip); +void oxygen_write_uart(struct oxygen *chip, u8 data); + static inline void oxygen_set_bits8(struct oxygen *chip, unsigned int reg, u8 value) { diff --git a/sound/pci/oxygen/oxygen_io.c b/sound/pci/oxygen/oxygen_io.c index 83f135f80df..deba7389aec 100644 --- a/sound/pci/oxygen/oxygen_io.c +++ b/sound/pci/oxygen/oxygen_io.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include "oxygen.h" @@ -232,3 +233,23 @@ void oxygen_write_i2c(struct oxygen *chip, u8 device, u8 map, u8 data) device | OXYGEN_2WIRE_DIR_WRITE); } EXPORT_SYMBOL(oxygen_write_i2c); + +static void _write_uart(struct oxygen *chip, unsigned int port, u8 data) +{ + if (oxygen_read8(chip, OXYGEN_MPU401 + 1) & MPU401_TX_FULL) + msleep(1); + oxygen_write8(chip, OXYGEN_MPU401 + port, data); +} + +void oxygen_reset_uart(struct oxygen *chip) +{ + _write_uart(chip, 1, MPU401_RESET); + _write_uart(chip, 1, MPU401_ENTER_UART); +} +EXPORT_SYMBOL(oxygen_reset_uart); + +void oxygen_write_uart(struct oxygen *chip, u8 data) +{ + _write_uart(chip, 0, data); +} +EXPORT_SYMBOL(oxygen_write_uart); diff --git a/sound/pci/oxygen/oxygen_lib.c b/sound/pci/oxygen/oxygen_lib.c index b1997216b4a..84f481d41ef 100644 --- a/sound/pci/oxygen/oxygen_lib.c +++ b/sound/pci/oxygen/oxygen_lib.c @@ -35,6 +35,30 @@ MODULE_DESCRIPTION("C-Media CMI8788 helper library"); MODULE_LICENSE("GPL v2"); +static inline int oxygen_uart_input_ready(struct oxygen *chip) +{ + return !(oxygen_read8(chip, OXYGEN_MPU401 + 1) & MPU401_RX_EMPTY); +} + +static void oxygen_read_uart(struct oxygen *chip) +{ + if (unlikely(!oxygen_uart_input_ready(chip))) { + /* no data, but read it anyway to clear the interrupt */ + oxygen_read8(chip, OXYGEN_MPU401); + return; + } + do { + u8 data = oxygen_read8(chip, OXYGEN_MPU401); + if (data == MPU401_ACK) + continue; + if (chip->uart_input_count >= ARRAY_SIZE(chip->uart_input)) + chip->uart_input_count = 0; + chip->uart_input[chip->uart_input_count++] = data; + } while (oxygen_uart_input_ready(chip)); + if (chip->model.uart_input) + chip->model.uart_input(chip); +} + static irqreturn_t oxygen_interrupt(int dummy, void *dev_id) { struct oxygen *chip = dev_id; @@ -87,8 +111,12 @@ static irqreturn_t oxygen_interrupt(int dummy, void *dev_id) if (status & OXYGEN_INT_GPIO) schedule_work(&chip->gpio_work); - if ((status & OXYGEN_INT_MIDI) && chip->midi) - snd_mpu401_uart_interrupt(0, chip->midi->private_data); + if (status & OXYGEN_INT_MIDI) { + if (chip->midi) + snd_mpu401_uart_interrupt(0, chip->midi->private_data); + else + oxygen_read_uart(chip); + } if (status & OXYGEN_INT_AC97) wake_up(&chip->ac97_waitqueue); -- cgit v1.2.3 From c2bc4ff58d7aabcf1fc96134200d685d796ae425 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 22 Sep 2008 09:05:29 +0200 Subject: ALSA: oxygen: add self-documenting functions Introduce some trivial functions to better document the relationships of the various model callbacks. Signed-off-by: Clemens Ladisch --- sound/pci/oxygen/hifier.c | 7 ++++++- sound/pci/oxygen/oxygen.c | 7 ++++++- sound/pci/oxygen/virtuoso.c | 25 ++++++++++++++++++++----- 3 files changed, 32 insertions(+), 7 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/hifier.c b/sound/pci/oxygen/hifier.c index 088939903ee..1ab833f843e 100644 --- a/sound/pci/oxygen/hifier.c +++ b/sound/pci/oxygen/hifier.c @@ -94,6 +94,11 @@ static void hifier_cleanup(struct oxygen *chip) { } +static void hifier_resume(struct oxygen *chip) +{ + hifier_registers_init(chip); +} + static void set_ak4396_params(struct oxygen *chip, struct snd_pcm_hw_params *params) { @@ -150,7 +155,7 @@ static const struct oxygen_model model_hifier = { .init = hifier_init, .control_filter = hifier_control_filter, .cleanup = hifier_cleanup, - .resume = hifier_registers_init, + .resume = hifier_resume, .set_dac_params = set_ak4396_params, .set_adc_params = set_cs5340_params, .update_dac_volume = update_ak4396_volume, diff --git a/sound/pci/oxygen/oxygen.c b/sound/pci/oxygen/oxygen.c index 62888c7b61d..b60f6212745 100644 --- a/sound/pci/oxygen/oxygen.c +++ b/sound/pci/oxygen/oxygen.c @@ -204,6 +204,11 @@ static void generic_resume(struct oxygen *chip) wm8785_registers_init(chip); } +static void meridian_resume(struct oxygen *chip) +{ + ak4396_registers_init(chip); +} + static void set_ak4396_params(struct oxygen *chip, struct snd_pcm_hw_params *params) { @@ -290,7 +295,7 @@ static int generic_probe(struct oxygen *chip, unsigned long driver_data) { if (driver_data == MODEL_MERIDIAN) { chip->model.init = meridian_init; - chip->model.resume = ak4396_registers_init; + chip->model.resume = meridian_resume; chip->model.set_adc_params = set_ak5385_params; chip->model.device_config = PLAYBACK_0_TO_I2S | PLAYBACK_1_TO_SPDIF | diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c index befada742ae..8f65aa80d3b 100644 --- a/sound/pci/oxygen/virtuoso.c +++ b/sound/pci/oxygen/virtuoso.c @@ -349,20 +349,35 @@ static void xonar_d1_init(struct oxygen *chip) snd_component_add(chip->card, "CS5361"); } -static void xonar_cleanup(struct oxygen *chip) +static void xonar_disable_output(struct oxygen *chip) { struct xonar_data *data = chip->model_data; oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, data->output_enable_bit); } +static void xonar_d2_cleanup(struct oxygen *chip) +{ + xonar_disable_output(chip); +} + static void xonar_d1_cleanup(struct oxygen *chip) { - xonar_cleanup(chip); + xonar_disable_output(chip); cs4362a_write(chip, 0x01, CS4362A_PDN | CS4362A_CPEN); oxygen_clear_bits8(chip, OXYGEN_FUNCTION, OXYGEN_FUNCTION_RESET_CODEC); } +static void xonar_d2_suspend(struct oxygen *chip) +{ + xonar_d2_cleanup(chip); +} + +static void xonar_d1_suspend(struct oxygen *chip) +{ + xonar_d1_cleanup(chip); +} + static void xonar_d2_resume(struct oxygen *chip) { pcm1796_init(chip); @@ -557,8 +572,8 @@ static const struct oxygen_model model_xonar_d2 = { .init = xonar_d2_init, .control_filter = xonar_d2_control_filter, .mixer_init = xonar_d2_mixer_init, - .cleanup = xonar_cleanup, - .suspend = xonar_cleanup, + .cleanup = xonar_d2_cleanup, + .suspend = xonar_d2_suspend, .resume = xonar_d2_resume, .set_dac_params = set_pcm1796_params, .set_adc_params = set_cs53x1_params, @@ -591,7 +606,7 @@ static const struct oxygen_model model_xonar_d1 = { .control_filter = xonar_d1_control_filter, .mixer_init = xonar_d1_mixer_init, .cleanup = xonar_d1_cleanup, - .suspend = xonar_d1_cleanup, + .suspend = xonar_d1_suspend, .resume = xonar_d1_resume, .set_dac_params = set_cs43xx_params, .set_adc_params = set_cs53x1_params, -- cgit v1.2.3 From 4f50d2fd00da451261f51f28e929ebd161068422 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 22 Sep 2008 09:06:04 +0200 Subject: ALSA: virtuoso: allow I2C-connected PCM1796 Add support for PCM1796 chips that are connected with an I2C bus instead of SPI. Signed-off-by: Clemens Ladisch --- sound/pci/oxygen/virtuoso.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c index 8f65aa80d3b..853e8898bf9 100644 --- a/sound/pci/oxygen/virtuoso.c +++ b/sound/pci/oxygen/virtuoso.c @@ -124,6 +124,7 @@ MODULE_DEVICE_TABLE(pci, xonar_ids); #define GPIO_DX_FRONT_PANEL 0x0002 #define GPIO_DX_INPUT_ROUTE 0x0100 +#define I2C_DEVICE_PCM1796(i) (0x98 + ((i) << 1)) /* 10011, ADx=i, /W=0 */ #define I2C_DEVICE_CS4398 0x9e /* 10011, AD1=1, AD0=1, /W=0 */ #define I2C_DEVICE_CS4362A 0x30 /* 001100, AD0=0, /W=0 */ @@ -142,8 +143,8 @@ struct xonar_data { static void xonar_gpio_changed(struct oxygen *chip); -static void pcm1796_write(struct oxygen *chip, unsigned int codec, - u8 reg, u8 value) +static inline void pcm1796_write_spi(struct oxygen *chip, unsigned int codec, + u8 reg, u8 value) { /* maps ALSA channel pair number to SPI output */ static const u8 codec_map[4] = { @@ -157,6 +158,22 @@ static void pcm1796_write(struct oxygen *chip, unsigned int codec, (reg << 8) | value); } +static inline void pcm1796_write_i2c(struct oxygen *chip, unsigned int codec, + u8 reg, u8 value) +{ + oxygen_write_i2c(chip, I2C_DEVICE_PCM1796(codec), reg, value); +} + +static void pcm1796_write(struct oxygen *chip, unsigned int codec, + u8 reg, u8 value) +{ + if ((chip->model.function_flags & OXYGEN_FUNCTION_2WIRE_SPI_MASK) == + OXYGEN_FUNCTION_SPI) + pcm1796_write_spi(chip, codec, reg, value); + else + pcm1796_write_i2c(chip, codec, reg, value); +} + static void cs4398_write(struct oxygen *chip, u8 reg, u8 value) { oxygen_write_i2c(chip, I2C_DEVICE_CS4398, reg, value); -- cgit v1.2.3 From 70c27d345ed74ca9ea7ebf1fa0186af644caeb1d Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 22 Sep 2008 09:06:38 +0200 Subject: ALSA: virtuoso: make number of PCM1796 DACs configurable Do not use a hardcoded number when iterating over the PCM1796 DACs to allow for cards with a different number of analog output channels. Signed-off-by: Clemens Ladisch --- sound/pci/oxygen/virtuoso.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c index 853e8898bf9..0cecf1f9717 100644 --- a/sound/pci/oxygen/virtuoso.c +++ b/sound/pci/oxygen/virtuoso.c @@ -131,6 +131,7 @@ MODULE_DEVICE_TABLE(pci, xonar_ids); struct xonar_data { unsigned int model; unsigned int anti_pop_delay; + unsigned int dacs; u16 output_enable_bit; u8 ext_power_reg; u8 ext_power_int_reg; @@ -214,9 +215,10 @@ static void xonar_common_init(struct oxygen *chip) static void update_pcm1796_volume(struct oxygen *chip) { + struct xonar_data *data = chip->model_data; unsigned int i; - for (i = 0; i < 4; ++i) { + for (i = 0; i < data->dacs; ++i) { pcm1796_write(chip, i, 16, chip->dac_volume[i * 2]); pcm1796_write(chip, i, 17, chip->dac_volume[i * 2 + 1]); } @@ -224,13 +226,14 @@ static void update_pcm1796_volume(struct oxygen *chip) static void update_pcm1796_mute(struct oxygen *chip) { + struct xonar_data *data = chip->model_data; unsigned int i; u8 value; value = PCM1796_DMF_DISABLED | PCM1796_FMT_24_LJUST | PCM1796_ATLD; if (chip->dac_mute) value |= PCM1796_MUTE; - for (i = 0; i < 4; ++i) + for (i = 0; i < data->dacs; ++i) pcm1796_write(chip, i, 18, value); } @@ -239,7 +242,7 @@ static void pcm1796_init(struct oxygen *chip) struct xonar_data *data = chip->model_data; unsigned int i; - for (i = 0; i < 4; ++i) { + for (i = 0; i < data->dacs; ++i) { pcm1796_write(chip, i, 19, PCM1796_FLT_SHARP | PCM1796_ATS_1); pcm1796_write(chip, i, 20, data->pcm1796_oversampling); pcm1796_write(chip, i, 21, 0); @@ -415,7 +418,7 @@ static void set_pcm1796_params(struct oxygen *chip, data->pcm1796_oversampling = params_rate(params) >= 96000 ? PCM1796_OS_32 : PCM1796_OS_64; - for (i = 0; i < 4; ++i) + for (i = 0; i < data->dacs; ++i) pcm1796_write(chip, i, 20, data->pcm1796_oversampling); } @@ -574,9 +577,17 @@ static int xonar_model_probe(struct oxygen *chip, unsigned long driver_data) [MODEL_D2] = "Xonar D2", [MODEL_D2X] = "Xonar D2X", }; + static const u8 dacs[] = { + [MODEL_D1] = 2, + [MODEL_DX] = 2, + [MODEL_D2] = 4, + [MODEL_D2X] = 4, + }; struct xonar_data *data = chip->model_data; data->model = driver_data; + + data->dacs = dacs[data->model]; chip->model.shortname = names[data->model]; return 0; } -- cgit v1.2.3 From c871c4a83abaf6caedeff1c502e2c10fd88cbb54 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 22 Sep 2008 09:07:20 +0200 Subject: ALSA: virtuoso: rename AC97 callback function Rename the callback function that switches between line and mic inputs on the Xonar D1 because it is also usable on other models. Signed-off-by: Clemens Ladisch --- sound/pci/oxygen/virtuoso.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c index 0cecf1f9717..928283de6f3 100644 --- a/sound/pci/oxygen/virtuoso.c +++ b/sound/pci/oxygen/virtuoso.c @@ -529,8 +529,8 @@ static const struct snd_kcontrol_new front_panel_switch = { .private_value = GPIO_DX_FRONT_PANEL, }; -static void xonar_d1_ac97_switch(struct oxygen *chip, - unsigned int reg, unsigned int mute) +static void xonar_line_mic_ac97_switch(struct oxygen *chip, + unsigned int reg, unsigned int mute) { if (reg == AC97_LINE) { spin_lock_irq(&chip->reg_lock); @@ -640,7 +640,7 @@ static const struct oxygen_model model_xonar_d1 = { .set_adc_params = set_cs53x1_params, .update_dac_volume = update_cs43xx_volume, .update_dac_mute = update_cs43xx_mute, - .ac97_switch = xonar_d1_ac97_switch, + .ac97_switch = xonar_line_mic_ac97_switch, .dac_tlv = cs4362a_db_scale, .model_data_size = sizeof(struct xonar_data), .device_config = PLAYBACK_0_TO_I2S | -- cgit v1.2.3 From 79c50e23d4272404da7349010f514516976b447a Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 22 Sep 2008 09:07:53 +0200 Subject: ALSA: oxygen: rename first PCM device Rename the first PCM device from "Analog" to "Multichannel" because it can be used for HDMI output on the Xonar HDAV. Signed-off-by: Clemens Ladisch --- sound/pci/oxygen/oxygen_pcm.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/oxygen_pcm.c b/sound/pci/oxygen/oxygen_pcm.c index 87b60071b61..c262049961e 100644 --- a/sound/pci/oxygen/oxygen_pcm.c +++ b/sound/pci/oxygen/oxygen_pcm.c @@ -661,7 +661,8 @@ int oxygen_pcm_init(struct oxygen *chip) ins = !!(chip->model.device_config & (CAPTURE_0_FROM_I2S_1 | CAPTURE_0_FROM_I2S_2)); if (outs | ins) { - err = snd_pcm_new(chip->card, "Analog", 0, outs, ins, &pcm); + err = snd_pcm_new(chip->card, "Multichannel", + 0, outs, ins, &pcm); if (err < 0) return err; if (outs) @@ -675,7 +676,7 @@ int oxygen_pcm_init(struct oxygen *chip) &oxygen_rec_b_ops); pcm->private_data = chip; pcm->private_free = oxygen_pcm_free; - strcpy(pcm->name, "Analog"); + strcpy(pcm->name, "Multichannel"); if (outs) snd_pcm_lib_preallocate_pages(pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream, SNDRV_DMA_TYPE_DEV, -- cgit v1.2.3 From 7407a2e4b9e1fb3528bb355a571ee3eb7e32c386 Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Mon, 22 Sep 2008 09:12:11 +0200 Subject: ALSA: virtuoso: add Xonar HDAV1.3 support Add support for the Asus Xonar HDAV1.3 and the Xonar HDAV1.3 Deluxe. Signed-off-by: Clemens Ladisch --- sound/pci/Kconfig | 3 +- sound/pci/oxygen/virtuoso.c | 251 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 253 insertions(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index 4a7ebbc9676..1f8b7966a83 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -857,7 +857,8 @@ config SND_VIRTUOSO select SND_OXYGEN_LIB help Say Y here to include support for sound cards based on the - Asus AV100/AV200 chips, i.e., Xonar D1, DX, D2 and D2X. + Asus AV100/AV200 chips, i.e., Xonar D1, DX, D2, D2X and + HDAV1.3 (Deluxe). To compile this driver as a module, choose M here: the module will be called snd-virtuoso. diff --git a/sound/pci/oxygen/virtuoso.c b/sound/pci/oxygen/virtuoso.c index 928283de6f3..98c6a8c65d8 100644 --- a/sound/pci/oxygen/virtuoso.c +++ b/sound/pci/oxygen/virtuoso.c @@ -62,14 +62,66 @@ * AD0 <- 0 */ +/* + * Xonar HDAV1.3 (Deluxe) + * ---------------------- + * + * CMI8788: + * + * I²C <-> PCM1796 (front) + * + * GPI 0 <- external power present + * + * GPIO 0 -> enable output to speakers + * GPIO 2 -> M0 of CS5381 + * GPIO 3 -> M1 of CS5381 + * GPIO 8 -> route input jack to line-in (0) or mic-in (1) + * + * TXD -> HDMI controller + * RXD <- HDMI controller + * + * PCM1796 front: AD1,0 <- 0,0 + * + * no daughterboard + * ---------------- + * + * GPIO 4 <- 1 + * + * H6 daughterboard + * ---------------- + * + * GPIO 4 <- 0 + * GPIO 5 <- 0 + * + * I²C <-> PCM1796 (surround) + * <-> PCM1796 (center/LFE) + * <-> PCM1796 (back) + * + * PCM1796 surround: AD1,0 <- 0,1 + * PCM1796 center/LFE: AD1,0 <- 1,0 + * PCM1796 back: AD1,0 <- 1,1 + * + * unknown daughterboard + * --------------------- + * + * GPIO 4 <- 0 + * GPIO 5 <- 1 + * + * I²C <-> CS4362A (surround, center/LFE, back) + * + * CS4362A: AD0 <- 0 + */ + #include #include #include #include +#include #include #include #include #include +#include #include #include "oxygen.h" #include "cm9780.h" @@ -98,12 +150,15 @@ enum { MODEL_D2X, MODEL_D1, MODEL_DX, + MODEL_HDAV, /* without daughterboard */ + MODEL_HDAV_H6, /* with H6 daughterboard */ }; static struct pci_device_id xonar_ids[] __devinitdata = { { OXYGEN_PCI_SUBID(0x1043, 0x8269), .driver_data = MODEL_D2 }, { OXYGEN_PCI_SUBID(0x1043, 0x8275), .driver_data = MODEL_DX }, { OXYGEN_PCI_SUBID(0x1043, 0x82b7), .driver_data = MODEL_D2X }, + { OXYGEN_PCI_SUBID(0x1043, 0x8314), .driver_data = MODEL_HDAV }, { OXYGEN_PCI_SUBID(0x1043, 0x834f), .driver_data = MODEL_D1 }, { } }; @@ -124,6 +179,10 @@ MODULE_DEVICE_TABLE(pci, xonar_ids); #define GPIO_DX_FRONT_PANEL 0x0002 #define GPIO_DX_INPUT_ROUTE 0x0100 +#define GPIO_HDAV_DB_MASK 0x0030 +#define GPIO_HDAV_DB_H6 0x0000 +#define GPIO_HDAV_DB_XX 0x0020 + #define I2C_DEVICE_PCM1796(i) (0x98 + ((i) << 1)) /* 10011, ADx=i, /W=0 */ #define I2C_DEVICE_CS4398 0x9e /* 10011, AD1=1, AD0=1, /W=0 */ #define I2C_DEVICE_CS4362A 0x30 /* 001100, AD0=0, /W=0 */ @@ -140,6 +199,7 @@ struct xonar_data { u8 pcm1796_oversampling; u8 cs4398_fm; u8 cs4362a_fm; + u8 hdmi_params[5]; }; static void xonar_gpio_changed(struct oxygen *chip); @@ -185,6 +245,24 @@ static void cs4362a_write(struct oxygen *chip, u8 reg, u8 value) oxygen_write_i2c(chip, I2C_DEVICE_CS4362A, reg, value); } +static void hdmi_write_command(struct oxygen *chip, u8 command, + unsigned int count, const u8 *params) +{ + unsigned int i; + u8 checksum; + + oxygen_write_uart(chip, 0xfb); + oxygen_write_uart(chip, 0xef); + oxygen_write_uart(chip, command); + oxygen_write_uart(chip, count); + for (i = 0; i < count; ++i) + oxygen_write_uart(chip, params[i]); + checksum = 0xfb + 0xef + command + count; + for (i = 0; i < count; ++i) + checksum += params[i]; + oxygen_write_uart(chip, checksum); +} + static void xonar_enable_output(struct oxygen *chip) { struct xonar_data *data = chip->model_data; @@ -369,6 +447,43 @@ static void xonar_d1_init(struct oxygen *chip) snd_component_add(chip->card, "CS5361"); } +static void xonar_hdav_init(struct oxygen *chip) +{ + struct xonar_data *data = chip->model_data; + u8 param; + + oxygen_write16(chip, OXYGEN_2WIRE_BUS_STATUS, + OXYGEN_2WIRE_LENGTH_8 | + OXYGEN_2WIRE_INTERRUPT_MASK | + OXYGEN_2WIRE_SPEED_FAST); + + data->anti_pop_delay = 100; + data->output_enable_bit = GPIO_DX_OUTPUT_ENABLE; + data->ext_power_reg = OXYGEN_GPI_DATA; + data->ext_power_int_reg = OXYGEN_GPI_INTERRUPT_MASK; + data->ext_power_bit = GPI_DX_EXT_POWER; + data->pcm1796_oversampling = PCM1796_OS_64; + + pcm1796_init(chip); + + oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL, GPIO_DX_INPUT_ROUTE); + oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_DX_INPUT_ROUTE); + + oxygen_reset_uart(chip); + param = 0; + hdmi_write_command(chip, 0x61, 1, ¶m); + param = 1; + hdmi_write_command(chip, 0x74, 1, ¶m); + data->hdmi_params[1] = IEC958_AES3_CON_FS_48000; + data->hdmi_params[4] = 1; + hdmi_write_command(chip, 0x54, 5, data->hdmi_params); + + xonar_common_init(chip); + + snd_component_add(chip->card, "PCM1796"); + snd_component_add(chip->card, "CS5381"); +} + static void xonar_disable_output(struct oxygen *chip) { struct xonar_data *data = chip->model_data; @@ -388,6 +503,14 @@ static void xonar_d1_cleanup(struct oxygen *chip) oxygen_clear_bits8(chip, OXYGEN_FUNCTION, OXYGEN_FUNCTION_RESET_CODEC); } +static void xonar_hdav_cleanup(struct oxygen *chip) +{ + u8 param = 0; + + hdmi_write_command(chip, 0x74, 1, ¶m); + xonar_disable_output(chip); +} + static void xonar_d2_suspend(struct oxygen *chip) { xonar_d2_cleanup(chip); @@ -398,6 +521,12 @@ static void xonar_d1_suspend(struct oxygen *chip) xonar_d1_cleanup(chip); } +static void xonar_hdav_suspend(struct oxygen *chip) +{ + xonar_hdav_cleanup(chip); + msleep(2); +} + static void xonar_d2_resume(struct oxygen *chip) { pcm1796_init(chip); @@ -410,6 +539,33 @@ static void xonar_d1_resume(struct oxygen *chip) xonar_enable_output(chip); } +static void xonar_hdav_resume(struct oxygen *chip) +{ + struct xonar_data *data = chip->model_data; + u8 param; + + oxygen_reset_uart(chip); + param = 0; + hdmi_write_command(chip, 0x61, 1, ¶m); + param = 1; + hdmi_write_command(chip, 0x74, 1, ¶m); + hdmi_write_command(chip, 0x54, 5, data->hdmi_params); + pcm1796_init(chip); + xonar_enable_output(chip); +} + +static void xonar_hdav_pcm_hardware_filter(unsigned int channel, + struct snd_pcm_hardware *hardware) +{ + if (channel == PCM_MULTICH) { + hardware->rates = SNDRV_PCM_RATE_44100 | + SNDRV_PCM_RATE_48000 | + SNDRV_PCM_RATE_96000 | + SNDRV_PCM_RATE_192000; + hardware->rate_min = 44100; + } +} + static void set_pcm1796_params(struct oxygen *chip, struct snd_pcm_hw_params *params) { @@ -460,6 +616,42 @@ static void set_cs43xx_params(struct oxygen *chip, cs4362a_write(chip, 0x0c, data->cs4362a_fm); } +static void set_hdmi_params(struct oxygen *chip, + struct snd_pcm_hw_params *params) +{ + struct xonar_data *data = chip->model_data; + + data->hdmi_params[0] = 0; /* 1 = non-audio */ + switch (params_rate(params)) { + case 44100: + data->hdmi_params[1] = IEC958_AES3_CON_FS_44100; + break; + case 48000: + data->hdmi_params[1] = IEC958_AES3_CON_FS_48000; + break; + default: /* 96000 */ + data->hdmi_params[1] = IEC958_AES3_CON_FS_96000; + break; + case 192000: + data->hdmi_params[1] = IEC958_AES3_CON_FS_192000; + break; + } + data->hdmi_params[2] = params_channels(params) / 2 - 1; + if (params_format(params) == SNDRV_PCM_FORMAT_S16_LE) + data->hdmi_params[3] = 0; + else + data->hdmi_params[3] = 0xc0; + data->hdmi_params[4] = 1; /* ? */ + hdmi_write_command(chip, 0x54, 5, data->hdmi_params); +} + +static void set_hdav_params(struct oxygen *chip, + struct snd_pcm_hw_params *params) +{ + set_pcm1796_params(chip, params); + set_hdmi_params(chip, params); +} + static void xonar_gpio_changed(struct oxygen *chip) { struct xonar_data *data = chip->model_data; @@ -479,6 +671,18 @@ static void xonar_gpio_changed(struct oxygen *chip) } } +static void xonar_hdav_uart_input(struct oxygen *chip) +{ + if (chip->uart_input_count >= 2 && + chip->uart_input[chip->uart_input_count - 2] == 'O' && + chip->uart_input[chip->uart_input_count - 1] == 'K') { + printk(KERN_DEBUG "message from Xonar HDAV HDMI chip received:"); + print_hex_dump_bytes("", DUMP_PREFIX_OFFSET, + chip->uart_input, chip->uart_input_count); + chip->uart_input_count = 0; + } +} + static int gpio_bit_switch_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value) { @@ -576,16 +780,33 @@ static int xonar_model_probe(struct oxygen *chip, unsigned long driver_data) [MODEL_DX] = "Xonar DX", [MODEL_D2] = "Xonar D2", [MODEL_D2X] = "Xonar D2X", + [MODEL_HDAV] = "Xonar HDAV1.3", + [MODEL_HDAV_H6] = "Xonar HDAV1.3+H6", }; static const u8 dacs[] = { [MODEL_D1] = 2, [MODEL_DX] = 2, [MODEL_D2] = 4, [MODEL_D2X] = 4, + [MODEL_HDAV] = 1, + [MODEL_HDAV_H6] = 4, }; struct xonar_data *data = chip->model_data; data->model = driver_data; + if (data->model == MODEL_HDAV) { + oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL, + GPIO_HDAV_DB_MASK); + switch (oxygen_read16(chip, OXYGEN_GPIO_DATA) & + GPIO_HDAV_DB_MASK) { + case GPIO_HDAV_DB_H6: + data->model = MODEL_HDAV_H6; + break; + case GPIO_HDAV_DB_XX: + snd_printk(KERN_ERR "unknown daughterboard\n"); + return -ENODEV; + } + } data->dacs = dacs[data->model]; chip->model.shortname = names[data->model]; @@ -654,6 +875,35 @@ static const struct oxygen_model model_xonar_d1 = { .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, }; +static const struct oxygen_model model_xonar_hdav = { + .longname = "Asus Virtuoso 200", + .chip = "AV200", + .owner = THIS_MODULE, + .probe = xonar_model_probe, + .init = xonar_hdav_init, + .cleanup = xonar_hdav_cleanup, + .suspend = xonar_hdav_suspend, + .resume = xonar_hdav_resume, + .pcm_hardware_filter = xonar_hdav_pcm_hardware_filter, + .set_dac_params = set_hdav_params, + .set_adc_params = set_cs53x1_params, + .update_dac_volume = update_pcm1796_volume, + .update_dac_mute = update_pcm1796_mute, + .uart_input = xonar_hdav_uart_input, + .ac97_switch = xonar_line_mic_ac97_switch, + .dac_tlv = pcm1796_db_scale, + .model_data_size = sizeof(struct xonar_data), + .device_config = PLAYBACK_0_TO_I2S | + PLAYBACK_1_TO_SPDIF | + CAPTURE_0_FROM_I2S_2, + .dac_channels = 8, + .dac_volume_min = 0x0f, + .dac_volume_max = 0xff, + .function_flags = OXYGEN_FUNCTION_2WIRE, + .dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST, + .adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST, +}; + static int __devinit xonar_probe(struct pci_dev *pci, const struct pci_device_id *pci_id) { @@ -662,6 +912,7 @@ static int __devinit xonar_probe(struct pci_dev *pci, [MODEL_DX] = &model_xonar_d1, [MODEL_D2] = &model_xonar_d2, [MODEL_D2X] = &model_xonar_d2, + [MODEL_HDAV] = &model_xonar_hdav, }; static int dev; int err; -- cgit v1.2.3 From 9932fbb0b37d13201655b4de2b9acda2f415d83b Mon Sep 17 00:00:00 2001 From: Herton Ronaldo Krzesinski Date: Sat, 13 Sep 2008 16:44:29 +0200 Subject: ALSA: hda: fix oopses in snd-hda-intel after digital slave support additions Many places fail to check if codec has slave_dig_outs entries (the most common case is not having any entry), leading to various possible oopses in hda_codec code. Signed-off-by: Herton Ronaldo Krzesinski Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_codec.c | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 696d77e575e..531364d3535 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -1462,14 +1462,15 @@ static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol, AC_VERB_SET_DIGI_CONVERT_2, val >> 8); - for (d = codec->slave_dig_outs; *d; d++) { - snd_hda_codec_write_cache(codec, *d, 0, + if (codec->slave_dig_outs) + for (d = codec->slave_dig_outs; *d; d++) { + snd_hda_codec_write_cache(codec, *d, 0, AC_VERB_SET_DIGI_CONVERT_1, val & 0xff); - snd_hda_codec_write_cache(codec, *d, 0, + snd_hda_codec_write_cache(codec, *d, 0, AC_VERB_SET_DIGI_CONVERT_2, val >> 8); - } + } } mutex_unlock(&codec->spdif_mutex); @@ -1507,8 +1508,9 @@ static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol, AC_VERB_SET_DIGI_CONVERT_1, val & 0xff); - for (d = codec->slave_dig_outs; *d; d++) - snd_hda_codec_write_cache(codec, *d, 0, + if (codec->slave_dig_outs) + for (d = codec->slave_dig_outs; *d; d++) + snd_hda_codec_write_cache(codec, *d, 0, AC_VERB_SET_DIGI_CONVERT_1, val & 0xff); /* unmute amp switch (if any) */ @@ -1664,8 +1666,9 @@ static int snd_hda_spdif_in_switch_put(struct snd_kcontrol *kcontrol, snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, val); - for (d = codec->slave_dig_outs; *d; d++) - snd_hda_codec_write_cache(codec, *d, 0, + if (codec->slave_dig_outs) + for (d = codec->slave_dig_outs; *d; d++) + snd_hda_codec_write_cache(codec, *d, 0, AC_VERB_SET_DIGI_CONVERT_1, val); } mutex_unlock(&codec->spdif_mutex); @@ -2617,9 +2620,10 @@ static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid, snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff); - for (d = codec->slave_dig_outs; *d; d++) - snd_hda_codec_write(codec, *d, 0, - AC_VERB_SET_DIGI_CONVERT_1, + if (codec->slave_dig_outs) + for (d = codec->slave_dig_outs; *d; d++) + snd_hda_codec_write(codec, *d, 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); @@ -2628,9 +2632,10 @@ static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid, snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, codec->spdif_ctls & 0xff); - for (d = codec->slave_dig_outs; *d; d++) - snd_hda_codec_write(codec, *d, 0, - AC_VERB_SET_DIGI_CONVERT_1, + if (codec->slave_dig_outs) + for (d = codec->slave_dig_outs; *d; d++) + snd_hda_codec_write(codec, *d, 0, + AC_VERB_SET_DIGI_CONVERT_1, codec->spdif_ctls & 0xff); } -- cgit v1.2.3 From 6a14f58518dd18d315eaa6e4ca38bc6b051927af Mon Sep 17 00:00:00 2001 From: Matthew Ranostay Date: Fri, 12 Sep 2008 12:02:30 -0400 Subject: ALSA: hda: Added a STAC_HP_M4 quirk Added a new quirk for STAC_HP_M4 series for an 92hd75xxx family laptop. Signed-off-by: Matthew Ranostay Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 4343d5fe5f7..9744ae31dc7 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -80,6 +80,7 @@ enum { STAC_92HD71BXX_REF, STAC_DELL_M4_1, STAC_DELL_M4_2, + STAC_HP_M4, STAC_92HD71BXX_MODELS }; @@ -1527,12 +1528,14 @@ static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = { [STAC_92HD71BXX_REF] = ref92hd71bxx_pin_configs, [STAC_DELL_M4_1] = dell_m4_1_pin_configs, [STAC_DELL_M4_2] = dell_m4_2_pin_configs, + [STAC_HP_M4] = NULL, }; static const char *stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = { [STAC_92HD71BXX_REF] = "ref", [STAC_DELL_M4_1] = "dell-m4-1", [STAC_DELL_M4_2] = "dell-m4-2", + [STAC_HP_M4] = "hp-m4", }; static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { @@ -4204,10 +4207,24 @@ again: spec->num_muxes = ARRAY_SIZE(stac92hd71bxx_mux_nids); spec->num_adcs = ARRAY_SIZE(stac92hd71bxx_adc_nids); - spec->num_dmics = STAC92HD71BXX_NUM_DMICS; - spec->num_smuxes = ARRAY_SIZE(stac92hd71bxx_smux_nids); spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); + switch (spec->board_config) { + case STAC_HP_M4: + spec->num_dmics = 0; + spec->num_smuxes = 1; + spec->num_dmuxes = 0; + + /* enable internal microphone */ + snd_hda_codec_write_cache(codec, 0x0e, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80); + break; + default: + spec->num_dmics = STAC92HD71BXX_NUM_DMICS; + spec->num_smuxes = ARRAY_SIZE(stac92hd71bxx_smux_nids); + spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); + }; + spec->multiout.num_dacs = 1; spec->multiout.hp_nid = 0x11; spec->multiout.dac_nids = stac92hd71bxx_dac_nids; -- cgit v1.2.3 From 89385035fa3126dff27bfb73d186bc51e78d5ba5 Mon Sep 17 00:00:00 2001 From: Matthew Ranostay Date: Thu, 11 Sep 2008 09:49:39 -0400 Subject: ALSA: hda: Input port AMP controls Added support for controlling hardware gain amps on input ports using a volume control mixer with a mux selecting the port being controlled. Signed-off-by: Matthew Ranostay Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_codec.c | 9 --- sound/pci/hda/hda_local.h | 9 +++ sound/pci/hda/patch_sigmatel.c | 138 ++++++++++++++++++++++++++++++++++++++++- 3 files changed, 145 insertions(+), 11 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 531364d3535..c742e101d91 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -961,15 +961,6 @@ void snd_hda_codec_resume_amp(struct hda_codec *codec) } #endif /* SND_HDA_NEEDS_RESUME */ -/* - * AMP control callbacks - */ -/* retrieve parameters from private_value */ -#define get_amp_nid(kc) ((kc)->private_value & 0xffff) -#define get_amp_channels(kc) (((kc)->private_value >> 16) & 0x3) -#define get_amp_direction(kc) (((kc)->private_value >> 18) & 0x1) -#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) diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 5c9e578f7f2..d688f50cdfc 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h @@ -418,4 +418,13 @@ int snd_hda_check_amp_list_power(struct hda_codec *codec, hda_nid_t nid); #endif /* CONFIG_SND_HDA_POWER_SAVE */ +/* + * AMP control callbacks + */ +/* retrieve parameters from private_value */ +#define get_amp_nid(kc) ((kc)->private_value & 0xffff) +#define get_amp_channels(kc) (((kc)->private_value >> 16) & 0x3) +#define get_amp_direction(kc) (((kc)->private_value >> 18) & 0x1) +#define get_amp_index(kc) (((kc)->private_value >> 19) & 0xf) + #endif /* __SOUND_HDA_LOCAL_H */ diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 9744ae31dc7..d3c88c269da 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -157,10 +157,13 @@ struct sigmatel_spec { unsigned int num_pwrs; unsigned int *pwr_mapping; hda_nid_t *pwr_nids; + hda_nid_t *amp_nids; hda_nid_t *dac_list; /* playback */ struct hda_input_mux *mono_mux; + struct hda_input_mux *amp_mux; + unsigned int cur_amux; unsigned int cur_mmux; struct hda_multi_out multiout; hda_nid_t dac_nids[5]; @@ -216,6 +219,7 @@ struct sigmatel_spec { struct hda_input_mux private_dimux; struct hda_input_mux private_imux; struct hda_input_mux private_smux; + struct hda_input_mux private_amp_mux; struct hda_input_mux private_mono_mux; }; @@ -244,6 +248,10 @@ static hda_nid_t stac92hd73xx_adc_nids[2] = { 0x1a, 0x1b }; +static hda_nid_t stac92hd73xx_amp_nids[4] = { + 0x0b, 0x0c, 0x0e, 0 +}; + #define STAC92HD73XX_NUM_DMICS 2 static hda_nid_t stac92hd73xx_dmic_nids[STAC92HD73XX_NUM_DMICS + 1] = { 0x13, 0x14, 0 @@ -449,6 +457,34 @@ static hda_nid_t stac9205_pin_nids[12] = { 0x21, 0x22, }; +#define stac92xx_amp_volume_info snd_hda_mixer_amp_volume_info + +static int stac92xx_amp_volume_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct sigmatel_spec *spec = codec->spec; + hda_nid_t nid = spec->amp_nids[spec->cur_amux]; + + kcontrol->private_value ^= get_amp_nid(kcontrol); + kcontrol->private_value |= nid; + + return snd_hda_mixer_amp_volume_get(kcontrol, ucontrol); +} + +static int stac92xx_amp_volume_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct sigmatel_spec *spec = codec->spec; + hda_nid_t nid = spec->amp_nids[spec->cur_amux]; + + kcontrol->private_value ^= get_amp_nid(kcontrol); + kcontrol->private_value |= nid; + + return snd_hda_mixer_amp_volume_put(kcontrol, ucontrol); +} + static int stac92xx_dmux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { @@ -564,6 +600,41 @@ static int stac92xx_mono_mux_enum_put(struct snd_kcontrol *kcontrol, spec->mono_nid, &spec->cur_mmux); } +static int stac92xx_amp_mux_enum_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct sigmatel_spec *spec = codec->spec; + return snd_hda_input_mux_info(spec->amp_mux, uinfo); +} + +static int stac92xx_amp_mux_enum_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct sigmatel_spec *spec = codec->spec; + + ucontrol->value.enumerated.item[0] = spec->cur_amux; + return 0; +} + +static int stac92xx_amp_mux_enum_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct sigmatel_spec *spec = codec->spec; + struct snd_kcontrol *ctl = + snd_hda_find_mixer_ctl(codec, "Amp Capture Volume"); + if (!ctl) + return -EINVAL; + + snd_ctl_notify(codec->bus->card, SNDRV_CTL_EVENT_MASK_VALUE | + SNDRV_CTL_EVENT_MASK_INFO, &ctl->id); + + return snd_hda_input_mux_put(codec, spec->amp_mux, ucontrol, + 0, &spec->cur_amux); +} + #define stac92xx_aloopback_info snd_ctl_boolean_mono_info static int stac92xx_aloopback_get(struct snd_kcontrol *kcontrol, @@ -838,6 +909,31 @@ static struct hda_verb stac9205_core_init[] = { .put = stac92xx_mono_mux_enum_put, \ } +#define STAC_AMP_MUX \ + { \ + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .name = "Amp Selector Capture Switch", \ + .count = 1, \ + .info = stac92xx_amp_mux_enum_info, \ + .get = stac92xx_amp_mux_enum_get, \ + .put = stac92xx_amp_mux_enum_put, \ + } + +#define STAC_AMP_VOL(xname, nid, chs, idx, dir) \ + { \ + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .name = xname, \ + .index = 0, \ + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \ + SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ + SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, \ + .info = stac92xx_amp_volume_info, \ + .get = stac92xx_amp_volume_get, \ + .put = stac92xx_amp_volume_put, \ + .tlv = { .c = snd_hda_mixer_amp_tlv }, \ + .private_value = HDA_COMPOSE_AMP_VAL(nid, chs, idx, dir) \ + } + #define STAC_INPUT_SOURCE(cnt) \ { \ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ @@ -2421,6 +2517,8 @@ enum { STAC_CTL_WIDGET_VOL, STAC_CTL_WIDGET_MUTE, STAC_CTL_WIDGET_MONO_MUX, + STAC_CTL_WIDGET_AMP_MUX, + STAC_CTL_WIDGET_AMP_VOL, STAC_CTL_WIDGET_HP_SWITCH, STAC_CTL_WIDGET_IO_SWITCH, STAC_CTL_WIDGET_CLFE_SWITCH @@ -2430,6 +2528,8 @@ static struct snd_kcontrol_new stac92xx_control_templates[] = { HDA_CODEC_VOLUME(NULL, 0, 0, 0), HDA_CODEC_MUTE(NULL, 0, 0, 0), STAC_MONO_MUX, + STAC_AMP_MUX, + STAC_AMP_VOL(NULL, 0, 0, 0, 0), STAC_CODEC_HP_SWITCH(NULL), STAC_CODEC_IO_SWITCH(NULL, 0), STAC_CODEC_CLFE_SWITCH(NULL, 0), @@ -2847,6 +2947,35 @@ static int stac92xx_auto_create_mono_output_ctls(struct hda_codec *codec) "Mono Mux", spec->mono_nid); } +/* labels for amp mux outputs */ +static const char *stac92xx_amp_labels[3] = { + "Front Microphone", "Microphone", "Line In" +}; + +/* create amp out controls mux on capable codecs */ +static int stac92xx_auto_create_amp_output_ctls(struct hda_codec *codec) +{ + struct sigmatel_spec *spec = codec->spec; + struct hda_input_mux *amp_mux = &spec->private_amp_mux; + int i, err; + + for (i = 0; i < ARRAY_SIZE(stac92xx_amp_labels); i++) { + amp_mux->items[amp_mux->num_items].label = + stac92xx_amp_labels[i]; + amp_mux->items[amp_mux->num_items].index = i; + amp_mux->num_items++; + } + + err = stac92xx_add_control(spec, STAC_CTL_WIDGET_AMP_MUX, + "Amp Selector Capture Switch", 0); + if (err < 0) + return err; + return stac92xx_add_control(spec, STAC_CTL_WIDGET_AMP_VOL, + "Amp Capture Volume", + HDA_COMPOSE_AMP_VAL(spec->amp_nids[0], 3, 0, HDA_INPUT)); +} + + /* create PC beep volume controls */ static int stac92xx_auto_create_beep_ctls(struct hda_codec *codec, hda_nid_t nid) @@ -3216,7 +3345,11 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out if (err < 0) return err; } - + if (spec->amp_nids) { + err = stac92xx_auto_create_amp_output_ctls(codec); + if (err < 0) + return err; + } if (spec->num_dmics > 0) if ((err = stac92xx_auto_create_dmic_input_ctls(codec, &spec->autocfg)) < 0) @@ -3249,7 +3382,7 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out spec->dinput_mux = &spec->private_dimux; spec->sinput_mux = &spec->private_smux; spec->mono_mux = &spec->private_mono_mux; - + spec->amp_mux = &spec->private_amp_mux; return 1; } @@ -3917,6 +4050,7 @@ again: spec->dmic_nids = stac92hd73xx_dmic_nids; spec->dmux_nids = stac92hd73xx_dmux_nids; spec->smux_nids = stac92hd73xx_smux_nids; + spec->amp_nids = stac92hd73xx_amp_nids; spec->num_muxes = ARRAY_SIZE(stac92hd73xx_mux_nids); spec->num_adcs = ARRAY_SIZE(stac92hd73xx_adc_nids); -- cgit v1.2.3 From f7cf0a7ce56eb91752fa441cff2669f8d61d4e5e Mon Sep 17 00:00:00 2001 From: Matthew Ranostay Date: Sat, 13 Sep 2008 10:36:58 -0400 Subject: ALSA: hda: fixed hp_nid DAC for DELL_M6 This patch sets the HP out not used by the "Headphone to Line Out" switch to the hp_nid. Signed-off-by: Matthew Ranostay Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index d3c88c269da..e2b45b2f8f3 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -729,8 +729,8 @@ static struct hda_verb dell_eq_core_init[] = { { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec}, /* setup audio connections */ { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, - { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01}, - { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x02}, + { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x02}, + { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x01}, /* setup adcs to point to mixer */ { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, -- cgit v1.2.3 From 2a9c78160895af2a69ebcb1ac8be54b84815cfcf Mon Sep 17 00:00:00 2001 From: Matthew Ranostay Date: Sat, 13 Sep 2008 16:45:39 -0400 Subject: ALSA: hda: 92hd73xx fixes Added support for defining the number of amps and the creation of the private_dimux dynamically for the 92hd73xx codec family. Signed-off-by: Matthew Ranostay [Fixed a typo by tiwai] Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 78 ++++++++++++++++++++++++++---------------- 1 file changed, 49 insertions(+), 29 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index e2b45b2f8f3..16fc3aeeb13 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -157,13 +157,11 @@ struct sigmatel_spec { unsigned int num_pwrs; unsigned int *pwr_mapping; hda_nid_t *pwr_nids; - hda_nid_t *amp_nids; hda_nid_t *dac_list; /* playback */ struct hda_input_mux *mono_mux; struct hda_input_mux *amp_mux; - unsigned int cur_amux; unsigned int cur_mmux; struct hda_multi_out multiout; hda_nid_t dac_nids[5]; @@ -202,6 +200,9 @@ struct sigmatel_spec { unsigned int cur_mux[3]; struct hda_input_mux *sinput_mux; unsigned int cur_smux[2]; + unsigned int cur_amux; + hda_nid_t *amp_nids; + unsigned int num_amps; unsigned int powerdown_adcs; /* i/o switches */ @@ -248,8 +249,9 @@ static hda_nid_t stac92hd73xx_adc_nids[2] = { 0x1a, 0x1b }; -static hda_nid_t stac92hd73xx_amp_nids[4] = { - 0x0b, 0x0c, 0x0e, 0 +#define DELL_M6_AMP 2 +static hda_nid_t stac92hd73xx_amp_nids[3] = { + 0x0b, 0x0c, 0x0e }; #define STAC92HD73XX_NUM_DMICS 2 @@ -964,29 +966,33 @@ static struct snd_kcontrol_new stac9200_mixer[] = { { } /* end */ }; +#define DELL_M6_MIXER 6 static struct snd_kcontrol_new stac92hd73xx_6ch_mixer[] = { - STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 3), - - HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT), - - HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x21, 0x0, HDA_OUTPUT), - HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x21, 0x0, HDA_OUTPUT), - + /* start of config #1 */ HDA_CODEC_VOLUME("Front Mic Mixer Capture Volume", 0x1d, 0, HDA_INPUT), HDA_CODEC_MUTE("Front Mic Mixer Capture Switch", 0x1d, 0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Mixer Capture Volume", 0x1d, 0x1, HDA_INPUT), - HDA_CODEC_MUTE("Mic Mixer Capture Switch", 0x1d, 0x1, HDA_INPUT), - HDA_CODEC_VOLUME("Line In Mixer Capture Volume", 0x1d, 0x2, HDA_INPUT), HDA_CODEC_MUTE("Line In Mixer Capture Switch", 0x1d, 0x2, HDA_INPUT), + HDA_CODEC_VOLUME("CD Mixer Capture Volume", 0x1d, 0x4, HDA_INPUT), + HDA_CODEC_MUTE("CD Mixer Capture Switch", 0x1d, 0x4, HDA_INPUT), + + /* start of config #2 */ + HDA_CODEC_VOLUME("Mic Mixer Capture Volume", 0x1d, 0x1, HDA_INPUT), + HDA_CODEC_MUTE("Mic Mixer Capture Switch", 0x1d, 0x1, HDA_INPUT), + HDA_CODEC_VOLUME("DAC Mixer Capture Volume", 0x1d, 0x3, HDA_INPUT), HDA_CODEC_MUTE("DAC Mixer Capture Switch", 0x1d, 0x3, HDA_INPUT), - HDA_CODEC_VOLUME("CD Mixer Capture Volume", 0x1d, 0x4, HDA_INPUT), - HDA_CODEC_MUTE("CD Mixer Capture Switch", 0x1d, 0x4, HDA_INPUT), + STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 3), + + HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT), + + HDA_CODEC_VOLUME_IDX("Capture Volume", 0x1, 0x21, 0x0, HDA_OUTPUT), + HDA_CODEC_MUTE_IDX("Capture Switch", 0x1, 0x21, 0x0, HDA_OUTPUT), + { } /* end */ }; @@ -2959,17 +2965,19 @@ static int stac92xx_auto_create_amp_output_ctls(struct hda_codec *codec) struct hda_input_mux *amp_mux = &spec->private_amp_mux; int i, err; - for (i = 0; i < ARRAY_SIZE(stac92xx_amp_labels); i++) { + for (i = 0; i < spec->num_amps; i++) { amp_mux->items[amp_mux->num_items].label = stac92xx_amp_labels[i]; amp_mux->items[amp_mux->num_items].index = i; amp_mux->num_items++; } - err = stac92xx_add_control(spec, STAC_CTL_WIDGET_AMP_MUX, - "Amp Selector Capture Switch", 0); - if (err < 0) - return err; + if (spec->num_amps > 1) { + err = stac92xx_add_control(spec, STAC_CTL_WIDGET_AMP_MUX, + "Amp Selector Capture Switch", 0); + if (err < 0) + return err; + } return stac92xx_add_control(spec, STAC_CTL_WIDGET_AMP_VOL, "Amp Capture Volume", HDA_COMPOSE_AMP_VAL(spec->amp_nids[0], 3, 0, HDA_INPUT)); @@ -3345,12 +3353,12 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out if (err < 0) return err; } - if (spec->amp_nids) { + if (spec->num_amps > 0) { err = stac92xx_auto_create_amp_output_ctls(codec); if (err < 0) return err; } - if (spec->num_dmics > 0) + if (spec->num_dmics > 0 && !spec->dinput_mux) if ((err = stac92xx_auto_create_dmic_input_ctls(codec, &spec->autocfg)) < 0) return err; @@ -3378,8 +3386,7 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out spec->mixers[spec->num_mixers++] = spec->kctl_alloc; spec->input_mux = &spec->private_imux; - if (!spec->dinput_mux) - spec->dinput_mux = &spec->private_dimux; + spec->dinput_mux = &spec->private_dimux; spec->sinput_mux = &spec->private_smux; spec->mono_mux = &spec->private_mono_mux; spec->amp_mux = &spec->private_amp_mux; @@ -3978,9 +3985,9 @@ static struct hda_input_mux stac92hd73xx_dmux = { .num_items = 4, .items = { { "Analog Inputs", 0x0b }, - { "CD", 0x08 }, { "Digital Mic 1", 0x09 }, { "Digital Mic 2", 0x0a }, + { "CD", 0x08 }, } }; @@ -4051,12 +4058,14 @@ again: spec->dmux_nids = stac92hd73xx_dmux_nids; spec->smux_nids = stac92hd73xx_smux_nids; spec->amp_nids = stac92hd73xx_amp_nids; + spec->num_amps = ARRAY_SIZE(stac92hd73xx_amp_nids); spec->num_muxes = ARRAY_SIZE(stac92hd73xx_mux_nids); spec->num_adcs = ARRAY_SIZE(stac92hd73xx_adc_nids); spec->num_dmuxes = ARRAY_SIZE(stac92hd73xx_dmux_nids); - spec->num_smuxes = ARRAY_SIZE(stac92hd73xx_smux_nids); - spec->dinput_mux = &stac92hd73xx_dmux; + memcpy(&spec->private_dimux, &stac92hd73xx_dmux, + sizeof(stac92hd73xx_dmux)); + /* GPIO0 High = Enable EAPD */ spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1; spec->gpio_data = 0x01; @@ -4064,11 +4073,18 @@ again: switch (spec->board_config) { case STAC_DELL_M6: spec->init = dell_eq_core_init; + spec->num_smuxes = 0; + spec->multiout.hp_nid = + spec->multiout.dac_nids[spec->multiout.num_dacs - 1]; + spec->mixer = &stac92hd73xx_6ch_mixer[DELL_M6_MIXER]; + spec->amp_nids = &stac92hd73xx_amp_nids[DELL_M6_AMP]; + spec->num_amps = 1; switch (codec->subsystem_id) { case 0x1028025e: /* Analog Mics */ case 0x1028025f: stac92xx_set_config_reg(codec, 0x0b, 0x90A70170); spec->num_dmics = 0; + spec->private_dimux.num_items = 1; break; case 0x10280271: /* Digital Mics */ case 0x10280272: @@ -4078,18 +4094,22 @@ again: case 0x10280255: stac92xx_set_config_reg(codec, 0x13, 0x90A60160); spec->num_dmics = 1; + spec->private_dimux.num_items = 2; break; case 0x10280256: /* Both */ case 0x10280057: stac92xx_set_config_reg(codec, 0x0b, 0x90A70170); stac92xx_set_config_reg(codec, 0x13, 0x90A60160); spec->num_dmics = 1; + spec->private_dimux.num_items = 2; break; } break; default: spec->num_dmics = STAC92HD73XX_NUM_DMICS; + spec->num_smuxes = ARRAY_SIZE(stac92hd73xx_smux_nids); } + spec->dinput_mux = &spec->private_dimux; spec->num_pwrs = ARRAY_SIZE(stac92hd73xx_pwr_nids); spec->pwr_nids = stac92hd73xx_pwr_nids; -- cgit v1.2.3 From e8bfc6c1d22395ab706784cb1bcd60f6f9569ed6 Mon Sep 17 00:00:00 2001 From: "Robin H. Johnson" Date: Sat, 13 Sep 2008 16:55:00 -0700 Subject: ALSA: HDA: patch_analog: Fix SPDIF output on AD1989B The SPDIF pins for AD1989 are not enabled by default. Set OUT bit so that they actually work. Also initialize the HDMI SPDIF at the same time. Signed-off-by: Robin H. Johnson Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_analog.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 0899b6b3886..03b9d3df4eb 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -2249,8 +2249,12 @@ static struct hda_verb ad1988_spdif_init_verbs[] = { /* AD1989 has no ADC -> SPDIF route */ static struct hda_verb ad1989_spdif_init_verbs[] = { - /* SPDIF out pin */ + /* SPDIF-1 out pin */ + {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */ + /* SPDIF-2/HDMI out pin */ + {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, + {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */ { } }; -- cgit v1.2.3 From 35e8901e4de1d9d054ce6afe53293320651970fb Mon Sep 17 00:00:00 2001 From: "Robin H. Johnson" Date: Sat, 13 Sep 2008 16:54:59 -0700 Subject: ALSA: HDA: hda_local: Less magic numbers. Explain some of the magic numbers I saw while trying to fix the AD1989 SPDIF issue. Maybe should just use the expanded form directly in the verbs? Signed-off-by: Robin H. Johnson Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_local.h | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index d688f50cdfc..7957fefda73 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h @@ -368,12 +368,15 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, #define AMP_OUT_UNMUTE 0xb000 #define AMP_OUT_ZERO 0xb000 /* pinctl values */ -#define PIN_IN 0x20 -#define PIN_VREF80 0x24 -#define PIN_VREF50 0x21 -#define PIN_OUT 0x40 -#define PIN_HP 0xc0 -#define PIN_HP_AMP 0x80 +#define PIN_IN (AC_PINCTL_IN_EN) +#define PIN_VREFHIZ (AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ) +#define PIN_VREF50 (AC_PINCTL_IN_EN | AC_PINCTL_VREF_50) +#define PIN_VREFGRD (AC_PINCTL_IN_EN | AC_PINCTL_VREF_GRD) +#define PIN_VREF80 (AC_PINCTL_IN_EN | AC_PINCTL_VREF_80) +#define PIN_VREF100 (AC_PINCTL_IN_EN | AC_PINCTL_VREF_100) +#define PIN_OUT (AC_PINCTL_OUT_EN) +#define PIN_HP (AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN) +#define PIN_HP_AMP (AC_PINCTL_HP_EN) /* * get widget capabilities -- cgit v1.2.3 From 0481f4534910e644626a3607b2a1a979420a2d05 Mon Sep 17 00:00:00 2001 From: "Robin H. Johnson" Date: Sat, 13 Sep 2008 16:54:57 -0700 Subject: ALSA: HDA: hda_proc: Fix printf format specifier The Pincap output had a typod format specifier, leading to an extraneous "08" in the output, which is a reserved bit of the Vref field, and was really confused :-). Signed-off-by: Robin H. Johnson Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_proc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c index 4927c4b6bf6..743d77922bc 100644 --- a/sound/pci/hda/hda_proc.c +++ b/sound/pci/hda/hda_proc.c @@ -216,7 +216,7 @@ static void print_pin_caps(struct snd_info_buffer *buffer, unsigned int caps, val; caps = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); - snd_iprintf(buffer, " Pincap 0x08%x:", caps); + snd_iprintf(buffer, " Pincap 0x%08x:", caps); if (caps & AC_PINCAP_IN) snd_iprintf(buffer, " IN"); if (caps & AC_PINCAP_OUT) -- cgit v1.2.3 From 9cae0c63785d7e1ee1c97ca75148174d483f5200 Mon Sep 17 00:00:00 2001 From: "Robin H. Johnson" Date: Sat, 13 Sep 2008 16:54:58 -0700 Subject: ALSA: HDA: patch_analog: Implement multiple outputs for AD1988 Implement the slave_dig_outs for AD1989 cards. Untested due to lack of hardware. Signed-off-by: Robin H. Johnson Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_analog.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 03b9d3df4eb..42b1a231347 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -1826,9 +1826,14 @@ static hda_nid_t ad1988_capsrc_nids[3] = { 0x0c, 0x0d, 0x0e }; -#define AD1988_SPDIF_OUT 0x02 +#define AD1988_SPDIF_OUT 0x02 +#define AD1988_SPDIF_OUT_HDMI 0x0b #define AD1988_SPDIF_IN 0x07 +static hda_nid_t ad1989b_slave_dig_outs[2] = { + AD1988_SPDIF_OUT, AD1988_SPDIF_OUT_HDMI +}; + static struct hda_input_mux ad1988_6stack_capture_source = { .num_items = 5, .items = { @@ -2143,6 +2148,7 @@ static struct snd_kcontrol_new ad1988_spdif_in_mixers[] = { static struct snd_kcontrol_new ad1989_spdif_out_mixers[] = { HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT), + HDA_CODEC_VOLUME("HDMI Playback Volume", 0x1d, 0x0, HDA_OUTPUT), { } /* end */ }; @@ -2985,6 +2991,7 @@ static int patch_ad1988(struct hda_codec *codec) ad1989_spdif_out_mixers; spec->init_verbs[spec->num_init_verbs++] = ad1989_spdif_init_verbs; + codec->slave_dig_outs = ad1989b_slave_dig_outs; } else { spec->mixers[spec->num_mixers++] = ad1988_spdif_out_mixers; -- cgit v1.2.3 From f51ff9937bc6732ed5fc08088fdbe89ab8ed27c3 Mon Sep 17 00:00:00 2001 From: "Robin H. Johnson" Date: Sat, 13 Sep 2008 16:55:01 -0700 Subject: ALSA: HDA: patch_analog: Quirk for Asus P5Q Premium/Pro boards. Use 6STACK_DIG for the AD2000BX variant of the AD1989B chip used by Asus on their Asus P5Q Premium and Pro boards. Signed-off-by: Robin H. Johnson Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_analog.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 42b1a231347..2b00c4afdf9 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -2884,6 +2884,7 @@ static struct snd_pci_quirk ad1988_cfg_tbl[] = { SND_PCI_QUIRK(0x1043, 0x81ec, "Asus P5B-DLX", AD1988_6STACK_DIG), SND_PCI_QUIRK(0x1043, 0x81f6, "Asus M2N-SLI", AD1988_6STACK_DIG), SND_PCI_QUIRK(0x1043, 0x8277, "Asus P5K-E/WIFI-AP", AD1988_6STACK_DIG), + SND_PCI_QUIRK(0x1043, 0x8311, "Asus P5Q-Premium/Pro", AD1988_6STACK_DIG), {} }; -- cgit v1.2.3 From f8fdd4958b6c7af9abf630f06d43db4ddcd532f6 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Mon, 15 Sep 2008 22:41:31 +0800 Subject: ALSA: HDA VIA: Fix crash on codecs without Headphone Don't enumerate via_hp_mixer while hp_mux is null (headphone does not exist), to fix the crash of via_independent_hp_info (via_hp_mixer's .info), which will reference hp_mux. Signed-off-by: Logan Li Signed-off-by: Harald Welte Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_via.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 6e360d39c02..43fb96538b8 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -1303,7 +1303,8 @@ static int vt1708_parse_auto_config(struct hda_codec *codec) spec->input_mux = &spec->private_imux[0]; - spec->mixers[spec->num_mixers++] = via_hp_mixer; + if (spec->hp_mux) + spec->mixers[spec->num_mixers++] = via_hp_mixer; return 1; } @@ -1773,6 +1774,9 @@ static int vt1709_parse_auto_config(struct hda_codec *codec) spec->input_mux = &spec->private_imux[0]; + if (spec->hp_mux) + spec->mixers[spec->num_mixers++] = via_hp_mixer; + return 1; } @@ -2314,7 +2318,8 @@ static int vt1708B_parse_auto_config(struct hda_codec *codec) spec->input_mux = &spec->private_imux[0]; - spec->mixers[spec->num_mixers++] = via_hp_mixer; + if (spec->hp_mux) + spec->mixers[spec->num_mixers++] = via_hp_mixer; return 1; } @@ -2770,7 +2775,8 @@ static int vt1708S_parse_auto_config(struct hda_codec *codec) spec->input_mux = &spec->private_imux[0]; - spec->mixers[spec->num_mixers++] = via_hp_mixer; + if (spec->hp_mux) + spec->mixers[spec->num_mixers++] = via_hp_mixer; return 1; } @@ -3100,7 +3106,8 @@ static int vt1702_parse_auto_config(struct hda_codec *codec) spec->input_mux = &spec->private_imux[0]; - spec->mixers[spec->num_mixers++] = via_hp_mixer; + if (spec->hp_mux) + spec->mixers[spec->num_mixers++] = via_hp_mixer; return 1; } -- cgit v1.2.3 From 5691ec7fc302ecffddfa21b19477aaaa4386d002 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Mon, 15 Sep 2008 22:42:26 +0800 Subject: ALSA: HDA VIA: Fix 2nd S/PDIF out function As it seems, the recently-sent patch for the 2nd S/PDIF (HDMI) output is not working with alsa-kernel 1.0.18rc3. This patch makes it work by * activating the second S/PDIF output pin in the pin config * consolidating the dig_playback_pcm_prepare() with extra_dig_pcm_prepare() functions * remove the need for an extra hda_pcm_stream structure and rather represents the second digital output as substream within the primary S/PDIF digital out stream. Signed-off-by: Logan Li Signed-off-by: Harald Welte Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_via.c | 75 ++++++++++++++--------------------------------- 1 file changed, 22 insertions(+), 53 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 43fb96538b8..59a173e8812 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -123,7 +123,6 @@ struct via_spec { char *stream_name_digital; struct hda_pcm_stream *stream_digital_playback; struct hda_pcm_stream *stream_digital_capture; - struct hda_pcm_stream *stream_extra_digital_playback; /* playback */ struct hda_multi_out multiout; @@ -656,17 +655,6 @@ 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); -} - /* setup SPDIF output stream */ static void setup_dig_playback_stream(struct hda_codec *codec, hda_nid_t nid, unsigned int stream_tag, unsigned int format) @@ -682,17 +670,25 @@ static void setup_dig_playback_stream(struct hda_codec *codec, hda_nid_t nid, codec->spdif_ctls & 0xff); } -static int via_extra_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, +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; + hda_nid_t nid; + + /* 1st or 2nd S/PDIF */ + if (substream->number == 0) + nid = spec->multiout.dig_out_nid; + else if (substream->number == 1) + nid = spec->extra_dig_out_nid; + else + return -1; mutex_lock(&codec->spdif_mutex); - setup_dig_playback_stream(codec, spec->extra_dig_out_nid, stream_tag, - format); + setup_dig_playback_stream(codec, nid, stream_tag, format); mutex_unlock(&codec->spdif_mutex); return 0; } @@ -854,17 +850,6 @@ static int via_build_pcms(struct hda_codec *codec) } } - if (spec->extra_dig_out_nid) { - codec->num_pcms++; - info++; - info->name = spec->stream_name_digital; - info->pcm_type = HDA_PCM_TYPE_HDMI; - info->stream[SNDRV_PCM_STREAM_PLAYBACK] = - *(spec->stream_extra_digital_playback); - info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = - spec->extra_dig_out_nid; - } - return 0; } @@ -957,6 +942,10 @@ static void via_unsol_event(struct hda_codec *codec, via_gpio_control(codec); } +static hda_nid_t slave_dig_outs[] = { + 0, +}; + static int via_init(struct hda_codec *codec) { struct via_spec *spec = codec->spec; @@ -991,6 +980,9 @@ static int via_init(struct hda_codec *codec) snd_hda_codec_write(codec, spec->autocfg.dig_in_pin, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN); + /* no slave outs */ + codec->slave_dig_outs = slave_dig_outs; + return 0; } @@ -2477,8 +2469,9 @@ static struct hda_verb vt1708S_volume_init_verbs[] = { /* Setup default input of PW4 to MW0 */ {0x1d, AC_VERB_SET_CONNECT_SEL, 0x0}, - /* PW9 Output enable */ + /* PW9, PW10 Output enable */ {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, + {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, { } }; @@ -2511,7 +2504,7 @@ static struct hda_pcm_stream vt1708S_pcm_analog_capture = { }; static struct hda_pcm_stream vt1708S_pcm_digital_playback = { - .substreams = 1, + .substreams = 2, .channels_min = 2, .channels_max = 2, /* NID is set in via_build_pcms */ @@ -2522,16 +2515,6 @@ static struct hda_pcm_stream vt1708S_pcm_digital_playback = { }, }; -static struct hda_pcm_stream vt1708S_pcm_extra_digital_playback = { - .substreams = 1, - .channels_min = 2, - .channels_max = 2, - /* NID is set in via_build_pcms */ - .ops = { - .prepare = via_extra_dig_playback_pcm_prepare - }, -}; - /* fill in the dac_nids table from the parsed pin configuration */ static int vt1708S_auto_fill_dac_nids(struct via_spec *spec, const struct auto_pin_cfg *cfg) @@ -2822,8 +2805,6 @@ static int patch_vt1708S(struct hda_codec *codec) spec->stream_name_digital = "VT1708S Digital"; spec->stream_digital_playback = &vt1708S_pcm_digital_playback; - spec->stream_extra_digital_playback = - &vt1708S_pcm_extra_digital_playback; if (!spec->adc_nids && spec->input_mux) { spec->adc_nids = vt1708S_adc_nids; @@ -2927,7 +2908,7 @@ static struct hda_pcm_stream vt1702_pcm_analog_capture = { }; static struct hda_pcm_stream vt1702_pcm_digital_playback = { - .substreams = 1, + .substreams = 2, .channels_min = 2, .channels_max = 2, /* NID is set in via_build_pcms */ @@ -2938,16 +2919,6 @@ static struct hda_pcm_stream vt1702_pcm_digital_playback = { }, }; -static struct hda_pcm_stream vt1702_pcm_extra_digital_playback = { - .substreams = 1, - .channels_min = 2, - .channels_max = 2, - /* NID is set in via_build_pcms */ - .ops = { - .prepare = via_extra_dig_playback_pcm_prepare - }, -}; - /* fill in the dac_nids table from the parsed pin configuration */ static int vt1702_auto_fill_dac_nids(struct via_spec *spec, const struct auto_pin_cfg *cfg) @@ -3155,8 +3126,6 @@ static int patch_vt1702(struct hda_codec *codec) spec->stream_name_digital = "VT1702 Digital"; spec->stream_digital_playback = &vt1702_pcm_digital_playback; - spec->stream_extra_digital_playback = - &vt1702_pcm_extra_digital_playback; if (!spec->adc_nids && spec->input_mux) { spec->adc_nids = vt1702_adc_nids; -- cgit v1.2.3 From d74263296658f55ecca1f0b95c106b73d239ea2f Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Mon, 15 Sep 2008 22:43:23 +0800 Subject: ALSA: HDA VIA: Replace buggy Mic Boost VT1708S' Mic Boost should be hidden in hardware design according to some customers' requirements. However, in case of bugs, it has to be exhibited to normal users, so we need to: * open a software backdoor, which is disabled by default in hardware * re-write .tlv & .info, to indicate the actual necessary info, which we cannot get from amplifier's capabiliies Signed-off-by: Logan Li Signed-off-by: Harald Welte Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_via.c | 106 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 104 insertions(+), 2 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 59a173e8812..63e4871e5d8 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -35,6 +35,7 @@ /* 2008-04-09 Lydia Wang Add mute front speaker when HP plugin */ /* 2008-04-09 Lydia Wang Add Independent HP feature */ /* 2008-05-28 Lydia Wang Add second S/PDIF Out support for VT1702 */ +/* 2008-09-15 Logan Li Add VT1708S Mic Boost workaround/backdoor */ /* */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ @@ -87,6 +88,48 @@ #define IS_VT1708S_VENDORID(x) ((x) >= 0x11060397 && (x) <= 0x11067397) #define IS_VT1702_VENDORID(x) ((x) >= 0x11060398 && (x) <= 0x11067398) +enum VIA_HDA_CODEC { + UNKNOWN = -1, + VT1708, + VT1709_10CH, + VT1709_6CH, + VT1708B_8CH, + VT1708B_4CH, + VT1708S, + VT1702, + CODEC_TYPES, +}; + +static enum VIA_HDA_CODEC get_codec_type(u32 vendor_id) +{ + u16 ven_id = vendor_id >> 16; + u16 dev_id = vendor_id & 0xffff; + enum VIA_HDA_CODEC codec_type; + + /* get codec type */ + if (ven_id != 0x1106) + codec_type = UNKNOWN; + else if (dev_id >= 0x1708 && dev_id <= 0x170b) + codec_type = VT1708; + else if (dev_id >= 0xe710 && dev_id <= 0xe713) + codec_type = VT1709_10CH; + else if (dev_id >= 0xe714 && dev_id <= 0xe717) + codec_type = VT1709_6CH; + else if (dev_id >= 0xe720 && dev_id <= 0xe723) + codec_type = VT1708B_8CH; + else if (dev_id >= 0xe724 && dev_id <= 0xe727) + codec_type = VT1708B_4CH; + else if ((dev_id & 0xfff) == 0x397 + && (dev_id >> 12) < 8) + codec_type = VT1708S; + else if ((dev_id & 0xfff) == 0x398 + && (dev_id >> 12) < 8) + codec_type = VT1702; + else + codec_type = UNKNOWN; + return codec_type; +}; + #define VIA_HP_EVENT 0x01 #define VIA_GPIO_EVENT 0x02 @@ -102,6 +145,48 @@ enum { AUTO_SEQ_SIDE }; +#define get_amp_nid(kc) ((kc)->private_value & 0xffff) + +/* Some VT1708S based boards gets the micboost setting wrong, so we have + * to apply some brute-force and re-write the TLV's by software. */ +static int mic_boost_tlv(struct snd_kcontrol *kcontrol, int op_flag, + unsigned int size, unsigned int __user *_tlv) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + hda_nid_t nid = get_amp_nid(kcontrol); + + if (get_codec_type(codec->vendor_id) == VT1708S + && (nid == 0x1a || nid == 0x1e)) { + if (size < 4 * sizeof(unsigned int)) + return -ENOMEM; + if (put_user(1, _tlv)) /* SNDRV_CTL_TLVT_DB_SCALE */ + return -EFAULT; + if (put_user(2 * sizeof(unsigned int), _tlv + 1)) + return -EFAULT; + if (put_user(0, _tlv + 2)) /* offset = 0 */ + return -EFAULT; + if (put_user(1000, _tlv + 3)) /* step size = 10 dB */ + return -EFAULT; + } + return 0; +} + +static int mic_boost_volume_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + hda_nid_t nid = get_amp_nid(kcontrol); + + if (get_codec_type(codec->vendor_id) == VT1708S + && (nid == 0x1a || nid == 0x1e)) { + uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; + uinfo->count = 2; + uinfo->value.integer.min = 0; + uinfo->value.integer.max = 3; + } + return 0; +} + static struct snd_kcontrol_new vt1708_control_templates[] = { HDA_CODEC_VOLUME(NULL, 0, 0, 0), HDA_CODEC_MUTE(NULL, 0, 0, 0), @@ -2430,14 +2515,29 @@ static int patch_vt1708B_4ch(struct hda_codec *codec) /* Patch for VT1708S */ +/* VT1708S software backdoor based override for buggy hardware micboost + * setting */ +#define MIC_BOOST_VOLUME(xname, nid) { \ + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ + .name = xname, \ + .index = 0, \ + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \ + SNDRV_CTL_ELEM_ACCESS_TLV_READ | \ + SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, \ + .info = mic_boost_volume_info, \ + .get = snd_hda_mixer_amp_volume_get, \ + .put = snd_hda_mixer_amp_volume_put, \ + .tlv = { .c = mic_boost_tlv }, \ + .private_value = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT) } + /* capture mixer elements */ static struct snd_kcontrol_new vt1708S_capture_mixer[] = { HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT), HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT), HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x14, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Mic Boost", 0x1A, 0x0, HDA_INPUT), - HDA_CODEC_VOLUME("Front Mic Boost", 0x1E, 0x0, HDA_INPUT), + MIC_BOOST_VOLUME("Mic Boost Capture Volume", 0x1A), + MIC_BOOST_VOLUME("Front Mic Boost Capture Volume", 0x1E), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, /* The multiple "Capture Source" controls confuse alsamixer @@ -2472,6 +2572,8 @@ static struct hda_verb vt1708S_volume_init_verbs[] = { /* PW9, PW10 Output enable */ {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, + /* Enable Mic Boost Volume backdoor */ + {0x1, 0xf98, 0x1}, { } }; -- cgit v1.2.3 From 6597363219585be451e3b98c9485630ba656a536 Mon Sep 17 00:00:00 2001 From: Matthew Ranostay Date: Tue, 16 Sep 2008 10:39:37 -0400 Subject: ALSA: hda: SPDIF mux fixes for STAC927x Corrected bounds-checking in stac92xx_auto_create_mux_input_ctls() and added a spec->spdif_labels pointer for custom SPDIF mux labels for non-standard codec connections. Signed-off-by: Matthew Ranostay Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 16fc3aeeb13..bd0d6f8ab43 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -177,6 +177,7 @@ struct sigmatel_spec { unsigned int num_dmuxes; hda_nid_t *smux_nids; unsigned int num_smuxes; + const char **spdif_labels; hda_nid_t dig_in_nid; hda_nid_t mono_nid; @@ -394,6 +395,11 @@ static hda_nid_t stac927x_dmic_nids[STAC927X_NUM_DMICS + 1] = { 0x13, 0x14, 0 }; +static const char *stac927x_spdif_labels[5] = { + "Digital Playback", "ADAT", "Analog Mux 1", + "Analog Mux 2", "Analog Mux 3" +}; + static hda_nid_t stac9205_adc_nids[2] = { 0x12, 0x13 }; @@ -3033,26 +3039,29 @@ static int stac92xx_auto_create_mux_input_ctls(struct hda_codec *codec) }; static const char *stac92xx_spdif_labels[3] = { - "Digital Playback", "Analog Mux 1", "Analog Mux 2" + "Digital Playback", "Analog Mux 1", "Analog Mux 2", }; static int stac92xx_auto_create_spdif_mux_ctls(struct hda_codec *codec) { struct sigmatel_spec *spec = codec->spec; struct hda_input_mux *spdif_mux = &spec->private_smux; + const char **labels = spec->spdif_labels; int i, num_cons; - hda_nid_t con_lst[ARRAY_SIZE(stac92xx_spdif_labels)]; + hda_nid_t con_lst[HDA_MAX_NUM_INPUTS]; num_cons = snd_hda_get_connections(codec, spec->smux_nids[0], con_lst, HDA_MAX_NUM_INPUTS); - if (!num_cons || num_cons > ARRAY_SIZE(stac92xx_spdif_labels)) + if (!num_cons) return -EINVAL; + if (!labels) + labels = stac92xx_spdif_labels; + for (i = 0; i < num_cons; i++) { - spdif_mux->items[spdif_mux->num_items].label = - stac92xx_spdif_labels[i]; + spdif_mux->items[spdif_mux->num_items].label = labels[i]; spdif_mux->items[spdif_mux->num_items].index = i; spdif_mux->num_items++; } @@ -4547,6 +4556,7 @@ static int patch_stac927x(struct hda_codec *codec) spec->num_muxes = ARRAY_SIZE(stac927x_mux_nids); spec->smux_nids = stac927x_smux_nids; spec->num_smuxes = ARRAY_SIZE(stac927x_smux_nids); + spec->spdif_labels = stac927x_spdif_labels; spec->dac_list = stac927x_dac_nids; spec->multiout.dac_nids = spec->dac_nids; -- cgit v1.2.3 From 9c95c43de81d5556237fbc82c4e90403dfe468db Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Thu, 18 Sep 2008 13:37:13 -0700 Subject: ALSA: hda - Add PCI subsystem ID for MacBookPro4,1 This seems to work if I tell it that it's a mbp3. Not sure if there are actually any differences. Signed-off-by: David Woodhouse Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 5c80a27bfc8..6ada0e3436a 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6659,6 +6659,7 @@ static int patch_alc882(struct hda_codec *codec) board_config = ALC885_IMAC24; break; case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */ + case 0x106b00a4: /* MacbookPro4,1 */ case 0x106b2c00: /* Macbook Pro rev3 */ case 0x106b3600: /* Macbook 3.1 */ board_config = ALC885_MBP3; -- cgit v1.2.3 From b69ce01ae4ccbab2336b9beea83dea3ea3295df7 Mon Sep 17 00:00:00 2001 From: Herton Ronaldo Krzesinski Date: Thu, 18 Sep 2008 16:41:49 -0300 Subject: ALSA: hda - Fix ALC662 DAC mixer mutes also for auto config model In previous change "[ALSA] hda-codec - Fix ALC662 DAC mixer mutes", I missed to fix the mixer mute switches also for the auto config model of ALC662. Now mute for mixer items "Front", "Surround", "Center" and "LFE" when available will work too with "auto" model. Signed-off-by: Herton Ronaldo Krzesinski Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 6ada0e3436a..c2ff85dad50 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -15973,15 +15973,15 @@ static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec, HDA_OUTPUT)); if (err < 0) return err; - err = add_control(spec, ALC_CTL_BIND_MUTE, + err = add_control(spec, ALC_CTL_WIDGET_MUTE, "Center Playback Switch", - HDA_COMPOSE_AMP_VAL(nid, 1, 2, + HDA_COMPOSE_AMP_VAL(0x0e, 1, 0, HDA_INPUT)); if (err < 0) return err; - err = add_control(spec, ALC_CTL_BIND_MUTE, + err = add_control(spec, ALC_CTL_WIDGET_MUTE, "LFE Playback Switch", - HDA_COMPOSE_AMP_VAL(nid, 2, 2, + HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, HDA_INPUT)); if (err < 0) return err; @@ -15993,9 +15993,9 @@ static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec, 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)); + err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, + HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i), + 3, 0, HDA_INPUT)); if (err < 0) return err; } -- cgit v1.2.3 From cdad5b8db91ac46a8e226306d062fe4c896b2bed Mon Sep 17 00:00:00 2001 From: Clemens Ladisch Date: Wed, 24 Sep 2008 15:25:28 +0200 Subject: ALSA: oxygen: wait for ACK when resetting UART After sending a reset command to the UART, wait some time for the ACK to be generated (and to be read and dropped by the interrupt handler) before sending the next command. Signed-off-by: Clemens Ladisch --- sound/pci/oxygen/oxygen_io.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/pci') diff --git a/sound/pci/oxygen/oxygen_io.c b/sound/pci/oxygen/oxygen_io.c index deba7389aec..3126c4b403d 100644 --- a/sound/pci/oxygen/oxygen_io.c +++ b/sound/pci/oxygen/oxygen_io.c @@ -244,6 +244,7 @@ static void _write_uart(struct oxygen *chip, unsigned int port, u8 data) void oxygen_reset_uart(struct oxygen *chip) { _write_uart(chip, 1, MPU401_RESET); + msleep(1); /* wait for ACK */ _write_uart(chip, 1, MPU401_ENTER_UART); } EXPORT_SYMBOL(oxygen_reset_uart); -- cgit v1.2.3 From fedb7569100ac858bea7954d82c74e5561bf2c03 Mon Sep 17 00:00:00 2001 From: Matthew Ranostay Date: Tue, 23 Sep 2008 21:46:30 -0400 Subject: ALSA: hda: use last DAC defined for hp_pin Patch allows the last DAC in the dac_nids for the hp_nid if there is an available one this isn't in use by a line_out entry or if hp_nid isn't already defined. This solves the issues with the 'Headphone Playback' mixer controls on the 92hd73xxx branch and possibly others. Signed-off-by: Matthew Ranostay Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index bd0d6f8ab43..6e0a18bca23 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -2817,6 +2817,10 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec, } } + if ((spec->multiout.num_dacs - cfg->line_outs) > 0 && + cfg->hp_outs && !spec->multiout.hp_nid) + spec->multiout.hp_nid = nid; + if (cfg->hp_outs > 1) { err = stac92xx_add_control(spec, STAC_CTL_WIDGET_HP_SWITCH, @@ -4083,8 +4087,6 @@ again: case STAC_DELL_M6: spec->init = dell_eq_core_init; spec->num_smuxes = 0; - spec->multiout.hp_nid = - spec->multiout.dac_nids[spec->multiout.num_dacs - 1]; spec->mixer = &stac92hd73xx_6ch_mixer[DELL_M6_MIXER]; spec->amp_nids = &stac92hd73xx_amp_nids[DELL_M6_AMP]; spec->num_amps = 1; -- cgit v1.2.3 From 37c34ffb3a9a6051236a4ee1acb7752bcc3f50fd Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Wed, 24 Sep 2008 09:59:44 +0200 Subject: ALSA: intel8x0 - Add quirk for Fujitsu Lifebook P7010 Fujitsu Lifebook P7010 requires ac97_quirk=hp_only. http://bugzilla.kernel.org/show_bug.cgi?id=9100 Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/intel8x0.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index f7b4d0c5d49..c88d1eace1c 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c @@ -1961,6 +1961,12 @@ static struct ac97_quirk ac97_quirks[] __devinitdata = { .name = "Fujitsu S6210", /* STAC9750/51 */ .type = AC97_TUNE_HP_ONLY }, + { + .subvendor = 0x10cf, + .subdevice = 0x127d, + .name = "Fujitsu Lifebook P7010", + .type = AC97_TUNE_HP_ONLY + }, { .subvendor = 0x10cf, .subdevice = 0x127e, -- cgit v1.2.3 From ddc0f38a62083a552d6acb792d9ce513cf4081df Mon Sep 17 00:00:00 2001 From: Matthew Ranostay Date: Thu, 25 Sep 2008 09:17:11 -0400 Subject: ALSA: hda: slave_dig_outs code block in wrong location Removed invalid references to slave_dig_outs inside the S/PDIF IN capture switch control. Beforehand this was basically a mute switch for the S/PDIF outs as well. Signed-off-by: Matthew Ranostay Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_codec.c | 6 ------ 1 file changed, 6 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index c742e101d91..cb9aae5e9ca 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -1652,15 +1652,9 @@ static int snd_hda_spdif_in_switch_put(struct snd_kcontrol *kcontrol, mutex_lock(&codec->spdif_mutex); change = codec->spdif_in_enable != val; if (change) { - hda_nid_t *d; codec->spdif_in_enable = val; snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, val); - - if (codec->slave_dig_outs) - for (d = codec->slave_dig_outs; *d; d++) - snd_hda_codec_write_cache(codec, *d, 0, - AC_VERB_SET_DIGI_CONVERT_1, val); } mutex_unlock(&codec->spdif_mutex); return change; -- cgit v1.2.3 From 2f72853ca1ee1571377996471d05db51eb7c54c4 Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 25 Sep 2008 16:32:41 +0200 Subject: ALSA: hda - Fix / clean-up slave digital out codes The recent slave_dig_out addition has some rooms to clean up. Also it doesn't call snd_hda_cleanup_stream() properly for slaves at closing. The patch fixes both issues. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_codec.c | 115 ++++++++++++++++++++-------------------------- 1 file changed, 50 insertions(+), 65 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index cb9aae5e9ca..94ea6543440 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -1426,6 +1426,29 @@ static unsigned int convert_to_spdif_status(unsigned short val) return sbits; } +/* set digital convert verbs both for the given NID and its slaves */ +static void set_dig_out(struct hda_codec *codec, hda_nid_t nid, + int verb, int val) +{ + hda_nid_t *d; + + snd_hda_codec_write(codec, nid, 0, verb, val); + d = codec->slave_dig_outs; + if (!d) + return; + for (; *d; d++) + snd_hda_codec_write(codec, *d, 0, verb, val); +} + +static inline void set_dig_out_convert(struct hda_codec *codec, hda_nid_t nid, + int dig1, int dig2) +{ + if (dig1 != -1) + set_dig_out(codec, nid, AC_VERB_SET_DIGI_CONVERT_1, dig1); + if (dig2 != -1) + set_dig_out(codec, nid, AC_VERB_SET_DIGI_CONVERT_2, dig2); +} + static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { @@ -1444,25 +1467,8 @@ static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol, change = codec->spdif_ctls != val; codec->spdif_ctls = val; - if (change) { - hda_nid_t *d; - snd_hda_codec_write_cache(codec, nid, 0, - AC_VERB_SET_DIGI_CONVERT_1, - val & 0xff); - snd_hda_codec_write_cache(codec, nid, 0, - AC_VERB_SET_DIGI_CONVERT_2, - val >> 8); - - if (codec->slave_dig_outs) - for (d = codec->slave_dig_outs; *d; d++) { - snd_hda_codec_write_cache(codec, *d, 0, - AC_VERB_SET_DIGI_CONVERT_1, - val & 0xff); - snd_hda_codec_write_cache(codec, *d, 0, - AC_VERB_SET_DIGI_CONVERT_2, - val >> 8); - } - } + if (change) + set_dig_out_convert(codec, nid, val & 0xff, (val >> 8) & 0xff); mutex_unlock(&codec->spdif_mutex); return change; @@ -1493,17 +1499,8 @@ static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol, val |= AC_DIG1_ENABLE; change = codec->spdif_ctls != val; if (change) { - hda_nid_t *d; codec->spdif_ctls = val; - snd_hda_codec_write_cache(codec, nid, 0, - AC_VERB_SET_DIGI_CONVERT_1, - val & 0xff); - - if (codec->slave_dig_outs) - for (d = codec->slave_dig_outs; *d; d++) - snd_hda_codec_write_cache(codec, *d, 0, - AC_VERB_SET_DIGI_CONVERT_1, - val & 0xff); + set_dig_out_convert(codec, nid, val & 0xff, -1); /* unmute amp switch (if any) */ if ((get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) && (val & AC_DIG1_ENABLE)) @@ -2598,32 +2595,32 @@ int snd_hda_input_mux_put(struct hda_codec *codec, static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid, unsigned int stream_tag, unsigned int format) { - hda_nid_t *d; - /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */ - if (codec->spdif_status_reset && (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); - - if (codec->slave_dig_outs) - for (d = codec->slave_dig_outs; *d; d++) - snd_hda_codec_write(codec, *d, 0, - AC_VERB_SET_DIGI_CONVERT_1, - codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff); - } + if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) + set_dig_out_convert(codec, nid, + codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff, + -1); snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format); + if (codec->slave_dig_outs) { + hda_nid_t *d; + for (d = codec->slave_dig_outs; *d; d++) + snd_hda_codec_setup_stream(codec, *d, stream_tag, 0, + format); + } /* turn on again (if needed) */ - if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) { - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_DIGI_CONVERT_1, - codec->spdif_ctls & 0xff); + if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) + set_dig_out_convert(codec, nid, + codec->spdif_ctls & 0xff, -1); +} - if (codec->slave_dig_outs) - for (d = codec->slave_dig_outs; *d; d++) - snd_hda_codec_write(codec, *d, 0, - AC_VERB_SET_DIGI_CONVERT_1, - codec->spdif_ctls & 0xff); +static void cleanup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid) +{ + snd_hda_codec_cleanup_stream(codec, nid); + if (codec->slave_dig_outs) { + hda_nid_t *d; + for (d = codec->slave_dig_outs; *d; d++) + snd_hda_codec_cleanup_stream(codec, *d); } - } /* @@ -2635,7 +2632,7 @@ int snd_hda_multi_out_dig_open(struct hda_codec *codec, mutex_lock(&codec->spdif_mutex); if (mout->dig_out_used == HDA_DIG_ANALOG_DUP) /* already opened as analog dup; reset it once */ - snd_hda_codec_cleanup_stream(codec, mout->dig_out_nid); + cleanup_dig_out_stream(codec, mout->dig_out_nid); mout->dig_out_used = HDA_DIG_EXCLUSIVE; mutex_unlock(&codec->spdif_mutex); return 0; @@ -2647,12 +2644,8 @@ int snd_hda_multi_out_dig_prepare(struct hda_codec *codec, unsigned int format, struct snd_pcm_substream *substream) { - hda_nid_t *nid; mutex_lock(&codec->spdif_mutex); setup_dig_out_stream(codec, mout->dig_out_nid, stream_tag, format); - if (codec->slave_dig_outs) - for (nid = codec->slave_dig_outs; *nid; nid++) - setup_dig_out_stream(codec, *nid, stream_tag, format); mutex_unlock(&codec->spdif_mutex); return 0; } @@ -2719,7 +2712,6 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct snd_pcm_substream *substream) { hda_nid_t *nids = mout->dac_nids; - hda_nid_t *d; int chs = substream->runtime->channels; int i; @@ -2733,16 +2725,9 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, mout->dig_out_used = HDA_DIG_ANALOG_DUP; setup_dig_out_stream(codec, mout->dig_out_nid, stream_tag, format); - if (codec->slave_dig_outs) - for (d = codec->slave_dig_outs; *d; d++) - setup_dig_out_stream(codec, *d, - stream_tag, format); } else { mout->dig_out_used = 0; - snd_hda_codec_cleanup_stream(codec, mout->dig_out_nid); - if (codec->slave_dig_outs) - for (d = codec->slave_dig_outs; *d; d++) - snd_hda_codec_cleanup_stream(codec, *d); + cleanup_dig_out_stream(codec, mout->dig_out_nid); } } mutex_unlock(&codec->spdif_mutex); @@ -2793,7 +2778,7 @@ int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, mout->extra_out_nid[i]); mutex_lock(&codec->spdif_mutex); if (mout->dig_out_nid && mout->dig_out_used == HDA_DIG_ANALOG_DUP) { - snd_hda_codec_cleanup_stream(codec, mout->dig_out_nid); + cleanup_dig_out_stream(codec, mout->dig_out_nid); mout->dig_out_used = 0; } mutex_unlock(&codec->spdif_mutex); -- cgit v1.2.3 From 9a10eb21e1e1c389a8cea3016157a7f471512645 Mon Sep 17 00:00:00 2001 From: Wei Ni Date: Fri, 26 Sep 2008 13:45:46 +0800 Subject: ALSA: Support NVIDIA MCP78/7A HDMI audio Add NVIDIA HDMI HD-audio codec support in snd-hda-intel driver, include NVIDIA MCP78/7A HDMI. Signed-off-by: Wei Ni Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/Kconfig | 8 +++ sound/pci/hda/Makefile | 1 + sound/pci/hda/hda_codec.c | 3 + sound/pci/hda/hda_patch.h | 2 + sound/pci/hda/patch_nvhdmi.c | 164 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 178 insertions(+) create mode 100644 sound/pci/hda/patch_nvhdmi.c (limited to 'sound/pci') diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index 1f8b7966a83..7003711f4fc 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig @@ -565,6 +565,14 @@ config SND_HDA_CODEC_ATIHDMI Say Y here to include ATI HDMI HD-audio codec support in snd-hda-intel driver, such as ATI RS600 HDMI. +config SND_HDA_CODEC_NVHDMI + bool "Build NVIDIA HDMI HD-audio codec support" + depends on SND_HDA_INTEL + default y + help + Say Y here to include NVIDIA HDMI HD-audio codec support in + snd-hda-intel driver, such as NVIDIA MCP78 HDMI. + config SND_HDA_CODEC_CONEXANT bool "Build Conexant HD-audio codec support" depends on SND_HDA_INTEL diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile index 6db92fd954d..1980c6d207e 100644 --- a/sound/pci/hda/Makefile +++ b/sound/pci/hda/Makefile @@ -15,5 +15,6 @@ snd-hda-intel-$(CONFIG_SND_HDA_CODEC_SI3054) += patch_si3054.o snd-hda-intel-$(CONFIG_SND_HDA_CODEC_ATIHDMI) += patch_atihdmi.o snd-hda-intel-$(CONFIG_SND_HDA_CODEC_CONEXANT) += patch_conexant.o snd-hda-intel-$(CONFIG_SND_HDA_CODEC_VIA) += patch_via.o +snd-hda-intel-$(CONFIG_SND_HDA_CODEC_NVHDMI) += patch_nvhdmi.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 94ea6543440..fdb6d559f5d 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -93,6 +93,9 @@ static const struct hda_codec_preset *hda_preset_tables[] = { #endif #ifdef CONFIG_SND_HDA_CODEC_VIA snd_hda_preset_via, +#endif +#ifdef CONFIG_SND_HDA_CODEC_NVHDMI + snd_hda_preset_nvhdmi, #endif NULL }; diff --git a/sound/pci/hda/hda_patch.h b/sound/pci/hda/hda_patch.h index 2fdf2358dbc..dfbcfa88da4 100644 --- a/sound/pci/hda/hda_patch.h +++ b/sound/pci/hda/hda_patch.h @@ -18,3 +18,5 @@ extern struct hda_codec_preset snd_hda_preset_atihdmi[]; extern struct hda_codec_preset snd_hda_preset_conexant[]; /* VIA codecs */ extern struct hda_codec_preset snd_hda_preset_via[]; +/* NVIDIA HDMI codecs */ +extern struct hda_codec_preset snd_hda_preset_nvhdmi[]; diff --git a/sound/pci/hda/patch_nvhdmi.c b/sound/pci/hda/patch_nvhdmi.c new file mode 100644 index 00000000000..1a65775d28e --- /dev/null +++ b/sound/pci/hda/patch_nvhdmi.c @@ -0,0 +1,164 @@ +/* + * Universal Interface for Intel High Definition Audio Codec + * + * HD audio interface patch for NVIDIA HDMI codecs + * + * Copyright (c) 2008 NVIDIA Corp. All rights reserved. + * Copyright (c) 2008 Wei Ni + * + * + * This driver is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This driver is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include +#include +#include +#include +#include "hda_codec.h" +#include "hda_local.h" + +struct nvhdmi_spec { + struct hda_multi_out multiout; + + struct hda_pcm pcm_rec; +}; + +static struct hda_verb nvhdmi_basic_init[] = { + /* enable digital output on pin widget */ + { 0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, + {} /* terminator */ +}; + +/* + * Controls + */ +static int nvhdmi_build_controls(struct hda_codec *codec) +{ + struct nvhdmi_spec *spec = codec->spec; + int err; + + err = snd_hda_create_spdif_out_ctls(codec, spec->multiout.dig_out_nid); + if (err < 0) + return err; + + return 0; +} + +static int nvhdmi_init(struct hda_codec *codec) +{ + snd_hda_sequence_write(codec, nvhdmi_basic_init); + return 0; +} + +/* + * Digital out + */ +static int nvhdmi_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + struct snd_pcm_substream *substream) +{ + struct nvhdmi_spec *spec = codec->spec; + return snd_hda_multi_out_dig_open(codec, &spec->multiout); +} + +static int nvhdmi_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + struct snd_pcm_substream *substream) +{ + struct nvhdmi_spec *spec = codec->spec; + return snd_hda_multi_out_dig_close(codec, &spec->multiout); +} + +static int nvhdmi_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 nvhdmi_spec *spec = codec->spec; + return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag, + format, substream); +} + +static struct hda_pcm_stream nvhdmi_pcm_digital_playback = { + .substreams = 1, + .channels_min = 2, + .channels_max = 2, + .nid = 0x4, /* NID to query formats and rates and setup streams */ + .rates = SNDRV_PCM_RATE_48000, + .maxbps = 16, + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .ops = { + .open = nvhdmi_dig_playback_pcm_open, + .close = nvhdmi_dig_playback_pcm_close, + .prepare = nvhdmi_dig_playback_pcm_prepare + }, +}; + +static int nvhdmi_build_pcms(struct hda_codec *codec) +{ + struct nvhdmi_spec *spec = codec->spec; + struct hda_pcm *info = &spec->pcm_rec; + + codec->num_pcms = 1; + codec->pcm_info = info; + + info->name = "NVIDIA HDMI"; + info->stream[SNDRV_PCM_STREAM_PLAYBACK] = nvhdmi_pcm_digital_playback; + + return 0; +} + +static void nvhdmi_free(struct hda_codec *codec) +{ + kfree(codec->spec); +} + +static struct hda_codec_ops nvhdmi_patch_ops = { + .build_controls = nvhdmi_build_controls, + .build_pcms = nvhdmi_build_pcms, + .init = nvhdmi_init, + .free = nvhdmi_free, +}; + +static int patch_nvhdmi(struct hda_codec *codec) +{ + struct nvhdmi_spec *spec; + + spec = kzalloc(sizeof(*spec), GFP_KERNEL); + if (spec == NULL) + return -ENOMEM; + + codec->spec = spec; + + spec->multiout.num_dacs = 0; /* no analog */ + spec->multiout.max_channels = 2; + spec->multiout.dig_out_nid = 0x4; /* NID for copying analog to digital, + * seems to be unused in pure-digital + * case. */ + + codec->patch_ops = nvhdmi_patch_ops; + + return 0; +} + +/* + * patch entries + */ +struct hda_codec_preset snd_hda_preset_nvhdmi[] = { + { .id = 0x10de0002, .name = "NVIDIA MCP78 HDMI", .patch = patch_nvhdmi }, + { .id = 0x10de0007, .name = "NVIDIA MCP7A HDMI", .patch = patch_nvhdmi }, + {} /* terminator */ +}; -- cgit v1.2.3 From dc9c8e218da823008ce1572998902a4bdf46af37 Mon Sep 17 00:00:00 2001 From: Wei Ni Date: Fri, 26 Sep 2008 13:55:56 +0800 Subject: ALSA: Fix for reading RIRB buffer on NVIDIA aza controller with AMD Phenom cpu When read RIRB buffer immediately after RIRB interrupt received, sometimes the data will be "0x0". If we wait for some time, the data in buffer will be correct. This issue only occurred with AMD Phenom cpu. So we set this "needs_damn_long_delay" flag. Signed-off-by: Wei Ni Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_intel.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 60cc44abf58..9f316c1b279 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -1220,6 +1220,9 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model, if (err < 0) return err; + if (chip->driver_type == AZX_DRIVER_NVIDIA) + chip->bus->needs_damn_long_delay = 1; + codecs = audio_codecs = 0; max_slots = azx_max_codecs[chip->driver_type]; if (!max_slots) -- cgit v1.2.3 From b2c4f4d71f7a161630681678cbba84bd695bfd1e Mon Sep 17 00:00:00 2001 From: Matthew Ranostay Date: Fri, 26 Sep 2008 10:06:40 -0400 Subject: ALSA: hda: 92xx S/PDIF In support Add support for S/PDIF IN on reference boards quirks. Also disable the IEC958 capture switch on boards with GPIO0 enabled. Signed-off-by: Matthew Ranostay Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 6e0a18bca23..2191735068e 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -1245,7 +1245,7 @@ static int stac92xx_build_controls(struct hda_codec *codec) return err; spec->multiout.share_spdif = 1; } - if (spec->dig_in_nid) { + if (spec->dig_in_nid && (!spec->gpio_dir & 0x01)) { err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); if (err < 0) return err; @@ -4079,10 +4079,6 @@ again: memcpy(&spec->private_dimux, &stac92hd73xx_dmux, sizeof(stac92hd73xx_dmux)); - /* GPIO0 High = Enable EAPD */ - spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1; - spec->gpio_data = 0x01; - switch (spec->board_config) { case STAC_DELL_M6: spec->init = dell_eq_core_init; @@ -4120,6 +4116,11 @@ again: spec->num_dmics = STAC92HD73XX_NUM_DMICS; spec->num_smuxes = ARRAY_SIZE(stac92hd73xx_smux_nids); } + if (spec->board_config > STAC_92HD73XX_REF) { + /* GPIO0 High = Enable EAPD */ + spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1; + spec->gpio_data = 0x01; + } spec->dinput_mux = &spec->private_dimux; spec->num_pwrs = ARRAY_SIZE(stac92hd73xx_pwr_nids); @@ -4356,10 +4357,12 @@ again: spec->aloopback_mask = 0x20; spec->aloopback_shift = 0; - /* GPIO0 High = EAPD */ - spec->gpio_mask = 0x01; - spec->gpio_dir = 0x01; - spec->gpio_data = 0x01; + if (spec->board_config > STAC_92HD71BXX_REF) { + /* GPIO0 = EAPD */ + spec->gpio_mask = 0x01; + spec->gpio_dir = 0x01; + spec->gpio_data = 0x01; + } spec->powerdown_adcs = 1; spec->digbeep_nid = 0x26; @@ -4601,9 +4604,11 @@ static int patch_stac927x(struct hda_codec *codec) spec->num_dmuxes = ARRAY_SIZE(stac927x_dmux_nids); break; default: - /* GPIO0 High = Enable EAPD */ - spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1; - spec->gpio_data = 0x01; + if (spec->board_config > STAC_D965_REF) { + /* GPIO0 High = Enable EAPD */ + spec->eapd_mask = spec->gpio_mask = 0x01; + spec->gpio_dir = spec->gpio_data = 0x01; + } spec->num_dmics = 0; spec->init = stac927x_core_init; @@ -4717,6 +4722,9 @@ static int patch_stac9205(struct hda_codec *codec) */ spec->gpio_data = 0x01; break; + case STAC_9205_REF: + /* SPDIF-In enabled */ + break; default: /* GPIO0 High = EAPD */ spec->eapd_mask = spec->gpio_mask = spec->gpio_dir = 0x1; -- cgit v1.2.3 From 9a9e2359f484402c620f9a3748037fea65fa5af4 Mon Sep 17 00:00:00 2001 From: Matthew Ranostay Date: Fri, 26 Sep 2008 10:37:03 -0400 Subject: ALSA: hda: HP laptop quirk Added HP laptop SND_PCI_QUIRK for STAC_HP_M4. Signed-off-by: Matthew Ranostay Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 2191735068e..f9b25638892 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -1650,6 +1650,8 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { /* SigmaTel reference board */ SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_92HD71BXX_REF), + SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x361a, + "unknown HP", STAC_HP_M4), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233, "unknown Dell", STAC_DELL_M4_1), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0234, -- cgit v1.2.3 From cb55974cb461ff9c9c0675b2a8361d387212b64f Mon Sep 17 00:00:00 2001 From: Herton Ronaldo Krzesinski Date: Fri, 26 Sep 2008 23:47:45 -0300 Subject: ALSA: hda - Map ALC662 model for Gigabyte 945GCM-S2L Use 3stack-6ch-dig ALC662 model for Gigabyte 945GCM-S2L motherboard. Signed-off-by: Herton Ronaldo Krzesinski Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index c2ff85dad50..8f1fe962fb5 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -15703,6 +15703,8 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E), SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS), SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS), + SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L", + ALC662_3ST_6ch_DIG), SND_PCI_QUIRK(0x1854, 0x2000, "ASUS H13-2000", ALC663_ASUS_H13), SND_PCI_QUIRK(0x1854, 0x2001, "ASUS H13-2001", ALC663_ASUS_H13), SND_PCI_QUIRK(0x1854, 0x2002, "ASUS H13-2002", ALC663_ASUS_H13), -- cgit v1.2.3 From 95fe5f2cec831d73ee93227810ab95d05ced3416 Mon Sep 17 00:00:00 2001 From: Herton Ronaldo Krzesinski Date: Fri, 26 Sep 2008 23:48:45 -0300 Subject: ALSA: hda - Map ALC662 model for Foxconn 45CMX/45GMX/45CMX-K Use 3stack-6ch-dig ALC662 model for Foxconn 45CMX/45GMX/45CMX-K motherboard. Signed-off-by: Herton Ronaldo Krzesinski Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 8f1fe962fb5..dedd51d5540 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -15700,6 +15700,8 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = { SND_PCI_QUIRK(0x1043, 0x1833, "ASUS NB", ALC663_ASUS_MODE6), SND_PCI_QUIRK(0x1043, 0x1763, "ASUS NB", ALC663_ASUS_MODE6), SND_PCI_QUIRK(0x1043, 0x1765, "ASUS NB", ALC663_ASUS_MODE6), + SND_PCI_QUIRK(0x105b, 0x0d47, "Foxconn 45CMX/45GMX/45CMX-K", + ALC662_3ST_6ch_DIG), SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E), SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS), SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS), -- cgit v1.2.3 From f3911c5ab93e4295938b2013104d2986ea601454 Mon Sep 17 00:00:00 2001 From: Peter Korsgaard Date: Sat, 27 Sep 2008 09:13:45 +0200 Subject: ALSA: hda: appletv support The AppleTV needs the same handling as the 24" iMac. Signed-off-by: Peter Korsgaard Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 1 + 1 file changed, 1 insertion(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index dedd51d5540..2ff617d066c 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6656,6 +6656,7 @@ static int patch_alc882(struct hda_codec *codec) board_config = ALC885_MACPRO; break; case 0x106b1000: /* iMac 24 */ + case 0x106b2800: /* AppleTV */ board_config = ALC885_IMAC24; break; case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */ -- cgit v1.2.3 From 00ef50c242f05381cd3fbf56bbda28155cbbb7c8 Mon Sep 17 00:00:00 2001 From: Matthew Ranostay Date: Sat, 27 Sep 2008 18:13:47 -0400 Subject: ALSA: hda: SPDIF stream muting support Added support for muting S/DPIF outs using the 'Digital Playback Source' muxs on supporting codecs. Signed-off-by: Matthew Ranostay Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index f9b25638892..05661f7f3ce 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -138,6 +138,7 @@ struct sigmatel_spec { unsigned int mic_switch: 1; unsigned int alt_switch: 1; unsigned int hp_detect: 1; + unsigned int spdif_mute: 1; /* gpio lines */ unsigned int eapd_mask; @@ -547,10 +548,32 @@ static int stac92xx_smux_enum_put(struct snd_kcontrol *kcontrol, { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct sigmatel_spec *spec = codec->spec; + struct hda_input_mux *smux = &spec->private_smux; unsigned int smux_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); + int err, val; + hda_nid_t nid; - return snd_hda_input_mux_put(codec, spec->sinput_mux, ucontrol, + err = snd_hda_input_mux_put(codec, spec->sinput_mux, ucontrol, spec->smux_nids[smux_idx], &spec->cur_smux[smux_idx]); + if (err < 0) + return err; + + if (spec->spdif_mute) { + if (smux_idx == 0) + nid = spec->multiout.dig_out_nid; + else + nid = codec->slave_dig_outs[smux_idx - 1]; + if (spec->cur_smux[smux_idx] == smux->num_items - 1) + val = AMP_OUT_MUTE; + if (smux_idx == 0) + nid = spec->multiout.dig_out_nid; + else + nid = codec->slave_dig_outs[smux_idx - 1]; + /* un/mute SPDIF out */ + snd_hda_codec_write_cache(codec, nid, 0, + AC_VERB_SET_AMP_GAIN_MUTE, val); + } + return 0; } static int stac92xx_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) @@ -1228,6 +1251,15 @@ static int stac92xx_build_controls(struct hda_codec *codec) return err; } if (spec->num_smuxes > 0) { + int wcaps = get_wcaps(codec, spec->multiout.dig_out_nid); + struct hda_input_mux *smux = &spec->private_smux; + /* check for mute support on SPDIF out */ + if (wcaps & AC_WCAP_OUT_AMP) { + smux->items[smux->num_items].label = "Off"; + smux->items[smux->num_items].index = 0; + smux->num_items++; + spec->spdif_mute = 1; + } stac_smux_mixer.count = spec->num_smuxes; err = snd_ctl_add(codec->bus->card, snd_ctl_new1(&stac_smux_mixer, codec)); @@ -4377,7 +4409,6 @@ again: spec->num_muxes = ARRAY_SIZE(stac92hd71bxx_mux_nids); spec->num_adcs = ARRAY_SIZE(stac92hd71bxx_adc_nids); - spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); switch (spec->board_config) { case STAC_HP_M4: -- cgit v1.2.3 From b636a1d947c7f1bb0e0a157663e08ce3e49b2e52 Mon Sep 17 00:00:00 2001 From: Vedran Miletic Date: Mon, 29 Sep 2008 15:08:00 +0200 Subject: ALSA: cs46xx: Add PCI IDs for TerraTec and Hercules cards This patch adds PCI IDs for: * TerraTec DMX XFire 1024 * Hercules Gamesurround Fortissimo II * Hercules Gamesurround Fortissimo III 7.1 All those cards were supported as generic CS46xx device, so they will work as before. I'm pretty sure that first two cards work, as they have same hardware design as reference card. Not sure about Fortissimo III, but this won't break it if it worked. Tested on TerraTec DMX XFire 1024. Signed-off-by: Vedran Miletic Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/cs46xx/cs46xx_lib.c | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c index a10ab8283f9..fb6dc398025 100644 --- a/sound/pci/cs46xx/cs46xx_lib.c +++ b/sound/pci/cs46xx/cs46xx_lib.c @@ -3501,8 +3501,9 @@ static struct cs_card_type __devinitdata cards[] = { .name = "Mitac MI6020/21", .amp = amp_voyetra, }, + /* Hercules Game Theatre XP */ { - .vendor = 0x14AF, + .vendor = 0x14af, /* Guillemot Corporation */ .id = 0x0050, .name = "Hercules Game Theatre XP", .amp = amp_hercules, @@ -3544,7 +3545,23 @@ static struct cs_card_type __devinitdata cards[] = { .amp = amp_hercules, .mixer_init = hercules_mixer_init, }, + /* Herculess Fortissimo */ + { + .vendor = 0x1681, + .id = 0xa010, + .name = "Hercules Gamesurround Fortissimo II", + }, + { + .vendor = 0x1681, + .id = 0xa011, + .name = "Hercules Gamesurround Fortissimo III 7.1", + }, /* Teratec */ + { + .vendor = 0x153b, + .id = 0x112e, + .name = "Terratec DMX XFire 1024", + }, { .vendor = 0x153b, .id = 0x1136, -- cgit v1.2.3 From 19c009aad0ddeaa6a4ba41577022301f18d43afa Mon Sep 17 00:00:00 2001 From: Vedran Miletic Date: Mon, 29 Sep 2008 20:29:25 +0200 Subject: ALSA: hda: add more board-specific information for Realtek ALC662 rev1 I recently got a chance to play with two boards with ALC662 rev1: * BIOSTAR TA780G M2+ * ASROCK K10N78FullHD-hSLI R3.0 Both use 3 stack, 6ch mode with digital out. Since autodetection isn't able to figure that out from BIOS, we need to specify that manually. Signed-off-by: Vedran Miletic Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 2ff617d066c..6322ab76a39 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -15708,6 +15708,9 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = { SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS), SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L", ALC662_3ST_6ch_DIG), + SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG), + SND_PCI_QUIRK(0x1849, 0x0774, "ASROCK K10N78FullHD-hSLI R3.0", + ALC662_3ST_6ch_DIG), SND_PCI_QUIRK(0x1854, 0x2000, "ASUS H13-2000", ALC663_ASUS_H13), SND_PCI_QUIRK(0x1854, 0x2001, "ASUS H13-2001", ALC663_ASUS_H13), SND_PCI_QUIRK(0x1854, 0x2002, "ASUS H13-2002", ALC663_ASUS_H13), -- cgit v1.2.3 From 669faba27f2f7b04b9228d20e30e7f584f0becd5 Mon Sep 17 00:00:00 2001 From: Clive Messer Date: Tue, 30 Sep 2008 15:49:13 +0200 Subject: ALSA: hda - Fix another ALC889A (rev 0x100101) ALC889A hardware (id 0x10ec0885 rev 0x100101) to use patch_alc883 Signed-off-by: Clive Messer Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 6322ab76a39..e72b4eac0c6 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -6667,7 +6667,8 @@ static int patch_alc882(struct hda_codec *codec) break; default: /* ALC889A is handled better as ALC888-compatible */ - if (codec->revision_id == 0x100103) { + if (codec->revision_id == 0x100101 || + codec->revision_id == 0x100103) { alc_free(codec); return patch_alc883(codec); } @@ -16317,6 +16318,8 @@ struct hda_codec_preset snd_hda_preset_realtek[] = { { .id = 0x10ec0880, .name = "ALC880", .patch = patch_alc880 }, { .id = 0x10ec0882, .name = "ALC882", .patch = patch_alc882 }, { .id = 0x10ec0883, .name = "ALC883", .patch = patch_alc883 }, + { .id = 0x10ec0885, .rev = 0x100101, .name = "ALC889A", + .patch = patch_alc882 }, /* should be patch_alc883() in future */ { .id = 0x10ec0885, .rev = 0x100103, .name = "ALC889A", .patch = patch_alc882 }, /* should be patch_alc883() in future */ { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, -- cgit v1.2.3 From 238713d4891468f7942f7670d22ab44af0943a4b Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Sun, 5 Oct 2008 10:57:39 +0200 Subject: ALSA: hda - Fix PCI SSID for ASROCK K18N78FullHD-hSLI The PCI SSID for ASROCK mobo in commit ac56445dd6a38a36c2fa91989f5f6220a9bdf97c is wrong. This patch fixes to the correct one, 1849:3662. Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_realtek.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index e72b4eac0c6..0b6e682c46d 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -15710,7 +15710,7 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = { SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L", ALC662_3ST_6ch_DIG), SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG), - SND_PCI_QUIRK(0x1849, 0x0774, "ASROCK K10N78FullHD-hSLI R3.0", + SND_PCI_QUIRK(0x1849, 0x3662, "ASROCK K10N78FullHD-hSLI R3.0", ALC662_3ST_6ch_DIG), SND_PCI_QUIRK(0x1854, 0x2000, "ASUS H13-2000", ALC663_ASUS_H13), SND_PCI_QUIRK(0x1854, 0x2001, "ASUS H13-2001", ALC663_ASUS_H13), -- cgit v1.2.3 From 5c1d1a98c5e20ba517369d15995464a10add9132 Mon Sep 17 00:00:00 2001 From: Wu Fengguang Date: Tue, 7 Oct 2008 14:17:53 +0800 Subject: ALSA: hda: comment typo fix fix a typo in comment for process_unsol_events(). Signed-off-by: Wu Fengguang Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_codec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index fdb6d559f5d..1c0b33b6ce1 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -317,7 +317,7 @@ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex) } /* - * process queueud unsolicited events + * process queued unsolicited events */ static void process_unsol_events(struct work_struct *work) { -- cgit v1.2.3 From 6b34500c1ce9707b77ba1631bb21c8a1dea060bd Mon Sep 17 00:00:00 2001 From: Wu Fengguang Date: Tue, 7 Oct 2008 14:21:41 +0800 Subject: ALSA: hda: comment typo fix fix a typo in comment for is_in_nid_list(). Signed-off-by: Wu Fengguang Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/hda_codec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 1c0b33b6ce1..6447754ae56 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -2789,7 +2789,7 @@ int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, } /* - * Helper for automatic ping configuration + * Helper for automatic pin configuration */ static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list) -- cgit v1.2.3 From b9aea7150a84d037b6ca3c2506b0058cee4eb1d2 Mon Sep 17 00:00:00 2001 From: Matthew Ranostay Date: Thu, 9 Oct 2008 08:37:28 -0400 Subject: ALSA: hda: STAC_HP_M4 Set the third microphone to a default config of a 'Line In' to be added the Input Source Mux's. Signed-off-by: Matthew Ranostay Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 05661f7f3ce..5c65f7d4606 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -3643,7 +3643,12 @@ static int stac92xx_init(struct hda_codec *codec) for (i = 0; i < AUTO_PIN_LAST; i++) { hda_nid_t nid = cfg->input_pins[i]; if (nid) { - unsigned int pinctl = AC_PINCTL_IN_EN; + unsigned int pinctl = snd_hda_codec_read(codec, nid, + 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0); + /* if PINCTL already set then skip */ + if (pinctl & AC_PINCAP_IN) + continue; + pinctl = AC_PINCTL_IN_EN; if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC) pinctl |= stac92xx_get_vref(codec, nid); stac92xx_auto_set_pinctl(codec, nid, pinctl); @@ -4413,12 +4418,13 @@ again: switch (spec->board_config) { case STAC_HP_M4: spec->num_dmics = 0; - spec->num_smuxes = 1; + spec->num_smuxes = 0; spec->num_dmuxes = 0; /* enable internal microphone */ - snd_hda_codec_write_cache(codec, 0x0e, 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80); + stac92xx_set_config_reg(codec, 0x0e, 0x01813040); + stac92xx_auto_set_pinctl(codec, 0x0e, + AC_PINCTL_IN_EN | AC_PINCTL_VREF_80); break; default: spec->num_dmics = STAC92HD71BXX_NUM_DMICS; -- cgit v1.2.3 From 72474be62d6ec2e0337ff01ecbd737f9c5c242c7 Mon Sep 17 00:00:00 2001 From: Matthew Ranostay Date: Thu, 9 Oct 2008 09:32:17 -0400 Subject: ALSA: hda: VREF powerdown for headphones Add support for powering down VREF on standard headphone insertion, also powers up the VREF on a headset insertion. Signed-off-by: Matthew Ranostay Signed-off-by: Takashi Iwai Signed-off-by: Jaroslav Kysela --- sound/pci/hda/patch_sigmatel.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'sound/pci') diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 5c65f7d4606..c461baa83c2 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -38,6 +38,7 @@ #define NUM_CONTROL_ALLOC 32 #define STAC_PWR_EVENT 0x20 #define STAC_HP_EVENT 0x30 +#define STAC_VREF_EVENT 0x40 enum { STAC_REF, @@ -3854,13 +3855,22 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) struct sigmatel_spec *spec = codec->spec; int idx = res >> 26 & 0x0f; - switch ((res >> 26) & 0x30) { + switch ((res >> 26) & 0x70) { case STAC_HP_EVENT: stac92xx_hp_detect(codec, res); /* fallthru */ case STAC_PWR_EVENT: if (spec->num_pwrs > 0) stac92xx_pin_sense(codec, idx); + break; + case STAC_VREF_EVENT: { + int data = snd_hda_codec_read(codec, codec->afg, 0, + AC_VERB_GET_GPIO_DATA, 0); + /* toggle VREF state based on GPIOx status */ + snd_hda_codec_write(codec, codec->afg, 0, 0x7e0, + !!(data & (1 << idx))); + break; + } } } @@ -4360,6 +4370,17 @@ again: codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; break; case 0x111d7608: /* 5 Port with Analog Mixer */ + switch (codec->subsystem_id) { + case 0x103c361a: + /* Enable VREF power saving on GPIO1 detect */ + snd_hda_codec_write(codec, codec->afg, 0, + AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x02); + snd_hda_codec_write_cache(codec, codec->afg, 0, + AC_VERB_SET_UNSOLICITED_ENABLE, + (AC_USRSP_EN | STAC_VREF_EVENT | 0x01)); + spec->gpio_mask |= 0x02; + break; + } if ((codec->revision_id & 0xf) == 0 || (codec->revision_id & 0xf) == 1) { #ifdef SND_HDA_NEEDS_RESUME -- cgit v1.2.3