hdac_hdmi.c 57.4 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
/*
 *  hdac_hdmi.c - ASoc HDA-HDMI codec driver for Intel platforms
 *
 *  Copyright (C) 2014-2015 Intel Corp
 *  Author: Samreen Nilofer <samreen.nilofer@intel.com>
 *	    Subhransu S. Prusty <subhransu.s.prusty@intel.com>
 *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; version 2 of the License.
 *
 *  This program is distributed in the hope that it will be useful, but
 *  WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  General Public License for more details.
 *
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 */
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
24
#include <linux/hdmi.h>
25
#include <drm/drm_edid.h>
26
#include <sound/pcm_params.h>
Jeeja KP's avatar
Jeeja KP committed
27
#include <sound/jack.h>
28 29
#include <sound/soc.h>
#include <sound/hdaudio_ext.h>
30
#include <sound/hda_i915.h>
31
#include <sound/pcm_drm_eld.h>
32
#include <sound/hda_chmap.h>
33
#include "../../hda/local.h"
Jeeja KP's avatar
Jeeja KP committed
34
#include "hdac_hdmi.h"
35

36 37
#define NAME_SIZE	32

38 39
#define AMP_OUT_MUTE		0xb080
#define AMP_OUT_UNMUTE		0xb000
40
#define PIN_OUT			(AC_PINCTL_OUT_EN)
41

42 43
#define HDA_MAX_CONNECTIONS     32

44
#define HDA_MAX_CVTS		3
45
#define HDA_MAX_PORTS		3
46

47 48 49
#define ELD_MAX_SIZE    256
#define ELD_FIXED_BYTES	20

50 51 52 53
#define ELD_VER_CEA_861D 2
#define ELD_VER_PARTIAL 31
#define ELD_MAX_MNL     16

54 55 56 57 58 59 60 61 62
struct hdac_hdmi_cvt_params {
	unsigned int channels_min;
	unsigned int channels_max;
	u32 rates;
	u64 formats;
	unsigned int maxbps;
};

struct hdac_hdmi_cvt {
63
	struct list_head head;
64
	hda_nid_t nid;
Jeeja KP's avatar
Jeeja KP committed
65
	const char *name;
66 67 68
	struct hdac_hdmi_cvt_params params;
};

69 70 71 72 73
/* Currently only spk_alloc, more to be added */
struct hdac_hdmi_parsed_eld {
	u8 spk_alloc;
};

74 75 76 77 78
struct hdac_hdmi_eld {
	bool	monitor_present;
	bool	eld_valid;
	int	eld_size;
	char    eld_buffer[ELD_MAX_SIZE];
79
	struct	hdac_hdmi_parsed_eld info;
80 81
};

82
struct hdac_hdmi_pin {
83
	struct list_head head;
84
	hda_nid_t nid;
85
	bool mst_capable;
86 87
	struct hdac_hdmi_port *ports;
	int num_ports;
88
	struct hdac_device *hdev;
89 90 91
};

struct hdac_hdmi_port {
92
	struct list_head head;
93 94
	int id;
	struct hdac_hdmi_pin *pin;
95 96
	int num_mux_nids;
	hda_nid_t mux_nids[HDA_MAX_CONNECTIONS];
97
	struct hdac_hdmi_eld eld;
98 99 100
	const char *jack_pin;
	struct snd_soc_dapm_context *dapm;
	const char *output_pin;
101 102
};

Jeeja KP's avatar
Jeeja KP committed
103 104 105
struct hdac_hdmi_pcm {
	struct list_head head;
	int pcm_id;
106
	struct list_head port_list;
Jeeja KP's avatar
Jeeja KP committed
107
	struct hdac_hdmi_cvt *cvt;
108
	struct snd_soc_jack *jack;
109 110 111
	int stream_tag;
	int channels;
	int format;
112 113 114
	bool chmap_set;
	unsigned char chmap[8]; /* ALSA API channel-map */
	struct mutex lock;
115
	int jack_event;
Jeeja KP's avatar
Jeeja KP committed
116 117
};

118
struct hdac_hdmi_dai_port_map {
119
	int dai_id;
120
	struct hdac_hdmi_port *port;
121
	struct hdac_hdmi_cvt *cvt;
122 123
};

