From 4c81aba01c42be62310ead2e84af1f01fcd8458f Mon Sep 17 00:00:00 2001 From: root Date: Thu, 16 Jul 2009 03:41:22 -0700 Subject: [PATCH] Fix intel-hda-2.6.30 patch and re-enable. --- master/intel-hda-2.6.30 | 5432 ++++++--------------------------------- master/series | 1 + 2 files changed, 834 insertions(+), 4599 deletions(-) diff --git a/master/intel-hda-2.6.30 b/master/intel-hda-2.6.30 index a7e075f..06f187e 100644 --- a/master/intel-hda-2.6.30 +++ b/master/intel-hda-2.6.30 @@ -1,8 +1,8 @@ diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h -index 4a6eba5..094bf89 100644 +index 2300030..3181bcf 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h -@@ -2087,6 +2087,8 @@ +@@ -2090,6 +2090,8 @@ #define PCI_DEVICE_ID_MELLANOX_SINAI_OLD 0x5e8c #define PCI_DEVICE_ID_MELLANOX_SINAI 0x6274 @@ -190,200 +190,6 @@ index 0000000..f236e42 +#endif + +#endif -diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig -new file mode 100644 -index 0000000..eb2a19b ---- /dev/null -+++ b/sound/pci/hda/Kconfig -@@ -0,0 +1,188 @@ -+menuconfig SND_HDA_INTEL -+ tristate "Intel HD Audio" -+ select SND_PCM -+ select SND_VMASTER -+ select SND_JACK if INPUT=y || INPUT=SND -+ help -+ Say Y here to include support for Intel "High Definition -+ Audio" (Azalia) and its compatible devices. -+ -+ This option enables the HD-audio controller. Don't forget -+ to choose the appropriate codec options below. -+ -+ To compile this driver as a module, choose M here: the module -+ will be called snd-hda-intel. -+ -+if SND_HDA_INTEL -+ -+config SND_HDA_HWDEP -+ bool "Build hwdep interface for HD-audio driver" -+ select SND_HWDEP -+ help -+ Say Y here to build a hwdep interface for HD-audio driver. -+ This interface can be used for out-of-band communication -+ with codecs for debugging purposes. -+ -+config SND_HDA_RECONFIG -+ bool "Allow dynamic codec reconfiguration (EXPERIMENTAL)" -+ depends on SND_HDA_HWDEP && EXPERIMENTAL -+ help -+ Say Y here to enable the HD-audio codec re-configuration feature. -+ This adds the sysfs interfaces to allow user to clear the whole -+ codec configuration, change the codec setup, add extra verbs, -+ and re-configure the codec dynamically. -+ -+config SND_HDA_INPUT_BEEP -+ bool "Support digital beep via input layer" -+ 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" -+ default y -+ help -+ Say Y here to include Realtek HD-audio codec support in -+ snd-hda-intel driver, such as ALC880. -+ -+ When the HD-audio driver is built as a module, the codec -+ support code is also built as another module, -+ snd-hda-codec-realtek. -+ This module is automatically loaded at probing. -+ -+config SND_HDA_CODEC_ANALOG -+ bool "Build Analog Device HD-audio codec support" -+ default y -+ help -+ Say Y here to include Analog Device HD-audio codec support in -+ snd-hda-intel driver, such as AD1986A. -+ -+ When the HD-audio driver is built as a module, the codec -+ support code is also built as another module, -+ snd-hda-codec-analog. -+ This module is automatically loaded at probing. -+ -+config SND_HDA_CODEC_SIGMATEL -+ bool "Build IDT/Sigmatel HD-audio codec support" -+ default y -+ help -+ Say Y here to include IDT (Sigmatel) HD-audio codec support in -+ snd-hda-intel driver, such as STAC9200. -+ -+ When the HD-audio driver is built as a module, the codec -+ support code is also built as another module, -+ snd-hda-codec-idt. -+ This module is automatically loaded at probing. -+ -+config SND_HDA_CODEC_VIA -+ bool "Build VIA HD-audio codec support" -+ default y -+ help -+ Say Y here to include VIA HD-audio codec support in -+ snd-hda-intel driver, such as VT1708. -+ -+ When the HD-audio driver is built as a module, the codec -+ support code is also built as another module, -+ snd-hda-codec-via. -+ This module is automatically loaded at probing. -+ -+config SND_HDA_CODEC_ATIHDMI -+ bool "Build ATI HDMI HD-audio codec support" -+ default y -+ help -+ Say Y here to include ATI HDMI HD-audio codec support in -+ snd-hda-intel driver, such as ATI RS600 HDMI. -+ -+ When the HD-audio driver is built as a module, the codec -+ support code is also built as another module, -+ snd-hda-codec-atihdmi. -+ This module is automatically loaded at probing. -+ -+config SND_HDA_CODEC_NVHDMI -+ bool "Build NVIDIA HDMI HD-audio codec support" -+ default y -+ help -+ Say Y here to include NVIDIA HDMI HD-audio codec support in -+ snd-hda-intel driver, such as NVIDIA MCP78 HDMI. -+ -+ When the HD-audio driver is built as a module, the codec -+ support code is also built as another module, -+ snd-hda-codec-nvhdmi. -+ This module is automatically loaded at probing. -+ -+config SND_HDA_CODEC_INTELHDMI -+ bool "Build INTEL HDMI HD-audio codec support" -+ default y -+ help -+ Say Y here to include INTEL HDMI HD-audio codec support in -+ snd-hda-intel driver, such as Eaglelake integrated HDMI. -+ -+ When the HD-audio driver is built as a module, the codec -+ support code is also built as another module, -+ snd-hda-codec-intelhdmi. -+ This module is automatically loaded at probing. -+ -+config SND_HDA_ELD -+ def_bool y -+ depends on SND_HDA_CODEC_INTELHDMI -+ -+config SND_HDA_CODEC_CONEXANT -+ bool "Build Conexant HD-audio codec support" -+ default y -+ help -+ Say Y here to include Conexant HD-audio codec support in -+ snd-hda-intel driver, such as CX20549. -+ -+ When the HD-audio driver is built as a module, the codec -+ support code is also built as another module, -+ snd-hda-codec-conexant. -+ This module is automatically loaded at probing. -+ -+config SND_HDA_CODEC_CMEDIA -+ bool "Build C-Media HD-audio codec support" -+ default y -+ help -+ Say Y here to include C-Media HD-audio codec support in -+ snd-hda-intel driver, such as CMI9880. -+ -+ When the HD-audio driver is built as a module, the codec -+ support code is also built as another module, -+ snd-hda-codec-cmedia. -+ This module is automatically loaded at probing. -+ -+config SND_HDA_CODEC_SI3054 -+ bool "Build Silicon Labs 3054 HD-modem codec support" -+ default y -+ help -+ Say Y here to include Silicon Labs 3054 HD-modem codec -+ (and compatibles) support in snd-hda-intel driver. -+ -+ When the HD-audio driver is built as a module, the codec -+ support code is also built as another module, -+ snd-hda-codec-si3054. -+ This module is automatically loaded at probing. -+ -+config SND_HDA_GENERIC -+ bool "Enable generic HD-audio codec parser" -+ default y -+ help -+ Say Y here to enable the generic HD-audio codec parser -+ in snd-hda-intel driver. -+ -+config SND_HDA_POWER_SAVE -+ bool "Aggressive power-saving on HD-audio" -+ help -+ Say Y here to enable more aggressive power-saving mode on -+ HD-audio driver. The power-saving timeout can be configured -+ via power_save option or over sysfs on-the-fly. -+ -+config SND_HDA_POWER_SAVE_DEFAULT -+ int "Default time-out for HD-audio power-save mode" -+ depends on SND_HDA_POWER_SAVE -+ default 0 -+ help -+ The default time-out value in seconds for HD-audio automatic -+ power-save mode. 0 means to disable the power-save mode. -+ -+endif diff --git a/sound/pci/hda/Makefile b/sound/pci/hda/Makefile index 1980c6d..50f9d09 100644 --- a/sound/pci/hda/Makefile @@ -467,10 +273,10 @@ index 1980c6d..50f9d09 100644 +# when built in kernel obj-$(CONFIG_SND_HDA_INTEL) += snd-hda-intel.o diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c -index 3ecd7e7..4de5bac 100644 +index b4d0d35..4de5bac 100644 --- a/sound/pci/hda/hda_beep.c +++ b/sound/pci/hda/hda_beep.c -@@ -128,15 +128,17 @@ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid) +@@ -128,6 +128,7 @@ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid) INIT_WORK(&beep->beep_work, &snd_hda_generate_beep); return 0; } @@ -478,10 +284,7 @@ index 3ecd7e7..4de5bac 100644 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(); +@@ -137,5 +138,7 @@ void snd_hda_detach_beep_device(struct hda_codec *codec) input_unregister_device(beep->dev); kfree(beep); @@ -503,7 +306,7 @@ index b9679f0..51bf6a5 100644 #endif #endif diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c -index b5b1ba5..8820faf 100644 +index 21f609b..8820faf 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c @@ -31,15 +31,6 @@ @@ -594,7 +397,7 @@ index b5b1ba5..8820faf 100644 #ifdef CONFIG_SND_HDA_POWER_SAVE static void hda_power_work(struct work_struct *work); -@@ -107,6 +91,72 @@ static void hda_keep_power_on(struct hda_codec *codec); +@@ -107,6 +91,55 @@ static void hda_keep_power_on(struct hda_codec *codec); static inline void hda_keep_power_on(struct hda_codec *codec) {} #endif @@ -647,45 +450,36 @@ index b5b1ba5..8820faf 100644 +} +EXPORT_SYMBOL_HDA(snd_hda_get_jack_type); + -+/* -+ * Compose a 32bit command word to be sent to the HD-audio controller -+ */ -+static inline unsigned int -+make_codec_cmd(struct hda_codec *codec, hda_nid_t nid, int direct, -+ unsigned int verb, unsigned int parm) -+{ -+ u32 val; -+ -+ val = (u32)(codec->addr & 0x0f) << 28; -+ val |= (u32)direct << 27; -+ val |= (u32)nid << 20; -+ val |= verb << 8; -+ val |= parm; -+ return val; -+} -+ - /** - * snd_hda_codec_read - send a command and get the response - * @codec: the HDA codec -@@ -123,17 +173,21 @@ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, - int direct, + /* + * Compose a 32bit command word to be sent to the HD-audio controller + */ +@@ -141,28 +174,20 @@ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, unsigned int verb, unsigned int parm) { -+ struct hda_bus *bus = codec->bus; - unsigned int res; -+ + struct hda_bus *bus = codec->bus; +- unsigned int cmd, res; +- int repeated = 0; ++ unsigned int res; + +- cmd = make_codec_cmd(codec, nid, direct, verb, parm); + res = make_codec_cmd(codec, nid, direct, verb, parm); snd_hda_power_up(codec); -- mutex_lock(&codec->bus->cmd_mutex); -- if (!codec->bus->ops.command(codec, nid, direct, verb, parm)) -- res = codec->bus->ops.get_response(codec); -+ mutex_lock(&bus->cmd_mutex); + mutex_lock(&bus->cmd_mutex); +- again: +- if (!bus->ops.command(bus, cmd)) { + if (!bus->ops.command(bus, res)) -+ res = bus->ops.get_response(bus); - else + res = bus->ops.get_response(bus); +- if (res == -1 && bus->rirb_error) { +- if (repeated++ < 1) { +- snd_printd(KERN_WARNING "hda_codec: " +- "Trying verb 0x%08x again\n", cmd); +- goto again; +- } +- } +- } else ++ else res = (unsigned int)-1; -- mutex_unlock(&codec->bus->cmd_mutex); -+ mutex_unlock(&bus->cmd_mutex); + mutex_unlock(&bus->cmd_mutex); snd_hda_power_down(codec); return res; } @@ -693,22 +487,7 @@ index b5b1ba5..8820faf 100644 /** * snd_hda_codec_write - send a single command without waiting for response -@@ -150,14 +204,19 @@ unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid, - int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct, - unsigned int verb, unsigned int parm) - { -+ struct hda_bus *bus = codec->bus; -+ unsigned int res; - int err; -+ -+ res = make_codec_cmd(codec, nid, direct, verb, parm); - snd_hda_power_up(codec); -- mutex_lock(&codec->bus->cmd_mutex); -- err = codec->bus->ops.command(codec, nid, direct, verb, parm); -- mutex_unlock(&codec->bus->cmd_mutex); -+ mutex_lock(&bus->cmd_mutex); -+ err = bus->ops.command(bus, res); -+ mutex_unlock(&bus->cmd_mutex); +@@ -191,6 +216,7 @@ int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct, snd_hda_power_down(codec); return err; } @@ -716,7 +495,7 @@ index b5b1ba5..8820faf 100644 /** * snd_hda_sequence_write - sequence writes -@@ -172,6 +231,7 @@ void snd_hda_sequence_write(struct hda_codec *codec, const struct hda_verb *seq) +@@ -205,6 +231,7 @@ void snd_hda_sequence_write(struct hda_codec *codec, const struct hda_verb *seq) for (; seq->nid; seq++) snd_hda_codec_write(codec, seq->nid, 0, seq->verb, seq->param); } @@ -724,7 +503,7 @@ index b5b1ba5..8820faf 100644 /** * snd_hda_get_sub_nodes - get the range of sub nodes -@@ -193,6 +253,7 @@ int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid, +@@ -226,6 +253,7 @@ int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid, *start_id = (parm >> 16) & 0x7fff; return (int)(parm & 0x7fff); } @@ -732,7 +511,7 @@ index b5b1ba5..8820faf 100644 /** * snd_hda_get_connections - get connection list -@@ -214,7 +275,8 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, +@@ -247,7 +275,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; @@ -742,7 +521,7 @@ index b5b1ba5..8820faf 100644 parm = snd_hda_param_read(codec, nid, AC_PAR_CONNLIST_LEN); if (parm & AC_CLIST_LONG) { -@@ -280,6 +342,7 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, +@@ -313,6 +342,7 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, } return conns; } @@ -750,12 +529,7 @@ index b5b1ba5..8820faf 100644 /** -@@ -310,13 +373,14 @@ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex) - unsol->queue[wp] = res; - unsol->queue[wp + 1] = res_ex; - -- schedule_work(&unsol->work); -+ queue_work(bus->workq, &unsol->work); +@@ -347,9 +377,10 @@ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex) return 0; } @@ -767,7 +541,7 @@ index b5b1ba5..8820faf 100644 */ static void process_unsol_events(struct work_struct *work) { -@@ -343,7 +407,7 @@ static void process_unsol_events(struct work_struct *work) +@@ -376,7 +407,7 @@ static void process_unsol_events(struct work_struct *work) /* * initialize unsolicited queue */ @@ -776,28 +550,7 @@ index b5b1ba5..8820faf 100644 { struct hda_bus_unsolicited *unsol; -@@ -373,15 +437,17 @@ static int snd_hda_bus_free(struct hda_bus *bus) - - if (!bus) - return 0; -- if (bus->unsol) { -- flush_scheduled_work(); -+ if (bus->workq) -+ flush_workqueue(bus->workq); -+ if (bus->unsol) - kfree(bus->unsol); -- } - list_for_each_entry_safe(codec, n, &bus->codec_list, list) { - snd_hda_codec_free(codec); - } - if (bus->ops.private_free) - bus->ops.private_free(bus); -+ if (bus->workq) -+ destroy_workqueue(bus->workq); - kfree(bus); - return 0; - } -@@ -389,9 +455,24 @@ static int snd_hda_bus_free(struct hda_bus *bus) +@@ -424,9 +455,24 @@ static int snd_hda_bus_free(struct hda_bus *bus) static int snd_hda_bus_dev_free(struct snd_device *device) { struct hda_bus *bus = device->device_data; @@ -822,7 +575,7 @@ index b5b1ba5..8820faf 100644 /** * snd_hda_bus_new - create a HDA bus * @card: the card entry -@@ -400,18 +481,21 @@ static int snd_hda_bus_dev_free(struct snd_device *device) +@@ -435,18 +481,21 @@ static int snd_hda_bus_dev_free(struct snd_device *device) * * Returns 0 if successful, or a negative error code. */ @@ -847,7 +600,7 @@ index b5b1ba5..8820faf 100644 if (busp) *busp = NULL; -@@ -426,11 +510,22 @@ int __devinit snd_hda_bus_new(struct snd_card *card, +@@ -461,6 +510,7 @@ int __devinit snd_hda_bus_new(struct snd_card *card, bus->private_data = temp->private_data; bus->pci = temp->pci; bus->modelname = temp->modelname; @@ -855,22 +608,7 @@ index b5b1ba5..8820faf 100644 bus->ops = temp->ops; mutex_init(&bus->cmd_mutex); - INIT_LIST_HEAD(&bus->codec_list); - -+ snprintf(bus->workq_name, sizeof(bus->workq_name), -+ "hd-audio%d", card->number); -+ bus->workq = create_singlethread_workqueue(bus->workq_name); -+ if (!bus->workq) { -+ snd_printk(KERN_ERR "cannot create workqueue %s\n", -+ bus->workq_name); -+ kfree(bus); -+ return -ENOMEM; -+ } -+ - err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops); - if (err < 0) { - snd_hda_bus_free(bus); -@@ -440,27 +535,42 @@ int __devinit snd_hda_bus_new(struct snd_card *card, +@@ -485,27 +535,42 @@ int __devinit snd_hda_bus_new(struct snd_card *card, *busp = bus; return 0; } @@ -918,7 +656,7 @@ index b5b1ba5..8820faf 100644 u32 mask = preset->mask; if (preset->afg && preset->afg != codec->afg) continue; -@@ -470,23 +580,40 @@ find_codec_preset(struct hda_codec *codec) +@@ -515,23 +580,40 @@ find_codec_preset(struct hda_codec *codec) mask = ~0; if (preset->id == (codec->vendor_id & mask) && (!preset->rev || @@ -964,7 +702,7 @@ index b5b1ba5..8820faf 100644 for (c = hda_vendor_ids; c->id; c++) { if (c->id == vendor_id) { -@@ -499,30 +626,37 @@ void snd_hda_get_codec_name(struct hda_codec *codec, +@@ -544,30 +626,37 @@ void snd_hda_get_codec_name(struct hda_codec *codec, vendor = tmp; } if (codec->preset && codec->preset->name) @@ -1009,7 +747,7 @@ index b5b1ba5..8820faf 100644 break; default: break; -@@ -550,11 +684,140 @@ static int read_widget_caps(struct hda_codec *codec, hda_nid_t fg_node) +@@ -595,11 +684,140 @@ static int read_widget_caps(struct hda_codec *codec, hda_nid_t fg_node) return 0; } @@ -1150,15 +888,14 @@ index b5b1ba5..8820faf 100644 /* * codec destructor */ -@@ -562,20 +825,28 @@ static void snd_hda_codec_free(struct hda_codec *codec) +@@ -607,20 +825,28 @@ static void snd_hda_codec_free(struct hda_codec *codec) { if (!codec) return; + restore_init_pincfgs(codec); #ifdef CONFIG_SND_HDA_POWER_SAVE cancel_delayed_work(&codec->power_work); -- flush_scheduled_work(); -+ flush_workqueue(codec->bus->workq); + flush_workqueue(codec->bus->workq); #endif list_del(&codec->list); + snd_array_free(&codec->mixers); @@ -1180,7 +917,7 @@ index b5b1ba5..8820faf 100644 /** * snd_hda_codec_new - create a HDA codec * @bus: the bus to assign -@@ -584,15 +855,17 @@ static void snd_hda_codec_free(struct hda_codec *codec) +@@ -629,15 +855,17 @@ static void snd_hda_codec_free(struct hda_codec *codec) * * Returns 0 if successful, or a negative error code. */ @@ -1203,7 +940,7 @@ index b5b1ba5..8820faf 100644 if (bus->caddr_tbl[codec_addr]) { snd_printk(KERN_ERR "hda_codec: " -@@ -609,8 +882,19 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, +@@ -654,8 +882,19 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, codec->bus = bus; codec->addr = codec_addr; mutex_init(&codec->spdif_mutex); @@ -1223,7 +960,7 @@ index b5b1ba5..8820faf 100644 #ifdef CONFIG_SND_HDA_POWER_SAVE INIT_DELAYED_WORK(&codec->power_work, hda_power_work); -@@ -640,15 +924,18 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, +@@ -685,15 +924,18 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, setup_fg_nodes(codec); if (!codec->afg && !codec->mfg) { snd_printdd("hda_codec: no AFG or MFG node found\n"); @@ -1247,7 +984,7 @@ index b5b1ba5..8820faf 100644 if (!codec->subsystem_id) { hda_nid_t nid = codec->afg ? codec->afg : codec->mfg; -@@ -656,12 +943,51 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, +@@ -701,12 +943,51 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_SUBSYSTEM_ID, 0); } @@ -1302,7 +1039,7 @@ index b5b1ba5..8820faf 100644 if (is_generic_config(codec)) { err = snd_hda_parse_generic_codec(codec); -@@ -678,25 +1004,9 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, +@@ -723,25 +1004,9 @@ int __devinit snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, printk(KERN_ERR "hda-codec: No codec parser is available\n"); patched: @@ -1331,7 +1068,7 @@ index b5b1ba5..8820faf 100644 } /** -@@ -722,6 +1032,7 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, +@@ -767,6 +1032,7 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, msleep(1); snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, format); } @@ -1339,7 +1076,7 @@ index b5b1ba5..8820faf 100644 void snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid) { -@@ -735,6 +1046,7 @@ void snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid) +@@ -780,6 +1046,7 @@ void snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid) snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, 0); #endif } @@ -1347,7 +1084,7 @@ index b5b1ba5..8820faf 100644 /* * amp access functions -@@ -742,21 +1054,22 @@ void snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid) +@@ -787,21 +1054,22 @@ void snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid) /* FIXME: more better hash key? */ #define HDA_HASH_KEY(nid,dir,idx) (u32)((nid) + ((idx) << 16) + ((dir) << 24)) @@ -1373,7 +1110,7 @@ index b5b1ba5..8820faf 100644 } /* query the hash. allocate an entry if not found. */ -@@ -768,35 +1081,17 @@ static struct hda_cache_head *get_alloc_hash(struct hda_cache_rec *cache, +@@ -813,35 +1081,17 @@ static struct hda_cache_head *get_alloc_hash(struct hda_cache_rec *cache, struct hda_cache_head *info; while (cur != 0xffff) { @@ -1414,7 +1151,7 @@ index b5b1ba5..8820faf 100644 info->key = key; info->val = 0; info->next = cache->hash[idx]; -@@ -834,6 +1129,7 @@ u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction) +@@ -879,6 +1129,7 @@ u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction) } return info->amp_caps; } @@ -1422,7 +1159,7 @@ index b5b1ba5..8820faf 100644 int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, unsigned int caps) -@@ -847,6 +1143,22 @@ int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, +@@ -892,6 +1143,22 @@ int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, info->head.val |= INFO_AMP_CAPS; return 0; } @@ -1445,7 +1182,7 @@ index b5b1ba5..8820faf 100644 /* * read the current volume to info -@@ -900,6 +1212,7 @@ int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch, +@@ -945,6 +1212,7 @@ int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch, return 0; return get_vol_mute(codec, info, nid, ch, direction, index); } @@ -1453,7 +1190,7 @@ index b5b1ba5..8820faf 100644 /* * update the AMP value, mask = bit mask to set, val = the value -@@ -919,6 +1232,7 @@ int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, +@@ -964,6 +1232,7 @@ int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, put_vol_mute(codec, info, nid, ch, direction, idx, val); return 1; } @@ -1461,7 +1198,7 @@ index b5b1ba5..8820faf 100644 /* * update the AMP stereo with the same mask and value -@@ -932,15 +1246,16 @@ int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid, +@@ -977,15 +1246,16 @@ int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid, idx, mask, val); return ret; } @@ -1480,7 +1217,7 @@ index b5b1ba5..8820faf 100644 u32 key = buffer->head.key; hda_nid_t nid; unsigned int idx, dir, ch; -@@ -957,6 +1272,7 @@ void snd_hda_codec_resume_amp(struct hda_codec *codec) +@@ -1002,6 +1272,7 @@ void snd_hda_codec_resume_amp(struct hda_codec *codec) } } } @@ -1488,7 +1225,7 @@ index b5b1ba5..8820faf 100644 #endif /* SND_HDA_NEEDS_RESUME */ /* volume */ -@@ -987,6 +1303,7 @@ int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, +@@ -1032,6 +1303,7 @@ int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, uinfo->value.integer.max = caps; return 0; } @@ -1496,7 +1233,7 @@ index b5b1ba5..8820faf 100644 static inline unsigned int -@@ -1031,6 +1348,7 @@ int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol, +@@ -1076,6 +1348,7 @@ int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol, *valp = read_amp_value(codec, nid, 1, dir, idx, ofs); return 0; } @@ -1504,7 +1241,7 @@ index b5b1ba5..8820faf 100644 int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -@@ -1054,6 +1372,7 @@ int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol, +@@ -1099,6 +1372,7 @@ int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol, snd_hda_power_down(codec); return change; } @@ -1512,7 +1249,7 @@ index b5b1ba5..8820faf 100644 int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag, unsigned int size, unsigned int __user *_tlv) -@@ -1082,6 +1401,7 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag, +@@ -1127,6 +1401,7 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag, return -EFAULT; return 0; } @@ -1520,7 +1257,7 @@ index b5b1ba5..8820faf 100644 /* * set (static) TLV for virtual master volume; recalculated as max 0dB -@@ -1101,6 +1421,7 @@ void snd_hda_set_vmaster_tlv(struct hda_codec *codec, hda_nid_t nid, int dir, +@@ -1146,6 +1421,7 @@ void snd_hda_set_vmaster_tlv(struct hda_codec *codec, hda_nid_t nid, int dir, tlv[2] = -nums * step; tlv[3] = step; } @@ -1528,7 +1265,7 @@ index b5b1ba5..8820faf 100644 /* find a mixer control element with the given name */ static struct snd_kcontrol * -@@ -1120,6 +1441,119 @@ struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec, +@@ -1165,6 +1441,119 @@ struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec, { return _snd_hda_find_mixer_ctl(codec, name, 0); } @@ -1648,7 +1385,7 @@ index b5b1ba5..8820faf 100644 /* create a virtual master control and add slaves */ int snd_hda_add_vmaster(struct hda_codec *codec, char *name, -@@ -1138,24 +1572,30 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name, +@@ -1183,24 +1572,30 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name, kctl = snd_ctl_make_virtual_master(name, tlv); if (!kctl) return -ENOMEM; @@ -1688,7 +1425,7 @@ index b5b1ba5..8820faf 100644 /* switch */ int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, -@@ -1169,6 +1609,7 @@ int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, +@@ -1214,6 +1609,7 @@ int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, uinfo->value.integer.max = 1; return 0; } @@ -1696,7 +1433,7 @@ index b5b1ba5..8820faf 100644 int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -@@ -1188,6 +1629,7 @@ int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, +@@ -1233,6 +1629,7 @@ int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, HDA_AMP_MUTE) ? 0 : 1; return 0; } @@ -1704,7 +1441,7 @@ index b5b1ba5..8820faf 100644 int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -@@ -1218,6 +1660,7 @@ int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, +@@ -1263,6 +1660,7 @@ int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, snd_hda_power_down(codec); return change; } @@ -1712,7 +1449,7 @@ index b5b1ba5..8820faf 100644 /* * bound volume controls -@@ -1235,14 +1678,15 @@ int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol, +@@ -1280,14 +1678,15 @@ int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol, unsigned long pval; int err; @@ -1730,7 +1467,7 @@ index b5b1ba5..8820faf 100644 int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -@@ -1251,7 +1695,7 @@ int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, +@@ -1296,7 +1695,7 @@ int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, unsigned long pval; int i, indices, err = 0, change = 0; @@ -1739,7 +1476,7 @@ index b5b1ba5..8820faf 100644 pval = kcontrol->private_value; indices = (pval & AMP_VAL_IDX_MASK) >> AMP_VAL_IDX_SHIFT; for (i = 0; i < indices; i++) { -@@ -1263,9 +1707,10 @@ int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, +@@ -1308,9 +1707,10 @@ int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, change |= err; } kcontrol->private_value = pval; @@ -1751,7 +1488,7 @@ index b5b1ba5..8820faf 100644 /* * generic bound volume/swtich controls -@@ -1277,14 +1722,15 @@ int snd_hda_mixer_bind_ctls_info(struct snd_kcontrol *kcontrol, +@@ -1322,14 +1722,15 @@ int snd_hda_mixer_bind_ctls_info(struct snd_kcontrol *kcontrol, struct hda_bind_ctls *c; int err; @@ -1769,7 +1506,7 @@ index b5b1ba5..8820faf 100644 int snd_hda_mixer_bind_ctls_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -@@ -1293,14 +1739,15 @@ int snd_hda_mixer_bind_ctls_get(struct snd_kcontrol *kcontrol, +@@ -1338,14 +1739,15 @@ int snd_hda_mixer_bind_ctls_get(struct snd_kcontrol *kcontrol, struct hda_bind_ctls *c; int err; @@ -1787,7 +1524,7 @@ index b5b1ba5..8820faf 100644 int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) -@@ -1310,7 +1757,7 @@ int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol, +@@ -1355,7 +1757,7 @@ int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol, unsigned long *vals; int err = 0, change = 0; @@ -1796,7 +1533,7 @@ index b5b1ba5..8820faf 100644 c = (struct hda_bind_ctls *)kcontrol->private_value; for (vals = c->values; *vals; vals++) { kcontrol->private_value = *vals; -@@ -1320,9 +1767,10 @@ int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol, +@@ -1365,9 +1767,10 @@ int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol, change |= err; } kcontrol->private_value = (long)c; @@ -1808,7 +1545,7 @@ index b5b1ba5..8820faf 100644 int snd_hda_mixer_bind_tlv(struct snd_kcontrol *kcontrol, int op_flag, unsigned int size, unsigned int __user *tlv) -@@ -1331,14 +1779,15 @@ int snd_hda_mixer_bind_tlv(struct snd_kcontrol *kcontrol, int op_flag, +@@ -1376,14 +1779,15 @@ int snd_hda_mixer_bind_tlv(struct snd_kcontrol *kcontrol, int op_flag, struct hda_bind_ctls *c; int err; @@ -1826,7 +1563,7 @@ index b5b1ba5..8820faf 100644 struct hda_ctl_ops snd_hda_bind_vol = { .info = snd_hda_mixer_amp_volume_info, -@@ -1346,6 +1795,7 @@ struct hda_ctl_ops snd_hda_bind_vol = { +@@ -1391,6 +1795,7 @@ struct hda_ctl_ops snd_hda_bind_vol = { .put = snd_hda_mixer_amp_volume_put, .tlv = snd_hda_mixer_amp_tlv }; @@ -1834,7 +1571,7 @@ index b5b1ba5..8820faf 100644 struct hda_ctl_ops snd_hda_bind_sw = { .info = snd_hda_mixer_amp_switch_info, -@@ -1353,6 +1803,7 @@ struct hda_ctl_ops snd_hda_bind_sw = { +@@ -1398,6 +1803,7 @@ struct hda_ctl_ops snd_hda_bind_sw = { .put = snd_hda_mixer_amp_switch_put, .tlv = snd_hda_mixer_amp_tlv }; @@ -1842,7 +1579,7 @@ index b5b1ba5..8820faf 100644 /* * SPDIF out controls -@@ -1600,9 +2051,11 @@ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid) +@@ -1645,9 +2051,11 @@ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid) } for (dig_mix = dig_mixes; dig_mix->name; dig_mix++) { kctl = snd_ctl_new1(dig_mix, codec); @@ -1855,7 +1592,7 @@ index b5b1ba5..8820faf 100644 if (err < 0) return err; } -@@ -1612,6 +2065,7 @@ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid) +@@ -1657,6 +2065,7 @@ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid) codec->spdif_status = convert_to_spdif_status(codec->spdif_ctls); return 0; } @@ -1863,7 +1600,7 @@ index b5b1ba5..8820faf 100644 /* * SPDIF sharing with analog output -@@ -1646,9 +2100,10 @@ int snd_hda_create_spdif_share_sw(struct hda_codec *codec, +@@ -1691,9 +2100,10 @@ int snd_hda_create_spdif_share_sw(struct hda_codec *codec, if (!mout->dig_out_nid) return 0; /* ATTENTION: here mout is passed as private_data, instead of codec */ @@ -1875,7 +1612,7 @@ index b5b1ba5..8820faf 100644 /* * SPDIF input -@@ -1747,8 +2202,10 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid) +@@ -1792,8 +2202,10 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid) } for (dig_mix = dig_in_ctls; dig_mix->name; dig_mix++) { kctl = snd_ctl_new1(dig_mix, codec); @@ -1887,7 +1624,7 @@ index b5b1ba5..8820faf 100644 if (err < 0) return err; } -@@ -1758,6 +2215,7 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid) +@@ -1803,6 +2215,7 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid) AC_DIG1_ENABLE; return 0; } @@ -1895,20 +1632,8 @@ index b5b1ba5..8820faf 100644 #ifdef SND_HDA_NEEDS_RESUME /* -@@ -1784,29 +2242,38 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid) - int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid, - int direct, unsigned int verb, unsigned int parm) - { -+ struct hda_bus *bus = codec->bus; -+ unsigned int res; - int err; -+ -+ res = make_codec_cmd(codec, nid, direct, verb, parm); - snd_hda_power_up(codec); -- mutex_lock(&codec->bus->cmd_mutex); -- err = codec->bus->ops.command(codec, nid, direct, verb, parm); -+ mutex_lock(&bus->cmd_mutex); -+ err = bus->ops.command(bus, res); +@@ -1839,7 +2252,11 @@ int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid, + err = bus->ops.command(bus, res); if (!err) { struct hda_cache_head *c; - u32 key = build_cmd_cache_key(nid, verb); @@ -1920,9 +1645,7 @@ index b5b1ba5..8820faf 100644 c = get_alloc_hash(&codec->cmd_cache, key); if (c) c->val = parm; - } -- mutex_unlock(&codec->bus->cmd_mutex); -+ mutex_unlock(&bus->cmd_mutex); +@@ -1848,14 +2265,15 @@ int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid, snd_hda_power_down(codec); return err; } @@ -1940,7 +1663,7 @@ index b5b1ba5..8820faf 100644 u32 key = buffer->key; if (!key) continue; -@@ -1814,6 +2281,7 @@ void snd_hda_codec_resume_cache(struct hda_codec *codec) +@@ -1863,6 +2281,7 @@ void snd_hda_codec_resume_cache(struct hda_codec *codec) get_cmd_cache_cmd(key), buffer->val); } } @@ -1948,7 +1671,7 @@ index b5b1ba5..8820faf 100644 /** * snd_hda_sequence_write_cache - sequence writes with caching -@@ -1831,6 +2299,7 @@ void snd_hda_sequence_write_cache(struct hda_codec *codec, +@@ -1880,6 +2299,7 @@ void snd_hda_sequence_write_cache(struct hda_codec *codec, snd_hda_codec_write_cache(codec, seq->nid, 0, seq->verb, seq->param); } @@ -1956,7 +1679,7 @@ index b5b1ba5..8820faf 100644 #endif /* SND_HDA_NEEDS_RESUME */ /* -@@ -1858,8 +2327,7 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, +@@ -1907,8 +2327,7 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, * don't power down the widget if it controls * eapd and EAPD_BTLENABLE is set. */ @@ -1966,7 +1689,7 @@ index b5b1ba5..8820faf 100644 if (pincap & AC_PINCAP_EAPD) { int eapd = snd_hda_codec_read(codec, nid, 0, -@@ -1891,6 +2359,17 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, +@@ -1940,6 +2359,17 @@ static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, } } @@ -1984,7 +1707,7 @@ index b5b1ba5..8820faf 100644 #ifdef SND_HDA_NEEDS_RESUME /* * call suspend and power-down; used both from PM and power-save -@@ -1917,6 +2396,8 @@ static void hda_call_codec_resume(struct hda_codec *codec) +@@ -1966,6 +2396,8 @@ static void hda_call_codec_resume(struct hda_codec *codec) hda_set_power_state(codec, codec->afg ? codec->afg : codec->mfg, AC_PWRST_D0); @@ -1993,7 +1716,7 @@ index b5b1ba5..8820faf 100644 if (codec->patch_ops.resume) codec->patch_ops.resume(codec); else { -@@ -1937,28 +2418,38 @@ static void hda_call_codec_resume(struct hda_codec *codec) +@@ -1986,28 +2418,38 @@ static void hda_call_codec_resume(struct hda_codec *codec) * * Returns 0 if successful, otherwise a negative error code. */ @@ -2048,7 +1771,7 @@ index b5b1ba5..8820faf 100644 return 0; } -@@ -2051,6 +2542,7 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate, +@@ -2100,6 +2542,7 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate, return val; } @@ -2056,7 +1779,7 @@ index b5b1ba5..8820faf 100644 /** * snd_hda_query_supported_pcm - query the supported PCM rates and formats -@@ -2065,15 +2557,14 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate, +@@ -2114,15 +2557,14 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate, * * Returns 0 if successful, otherwise a negative error code. */ @@ -2076,7 +1799,7 @@ index b5b1ba5..8820faf 100644 val = snd_hda_param_read(codec, nid, AC_PAR_PCM); if (val == -1) return -EIO; -@@ -2087,15 +2578,20 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, +@@ -2136,15 +2578,20 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, if (val & (1 << i)) rates |= rate_bits[i].alsa_bits; } @@ -2100,7 +1823,7 @@ index b5b1ba5..8820faf 100644 streams = snd_hda_param_read(codec, nid, AC_PAR_STREAM); if (streams == -1) return -EIO; -@@ -2148,6 +2644,15 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, +@@ -2197,6 +2644,15 @@ int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, formats |= SNDRV_PCM_FMTBIT_U8; bps = 8; } @@ -2116,7 +1839,7 @@ index b5b1ba5..8820faf 100644 if (formatsp) *formatsp = formats; if (bpsp) -@@ -2230,6 +2735,7 @@ int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid, +@@ -2279,6 +2735,7 @@ int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid, return 1; } @@ -2124,7 +1847,7 @@ index b5b1ba5..8820faf 100644 /* * PCM stuff -@@ -2259,31 +2765,151 @@ static int hda_pcm_default_cleanup(struct hda_pcm_stream *hinfo, +@@ -2308,31 +2765,151 @@ static int hda_pcm_default_cleanup(struct hda_pcm_stream *hinfo, return 0; } @@ -2281,7 +2004,7 @@ index b5b1ba5..8820faf 100644 /** * snd_hda_build_pcms - build PCM information * @bus: the BUS -@@ -2315,27 +2941,13 @@ int __devinit snd_hda_build_pcms(struct hda_bus *bus) +@@ -2364,27 +2941,13 @@ int __devinit snd_hda_build_pcms(struct hda_bus *bus) struct hda_codec *codec; list_for_each_entry(codec, &bus->codec_list, list) { @@ -2311,7 +2034,7 @@ index b5b1ba5..8820faf 100644 /** * snd_hda_check_board_config - compare the current codec with the config table -@@ -2354,11 +2966,11 @@ int snd_hda_check_board_config(struct hda_codec *codec, +@@ -2403,11 +2966,11 @@ int snd_hda_check_board_config(struct hda_codec *codec, int num_configs, const char **models, const struct snd_pci_quirk *tbl) { @@ -2325,7 +2048,7 @@ index b5b1ba5..8820faf 100644 snd_printd(KERN_INFO "hda_codec: model '%s' is " "selected\n", models[i]); return i; -@@ -2391,6 +3003,7 @@ int snd_hda_check_board_config(struct hda_codec *codec, +@@ -2440,6 +3003,7 @@ int snd_hda_check_board_config(struct hda_codec *codec, } return -1; } @@ -2333,7 +2056,7 @@ index b5b1ba5..8820faf 100644 /** * snd_hda_check_board_codec_sid_config - compare the current codec -@@ -2451,6 +3064,7 @@ int snd_hda_check_board_codec_sid_config(struct hda_codec *codec, +@@ -2500,6 +3064,7 @@ int snd_hda_check_board_codec_sid_config(struct hda_codec *codec, } return -1; } @@ -2341,7 +2064,7 @@ index b5b1ba5..8820faf 100644 /** * snd_hda_add_new_ctls - create controls from the array -@@ -2471,7 +3085,7 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew) +@@ -2520,7 +3085,7 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew) kctl = snd_ctl_new1(knew, codec); if (!kctl) return -ENOMEM; @@ -2350,7 +2073,7 @@ index b5b1ba5..8820faf 100644 if (err < 0) { if (!codec->addr) return err; -@@ -2479,13 +3093,14 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew) +@@ -2528,13 +3093,14 @@ int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew) if (!kctl) return -ENOMEM; kctl->id.device = codec->addr; @@ -2366,41 +2089,7 @@ index b5b1ba5..8820faf 100644 #ifdef CONFIG_SND_HDA_POWER_SAVE static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, -@@ -2495,6 +3110,7 @@ static void hda_power_work(struct work_struct *work) - { - struct hda_codec *codec = - container_of(work, struct hda_codec, power_work.work); -+ struct hda_bus *bus = codec->bus; - - if (!codec->power_on || codec->power_count) { - codec->power_transition = 0; -@@ -2502,8 +3118,8 @@ static void hda_power_work(struct work_struct *work) - } - - hda_call_codec_suspend(codec); -- if (codec->bus->ops.pm_notify) -- codec->bus->ops.pm_notify(codec); -+ if (bus->ops.pm_notify) -+ bus->ops.pm_notify(bus); - } - - static void hda_keep_power_on(struct hda_codec *codec) -@@ -2514,29 +3130,39 @@ static void hda_keep_power_on(struct hda_codec *codec) - - void snd_hda_power_up(struct hda_codec *codec) - { -+ struct hda_bus *bus = codec->bus; -+ - codec->power_count++; - if (codec->power_on || codec->power_transition) - return; - - codec->power_on = 1; -- if (codec->bus->ops.pm_notify) -- codec->bus->ops.pm_notify(codec); -+ if (bus->ops.pm_notify) -+ bus->ops.pm_notify(bus); - hda_call_codec_resume(codec); +@@ -2577,18 +3143,26 @@ void snd_hda_power_up(struct hda_codec *codec) cancel_delayed_work(&codec->power_work); codec->power_transition = 0; } @@ -2420,9 +2109,8 @@ index b5b1ba5..8820faf 100644 - if (power_save) { + if (power_save(codec)) { codec->power_transition = 1; /* avoid reentrance */ -- schedule_delayed_work(&codec->power_work, + queue_delayed_work(codec->bus->workq, &codec->power_work, - msecs_to_jiffies(power_save * 1000)); -+ queue_delayed_work(codec->bus->workq, &codec->power_work, + msecs_to_jiffies(power_save(codec) * 1000)); } } @@ -2430,7 +2118,7 @@ index b5b1ba5..8820faf 100644 int snd_hda_check_amp_list_power(struct hda_codec *codec, struct hda_loopback_check *check, -@@ -2573,6 +3199,7 @@ int snd_hda_check_amp_list_power(struct hda_codec *codec, +@@ -2625,6 +3199,7 @@ int snd_hda_check_amp_list_power(struct hda_codec *codec, } return 0; } @@ -2438,7 +2126,7 @@ index b5b1ba5..8820faf 100644 #endif /* -@@ -2592,6 +3219,7 @@ int snd_hda_ch_mode_info(struct hda_codec *codec, +@@ -2644,6 +3219,7 @@ int snd_hda_ch_mode_info(struct hda_codec *codec, chmode[uinfo->value.enumerated.item].channels); return 0; } @@ -2446,7 +2134,7 @@ index b5b1ba5..8820faf 100644 int snd_hda_ch_mode_get(struct hda_codec *codec, struct snd_ctl_elem_value *ucontrol, -@@ -2609,6 +3237,7 @@ int snd_hda_ch_mode_get(struct hda_codec *codec, +@@ -2661,6 +3237,7 @@ int snd_hda_ch_mode_get(struct hda_codec *codec, } return 0; } @@ -2454,7 +2142,7 @@ index b5b1ba5..8820faf 100644 int snd_hda_ch_mode_put(struct hda_codec *codec, struct snd_ctl_elem_value *ucontrol, -@@ -2629,6 +3258,7 @@ int snd_hda_ch_mode_put(struct hda_codec *codec, +@@ -2681,6 +3258,7 @@ int snd_hda_ch_mode_put(struct hda_codec *codec, snd_hda_sequence_write_cache(codec, chmode[mode].sequence); return 1; } @@ -2462,7 +2150,7 @@ index b5b1ba5..8820faf 100644 /* * input MUX helper -@@ -2649,6 +3279,7 @@ int snd_hda_input_mux_info(const struct hda_input_mux *imux, +@@ -2701,6 +3279,7 @@ int snd_hda_input_mux_info(const struct hda_input_mux *imux, strcpy(uinfo->value.enumerated.name, imux->items[index].label); return 0; } @@ -2470,7 +2158,7 @@ index b5b1ba5..8820faf 100644 int snd_hda_input_mux_put(struct hda_codec *codec, const struct hda_input_mux *imux, -@@ -2670,6 +3301,7 @@ int snd_hda_input_mux_put(struct hda_codec *codec, +@@ -2722,6 +3301,7 @@ int snd_hda_input_mux_put(struct hda_codec *codec, *cur_val = idx; return 1; } @@ -2478,7 +2166,7 @@ index b5b1ba5..8820faf 100644 /* -@@ -2682,7 +3314,7 @@ static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid, +@@ -2734,7 +3314,7 @@ static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid, { /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */ if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE)) @@ -2487,7 +2175,7 @@ index b5b1ba5..8820faf 100644 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff, -1); snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format); -@@ -2722,6 +3354,7 @@ int snd_hda_multi_out_dig_open(struct hda_codec *codec, +@@ -2774,6 +3354,7 @@ int snd_hda_multi_out_dig_open(struct hda_codec *codec, mutex_unlock(&codec->spdif_mutex); return 0; } @@ -2495,7 +2183,7 @@ index b5b1ba5..8820faf 100644 int snd_hda_multi_out_dig_prepare(struct hda_codec *codec, struct hda_multi_out *mout, -@@ -2734,6 +3367,17 @@ int snd_hda_multi_out_dig_prepare(struct hda_codec *codec, +@@ -2786,6 +3367,17 @@ int snd_hda_multi_out_dig_prepare(struct hda_codec *codec, mutex_unlock(&codec->spdif_mutex); return 0; } @@ -2513,7 +2201,7 @@ index b5b1ba5..8820faf 100644 /* * release the digital out -@@ -2746,6 +3390,7 @@ int snd_hda_multi_out_dig_close(struct hda_codec *codec, +@@ -2798,6 +3390,7 @@ int snd_hda_multi_out_dig_close(struct hda_codec *codec, mutex_unlock(&codec->spdif_mutex); return 0; } @@ -2521,7 +2209,7 @@ index b5b1ba5..8820faf 100644 /* * set up more restrictions for analog out -@@ -2785,6 +3430,7 @@ int snd_hda_multi_out_analog_open(struct hda_codec *codec, +@@ -2837,6 +3430,7 @@ int snd_hda_multi_out_analog_open(struct hda_codec *codec, return snd_pcm_hw_constraint_step(substream->runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, 2); } @@ -2529,7 +2217,7 @@ index b5b1ba5..8820faf 100644 /* * set up the i/o for analog out -@@ -2843,6 +3489,7 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, +@@ -2895,6 +3489,7 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, } return 0; } @@ -2537,7 +2225,7 @@ index b5b1ba5..8820faf 100644 /* * clean up the setting for analog out -@@ -2869,9 +3516,10 @@ int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, +@@ -2921,9 +3516,10 @@ int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, mutex_unlock(&codec->spdif_mutex); return 0; } @@ -2549,7 +2237,7 @@ index b5b1ba5..8820faf 100644 */ static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list) -@@ -2957,8 +3605,7 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, +@@ -3009,8 +3605,7 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, if (ignore_nids && is_in_nid_list(nid, ignore_nids)) continue; @@ -2559,7 +2247,7 @@ index b5b1ba5..8820faf 100644 if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) continue; loc = get_defcfg_location(def_conf); -@@ -3034,10 +3681,22 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, +@@ -3086,10 +3681,22 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, cfg->input_pins[AUTO_PIN_AUX] = nid; break; case AC_JACK_SPDIF_OUT: @@ -2583,7 +2271,7 @@ index b5b1ba5..8820faf 100644 break; } } -@@ -3143,6 +3802,9 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, +@@ -3195,6 +3802,9 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, cfg->hp_pins[1], cfg->hp_pins[2], cfg->hp_pins[3], cfg->hp_pins[4]); snd_printd(" mono: mono_out=0x%x\n", cfg->mono_out_pin); @@ -2593,7 +2281,7 @@ index b5b1ba5..8820faf 100644 snd_printd(" inputs: mic=0x%x, fmic=0x%x, line=0x%x, fline=0x%x," " cd=0x%x, aux=0x%x\n", cfg->input_pins[AUTO_PIN_MIC], -@@ -3151,14 +3813,18 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, +@@ -3203,14 +3813,18 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, cfg->input_pins[AUTO_PIN_FRONT_LINE], cfg->input_pins[AUTO_PIN_CD], cfg->input_pins[AUTO_PIN_AUX]); @@ -2612,7 +2300,7 @@ index b5b1ba5..8820faf 100644 #ifdef CONFIG_PM -@@ -3186,11 +3852,11 @@ int snd_hda_suspend(struct hda_bus *bus, pm_message_t state) +@@ -3238,11 +3852,11 @@ int snd_hda_suspend(struct hda_bus *bus, pm_message_t state) } return 0; } @@ -2625,7 +2313,7 @@ index b5b1ba5..8820faf 100644 * * Returns 0 if successful. * -@@ -3207,16 +3873,79 @@ int snd_hda_resume(struct hda_bus *bus) +@@ -3259,16 +3873,79 @@ int snd_hda_resume(struct hda_bus *bus) } return 0; } @@ -2716,7 +2404,7 @@ index b5b1ba5..8820faf 100644 +MODULE_DESCRIPTION("HDA codec core"); +MODULE_LICENSE("GPL"); diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h -index 26f6f9e..2fdecf4 100644 +index 84e28db..2fdecf4 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h @@ -306,15 +306,15 @@ enum { @@ -2775,16 +2463,8 @@ index 26f6f9e..2fdecf4 100644 * Structures */ -@@ -536,15 +566,17 @@ typedef u16 hda_nid_t; - /* bus operators */ - struct hda_bus_ops { - /* send a single command */ -- int (*command)(struct hda_codec *codec, hda_nid_t nid, int direct, -- unsigned int verb, unsigned int parm); -+ int (*command)(struct hda_bus *bus, unsigned int cmd); - /* get a response from the last command */ -- unsigned int (*get_response)(struct hda_codec *codec); -+ unsigned int (*get_response)(struct hda_bus *bus); +@@ -541,6 +571,9 @@ struct hda_bus_ops { + unsigned int (*get_response)(struct hda_bus *bus); /* free the private data */ void (*private_free)(struct hda_bus *); + /* attach a PCM stream */ @@ -2792,12 +2472,8 @@ index 26f6f9e..2fdecf4 100644 + struct hda_pcm *pcm); #ifdef CONFIG_SND_HDA_POWER_SAVE /* notify power-up/down from codec to controller */ -- void (*pm_notify)(struct hda_codec *codec); -+ void (*pm_notify)(struct hda_bus *bus); - #endif - }; - -@@ -553,6 +585,7 @@ struct hda_bus_template { + void (*pm_notify)(struct hda_bus *bus); +@@ -552,6 +585,7 @@ struct hda_bus_template { void *private_data; struct pci_dev *pci; const char *modelname; @@ -2805,7 +2481,7 @@ index 26f6f9e..2fdecf4 100644 struct hda_bus_ops ops; }; -@@ -569,6 +602,7 @@ struct hda_bus { +@@ -568,6 +602,7 @@ struct hda_bus { void *private_data; struct pci_dev *pci; const char *modelname; @@ -2813,12 +2489,9 @@ index 26f6f9e..2fdecf4 100644 struct hda_bus_ops ops; /* codec linked list */ -@@ -580,11 +614,15 @@ struct hda_bus { - - /* unsolicited event queue */ - struct hda_bus_unsolicited *unsol; -+ char workq_name[16]; -+ struct workqueue_struct *workq; /* common workqueue for codecs */ +@@ -582,11 +617,12 @@ struct hda_bus { + char workq_name[16]; + struct workqueue_struct *workq; /* common workqueue for codecs */ - struct snd_info_entry *proc; + /* assigned PCMs */ @@ -2826,11 +2499,12 @@ index 26f6f9e..2fdecf4 100644 /* misc op flags */ unsigned int needs_damn_long_delay :1; +- unsigned int rirb_error:1; /* error in codec communication */ + unsigned int shutdown :1; /* being unloaded */ }; /* -@@ -604,6 +642,16 @@ struct hda_codec_preset { +@@ -606,6 +642,16 @@ struct hda_codec_preset { int (*patch)(struct hda_codec *codec); }; @@ -2847,7 +2521,7 @@ index 26f6f9e..2fdecf4 100644 /* ops set by the preset patch */ struct hda_codec_ops { int (*build_controls)(struct hda_codec *codec); -@@ -635,10 +683,7 @@ struct hda_amp_info { +@@ -637,10 +683,7 @@ struct hda_amp_info { struct hda_cache_rec { u16 hash[64]; /* hash table for index */ @@ -2859,7 +2533,7 @@ index 26f6f9e..2fdecf4 100644 }; /* PCM callbacks */ -@@ -680,7 +725,8 @@ struct hda_pcm { +@@ -682,7 +725,8 @@ struct hda_pcm { char *name; struct hda_pcm_stream stream[2]; unsigned int pcm_type; /* HDA_PCM_TYPE_XXX */ @@ -2869,7 +2543,7 @@ index 26f6f9e..2fdecf4 100644 }; /* codec information */ -@@ -693,12 +739,16 @@ struct hda_codec { +@@ -695,12 +739,16 @@ struct hda_codec { hda_nid_t mfg; /* MFG node id */ /* ids */ @@ -2886,7 +2560,7 @@ index 26f6f9e..2fdecf4 100644 /* set by patch */ struct hda_codec_ops patch_ops; -@@ -718,28 +768,45 @@ struct hda_codec { +@@ -720,28 +768,45 @@ struct hda_codec { hda_nid_t start_nid; u32 *wcaps; @@ -2932,7 +2606,7 @@ index 26f6f9e..2fdecf4 100644 }; /* direction */ -@@ -754,7 +821,7 @@ enum { +@@ -756,7 +821,7 @@ enum { int snd_hda_bus_new(struct snd_card *card, const struct hda_bus_template *temp, struct hda_bus **busp); int snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr, @@ -2941,7 +2615,7 @@ index 26f6f9e..2fdecf4 100644 /* * low level functions -@@ -795,15 +862,29 @@ void snd_hda_codec_resume_cache(struct hda_codec *codec); +@@ -797,15 +862,29 @@ void snd_hda_codec_resume_cache(struct hda_codec *codec); #define snd_hda_sequence_write_cache snd_hda_sequence_write #endif @@ -2971,7 +2645,7 @@ index 26f6f9e..2fdecf4 100644 void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, u32 stream_tag, int channel_id, int format); -@@ -812,8 +893,6 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate, +@@ -814,8 +893,6 @@ unsigned int snd_hda_calc_stream_format(unsigned int rate, unsigned int channels, unsigned int format, unsigned int maxbps); @@ -2980,7 +2654,7 @@ index 26f6f9e..2fdecf4 100644 int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid, unsigned int format); -@@ -831,18 +910,38 @@ int snd_hda_resume(struct hda_bus *bus); +@@ -833,18 +910,38 @@ int snd_hda_resume(struct hda_bus *bus); #endif /* @@ -3021,602 +2695,6 @@ index 26f6f9e..2fdecf4 100644 #endif #endif /* __SOUND_HDA_CODEC_H */ -diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c -new file mode 100644 -index 0000000..fcad5ec ---- /dev/null -+++ b/sound/pci/hda/hda_eld.c -@@ -0,0 +1,590 @@ -+/* -+ * Generic routines and proc interface for ELD(EDID Like Data) information -+ * -+ * Copyright(c) 2008 Intel Corporation. -+ * -+ * Authors: -+ * Wu Fengguang -+ * -+ * 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 "hda_codec.h" -+#include "hda_local.h" -+ -+enum eld_versions { -+ ELD_VER_CEA_861D = 2, -+ ELD_VER_PARTIAL = 31, -+}; -+ -+enum cea_edid_versions { -+ CEA_EDID_VER_NONE = 0, -+ CEA_EDID_VER_CEA861 = 1, -+ CEA_EDID_VER_CEA861A = 2, -+ CEA_EDID_VER_CEA861BCD = 3, -+ CEA_EDID_VER_RESERVED = 4, -+}; -+ -+static char *cea_speaker_allocation_names[] = { -+ /* 0 */ "FL/FR", -+ /* 1 */ "LFE", -+ /* 2 */ "FC", -+ /* 3 */ "RL/RR", -+ /* 4 */ "RC", -+ /* 5 */ "FLC/FRC", -+ /* 6 */ "RLC/RRC", -+ /* 7 */ "FLW/FRW", -+ /* 8 */ "FLH/FRH", -+ /* 9 */ "TC", -+ /* 10 */ "FCH", -+}; -+ -+static char *eld_connection_type_names[4] = { -+ "HDMI", -+ "DisplayPort", -+ "2-reserved", -+ "3-reserved" -+}; -+ -+enum cea_audio_coding_types { -+ AUDIO_CODING_TYPE_REF_STREAM_HEADER = 0, -+ AUDIO_CODING_TYPE_LPCM = 1, -+ AUDIO_CODING_TYPE_AC3 = 2, -+ AUDIO_CODING_TYPE_MPEG1 = 3, -+ AUDIO_CODING_TYPE_MP3 = 4, -+ AUDIO_CODING_TYPE_MPEG2 = 5, -+ AUDIO_CODING_TYPE_AACLC = 6, -+ AUDIO_CODING_TYPE_DTS = 7, -+ AUDIO_CODING_TYPE_ATRAC = 8, -+ AUDIO_CODING_TYPE_SACD = 9, -+ AUDIO_CODING_TYPE_EAC3 = 10, -+ AUDIO_CODING_TYPE_DTS_HD = 11, -+ AUDIO_CODING_TYPE_MLP = 12, -+ AUDIO_CODING_TYPE_DST = 13, -+ AUDIO_CODING_TYPE_WMAPRO = 14, -+ AUDIO_CODING_TYPE_REF_CXT = 15, -+ /* also include valid xtypes below */ -+ AUDIO_CODING_TYPE_HE_AAC = 15, -+ AUDIO_CODING_TYPE_HE_AAC2 = 16, -+ AUDIO_CODING_TYPE_MPEG_SURROUND = 17, -+}; -+ -+enum cea_audio_coding_xtypes { -+ AUDIO_CODING_XTYPE_HE_REF_CT = 0, -+ AUDIO_CODING_XTYPE_HE_AAC = 1, -+ AUDIO_CODING_XTYPE_HE_AAC2 = 2, -+ AUDIO_CODING_XTYPE_MPEG_SURROUND = 3, -+ AUDIO_CODING_XTYPE_FIRST_RESERVED = 4, -+}; -+ -+static char *cea_audio_coding_type_names[] = { -+ /* 0 */ "undefined", -+ /* 1 */ "LPCM", -+ /* 2 */ "AC-3", -+ /* 3 */ "MPEG1", -+ /* 4 */ "MP3", -+ /* 5 */ "MPEG2", -+ /* 6 */ "AAC-LC", -+ /* 7 */ "DTS", -+ /* 8 */ "ATRAC", -+ /* 9 */ "DSD (One Bit Audio)", -+ /* 10 */ "E-AC-3/DD+ (Dolby Digital Plus)", -+ /* 11 */ "DTS-HD", -+ /* 12 */ "MLP (Dolby TrueHD)", -+ /* 13 */ "DST", -+ /* 14 */ "WMAPro", -+ /* 15 */ "HE-AAC", -+ /* 16 */ "HE-AACv2", -+ /* 17 */ "MPEG Surround", -+}; -+ -+/* -+ * The following two lists are shared between -+ * - HDMI audio InfoFrame (source to sink) -+ * - CEA E-EDID Extension (sink to source) -+ */ -+ -+/* -+ * SS1:SS0 index => sample size -+ */ -+static int cea_sample_sizes[4] = { -+ 0, /* 0: Refer to Stream Header */ -+ AC_SUPPCM_BITS_16, /* 1: 16 bits */ -+ AC_SUPPCM_BITS_20, /* 2: 20 bits */ -+ AC_SUPPCM_BITS_24, /* 3: 24 bits */ -+}; -+ -+/* -+ * SF2:SF1:SF0 index => sampling frequency -+ */ -+static int cea_sampling_frequencies[8] = { -+ 0, /* 0: Refer to Stream Header */ -+ SNDRV_PCM_RATE_32000, /* 1: 32000Hz */ -+ SNDRV_PCM_RATE_44100, /* 2: 44100Hz */ -+ SNDRV_PCM_RATE_48000, /* 3: 48000Hz */ -+ SNDRV_PCM_RATE_88200, /* 4: 88200Hz */ -+ SNDRV_PCM_RATE_96000, /* 5: 96000Hz */ -+ SNDRV_PCM_RATE_176400, /* 6: 176400Hz */ -+ SNDRV_PCM_RATE_192000, /* 7: 192000Hz */ -+}; -+ -+static unsigned char hdmi_get_eld_byte(struct hda_codec *codec, hda_nid_t nid, -+ int byte_index) -+{ -+ unsigned int val; -+ -+ val = snd_hda_codec_read(codec, nid, 0, -+ AC_VERB_GET_HDMI_ELDD, byte_index); -+ -+#ifdef BE_PARANOID -+ printk(KERN_INFO "HDMI: ELD data byte %d: 0x%x\n", byte_index, val); -+#endif -+ -+ if ((val & AC_ELDD_ELD_VALID) == 0) { -+ snd_printd(KERN_INFO "HDMI: invalid ELD data byte %d\n", -+ byte_index); -+ val = 0; -+ } -+ -+ return val & AC_ELDD_ELD_DATA; -+} -+ -+#define GRAB_BITS(buf, byte, lowbit, bits) \ -+({ \ -+ BUILD_BUG_ON(lowbit > 7); \ -+ BUILD_BUG_ON(bits > 8); \ -+ BUILD_BUG_ON(bits <= 0); \ -+ \ -+ (buf[byte] >> (lowbit)) & ((1 << (bits)) - 1); \ -+}) -+ -+static void hdmi_update_short_audio_desc(struct cea_sad *a, -+ const unsigned char *buf) -+{ -+ int i; -+ int val; -+ -+ val = GRAB_BITS(buf, 1, 0, 7); -+ a->rates = 0; -+ for (i = 0; i < 7; i++) -+ if (val & (1 << i)) -+ a->rates |= cea_sampling_frequencies[i + 1]; -+ -+ a->channels = GRAB_BITS(buf, 0, 0, 3); -+ a->channels++; -+ -+ a->format = GRAB_BITS(buf, 0, 3, 4); -+ switch (a->format) { -+ case AUDIO_CODING_TYPE_REF_STREAM_HEADER: -+ snd_printd(KERN_INFO -+ "HDMI: audio coding type 0 not expected\n"); -+ break; -+ -+ case AUDIO_CODING_TYPE_LPCM: -+ val = GRAB_BITS(buf, 2, 0, 3); -+ a->sample_bits = 0; -+ for (i = 0; i < 3; i++) -+ if (val & (1 << i)) -+ a->sample_bits |= cea_sample_sizes[i + 1]; -+ break; -+ -+ case AUDIO_CODING_TYPE_AC3: -+ case AUDIO_CODING_TYPE_MPEG1: -+ case AUDIO_CODING_TYPE_MP3: -+ case AUDIO_CODING_TYPE_MPEG2: -+ case AUDIO_CODING_TYPE_AACLC: -+ case AUDIO_CODING_TYPE_DTS: -+ case AUDIO_CODING_TYPE_ATRAC: -+ a->max_bitrate = GRAB_BITS(buf, 2, 0, 8); -+ a->max_bitrate *= 8000; -+ break; -+ -+ case AUDIO_CODING_TYPE_SACD: -+ break; -+ -+ case AUDIO_CODING_TYPE_EAC3: -+ break; -+ -+ case AUDIO_CODING_TYPE_DTS_HD: -+ break; -+ -+ case AUDIO_CODING_TYPE_MLP: -+ break; -+ -+ case AUDIO_CODING_TYPE_DST: -+ break; -+ -+ case AUDIO_CODING_TYPE_WMAPRO: -+ a->profile = GRAB_BITS(buf, 2, 0, 3); -+ break; -+ -+ case AUDIO_CODING_TYPE_REF_CXT: -+ a->format = GRAB_BITS(buf, 2, 3, 5); -+ if (a->format == AUDIO_CODING_XTYPE_HE_REF_CT || -+ a->format >= AUDIO_CODING_XTYPE_FIRST_RESERVED) { -+ snd_printd(KERN_INFO -+ "HDMI: audio coding xtype %d not expected\n", -+ a->format); -+ a->format = 0; -+ } else -+ a->format += AUDIO_CODING_TYPE_HE_AAC - -+ AUDIO_CODING_XTYPE_HE_AAC; -+ break; -+ } -+} -+ -+/* -+ * Be careful, ELD buf could be totally rubbish! -+ */ -+static int hdmi_update_eld(struct hdmi_eld *e, -+ const unsigned char *buf, int size) -+{ -+ int mnl; -+ int i; -+ -+ e->eld_ver = GRAB_BITS(buf, 0, 3, 5); -+ if (e->eld_ver != ELD_VER_CEA_861D && -+ e->eld_ver != ELD_VER_PARTIAL) { -+ snd_printd(KERN_INFO "HDMI: Unknown ELD version %d\n", -+ e->eld_ver); -+ goto out_fail; -+ } -+ -+ e->eld_size = size; -+ e->baseline_len = GRAB_BITS(buf, 2, 0, 8); -+ mnl = GRAB_BITS(buf, 4, 0, 5); -+ e->cea_edid_ver = GRAB_BITS(buf, 4, 5, 3); -+ -+ e->support_hdcp = GRAB_BITS(buf, 5, 0, 1); -+ e->support_ai = GRAB_BITS(buf, 5, 1, 1); -+ e->conn_type = GRAB_BITS(buf, 5, 2, 2); -+ e->sad_count = GRAB_BITS(buf, 5, 4, 4); -+ -+ e->aud_synch_delay = GRAB_BITS(buf, 6, 0, 8) * 2; -+ e->spk_alloc = GRAB_BITS(buf, 7, 0, 7); -+ -+ e->port_id = get_unaligned_le64(buf + 8); -+ -+ /* not specified, but the spec's tendency is little endian */ -+ e->manufacture_id = get_unaligned_le16(buf + 16); -+ e->product_id = get_unaligned_le16(buf + 18); -+ -+ if (mnl > ELD_MAX_MNL) { -+ snd_printd(KERN_INFO "HDMI: MNL is reserved value %d\n", mnl); -+ goto out_fail; -+ } else if (ELD_FIXED_BYTES + mnl > size) { -+ snd_printd(KERN_INFO "HDMI: out of range MNL %d\n", mnl); -+ goto out_fail; -+ } else -+ strlcpy(e->monitor_name, buf + ELD_FIXED_BYTES, mnl); -+ -+ for (i = 0; i < e->sad_count; i++) { -+ if (ELD_FIXED_BYTES + mnl + 3 * (i + 1) > size) { -+ snd_printd(KERN_INFO "HDMI: out of range SAD %d\n", i); -+ goto out_fail; -+ } -+ hdmi_update_short_audio_desc(e->sad + i, -+ buf + ELD_FIXED_BYTES + mnl + 3 * i); -+ } -+ -+ return 0; -+ -+out_fail: -+ e->eld_ver = 0; -+ return -EINVAL; -+} -+ -+static int hdmi_present_sense(struct hda_codec *codec, hda_nid_t nid) -+{ -+ return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_SENSE, 0); -+} -+ -+static int hdmi_eld_valid(struct hda_codec *codec, hda_nid_t nid) -+{ -+ int eldv; -+ int present; -+ -+ present = hdmi_present_sense(codec, nid); -+ eldv = (present & AC_PINSENSE_ELDV); -+ present = (present & AC_PINSENSE_PRESENCE); -+ -+#ifdef CONFIG_SND_DEBUG_VERBOSE -+ printk(KERN_INFO "HDMI: sink_present = %d, eld_valid = %d\n", -+ !!present, !!eldv); -+#endif -+ -+ return eldv && present; -+} -+ -+int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid) -+{ -+ return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_DIP_SIZE, -+ AC_DIPSIZE_ELD_BUF); -+} -+ -+int snd_hdmi_get_eld(struct hdmi_eld *eld, -+ struct hda_codec *codec, hda_nid_t nid) -+{ -+ int i; -+ int ret; -+ int size; -+ unsigned char *buf; -+ -+ if (!hdmi_eld_valid(codec, nid)) -+ return -ENOENT; -+ -+ size = snd_hdmi_get_eld_size(codec, nid); -+ if (size == 0) { -+ /* wfg: workaround for ASUS P5E-VM HDMI board */ -+ snd_printd(KERN_INFO "HDMI: ELD buf size is 0, force 128\n"); -+ size = 128; -+ } -+ if (size < ELD_FIXED_BYTES || size > PAGE_SIZE) { -+ snd_printd(KERN_INFO "HDMI: invalid ELD buf size %d\n", size); -+ return -ERANGE; -+ } -+ -+ buf = kmalloc(size, GFP_KERNEL); -+ if (!buf) -+ return -ENOMEM; -+ -+ for (i = 0; i < size; i++) -+ buf[i] = hdmi_get_eld_byte(codec, nid, i); -+ -+ ret = hdmi_update_eld(eld, buf, size); -+ -+ kfree(buf); -+ return ret; -+} -+ -+static void hdmi_show_short_audio_desc(struct cea_sad *a) -+{ -+ char buf[SND_PRINT_RATES_ADVISED_BUFSIZE]; -+ char buf2[8 + SND_PRINT_BITS_ADVISED_BUFSIZE] = ", bits ="; -+ -+ if (!a->format) -+ return; -+ -+ snd_print_pcm_rates(a->rates, buf, sizeof(buf)); -+ -+ if (a->format == AUDIO_CODING_TYPE_LPCM) -+ snd_print_pcm_bits(a->sample_bits, buf2 + 8, sizeof(buf2 - 8)); -+ else if (a->max_bitrate) -+ snprintf(buf2, sizeof(buf2), -+ ", max bitrate = %d", a->max_bitrate); -+ else -+ buf2[0] = '\0'; -+ -+ printk(KERN_INFO "HDMI: supports coding type %s:" -+ " channels = %d, rates =%s%s\n", -+ cea_audio_coding_type_names[a->format], -+ a->channels, -+ buf, -+ buf2); -+} -+ -+void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen) -+{ -+ int i, j; -+ -+ for (i = 0, j = 0; i < ARRAY_SIZE(cea_speaker_allocation_names); i++) { -+ if (spk_alloc & (1 << i)) -+ j += snprintf(buf + j, buflen - j, " %s", -+ cea_speaker_allocation_names[i]); -+ } -+ buf[j] = '\0'; /* necessary when j == 0 */ -+} -+ -+void snd_hdmi_show_eld(struct hdmi_eld *e) -+{ -+ int i; -+ -+ printk(KERN_INFO "HDMI: detected monitor %s at connection type %s\n", -+ e->monitor_name, -+ eld_connection_type_names[e->conn_type]); -+ -+ if (e->spk_alloc) { -+ char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE]; -+ snd_print_channel_allocation(e->spk_alloc, buf, sizeof(buf)); -+ printk(KERN_INFO "HDMI: available speakers:%s\n", buf); -+ } -+ -+ for (i = 0; i < e->sad_count; i++) -+ hdmi_show_short_audio_desc(e->sad + i); -+} -+ -+#ifdef CONFIG_PROC_FS -+ -+static void hdmi_print_sad_info(int i, struct cea_sad *a, -+ struct snd_info_buffer *buffer) -+{ -+ char buf[SND_PRINT_RATES_ADVISED_BUFSIZE]; -+ -+ snd_iprintf(buffer, "sad%d_coding_type\t[0x%x] %s\n", -+ i, a->format, cea_audio_coding_type_names[a->format]); -+ snd_iprintf(buffer, "sad%d_channels\t\t%d\n", i, a->channels); -+ -+ snd_print_pcm_rates(a->rates, buf, sizeof(buf)); -+ snd_iprintf(buffer, "sad%d_rates\t\t[0x%x]%s\n", i, a->rates, buf); -+ -+ if (a->format == AUDIO_CODING_TYPE_LPCM) { -+ snd_print_pcm_bits(a->sample_bits, buf, sizeof(buf)); -+ snd_iprintf(buffer, "sad%d_bits\t\t[0x%x]%s\n", -+ i, a->sample_bits, buf); -+ } -+ -+ if (a->max_bitrate) -+ snd_iprintf(buffer, "sad%d_max_bitrate\t%d\n", -+ i, a->max_bitrate); -+ -+ if (a->profile) -+ snd_iprintf(buffer, "sad%d_profile\t\t%d\n", i, a->profile); -+} -+ -+static void hdmi_print_eld_info(struct snd_info_entry *entry, -+ struct snd_info_buffer *buffer) -+{ -+ struct hdmi_eld *e = entry->private_data; -+ char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE]; -+ int i; -+ static char *eld_versoin_names[32] = { -+ "reserved", -+ "reserved", -+ "CEA-861D or below", -+ [3 ... 30] = "reserved", -+ [31] = "partial" -+ }; -+ static char *cea_edid_version_names[8] = { -+ "no CEA EDID Timing Extension block present", -+ "CEA-861", -+ "CEA-861-A", -+ "CEA-861-B, C or D", -+ [4 ... 7] = "reserved" -+ }; -+ -+ snd_iprintf(buffer, "monitor_name\t\t%s\n", e->monitor_name); -+ snd_iprintf(buffer, "connection_type\t\t%s\n", -+ eld_connection_type_names[e->conn_type]); -+ snd_iprintf(buffer, "eld_version\t\t[0x%x] %s\n", e->eld_ver, -+ eld_versoin_names[e->eld_ver]); -+ snd_iprintf(buffer, "edid_version\t\t[0x%x] %s\n", e->cea_edid_ver, -+ cea_edid_version_names[e->cea_edid_ver]); -+ snd_iprintf(buffer, "manufacture_id\t\t0x%x\n", e->manufacture_id); -+ snd_iprintf(buffer, "product_id\t\t0x%x\n", e->product_id); -+ snd_iprintf(buffer, "port_id\t\t\t0x%llx\n", (long long)e->port_id); -+ snd_iprintf(buffer, "support_hdcp\t\t%d\n", e->support_hdcp); -+ snd_iprintf(buffer, "support_ai\t\t%d\n", e->support_ai); -+ snd_iprintf(buffer, "audio_sync_delay\t%d\n", e->aud_synch_delay); -+ -+ snd_print_channel_allocation(e->spk_alloc, buf, sizeof(buf)); -+ snd_iprintf(buffer, "speakers\t\t[0x%x]%s\n", e->spk_alloc, buf); -+ -+ snd_iprintf(buffer, "sad_count\t\t%d\n", e->sad_count); -+ -+ for (i = 0; i < e->sad_count; i++) -+ hdmi_print_sad_info(i, e->sad + i, buffer); -+} -+ -+static void hdmi_write_eld_info(struct snd_info_entry *entry, -+ struct snd_info_buffer *buffer) -+{ -+ struct hdmi_eld *e = entry->private_data; -+ char line[64]; -+ char name[64]; -+ char *sname; -+ long long val; -+ int n; -+ -+ while (!snd_info_get_line(buffer, line, sizeof(line))) { -+ if (sscanf(line, "%s %llx", name, &val) != 2) -+ continue; -+ /* -+ * We don't allow modification to these fields: -+ * monitor_name manufacture_id product_id -+ * eld_version edid_version -+ */ -+ if (!strcmp(name, "connection_type")) -+ e->conn_type = val; -+ else if (!strcmp(name, "port_id")) -+ e->port_id = val; -+ else if (!strcmp(name, "support_hdcp")) -+ e->support_hdcp = val; -+ else if (!strcmp(name, "support_ai")) -+ e->support_ai = val; -+ else if (!strcmp(name, "audio_sync_delay")) -+ e->aud_synch_delay = val; -+ else if (!strcmp(name, "speakers")) -+ e->spk_alloc = val; -+ else if (!strcmp(name, "sad_count")) -+ e->sad_count = val; -+ else if (!strncmp(name, "sad", 3)) { -+ sname = name + 4; -+ n = name[3] - '0'; -+ if (name[4] >= '0' && name[4] <= '9') { -+ sname++; -+ n = 10 * n + name[4] - '0'; -+ } -+ if (n < 0 || n > 31) /* double the CEA limit */ -+ continue; -+ if (!strcmp(sname, "_coding_type")) -+ e->sad[n].format = val; -+ else if (!strcmp(sname, "_channels")) -+ e->sad[n].channels = val; -+ else if (!strcmp(sname, "_rates")) -+ e->sad[n].rates = val; -+ else if (!strcmp(sname, "_bits")) -+ e->sad[n].sample_bits = val; -+ else if (!strcmp(sname, "_max_bitrate")) -+ e->sad[n].max_bitrate = val; -+ else if (!strcmp(sname, "_profile")) -+ e->sad[n].profile = val; -+ if (n >= e->sad_count) -+ e->sad_count = n + 1; -+ } -+ } -+} -+ -+ -+int snd_hda_eld_proc_new(struct hda_codec *codec, struct hdmi_eld *eld) -+{ -+ char name[32]; -+ struct snd_info_entry *entry; -+ int err; -+ -+ snprintf(name, sizeof(name), "eld#%d", codec->addr); -+ err = snd_card_proc_new(codec->bus->card, name, &entry); -+ if (err < 0) -+ return err; -+ -+ snd_info_set_text_ops(entry, eld, hdmi_print_eld_info); -+ entry->c.text.write = hdmi_write_eld_info; -+ entry->mode |= S_IWUSR; -+ eld->proc_entry = entry; -+ -+ return 0; -+} -+ -+void snd_hda_eld_proc_free(struct hda_codec *codec, struct hdmi_eld *eld) -+{ -+ if (!codec->bus->shutdown && eld->proc_entry) { -+ snd_device_free(codec->bus->card, eld->proc_entry); -+ eld->proc_entry = NULL; -+ } -+} -+ -+#endif /* CONFIG_PROC_FS */ diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 59e4389..1d5797a 100644 --- a/sound/pci/hda/hda_generic.c @@ -4178,7 +3256,7 @@ index 6e18a42..1c57505 100644 + +#endif /* CONFIG_SND_HDA_RECONFIG */ diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c -index d9d2943..d1c03f9 100644 +index 0d1a74b..d1c03f9 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -58,6 +58,7 @@ static char *model[SNDRV_CARDS]; @@ -4219,41 +3297,23 @@ index d9d2943..d1c03f9 100644 /* */ -@@ -304,6 +312,8 @@ struct azx_dev { +@@ -304,7 +312,6 @@ struct azx_dev { unsigned int period_bytes; /* size of the period in bytes */ unsigned int frags; /* number for period in the play buffer */ unsigned int fifo_size; /* FIFO size */ -+ unsigned long start_jiffies; /* start + minimum jiffies */ -+ unsigned long min_jiffies; /* minimum jiffies before position is valid */ - - void __iomem *sd_addr; /* stream descriptor pointer */ +- unsigned int start_flag: 1; /* stream full start flag */ + unsigned long start_jiffies; /* start + minimum jiffies */ + unsigned long min_jiffies; /* minimum jiffies before position is valid */ -@@ -322,7 +332,7 @@ struct azx_dev { +@@ -325,6 +332,7 @@ struct azx_dev { unsigned int opened :1; unsigned int running :1; unsigned int irq_pending :1; -- unsigned int irq_ignore :1; + unsigned int start_flag: 1; /* stream full start flag */ /* * For VIA: * A flag to ensure DMA position is 0 -@@ -373,6 +383,7 @@ struct azx { - - /* HD codec */ - unsigned short codec_mask; -+ int codec_probe_mask; /* copied from probe_mask option */ - struct hda_bus *bus; - - /* CORB/RIRB */ -@@ -392,6 +403,7 @@ struct azx { - unsigned int msi :1; - unsigned int irq_pending_warned :1; - unsigned int via_dmapos_patch :1; /* enable DMA-position fix for VIA */ -+ unsigned int probing :1; /* codec probing phase */ - - /* for debugging */ - unsigned int last_cmd; /* last issued command (to sync) */ -@@ -414,6 +426,7 @@ enum { +@@ -418,6 +426,7 @@ enum { AZX_DRIVER_ULI, AZX_DRIVER_NVIDIA, AZX_DRIVER_TERA, @@ -4261,7 +3321,7 @@ index d9d2943..d1c03f9 100644 AZX_NUM_DRIVERS, /* keep this as last entry */ }; -@@ -427,6 +440,7 @@ static char *driver_short_names[] __devinitdata = { +@@ -431,6 +440,7 @@ static char *driver_short_names[] __devinitdata = { [AZX_DRIVER_ULI] = "HDA ULI M5461", [AZX_DRIVER_NVIDIA] = "HDA NVidia", [AZX_DRIVER_TERA] = "HDA Teradici", @@ -4269,313 +3329,67 @@ index d9d2943..d1c03f9 100644 }; /* -@@ -527,9 +541,9 @@ static void azx_free_cmd_io(struct azx *chip) - } - - /* send a command */ --static int azx_corb_send_cmd(struct hda_codec *codec, u32 val) -+static int azx_corb_send_cmd(struct hda_bus *bus, u32 val) - { -- struct azx *chip = codec->bus->private_data; -+ struct azx *chip = bus->private_data; - unsigned int wp; - - /* add command to corb */ -@@ -577,9 +591,9 @@ static void azx_update_rirb(struct azx *chip) - } - - /* receive a response */ --static unsigned int azx_rirb_get_response(struct hda_codec *codec) -+static unsigned int azx_rirb_get_response(struct hda_bus *bus) - { -- struct azx *chip = codec->bus->private_data; -+ struct azx *chip = bus->private_data; - unsigned long timeout; - - again: -@@ -596,7 +610,7 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec) +@@ -596,7 +606,6 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus) + } + if (!chip->rirb.cmds) { + smp_rmb(); +- bus->rirb_error = 0; + return chip->rirb.res; /* the last value */ } if (time_after(jiffies, timeout)) - break; -- if (codec->bus->needs_damn_long_delay) -+ if (bus->needs_damn_long_delay) - msleep(2); /* temporary workaround */ - else { - udelay(10); -@@ -624,6 +638,14 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec) +@@ -616,10 +625,8 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus) + chip->irq = -1; + pci_disable_msi(chip->pci); + chip->msi = 0; +- if (azx_acquire_irq(chip, 1) < 0) { +- bus->rirb_error = 1; ++ if (azx_acquire_irq(chip, 1) < 0) + return -1; +- } goto again; } -+ if (chip->probing) { -+ /* If this critical timeout happens during the codec probing -+ * phase, this is likely an access to a non-existing codec -+ * slot. Better to return an error and reset the system. -+ */ -+ return -1; -+ } -+ - snd_printk(KERN_ERR "hda_intel: azx_get_response timeout, " - "switching to single_cmd mode: last cmd=0x%08x\n", - chip->last_cmd); -@@ -646,9 +668,9 @@ static unsigned int azx_rirb_get_response(struct hda_codec *codec) - */ - - /* send a command */ --static int azx_single_send_cmd(struct hda_codec *codec, u32 val) -+static int azx_single_send_cmd(struct hda_bus *bus, u32 val) - { -- struct azx *chip = codec->bus->private_data; -+ struct azx *chip = bus->private_data; - int timeout = 50; - - while (timeout--) { -@@ -671,9 +693,9 @@ static int azx_single_send_cmd(struct hda_codec *codec, u32 val) - } - - /* receive a response */ --static unsigned int azx_single_get_response(struct hda_codec *codec) -+static unsigned int azx_single_get_response(struct hda_bus *bus) - { -- struct azx *chip = codec->bus->private_data; -+ struct azx *chip = bus->private_data; - int timeout = 50; - - while (timeout--) { -@@ -696,38 +718,29 @@ static unsigned int azx_single_get_response(struct hda_codec *codec) - */ - - /* send a command */ --static int azx_send_cmd(struct hda_codec *codec, hda_nid_t nid, -- int direct, unsigned int verb, -- unsigned int para) --{ -- struct azx *chip = codec->bus->private_data; -- u32 val; -- -- val = (u32)(codec->addr & 0x0f) << 28; -- val |= (u32)direct << 27; -- val |= (u32)nid << 20; -- val |= verb << 8; -- val |= para; -- chip->last_cmd = val; -+static int azx_send_cmd(struct hda_bus *bus, unsigned int val) -+{ -+ struct azx *chip = bus->private_data; - -+ chip->last_cmd = val; - if (chip->single_cmd) -- return azx_single_send_cmd(codec, val); -+ return azx_single_send_cmd(bus, val); - else -- return azx_corb_send_cmd(codec, val); -+ return azx_corb_send_cmd(bus, val); - } - - /* get a response */ --static unsigned int azx_get_response(struct hda_codec *codec) -+static unsigned int azx_get_response(struct hda_bus *bus) - { -- struct azx *chip = codec->bus->private_data; -+ struct azx *chip = bus->private_data; - if (chip->single_cmd) -- return azx_single_get_response(codec); -+ return azx_single_get_response(bus); - else -- return azx_rirb_get_response(codec); -+ return azx_rirb_get_response(bus); - } - - #ifdef CONFIG_SND_HDA_POWER_SAVE --static void azx_power_notify(struct hda_codec *codec); -+static void azx_power_notify(struct hda_bus *bus); - #endif - - /* reset codec link */ -@@ -848,13 +861,18 @@ static void azx_stream_start(struct azx *chip, struct azx_dev *azx_dev) - SD_CTL_DMA_START | SD_INT_MASK); - } - --/* stop a stream */ --static void azx_stream_stop(struct azx *chip, struct azx_dev *azx_dev) -+/* stop DMA */ -+static void azx_stream_clear(struct azx *chip, struct azx_dev *azx_dev) - { -- /* stop DMA */ - azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) & - ~(SD_CTL_DMA_START | SD_INT_MASK)); - azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK); /* to be sure */ -+} -+ -+/* stop a stream */ -+static void azx_stream_stop(struct azx *chip, struct azx_dev *azx_dev) -+{ -+ azx_stream_clear(chip, azx_dev); - /* disable SIE */ - azx_writeb(chip, INTCTL, - azx_readb(chip, INTCTL) & ~(1 << azx_dev->index)); -@@ -959,7 +977,7 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id) - struct azx *chip = dev_id; - struct azx_dev *azx_dev; - u32 status; -- int i; -+ int i, ok; - - spin_lock(&chip->reg_lock); - -@@ -975,21 +993,18 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id) - azx_sd_writeb(azx_dev, SD_STS, SD_INT_MASK); - if (!azx_dev->substream || !azx_dev->running) - continue; -- /* ignore the first dummy IRQ (due to pos_adj) */ -- if (azx_dev->irq_ignore) { -- azx_dev->irq_ignore = 0; -- continue; -- } - /* check whether this IRQ is really acceptable */ -- if (azx_position_ok(chip, azx_dev)) { -+ ok = azx_position_ok(chip, azx_dev); -+ if (ok == 1) { - azx_dev->irq_pending = 0; - spin_unlock(&chip->reg_lock); - snd_pcm_period_elapsed(azx_dev->substream); - spin_lock(&chip->reg_lock); -- } else { -+ } else if (ok == 0 && chip->bus && chip->bus->workq) { - /* bogus IRQ, process it later */ - azx_dev->irq_pending = 1; -- schedule_work(&chip->irq_pending_work); -+ queue_work(chip->bus->workq, -+ &chip->irq_pending_work); - } - } - } -@@ -1067,15 +1082,13 @@ static int azx_setup_periods(struct azx *chip, - azx_sd_writel(azx_dev, SD_BDLPL, 0); - azx_sd_writel(azx_dev, SD_BDLPU, 0); - -- period_bytes = snd_pcm_lib_period_bytes(substream); -- azx_dev->period_bytes = period_bytes; -+ period_bytes = azx_dev->period_bytes; - periods = azx_dev->bufsize / period_bytes; - - /* program the initial BDL entries */ - bdl = (u32 *)azx_dev->bdl.area; - ofs = 0; - azx_dev->frags = 0; -- azx_dev->irq_ignore = 0; - pos_adj = bdl_pos_adj[chip->dev_index]; - if (pos_adj > 0) { - struct snd_pcm_runtime *runtime = substream->runtime; -@@ -1096,7 +1109,6 @@ static int azx_setup_periods(struct azx *chip, - &bdl, ofs, pos_adj, 1); - if (ofs < 0) - goto error; -- azx_dev->irq_ignore = 1; - } - } else - pos_adj = 0; -@@ -1115,24 +1127,17 @@ static int azx_setup_periods(struct azx *chip, - error: - snd_printk(KERN_ERR "Too many BDL entries: buffer=%d, period=%d\n", - azx_dev->bufsize, period_bytes); -- /* reset */ -- azx_sd_writel(azx_dev, SD_BDLPL, 0); -- azx_sd_writel(azx_dev, SD_BDLPU, 0); - return -EINVAL; +@@ -639,12 +646,14 @@ static unsigned int azx_rirb_get_response(struct hda_bus *bus) + return -1; + } + +- snd_printk(KERN_ERR "hda_intel: azx_get_response timeout (ERROR): " +- "last cmd=0x%08x\n", chip->last_cmd); +- spin_lock_irq(&chip->reg_lock); +- chip->rirb.cmds = 0; /* reset the index */ +- bus->rirb_error = 1; +- spin_unlock_irq(&chip->reg_lock); ++ snd_printk(KERN_ERR "hda_intel: azx_get_response timeout, " ++ "switching to single_cmd mode: last cmd=0x%08x\n", ++ chip->last_cmd); ++ chip->rirb.rp = azx_readb(chip, RIRBWP); ++ chip->rirb.cmds = 0; ++ /* switch to single_cmd mode */ ++ chip->single_cmd = 1; ++ azx_free_cmd_io(chip); + return -1; } --/* -- * set up the SD for streaming -- */ --static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev) -+/* reset stream */ -+static void azx_stream_reset(struct azx *chip, struct azx_dev *azx_dev) - { - unsigned char val; - int timeout; - -- /* make sure the run bit is zero for SD */ -- azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) & -- ~SD_CTL_DMA_START); -- /* reset stream */ -+ azx_stream_clear(chip, azx_dev); -+ - azx_sd_writeb(azx_dev, SD_CTL, azx_sd_readb(azx_dev, SD_CTL) | - SD_CTL_STREAM_RESET); - udelay(3); -@@ -1150,6 +1155,17 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev) - --timeout) - ; - -+ /* reset first position - may not be synced with hw at this time */ -+ *azx_dev->posbuf = 0; -+} -+ -+/* -+ * set up the SD for streaming -+ */ -+static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev) -+{ -+ /* make sure the run bit is zero for SD */ -+ azx_stream_clear(chip, azx_dev); - /* program the stream_tag */ - azx_sd_writel(azx_dev, SD_CTL, - (azx_sd_readl(azx_dev, SD_CTL) & ~SD_CTL_STREAM_TAG_MASK)| -@@ -1187,6 +1203,28 @@ static int azx_setup_controller(struct azx *chip, struct azx_dev *azx_dev) +@@ -1213,6 +1222,8 @@ static int probe_codec(struct azx *chip, int addr) return 0; } -+/* -+ * Probe the given codec address -+ */ -+static int probe_codec(struct azx *chip, int addr) -+{ -+ unsigned int cmd = (addr << 28) | (AC_NODE_ROOT << 20) | -+ (AC_VERB_PARAMETERS << 8) | AC_PAR_VENDOR_ID; -+ unsigned int res; -+ -+ chip->probing = 1; -+ azx_send_cmd(chip->bus, cmd); -+ res = azx_get_response(chip->bus); -+ chip->probing = 0; -+ if (res == -1) -+ return -EIO; -+ snd_printdd("hda_intel: codec #%d probed OK\n", addr); -+ return 0; -+} -+ +static int azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec, + struct hda_pcm *cpcm); -+static void azx_stop_chip(struct azx *chip); + static void azx_stop_chip(struct azx *chip); /* - * Codec initialization -@@ -1197,21 +1235,12 @@ static unsigned int azx_max_codecs[AZX_NUM_DRIVERS] __devinitdata = { +@@ -1224,7 +1235,8 @@ 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) +-static int __devinit azx_codec_create(struct azx *chip, const char *model) ++static int __devinit azx_codec_create(struct azx *chip, const char *model, + int no_init) { struct hda_bus_template bus_temp; -- int c, codecs, audio_codecs, err; -- int def_slots, max_slots; -+ int c, codecs, err; -+ int max_slots; - - memset(&bus_temp, 0, sizeof(bus_temp)); - bus_temp.private_data = chip; -@@ -1219,7 +1248,9 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model, + int c, codecs, err; +@@ -1236,7 +1248,9 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model) bus_temp.pci = chip->pci; bus_temp.ops.command = azx_send_cmd; bus_temp.ops.get_response = azx_get_response; @@ -4585,199 +3399,16 @@ index d9d2943..d1c03f9 100644 bus_temp.ops.pm_notify = azx_power_notify; #endif -@@ -1230,33 +1261,43 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model, - if (chip->driver_type == AZX_DRIVER_NVIDIA) - chip->bus->needs_damn_long_delay = 1; - -- codecs = audio_codecs = 0; -+ codecs = 0; - 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) { -+ -+ /* First try to probe all given codec slots */ -+ for (c = 0; c < max_slots; c++) { -+ if ((chip->codec_mask & (1 << c)) & chip->codec_probe_mask) { -+ if (probe_codec(chip, c) < 0) { -+ /* Some BIOSen give you wrong codec addresses -+ * that don't exist -+ */ -+ snd_printk(KERN_WARNING -+ "hda_intel: Codec #%d probe error; " -+ "disabling it...\n", c); -+ chip->codec_mask &= ~(1 << c); -+ /* More badly, accessing to a non-existing -+ * codec often screws up the controller chip, -+ * and distrubs the further communications. -+ * Thus if an error occurs during probing, -+ * better to reset the controller chip to -+ * get back to the sanity state. -+ */ -+ azx_stop_chip(chip); -+ azx_init_chip(chip); -+ } -+ } -+ } -+ -+ /* Then create codec instances */ -+ for (c = 0; c < max_slots; c++) { -+ if ((chip->codec_mask & (1 << c)) & chip->codec_probe_mask) { +@@ -1280,7 +1294,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model) + for (c = 0; c < max_slots; c++) { + if ((chip->codec_mask & (1 << c)) & chip->codec_probe_mask) { struct hda_codec *codec; - err = snd_hda_codec_new(chip->bus, c, &codec); + err = snd_hda_codec_new(chip->bus, c, !no_init, &codec); if (err < 0) continue; codecs++; -- if (codec->afg) -- audio_codecs++; -- } -- } -- if (!audio_codecs) { -- /* probe additional slots if no codec is found */ -- 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) -- continue; -- codecs++; -- } - } - } - if (!codecs) { -@@ -1369,6 +1410,7 @@ static int azx_pcm_open(struct snd_pcm_substream *substream) - runtime->private_data = azx_dev; - snd_pcm_set_sync(substream); - mutex_unlock(&chip->open_mutex); -+ - return 0; - } - -@@ -1395,6 +1437,11 @@ static int azx_pcm_close(struct snd_pcm_substream *substream) - static int azx_pcm_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params) - { -+ struct azx_dev *azx_dev = get_azx_dev(substream); -+ -+ azx_dev->bufsize = 0; -+ azx_dev->period_bytes = 0; -+ azx_dev->format_val = 0; - return snd_pcm_lib_malloc_pages(substream, - params_buffer_bytes(hw_params)); - } -@@ -1409,6 +1456,9 @@ static int azx_pcm_hw_free(struct snd_pcm_substream *substream) - azx_sd_writel(azx_dev, SD_BDLPL, 0); - azx_sd_writel(azx_dev, SD_BDLPU, 0); - azx_sd_writel(azx_dev, SD_CTL, 0); -+ azx_dev->bufsize = 0; -+ azx_dev->period_bytes = 0; -+ azx_dev->format_val = 0; - - hinfo->ops.cleanup(hinfo, apcm->codec, substream); - -@@ -1422,23 +1472,40 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream) - struct azx_dev *azx_dev = get_azx_dev(substream); - struct hda_pcm_stream *hinfo = apcm->hinfo[substream->stream]; - struct snd_pcm_runtime *runtime = substream->runtime; -+ unsigned int bufsize, period_bytes, format_val; -+ int err; - -- azx_dev->bufsize = snd_pcm_lib_buffer_bytes(substream); -- azx_dev->format_val = snd_hda_calc_stream_format(runtime->rate, -- runtime->channels, -- runtime->format, -- hinfo->maxbps); -- if (!azx_dev->format_val) { -+ azx_stream_reset(chip, azx_dev); -+ format_val = snd_hda_calc_stream_format(runtime->rate, -+ runtime->channels, -+ runtime->format, -+ hinfo->maxbps); -+ if (!format_val) { - snd_printk(KERN_ERR SFX - "invalid format_val, rate=%d, ch=%d, format=%d\n", - runtime->rate, runtime->channels, runtime->format); - return -EINVAL; - } - -+ bufsize = snd_pcm_lib_buffer_bytes(substream); -+ period_bytes = snd_pcm_lib_period_bytes(substream); -+ - snd_printdd("azx_pcm_prepare: bufsize=0x%x, format=0x%x\n", -- azx_dev->bufsize, azx_dev->format_val); -- if (azx_setup_periods(chip, substream, azx_dev) < 0) -- return -EINVAL; -+ bufsize, format_val); -+ -+ if (bufsize != azx_dev->bufsize || -+ period_bytes != azx_dev->period_bytes || -+ format_val != azx_dev->format_val) { -+ azx_dev->bufsize = bufsize; -+ azx_dev->period_bytes = period_bytes; -+ azx_dev->format_val = format_val; -+ err = azx_setup_periods(chip, substream, azx_dev); -+ if (err < 0) -+ return err; -+ } -+ -+ azx_dev->min_jiffies = (runtime->period_size * HZ) / -+ (runtime->rate * 2); - azx_setup_controller(chip, azx_dev); - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - azx_dev->fifo_size = azx_sd_readw(azx_dev, SD_FIFOSIZE) + 1; -@@ -1455,13 +1522,14 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) - struct azx *chip = apcm->chip; - struct azx_dev *azx_dev; - struct snd_pcm_substream *s; -- int start, nsync = 0, sbits = 0; -+ int rstart = 0, start, nsync = 0, sbits = 0; - int nwait, timeout; - - switch (cmd) { -+ case SNDRV_PCM_TRIGGER_START: -+ rstart = 1; - case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: - case SNDRV_PCM_TRIGGER_RESUME: -- case SNDRV_PCM_TRIGGER_START: - start = 1; - break; - case SNDRV_PCM_TRIGGER_PAUSE_PUSH: -@@ -1491,6 +1559,10 @@ static int azx_pcm_trigger(struct snd_pcm_substream *substream, int cmd) - if (s->pcm->card != substream->pcm->card) - continue; - azx_dev = get_azx_dev(s); -+ if (rstart) { -+ azx_dev->start_flag = 1; -+ azx_dev->start_jiffies = jiffies + azx_dev->min_jiffies; -+ } - if (start) - azx_stream_start(chip, azx_dev); - else -@@ -1640,6 +1712,11 @@ static int azx_position_ok(struct azx *chip, struct azx_dev *azx_dev) - { - unsigned int pos; - -+ if (azx_dev->start_flag && -+ time_before_eq(jiffies, azx_dev->start_jiffies)) -+ return -1; /* bogus (too early) interrupt */ -+ azx_dev->start_flag = 0; -+ - pos = azx_get_position(chip, azx_dev); - if (chip->position_fix == POS_FIX_AUTO) { - if (!pos) { -@@ -1708,7 +1785,6 @@ static void azx_clear_irq_pending(struct azx *chip) - for (i = 0; i < chip->num_streams; i++) - chip->azx_dev[i].irq_pending = 0; - spin_unlock_irq(&chip->reg_lock); -- flush_scheduled_work(); - } - - static struct snd_pcm_ops azx_pcm_ops = { -@@ -1725,110 +1801,59 @@ static struct snd_pcm_ops azx_pcm_ops = { +@@ -1787,110 +1801,59 @@ static struct snd_pcm_ops azx_pcm_ops = { static void azx_pcm_free(struct snd_pcm *pcm) { @@ -4922,24 +3553,7 @@ index d9d2943..d1c03f9 100644 return 0; } -@@ -1905,13 +1930,13 @@ static void azx_stop_chip(struct azx *chip) - - #ifdef CONFIG_SND_HDA_POWER_SAVE - /* power-up/down the controller */ --static void azx_power_notify(struct hda_codec *codec) -+static void azx_power_notify(struct hda_bus *bus) - { -- struct azx *chip = codec->bus->private_data; -+ struct azx *chip = bus->private_data; - struct hda_codec *c; - int power_on = 0; - -- list_for_each_entry(c, &codec->bus->codec_list, list) { -+ list_for_each_entry(c, &bus->codec_list, list) { - if (c->power_on) { - power_on = 1; - break; -@@ -1928,6 +1953,18 @@ static void azx_power_notify(struct hda_codec *codec) +@@ -1990,6 +1953,18 @@ static void azx_power_notify(struct hda_bus *bus) /* * power management */ @@ -4958,114 +3572,31 @@ index d9d2943..d1c03f9 100644 static int azx_suspend(struct pci_dev *pci, pm_message_t state) { struct snd_card *card = pci_get_drvdata(pci); -@@ -2065,26 +2102,31 @@ 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) { -+ switch (fix) { -+ case POS_FIX_LPIB: -+ case POS_FIX_POSBUF: -+ return fix; -+ } -+ -+ /* Check VIA/ATI HD Audio Controller exist */ -+ switch (chip->driver_type) { -+ case AZX_DRIVER_VIA: -+ case AZX_DRIVER_ATI: - 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) { -- printk(KERN_INFO -- "hda_intel: position_fix set to %d " -- "for device %04x:%04x\n", -- q->value, q->subvendor, q->subdevice); -- return q->value; -- } -+ q = snd_pci_quirk_lookup(chip->pci, position_fix_list); -+ if (q) { -+ printk(KERN_INFO -+ "hda_intel: position_fix set to %d " -+ "for device %04x:%04x\n", -+ q->value, q->subvendor, q->subdevice); -+ return q->value; - } -- return fix; -+ return POS_FIX_AUTO; - } - - /* -@@ -2099,23 +2141,39 @@ static struct snd_pci_quirk probe_mask_list[] __devinitdata = { - SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X/T/R61", 0x01), - /* broken BIOS */ - SND_PCI_QUIRK(0x1028, 0x20ac, "Dell Studio Desktop", 0x01), -+ /* including bogus ALC268 in slot#2 that conflicts with ALC888 */ -+ SND_PCI_QUIRK(0x17c0, 0x4085, "Medion MD96630", 0x01), -+ /* forced codec slots */ +@@ -2169,6 +2144,7 @@ static struct snd_pci_quirk probe_mask_list[] __devinitdata = { + /* including bogus ALC268 in slot#2 that conflicts with ALC888 */ + SND_PCI_QUIRK(0x17c0, 0x4085, "Medion MD96630", 0x01), + /* forced codec slots */ + SND_PCI_QUIRK(0x1043, 0x1262, "ASUS W5Fm", 0x103), -+ SND_PCI_QUIRK(0x1046, 0x1262, "ASUS W5F", 0x103), + SND_PCI_QUIRK(0x1046, 0x1262, "ASUS W5F", 0x103), {} }; +@@ -2299,11 +2275,11 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, + gcap &= ~0x01; -+#define AZX_FORCE_CODEC_MASK 0x100 -+ - static void __devinit check_probe_mask(struct azx *chip, int dev) - { - const struct snd_pci_quirk *q; - -- if (probe_mask[dev] == -1) { -+ chip->codec_probe_mask = probe_mask[dev]; -+ if (chip->codec_probe_mask == -1) { - q = snd_pci_quirk_lookup(chip->pci, probe_mask_list); - if (q) { - printk(KERN_INFO - "hda_intel: probe_mask set to 0x%x " - "for device %04x:%04x\n", - q->value, q->subvendor, q->subdevice); -- probe_mask[dev] = q->value; -+ chip->codec_probe_mask = q->value; - } - } -+ -+ /* check forced option */ -+ if (chip->codec_probe_mask != -1 && -+ (chip->codec_probe_mask & AZX_FORCE_CODEC_MASK)) { -+ chip->codec_mask = chip->codec_probe_mask & 0xff; -+ printk(KERN_INFO "hda_intel: codec_mask forced to 0x%x\n", -+ chip->codec_mask); -+ } - } - - -@@ -2212,9 +2270,17 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, - gcap = azx_readw(chip, GCAP); - snd_printdd("chipset global capabilities = 0x%x\n", gcap); - -+ /* ATI chips seems buggy about 64bit DMA addresses */ -+ if (chip->driver_type == AZX_DRIVER_ATI) -+ gcap &= ~0x01; -+ /* allow 64bit DMA address if supported by H/W */ - if ((gcap & 0x01) && !pci_set_dma_mask(pci, DMA_64BIT_MASK)) - pci_set_consistent_dma_mask(pci, DMA_64BIT_MASK); + if ((gcap & 0x01) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64))) + pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(64)); -+ else { + else { +- pci_set_dma_mask(pci, DMA_32BIT_MASK); +- pci_set_consistent_dma_mask(pci, DMA_32BIT_MASK); + pci_set_dma_mask(pci, DMA_BIT_MASK(32)); + pci_set_consistent_dma_mask(pci, DMA_BIT_MASK(32)); -+ } + } /* read number of streams from GCAP register instead of using - * hardcoded value -@@ -2233,6 +2299,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, +@@ -2323,6 +2299,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, chip->playback_streams = ATIHDMI_NUM_PLAYBACK; chip->capture_streams = ATIHDMI_NUM_CAPTURE; break; @@ -5073,70 +3604,22 @@ index d9d2943..d1c03f9 100644 default: chip->playback_streams = ICH6_NUM_PLAYBACK; chip->capture_streams = ICH6_NUM_CAPTURE; -@@ -2342,40 +2409,30 @@ static int __devinit azx_probe(struct pci_dev *pci, - } - - err = azx_create(card, pci, dev, pci_id->driver_data, &chip); -- if (err < 0) { -- snd_card_free(card); -- return err; -- } -+ if (err < 0) -+ goto out_free; +@@ -2437,12 +2414,12 @@ static int __devinit azx_probe(struct pci_dev *pci, card->private_data = chip; /* create codec instances */ -- err = azx_codec_create(chip, model[dev], probe_mask[dev]); -- if (err < 0) { -- snd_card_free(card); -- return err; -- } +- err = azx_codec_create(chip, model[dev]); + err = azx_codec_create(chip, model[dev], probe_only[dev]); -+ if (err < 0) -+ goto out_free; + if (err < 0) + goto out_free; /* create PCM streams */ - err = azx_pcm_create(chip); -- if (err < 0) { -- snd_card_free(card); -- return err; -- } + err = snd_hda_build_pcms(chip->bus); -+ if (err < 0) -+ goto out_free; - - /* create mixer controls */ - err = azx_mixer_create(chip); -- if (err < 0) { -- snd_card_free(card); -- return err; -- } -+ if (err < 0) -+ goto out_free; - - snd_card_set_dev(card, &pci->dev); - - err = snd_card_register(card); -- if (err < 0) { -- snd_card_free(card); -- return err; -- } -+ if (err < 0) -+ goto out_free; - - pci_set_drvdata(pci, card); - chip->running = 1; -@@ -2384,6 +2441,9 @@ static int __devinit azx_probe(struct pci_dev *pci, - - dev++; - return err; -+out_free: -+ snd_card_free(card); -+ return err; - } + if (err < 0) + goto out_free; - static void __devexit azx_remove(struct pci_dev *pci) -@@ -2451,12 +2511,17 @@ static struct pci_device_id azx_ids[] = { +@@ -2534,12 +2511,17 @@ static struct pci_device_id azx_ids[] = { { PCI_DEVICE(0x10de, 0x0ac1), .driver_data = AZX_DRIVER_NVIDIA }, { PCI_DEVICE(0x10de, 0x0ac2), .driver_data = AZX_DRIVER_NVIDIA }, { PCI_DEVICE(0x10de, 0x0ac3), .driver_data = AZX_DRIVER_NVIDIA }, @@ -5362,34 +3845,6 @@ index 3018b76..8334901 100644 +void snd_print_channel_allocation(int spk_alloc, char *buf, int buflen); + #endif /* __SOUND_HDA_LOCAL_H */ -diff --git a/sound/pci/hda/hda_patch.h b/sound/pci/hda/hda_patch.h -deleted file mode 100644 -index dfbcfa8..0000000 ---- a/sound/pci/hda/hda_patch.h -+++ /dev/null -@@ -1,22 +0,0 @@ --/* -- * HDA Patches - included by hda_codec.c -- */ -- --/* Realtek codecs */ --extern struct hda_codec_preset snd_hda_preset_realtek[]; --/* C-Media codecs */ --extern struct hda_codec_preset snd_hda_preset_cmedia[]; --/* Analog Devices codecs */ --extern struct hda_codec_preset snd_hda_preset_analog[]; --/* SigmaTel codecs */ --extern struct hda_codec_preset snd_hda_preset_sigmatel[]; --/* SiLabs 3054/3055 modem codecs */ --extern struct hda_codec_preset snd_hda_preset_si3054[]; --/* ATI HDMI codecs */ --extern struct hda_codec_preset snd_hda_preset_atihdmi[]; --/* Conexant audio codec */ --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/hda_proc.c b/sound/pci/hda/hda_proc.c index 0890528..93d7499 100644 --- a/sound/pci/hda/hda_proc.c @@ -5608,7 +4063,7 @@ index 0890528..93d7499 100644 snd_hda_power_down(codec); } diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c -index 10fe100..84cc49c 100644 +index d26f31c..84cc49c 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -27,12 +27,12 @@ @@ -6097,13 +4552,11 @@ index 10fe100..84cc49c 100644 /* Analog mixer; mute as default */ {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, -@@ -3233,8 +3256,8 @@ static const char *ad1884_slave_vols[] = { - "Mic Playback Volume", +@@ -3234,7 +3257,7 @@ static const char *ad1884_slave_vols[] = { "CD Playback Volume", "Internal Mic Playback Volume", -- "Docking Mic Playback Volume" + "Docking Mic Playback Volume", - "Beep Playback Volume", -+ "Docking Mic Playback Volume", + /* "Beep Playback Volume", */ "IEC958 Playback Volume", NULL @@ -6208,57 +4661,7 @@ index 10fe100..84cc49c 100644 HDA_CODEC_VOLUME("Mic Capture Volume", 0x14, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x15, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), -@@ -3798,6 +3817,49 @@ static struct hda_verb ad1884a_laptop_verbs[] = { - { } /* end */ - }; - -+static struct hda_verb ad1884a_mobile_verbs[] = { -+ /* DACs; unmute as default */ -+ {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ -+ {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ -+ /* Port-A (HP) mixer - route only from analog mixer */ -+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, -+ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, -+ /* Port-A pin */ -+ {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, -+ /* Port-A (HP) pin - always unmuted */ -+ {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, -+ /* Port-B (mic jack) pin */ -+ {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, -+ {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */ -+ /* Port-C (int mic) pin */ -+ {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, -+ {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */ -+ /* Port-F (int speaker) mixer - route only from analog mixer */ -+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, -+ {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, -+ /* Port-F pin */ -+ {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, -+ {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, -+ /* Analog mixer; mute as default */ -+ {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, -+ {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, -+ {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, -+ {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, -+ {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, -+ {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, -+ /* Analog Mix output amp */ -+ {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, -+ /* capture sources */ -+ /* {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, */ /* set via unsol */ -+ {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, -+ {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0}, -+ {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, -+ /* unsolicited event for pin-sense */ -+ {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT}, -+ {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT}, -+ { } /* end */ -+}; -+ - /* - * Thinkpad X300 - * 0x11 - HP -@@ -3830,8 +3892,6 @@ static struct snd_kcontrol_new ad1984a_thinkpad_mixers[] = { +@@ -3873,8 +3892,6 @@ static struct snd_kcontrol_new ad1984a_thinkpad_mixers[] = { HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT), @@ -6267,27 +4670,32 @@ index 10fe100..84cc49c 100644 HDA_CODEC_VOLUME("Mic Boost", 0x14, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Internal Mic Boost", 0x17, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), -@@ -3905,16 +3965,9 @@ static struct snd_pci_quirk ad1884a_cfg_tbl[] = { +@@ -3948,21 +3965,9 @@ static struct snd_pci_quirk ad1884a_cfg_tbl[] = { SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE), SND_PCI_QUIRK(0x103c, 0x3037, "HP 2230s", AD1884A_LAPTOP), SND_PCI_QUIRK(0x103c, 0x3056, "HP", AD1884A_MOBILE), - SND_PCI_QUIRK(0x103c, 0x3072, "HP", AD1884A_MOBILE), - SND_PCI_QUIRK(0x103c, 0x3073, "HP", AD1884A_MOBILE), +- SND_PCI_QUIRK(0x103c, 0x3074, "HP", AD1884A_MOBILE), +- SND_PCI_QUIRK(0x103c, 0x3075, "HP", AD1884A_MOBILE), - SND_PCI_QUIRK(0x103c, 0x3076, "HP", AD1884A_MOBILE), - SND_PCI_QUIRK(0x103c, 0x3077, "HP", AD1884A_MOBILE), +- SND_PCI_QUIRK(0x103c, 0x3078, "HP", AD1884A_MOBILE), - SND_PCI_QUIRK(0x103c, 0x3079, "HP", AD1884A_MOBILE), - SND_PCI_QUIRK(0x103c, 0x307a, "HP", AD1884A_MOBILE), +- SND_PCI_QUIRK(0x103c, 0x30e1, "HP 2530p", AD1884A_LAPTOP), - SND_PCI_QUIRK(0x103c, 0x30e6, "HP 6730b", AD1884A_LAPTOP), - SND_PCI_QUIRK(0x103c, 0x30e7, "HP EliteBook 8530p", AD1884A_LAPTOP), -- SND_PCI_QUIRK(0x103c, 0x30db, "HP EliteBook 6930p", AD1884A_LAPTOP), +- SND_PCI_QUIRK(0x103c, 0x360d, "HP 6530b", AD1884A_LAPTOP), - SND_PCI_QUIRK(0x103c, 0x3614, "HP 6730s", AD1884A_LAPTOP), +- SND_PCI_QUIRK(0x103c, 0x3632, "HP", AD1884A_MOBILE), + SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x3070, "HP", AD1884A_MOBILE), + SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x30e0, "HP laptop", AD1884A_LAPTOP), + SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3600, "HP laptop", AD1884A_LAPTOP), SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X300", AD1884A_THINKPAD), {} }; -@@ -3922,7 +3975,7 @@ static struct snd_pci_quirk ad1884a_cfg_tbl[] = { +@@ -3970,7 +3975,7 @@ static struct snd_pci_quirk ad1884a_cfg_tbl[] = { static int patch_ad1884a(struct hda_codec *codec) { struct ad198x_spec *spec; @@ -6296,7 +4704,7 @@ index 10fe100..84cc49c 100644 spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (spec == NULL) -@@ -3930,6 +3983,13 @@ static int patch_ad1884a(struct hda_codec *codec) +@@ -3978,6 +3983,13 @@ static int patch_ad1884a(struct hda_codec *codec) codec->spec = spec; @@ -6310,27 +4718,7 @@ index 10fe100..84cc49c 100644 spec->multiout.max_channels = 2; spec->multiout.num_dacs = ARRAY_SIZE(ad1884a_dac_nids); spec->multiout.dac_nids = ad1884a_dac_nids; -@@ -3971,10 +4031,18 @@ static int patch_ad1884a(struct hda_codec *codec) - break; - case AD1884A_MOBILE: - spec->mixers[0] = ad1884a_mobile_mixers; -- spec->init_verbs[spec->num_init_verbs++] = ad1884a_laptop_verbs; -+ spec->init_verbs[0] = ad1884a_mobile_verbs; - spec->multiout.dig_out_nid = 0; - codec->patch_ops.unsol_event = ad1884a_hp_unsol_event; - codec->patch_ops.init = ad1884a_hp_init; -+ /* set the upper-limit for mixer amp to 0dB for avoiding the -+ * possible damage by overloading -+ */ -+ snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT, -+ (0x17 << AC_AMPCAP_OFFSET_SHIFT) | -+ (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) | -+ (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) | -+ (1 << AC_AMPCAP_MUTE_SHIFT)); - break; - case AD1884A_THINKPAD: - spec->mixers[0] = ad1984a_thinkpad_mixers; -@@ -4092,8 +4160,6 @@ static struct snd_kcontrol_new ad1882_loopback_mixers[] = { +@@ -4148,8 +4160,6 @@ static struct snd_kcontrol_new ad1882_loopback_mixers[] = { 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), @@ -6339,7 +4727,7 @@ index 10fe100..84cc49c 100644 { } /* end */ }; -@@ -4106,8 +4172,6 @@ static struct snd_kcontrol_new ad1882a_loopback_mixers[] = { +@@ -4162,8 +4172,6 @@ static struct snd_kcontrol_new ad1882a_loopback_mixers[] = { 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), @@ -6348,7 +4736,7 @@ index 10fe100..84cc49c 100644 HDA_CODEC_VOLUME("Digital Mic Boost", 0x1f, 0x0, HDA_INPUT), { } /* end */ }; -@@ -4266,7 +4330,7 @@ static const char *ad1882_models[AD1986A_MODELS] = { +@@ -4322,7 +4330,7 @@ static const char *ad1882_models[AD1986A_MODELS] = { static int patch_ad1882(struct hda_codec *codec) { struct ad198x_spec *spec; @@ -6357,7 +4745,7 @@ index 10fe100..84cc49c 100644 spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (spec == NULL) -@@ -4274,6 +4338,13 @@ static int patch_ad1882(struct hda_codec *codec) +@@ -4330,6 +4338,13 @@ static int patch_ad1882(struct hda_codec *codec) codec->spec = spec; @@ -6371,7 +4759,7 @@ index 10fe100..84cc49c 100644 spec->multiout.max_channels = 6; spec->multiout.num_dacs = 3; spec->multiout.dac_nids = ad1882_dac_nids; -@@ -4327,7 +4398,7 @@ static int patch_ad1882(struct hda_codec *codec) +@@ -4383,7 +4398,7 @@ static int patch_ad1882(struct hda_codec *codec) /* * patch entries */ @@ -6380,7 +4768,7 @@ index 10fe100..84cc49c 100644 { .id = 0x11d4184a, .name = "AD1884A", .patch = patch_ad1884a }, { .id = 0x11d41882, .name = "AD1882", .patch = patch_ad1882 }, { .id = 0x11d41883, .name = "AD1883", .patch = patch_ad1884a }, -@@ -4345,3 +4416,26 @@ struct hda_codec_preset snd_hda_preset_analog[] = { +@@ -4401,3 +4416,26 @@ struct hda_codec_preset snd_hda_preset_analog[] = { { .id = 0x11d4989b, .name = "AD1989B", .patch = patch_ad1988 }, {} /* terminator */ }; @@ -6542,7 +4930,7 @@ index 6ef57fb..c921264 100644 +module_init(patch_cmedia_init) +module_exit(patch_cmedia_exit) diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c -index a50089f..4fcbe21 100644 +index 5139c8c..4fcbe21 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -25,9 +25,10 @@ @@ -6562,12 +4950,12 @@ index a50089f..4fcbe21 100644 #define CONEXANT_MIC_EVENT 0x38 +/* Conexant 5051 specific */ - ++ +#define CXT5051_SPDIF_OUT 0x1C +#define CXT5051_PORTB_EVENT 0x38 +#define CXT5051_PORTC_EVENT 0x39 + -+ + +struct conexant_jack { + + hda_nid_t nid; @@ -6584,15 +4972,7 @@ index a50089f..4fcbe21 100644 const struct hda_verb *init_verbs[5]; /* initialization verbs * don't forget NULL -@@ -58,6 +73,7 @@ struct conexant_spec { - */ - unsigned int cur_eapd; - unsigned int hp_present; -+ unsigned int no_auto_mic; - unsigned int need_dac_fix; - - /* capture */ -@@ -84,10 +100,11 @@ struct conexant_spec { +@@ -85,10 +100,11 @@ struct conexant_spec { unsigned int spdif_route; @@ -6606,7 +4986,7 @@ index a50089f..4fcbe21 100644 struct hda_input_mux private_imux; hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; -@@ -332,6 +349,108 @@ static int conexant_mux_enum_put(struct snd_kcontrol *kcontrol, +@@ -333,6 +349,108 @@ static int conexant_mux_enum_put(struct snd_kcontrol *kcontrol, &spec->cur_mux[adc_idx]); } @@ -6715,7 +5095,7 @@ index a50089f..4fcbe21 100644 static int conexant_init(struct hda_codec *codec) { struct conexant_spec *spec = codec->spec; -@@ -344,18 +463,44 @@ static int conexant_init(struct hda_codec *codec) +@@ -345,18 +463,44 @@ static int conexant_init(struct hda_codec *codec) static void conexant_free(struct hda_codec *codec) { @@ -6769,7 +5149,7 @@ index a50089f..4fcbe21 100644 static int conexant_build_controls(struct hda_codec *codec) { struct conexant_spec *spec = codec->spec; -@@ -383,6 +528,32 @@ static int conexant_build_controls(struct hda_codec *codec) +@@ -384,6 +528,32 @@ static int conexant_build_controls(struct hda_codec *codec) if (err < 0) return err; } @@ -6802,7 +5182,7 @@ index a50089f..4fcbe21 100644 return 0; } -@@ -614,13 +785,6 @@ static void cxt5045_hp_unsol_event(struct hda_codec *codec, +@@ -615,13 +785,6 @@ static void cxt5045_hp_unsol_event(struct hda_codec *codec, } static struct snd_kcontrol_new cxt5045_mixers[] = { @@ -6816,7 +5196,7 @@ index a50089f..4fcbe21 100644 HDA_CODEC_VOLUME("Int Mic Capture Volume", 0x1a, 0x01, HDA_INPUT), HDA_CODEC_MUTE("Int Mic Capture Switch", 0x1a, 0x01, HDA_INPUT), HDA_CODEC_VOLUME("Ext Mic Capture Volume", 0x1a, 0x02, HDA_INPUT), -@@ -654,13 +818,6 @@ static struct snd_kcontrol_new cxt5045_benq_mixers[] = { +@@ -655,13 +818,6 @@ static struct snd_kcontrol_new cxt5045_benq_mixers[] = { }; static struct snd_kcontrol_new cxt5045_mixers_hp530[] = { @@ -6830,7 +5210,7 @@ index a50089f..4fcbe21 100644 HDA_CODEC_VOLUME("Int Mic Capture Volume", 0x1a, 0x02, HDA_INPUT), HDA_CODEC_MUTE("Int Mic Capture Switch", 0x1a, 0x02, HDA_INPUT), HDA_CODEC_VOLUME("Ext Mic Capture Volume", 0x1a, 0x01, HDA_INPUT), -@@ -897,15 +1054,9 @@ static const char *cxt5045_models[CXT5045_MODELS] = { +@@ -898,15 +1054,9 @@ static const char *cxt5045_models[CXT5045_MODELS] = { }; static struct snd_pci_quirk cxt5045_cfg_tbl[] = { @@ -6848,7 +5228,7 @@ index a50089f..4fcbe21 100644 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P105", CXT5045_LAPTOP_MICSENSE), SND_PCI_QUIRK(0x152d, 0x0753, "Benq R55E", CXT5045_BENQ), SND_PCI_QUIRK(0x1734, 0x10ad, "Fujitsu Si1520", CXT5045_LAPTOP_MICSENSE), -@@ -915,8 +1066,8 @@ static struct snd_pci_quirk cxt5045_cfg_tbl[] = { +@@ -916,8 +1066,8 @@ static struct snd_pci_quirk cxt5045_cfg_tbl[] = { SND_PCI_QUIRK(0x1509, 0x1e40, "FIC", CXT5045_LAPTOP_HPMICSENSE), SND_PCI_QUIRK(0x1509, 0x2f05, "FIC", CXT5045_LAPTOP_HPMICSENSE), SND_PCI_QUIRK(0x1509, 0x2f06, "FIC", CXT5045_LAPTOP_HPMICSENSE), @@ -6859,7 +5239,7 @@ index a50089f..4fcbe21 100644 SND_PCI_QUIRK(0x8086, 0x2111, "Conexant Reference board", CXT5045_LAPTOP_HPSENSE), {} }; -@@ -930,6 +1081,7 @@ static int patch_cxt5045(struct hda_codec *codec) +@@ -931,6 +1081,7 @@ static int patch_cxt5045(struct hda_codec *codec) if (!spec) return -ENOMEM; codec->spec = spec; @@ -6867,7 +5247,7 @@ index a50089f..4fcbe21 100644 spec->multiout.max_channels = 2; spec->multiout.num_dacs = ARRAY_SIZE(cxt5045_dac_nids); -@@ -1029,7 +1181,7 @@ static int patch_cxt5045(struct hda_codec *codec) +@@ -1030,7 +1181,7 @@ static int patch_cxt5045(struct hda_codec *codec) /* Conexant 5047 specific */ #define CXT5047_SPDIF_OUT 0x11 @@ -6876,7 +5256,7 @@ index a50089f..4fcbe21 100644 static hda_nid_t cxt5047_adc_nids[1] = { 0x12 }; static hda_nid_t cxt5047_capsrc_nids[1] = { 0x1a }; -@@ -1037,20 +1189,6 @@ static struct hda_channel_mode cxt5047_modes[1] = { +@@ -1038,20 +1189,6 @@ static struct hda_channel_mode cxt5047_modes[1] = { { 2, NULL }, }; @@ -6897,7 +5277,7 @@ index a50089f..4fcbe21 100644 static struct hda_input_mux cxt5047_toshiba_capture_source = { .num_items = 2, .items = { -@@ -1074,7 +1212,11 @@ static int cxt5047_hp_master_sw_put(struct snd_kcontrol *kcontrol, +@@ -1075,7 +1212,11 @@ static int cxt5047_hp_master_sw_put(struct snd_kcontrol *kcontrol, * the headphone jack */ bits = (!spec->hp_present && spec->cur_eapd) ? 0 : HDA_AMP_MUTE; @@ -6910,7 +5290,7 @@ index a50089f..4fcbe21 100644 HDA_AMP_MUTE, bits); bits = spec->cur_eapd ? 0 : HDA_AMP_MUTE; snd_hda_codec_amp_stereo(codec, 0x13, HDA_OUTPUT, 0, -@@ -1082,16 +1224,6 @@ static int cxt5047_hp_master_sw_put(struct snd_kcontrol *kcontrol, +@@ -1083,16 +1224,6 @@ static int cxt5047_hp_master_sw_put(struct snd_kcontrol *kcontrol, return 1; } @@ -6927,7 +5307,7 @@ index a50089f..4fcbe21 100644 /* mute internal speaker if HP is plugged */ static void cxt5047_hp_automute(struct hda_codec *codec) { -@@ -1102,27 +1234,8 @@ static void cxt5047_hp_automute(struct hda_codec *codec) +@@ -1103,27 +1234,8 @@ static void cxt5047_hp_automute(struct hda_codec *codec) AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; bits = (spec->hp_present || !spec->cur_eapd) ? HDA_AMP_MUTE : 0; @@ -6957,7 +5337,7 @@ index a50089f..4fcbe21 100644 HDA_AMP_MUTE, bits); } -@@ -1163,55 +1276,14 @@ static void cxt5047_hp_unsol_event(struct hda_codec *codec, +@@ -1164,55 +1276,14 @@ static void cxt5047_hp_unsol_event(struct hda_codec *codec, } } @@ -7017,7 +5397,7 @@ index a50089f..4fcbe21 100644 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", -@@ -1224,29 +1296,15 @@ static struct snd_kcontrol_new cxt5047_toshiba_mixers[] = { +@@ -1225,29 +1296,15 @@ static struct snd_kcontrol_new cxt5047_toshiba_mixers[] = { {} }; @@ -7055,7 +5435,7 @@ index a50089f..4fcbe21 100644 { } /* end */ }; -@@ -1257,8 +1315,8 @@ static struct hda_verb cxt5047_init_verbs[] = { +@@ -1258,8 +1315,8 @@ static struct hda_verb cxt5047_init_verbs[] = { {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 }, /* HP, Speaker */ {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, @@ -7066,7 +5446,7 @@ index a50089f..4fcbe21 100644 /* Record selector: Mic */ {0x12, AC_VERB_SET_CONNECT_SEL,0x03}, {0x19, AC_VERB_SET_AMP_GAIN_MUTE, -@@ -1278,30 +1336,7 @@ static struct hda_verb cxt5047_init_verbs[] = { +@@ -1279,30 +1336,7 @@ static struct hda_verb cxt5047_init_verbs[] = { /* configuration for Toshiba Laptops */ static struct hda_verb cxt5047_toshiba_init_verbs[] = { @@ -7098,7 +5478,7 @@ index a50089f..4fcbe21 100644 {} }; -@@ -1466,11 +1501,9 @@ static const char *cxt5047_models[CXT5047_MODELS] = { +@@ -1467,11 +1501,9 @@ static const char *cxt5047_models[CXT5047_MODELS] = { }; static struct snd_pci_quirk cxt5047_cfg_tbl[] = { @@ -7112,7 +5492,7 @@ index a50089f..4fcbe21 100644 SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba P100", CXT5047_LAPTOP_EAPD), {} }; -@@ -1484,6 +1517,7 @@ static int patch_cxt5047(struct hda_codec *codec) +@@ -1485,6 +1517,7 @@ static int patch_cxt5047(struct hda_codec *codec) if (!spec) return -ENOMEM; codec->spec = spec; @@ -7120,7 +5500,7 @@ index a50089f..4fcbe21 100644 spec->multiout.max_channels = 2; spec->multiout.num_dacs = ARRAY_SIZE(cxt5047_dac_nids); -@@ -1492,9 +1526,8 @@ static int patch_cxt5047(struct hda_codec *codec) +@@ -1493,9 +1526,8 @@ static int patch_cxt5047(struct hda_codec *codec) spec->num_adc_nids = 1; spec->adc_nids = cxt5047_adc_nids; spec->capsrc_nids = cxt5047_capsrc_nids; @@ -7131,7 +5511,7 @@ index a50089f..4fcbe21 100644 spec->num_init_verbs = 1; spec->init_verbs[0] = cxt5047_init_verbs; spec->spdif_route = 0; -@@ -1508,21 +1541,22 @@ static int patch_cxt5047(struct hda_codec *codec) +@@ -1509,21 +1541,22 @@ static int patch_cxt5047(struct hda_codec *codec) cxt5047_cfg_tbl); switch (board_config) { case CXT5047_LAPTOP: @@ -7160,7 +5540,7 @@ index a50089f..4fcbe21 100644 codec->patch_ops.unsol_event = cxt5047_hp_unsol_event; break; #ifdef CONFIG_SND_DEBUG -@@ -1533,15 +1567,13 @@ static int patch_cxt5047(struct hda_codec *codec) +@@ -1534,15 +1567,13 @@ static int patch_cxt5047(struct hda_codec *codec) codec->patch_ops.unsol_event = cxt5047_hp_unsol_event; #endif } @@ -7177,28 +5557,7 @@ index a50089f..4fcbe21 100644 static struct hda_channel_mode cxt5051_modes[1] = { { 2, NULL }, -@@ -1571,8 +1603,11 @@ static int cxt5051_hp_master_sw_put(struct snd_kcontrol *kcontrol, - /* toggle input of built-in and mic jack appropriately */ - static void cxt5051_portb_automic(struct hda_codec *codec) - { -+ struct conexant_spec *spec = codec->spec; - unsigned int present; - -+ if (spec->no_auto_mic) -+ return; - present = snd_hda_codec_read(codec, 0x17, 0, - AC_VERB_GET_PIN_SENSE, 0) & - AC_PINSENSE_PRESENCE; -@@ -1588,6 +1623,8 @@ static void cxt5051_portc_automic(struct hda_codec *codec) - unsigned int present; - hda_nid_t new_adc; - -+ if (spec->no_auto_mic) -+ return; - present = snd_hda_codec_read(codec, 0x18, 0, - AC_VERB_GET_PIN_SENSE, 0) & - AC_PINSENSE_PRESENCE; -@@ -1621,6 +1658,7 @@ static void cxt5051_hp_automute(struct hda_codec *codec) +@@ -1627,6 +1658,7 @@ static void cxt5051_hp_automute(struct hda_codec *codec) static void cxt5051_hp_unsol_event(struct hda_codec *codec, unsigned int res) { @@ -7206,7 +5565,7 @@ index a50089f..4fcbe21 100644 switch (res >> 26) { case CONEXANT_HP_EVENT: cxt5051_hp_automute(codec); -@@ -1632,6 +1670,7 @@ static void cxt5051_hp_unsol_event(struct hda_codec *codec, +@@ -1638,6 +1670,7 @@ static void cxt5051_hp_unsol_event(struct hda_codec *codec, cxt5051_portc_automic(codec); break; } @@ -7214,94 +5573,7 @@ index a50089f..4fcbe21 100644 } static struct snd_kcontrol_new cxt5051_mixers[] = { -@@ -1672,6 +1711,22 @@ static struct snd_kcontrol_new cxt5051_hp_mixers[] = { - {} - }; - -+static struct snd_kcontrol_new cxt5051_hp_dv6736_mixers[] = { -+ HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x00, HDA_INPUT), -+ HDA_CODEC_MUTE("Mic Switch", 0x14, 0x00, HDA_INPUT), -+ HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT), -+ { -+ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, -+ .name = "Master Playback Switch", -+ .info = cxt_eapd_info, -+ .get = cxt_eapd_get, -+ .put = cxt5051_hp_master_sw_put, -+ .private_value = 0x1a, -+ }, -+ -+ {} -+}; -+ - static struct hda_verb cxt5051_init_verbs[] = { - /* Line in, Mic */ - {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, -@@ -1702,10 +1757,71 @@ static struct hda_verb cxt5051_init_verbs[] = { - { } /* end */ - }; - -+static struct hda_verb cxt5051_hp_dv6736_init_verbs[] = { -+ /* Line in, Mic */ -+ {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, -+ {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, -+ {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0}, -+ {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0}, -+ /* SPK */ -+ {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, -+ {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, -+ /* HP, Amp */ -+ {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, -+ {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, -+ /* DAC1 */ -+ {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, -+ /* Record selector: Int mic */ -+ {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44}, -+ {0x14, AC_VERB_SET_CONNECT_SEL, 0x1}, -+ /* SPDIF route: PCM */ -+ {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0}, -+ /* EAPD */ -+ {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ -+ {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT}, -+ {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTB_EVENT}, -+ { } /* end */ -+}; -+ -+static struct hda_verb cxt5051_lenovo_x200_init_verbs[] = { -+ /* Line in, Mic */ -+ {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, -+ {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, -+ {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, -+ {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, -+ {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, -+ {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, -+ /* SPK */ -+ {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, -+ {0x1a, AC_VERB_SET_CONNECT_SEL, 0x00}, -+ /* HP, Amp */ -+ {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, -+ {0x16, AC_VERB_SET_CONNECT_SEL, 0x00}, -+ /* Docking HP */ -+ {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, -+ {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, -+ /* DAC1 */ -+ {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, -+ /* Record selector: Int mic */ -+ {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44}, -+ {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1) | 0x44}, -+ {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x44}, -+ /* SPDIF route: PCM */ -+ {0x1c, AC_VERB_SET_CONNECT_SEL, 0x0}, -+ /* EAPD */ -+ {0x1a, AC_VERB_SET_EAPD_BTLENABLE, 0x2}, /* default on */ -+ {0x16, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT}, -+ {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTB_EVENT}, -+ {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CXT5051_PORTC_EVENT}, -+ {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|CONEXANT_HP_EVENT}, -+ { } /* end */ -+}; -+ - /* initialize jack-sensing, too */ +@@ -1788,6 +1821,7 @@ static struct hda_verb cxt5051_lenovo_x200_init_verbs[] = { static int cxt5051_init(struct hda_codec *codec) { conexant_init(codec); @@ -7309,33 +5581,15 @@ index a50089f..4fcbe21 100644 if (codec->patch_ops.unsol_event) { cxt5051_hp_automute(codec); cxt5051_portb_automic(codec); -@@ -1718,18 +1834,25 @@ static int cxt5051_init(struct hda_codec *codec) - enum { - CXT5051_LAPTOP, /* Laptops w/ EAPD support */ - CXT5051_HP, /* no docking */ -+ CXT5051_HP_DV6736, /* HP without mic switch */ -+ CXT5051_LENOVO_X200, /* Lenovo X200 laptop */ - CXT5051_MODELS - }; - - static const char *cxt5051_models[CXT5051_MODELS] = { - [CXT5051_LAPTOP] = "laptop", - [CXT5051_HP] = "hp", -+ [CXT5051_HP_DV6736] = "hp-dv6736", -+ [CXT5051_LENOVO_X200] = "lenovo-x200", - }; +@@ -1814,6 +1848,7 @@ static const char *cxt5051_models[CXT5051_MODELS] = { static struct snd_pci_quirk cxt5051_cfg_tbl[] = { -+ SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV6736", CXT5051_HP_DV6736), + SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV6736", CXT5051_HP_DV6736), + SND_PCI_QUIRK(0x103c, 0x360b, "Compaq Presario CQ60", CXT5051_HP), SND_PCI_QUIRK(0x14f1, 0x0101, "Conexant Reference board", CXT5051_LAPTOP), SND_PCI_QUIRK(0x14f1, 0x5051, "HP Spartan 1.1", CXT5051_HP), -+ SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo X200", CXT5051_LENOVO_X200), - {} - }; - -@@ -1742,6 +1865,7 @@ static int patch_cxt5051(struct hda_codec *codec) +@@ -1830,6 +1865,7 @@ static int patch_cxt5051(struct hda_codec *codec) if (!spec) return -ENOMEM; codec->spec = spec; @@ -7343,34 +5597,7 @@ index a50089f..4fcbe21 100644 codec->patch_ops = conexant_patch_ops; codec->patch_ops.init = cxt5051_init; -@@ -1762,17 +1886,22 @@ static int patch_cxt5051(struct hda_codec *codec) - spec->cur_adc = 0; - spec->cur_adc_idx = 0; - -+ codec->patch_ops.unsol_event = cxt5051_hp_unsol_event; -+ - board_config = snd_hda_check_board_config(codec, CXT5051_MODELS, - cxt5051_models, - cxt5051_cfg_tbl); - switch (board_config) { - case CXT5051_HP: -- codec->patch_ops.unsol_event = cxt5051_hp_unsol_event; - spec->mixers[0] = cxt5051_hp_mixers; - break; -- default: -- case CXT5051_LAPTOP: -- codec->patch_ops.unsol_event = cxt5051_hp_unsol_event; -+ case CXT5051_HP_DV6736: -+ spec->init_verbs[0] = cxt5051_hp_dv6736_init_verbs; -+ spec->mixers[0] = cxt5051_hp_dv6736_mixers; -+ spec->no_auto_mic = 1; -+ break; -+ case CXT5051_LENOVO_X200: -+ spec->init_verbs[0] = cxt5051_lenovo_x200_init_verbs; - break; - } - -@@ -1783,7 +1912,7 @@ static int patch_cxt5051(struct hda_codec *codec) +@@ -1876,7 +1912,7 @@ static int patch_cxt5051(struct hda_codec *codec) /* */ @@ -7379,7 +5606,7 @@ index a50089f..4fcbe21 100644 { .id = 0x14f15045, .name = "CX20549 (Venice)", .patch = patch_cxt5045 }, { .id = 0x14f15047, .name = "CX20551 (Waikiki)", -@@ -1792,3 +1921,28 @@ struct hda_codec_preset snd_hda_preset_conexant[] = { +@@ -1885,3 +1921,28 @@ struct hda_codec_preset snd_hda_preset_conexant[] = { .patch = patch_cxt5051 }, {} /* terminator */ }; @@ -7408,730 +5635,6 @@ index a50089f..4fcbe21 100644 + +module_init(patch_conexant_init) +module_exit(patch_conexant_exit) -diff --git a/sound/pci/hda/patch_intelhdmi.c b/sound/pci/hda/patch_intelhdmi.c -new file mode 100644 -index 0000000..fcc77fe ---- /dev/null -+++ b/sound/pci/hda/patch_intelhdmi.c -@@ -0,0 +1,718 @@ -+/* -+ * -+ * patch_intelhdmi.c - Patch for Intel HDMI codecs -+ * -+ * Copyright(c) 2008 Intel Corporation. All rights reserved. -+ * -+ * Authors: -+ * Jiang Zhe -+ * Wu Fengguang -+ * -+ * Maintained by: -+ * Wu Fengguang -+ * -+ * 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 (at your option) -+ * any later version. -+ * -+ * This program 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" -+ -+#define CVT_NID 0x02 /* audio converter */ -+#define PIN_NID 0x03 /* HDMI output pin */ -+ -+#define INTEL_HDMI_EVENT_TAG 0x08 -+ -+struct intel_hdmi_spec { -+ struct hda_multi_out multiout; -+ struct hda_pcm pcm_rec; -+ struct hdmi_eld sink_eld; -+}; -+ -+static struct hda_verb pinout_enable_verb[] = { -+ {PIN_NID, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, -+ {} /* terminator */ -+}; -+ -+static struct hda_verb unsolicited_response_verb[] = { -+ {PIN_NID, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | -+ INTEL_HDMI_EVENT_TAG}, -+ {} -+}; -+ -+static struct hda_verb def_chan_map[] = { -+ {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x00}, -+ {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x11}, -+ {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x22}, -+ {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x33}, -+ {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x44}, -+ {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x55}, -+ {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x66}, -+ {CVT_NID, AC_VERB_SET_HDMI_CHAN_SLOT, 0x77}, -+ {} -+}; -+ -+ -+struct hdmi_audio_infoframe { -+ u8 type; /* 0x84 */ -+ u8 ver; /* 0x01 */ -+ u8 len; /* 0x0a */ -+ -+ u8 checksum; /* PB0 */ -+ u8 CC02_CT47; /* CC in bits 0:2, CT in 4:7 */ -+ u8 SS01_SF24; -+ u8 CXT04; -+ u8 CA; -+ u8 LFEPBL01_LSV36_DM_INH7; -+ u8 reserved[5]; /* PB6 - PB10 */ -+}; -+ -+/* -+ * CEA speaker placement: -+ * -+ * FLH FCH FRH -+ * FLW FL FLC FC FRC FR FRW -+ * -+ * LFE -+ * TC -+ * -+ * RL RLC RC RRC RR -+ * -+ * The Left/Right Surround channel _notions_ LS/RS in SMPTE 320M corresponds to -+ * CEA RL/RR; The SMPTE channel _assignment_ C/LFE is swapped to CEA LFE/FC. -+ */ -+enum cea_speaker_placement { -+ FL = (1 << 0), /* Front Left */ -+ FC = (1 << 1), /* Front Center */ -+ FR = (1 << 2), /* Front Right */ -+ FLC = (1 << 3), /* Front Left Center */ -+ FRC = (1 << 4), /* Front Right Center */ -+ RL = (1 << 5), /* Rear Left */ -+ RC = (1 << 6), /* Rear Center */ -+ RR = (1 << 7), /* Rear Right */ -+ RLC = (1 << 8), /* Rear Left Center */ -+ RRC = (1 << 9), /* Rear Right Center */ -+ LFE = (1 << 10), /* Low Frequency Effect */ -+ FLW = (1 << 11), /* Front Left Wide */ -+ FRW = (1 << 12), /* Front Right Wide */ -+ FLH = (1 << 13), /* Front Left High */ -+ FCH = (1 << 14), /* Front Center High */ -+ FRH = (1 << 15), /* Front Right High */ -+ TC = (1 << 16), /* Top Center */ -+}; -+ -+/* -+ * ELD SA bits in the CEA Speaker Allocation data block -+ */ -+static int eld_speaker_allocation_bits[] = { -+ [0] = FL | FR, -+ [1] = LFE, -+ [2] = FC, -+ [3] = RL | RR, -+ [4] = RC, -+ [5] = FLC | FRC, -+ [6] = RLC | RRC, -+ /* the following are not defined in ELD yet */ -+ [7] = FLW | FRW, -+ [8] = FLH | FRH, -+ [9] = TC, -+ [10] = FCH, -+}; -+ -+struct cea_channel_speaker_allocation { -+ int ca_index; -+ int speakers[8]; -+ -+ /* derived values, just for convenience */ -+ int channels; -+ int spk_mask; -+}; -+ -+/* -+ * This is an ordered list! -+ * -+ * The preceding ones have better chances to be selected by -+ * hdmi_setup_channel_allocation(). -+ */ -+static struct cea_channel_speaker_allocation channel_allocations[] = { -+/* channel: 8 7 6 5 4 3 2 1 */ -+{ .ca_index = 0x00, .speakers = { 0, 0, 0, 0, 0, 0, FR, FL } }, -+ /* 2.1 */ -+{ .ca_index = 0x01, .speakers = { 0, 0, 0, 0, 0, LFE, FR, FL } }, -+ /* Dolby Surround */ -+{ .ca_index = 0x02, .speakers = { 0, 0, 0, 0, FC, 0, FR, FL } }, -+{ .ca_index = 0x03, .speakers = { 0, 0, 0, 0, FC, LFE, FR, FL } }, -+{ .ca_index = 0x04, .speakers = { 0, 0, 0, RC, 0, 0, FR, FL } }, -+{ .ca_index = 0x05, .speakers = { 0, 0, 0, RC, 0, LFE, FR, FL } }, -+{ .ca_index = 0x06, .speakers = { 0, 0, 0, RC, FC, 0, FR, FL } }, -+{ .ca_index = 0x07, .speakers = { 0, 0, 0, RC, FC, LFE, FR, FL } }, -+{ .ca_index = 0x08, .speakers = { 0, 0, RR, RL, 0, 0, FR, FL } }, -+{ .ca_index = 0x09, .speakers = { 0, 0, RR, RL, 0, LFE, FR, FL } }, -+{ .ca_index = 0x0a, .speakers = { 0, 0, RR, RL, FC, 0, FR, FL } }, -+ /* 5.1 */ -+{ .ca_index = 0x0b, .speakers = { 0, 0, RR, RL, FC, LFE, FR, FL } }, -+{ .ca_index = 0x0c, .speakers = { 0, RC, RR, RL, 0, 0, FR, FL } }, -+{ .ca_index = 0x0d, .speakers = { 0, RC, RR, RL, 0, LFE, FR, FL } }, -+{ .ca_index = 0x0e, .speakers = { 0, RC, RR, RL, FC, 0, FR, FL } }, -+ /* 6.1 */ -+{ .ca_index = 0x0f, .speakers = { 0, RC, RR, RL, FC, LFE, FR, FL } }, -+{ .ca_index = 0x10, .speakers = { RRC, RLC, RR, RL, 0, 0, FR, FL } }, -+{ .ca_index = 0x11, .speakers = { RRC, RLC, RR, RL, 0, LFE, FR, FL } }, -+{ .ca_index = 0x12, .speakers = { RRC, RLC, RR, RL, FC, 0, FR, FL } }, -+ /* 7.1 */ -+{ .ca_index = 0x13, .speakers = { RRC, RLC, RR, RL, FC, LFE, FR, FL } }, -+{ .ca_index = 0x14, .speakers = { FRC, FLC, 0, 0, 0, 0, FR, FL } }, -+{ .ca_index = 0x15, .speakers = { FRC, FLC, 0, 0, 0, LFE, FR, FL } }, -+{ .ca_index = 0x16, .speakers = { FRC, FLC, 0, 0, FC, 0, FR, FL } }, -+{ .ca_index = 0x17, .speakers = { FRC, FLC, 0, 0, FC, LFE, FR, FL } }, -+{ .ca_index = 0x18, .speakers = { FRC, FLC, 0, RC, 0, 0, FR, FL } }, -+{ .ca_index = 0x19, .speakers = { FRC, FLC, 0, RC, 0, LFE, FR, FL } }, -+{ .ca_index = 0x1a, .speakers = { FRC, FLC, 0, RC, FC, 0, FR, FL } }, -+{ .ca_index = 0x1b, .speakers = { FRC, FLC, 0, RC, FC, LFE, FR, FL } }, -+{ .ca_index = 0x1c, .speakers = { FRC, FLC, RR, RL, 0, 0, FR, FL } }, -+{ .ca_index = 0x1d, .speakers = { FRC, FLC, RR, RL, 0, LFE, FR, FL } }, -+{ .ca_index = 0x1e, .speakers = { FRC, FLC, RR, RL, FC, 0, FR, FL } }, -+{ .ca_index = 0x1f, .speakers = { FRC, FLC, RR, RL, FC, LFE, FR, FL } }, -+{ .ca_index = 0x20, .speakers = { 0, FCH, RR, RL, FC, 0, FR, FL } }, -+{ .ca_index = 0x21, .speakers = { 0, FCH, RR, RL, FC, LFE, FR, FL } }, -+{ .ca_index = 0x22, .speakers = { TC, 0, RR, RL, FC, 0, FR, FL } }, -+{ .ca_index = 0x23, .speakers = { TC, 0, RR, RL, FC, LFE, FR, FL } }, -+{ .ca_index = 0x24, .speakers = { FRH, FLH, RR, RL, 0, 0, FR, FL } }, -+{ .ca_index = 0x25, .speakers = { FRH, FLH, RR, RL, 0, LFE, FR, FL } }, -+{ .ca_index = 0x26, .speakers = { FRW, FLW, RR, RL, 0, 0, FR, FL } }, -+{ .ca_index = 0x27, .speakers = { FRW, FLW, RR, RL, 0, LFE, FR, FL } }, -+{ .ca_index = 0x28, .speakers = { TC, RC, RR, RL, FC, 0, FR, FL } }, -+{ .ca_index = 0x29, .speakers = { TC, RC, RR, RL, FC, LFE, FR, FL } }, -+{ .ca_index = 0x2a, .speakers = { FCH, RC, RR, RL, FC, 0, FR, FL } }, -+{ .ca_index = 0x2b, .speakers = { FCH, RC, RR, RL, FC, LFE, FR, FL } }, -+{ .ca_index = 0x2c, .speakers = { TC, FCH, RR, RL, FC, 0, FR, FL } }, -+{ .ca_index = 0x2d, .speakers = { TC, FCH, RR, RL, FC, LFE, FR, FL } }, -+{ .ca_index = 0x2e, .speakers = { FRH, FLH, RR, RL, FC, 0, FR, FL } }, -+{ .ca_index = 0x2f, .speakers = { FRH, FLH, RR, RL, FC, LFE, FR, FL } }, -+{ .ca_index = 0x30, .speakers = { FRW, FLW, RR, RL, FC, 0, FR, FL } }, -+{ .ca_index = 0x31, .speakers = { FRW, FLW, RR, RL, FC, LFE, FR, FL } }, -+}; -+ -+/* -+ * HDMI routines -+ */ -+ -+#ifdef BE_PARANOID -+static void hdmi_get_dip_index(struct hda_codec *codec, hda_nid_t nid, -+ int *packet_index, int *byte_index) -+{ -+ int val; -+ -+ val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_DIP_INDEX, 0); -+ -+ *packet_index = val >> 5; -+ *byte_index = val & 0x1f; -+} -+#endif -+ -+static void hdmi_set_dip_index(struct hda_codec *codec, hda_nid_t nid, -+ int packet_index, int byte_index) -+{ -+ int val; -+ -+ val = (packet_index << 5) | (byte_index & 0x1f); -+ -+ snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_HDMI_DIP_INDEX, val); -+} -+ -+static void hdmi_write_dip_byte(struct hda_codec *codec, hda_nid_t nid, -+ unsigned char val) -+{ -+ snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_HDMI_DIP_DATA, val); -+} -+ -+static void hdmi_enable_output(struct hda_codec *codec) -+{ -+ /* Unmute */ -+ 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); -+ /* Enable pin out */ -+ snd_hda_sequence_write(codec, pinout_enable_verb); -+} -+ -+/* -+ * Enable Audio InfoFrame Transmission -+ */ -+static void hdmi_start_infoframe_trans(struct hda_codec *codec) -+{ -+ hdmi_set_dip_index(codec, PIN_NID, 0x0, 0x0); -+ snd_hda_codec_write(codec, PIN_NID, 0, AC_VERB_SET_HDMI_DIP_XMIT, -+ AC_DIPXMIT_BEST); -+} -+ -+/* -+ * Disable Audio InfoFrame Transmission -+ */ -+static void hdmi_stop_infoframe_trans(struct hda_codec *codec) -+{ -+ hdmi_set_dip_index(codec, PIN_NID, 0x0, 0x0); -+ snd_hda_codec_write(codec, PIN_NID, 0, AC_VERB_SET_HDMI_DIP_XMIT, -+ AC_DIPXMIT_DISABLE); -+} -+ -+static int hdmi_get_channel_count(struct hda_codec *codec) -+{ -+ return 1 + snd_hda_codec_read(codec, CVT_NID, 0, -+ AC_VERB_GET_CVT_CHAN_COUNT, 0); -+} -+ -+static void hdmi_set_channel_count(struct hda_codec *codec, int chs) -+{ -+ snd_hda_codec_write(codec, CVT_NID, 0, -+ AC_VERB_SET_CVT_CHAN_COUNT, chs - 1); -+ -+ if (chs != hdmi_get_channel_count(codec)) -+ snd_printd(KERN_INFO "HDMI channel count: expect %d, get %d\n", -+ chs, hdmi_get_channel_count(codec)); -+} -+ -+static void hdmi_debug_channel_mapping(struct hda_codec *codec) -+{ -+#ifdef CONFIG_SND_DEBUG_VERBOSE -+ int i; -+ int slot; -+ -+ for (i = 0; i < 8; i++) { -+ slot = snd_hda_codec_read(codec, CVT_NID, 0, -+ AC_VERB_GET_HDMI_CHAN_SLOT, i); -+ printk(KERN_DEBUG "HDMI: ASP channel %d => slot %d\n", -+ slot >> 4, slot & 0x7); -+ } -+#endif -+} -+ -+static void hdmi_parse_eld(struct hda_codec *codec) -+{ -+ struct intel_hdmi_spec *spec = codec->spec; -+ struct hdmi_eld *eld = &spec->sink_eld; -+ -+ if (!snd_hdmi_get_eld(eld, codec, PIN_NID)) -+ snd_hdmi_show_eld(eld); -+} -+ -+ -+/* -+ * Audio InfoFrame routines -+ */ -+ -+static void hdmi_debug_dip_size(struct hda_codec *codec) -+{ -+#ifdef CONFIG_SND_DEBUG_VERBOSE -+ int i; -+ int size; -+ -+ size = snd_hdmi_get_eld_size(codec, PIN_NID); -+ printk(KERN_DEBUG "HDMI: ELD buf size is %d\n", size); -+ -+ for (i = 0; i < 8; i++) { -+ size = snd_hda_codec_read(codec, PIN_NID, 0, -+ AC_VERB_GET_HDMI_DIP_SIZE, i); -+ printk(KERN_DEBUG "HDMI: DIP GP[%d] buf size is %d\n", i, size); -+ } -+#endif -+} -+ -+static void hdmi_clear_dip_buffers(struct hda_codec *codec) -+{ -+#ifdef BE_PARANOID -+ int i, j; -+ int size; -+ int pi, bi; -+ for (i = 0; i < 8; i++) { -+ size = snd_hda_codec_read(codec, PIN_NID, 0, -+ AC_VERB_GET_HDMI_DIP_SIZE, i); -+ if (size == 0) -+ continue; -+ -+ hdmi_set_dip_index(codec, PIN_NID, i, 0x0); -+ for (j = 1; j < 1000; j++) { -+ hdmi_write_dip_byte(codec, PIN_NID, 0x0); -+ hdmi_get_dip_index(codec, PIN_NID, &pi, &bi); -+ if (pi != i) -+ snd_printd(KERN_INFO "dip index %d: %d != %d\n", -+ bi, pi, i); -+ if (bi == 0) /* byte index wrapped around */ -+ break; -+ } -+ snd_printd(KERN_INFO -+ "HDMI: DIP GP[%d] buf reported size=%d, written=%d\n", -+ i, size, j); -+ } -+#endif -+} -+ -+static void hdmi_fill_audio_infoframe(struct hda_codec *codec, -+ struct hdmi_audio_infoframe *ai) -+{ -+ u8 *params = (u8 *)ai; -+ u8 sum = 0; -+ int i; -+ -+ hdmi_debug_dip_size(codec); -+ hdmi_clear_dip_buffers(codec); /* be paranoid */ -+ -+ for (i = 0; i < sizeof(ai); i++) -+ sum += params[i]; -+ ai->checksum = - sum; -+ -+ hdmi_set_dip_index(codec, PIN_NID, 0x0, 0x0); -+ for (i = 0; i < sizeof(ai); i++) -+ hdmi_write_dip_byte(codec, PIN_NID, params[i]); -+} -+ -+/* -+ * Compute derived values in channel_allocations[]. -+ */ -+static void init_channel_allocations(void) -+{ -+ int i, j; -+ struct cea_channel_speaker_allocation *p; -+ -+ for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) { -+ p = channel_allocations + i; -+ p->channels = 0; -+ p->spk_mask = 0; -+ for (j = 0; j < ARRAY_SIZE(p->speakers); j++) -+ if (p->speakers[j]) { -+ p->channels++; -+ p->spk_mask |= p->speakers[j]; -+ } -+ } -+} -+ -+/* -+ * The transformation takes two steps: -+ * -+ * eld->spk_alloc => (eld_speaker_allocation_bits[]) => spk_mask -+ * spk_mask => (channel_allocations[]) => ai->CA -+ * -+ * TODO: it could select the wrong CA from multiple candidates. -+*/ -+static int hdmi_setup_channel_allocation(struct hda_codec *codec, -+ struct hdmi_audio_infoframe *ai) -+{ -+ struct intel_hdmi_spec *spec = codec->spec; -+ struct hdmi_eld *eld = &spec->sink_eld; -+ int i; -+ int spk_mask = 0; -+ int channels = 1 + (ai->CC02_CT47 & 0x7); -+ char buf[SND_PRINT_CHANNEL_ALLOCATION_ADVISED_BUFSIZE]; -+ -+ /* -+ * CA defaults to 0 for basic stereo audio -+ */ -+ if (channels <= 2) -+ return 0; -+ -+ /* -+ * HDMI sink's ELD info cannot always be retrieved for now, e.g. -+ * in console or for audio devices. Assume the highest speakers -+ * configuration, to _not_ prohibit multi-channel audio playback. -+ */ -+ if (!eld->spk_alloc) -+ eld->spk_alloc = 0xffff; -+ -+ /* -+ * expand ELD's speaker allocation mask -+ * -+ * ELD tells the speaker mask in a compact(paired) form, -+ * expand ELD's notions to match the ones used by Audio InfoFrame. -+ */ -+ for (i = 0; i < ARRAY_SIZE(eld_speaker_allocation_bits); i++) { -+ if (eld->spk_alloc & (1 << i)) -+ spk_mask |= eld_speaker_allocation_bits[i]; -+ } -+ -+ /* search for the first working match in the CA table */ -+ for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) { -+ if (channels == channel_allocations[i].channels && -+ (spk_mask & channel_allocations[i].spk_mask) == -+ channel_allocations[i].spk_mask) { -+ ai->CA = channel_allocations[i].ca_index; -+ break; -+ } -+ } -+ -+ snd_print_channel_allocation(eld->spk_alloc, buf, sizeof(buf)); -+ snd_printdd(KERN_INFO -+ "HDMI: select CA 0x%x for %d-channel allocation: %s\n", -+ ai->CA, channels, buf); -+ -+ return ai->CA; -+} -+ -+static void hdmi_setup_channel_mapping(struct hda_codec *codec, -+ struct hdmi_audio_infoframe *ai) -+{ -+ if (!ai->CA) -+ return; -+ -+ /* -+ * TODO: adjust channel mapping if necessary -+ * ALSA sequence is front/surr/clfe/side? -+ */ -+ -+ snd_hda_sequence_write(codec, def_chan_map); -+ hdmi_debug_channel_mapping(codec); -+} -+ -+ -+static void hdmi_setup_audio_infoframe(struct hda_codec *codec, -+ struct snd_pcm_substream *substream) -+{ -+ struct hdmi_audio_infoframe ai = { -+ .type = 0x84, -+ .ver = 0x01, -+ .len = 0x0a, -+ .CC02_CT47 = substream->runtime->channels - 1, -+ }; -+ -+ hdmi_setup_channel_allocation(codec, &ai); -+ hdmi_setup_channel_mapping(codec, &ai); -+ -+ hdmi_fill_audio_infoframe(codec, &ai); -+ hdmi_start_infoframe_trans(codec); -+} -+ -+ -+/* -+ * Unsolicited events -+ */ -+ -+static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) -+{ -+ int pind = !!(res & AC_UNSOL_RES_PD); -+ int eldv = !!(res & AC_UNSOL_RES_ELDV); -+ -+ printk(KERN_INFO -+ "HDMI hot plug event: Presence_Detect=%d ELD_Valid=%d\n", -+ pind, eldv); -+ -+ if (pind && eldv) { -+ hdmi_parse_eld(codec); -+ /* TODO: do real things about ELD */ -+ } -+} -+ -+static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res) -+{ -+ int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT; -+ int cp_state = !!(res & AC_UNSOL_RES_CP_STATE); -+ int cp_ready = !!(res & AC_UNSOL_RES_CP_READY); -+ -+ printk(KERN_INFO -+ "HDMI content protection event: SUBTAG=0x%x CP_STATE=%d CP_READY=%d\n", -+ subtag, -+ cp_state, -+ cp_ready); -+ -+ /* TODO */ -+ if (cp_state) -+ ; -+ if (cp_ready) -+ ; -+} -+ -+ -+static void intel_hdmi_unsol_event(struct hda_codec *codec, unsigned int res) -+{ -+ int tag = res >> AC_UNSOL_RES_TAG_SHIFT; -+ int subtag = (res & AC_UNSOL_RES_SUBTAG) >> AC_UNSOL_RES_SUBTAG_SHIFT; -+ -+ if (tag != INTEL_HDMI_EVENT_TAG) { -+ snd_printd(KERN_INFO "Unexpected HDMI event tag 0x%x\n", tag); -+ return; -+ } -+ -+ if (subtag == 0) -+ hdmi_intrinsic_event(codec, res); -+ else -+ hdmi_non_intrinsic_event(codec, res); -+} -+ -+/* -+ * Callbacks -+ */ -+ -+static int intel_hdmi_playback_pcm_open(struct hda_pcm_stream *hinfo, -+ struct hda_codec *codec, -+ struct snd_pcm_substream *substream) -+{ -+ struct intel_hdmi_spec *spec = codec->spec; -+ -+ return snd_hda_multi_out_dig_open(codec, &spec->multiout); -+} -+ -+static int intel_hdmi_playback_pcm_close(struct hda_pcm_stream *hinfo, -+ struct hda_codec *codec, -+ struct snd_pcm_substream *substream) -+{ -+ struct intel_hdmi_spec *spec = codec->spec; -+ -+ hdmi_stop_infoframe_trans(codec); -+ -+ return snd_hda_multi_out_dig_close(codec, &spec->multiout); -+} -+ -+static int intel_hdmi_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 intel_hdmi_spec *spec = codec->spec; -+ -+ snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag, -+ format, substream); -+ -+ hdmi_set_channel_count(codec, substream->runtime->channels); -+ -+ hdmi_setup_audio_infoframe(codec, substream); -+ -+ return 0; -+} -+ -+static struct hda_pcm_stream intel_hdmi_pcm_playback = { -+ .substreams = 1, -+ .channels_min = 2, -+ .channels_max = 8, -+ .nid = CVT_NID, /* NID to query formats and rates and setup streams */ -+ .ops = { -+ .open = intel_hdmi_playback_pcm_open, -+ .close = intel_hdmi_playback_pcm_close, -+ .prepare = intel_hdmi_playback_pcm_prepare -+ }, -+}; -+ -+static int intel_hdmi_build_pcms(struct hda_codec *codec) -+{ -+ struct intel_hdmi_spec *spec = codec->spec; -+ struct hda_pcm *info = &spec->pcm_rec; -+ -+ codec->num_pcms = 1; -+ codec->pcm_info = info; -+ -+ info->name = "INTEL HDMI"; -+ info->pcm_type = HDA_PCM_TYPE_HDMI; -+ info->stream[SNDRV_PCM_STREAM_PLAYBACK] = intel_hdmi_pcm_playback; -+ -+ return 0; -+} -+ -+static int intel_hdmi_build_controls(struct hda_codec *codec) -+{ -+ struct intel_hdmi_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 intel_hdmi_init(struct hda_codec *codec) -+{ -+ hdmi_enable_output(codec); -+ -+ snd_hda_sequence_write(codec, unsolicited_response_verb); -+ -+ return 0; -+} -+ -+static void intel_hdmi_free(struct hda_codec *codec) -+{ -+ struct intel_hdmi_spec *spec = codec->spec; -+ -+ snd_hda_eld_proc_free(codec, &spec->sink_eld); -+ kfree(spec); -+} -+ -+static struct hda_codec_ops intel_hdmi_patch_ops = { -+ .init = intel_hdmi_init, -+ .free = intel_hdmi_free, -+ .build_pcms = intel_hdmi_build_pcms, -+ .build_controls = intel_hdmi_build_controls, -+ .unsol_event = intel_hdmi_unsol_event, -+}; -+ -+static int patch_intel_hdmi(struct hda_codec *codec) -+{ -+ struct intel_hdmi_spec *spec; -+ -+ spec = kzalloc(sizeof(*spec), GFP_KERNEL); -+ if (spec == NULL) -+ return -ENOMEM; -+ -+ spec->multiout.num_dacs = 0; /* no analog */ -+ spec->multiout.max_channels = 8; -+ spec->multiout.dig_out_nid = CVT_NID; -+ -+ codec->spec = spec; -+ codec->patch_ops = intel_hdmi_patch_ops; -+ -+ snd_hda_eld_proc_new(codec, &spec->sink_eld); -+ -+ init_channel_allocations(); -+ -+ return 0; -+} -+ -+static struct hda_codec_preset snd_hda_preset_intelhdmi[] = { -+ { .id = 0x808629fb, .name = "G45 DEVCL", .patch = patch_intel_hdmi }, -+ { .id = 0x80862801, .name = "G45 DEVBLC", .patch = patch_intel_hdmi }, -+ { .id = 0x80862802, .name = "G45 DEVCTG", .patch = patch_intel_hdmi }, -+ { .id = 0x80862803, .name = "G45 DEVELK", .patch = patch_intel_hdmi }, -+ { .id = 0x80862804, .name = "G45 DEVIBX", .patch = patch_intel_hdmi }, -+ { .id = 0x10951392, .name = "SiI1392 HDMI", .patch = patch_intel_hdmi }, -+ {} /* terminator */ -+}; -+ -+MODULE_ALIAS("snd-hda-codec-id:808629fb"); -+MODULE_ALIAS("snd-hda-codec-id:80862801"); -+MODULE_ALIAS("snd-hda-codec-id:80862802"); -+MODULE_ALIAS("snd-hda-codec-id:80862803"); -+MODULE_ALIAS("snd-hda-codec-id:80862804"); -+MODULE_ALIAS("snd-hda-codec-id:10951392"); -+ -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("Intel HDMI HD-audio codec"); -+ -+static struct hda_codec_preset_list intel_list = { -+ .preset = snd_hda_preset_intelhdmi, -+ .owner = THIS_MODULE, -+}; -+ -+static int __init patch_intelhdmi_init(void) -+{ -+ return snd_hda_add_codec_preset(&intel_list); -+} -+ -+static void __exit patch_intelhdmi_exit(void) -+{ -+ snd_hda_delete_codec_preset(&intel_list); -+} -+ -+module_init(patch_intelhdmi_init) -+module_exit(patch_intelhdmi_exit) diff --git a/sound/pci/hda/patch_nvhdmi.c b/sound/pci/hda/patch_nvhdmi.c index 2eed2c8..d57d813 100644 --- a/sound/pci/hda/patch_nvhdmi.c @@ -8179,7 +5682,7 @@ index 2eed2c8..d57d813 100644 +module_init(patch_nvhdmi_init) +module_exit(patch_nvhdmi_exit) diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c -index 067e6ed..0fd258e 100644 +index 131bf5a..0fd258e 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -30,7 +30,7 @@ @@ -8483,15 +5986,6 @@ index 067e6ed..0fd258e 100644 #endif /* disabled */ /* unsolicited event for HP jack sensing */ -@@ -884,7 +990,7 @@ static void alc888_coef_init(struct hda_codec *codec) - snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0); - 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); -- if ((tmp & 0xf0) == 2) -+ if ((tmp & 0xf0) == 0x20) - /* alc888S-VC */ - snd_hda_codec_read(codec, 0x20, 0, - AC_VERB_SET_PROC_COEF, 0x830); @@ -923,8 +1029,7 @@ static void alc_subsystem_id(struct hda_codec *codec, nid = 0x1d; if (codec->vendor_id == 0x10ec0260) @@ -8806,7 +6300,7 @@ index 067e6ed..0fd258e 100644 + mutex_unlock(&codec->control_mutex); + return err; +} -+ + +static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag, + unsigned int size, unsigned int __user *tlv) +{ @@ -8821,7 +6315,7 @@ index 067e6ed..0fd258e 100644 + mutex_unlock(&codec->control_mutex); + return err; +} -+ + +typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol); + @@ -8906,14 +6400,14 @@ index 067e6ed..0fd258e 100644 + .get = alc_mux_enum_get, \ + .put = alc_mux_enum_put, \ + } - ++ +#define DEFINE_CAPMIX(num) \ +static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \ + _DEFINE_CAPMIX(num), \ + _DEFINE_CAPSRC(num), \ + { } /* end */ \ +} - ++ +#define DEFINE_CAPMIX_NOSRC(num) \ +static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \ + _DEFINE_CAPMIX(num), \ @@ -10196,18 +7690,15 @@ index 067e6ed..0fd258e 100644 } } } -@@ -6777,8 +7190,10 @@ static int patch_alc882(struct hda_codec *codec) +@@ -6777,6 +7190,7 @@ static int patch_alc882(struct hda_codec *codec) break; case 0x106b1000: /* iMac 24 */ case 0x106b2800: /* AppleTV */ + case 0x106b3e00: /* iMac 24 Aluminium */ board_config = ALC885_IMAC24; break; -+ case 0x106b00a0: /* MacBookPro3,1 - Another revision */ - case 0x106b00a1: /* Macbook (might be wrong - PCI SSID?) */ - case 0x106b00a4: /* MacbookPro4,1 */ - case 0x106b2c00: /* Macbook Pro rev3 */ -@@ -6815,6 +7230,12 @@ static int patch_alc882(struct hda_codec *codec) + case 0x106b00a0: /* MacBookPro3,1 - Another revision */ +@@ -6816,6 +7230,12 @@ static int patch_alc882(struct hda_codec *codec) } } @@ -10220,7 +7711,7 @@ index 067e6ed..0fd258e 100644 if (board_config != ALC882_AUTO) setup_preset(spec, &alc882_presets[board_config]); -@@ -6835,6 +7256,7 @@ static int patch_alc882(struct hda_codec *codec) +@@ -6836,6 +7256,7 @@ static int patch_alc882(struct hda_codec *codec) spec->stream_digital_playback = &alc882_pcm_digital_playback; spec->stream_digital_capture = &alc882_pcm_digital_capture; @@ -10228,7 +7719,7 @@ index 067e6ed..0fd258e 100644 if (!spec->adc_nids && spec->input_mux) { /* check whether NID 0x07 is valid */ unsigned int wcap = get_wcaps(codec, 0x07); -@@ -6844,17 +7266,14 @@ static int patch_alc882(struct hda_codec *codec) +@@ -6845,17 +7266,14 @@ static int patch_alc882(struct hda_codec *codec) spec->adc_nids = alc882_adc_nids_alt; spec->num_adc_nids = ARRAY_SIZE(alc882_adc_nids_alt); spec->capsrc_nids = alc882_capsrc_nids_alt; @@ -10248,7 +7739,7 @@ index 067e6ed..0fd258e 100644 spec->vmaster_nid = 0x0c; -@@ -6865,6 +7284,7 @@ static int patch_alc882(struct hda_codec *codec) +@@ -6866,6 +7284,7 @@ static int patch_alc882(struct hda_codec *codec) if (!spec->loopback.amplist) spec->loopback.amplist = alc882_loopbacks; #endif @@ -10256,7 +7747,7 @@ index 067e6ed..0fd258e 100644 return 0; } -@@ -6883,6 +7303,8 @@ static int patch_alc882(struct hda_codec *codec) +@@ -6884,6 +7303,8 @@ static int patch_alc882(struct hda_codec *codec) #define ALC883_DIGOUT_NID 0x06 #define ALC883_DIGIN_NID 0x0a @@ -10265,7 +7756,7 @@ index 067e6ed..0fd258e 100644 static hda_nid_t alc883_dac_nids[4] = { /* front, rear, clfe, rear_surr */ 0x02, 0x03, 0x04, 0x05 -@@ -6893,8 +7315,24 @@ static hda_nid_t alc883_adc_nids[2] = { +@@ -6894,8 +7315,24 @@ static hda_nid_t alc883_adc_nids[2] = { 0x08, 0x09, }; @@ -10290,7 +7781,7 @@ index 067e6ed..0fd258e 100644 /* input MUX */ /* FIXME: should be a matrix-type input source selection */ -@@ -6961,11 +7399,6 @@ static struct hda_input_mux alc883_asus_eee1601_capture_source = { +@@ -6962,11 +7399,6 @@ static struct hda_input_mux alc883_asus_eee1601_capture_source = { }, }; @@ -10302,7 +7793,7 @@ index 067e6ed..0fd258e 100644 /* * 2ch mode */ -@@ -7117,21 +7550,6 @@ static struct snd_kcontrol_new alc883_base_mixer[] = { +@@ -7118,21 +7550,6 @@ static struct snd_kcontrol_new alc883_base_mixer[] = { 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), @@ -10324,7 +7815,7 @@ index 067e6ed..0fd258e 100644 { } /* end */ }; -@@ -7149,19 +7567,6 @@ static struct snd_kcontrol_new alc883_mitac_mixer[] = { +@@ -7150,19 +7567,6 @@ static struct snd_kcontrol_new alc883_mitac_mixer[] = { 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), @@ -10344,7 +7835,7 @@ index 067e6ed..0fd258e 100644 { } /* end */ }; -@@ -7176,19 +7581,6 @@ static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = { +@@ -7177,19 +7581,6 @@ static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = { HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), @@ -10364,7 +7855,7 @@ index 067e6ed..0fd258e 100644 { } /* end */ }; -@@ -7203,19 +7595,6 @@ static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = { +@@ -7204,19 +7595,6 @@ static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = { HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), @@ -10384,7 +7875,7 @@ index 067e6ed..0fd258e 100644 { } /* end */ }; -@@ -7233,21 +7612,6 @@ static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = { +@@ -7234,21 +7612,6 @@ static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = { 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), @@ -10406,7 +7897,7 @@ index 067e6ed..0fd258e 100644 { } /* end */ }; -@@ -7271,19 +7635,6 @@ static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = { +@@ -7272,19 +7635,6 @@ static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = { 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), @@ -10426,7 +7917,7 @@ index 067e6ed..0fd258e 100644 { } /* end */ }; -@@ -7308,21 +7659,6 @@ static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = { +@@ -7309,21 +7659,6 @@ static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = { HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Front Mic Boost", 0x18, 0, HDA_INPUT), HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), @@ -10448,7 +7939,7 @@ index 067e6ed..0fd258e 100644 { } /* end */ }; -@@ -7346,20 +7682,6 @@ static struct snd_kcontrol_new alc883_fivestack_mixer[] = { +@@ -7347,20 +7682,6 @@ static struct snd_kcontrol_new alc883_fivestack_mixer[] = { 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), @@ -10469,7 +7960,7 @@ index 067e6ed..0fd258e 100644 { } /* end */ }; -@@ -7380,19 +7702,6 @@ static struct snd_kcontrol_new alc883_tagra_mixer[] = { +@@ -7381,19 +7702,6 @@ static struct snd_kcontrol_new alc883_tagra_mixer[] = { 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), @@ -10489,7 +7980,7 @@ index 067e6ed..0fd258e 100644 { } /* end */ }; -@@ -7408,19 +7717,6 @@ static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = { +@@ -7409,19 +7717,6 @@ static struct snd_kcontrol_new alc883_tagra_2ch_mixer[] = { HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), @@ -10509,7 +8000,7 @@ index 067e6ed..0fd258e 100644 { } /* end */ }; -@@ -7433,17 +7729,6 @@ static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = { +@@ -7434,17 +7729,6 @@ static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = { HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), @@ -10527,7 +8018,7 @@ index 067e6ed..0fd258e 100644 { } /* end */ }; -@@ -7457,19 +7742,6 @@ static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = { +@@ -7458,19 +7742,6 @@ static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = { HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("iMic Playback Volume", 0x0b, 0x1, HDA_INPUT), HDA_CODEC_MUTE("iMic Playback Switch", 0x0b, 0x1, HDA_INPUT), @@ -10547,7 +8038,7 @@ index 067e6ed..0fd258e 100644 { } /* end */ }; -@@ -7483,19 +7755,6 @@ static struct snd_kcontrol_new alc883_medion_md2_mixer[] = { +@@ -7484,19 +7755,6 @@ static struct snd_kcontrol_new alc883_medion_md2_mixer[] = { HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), @@ -10567,7 +8058,7 @@ index 067e6ed..0fd258e 100644 { } /* end */ }; -@@ -7508,19 +7767,6 @@ static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { +@@ -7509,19 +7767,6 @@ static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { 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), @@ -10587,7 +8078,7 @@ index 067e6ed..0fd258e 100644 { } /* end */ }; -@@ -7548,19 +7794,6 @@ static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = { +@@ -7549,19 +7794,6 @@ static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = { 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), @@ -10607,7 +8098,7 @@ index 067e6ed..0fd258e 100644 { } /* end */ }; -@@ -7591,6 +7824,10 @@ static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = { +@@ -7592,6 +7824,10 @@ static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = { 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), @@ -10618,7 +8109,7 @@ index 067e6ed..0fd258e 100644 HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol), HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch), { -@@ -7598,9 +7835,9 @@ static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = { +@@ -7599,9 +7835,9 @@ static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = { /* .name = "Capture Source", */ .name = "Input Source", .count = 1, @@ -10631,99 +8122,7 @@ index 067e6ed..0fd258e 100644 }, { } /* end */ }; -@@ -7852,36 +8089,83 @@ static struct hda_verb alc888_lenovo_sky_verbs[] = { - { } /* end */ - }; - -+static struct hda_verb alc888_6st_dell_verbs[] = { -+ {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, -+ { } -+}; -+ -+static void alc888_3st_hp_front_automute(struct hda_codec *codec) -+{ -+ unsigned int present, bits; -+ -+ present = snd_hda_codec_read(codec, 0x1b, 0, -+ AC_VERB_GET_PIN_SENSE, 0) & 0x80000000; -+ 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, 0x16, HDA_OUTPUT, 0, -+ HDA_AMP_MUTE, bits); -+ snd_hda_codec_amp_stereo(codec, 0x18, HDA_OUTPUT, 0, -+ HDA_AMP_MUTE, bits); -+} -+ -+static void alc888_3st_hp_unsol_event(struct hda_codec *codec, -+ unsigned int res) -+{ -+ switch (res >> 26) { -+ case ALC880_HP_EVENT: -+ alc888_3st_hp_front_automute(codec); -+ break; -+ } -+} -+ - 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) */ - {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */ -- { } --}; -- --static struct hda_verb alc888_6st_dell_verbs[] = { - {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, -- { } -+ { } /* end */ - }; - -+/* -+ * 2ch mode -+ */ - static struct hda_verb alc888_3st_hp_2ch_init[] = { - { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, - { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, - { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, - { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, -- { } -+ { } /* end */ - }; - -+/* -+ * 4ch mode -+ */ -+static struct hda_verb alc888_3st_hp_4ch_init[] = { -+ { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, -+ { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, -+ { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, -+ { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, -+ { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 }, -+ { } /* end */ -+}; -+ -+/* -+ * 6ch mode -+ */ - static struct hda_verb alc888_3st_hp_6ch_init[] = { - { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, -+ { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, - { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, - { 0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, -- { } -+ { 0x16, AC_VERB_SET_CONNECT_SEL, 0x01 }, -+ { } /* end */ - }; - --static struct hda_channel_mode alc888_3st_hp_modes[2] = { -+static struct hda_channel_mode alc888_3st_hp_modes[3] = { - { 2, alc888_3st_hp_2ch_init }, -+ { 4, alc888_3st_hp_4ch_init }, - { 6, alc888_3st_hp_6ch_init }, - }; - -@@ -8142,7 +8426,7 @@ static void alc888_6st_dell_unsol_event(struct hda_codec *codec, +@@ -8190,7 +8426,7 @@ static void alc888_6st_dell_unsol_event(struct hda_codec *codec, { switch (res >> 26) { case ALC880_HP_EVENT: @@ -10732,7 +8131,7 @@ index 067e6ed..0fd258e 100644 alc888_6st_dell_front_automute(codec); break; } -@@ -8255,27 +8539,6 @@ static struct hda_verb alc883_auto_init_verbs[] = { +@@ -8303,27 +8539,6 @@ static struct hda_verb alc883_auto_init_verbs[] = { { } }; @@ -10760,7 +8159,7 @@ index 067e6ed..0fd258e 100644 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)}, -@@ -8398,6 +8661,7 @@ static const char *alc883_models[ALC883_MODEL_LAST] = { +@@ -8446,6 +8661,7 @@ static const char *alc883_models[ALC883_MODEL_LAST] = { [ALC883_TARGA_2ch_DIG] = "targa-2ch-dig", [ALC883_ACER] = "acer", [ALC883_ACER_ASPIRE] = "acer-aspire", @@ -10768,7 +8167,7 @@ index 067e6ed..0fd258e 100644 [ALC883_MEDION] = "medion", [ALC883_MEDION_MD2] = "medion-md2", [ALC883_LAPTOP_EAPD] = "laptop-eapd", -@@ -8411,7 +8675,9 @@ static const char *alc883_models[ALC883_MODEL_LAST] = { +@@ -8459,7 +8675,9 @@ static const char *alc883_models[ALC883_MODEL_LAST] = { [ALC883_MITAC] = "mitac", [ALC883_CLEVO_M720] = "clevo-m720", [ALC883_FUJITSU_PI2515] = "fujitsu-pi2515", @@ -10778,7 +8177,7 @@ index 067e6ed..0fd258e 100644 [ALC883_AUTO] = "auto", }; -@@ -8419,20 +8685,37 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { +@@ -8467,10 +8685,22 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC883_3ST_6ch_DIG), SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE), SND_PCI_QUIRK(0x1025, 0x0090, "Acer Aspire", ALC883_ACER_ASPIRE), @@ -10802,12 +8201,11 @@ index 067e6ed..0fd258e 100644 SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL), SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG), SND_PCI_QUIRK(0x103c, 0x2a4f, "HP Samba", ALC888_3ST_HP), - SND_PCI_QUIRK(0x103c, 0x2a60, "HP Lucknow", ALC888_3ST_HP), - SND_PCI_QUIRK(0x103c, 0x2a61, "HP Nettle", ALC883_6ST_DIG), -+ SND_PCI_QUIRK(0x103c, 0x2a66, "HP Acacia", ALC888_3ST_HP), -+ SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP), +@@ -8480,10 +8710,12 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { + SND_PCI_QUIRK(0x103c, 0x2a72, "HP Educ.ar", ALC888_3ST_HP), SND_PCI_QUIRK(0x1043, 0x1873, "Asus M90V", ALC888_ASUS_M90V), SND_PCI_QUIRK(0x1043, 0x8249, "Asus M2A-VM HDMI", ALC883_3ST_6ch_DIG), +- SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG), + SND_PCI_QUIRK(0x1043, 0x8284, "Asus Z37E", ALC883_6ST_DIG), + SND_PCI_QUIRK(0x1043, 0x82fe, "Asus P5Q-EM HDMI", ALC1200_ASUS_P5Q), SND_PCI_QUIRK(0x1043, 0x835f, "Asus Eee 1601", ALC888_ASUS_EEE1601), @@ -10817,7 +8215,7 @@ index 067e6ed..0fd258e 100644 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), -@@ -8456,6 +8739,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { +@@ -8507,6 +8739,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { SND_PCI_QUIRK(0x1462, 0x6668, "MSI", ALC883_6ST_DIG), SND_PCI_QUIRK(0x1462, 0x7187, "MSI", ALC883_6ST_DIG), SND_PCI_QUIRK(0x1462, 0x7250, "MSI", ALC883_6ST_DIG), @@ -10825,7 +8223,7 @@ index 067e6ed..0fd258e 100644 SND_PCI_QUIRK(0x1462, 0x7267, "MSI", ALC883_3ST_6ch_DIG), SND_PCI_QUIRK(0x1462, 0x7280, "MSI", ALC883_6ST_DIG), SND_PCI_QUIRK(0x1462, 0x7327, "MSI", ALC883_6ST_DIG), -@@ -8463,12 +8747,13 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { +@@ -8514,12 +8747,13 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { SND_PCI_QUIRK(0x147b, 0x1083, "Abit IP35-PRO", ALC883_6ST_DIG), SND_PCI_QUIRK(0x1558, 0x0721, "Clevo laptop M720R", ALC883_CLEVO_M720), SND_PCI_QUIRK(0x1558, 0x0722, "Clevo laptop M720SR", ALC883_CLEVO_M720), @@ -10842,7 +8240,7 @@ index 067e6ed..0fd258e 100644 SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo 101e", ALC883_LENOVO_101E_2ch), SND_PCI_QUIRK(0x17aa, 0x2085, "Lenovo NB0763", ALC883_LENOVO_NB0763), SND_PCI_QUIRK(0x17aa, 0x3bfc, "Lenovo NB0763", ALC883_LENOVO_NB0763), -@@ -8480,10 +8765,20 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { +@@ -8531,10 +8765,20 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = { SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66), SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL), SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL), @@ -10863,7 +8261,7 @@ index 067e6ed..0fd258e 100644 static struct alc_config_preset alc883_presets[] = { [ALC883_3ST_2ch_DIG] = { .mixers = { alc883_3ST_2ch_mixer }, -@@ -8525,6 +8820,7 @@ static struct alc_config_preset alc883_presets[] = { +@@ -8576,6 +8820,7 @@ static struct alc_config_preset alc883_presets[] = { .dac_nids = alc883_dac_nids, .dig_out_nid = ALC883_DIGOUT_NID, .dig_in_nid = ALC883_DIGIN_NID, @@ -10871,7 +8269,7 @@ index 067e6ed..0fd258e 100644 .num_channel_mode = ARRAY_SIZE(alc883_3ST_6ch_intel_modes), .channel_mode = alc883_3ST_6ch_intel_modes, .need_dac_fix = 1, -@@ -8559,6 +8855,8 @@ static struct alc_config_preset alc883_presets[] = { +@@ -8610,6 +8855,8 @@ static struct alc_config_preset alc883_presets[] = { .init_verbs = { alc883_init_verbs, alc883_tagra_verbs}, .num_dacs = ARRAY_SIZE(alc883_dac_nids), .dac_nids = alc883_dac_nids, @@ -10880,7 +8278,7 @@ index 067e6ed..0fd258e 100644 .dig_out_nid = ALC883_DIGOUT_NID, .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), .channel_mode = alc883_3ST_2ch_modes, -@@ -8592,6 +8890,26 @@ static struct alc_config_preset alc883_presets[] = { +@@ -8643,6 +8890,26 @@ static struct alc_config_preset alc883_presets[] = { .unsol_event = alc883_acer_aspire_unsol_event, .init_hook = alc883_acer_aspire_automute, }, @@ -10907,7 +8305,7 @@ index 067e6ed..0fd258e 100644 [ALC883_MEDION] = { .mixers = { alc883_fivestack_mixer, alc883_chmode_mixer }, -@@ -8599,6 +8917,8 @@ static struct alc_config_preset alc883_presets[] = { +@@ -8650,6 +8917,8 @@ static struct alc_config_preset alc883_presets[] = { alc883_medion_eapd_verbs }, .num_dacs = ARRAY_SIZE(alc883_dac_nids), .dac_nids = alc883_dac_nids, @@ -10916,7 +8314,7 @@ index 067e6ed..0fd258e 100644 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), .channel_mode = alc883_sixstack_modes, .input_mux = &alc883_capture_source, -@@ -8641,6 +8961,8 @@ static struct alc_config_preset alc883_presets[] = { +@@ -8692,6 +8961,8 @@ static struct alc_config_preset alc883_presets[] = { .init_verbs = { alc883_init_verbs, alc883_lenovo_101e_verbs}, .num_dacs = ARRAY_SIZE(alc883_dac_nids), .dac_nids = alc883_dac_nids, @@ -10925,16 +8323,7 @@ index 067e6ed..0fd258e 100644 .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), .channel_mode = alc883_3ST_2ch_modes, .input_mux = &alc883_lenovo_101e_capture_source, -@@ -8693,6 +9015,8 @@ static struct alc_config_preset alc883_presets[] = { - .channel_mode = alc888_3st_hp_modes, - .need_dac_fix = 1, - .input_mux = &alc883_capture_source, -+ .unsol_event = alc888_3st_hp_unsol_event, -+ .init_hook = alc888_3st_hp_front_automute, - }, - [ALC888_6ST_DELL] = { - .mixers = { alc883_base_mixer, alc883_chmode_mixer }, -@@ -8731,14 +9055,30 @@ static struct alc_config_preset alc883_presets[] = { +@@ -8784,14 +9055,30 @@ static struct alc_config_preset alc883_presets[] = { .unsol_event = alc883_2ch_fujitsu_pi2515_unsol_event, .init_hook = alc883_2ch_fujitsu_pi2515_automute, }, @@ -10967,7 +8356,7 @@ index 067e6ed..0fd258e 100644 .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), .channel_mode = alc883_sixstack_modes, .need_dac_fix = 1, -@@ -8762,6 +9102,7 @@ static struct alc_config_preset alc883_presets[] = { +@@ -8815,6 +9102,7 @@ static struct alc_config_preset alc883_presets[] = { }, [ALC888_ASUS_EEE1601] = { .mixers = { alc883_asus_eee1601_mixer }, @@ -10975,7 +8364,7 @@ index 067e6ed..0fd258e 100644 .init_verbs = { alc883_init_verbs, alc888_asus_eee1601_verbs }, .num_dacs = ARRAY_SIZE(alc883_dac_nids), .dac_nids = alc883_dac_nids, -@@ -8774,6 +9115,18 @@ static struct alc_config_preset alc883_presets[] = { +@@ -8827,6 +9115,18 @@ static struct alc_config_preset alc883_presets[] = { .unsol_event = alc883_eee1601_unsol_event, .init_hook = alc883_eee1601_inithook, }, @@ -10994,7 +8383,7 @@ index 067e6ed..0fd258e 100644 }; -@@ -8837,11 +9190,9 @@ static void alc883_auto_init_analog_input(struct hda_codec *codec) +@@ -8890,11 +9190,9 @@ static void alc883_auto_init_analog_input(struct hda_codec *codec) for (i = 0; i < AUTO_PIN_LAST; i++) { hda_nid_t nid = spec->autocfg.input_pins[i]; if (alc883_is_input_pin(nid)) { @@ -11009,7 +8398,7 @@ index 067e6ed..0fd258e 100644 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); -@@ -8856,6 +9207,8 @@ static int alc883_parse_auto_config(struct hda_codec *codec) +@@ -8909,6 +9207,8 @@ static int alc883_parse_auto_config(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; int err = alc880_parse_auto_config(codec); @@ -11018,7 +8407,7 @@ index 067e6ed..0fd258e 100644 if (err < 0) return err; -@@ -8868,8 +9221,26 @@ static int alc883_parse_auto_config(struct hda_codec *codec) +@@ -8921,8 +9221,26 @@ static int alc883_parse_auto_config(struct hda_codec *codec) /* hack - override the init verbs */ spec->init_verbs[0] = alc883_auto_init_verbs; @@ -11047,7 +8436,7 @@ index 067e6ed..0fd258e 100644 return 1; /* config found */ } -@@ -8922,6 +9293,12 @@ static int patch_alc883(struct hda_codec *codec) +@@ -8975,6 +9293,12 @@ static int patch_alc883(struct hda_codec *codec) } } @@ -11060,7 +8449,7 @@ index 067e6ed..0fd258e 100644 if (board_config != ALC883_AUTO) setup_preset(spec, &alc883_presets[board_config]); -@@ -8934,14 +9311,36 @@ static int patch_alc883(struct hda_codec *codec) +@@ -8987,14 +9311,36 @@ static int patch_alc883(struct hda_codec *codec) spec->stream_name_analog = "ALC888 Analog"; spec->stream_name_digital = "ALC888 Digital"; } @@ -11097,7 +8486,7 @@ index 067e6ed..0fd258e 100644 break; } -@@ -8952,9 +9351,9 @@ static int patch_alc883(struct hda_codec *codec) +@@ -9005,9 +9351,9 @@ static int patch_alc883(struct hda_codec *codec) spec->stream_digital_playback = &alc883_pcm_digital_playback; spec->stream_digital_capture = &alc883_pcm_digital_capture; @@ -11110,7 +8499,7 @@ index 067e6ed..0fd258e 100644 spec->vmaster_nid = 0x0c; -@@ -8966,6 +9365,7 @@ static int patch_alc883(struct hda_codec *codec) +@@ -9019,6 +9365,7 @@ static int patch_alc883(struct hda_codec *codec) if (!spec->loopback.amplist) spec->loopback.amplist = alc883_loopbacks; #endif @@ -11118,7 +8507,7 @@ index 067e6ed..0fd258e 100644 return 0; } -@@ -9006,8 +9406,6 @@ static struct snd_kcontrol_new alc262_base_mixer[] = { +@@ -9059,8 +9406,6 @@ static struct snd_kcontrol_new alc262_base_mixer[] = { 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), @@ -11127,7 +8516,7 @@ index 067e6ed..0fd258e 100644 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0e, 2, 0x0, HDA_OUTPUT), -@@ -9028,8 +9426,6 @@ static struct snd_kcontrol_new alc262_hippo1_mixer[] = { +@@ -9081,8 +9426,6 @@ static struct snd_kcontrol_new alc262_hippo1_mixer[] = { 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), @@ -11136,7 +8525,7 @@ index 067e6ed..0fd258e 100644 /*HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0D, 0x0, HDA_OUTPUT),*/ HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), { } /* end */ -@@ -9138,8 +9534,6 @@ static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { +@@ -9191,8 +9534,6 @@ static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x02, HDA_INPUT), HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), @@ -11145,7 +8534,7 @@ index 067e6ed..0fd258e 100644 HDA_CODEC_VOLUME("AUX IN Playback Volume", 0x0b, 0x06, HDA_INPUT), HDA_CODEC_MUTE("AUX IN Playback Switch", 0x0b, 0x06, HDA_INPUT), { } /* end */ -@@ -9168,8 +9562,6 @@ static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = { +@@ -9221,8 +9562,6 @@ static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = { HDA_CODEC_MUTE("Line Playback Switch", 0x0b, 0x01, HDA_INPUT), HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), @@ -11154,7 +8543,7 @@ index 067e6ed..0fd258e 100644 { } /* end */ }; -@@ -9317,6 +9709,67 @@ static struct snd_kcontrol_new alc262_benq_t31_mixer[] = { +@@ -9370,6 +9709,67 @@ static struct snd_kcontrol_new alc262_benq_t31_mixer[] = { { } /* end */ }; @@ -11222,7 +8611,7 @@ index 067e6ed..0fd258e 100644 #define alc262_capture_mixer alc882_capture_mixer #define alc262_capture_alt_mixer alc882_capture_alt_mixer -@@ -9445,20 +9898,6 @@ static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = { +@@ -9498,20 +9898,6 @@ static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = { 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), @@ -11243,7 +8632,7 @@ index 067e6ed..0fd258e 100644 { } /* end */ }; -@@ -9797,8 +10236,6 @@ static struct snd_kcontrol_new alc262_fujitsu_mixer[] = { +@@ -9850,8 +10236,6 @@ static struct snd_kcontrol_new alc262_fujitsu_mixer[] = { }, HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), @@ -11252,7 +8641,7 @@ index 067e6ed..0fd258e 100644 HDA_CODEC_VOLUME("Mic Boost", 0x18, 0, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), -@@ -9975,7 +10412,7 @@ static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol, +@@ -10028,7 +10412,7 @@ static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol, struct alc_spec *spec = codec->spec; int ret; @@ -11261,7 +8650,7 @@ index 067e6ed..0fd258e 100644 if (!ret) return 0; /* reprogram the HP pin as mic or HP according to the input source */ -@@ -9992,8 +10429,8 @@ static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = { +@@ -10045,8 +10429,8 @@ static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Capture Source", @@ -11272,7 +8661,7 @@ index 067e6ed..0fd258e 100644 .put = alc262_ultra_mux_enum_put, }, { } /* end */ -@@ -10370,8 +10807,14 @@ static int alc262_parse_auto_config(struct hda_codec *codec) +@@ -10423,8 +10807,14 @@ static int alc262_parse_auto_config(struct hda_codec *codec) alc262_ignore); if (err < 0) return err; @@ -11288,7 +8677,7 @@ index 067e6ed..0fd258e 100644 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg); if (err < 0) return err; -@@ -10381,23 +10824,25 @@ static int alc262_parse_auto_config(struct hda_codec *codec) +@@ -10434,23 +10824,25 @@ static int alc262_parse_auto_config(struct hda_codec *codec) spec->multiout.max_channels = spec->multiout.num_dacs * 2; @@ -11320,7 +8709,7 @@ index 067e6ed..0fd258e 100644 return 1; } -@@ -10439,20 +10884,19 @@ static const char *alc262_models[ALC262_MODEL_LAST] = { +@@ -10492,21 +10884,19 @@ static const char *alc262_models[ALC262_MODEL_LAST] = { [ALC262_ULTRA] = "ultra", [ALC262_LENOVO_3000] = "lenovo-3000", [ALC262_NEC] = "nec", @@ -11339,6 +8728,7 @@ index 067e6ed..0fd258e 100644 - SND_PCI_QUIRK(0x103c, 0x1309, "HP xw4*00", ALC262_HP_BPC), - SND_PCI_QUIRK(0x103c, 0x130a, "HP xw6*00", ALC262_HP_BPC), - SND_PCI_QUIRK(0x103c, 0x130b, "HP xw8*00", ALC262_HP_BPC), +- SND_PCI_QUIRK(0x103c, 0x170b, "HP xw*", ALC262_HP_BPC), + SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series", + ALC262_HP_BPC), + SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1300, "HP xw series", @@ -11348,7 +8738,7 @@ index 067e6ed..0fd258e 100644 SND_PCI_QUIRK(0x103c, 0x2800, "HP D7000", ALC262_HP_BPC_D7000_WL), SND_PCI_QUIRK(0x103c, 0x2801, "HP D7000", ALC262_HP_BPC_D7000_WF), SND_PCI_QUIRK(0x103c, 0x2802, "HP D7000", ALC262_HP_BPC_D7000_WL), -@@ -10470,17 +10914,17 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = { +@@ -10524,17 +10914,17 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = { SND_PCI_QUIRK(0x104d, 0x1f00, "Sony ASSAMD", ALC262_SONY_ASSAMD), SND_PCI_QUIRK(0x104d, 0x8203, "Sony UX-90", ALC262_HIPPO), SND_PCI_QUIRK(0x104d, 0x820f, "Sony ASSAMD", ALC262_SONY_ASSAMD), @@ -11372,7 +8762,7 @@ index 067e6ed..0fd258e 100644 SND_PCI_QUIRK(0x144d, 0xc510, "Samsung Q45", ALC262_HIPPO), SND_PCI_QUIRK(0x17aa, 0x384e, "Lenovo 3000 y410", ALC262_LENOVO_3000), SND_PCI_QUIRK(0x17ff, 0x0560, "Benq ED8", ALC262_BENQ_ED8), -@@ -10633,7 +11077,8 @@ static struct alc_config_preset alc262_presets[] = { +@@ -10687,7 +11077,8 @@ static struct alc_config_preset alc262_presets[] = { .init_hook = alc262_hippo_automute, }, [ALC262_ULTRA] = { @@ -11382,24 +8772,7 @@ index 067e6ed..0fd258e 100644 .init_verbs = { alc262_ultra_verbs }, .num_dacs = ARRAY_SIZE(alc262_dac_nids), .dac_nids = alc262_dac_nids, -@@ -10669,16 +11114,6 @@ static struct alc_config_preset alc262_presets[] = { - .channel_mode = alc262_modes, - .input_mux = &alc262_capture_source, - }, -- [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, -- }, - [ALC262_TOSHIBA_S06] = { - .mixers = { alc262_toshiba_s06_mixer }, - .init_verbs = { alc262_init_verbs, alc262_toshiba_s06_verbs, -@@ -10706,6 +11141,19 @@ static struct alc_config_preset alc262_presets[] = { +@@ -10750,6 +11141,19 @@ static struct alc_config_preset alc262_presets[] = { .unsol_event = alc262_hippo_unsol_event, .init_hook = alc262_hippo_automute, }, @@ -11419,7 +8792,7 @@ index 067e6ed..0fd258e 100644 }; static int patch_alc262(struct hda_codec *codec) -@@ -10758,6 +11206,14 @@ static int patch_alc262(struct hda_codec *codec) +@@ -10802,6 +11206,14 @@ static int patch_alc262(struct hda_codec *codec) } } @@ -11434,7 +8807,7 @@ index 067e6ed..0fd258e 100644 if (board_config != ALC262_AUTO) setup_preset(spec, &alc262_presets[board_config]); -@@ -10769,6 +11225,7 @@ static int patch_alc262(struct hda_codec *codec) +@@ -10813,6 +11225,7 @@ static int patch_alc262(struct hda_codec *codec) spec->stream_digital_playback = &alc262_pcm_digital_playback; spec->stream_digital_capture = &alc262_pcm_digital_capture; @@ -11442,7 +8815,7 @@ index 067e6ed..0fd258e 100644 if (!spec->adc_nids && spec->input_mux) { /* check whether NID 0x07 is valid */ unsigned int wcap = get_wcaps(codec, 0x07); -@@ -10779,17 +11236,16 @@ static int patch_alc262(struct hda_codec *codec) +@@ -10823,17 +11236,16 @@ static int patch_alc262(struct hda_codec *codec) spec->adc_nids = alc262_adc_nids_alt; spec->num_adc_nids = ARRAY_SIZE(alc262_adc_nids_alt); spec->capsrc_nids = alc262_capsrc_nids_alt; @@ -11464,7 +8837,7 @@ index 067e6ed..0fd258e 100644 spec->vmaster_nid = 0x0c; -@@ -10800,6 +11256,7 @@ static int patch_alc262(struct hda_codec *codec) +@@ -10844,6 +11256,7 @@ static int patch_alc262(struct hda_codec *codec) if (!spec->loopback.amplist) spec->loopback.amplist = alc262_loopbacks; #endif @@ -11472,7 +8845,7 @@ index 067e6ed..0fd258e 100644 return 0; } -@@ -11168,19 +11625,13 @@ static void alc267_quanta_il1_unsol_event(struct hda_codec *codec, +@@ -11212,19 +11625,13 @@ static void alc267_quanta_il1_unsol_event(struct hda_codec *codec, static struct hda_verb alc268_base_init_verbs[] = { /* Unmute DAC0-1 and set vol = 0 */ {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, @@ -11492,7 +8865,7 @@ index 067e6ed..0fd258e 100644 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x00}, {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, -@@ -11199,9 +11650,7 @@ static struct hda_verb alc268_base_init_verbs[] = { +@@ -11243,9 +11650,7 @@ static struct hda_verb alc268_base_init_verbs[] = { {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, @@ -11502,7 +8875,7 @@ index 067e6ed..0fd258e 100644 /* set PCBEEP vol = 0, mute connections */ {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, -@@ -11223,10 +11672,8 @@ static struct hda_verb alc268_base_init_verbs[] = { +@@ -11267,10 +11672,8 @@ static struct hda_verb alc268_base_init_verbs[] = { */ static struct hda_verb alc268_volume_init_verbs[] = { /* set output DAC */ @@ -11515,7 +8888,7 @@ index 067e6ed..0fd258e 100644 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, -@@ -11234,16 +11681,12 @@ static struct hda_verb alc268_volume_init_verbs[] = { +@@ -11278,16 +11681,12 @@ static struct hda_verb alc268_volume_init_verbs[] = { {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20}, @@ -11532,7 +8905,7 @@ index 067e6ed..0fd258e 100644 /* set PCBEEP vol = 0, mute connections */ {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, -@@ -11253,10 +11696,6 @@ static struct hda_verb alc268_volume_init_verbs[] = { +@@ -11297,10 +11696,6 @@ static struct hda_verb alc268_volume_init_verbs[] = { { } }; @@ -11543,7 +8916,7 @@ index 067e6ed..0fd258e 100644 static struct snd_kcontrol_new alc268_capture_alt_mixer[] = { HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), -@@ -11268,9 +11707,9 @@ static struct snd_kcontrol_new alc268_capture_alt_mixer[] = { +@@ -11312,9 +11707,9 @@ static struct snd_kcontrol_new alc268_capture_alt_mixer[] = { /* .name = "Capture Source", */ .name = "Input Source", .count = 1, @@ -11556,7 +8929,7 @@ index 067e6ed..0fd258e 100644 }, { } /* end */ }; -@@ -11288,9 +11727,9 @@ static struct snd_kcontrol_new alc268_capture_mixer[] = { +@@ -11332,9 +11727,9 @@ static struct snd_kcontrol_new alc268_capture_mixer[] = { /* .name = "Capture Source", */ .name = "Input Source", .count = 2, @@ -11569,7 +8942,7 @@ index 067e6ed..0fd258e 100644 }, { } /* end */ }; -@@ -11446,7 +11885,7 @@ static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec, +@@ -11490,7 +11885,7 @@ static int alc268_auto_create_multi_out_ctls(struct alc_spec *spec, static int alc268_auto_create_analog_input_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg) { @@ -11578,7 +8951,7 @@ index 067e6ed..0fd258e 100644 int i, idx1; for (i = 0; i < AUTO_PIN_LAST; i++) { -@@ -11540,9 +11979,14 @@ static int alc268_parse_auto_config(struct hda_codec *codec) +@@ -11584,9 +11979,14 @@ static int alc268_parse_auto_config(struct hda_codec *codec) alc268_ignore); if (err < 0) return err; @@ -11595,7 +8968,7 @@ index 067e6ed..0fd258e 100644 err = alc268_auto_create_multi_out_ctls(spec, &spec->autocfg); if (err < 0) return err; -@@ -11552,25 +11996,26 @@ static int alc268_parse_auto_config(struct hda_codec *codec) +@@ -11596,25 +11996,26 @@ static int alc268_parse_auto_config(struct hda_codec *codec) spec->multiout.max_channels = 2; @@ -11631,7 +9004,7 @@ index 067e6ed..0fd258e 100644 return 1; } -@@ -11617,7 +12062,9 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = { +@@ -11661,7 +12062,9 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = { SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One", ALC268_ACER_ASPIRE_ONE), SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL), @@ -11641,7 +9014,7 @@ index 067e6ed..0fd258e 100644 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), -@@ -11631,7 +12078,7 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = { +@@ -11675,7 +12078,7 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = { static struct alc_config_preset alc268_presets[] = { [ALC267_QUANTA_IL1] = { @@ -11650,7 +9023,7 @@ index 067e6ed..0fd258e 100644 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, alc267_quanta_il1_verbs }, .num_dacs = ARRAY_SIZE(alc268_dac_nids), -@@ -11713,7 +12160,8 @@ static struct alc_config_preset alc268_presets[] = { +@@ -11757,7 +12160,8 @@ static struct alc_config_preset alc268_presets[] = { }, [ALC268_ACER_ASPIRE_ONE] = { .mixers = { alc268_acer_aspire_one_mixer, @@ -11660,7 +9033,7 @@ index 067e6ed..0fd258e 100644 .init_verbs = { alc268_base_init_verbs, alc268_eapd_verbs, alc268_acer_aspire_one_verbs }, .num_dacs = ARRAY_SIZE(alc268_dac_nids), -@@ -11782,7 +12230,7 @@ static int patch_alc268(struct hda_codec *codec) +@@ -11826,7 +12230,7 @@ static int patch_alc268(struct hda_codec *codec) { struct alc_spec *spec; int board_config; @@ -11669,7 +9042,7 @@ index 067e6ed..0fd258e 100644 spec = kcalloc(1, sizeof(*spec), GFP_KERNEL); if (spec == NULL) -@@ -11831,15 +12279,30 @@ static int patch_alc268(struct hda_codec *codec) +@@ -11875,15 +12279,30 @@ static int patch_alc268(struct hda_codec *codec) spec->stream_digital_playback = &alc268_pcm_digital_playback; @@ -11704,7 +9077,7 @@ index 067e6ed..0fd258e 100644 /* check whether NID 0x07 is valid */ unsigned int wcap = get_wcaps(codec, 0x07); int i; -@@ -11849,15 +12312,11 @@ static int patch_alc268(struct hda_codec *codec) +@@ -11893,15 +12312,11 @@ static int patch_alc268(struct hda_codec *codec) if (wcap != AC_WID_AUD_IN || spec->input_mux->num_items == 1) { spec->adc_nids = alc268_adc_nids_alt; spec->num_adc_nids = ARRAY_SIZE(alc268_adc_nids_alt); @@ -11722,7 +9095,7 @@ index 067e6ed..0fd258e 100644 } spec->capsrc_nids = alc268_capsrc_nids; /* set default input source */ -@@ -11873,6 +12332,8 @@ static int patch_alc268(struct hda_codec *codec) +@@ -11917,6 +12332,8 @@ static int patch_alc268(struct hda_codec *codec) if (board_config == ALC268_AUTO) spec->init_hook = alc268_auto_init; @@ -11731,7 +9104,7 @@ index 067e6ed..0fd258e 100644 return 0; } -@@ -11922,8 +12383,6 @@ static struct snd_kcontrol_new alc269_base_mixer[] = { +@@ -11966,8 +12383,6 @@ 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), @@ -11740,7 +9113,7 @@ index 067e6ed..0fd258e 100644 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), -@@ -11950,8 +12409,29 @@ static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = { +@@ -11994,8 +12409,29 @@ static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = { 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), @@ -11772,7 +9145,7 @@ index 067e6ed..0fd258e 100644 { } }; -@@ -11973,25 +12453,6 @@ static struct snd_kcontrol_new alc269_eeepc_mixer[] = { +@@ -12017,25 +12453,6 @@ static struct snd_kcontrol_new alc269_eeepc_mixer[] = { }; /* capture mixer elements */ @@ -11798,7 +9171,7 @@ index 067e6ed..0fd258e 100644 static struct snd_kcontrol_new alc269_epc_capture_mixer[] = { HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), -@@ -12007,18 +12468,25 @@ static struct snd_kcontrol_new alc269_fujitsu_mixer[] = { +@@ -12051,18 +12468,25 @@ static struct snd_kcontrol_new alc269_fujitsu_mixer[] = { { } /* end */ }; @@ -11830,7 +9203,7 @@ index 067e6ed..0fd258e 100644 {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, { } -@@ -12049,6 +12517,37 @@ static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec) +@@ -12093,6 +12517,37 @@ static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec) AC_VERB_SET_PROC_COEF, 0x480); } @@ -11868,7 +9241,7 @@ index 067e6ed..0fd258e 100644 static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec) { unsigned int present; -@@ -12059,6 +12558,29 @@ static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec) +@@ -12103,6 +12558,29 @@ static void alc269_quanta_fl1_mic_automute(struct hda_codec *codec) AC_VERB_SET_CONNECT_SEL, present ? 0x0 : 0x1); } @@ -11898,7 +9271,7 @@ index 067e6ed..0fd258e 100644 static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec, unsigned int res) { -@@ -12068,12 +12590,27 @@ static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec, +@@ -12112,12 +12590,27 @@ static void alc269_quanta_fl1_unsol_event(struct hda_codec *codec, alc269_quanta_fl1_mic_automute(codec); } @@ -11926,7 +9299,7 @@ index 067e6ed..0fd258e 100644 static struct hda_verb alc269_eeepc_dmic_init_verbs[] = { {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, {0x23, AC_VERB_SET_CONNECT_SEL, 0x05}, -@@ -12330,7 +12867,7 @@ static int alc269_auto_create_analog_input_ctls(struct alc_spec *spec, +@@ -12374,7 +12867,7 @@ static int alc269_auto_create_analog_input_ctls(struct alc_spec *spec, */ if (cfg->input_pins[AUTO_PIN_MIC] == 0x12 || cfg->input_pins[AUTO_PIN_FRONT_MIC] == 0x12) { @@ -11935,34 +9308,7 @@ index 067e6ed..0fd258e 100644 imux->items[imux->num_items].label = "Int Mic"; imux->items[imux->num_items].index = 0x05; imux->num_items++; -@@ -12348,13 +12885,34 @@ static int alc269_auto_create_analog_input_ctls(struct alc_spec *spec, - #define alc269_pcm_digital_playback alc880_pcm_digital_playback - #define alc269_pcm_digital_capture alc880_pcm_digital_capture - -+static struct hda_pcm_stream alc269_44k_pcm_analog_playback = { -+ .substreams = 1, -+ .channels_min = 2, -+ .channels_max = 8, -+ .rates = SNDRV_PCM_RATE_44100, /* fixed rate */ -+ /* NID is set in alc_build_pcms */ -+ .ops = { -+ .open = alc880_playback_pcm_open, -+ .prepare = alc880_playback_pcm_prepare, -+ .cleanup = alc880_playback_pcm_cleanup -+ }, -+}; -+ -+static struct hda_pcm_stream alc269_44k_pcm_analog_capture = { -+ .substreams = 1, -+ .channels_min = 2, -+ .channels_max = 2, -+ .rates = SNDRV_PCM_RATE_44100, /* fixed rate */ -+ /* NID is set in alc_build_pcms */ -+}; -+ - /* - * BIOS auto configuration - */ +@@ -12419,7 +12912,7 @@ static struct hda_pcm_stream alc269_44k_pcm_analog_capture = { static int alc269_parse_auto_config(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; @@ -11971,7 +9317,7 @@ index 067e6ed..0fd258e 100644 static hda_nid_t alc269_ignore[] = { 0x1d, 0 }; err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, -@@ -12371,22 +12929,15 @@ static int alc269_parse_auto_config(struct hda_codec *codec) +@@ -12436,22 +12929,15 @@ static int alc269_parse_auto_config(struct hda_codec *codec) spec->multiout.max_channels = spec->multiout.num_dacs * 2; @@ -11981,16 +9327,16 @@ index 067e6ed..0fd258e 100644 - if (spec->kctl_alloc) - spec->mixers[spec->num_mixers++] = spec->kctl_alloc; -- ++ if (spec->kctls.list) ++ add_mixer(spec, spec->kctls.list); + - /* 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; -+ if (spec->kctls.list) -+ add_mixer(spec, spec->kctls.list); - +- - spec->init_verbs[spec->num_init_verbs++] = alc269_init_verbs; + add_verb(spec, alc269_init_verbs); spec->num_mux_defs = 1; @@ -11999,7 +9345,7 @@ index 067e6ed..0fd258e 100644 /* set default input source */ snd_hda_codec_write_cache(codec, alc269_capsrc_nids[0], 0, AC_VERB_SET_CONNECT_SEL, -@@ -12396,10 +12947,9 @@ static int alc269_parse_auto_config(struct hda_codec *codec) +@@ -12461,10 +12947,9 @@ static int alc269_parse_auto_config(struct hda_codec *codec) if (err < 0) return err; @@ -12012,7 +9358,7 @@ index 067e6ed..0fd258e 100644 return 1; } -@@ -12427,24 +12977,33 @@ static const char *alc269_models[ALC269_MODEL_LAST] = { +@@ -12492,24 +12977,33 @@ static const char *alc269_models[ALC269_MODEL_LAST] = { [ALC269_QUANTA_FL1] = "quanta", [ALC269_ASUS_EEEPC_P703] = "eeepc-p703", [ALC269_ASUS_EEEPC_P901] = "eeepc-p901", @@ -12048,7 +9394,7 @@ index 067e6ed..0fd258e 100644 .init_verbs = { alc269_init_verbs }, .num_dacs = ARRAY_SIZE(alc269_dac_nids), .dac_nids = alc269_dac_nids, -@@ -12466,7 +13025,8 @@ static struct alc_config_preset alc269_presets[] = { +@@ -12531,7 +13025,8 @@ static struct alc_config_preset alc269_presets[] = { .init_hook = alc269_quanta_fl1_init_hook, }, [ALC269_ASUS_EEEPC_P703] = { @@ -12058,7 +9404,7 @@ index 067e6ed..0fd258e 100644 .init_verbs = { alc269_init_verbs, alc269_eeepc_amic_init_verbs }, .num_dacs = ARRAY_SIZE(alc269_dac_nids), -@@ -12479,7 +13039,8 @@ static struct alc_config_preset alc269_presets[] = { +@@ -12544,7 +13039,8 @@ static struct alc_config_preset alc269_presets[] = { .init_hook = alc269_eeepc_amic_inithook, }, [ALC269_ASUS_EEEPC_P901] = { @@ -12068,7 +9414,7 @@ index 067e6ed..0fd258e 100644 .init_verbs = { alc269_init_verbs, alc269_eeepc_dmic_init_verbs }, .num_dacs = ARRAY_SIZE(alc269_dac_nids), -@@ -12492,8 +13053,8 @@ static struct alc_config_preset alc269_presets[] = { +@@ -12557,8 +13053,8 @@ static struct alc_config_preset alc269_presets[] = { .init_hook = alc269_eeepc_dmic_inithook, }, [ALC269_FUJITSU] = { @@ -12079,7 +9425,7 @@ index 067e6ed..0fd258e 100644 .init_verbs = { alc269_init_verbs, alc269_eeepc_dmic_init_verbs }, .num_dacs = ARRAY_SIZE(alc269_dac_nids), -@@ -12505,6 +13066,18 @@ static struct alc_config_preset alc269_presets[] = { +@@ -12570,6 +13066,18 @@ static struct alc_config_preset alc269_presets[] = { .unsol_event = alc269_eeepc_dmic_unsol_event, .init_hook = alc269_eeepc_dmic_inithook, }, @@ -12098,7 +9444,7 @@ index 067e6ed..0fd258e 100644 }; static int patch_alc269(struct hda_codec *codec) -@@ -12545,13 +13118,26 @@ static int patch_alc269(struct hda_codec *codec) +@@ -12610,6 +13118,12 @@ static int patch_alc269(struct hda_codec *codec) } } @@ -12111,24 +9457,7 @@ index 067e6ed..0fd258e 100644 if (board_config != ALC269_AUTO) setup_preset(spec, &alc269_presets[board_config]); - spec->stream_name_analog = "ALC269 Analog"; -- spec->stream_analog_playback = &alc269_pcm_analog_playback; -- spec->stream_analog_capture = &alc269_pcm_analog_capture; -- -+ if (codec->subsystem_id == 0x17aa3bf8) { -+ /* Due to a hardware problem on Lenovo Ideadpad, we need to -+ * fix the sample rate of analog I/O to 44.1kHz -+ */ -+ spec->stream_analog_playback = &alc269_44k_pcm_analog_playback; -+ spec->stream_analog_capture = &alc269_44k_pcm_analog_capture; -+ } else { -+ spec->stream_analog_playback = &alc269_pcm_analog_playback; -+ spec->stream_analog_capture = &alc269_pcm_analog_capture; -+ } - spec->stream_name_digital = "ALC269 Digital"; - spec->stream_digital_playback = &alc269_pcm_digital_playback; - spec->stream_digital_capture = &alc269_pcm_digital_capture; -@@ -12559,6 +13145,9 @@ static int patch_alc269(struct hda_codec *codec) +@@ -12631,6 +13145,9 @@ 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; @@ -12138,7 +9467,7 @@ index 067e6ed..0fd258e 100644 codec->patch_ops = alc_patch_ops; if (board_config == ALC269_AUTO) -@@ -12567,6 +13156,7 @@ static int patch_alc269(struct hda_codec *codec) +@@ -12639,6 +13156,7 @@ static int patch_alc269(struct hda_codec *codec) if (!spec->loopback.amplist) spec->loopback.amplist = alc269_loopbacks; #endif @@ -12146,7 +9475,7 @@ index 067e6ed..0fd258e 100644 return 0; } -@@ -12699,17 +13289,6 @@ static struct snd_kcontrol_new alc861_base_mixer[] = { +@@ -12771,17 +13289,6 @@ static struct snd_kcontrol_new alc861_base_mixer[] = { HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), @@ -12164,7 +9493,7 @@ index 067e6ed..0fd258e 100644 { } /* end */ }; -@@ -12733,17 +13312,6 @@ static struct snd_kcontrol_new alc861_3ST_mixer[] = { +@@ -12805,17 +13312,6 @@ static struct snd_kcontrol_new alc861_3ST_mixer[] = { HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), @@ -12182,7 +9511,7 @@ index 067e6ed..0fd258e 100644 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Channel Mode", -@@ -12761,18 +13329,6 @@ static struct snd_kcontrol_new alc861_toshiba_mixer[] = { +@@ -12833,18 +13329,6 @@ static struct snd_kcontrol_new alc861_toshiba_mixer[] = { HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x15, 0x01, HDA_INPUT), @@ -12201,7 +9530,7 @@ index 067e6ed..0fd258e 100644 { } /* end */ }; -@@ -12796,17 +13352,6 @@ static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { +@@ -12868,17 +13352,6 @@ static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_INPUT), @@ -12219,7 +9548,7 @@ index 067e6ed..0fd258e 100644 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Channel Mode", -@@ -12838,17 +13383,6 @@ static struct snd_kcontrol_new alc861_asus_mixer[] = { +@@ -12910,17 +13383,6 @@ static struct snd_kcontrol_new alc861_asus_mixer[] = { HDA_CODEC_MUTE("Front Mic Playback Switch", 0x10, 0x01, HDA_OUTPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x03, HDA_OUTPUT), @@ -12237,7 +9566,7 @@ index 067e6ed..0fd258e 100644 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Channel Mode", -@@ -12864,8 +13398,6 @@ static struct snd_kcontrol_new alc861_asus_mixer[] = { +@@ -12936,8 +13398,6 @@ static struct snd_kcontrol_new alc861_asus_mixer[] = { static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = { HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), @@ -12246,7 +9575,7 @@ index 067e6ed..0fd258e 100644 { } }; -@@ -13339,7 +13871,7 @@ static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin) +@@ -13411,7 +13871,7 @@ static int alc861_auto_create_hp_ctls(struct alc_spec *spec, hda_nid_t pin) static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, const struct auto_pin_cfg *cfg) { @@ -12255,7 +9584,7 @@ index 067e6ed..0fd258e 100644 int i, err, idx, idx1; for (i = 0; i < AUTO_PIN_LAST; i++) { -@@ -13380,25 +13912,6 @@ static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, +@@ -13452,25 +13912,6 @@ static int alc861_auto_create_analog_input_ctls(struct alc_spec *spec, return 0; } @@ -12281,7 +9610,7 @@ index 067e6ed..0fd258e 100644 static void alc861_auto_set_output_and_unmute(struct hda_codec *codec, hda_nid_t nid, int pin_type, int dac_idx) -@@ -13445,12 +13958,8 @@ static void alc861_auto_init_analog_input(struct hda_codec *codec) +@@ -13517,12 +13958,8 @@ static void alc861_auto_init_analog_input(struct hda_codec *codec) for (i = 0; i < AUTO_PIN_LAST; i++) { hda_nid_t nid = spec->autocfg.input_pins[i]; @@ -12296,7 +9625,7 @@ index 067e6ed..0fd258e 100644 } } -@@ -13486,23 +13995,21 @@ static int alc861_parse_auto_config(struct hda_codec *codec) +@@ -13558,23 +13995,21 @@ static int alc861_parse_auto_config(struct hda_codec *codec) spec->multiout.max_channels = spec->multiout.num_dacs * 2; @@ -12326,7 +9655,7 @@ index 067e6ed..0fd258e 100644 return 1; } -@@ -13711,6 +14218,12 @@ static int patch_alc861(struct hda_codec *codec) +@@ -13783,6 +14218,12 @@ static int patch_alc861(struct hda_codec *codec) } } @@ -12339,7 +9668,7 @@ index 067e6ed..0fd258e 100644 if (board_config != ALC861_AUTO) setup_preset(spec, &alc861_presets[board_config]); -@@ -13722,6 +14235,8 @@ static int patch_alc861(struct hda_codec *codec) +@@ -13794,6 +14235,8 @@ static int patch_alc861(struct hda_codec *codec) spec->stream_digital_playback = &alc861_pcm_digital_playback; spec->stream_digital_capture = &alc861_pcm_digital_capture; @@ -12348,7 +9677,7 @@ index 067e6ed..0fd258e 100644 spec->vmaster_nid = 0x03; codec->patch_ops = alc_patch_ops; -@@ -13731,6 +14246,7 @@ static int patch_alc861(struct hda_codec *codec) +@@ -13803,6 +14246,7 @@ static int patch_alc861(struct hda_codec *codec) if (!spec->loopback.amplist) spec->loopback.amplist = alc861_loopbacks; #endif @@ -12356,7 +9685,7 @@ index 067e6ed..0fd258e 100644 return 0; } -@@ -13796,11 +14312,6 @@ static struct hda_input_mux alc861vd_hp_capture_source = { +@@ -13868,11 +14312,6 @@ static struct hda_input_mux alc861vd_hp_capture_source = { }, }; @@ -12368,7 +9697,7 @@ index 067e6ed..0fd258e 100644 /* * 2ch mode */ -@@ -13846,25 +14357,6 @@ static struct snd_kcontrol_new alc861vd_chmode_mixer[] = { +@@ -13918,25 +14357,6 @@ static struct snd_kcontrol_new alc861vd_chmode_mixer[] = { { } /* end */ }; @@ -12394,7 +9723,7 @@ index 067e6ed..0fd258e 100644 /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b */ -@@ -13901,9 +14393,6 @@ static struct snd_kcontrol_new alc861vd_6st_mixer[] = { +@@ -13973,9 +14393,6 @@ static struct snd_kcontrol_new alc861vd_6st_mixer[] = { HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), @@ -12404,7 +9733,7 @@ index 067e6ed..0fd258e 100644 { } /* end */ }; -@@ -13927,9 +14416,6 @@ static struct snd_kcontrol_new alc861vd_3st_mixer[] = { +@@ -13999,9 +14416,6 @@ static struct snd_kcontrol_new alc861vd_3st_mixer[] = { HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), @@ -12414,7 +9743,7 @@ index 067e6ed..0fd258e 100644 { } /* end */ }; -@@ -13968,8 +14454,6 @@ static struct snd_kcontrol_new alc861vd_dallas_mixer[] = { +@@ -14040,8 +14454,6 @@ static struct snd_kcontrol_new alc861vd_dallas_mixer[] = { HDA_CODEC_VOLUME("Int Mic Boost", 0x19, 0, HDA_INPUT), HDA_CODEC_VOLUME("Int Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), HDA_CODEC_MUTE("Int Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), @@ -12423,7 +9752,7 @@ index 067e6ed..0fd258e 100644 { } /* end */ }; -@@ -14256,6 +14740,7 @@ static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int re +@@ -14328,6 +14740,7 @@ static void alc861vd_dallas_unsol_event(struct hda_codec *codec, unsigned int re static const char *alc861vd_models[ALC861VD_MODEL_LAST] = { [ALC660VD_3ST] = "3stack-660", [ALC660VD_3ST_DIG] = "3stack-660-digout", @@ -12431,7 +9760,7 @@ index 067e6ed..0fd258e 100644 [ALC861VD_3ST] = "3stack", [ALC861VD_3ST_DIG] = "3stack-digout", [ALC861VD_6ST_DIG] = "6stack-digout", -@@ -14270,7 +14755,7 @@ static struct snd_pci_quirk alc861vd_cfg_tbl[] = { +@@ -14342,7 +14755,7 @@ static struct snd_pci_quirk alc861vd_cfg_tbl[] = { SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP), SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST), SND_PCI_QUIRK(0x1043, 0x1339, "Asus G1", ALC660VD_3ST), @@ -12440,7 +9769,7 @@ index 067e6ed..0fd258e 100644 SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS", ALC660VD_3ST_DIG), SND_PCI_QUIRK(0x10de, 0x03f0, "Realtek ALC660 demo", ALC660VD_3ST), SND_PCI_QUIRK(0x1179, 0xff00, "Toshiba A135", ALC861VD_LENOVO), -@@ -14279,9 +14764,7 @@ static struct snd_pci_quirk alc861vd_cfg_tbl[] = { +@@ -14351,9 +14764,7 @@ static struct snd_pci_quirk alc861vd_cfg_tbl[] = { SND_PCI_QUIRK(0x1179, 0xff03, "Toshiba P205", ALC861VD_LENOVO), SND_PCI_QUIRK(0x1179, 0xff31, "Toshiba L30-149", ALC861VD_DALLAS), SND_PCI_QUIRK(0x1565, 0x820d, "Biostar NF61S SE", ALC861VD_6ST_DIG), @@ -12451,7 +9780,7 @@ index 067e6ed..0fd258e 100644 SND_PCI_QUIRK(0x1849, 0x0862, "ASRock K8NF6G-VSTA", ALC861VD_6ST_DIG), {} }; -@@ -14377,6 +14860,21 @@ static struct alc_config_preset alc861vd_presets[] = { +@@ -14449,6 +14860,21 @@ static struct alc_config_preset alc861vd_presets[] = { .unsol_event = alc861vd_dallas_unsol_event, .init_hook = alc861vd_dallas_automute, }, @@ -12473,7 +9802,7 @@ index 067e6ed..0fd258e 100644 }; /* -@@ -14428,11 +14926,9 @@ static void alc861vd_auto_init_analog_input(struct hda_codec *codec) +@@ -14500,11 +14926,9 @@ static void alc861vd_auto_init_analog_input(struct hda_codec *codec) for (i = 0; i < AUTO_PIN_LAST; i++) { hda_nid_t nid = spec->autocfg.input_pins[i]; if (alc861vd_is_input_pin(nid)) { @@ -12488,7 +9817,7 @@ index 067e6ed..0fd258e 100644 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); -@@ -14598,23 +15094,21 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec) +@@ -14670,23 +15094,21 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec) spec->multiout.max_channels = spec->multiout.num_dacs * 2; @@ -12517,7 +9846,7 @@ index 067e6ed..0fd258e 100644 return 1; } -@@ -14665,6 +15159,12 @@ static int patch_alc861vd(struct hda_codec *codec) +@@ -14737,6 +15159,12 @@ static int patch_alc861vd(struct hda_codec *codec) } } @@ -12530,7 +9859,7 @@ index 067e6ed..0fd258e 100644 if (board_config != ALC861VD_AUTO) setup_preset(spec, &alc861vd_presets[board_config]); -@@ -14672,7 +15172,7 @@ static int patch_alc861vd(struct hda_codec *codec) +@@ -14744,7 +15172,7 @@ static int patch_alc861vd(struct hda_codec *codec) spec->stream_name_analog = "ALC660-VD Analog"; spec->stream_name_digital = "ALC660-VD Digital"; /* always turn on EAPD */ @@ -12539,7 +9868,7 @@ index 067e6ed..0fd258e 100644 } else { spec->stream_name_analog = "ALC861VD Analog"; spec->stream_name_digital = "ALC861VD Digital"; -@@ -14687,9 +15187,10 @@ static int patch_alc861vd(struct hda_codec *codec) +@@ -14759,9 +15187,10 @@ static int patch_alc861vd(struct hda_codec *codec) spec->adc_nids = alc861vd_adc_nids; spec->num_adc_nids = ARRAY_SIZE(alc861vd_adc_nids); spec->capsrc_nids = alc861vd_capsrc_nids; @@ -12552,7 +9881,7 @@ index 067e6ed..0fd258e 100644 spec->vmaster_nid = 0x02; -@@ -14701,6 +15202,7 @@ static int patch_alc861vd(struct hda_codec *codec) +@@ -14773,6 +15202,7 @@ static int patch_alc861vd(struct hda_codec *codec) if (!spec->loopback.amplist) spec->loopback.amplist = alc861vd_loopbacks; #endif @@ -12560,7 +9889,7 @@ index 067e6ed..0fd258e 100644 return 0; } -@@ -14724,12 +15226,23 @@ static hda_nid_t alc662_dac_nids[4] = { +@@ -14796,12 +15226,23 @@ static hda_nid_t alc662_dac_nids[4] = { 0x02, 0x03, 0x04 }; @@ -12584,7 +9913,7 @@ index 067e6ed..0fd258e 100644 /* input MUX */ /* FIXME: should be a matrix-type input source selection */ -@@ -14776,10 +15289,6 @@ static struct hda_input_mux alc663_m51va_capture_source = { +@@ -14848,10 +15289,6 @@ static struct hda_input_mux alc663_m51va_capture_source = { }, }; @@ -12595,7 +9924,7 @@ index 067e6ed..0fd258e 100644 /* * 2ch mode */ -@@ -14881,8 +15390,6 @@ static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = { +@@ -14953,8 +15390,6 @@ static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = { HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), @@ -12604,7 +9933,7 @@ index 067e6ed..0fd258e 100644 { } /* end */ }; -@@ -14904,8 +15411,6 @@ static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = { +@@ -14976,8 +15411,6 @@ static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = { HDA_CODEC_MUTE("Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), HDA_CODEC_MUTE("Front Mic Playback Switch", 0x0b, 0x1, HDA_INPUT), @@ -12613,7 +9942,7 @@ index 067e6ed..0fd258e 100644 { } /* end */ }; -@@ -15163,14 +15668,7 @@ static struct hda_verb alc662_init_verbs[] = { +@@ -15235,14 +15668,7 @@ static struct hda_verb alc662_init_verbs[] = { /* Mixer elements: 0x18, 19, 1a, 1b, 1c, 1d, 14, 15, 16, 17, 0b */ /* Input mixer */ {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, @@ -12628,7 +9957,7 @@ index 067e6ed..0fd258e 100644 /* always trun on EAPD */ {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, -@@ -15365,23 +15863,34 @@ static struct hda_verb alc662_ecs_init_verbs[] = { +@@ -15437,23 +15863,34 @@ static struct hda_verb alc662_ecs_init_verbs[] = { {} }; @@ -12680,7 +10009,7 @@ index 067e6ed..0fd258e 100644 }; static struct snd_kcontrol_new alc662_auto_capture_mixer[] = { -@@ -15390,6 +15899,12 @@ static struct snd_kcontrol_new alc662_auto_capture_mixer[] = { +@@ -15462,6 +15899,12 @@ static struct snd_kcontrol_new alc662_auto_capture_mixer[] = { { } /* end */ }; @@ -12693,7 +10022,7 @@ index 067e6ed..0fd258e 100644 static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec) { unsigned int present; -@@ -15900,62 +16415,74 @@ static const char *alc662_models[ALC662_MODEL_LAST] = { +@@ -15972,47 +16415,59 @@ static const char *alc662_models[ALC662_MODEL_LAST] = { }; static struct snd_pci_quirk alc662_cfg_tbl[] = { @@ -12778,14 +10107,13 @@ index 067e6ed..0fd258e 100644 + SND_PCI_QUIRK(0x105b, 0x0cd6, "Foxconn", ALC662_ECS), 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), 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(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA), -+ SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E), +@@ -16020,15 +16475,14 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = { + SND_PCI_QUIRK(0x17aa, 0x101e, "Lenovo", ALC662_LENOVO_101E), 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), @@ -12803,7 +10131,7 @@ index 067e6ed..0fd258e 100644 .init_verbs = { alc662_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .dac_nids = alc662_dac_nids, -@@ -15966,8 +16493,7 @@ static struct alc_config_preset alc662_presets[] = { +@@ -16039,8 +16493,7 @@ static struct alc_config_preset alc662_presets[] = { .input_mux = &alc662_capture_source, }, [ALC662_3ST_6ch_DIG] = { @@ -12813,7 +10141,7 @@ index 067e6ed..0fd258e 100644 .init_verbs = { alc662_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .dac_nids = alc662_dac_nids, -@@ -15979,8 +16505,7 @@ static struct alc_config_preset alc662_presets[] = { +@@ -16052,8 +16505,7 @@ static struct alc_config_preset alc662_presets[] = { .input_mux = &alc662_capture_source, }, [ALC662_3ST_6ch] = { @@ -12823,7 +10151,7 @@ index 067e6ed..0fd258e 100644 .init_verbs = { alc662_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .dac_nids = alc662_dac_nids, -@@ -15990,8 +16515,7 @@ static struct alc_config_preset alc662_presets[] = { +@@ -16063,8 +16515,7 @@ static struct alc_config_preset alc662_presets[] = { .input_mux = &alc662_capture_source, }, [ALC662_5ST_DIG] = { @@ -12833,7 +10161,7 @@ index 067e6ed..0fd258e 100644 .init_verbs = { alc662_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .dac_nids = alc662_dac_nids, -@@ -16002,7 +16526,7 @@ static struct alc_config_preset alc662_presets[] = { +@@ -16075,7 +16526,7 @@ static struct alc_config_preset alc662_presets[] = { .input_mux = &alc662_capture_source, }, [ALC662_LENOVO_101E] = { @@ -12842,7 +10170,7 @@ index 067e6ed..0fd258e 100644 .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .dac_nids = alc662_dac_nids, -@@ -16013,7 +16537,7 @@ static struct alc_config_preset alc662_presets[] = { +@@ -16086,7 +16537,7 @@ static struct alc_config_preset alc662_presets[] = { .init_hook = alc662_lenovo_101e_all_automute, }, [ALC662_ASUS_EEEPC_P701] = { @@ -12851,7 +10179,7 @@ index 067e6ed..0fd258e 100644 .init_verbs = { alc662_init_verbs, alc662_eeepc_sue_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), -@@ -16025,7 +16549,7 @@ static struct alc_config_preset alc662_presets[] = { +@@ -16098,7 +16549,7 @@ static struct alc_config_preset alc662_presets[] = { .init_hook = alc662_eeepc_inithook, }, [ALC662_ASUS_EEEPC_EP20] = { @@ -12860,7 +10188,7 @@ index 067e6ed..0fd258e 100644 alc662_chmode_mixer }, .init_verbs = { alc662_init_verbs, alc662_eeepc_ep20_sue_init_verbs }, -@@ -16038,7 +16562,7 @@ static struct alc_config_preset alc662_presets[] = { +@@ -16111,7 +16562,7 @@ static struct alc_config_preset alc662_presets[] = { .init_hook = alc662_eeepc_ep20_inithook, }, [ALC662_ECS] = { @@ -12869,7 +10197,7 @@ index 067e6ed..0fd258e 100644 .init_verbs = { alc662_init_verbs, alc662_ecs_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), -@@ -16050,7 +16574,7 @@ static struct alc_config_preset alc662_presets[] = { +@@ -16123,7 +16574,7 @@ static struct alc_config_preset alc662_presets[] = { .init_hook = alc662_eeepc_inithook, }, [ALC663_ASUS_M51VA] = { @@ -12878,7 +10206,7 @@ index 067e6ed..0fd258e 100644 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .dac_nids = alc662_dac_nids, -@@ -16062,7 +16586,7 @@ static struct alc_config_preset alc662_presets[] = { +@@ -16135,7 +16586,7 @@ static struct alc_config_preset alc662_presets[] = { .init_hook = alc663_m51va_inithook, }, [ALC663_ASUS_G71V] = { @@ -12887,7 +10215,7 @@ index 067e6ed..0fd258e 100644 .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .dac_nids = alc662_dac_nids, -@@ -16074,7 +16598,7 @@ static struct alc_config_preset alc662_presets[] = { +@@ -16147,7 +16598,7 @@ static struct alc_config_preset alc662_presets[] = { .init_hook = alc663_g71v_inithook, }, [ALC663_ASUS_H13] = { @@ -12896,7 +10224,7 @@ index 067e6ed..0fd258e 100644 .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .dac_nids = alc662_dac_nids, -@@ -16085,7 +16609,7 @@ static struct alc_config_preset alc662_presets[] = { +@@ -16158,7 +16609,7 @@ static struct alc_config_preset alc662_presets[] = { .init_hook = alc663_m51va_inithook, }, [ALC663_ASUS_G50V] = { @@ -12905,7 +10233,7 @@ index 067e6ed..0fd258e 100644 .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .dac_nids = alc662_dac_nids, -@@ -16097,7 +16621,8 @@ static struct alc_config_preset alc662_presets[] = { +@@ -16170,7 +16621,8 @@ static struct alc_config_preset alc662_presets[] = { .init_hook = alc663_g50v_inithook, }, [ALC663_ASUS_MODE1] = { @@ -12915,7 +10243,7 @@ index 067e6ed..0fd258e 100644 .init_verbs = { alc662_init_verbs, alc663_21jd_amic_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), -@@ -16111,7 +16636,8 @@ static struct alc_config_preset alc662_presets[] = { +@@ -16184,7 +16636,8 @@ static struct alc_config_preset alc662_presets[] = { .init_hook = alc663_mode1_inithook, }, [ALC662_ASUS_MODE2] = { @@ -12925,7 +10253,7 @@ index 067e6ed..0fd258e 100644 .init_verbs = { alc662_init_verbs, alc662_1bjd_amic_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), -@@ -16124,7 +16650,8 @@ static struct alc_config_preset alc662_presets[] = { +@@ -16197,7 +16650,8 @@ static struct alc_config_preset alc662_presets[] = { .init_hook = alc662_mode2_inithook, }, [ALC663_ASUS_MODE3] = { @@ -12935,7 +10263,7 @@ index 067e6ed..0fd258e 100644 .init_verbs = { alc662_init_verbs, alc663_two_hp_amic_m1_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), -@@ -16138,8 +16665,8 @@ static struct alc_config_preset alc662_presets[] = { +@@ -16211,8 +16665,8 @@ static struct alc_config_preset alc662_presets[] = { .init_hook = alc663_mode3_inithook, }, [ALC663_ASUS_MODE4] = { @@ -12946,7 +10274,7 @@ index 067e6ed..0fd258e 100644 .init_verbs = { alc662_init_verbs, alc663_21jd_amic_init_verbs}, .num_dacs = ARRAY_SIZE(alc662_dac_nids), -@@ -16153,8 +16680,8 @@ static struct alc_config_preset alc662_presets[] = { +@@ -16226,8 +16680,8 @@ static struct alc_config_preset alc662_presets[] = { .init_hook = alc663_mode4_inithook, }, [ALC663_ASUS_MODE5] = { @@ -12957,7 +10285,7 @@ index 067e6ed..0fd258e 100644 .init_verbs = { alc662_init_verbs, alc663_15jd_amic_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), -@@ -16168,7 +16695,8 @@ static struct alc_config_preset alc662_presets[] = { +@@ -16241,7 +16695,8 @@ static struct alc_config_preset alc662_presets[] = { .init_hook = alc663_mode5_inithook, }, [ALC663_ASUS_MODE6] = { @@ -12967,7 +10295,7 @@ index 067e6ed..0fd258e 100644 .init_verbs = { alc662_init_verbs, alc663_two_hp_amic_m2_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), -@@ -16181,6 +16709,36 @@ static struct alc_config_preset alc662_presets[] = { +@@ -16254,6 +16709,36 @@ static struct alc_config_preset alc662_presets[] = { .unsol_event = alc663_mode6_unsol_event, .init_hook = alc663_mode6_inithook, }, @@ -13004,7 +10332,7 @@ index 067e6ed..0fd258e 100644 }; -@@ -16268,7 +16826,7 @@ static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, +@@ -16341,7 +16826,7 @@ static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, if (alc880_is_fixed_pin(pin)) { nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); @@ -13013,7 +10341,7 @@ index 067e6ed..0fd258e 100644 /* specify the DAC as the extra output */ if (!spec->multiout.hp_nid) spec->multiout.hp_nid = nid; -@@ -16298,26 +16856,58 @@ static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, +@@ -16371,26 +16856,58 @@ static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, return 0; } @@ -13086,7 +10414,7 @@ index 067e6ed..0fd258e 100644 } } return 0; -@@ -16367,7 +16957,6 @@ static void alc662_auto_init_hp_out(struct hda_codec *codec) +@@ -16440,7 +16957,6 @@ static void alc662_auto_init_hp_out(struct hda_codec *codec) alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); } @@ -13094,7 +10422,7 @@ index 067e6ed..0fd258e 100644 #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID static void alc662_auto_init_analog_input(struct hda_codec *codec) -@@ -16377,12 +16966,10 @@ static void alc662_auto_init_analog_input(struct hda_codec *codec) +@@ -16450,12 +16966,10 @@ static void alc662_auto_init_analog_input(struct hda_codec *codec) for (i = 0; i < AUTO_PIN_LAST; i++) { hda_nid_t nid = spec->autocfg.input_pins[i]; @@ -13111,7 +10439,7 @@ index 067e6ed..0fd258e 100644 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); -@@ -16420,34 +17007,29 @@ static int alc662_parse_auto_config(struct hda_codec *codec) +@@ -16493,34 +17007,29 @@ static int alc662_parse_auto_config(struct hda_codec *codec) "Headphone"); if (err < 0) return err; @@ -13153,7 +10481,7 @@ index 067e6ed..0fd258e 100644 return 1; } -@@ -16499,6 +17081,12 @@ static int patch_alc662(struct hda_codec *codec) +@@ -16572,6 +17081,12 @@ static int patch_alc662(struct hda_codec *codec) } } @@ -13166,7 +10494,7 @@ index 067e6ed..0fd258e 100644 if (board_config != ALC662_AUTO) setup_preset(spec, &alc662_presets[board_config]); -@@ -16522,6 +17110,14 @@ static int patch_alc662(struct hda_codec *codec) +@@ -16595,6 +17110,14 @@ static int patch_alc662(struct hda_codec *codec) spec->adc_nids = alc662_adc_nids; spec->num_adc_nids = ARRAY_SIZE(alc662_adc_nids); spec->capsrc_nids = alc662_capsrc_nids; @@ -13181,7 +10509,7 @@ index 067e6ed..0fd258e 100644 spec->vmaster_nid = 0x02; -@@ -16532,6 +17128,7 @@ static int patch_alc662(struct hda_codec *codec) +@@ -16605,6 +17128,7 @@ static int patch_alc662(struct hda_codec *codec) if (!spec->loopback.amplist) spec->loopback.amplist = alc662_loopbacks; #endif @@ -13189,7 +10517,7 @@ index 067e6ed..0fd258e 100644 return 0; } -@@ -16539,7 +17136,7 @@ static int patch_alc662(struct hda_codec *codec) +@@ -16612,7 +17136,7 @@ static int patch_alc662(struct hda_codec *codec) /* * patch entries */ @@ -13198,7 +10526,7 @@ index 067e6ed..0fd258e 100644 { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 }, -@@ -16565,9 +17162,32 @@ struct hda_codec_preset snd_hda_preset_realtek[] = { +@@ -16638,9 +17162,32 @@ struct hda_codec_preset snd_hda_preset_realtek[] = { .patch = patch_alc882 }, /* should be patch_alc883() in future */ { .id = 0x10ec0885, .name = "ALC885", .patch = patch_alc882 }, { .id = 0x10ec0887, .name = "ALC887", .patch = patch_alc883 }, @@ -13290,7 +10618,7 @@ index 9332b63..43b436c 100644 +module_init(patch_si3054_init) +module_exit(patch_si3054_exit) diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c -index 5e89424..d2fd8ef 100644 +index bdd6964..d2fd8ef 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c @@ -30,19 +30,20 @@ @@ -13337,13 +10665,13 @@ index 5e89424..d2fd8ef 100644 STAC_92HD73XX_NO_JD, /* no jack-detection */ STAC_92HD73XX_REF, STAC_DELL_M6_AMIC, -@@ -81,21 +84,27 @@ enum { +@@ -81,22 +84,27 @@ enum { }; enum { + STAC_92HD83XXX_AUTO, STAC_92HD83XXX_REF, -+ STAC_92HD83XXX_PWR_REF, + STAC_92HD83XXX_PWR_REF, + STAC_DELL_S14, STAC_92HD83XXX_MODELS }; @@ -13365,7 +10693,7 @@ index 5e89424..d2fd8ef 100644 STAC_925x_REF, STAC_M1, STAC_M1_2, -@@ -108,6 +117,7 @@ enum { +@@ -109,6 +117,7 @@ enum { }; enum { @@ -13373,7 +10701,7 @@ index 5e89424..d2fd8ef 100644 STAC_D945_REF, STAC_D945GTP3, STAC_D945GTP5, -@@ -135,15 +145,36 @@ enum { +@@ -136,15 +145,23 @@ enum { }; enum { @@ -13394,13 +10722,13 @@ index 5e89424..d2fd8ef 100644 + STAC_9872_MODELS +}; + -+struct sigmatel_event { -+ hda_nid_t nid; -+ unsigned char type; -+ unsigned char tag; -+ int data; -+}; -+ + struct sigmatel_event { + hda_nid_t nid; + unsigned char type; +@@ -152,6 +169,12 @@ struct sigmatel_event { + int data; + }; + +struct sigmatel_jack { + hda_nid_t nid; + int type; @@ -13410,16 +10738,7 @@ index 5e89424..d2fd8ef 100644 struct sigmatel_spec { struct snd_kcontrol_new *mixers[4]; unsigned int num_mixers; -@@ -151,8 +182,6 @@ struct sigmatel_spec { - int board_config; - unsigned int eapd_switch: 1; - unsigned int surr_switch: 1; -- unsigned int line_switch: 1; -- unsigned int mic_switch: 1; - unsigned int alt_switch: 1; - unsigned int hp_detect: 1; - unsigned int spdif_mute: 1; -@@ -169,6 +198,7 @@ struct sigmatel_spec { +@@ -175,6 +198,7 @@ struct sigmatel_spec { unsigned int stream_delay; /* analog loopback */ @@ -13427,28 +10746,21 @@ index 5e89424..d2fd8ef 100644 unsigned char aloopback_mask; unsigned char aloopback_shift; -@@ -178,12 +208,20 @@ struct sigmatel_spec { +@@ -184,9 +208,11 @@ struct sigmatel_spec { hda_nid_t *pwr_nids; hda_nid_t *dac_list; + /* jack detection */ + struct snd_array jacks; + -+ /* events */ + /* events */ +- int num_events; +- struct sigmatel_event events[32]; + struct snd_array events; -+ + /* playback */ struct hda_input_mux *mono_mux; - struct hda_input_mux *amp_mux; - unsigned int cur_mmux; - struct hda_multi_out multiout; - hda_nid_t dac_nids[5]; -+ hda_nid_t hp_dacs[5]; -+ hda_nid_t speaker_dacs[5]; - - int volume_offset; - -@@ -208,8 +246,6 @@ struct sigmatel_spec { +@@ -220,8 +246,6 @@ struct sigmatel_spec { /* pin widgets */ hda_nid_t *pin_nids; unsigned int num_pins; @@ -13457,17 +10769,7 @@ index 5e89424..d2fd8ef 100644 /* codec specific stuff */ struct hda_verb *init; -@@ -230,15 +266,16 @@ struct sigmatel_spec { - /* i/o switches */ - unsigned int io_switch[2]; - unsigned int clfe_swap; -- unsigned int hp_switch; /* NID of HP as line-out */ -+ hda_nid_t line_switch; /* shared line-in for input and output */ -+ hda_nid_t mic_switch; /* shared mic-in for input and output */ -+ hda_nid_t hp_switch; /* NID of HP as line-out */ - unsigned int aloopback; - - struct hda_pcm pcm_rec[2]; /* PCM information */ +@@ -251,8 +275,7 @@ struct sigmatel_spec { /* dynamic controls and input_mux */ struct auto_pin_cfg autocfg; @@ -13477,53 +10779,7 @@ index 5e89424..d2fd8ef 100644 struct hda_input_mux private_dimux; struct hda_input_mux private_imux; struct hda_input_mux private_smux; -@@ -282,9 +319,6 @@ static hda_nid_t stac92hd73xx_dmic_nids[STAC92HD73XX_NUM_DMICS + 1] = { - }; - - #define STAC92HD73_DAC_COUNT 5 --static hda_nid_t stac92hd73xx_dac_nids[STAC92HD73_DAC_COUNT] = { -- 0x15, 0x16, 0x17, 0x18, 0x19, --}; - - static hda_nid_t stac92hd73xx_mux_nids[4] = { - 0x28, 0x29, 0x2a, 0x2b, -@@ -303,11 +337,7 @@ 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, -@@ -326,7 +356,11 @@ static hda_nid_t stac92hd83xxx_slave_dig_outs[2] = { - }; - - static unsigned int stac92hd83xxx_pwr_mapping[4] = { -- 0x03, 0x0c, 0x10, 0x40, -+ 0x03, 0x0c, 0x20, 0x40, -+}; -+ -+static hda_nid_t stac92hd83xxx_amp_nids[1] = { -+ 0xc, - }; - - static hda_nid_t stac92hd71bxx_pwr_nids[3] = { -@@ -349,10 +383,6 @@ static hda_nid_t stac92hd71bxx_smux_nids[2] = { - 0x24, 0x25, - }; - --static hda_nid_t stac92hd71bxx_dac_nids[1] = { -- 0x10, /*0x11, */ --}; -- - #define STAC92HD71BXX_NUM_DMICS 2 - static hda_nid_t stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS + 1] = { - 0x18, 0x19, 0 -@@ -391,6 +421,10 @@ static hda_nid_t stac922x_mux_nids[2] = { +@@ -398,6 +421,10 @@ static hda_nid_t stac922x_mux_nids[2] = { 0x12, 0x13, }; @@ -13534,7 +10790,7 @@ index 5e89424..d2fd8ef 100644 static hda_nid_t stac927x_adc_nids[3] = { 0x07, 0x08, 0x09 }; -@@ -463,15 +497,21 @@ static hda_nid_t stac92hd73xx_pin_nids[13] = { +@@ -470,15 +497,21 @@ static hda_nid_t stac92hd73xx_pin_nids[13] = { 0x14, 0x22, 0x23 }; @@ -13544,15 +10800,15 @@ index 5e89424..d2fd8ef 100644 - 0x0f, 0x10, 0x11, 0x12, 0x13, - 0x1d, 0x1e, 0x1f, 0x20 + 0x0f, 0x10, 0x11, 0x1f, 0x20, -+}; + }; +-static hda_nid_t stac92hd71bxx_pin_nids[11] = { + +#define STAC92HD71BXX_NUM_PINS 13 +static hda_nid_t stac92hd71bxx_pin_nids_4port[STAC92HD71BXX_NUM_PINS] = { + 0x0a, 0x0b, 0x0c, 0x0d, 0x00, + 0x00, 0x14, 0x18, 0x19, 0x1e, + 0x1f, 0x20, 0x27 - }; --static hda_nid_t stac92hd71bxx_pin_nids[11] = { ++}; +static hda_nid_t stac92hd71bxx_pin_nids_6port[STAC92HD71BXX_NUM_PINS] = { 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x14, 0x18, 0x19, 0x1e, @@ -13561,94 +10817,10 @@ index 5e89424..d2fd8ef 100644 }; static hda_nid_t stac927x_pin_nids[14] = { -@@ -584,12 +624,12 @@ static int stac92xx_smux_enum_put(struct snd_kcontrol *kcontrol, - else - nid = codec->slave_dig_outs[smux_idx - 1]; - if (spec->cur_smux[smux_idx] == smux->num_items - 1) -- val = AMP_OUT_MUTE; -+ val = HDA_AMP_MUTE; - else -- val = AMP_OUT_UNMUTE; -+ val = 0; - /* un/mute SPDIF out */ -- snd_hda_codec_write_cache(codec, nid, 0, -- AC_VERB_SET_AMP_GAIN_MUTE, val); -+ snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, -+ HDA_AMP_MUTE, val); - } - return 0; - } -@@ -754,10 +794,6 @@ static struct hda_verb stac9200_eapd_init[] = { - static struct hda_verb stac92hd73xx_6ch_core_init[] = { - /* set master volume and direct control */ - { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, -- /* setup audio connections */ -- { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00}, -- { 0x10, AC_VERB_SET_CONNECT_SEL, 0x01}, -- { 0x11, AC_VERB_SET_CONNECT_SEL, 0x02}, - /* setup adcs to point to mixer */ - { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, - { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, -@@ -776,10 +812,6 @@ static struct hda_verb dell_eq_core_init[] = { - /* set master volume to max value without distortion - * and direct control */ - { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec}, -- /* setup audio connections */ -- { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, -- { 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}, -@@ -793,10 +825,6 @@ static struct hda_verb dell_eq_core_init[] = { - - static struct hda_verb dell_m6_core_init[] = { - { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, -- /* setup audio connections */ -- { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, -- { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01}, -- { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x02}, - /* setup adcs to point to mixer */ - { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, - { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, -@@ -811,13 +839,6 @@ static struct hda_verb dell_m6_core_init[] = { - static struct hda_verb stac92hd73xx_8ch_core_init[] = { - /* set master volume and direct control */ - { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, -- /* setup audio connections */ -- { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00}, -- { 0x10, AC_VERB_SET_CONNECT_SEL, 0x01}, -- { 0x11, AC_VERB_SET_CONNECT_SEL, 0x02}, -- /* connect hp ports to dac3 */ -- { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x03}, -- { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x03}, - /* setup adcs to point to mixer */ - { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, - { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, -@@ -835,15 +856,8 @@ static struct hda_verb stac92hd73xx_8ch_core_init[] = { - static struct hda_verb stac92hd73xx_10ch_core_init[] = { - /* set master volume and direct control */ - { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, -- /* setup audio connections */ -- { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x00 }, -- { 0x10, AC_VERB_SET_CONNECT_SEL, 0x01 }, -- { 0x11, AC_VERB_SET_CONNECT_SEL, 0x02 }, - /* dac3 is connected to import3 mux */ - { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, 0xb07f}, -- /* connect hp ports to dac4 */ -- { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x04}, -- { 0x0d, AC_VERB_SET_CONNECT_SEL, 0x04}, - /* setup adcs to point to mixer */ - { 0x20, AC_VERB_SET_CONNECT_SEL, 0x0b}, - { 0x21, AC_VERB_SET_CONNECT_SEL, 0x0b}, -@@ -859,13 +873,9 @@ static struct hda_verb stac92hd73xx_10ch_core_init[] = { +@@ -840,9 +873,9 @@ 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}, @@ -13658,12 +10830,10 @@ index 5e89424..d2fd8ef 100644 /* power state controls amps */ { 0x01, AC_VERB_SET_EAPD, 1 << 2}, -@@ -875,30 +885,25 @@ static struct hda_verb stac92hd83xxx_core_init[] = { +@@ -852,26 +885,25 @@ static struct hda_verb stac92hd83xxx_core_init[] = { static struct hda_verb stac92hd71bxx_core_init[] = { /* set master volume and direct control */ { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, -- /* connect headphone jack to dac1 */ -- { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01}, - /* unmute right and left channels for nodes 0x0a, 0xd, 0x0f */ - { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, @@ -13684,8 +10854,6 @@ index 5e89424..d2fd8ef 100644 /* set master volume and direct control */ { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, -- /* connect headphone jack to dac1 */ -- { 0x0a, AC_VERB_SET_CONNECT_SEL, 0x01}, - /* unmute right and left channels for nodes 0x0a, 0xd */ + {} +}; @@ -13696,7 +10864,7 @@ index 5e89424..d2fd8ef 100644 { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {} -@@ -979,16 +984,6 @@ static struct hda_verb stac9205_core_init[] = { +@@ -952,16 +984,6 @@ static struct hda_verb stac9205_core_init[] = { .private_value = HDA_COMPOSE_AMP_VAL(nid, chs, idx, dir) \ } @@ -13713,7 +10881,7 @@ index 5e89424..d2fd8ef 100644 #define STAC_ANALOG_LOOPBACK(verb_read, verb_write, cnt) \ { \ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ -@@ -1003,7 +998,6 @@ static struct hda_verb stac9205_core_init[] = { +@@ -976,7 +998,6 @@ static struct hda_verb stac9205_core_init[] = { static struct snd_kcontrol_new stac9200_mixer[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0xb, 0, HDA_OUTPUT), HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT), @@ -13721,7 +10889,7 @@ index 5e89424..d2fd8ef 100644 HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT), HDA_CODEC_MUTE("Capture Switch", 0x0a, 0, HDA_OUTPUT), { } /* end */ -@@ -1028,8 +1022,6 @@ static struct snd_kcontrol_new stac92hd73xx_6ch_mixer[] = { +@@ -1001,8 +1022,6 @@ static struct snd_kcontrol_new stac92hd73xx_6ch_mixer[] = { HDA_CODEC_VOLUME("DAC Mixer Capture Volume", 0x1d, 0x3, HDA_INPUT), HDA_CODEC_MUTE("DAC Mixer Capture Switch", 0x1d, 0x3, HDA_INPUT), @@ -13730,7 +10898,7 @@ index 5e89424..d2fd8ef 100644 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT), -@@ -1039,9 +1031,22 @@ static struct snd_kcontrol_new stac92hd73xx_6ch_mixer[] = { +@@ -1012,9 +1031,22 @@ static struct snd_kcontrol_new stac92hd73xx_6ch_mixer[] = { { } /* end */ }; @@ -13754,7 +10922,7 @@ index 5e89424..d2fd8ef 100644 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT), -@@ -1066,8 +1071,6 @@ static struct snd_kcontrol_new stac92hd73xx_8ch_mixer[] = { +@@ -1039,8 +1071,6 @@ static struct snd_kcontrol_new stac92hd73xx_8ch_mixer[] = { }; static struct snd_kcontrol_new stac92hd73xx_10ch_mixer[] = { @@ -13763,37 +10931,7 @@ index 5e89424..d2fd8ef 100644 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x20, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x20, 0x0, HDA_OUTPUT), -@@ -1099,29 +1102,26 @@ static struct snd_kcontrol_new stac92hd83xxx_mixer[] = { - 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("DAC0 Capture Volume", 0x1b, 0x3, HDA_INPUT), -+ HDA_CODEC_MUTE("DAC0 Capture Switch", 0x1b, 0x3, 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("DAC1 Capture Volume", 0x1b, 0x4, HDA_INPUT), -+ HDA_CODEC_MUTE("DAC1 Capture Switch", 0x1b, 0x4, 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("Front Mic Capture Volume", 0x1b, 0x0, HDA_INPUT), -+ HDA_CODEC_MUTE("Front Mic Capture Switch", 0x1b, 0x0, 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("Line In Capture Volume", 0x1b, 0x2, HDA_INPUT), -+ HDA_CODEC_MUTE("Line In Capture Switch", 0x1b, 0x2, HDA_INPUT), - - /* -- HDA_CODEC_VOLUME("Mic Capture Volume", 0x1b, 0x4, HDA_INPUT), -- HDA_CODEC_MUTE("Mic Capture Switch", 0x1b 0x4, HDA_INPUT), -+ HDA_CODEC_VOLUME("Mic Capture Volume", 0x1b, 0x1, HDA_INPUT), -+ HDA_CODEC_MUTE("Mic Capture Switch", 0x1b 0x1, HDA_INPUT), - */ - { } /* end */ +@@ -1092,9 +1122,6 @@ static struct snd_kcontrol_new stac92hd83xxx_mixer[] = { }; static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = { @@ -13803,7 +10941,7 @@ index 5e89424..d2fd8ef 100644 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT), -@@ -1147,10 +1147,11 @@ static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = { +@@ -1120,10 +1147,11 @@ static struct snd_kcontrol_new stac92hd71bxx_analog_mixer[] = { { } /* end */ }; @@ -13818,7 +10956,7 @@ index 5e89424..d2fd8ef 100644 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1c, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1c, 0x0, HDA_OUTPUT), -@@ -1162,16 +1163,12 @@ static struct snd_kcontrol_new stac92hd71bxx_mixer[] = { +@@ -1135,16 +1163,12 @@ static struct snd_kcontrol_new stac92hd71bxx_mixer[] = { static struct snd_kcontrol_new stac925x_mixer[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0x0e, 0, HDA_OUTPUT), HDA_CODEC_MUTE("Master Playback Switch", 0x0e, 0, HDA_OUTPUT), @@ -13835,7 +10973,7 @@ index 5e89424..d2fd8ef 100644 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x1b, 0x0, HDA_INPUT), HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1d, 0x0, HDA_OUTPUT), -@@ -1180,9 +1177,13 @@ static struct snd_kcontrol_new stac9205_mixer[] = { +@@ -1153,9 +1177,13 @@ static struct snd_kcontrol_new stac9205_mixer[] = { { } /* end */ }; @@ -13850,7 +10988,7 @@ index 5e89424..d2fd8ef 100644 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x17, 0x0, HDA_INPUT), HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x17, 0x0, HDA_INPUT), -@@ -1193,9 +1194,6 @@ static struct snd_kcontrol_new stac922x_mixer[] = { +@@ -1166,9 +1194,6 @@ static struct snd_kcontrol_new stac922x_mixer[] = { static struct snd_kcontrol_new stac927x_mixer[] = { @@ -13860,7 +10998,7 @@ index 5e89424..d2fd8ef 100644 HDA_CODEC_VOLUME_IDX("Capture Volume", 0x0, 0x18, 0x0, HDA_INPUT), HDA_CODEC_MUTE_IDX("Capture Switch", 0x0, 0x1b, 0x0, HDA_OUTPUT), -@@ -1207,6 +1205,11 @@ static struct snd_kcontrol_new stac927x_mixer[] = { +@@ -1180,6 +1205,11 @@ static struct snd_kcontrol_new stac927x_mixer[] = { { } /* end */ }; @@ -13872,22 +11010,22 @@ index 5e89424..d2fd8ef 100644 static struct snd_kcontrol_new stac_dmux_mixer = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Digital Input Source", -@@ -1232,10 +1235,7 @@ static const char *slave_vols[] = { +@@ -1205,10 +1235,7 @@ static const char *slave_vols[] = { "LFE Playback Volume", "Side Playback Volume", "Headphone Playback Volume", -- "Headphone Playback Volume", +- "Headphone2 Playback Volume", "Speaker Playback Volume", - "External Speaker Playback Volume", - "Speaker2 Playback Volume", NULL }; -@@ -1246,17 +1246,19 @@ static const char *slave_sws[] = { +@@ -1219,17 +1246,19 @@ static const char *slave_sws[] = { "LFE Playback Switch", "Side Playback Switch", "Headphone Playback Switch", -- "Headphone Playback Switch", +- "Headphone2 Playback Switch", "Speaker Playback Switch", - "External Speaker Playback Switch", - "Speaker2 Playback Switch", @@ -13906,7 +11044,7 @@ index 5e89424..d2fd8ef 100644 int err; int i; -@@ -1271,7 +1273,7 @@ static int stac92xx_build_controls(struct hda_codec *codec) +@@ -1244,7 +1273,7 @@ static int stac92xx_build_controls(struct hda_codec *codec) } if (spec->num_dmuxes > 0) { stac_dmux_mixer.count = spec->num_dmuxes; @@ -13915,7 +11053,7 @@ index 5e89424..d2fd8ef 100644 snd_ctl_new1(&stac_dmux_mixer, codec)); if (err < 0) return err; -@@ -1287,7 +1289,7 @@ static int stac92xx_build_controls(struct hda_codec *codec) +@@ -1260,7 +1289,7 @@ static int stac92xx_build_controls(struct hda_codec *codec) spec->spdif_mute = 1; } stac_smux_mixer.count = spec->num_smuxes; @@ -13924,7 +11062,7 @@ index 5e89424..d2fd8ef 100644 snd_ctl_new1(&stac_smux_mixer, codec)); if (err < 0) return err; -@@ -1328,6 +1330,44 @@ static int stac92xx_build_controls(struct hda_codec *codec) +@@ -1301,6 +1330,44 @@ static int stac92xx_build_controls(struct hda_codec *codec) return err; } @@ -13969,7 +11107,7 @@ index 5e89424..d2fd8ef 100644 return 0; } -@@ -1481,6 +1521,7 @@ static unsigned int *stac9200_brd_tbl[STAC_9200_MODELS] = { +@@ -1454,6 +1521,7 @@ static unsigned int *stac9200_brd_tbl[STAC_9200_MODELS] = { }; static const char *stac9200_models[STAC_9200_MODELS] = { @@ -13977,7 +11115,7 @@ index 5e89424..d2fd8ef 100644 [STAC_REF] = "ref", [STAC_9200_OQO] = "oqo", [STAC_9200_DELL_D21] = "dell-d21", -@@ -1502,6 +1543,8 @@ static struct snd_pci_quirk stac9200_cfg_tbl[] = { +@@ -1475,6 +1543,8 @@ static struct snd_pci_quirk stac9200_cfg_tbl[] = { /* SigmaTel reference board */ SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF), @@ -13986,7 +11124,7 @@ index 5e89424..d2fd8ef 100644 /* Dell laptops have BIOS problem */ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01a8, "unknown Dell", STAC_9200_DELL_D21), -@@ -1624,6 +1667,7 @@ static unsigned int *stac925x_brd_tbl[STAC_925x_MODELS] = { +@@ -1597,6 +1667,7 @@ static unsigned int *stac925x_brd_tbl[STAC_925x_MODELS] = { }; static const char *stac925x_models[STAC_925x_MODELS] = { @@ -13994,7 +11132,7 @@ index 5e89424..d2fd8ef 100644 [STAC_REF] = "ref", [STAC_M1] = "m1", [STAC_M1_2] = "m1-2", -@@ -1651,6 +1695,7 @@ static struct snd_pci_quirk stac925x_codec_id_cfg_tbl[] = { +@@ -1624,6 +1695,7 @@ static struct snd_pci_quirk stac925x_codec_id_cfg_tbl[] = { static struct snd_pci_quirk stac925x_cfg_tbl[] = { /* SigmaTel reference board */ SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF), @@ -14002,7 +11140,7 @@ index 5e89424..d2fd8ef 100644 SND_PCI_QUIRK(0x8384, 0x7632, "Stac9202 Reference Board", STAC_REF), /* Default table for unknown ID */ -@@ -1682,6 +1727,7 @@ static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = { +@@ -1655,6 +1727,7 @@ static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = { }; static const char *stac92hd73xx_models[STAC_92HD73XX_MODELS] = { @@ -14010,7 +11148,7 @@ index 5e89424..d2fd8ef 100644 [STAC_92HD73XX_NO_JD] = "no-jd", [STAC_92HD73XX_REF] = "ref", [STAC_DELL_M6_AMIC] = "dell-m6-amic", -@@ -1694,6 +1740,8 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = { +@@ -1667,6 +1740,8 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = { /* SigmaTel reference board */ SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_92HD73XX_REF), @@ -14019,7 +11157,7 @@ index 5e89424..d2fd8ef 100644 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0254, "Dell Studio 1535", STAC_DELL_M6_DMIC), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0255, -@@ -1717,50 +1765,68 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = { +@@ -1690,52 +1765,68 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = { {} /* terminator */ }; @@ -14039,14 +11177,14 @@ index 5e89424..d2fd8ef 100644 + static unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = { [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs, -+ [STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs, + [STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs, + [STAC_DELL_S14] = dell_s14_pin_configs, }; static const char *stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = { + [STAC_92HD83XXX_AUTO] = "auto", [STAC_92HD83XXX_REF] = "ref", -+ [STAC_92HD83XXX_PWR_REF] = "mic-ref", + [STAC_92HD83XXX_PWR_REF] = "mic-ref", + [STAC_DELL_S14] = "dell-s14", }; @@ -14098,7 +11236,7 @@ index 5e89424..d2fd8ef 100644 }; static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = { -@@ -1770,33 +1836,38 @@ static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = { +@@ -1745,39 +1836,38 @@ static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = { [STAC_DELL_M4_3] = dell_m4_3_pin_configs, [STAC_HP_M4] = NULL, [STAC_HP_DV5] = NULL, @@ -14120,20 +11258,25 @@ index 5e89424..d2fd8ef 100644 /* SigmaTel reference board */ SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_92HD71BXX_REF), +- SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x308c, +- "HP", STAC_HP_DV5), +- SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x308d, ++ SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, ++ "DFI LanParty", STAC_92HD71BXX_REF), ++ SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3080, + "HP", STAC_HP_DV5), - SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f2, -- "HP dv5", STAC_HP_M4), +- "HP dv5", STAC_HP_DV5), - SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f4, -- "HP dv7", STAC_HP_M4), +- "HP dv7", STAC_HP_DV5), - SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30f7, - "HP dv4", STAC_HP_DV5), - SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x30fc, -- "HP dv7", STAC_HP_M4), +- "HP dv7", STAC_HP_DV5), +- SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3600, +- "HP dv5", STAC_HP_DV5), - SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x3603, - "HP dv5", STAC_HP_DV5), -+ SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, -+ "DFI LanParty", STAC_92HD71BXX_REF), -+ SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3080, -+ "HP", STAC_HP_DV5), + SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x30f0, + "HP dv4-7", STAC_HP_DV5), + SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xfff0, 0x3600, @@ -14148,7 +11291,7 @@ index 5e89424..d2fd8ef 100644 SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0233, "unknown Dell", STAC_DELL_M4_1), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0234, -@@ -1948,6 +2019,7 @@ static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { +@@ -1929,6 +2019,7 @@ static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { }; static const char *stac922x_models[STAC_922X_MODELS] = { @@ -14156,7 +11299,7 @@ index 5e89424..d2fd8ef 100644 [STAC_D945_REF] = "ref", [STAC_D945GTP5] = "5stack", [STAC_D945GTP3] = "3stack", -@@ -1975,6 +2047,8 @@ static struct snd_pci_quirk stac922x_cfg_tbl[] = { +@@ -1956,6 +2047,8 @@ static struct snd_pci_quirk stac922x_cfg_tbl[] = { /* SigmaTel reference board */ SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_D945_REF), @@ -14165,7 +11308,7 @@ index 5e89424..d2fd8ef 100644 /* Intel 945G based systems */ SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x0101, "Intel D945G", STAC_D945GTP3), -@@ -2055,31 +2129,7 @@ static struct snd_pci_quirk stac922x_cfg_tbl[] = { +@@ -2036,31 +2129,7 @@ static struct snd_pci_quirk stac922x_cfg_tbl[] = { SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01d7, "Dell XPS M1210", STAC_922X_DELL_M82), /* ECS/PC Chips boards */ @@ -14198,7 +11341,7 @@ index 5e89424..d2fd8ef 100644 "ECS/PC chips", STAC_ECS_202), {} /* terminator */ }; -@@ -2105,6 +2155,13 @@ static unsigned int d965_5st_pin_configs[14] = { +@@ -2086,6 +2155,13 @@ static unsigned int d965_5st_pin_configs[14] = { 0x40000100, 0x40000100 }; @@ -14212,7 +11355,7 @@ index 5e89424..d2fd8ef 100644 static unsigned int dell_3st_pin_configs[14] = { 0x02211230, 0x02a11220, 0x01a19040, 0x01114210, 0x01111212, 0x01116211, 0x01813050, 0x01112214, -@@ -2117,15 +2174,18 @@ static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = { +@@ -2098,15 +2174,18 @@ static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = { [STAC_D965_REF] = ref927x_pin_configs, [STAC_D965_3ST] = d965_3st_pin_configs, [STAC_D965_5ST] = d965_5st_pin_configs, @@ -14231,7 +11374,7 @@ index 5e89424..d2fd8ef 100644 [STAC_DELL_3ST] = "dell-3stack", [STAC_DELL_BIOS] = "dell-bios", }; -@@ -2134,26 +2194,16 @@ static struct snd_pci_quirk stac927x_cfg_tbl[] = { +@@ -2115,26 +2194,16 @@ static struct snd_pci_quirk stac927x_cfg_tbl[] = { /* SigmaTel reference board */ SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_D965_REF), @@ -14264,7 +11407,7 @@ index 5e89424..d2fd8ef 100644 /* Dell 3 stack systems */ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f7, "Dell XPS M1730", STAC_DELL_3ST), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01dd, "Dell Dimension E520", STAC_DELL_3ST), -@@ -2169,15 +2219,10 @@ static struct snd_pci_quirk stac927x_cfg_tbl[] = { +@@ -2150,15 +2219,10 @@ static struct snd_pci_quirk stac927x_cfg_tbl[] = { SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02ff, "Dell ", STAC_DELL_BIOS), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0209, "Dell XPS 1330", STAC_DELL_BIOS), /* 965 based 5 stack systems */ @@ -14284,7 +11427,7 @@ index 5e89424..d2fd8ef 100644 {} /* terminator */ }; -@@ -2234,6 +2279,7 @@ static unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = { +@@ -2215,6 +2279,7 @@ static unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = { }; static const char *stac9205_models[STAC_9205_MODELS] = { @@ -14292,7 +11435,7 @@ index 5e89424..d2fd8ef 100644 [STAC_9205_REF] = "ref", [STAC_9205_DELL_M42] = "dell-m42", [STAC_9205_DELL_M43] = "dell-m43", -@@ -2245,6 +2291,8 @@ static struct snd_pci_quirk stac9205_cfg_tbl[] = { +@@ -2226,6 +2291,8 @@ static struct snd_pci_quirk stac9205_cfg_tbl[] = { /* SigmaTel reference board */ SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_9205_REF), @@ -14301,16 +11444,14 @@ index 5e89424..d2fd8ef 100644 /* Dell */ SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x01f1, "unknown Dell", STAC_9205_DELL_M42), -@@ -2281,66 +2329,19 @@ static struct snd_pci_quirk stac9205_cfg_tbl[] = { +@@ -2262,66 +2329,19 @@ static struct snd_pci_quirk stac9205_cfg_tbl[] = { {} /* terminator */ }; -static int stac92xx_save_bios_config_regs(struct hda_codec *codec) -+static void stac92xx_set_config_regs(struct hda_codec *codec, -+ unsigned int *pincfgs) - { - int i; - struct sigmatel_spec *spec = codec->spec; +-{ +- int i; +- struct sigmatel_spec *spec = codec->spec; - - if (! spec->bios_pin_configs) { - spec->bios_pin_configs = kcalloc(spec->num_pins, @@ -14332,7 +11473,7 @@ index 5e89424..d2fd8ef 100644 - - return 0; -} - +- -static void stac92xx_set_config_reg(struct hda_codec *codec, - hda_nid_t pin_nid, unsigned int pin_config) -{ @@ -14357,10 +11498,12 @@ index 5e89424..d2fd8ef 100644 -} - -static void stac92xx_set_config_regs(struct hda_codec *codec) --{ -- int i; -- struct sigmatel_spec *spec = codec->spec; -- ++static void stac92xx_set_config_regs(struct hda_codec *codec, ++ unsigned int *pincfgs) + { + int i; + struct sigmatel_spec *spec = codec->spec; + - if (!spec->pin_configs) - return; + if (!pincfgs) @@ -14375,7 +11518,7 @@ index 5e89424..d2fd8ef 100644 } /* -@@ -2405,6 +2406,15 @@ static int stac92xx_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, +@@ -2386,6 +2406,15 @@ static int stac92xx_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, stream_tag, format, substream); } @@ -14391,25 +11534,7 @@ index 5e89424..d2fd8ef 100644 /* * Analog capture callbacks */ -@@ -2419,7 +2429,7 @@ static int stac92xx_capture_pcm_prepare(struct hda_pcm_stream *hinfo, - - if (spec->powerdown_adcs) { - msleep(40); -- snd_hda_codec_write_cache(codec, nid, 0, -+ snd_hda_codec_write(codec, nid, 0, - AC_VERB_SET_POWER_STATE, AC_PWRST_D0); - } - snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format); -@@ -2435,7 +2445,7 @@ static int stac92xx_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, - - snd_hda_codec_cleanup_stream(codec, nid); - if (spec->powerdown_adcs) -- snd_hda_codec_write_cache(codec, nid, 0, -+ snd_hda_codec_write(codec, nid, 0, - AC_VERB_SET_POWER_STATE, AC_PWRST_D3); - return 0; - } -@@ -2448,7 +2458,8 @@ static struct hda_pcm_stream stac92xx_pcm_digital_playback = { +@@ -2429,7 +2458,8 @@ static struct hda_pcm_stream stac92xx_pcm_digital_playback = { .ops = { .open = stac92xx_dig_playback_pcm_open, .close = stac92xx_dig_playback_pcm_close, @@ -14419,7 +11544,7 @@ index 5e89424..d2fd8ef 100644 }, }; -@@ -2520,7 +2531,7 @@ static int stac92xx_build_pcms(struct hda_codec *codec) +@@ -2501,7 +2531,7 @@ static int stac92xx_build_pcms(struct hda_codec *codec) codec->num_pcms++; info++; info->name = "STAC92xx Digital"; @@ -14428,7 +11553,7 @@ index 5e89424..d2fd8ef 100644 if (spec->multiout.dig_out_nid) { info->stream[SNDRV_PCM_STREAM_PLAYBACK] = stac92xx_pcm_digital_playback; info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid; -@@ -2536,8 +2547,7 @@ static int stac92xx_build_pcms(struct hda_codec *codec) +@@ -2517,8 +2547,7 @@ static int stac92xx_build_pcms(struct hda_codec *codec) static unsigned int stac92xx_get_vref(struct hda_codec *codec, hda_nid_t nid) { @@ -14438,16 +11563,7 @@ index 5e89424..d2fd8ef 100644 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT; if (pincap & AC_PINCAP_VREF_100) return AC_PINCTL_VREF_100; -@@ -2569,19 +2579,22 @@ static int stac92xx_hp_switch_get(struct snd_kcontrol *kcontrol, - return 0; - } - -+static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid, -+ unsigned char type); -+ - static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) - { +@@ -2559,13 +2588,14 @@ static int stac92xx_hp_switch_put(struct snd_kcontrol *kcontrol, struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct sigmatel_spec *spec = codec->spec; int nid = kcontrol->private_value; @@ -14458,21 +11574,12 @@ index 5e89424..d2fd8ef 100644 /* check to be sure that the ports are upto date with * switch changes */ -- codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26); -+ stac_issue_unsol_event(codec, nid, STAC_HP_EVENT); - + stac_issue_unsol_event(codec, nid, STAC_HP_EVENT); ++ return 1; } -@@ -2621,7 +2634,7 @@ static int stac92xx_io_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ - * appropriately according to the pin direction - */ - if (spec->hp_detect) -- codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26); -+ stac_issue_unsol_event(codec, nid, STAC_HP_EVENT); - return 1; - } -@@ -2709,35 +2722,38 @@ static struct snd_kcontrol_new stac92xx_control_templates[] = { +@@ -2692,35 +2722,38 @@ static struct snd_kcontrol_new stac92xx_control_templates[] = { }; /* add dynamic controls */ @@ -14533,12 +11640,10 @@ index 5e89424..d2fd8ef 100644 return 0; } -@@ -2758,70 +2774,75 @@ static inline int stac92xx_add_control(struct sigmatel_spec *spec, int type, +@@ -2741,6 +2774,29 @@ static inline int stac92xx_add_control(struct sigmatel_spec *spec, int type, 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) +static struct snd_kcontrol_new stac_input_src_temp = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Input Source", @@ -14562,151 +11667,47 @@ index 5e89424..d2fd8ef 100644 + return 0; +} + -+/* check whether the line-input can be used as line-out */ -+static hda_nid_t check_line_out_switch(struct hda_codec *codec) + /* check whether the line-input can be used as line-out */ + static hda_nid_t check_line_out_switch(struct hda_codec *codec) { - struct sigmatel_spec *spec = codec->spec; -- unsigned int wcaps, wtype; -- int i, num_dacs = 0; -- -- /* use the wcaps cache to count all DACs available for line-outs */ -- for (i = 0; i < codec->num_nodes; i++) { -- wcaps = codec->wcaps[i]; -- wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; -+ struct auto_pin_cfg *cfg = &spec->autocfg; -+ hda_nid_t nid; -+ unsigned int pincap; - -- if (wtype == AC_WID_AUD_OUT && !(wcaps & AC_WCAP_DIGITAL)) -- num_dacs++; -- } -+ if (cfg->line_out_type != AUTO_PIN_LINE_OUT) -+ return 0; -+ nid = cfg->input_pins[AUTO_PIN_LINE]; +@@ -2752,7 +2808,7 @@ static hda_nid_t check_line_out_switch(struct hda_codec *codec) + if (cfg->line_out_type != AUTO_PIN_LINE_OUT) + return 0; + nid = cfg->input_pins[AUTO_PIN_LINE]; +- pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); + pincap = snd_hda_query_pin_caps(codec, nid); -+ if (pincap & AC_PINCAP_OUT) -+ return nid; -+ return 0; -+} - -- snd_printdd("%s: total dac count=%d\n", __func__, num_dacs); -- -- switch (cfg->line_outs) { -- case 3: -- /* add line-in as side */ -- if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 3) { -- cfg->line_out_pins[cfg->line_outs] = -- cfg->input_pins[AUTO_PIN_LINE]; -- spec->line_switch = 1; -- cfg->line_outs++; -- } -- break; -- case 2: -- /* add line-in as clfe and mic as side */ -- if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 2) { -- cfg->line_out_pins[cfg->line_outs] = -- cfg->input_pins[AUTO_PIN_LINE]; -- spec->line_switch = 1; -- cfg->line_outs++; -- } -- if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 3) { -- cfg->line_out_pins[cfg->line_outs] = -- cfg->input_pins[AUTO_PIN_MIC]; -- spec->mic_switch = 1; -- cfg->line_outs++; -- } -- break; -- case 1: -- /* add line-in as surr and mic as clfe */ -- if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 1) { -- cfg->line_out_pins[cfg->line_outs] = -- cfg->input_pins[AUTO_PIN_LINE]; -- spec->line_switch = 1; -- cfg->line_outs++; -- } -- if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 2) { -- cfg->line_out_pins[cfg->line_outs] = -- cfg->input_pins[AUTO_PIN_MIC]; -- spec->mic_switch = 1; -- cfg->line_outs++; -+/* check whether the mic-input can be used as line-out */ -+static hda_nid_t check_mic_out_switch(struct hda_codec *codec) -+{ -+ struct sigmatel_spec *spec = codec->spec; -+ struct auto_pin_cfg *cfg = &spec->autocfg; -+ unsigned int def_conf, pincap; -+ unsigned int mic_pin; -+ -+ if (cfg->line_out_type != AUTO_PIN_LINE_OUT) -+ return 0; -+ mic_pin = AUTO_PIN_MIC; -+ for (;;) { -+ hda_nid_t nid = cfg->input_pins[mic_pin]; + if (pincap & AC_PINCAP_OUT) + return nid; + return 0; +@@ -2771,12 +2827,11 @@ static hda_nid_t check_mic_out_switch(struct hda_codec *codec) + mic_pin = AUTO_PIN_MIC; + for (;;) { + hda_nid_t nid = cfg->input_pins[mic_pin]; +- def_conf = snd_hda_codec_read(codec, nid, 0, +- AC_VERB_GET_CONFIG_DEFAULT, 0); + def_conf = snd_hda_codec_get_pincfg(codec, nid); -+ /* some laptops have an internal analog microphone -+ * which can't be used as a output */ -+ if (get_defcfg_connect(def_conf) != AC_JACK_PORT_FIXED) { + /* some laptops have an internal analog microphone + * which can't be used as a output */ + if (get_defcfg_connect(def_conf) != AC_JACK_PORT_FIXED) { +- pincap = snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP); + pincap = snd_hda_query_pin_caps(codec, nid); -+ if (pincap & AC_PINCAP_OUT) -+ return nid; + if (pincap & AC_PINCAP_OUT) + return nid; } -- break; -+ if (mic_pin == AUTO_PIN_MIC) -+ mic_pin = AUTO_PIN_FRONT_MIC; -+ else -+ break; - } -- - return 0; - } - -- - static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid) - { - int i; -@@ -2834,6 +2855,61 @@ static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid) - return 0; - } - -+static int check_all_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid) -+{ -+ int i; -+ if (is_in_dac_nids(spec, nid)) -+ return 1; -+ for (i = 0; i < spec->autocfg.hp_outs; i++) -+ if (spec->hp_dacs[i] == nid) -+ return 1; -+ for (i = 0; i < spec->autocfg.speaker_outs; i++) -+ if (spec->speaker_dacs[i] == nid) -+ return 1; -+ return 0; -+} -+ -+static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid) -+{ -+ struct sigmatel_spec *spec = codec->spec; -+ int j, conn_len; -+ hda_nid_t conn[HDA_MAX_CONNECTIONS]; -+ unsigned int wcaps, wtype; -+ -+ conn_len = snd_hda_get_connections(codec, nid, conn, -+ HDA_MAX_CONNECTIONS); -+ for (j = 0; j < conn_len; j++) { +@@ -2824,8 +2879,7 @@ static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid) + conn_len = snd_hda_get_connections(codec, nid, conn, + HDA_MAX_CONNECTIONS); + for (j = 0; j < conn_len; j++) { +- wcaps = snd_hda_param_read(codec, conn[j], +- AC_PAR_AUDIO_WIDGET_CAP); + wcaps = get_wcaps(codec, conn[j]); -+ wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; -+ /* we check only analog outputs */ -+ if (wtype != AC_WID_AUD_OUT || (wcaps & AC_WCAP_DIGITAL)) -+ continue; -+ /* if this route has a free DAC, assign it */ -+ if (!check_all_dac_nids(spec, conn[j])) { -+ if (conn_len > 1) { -+ /* select this DAC in the pin's input mux */ -+ snd_hda_codec_write_cache(codec, nid, 0, -+ AC_VERB_SET_CONNECT_SEL, j); -+ } -+ return conn[j]; -+ } -+ } + wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; + /* we check only analog outputs */ + if (wtype != AC_WID_AUD_OUT || (wcaps & AC_WCAP_DIGITAL)) +@@ -2840,6 +2894,16 @@ static hda_nid_t get_unassigned_dac(struct hda_codec *codec, hda_nid_t nid) + return conn[j]; + } + } + /* if all DACs are already assigned, connect to the primary DAC */ + if (conn_len > 1) { + for (j = 0; j < conn_len; j++) { @@ -14717,66 +11718,13 @@ index 5e89424..d2fd8ef 100644 + } + } + } -+ return 0; -+} -+ -+static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid); -+static int add_spec_extra_dacs(struct sigmatel_spec *spec, hda_nid_t nid); -+ - /* - * Fill in the dac_nids table from the parsed pin configuration - * This function only works when every pin in line_out_pins[] -@@ -2841,31 +2917,17 @@ static int is_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid) - * codecs are not connected directly to a DAC, such as the 9200 - * and 9202/925x. For those, dac_nids[] must be hard-coded. - */ --static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec, -- struct auto_pin_cfg *cfg) -+static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec) - { - struct sigmatel_spec *spec = codec->spec; -- int i, j, conn_len = 0; -- hda_nid_t nid, conn[HDA_MAX_CONNECTIONS]; -- unsigned int wcaps, wtype; -+ struct auto_pin_cfg *cfg = &spec->autocfg; -+ int i; -+ hda_nid_t nid, dac; - - for (i = 0; i < cfg->line_outs; i++) { - nid = cfg->line_out_pins[i]; -- conn_len = snd_hda_get_connections(codec, nid, conn, -- HDA_MAX_CONNECTIONS); -- for (j = 0; j < conn_len; j++) { -- wcaps = snd_hda_param_read(codec, conn[j], -- AC_PAR_AUDIO_WIDGET_CAP); -- wtype = (wcaps & AC_WCAP_TYPE) >> AC_WCAP_TYPE_SHIFT; -- if (wtype != AC_WID_AUD_OUT || -- (wcaps & AC_WCAP_DIGITAL)) -- continue; -- /* conn[j] is a DAC routed to this line-out */ -- if (!is_in_dac_nids(spec, conn[j])) -- break; -- } -- -- if (j == conn_len) { -+ dac = get_unassigned_dac(codec, nid); -+ if (!dac) { - if (spec->multiout.num_dacs > 0) { - /* we have already working output pins, - * so let's drop the broken ones again -@@ -2879,30 +2941,70 @@ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec, - __func__, nid); - return -ENODEV; - } -+ add_spec_dacs(spec, dac); -+ } + return 0; + } + +@@ -2880,6 +2944,26 @@ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec) + add_spec_dacs(spec, dac); + } -- spec->multiout.dac_nids[i] = conn[j]; -- spec->multiout.num_dacs++; -- if (conn_len > 1) { -- /* select this DAC in the pin's input mux */ -- snd_hda_codec_write_cache(codec, nid, 0, -- AC_VERB_SET_CONNECT_SEL, j); + for (i = 0; i < cfg->hp_outs; i++) { + nid = cfg->hp_pins[i]; + dac = get_unassigned_dac(codec, nid); @@ -14796,44 +11744,38 @@ index 5e89424..d2fd8ef 100644 + add_spec_extra_dacs(spec, dac); + spec->speaker_dacs[i] = dac; + } - -+ /* add line-in as output */ -+ nid = check_line_out_switch(codec); -+ if (nid) { -+ dac = get_unassigned_dac(codec, nid); -+ if (dac) { -+ snd_printdd("STAC: Add line-in 0x%x as output %d\n", -+ nid, cfg->line_outs); -+ cfg->line_out_pins[cfg->line_outs] = nid; -+ cfg->line_outs++; -+ spec->line_switch = nid; -+ add_spec_dacs(spec, dac); -+ } -+ } -+ /* add mic as output */ -+ nid = check_mic_out_switch(codec); -+ if (nid) { -+ dac = get_unassigned_dac(codec, nid); -+ if (dac) { -+ snd_printdd("STAC: Add mic-in 0x%x as output %d\n", -+ nid, cfg->line_outs); -+ cfg->line_out_pins[cfg->line_outs] = nid; -+ cfg->line_outs++; -+ spec->mic_switch = nid; -+ add_spec_dacs(spec, dac); ++ + /* add line-in as output */ + nid = check_line_out_switch(codec); + if (nid) { +@@ -2907,26 +2991,6 @@ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec) } } -- snd_printd("dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n", -+ snd_printd("stac92xx: dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n", +- for (i = 0; i < cfg->hp_outs; i++) { +- nid = cfg->hp_pins[i]; +- dac = get_unassigned_dac(codec, nid); +- if (dac) { +- if (!spec->multiout.hp_nid) +- spec->multiout.hp_nid = dac; +- else +- add_spec_extra_dacs(spec, dac); +- } +- spec->hp_dacs[i] = dac; +- } +- +- for (i = 0; i < cfg->speaker_outs; i++) { +- nid = cfg->speaker_pins[i]; +- dac = get_unassigned_dac(codec, nid); +- if (dac) +- add_spec_extra_dacs(spec, dac); +- spec->speaker_dacs[i] = dac; +- } +- + snd_printd("stac92xx: dac_nids=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n", spec->multiout.num_dacs, spec->multiout.dac_nids[0], - spec->multiout.dac_nids[1], - spec->multiout.dac_nids[2], - spec->multiout.dac_nids[3], - spec->multiout.dac_nids[4]); -+ - return 0; +@@ -2939,8 +3003,8 @@ static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec) } /* create volume control/switch for the given prefx type */ @@ -14844,7 +11786,7 @@ index 5e89424..d2fd8ef 100644 { struct sigmatel_spec *spec = codec->spec; char name[32]; -@@ -2926,24 +3028,25 @@ static int create_controls(struct hda_codec *codec, const char *pfx, +@@ -2964,19 +3028,22 @@ static int create_controls(struct hda_codec *codec, const char *pfx, } sprintf(name, "%s Playback Volume", pfx); @@ -14868,249 +11810,47 @@ index 5e89424..d2fd8ef 100644 + static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid) { -- if (!spec->multiout.hp_nid) -- spec->multiout.hp_nid = nid; -- else if (spec->multiout.num_dacs > 4) { -+ if (spec->multiout.num_dacs > 4) { - printk(KERN_WARNING "stac92xx: No space for DAC 0x%x\n", nid); - return 1; - } else { -@@ -2953,36 +3056,45 @@ static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid) - return 0; - } - --static int check_in_dac_nids(struct sigmatel_spec *spec, hda_nid_t nid) -+static int add_spec_extra_dacs(struct sigmatel_spec *spec, hda_nid_t nid) - { -- if (is_in_dac_nids(spec, nid)) -- return 1; -- if (spec->multiout.hp_nid == nid) -- return 1; -- return 0; -+ int i; -+ for (i = 0; i < ARRAY_SIZE(spec->multiout.extra_out_nid); i++) { -+ if (!spec->multiout.extra_out_nid[i]) { -+ spec->multiout.extra_out_nid[i] = nid; -+ return 0; -+ } -+ } -+ printk(KERN_WARNING "stac92xx: No space for extra DAC 0x%x\n", nid); -+ return 1; - } - --/* add playback controls from the parsed DAC table */ --static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec, -- const struct auto_pin_cfg *cfg) -+/* Create output controls -+ * The mixer elements are named depending on the given type (AUTO_PIN_XXX_OUT) -+ */ -+static int create_multi_out_ctls(struct hda_codec *codec, int num_outs, -+ const hda_nid_t *pins, -+ const hda_nid_t *dac_nids, -+ int type) - { -+ struct sigmatel_spec *spec = codec->spec; + if (spec->multiout.num_dacs > 4) { +@@ -3014,12 +3081,6 @@ static int create_multi_out_ctls(struct hda_codec *codec, int num_outs, static const char *chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" }; -- hda_nid_t nid = 0; -+ hda_nid_t nid; +- static const char *hp_pfxs[] = { +- "Headphone", "Headphone2", "Headphone3", "Headphone4" +- }; +- static const char *speaker_pfxs[] = { +- "Speaker", "External Speaker", "Speaker2", "Speaker3" +- }; + hda_nid_t nid; int i, err; -+ unsigned int wid_caps; - -- struct sigmatel_spec *spec = codec->spec; -- unsigned int wid_caps, pincap; -- -- -- for (i = 0; i < cfg->line_outs && i < spec->multiout.num_dacs; i++) { -- if (!spec->multiout.dac_nids[i]) -+ for (i = 0; i < num_outs && i < ARRAY_SIZE(chname); i++) { -+ if (type == AUTO_PIN_HP_OUT && !spec->hp_detect) { -+ wid_caps = get_wcaps(codec, pins[i]); -+ if (wid_caps & AC_WCAP_UNSOL_CAP) -+ spec->hp_detect = 1; -+ } -+ nid = dac_nids[i]; -+ if (!nid) - continue; -- -- nid = spec->multiout.dac_nids[i]; -- -- if (i == 2) { -+ if (type != AUTO_PIN_HP_OUT && i == 2) { - /* Center/LFE */ - err = create_controls(codec, "Center", nid, 1); - if (err < 0) -@@ -3003,15 +3115,42 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec, - } + unsigned int wid_caps; +@@ -3055,18 +3116,22 @@ static int create_multi_out_ctls(struct hda_codec *codec, int num_outs, } else { -- err = create_controls(codec, chname[i], nid, 3); -+ const char *name; + const char *name; + int idx; -+ switch (type) { -+ case AUTO_PIN_HP_OUT: + switch (type) { + case AUTO_PIN_HP_OUT: +- name = hp_pfxs[i]; + name = "Headphone"; + idx = i; -+ break; -+ case AUTO_PIN_SPEAKER_OUT: + break; + case AUTO_PIN_SPEAKER_OUT: +- name = speaker_pfxs[i]; + name = "Speaker"; + idx = i; -+ break; -+ default: -+ name = chname[i]; + break; + default: + name = chname[i]; + idx = 0; -+ break; -+ } + break; + } +- err = create_controls(codec, name, nid, 3); + err = create_controls_idx(codec, name, idx, nid, 3); if (err < 0) return err; } - } -+ return 0; -+} -+ -+/* add playback controls from the parsed DAC table */ -+static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec, -+ const struct auto_pin_cfg *cfg) -+{ -+ struct sigmatel_spec *spec = codec->spec; -+ int err; - -- if ((spec->multiout.num_dacs - cfg->line_outs) > 0 && -- cfg->hp_outs == 1 && !spec->multiout.hp_nid) -- spec->multiout.hp_nid = nid; -+ err = create_multi_out_ctls(codec, cfg->line_outs, cfg->line_out_pins, -+ spec->multiout.dac_nids, -+ cfg->line_out_type); -+ if (err < 0) -+ return err; - - if (cfg->hp_outs > 1 && cfg->line_out_type == AUTO_PIN_LINE_OUT) { - err = stac92xx_add_control(spec, -@@ -3023,45 +3162,19 @@ static int stac92xx_auto_create_multi_out_ctls(struct hda_codec *codec, - } - - if (spec->line_switch) { -- nid = cfg->input_pins[AUTO_PIN_LINE]; -- pincap = snd_hda_param_read(codec, nid, -- AC_PAR_PIN_CAP); -- if (pincap & AC_PINCAP_OUT) { -- err = stac92xx_add_control(spec, -- STAC_CTL_WIDGET_IO_SWITCH, -- "Line In as Output Switch", nid << 8); -- if (err < 0) -- return err; -- } -+ err = stac92xx_add_control(spec, STAC_CTL_WIDGET_IO_SWITCH, -+ "Line In as Output Switch", -+ spec->line_switch << 8); -+ if (err < 0) -+ return err; - } - - if (spec->mic_switch) { -- unsigned int def_conf; -- unsigned int mic_pin = AUTO_PIN_MIC; --again: -- nid = cfg->input_pins[mic_pin]; -- def_conf = snd_hda_codec_read(codec, nid, 0, -- AC_VERB_GET_CONFIG_DEFAULT, 0); -- /* some laptops have an internal analog microphone -- * which can't be used as a output */ -- if (get_defcfg_connect(def_conf) != AC_JACK_PORT_FIXED) { -- pincap = snd_hda_param_read(codec, nid, -- AC_PAR_PIN_CAP); -- if (pincap & AC_PINCAP_OUT) { -- err = stac92xx_add_control(spec, -- STAC_CTL_WIDGET_IO_SWITCH, -- "Mic as Output Switch", (nid << 8) | 1); -- nid = snd_hda_codec_read(codec, nid, 0, -- AC_VERB_GET_CONNECT_LIST, 0) & 0xff; -- if (!check_in_dac_nids(spec, nid)) -- add_spec_dacs(spec, nid); -- if (err < 0) -- return err; -- } -- } else if (mic_pin == AUTO_PIN_MIC) { -- mic_pin = AUTO_PIN_FRONT_MIC; -- goto again; -- } -+ err = stac92xx_add_control(spec, STAC_CTL_WIDGET_IO_SWITCH, -+ "Mic as Output Switch", -+ (spec->mic_switch << 8) | 1); -+ if (err < 0) -+ return err; - } - - return 0; -@@ -3072,55 +3185,17 @@ static int stac92xx_auto_create_hp_ctls(struct hda_codec *codec, - struct auto_pin_cfg *cfg) - { - struct sigmatel_spec *spec = codec->spec; -- hda_nid_t nid; -- int i, old_num_dacs, err; -+ int err; - -- old_num_dacs = spec->multiout.num_dacs; -- for (i = 0; i < cfg->hp_outs; i++) { -- unsigned int wid_caps = get_wcaps(codec, cfg->hp_pins[i]); -- if (wid_caps & AC_WCAP_UNSOL_CAP) -- spec->hp_detect = 1; -- nid = snd_hda_codec_read(codec, cfg->hp_pins[i], 0, -- AC_VERB_GET_CONNECT_LIST, 0) & 0xff; -- if (check_in_dac_nids(spec, nid)) -- nid = 0; -- if (! nid) -- continue; -- add_spec_dacs(spec, nid); -- } -- for (i = 0; i < cfg->speaker_outs; i++) { -- nid = snd_hda_codec_read(codec, cfg->speaker_pins[i], 0, -- AC_VERB_GET_CONNECT_LIST, 0) & 0xff; -- if (check_in_dac_nids(spec, nid)) -- nid = 0; -- if (! nid) -- continue; -- add_spec_dacs(spec, nid); -- } -- for (i = 0; i < cfg->line_outs; i++) { -- nid = snd_hda_codec_read(codec, cfg->line_out_pins[i], 0, -- AC_VERB_GET_CONNECT_LIST, 0) & 0xff; -- if (check_in_dac_nids(spec, nid)) -- nid = 0; -- if (! nid) -- continue; -- add_spec_dacs(spec, nid); -- } -- for (i = old_num_dacs; i < spec->multiout.num_dacs; i++) { -- static const char *pfxs[] = { -- "Speaker", "External Speaker", "Speaker2", -- }; -- err = create_controls(codec, pfxs[i - old_num_dacs], -- spec->multiout.dac_nids[i], 3); -- if (err < 0) -- return err; -- } -- if (spec->multiout.hp_nid) { -- err = create_controls(codec, "Headphone", -- spec->multiout.hp_nid, 3); -- if (err < 0) -- return err; -- } -+ err = create_multi_out_ctls(codec, cfg->hp_outs, cfg->hp_pins, -+ spec->hp_dacs, AUTO_PIN_HP_OUT); -+ if (err < 0) -+ return err; -+ -+ err = create_multi_out_ctls(codec, cfg->speaker_outs, cfg->speaker_pins, -+ spec->speaker_dacs, AUTO_PIN_SPEAKER_OUT); -+ if (err < 0) -+ return err; - - return 0; - } -@@ -3330,11 +3405,7 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, +@@ -3340,11 +3405,7 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, unsigned int wcaps; unsigned int def_conf; @@ -15123,85 +11863,7 @@ index 5e89424..d2fd8ef 100644 if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) continue; -@@ -3458,8 +3529,8 @@ static void stac92xx_auto_init_hp_out(struct hda_codec *codec) - static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out, hda_nid_t dig_in) - { - struct sigmatel_spec *spec = codec->spec; -+ int hp_swap = 0; - int err; -- int hp_speaker_swap = 0; - - if ((err = snd_hda_parse_pin_def_config(codec, - &spec->autocfg, -@@ -3477,13 +3548,16 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out - * speaker_outs so that the following routines can handle - * HP pins as primary outputs. - */ -+ snd_printdd("stac92xx: Enabling multi-HPs workaround\n"); - memcpy(spec->autocfg.speaker_pins, spec->autocfg.line_out_pins, - sizeof(spec->autocfg.line_out_pins)); - spec->autocfg.speaker_outs = spec->autocfg.line_outs; - memcpy(spec->autocfg.line_out_pins, spec->autocfg.hp_pins, - sizeof(spec->autocfg.hp_pins)); - spec->autocfg.line_outs = spec->autocfg.hp_outs; -- hp_speaker_swap = 1; -+ spec->autocfg.line_out_type = AUTO_PIN_HP_OUT; -+ spec->autocfg.hp_outs = 0; -+ hp_swap = 1; - } - if (spec->autocfg.mono_out_pin) { - int dir = get_wcaps(codec, spec->autocfg.mono_out_pin) & -@@ -3535,10 +3609,9 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out - AC_PINCTL_OUT_EN); - } - -- if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0) -- return err; -- if (spec->multiout.num_dacs == 0) { -- if ((err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg)) < 0) -+ if (!spec->multiout.num_dacs) { -+ err = stac92xx_auto_fill_dac_nids(codec); -+ if (err < 0) - return err; - err = stac92xx_auto_create_multi_out_ctls(codec, - &spec->autocfg); -@@ -3577,26 +3650,20 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out - } - #endif - -- if (hp_speaker_swap == 1) { -- /* Restore the hp_outs and line_outs */ -- memcpy(spec->autocfg.hp_pins, spec->autocfg.line_out_pins, -- sizeof(spec->autocfg.line_out_pins)); -- spec->autocfg.hp_outs = spec->autocfg.line_outs; -- memcpy(spec->autocfg.line_out_pins, spec->autocfg.speaker_pins, -- sizeof(spec->autocfg.speaker_pins)); -- spec->autocfg.line_outs = spec->autocfg.speaker_outs; -- memset(spec->autocfg.speaker_pins, 0, -- sizeof(spec->autocfg.speaker_pins)); -- spec->autocfg.speaker_outs = 0; -- } -- - err = stac92xx_auto_create_hp_ctls(codec, &spec->autocfg); -- - if (err < 0) - return err; - -- err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg); -+ /* All output parsing done, now restore the swapped hp pins */ -+ if (hp_swap) { -+ memcpy(spec->autocfg.hp_pins, spec->autocfg.line_out_pins, -+ sizeof(spec->autocfg.hp_pins)); -+ spec->autocfg.hp_outs = spec->autocfg.line_outs; -+ spec->autocfg.line_out_type = AUTO_PIN_HP_OUT; -+ spec->autocfg.line_outs = 0; -+ } - -+ err = stac92xx_auto_create_analog_input_ctls(codec, &spec->autocfg); - if (err < 0) - return err; - -@@ -3625,20 +3692,25 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out +@@ -3631,17 +3692,21 @@ static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out return err; } @@ -15225,13 +11887,8 @@ index 5e89424..d2fd8ef 100644 + spec->mixers[spec->num_mixers++] = spec->kctls.list; spec->input_mux = &spec->private_imux; -- spec->dinput_mux = &spec->private_dimux; -+ if (!spec->dinput_mux) -+ 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; -@@ -3691,9 +3763,7 @@ static int stac9200_auto_create_lfe_ctls(struct hda_codec *codec, + if (!spec->dinput_mux) +@@ -3698,9 +3763,7 @@ static int stac9200_auto_create_lfe_ctls(struct hda_codec *codec, for (i = 0; i < spec->autocfg.line_outs && lfe_pin == 0x0; i++) { hda_nid_t pin = spec->autocfg.line_out_pins[i]; unsigned int defcfg; @@ -15242,7 +11899,7 @@ index 5e89424..d2fd8ef 100644 if (get_defcfg_device(defcfg) == AC_JACK_SPEAKER) { unsigned int wcaps = get_wcaps(codec, pin); wcaps &= (AC_WCAP_STEREO | AC_WCAP_OUT_AMP); -@@ -3737,13 +3807,17 @@ static int stac9200_parse_auto_config(struct hda_codec *codec) +@@ -3744,13 +3807,17 @@ static int stac9200_parse_auto_config(struct hda_codec *codec) return err; } @@ -15263,7 +11920,7 @@ index 5e89424..d2fd8ef 100644 spec->input_mux = &spec->private_imux; spec->dinput_mux = &spec->private_dimux; -@@ -3787,13 +3861,115 @@ static void stac_gpio_set(struct hda_codec *codec, unsigned int mask, +@@ -3794,17 +3861,64 @@ static void stac_gpio_set(struct hda_codec *codec, unsigned int mask, AC_VERB_SET_GPIO_DATA, gpiostate); /* sync */ } @@ -15303,99 +11960,61 @@ index 5e89424..d2fd8ef 100644 + snd_hda_get_jack_location(def_conf)); + + err = snd_jack_new(codec->bus->card, name, type, &jack->jack); -+ if (err < 0) { -+ jack->nid = 0; -+ return err; -+ } -+ jack->jack->private_data = jack; -+ jack->jack->private_free = stac92xx_free_jack_priv; -+#endif -+ return 0; -+} -+ -+static int stac_add_event(struct sigmatel_spec *spec, hda_nid_t nid, -+ unsigned char type, int data) -+{ -+ struct sigmatel_event *event; -+ -+ snd_array_init(&spec->events, sizeof(*event), 32); -+ event = snd_array_new(&spec->events); -+ if (!event) -+ return -ENOMEM; -+ event->nid = nid; -+ event->type = type; -+ event->tag = spec->events.used; -+ event->data = data; -+ -+ return event->tag; -+} -+ -+static struct sigmatel_event *stac_get_event(struct hda_codec *codec, -+ hda_nid_t nid, unsigned char type) -+{ -+ struct sigmatel_spec *spec = codec->spec; -+ struct sigmatel_event *event = spec->events.list; -+ int i; -+ -+ for (i = 0; i < spec->events.used; i++, event++) { -+ if (event->nid == nid && event->type == type) -+ return event; -+ } -+ return NULL; -+} -+ -+static struct sigmatel_event *stac_get_event_from_tag(struct hda_codec *codec, -+ unsigned char tag) -+{ -+ struct sigmatel_spec *spec = codec->spec; -+ struct sigmatel_event *event = spec->events.list; -+ int i; -+ -+ for (i = 0; i < spec->events.used; i++, event++) { -+ if (event->tag == tag) -+ return event; ++ if (err < 0) { ++ jack->nid = 0; ++ return err; + } -+ return NULL; ++ jack->jack->private_data = jack; ++ jack->jack->private_free = stac92xx_free_jack_priv; ++#endif ++ return 0; +} + - static void enable_pin_detect(struct hda_codec *codec, hda_nid_t nid, -- unsigned int event) -+ unsigned int type) + static int stac_add_event(struct sigmatel_spec *spec, hda_nid_t nid, + unsigned char type, int data) { -- if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) -- snd_hda_codec_write_cache(codec, nid, 0, -- AC_VERB_SET_UNSOLICITED_ENABLE, -- (AC_USRSP_EN | event)); -+ struct sigmatel_event *event; -+ int tag; -+ -+ if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP)) -+ return; -+ event = stac_get_event(codec, nid, type); -+ if (event) -+ tag = event->tag; -+ else -+ tag = stac_add_event(codec->spec, nid, type, 0); -+ if (tag < 0) -+ return; -+ snd_hda_codec_write_cache(codec, nid, 0, -+ AC_VERB_SET_UNSOLICITED_ENABLE, -+ AC_USRSP_EN | tag); - } + struct sigmatel_event *event; - static int is_nid_hp_pin(struct auto_pin_cfg *cfg, hda_nid_t nid) -@@ -3813,15 +3989,44 @@ static void stac92xx_power_down(struct hda_codec *codec) - /* power down inactive DACs */ - hda_nid_t *dac; - for (dac = spec->dac_list; *dac; dac++) -- if (!is_in_dac_nids(spec, *dac) && -- spec->multiout.hp_nid != *dac) -- snd_hda_codec_write_cache(codec, *dac, 0, -+ if (!check_all_dac_nids(spec, *dac)) -+ snd_hda_codec_write(codec, *dac, 0, - AC_VERB_SET_POWER_STATE, AC_PWRST_D3); - } +- if (spec->num_events >= ARRAY_SIZE(spec->events)) ++ snd_array_init(&spec->events, sizeof(*event), 32); ++ event = snd_array_new(&spec->events); ++ if (!event) + return -ENOMEM; +- event = &spec->events[spec->num_events++]; + event->nid = nid; + event->type = type; +- event->tag = spec->num_events; ++ event->tag = spec->events.used; + event->data = data; + + return event->tag; +@@ -3814,10 +3928,10 @@ static struct sigmatel_event *stac_get_event(struct hda_codec *codec, + hda_nid_t nid, unsigned char type) + { + struct sigmatel_spec *spec = codec->spec; +- struct sigmatel_event *event = spec->events; ++ struct sigmatel_event *event = spec->events.list; + int i; +- for (i = 0; i < spec->num_events; i++, event++) { ++ for (i = 0; i < spec->events.used; i++, event++) { + if (event->nid == nid && event->type == type) + return event; + } +@@ -3828,10 +3942,10 @@ static struct sigmatel_event *stac_get_event_from_tag(struct hda_codec *codec, + unsigned char tag) + { + struct sigmatel_spec *spec = codec->spec; +- struct sigmatel_event *event = spec->events; ++ struct sigmatel_event *event = spec->events.list; + int i; + +- for (i = 0; i < spec->num_events; i++, event++) { ++ for (i = 0; i < spec->events.used; i++, event++) { + if (event->tag == tag) + return event; + } +@@ -3883,6 +3997,36 @@ static void stac92xx_power_down(struct hda_codec *codec) static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid, int enable); @@ -15432,12 +12051,7 @@ index 5e89424..d2fd8ef 100644 static int stac92xx_init(struct hda_codec *codec) { struct sigmatel_spec *spec = codec->spec; -@@ -3834,10 +4039,13 @@ static int stac92xx_init(struct hda_codec *codec) - /* power down adcs initially */ - if (spec->powerdown_adcs) - for (i = 0; i < spec->num_adcs; i++) -- snd_hda_codec_write_cache(codec, -+ snd_hda_codec_write(codec, +@@ -3899,6 +4043,9 @@ static int stac92xx_init(struct hda_codec *codec) spec->adc_nids[i], 0, AC_VERB_SET_POWER_STATE, AC_PWRST_D3); @@ -15447,72 +12061,38 @@ index 5e89424..d2fd8ef 100644 /* set up GPIO */ gpio = spec->gpio_data; /* turn on EAPD statically when spec->eapd_switch isn't set. -@@ -3850,44 +4058,62 @@ static int stac92xx_init(struct hda_codec *codec) - /* set up pins */ - if (spec->hp_detect) { - /* Enable unsolicited responses on the HP widget */ -- for (i = 0; i < cfg->hp_outs; i++) -- enable_pin_detect(codec, cfg->hp_pins[i], -- STAC_HP_EVENT); -+ for (i = 0; i < cfg->hp_outs; i++) { -+ hda_nid_t nid = cfg->hp_pins[i]; -+ enable_pin_detect(codec, nid, STAC_HP_EVENT); -+ } - /* force to enable the first line-out; the others are set up +@@ -3919,7 +4066,7 @@ static int stac92xx_init(struct hda_codec *codec) * in unsol_event */ stac92xx_auto_set_pinctl(codec, spec->autocfg.line_out_pins[0], - AC_PINCTL_OUT_EN); -- stac92xx_auto_init_hp_out(codec); + AC_PINCTL_OUT_EN); /* fake event to set up pins */ -- codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26); -+ stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0], -+ STAC_HP_EVENT); - } else { - stac92xx_auto_init_multi_out(codec); - stac92xx_auto_init_hp_out(codec); -+ for (i = 0; i < cfg->hp_outs; i++) -+ stac_toggle_power_map(codec, cfg->hp_pins[i], 1); - } - for (i = 0; i < AUTO_PIN_LAST; i++) { - hda_nid_t nid = cfg->input_pins[i]; - if (nid) { -- unsigned int pinctl; -+ unsigned int pinctl, conf; - if (i == AUTO_PIN_MIC || i == AUTO_PIN_FRONT_MIC) { - /* for mic pins, force to initialize */ - pinctl = stac92xx_get_vref(codec, nid); -+ pinctl |= AC_PINCTL_IN_EN; -+ stac92xx_auto_set_pinctl(codec, nid, pinctl); - } else { + stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0], + STAC_HP_EVENT); +@@ -3942,14 +4089,18 @@ static int stac92xx_init(struct hda_codec *codec) pinctl = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0); /* if PINCTL already set then skip */ -- if (pinctl & AC_PINCTL_IN_EN) -- continue; +- if (!(pinctl & AC_PINCTL_IN_EN)) { + /* Also, if both INPUT and OUTPUT are set, + * it must be a BIOS bug; need to override, too + */ + if (!(pinctl & AC_PINCTL_IN_EN) || + (pinctl & AC_PINCTL_OUT_EN)) { + pinctl &= ~AC_PINCTL_OUT_EN; -+ pinctl |= AC_PINCTL_IN_EN; -+ stac92xx_auto_set_pinctl(codec, nid, -+ pinctl); -+ } -+ } -+ conf = snd_hda_codec_get_pincfg(codec, nid); -+ if (get_defcfg_connect(conf) != AC_JACK_PORT_FIXED) { -+ enable_pin_detect(codec, nid, -+ STAC_INSERT_EVENT); -+ stac_issue_unsol_event(codec, nid, -+ STAC_INSERT_EVENT); + pinctl |= AC_PINCTL_IN_EN; + stac92xx_auto_set_pinctl(codec, nid, + pinctl); + } } -- pinctl |= AC_PINCTL_IN_EN; -- stac92xx_auto_set_pinctl(codec, nid, pinctl); - } - } +- conf = snd_hda_codec_read(codec, nid, 0, +- AC_VERB_GET_CONFIG_DEFAULT, 0); ++ conf = snd_hda_codec_get_pincfg(codec, nid); + if (get_defcfg_connect(conf) != AC_JACK_PORT_FIXED) { + enable_pin_detect(codec, nid, + STAC_INSERT_EVENT); +@@ -3961,8 +4112,8 @@ static int stac92xx_init(struct hda_codec *codec) for (i = 0; i < spec->num_dmics; i++) stac92xx_auto_set_pinctl(codec, spec->dmic_nids[i], AC_PINCTL_IN_EN); @@ -15523,51 +12103,17 @@ index 5e89424..d2fd8ef 100644 AC_PINCTL_OUT_EN); if (cfg->dig_in_pin) stac92xx_auto_set_pinctl(codec, cfg->dig_in_pin, -@@ -3895,9 +4121,14 @@ static int stac92xx_init(struct hda_codec *codec) - for (i = 0; i < spec->num_pwrs; i++) { - hda_nid_t nid = spec->pwr_nids[i]; - int pinctl, def_conf; -- int event = STAC_PWR_EVENT; - -- if (is_nid_hp_pin(cfg, nid) && spec->hp_detect) -+ /* power on when no jack detection is available */ -+ if (!spec->hp_detect) { -+ stac_toggle_power_map(codec, nid, 1); -+ continue; -+ } -+ -+ if (is_nid_hp_pin(cfg, nid)) - continue; /* already has an unsol event */ - - pinctl = snd_hda_codec_read(codec, nid, 0, -@@ -3906,10 +4137,11 @@ static int stac92xx_init(struct hda_codec *codec) - * any attempts on powering down a input port cause the - * referenced VREF to act quirky. - */ -- if (pinctl & AC_PINCTL_IN_EN) -+ if (pinctl & AC_PINCTL_IN_EN) { -+ stac_toggle_power_map(codec, nid, 1); +@@ -3990,8 +4141,7 @@ static int stac92xx_init(struct hda_codec *codec) + stac_toggle_power_map(codec, nid, 1); continue; + } - def_conf = snd_hda_codec_read(codec, nid, 0, - AC_VERB_GET_CONFIG_DEFAULT, 0); -+ } + def_conf = snd_hda_codec_get_pincfg(codec, nid); def_conf = get_defcfg_connect(def_conf); /* skip any ports that don't have jacks since presence * detection is useless */ -@@ -3918,30 +4150,55 @@ static int stac92xx_init(struct hda_codec *codec) - stac_toggle_power_map(codec, nid, 1); - continue; - } -- enable_pin_detect(codec, spec->pwr_nids[i], event | i); -- codec->patch_ops.unsol_event(codec, (event | i) << 26); -+ if (!stac_get_event(codec, nid, STAC_INSERT_EVENT)) { -+ enable_pin_detect(codec, nid, STAC_PWR_EVENT); -+ stac_issue_unsol_event(codec, nid, STAC_PWR_EVENT); -+ } - } - if (spec->dac_list) - stac92xx_power_down(codec); +@@ -4010,22 +4160,45 @@ static int stac92xx_init(struct hda_codec *codec) return 0; } @@ -15622,7 +12168,7 @@ index 5e89424..d2fd8ef 100644 kfree(spec); snd_hda_detach_beep_device(codec); -@@ -3950,7 +4207,9 @@ static void stac92xx_free(struct hda_codec *codec) +@@ -4034,7 +4207,9 @@ static void stac92xx_free(struct hda_codec *codec) static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid, unsigned int flag) { @@ -15633,16 +12179,7 @@ index 5e89424..d2fd8ef 100644 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00); if (pin_ctl & AC_PINCTL_IN_EN) { -@@ -3960,22 +4219,21 @@ static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid, - * "xxx as Output" mixer switch - */ - struct sigmatel_spec *spec = codec->spec; -- struct auto_pin_cfg *cfg = &spec->autocfg; -- if ((nid == cfg->input_pins[AUTO_PIN_LINE] && -- spec->line_switch) || -- (nid == cfg->input_pins[AUTO_PIN_MIC] && -- spec->mic_switch)) -+ if (nid == spec->line_switch || nid == spec->mic_switch) +@@ -4048,14 +4223,17 @@ static void stac92xx_set_pinctl(struct hda_codec *codec, hda_nid_t nid, return; } @@ -15663,7 +12200,7 @@ index 5e89424..d2fd8ef 100644 } static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid, -@@ -3983,25 +4241,19 @@ static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid, +@@ -4063,9 +4241,10 @@ static void stac92xx_reset_pinctl(struct hda_codec *codec, hda_nid_t nid, { unsigned int pin_ctl = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_WIDGET_CONTROL, 0x00); @@ -15676,93 +12213,11 @@ index 5e89424..d2fd8ef 100644 + pin_ctl & ~flag); } --static int get_hp_pin_presence(struct hda_codec *codec, hda_nid_t nid) -+static int get_pin_presence(struct hda_codec *codec, hda_nid_t nid) - { - if (!nid) - return 0; - if (snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_PIN_SENSE, 0x00) -- & (1 << 31)) { -- unsigned int pinctl; -- pinctl = snd_hda_codec_read(codec, nid, 0, -- AC_VERB_GET_PIN_WIDGET_CONTROL, 0); -- if (pinctl & AC_PINCTL_IN_EN) -- return 0; /* mic- or line-input */ -- else -- return 1; /* HP-output */ -- } -+ & (1 << 31)) -+ return 1; - return 0; - } - -@@ -4013,11 +4265,9 @@ static int no_hp_sensing(struct sigmatel_spec *spec, int i) - struct auto_pin_cfg *cfg = &spec->autocfg; - - /* ignore sensing of shared line and mic jacks */ -- if (spec->line_switch && -- cfg->hp_pins[i] == cfg->input_pins[AUTO_PIN_LINE]) -+ if (cfg->hp_pins[i] == spec->line_switch) - return 1; -- if (spec->mic_switch && -- cfg->hp_pins[i] == cfg->input_pins[AUTO_PIN_MIC]) -+ if (cfg->hp_pins[i] == spec->mic_switch) - return 1; - /* ignore if the pin is set as line-out */ - if (cfg->hp_pins[i] == spec->hp_switch) -@@ -4025,7 +4275,7 @@ static int no_hp_sensing(struct sigmatel_spec *spec, int i) - return 0; + static int get_pin_presence(struct hda_codec *codec, hda_nid_t nid) +@@ -4210,6 +4389,33 @@ static void stac92xx_pin_sense(struct hda_codec *codec, hda_nid_t nid) + stac_toggle_power_map(codec, nid, get_pin_presence(codec, nid)); } --static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res) -+static void stac92xx_hp_detect(struct hda_codec *codec) - { - struct sigmatel_spec *spec = codec->spec; - struct auto_pin_cfg *cfg = &spec->autocfg; -@@ -4041,7 +4291,14 @@ static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res) - break; - if (no_hp_sensing(spec, i)) - continue; -- presence = get_hp_pin_presence(codec, cfg->hp_pins[i]); -+ presence = get_pin_presence(codec, cfg->hp_pins[i]); -+ if (presence) { -+ unsigned int pinctl; -+ pinctl = snd_hda_codec_read(codec, cfg->hp_pins[i], 0, -+ AC_VERB_GET_PIN_WIDGET_CONTROL, 0); -+ if (pinctl & AC_PINCTL_IN_EN) -+ presence = 0; /* mic- or line-input */ -+ } - } - - if (presence) { -@@ -4082,8 +4339,19 @@ static void stac92xx_hp_detect(struct hda_codec *codec, unsigned int res) - continue; - if (presence) - stac92xx_set_pinctl(codec, cfg->hp_pins[i], val); -+#if 0 /* FIXME */ -+/* Resetting the pinctl like below may lead to (a sort of) regressions -+ * on some devices since they use the HP pin actually for line/speaker -+ * outs although the default pin config shows a different pin (that is -+ * wrong and useless). -+ * -+ * So, it's basically a problem of default pin configs, likely a BIOS issue. -+ * But, disabling the code below just works around it, and I'm too tired of -+ * bug reports with such devices... -+ */ - else - stac92xx_reset_pinctl(codec, cfg->hp_pins[i], val); -+#endif /* FIXME */ - } - } - -@@ -4118,50 +4386,193 @@ static void stac_toggle_power_map(struct hda_codec *codec, hda_nid_t nid, - - static void stac92xx_pin_sense(struct hda_codec *codec, hda_nid_t nid) - { -- stac_toggle_power_map(codec, nid, get_hp_pin_presence(codec, nid)); -+ stac_toggle_power_map(codec, nid, get_pin_presence(codec, nid)); -+} -+ +static void stac92xx_report_jack(struct hda_codec *codec, hda_nid_t nid) +{ + struct sigmatel_spec *spec = codec->spec; @@ -15790,38 +12245,13 @@ index 5e89424..d2fd8ef 100644 + } +} + -+static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid, -+ unsigned char type) -+{ -+ struct sigmatel_event *event = stac_get_event(codec, nid, type); -+ if (!event) -+ return; -+ codec->patch_ops.unsol_event(codec, (unsigned)event->tag << 26); - } - - static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) + static void stac_issue_unsol_event(struct hda_codec *codec, hda_nid_t nid, + unsigned char type) { - struct sigmatel_spec *spec = codec->spec; -- int idx = res >> 26 & 0x0f; -+ struct sigmatel_event *event; -+ int tag, data; - -- switch ((res >> 26) & 0x70) { -+ tag = (res >> 26) & 0x7f; -+ event = stac_get_event_from_tag(codec, tag); -+ if (!event) -+ return; -+ -+ switch (event->type) { - case STAC_HP_EVENT: -- stac92xx_hp_detect(codec, res); -+ stac92xx_hp_detect(codec); - /* fallthru */ -+ case STAC_INSERT_EVENT: +@@ -4238,6 +4444,25 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) case STAC_PWR_EVENT: if (spec->num_pwrs > 0) -- stac92xx_pin_sense(codec, idx); -+ stac92xx_pin_sense(codec, event->nid); + stac92xx_pin_sense(codec, event->nid); + stac92xx_report_jack(codec, event->nid); + + switch (codec->subsystem_id) { @@ -15842,18 +12272,9 @@ index 5e89424..d2fd8ef 100644 + } + } break; -- case STAC_VREF_EVENT: { -- int data = snd_hda_codec_read(codec, codec->afg, 0, -- AC_VERB_GET_GPIO_DATA, 0); -+ case STAC_VREF_EVENT: -+ 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))); -+ !!(data & (1 << event->data))); - break; -- } + case STAC_VREF_EVENT: + data = snd_hda_codec_read(codec, codec->afg, 0, +@@ -4249,12 +4474,57 @@ static void stac92xx_unsol_event(struct hda_codec *codec, unsigned int res) } } @@ -15909,24 +12330,13 @@ index 5e89424..d2fd8ef 100644 struct sigmatel_spec *spec = codec->spec; - stac92xx_set_config_regs(codec); -- snd_hda_sequence_write(codec, spec->init); -- stac_gpio_set(codec, spec->gpio_mask, -- spec->gpio_dir, spec->gpio_data); -+ stac92xx_init(codec); + stac92xx_init(codec); snd_hda_codec_resume_amp(codec); snd_hda_codec_resume_cache(codec); -- /* power down inactive DACs */ -- if (spec->dac_list) -- stac92xx_power_down(codec); -- /* invoke unsolicited event to reset the HP state */ -+ /* fake event to set up pins again to override cached values */ - if (spec->hp_detect) -- codec->patch_ops.unsol_event(codec, STAC_HP_EVENT << 26); -+ stac_issue_unsol_event(codec, spec->autocfg.hp_pins[0], -+ STAC_HP_EVENT); -+ return 0; -+} -+ +@@ -4265,6 +4535,37 @@ static int stac92xx_resume(struct hda_codec *codec) + return 0; + } + + +/* + * using power check for controlling mute led of HP HDX notebooks @@ -15958,25 +12368,10 @@ index 5e89424..d2fd8ef 100644 +} +#endif + -+static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state) -+{ -+ struct sigmatel_spec *spec = codec->spec; -+ if (spec->eapd_mask) -+ stac_gpio_set(codec, spec->gpio_mask, -+ spec->gpio_dir, spec->gpio_data & -+ ~spec->eapd_mask); - return 0; - } - #endif -@@ -4173,6 +4584,7 @@ static struct hda_codec_ops stac92xx_patch_ops = { - .free = stac92xx_free, - .unsol_event = stac92xx_unsol_event, - #ifdef SND_HDA_NEEDS_RESUME -+ .suspend = stac92xx_suspend, - .resume = stac92xx_resume, - #endif - }; -@@ -4192,18 +4604,11 @@ static int patch_stac9200(struct hda_codec *codec) + static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state) + { + struct sigmatel_spec *spec = codec->spec; +@@ -4303,18 +4604,11 @@ static int patch_stac9200(struct hda_codec *codec) spec->board_config = snd_hda_check_board_config(codec, STAC_9200_MODELS, stac9200_models, stac9200_cfg_tbl); @@ -15999,20 +12394,7 @@ index 5e89424..d2fd8ef 100644 spec->multiout.max_channels = 2; spec->multiout.num_dacs = 1; -@@ -4234,6 +4639,12 @@ static int patch_stac9200(struct hda_codec *codec) - return err; - } - -+ /* CF-74 has no headphone detection, and the driver should *NOT* -+ * do detection and HP/speaker toggle because the hardware does it. -+ */ -+ if (spec->board_config == STAC_9200_PANASONIC) -+ spec->hp_detect = 0; -+ - codec->patch_ops = stac92xx_patch_ops; - - return 0; -@@ -4265,19 +4676,12 @@ static int patch_stac925x(struct hda_codec *codec) +@@ -4382,19 +4676,12 @@ static int patch_stac925x(struct hda_codec *codec) stac925x_models, stac925x_cfg_tbl); again: @@ -16036,15 +12418,7 @@ index 5e89424..d2fd8ef 100644 spec->multiout.max_channels = 2; spec->multiout.num_dacs = 1; -@@ -4340,6 +4744,7 @@ static int patch_stac92hd73xx(struct hda_codec *codec) - struct sigmatel_spec *spec; - hda_nid_t conn[STAC92HD73_DAC_COUNT + 2]; - int err = 0; -+ int num_dacs; - - spec = kzalloc(sizeof(*spec), GFP_KERNEL); - if (spec == NULL) -@@ -4354,47 +4759,40 @@ static int patch_stac92hd73xx(struct hda_codec *codec) +@@ -4472,19 +4759,12 @@ static int patch_stac92hd73xx(struct hda_codec *codec) stac92hd73xx_models, stac92hd73xx_cfg_tbl); again: @@ -16066,54 +12440,28 @@ index 5e89424..d2fd8ef 100644 + stac92xx_set_config_regs(codec, + stac92hd73xx_brd_tbl[spec->board_config]); -- spec->multiout.num_dacs = snd_hda_get_connections(codec, 0x0a, -+ num_dacs = snd_hda_get_connections(codec, 0x0a, + num_dacs = snd_hda_get_connections(codec, 0x0a, conn, STAC92HD73_DAC_COUNT + 2) - 1; - -- if (spec->multiout.num_dacs < 0) { -+ if (num_dacs < 3 || num_dacs > 5) { - printk(KERN_WARNING "hda_codec: Could not determine " - "number of channels defaulting to DAC count\n"); -- spec->multiout.num_dacs = STAC92HD73_DAC_COUNT; -+ num_dacs = STAC92HD73_DAC_COUNT; - } -- -- switch (spec->multiout.num_dacs) { -+ switch (num_dacs) { +@@ -4498,14 +4778,18 @@ again: case 0x3: /* 6 Channel */ -- spec->multiout.hp_nid = 0x17; spec->mixer = stac92hd73xx_6ch_mixer; spec->init = stac92hd73xx_6ch_core_init; + spec->aloopback_ctl = stac92hd73xx_6ch_loopback; break; case 0x4: /* 8 Channel */ -- spec->multiout.hp_nid = 0x18; spec->mixer = stac92hd73xx_8ch_mixer; spec->init = stac92hd73xx_8ch_core_init; + spec->aloopback_ctl = stac92hd73xx_8ch_loopback; break; case 0x5: /* 10 Channel */ -- spec->multiout.hp_nid = 0x19; spec->mixer = stac92hd73xx_10ch_mixer; spec->init = stac92hd73xx_10ch_core_init; -- }; + spec->aloopback_ctl = stac92hd73xx_10ch_loopback; + break; -+ } -+ spec->multiout.dac_nids = spec->dac_nids; - -- spec->multiout.dac_nids = stac92hd73xx_dac_nids; - spec->aloopback_mask = 0x01; - spec->aloopback_shift = 8; - -@@ -4425,24 +4823,23 @@ again: - spec->amp_nids = &stac92hd73xx_amp_nids[DELL_M6_AMP]; - spec->eapd_switch = 0; - spec->num_amps = 1; -- spec->multiout.hp_nid = 0; /* dual HPs */ + } + spec->multiout.dac_nids = spec->dac_nids; -- if (!spec->init) -+ if (spec->board_config != STAC_DELL_EQ) +@@ -4544,18 +4828,18 @@ again: spec->init = dell_m6_core_init; switch (spec->board_config) { case STAC_DELL_M6_AMIC: /* Analog Mics */ @@ -16136,7 +12484,7 @@ index 5e89424..d2fd8ef 100644 spec->num_dmics = 1; spec->private_dimux.num_items = 2; break; -@@ -4485,6 +4882,8 @@ again: +@@ -4598,6 +4882,8 @@ again: codec->patch_ops = stac92xx_patch_ops; @@ -16145,47 +12493,30 @@ index 5e89424..d2fd8ef 100644 return 0; } -@@ -4500,7 +4899,10 @@ static struct hda_input_mux stac92hd83xxx_dmux = { - static int patch_stac92hd83xxx(struct hda_codec *codec) - { - struct sigmatel_spec *spec; -+ hda_nid_t conn[STAC92HD83_DAC_COUNT + 1]; +@@ -4616,6 +4902,7 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) + hda_nid_t conn[STAC92HD83_DAC_COUNT + 1]; int err; -+ int num_dacs; + int num_dacs; + hda_nid_t nid; spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (spec == NULL) -@@ -4514,25 +4916,17 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) - spec->dmux_nids = stac92hd83xxx_dmux_nids; - spec->adc_nids = stac92hd83xxx_adc_nids; - spec->pwr_nids = stac92hd83xxx_pwr_nids; -+ spec->amp_nids = stac92hd83xxx_amp_nids; - spec->pwr_mapping = stac92hd83xxx_pwr_mapping; +@@ -4634,14 +4921,6 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) spec->num_pwrs = ARRAY_SIZE(stac92hd83xxx_pwr_nids); -- spec->multiout.dac_nids = stac92hd83xxx_dac_nids; -+ spec->multiout.dac_nids = spec->dac_nids; + spec->multiout.dac_nids = spec->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; -- } +- /* set port 0xe to select the last DAC +- */ +- num_dacs = snd_hda_get_connections(codec, 0x0e, +- conn, STAC92HD83_DAC_COUNT + 1) - 1; +- +- snd_hda_codec_write_cache(codec, 0xe, 0, +- AC_VERB_SET_CONNECT_SEL, num_dacs); - + spec->init = stac92hd83xxx_core_init; 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_amps = ARRAY_SIZE(stac92hd83xxx_amp_nids); - spec->num_dmics = STAC92HD83XXX_NUM_DMICS; - spec->dinput_mux = &stac92hd83xxx_dmux; - spec->pin_nids = stac92hd83xxx_pin_nids; -@@ -4541,18 +4935,21 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) +@@ -4656,23 +4935,17 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) stac92hd83xxx_models, stac92hd83xxx_cfg_tbl); again: @@ -16202,22 +12533,19 @@ index 5e89424..d2fd8ef 100644 - } else { - spec->pin_configs = stac92hd83xxx_brd_tbl[spec->board_config]; - stac92xx_set_config_regs(codec); +- } + else + stac92xx_set_config_regs(codec, + stac92hd83xxx_brd_tbl[spec->board_config]); -+ -+ switch (codec->vendor_id) { -+ case 0x111d7604: -+ case 0x111d7605: -+ case 0x111d76d5: -+ if (spec->board_config == STAC_92HD83XXX_PWR_REF) -+ break; -+ spec->num_pwrs = 0; -+ break; - } - err = stac92xx_parse_auto_config(codec, 0x1d, 0); -@@ -4571,73 +4968,110 @@ again: + switch (codec->vendor_id) { + case 0x111d7604: + case 0x111d7605: ++ case 0x111d76d5: + if (spec->board_config == STAC_92HD83XXX_PWR_REF) + break; + spec->num_pwrs = 0; +@@ -4695,12 +4968,40 @@ again: return err; } @@ -16245,13 +12573,7 @@ index 5e89424..d2fd8ef 100644 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); +-static struct hda_input_mux stac92hd71bxx_dmux = { +static struct hda_input_mux stac92hd71bxx_dmux_nomixer = { + .num_items = 3, + .items = { @@ -16260,50 +12582,32 @@ index 5e89424..d2fd8ef 100644 + { "Digital Mic 2", 0x03 }, + } +}; - -- 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 struct hda_input_mux stac92hd71bxx_dmux_amixer = { -+ .num_items = 4, -+ .items = { -+ { "Analog Inputs", 0x00 }, -+ { "Mixer", 0x01 }, -+ { "Digital Mic 1", 0x02 }, -+ { "Digital Mic 2", 0x03 }, + .num_items = 4, + .items = { + { "Analog Inputs", 0x00 }, +@@ -4710,10 +5011,67 @@ static struct hda_input_mux stac92hd71bxx_dmux = { } }; --static int stac92hd71xx_resume(struct hda_codec *codec) +/* get the pin connection (fixed, none, etc) */ +static unsigned int stac_get_defcfg_connect(struct hda_codec *codec, int idx) - { -- stac92hd71xx_set_power_state(codec, AC_PWRST_D0); -- return stac92xx_resume(codec); ++{ + struct sigmatel_spec *spec = codec->spec; + unsigned int cfg; + + cfg = snd_hda_codec_get_pincfg(codec, spec->pin_nids[idx]); + return get_defcfg_connect(cfg); - } - --static int stac92hd71xx_suspend(struct hda_codec *codec, pm_message_t state) ++} ++ +static int stac92hd71bxx_connected_ports(struct hda_codec *codec, + hda_nid_t *nids, int num_nids) - { - struct sigmatel_spec *spec = codec->spec; ++{ ++ struct sigmatel_spec *spec = codec->spec; + int idx, num; + unsigned int def_conf; - -- stac92hd71xx_set_power_state(codec, AC_PWRST_D3); -- if (spec->eapd_mask) -- stac_gpio_set(codec, spec->gpio_mask, -- spec->gpio_dir, spec->gpio_data & -- ~spec->eapd_mask); -- return 0; --}; ++ + for (num = 0; num < num_nids; num++) { + for (idx = 0; idx < spec->num_pins; idx++) + if (spec->pin_nids[idx] == nids[num]) @@ -16316,40 +12620,19 @@ index 5e89424..d2fd8ef 100644 + } + return num; +} - --#endif ++ +static int stac92hd71bxx_connected_smuxes(struct hda_codec *codec, + hda_nid_t dig0pin) +{ + struct sigmatel_spec *spec = codec->spec; + int idx; - --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 --}; ++ + for (idx = 0; idx < spec->num_pins; idx++) + if (spec->pin_nids[idx] == dig0pin) + break; + if ((idx + 2) >= spec->num_pins) + return 0; - --static struct hda_input_mux stac92hd71bxx_dmux = { -- .num_items = 4, -- .items = { -- { "Analog Inputs", 0x00 }, -- { "Mixer", 0x01 }, -- { "Digital Mic 1", 0x02 }, -- { "Digital Mic 2", 0x03 }, -- } --}; ++ + /* dig1pin case */ + if (stac_get_defcfg_connect(codec, idx + 1) != AC_JACK_PORT_NONE) + return 2; @@ -16362,7 +12645,7 @@ index 5e89424..d2fd8ef 100644 + else + return 0; +} - ++ static int patch_stac92hd71bxx(struct hda_codec *codec) { struct sigmatel_spec *spec; @@ -16372,7 +12655,7 @@ index 5e89424..d2fd8ef 100644 spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (spec == NULL) -@@ -4645,29 +5079,32 @@ static int patch_stac92hd71bxx(struct hda_codec *codec) +@@ -4721,29 +5079,32 @@ static int patch_stac92hd71bxx(struct hda_codec *codec) codec->spec = spec; codec->patch_ops = stac92xx_patch_ops; @@ -16420,7 +12703,7 @@ index 5e89424..d2fd8ef 100644 if (spec->board_config > STAC_92HD71BXX_REF) { /* GPIO0 = EAPD */ -@@ -4676,34 +5113,52 @@ again: +@@ -4752,16 +5113,34 @@ again: spec->gpio_data = 0x01; } @@ -16455,32 +12738,7 @@ index 5e89424..d2fd8ef 100644 switch (spec->board_config) { case STAC_HP_M4: /* Enable VREF power saving on GPIO1 detect */ -+ err = stac_add_event(spec, codec->afg, -+ STAC_VREF_EVENT, 0x02); -+ if (err < 0) -+ return err; - snd_hda_codec_write_cache(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)); -+ AC_VERB_SET_UNSOLICITED_ENABLE, -+ AC_USRSP_EN | err); - spec->gpio_mask |= 0x02; - break; - } - if ((codec->revision_id & 0xf) == 0 || -- (codec->revision_id & 0xf) == 1) { --#ifdef SND_HDA_NEEDS_RESUME -- codec->patch_ops = stac92hd71bxx_patch_ops; --#endif -+ (codec->revision_id & 0xf) == 1) - spec->stream_delay = 40; /* 40 milliseconds */ -- } - - /* no output amps */ - spec->num_pwrs = 0; -@@ -4712,26 +5167,41 @@ again: +@@ -4788,7 +5167,15 @@ again: /* disable VSW */ spec->init = &stac92hd71bxx_analog_core_init[HD_DISABLE_PORTF]; @@ -16496,15 +12754,8 @@ index 5e89424..d2fd8ef 100644 + ndmic_nids = ARRAY_SIZE(stac92hd71bxx_dmic_nids) - 2; 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 -+ if ((codec->revision_id & 0xf) == 1) - spec->stream_delay = 40; /* 40 milliseconds */ -- } - - /* no output amps */ + if ((codec->revision_id & 0xf) == 1) +@@ -4798,12 +5185,23 @@ again: spec->num_pwrs = 0; /* fallthru */ default: @@ -16528,7 +12779,7 @@ index 5e89424..d2fd8ef 100644 spec->aloopback_mask = 0x50; spec->aloopback_shift = 0; -@@ -4739,18 +5209,17 @@ again: +@@ -4811,18 +5209,17 @@ again: spec->digbeep_nid = 0x26; spec->mux_nids = stac92hd71bxx_mux_nids; spec->adc_nids = stac92hd71bxx_adc_nids; @@ -16549,13 +12800,14 @@ index 5e89424..d2fd8ef 100644 stac92xx_auto_set_pinctl(codec, 0x0e, AC_PINCTL_IN_EN | AC_PINCTL_VREF_80); /* fallthru */ -@@ -4763,23 +5232,38 @@ again: - case STAC_DELL_M4_3: - spec->num_dmics = 1; +@@ -4837,19 +5234,36 @@ again: spec->num_smuxes = 0; -- spec->num_dmuxes = 0; -+ spec->num_dmuxes = 1; -+ break; + spec->num_dmuxes = 1; + break; +- default: +- spec->num_dmics = STAC92HD71BXX_NUM_DMICS; +- spec->num_smuxes = ARRAY_SIZE(stac92hd71bxx_smux_nids); +- spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); + case STAC_HP_DV5: + snd_hda_codec_set_pincfg(codec, 0x0d, 0x90170010); + stac92xx_auto_set_pinctl(codec, 0x0d, AC_PINCTL_OUT_EN); @@ -16578,17 +12830,10 @@ index 5e89424..d2fd8ef 100644 + codec->patch_ops.check_power_status = + stac92xx_hp_hdx_check_power_status; +#endif - break; -- default: -- spec->num_dmics = STAC92HD71BXX_NUM_DMICS; -- spec->num_smuxes = ARRAY_SIZE(stac92hd71bxx_smux_nids); -- spec->num_dmuxes = ARRAY_SIZE(stac92hd71bxx_dmux_nids); ++ break; }; -- spec->multiout.num_dacs = 1; -- spec->multiout.hp_nid = 0x11; -- spec->multiout.dac_nids = stac92hd71bxx_dac_nids; -+ spec->multiout.dac_nids = spec->dac_nids; + spec->multiout.dac_nids = spec->dac_nids; if (spec->dinput_mux) - spec->private_dimux.num_items += - spec->num_dmics - @@ -16600,7 +12845,7 @@ index 5e89424..d2fd8ef 100644 if (!err) { if (spec->board_config < 0) { printk(KERN_WARNING "hda_codec: No auto-config is " -@@ -4795,6 +5279,8 @@ again: +@@ -4865,6 +5279,8 @@ again: return err; } @@ -16609,7 +12854,7 @@ index 5e89424..d2fd8ef 100644 return 0; }; -@@ -4852,19 +5338,12 @@ static int patch_stac922x(struct hda_codec *codec) +@@ -4922,19 +5338,12 @@ static int patch_stac922x(struct hda_codec *codec) } again: @@ -16633,7 +12878,7 @@ index 5e89424..d2fd8ef 100644 spec->adc_nids = stac922x_adc_nids; spec->mux_nids = stac922x_mux_nids; -@@ -4915,26 +5394,19 @@ static int patch_stac927x(struct hda_codec *codec) +@@ -4985,26 +5394,19 @@ static int patch_stac927x(struct hda_codec *codec) return -ENOMEM; codec->spec = spec; @@ -16667,7 +12912,7 @@ index 5e89424..d2fd8ef 100644 spec->digbeep_nid = 0x23; spec->adc_nids = stac927x_adc_nids; -@@ -4963,15 +5435,15 @@ static int patch_stac927x(struct hda_codec *codec) +@@ -5033,15 +5435,15 @@ static int patch_stac927x(struct hda_codec *codec) case 0x10280209: case 0x1028022e: /* correct the device field to SPDIF out */ @@ -16687,7 +12932,7 @@ index 5e89424..d2fd8ef 100644 /* fallthru */ case STAC_DELL_3ST: /* GPIO2 High = Enable EAPD */ -@@ -4998,6 +5470,7 @@ static int patch_stac927x(struct hda_codec *codec) +@@ -5068,6 +5470,7 @@ static int patch_stac927x(struct hda_codec *codec) } spec->num_pwrs = 0; @@ -16695,7 +12940,7 @@ index 5e89424..d2fd8ef 100644 spec->aloopback_mask = 0x40; spec->aloopback_shift = 0; spec->eapd_switch = 1; -@@ -5019,6 +5492,8 @@ static int patch_stac927x(struct hda_codec *codec) +@@ -5089,6 +5492,8 @@ static int patch_stac927x(struct hda_codec *codec) codec->patch_ops = stac92xx_patch_ops; @@ -16704,7 +12949,7 @@ index 5e89424..d2fd8ef 100644 /* * !!FIXME!! * The STAC927x seem to require fairly long delays for certain -@@ -5054,18 +5529,11 @@ static int patch_stac9205(struct hda_codec *codec) +@@ -5124,18 +5529,11 @@ static int patch_stac9205(struct hda_codec *codec) stac9205_models, stac9205_cfg_tbl); again: @@ -16727,7 +12972,7 @@ index 5e89424..d2fd8ef 100644 spec->digbeep_nid = 0x23; spec->adc_nids = stac9205_adc_nids; -@@ -5082,6 +5550,7 @@ static int patch_stac9205(struct hda_codec *codec) +@@ -5152,6 +5550,7 @@ static int patch_stac9205(struct hda_codec *codec) spec->init = stac9205_core_init; spec->mixer = stac9205_mixer; @@ -16735,7 +12980,7 @@ index 5e89424..d2fd8ef 100644 spec->aloopback_mask = 0x40; spec->aloopback_shift = 0; -@@ -5093,15 +5562,18 @@ static int patch_stac9205(struct hda_codec *codec) +@@ -5163,8 +5562,8 @@ static int patch_stac9205(struct hda_codec *codec) switch (spec->board_config){ case STAC_9205_DELL_M43: /* Enable SPDIF in/out */ @@ -16745,19 +12990,8 @@ index 5e89424..d2fd8ef 100644 + snd_hda_codec_set_pincfg(codec, 0x20, 0x1c410030); /* Enable unsol response for GPIO4/Dock HP connection */ -+ err = stac_add_event(spec, codec->afg, STAC_VREF_EVENT, 0x01); -+ if (err < 0) -+ return err; - snd_hda_codec_write_cache(codec, codec->afg, 0, - AC_VERB_SET_GPIO_UNSOLICITED_RSP_MASK, 0x10); - snd_hda_codec_write_cache(codec, codec->afg, 0, - AC_VERB_SET_UNSOLICITED_ENABLE, -- (AC_USRSP_EN | STAC_HP_EVENT)); -+ AC_USRSP_EN | err); - - spec->gpio_dir = 0x0b; - spec->eapd_mask = 0x01; -@@ -5139,6 +5611,8 @@ static int patch_stac9205(struct hda_codec *codec) + err = stac_add_event(spec, codec->afg, STAC_VREF_EVENT, 0x01); +@@ -5212,6 +5611,8 @@ static int patch_stac9205(struct hda_codec *codec) codec->patch_ops = stac92xx_patch_ops; @@ -16766,7 +13000,7 @@ index 5e89424..d2fd8ef 100644 return 0; } -@@ -5146,239 +5620,87 @@ static int patch_stac9205(struct hda_codec *codec) +@@ -5219,239 +5620,87 @@ static int patch_stac9205(struct hda_codec *codec) * STAC9872 hack */ @@ -16793,15 +13027,16 @@ index 5e89424..d2fd8ef 100644 - {0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? (<- 0x2) */ - {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */ - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */ -- {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */ ++static struct hda_verb stac9872_core_init[] = { + {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */ - {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */ - {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */ - {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */ -- {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */ -- {} --}; -- + {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */ + {} + }; + -static struct hda_verb vaio_ar_init[] = { - {0x0a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* HP <- 0x2 */ - {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Speaker <- 0x5 */ @@ -16809,17 +13044,16 @@ index 5e89424..d2fd8ef 100644 - {0x0e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* CD */ -/* {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },*/ /* Optical Out */ - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, /* Mic? */ -+static struct hda_verb stac9872_core_init[] = { - {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */ +- {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */ - {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* HP */ - {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Speaker */ -/* {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},*/ /* Optical Out */ - {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, /* capture sw/vol -> 0x8 */ - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, /* CD-in -> 0x6 */ - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */ - {} - }; - +- {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */ +- {} +-}; +- -/* bind volumes of both NID 0x02 and 0x05 */ -static struct hda_bind_ctls vaio_bind_master_vol = { - .ops = &snd_hda_bind_vol, @@ -16907,7 +13141,7 @@ index 5e89424..d2fd8ef 100644 - -static void stac9872_vaio_hp_detect(struct hda_codec *codec, unsigned int res) -{ -- if (get_hp_pin_presence(codec, 0x0a)) { +- if (get_pin_presence(codec, 0x0a)) { - stac92xx_reset_pinctl(codec, 0x0f, AC_PINCTL_OUT_EN); - stac92xx_set_pinctl(codec, 0x0a, AC_PINCTL_OUT_EN); - } else { @@ -17055,7 +13289,7 @@ index 5e89424..d2fd8ef 100644 return 0; } -@@ -5386,7 +5708,7 @@ static int patch_stac9872(struct hda_codec *codec) +@@ -5459,7 +5708,7 @@ static int patch_stac9872(struct hda_codec *codec) /* * patch entries */ @@ -17064,7 +13298,7 @@ index 5e89424..d2fd8ef 100644 { .id = 0x83847690, .name = "STAC9200", .patch = patch_stac9200 }, { .id = 0x83847882, .name = "STAC9220 A1", .patch = patch_stac922x }, { .id = 0x83847680, .name = "STAC9221 A1", .patch = patch_stac922x }, -@@ -5436,6 +5758,7 @@ struct hda_codec_preset snd_hda_preset_sigmatel[] = { +@@ -5509,6 +5758,7 @@ struct hda_codec_preset snd_hda_preset_sigmatel[] = { { .id = 0x111d7603, .name = "92HD75B3X5", .patch = patch_stac92hd71bxx}, { .id = 0x111d7604, .name = "92HD83C1X5", .patch = patch_stac92hd83xxx}, { .id = 0x111d7605, .name = "92HD81B1X5", .patch = patch_stac92hd83xxx}, @@ -17072,7 +13306,7 @@ index 5e89424..d2fd8ef 100644 { .id = 0x111d7608, .name = "92HD75B2X5", .patch = patch_stac92hd71bxx}, { .id = 0x111d7674, .name = "92HD73D1X5", .patch = patch_stac92hd73xx }, { .id = 0x111d7675, .name = "92HD73C1X5", .patch = patch_stac92hd73xx }, -@@ -5450,3 +5773,27 @@ struct hda_codec_preset snd_hda_preset_sigmatel[] = { +@@ -5523,3 +5773,27 @@ struct hda_codec_preset snd_hda_preset_sigmatel[] = { { .id = 0x111d76b7, .name = "92HD71B5X", .patch = patch_stac92hd71bxx }, {} /* terminator */ }; diff --git a/master/series b/master/series index cd6e6cb..06b65a6 100644 --- a/master/series +++ b/master/series @@ -159,6 +159,7 @@ nfs-allow-0-retransmits.patch # ... Other. cdrom-sysctl-info.patch export-mlock +intel-hda-2.6.30 # # ParaVirtual Memory Management -- 2.39.5