1*287599cfSJerome Anand /* 2*287599cfSJerome Anand * intel_hdmi_lpe_audio.h - Intel HDMI LPE audio driver 3*287599cfSJerome Anand * 4*287599cfSJerome Anand * Copyright (C) 2016 Intel Corp 5*287599cfSJerome Anand * Authors: Sailaja Bandarupalli <sailaja.bandarupalli@intel.com> 6*287599cfSJerome Anand * Ramesh Babu K V <ramesh.babu@intel.com> 7*287599cfSJerome Anand * Vaibhav Agarwal <vaibhav.agarwal@intel.com> 8*287599cfSJerome Anand * Jerome Anand <jerome.anand@intel.com> 9*287599cfSJerome Anand * Aravind Siddappaji <aravindx.siddappaji@intel.com> 10*287599cfSJerome Anand * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 11*287599cfSJerome Anand * 12*287599cfSJerome Anand * This program is free software; you can redistribute it and/or modify 13*287599cfSJerome Anand * it under the terms of the GNU General Public License as published by 14*287599cfSJerome Anand * the Free Software Foundation; version 2 of the License. 15*287599cfSJerome Anand * 16*287599cfSJerome Anand * This program is distributed in the hope that it will be useful, but 17*287599cfSJerome Anand * WITHOUT ANY WARRANTY; without even the implied warranty of 18*287599cfSJerome Anand * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 19*287599cfSJerome Anand * General Public License for more details. 20*287599cfSJerome Anand * 21*287599cfSJerome Anand * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 22*287599cfSJerome Anand */ 23*287599cfSJerome Anand #ifndef __INTEL_HDMI_LPE_AUDIO_H 24*287599cfSJerome Anand #define __INTEL_HDMI_LPE_AUDIO_H 25*287599cfSJerome Anand 26*287599cfSJerome Anand #include <linux/types.h> 27*287599cfSJerome Anand #include <sound/initval.h> 28*287599cfSJerome Anand #include <linux/version.h> 29*287599cfSJerome Anand #include <linux/pm_runtime.h> 30*287599cfSJerome Anand #include <sound/asoundef.h> 31*287599cfSJerome Anand #include <sound/control.h> 32*287599cfSJerome Anand #include <sound/pcm.h> 33*287599cfSJerome Anand 34*287599cfSJerome Anand #define HMDI_LPE_AUDIO_DRIVER_NAME "intel-hdmi-lpe-audio" 35*287599cfSJerome Anand #define HAD_MAX_DEVICES 1 36*287599cfSJerome Anand #define HAD_MIN_CHANNEL 2 37*287599cfSJerome Anand #define HAD_MAX_CHANNEL 8 38*287599cfSJerome Anand #define HAD_NUM_OF_RING_BUFS 4 39*287599cfSJerome Anand 40*287599cfSJerome Anand /* Assume 192KHz, 8channel, 25msec period */ 41*287599cfSJerome Anand #define HAD_MAX_BUFFER (600*1024) 42*287599cfSJerome Anand #define HAD_MIN_BUFFER (32*1024) 43*287599cfSJerome Anand #define HAD_MAX_PERIODS 4 44*287599cfSJerome Anand #define HAD_MIN_PERIODS 4 45*287599cfSJerome Anand #define HAD_MAX_PERIOD_BYTES (HAD_MAX_BUFFER/HAD_MIN_PERIODS) 46*287599cfSJerome Anand #define HAD_MIN_PERIOD_BYTES 256 47*287599cfSJerome Anand #define HAD_FIFO_SIZE 0 /* fifo not being used */ 48*287599cfSJerome Anand #define MAX_SPEAKERS 8 49*287599cfSJerome Anand 50*287599cfSJerome Anand #define AUD_SAMPLE_RATE_32 32000 51*287599cfSJerome Anand #define AUD_SAMPLE_RATE_44_1 44100 52*287599cfSJerome Anand #define AUD_SAMPLE_RATE_48 48000 53*287599cfSJerome Anand #define AUD_SAMPLE_RATE_88_2 88200 54*287599cfSJerome Anand #define AUD_SAMPLE_RATE_96 96000 55*287599cfSJerome Anand #define AUD_SAMPLE_RATE_176_4 176400 56*287599cfSJerome Anand #define AUD_SAMPLE_RATE_192 192000 57*287599cfSJerome Anand 58*287599cfSJerome Anand #define HAD_MIN_RATE AUD_SAMPLE_RATE_32 59*287599cfSJerome Anand #define HAD_MAX_RATE AUD_SAMPLE_RATE_192 60*287599cfSJerome Anand 61*287599cfSJerome Anand #define DIS_SAMPLE_RATE_25_2 25200 62*287599cfSJerome Anand #define DIS_SAMPLE_RATE_27 27000 63*287599cfSJerome Anand #define DIS_SAMPLE_RATE_54 54000 64*287599cfSJerome Anand #define DIS_SAMPLE_RATE_74_25 74250 65*287599cfSJerome Anand #define DIS_SAMPLE_RATE_148_5 148500 66*287599cfSJerome Anand #define HAD_REG_WIDTH 0x08 67*287599cfSJerome Anand #define HAD_MAX_HW_BUFS 0x04 68*287599cfSJerome Anand #define HAD_MAX_DIP_WORDS 16 69*287599cfSJerome Anand #define INTEL_HAD "IntelHdmiLpeAudio" 70*287599cfSJerome Anand 71*287599cfSJerome Anand /* _AUD_CONFIG register MASK */ 72*287599cfSJerome Anand #define AUD_CONFIG_MASK_UNDERRUN 0xC0000000 73*287599cfSJerome Anand #define AUD_CONFIG_MASK_SRDBG 0x00000002 74*287599cfSJerome Anand #define AUD_CONFIG_MASK_FUNCRST 0x00000001 75*287599cfSJerome Anand 76*287599cfSJerome Anand #define MAX_CNT 0xFF 77*287599cfSJerome Anand #define HAD_SUSPEND_DELAY 1000 78*287599cfSJerome Anand 79*287599cfSJerome Anand #define OTM_HDMI_ELD_SIZE 128 80*287599cfSJerome Anand 81*287599cfSJerome Anand union otm_hdmi_eld_t { 82*287599cfSJerome Anand unsigned char eld_data[OTM_HDMI_ELD_SIZE]; 83*287599cfSJerome Anand struct { 84*287599cfSJerome Anand /* Byte[0] = ELD Version Number */ 85*287599cfSJerome Anand union { 86*287599cfSJerome Anand unsigned char byte0; 87*287599cfSJerome Anand struct { 88*287599cfSJerome Anand unsigned char reserved:3; /* Reserf */ 89*287599cfSJerome Anand unsigned char eld_ver:5; /* ELD Version Number */ 90*287599cfSJerome Anand /* 00000b - reserved 91*287599cfSJerome Anand * 00001b - first rev, obsoleted 92*287599cfSJerome Anand * 00010b - version 2, supporting CEA version 93*287599cfSJerome Anand * 861D or below 94*287599cfSJerome Anand * 00011b:11111b - reserved 95*287599cfSJerome Anand * for future 96*287599cfSJerome Anand */ 97*287599cfSJerome Anand }; 98*287599cfSJerome Anand }; 99*287599cfSJerome Anand 100*287599cfSJerome Anand /* Byte[1] = Vendor Version Field */ 101*287599cfSJerome Anand union { 102*287599cfSJerome Anand unsigned char vendor_version; 103*287599cfSJerome Anand struct { 104*287599cfSJerome Anand unsigned char reserved1:3; 105*287599cfSJerome Anand unsigned char veld_ver:5; /* Version number of the ELD 106*287599cfSJerome Anand * extension. This value is 107*287599cfSJerome Anand * provisioned and unique to 108*287599cfSJerome Anand * each vendor. 109*287599cfSJerome Anand */ 110*287599cfSJerome Anand }; 111*287599cfSJerome Anand }; 112*287599cfSJerome Anand 113*287599cfSJerome Anand /* Byte[2] = Baseline Length field */ 114*287599cfSJerome Anand unsigned char baseline_eld_length; /* Length of the Baseline structure 115*287599cfSJerome Anand * divided by Four. 116*287599cfSJerome Anand */ 117*287599cfSJerome Anand 118*287599cfSJerome Anand /* Byte [3] = Reserved for future use */ 119*287599cfSJerome Anand unsigned char byte3; 120*287599cfSJerome Anand 121*287599cfSJerome Anand /* Starting of the BaseLine EELD structure 122*287599cfSJerome Anand * Byte[4] = Monitor Name Length 123*287599cfSJerome Anand */ 124*287599cfSJerome Anand union { 125*287599cfSJerome Anand unsigned char byte4; 126*287599cfSJerome Anand struct { 127*287599cfSJerome Anand unsigned char mnl:5; 128*287599cfSJerome Anand unsigned char cea_edid_rev_id:3; 129*287599cfSJerome Anand }; 130*287599cfSJerome Anand }; 131*287599cfSJerome Anand 132*287599cfSJerome Anand /* Byte[5] = Capabilities */ 133*287599cfSJerome Anand union { 134*287599cfSJerome Anand unsigned char capabilities; 135*287599cfSJerome Anand struct { 136*287599cfSJerome Anand unsigned char hdcp:1; /* HDCP support */ 137*287599cfSJerome Anand unsigned char ai_support:1; /* AI support */ 138*287599cfSJerome Anand unsigned char connection_type:2; /* Connection type 139*287599cfSJerome Anand * 00 - HDMI 140*287599cfSJerome Anand * 01 - DP 141*287599cfSJerome Anand * 10 -11 Reserved 142*287599cfSJerome Anand * for future 143*287599cfSJerome Anand * connection types 144*287599cfSJerome Anand */ 145*287599cfSJerome Anand unsigned char sadc:4; /* Indicates number of 3 bytes 146*287599cfSJerome Anand * Short Audio Descriptors. 147*287599cfSJerome Anand */ 148*287599cfSJerome Anand }; 149*287599cfSJerome Anand }; 150*287599cfSJerome Anand 151*287599cfSJerome Anand /* Byte[6] = Audio Synch Delay */ 152*287599cfSJerome Anand unsigned char audio_synch_delay; /* Amount of time reported by the 153*287599cfSJerome Anand * sink that the video trails audio 154*287599cfSJerome Anand * in milliseconds. 155*287599cfSJerome Anand */ 156*287599cfSJerome Anand 157*287599cfSJerome Anand /* Byte[7] = Speaker Allocation Block */ 158*287599cfSJerome Anand union { 159*287599cfSJerome Anand unsigned char speaker_allocation_block; 160*287599cfSJerome Anand struct { 161*287599cfSJerome Anand unsigned char flr:1; /*Front Left and Right channels*/ 162*287599cfSJerome Anand unsigned char lfe:1; /*Low Frequency Effect channel*/ 163*287599cfSJerome Anand unsigned char fc:1; /*Center transmission channel*/ 164*287599cfSJerome Anand unsigned char rlr:1; /*Rear Left and Right channels*/ 165*287599cfSJerome Anand unsigned char rc:1; /*Rear Center channel*/ 166*287599cfSJerome Anand unsigned char flrc:1; /*Front left and Right of Center 167*287599cfSJerome Anand *transmission channels 168*287599cfSJerome Anand */ 169*287599cfSJerome Anand unsigned char rlrc:1; /*Rear left and Right of Center 170*287599cfSJerome Anand *transmission channels 171*287599cfSJerome Anand */ 172*287599cfSJerome Anand unsigned char reserved3:1; /* Reserved */ 173*287599cfSJerome Anand }; 174*287599cfSJerome Anand }; 175*287599cfSJerome Anand 176*287599cfSJerome Anand /* Byte[8 - 15] - 8 Byte port identification value */ 177*287599cfSJerome Anand unsigned char port_id_value[8]; 178*287599cfSJerome Anand 179*287599cfSJerome Anand /* Byte[16 - 17] - 2 Byte Manufacturer ID */ 180*287599cfSJerome Anand unsigned char manufacturer_id[2]; 181*287599cfSJerome Anand 182*287599cfSJerome Anand /* Byte[18 - 19] - 2 Byte Product ID */ 183*287599cfSJerome Anand unsigned char product_id[2]; 184*287599cfSJerome Anand 185*287599cfSJerome Anand /* Byte [20-83] - 64 Bytes of BaseLine Data */ 186*287599cfSJerome Anand unsigned char mn_sand_sads[64]; /* This will include 187*287599cfSJerome Anand * - ASCII string of Monitor name 188*287599cfSJerome Anand * - List of 3 byte SADs 189*287599cfSJerome Anand * - Zero padding 190*287599cfSJerome Anand */ 191*287599cfSJerome Anand 192*287599cfSJerome Anand /* Vendor ELD Block should continue here! 193*287599cfSJerome Anand * No Vendor ELD block defined as of now. 194*287599cfSJerome Anand */ 195*287599cfSJerome Anand } __packed; 196*287599cfSJerome Anand }; 197*287599cfSJerome Anand 198*287599cfSJerome Anand /** 199*287599cfSJerome Anand * enum had_status - Audio stream states 200*287599cfSJerome Anand * 201*287599cfSJerome Anand * @STREAM_INIT: Stream initialized 202*287599cfSJerome Anand * @STREAM_RUNNING: Stream running 203*287599cfSJerome Anand * @STREAM_PAUSED: Stream paused 204*287599cfSJerome Anand * @STREAM_DROPPED: Stream dropped 205*287599cfSJerome Anand */ 206*287599cfSJerome Anand enum had_stream_status { 207*287599cfSJerome Anand STREAM_INIT = 0, 208*287599cfSJerome Anand STREAM_RUNNING = 1, 209*287599cfSJerome Anand STREAM_PAUSED = 2, 210*287599cfSJerome Anand STREAM_DROPPED = 3 211*287599cfSJerome Anand }; 212*287599cfSJerome Anand 213*287599cfSJerome Anand /** 214*287599cfSJerome Anand * enum had_status_stream - HAD stream states 215*287599cfSJerome Anand */ 216*287599cfSJerome Anand enum had_status_stream { 217*287599cfSJerome Anand HAD_INIT = 0, 218*287599cfSJerome Anand HAD_RUNNING_STREAM, 219*287599cfSJerome Anand }; 220*287599cfSJerome Anand 221*287599cfSJerome Anand enum had_drv_status { 222*287599cfSJerome Anand HAD_DRV_CONNECTED, 223*287599cfSJerome Anand HAD_DRV_RUNNING, 224*287599cfSJerome Anand HAD_DRV_DISCONNECTED, 225*287599cfSJerome Anand HAD_DRV_SUSPENDED, 226*287599cfSJerome Anand HAD_DRV_ERR, 227*287599cfSJerome Anand }; 228*287599cfSJerome Anand 229*287599cfSJerome Anand /* enum intel_had_aud_buf_type - HDMI controller ring buffer types */ 230*287599cfSJerome Anand enum intel_had_aud_buf_type { 231*287599cfSJerome Anand HAD_BUF_TYPE_A = 0, 232*287599cfSJerome Anand HAD_BUF_TYPE_B = 1, 233*287599cfSJerome Anand HAD_BUF_TYPE_C = 2, 234*287599cfSJerome Anand HAD_BUF_TYPE_D = 3, 235*287599cfSJerome Anand }; 236*287599cfSJerome Anand 237*287599cfSJerome Anand enum num_aud_ch { 238*287599cfSJerome Anand CH_STEREO = 0, 239*287599cfSJerome Anand CH_THREE_FOUR = 1, 240*287599cfSJerome Anand CH_FIVE_SIX = 2, 241*287599cfSJerome Anand CH_SEVEN_EIGHT = 3 242*287599cfSJerome Anand }; 243*287599cfSJerome Anand 244*287599cfSJerome Anand /* HDMI Controller register offsets - audio domain common */ 245*287599cfSJerome Anand /* Base address for below regs = 0x65000 */ 246*287599cfSJerome Anand enum hdmi_ctrl_reg_offset_common { 247*287599cfSJerome Anand AUDIO_HDMI_CONFIG_A = 0x000, 248*287599cfSJerome Anand AUDIO_HDMI_CONFIG_B = 0x800, 249*287599cfSJerome Anand AUDIO_HDMI_CONFIG_C = 0x900, 250*287599cfSJerome Anand }; 251*287599cfSJerome Anand /* HDMI controller register offsets */ 252*287599cfSJerome Anand enum hdmi_ctrl_reg_offset_v1 { 253*287599cfSJerome Anand AUD_CONFIG = 0x0, 254*287599cfSJerome Anand AUD_CH_STATUS_0 = 0x08, 255*287599cfSJerome Anand AUD_CH_STATUS_1 = 0x0C, 256*287599cfSJerome Anand AUD_HDMI_CTS = 0x10, 257*287599cfSJerome Anand AUD_N_ENABLE = 0x14, 258*287599cfSJerome Anand AUD_SAMPLE_RATE = 0x18, 259*287599cfSJerome Anand AUD_BUF_CONFIG = 0x20, 260*287599cfSJerome Anand AUD_BUF_CH_SWAP = 0x24, 261*287599cfSJerome Anand AUD_BUF_A_ADDR = 0x40, 262*287599cfSJerome Anand AUD_BUF_A_LENGTH = 0x44, 263*287599cfSJerome Anand AUD_BUF_B_ADDR = 0x48, 264*287599cfSJerome Anand AUD_BUF_B_LENGTH = 0x4c, 265*287599cfSJerome Anand AUD_BUF_C_ADDR = 0x50, 266*287599cfSJerome Anand AUD_BUF_C_LENGTH = 0x54, 267*287599cfSJerome Anand AUD_BUF_D_ADDR = 0x58, 268*287599cfSJerome Anand AUD_BUF_D_LENGTH = 0x5c, 269*287599cfSJerome Anand AUD_CNTL_ST = 0x60, 270*287599cfSJerome Anand AUD_HDMI_STATUS = 0x68, 271*287599cfSJerome Anand AUD_HDMIW_INFOFR = 0x114, 272*287599cfSJerome Anand }; 273*287599cfSJerome Anand 274*287599cfSJerome Anand /* 275*287599cfSJerome Anand * Delta changes in HDMI controller register offsets 276*287599cfSJerome Anand * compare to v1 version 277*287599cfSJerome Anand */ 278*287599cfSJerome Anand 279*287599cfSJerome Anand enum hdmi_ctrl_reg_offset_v2 { 280*287599cfSJerome Anand AUD_HDMI_STATUS_v2 = 0x64, 281*287599cfSJerome Anand AUD_HDMIW_INFOFR_v2 = 0x68, 282*287599cfSJerome Anand }; 283*287599cfSJerome Anand 284*287599cfSJerome Anand /* 285*287599cfSJerome Anand * CEA speaker placement: 286*287599cfSJerome Anand * 287*287599cfSJerome Anand * FL FLC FC FRC FR 288*287599cfSJerome Anand * 289*287599cfSJerome Anand * LFE 290*287599cfSJerome Anand * 291*287599cfSJerome Anand * RL RLC RC RRC RR 292*287599cfSJerome Anand * 293*287599cfSJerome Anand * The Left/Right Surround channel _notions_ LS/RS in SMPTE 320M 294*287599cfSJerome Anand * corresponds to CEA RL/RR; The SMPTE channel _assignment_ C/LFE is 295*287599cfSJerome Anand * swapped to CEA LFE/FC. 296*287599cfSJerome Anand */ 297*287599cfSJerome Anand enum cea_speaker_placement { 298*287599cfSJerome Anand FL = (1 << 0), /* Front Left */ 299*287599cfSJerome Anand FC = (1 << 1), /* Front Center */ 300*287599cfSJerome Anand FR = (1 << 2), /* Front Right */ 301*287599cfSJerome Anand FLC = (1 << 3), /* Front Left Center */ 302*287599cfSJerome Anand FRC = (1 << 4), /* Front Right Center */ 303*287599cfSJerome Anand RL = (1 << 5), /* Rear Left */ 304*287599cfSJerome Anand RC = (1 << 6), /* Rear Center */ 305*287599cfSJerome Anand RR = (1 << 7), /* Rear Right */ 306*287599cfSJerome Anand RLC = (1 << 8), /* Rear Left Center */ 307*287599cfSJerome Anand RRC = (1 << 9), /* Rear Right Center */ 308*287599cfSJerome Anand LFE = (1 << 10), /* Low Frequency Effect */ 309*287599cfSJerome Anand }; 310*287599cfSJerome Anand 311*287599cfSJerome Anand struct cea_channel_speaker_allocation { 312*287599cfSJerome Anand int ca_index; 313*287599cfSJerome Anand int speakers[8]; 314*287599cfSJerome Anand 315*287599cfSJerome Anand /* derived values, just for convenience */ 316*287599cfSJerome Anand int channels; 317*287599cfSJerome Anand int spk_mask; 318*287599cfSJerome Anand }; 319*287599cfSJerome Anand 320*287599cfSJerome Anand struct channel_map_table { 321*287599cfSJerome Anand unsigned char map; /* ALSA API channel map position */ 322*287599cfSJerome Anand unsigned char cea_slot; /* CEA slot value */ 323*287599cfSJerome Anand int spk_mask; /* speaker position bit mask */ 324*287599cfSJerome Anand }; 325*287599cfSJerome Anand 326*287599cfSJerome Anand /** 327*287599cfSJerome Anand * union aud_cfg - Audio configuration 328*287599cfSJerome Anand * 329*287599cfSJerome Anand * @cfg_regx: individual register bits 330*287599cfSJerome Anand * @cfg_regval: full register value 331*287599cfSJerome Anand * 332*287599cfSJerome Anand */ 333*287599cfSJerome Anand union aud_cfg { 334*287599cfSJerome Anand struct { 335*287599cfSJerome Anand u32 aud_en:1; 336*287599cfSJerome Anand u32 layout:1; 337*287599cfSJerome Anand u32 fmt:2; 338*287599cfSJerome Anand u32 num_ch:2; 339*287599cfSJerome Anand u32 rsvd0:1; 340*287599cfSJerome Anand u32 set:1; 341*287599cfSJerome Anand u32 flat:1; 342*287599cfSJerome Anand u32 val_bit:1; 343*287599cfSJerome Anand u32 user_bit:1; 344*287599cfSJerome Anand u32 underrun:1; 345*287599cfSJerome Anand u32 rsvd1:20; 346*287599cfSJerome Anand } cfg_regx; 347*287599cfSJerome Anand struct { 348*287599cfSJerome Anand u32 aud_en:1; 349*287599cfSJerome Anand u32 layout:1; 350*287599cfSJerome Anand u32 fmt:2; 351*287599cfSJerome Anand u32 num_ch:3; 352*287599cfSJerome Anand u32 set:1; 353*287599cfSJerome Anand u32 flat:1; 354*287599cfSJerome Anand u32 val_bit:1; 355*287599cfSJerome Anand u32 user_bit:1; 356*287599cfSJerome Anand u32 underrun:1; 357*287599cfSJerome Anand u32 packet_mode:1; 358*287599cfSJerome Anand u32 left_align:1; 359*287599cfSJerome Anand u32 bogus_sample:1; 360*287599cfSJerome Anand u32 dp_modei:1; 361*287599cfSJerome Anand u32 rsvd:16; 362*287599cfSJerome Anand } cfg_regx_v2; 363*287599cfSJerome Anand u32 cfg_regval; 364*287599cfSJerome Anand }; 365*287599cfSJerome Anand 366*287599cfSJerome Anand /** 367*287599cfSJerome Anand * union aud_ch_status_0 - Audio Channel Status 0 Attributes 368*287599cfSJerome Anand * 369*287599cfSJerome Anand * @status_0_regx:individual register bits 370*287599cfSJerome Anand * @status_0_regval:full register value 371*287599cfSJerome Anand * 372*287599cfSJerome Anand */ 373*287599cfSJerome Anand union aud_ch_status_0 { 374*287599cfSJerome Anand struct { 375*287599cfSJerome Anand u32 ch_status:1; 376*287599cfSJerome Anand u32 lpcm_id:1; 377*287599cfSJerome Anand u32 cp_info:1; 378*287599cfSJerome Anand u32 format:3; 379*287599cfSJerome Anand u32 mode:2; 380*287599cfSJerome Anand u32 ctg_code:8; 381*287599cfSJerome Anand u32 src_num:4; 382*287599cfSJerome Anand u32 ch_num:4; 383*287599cfSJerome Anand u32 samp_freq:4; 384*287599cfSJerome Anand u32 clk_acc:2; 385*287599cfSJerome Anand u32 rsvd:2; 386*287599cfSJerome Anand } status_0_regx; 387*287599cfSJerome Anand u32 status_0_regval; 388*287599cfSJerome Anand }; 389*287599cfSJerome Anand 390*287599cfSJerome Anand /** 391*287599cfSJerome Anand * union aud_ch_status_1 - Audio Channel Status 1 Attributes 392*287599cfSJerome Anand * 393*287599cfSJerome Anand * @status_1_regx: individual register bits 394*287599cfSJerome Anand * @status_1_regval: full register value 395*287599cfSJerome Anand * 396*287599cfSJerome Anand */ 397*287599cfSJerome Anand union aud_ch_status_1 { 398*287599cfSJerome Anand struct { 399*287599cfSJerome Anand u32 max_wrd_len:1; 400*287599cfSJerome Anand u32 wrd_len:3; 401*287599cfSJerome Anand u32 rsvd:28; 402*287599cfSJerome Anand } status_1_regx; 403*287599cfSJerome Anand u32 status_1_regval; 404*287599cfSJerome Anand }; 405*287599cfSJerome Anand 406*287599cfSJerome Anand /** 407*287599cfSJerome Anand * union aud_hdmi_cts - CTS register 408*287599cfSJerome Anand * 409*287599cfSJerome Anand * @cts_regx: individual register bits 410*287599cfSJerome Anand * @cts_regval: full register value 411*287599cfSJerome Anand * 412*287599cfSJerome Anand */ 413*287599cfSJerome Anand union aud_hdmi_cts { 414*287599cfSJerome Anand struct { 415*287599cfSJerome Anand u32 cts_val:20; 416*287599cfSJerome Anand u32 en_cts_prog:1; 417*287599cfSJerome Anand u32 rsvd:11; 418*287599cfSJerome Anand } cts_regx; 419*287599cfSJerome Anand struct { 420*287599cfSJerome Anand u32 cts_val:24; 421*287599cfSJerome Anand u32 en_cts_prog:1; 422*287599cfSJerome Anand u32 rsvd:7; 423*287599cfSJerome Anand } cts_regx_v2; 424*287599cfSJerome Anand u32 cts_regval; 425*287599cfSJerome Anand }; 426*287599cfSJerome Anand 427*287599cfSJerome Anand /** 428*287599cfSJerome Anand * union aud_hdmi_n_enable - N register 429*287599cfSJerome Anand * 430*287599cfSJerome Anand * @n_regx: individual register bits 431*287599cfSJerome Anand * @n_regval: full register value 432*287599cfSJerome Anand * 433*287599cfSJerome Anand */ 434*287599cfSJerome Anand union aud_hdmi_n_enable { 435*287599cfSJerome Anand struct { 436*287599cfSJerome Anand u32 n_val:20; 437*287599cfSJerome Anand u32 en_n_prog:1; 438*287599cfSJerome Anand u32 rsvd:11; 439*287599cfSJerome Anand } n_regx; 440*287599cfSJerome Anand struct { 441*287599cfSJerome Anand u32 n_val:24; 442*287599cfSJerome Anand u32 en_n_prog:1; 443*287599cfSJerome Anand u32 rsvd:7; 444*287599cfSJerome Anand } n_regx_v2; 445*287599cfSJerome Anand u32 n_regval; 446*287599cfSJerome Anand }; 447*287599cfSJerome Anand 448*287599cfSJerome Anand /** 449*287599cfSJerome Anand * union aud_buf_config - Audio Buffer configurations 450*287599cfSJerome Anand * 451*287599cfSJerome Anand * @buf_cfg_regx: individual register bits 452*287599cfSJerome Anand * @buf_cfgval: full register value 453*287599cfSJerome Anand * 454*287599cfSJerome Anand */ 455*287599cfSJerome Anand union aud_buf_config { 456*287599cfSJerome Anand struct { 457*287599cfSJerome Anand u32 fifo_width:8; 458*287599cfSJerome Anand u32 rsvd0:8; 459*287599cfSJerome Anand u32 aud_delay:8; 460*287599cfSJerome Anand u32 rsvd1:8; 461*287599cfSJerome Anand } buf_cfg_regx; 462*287599cfSJerome Anand struct { 463*287599cfSJerome Anand u32 audio_fifo_watermark:8; 464*287599cfSJerome Anand u32 dma_fifo_watermark:3; 465*287599cfSJerome Anand u32 rsvd0:5; 466*287599cfSJerome Anand u32 aud_delay:8; 467*287599cfSJerome Anand u32 rsvd1:8; 468*287599cfSJerome Anand } buf_cfg_regx_v2; 469*287599cfSJerome Anand u32 buf_cfgval; 470*287599cfSJerome Anand }; 471*287599cfSJerome Anand 472*287599cfSJerome Anand /** 473*287599cfSJerome Anand * union aud_buf_ch_swap - Audio Sample Swapping offset 474*287599cfSJerome Anand * 475*287599cfSJerome Anand * @buf_ch_swap_regx: individual register bits 476*287599cfSJerome Anand * @buf_ch_swap_val: full register value 477*287599cfSJerome Anand * 478*287599cfSJerome Anand */ 479*287599cfSJerome Anand union aud_buf_ch_swap { 480*287599cfSJerome Anand struct { 481*287599cfSJerome Anand u32 first_0:3; 482*287599cfSJerome Anand u32 second_0:3; 483*287599cfSJerome Anand u32 first_1:3; 484*287599cfSJerome Anand u32 second_1:3; 485*287599cfSJerome Anand u32 first_2:3; 486*287599cfSJerome Anand u32 second_2:3; 487*287599cfSJerome Anand u32 first_3:3; 488*287599cfSJerome Anand u32 second_3:3; 489*287599cfSJerome Anand u32 rsvd:8; 490*287599cfSJerome Anand } buf_ch_swap_regx; 491*287599cfSJerome Anand u32 buf_ch_swap_val; 492*287599cfSJerome Anand }; 493*287599cfSJerome Anand 494*287599cfSJerome Anand /** 495*287599cfSJerome Anand * union aud_buf_addr - Address for Audio Buffer 496*287599cfSJerome Anand * 497*287599cfSJerome Anand * @buf_addr_regx: individual register bits 498*287599cfSJerome Anand * @buf_addr_val: full register value 499*287599cfSJerome Anand * 500*287599cfSJerome Anand */ 501*287599cfSJerome Anand union aud_buf_addr { 502*287599cfSJerome Anand struct { 503*287599cfSJerome Anand u32 valid:1; 504*287599cfSJerome Anand u32 intr_en:1; 505*287599cfSJerome Anand u32 rsvd:4; 506*287599cfSJerome Anand u32 addr:26; 507*287599cfSJerome Anand } buf_addr_regx; 508*287599cfSJerome Anand u32 buf_addr_val; 509*287599cfSJerome Anand }; 510*287599cfSJerome Anand 511*287599cfSJerome Anand /** 512*287599cfSJerome Anand * union aud_buf_len - Length of Audio Buffer 513*287599cfSJerome Anand * 514*287599cfSJerome Anand * @buf_len_regx: individual register bits 515*287599cfSJerome Anand * @buf_len_val: full register value 516*287599cfSJerome Anand * 517*287599cfSJerome Anand */ 518*287599cfSJerome Anand union aud_buf_len { 519*287599cfSJerome Anand struct { 520*287599cfSJerome Anand u32 buf_len:20; 521*287599cfSJerome Anand u32 rsvd:12; 522*287599cfSJerome Anand } buf_len_regx; 523*287599cfSJerome Anand u32 buf_len_val; 524*287599cfSJerome Anand }; 525*287599cfSJerome Anand 526*287599cfSJerome Anand /** 527*287599cfSJerome Anand * union aud_ctrl_st - Audio Control State Register offset 528*287599cfSJerome Anand * 529*287599cfSJerome Anand * @ctrl_regx: individual register bits 530*287599cfSJerome Anand * @ctrl_val: full register value 531*287599cfSJerome Anand * 532*287599cfSJerome Anand */ 533*287599cfSJerome Anand union aud_ctrl_st { 534*287599cfSJerome Anand struct { 535*287599cfSJerome Anand u32 ram_addr:4; 536*287599cfSJerome Anand u32 eld_ack:1; 537*287599cfSJerome Anand u32 eld_addr:4; 538*287599cfSJerome Anand u32 eld_buf_size:5; 539*287599cfSJerome Anand u32 eld_valid:1; 540*287599cfSJerome Anand u32 cp_ready:1; 541*287599cfSJerome Anand u32 dip_freq:2; 542*287599cfSJerome Anand u32 dip_idx:3; 543*287599cfSJerome Anand u32 dip_en_sta:4; 544*287599cfSJerome Anand u32 rsvd:7; 545*287599cfSJerome Anand } ctrl_regx; 546*287599cfSJerome Anand u32 ctrl_val; 547*287599cfSJerome Anand }; 548*287599cfSJerome Anand 549*287599cfSJerome Anand /** 550*287599cfSJerome Anand * union aud_info_frame1 - Audio HDMI Widget Data Island Packet offset 551*287599cfSJerome Anand * 552*287599cfSJerome Anand * @fr1_regx: individual register bits 553*287599cfSJerome Anand * @fr1_val: full register value 554*287599cfSJerome Anand * 555*287599cfSJerome Anand */ 556*287599cfSJerome Anand union aud_info_frame1 { 557*287599cfSJerome Anand struct { 558*287599cfSJerome Anand u32 pkt_type:8; 559*287599cfSJerome Anand u32 ver_num:8; 560*287599cfSJerome Anand u32 len:5; 561*287599cfSJerome Anand u32 rsvd:11; 562*287599cfSJerome Anand } fr1_regx; 563*287599cfSJerome Anand u32 fr1_val; 564*287599cfSJerome Anand }; 565*287599cfSJerome Anand 566*287599cfSJerome Anand /** 567*287599cfSJerome Anand * union aud_info_frame2 - DIP frame 2 568*287599cfSJerome Anand * 569*287599cfSJerome Anand * @fr2_regx: individual register bits 570*287599cfSJerome Anand * @fr2_val: full register value 571*287599cfSJerome Anand * 572*287599cfSJerome Anand */ 573*287599cfSJerome Anand union aud_info_frame2 { 574*287599cfSJerome Anand struct { 575*287599cfSJerome Anand u32 chksum:8; 576*287599cfSJerome Anand u32 chnl_cnt:3; 577*287599cfSJerome Anand u32 rsvd0:1; 578*287599cfSJerome Anand u32 coding_type:4; 579*287599cfSJerome Anand u32 smpl_size:2; 580*287599cfSJerome Anand u32 smpl_freq:3; 581*287599cfSJerome Anand u32 rsvd1:3; 582*287599cfSJerome Anand u32 format:8; 583*287599cfSJerome Anand } fr2_regx; 584*287599cfSJerome Anand u32 fr2_val; 585*287599cfSJerome Anand }; 586*287599cfSJerome Anand 587*287599cfSJerome Anand /** 588*287599cfSJerome Anand * union aud_info_frame3 - DIP frame 3 589*287599cfSJerome Anand * 590*287599cfSJerome Anand * @fr3_regx: individual register bits 591*287599cfSJerome Anand * @fr3_val: full register value 592*287599cfSJerome Anand * 593*287599cfSJerome Anand */ 594*287599cfSJerome Anand union aud_info_frame3 { 595*287599cfSJerome Anand struct { 596*287599cfSJerome Anand u32 chnl_alloc:8; 597*287599cfSJerome Anand u32 rsvd0:3; 598*287599cfSJerome Anand u32 lsv:4; 599*287599cfSJerome Anand u32 dm_inh:1; 600*287599cfSJerome Anand u32 rsvd1:16; 601*287599cfSJerome Anand } fr3_regx; 602*287599cfSJerome Anand u32 fr3_val; 603*287599cfSJerome Anand }; 604*287599cfSJerome Anand 605*287599cfSJerome Anand enum hdmi_connector_status { 606*287599cfSJerome Anand hdmi_connector_status_connected = 1, 607*287599cfSJerome Anand hdmi_connector_status_disconnected = 2, 608*287599cfSJerome Anand hdmi_connector_status_unknown = 3, 609*287599cfSJerome Anand }; 610*287599cfSJerome Anand 611*287599cfSJerome Anand #define HDMI_AUDIO_UNDERRUN (1UL<<31) 612*287599cfSJerome Anand #define HDMI_AUDIO_BUFFER_DONE (1UL<<29) 613*287599cfSJerome Anand 614*287599cfSJerome Anand 615*287599cfSJerome Anand #define PORT_ENABLE (1 << 31) 616*287599cfSJerome Anand #define SDVO_AUDIO_ENABLE (1 << 6) 617*287599cfSJerome Anand 618*287599cfSJerome Anand enum had_caps_list { 619*287599cfSJerome Anand HAD_GET_ELD = 1, 620*287599cfSJerome Anand HAD_GET_DISPLAY_RATE, 621*287599cfSJerome Anand HAD_SET_ENABLE_AUDIO, 622*287599cfSJerome Anand HAD_SET_DISABLE_AUDIO, 623*287599cfSJerome Anand HAD_SET_ENABLE_AUDIO_INT, 624*287599cfSJerome Anand HAD_SET_DISABLE_AUDIO_INT, 625*287599cfSJerome Anand }; 626*287599cfSJerome Anand 627*287599cfSJerome Anand enum had_event_type { 628*287599cfSJerome Anand HAD_EVENT_HOT_PLUG = 1, 629*287599cfSJerome Anand HAD_EVENT_HOT_UNPLUG, 630*287599cfSJerome Anand HAD_EVENT_MODE_CHANGING, 631*287599cfSJerome Anand HAD_EVENT_AUDIO_BUFFER_DONE, 632*287599cfSJerome Anand HAD_EVENT_AUDIO_BUFFER_UNDERRUN, 633*287599cfSJerome Anand HAD_EVENT_QUERY_IS_AUDIO_BUSY, 634*287599cfSJerome Anand HAD_EVENT_QUERY_IS_AUDIO_SUSPENDED, 635*287599cfSJerome Anand }; 636*287599cfSJerome Anand 637*287599cfSJerome Anand /* 638*287599cfSJerome Anand * HDMI Display Controller Audio Interface 639*287599cfSJerome Anand * 640*287599cfSJerome Anand */ 641*287599cfSJerome Anand typedef int (*had_event_call_back) (enum had_event_type event_type, 642*287599cfSJerome Anand void *ctxt_info); 643*287599cfSJerome Anand 644*287599cfSJerome Anand struct hdmi_audio_registers_ops { 645*287599cfSJerome Anand int (*hdmi_audio_get_register_base)(u32 **reg_base, 646*287599cfSJerome Anand u32 *config_offset); 647*287599cfSJerome Anand int (*hdmi_audio_read_register)(u32 reg_addr, u32 *data); 648*287599cfSJerome Anand int (*hdmi_audio_write_register)(u32 reg_addr, u32 data); 649*287599cfSJerome Anand int (*hdmi_audio_read_modify)(u32 reg_addr, u32 data, 650*287599cfSJerome Anand u32 mask); 651*287599cfSJerome Anand }; 652*287599cfSJerome Anand 653*287599cfSJerome Anand struct hdmi_audio_query_set_ops { 654*287599cfSJerome Anand int (*hdmi_audio_get_caps)(enum had_caps_list query_element, 655*287599cfSJerome Anand void *capabilties); 656*287599cfSJerome Anand int (*hdmi_audio_set_caps)(enum had_caps_list set_element, 657*287599cfSJerome Anand void *capabilties); 658*287599cfSJerome Anand }; 659*287599cfSJerome Anand 660*287599cfSJerome Anand struct hdmi_audio_event { 661*287599cfSJerome Anand int type; 662*287599cfSJerome Anand }; 663*287599cfSJerome Anand 664*287599cfSJerome Anand struct snd_intel_had_interface { 665*287599cfSJerome Anand const char *name; 666*287599cfSJerome Anand int (*query)(void *had_data, struct hdmi_audio_event event); 667*287599cfSJerome Anand int (*suspend)(void *had_data, struct hdmi_audio_event event); 668*287599cfSJerome Anand int (*resume)(void *had_data); 669*287599cfSJerome Anand }; 670*287599cfSJerome Anand 671*287599cfSJerome Anand bool mid_hdmi_audio_is_busy(void *dev); 672*287599cfSJerome Anand bool mid_hdmi_audio_suspend(void *dev); 673*287599cfSJerome Anand void mid_hdmi_audio_resume(void *dev); 674*287599cfSJerome Anand void mid_hdmi_audio_signal_event(enum had_event_type event); 675*287599cfSJerome Anand int mid_hdmi_audio_setup( 676*287599cfSJerome Anand had_event_call_back audio_callbacks, 677*287599cfSJerome Anand struct hdmi_audio_registers_ops *reg_ops, 678*287599cfSJerome Anand struct hdmi_audio_query_set_ops *query_ops); 679*287599cfSJerome Anand int mid_hdmi_audio_register( 680*287599cfSJerome Anand struct snd_intel_had_interface *driver, 681*287599cfSJerome Anand void *had_data); 682*287599cfSJerome Anand 683*287599cfSJerome Anand #endif 684