124 125 126 127
struct hdac_hdmi_drv_data {
	unsigned int vendor_nid;
};

128
struct hdac_hdmi_priv {
129 130 131
	struct hdac_device *hdev;
	struct snd_soc_component *component;
	struct snd_card *card;
132
	struct hdac_hdmi_dai_port_map dai_map[HDA_MAX_CVTS];
133 134
	struct list_head pin_list;
	struct list_head cvt_list;
Jeeja KP's avatar
Jeeja KP committed
135
	struct list_head pcm_list;
136 137
	int num_pin;
	int num_cvt;
138
	int num_ports;
Jeeja KP's avatar
Jeeja KP committed
139
	struct mutex pin_mutex;
140
	struct hdac_chmap chmap;
141
	struct hdac_hdmi_drv_data *drv_data;
142
	struct snd_soc_dai_driver *dai_drv;
143 144
};

145
#define hdev_to_hdmi_priv(_hdev) dev_get_drvdata(&(_hdev)->dev)
146

147 148 149 150 151 152 153 154 155 156
static struct hdac_hdmi_pcm *
hdac_hdmi_get_pcm_from_cvt(struct hdac_hdmi_priv *hdmi,
			   struct hdac_hdmi_cvt *cvt)
{
	struct hdac_hdmi_pcm *pcm = NULL;

	list_for_each_entry(pcm, &hdmi->pcm_list, head) {
		if (pcm->cvt == cvt)
			break;
	}
157

158 159
	return pcm;
}
160

161 162 163
static void hdac_hdmi_jack_report(struct hdac_hdmi_pcm *pcm,
		struct hdac_hdmi_port *port, bool is_connect)
{
164
	struct hdac_device *hdev = port->pin->hdev;
165

166 167 168 169 170
	if (is_connect)
		snd_soc_dapm_enable_pin(port->dapm, port->jack_pin);
	else
		snd_soc_dapm_disable_pin(port->dapm, port->jack_pin);

171 172 173 174 175 176 177
	if (is_connect) {
		/*
		 * Report Jack connect event when a device is connected
		 * for the first time where same PCM is attached to multiple
		 * ports.
		 */
		if (pcm->jack_event == 0) {
178
			dev_dbg(&hdev->dev,
179 180
					"jack report for pcm=%d\n",
					pcm->pcm_id);
181 182
			snd_soc_jack_report(pcm->jack, SND_JACK_AVOUT,
						SND_JACK_AVOUT);
183 184 185 186 187 188 189 190 191
		}
		pcm->jack_event++;
	} else {
		/*
		 * Report Jack disconnect event when a device is disconnected
		 * is the only last connected device when same PCM is attached
		 * to multiple ports.
		 */
		if (pcm->jack_event == 1)
192
			snd_soc_jack_report(pcm->jack, 0, SND_JACK_AVOUT);
193 194 195
		if (pcm->jack_event > 0)
			pcm->jack_event--;
	}
196 197

	snd_soc_dapm_sync(port->dapm);
198 199
}

200 201 202 203
/* MST supported verbs */
/*
 * Get the no devices that can be connected to a port on the Pin widget.
 */
204
static int hdac_hdmi_get_port_len(struct hdac_device *hdev, hda_nid_t nid)
205 206 207 208
{
	unsigned int caps;
	unsigned int type, param;

209
	caps = get_wcaps(hdev, nid);
210 211 212 213 214
	type = get_wcaps_type(caps);

	if (!(caps & AC_WCAP_DIGITAL) || (type != AC_WID_PIN))
		return 0;

215
	param = snd_hdac_read_parm_uncached(hdev, nid, AC_PAR_DEVLIST_LEN);
216 217 218 219 220 221 222 223 224 225 226
	if (param == -1)
		return param;

	return param & AC_DEV_LIST_LEN_MASK;
}

/*
 * Get the port entry select on the pin. Return the port entry
 * id selected on the pin. Return 0 means the first port entry
 * is selected or MST is not supported.
 */
227
static int hdac_hdmi_port_select_get(struct hdac_device *hdev,
228 229
					struct hdac_hdmi_port *port)
{
230
	return snd_hdac_codec_read(hdev, port->pin->nid,
231 232 233 234 235 236 237
				0, AC_VERB_GET_DEVICE_SEL, 0);
}

