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