2 * ALSA SoC codec for HDMI encoder drivers
3 * Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com/
4 * Author: Jyri Sarha <jsarha@ti.com>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * version 2 as published by the Free Software Foundation.
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
15 #include <linux/module.h>
16 #include <linux/string.h>
17 #include <sound/core.h>
18 #include <sound/pcm.h>
19 #include <sound/pcm_params.h>
20 #include <sound/soc.h>
21 #include <sound/pcm_drm_eld.h>
22 #include <sound/hdmi-codec.h>
23 #include <sound/pcm_iec958.h>
25 #include <drm/drm_crtc.h> /* This is only to get MAX_ELD_BYTES */
29 struct list_head list
;
32 #define pos_to_hdmi_device(pos) container_of((pos), struct hdmi_device, list)
33 LIST_HEAD(hdmi_device_list
);
35 #define DAI_NAME_SIZE 16
36 struct hdmi_codec_priv
{
37 struct hdmi_codec_pdata hcd
;
38 struct snd_soc_dai_driver
*daidrv
;
39 struct hdmi_codec_daifmt daifmt
[2];
40 struct mutex current_stream_lock
;
41 struct snd_pcm_substream
*current_stream
;
42 struct snd_pcm_hw_constraint_list ratec
;
43 uint8_t eld
[MAX_ELD_BYTES
];
46 static const struct snd_soc_dapm_widget hdmi_widgets
[] = {
47 SND_SOC_DAPM_OUTPUT("TX"),
50 static const struct snd_soc_dapm_route hdmi_routes
[] = {
51 { "TX", NULL
, "Playback" },
59 static int hdmi_eld_ctl_info(struct snd_kcontrol
*kcontrol
,
60 struct snd_ctl_elem_info
*uinfo
)
62 struct snd_soc_component
*component
= snd_kcontrol_chip(kcontrol
);
63 struct hdmi_codec_priv
*hcp
= snd_soc_component_get_drvdata(component
);
65 uinfo
->type
= SNDRV_CTL_ELEM_TYPE_BYTES
;
66 uinfo
->count
= sizeof(hcp
->eld
);
71 static int hdmi_eld_ctl_get(struct snd_kcontrol
*kcontrol
,
72 struct snd_ctl_elem_value
*ucontrol
)
74 struct snd_soc_component
*component
= snd_kcontrol_chip(kcontrol
);
75 struct hdmi_codec_priv
*hcp
= snd_soc_component_get_drvdata(component
);
77 memcpy(ucontrol
->value
.bytes
.data
, hcp
->eld
, sizeof(hcp
->eld
));
82 static const struct snd_kcontrol_new hdmi_controls
[] = {
84 .access
= SNDRV_CTL_ELEM_ACCESS_READ
|
85 SNDRV_CTL_ELEM_ACCESS_VOLATILE
,
86 .iface
= SNDRV_CTL_ELEM_IFACE_PCM
,
88 .info
= hdmi_eld_ctl_info
,
89 .get
= hdmi_eld_ctl_get
,
93 static int hdmi_codec_new_stream(struct snd_pcm_substream
*substream
,
94 struct snd_soc_dai
*dai
)
96 struct hdmi_codec_priv
*hcp
= snd_soc_dai_get_drvdata(dai
);
99 mutex_lock(&hcp
->current_stream_lock
);
100 if (!hcp
->current_stream
) {
101 hcp
->current_stream
= substream
;
102 } else if (hcp
->current_stream
!= substream
) {
103 dev_err(dai
->dev
, "Only one simultaneous stream supported!\n");
106 mutex_unlock(&hcp
->current_stream_lock
);
111 static int hdmi_codec_startup(struct snd_pcm_substream
*substream
,
112 struct snd_soc_dai
*dai
)
114 struct hdmi_codec_priv
*hcp
= snd_soc_dai_get_drvdata(dai
);
117 dev_dbg(dai
->dev
, "%s()\n", __func__
);
119 ret
= hdmi_codec_new_stream(substream
, dai
);
123 if (hcp
->hcd
.ops
->audio_startup
) {
124 ret
= hcp
->hcd
.ops
->audio_startup(dai
->dev
->parent
, hcp
->hcd
.data
);
126 mutex_lock(&hcp
->current_stream_lock
);
127 hcp
->current_stream
= NULL
;
128 mutex_unlock(&hcp
->current_stream_lock
);
133 if (hcp
->hcd
.ops
->get_eld
) {
134 ret
= hcp
->hcd
.ops
->get_eld(dai
->dev
->parent
, hcp
->hcd
.data
,
135 hcp
->eld
, sizeof(hcp
->eld
));
138 ret
= snd_pcm_hw_constraint_eld(substream
->runtime
,
147 static void hdmi_codec_shutdown(struct snd_pcm_substream
*substream
,
148 struct snd_soc_dai
*dai
)
150 struct hdmi_codec_priv
*hcp
= snd_soc_dai_get_drvdata(dai
);
152 dev_dbg(dai
->dev
, "%s()\n", __func__
);
154 WARN_ON(hcp
->current_stream
!= substream
);
156 hcp
->hcd
.ops
->audio_shutdown(dai
->dev
->parent
, hcp
->hcd
.data
);
158 mutex_lock(&hcp
->current_stream_lock
);
159 hcp
->current_stream
= NULL
;
160 mutex_unlock(&hcp
->current_stream_lock
);
163 static int hdmi_codec_hw_params(struct snd_pcm_substream
*substream
,
164 struct snd_pcm_hw_params
*params
,
165 struct snd_soc_dai
*dai
)
167 struct hdmi_codec_priv
*hcp
= snd_soc_dai_get_drvdata(dai
);
168 struct hdmi_codec_params hp
= {
173 .dig_subframe
= { 0 },
178 dev_dbg(dai
->dev
, "%s() width %d rate %d channels %d\n", __func__
,
179 params_width(params
), params_rate(params
),
180 params_channels(params
));
182 if (params_width(params
) > 24)
185 ret
= snd_pcm_create_iec958_consumer_hw_params(params
, hp
.iec
.status
,
186 sizeof(hp
.iec
.status
));
188 dev_err(dai
->dev
, "Creating IEC958 channel status failed %d\n",
193 ret
= hdmi_codec_new_stream(substream
, dai
);
197 hdmi_audio_infoframe_init(&hp
.cea
);
198 hp
.cea
.channels
= params_channels(params
);
199 hp
.cea
.coding_type
= HDMI_AUDIO_CODING_TYPE_STREAM
;
200 hp
.cea
.sample_size
= HDMI_AUDIO_SAMPLE_SIZE_STREAM
;
201 hp
.cea
.sample_frequency
= HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM
;
203 hp
.sample_width
= params_width(params
);
204 hp
.sample_rate
= params_rate(params
);
205 hp
.channels
= params_channels(params
);
207 return hcp
->hcd
.ops
->hw_params(dai
->dev
->parent
, hcp
->hcd
.data
,
208 &hcp
->daifmt
[dai
->id
], &hp
);
211 static int hdmi_codec_set_fmt(struct snd_soc_dai
*dai
,
214 struct hdmi_codec_priv
*hcp
= snd_soc_dai_get_drvdata(dai
);
215 struct hdmi_codec_daifmt cf
= { 0 };
218 dev_dbg(dai
->dev
, "%s()\n", __func__
);
220 if (dai
->id
== DAI_ID_SPDIF
) {
223 switch (fmt
& SND_SOC_DAIFMT_MASTER_MASK
) {
224 case SND_SOC_DAIFMT_CBM_CFM
:
225 cf
.bit_clk_master
= 1;
226 cf
.frame_clk_master
= 1;
228 case SND_SOC_DAIFMT_CBS_CFM
:
229 cf
.frame_clk_master
= 1;
231 case SND_SOC_DAIFMT_CBM_CFS
:
232 cf
.bit_clk_master
= 1;
234 case SND_SOC_DAIFMT_CBS_CFS
:
240 switch (fmt
& SND_SOC_DAIFMT_INV_MASK
) {
241 case SND_SOC_DAIFMT_NB_NF
:
243 case SND_SOC_DAIFMT_NB_IF
:
244 cf
.frame_clk_inv
= 1;
246 case SND_SOC_DAIFMT_IB_NF
:
249 case SND_SOC_DAIFMT_IB_IF
:
250 cf
.frame_clk_inv
= 1;
255 switch (fmt
& SND_SOC_DAIFMT_FORMAT_MASK
) {
256 case SND_SOC_DAIFMT_I2S
:
259 case SND_SOC_DAIFMT_DSP_A
:
262 case SND_SOC_DAIFMT_DSP_B
:
265 case SND_SOC_DAIFMT_RIGHT_J
:
266 cf
.fmt
= HDMI_RIGHT_J
;
268 case SND_SOC_DAIFMT_LEFT_J
:
269 cf
.fmt
= HDMI_LEFT_J
;
271 case SND_SOC_DAIFMT_AC97
:
275 dev_err(dai
->dev
, "Invalid DAI interface format\n");
280 hcp
->daifmt
[dai
->id
] = cf
;
285 static int hdmi_codec_digital_mute(struct snd_soc_dai
*dai
, int mute
)
287 struct hdmi_codec_priv
*hcp
= snd_soc_dai_get_drvdata(dai
);
289 dev_dbg(dai
->dev
, "%s()\n", __func__
);
291 if (hcp
->hcd
.ops
->digital_mute
)
292 return hcp
->hcd
.ops
->digital_mute(dai
->dev
->parent
,
293 hcp
->hcd
.data
, mute
);
298 static const struct snd_soc_dai_ops hdmi_dai_ops
= {
299 .startup
= hdmi_codec_startup
,
300 .shutdown
= hdmi_codec_shutdown
,
301 .hw_params
= hdmi_codec_hw_params
,
302 .set_fmt
= hdmi_codec_set_fmt
,
303 .digital_mute
= hdmi_codec_digital_mute
,
307 #define HDMI_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
308 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
309 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |\
310 SNDRV_PCM_RATE_192000)
312 #define SPDIF_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |\
313 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE |\
314 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE |\
315 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE)
318 * This list is only for formats allowed on the I2S bus. So there is
319 * some formats listed that are not supported by HDMI interface. For
320 * instance allowing the 32-bit formats enables 24-precision with CPU
321 * DAIs that do not support 24-bit formats. If the extra formats cause
322 * problems, we should add the video side driver an option to disable
325 #define I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S16_BE |\
326 SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_S20_3BE |\
327 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_3BE |\
328 SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S24_BE |\
329 SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_S32_BE)
331 static struct snd_soc_dai_driver hdmi_i2s_dai
= {
334 .stream_name
= "Playback",
338 .formats
= I2S_FORMATS
,
341 .ops
= &hdmi_dai_ops
,
344 static const struct snd_soc_dai_driver hdmi_spdif_dai
= {
347 .stream_name
= "Playback",
351 .formats
= SPDIF_FORMATS
,
353 .ops
= &hdmi_dai_ops
,
356 static char hdmi_dai_name
[][DAI_NAME_SIZE
] = {
363 static int hdmi_of_xlate_dai_name(struct snd_soc_component
*component
,
364 struct of_phandle_args
*args
,
365 const char **dai_name
)
369 if (args
->args_count
)
374 if (id
< ARRAY_SIZE(hdmi_dai_name
)) {
375 *dai_name
= hdmi_dai_name
[id
];
382 static struct snd_soc_codec_driver hdmi_codec
= {
383 .component_driver
= {
384 .controls
= hdmi_controls
,
385 .num_controls
= ARRAY_SIZE(hdmi_controls
),
386 .dapm_widgets
= hdmi_widgets
,
387 .num_dapm_widgets
= ARRAY_SIZE(hdmi_widgets
),
388 .dapm_routes
= hdmi_routes
,
389 .num_dapm_routes
= ARRAY_SIZE(hdmi_routes
),
390 .of_xlate_dai_name
= hdmi_of_xlate_dai_name
,
394 static int hdmi_codec_probe(struct platform_device
*pdev
)
396 struct hdmi_codec_pdata
*hcd
= pdev
->dev
.platform_data
;
397 struct device
*dev
= &pdev
->dev
;
398 struct hdmi_codec_priv
*hcp
;
399 struct hdmi_device
*hd
;
400 struct list_head
*pos
;
401 int dai_count
, i
= 0;
404 dev_dbg(dev
, "%s()\n", __func__
);
407 dev_err(dev
, "%s: No plalform data\n", __func__
);
411 dai_count
= hcd
->i2s
+ hcd
->spdif
;
412 if (dai_count
< 1 || !hcd
->ops
|| !hcd
->ops
->hw_params
||
413 !hcd
->ops
->audio_shutdown
) {
414 dev_err(dev
, "%s: Invalid parameters\n", __func__
);
418 hcp
= devm_kzalloc(dev
, sizeof(*hcp
), GFP_KERNEL
);
423 list_for_each(pos
, &hdmi_device_list
) {
424 struct hdmi_device
*tmp
= pos_to_hdmi_device(pos
);
426 if (tmp
->dev
== dev
->parent
) {
433 hd
= devm_kzalloc(dev
, sizeof(*hd
), GFP_KERNEL
);
437 hd
->dev
= dev
->parent
;
439 list_add_tail(&hd
->list
, &hdmi_device_list
);
442 if (hd
->cnt
>= ARRAY_SIZE(hdmi_dai_name
)) {
443 dev_err(dev
, "too many hdmi codec are deteced\n");
448 mutex_init(&hcp
->current_stream_lock
);
450 hcp
->daidrv
= devm_kzalloc(dev
, dai_count
* sizeof(*hcp
->daidrv
),
456 hcp
->daidrv
[i
] = hdmi_i2s_dai
;
457 hcp
->daidrv
[i
].playback
.channels_max
=
458 hcd
->max_i2s_channels
;
459 hcp
->daidrv
[i
].name
= hdmi_dai_name
[hd
->cnt
++];
464 hcp
->daidrv
[i
] = hdmi_spdif_dai
;
465 hcp
->daidrv
[i
].name
= hdmi_dai_name
[hd
->cnt
++];
468 ret
= snd_soc_register_codec(dev
, &hdmi_codec
, hcp
->daidrv
,
471 dev_err(dev
, "%s: snd_soc_register_codec() failed (%d)\n",
476 dev_set_drvdata(dev
, hcp
);
480 static int hdmi_codec_remove(struct platform_device
*pdev
)
482 snd_soc_unregister_codec(&pdev
->dev
);
486 static struct platform_driver hdmi_codec_driver
= {
488 .name
= HDMI_CODEC_DRV_NAME
,
490 .probe
= hdmi_codec_probe
,
491 .remove
= hdmi_codec_remove
,
494 module_platform_driver(hdmi_codec_driver
);
496 MODULE_AUTHOR("Jyri Sarha <jsarha@ti.com>");
497 MODULE_DESCRIPTION("HDMI Audio Codec Driver");
498 MODULE_LICENSE("GPL");
499 MODULE_ALIAS("platform:" HDMI_CODEC_DRV_NAME
);