/*
 * Sets the selected port entry for the configuring Pin widget verb.
 * returns error if port set is not equal to port get otherwise success
 */
238
static int hdac_hdmi_port_select_set(struct hdac_device *hdev,
239 240 241 242 243 244 245 246
					struct hdac_hdmi_port *port)
{
	int num_ports;

	if (!port->pin->mst_capable)
		return 0;

	/* AC_PAR_DEVLIST_LEN is 0 based. */
247
	num_ports = hdac_hdmi_get_port_len(hdev, port->pin->nid);
248 249 250 251 252 253 254 255 256
	if (num_ports < 0)
		return -EIO;
	/*
	 * Device List Length is a 0 based integer value indicating the
	 * number of sink device that a MST Pin Widget can support.
	 */
	if (num_ports + 1  < port->id)
		return 0;

257
	snd_hdac_codec_write(hdev, port->pin->nid, 0,
258 259
			AC_VERB_SET_DEVICE_SEL, port->id);

260
	if (port->id != hdac_hdmi_port_select_get(hdev, port))
261 262
		return -EIO;

263
	dev_dbg(&hdev->dev, "Selected the port=%d\n", port->id);
264 265 266 267

	return 0;
}

268 269 270 271 272 273 274 275 276 277 278 279 280
static struct hdac_hdmi_pcm *get_hdmi_pcm_from_id(struct hdac_hdmi_priv *hdmi,
						int pcm_idx)
{
	struct hdac_hdmi_pcm *pcm;

	list_for_each_entry(pcm, &hdmi->pcm_list, head) {
		if (pcm->pcm_id == pcm_idx)
			return pcm;
	}

	return NULL;
}

281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319
static unsigned int sad_format(const u8 *sad)
{
	return ((sad[0] >> 0x3) & 0x1f);
}

static unsigned int sad_sample_bits_lpcm(const u8 *sad)
{
	return (sad[2] & 7);
}

static int hdac_hdmi_eld_limit_formats(struct snd_pcm_runtime *runtime,
						void *eld)
{
	u64 formats = SNDRV_PCM_FMTBIT_S16;
	int i;
	const u8 *sad, *eld_buf = eld;

	sad = drm_eld_sad(eld_buf);
	if (!sad)
		goto format_constraint;

	for (i = drm_eld_sad_count(eld_buf); i > 0; i--, sad += 3) {
		if (sad_format(sad) == 1) { /* AUDIO_CODING_TYPE_LPCM */

			/*
			 * the controller support 20 and 24 bits in 32 bit
			 * container so we set S32
			 */
			if (sad_sample_bits_lpcm(sad) & 0x6)
				formats |= SNDRV_PCM_FMTBIT_S32;
		}
	}

format_constraint:
	return snd_pcm_hw_constraint_mask64(runtime, SNDRV_PCM_HW_PARAM_FORMAT,
				formats);

}

320
static void
321
hdac_hdmi_set_dip_index(struct hdac_device *hdev, hda_nid_t pin_nid,
322 323 324 325 326
				int packet_index, int byte_index)
{
	int val;

	val = (packet_index << 5) | (byte_index & 0x1f);
327
	snd_hdac_codec_write(hdev, pin_nid, 0, AC_VERB_SET_HDMI_DIP_INDEX, val);
328 329
}

330 331 332 333 334 335 336 337 338 339 340 341
struct dp_audio_infoframe {
	u8 type; /* 0x84 */
	u8 len;  /* 0x1b */
	u8 ver;  /* 0x11 << 2 */

	u8 CC02_CT47;	/* match with HDMI infoframe from this on */
	u8 SS01_SF24;
	u8 CXT04;
	u8 CA;
	u8 LFEPBL01_LSV36_DM_INH7;
};

342
static int hdac_hdmi_setup_audio_infoframe(struct hdac_device *hdev,
343
		   struct hdac_hdmi_pcm *pcm, struct hdac_hdmi_port *port)
344 345 346
{
	uint8_t buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AUDIO_INFOFRAME_SIZE];
	struct hdmi_audio_infoframe frame;
347
	struct hdac_hdmi_pin *pin = port->pin;
