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