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