348
	struct dp_audio_infoframe dp_ai;
349
	struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev);
350
	struct hdac_hdmi_cvt *cvt = pcm->cvt;
351
	u8 *dip;
352 353
	int ret;
	int i;
354 355
	const u8 *eld_buf;
	u8 conn_type;
356
	int channels, ca;
357

358
	ca = snd_hdac_channel_allocation(hdev, port->eld.info.spk_alloc,
359
			pcm->channels, pcm->chmap_set, true, pcm->chmap);
360 361

	channels = snd_hdac_get_active_channels(ca);
362
	hdmi->chmap.ops.set_channel_count(hdev, cvt->nid, channels);
363 364

	snd_hdac_setup_channel_mapping(&hdmi->chmap, pin->nid, false, ca,
365
				pcm->channels, pcm->chmap, pcm->chmap_set);
366

367
	eld_buf = port->eld.eld_buffer;
368
	conn_type = drm_eld_get_conn_type(eld_buf);
369

370 371 372 373 374
	switch (conn_type) {
	case DRM_ELD_CONN_TYPE_HDMI:
		hdmi_audio_infoframe_init(&frame);

		frame.channels = channels;
375
		frame.channel_allocation = ca;
376 377 378 379

		ret = hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer));
		if (ret < 0)
			return ret;
380

381 382 383 384 385 386 387 388
		break;

	case DRM_ELD_CONN_TYPE_DP:
		memset(&dp_ai, 0, sizeof(dp_ai));
		dp_ai.type	= 0x84;
		dp_ai.len	= 0x1b;
		dp_ai.ver	= 0x11 << 2;
		dp_ai.CC02_CT47	= channels - 1;
389
		dp_ai.CA	= ca;
390 391 392 393 394

		dip = (u8 *)&dp_ai;
		break;

	default:
395
		dev_err(&hdev->dev, "Invalid connection type: %d\n", conn_type);
396 397
		return -EIO;
	}
398 399

	/* stop infoframe transmission */
400 401
	hdac_hdmi_set_dip_index(hdev, pin->nid, 0x0, 0x0);
	snd_hdac_codec_write(hdev, pin->nid, 0,
402 403 404 405
			AC_VERB_SET_HDMI_DIP_XMIT, AC_DIPXMIT_DISABLE);


	/*  Fill infoframe. Index auto-incremented */
406
	hdac_hdmi_set_dip_index(hdev, pin->nid, 0x0, 0x0);
407
	if (conn_type == DRM_ELD_CONN_TYPE_HDMI) {
408
		for (i = 0; i < sizeof(buffer); i++)
409
			snd_hdac_codec_write(hdev, pin->nid, 0,
410
				AC_VERB_SET_HDMI_DIP_DATA, buffer[i]);
411 412
	} else {
		for (i = 0; i < sizeof(dp_ai); i++)
413
			snd_hdac_codec_write(hdev, pin->nid, 0,
414
				AC_VERB_SET_HDMI_DIP_DATA, dip[i]);
415
	}
416 417

	/* Start infoframe */
418 419
	hdac_hdmi_set_dip_index(hdev, pin->nid, 0x0, 0x0);
	snd_hdac_codec_write(hdev, pin->nid, 0,
420 421 422 423 424
			AC_VERB_SET_HDMI_DIP_XMIT, AC_DIPXMIT_BEST);

	return 0;
}

425 426 427
static int hdac_hdmi_set_tdm_slot(struct snd_soc_dai *dai,
		unsigned int tx_mask, unsigned int rx_mask,
		int slots, int slot_width)
428
{
429 430
	struct hdac_hdmi_priv *hdmi = snd_soc_dai_get_drvdata(dai);
	struct hdac_device *hdev = hdmi->hdev;
431
	struct hdac_hdmi_dai_port_map *dai_map;
432
	struct hdac_hdmi_pcm *pcm;
433

434
	dev_dbg(&hdev->dev, "%s: strm_tag: %d\n", __func__, tx_mask);
435

436
	dai_map = &hdmi->dai_map[dai->id];
437

438
	pcm = hdac_hdmi_get_pcm_from_cvt(hdmi, dai_map->cvt);
439

440 441
	if (pcm)
		pcm->stream_tag = (tx_mask << 4);
442

443
	return 0;
444 445 446 447 448
}

