xref: /linux/sound/x86/intel_hdmi_lpe_audio.h (revision 287599cf2d7719c812774ff49db9ae8ca4fa844a)
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