1 /* 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> 5 * 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. 9 * 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. 14 */ 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> 24 25 #include <drm/drm_crtc.h> /* This is only to get MAX_ELD_BYTES */ 26 27 struct hdmi_device { 28 struct device *dev; 29 struct list_head list; 30 int cnt; 31 }; 32 #define pos_to_hdmi_device(pos) container_of((pos), struct hdmi_device, list) 33 LIST_HEAD(hdmi_device_list); 34 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]; 44 }; 45 46 static const struct snd_soc_dapm_widget hdmi_widgets[] = { 47 SND_SOC_DAPM_OUTPUT("TX"), 48 }; 49 50 static const struct snd_soc_dapm_route hdmi_routes[] = { 51 { "TX", NULL, "Playback" }, 52 }; 53 54 enum { 55 DAI_ID_I2S = 0, 56 DAI_ID_SPDIF, 57 }; 58 59 static int hdmi_eld_ctl_info(struct snd_kcontrol *kcontrol, 60 struct snd_ctl_elem_info *uinfo) 61 { 62 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 63 struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component); 64 65 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; 66 uinfo->count = sizeof(hcp->eld); 67 68 return 0; 69 } 70 71 static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol, 72 struct snd_ctl_elem_value *ucontrol) 73 { 74 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol); 75 struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component); 76 77 memcpy(ucontrol->value.bytes.data, hcp->eld, sizeof(hcp->eld)); 78 79 return 0; 80 } 81 82 static const struct snd_kcontrol_new hdmi_controls[] = { 83 { 84 .access = SNDRV_CTL_ELEM_ACCESS_READ | 85 SNDRV_CTL_ELEM_ACCESS_VOLATILE, 86 .iface = SNDRV_CTL_ELEM_IFACE_PCM, 87 .name = "ELD", 88 .info = hdmi_eld_ctl_info, 89 .get = hdmi_eld_ctl_get, 90 }, 91 }; 92 93 static int hdmi_codec_new_stream(struct snd_pcm_substream *substream, 94 struct snd_soc_dai *dai) 95 { 96 struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai); 97 int ret = 0; 98 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"); 104 ret = -EINVAL; 105 } 106 mutex_unlock(&hcp->current_stream_lock); 107 108 return ret; 109 } 110 111 static int hdmi_codec_startup(struct snd_pcm_substream *substream, 112 struct snd_soc_dai *dai) 113 { 114 struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai); 115 int ret = 0; 116 117 dev_dbg(dai->dev, "%s()\n", __func__); 118 119 ret = hdmi_codec_new_stream(substream, dai); 120 if (ret) 121 return ret; 122 123 if (hcp->hcd.ops->audio_startup) { 124 ret = hcp->hcd.ops->audio_startup(dai->dev->parent, hcp->hcd.data); 125 if (ret) { 126 mutex_lock(&hcp->current_stream_lock); 127 hcp->current_stream = NULL; 128 mutex_unlock(&hcp->current_stream_lock); 129 return ret; 130 } 131 } 132 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)); 136 137 if (!ret) { 138 ret = snd_pcm_hw_constraint_eld(substream->runtime, 139 hcp->eld); 140 if (ret) 141 return ret; 142 } 143 } 144 return 0; 145 } 146 147 static void hdmi_codec_shutdown(struct snd_pcm_substream *substream, 148 struct snd_soc_dai *dai) 149 { 150 struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai); 151 152 dev_dbg(dai->dev, "%s()\n", __func__); 153 154 WARN_ON(hcp->current_stream != substream); 155 156 hcp->hcd.ops->audio_shutdown(dai->dev->parent, hcp->hcd.data); 157 158 mutex_lock(&hcp->current_stream_lock); 159 hcp->current_stream = NULL; 160 mutex_unlock(&hcp->current_stream_lock); 161 } 162 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) 166 { 167 struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai); 168 struct hdmi_codec_params hp = { 169 .iec = { 170 .status = { 0 }, 171 .subcode = { 0 }, 172 .pad = 0, 173 .dig_subframe = { 0 }, 174 } 175 }; 176 int ret; 177 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)); 181 182 if (params_width(params) > 24) 183 params->msbits = 24; 184 185 ret = snd_pcm_create_iec958_consumer_hw_params(params, hp.iec.status, 186 sizeof(hp.iec.status)); 187 if (ret < 0) { 188 dev_err(dai->dev, "Creating IEC958 channel status failed %d\n", 189 ret); 190 return ret; 191 } 192 193 ret = hdmi_codec_new_stream(substream, dai); 194 if (ret) 195 return ret; 196 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; 202 203 hp.sample_width = params_width(params); 204 hp.sample_rate = params_rate(params); 205 hp.channels = params_channels(params); 206 207 return hcp->hcd.ops->hw_params(dai->dev->parent, hcp->hcd.data, 208 &hcp->daifmt[dai->id], &hp); 209 } 210 211 static int hdmi_codec_set_fmt(struct snd_soc_dai *dai, 212 unsigned int fmt) 213 { 214 struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai); 215 struct hdmi_codec_daifmt cf = { 0 }; 216 int ret = 0; 217 218 dev_dbg(dai->dev, "%s()\n", __func__); 219 220 if (dai->id == DAI_ID_SPDIF) { 221 cf.fmt = HDMI_SPDIF; 222 } else { 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; 227 break; 228 case SND_SOC_DAIFMT_CBS_CFM: 229 cf.frame_clk_master = 1; 230 break; 231 case SND_SOC_DAIFMT_CBM_CFS: 232 cf.bit_clk_master = 1; 233 break; 234 case SND_SOC_DAIFMT_CBS_CFS: 235 break; 236 default: 237 return -EINVAL; 238 } 239 240 switch (fmt & SND_SOC_DAIFMT_INV_MASK) { 241 case SND_SOC_DAIFMT_NB_NF: 242 break; 243 case SND_SOC_DAIFMT_NB_IF: 244 cf.frame_clk_inv = 1; 245 break; 246 case SND_SOC_DAIFMT_IB_NF: 247 cf.bit_clk_inv = 1; 248 break; 249 case SND_SOC_DAIFMT_IB_IF: 250 cf.frame_clk_inv = 1; 251 cf.bit_clk_inv = 1; 252 break; 253 } 254 255 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { 256 case SND_SOC_DAIFMT_I2S: 257 cf.fmt = HDMI_I2S; 258 break; 259 case SND_SOC_DAIFMT_DSP_A: 260 cf.fmt = HDMI_DSP_A; 261 break; 262 case SND_SOC_DAIFMT_DSP_B: 263 cf.fmt = HDMI_DSP_B; 264 break; 265 case SND_SOC_DAIFMT_RIGHT_J: 266 cf.fmt = HDMI_RIGHT_J; 267 break; 268 case SND_SOC_DAIFMT_LEFT_J: 269 cf.fmt = HDMI_LEFT_J; 270 break; 271 case SND_SOC_DAIFMT_AC97: 272 cf.fmt = HDMI_AC97; 273 break; 274 default: 275 dev_err(dai->dev, "Invalid DAI interface format\n"); 276 return -EINVAL; 277 } 278 } 279 280 hcp->daifmt[dai->id] = cf; 281 282 return ret; 283 } 284 285 static int hdmi_codec_digital_mute(struct snd_soc_dai *dai, int mute) 286 { 287 struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai); 288 289 dev_dbg(dai->dev, "%s()\n", __func__); 290 291 if (hcp->hcd.ops->digital_mute) 292 return hcp->hcd.ops->digital_mute(dai->dev->parent, 293 hcp->hcd.data, mute); 294 295 return 0; 296 } 297 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, 304 }; 305 306 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) 311 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) 316 317 /* 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 323 * them. 324 */ 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) 330 331 static struct snd_soc_dai_driver hdmi_i2s_dai = { 332 .id = DAI_ID_I2S, 333 .playback = { 334 .stream_name = "Playback", 335 .channels_min = 2, 336 .channels_max = 8, 337 .rates = HDMI_RATES, 338 .formats = I2S_FORMATS, 339 .sig_bits = 24, 340 }, 341 .ops = &hdmi_dai_ops, 342 }; 343 344 static const struct snd_soc_dai_driver hdmi_spdif_dai = { 345 .id = DAI_ID_SPDIF, 346 .playback = { 347 .stream_name = "Playback", 348 .channels_min = 2, 349 .channels_max = 2, 350 .rates = HDMI_RATES, 351 .formats = SPDIF_FORMATS, 352 }, 353 .ops = &hdmi_dai_ops, 354 }; 355 356 static char hdmi_dai_name[][DAI_NAME_SIZE] = { 357 "hdmi-hifi.0", 358 "hdmi-hifi.1", 359 "hdmi-hifi.2", 360 "hdmi-hifi.3", 361 }; 362 363 static int hdmi_of_xlate_dai_name(struct snd_soc_component *component, 364 struct of_phandle_args *args, 365 const char **dai_name) 366 { 367 int id = args->args[0]; 368 369 if (id < ARRAY_SIZE(hdmi_dai_name)) { 370 *dai_name = hdmi_dai_name[id]; 371 return 0; 372 } 373 374 return -EAGAIN; 375 } 376 377 static struct snd_soc_codec_driver hdmi_codec = { 378 .component_driver = { 379 .controls = hdmi_controls, 380 .num_controls = ARRAY_SIZE(hdmi_controls), 381 .dapm_widgets = hdmi_widgets, 382 .num_dapm_widgets = ARRAY_SIZE(hdmi_widgets), 383 .dapm_routes = hdmi_routes, 384 .num_dapm_routes = ARRAY_SIZE(hdmi_routes), 385 .of_xlate_dai_name = hdmi_of_xlate_dai_name, 386 }, 387 }; 388 389 static int hdmi_codec_probe(struct platform_device *pdev) 390 { 391 struct hdmi_codec_pdata *hcd = pdev->dev.platform_data; 392 struct device *dev = &pdev->dev; 393 struct hdmi_codec_priv *hcp; 394 struct hdmi_device *hd; 395 struct list_head *pos; 396 int dai_count, i = 0; 397 int ret; 398 399 dev_dbg(dev, "%s()\n", __func__); 400 401 if (!hcd) { 402 dev_err(dev, "%s: No plalform data\n", __func__); 403 return -EINVAL; 404 } 405 406 dai_count = hcd->i2s + hcd->spdif; 407 if (dai_count < 1 || !hcd->ops || !hcd->ops->hw_params || 408 !hcd->ops->audio_shutdown) { 409 dev_err(dev, "%s: Invalid parameters\n", __func__); 410 return -EINVAL; 411 } 412 413 hcp = devm_kzalloc(dev, sizeof(*hcp), GFP_KERNEL); 414 if (!hcp) 415 return -ENOMEM; 416 417 hd = NULL; 418 list_for_each(pos, &hdmi_device_list) { 419 struct hdmi_device *tmp = pos_to_hdmi_device(pos); 420 421 if (tmp->dev == dev->parent) { 422 hd = tmp; 423 break; 424 } 425 } 426 427 if (!hd) { 428 hd = devm_kzalloc(dev, sizeof(*hd), GFP_KERNEL); 429 if (!hd) 430 return -ENOMEM; 431 432 hd->dev = dev->parent; 433 434 list_add_tail(&hd->list, &hdmi_device_list); 435 } 436 437 if (hd->cnt >= ARRAY_SIZE(hdmi_dai_name)) { 438 dev_err(dev, "too many hdmi codec are deteced\n"); 439 return -EINVAL; 440 } 441 442 hcp->hcd = *hcd; 443 mutex_init(&hcp->current_stream_lock); 444 445 hcp->daidrv = devm_kzalloc(dev, dai_count * sizeof(*hcp->daidrv), 446 GFP_KERNEL); 447 if (!hcp->daidrv) 448 return -ENOMEM; 449 450 if (hcd->i2s) { 451 hcp->daidrv[i] = hdmi_i2s_dai; 452 hcp->daidrv[i].playback.channels_max = 453 hcd->max_i2s_channels; 454 hcp->daidrv[i].name = hdmi_dai_name[hd->cnt++]; 455 i++; 456 } 457 458 if (hcd->spdif) { 459 hcp->daidrv[i] = hdmi_spdif_dai; 460 hcp->daidrv[i].name = hdmi_dai_name[hd->cnt++]; 461 } 462 463 ret = snd_soc_register_codec(dev, &hdmi_codec, hcp->daidrv, 464 dai_count); 465 if (ret) { 466 dev_err(dev, "%s: snd_soc_register_codec() failed (%d)\n", 467 __func__, ret); 468 return ret; 469 } 470 471 dev_set_drvdata(dev, hcp); 472 return 0; 473 } 474 475 static int hdmi_codec_remove(struct platform_device *pdev) 476 { 477 snd_soc_unregister_codec(&pdev->dev); 478 return 0; 479 } 480 481 static struct platform_driver hdmi_codec_driver = { 482 .driver = { 483 .name = HDMI_CODEC_DRV_NAME, 484 }, 485 .probe = hdmi_codec_probe, 486 .remove = hdmi_codec_remove, 487 }; 488 489 module_platform_driver(hdmi_codec_driver); 490 491 MODULE_AUTHOR("Jyri Sarha <jsarha@ti.com>"); 492 MODULE_DESCRIPTION("HDMI Audio Codec Driver"); 493 MODULE_LICENSE("GPL"); 494 MODULE_ALIAS("platform:" HDMI_CODEC_DRV_NAME); 495