static int hdac_hdmi_set_hw_params(struct snd_pcm_substream *substream,
	struct snd_pcm_hw_params *hparams, struct snd_soc_dai *dai)
{
449 450
	struct hdac_hdmi_priv *hdmi = snd_soc_dai_get_drvdata(dai);
	struct hdac_device *hdev = hdmi->hdev;
451 452
	struct hdac_hdmi_dai_port_map *dai_map;
	struct hdac_hdmi_port *port;
453 454
	struct hdac_hdmi_pcm *pcm;
	int format;
455

456
	dai_map = &hdmi->dai_map[dai->id];
457
	port = dai_map->port;
458

459
	if (!port)
460 461
		return -ENODEV;

462
	if ((!port->eld.monitor_present) || (!port->eld.eld_valid)) {
463
		dev_err(&hdev->dev,
464 465
			"device is not configured for this pin:port%d:%d\n",
					port->pin->nid, port->id);
466 467 468
		return -ENODEV;
	}

469
	format = snd_hdac_calc_stream_format(params_rate(hparams),
470
			params_channels(hparams), params_format(hparams),
471
			dai->driver->playback.sig_bits, 0);
472

473 474
	pcm = hdac_hdmi_get_pcm_from_cvt(hdmi, dai_map->cvt);
	if (!pcm)
475 476
		return -EIO;

477 478
	pcm->format = format;
	pcm->channels = params_channels(hparams);
479 480 481 482

	return 0;
}

483
static int hdac_hdmi_query_port_connlist(struct hdac_device *hdev,
484 485
					struct hdac_hdmi_pin *pin,
					struct hdac_hdmi_port *port)
486
{
487 488
	if (!(get_wcaps(hdev, pin->nid) & AC_WCAP_CONN_LIST)) {
		dev_warn(&hdev->dev,
489
			"HDMI: pin %d wcaps %#x does not support connection list\n",
490
			pin->nid, get_wcaps(hdev, pin->nid));
491 492 493
		return -EINVAL;
	}

494
	if (hdac_hdmi_port_select_set(hdev, port) < 0)
495 496
		return -EIO;

497
	port->num_mux_nids = snd_hdac_get_connections(hdev, pin->nid,
498 499
			port->mux_nids, HDA_MAX_CONNECTIONS);
	if (port->num_mux_nids == 0)
500
		dev_warn(&hdev->dev,
501 502
			"No connections found for pin:port %d:%d\n",
						pin->nid, port->id);
503

504
	dev_dbg(&hdev->dev, "num_mux_nids %d for pin:port %d:%d\n",
505
			port->num_mux_nids, pin->nid, port->id);
506

507
	return port->num_mux_nids;
508 509 510
}

/*
511
 * Query pcm list and return port to which stream is routed.
512
 *
513
 * Also query connection list of the pin, to validate the cvt to port map.
514
 *
515 516
 * Same stream rendering to multiple ports simultaneously can be done
 * possibly, but not supported for now in driver. So return the first port
517 518
 * connected.
 */
519
static struct hdac_hdmi_port *hdac_hdmi_get_port_from_cvt(
520
			struct hdac_device *hdev,
521 522 523 524
			struct hdac_hdmi_priv *hdmi,
			struct hdac_hdmi_cvt *cvt)
{
	struct hdac_hdmi_pcm *pcm;
525
	struct hdac_hdmi_port *port = NULL;
526 527 528 529
	int ret, i;

	list_for_each_entry(pcm, &hdmi->pcm_list, head) {
		if (pcm->cvt == cvt) {
530 531
			if (list_empty(&pcm->port_list))
				continue;
532

533 534
			list_for_each_entry(port, &pcm->port_list, head) {
				mutex_lock(&pcm->lock);
535
				ret = hdac_hdmi_query_port_connlist(hdev,
536 537 538 539 540 541 542 543 544 545 546 547
							port->pin, port);
				mutex_unlock(&pcm->lock);
				if (ret < 0)
					continue;

				for (i = 0; i < port->num_mux_nids; i++) {
					if (port->mux_nids[i] == cvt->nid &&
						port->eld.monitor_present &&
						port->eld.eld_valid)
						return port;
				}
			}
548 549 550 551 552 553
		}
	}

