aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2013-01-07 04:33:57 -0500
committerTakashi Iwai <tiwai@suse.de>2013-01-12 02:43:51 -0500
commitc2c803830a5d9897344cd3ffd82daddd7f9f3864 (patch)
tree07f486ef62415ee420fc424cf1ac8fb5d7dbe28b /sound/pci/hda
parentd4156930b21e9317a560c9e1fc1d544935a9f6f3 (diff)
ALSA: hda - Drop bind-volume workaround
The bind-volume workaround was introduced for simplifying the mixer abstraction in the case where one or more pins of multiple outputs lack of individual volume controls. This was essentially the case like Acer Aspire 5935, which has 5.1 speakers and 5.1 (multi-io) jacks although there are 5 DACs, so some of them must share a DAC. However, the recent code rewrite changed the DAC assignment policy to share with the same channel instead of binding to the front, thus binding the volumes for all channels makes little sense now, rather it's confusing. So in this patch, the ugly workaround is finally dropped and simply create the volume control corresponding to the parsed path position. For dual headphones or 2.1 speakers with a shared volume control, it's anyway bound to the same DAC if needed, so this change shouldn't bring any practical difference. And, as a good bonus, we can cut off the whole code handling the bind volume elements. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda')
-rw-r--r--sound/pci/hda/hda_generic.c114
-rw-r--r--sound/pci/hda/hda_generic.h3
2 files changed, 17 insertions, 100 deletions
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index bebc3f4a47ba..296628b6ffc2 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -39,7 +39,6 @@
39int snd_hda_gen_spec_init(struct hda_gen_spec *spec) 39int snd_hda_gen_spec_init(struct hda_gen_spec *spec)
40{ 40{
41 snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32); 41 snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
42 snd_array_init(&spec->bind_ctls, sizeof(struct hda_bind_ctls *), 8);
43 snd_array_init(&spec->paths, sizeof(struct nid_path), 8); 42 snd_array_init(&spec->paths, sizeof(struct nid_path), 8);
44 mutex_init(&spec->pcm_mutex); 43 mutex_init(&spec->pcm_mutex);
45 return 0; 44 return 0;
@@ -75,39 +74,11 @@ static void free_kctls(struct hda_gen_spec *spec)
75 snd_array_free(&spec->kctls); 74 snd_array_free(&spec->kctls);
76} 75}
77 76
78static struct hda_bind_ctls *new_bind_ctl(struct hda_codec *codec,
79 unsigned int nums,
80 struct hda_ctl_ops *ops)
81{
82 struct hda_gen_spec *spec = codec->spec;
83 struct hda_bind_ctls **ctlp, *ctl;
84 ctlp = snd_array_new(&spec->bind_ctls);
85 if (!ctlp)
86 return NULL;
87 ctl = kzalloc(sizeof(*ctl) + sizeof(long) * (nums + 1), GFP_KERNEL);
88 *ctlp = ctl;
89 if (ctl)
90 ctl->ops = ops;
91 return ctl;
92}
93
94static void free_bind_ctls(struct hda_gen_spec *spec)
95{
96 if (spec->bind_ctls.list) {
97 struct hda_bind_ctls **ctl = spec->bind_ctls.list;
98 int i;
99 for (i = 0; i < spec->bind_ctls.used; i++)
100 kfree(ctl[i]);
101 }
102 snd_array_free(&spec->bind_ctls);
103}
104
105void snd_hda_gen_spec_free(struct hda_gen_spec *spec) 77void snd_hda_gen_spec_free(struct hda_gen_spec *spec)
106{ 78{
107 if (!spec) 79 if (!spec)
108 return; 80 return;
109 free_kctls(spec); 81 free_kctls(spec);
110 free_bind_ctls(spec);
111 snd_array_free(&spec->paths); 82 snd_array_free(&spec->paths);
112} 83}
113EXPORT_SYMBOL_HDA(snd_hda_gen_spec_free); 84EXPORT_SYMBOL_HDA(snd_hda_gen_spec_free);
@@ -1489,8 +1460,7 @@ static int create_multi_out_ctls(struct hda_codec *codec,
1489 return 0; 1460 return 0;
1490} 1461}
1491 1462
1492static int create_extra_out(struct hda_codec *codec, hda_nid_t pin, 1463static int create_extra_out(struct hda_codec *codec, int path_idx,
1493 hda_nid_t dac, int path_idx,
1494 const char *pfx, int cidx) 1464 const char *pfx, int cidx)
1495{ 1465{
1496 struct nid_path *path; 1466 struct nid_path *path;
@@ -1499,12 +1469,9 @@ static int create_extra_out(struct hda_codec *codec, hda_nid_t pin,
1499 path = snd_hda_get_path_from_idx(codec, path_idx); 1469 path = snd_hda_get_path_from_idx(codec, path_idx);
1500 if (!path) 1470 if (!path)
1501 return 0; 1471 return 0;
1502 /* bind volume control will be created in the case of dac = 0 */ 1472 err = add_stereo_vol(codec, pfx, cidx, path);
1503 if (dac) { 1473 if (err < 0)
1504 err = add_stereo_vol(codec, pfx, cidx, path); 1474 return err;
1505 if (err < 0)
1506 return err;
1507 }
1508 err = add_stereo_sw(codec, pfx, cidx, path); 1475 err = add_stereo_sw(codec, pfx, cidx, path);
1509 if (err < 0) 1476 if (err < 0)
1510 return err; 1477 return err;
@@ -1513,69 +1480,26 @@ static int create_extra_out(struct hda_codec *codec, hda_nid_t pin,
1513 1480
1514/* add playback controls for speaker and HP outputs */ 1481/* add playback controls for speaker and HP outputs */
1515static int create_extra_outs(struct hda_codec *codec, int num_pins, 1482static int create_extra_outs(struct hda_codec *codec, int num_pins,
1516 const hda_nid_t *pins, const hda_nid_t *dacs,
1517 const int *paths, const char *pfx) 1483 const int *paths, const char *pfx)
1518{ 1484{
1519 struct hda_gen_spec *spec = codec->spec; 1485 int i;
1520 struct hda_bind_ctls *ctl;
1521 char name[44];
1522 int i, n, err;
1523
1524 if (!num_pins || !pins[0])
1525 return 0;
1526
1527 if (num_pins == 1) {
1528 hda_nid_t dac = *dacs;
1529 if (!dac)
1530 dac = spec->multiout.dac_nids[0];
1531 return create_extra_out(codec, *pins, dac, paths[0], pfx, 0);
1532 }
1533 1486
1534 for (i = 0; i < num_pins; i++) { 1487 for (i = 0; i < num_pins; i++) {
1535 hda_nid_t dac; 1488 const char *name;
1536 if (dacs[num_pins - 1]) 1489 char tmp[44];
1537 dac = dacs[i]; /* with individual volumes */ 1490 int err, idx = 0;
1538 else 1491
1539 dac = 0; 1492 if (num_pins == 2 && i == 1 && !strcmp(pfx, "Speaker"))
1540 if (num_pins == 2 && i == 1 && !strcmp(pfx, "Speaker")) { 1493 name = "Bass Speaker";
1541 err = create_extra_out(codec, pins[i], dac, paths[i], 1494 else if (num_pins >= 3) {
1542 "Bass Speaker", 0); 1495 snprintf(tmp, sizeof(tmp), "%s %s",
1543 } else if (num_pins >= 3) {
1544 snprintf(name, sizeof(name), "%s %s",
1545 pfx, channel_name[i]); 1496 pfx, channel_name[i]);
1546 err = create_extra_out(codec, pins[i], dac, paths[i], 1497 name = tmp;
1547 name, 0);
1548 } else { 1498 } else {
1549 err = create_extra_out(codec, pins[i], dac, paths[i], 1499 name = pfx;
1550 pfx, i); 1500 idx = i;
1551 } 1501 }
1552 if (err < 0) 1502 err = create_extra_out(codec, paths[i], name, idx);
1553 return err;
1554 }
1555 if (dacs[num_pins - 1])
1556 return 0;
1557
1558 /* Let's create a bind-controls for volumes */
1559 ctl = new_bind_ctl(codec, num_pins, &snd_hda_bind_vol);
1560 if (!ctl)
1561 return -ENOMEM;
1562 n = 0;
1563 for (i = 0; i < num_pins; i++) {
1564 hda_nid_t vol;
1565 struct nid_path *path;
1566 if (!pins[i] || !dacs[i])
1567 continue;
1568 path = snd_hda_get_path_from_idx(codec, paths[i]);
1569 if (!path)
1570 continue;
1571 vol = look_for_out_vol_nid(codec, path);
1572 if (vol)
1573 ctl->values[n++] =
1574 HDA_COMPOSE_AMP_VAL(vol, 3, 0, HDA_OUTPUT);
1575 }
1576 if (n) {
1577 snprintf(name, sizeof(name), "%s Playback Volume", pfx);
1578 err = add_control(spec, HDA_CTL_BIND_VOL, name, 0, (long)ctl);
1579 if (err < 0) 1503 if (err < 0)
1580 return err; 1504 return err;
1581 } 1505 }
@@ -1586,8 +1510,6 @@ static int create_hp_out_ctls(struct hda_codec *codec)
1586{ 1510{
1587 struct hda_gen_spec *spec = codec->spec; 1511 struct hda_gen_spec *spec = codec->spec;
1588 return create_extra_outs(codec, spec->autocfg.hp_outs, 1512 return create_extra_outs(codec, spec->autocfg.hp_outs,
1589 spec->autocfg.hp_pins,
1590 spec->multiout.hp_out_nid,
1591 spec->hp_paths, 1513 spec->hp_paths,
1592 "Headphone"); 1514 "Headphone");
1593} 1515}
@@ -1596,8 +1518,6 @@ static int create_speaker_out_ctls(struct hda_codec *codec)
1596{ 1518{
1597 struct hda_gen_spec *spec = codec->spec; 1519 struct hda_gen_spec *spec = codec->spec;
1598 return create_extra_outs(codec, spec->autocfg.speaker_outs, 1520 return create_extra_outs(codec, spec->autocfg.speaker_outs,
1599 spec->autocfg.speaker_pins,
1600 spec->multiout.extra_out_nid,
1601 spec->speaker_paths, 1521 spec->speaker_paths,
1602 "Speaker"); 1522 "Speaker");
1603} 1523}
diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h
index d4a8f6c4e7a9..4c0d9add6145 100644
--- a/sound/pci/hda/hda_generic.h
+++ b/sound/pci/hda/hda_generic.h
@@ -186,9 +186,6 @@ struct hda_gen_spec {
186 int multi_ios; 186 int multi_ios;
187 struct hda_multi_io multi_io[4]; 187 struct hda_multi_io multi_io[4];
188 188
189 /* bind volumes */
190 struct snd_array bind_ctls;
191
192 /* hooks */ 189 /* hooks */
193 void (*init_hook)(struct hda_codec *codec); 190 void (*init_hook)(struct hda_codec *codec);
194 void (*automute_hook)(struct hda_codec *codec); 191 void (*automute_hook)(struct hda_codec *codec);