diff options
Diffstat (limited to 'sound')
43 files changed, 1087 insertions, 606 deletions
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c index 8f312fa6c28..7ae67192339 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c | |||
@@ -1250,10 +1250,10 @@ static int snd_pcm_hw_rule_list(struct snd_pcm_hw_params *params, | |||
1250 | int snd_pcm_hw_constraint_list(struct snd_pcm_runtime *runtime, | 1250 | int snd_pcm_hw_constraint_list(struct snd_pcm_runtime *runtime, |
1251 | unsigned int cond, | 1251 | unsigned int cond, |
1252 | snd_pcm_hw_param_t var, | 1252 | snd_pcm_hw_param_t var, |
1253 | struct snd_pcm_hw_constraint_list *l) | 1253 | const struct snd_pcm_hw_constraint_list *l) |
1254 | { | 1254 | { |
1255 | return snd_pcm_hw_rule_add(runtime, cond, var, | 1255 | return snd_pcm_hw_rule_add(runtime, cond, var, |
1256 | snd_pcm_hw_rule_list, l, | 1256 | snd_pcm_hw_rule_list, (void *)l, |
1257 | var, -1); | 1257 | var, -1); |
1258 | } | 1258 | } |
1259 | 1259 | ||
diff --git a/sound/core/pcm_misc.c b/sound/core/pcm_misc.c index 9c9eff9afba..d4fc1bfbe45 100644 --- a/sound/core/pcm_misc.c +++ b/sound/core/pcm_misc.c | |||
@@ -488,3 +488,21 @@ unsigned int snd_pcm_rate_to_rate_bit(unsigned int rate) | |||
488 | return SNDRV_PCM_RATE_KNOT; | 488 | return SNDRV_PCM_RATE_KNOT; |
489 | } | 489 | } |
490 | EXPORT_SYMBOL(snd_pcm_rate_to_rate_bit); | 490 | EXPORT_SYMBOL(snd_pcm_rate_to_rate_bit); |
491 | |||
492 | /** | ||
493 | * snd_pcm_rate_bit_to_rate - converts SNDRV_PCM_RATE_xxx bit to sample rate | ||
494 | * @rate_bit: the rate bit to convert | ||
495 | * | ||
496 | * Returns the sample rate that corresponds to the given SNDRV_PCM_RATE_xxx flag | ||
497 | * or 0 for an unknown rate bit | ||
498 | */ | ||
499 | unsigned int snd_pcm_rate_bit_to_rate(unsigned int rate_bit) | ||
500 | { | ||
501 | unsigned int i; | ||
502 | |||
503 | for (i = 0; i < snd_pcm_known_rates.count; i++) | ||
504 | if ((1u << i) == rate_bit) | ||
505 | return snd_pcm_known_rates.list[i]; | ||
506 | return 0; | ||
507 | } | ||
508 | EXPORT_SYMBOL(snd_pcm_rate_bit_to_rate); | ||
diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c index 582aace20ea..7eca25fae41 100644 --- a/sound/i2c/other/tea575x-tuner.c +++ b/sound/i2c/other/tea575x-tuner.c | |||
@@ -37,8 +37,8 @@ MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); | |||
37 | MODULE_DESCRIPTION("Routines for control of TEA5757/5759 Philips AM/FM radio tuner chips"); | 37 | MODULE_DESCRIPTION("Routines for control of TEA5757/5759 Philips AM/FM radio tuner chips"); |
38 | MODULE_LICENSE("GPL"); | 38 | MODULE_LICENSE("GPL"); |
39 | 39 | ||
40 | #define FREQ_LO (76U * 16000) | 40 | #define FREQ_LO ((tea->tea5759 ? 760 : 875) * 1600U) |
41 | #define FREQ_HI (108U * 16000) | 41 | #define FREQ_HI ((tea->tea5759 ? 910 : 1080) * 1600U) |
42 | 42 | ||
43 | /* | 43 | /* |
44 | * definitions | 44 | * definitions |
@@ -120,9 +120,9 @@ static u32 snd_tea575x_read(struct snd_tea575x *tea) | |||
120 | return data; | 120 | return data; |
121 | } | 121 | } |
122 | 122 | ||
123 | static u32 snd_tea575x_get_freq(struct snd_tea575x *tea) | 123 | static u32 snd_tea575x_val_to_freq(struct snd_tea575x *tea, u32 val) |
124 | { | 124 | { |
125 | u32 freq = snd_tea575x_read(tea) & TEA575X_BIT_FREQ_MASK; | 125 | u32 freq = val & TEA575X_BIT_FREQ_MASK; |
126 | 126 | ||
127 | if (freq == 0) | 127 | if (freq == 0) |
128 | return freq; | 128 | return freq; |
@@ -139,6 +139,11 @@ static u32 snd_tea575x_get_freq(struct snd_tea575x *tea) | |||
139 | return clamp(freq * 16, FREQ_LO, FREQ_HI); /* from kHz */ | 139 | return clamp(freq * 16, FREQ_LO, FREQ_HI); /* from kHz */ |
140 | } | 140 | } |
141 | 141 | ||
142 | static u32 snd_tea575x_get_freq(struct snd_tea575x *tea) | ||
143 | { | ||
144 | return snd_tea575x_val_to_freq(tea, snd_tea575x_read(tea)); | ||
145 | } | ||
146 | |||
142 | static void snd_tea575x_set_freq(struct snd_tea575x *tea) | 147 | static void snd_tea575x_set_freq(struct snd_tea575x *tea) |
143 | { | 148 | { |
144 | u32 freq = tea->freq; | 149 | u32 freq = tea->freq; |
@@ -156,6 +161,7 @@ static void snd_tea575x_set_freq(struct snd_tea575x *tea) | |||
156 | tea->val &= ~TEA575X_BIT_FREQ_MASK; | 161 | tea->val &= ~TEA575X_BIT_FREQ_MASK; |
157 | tea->val |= freq & TEA575X_BIT_FREQ_MASK; | 162 | tea->val |= freq & TEA575X_BIT_FREQ_MASK; |
158 | snd_tea575x_write(tea, tea->val); | 163 | snd_tea575x_write(tea, tea->val); |
164 | tea->freq = snd_tea575x_val_to_freq(tea, tea->val); | ||
159 | } | 165 | } |
160 | 166 | ||
161 | /* | 167 | /* |
@@ -317,7 +323,6 @@ static int tea575x_s_ctrl(struct v4l2_ctrl *ctrl) | |||
317 | } | 323 | } |
318 | 324 | ||
319 | static const struct v4l2_file_operations tea575x_fops = { | 325 | static const struct v4l2_file_operations tea575x_fops = { |
320 | .owner = THIS_MODULE, | ||
321 | .unlocked_ioctl = video_ioctl2, | 326 | .unlocked_ioctl = video_ioctl2, |
322 | .open = v4l2_fh_open, | 327 | .open = v4l2_fh_open, |
323 | .release = v4l2_fh_release, | 328 | .release = v4l2_fh_release, |
@@ -337,7 +342,6 @@ static const struct v4l2_ioctl_ops tea575x_ioctl_ops = { | |||
337 | }; | 342 | }; |
338 | 343 | ||
339 | static const struct video_device tea575x_radio = { | 344 | static const struct video_device tea575x_radio = { |
340 | .fops = &tea575x_fops, | ||
341 | .ioctl_ops = &tea575x_ioctl_ops, | 345 | .ioctl_ops = &tea575x_ioctl_ops, |
342 | .release = video_device_release_empty, | 346 | .release = video_device_release_empty, |
343 | }; | 347 | }; |
@@ -349,7 +353,7 @@ static const struct v4l2_ctrl_ops tea575x_ctrl_ops = { | |||
349 | /* | 353 | /* |
350 | * initialize all the tea575x chips | 354 | * initialize all the tea575x chips |
351 | */ | 355 | */ |
352 | int snd_tea575x_init(struct snd_tea575x *tea) | 356 | int snd_tea575x_init(struct snd_tea575x *tea, struct module *owner) |
353 | { | 357 | { |
354 | int retval; | 358 | int retval; |
355 | 359 | ||
@@ -374,6 +378,9 @@ int snd_tea575x_init(struct snd_tea575x *tea) | |||
374 | tea->vd.lock = &tea->mutex; | 378 | tea->vd.lock = &tea->mutex; |
375 | tea->vd.v4l2_dev = tea->v4l2_dev; | 379 | tea->vd.v4l2_dev = tea->v4l2_dev; |
376 | tea->vd.ctrl_handler = &tea->ctrl_handler; | 380 | tea->vd.ctrl_handler = &tea->ctrl_handler; |
381 | tea->fops = tea575x_fops; | ||
382 | tea->fops.owner = owner; | ||
383 | tea->vd.fops = &tea->fops; | ||
377 | set_bit(V4L2_FL_USE_FH_PRIO, &tea->vd.flags); | 384 | set_bit(V4L2_FL_USE_FH_PRIO, &tea->vd.flags); |
378 | /* disable hw_freq_seek if we can't use it */ | 385 | /* disable hw_freq_seek if we can't use it */ |
379 | if (tea->cannot_read_data) | 386 | if (tea->cannot_read_data) |
diff --git a/sound/isa/opti9xx/opti92x-ad1848.c b/sound/isa/opti9xx/opti92x-ad1848.c index d7ccf28bd66..f8fbe22515c 100644 --- a/sound/isa/opti9xx/opti92x-ad1848.c +++ b/sound/isa/opti9xx/opti92x-ad1848.c | |||
@@ -135,10 +135,9 @@ struct snd_opti9xx { | |||
135 | unsigned long mc_base_size; | 135 | unsigned long mc_base_size; |
136 | #ifdef OPTi93X | 136 | #ifdef OPTi93X |
137 | unsigned long mc_indir_index; | 137 | unsigned long mc_indir_index; |
138 | unsigned long mc_indir_size; | ||
139 | struct resource *res_mc_indir; | 138 | struct resource *res_mc_indir; |
140 | struct snd_wss *codec; | ||
141 | #endif /* OPTi93X */ | 139 | #endif /* OPTi93X */ |
140 | struct snd_wss *codec; | ||
142 | unsigned long pwd_reg; | 141 | unsigned long pwd_reg; |
143 | 142 | ||
144 | spinlock_t lock; | 143 | spinlock_t lock; |
@@ -245,10 +244,8 @@ static int __devinit snd_opti9xx_init(struct snd_opti9xx *chip, | |||
245 | case OPTi9XX_HW_82C931: | 244 | case OPTi9XX_HW_82C931: |
246 | case OPTi9XX_HW_82C933: | 245 | case OPTi9XX_HW_82C933: |
247 | chip->mc_base = (hardware == OPTi9XX_HW_82C930) ? 0xf8f : 0xf8d; | 246 | chip->mc_base = (hardware == OPTi9XX_HW_82C930) ? 0xf8f : 0xf8d; |
248 | if (!chip->mc_indir_index) { | 247 | if (!chip->mc_indir_index) |
249 | chip->mc_indir_index = 0xe0e; | 248 | chip->mc_indir_index = 0xe0e; |
250 | chip->mc_indir_size = 2; | ||
251 | } | ||
252 | chip->password = 0xe4; | 249 | chip->password = 0xe4; |
253 | chip->pwd_reg = 0; | 250 | chip->pwd_reg = 0; |
254 | break; | 251 | break; |
@@ -351,7 +348,7 @@ static void snd_opti9xx_write(struct snd_opti9xx *chip, unsigned char reg, | |||
351 | (snd_opti9xx_read(chip, reg) & ~(mask)) | ((value) & (mask))) | 348 | (snd_opti9xx_read(chip, reg) & ~(mask)) | ((value) & (mask))) |
352 | 349 | ||
353 | 350 | ||
354 | static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip, | 351 | static int snd_opti9xx_configure(struct snd_opti9xx *chip, |
355 | long port, | 352 | long port, |
356 | int irq, int dma1, int dma2, | 353 | int irq, int dma1, int dma2, |
357 | long mpu_port, int mpu_irq) | 354 | long mpu_port, int mpu_irq) |
@@ -403,7 +400,9 @@ static int __devinit snd_opti9xx_configure(struct snd_opti9xx *chip, | |||
403 | 400 | ||
404 | #else /* OPTi93X */ | 401 | #else /* OPTi93X */ |
405 | case OPTi9XX_HW_82C931: | 402 | case OPTi9XX_HW_82C931: |
406 | case OPTi9XX_HW_82C933: | 403 | /* disable 3D sound (set GPIO1 as output, low) */ |
404 | snd_opti9xx_write_mask(chip, OPTi9XX_MC_REG(20), 0x04, 0x0c); | ||
405 | case OPTi9XX_HW_82C933: /* FALL THROUGH */ | ||
407 | /* | 406 | /* |
408 | * The BTC 1817DW has QS1000 wavetable which is connected | 407 | * The BTC 1817DW has QS1000 wavetable which is connected |
409 | * to the serial digital input of the OPTI931. | 408 | * to the serial digital input of the OPTI931. |
@@ -696,8 +695,7 @@ static int __devinit snd_opti9xx_read_check(struct snd_opti9xx *chip) | |||
696 | if (value == snd_opti9xx_read(chip, OPTi9XX_MC_REG(1))) | 695 | if (value == snd_opti9xx_read(chip, OPTi9XX_MC_REG(1))) |
697 | return 0; | 696 | return 0; |
698 | #else /* OPTi93X */ | 697 | #else /* OPTi93X */ |
699 | chip->res_mc_indir = request_region(chip->mc_indir_index, | 698 | chip->res_mc_indir = request_region(chip->mc_indir_index, 2, |
700 | chip->mc_indir_size, | ||
701 | "OPTi93x MC"); | 699 | "OPTi93x MC"); |
702 | if (chip->res_mc_indir == NULL) | 700 | if (chip->res_mc_indir == NULL) |
703 | return -EBUSY; | 701 | return -EBUSY; |
@@ -770,8 +768,9 @@ static int __devinit snd_card_opti9xx_pnp(struct snd_opti9xx *chip, | |||
770 | #ifdef OPTi93X | 768 | #ifdef OPTi93X |
771 | port = pnp_port_start(pdev, 0) - 4; | 769 | port = pnp_port_start(pdev, 0) - 4; |
772 | fm_port = pnp_port_start(pdev, 1) + 8; | 770 | fm_port = pnp_port_start(pdev, 1) + 8; |
773 | chip->mc_indir_index = pnp_port_start(pdev, 3) + 2; | 771 | /* adjust mc_indir_index - some cards report it at 0xe?d, |
774 | chip->mc_indir_size = pnp_port_len(pdev, 3) - 2; | 772 | other at 0xe?c but it really is always at 0xe?e */ |
773 | chip->mc_indir_index = (pnp_port_start(pdev, 3) & ~0xf) | 0xe; | ||
775 | #else | 774 | #else |
776 | devmc = pnp_request_card_device(card, pid->devs[2].id, NULL); | 775 | devmc = pnp_request_card_device(card, pid->devs[2].id, NULL); |
777 | if (devmc == NULL) | 776 | if (devmc == NULL) |
@@ -871,9 +870,7 @@ static int __devinit snd_opti9xx_probe(struct snd_card *card) | |||
871 | &codec); | 870 | &codec); |
872 | if (error < 0) | 871 | if (error < 0) |
873 | return error; | 872 | return error; |
874 | #ifdef OPTi93X | ||
875 | chip->codec = codec; | 873 | chip->codec = codec; |
876 | #endif | ||
877 | error = snd_wss_pcm(codec, 0, &pcm); | 874 | error = snd_wss_pcm(codec, 0, &pcm); |
878 | if (error < 0) | 875 | if (error < 0) |
879 | return error; | 876 | return error; |
@@ -1054,11 +1051,55 @@ static int __devexit snd_opti9xx_isa_remove(struct device *devptr, | |||
1054 | return 0; | 1051 | return 0; |
1055 | } | 1052 | } |
1056 | 1053 | ||
1054 | #ifdef CONFIG_PM | ||
1055 | static int snd_opti9xx_suspend(struct snd_card *card) | ||
1056 | { | ||
1057 | struct snd_opti9xx *chip = card->private_data; | ||
1058 | |||
1059 | snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); | ||
1060 | chip->codec->suspend(chip->codec); | ||
1061 | return 0; | ||
1062 | } | ||
1063 | |||
1064 | static int snd_opti9xx_resume(struct snd_card *card) | ||
1065 | { | ||
1066 | struct snd_opti9xx *chip = card->private_data; | ||
1067 | int error, xdma2; | ||
1068 | #if defined(CS4231) || defined(OPTi93X) | ||
1069 | xdma2 = dma2; | ||
1070 | #else | ||
1071 | xdma2 = -1; | ||
1072 | #endif | ||
1073 | |||
1074 | error = snd_opti9xx_configure(chip, port, irq, dma1, xdma2, | ||
1075 | mpu_port, mpu_irq); | ||
1076 | if (error) | ||
1077 | return error; | ||
1078 | chip->codec->resume(chip->codec); | ||
1079 | snd_power_change_state(card, SNDRV_CTL_POWER_D0); | ||
1080 | return 0; | ||
1081 | } | ||
1082 | |||
1083 | static int snd_opti9xx_isa_suspend(struct device *dev, unsigned int n, | ||
1084 | pm_message_t state) | ||
1085 | { | ||
1086 | return snd_opti9xx_suspend(dev_get_drvdata(dev)); | ||
1087 | } | ||
1088 | |||
1089 | static int snd_opti9xx_isa_resume(struct device *dev, unsigned int n) | ||
1090 | { | ||
1091 | return snd_opti9xx_resume(dev_get_drvdata(dev)); | ||
1092 | } | ||
1093 | #endif | ||
1094 | |||
1057 | static struct isa_driver snd_opti9xx_driver = { | 1095 | static struct isa_driver snd_opti9xx_driver = { |
1058 | .match = snd_opti9xx_isa_match, | 1096 | .match = snd_opti9xx_isa_match, |
1059 | .probe = snd_opti9xx_isa_probe, | 1097 | .probe = snd_opti9xx_isa_probe, |
1060 | .remove = __devexit_p(snd_opti9xx_isa_remove), | 1098 | .remove = __devexit_p(snd_opti9xx_isa_remove), |
1061 | /* FIXME: suspend/resume */ | 1099 | #ifdef CONFIG_PM |
1100 | .suspend = snd_opti9xx_isa_suspend, | ||
1101 | .resume = snd_opti9xx_isa_resume, | ||
1102 | #endif | ||
1062 | .driver = { | 1103 | .driver = { |
1063 | .name = DEV_NAME | 1104 | .name = DEV_NAME |
1064 | }, | 1105 | }, |
@@ -1124,12 +1165,29 @@ static void __devexit snd_opti9xx_pnp_remove(struct pnp_card_link * pcard) | |||
1124 | snd_opti9xx_pnp_is_probed = 0; | 1165 | snd_opti9xx_pnp_is_probed = 0; |
1125 | } | 1166 | } |
1126 | 1167 | ||
1168 | #ifdef CONFIG_PM | ||
1169 | static int snd_opti9xx_pnp_suspend(struct pnp_card_link *pcard, | ||
1170 | pm_message_t state) | ||
1171 | { | ||
1172 | return snd_opti9xx_suspend(pnp_get_card_drvdata(pcard)); | ||
1173 | } | ||
1174 | |||
1175 | static int snd_opti9xx_pnp_resume(struct pnp_card_link *pcard) | ||
1176 | { | ||
1177 | return snd_opti9xx_resume(pnp_get_card_drvdata(pcard)); | ||
1178 | } | ||
1179 | #endif | ||
1180 | |||
1127 | static struct pnp_card_driver opti9xx_pnpc_driver = { | 1181 | static struct pnp_card_driver opti9xx_pnpc_driver = { |
1128 | .flags = PNP_DRIVER_RES_DISABLE, | 1182 | .flags = PNP_DRIVER_RES_DISABLE, |
1129 | .name = "opti9xx", | 1183 | .name = "opti9xx", |
1130 | .id_table = snd_opti9xx_pnpids, | 1184 | .id_table = snd_opti9xx_pnpids, |
1131 | .probe = snd_opti9xx_pnp_probe, | 1185 | .probe = snd_opti9xx_pnp_probe, |
1132 | .remove = __devexit_p(snd_opti9xx_pnp_remove), | 1186 | .remove = __devexit_p(snd_opti9xx_pnp_remove), |
1187 | #ifdef CONFIG_PM | ||
1188 | .suspend = snd_opti9xx_pnp_suspend, | ||
1189 | .resume = snd_opti9xx_pnp_resume, | ||
1190 | #endif | ||
1133 | }; | 1191 | }; |
1134 | #endif | 1192 | #endif |
1135 | 1193 | ||
diff --git a/sound/isa/wss/wss_lib.c b/sound/isa/wss/wss_lib.c index 49c8a0c2442..360b08b03e1 100644 --- a/sound/isa/wss/wss_lib.c +++ b/sound/isa/wss/wss_lib.c | |||
@@ -1456,7 +1456,6 @@ static struct snd_pcm_hardware snd_wss_playback = | |||
1456 | { | 1456 | { |
1457 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | | 1457 | .info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_INTERLEAVED | |
1458 | SNDRV_PCM_INFO_MMAP_VALID | | 1458 | SNDRV_PCM_INFO_MMAP_VALID | |
1459 | SNDRV_PCM_INFO_RESUME | | ||
1460 | SNDRV_PCM_INFO_SYNC_START), | 1459 | SNDRV_PCM_INFO_SYNC_START), |
1461 | .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | SNDRV_PCM_FMTBIT_IMA_ADPCM | | 1460 | .formats = (SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW | SNDRV_PCM_FMTBIT_IMA_ADPCM | |
1462 | SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE), | 1461 | SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE), |
@@ -1657,6 +1656,10 @@ static void snd_wss_resume(struct snd_wss *chip) | |||
1657 | break; | 1656 | break; |
1658 | } | 1657 | } |
1659 | } | 1658 | } |
1659 | /* Yamaha needs this to resume properly */ | ||
1660 | if (chip->hardware == WSS_HW_OPL3SA2) | ||
1661 | snd_wss_out(chip, CS4231_PLAYBK_FORMAT, | ||
1662 | chip->image[CS4231_PLAYBK_FORMAT]); | ||
1660 | spin_unlock_irqrestore(&chip->reg_lock, flags); | 1663 | spin_unlock_irqrestore(&chip->reg_lock, flags); |
1661 | #if 1 | 1664 | #if 1 |
1662 | snd_wss_mce_down(chip); | 1665 | snd_wss_mce_down(chip); |
diff --git a/sound/oss/swarm_cs4297a.c b/sound/oss/swarm_cs4297a.c index 09d46484bc1..7d8803a00b7 100644 --- a/sound/oss/swarm_cs4297a.c +++ b/sound/oss/swarm_cs4297a.c | |||
@@ -69,7 +69,6 @@ | |||
69 | #include <linux/sound.h> | 69 | #include <linux/sound.h> |
70 | #include <linux/slab.h> | 70 | #include <linux/slab.h> |
71 | #include <linux/soundcard.h> | 71 | #include <linux/soundcard.h> |
72 | #include <linux/ac97_codec.h> | ||
73 | #include <linux/pci.h> | 72 | #include <linux/pci.h> |
74 | #include <linux/bitops.h> | 73 | #include <linux/bitops.h> |
75 | #include <linux/interrupt.h> | 74 | #include <linux/interrupt.h> |
@@ -199,6 +198,22 @@ static const char invalid_magic[] = | |||
199 | } \ | 198 | } \ |
200 | }) | 199 | }) |
201 | 200 | ||
201 | /* AC97 registers */ | ||
202 | #define AC97_MASTER_VOL_STEREO 0x0002 /* Line Out */ | ||
203 | #define AC97_PCBEEP_VOL 0x000a /* none */ | ||
204 | #define AC97_PHONE_VOL 0x000c /* TAD Input (mono) */ | ||
205 | #define AC97_MIC_VOL 0x000e /* MIC Input (mono) */ | ||
206 | #define AC97_LINEIN_VOL 0x0010 /* Line Input (stereo) */ | ||
207 | #define AC97_CD_VOL 0x0012 /* CD Input (stereo) */ | ||
208 | #define AC97_AUX_VOL 0x0016 /* Aux Input (stereo) */ | ||
209 | #define AC97_PCMOUT_VOL 0x0018 /* Wave Output (stereo) */ | ||
210 | #define AC97_RECORD_SELECT 0x001a /* */ | ||
211 | #define AC97_RECORD_GAIN 0x001c | ||
212 | #define AC97_GENERAL_PURPOSE 0x0020 | ||
213 | #define AC97_3D_CONTROL 0x0022 | ||
214 | #define AC97_POWER_CONTROL 0x0026 | ||
215 | #define AC97_VENDOR_ID1 0x007c | ||
216 | |||
202 | struct list_head cs4297a_devs = { &cs4297a_devs, &cs4297a_devs }; | 217 | struct list_head cs4297a_devs = { &cs4297a_devs, &cs4297a_devs }; |
203 | 218 | ||
204 | typedef struct serdma_descr_s { | 219 | typedef struct serdma_descr_s { |
diff --git a/sound/pci/au88x0/au88x0_mixer.c b/sound/pci/au88x0/au88x0_mixer.c index 557c782ae4f..fa13efbebda 100644 --- a/sound/pci/au88x0/au88x0_mixer.c +++ b/sound/pci/au88x0/au88x0_mixer.c | |||
@@ -10,6 +10,15 @@ | |||
10 | #include <sound/core.h> | 10 | #include <sound/core.h> |
11 | #include "au88x0.h" | 11 | #include "au88x0.h" |
12 | 12 | ||
13 | static int remove_ctl(struct snd_card *card, const char *name) | ||
14 | { | ||
15 | struct snd_ctl_elem_id id; | ||
16 | memset(&id, 0, sizeof(id)); | ||
17 | strcpy(id.name, name); | ||
18 | id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; | ||
19 | return snd_ctl_remove_id(card, &id); | ||
20 | } | ||
21 | |||
13 | static int __devinit snd_vortex_mixer(vortex_t * vortex) | 22 | static int __devinit snd_vortex_mixer(vortex_t * vortex) |
14 | { | 23 | { |
15 | struct snd_ac97_bus *pbus; | 24 | struct snd_ac97_bus *pbus; |
@@ -28,5 +37,7 @@ static int __devinit snd_vortex_mixer(vortex_t * vortex) | |||
28 | ac97.scaps = AC97_SCAP_NO_SPDIF; | 37 | ac97.scaps = AC97_SCAP_NO_SPDIF; |
29 | err = snd_ac97_mixer(pbus, &ac97, &vortex->codec); | 38 | err = snd_ac97_mixer(pbus, &ac97, &vortex->codec); |
30 | vortex->isquad = ((vortex->codec == NULL) ? 0 : (vortex->codec->ext_id&0x80)); | 39 | vortex->isquad = ((vortex->codec == NULL) ? 0 : (vortex->codec->ext_id&0x80)); |
40 | remove_ctl(vortex->card, "Master Mono Playback Volume"); | ||
41 | remove_ctl(vortex->card, "Master Mono Playback Switch"); | ||
31 | return err; | 42 | return err; |
32 | } | 43 | } |
diff --git a/sound/pci/es1938.c b/sound/pci/es1938.c index 82c8d8c5c52..a41106d745c 100644 --- a/sound/pci/es1938.c +++ b/sound/pci/es1938.c | |||
@@ -1321,35 +1321,30 @@ static int snd_es1938_put_double(struct snd_kcontrol *kcontrol, | |||
1321 | return change; | 1321 | return change; |
1322 | } | 1322 | } |
1323 | 1323 | ||
1324 | static unsigned int db_scale_master[] = { | 1324 | static const DECLARE_TLV_DB_RANGE(db_scale_master, |
1325 | TLV_DB_RANGE_HEAD(2), | ||
1326 | 0, 54, TLV_DB_SCALE_ITEM(-3600, 50, 1), | 1325 | 0, 54, TLV_DB_SCALE_ITEM(-3600, 50, 1), |
1327 | 54, 63, TLV_DB_SCALE_ITEM(-900, 100, 0), | 1326 | 54, 63, TLV_DB_SCALE_ITEM(-900, 100, 0), |
1328 | }; | 1327 | ); |
1329 | 1328 | ||
1330 | static unsigned int db_scale_audio1[] = { | 1329 | static const DECLARE_TLV_DB_RANGE(db_scale_audio1, |
1331 | TLV_DB_RANGE_HEAD(2), | ||
1332 | 0, 8, TLV_DB_SCALE_ITEM(-3300, 300, 1), | 1330 | 0, 8, TLV_DB_SCALE_ITEM(-3300, 300, 1), |
1333 | 8, 15, TLV_DB_SCALE_ITEM(-900, 150, 0), | 1331 | 8, 15, TLV_DB_SCALE_ITEM(-900, 150, 0), |
1334 | }; | 1332 | ); |
1335 | 1333 | ||
1336 | static unsigned int db_scale_audio2[] = { | 1334 | static const DECLARE_TLV_DB_RANGE(db_scale_audio2, |
1337 | TLV_DB_RANGE_HEAD(2), | ||
1338 | 0, 8, TLV_DB_SCALE_ITEM(-3450, 300, 1), | 1335 | 0, 8, TLV_DB_SCALE_ITEM(-3450, 300, 1), |
1339 | 8, 15, TLV_DB_SCALE_ITEM(-1050, 150, 0), | 1336 | 8, 15, TLV_DB_SCALE_ITEM(-1050, 150, 0), |
1340 | }; | 1337 | ); |
1341 | 1338 | ||
1342 | static unsigned int db_scale_mic[] = { | 1339 | static const DECLARE_TLV_DB_RANGE(db_scale_mic, |
1343 | TLV_DB_RANGE_HEAD(2), | ||
1344 | 0, 8, TLV_DB_SCALE_ITEM(-2400, 300, 1), | 1340 | 0, 8, TLV_DB_SCALE_ITEM(-2400, 300, 1), |
1345 | 8, 15, TLV_DB_SCALE_ITEM(0, 150, 0), | 1341 | 8, 15, TLV_DB_SCALE_ITEM(0, 150, 0), |
1346 | }; | 1342 | ); |
1347 | 1343 | ||
1348 | static unsigned int db_scale_line[] = { | 1344 | static const DECLARE_TLV_DB_RANGE(db_scale_line, |
1349 | TLV_DB_RANGE_HEAD(2), | ||
1350 | 0, 8, TLV_DB_SCALE_ITEM(-3150, 300, 1), | 1345 | 0, 8, TLV_DB_SCALE_ITEM(-3150, 300, 1), |
1351 | 8, 15, TLV_DB_SCALE_ITEM(-750, 150, 0), | 1346 | 8, 15, TLV_DB_SCALE_ITEM(-750, 150, 0), |
1352 | }; | 1347 | ); |
1353 | 1348 | ||
1354 | static const DECLARE_TLV_DB_SCALE(db_scale_capture, 0, 150, 0); | 1349 | static const DECLARE_TLV_DB_SCALE(db_scale_capture, 0, 150, 0); |
1355 | 1350 | ||
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c index 67f47d89195..52b5c0bf90c 100644 --- a/sound/pci/es1968.c +++ b/sound/pci/es1968.c | |||
@@ -2769,7 +2769,7 @@ static int __devinit snd_es1968_create(struct snd_card *card, | |||
2769 | chip->tea.ops = &snd_es1968_tea_ops; | 2769 | chip->tea.ops = &snd_es1968_tea_ops; |
2770 | strlcpy(chip->tea.card, "SF64-PCE2", sizeof(chip->tea.card)); | 2770 | strlcpy(chip->tea.card, "SF64-PCE2", sizeof(chip->tea.card)); |
2771 | sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci)); | 2771 | sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci)); |
2772 | if (!snd_tea575x_init(&chip->tea)) | 2772 | if (!snd_tea575x_init(&chip->tea, THIS_MODULE)) |
2773 | printk(KERN_INFO "es1968: detected TEA575x radio\n"); | 2773 | printk(KERN_INFO "es1968: detected TEA575x radio\n"); |
2774 | #endif | 2774 | #endif |
2775 | 2775 | ||
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c index f6966232275..b32e8024ea8 100644 --- a/sound/pci/fm801.c +++ b/sound/pci/fm801.c | |||
@@ -1254,7 +1254,7 @@ static int __devinit snd_fm801_create(struct snd_card *card, | |||
1254 | sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci)); | 1254 | sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci)); |
1255 | if ((tea575x_tuner & TUNER_TYPE_MASK) > 0 && | 1255 | if ((tea575x_tuner & TUNER_TYPE_MASK) > 0 && |
1256 | (tea575x_tuner & TUNER_TYPE_MASK) < 4) { | 1256 | (tea575x_tuner & TUNER_TYPE_MASK) < 4) { |
1257 | if (snd_tea575x_init(&chip->tea)) { | 1257 | if (snd_tea575x_init(&chip->tea, THIS_MODULE)) { |
1258 | snd_printk(KERN_ERR "TEA575x radio not found\n"); | 1258 | snd_printk(KERN_ERR "TEA575x radio not found\n"); |
1259 | snd_fm801_free(chip); | 1259 | snd_fm801_free(chip); |
1260 | return -ENODEV; | 1260 | return -ENODEV; |
@@ -1263,7 +1263,7 @@ static int __devinit snd_fm801_create(struct snd_card *card, | |||
1263 | /* autodetect tuner connection */ | 1263 | /* autodetect tuner connection */ |
1264 | for (tea575x_tuner = 1; tea575x_tuner <= 3; tea575x_tuner++) { | 1264 | for (tea575x_tuner = 1; tea575x_tuner <= 3; tea575x_tuner++) { |
1265 | chip->tea575x_tuner = tea575x_tuner; | 1265 | chip->tea575x_tuner = tea575x_tuner; |
1266 | if (!snd_tea575x_init(&chip->tea)) { | 1266 | if (!snd_tea575x_init(&chip->tea, THIS_MODULE)) { |
1267 | snd_printk(KERN_INFO "detected TEA575x radio type %s\n", | 1267 | snd_printk(KERN_INFO "detected TEA575x radio type %s\n", |
1268 | get_tea575x_gpio(chip)->name); | 1268 | get_tea575x_gpio(chip)->name); |
1269 | break; | 1269 | break; |
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig index 163b6b5de3e..194d625c1f8 100644 --- a/sound/pci/hda/Kconfig +++ b/sound/pci/hda/Kconfig | |||
@@ -53,15 +53,14 @@ config SND_HDA_INPUT_BEEP | |||
53 | driver. This interface is used to generate digital beeps. | 53 | driver. This interface is used to generate digital beeps. |
54 | 54 | ||
55 | config SND_HDA_INPUT_BEEP_MODE | 55 | config SND_HDA_INPUT_BEEP_MODE |
56 | int "Digital beep registration mode (0=off, 1=on, 2=mute sw on/off)" | 56 | int "Digital beep registration mode (0=off, 1=on)" |
57 | depends on SND_HDA_INPUT_BEEP=y | 57 | depends on SND_HDA_INPUT_BEEP=y |
58 | default "1" | 58 | default "1" |
59 | range 0 2 | 59 | range 0 1 |
60 | help | 60 | help |
61 | Set 0 to disable the digital beep interface for HD-audio by default. | 61 | Set 0 to disable the digital beep interface for HD-audio by default. |
62 | Set 1 to always enable the digital beep interface for HD-audio by | 62 | Set 1 to always enable the digital beep interface for HD-audio by |
63 | default. Set 2 to control the beep device registration to input | 63 | default. |
64 | layer using a "Beep Switch" in mixer applications. | ||
65 | 64 | ||
66 | config SND_HDA_INPUT_JACK | 65 | config SND_HDA_INPUT_JACK |
67 | bool "Support jack plugging notification via input layer" | 66 | bool "Support jack plugging notification via input layer" |
@@ -97,19 +96,6 @@ config SND_HDA_CODEC_REALTEK | |||
97 | snd-hda-codec-realtek. | 96 | snd-hda-codec-realtek. |
98 | This module is automatically loaded at probing. | 97 | This module is automatically loaded at probing. |
99 | 98 | ||
100 | config SND_HDA_ENABLE_REALTEK_QUIRKS | ||
101 | bool "Build static quirks for Realtek codecs" | ||
102 | depends on SND_HDA_CODEC_REALTEK | ||
103 | default y | ||
104 | help | ||
105 | Say Y here to build the static quirks codes for Realtek codecs. | ||
106 | If you need the "model" preset that the default BIOS auto-parser | ||
107 | can't handle, turn this option on. | ||
108 | |||
109 | If your device works with model=auto option, basically you don't | ||
110 | need the quirk code. By turning this off, you can reduce the | ||
111 | module size quite a lot. | ||
112 | |||
113 | config SND_HDA_CODEC_ANALOG | 99 | config SND_HDA_CODEC_ANALOG |
114 | bool "Build Analog Device HD-audio codec support" | 100 | bool "Build Analog Device HD-audio codec support" |
115 | default y | 101 | default y |
diff --git a/sound/pci/hda/hda_auto_parser.c b/sound/pci/hda/hda_auto_parser.c index 6e9ef3e2509..647218d69f6 100644 --- a/sound/pci/hda/hda_auto_parser.c +++ b/sound/pci/hda/hda_auto_parser.c | |||
@@ -618,7 +618,6 @@ int snd_hda_gen_add_verbs(struct hda_gen_spec *spec, | |||
618 | const struct hda_verb *list) | 618 | const struct hda_verb *list) |
619 | { | 619 | { |
620 | const struct hda_verb **v; | 620 | const struct hda_verb **v; |
621 | snd_array_init(&spec->verbs, sizeof(struct hda_verb *), 8); | ||
622 | v = snd_array_new(&spec->verbs); | 621 | v = snd_array_new(&spec->verbs); |
623 | if (!v) | 622 | if (!v) |
624 | return -ENOMEM; | 623 | return -ENOMEM; |
@@ -728,7 +727,7 @@ void snd_hda_pick_fixup(struct hda_codec *codec, | |||
728 | models++; | 727 | models++; |
729 | } | 728 | } |
730 | } | 729 | } |
731 | if (id < 0) { | 730 | if (id < 0 && quirk) { |
732 | q = snd_pci_quirk_lookup(codec->bus->pci, quirk); | 731 | q = snd_pci_quirk_lookup(codec->bus->pci, quirk); |
733 | if (q) { | 732 | if (q) { |
734 | id = q->value; | 733 | id = q->value; |
@@ -737,7 +736,7 @@ void snd_hda_pick_fixup(struct hda_codec *codec, | |||
737 | #endif | 736 | #endif |
738 | } | 737 | } |
739 | } | 738 | } |
740 | if (id < 0) { | 739 | if (id < 0 && quirk) { |
741 | for (q = quirk; q->subvendor; q++) { | 740 | for (q = quirk; q->subvendor; q++) { |
742 | unsigned int vendorid = | 741 | unsigned int vendorid = |
743 | q->subdevice | (q->subvendor << 16); | 742 | q->subdevice | (q->subvendor << 16); |
diff --git a/sound/pci/hda/hda_auto_parser.h b/sound/pci/hda/hda_auto_parser.h index 2a7889dfbd1..632ad0ad300 100644 --- a/sound/pci/hda/hda_auto_parser.h +++ b/sound/pci/hda/hda_auto_parser.h | |||
@@ -157,4 +157,14 @@ void snd_hda_pick_fixup(struct hda_codec *codec, | |||
157 | const struct snd_pci_quirk *quirk, | 157 | const struct snd_pci_quirk *quirk, |
158 | const struct hda_fixup *fixlist); | 158 | const struct hda_fixup *fixlist); |
159 | 159 | ||
160 | static inline void snd_hda_gen_init(struct hda_gen_spec *spec) | ||
161 | { | ||
162 | snd_array_init(&spec->verbs, sizeof(struct hda_verb *), 8); | ||
163 | } | ||
164 | |||
165 | static inline void snd_hda_gen_free(struct hda_gen_spec *spec) | ||
166 | { | ||
167 | snd_array_free(&spec->verbs); | ||
168 | } | ||
169 | |||
160 | #endif /* __SOUND_HDA_AUTO_PARSER_H */ | 170 | #endif /* __SOUND_HDA_AUTO_PARSER_H */ |
diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c index 60738e52b8f..0bc2315b181 100644 --- a/sound/pci/hda/hda_beep.c +++ b/sound/pci/hda/hda_beep.c | |||
@@ -162,50 +162,20 @@ static int snd_hda_do_attach(struct hda_beep *beep) | |||
162 | return 0; | 162 | return 0; |
163 | } | 163 | } |
164 | 164 | ||
165 | static void snd_hda_do_register(struct work_struct *work) | ||
166 | { | ||
167 | struct hda_beep *beep = | ||
168 | container_of(work, struct hda_beep, register_work); | ||
169 | |||
170 | mutex_lock(&beep->mutex); | ||
171 | if (beep->enabled && !beep->dev) | ||
172 | snd_hda_do_attach(beep); | ||
173 | mutex_unlock(&beep->mutex); | ||
174 | } | ||
175 | |||
176 | static void snd_hda_do_unregister(struct work_struct *work) | ||
177 | { | ||
178 | struct hda_beep *beep = | ||
179 | container_of(work, struct hda_beep, unregister_work.work); | ||
180 | |||
181 | mutex_lock(&beep->mutex); | ||
182 | if (!beep->enabled && beep->dev) | ||
183 | snd_hda_do_detach(beep); | ||
184 | mutex_unlock(&beep->mutex); | ||
185 | } | ||
186 | |||
187 | int snd_hda_enable_beep_device(struct hda_codec *codec, int enable) | 165 | int snd_hda_enable_beep_device(struct hda_codec *codec, int enable) |
188 | { | 166 | { |
189 | struct hda_beep *beep = codec->beep; | 167 | struct hda_beep *beep = codec->beep; |
190 | enable = !!enable; | 168 | if (!beep) |
191 | if (beep == NULL) | ||
192 | return 0; | 169 | return 0; |
170 | enable = !!enable; | ||
193 | if (beep->enabled != enable) { | 171 | if (beep->enabled != enable) { |
194 | beep->enabled = enable; | 172 | beep->enabled = enable; |
195 | if (!enable) { | 173 | if (!enable) { |
174 | cancel_work_sync(&beep->beep_work); | ||
196 | /* turn off beep */ | 175 | /* turn off beep */ |
197 | snd_hda_codec_write(beep->codec, beep->nid, 0, | 176 | snd_hda_codec_write(beep->codec, beep->nid, 0, |
198 | AC_VERB_SET_BEEP_CONTROL, 0); | 177 | AC_VERB_SET_BEEP_CONTROL, 0); |
199 | } | 178 | } |
200 | if (beep->mode == HDA_BEEP_MODE_SWREG) { | ||
201 | if (enable) { | ||
202 | cancel_delayed_work(&beep->unregister_work); | ||
203 | schedule_work(&beep->register_work); | ||
204 | } else { | ||
205 | schedule_delayed_work(&beep->unregister_work, | ||
206 | HZ); | ||
207 | } | ||
208 | } | ||
209 | return 1; | 179 | return 1; |
210 | } | 180 | } |
211 | return 0; | 181 | return 0; |
@@ -215,6 +185,7 @@ EXPORT_SYMBOL_HDA(snd_hda_enable_beep_device); | |||
215 | int snd_hda_attach_beep_device(struct hda_codec *codec, int nid) | 185 | int snd_hda_attach_beep_device(struct hda_codec *codec, int nid) |
216 | { | 186 | { |
217 | struct hda_beep *beep; | 187 | struct hda_beep *beep; |
188 | int err; | ||
218 | 189 | ||
219 | if (!snd_hda_get_bool_hint(codec, "beep")) | 190 | if (!snd_hda_get_bool_hint(codec, "beep")) |
220 | return 0; /* disabled explicitly by hints */ | 191 | return 0; /* disabled explicitly by hints */ |
@@ -232,21 +203,16 @@ int snd_hda_attach_beep_device(struct hda_codec *codec, int nid) | |||
232 | 203 | ||
233 | beep->nid = nid; | 204 | beep->nid = nid; |
234 | beep->codec = codec; | 205 | beep->codec = codec; |
235 | beep->mode = codec->beep_mode; | ||
236 | codec->beep = beep; | 206 | codec->beep = beep; |
237 | 207 | ||
238 | INIT_WORK(&beep->register_work, &snd_hda_do_register); | ||
239 | INIT_DELAYED_WORK(&beep->unregister_work, &snd_hda_do_unregister); | ||
240 | INIT_WORK(&beep->beep_work, &snd_hda_generate_beep); | 208 | INIT_WORK(&beep->beep_work, &snd_hda_generate_beep); |
241 | mutex_init(&beep->mutex); | 209 | mutex_init(&beep->mutex); |
242 | 210 | ||
243 | if (beep->mode == HDA_BEEP_MODE_ON) { | 211 | err = snd_hda_do_attach(beep); |
244 | int err = snd_hda_do_attach(beep); | 212 | if (err < 0) { |
245 | if (err < 0) { | 213 | kfree(beep); |
246 | kfree(beep); | 214 | codec->beep = NULL; |
247 | codec->beep = NULL; | 215 | return err; |
248 | return err; | ||
249 | } | ||
250 | } | 216 | } |
251 | 217 | ||
252 | return 0; | 218 | return 0; |
@@ -257,8 +223,6 @@ void snd_hda_detach_beep_device(struct hda_codec *codec) | |||
257 | { | 223 | { |
258 | struct hda_beep *beep = codec->beep; | 224 | struct hda_beep *beep = codec->beep; |
259 | if (beep) { | 225 | if (beep) { |
260 | cancel_work_sync(&beep->register_work); | ||
261 | cancel_delayed_work(&beep->unregister_work); | ||
262 | if (beep->dev) | 226 | if (beep->dev) |
263 | snd_hda_do_detach(beep); | 227 | snd_hda_do_detach(beep); |
264 | codec->beep = NULL; | 228 | codec->beep = NULL; |
@@ -266,3 +230,31 @@ void snd_hda_detach_beep_device(struct hda_codec *codec) | |||
266 | } | 230 | } |
267 | } | 231 | } |
268 | EXPORT_SYMBOL_HDA(snd_hda_detach_beep_device); | 232 | EXPORT_SYMBOL_HDA(snd_hda_detach_beep_device); |
233 | |||
234 | /* get/put callbacks for beep mute mixer switches */ | ||
235 | int snd_hda_mixer_amp_switch_get_beep(struct snd_kcontrol *kcontrol, | ||
236 | struct snd_ctl_elem_value *ucontrol) | ||
237 | { | ||
238 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
239 | struct hda_beep *beep = codec->beep; | ||
240 | if (beep) { | ||
241 | ucontrol->value.integer.value[0] = | ||
242 | ucontrol->value.integer.value[1] = | ||
243 | beep->enabled; | ||
244 | return 0; | ||
245 | } | ||
246 | return snd_hda_mixer_amp_switch_get(kcontrol, ucontrol); | ||
247 | } | ||
248 | EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_get_beep); | ||
249 | |||
250 | int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol, | ||
251 | struct snd_ctl_elem_value *ucontrol) | ||
252 | { | ||
253 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
254 | struct hda_beep *beep = codec->beep; | ||
255 | if (beep) | ||
256 | snd_hda_enable_beep_device(codec, | ||
257 | *ucontrol->value.integer.value); | ||
258 | return snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); | ||
259 | } | ||
260 | EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put_beep); | ||
diff --git a/sound/pci/hda/hda_beep.h b/sound/pci/hda/hda_beep.h index 55f0647458c..4dc6933bc65 100644 --- a/sound/pci/hda/hda_beep.h +++ b/sound/pci/hda/hda_beep.h | |||
@@ -26,21 +26,16 @@ | |||
26 | 26 | ||
27 | #define HDA_BEEP_MODE_OFF 0 | 27 | #define HDA_BEEP_MODE_OFF 0 |
28 | #define HDA_BEEP_MODE_ON 1 | 28 | #define HDA_BEEP_MODE_ON 1 |
29 | #define HDA_BEEP_MODE_SWREG 2 | ||
30 | 29 | ||
31 | /* beep information */ | 30 | /* beep information */ |
32 | struct hda_beep { | 31 | struct hda_beep { |
33 | struct input_dev *dev; | 32 | struct input_dev *dev; |
34 | struct hda_codec *codec; | 33 | struct hda_codec *codec; |
35 | unsigned int mode; | ||
36 | char phys[32]; | 34 | char phys[32]; |
37 | int tone; | 35 | int tone; |
38 | hda_nid_t nid; | 36 | hda_nid_t nid; |
39 | unsigned int enabled:1; | 37 | unsigned int enabled:1; |
40 | unsigned int request_enable:1; | ||
41 | unsigned int linear_tone:1; /* linear tone for IDT/STAC codec */ | 38 | unsigned int linear_tone:1; /* linear tone for IDT/STAC codec */ |
42 | struct work_struct register_work; /* registration work */ | ||
43 | struct delayed_work unregister_work; /* unregistration work */ | ||
44 | struct work_struct beep_work; /* scheduled task for beep event */ | 39 | struct work_struct beep_work; /* scheduled task for beep event */ |
45 | struct mutex mutex; | 40 | struct mutex mutex; |
46 | }; | 41 | }; |
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 7504e62188d..20580bf6969 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -1184,6 +1184,7 @@ static void snd_hda_codec_free(struct hda_codec *codec) | |||
1184 | { | 1184 | { |
1185 | if (!codec) | 1185 | if (!codec) |
1186 | return; | 1186 | return; |
1187 | snd_hda_jack_tbl_clear(codec); | ||
1187 | restore_init_pincfgs(codec); | 1188 | restore_init_pincfgs(codec); |
1188 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 1189 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
1189 | cancel_delayed_work(&codec->power_work); | 1190 | cancel_delayed_work(&codec->power_work); |
@@ -1192,6 +1193,7 @@ static void snd_hda_codec_free(struct hda_codec *codec) | |||
1192 | list_del(&codec->list); | 1193 | list_del(&codec->list); |
1193 | snd_array_free(&codec->mixers); | 1194 | snd_array_free(&codec->mixers); |
1194 | snd_array_free(&codec->nids); | 1195 | snd_array_free(&codec->nids); |
1196 | snd_array_free(&codec->cvt_setups); | ||
1195 | snd_array_free(&codec->conn_lists); | 1197 | snd_array_free(&codec->conn_lists); |
1196 | snd_array_free(&codec->spdif_out); | 1198 | snd_array_free(&codec->spdif_out); |
1197 | codec->bus->caddr_tbl[codec->addr] = NULL; | 1199 | codec->bus->caddr_tbl[codec->addr] = NULL; |
@@ -2333,6 +2335,8 @@ int snd_hda_codec_reset(struct hda_codec *codec) | |||
2333 | /* free only driver_pins so that init_pins + user_pins are restored */ | 2335 | /* free only driver_pins so that init_pins + user_pins are restored */ |
2334 | snd_array_free(&codec->driver_pins); | 2336 | snd_array_free(&codec->driver_pins); |
2335 | restore_pincfgs(codec); | 2337 | restore_pincfgs(codec); |
2338 | snd_array_free(&codec->cvt_setups); | ||
2339 | snd_array_free(&codec->spdif_out); | ||
2336 | codec->num_pcms = 0; | 2340 | codec->num_pcms = 0; |
2337 | codec->pcm_info = NULL; | 2341 | codec->pcm_info = NULL; |
2338 | codec->preset = NULL; | 2342 | codec->preset = NULL; |
@@ -2672,25 +2676,6 @@ int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, | |||
2672 | } | 2676 | } |
2673 | EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put); | 2677 | EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put); |
2674 | 2678 | ||
2675 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | ||
2676 | /** | ||
2677 | * snd_hda_mixer_amp_switch_put_beep - Put callback for a beep AMP switch | ||
2678 | * | ||
2679 | * This function calls snd_hda_enable_beep_device(), which behaves differently | ||
2680 | * depending on beep_mode option. | ||
2681 | */ | ||
2682 | int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol, | ||
2683 | struct snd_ctl_elem_value *ucontrol) | ||
2684 | { | ||
2685 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
2686 | long *valp = ucontrol->value.integer.value; | ||
2687 | |||
2688 | snd_hda_enable_beep_device(codec, *valp); | ||
2689 | return snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); | ||
2690 | } | ||
2691 | EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put_beep); | ||
2692 | #endif /* CONFIG_SND_HDA_INPUT_BEEP */ | ||
2693 | |||
2694 | /* | 2679 | /* |
2695 | * bound volume controls | 2680 | * bound volume controls |
2696 | * | 2681 | * |
@@ -3505,22 +3490,52 @@ void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg, | |||
3505 | EXPORT_SYMBOL_HDA(snd_hda_codec_set_power_to_all); | 3490 | EXPORT_SYMBOL_HDA(snd_hda_codec_set_power_to_all); |
3506 | 3491 | ||
3507 | /* | 3492 | /* |
3493 | * supported power states check | ||
3494 | */ | ||
3495 | static bool snd_hda_codec_get_supported_ps(struct hda_codec *codec, hda_nid_t fg, | ||
3496 | unsigned int power_state) | ||
3497 | { | ||
3498 | int sup = snd_hda_param_read(codec, fg, AC_PAR_POWER_STATE); | ||
3499 | |||
3500 | if (sup < 0) | ||
3501 | return false; | ||
3502 | if (sup & power_state) | ||
3503 | return true; | ||
3504 | else | ||
3505 | return false; | ||
3506 | } | ||
3507 | |||
3508 | /* | ||
3508 | * set power state of the codec | 3509 | * set power state of the codec |
3509 | */ | 3510 | */ |
3510 | static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, | 3511 | static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg, |
3511 | unsigned int power_state) | 3512 | unsigned int power_state) |
3512 | { | 3513 | { |
3514 | int count; | ||
3515 | unsigned int state; | ||
3516 | |||
3513 | if (codec->patch_ops.set_power_state) { | 3517 | if (codec->patch_ops.set_power_state) { |
3514 | codec->patch_ops.set_power_state(codec, fg, power_state); | 3518 | codec->patch_ops.set_power_state(codec, fg, power_state); |
3515 | return; | 3519 | return; |
3516 | } | 3520 | } |
3517 | 3521 | ||
3518 | /* this delay seems necessary to avoid click noise at power-down */ | 3522 | /* this delay seems necessary to avoid click noise at power-down */ |
3519 | if (power_state == AC_PWRST_D3) | 3523 | if (power_state == AC_PWRST_D3) { |
3520 | msleep(100); | 3524 | /* transition time less than 10ms for power down */ |
3521 | snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE, | 3525 | bool epss = snd_hda_codec_get_supported_ps(codec, fg, AC_PWRST_EPSS); |
3522 | power_state); | 3526 | msleep(epss ? 10 : 100); |
3523 | snd_hda_codec_set_power_to_all(codec, fg, power_state, true); | 3527 | } |
3528 | |||
3529 | /* repeat power states setting at most 10 times*/ | ||
3530 | for (count = 0; count < 10; count++) { | ||
3531 | snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE, | ||
3532 | power_state); | ||
3533 | snd_hda_codec_set_power_to_all(codec, fg, power_state, true); | ||
3534 | state = snd_hda_codec_read(codec, fg, 0, | ||
3535 | AC_VERB_GET_POWER_STATE, 0); | ||
3536 | if (!(state & AC_PWRST_ERROR)) | ||
3537 | break; | ||
3538 | } | ||
3524 | } | 3539 | } |
3525 | 3540 | ||
3526 | #ifdef CONFIG_SND_HDA_HWDEP | 3541 | #ifdef CONFIG_SND_HDA_HWDEP |
@@ -4414,6 +4429,13 @@ static void __snd_hda_power_up(struct hda_codec *codec, bool wait_power_down) | |||
4414 | cancel_delayed_work_sync(&codec->power_work); | 4429 | cancel_delayed_work_sync(&codec->power_work); |
4415 | 4430 | ||
4416 | spin_lock(&codec->power_lock); | 4431 | spin_lock(&codec->power_lock); |
4432 | /* If the power down delayed work was cancelled above before starting, | ||
4433 | * then there is no need to go through power up here. | ||
4434 | */ | ||
4435 | if (codec->power_on) { | ||
4436 | spin_unlock(&codec->power_lock); | ||
4437 | return; | ||
4438 | } | ||
4417 | trace_hda_power_up(codec); | 4439 | trace_hda_power_up(codec); |
4418 | snd_hda_update_power_acct(codec); | 4440 | snd_hda_update_power_acct(codec); |
4419 | codec->power_on = 1; | 4441 | codec->power_on = 1; |
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index 2fdaadbb432..a4ac1de7aa1 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
@@ -323,6 +323,9 @@ enum { | |||
323 | #define AC_PWRST_D1 0x01 | 323 | #define AC_PWRST_D1 0x01 |
324 | #define AC_PWRST_D2 0x02 | 324 | #define AC_PWRST_D2 0x02 |
325 | #define AC_PWRST_D3 0x03 | 325 | #define AC_PWRST_D3 0x03 |
326 | #define AC_PWRST_ERROR (1<<8) | ||
327 | #define AC_PWRST_CLK_STOP_OK (1<<9) | ||
328 | #define AC_PWRST_SETTING_RESET (1<<10) | ||
326 | 329 | ||
327 | /* Processing capabilies */ | 330 | /* Processing capabilies */ |
328 | #define AC_PCAP_BENIGN (1<<0) | 331 | #define AC_PCAP_BENIGN (1<<0) |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 7757536b9d5..b4f3c7295a5 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -72,7 +72,7 @@ static int enable_msi = -1; | |||
72 | static char *patch[SNDRV_CARDS]; | 72 | static char *patch[SNDRV_CARDS]; |
73 | #endif | 73 | #endif |
74 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | 74 | #ifdef CONFIG_SND_HDA_INPUT_BEEP |
75 | static int beep_mode[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = | 75 | static bool beep_mode[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = |
76 | CONFIG_SND_HDA_INPUT_BEEP_MODE}; | 76 | CONFIG_SND_HDA_INPUT_BEEP_MODE}; |
77 | #endif | 77 | #endif |
78 | 78 | ||
@@ -103,9 +103,9 @@ module_param_array(patch, charp, NULL, 0444); | |||
103 | MODULE_PARM_DESC(patch, "Patch file for Intel HD audio interface."); | 103 | MODULE_PARM_DESC(patch, "Patch file for Intel HD audio interface."); |
104 | #endif | 104 | #endif |
105 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | 105 | #ifdef CONFIG_SND_HDA_INPUT_BEEP |
106 | module_param_array(beep_mode, int, NULL, 0444); | 106 | module_param_array(beep_mode, bool, NULL, 0444); |
107 | MODULE_PARM_DESC(beep_mode, "Select HDA Beep registration mode " | 107 | MODULE_PARM_DESC(beep_mode, "Select HDA Beep registration mode " |
108 | "(0=off, 1=on, 2=mute switch on/off) (default=1)."); | 108 | "(0=off, 1=on) (default=1)."); |
109 | #endif | 109 | #endif |
110 | 110 | ||
111 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 111 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
@@ -151,6 +151,7 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6}," | |||
151 | "{Intel, CPT}," | 151 | "{Intel, CPT}," |
152 | "{Intel, PPT}," | 152 | "{Intel, PPT}," |
153 | "{Intel, LPT}," | 153 | "{Intel, LPT}," |
154 | "{Intel, HPT}," | ||
154 | "{Intel, PBG}," | 155 | "{Intel, PBG}," |
155 | "{Intel, SCH}," | 156 | "{Intel, SCH}," |
156 | "{ATI, SB450}," | 157 | "{ATI, SB450}," |
@@ -535,6 +536,7 @@ enum { | |||
535 | #define AZX_DCAPS_BUFSIZE (1 << 21) /* no buffer size alignment */ | 536 | #define AZX_DCAPS_BUFSIZE (1 << 21) /* no buffer size alignment */ |
536 | #define AZX_DCAPS_ALIGN_BUFSIZE (1 << 22) /* buffer size alignment */ | 537 | #define AZX_DCAPS_ALIGN_BUFSIZE (1 << 22) /* buffer size alignment */ |
537 | #define AZX_DCAPS_4K_BDLE_BOUNDARY (1 << 23) /* BDLE in 4k boundary */ | 538 | #define AZX_DCAPS_4K_BDLE_BOUNDARY (1 << 23) /* BDLE in 4k boundary */ |
539 | #define AZX_DCAPS_POSFIX_COMBO (1 << 24) /* Use COMBO as default */ | ||
538 | 540 | ||
539 | /* quirks for ATI SB / AMD Hudson */ | 541 | /* quirks for ATI SB / AMD Hudson */ |
540 | #define AZX_DCAPS_PRESET_ATI_SB \ | 542 | #define AZX_DCAPS_PRESET_ATI_SB \ |
@@ -2731,6 +2733,10 @@ static int __devinit check_position_fix(struct azx *chip, int fix) | |||
2731 | snd_printd(SFX "Using LPIB position fix\n"); | 2733 | snd_printd(SFX "Using LPIB position fix\n"); |
2732 | return POS_FIX_LPIB; | 2734 | return POS_FIX_LPIB; |
2733 | } | 2735 | } |
2736 | if (chip->driver_caps & AZX_DCAPS_POSFIX_COMBO) { | ||
2737 | snd_printd(SFX "Using COMBO position fix\n"); | ||
2738 | return POS_FIX_COMBO; | ||
2739 | } | ||
2734 | return POS_FIX_AUTO; | 2740 | return POS_FIX_AUTO; |
2735 | } | 2741 | } |
2736 | 2742 | ||
@@ -3243,7 +3249,7 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { | |||
3243 | /* CPT */ | 3249 | /* CPT */ |
3244 | { PCI_DEVICE(0x8086, 0x1c20), | 3250 | { PCI_DEVICE(0x8086, 0x1c20), |
3245 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | | 3251 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | |
3246 | AZX_DCAPS_BUFSIZE }, | 3252 | AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO }, |
3247 | /* PBG */ | 3253 | /* PBG */ |
3248 | { PCI_DEVICE(0x8086, 0x1d20), | 3254 | { PCI_DEVICE(0x8086, 0x1d20), |
3249 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | | 3255 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | |
@@ -3251,11 +3257,15 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { | |||
3251 | /* Panther Point */ | 3257 | /* Panther Point */ |
3252 | { PCI_DEVICE(0x8086, 0x1e20), | 3258 | { PCI_DEVICE(0x8086, 0x1e20), |
3253 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | | 3259 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | |
3254 | AZX_DCAPS_BUFSIZE}, | 3260 | AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO }, |
3255 | /* Lynx Point */ | 3261 | /* Lynx Point */ |
3256 | { PCI_DEVICE(0x8086, 0x8c20), | 3262 | { PCI_DEVICE(0x8086, 0x8c20), |
3257 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | | 3263 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | |
3258 | AZX_DCAPS_BUFSIZE}, | 3264 | AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO }, |
3265 | /* Haswell */ | ||
3266 | { PCI_DEVICE(0x8086, 0x0c0c), | ||
3267 | .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | | ||
3268 | AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO }, | ||
3259 | /* SCH */ | 3269 | /* SCH */ |
3260 | { PCI_DEVICE(0x8086, 0x811b), | 3270 | { PCI_DEVICE(0x8086, 0x811b), |
3261 | .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | | 3271 | .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | |
@@ -3341,6 +3351,10 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { | |||
3341 | /* VIA VT8251/VT8237A */ | 3351 | /* VIA VT8251/VT8237A */ |
3342 | { PCI_DEVICE(0x1106, 0x3288), | 3352 | { PCI_DEVICE(0x1106, 0x3288), |
3343 | .driver_data = AZX_DRIVER_VIA | AZX_DCAPS_POSFIX_VIA }, | 3353 | .driver_data = AZX_DRIVER_VIA | AZX_DCAPS_POSFIX_VIA }, |
3354 | /* VIA GFX VT7122/VX900 */ | ||
3355 | { PCI_DEVICE(0x1106, 0x9170), .driver_data = AZX_DRIVER_GENERIC }, | ||
3356 | /* VIA GFX VT6122/VX11 */ | ||
3357 | { PCI_DEVICE(0x1106, 0x9140), .driver_data = AZX_DRIVER_GENERIC }, | ||
3344 | /* SIS966 */ | 3358 | /* SIS966 */ |
3345 | { PCI_DEVICE(0x1039, 0x7502), .driver_data = AZX_DRIVER_SIS }, | 3359 | { PCI_DEVICE(0x1039, 0x7502), .driver_data = AZX_DRIVER_SIS }, |
3346 | /* ULI M5461 */ | 3360 | /* ULI M5461 */ |
diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c index 2dd1c113a4c..aaccc0236bd 100644 --- a/sound/pci/hda/hda_jack.c +++ b/sound/pci/hda/hda_jack.c | |||
@@ -127,10 +127,15 @@ void snd_hda_jack_tbl_clear(struct hda_codec *codec) | |||
127 | static void jack_detect_update(struct hda_codec *codec, | 127 | static void jack_detect_update(struct hda_codec *codec, |
128 | struct hda_jack_tbl *jack) | 128 | struct hda_jack_tbl *jack) |
129 | { | 129 | { |
130 | if (jack->jack_dirty || !jack->jack_detect) { | 130 | if (!jack->jack_dirty) |
131 | return; | ||
132 | |||
133 | if (jack->phantom_jack) | ||
134 | jack->pin_sense = AC_PINSENSE_PRESENCE; | ||
135 | else | ||
131 | jack->pin_sense = read_pin_sense(codec, jack->nid); | 136 | jack->pin_sense = read_pin_sense(codec, jack->nid); |
132 | jack->jack_dirty = 0; | 137 | |
133 | } | 138 | jack->jack_dirty = 0; |
134 | } | 139 | } |
135 | 140 | ||
136 | /** | 141 | /** |
@@ -264,8 +269,8 @@ static void hda_free_jack_priv(struct snd_jack *jack) | |||
264 | * This assigns a jack-detection kctl to the given pin. The kcontrol | 269 | * This assigns a jack-detection kctl to the given pin. The kcontrol |
265 | * will have the given name and index. | 270 | * will have the given name and index. |
266 | */ | 271 | */ |
267 | int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, | 272 | static int __snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, |
268 | const char *name, int idx) | 273 | const char *name, int idx, bool phantom_jack) |
269 | { | 274 | { |
270 | struct hda_jack_tbl *jack; | 275 | struct hda_jack_tbl *jack; |
271 | struct snd_kcontrol *kctl; | 276 | struct snd_kcontrol *kctl; |
@@ -283,47 +288,81 @@ int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, | |||
283 | if (err < 0) | 288 | if (err < 0) |
284 | return err; | 289 | return err; |
285 | jack->kctl = kctl; | 290 | jack->kctl = kctl; |
291 | jack->phantom_jack = !!phantom_jack; | ||
292 | |||
286 | state = snd_hda_jack_detect(codec, nid); | 293 | state = snd_hda_jack_detect(codec, nid); |
287 | snd_kctl_jack_report(codec->bus->card, kctl, state); | 294 | snd_kctl_jack_report(codec->bus->card, kctl, state); |
288 | #ifdef CONFIG_SND_HDA_INPUT_JACK | 295 | #ifdef CONFIG_SND_HDA_INPUT_JACK |
289 | jack->type = get_input_jack_type(codec, nid); | 296 | if (!phantom_jack) { |
290 | err = snd_jack_new(codec->bus->card, name, jack->type, &jack->jack); | 297 | jack->type = get_input_jack_type(codec, nid); |
291 | if (err < 0) | 298 | err = snd_jack_new(codec->bus->card, name, jack->type, |
292 | return err; | 299 | &jack->jack); |
293 | jack->jack->private_data = jack; | 300 | if (err < 0) |
294 | jack->jack->private_free = hda_free_jack_priv; | 301 | return err; |
295 | snd_jack_report(jack->jack, state ? jack->type : 0); | 302 | jack->jack->private_data = jack; |
303 | jack->jack->private_free = hda_free_jack_priv; | ||
304 | snd_jack_report(jack->jack, state ? jack->type : 0); | ||
305 | } | ||
296 | #endif | 306 | #endif |
297 | return 0; | 307 | return 0; |
298 | } | 308 | } |
309 | |||
310 | int snd_hda_jack_add_kctl(struct hda_codec *codec, hda_nid_t nid, | ||
311 | const char *name, int idx) | ||
312 | { | ||
313 | return __snd_hda_jack_add_kctl(codec, nid, name, idx, false); | ||
314 | } | ||
299 | EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctl); | 315 | EXPORT_SYMBOL_HDA(snd_hda_jack_add_kctl); |
300 | 316 | ||
317 | /* get the unique index number for the given kctl name */ | ||
318 | static int get_unique_index(struct hda_codec *codec, const char *name, int idx) | ||
319 | { | ||
320 | struct hda_jack_tbl *jack; | ||
321 | int i, len = strlen(name); | ||
322 | again: | ||
323 | jack = codec->jacktbl.list; | ||
324 | for (i = 0; i < codec->jacktbl.used; i++, jack++) { | ||
325 | /* jack->kctl.id contains "XXX Jack" name string with index */ | ||
326 | if (jack->kctl && | ||
327 | !strncmp(name, jack->kctl->id.name, len) && | ||
328 | !strcmp(" Jack", jack->kctl->id.name + len) && | ||
329 | jack->kctl->id.index == idx) { | ||
330 | idx++; | ||
331 | goto again; | ||
332 | } | ||
333 | } | ||
334 | return idx; | ||
335 | } | ||
336 | |||
301 | static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, | 337 | static int add_jack_kctl(struct hda_codec *codec, hda_nid_t nid, |
302 | const struct auto_pin_cfg *cfg, | 338 | const struct auto_pin_cfg *cfg) |
303 | char *lastname, int *lastidx) | ||
304 | { | 339 | { |
305 | unsigned int def_conf, conn; | 340 | unsigned int def_conf, conn; |
306 | char name[44]; | 341 | char name[44]; |
307 | int idx, err; | 342 | int idx, err; |
343 | bool phantom_jack; | ||
308 | 344 | ||
309 | if (!nid) | 345 | if (!nid) |
310 | return 0; | 346 | return 0; |
311 | if (!is_jack_detectable(codec, nid)) | ||
312 | return 0; | ||
313 | def_conf = snd_hda_codec_get_pincfg(codec, nid); | 347 | def_conf = snd_hda_codec_get_pincfg(codec, nid); |
314 | conn = get_defcfg_connect(def_conf); | 348 | conn = get_defcfg_connect(def_conf); |
315 | if (conn != AC_JACK_PORT_COMPLEX) | 349 | if (conn == AC_JACK_PORT_NONE) |
316 | return 0; | 350 | return 0; |
351 | phantom_jack = (conn != AC_JACK_PORT_COMPLEX) || | ||
352 | !is_jack_detectable(codec, nid); | ||
317 | 353 | ||
318 | snd_hda_get_pin_label(codec, nid, cfg, name, sizeof(name), &idx); | 354 | snd_hda_get_pin_label(codec, nid, cfg, name, sizeof(name), &idx); |
319 | if (!strcmp(name, lastname) && idx == *lastidx) | 355 | if (phantom_jack) |
320 | idx++; | 356 | /* Example final name: "Internal Mic Phantom Jack" */ |
321 | strncpy(lastname, name, 44); | 357 | strncat(name, " Phantom", sizeof(name) - strlen(name) - 1); |
322 | *lastidx = idx; | 358 | idx = get_unique_index(codec, name, idx); |
323 | err = snd_hda_jack_add_kctl(codec, nid, name, idx); | 359 | err = __snd_hda_jack_add_kctl(codec, nid, name, idx, phantom_jack); |
324 | if (err < 0) | 360 | if (err < 0) |
325 | return err; | 361 | return err; |
326 | return snd_hda_jack_detect_enable(codec, nid, 0); | 362 | |
363 | if (!phantom_jack) | ||
364 | return snd_hda_jack_detect_enable(codec, nid, 0); | ||
365 | return 0; | ||
327 | } | 366 | } |
328 | 367 | ||
329 | /** | 368 | /** |
@@ -333,42 +372,41 @@ int snd_hda_jack_add_kctls(struct hda_codec *codec, | |||
333 | const struct auto_pin_cfg *cfg) | 372 | const struct auto_pin_cfg *cfg) |
334 | { | 373 | { |
335 | const hda_nid_t *p; | 374 | const hda_nid_t *p; |
336 | int i, err, lastidx = 0; | 375 | int i, err; |
337 | char lastname[44] = ""; | ||
338 | 376 | ||
339 | for (i = 0, p = cfg->line_out_pins; i < cfg->line_outs; i++, p++) { | 377 | for (i = 0, p = cfg->line_out_pins; i < cfg->line_outs; i++, p++) { |
340 | err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx); | 378 | err = add_jack_kctl(codec, *p, cfg); |
341 | if (err < 0) | 379 | if (err < 0) |
342 | return err; | 380 | return err; |
343 | } | 381 | } |
344 | for (i = 0, p = cfg->hp_pins; i < cfg->hp_outs; i++, p++) { | 382 | for (i = 0, p = cfg->hp_pins; i < cfg->hp_outs; i++, p++) { |
345 | if (*p == *cfg->line_out_pins) /* might be duplicated */ | 383 | if (*p == *cfg->line_out_pins) /* might be duplicated */ |
346 | break; | 384 | break; |
347 | err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx); | 385 | err = add_jack_kctl(codec, *p, cfg); |
348 | if (err < 0) | 386 | if (err < 0) |
349 | return err; | 387 | return err; |
350 | } | 388 | } |
351 | for (i = 0, p = cfg->speaker_pins; i < cfg->speaker_outs; i++, p++) { | 389 | for (i = 0, p = cfg->speaker_pins; i < cfg->speaker_outs; i++, p++) { |
352 | if (*p == *cfg->line_out_pins) /* might be duplicated */ | 390 | if (*p == *cfg->line_out_pins) /* might be duplicated */ |
353 | break; | 391 | break; |
354 | err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx); | 392 | err = add_jack_kctl(codec, *p, cfg); |
355 | if (err < 0) | 393 | if (err < 0) |
356 | return err; | 394 | return err; |
357 | } | 395 | } |
358 | for (i = 0; i < cfg->num_inputs; i++) { | 396 | for (i = 0; i < cfg->num_inputs; i++) { |
359 | err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg, lastname, &lastidx); | 397 | err = add_jack_kctl(codec, cfg->inputs[i].pin, cfg); |
360 | if (err < 0) | 398 | if (err < 0) |
361 | return err; | 399 | return err; |
362 | } | 400 | } |
363 | for (i = 0, p = cfg->dig_out_pins; i < cfg->dig_outs; i++, p++) { | 401 | for (i = 0, p = cfg->dig_out_pins; i < cfg->dig_outs; i++, p++) { |
364 | err = add_jack_kctl(codec, *p, cfg, lastname, &lastidx); | 402 | err = add_jack_kctl(codec, *p, cfg); |
365 | if (err < 0) | 403 | if (err < 0) |
366 | return err; | 404 | return err; |
367 | } | 405 | } |
368 | err = add_jack_kctl(codec, cfg->dig_in_pin, cfg, lastname, &lastidx); | 406 | err = add_jack_kctl(codec, cfg->dig_in_pin, cfg); |
369 | if (err < 0) | 407 | if (err < 0) |
370 | return err; | 408 | return err; |
371 | err = add_jack_kctl(codec, cfg->mono_out_pin, cfg, lastname, &lastidx); | 409 | err = add_jack_kctl(codec, cfg->mono_out_pin, cfg); |
372 | if (err < 0) | 410 | if (err < 0) |
373 | return err; | 411 | return err; |
374 | return 0; | 412 | return 0; |
diff --git a/sound/pci/hda/hda_jack.h b/sound/pci/hda/hda_jack.h index 8ae52465ec5..a9803da633c 100644 --- a/sound/pci/hda/hda_jack.h +++ b/sound/pci/hda/hda_jack.h | |||
@@ -23,6 +23,7 @@ struct hda_jack_tbl { | |||
23 | unsigned int pin_sense; /* cached pin-sense value */ | 23 | unsigned int pin_sense; /* cached pin-sense value */ |
24 | unsigned int jack_detect:1; /* capable of jack-detection? */ | 24 | unsigned int jack_detect:1; /* capable of jack-detection? */ |
25 | unsigned int jack_dirty:1; /* needs to update? */ | 25 | unsigned int jack_dirty:1; /* needs to update? */ |
26 | unsigned int phantom_jack:1; /* a fixed, always present port? */ | ||
26 | struct snd_kcontrol *kctl; /* assigned kctl for jack-detection */ | 27 | struct snd_kcontrol *kctl; /* assigned kctl for jack-detection */ |
27 | #ifdef CONFIG_SND_HDA_INPUT_JACK | 28 | #ifdef CONFIG_SND_HDA_INPUT_JACK |
28 | int type; | 29 | int type; |
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index 9a096a8e0fc..1b4c12941ba 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h | |||
@@ -89,7 +89,7 @@ | |||
89 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ | 89 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ |
90 | .subdevice = HDA_SUBDEV_AMP_FLAG, \ | 90 | .subdevice = HDA_SUBDEV_AMP_FLAG, \ |
91 | .info = snd_hda_mixer_amp_switch_info, \ | 91 | .info = snd_hda_mixer_amp_switch_info, \ |
92 | .get = snd_hda_mixer_amp_switch_get, \ | 92 | .get = snd_hda_mixer_amp_switch_get_beep, \ |
93 | .put = snd_hda_mixer_amp_switch_put_beep, \ | 93 | .put = snd_hda_mixer_amp_switch_put_beep, \ |
94 | .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) } | 94 | .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) } |
95 | #else | 95 | #else |
@@ -121,6 +121,8 @@ int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, | |||
121 | int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, | 121 | int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, |
122 | struct snd_ctl_elem_value *ucontrol); | 122 | struct snd_ctl_elem_value *ucontrol); |
123 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | 123 | #ifdef CONFIG_SND_HDA_INPUT_BEEP |
124 | int snd_hda_mixer_amp_switch_get_beep(struct snd_kcontrol *kcontrol, | ||
125 | struct snd_ctl_elem_value *ucontrol); | ||
124 | int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol, | 126 | int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol, |
125 | struct snd_ctl_elem_value *ucontrol); | 127 | struct snd_ctl_elem_value *ucontrol); |
126 | #endif | 128 | #endif |
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c index e59e2f059b6..7e46258fc70 100644 --- a/sound/pci/hda/hda_proc.c +++ b/sound/pci/hda/hda_proc.c | |||
@@ -426,10 +426,10 @@ static void print_digital_conv(struct snd_info_buffer *buffer, | |||
426 | 426 | ||
427 | static const char *get_pwr_state(u32 state) | 427 | static const char *get_pwr_state(u32 state) |
428 | { | 428 | { |
429 | static const char * const buf[4] = { | 429 | static const char * const buf[] = { |
430 | "D0", "D1", "D2", "D3" | 430 | "D0", "D1", "D2", "D3", "D3cold" |
431 | }; | 431 | }; |
432 | if (state < 4) | 432 | if (state < ARRAY_SIZE(buf)) |
433 | return buf[state]; | 433 | return buf[state]; |
434 | return "UNKNOWN"; | 434 | return "UNKNOWN"; |
435 | } | 435 | } |
@@ -451,14 +451,21 @@ static void print_power_state(struct snd_info_buffer *buffer, | |||
451 | int sup = snd_hda_param_read(codec, nid, AC_PAR_POWER_STATE); | 451 | int sup = snd_hda_param_read(codec, nid, AC_PAR_POWER_STATE); |
452 | int pwr = snd_hda_codec_read(codec, nid, 0, | 452 | int pwr = snd_hda_codec_read(codec, nid, 0, |
453 | AC_VERB_GET_POWER_STATE, 0); | 453 | AC_VERB_GET_POWER_STATE, 0); |
454 | if (sup) | 454 | if (sup != -1) |
455 | snd_iprintf(buffer, " Power states: %s\n", | 455 | snd_iprintf(buffer, " Power states: %s\n", |
456 | bits_names(sup, names, ARRAY_SIZE(names))); | 456 | bits_names(sup, names, ARRAY_SIZE(names))); |
457 | 457 | ||
458 | snd_iprintf(buffer, " Power: setting=%s, actual=%s\n", | 458 | snd_iprintf(buffer, " Power: setting=%s, actual=%s", |
459 | get_pwr_state(pwr & AC_PWRST_SETTING), | 459 | get_pwr_state(pwr & AC_PWRST_SETTING), |
460 | get_pwr_state((pwr & AC_PWRST_ACTUAL) >> | 460 | get_pwr_state((pwr & AC_PWRST_ACTUAL) >> |
461 | AC_PWRST_ACTUAL_SHIFT)); | 461 | AC_PWRST_ACTUAL_SHIFT)); |
462 | if (pwr & AC_PWRST_ERROR) | ||
463 | snd_iprintf(buffer, ", Error"); | ||
464 | if (pwr & AC_PWRST_CLK_STOP_OK) | ||
465 | snd_iprintf(buffer, ", Clock-stop-OK"); | ||
466 | if (pwr & AC_PWRST_SETTING_RESET) | ||
467 | snd_iprintf(buffer, ", Setting-reset"); | ||
468 | snd_iprintf(buffer, "\n"); | ||
462 | } | 469 | } |
463 | 470 | ||
464 | static void print_unsol_cap(struct snd_info_buffer *buffer, | 471 | static void print_unsol_cap(struct snd_info_buffer *buffer, |
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 172370b3793..2bf99fc1cbf 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -445,8 +445,10 @@ static int conexant_init(struct hda_codec *codec) | |||
445 | 445 | ||
446 | static void conexant_free(struct hda_codec *codec) | 446 | static void conexant_free(struct hda_codec *codec) |
447 | { | 447 | { |
448 | struct conexant_spec *spec = codec->spec; | ||
449 | snd_hda_gen_free(&spec->gen); | ||
448 | snd_hda_detach_beep_device(codec); | 450 | snd_hda_detach_beep_device(codec); |
449 | kfree(codec->spec); | 451 | kfree(spec); |
450 | } | 452 | } |
451 | 453 | ||
452 | static const struct snd_kcontrol_new cxt_capture_mixers[] = { | 454 | static const struct snd_kcontrol_new cxt_capture_mixers[] = { |
@@ -4466,6 +4468,7 @@ static const struct snd_pci_quirk cxt5066_fixups[] = { | |||
4466 | SND_PCI_QUIRK(0x17aa, 0x21ce, "Lenovo T420", CXT_PINCFG_LENOVO_TP410), | 4468 | SND_PCI_QUIRK(0x17aa, 0x21ce, "Lenovo T420", CXT_PINCFG_LENOVO_TP410), |
4467 | SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520", CXT_PINCFG_LENOVO_TP410), | 4469 | SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520", CXT_PINCFG_LENOVO_TP410), |
4468 | SND_PCI_QUIRK(0x17aa, 0x3975, "Lenovo U300s", CXT_FIXUP_STEREO_DMIC), | 4470 | SND_PCI_QUIRK(0x17aa, 0x3975, "Lenovo U300s", CXT_FIXUP_STEREO_DMIC), |
4471 | SND_PCI_QUIRK(0x17aa, 0x397b, "Lenovo S205", CXT_FIXUP_STEREO_DMIC), | ||
4469 | {} | 4472 | {} |
4470 | }; | 4473 | }; |
4471 | 4474 | ||
@@ -4497,6 +4500,7 @@ static int patch_conexant_auto(struct hda_codec *codec) | |||
4497 | if (!spec) | 4500 | if (!spec) |
4498 | return -ENOMEM; | 4501 | return -ENOMEM; |
4499 | codec->spec = spec; | 4502 | codec->spec = spec; |
4503 | snd_hda_gen_init(&spec->gen); | ||
4500 | 4504 | ||
4501 | switch (codec->vendor_id) { | 4505 | switch (codec->vendor_id) { |
4502 | case 0x14f15045: | 4506 | case 0x14f15045: |
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index ad319d4dc32..0b4a1ea147c 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c | |||
@@ -85,7 +85,7 @@ struct hdmi_spec { | |||
85 | * Non-generic ATI/NVIDIA specific | 85 | * Non-generic ATI/NVIDIA specific |
86 | */ | 86 | */ |
87 | struct hda_multi_out multiout; | 87 | struct hda_multi_out multiout; |
88 | const struct hda_pcm_stream *pcm_playback; | 88 | struct hda_pcm_stream pcm_playback; |
89 | }; | 89 | }; |
90 | 90 | ||
91 | 91 | ||
@@ -787,7 +787,7 @@ static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res) | |||
787 | int cp_ready = !!(res & AC_UNSOL_RES_CP_READY); | 787 | int cp_ready = !!(res & AC_UNSOL_RES_CP_READY); |
788 | 788 | ||
789 | printk(KERN_INFO | 789 | printk(KERN_INFO |
790 | "HDMI CP event: CODEC=%d PIN=%d SUBTAG=0x%x CP_STATE=%d CP_READY=%d\n", | 790 | "HDMI CP event: CODEC=%d TAG=%d SUBTAG=0x%x CP_STATE=%d CP_READY=%d\n", |
791 | codec->addr, | 791 | codec->addr, |
792 | tag, | 792 | tag, |
793 | subtag, | 793 | subtag, |
@@ -1277,23 +1277,34 @@ static int generic_hdmi_build_controls(struct hda_codec *codec) | |||
1277 | return 0; | 1277 | return 0; |
1278 | } | 1278 | } |
1279 | 1279 | ||
1280 | static int generic_hdmi_init(struct hda_codec *codec) | 1280 | static int generic_hdmi_init_per_pins(struct hda_codec *codec) |
1281 | { | 1281 | { |
1282 | struct hdmi_spec *spec = codec->spec; | 1282 | struct hdmi_spec *spec = codec->spec; |
1283 | int pin_idx; | 1283 | int pin_idx; |
1284 | 1284 | ||
1285 | for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { | 1285 | for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { |
1286 | struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; | 1286 | struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; |
1287 | hda_nid_t pin_nid = per_pin->pin_nid; | ||
1288 | struct hdmi_eld *eld = &per_pin->sink_eld; | 1287 | struct hdmi_eld *eld = &per_pin->sink_eld; |
1289 | 1288 | ||
1290 | hdmi_init_pin(codec, pin_nid); | ||
1291 | snd_hda_jack_detect_enable(codec, pin_nid, pin_nid); | ||
1292 | |||
1293 | per_pin->codec = codec; | 1289 | per_pin->codec = codec; |
1294 | INIT_DELAYED_WORK(&per_pin->work, hdmi_repoll_eld); | 1290 | INIT_DELAYED_WORK(&per_pin->work, hdmi_repoll_eld); |
1295 | snd_hda_eld_proc_new(codec, eld, pin_idx); | 1291 | snd_hda_eld_proc_new(codec, eld, pin_idx); |
1296 | } | 1292 | } |
1293 | return 0; | ||
1294 | } | ||
1295 | |||
1296 | static int generic_hdmi_init(struct hda_codec *codec) | ||
1297 | { | ||
1298 | struct hdmi_spec *spec = codec->spec; | ||
1299 | int pin_idx; | ||
1300 | |||
1301 | for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { | ||
1302 | struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; | ||
1303 | hda_nid_t pin_nid = per_pin->pin_nid; | ||
1304 | |||
1305 | hdmi_init_pin(codec, pin_nid); | ||
1306 | snd_hda_jack_detect_enable(codec, pin_nid, pin_nid); | ||
1307 | } | ||
1297 | snd_hda_jack_report_sync(codec); | 1308 | snd_hda_jack_report_sync(codec); |
1298 | return 0; | 1309 | return 0; |
1299 | } | 1310 | } |
@@ -1338,6 +1349,7 @@ static int patch_generic_hdmi(struct hda_codec *codec) | |||
1338 | return -EINVAL; | 1349 | return -EINVAL; |
1339 | } | 1350 | } |
1340 | codec->patch_ops = generic_hdmi_patch_ops; | 1351 | codec->patch_ops = generic_hdmi_patch_ops; |
1352 | generic_hdmi_init_per_pins(codec); | ||
1341 | 1353 | ||
1342 | init_channel_allocations(); | 1354 | init_channel_allocations(); |
1343 | 1355 | ||
@@ -1352,45 +1364,65 @@ static int simple_playback_build_pcms(struct hda_codec *codec) | |||
1352 | { | 1364 | { |
1353 | struct hdmi_spec *spec = codec->spec; | 1365 | struct hdmi_spec *spec = codec->spec; |
1354 | struct hda_pcm *info = spec->pcm_rec; | 1366 | struct hda_pcm *info = spec->pcm_rec; |
1355 | int i; | 1367 | unsigned int chans; |
1368 | struct hda_pcm_stream *pstr; | ||
1356 | 1369 | ||
1357 | codec->num_pcms = spec->num_cvts; | 1370 | codec->num_pcms = 1; |
1358 | codec->pcm_info = info; | 1371 | codec->pcm_info = info; |
1359 | 1372 | ||
1360 | for (i = 0; i < codec->num_pcms; i++, info++) { | 1373 | chans = get_wcaps(codec, spec->cvts[0].cvt_nid); |
1361 | unsigned int chans; | 1374 | chans = get_wcaps_channels(chans); |
1362 | struct hda_pcm_stream *pstr; | ||
1363 | |||
1364 | chans = get_wcaps(codec, spec->cvts[i].cvt_nid); | ||
1365 | chans = get_wcaps_channels(chans); | ||
1366 | 1375 | ||
1367 | info->name = get_hdmi_pcm_name(i); | 1376 | info->name = get_hdmi_pcm_name(0); |
1368 | info->pcm_type = HDA_PCM_TYPE_HDMI; | 1377 | info->pcm_type = HDA_PCM_TYPE_HDMI; |
1369 | pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK]; | 1378 | pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK]; |
1370 | snd_BUG_ON(!spec->pcm_playback); | 1379 | *pstr = spec->pcm_playback; |
1371 | *pstr = *spec->pcm_playback; | 1380 | pstr->nid = spec->cvts[0].cvt_nid; |
1372 | pstr->nid = spec->cvts[i].cvt_nid; | 1381 | if (pstr->channels_max <= 2 && chans && chans <= 16) |
1373 | if (pstr->channels_max <= 2 && chans && chans <= 16) | 1382 | pstr->channels_max = chans; |
1374 | pstr->channels_max = chans; | ||
1375 | } | ||
1376 | 1383 | ||
1377 | return 0; | 1384 | return 0; |
1378 | } | 1385 | } |
1379 | 1386 | ||
1387 | /* unsolicited event for jack sensing */ | ||
1388 | static void simple_hdmi_unsol_event(struct hda_codec *codec, | ||
1389 | unsigned int res) | ||
1390 | { | ||
1391 | snd_hda_jack_set_dirty_all(codec); | ||
1392 | snd_hda_jack_report_sync(codec); | ||
1393 | } | ||
1394 | |||
1395 | /* generic_hdmi_build_jack can be used for simple_hdmi, too, | ||
1396 | * as long as spec->pins[] is set correctly | ||
1397 | */ | ||
1398 | #define simple_hdmi_build_jack generic_hdmi_build_jack | ||
1399 | |||
1380 | static int simple_playback_build_controls(struct hda_codec *codec) | 1400 | static int simple_playback_build_controls(struct hda_codec *codec) |
1381 | { | 1401 | { |
1382 | struct hdmi_spec *spec = codec->spec; | 1402 | struct hdmi_spec *spec = codec->spec; |
1383 | int err; | 1403 | int err; |
1384 | int i; | ||
1385 | 1404 | ||
1386 | for (i = 0; i < codec->num_pcms; i++) { | 1405 | err = snd_hda_create_spdif_out_ctls(codec, |
1387 | err = snd_hda_create_spdif_out_ctls(codec, | 1406 | spec->cvts[0].cvt_nid, |
1388 | spec->cvts[i].cvt_nid, | 1407 | spec->cvts[0].cvt_nid); |
1389 | spec->cvts[i].cvt_nid); | 1408 | if (err < 0) |
1390 | if (err < 0) | 1409 | return err; |
1391 | return err; | 1410 | return simple_hdmi_build_jack(codec, 0); |
1392 | } | 1411 | } |
1393 | 1412 | ||
1413 | static int simple_playback_init(struct hda_codec *codec) | ||
1414 | { | ||
1415 | struct hdmi_spec *spec = codec->spec; | ||
1416 | hda_nid_t pin = spec->pins[0].pin_nid; | ||
1417 | |||
1418 | snd_hda_codec_write(codec, pin, 0, | ||
1419 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); | ||
1420 | /* some codecs require to unmute the pin */ | ||
1421 | if (get_wcaps(codec, pin) & AC_WCAP_OUT_AMP) | ||
1422 | snd_hda_codec_write(codec, pin, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
1423 | AMP_OUT_UNMUTE); | ||
1424 | snd_hda_jack_detect_enable(codec, pin, pin); | ||
1425 | snd_hda_jack_report_sync(codec); | ||
1394 | return 0; | 1426 | return 0; |
1395 | } | 1427 | } |
1396 | 1428 | ||
@@ -1418,7 +1450,15 @@ static const hda_nid_t nvhdmi_con_nids_7x[4] = { | |||
1418 | 0x6, 0x8, 0xa, 0xc, | 1450 | 0x6, 0x8, 0xa, 0xc, |
1419 | }; | 1451 | }; |
1420 | 1452 | ||
1421 | static const struct hda_verb nvhdmi_basic_init_7x[] = { | 1453 | static const struct hda_verb nvhdmi_basic_init_7x_2ch[] = { |
1454 | /* set audio protect on */ | ||
1455 | { 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1}, | ||
1456 | /* enable digital output on pin widget */ | ||
1457 | { 0x5, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT | 0x5 }, | ||
1458 | {} /* terminator */ | ||
1459 | }; | ||
1460 | |||
1461 | static const struct hda_verb nvhdmi_basic_init_7x_8ch[] = { | ||
1422 | /* set audio protect on */ | 1462 | /* set audio protect on */ |
1423 | { 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1}, | 1463 | { 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1}, |
1424 | /* enable digital output on pin widget */ | 1464 | /* enable digital output on pin widget */ |
@@ -1446,9 +1486,15 @@ static const struct hda_verb nvhdmi_basic_init_7x[] = { | |||
1446 | (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE) | 1486 | (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S32_LE) |
1447 | #endif | 1487 | #endif |
1448 | 1488 | ||
1449 | static int nvhdmi_7x_init(struct hda_codec *codec) | 1489 | static int nvhdmi_7x_init_2ch(struct hda_codec *codec) |
1450 | { | 1490 | { |
1451 | snd_hda_sequence_write(codec, nvhdmi_basic_init_7x); | 1491 | snd_hda_sequence_write(codec, nvhdmi_basic_init_7x_2ch); |
1492 | return 0; | ||
1493 | } | ||
1494 | |||
1495 | static int nvhdmi_7x_init_8ch(struct hda_codec *codec) | ||
1496 | { | ||
1497 | snd_hda_sequence_write(codec, nvhdmi_basic_init_7x_8ch); | ||
1452 | return 0; | 1498 | return 0; |
1453 | } | 1499 | } |
1454 | 1500 | ||
@@ -1524,6 +1570,50 @@ static int simple_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
1524 | stream_tag, format, substream); | 1570 | stream_tag, format, substream); |
1525 | } | 1571 | } |
1526 | 1572 | ||
1573 | static const struct hda_pcm_stream simple_pcm_playback = { | ||
1574 | .substreams = 1, | ||
1575 | .channels_min = 2, | ||
1576 | .channels_max = 2, | ||
1577 | .ops = { | ||
1578 | .open = simple_playback_pcm_open, | ||
1579 | .close = simple_playback_pcm_close, | ||
1580 | .prepare = simple_playback_pcm_prepare | ||
1581 | }, | ||
1582 | }; | ||
1583 | |||
1584 | static const struct hda_codec_ops simple_hdmi_patch_ops = { | ||
1585 | .build_controls = simple_playback_build_controls, | ||
1586 | .build_pcms = simple_playback_build_pcms, | ||
1587 | .init = simple_playback_init, | ||
1588 | .free = simple_playback_free, | ||
1589 | .unsol_event = simple_hdmi_unsol_event, | ||
1590 | }; | ||
1591 | |||
1592 | static int patch_simple_hdmi(struct hda_codec *codec, | ||
1593 | hda_nid_t cvt_nid, hda_nid_t pin_nid) | ||
1594 | { | ||
1595 | struct hdmi_spec *spec; | ||
1596 | |||
1597 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | ||
1598 | if (!spec) | ||
1599 | return -ENOMEM; | ||
1600 | |||
1601 | codec->spec = spec; | ||
1602 | |||
1603 | spec->multiout.num_dacs = 0; /* no analog */ | ||
1604 | spec->multiout.max_channels = 2; | ||
1605 | spec->multiout.dig_out_nid = cvt_nid; | ||
1606 | spec->num_cvts = 1; | ||
1607 | spec->num_pins = 1; | ||
1608 | spec->cvts[0].cvt_nid = cvt_nid; | ||
1609 | spec->pins[0].pin_nid = pin_nid; | ||
1610 | spec->pcm_playback = simple_pcm_playback; | ||
1611 | |||
1612 | codec->patch_ops = simple_hdmi_patch_ops; | ||
1613 | |||
1614 | return 0; | ||
1615 | } | ||
1616 | |||
1527 | static void nvhdmi_8ch_7x_set_info_frame_parameters(struct hda_codec *codec, | 1617 | static void nvhdmi_8ch_7x_set_info_frame_parameters(struct hda_codec *codec, |
1528 | int channels) | 1618 | int channels) |
1529 | { | 1619 | { |
@@ -1696,54 +1786,20 @@ static const struct hda_pcm_stream nvhdmi_pcm_playback_8ch_7x = { | |||
1696 | }, | 1786 | }, |
1697 | }; | 1787 | }; |
1698 | 1788 | ||
1699 | static const struct hda_pcm_stream nvhdmi_pcm_playback_2ch = { | ||
1700 | .substreams = 1, | ||
1701 | .channels_min = 2, | ||
1702 | .channels_max = 2, | ||
1703 | .nid = nvhdmi_master_con_nid_7x, | ||
1704 | .rates = SUPPORTED_RATES, | ||
1705 | .maxbps = SUPPORTED_MAXBPS, | ||
1706 | .formats = SUPPORTED_FORMATS, | ||
1707 | .ops = { | ||
1708 | .open = simple_playback_pcm_open, | ||
1709 | .close = simple_playback_pcm_close, | ||
1710 | .prepare = simple_playback_pcm_prepare | ||
1711 | }, | ||
1712 | }; | ||
1713 | |||
1714 | static const struct hda_codec_ops nvhdmi_patch_ops_8ch_7x = { | ||
1715 | .build_controls = simple_playback_build_controls, | ||
1716 | .build_pcms = simple_playback_build_pcms, | ||
1717 | .init = nvhdmi_7x_init, | ||
1718 | .free = simple_playback_free, | ||
1719 | }; | ||
1720 | |||
1721 | static const struct hda_codec_ops nvhdmi_patch_ops_2ch = { | ||
1722 | .build_controls = simple_playback_build_controls, | ||
1723 | .build_pcms = simple_playback_build_pcms, | ||
1724 | .init = nvhdmi_7x_init, | ||
1725 | .free = simple_playback_free, | ||
1726 | }; | ||
1727 | |||
1728 | static int patch_nvhdmi_2ch(struct hda_codec *codec) | 1789 | static int patch_nvhdmi_2ch(struct hda_codec *codec) |
1729 | { | 1790 | { |
1730 | struct hdmi_spec *spec; | 1791 | struct hdmi_spec *spec; |
1792 | int err = patch_simple_hdmi(codec, nvhdmi_master_con_nid_7x, | ||
1793 | nvhdmi_master_pin_nid_7x); | ||
1794 | if (err < 0) | ||
1795 | return err; | ||
1731 | 1796 | ||
1732 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 1797 | codec->patch_ops.init = nvhdmi_7x_init_2ch; |
1733 | if (spec == NULL) | 1798 | /* override the PCM rates, etc, as the codec doesn't give full list */ |
1734 | return -ENOMEM; | 1799 | spec = codec->spec; |
1735 | 1800 | spec->pcm_playback.rates = SUPPORTED_RATES; | |
1736 | codec->spec = spec; | 1801 | spec->pcm_playback.maxbps = SUPPORTED_MAXBPS; |
1737 | 1802 | spec->pcm_playback.formats = SUPPORTED_FORMATS; | |
1738 | spec->multiout.num_dacs = 0; /* no analog */ | ||
1739 | spec->multiout.max_channels = 2; | ||
1740 | spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x; | ||
1741 | spec->num_cvts = 1; | ||
1742 | spec->cvts[0].cvt_nid = nvhdmi_master_con_nid_7x; | ||
1743 | spec->pcm_playback = &nvhdmi_pcm_playback_2ch; | ||
1744 | |||
1745 | codec->patch_ops = nvhdmi_patch_ops_2ch; | ||
1746 | |||
1747 | return 0; | 1803 | return 0; |
1748 | } | 1804 | } |
1749 | 1805 | ||
@@ -1751,13 +1807,12 @@ static int patch_nvhdmi_8ch_7x(struct hda_codec *codec) | |||
1751 | { | 1807 | { |
1752 | struct hdmi_spec *spec; | 1808 | struct hdmi_spec *spec; |
1753 | int err = patch_nvhdmi_2ch(codec); | 1809 | int err = patch_nvhdmi_2ch(codec); |
1754 | |||
1755 | if (err < 0) | 1810 | if (err < 0) |
1756 | return err; | 1811 | return err; |
1757 | spec = codec->spec; | 1812 | spec = codec->spec; |
1758 | spec->multiout.max_channels = 8; | 1813 | spec->multiout.max_channels = 8; |
1759 | spec->pcm_playback = &nvhdmi_pcm_playback_8ch_7x; | 1814 | spec->pcm_playback = nvhdmi_pcm_playback_8ch_7x; |
1760 | codec->patch_ops = nvhdmi_patch_ops_8ch_7x; | 1815 | codec->patch_ops.init = nvhdmi_7x_init_8ch; |
1761 | 1816 | ||
1762 | /* Initialize the audio infoframe channel mask and checksum to something | 1817 | /* Initialize the audio infoframe channel mask and checksum to something |
1763 | * valid */ | 1818 | * valid */ |
@@ -1801,69 +1856,26 @@ static int atihdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
1801 | return 0; | 1856 | return 0; |
1802 | } | 1857 | } |
1803 | 1858 | ||
1804 | static const struct hda_pcm_stream atihdmi_pcm_digital_playback = { | 1859 | static int patch_atihdmi(struct hda_codec *codec) |
1805 | .substreams = 1, | ||
1806 | .channels_min = 2, | ||
1807 | .channels_max = 2, | ||
1808 | .nid = ATIHDMI_CVT_NID, | ||
1809 | .ops = { | ||
1810 | .open = simple_playback_pcm_open, | ||
1811 | .close = simple_playback_pcm_close, | ||
1812 | .prepare = atihdmi_playback_pcm_prepare | ||
1813 | }, | ||
1814 | }; | ||
1815 | |||
1816 | static const struct hda_verb atihdmi_basic_init[] = { | ||
1817 | /* enable digital output on pin widget */ | ||
1818 | { 0x03, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | ||
1819 | {} /* terminator */ | ||
1820 | }; | ||
1821 | |||
1822 | static int atihdmi_init(struct hda_codec *codec) | ||
1823 | { | 1860 | { |
1824 | struct hdmi_spec *spec = codec->spec; | 1861 | struct hdmi_spec *spec; |
1825 | 1862 | int err = patch_simple_hdmi(codec, ATIHDMI_CVT_NID, ATIHDMI_PIN_NID); | |
1826 | snd_hda_sequence_write(codec, atihdmi_basic_init); | 1863 | if (err < 0) |
1827 | /* SI codec requires to unmute the pin */ | 1864 | return err; |
1828 | if (get_wcaps(codec, spec->pins[0].pin_nid) & AC_WCAP_OUT_AMP) | 1865 | spec = codec->spec; |
1829 | snd_hda_codec_write(codec, spec->pins[0].pin_nid, 0, | 1866 | spec->pcm_playback.ops.prepare = atihdmi_playback_pcm_prepare; |
1830 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
1831 | AMP_OUT_UNMUTE); | ||
1832 | return 0; | 1867 | return 0; |
1833 | } | 1868 | } |
1834 | 1869 | ||
1835 | static const struct hda_codec_ops atihdmi_patch_ops = { | 1870 | /* VIA HDMI Implementation */ |
1836 | .build_controls = simple_playback_build_controls, | 1871 | #define VIAHDMI_CVT_NID 0x02 /* audio converter1 */ |
1837 | .build_pcms = simple_playback_build_pcms, | 1872 | #define VIAHDMI_PIN_NID 0x03 /* HDMI output pin1 */ |
1838 | .init = atihdmi_init, | ||
1839 | .free = simple_playback_free, | ||
1840 | }; | ||
1841 | |||
1842 | 1873 | ||
1843 | static int patch_atihdmi(struct hda_codec *codec) | 1874 | static int patch_via_hdmi(struct hda_codec *codec) |
1844 | { | 1875 | { |
1845 | struct hdmi_spec *spec; | 1876 | return patch_simple_hdmi(codec, VIAHDMI_CVT_NID, VIAHDMI_PIN_NID); |
1846 | |||
1847 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | ||
1848 | if (spec == NULL) | ||
1849 | return -ENOMEM; | ||
1850 | |||
1851 | codec->spec = spec; | ||
1852 | |||
1853 | spec->multiout.num_dacs = 0; /* no analog */ | ||
1854 | spec->multiout.max_channels = 2; | ||
1855 | spec->multiout.dig_out_nid = ATIHDMI_CVT_NID; | ||
1856 | spec->num_cvts = 1; | ||
1857 | spec->cvts[0].cvt_nid = ATIHDMI_CVT_NID; | ||
1858 | spec->pins[0].pin_nid = ATIHDMI_PIN_NID; | ||
1859 | spec->pcm_playback = &atihdmi_pcm_digital_playback; | ||
1860 | |||
1861 | codec->patch_ops = atihdmi_patch_ops; | ||
1862 | |||
1863 | return 0; | ||
1864 | } | 1877 | } |
1865 | 1878 | ||
1866 | |||
1867 | /* | 1879 | /* |
1868 | * patch entries | 1880 | * patch entries |
1869 | */ | 1881 | */ |
@@ -1902,8 +1914,13 @@ static const struct hda_codec_preset snd_hda_preset_hdmi[] = { | |||
1902 | { .id = 0x10de0042, .name = "GPU 42 HDMI/DP", .patch = patch_generic_hdmi }, | 1914 | { .id = 0x10de0042, .name = "GPU 42 HDMI/DP", .patch = patch_generic_hdmi }, |
1903 | { .id = 0x10de0043, .name = "GPU 43 HDMI/DP", .patch = patch_generic_hdmi }, | 1915 | { .id = 0x10de0043, .name = "GPU 43 HDMI/DP", .patch = patch_generic_hdmi }, |
1904 | { .id = 0x10de0044, .name = "GPU 44 HDMI/DP", .patch = patch_generic_hdmi }, | 1916 | { .id = 0x10de0044, .name = "GPU 44 HDMI/DP", .patch = patch_generic_hdmi }, |
1917 | { .id = 0x10de0051, .name = "GPU 51 HDMI/DP", .patch = patch_generic_hdmi }, | ||
1905 | { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch }, | 1918 | { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch }, |
1906 | { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch }, | 1919 | { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch }, |
1920 | { .id = 0x11069f80, .name = "VX900 HDMI/DP", .patch = patch_via_hdmi }, | ||
1921 | { .id = 0x11069f81, .name = "VX900 HDMI/DP", .patch = patch_via_hdmi }, | ||
1922 | { .id = 0x11069f84, .name = "VX11 HDMI/DP", .patch = patch_generic_hdmi }, | ||
1923 | { .id = 0x11069f85, .name = "VX11 HDMI/DP", .patch = patch_generic_hdmi }, | ||
1907 | { .id = 0x80860054, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi }, | 1924 | { .id = 0x80860054, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi }, |
1908 | { .id = 0x80862801, .name = "Bearlake HDMI", .patch = patch_generic_hdmi }, | 1925 | { .id = 0x80862801, .name = "Bearlake HDMI", .patch = patch_generic_hdmi }, |
1909 | { .id = 0x80862802, .name = "Cantiga HDMI", .patch = patch_generic_hdmi }, | 1926 | { .id = 0x80862802, .name = "Cantiga HDMI", .patch = patch_generic_hdmi }, |
@@ -1911,6 +1928,7 @@ static const struct hda_codec_preset snd_hda_preset_hdmi[] = { | |||
1911 | { .id = 0x80862804, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi }, | 1928 | { .id = 0x80862804, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi }, |
1912 | { .id = 0x80862805, .name = "CougarPoint HDMI", .patch = patch_generic_hdmi }, | 1929 | { .id = 0x80862805, .name = "CougarPoint HDMI", .patch = patch_generic_hdmi }, |
1913 | { .id = 0x80862806, .name = "PantherPoint HDMI", .patch = patch_generic_hdmi }, | 1930 | { .id = 0x80862806, .name = "PantherPoint HDMI", .patch = patch_generic_hdmi }, |
1931 | { .id = 0x80862807, .name = "Haswell HDMI", .patch = patch_generic_hdmi }, | ||
1914 | { .id = 0x80862880, .name = "CedarTrail HDMI", .patch = patch_generic_hdmi }, | 1932 | { .id = 0x80862880, .name = "CedarTrail HDMI", .patch = patch_generic_hdmi }, |
1915 | { .id = 0x808629fb, .name = "Crestline HDMI", .patch = patch_generic_hdmi }, | 1933 | { .id = 0x808629fb, .name = "Crestline HDMI", .patch = patch_generic_hdmi }, |
1916 | {} /* terminator */ | 1934 | {} /* terminator */ |
@@ -1948,8 +1966,13 @@ MODULE_ALIAS("snd-hda-codec-id:10de0041"); | |||
1948 | MODULE_ALIAS("snd-hda-codec-id:10de0042"); | 1966 | MODULE_ALIAS("snd-hda-codec-id:10de0042"); |
1949 | MODULE_ALIAS("snd-hda-codec-id:10de0043"); | 1967 | MODULE_ALIAS("snd-hda-codec-id:10de0043"); |
1950 | MODULE_ALIAS("snd-hda-codec-id:10de0044"); | 1968 | MODULE_ALIAS("snd-hda-codec-id:10de0044"); |
1969 | MODULE_ALIAS("snd-hda-codec-id:10de0051"); | ||
1951 | MODULE_ALIAS("snd-hda-codec-id:10de0067"); | 1970 | MODULE_ALIAS("snd-hda-codec-id:10de0067"); |
1952 | MODULE_ALIAS("snd-hda-codec-id:10de8001"); | 1971 | MODULE_ALIAS("snd-hda-codec-id:10de8001"); |
1972 | MODULE_ALIAS("snd-hda-codec-id:11069f80"); | ||
1973 | MODULE_ALIAS("snd-hda-codec-id:11069f81"); | ||
1974 | MODULE_ALIAS("snd-hda-codec-id:11069f84"); | ||
1975 | MODULE_ALIAS("snd-hda-codec-id:11069f85"); | ||
1953 | MODULE_ALIAS("snd-hda-codec-id:17e80047"); | 1976 | MODULE_ALIAS("snd-hda-codec-id:17e80047"); |
1954 | MODULE_ALIAS("snd-hda-codec-id:80860054"); | 1977 | MODULE_ALIAS("snd-hda-codec-id:80860054"); |
1955 | MODULE_ALIAS("snd-hda-codec-id:80862801"); | 1978 | MODULE_ALIAS("snd-hda-codec-id:80862801"); |
@@ -1958,6 +1981,7 @@ MODULE_ALIAS("snd-hda-codec-id:80862803"); | |||
1958 | MODULE_ALIAS("snd-hda-codec-id:80862804"); | 1981 | MODULE_ALIAS("snd-hda-codec-id:80862804"); |
1959 | MODULE_ALIAS("snd-hda-codec-id:80862805"); | 1982 | MODULE_ALIAS("snd-hda-codec-id:80862805"); |
1960 | MODULE_ALIAS("snd-hda-codec-id:80862806"); | 1983 | MODULE_ALIAS("snd-hda-codec-id:80862806"); |
1984 | MODULE_ALIAS("snd-hda-codec-id:80862807"); | ||
1961 | MODULE_ALIAS("snd-hda-codec-id:80862880"); | 1985 | MODULE_ALIAS("snd-hda-codec-id:80862880"); |
1962 | MODULE_ALIAS("snd-hda-codec-id:808629fb"); | 1986 | MODULE_ALIAS("snd-hda-codec-id:808629fb"); |
1963 | 1987 | ||
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index f8f4906e498..ec14224021a 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -170,10 +170,10 @@ struct alc_spec { | |||
170 | hda_nid_t imux_pins[HDA_MAX_NUM_INPUTS]; | 170 | hda_nid_t imux_pins[HDA_MAX_NUM_INPUTS]; |
171 | unsigned int dyn_adc_idx[HDA_MAX_NUM_INPUTS]; | 171 | unsigned int dyn_adc_idx[HDA_MAX_NUM_INPUTS]; |
172 | int int_mic_idx, ext_mic_idx, dock_mic_idx; /* for auto-mic */ | 172 | int int_mic_idx, ext_mic_idx, dock_mic_idx; /* for auto-mic */ |
173 | hda_nid_t inv_dmic_pin; | ||
173 | 174 | ||
174 | /* hooks */ | 175 | /* hooks */ |
175 | void (*init_hook)(struct hda_codec *codec); | 176 | void (*init_hook)(struct hda_codec *codec); |
176 | void (*unsol_event)(struct hda_codec *codec, unsigned int res); | ||
177 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 177 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
178 | void (*power_hook)(struct hda_codec *codec); | 178 | void (*power_hook)(struct hda_codec *codec); |
179 | #endif | 179 | #endif |
@@ -201,6 +201,8 @@ struct alc_spec { | |||
201 | unsigned int vol_in_capsrc:1; /* use capsrc volume (ADC has no vol) */ | 201 | unsigned int vol_in_capsrc:1; /* use capsrc volume (ADC has no vol) */ |
202 | unsigned int parse_flags; /* passed to snd_hda_parse_pin_defcfg() */ | 202 | unsigned int parse_flags; /* passed to snd_hda_parse_pin_defcfg() */ |
203 | unsigned int shared_mic_hp:1; /* HP/Mic-in sharing */ | 203 | unsigned int shared_mic_hp:1; /* HP/Mic-in sharing */ |
204 | unsigned int inv_dmic_fixup:1; /* has inverted digital-mic workaround */ | ||
205 | unsigned int inv_dmic_muted:1; /* R-ch of inv d-mic is muted? */ | ||
204 | 206 | ||
205 | /* auto-mute control */ | 207 | /* auto-mute control */ |
206 | int automute_mode; | 208 | int automute_mode; |
@@ -298,6 +300,39 @@ static inline hda_nid_t get_capsrc(struct alc_spec *spec, int idx) | |||
298 | } | 300 | } |
299 | 301 | ||
300 | static void call_update_outputs(struct hda_codec *codec); | 302 | static void call_update_outputs(struct hda_codec *codec); |
303 | static void alc_inv_dmic_sync(struct hda_codec *codec, bool force); | ||
304 | |||
305 | /* for shared I/O, change the pin-control accordingly */ | ||
306 | static void update_shared_mic_hp(struct hda_codec *codec, bool set_as_mic) | ||
307 | { | ||
308 | struct alc_spec *spec = codec->spec; | ||
309 | unsigned int val; | ||
310 | hda_nid_t pin = spec->autocfg.inputs[1].pin; | ||
311 | /* NOTE: this assumes that there are only two inputs, the | ||
312 | * first is the real internal mic and the second is HP/mic jack. | ||
313 | */ | ||
314 | |||
315 | val = snd_hda_get_default_vref(codec, pin); | ||
316 | |||
317 | /* This pin does not have vref caps - let's enable vref on pin 0x18 | ||
318 | instead, as suggested by Realtek */ | ||
319 | if (val == AC_PINCTL_VREF_HIZ) { | ||
320 | const hda_nid_t vref_pin = 0x18; | ||
321 | /* Sanity check pin 0x18 */ | ||
322 | if (get_wcaps_type(get_wcaps(codec, vref_pin)) == AC_WID_PIN && | ||
323 | get_defcfg_connect(snd_hda_codec_get_pincfg(codec, vref_pin)) == AC_JACK_PORT_NONE) { | ||
324 | unsigned int vref_val = snd_hda_get_default_vref(codec, vref_pin); | ||
325 | if (vref_val != AC_PINCTL_VREF_HIZ) | ||
326 | snd_hda_set_pin_ctl(codec, vref_pin, PIN_IN | (set_as_mic ? vref_val : 0)); | ||
327 | } | ||
328 | } | ||
329 | |||
330 | val = set_as_mic ? val | PIN_IN : PIN_HP; | ||
331 | snd_hda_set_pin_ctl(codec, pin, val); | ||
332 | |||
333 | spec->automute_speaker = !set_as_mic; | ||
334 | call_update_outputs(codec); | ||
335 | } | ||
301 | 336 | ||
302 | /* select the given imux item; either unmute exclusively or select the route */ | 337 | /* select the given imux item; either unmute exclusively or select the route */ |
303 | static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, | 338 | static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, |
@@ -325,21 +360,8 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, | |||
325 | return 0; | 360 | return 0; |
326 | spec->cur_mux[adc_idx] = idx; | 361 | spec->cur_mux[adc_idx] = idx; |
327 | 362 | ||
328 | /* for shared I/O, change the pin-control accordingly */ | 363 | if (spec->shared_mic_hp) |
329 | if (spec->shared_mic_hp) { | 364 | update_shared_mic_hp(codec, spec->cur_mux[adc_idx]); |
330 | unsigned int val; | ||
331 | hda_nid_t pin = spec->autocfg.inputs[1].pin; | ||
332 | /* NOTE: this assumes that there are only two inputs, the | ||
333 | * first is the real internal mic and the second is HP jack. | ||
334 | */ | ||
335 | if (spec->cur_mux[adc_idx]) | ||
336 | val = snd_hda_get_default_vref(codec, pin) | PIN_IN; | ||
337 | else | ||
338 | val = PIN_HP; | ||
339 | snd_hda_set_pin_ctl(codec, pin, val); | ||
340 | spec->automute_speaker = !spec->cur_mux[adc_idx]; | ||
341 | call_update_outputs(codec); | ||
342 | } | ||
343 | 365 | ||
344 | if (spec->dyn_adc_switch) { | 366 | if (spec->dyn_adc_switch) { |
345 | alc_dyn_adc_pcm_resetup(codec, idx); | 367 | alc_dyn_adc_pcm_resetup(codec, idx); |
@@ -368,6 +390,7 @@ static int alc_mux_select(struct hda_codec *codec, unsigned int adc_idx, | |||
368 | AC_VERB_SET_CONNECT_SEL, | 390 | AC_VERB_SET_CONNECT_SEL, |
369 | imux->items[idx].index); | 391 | imux->items[idx].index); |
370 | } | 392 | } |
393 | alc_inv_dmic_sync(codec, true); | ||
371 | return 1; | 394 | return 1; |
372 | } | 395 | } |
373 | 396 | ||
@@ -664,7 +687,7 @@ static void alc_update_knob_master(struct hda_codec *codec, hda_nid_t nid) | |||
664 | } | 687 | } |
665 | 688 | ||
666 | /* unsolicited event for HP jack sensing */ | 689 | /* unsolicited event for HP jack sensing */ |
667 | static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) | 690 | static void alc_unsol_event(struct hda_codec *codec, unsigned int res) |
668 | { | 691 | { |
669 | int action; | 692 | int action; |
670 | 693 | ||
@@ -1000,11 +1023,9 @@ static void alc_init_automute(struct hda_codec *codec) | |||
1000 | spec->automute_lo = spec->automute_lo_possible; | 1023 | spec->automute_lo = spec->automute_lo_possible; |
1001 | spec->automute_speaker = spec->automute_speaker_possible; | 1024 | spec->automute_speaker = spec->automute_speaker_possible; |
1002 | 1025 | ||
1003 | if (spec->automute_speaker_possible || spec->automute_lo_possible) { | 1026 | if (spec->automute_speaker_possible || spec->automute_lo_possible) |
1004 | /* create a control for automute mode */ | 1027 | /* create a control for automute mode */ |
1005 | alc_add_automute_mode_enum(codec); | 1028 | alc_add_automute_mode_enum(codec); |
1006 | spec->unsol_event = alc_sku_unsol_event; | ||
1007 | } | ||
1008 | } | 1029 | } |
1009 | 1030 | ||
1010 | /* return the position of NID in the list, or -1 if not found */ | 1031 | /* return the position of NID in the list, or -1 if not found */ |
@@ -1167,7 +1188,6 @@ static void alc_init_auto_mic(struct hda_codec *codec) | |||
1167 | 1188 | ||
1168 | snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n", | 1189 | snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n", |
1169 | ext, fixed, dock); | 1190 | ext, fixed, dock); |
1170 | spec->unsol_event = alc_sku_unsol_event; | ||
1171 | } | 1191 | } |
1172 | 1192 | ||
1173 | /* check the availabilities of auto-mute and auto-mic switches */ | 1193 | /* check the availabilities of auto-mute and auto-mic switches */ |
@@ -1556,14 +1576,14 @@ typedef int (*getput_call_t)(struct snd_kcontrol *kcontrol, | |||
1556 | 1576 | ||
1557 | static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol, | 1577 | static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol, |
1558 | struct snd_ctl_elem_value *ucontrol, | 1578 | struct snd_ctl_elem_value *ucontrol, |
1559 | getput_call_t func, bool check_adc_switch) | 1579 | getput_call_t func, bool is_put) |
1560 | { | 1580 | { |
1561 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 1581 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
1562 | struct alc_spec *spec = codec->spec; | 1582 | struct alc_spec *spec = codec->spec; |
1563 | int i, err = 0; | 1583 | int i, err = 0; |
1564 | 1584 | ||
1565 | mutex_lock(&codec->control_mutex); | 1585 | mutex_lock(&codec->control_mutex); |
1566 | if (check_adc_switch && spec->dyn_adc_switch) { | 1586 | if (is_put && spec->dyn_adc_switch) { |
1567 | for (i = 0; i < spec->num_adc_nids; i++) { | 1587 | for (i = 0; i < spec->num_adc_nids; i++) { |
1568 | kcontrol->private_value = | 1588 | kcontrol->private_value = |
1569 | HDA_COMPOSE_AMP_VAL(spec->adc_nids[i], | 1589 | HDA_COMPOSE_AMP_VAL(spec->adc_nids[i], |
@@ -1584,6 +1604,8 @@ static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol, | |||
1584 | 3, 0, HDA_INPUT); | 1604 | 3, 0, HDA_INPUT); |
1585 | err = func(kcontrol, ucontrol); | 1605 | err = func(kcontrol, ucontrol); |
1586 | } | 1606 | } |
1607 | if (err >= 0 && is_put) | ||
1608 | alc_inv_dmic_sync(codec, false); | ||
1587 | error: | 1609 | error: |
1588 | mutex_unlock(&codec->control_mutex); | 1610 | mutex_unlock(&codec->control_mutex); |
1589 | return err; | 1611 | return err; |
@@ -1676,6 +1698,116 @@ DEFINE_CAPMIX_NOSRC(2); | |||
1676 | DEFINE_CAPMIX_NOSRC(3); | 1698 | DEFINE_CAPMIX_NOSRC(3); |
1677 | 1699 | ||
1678 | /* | 1700 | /* |
1701 | * Inverted digital-mic handling | ||
1702 | * | ||
1703 | * First off, it's a bit tricky. The "Inverted Internal Mic Capture Switch" | ||
1704 | * gives the additional mute only to the right channel of the digital mic | ||
1705 | * capture stream. This is a workaround for avoiding the almost silence | ||
1706 | * by summing the stereo stream from some (known to be ForteMedia) | ||
1707 | * digital mic unit. | ||
1708 | * | ||
1709 | * The logic is to call alc_inv_dmic_sync() after each action (possibly) | ||
1710 | * modifying ADC amp. When the mute flag is set, it mutes the R-channel | ||
1711 | * without caching so that the cache can still keep the original value. | ||
1712 | * The cached value is then restored when the flag is set off or any other | ||
1713 | * than d-mic is used as the current input source. | ||
1714 | */ | ||
1715 | static void alc_inv_dmic_sync(struct hda_codec *codec, bool force) | ||
1716 | { | ||
1717 | struct alc_spec *spec = codec->spec; | ||
1718 | int i; | ||
1719 | |||
1720 | if (!spec->inv_dmic_fixup) | ||
1721 | return; | ||
1722 | if (!spec->inv_dmic_muted && !force) | ||
1723 | return; | ||
1724 | for (i = 0; i < spec->num_adc_nids; i++) { | ||
1725 | int src = spec->dyn_adc_switch ? 0 : i; | ||
1726 | bool dmic_fixup = false; | ||
1727 | hda_nid_t nid; | ||
1728 | int parm, dir, v; | ||
1729 | |||
1730 | if (spec->inv_dmic_muted && | ||
1731 | spec->imux_pins[spec->cur_mux[src]] == spec->inv_dmic_pin) | ||
1732 | dmic_fixup = true; | ||
1733 | if (!dmic_fixup && !force) | ||
1734 | continue; | ||
1735 | if (spec->vol_in_capsrc) { | ||
1736 | nid = spec->capsrc_nids[i]; | ||
1737 | parm = AC_AMP_SET_RIGHT | AC_AMP_SET_OUTPUT; | ||
1738 | dir = HDA_OUTPUT; | ||
1739 | } else { | ||
1740 | nid = spec->adc_nids[i]; | ||
1741 | parm = AC_AMP_SET_RIGHT | AC_AMP_SET_INPUT; | ||
1742 | dir = HDA_INPUT; | ||
1743 | } | ||
1744 | /* we care only right channel */ | ||
1745 | v = snd_hda_codec_amp_read(codec, nid, 1, dir, 0); | ||
1746 | if (v & 0x80) /* if already muted, we don't need to touch */ | ||
1747 | continue; | ||
1748 | if (dmic_fixup) /* add mute for d-mic */ | ||
1749 | v |= 0x80; | ||
1750 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
1751 | parm | v); | ||
1752 | } | ||
1753 | } | ||
1754 | |||
1755 | static int alc_inv_dmic_sw_get(struct snd_kcontrol *kcontrol, | ||
1756 | struct snd_ctl_elem_value *ucontrol) | ||
1757 | { | ||
1758 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1759 | struct alc_spec *spec = codec->spec; | ||
1760 | |||
1761 | ucontrol->value.integer.value[0] = !spec->inv_dmic_muted; | ||
1762 | return 0; | ||
1763 | } | ||
1764 | |||
1765 | static int alc_inv_dmic_sw_put(struct snd_kcontrol *kcontrol, | ||
1766 | struct snd_ctl_elem_value *ucontrol) | ||
1767 | { | ||
1768 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1769 | struct alc_spec *spec = codec->spec; | ||
1770 | unsigned int val = !ucontrol->value.integer.value[0]; | ||
1771 | |||
1772 | if (val == spec->inv_dmic_muted) | ||
1773 | return 0; | ||
1774 | spec->inv_dmic_muted = val; | ||
1775 | alc_inv_dmic_sync(codec, true); | ||
1776 | return 0; | ||
1777 | } | ||
1778 | |||
1779 | static const struct snd_kcontrol_new alc_inv_dmic_sw = { | ||
1780 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1781 | .info = snd_ctl_boolean_mono_info, | ||
1782 | .get = alc_inv_dmic_sw_get, | ||
1783 | .put = alc_inv_dmic_sw_put, | ||
1784 | }; | ||
1785 | |||
1786 | static int alc_add_inv_dmic_mixer(struct hda_codec *codec, hda_nid_t nid) | ||
1787 | { | ||
1788 | struct alc_spec *spec = codec->spec; | ||
1789 | struct snd_kcontrol_new *knew = alc_kcontrol_new(spec); | ||
1790 | if (!knew) | ||
1791 | return -ENOMEM; | ||
1792 | *knew = alc_inv_dmic_sw; | ||
1793 | knew->name = kstrdup("Inverted Internal Mic Capture Switch", GFP_KERNEL); | ||
1794 | if (!knew->name) | ||
1795 | return -ENOMEM; | ||
1796 | spec->inv_dmic_fixup = 1; | ||
1797 | spec->inv_dmic_muted = 0; | ||
1798 | spec->inv_dmic_pin = nid; | ||
1799 | return 0; | ||
1800 | } | ||
1801 | |||
1802 | /* typically the digital mic is put at node 0x12 */ | ||
1803 | static void alc_fixup_inv_dmic_0x12(struct hda_codec *codec, | ||
1804 | const struct alc_fixup *fix, int action) | ||
1805 | { | ||
1806 | if (action == ALC_FIXUP_ACT_PROBE) | ||
1807 | alc_add_inv_dmic_mixer(codec, 0x12); | ||
1808 | } | ||
1809 | |||
1810 | /* | ||
1679 | * virtual master controls | 1811 | * virtual master controls |
1680 | */ | 1812 | */ |
1681 | 1813 | ||
@@ -1865,13 +1997,31 @@ static int __alc_build_controls(struct hda_codec *codec) | |||
1865 | return 0; | 1997 | return 0; |
1866 | } | 1998 | } |
1867 | 1999 | ||
1868 | static int alc_build_controls(struct hda_codec *codec) | 2000 | static int alc_build_jacks(struct hda_codec *codec) |
1869 | { | 2001 | { |
1870 | struct alc_spec *spec = codec->spec; | 2002 | struct alc_spec *spec = codec->spec; |
2003 | |||
2004 | if (spec->shared_mic_hp) { | ||
2005 | int err; | ||
2006 | int nid = spec->autocfg.inputs[1].pin; | ||
2007 | err = snd_hda_jack_add_kctl(codec, nid, "Headphone Mic", 0); | ||
2008 | if (err < 0) | ||
2009 | return err; | ||
2010 | err = snd_hda_jack_detect_enable(codec, nid, 0); | ||
2011 | if (err < 0) | ||
2012 | return err; | ||
2013 | } | ||
2014 | |||
2015 | return snd_hda_jack_add_kctls(codec, &spec->autocfg); | ||
2016 | } | ||
2017 | |||
2018 | static int alc_build_controls(struct hda_codec *codec) | ||
2019 | { | ||
1871 | int err = __alc_build_controls(codec); | 2020 | int err = __alc_build_controls(codec); |
1872 | if (err < 0) | 2021 | if (err < 0) |
1873 | return err; | 2022 | return err; |
1874 | err = snd_hda_jack_add_kctls(codec, &spec->autocfg); | 2023 | |
2024 | err = alc_build_jacks(codec); | ||
1875 | if (err < 0) | 2025 | if (err < 0) |
1876 | return err; | 2026 | return err; |
1877 | alc_apply_fixup(codec, ALC_FIXUP_ACT_BUILD); | 2027 | alc_apply_fixup(codec, ALC_FIXUP_ACT_BUILD); |
@@ -1908,14 +2058,6 @@ static int alc_init(struct hda_codec *codec) | |||
1908 | return 0; | 2058 | return 0; |
1909 | } | 2059 | } |
1910 | 2060 | ||
1911 | static void alc_unsol_event(struct hda_codec *codec, unsigned int res) | ||
1912 | { | ||
1913 | struct alc_spec *spec = codec->spec; | ||
1914 | |||
1915 | if (spec->unsol_event) | ||
1916 | spec->unsol_event(codec, res); | ||
1917 | } | ||
1918 | |||
1919 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 2061 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
1920 | static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid) | 2062 | static int alc_check_power_status(struct hda_codec *codec, hda_nid_t nid) |
1921 | { | 2063 | { |
@@ -2289,6 +2431,7 @@ static void alc_free(struct hda_codec *codec) | |||
2289 | alc_shutup(codec); | 2431 | alc_shutup(codec); |
2290 | alc_free_kctls(codec); | 2432 | alc_free_kctls(codec); |
2291 | alc_free_bind_ctls(codec); | 2433 | alc_free_bind_ctls(codec); |
2434 | snd_hda_gen_free(&spec->gen); | ||
2292 | kfree(spec); | 2435 | kfree(spec); |
2293 | snd_hda_detach_beep_device(codec); | 2436 | snd_hda_detach_beep_device(codec); |
2294 | } | 2437 | } |
@@ -2316,6 +2459,7 @@ static int alc_resume(struct hda_codec *codec) | |||
2316 | codec->patch_ops.init(codec); | 2459 | codec->patch_ops.init(codec); |
2317 | snd_hda_codec_resume_amp(codec); | 2460 | snd_hda_codec_resume_amp(codec); |
2318 | snd_hda_codec_resume_cache(codec); | 2461 | snd_hda_codec_resume_cache(codec); |
2462 | alc_inv_dmic_sync(codec, true); | ||
2319 | hda_call_check_power_status(codec, 0x01); | 2463 | hda_call_check_power_status(codec, 0x01); |
2320 | return 0; | 2464 | return 0; |
2321 | } | 2465 | } |
@@ -4115,14 +4259,12 @@ static void set_capture_mixer(struct hda_codec *codec) | |||
4115 | */ | 4259 | */ |
4116 | static void alc_auto_init_std(struct hda_codec *codec) | 4260 | static void alc_auto_init_std(struct hda_codec *codec) |
4117 | { | 4261 | { |
4118 | struct alc_spec *spec = codec->spec; | ||
4119 | alc_auto_init_multi_out(codec); | 4262 | alc_auto_init_multi_out(codec); |
4120 | alc_auto_init_extra_out(codec); | 4263 | alc_auto_init_extra_out(codec); |
4121 | alc_auto_init_analog_input(codec); | 4264 | alc_auto_init_analog_input(codec); |
4122 | alc_auto_init_input_src(codec); | 4265 | alc_auto_init_input_src(codec); |
4123 | alc_auto_init_digital(codec); | 4266 | alc_auto_init_digital(codec); |
4124 | if (spec->unsol_event) | 4267 | alc_inithook(codec); |
4125 | alc_inithook(codec); | ||
4126 | } | 4268 | } |
4127 | 4269 | ||
4128 | /* | 4270 | /* |
@@ -4253,6 +4395,7 @@ static int alc_alloc_spec(struct hda_codec *codec, hda_nid_t mixer_nid) | |||
4253 | return -ENOMEM; | 4395 | return -ENOMEM; |
4254 | codec->spec = spec; | 4396 | codec->spec = spec; |
4255 | spec->mixer_nid = mixer_nid; | 4397 | spec->mixer_nid = mixer_nid; |
4398 | snd_hda_gen_init(&spec->gen); | ||
4256 | 4399 | ||
4257 | err = alc_codec_rename_from_preset(codec); | 4400 | err = alc_codec_rename_from_preset(codec); |
4258 | if (err < 0) { | 4401 | if (err < 0) { |
@@ -4722,7 +4865,6 @@ static void alc260_fixup_gpio1_toggle(struct hda_codec *codec, | |||
4722 | spec->automute_speaker = 1; | 4865 | spec->automute_speaker = 1; |
4723 | spec->autocfg.hp_pins[0] = 0x0f; /* copy it for automute */ | 4866 | spec->autocfg.hp_pins[0] = 0x0f; /* copy it for automute */ |
4724 | snd_hda_jack_detect_enable(codec, 0x0f, ALC_HP_EVENT); | 4867 | snd_hda_jack_detect_enable(codec, 0x0f, ALC_HP_EVENT); |
4725 | spec->unsol_event = alc_sku_unsol_event; | ||
4726 | snd_hda_gen_add_verbs(&spec->gen, alc_gpio1_init_verbs); | 4868 | snd_hda_gen_add_verbs(&spec->gen, alc_gpio1_init_verbs); |
4727 | } | 4869 | } |
4728 | } | 4870 | } |
@@ -4907,6 +5049,7 @@ enum { | |||
4907 | ALC889_FIXUP_DAC_ROUTE, | 5049 | ALC889_FIXUP_DAC_ROUTE, |
4908 | ALC889_FIXUP_MBP_VREF, | 5050 | ALC889_FIXUP_MBP_VREF, |
4909 | ALC889_FIXUP_IMAC91_VREF, | 5051 | ALC889_FIXUP_IMAC91_VREF, |
5052 | ALC882_FIXUP_INV_DMIC, | ||
4910 | }; | 5053 | }; |
4911 | 5054 | ||
4912 | static void alc889_fixup_coef(struct hda_codec *codec, | 5055 | static void alc889_fixup_coef(struct hda_codec *codec, |
@@ -5210,6 +5353,10 @@ static const struct alc_fixup alc882_fixups[] = { | |||
5210 | .chained = true, | 5353 | .chained = true, |
5211 | .chain_id = ALC882_FIXUP_GPIO1, | 5354 | .chain_id = ALC882_FIXUP_GPIO1, |
5212 | }, | 5355 | }, |
5356 | [ALC882_FIXUP_INV_DMIC] = { | ||
5357 | .type = ALC_FIXUP_FUNC, | ||
5358 | .v.func = alc_fixup_inv_dmic_0x12, | ||
5359 | }, | ||
5213 | }; | 5360 | }; |
5214 | 5361 | ||
5215 | static const struct snd_pci_quirk alc882_fixup_tbl[] = { | 5362 | static const struct snd_pci_quirk alc882_fixup_tbl[] = { |
@@ -5284,6 +5431,7 @@ static const struct alc_model_fixup alc882_fixup_models[] = { | |||
5284 | {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"}, | 5431 | {.id = ALC882_FIXUP_ACER_ASPIRE_4930G, .name = "acer-aspire-4930g"}, |
5285 | {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"}, | 5432 | {.id = ALC882_FIXUP_ACER_ASPIRE_8930G, .name = "acer-aspire-8930g"}, |
5286 | {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"}, | 5433 | {.id = ALC883_FIXUP_ACER_EAPD, .name = "acer-aspire"}, |
5434 | {.id = ALC882_FIXUP_INV_DMIC, .name = "inv-dmic"}, | ||
5287 | {} | 5435 | {} |
5288 | }; | 5436 | }; |
5289 | 5437 | ||
@@ -5371,6 +5519,7 @@ enum { | |||
5371 | ALC262_FIXUP_LENOVO_3000, | 5519 | ALC262_FIXUP_LENOVO_3000, |
5372 | ALC262_FIXUP_BENQ, | 5520 | ALC262_FIXUP_BENQ, |
5373 | ALC262_FIXUP_BENQ_T31, | 5521 | ALC262_FIXUP_BENQ_T31, |
5522 | ALC262_FIXUP_INV_DMIC, | ||
5374 | }; | 5523 | }; |
5375 | 5524 | ||
5376 | static const struct alc_fixup alc262_fixups[] = { | 5525 | static const struct alc_fixup alc262_fixups[] = { |
@@ -5422,6 +5571,10 @@ static const struct alc_fixup alc262_fixups[] = { | |||
5422 | {} | 5571 | {} |
5423 | } | 5572 | } |
5424 | }, | 5573 | }, |
5574 | [ALC262_FIXUP_INV_DMIC] = { | ||
5575 | .type = ALC_FIXUP_FUNC, | ||
5576 | .v.func = alc_fixup_inv_dmic_0x12, | ||
5577 | }, | ||
5425 | }; | 5578 | }; |
5426 | 5579 | ||
5427 | static const struct snd_pci_quirk alc262_fixup_tbl[] = { | 5580 | static const struct snd_pci_quirk alc262_fixup_tbl[] = { |
@@ -5436,6 +5589,10 @@ static const struct snd_pci_quirk alc262_fixup_tbl[] = { | |||
5436 | {} | 5589 | {} |
5437 | }; | 5590 | }; |
5438 | 5591 | ||
5592 | static const struct alc_model_fixup alc262_fixup_models[] = { | ||
5593 | {.id = ALC262_FIXUP_INV_DMIC, .name = "inv-dmic"}, | ||
5594 | {} | ||
5595 | }; | ||
5439 | 5596 | ||
5440 | /* | 5597 | /* |
5441 | */ | 5598 | */ |
@@ -5464,7 +5621,8 @@ static int patch_alc262(struct hda_codec *codec) | |||
5464 | #endif | 5621 | #endif |
5465 | alc_fix_pll_init(codec, 0x20, 0x0a, 10); | 5622 | alc_fix_pll_init(codec, 0x20, 0x0a, 10); |
5466 | 5623 | ||
5467 | alc_pick_fixup(codec, NULL, alc262_fixup_tbl, alc262_fixups); | 5624 | alc_pick_fixup(codec, alc262_fixup_models, alc262_fixup_tbl, |
5625 | alc262_fixups); | ||
5468 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); | 5626 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); |
5469 | 5627 | ||
5470 | alc_auto_parse_customize_define(codec); | 5628 | alc_auto_parse_customize_define(codec); |
@@ -5520,6 +5678,22 @@ static const struct hda_verb alc268_beep_init_verbs[] = { | |||
5520 | { } | 5678 | { } |
5521 | }; | 5679 | }; |
5522 | 5680 | ||
5681 | enum { | ||
5682 | ALC268_FIXUP_INV_DMIC, | ||
5683 | }; | ||
5684 | |||
5685 | static const struct alc_fixup alc268_fixups[] = { | ||
5686 | [ALC268_FIXUP_INV_DMIC] = { | ||
5687 | .type = ALC_FIXUP_FUNC, | ||
5688 | .v.func = alc_fixup_inv_dmic_0x12, | ||
5689 | }, | ||
5690 | }; | ||
5691 | |||
5692 | static const struct alc_model_fixup alc268_fixup_models[] = { | ||
5693 | {.id = ALC268_FIXUP_INV_DMIC, .name = "inv-dmic"}, | ||
5694 | {} | ||
5695 | }; | ||
5696 | |||
5523 | /* | 5697 | /* |
5524 | * BIOS auto configuration | 5698 | * BIOS auto configuration |
5525 | */ | 5699 | */ |
@@ -5551,6 +5725,9 @@ static int patch_alc268(struct hda_codec *codec) | |||
5551 | 5725 | ||
5552 | spec = codec->spec; | 5726 | spec = codec->spec; |
5553 | 5727 | ||
5728 | alc_pick_fixup(codec, alc268_fixup_models, NULL, alc268_fixups); | ||
5729 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PRE_PROBE); | ||
5730 | |||
5554 | /* automatic parse from the BIOS config */ | 5731 | /* automatic parse from the BIOS config */ |
5555 | err = alc268_parse_auto_config(codec); | 5732 | err = alc268_parse_auto_config(codec); |
5556 | if (err < 0) | 5733 | if (err < 0) |
@@ -5580,6 +5757,8 @@ static int patch_alc268(struct hda_codec *codec) | |||
5580 | codec->patch_ops = alc_patch_ops; | 5757 | codec->patch_ops = alc_patch_ops; |
5581 | spec->shutup = alc_eapd_shutup; | 5758 | spec->shutup = alc_eapd_shutup; |
5582 | 5759 | ||
5760 | alc_apply_fixup(codec, ALC_FIXUP_ACT_PROBE); | ||
5761 | |||
5583 | return 0; | 5762 | return 0; |
5584 | 5763 | ||
5585 | error: | 5764 | error: |
@@ -5808,6 +5987,7 @@ static void alc269_fixup_mic2_mute(struct hda_codec *codec, | |||
5808 | } | 5987 | } |
5809 | } | 5988 | } |
5810 | 5989 | ||
5990 | |||
5811 | enum { | 5991 | enum { |
5812 | ALC269_FIXUP_SONY_VAIO, | 5992 | ALC269_FIXUP_SONY_VAIO, |
5813 | ALC275_FIXUP_SONY_VAIO_GPIO2, | 5993 | ALC275_FIXUP_SONY_VAIO_GPIO2, |
@@ -5826,6 +6006,7 @@ enum { | |||
5826 | ALC269VB_FIXUP_AMIC, | 6006 | ALC269VB_FIXUP_AMIC, |
5827 | ALC269VB_FIXUP_DMIC, | 6007 | ALC269VB_FIXUP_DMIC, |
5828 | ALC269_FIXUP_MIC2_MUTE_LED, | 6008 | ALC269_FIXUP_MIC2_MUTE_LED, |
6009 | ALC269_FIXUP_INV_DMIC, | ||
5829 | }; | 6010 | }; |
5830 | 6011 | ||
5831 | static const struct alc_fixup alc269_fixups[] = { | 6012 | static const struct alc_fixup alc269_fixups[] = { |
@@ -5950,12 +6131,19 @@ static const struct alc_fixup alc269_fixups[] = { | |||
5950 | .type = ALC_FIXUP_FUNC, | 6131 | .type = ALC_FIXUP_FUNC, |
5951 | .v.func = alc269_fixup_mic2_mute, | 6132 | .v.func = alc269_fixup_mic2_mute, |
5952 | }, | 6133 | }, |
6134 | [ALC269_FIXUP_INV_DMIC] = { | ||
6135 | .type = ALC_FIXUP_FUNC, | ||
6136 | .v.func = alc_fixup_inv_dmic_0x12, | ||
6137 | }, | ||
5953 | }; | 6138 | }; |
5954 | 6139 | ||
5955 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { | 6140 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { |
6141 | SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC), | ||
6142 | SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC), | ||
5956 | SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_MIC2_MUTE_LED), | 6143 | SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_MIC2_MUTE_LED), |
5957 | SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_DMIC), | 6144 | SND_PCI_QUIRK(0x1043, 0x1427, "Asus Zenbook UX31E", ALC269VB_FIXUP_DMIC), |
5958 | SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), | 6145 | SND_PCI_QUIRK(0x1043, 0x1a13, "Asus G73Jw", ALC269_FIXUP_ASUS_G73JW), |
6146 | SND_PCI_QUIRK(0x1043, 0x1b13, "Asus U41SV", ALC269_FIXUP_INV_DMIC), | ||
5959 | SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), | 6147 | SND_PCI_QUIRK(0x1043, 0x16e3, "ASUS UX50", ALC269_FIXUP_STEREO_DMIC), |
5960 | SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), | 6148 | SND_PCI_QUIRK(0x1043, 0x831a, "ASUS P901", ALC269_FIXUP_STEREO_DMIC), |
5961 | SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC), | 6149 | SND_PCI_QUIRK(0x1043, 0x834a, "ASUS S101", ALC269_FIXUP_STEREO_DMIC), |
@@ -6031,6 +6219,9 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | |||
6031 | static const struct alc_model_fixup alc269_fixup_models[] = { | 6219 | static const struct alc_model_fixup alc269_fixup_models[] = { |
6032 | {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"}, | 6220 | {.id = ALC269_FIXUP_AMIC, .name = "laptop-amic"}, |
6033 | {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"}, | 6221 | {.id = ALC269_FIXUP_DMIC, .name = "laptop-dmic"}, |
6222 | {.id = ALC269_FIXUP_STEREO_DMIC, .name = "alc269-dmic"}, | ||
6223 | {.id = ALC271_FIXUP_DMIC, .name = "alc271-dmic"}, | ||
6224 | {.id = ALC269_FIXUP_INV_DMIC, .name = "inv-dmic"}, | ||
6034 | {} | 6225 | {} |
6035 | }; | 6226 | }; |
6036 | 6227 | ||
@@ -6327,12 +6518,6 @@ static const struct snd_pci_quirk alc861vd_fixup_tbl[] = { | |||
6327 | {} | 6518 | {} |
6328 | }; | 6519 | }; |
6329 | 6520 | ||
6330 | static const struct hda_verb alc660vd_eapd_verbs[] = { | ||
6331 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, | ||
6332 | {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, | ||
6333 | { } | ||
6334 | }; | ||
6335 | |||
6336 | /* | 6521 | /* |
6337 | */ | 6522 | */ |
6338 | static int patch_alc861vd(struct hda_codec *codec) | 6523 | static int patch_alc861vd(struct hda_codec *codec) |
@@ -6354,11 +6539,6 @@ static int patch_alc861vd(struct hda_codec *codec) | |||
6354 | if (err < 0) | 6539 | if (err < 0) |
6355 | goto error; | 6540 | goto error; |
6356 | 6541 | ||
6357 | if (codec->vendor_id == 0x10ec0660) { | ||
6358 | /* always turn on EAPD */ | ||
6359 | snd_hda_gen_add_verbs(&spec->gen, alc660vd_eapd_verbs); | ||
6360 | } | ||
6361 | |||
6362 | if (!spec->no_analog) { | 6542 | if (!spec->no_analog) { |
6363 | err = snd_hda_attach_beep_device(codec, 0x23); | 6543 | err = snd_hda_attach_beep_device(codec, 0x23); |
6364 | if (err < 0) | 6544 | if (err < 0) |
@@ -6441,6 +6621,7 @@ enum { | |||
6441 | ALC662_FIXUP_ASUS_MODE8, | 6621 | ALC662_FIXUP_ASUS_MODE8, |
6442 | ALC662_FIXUP_NO_JACK_DETECT, | 6622 | ALC662_FIXUP_NO_JACK_DETECT, |
6443 | ALC662_FIXUP_ZOTAC_Z68, | 6623 | ALC662_FIXUP_ZOTAC_Z68, |
6624 | ALC662_FIXUP_INV_DMIC, | ||
6444 | }; | 6625 | }; |
6445 | 6626 | ||
6446 | static const struct alc_fixup alc662_fixups[] = { | 6627 | static const struct alc_fixup alc662_fixups[] = { |
@@ -6597,12 +6778,17 @@ static const struct alc_fixup alc662_fixups[] = { | |||
6597 | { } | 6778 | { } |
6598 | } | 6779 | } |
6599 | }, | 6780 | }, |
6781 | [ALC662_FIXUP_INV_DMIC] = { | ||
6782 | .type = ALC_FIXUP_FUNC, | ||
6783 | .v.func = alc_fixup_inv_dmic_0x12, | ||
6784 | }, | ||
6600 | }; | 6785 | }; |
6601 | 6786 | ||
6602 | static const struct snd_pci_quirk alc662_fixup_tbl[] = { | 6787 | static const struct snd_pci_quirk alc662_fixup_tbl[] = { |
6603 | SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2), | 6788 | SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_FIXUP_ASUS_MODE2), |
6604 | SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE), | 6789 | SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE), |
6605 | SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE), | 6790 | SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE), |
6791 | SND_PCI_QUIRK(0x1025, 0x0349, "eMachines eM250", ALC662_FIXUP_INV_DMIC), | ||
6606 | SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), | 6792 | SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), |
6607 | SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), | 6793 | SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800), |
6608 | SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT), | 6794 | SND_PCI_QUIRK(0x1043, 0x8469, "ASUS mobo", ALC662_FIXUP_NO_JACK_DETECT), |
@@ -6683,9 +6869,35 @@ static const struct alc_model_fixup alc662_fixup_models[] = { | |||
6683 | {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"}, | 6869 | {.id = ALC662_FIXUP_ASUS_MODE6, .name = "asus-mode6"}, |
6684 | {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"}, | 6870 | {.id = ALC662_FIXUP_ASUS_MODE7, .name = "asus-mode7"}, |
6685 | {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"}, | 6871 | {.id = ALC662_FIXUP_ASUS_MODE8, .name = "asus-mode8"}, |
6872 | {.id = ALC662_FIXUP_INV_DMIC, .name = "inv-dmic"}, | ||
6686 | {} | 6873 | {} |
6687 | }; | 6874 | }; |
6688 | 6875 | ||
6876 | static void alc662_fill_coef(struct hda_codec *codec) | ||
6877 | { | ||
6878 | int val, coef; | ||
6879 | |||
6880 | coef = alc_get_coef0(codec); | ||
6881 | |||
6882 | switch (codec->vendor_id) { | ||
6883 | case 0x10ec0662: | ||
6884 | if ((coef & 0x00f0) == 0x0030) { | ||
6885 | val = alc_read_coef_idx(codec, 0x4); /* EAPD Ctrl */ | ||
6886 | alc_write_coef_idx(codec, 0x4, val & ~(1<<10)); | ||
6887 | } | ||
6888 | break; | ||
6889 | case 0x10ec0272: | ||
6890 | case 0x10ec0273: | ||
6891 | case 0x10ec0663: | ||
6892 | case 0x10ec0665: | ||
6893 | case 0x10ec0670: | ||
6894 | case 0x10ec0671: | ||
6895 | case 0x10ec0672: | ||
6896 | val = alc_read_coef_idx(codec, 0xd); /* EAPD Ctrl */ | ||
6897 | alc_write_coef_idx(codec, 0xd, val | (1<<14)); | ||
6898 | break; | ||
6899 | } | ||
6900 | } | ||
6689 | 6901 | ||
6690 | /* | 6902 | /* |
6691 | */ | 6903 | */ |
@@ -6705,12 +6917,8 @@ static int patch_alc662(struct hda_codec *codec) | |||
6705 | 6917 | ||
6706 | alc_fix_pll_init(codec, 0x20, 0x04, 15); | 6918 | alc_fix_pll_init(codec, 0x20, 0x04, 15); |
6707 | 6919 | ||
6708 | if ((alc_get_coef0(codec) & (1 << 14)) && | 6920 | spec->init_hook = alc662_fill_coef; |
6709 | codec->bus->pci->subsystem_vendor == 0x1025 && | 6921 | alc662_fill_coef(codec); |
6710 | spec->cdefine.platform_type == 1) { | ||
6711 | if (alc_codec_rename(codec, "ALC272X") < 0) | ||
6712 | goto error; | ||
6713 | } | ||
6714 | 6922 | ||
6715 | alc_pick_fixup(codec, alc662_fixup_models, | 6923 | alc_pick_fixup(codec, alc662_fixup_models, |
6716 | alc662_fixup_tbl, alc662_fixups); | 6924 | alc662_fixup_tbl, alc662_fixups); |
@@ -6718,6 +6926,13 @@ static int patch_alc662(struct hda_codec *codec) | |||
6718 | 6926 | ||
6719 | alc_auto_parse_customize_define(codec); | 6927 | alc_auto_parse_customize_define(codec); |
6720 | 6928 | ||
6929 | if ((alc_get_coef0(codec) & (1 << 14)) && | ||
6930 | codec->bus->pci->subsystem_vendor == 0x1025 && | ||
6931 | spec->cdefine.platform_type == 1) { | ||
6932 | if (alc_codec_rename(codec, "ALC272X") < 0) | ||
6933 | goto error; | ||
6934 | } | ||
6935 | |||
6721 | /* automatic parse from the BIOS config */ | 6936 | /* automatic parse from the BIOS config */ |
6722 | err = alc662_parse_auto_config(codec); | 6937 | err = alc662_parse_auto_config(codec); |
6723 | if (err < 0) | 6938 | if (err < 0) |
@@ -6800,6 +7015,8 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = { | |||
6800 | { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 }, | 7015 | { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 }, |
6801 | { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 }, | 7016 | { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 }, |
6802 | { .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 }, | 7017 | { .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 }, |
7018 | { .id = 0x10ec0280, .name = "ALC280", .patch = patch_alc269 }, | ||
7019 | { .id = 0x10ec0282, .name = "ALC282", .patch = patch_alc269 }, | ||
6803 | { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", | 7020 | { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", |
6804 | .patch = patch_alc861 }, | 7021 | .patch = patch_alc861 }, |
6805 | { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, | 7022 | { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 7db8228f1b8..07675282015 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -4367,7 +4367,7 @@ static int stac92xx_init(struct hda_codec *codec) | |||
4367 | AC_PINCTL_IN_EN); | 4367 | AC_PINCTL_IN_EN); |
4368 | for (i = 0; i < spec->num_pwrs; i++) { | 4368 | for (i = 0; i < spec->num_pwrs; i++) { |
4369 | hda_nid_t nid = spec->pwr_nids[i]; | 4369 | hda_nid_t nid = spec->pwr_nids[i]; |
4370 | int pinctl, def_conf; | 4370 | unsigned int pinctl, def_conf; |
4371 | 4371 | ||
4372 | def_conf = snd_hda_codec_get_pincfg(codec, nid); | 4372 | def_conf = snd_hda_codec_get_pincfg(codec, nid); |
4373 | def_conf = get_defcfg_connect(def_conf); | 4373 | def_conf = get_defcfg_connect(def_conf); |
@@ -4376,6 +4376,11 @@ static int stac92xx_init(struct hda_codec *codec) | |||
4376 | stac_toggle_power_map(codec, nid, 0); | 4376 | stac_toggle_power_map(codec, nid, 0); |
4377 | continue; | 4377 | continue; |
4378 | } | 4378 | } |
4379 | if (def_conf == AC_JACK_PORT_FIXED) { | ||
4380 | /* no need for jack detection for fixed pins */ | ||
4381 | stac_toggle_power_map(codec, nid, 1); | ||
4382 | continue; | ||
4383 | } | ||
4379 | /* power on when no jack detection is available */ | 4384 | /* power on when no jack detection is available */ |
4380 | /* or when the VREF is used for controlling LED */ | 4385 | /* or when the VREF is used for controlling LED */ |
4381 | if (!spec->hp_detect || | 4386 | if (!spec->hp_detect || |
diff --git a/sound/pci/maestro3.c b/sound/pci/maestro3.c index deef2139958..adb3b4c7917 100644 --- a/sound/pci/maestro3.c +++ b/sound/pci/maestro3.c | |||
@@ -361,74 +361,6 @@ MODULE_PARM_DESC(amp_gpio, "GPIO pin number for external amp. (default = -1)"); | |||
361 | #define DSP2HOST_REQ_I2SRATE 0x02 | 361 | #define DSP2HOST_REQ_I2SRATE 0x02 |
362 | #define DSP2HOST_REQ_TIMER 0x04 | 362 | #define DSP2HOST_REQ_TIMER 0x04 |
363 | 363 | ||
364 | /* AC97 registers */ | ||
365 | /* XXX fix this crap up */ | ||
366 | /*#define AC97_RESET 0x00*/ | ||
367 | |||
368 | #define AC97_VOL_MUTE_B 0x8000 | ||
369 | #define AC97_VOL_M 0x1F | ||
370 | #define AC97_LEFT_VOL_S 8 | ||
371 | |||
372 | #define AC97_MASTER_VOL 0x02 | ||
373 | #define AC97_LINE_LEVEL_VOL 0x04 | ||
374 | #define AC97_MASTER_MONO_VOL 0x06 | ||
375 | #define AC97_PC_BEEP_VOL 0x0A | ||
376 | #define AC97_PC_BEEP_VOL_M 0x0F | ||
377 | #define AC97_SROUND_MASTER_VOL 0x38 | ||
378 | #define AC97_PC_BEEP_VOL_S 1 | ||
379 | |||
380 | /*#define AC97_PHONE_VOL 0x0C | ||
381 | #define AC97_MIC_VOL 0x0E*/ | ||
382 | #define AC97_MIC_20DB_ENABLE 0x40 | ||
383 | |||
384 | /*#define AC97_LINEIN_VOL 0x10 | ||
385 | #define AC97_CD_VOL 0x12 | ||
386 | #define AC97_VIDEO_VOL 0x14 | ||
387 | #define AC97_AUX_VOL 0x16*/ | ||
388 | #define AC97_PCM_OUT_VOL 0x18 | ||
389 | /*#define AC97_RECORD_SELECT 0x1A*/ | ||
390 | #define AC97_RECORD_MIC 0x00 | ||
391 | #define AC97_RECORD_CD 0x01 | ||
392 | #define AC97_RECORD_VIDEO 0x02 | ||
393 | #define AC97_RECORD_AUX 0x03 | ||
394 | #define AC97_RECORD_MONO_MUX 0x02 | ||
395 | #define AC97_RECORD_DIGITAL 0x03 | ||
396 | #define AC97_RECORD_LINE 0x04 | ||
397 | #define AC97_RECORD_STEREO 0x05 | ||
398 | #define AC97_RECORD_MONO 0x06 | ||
399 | #define AC97_RECORD_PHONE 0x07 | ||
400 | |||
401 | /*#define AC97_RECORD_GAIN 0x1C*/ | ||
402 | #define AC97_RECORD_VOL_M 0x0F | ||
403 | |||
404 | /*#define AC97_GENERAL_PURPOSE 0x20*/ | ||
405 | #define AC97_POWER_DOWN_CTRL 0x26 | ||
406 | #define AC97_ADC_READY 0x0001 | ||
407 | #define AC97_DAC_READY 0x0002 | ||
408 | #define AC97_ANALOG_READY 0x0004 | ||
409 | #define AC97_VREF_ON 0x0008 | ||
410 | #define AC97_PR0 0x0100 | ||
411 | #define AC97_PR1 0x0200 | ||
412 | #define AC97_PR2 0x0400 | ||
413 | #define AC97_PR3 0x0800 | ||
414 | #define AC97_PR4 0x1000 | ||
415 | |||
416 | #define AC97_RESERVED1 0x28 | ||
417 | |||
418 | #define AC97_VENDOR_TEST 0x5A | ||
419 | |||
420 | #define AC97_CLOCK_DELAY 0x5C | ||
421 | #define AC97_LINEOUT_MUX_SEL 0x0001 | ||
422 | #define AC97_MONO_MUX_SEL 0x0002 | ||
423 | #define AC97_CLOCK_DELAY_SEL 0x1F | ||
424 | #define AC97_DAC_CDS_SHIFT 6 | ||
425 | #define AC97_ADC_CDS_SHIFT 11 | ||
426 | |||
427 | #define AC97_MULTI_CHANNEL_SEL 0x74 | ||
428 | |||
429 | /*#define AC97_VENDOR_ID1 0x7C | ||
430 | #define AC97_VENDOR_ID2 0x7E*/ | ||
431 | |||
432 | /* | 364 | /* |
433 | * ASSP control regs | 365 | * ASSP control regs |
434 | */ | 366 | */ |
diff --git a/sound/pci/pcxhr/pcxhr.c b/sound/pci/pcxhr/pcxhr.c index 0435f45e951..e3ac1f768ff 100644 --- a/sound/pci/pcxhr/pcxhr.c +++ b/sound/pci/pcxhr/pcxhr.c | |||
@@ -1368,6 +1368,67 @@ static void pcxhr_proc_gpo_write(struct snd_info_entry *entry, | |||
1368 | } | 1368 | } |
1369 | } | 1369 | } |
1370 | 1370 | ||
1371 | /* Access to the results of the CMD_GET_TIME_CODE RMH */ | ||
1372 | #define TIME_CODE_VALID_MASK 0x00800000 | ||
1373 | #define TIME_CODE_NEW_MASK 0x00400000 | ||
1374 | #define TIME_CODE_BACK_MASK 0x00200000 | ||
1375 | #define TIME_CODE_WAIT_MASK 0x00100000 | ||
1376 | |||
1377 | /* Values for the CMD_MANAGE_SIGNAL RMH */ | ||
1378 | #define MANAGE_SIGNAL_TIME_CODE 0x01 | ||
1379 | #define MANAGE_SIGNAL_MIDI 0x02 | ||
1380 | |||
1381 | /* linear time code read proc*/ | ||
1382 | static void pcxhr_proc_ltc(struct snd_info_entry *entry, | ||
1383 | struct snd_info_buffer *buffer) | ||
1384 | { | ||
1385 | struct snd_pcxhr *chip = entry->private_data; | ||
1386 | struct pcxhr_mgr *mgr = chip->mgr; | ||
1387 | struct pcxhr_rmh rmh; | ||
1388 | unsigned int ltcHrs, ltcMin, ltcSec, ltcFrm; | ||
1389 | int err; | ||
1390 | /* commands available when embedded DSP is running */ | ||
1391 | if (!(mgr->dsp_loaded & (1 << PCXHR_FIRMWARE_DSP_MAIN_INDEX))) { | ||
1392 | snd_iprintf(buffer, "no firmware loaded\n"); | ||
1393 | return; | ||
1394 | } | ||
1395 | if (!mgr->capture_ltc) { | ||
1396 | pcxhr_init_rmh(&rmh, CMD_MANAGE_SIGNAL); | ||
1397 | rmh.cmd[0] |= MANAGE_SIGNAL_TIME_CODE; | ||
1398 | err = pcxhr_send_msg(mgr, &rmh); | ||
1399 | if (err) { | ||
1400 | snd_iprintf(buffer, "ltc not activated (%d)\n", err); | ||
1401 | return; | ||
1402 | } | ||
1403 | if (mgr->is_hr_stereo) | ||
1404 | hr222_manage_timecode(mgr, 1); | ||
1405 | else | ||
1406 | pcxhr_write_io_num_reg_cont(mgr, REG_CONT_VALSMPTE, | ||
1407 | REG_CONT_VALSMPTE, NULL); | ||
1408 | mgr->capture_ltc = 1; | ||
1409 | } | ||
1410 | pcxhr_init_rmh(&rmh, CMD_GET_TIME_CODE); | ||
1411 | err = pcxhr_send_msg(mgr, &rmh); | ||
1412 | if (err) { | ||
1413 | snd_iprintf(buffer, "ltc read error (err=%d)\n", err); | ||
1414 | return ; | ||
1415 | } | ||
1416 | ltcHrs = 10*((rmh.stat[0] >> 8) & 0x3) + (rmh.stat[0] & 0xf); | ||
1417 | ltcMin = 10*((rmh.stat[1] >> 16) & 0x7) + ((rmh.stat[1] >> 8) & 0xf); | ||
1418 | ltcSec = 10*(rmh.stat[1] & 0x7) + ((rmh.stat[2] >> 16) & 0xf); | ||
1419 | ltcFrm = 10*((rmh.stat[2] >> 8) & 0x3) + (rmh.stat[2] & 0xf); | ||
1420 | |||
1421 | snd_iprintf(buffer, "timecode: %02u:%02u:%02u-%02u\n", | ||
1422 | ltcHrs, ltcMin, ltcSec, ltcFrm); | ||
1423 | snd_iprintf(buffer, "raw: 0x%04x%06x%06x\n", rmh.stat[0] & 0x00ffff, | ||
1424 | rmh.stat[1] & 0xffffff, rmh.stat[2] & 0xffffff); | ||
1425 | /*snd_iprintf(buffer, "dsp ref time: 0x%06x%06x\n", | ||
1426 | rmh.stat[3] & 0xffffff, rmh.stat[4] & 0xffffff);*/ | ||
1427 | if (!(rmh.stat[0] & TIME_CODE_VALID_MASK)) { | ||
1428 | snd_iprintf(buffer, "warning: linear timecode not valid\n"); | ||
1429 | } | ||
1430 | } | ||
1431 | |||
1371 | static void __devinit pcxhr_proc_init(struct snd_pcxhr *chip) | 1432 | static void __devinit pcxhr_proc_init(struct snd_pcxhr *chip) |
1372 | { | 1433 | { |
1373 | struct snd_info_entry *entry; | 1434 | struct snd_info_entry *entry; |
@@ -1383,6 +1444,8 @@ static void __devinit pcxhr_proc_init(struct snd_pcxhr *chip) | |||
1383 | entry->c.text.write = pcxhr_proc_gpo_write; | 1444 | entry->c.text.write = pcxhr_proc_gpo_write; |
1384 | entry->mode |= S_IWUSR; | 1445 | entry->mode |= S_IWUSR; |
1385 | } | 1446 | } |
1447 | if (!snd_card_proc_new(chip->card, "ltc", &entry)) | ||
1448 | snd_info_set_text_ops(entry, chip, pcxhr_proc_ltc); | ||
1386 | } | 1449 | } |
1387 | /* end of proc interface */ | 1450 | /* end of proc interface */ |
1388 | 1451 | ||
diff --git a/sound/pci/pcxhr/pcxhr.h b/sound/pci/pcxhr/pcxhr.h index bda776c4988..a4c602c4517 100644 --- a/sound/pci/pcxhr/pcxhr.h +++ b/sound/pci/pcxhr/pcxhr.h | |||
@@ -103,6 +103,7 @@ struct pcxhr_mgr { | |||
103 | unsigned int board_has_mic:1; /* if 1 the board has microphone input */ | 103 | unsigned int board_has_mic:1; /* if 1 the board has microphone input */ |
104 | unsigned int board_aes_in_192k:1;/* if 1 the aes input plugs do support 192kHz */ | 104 | unsigned int board_aes_in_192k:1;/* if 1 the aes input plugs do support 192kHz */ |
105 | unsigned int mono_capture:1; /* if 1 the board does mono capture */ | 105 | unsigned int mono_capture:1; /* if 1 the board does mono capture */ |
106 | unsigned int capture_ltc:1; /* if 1 the board captures LTC input */ | ||
106 | 107 | ||
107 | struct snd_dma_buffer hostport; | 108 | struct snd_dma_buffer hostport; |
108 | 109 | ||
diff --git a/sound/pci/pcxhr/pcxhr_core.c b/sound/pci/pcxhr/pcxhr_core.c index 304411c1fe4..b33db1e006e 100644 --- a/sound/pci/pcxhr/pcxhr_core.c +++ b/sound/pci/pcxhr/pcxhr_core.c | |||
@@ -504,6 +504,8 @@ static struct pcxhr_cmd_info pcxhr_dsp_cmds[] = { | |||
504 | [CMD_FORMAT_STREAM_IN] = { 0x870000, 0, RMH_SSIZE_FIXED }, | 504 | [CMD_FORMAT_STREAM_IN] = { 0x870000, 0, RMH_SSIZE_FIXED }, |
505 | [CMD_STREAM_SAMPLE_COUNT] = { 0x902000, 2, RMH_SSIZE_FIXED }, | 505 | [CMD_STREAM_SAMPLE_COUNT] = { 0x902000, 2, RMH_SSIZE_FIXED }, |
506 | [CMD_AUDIO_LEVEL_ADJUST] = { 0xc22000, 0, RMH_SSIZE_FIXED }, | 506 | [CMD_AUDIO_LEVEL_ADJUST] = { 0xc22000, 0, RMH_SSIZE_FIXED }, |
507 | [CMD_GET_TIME_CODE] = { 0x060000, 5, RMH_SSIZE_FIXED }, | ||
508 | [CMD_MANAGE_SIGNAL] = { 0x0f0000, 0, RMH_SSIZE_FIXED }, | ||
507 | }; | 509 | }; |
508 | 510 | ||
509 | #ifdef CONFIG_SND_DEBUG_VERBOSE | 511 | #ifdef CONFIG_SND_DEBUG_VERBOSE |
@@ -533,6 +535,8 @@ static char* cmd_names[] = { | |||
533 | [CMD_FORMAT_STREAM_IN] = "CMD_FORMAT_STREAM_IN", | 535 | [CMD_FORMAT_STREAM_IN] = "CMD_FORMAT_STREAM_IN", |
534 | [CMD_STREAM_SAMPLE_COUNT] = "CMD_STREAM_SAMPLE_COUNT", | 536 | [CMD_STREAM_SAMPLE_COUNT] = "CMD_STREAM_SAMPLE_COUNT", |
535 | [CMD_AUDIO_LEVEL_ADJUST] = "CMD_AUDIO_LEVEL_ADJUST", | 537 | [CMD_AUDIO_LEVEL_ADJUST] = "CMD_AUDIO_LEVEL_ADJUST", |
538 | [CMD_GET_TIME_CODE] = "CMD_GET_TIME_CODE", | ||
539 | [CMD_MANAGE_SIGNAL] = "CMD_MANAGE_SIGNAL", | ||
536 | }; | 540 | }; |
537 | #endif | 541 | #endif |
538 | 542 | ||
@@ -1133,13 +1137,12 @@ static u_int64_t pcxhr_stream_read_position(struct pcxhr_mgr *mgr, | |||
1133 | hw_sample_count = ((u_int64_t)rmh.stat[0]) << 24; | 1137 | hw_sample_count = ((u_int64_t)rmh.stat[0]) << 24; |
1134 | hw_sample_count += (u_int64_t)rmh.stat[1]; | 1138 | hw_sample_count += (u_int64_t)rmh.stat[1]; |
1135 | 1139 | ||
1136 | snd_printdd("stream %c%d : abs samples real(%ld) timer(%ld)\n", | 1140 | snd_printdd("stream %c%d : abs samples real(%llu) timer(%llu)\n", |
1137 | stream->pipe->is_capture ? 'C' : 'P', | 1141 | stream->pipe->is_capture ? 'C' : 'P', |
1138 | stream->substream->number, | 1142 | stream->substream->number, |
1139 | (long unsigned int)hw_sample_count, | 1143 | hw_sample_count, |
1140 | (long unsigned int)(stream->timer_abs_periods + | 1144 | stream->timer_abs_periods + stream->timer_period_frag + |
1141 | stream->timer_period_frag + | 1145 | mgr->granularity); |
1142 | mgr->granularity)); | ||
1143 | return hw_sample_count; | 1146 | return hw_sample_count; |
1144 | } | 1147 | } |
1145 | 1148 | ||
@@ -1243,10 +1246,18 @@ irqreturn_t pcxhr_interrupt(int irq, void *dev_id) | |||
1243 | 1246 | ||
1244 | if ((dsp_time_diff < 0) && | 1247 | if ((dsp_time_diff < 0) && |
1245 | (mgr->dsp_time_last != PCXHR_DSP_TIME_INVALID)) { | 1248 | (mgr->dsp_time_last != PCXHR_DSP_TIME_INVALID)) { |
1246 | snd_printdd("ERROR DSP TIME old(%d) new(%d) -> " | 1249 | /* handle dsp counter wraparound without resync */ |
1247 | "resynchronize all streams\n", | 1250 | int tmp_diff = dsp_time_diff + PCXHR_DSP_TIME_MASK + 1; |
1251 | snd_printdd("WARNING DSP timestamp old(%d) new(%d)", | ||
1248 | mgr->dsp_time_last, dsp_time_new); | 1252 | mgr->dsp_time_last, dsp_time_new); |
1249 | mgr->dsp_time_err++; | 1253 | if (tmp_diff > 0 && tmp_diff <= (2*mgr->granularity)) { |
1254 | snd_printdd("-> timestamp wraparound OK: " | ||
1255 | "diff=%d\n", tmp_diff); | ||
1256 | dsp_time_diff = tmp_diff; | ||
1257 | } else { | ||
1258 | snd_printdd("-> resynchronize all streams\n"); | ||
1259 | mgr->dsp_time_err++; | ||
1260 | } | ||
1250 | } | 1261 | } |
1251 | #ifdef CONFIG_SND_DEBUG_VERBOSE | 1262 | #ifdef CONFIG_SND_DEBUG_VERBOSE |
1252 | if (dsp_time_diff == 0) | 1263 | if (dsp_time_diff == 0) |
diff --git a/sound/pci/pcxhr/pcxhr_core.h b/sound/pci/pcxhr/pcxhr_core.h index be0173796cd..a81ab6b811e 100644 --- a/sound/pci/pcxhr/pcxhr_core.h +++ b/sound/pci/pcxhr/pcxhr_core.h | |||
@@ -79,6 +79,8 @@ enum { | |||
79 | CMD_FORMAT_STREAM_IN, /* cmd_len >= 4 stat_len = 0 */ | 79 | CMD_FORMAT_STREAM_IN, /* cmd_len >= 4 stat_len = 0 */ |
80 | CMD_STREAM_SAMPLE_COUNT, /* cmd_len = 2 stat_len = (2 * nb_stream) */ | 80 | CMD_STREAM_SAMPLE_COUNT, /* cmd_len = 2 stat_len = (2 * nb_stream) */ |
81 | CMD_AUDIO_LEVEL_ADJUST, /* cmd_len = 3 stat_len = 0 */ | 81 | CMD_AUDIO_LEVEL_ADJUST, /* cmd_len = 3 stat_len = 0 */ |
82 | CMD_GET_TIME_CODE, /* cmd_len = 1 stat_len = 5 */ | ||
83 | CMD_MANAGE_SIGNAL, /* cmd_len = 1 stat_len = 0 */ | ||
82 | CMD_LAST_INDEX | 84 | CMD_LAST_INDEX |
83 | }; | 85 | }; |
84 | 86 | ||
@@ -116,7 +118,7 @@ int pcxhr_send_msg(struct pcxhr_mgr *mgr, struct pcxhr_rmh *rmh); | |||
116 | #define IO_NUM_REG_OUT_ANA_LEVEL 20 | 118 | #define IO_NUM_REG_OUT_ANA_LEVEL 20 |
117 | #define IO_NUM_REG_IN_ANA_LEVEL 21 | 119 | #define IO_NUM_REG_IN_ANA_LEVEL 21 |
118 | 120 | ||
119 | 121 | #define REG_CONT_VALSMPTE 0x000800 | |
120 | #define REG_CONT_UNMUTE_INPUTS 0x020000 | 122 | #define REG_CONT_UNMUTE_INPUTS 0x020000 |
121 | 123 | ||
122 | /* parameters used with register IO_NUM_REG_STATUS */ | 124 | /* parameters used with register IO_NUM_REG_STATUS */ |
diff --git a/sound/pci/pcxhr/pcxhr_mix22.c b/sound/pci/pcxhr/pcxhr_mix22.c index 1cb82c0a9cb..84fe57626eb 100644 --- a/sound/pci/pcxhr/pcxhr_mix22.c +++ b/sound/pci/pcxhr/pcxhr_mix22.c | |||
@@ -53,6 +53,7 @@ | |||
53 | #define PCXHR_DSP_RESET_DSP 0x01 | 53 | #define PCXHR_DSP_RESET_DSP 0x01 |
54 | #define PCXHR_DSP_RESET_MUTE 0x02 | 54 | #define PCXHR_DSP_RESET_MUTE 0x02 |
55 | #define PCXHR_DSP_RESET_CODEC 0x08 | 55 | #define PCXHR_DSP_RESET_CODEC 0x08 |
56 | #define PCXHR_DSP_RESET_SMPTE 0x10 | ||
56 | #define PCXHR_DSP_RESET_GPO_OFFSET 5 | 57 | #define PCXHR_DSP_RESET_GPO_OFFSET 5 |
57 | #define PCXHR_DSP_RESET_GPO_MASK 0x60 | 58 | #define PCXHR_DSP_RESET_GPO_MASK 0x60 |
58 | 59 | ||
@@ -527,6 +528,16 @@ int hr222_write_gpo(struct pcxhr_mgr *mgr, int value) | |||
527 | return 0; | 528 | return 0; |
528 | } | 529 | } |
529 | 530 | ||
531 | int hr222_manage_timecode(struct pcxhr_mgr *mgr, int enable) | ||
532 | { | ||
533 | if (enable) | ||
534 | mgr->dsp_reset |= PCXHR_DSP_RESET_SMPTE; | ||
535 | else | ||
536 | mgr->dsp_reset &= ~PCXHR_DSP_RESET_SMPTE; | ||
537 | |||
538 | PCXHR_OUTPB(mgr, PCXHR_DSP_RESET, mgr->dsp_reset); | ||
539 | return 0; | ||
540 | } | ||
530 | 541 | ||
531 | int hr222_update_analog_audio_level(struct snd_pcxhr *chip, | 542 | int hr222_update_analog_audio_level(struct snd_pcxhr *chip, |
532 | int is_capture, int channel) | 543 | int is_capture, int channel) |
diff --git a/sound/pci/pcxhr/pcxhr_mix22.h b/sound/pci/pcxhr/pcxhr_mix22.h index 5a37a0007e8..5971b9933f4 100644 --- a/sound/pci/pcxhr/pcxhr_mix22.h +++ b/sound/pci/pcxhr/pcxhr_mix22.h | |||
@@ -34,6 +34,7 @@ int hr222_get_external_clock(struct pcxhr_mgr *mgr, | |||
34 | 34 | ||
35 | int hr222_read_gpio(struct pcxhr_mgr *mgr, int is_gpi, int *value); | 35 | int hr222_read_gpio(struct pcxhr_mgr *mgr, int is_gpi, int *value); |
36 | int hr222_write_gpo(struct pcxhr_mgr *mgr, int value); | 36 | int hr222_write_gpo(struct pcxhr_mgr *mgr, int value); |
37 | int hr222_manage_timecode(struct pcxhr_mgr *mgr, int enable); | ||
37 | 38 | ||
38 | #define HR222_LINE_PLAYBACK_LEVEL_MIN 0 /* -25.5 dB */ | 39 | #define HR222_LINE_PLAYBACK_LEVEL_MIN 0 /* -25.5 dB */ |
39 | #define HR222_LINE_PLAYBACK_ZERO_LEVEL 51 /* 0.0 dB */ | 40 | #define HR222_LINE_PLAYBACK_ZERO_LEVEL 51 /* 0.0 dB */ |
diff --git a/sound/soc/codecs/tlv320aic3x.c b/sound/soc/codecs/tlv320aic3x.c index b94f81ffed3..dc78f5a4bcb 100644 --- a/sound/soc/codecs/tlv320aic3x.c +++ b/sound/soc/codecs/tlv320aic3x.c | |||
@@ -965,9 +965,7 @@ static int aic3x_hw_params(struct snd_pcm_substream *substream, | |||
965 | } | 965 | } |
966 | 966 | ||
967 | found: | 967 | found: |
968 | data = snd_soc_read(codec, AIC3X_PLL_PROGA_REG); | 968 | snd_soc_update_bits(codec, AIC3X_PLL_PROGA_REG, PLLP_MASK, pll_p); |
969 | snd_soc_write(codec, AIC3X_PLL_PROGA_REG, | ||
970 | data | (pll_p << PLLP_SHIFT)); | ||
971 | snd_soc_write(codec, AIC3X_OVRF_STATUS_AND_PLLR_REG, | 969 | snd_soc_write(codec, AIC3X_OVRF_STATUS_AND_PLLR_REG, |
972 | pll_r << PLLR_SHIFT); | 970 | pll_r << PLLR_SHIFT); |
973 | snd_soc_write(codec, AIC3X_PLL_PROGB_REG, pll_j << PLLJ_SHIFT); | 971 | snd_soc_write(codec, AIC3X_PLL_PROGB_REG, pll_j << PLLJ_SHIFT); |
diff --git a/sound/soc/codecs/tlv320aic3x.h b/sound/soc/codecs/tlv320aic3x.h index 149338b254f..6db3c41b016 100644 --- a/sound/soc/codecs/tlv320aic3x.h +++ b/sound/soc/codecs/tlv320aic3x.h | |||
@@ -183,6 +183,7 @@ | |||
183 | 183 | ||
184 | /* PLL registers bitfields */ | 184 | /* PLL registers bitfields */ |
185 | #define PLLP_SHIFT 0 | 185 | #define PLLP_SHIFT 0 |
186 | #define PLLP_MASK 7 | ||
186 | #define PLLQ_SHIFT 3 | 187 | #define PLLQ_SHIFT 3 |
187 | #define PLLR_SHIFT 0 | 188 | #define PLLR_SHIFT 0 |
188 | #define PLLJ_SHIFT 2 | 189 | #define PLLJ_SHIFT 2 |
diff --git a/sound/soc/codecs/wm2200.c b/sound/soc/codecs/wm2200.c index acbdc5fde92..32682c1b7cd 100644 --- a/sound/soc/codecs/wm2200.c +++ b/sound/soc/codecs/wm2200.c | |||
@@ -1491,6 +1491,7 @@ static int wm2200_bclk_rates_dat[WM2200_NUM_BCLK_RATES] = { | |||
1491 | 1491 | ||
1492 | static int wm2200_bclk_rates_cd[WM2200_NUM_BCLK_RATES] = { | 1492 | static int wm2200_bclk_rates_cd[WM2200_NUM_BCLK_RATES] = { |
1493 | 5644800, | 1493 | 5644800, |
1494 | 3763200, | ||
1494 | 2882400, | 1495 | 2882400, |
1495 | 1881600, | 1496 | 1881600, |
1496 | 1411200, | 1497 | 1411200, |
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index 65763388649..bb62f4b3d56 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c | |||
@@ -727,9 +727,6 @@ static void wm1811_jackdet_set_mode(struct snd_soc_codec *codec, u16 mode) | |||
727 | if (!wm8994->jackdet || !wm8994->jack_cb) | 727 | if (!wm8994->jackdet || !wm8994->jack_cb) |
728 | return; | 728 | return; |
729 | 729 | ||
730 | if (!wm8994->jackdet || !wm8994->jack_cb) | ||
731 | return; | ||
732 | |||
733 | if (wm8994->active_refcount) | 730 | if (wm8994->active_refcount) |
734 | mode = WM1811_JACKDET_MODE_AUDIO; | 731 | mode = WM1811_JACKDET_MODE_AUDIO; |
735 | 732 | ||
diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c index 64aed432ae2..7da0d0aa72c 100644 --- a/sound/usb/caiaq/device.c +++ b/sound/usb/caiaq/device.c | |||
@@ -485,7 +485,7 @@ static int __devinit snd_probe(struct usb_interface *intf, | |||
485 | const struct usb_device_id *id) | 485 | const struct usb_device_id *id) |
486 | { | 486 | { |
487 | int ret; | 487 | int ret; |
488 | struct snd_card *card; | 488 | struct snd_card *card = NULL; |
489 | struct usb_device *device = interface_to_usbdev(intf); | 489 | struct usb_device *device = interface_to_usbdev(intf); |
490 | 490 | ||
491 | ret = create_card(device, intf, &card); | 491 | ret = create_card(device, intf, &card); |
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index e6906901deb..0f647d22cb4 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c | |||
@@ -414,7 +414,7 @@ struct snd_usb_endpoint *snd_usb_add_endpoint(struct snd_usb_audio *chip, | |||
414 | { | 414 | { |
415 | struct list_head *p; | 415 | struct list_head *p; |
416 | struct snd_usb_endpoint *ep; | 416 | struct snd_usb_endpoint *ep; |
417 | int ret, is_playback = direction == SNDRV_PCM_STREAM_PLAYBACK; | 417 | int is_playback = direction == SNDRV_PCM_STREAM_PLAYBACK; |
418 | 418 | ||
419 | mutex_lock(&chip->mutex); | 419 | mutex_lock(&chip->mutex); |
420 | 420 | ||
@@ -434,16 +434,6 @@ struct snd_usb_endpoint *snd_usb_add_endpoint(struct snd_usb_audio *chip, | |||
434 | type == SND_USB_ENDPOINT_TYPE_DATA ? "data" : "sync", | 434 | type == SND_USB_ENDPOINT_TYPE_DATA ? "data" : "sync", |
435 | ep_num); | 435 | ep_num); |
436 | 436 | ||
437 | /* select the alt setting once so the endpoints become valid */ | ||
438 | ret = usb_set_interface(chip->dev, alts->desc.bInterfaceNumber, | ||
439 | alts->desc.bAlternateSetting); | ||
440 | if (ret < 0) { | ||
441 | snd_printk(KERN_ERR "%s(): usb_set_interface() failed, ret = %d\n", | ||
442 | __func__, ret); | ||
443 | ep = NULL; | ||
444 | goto __exit_unlock; | ||
445 | } | ||
446 | |||
447 | ep = kzalloc(sizeof(*ep), GFP_KERNEL); | 437 | ep = kzalloc(sizeof(*ep), GFP_KERNEL); |
448 | if (!ep) | 438 | if (!ep) |
449 | goto __exit_unlock; | 439 | goto __exit_unlock; |
@@ -831,9 +821,6 @@ int snd_usb_endpoint_start(struct snd_usb_endpoint *ep) | |||
831 | if (++ep->use_count != 1) | 821 | if (++ep->use_count != 1) |
832 | return 0; | 822 | return 0; |
833 | 823 | ||
834 | if (snd_BUG_ON(!test_bit(EP_FLAG_ACTIVATED, &ep->flags))) | ||
835 | return -EINVAL; | ||
836 | |||
837 | /* just to be sure */ | 824 | /* just to be sure */ |
838 | deactivate_urbs(ep, 0, 1); | 825 | deactivate_urbs(ep, 0, 1); |
839 | wait_clear_urbs(ep); | 826 | wait_clear_urbs(ep); |
@@ -911,9 +898,6 @@ void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep, | |||
911 | if (snd_BUG_ON(ep->use_count == 0)) | 898 | if (snd_BUG_ON(ep->use_count == 0)) |
912 | return; | 899 | return; |
913 | 900 | ||
914 | if (snd_BUG_ON(!test_bit(EP_FLAG_ACTIVATED, &ep->flags))) | ||
915 | return; | ||
916 | |||
917 | if (--ep->use_count == 0) { | 901 | if (--ep->use_count == 0) { |
918 | deactivate_urbs(ep, force, can_sleep); | 902 | deactivate_urbs(ep, force, can_sleep); |
919 | ep->data_subs = NULL; | 903 | ep->data_subs = NULL; |
@@ -927,42 +911,6 @@ void snd_usb_endpoint_stop(struct snd_usb_endpoint *ep, | |||
927 | } | 911 | } |
928 | 912 | ||
929 | /** | 913 | /** |
930 | * snd_usb_endpoint_activate: activate an snd_usb_endpoint | ||
931 | * | ||
932 | * @ep: the endpoint to activate | ||
933 | * | ||
934 | * If the endpoint is not currently in use, this functions will select the | ||
935 | * correct alternate interface setting for the interface of this endpoint. | ||
936 | * | ||
937 | * In case of any active users, this functions does nothing. | ||
938 | * | ||
939 | * Returns an error if usb_set_interface() failed, 0 in all other | ||
940 | * cases. | ||
941 | */ | ||
942 | int snd_usb_endpoint_activate(struct snd_usb_endpoint *ep) | ||
943 | { | ||
944 | if (ep->use_count != 0) | ||
945 | return 0; | ||
946 | |||
947 | if (!ep->chip->shutdown && | ||
948 | !test_and_set_bit(EP_FLAG_ACTIVATED, &ep->flags)) { | ||
949 | int ret; | ||
950 | |||
951 | ret = usb_set_interface(ep->chip->dev, ep->iface, ep->alt_idx); | ||
952 | if (ret < 0) { | ||
953 | snd_printk(KERN_ERR "%s() usb_set_interface() failed, ret = %d\n", | ||
954 | __func__, ret); | ||
955 | clear_bit(EP_FLAG_ACTIVATED, &ep->flags); | ||
956 | return ret; | ||
957 | } | ||
958 | |||
959 | return 0; | ||
960 | } | ||
961 | |||
962 | return -EBUSY; | ||
963 | } | ||
964 | |||
965 | /** | ||
966 | * snd_usb_endpoint_deactivate: deactivate an snd_usb_endpoint | 914 | * snd_usb_endpoint_deactivate: deactivate an snd_usb_endpoint |
967 | * | 915 | * |
968 | * @ep: the endpoint to deactivate | 916 | * @ep: the endpoint to deactivate |
@@ -980,24 +928,15 @@ int snd_usb_endpoint_deactivate(struct snd_usb_endpoint *ep) | |||
980 | if (!ep) | 928 | if (!ep) |
981 | return -EINVAL; | 929 | return -EINVAL; |
982 | 930 | ||
931 | deactivate_urbs(ep, 1, 1); | ||
932 | wait_clear_urbs(ep); | ||
933 | |||
983 | if (ep->use_count != 0) | 934 | if (ep->use_count != 0) |
984 | return 0; | 935 | return 0; |
985 | 936 | ||
986 | if (!ep->chip->shutdown && | 937 | clear_bit(EP_FLAG_ACTIVATED, &ep->flags); |
987 | test_and_clear_bit(EP_FLAG_ACTIVATED, &ep->flags)) { | ||
988 | int ret; | ||
989 | |||
990 | ret = usb_set_interface(ep->chip->dev, ep->iface, 0); | ||
991 | if (ret < 0) { | ||
992 | snd_printk(KERN_ERR "%s(): usb_set_interface() failed, ret = %d\n", | ||
993 | __func__, ret); | ||
994 | return ret; | ||
995 | } | ||
996 | 938 | ||
997 | return 0; | 939 | return 0; |
998 | } | ||
999 | |||
1000 | return -EBUSY; | ||
1001 | } | 940 | } |
1002 | 941 | ||
1003 | /** | 942 | /** |
diff --git a/sound/usb/mixer_maps.c b/sound/usb/mixer_maps.c index 41daaa24c25..e71fe55cebe 100644 --- a/sound/usb/mixer_maps.c +++ b/sound/usb/mixer_maps.c | |||
@@ -341,6 +341,14 @@ static struct usbmix_ctl_map usbmix_ctl_maps[] = { | |||
341 | .map = audigy2nx_map, | 341 | .map = audigy2nx_map, |
342 | .selector_map = audigy2nx_selectors, | 342 | .selector_map = audigy2nx_selectors, |
343 | }, | 343 | }, |
344 | { /* Logitech, Inc. QuickCam Pro for Notebooks */ | ||
345 | .id = USB_ID(0x046d, 0x0991), | ||
346 | .ignore_ctl_error = 1, | ||
347 | }, | ||
348 | { /* Logitech, Inc. QuickCam E 3500 */ | ||
349 | .id = USB_ID(0x046d, 0x09a4), | ||
350 | .ignore_ctl_error = 1, | ||
351 | }, | ||
344 | { | 352 | { |
345 | /* Hercules DJ Console (Windows Edition) */ | 353 | /* Hercules DJ Console (Windows Edition) */ |
346 | .id = USB_ID(0x06f8, 0xb000), | 354 | .id = USB_ID(0x06f8, 0xb000), |
diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c index 41f4b691192..690000db0ec 100644 --- a/sound/usb/mixer_quirks.c +++ b/sound/usb/mixer_quirks.c | |||
@@ -42,6 +42,13 @@ | |||
42 | 42 | ||
43 | extern struct snd_kcontrol_new *snd_usb_feature_unit_ctl; | 43 | extern struct snd_kcontrol_new *snd_usb_feature_unit_ctl; |
44 | 44 | ||
45 | struct std_mono_table { | ||
46 | unsigned int unitid, control, cmask; | ||
47 | int val_type; | ||
48 | const char *name; | ||
49 | snd_kcontrol_tlv_rw_t *tlv_callback; | ||
50 | }; | ||
51 | |||
45 | /* private_free callback */ | 52 | /* private_free callback */ |
46 | static void usb_mixer_elem_free(struct snd_kcontrol *kctl) | 53 | static void usb_mixer_elem_free(struct snd_kcontrol *kctl) |
47 | { | 54 | { |
@@ -114,6 +121,25 @@ static int snd_create_std_mono_ctl(struct usb_mixer_interface *mixer, | |||
114 | } | 121 | } |
115 | 122 | ||
116 | /* | 123 | /* |
124 | * Create a set of standard UAC controls from a table | ||
125 | */ | ||
126 | static int snd_create_std_mono_table(struct usb_mixer_interface *mixer, | ||
127 | struct std_mono_table *t) | ||
128 | { | ||
129 | int err; | ||
130 | |||
131 | while (t->name != NULL) { | ||
132 | err = snd_create_std_mono_ctl(mixer, t->unitid, t->control, | ||
133 | t->cmask, t->val_type, t->name, t->tlv_callback); | ||
134 | if (err < 0) | ||
135 | return err; | ||
136 | t++; | ||
137 | } | ||
138 | |||
139 | return 0; | ||
140 | } | ||
141 | |||
142 | /* | ||
117 | * Sound Blaster remote control configuration | 143 | * Sound Blaster remote control configuration |
118 | * | 144 | * |
119 | * format of remote control data: | 145 | * format of remote control data: |
@@ -916,61 +942,6 @@ static int snd_ftu_create_mixer(struct usb_mixer_interface *mixer) | |||
916 | return 0; | 942 | return 0; |
917 | } | 943 | } |
918 | 944 | ||
919 | |||
920 | /* | ||
921 | * Create mixer for Electrix Ebox-44 | ||
922 | * | ||
923 | * The mixer units from this device are corrupt, and even where they | ||
924 | * are valid they presents mono controls as L and R channels of | ||
925 | * stereo. So we create a good mixer in code. | ||
926 | */ | ||
927 | |||
928 | static int snd_ebox44_create_mixer(struct usb_mixer_interface *mixer) | ||
929 | { | ||
930 | int err; | ||
931 | |||
932 | err = snd_create_std_mono_ctl(mixer, 4, 1, 0x0, USB_MIXER_INV_BOOLEAN, | ||
933 | "Headphone Playback Switch", NULL); | ||
934 | if (err < 0) | ||
935 | return err; | ||
936 | err = snd_create_std_mono_ctl(mixer, 4, 2, 0x1, USB_MIXER_S16, | ||
937 | "Headphone A Mix Playback Volume", NULL); | ||
938 | if (err < 0) | ||
939 | return err; | ||
940 | err = snd_create_std_mono_ctl(mixer, 4, 2, 0x2, USB_MIXER_S16, | ||
941 | "Headphone B Mix Playback Volume", NULL); | ||
942 | if (err < 0) | ||
943 | return err; | ||
944 | |||
945 | err = snd_create_std_mono_ctl(mixer, 7, 1, 0x0, USB_MIXER_INV_BOOLEAN, | ||
946 | "Output Playback Switch", NULL); | ||
947 | if (err < 0) | ||
948 | return err; | ||
949 | err = snd_create_std_mono_ctl(mixer, 7, 2, 0x1, USB_MIXER_S16, | ||
950 | "Output A Playback Volume", NULL); | ||
951 | if (err < 0) | ||
952 | return err; | ||
953 | err = snd_create_std_mono_ctl(mixer, 7, 2, 0x2, USB_MIXER_S16, | ||
954 | "Output B Playback Volume", NULL); | ||
955 | if (err < 0) | ||
956 | return err; | ||
957 | |||
958 | err = snd_create_std_mono_ctl(mixer, 10, 1, 0x0, USB_MIXER_INV_BOOLEAN, | ||
959 | "Input Capture Switch", NULL); | ||
960 | if (err < 0) | ||
961 | return err; | ||
962 | err = snd_create_std_mono_ctl(mixer, 10, 2, 0x1, USB_MIXER_S16, | ||
963 | "Input A Capture Volume", NULL); | ||
964 | if (err < 0) | ||
965 | return err; | ||
966 | err = snd_create_std_mono_ctl(mixer, 10, 2, 0x2, USB_MIXER_S16, | ||
967 | "Input B Capture Volume", NULL); | ||
968 | if (err < 0) | ||
969 | return err; | ||
970 | |||
971 | return 0; | ||
972 | } | ||
973 | |||
974 | void snd_emuusb_set_samplerate(struct snd_usb_audio *chip, | 945 | void snd_emuusb_set_samplerate(struct snd_usb_audio *chip, |
975 | unsigned char samplerate_id) | 946 | unsigned char samplerate_id) |
976 | { | 947 | { |
@@ -990,6 +961,81 @@ void snd_emuusb_set_samplerate(struct snd_usb_audio *chip, | |||
990 | } | 961 | } |
991 | } | 962 | } |
992 | 963 | ||
964 | /* | ||
965 | * The mixer units for Ebox-44 are corrupt, and even where they | ||
966 | * are valid they presents mono controls as L and R channels of | ||
967 | * stereo. So we provide a good mixer here. | ||
968 | */ | ||
969 | struct std_mono_table ebox44_table[] = { | ||
970 | { | ||
971 | .unitid = 4, | ||
972 | .control = 1, | ||
973 | .cmask = 0x0, | ||
974 | .val_type = USB_MIXER_INV_BOOLEAN, | ||
975 | .name = "Headphone Playback Switch" | ||
976 | }, | ||
977 | { | ||
978 | .unitid = 4, | ||
979 | .control = 2, | ||
980 | .cmask = 0x1, | ||
981 | .val_type = USB_MIXER_S16, | ||
982 | .name = "Headphone A Mix Playback Volume" | ||
983 | }, | ||
984 | { | ||
985 | .unitid = 4, | ||
986 | .control = 2, | ||
987 | .cmask = 0x2, | ||
988 | .val_type = USB_MIXER_S16, | ||
989 | .name = "Headphone B Mix Playback Volume" | ||
990 | }, | ||
991 | |||
992 | { | ||
993 | .unitid = 7, | ||
994 | .control = 1, | ||
995 | .cmask = 0x0, | ||
996 | .val_type = USB_MIXER_INV_BOOLEAN, | ||
997 | .name = "Output Playback Switch" | ||
998 | }, | ||
999 | { | ||
1000 | .unitid = 7, | ||
1001 | .control = 2, | ||
1002 | .cmask = 0x1, | ||
1003 | .val_type = USB_MIXER_S16, | ||
1004 | .name = "Output A Playback Volume" | ||
1005 | }, | ||
1006 | { | ||
1007 | .unitid = 7, | ||
1008 | .control = 2, | ||
1009 | .cmask = 0x2, | ||
1010 | .val_type = USB_MIXER_S16, | ||
1011 | .name = "Output B Playback Volume" | ||
1012 | }, | ||
1013 | |||
1014 | { | ||
1015 | .unitid = 10, | ||
1016 | .control = 1, | ||
1017 | .cmask = 0x0, | ||
1018 | .val_type = USB_MIXER_INV_BOOLEAN, | ||
1019 | .name = "Input Capture Switch" | ||
1020 | }, | ||
1021 | { | ||
1022 | .unitid = 10, | ||
1023 | .control = 2, | ||
1024 | .cmask = 0x1, | ||
1025 | .val_type = USB_MIXER_S16, | ||
1026 | .name = "Input A Capture Volume" | ||
1027 | }, | ||
1028 | { | ||
1029 | .unitid = 10, | ||
1030 | .control = 2, | ||
1031 | .cmask = 0x2, | ||
1032 | .val_type = USB_MIXER_S16, | ||
1033 | .name = "Input B Capture Volume" | ||
1034 | }, | ||
1035 | |||
1036 | {} | ||
1037 | }; | ||
1038 | |||
993 | int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) | 1039 | int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) |
994 | { | 1040 | { |
995 | int err = 0; | 1041 | int err = 0; |
@@ -1035,7 +1081,8 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) | |||
1035 | break; | 1081 | break; |
1036 | 1082 | ||
1037 | case USB_ID(0x200c, 0x1018): /* Electrix Ebox-44 */ | 1083 | case USB_ID(0x200c, 0x1018): /* Electrix Ebox-44 */ |
1038 | err = snd_ebox44_create_mixer(mixer); | 1084 | /* detection is disabled in mixer_maps.c */ |
1085 | err = snd_create_std_mono_table(mixer, ebox44_table); | ||
1039 | break; | 1086 | break; |
1040 | } | 1087 | } |
1041 | 1088 | ||
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index 54607f8c4f6..a1298f37942 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c | |||
@@ -261,19 +261,6 @@ static void stop_endpoints(struct snd_usb_substream *subs, | |||
261 | force, can_sleep, wait); | 261 | force, can_sleep, wait); |
262 | } | 262 | } |
263 | 263 | ||
264 | static int activate_endpoints(struct snd_usb_substream *subs) | ||
265 | { | ||
266 | if (subs->sync_endpoint) { | ||
267 | int ret; | ||
268 | |||
269 | ret = snd_usb_endpoint_activate(subs->sync_endpoint); | ||
270 | if (ret < 0) | ||
271 | return ret; | ||
272 | } | ||
273 | |||
274 | return snd_usb_endpoint_activate(subs->data_endpoint); | ||
275 | } | ||
276 | |||
277 | static int deactivate_endpoints(struct snd_usb_substream *subs) | 264 | static int deactivate_endpoints(struct snd_usb_substream *subs) |
278 | { | 265 | { |
279 | int reta, retb; | 266 | int reta, retb; |
@@ -314,6 +301,33 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt) | |||
314 | if (fmt == subs->cur_audiofmt) | 301 | if (fmt == subs->cur_audiofmt) |
315 | return 0; | 302 | return 0; |
316 | 303 | ||
304 | /* close the old interface */ | ||
305 | if (subs->interface >= 0 && subs->interface != fmt->iface) { | ||
306 | err = usb_set_interface(subs->dev, subs->interface, 0); | ||
307 | if (err < 0) { | ||
308 | snd_printk(KERN_ERR "%d:%d:%d: return to setting 0 failed (%d)\n", | ||
309 | dev->devnum, fmt->iface, fmt->altsetting, err); | ||
310 | return -EIO; | ||
311 | } | ||
312 | subs->interface = -1; | ||
313 | subs->altset_idx = 0; | ||
314 | } | ||
315 | |||
316 | /* set interface */ | ||
317 | if (subs->interface != fmt->iface || | ||
318 | subs->altset_idx != fmt->altset_idx) { | ||
319 | err = usb_set_interface(dev, fmt->iface, fmt->altsetting); | ||
320 | if (err < 0) { | ||
321 | snd_printk(KERN_ERR "%d:%d:%d: usb_set_interface failed (%d)\n", | ||
322 | dev->devnum, fmt->iface, fmt->altsetting, err); | ||
323 | return -EIO; | ||
324 | } | ||
325 | snd_printdd(KERN_INFO "setting usb interface %d:%d\n", | ||
326 | fmt->iface, fmt->altsetting); | ||
327 | subs->interface = fmt->iface; | ||
328 | subs->altset_idx = fmt->altset_idx; | ||
329 | } | ||
330 | |||
317 | subs->data_endpoint = snd_usb_add_endpoint(subs->stream->chip, | 331 | subs->data_endpoint = snd_usb_add_endpoint(subs->stream->chip, |
318 | alts, fmt->endpoint, subs->direction, | 332 | alts, fmt->endpoint, subs->direction, |
319 | SND_USB_ENDPOINT_TYPE_DATA); | 333 | SND_USB_ENDPOINT_TYPE_DATA); |
@@ -387,7 +401,7 @@ add_sync_ep: | |||
387 | subs->data_endpoint->sync_master = subs->sync_endpoint; | 401 | subs->data_endpoint->sync_master = subs->sync_endpoint; |
388 | } | 402 | } |
389 | 403 | ||
390 | if ((err = snd_usb_init_pitch(subs->stream->chip, subs->interface, alts, fmt)) < 0) | 404 | if ((err = snd_usb_init_pitch(subs->stream->chip, fmt->iface, alts, fmt)) < 0) |
391 | return err; | 405 | return err; |
392 | 406 | ||
393 | subs->cur_audiofmt = fmt; | 407 | subs->cur_audiofmt = fmt; |
@@ -450,7 +464,7 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream, | |||
450 | struct usb_interface *iface; | 464 | struct usb_interface *iface; |
451 | iface = usb_ifnum_to_if(subs->dev, fmt->iface); | 465 | iface = usb_ifnum_to_if(subs->dev, fmt->iface); |
452 | alts = &iface->altsetting[fmt->altset_idx]; | 466 | alts = &iface->altsetting[fmt->altset_idx]; |
453 | ret = snd_usb_init_sample_rate(subs->stream->chip, subs->interface, alts, fmt, rate); | 467 | ret = snd_usb_init_sample_rate(subs->stream->chip, fmt->iface, alts, fmt, rate); |
454 | if (ret < 0) | 468 | if (ret < 0) |
455 | return ret; | 469 | return ret; |
456 | subs->cur_rate = rate; | 470 | subs->cur_rate = rate; |
@@ -460,12 +474,6 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream, | |||
460 | mutex_lock(&subs->stream->chip->shutdown_mutex); | 474 | mutex_lock(&subs->stream->chip->shutdown_mutex); |
461 | /* format changed */ | 475 | /* format changed */ |
462 | stop_endpoints(subs, 0, 0, 0); | 476 | stop_endpoints(subs, 0, 0, 0); |
463 | deactivate_endpoints(subs); | ||
464 | |||
465 | ret = activate_endpoints(subs); | ||
466 | if (ret < 0) | ||
467 | goto unlock; | ||
468 | |||
469 | ret = snd_usb_endpoint_set_params(subs->data_endpoint, hw_params, fmt, | 477 | ret = snd_usb_endpoint_set_params(subs->data_endpoint, hw_params, fmt, |
470 | subs->sync_endpoint); | 478 | subs->sync_endpoint); |
471 | if (ret < 0) | 479 | if (ret < 0) |
@@ -500,6 +508,7 @@ static int snd_usb_hw_free(struct snd_pcm_substream *substream) | |||
500 | subs->period_bytes = 0; | 508 | subs->period_bytes = 0; |
501 | mutex_lock(&subs->stream->chip->shutdown_mutex); | 509 | mutex_lock(&subs->stream->chip->shutdown_mutex); |
502 | stop_endpoints(subs, 0, 1, 1); | 510 | stop_endpoints(subs, 0, 1, 1); |
511 | deactivate_endpoints(subs); | ||
503 | mutex_unlock(&subs->stream->chip->shutdown_mutex); | 512 | mutex_unlock(&subs->stream->chip->shutdown_mutex); |
504 | return snd_pcm_lib_free_vmalloc_buffer(substream); | 513 | return snd_pcm_lib_free_vmalloc_buffer(substream); |
505 | } | 514 | } |
@@ -938,16 +947,20 @@ static int snd_usb_pcm_open(struct snd_pcm_substream *substream, int direction) | |||
938 | 947 | ||
939 | static int snd_usb_pcm_close(struct snd_pcm_substream *substream, int direction) | 948 | static int snd_usb_pcm_close(struct snd_pcm_substream *substream, int direction) |
940 | { | 949 | { |
941 | int ret; | ||
942 | struct snd_usb_stream *as = snd_pcm_substream_chip(substream); | 950 | struct snd_usb_stream *as = snd_pcm_substream_chip(substream); |
943 | struct snd_usb_substream *subs = &as->substream[direction]; | 951 | struct snd_usb_substream *subs = &as->substream[direction]; |
944 | 952 | ||
945 | stop_endpoints(subs, 0, 0, 0); | 953 | stop_endpoints(subs, 0, 0, 0); |
946 | ret = deactivate_endpoints(subs); | 954 | |
955 | if (!as->chip->shutdown && subs->interface >= 0) { | ||
956 | usb_set_interface(subs->dev, subs->interface, 0); | ||
957 | subs->interface = -1; | ||
958 | } | ||
959 | |||
947 | subs->pcm_substream = NULL; | 960 | subs->pcm_substream = NULL; |
948 | snd_usb_autosuspend(subs->stream->chip); | 961 | snd_usb_autosuspend(subs->stream->chip); |
949 | 962 | ||
950 | return ret; | 963 | return 0; |
951 | } | 964 | } |
952 | 965 | ||
953 | /* Since a URB can handle only a single linear buffer, we must use double | 966 | /* Since a URB can handle only a single linear buffer, we must use double |
diff --git a/sound/usb/quirks-table.h b/sound/usb/quirks-table.h index d89ab4c7d44..79780fa57a4 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h | |||
@@ -1831,6 +1831,36 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
1831 | } | 1831 | } |
1832 | } | 1832 | } |
1833 | }, | 1833 | }, |
1834 | { | ||
1835 | USB_DEVICE(0x0582, 0x014d), | ||
1836 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | ||
1837 | /* .vendor_name = "BOSS", */ | ||
1838 | /* .product_name = "GT-100", */ | ||
1839 | .ifnum = QUIRK_ANY_INTERFACE, | ||
1840 | .type = QUIRK_COMPOSITE, | ||
1841 | .data = (const struct snd_usb_audio_quirk[]) { | ||
1842 | { | ||
1843 | .ifnum = 1, | ||
1844 | .type = QUIRK_AUDIO_STANDARD_INTERFACE | ||
1845 | }, | ||
1846 | { | ||
1847 | .ifnum = 2, | ||
1848 | .type = QUIRK_AUDIO_STANDARD_INTERFACE | ||
1849 | }, | ||
1850 | { | ||
1851 | .ifnum = 3, | ||
1852 | .type = QUIRK_MIDI_FIXED_ENDPOINT, | ||
1853 | .data = & (const struct snd_usb_midi_endpoint_info) { | ||
1854 | .out_cables = 0x0001, | ||
1855 | .in_cables = 0x0001 | ||
1856 | } | ||
1857 | }, | ||
1858 | { | ||
1859 | .ifnum = -1 | ||
1860 | } | ||
1861 | } | ||
1862 | } | ||
1863 | }, | ||
1834 | 1864 | ||
1835 | /* Guillemot devices */ | 1865 | /* Guillemot devices */ |
1836 | { | 1866 | { |