	return NULL;
}

554 555 556 557 558
/*
 * This tries to get a valid pin and set the HW constraints based on the
 * ELD. Even if a valid pin is not found return success so that device open
 * doesn't fail.
 */
559 560 561
static int hdac_hdmi_pcm_open(struct snd_pcm_substream *substream,
			struct snd_soc_dai *dai)
{
562 563
	struct hdac_hdmi_priv *hdmi = snd_soc_dai_get_drvdata(dai);
	struct hdac_device *hdev = hdmi->hdev;
564
	struct hdac_hdmi_dai_port_map *dai_map;
565
	struct hdac_hdmi_cvt *cvt;
566
	struct hdac_hdmi_port *port;
567
	int ret;
568 569 570

	dai_map = &hdmi->dai_map[dai->id];

571
	cvt = dai_map->cvt;
572
	port = hdac_hdmi_get_port_from_cvt(hdev, hdmi, cvt);
573 574 575 576 577

	/*
	 * To make PA and other userland happy.
	 * userland scans devices so returning error does not help.
	 */
578
	if (!port)
579
		return 0;
580 581
	if ((!port->eld.monitor_present) ||
			(!port->eld.eld_valid)) {
582

583
		dev_warn(&hdev->dev,
584 585 586
			"Failed: present?:%d ELD valid?:%d pin:port: %d:%d\n",
			port->eld.monitor_present, port->eld.eld_valid,
			port->pin->nid, port->id);
587

588
		return 0;
589 590
	}

591
	dai_map->port = port;
592

593
	ret = hdac_hdmi_eld_limit_formats(substream->runtime,
594
				port->eld.eld_buffer);
595 596
	if (ret < 0)
		return ret;
597

598
	return snd_pcm_hw_constraint_eld(substream->runtime,
599
				port->eld.eld_buffer);
600 601 602 603 604
}

static void hdac_hdmi_pcm_close(struct snd_pcm_substream *substream,
		struct snd_soc_dai *dai)
{
605
	struct hdac_hdmi_priv *hdmi = snd_soc_dai_get_drvdata(dai);
606
	struct hdac_hdmi_dai_port_map *dai_map;
607
	struct hdac_hdmi_pcm *pcm;
608 609 610

	dai_map = &hdmi->dai_map[dai->id];

611
	pcm = hdac_hdmi_get_pcm_from_cvt(hdmi, dai_map->cvt);
612

613 614 615 616 617 618
	if (pcm) {
		mutex_lock(&pcm->lock);
		pcm->chmap_set = false;
		memset(pcm->chmap, 0, sizeof(pcm->chmap));
		pcm->channels = 0;
		mutex_unlock(&pcm->lock);
619
	}
620

621 622
	if (dai_map->port)
		dai_map->port = NULL;
623 624
}

625
static int
626
hdac_hdmi_query_cvt_params(struct hdac_device *hdev, struct hdac_hdmi_cvt *cvt)
627
{
628
	unsigned int chans;
629
	struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev);
630 631
	int err;

632
	chans = get_wcaps(hdev, cvt->nid);
633 634 635 636 637 638 639
	chans = get_wcaps_channels(chans);

	cvt->params.channels_min = 2;

	cvt->params.channels_max = chans;
	if (chans > hdmi->chmap.channels_max)
		hdmi->chmap.channels_max = chans;
640

641
	err = snd_hdac_query_supported_pcm(hdev, cvt->nid,
642 643 644 645
			&cvt->params.rates,
			&cvt->params.formats,
			&cvt->params.maxbps);
	if (err < 0)
646
		dev_err(&hdev->dev,
647 648 649 650 651 652
			"Failed to query pcm params for nid %d: %d\n",
			cvt->nid, err);

	return err;
}

653
static int hdac_hdmi_fill_widget_info(struct device *dev,
654 655 656 657 658
		struct snd_soc_dapm_widget *w, enum snd_soc_dapm_type id,
		void *priv, const char *wname, const char *stream,
		struct snd_kcontrol_new *wc, int numkc,
		int (*event)(struct snd_soc_dapm_widget *,
		struct snd_kcontrol *, int), unsigned short event_flags)
