aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2013-03-13 09:40:31 -0400
committerTakashi Iwai <tiwai@suse.de>2013-03-13 13:07:04 -0400
commitbce0d2a80e428aac3b39bf19675f1f57126f9cb6 (patch)
tree9f652749f3f6843c94b47973e7e910cfa900ff1f /sound/pci
parent5265fd9a9f512e0822955b0614bc4a5458defff9 (diff)
ALSA: hda - Allow unlimited pins and converters in patch_hdmi.c
Use the dynamic array allocations for pins, converters and PCM arrays instead of the fixed size arrays. The modern HDMI codecs get more and more pins, and we don't know the sensitive limit. Most of the patch are spent for the straight conversions from the fixed array access to snd_array helpers. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/hda/patch_hdmi.c198
1 files changed, 117 insertions, 81 deletions
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 78e1827d0a95..3e1159dd98c3 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -44,16 +44,6 @@ static bool static_hdmi_pcm;
44module_param(static_hdmi_pcm, bool, 0644); 44module_param(static_hdmi_pcm, bool, 0644);
45MODULE_PARM_DESC(static_hdmi_pcm, "Don't restrict PCM parameters per ELD info"); 45MODULE_PARM_DESC(static_hdmi_pcm, "Don't restrict PCM parameters per ELD info");
46 46
47/*
48 * The HDMI/DisplayPort configuration can be highly dynamic. A graphics device
49 * could support N independent pipes, each of them can be connected to one or
50 * more ports (DVI, HDMI or DisplayPort).
51 *
52 * The HDA correspondence of pipes/ports are converter/pin nodes.
53 */
54#define MAX_HDMI_CVTS 8
55#define MAX_HDMI_PINS 8
56
57struct hdmi_spec_per_cvt { 47struct hdmi_spec_per_cvt {
58 hda_nid_t cvt_nid; 48 hda_nid_t cvt_nid;
59 int assigned; 49 int assigned;
@@ -80,16 +70,17 @@ struct hdmi_spec_per_pin {
80 bool non_pcm; 70 bool non_pcm;
81 bool chmap_set; /* channel-map override by ALSA API? */ 71 bool chmap_set; /* channel-map override by ALSA API? */
82 unsigned char chmap[8]; /* ALSA API channel-map */ 72 unsigned char chmap[8]; /* ALSA API channel-map */
73 char pcm_name[8]; /* filled in build_pcm callbacks */
83}; 74};
84 75
85struct hdmi_spec { 76struct hdmi_spec {
86 int num_cvts; 77 int num_cvts;
87 struct hdmi_spec_per_cvt cvts[MAX_HDMI_CVTS]; 78 struct snd_array cvts; /* struct hdmi_spec_per_cvt */
88 hda_nid_t cvt_nids[MAX_HDMI_CVTS]; 79 hda_nid_t cvt_nids[4]; /* only for haswell fix */
89 80
90 int num_pins; 81 int num_pins;
91 struct hdmi_spec_per_pin pins[MAX_HDMI_PINS]; 82 struct snd_array pins; /* struct hdmi_spec_per_pin */
92 struct hda_pcm pcm_rec[MAX_HDMI_PINS]; 83 struct snd_array pcm_rec; /* struct hda_pcm */
93 unsigned int channels_max; /* max over all cvts */ 84 unsigned int channels_max; /* max over all cvts */
94 85
95 struct hdmi_eld temp_eld; 86 struct hdmi_eld temp_eld;
@@ -304,12 +295,19 @@ static struct cea_channel_speaker_allocation channel_allocations[] = {
304 * HDMI routines 295 * HDMI routines
305 */ 296 */
306 297
298#define get_pin(spec, idx) \
299 ((struct hdmi_spec_per_pin *)snd_array_elem(&spec->pins, idx))
300#define get_cvt(spec, idx) \
301 ((struct hdmi_spec_per_cvt *)snd_array_elem(&spec->cvts, idx))
302#define get_pcm_rec(spec, idx) \
303 ((struct hda_pcm *)snd_array_elem(&spec->pcm_rec, idx))
304
307static int pin_nid_to_pin_index(struct hdmi_spec *spec, hda_nid_t pin_nid) 305static int pin_nid_to_pin_index(struct hdmi_spec *spec, hda_nid_t pin_nid)
308{ 306{
309 int pin_idx; 307 int pin_idx;
310 308
311 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) 309 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++)
312 if (spec->pins[pin_idx].pin_nid == pin_nid) 310 if (get_pin(spec, pin_idx)->pin_nid == pin_nid)
313 return pin_idx; 311 return pin_idx;
314 312
315 snd_printk(KERN_WARNING "HDMI: pin nid %d not registered\n", pin_nid); 313 snd_printk(KERN_WARNING "HDMI: pin nid %d not registered\n", pin_nid);
@@ -322,7 +320,7 @@ static int hinfo_to_pin_index(struct hdmi_spec *spec,
322 int pin_idx; 320 int pin_idx;
323 321
324 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) 322 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++)
325 if (&spec->pcm_rec[pin_idx].stream[0] == hinfo) 323 if (get_pcm_rec(spec, pin_idx)->stream == hinfo)
326 return pin_idx; 324 return pin_idx;
327 325
328 snd_printk(KERN_WARNING "HDMI: hinfo %p not registered\n", hinfo); 326 snd_printk(KERN_WARNING "HDMI: hinfo %p not registered\n", hinfo);
@@ -334,7 +332,7 @@ static int cvt_nid_to_cvt_index(struct hdmi_spec *spec, hda_nid_t cvt_nid)
334 int cvt_idx; 332 int cvt_idx;
335 333
336 for (cvt_idx = 0; cvt_idx < spec->num_cvts; cvt_idx++) 334 for (cvt_idx = 0; cvt_idx < spec->num_cvts; cvt_idx++)
337 if (spec->cvts[cvt_idx].cvt_nid == cvt_nid) 335 if (get_cvt(spec, cvt_idx)->cvt_nid == cvt_nid)
338 return cvt_idx; 336 return cvt_idx;
339 337
340 snd_printk(KERN_WARNING "HDMI: cvt nid %d not registered\n", cvt_nid); 338 snd_printk(KERN_WARNING "HDMI: cvt nid %d not registered\n", cvt_nid);
@@ -352,7 +350,7 @@ static int hdmi_eld_ctl_info(struct snd_kcontrol *kcontrol,
352 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; 350 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
353 351
354 pin_idx = kcontrol->private_value; 352 pin_idx = kcontrol->private_value;
355 eld = &spec->pins[pin_idx].sink_eld; 353 eld = &get_pin(spec, pin_idx)->sink_eld;
356 354
357 mutex_lock(&eld->lock); 355 mutex_lock(&eld->lock);
358 uinfo->count = eld->eld_valid ? eld->eld_size : 0; 356 uinfo->count = eld->eld_valid ? eld->eld_size : 0;
@@ -370,7 +368,7 @@ static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol,
370 int pin_idx; 368 int pin_idx;
371 369
372 pin_idx = kcontrol->private_value; 370 pin_idx = kcontrol->private_value;
373 eld = &spec->pins[pin_idx].sink_eld; 371 eld = &get_pin(spec, pin_idx)->sink_eld;
374 372
375 mutex_lock(&eld->lock); 373 mutex_lock(&eld->lock);
376 if (eld->eld_size > ARRAY_SIZE(ucontrol->value.bytes.data)) { 374 if (eld->eld_size > ARRAY_SIZE(ucontrol->value.bytes.data)) {
@@ -410,11 +408,11 @@ static int hdmi_create_eld_ctl(struct hda_codec *codec, int pin_idx,
410 kctl->private_value = pin_idx; 408 kctl->private_value = pin_idx;
411 kctl->id.device = device; 409 kctl->id.device = device;
412 410
413 err = snd_hda_ctl_add(codec, spec->pins[pin_idx].pin_nid, kctl); 411 err = snd_hda_ctl_add(codec, get_pin(spec, pin_idx)->pin_nid, kctl);
414 if (err < 0) 412 if (err < 0)
415 return err; 413 return err;
416 414
417 spec->pins[pin_idx].eld_ctl = kctl; 415 get_pin(spec, pin_idx)->eld_ctl = kctl;
418 return 0; 416 return 0;
419} 417}
420 418
@@ -875,14 +873,14 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, int pin_idx,
875 struct snd_pcm_substream *substream) 873 struct snd_pcm_substream *substream)
876{ 874{
877 struct hdmi_spec *spec = codec->spec; 875 struct hdmi_spec *spec = codec->spec;
878 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; 876 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
879 hda_nid_t pin_nid = per_pin->pin_nid; 877 hda_nid_t pin_nid = per_pin->pin_nid;
880 int channels = substream->runtime->channels; 878 int channels = substream->runtime->channels;
881 struct hdmi_eld *eld; 879 struct hdmi_eld *eld;
882 int ca; 880 int ca;
883 union audio_infoframe ai; 881 union audio_infoframe ai;
884 882
885 eld = &spec->pins[pin_idx].sink_eld; 883 eld = &per_pin->sink_eld;
886 if (!eld->monitor_present) 884 if (!eld->monitor_present)
887 return; 885 return;
888 886
@@ -977,7 +975,7 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
977 if (pin_idx < 0) 975 if (pin_idx < 0)
978 return; 976 return;
979 977
980 hdmi_present_sense(&spec->pins[pin_idx], 1); 978 hdmi_present_sense(get_pin(spec, pin_idx), 1);
981 snd_hda_jack_report_sync(codec); 979 snd_hda_jack_report_sync(codec);
982} 980}
983 981
@@ -1083,12 +1081,12 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
1083 pin_idx = hinfo_to_pin_index(spec, hinfo); 1081 pin_idx = hinfo_to_pin_index(spec, hinfo);
1084 if (snd_BUG_ON(pin_idx < 0)) 1082 if (snd_BUG_ON(pin_idx < 0))
1085 return -EINVAL; 1083 return -EINVAL;
1086 per_pin = &spec->pins[pin_idx]; 1084 per_pin = get_pin(spec, pin_idx);
1087 eld = &per_pin->sink_eld; 1085 eld = &per_pin->sink_eld;
1088 1086
1089 /* Dynamically assign converter to stream */ 1087 /* Dynamically assign converter to stream */
1090 for (cvt_idx = 0; cvt_idx < spec->num_cvts; cvt_idx++) { 1088 for (cvt_idx = 0; cvt_idx < spec->num_cvts; cvt_idx++) {
1091 per_cvt = &spec->cvts[cvt_idx]; 1089 per_cvt = get_cvt(spec, cvt_idx);
1092 1090
1093 /* Must not already be assigned */ 1091 /* Must not already be assigned */
1094 if (per_cvt->assigned) 1092 if (per_cvt->assigned)
@@ -1151,7 +1149,7 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo,
1151static int hdmi_read_pin_conn(struct hda_codec *codec, int pin_idx) 1149static int hdmi_read_pin_conn(struct hda_codec *codec, int pin_idx)
1152{ 1150{
1153 struct hdmi_spec *spec = codec->spec; 1151 struct hdmi_spec *spec = codec->spec;
1154 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; 1152 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
1155 hda_nid_t pin_nid = per_pin->pin_nid; 1153 hda_nid_t pin_nid = per_pin->pin_nid;
1156 1154
1157 if (!(get_wcaps(codec, pin_nid) & AC_WCAP_CONN_LIST)) { 1155 if (!(get_wcaps(codec, pin_nid) & AC_WCAP_CONN_LIST)) {
@@ -1275,14 +1273,13 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
1275 if (get_defcfg_connect(config) == AC_JACK_PORT_NONE) 1273 if (get_defcfg_connect(config) == AC_JACK_PORT_NONE)
1276 return 0; 1274 return 0;
1277 1275
1278 if (snd_BUG_ON(spec->num_pins >= MAX_HDMI_PINS))
1279 return -E2BIG;
1280
1281 if (codec->vendor_id == 0x80862807) 1276 if (codec->vendor_id == 0x80862807)
1282 intel_haswell_fixup_connect_list(codec, pin_nid); 1277 intel_haswell_fixup_connect_list(codec, pin_nid);
1283 1278
1284 pin_idx = spec->num_pins; 1279 pin_idx = spec->num_pins;
1285 per_pin = &spec->pins[pin_idx]; 1280 per_pin = snd_array_new(&spec->pins);
1281 if (!per_pin)
1282 return -ENOMEM;
1286 1283
1287 per_pin->pin_nid = pin_nid; 1284 per_pin->pin_nid = pin_nid;
1288 per_pin->non_pcm = false; 1285 per_pin->non_pcm = false;
@@ -1299,19 +1296,16 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid)
1299static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t cvt_nid) 1296static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t cvt_nid)
1300{ 1297{
1301 struct hdmi_spec *spec = codec->spec; 1298 struct hdmi_spec *spec = codec->spec;
1302 int cvt_idx;
1303 struct hdmi_spec_per_cvt *per_cvt; 1299 struct hdmi_spec_per_cvt *per_cvt;
1304 unsigned int chans; 1300 unsigned int chans;
1305 int err; 1301 int err;
1306 1302
1307 if (snd_BUG_ON(spec->num_cvts >= MAX_HDMI_CVTS))
1308 return -E2BIG;
1309
1310 chans = get_wcaps(codec, cvt_nid); 1303 chans = get_wcaps(codec, cvt_nid);
1311 chans = get_wcaps_channels(chans); 1304 chans = get_wcaps_channels(chans);
1312 1305
1313 cvt_idx = spec->num_cvts; 1306 per_cvt = snd_array_new(&spec->cvts);
1314 per_cvt = &spec->cvts[cvt_idx]; 1307 if (!per_cvt)
1308 return -ENOMEM;
1315 1309
1316 per_cvt->cvt_nid = cvt_nid; 1310 per_cvt->cvt_nid = cvt_nid;
1317 per_cvt->channels_min = 2; 1311 per_cvt->channels_min = 2;
@@ -1328,7 +1322,9 @@ static int hdmi_add_cvt(struct hda_codec *codec, hda_nid_t cvt_nid)
1328 if (err < 0) 1322 if (err < 0)
1329 return err; 1323 return err;
1330 1324
1331 spec->cvt_nids[spec->num_cvts++] = cvt_nid; 1325 if (spec->num_cvts < ARRAY_SIZE(spec->cvt_nids))
1326 spec->cvt_nids[spec->num_cvts] = cvt_nid;
1327 spec->num_cvts++;
1332 1328
1333 return 0; 1329 return 0;
1334} 1330}
@@ -1384,13 +1380,6 @@ static int hdmi_parse_codec(struct hda_codec *codec)
1384 1380
1385/* 1381/*
1386 */ 1382 */
1387static char *get_hdmi_pcm_name(int idx)
1388{
1389 static char names[MAX_HDMI_PINS][8];
1390 sprintf(&names[idx][0], "HDMI %d", idx);
1391 return &names[idx][0];
1392}
1393
1394static bool check_non_pcm_per_cvt(struct hda_codec *codec, hda_nid_t cvt_nid) 1383static bool check_non_pcm_per_cvt(struct hda_codec *codec, hda_nid_t cvt_nid)
1395{ 1384{
1396 struct hda_spdif_out *spdif; 1385 struct hda_spdif_out *spdif;
@@ -1417,7 +1406,7 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1417 hda_nid_t cvt_nid = hinfo->nid; 1406 hda_nid_t cvt_nid = hinfo->nid;
1418 struct hdmi_spec *spec = codec->spec; 1407 struct hdmi_spec *spec = codec->spec;
1419 int pin_idx = hinfo_to_pin_index(spec, hinfo); 1408 int pin_idx = hinfo_to_pin_index(spec, hinfo);
1420 hda_nid_t pin_nid = spec->pins[pin_idx].pin_nid; 1409 hda_nid_t pin_nid = get_pin(spec, pin_idx)->pin_nid;
1421 bool non_pcm; 1410 bool non_pcm;
1422 1411
1423 non_pcm = check_non_pcm_per_cvt(codec, cvt_nid); 1412 non_pcm = check_non_pcm_per_cvt(codec, cvt_nid);
@@ -1450,7 +1439,7 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo,
1450 cvt_idx = cvt_nid_to_cvt_index(spec, hinfo->nid); 1439 cvt_idx = cvt_nid_to_cvt_index(spec, hinfo->nid);
1451 if (snd_BUG_ON(cvt_idx < 0)) 1440 if (snd_BUG_ON(cvt_idx < 0))
1452 return -EINVAL; 1441 return -EINVAL;
1453 per_cvt = &spec->cvts[cvt_idx]; 1442 per_cvt = get_cvt(spec, cvt_idx);
1454 1443
1455 snd_BUG_ON(!per_cvt->assigned); 1444 snd_BUG_ON(!per_cvt->assigned);
1456 per_cvt->assigned = 0; 1445 per_cvt->assigned = 0;
@@ -1459,7 +1448,7 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo,
1459 pin_idx = hinfo_to_pin_index(spec, hinfo); 1448 pin_idx = hinfo_to_pin_index(spec, hinfo);
1460 if (snd_BUG_ON(pin_idx < 0)) 1449 if (snd_BUG_ON(pin_idx < 0))
1461 return -EINVAL; 1450 return -EINVAL;
1462 per_pin = &spec->pins[pin_idx]; 1451 per_pin = get_pin(spec, pin_idx);
1463 1452
1464 snd_hda_spdif_ctls_unassign(codec, pin_idx); 1453 snd_hda_spdif_ctls_unassign(codec, pin_idx);
1465 per_pin->chmap_set = false; 1454 per_pin->chmap_set = false;
@@ -1553,7 +1542,7 @@ static int hdmi_chmap_ctl_get(struct snd_kcontrol *kcontrol,
1553 struct hda_codec *codec = info->private_data; 1542 struct hda_codec *codec = info->private_data;
1554 struct hdmi_spec *spec = codec->spec; 1543 struct hdmi_spec *spec = codec->spec;
1555 int pin_idx = kcontrol->private_value; 1544 int pin_idx = kcontrol->private_value;
1556 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; 1545 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
1557 int i; 1546 int i;
1558 1547
1559 for (i = 0; i < ARRAY_SIZE(per_pin->chmap); i++) 1548 for (i = 0; i < ARRAY_SIZE(per_pin->chmap); i++)
@@ -1568,7 +1557,7 @@ static int hdmi_chmap_ctl_put(struct snd_kcontrol *kcontrol,
1568 struct hda_codec *codec = info->private_data; 1557 struct hda_codec *codec = info->private_data;
1569 struct hdmi_spec *spec = codec->spec; 1558 struct hdmi_spec *spec = codec->spec;
1570 int pin_idx = kcontrol->private_value; 1559 int pin_idx = kcontrol->private_value;
1571 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; 1560 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
1572 unsigned int ctl_idx; 1561 unsigned int ctl_idx;
1573 struct snd_pcm_substream *substream; 1562 struct snd_pcm_substream *substream;
1574 unsigned char chmap[8]; 1563 unsigned char chmap[8];
@@ -1613,9 +1602,14 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec)
1613 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { 1602 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
1614 struct hda_pcm *info; 1603 struct hda_pcm *info;
1615 struct hda_pcm_stream *pstr; 1604 struct hda_pcm_stream *pstr;
1616 1605 struct hdmi_spec_per_pin *per_pin;
1617 info = &spec->pcm_rec[pin_idx]; 1606
1618 info->name = get_hdmi_pcm_name(pin_idx); 1607 per_pin = get_pin(spec, pin_idx);
1608 sprintf(per_pin->pcm_name, "HDMI %d", pin_idx);
1609 info = snd_array_new(&spec->pcm_rec);
1610 if (!info)
1611 return -ENOMEM;
1612 info->name = per_pin->pcm_name;
1619 info->pcm_type = HDA_PCM_TYPE_HDMI; 1613 info->pcm_type = HDA_PCM_TYPE_HDMI;
1620 info->own_chmap = true; 1614 info->own_chmap = true;
1621 1615
@@ -1626,7 +1620,7 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec)
1626 } 1620 }
1627 1621
1628 codec->num_pcms = spec->num_pins; 1622 codec->num_pcms = spec->num_pins;
1629 codec->pcm_info = spec->pcm_rec; 1623 codec->pcm_info = spec->pcm_rec.list;
1630 1624
1631 return 0; 1625 return 0;
1632} 1626}
@@ -1635,8 +1629,8 @@ static int generic_hdmi_build_jack(struct hda_codec *codec, int pin_idx)
1635{ 1629{
1636 char hdmi_str[32] = "HDMI/DP"; 1630 char hdmi_str[32] = "HDMI/DP";
1637 struct hdmi_spec *spec = codec->spec; 1631 struct hdmi_spec *spec = codec->spec;
1638 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; 1632 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
1639 int pcmdev = spec->pcm_rec[pin_idx].device; 1633 int pcmdev = get_pcm_rec(spec, pin_idx)->device;
1640 1634
1641 if (pcmdev > 0) 1635 if (pcmdev > 0)
1642 sprintf(hdmi_str + strlen(hdmi_str), ",pcm=%d", pcmdev); 1636 sprintf(hdmi_str + strlen(hdmi_str), ",pcm=%d", pcmdev);
@@ -1654,7 +1648,7 @@ static int generic_hdmi_build_controls(struct hda_codec *codec)
1654 int pin_idx; 1648 int pin_idx;
1655 1649
1656 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { 1650 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
1657 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; 1651 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
1658 1652
1659 err = generic_hdmi_build_jack(codec, pin_idx); 1653 err = generic_hdmi_build_jack(codec, pin_idx);
1660 if (err < 0) 1654 if (err < 0)
@@ -1669,9 +1663,8 @@ static int generic_hdmi_build_controls(struct hda_codec *codec)
1669 snd_hda_spdif_ctls_unassign(codec, pin_idx); 1663 snd_hda_spdif_ctls_unassign(codec, pin_idx);
1670 1664
1671 /* add control for ELD Bytes */ 1665 /* add control for ELD Bytes */
1672 err = hdmi_create_eld_ctl(codec, 1666 err = hdmi_create_eld_ctl(codec, pin_idx,
1673 pin_idx, 1667 get_pcm_rec(spec, pin_idx)->device);
1674 spec->pcm_rec[pin_idx].device);
1675 1668
1676 if (err < 0) 1669 if (err < 0)
1677 return err; 1670 return err;
@@ -1709,7 +1702,7 @@ static int generic_hdmi_init_per_pins(struct hda_codec *codec)
1709 int pin_idx; 1702 int pin_idx;
1710 1703
1711 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { 1704 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
1712 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; 1705 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
1713 struct hdmi_eld *eld = &per_pin->sink_eld; 1706 struct hdmi_eld *eld = &per_pin->sink_eld;
1714 1707
1715 per_pin->codec = codec; 1708 per_pin->codec = codec;
@@ -1726,7 +1719,7 @@ static int generic_hdmi_init(struct hda_codec *codec)
1726 int pin_idx; 1719 int pin_idx;
1727 1720
1728 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { 1721 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
1729 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; 1722 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
1730 hda_nid_t pin_nid = per_pin->pin_nid; 1723 hda_nid_t pin_nid = per_pin->pin_nid;
1731 1724
1732 hdmi_init_pin(codec, pin_nid); 1725 hdmi_init_pin(codec, pin_nid);
@@ -1735,13 +1728,27 @@ static int generic_hdmi_init(struct hda_codec *codec)
1735 return 0; 1728 return 0;
1736} 1729}
1737 1730
1731static void hdmi_array_init(struct hdmi_spec *spec, int nums)
1732{
1733 snd_array_init(&spec->pins, sizeof(struct hdmi_spec_per_pin), nums);
1734 snd_array_init(&spec->cvts, sizeof(struct hdmi_spec_per_cvt), nums);
1735 snd_array_init(&spec->pcm_rec, sizeof(struct hda_pcm), nums);
1736}
1737
1738static void hdmi_array_free(struct hdmi_spec *spec)
1739{
1740 snd_array_free(&spec->pins);
1741 snd_array_free(&spec->cvts);
1742 snd_array_free(&spec->pcm_rec);
1743}
1744
1738static void generic_hdmi_free(struct hda_codec *codec) 1745static void generic_hdmi_free(struct hda_codec *codec)
1739{ 1746{
1740 struct hdmi_spec *spec = codec->spec; 1747 struct hdmi_spec *spec = codec->spec;
1741 int pin_idx; 1748 int pin_idx;
1742 1749
1743 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) { 1750 for (pin_idx = 0; pin_idx < spec->num_pins; pin_idx++) {
1744 struct hdmi_spec_per_pin *per_pin = &spec->pins[pin_idx]; 1751 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
1745 struct hdmi_eld *eld = &per_pin->sink_eld; 1752 struct hdmi_eld *eld = &per_pin->sink_eld;
1746 1753
1747 cancel_delayed_work(&per_pin->work); 1754 cancel_delayed_work(&per_pin->work);
@@ -1749,6 +1756,7 @@ static void generic_hdmi_free(struct hda_codec *codec)
1749 } 1756 }
1750 1757
1751 flush_workqueue(codec->bus->workq); 1758 flush_workqueue(codec->bus->workq);
1759 hdmi_array_free(spec);
1752 kfree(spec); 1760 kfree(spec);
1753} 1761}
1754 1762
@@ -1775,6 +1783,7 @@ static void intel_haswell_fixup_connect_list(struct hda_codec *codec,
1775 1783
1776 /* override pins connection list */ 1784 /* override pins connection list */
1777 snd_printdd("hdmi: haswell: override pin connection 0x%x\n", nid); 1785 snd_printdd("hdmi: haswell: override pin connection 0x%x\n", nid);
1786 nconns = max(spec->num_cvts, 4);
1778 snd_hda_override_conn_list(codec, nid, spec->num_cvts, spec->cvt_nids); 1787 snd_hda_override_conn_list(codec, nid, spec->num_cvts, spec->cvt_nids);
1779} 1788}
1780 1789
@@ -1855,6 +1864,7 @@ static int patch_generic_hdmi(struct hda_codec *codec)
1855 return -ENOMEM; 1864 return -ENOMEM;
1856 1865
1857 codec->spec = spec; 1866 codec->spec = spec;
1867 hdmi_array_init(spec, 4);
1858 1868
1859 snd_hda_pick_fixup(codec, hdmi_models, hdmi_fixup_tbl, hdmi_fixups); 1869 snd_hda_pick_fixup(codec, hdmi_models, hdmi_fixup_tbl, hdmi_fixups);
1860 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 1870 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
@@ -1882,24 +1892,30 @@ static int patch_generic_hdmi(struct hda_codec *codec)
1882static int simple_playback_build_pcms(struct hda_codec *codec) 1892static int simple_playback_build_pcms(struct hda_codec *codec)
1883{ 1893{
1884 struct hdmi_spec *spec = codec->spec; 1894 struct hdmi_spec *spec = codec->spec;
1885 struct hda_pcm *info = spec->pcm_rec; 1895 struct hda_pcm *info;
1886 unsigned int chans; 1896 unsigned int chans;
1887 struct hda_pcm_stream *pstr; 1897 struct hda_pcm_stream *pstr;
1898 struct hdmi_spec_per_cvt *per_cvt;
1888 1899
1889 codec->num_pcms = 1; 1900 per_cvt = get_cvt(spec, 0);
1890 codec->pcm_info = info; 1901 chans = get_wcaps(codec, per_cvt->cvt_nid);
1891
1892 chans = get_wcaps(codec, spec->cvts[0].cvt_nid);
1893 chans = get_wcaps_channels(chans); 1902 chans = get_wcaps_channels(chans);
1894 1903
1895 info->name = get_hdmi_pcm_name(0); 1904 info = snd_array_new(&spec->pcm_rec);
1905 if (!info)
1906 return -ENOMEM;
1907 info->name = get_pin(spec, 0)->pcm_name;
1908 sprintf(info->name, "HDMI 0");
1896 info->pcm_type = HDA_PCM_TYPE_HDMI; 1909 info->pcm_type = HDA_PCM_TYPE_HDMI;
1897 pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK]; 1910 pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK];
1898 *pstr = spec->pcm_playback; 1911 *pstr = spec->pcm_playback;
1899 pstr->nid = spec->cvts[0].cvt_nid; 1912 pstr->nid = per_cvt->cvt_nid;
1900 if (pstr->channels_max <= 2 && chans && chans <= 16) 1913 if (pstr->channels_max <= 2 && chans && chans <= 16)
1901 pstr->channels_max = chans; 1914 pstr->channels_max = chans;
1902 1915
1916 codec->num_pcms = 1;
1917 codec->pcm_info = info;
1918
1903 return 0; 1919 return 0;
1904} 1920}
1905 1921
@@ -1919,11 +1935,12 @@ static void simple_hdmi_unsol_event(struct hda_codec *codec,
1919static int simple_playback_build_controls(struct hda_codec *codec) 1935static int simple_playback_build_controls(struct hda_codec *codec)
1920{ 1936{
1921 struct hdmi_spec *spec = codec->spec; 1937 struct hdmi_spec *spec = codec->spec;
1938 struct hdmi_spec_per_cvt *per_cvt;
1922 int err; 1939 int err;
1923 1940
1924 err = snd_hda_create_spdif_out_ctls(codec, 1941 per_cvt = get_cvt(spec, 0);
1925 spec->cvts[0].cvt_nid, 1942 err = snd_hda_create_spdif_out_ctls(codec, per_cvt->cvt_nid,
1926 spec->cvts[0].cvt_nid); 1943 per_cvt->cvt_nid);
1927 if (err < 0) 1944 if (err < 0)
1928 return err; 1945 return err;
1929 return simple_hdmi_build_jack(codec, 0); 1946 return simple_hdmi_build_jack(codec, 0);
@@ -1932,7 +1949,8 @@ static int simple_playback_build_controls(struct hda_codec *codec)
1932static int simple_playback_init(struct hda_codec *codec) 1949static int simple_playback_init(struct hda_codec *codec)
1933{ 1950{
1934 struct hdmi_spec *spec = codec->spec; 1951 struct hdmi_spec *spec = codec->spec;
1935 hda_nid_t pin = spec->pins[0].pin_nid; 1952 struct hdmi_spec_per_pin *per_pin = get_pin(spec, 0);
1953 hda_nid_t pin = per_pin->pin_nid;
1936 1954
1937 snd_hda_codec_write(codec, pin, 0, 1955 snd_hda_codec_write(codec, pin, 0,
1938 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 1956 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
@@ -1948,6 +1966,7 @@ static void simple_playback_free(struct hda_codec *codec)
1948{ 1966{
1949 struct hdmi_spec *spec = codec->spec; 1967 struct hdmi_spec *spec = codec->spec;
1950 1968
1969 hdmi_array_free(spec);
1951 kfree(spec); 1970 kfree(spec);
1952} 1971}
1953 1972
@@ -2111,20 +2130,29 @@ static int patch_simple_hdmi(struct hda_codec *codec,
2111 hda_nid_t cvt_nid, hda_nid_t pin_nid) 2130 hda_nid_t cvt_nid, hda_nid_t pin_nid)
2112{ 2131{
2113 struct hdmi_spec *spec; 2132 struct hdmi_spec *spec;
2133 struct hdmi_spec_per_cvt *per_cvt;
2134 struct hdmi_spec_per_pin *per_pin;
2114 2135
2115 spec = kzalloc(sizeof(*spec), GFP_KERNEL); 2136 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
2116 if (!spec) 2137 if (!spec)
2117 return -ENOMEM; 2138 return -ENOMEM;
2118 2139
2119 codec->spec = spec; 2140 codec->spec = spec;
2141 hdmi_array_init(spec, 1);
2120 2142
2121 spec->multiout.num_dacs = 0; /* no analog */ 2143 spec->multiout.num_dacs = 0; /* no analog */
2122 spec->multiout.max_channels = 2; 2144 spec->multiout.max_channels = 2;
2123 spec->multiout.dig_out_nid = cvt_nid; 2145 spec->multiout.dig_out_nid = cvt_nid;
2124 spec->num_cvts = 1; 2146 spec->num_cvts = 1;
2125 spec->num_pins = 1; 2147 spec->num_pins = 1;
2126 spec->cvts[0].cvt_nid = cvt_nid; 2148 per_pin = snd_array_new(&spec->pins);
2127 spec->pins[0].pin_nid = pin_nid; 2149 per_cvt = snd_array_new(&spec->cvts);
2150 if (!per_pin || !per_cvt) {
2151 simple_playback_free(codec);
2152 return -ENOMEM;
2153 }
2154 per_cvt->cvt_nid = cvt_nid;
2155 per_pin->pin_nid = pin_nid;
2128 spec->pcm_playback = simple_pcm_playback; 2156 spec->pcm_playback = simple_pcm_playback;
2129 2157
2130 codec->patch_ops = simple_hdmi_patch_ops; 2158 codec->patch_ops = simple_hdmi_patch_ops;
@@ -2201,9 +2229,11 @@ static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo,
2201 int i; 2229 int i;
2202 struct hdmi_spec *spec = codec->spec; 2230 struct hdmi_spec *spec = codec->spec;
2203 struct hda_spdif_out *spdif; 2231 struct hda_spdif_out *spdif;
2232 struct hdmi_spec_per_cvt *per_cvt;
2204 2233
2205 mutex_lock(&codec->spdif_mutex); 2234 mutex_lock(&codec->spdif_mutex);
2206 spdif = snd_hda_spdif_out_of_nid(codec, spec->cvts[0].cvt_nid); 2235 per_cvt = get_cvt(spec, 0);
2236 spdif = snd_hda_spdif_out_of_nid(codec, per_cvt->cvt_nid);
2207 2237
2208 chs = substream->runtime->channels; 2238 chs = substream->runtime->channels;
2209 2239
@@ -2325,13 +2355,17 @@ static int nvhdmi_7x_8ch_build_pcms(struct hda_codec *codec)
2325{ 2355{
2326 struct hdmi_spec *spec = codec->spec; 2356 struct hdmi_spec *spec = codec->spec;
2327 int err = simple_playback_build_pcms(codec); 2357 int err = simple_playback_build_pcms(codec);
2328 spec->pcm_rec[0].own_chmap = true; 2358 if (!err) {
2359 struct hda_pcm *info = get_pcm_rec(spec, 0);
2360 info->own_chmap = true;
2361 }
2329 return err; 2362 return err;
2330} 2363}
2331 2364
2332static int nvhdmi_7x_8ch_build_controls(struct hda_codec *codec) 2365static int nvhdmi_7x_8ch_build_controls(struct hda_codec *codec)
2333{ 2366{
2334 struct hdmi_spec *spec = codec->spec; 2367 struct hdmi_spec *spec = codec->spec;
2368 struct hda_pcm *info;
2335 struct snd_pcm_chmap *chmap; 2369 struct snd_pcm_chmap *chmap;
2336 int err; 2370 int err;
2337 2371
@@ -2340,7 +2374,8 @@ static int nvhdmi_7x_8ch_build_controls(struct hda_codec *codec)
2340 return err; 2374 return err;
2341 2375
2342 /* add channel maps */ 2376 /* add channel maps */
2343 err = snd_pcm_add_chmap_ctls(spec->pcm_rec[0].pcm, 2377 info = get_pcm_rec(spec, 0);
2378 err = snd_pcm_add_chmap_ctls(info->pcm,
2344 SNDRV_PCM_STREAM_PLAYBACK, 2379 SNDRV_PCM_STREAM_PLAYBACK,
2345 snd_pcm_alt_chmaps, 8, 0, &chmap); 2380 snd_pcm_alt_chmaps, 8, 0, &chmap);
2346 if (err < 0) 2381 if (err < 0)
@@ -2395,6 +2430,7 @@ static int atihdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2395 struct snd_pcm_substream *substream) 2430 struct snd_pcm_substream *substream)
2396{ 2431{
2397 struct hdmi_spec *spec = codec->spec; 2432 struct hdmi_spec *spec = codec->spec;
2433 struct hdmi_spec_per_cvt *per_cvt = get_cvt(spec, 0);
2398 int chans = substream->runtime->channels; 2434 int chans = substream->runtime->channels;
2399 int i, err; 2435 int i, err;
2400 2436
@@ -2402,11 +2438,11 @@ static int atihdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
2402 substream); 2438 substream);
2403 if (err < 0) 2439 if (err < 0)
2404 return err; 2440 return err;
2405 snd_hda_codec_write(codec, spec->cvts[0].cvt_nid, 0, 2441 snd_hda_codec_write(codec, per_cvt->cvt_nid, 0,
2406 AC_VERB_SET_CVT_CHAN_COUNT, chans - 1); 2442 AC_VERB_SET_CVT_CHAN_COUNT, chans - 1);
2407 /* FIXME: XXX */ 2443 /* FIXME: XXX */
2408 for (i = 0; i < chans; i++) { 2444 for (i = 0; i < chans; i++) {
2409 snd_hda_codec_write(codec, spec->cvts[0].cvt_nid, 0, 2445 snd_hda_codec_write(codec, per_cvt->cvt_nid, 0,
2410 AC_VERB_SET_HDMI_CHAN_SLOT, 2446 AC_VERB_SET_HDMI_CHAN_SLOT,
2411 (i << 4) | i); 2447 (i << 4) | i);
2412 } 2448 }