2350 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * hdac_hdmi.c - ASoc HDA-HDMI codec driver for Intel platforms4 *5 * Copyright (C) 2014-2015 Intel Corp6 * Author: Samreen Nilofer <samreen.nilofer@intel.com>7 * Subhransu S. Prusty <subhransu.s.prusty@intel.com>8 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~9 *10 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~11 */12 13#include <linux/init.h>14#include <linux/delay.h>15#include <linux/module.h>16#include <linux/pm_runtime.h>17#include <linux/hdmi.h>18#include <drm/drm_edid.h>19#include <drm/drm_eld.h>20#include <sound/pcm_params.h>21#include <sound/jack.h>22#include <sound/soc.h>23#include <sound/hdaudio_ext.h>24#include <sound/hda_i915.h>25#include <sound/pcm_drm_eld.h>26#include <sound/hda_chmap.h>27#include "../../hda/local.h"28#include "hdac_hdmi.h"29 30#define NAME_SIZE 3231 32#define AMP_OUT_MUTE 0xb08033#define AMP_OUT_UNMUTE 0xb00034#define PIN_OUT (AC_PINCTL_OUT_EN)35 36#define HDA_MAX_CONNECTIONS 3237 38#define HDA_MAX_CVTS 339#define HDA_MAX_PORTS 340 41#define ELD_MAX_SIZE 25642#define ELD_FIXED_BYTES 2043 44#define ELD_VER_CEA_861D 245#define ELD_VER_PARTIAL 3146#define ELD_MAX_MNL 1647 48struct hdac_hdmi_cvt_params {49 unsigned int channels_min;50 unsigned int channels_max;51 u32 rates;52 u64 formats;53 unsigned int maxbps;54};55 56struct hdac_hdmi_cvt {57 struct list_head head;58 hda_nid_t nid;59 const char *name;60 struct hdac_hdmi_cvt_params params;61};62 63/* Currently only spk_alloc, more to be added */64struct hdac_hdmi_parsed_eld {65 u8 spk_alloc;66};67 68struct hdac_hdmi_eld {69 bool monitor_present;70 bool eld_valid;71 int eld_size;72 char eld_buffer[ELD_MAX_SIZE];73 struct hdac_hdmi_parsed_eld info;74};75 76struct hdac_hdmi_pin {77 struct list_head head;78 hda_nid_t nid;79 bool mst_capable;80 struct hdac_hdmi_port *ports;81 int num_ports;82 struct hdac_device *hdev;83};84 85struct hdac_hdmi_port {86 struct list_head head;87 int id;88 struct hdac_hdmi_pin *pin;89 int num_mux_nids;90 hda_nid_t mux_nids[HDA_MAX_CONNECTIONS];91 struct hdac_hdmi_eld eld;92 const char *jack_pin;93 bool is_connect;94 struct snd_soc_dapm_context *dapm;95 const char *output_pin;96 struct work_struct dapm_work;97};98 99struct hdac_hdmi_pcm {100 struct list_head head;101 int pcm_id;102 struct list_head port_list;103 struct hdac_hdmi_cvt *cvt;104 struct snd_soc_jack *jack;105 int stream_tag;106 int channels;107 int format;108 bool chmap_set;109 unsigned char chmap[8]; /* ALSA API channel-map */110 struct mutex lock;111 int jack_event;112 struct snd_kcontrol *eld_ctl;113};114 115struct hdac_hdmi_dai_port_map {116 int dai_id;117 struct hdac_hdmi_port *port;118 struct hdac_hdmi_cvt *cvt;119};120 121struct hdac_hdmi_drv_data {122 unsigned int vendor_nid;123};124 125struct hdac_hdmi_priv {126 struct hdac_device *hdev;127 struct snd_soc_component *component;128 struct snd_card *card;129 struct hdac_hdmi_dai_port_map dai_map[HDA_MAX_CVTS];130 struct list_head pin_list;131 struct list_head cvt_list;132 struct list_head pcm_list;133 int num_pin;134 int num_cvt;135 int num_ports;136 struct mutex pin_mutex;137 struct hdac_chmap chmap;138 struct hdac_hdmi_drv_data *drv_data;139 struct snd_soc_dai_driver *dai_drv;140};141 142#define hdev_to_hdmi_priv(_hdev) dev_get_drvdata(&(_hdev)->dev)143 144static struct hdac_hdmi_pcm *145hdac_hdmi_get_pcm_from_cvt(struct hdac_hdmi_priv *hdmi,146 struct hdac_hdmi_cvt *cvt)147{148 struct hdac_hdmi_pcm *pcm;149 150 list_for_each_entry(pcm, &hdmi->pcm_list, head) {151 if (pcm->cvt == cvt)152 return pcm;153 }154 155 return NULL;156}157 158static void hdac_hdmi_jack_report(struct hdac_hdmi_pcm *pcm,159 struct hdac_hdmi_port *port, bool is_connect)160{161 struct hdac_device *hdev = port->pin->hdev;162 163 port->is_connect = is_connect;164 if (is_connect) {165 /*166 * Report Jack connect event when a device is connected167 * for the first time where same PCM is attached to multiple168 * ports.169 */170 if (pcm->jack_event == 0) {171 dev_dbg(&hdev->dev,172 "jack report for pcm=%d\n",173 pcm->pcm_id);174 snd_soc_jack_report(pcm->jack, SND_JACK_AVOUT,175 SND_JACK_AVOUT);176 }177 pcm->jack_event++;178 } else {179 /*180 * Report Jack disconnect event when a device is disconnected181 * is the only last connected device when same PCM is attached182 * to multiple ports.183 */184 if (pcm->jack_event == 1)185 snd_soc_jack_report(pcm->jack, 0, SND_JACK_AVOUT);186 if (pcm->jack_event > 0)187 pcm->jack_event--;188 }189}190 191static void hdac_hdmi_port_dapm_update(struct hdac_hdmi_port *port)192{193 if (port->is_connect)194 snd_soc_dapm_enable_pin(port->dapm, port->jack_pin);195 else196 snd_soc_dapm_disable_pin(port->dapm, port->jack_pin);197 snd_soc_dapm_sync(port->dapm);198}199 200static void hdac_hdmi_jack_dapm_work(struct work_struct *work)201{202 struct hdac_hdmi_port *port;203 204 port = container_of(work, struct hdac_hdmi_port, dapm_work);205 hdac_hdmi_port_dapm_update(port);206}207 208static void hdac_hdmi_jack_report_sync(struct hdac_hdmi_pcm *pcm,209 struct hdac_hdmi_port *port, bool is_connect)210{211 hdac_hdmi_jack_report(pcm, port, is_connect);212 hdac_hdmi_port_dapm_update(port);213}214 215/* MST supported verbs */216/*217 * Get the no devices that can be connected to a port on the Pin widget.218 */219static int hdac_hdmi_get_port_len(struct hdac_device *hdev, hda_nid_t nid)220{221 unsigned int caps;222 unsigned int type, param;223 224 caps = get_wcaps(hdev, nid);225 type = get_wcaps_type(caps);226 227 if (!(caps & AC_WCAP_DIGITAL) || (type != AC_WID_PIN))228 return 0;229 230 param = snd_hdac_read_parm_uncached(hdev, nid, AC_PAR_DEVLIST_LEN);231 if (param == -1)232 return param;233 234 return param & AC_DEV_LIST_LEN_MASK;235}236 237/*238 * Get the port entry select on the pin. Return the port entry239 * id selected on the pin. Return 0 means the first port entry240 * is selected or MST is not supported.241 */242static int hdac_hdmi_port_select_get(struct hdac_device *hdev,243 struct hdac_hdmi_port *port)244{245 return snd_hdac_codec_read(hdev, port->pin->nid,246 0, AC_VERB_GET_DEVICE_SEL, 0);247}248 249/*250 * Sets the selected port entry for the configuring Pin widget verb.251 * returns error if port set is not equal to port get otherwise success252 */253static int hdac_hdmi_port_select_set(struct hdac_device *hdev,254 struct hdac_hdmi_port *port)255{256 int num_ports;257 258 if (!port->pin->mst_capable)259 return 0;260 261 /* AC_PAR_DEVLIST_LEN is 0 based. */262 num_ports = hdac_hdmi_get_port_len(hdev, port->pin->nid);263 if (num_ports < 0)264 return -EIO;265 /*266 * Device List Length is a 0 based integer value indicating the267 * number of sink device that a MST Pin Widget can support.268 */269 if (num_ports + 1 < port->id)270 return 0;271 272 snd_hdac_codec_write(hdev, port->pin->nid, 0,273 AC_VERB_SET_DEVICE_SEL, port->id);274 275 if (port->id != hdac_hdmi_port_select_get(hdev, port))276 return -EIO;277 278 dev_dbg(&hdev->dev, "Selected the port=%d\n", port->id);279 280 return 0;281}282 283static struct hdac_hdmi_pcm *get_hdmi_pcm_from_id(struct hdac_hdmi_priv *hdmi,284 int pcm_idx)285{286 struct hdac_hdmi_pcm *pcm;287 288 list_for_each_entry(pcm, &hdmi->pcm_list, head) {289 if (pcm->pcm_id == pcm_idx)290 return pcm;291 }292 293 return NULL;294}295 296static unsigned int sad_format(const u8 *sad)297{298 return ((sad[0] >> 0x3) & 0x1f);299}300 301static unsigned int sad_sample_bits_lpcm(const u8 *sad)302{303 return (sad[2] & 7);304}305 306static int hdac_hdmi_eld_limit_formats(struct snd_pcm_runtime *runtime,307 void *eld)308{309 u64 formats = SNDRV_PCM_FMTBIT_S16;310 int i;311 const u8 *sad, *eld_buf = eld;312 313 sad = drm_eld_sad(eld_buf);314 if (!sad)315 goto format_constraint;316 317 for (i = drm_eld_sad_count(eld_buf); i > 0; i--, sad += 3) {318 if (sad_format(sad) == 1) { /* AUDIO_CODING_TYPE_LPCM */319 320 /*321 * the controller support 20 and 24 bits in 32 bit322 * container so we set S32323 */324 if (sad_sample_bits_lpcm(sad) & 0x6)325 formats |= SNDRV_PCM_FMTBIT_S32;326 }327 }328 329format_constraint:330 return snd_pcm_hw_constraint_mask64(runtime, SNDRV_PCM_HW_PARAM_FORMAT,331 formats);332 333}334 335static void336hdac_hdmi_set_dip_index(struct hdac_device *hdev, hda_nid_t pin_nid,337 int packet_index, int byte_index)338{339 int val;340 341 val = (packet_index << 5) | (byte_index & 0x1f);342 snd_hdac_codec_write(hdev, pin_nid, 0, AC_VERB_SET_HDMI_DIP_INDEX, val);343}344 345struct dp_audio_infoframe {346 u8 type; /* 0x84 */347 u8 len; /* 0x1b */348 u8 ver; /* 0x11 << 2 */349 350 u8 CC02_CT47; /* match with HDMI infoframe from this on */351 u8 SS01_SF24;352 u8 CXT04;353 u8 CA;354 u8 LFEPBL01_LSV36_DM_INH7;355};356 357static int hdac_hdmi_setup_audio_infoframe(struct hdac_device *hdev,358 struct hdac_hdmi_pcm *pcm, struct hdac_hdmi_port *port)359{360 uint8_t buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AUDIO_INFOFRAME_SIZE];361 struct hdmi_audio_infoframe frame;362 struct hdac_hdmi_pin *pin = port->pin;363 struct dp_audio_infoframe dp_ai;364 struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev);365 struct hdac_hdmi_cvt *cvt = pcm->cvt;366 u8 *dip;367 int ret;368 int i;369 const u8 *eld_buf;370 u8 conn_type;371 int channels, ca;372 373 ca = snd_hdac_channel_allocation(hdev, port->eld.info.spk_alloc,374 pcm->channels, pcm->chmap_set, true, pcm->chmap);375 376 channels = snd_hdac_get_active_channels(ca);377 hdmi->chmap.ops.set_channel_count(hdev, cvt->nid, channels);378 379 snd_hdac_setup_channel_mapping(&hdmi->chmap, pin->nid, false, ca,380 pcm->channels, pcm->chmap, pcm->chmap_set);381 382 eld_buf = port->eld.eld_buffer;383 conn_type = drm_eld_get_conn_type(eld_buf);384 385 switch (conn_type) {386 case DRM_ELD_CONN_TYPE_HDMI:387 hdmi_audio_infoframe_init(&frame);388 389 frame.channels = channels;390 frame.channel_allocation = ca;391 392 ret = hdmi_audio_infoframe_pack(&frame, buffer, sizeof(buffer));393 if (ret < 0)394 return ret;395 396 break;397 398 case DRM_ELD_CONN_TYPE_DP:399 memset(&dp_ai, 0, sizeof(dp_ai));400 dp_ai.type = 0x84;401 dp_ai.len = 0x1b;402 dp_ai.ver = 0x11 << 2;403 dp_ai.CC02_CT47 = channels - 1;404 dp_ai.CA = ca;405 406 dip = (u8 *)&dp_ai;407 break;408 409 default:410 dev_err(&hdev->dev, "Invalid connection type: %d\n", conn_type);411 return -EIO;412 }413 414 /* stop infoframe transmission */415 hdac_hdmi_set_dip_index(hdev, pin->nid, 0x0, 0x0);416 snd_hdac_codec_write(hdev, pin->nid, 0,417 AC_VERB_SET_HDMI_DIP_XMIT, AC_DIPXMIT_DISABLE);418 419 420 /* Fill infoframe. Index auto-incremented */421 hdac_hdmi_set_dip_index(hdev, pin->nid, 0x0, 0x0);422 if (conn_type == DRM_ELD_CONN_TYPE_HDMI) {423 for (i = 0; i < sizeof(buffer); i++)424 snd_hdac_codec_write(hdev, pin->nid, 0,425 AC_VERB_SET_HDMI_DIP_DATA, buffer[i]);426 } else {427 for (i = 0; i < sizeof(dp_ai); i++)428 snd_hdac_codec_write(hdev, pin->nid, 0,429 AC_VERB_SET_HDMI_DIP_DATA, dip[i]);430 }431 432 /* Start infoframe */433 hdac_hdmi_set_dip_index(hdev, pin->nid, 0x0, 0x0);434 snd_hdac_codec_write(hdev, pin->nid, 0,435 AC_VERB_SET_HDMI_DIP_XMIT, AC_DIPXMIT_BEST);436 437 return 0;438}439 440static int hdac_hdmi_set_stream(struct snd_soc_dai *dai,441 void *stream, int direction)442{443 struct hdac_hdmi_priv *hdmi = snd_soc_dai_get_drvdata(dai);444 struct hdac_device *hdev = hdmi->hdev;445 struct hdac_hdmi_dai_port_map *dai_map;446 struct hdac_hdmi_pcm *pcm;447 struct hdac_stream *hstream;448 449 if (!stream)450 return -EINVAL;451 452 hstream = (struct hdac_stream *)stream;453 454 dev_dbg(&hdev->dev, "%s: strm_tag: %d\n", __func__, hstream->stream_tag);455 456 dai_map = &hdmi->dai_map[dai->id];457 458 pcm = hdac_hdmi_get_pcm_from_cvt(hdmi, dai_map->cvt);459 460 if (pcm)461 pcm->stream_tag = (hstream->stream_tag << 4);462 463 return 0;464}465 466static int hdac_hdmi_set_hw_params(struct snd_pcm_substream *substream,467 struct snd_pcm_hw_params *hparams, struct snd_soc_dai *dai)468{469 struct hdac_hdmi_priv *hdmi = snd_soc_dai_get_drvdata(dai);470 struct hdac_hdmi_dai_port_map *dai_map;471 struct hdac_hdmi_pcm *pcm;472 unsigned int bits;473 int format;474 475 dai_map = &hdmi->dai_map[dai->id];476 477 bits = snd_hdac_stream_format_bits(params_format(hparams), SNDRV_PCM_SUBFORMAT_STD,478 dai->driver->playback.sig_bits);479 format = snd_hdac_stream_format(params_channels(hparams), bits, params_rate(hparams));480 481 pcm = hdac_hdmi_get_pcm_from_cvt(hdmi, dai_map->cvt);482 if (!pcm)483 return -EIO;484 485 pcm->format = format;486 pcm->channels = params_channels(hparams);487 488 return 0;489}490 491static int hdac_hdmi_query_port_connlist(struct hdac_device *hdev,492 struct hdac_hdmi_pin *pin,493 struct hdac_hdmi_port *port)494{495 if (!(get_wcaps(hdev, pin->nid) & AC_WCAP_CONN_LIST)) {496 dev_warn(&hdev->dev,497 "HDMI: pin %d wcaps %#x does not support connection list\n",498 pin->nid, get_wcaps(hdev, pin->nid));499 return -EINVAL;500 }501 502 if (hdac_hdmi_port_select_set(hdev, port) < 0)503 return -EIO;504 505 port->num_mux_nids = snd_hdac_get_connections(hdev, pin->nid,506 port->mux_nids, HDA_MAX_CONNECTIONS);507 if (port->num_mux_nids == 0)508 dev_warn(&hdev->dev,509 "No connections found for pin:port %d:%d\n",510 pin->nid, port->id);511 512 dev_dbg(&hdev->dev, "num_mux_nids %d for pin:port %d:%d\n",513 port->num_mux_nids, pin->nid, port->id);514 515 return port->num_mux_nids;516}517 518/*519 * Query pcm list and return port to which stream is routed.520 *521 * Also query connection list of the pin, to validate the cvt to port map.522 *523 * Same stream rendering to multiple ports simultaneously can be done524 * possibly, but not supported for now in driver. So return the first port525 * connected.526 */527static struct hdac_hdmi_port *hdac_hdmi_get_port_from_cvt(528 struct hdac_device *hdev,529 struct hdac_hdmi_priv *hdmi,530 struct hdac_hdmi_cvt *cvt)531{532 struct hdac_hdmi_pcm *pcm;533 struct hdac_hdmi_port *port;534 int ret, i;535 536 list_for_each_entry(pcm, &hdmi->pcm_list, head) {537 if (pcm->cvt == cvt) {538 if (list_empty(&pcm->port_list))539 continue;540 541 list_for_each_entry(port, &pcm->port_list, head) {542 mutex_lock(&pcm->lock);543 ret = hdac_hdmi_query_port_connlist(hdev,544 port->pin, port);545 mutex_unlock(&pcm->lock);546 if (ret < 0)547 continue;548 549 for (i = 0; i < port->num_mux_nids; i++) {550 if (port->mux_nids[i] == cvt->nid &&551 port->eld.monitor_present &&552 port->eld.eld_valid)553 return port;554 }555 }556 }557 }558 559 return NULL;560}561 562/*563 * Go through all converters and ensure connection is set to564 * the correct pin as set via kcontrols.565 */566static void hdac_hdmi_verify_connect_sel_all_pins(struct hdac_device *hdev)567{568 struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev);569 struct hdac_hdmi_port *port;570 struct hdac_hdmi_cvt *cvt;571 int cvt_idx = 0;572 573 list_for_each_entry(cvt, &hdmi->cvt_list, head) {574 port = hdac_hdmi_get_port_from_cvt(hdev, hdmi, cvt);575 if (port && port->pin) {576 snd_hdac_codec_write(hdev, port->pin->nid, 0,577 AC_VERB_SET_CONNECT_SEL, cvt_idx);578 dev_dbg(&hdev->dev, "%s: %s set connect %d -> %d\n",579 __func__, cvt->name, port->pin->nid, cvt_idx);580 }581 ++cvt_idx;582 }583}584 585/*586 * This tries to get a valid pin and set the HW constraints based on the587 * ELD. Even if a valid pin is not found return success so that device open588 * doesn't fail.589 */590static int hdac_hdmi_pcm_open(struct snd_pcm_substream *substream,591 struct snd_soc_dai *dai)592{593 struct hdac_hdmi_priv *hdmi = snd_soc_dai_get_drvdata(dai);594 struct hdac_device *hdev = hdmi->hdev;595 struct hdac_hdmi_dai_port_map *dai_map;596 struct hdac_hdmi_cvt *cvt;597 struct hdac_hdmi_port *port;598 int ret;599 600 dai_map = &hdmi->dai_map[dai->id];601 602 cvt = dai_map->cvt;603 port = hdac_hdmi_get_port_from_cvt(hdev, hdmi, cvt);604 605 /*606 * To make PA and other userland happy.607 * userland scans devices so returning error does not help.608 */609 if (!port)610 return 0;611 if ((!port->eld.monitor_present) ||612 (!port->eld.eld_valid)) {613 614 dev_warn(&hdev->dev,615 "Failed: present?:%d ELD valid?:%d pin:port: %d:%d\n",616 port->eld.monitor_present, port->eld.eld_valid,617 port->pin->nid, port->id);618 619 return 0;620 }621 622 dai_map->port = port;623 624 ret = hdac_hdmi_eld_limit_formats(substream->runtime,625 port->eld.eld_buffer);626 if (ret < 0)627 return ret;628 629 return snd_pcm_hw_constraint_eld(substream->runtime,630 port->eld.eld_buffer);631}632 633static void hdac_hdmi_pcm_close(struct snd_pcm_substream *substream,634 struct snd_soc_dai *dai)635{636 struct hdac_hdmi_priv *hdmi = snd_soc_dai_get_drvdata(dai);637 struct hdac_hdmi_dai_port_map *dai_map;638 struct hdac_hdmi_pcm *pcm;639 640 dai_map = &hdmi->dai_map[dai->id];641 642 pcm = hdac_hdmi_get_pcm_from_cvt(hdmi, dai_map->cvt);643 644 if (pcm) {645 mutex_lock(&pcm->lock);646 pcm->chmap_set = false;647 memset(pcm->chmap, 0, sizeof(pcm->chmap));648 pcm->channels = 0;649 mutex_unlock(&pcm->lock);650 }651 652 if (dai_map->port)653 dai_map->port = NULL;654}655 656static int657hdac_hdmi_query_cvt_params(struct hdac_device *hdev, struct hdac_hdmi_cvt *cvt)658{659 unsigned int chans;660 struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev);661 int err;662 663 chans = get_wcaps(hdev, cvt->nid);664 chans = get_wcaps_channels(chans);665 666 cvt->params.channels_min = 2;667 668 cvt->params.channels_max = chans;669 if (chans > hdmi->chmap.channels_max)670 hdmi->chmap.channels_max = chans;671 672 err = snd_hdac_query_supported_pcm(hdev, cvt->nid,673 &cvt->params.rates,674 &cvt->params.formats,675 NULL,676 &cvt->params.maxbps);677 if (err < 0)678 dev_err(&hdev->dev,679 "Failed to query pcm params for nid %d: %d\n",680 cvt->nid, err);681 682 return err;683}684 685static int hdac_hdmi_fill_widget_info(struct device *dev,686 struct snd_soc_dapm_widget *w, enum snd_soc_dapm_type id,687 void *priv, const char *wname, const char *stream,688 struct snd_kcontrol_new *wc, int numkc,689 int (*event)(struct snd_soc_dapm_widget *,690 struct snd_kcontrol *, int), unsigned short event_flags)691{692 w->id = id;693 w->name = devm_kstrdup(dev, wname, GFP_KERNEL);694 if (!w->name)695 return -ENOMEM;696 697 w->sname = stream;698 w->reg = SND_SOC_NOPM;699 w->shift = 0;700 w->kcontrol_news = wc;701 w->num_kcontrols = numkc;702 w->priv = priv;703 w->event = event;704 w->event_flags = event_flags;705 706 return 0;707}708 709static void hdac_hdmi_fill_route(struct snd_soc_dapm_route *route,710 const char *sink, const char *control, const char *src,711 int (*handler)(struct snd_soc_dapm_widget *src,712 struct snd_soc_dapm_widget *sink))713{714 route->sink = sink;715 route->source = src;716 route->control = control;717 route->connected = handler;718}719 720static struct hdac_hdmi_pcm *hdac_hdmi_get_pcm(struct hdac_device *hdev,721 struct hdac_hdmi_port *port)722{723 struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev);724 struct hdac_hdmi_pcm *pcm;725 struct hdac_hdmi_port *p;726 727 list_for_each_entry(pcm, &hdmi->pcm_list, head) {728 if (list_empty(&pcm->port_list))729 continue;730 731 list_for_each_entry(p, &pcm->port_list, head) {732 if (p->id == port->id && port->pin == p->pin)733 return pcm;734 }735 }736 737 return NULL;738}739 740static void hdac_hdmi_set_power_state(struct hdac_device *hdev,741 hda_nid_t nid, unsigned int pwr_state)742{743 int count;744 unsigned int state;745 746 if (get_wcaps(hdev, nid) & AC_WCAP_POWER) {747 if (!snd_hdac_check_power_state(hdev, nid, pwr_state)) {748 for (count = 0; count < 10; count++) {749 snd_hdac_codec_read(hdev, nid, 0,750 AC_VERB_SET_POWER_STATE,751 pwr_state);752 state = snd_hdac_sync_power_state(hdev,753 nid, pwr_state);754 if (!(state & AC_PWRST_ERROR))755 break;756 }757 }758 }759}760 761static void hdac_hdmi_set_amp(struct hdac_device *hdev,762 hda_nid_t nid, int val)763{764 if (get_wcaps(hdev, nid) & AC_WCAP_OUT_AMP)765 snd_hdac_codec_write(hdev, nid, 0,766 AC_VERB_SET_AMP_GAIN_MUTE, val);767}768 769 770static int hdac_hdmi_pin_output_widget_event(struct snd_soc_dapm_widget *w,771 struct snd_kcontrol *kc, int event)772{773 struct hdac_hdmi_port *port = w->priv;774 struct hdac_device *hdev = dev_to_hdac_dev(w->dapm->dev);775 struct hdac_hdmi_pcm *pcm;776 777 dev_dbg(&hdev->dev, "%s: widget: %s event: %x\n",778 __func__, w->name, event);779 780 pcm = hdac_hdmi_get_pcm(hdev, port);781 if (!pcm)782 return -EIO;783 784 /* set the device if pin is mst_capable */785 if (hdac_hdmi_port_select_set(hdev, port) < 0)786 return -EIO;787 788 switch (event) {789 case SND_SOC_DAPM_PRE_PMU:790 hdac_hdmi_set_power_state(hdev, port->pin->nid, AC_PWRST_D0);791 792 /* Enable out path for this pin widget */793 snd_hdac_codec_write(hdev, port->pin->nid, 0,794 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);795 796 hdac_hdmi_set_amp(hdev, port->pin->nid, AMP_OUT_UNMUTE);797 798 return hdac_hdmi_setup_audio_infoframe(hdev, pcm, port);799 800 case SND_SOC_DAPM_POST_PMD:801 hdac_hdmi_set_amp(hdev, port->pin->nid, AMP_OUT_MUTE);802 803 /* Disable out path for this pin widget */804 snd_hdac_codec_write(hdev, port->pin->nid, 0,805 AC_VERB_SET_PIN_WIDGET_CONTROL, 0);806 807 hdac_hdmi_set_power_state(hdev, port->pin->nid, AC_PWRST_D3);808 break;809 810 }811 812 return 0;813}814 815static int hdac_hdmi_cvt_output_widget_event(struct snd_soc_dapm_widget *w,816 struct snd_kcontrol *kc, int event)817{818 struct hdac_hdmi_cvt *cvt = w->priv;819 struct hdac_device *hdev = dev_to_hdac_dev(w->dapm->dev);820 struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev);821 struct hdac_hdmi_pcm *pcm;822 823 dev_dbg(&hdev->dev, "%s: widget: %s event: %x\n",824 __func__, w->name, event);825 826 pcm = hdac_hdmi_get_pcm_from_cvt(hdmi, cvt);827 if (!pcm)828 return -EIO;829 830 switch (event) {831 case SND_SOC_DAPM_PRE_PMU:832 hdac_hdmi_set_power_state(hdev, cvt->nid, AC_PWRST_D0);833 834 /* Enable transmission */835 snd_hdac_codec_write(hdev, cvt->nid, 0,836 AC_VERB_SET_DIGI_CONVERT_1, 1);837 838 /* Category Code (CC) to zero */839 snd_hdac_codec_write(hdev, cvt->nid, 0,840 AC_VERB_SET_DIGI_CONVERT_2, 0);841 842 snd_hdac_codec_write(hdev, cvt->nid, 0,843 AC_VERB_SET_CHANNEL_STREAMID, pcm->stream_tag);844 snd_hdac_codec_write(hdev, cvt->nid, 0,845 AC_VERB_SET_STREAM_FORMAT, pcm->format);846 847 /*848 * The connection indices are shared by all converters and849 * may interfere with each other. Ensure correct850 * routing for all converters at stream start.851 */852 hdac_hdmi_verify_connect_sel_all_pins(hdev);853 854 break;855 856 case SND_SOC_DAPM_POST_PMD:857 snd_hdac_codec_write(hdev, cvt->nid, 0,858 AC_VERB_SET_CHANNEL_STREAMID, 0);859 snd_hdac_codec_write(hdev, cvt->nid, 0,860 AC_VERB_SET_STREAM_FORMAT, 0);861 862 hdac_hdmi_set_power_state(hdev, cvt->nid, AC_PWRST_D3);863 break;864 865 }866 867 return 0;868}869 870static int hdac_hdmi_pin_mux_widget_event(struct snd_soc_dapm_widget *w,871 struct snd_kcontrol *kc, int event)872{873 struct hdac_hdmi_port *port = w->priv;874 struct hdac_device *hdev = dev_to_hdac_dev(w->dapm->dev);875 int mux_idx;876 877 dev_dbg(&hdev->dev, "%s: widget: %s event: %x\n",878 __func__, w->name, event);879 880 if (!kc)881 kc = w->kcontrols[0];882 883 mux_idx = dapm_kcontrol_get_value(kc);884 885 /* set the device if pin is mst_capable */886 if (hdac_hdmi_port_select_set(hdev, port) < 0)887 return -EIO;888 889 if (mux_idx > 0) {890 snd_hdac_codec_write(hdev, port->pin->nid, 0,891 AC_VERB_SET_CONNECT_SEL, (mux_idx - 1));892 }893 894 return 0;895}896 897/*898 * Based on user selection, map the PINs with the PCMs.899 */900static int hdac_hdmi_set_pin_port_mux(struct snd_kcontrol *kcontrol,901 struct snd_ctl_elem_value *ucontrol)902{903 int ret;904 struct hdac_hdmi_port *p, *p_next;905 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;906 struct snd_soc_dapm_widget *w = snd_soc_dapm_kcontrol_widget(kcontrol);907 struct snd_soc_dapm_context *dapm = w->dapm;908 struct hdac_hdmi_port *port = w->priv;909 struct hdac_device *hdev = dev_to_hdac_dev(dapm->dev);910 struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev);911 struct hdac_hdmi_pcm *pcm;912 const char *cvt_name = e->texts[ucontrol->value.enumerated.item[0]];913 914 ret = snd_soc_dapm_put_enum_double(kcontrol, ucontrol);915 if (ret < 0)916 return ret;917 918 if (port == NULL)919 return -EINVAL;920 921 mutex_lock(&hdmi->pin_mutex);922 list_for_each_entry(pcm, &hdmi->pcm_list, head) {923 if (list_empty(&pcm->port_list))924 continue;925 926 list_for_each_entry_safe(p, p_next, &pcm->port_list, head) {927 if (p == port && p->id == port->id &&928 p->pin == port->pin) {929 hdac_hdmi_jack_report_sync(pcm, port, false);930 list_del(&p->head);931 }932 }933 }934 935 /*936 * Jack status is not reported during device probe as the937 * PCMs are not registered by then. So report it here.938 */939 list_for_each_entry(pcm, &hdmi->pcm_list, head) {940 if (!strcmp(cvt_name, pcm->cvt->name)) {941 list_add_tail(&port->head, &pcm->port_list);942 if (port->eld.monitor_present && port->eld.eld_valid) {943 hdac_hdmi_jack_report_sync(pcm, port, true);944 mutex_unlock(&hdmi->pin_mutex);945 return ret;946 }947 }948 }949 mutex_unlock(&hdmi->pin_mutex);950 951 return ret;952}953 954/*955 * Ideally the Mux inputs should be based on the num_muxs enumerated, but956 * the display driver seem to be programming the connection list for the pin957 * widget runtime.958 *959 * So programming all the possible inputs for the mux, the user has to take960 * care of selecting the right one and leaving all other inputs selected to961 * "NONE"962 */963static int hdac_hdmi_create_pin_port_muxs(struct hdac_device *hdev,964 struct hdac_hdmi_port *port,965 struct snd_soc_dapm_widget *widget,966 const char *widget_name)967{968 struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev);969 struct hdac_hdmi_pin *pin = port->pin;970 struct snd_kcontrol_new *kc;971 struct hdac_hdmi_cvt *cvt;972 struct soc_enum *se;973 char kc_name[NAME_SIZE];974 char mux_items[NAME_SIZE];975 /* To hold inputs to the Pin mux */976 char *items[HDA_MAX_CONNECTIONS];977 int i = 0;978 int num_items = hdmi->num_cvt + 1;979 980 kc = devm_kzalloc(&hdev->dev, sizeof(*kc), GFP_KERNEL);981 if (!kc)982 return -ENOMEM;983 984 se = devm_kzalloc(&hdev->dev, sizeof(*se), GFP_KERNEL);985 if (!se)986 return -ENOMEM;987 988 snprintf(kc_name, NAME_SIZE, "Pin %d port %d Input",989 pin->nid, port->id);990 kc->name = devm_kstrdup(&hdev->dev, kc_name, GFP_KERNEL);991 if (!kc->name)992 return -ENOMEM;993 994 kc->private_value = (long)se;995 kc->iface = SNDRV_CTL_ELEM_IFACE_MIXER;996 kc->access = 0;997 kc->info = snd_soc_info_enum_double;998 kc->put = hdac_hdmi_set_pin_port_mux;999 kc->get = snd_soc_dapm_get_enum_double;1000 1001 se->reg = SND_SOC_NOPM;1002 1003 /* enum texts: ["NONE", "cvt #", "cvt #", ...] */1004 se->items = num_items;1005 se->mask = roundup_pow_of_two(se->items) - 1;1006 1007 sprintf(mux_items, "NONE");1008 items[i] = devm_kstrdup(&hdev->dev, mux_items, GFP_KERNEL);1009 if (!items[i])1010 return -ENOMEM;1011 1012 list_for_each_entry(cvt, &hdmi->cvt_list, head) {1013 i++;1014 sprintf(mux_items, "cvt %d", cvt->nid);1015 items[i] = devm_kstrdup(&hdev->dev, mux_items, GFP_KERNEL);1016 if (!items[i])1017 return -ENOMEM;1018 }1019 1020 se->texts = devm_kmemdup(&hdev->dev, items,1021 (num_items * sizeof(char *)), GFP_KERNEL);1022 if (!se->texts)1023 return -ENOMEM;1024 1025 return hdac_hdmi_fill_widget_info(&hdev->dev, widget,1026 snd_soc_dapm_mux, port, widget_name, NULL, kc, 1,1027 hdac_hdmi_pin_mux_widget_event,1028 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_REG);1029}1030 1031/* Add cvt <- input <- mux route map */1032static void hdac_hdmi_add_pinmux_cvt_route(struct hdac_device *hdev,1033 struct snd_soc_dapm_widget *widgets,1034 struct snd_soc_dapm_route *route, int rindex)1035{1036 struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev);1037 const struct snd_kcontrol_new *kc;1038 struct soc_enum *se;1039 int mux_index = hdmi->num_cvt + hdmi->num_ports;1040 int i, j;1041 1042 for (i = 0; i < hdmi->num_ports; i++) {1043 kc = widgets[mux_index].kcontrol_news;1044 se = (struct soc_enum *)kc->private_value;1045 for (j = 0; j < hdmi->num_cvt; j++) {1046 hdac_hdmi_fill_route(&route[rindex],1047 widgets[mux_index].name,1048 se->texts[j + 1],1049 widgets[j].name, NULL);1050 1051 rindex++;1052 }1053 1054 mux_index++;1055 }1056}1057 1058/*1059 * Widgets are added in the below sequence1060 * Converter widgets for num converters enumerated1061 * Pin-port widgets for num ports for Pins enumerated1062 * Pin-port mux widgets to represent connenction list of pin widget1063 *1064 * For each port, one Mux and One output widget is added1065 * Total widgets elements = num_cvt + (num_ports * 2);1066 *1067 * Routes are added as below:1068 * pin-port mux -> pin (based on num_ports)1069 * cvt -> "Input sel control" -> pin-port_mux1070 *1071 * Total route elements:1072 * num_ports + (pin_muxes * num_cvt)1073 */1074static int create_fill_widget_route_map(struct snd_soc_dapm_context *dapm)1075{1076 struct snd_soc_dapm_widget *widgets;1077 struct snd_soc_dapm_route *route;1078 struct hdac_device *hdev = dev_to_hdac_dev(dapm->dev);1079 struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev);1080 struct snd_soc_dai_driver *dai_drv = hdmi->dai_drv;1081 char widget_name[NAME_SIZE];1082 struct hdac_hdmi_cvt *cvt;1083 struct hdac_hdmi_pin *pin;1084 int ret, i = 0, num_routes = 0, j;1085 1086 if (list_empty(&hdmi->cvt_list) || list_empty(&hdmi->pin_list))1087 return -EINVAL;1088 1089 widgets = devm_kzalloc(dapm->dev, (sizeof(*widgets) *1090 ((2 * hdmi->num_ports) + hdmi->num_cvt)),1091 GFP_KERNEL);1092 1093 if (!widgets)1094 return -ENOMEM;1095 1096 /* DAPM widgets to represent each converter widget */1097 list_for_each_entry(cvt, &hdmi->cvt_list, head) {1098 sprintf(widget_name, "Converter %d", cvt->nid);1099 ret = hdac_hdmi_fill_widget_info(dapm->dev, &widgets[i],1100 snd_soc_dapm_aif_in, cvt,1101 widget_name, dai_drv[i].playback.stream_name, NULL, 0,1102 hdac_hdmi_cvt_output_widget_event,1103 SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD);1104 if (ret < 0)1105 return ret;1106 i++;1107 }1108 1109 list_for_each_entry(pin, &hdmi->pin_list, head) {1110 for (j = 0; j < pin->num_ports; j++) {1111 sprintf(widget_name, "hif%d-%d Output",1112 pin->nid, pin->ports[j].id);1113 ret = hdac_hdmi_fill_widget_info(dapm->dev, &widgets[i],1114 snd_soc_dapm_output, &pin->ports[j],1115 widget_name, NULL, NULL, 0,1116 hdac_hdmi_pin_output_widget_event,1117 SND_SOC_DAPM_PRE_PMU |1118 SND_SOC_DAPM_POST_PMD);1119 if (ret < 0)1120 return ret;1121 pin->ports[j].output_pin = widgets[i].name;1122 i++;1123 }1124 }1125 1126 /* DAPM widgets to represent the connection list to pin widget */1127 list_for_each_entry(pin, &hdmi->pin_list, head) {1128 for (j = 0; j < pin->num_ports; j++) {1129 sprintf(widget_name, "Pin%d-Port%d Mux",1130 pin->nid, pin->ports[j].id);1131 ret = hdac_hdmi_create_pin_port_muxs(hdev,1132 &pin->ports[j], &widgets[i],1133 widget_name);1134 if (ret < 0)1135 return ret;1136 i++;1137 1138 /* For cvt to pin_mux mapping */1139 num_routes += hdmi->num_cvt;1140 1141 /* For pin_mux to pin mapping */1142 num_routes++;1143 }1144 }1145 1146 route = devm_kzalloc(dapm->dev, (sizeof(*route) * num_routes),1147 GFP_KERNEL);1148 if (!route)1149 return -ENOMEM;1150 1151 i = 0;1152 /* Add pin <- NULL <- mux route map */1153 list_for_each_entry(pin, &hdmi->pin_list, head) {1154 for (j = 0; j < pin->num_ports; j++) {1155 int sink_index = i + hdmi->num_cvt;1156 int src_index = sink_index + pin->num_ports *1157 hdmi->num_pin;1158 1159 hdac_hdmi_fill_route(&route[i],1160 widgets[sink_index].name, NULL,1161 widgets[src_index].name, NULL);1162 i++;1163 }1164 }1165 1166 hdac_hdmi_add_pinmux_cvt_route(hdev, widgets, route, i);1167 1168 snd_soc_dapm_new_controls(dapm, widgets,1169 ((2 * hdmi->num_ports) + hdmi->num_cvt));1170 1171 snd_soc_dapm_add_routes(dapm, route, num_routes);1172 snd_soc_dapm_new_widgets(dapm->card);1173 1174 return 0;1175 1176}1177 1178static int hdac_hdmi_init_dai_map(struct hdac_device *hdev)1179{1180 struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev);1181 struct hdac_hdmi_dai_port_map *dai_map;1182 struct hdac_hdmi_cvt *cvt;1183 int dai_id = 0;1184 1185 if (list_empty(&hdmi->cvt_list))1186 return -EINVAL;1187 1188 list_for_each_entry(cvt, &hdmi->cvt_list, head) {1189 dai_map = &hdmi->dai_map[dai_id];1190 dai_map->dai_id = dai_id;1191 dai_map->cvt = cvt;1192 1193 dai_id++;1194 1195 if (dai_id == HDA_MAX_CVTS) {1196 dev_warn(&hdev->dev,1197 "Max dais supported: %d\n", dai_id);1198 break;1199 }1200 }1201 1202 return 0;1203}1204 1205static int hdac_hdmi_add_cvt(struct hdac_device *hdev, hda_nid_t nid)1206{1207 struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev);1208 struct hdac_hdmi_cvt *cvt;1209 char name[NAME_SIZE];1210 1211 cvt = devm_kzalloc(&hdev->dev, sizeof(*cvt), GFP_KERNEL);1212 if (!cvt)1213 return -ENOMEM;1214 1215 cvt->nid = nid;1216 sprintf(name, "cvt %d", cvt->nid);1217 cvt->name = devm_kstrdup(&hdev->dev, name, GFP_KERNEL);1218 if (!cvt->name)1219 return -ENOMEM;1220 1221 list_add_tail(&cvt->head, &hdmi->cvt_list);1222 hdmi->num_cvt++;1223 1224 return hdac_hdmi_query_cvt_params(hdev, cvt);1225}1226 1227static int hdac_hdmi_parse_eld(struct hdac_device *hdev,1228 struct hdac_hdmi_port *port)1229{1230 unsigned int ver, mnl;1231 1232 ver = (port->eld.eld_buffer[DRM_ELD_VER] & DRM_ELD_VER_MASK)1233 >> DRM_ELD_VER_SHIFT;1234 1235 if (ver != ELD_VER_CEA_861D && ver != ELD_VER_PARTIAL) {1236 dev_err(&hdev->dev, "HDMI: Unknown ELD version %d\n", ver);1237 return -EINVAL;1238 }1239 1240 mnl = (port->eld.eld_buffer[DRM_ELD_CEA_EDID_VER_MNL] &1241 DRM_ELD_MNL_MASK) >> DRM_ELD_MNL_SHIFT;1242 1243 if (mnl > ELD_MAX_MNL) {1244 dev_err(&hdev->dev, "HDMI: MNL Invalid %d\n", mnl);1245 return -EINVAL;1246 }1247 1248 port->eld.info.spk_alloc = port->eld.eld_buffer[DRM_ELD_SPEAKER];1249 1250 return 0;1251}1252 1253static void hdac_hdmi_present_sense(struct hdac_hdmi_pin *pin,1254 struct hdac_hdmi_port *port)1255{1256 struct hdac_device *hdev = pin->hdev;1257 struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev);1258 struct hdac_hdmi_pcm *pcm;1259 int size = 0;1260 int port_id = -1;1261 bool eld_valid, eld_changed;1262 1263 if (!hdmi)1264 return;1265 1266 /*1267 * In case of non MST pin, get_eld info API expectes port1268 * to be -1.1269 */1270 mutex_lock(&hdmi->pin_mutex);1271 port->eld.monitor_present = false;1272 1273 if (pin->mst_capable)1274 port_id = port->id;1275 1276 size = snd_hdac_acomp_get_eld(hdev, pin->nid, port_id,1277 &port->eld.monitor_present,1278 port->eld.eld_buffer,1279 ELD_MAX_SIZE);1280 1281 if (size > 0) {1282 size = min(size, ELD_MAX_SIZE);1283 if (hdac_hdmi_parse_eld(hdev, port) < 0)1284 size = -EINVAL;1285 }1286 1287 eld_valid = port->eld.eld_valid;1288 1289 if (size > 0) {1290 port->eld.eld_valid = true;1291 port->eld.eld_size = size;1292 } else {1293 port->eld.eld_valid = false;1294 port->eld.eld_size = 0;1295 }1296 1297 eld_changed = (eld_valid != port->eld.eld_valid);1298 1299 pcm = hdac_hdmi_get_pcm(hdev, port);1300 1301 if (!port->eld.monitor_present || !port->eld.eld_valid) {1302 1303 dev_err(&hdev->dev, "%s: disconnect for pin:port %d:%d\n",1304 __func__, pin->nid, port->id);1305 1306 /*1307 * PCMs are not registered during device probe, so don't1308 * report jack here. It will be done in usermode mux1309 * control select.1310 */1311 if (pcm) {1312 hdac_hdmi_jack_report(pcm, port, false);1313 schedule_work(&port->dapm_work);1314 }1315 1316 mutex_unlock(&hdmi->pin_mutex);1317 return;1318 }1319 1320 if (port->eld.monitor_present && port->eld.eld_valid) {1321 if (pcm) {1322 hdac_hdmi_jack_report(pcm, port, true);1323 schedule_work(&port->dapm_work);1324 }1325 1326 print_hex_dump_debug("ELD: ", DUMP_PREFIX_OFFSET, 16, 1,1327 port->eld.eld_buffer, port->eld.eld_size, false);1328 1329 }1330 mutex_unlock(&hdmi->pin_mutex);1331 1332 if (eld_changed && pcm)1333 snd_ctl_notify(hdmi->card,1334 SNDRV_CTL_EVENT_MASK_VALUE |1335 SNDRV_CTL_EVENT_MASK_INFO,1336 &pcm->eld_ctl->id);1337}1338 1339static int hdac_hdmi_add_ports(struct hdac_device *hdev,1340 struct hdac_hdmi_pin *pin)1341{1342 struct hdac_hdmi_port *ports;1343 int max_ports = HDA_MAX_PORTS;1344 int i;1345 1346 /*1347 * FIXME: max_port may vary for each platform, so pass this as1348 * as driver data or query from i915 interface when this API is1349 * implemented.1350 */1351 1352 ports = devm_kcalloc(&hdev->dev, max_ports, sizeof(*ports), GFP_KERNEL);1353 if (!ports)1354 return -ENOMEM;1355 1356 for (i = 0; i < max_ports; i++) {1357 ports[i].id = i;1358 ports[i].pin = pin;1359 INIT_WORK(&ports[i].dapm_work, hdac_hdmi_jack_dapm_work);1360 }1361 pin->ports = ports;1362 pin->num_ports = max_ports;1363 return 0;1364}1365 1366static int hdac_hdmi_add_pin(struct hdac_device *hdev, hda_nid_t nid)1367{1368 struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev);1369 struct hdac_hdmi_pin *pin;1370 int ret;1371 1372 pin = devm_kzalloc(&hdev->dev, sizeof(*pin), GFP_KERNEL);1373 if (!pin)1374 return -ENOMEM;1375 1376 pin->nid = nid;1377 pin->mst_capable = false;1378 pin->hdev = hdev;1379 ret = hdac_hdmi_add_ports(hdev, pin);1380 if (ret < 0)1381 return ret;1382 1383 list_add_tail(&pin->head, &hdmi->pin_list);1384 hdmi->num_pin++;1385 hdmi->num_ports += pin->num_ports;1386 1387 return 0;1388}1389 1390#define INTEL_VENDOR_NID 0x081391#define INTEL_GLK_VENDOR_NID 0x0b1392#define INTEL_GET_VENDOR_VERB 0xf811393#define INTEL_SET_VENDOR_VERB 0x7811394#define INTEL_EN_DP12 0x02 /* enable DP 1.2 features */1395#define INTEL_EN_ALL_PIN_CVTS 0x01 /* enable 2nd & 3rd pins and convertors */1396 1397static void hdac_hdmi_skl_enable_all_pins(struct hdac_device *hdev)1398{1399 unsigned int vendor_param;1400 struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev);1401 unsigned int vendor_nid = hdmi->drv_data->vendor_nid;1402 1403 vendor_param = snd_hdac_codec_read(hdev, vendor_nid, 0,1404 INTEL_GET_VENDOR_VERB, 0);1405 if (vendor_param == -1 || vendor_param & INTEL_EN_ALL_PIN_CVTS)1406 return;1407 1408 vendor_param |= INTEL_EN_ALL_PIN_CVTS;1409 vendor_param = snd_hdac_codec_read(hdev, vendor_nid, 0,1410 INTEL_SET_VENDOR_VERB, vendor_param);1411 if (vendor_param == -1)1412 return;1413}1414 1415static void hdac_hdmi_skl_enable_dp12(struct hdac_device *hdev)1416{1417 unsigned int vendor_param;1418 struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev);1419 unsigned int vendor_nid = hdmi->drv_data->vendor_nid;1420 1421 vendor_param = snd_hdac_codec_read(hdev, vendor_nid, 0,1422 INTEL_GET_VENDOR_VERB, 0);1423 if (vendor_param == -1 || vendor_param & INTEL_EN_DP12)1424 return;1425 1426 /* enable DP1.2 mode */1427 vendor_param |= INTEL_EN_DP12;1428 vendor_param = snd_hdac_codec_read(hdev, vendor_nid, 0,1429 INTEL_SET_VENDOR_VERB, vendor_param);1430 if (vendor_param == -1)1431 return;1432 1433}1434 1435static int hdac_hdmi_eld_ctl_info(struct snd_kcontrol *kcontrol,1436 struct snd_ctl_elem_info *uinfo)1437{1438 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);1439 struct hdac_hdmi_priv *hdmi = snd_soc_component_get_drvdata(component);1440 struct hdac_hdmi_pcm *pcm;1441 struct hdac_hdmi_port *port;1442 struct hdac_hdmi_eld *eld;1443 1444 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;1445 uinfo->count = 0;1446 1447 pcm = get_hdmi_pcm_from_id(hdmi, kcontrol->id.device);1448 if (!pcm) {1449 dev_dbg(component->dev, "%s: no pcm, device %d\n", __func__,1450 kcontrol->id.device);1451 return 0;1452 }1453 1454 if (list_empty(&pcm->port_list)) {1455 dev_dbg(component->dev, "%s: empty port list, device %d\n",1456 __func__, kcontrol->id.device);1457 return 0;1458 }1459 1460 mutex_lock(&hdmi->pin_mutex);1461 1462 list_for_each_entry(port, &pcm->port_list, head) {1463 eld = &port->eld;1464 1465 if (eld->eld_valid) {1466 uinfo->count = eld->eld_size;1467 break;1468 }1469 }1470 1471 mutex_unlock(&hdmi->pin_mutex);1472 1473 return 0;1474}1475 1476static int hdac_hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol,1477 struct snd_ctl_elem_value *ucontrol)1478{1479 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);1480 struct hdac_hdmi_priv *hdmi = snd_soc_component_get_drvdata(component);1481 struct hdac_hdmi_pcm *pcm;1482 struct hdac_hdmi_port *port;1483 struct hdac_hdmi_eld *eld;1484 1485 memset(ucontrol->value.bytes.data, 0, sizeof(ucontrol->value.bytes.data));1486 1487 pcm = get_hdmi_pcm_from_id(hdmi, kcontrol->id.device);1488 if (!pcm) {1489 dev_dbg(component->dev, "%s: no pcm, device %d\n", __func__,1490 kcontrol->id.device);1491 return 0;1492 }1493 1494 if (list_empty(&pcm->port_list)) {1495 dev_dbg(component->dev, "%s: empty port list, device %d\n",1496 __func__, kcontrol->id.device);1497 return 0;1498 }1499 1500 mutex_lock(&hdmi->pin_mutex);1501 1502 list_for_each_entry(port, &pcm->port_list, head) {1503 eld = &port->eld;1504 1505 if (!eld->eld_valid)1506 continue;1507 1508 if (eld->eld_size > ARRAY_SIZE(ucontrol->value.bytes.data) ||1509 eld->eld_size > ELD_MAX_SIZE) {1510 mutex_unlock(&hdmi->pin_mutex);1511 1512 dev_err(component->dev, "%s: buffer too small, device %d eld_size %d\n",1513 __func__, kcontrol->id.device, eld->eld_size);1514 snd_BUG();1515 return -EINVAL;1516 }1517 1518 memcpy(ucontrol->value.bytes.data, eld->eld_buffer,1519 eld->eld_size);1520 break;1521 }1522 1523 mutex_unlock(&hdmi->pin_mutex);1524 1525 return 0;1526}1527 1528static int hdac_hdmi_create_eld_ctl(struct snd_soc_component *component, struct hdac_hdmi_pcm *pcm)1529{1530 struct snd_kcontrol *kctl;1531 struct snd_kcontrol_new hdmi_eld_ctl = {1532 .access = SNDRV_CTL_ELEM_ACCESS_READ |1533 SNDRV_CTL_ELEM_ACCESS_VOLATILE,1534 .iface = SNDRV_CTL_ELEM_IFACE_PCM,1535 .name = "ELD",1536 .info = hdac_hdmi_eld_ctl_info,1537 .get = hdac_hdmi_eld_ctl_get,1538 .device = pcm->pcm_id,1539 };1540 1541 /* add ELD ctl with the device number corresponding to the PCM stream */1542 kctl = snd_ctl_new1(&hdmi_eld_ctl, component);1543 if (!kctl)1544 return -ENOMEM;1545 1546 pcm->eld_ctl = kctl;1547 1548 return snd_ctl_add(component->card->snd_card, kctl);1549}1550 1551static const struct snd_soc_dai_ops hdmi_dai_ops = {1552 .startup = hdac_hdmi_pcm_open,1553 .shutdown = hdac_hdmi_pcm_close,1554 .hw_params = hdac_hdmi_set_hw_params,1555 .set_stream = hdac_hdmi_set_stream,1556};1557 1558/*1559 * Each converter can support a stream independently. So a dai is created1560 * based on the number of converter queried.1561 */1562static int hdac_hdmi_create_dais(struct hdac_device *hdev,1563 struct snd_soc_dai_driver **dais,1564 struct hdac_hdmi_priv *hdmi, int num_dais)1565{1566 struct snd_soc_dai_driver *hdmi_dais;1567 struct hdac_hdmi_cvt *cvt;1568 char name[NAME_SIZE], dai_name[NAME_SIZE];1569 int i = 0;1570 u32 rates, bps;1571 unsigned int rate_max = 384000, rate_min = 8000;1572 u64 formats;1573 int ret;1574 1575 hdmi_dais = devm_kzalloc(&hdev->dev,1576 (sizeof(*hdmi_dais) * num_dais),1577 GFP_KERNEL);1578 if (!hdmi_dais)1579 return -ENOMEM;1580 1581 list_for_each_entry(cvt, &hdmi->cvt_list, head) {1582 ret = snd_hdac_query_supported_pcm(hdev, cvt->nid,1583 &rates, &formats, NULL, &bps);1584 if (ret)1585 return ret;1586 1587 /* Filter out 44.1, 88.2 and 176.4Khz */1588 rates &= ~(SNDRV_PCM_RATE_44100 | SNDRV_PCM_RATE_88200 |1589 SNDRV_PCM_RATE_176400);1590 if (!rates)1591 return -EINVAL;1592 1593 sprintf(dai_name, "intel-hdmi-hifi%d", i+1);1594 hdmi_dais[i].name = devm_kstrdup(&hdev->dev,1595 dai_name, GFP_KERNEL);1596 1597 if (!hdmi_dais[i].name)1598 return -ENOMEM;1599 1600 snprintf(name, sizeof(name), "hifi%d", i+1);1601 hdmi_dais[i].playback.stream_name =1602 devm_kstrdup(&hdev->dev, name, GFP_KERNEL);1603 if (!hdmi_dais[i].playback.stream_name)1604 return -ENOMEM;1605 1606 /*1607 * Set caps based on capability queried from the converter.1608 * It will be constrained runtime based on ELD queried.1609 */1610 hdmi_dais[i].playback.formats = formats;1611 hdmi_dais[i].playback.rates = rates;1612 hdmi_dais[i].playback.rate_max = rate_max;1613 hdmi_dais[i].playback.rate_min = rate_min;1614 hdmi_dais[i].playback.channels_min = 2;1615 hdmi_dais[i].playback.channels_max = 2;1616 hdmi_dais[i].playback.sig_bits = bps;1617 hdmi_dais[i].ops = &hdmi_dai_ops;1618 i++;1619 }1620 1621 *dais = hdmi_dais;1622 hdmi->dai_drv = hdmi_dais;1623 1624 return 0;1625}1626 1627/*1628 * Parse all nodes and store the cvt/pin nids in array1629 * Add one time initialization for pin and cvt widgets1630 */1631static int hdac_hdmi_parse_and_map_nid(struct hdac_device *hdev,1632 struct snd_soc_dai_driver **dais, int *num_dais)1633{1634 hda_nid_t nid;1635 int i, num_nodes;1636 struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev);1637 int ret;1638 1639 hdac_hdmi_skl_enable_all_pins(hdev);1640 hdac_hdmi_skl_enable_dp12(hdev);1641 1642 num_nodes = snd_hdac_get_sub_nodes(hdev, hdev->afg, &nid);1643 if (!nid || num_nodes <= 0) {1644 dev_warn(&hdev->dev, "HDMI: failed to get afg sub nodes\n");1645 return -EINVAL;1646 }1647 1648 for (i = 0; i < num_nodes; i++, nid++) {1649 unsigned int caps;1650 unsigned int type;1651 1652 caps = get_wcaps(hdev, nid);1653 type = get_wcaps_type(caps);1654 1655 if (!(caps & AC_WCAP_DIGITAL))1656 continue;1657 1658 switch (type) {1659 1660 case AC_WID_AUD_OUT:1661 ret = hdac_hdmi_add_cvt(hdev, nid);1662 if (ret < 0)1663 return ret;1664 break;1665 1666 case AC_WID_PIN:1667 ret = hdac_hdmi_add_pin(hdev, nid);1668 if (ret < 0)1669 return ret;1670 break;1671 }1672 }1673 1674 if (!hdmi->num_pin || !hdmi->num_cvt) {1675 ret = -EIO;1676 dev_err(&hdev->dev, "Bad pin/cvt setup in %s\n", __func__);1677 return ret;1678 }1679 1680 ret = hdac_hdmi_create_dais(hdev, dais, hdmi, hdmi->num_cvt);1681 if (ret) {1682 dev_err(&hdev->dev, "Failed to create dais with err: %d\n",1683 ret);1684 return ret;1685 }1686 1687 *num_dais = hdmi->num_cvt;1688 ret = hdac_hdmi_init_dai_map(hdev);1689 if (ret < 0)1690 dev_err(&hdev->dev, "Failed to init DAI map with err: %d\n",1691 ret);1692 return ret;1693}1694 1695static int hdac_hdmi_pin2port(void *aptr, int pin)1696{1697 return pin - 4; /* map NID 0x05 -> port #1 */1698}1699 1700static void hdac_hdmi_eld_notify_cb(void *aptr, int port, int pipe)1701{1702 struct hdac_device *hdev = aptr;1703 struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev);1704 struct hdac_hdmi_pin *pin;1705 struct hdac_hdmi_port *hport = NULL;1706 struct snd_soc_component *component = hdmi->component;1707 int i;1708 1709 /* Don't know how this mapping is derived */1710 hda_nid_t pin_nid = port + 0x04;1711 1712 dev_dbg(&hdev->dev, "%s: for pin:%d port=%d\n", __func__,1713 pin_nid, pipe);1714 1715 /*1716 * skip notification during system suspend (but not in runtime PM);1717 * the state will be updated at resume. Also since the ELD and1718 * connection states are updated in anyway at the end of the resume,1719 * we can skip it when received during PM process.1720 */1721 if (snd_power_get_state(component->card->snd_card) !=1722 SNDRV_CTL_POWER_D0)1723 return;1724 1725 if (atomic_read(&hdev->in_pm))1726 return;1727 1728 list_for_each_entry(pin, &hdmi->pin_list, head) {1729 if (pin->nid != pin_nid)1730 continue;1731 1732 /* In case of non MST pin, pipe is -1 */1733 if (pipe == -1) {1734 pin->mst_capable = false;1735 /* if not MST, default is port[0] */1736 hport = &pin->ports[0];1737 } else {1738 for (i = 0; i < pin->num_ports; i++) {1739 pin->mst_capable = true;1740 if (pin->ports[i].id == pipe) {1741 hport = &pin->ports[i];1742 break;1743 }1744 }1745 }1746 1747 if (hport)1748 hdac_hdmi_present_sense(pin, hport);1749 }1750 1751}1752 1753static struct drm_audio_component_audio_ops aops = {1754 .pin2port = hdac_hdmi_pin2port,1755 .pin_eld_notify = hdac_hdmi_eld_notify_cb,1756};1757 1758static struct snd_pcm *hdac_hdmi_get_pcm_from_id(struct snd_soc_card *card,1759 int device)1760{1761 struct snd_soc_pcm_runtime *rtd;1762 1763 for_each_card_rtds(card, rtd) {1764 if (rtd->pcm && (rtd->pcm->device == device))1765 return rtd->pcm;1766 }1767 1768 return NULL;1769}1770 1771/* create jack pin kcontrols */1772static int create_fill_jack_kcontrols(struct snd_soc_card *card,1773 struct hdac_device *hdev)1774{1775 struct hdac_hdmi_pin *pin;1776 struct snd_kcontrol_new *kc;1777 char *name;1778 int i = 0, j;1779 struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev);1780 struct snd_soc_component *component = hdmi->component;1781 1782 kc = devm_kcalloc(component->dev, hdmi->num_ports,1783 sizeof(*kc), GFP_KERNEL);1784 1785 if (!kc)1786 return -ENOMEM;1787 1788 list_for_each_entry(pin, &hdmi->pin_list, head) {1789 for (j = 0; j < pin->num_ports; j++) {1790 name = devm_kasprintf(component->dev, GFP_KERNEL,1791 "hif%d-%d Jack",1792 pin->nid, pin->ports[j].id);1793 if (!name)1794 return -ENOMEM;1795 1796 kc[i].name = devm_kasprintf(component->dev, GFP_KERNEL,1797 "%s Switch", name);1798 if (!kc[i].name)1799 return -ENOMEM;1800 1801 kc[i].private_value = (unsigned long)name;1802 kc[i].iface = SNDRV_CTL_ELEM_IFACE_MIXER;1803 kc[i].access = 0;1804 kc[i].info = snd_soc_dapm_info_pin_switch;1805 kc[i].put = snd_soc_dapm_put_pin_switch;1806 kc[i].get = snd_soc_dapm_get_pin_switch;1807 i++;1808 }1809 }1810 1811 return snd_soc_add_card_controls(card, kc, i);1812}1813 1814int hdac_hdmi_jack_port_init(struct snd_soc_component *component,1815 struct snd_soc_dapm_context *dapm)1816{1817 struct hdac_hdmi_priv *hdmi = snd_soc_component_get_drvdata(component);1818 struct hdac_device *hdev = hdmi->hdev;1819 struct hdac_hdmi_pin *pin;1820 struct snd_soc_dapm_widget *widgets;1821 struct snd_soc_dapm_route *route;1822 char w_name[NAME_SIZE];1823 int i = 0, j, ret;1824 1825 widgets = devm_kcalloc(dapm->dev, hdmi->num_ports,1826 sizeof(*widgets), GFP_KERNEL);1827 1828 if (!widgets)1829 return -ENOMEM;1830 1831 route = devm_kcalloc(dapm->dev, hdmi->num_ports,1832 sizeof(*route), GFP_KERNEL);1833 if (!route)1834 return -ENOMEM;1835 1836 /* create Jack DAPM widget */1837 list_for_each_entry(pin, &hdmi->pin_list, head) {1838 for (j = 0; j < pin->num_ports; j++) {1839 snprintf(w_name, sizeof(w_name), "hif%d-%d Jack",1840 pin->nid, pin->ports[j].id);1841 1842 ret = hdac_hdmi_fill_widget_info(dapm->dev, &widgets[i],1843 snd_soc_dapm_spk, NULL,1844 w_name, NULL, NULL, 0, NULL, 0);1845 if (ret < 0)1846 return ret;1847 1848 pin->ports[j].jack_pin = widgets[i].name;1849 pin->ports[j].dapm = dapm;1850 1851 /* add to route from Jack widget to output */1852 hdac_hdmi_fill_route(&route[i], pin->ports[j].jack_pin,1853 NULL, pin->ports[j].output_pin, NULL);1854 1855 i++;1856 }1857 }1858 1859 /* Add Route from Jack widget to the output widget */1860 ret = snd_soc_dapm_new_controls(dapm, widgets, hdmi->num_ports);1861 if (ret < 0)1862 return ret;1863 1864 ret = snd_soc_dapm_add_routes(dapm, route, hdmi->num_ports);1865 if (ret < 0)1866 return ret;1867 1868 ret = snd_soc_dapm_new_widgets(dapm->card);1869 if (ret < 0)1870 return ret;1871 1872 /* Add Jack Pin switch Kcontrol */1873 ret = create_fill_jack_kcontrols(dapm->card, hdev);1874 1875 if (ret < 0)1876 return ret;1877 1878 /* default set the Jack Pin switch to OFF */1879 list_for_each_entry(pin, &hdmi->pin_list, head) {1880 for (j = 0; j < pin->num_ports; j++)1881 snd_soc_dapm_disable_pin(pin->ports[j].dapm,1882 pin->ports[j].jack_pin);1883 }1884 1885 return 0;1886}1887EXPORT_SYMBOL_GPL(hdac_hdmi_jack_port_init);1888 1889int hdac_hdmi_jack_init(struct snd_soc_dai *dai, int device,1890 struct snd_soc_jack *jack)1891{1892 struct snd_soc_component *component = dai->component;1893 struct hdac_hdmi_priv *hdmi = snd_soc_component_get_drvdata(component);1894 struct hdac_device *hdev = hdmi->hdev;1895 struct hdac_hdmi_pcm *pcm;1896 struct snd_pcm *snd_pcm;1897 int err;1898 1899 /*1900 * this is a new PCM device, create new pcm and1901 * add to the pcm list1902 */1903 pcm = devm_kzalloc(&hdev->dev, sizeof(*pcm), GFP_KERNEL);1904 if (!pcm)1905 return -ENOMEM;1906 pcm->pcm_id = device;1907 pcm->cvt = hdmi->dai_map[dai->id].cvt;1908 pcm->jack_event = 0;1909 pcm->jack = jack;1910 mutex_init(&pcm->lock);1911 INIT_LIST_HEAD(&pcm->port_list);1912 snd_pcm = hdac_hdmi_get_pcm_from_id(dai->component->card, device);1913 if (snd_pcm) {1914 err = snd_hdac_add_chmap_ctls(snd_pcm, device, &hdmi->chmap);1915 if (err < 0) {1916 dev_err(&hdev->dev,1917 "chmap control add failed with err: %d for pcm: %d\n",1918 err, device);1919 return err;1920 }1921 }1922 1923 /* add control for ELD Bytes */1924 err = hdac_hdmi_create_eld_ctl(component, pcm);1925 if (err < 0) {1926 dev_err(&hdev->dev,1927 "eld control add failed with err: %d for pcm: %d\n",1928 err, device);1929 return err;1930 }1931 1932 list_add_tail(&pcm->head, &hdmi->pcm_list);1933 1934 return 0;1935}1936EXPORT_SYMBOL_GPL(hdac_hdmi_jack_init);1937 1938static void hdac_hdmi_present_sense_all_pins(struct hdac_device *hdev,1939 struct hdac_hdmi_priv *hdmi, bool detect_pin_caps)1940{1941 int i;1942 struct hdac_hdmi_pin *pin;1943 1944 list_for_each_entry(pin, &hdmi->pin_list, head) {1945 if (detect_pin_caps) {1946 1947 if (hdac_hdmi_get_port_len(hdev, pin->nid) == 0)1948 pin->mst_capable = false;1949 else1950 pin->mst_capable = true;1951 }1952 1953 for (i = 0; i < pin->num_ports; i++) {1954 if (!pin->mst_capable && i > 0)1955 continue;1956 1957 hdac_hdmi_present_sense(pin, &pin->ports[i]);1958 }1959 }1960}1961 1962static int hdmi_codec_probe(struct snd_soc_component *component)1963{1964 struct hdac_hdmi_priv *hdmi = snd_soc_component_get_drvdata(component);1965 struct hdac_device *hdev = hdmi->hdev;1966 struct snd_soc_dapm_context *dapm =1967 snd_soc_component_get_dapm(component);1968 struct hdac_ext_link *hlink;1969 int ret;1970 1971 hdmi->component = component;1972 1973 /*1974 * hold the ref while we probe, also no need to drop the ref on1975 * exit, we call pm_runtime_suspend() so that will do for us1976 */1977 hlink = snd_hdac_ext_bus_get_hlink_by_name(hdev->bus, dev_name(&hdev->dev));1978 if (!hlink) {1979 dev_err(&hdev->dev, "hdac link not found\n");1980 return -EIO;1981 }1982 1983 snd_hdac_ext_bus_link_get(hdev->bus, hlink);1984 1985 ret = create_fill_widget_route_map(dapm);1986 if (ret < 0)1987 return ret;1988 1989 aops.audio_ptr = hdev;1990 ret = snd_hdac_acomp_register_notifier(hdev->bus, &aops);1991 if (ret < 0) {1992 dev_err(&hdev->dev, "notifier register failed: err: %d\n", ret);1993 return ret;1994 }1995 1996 hdac_hdmi_present_sense_all_pins(hdev, hdmi, true);1997 /* Imp: Store the card pointer in hda_codec */1998 hdmi->card = dapm->card->snd_card;1999 2000 /*2001 * Setup a device_link between card device and HDMI codec device.2002 * The card device is the consumer and the HDMI codec device is2003 * the supplier. With this setting, we can make sure that the audio2004 * domain in display power will be always turned on before operating2005 * on the HDMI audio codec registers.2006 * Let's use the flag DL_FLAG_AUTOREMOVE_CONSUMER. This can make2007 * sure the device link is freed when the machine driver is removed.2008 */2009 device_link_add(component->card->dev, &hdev->dev, DL_FLAG_RPM_ACTIVE |2010 DL_FLAG_AUTOREMOVE_CONSUMER);2011 /*2012 * hdac_device core already sets the state to active and calls2013 * get_noresume. So enable runtime and set the device to suspend.2014 */2015 pm_runtime_enable(&hdev->dev);2016 pm_runtime_put(&hdev->dev);2017 pm_runtime_suspend(&hdev->dev);2018 2019 return 0;2020}2021 2022static void hdmi_codec_remove(struct snd_soc_component *component)2023{2024 struct hdac_hdmi_priv *hdmi = snd_soc_component_get_drvdata(component);2025 struct hdac_device *hdev = hdmi->hdev;2026 int ret;2027 2028 ret = snd_hdac_acomp_register_notifier(hdev->bus, NULL);2029 if (ret < 0)2030 dev_err(&hdev->dev, "notifier unregister failed: err: %d\n",2031 ret);2032 2033 pm_runtime_disable(&hdev->dev);2034}2035 2036#ifdef CONFIG_PM_SLEEP2037static int hdmi_codec_resume(struct device *dev)2038{2039 struct hdac_device *hdev = dev_to_hdac_dev(dev);2040 struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev);2041 int ret;2042 2043 ret = pm_runtime_force_resume(dev);2044 if (ret < 0)2045 return ret;2046 /*2047 * As the ELD notify callback request is not entertained while the2048 * device is in suspend state. Need to manually check detection of2049 * all pins here. pin capablity change is not support, so use the2050 * already set pin caps.2051 *2052 * NOTE: this is safe to call even if the codec doesn't actually resume.2053 * The pin check involves only with DRM audio component hooks, so it2054 * works even if the HD-audio side is still dreaming peacefully.2055 */2056 hdac_hdmi_present_sense_all_pins(hdev, hdmi, false);2057 return 0;2058}2059#else2060#define hdmi_codec_resume NULL2061#endif2062 2063static const struct snd_soc_component_driver hdmi_hda_codec = {2064 .probe = hdmi_codec_probe,2065 .remove = hdmi_codec_remove,2066 .use_pmdown_time = 1,2067 .endianness = 1,2068};2069 2070static void hdac_hdmi_get_chmap(struct hdac_device *hdev, int pcm_idx,2071 unsigned char *chmap)2072{2073 struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev);2074 struct hdac_hdmi_pcm *pcm = get_hdmi_pcm_from_id(hdmi, pcm_idx);2075 2076 memcpy(chmap, pcm->chmap, ARRAY_SIZE(pcm->chmap));2077}2078 2079static void hdac_hdmi_set_chmap(struct hdac_device *hdev, int pcm_idx,2080 unsigned char *chmap, int prepared)2081{2082 struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev);2083 struct hdac_hdmi_pcm *pcm = get_hdmi_pcm_from_id(hdmi, pcm_idx);2084 struct hdac_hdmi_port *port;2085 2086 if (!pcm)2087 return;2088 2089 if (list_empty(&pcm->port_list))2090 return;2091 2092 mutex_lock(&pcm->lock);2093 pcm->chmap_set = true;2094 memcpy(pcm->chmap, chmap, ARRAY_SIZE(pcm->chmap));2095 list_for_each_entry(port, &pcm->port_list, head)2096 if (prepared)2097 hdac_hdmi_setup_audio_infoframe(hdev, pcm, port);2098 mutex_unlock(&pcm->lock);2099}2100 2101static bool is_hdac_hdmi_pcm_attached(struct hdac_device *hdev, int pcm_idx)2102{2103 struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev);2104 struct hdac_hdmi_pcm *pcm = get_hdmi_pcm_from_id(hdmi, pcm_idx);2105 2106 if (!pcm)2107 return false;2108 2109 if (list_empty(&pcm->port_list))2110 return false;2111 2112 return true;2113}2114 2115static int hdac_hdmi_get_spk_alloc(struct hdac_device *hdev, int pcm_idx)2116{2117 struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev);2118 struct hdac_hdmi_pcm *pcm = get_hdmi_pcm_from_id(hdmi, pcm_idx);2119 struct hdac_hdmi_port *port;2120 2121 if (!pcm)2122 return 0;2123 2124 if (list_empty(&pcm->port_list))2125 return 0;2126 2127 port = list_first_entry(&pcm->port_list, struct hdac_hdmi_port, head);2128 2129 if (!port || !port->eld.eld_valid)2130 return 0;2131 2132 return port->eld.info.spk_alloc;2133}2134 2135static struct hdac_hdmi_drv_data intel_glk_drv_data = {2136 .vendor_nid = INTEL_GLK_VENDOR_NID,2137};2138 2139static struct hdac_hdmi_drv_data intel_drv_data = {2140 .vendor_nid = INTEL_VENDOR_NID,2141};2142 2143static int hdac_hdmi_dev_probe(struct hdac_device *hdev)2144{2145 struct hdac_hdmi_priv *hdmi_priv;2146 struct snd_soc_dai_driver *hdmi_dais = NULL;2147 struct hdac_ext_link *hlink;2148 int num_dais = 0;2149 int ret;2150 struct hdac_driver *hdrv = drv_to_hdac_driver(hdev->dev.driver);2151 const struct hda_device_id *hdac_id = hdac_get_device_id(hdev, hdrv);2152 2153 /* hold the ref while we probe */2154 hlink = snd_hdac_ext_bus_get_hlink_by_name(hdev->bus, dev_name(&hdev->dev));2155 if (!hlink) {2156 dev_err(&hdev->dev, "hdac link not found\n");2157 return -EIO;2158 }2159 2160 snd_hdac_ext_bus_link_get(hdev->bus, hlink);2161 2162 hdmi_priv = devm_kzalloc(&hdev->dev, sizeof(*hdmi_priv), GFP_KERNEL);2163 if (hdmi_priv == NULL)2164 return -ENOMEM;2165 2166 snd_hdac_register_chmap_ops(hdev, &hdmi_priv->chmap);2167 hdmi_priv->chmap.ops.get_chmap = hdac_hdmi_get_chmap;2168 hdmi_priv->chmap.ops.set_chmap = hdac_hdmi_set_chmap;2169 hdmi_priv->chmap.ops.is_pcm_attached = is_hdac_hdmi_pcm_attached;2170 hdmi_priv->chmap.ops.get_spk_alloc = hdac_hdmi_get_spk_alloc;2171 hdmi_priv->hdev = hdev;2172 2173 if (!hdac_id)2174 return -ENODEV;2175 2176 if (hdac_id->driver_data)2177 hdmi_priv->drv_data =2178 (struct hdac_hdmi_drv_data *)hdac_id->driver_data;2179 else2180 hdmi_priv->drv_data = &intel_drv_data;2181 2182 dev_set_drvdata(&hdev->dev, hdmi_priv);2183 2184 INIT_LIST_HEAD(&hdmi_priv->pin_list);2185 INIT_LIST_HEAD(&hdmi_priv->cvt_list);2186 INIT_LIST_HEAD(&hdmi_priv->pcm_list);2187 mutex_init(&hdmi_priv->pin_mutex);2188 2189 /*2190 * Turned off in the runtime_suspend during the first explicit2191 * pm_runtime_suspend call.2192 */2193 snd_hdac_display_power(hdev->bus, hdev->addr, true);2194 2195 ret = hdac_hdmi_parse_and_map_nid(hdev, &hdmi_dais, &num_dais);2196 if (ret < 0) {2197 dev_err(&hdev->dev,2198 "Failed in parse and map nid with err: %d\n", ret);2199 return ret;2200 }2201 snd_hdac_refresh_widgets(hdev);2202 2203 /* ASoC specific initialization */2204 ret = devm_snd_soc_register_component(&hdev->dev, &hdmi_hda_codec,2205 hdmi_dais, num_dais);2206 2207 snd_hdac_ext_bus_link_put(hdev->bus, hlink);2208 2209 return ret;2210}2211 2212static void clear_dapm_works(struct hdac_device *hdev)2213{2214 struct hdac_hdmi_priv *hdmi = hdev_to_hdmi_priv(hdev);2215 struct hdac_hdmi_pin *pin;2216 int i;2217 2218 list_for_each_entry(pin, &hdmi->pin_list, head)2219 for (i = 0; i < pin->num_ports; i++)2220 cancel_work_sync(&pin->ports[i].dapm_work);2221}2222 2223static int hdac_hdmi_dev_remove(struct hdac_device *hdev)2224{2225 clear_dapm_works(hdev);2226 snd_hdac_display_power(hdev->bus, hdev->addr, false);2227 2228 return 0;2229}2230 2231#ifdef CONFIG_PM2232static int hdac_hdmi_runtime_suspend(struct device *dev)2233{2234 struct hdac_device *hdev = dev_to_hdac_dev(dev);2235 struct hdac_bus *bus = hdev->bus;2236 struct hdac_ext_link *hlink;2237 2238 dev_dbg(dev, "Enter: %s\n", __func__);2239 2240 /* controller may not have been initialized for the first time */2241 if (!bus)2242 return 0;2243 2244 /*2245 * Power down afg.2246 * codec_read is preferred over codec_write to set the power state.2247 * This way verb is send to set the power state and response2248 * is received. So setting power state is ensured without using loop2249 * to read the state.2250 */2251 snd_hdac_codec_read(hdev, hdev->afg, 0, AC_VERB_SET_POWER_STATE,2252 AC_PWRST_D3);2253 2254 hlink = snd_hdac_ext_bus_get_hlink_by_name(bus, dev_name(dev));2255 if (!hlink) {2256 dev_err(dev, "hdac link not found\n");2257 return -EIO;2258 }2259 2260 snd_hdac_codec_link_down(hdev);2261 snd_hdac_ext_bus_link_put(bus, hlink);2262 2263 snd_hdac_display_power(bus, hdev->addr, false);2264 2265 return 0;2266}2267 2268static int hdac_hdmi_runtime_resume(struct device *dev)2269{2270 struct hdac_device *hdev = dev_to_hdac_dev(dev);2271 struct hdac_bus *bus = hdev->bus;2272 struct hdac_ext_link *hlink;2273 2274 dev_dbg(dev, "Enter: %s\n", __func__);2275 2276 /* controller may not have been initialized for the first time */2277 if (!bus)2278 return 0;2279 2280 hlink = snd_hdac_ext_bus_get_hlink_by_name(bus, dev_name(dev));2281 if (!hlink) {2282 dev_err(dev, "hdac link not found\n");2283 return -EIO;2284 }2285 2286 snd_hdac_ext_bus_link_get(bus, hlink);2287 snd_hdac_codec_link_up(hdev);2288 2289 snd_hdac_display_power(bus, hdev->addr, true);2290 2291 hdac_hdmi_skl_enable_all_pins(hdev);2292 hdac_hdmi_skl_enable_dp12(hdev);2293 2294 /* Power up afg */2295 snd_hdac_codec_read(hdev, hdev->afg, 0, AC_VERB_SET_POWER_STATE,2296 AC_PWRST_D0);2297 2298 return 0;2299}2300#else2301#define hdac_hdmi_runtime_suspend NULL2302#define hdac_hdmi_runtime_resume NULL2303#endif2304 2305static const struct dev_pm_ops hdac_hdmi_pm = {2306 SET_RUNTIME_PM_OPS(hdac_hdmi_runtime_suspend, hdac_hdmi_runtime_resume, NULL)2307 SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, hdmi_codec_resume)2308};2309 2310static const struct hda_device_id hdmi_list[] = {2311 HDA_CODEC_EXT_ENTRY(0x80862809, 0x100000, "Skylake HDMI", 0),2312 HDA_CODEC_EXT_ENTRY(0x8086280a, 0x100000, "Broxton HDMI", 0),2313 HDA_CODEC_EXT_ENTRY(0x8086280b, 0x100000, "Kabylake HDMI", 0),2314 HDA_CODEC_EXT_ENTRY(0x8086280c, 0x100000, "Cannonlake HDMI",2315 &intel_glk_drv_data),2316 HDA_CODEC_EXT_ENTRY(0x8086280d, 0x100000, "Geminilake HDMI",2317 &intel_glk_drv_data),2318 {}2319};2320 2321MODULE_DEVICE_TABLE(hdaudio, hdmi_list);2322 2323static struct hdac_driver hdmi_driver = {2324 .driver = {2325 .name = "HDMI HDA Codec",2326 .pm = &hdac_hdmi_pm,2327 },2328 .id_table = hdmi_list,2329 .probe = hdac_hdmi_dev_probe,2330 .remove = hdac_hdmi_dev_remove,2331};2332 2333static int __init hdmi_init(void)2334{2335 return snd_hda_ext_driver_register(&hdmi_driver);2336}2337 2338static void __exit hdmi_exit(void)2339{2340 snd_hda_ext_driver_unregister(&hdmi_driver);2341}2342 2343module_init(hdmi_init);2344module_exit(hdmi_exit);2345 2346MODULE_LICENSE("GPL v2");2347MODULE_DESCRIPTION("HDMI HD codec");2348MODULE_AUTHOR("Samreen Nilofer<samreen.nilofer@intel.com>");2349MODULE_AUTHOR("Subhransu S. Prusty<subhransu.s.prusty@intel.com>");2350