aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/hda_codec.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/pci/hda/hda_codec.c')
-rw-r--r--sound/pci/hda/hda_codec.c271
1 files changed, 216 insertions, 55 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 14829210ef0b..644e3f14f8ca 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -1216,6 +1216,7 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
1216 struct hda_codec *c; 1216 struct hda_codec *c;
1217 struct hda_cvt_setup *p; 1217 struct hda_cvt_setup *p;
1218 unsigned int oldval, newval; 1218 unsigned int oldval, newval;
1219 int type;
1219 int i; 1220 int i;
1220 1221
1221 if (!nid) 1222 if (!nid)
@@ -1254,10 +1255,12 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
1254 p->dirty = 0; 1255 p->dirty = 0;
1255 1256
1256 /* make other inactive cvts with the same stream-tag dirty */ 1257 /* make other inactive cvts with the same stream-tag dirty */
1258 type = get_wcaps_type(get_wcaps(codec, nid));
1257 list_for_each_entry(c, &codec->bus->codec_list, list) { 1259 list_for_each_entry(c, &codec->bus->codec_list, list) {
1258 for (i = 0; i < c->cvt_setups.used; i++) { 1260 for (i = 0; i < c->cvt_setups.used; i++) {
1259 p = snd_array_elem(&c->cvt_setups, i); 1261 p = snd_array_elem(&c->cvt_setups, i);
1260 if (!p->active && p->stream_tag == stream_tag) 1262 if (!p->active && p->stream_tag == stream_tag &&
1263 get_wcaps_type(get_wcaps(codec, p->nid)) == type)
1261 p->dirty = 1; 1264 p->dirty = 1;
1262 } 1265 }
1263 } 1266 }
@@ -1281,6 +1284,9 @@ void __snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid,
1281 if (!nid) 1284 if (!nid)
1282 return; 1285 return;
1283 1286
1287 if (codec->no_sticky_stream)
1288 do_now = 1;
1289
1284 snd_printdd("hda_codec_cleanup_stream: NID=0x%x\n", nid); 1290 snd_printdd("hda_codec_cleanup_stream: NID=0x%x\n", nid);
1285 p = get_hda_cvt_setup(codec, nid); 1291 p = get_hda_cvt_setup(codec, nid);
1286 if (p) { 1292 if (p) {
@@ -1831,6 +1837,7 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1831 hda_nid_t nid = get_amp_nid(kcontrol); 1837 hda_nid_t nid = get_amp_nid(kcontrol);
1832 int dir = get_amp_direction(kcontrol); 1838 int dir = get_amp_direction(kcontrol);
1833 unsigned int ofs = get_amp_offset(kcontrol); 1839 unsigned int ofs = get_amp_offset(kcontrol);
1840 bool min_mute = get_amp_min_mute(kcontrol);
1834 u32 caps, val1, val2; 1841 u32 caps, val1, val2;
1835 1842
1836 if (size < 4 * sizeof(unsigned int)) 1843 if (size < 4 * sizeof(unsigned int))
@@ -1841,6 +1848,8 @@ int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1841 val1 = -((caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT); 1848 val1 = -((caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT);
1842 val1 += ofs; 1849 val1 += ofs;
1843 val1 = ((int)val1) * ((int)val2); 1850 val1 = ((int)val1) * ((int)val2);
1851 if (min_mute)
1852 val2 |= TLV_DB_SCALE_MUTE;
1844 if (put_user(SNDRV_CTL_TLVT_DB_SCALE, _tlv)) 1853 if (put_user(SNDRV_CTL_TLVT_DB_SCALE, _tlv))
1845 return -EFAULT; 1854 return -EFAULT;
1846 if (put_user(2 * sizeof(unsigned int), _tlv + 1)) 1855 if (put_user(2 * sizeof(unsigned int), _tlv + 1))
@@ -2228,10 +2237,7 @@ int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol,
2228 change |= snd_hda_codec_amp_update(codec, nid, 1, dir, idx, 2237 change |= snd_hda_codec_amp_update(codec, nid, 1, dir, idx,
2229 HDA_AMP_MUTE, 2238 HDA_AMP_MUTE,
2230 *valp ? 0 : HDA_AMP_MUTE); 2239 *valp ? 0 : HDA_AMP_MUTE);
2231#ifdef CONFIG_SND_HDA_POWER_SAVE 2240 hda_call_check_power_status(codec, nid);
2232 if (codec->patch_ops.check_power_status)
2233 codec->patch_ops.check_power_status(codec, nid);
2234#endif
2235 snd_hda_power_down(codec); 2241 snd_hda_power_down(codec);
2236 return change; 2242 return change;
2237} 2243}
@@ -4372,6 +4378,34 @@ static void sort_pins_by_sequence(hda_nid_t *pins, short *sequences,
4372} 4378}
4373 4379
4374 4380
4381/* add the found input-pin to the cfg->inputs[] table */
4382static void add_auto_cfg_input_pin(struct auto_pin_cfg *cfg, hda_nid_t nid,
4383 int type)
4384{
4385 if (cfg->num_inputs < AUTO_CFG_MAX_INS) {
4386 cfg->inputs[cfg->num_inputs].pin = nid;
4387 cfg->inputs[cfg->num_inputs].type = type;
4388 cfg->num_inputs++;
4389 }
4390}
4391
4392/* sort inputs in the order of AUTO_PIN_* type */
4393static void sort_autocfg_input_pins(struct auto_pin_cfg *cfg)
4394{
4395 int i, j;
4396
4397 for (i = 0; i < cfg->num_inputs; i++) {
4398 for (j = i + 1; j < cfg->num_inputs; j++) {
4399 if (cfg->inputs[i].type > cfg->inputs[j].type) {
4400 struct auto_pin_cfg_item tmp;
4401 tmp = cfg->inputs[i];
4402 cfg->inputs[i] = cfg->inputs[j];
4403 cfg->inputs[j] = tmp;
4404 }
4405 }
4406 }
4407}
4408
4375/* 4409/*
4376 * Parse all pin widgets and store the useful pin nids to cfg 4410 * Parse all pin widgets and store the useful pin nids to cfg
4377 * 4411 *
@@ -4385,7 +4419,7 @@ static void sort_pins_by_sequence(hda_nid_t *pins, short *sequences,
4385 * output, i.e. to line_out_pins[0]. So, line_outs is always positive 4419 * output, i.e. to line_out_pins[0]. So, line_outs is always positive
4386 * if any analog output exists. 4420 * if any analog output exists.
4387 * 4421 *
4388 * The analog input pins are assigned to input_pins array. 4422 * The analog input pins are assigned to inputs array.
4389 * The digital input/output pins are assigned to dig_in_pin and dig_out_pin, 4423 * The digital input/output pins are assigned to dig_in_pin and dig_out_pin,
4390 * respectively. 4424 * respectively.
4391 */ 4425 */
@@ -4398,6 +4432,7 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
4398 short sequences_line_out[ARRAY_SIZE(cfg->line_out_pins)]; 4432 short sequences_line_out[ARRAY_SIZE(cfg->line_out_pins)];
4399 short sequences_speaker[ARRAY_SIZE(cfg->speaker_pins)]; 4433 short sequences_speaker[ARRAY_SIZE(cfg->speaker_pins)];
4400 short sequences_hp[ARRAY_SIZE(cfg->hp_pins)]; 4434 short sequences_hp[ARRAY_SIZE(cfg->hp_pins)];
4435 int i;
4401 4436
4402 memset(cfg, 0, sizeof(*cfg)); 4437 memset(cfg, 0, sizeof(*cfg));
4403 4438
@@ -4468,33 +4503,17 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
4468 sequences_hp[cfg->hp_outs] = (assoc << 4) | seq; 4503 sequences_hp[cfg->hp_outs] = (assoc << 4) | seq;
4469 cfg->hp_outs++; 4504 cfg->hp_outs++;
4470 break; 4505 break;
4471 case AC_JACK_MIC_IN: { 4506 case AC_JACK_MIC_IN:
4472 int preferred, alt; 4507 add_auto_cfg_input_pin(cfg, nid, AUTO_PIN_MIC);
4473 if (loc == AC_JACK_LOC_FRONT ||
4474 (loc & 0x30) == AC_JACK_LOC_INTERNAL) {
4475 preferred = AUTO_PIN_FRONT_MIC;
4476 alt = AUTO_PIN_MIC;
4477 } else {
4478 preferred = AUTO_PIN_MIC;
4479 alt = AUTO_PIN_FRONT_MIC;
4480 }
4481 if (!cfg->input_pins[preferred])
4482 cfg->input_pins[preferred] = nid;
4483 else if (!cfg->input_pins[alt])
4484 cfg->input_pins[alt] = nid;
4485 break; 4508 break;
4486 }
4487 case AC_JACK_LINE_IN: 4509 case AC_JACK_LINE_IN:
4488 if (loc == AC_JACK_LOC_FRONT) 4510 add_auto_cfg_input_pin(cfg, nid, AUTO_PIN_LINE_IN);
4489 cfg->input_pins[AUTO_PIN_FRONT_LINE] = nid;
4490 else
4491 cfg->input_pins[AUTO_PIN_LINE] = nid;
4492 break; 4511 break;
4493 case AC_JACK_CD: 4512 case AC_JACK_CD:
4494 cfg->input_pins[AUTO_PIN_CD] = nid; 4513 add_auto_cfg_input_pin(cfg, nid, AUTO_PIN_CD);
4495 break; 4514 break;
4496 case AC_JACK_AUX: 4515 case AC_JACK_AUX:
4497 cfg->input_pins[AUTO_PIN_AUX] = nid; 4516 add_auto_cfg_input_pin(cfg, nid, AUTO_PIN_AUX);
4498 break; 4517 break;
4499 case AC_JACK_SPDIF_OUT: 4518 case AC_JACK_SPDIF_OUT:
4500 case AC_JACK_DIG_OTHER_OUT: 4519 case AC_JACK_DIG_OTHER_OUT:
@@ -4539,6 +4558,8 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
4539 memmove(sequences_hp + i, sequences_hp + i + 1, 4558 memmove(sequences_hp + i, sequences_hp + i + 1,
4540 sizeof(sequences_hp[0]) * (cfg->hp_outs - i)); 4559 sizeof(sequences_hp[0]) * (cfg->hp_outs - i));
4541 } 4560 }
4561 memset(cfg->hp_pins + cfg->hp_outs, 0,
4562 sizeof(hda_nid_t) * (AUTO_CFG_MAX_OUTS - cfg->hp_outs));
4542 } 4563 }
4543 4564
4544 /* sort by sequence */ 4565 /* sort by sequence */
@@ -4549,21 +4570,6 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
4549 sort_pins_by_sequence(cfg->hp_pins, sequences_hp, 4570 sort_pins_by_sequence(cfg->hp_pins, sequences_hp,
4550 cfg->hp_outs); 4571 cfg->hp_outs);
4551 4572
4552 /* if we have only one mic, make it AUTO_PIN_MIC */
4553 if (!cfg->input_pins[AUTO_PIN_MIC] &&
4554 cfg->input_pins[AUTO_PIN_FRONT_MIC]) {
4555 cfg->input_pins[AUTO_PIN_MIC] =
4556 cfg->input_pins[AUTO_PIN_FRONT_MIC];
4557 cfg->input_pins[AUTO_PIN_FRONT_MIC] = 0;
4558 }
4559 /* ditto for line-in */
4560 if (!cfg->input_pins[AUTO_PIN_LINE] &&
4561 cfg->input_pins[AUTO_PIN_FRONT_LINE]) {
4562 cfg->input_pins[AUTO_PIN_LINE] =
4563 cfg->input_pins[AUTO_PIN_FRONT_LINE];
4564 cfg->input_pins[AUTO_PIN_FRONT_LINE] = 0;
4565 }
4566
4567 /* 4573 /*
4568 * FIX-UP: if no line-outs are detected, try to use speaker or HP pin 4574 * FIX-UP: if no line-outs are detected, try to use speaker or HP pin
4569 * as a primary output 4575 * as a primary output
@@ -4602,6 +4608,8 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
4602 break; 4608 break;
4603 } 4609 }
4604 4610
4611 sort_autocfg_input_pins(cfg);
4612
4605 /* 4613 /*
4606 * debug prints of the parsed results 4614 * debug prints of the parsed results
4607 */ 4615 */
@@ -4621,14 +4629,13 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
4621 if (cfg->dig_outs) 4629 if (cfg->dig_outs)
4622 snd_printd(" dig-out=0x%x/0x%x\n", 4630 snd_printd(" dig-out=0x%x/0x%x\n",
4623 cfg->dig_out_pins[0], cfg->dig_out_pins[1]); 4631 cfg->dig_out_pins[0], cfg->dig_out_pins[1]);
4624 snd_printd(" inputs: mic=0x%x, fmic=0x%x, line=0x%x, fline=0x%x," 4632 snd_printd(" inputs:");
4625 " cd=0x%x, aux=0x%x\n", 4633 for (i = 0; i < cfg->num_inputs; i++) {
4626 cfg->input_pins[AUTO_PIN_MIC], 4634 snd_printdd(" %s=0x%x",
4627 cfg->input_pins[AUTO_PIN_FRONT_MIC], 4635 hda_get_autocfg_input_label(codec, cfg, i),
4628 cfg->input_pins[AUTO_PIN_LINE], 4636 cfg->inputs[i].pin);
4629 cfg->input_pins[AUTO_PIN_FRONT_LINE], 4637 }
4630 cfg->input_pins[AUTO_PIN_CD], 4638 snd_printd("\n");
4631 cfg->input_pins[AUTO_PIN_AUX]);
4632 if (cfg->dig_in_pin) 4639 if (cfg->dig_in_pin)
4633 snd_printd(" dig-in=0x%x\n", cfg->dig_in_pin); 4640 snd_printd(" dig-in=0x%x\n", cfg->dig_in_pin);
4634 4641
@@ -4636,11 +4643,165 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec,
4636} 4643}
4637EXPORT_SYMBOL_HDA(snd_hda_parse_pin_def_config); 4644EXPORT_SYMBOL_HDA(snd_hda_parse_pin_def_config);
4638 4645
4639/* labels for input pins */ 4646int snd_hda_get_input_pin_attr(unsigned int def_conf)
4640const char *auto_pin_cfg_labels[AUTO_PIN_LAST] = { 4647{
4641 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux" 4648 unsigned int loc = get_defcfg_location(def_conf);
4642}; 4649 unsigned int conn = get_defcfg_connect(def_conf);
4643EXPORT_SYMBOL_HDA(auto_pin_cfg_labels); 4650 if (conn == AC_JACK_PORT_NONE)
4651 return INPUT_PIN_ATTR_UNUSED;
4652 /* Windows may claim the internal mic to be BOTH, too */
4653 if (conn == AC_JACK_PORT_FIXED || conn == AC_JACK_PORT_BOTH)
4654 return INPUT_PIN_ATTR_INT;
4655 if ((loc & 0x30) == AC_JACK_LOC_INTERNAL)
4656 return INPUT_PIN_ATTR_INT;
4657 if ((loc & 0x30) == AC_JACK_LOC_SEPARATE)
4658 return INPUT_PIN_ATTR_DOCK;
4659 if (loc == AC_JACK_LOC_REAR)
4660 return INPUT_PIN_ATTR_REAR;
4661 if (loc == AC_JACK_LOC_FRONT)
4662 return INPUT_PIN_ATTR_FRONT;
4663 return INPUT_PIN_ATTR_NORMAL;
4664}
4665EXPORT_SYMBOL_HDA(snd_hda_get_input_pin_attr);
4666
4667/**
4668 * hda_get_input_pin_label - Give a label for the given input pin
4669 *
4670 * When check_location is true, the function checks the pin location
4671 * for mic and line-in pins, and set an appropriate prefix like "Front",
4672 * "Rear", "Internal".
4673 */
4674
4675const char *hda_get_input_pin_label(struct hda_codec *codec, hda_nid_t pin,
4676 int check_location)
4677{
4678 unsigned int def_conf;
4679 static const char *mic_names[] = {
4680 "Internal Mic", "Dock Mic", "Mic", "Front Mic", "Rear Mic",
4681 };
4682 int attr;
4683
4684 def_conf = snd_hda_codec_get_pincfg(codec, pin);
4685
4686 switch (get_defcfg_device(def_conf)) {
4687 case AC_JACK_MIC_IN:
4688 if (!check_location)
4689 return "Mic";
4690 attr = snd_hda_get_input_pin_attr(def_conf);
4691 if (!attr)
4692 return "None";
4693 return mic_names[attr - 1];
4694 case AC_JACK_LINE_IN:
4695 if (!check_location)
4696 return "Line";
4697 attr = snd_hda_get_input_pin_attr(def_conf);
4698 if (!attr)
4699 return "None";
4700 if (attr == INPUT_PIN_ATTR_DOCK)
4701 return "Dock Line";
4702 return "Line";
4703 case AC_JACK_AUX:
4704 return "Aux";
4705 case AC_JACK_CD:
4706 return "CD";
4707 case AC_JACK_SPDIF_IN:
4708 return "SPDIF In";
4709 case AC_JACK_DIG_OTHER_IN:
4710 return "Digital In";
4711 default:
4712 return "Misc";
4713 }
4714}
4715EXPORT_SYMBOL_HDA(hda_get_input_pin_label);
4716
4717/* Check whether the location prefix needs to be added to the label.
4718 * If all mic-jacks are in the same location (e.g. rear panel), we don't
4719 * have to put "Front" prefix to each label. In such a case, returns false.
4720 */
4721static int check_mic_location_need(struct hda_codec *codec,
4722 const struct auto_pin_cfg *cfg,
4723 int input)
4724{
4725 unsigned int defc;
4726 int i, attr, attr2;
4727
4728 defc = snd_hda_codec_get_pincfg(codec, cfg->inputs[input].pin);
4729 attr = snd_hda_get_input_pin_attr(defc);
4730 /* for internal or docking mics, we need locations */
4731 if (attr <= INPUT_PIN_ATTR_NORMAL)
4732 return 1;
4733
4734 attr = 0;
4735 for (i = 0; i < cfg->num_inputs; i++) {
4736 defc = snd_hda_codec_get_pincfg(codec, cfg->inputs[i].pin);
4737 attr2 = snd_hda_get_input_pin_attr(defc);
4738 if (attr2 >= INPUT_PIN_ATTR_NORMAL) {
4739 if (attr && attr != attr2)
4740 return 1; /* different locations found */
4741 attr = attr2;
4742 }
4743 }
4744 return 0;
4745}
4746
4747/**
4748 * hda_get_autocfg_input_label - Get a label for the given input
4749 *
4750 * Get a label for the given input pin defined by the autocfg item.
4751 * Unlike hda_get_input_pin_label(), this function checks all inputs
4752 * defined in autocfg and avoids the redundant mic/line prefix as much as
4753 * possible.
4754 */
4755const char *hda_get_autocfg_input_label(struct hda_codec *codec,
4756 const struct auto_pin_cfg *cfg,
4757 int input)
4758{
4759 int type = cfg->inputs[input].type;
4760 int has_multiple_pins = 0;
4761
4762 if ((input > 0 && cfg->inputs[input - 1].type == type) ||
4763 (input < cfg->num_inputs - 1 && cfg->inputs[input + 1].type == type))
4764 has_multiple_pins = 1;
4765 if (has_multiple_pins && type == AUTO_PIN_MIC)
4766 has_multiple_pins &= check_mic_location_need(codec, cfg, input);
4767 return hda_get_input_pin_label(codec, cfg->inputs[input].pin,
4768 has_multiple_pins);
4769}
4770EXPORT_SYMBOL_HDA(hda_get_autocfg_input_label);
4771
4772/**
4773 * snd_hda_add_imux_item - Add an item to input_mux
4774 *
4775 * When the same label is used already in the existing items, the number
4776 * suffix is appended to the label. This label index number is stored
4777 * to type_idx when non-NULL pointer is given.
4778 */
4779int snd_hda_add_imux_item(struct hda_input_mux *imux, const char *label,
4780 int index, int *type_idx)
4781{
4782 int i, label_idx = 0;
4783 if (imux->num_items >= HDA_MAX_NUM_INPUTS) {
4784 snd_printd(KERN_ERR "hda_codec: Too many imux items!\n");
4785 return -EINVAL;
4786 }
4787 for (i = 0; i < imux->num_items; i++) {
4788 if (!strncmp(label, imux->items[i].label, strlen(label)))
4789 label_idx++;
4790 }
4791 if (type_idx)
4792 *type_idx = label_idx;
4793 if (label_idx > 0)
4794 snprintf(imux->items[imux->num_items].label,
4795 sizeof(imux->items[imux->num_items].label),
4796 "%s %d", label, label_idx);
4797 else
4798 strlcpy(imux->items[imux->num_items].label, label,
4799 sizeof(imux->items[imux->num_items].label));
4800 imux->items[imux->num_items].index = index;
4801 imux->num_items++;
4802 return 0;
4803}
4804EXPORT_SYMBOL_HDA(snd_hda_add_imux_item);
4644 4805
4645 4806
4646#ifdef CONFIG_PM 4807#ifdef CONFIG_PM