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; 368 369 if (args->args_count) 370 id = args->args[0]; 371 else 372 id = 0; 373 374 if (id < ARRAY_SIZE(hdmi_dai_name)) { 375 *dai_name = hdmi_dai_name[id]; 376 return 0; 377 } 378 379 return -EAGAIN; 380 } 381 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, 391 }, 392 }; 393 394 static int hdmi_codec_probe(struct platform_device *pdev) 395 { 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; 402 int ret; 403 404 dev_dbg(dev, "%s()\n", __func__); 405 406 if (!hcd) { 407 dev_err(dev, "%s: No plalform data\n", __func__); 408 return -EINVAL; 409 } 410 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__); 415 return -EINVAL; 416 } 417 418 hcp = devm_kzalloc(dev, sizeof(*hcp), GFP_KERNEL); 419 if (!hcp) 420 return -ENOMEM; 421 422 hd = NULL; 423 list_for_each(pos, &hdmi_device_list) { 424 struct hdmi_device *tmp = pos_to_hdmi_device(pos); 425 426 if (tmp->dev == dev->parent) { 427 hd = tmp; 428 break; 429 } 430 } 431 432 if (!hd) { 433 hd = devm_kzalloc(dev, sizeof(*hd), GFP_KERNEL); 434 if (!hd) 435 return -ENOMEM; 436 437 hd->dev = dev->parent; 438 439 list_add_tail(&hd->list, &hdmi_device_list); 440 } 441 442 if (hd->cnt >= ARRAY_SIZE(hdmi_dai_name)) { 443 dev_err(dev, "too many hdmi codec are deteced\n"); 444 return -EINVAL; 445 } 446 447 hcp->hcd = *hcd; 448 mutex_init(&hcp->current_stream_lock); 449 450 hcp->daidrv = devm_kzalloc(dev, dai_count * sizeof(*hcp->daidrv), 451 GFP_KERNEL); 452 if (!hcp->daidrv) 453 return -ENOMEM; 454 455 if (hcd->i2s) { 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++]; 460 i++; 461 } 462 463 if (hcd->spdif) { 464 hcp->daidrv[i] = hdmi_spdif_dai; 465 hcp->daidrv[i].name = hdmi_dai_name[hd->cnt++]; 466 } 467 468 ret = snd_soc_register_codec(dev, &hdmi_codec, hcp->daidrv, 469 dai_count); 470 if (ret) { 471 dev_err(dev, "%s: snd_soc_register_codec() failed (%d)\n", 472 __func__, ret); 473 return ret; 474 } 475 476 dev_set_drvdata(dev, hcp); 477 return 0; 478 } 479 480 static int hdmi_codec_remove(struct platform_device *pdev) 481 { 482 snd_soc_unregister_codec(&pdev->dev); 483 return 0; 484 } 485 486 static struct platform_driver hdmi_codec_driver = { 487 .driver = { 488 .name = HDMI_CODEC_DRV_NAME, 489 }, 490 .probe = hdmi_codec_probe, 491 .remove = hdmi_codec_remove, 492 }; 493 494 module_platform_driver(hdmi_codec_driver); 495 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); 500