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