659 660
{
	w->id = id;
661 662 663 664
	w->name = devm_kstrdup(dev, wname, GFP_KERNEL);
	if (!w->name)
		return -ENOMEM;

665 666 667
	w->sname = stream;
	w->reg = SND_SOC_NOPM;
	w->shift = 0;
668 669 670
	w->kcontrol_news = wc;
	w->num_kcontrols = numkc;
	w->priv = priv;
671 672
	w->event = event;
	w->event_flags = event_flags;
673 674

	return 0;
675 676 677
}

static void hdac_hdmi_fill_route(struct snd_soc_dapm_route *route,
678 679 680
		const char *sink, const char *control, const char *src,
		int (*handler)(struct snd_soc_dapm_widget *src,
			struct snd_soc_dapm_widget *sink))
681 682 683 684
{
	route->sink = sink;
	route->source = src;
	route->control = control;
685
	route->connected = handler;
686 687
}

688
static struct hdac_hdmi_pcm *hdac_hdmi_get_pcm(struct hdac_device *hdev,
689
					struct hdac_hdmi_port *port)
Jeeja KP's avatar
Jeeja KP committed
690
{
691
	struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev);
Jeeja KP's avatar
Jeeja KP committed
692
	struct hdac_hdmi_pcm *pcm = NULL;
693
	struct hdac_hdmi_port *p;
Jeeja KP's avatar
Jeeja KP committed
694 695

	list_for_each_entry(pcm, &hdmi->pcm_list, head) {
696
		if (list_empty(&pcm->port_list))
697 698
			continue;

699 700 701 702
		list_for_each_entry(p, &pcm->port_list, head) {
			if (p->id == port->id && port->pin == p->pin)
				return pcm;
		}
Jeeja KP's avatar
Jeeja KP committed
703 704 705 706 707
	}

	return NULL;
}

708
static void hdac_hdmi_set_power_state(struct hdac_device *hdev,
709 710
			     hda_nid_t nid, unsigned int pwr_state)
{
711 712 713
	int count;
	unsigned int state;

714 715
	if (get_wcaps(hdev, nid) & AC_WCAP_POWER) {
		if (!snd_hdac_check_power_state(hdev, nid, pwr_state)) {
716
			for (count = 0; count < 10; count++) {
717
				snd_hdac_codec_read(hdev, nid, 0,
718 719
						AC_VERB_SET_POWER_STATE,
						pwr_state);
720
				state = snd_hdac_sync_power_state(hdev,
721 722 723 724 725
						nid, pwr_state);
				if (!(state & AC_PWRST_ERROR))
					break;
			}
		}
726 727 728
	}
}

729
static void hdac_hdmi_set_amp(struct hdac_device *hdev,
730 731
				   hda_nid_t nid, int val)
{
732 733
	if (get_wcaps(hdev, nid) & AC_WCAP_OUT_AMP)
		snd_hdac_codec_write(hdev, nid, 0,
734 735 736 737 738 739 740
					AC_VERB_SET_AMP_GAIN_MUTE, val);
}


static int hdac_hdmi_pin_output_widget_event(struct snd_soc_dapm_widget *w,
					struct snd_kcontrol *kc, int event)
{
741
	struct hdac_hdmi_port *port = w->priv;
742
	struct hdac_device *hdev = dev_to_hdac_dev(w->dapm->dev);
743 744
	struct hdac_hdmi_pcm *pcm;

745
	dev_dbg(&hdev->dev, "%s: widget: %s event: %x\n",
746 747
			__func__, w->name, event);

748
	pcm = hdac_hdmi_get_pcm(hdev, port);
749 750 751
	if (!pcm)
		return -EIO;

752
	/* set the device if pin is mst_capable */
753
	if (hdac_hdmi_port_select_set(hdev, port) < 0)
754 755
		return -EIO;

756 757
	switch (event) {
	case SND_SOC_DAPM_PRE_PMU:
758
		hdac_hdmi_set_power_state(hdev, port->pin->nid, AC_PWRST_D0);
759 760

		/* Enable out path for this pin widget */
761
		snd_hdac_codec_write(hdev, port->pin->nid, 0,
762 763
				AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);

764
		hdac_hdmi_set_amp(hdev, port->pin->nid, AMP_OUT_UNMUTE);
765

766
		return hdac_hdmi_setup_audio_infoframe(hdev, pcm, port);
767 768

	case SND_SOC_DAPM_POST_PMD:
769
		hdac_hdmi_set_amp(hdev, port->pin->nid, AMP_OUT_MUTE);
770 771

		/* Disable out path for this pin widget */
772
		snd_hdac_codec_write(hdev, port->pin->nid, 0,
773 774
				AC_VERB_SET_PIN_WIDGET_CONTROL, 0);

775
		hdac_hdmi_set_power_state(hdev, port->pin->nid, AC_PWRST_D3);
776 777 778 779 780 781 782 783 784 785 786
		break;

	}

