0001
0002
0003
0004
0005
0006
0007 #include <linux/module.h>
0008 #include <linux/string.h>
0009 #include <sound/core.h>
0010 #include <sound/jack.h>
0011 #include <sound/pcm.h>
0012 #include <sound/pcm_params.h>
0013 #include <sound/soc.h>
0014 #include <sound/tlv.h>
0015 #include <sound/pcm_drm_eld.h>
0016 #include <sound/hdmi-codec.h>
0017 #include <sound/pcm_iec958.h>
0018
0019 #include <drm/drm_crtc.h> /* This is only to get MAX_ELD_BYTES */
0020
0021 #define HDMI_CODEC_CHMAP_IDX_UNKNOWN -1
0022
0023 struct hdmi_codec_channel_map_table {
0024 unsigned char map;
0025 };
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 enum hdmi_codec_cea_spk_placement {
0039 FL = BIT(0),
0040 FC = BIT(1),
0041 FR = BIT(2),
0042 FLC = BIT(3),
0043 FRC = BIT(4),
0044 RL = BIT(5),
0045 RC = BIT(6),
0046 RR = BIT(7),
0047 RLC = BIT(8),
0048 RRC = BIT(9),
0049 LFE = BIT(10),
0050 };
0051
0052
0053
0054
0055 struct hdmi_codec_cea_spk_alloc {
0056 const int ca_id;
0057 unsigned int n_ch;
0058 unsigned long mask;
0059 };
0060
0061
0062 static const struct snd_pcm_chmap_elem hdmi_codec_stereo_chmaps[] = {
0063 { .channels = 2,
0064 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
0065 { }
0066 };
0067
0068
0069 static const struct snd_pcm_chmap_elem hdmi_codec_8ch_chmaps[] = {
0070 { .channels = 2,
0071 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
0072 { .channels = 4,
0073 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
0074 SNDRV_CHMAP_NA } },
0075 { .channels = 4,
0076 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
0077 SNDRV_CHMAP_FC } },
0078 { .channels = 4,
0079 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
0080 SNDRV_CHMAP_FC } },
0081 { .channels = 6,
0082 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
0083 SNDRV_CHMAP_NA, SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
0084 { .channels = 6,
0085 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
0086 SNDRV_CHMAP_NA, SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
0087 { .channels = 6,
0088 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
0089 SNDRV_CHMAP_FC, SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
0090 { .channels = 6,
0091 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
0092 SNDRV_CHMAP_FC, SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
0093 { .channels = 6,
0094 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
0095 SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
0096 { .channels = 6,
0097 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
0098 SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
0099 { .channels = 6,
0100 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
0101 SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
0102 { .channels = 6,
0103 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
0104 SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
0105 { .channels = 8,
0106 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
0107 SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
0108 SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
0109 { .channels = 8,
0110 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
0111 SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
0112 SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
0113 { .channels = 8,
0114 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
0115 SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
0116 SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
0117 { .channels = 8,
0118 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
0119 SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
0120 SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
0121 { .channels = 8,
0122 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
0123 SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
0124 SNDRV_CHMAP_RLC, SNDRV_CHMAP_RRC } },
0125 { .channels = 8,
0126 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
0127 SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
0128 SNDRV_CHMAP_RLC, SNDRV_CHMAP_RRC } },
0129 { .channels = 8,
0130 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
0131 SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
0132 SNDRV_CHMAP_RLC, SNDRV_CHMAP_RRC } },
0133 { .channels = 8,
0134 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
0135 SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
0136 SNDRV_CHMAP_RLC, SNDRV_CHMAP_RRC } },
0137 { .channels = 8,
0138 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
0139 SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
0140 SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
0141 { .channels = 8,
0142 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
0143 SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
0144 SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
0145 { .channels = 8,
0146 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
0147 SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
0148 SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
0149 { .channels = 8,
0150 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
0151 SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
0152 SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
0153 { .channels = 8,
0154 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
0155 SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
0156 SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
0157 { .channels = 8,
0158 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
0159 SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
0160 SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
0161 { .channels = 8,
0162 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
0163 SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
0164 SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
0165 { .channels = 8,
0166 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
0167 SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
0168 SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
0169 { .channels = 8,
0170 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
0171 SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
0172 SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
0173 { .channels = 8,
0174 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
0175 SNDRV_CHMAP_NA, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
0176 SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
0177 { .channels = 8,
0178 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
0179 SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
0180 SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
0181 { .channels = 8,
0182 .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
0183 SNDRV_CHMAP_FC, SNDRV_CHMAP_NA, SNDRV_CHMAP_NA,
0184 SNDRV_CHMAP_FLC, SNDRV_CHMAP_FRC } },
0185 { }
0186 };
0187
0188
0189
0190
0191
0192
0193
0194
0195 static const struct hdmi_codec_cea_spk_alloc hdmi_codec_channel_alloc[] = {
0196 { .ca_id = 0x00, .n_ch = 2,
0197 .mask = FL | FR},
0198
0199 { .ca_id = 0x01, .n_ch = 4,
0200 .mask = FL | FR | LFE},
0201
0202 { .ca_id = 0x02, .n_ch = 4,
0203 .mask = FL | FR | FC },
0204
0205 { .ca_id = 0x0b, .n_ch = 6,
0206 .mask = FL | FR | LFE | FC | RL | RR},
0207
0208 { .ca_id = 0x08, .n_ch = 6,
0209 .mask = FL | FR | RL | RR },
0210
0211 { .ca_id = 0x09, .n_ch = 6,
0212 .mask = FL | FR | LFE | RL | RR },
0213
0214 { .ca_id = 0x0a, .n_ch = 6,
0215 .mask = FL | FR | FC | RL | RR },
0216
0217 { .ca_id = 0x0f, .n_ch = 8,
0218 .mask = FL | FR | LFE | FC | RL | RR | RC },
0219
0220 { .ca_id = 0x13, .n_ch = 8,
0221 .mask = FL | FR | LFE | FC | RL | RR | RLC | RRC },
0222
0223 { .ca_id = 0x03, .n_ch = 8,
0224 .mask = FL | FR | LFE | FC },
0225 { .ca_id = 0x04, .n_ch = 8,
0226 .mask = FL | FR | RC},
0227 { .ca_id = 0x05, .n_ch = 8,
0228 .mask = FL | FR | LFE | RC },
0229 { .ca_id = 0x06, .n_ch = 8,
0230 .mask = FL | FR | FC | RC },
0231 { .ca_id = 0x07, .n_ch = 8,
0232 .mask = FL | FR | LFE | FC | RC },
0233 { .ca_id = 0x0c, .n_ch = 8,
0234 .mask = FL | FR | RC | RL | RR },
0235 { .ca_id = 0x0d, .n_ch = 8,
0236 .mask = FL | FR | LFE | RL | RR | RC },
0237 { .ca_id = 0x0e, .n_ch = 8,
0238 .mask = FL | FR | FC | RL | RR | RC },
0239 { .ca_id = 0x10, .n_ch = 8,
0240 .mask = FL | FR | RL | RR | RLC | RRC },
0241 { .ca_id = 0x11, .n_ch = 8,
0242 .mask = FL | FR | LFE | RL | RR | RLC | RRC },
0243 { .ca_id = 0x12, .n_ch = 8,
0244 .mask = FL | FR | FC | RL | RR | RLC | RRC },
0245 { .ca_id = 0x14, .n_ch = 8,
0246 .mask = FL | FR | FLC | FRC },
0247 { .ca_id = 0x15, .n_ch = 8,
0248 .mask = FL | FR | LFE | FLC | FRC },
0249 { .ca_id = 0x16, .n_ch = 8,
0250 .mask = FL | FR | FC | FLC | FRC },
0251 { .ca_id = 0x17, .n_ch = 8,
0252 .mask = FL | FR | LFE | FC | FLC | FRC },
0253 { .ca_id = 0x18, .n_ch = 8,
0254 .mask = FL | FR | RC | FLC | FRC },
0255 { .ca_id = 0x19, .n_ch = 8,
0256 .mask = FL | FR | LFE | RC | FLC | FRC },
0257 { .ca_id = 0x1a, .n_ch = 8,
0258 .mask = FL | FR | RC | FC | FLC | FRC },
0259 { .ca_id = 0x1b, .n_ch = 8,
0260 .mask = FL | FR | LFE | RC | FC | FLC | FRC },
0261 { .ca_id = 0x1c, .n_ch = 8,
0262 .mask = FL | FR | RL | RR | FLC | FRC },
0263 { .ca_id = 0x1d, .n_ch = 8,
0264 .mask = FL | FR | LFE | RL | RR | FLC | FRC },
0265 { .ca_id = 0x1e, .n_ch = 8,
0266 .mask = FL | FR | FC | RL | RR | FLC | FRC },
0267 { .ca_id = 0x1f, .n_ch = 8,
0268 .mask = FL | FR | LFE | FC | RL | RR | FLC | FRC },
0269 };
0270
0271 struct hdmi_codec_priv {
0272 struct hdmi_codec_pdata hcd;
0273 uint8_t eld[MAX_ELD_BYTES];
0274 struct snd_pcm_chmap *chmap_info;
0275 unsigned int chmap_idx;
0276 struct mutex lock;
0277 bool busy;
0278 struct snd_soc_jack *jack;
0279 unsigned int jack_status;
0280 u8 iec_status[AES_IEC958_STATUS_SIZE];
0281 };
0282
0283 static const struct snd_soc_dapm_widget hdmi_widgets[] = {
0284 SND_SOC_DAPM_OUTPUT("TX"),
0285 SND_SOC_DAPM_OUTPUT("RX"),
0286 };
0287
0288 enum {
0289 DAI_ID_I2S = 0,
0290 DAI_ID_SPDIF,
0291 };
0292
0293 static int hdmi_eld_ctl_info(struct snd_kcontrol *kcontrol,
0294 struct snd_ctl_elem_info *uinfo)
0295 {
0296 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
0297 uinfo->count = sizeof_field(struct hdmi_codec_priv, eld);
0298
0299 return 0;
0300 }
0301
0302 static int hdmi_eld_ctl_get(struct snd_kcontrol *kcontrol,
0303 struct snd_ctl_elem_value *ucontrol)
0304 {
0305 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
0306 struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component);
0307
0308 memcpy(ucontrol->value.bytes.data, hcp->eld, sizeof(hcp->eld));
0309
0310 return 0;
0311 }
0312
0313 static unsigned long hdmi_codec_spk_mask_from_alloc(int spk_alloc)
0314 {
0315 int i;
0316 static const unsigned long hdmi_codec_eld_spk_alloc_bits[] = {
0317 [0] = FL | FR, [1] = LFE, [2] = FC, [3] = RL | RR,
0318 [4] = RC, [5] = FLC | FRC, [6] = RLC | RRC,
0319 };
0320 unsigned long spk_mask = 0;
0321
0322 for (i = 0; i < ARRAY_SIZE(hdmi_codec_eld_spk_alloc_bits); i++) {
0323 if (spk_alloc & (1 << i))
0324 spk_mask |= hdmi_codec_eld_spk_alloc_bits[i];
0325 }
0326
0327 return spk_mask;
0328 }
0329
0330 static void hdmi_codec_eld_chmap(struct hdmi_codec_priv *hcp)
0331 {
0332 u8 spk_alloc;
0333 unsigned long spk_mask;
0334
0335 spk_alloc = drm_eld_get_spk_alloc(hcp->eld);
0336 spk_mask = hdmi_codec_spk_mask_from_alloc(spk_alloc);
0337
0338
0339 if ((spk_mask & ~(FL | FR)) && hcp->chmap_info->max_channels > 2)
0340 hcp->chmap_info->chmap = hdmi_codec_8ch_chmaps;
0341 else
0342 hcp->chmap_info->chmap = hdmi_codec_stereo_chmaps;
0343 }
0344
0345 static int hdmi_codec_get_ch_alloc_table_idx(struct hdmi_codec_priv *hcp,
0346 unsigned char channels)
0347 {
0348 int i;
0349 u8 spk_alloc;
0350 unsigned long spk_mask;
0351 const struct hdmi_codec_cea_spk_alloc *cap = hdmi_codec_channel_alloc;
0352
0353 spk_alloc = drm_eld_get_spk_alloc(hcp->eld);
0354 spk_mask = hdmi_codec_spk_mask_from_alloc(spk_alloc);
0355
0356 for (i = 0; i < ARRAY_SIZE(hdmi_codec_channel_alloc); i++, cap++) {
0357
0358 if (!spk_alloc && cap->ca_id == 0)
0359 return i;
0360 if (cap->n_ch != channels)
0361 continue;
0362 if (!(cap->mask == (spk_mask & cap->mask)))
0363 continue;
0364 return i;
0365 }
0366
0367 return -EINVAL;
0368 }
0369 static int hdmi_codec_chmap_ctl_get(struct snd_kcontrol *kcontrol,
0370 struct snd_ctl_elem_value *ucontrol)
0371 {
0372 unsigned const char *map;
0373 unsigned int i;
0374 struct snd_pcm_chmap *info = snd_kcontrol_chip(kcontrol);
0375 struct hdmi_codec_priv *hcp = info->private_data;
0376
0377 map = info->chmap[hcp->chmap_idx].map;
0378
0379 for (i = 0; i < info->max_channels; i++) {
0380 if (hcp->chmap_idx == HDMI_CODEC_CHMAP_IDX_UNKNOWN)
0381 ucontrol->value.integer.value[i] = 0;
0382 else
0383 ucontrol->value.integer.value[i] = map[i];
0384 }
0385
0386 return 0;
0387 }
0388
0389 static int hdmi_codec_iec958_info(struct snd_kcontrol *kcontrol,
0390 struct snd_ctl_elem_info *uinfo)
0391 {
0392 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
0393 uinfo->count = 1;
0394 return 0;
0395 }
0396
0397 static int hdmi_codec_iec958_default_get(struct snd_kcontrol *kcontrol,
0398 struct snd_ctl_elem_value *ucontrol)
0399 {
0400 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
0401 struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component);
0402
0403 memcpy(ucontrol->value.iec958.status, hcp->iec_status,
0404 sizeof(hcp->iec_status));
0405
0406 return 0;
0407 }
0408
0409 static int hdmi_codec_iec958_default_put(struct snd_kcontrol *kcontrol,
0410 struct snd_ctl_elem_value *ucontrol)
0411 {
0412 struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
0413 struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component);
0414
0415 memcpy(hcp->iec_status, ucontrol->value.iec958.status,
0416 sizeof(hcp->iec_status));
0417
0418 return 0;
0419 }
0420
0421 static int hdmi_codec_iec958_mask_get(struct snd_kcontrol *kcontrol,
0422 struct snd_ctl_elem_value *ucontrol)
0423 {
0424 memset(ucontrol->value.iec958.status, 0xff,
0425 sizeof_field(struct hdmi_codec_priv, iec_status));
0426
0427 return 0;
0428 }
0429
0430 static int hdmi_codec_startup(struct snd_pcm_substream *substream,
0431 struct snd_soc_dai *dai)
0432 {
0433 struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
0434 bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
0435 int ret = 0;
0436
0437 mutex_lock(&hcp->lock);
0438 if (hcp->busy) {
0439 dev_err(dai->dev, "Only one simultaneous stream supported!\n");
0440 mutex_unlock(&hcp->lock);
0441 return -EINVAL;
0442 }
0443
0444 if (hcp->hcd.ops->audio_startup) {
0445 ret = hcp->hcd.ops->audio_startup(dai->dev->parent, hcp->hcd.data);
0446 if (ret)
0447 goto err;
0448 }
0449
0450 if (tx && hcp->hcd.ops->get_eld) {
0451 ret = hcp->hcd.ops->get_eld(dai->dev->parent, hcp->hcd.data,
0452 hcp->eld, sizeof(hcp->eld));
0453 if (ret)
0454 goto err;
0455
0456 ret = snd_pcm_hw_constraint_eld(substream->runtime, hcp->eld);
0457 if (ret)
0458 goto err;
0459
0460
0461 hdmi_codec_eld_chmap(hcp);
0462 }
0463
0464 hcp->busy = true;
0465
0466 err:
0467 mutex_unlock(&hcp->lock);
0468 return ret;
0469 }
0470
0471 static void hdmi_codec_shutdown(struct snd_pcm_substream *substream,
0472 struct snd_soc_dai *dai)
0473 {
0474 struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
0475
0476 hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN;
0477 hcp->hcd.ops->audio_shutdown(dai->dev->parent, hcp->hcd.data);
0478
0479 mutex_lock(&hcp->lock);
0480 hcp->busy = false;
0481 mutex_unlock(&hcp->lock);
0482 }
0483
0484 static int hdmi_codec_fill_codec_params(struct snd_soc_dai *dai,
0485 unsigned int sample_width,
0486 unsigned int sample_rate,
0487 unsigned int channels,
0488 struct hdmi_codec_params *hp)
0489 {
0490 struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
0491 int idx;
0492
0493
0494 idx = hdmi_codec_get_ch_alloc_table_idx(hcp, channels);
0495 if (idx < 0) {
0496 dev_err(dai->dev, "Not able to map channels to speakers (%d)\n",
0497 idx);
0498 hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN;
0499 return idx;
0500 }
0501
0502 memset(hp, 0, sizeof(*hp));
0503
0504 hdmi_audio_infoframe_init(&hp->cea);
0505 hp->cea.channels = channels;
0506 hp->cea.coding_type = HDMI_AUDIO_CODING_TYPE_STREAM;
0507 hp->cea.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM;
0508 hp->cea.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM;
0509 hp->cea.channel_allocation = hdmi_codec_channel_alloc[idx].ca_id;
0510
0511 hp->sample_width = sample_width;
0512 hp->sample_rate = sample_rate;
0513 hp->channels = channels;
0514
0515 hcp->chmap_idx = hdmi_codec_channel_alloc[idx].ca_id;
0516
0517 return 0;
0518 }
0519
0520 static int hdmi_codec_hw_params(struct snd_pcm_substream *substream,
0521 struct snd_pcm_hw_params *params,
0522 struct snd_soc_dai *dai)
0523 {
0524 struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
0525 struct hdmi_codec_daifmt *cf = dai->playback_dma_data;
0526 struct hdmi_codec_params hp = {
0527 .iec = {
0528 .status = { 0 },
0529 .subcode = { 0 },
0530 .pad = 0,
0531 .dig_subframe = { 0 },
0532 }
0533 };
0534 int ret;
0535
0536 if (!hcp->hcd.ops->hw_params)
0537 return 0;
0538
0539 dev_dbg(dai->dev, "%s() width %d rate %d channels %d\n", __func__,
0540 params_width(params), params_rate(params),
0541 params_channels(params));
0542
0543 ret = hdmi_codec_fill_codec_params(dai,
0544 params_width(params),
0545 params_rate(params),
0546 params_channels(params),
0547 &hp);
0548 if (ret < 0)
0549 return ret;
0550
0551 memcpy(hp.iec.status, hcp->iec_status, sizeof(hp.iec.status));
0552 ret = snd_pcm_fill_iec958_consumer_hw_params(params, hp.iec.status,
0553 sizeof(hp.iec.status));
0554 if (ret < 0) {
0555 dev_err(dai->dev, "Creating IEC958 channel status failed %d\n",
0556 ret);
0557 return ret;
0558 }
0559
0560 cf->bit_fmt = params_format(params);
0561 return hcp->hcd.ops->hw_params(dai->dev->parent, hcp->hcd.data,
0562 cf, &hp);
0563 }
0564
0565 static int hdmi_codec_prepare(struct snd_pcm_substream *substream,
0566 struct snd_soc_dai *dai)
0567 {
0568 struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
0569 struct hdmi_codec_daifmt *cf = dai->playback_dma_data;
0570 struct snd_pcm_runtime *runtime = substream->runtime;
0571 unsigned int channels = runtime->channels;
0572 unsigned int width = snd_pcm_format_width(runtime->format);
0573 unsigned int rate = runtime->rate;
0574 struct hdmi_codec_params hp;
0575 int ret;
0576
0577 if (!hcp->hcd.ops->prepare)
0578 return 0;
0579
0580 dev_dbg(dai->dev, "%s() width %d rate %d channels %d\n", __func__,
0581 width, rate, channels);
0582
0583 ret = hdmi_codec_fill_codec_params(dai, width, rate, channels, &hp);
0584 if (ret < 0)
0585 return ret;
0586
0587 memcpy(hp.iec.status, hcp->iec_status, sizeof(hp.iec.status));
0588 ret = snd_pcm_fill_iec958_consumer(runtime, hp.iec.status,
0589 sizeof(hp.iec.status));
0590 if (ret < 0) {
0591 dev_err(dai->dev, "Creating IEC958 channel status failed %d\n",
0592 ret);
0593 return ret;
0594 }
0595
0596 cf->bit_fmt = runtime->format;
0597 return hcp->hcd.ops->prepare(dai->dev->parent, hcp->hcd.data,
0598 cf, &hp);
0599 }
0600
0601 static int hdmi_codec_i2s_set_fmt(struct snd_soc_dai *dai,
0602 unsigned int fmt)
0603 {
0604 struct hdmi_codec_daifmt *cf = dai->playback_dma_data;
0605
0606
0607 memset(cf, 0, sizeof(*cf));
0608
0609 switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
0610 case SND_SOC_DAIFMT_CBP_CFP:
0611 cf->bit_clk_provider = 1;
0612 cf->frame_clk_provider = 1;
0613 break;
0614 case SND_SOC_DAIFMT_CBC_CFP:
0615 cf->frame_clk_provider = 1;
0616 break;
0617 case SND_SOC_DAIFMT_CBP_CFC:
0618 cf->bit_clk_provider = 1;
0619 break;
0620 case SND_SOC_DAIFMT_CBC_CFC:
0621 break;
0622 default:
0623 return -EINVAL;
0624 }
0625
0626 switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
0627 case SND_SOC_DAIFMT_NB_NF:
0628 break;
0629 case SND_SOC_DAIFMT_NB_IF:
0630 cf->frame_clk_inv = 1;
0631 break;
0632 case SND_SOC_DAIFMT_IB_NF:
0633 cf->bit_clk_inv = 1;
0634 break;
0635 case SND_SOC_DAIFMT_IB_IF:
0636 cf->frame_clk_inv = 1;
0637 cf->bit_clk_inv = 1;
0638 break;
0639 }
0640
0641 switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
0642 case SND_SOC_DAIFMT_I2S:
0643 cf->fmt = HDMI_I2S;
0644 break;
0645 case SND_SOC_DAIFMT_DSP_A:
0646 cf->fmt = HDMI_DSP_A;
0647 break;
0648 case SND_SOC_DAIFMT_DSP_B:
0649 cf->fmt = HDMI_DSP_B;
0650 break;
0651 case SND_SOC_DAIFMT_RIGHT_J:
0652 cf->fmt = HDMI_RIGHT_J;
0653 break;
0654 case SND_SOC_DAIFMT_LEFT_J:
0655 cf->fmt = HDMI_LEFT_J;
0656 break;
0657 case SND_SOC_DAIFMT_AC97:
0658 cf->fmt = HDMI_AC97;
0659 break;
0660 default:
0661 dev_err(dai->dev, "Invalid DAI interface format\n");
0662 return -EINVAL;
0663 }
0664
0665 return 0;
0666 }
0667
0668 static int hdmi_codec_mute(struct snd_soc_dai *dai, int mute, int direction)
0669 {
0670 struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
0671
0672
0673
0674
0675
0676
0677
0678 if (hcp->hcd.ops->mute_stream &&
0679 (direction == SNDRV_PCM_STREAM_PLAYBACK ||
0680 !hcp->hcd.ops->no_capture_mute))
0681 return hcp->hcd.ops->mute_stream(dai->dev->parent,
0682 hcp->hcd.data,
0683 mute, direction);
0684
0685 return -ENOTSUPP;
0686 }
0687
0688
0689
0690
0691
0692
0693
0694
0695 static u64 hdmi_codec_formats =
0696 SND_SOC_POSSIBLE_DAIFMT_NB_NF |
0697 SND_SOC_POSSIBLE_DAIFMT_NB_IF |
0698 SND_SOC_POSSIBLE_DAIFMT_IB_NF |
0699 SND_SOC_POSSIBLE_DAIFMT_IB_IF |
0700 SND_SOC_POSSIBLE_DAIFMT_I2S |
0701 SND_SOC_POSSIBLE_DAIFMT_DSP_A |
0702 SND_SOC_POSSIBLE_DAIFMT_DSP_B |
0703 SND_SOC_POSSIBLE_DAIFMT_RIGHT_J |
0704 SND_SOC_POSSIBLE_DAIFMT_LEFT_J |
0705 SND_SOC_POSSIBLE_DAIFMT_AC97;
0706
0707 static const struct snd_soc_dai_ops hdmi_codec_i2s_dai_ops = {
0708 .startup = hdmi_codec_startup,
0709 .shutdown = hdmi_codec_shutdown,
0710 .hw_params = hdmi_codec_hw_params,
0711 .prepare = hdmi_codec_prepare,
0712 .set_fmt = hdmi_codec_i2s_set_fmt,
0713 .mute_stream = hdmi_codec_mute,
0714 .auto_selectable_formats = &hdmi_codec_formats,
0715 .num_auto_selectable_formats = 1,
0716 };
0717
0718 static const struct snd_soc_dai_ops hdmi_codec_spdif_dai_ops = {
0719 .startup = hdmi_codec_startup,
0720 .shutdown = hdmi_codec_shutdown,
0721 .hw_params = hdmi_codec_hw_params,
0722 .mute_stream = hdmi_codec_mute,
0723 };
0724
0725 #define HDMI_RATES (SNDRV_PCM_RATE_32000 | SNDRV_PCM_RATE_44100 |\
0726 SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_88200 |\
0727 SNDRV_PCM_RATE_96000 | SNDRV_PCM_RATE_176400 |\
0728 SNDRV_PCM_RATE_192000)
0729
0730 #define SPDIF_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
0731 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_LE)
0732
0733
0734
0735
0736
0737
0738
0739
0740
0741 #define I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S20_3LE |\
0742 SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_S24_LE |\
0743 SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE)
0744
0745 static struct snd_kcontrol_new hdmi_codec_controls[] = {
0746 {
0747 .access = SNDRV_CTL_ELEM_ACCESS_READ,
0748 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
0749 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, MASK),
0750 .info = hdmi_codec_iec958_info,
0751 .get = hdmi_codec_iec958_mask_get,
0752 },
0753 {
0754 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
0755 .name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
0756 .info = hdmi_codec_iec958_info,
0757 .get = hdmi_codec_iec958_default_get,
0758 .put = hdmi_codec_iec958_default_put,
0759 },
0760 {
0761 .access = (SNDRV_CTL_ELEM_ACCESS_READ |
0762 SNDRV_CTL_ELEM_ACCESS_VOLATILE),
0763 .iface = SNDRV_CTL_ELEM_IFACE_PCM,
0764 .name = "ELD",
0765 .info = hdmi_eld_ctl_info,
0766 .get = hdmi_eld_ctl_get,
0767 },
0768 };
0769
0770 static int hdmi_codec_pcm_new(struct snd_soc_pcm_runtime *rtd,
0771 struct snd_soc_dai *dai)
0772 {
0773 struct snd_soc_dai_driver *drv = dai->driver;
0774 struct hdmi_codec_priv *hcp = snd_soc_dai_get_drvdata(dai);
0775 unsigned int i;
0776 int ret;
0777
0778 ret = snd_pcm_add_chmap_ctls(rtd->pcm, SNDRV_PCM_STREAM_PLAYBACK,
0779 NULL, drv->playback.channels_max, 0,
0780 &hcp->chmap_info);
0781 if (ret < 0)
0782 return ret;
0783
0784
0785 hcp->chmap_info->private_data = hcp;
0786 hcp->chmap_info->kctl->get = hdmi_codec_chmap_ctl_get;
0787
0788
0789 hcp->chmap_info->chmap = hdmi_codec_stereo_chmaps;
0790 hcp->chmap_idx = HDMI_CODEC_CHMAP_IDX_UNKNOWN;
0791
0792 for (i = 0; i < ARRAY_SIZE(hdmi_codec_controls); i++) {
0793 struct snd_kcontrol *kctl;
0794
0795
0796 kctl = snd_ctl_new1(&hdmi_codec_controls[i], dai->component);
0797 if (!kctl)
0798 return -ENOMEM;
0799
0800 kctl->id.device = rtd->pcm->device;
0801 ret = snd_ctl_add(rtd->card->snd_card, kctl);
0802 if (ret < 0)
0803 return ret;
0804 }
0805
0806 return 0;
0807 }
0808
0809 static int hdmi_dai_probe(struct snd_soc_dai *dai)
0810 {
0811 struct snd_soc_dapm_context *dapm;
0812 struct hdmi_codec_daifmt *daifmt;
0813 struct snd_soc_dapm_route route[] = {
0814 {
0815 .sink = "TX",
0816 .source = dai->driver->playback.stream_name,
0817 },
0818 {
0819 .sink = dai->driver->capture.stream_name,
0820 .source = "RX",
0821 },
0822 };
0823 int ret;
0824
0825 dapm = snd_soc_component_get_dapm(dai->component);
0826 ret = snd_soc_dapm_add_routes(dapm, route, 2);
0827 if (ret)
0828 return ret;
0829
0830 daifmt = kzalloc(sizeof(*daifmt), GFP_KERNEL);
0831 if (!daifmt)
0832 return -ENOMEM;
0833
0834 dai->playback_dma_data = daifmt;
0835 return 0;
0836 }
0837
0838 static void hdmi_codec_jack_report(struct hdmi_codec_priv *hcp,
0839 unsigned int jack_status)
0840 {
0841 if (hcp->jack && jack_status != hcp->jack_status) {
0842 snd_soc_jack_report(hcp->jack, jack_status, SND_JACK_LINEOUT);
0843 hcp->jack_status = jack_status;
0844 }
0845 }
0846
0847 static void plugged_cb(struct device *dev, bool plugged)
0848 {
0849 struct hdmi_codec_priv *hcp = dev_get_drvdata(dev);
0850
0851 if (plugged) {
0852 if (hcp->hcd.ops->get_eld) {
0853 hcp->hcd.ops->get_eld(dev->parent, hcp->hcd.data,
0854 hcp->eld, sizeof(hcp->eld));
0855 }
0856 hdmi_codec_jack_report(hcp, SND_JACK_LINEOUT);
0857 } else {
0858 hdmi_codec_jack_report(hcp, 0);
0859 memset(hcp->eld, 0, sizeof(hcp->eld));
0860 }
0861 }
0862
0863 static int hdmi_codec_set_jack(struct snd_soc_component *component,
0864 struct snd_soc_jack *jack,
0865 void *data)
0866 {
0867 struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component);
0868 int ret = -ENOTSUPP;
0869
0870 if (hcp->hcd.ops->hook_plugged_cb) {
0871 hcp->jack = jack;
0872 ret = hcp->hcd.ops->hook_plugged_cb(component->dev->parent,
0873 hcp->hcd.data,
0874 plugged_cb,
0875 component->dev);
0876 if (ret)
0877 hcp->jack = NULL;
0878 }
0879 return ret;
0880 }
0881
0882 static int hdmi_dai_spdif_probe(struct snd_soc_dai *dai)
0883 {
0884 struct hdmi_codec_daifmt *cf;
0885 int ret;
0886
0887 ret = hdmi_dai_probe(dai);
0888 if (ret)
0889 return ret;
0890
0891 cf = dai->playback_dma_data;
0892 cf->fmt = HDMI_SPDIF;
0893
0894 return 0;
0895 }
0896
0897 static int hdmi_codec_dai_remove(struct snd_soc_dai *dai)
0898 {
0899 kfree(dai->playback_dma_data);
0900 return 0;
0901 }
0902
0903 static const struct snd_soc_dai_driver hdmi_i2s_dai = {
0904 .name = "i2s-hifi",
0905 .id = DAI_ID_I2S,
0906 .probe = hdmi_dai_probe,
0907 .remove = hdmi_codec_dai_remove,
0908 .playback = {
0909 .stream_name = "I2S Playback",
0910 .channels_min = 2,
0911 .channels_max = 8,
0912 .rates = HDMI_RATES,
0913 .formats = I2S_FORMATS,
0914 .sig_bits = 24,
0915 },
0916 .capture = {
0917 .stream_name = "Capture",
0918 .channels_min = 2,
0919 .channels_max = 8,
0920 .rates = HDMI_RATES,
0921 .formats = I2S_FORMATS,
0922 .sig_bits = 24,
0923 },
0924 .ops = &hdmi_codec_i2s_dai_ops,
0925 .pcm_new = hdmi_codec_pcm_new,
0926 };
0927
0928 static const struct snd_soc_dai_driver hdmi_spdif_dai = {
0929 .name = "spdif-hifi",
0930 .id = DAI_ID_SPDIF,
0931 .probe = hdmi_dai_spdif_probe,
0932 .remove = hdmi_codec_dai_remove,
0933 .playback = {
0934 .stream_name = "SPDIF Playback",
0935 .channels_min = 2,
0936 .channels_max = 2,
0937 .rates = HDMI_RATES,
0938 .formats = SPDIF_FORMATS,
0939 },
0940 .capture = {
0941 .stream_name = "Capture",
0942 .channels_min = 2,
0943 .channels_max = 2,
0944 .rates = HDMI_RATES,
0945 .formats = SPDIF_FORMATS,
0946 },
0947 .ops = &hdmi_codec_spdif_dai_ops,
0948 .pcm_new = hdmi_codec_pcm_new,
0949 };
0950
0951 static int hdmi_of_xlate_dai_id(struct snd_soc_component *component,
0952 struct device_node *endpoint)
0953 {
0954 struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component);
0955 int ret = -ENOTSUPP;
0956
0957 if (hcp->hcd.ops->get_dai_id)
0958 ret = hcp->hcd.ops->get_dai_id(component, endpoint);
0959
0960 return ret;
0961 }
0962
0963 static void hdmi_remove(struct snd_soc_component *component)
0964 {
0965 struct hdmi_codec_priv *hcp = snd_soc_component_get_drvdata(component);
0966
0967 if (hcp->hcd.ops->hook_plugged_cb)
0968 hcp->hcd.ops->hook_plugged_cb(component->dev->parent,
0969 hcp->hcd.data, NULL, NULL);
0970 }
0971
0972 static const struct snd_soc_component_driver hdmi_driver = {
0973 .remove = hdmi_remove,
0974 .dapm_widgets = hdmi_widgets,
0975 .num_dapm_widgets = ARRAY_SIZE(hdmi_widgets),
0976 .of_xlate_dai_id = hdmi_of_xlate_dai_id,
0977 .idle_bias_on = 1,
0978 .use_pmdown_time = 1,
0979 .endianness = 1,
0980 .set_jack = hdmi_codec_set_jack,
0981 };
0982
0983 static int hdmi_codec_probe(struct platform_device *pdev)
0984 {
0985 struct hdmi_codec_pdata *hcd = pdev->dev.platform_data;
0986 struct snd_soc_dai_driver *daidrv;
0987 struct device *dev = &pdev->dev;
0988 struct hdmi_codec_priv *hcp;
0989 int dai_count, i = 0;
0990 int ret;
0991
0992 if (!hcd) {
0993 dev_err(dev, "%s: No platform data\n", __func__);
0994 return -EINVAL;
0995 }
0996
0997 dai_count = hcd->i2s + hcd->spdif;
0998 if (dai_count < 1 || !hcd->ops ||
0999 (!hcd->ops->hw_params && !hcd->ops->prepare) ||
1000 !hcd->ops->audio_shutdown) {
1001 dev_err(dev, "%s: Invalid parameters\n", __func__);
1002 return -EINVAL;
1003 }
1004
1005 hcp = devm_kzalloc(dev, sizeof(*hcp), GFP_KERNEL);
1006 if (!hcp)
1007 return -ENOMEM;
1008
1009 hcp->hcd = *hcd;
1010 mutex_init(&hcp->lock);
1011
1012 ret = snd_pcm_create_iec958_consumer_default(hcp->iec_status,
1013 sizeof(hcp->iec_status));
1014 if (ret < 0)
1015 return ret;
1016
1017 daidrv = devm_kcalloc(dev, dai_count, sizeof(*daidrv), GFP_KERNEL);
1018 if (!daidrv)
1019 return -ENOMEM;
1020
1021 if (hcd->i2s) {
1022 daidrv[i] = hdmi_i2s_dai;
1023 daidrv[i].playback.channels_max = hcd->max_i2s_channels;
1024 i++;
1025 }
1026
1027 if (hcd->spdif)
1028 daidrv[i] = hdmi_spdif_dai;
1029
1030 dev_set_drvdata(dev, hcp);
1031
1032 ret = devm_snd_soc_register_component(dev, &hdmi_driver, daidrv,
1033 dai_count);
1034 if (ret) {
1035 dev_err(dev, "%s: snd_soc_register_component() failed (%d)\n",
1036 __func__, ret);
1037 return ret;
1038 }
1039 return 0;
1040 }
1041
1042 static struct platform_driver hdmi_codec_driver = {
1043 .driver = {
1044 .name = HDMI_CODEC_DRV_NAME,
1045 },
1046 .probe = hdmi_codec_probe,
1047 };
1048
1049 module_platform_driver(hdmi_codec_driver);
1050
1051 MODULE_AUTHOR("Jyri Sarha <jsarha@ti.com>");
1052 MODULE_DESCRIPTION("HDMI Audio Codec Driver");
1053 MODULE_LICENSE("GPL");
1054 MODULE_ALIAS("platform:" HDMI_CODEC_DRV_NAME);