From c71a5e858fc63589ad68e2342686149bb4a72f0f Mon Sep 17 00:00:00 2001 From: Takashi Iwai Date: Thu, 27 Oct 2011 20:47:07 +0200 Subject: [PATCH] --- yaml --- r: 284202 b: refs/heads/master c: 04f5ade6afc4326dc6cd10d235500972fba548eb h: refs/heads/master v: v3 --- [refs] | 2 +- .../sound/alsa/HD-Audio-Models.txt | 1 + .../Documentation/sound/alsa/soc/machine.txt | 6 +- trunk/MAINTAINERS | 1 + trunk/drivers/firmware/sigma.c | 81 +-- trunk/include/linux/sigma.h | 13 +- trunk/sound/pci/cs5535audio/cs5535audio_pcm.c | 2 +- trunk/sound/pci/hda/hda_codec.c | 75 ++- trunk/sound/pci/hda/hda_codec.h | 3 + trunk/sound/pci/hda/hda_eld.c | 28 +- trunk/sound/pci/hda/hda_intel.c | 104 ++-- trunk/sound/pci/hda/hda_local.h | 4 +- trunk/sound/pci/hda/patch_ca0110.c | 2 +- trunk/sound/pci/hda/patch_cirrus.c | 57 +-- trunk/sound/pci/hda/patch_hdmi.c | 36 +- trunk/sound/pci/hda/patch_realtek.c | 136 ++--- trunk/sound/pci/hda/patch_sigmatel.c | 95 ++-- trunk/sound/pci/hda/patch_via.c | 76 ++- trunk/sound/pci/lx6464es/lx_core.c | 23 +- trunk/sound/pci/lx6464es/lx_core.h | 3 + trunk/sound/pci/rme9652/hdspm.c | 2 +- trunk/sound/pci/sis7019.c | 64 +-- trunk/sound/soc/atmel/Kconfig | 21 +- trunk/sound/soc/atmel/Makefile | 4 + trunk/sound/soc/atmel/playpaq_wm8510.c | 473 ++++++++++++++++++ trunk/sound/soc/codecs/ad1836.h | 2 +- trunk/sound/soc/codecs/adau1373.c | 2 +- trunk/sound/soc/codecs/cs4270.c | 10 +- trunk/sound/soc/codecs/cs4271.c | 8 +- trunk/sound/soc/codecs/cs42l51.c | 2 +- trunk/sound/soc/codecs/max9877.c | 10 +- trunk/sound/soc/codecs/rt5631.c | 2 +- trunk/sound/soc/codecs/sgtl5000.c | 2 +- trunk/sound/soc/codecs/sta32x.c | 63 +-- trunk/sound/soc/codecs/sta32x.h | 1 - trunk/sound/soc/codecs/uda1380.c | 4 +- trunk/sound/soc/codecs/wm8731.c | 1 - trunk/sound/soc/codecs/wm8753.c | 3 - trunk/sound/soc/codecs/wm8962.c | 4 +- trunk/sound/soc/codecs/wm8993.c | 2 +- trunk/sound/soc/codecs/wm8994.c | 19 +- trunk/sound/soc/codecs/wm9081.c | 10 +- trunk/sound/soc/codecs/wm9090.c | 6 +- trunk/sound/soc/codecs/wm_hubs.c | 2 +- trunk/sound/soc/fsl/fsl_ssi.c | 1 - trunk/sound/soc/fsl/mpc8610_hpcd.c | 24 +- trunk/sound/soc/imx/Kconfig | 2 +- trunk/sound/soc/kirkwood/Kconfig | 3 +- trunk/sound/soc/pxa/Kconfig | 3 +- trunk/sound/soc/samsung/smdk_wm8994.c | 1 - trunk/sound/soc/samsung/speyside.c | 2 +- trunk/sound/soc/soc-core.c | 6 - trunk/sound/soc/soc-utils.c | 31 +- trunk/sound/usb/quirks-table.h | 31 -- 54 files changed, 898 insertions(+), 671 deletions(-) create mode 100644 trunk/sound/soc/atmel/playpaq_wm8510.c diff --git a/[refs] b/[refs] index 04b35e5cbf51..6194cbd21f75 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: db9c6f842fa957b41984cd8ceea1f07c53fb3fbf +refs/heads/master: 04f5ade6afc4326dc6cd10d235500972fba548eb diff --git a/trunk/Documentation/sound/alsa/HD-Audio-Models.txt b/trunk/Documentation/sound/alsa/HD-Audio-Models.txt index c8c54544abc5..bda546928a42 100644 --- a/trunk/Documentation/sound/alsa/HD-Audio-Models.txt +++ b/trunk/Documentation/sound/alsa/HD-Audio-Models.txt @@ -338,6 +338,7 @@ STAC92HD83* mic-ref Reference board with power management for ports dell-s14 Dell laptop dell-vostro-3500 Dell Vostro 3500 laptop + hp HP laptops with (inverted) mute-LED hp-dv7-4000 HP dv-7 4000 auto BIOS setup (default) diff --git a/trunk/Documentation/sound/alsa/soc/machine.txt b/trunk/Documentation/sound/alsa/soc/machine.txt index d50c14df3411..3e2ec9cbf397 100644 --- a/trunk/Documentation/sound/alsa/soc/machine.txt +++ b/trunk/Documentation/sound/alsa/soc/machine.txt @@ -50,7 +50,8 @@ Machine DAI Configuration The machine DAI configuration glues all the codec and CPU DAIs together. It can also be used to set up the DAI system clock and for any machine related DAI initialisation e.g. the machine audio map can be connected to the codec audio -map, unconnected codec pins can be set as such. +map, unconnected codec pins can be set as such. Please see corgi.c, spitz.c +for examples. struct snd_soc_dai_link is used to set up each DAI in your machine. e.g. @@ -82,7 +83,8 @@ Machine Power Map The machine driver can optionally extend the codec power map and to become an audio power map of the audio subsystem. This allows for automatic power up/down of speaker/HP amplifiers, etc. Codec pins can be connected to the machines jack -sockets in the machine init function. +sockets in the machine init function. See soc/pxa/spitz.c and dapm.txt for +details. Machine Controls diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index fd7e441b5ea7..c802e5fa2d11 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -5648,6 +5648,7 @@ F: drivers/media/video/*7146* F: include/media/*7146* SAMSUNG AUDIO (ASoC) DRIVERS +M: Jassi Brar M: Sangbeom Kim L: alsa-devel@alsa-project.org (moderated for non-subscribers) S: Supported diff --git a/trunk/drivers/firmware/sigma.c b/trunk/drivers/firmware/sigma.c index 1eedb6f7fdab..f10fc521951b 100644 --- a/trunk/drivers/firmware/sigma.c +++ b/trunk/drivers/firmware/sigma.c @@ -14,34 +14,13 @@ #include #include -static size_t sigma_action_size(struct sigma_action *sa) -{ - size_t payload = 0; - - switch (sa->instr) { - case SIGMA_ACTION_WRITEXBYTES: - case SIGMA_ACTION_WRITESINGLE: - case SIGMA_ACTION_WRITESAFELOAD: - payload = sigma_action_len(sa); - break; - default: - break; - } - - payload = ALIGN(payload, 2); - - return payload + sizeof(struct sigma_action); -} - -/* - * Returns a negative error value in case of an error, 0 if processing of - * the firmware should be stopped after this action, 1 otherwise. - */ +/* Return: 0==OK, <0==error, =1 ==no more actions */ static int -process_sigma_action(struct i2c_client *client, struct sigma_action *sa) +process_sigma_action(struct i2c_client *client, struct sigma_firmware *ssfw) { + struct sigma_action *sa = (void *)(ssfw->fw->data + ssfw->pos); size_t len = sigma_action_len(sa); - int ret; + int ret = 0; pr_debug("%s: instr:%i addr:%#x len:%zu\n", __func__, sa->instr, sa->addr, len); @@ -50,50 +29,44 @@ process_sigma_action(struct i2c_client *client, struct sigma_action *sa) case SIGMA_ACTION_WRITEXBYTES: case SIGMA_ACTION_WRITESINGLE: case SIGMA_ACTION_WRITESAFELOAD: + if (ssfw->fw->size < ssfw->pos + len) + return -EINVAL; ret = i2c_master_send(client, (void *)&sa->addr, len); if (ret < 0) return -EINVAL; break; + case SIGMA_ACTION_DELAY: + ret = 0; udelay(len); len = 0; break; + case SIGMA_ACTION_END: - return 0; + return 1; + default: return -EINVAL; } - return 1; + /* when arrive here ret=0 or sent data */ + ssfw->pos += sigma_action_size(sa, len); + return ssfw->pos == ssfw->fw->size; } static int process_sigma_actions(struct i2c_client *client, struct sigma_firmware *ssfw) { - struct sigma_action *sa; - size_t size; - int ret; - - while (ssfw->pos + sizeof(*sa) <= ssfw->fw->size) { - sa = (struct sigma_action *)(ssfw->fw->data + ssfw->pos); - - size = sigma_action_size(sa); - ssfw->pos += size; - if (ssfw->pos > ssfw->fw->size || size == 0) - break; - - ret = process_sigma_action(client, sa); + pr_debug("%s: processing %p\n", __func__, ssfw); + while (1) { + int ret = process_sigma_action(client, ssfw); pr_debug("%s: action returned %i\n", __func__, ret); - - if (ret <= 0) + if (ret == 1) + return 0; + else if (ret) return ret; } - - if (ssfw->pos != ssfw->fw->size) - return -EINVAL; - - return 0; } int process_sigma_firmware(struct i2c_client *client, const char *name) @@ -116,24 +89,16 @@ int process_sigma_firmware(struct i2c_client *client, const char *name) /* then verify the header */ ret = -EINVAL; - - /* - * Reject too small or unreasonable large files. The upper limit has been - * chosen a bit arbitrarily, but it should be enough for all practical - * purposes and having the limit makes it easier to avoid integer - * overflows later in the loading process. - */ - if (fw->size < sizeof(*ssfw_head) || fw->size >= 0x4000000) + if (fw->size < sizeof(*ssfw_head)) goto done; ssfw_head = (void *)fw->data; if (memcmp(ssfw_head->magic, SIGMA_MAGIC, ARRAY_SIZE(ssfw_head->magic))) goto done; - crc = crc32(0, fw->data + sizeof(*ssfw_head), - fw->size - sizeof(*ssfw_head)); + crc = crc32(0, fw->data, fw->size); pr_debug("%s: crc=%x\n", __func__, crc); - if (crc != le32_to_cpu(ssfw_head->crc)) + if (crc != ssfw_head->crc) goto done; ssfw.pos = sizeof(*ssfw_head); diff --git a/trunk/include/linux/sigma.h b/trunk/include/linux/sigma.h index d0de882c0d96..e2accb3164d8 100644 --- a/trunk/include/linux/sigma.h +++ b/trunk/include/linux/sigma.h @@ -24,7 +24,7 @@ struct sigma_firmware { struct sigma_firmware_header { unsigned char magic[7]; u8 version; - __le32 crc; + u32 crc; }; enum { @@ -40,14 +40,19 @@ enum { struct sigma_action { u8 instr; u8 len_hi; - __le16 len; - __be16 addr; + u16 len; + u16 addr; unsigned char payload[]; }; static inline u32 sigma_action_len(struct sigma_action *sa) { - return (sa->len_hi << 16) | le16_to_cpu(sa->len); + return (sa->len_hi << 16) | sa->len; +} + +static inline size_t sigma_action_size(struct sigma_action *sa, u32 payload_len) +{ + return sizeof(*sa) + payload_len + (payload_len % 2); } extern int process_sigma_firmware(struct i2c_client *client, const char *name); diff --git a/trunk/sound/pci/cs5535audio/cs5535audio_pcm.c b/trunk/sound/pci/cs5535audio/cs5535audio_pcm.c index dbf94b189e75..e083122ca55a 100644 --- a/trunk/sound/pci/cs5535audio/cs5535audio_pcm.c +++ b/trunk/sound/pci/cs5535audio/cs5535audio_pcm.c @@ -148,7 +148,7 @@ static int cs5535audio_build_dma_packets(struct cs5535audio *cs5535au, struct cs5535audio_dma_desc *desc = &((struct cs5535audio_dma_desc *) dma->desc_buf.area)[i]; desc->addr = cpu_to_le32(addr); - desc->size = cpu_to_le16(period_bytes); + desc->size = cpu_to_le32(period_bytes); desc->ctlreserved = cpu_to_le16(PRD_EOP); desc_addr += sizeof(struct cs5535audio_dma_desc); addr += period_bytes; diff --git a/trunk/sound/pci/hda/hda_codec.c b/trunk/sound/pci/hda/hda_codec.c index 4463f9a9619a..c6ff9b9de553 100644 --- a/trunk/sound/pci/hda/hda_codec.c +++ b/trunk/sound/pci/hda/hda_codec.c @@ -3850,12 +3850,6 @@ static int get_empty_pcm_device(struct hda_bus *bus, int type) if (!test_and_set_bit(audio_idx[type][i], bus->pcm_dev_bits)) return audio_idx[type][i]; - /* non-fixed slots starting from 10 */ - for (i = 10; i < 32; i++) { - if (!test_and_set_bit(i, bus->pcm_dev_bits)) - return i; - } - snd_printk(KERN_WARNING "Too many %s devices\n", snd_hda_pcm_type_name[type]); return -EAGAIN; @@ -4052,9 +4046,9 @@ int snd_hda_check_board_codec_sid_config(struct hda_codec *codec, /* Search for codec ID */ for (q = tbl; q->subvendor; q++) { - unsigned int mask = 0xffff0000 | q->subdevice_mask; - unsigned int id = (q->subdevice | (q->subvendor << 16)) & mask; - if ((codec->subsystem_id & mask) == id) + unsigned long vendorid = (q->subdevice) | (q->subvendor << 16); + + if (vendorid == codec->subsystem_id) break; } @@ -5010,8 +5004,8 @@ EXPORT_SYMBOL_HDA(snd_hda_get_input_pin_attr); * "Rear", "Internal". */ -const char *hda_get_input_pin_label(struct hda_codec *codec, hda_nid_t pin, - int check_location) +static const char *hda_get_input_pin_label(struct hda_codec *codec, + hda_nid_t pin, bool check_location) { unsigned int def_conf; static const char * const mic_names[] = { @@ -5050,7 +5044,6 @@ const char *hda_get_input_pin_label(struct hda_codec *codec, hda_nid_t pin, return "Misc"; } } -EXPORT_SYMBOL_HDA(hda_get_input_pin_label); /* Check whether the location prefix needs to be added to the label. * If all mic-jacks are in the same location (e.g. rear panel), we don't @@ -5107,6 +5100,64 @@ const char *hda_get_autocfg_input_label(struct hda_codec *codec, } EXPORT_SYMBOL_HDA(hda_get_autocfg_input_label); +/** + * snd_hda_get_pin_label - Get a label for the given I/O pin + * + * Get a label for the given pin. This function works for both input and + * output pins. When @cfg is given as non-NULL, the function tries to get + * an optimized label using hda_get_autocfg_input_label(). + */ +const char *snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid, + const struct auto_pin_cfg *cfg) +{ + unsigned int def_conf = snd_hda_codec_get_pincfg(codec, nid); + int attr; + int i; + + if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE) + return NULL; + + attr = snd_hda_get_input_pin_attr(def_conf); + switch (get_defcfg_device(def_conf)) { + case AC_JACK_LINE_OUT: + switch (attr) { + case INPUT_PIN_ATTR_INT: + return "Speaker"; + case INPUT_PIN_ATTR_DOCK: + return "Dock Line-Out"; + case INPUT_PIN_ATTR_FRONT: + return "Front Line-Out"; + default: + return "Line-Out"; + } + case AC_JACK_SPEAKER: + return "Speaker"; + case AC_JACK_HP_OUT: + switch (attr) { + case INPUT_PIN_ATTR_DOCK: + return "Dock Headphone"; + case INPUT_PIN_ATTR_FRONT: + return "Front Headphone"; + default: + return "Headphone"; + } + case AC_JACK_SPDIF_OUT: + case AC_JACK_DIG_OTHER_OUT: + if (get_defcfg_location(def_conf) == AC_JACK_LOC_HDMI) + return "HDMI"; + else + return "SPDIF"; + } + + if (cfg) { + for (i = 0; i < cfg->num_inputs; i++) + if (cfg->inputs[i].pin == nid) + return hda_get_autocfg_input_label(codec, cfg, i); + } + return hda_get_input_pin_label(codec, nid, true); +} +EXPORT_SYMBOL_HDA(snd_hda_get_pin_label); + /** * snd_hda_add_imux_item - Add an item to input_mux * diff --git a/trunk/sound/pci/hda/hda_codec.h b/trunk/sound/pci/hda/hda_codec.h index 17cee4ee8e65..564471169cae 100644 --- a/trunk/sound/pci/hda/hda_codec.h +++ b/trunk/sound/pci/hda/hda_codec.h @@ -547,6 +547,9 @@ enum { /* max. codec address */ #define HDA_MAX_CODEC_ADDRESS 0x0f +/* max number of PCM devics per card */ +#define HDA_MAX_PCMS 10 + /* * generic arrays */ diff --git a/trunk/sound/pci/hda/hda_eld.c b/trunk/sound/pci/hda/hda_eld.c index c1da422e085a..7ae7578bdcc0 100644 --- a/trunk/sound/pci/hda/hda_eld.c +++ b/trunk/sound/pci/hda/hda_eld.c @@ -347,28 +347,18 @@ int snd_hdmi_get_eld(struct hdmi_eld *eld, for (i = 0; i < size; i++) { unsigned int val = hdmi_get_eld_data(codec, nid, i); - /* - * Graphics driver might be writing to ELD buffer right now. - * Just abort. The caller will repoll after a while. - */ if (!(val & AC_ELDD_ELD_VALID)) { + if (!i) { + snd_printd(KERN_INFO + "HDMI: invalid ELD data\n"); + ret = -EINVAL; + goto error; + } snd_printd(KERN_INFO "HDMI: invalid ELD data byte %d\n", i); - ret = -EINVAL; - goto error; - } - val &= AC_ELDD_ELD_DATA; - /* - * The first byte cannot be zero. This can happen on some DVI - * connections. Some Intel chips may also need some 250ms delay - * to return non-zero ELD data, even when the graphics driver - * correctly writes ELD content before setting ELD_valid bit. - */ - if (!val && !i) { - snd_printdd(KERN_INFO "HDMI: 0 ELD data\n"); - ret = -EINVAL; - goto error; - } + val = 0; + } else + val &= AC_ELDD_ELD_DATA; buf[i] = val; } diff --git a/trunk/sound/pci/hda/hda_intel.c b/trunk/sound/pci/hda/hda_intel.c index 4045b0cc463e..096507d2ca9a 100644 --- a/trunk/sound/pci/hda/hda_intel.c +++ b/trunk/sound/pci/hda/hda_intel.c @@ -407,14 +407,6 @@ struct azx_rb { u32 res[AZX_MAX_CODECS]; /* last read value */ }; -struct azx_pcm { - struct azx *chip; - struct snd_pcm *pcm; - struct hda_codec *codec; - struct hda_pcm_stream *hinfo[2]; - struct list_head list; -}; - struct azx { struct snd_card *card; struct pci_dev *pci; @@ -442,7 +434,7 @@ struct azx { struct azx_dev *azx_dev; /* PCM */ - struct list_head pcm_list; /* azx_pcm list */ + struct snd_pcm *pcm[HDA_MAX_PCMS]; /* HD codec */ unsigned short codec_mask; @@ -487,7 +479,6 @@ enum { AZX_DRIVER_SCH, AZX_DRIVER_ATI, AZX_DRIVER_ATIHDMI, - AZX_DRIVER_ATIHDMI_NS, AZX_DRIVER_VIA, AZX_DRIVER_SIS, AZX_DRIVER_ULI, @@ -534,7 +525,6 @@ static char *driver_short_names[] __devinitdata = { [AZX_DRIVER_SCH] = "HDA Intel MID", [AZX_DRIVER_ATI] = "HDA ATI SB", [AZX_DRIVER_ATIHDMI] = "HDA ATI HDMI", - [AZX_DRIVER_ATIHDMI_NS] = "HDA ATI HDMI", [AZX_DRIVER_VIA] = "HDA VIA VT82xx", [AZX_DRIVER_SIS] = "HDA SIS966", [AZX_DRIVER_ULI] = "HDA ULI M5461", @@ -1153,6 +1143,16 @@ static void update_pci_byte(struct pci_dev *pci, unsigned int reg, static void azx_init_pci(struct azx *chip) { + /* force to non-snoop mode for a new VIA controller when BIOS is set */ + if (chip->snoop && chip->driver_type == AZX_DRIVER_VIA) { + u8 snoop; + pci_read_config_byte(chip->pci, 0x42, &snoop); + if (!(snoop & 0x80) && chip->pci->revision == 0x30) { + chip->snoop = 0; + snd_printdd(SFX "Force to non-snoop mode\n"); + } + } + /* Clear bits 0-2 of PCI register TCSEL (at offset 0x44) * TCSEL == Traffic Class Select Register, which sets PCI express QOS * Ensuring these bits are 0 clears playback static on some HD Audio @@ -1486,9 +1486,10 @@ static void azx_bus_reset(struct hda_bus *bus) azx_init_chip(chip, 1); #ifdef CONFIG_PM if (chip->initialized) { - struct azx_pcm *p; - list_for_each_entry(p, &chip->pcm_list, list) - snd_pcm_suspend_all(p->pcm); + int i; + + for (i = 0; i < HDA_MAX_PCMS; i++) + snd_pcm_suspend_all(chip->pcm[i]); snd_hda_suspend(chip->bus); snd_hda_resume(chip->bus); } @@ -1666,6 +1667,12 @@ static struct snd_pcm_hardware azx_pcm_hw = { .fifo_size = 0, }; +struct azx_pcm { + struct azx *chip; + struct hda_codec *codec; + struct hda_pcm_stream *hinfo[2]; +}; + static int azx_pcm_open(struct snd_pcm_substream *substream) { struct azx_pcm *apcm = snd_pcm_substream_chip(substream); @@ -2190,7 +2197,7 @@ static void azx_pcm_free(struct snd_pcm *pcm) { struct azx_pcm *apcm = pcm->private_data; if (apcm) { - list_del(&apcm->list); + apcm->chip->pcm[pcm->device] = NULL; kfree(apcm); } } @@ -2208,11 +2215,14 @@ azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec, unsigned int size; int s, err; - list_for_each_entry(apcm, &chip->pcm_list, list) { - if (apcm->pcm->device == pcm_dev) { - snd_printk(KERN_ERR SFX "PCM %d already exists\n", pcm_dev); - return -EBUSY; - } + if (pcm_dev >= HDA_MAX_PCMS) { + snd_printk(KERN_ERR SFX "Invalid PCM device number %d\n", + pcm_dev); + return -EINVAL; + } + if (chip->pcm[pcm_dev]) { + snd_printk(KERN_ERR SFX "PCM %d already exists\n", pcm_dev); + return -EBUSY; } err = snd_pcm_new(chip->card, cpcm->name, pcm_dev, cpcm->stream[SNDRV_PCM_STREAM_PLAYBACK].substreams, @@ -2225,13 +2235,12 @@ azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec, if (apcm == NULL) return -ENOMEM; apcm->chip = chip; - apcm->pcm = pcm; apcm->codec = codec; pcm->private_data = apcm; pcm->private_free = azx_pcm_free; if (cpcm->pcm_type == HDA_PCM_TYPE_MODEM) pcm->dev_class = SNDRV_PCM_CLASS_MODEM; - list_add_tail(&apcm->list, &chip->pcm_list); + chip->pcm[pcm_dev] = pcm; cpcm->pcm = pcm; for (s = 0; s < 2; s++) { apcm->hinfo[s] = &cpcm->stream[s]; @@ -2361,12 +2370,12 @@ static int azx_suspend(struct pci_dev *pci, pm_message_t state) { struct snd_card *card = pci_get_drvdata(pci); struct azx *chip = card->private_data; - struct azx_pcm *p; + int i; snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); azx_clear_irq_pending(chip); - list_for_each_entry(p, &chip->pcm_list, list) - snd_pcm_suspend_all(p->pcm); + for (i = 0; i < HDA_MAX_PCMS; i++) + snd_pcm_suspend_all(chip->pcm[i]); if (chip->initialized) snd_hda_suspend(chip->bus); azx_stop_chip(chip); @@ -2498,8 +2507,8 @@ static struct snd_pci_quirk position_fix_list[] __devinitdata = { SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB), SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB), SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS M2V", POS_FIX_LPIB), - SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS 1101HA", POS_FIX_LPIB), SND_PCI_QUIRK(0x104d, 0x9069, "Sony VPCS11V9E", POS_FIX_LPIB), + SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB), SND_PCI_QUIRK(0x1297, 0x3166, "Shuttle", POS_FIX_LPIB), SND_PCI_QUIRK(0x1458, 0xa022, "ga-ma770-ud3", POS_FIX_LPIB), SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB), @@ -2625,35 +2634,6 @@ static void __devinit check_msi(struct azx *chip) } } -/* check the snoop mode availability */ -static void __devinit azx_check_snoop_available(struct azx *chip) -{ - bool snoop = chip->snoop; - - switch (chip->driver_type) { - case AZX_DRIVER_VIA: - /* force to non-snoop mode for a new VIA controller - * when BIOS is set - */ - if (snoop) { - u8 val; - pci_read_config_byte(chip->pci, 0x42, &val); - if (!(val & 0x80) && chip->pci->revision == 0x30) - snoop = false; - } - break; - case AZX_DRIVER_ATIHDMI_NS: - /* new ATI HDMI requires non-snoop */ - snoop = false; - break; - } - - if (snoop != chip->snoop) { - snd_printk(KERN_INFO SFX "Force to %s mode\n", - snoop ? "snoop" : "non-snoop"); - chip->snoop = snoop; - } -} /* * constructor @@ -2692,7 +2672,6 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, check_msi(chip); chip->dev_index = dev; INIT_WORK(&chip->irq_pending_work, azx_irq_pending_work); - INIT_LIST_HEAD(&chip->pcm_list); chip->position_fix[0] = chip->position_fix[1] = check_position_fix(chip, position_fix[dev]); @@ -2700,7 +2679,6 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, chip->single_cmd = single_cmd; chip->snoop = hda_snoop; - azx_check_snoop_available(chip); if (bdl_pos_adj[dev] < 0) { switch (chip->driver_type) { @@ -2799,7 +2777,6 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, chip->capture_streams = ULI_NUM_CAPTURE; break; case AZX_DRIVER_ATIHDMI: - case AZX_DRIVER_ATIHDMI_NS: chip->playback_streams = ATIHDMI_NUM_PLAYBACK; chip->capture_streams = ATIHDMI_NUM_CAPTURE; break; @@ -2994,8 +2971,7 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { /* SCH */ { PCI_DEVICE(0x8086, 0x811b), .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | - AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_LPIB }, /* Poulsbo */ - /* ICH */ + AZX_DCAPS_BUFSIZE}, { PCI_DEVICE(0x8086, 0x2668), .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC | AZX_DCAPS_BUFSIZE }, /* ICH6 */ @@ -3062,14 +3038,6 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI }, { PCI_DEVICE(0x1002, 0xaa48), .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI }, - { PCI_DEVICE(0x1002, 0x9902), - .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI }, - { PCI_DEVICE(0x1002, 0xaaa0), - .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI }, - { PCI_DEVICE(0x1002, 0xaaa8), - .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI }, - { PCI_DEVICE(0x1002, 0xaab0), - .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI }, /* VIA VT8251/VT8237A */ { PCI_DEVICE(0x1106, 0x3288), .driver_data = AZX_DRIVER_VIA | AZX_DCAPS_POSFIX_VIA }, diff --git a/trunk/sound/pci/hda/hda_local.h b/trunk/sound/pci/hda/hda_local.h index 618ddad17236..7a10fe95211e 100644 --- a/trunk/sound/pci/hda/hda_local.h +++ b/trunk/sound/pci/hda/hda_local.h @@ -394,11 +394,11 @@ struct auto_pin_cfg_item { }; struct auto_pin_cfg; -const char *hda_get_input_pin_label(struct hda_codec *codec, hda_nid_t pin, - int check_location); const char *hda_get_autocfg_input_label(struct hda_codec *codec, const struct auto_pin_cfg *cfg, int input); +const char *snd_hda_get_pin_label(struct hda_codec *codec, hda_nid_t nid, + const struct auto_pin_cfg *cfg); int snd_hda_add_imux_item(struct hda_input_mux *imux, const char *label, int index, int *type_index_ret); diff --git a/trunk/sound/pci/hda/patch_ca0110.c b/trunk/sound/pci/hda/patch_ca0110.c index 993757b65736..6bd602bfe0fe 100644 --- a/trunk/sound/pci/hda/patch_ca0110.c +++ b/trunk/sound/pci/hda/patch_ca0110.c @@ -476,7 +476,7 @@ static void parse_input(struct hda_codec *codec) if (j >= cfg->num_inputs) continue; spec->input_pins[n] = pin; - spec->input_labels[n] = hda_get_input_pin_label(codec, pin, 1); + spec->input_labels[n] = snd_hda_get_pin_label(codec, pin, NULL); spec->adcs[n] = nid; n++; } diff --git a/trunk/sound/pci/hda/patch_cirrus.c b/trunk/sound/pci/hda/patch_cirrus.c index 70a7abda7e22..34a460bd27bb 100644 --- a/trunk/sound/pci/hda/patch_cirrus.c +++ b/trunk/sound/pci/hda/patch_cirrus.c @@ -58,8 +58,6 @@ struct cs_spec { unsigned int gpio_mask; unsigned int gpio_dir; unsigned int gpio_data; - unsigned int gpio_eapd_hp; /* EAPD GPIO bit for headphones */ - unsigned int gpio_eapd_speaker; /* EAPD GPIO bit for speakers */ struct hda_pcm pcm_rec[2]; /* PCM information */ @@ -78,7 +76,6 @@ enum { CS420X_MBP53, CS420X_MBP55, CS420X_IMAC27, - CS420X_APPLE, CS420X_AUTO, CS420X_MODELS }; @@ -240,15 +237,6 @@ static int cs_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout); } -static void cs_update_input_select(struct hda_codec *codec) -{ - struct cs_spec *spec = codec->spec; - if (spec->cur_adc) - snd_hda_codec_write(codec, spec->cur_adc, 0, - AC_VERB_SET_CONNECT_SEL, - spec->adc_idx[spec->cur_input]); -} - /* * Analog capture */ @@ -262,7 +250,6 @@ static int cs_capture_pcm_prepare(struct hda_pcm_stream *hinfo, spec->cur_adc = spec->adc_nid[spec->cur_input]; spec->cur_adc_stream_tag = stream_tag; spec->cur_adc_format = format; - cs_update_input_select(codec); snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format); return 0; } @@ -702,8 +689,10 @@ static int change_cur_input(struct hda_codec *codec, unsigned int idx, spec->cur_adc_stream_tag, 0, spec->cur_adc_format); } + snd_hda_codec_write(codec, spec->cur_adc, 0, + AC_VERB_SET_CONNECT_SEL, + spec->adc_idx[idx]); spec->cur_input = idx; - cs_update_input_select(codec); return 1; } @@ -722,7 +711,7 @@ static int cs_capture_source_info(struct snd_kcontrol *kcontrol, uinfo->value.enumerated.item = spec->num_inputs - 1; idx = spec->input_idx[uinfo->value.enumerated.item]; strcpy(uinfo->value.enumerated.name, - hda_get_input_pin_label(codec, cfg->inputs[idx].pin, 1)); + snd_hda_get_pin_label(codec, cfg->inputs[idx].pin, NULL)); return 0; } @@ -931,9 +920,10 @@ static void cs_automute(struct hda_codec *codec) spdif_present ? 0 : PIN_OUT); } } - if (spec->gpio_eapd_hp) { - unsigned int gpio = hp_present ? - spec->gpio_eapd_hp : spec->gpio_eapd_speaker; + if (spec->board_config == CS420X_MBP53 || + spec->board_config == CS420X_MBP55 || + spec->board_config == CS420X_IMAC27) { + unsigned int gpio = hp_present ? 0x02 : 0x08; snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, gpio); } @@ -983,7 +973,10 @@ static void cs_automic(struct hda_codec *codec) } else { spec->cur_input = spec->last_input; } - cs_update_input_select(codec); + + snd_hda_codec_write_cache(codec, spec->cur_adc, 0, + AC_VERB_SET_CONNECT_SEL, + spec->adc_idx[spec->cur_input]); } else { if (present) change_cur_input(codec, spec->automic_idx, 0); @@ -1080,7 +1073,9 @@ static void init_input(struct hda_codec *codec) cs_automic(codec); else { spec->cur_adc = spec->adc_nid[spec->cur_input]; - cs_update_input_select(codec); + snd_hda_codec_write(codec, spec->cur_adc, 0, + AC_VERB_SET_CONNECT_SEL, + spec->adc_idx[spec->cur_input]); } } else { change_cur_input(codec, spec->cur_input, 1); @@ -1278,7 +1273,6 @@ static const char * const cs420x_models[CS420X_MODELS] = { [CS420X_MBP53] = "mbp53", [CS420X_MBP55] = "mbp55", [CS420X_IMAC27] = "imac27", - [CS420X_APPLE] = "apple", [CS420X_AUTO] = "auto", }; @@ -1288,13 +1282,7 @@ static const struct snd_pci_quirk cs420x_cfg_tbl[] = { SND_PCI_QUIRK(0x10de, 0x0d94, "MacBookAir 3,1(2)", CS420X_MBP55), SND_PCI_QUIRK(0x10de, 0xcb79, "MacBookPro 5,5", CS420X_MBP55), SND_PCI_QUIRK(0x10de, 0xcb89, "MacBookPro 7,1", CS420X_MBP55), - /* this conflicts with too many other models */ - /*SND_PCI_QUIRK(0x8086, 0x7270, "IMac 27 Inch", CS420X_IMAC27),*/ - {} /* terminator */ -}; - -static const struct snd_pci_quirk cs420x_codec_cfg_tbl[] = { - SND_PCI_QUIRK_VENDOR(0x106b, "Apple", CS420X_APPLE), + SND_PCI_QUIRK(0x8086, 0x7270, "IMac 27 Inch", CS420X_IMAC27), {} /* terminator */ }; @@ -1376,10 +1364,6 @@ static int patch_cs420x(struct hda_codec *codec) spec->board_config = snd_hda_check_board_config(codec, CS420X_MODELS, cs420x_models, cs420x_cfg_tbl); - if (spec->board_config < 0) - spec->board_config = - snd_hda_check_board_codec_sid_config(codec, - CS420X_MODELS, NULL, cs420x_codec_cfg_tbl); if (spec->board_config >= 0) fix_pincfg(codec, spec->board_config, cs_pincfgs); @@ -1387,11 +1371,10 @@ static int patch_cs420x(struct hda_codec *codec) case CS420X_IMAC27: case CS420X_MBP53: case CS420X_MBP55: - case CS420X_APPLE: - spec->gpio_eapd_hp = 2; /* GPIO1 = headphones */ - spec->gpio_eapd_speaker = 8; /* GPIO3 = speakers */ - spec->gpio_mask = spec->gpio_dir = - spec->gpio_eapd_hp | spec->gpio_eapd_speaker; + /* GPIO1 = headphones */ + /* GPIO3 = speakers */ + spec->gpio_mask = 0x0a; + spec->gpio_dir = 0x0a; break; } diff --git a/trunk/sound/pci/hda/patch_hdmi.c b/trunk/sound/pci/hda/patch_hdmi.c index 6e0756febb2e..9850c5b481ea 100644 --- a/trunk/sound/pci/hda/patch_hdmi.c +++ b/trunk/sound/pci/hda/patch_hdmi.c @@ -48,8 +48,8 @@ MODULE_PARM_DESC(static_hdmi_pcm, "Don't restrict PCM parameters per ELD info"); * * The HDA correspondence of pipes/ports are converter/pin nodes. */ -#define MAX_HDMI_CVTS 8 -#define MAX_HDMI_PINS 8 +#define MAX_HDMI_CVTS 4 +#define MAX_HDMI_PINS 4 struct hdmi_spec_per_cvt { hda_nid_t cvt_nid; @@ -69,7 +69,6 @@ struct hdmi_spec_per_pin { struct hda_codec *codec; struct hdmi_eld sink_eld; struct delayed_work work; - int repoll_count; }; struct hdmi_spec { @@ -749,7 +748,7 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, int pin_idx, * Unsolicited events */ -static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll); +static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, bool retry); static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) { @@ -767,7 +766,7 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) if (pin_idx < 0) return; - hdmi_present_sense(&spec->pins[pin_idx], 1); + hdmi_present_sense(&spec->pins[pin_idx], true); } static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res) @@ -961,7 +960,7 @@ static int hdmi_read_pin_conn(struct hda_codec *codec, int pin_idx) return 0; } -static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll) +static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, bool retry) { struct hda_codec *codec = per_pin->codec; struct hdmi_eld *eld = &per_pin->sink_eld; @@ -990,7 +989,7 @@ static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll) if (eld_valid) { if (!snd_hdmi_get_eld(eld, codec, pin_nid)) snd_hdmi_show_eld(eld); - else if (repoll) { + else if (retry) { queue_delayed_work(codec->bus->workq, &per_pin->work, msecs_to_jiffies(300)); @@ -1005,10 +1004,7 @@ static void hdmi_repoll_eld(struct work_struct *work) struct hdmi_spec_per_pin *per_pin = container_of(to_delayed_work(work), struct hdmi_spec_per_pin, work); - if (per_pin->repoll_count++ > 6) - per_pin->repoll_count = 0; - - hdmi_present_sense(per_pin, per_pin->repoll_count); + hdmi_present_sense(per_pin, false); } static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid) @@ -1126,12 +1122,12 @@ static int hdmi_parse_codec(struct hda_codec *codec) /* */ -static char *get_hdmi_pcm_name(int idx) -{ - static char names[MAX_HDMI_PINS][8]; - sprintf(&names[idx][0], "HDMI %d", idx); - return &names[idx][0]; -} +static char *generic_hdmi_pcm_names[MAX_HDMI_PINS] = { + "HDMI 0", + "HDMI 1", + "HDMI 2", + "HDMI 3", +}; /* * HDMI callbacks @@ -1209,7 +1205,7 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec) struct hda_pcm_stream *pstr; info = &spec->pcm_rec[pin_idx]; - info->name = get_hdmi_pcm_name(pin_idx); + info->name = generic_hdmi_pcm_names[pin_idx]; info->pcm_type = HDA_PCM_TYPE_HDMI; pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK]; @@ -1239,7 +1235,7 @@ static int generic_hdmi_build_jack(struct hda_codec *codec, int pin_idx) if (err < 0) return err; - hdmi_present_sense(per_pin, 0); + hdmi_present_sense(per_pin, false); return 0; } @@ -1364,7 +1360,7 @@ static int simple_playback_build_pcms(struct hda_codec *codec) chans = get_wcaps(codec, spec->cvts[i].cvt_nid); chans = get_wcaps_channels(chans); - info->name = get_hdmi_pcm_name(i); + info->name = generic_hdmi_pcm_names[i]; info->pcm_type = HDA_PCM_TYPE_HDMI; pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK]; snd_BUG_ON(!spec->pcm_playback); diff --git a/trunk/sound/pci/hda/patch_realtek.c b/trunk/sound/pci/hda/patch_realtek.c index 690f2a2a4595..14feecf2d802 100644 --- a/trunk/sound/pci/hda/patch_realtek.c +++ b/trunk/sound/pci/hda/patch_realtek.c @@ -278,12 +278,6 @@ static bool alc_dyn_adc_pcm_resetup(struct hda_codec *codec, int cur) return false; } -static inline hda_nid_t get_capsrc(struct alc_spec *spec, int idx) -{ - return spec->capsrc_nids ? - spec->capsrc_nids[idx] : spec->adc_nids[idx]; -} - static void call_update_outputs(struct hda_codec *codec); /* select the given imux item; either unmute exclusively or select the route */ @@ -300,8 +294,6 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, imux = &spec->input_mux[mux_idx]; if (!imux->num_items && mux_idx > 0) imux = &spec->input_mux[0]; - if (!imux->num_items) - return 0; if (idx >= imux->num_items) idx = imux->num_items - 1; @@ -327,7 +319,8 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, adc_idx = spec->dyn_adc_idx[idx]; } - nid = get_capsrc(spec, adc_idx); + nid = spec->capsrc_nids ? + spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx]; /* no selection? */ num_conns = snd_hda_get_conn_list(codec, nid, NULL); @@ -1078,19 +1071,8 @@ static bool alc_rebuild_imux_for_auto_mic(struct hda_codec *codec) spec->imux_pins[2] = spec->dock_mic_pin; for (i = 0; i < 3; i++) { strcpy(imux->items[i].label, texts[i]); - if (spec->imux_pins[i]) { - hda_nid_t pin = spec->imux_pins[i]; - int c; - for (c = 0; c < spec->num_adc_nids; c++) { - hda_nid_t cap = get_capsrc(spec, c); - int idx = get_connection_index(codec, cap, pin); - if (idx >= 0) { - imux->items[i].index = idx; - break; - } - } + if (spec->imux_pins[i]) imux->num_items = i + 1; - } } spec->num_mux_defs = 1; spec->input_mux = imux; @@ -2009,8 +1991,10 @@ static int alc_build_controls(struct hda_codec *codec) if (!kctl) kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); for (i = 0; kctl && i < kctl->count; i++) { - err = snd_hda_add_nid(codec, kctl, i, - get_capsrc(spec, i)); + const hda_nid_t *nids = spec->capsrc_nids; + if (!nids) + nids = spec->adc_nids; + err = snd_hda_add_nid(codec, kctl, i, nids[i]); if (err < 0) return err; } @@ -2665,8 +2649,6 @@ static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch, case AUTO_PIN_SPEAKER_OUT: if (cfg->line_outs == 1) return "Speaker"; - if (cfg->line_outs == 2) - return ch ? "Bass Speaker" : "Speaker"; break; case AUTO_PIN_HP_OUT: /* for multi-io case, only the primary out */ @@ -2804,7 +2786,8 @@ static int alc_auto_create_input_ctls(struct hda_codec *codec) } for (c = 0; c < num_adcs; c++) { - hda_nid_t cap = get_capsrc(spec, c); + hda_nid_t cap = spec->capsrc_nids ? + spec->capsrc_nids[c] : spec->adc_nids[c]; idx = get_connection_index(codec, cap, pin); if (idx >= 0) { spec->imux_pins[imux->num_items] = pin; @@ -2978,7 +2961,7 @@ static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin) if (!nid) continue; if (found_in_nid_list(nid, spec->multiout.dac_nids, - ARRAY_SIZE(spec->private_dac_nids))) + spec->multiout.num_dacs)) continue; if (found_in_nid_list(nid, spec->multiout.hp_out_nid, ARRAY_SIZE(spec->multiout.hp_out_nid))) @@ -3016,7 +2999,6 @@ static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin) return 0; } -/* return 0 if no possible DAC is found, 1 if one or more found */ static int alc_auto_fill_extra_dacs(struct hda_codec *codec, int num_outs, const hda_nid_t *pins, hda_nid_t *dacs) { @@ -3034,19 +3016,17 @@ static int alc_auto_fill_extra_dacs(struct hda_codec *codec, int num_outs, if (!dacs[i]) dacs[i] = alc_auto_look_for_dac(codec, pins[i]); } - return 1; + return 0; } static int alc_auto_fill_multi_ios(struct hda_codec *codec, unsigned int location, int offset); -static hda_nid_t alc_look_for_out_vol_nid(struct hda_codec *codec, - hda_nid_t pin, hda_nid_t dac); /* fill in the dac_nids table from the parsed pin configuration */ static int alc_auto_fill_dac_nids(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; - struct auto_pin_cfg *cfg = &spec->autocfg; + const struct auto_pin_cfg *cfg = &spec->autocfg; unsigned int location, defcfg; int num_pins; bool redone = false; @@ -3059,7 +3039,6 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec) spec->multiout.extra_out_nid[0] = 0; memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids)); spec->multiout.dac_nids = spec->private_dac_nids; - spec->multi_ios = 0; /* fill hard-wired DACs first */ if (!redone) { @@ -3093,12 +3072,10 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec) for (i = 0; i < cfg->line_outs; i++) { if (spec->private_dac_nids[i]) spec->multiout.num_dacs++; - else { + else memmove(spec->private_dac_nids + i, spec->private_dac_nids + i + 1, sizeof(hda_nid_t) * (cfg->line_outs - i - 1)); - spec->private_dac_nids[cfg->line_outs - 1] = 0; - } } if (cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { @@ -3117,28 +3094,9 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec) if (cfg->line_out_type != AUTO_PIN_HP_OUT) alc_auto_fill_extra_dacs(codec, cfg->hp_outs, cfg->hp_pins, spec->multiout.hp_out_nid); - if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { - int err = alc_auto_fill_extra_dacs(codec, cfg->speaker_outs, - cfg->speaker_pins, - spec->multiout.extra_out_nid); - /* if no speaker volume is assigned, try again as the primary - * output - */ - if (!err && cfg->speaker_outs > 0 && - cfg->line_out_type == AUTO_PIN_HP_OUT) { - cfg->hp_outs = cfg->line_outs; - memcpy(cfg->hp_pins, cfg->line_out_pins, - sizeof(cfg->hp_pins)); - cfg->line_outs = cfg->speaker_outs; - memcpy(cfg->line_out_pins, cfg->speaker_pins, - sizeof(cfg->speaker_pins)); - cfg->speaker_outs = 0; - memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins)); - cfg->line_out_type = AUTO_PIN_SPEAKER_OUT; - redone = false; - goto again; - } - } + if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) + alc_auto_fill_extra_dacs(codec, cfg->speaker_outs, cfg->speaker_pins, + spec->multiout.extra_out_nid); if (!spec->multi_ios && cfg->line_out_type == AUTO_PIN_SPEAKER_OUT && @@ -3155,10 +3113,6 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec) } } - if (cfg->line_out_pins[0]) - spec->vmaster_nid = - alc_look_for_out_vol_nid(codec, cfg->line_out_pins[0], - spec->multiout.dac_nids[0]); return 0; } @@ -3320,8 +3274,7 @@ static int alc_auto_create_multi_out_ctls(struct hda_codec *codec, } static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, - hda_nid_t dac, const char *pfx, - int cidx) + hda_nid_t dac, const char *pfx) { struct alc_spec *spec = codec->spec; hda_nid_t sw, vol; @@ -3337,15 +3290,15 @@ static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, if (is_ctl_used(spec->sw_ctls, val)) return 0; /* already created */ mark_ctl_usage(spec->sw_ctls, val); - return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, cidx, val); + return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, val); } sw = alc_look_for_out_mute_nid(codec, pin, dac); vol = alc_look_for_out_vol_nid(codec, pin, dac); - err = alc_auto_add_stereo_vol(codec, pfx, cidx, vol); + err = alc_auto_add_stereo_vol(codec, pfx, 0, vol); if (err < 0) return err; - err = alc_auto_add_stereo_sw(codec, pfx, cidx, sw); + err = alc_auto_add_stereo_sw(codec, pfx, 0, sw); if (err < 0) return err; return 0; @@ -3386,21 +3339,16 @@ static int alc_auto_create_extra_outs(struct hda_codec *codec, int num_pins, hda_nid_t dac = *dacs; if (!dac) dac = spec->multiout.dac_nids[0]; - return alc_auto_create_extra_out(codec, *pins, dac, pfx, 0); + return alc_auto_create_extra_out(codec, *pins, dac, pfx); } if (dacs[num_pins - 1]) { /* OK, we have a multi-output system with individual volumes */ for (i = 0; i < num_pins; i++) { - if (num_pins >= 3) { - snprintf(name, sizeof(name), "%s %s", - pfx, channel_name[i]); - err = alc_auto_create_extra_out(codec, pins[i], dacs[i], - name, 0); - } else { - err = alc_auto_create_extra_out(codec, pins[i], dacs[i], - pfx, i); - } + snprintf(name, sizeof(name), "%s %s", + pfx, channel_name[i]); + err = alc_auto_create_extra_out(codec, pins[i], dacs[i], + name); if (err < 0) return err; } @@ -3872,7 +3820,8 @@ static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin) if (!pin) return 0; for (i = 0; i < spec->num_adc_nids; i++) { - hda_nid_t cap = get_capsrc(spec, i); + hda_nid_t cap = spec->capsrc_nids ? + spec->capsrc_nids[i] : spec->adc_nids[i]; int idx; idx = get_connection_index(codec, cap, pin); @@ -4181,10 +4130,8 @@ static int patch_alc880(struct hda_codec *codec) #endif } - if (board_config != ALC_MODEL_AUTO) { - spec->vmaster_nid = 0x0c; + if (board_config != ALC_MODEL_AUTO) setup_preset(codec, &alc880_presets[board_config]); - } if (!spec->no_analog && !spec->adc_nids) { alc_auto_fill_adc_caps(codec); @@ -4204,6 +4151,8 @@ static int patch_alc880(struct hda_codec *codec) alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); + spec->vmaster_nid = 0x0c; + codec->patch_ops = alc_patch_ops; if (board_config == ALC_MODEL_AUTO) spec->init_hook = alc_auto_init_std; @@ -4310,10 +4259,8 @@ static int patch_alc260(struct hda_codec *codec) #endif } - if (board_config != ALC_MODEL_AUTO) { + if (board_config != ALC_MODEL_AUTO) setup_preset(codec, &alc260_presets[board_config]); - spec->vmaster_nid = 0x08; - } if (!spec->no_analog && !spec->adc_nids) { alc_auto_fill_adc_caps(codec); @@ -4333,6 +4280,8 @@ static int patch_alc260(struct hda_codec *codec) alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); + spec->vmaster_nid = 0x08; + codec->patch_ops = alc_patch_ops; if (board_config == ALC_MODEL_AUTO) spec->init_hook = alc_auto_init_std; @@ -4704,10 +4653,8 @@ static int patch_alc882(struct hda_codec *codec) goto error; } - if (board_config != ALC_MODEL_AUTO) { + if (board_config != ALC_MODEL_AUTO) setup_preset(codec, &alc882_presets[board_config]); - spec->vmaster_nid = 0x0c; - } if (!spec->no_analog && !spec->adc_nids) { alc_auto_fill_adc_caps(codec); @@ -4727,6 +4674,8 @@ static int patch_alc882(struct hda_codec *codec) alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); + spec->vmaster_nid = 0x0c; + codec->patch_ops = alc_patch_ops; if (board_config == ALC_MODEL_AUTO) spec->init_hook = alc_auto_init_std; @@ -4905,6 +4854,8 @@ static int patch_alc262(struct hda_codec *codec) alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); + spec->vmaster_nid = 0x0c; + codec->patch_ops = alc_patch_ops; spec->init_hook = alc_auto_init_std; spec->shutup = alc_eapd_shutup; @@ -5016,6 +4967,8 @@ static int patch_alc268(struct hda_codec *codec) if (!spec->no_analog && !spec->cap_mixer) set_capture_mixer(codec); + spec->vmaster_nid = 0x02; + codec->patch_ops = alc_patch_ops; spec->init_hook = alc_auto_init_std; spec->shutup = alc_eapd_shutup; @@ -5570,6 +5523,8 @@ static int patch_alc269(struct hda_codec *codec) alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); + spec->vmaster_nid = 0x02; + codec->patch_ops = alc_patch_ops; #ifdef CONFIG_PM codec->patch_ops.resume = alc269_resume; @@ -5674,6 +5629,8 @@ static int patch_alc861(struct hda_codec *codec) set_beep_amp(spec, 0x23, 0, HDA_OUTPUT); } + spec->vmaster_nid = 0x03; + alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); codec->patch_ops = alc_patch_ops; @@ -5798,6 +5755,8 @@ static int patch_alc861vd(struct hda_codec *codec) set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); } + spec->vmaster_nid = 0x02; + alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); codec->patch_ops = alc_patch_ops; @@ -6180,6 +6139,7 @@ static int patch_alc662(struct hda_codec *codec) break; } } + spec->vmaster_nid = 0x02; alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); @@ -6235,6 +6195,8 @@ static int patch_alc680(struct hda_codec *codec) if (!spec->no_analog && !spec->cap_mixer) set_capture_mixer(codec); + spec->vmaster_nid = 0x02; + codec->patch_ops = alc_patch_ops; spec->init_hook = alc_auto_init_std; diff --git a/trunk/sound/pci/hda/patch_sigmatel.c b/trunk/sound/pci/hda/patch_sigmatel.c index aaed004eacc5..3b4ef0cba0e7 100644 --- a/trunk/sound/pci/hda/patch_sigmatel.c +++ b/trunk/sound/pci/hda/patch_sigmatel.c @@ -96,6 +96,7 @@ enum { STAC_92HD83XXX_PWR_REF, STAC_DELL_S14, STAC_DELL_VOSTRO_3500, + STAC_92HD83XXX_HP, STAC_92HD83XXX_HP_cNB11_INTQUAD, STAC_HP_DV7_4000, STAC_92HD83XXX_MODELS @@ -214,7 +215,6 @@ struct sigmatel_spec { unsigned int gpio_mute; unsigned int gpio_led; unsigned int gpio_led_polarity; - unsigned int vref_mute_led_nid; /* pin NID for mute-LED vref control */ unsigned int vref_led; /* stream */ @@ -1641,8 +1641,6 @@ static const struct snd_pci_quirk stac92hd73xx_codec_id_cfg_tbl[] = { "Alienware M17x", STAC_ALIENWARE_M17X), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x043a, "Alienware M17x", STAC_ALIENWARE_M17X), - SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0490, - "Alienware M17x", STAC_ALIENWARE_M17X), {} /* terminator */ }; @@ -1691,6 +1689,7 @@ static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = { [STAC_92HD83XXX_PWR_REF] = "mic-ref", [STAC_DELL_S14] = "dell-s14", [STAC_DELL_VOSTRO_3500] = "dell-vostro-3500", + [STAC_92HD83XXX_HP] = "hp", [STAC_92HD83XXX_HP_cNB11_INTQUAD] = "hp_cNB11_intquad", [STAC_HP_DV7_4000] = "hp-dv7-4000", }; @@ -1705,6 +1704,8 @@ static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { "unknown Dell", STAC_DELL_S14), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x1028, "Dell Vostro 3500", STAC_DELL_VOSTRO_3500), + SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x3600, + "HP", STAC_92HD83XXX_HP), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1656, "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1657, @@ -2871,7 +2872,7 @@ static inline int stac92xx_add_jack_mode_control(struct hda_codec *codec, } if (control) { - strcpy(name, hda_get_input_pin_label(codec, nid, 1)); + strcpy(name, snd_hda_get_pin_label(codec, nid, NULL)); return stac92xx_add_control(codec->spec, control, strcat(name, " Jack Mode"), nid); } @@ -3562,7 +3563,7 @@ static int stac92xx_auto_create_dmic_input_ctls(struct hda_codec *codec, if (index < 0) continue; - label = hda_get_input_pin_label(codec, nid, 1); + label = snd_hda_get_pin_label(codec, nid, NULL); snd_hda_add_imux_item(dimux, label, index, &type_idx); if (snd_hda_get_bool_hint(codec, "separate_dmux") != 1) snd_hda_add_imux_item(imux, label, index, &type_idx); @@ -4315,10 +4316,12 @@ static void stac_store_hints(struct hda_codec *codec) spec->eapd_switch = val; get_int_hint(codec, "gpio_led_polarity", &spec->gpio_led_polarity); if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) { - spec->gpio_mask |= spec->gpio_led; - spec->gpio_dir |= spec->gpio_led; - if (spec->gpio_led_polarity) - spec->gpio_data |= spec->gpio_led; + if (spec->gpio_led <= 8) { + spec->gpio_mask |= spec->gpio_led; + spec->gpio_dir |= spec->gpio_led; + if (spec->gpio_led_polarity) + spec->gpio_data |= spec->gpio_led; + } } } @@ -4436,9 +4439,7 @@ static int stac92xx_init(struct hda_codec *codec) int pinctl, def_conf; /* power on when no jack detection is available */ - /* or when the VREF is used for controlling LED */ - if (!spec->hp_detect || - spec->vref_mute_led_nid == nid) { + if (!spec->hp_detect) { stac_toggle_power_map(codec, nid, 1); continue; } @@ -4899,7 +4900,7 @@ static void set_hp_led_gpio(struct hda_codec *codec) * Need more information on whether it is true across the entire series. * -- kunal */ -static int find_mute_led_cfg(struct hda_codec *codec, int default_polarity) +static int find_mute_led_gpio(struct hda_codec *codec, int default_polarity) { struct sigmatel_spec *spec = codec->spec; const struct dmi_device *dev = NULL; @@ -4910,14 +4911,8 @@ static int find_mute_led_cfg(struct hda_codec *codec, int default_polarity) if (sscanf(dev->name, "HP_Mute_LED_%d_%x", &spec->gpio_led_polarity, &spec->gpio_led) == 2) { - unsigned int max_gpio; - max_gpio = snd_hda_param_read(codec, codec->afg, - AC_PAR_GPIO_CAP); - max_gpio &= AC_GPIO_IO_COUNT; - if (spec->gpio_led < max_gpio) + if (spec->gpio_led < 4) spec->gpio_led = 1 << spec->gpio_led; - else - spec->vref_mute_led_nid = spec->gpio_led; return 1; } if (sscanf(dev->name, "HP_Mute_LED_%d", @@ -4925,21 +4920,13 @@ static int find_mute_led_cfg(struct hda_codec *codec, int default_polarity) set_hp_led_gpio(codec); return 1; } - /* BIOS bug: unfilled OEM string */ - if (strstr(dev->name, "HP_Mute_LED_P_G")) { - set_hp_led_gpio(codec); - spec->gpio_led_polarity = 1; - return 1; - } } /* * Fallback case - if we don't find the DMI strings, - * we statically set the GPIO - if not a B-series system - * and default polarity is provided + * we statically set the GPIO - if not a B-series system. */ - if (!hp_blike_system(codec->subsystem_id) && - (default_polarity == 0 || default_polarity == 1)) { + if (!hp_blike_system(codec->subsystem_id)) { set_hp_led_gpio(codec); spec->gpio_led_polarity = default_polarity; return 1; @@ -5054,12 +5041,29 @@ static int stac92xx_pre_resume(struct hda_codec *codec) struct sigmatel_spec *spec = codec->spec; /* sync mute LED */ - if (spec->vref_mute_led_nid) - stac_vrefout_set(codec, spec->vref_mute_led_nid, - spec->vref_led); - else if (spec->gpio_led) - stac_gpio_set(codec, spec->gpio_mask, - spec->gpio_dir, spec->gpio_data); + if (spec->gpio_led) { + if (spec->gpio_led <= 8) { + stac_gpio_set(codec, spec->gpio_mask, + spec->gpio_dir, spec->gpio_data); + } else { + stac_vrefout_set(codec, + spec->gpio_led, spec->vref_led); + } + } + return 0; +} + +static int stac92xx_post_suspend(struct hda_codec *codec) +{ + struct sigmatel_spec *spec = codec->spec; + if (spec->gpio_led > 8) { + /* with vref-out pin used for mute led control + * codec AFG is prevented from D3 state, but on + * system suspend it can (and should) be used + */ + snd_hda_codec_read(codec, codec->afg, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D3); + } return 0; } @@ -5070,7 +5074,7 @@ static void stac92xx_set_power_state(struct hda_codec *codec, hda_nid_t fg, struct sigmatel_spec *spec = codec->spec; if (power_state == AC_PWRST_D3) { - if (spec->vref_mute_led_nid) { + if (spec->gpio_led > 8) { /* with vref-out pin used for mute led control * codec AFG is prevented from D3 state */ @@ -5123,7 +5127,7 @@ static int stac92xx_update_led_status(struct hda_codec *codec) } } /*polarity defines *not* muted state level*/ - if (!spec->vref_mute_led_nid) { + if (spec->gpio_led <= 8) { if (muted) spec->gpio_data &= ~spec->gpio_led; /* orange */ else @@ -5141,8 +5145,7 @@ static int stac92xx_update_led_status(struct hda_codec *codec) muted_lvl = spec->gpio_led_polarity ? AC_PINCTL_VREF_GRD : AC_PINCTL_VREF_HIZ; spec->vref_led = muted ? muted_lvl : notmtd_lvl; - stac_vrefout_set(codec, spec->vref_mute_led_nid, - spec->vref_led); + stac_vrefout_set(codec, spec->gpio_led, spec->vref_led); } return 0; } @@ -5649,20 +5652,22 @@ static int patch_stac92hd83xxx(struct hda_codec *codec) codec->patch_ops = stac92xx_patch_ops; - if (find_mute_led_cfg(codec, -1/*no default cfg*/)) + if (find_mute_led_gpio(codec, 0)) snd_printd("mute LED gpio %d polarity %d\n", spec->gpio_led, spec->gpio_led_polarity); #ifdef CONFIG_SND_HDA_POWER_SAVE if (spec->gpio_led) { - if (!spec->vref_mute_led_nid) { + if (spec->gpio_led <= 8) { spec->gpio_mask |= spec->gpio_led; spec->gpio_dir |= spec->gpio_led; spec->gpio_data |= spec->gpio_led; } else { codec->patch_ops.set_power_state = stac92xx_set_power_state; + codec->patch_ops.post_suspend = + stac92xx_post_suspend; } codec->patch_ops.pre_resume = stac92xx_pre_resume; codec->patch_ops.check_power_status = @@ -5962,20 +5967,22 @@ static int patch_stac92hd71bxx(struct hda_codec *codec) } } - if (find_mute_led_cfg(codec, 1)) + if (find_mute_led_gpio(codec, 1)) snd_printd("mute LED gpio %d polarity %d\n", spec->gpio_led, spec->gpio_led_polarity); #ifdef CONFIG_SND_HDA_POWER_SAVE if (spec->gpio_led) { - if (!spec->vref_mute_led_nid) { + if (spec->gpio_led <= 8) { spec->gpio_mask |= spec->gpio_led; spec->gpio_dir |= spec->gpio_led; spec->gpio_data |= spec->gpio_led; } else { codec->patch_ops.set_power_state = stac92xx_set_power_state; + codec->patch_ops.post_suspend = + stac92xx_post_suspend; } codec->patch_ops.pre_resume = stac92xx_pre_resume; codec->patch_ops.check_power_status = diff --git a/trunk/sound/pci/hda/patch_via.c b/trunk/sound/pci/hda/patch_via.c index b5137629f8e9..431c0d417eeb 100644 --- a/trunk/sound/pci/hda/patch_via.c +++ b/trunk/sound/pci/hda/patch_via.c @@ -208,7 +208,6 @@ struct via_spec { /* work to check hp jack state */ struct hda_codec *codec; struct delayed_work vt1708_hp_work; - int hp_work_active; int vt1708_jack_detect; int vt1708_hp_present; @@ -306,35 +305,27 @@ enum { static void analog_low_current_mode(struct hda_codec *codec); static bool is_aa_path_mute(struct hda_codec *codec); -#define hp_detect_with_aa(codec) \ - (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1 && \ - !is_aa_path_mute(codec)) - -static void vt1708_stop_hp_work(struct via_spec *spec) +static void vt1708_start_hp_work(struct via_spec *spec) { if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0) return; - if (spec->hp_work_active) { - snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81, 1); - cancel_delayed_work_sync(&spec->vt1708_hp_work); - spec->hp_work_active = 0; - } + snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81, + !spec->vt1708_jack_detect); + if (!delayed_work_pending(&spec->vt1708_hp_work)) + schedule_delayed_work(&spec->vt1708_hp_work, + msecs_to_jiffies(100)); } -static void vt1708_update_hp_work(struct via_spec *spec) +static void vt1708_stop_hp_work(struct via_spec *spec) { if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0) return; - if (spec->vt1708_jack_detect && - (spec->active_streams || hp_detect_with_aa(spec->codec))) { - if (!spec->hp_work_active) { - snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81, 0); - schedule_delayed_work(&spec->vt1708_hp_work, - msecs_to_jiffies(100)); - spec->hp_work_active = 1; - } - } else if (!hp_detect_with_aa(spec->codec)) - vt1708_stop_hp_work(spec); + if (snd_hda_get_bool_hint(spec->codec, "analog_loopback_hp_detect") == 1 + && !is_aa_path_mute(spec->codec)) + return; + snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81, + !spec->vt1708_jack_detect); + cancel_delayed_work_sync(&spec->vt1708_hp_work); } static void set_widgets_power_state(struct hda_codec *codec) @@ -352,7 +343,12 @@ static int analog_input_switch_put(struct snd_kcontrol *kcontrol, set_widgets_power_state(codec); analog_low_current_mode(snd_kcontrol_chip(kcontrol)); - vt1708_update_hp_work(codec->spec); + if (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1) { + if (is_aa_path_mute(codec)) + vt1708_start_hp_work(codec->spec); + else + vt1708_stop_hp_work(codec->spec); + } return change; } @@ -1158,7 +1154,7 @@ static int via_playback_multi_pcm_prepare(struct hda_pcm_stream *hinfo, spec->cur_dac_stream_tag = stream_tag; spec->cur_dac_format = format; mutex_unlock(&spec->config_mutex); - vt1708_update_hp_work(spec); + vt1708_start_hp_work(spec); return 0; } @@ -1178,7 +1174,7 @@ static int via_playback_hp_pcm_prepare(struct hda_pcm_stream *hinfo, spec->cur_hp_stream_tag = stream_tag; spec->cur_hp_format = format; mutex_unlock(&spec->config_mutex); - vt1708_update_hp_work(spec); + vt1708_start_hp_work(spec); return 0; } @@ -1192,7 +1188,7 @@ static int via_playback_multi_pcm_cleanup(struct hda_pcm_stream *hinfo, snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); spec->active_streams &= ~STREAM_MULTI_OUT; mutex_unlock(&spec->config_mutex); - vt1708_update_hp_work(spec); + vt1708_stop_hp_work(spec); return 0; } @@ -1207,7 +1203,7 @@ static int via_playback_hp_pcm_cleanup(struct hda_pcm_stream *hinfo, snd_hda_codec_setup_stream(codec, spec->hp_dac_nid, 0, 0, 0); spec->active_streams &= ~STREAM_INDEP_HP; mutex_unlock(&spec->config_mutex); - vt1708_update_hp_work(spec); + vt1708_stop_hp_work(spec); return 0; } @@ -1649,8 +1645,7 @@ static void via_hp_automute(struct hda_codec *codec) int nums; struct via_spec *spec = codec->spec; - if (!spec->hp_independent_mode && spec->autocfg.hp_pins[0] && - (spec->codec_type != VT1708 || spec->vt1708_jack_detect)) + if (!spec->hp_independent_mode && spec->autocfg.hp_pins[0]) present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]); if (spec->smart51_enabled) @@ -2617,6 +2612,8 @@ static int vt1708_jack_detect_get(struct snd_kcontrol *kcontrol, if (spec->codec_type != VT1708) return 0; + spec->vt1708_jack_detect = + !((snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8) & 0x1); ucontrol->value.integer.value[0] = spec->vt1708_jack_detect; return 0; } @@ -2626,22 +2623,18 @@ static int vt1708_jack_detect_put(struct snd_kcontrol *kcontrol, { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct via_spec *spec = codec->spec; - int val; + int change; if (spec->codec_type != VT1708) return 0; - val = !!ucontrol->value.integer.value[0]; - if (spec->vt1708_jack_detect == val) - return 0; - spec->vt1708_jack_detect = val; - if (spec->vt1708_jack_detect && - snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") != 1) { + spec->vt1708_jack_detect = ucontrol->value.integer.value[0]; + change = (0x1 & (snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8)) + == !spec->vt1708_jack_detect; + if (spec->vt1708_jack_detect) { mute_aa_path(codec, 1); notify_aa_path_ctls(codec); } - via_hp_automute(codec); - vt1708_update_hp_work(spec); - return 1; + return change; } static const struct snd_kcontrol_new vt1708_jack_detect_ctl = { @@ -2778,7 +2771,6 @@ static int via_init(struct hda_codec *codec) via_auto_init_unsol_event(codec); via_hp_automute(codec); - vt1708_update_hp_work(spec); return 0; } @@ -2795,9 +2787,7 @@ static void vt1708_update_hp_jack_state(struct work_struct *work) spec->vt1708_hp_present ^= 1; via_hp_automute(spec->codec); } - if (spec->vt1708_jack_detect) - schedule_delayed_work(&spec->vt1708_hp_work, - msecs_to_jiffies(100)); + vt1708_start_hp_work(spec); } static int get_mux_nids(struct hda_codec *codec) diff --git a/trunk/sound/pci/lx6464es/lx_core.c b/trunk/sound/pci/lx6464es/lx_core.c index 8c3e7fcefd99..5c8717e29eeb 100644 --- a/trunk/sound/pci/lx6464es/lx_core.c +++ b/trunk/sound/pci/lx6464es/lx_core.c @@ -78,15 +78,10 @@ unsigned long lx_dsp_reg_read(struct lx6464es *chip, int port) return ioread32(address); } -static void lx_dsp_reg_readbuf(struct lx6464es *chip, int port, u32 *data, - u32 len) +void lx_dsp_reg_readbuf(struct lx6464es *chip, int port, u32 *data, u32 len) { - u32 __iomem *address = lx_dsp_register(chip, port); - int i; - - /* we cannot use memcpy_fromio */ - for (i = 0; i != len; ++i) - data[i] = ioread32(address + i); + void __iomem *address = lx_dsp_register(chip, port); + memcpy_fromio(data, address, len*sizeof(u32)); } @@ -96,15 +91,11 @@ void lx_dsp_reg_write(struct lx6464es *chip, int port, unsigned data) iowrite32(data, address); } -static void lx_dsp_reg_writebuf(struct lx6464es *chip, int port, - const u32 *data, u32 len) +void lx_dsp_reg_writebuf(struct lx6464es *chip, int port, const u32 *data, + u32 len) { - u32 __iomem *address = lx_dsp_register(chip, port); - int i; - - /* we cannot use memcpy_to */ - for (i = 0; i != len; ++i) - iowrite32(data[i], address + i); + void __iomem *address = lx_dsp_register(chip, port); + memcpy_toio(address, data, len*sizeof(u32)); } diff --git a/trunk/sound/pci/lx6464es/lx_core.h b/trunk/sound/pci/lx6464es/lx_core.h index 4d7ff797a646..1dd562980b6c 100644 --- a/trunk/sound/pci/lx6464es/lx_core.h +++ b/trunk/sound/pci/lx6464es/lx_core.h @@ -72,7 +72,10 @@ enum { }; unsigned long lx_dsp_reg_read(struct lx6464es *chip, int port); +void lx_dsp_reg_readbuf(struct lx6464es *chip, int port, u32 *data, u32 len); void lx_dsp_reg_write(struct lx6464es *chip, int port, unsigned data); +void lx_dsp_reg_writebuf(struct lx6464es *chip, int port, const u32 *data, + u32 len); /* plx register access */ enum { diff --git a/trunk/sound/pci/rme9652/hdspm.c b/trunk/sound/pci/rme9652/hdspm.c index 19ee2203cbb5..e760adad9523 100644 --- a/trunk/sound/pci/rme9652/hdspm.c +++ b/trunk/sound/pci/rme9652/hdspm.c @@ -6518,7 +6518,7 @@ static int __devinit snd_hdspm_create(struct snd_card *card, hdspm->io_type = AES32; hdspm->card_name = "RME AES32"; hdspm->midiPorts = 2; - } else if ((hdspm->firmware_rev == 0xd2) || + } else if ((hdspm->firmware_rev == 0xd5) || ((hdspm->firmware_rev >= 0xc8) && (hdspm->firmware_rev <= 0xcf))) { hdspm->io_type = MADI; diff --git a/trunk/sound/pci/sis7019.c b/trunk/sound/pci/sis7019.c index 28dfafb56dd1..a391e622a192 100644 --- a/trunk/sound/pci/sis7019.c +++ b/trunk/sound/pci/sis7019.c @@ -41,7 +41,6 @@ MODULE_SUPPORTED_DEVICE("{{SiS,SiS7019 Audio Accelerator}}"); static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */ static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ static int enable = 1; -static int codecs = 1; module_param(index, int, 0444); MODULE_PARM_DESC(index, "Index value for SiS7019 Audio Accelerator."); @@ -49,8 +48,6 @@ module_param(id, charp, 0444); MODULE_PARM_DESC(id, "ID string for SiS7019 Audio Accelerator."); module_param(enable, bool, 0444); MODULE_PARM_DESC(enable, "Enable SiS7019 Audio Accelerator."); -module_param(codecs, int, 0444); -MODULE_PARM_DESC(codecs, "Set bit to indicate that codec number is expected to be present (default 1)"); static DEFINE_PCI_DEVICE_TABLE(snd_sis7019_ids) = { { PCI_DEVICE(PCI_VENDOR_ID_SI, 0x7019) }, @@ -143,9 +140,6 @@ struct sis7019 { dma_addr_t silence_dma_addr; }; -/* These values are also used by the module param 'codecs' to indicate - * which codecs should be present. - */ #define SIS_PRIMARY_CODEC_PRESENT 0x0001 #define SIS_SECONDARY_CODEC_PRESENT 0x0002 #define SIS_TERTIARY_CODEC_PRESENT 0x0004 @@ -1084,7 +1078,6 @@ static int sis_chip_init(struct sis7019 *sis) { unsigned long io = sis->ioport; void __iomem *ioaddr = sis->ioaddr; - unsigned long timeout; u16 status; int count; int i; @@ -1111,45 +1104,21 @@ static int sis_chip_init(struct sis7019 *sis) while ((inw(io + SIS_AC97_STATUS) & SIS_AC97_STATUS_BUSY) && --count) udelay(1); - /* Command complete, we can let go of the semaphore now. - */ - outl(SIS_AC97_SEMA_RELEASE, io + SIS_AC97_SEMA); - if (!count) - return -EIO; - /* Now that we've finished the reset, find out what's attached. - * There are some codec/board combinations that take an extremely - * long time to come up. 350+ ms has been observed in the field, - * so we'll give them up to 500ms. */ - sis->codecs_present = 0; - timeout = msecs_to_jiffies(500) + jiffies; - while (time_before_eq(jiffies, timeout)) { - status = inl(io + SIS_AC97_STATUS); - if (status & SIS_AC97_STATUS_CODEC_READY) - sis->codecs_present |= SIS_PRIMARY_CODEC_PRESENT; - if (status & SIS_AC97_STATUS_CODEC2_READY) - sis->codecs_present |= SIS_SECONDARY_CODEC_PRESENT; - if (status & SIS_AC97_STATUS_CODEC3_READY) - sis->codecs_present |= SIS_TERTIARY_CODEC_PRESENT; - - if (sis->codecs_present == codecs) - break; - - msleep(1); - } - - /* All done, check for errors. + status = inl(io + SIS_AC97_STATUS); + if (status & SIS_AC97_STATUS_CODEC_READY) + sis->codecs_present |= SIS_PRIMARY_CODEC_PRESENT; + if (status & SIS_AC97_STATUS_CODEC2_READY) + sis->codecs_present |= SIS_SECONDARY_CODEC_PRESENT; + if (status & SIS_AC97_STATUS_CODEC3_READY) + sis->codecs_present |= SIS_TERTIARY_CODEC_PRESENT; + + /* All done, let go of the semaphore, and check for errors */ - if (!sis->codecs_present) { - printk(KERN_ERR "sis7019: could not find any codecs\n"); + outl(SIS_AC97_SEMA_RELEASE, io + SIS_AC97_SEMA); + if (!sis->codecs_present || !count) return -EIO; - } - - if (sis->codecs_present != codecs) { - printk(KERN_WARNING "sis7019: missing codecs, found %0x, expected %0x\n", - sis->codecs_present, codecs); - } /* Let the hardware know that the audio driver is alive, * and enable PCM slots on the AC-link for L/R playback (3 & 4) and @@ -1421,17 +1390,6 @@ static int __devinit snd_sis7019_probe(struct pci_dev *pci, if (!enable) goto error_out; - /* The user can specify which codecs should be present so that we - * can wait for them to show up if they are slow to recover from - * the AC97 cold reset. We default to a single codec, the primary. - * - * We assume that SIS_PRIMARY_*_PRESENT matches bits 0-2. - */ - codecs &= SIS_PRIMARY_CODEC_PRESENT | SIS_SECONDARY_CODEC_PRESENT | - SIS_TERTIARY_CODEC_PRESENT; - if (!codecs) - codecs = SIS_PRIMARY_CODEC_PRESENT; - rc = snd_card_create(index, id, THIS_MODULE, sizeof(*sis), &card); if (rc < 0) goto error_out; diff --git a/trunk/sound/soc/atmel/Kconfig b/trunk/sound/soc/atmel/Kconfig index d1fcc816ce97..bee3c94f58b0 100644 --- a/trunk/sound/soc/atmel/Kconfig +++ b/trunk/sound/soc/atmel/Kconfig @@ -1,6 +1,6 @@ config SND_ATMEL_SOC tristate "SoC Audio for the Atmel System-on-Chip" - depends on ARCH_AT91 + depends on ARCH_AT91 || AVR32 help Say Y or M if you want to add support for codecs attached to the ATMEL SSC interface. You will also need @@ -24,6 +24,25 @@ config SND_AT91_SOC_SAM9G20_WM8731 Say Y if you want to add support for SoC audio on WM8731-based AT91sam9g20 evaluation board. +config SND_AT32_SOC_PLAYPAQ + tristate "SoC Audio support for PlayPaq with WM8510" + depends on SND_ATMEL_SOC && BOARD_PLAYPAQ && AT91_PROGRAMMABLE_CLOCKS + select SND_ATMEL_SOC_SSC + select SND_SOC_WM8510 + help + Say Y or M here if you want to add support for SoC audio + on the LRS PlayPaq. + +config SND_AT32_SOC_PLAYPAQ_SLAVE + bool "Run CODEC on PlayPaq in slave mode" + depends on SND_AT32_SOC_PLAYPAQ + default n + help + Say Y if you want to run with the AT32 SSC generating the BCLK + and FRAME signals on the PlayPaq. Unless you want to play + with the AT32 as the SSC master, you probably want to say N here, + as this will give you better sound quality. + config SND_AT91_SOC_AFEB9260 tristate "SoC Audio support for AFEB9260 board" depends on ARCH_AT91 && MACH_AFEB9260 && SND_ATMEL_SOC diff --git a/trunk/sound/soc/atmel/Makefile b/trunk/sound/soc/atmel/Makefile index a5c0bf19da78..e7ea56bd5f82 100644 --- a/trunk/sound/soc/atmel/Makefile +++ b/trunk/sound/soc/atmel/Makefile @@ -8,5 +8,9 @@ obj-$(CONFIG_SND_ATMEL_SOC_SSC) += snd-soc-atmel_ssc_dai.o # AT91 Machine Support snd-soc-sam9g20-wm8731-objs := sam9g20_wm8731.o +# AT32 Machine Support +snd-soc-playpaq-objs := playpaq_wm8510.o + obj-$(CONFIG_SND_AT91_SOC_SAM9G20_WM8731) += snd-soc-sam9g20-wm8731.o +obj-$(CONFIG_SND_AT32_SOC_PLAYPAQ) += snd-soc-playpaq.o obj-$(CONFIG_SND_AT91_SOC_AFEB9260) += snd-soc-afeb9260.o diff --git a/trunk/sound/soc/atmel/playpaq_wm8510.c b/trunk/sound/soc/atmel/playpaq_wm8510.c new file mode 100644 index 000000000000..73ae99ad4578 --- /dev/null +++ b/trunk/sound/soc/atmel/playpaq_wm8510.c @@ -0,0 +1,473 @@ +/* sound/soc/at32/playpaq_wm8510.c + * ASoC machine driver for PlayPaq using WM8510 codec + * + * Copyright (C) 2008 Long Range Systems + * Geoffrey Wossum + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This code is largely inspired by sound/soc/at91/eti_b1_wm8731.c + * + * NOTE: If you don't have the AT32 enhanced portmux configured (which + * isn't currently in the mainline or Atmel patched kernel), you will + * need to set the MCLK pin (PA30) to peripheral A in your board initialization + * code. Something like: + * at32_select_periph(GPIO_PIN_PA(30), GPIO_PERIPH_A, 0); + * + */ + +/* #define DEBUG */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include "../codecs/wm8510.h" +#include "atmel-pcm.h" +#include "atmel_ssc_dai.h" + + +/*-------------------------------------------------------------------------*\ + * constants +\*-------------------------------------------------------------------------*/ +#define MCLK_PIN GPIO_PIN_PA(30) +#define MCLK_PERIPH GPIO_PERIPH_A + + +/*-------------------------------------------------------------------------*\ + * data types +\*-------------------------------------------------------------------------*/ +/* SSC clocking data */ +struct ssc_clock_data { + /* CMR div */ + unsigned int cmr_div; + + /* Frame period (as needed by xCMR.PERIOD) */ + unsigned int period; + + /* The SSC clock rate these settings where calculated for */ + unsigned long ssc_rate; +}; + + +/*-------------------------------------------------------------------------*\ + * module data +\*-------------------------------------------------------------------------*/ +static struct clk *_gclk0; +static struct clk *_pll0; + +#define CODEC_CLK (_gclk0) + + +/*-------------------------------------------------------------------------*\ + * Sound SOC operations +\*-------------------------------------------------------------------------*/ +#if defined CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE +static struct ssc_clock_data playpaq_wm8510_calc_ssc_clock( + struct snd_pcm_hw_params *params, + struct snd_soc_dai *cpu_dai) +{ + struct at32_ssc_info *ssc_p = snd_soc_dai_get_drvdata(cpu_dai); + struct ssc_device *ssc = ssc_p->ssc; + struct ssc_clock_data cd; + unsigned int rate, width_bits, channels; + unsigned int bitrate, ssc_div; + unsigned actual_rate; + + + /* + * Figure out required bitrate + */ + rate = params_rate(params); + channels = params_channels(params); + width_bits = snd_pcm_format_physical_width(params_format(params)); + bitrate = rate * width_bits * channels; + + + /* + * Figure out required SSC divider and period for required bitrate + */ + cd.ssc_rate = clk_get_rate(ssc->clk); + ssc_div = cd.ssc_rate / bitrate; + cd.cmr_div = ssc_div / 2; + if (ssc_div & 1) { + /* round cmr_div up */ + cd.cmr_div++; + } + cd.period = width_bits - 1; + + + /* + * Find actual rate, compare to requested rate + */ + actual_rate = (cd.ssc_rate / (cd.cmr_div * 2)) / (2 * (cd.period + 1)); + pr_debug("playpaq_wm8510: Request rate = %u, actual rate = %u\n", + rate, actual_rate); + + + return cd; +} +#endif /* CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE */ + + + +static int playpaq_wm8510_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *rtd = substream->private_data; + struct snd_soc_dai *codec_dai = rtd->codec_dai; + struct snd_soc_dai *cpu_dai = rtd->cpu_dai; + struct at32_ssc_info *ssc_p = snd_soc_dai_get_drvdata(cpu_dai); + struct ssc_device *ssc = ssc_p->ssc; + unsigned int pll_out = 0, bclk = 0, mclk_div = 0; + int ret; + + + /* Due to difficulties with getting the correct clocks from the AT32's + * PLL0, we're going to let the CODEC be in charge of all the clocks + */ +#if !defined CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE + const unsigned int fmt = (SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBM_CFM); +#else + struct ssc_clock_data cd; + const unsigned int fmt = (SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBS_CFS); +#endif + + if (ssc == NULL) { + pr_warning("playpaq_wm8510_hw_params: ssc is NULL!\n"); + return -EINVAL; + } + + + /* + * Figure out PLL and BCLK dividers for WM8510 + */ + switch (params_rate(params)) { + case 48000: + pll_out = 24576000; + mclk_div = WM8510_MCLKDIV_2; + bclk = WM8510_BCLKDIV_8; + break; + + case 44100: + pll_out = 22579200; + mclk_div = WM8510_MCLKDIV_2; + bclk = WM8510_BCLKDIV_8; + break; + + case 22050: + pll_out = 22579200; + mclk_div = WM8510_MCLKDIV_4; + bclk = WM8510_BCLKDIV_8; + break; + + case 16000: + pll_out = 24576000; + mclk_div = WM8510_MCLKDIV_6; + bclk = WM8510_BCLKDIV_8; + break; + + case 11025: + pll_out = 22579200; + mclk_div = WM8510_MCLKDIV_8; + bclk = WM8510_BCLKDIV_8; + break; + + case 8000: + pll_out = 24576000; + mclk_div = WM8510_MCLKDIV_12; + bclk = WM8510_BCLKDIV_8; + break; + + default: + pr_warning("playpaq_wm8510: Unsupported sample rate %d\n", + params_rate(params)); + return -EINVAL; + } + + + /* + * set CPU and CODEC DAI configuration + */ + ret = snd_soc_dai_set_fmt(codec_dai, fmt); + if (ret < 0) { + pr_warning("playpaq_wm8510: " + "Failed to set CODEC DAI format (%d)\n", + ret); + return ret; + } + ret = snd_soc_dai_set_fmt(cpu_dai, fmt); + if (ret < 0) { + pr_warning("playpaq_wm8510: " + "Failed to set CPU DAI format (%d)\n", + ret); + return ret; + } + + + /* + * Set CPU clock configuration + */ +#if defined CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE + cd = playpaq_wm8510_calc_ssc_clock(params, cpu_dai); + pr_debug("playpaq_wm8510: cmr_div = %d, period = %d\n", + cd.cmr_div, cd.period); + ret = snd_soc_dai_set_clkdiv(cpu_dai, AT32_SSC_CMR_DIV, cd.cmr_div); + if (ret < 0) { + pr_warning("playpaq_wm8510: Failed to set CPU CMR_DIV (%d)\n", + ret); + return ret; + } + ret = snd_soc_dai_set_clkdiv(cpu_dai, AT32_SSC_TCMR_PERIOD, + cd.period); + if (ret < 0) { + pr_warning("playpaq_wm8510: " + "Failed to set CPU transmit period (%d)\n", + ret); + return ret; + } +#endif /* CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE */ + + + /* + * Set CODEC clock configuration + */ + pr_debug("playpaq_wm8510: " + "pll_in = %ld, pll_out = %u, bclk = %x, mclk = %x\n", + clk_get_rate(CODEC_CLK), pll_out, bclk, mclk_div); + + +#if !defined CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE + ret = snd_soc_dai_set_clkdiv(codec_dai, WM8510_BCLKDIV, bclk); + if (ret < 0) { + pr_warning + ("playpaq_wm8510: Failed to set CODEC DAI BCLKDIV (%d)\n", + ret); + return ret; + } +#endif /* CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE */ + + + ret = snd_soc_dai_set_pll(codec_dai, 0, 0, + clk_get_rate(CODEC_CLK), pll_out); + if (ret < 0) { + pr_warning("playpaq_wm8510: Failed to set CODEC DAI PLL (%d)\n", + ret); + return ret; + } + + + ret = snd_soc_dai_set_clkdiv(codec_dai, WM8510_MCLKDIV, mclk_div); + if (ret < 0) { + pr_warning("playpaq_wm8510: Failed to set CODEC MCLKDIV (%d)\n", + ret); + return ret; + } + + + return 0; +} + + + +static struct snd_soc_ops playpaq_wm8510_ops = { + .hw_params = playpaq_wm8510_hw_params, +}; + + + +static const struct snd_soc_dapm_widget playpaq_dapm_widgets[] = { + SND_SOC_DAPM_MIC("Int Mic", NULL), + SND_SOC_DAPM_SPK("Ext Spk", NULL), +}; + + + +static const struct snd_soc_dapm_route intercon[] = { + /* speaker connected to SPKOUT */ + {"Ext Spk", NULL, "SPKOUTP"}, + {"Ext Spk", NULL, "SPKOUTN"}, + + {"Mic Bias", NULL, "Int Mic"}, + {"MICN", NULL, "Mic Bias"}, + {"MICP", NULL, "Mic Bias"}, +}; + + + +static int playpaq_wm8510_init(struct snd_soc_pcm_runtime *rtd) +{ + struct snd_soc_codec *codec = rtd->codec; + struct snd_soc_dapm_context *dapm = &codec->dapm; + int i; + + /* + * Add DAPM widgets + */ + for (i = 0; i < ARRAY_SIZE(playpaq_dapm_widgets); i++) + snd_soc_dapm_new_control(dapm, &playpaq_dapm_widgets[i]); + + + + /* + * Setup audio path interconnects + */ + snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); + + + + /* always connected pins */ + snd_soc_dapm_enable_pin(dapm, "Int Mic"); + snd_soc_dapm_enable_pin(dapm, "Ext Spk"); + + + + /* Make CSB show PLL rate */ + snd_soc_dai_set_clkdiv(rtd->codec_dai, WM8510_OPCLKDIV, + WM8510_OPCLKDIV_1 | 4); + + return 0; +} + + + +static struct snd_soc_dai_link playpaq_wm8510_dai = { + .name = "WM8510", + .stream_name = "WM8510 PCM", + .cpu_dai_name= "atmel-ssc-dai.0", + .platform_name = "atmel-pcm-audio", + .codec_name = "wm8510-codec.0-0x1a", + .codec_dai_name = "wm8510-hifi", + .init = playpaq_wm8510_init, + .ops = &playpaq_wm8510_ops, +}; + + + +static struct snd_soc_card snd_soc_playpaq = { + .name = "LRS_PlayPaq_WM8510", + .dai_link = &playpaq_wm8510_dai, + .num_links = 1, +}; + +static struct platform_device *playpaq_snd_device; + + +static int __init playpaq_asoc_init(void) +{ + int ret = 0; + + /* + * Configure MCLK for WM8510 + */ + _gclk0 = clk_get(NULL, "gclk0"); + if (IS_ERR(_gclk0)) { + _gclk0 = NULL; + ret = PTR_ERR(_gclk0); + goto err_gclk0; + } + _pll0 = clk_get(NULL, "pll0"); + if (IS_ERR(_pll0)) { + _pll0 = NULL; + ret = PTR_ERR(_pll0); + goto err_pll0; + } + ret = clk_set_parent(_gclk0, _pll0); + if (ret) { + pr_warning("snd-soc-playpaq: " + "Failed to set PLL0 as parent for DAC clock\n"); + goto err_set_clk; + } + clk_set_rate(CODEC_CLK, 12000000); + clk_enable(CODEC_CLK); + +#if defined CONFIG_AT32_ENHANCED_PORTMUX + at32_select_periph(MCLK_PIN, MCLK_PERIPH, 0); +#endif + + + /* + * Create and register platform device + */ + playpaq_snd_device = platform_device_alloc("soc-audio", 0); + if (playpaq_snd_device == NULL) { + ret = -ENOMEM; + goto err_device_alloc; + } + + platform_set_drvdata(playpaq_snd_device, &snd_soc_playpaq); + + ret = platform_device_add(playpaq_snd_device); + if (ret) { + pr_warning("playpaq_wm8510: platform_device_add failed (%d)\n", + ret); + goto err_device_add; + } + + return 0; + + +err_device_add: + if (playpaq_snd_device != NULL) { + platform_device_put(playpaq_snd_device); + playpaq_snd_device = NULL; + } +err_device_alloc: +err_set_clk: + if (_pll0 != NULL) { + clk_put(_pll0); + _pll0 = NULL; + } +err_pll0: + if (_gclk0 != NULL) { + clk_put(_gclk0); + _gclk0 = NULL; + } + return ret; +} + + +static void __exit playpaq_asoc_exit(void) +{ + if (_gclk0 != NULL) { + clk_put(_gclk0); + _gclk0 = NULL; + } + if (_pll0 != NULL) { + clk_put(_pll0); + _pll0 = NULL; + } + +#if defined CONFIG_AT32_ENHANCED_PORTMUX + at32_free_pin(MCLK_PIN); +#endif + + platform_device_unregister(playpaq_snd_device); + playpaq_snd_device = NULL; +} + +module_init(playpaq_asoc_init); +module_exit(playpaq_asoc_exit); + +MODULE_AUTHOR("Geoffrey Wossum "); +MODULE_DESCRIPTION("ASoC machine driver for LRS PlayPaq"); +MODULE_LICENSE("GPL"); diff --git a/trunk/sound/soc/codecs/ad1836.h b/trunk/sound/soc/codecs/ad1836.h index dd7be0dbbc58..444747f0db26 100644 --- a/trunk/sound/soc/codecs/ad1836.h +++ b/trunk/sound/soc/codecs/ad1836.h @@ -34,7 +34,7 @@ #define AD1836_ADC_CTRL2 13 #define AD1836_ADC_WORD_LEN_MASK 0x30 -#define AD1836_ADC_WORD_OFFSET 4 +#define AD1836_ADC_WORD_OFFSET 5 #define AD1836_ADC_SERFMT_MASK (7 << 6) #define AD1836_ADC_SERFMT_PCK256 (0x4 << 6) #define AD1836_ADC_SERFMT_PCK128 (0x5 << 6) diff --git a/trunk/sound/soc/codecs/adau1373.c b/trunk/sound/soc/codecs/adau1373.c index 45c63028b40d..1ccf8dd47576 100644 --- a/trunk/sound/soc/codecs/adau1373.c +++ b/trunk/sound/soc/codecs/adau1373.c @@ -245,7 +245,7 @@ static const char *adau1373_bass_hpf_cutoff_text[] = { }; static const unsigned int adau1373_bass_tlv[] = { - TLV_DB_RANGE_HEAD(3), + TLV_DB_RANGE_HEAD(4), 0, 2, TLV_DB_SCALE_ITEM(-600, 600, 1), 3, 4, TLV_DB_SCALE_ITEM(950, 250, 0), 5, 7, TLV_DB_SCALE_ITEM(1400, 150, 0), diff --git a/trunk/sound/soc/codecs/cs4270.c b/trunk/sound/soc/codecs/cs4270.c index 73f46eb459f1..f1f237ecec2a 100644 --- a/trunk/sound/soc/codecs/cs4270.c +++ b/trunk/sound/soc/codecs/cs4270.c @@ -601,6 +601,7 @@ static int cs4270_soc_suspend(struct snd_soc_codec *codec, pm_message_t mesg) static int cs4270_soc_resume(struct snd_soc_codec *codec) { struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); + struct i2c_client *i2c_client = to_i2c_client(codec->dev); int reg; regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies), @@ -611,7 +612,14 @@ static int cs4270_soc_resume(struct snd_soc_codec *codec) ndelay(500); /* first restore the entire register cache ... */ - snd_soc_cache_sync(codec); + for (reg = CS4270_FIRSTREG; reg <= CS4270_LASTREG; reg++) { + u8 val = snd_soc_read(codec, reg); + + if (i2c_smbus_write_byte_data(i2c_client, reg, val)) { + dev_err(codec->dev, "i2c write failed\n"); + return -EIO; + } + } /* ... then disable the power-down bits */ reg = snd_soc_read(codec, CS4270_PWRCTL); diff --git a/trunk/sound/soc/codecs/cs4271.c b/trunk/sound/soc/codecs/cs4271.c index 69fde1506fe1..23d1bd5dadda 100644 --- a/trunk/sound/soc/codecs/cs4271.c +++ b/trunk/sound/soc/codecs/cs4271.c @@ -434,8 +434,7 @@ static int cs4271_soc_suspend(struct snd_soc_codec *codec, pm_message_t mesg) { int ret; /* Set power-down bit */ - ret = snd_soc_update_bits(codec, CS4271_MODE2, CS4271_MODE2_PDN, - CS4271_MODE2_PDN); + ret = snd_soc_update_bits(codec, CS4271_MODE2, 0, CS4271_MODE2_PDN); if (ret < 0) return ret; return 0; @@ -502,9 +501,8 @@ static int cs4271_probe(struct snd_soc_codec *codec) return ret; } - ret = snd_soc_update_bits(codec, CS4271_MODE2, - CS4271_MODE2_PDN | CS4271_MODE2_CPEN, - CS4271_MODE2_PDN | CS4271_MODE2_CPEN); + ret = snd_soc_update_bits(codec, CS4271_MODE2, 0, + CS4271_MODE2_PDN | CS4271_MODE2_CPEN); if (ret < 0) return ret; ret = snd_soc_update_bits(codec, CS4271_MODE2, CS4271_MODE2_PDN, 0); diff --git a/trunk/sound/soc/codecs/cs42l51.c b/trunk/sound/soc/codecs/cs42l51.c index 1ee66361f61b..8c3c8205d19e 100644 --- a/trunk/sound/soc/codecs/cs42l51.c +++ b/trunk/sound/soc/codecs/cs42l51.c @@ -555,7 +555,7 @@ static int cs42l51_probe(struct snd_soc_codec *codec) static struct snd_soc_codec_driver soc_codec_device_cs42l51 = { .probe = cs42l51_probe, - .reg_cache_size = CS42L51_NUMREGS + 1, + .reg_cache_size = CS42L51_NUMREGS, .reg_word_size = sizeof(u8), }; diff --git a/trunk/sound/soc/codecs/max9877.c b/trunk/sound/soc/codecs/max9877.c index dcf6f2a1600a..9e7e964a5fa3 100644 --- a/trunk/sound/soc/codecs/max9877.c +++ b/trunk/sound/soc/codecs/max9877.c @@ -106,13 +106,13 @@ static int max9877_set_2reg(struct snd_kcontrol *kcontrol, unsigned int mask = mc->max; unsigned int val = (ucontrol->value.integer.value[0] & mask); unsigned int val2 = (ucontrol->value.integer.value[1] & mask); - unsigned int change = 0; + unsigned int change = 1; - if (((max9877_regs[reg] >> shift) & mask) != val) - change = 1; + if (((max9877_regs[reg] >> shift) & mask) == val) + change = 0; - if (((max9877_regs[reg2] >> shift) & mask) != val2) - change = 1; + if (((max9877_regs[reg2] >> shift) & mask) == val2) + change = 0; if (change) { max9877_regs[reg] &= ~(mask << shift); diff --git a/trunk/sound/soc/codecs/rt5631.c b/trunk/sound/soc/codecs/rt5631.c index 4646e808b90a..27a078cbb6eb 100644 --- a/trunk/sound/soc/codecs/rt5631.c +++ b/trunk/sound/soc/codecs/rt5631.c @@ -177,7 +177,7 @@ static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -95625, 375, 0); static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0); /* {0, +20, +24, +30, +35, +40, +44, +50, +52}dB */ static unsigned int mic_bst_tlv[] = { - TLV_DB_RANGE_HEAD(7), + TLV_DB_RANGE_HEAD(6), 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0), 2, 2, TLV_DB_SCALE_ITEM(2400, 0, 0), diff --git a/trunk/sound/soc/codecs/sgtl5000.c b/trunk/sound/soc/codecs/sgtl5000.c index bbcf921166f7..d15695d1c273 100644 --- a/trunk/sound/soc/codecs/sgtl5000.c +++ b/trunk/sound/soc/codecs/sgtl5000.c @@ -365,7 +365,7 @@ static const DECLARE_TLV_DB_SCALE(capture_6db_attenuate, -600, 600, 0); /* tlv for mic gain, 0db 20db 30db 40db */ static const unsigned int mic_gain_tlv[] = { - TLV_DB_RANGE_HEAD(2), + TLV_DB_RANGE_HEAD(4), 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), 1, 3, TLV_DB_SCALE_ITEM(2000, 1000, 0), }; diff --git a/trunk/sound/soc/codecs/sta32x.c b/trunk/sound/soc/codecs/sta32x.c index d2f37152f940..bb82408ab8e1 100644 --- a/trunk/sound/soc/codecs/sta32x.c +++ b/trunk/sound/soc/codecs/sta32x.c @@ -76,8 +76,6 @@ struct sta32x_priv { unsigned int mclk; unsigned int format; - - u32 coef_shadow[STA32X_COEF_COUNT]; }; static const DECLARE_TLV_DB_SCALE(mvol_tlv, -12700, 50, 1); @@ -229,7 +227,6 @@ static int sta32x_coefficient_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); - struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec); int numcoef = kcontrol->private_value >> 16; int index = kcontrol->private_value & 0xffff; unsigned int cfud; @@ -242,11 +239,6 @@ static int sta32x_coefficient_put(struct snd_kcontrol *kcontrol, snd_soc_write(codec, STA32X_CFUD, cfud); snd_soc_write(codec, STA32X_CFADDR2, index); - for (i = 0; i < numcoef && (index + i < STA32X_COEF_COUNT); i++) - sta32x->coef_shadow[index + i] = - (ucontrol->value.bytes.data[3 * i] << 16) - | (ucontrol->value.bytes.data[3 * i + 1] << 8) - | (ucontrol->value.bytes.data[3 * i + 2]); for (i = 0; i < 3 * numcoef; i++) snd_soc_write(codec, STA32X_B1CF1 + i, ucontrol->value.bytes.data[i]); @@ -260,48 +252,6 @@ static int sta32x_coefficient_put(struct snd_kcontrol *kcontrol, return 0; } -int sta32x_sync_coef_shadow(struct snd_soc_codec *codec) -{ - struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec); - unsigned int cfud; - int i; - - /* preserve reserved bits in STA32X_CFUD */ - cfud = snd_soc_read(codec, STA32X_CFUD) & 0xf0; - - for (i = 0; i < STA32X_COEF_COUNT; i++) { - snd_soc_write(codec, STA32X_CFADDR2, i); - snd_soc_write(codec, STA32X_B1CF1, - (sta32x->coef_shadow[i] >> 16) & 0xff); - snd_soc_write(codec, STA32X_B1CF2, - (sta32x->coef_shadow[i] >> 8) & 0xff); - snd_soc_write(codec, STA32X_B1CF3, - (sta32x->coef_shadow[i]) & 0xff); - /* chip documentation does not say if the bits are - * self-clearing, so do it explicitly */ - snd_soc_write(codec, STA32X_CFUD, cfud); - snd_soc_write(codec, STA32X_CFUD, cfud | 0x01); - } - return 0; -} - -int sta32x_cache_sync(struct snd_soc_codec *codec) -{ - unsigned int mute; - int rc; - - if (!codec->cache_sync) - return 0; - - /* mute during register sync */ - mute = snd_soc_read(codec, STA32X_MMUTE); - snd_soc_write(codec, STA32X_MMUTE, mute | STA32X_MMUTE_MMUTE); - sta32x_sync_coef_shadow(codec); - rc = snd_soc_cache_sync(codec); - snd_soc_write(codec, STA32X_MMUTE, mute); - return rc; -} - #define SINGLE_COEF(xname, index) \ { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ .info = sta32x_coefficient_info, \ @@ -711,7 +661,7 @@ static int sta32x_set_bias_level(struct snd_soc_codec *codec, return ret; } - sta32x_cache_sync(codec); + snd_soc_cache_sync(codec); } /* Power up to mute */ @@ -840,17 +790,6 @@ static int sta32x_probe(struct snd_soc_codec *codec) STA32X_CxCFG_OM_MASK, 2 << STA32X_CxCFG_OM_SHIFT); - /* initialize coefficient shadow RAM with reset values */ - for (i = 4; i <= 49; i += 5) - sta32x->coef_shadow[i] = 0x400000; - for (i = 50; i <= 54; i++) - sta32x->coef_shadow[i] = 0x7fffff; - sta32x->coef_shadow[55] = 0x5a9df7; - sta32x->coef_shadow[56] = 0x7fffff; - sta32x->coef_shadow[59] = 0x7fffff; - sta32x->coef_shadow[60] = 0x400000; - sta32x->coef_shadow[61] = 0x400000; - sta32x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); /* Bias level configuration will have done an extra enable */ regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies); diff --git a/trunk/sound/soc/codecs/sta32x.h b/trunk/sound/soc/codecs/sta32x.h index d8e32a6262ee..b97ee5a75667 100644 --- a/trunk/sound/soc/codecs/sta32x.h +++ b/trunk/sound/soc/codecs/sta32x.h @@ -19,7 +19,6 @@ /* STA326 register addresses */ #define STA32X_REGISTER_COUNT 0x2d -#define STA32X_COEF_COUNT 62 #define STA32X_CONFA 0x00 #define STA32X_CONFB 0x01 diff --git a/trunk/sound/soc/codecs/uda1380.c b/trunk/sound/soc/codecs/uda1380.c index 0441893e270e..c5ca8cfea60f 100644 --- a/trunk/sound/soc/codecs/uda1380.c +++ b/trunk/sound/soc/codecs/uda1380.c @@ -863,13 +863,13 @@ static struct i2c_driver uda1380_i2c_driver = { static int __init uda1380_modinit(void) { - int ret = 0; + int ret; #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) ret = i2c_add_driver(&uda1380_i2c_driver); if (ret != 0) pr_err("Failed to register UDA1380 I2C driver: %d\n", ret); #endif - return ret; + return 0; } module_init(uda1380_modinit); diff --git a/trunk/sound/soc/codecs/wm8731.c b/trunk/sound/soc/codecs/wm8731.c index a7c9ae17fc7e..7e5ec03f6f8d 100644 --- a/trunk/sound/soc/codecs/wm8731.c +++ b/trunk/sound/soc/codecs/wm8731.c @@ -453,7 +453,6 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec, snd_soc_write(codec, WM8731_PWR, 0xffff); regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), wm8731->supplies); - codec->cache_sync = 1; break; } codec->dapm.bias_level = level; diff --git a/trunk/sound/soc/codecs/wm8753.c b/trunk/sound/soc/codecs/wm8753.c index 3a629d0d690e..a9504710bb69 100644 --- a/trunk/sound/soc/codecs/wm8753.c +++ b/trunk/sound/soc/codecs/wm8753.c @@ -190,9 +190,6 @@ static int wm8753_set_dai(struct snd_kcontrol *kcontrol, struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); u16 ioctl; - if (wm8753->dai_func == ucontrol->value.integer.value[0]) - return 0; - if (codec->active) return -EBUSY; diff --git a/trunk/sound/soc/codecs/wm8962.c b/trunk/sound/soc/codecs/wm8962.c index 53edd9a8c758..91d3c6dbeba3 100644 --- a/trunk/sound/soc/codecs/wm8962.c +++ b/trunk/sound/soc/codecs/wm8962.c @@ -1973,7 +1973,7 @@ static int wm8962_reset(struct snd_soc_codec *codec) static const DECLARE_TLV_DB_SCALE(inpga_tlv, -2325, 75, 0); static const DECLARE_TLV_DB_SCALE(mixin_tlv, -1500, 300, 0); static const unsigned int mixinpga_tlv[] = { - TLV_DB_RANGE_HEAD(5), + TLV_DB_RANGE_HEAD(7), 0, 1, TLV_DB_SCALE_ITEM(0, 600, 0), 2, 2, TLV_DB_SCALE_ITEM(1300, 1300, 0), 3, 4, TLV_DB_SCALE_ITEM(1800, 200, 0), @@ -1988,7 +1988,7 @@ static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0); static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1); static const DECLARE_TLV_DB_SCALE(hp_tlv, -700, 100, 0); static const unsigned int classd_tlv[] = { - TLV_DB_RANGE_HEAD(2), + TLV_DB_RANGE_HEAD(7), 0, 6, TLV_DB_SCALE_ITEM(0, 150, 0), 7, 7, TLV_DB_SCALE_ITEM(1200, 0, 0), }; diff --git a/trunk/sound/soc/codecs/wm8993.c b/trunk/sound/soc/codecs/wm8993.c index d1a142f48b09..eec8e1435116 100644 --- a/trunk/sound/soc/codecs/wm8993.c +++ b/trunk/sound/soc/codecs/wm8993.c @@ -512,7 +512,7 @@ static const DECLARE_TLV_DB_SCALE(drc_comp_threash, -4500, 75, 0); static const DECLARE_TLV_DB_SCALE(drc_comp_amp, -2250, 75, 0); static const DECLARE_TLV_DB_SCALE(drc_min_tlv, -1800, 600, 0); static const unsigned int drc_max_tlv[] = { - TLV_DB_RANGE_HEAD(2), + TLV_DB_RANGE_HEAD(4), 0, 2, TLV_DB_SCALE_ITEM(1200, 600, 0), 3, 3, TLV_DB_SCALE_ITEM(3600, 0, 0), }; diff --git a/trunk/sound/soc/codecs/wm8994.c b/trunk/sound/soc/codecs/wm8994.c index d0c545b73d78..9c982e47eb99 100644 --- a/trunk/sound/soc/codecs/wm8994.c +++ b/trunk/sound/soc/codecs/wm8994.c @@ -1325,15 +1325,15 @@ SND_SOC_DAPM_DAC("DAC1R", NULL, WM8994_POWER_MANAGEMENT_5, 0, 0), }; static const struct snd_soc_dapm_widget wm8994_adc_revd_widgets[] = { -SND_SOC_DAPM_VIRT_MUX_E("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux, - adc_mux_ev, SND_SOC_DAPM_PRE_PMU), -SND_SOC_DAPM_VIRT_MUX_E("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux, - adc_mux_ev, SND_SOC_DAPM_PRE_PMU), +SND_SOC_DAPM_MUX_E("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux, + adc_mux_ev, SND_SOC_DAPM_PRE_PMU), +SND_SOC_DAPM_MUX_E("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux, + adc_mux_ev, SND_SOC_DAPM_PRE_PMU), }; static const struct snd_soc_dapm_widget wm8994_adc_widgets[] = { -SND_SOC_DAPM_VIRT_MUX("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux), -SND_SOC_DAPM_VIRT_MUX("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux), +SND_SOC_DAPM_MUX("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux), +SND_SOC_DAPM_MUX("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux), }; static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = { @@ -2357,11 +2357,6 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream, bclk |= best << WM8994_AIF1_BCLK_DIV_SHIFT; lrclk = bclk_rate / params_rate(params); - if (!lrclk) { - dev_err(dai->dev, "Unable to generate LRCLK from %dHz BCLK\n", - bclk_rate); - return -EINVAL; - } dev_dbg(dai->dev, "Using LRCLK rate %d for actual LRCLK %dHz\n", lrclk, bclk_rate / lrclk); @@ -3183,8 +3178,6 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) switch (wm8994->revision) { case 0: case 1: - case 2: - case 3: wm8994->hubs.dcs_codes_l = -9; wm8994->hubs.dcs_codes_r = -5; break; diff --git a/trunk/sound/soc/codecs/wm9081.c b/trunk/sound/soc/codecs/wm9081.c index 4a398c3bfe84..3cd35a02c28c 100644 --- a/trunk/sound/soc/codecs/wm9081.c +++ b/trunk/sound/soc/codecs/wm9081.c @@ -807,6 +807,7 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec, mdelay(100); /* Normal bias enable & soft start off */ + reg |= WM9081_BIAS_ENA; reg &= ~WM9081_VMID_RAMP; snd_soc_write(codec, WM9081_VMID_CONTROL, reg); @@ -817,7 +818,7 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec, } /* VMID 2*240k */ - reg = snd_soc_read(codec, WM9081_VMID_CONTROL); + reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1); reg &= ~WM9081_VMID_SEL_MASK; reg |= 0x04; snd_soc_write(codec, WM9081_VMID_CONTROL, reg); @@ -829,15 +830,14 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec, break; case SND_SOC_BIAS_OFF: - /* Startup bias source and disable bias */ + /* Startup bias source */ reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1); reg |= WM9081_BIAS_SRC; - reg &= ~WM9081_BIAS_ENA; snd_soc_write(codec, WM9081_BIAS_CONTROL_1, reg); - /* Disable VMID with soft ramping */ + /* Disable VMID and biases with soft ramping */ reg = snd_soc_read(codec, WM9081_VMID_CONTROL); - reg &= ~WM9081_VMID_SEL_MASK; + reg &= ~(WM9081_VMID_SEL_MASK | WM9081_BIAS_ENA); reg |= WM9081_VMID_RAMP; snd_soc_write(codec, WM9081_VMID_CONTROL, reg); diff --git a/trunk/sound/soc/codecs/wm9090.c b/trunk/sound/soc/codecs/wm9090.c index f94c06057c64..2b5252c9e377 100644 --- a/trunk/sound/soc/codecs/wm9090.c +++ b/trunk/sound/soc/codecs/wm9090.c @@ -177,19 +177,19 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec) } static const unsigned int in_tlv[] = { - TLV_DB_RANGE_HEAD(3), + TLV_DB_RANGE_HEAD(6), 0, 0, TLV_DB_SCALE_ITEM(-600, 0, 0), 1, 3, TLV_DB_SCALE_ITEM(-350, 350, 0), 4, 6, TLV_DB_SCALE_ITEM(600, 600, 0), }; static const unsigned int mix_tlv[] = { - TLV_DB_RANGE_HEAD(2), + TLV_DB_RANGE_HEAD(4), 0, 2, TLV_DB_SCALE_ITEM(-1200, 300, 0), 3, 3, TLV_DB_SCALE_ITEM(0, 0, 0), }; static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0); static const unsigned int spkboost_tlv[] = { - TLV_DB_RANGE_HEAD(2), + TLV_DB_RANGE_HEAD(7), 0, 6, TLV_DB_SCALE_ITEM(0, 150, 0), 7, 7, TLV_DB_SCALE_ITEM(1200, 0, 0), }; diff --git a/trunk/sound/soc/codecs/wm_hubs.c b/trunk/sound/soc/codecs/wm_hubs.c index 48e61e912400..84f33d4ea2cd 100644 --- a/trunk/sound/soc/codecs/wm_hubs.c +++ b/trunk/sound/soc/codecs/wm_hubs.c @@ -40,7 +40,7 @@ static const DECLARE_TLV_DB_SCALE(outmix_tlv, -2100, 300, 0); static const DECLARE_TLV_DB_SCALE(spkmixout_tlv, -1800, 600, 1); static const DECLARE_TLV_DB_SCALE(outpga_tlv, -5700, 100, 0); static const unsigned int spkboost_tlv[] = { - TLV_DB_RANGE_HEAD(2), + TLV_DB_RANGE_HEAD(7), 0, 6, TLV_DB_SCALE_ITEM(0, 150, 0), 7, 7, TLV_DB_SCALE_ITEM(1200, 0, 0), }; diff --git a/trunk/sound/soc/fsl/fsl_ssi.c b/trunk/sound/soc/fsl/fsl_ssi.c index 83c4bd5b2dd7..0268cf989736 100644 --- a/trunk/sound/soc/fsl/fsl_ssi.c +++ b/trunk/sound/soc/fsl/fsl_ssi.c @@ -694,7 +694,6 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev) /* Initialize the the device_attribute structure */ dev_attr = &ssi_private->dev_attr; - sysfs_attr_init(&dev_attr->attr); dev_attr->attr.name = "statistics"; dev_attr->attr.mode = S_IRUGO; dev_attr->show = fsl_sysfs_ssi_show; diff --git a/trunk/sound/soc/fsl/mpc8610_hpcd.c b/trunk/sound/soc/fsl/mpc8610_hpcd.c index ae49f1c78c6d..31af405bda84 100644 --- a/trunk/sound/soc/fsl/mpc8610_hpcd.c +++ b/trunk/sound/soc/fsl/mpc8610_hpcd.c @@ -392,8 +392,7 @@ static int mpc8610_hpcd_probe(struct platform_device *pdev) } if (strcasecmp(sprop, "i2s-slave") == 0) { - machine_data->dai_format = - SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM; + machine_data->dai_format = SND_SOC_DAIFMT_I2S; machine_data->codec_clk_direction = SND_SOC_CLOCK_OUT; machine_data->cpu_clk_direction = SND_SOC_CLOCK_IN; @@ -410,38 +409,31 @@ static int mpc8610_hpcd_probe(struct platform_device *pdev) } machine_data->clk_frequency = be32_to_cpup(iprop); } else if (strcasecmp(sprop, "i2s-master") == 0) { - machine_data->dai_format = - SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS; + machine_data->dai_format = SND_SOC_DAIFMT_I2S; machine_data->codec_clk_direction = SND_SOC_CLOCK_IN; machine_data->cpu_clk_direction = SND_SOC_CLOCK_OUT; } else if (strcasecmp(sprop, "lj-slave") == 0) { - machine_data->dai_format = - SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_CBM_CFM; + machine_data->dai_format = SND_SOC_DAIFMT_LEFT_J; machine_data->codec_clk_direction = SND_SOC_CLOCK_OUT; machine_data->cpu_clk_direction = SND_SOC_CLOCK_IN; } else if (strcasecmp(sprop, "lj-master") == 0) { - machine_data->dai_format = - SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_CBS_CFS; + machine_data->dai_format = SND_SOC_DAIFMT_LEFT_J; machine_data->codec_clk_direction = SND_SOC_CLOCK_IN; machine_data->cpu_clk_direction = SND_SOC_CLOCK_OUT; } else if (strcasecmp(sprop, "rj-slave") == 0) { - machine_data->dai_format = - SND_SOC_DAIFMT_RIGHT_J | SND_SOC_DAIFMT_CBM_CFM; + machine_data->dai_format = SND_SOC_DAIFMT_RIGHT_J; machine_data->codec_clk_direction = SND_SOC_CLOCK_OUT; machine_data->cpu_clk_direction = SND_SOC_CLOCK_IN; } else if (strcasecmp(sprop, "rj-master") == 0) { - machine_data->dai_format = - SND_SOC_DAIFMT_RIGHT_J | SND_SOC_DAIFMT_CBS_CFS; + machine_data->dai_format = SND_SOC_DAIFMT_RIGHT_J; machine_data->codec_clk_direction = SND_SOC_CLOCK_IN; machine_data->cpu_clk_direction = SND_SOC_CLOCK_OUT; } else if (strcasecmp(sprop, "ac97-slave") == 0) { - machine_data->dai_format = - SND_SOC_DAIFMT_AC97 | SND_SOC_DAIFMT_CBM_CFM; + machine_data->dai_format = SND_SOC_DAIFMT_AC97; machine_data->codec_clk_direction = SND_SOC_CLOCK_OUT; machine_data->cpu_clk_direction = SND_SOC_CLOCK_IN; } else if (strcasecmp(sprop, "ac97-master") == 0) { - machine_data->dai_format = - SND_SOC_DAIFMT_AC97 | SND_SOC_DAIFMT_CBS_CFS; + machine_data->dai_format = SND_SOC_DAIFMT_AC97; machine_data->codec_clk_direction = SND_SOC_CLOCK_IN; machine_data->cpu_clk_direction = SND_SOC_CLOCK_OUT; } else { diff --git a/trunk/sound/soc/imx/Kconfig b/trunk/sound/soc/imx/Kconfig index 738391757f2c..b133bfcc5848 100644 --- a/trunk/sound/soc/imx/Kconfig +++ b/trunk/sound/soc/imx/Kconfig @@ -28,7 +28,7 @@ config SND_MXC_SOC_WM1133_EV1 config SND_SOC_MX27VIS_AIC32X4 tristate "SoC audio support for Visstrim M10 boards" - depends on MACH_IMX27_VISSTRIM_M10 && I2C + depends on MACH_IMX27_VISSTRIM_M10 select SND_SOC_TLV320AIC32X4 select SND_MXC_SOC_MX2 help diff --git a/trunk/sound/soc/kirkwood/Kconfig b/trunk/sound/soc/kirkwood/Kconfig index c62d715235e2..8f49e165f4d1 100644 --- a/trunk/sound/soc/kirkwood/Kconfig +++ b/trunk/sound/soc/kirkwood/Kconfig @@ -12,7 +12,6 @@ config SND_KIRKWOOD_SOC_I2S config SND_KIRKWOOD_SOC_OPENRD tristate "SoC Audio support for Kirkwood Openrd Client" depends on SND_KIRKWOOD_SOC && (MACH_OPENRD_CLIENT || MACH_OPENRD_ULTIMATE) - depends on I2C select SND_KIRKWOOD_SOC_I2S select SND_SOC_CS42L51 help @@ -21,7 +20,7 @@ config SND_KIRKWOOD_SOC_OPENRD config SND_KIRKWOOD_SOC_T5325 tristate "SoC Audio support for HP t5325" - depends on SND_KIRKWOOD_SOC && MACH_T5325 && I2C + depends on SND_KIRKWOOD_SOC && MACH_T5325 select SND_KIRKWOOD_SOC_I2S select SND_SOC_ALC5623 help diff --git a/trunk/sound/soc/pxa/Kconfig b/trunk/sound/soc/pxa/Kconfig index a0f7d3cfa470..ffd2242e305f 100644 --- a/trunk/sound/soc/pxa/Kconfig +++ b/trunk/sound/soc/pxa/Kconfig @@ -151,7 +151,6 @@ config SND_SOC_ZYLONITE config SND_SOC_RAUMFELD tristate "SoC Audio support Raumfeld audio adapter" depends on SND_PXA2XX_SOC && (MACH_RAUMFELD_SPEAKER || MACH_RAUMFELD_CONNECTOR) - depends on I2C && SPI_MASTER select SND_PXA_SOC_SSP select SND_SOC_CS4270 select SND_SOC_AK4104 @@ -160,7 +159,7 @@ config SND_SOC_RAUMFELD config SND_PXA2XX_SOC_HX4700 tristate "SoC Audio support for HP iPAQ hx4700" - depends on SND_PXA2XX_SOC && MACH_H4700 && I2C + depends on SND_PXA2XX_SOC && MACH_H4700 select SND_PXA2XX_SOC_I2S select SND_SOC_AK4641 help diff --git a/trunk/sound/soc/samsung/smdk_wm8994.c b/trunk/sound/soc/samsung/smdk_wm8994.c index ad9ac42522e2..f75e43997d5b 100644 --- a/trunk/sound/soc/samsung/smdk_wm8994.c +++ b/trunk/sound/soc/samsung/smdk_wm8994.c @@ -9,7 +9,6 @@ #include "../codecs/wm8994.h" #include -#include /* * Default CFG switch settings to use this driver: diff --git a/trunk/sound/soc/samsung/speyside.c b/trunk/sound/soc/samsung/speyside.c index 4b8e35410eb1..85bf541a771d 100644 --- a/trunk/sound/soc/samsung/speyside.c +++ b/trunk/sound/soc/samsung/speyside.c @@ -191,7 +191,7 @@ static int speyside_late_probe(struct snd_soc_card *card) snd_soc_dapm_ignore_suspend(&card->dapm, "Headset Mic"); snd_soc_dapm_ignore_suspend(&card->dapm, "Main AMIC"); snd_soc_dapm_ignore_suspend(&card->dapm, "Main DMIC"); - snd_soc_dapm_ignore_suspend(&card->dapm, "Main Speaker"); + snd_soc_dapm_ignore_suspend(&card->dapm, "Speaker"); snd_soc_dapm_ignore_suspend(&card->dapm, "WM1250 Output"); snd_soc_dapm_ignore_suspend(&card->dapm, "WM1250 Input"); diff --git a/trunk/sound/soc/soc-core.c b/trunk/sound/soc/soc-core.c index a25fa63ce9a2..a5d3685a5d38 100644 --- a/trunk/sound/soc/soc-core.c +++ b/trunk/sound/soc/soc-core.c @@ -709,12 +709,6 @@ int snd_soc_resume(struct device *dev) struct snd_soc_card *card = dev_get_drvdata(dev); int i, ac97_control = 0; - /* If the initialization of this soc device failed, there is no codec - * associated with it. Just bail out in this case. - */ - if (list_empty(&card->codec_dev_list)) - return 0; - /* AC97 devices might have other drivers hanging off them so * need to resume immediately. Other drivers don't have that * problem and may take a substantial amount of time to resume diff --git a/trunk/sound/soc/soc-utils.c b/trunk/sound/soc/soc-utils.c index 4220bb0f2730..0c12b98484bd 100644 --- a/trunk/sound/soc/soc-utils.c +++ b/trunk/sound/soc/soc-utils.c @@ -58,36 +58,7 @@ int snd_soc_params_to_bclk(struct snd_pcm_hw_params *params) } EXPORT_SYMBOL_GPL(snd_soc_params_to_bclk); -static const struct snd_pcm_hardware dummy_dma_hardware = { - .formats = 0xffffffff, - .channels_min = 1, - .channels_max = UINT_MAX, - - /* Random values to keep userspace happy when checking constraints */ - .info = SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER, - .buffer_bytes_max = 128*1024, - .period_bytes_min = PAGE_SIZE, - .period_bytes_max = PAGE_SIZE*2, - .periods_min = 2, - .periods_max = 128, -}; - -static int dummy_dma_open(struct snd_pcm_substream *substream) -{ - snd_soc_set_runtime_hwparams(substream, &dummy_dma_hardware); - - return 0; -} - -static struct snd_pcm_ops dummy_dma_ops = { - .open = dummy_dma_open, - .ioctl = snd_pcm_lib_ioctl, -}; - -static struct snd_soc_platform_driver dummy_platform = { - .ops = &dummy_dma_ops, -}; +static struct snd_soc_platform_driver dummy_platform; static __devinit int snd_soc_dummy_probe(struct platform_device *pdev) { diff --git a/trunk/sound/usb/quirks-table.h b/trunk/sound/usb/quirks-table.h index 32d2a21f2e3b..b61945f3af9e 100644 --- a/trunk/sound/usb/quirks-table.h +++ b/trunk/sound/usb/quirks-table.h @@ -1632,37 +1632,6 @@ YAMAHA_DEVICE(0x7010, "UB99"), } } }, -{ - /* Roland GAIA SH-01 */ - USB_DEVICE(0x0582, 0x0111), - .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { - .vendor_name = "Roland", - .product_name = "GAIA", - .ifnum = QUIRK_ANY_INTERFACE, - .type = QUIRK_COMPOSITE, - .data = (const struct snd_usb_audio_quirk[]) { - { - .ifnum = 0, - .type = QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum = 1, - .type = QUIRK_AUDIO_STANDARD_INTERFACE - }, - { - .ifnum = 2, - .type = QUIRK_MIDI_FIXED_ENDPOINT, - .data = &(const struct snd_usb_midi_endpoint_info) { - .out_cables = 0x0003, - .in_cables = 0x0003 - } - }, - { - .ifnum = -1 - } - } - } -}, { USB_DEVICE(0x0582, 0x0113), .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) {