Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * ALSA SoC codec for HDMI encoder drivers
0004  * Copyright (C) 2015 Texas Instruments Incorporated - https://www.ti.com/
0005  * Author: Jyri Sarha <jsarha@ti.com>
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;  /* ALSA API channel map position */
0025 };
0026 
0027 /*
0028  * CEA speaker placement for HDMI 1.4:
0029  *
0030  *  FL  FLC   FC   FRC   FR   FRW
0031  *
0032  *                                  LFE
0033  *
0034  *  RL  RLC   RC   RRC   RR
0035  *
0036  *  Speaker placement has to be extended to support HDMI 2.0
0037  */
0038 enum hdmi_codec_cea_spk_placement {
0039     FL  = BIT(0),   /* Front Left           */
0040     FC  = BIT(1),   /* Front Center         */
0041     FR  = BIT(2),   /* Front Right          */
0042     FLC = BIT(3),   /* Front Left Center    */
0043     FRC = BIT(4),   /* Front Right Center   */
0044     RL  = BIT(5),   /* Rear Left            */
0045     RC  = BIT(6),   /* Rear Center          */
0046     RR  = BIT(7),   /* Rear Right           */
0047     RLC = BIT(8),   /* Rear Left Center     */
0048     RRC = BIT(9),   /* Rear Right Center    */
0049     LFE = BIT(10),  /* Low Frequency Effect */
0050 };
0051 
0052 /*
0053  * cea Speaker allocation structure
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 /* Channel maps  stereo HDMI */
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 /* Channel maps for multi-channel playbacks, up to 8 n_ch */
0069 static const struct snd_pcm_chmap_elem hdmi_codec_8ch_chmaps[] = {
0070     { .channels = 2, /* CA_ID 0x00 */
0071       .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
0072     { .channels = 4, /* CA_ID 0x01 */
0073       .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
0074            SNDRV_CHMAP_NA } },
0075     { .channels = 4, /* CA_ID 0x02 */
0076       .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
0077            SNDRV_CHMAP_FC } },
0078     { .channels = 4, /* CA_ID 0x03 */
0079       .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
0080            SNDRV_CHMAP_FC } },
0081     { .channels = 6, /* CA_ID 0x04 */
0082       .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
0083            SNDRV_CHMAP_NA, SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
0084     { .channels = 6, /* CA_ID 0x05 */
0085       .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
0086            SNDRV_CHMAP_NA, SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
0087     { .channels = 6, /* CA_ID 0x06 */
0088       .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
0089            SNDRV_CHMAP_FC, SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
0090     { .channels = 6, /* CA_ID 0x07 */
0091       .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
0092            SNDRV_CHMAP_FC, SNDRV_CHMAP_RC, SNDRV_CHMAP_NA } },
0093     { .channels = 6, /* CA_ID 0x08 */
0094       .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
0095            SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
0096     { .channels = 6, /* CA_ID 0x09 */
0097       .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
0098            SNDRV_CHMAP_NA, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
0099     { .channels = 6, /* CA_ID 0x0A */
0100       .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_NA,
0101            SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
0102     { .channels = 6, /* CA_ID 0x0B */
0103       .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR, SNDRV_CHMAP_LFE,
0104            SNDRV_CHMAP_FC, SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
0105     { .channels = 8, /* CA_ID 0x0C */
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, /* CA_ID 0x0D */
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, /* CA_ID 0x0E */
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, /* CA_ID 0x0F */
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, /* CA_ID 0x10 */
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, /* CA_ID 0x11 */
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, /* CA_ID 0x12 */
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, /* CA_ID 0x13 */
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, /* CA_ID 0x14 */
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, /* CA_ID 0x15 */
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, /* CA_ID 0x16 */
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, /* CA_ID 0x17 */
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, /* CA_ID 0x18 */
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, /* CA_ID 0x19 */
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, /* CA_ID 0x1A */
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, /* CA_ID 0x1B */
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, /* CA_ID 0x1C */
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, /* CA_ID 0x1D */
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, /* CA_ID 0x1E */
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, /* CA_ID 0x1F */
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  * hdmi_codec_channel_alloc: speaker configuration available for CEA
0190  *
0191  * This is an ordered list that must match with hdmi_codec_8ch_chmaps struct
0192  * The preceding ones have better chances to be selected by
0193  * hdmi_codec_get_ch_alloc_table_idx().
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     /* 2.1 */
0199     { .ca_id = 0x01, .n_ch = 4,
0200       .mask = FL | FR | LFE},
0201     /* Dolby Surround */
0202     { .ca_id = 0x02, .n_ch = 4,
0203       .mask = FL | FR | FC },
0204     /* surround51 */
0205     { .ca_id = 0x0b, .n_ch = 6,
0206       .mask = FL | FR | LFE | FC | RL | RR},
0207     /* surround40 */
0208     { .ca_id = 0x08, .n_ch = 6,
0209       .mask = FL | FR | RL | RR },
0210     /* surround41 */
0211     { .ca_id = 0x09, .n_ch = 6,
0212       .mask = FL | FR | LFE | RL | RR },
0213     /* surround50 */
0214     { .ca_id = 0x0a, .n_ch = 6,
0215       .mask = FL | FR | FC | RL | RR },
0216     /* 6.1 */
0217     { .ca_id = 0x0f, .n_ch = 8,
0218       .mask = FL | FR | LFE | FC | RL | RR | RC },
0219     /* surround71 */
0220     { .ca_id = 0x13, .n_ch = 8,
0221       .mask = FL | FR | LFE | FC | RL | RR | RLC | RRC },
0222     /* others */
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     /* Detect if only stereo supported, else return 8 channels mappings */
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         /* If spk_alloc == 0, HDMI is unplugged return stereo config*/
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         /* Select chmap supported */
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     /* Select a channel allocation that matches with ELD and pcm channels */
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     /* Reset daifmt */
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      * ignore if direction was CAPTURE
0674      * and it had .no_capture_mute flag
0675      * see
0676      *  snd_soc_dai_digital_mute()
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  * This driver can select all SND_SOC_DAIFMT_CBx_CFx,
0690  * but need to be selected from Sound Card, not be auto selected.
0691  * Because it might be used from other driver.
0692  * For example,
0693  *  ${LINUX}/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c
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  * This list is only for formats allowed on the I2S bus. So there is
0735  * some formats listed that are not supported by HDMI interface. For
0736  * instance allowing the 32-bit formats enables 24-precision with CPU
0737  * DAIs that do not support 24-bit formats. If the extra formats cause
0738  * problems, we should add the video side driver an option to disable
0739  * them.
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     /* override handlers */
0785     hcp->chmap_info->private_data = hcp;
0786     hcp->chmap_info->kctl->get = hdmi_codec_chmap_ctl_get;
0787 
0788     /* default chmap supported is stereo */
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         /* add ELD ctl with the device number corresponding to the PCM stream */
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; /* see snd_soc_get_dai_id() */
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);