	return 0;
}

static int hdac_hdmi_cvt_output_widget_event(struct snd_soc_dapm_widget *w,
					struct snd_kcontrol *kc, int event)
{
	struct hdac_hdmi_cvt *cvt = w->priv;
787 788
	struct hdac_device *hdev = dev_to_hdac_dev(w->dapm->dev);
	struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev);
789 790
	struct hdac_hdmi_pcm *pcm;

791
	dev_dbg(&hdev->dev, "%s: widget: %s event: %x\n",
792 793 794 795 796 797 798 799
			__func__, w->name, event);

	pcm = hdac_hdmi_get_pcm_from_cvt(hdmi, cvt);
	if (!pcm)
		return -EIO;

	switch (event) {
	case SND_SOC_DAPM_PRE_PMU:
800
		hdac_hdmi_set_power_state(hdev, cvt->nid, AC_PWRST_D0);
801 802

		/* Enable transmission */
803
		snd_hdac_codec_write(hdev, cvt->nid, 0,
804 805 806
			AC_VERB_SET_DIGI_CONVERT_1, 1);

		/* Category Code (CC) to zero */
807
		snd_hdac_codec_write(hdev, cvt->nid, 0,
808 809
			AC_VERB_SET_DIGI_CONVERT_2, 0);

810
		snd_hdac_codec_write(hdev, cvt->nid, 0,
811
				AC_VERB_SET_CHANNEL_STREAMID, pcm->stream_tag);
812
		snd_hdac_codec_write(hdev, cvt->nid, 0,
813 814 815 816
				AC_VERB_SET_STREAM_FORMAT, pcm->format);
		break;

	case SND_SOC_DAPM_POST_PMD:
817
		snd_hdac_codec_write(hdev, cvt->nid, 0,
818
				AC_VERB_SET_CHANNEL_STREAMID, 0);
819
		snd_hdac_codec_write(hdev, cvt->nid, 0,
820 821
				AC_VERB_SET_STREAM_FORMAT, 0);

822
		hdac_hdmi_set_power_state(hdev, cvt->nid, AC_PWRST_D3);
823 824 825 826 827 828 829 830 831 832
		break;

	}

	return 0;
}

static int hdac_hdmi_pin_mux_widget_event(struct snd_soc_dapm_widget *w,
					struct snd_kcontrol *kc, int event)
{
833
	struct hdac_hdmi_port *port = w->priv;
834
	struct hdac_device *hdev = dev_to_hdac_dev(w->dapm->dev);
835 836
	int mux_idx;

837
	dev_dbg(&hdev->dev, "%s: widget: %s event: %x\n",
838 839 840 841 842 843
			__func__, w->name, event);

	if (!kc)
		kc  = w->kcontrols[0];

	mux_idx = dapm_kcontrol_get_value(kc);
844 845

	/* set the device if pin is mst_capable */
846
	if (hdac_hdmi_port_select_set(hdev, port) < 0)
847 848
		return -EIO;

849
	if (mux_idx > 0) {
850
		snd_hdac_codec_write(hdev, port->pin->nid, 0,
851 852 853 854 855 856
			AC_VERB_SET_CONNECT_SEL, (mux_idx - 1));
	}

	return 0;
}

Jeeja KP's avatar
Jeeja KP committed
857 858 859
/*
 * Based on user selection, map the PINs with the PCMs.
 */
860
static int hdac_hdmi_set_pin_port_mux(struct snd_kcontrol *kcontrol,