diff options
51 files changed, 661 insertions, 830 deletions
diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt index bda546928a42..c8c54544abc5 100644 --- a/Documentation/sound/alsa/HD-Audio-Models.txt +++ b/Documentation/sound/alsa/HD-Audio-Models.txt | |||
@@ -338,7 +338,6 @@ STAC92HD83* | |||
338 | mic-ref Reference board with power management for ports | 338 | mic-ref Reference board with power management for ports |
339 | dell-s14 Dell laptop | 339 | dell-s14 Dell laptop |
340 | dell-vostro-3500 Dell Vostro 3500 laptop | 340 | dell-vostro-3500 Dell Vostro 3500 laptop |
341 | hp HP laptops with (inverted) mute-LED | ||
342 | hp-dv7-4000 HP dv-7 4000 | 341 | hp-dv7-4000 HP dv-7 4000 |
343 | auto BIOS setup (default) | 342 | auto BIOS setup (default) |
344 | 343 | ||
diff --git a/Documentation/sound/alsa/soc/machine.txt b/Documentation/sound/alsa/soc/machine.txt index 3e2ec9cbf397..d50c14df3411 100644 --- a/Documentation/sound/alsa/soc/machine.txt +++ b/Documentation/sound/alsa/soc/machine.txt | |||
@@ -50,8 +50,7 @@ Machine DAI Configuration | |||
50 | The machine DAI configuration glues all the codec and CPU DAIs together. It can | 50 | The machine DAI configuration glues all the codec and CPU DAIs together. It can |
51 | also be used to set up the DAI system clock and for any machine related DAI | 51 | also be used to set up the DAI system clock and for any machine related DAI |
52 | initialisation e.g. the machine audio map can be connected to the codec audio | 52 | initialisation e.g. the machine audio map can be connected to the codec audio |
53 | map, unconnected codec pins can be set as such. Please see corgi.c, spitz.c | 53 | map, unconnected codec pins can be set as such. |
54 | for examples. | ||
55 | 54 | ||
56 | struct snd_soc_dai_link is used to set up each DAI in your machine. e.g. | 55 | struct snd_soc_dai_link is used to set up each DAI in your machine. e.g. |
57 | 56 | ||
@@ -83,8 +82,7 @@ Machine Power Map | |||
83 | The machine driver can optionally extend the codec power map and to become an | 82 | The machine driver can optionally extend the codec power map and to become an |
84 | audio power map of the audio subsystem. This allows for automatic power up/down | 83 | audio power map of the audio subsystem. This allows for automatic power up/down |
85 | of speaker/HP amplifiers, etc. Codec pins can be connected to the machines jack | 84 | of speaker/HP amplifiers, etc. Codec pins can be connected to the machines jack |
86 | sockets in the machine init function. See soc/pxa/spitz.c and dapm.txt for | 85 | sockets in the machine init function. |
87 | details. | ||
88 | 86 | ||
89 | 87 | ||
90 | Machine Controls | 88 | Machine Controls |
diff --git a/MAINTAINERS b/MAINTAINERS index c802e5fa2d11..fd7e441b5ea7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -5648,7 +5648,6 @@ F: drivers/media/video/*7146* | |||
5648 | F: include/media/*7146* | 5648 | F: include/media/*7146* |
5649 | 5649 | ||
5650 | SAMSUNG AUDIO (ASoC) DRIVERS | 5650 | SAMSUNG AUDIO (ASoC) DRIVERS |
5651 | M: Jassi Brar <jassisinghbrar@gmail.com> | ||
5652 | M: Sangbeom Kim <sbkim73@samsung.com> | 5651 | M: Sangbeom Kim <sbkim73@samsung.com> |
5653 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) | 5652 | L: alsa-devel@alsa-project.org (moderated for non-subscribers) |
5654 | S: Supported | 5653 | S: Supported |
diff --git a/drivers/firmware/sigma.c b/drivers/firmware/sigma.c index f10fc521951b..1eedb6f7fdab 100644 --- a/drivers/firmware/sigma.c +++ b/drivers/firmware/sigma.c | |||
@@ -14,13 +14,34 @@ | |||
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/sigma.h> | 15 | #include <linux/sigma.h> |
16 | 16 | ||
17 | /* Return: 0==OK, <0==error, =1 ==no more actions */ | 17 | static size_t sigma_action_size(struct sigma_action *sa) |
18 | { | ||
19 | size_t payload = 0; | ||
20 | |||
21 | switch (sa->instr) { | ||
22 | case SIGMA_ACTION_WRITEXBYTES: | ||
23 | case SIGMA_ACTION_WRITESINGLE: | ||
24 | case SIGMA_ACTION_WRITESAFELOAD: | ||
25 | payload = sigma_action_len(sa); | ||
26 | break; | ||
27 | default: | ||
28 | break; | ||
29 | } | ||
30 | |||
31 | payload = ALIGN(payload, 2); | ||
32 | |||
33 | return payload + sizeof(struct sigma_action); | ||
34 | } | ||
35 | |||
36 | /* | ||
37 | * Returns a negative error value in case of an error, 0 if processing of | ||
38 | * the firmware should be stopped after this action, 1 otherwise. | ||
39 | */ | ||
18 | static int | 40 | static int |
19 | process_sigma_action(struct i2c_client *client, struct sigma_firmware *ssfw) | 41 | process_sigma_action(struct i2c_client *client, struct sigma_action *sa) |
20 | { | 42 | { |
21 | struct sigma_action *sa = (void *)(ssfw->fw->data + ssfw->pos); | ||
22 | size_t len = sigma_action_len(sa); | 43 | size_t len = sigma_action_len(sa); |
23 | int ret = 0; | 44 | int ret; |
24 | 45 | ||
25 | pr_debug("%s: instr:%i addr:%#x len:%zu\n", __func__, | 46 | pr_debug("%s: instr:%i addr:%#x len:%zu\n", __func__, |
26 | sa->instr, sa->addr, len); | 47 | sa->instr, sa->addr, len); |
@@ -29,44 +50,50 @@ process_sigma_action(struct i2c_client *client, struct sigma_firmware *ssfw) | |||
29 | case SIGMA_ACTION_WRITEXBYTES: | 50 | case SIGMA_ACTION_WRITEXBYTES: |
30 | case SIGMA_ACTION_WRITESINGLE: | 51 | case SIGMA_ACTION_WRITESINGLE: |
31 | case SIGMA_ACTION_WRITESAFELOAD: | 52 | case SIGMA_ACTION_WRITESAFELOAD: |
32 | if (ssfw->fw->size < ssfw->pos + len) | ||
33 | return -EINVAL; | ||
34 | ret = i2c_master_send(client, (void *)&sa->addr, len); | 53 | ret = i2c_master_send(client, (void *)&sa->addr, len); |
35 | if (ret < 0) | 54 | if (ret < 0) |
36 | return -EINVAL; | 55 | return -EINVAL; |
37 | break; | 56 | break; |
38 | |||
39 | case SIGMA_ACTION_DELAY: | 57 | case SIGMA_ACTION_DELAY: |
40 | ret = 0; | ||
41 | udelay(len); | 58 | udelay(len); |
42 | len = 0; | 59 | len = 0; |
43 | break; | 60 | break; |
44 | |||
45 | case SIGMA_ACTION_END: | 61 | case SIGMA_ACTION_END: |
46 | return 1; | 62 | return 0; |
47 | |||
48 | default: | 63 | default: |
49 | return -EINVAL; | 64 | return -EINVAL; |
50 | } | 65 | } |
51 | 66 | ||
52 | /* when arrive here ret=0 or sent data */ | 67 | return 1; |
53 | ssfw->pos += sigma_action_size(sa, len); | ||
54 | return ssfw->pos == ssfw->fw->size; | ||
55 | } | 68 | } |
56 | 69 | ||
57 | static int | 70 | static int |
58 | process_sigma_actions(struct i2c_client *client, struct sigma_firmware *ssfw) | 71 | process_sigma_actions(struct i2c_client *client, struct sigma_firmware *ssfw) |
59 | { | 72 | { |
60 | pr_debug("%s: processing %p\n", __func__, ssfw); | 73 | struct sigma_action *sa; |
74 | size_t size; | ||
75 | int ret; | ||
76 | |||
77 | while (ssfw->pos + sizeof(*sa) <= ssfw->fw->size) { | ||
78 | sa = (struct sigma_action *)(ssfw->fw->data + ssfw->pos); | ||
79 | |||
80 | size = sigma_action_size(sa); | ||
81 | ssfw->pos += size; | ||
82 | if (ssfw->pos > ssfw->fw->size || size == 0) | ||
83 | break; | ||
84 | |||
85 | ret = process_sigma_action(client, sa); | ||
61 | 86 | ||
62 | while (1) { | ||
63 | int ret = process_sigma_action(client, ssfw); | ||
64 | pr_debug("%s: action returned %i\n", __func__, ret); | 87 | pr_debug("%s: action returned %i\n", __func__, ret); |
65 | if (ret == 1) | 88 | |
66 | return 0; | 89 | if (ret <= 0) |
67 | else if (ret) | ||
68 | return ret; | 90 | return ret; |
69 | } | 91 | } |
92 | |||
93 | if (ssfw->pos != ssfw->fw->size) | ||
94 | return -EINVAL; | ||
95 | |||
96 | return 0; | ||
70 | } | 97 | } |
71 | 98 | ||
72 | int process_sigma_firmware(struct i2c_client *client, const char *name) | 99 | int process_sigma_firmware(struct i2c_client *client, const char *name) |
@@ -89,16 +116,24 @@ int process_sigma_firmware(struct i2c_client *client, const char *name) | |||
89 | 116 | ||
90 | /* then verify the header */ | 117 | /* then verify the header */ |
91 | ret = -EINVAL; | 118 | ret = -EINVAL; |
92 | if (fw->size < sizeof(*ssfw_head)) | 119 | |
120 | /* | ||
121 | * Reject too small or unreasonable large files. The upper limit has been | ||
122 | * chosen a bit arbitrarily, but it should be enough for all practical | ||
123 | * purposes and having the limit makes it easier to avoid integer | ||
124 | * overflows later in the loading process. | ||
125 | */ | ||
126 | if (fw->size < sizeof(*ssfw_head) || fw->size >= 0x4000000) | ||
93 | goto done; | 127 | goto done; |
94 | 128 | ||
95 | ssfw_head = (void *)fw->data; | 129 | ssfw_head = (void *)fw->data; |
96 | if (memcmp(ssfw_head->magic, SIGMA_MAGIC, ARRAY_SIZE(ssfw_head->magic))) | 130 | if (memcmp(ssfw_head->magic, SIGMA_MAGIC, ARRAY_SIZE(ssfw_head->magic))) |
97 | goto done; | 131 | goto done; |
98 | 132 | ||
99 | crc = crc32(0, fw->data, fw->size); | 133 | crc = crc32(0, fw->data + sizeof(*ssfw_head), |
134 | fw->size - sizeof(*ssfw_head)); | ||
100 | pr_debug("%s: crc=%x\n", __func__, crc); | 135 | pr_debug("%s: crc=%x\n", __func__, crc); |
101 | if (crc != ssfw_head->crc) | 136 | if (crc != le32_to_cpu(ssfw_head->crc)) |
102 | goto done; | 137 | goto done; |
103 | 138 | ||
104 | ssfw.pos = sizeof(*ssfw_head); | 139 | ssfw.pos = sizeof(*ssfw_head); |
diff --git a/include/linux/sigma.h b/include/linux/sigma.h index e2accb3164d8..d0de882c0d96 100644 --- a/include/linux/sigma.h +++ b/include/linux/sigma.h | |||
@@ -24,7 +24,7 @@ struct sigma_firmware { | |||
24 | struct sigma_firmware_header { | 24 | struct sigma_firmware_header { |
25 | unsigned char magic[7]; | 25 | unsigned char magic[7]; |
26 | u8 version; | 26 | u8 version; |
27 | u32 crc; | 27 | __le32 crc; |
28 | }; | 28 | }; |
29 | 29 | ||
30 | enum { | 30 | enum { |
@@ -40,19 +40,14 @@ enum { | |||
40 | struct sigma_action { | 40 | struct sigma_action { |
41 | u8 instr; | 41 | u8 instr; |
42 | u8 len_hi; | 42 | u8 len_hi; |
43 | u16 len; | 43 | __le16 len; |
44 | u16 addr; | 44 | __be16 addr; |
45 | unsigned char payload[]; | 45 | unsigned char payload[]; |
46 | }; | 46 | }; |
47 | 47 | ||
48 | static inline u32 sigma_action_len(struct sigma_action *sa) | 48 | static inline u32 sigma_action_len(struct sigma_action *sa) |
49 | { | 49 | { |
50 | return (sa->len_hi << 16) | sa->len; | 50 | return (sa->len_hi << 16) | le16_to_cpu(sa->len); |
51 | } | ||
52 | |||
53 | static inline size_t sigma_action_size(struct sigma_action *sa, u32 payload_len) | ||
54 | { | ||
55 | return sizeof(*sa) + payload_len + (payload_len % 2); | ||
56 | } | 51 | } |
57 | 52 | ||
58 | extern int process_sigma_firmware(struct i2c_client *client, const char *name); | 53 | extern int process_sigma_firmware(struct i2c_client *client, const char *name); |
diff --git a/sound/pci/cs5535audio/cs5535audio_pcm.c b/sound/pci/cs5535audio/cs5535audio_pcm.c index e083122ca55a..dbf94b189e75 100644 --- a/sound/pci/cs5535audio/cs5535audio_pcm.c +++ b/sound/pci/cs5535audio/cs5535audio_pcm.c | |||
@@ -148,7 +148,7 @@ static int cs5535audio_build_dma_packets(struct cs5535audio *cs5535au, | |||
148 | struct cs5535audio_dma_desc *desc = | 148 | struct cs5535audio_dma_desc *desc = |
149 | &((struct cs5535audio_dma_desc *) dma->desc_buf.area)[i]; | 149 | &((struct cs5535audio_dma_desc *) dma->desc_buf.area)[i]; |
150 | desc->addr = cpu_to_le32(addr); | 150 | desc->addr = cpu_to_le32(addr); |
151 | desc->size = cpu_to_le32(period_bytes); | 151 | desc->size = cpu_to_le16(period_bytes); |
152 | desc->ctlreserved = cpu_to_le16(PRD_EOP); | 152 | desc->ctlreserved = cpu_to_le16(PRD_EOP); |
153 | desc_addr += sizeof(struct cs5535audio_dma_desc); | 153 | desc_addr += sizeof(struct cs5535audio_dma_desc); |
154 | addr += period_bytes; | 154 | addr += period_bytes; |
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index de3325e79087..4df72c0e8c37 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -3816,6 +3816,12 @@ static int get_empty_pcm_device(struct hda_bus *bus, int type) | |||
3816 | if (!test_and_set_bit(audio_idx[type][i], bus->pcm_dev_bits)) | 3816 | if (!test_and_set_bit(audio_idx[type][i], bus->pcm_dev_bits)) |
3817 | return audio_idx[type][i]; | 3817 | return audio_idx[type][i]; |
3818 | 3818 | ||
3819 | /* non-fixed slots starting from 10 */ | ||
3820 | for (i = 10; i < 32; i++) { | ||
3821 | if (!test_and_set_bit(i, bus->pcm_dev_bits)) | ||
3822 | return i; | ||
3823 | } | ||
3824 | |||
3819 | snd_printk(KERN_WARNING "Too many %s devices\n", | 3825 | snd_printk(KERN_WARNING "Too many %s devices\n", |
3820 | snd_hda_pcm_type_name[type]); | 3826 | snd_hda_pcm_type_name[type]); |
3821 | return -EAGAIN; | 3827 | return -EAGAIN; |
@@ -4012,9 +4018,9 @@ int snd_hda_check_board_codec_sid_config(struct hda_codec *codec, | |||
4012 | 4018 | ||
4013 | /* Search for codec ID */ | 4019 | /* Search for codec ID */ |
4014 | for (q = tbl; q->subvendor; q++) { | 4020 | for (q = tbl; q->subvendor; q++) { |
4015 | unsigned long vendorid = (q->subdevice) | (q->subvendor << 16); | 4021 | unsigned int mask = 0xffff0000 | q->subdevice_mask; |
4016 | 4022 | unsigned int id = (q->subdevice | (q->subvendor << 16)) & mask; | |
4017 | if (vendorid == codec->subsystem_id) | 4023 | if ((codec->subsystem_id & mask) == id) |
4018 | break; | 4024 | break; |
4019 | } | 4025 | } |
4020 | 4026 | ||
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 97aa65d1f1d1..e9f71dc0d464 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
@@ -547,9 +547,6 @@ enum { | |||
547 | /* max. codec address */ | 547 | /* max. codec address */ |
548 | #define HDA_MAX_CODEC_ADDRESS 0x0f | 548 | #define HDA_MAX_CODEC_ADDRESS 0x0f |
549 | 549 | ||
550 | /* max number of PCM devics per card */ | ||
551 | #define HDA_MAX_PCMS 10 | ||
552 | |||
553 | /* | 550 | /* |
554 | * generic arrays | 551 | * generic arrays |
555 | */ | 552 | */ |
diff --git a/sound/pci/hda/hda_eld.c b/sound/pci/hda/hda_eld.c index 7ae7578bdcc0..c1da422e085a 100644 --- a/sound/pci/hda/hda_eld.c +++ b/sound/pci/hda/hda_eld.c | |||
@@ -347,18 +347,28 @@ int snd_hdmi_get_eld(struct hdmi_eld *eld, | |||
347 | 347 | ||
348 | for (i = 0; i < size; i++) { | 348 | for (i = 0; i < size; i++) { |
349 | unsigned int val = hdmi_get_eld_data(codec, nid, i); | 349 | unsigned int val = hdmi_get_eld_data(codec, nid, i); |
350 | /* | ||
351 | * Graphics driver might be writing to ELD buffer right now. | ||
352 | * Just abort. The caller will repoll after a while. | ||
353 | */ | ||
350 | if (!(val & AC_ELDD_ELD_VALID)) { | 354 | if (!(val & AC_ELDD_ELD_VALID)) { |
351 | if (!i) { | ||
352 | snd_printd(KERN_INFO | ||
353 | "HDMI: invalid ELD data\n"); | ||
354 | ret = -EINVAL; | ||
355 | goto error; | ||
356 | } | ||
357 | snd_printd(KERN_INFO | 355 | snd_printd(KERN_INFO |
358 | "HDMI: invalid ELD data byte %d\n", i); | 356 | "HDMI: invalid ELD data byte %d\n", i); |
359 | val = 0; | 357 | ret = -EINVAL; |
360 | } else | 358 | goto error; |
361 | val &= AC_ELDD_ELD_DATA; | 359 | } |
360 | val &= AC_ELDD_ELD_DATA; | ||
361 | /* | ||
362 | * The first byte cannot be zero. This can happen on some DVI | ||
363 | * connections. Some Intel chips may also need some 250ms delay | ||
364 | * to return non-zero ELD data, even when the graphics driver | ||
365 | * correctly writes ELD content before setting ELD_valid bit. | ||
366 | */ | ||
367 | if (!val && !i) { | ||
368 | snd_printdd(KERN_INFO "HDMI: 0 ELD data\n"); | ||
369 | ret = -EINVAL; | ||
370 | goto error; | ||
371 | } | ||
362 | buf[i] = val; | 372 | buf[i] = val; |
363 | } | 373 | } |
364 | 374 | ||
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 096507d2ca9a..4045b0cc463e 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -407,6 +407,14 @@ struct azx_rb { | |||
407 | u32 res[AZX_MAX_CODECS]; /* last read value */ | 407 | u32 res[AZX_MAX_CODECS]; /* last read value */ |
408 | }; | 408 | }; |
409 | 409 | ||
410 | struct azx_pcm { | ||
411 | struct azx *chip; | ||
412 | struct snd_pcm *pcm; | ||
413 | struct hda_codec *codec; | ||
414 | struct hda_pcm_stream *hinfo[2]; | ||
415 | struct list_head list; | ||
416 | }; | ||
417 | |||
410 | struct azx { | 418 | struct azx { |
411 | struct snd_card *card; | 419 | struct snd_card *card; |
412 | struct pci_dev *pci; | 420 | struct pci_dev *pci; |
@@ -434,7 +442,7 @@ struct azx { | |||
434 | struct azx_dev *azx_dev; | 442 | struct azx_dev *azx_dev; |
435 | 443 | ||
436 | /* PCM */ | 444 | /* PCM */ |
437 | struct snd_pcm *pcm[HDA_MAX_PCMS]; | 445 | struct list_head pcm_list; /* azx_pcm list */ |
438 | 446 | ||
439 | /* HD codec */ | 447 | /* HD codec */ |
440 | unsigned short codec_mask; | 448 | unsigned short codec_mask; |
@@ -479,6 +487,7 @@ enum { | |||
479 | AZX_DRIVER_SCH, | 487 | AZX_DRIVER_SCH, |
480 | AZX_DRIVER_ATI, | 488 | AZX_DRIVER_ATI, |
481 | AZX_DRIVER_ATIHDMI, | 489 | AZX_DRIVER_ATIHDMI, |
490 | AZX_DRIVER_ATIHDMI_NS, | ||
482 | AZX_DRIVER_VIA, | 491 | AZX_DRIVER_VIA, |
483 | AZX_DRIVER_SIS, | 492 | AZX_DRIVER_SIS, |
484 | AZX_DRIVER_ULI, | 493 | AZX_DRIVER_ULI, |
@@ -525,6 +534,7 @@ static char *driver_short_names[] __devinitdata = { | |||
525 | [AZX_DRIVER_SCH] = "HDA Intel MID", | 534 | [AZX_DRIVER_SCH] = "HDA Intel MID", |
526 | [AZX_DRIVER_ATI] = "HDA ATI SB", | 535 | [AZX_DRIVER_ATI] = "HDA ATI SB", |
527 | [AZX_DRIVER_ATIHDMI] = "HDA ATI HDMI", | 536 | [AZX_DRIVER_ATIHDMI] = "HDA ATI HDMI", |
537 | [AZX_DRIVER_ATIHDMI_NS] = "HDA ATI HDMI", | ||
528 | [AZX_DRIVER_VIA] = "HDA VIA VT82xx", | 538 | [AZX_DRIVER_VIA] = "HDA VIA VT82xx", |
529 | [AZX_DRIVER_SIS] = "HDA SIS966", | 539 | [AZX_DRIVER_SIS] = "HDA SIS966", |
530 | [AZX_DRIVER_ULI] = "HDA ULI M5461", | 540 | [AZX_DRIVER_ULI] = "HDA ULI M5461", |
@@ -1143,16 +1153,6 @@ static void update_pci_byte(struct pci_dev *pci, unsigned int reg, | |||
1143 | 1153 | ||
1144 | static void azx_init_pci(struct azx *chip) | 1154 | static void azx_init_pci(struct azx *chip) |
1145 | { | 1155 | { |
1146 | /* force to non-snoop mode for a new VIA controller when BIOS is set */ | ||
1147 | if (chip->snoop && chip->driver_type == AZX_DRIVER_VIA) { | ||
1148 | u8 snoop; | ||
1149 | pci_read_config_byte(chip->pci, 0x42, &snoop); | ||
1150 | if (!(snoop & 0x80) && chip->pci->revision == 0x30) { | ||
1151 | chip->snoop = 0; | ||
1152 | snd_printdd(SFX "Force to non-snoop mode\n"); | ||
1153 | } | ||
1154 | } | ||
1155 | |||
1156 | /* Clear bits 0-2 of PCI register TCSEL (at offset 0x44) | 1156 | /* Clear bits 0-2 of PCI register TCSEL (at offset 0x44) |
1157 | * TCSEL == Traffic Class Select Register, which sets PCI express QOS | 1157 | * TCSEL == Traffic Class Select Register, which sets PCI express QOS |
1158 | * Ensuring these bits are 0 clears playback static on some HD Audio | 1158 | * Ensuring these bits are 0 clears playback static on some HD Audio |
@@ -1486,10 +1486,9 @@ static void azx_bus_reset(struct hda_bus *bus) | |||
1486 | azx_init_chip(chip, 1); | 1486 | azx_init_chip(chip, 1); |
1487 | #ifdef CONFIG_PM | 1487 | #ifdef CONFIG_PM |
1488 | if (chip->initialized) { | 1488 | if (chip->initialized) { |
1489 | int i; | 1489 | struct azx_pcm *p; |
1490 | 1490 | list_for_each_entry(p, &chip->pcm_list, list) | |
1491 | for (i = 0; i < HDA_MAX_PCMS; i++) | 1491 | snd_pcm_suspend_all(p->pcm); |
1492 | snd_pcm_suspend_all(chip->pcm[i]); | ||
1493 | snd_hda_suspend(chip->bus); | 1492 | snd_hda_suspend(chip->bus); |
1494 | snd_hda_resume(chip->bus); | 1493 | snd_hda_resume(chip->bus); |
1495 | } | 1494 | } |
@@ -1667,12 +1666,6 @@ static struct snd_pcm_hardware azx_pcm_hw = { | |||
1667 | .fifo_size = 0, | 1666 | .fifo_size = 0, |
1668 | }; | 1667 | }; |
1669 | 1668 | ||
1670 | struct azx_pcm { | ||
1671 | struct azx *chip; | ||
1672 | struct hda_codec *codec; | ||
1673 | struct hda_pcm_stream *hinfo[2]; | ||
1674 | }; | ||
1675 | |||
1676 | static int azx_pcm_open(struct snd_pcm_substream *substream) | 1669 | static int azx_pcm_open(struct snd_pcm_substream *substream) |
1677 | { | 1670 | { |
1678 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); | 1671 | struct azx_pcm *apcm = snd_pcm_substream_chip(substream); |
@@ -2197,7 +2190,7 @@ static void azx_pcm_free(struct snd_pcm *pcm) | |||
2197 | { | 2190 | { |
2198 | struct azx_pcm *apcm = pcm->private_data; | 2191 | struct azx_pcm *apcm = pcm->private_data; |
2199 | if (apcm) { | 2192 | if (apcm) { |
2200 | apcm->chip->pcm[pcm->device] = NULL; | 2193 | list_del(&apcm->list); |
2201 | kfree(apcm); | 2194 | kfree(apcm); |
2202 | } | 2195 | } |
2203 | } | 2196 | } |
@@ -2215,14 +2208,11 @@ azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec, | |||
2215 | unsigned int size; | 2208 | unsigned int size; |
2216 | int s, err; | 2209 | int s, err; |
2217 | 2210 | ||
2218 | if (pcm_dev >= HDA_MAX_PCMS) { | 2211 | list_for_each_entry(apcm, &chip->pcm_list, list) { |
2219 | snd_printk(KERN_ERR SFX "Invalid PCM device number %d\n", | 2212 | if (apcm->pcm->device == pcm_dev) { |
2220 | pcm_dev); | 2213 | snd_printk(KERN_ERR SFX "PCM %d already exists\n", pcm_dev); |
2221 | return -EINVAL; | 2214 | return -EBUSY; |
2222 | } | 2215 | } |
2223 | if (chip->pcm[pcm_dev]) { | ||
2224 | snd_printk(KERN_ERR SFX "PCM %d already exists\n", pcm_dev); | ||
2225 | return -EBUSY; | ||
2226 | } | 2216 | } |
2227 | err = snd_pcm_new(chip->card, cpcm->name, pcm_dev, | 2217 | err = snd_pcm_new(chip->card, cpcm->name, pcm_dev, |
2228 | cpcm->stream[SNDRV_PCM_STREAM_PLAYBACK].substreams, | 2218 | cpcm->stream[SNDRV_PCM_STREAM_PLAYBACK].substreams, |
@@ -2235,12 +2225,13 @@ azx_attach_pcm_stream(struct hda_bus *bus, struct hda_codec *codec, | |||
2235 | if (apcm == NULL) | 2225 | if (apcm == NULL) |
2236 | return -ENOMEM; | 2226 | return -ENOMEM; |
2237 | apcm->chip = chip; | 2227 | apcm->chip = chip; |
2228 | apcm->pcm = pcm; | ||
2238 | apcm->codec = codec; | 2229 | apcm->codec = codec; |
2239 | pcm->private_data = apcm; | 2230 | pcm->private_data = apcm; |
2240 | pcm->private_free = azx_pcm_free; | 2231 | pcm->private_free = azx_pcm_free; |
2241 | if (cpcm->pcm_type == HDA_PCM_TYPE_MODEM) | 2232 | if (cpcm->pcm_type == HDA_PCM_TYPE_MODEM) |
2242 | pcm->dev_class = SNDRV_PCM_CLASS_MODEM; | 2233 | pcm->dev_class = SNDRV_PCM_CLASS_MODEM; |
2243 | chip->pcm[pcm_dev] = pcm; | 2234 | list_add_tail(&apcm->list, &chip->pcm_list); |
2244 | cpcm->pcm = pcm; | 2235 | cpcm->pcm = pcm; |
2245 | for (s = 0; s < 2; s++) { | 2236 | for (s = 0; s < 2; s++) { |
2246 | apcm->hinfo[s] = &cpcm->stream[s]; | 2237 | apcm->hinfo[s] = &cpcm->stream[s]; |
@@ -2370,12 +2361,12 @@ static int azx_suspend(struct pci_dev *pci, pm_message_t state) | |||
2370 | { | 2361 | { |
2371 | struct snd_card *card = pci_get_drvdata(pci); | 2362 | struct snd_card *card = pci_get_drvdata(pci); |
2372 | struct azx *chip = card->private_data; | 2363 | struct azx *chip = card->private_data; |
2373 | int i; | 2364 | struct azx_pcm *p; |
2374 | 2365 | ||
2375 | snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); | 2366 | snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); |
2376 | azx_clear_irq_pending(chip); | 2367 | azx_clear_irq_pending(chip); |
2377 | for (i = 0; i < HDA_MAX_PCMS; i++) | 2368 | list_for_each_entry(p, &chip->pcm_list, list) |
2378 | snd_pcm_suspend_all(chip->pcm[i]); | 2369 | snd_pcm_suspend_all(p->pcm); |
2379 | if (chip->initialized) | 2370 | if (chip->initialized) |
2380 | snd_hda_suspend(chip->bus); | 2371 | snd_hda_suspend(chip->bus); |
2381 | azx_stop_chip(chip); | 2372 | azx_stop_chip(chip); |
@@ -2507,8 +2498,8 @@ static struct snd_pci_quirk position_fix_list[] __devinitdata = { | |||
2507 | SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB), | 2498 | SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", POS_FIX_LPIB), |
2508 | SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB), | 2499 | SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS", POS_FIX_LPIB), |
2509 | SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS M2V", POS_FIX_LPIB), | 2500 | SND_PCI_QUIRK(0x1043, 0x81e7, "ASUS M2V", POS_FIX_LPIB), |
2501 | SND_PCI_QUIRK(0x1043, 0x83ce, "ASUS 1101HA", POS_FIX_LPIB), | ||
2510 | SND_PCI_QUIRK(0x104d, 0x9069, "Sony VPCS11V9E", POS_FIX_LPIB), | 2502 | SND_PCI_QUIRK(0x104d, 0x9069, "Sony VPCS11V9E", POS_FIX_LPIB), |
2511 | SND_PCI_QUIRK(0x1106, 0x3288, "ASUS M2V-MX SE", POS_FIX_LPIB), | ||
2512 | SND_PCI_QUIRK(0x1297, 0x3166, "Shuttle", POS_FIX_LPIB), | 2503 | SND_PCI_QUIRK(0x1297, 0x3166, "Shuttle", POS_FIX_LPIB), |
2513 | SND_PCI_QUIRK(0x1458, 0xa022, "ga-ma770-ud3", POS_FIX_LPIB), | 2504 | SND_PCI_QUIRK(0x1458, 0xa022, "ga-ma770-ud3", POS_FIX_LPIB), |
2514 | SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB), | 2505 | SND_PCI_QUIRK(0x1462, 0x1002, "MSI Wind U115", POS_FIX_LPIB), |
@@ -2634,6 +2625,35 @@ static void __devinit check_msi(struct azx *chip) | |||
2634 | } | 2625 | } |
2635 | } | 2626 | } |
2636 | 2627 | ||
2628 | /* check the snoop mode availability */ | ||
2629 | static void __devinit azx_check_snoop_available(struct azx *chip) | ||
2630 | { | ||
2631 | bool snoop = chip->snoop; | ||
2632 | |||
2633 | switch (chip->driver_type) { | ||
2634 | case AZX_DRIVER_VIA: | ||
2635 | /* force to non-snoop mode for a new VIA controller | ||
2636 | * when BIOS is set | ||
2637 | */ | ||
2638 | if (snoop) { | ||
2639 | u8 val; | ||
2640 | pci_read_config_byte(chip->pci, 0x42, &val); | ||
2641 | if (!(val & 0x80) && chip->pci->revision == 0x30) | ||
2642 | snoop = false; | ||
2643 | } | ||
2644 | break; | ||
2645 | case AZX_DRIVER_ATIHDMI_NS: | ||
2646 | /* new ATI HDMI requires non-snoop */ | ||
2647 | snoop = false; | ||
2648 | break; | ||
2649 | } | ||
2650 | |||
2651 | if (snoop != chip->snoop) { | ||
2652 | snd_printk(KERN_INFO SFX "Force to %s mode\n", | ||
2653 | snoop ? "snoop" : "non-snoop"); | ||
2654 | chip->snoop = snoop; | ||
2655 | } | ||
2656 | } | ||
2637 | 2657 | ||
2638 | /* | 2658 | /* |
2639 | * constructor | 2659 | * constructor |
@@ -2672,6 +2692,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
2672 | check_msi(chip); | 2692 | check_msi(chip); |
2673 | chip->dev_index = dev; | 2693 | chip->dev_index = dev; |
2674 | INIT_WORK(&chip->irq_pending_work, azx_irq_pending_work); | 2694 | INIT_WORK(&chip->irq_pending_work, azx_irq_pending_work); |
2695 | INIT_LIST_HEAD(&chip->pcm_list); | ||
2675 | 2696 | ||
2676 | chip->position_fix[0] = chip->position_fix[1] = | 2697 | chip->position_fix[0] = chip->position_fix[1] = |
2677 | check_position_fix(chip, position_fix[dev]); | 2698 | check_position_fix(chip, position_fix[dev]); |
@@ -2679,6 +2700,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
2679 | 2700 | ||
2680 | chip->single_cmd = single_cmd; | 2701 | chip->single_cmd = single_cmd; |
2681 | chip->snoop = hda_snoop; | 2702 | chip->snoop = hda_snoop; |
2703 | azx_check_snoop_available(chip); | ||
2682 | 2704 | ||
2683 | if (bdl_pos_adj[dev] < 0) { | 2705 | if (bdl_pos_adj[dev] < 0) { |
2684 | switch (chip->driver_type) { | 2706 | switch (chip->driver_type) { |
@@ -2777,6 +2799,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
2777 | chip->capture_streams = ULI_NUM_CAPTURE; | 2799 | chip->capture_streams = ULI_NUM_CAPTURE; |
2778 | break; | 2800 | break; |
2779 | case AZX_DRIVER_ATIHDMI: | 2801 | case AZX_DRIVER_ATIHDMI: |
2802 | case AZX_DRIVER_ATIHDMI_NS: | ||
2780 | chip->playback_streams = ATIHDMI_NUM_PLAYBACK; | 2803 | chip->playback_streams = ATIHDMI_NUM_PLAYBACK; |
2781 | chip->capture_streams = ATIHDMI_NUM_CAPTURE; | 2804 | chip->capture_streams = ATIHDMI_NUM_CAPTURE; |
2782 | break; | 2805 | break; |
@@ -2971,7 +2994,8 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { | |||
2971 | /* SCH */ | 2994 | /* SCH */ |
2972 | { PCI_DEVICE(0x8086, 0x811b), | 2995 | { PCI_DEVICE(0x8086, 0x811b), |
2973 | .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | | 2996 | .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | |
2974 | AZX_DCAPS_BUFSIZE}, | 2997 | AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_LPIB }, /* Poulsbo */ |
2998 | /* ICH */ | ||
2975 | { PCI_DEVICE(0x8086, 0x2668), | 2999 | { PCI_DEVICE(0x8086, 0x2668), |
2976 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC | | 3000 | .driver_data = AZX_DRIVER_ICH | AZX_DCAPS_OLD_SSYNC | |
2977 | AZX_DCAPS_BUFSIZE }, /* ICH6 */ | 3001 | AZX_DCAPS_BUFSIZE }, /* ICH6 */ |
@@ -3038,6 +3062,14 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { | |||
3038 | .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI }, | 3062 | .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI }, |
3039 | { PCI_DEVICE(0x1002, 0xaa48), | 3063 | { PCI_DEVICE(0x1002, 0xaa48), |
3040 | .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI }, | 3064 | .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI }, |
3065 | { PCI_DEVICE(0x1002, 0x9902), | ||
3066 | .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI }, | ||
3067 | { PCI_DEVICE(0x1002, 0xaaa0), | ||
3068 | .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI }, | ||
3069 | { PCI_DEVICE(0x1002, 0xaaa8), | ||
3070 | .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI }, | ||
3071 | { PCI_DEVICE(0x1002, 0xaab0), | ||
3072 | .driver_data = AZX_DRIVER_ATIHDMI_NS | AZX_DCAPS_PRESET_ATI_HDMI }, | ||
3041 | /* VIA VT8251/VT8237A */ | 3073 | /* VIA VT8251/VT8237A */ |
3042 | { PCI_DEVICE(0x1106, 0x3288), | 3074 | { PCI_DEVICE(0x1106, 0x3288), |
3043 | .driver_data = AZX_DRIVER_VIA | AZX_DCAPS_POSFIX_VIA }, | 3075 | .driver_data = AZX_DRIVER_VIA | AZX_DCAPS_POSFIX_VIA }, |
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index 0ba03878c5e0..acfb64534bf0 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c | |||
@@ -59,6 +59,8 @@ struct cs_spec { | |||
59 | unsigned int gpio_mask; | 59 | unsigned int gpio_mask; |
60 | unsigned int gpio_dir; | 60 | unsigned int gpio_dir; |
61 | unsigned int gpio_data; | 61 | unsigned int gpio_data; |
62 | unsigned int gpio_eapd_hp; /* EAPD GPIO bit for headphones */ | ||
63 | unsigned int gpio_eapd_speaker; /* EAPD GPIO bit for speakers */ | ||
62 | 64 | ||
63 | struct hda_pcm pcm_rec[2]; /* PCM information */ | 65 | struct hda_pcm pcm_rec[2]; /* PCM information */ |
64 | 66 | ||
@@ -77,6 +79,7 @@ enum { | |||
77 | CS420X_MBP53, | 79 | CS420X_MBP53, |
78 | CS420X_MBP55, | 80 | CS420X_MBP55, |
79 | CS420X_IMAC27, | 81 | CS420X_IMAC27, |
82 | CS420X_APPLE, | ||
80 | CS420X_AUTO, | 83 | CS420X_AUTO, |
81 | CS420X_MODELS | 84 | CS420X_MODELS |
82 | }; | 85 | }; |
@@ -238,6 +241,15 @@ static int cs_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
238 | return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout); | 241 | return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout); |
239 | } | 242 | } |
240 | 243 | ||
244 | static void cs_update_input_select(struct hda_codec *codec) | ||
245 | { | ||
246 | struct cs_spec *spec = codec->spec; | ||
247 | if (spec->cur_adc) | ||
248 | snd_hda_codec_write(codec, spec->cur_adc, 0, | ||
249 | AC_VERB_SET_CONNECT_SEL, | ||
250 | spec->adc_idx[spec->cur_input]); | ||
251 | } | ||
252 | |||
241 | /* | 253 | /* |
242 | * Analog capture | 254 | * Analog capture |
243 | */ | 255 | */ |
@@ -251,6 +263,7 @@ static int cs_capture_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
251 | spec->cur_adc = spec->adc_nid[spec->cur_input]; | 263 | spec->cur_adc = spec->adc_nid[spec->cur_input]; |
252 | spec->cur_adc_stream_tag = stream_tag; | 264 | spec->cur_adc_stream_tag = stream_tag; |
253 | spec->cur_adc_format = format; | 265 | spec->cur_adc_format = format; |
266 | cs_update_input_select(codec); | ||
254 | snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format); | 267 | snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format); |
255 | return 0; | 268 | return 0; |
256 | } | 269 | } |
@@ -690,10 +703,8 @@ static int change_cur_input(struct hda_codec *codec, unsigned int idx, | |||
690 | spec->cur_adc_stream_tag, 0, | 703 | spec->cur_adc_stream_tag, 0, |
691 | spec->cur_adc_format); | 704 | spec->cur_adc_format); |
692 | } | 705 | } |
693 | snd_hda_codec_write(codec, spec->cur_adc, 0, | ||
694 | AC_VERB_SET_CONNECT_SEL, | ||
695 | spec->adc_idx[idx]); | ||
696 | spec->cur_input = idx; | 706 | spec->cur_input = idx; |
707 | cs_update_input_select(codec); | ||
697 | return 1; | 708 | return 1; |
698 | } | 709 | } |
699 | 710 | ||
@@ -922,10 +933,9 @@ static void cs_automute(struct hda_codec *codec) | |||
922 | spdif_present ? 0 : PIN_OUT); | 933 | spdif_present ? 0 : PIN_OUT); |
923 | } | 934 | } |
924 | } | 935 | } |
925 | if (spec->board_config == CS420X_MBP53 || | 936 | if (spec->gpio_eapd_hp) { |
926 | spec->board_config == CS420X_MBP55 || | 937 | unsigned int gpio = hp_present ? |
927 | spec->board_config == CS420X_IMAC27) { | 938 | spec->gpio_eapd_hp : spec->gpio_eapd_speaker; |
928 | unsigned int gpio = hp_present ? 0x02 : 0x08; | ||
929 | snd_hda_codec_write(codec, 0x01, 0, | 939 | snd_hda_codec_write(codec, 0x01, 0, |
930 | AC_VERB_SET_GPIO_DATA, gpio); | 940 | AC_VERB_SET_GPIO_DATA, gpio); |
931 | } | 941 | } |
@@ -975,10 +985,7 @@ static void cs_automic(struct hda_codec *codec) | |||
975 | } else { | 985 | } else { |
976 | spec->cur_input = spec->last_input; | 986 | spec->cur_input = spec->last_input; |
977 | } | 987 | } |
978 | 988 | cs_update_input_select(codec); | |
979 | snd_hda_codec_write_cache(codec, spec->cur_adc, 0, | ||
980 | AC_VERB_SET_CONNECT_SEL, | ||
981 | spec->adc_idx[spec->cur_input]); | ||
982 | } else { | 989 | } else { |
983 | if (present) | 990 | if (present) |
984 | change_cur_input(codec, spec->automic_idx, 0); | 991 | change_cur_input(codec, spec->automic_idx, 0); |
@@ -1071,9 +1078,7 @@ static void init_input(struct hda_codec *codec) | |||
1071 | cs_automic(codec); | 1078 | cs_automic(codec); |
1072 | else { | 1079 | else { |
1073 | spec->cur_adc = spec->adc_nid[spec->cur_input]; | 1080 | spec->cur_adc = spec->adc_nid[spec->cur_input]; |
1074 | snd_hda_codec_write(codec, spec->cur_adc, 0, | 1081 | cs_update_input_select(codec); |
1075 | AC_VERB_SET_CONNECT_SEL, | ||
1076 | spec->adc_idx[spec->cur_input]); | ||
1077 | } | 1082 | } |
1078 | } else { | 1083 | } else { |
1079 | change_cur_input(codec, spec->cur_input, 1); | 1084 | change_cur_input(codec, spec->cur_input, 1); |
@@ -1283,6 +1288,7 @@ static const char * const cs420x_models[CS420X_MODELS] = { | |||
1283 | [CS420X_MBP53] = "mbp53", | 1288 | [CS420X_MBP53] = "mbp53", |
1284 | [CS420X_MBP55] = "mbp55", | 1289 | [CS420X_MBP55] = "mbp55", |
1285 | [CS420X_IMAC27] = "imac27", | 1290 | [CS420X_IMAC27] = "imac27", |
1291 | [CS420X_APPLE] = "apple", | ||
1286 | [CS420X_AUTO] = "auto", | 1292 | [CS420X_AUTO] = "auto", |
1287 | }; | 1293 | }; |
1288 | 1294 | ||
@@ -1292,7 +1298,13 @@ static const struct snd_pci_quirk cs420x_cfg_tbl[] = { | |||
1292 | SND_PCI_QUIRK(0x10de, 0x0d94, "MacBookAir 3,1(2)", CS420X_MBP55), | 1298 | SND_PCI_QUIRK(0x10de, 0x0d94, "MacBookAir 3,1(2)", CS420X_MBP55), |
1293 | SND_PCI_QUIRK(0x10de, 0xcb79, "MacBookPro 5,5", CS420X_MBP55), | 1299 | SND_PCI_QUIRK(0x10de, 0xcb79, "MacBookPro 5,5", CS420X_MBP55), |
1294 | SND_PCI_QUIRK(0x10de, 0xcb89, "MacBookPro 7,1", CS420X_MBP55), | 1300 | SND_PCI_QUIRK(0x10de, 0xcb89, "MacBookPro 7,1", CS420X_MBP55), |
1295 | SND_PCI_QUIRK(0x8086, 0x7270, "IMac 27 Inch", CS420X_IMAC27), | 1301 | /* this conflicts with too many other models */ |
1302 | /*SND_PCI_QUIRK(0x8086, 0x7270, "IMac 27 Inch", CS420X_IMAC27),*/ | ||
1303 | {} /* terminator */ | ||
1304 | }; | ||
1305 | |||
1306 | static const struct snd_pci_quirk cs420x_codec_cfg_tbl[] = { | ||
1307 | SND_PCI_QUIRK_VENDOR(0x106b, "Apple", CS420X_APPLE), | ||
1296 | {} /* terminator */ | 1308 | {} /* terminator */ |
1297 | }; | 1309 | }; |
1298 | 1310 | ||
@@ -1374,6 +1386,10 @@ static int patch_cs420x(struct hda_codec *codec) | |||
1374 | spec->board_config = | 1386 | spec->board_config = |
1375 | snd_hda_check_board_config(codec, CS420X_MODELS, | 1387 | snd_hda_check_board_config(codec, CS420X_MODELS, |
1376 | cs420x_models, cs420x_cfg_tbl); | 1388 | cs420x_models, cs420x_cfg_tbl); |
1389 | if (spec->board_config < 0) | ||
1390 | spec->board_config = | ||
1391 | snd_hda_check_board_codec_sid_config(codec, | ||
1392 | CS420X_MODELS, NULL, cs420x_codec_cfg_tbl); | ||
1377 | if (spec->board_config >= 0) | 1393 | if (spec->board_config >= 0) |
1378 | fix_pincfg(codec, spec->board_config, cs_pincfgs); | 1394 | fix_pincfg(codec, spec->board_config, cs_pincfgs); |
1379 | 1395 | ||
@@ -1381,10 +1397,11 @@ static int patch_cs420x(struct hda_codec *codec) | |||
1381 | case CS420X_IMAC27: | 1397 | case CS420X_IMAC27: |
1382 | case CS420X_MBP53: | 1398 | case CS420X_MBP53: |
1383 | case CS420X_MBP55: | 1399 | case CS420X_MBP55: |
1384 | /* GPIO1 = headphones */ | 1400 | case CS420X_APPLE: |
1385 | /* GPIO3 = speakers */ | 1401 | spec->gpio_eapd_hp = 2; /* GPIO1 = headphones */ |
1386 | spec->gpio_mask = 0x0a; | 1402 | spec->gpio_eapd_speaker = 8; /* GPIO3 = speakers */ |
1387 | spec->gpio_dir = 0x0a; | 1403 | spec->gpio_mask = spec->gpio_dir = |
1404 | spec->gpio_eapd_hp | spec->gpio_eapd_speaker; | ||
1388 | break; | 1405 | break; |
1389 | } | 1406 | } |
1390 | 1407 | ||
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 66dc7e651758..3f42cc965b46 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c | |||
@@ -49,8 +49,8 @@ MODULE_PARM_DESC(static_hdmi_pcm, "Don't restrict PCM parameters per ELD info"); | |||
49 | * | 49 | * |
50 | * The HDA correspondence of pipes/ports are converter/pin nodes. | 50 | * The HDA correspondence of pipes/ports are converter/pin nodes. |
51 | */ | 51 | */ |
52 | #define MAX_HDMI_CVTS 4 | 52 | #define MAX_HDMI_CVTS 8 |
53 | #define MAX_HDMI_PINS 4 | 53 | #define MAX_HDMI_PINS 8 |
54 | 54 | ||
55 | struct hdmi_spec_per_cvt { | 55 | struct hdmi_spec_per_cvt { |
56 | hda_nid_t cvt_nid; | 56 | hda_nid_t cvt_nid; |
@@ -70,6 +70,7 @@ struct hdmi_spec_per_pin { | |||
70 | struct hda_codec *codec; | 70 | struct hda_codec *codec; |
71 | struct hdmi_eld sink_eld; | 71 | struct hdmi_eld sink_eld; |
72 | struct delayed_work work; | 72 | struct delayed_work work; |
73 | int repoll_count; | ||
73 | }; | 74 | }; |
74 | 75 | ||
75 | struct hdmi_spec { | 76 | struct hdmi_spec { |
@@ -749,7 +750,7 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, int pin_idx, | |||
749 | * Unsolicited events | 750 | * Unsolicited events |
750 | */ | 751 | */ |
751 | 752 | ||
752 | static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, bool retry); | 753 | static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll); |
753 | 754 | ||
754 | static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) | 755 | static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) |
755 | { | 756 | { |
@@ -775,7 +776,7 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) | |||
775 | if (pin_idx < 0) | 776 | if (pin_idx < 0) |
776 | return; | 777 | return; |
777 | 778 | ||
778 | hdmi_present_sense(&spec->pins[pin_idx], true); | 779 | hdmi_present_sense(&spec->pins[pin_idx], 1); |
779 | snd_hda_jack_report_sync(codec); | 780 | snd_hda_jack_report_sync(codec); |
780 | } | 781 | } |
781 | 782 | ||
@@ -970,7 +971,7 @@ static int hdmi_read_pin_conn(struct hda_codec *codec, int pin_idx) | |||
970 | return 0; | 971 | return 0; |
971 | } | 972 | } |
972 | 973 | ||
973 | static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, bool retry) | 974 | static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll) |
974 | { | 975 | { |
975 | struct hda_codec *codec = per_pin->codec; | 976 | struct hda_codec *codec = per_pin->codec; |
976 | struct hdmi_eld *eld = &per_pin->sink_eld; | 977 | struct hdmi_eld *eld = &per_pin->sink_eld; |
@@ -999,7 +1000,7 @@ static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, bool retry) | |||
999 | if (eld_valid) { | 1000 | if (eld_valid) { |
1000 | if (!snd_hdmi_get_eld(eld, codec, pin_nid)) | 1001 | if (!snd_hdmi_get_eld(eld, codec, pin_nid)) |
1001 | snd_hdmi_show_eld(eld); | 1002 | snd_hdmi_show_eld(eld); |
1002 | else if (retry) { | 1003 | else if (repoll) { |
1003 | queue_delayed_work(codec->bus->workq, | 1004 | queue_delayed_work(codec->bus->workq, |
1004 | &per_pin->work, | 1005 | &per_pin->work, |
1005 | msecs_to_jiffies(300)); | 1006 | msecs_to_jiffies(300)); |
@@ -1012,7 +1013,10 @@ static void hdmi_repoll_eld(struct work_struct *work) | |||
1012 | struct hdmi_spec_per_pin *per_pin = | 1013 | struct hdmi_spec_per_pin *per_pin = |
1013 | container_of(to_delayed_work(work), struct hdmi_spec_per_pin, work); | 1014 | container_of(to_delayed_work(work), struct hdmi_spec_per_pin, work); |
1014 | 1015 | ||
1015 | hdmi_present_sense(per_pin, false); | 1016 | if (per_pin->repoll_count++ > 6) |
1017 | per_pin->repoll_count = 0; | ||
1018 | |||
1019 | hdmi_present_sense(per_pin, per_pin->repoll_count); | ||
1016 | } | 1020 | } |
1017 | 1021 | ||
1018 | static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid) | 1022 | static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid) |
@@ -1130,12 +1134,12 @@ static int hdmi_parse_codec(struct hda_codec *codec) | |||
1130 | 1134 | ||
1131 | /* | 1135 | /* |
1132 | */ | 1136 | */ |
1133 | static char *generic_hdmi_pcm_names[MAX_HDMI_PINS] = { | 1137 | static char *get_hdmi_pcm_name(int idx) |
1134 | "HDMI 0", | 1138 | { |
1135 | "HDMI 1", | 1139 | static char names[MAX_HDMI_PINS][8]; |
1136 | "HDMI 2", | 1140 | sprintf(&names[idx][0], "HDMI %d", idx); |
1137 | "HDMI 3", | 1141 | return &names[idx][0]; |
1138 | }; | 1142 | } |
1139 | 1143 | ||
1140 | /* | 1144 | /* |
1141 | * HDMI callbacks | 1145 | * HDMI callbacks |
@@ -1213,7 +1217,7 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec) | |||
1213 | struct hda_pcm_stream *pstr; | 1217 | struct hda_pcm_stream *pstr; |
1214 | 1218 | ||
1215 | info = &spec->pcm_rec[pin_idx]; | 1219 | info = &spec->pcm_rec[pin_idx]; |
1216 | info->name = generic_hdmi_pcm_names[pin_idx]; | 1220 | info->name = get_hdmi_pcm_name(pin_idx); |
1217 | info->pcm_type = HDA_PCM_TYPE_HDMI; | 1221 | info->pcm_type = HDA_PCM_TYPE_HDMI; |
1218 | 1222 | ||
1219 | pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK]; | 1223 | pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK]; |
@@ -1238,6 +1242,7 @@ static int generic_hdmi_build_jack(struct hda_codec *codec, int pin_idx) | |||
1238 | if (pcmdev > 0) | 1242 | if (pcmdev > 0) |
1239 | sprintf(hdmi_str + strlen(hdmi_str), ",pcm=%d", pcmdev); | 1243 | sprintf(hdmi_str + strlen(hdmi_str), ",pcm=%d", pcmdev); |
1240 | 1244 | ||
1245 | hdmi_present_sense(per_pin, 0); | ||
1241 | return snd_hda_jack_add_kctl(codec, per_pin->pin_nid, hdmi_str, 0); | 1246 | return snd_hda_jack_add_kctl(codec, per_pin->pin_nid, hdmi_str, 0); |
1242 | } | 1247 | } |
1243 | 1248 | ||
@@ -1362,7 +1367,7 @@ static int simple_playback_build_pcms(struct hda_codec *codec) | |||
1362 | chans = get_wcaps(codec, spec->cvts[i].cvt_nid); | 1367 | chans = get_wcaps(codec, spec->cvts[i].cvt_nid); |
1363 | chans = get_wcaps_channels(chans); | 1368 | chans = get_wcaps_channels(chans); |
1364 | 1369 | ||
1365 | info->name = generic_hdmi_pcm_names[i]; | 1370 | info->name = get_hdmi_pcm_name(i); |
1366 | info->pcm_type = HDA_PCM_TYPE_HDMI; | 1371 | info->pcm_type = HDA_PCM_TYPE_HDMI; |
1367 | pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK]; | 1372 | pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK]; |
1368 | snd_BUG_ON(!spec->pcm_playback); | 1373 | snd_BUG_ON(!spec->pcm_playback); |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 641c8295b643..d24adbd023ee 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -280,6 +280,12 @@ static bool alc_dyn_adc_pcm_resetup(struct hda_codec *codec, int cur) | |||
280 | return false; | 280 | return false; |
281 | } | 281 | } |
282 | 282 | ||
283 | static inline hda_nid_t get_capsrc(struct alc_spec *spec, int idx) | ||
284 | { | ||
285 | return spec->capsrc_nids ? | ||
286 | spec->capsrc_nids[idx] : spec->adc_nids[idx]; | ||
287 | } | ||
288 | |||
283 | static void call_update_outputs(struct hda_codec *codec); | 289 | static void call_update_outputs(struct hda_codec *codec); |
284 | 290 | ||
285 | /* select the given imux item; either unmute exclusively or select the route */ | 291 | /* select the given imux item; either unmute exclusively or select the route */ |
@@ -296,6 +302,8 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, | |||
296 | imux = &spec->input_mux[mux_idx]; | 302 | imux = &spec->input_mux[mux_idx]; |
297 | if (!imux->num_items && mux_idx > 0) | 303 | if (!imux->num_items && mux_idx > 0) |
298 | imux = &spec->input_mux[0]; | 304 | imux = &spec->input_mux[0]; |
305 | if (!imux->num_items) | ||
306 | return 0; | ||
299 | 307 | ||
300 | if (idx >= imux->num_items) | 308 | if (idx >= imux->num_items) |
301 | idx = imux->num_items - 1; | 309 | idx = imux->num_items - 1; |
@@ -321,8 +329,7 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, | |||
321 | adc_idx = spec->dyn_adc_idx[idx]; | 329 | adc_idx = spec->dyn_adc_idx[idx]; |
322 | } | 330 | } |
323 | 331 | ||
324 | nid = spec->capsrc_nids ? | 332 | nid = get_capsrc(spec, adc_idx); |
325 | spec->capsrc_nids[adc_idx] : spec->adc_nids[adc_idx]; | ||
326 | 333 | ||
327 | /* no selection? */ | 334 | /* no selection? */ |
328 | num_conns = snd_hda_get_conn_list(codec, nid, NULL); | 335 | num_conns = snd_hda_get_conn_list(codec, nid, NULL); |
@@ -1029,8 +1036,19 @@ static bool alc_rebuild_imux_for_auto_mic(struct hda_codec *codec) | |||
1029 | spec->imux_pins[2] = spec->dock_mic_pin; | 1036 | spec->imux_pins[2] = spec->dock_mic_pin; |
1030 | for (i = 0; i < 3; i++) { | 1037 | for (i = 0; i < 3; i++) { |
1031 | strcpy(imux->items[i].label, texts[i]); | 1038 | strcpy(imux->items[i].label, texts[i]); |
1032 | if (spec->imux_pins[i]) | 1039 | if (spec->imux_pins[i]) { |
1040 | hda_nid_t pin = spec->imux_pins[i]; | ||
1041 | int c; | ||
1042 | for (c = 0; c < spec->num_adc_nids; c++) { | ||
1043 | hda_nid_t cap = get_capsrc(spec, c); | ||
1044 | int idx = get_connection_index(codec, cap, pin); | ||
1045 | if (idx >= 0) { | ||
1046 | imux->items[i].index = idx; | ||
1047 | break; | ||
1048 | } | ||
1049 | } | ||
1033 | imux->num_items = i + 1; | 1050 | imux->num_items = i + 1; |
1051 | } | ||
1034 | } | 1052 | } |
1035 | spec->num_mux_defs = 1; | 1053 | spec->num_mux_defs = 1; |
1036 | spec->input_mux = imux; | 1054 | spec->input_mux = imux; |
@@ -1946,10 +1964,8 @@ static int alc_build_controls(struct hda_codec *codec) | |||
1946 | if (!kctl) | 1964 | if (!kctl) |
1947 | kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); | 1965 | kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); |
1948 | for (i = 0; kctl && i < kctl->count; i++) { | 1966 | for (i = 0; kctl && i < kctl->count; i++) { |
1949 | const hda_nid_t *nids = spec->capsrc_nids; | 1967 | err = snd_hda_add_nid(codec, kctl, i, |
1950 | if (!nids) | 1968 | get_capsrc(spec, i)); |
1951 | nids = spec->adc_nids; | ||
1952 | err = snd_hda_add_nid(codec, kctl, i, nids[i]); | ||
1953 | if (err < 0) | 1969 | if (err < 0) |
1954 | return err; | 1970 | return err; |
1955 | } | 1971 | } |
@@ -2609,6 +2625,8 @@ static const char *alc_get_line_out_pfx(struct alc_spec *spec, int ch, | |||
2609 | case AUTO_PIN_SPEAKER_OUT: | 2625 | case AUTO_PIN_SPEAKER_OUT: |
2610 | if (cfg->line_outs == 1) | 2626 | if (cfg->line_outs == 1) |
2611 | return "Speaker"; | 2627 | return "Speaker"; |
2628 | if (cfg->line_outs == 2) | ||
2629 | return ch ? "Bass Speaker" : "Speaker"; | ||
2612 | break; | 2630 | break; |
2613 | case AUTO_PIN_HP_OUT: | 2631 | case AUTO_PIN_HP_OUT: |
2614 | /* for multi-io case, only the primary out */ | 2632 | /* for multi-io case, only the primary out */ |
@@ -2746,8 +2764,7 @@ static int alc_auto_create_input_ctls(struct hda_codec *codec) | |||
2746 | } | 2764 | } |
2747 | 2765 | ||
2748 | for (c = 0; c < num_adcs; c++) { | 2766 | for (c = 0; c < num_adcs; c++) { |
2749 | hda_nid_t cap = spec->capsrc_nids ? | 2767 | hda_nid_t cap = get_capsrc(spec, c); |
2750 | spec->capsrc_nids[c] : spec->adc_nids[c]; | ||
2751 | idx = get_connection_index(codec, cap, pin); | 2768 | idx = get_connection_index(codec, cap, pin); |
2752 | if (idx >= 0) { | 2769 | if (idx >= 0) { |
2753 | spec->imux_pins[imux->num_items] = pin; | 2770 | spec->imux_pins[imux->num_items] = pin; |
@@ -2921,7 +2938,7 @@ static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin) | |||
2921 | if (!nid) | 2938 | if (!nid) |
2922 | continue; | 2939 | continue; |
2923 | if (found_in_nid_list(nid, spec->multiout.dac_nids, | 2940 | if (found_in_nid_list(nid, spec->multiout.dac_nids, |
2924 | spec->multiout.num_dacs)) | 2941 | ARRAY_SIZE(spec->private_dac_nids))) |
2925 | continue; | 2942 | continue; |
2926 | if (found_in_nid_list(nid, spec->multiout.hp_out_nid, | 2943 | if (found_in_nid_list(nid, spec->multiout.hp_out_nid, |
2927 | ARRAY_SIZE(spec->multiout.hp_out_nid))) | 2944 | ARRAY_SIZE(spec->multiout.hp_out_nid))) |
@@ -2959,6 +2976,7 @@ static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin) | |||
2959 | return 0; | 2976 | return 0; |
2960 | } | 2977 | } |
2961 | 2978 | ||
2979 | /* return 0 if no possible DAC is found, 1 if one or more found */ | ||
2962 | static int alc_auto_fill_extra_dacs(struct hda_codec *codec, int num_outs, | 2980 | static int alc_auto_fill_extra_dacs(struct hda_codec *codec, int num_outs, |
2963 | const hda_nid_t *pins, hda_nid_t *dacs) | 2981 | const hda_nid_t *pins, hda_nid_t *dacs) |
2964 | { | 2982 | { |
@@ -2976,17 +2994,19 @@ static int alc_auto_fill_extra_dacs(struct hda_codec *codec, int num_outs, | |||
2976 | if (!dacs[i]) | 2994 | if (!dacs[i]) |
2977 | dacs[i] = alc_auto_look_for_dac(codec, pins[i]); | 2995 | dacs[i] = alc_auto_look_for_dac(codec, pins[i]); |
2978 | } | 2996 | } |
2979 | return 0; | 2997 | return 1; |
2980 | } | 2998 | } |
2981 | 2999 | ||
2982 | static int alc_auto_fill_multi_ios(struct hda_codec *codec, | 3000 | static int alc_auto_fill_multi_ios(struct hda_codec *codec, |
2983 | unsigned int location, int offset); | 3001 | unsigned int location, int offset); |
3002 | static hda_nid_t alc_look_for_out_vol_nid(struct hda_codec *codec, | ||
3003 | hda_nid_t pin, hda_nid_t dac); | ||
2984 | 3004 | ||
2985 | /* fill in the dac_nids table from the parsed pin configuration */ | 3005 | /* fill in the dac_nids table from the parsed pin configuration */ |
2986 | static int alc_auto_fill_dac_nids(struct hda_codec *codec) | 3006 | static int alc_auto_fill_dac_nids(struct hda_codec *codec) |
2987 | { | 3007 | { |
2988 | struct alc_spec *spec = codec->spec; | 3008 | struct alc_spec *spec = codec->spec; |
2989 | const struct auto_pin_cfg *cfg = &spec->autocfg; | 3009 | struct auto_pin_cfg *cfg = &spec->autocfg; |
2990 | unsigned int location, defcfg; | 3010 | unsigned int location, defcfg; |
2991 | int num_pins; | 3011 | int num_pins; |
2992 | bool redone = false; | 3012 | bool redone = false; |
@@ -2999,6 +3019,7 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec) | |||
2999 | spec->multiout.extra_out_nid[0] = 0; | 3019 | spec->multiout.extra_out_nid[0] = 0; |
3000 | memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids)); | 3020 | memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids)); |
3001 | spec->multiout.dac_nids = spec->private_dac_nids; | 3021 | spec->multiout.dac_nids = spec->private_dac_nids; |
3022 | spec->multi_ios = 0; | ||
3002 | 3023 | ||
3003 | /* fill hard-wired DACs first */ | 3024 | /* fill hard-wired DACs first */ |
3004 | if (!redone) { | 3025 | if (!redone) { |
@@ -3032,10 +3053,12 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec) | |||
3032 | for (i = 0; i < cfg->line_outs; i++) { | 3053 | for (i = 0; i < cfg->line_outs; i++) { |
3033 | if (spec->private_dac_nids[i]) | 3054 | if (spec->private_dac_nids[i]) |
3034 | spec->multiout.num_dacs++; | 3055 | spec->multiout.num_dacs++; |
3035 | else | 3056 | else { |
3036 | memmove(spec->private_dac_nids + i, | 3057 | memmove(spec->private_dac_nids + i, |
3037 | spec->private_dac_nids + i + 1, | 3058 | spec->private_dac_nids + i + 1, |
3038 | sizeof(hda_nid_t) * (cfg->line_outs - i - 1)); | 3059 | sizeof(hda_nid_t) * (cfg->line_outs - i - 1)); |
3060 | spec->private_dac_nids[cfg->line_outs - 1] = 0; | ||
3061 | } | ||
3039 | } | 3062 | } |
3040 | 3063 | ||
3041 | if (cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { | 3064 | if (cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { |
@@ -3054,9 +3077,28 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec) | |||
3054 | if (cfg->line_out_type != AUTO_PIN_HP_OUT) | 3077 | if (cfg->line_out_type != AUTO_PIN_HP_OUT) |
3055 | alc_auto_fill_extra_dacs(codec, cfg->hp_outs, cfg->hp_pins, | 3078 | alc_auto_fill_extra_dacs(codec, cfg->hp_outs, cfg->hp_pins, |
3056 | spec->multiout.hp_out_nid); | 3079 | spec->multiout.hp_out_nid); |
3057 | if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) | 3080 | if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { |
3058 | alc_auto_fill_extra_dacs(codec, cfg->speaker_outs, cfg->speaker_pins, | 3081 | int err = alc_auto_fill_extra_dacs(codec, cfg->speaker_outs, |
3059 | spec->multiout.extra_out_nid); | 3082 | cfg->speaker_pins, |
3083 | spec->multiout.extra_out_nid); | ||
3084 | /* if no speaker volume is assigned, try again as the primary | ||
3085 | * output | ||
3086 | */ | ||
3087 | if (!err && cfg->speaker_outs > 0 && | ||
3088 | cfg->line_out_type == AUTO_PIN_HP_OUT) { | ||
3089 | cfg->hp_outs = cfg->line_outs; | ||
3090 | memcpy(cfg->hp_pins, cfg->line_out_pins, | ||
3091 | sizeof(cfg->hp_pins)); | ||
3092 | cfg->line_outs = cfg->speaker_outs; | ||
3093 | memcpy(cfg->line_out_pins, cfg->speaker_pins, | ||
3094 | sizeof(cfg->speaker_pins)); | ||
3095 | cfg->speaker_outs = 0; | ||
3096 | memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins)); | ||
3097 | cfg->line_out_type = AUTO_PIN_SPEAKER_OUT; | ||
3098 | redone = false; | ||
3099 | goto again; | ||
3100 | } | ||
3101 | } | ||
3060 | 3102 | ||
3061 | if (!spec->multi_ios && | 3103 | if (!spec->multi_ios && |
3062 | cfg->line_out_type == AUTO_PIN_SPEAKER_OUT && | 3104 | cfg->line_out_type == AUTO_PIN_SPEAKER_OUT && |
@@ -3073,6 +3115,10 @@ static int alc_auto_fill_dac_nids(struct hda_codec *codec) | |||
3073 | } | 3115 | } |
3074 | } | 3116 | } |
3075 | 3117 | ||
3118 | if (cfg->line_out_pins[0]) | ||
3119 | spec->vmaster_nid = | ||
3120 | alc_look_for_out_vol_nid(codec, cfg->line_out_pins[0], | ||
3121 | spec->multiout.dac_nids[0]); | ||
3076 | return 0; | 3122 | return 0; |
3077 | } | 3123 | } |
3078 | 3124 | ||
@@ -3234,7 +3280,8 @@ static int alc_auto_create_multi_out_ctls(struct hda_codec *codec, | |||
3234 | } | 3280 | } |
3235 | 3281 | ||
3236 | static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, | 3282 | static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, |
3237 | hda_nid_t dac, const char *pfx) | 3283 | hda_nid_t dac, const char *pfx, |
3284 | int cidx) | ||
3238 | { | 3285 | { |
3239 | struct alc_spec *spec = codec->spec; | 3286 | struct alc_spec *spec = codec->spec; |
3240 | hda_nid_t sw, vol; | 3287 | hda_nid_t sw, vol; |
@@ -3250,15 +3297,15 @@ static int alc_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, | |||
3250 | if (is_ctl_used(spec->sw_ctls, val)) | 3297 | if (is_ctl_used(spec->sw_ctls, val)) |
3251 | return 0; /* already created */ | 3298 | return 0; /* already created */ |
3252 | mark_ctl_usage(spec->sw_ctls, val); | 3299 | mark_ctl_usage(spec->sw_ctls, val); |
3253 | return add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, val); | 3300 | return __add_pb_sw_ctrl(spec, ALC_CTL_WIDGET_MUTE, pfx, cidx, val); |
3254 | } | 3301 | } |
3255 | 3302 | ||
3256 | sw = alc_look_for_out_mute_nid(codec, pin, dac); | 3303 | sw = alc_look_for_out_mute_nid(codec, pin, dac); |
3257 | vol = alc_look_for_out_vol_nid(codec, pin, dac); | 3304 | vol = alc_look_for_out_vol_nid(codec, pin, dac); |
3258 | err = alc_auto_add_stereo_vol(codec, pfx, 0, vol); | 3305 | err = alc_auto_add_stereo_vol(codec, pfx, cidx, vol); |
3259 | if (err < 0) | 3306 | if (err < 0) |
3260 | return err; | 3307 | return err; |
3261 | err = alc_auto_add_stereo_sw(codec, pfx, 0, sw); | 3308 | err = alc_auto_add_stereo_sw(codec, pfx, cidx, sw); |
3262 | if (err < 0) | 3309 | if (err < 0) |
3263 | return err; | 3310 | return err; |
3264 | return 0; | 3311 | return 0; |
@@ -3299,16 +3346,21 @@ static int alc_auto_create_extra_outs(struct hda_codec *codec, int num_pins, | |||
3299 | hda_nid_t dac = *dacs; | 3346 | hda_nid_t dac = *dacs; |
3300 | if (!dac) | 3347 | if (!dac) |
3301 | dac = spec->multiout.dac_nids[0]; | 3348 | dac = spec->multiout.dac_nids[0]; |
3302 | return alc_auto_create_extra_out(codec, *pins, dac, pfx); | 3349 | return alc_auto_create_extra_out(codec, *pins, dac, pfx, 0); |
3303 | } | 3350 | } |
3304 | 3351 | ||
3305 | if (dacs[num_pins - 1]) { | 3352 | if (dacs[num_pins - 1]) { |
3306 | /* OK, we have a multi-output system with individual volumes */ | 3353 | /* OK, we have a multi-output system with individual volumes */ |
3307 | for (i = 0; i < num_pins; i++) { | 3354 | for (i = 0; i < num_pins; i++) { |
3308 | snprintf(name, sizeof(name), "%s %s", | 3355 | if (num_pins >= 3) { |
3309 | pfx, channel_name[i]); | 3356 | snprintf(name, sizeof(name), "%s %s", |
3310 | err = alc_auto_create_extra_out(codec, pins[i], dacs[i], | 3357 | pfx, channel_name[i]); |
3311 | name); | 3358 | err = alc_auto_create_extra_out(codec, pins[i], dacs[i], |
3359 | name, 0); | ||
3360 | } else { | ||
3361 | err = alc_auto_create_extra_out(codec, pins[i], dacs[i], | ||
3362 | pfx, i); | ||
3363 | } | ||
3312 | if (err < 0) | 3364 | if (err < 0) |
3313 | return err; | 3365 | return err; |
3314 | } | 3366 | } |
@@ -3780,8 +3832,7 @@ static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin) | |||
3780 | if (!pin) | 3832 | if (!pin) |
3781 | return 0; | 3833 | return 0; |
3782 | for (i = 0; i < spec->num_adc_nids; i++) { | 3834 | for (i = 0; i < spec->num_adc_nids; i++) { |
3783 | hda_nid_t cap = spec->capsrc_nids ? | 3835 | hda_nid_t cap = get_capsrc(spec, i); |
3784 | spec->capsrc_nids[i] : spec->adc_nids[i]; | ||
3785 | int idx; | 3836 | int idx; |
3786 | 3837 | ||
3787 | idx = get_connection_index(codec, cap, pin); | 3838 | idx = get_connection_index(codec, cap, pin); |
@@ -4091,8 +4142,10 @@ static int patch_alc880(struct hda_codec *codec) | |||
4091 | #endif | 4142 | #endif |
4092 | } | 4143 | } |
4093 | 4144 | ||
4094 | if (board_config != ALC_MODEL_AUTO) | 4145 | if (board_config != ALC_MODEL_AUTO) { |
4146 | spec->vmaster_nid = 0x0c; | ||
4095 | setup_preset(codec, &alc880_presets[board_config]); | 4147 | setup_preset(codec, &alc880_presets[board_config]); |
4148 | } | ||
4096 | 4149 | ||
4097 | if (!spec->no_analog && !spec->adc_nids) { | 4150 | if (!spec->no_analog && !spec->adc_nids) { |
4098 | alc_auto_fill_adc_caps(codec); | 4151 | alc_auto_fill_adc_caps(codec); |
@@ -4112,8 +4165,6 @@ static int patch_alc880(struct hda_codec *codec) | |||
4112 | 4165 | ||
4113 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); | 4166 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); |
4114 | 4167 | ||
4115 | spec->vmaster_nid = 0x0c; | ||
4116 | |||
4117 | codec->patch_ops = alc_patch_ops; | 4168 | codec->patch_ops = alc_patch_ops; |
4118 | if (board_config == ALC_MODEL_AUTO) | 4169 | if (board_config == ALC_MODEL_AUTO) |
4119 | spec->init_hook = alc_auto_init_std; | 4170 | spec->init_hook = alc_auto_init_std; |
@@ -4220,8 +4271,10 @@ static int patch_alc260(struct hda_codec *codec) | |||
4220 | #endif | 4271 | #endif |
4221 | } | 4272 | } |
4222 | 4273 | ||
4223 | if (board_config != ALC_MODEL_AUTO) | 4274 | if (board_config != ALC_MODEL_AUTO) { |
4224 | setup_preset(codec, &alc260_presets[board_config]); | 4275 | setup_preset(codec, &alc260_presets[board_config]); |
4276 | spec->vmaster_nid = 0x08; | ||
4277 | } | ||
4225 | 4278 | ||
4226 | if (!spec->no_analog && !spec->adc_nids) { | 4279 | if (!spec->no_analog && !spec->adc_nids) { |
4227 | alc_auto_fill_adc_caps(codec); | 4280 | alc_auto_fill_adc_caps(codec); |
@@ -4241,8 +4294,6 @@ static int patch_alc260(struct hda_codec *codec) | |||
4241 | 4294 | ||
4242 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); | 4295 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); |
4243 | 4296 | ||
4244 | spec->vmaster_nid = 0x08; | ||
4245 | |||
4246 | codec->patch_ops = alc_patch_ops; | 4297 | codec->patch_ops = alc_patch_ops; |
4247 | if (board_config == ALC_MODEL_AUTO) | 4298 | if (board_config == ALC_MODEL_AUTO) |
4248 | spec->init_hook = alc_auto_init_std; | 4299 | spec->init_hook = alc_auto_init_std; |
@@ -4614,8 +4665,10 @@ static int patch_alc882(struct hda_codec *codec) | |||
4614 | goto error; | 4665 | goto error; |
4615 | } | 4666 | } |
4616 | 4667 | ||
4617 | if (board_config != ALC_MODEL_AUTO) | 4668 | if (board_config != ALC_MODEL_AUTO) { |
4618 | setup_preset(codec, &alc882_presets[board_config]); | 4669 | setup_preset(codec, &alc882_presets[board_config]); |
4670 | spec->vmaster_nid = 0x0c; | ||
4671 | } | ||
4619 | 4672 | ||
4620 | if (!spec->no_analog && !spec->adc_nids) { | 4673 | if (!spec->no_analog && !spec->adc_nids) { |
4621 | alc_auto_fill_adc_caps(codec); | 4674 | alc_auto_fill_adc_caps(codec); |
@@ -4635,8 +4688,6 @@ static int patch_alc882(struct hda_codec *codec) | |||
4635 | 4688 | ||
4636 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); | 4689 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); |
4637 | 4690 | ||
4638 | spec->vmaster_nid = 0x0c; | ||
4639 | |||
4640 | codec->patch_ops = alc_patch_ops; | 4691 | codec->patch_ops = alc_patch_ops; |
4641 | if (board_config == ALC_MODEL_AUTO) | 4692 | if (board_config == ALC_MODEL_AUTO) |
4642 | spec->init_hook = alc_auto_init_std; | 4693 | spec->init_hook = alc_auto_init_std; |
@@ -4814,8 +4865,6 @@ static int patch_alc262(struct hda_codec *codec) | |||
4814 | 4865 | ||
4815 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); | 4866 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); |
4816 | 4867 | ||
4817 | spec->vmaster_nid = 0x0c; | ||
4818 | |||
4819 | codec->patch_ops = alc_patch_ops; | 4868 | codec->patch_ops = alc_patch_ops; |
4820 | spec->init_hook = alc_auto_init_std; | 4869 | spec->init_hook = alc_auto_init_std; |
4821 | spec->shutup = alc_eapd_shutup; | 4870 | spec->shutup = alc_eapd_shutup; |
@@ -4926,8 +4975,6 @@ static int patch_alc268(struct hda_codec *codec) | |||
4926 | if (!spec->no_analog && !spec->cap_mixer) | 4975 | if (!spec->no_analog && !spec->cap_mixer) |
4927 | set_capture_mixer(codec); | 4976 | set_capture_mixer(codec); |
4928 | 4977 | ||
4929 | spec->vmaster_nid = 0x02; | ||
4930 | |||
4931 | codec->patch_ops = alc_patch_ops; | 4978 | codec->patch_ops = alc_patch_ops; |
4932 | spec->init_hook = alc_auto_init_std; | 4979 | spec->init_hook = alc_auto_init_std; |
4933 | spec->shutup = alc_eapd_shutup; | 4980 | spec->shutup = alc_eapd_shutup; |
@@ -5480,8 +5527,6 @@ static int patch_alc269(struct hda_codec *codec) | |||
5480 | 5527 | ||
5481 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); | 5528 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); |
5482 | 5529 | ||
5483 | spec->vmaster_nid = 0x02; | ||
5484 | |||
5485 | codec->patch_ops = alc_patch_ops; | 5530 | codec->patch_ops = alc_patch_ops; |
5486 | #ifdef CONFIG_PM | 5531 | #ifdef CONFIG_PM |
5487 | codec->patch_ops.resume = alc269_resume; | 5532 | codec->patch_ops.resume = alc269_resume; |
@@ -5585,8 +5630,6 @@ static int patch_alc861(struct hda_codec *codec) | |||
5585 | set_beep_amp(spec, 0x23, 0, HDA_OUTPUT); | 5630 | set_beep_amp(spec, 0x23, 0, HDA_OUTPUT); |
5586 | } | 5631 | } |
5587 | 5632 | ||
5588 | spec->vmaster_nid = 0x03; | ||
5589 | |||
5590 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); | 5633 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); |
5591 | 5634 | ||
5592 | codec->patch_ops = alc_patch_ops; | 5635 | codec->patch_ops = alc_patch_ops; |
@@ -5711,8 +5754,6 @@ static int patch_alc861vd(struct hda_codec *codec) | |||
5711 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); | 5754 | set_beep_amp(spec, 0x0b, 0x05, HDA_INPUT); |
5712 | } | 5755 | } |
5713 | 5756 | ||
5714 | spec->vmaster_nid = 0x02; | ||
5715 | |||
5716 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); | 5757 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); |
5717 | 5758 | ||
5718 | codec->patch_ops = alc_patch_ops; | 5759 | codec->patch_ops = alc_patch_ops; |
@@ -6095,7 +6136,6 @@ static int patch_alc662(struct hda_codec *codec) | |||
6095 | break; | 6136 | break; |
6096 | } | 6137 | } |
6097 | } | 6138 | } |
6098 | spec->vmaster_nid = 0x02; | ||
6099 | 6139 | ||
6100 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); | 6140 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); |
6101 | 6141 | ||
@@ -6149,8 +6189,6 @@ static int patch_alc680(struct hda_codec *codec) | |||
6149 | if (!spec->no_analog && !spec->cap_mixer) | 6189 | if (!spec->no_analog && !spec->cap_mixer) |
6150 | set_capture_mixer(codec); | 6190 | set_capture_mixer(codec); |
6151 | 6191 | ||
6152 | spec->vmaster_nid = 0x02; | ||
6153 | |||
6154 | codec->patch_ops = alc_patch_ops; | 6192 | codec->patch_ops = alc_patch_ops; |
6155 | spec->init_hook = alc_auto_init_std; | 6193 | spec->init_hook = alc_auto_init_std; |
6156 | 6194 | ||
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 2d4156c583c6..03145aec65f1 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -97,7 +97,6 @@ enum { | |||
97 | STAC_92HD83XXX_PWR_REF, | 97 | STAC_92HD83XXX_PWR_REF, |
98 | STAC_DELL_S14, | 98 | STAC_DELL_S14, |
99 | STAC_DELL_VOSTRO_3500, | 99 | STAC_DELL_VOSTRO_3500, |
100 | STAC_92HD83XXX_HP, | ||
101 | STAC_92HD83XXX_HP_cNB11_INTQUAD, | 100 | STAC_92HD83XXX_HP_cNB11_INTQUAD, |
102 | STAC_HP_DV7_4000, | 101 | STAC_HP_DV7_4000, |
103 | STAC_92HD83XXX_MODELS | 102 | STAC_92HD83XXX_MODELS |
@@ -209,6 +208,7 @@ struct sigmatel_spec { | |||
209 | unsigned int gpio_mute; | 208 | unsigned int gpio_mute; |
210 | unsigned int gpio_led; | 209 | unsigned int gpio_led; |
211 | unsigned int gpio_led_polarity; | 210 | unsigned int gpio_led_polarity; |
211 | unsigned int vref_mute_led_nid; /* pin NID for mute-LED vref control */ | ||
212 | unsigned int vref_led; | 212 | unsigned int vref_led; |
213 | 213 | ||
214 | /* stream */ | 214 | /* stream */ |
@@ -1607,6 +1607,8 @@ static const struct snd_pci_quirk stac92hd73xx_codec_id_cfg_tbl[] = { | |||
1607 | "Alienware M17x", STAC_ALIENWARE_M17X), | 1607 | "Alienware M17x", STAC_ALIENWARE_M17X), |
1608 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x043a, | 1608 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x043a, |
1609 | "Alienware M17x", STAC_ALIENWARE_M17X), | 1609 | "Alienware M17x", STAC_ALIENWARE_M17X), |
1610 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0490, | ||
1611 | "Alienware M17x", STAC_ALIENWARE_M17X), | ||
1610 | {} /* terminator */ | 1612 | {} /* terminator */ |
1611 | }; | 1613 | }; |
1612 | 1614 | ||
@@ -1655,7 +1657,6 @@ static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = { | |||
1655 | [STAC_92HD83XXX_PWR_REF] = "mic-ref", | 1657 | [STAC_92HD83XXX_PWR_REF] = "mic-ref", |
1656 | [STAC_DELL_S14] = "dell-s14", | 1658 | [STAC_DELL_S14] = "dell-s14", |
1657 | [STAC_DELL_VOSTRO_3500] = "dell-vostro-3500", | 1659 | [STAC_DELL_VOSTRO_3500] = "dell-vostro-3500", |
1658 | [STAC_92HD83XXX_HP] = "hp", | ||
1659 | [STAC_92HD83XXX_HP_cNB11_INTQUAD] = "hp_cNB11_intquad", | 1660 | [STAC_92HD83XXX_HP_cNB11_INTQUAD] = "hp_cNB11_intquad", |
1660 | [STAC_HP_DV7_4000] = "hp-dv7-4000", | 1661 | [STAC_HP_DV7_4000] = "hp-dv7-4000", |
1661 | }; | 1662 | }; |
@@ -1670,8 +1671,6 @@ static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { | |||
1670 | "unknown Dell", STAC_DELL_S14), | 1671 | "unknown Dell", STAC_DELL_S14), |
1671 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x1028, | 1672 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x1028, |
1672 | "Dell Vostro 3500", STAC_DELL_VOSTRO_3500), | 1673 | "Dell Vostro 3500", STAC_DELL_VOSTRO_3500), |
1673 | SND_PCI_QUIRK_MASK(PCI_VENDOR_ID_HP, 0xff00, 0x3600, | ||
1674 | "HP", STAC_92HD83XXX_HP), | ||
1675 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1656, | 1674 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1656, |
1676 | "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), | 1675 | "HP", STAC_92HD83XXX_HP_cNB11_INTQUAD), |
1677 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1657, | 1676 | SND_PCI_QUIRK(PCI_VENDOR_ID_HP, 0x1657, |
@@ -4230,12 +4229,10 @@ static void stac_store_hints(struct hda_codec *codec) | |||
4230 | spec->eapd_switch = val; | 4229 | spec->eapd_switch = val; |
4231 | get_int_hint(codec, "gpio_led_polarity", &spec->gpio_led_polarity); | 4230 | get_int_hint(codec, "gpio_led_polarity", &spec->gpio_led_polarity); |
4232 | if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) { | 4231 | if (get_int_hint(codec, "gpio_led", &spec->gpio_led)) { |
4233 | if (spec->gpio_led <= 8) { | 4232 | spec->gpio_mask |= spec->gpio_led; |
4234 | spec->gpio_mask |= spec->gpio_led; | 4233 | spec->gpio_dir |= spec->gpio_led; |
4235 | spec->gpio_dir |= spec->gpio_led; | 4234 | if (spec->gpio_led_polarity) |
4236 | if (spec->gpio_led_polarity) | 4235 | spec->gpio_data |= spec->gpio_led; |
4237 | spec->gpio_data |= spec->gpio_led; | ||
4238 | } | ||
4239 | } | 4236 | } |
4240 | } | 4237 | } |
4241 | 4238 | ||
@@ -4353,7 +4350,9 @@ static int stac92xx_init(struct hda_codec *codec) | |||
4353 | int pinctl, def_conf; | 4350 | int pinctl, def_conf; |
4354 | 4351 | ||
4355 | /* power on when no jack detection is available */ | 4352 | /* power on when no jack detection is available */ |
4356 | if (!spec->hp_detect) { | 4353 | /* or when the VREF is used for controlling LED */ |
4354 | if (!spec->hp_detect || | ||
4355 | spec->vref_mute_led_nid == nid) { | ||
4357 | stac_toggle_power_map(codec, nid, 1); | 4356 | stac_toggle_power_map(codec, nid, 1); |
4358 | continue; | 4357 | continue; |
4359 | } | 4358 | } |
@@ -4822,7 +4821,7 @@ static void set_hp_led_gpio(struct hda_codec *codec) | |||
4822 | * Need more information on whether it is true across the entire series. | 4821 | * Need more information on whether it is true across the entire series. |
4823 | * -- kunal | 4822 | * -- kunal |
4824 | */ | 4823 | */ |
4825 | static int find_mute_led_gpio(struct hda_codec *codec, int default_polarity) | 4824 | static int find_mute_led_cfg(struct hda_codec *codec, int default_polarity) |
4826 | { | 4825 | { |
4827 | struct sigmatel_spec *spec = codec->spec; | 4826 | struct sigmatel_spec *spec = codec->spec; |
4828 | const struct dmi_device *dev = NULL; | 4827 | const struct dmi_device *dev = NULL; |
@@ -4833,8 +4832,14 @@ static int find_mute_led_gpio(struct hda_codec *codec, int default_polarity) | |||
4833 | if (sscanf(dev->name, "HP_Mute_LED_%d_%x", | 4832 | if (sscanf(dev->name, "HP_Mute_LED_%d_%x", |
4834 | &spec->gpio_led_polarity, | 4833 | &spec->gpio_led_polarity, |
4835 | &spec->gpio_led) == 2) { | 4834 | &spec->gpio_led) == 2) { |
4836 | if (spec->gpio_led < 4) | 4835 | unsigned int max_gpio; |
4836 | max_gpio = snd_hda_param_read(codec, codec->afg, | ||
4837 | AC_PAR_GPIO_CAP); | ||
4838 | max_gpio &= AC_GPIO_IO_COUNT; | ||
4839 | if (spec->gpio_led < max_gpio) | ||
4837 | spec->gpio_led = 1 << spec->gpio_led; | 4840 | spec->gpio_led = 1 << spec->gpio_led; |
4841 | else | ||
4842 | spec->vref_mute_led_nid = spec->gpio_led; | ||
4838 | return 1; | 4843 | return 1; |
4839 | } | 4844 | } |
4840 | if (sscanf(dev->name, "HP_Mute_LED_%d", | 4845 | if (sscanf(dev->name, "HP_Mute_LED_%d", |
@@ -4842,13 +4847,21 @@ static int find_mute_led_gpio(struct hda_codec *codec, int default_polarity) | |||
4842 | set_hp_led_gpio(codec); | 4847 | set_hp_led_gpio(codec); |
4843 | return 1; | 4848 | return 1; |
4844 | } | 4849 | } |
4850 | /* BIOS bug: unfilled OEM string */ | ||
4851 | if (strstr(dev->name, "HP_Mute_LED_P_G")) { | ||
4852 | set_hp_led_gpio(codec); | ||
4853 | spec->gpio_led_polarity = 1; | ||
4854 | return 1; | ||
4855 | } | ||
4845 | } | 4856 | } |
4846 | 4857 | ||
4847 | /* | 4858 | /* |
4848 | * Fallback case - if we don't find the DMI strings, | 4859 | * Fallback case - if we don't find the DMI strings, |
4849 | * we statically set the GPIO - if not a B-series system. | 4860 | * we statically set the GPIO - if not a B-series system |
4861 | * and default polarity is provided | ||
4850 | */ | 4862 | */ |
4851 | if (!hp_blike_system(codec->subsystem_id)) { | 4863 | if (!hp_blike_system(codec->subsystem_id) && |
4864 | (default_polarity == 0 || default_polarity == 1)) { | ||
4852 | set_hp_led_gpio(codec); | 4865 | set_hp_led_gpio(codec); |
4853 | spec->gpio_led_polarity = default_polarity; | 4866 | spec->gpio_led_polarity = default_polarity; |
4854 | return 1; | 4867 | return 1; |
@@ -4963,29 +4976,12 @@ static int stac92xx_pre_resume(struct hda_codec *codec) | |||
4963 | struct sigmatel_spec *spec = codec->spec; | 4976 | struct sigmatel_spec *spec = codec->spec; |
4964 | 4977 | ||
4965 | /* sync mute LED */ | 4978 | /* sync mute LED */ |
4966 | if (spec->gpio_led) { | 4979 | if (spec->vref_mute_led_nid) |
4967 | if (spec->gpio_led <= 8) { | 4980 | stac_vrefout_set(codec, spec->vref_mute_led_nid, |
4968 | stac_gpio_set(codec, spec->gpio_mask, | 4981 | spec->vref_led); |
4969 | spec->gpio_dir, spec->gpio_data); | 4982 | else if (spec->gpio_led) |
4970 | } else { | 4983 | stac_gpio_set(codec, spec->gpio_mask, |
4971 | stac_vrefout_set(codec, | 4984 | spec->gpio_dir, spec->gpio_data); |
4972 | spec->gpio_led, spec->vref_led); | ||
4973 | } | ||
4974 | } | ||
4975 | return 0; | ||
4976 | } | ||
4977 | |||
4978 | static int stac92xx_post_suspend(struct hda_codec *codec) | ||
4979 | { | ||
4980 | struct sigmatel_spec *spec = codec->spec; | ||
4981 | if (spec->gpio_led > 8) { | ||
4982 | /* with vref-out pin used for mute led control | ||
4983 | * codec AFG is prevented from D3 state, but on | ||
4984 | * system suspend it can (and should) be used | ||
4985 | */ | ||
4986 | snd_hda_codec_read(codec, codec->afg, 0, | ||
4987 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | ||
4988 | } | ||
4989 | return 0; | 4985 | return 0; |
4990 | } | 4986 | } |
4991 | 4987 | ||
@@ -4996,7 +4992,7 @@ static void stac92xx_set_power_state(struct hda_codec *codec, hda_nid_t fg, | |||
4996 | struct sigmatel_spec *spec = codec->spec; | 4992 | struct sigmatel_spec *spec = codec->spec; |
4997 | 4993 | ||
4998 | if (power_state == AC_PWRST_D3) { | 4994 | if (power_state == AC_PWRST_D3) { |
4999 | if (spec->gpio_led > 8) { | 4995 | if (spec->vref_mute_led_nid) { |
5000 | /* with vref-out pin used for mute led control | 4996 | /* with vref-out pin used for mute led control |
5001 | * codec AFG is prevented from D3 state | 4997 | * codec AFG is prevented from D3 state |
5002 | */ | 4998 | */ |
@@ -5049,7 +5045,7 @@ static int stac92xx_update_led_status(struct hda_codec *codec) | |||
5049 | } | 5045 | } |
5050 | } | 5046 | } |
5051 | /*polarity defines *not* muted state level*/ | 5047 | /*polarity defines *not* muted state level*/ |
5052 | if (spec->gpio_led <= 8) { | 5048 | if (!spec->vref_mute_led_nid) { |
5053 | if (muted) | 5049 | if (muted) |
5054 | spec->gpio_data &= ~spec->gpio_led; /* orange */ | 5050 | spec->gpio_data &= ~spec->gpio_led; /* orange */ |
5055 | else | 5051 | else |
@@ -5067,7 +5063,8 @@ static int stac92xx_update_led_status(struct hda_codec *codec) | |||
5067 | muted_lvl = spec->gpio_led_polarity ? | 5063 | muted_lvl = spec->gpio_led_polarity ? |
5068 | AC_PINCTL_VREF_GRD : AC_PINCTL_VREF_HIZ; | 5064 | AC_PINCTL_VREF_GRD : AC_PINCTL_VREF_HIZ; |
5069 | spec->vref_led = muted ? muted_lvl : notmtd_lvl; | 5065 | spec->vref_led = muted ? muted_lvl : notmtd_lvl; |
5070 | stac_vrefout_set(codec, spec->gpio_led, spec->vref_led); | 5066 | stac_vrefout_set(codec, spec->vref_mute_led_nid, |
5067 | spec->vref_led); | ||
5071 | } | 5068 | } |
5072 | return 0; | 5069 | return 0; |
5073 | } | 5070 | } |
@@ -5574,22 +5571,20 @@ again: | |||
5574 | 5571 | ||
5575 | codec->patch_ops = stac92xx_patch_ops; | 5572 | codec->patch_ops = stac92xx_patch_ops; |
5576 | 5573 | ||
5577 | if (find_mute_led_gpio(codec, 0)) | 5574 | if (find_mute_led_cfg(codec, -1/*no default cfg*/)) |
5578 | snd_printd("mute LED gpio %d polarity %d\n", | 5575 | snd_printd("mute LED gpio %d polarity %d\n", |
5579 | spec->gpio_led, | 5576 | spec->gpio_led, |
5580 | spec->gpio_led_polarity); | 5577 | spec->gpio_led_polarity); |
5581 | 5578 | ||
5582 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 5579 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
5583 | if (spec->gpio_led) { | 5580 | if (spec->gpio_led) { |
5584 | if (spec->gpio_led <= 8) { | 5581 | if (!spec->vref_mute_led_nid) { |
5585 | spec->gpio_mask |= spec->gpio_led; | 5582 | spec->gpio_mask |= spec->gpio_led; |
5586 | spec->gpio_dir |= spec->gpio_led; | 5583 | spec->gpio_dir |= spec->gpio_led; |
5587 | spec->gpio_data |= spec->gpio_led; | 5584 | spec->gpio_data |= spec->gpio_led; |
5588 | } else { | 5585 | } else { |
5589 | codec->patch_ops.set_power_state = | 5586 | codec->patch_ops.set_power_state = |
5590 | stac92xx_set_power_state; | 5587 | stac92xx_set_power_state; |
5591 | codec->patch_ops.post_suspend = | ||
5592 | stac92xx_post_suspend; | ||
5593 | } | 5588 | } |
5594 | codec->patch_ops.pre_resume = stac92xx_pre_resume; | 5589 | codec->patch_ops.pre_resume = stac92xx_pre_resume; |
5595 | codec->patch_ops.check_power_status = | 5590 | codec->patch_ops.check_power_status = |
@@ -5887,22 +5882,20 @@ again: | |||
5887 | } | 5882 | } |
5888 | } | 5883 | } |
5889 | 5884 | ||
5890 | if (find_mute_led_gpio(codec, 1)) | 5885 | if (find_mute_led_cfg(codec, 1)) |
5891 | snd_printd("mute LED gpio %d polarity %d\n", | 5886 | snd_printd("mute LED gpio %d polarity %d\n", |
5892 | spec->gpio_led, | 5887 | spec->gpio_led, |
5893 | spec->gpio_led_polarity); | 5888 | spec->gpio_led_polarity); |
5894 | 5889 | ||
5895 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 5890 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
5896 | if (spec->gpio_led) { | 5891 | if (spec->gpio_led) { |
5897 | if (spec->gpio_led <= 8) { | 5892 | if (!spec->vref_mute_led_nid) { |
5898 | spec->gpio_mask |= spec->gpio_led; | 5893 | spec->gpio_mask |= spec->gpio_led; |
5899 | spec->gpio_dir |= spec->gpio_led; | 5894 | spec->gpio_dir |= spec->gpio_led; |
5900 | spec->gpio_data |= spec->gpio_led; | 5895 | spec->gpio_data |= spec->gpio_led; |
5901 | } else { | 5896 | } else { |
5902 | codec->patch_ops.set_power_state = | 5897 | codec->patch_ops.set_power_state = |
5903 | stac92xx_set_power_state; | 5898 | stac92xx_set_power_state; |
5904 | codec->patch_ops.post_suspend = | ||
5905 | stac92xx_post_suspend; | ||
5906 | } | 5899 | } |
5907 | codec->patch_ops.pre_resume = stac92xx_pre_resume; | 5900 | codec->patch_ops.pre_resume = stac92xx_pre_resume; |
5908 | codec->patch_ops.check_power_status = | 5901 | codec->patch_ops.check_power_status = |
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index f73c98638abd..ab56866cc94e 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c | |||
@@ -209,6 +209,7 @@ struct via_spec { | |||
209 | /* work to check hp jack state */ | 209 | /* work to check hp jack state */ |
210 | struct hda_codec *codec; | 210 | struct hda_codec *codec; |
211 | struct delayed_work vt1708_hp_work; | 211 | struct delayed_work vt1708_hp_work; |
212 | int hp_work_active; | ||
212 | int vt1708_jack_detect; | 213 | int vt1708_jack_detect; |
213 | int vt1708_hp_present; | 214 | int vt1708_hp_present; |
214 | 215 | ||
@@ -306,27 +307,35 @@ enum { | |||
306 | static void analog_low_current_mode(struct hda_codec *codec); | 307 | static void analog_low_current_mode(struct hda_codec *codec); |
307 | static bool is_aa_path_mute(struct hda_codec *codec); | 308 | static bool is_aa_path_mute(struct hda_codec *codec); |
308 | 309 | ||
309 | static void vt1708_start_hp_work(struct via_spec *spec) | 310 | #define hp_detect_with_aa(codec) \ |
311 | (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1 && \ | ||
312 | !is_aa_path_mute(codec)) | ||
313 | |||
314 | static void vt1708_stop_hp_work(struct via_spec *spec) | ||
310 | { | 315 | { |
311 | if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0) | 316 | if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0) |
312 | return; | 317 | return; |
313 | snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81, | 318 | if (spec->hp_work_active) { |
314 | !spec->vt1708_jack_detect); | 319 | snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81, 1); |
315 | if (!delayed_work_pending(&spec->vt1708_hp_work)) | 320 | cancel_delayed_work_sync(&spec->vt1708_hp_work); |
316 | schedule_delayed_work(&spec->vt1708_hp_work, | 321 | spec->hp_work_active = 0; |
317 | msecs_to_jiffies(100)); | 322 | } |
318 | } | 323 | } |
319 | 324 | ||
320 | static void vt1708_stop_hp_work(struct via_spec *spec) | 325 | static void vt1708_update_hp_work(struct via_spec *spec) |
321 | { | 326 | { |
322 | if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0) | 327 | if (spec->codec_type != VT1708 || spec->autocfg.hp_pins[0] == 0) |
323 | return; | 328 | return; |
324 | if (snd_hda_get_bool_hint(spec->codec, "analog_loopback_hp_detect") == 1 | 329 | if (spec->vt1708_jack_detect && |
325 | && !is_aa_path_mute(spec->codec)) | 330 | (spec->active_streams || hp_detect_with_aa(spec->codec))) { |
326 | return; | 331 | if (!spec->hp_work_active) { |
327 | snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81, | 332 | snd_hda_codec_write(spec->codec, 0x1, 0, 0xf81, 0); |
328 | !spec->vt1708_jack_detect); | 333 | schedule_delayed_work(&spec->vt1708_hp_work, |
329 | cancel_delayed_work_sync(&spec->vt1708_hp_work); | 334 | msecs_to_jiffies(100)); |
335 | spec->hp_work_active = 1; | ||
336 | } | ||
337 | } else if (!hp_detect_with_aa(spec->codec)) | ||
338 | vt1708_stop_hp_work(spec); | ||
330 | } | 339 | } |
331 | 340 | ||
332 | static void set_widgets_power_state(struct hda_codec *codec) | 341 | static void set_widgets_power_state(struct hda_codec *codec) |
@@ -344,12 +353,7 @@ static int analog_input_switch_put(struct snd_kcontrol *kcontrol, | |||
344 | 353 | ||
345 | set_widgets_power_state(codec); | 354 | set_widgets_power_state(codec); |
346 | analog_low_current_mode(snd_kcontrol_chip(kcontrol)); | 355 | analog_low_current_mode(snd_kcontrol_chip(kcontrol)); |
347 | if (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1) { | 356 | vt1708_update_hp_work(codec->spec); |
348 | if (is_aa_path_mute(codec)) | ||
349 | vt1708_start_hp_work(codec->spec); | ||
350 | else | ||
351 | vt1708_stop_hp_work(codec->spec); | ||
352 | } | ||
353 | return change; | 357 | return change; |
354 | } | 358 | } |
355 | 359 | ||
@@ -1155,7 +1159,7 @@ static int via_playback_multi_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
1155 | spec->cur_dac_stream_tag = stream_tag; | 1159 | spec->cur_dac_stream_tag = stream_tag; |
1156 | spec->cur_dac_format = format; | 1160 | spec->cur_dac_format = format; |
1157 | mutex_unlock(&spec->config_mutex); | 1161 | mutex_unlock(&spec->config_mutex); |
1158 | vt1708_start_hp_work(spec); | 1162 | vt1708_update_hp_work(spec); |
1159 | return 0; | 1163 | return 0; |
1160 | } | 1164 | } |
1161 | 1165 | ||
@@ -1175,7 +1179,7 @@ static int via_playback_hp_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
1175 | spec->cur_hp_stream_tag = stream_tag; | 1179 | spec->cur_hp_stream_tag = stream_tag; |
1176 | spec->cur_hp_format = format; | 1180 | spec->cur_hp_format = format; |
1177 | mutex_unlock(&spec->config_mutex); | 1181 | mutex_unlock(&spec->config_mutex); |
1178 | vt1708_start_hp_work(spec); | 1182 | vt1708_update_hp_work(spec); |
1179 | return 0; | 1183 | return 0; |
1180 | } | 1184 | } |
1181 | 1185 | ||
@@ -1189,7 +1193,7 @@ static int via_playback_multi_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
1189 | snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); | 1193 | snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); |
1190 | spec->active_streams &= ~STREAM_MULTI_OUT; | 1194 | spec->active_streams &= ~STREAM_MULTI_OUT; |
1191 | mutex_unlock(&spec->config_mutex); | 1195 | mutex_unlock(&spec->config_mutex); |
1192 | vt1708_stop_hp_work(spec); | 1196 | vt1708_update_hp_work(spec); |
1193 | return 0; | 1197 | return 0; |
1194 | } | 1198 | } |
1195 | 1199 | ||
@@ -1204,7 +1208,7 @@ static int via_playback_hp_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
1204 | snd_hda_codec_setup_stream(codec, spec->hp_dac_nid, 0, 0, 0); | 1208 | snd_hda_codec_setup_stream(codec, spec->hp_dac_nid, 0, 0, 0); |
1205 | spec->active_streams &= ~STREAM_INDEP_HP; | 1209 | spec->active_streams &= ~STREAM_INDEP_HP; |
1206 | mutex_unlock(&spec->config_mutex); | 1210 | mutex_unlock(&spec->config_mutex); |
1207 | vt1708_stop_hp_work(spec); | 1211 | vt1708_update_hp_work(spec); |
1208 | return 0; | 1212 | return 0; |
1209 | } | 1213 | } |
1210 | 1214 | ||
@@ -1651,7 +1655,8 @@ static void via_hp_automute(struct hda_codec *codec) | |||
1651 | int nums; | 1655 | int nums; |
1652 | struct via_spec *spec = codec->spec; | 1656 | struct via_spec *spec = codec->spec; |
1653 | 1657 | ||
1654 | if (!spec->hp_independent_mode && spec->autocfg.hp_pins[0]) | 1658 | if (!spec->hp_independent_mode && spec->autocfg.hp_pins[0] && |
1659 | (spec->codec_type != VT1708 || spec->vt1708_jack_detect)) | ||
1655 | present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]); | 1660 | present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]); |
1656 | 1661 | ||
1657 | if (spec->smart51_enabled) | 1662 | if (spec->smart51_enabled) |
@@ -2620,8 +2625,6 @@ static int vt1708_jack_detect_get(struct snd_kcontrol *kcontrol, | |||
2620 | 2625 | ||
2621 | if (spec->codec_type != VT1708) | 2626 | if (spec->codec_type != VT1708) |
2622 | return 0; | 2627 | return 0; |
2623 | spec->vt1708_jack_detect = | ||
2624 | !((snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8) & 0x1); | ||
2625 | ucontrol->value.integer.value[0] = spec->vt1708_jack_detect; | 2628 | ucontrol->value.integer.value[0] = spec->vt1708_jack_detect; |
2626 | return 0; | 2629 | return 0; |
2627 | } | 2630 | } |
@@ -2631,18 +2634,22 @@ static int vt1708_jack_detect_put(struct snd_kcontrol *kcontrol, | |||
2631 | { | 2634 | { |
2632 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 2635 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
2633 | struct via_spec *spec = codec->spec; | 2636 | struct via_spec *spec = codec->spec; |
2634 | int change; | 2637 | int val; |
2635 | 2638 | ||
2636 | if (spec->codec_type != VT1708) | 2639 | if (spec->codec_type != VT1708) |
2637 | return 0; | 2640 | return 0; |
2638 | spec->vt1708_jack_detect = ucontrol->value.integer.value[0]; | 2641 | val = !!ucontrol->value.integer.value[0]; |
2639 | change = (0x1 & (snd_hda_codec_read(codec, 0x1, 0, 0xf84, 0) >> 8)) | 2642 | if (spec->vt1708_jack_detect == val) |
2640 | == !spec->vt1708_jack_detect; | 2643 | return 0; |
2641 | if (spec->vt1708_jack_detect) { | 2644 | spec->vt1708_jack_detect = val; |
2645 | if (spec->vt1708_jack_detect && | ||
2646 | snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") != 1) { | ||
2642 | mute_aa_path(codec, 1); | 2647 | mute_aa_path(codec, 1); |
2643 | notify_aa_path_ctls(codec); | 2648 | notify_aa_path_ctls(codec); |
2644 | } | 2649 | } |
2645 | return change; | 2650 | via_hp_automute(codec); |
2651 | vt1708_update_hp_work(spec); | ||
2652 | return 1; | ||
2646 | } | 2653 | } |
2647 | 2654 | ||
2648 | static const struct snd_kcontrol_new vt1708_jack_detect_ctl = { | 2655 | static const struct snd_kcontrol_new vt1708_jack_detect_ctl = { |
@@ -2776,6 +2783,7 @@ static int via_init(struct hda_codec *codec) | |||
2776 | via_auto_init_unsol_event(codec); | 2783 | via_auto_init_unsol_event(codec); |
2777 | 2784 | ||
2778 | via_hp_automute(codec); | 2785 | via_hp_automute(codec); |
2786 | vt1708_update_hp_work(spec); | ||
2779 | snd_hda_jack_report_sync(codec); | 2787 | snd_hda_jack_report_sync(codec); |
2780 | 2788 | ||
2781 | return 0; | 2789 | return 0; |
@@ -2794,7 +2802,9 @@ static void vt1708_update_hp_jack_state(struct work_struct *work) | |||
2794 | spec->vt1708_hp_present ^= 1; | 2802 | spec->vt1708_hp_present ^= 1; |
2795 | via_hp_automute(spec->codec); | 2803 | via_hp_automute(spec->codec); |
2796 | } | 2804 | } |
2797 | vt1708_start_hp_work(spec); | 2805 | if (spec->vt1708_jack_detect) |
2806 | schedule_delayed_work(&spec->vt1708_hp_work, | ||
2807 | msecs_to_jiffies(100)); | ||
2798 | } | 2808 | } |
2799 | 2809 | ||
2800 | static int get_mux_nids(struct hda_codec *codec) | 2810 | static int get_mux_nids(struct hda_codec *codec) |
diff --git a/sound/pci/lx6464es/lx_core.c b/sound/pci/lx6464es/lx_core.c index 5c8717e29eeb..8c3e7fcefd99 100644 --- a/sound/pci/lx6464es/lx_core.c +++ b/sound/pci/lx6464es/lx_core.c | |||
@@ -78,10 +78,15 @@ unsigned long lx_dsp_reg_read(struct lx6464es *chip, int port) | |||
78 | return ioread32(address); | 78 | return ioread32(address); |
79 | } | 79 | } |
80 | 80 | ||
81 | void lx_dsp_reg_readbuf(struct lx6464es *chip, int port, u32 *data, u32 len) | 81 | static void lx_dsp_reg_readbuf(struct lx6464es *chip, int port, u32 *data, |
82 | u32 len) | ||
82 | { | 83 | { |
83 | void __iomem *address = lx_dsp_register(chip, port); | 84 | u32 __iomem *address = lx_dsp_register(chip, port); |
84 | memcpy_fromio(data, address, len*sizeof(u32)); | 85 | int i; |
86 | |||
87 | /* we cannot use memcpy_fromio */ | ||
88 | for (i = 0; i != len; ++i) | ||
89 | data[i] = ioread32(address + i); | ||
85 | } | 90 | } |
86 | 91 | ||
87 | 92 | ||
@@ -91,11 +96,15 @@ void lx_dsp_reg_write(struct lx6464es *chip, int port, unsigned data) | |||
91 | iowrite32(data, address); | 96 | iowrite32(data, address); |
92 | } | 97 | } |
93 | 98 | ||
94 | void lx_dsp_reg_writebuf(struct lx6464es *chip, int port, const u32 *data, | 99 | static void lx_dsp_reg_writebuf(struct lx6464es *chip, int port, |
95 | u32 len) | 100 | const u32 *data, u32 len) |
96 | { | 101 | { |
97 | void __iomem *address = lx_dsp_register(chip, port); | 102 | u32 __iomem *address = lx_dsp_register(chip, port); |
98 | memcpy_toio(address, data, len*sizeof(u32)); | 103 | int i; |
104 | |||
105 | /* we cannot use memcpy_to */ | ||
106 | for (i = 0; i != len; ++i) | ||
107 | iowrite32(data[i], address + i); | ||
99 | } | 108 | } |
100 | 109 | ||
101 | 110 | ||
diff --git a/sound/pci/lx6464es/lx_core.h b/sound/pci/lx6464es/lx_core.h index 1dd562980b6c..4d7ff797a646 100644 --- a/sound/pci/lx6464es/lx_core.h +++ b/sound/pci/lx6464es/lx_core.h | |||
@@ -72,10 +72,7 @@ enum { | |||
72 | }; | 72 | }; |
73 | 73 | ||
74 | unsigned long lx_dsp_reg_read(struct lx6464es *chip, int port); | 74 | unsigned long lx_dsp_reg_read(struct lx6464es *chip, int port); |
75 | void lx_dsp_reg_readbuf(struct lx6464es *chip, int port, u32 *data, u32 len); | ||
76 | void lx_dsp_reg_write(struct lx6464es *chip, int port, unsigned data); | 75 | void lx_dsp_reg_write(struct lx6464es *chip, int port, unsigned data); |
77 | void lx_dsp_reg_writebuf(struct lx6464es *chip, int port, const u32 *data, | ||
78 | u32 len); | ||
79 | 76 | ||
80 | /* plx register access */ | 77 | /* plx register access */ |
81 | enum { | 78 | enum { |
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index e760adad9523..19ee2203cbb5 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c | |||
@@ -6518,7 +6518,7 @@ static int __devinit snd_hdspm_create(struct snd_card *card, | |||
6518 | hdspm->io_type = AES32; | 6518 | hdspm->io_type = AES32; |
6519 | hdspm->card_name = "RME AES32"; | 6519 | hdspm->card_name = "RME AES32"; |
6520 | hdspm->midiPorts = 2; | 6520 | hdspm->midiPorts = 2; |
6521 | } else if ((hdspm->firmware_rev == 0xd5) || | 6521 | } else if ((hdspm->firmware_rev == 0xd2) || |
6522 | ((hdspm->firmware_rev >= 0xc8) && | 6522 | ((hdspm->firmware_rev >= 0xc8) && |
6523 | (hdspm->firmware_rev <= 0xcf))) { | 6523 | (hdspm->firmware_rev <= 0xcf))) { |
6524 | hdspm->io_type = MADI; | 6524 | hdspm->io_type = MADI; |
diff --git a/sound/pci/sis7019.c b/sound/pci/sis7019.c index a391e622a192..28dfafb56dd1 100644 --- a/sound/pci/sis7019.c +++ b/sound/pci/sis7019.c | |||
@@ -41,6 +41,7 @@ MODULE_SUPPORTED_DEVICE("{{SiS,SiS7019 Audio Accelerator}}"); | |||
41 | static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */ | 41 | static int index = SNDRV_DEFAULT_IDX1; /* Index 0-MAX */ |
42 | static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ | 42 | static char *id = SNDRV_DEFAULT_STR1; /* ID for this card */ |
43 | static int enable = 1; | 43 | static int enable = 1; |
44 | static int codecs = 1; | ||
44 | 45 | ||
45 | module_param(index, int, 0444); | 46 | module_param(index, int, 0444); |
46 | MODULE_PARM_DESC(index, "Index value for SiS7019 Audio Accelerator."); | 47 | MODULE_PARM_DESC(index, "Index value for SiS7019 Audio Accelerator."); |
@@ -48,6 +49,8 @@ module_param(id, charp, 0444); | |||
48 | MODULE_PARM_DESC(id, "ID string for SiS7019 Audio Accelerator."); | 49 | MODULE_PARM_DESC(id, "ID string for SiS7019 Audio Accelerator."); |
49 | module_param(enable, bool, 0444); | 50 | module_param(enable, bool, 0444); |
50 | MODULE_PARM_DESC(enable, "Enable SiS7019 Audio Accelerator."); | 51 | MODULE_PARM_DESC(enable, "Enable SiS7019 Audio Accelerator."); |
52 | module_param(codecs, int, 0444); | ||
53 | MODULE_PARM_DESC(codecs, "Set bit to indicate that codec number is expected to be present (default 1)"); | ||
51 | 54 | ||
52 | static DEFINE_PCI_DEVICE_TABLE(snd_sis7019_ids) = { | 55 | static DEFINE_PCI_DEVICE_TABLE(snd_sis7019_ids) = { |
53 | { PCI_DEVICE(PCI_VENDOR_ID_SI, 0x7019) }, | 56 | { PCI_DEVICE(PCI_VENDOR_ID_SI, 0x7019) }, |
@@ -140,6 +143,9 @@ struct sis7019 { | |||
140 | dma_addr_t silence_dma_addr; | 143 | dma_addr_t silence_dma_addr; |
141 | }; | 144 | }; |
142 | 145 | ||
146 | /* These values are also used by the module param 'codecs' to indicate | ||
147 | * which codecs should be present. | ||
148 | */ | ||
143 | #define SIS_PRIMARY_CODEC_PRESENT 0x0001 | 149 | #define SIS_PRIMARY_CODEC_PRESENT 0x0001 |
144 | #define SIS_SECONDARY_CODEC_PRESENT 0x0002 | 150 | #define SIS_SECONDARY_CODEC_PRESENT 0x0002 |
145 | #define SIS_TERTIARY_CODEC_PRESENT 0x0004 | 151 | #define SIS_TERTIARY_CODEC_PRESENT 0x0004 |
@@ -1078,6 +1084,7 @@ static int sis_chip_init(struct sis7019 *sis) | |||
1078 | { | 1084 | { |
1079 | unsigned long io = sis->ioport; | 1085 | unsigned long io = sis->ioport; |
1080 | void __iomem *ioaddr = sis->ioaddr; | 1086 | void __iomem *ioaddr = sis->ioaddr; |
1087 | unsigned long timeout; | ||
1081 | u16 status; | 1088 | u16 status; |
1082 | int count; | 1089 | int count; |
1083 | int i; | 1090 | int i; |
@@ -1104,21 +1111,45 @@ static int sis_chip_init(struct sis7019 *sis) | |||
1104 | while ((inw(io + SIS_AC97_STATUS) & SIS_AC97_STATUS_BUSY) && --count) | 1111 | while ((inw(io + SIS_AC97_STATUS) & SIS_AC97_STATUS_BUSY) && --count) |
1105 | udelay(1); | 1112 | udelay(1); |
1106 | 1113 | ||
1114 | /* Command complete, we can let go of the semaphore now. | ||
1115 | */ | ||
1116 | outl(SIS_AC97_SEMA_RELEASE, io + SIS_AC97_SEMA); | ||
1117 | if (!count) | ||
1118 | return -EIO; | ||
1119 | |||
1107 | /* Now that we've finished the reset, find out what's attached. | 1120 | /* Now that we've finished the reset, find out what's attached. |
1121 | * There are some codec/board combinations that take an extremely | ||
1122 | * long time to come up. 350+ ms has been observed in the field, | ||
1123 | * so we'll give them up to 500ms. | ||
1108 | */ | 1124 | */ |
1109 | status = inl(io + SIS_AC97_STATUS); | 1125 | sis->codecs_present = 0; |
1110 | if (status & SIS_AC97_STATUS_CODEC_READY) | 1126 | timeout = msecs_to_jiffies(500) + jiffies; |
1111 | sis->codecs_present |= SIS_PRIMARY_CODEC_PRESENT; | 1127 | while (time_before_eq(jiffies, timeout)) { |
1112 | if (status & SIS_AC97_STATUS_CODEC2_READY) | 1128 | status = inl(io + SIS_AC97_STATUS); |
1113 | sis->codecs_present |= SIS_SECONDARY_CODEC_PRESENT; | 1129 | if (status & SIS_AC97_STATUS_CODEC_READY) |
1114 | if (status & SIS_AC97_STATUS_CODEC3_READY) | 1130 | sis->codecs_present |= SIS_PRIMARY_CODEC_PRESENT; |
1115 | sis->codecs_present |= SIS_TERTIARY_CODEC_PRESENT; | 1131 | if (status & SIS_AC97_STATUS_CODEC2_READY) |
1116 | 1132 | sis->codecs_present |= SIS_SECONDARY_CODEC_PRESENT; | |
1117 | /* All done, let go of the semaphore, and check for errors | 1133 | if (status & SIS_AC97_STATUS_CODEC3_READY) |
1134 | sis->codecs_present |= SIS_TERTIARY_CODEC_PRESENT; | ||
1135 | |||
1136 | if (sis->codecs_present == codecs) | ||
1137 | break; | ||
1138 | |||
1139 | msleep(1); | ||
1140 | } | ||
1141 | |||
1142 | /* All done, check for errors. | ||
1118 | */ | 1143 | */ |
1119 | outl(SIS_AC97_SEMA_RELEASE, io + SIS_AC97_SEMA); | 1144 | if (!sis->codecs_present) { |
1120 | if (!sis->codecs_present || !count) | 1145 | printk(KERN_ERR "sis7019: could not find any codecs\n"); |
1121 | return -EIO; | 1146 | return -EIO; |
1147 | } | ||
1148 | |||
1149 | if (sis->codecs_present != codecs) { | ||
1150 | printk(KERN_WARNING "sis7019: missing codecs, found %0x, expected %0x\n", | ||
1151 | sis->codecs_present, codecs); | ||
1152 | } | ||
1122 | 1153 | ||
1123 | /* Let the hardware know that the audio driver is alive, | 1154 | /* Let the hardware know that the audio driver is alive, |
1124 | * and enable PCM slots on the AC-link for L/R playback (3 & 4) and | 1155 | * and enable PCM slots on the AC-link for L/R playback (3 & 4) and |
@@ -1390,6 +1421,17 @@ static int __devinit snd_sis7019_probe(struct pci_dev *pci, | |||
1390 | if (!enable) | 1421 | if (!enable) |
1391 | goto error_out; | 1422 | goto error_out; |
1392 | 1423 | ||
1424 | /* The user can specify which codecs should be present so that we | ||
1425 | * can wait for them to show up if they are slow to recover from | ||
1426 | * the AC97 cold reset. We default to a single codec, the primary. | ||
1427 | * | ||
1428 | * We assume that SIS_PRIMARY_*_PRESENT matches bits 0-2. | ||
1429 | */ | ||
1430 | codecs &= SIS_PRIMARY_CODEC_PRESENT | SIS_SECONDARY_CODEC_PRESENT | | ||
1431 | SIS_TERTIARY_CODEC_PRESENT; | ||
1432 | if (!codecs) | ||
1433 | codecs = SIS_PRIMARY_CODEC_PRESENT; | ||
1434 | |||
1393 | rc = snd_card_create(index, id, THIS_MODULE, sizeof(*sis), &card); | 1435 | rc = snd_card_create(index, id, THIS_MODULE, sizeof(*sis), &card); |
1394 | if (rc < 0) | 1436 | if (rc < 0) |
1395 | goto error_out; | 1437 | goto error_out; |
diff --git a/sound/soc/atmel/Kconfig b/sound/soc/atmel/Kconfig index bee3c94f58b0..d1fcc816ce97 100644 --- a/sound/soc/atmel/Kconfig +++ b/sound/soc/atmel/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config SND_ATMEL_SOC | 1 | config SND_ATMEL_SOC |
2 | tristate "SoC Audio for the Atmel System-on-Chip" | 2 | tristate "SoC Audio for the Atmel System-on-Chip" |
3 | depends on ARCH_AT91 || AVR32 | 3 | depends on ARCH_AT91 |
4 | help | 4 | help |
5 | Say Y or M if you want to add support for codecs attached to | 5 | Say Y or M if you want to add support for codecs attached to |
6 | the ATMEL SSC interface. You will also need | 6 | the ATMEL SSC interface. You will also need |
@@ -24,25 +24,6 @@ config SND_AT91_SOC_SAM9G20_WM8731 | |||
24 | Say Y if you want to add support for SoC audio on WM8731-based | 24 | Say Y if you want to add support for SoC audio on WM8731-based |
25 | AT91sam9g20 evaluation board. | 25 | AT91sam9g20 evaluation board. |
26 | 26 | ||
27 | config SND_AT32_SOC_PLAYPAQ | ||
28 | tristate "SoC Audio support for PlayPaq with WM8510" | ||
29 | depends on SND_ATMEL_SOC && BOARD_PLAYPAQ && AT91_PROGRAMMABLE_CLOCKS | ||
30 | select SND_ATMEL_SOC_SSC | ||
31 | select SND_SOC_WM8510 | ||
32 | help | ||
33 | Say Y or M here if you want to add support for SoC audio | ||
34 | on the LRS PlayPaq. | ||
35 | |||
36 | config SND_AT32_SOC_PLAYPAQ_SLAVE | ||
37 | bool "Run CODEC on PlayPaq in slave mode" | ||
38 | depends on SND_AT32_SOC_PLAYPAQ | ||
39 | default n | ||
40 | help | ||
41 | Say Y if you want to run with the AT32 SSC generating the BCLK | ||
42 | and FRAME signals on the PlayPaq. Unless you want to play | ||
43 | with the AT32 as the SSC master, you probably want to say N here, | ||
44 | as this will give you better sound quality. | ||
45 | |||
46 | config SND_AT91_SOC_AFEB9260 | 27 | config SND_AT91_SOC_AFEB9260 |
47 | tristate "SoC Audio support for AFEB9260 board" | 28 | tristate "SoC Audio support for AFEB9260 board" |
48 | depends on ARCH_AT91 && MACH_AFEB9260 && SND_ATMEL_SOC | 29 | depends on ARCH_AT91 && MACH_AFEB9260 && SND_ATMEL_SOC |
diff --git a/sound/soc/atmel/Makefile b/sound/soc/atmel/Makefile index e7ea56bd5f82..a5c0bf19da78 100644 --- a/sound/soc/atmel/Makefile +++ b/sound/soc/atmel/Makefile | |||
@@ -8,9 +8,5 @@ obj-$(CONFIG_SND_ATMEL_SOC_SSC) += snd-soc-atmel_ssc_dai.o | |||
8 | # AT91 Machine Support | 8 | # AT91 Machine Support |
9 | snd-soc-sam9g20-wm8731-objs := sam9g20_wm8731.o | 9 | snd-soc-sam9g20-wm8731-objs := sam9g20_wm8731.o |
10 | 10 | ||
11 | # AT32 Machine Support | ||
12 | snd-soc-playpaq-objs := playpaq_wm8510.o | ||
13 | |||
14 | obj-$(CONFIG_SND_AT91_SOC_SAM9G20_WM8731) += snd-soc-sam9g20-wm8731.o | 11 | obj-$(CONFIG_SND_AT91_SOC_SAM9G20_WM8731) += snd-soc-sam9g20-wm8731.o |
15 | obj-$(CONFIG_SND_AT32_SOC_PLAYPAQ) += snd-soc-playpaq.o | ||
16 | obj-$(CONFIG_SND_AT91_SOC_AFEB9260) += snd-soc-afeb9260.o | 12 | obj-$(CONFIG_SND_AT91_SOC_AFEB9260) += snd-soc-afeb9260.o |
diff --git a/sound/soc/atmel/playpaq_wm8510.c b/sound/soc/atmel/playpaq_wm8510.c deleted file mode 100644 index 73ae99ad4578..000000000000 --- a/sound/soc/atmel/playpaq_wm8510.c +++ /dev/null | |||
@@ -1,473 +0,0 @@ | |||
1 | /* sound/soc/at32/playpaq_wm8510.c | ||
2 | * ASoC machine driver for PlayPaq using WM8510 codec | ||
3 | * | ||
4 | * Copyright (C) 2008 Long Range Systems | ||
5 | * Geoffrey Wossum <gwossum@acm.org> | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License version 2 as | ||
9 | * published by the Free Software Foundation. | ||
10 | * | ||
11 | * This code is largely inspired by sound/soc/at91/eti_b1_wm8731.c | ||
12 | * | ||
13 | * NOTE: If you don't have the AT32 enhanced portmux configured (which | ||
14 | * isn't currently in the mainline or Atmel patched kernel), you will | ||
15 | * need to set the MCLK pin (PA30) to peripheral A in your board initialization | ||
16 | * code. Something like: | ||
17 | * at32_select_periph(GPIO_PIN_PA(30), GPIO_PERIPH_A, 0); | ||
18 | * | ||
19 | */ | ||
20 | |||
21 | /* #define DEBUG */ | ||
22 | |||
23 | #include <linux/module.h> | ||
24 | #include <linux/moduleparam.h> | ||
25 | #include <linux/kernel.h> | ||
26 | #include <linux/errno.h> | ||
27 | #include <linux/clk.h> | ||
28 | #include <linux/timer.h> | ||
29 | #include <linux/interrupt.h> | ||
30 | #include <linux/platform_device.h> | ||
31 | |||
32 | #include <sound/core.h> | ||
33 | #include <sound/pcm.h> | ||
34 | #include <sound/pcm_params.h> | ||
35 | #include <sound/soc.h> | ||
36 | |||
37 | #include <mach/at32ap700x.h> | ||
38 | #include <mach/portmux.h> | ||
39 | |||
40 | #include "../codecs/wm8510.h" | ||
41 | #include "atmel-pcm.h" | ||
42 | #include "atmel_ssc_dai.h" | ||
43 | |||
44 | |||
45 | /*-------------------------------------------------------------------------*\ | ||
46 | * constants | ||
47 | \*-------------------------------------------------------------------------*/ | ||
48 | #define MCLK_PIN GPIO_PIN_PA(30) | ||
49 | #define MCLK_PERIPH GPIO_PERIPH_A | ||
50 | |||
51 | |||
52 | /*-------------------------------------------------------------------------*\ | ||
53 | * data types | ||
54 | \*-------------------------------------------------------------------------*/ | ||
55 | /* SSC clocking data */ | ||
56 | struct ssc_clock_data { | ||
57 | /* CMR div */ | ||
58 | unsigned int cmr_div; | ||
59 | |||
60 | /* Frame period (as needed by xCMR.PERIOD) */ | ||
61 | unsigned int period; | ||
62 | |||
63 | /* The SSC clock rate these settings where calculated for */ | ||
64 | unsigned long ssc_rate; | ||
65 | }; | ||
66 | |||
67 | |||
68 | /*-------------------------------------------------------------------------*\ | ||
69 | * module data | ||
70 | \*-------------------------------------------------------------------------*/ | ||
71 | static struct clk *_gclk0; | ||
72 | static struct clk *_pll0; | ||
73 | |||
74 | #define CODEC_CLK (_gclk0) | ||
75 | |||
76 | |||
77 | /*-------------------------------------------------------------------------*\ | ||
78 | * Sound SOC operations | ||
79 | \*-------------------------------------------------------------------------*/ | ||
80 | #if defined CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE | ||
81 | static struct ssc_clock_data playpaq_wm8510_calc_ssc_clock( | ||
82 | struct snd_pcm_hw_params *params, | ||
83 | struct snd_soc_dai *cpu_dai) | ||
84 | { | ||
85 | struct at32_ssc_info *ssc_p = snd_soc_dai_get_drvdata(cpu_dai); | ||
86 | struct ssc_device *ssc = ssc_p->ssc; | ||
87 | struct ssc_clock_data cd; | ||
88 | unsigned int rate, width_bits, channels; | ||
89 | unsigned int bitrate, ssc_div; | ||
90 | unsigned actual_rate; | ||
91 | |||
92 | |||
93 | /* | ||
94 | * Figure out required bitrate | ||
95 | */ | ||
96 | rate = params_rate(params); | ||
97 | channels = params_channels(params); | ||
98 | width_bits = snd_pcm_format_physical_width(params_format(params)); | ||
99 | bitrate = rate * width_bits * channels; | ||
100 | |||
101 | |||
102 | /* | ||
103 | * Figure out required SSC divider and period for required bitrate | ||
104 | */ | ||
105 | cd.ssc_rate = clk_get_rate(ssc->clk); | ||
106 | ssc_div = cd.ssc_rate / bitrate; | ||
107 | cd.cmr_div = ssc_div / 2; | ||
108 | if (ssc_div & 1) { | ||
109 | /* round cmr_div up */ | ||
110 | cd.cmr_div++; | ||
111 | } | ||
112 | cd.period = width_bits - 1; | ||
113 | |||
114 | |||
115 | /* | ||
116 | * Find actual rate, compare to requested rate | ||
117 | */ | ||
118 | actual_rate = (cd.ssc_rate / (cd.cmr_div * 2)) / (2 * (cd.period + 1)); | ||
119 | pr_debug("playpaq_wm8510: Request rate = %u, actual rate = %u\n", | ||
120 | rate, actual_rate); | ||
121 | |||
122 | |||
123 | return cd; | ||
124 | } | ||
125 | #endif /* CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE */ | ||
126 | |||
127 | |||
128 | |||
129 | static int playpaq_wm8510_hw_params(struct snd_pcm_substream *substream, | ||
130 | struct snd_pcm_hw_params *params) | ||
131 | { | ||
132 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
133 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
134 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
135 | struct at32_ssc_info *ssc_p = snd_soc_dai_get_drvdata(cpu_dai); | ||
136 | struct ssc_device *ssc = ssc_p->ssc; | ||
137 | unsigned int pll_out = 0, bclk = 0, mclk_div = 0; | ||
138 | int ret; | ||
139 | |||
140 | |||
141 | /* Due to difficulties with getting the correct clocks from the AT32's | ||
142 | * PLL0, we're going to let the CODEC be in charge of all the clocks | ||
143 | */ | ||
144 | #if !defined CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE | ||
145 | const unsigned int fmt = (SND_SOC_DAIFMT_I2S | | ||
146 | SND_SOC_DAIFMT_NB_NF | | ||
147 | SND_SOC_DAIFMT_CBM_CFM); | ||
148 | #else | ||
149 | struct ssc_clock_data cd; | ||
150 | const unsigned int fmt = (SND_SOC_DAIFMT_I2S | | ||
151 | SND_SOC_DAIFMT_NB_NF | | ||
152 | SND_SOC_DAIFMT_CBS_CFS); | ||
153 | #endif | ||
154 | |||
155 | if (ssc == NULL) { | ||
156 | pr_warning("playpaq_wm8510_hw_params: ssc is NULL!\n"); | ||
157 | return -EINVAL; | ||
158 | } | ||
159 | |||
160 | |||
161 | /* | ||
162 | * Figure out PLL and BCLK dividers for WM8510 | ||
163 | */ | ||
164 | switch (params_rate(params)) { | ||
165 | case 48000: | ||
166 | pll_out = 24576000; | ||
167 | mclk_div = WM8510_MCLKDIV_2; | ||
168 | bclk = WM8510_BCLKDIV_8; | ||
169 | break; | ||
170 | |||
171 | case 44100: | ||
172 | pll_out = 22579200; | ||
173 | mclk_div = WM8510_MCLKDIV_2; | ||
174 | bclk = WM8510_BCLKDIV_8; | ||
175 | break; | ||
176 | |||
177 | case 22050: | ||
178 | pll_out = 22579200; | ||
179 | mclk_div = WM8510_MCLKDIV_4; | ||
180 | bclk = WM8510_BCLKDIV_8; | ||
181 | break; | ||
182 | |||
183 | case 16000: | ||
184 | pll_out = 24576000; | ||
185 | mclk_div = WM8510_MCLKDIV_6; | ||
186 | bclk = WM8510_BCLKDIV_8; | ||
187 | break; | ||
188 | |||
189 | case 11025: | ||
190 | pll_out = 22579200; | ||
191 | mclk_div = WM8510_MCLKDIV_8; | ||
192 | bclk = WM8510_BCLKDIV_8; | ||
193 | break; | ||
194 | |||
195 | case 8000: | ||
196 | pll_out = 24576000; | ||
197 | mclk_div = WM8510_MCLKDIV_12; | ||
198 | bclk = WM8510_BCLKDIV_8; | ||
199 | break; | ||
200 | |||
201 | default: | ||
202 | pr_warning("playpaq_wm8510: Unsupported sample rate %d\n", | ||
203 | params_rate(params)); | ||
204 | return -EINVAL; | ||
205 | } | ||
206 | |||
207 | |||
208 | /* | ||
209 | * set CPU and CODEC DAI configuration | ||
210 | */ | ||
211 | ret = snd_soc_dai_set_fmt(codec_dai, fmt); | ||
212 | if (ret < 0) { | ||
213 | pr_warning("playpaq_wm8510: " | ||
214 | "Failed to set CODEC DAI format (%d)\n", | ||
215 | ret); | ||
216 | return ret; | ||
217 | } | ||
218 | ret = snd_soc_dai_set_fmt(cpu_dai, fmt); | ||
219 | if (ret < 0) { | ||
220 | pr_warning("playpaq_wm8510: " | ||
221 | "Failed to set CPU DAI format (%d)\n", | ||
222 | ret); | ||
223 | return ret; | ||
224 | } | ||
225 | |||
226 | |||
227 | /* | ||
228 | * Set CPU clock configuration | ||
229 | */ | ||
230 | #if defined CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE | ||
231 | cd = playpaq_wm8510_calc_ssc_clock(params, cpu_dai); | ||
232 | pr_debug("playpaq_wm8510: cmr_div = %d, period = %d\n", | ||
233 | cd.cmr_div, cd.period); | ||
234 | ret = snd_soc_dai_set_clkdiv(cpu_dai, AT32_SSC_CMR_DIV, cd.cmr_div); | ||
235 | if (ret < 0) { | ||
236 | pr_warning("playpaq_wm8510: Failed to set CPU CMR_DIV (%d)\n", | ||
237 | ret); | ||
238 | return ret; | ||
239 | } | ||
240 | ret = snd_soc_dai_set_clkdiv(cpu_dai, AT32_SSC_TCMR_PERIOD, | ||
241 | cd.period); | ||
242 | if (ret < 0) { | ||
243 | pr_warning("playpaq_wm8510: " | ||
244 | "Failed to set CPU transmit period (%d)\n", | ||
245 | ret); | ||
246 | return ret; | ||
247 | } | ||
248 | #endif /* CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE */ | ||
249 | |||
250 | |||
251 | /* | ||
252 | * Set CODEC clock configuration | ||
253 | */ | ||
254 | pr_debug("playpaq_wm8510: " | ||
255 | "pll_in = %ld, pll_out = %u, bclk = %x, mclk = %x\n", | ||
256 | clk_get_rate(CODEC_CLK), pll_out, bclk, mclk_div); | ||
257 | |||
258 | |||
259 | #if !defined CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE | ||
260 | ret = snd_soc_dai_set_clkdiv(codec_dai, WM8510_BCLKDIV, bclk); | ||
261 | if (ret < 0) { | ||
262 | pr_warning | ||
263 | ("playpaq_wm8510: Failed to set CODEC DAI BCLKDIV (%d)\n", | ||
264 | ret); | ||
265 | return ret; | ||
266 | } | ||
267 | #endif /* CONFIG_SND_AT32_SOC_PLAYPAQ_SLAVE */ | ||
268 | |||
269 | |||
270 | ret = snd_soc_dai_set_pll(codec_dai, 0, 0, | ||
271 | clk_get_rate(CODEC_CLK), pll_out); | ||
272 | if (ret < 0) { | ||
273 | pr_warning("playpaq_wm8510: Failed to set CODEC DAI PLL (%d)\n", | ||
274 | ret); | ||
275 | return ret; | ||
276 | } | ||
277 | |||
278 | |||
279 | ret = snd_soc_dai_set_clkdiv(codec_dai, WM8510_MCLKDIV, mclk_div); | ||
280 | if (ret < 0) { | ||
281 | pr_warning("playpaq_wm8510: Failed to set CODEC MCLKDIV (%d)\n", | ||
282 | ret); | ||
283 | return ret; | ||
284 | } | ||
285 | |||
286 | |||
287 | return 0; | ||
288 | } | ||
289 | |||
290 | |||
291 | |||
292 | static struct snd_soc_ops playpaq_wm8510_ops = { | ||
293 | .hw_params = playpaq_wm8510_hw_params, | ||
294 | }; | ||
295 | |||
296 | |||
297 | |||
298 | static const struct snd_soc_dapm_widget playpaq_dapm_widgets[] = { | ||
299 | SND_SOC_DAPM_MIC("Int Mic", NULL), | ||
300 | SND_SOC_DAPM_SPK("Ext Spk", NULL), | ||
301 | }; | ||
302 | |||
303 | |||
304 | |||
305 | static const struct snd_soc_dapm_route intercon[] = { | ||
306 | /* speaker connected to SPKOUT */ | ||
307 | {"Ext Spk", NULL, "SPKOUTP"}, | ||
308 | {"Ext Spk", NULL, "SPKOUTN"}, | ||
309 | |||
310 | {"Mic Bias", NULL, "Int Mic"}, | ||
311 | {"MICN", NULL, "Mic Bias"}, | ||
312 | {"MICP", NULL, "Mic Bias"}, | ||
313 | }; | ||
314 | |||
315 | |||
316 | |||
317 | static int playpaq_wm8510_init(struct snd_soc_pcm_runtime *rtd) | ||
318 | { | ||
319 | struct snd_soc_codec *codec = rtd->codec; | ||
320 | struct snd_soc_dapm_context *dapm = &codec->dapm; | ||
321 | int i; | ||
322 | |||
323 | /* | ||
324 | * Add DAPM widgets | ||
325 | */ | ||
326 | for (i = 0; i < ARRAY_SIZE(playpaq_dapm_widgets); i++) | ||
327 | snd_soc_dapm_new_control(dapm, &playpaq_dapm_widgets[i]); | ||
328 | |||
329 | |||
330 | |||
331 | /* | ||
332 | * Setup audio path interconnects | ||
333 | */ | ||
334 | snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon)); | ||
335 | |||
336 | |||
337 | |||
338 | /* always connected pins */ | ||
339 | snd_soc_dapm_enable_pin(dapm, "Int Mic"); | ||
340 | snd_soc_dapm_enable_pin(dapm, "Ext Spk"); | ||
341 | |||
342 | |||
343 | |||
344 | /* Make CSB show PLL rate */ | ||
345 | snd_soc_dai_set_clkdiv(rtd->codec_dai, WM8510_OPCLKDIV, | ||
346 | WM8510_OPCLKDIV_1 | 4); | ||
347 | |||
348 | return 0; | ||
349 | } | ||
350 | |||
351 | |||
352 | |||
353 | static struct snd_soc_dai_link playpaq_wm8510_dai = { | ||
354 | .name = "WM8510", | ||
355 | .stream_name = "WM8510 PCM", | ||
356 | .cpu_dai_name= "atmel-ssc-dai.0", | ||
357 | .platform_name = "atmel-pcm-audio", | ||
358 | .codec_name = "wm8510-codec.0-0x1a", | ||
359 | .codec_dai_name = "wm8510-hifi", | ||
360 | .init = playpaq_wm8510_init, | ||
361 | .ops = &playpaq_wm8510_ops, | ||
362 | }; | ||
363 | |||
364 | |||
365 | |||
366 | static struct snd_soc_card snd_soc_playpaq = { | ||
367 | .name = "LRS_PlayPaq_WM8510", | ||
368 | .dai_link = &playpaq_wm8510_dai, | ||
369 | .num_links = 1, | ||
370 | }; | ||
371 | |||
372 | static struct platform_device *playpaq_snd_device; | ||
373 | |||
374 | |||
375 | static int __init playpaq_asoc_init(void) | ||
376 | { | ||
377 | int ret = 0; | ||
378 | |||
379 | /* | ||
380 | * Configure MCLK for WM8510 | ||
381 | */ | ||
382 | _gclk0 = clk_get(NULL, "gclk0"); | ||
383 | if (IS_ERR(_gclk0)) { | ||
384 | _gclk0 = NULL; | ||
385 | ret = PTR_ERR(_gclk0); | ||
386 | goto err_gclk0; | ||
387 | } | ||
388 | _pll0 = clk_get(NULL, "pll0"); | ||
389 | if (IS_ERR(_pll0)) { | ||
390 | _pll0 = NULL; | ||
391 | ret = PTR_ERR(_pll0); | ||
392 | goto err_pll0; | ||
393 | } | ||
394 | ret = clk_set_parent(_gclk0, _pll0); | ||
395 | if (ret) { | ||
396 | pr_warning("snd-soc-playpaq: " | ||
397 | "Failed to set PLL0 as parent for DAC clock\n"); | ||
398 | goto err_set_clk; | ||
399 | } | ||
400 | clk_set_rate(CODEC_CLK, 12000000); | ||
401 | clk_enable(CODEC_CLK); | ||
402 | |||
403 | #if defined CONFIG_AT32_ENHANCED_PORTMUX | ||
404 | at32_select_periph(MCLK_PIN, MCLK_PERIPH, 0); | ||
405 | #endif | ||
406 | |||
407 | |||
408 | /* | ||
409 | * Create and register platform device | ||
410 | */ | ||
411 | playpaq_snd_device = platform_device_alloc("soc-audio", 0); | ||
412 | if (playpaq_snd_device == NULL) { | ||
413 | ret = -ENOMEM; | ||
414 | goto err_device_alloc; | ||
415 | } | ||
416 | |||
417 | platform_set_drvdata(playpaq_snd_device, &snd_soc_playpaq); | ||
418 | |||
419 | ret = platform_device_add(playpaq_snd_device); | ||
420 | if (ret) { | ||
421 | pr_warning("playpaq_wm8510: platform_device_add failed (%d)\n", | ||
422 | ret); | ||
423 | goto err_device_add; | ||
424 | } | ||
425 | |||
426 | return 0; | ||
427 | |||
428 | |||
429 | err_device_add: | ||
430 | if (playpaq_snd_device != NULL) { | ||
431 | platform_device_put(playpaq_snd_device); | ||
432 | playpaq_snd_device = NULL; | ||
433 | } | ||
434 | err_device_alloc: | ||
435 | err_set_clk: | ||
436 | if (_pll0 != NULL) { | ||
437 | clk_put(_pll0); | ||
438 | _pll0 = NULL; | ||
439 | } | ||
440 | err_pll0: | ||
441 | if (_gclk0 != NULL) { | ||
442 | clk_put(_gclk0); | ||
443 | _gclk0 = NULL; | ||
444 | } | ||
445 | return ret; | ||
446 | } | ||
447 | |||
448 | |||
449 | static void __exit playpaq_asoc_exit(void) | ||
450 | { | ||
451 | if (_gclk0 != NULL) { | ||
452 | clk_put(_gclk0); | ||
453 | _gclk0 = NULL; | ||
454 | } | ||
455 | if (_pll0 != NULL) { | ||
456 | clk_put(_pll0); | ||
457 | _pll0 = NULL; | ||
458 | } | ||
459 | |||
460 | #if defined CONFIG_AT32_ENHANCED_PORTMUX | ||
461 | at32_free_pin(MCLK_PIN); | ||
462 | #endif | ||
463 | |||
464 | platform_device_unregister(playpaq_snd_device); | ||
465 | playpaq_snd_device = NULL; | ||
466 | } | ||
467 | |||
468 | module_init(playpaq_asoc_init); | ||
469 | module_exit(playpaq_asoc_exit); | ||
470 | |||
471 | MODULE_AUTHOR("Geoffrey Wossum <gwossum@acm.org>"); | ||
472 | MODULE_DESCRIPTION("ASoC machine driver for LRS PlayPaq"); | ||
473 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/codecs/ad1836.h b/sound/soc/codecs/ad1836.h index 444747f0db26..dd7be0dbbc58 100644 --- a/sound/soc/codecs/ad1836.h +++ b/sound/soc/codecs/ad1836.h | |||
@@ -34,7 +34,7 @@ | |||
34 | 34 | ||
35 | #define AD1836_ADC_CTRL2 13 | 35 | #define AD1836_ADC_CTRL2 13 |
36 | #define AD1836_ADC_WORD_LEN_MASK 0x30 | 36 | #define AD1836_ADC_WORD_LEN_MASK 0x30 |
37 | #define AD1836_ADC_WORD_OFFSET 5 | 37 | #define AD1836_ADC_WORD_OFFSET 4 |
38 | #define AD1836_ADC_SERFMT_MASK (7 << 6) | 38 | #define AD1836_ADC_SERFMT_MASK (7 << 6) |
39 | #define AD1836_ADC_SERFMT_PCK256 (0x4 << 6) | 39 | #define AD1836_ADC_SERFMT_PCK256 (0x4 << 6) |
40 | #define AD1836_ADC_SERFMT_PCK128 (0x5 << 6) | 40 | #define AD1836_ADC_SERFMT_PCK128 (0x5 << 6) |
diff --git a/sound/soc/codecs/adau1373.c b/sound/soc/codecs/adau1373.c index 1ccf8dd47576..45c63028b40d 100644 --- a/sound/soc/codecs/adau1373.c +++ b/sound/soc/codecs/adau1373.c | |||
@@ -245,7 +245,7 @@ static const char *adau1373_bass_hpf_cutoff_text[] = { | |||
245 | }; | 245 | }; |
246 | 246 | ||
247 | static const unsigned int adau1373_bass_tlv[] = { | 247 | static const unsigned int adau1373_bass_tlv[] = { |
248 | TLV_DB_RANGE_HEAD(4), | 248 | TLV_DB_RANGE_HEAD(3), |
249 | 0, 2, TLV_DB_SCALE_ITEM(-600, 600, 1), | 249 | 0, 2, TLV_DB_SCALE_ITEM(-600, 600, 1), |
250 | 3, 4, TLV_DB_SCALE_ITEM(950, 250, 0), | 250 | 3, 4, TLV_DB_SCALE_ITEM(950, 250, 0), |
251 | 5, 7, TLV_DB_SCALE_ITEM(1400, 150, 0), | 251 | 5, 7, TLV_DB_SCALE_ITEM(1400, 150, 0), |
diff --git a/sound/soc/codecs/cs4270.c b/sound/soc/codecs/cs4270.c index f1f237ecec2a..73f46eb459f1 100644 --- a/sound/soc/codecs/cs4270.c +++ b/sound/soc/codecs/cs4270.c | |||
@@ -601,7 +601,6 @@ static int cs4270_soc_suspend(struct snd_soc_codec *codec, pm_message_t mesg) | |||
601 | static int cs4270_soc_resume(struct snd_soc_codec *codec) | 601 | static int cs4270_soc_resume(struct snd_soc_codec *codec) |
602 | { | 602 | { |
603 | struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); | 603 | struct cs4270_private *cs4270 = snd_soc_codec_get_drvdata(codec); |
604 | struct i2c_client *i2c_client = to_i2c_client(codec->dev); | ||
605 | int reg; | 604 | int reg; |
606 | 605 | ||
607 | regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies), | 606 | regulator_bulk_enable(ARRAY_SIZE(cs4270->supplies), |
@@ -612,14 +611,7 @@ static int cs4270_soc_resume(struct snd_soc_codec *codec) | |||
612 | ndelay(500); | 611 | ndelay(500); |
613 | 612 | ||
614 | /* first restore the entire register cache ... */ | 613 | /* first restore the entire register cache ... */ |
615 | for (reg = CS4270_FIRSTREG; reg <= CS4270_LASTREG; reg++) { | 614 | snd_soc_cache_sync(codec); |
616 | u8 val = snd_soc_read(codec, reg); | ||
617 | |||
618 | if (i2c_smbus_write_byte_data(i2c_client, reg, val)) { | ||
619 | dev_err(codec->dev, "i2c write failed\n"); | ||
620 | return -EIO; | ||
621 | } | ||
622 | } | ||
623 | 615 | ||
624 | /* ... then disable the power-down bits */ | 616 | /* ... then disable the power-down bits */ |
625 | reg = snd_soc_read(codec, CS4270_PWRCTL); | 617 | reg = snd_soc_read(codec, CS4270_PWRCTL); |
diff --git a/sound/soc/codecs/cs4271.c b/sound/soc/codecs/cs4271.c index 23d1bd5dadda..69fde1506fe1 100644 --- a/sound/soc/codecs/cs4271.c +++ b/sound/soc/codecs/cs4271.c | |||
@@ -434,7 +434,8 @@ static int cs4271_soc_suspend(struct snd_soc_codec *codec, pm_message_t mesg) | |||
434 | { | 434 | { |
435 | int ret; | 435 | int ret; |
436 | /* Set power-down bit */ | 436 | /* Set power-down bit */ |
437 | ret = snd_soc_update_bits(codec, CS4271_MODE2, 0, CS4271_MODE2_PDN); | 437 | ret = snd_soc_update_bits(codec, CS4271_MODE2, CS4271_MODE2_PDN, |
438 | CS4271_MODE2_PDN); | ||
438 | if (ret < 0) | 439 | if (ret < 0) |
439 | return ret; | 440 | return ret; |
440 | return 0; | 441 | return 0; |
@@ -501,8 +502,9 @@ static int cs4271_probe(struct snd_soc_codec *codec) | |||
501 | return ret; | 502 | return ret; |
502 | } | 503 | } |
503 | 504 | ||
504 | ret = snd_soc_update_bits(codec, CS4271_MODE2, 0, | 505 | ret = snd_soc_update_bits(codec, CS4271_MODE2, |
505 | CS4271_MODE2_PDN | CS4271_MODE2_CPEN); | 506 | CS4271_MODE2_PDN | CS4271_MODE2_CPEN, |
507 | CS4271_MODE2_PDN | CS4271_MODE2_CPEN); | ||
506 | if (ret < 0) | 508 | if (ret < 0) |
507 | return ret; | 509 | return ret; |
508 | ret = snd_soc_update_bits(codec, CS4271_MODE2, CS4271_MODE2_PDN, 0); | 510 | ret = snd_soc_update_bits(codec, CS4271_MODE2, CS4271_MODE2_PDN, 0); |
diff --git a/sound/soc/codecs/cs42l51.c b/sound/soc/codecs/cs42l51.c index 8c3c8205d19e..1ee66361f61b 100644 --- a/sound/soc/codecs/cs42l51.c +++ b/sound/soc/codecs/cs42l51.c | |||
@@ -555,7 +555,7 @@ static int cs42l51_probe(struct snd_soc_codec *codec) | |||
555 | 555 | ||
556 | static struct snd_soc_codec_driver soc_codec_device_cs42l51 = { | 556 | static struct snd_soc_codec_driver soc_codec_device_cs42l51 = { |
557 | .probe = cs42l51_probe, | 557 | .probe = cs42l51_probe, |
558 | .reg_cache_size = CS42L51_NUMREGS, | 558 | .reg_cache_size = CS42L51_NUMREGS + 1, |
559 | .reg_word_size = sizeof(u8), | 559 | .reg_word_size = sizeof(u8), |
560 | }; | 560 | }; |
561 | 561 | ||
diff --git a/sound/soc/codecs/max9877.c b/sound/soc/codecs/max9877.c index 9e7e964a5fa3..dcf6f2a1600a 100644 --- a/sound/soc/codecs/max9877.c +++ b/sound/soc/codecs/max9877.c | |||
@@ -106,13 +106,13 @@ static int max9877_set_2reg(struct snd_kcontrol *kcontrol, | |||
106 | unsigned int mask = mc->max; | 106 | unsigned int mask = mc->max; |
107 | unsigned int val = (ucontrol->value.integer.value[0] & mask); | 107 | unsigned int val = (ucontrol->value.integer.value[0] & mask); |
108 | unsigned int val2 = (ucontrol->value.integer.value[1] & mask); | 108 | unsigned int val2 = (ucontrol->value.integer.value[1] & mask); |
109 | unsigned int change = 1; | 109 | unsigned int change = 0; |
110 | 110 | ||
111 | if (((max9877_regs[reg] >> shift) & mask) == val) | 111 | if (((max9877_regs[reg] >> shift) & mask) != val) |
112 | change = 0; | 112 | change = 1; |
113 | 113 | ||
114 | if (((max9877_regs[reg2] >> shift) & mask) == val2) | 114 | if (((max9877_regs[reg2] >> shift) & mask) != val2) |
115 | change = 0; | 115 | change = 1; |
116 | 116 | ||
117 | if (change) { | 117 | if (change) { |
118 | max9877_regs[reg] &= ~(mask << shift); | 118 | max9877_regs[reg] &= ~(mask << shift); |
diff --git a/sound/soc/codecs/rt5631.c b/sound/soc/codecs/rt5631.c index 27a078cbb6eb..4646e808b90a 100644 --- a/sound/soc/codecs/rt5631.c +++ b/sound/soc/codecs/rt5631.c | |||
@@ -177,7 +177,7 @@ static const DECLARE_TLV_DB_SCALE(dac_vol_tlv, -95625, 375, 0); | |||
177 | static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0); | 177 | static const DECLARE_TLV_DB_SCALE(in_vol_tlv, -3450, 150, 0); |
178 | /* {0, +20, +24, +30, +35, +40, +44, +50, +52}dB */ | 178 | /* {0, +20, +24, +30, +35, +40, +44, +50, +52}dB */ |
179 | static unsigned int mic_bst_tlv[] = { | 179 | static unsigned int mic_bst_tlv[] = { |
180 | TLV_DB_RANGE_HEAD(6), | 180 | TLV_DB_RANGE_HEAD(7), |
181 | 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), | 181 | 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), |
182 | 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0), | 182 | 1, 1, TLV_DB_SCALE_ITEM(2000, 0, 0), |
183 | 2, 2, TLV_DB_SCALE_ITEM(2400, 0, 0), | 183 | 2, 2, TLV_DB_SCALE_ITEM(2400, 0, 0), |
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index d15695d1c273..bbcf921166f7 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c | |||
@@ -365,7 +365,7 @@ static const DECLARE_TLV_DB_SCALE(capture_6db_attenuate, -600, 600, 0); | |||
365 | 365 | ||
366 | /* tlv for mic gain, 0db 20db 30db 40db */ | 366 | /* tlv for mic gain, 0db 20db 30db 40db */ |
367 | static const unsigned int mic_gain_tlv[] = { | 367 | static const unsigned int mic_gain_tlv[] = { |
368 | TLV_DB_RANGE_HEAD(4), | 368 | TLV_DB_RANGE_HEAD(2), |
369 | 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), | 369 | 0, 0, TLV_DB_SCALE_ITEM(0, 0, 0), |
370 | 1, 3, TLV_DB_SCALE_ITEM(2000, 1000, 0), | 370 | 1, 3, TLV_DB_SCALE_ITEM(2000, 1000, 0), |
371 | }; | 371 | }; |
diff --git a/sound/soc/codecs/sta32x.c b/sound/soc/codecs/sta32x.c index bb82408ab8e1..d2f37152f940 100644 --- a/sound/soc/codecs/sta32x.c +++ b/sound/soc/codecs/sta32x.c | |||
@@ -76,6 +76,8 @@ struct sta32x_priv { | |||
76 | 76 | ||
77 | unsigned int mclk; | 77 | unsigned int mclk; |
78 | unsigned int format; | 78 | unsigned int format; |
79 | |||
80 | u32 coef_shadow[STA32X_COEF_COUNT]; | ||
79 | }; | 81 | }; |
80 | 82 | ||
81 | static const DECLARE_TLV_DB_SCALE(mvol_tlv, -12700, 50, 1); | 83 | static const DECLARE_TLV_DB_SCALE(mvol_tlv, -12700, 50, 1); |
@@ -227,6 +229,7 @@ static int sta32x_coefficient_put(struct snd_kcontrol *kcontrol, | |||
227 | struct snd_ctl_elem_value *ucontrol) | 229 | struct snd_ctl_elem_value *ucontrol) |
228 | { | 230 | { |
229 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); | 231 | struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); |
232 | struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec); | ||
230 | int numcoef = kcontrol->private_value >> 16; | 233 | int numcoef = kcontrol->private_value >> 16; |
231 | int index = kcontrol->private_value & 0xffff; | 234 | int index = kcontrol->private_value & 0xffff; |
232 | unsigned int cfud; | 235 | unsigned int cfud; |
@@ -239,6 +242,11 @@ static int sta32x_coefficient_put(struct snd_kcontrol *kcontrol, | |||
239 | snd_soc_write(codec, STA32X_CFUD, cfud); | 242 | snd_soc_write(codec, STA32X_CFUD, cfud); |
240 | 243 | ||
241 | snd_soc_write(codec, STA32X_CFADDR2, index); | 244 | snd_soc_write(codec, STA32X_CFADDR2, index); |
245 | for (i = 0; i < numcoef && (index + i < STA32X_COEF_COUNT); i++) | ||
246 | sta32x->coef_shadow[index + i] = | ||
247 | (ucontrol->value.bytes.data[3 * i] << 16) | ||
248 | | (ucontrol->value.bytes.data[3 * i + 1] << 8) | ||
249 | | (ucontrol->value.bytes.data[3 * i + 2]); | ||
242 | for (i = 0; i < 3 * numcoef; i++) | 250 | for (i = 0; i < 3 * numcoef; i++) |
243 | snd_soc_write(codec, STA32X_B1CF1 + i, | 251 | snd_soc_write(codec, STA32X_B1CF1 + i, |
244 | ucontrol->value.bytes.data[i]); | 252 | ucontrol->value.bytes.data[i]); |
@@ -252,6 +260,48 @@ static int sta32x_coefficient_put(struct snd_kcontrol *kcontrol, | |||
252 | return 0; | 260 | return 0; |
253 | } | 261 | } |
254 | 262 | ||
263 | int sta32x_sync_coef_shadow(struct snd_soc_codec *codec) | ||
264 | { | ||
265 | struct sta32x_priv *sta32x = snd_soc_codec_get_drvdata(codec); | ||
266 | unsigned int cfud; | ||
267 | int i; | ||
268 | |||
269 | /* preserve reserved bits in STA32X_CFUD */ | ||
270 | cfud = snd_soc_read(codec, STA32X_CFUD) & 0xf0; | ||
271 | |||
272 | for (i = 0; i < STA32X_COEF_COUNT; i++) { | ||
273 | snd_soc_write(codec, STA32X_CFADDR2, i); | ||
274 | snd_soc_write(codec, STA32X_B1CF1, | ||
275 | (sta32x->coef_shadow[i] >> 16) & 0xff); | ||
276 | snd_soc_write(codec, STA32X_B1CF2, | ||
277 | (sta32x->coef_shadow[i] >> 8) & 0xff); | ||
278 | snd_soc_write(codec, STA32X_B1CF3, | ||
279 | (sta32x->coef_shadow[i]) & 0xff); | ||
280 | /* chip documentation does not say if the bits are | ||
281 | * self-clearing, so do it explicitly */ | ||
282 | snd_soc_write(codec, STA32X_CFUD, cfud); | ||
283 | snd_soc_write(codec, STA32X_CFUD, cfud | 0x01); | ||
284 | } | ||
285 | return 0; | ||
286 | } | ||
287 | |||
288 | int sta32x_cache_sync(struct snd_soc_codec *codec) | ||
289 | { | ||
290 | unsigned int mute; | ||
291 | int rc; | ||
292 | |||
293 | if (!codec->cache_sync) | ||
294 | return 0; | ||
295 | |||
296 | /* mute during register sync */ | ||
297 | mute = snd_soc_read(codec, STA32X_MMUTE); | ||
298 | snd_soc_write(codec, STA32X_MMUTE, mute | STA32X_MMUTE_MMUTE); | ||
299 | sta32x_sync_coef_shadow(codec); | ||
300 | rc = snd_soc_cache_sync(codec); | ||
301 | snd_soc_write(codec, STA32X_MMUTE, mute); | ||
302 | return rc; | ||
303 | } | ||
304 | |||
255 | #define SINGLE_COEF(xname, index) \ | 305 | #define SINGLE_COEF(xname, index) \ |
256 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ | 306 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \ |
257 | .info = sta32x_coefficient_info, \ | 307 | .info = sta32x_coefficient_info, \ |
@@ -661,7 +711,7 @@ static int sta32x_set_bias_level(struct snd_soc_codec *codec, | |||
661 | return ret; | 711 | return ret; |
662 | } | 712 | } |
663 | 713 | ||
664 | snd_soc_cache_sync(codec); | 714 | sta32x_cache_sync(codec); |
665 | } | 715 | } |
666 | 716 | ||
667 | /* Power up to mute */ | 717 | /* Power up to mute */ |
@@ -790,6 +840,17 @@ static int sta32x_probe(struct snd_soc_codec *codec) | |||
790 | STA32X_CxCFG_OM_MASK, | 840 | STA32X_CxCFG_OM_MASK, |
791 | 2 << STA32X_CxCFG_OM_SHIFT); | 841 | 2 << STA32X_CxCFG_OM_SHIFT); |
792 | 842 | ||
843 | /* initialize coefficient shadow RAM with reset values */ | ||
844 | for (i = 4; i <= 49; i += 5) | ||
845 | sta32x->coef_shadow[i] = 0x400000; | ||
846 | for (i = 50; i <= 54; i++) | ||
847 | sta32x->coef_shadow[i] = 0x7fffff; | ||
848 | sta32x->coef_shadow[55] = 0x5a9df7; | ||
849 | sta32x->coef_shadow[56] = 0x7fffff; | ||
850 | sta32x->coef_shadow[59] = 0x7fffff; | ||
851 | sta32x->coef_shadow[60] = 0x400000; | ||
852 | sta32x->coef_shadow[61] = 0x400000; | ||
853 | |||
793 | sta32x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); | 854 | sta32x_set_bias_level(codec, SND_SOC_BIAS_STANDBY); |
794 | /* Bias level configuration will have done an extra enable */ | 855 | /* Bias level configuration will have done an extra enable */ |
795 | regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies); | 856 | regulator_bulk_disable(ARRAY_SIZE(sta32x->supplies), sta32x->supplies); |
diff --git a/sound/soc/codecs/sta32x.h b/sound/soc/codecs/sta32x.h index b97ee5a75667..d8e32a6262ee 100644 --- a/sound/soc/codecs/sta32x.h +++ b/sound/soc/codecs/sta32x.h | |||
@@ -19,6 +19,7 @@ | |||
19 | /* STA326 register addresses */ | 19 | /* STA326 register addresses */ |
20 | 20 | ||
21 | #define STA32X_REGISTER_COUNT 0x2d | 21 | #define STA32X_REGISTER_COUNT 0x2d |
22 | #define STA32X_COEF_COUNT 62 | ||
22 | 23 | ||
23 | #define STA32X_CONFA 0x00 | 24 | #define STA32X_CONFA 0x00 |
24 | #define STA32X_CONFB 0x01 | 25 | #define STA32X_CONFB 0x01 |
diff --git a/sound/soc/codecs/uda1380.c b/sound/soc/codecs/uda1380.c index c5ca8cfea60f..0441893e270e 100644 --- a/sound/soc/codecs/uda1380.c +++ b/sound/soc/codecs/uda1380.c | |||
@@ -863,13 +863,13 @@ static struct i2c_driver uda1380_i2c_driver = { | |||
863 | 863 | ||
864 | static int __init uda1380_modinit(void) | 864 | static int __init uda1380_modinit(void) |
865 | { | 865 | { |
866 | int ret; | 866 | int ret = 0; |
867 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) | 867 | #if defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE) |
868 | ret = i2c_add_driver(&uda1380_i2c_driver); | 868 | ret = i2c_add_driver(&uda1380_i2c_driver); |
869 | if (ret != 0) | 869 | if (ret != 0) |
870 | pr_err("Failed to register UDA1380 I2C driver: %d\n", ret); | 870 | pr_err("Failed to register UDA1380 I2C driver: %d\n", ret); |
871 | #endif | 871 | #endif |
872 | return 0; | 872 | return ret; |
873 | } | 873 | } |
874 | module_init(uda1380_modinit); | 874 | module_init(uda1380_modinit); |
875 | 875 | ||
diff --git a/sound/soc/codecs/wm8731.c b/sound/soc/codecs/wm8731.c index 7e5ec03f6f8d..a7c9ae17fc7e 100644 --- a/sound/soc/codecs/wm8731.c +++ b/sound/soc/codecs/wm8731.c | |||
@@ -453,6 +453,7 @@ static int wm8731_set_bias_level(struct snd_soc_codec *codec, | |||
453 | snd_soc_write(codec, WM8731_PWR, 0xffff); | 453 | snd_soc_write(codec, WM8731_PWR, 0xffff); |
454 | regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), | 454 | regulator_bulk_disable(ARRAY_SIZE(wm8731->supplies), |
455 | wm8731->supplies); | 455 | wm8731->supplies); |
456 | codec->cache_sync = 1; | ||
456 | break; | 457 | break; |
457 | } | 458 | } |
458 | codec->dapm.bias_level = level; | 459 | codec->dapm.bias_level = level; |
diff --git a/sound/soc/codecs/wm8753.c b/sound/soc/codecs/wm8753.c index a9504710bb69..3a629d0d690e 100644 --- a/sound/soc/codecs/wm8753.c +++ b/sound/soc/codecs/wm8753.c | |||
@@ -190,6 +190,9 @@ static int wm8753_set_dai(struct snd_kcontrol *kcontrol, | |||
190 | struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); | 190 | struct wm8753_priv *wm8753 = snd_soc_codec_get_drvdata(codec); |
191 | u16 ioctl; | 191 | u16 ioctl; |
192 | 192 | ||
193 | if (wm8753->dai_func == ucontrol->value.integer.value[0]) | ||
194 | return 0; | ||
195 | |||
193 | if (codec->active) | 196 | if (codec->active) |
194 | return -EBUSY; | 197 | return -EBUSY; |
195 | 198 | ||
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index 91d3c6dbeba3..53edd9a8c758 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c | |||
@@ -1973,7 +1973,7 @@ static int wm8962_reset(struct snd_soc_codec *codec) | |||
1973 | static const DECLARE_TLV_DB_SCALE(inpga_tlv, -2325, 75, 0); | 1973 | static const DECLARE_TLV_DB_SCALE(inpga_tlv, -2325, 75, 0); |
1974 | static const DECLARE_TLV_DB_SCALE(mixin_tlv, -1500, 300, 0); | 1974 | static const DECLARE_TLV_DB_SCALE(mixin_tlv, -1500, 300, 0); |
1975 | static const unsigned int mixinpga_tlv[] = { | 1975 | static const unsigned int mixinpga_tlv[] = { |
1976 | TLV_DB_RANGE_HEAD(7), | 1976 | TLV_DB_RANGE_HEAD(5), |
1977 | 0, 1, TLV_DB_SCALE_ITEM(0, 600, 0), | 1977 | 0, 1, TLV_DB_SCALE_ITEM(0, 600, 0), |
1978 | 2, 2, TLV_DB_SCALE_ITEM(1300, 1300, 0), | 1978 | 2, 2, TLV_DB_SCALE_ITEM(1300, 1300, 0), |
1979 | 3, 4, TLV_DB_SCALE_ITEM(1800, 200, 0), | 1979 | 3, 4, TLV_DB_SCALE_ITEM(1800, 200, 0), |
@@ -1988,7 +1988,7 @@ static const DECLARE_TLV_DB_SCALE(bypass_tlv, -1500, 300, 0); | |||
1988 | static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1); | 1988 | static const DECLARE_TLV_DB_SCALE(out_tlv, -12100, 100, 1); |
1989 | static const DECLARE_TLV_DB_SCALE(hp_tlv, -700, 100, 0); | 1989 | static const DECLARE_TLV_DB_SCALE(hp_tlv, -700, 100, 0); |
1990 | static const unsigned int classd_tlv[] = { | 1990 | static const unsigned int classd_tlv[] = { |
1991 | TLV_DB_RANGE_HEAD(7), | 1991 | TLV_DB_RANGE_HEAD(2), |
1992 | 0, 6, TLV_DB_SCALE_ITEM(0, 150, 0), | 1992 | 0, 6, TLV_DB_SCALE_ITEM(0, 150, 0), |
1993 | 7, 7, TLV_DB_SCALE_ITEM(1200, 0, 0), | 1993 | 7, 7, TLV_DB_SCALE_ITEM(1200, 0, 0), |
1994 | }; | 1994 | }; |
diff --git a/sound/soc/codecs/wm8993.c b/sound/soc/codecs/wm8993.c index eec8e1435116..d1a142f48b09 100644 --- a/sound/soc/codecs/wm8993.c +++ b/sound/soc/codecs/wm8993.c | |||
@@ -512,7 +512,7 @@ static const DECLARE_TLV_DB_SCALE(drc_comp_threash, -4500, 75, 0); | |||
512 | static const DECLARE_TLV_DB_SCALE(drc_comp_amp, -2250, 75, 0); | 512 | static const DECLARE_TLV_DB_SCALE(drc_comp_amp, -2250, 75, 0); |
513 | static const DECLARE_TLV_DB_SCALE(drc_min_tlv, -1800, 600, 0); | 513 | static const DECLARE_TLV_DB_SCALE(drc_min_tlv, -1800, 600, 0); |
514 | static const unsigned int drc_max_tlv[] = { | 514 | static const unsigned int drc_max_tlv[] = { |
515 | TLV_DB_RANGE_HEAD(4), | 515 | TLV_DB_RANGE_HEAD(2), |
516 | 0, 2, TLV_DB_SCALE_ITEM(1200, 600, 0), | 516 | 0, 2, TLV_DB_SCALE_ITEM(1200, 600, 0), |
517 | 3, 3, TLV_DB_SCALE_ITEM(3600, 0, 0), | 517 | 3, 3, TLV_DB_SCALE_ITEM(3600, 0, 0), |
518 | }; | 518 | }; |
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 9c982e47eb99..d0c545b73d78 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c | |||
@@ -1325,15 +1325,15 @@ SND_SOC_DAPM_DAC("DAC1R", NULL, WM8994_POWER_MANAGEMENT_5, 0, 0), | |||
1325 | }; | 1325 | }; |
1326 | 1326 | ||
1327 | static const struct snd_soc_dapm_widget wm8994_adc_revd_widgets[] = { | 1327 | static const struct snd_soc_dapm_widget wm8994_adc_revd_widgets[] = { |
1328 | SND_SOC_DAPM_MUX_E("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux, | 1328 | SND_SOC_DAPM_VIRT_MUX_E("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux, |
1329 | adc_mux_ev, SND_SOC_DAPM_PRE_PMU), | 1329 | adc_mux_ev, SND_SOC_DAPM_PRE_PMU), |
1330 | SND_SOC_DAPM_MUX_E("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux, | 1330 | SND_SOC_DAPM_VIRT_MUX_E("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux, |
1331 | adc_mux_ev, SND_SOC_DAPM_PRE_PMU), | 1331 | adc_mux_ev, SND_SOC_DAPM_PRE_PMU), |
1332 | }; | 1332 | }; |
1333 | 1333 | ||
1334 | static const struct snd_soc_dapm_widget wm8994_adc_widgets[] = { | 1334 | static const struct snd_soc_dapm_widget wm8994_adc_widgets[] = { |
1335 | SND_SOC_DAPM_MUX("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux), | 1335 | SND_SOC_DAPM_VIRT_MUX("ADCL Mux", WM8994_POWER_MANAGEMENT_4, 1, 0, &adcl_mux), |
1336 | SND_SOC_DAPM_MUX("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux), | 1336 | SND_SOC_DAPM_VIRT_MUX("ADCR Mux", WM8994_POWER_MANAGEMENT_4, 0, 0, &adcr_mux), |
1337 | }; | 1337 | }; |
1338 | 1338 | ||
1339 | static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = { | 1339 | static const struct snd_soc_dapm_widget wm8994_dapm_widgets[] = { |
@@ -2357,6 +2357,11 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream, | |||
2357 | bclk |= best << WM8994_AIF1_BCLK_DIV_SHIFT; | 2357 | bclk |= best << WM8994_AIF1_BCLK_DIV_SHIFT; |
2358 | 2358 | ||
2359 | lrclk = bclk_rate / params_rate(params); | 2359 | lrclk = bclk_rate / params_rate(params); |
2360 | if (!lrclk) { | ||
2361 | dev_err(dai->dev, "Unable to generate LRCLK from %dHz BCLK\n", | ||
2362 | bclk_rate); | ||
2363 | return -EINVAL; | ||
2364 | } | ||
2360 | dev_dbg(dai->dev, "Using LRCLK rate %d for actual LRCLK %dHz\n", | 2365 | dev_dbg(dai->dev, "Using LRCLK rate %d for actual LRCLK %dHz\n", |
2361 | lrclk, bclk_rate / lrclk); | 2366 | lrclk, bclk_rate / lrclk); |
2362 | 2367 | ||
@@ -3178,6 +3183,8 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
3178 | switch (wm8994->revision) { | 3183 | switch (wm8994->revision) { |
3179 | case 0: | 3184 | case 0: |
3180 | case 1: | 3185 | case 1: |
3186 | case 2: | ||
3187 | case 3: | ||
3181 | wm8994->hubs.dcs_codes_l = -9; | 3188 | wm8994->hubs.dcs_codes_l = -9; |
3182 | wm8994->hubs.dcs_codes_r = -5; | 3189 | wm8994->hubs.dcs_codes_r = -5; |
3183 | break; | 3190 | break; |
diff --git a/sound/soc/codecs/wm9081.c b/sound/soc/codecs/wm9081.c index 3cd35a02c28c..4a398c3bfe84 100644 --- a/sound/soc/codecs/wm9081.c +++ b/sound/soc/codecs/wm9081.c | |||
@@ -807,7 +807,6 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec, | |||
807 | mdelay(100); | 807 | mdelay(100); |
808 | 808 | ||
809 | /* Normal bias enable & soft start off */ | 809 | /* Normal bias enable & soft start off */ |
810 | reg |= WM9081_BIAS_ENA; | ||
811 | reg &= ~WM9081_VMID_RAMP; | 810 | reg &= ~WM9081_VMID_RAMP; |
812 | snd_soc_write(codec, WM9081_VMID_CONTROL, reg); | 811 | snd_soc_write(codec, WM9081_VMID_CONTROL, reg); |
813 | 812 | ||
@@ -818,7 +817,7 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec, | |||
818 | } | 817 | } |
819 | 818 | ||
820 | /* VMID 2*240k */ | 819 | /* VMID 2*240k */ |
821 | reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1); | 820 | reg = snd_soc_read(codec, WM9081_VMID_CONTROL); |
822 | reg &= ~WM9081_VMID_SEL_MASK; | 821 | reg &= ~WM9081_VMID_SEL_MASK; |
823 | reg |= 0x04; | 822 | reg |= 0x04; |
824 | snd_soc_write(codec, WM9081_VMID_CONTROL, reg); | 823 | snd_soc_write(codec, WM9081_VMID_CONTROL, reg); |
@@ -830,14 +829,15 @@ static int wm9081_set_bias_level(struct snd_soc_codec *codec, | |||
830 | break; | 829 | break; |
831 | 830 | ||
832 | case SND_SOC_BIAS_OFF: | 831 | case SND_SOC_BIAS_OFF: |
833 | /* Startup bias source */ | 832 | /* Startup bias source and disable bias */ |
834 | reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1); | 833 | reg = snd_soc_read(codec, WM9081_BIAS_CONTROL_1); |
835 | reg |= WM9081_BIAS_SRC; | 834 | reg |= WM9081_BIAS_SRC; |
835 | reg &= ~WM9081_BIAS_ENA; | ||
836 | snd_soc_write(codec, WM9081_BIAS_CONTROL_1, reg); | 836 | snd_soc_write(codec, WM9081_BIAS_CONTROL_1, reg); |
837 | 837 | ||
838 | /* Disable VMID and biases with soft ramping */ | 838 | /* Disable VMID with soft ramping */ |
839 | reg = snd_soc_read(codec, WM9081_VMID_CONTROL); | 839 | reg = snd_soc_read(codec, WM9081_VMID_CONTROL); |
840 | reg &= ~(WM9081_VMID_SEL_MASK | WM9081_BIAS_ENA); | 840 | reg &= ~WM9081_VMID_SEL_MASK; |
841 | reg |= WM9081_VMID_RAMP; | 841 | reg |= WM9081_VMID_RAMP; |
842 | snd_soc_write(codec, WM9081_VMID_CONTROL, reg); | 842 | snd_soc_write(codec, WM9081_VMID_CONTROL, reg); |
843 | 843 | ||
diff --git a/sound/soc/codecs/wm9090.c b/sound/soc/codecs/wm9090.c index 2b5252c9e377..f94c06057c64 100644 --- a/sound/soc/codecs/wm9090.c +++ b/sound/soc/codecs/wm9090.c | |||
@@ -177,19 +177,19 @@ static void wait_for_dc_servo(struct snd_soc_codec *codec) | |||
177 | } | 177 | } |
178 | 178 | ||
179 | static const unsigned int in_tlv[] = { | 179 | static const unsigned int in_tlv[] = { |
180 | TLV_DB_RANGE_HEAD(6), | 180 | TLV_DB_RANGE_HEAD(3), |
181 | 0, 0, TLV_DB_SCALE_ITEM(-600, 0, 0), | 181 | 0, 0, TLV_DB_SCALE_ITEM(-600, 0, 0), |
182 | 1, 3, TLV_DB_SCALE_ITEM(-350, 350, 0), | 182 | 1, 3, TLV_DB_SCALE_ITEM(-350, 350, 0), |
183 | 4, 6, TLV_DB_SCALE_ITEM(600, 600, 0), | 183 | 4, 6, TLV_DB_SCALE_ITEM(600, 600, 0), |
184 | }; | 184 | }; |
185 | static const unsigned int mix_tlv[] = { | 185 | static const unsigned int mix_tlv[] = { |
186 | TLV_DB_RANGE_HEAD(4), | 186 | TLV_DB_RANGE_HEAD(2), |
187 | 0, 2, TLV_DB_SCALE_ITEM(-1200, 300, 0), | 187 | 0, 2, TLV_DB_SCALE_ITEM(-1200, 300, 0), |
188 | 3, 3, TLV_DB_SCALE_ITEM(0, 0, 0), | 188 | 3, 3, TLV_DB_SCALE_ITEM(0, 0, 0), |
189 | }; | 189 | }; |
190 | static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0); | 190 | static const DECLARE_TLV_DB_SCALE(out_tlv, -5700, 100, 0); |
191 | static const unsigned int spkboost_tlv[] = { | 191 | static const unsigned int spkboost_tlv[] = { |
192 | TLV_DB_RANGE_HEAD(7), | 192 | TLV_DB_RANGE_HEAD(2), |
193 | 0, 6, TLV_DB_SCALE_ITEM(0, 150, 0), | 193 | 0, 6, TLV_DB_SCALE_ITEM(0, 150, 0), |
194 | 7, 7, TLV_DB_SCALE_ITEM(1200, 0, 0), | 194 | 7, 7, TLV_DB_SCALE_ITEM(1200, 0, 0), |
195 | }; | 195 | }; |
diff --git a/sound/soc/codecs/wm_hubs.c b/sound/soc/codecs/wm_hubs.c index 84f33d4ea2cd..48e61e912400 100644 --- a/sound/soc/codecs/wm_hubs.c +++ b/sound/soc/codecs/wm_hubs.c | |||
@@ -40,7 +40,7 @@ static const DECLARE_TLV_DB_SCALE(outmix_tlv, -2100, 300, 0); | |||
40 | static const DECLARE_TLV_DB_SCALE(spkmixout_tlv, -1800, 600, 1); | 40 | static const DECLARE_TLV_DB_SCALE(spkmixout_tlv, -1800, 600, 1); |
41 | static const DECLARE_TLV_DB_SCALE(outpga_tlv, -5700, 100, 0); | 41 | static const DECLARE_TLV_DB_SCALE(outpga_tlv, -5700, 100, 0); |
42 | static const unsigned int spkboost_tlv[] = { | 42 | static const unsigned int spkboost_tlv[] = { |
43 | TLV_DB_RANGE_HEAD(7), | 43 | TLV_DB_RANGE_HEAD(2), |
44 | 0, 6, TLV_DB_SCALE_ITEM(0, 150, 0), | 44 | 0, 6, TLV_DB_SCALE_ITEM(0, 150, 0), |
45 | 7, 7, TLV_DB_SCALE_ITEM(1200, 0, 0), | 45 | 7, 7, TLV_DB_SCALE_ITEM(1200, 0, 0), |
46 | }; | 46 | }; |
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c index 0268cf989736..83c4bd5b2dd7 100644 --- a/sound/soc/fsl/fsl_ssi.c +++ b/sound/soc/fsl/fsl_ssi.c | |||
@@ -694,6 +694,7 @@ static int __devinit fsl_ssi_probe(struct platform_device *pdev) | |||
694 | 694 | ||
695 | /* Initialize the the device_attribute structure */ | 695 | /* Initialize the the device_attribute structure */ |
696 | dev_attr = &ssi_private->dev_attr; | 696 | dev_attr = &ssi_private->dev_attr; |
697 | sysfs_attr_init(&dev_attr->attr); | ||
697 | dev_attr->attr.name = "statistics"; | 698 | dev_attr->attr.name = "statistics"; |
698 | dev_attr->attr.mode = S_IRUGO; | 699 | dev_attr->attr.mode = S_IRUGO; |
699 | dev_attr->show = fsl_sysfs_ssi_show; | 700 | dev_attr->show = fsl_sysfs_ssi_show; |
diff --git a/sound/soc/fsl/mpc8610_hpcd.c b/sound/soc/fsl/mpc8610_hpcd.c index 31af405bda84..ae49f1c78c6d 100644 --- a/sound/soc/fsl/mpc8610_hpcd.c +++ b/sound/soc/fsl/mpc8610_hpcd.c | |||
@@ -392,7 +392,8 @@ static int mpc8610_hpcd_probe(struct platform_device *pdev) | |||
392 | } | 392 | } |
393 | 393 | ||
394 | if (strcasecmp(sprop, "i2s-slave") == 0) { | 394 | if (strcasecmp(sprop, "i2s-slave") == 0) { |
395 | machine_data->dai_format = SND_SOC_DAIFMT_I2S; | 395 | machine_data->dai_format = |
396 | SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBM_CFM; | ||
396 | machine_data->codec_clk_direction = SND_SOC_CLOCK_OUT; | 397 | machine_data->codec_clk_direction = SND_SOC_CLOCK_OUT; |
397 | machine_data->cpu_clk_direction = SND_SOC_CLOCK_IN; | 398 | machine_data->cpu_clk_direction = SND_SOC_CLOCK_IN; |
398 | 399 | ||
@@ -409,31 +410,38 @@ static int mpc8610_hpcd_probe(struct platform_device *pdev) | |||
409 | } | 410 | } |
410 | machine_data->clk_frequency = be32_to_cpup(iprop); | 411 | machine_data->clk_frequency = be32_to_cpup(iprop); |
411 | } else if (strcasecmp(sprop, "i2s-master") == 0) { | 412 | } else if (strcasecmp(sprop, "i2s-master") == 0) { |
412 | machine_data->dai_format = SND_SOC_DAIFMT_I2S; | 413 | machine_data->dai_format = |
414 | SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_CBS_CFS; | ||
413 | machine_data->codec_clk_direction = SND_SOC_CLOCK_IN; | 415 | machine_data->codec_clk_direction = SND_SOC_CLOCK_IN; |
414 | machine_data->cpu_clk_direction = SND_SOC_CLOCK_OUT; | 416 | machine_data->cpu_clk_direction = SND_SOC_CLOCK_OUT; |
415 | } else if (strcasecmp(sprop, "lj-slave") == 0) { | 417 | } else if (strcasecmp(sprop, "lj-slave") == 0) { |
416 | machine_data->dai_format = SND_SOC_DAIFMT_LEFT_J; | 418 | machine_data->dai_format = |
419 | SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_CBM_CFM; | ||
417 | machine_data->codec_clk_direction = SND_SOC_CLOCK_OUT; | 420 | machine_data->codec_clk_direction = SND_SOC_CLOCK_OUT; |
418 | machine_data->cpu_clk_direction = SND_SOC_CLOCK_IN; | 421 | machine_data->cpu_clk_direction = SND_SOC_CLOCK_IN; |
419 | } else if (strcasecmp(sprop, "lj-master") == 0) { | 422 | } else if (strcasecmp(sprop, "lj-master") == 0) { |
420 | machine_data->dai_format = SND_SOC_DAIFMT_LEFT_J; | 423 | machine_data->dai_format = |
424 | SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_CBS_CFS; | ||
421 | machine_data->codec_clk_direction = SND_SOC_CLOCK_IN; | 425 | machine_data->codec_clk_direction = SND_SOC_CLOCK_IN; |
422 | machine_data->cpu_clk_direction = SND_SOC_CLOCK_OUT; | 426 | machine_data->cpu_clk_direction = SND_SOC_CLOCK_OUT; |
423 | } else if (strcasecmp(sprop, "rj-slave") == 0) { | 427 | } else if (strcasecmp(sprop, "rj-slave") == 0) { |
424 | machine_data->dai_format = SND_SOC_DAIFMT_RIGHT_J; | 428 | machine_data->dai_format = |
429 | SND_SOC_DAIFMT_RIGHT_J | SND_SOC_DAIFMT_CBM_CFM; | ||
425 | machine_data->codec_clk_direction = SND_SOC_CLOCK_OUT; | 430 | machine_data->codec_clk_direction = SND_SOC_CLOCK_OUT; |
426 | machine_data->cpu_clk_direction = SND_SOC_CLOCK_IN; | 431 | machine_data->cpu_clk_direction = SND_SOC_CLOCK_IN; |
427 | } else if (strcasecmp(sprop, "rj-master") == 0) { | 432 | } else if (strcasecmp(sprop, "rj-master") == 0) { |
428 | machine_data->dai_format = SND_SOC_DAIFMT_RIGHT_J; | 433 | machine_data->dai_format = |
434 | SND_SOC_DAIFMT_RIGHT_J | SND_SOC_DAIFMT_CBS_CFS; | ||
429 | machine_data->codec_clk_direction = SND_SOC_CLOCK_IN; | 435 | machine_data->codec_clk_direction = SND_SOC_CLOCK_IN; |
430 | machine_data->cpu_clk_direction = SND_SOC_CLOCK_OUT; | 436 | machine_data->cpu_clk_direction = SND_SOC_CLOCK_OUT; |
431 | } else if (strcasecmp(sprop, "ac97-slave") == 0) { | 437 | } else if (strcasecmp(sprop, "ac97-slave") == 0) { |
432 | machine_data->dai_format = SND_SOC_DAIFMT_AC97; | 438 | machine_data->dai_format = |
439 | SND_SOC_DAIFMT_AC97 | SND_SOC_DAIFMT_CBM_CFM; | ||
433 | machine_data->codec_clk_direction = SND_SOC_CLOCK_OUT; | 440 | machine_data->codec_clk_direction = SND_SOC_CLOCK_OUT; |
434 | machine_data->cpu_clk_direction = SND_SOC_CLOCK_IN; | 441 | machine_data->cpu_clk_direction = SND_SOC_CLOCK_IN; |
435 | } else if (strcasecmp(sprop, "ac97-master") == 0) { | 442 | } else if (strcasecmp(sprop, "ac97-master") == 0) { |
436 | machine_data->dai_format = SND_SOC_DAIFMT_AC97; | 443 | machine_data->dai_format = |
444 | SND_SOC_DAIFMT_AC97 | SND_SOC_DAIFMT_CBS_CFS; | ||
437 | machine_data->codec_clk_direction = SND_SOC_CLOCK_IN; | 445 | machine_data->codec_clk_direction = SND_SOC_CLOCK_IN; |
438 | machine_data->cpu_clk_direction = SND_SOC_CLOCK_OUT; | 446 | machine_data->cpu_clk_direction = SND_SOC_CLOCK_OUT; |
439 | } else { | 447 | } else { |
diff --git a/sound/soc/imx/Kconfig b/sound/soc/imx/Kconfig index b133bfcc5848..738391757f2c 100644 --- a/sound/soc/imx/Kconfig +++ b/sound/soc/imx/Kconfig | |||
@@ -28,7 +28,7 @@ config SND_MXC_SOC_WM1133_EV1 | |||
28 | 28 | ||
29 | config SND_SOC_MX27VIS_AIC32X4 | 29 | config SND_SOC_MX27VIS_AIC32X4 |
30 | tristate "SoC audio support for Visstrim M10 boards" | 30 | tristate "SoC audio support for Visstrim M10 boards" |
31 | depends on MACH_IMX27_VISSTRIM_M10 | 31 | depends on MACH_IMX27_VISSTRIM_M10 && I2C |
32 | select SND_SOC_TLV320AIC32X4 | 32 | select SND_SOC_TLV320AIC32X4 |
33 | select SND_MXC_SOC_MX2 | 33 | select SND_MXC_SOC_MX2 |
34 | help | 34 | help |
diff --git a/sound/soc/kirkwood/Kconfig b/sound/soc/kirkwood/Kconfig index 8f49e165f4d1..c62d715235e2 100644 --- a/sound/soc/kirkwood/Kconfig +++ b/sound/soc/kirkwood/Kconfig | |||
@@ -12,6 +12,7 @@ config SND_KIRKWOOD_SOC_I2S | |||
12 | config SND_KIRKWOOD_SOC_OPENRD | 12 | config SND_KIRKWOOD_SOC_OPENRD |
13 | tristate "SoC Audio support for Kirkwood Openrd Client" | 13 | tristate "SoC Audio support for Kirkwood Openrd Client" |
14 | depends on SND_KIRKWOOD_SOC && (MACH_OPENRD_CLIENT || MACH_OPENRD_ULTIMATE) | 14 | depends on SND_KIRKWOOD_SOC && (MACH_OPENRD_CLIENT || MACH_OPENRD_ULTIMATE) |
15 | depends on I2C | ||
15 | select SND_KIRKWOOD_SOC_I2S | 16 | select SND_KIRKWOOD_SOC_I2S |
16 | select SND_SOC_CS42L51 | 17 | select SND_SOC_CS42L51 |
17 | help | 18 | help |
@@ -20,7 +21,7 @@ config SND_KIRKWOOD_SOC_OPENRD | |||
20 | 21 | ||
21 | config SND_KIRKWOOD_SOC_T5325 | 22 | config SND_KIRKWOOD_SOC_T5325 |
22 | tristate "SoC Audio support for HP t5325" | 23 | tristate "SoC Audio support for HP t5325" |
23 | depends on SND_KIRKWOOD_SOC && MACH_T5325 | 24 | depends on SND_KIRKWOOD_SOC && MACH_T5325 && I2C |
24 | select SND_KIRKWOOD_SOC_I2S | 25 | select SND_KIRKWOOD_SOC_I2S |
25 | select SND_SOC_ALC5623 | 26 | select SND_SOC_ALC5623 |
26 | help | 27 | help |
diff --git a/sound/soc/pxa/Kconfig b/sound/soc/pxa/Kconfig index ffd2242e305f..a0f7d3cfa470 100644 --- a/sound/soc/pxa/Kconfig +++ b/sound/soc/pxa/Kconfig | |||
@@ -151,6 +151,7 @@ config SND_SOC_ZYLONITE | |||
151 | config SND_SOC_RAUMFELD | 151 | config SND_SOC_RAUMFELD |
152 | tristate "SoC Audio support Raumfeld audio adapter" | 152 | tristate "SoC Audio support Raumfeld audio adapter" |
153 | depends on SND_PXA2XX_SOC && (MACH_RAUMFELD_SPEAKER || MACH_RAUMFELD_CONNECTOR) | 153 | depends on SND_PXA2XX_SOC && (MACH_RAUMFELD_SPEAKER || MACH_RAUMFELD_CONNECTOR) |
154 | depends on I2C && SPI_MASTER | ||
154 | select SND_PXA_SOC_SSP | 155 | select SND_PXA_SOC_SSP |
155 | select SND_SOC_CS4270 | 156 | select SND_SOC_CS4270 |
156 | select SND_SOC_AK4104 | 157 | select SND_SOC_AK4104 |
@@ -159,7 +160,7 @@ config SND_SOC_RAUMFELD | |||
159 | 160 | ||
160 | config SND_PXA2XX_SOC_HX4700 | 161 | config SND_PXA2XX_SOC_HX4700 |
161 | tristate "SoC Audio support for HP iPAQ hx4700" | 162 | tristate "SoC Audio support for HP iPAQ hx4700" |
162 | depends on SND_PXA2XX_SOC && MACH_H4700 | 163 | depends on SND_PXA2XX_SOC && MACH_H4700 && I2C |
163 | select SND_PXA2XX_SOC_I2S | 164 | select SND_PXA2XX_SOC_I2S |
164 | select SND_SOC_AK4641 | 165 | select SND_SOC_AK4641 |
165 | help | 166 | help |
diff --git a/sound/soc/samsung/smdk_wm8994.c b/sound/soc/samsung/smdk_wm8994.c index f75e43997d5b..ad9ac42522e2 100644 --- a/sound/soc/samsung/smdk_wm8994.c +++ b/sound/soc/samsung/smdk_wm8994.c | |||
@@ -9,6 +9,7 @@ | |||
9 | 9 | ||
10 | #include "../codecs/wm8994.h" | 10 | #include "../codecs/wm8994.h" |
11 | #include <sound/pcm_params.h> | 11 | #include <sound/pcm_params.h> |
12 | #include <linux/module.h> | ||
12 | 13 | ||
13 | /* | 14 | /* |
14 | * Default CFG switch settings to use this driver: | 15 | * Default CFG switch settings to use this driver: |
diff --git a/sound/soc/samsung/speyside.c b/sound/soc/samsung/speyside.c index 85bf541a771d..4b8e35410eb1 100644 --- a/sound/soc/samsung/speyside.c +++ b/sound/soc/samsung/speyside.c | |||
@@ -191,7 +191,7 @@ static int speyside_late_probe(struct snd_soc_card *card) | |||
191 | snd_soc_dapm_ignore_suspend(&card->dapm, "Headset Mic"); | 191 | snd_soc_dapm_ignore_suspend(&card->dapm, "Headset Mic"); |
192 | snd_soc_dapm_ignore_suspend(&card->dapm, "Main AMIC"); | 192 | snd_soc_dapm_ignore_suspend(&card->dapm, "Main AMIC"); |
193 | snd_soc_dapm_ignore_suspend(&card->dapm, "Main DMIC"); | 193 | snd_soc_dapm_ignore_suspend(&card->dapm, "Main DMIC"); |
194 | snd_soc_dapm_ignore_suspend(&card->dapm, "Speaker"); | 194 | snd_soc_dapm_ignore_suspend(&card->dapm, "Main Speaker"); |
195 | snd_soc_dapm_ignore_suspend(&card->dapm, "WM1250 Output"); | 195 | snd_soc_dapm_ignore_suspend(&card->dapm, "WM1250 Output"); |
196 | snd_soc_dapm_ignore_suspend(&card->dapm, "WM1250 Input"); | 196 | snd_soc_dapm_ignore_suspend(&card->dapm, "WM1250 Input"); |
197 | 197 | ||
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index a5d3685a5d38..a25fa63ce9a2 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
@@ -709,6 +709,12 @@ int snd_soc_resume(struct device *dev) | |||
709 | struct snd_soc_card *card = dev_get_drvdata(dev); | 709 | struct snd_soc_card *card = dev_get_drvdata(dev); |
710 | int i, ac97_control = 0; | 710 | int i, ac97_control = 0; |
711 | 711 | ||
712 | /* If the initialization of this soc device failed, there is no codec | ||
713 | * associated with it. Just bail out in this case. | ||
714 | */ | ||
715 | if (list_empty(&card->codec_dev_list)) | ||
716 | return 0; | ||
717 | |||
712 | /* AC97 devices might have other drivers hanging off them so | 718 | /* AC97 devices might have other drivers hanging off them so |
713 | * need to resume immediately. Other drivers don't have that | 719 | * need to resume immediately. Other drivers don't have that |
714 | * problem and may take a substantial amount of time to resume | 720 | * problem and may take a substantial amount of time to resume |
diff --git a/sound/soc/soc-utils.c b/sound/soc/soc-utils.c index 0c12b98484bd..4220bb0f2730 100644 --- a/sound/soc/soc-utils.c +++ b/sound/soc/soc-utils.c | |||
@@ -58,7 +58,36 @@ int snd_soc_params_to_bclk(struct snd_pcm_hw_params *params) | |||
58 | } | 58 | } |
59 | EXPORT_SYMBOL_GPL(snd_soc_params_to_bclk); | 59 | EXPORT_SYMBOL_GPL(snd_soc_params_to_bclk); |
60 | 60 | ||
61 | static struct snd_soc_platform_driver dummy_platform; | 61 | static const struct snd_pcm_hardware dummy_dma_hardware = { |
62 | .formats = 0xffffffff, | ||
63 | .channels_min = 1, | ||
64 | .channels_max = UINT_MAX, | ||
65 | |||
66 | /* Random values to keep userspace happy when checking constraints */ | ||
67 | .info = SNDRV_PCM_INFO_INTERLEAVED | | ||
68 | SNDRV_PCM_INFO_BLOCK_TRANSFER, | ||
69 | .buffer_bytes_max = 128*1024, | ||
70 | .period_bytes_min = PAGE_SIZE, | ||
71 | .period_bytes_max = PAGE_SIZE*2, | ||
72 | .periods_min = 2, | ||
73 | .periods_max = 128, | ||
74 | }; | ||
75 | |||
76 | static int dummy_dma_open(struct snd_pcm_substream *substream) | ||
77 | { | ||
78 | snd_soc_set_runtime_hwparams(substream, &dummy_dma_hardware); | ||
79 | |||
80 | return 0; | ||
81 | } | ||
82 | |||
83 | static struct snd_pcm_ops dummy_dma_ops = { | ||
84 | .open = dummy_dma_open, | ||
85 | .ioctl = snd_pcm_lib_ioctl, | ||
86 | }; | ||
87 | |||
88 | static struct snd_soc_platform_driver dummy_platform = { | ||
89 | .ops = &dummy_dma_ops, | ||
90 | }; | ||
62 | 91 | ||
63 | static __devinit int snd_soc_dummy_probe(struct platform_device *pdev) | 92 | static __devinit int snd_soc_dummy_probe(struct platform_device *pdev) |
64 | { | 93 | { |
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index b61945f3af9e..32d2a21f2e3b 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h | |||
@@ -1633,6 +1633,37 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
1633 | } | 1633 | } |
1634 | }, | 1634 | }, |
1635 | { | 1635 | { |
1636 | /* Roland GAIA SH-01 */ | ||
1637 | USB_DEVICE(0x0582, 0x0111), | ||
1638 | .driver_info = (unsigned long) &(const struct snd_usb_audio_quirk) { | ||
1639 | .vendor_name = "Roland", | ||
1640 | .product_name = "GAIA", | ||
1641 | .ifnum = QUIRK_ANY_INTERFACE, | ||
1642 | .type = QUIRK_COMPOSITE, | ||
1643 | .data = (const struct snd_usb_audio_quirk[]) { | ||
1644 | { | ||
1645 | .ifnum = 0, | ||
1646 | .type = QUIRK_AUDIO_STANDARD_INTERFACE | ||
1647 | }, | ||
1648 | { | ||
1649 | .ifnum = 1, | ||
1650 | .type = QUIRK_AUDIO_STANDARD_INTERFACE | ||
1651 | }, | ||
1652 | { | ||
1653 | .ifnum = 2, | ||
1654 | .type = QUIRK_MIDI_FIXED_ENDPOINT, | ||
1655 | .data = &(const struct snd_usb_midi_endpoint_info) { | ||
1656 | .out_cables = 0x0003, | ||
1657 | .in_cables = 0x0003 | ||
1658 | } | ||
1659 | }, | ||
1660 | { | ||
1661 | .ifnum = -1 | ||
1662 | } | ||
1663 | } | ||
1664 | } | ||
1665 | }, | ||
1666 | { | ||
1636 | USB_DEVICE(0x0582, 0x0113), | 1667 | USB_DEVICE(0x0582, 0x0113), |
1637 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | 1668 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { |
1638 | /* .vendor_name = "BOSS", */ | 1669 | /* .vendor_name = "BOSS", */ |