cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

hdmi-codec.c (30205B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * ALSA SoC codec for HDMI encoder drivers
      4 * Copyright (C) 2015 Texas Instruments Incorporated - https://www.ti.com/
      5 * Author: Jyri Sarha <jsarha@ti.com>
      6 */
      7#include <linux/module.h>
      8#include <linux/string.h>
      9#include <sound/core.h>
     10#include <sound/jack.h>
     11#include <sound/pcm.h>
     12#include <sound/pcm_params.h>
     13#include <sound/soc.h>
     14#include <sound/tlv.h>
     15#include <sound/pcm_drm_eld.h>
     16#include <sound/hdmi-codec.h>
     17#include <sound/pcm_iec958.h>
     18
     19#include <drm/drm_crtc.h> /* This is only to get MAX_ELD_BYTES */
     20
     21#define HDMI_CODEC_CHMAP_IDX_UNKNOWN  -1
     22
     23struct hdmi_codec_channel_map_table {
     24	unsigned char map;	/* ALSA API channel map position */
     25};
     26
     27/*
     28 * CEA speaker placement for HDMI 1.4:
     29 *
     30 *  FL  FLC   FC   FRC   FR   FRW
     31 *
     32 *                                  LFE
     33 *
     34 *  RL  RLC   RC   RRC   RR
     35 *
     36 *  Speaker placement has to be extended to support HDMI 2.0
     37 */
     38enum hdmi_codec_cea_spk_placement {
     39	FL  = BIT(0),	/* Front Left           */
     40	FC  = BIT(1),	/* Front Center         */
     41	FR  = BIT(2),	/* Front Right          */
     42	FLC = BIT(3),	/* Front Left Center    */
     43	FRC = BIT(4),	/* Front Right Center   */
     44	RL  = BIT(5),	/* Rear Left            */
     45	RC  = BIT(6),	/* Rear Center          */
     46	RR  = BIT(7),	/* Rear Right           */
     47	RLC = BIT(8),	/* Rear Left Center     */
     48	RRC = BIT(9),	/* Rear Right Center    */
     49	LFE = BIT(10),	/* Low Frequency Effect */
     50};
     51
     52/*
     53 * cea Speaker allocation structure
     54 */
     55struct hdmi_codec_cea_spk_alloc {
     56	const int ca_id;
     57	unsigned int n_ch;
     58	unsigned long mask;
     59};
     60
     61/* Channel maps  stereo HDMI */
     62static const struct snd_pcm_chmap_elem hdmi_codec_stereo_chmaps[] = {
     63	{ .channels = 2,
     64	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
     65	{ }
     66};
     67
     68/* Channel maps for multi-channel playbacks, up to 8 n_ch */
     69static const struct snd_pcm_chmap_elem hdmi_codec_8ch_chmaps[] = {
     70	{ .channels = 2, /* CA_ID 0x00 */
     71	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
     72	{ .channels = 4, /* CA_ID 0x01 */
     73	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
     74		   SNDRV_CHMAP_NA } },
     75	{ .channels = 4, /* CA_ID 0x02 */
     76	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
     77		   SNDRV_CHMAP_FC } },
     78	{ .channels = 4, /* CA_ID 0x03 */
     79	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
     80		   SNDRV_CHMAP_FC } },
     81	{ .channels = 6, /* CA_ID 0x04 */
     82	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
     83		   SNDRV_CHMAP_NA, SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
     84	{ .channels = 6, /* CA_ID 0x05 */
     85	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
     86		   SNDRV_CHMAP_NA, SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
     87	{ .channels = 6, /* CA_ID 0x06 */
     88	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
     89		   SNDRV_CHMAP_FC, SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
     90	{ .channels = 6, /* CA_ID 0x07 */
     91	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
     92		   SNDRV_CHMAP_FC, SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
     93	{ .channels = 6, /* CA_ID 0x08 */
     94	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
     95		   SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
     96	{ .channels = 6, /* CA_ID 0x09 */
     97	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
     98		   SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
     99	{ .channels = 6, /* CA_ID 0x0A */
    100	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
    101		   SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
    102	{ .channels = 6, /* CA_ID 0x0B */
    103	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
    104		   SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
    105	{ .channels = 8, /* CA_ID 0x0C */
    106	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
    107		   SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
    108		   SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
    109	{ .channels = 8, /* CA_ID 0x0D */
    110	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
    111		   SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
    112		   SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
    113	{ .channels = 8, /* CA_ID 0x0E */
    114	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
    115		   SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
    116		   SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
    117	{ .channels = 8, /* CA_ID 0x0F */
    118	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
    119		   SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
    120		   SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
    121	{ .channels = 8, /* CA_ID 0x10 */
    122	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
    123		   SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
    124		   SNDRV_CHMAP_RLC, SNDRV_CHMAP_RRC } },
    125	{ .channels = 8, /* CA_ID 0x11 */
    126	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
    127		   SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
    128		   SNDRV_CHMAP_RLC, SNDRV_CHMAP_RRC } },
    129	{ .channels = 8, /* CA_ID 0x12 */
    130	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
    131		   SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
    132		   SNDRV_CHMAP_RLC, SNDRV_CHMAP_RRC } },
    133	{ .channels = 8, /* CA_ID 0x13 */
    134	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
    135		   SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
    136		   SNDRV_CHMAP_RLC, SNDRV_CHMAP_RRC } },
    137	{ .channels = 8, /* CA_ID 0x14 */
    138	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
    139		   SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
    140		   SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
    141	{ .channels = 8, /* CA_ID 0x15 */
    142	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
    143		   SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
    144		   SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
    145	{ .channels = 8, /* CA_ID 0x16 */
    146	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
    147		   SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
    148		   SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
    149	{ .channels = 8, /* CA_ID 0x17 */
    150	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
    151		   SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
    152		   SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
    153	{ .channels = 8, /* CA_ID 0x18 */
    154	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
    155		   SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
    156		   SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
    157	{ .channels = 8, /* CA_ID 0x19 */
    158	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
    159		   SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
    160		   SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
    161	{ .channels = 8, /* CA_ID 0x1A */
    162	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
    163		   SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
    164		   SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
    165	{ .channels = 8, /* CA_ID 0x1B */
    166	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
    167		   SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
    168		   SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
    169	{ .channels = 8, /* CA_ID 0x1C */
    170	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
    171		   SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
    172		   SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
    173	{ .channels = 8, /* CA_ID 0x1D */
    174	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
    175		   SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
    176		   SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
    177	{ .channels = 8, /* CA_ID 0x1E */
    178	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
    179		   SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
    180		   SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
    181	{ .channels = 8, /* CA_ID 0x1F */
    182	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
    183		   SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
    184		   SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
    185	{ }
    186};
    187
    188/*
    189 * hdmi_codec_channel_alloc: speaker configuration available for CEA
    190 *
    191 * This is an ordered list that must match with hdmi_codec_8ch_chmaps struct
    192 * The preceding ones have better chances to be selected by
    193 * hdmi_codec_get_ch_alloc_table_idx().
    194 */
    195static const struct hdmi_codec_cea_spk_alloc hdmi_codec_channel_alloc[] = {
    196	{ .ca_id = 0x00, .n_ch = 2,
    197	  .mask = FL | FR},
    198	/* 2.1 */
    199	{ .ca_id = 0x01, .n_ch = 4,
    200	  .mask = FL | FR | LFE},
    201	/* Dolby Surround */
    202	{ .ca_id = 0x02, .n_ch = 4,
    203	  .mask = FL | FR | FC },
    204	/* surround51 */
    205	{ .ca_id = 0x0b, .n_ch = 6,
    206	  .mask = FL | FR | LFE | FC | RL | RR},
    207	/* surround40 */
    208	{ .ca_id = 0x08, .n_ch = 6,
    209	  .mask = FL | FR | RL | RR },
    210	/* surround41 */
    211	{ .ca_id = 0x09, .n_ch = 6,
    212	  .mask = FL | FR | LFE | RL | RR },
    213	/* surround50 */
    214	{ .ca_id = 0x0a, .n_ch = 6,
    215	  .mask = FL | FR | FC | RL | RR },
    216	/* 6.1 */
    217	{ .ca_id = 0x0f, .n_ch = 8,
    218	  .mask = FL | FR | LFE | FC | RL | RR | RC },
    219	/* surround71 */
    220	{ .ca_id = 0x13, .n_ch = 8,
    221	  .mask = FL | FR | LFE | FC | RL | RR | RLC | RRC },
    222	/* others */
    223	{ .ca_id = 0x03, .n_ch = 8,
    224	  .mask = FL | FR | LFE | FC },
    225	{ .ca_id = 0x04, .n_ch = 8,
    226	  .mask = FL | FR | RC},
    227	{ .ca_id = 0x05, .n_ch = 8,
    228	  .mask = FL | FR | LFE | RC },
    229	{ .ca_id = 0x06, .n_ch = 8,
    230	  .mask = FL | FR | FC | RC },
    231	{ .ca_id = 0x07, .n_ch = 8,
    232	  .mask = FL | FR | LFE | FC | RC },
    233	{ .ca_id = 0x0c, .n_ch = 8,
    234	  .mask = FL | FR | RC | RL | RR },
    235	{ .ca_id = 0x0d, .n_ch = 8,
    236	  .mask = FL | FR | LFE | RL | RR | RC },
    237	{ .ca_id = 0x0e, .n_ch = 8,
    238	  .mask = FL | FR | FC | RL | RR | RC },
    239	{ .ca_id = 0x10, .n_ch = 8,
    240	  .mask = FL | FR | RL | RR | RLC | RRC },
    241	{ .ca_id = 0x11, .n_ch = 8,
    242	  .mask = FL | FR | LFE | RL | RR | RLC | RRC },
    243	{ .ca_id = 0x12, .n_ch = 8,
    244	  .mask = FL | FR | FC | RL | RR | RLC | RRC },
    245	{ .ca_id = 0x14, .n_ch = 8,
    246	  .mask = FL | FR | FLC | FRC },
    247	{ .ca_id = 0x15, .n_ch = 8,
    248	  .mask = FL | FR | LFE | FLC | FRC },
    249	{ .ca_id = 0x16, .n_ch = 8,
    250	  .mask = FL | FR | FC | FLC | FRC },
    251	{ .ca_id = 0x17, .n_ch = 8,
    252	  .mask = FL | FR | LFE | FC | FLC | FRC },
    253	{ .ca_id = 0x18, .n_ch = 8,
    254	  .mask = FL | FR | RC | FLC | FRC },
    255	{ .ca_id = 0x19, .n_ch = 8,
    256	  .mask = FL | FR | LFE | RC | FLC | FRC },
    257	{ .ca_id = 0x1a, .n_ch = 8,
    258	  .mask = FL | FR | RC | FC | FLC | FRC },
    259	{ .ca_id = 0x1b, .n_ch = 8,
    260	  .mask = FL | FR | LFE | RC | FC | FLC | FRC },
    261	{ .ca_id = 0x1c, .n_ch = 8,
    262	  .mask = FL | FR | RL | RR | FLC | FRC },
    263	{ .ca_id = 0x1d, .n_ch = 8,
    264	  .mask = FL | FR | LFE | RL | RR | FLC | FRC },
    265	{ .ca_id = 0x1e, .n_ch = 8,
    266	  .mask = FL | FR | FC | RL | RR | FLC | FRC },
    267	{ .ca_id = 0x1f, .n_ch = 8,
    268	  .mask = FL | FR | LFE | FC | RL | RR | FLC | FRC },
    269};
    270
    271struct hdmi_codec_priv {
    272	struct hdmi_codec_pdata hcd;
    273	uint8_t eld[MAX_ELD_BYTES];
    274	struct snd_pcm_chmap *chmap_info;
    275	unsigned int chmap_idx;
    276	struct mutex lock;
    277	bool busy;
    278	struct snd_soc_jack *jack;
    279	unsigned int jack_status;
    280	u8 iec_status[AES_IEC958_STATUS_SIZE];
    281};
    282
    283static const struct snd_soc_dapm_widget hdmi_widgets[] = {
    284	SND_SOC_DAPM_OUTPUT("TX"),
    285	SND_SOC_DAPM_OUTPUT("RX"),
    286};
    287
    288enum {
    289	DAI_ID_I2S = 0,
    290	DAI_ID_SPDIF,
    291};
    292
    293static int hdmi_eld_ctl_info(struct snd_kcontrol *kcontrol,
    294			     struct snd_ctl_elem_info *uinfo)
    295{
    296	uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
    297	uinfo->count = sizeof_field(struct hdmi_codec_priv, eld);
    298
    299	return 0;
    300}
    301
    302static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol,
    303			    struct snd_ctl_elem_value *ucontrol)
    304{
    305	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
    306	struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component);
    307
    308	memcpy(ucontrol->value.bytes.data, hcp->eld, sizeof(hcp->eld));
    309
    310	return 0;
    311}
    312
    313static unsigned long hdmi_codec_spk_mask_from_alloc(int spk_alloc)
    314{
    315	int i;
    316	static const unsigned long hdmi_codec_eld_spk_alloc_bits[] = {
    317		[0] = FL | FR, [1] = LFE, [2] = FC, [3] = RL | RR,
    318		[4] = RC, [5] = FLC | FRC, [6] = RLC | RRC,
    319	};
    320	unsigned long spk_mask = 0;
    321
    322	for (i = 0; i < ARRAY_SIZE(hdmi_codec_eld_spk_alloc_bits); i++) {
    323		if (spk_alloc & (1 << i))
    324			spk_mask |= hdmi_codec_eld_spk_alloc_bits[i];
    325	}
    326
    327	return spk_mask;
    328}
    329
    330static void hdmi_codec_eld_chmap(struct hdmi_codec_priv *hcp)
    331{
    332	u8 spk_alloc;
    333	unsigned long spk_mask;
    334
    335	spk_alloc = drm_eld_get_spk_alloc(hcp->eld);
    336	spk_mask = hdmi_codec_spk_mask_from_alloc(spk_alloc);
    337
    338	/* Detect if only stereo supported, else return 8 channels mappings */
    339	if ((spk_mask & ~(FL | FR)) && hcp->chmap_info->max_channels > 2)
    340		hcp->chmap_info->chmap = hdmi_codec_8ch_chmaps;
    341	else
    342		hcp->chmap_info->chmap = hdmi_codec_stereo_chmaps;
    343}
    344
    345static int hdmi_codec_get_ch_alloc_table_idx(struct hdmi_codec_priv *hcp,
    346					     unsigned char channels)
    347{
    348	int i;
    349	u8 spk_alloc;
    350	unsigned long spk_mask;
    351	const struct hdmi_codec_cea_spk_alloc *cap = hdmi_codec_channel_alloc;
    352
    353	spk_alloc = drm_eld_get_spk_alloc(hcp->eld);
    354	spk_mask = hdmi_codec_spk_mask_from_alloc(spk_alloc);
    355
    356	for (i = 0; i < ARRAY_SIZE(hdmi_codec_channel_alloc); i++, cap++) {
    357		/* If spk_alloc == 0, HDMI is unplugged return stereo config*/
    358		if (!spk_alloc && cap->ca_id == 0)
    359			return i;
    360		if (cap->n_ch != channels)
    361			continue;
    362		if (!(cap->mask == (spk_mask & cap->mask)))
    363			continue;
    364		return i;
    365	}
    366
    367	return -EINVAL;
    368}
    369static int hdmi_codec_chmap_ctl_get(struct snd_kcontrol *kcontrol,
    370			      struct snd_ctl_elem_value *ucontrol)
    371{
    372	unsigned const char *map;
    373	unsigned int i;
    374	struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
    375	struct hdmi_codec_priv *hcp = info->private_data;
    376
    377	map = info->chmap[hcp->chmap_idx].map;
    378
    379	for (i = 0; i < info->max_channels; i++) {
    380		if (hcp->chmap_idx == HDMI_CODEC_CHMAP_IDX_UNKNOWN)
    381			ucontrol->value.integer.value[i] = 0;
    382		else
    383			ucontrol->value.integer.value[i] = map[i];
    384	}
    385
    386	return 0;
    387}
    388
    389static int hdmi_codec_iec958_info(struct snd_kcontrol *kcontrol,
    390				  struct snd_ctl_elem_info *uinfo)
    391{
    392	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
    393	uinfo->count = 1;
    394	return 0;
    395}
    396
    397static int hdmi_codec_iec958_default_get(struct snd_kcontrol *kcontrol,
    398					 struct snd_ctl_elem_value *ucontrol)
    399{
    400	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
    401	struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component);
    402
    403	memcpy(ucontrol->value.iec958.status, hcp->iec_status,
    404	       sizeof(hcp->iec_status));
    405
    406	return 0;
    407}
    408
    409static int hdmi_codec_iec958_default_put(struct snd_kcontrol *kcontrol,
    410					 struct snd_ctl_elem_value *ucontrol)
    411{
    412	struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
    413	struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component);
    414
    415	memcpy(hcp->iec_status, ucontrol->value.iec958.status,
    416	       sizeof(hcp->iec_status));
    417
    418	return 0;
    419}
    420
    421static int hdmi_codec_iec958_mask_get(struct snd_kcontrol *kcontrol,
    422				      struct snd_ctl_elem_value *ucontrol)
    423{
    424	memset(ucontrol->value.iec958.status, 0xff,
    425	       sizeof_field(struct hdmi_codec_priv, iec_status));
    426
    427	return 0;
    428}
    429
    430static int hdmi_codec_startup(struct snd_pcm_substream *substream,
    431			      struct snd_soc_dai *dai)
    432{
    433	struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
    434	bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
    435	int ret = 0;
    436
    437	mutex_lock(&hcp->lock);
    438	if (hcp->busy) {
    439		dev_err(dai->dev, "Only one simultaneous stream supported!\n");
    440		mutex_unlock(&hcp->lock);
    441		return -EINVAL;
    442	}
    443
    444	if (hcp->hcd.ops->audio_startup) {
    445		ret = hcp->hcd.ops->audio_startup(dai->dev->parent, hcp->hcd.data);
    446		if (ret)
    447			goto err;
    448	}
    449
    450	if (tx && hcp->hcd.ops->get_eld) {
    451		ret = hcp->hcd.ops->get_eld(dai->dev->parent, hcp->hcd.data,
    452					    hcp->eld, sizeof(hcp->eld));
    453		if (ret)
    454			goto err;
    455
    456		ret = snd_pcm_hw_constraint_eld(substream->runtime, hcp->eld);
    457		if (ret)
    458			goto err;
    459
    460		/* Select chmap supported */
    461		hdmi_codec_eld_chmap(hcp);
    462	}
    463
    464	hcp->busy = true;
    465
    466err:
    467	mutex_unlock(&hcp->lock);
    468	return ret;
    469}
    470
    471static void hdmi_codec_shutdown(struct snd_pcm_substream *substream,
    472				struct snd_soc_dai *dai)
    473{
    474	struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
    475
    476	hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN;
    477	hcp->hcd.ops->audio_shutdown(dai->dev->parent, hcp->hcd.data);
    478
    479	mutex_lock(&hcp->lock);
    480	hcp->busy = false;
    481	mutex_unlock(&hcp->lock);
    482}
    483
    484static int hdmi_codec_fill_codec_params(struct snd_soc_dai *dai,
    485					unsigned int sample_width,
    486					unsigned int sample_rate,
    487					unsigned int channels,
    488					struct hdmi_codec_params *hp)
    489{
    490	struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
    491	int idx;
    492
    493	/* Select a channel allocation that matches with ELD and pcm channels */
    494	idx = hdmi_codec_get_ch_alloc_table_idx(hcp, channels);
    495	if (idx < 0) {
    496		dev_err(dai->dev, "Not able to map channels to speakers (%d)\n",
    497			idx);
    498		hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN;
    499		return idx;
    500	}
    501
    502	memset(hp, 0, sizeof(*hp));
    503
    504	hdmi_audio_infoframe_init(&hp->cea);
    505	hp->cea.channels = channels;
    506	hp->cea.coding_type = HDMI_AUDIO_CODING_TYPE_STREAM;
    507	hp->cea.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM;
    508	hp->cea.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM;
    509	hp->cea.channel_allocation = hdmi_codec_channel_alloc[idx].ca_id;
    510
    511	hp->sample_width = sample_width;
    512	hp->sample_rate = sample_rate;
    513	hp->channels = channels;
    514
    515	hcp->chmap_idx = hdmi_codec_channel_alloc[idx].ca_id;
    516
    517	return 0;
    518}
    519
    520static int hdmi_codec_hw_params(struct snd_pcm_substream *substream,
    521				struct snd_pcm_hw_params *params,
    522				struct snd_soc_dai *dai)
    523{
    524	struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
    525	struct hdmi_codec_daifmt *cf = dai->playback_dma_data;
    526	struct hdmi_codec_params hp = {
    527		.iec = {
    528			.status = { 0 },
    529			.subcode = { 0 },
    530			.pad = 0,
    531			.dig_subframe = { 0 },
    532		}
    533	};
    534	int ret;
    535
    536	if (!hcp->hcd.ops->hw_params)
    537		return 0;
    538
    539	dev_dbg(dai->dev, "%s() width %d rate %d channels %d\n", __func__,
    540		params_width(params), params_rate(params),
    541		params_channels(params));
    542
    543	ret = hdmi_codec_fill_codec_params(dai,
    544					   params_width(params),
    545					   params_rate(params),
    546					   params_channels(params),
    547					   &hp);
    548	if (ret < 0)
    549		return ret;
    550
    551	memcpy(hp.iec.status, hcp->iec_status, sizeof(hp.iec.status));
    552	ret = snd_pcm_fill_iec958_consumer_hw_params(params, hp.iec.status,
    553						     sizeof(hp.iec.status));
    554	if (ret < 0) {
    555		dev_err(dai->dev, "Creating IEC958 channel status failed %d\n",
    556			ret);
    557		return ret;
    558	}
    559
    560	cf->bit_fmt = params_format(params);
    561	return hcp->hcd.ops->hw_params(dai->dev->parent, hcp->hcd.data,
    562				       cf, &hp);
    563}
    564
    565static int hdmi_codec_prepare(struct snd_pcm_substream *substream,
    566			      struct snd_soc_dai *dai)
    567{
    568	struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
    569	struct hdmi_codec_daifmt *cf = dai->playback_dma_data;
    570	struct snd_pcm_runtime *runtime = substream->runtime;
    571	unsigned int channels = runtime->channels;
    572	unsigned int width = snd_pcm_format_width(runtime->format);
    573	unsigned int rate = runtime->rate;
    574	struct hdmi_codec_params hp;
    575	int ret;
    576
    577	if (!hcp->hcd.ops->prepare)
    578		return 0;
    579
    580	dev_dbg(dai->dev, "%s() width %d rate %d channels %d\n", __func__,
    581		width, rate, channels);
    582
    583	ret = hdmi_codec_fill_codec_params(dai, width, rate, channels, &hp);
    584	if (ret < 0)
    585		return ret;
    586
    587	memcpy(hp.iec.status, hcp->iec_status, sizeof(hp.iec.status));
    588	ret = snd_pcm_fill_iec958_consumer(runtime, hp.iec.status,
    589					   sizeof(hp.iec.status));
    590	if (ret < 0) {
    591		dev_err(dai->dev, "Creating IEC958 channel status failed %d\n",
    592			ret);
    593		return ret;
    594	}
    595
    596	cf->bit_fmt = runtime->format;
    597	return hcp->hcd.ops->prepare(dai->dev->parent, hcp->hcd.data,
    598				     cf, &hp);
    599}
    600
    601static int hdmi_codec_i2s_set_fmt(struct snd_soc_dai *dai,
    602				  unsigned int fmt)
    603{
    604	struct hdmi_codec_daifmt *cf = dai->playback_dma_data;
    605
    606	/* Reset daifmt */
    607	memset(cf, 0, sizeof(*cf));
    608
    609	switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
    610	case SND_SOC_DAIFMT_CBM_CFM:
    611		cf->bit_clk_master = 1;
    612		cf->frame_clk_master = 1;
    613		break;
    614	case SND_SOC_DAIFMT_CBS_CFM:
    615		cf->frame_clk_master = 1;
    616		break;
    617	case SND_SOC_DAIFMT_CBM_CFS:
    618		cf->bit_clk_master = 1;
    619		break;
    620	case SND_SOC_DAIFMT_CBS_CFS:
    621		break;
    622	default:
    623		return -EINVAL;
    624	}
    625
    626	switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
    627	case SND_SOC_DAIFMT_NB_NF:
    628		break;
    629	case SND_SOC_DAIFMT_NB_IF:
    630		cf->frame_clk_inv = 1;
    631		break;
    632	case SND_SOC_DAIFMT_IB_NF:
    633		cf->bit_clk_inv = 1;
    634		break;
    635	case SND_SOC_DAIFMT_IB_IF:
    636		cf->frame_clk_inv = 1;
    637		cf->bit_clk_inv = 1;
    638		break;
    639	}
    640
    641	switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
    642	case SND_SOC_DAIFMT_I2S:
    643		cf->fmt = HDMI_I2S;
    644		break;
    645	case SND_SOC_DAIFMT_DSP_A:
    646		cf->fmt = HDMI_DSP_A;
    647		break;
    648	case SND_SOC_DAIFMT_DSP_B:
    649		cf->fmt = HDMI_DSP_B;
    650		break;
    651	case SND_SOC_DAIFMT_RIGHT_J:
    652		cf->fmt = HDMI_RIGHT_J;
    653		break;
    654	case SND_SOC_DAIFMT_LEFT_J:
    655		cf->fmt = HDMI_LEFT_J;
    656		break;
    657	case SND_SOC_DAIFMT_AC97:
    658		cf->fmt = HDMI_AC97;
    659		break;
    660	default:
    661		dev_err(dai->dev, "Invalid DAI interface format\n");
    662		return -EINVAL;
    663	}
    664
    665	return 0;
    666}
    667
    668static int hdmi_codec_mute(struct snd_soc_dai *dai, int mute, int direction)
    669{
    670	struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
    671
    672	/*
    673	 * ignore if direction was CAPTURE
    674	 * and it had .no_capture_mute flag
    675	 * see
    676	 *	snd_soc_dai_digital_mute()
    677	 */
    678	if (hcp->hcd.ops->mute_stream &&
    679	    (direction == SNDRV_PCM_STREAM_PLAYBACK ||
    680	     !hcp->hcd.ops->no_capture_mute))
    681		return hcp->hcd.ops->mute_stream(dai->dev->parent,
    682						 hcp->hcd.data,
    683						 mute, direction);
    684
    685	return -ENOTSUPP;
    686}
    687
    688/*
    689 * This driver can select all SND_SOC_DAIFMT_CBx_CFx,
    690 * but need to be selected from Sound Card, not be auto selected.
    691 * Because it might be used from other driver.
    692 * For example,
    693 *	${LINUX}/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
    694 */
    695static u64 hdmi_codec_formats =
    696	SND_SOC_POSSIBLE_DAIFMT_NB_NF	|
    697	SND_SOC_POSSIBLE_DAIFMT_NB_IF	|
    698	SND_SOC_POSSIBLE_DAIFMT_IB_NF	|
    699	SND_SOC_POSSIBLE_DAIFMT_IB_IF	|
    700	SND_SOC_POSSIBLE_DAIFMT_I2S	|
    701	SND_SOC_POSSIBLE_DAIFMT_DSP_A	|
    702	SND_SOC_POSSIBLE_DAIFMT_DSP_B	|
    703	SND_SOC_POSSIBLE_DAIFMT_RIGHT_J	|
    704	SND_SOC_POSSIBLE_DAIFMT_LEFT_J	|
    705	SND_SOC_POSSIBLE_DAIFMT_AC97;
    706
    707static const struct snd_soc_dai_ops hdmi_codec_i2s_dai_ops = {
    708	.startup	= hdmi_codec_startup,
    709	.shutdown	= hdmi_codec_shutdown,
    710	.hw_params	= hdmi_codec_hw_params,
    711	.prepare	= hdmi_codec_prepare,
    712	.set_fmt	= hdmi_codec_i2s_set_fmt,
    713	.mute_stream	= hdmi_codec_mute,
    714	.auto_selectable_formats	= &hdmi_codec_formats,
    715	.num_auto_selectable_formats	= 1,
    716};
    717
    718static const struct snd_soc_dai_ops hdmi_codec_spdif_dai_ops = {
    719	.startup	= hdmi_codec_startup,
    720	.shutdown	= hdmi_codec_shutdown,
    721	.hw_params	= hdmi_codec_hw_params,
    722	.mute_stream	= hdmi_codec_mute,
    723};
    724
    725#define HDMI_RATES	(SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
    726			 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
    727			 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |\
    728			 SNDRV_PCM_RATE_192000)
    729
    730#define SPDIF_FORMATS	(SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
    731			 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_LE)
    732
    733/*
    734 * This list is only for formats allowed on the I2S bus. So there is
    735 * some formats listed that are not supported by HDMI interface. For
    736 * instance allowing the 32-bit formats enables 24-precision with CPU
    737 * DAIs that do not support 24-bit formats. If the extra formats cause
    738 * problems, we should add the video side driver an option to disable
    739 * them.
    740 */
    741#define I2S_FORMATS	(SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
    742			 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_LE |\
    743			 SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE)
    744
    745static struct snd_kcontrol_new hdmi_codec_controls[] = {
    746	{
    747		.access = SNDRV_CTL_ELEM_ACCESS_READ,
    748		.iface = SNDRV_CTL_ELEM_IFACE_PCM,
    749		.name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, MASK),
    750		.info = hdmi_codec_iec958_info,
    751		.get = hdmi_codec_iec958_mask_get,
    752	},
    753	{
    754		.iface = SNDRV_CTL_ELEM_IFACE_PCM,
    755		.name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
    756		.info = hdmi_codec_iec958_info,
    757		.get = hdmi_codec_iec958_default_get,
    758		.put = hdmi_codec_iec958_default_put,
    759	},
    760	{
    761		.access	= (SNDRV_CTL_ELEM_ACCESS_READ |
    762			   SNDRV_CTL_ELEM_ACCESS_VOLATILE),
    763		.iface	= SNDRV_CTL_ELEM_IFACE_PCM,
    764		.name	= "ELD",
    765		.info	= hdmi_eld_ctl_info,
    766		.get	= hdmi_eld_ctl_get,
    767	},
    768};
    769
    770static int hdmi_codec_pcm_new(struct snd_soc_pcm_runtime *rtd,
    771			      struct snd_soc_dai *dai)
    772{
    773	struct snd_soc_dai_driver *drv = dai->driver;
    774	struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
    775	unsigned int i;
    776	int ret;
    777
    778	ret =  snd_pcm_add_chmap_ctls(rtd->pcm, SNDRV_PCM_STREAM_PLAYBACK,
    779				      NULL, drv->playback.channels_max, 0,
    780				      &hcp->chmap_info);
    781	if (ret < 0)
    782		return ret;
    783
    784	/* override handlers */
    785	hcp->chmap_info->private_data = hcp;
    786	hcp->chmap_info->kctl->get = hdmi_codec_chmap_ctl_get;
    787
    788	/* default chmap supported is stereo */
    789	hcp->chmap_info->chmap = hdmi_codec_stereo_chmaps;
    790	hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN;
    791
    792	for (i = 0; i < ARRAY_SIZE(hdmi_codec_controls); i++) {
    793		struct snd_kcontrol *kctl;
    794
    795		/* add ELD ctl with the device number corresponding to the PCM stream */
    796		kctl = snd_ctl_new1(&hdmi_codec_controls[i], dai->component);
    797		if (!kctl)
    798			return -ENOMEM;
    799
    800		kctl->id.device = rtd->pcm->device;
    801		ret = snd_ctl_add(rtd->card->snd_card, kctl);
    802		if (ret < 0)
    803			return ret;
    804	}
    805
    806	return 0;
    807}
    808
    809static int hdmi_dai_probe(struct snd_soc_dai *dai)
    810{
    811	struct snd_soc_dapm_context *dapm;
    812	struct hdmi_codec_daifmt *daifmt;
    813	struct snd_soc_dapm_route route[] = {
    814		{
    815			.sink = "TX",
    816			.source = dai->driver->playback.stream_name,
    817		},
    818		{
    819			.sink = dai->driver->capture.stream_name,
    820			.source = "RX",
    821		},
    822	};
    823	int ret;
    824
    825	dapm = snd_soc_component_get_dapm(dai->component);
    826	ret = snd_soc_dapm_add_routes(dapm, route, 2);
    827	if (ret)
    828		return ret;
    829
    830	daifmt = kzalloc(sizeof(*daifmt), GFP_KERNEL);
    831	if (!daifmt)
    832		return -ENOMEM;
    833
    834	dai->playback_dma_data = daifmt;
    835	return 0;
    836}
    837
    838static void hdmi_codec_jack_report(struct hdmi_codec_priv *hcp,
    839				   unsigned int jack_status)
    840{
    841	if (hcp->jack && jack_status != hcp->jack_status) {
    842		snd_soc_jack_report(hcp->jack, jack_status, SND_JACK_LINEOUT);
    843		hcp->jack_status = jack_status;
    844	}
    845}
    846
    847static void plugged_cb(struct device *dev, bool plugged)
    848{
    849	struct hdmi_codec_priv *hcp = dev_get_drvdata(dev);
    850
    851	if (plugged) {
    852		if (hcp->hcd.ops->get_eld) {
    853			hcp->hcd.ops->get_eld(dev->parent, hcp->hcd.data,
    854					    hcp->eld, sizeof(hcp->eld));
    855		}
    856		hdmi_codec_jack_report(hcp, SND_JACK_LINEOUT);
    857	} else {
    858		hdmi_codec_jack_report(hcp, 0);
    859		memset(hcp->eld, 0, sizeof(hcp->eld));
    860	}
    861}
    862
    863static int hdmi_codec_set_jack(struct snd_soc_component *component,
    864			       struct snd_soc_jack *jack,
    865			       void *data)
    866{
    867	struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component);
    868	int ret = -ENOTSUPP;
    869
    870	if (hcp->hcd.ops->hook_plugged_cb) {
    871		hcp->jack = jack;
    872		ret = hcp->hcd.ops->hook_plugged_cb(component->dev->parent,
    873						    hcp->hcd.data,
    874						    plugged_cb,
    875						    component->dev);
    876		if (ret)
    877			hcp->jack = NULL;
    878	}
    879	return ret;
    880}
    881
    882static int hdmi_dai_spdif_probe(struct snd_soc_dai *dai)
    883{
    884	struct hdmi_codec_daifmt *cf;
    885	int ret;
    886
    887	ret = hdmi_dai_probe(dai);
    888	if (ret)
    889		return ret;
    890
    891	cf = dai->playback_dma_data;
    892	cf->fmt = HDMI_SPDIF;
    893
    894	return 0;
    895}
    896
    897static int hdmi_codec_dai_remove(struct snd_soc_dai *dai)
    898{
    899	kfree(dai->playback_dma_data);
    900	return 0;
    901}
    902
    903static const struct snd_soc_dai_driver hdmi_i2s_dai = {
    904	.name = "i2s-hifi",
    905	.id = DAI_ID_I2S,
    906	.probe = hdmi_dai_probe,
    907	.remove = hdmi_codec_dai_remove,
    908	.playback = {
    909		.stream_name = "I2S Playback",
    910		.channels_min = 2,
    911		.channels_max = 8,
    912		.rates = HDMI_RATES,
    913		.formats = I2S_FORMATS,
    914		.sig_bits = 24,
    915	},
    916	.capture = {
    917		.stream_name = "Capture",
    918		.channels_min = 2,
    919		.channels_max = 8,
    920		.rates = HDMI_RATES,
    921		.formats = I2S_FORMATS,
    922		.sig_bits = 24,
    923	},
    924	.ops = &hdmi_codec_i2s_dai_ops,
    925	.pcm_new = hdmi_codec_pcm_new,
    926};
    927
    928static const struct snd_soc_dai_driver hdmi_spdif_dai = {
    929	.name = "spdif-hifi",
    930	.id = DAI_ID_SPDIF,
    931	.probe = hdmi_dai_spdif_probe,
    932	.remove = hdmi_codec_dai_remove,
    933	.playback = {
    934		.stream_name = "SPDIF Playback",
    935		.channels_min = 2,
    936		.channels_max = 2,
    937		.rates = HDMI_RATES,
    938		.formats = SPDIF_FORMATS,
    939	},
    940	.capture = {
    941		.stream_name = "Capture",
    942		.channels_min = 2,
    943		.channels_max = 2,
    944		.rates = HDMI_RATES,
    945		.formats = SPDIF_FORMATS,
    946	},
    947	.ops = &hdmi_codec_spdif_dai_ops,
    948	.pcm_new = hdmi_codec_pcm_new,
    949};
    950
    951static int hdmi_of_xlate_dai_id(struct snd_soc_component *component,
    952				 struct device_node *endpoint)
    953{
    954	struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component);
    955	int ret = -ENOTSUPP; /* see snd_soc_get_dai_id() */
    956
    957	if (hcp->hcd.ops->get_dai_id)
    958		ret = hcp->hcd.ops->get_dai_id(component, endpoint);
    959
    960	return ret;
    961}
    962
    963static void hdmi_remove(struct snd_soc_component *component)
    964{
    965	struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component);
    966
    967	if (hcp->hcd.ops->hook_plugged_cb)
    968		hcp->hcd.ops->hook_plugged_cb(component->dev->parent,
    969					      hcp->hcd.data, NULL, NULL);
    970}
    971
    972static const struct snd_soc_component_driver hdmi_driver = {
    973	.remove			= hdmi_remove,
    974	.dapm_widgets		= hdmi_widgets,
    975	.num_dapm_widgets	= ARRAY_SIZE(hdmi_widgets),
    976	.of_xlate_dai_id	= hdmi_of_xlate_dai_id,
    977	.idle_bias_on		= 1,
    978	.use_pmdown_time	= 1,
    979	.endianness		= 1,
    980	.non_legacy_dai_naming	= 1,
    981	.set_jack		= hdmi_codec_set_jack,
    982};
    983
    984static int hdmi_codec_probe(struct platform_device *pdev)
    985{
    986	struct hdmi_codec_pdata *hcd = pdev->dev.platform_data;
    987	struct snd_soc_dai_driver *daidrv;
    988	struct device *dev = &pdev->dev;
    989	struct hdmi_codec_priv *hcp;
    990	int dai_count, i = 0;
    991	int ret;
    992
    993	if (!hcd) {
    994		dev_err(dev, "%s: No platform data\n", __func__);
    995		return -EINVAL;
    996	}
    997
    998	dai_count = hcd->i2s + hcd->spdif;
    999	if (dai_count < 1 || !hcd->ops ||
   1000	    (!hcd->ops->hw_params && !hcd->ops->prepare) ||
   1001	    !hcd->ops->audio_shutdown) {
   1002		dev_err(dev, "%s: Invalid parameters\n", __func__);
   1003		return -EINVAL;
   1004	}
   1005
   1006	hcp = devm_kzalloc(dev, sizeof(*hcp), GFP_KERNEL);
   1007	if (!hcp)
   1008		return -ENOMEM;
   1009
   1010	hcp->hcd = *hcd;
   1011	mutex_init(&hcp->lock);
   1012
   1013	ret = snd_pcm_create_iec958_consumer_default(hcp->iec_status,
   1014						     sizeof(hcp->iec_status));
   1015	if (ret < 0)
   1016		return ret;
   1017
   1018	daidrv = devm_kcalloc(dev, dai_count, sizeof(*daidrv), GFP_KERNEL);
   1019	if (!daidrv)
   1020		return -ENOMEM;
   1021
   1022	if (hcd->i2s) {
   1023		daidrv[i] = hdmi_i2s_dai;
   1024		daidrv[i].playback.channels_max = hcd->max_i2s_channels;
   1025		i++;
   1026	}
   1027
   1028	if (hcd->spdif)
   1029		daidrv[i] = hdmi_spdif_dai;
   1030
   1031	dev_set_drvdata(dev, hcp);
   1032
   1033	ret = devm_snd_soc_register_component(dev, &hdmi_driver, daidrv,
   1034					      dai_count);
   1035	if (ret) {
   1036		dev_err(dev, "%s: snd_soc_register_component() failed (%d)\n",
   1037			__func__, ret);
   1038		return ret;
   1039	}
   1040	return 0;
   1041}
   1042
   1043static struct platform_driver hdmi_codec_driver = {
   1044	.driver = {
   1045		.name = HDMI_CODEC_DRV_NAME,
   1046	},
   1047	.probe = hdmi_codec_probe,
   1048};
   1049
   1050module_platform_driver(hdmi_codec_driver);
   1051
   1052MODULE_AUTHOR("Jyri Sarha <jsarha@ti.com>");
   1053MODULE_DESCRIPTION("HDMI Audio Codec Driver");
   1054MODULE_LICENSE("GPL");
   1055MODULE_ALIAS("platform:" HDMI_CODEC_DRV_NAME);