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