xref: /linux/sound/x86/intel_hdmi_lpe_audio.h (revision 964ca8083c0239b5a729ed08c9f50b6c31ab3a93)
1287599cfSJerome Anand /*
2287599cfSJerome Anand  *   intel_hdmi_lpe_audio.h - Intel HDMI LPE audio driver
3287599cfSJerome Anand  *
4287599cfSJerome Anand  *  Copyright (C) 2016 Intel Corp
5287599cfSJerome Anand  *  Authors:	Sailaja Bandarupalli <sailaja.bandarupalli@intel.com>
6287599cfSJerome Anand  *		Ramesh Babu K V <ramesh.babu@intel.com>
7287599cfSJerome Anand  *		Vaibhav Agarwal <vaibhav.agarwal@intel.com>
8287599cfSJerome Anand  *		Jerome Anand <jerome.anand@intel.com>
9287599cfSJerome Anand  *		Aravind Siddappaji <aravindx.siddappaji@intel.com>
10287599cfSJerome Anand  *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
11287599cfSJerome Anand  *
12287599cfSJerome Anand  *  This program is free software; you can redistribute it and/or modify
13287599cfSJerome Anand  *  it under the terms of the GNU General Public License as published by
14287599cfSJerome Anand  *  the Free Software Foundation; version 2 of the License.
15287599cfSJerome Anand  *
16287599cfSJerome Anand  *  This program is distributed in the hope that it will be useful, but
17287599cfSJerome Anand  *  WITHOUT ANY WARRANTY; without even the implied warranty of
18287599cfSJerome Anand  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19287599cfSJerome Anand  *  General Public License for more details.
20287599cfSJerome Anand  *
21287599cfSJerome Anand  * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
22287599cfSJerome Anand  */
23287599cfSJerome Anand #ifndef __INTEL_HDMI_LPE_AUDIO_H
24287599cfSJerome Anand #define __INTEL_HDMI_LPE_AUDIO_H
25287599cfSJerome Anand 
26287599cfSJerome Anand #include <linux/types.h>
27287599cfSJerome Anand #include <sound/initval.h>
28287599cfSJerome Anand #include <linux/version.h>
29287599cfSJerome Anand #include <linux/pm_runtime.h>
30287599cfSJerome Anand #include <sound/asoundef.h>
31287599cfSJerome Anand #include <sound/control.h>
32287599cfSJerome Anand #include <sound/pcm.h>
33287599cfSJerome Anand 
34*964ca808SPierre-Louis Bossart #define AUD_CONFIG_VALID_BIT			(1<<9)
35*964ca808SPierre-Louis Bossart #define AUD_CONFIG_DP_MODE			(1<<15)
36*964ca808SPierre-Louis Bossart #define AUD_CONFIG_BLOCK_BIT			(1<<7)
37*964ca808SPierre-Louis Bossart 
38287599cfSJerome Anand #define HMDI_LPE_AUDIO_DRIVER_NAME		"intel-hdmi-lpe-audio"
39287599cfSJerome Anand #define HAD_MAX_DEVICES		1
40287599cfSJerome Anand #define HAD_MIN_CHANNEL		2
41287599cfSJerome Anand #define HAD_MAX_CHANNEL		8
42287599cfSJerome Anand #define HAD_NUM_OF_RING_BUFS	4
43287599cfSJerome Anand 
44287599cfSJerome Anand /* Assume 192KHz, 8channel, 25msec period */
45287599cfSJerome Anand #define HAD_MAX_BUFFER		(600*1024)
46287599cfSJerome Anand #define HAD_MIN_BUFFER		(32*1024)
47287599cfSJerome Anand #define HAD_MAX_PERIODS		4
48287599cfSJerome Anand #define HAD_MIN_PERIODS		4
49287599cfSJerome Anand #define HAD_MAX_PERIOD_BYTES	(HAD_MAX_BUFFER/HAD_MIN_PERIODS)
50287599cfSJerome Anand #define HAD_MIN_PERIOD_BYTES	256
51287599cfSJerome Anand #define HAD_FIFO_SIZE		0 /* fifo not being used */
52287599cfSJerome Anand #define MAX_SPEAKERS		8
53287599cfSJerome Anand 
54287599cfSJerome Anand #define AUD_SAMPLE_RATE_32	32000
55287599cfSJerome Anand #define AUD_SAMPLE_RATE_44_1	44100
56287599cfSJerome Anand #define AUD_SAMPLE_RATE_48	48000
57287599cfSJerome Anand #define AUD_SAMPLE_RATE_88_2	88200
58287599cfSJerome Anand #define AUD_SAMPLE_RATE_96	96000
59287599cfSJerome Anand #define AUD_SAMPLE_RATE_176_4	176400
60287599cfSJerome Anand #define AUD_SAMPLE_RATE_192	192000
61287599cfSJerome Anand 
62287599cfSJerome Anand #define HAD_MIN_RATE		AUD_SAMPLE_RATE_32
63287599cfSJerome Anand #define HAD_MAX_RATE		AUD_SAMPLE_RATE_192
64287599cfSJerome Anand 
65287599cfSJerome Anand #define DIS_SAMPLE_RATE_25_2	25200
66287599cfSJerome Anand #define DIS_SAMPLE_RATE_27	27000
67287599cfSJerome Anand #define DIS_SAMPLE_RATE_54	54000
68287599cfSJerome Anand #define DIS_SAMPLE_RATE_74_25	74250
69287599cfSJerome Anand #define DIS_SAMPLE_RATE_148_5	148500
70287599cfSJerome Anand #define HAD_REG_WIDTH		0x08
71287599cfSJerome Anand #define HAD_MAX_HW_BUFS		0x04
72287599cfSJerome Anand #define HAD_MAX_DIP_WORDS		16
73287599cfSJerome Anand #define INTEL_HAD		"IntelHdmiLpeAudio"
74287599cfSJerome Anand 
75*964ca808SPierre-Louis Bossart /* DP Link Rates */
76*964ca808SPierre-Louis Bossart #define DP_2_7_GHZ			270000
77*964ca808SPierre-Louis Bossart #define DP_1_62_GHZ			162000
78*964ca808SPierre-Louis Bossart 
79*964ca808SPierre-Louis Bossart /* Maud Values */
80*964ca808SPierre-Louis Bossart #define AUD_SAMPLE_RATE_32_DP_2_7_MAUD_VAL		1988
81*964ca808SPierre-Louis Bossart #define AUD_SAMPLE_RATE_44_1_DP_2_7_MAUD_VAL		2740
82*964ca808SPierre-Louis Bossart #define AUD_SAMPLE_RATE_48_DP_2_7_MAUD_VAL		2982
83*964ca808SPierre-Louis Bossart #define AUD_SAMPLE_RATE_88_2_DP_2_7_MAUD_VAL		5480
84*964ca808SPierre-Louis Bossart #define AUD_SAMPLE_RATE_96_DP_2_7_MAUD_VAL		5965
85*964ca808SPierre-Louis Bossart #define AUD_SAMPLE_RATE_176_4_DP_2_7_MAUD_VAL		10961
86*964ca808SPierre-Louis Bossart #define HAD_MAX_RATE_DP_2_7_MAUD_VAL			11930
87*964ca808SPierre-Louis Bossart #define AUD_SAMPLE_RATE_32_DP_1_62_MAUD_VAL		3314
88*964ca808SPierre-Louis Bossart #define AUD_SAMPLE_RATE_44_1_DP_1_62_MAUD_VAL		4567
89*964ca808SPierre-Louis Bossart #define AUD_SAMPLE_RATE_48_DP_1_62_MAUD_VAL		4971
90*964ca808SPierre-Louis Bossart #define AUD_SAMPLE_RATE_88_2_DP_1_62_MAUD_VAL		9134
91*964ca808SPierre-Louis Bossart #define AUD_SAMPLE_RATE_96_DP_1_62_MAUD_VAL		9942
92*964ca808SPierre-Louis Bossart #define AUD_SAMPLE_RATE_176_4_DP_1_62_MAUD_VAL		18268
93*964ca808SPierre-Louis Bossart #define HAD_MAX_RATE_DP_1_62_MAUD_VAL			19884
94*964ca808SPierre-Louis Bossart 
95*964ca808SPierre-Louis Bossart /* Naud Value */
96*964ca808SPierre-Louis Bossart #define DP_NAUD_VAL					32768
97*964ca808SPierre-Louis Bossart 
98287599cfSJerome Anand /* _AUD_CONFIG register MASK */
99287599cfSJerome Anand #define AUD_CONFIG_MASK_UNDERRUN	0xC0000000
100287599cfSJerome Anand #define AUD_CONFIG_MASK_SRDBG		0x00000002
101287599cfSJerome Anand #define AUD_CONFIG_MASK_FUNCRST		0x00000001
102287599cfSJerome Anand 
103287599cfSJerome Anand #define MAX_CNT			0xFF
104287599cfSJerome Anand #define HAD_SUSPEND_DELAY	1000
105287599cfSJerome Anand 
106287599cfSJerome Anand #define OTM_HDMI_ELD_SIZE 128
107287599cfSJerome Anand 
108287599cfSJerome Anand union otm_hdmi_eld_t {
109287599cfSJerome Anand 	unsigned char eld_data[OTM_HDMI_ELD_SIZE];
110287599cfSJerome Anand 	struct {
111287599cfSJerome Anand 		/* Byte[0] = ELD Version Number */
112287599cfSJerome Anand 		union {
113287599cfSJerome Anand 			unsigned char   byte0;
114287599cfSJerome Anand 			struct {
115287599cfSJerome Anand 				unsigned char reserved:3; /* Reserf */
116287599cfSJerome Anand 				unsigned char eld_ver:5; /* ELD Version Number */
117287599cfSJerome Anand 				/* 00000b - reserved
118287599cfSJerome Anand 				 * 00001b - first rev, obsoleted
119287599cfSJerome Anand 				 * 00010b - version 2, supporting CEA version
120287599cfSJerome Anand 				 *			861D or below
121287599cfSJerome Anand 				 * 00011b:11111b - reserved
122287599cfSJerome Anand 				 * for future
123287599cfSJerome Anand 				 */
124287599cfSJerome Anand 			};
125287599cfSJerome Anand 		};
126287599cfSJerome Anand 
127287599cfSJerome Anand 		/* Byte[1] = Vendor Version Field */
128287599cfSJerome Anand 		union {
129287599cfSJerome Anand 			unsigned char vendor_version;
130287599cfSJerome Anand 			struct {
131287599cfSJerome Anand 				unsigned char reserved1:3;
132287599cfSJerome Anand 				unsigned char veld_ver:5; /* Version number of the ELD
133287599cfSJerome Anand 						     * extension. This value is
134287599cfSJerome Anand 						     * provisioned and unique to
135287599cfSJerome Anand 						     * each vendor.
136287599cfSJerome Anand 						     */
137287599cfSJerome Anand 			};
138287599cfSJerome Anand 		};
139287599cfSJerome Anand 
140287599cfSJerome Anand 		/* Byte[2] = Baseline Length field */
141287599cfSJerome Anand 		unsigned char baseline_eld_length; /* Length of the Baseline structure
142287599cfSJerome Anand 					      *	divided by Four.
143287599cfSJerome Anand 					      */
144287599cfSJerome Anand 
145287599cfSJerome Anand 		/* Byte [3] = Reserved for future use */
146287599cfSJerome Anand 		unsigned char byte3;
147287599cfSJerome Anand 
148287599cfSJerome Anand 		/* Starting of the BaseLine EELD structure
149287599cfSJerome Anand 		 * Byte[4] = Monitor Name Length
150287599cfSJerome Anand 		 */
151287599cfSJerome Anand 		union {
152287599cfSJerome Anand 			unsigned char byte4;
153287599cfSJerome Anand 			struct {
154287599cfSJerome Anand 				unsigned char mnl:5;
155287599cfSJerome Anand 				unsigned char cea_edid_rev_id:3;
156287599cfSJerome Anand 			};
157287599cfSJerome Anand 		};
158287599cfSJerome Anand 
159287599cfSJerome Anand 		/* Byte[5] = Capabilities */
160287599cfSJerome Anand 		union {
161287599cfSJerome Anand 			unsigned char capabilities;
162287599cfSJerome Anand 			struct {
163287599cfSJerome Anand 				unsigned char hdcp:1; /* HDCP support */
164287599cfSJerome Anand 				unsigned char ai_support:1;   /* AI support */
165287599cfSJerome Anand 				unsigned char connection_type:2; /* Connection type
166287599cfSJerome Anand 							    * 00 - HDMI
167287599cfSJerome Anand 							    * 01 - DP
168287599cfSJerome Anand 							    * 10 -11  Reserved
169287599cfSJerome Anand 							    * for future
170287599cfSJerome Anand 							    * connection types
171287599cfSJerome Anand 							    */
172287599cfSJerome Anand 				unsigned char sadc:4; /* Indicates number of 3 bytes
173287599cfSJerome Anand 						 * Short Audio Descriptors.
174287599cfSJerome Anand 						 */
175287599cfSJerome Anand 			};
176287599cfSJerome Anand 		};
177287599cfSJerome Anand 
178287599cfSJerome Anand 		/* Byte[6] = Audio Synch Delay */
179287599cfSJerome Anand 		unsigned char audio_synch_delay; /* Amount of time reported by the
180287599cfSJerome Anand 					    * sink that the video trails audio
181287599cfSJerome Anand 					    * in milliseconds.
182287599cfSJerome Anand 					    */
183287599cfSJerome Anand 
184287599cfSJerome Anand 		/* Byte[7] = Speaker Allocation Block */
185287599cfSJerome Anand 		union {
186287599cfSJerome Anand 			unsigned char speaker_allocation_block;
187287599cfSJerome Anand 			struct {
188287599cfSJerome Anand 				unsigned char flr:1; /*Front Left and Right channels*/
189287599cfSJerome Anand 				unsigned char lfe:1; /*Low Frequency Effect channel*/
190287599cfSJerome Anand 				unsigned char fc:1;  /*Center transmission channel*/
191287599cfSJerome Anand 				unsigned char rlr:1; /*Rear Left and Right channels*/
192287599cfSJerome Anand 				unsigned char rc:1; /*Rear Center channel*/
193287599cfSJerome Anand 				unsigned char flrc:1; /*Front left and Right of Center
194287599cfSJerome Anand 						 *transmission channels
195287599cfSJerome Anand 						 */
196287599cfSJerome Anand 				unsigned char rlrc:1; /*Rear left and Right of Center
197287599cfSJerome Anand 						 *transmission channels
198287599cfSJerome Anand 						 */
199287599cfSJerome Anand 				unsigned char reserved3:1; /* Reserved */
200287599cfSJerome Anand 			};
201287599cfSJerome Anand 		};
202287599cfSJerome Anand 
203287599cfSJerome Anand 		/* Byte[8 - 15] - 8 Byte port identification value */
204287599cfSJerome Anand 		unsigned char port_id_value[8];
205287599cfSJerome Anand 
206287599cfSJerome Anand 		/* Byte[16 - 17] - 2 Byte Manufacturer ID */
207287599cfSJerome Anand 		unsigned char manufacturer_id[2];
208287599cfSJerome Anand 
209287599cfSJerome Anand 		/* Byte[18 - 19] - 2 Byte Product ID */
210287599cfSJerome Anand 		unsigned char product_id[2];
211287599cfSJerome Anand 
212287599cfSJerome Anand 		/* Byte [20-83] - 64 Bytes of BaseLine Data */
213287599cfSJerome Anand 		unsigned char mn_sand_sads[64]; /* This will include
214287599cfSJerome Anand 					   * - ASCII string of Monitor name
215287599cfSJerome Anand 					   * - List of 3 byte SADs
216287599cfSJerome Anand 					   * - Zero padding
217287599cfSJerome Anand 					   */
218287599cfSJerome Anand 
219287599cfSJerome Anand 		/* Vendor ELD Block should continue here!
220287599cfSJerome Anand 		 * No Vendor ELD block defined as of now.
221287599cfSJerome Anand 		 */
222287599cfSJerome Anand 	} __packed;
223287599cfSJerome Anand };
224287599cfSJerome Anand 
225287599cfSJerome Anand /**
226287599cfSJerome Anand  * enum had_status - Audio stream states
227287599cfSJerome Anand  *
228287599cfSJerome Anand  * @STREAM_INIT: Stream initialized
229287599cfSJerome Anand  * @STREAM_RUNNING: Stream running
230287599cfSJerome Anand  * @STREAM_PAUSED: Stream paused
231287599cfSJerome Anand  * @STREAM_DROPPED: Stream dropped
232287599cfSJerome Anand  */
233287599cfSJerome Anand enum had_stream_status {
234287599cfSJerome Anand 	STREAM_INIT = 0,
235287599cfSJerome Anand 	STREAM_RUNNING = 1,
236287599cfSJerome Anand 	STREAM_PAUSED = 2,
237287599cfSJerome Anand 	STREAM_DROPPED = 3
238287599cfSJerome Anand };
239287599cfSJerome Anand 
240287599cfSJerome Anand /**
241287599cfSJerome Anand  * enum had_status_stream - HAD stream states
242287599cfSJerome Anand  */
243287599cfSJerome Anand enum had_status_stream {
244287599cfSJerome Anand 	HAD_INIT = 0,
245287599cfSJerome Anand 	HAD_RUNNING_STREAM,
246287599cfSJerome Anand };
247287599cfSJerome Anand 
248287599cfSJerome Anand enum had_drv_status {
249287599cfSJerome Anand 	HAD_DRV_CONNECTED,
250287599cfSJerome Anand 	HAD_DRV_RUNNING,
251287599cfSJerome Anand 	HAD_DRV_DISCONNECTED,
252287599cfSJerome Anand 	HAD_DRV_SUSPENDED,
253287599cfSJerome Anand 	HAD_DRV_ERR,
254287599cfSJerome Anand };
255287599cfSJerome Anand 
256287599cfSJerome Anand /* enum intel_had_aud_buf_type - HDMI controller ring buffer types */
257287599cfSJerome Anand enum intel_had_aud_buf_type {
258287599cfSJerome Anand 	HAD_BUF_TYPE_A = 0,
259287599cfSJerome Anand 	HAD_BUF_TYPE_B = 1,
260287599cfSJerome Anand 	HAD_BUF_TYPE_C = 2,
261287599cfSJerome Anand 	HAD_BUF_TYPE_D = 3,
262287599cfSJerome Anand };
263287599cfSJerome Anand 
264287599cfSJerome Anand enum num_aud_ch {
265287599cfSJerome Anand 	CH_STEREO = 0,
266287599cfSJerome Anand 	CH_THREE_FOUR = 1,
267287599cfSJerome Anand 	CH_FIVE_SIX = 2,
268287599cfSJerome Anand 	CH_SEVEN_EIGHT = 3
269287599cfSJerome Anand };
270287599cfSJerome Anand 
271287599cfSJerome Anand /* HDMI Controller register offsets - audio domain common */
272287599cfSJerome Anand /* Base address for below regs = 0x65000 */
273287599cfSJerome Anand enum hdmi_ctrl_reg_offset_common {
274287599cfSJerome Anand 	AUDIO_HDMI_CONFIG_A	= 0x000,
275287599cfSJerome Anand 	AUDIO_HDMI_CONFIG_B = 0x800,
276287599cfSJerome Anand 	AUDIO_HDMI_CONFIG_C = 0x900,
277287599cfSJerome Anand };
278287599cfSJerome Anand /* HDMI controller register offsets */
279287599cfSJerome Anand enum hdmi_ctrl_reg_offset_v1 {
280287599cfSJerome Anand 	AUD_CONFIG		= 0x0,
281287599cfSJerome Anand 	AUD_CH_STATUS_0		= 0x08,
282287599cfSJerome Anand 	AUD_CH_STATUS_1		= 0x0C,
283287599cfSJerome Anand 	AUD_HDMI_CTS		= 0x10,
284287599cfSJerome Anand 	AUD_N_ENABLE		= 0x14,
285287599cfSJerome Anand 	AUD_SAMPLE_RATE		= 0x18,
286287599cfSJerome Anand 	AUD_BUF_CONFIG		= 0x20,
287287599cfSJerome Anand 	AUD_BUF_CH_SWAP		= 0x24,
288287599cfSJerome Anand 	AUD_BUF_A_ADDR		= 0x40,
289287599cfSJerome Anand 	AUD_BUF_A_LENGTH	= 0x44,
290287599cfSJerome Anand 	AUD_BUF_B_ADDR		= 0x48,
291287599cfSJerome Anand 	AUD_BUF_B_LENGTH	= 0x4c,
292287599cfSJerome Anand 	AUD_BUF_C_ADDR		= 0x50,
293287599cfSJerome Anand 	AUD_BUF_C_LENGTH	= 0x54,
294287599cfSJerome Anand 	AUD_BUF_D_ADDR		= 0x58,
295287599cfSJerome Anand 	AUD_BUF_D_LENGTH	= 0x5c,
296287599cfSJerome Anand 	AUD_CNTL_ST		= 0x60,
297287599cfSJerome Anand 	AUD_HDMI_STATUS		= 0x68,
298287599cfSJerome Anand 	AUD_HDMIW_INFOFR	= 0x114,
299287599cfSJerome Anand };
300287599cfSJerome Anand 
301287599cfSJerome Anand /*
302287599cfSJerome Anand  * Delta changes in HDMI controller register offsets
303287599cfSJerome Anand  * compare to v1 version
304287599cfSJerome Anand  */
305287599cfSJerome Anand 
306287599cfSJerome Anand enum hdmi_ctrl_reg_offset_v2 {
307287599cfSJerome Anand 	AUD_HDMI_STATUS_v2	= 0x64,
308287599cfSJerome Anand 	AUD_HDMIW_INFOFR_v2	= 0x68,
309287599cfSJerome Anand };
310287599cfSJerome Anand 
311287599cfSJerome Anand /*
312287599cfSJerome Anand  *	CEA speaker placement:
313287599cfSJerome Anand  *
314287599cfSJerome Anand  *	FL  FLC   FC   FRC   FR
315287599cfSJerome Anand  *
316287599cfSJerome Anand  *						LFE
317287599cfSJerome Anand  *
318287599cfSJerome Anand  *	RL  RLC   RC   RRC   RR
319287599cfSJerome Anand  *
320287599cfSJerome Anand  *	The Left/Right Surround channel _notions_ LS/RS in SMPTE 320M
321287599cfSJerome Anand  *	corresponds to CEA RL/RR; The SMPTE channel _assignment_ C/LFE is
322287599cfSJerome Anand  *	swapped to CEA LFE/FC.
323287599cfSJerome Anand  */
324287599cfSJerome Anand enum cea_speaker_placement {
325287599cfSJerome Anand 	FL  = (1 <<  0),        /* Front Left           */
326287599cfSJerome Anand 	FC  = (1 <<  1),        /* Front Center         */
327287599cfSJerome Anand 	FR  = (1 <<  2),        /* Front Right          */
328287599cfSJerome Anand 	FLC = (1 <<  3),        /* Front Left Center    */
329287599cfSJerome Anand 	FRC = (1 <<  4),        /* Front Right Center   */
330287599cfSJerome Anand 	RL  = (1 <<  5),        /* Rear Left            */
331287599cfSJerome Anand 	RC  = (1 <<  6),        /* Rear Center          */
332287599cfSJerome Anand 	RR  = (1 <<  7),        /* Rear Right           */
333287599cfSJerome Anand 	RLC = (1 <<  8),        /* Rear Left Center     */
334287599cfSJerome Anand 	RRC = (1 <<  9),        /* Rear Right Center    */
335287599cfSJerome Anand 	LFE = (1 << 10),        /* Low Frequency Effect */
336287599cfSJerome Anand };
337287599cfSJerome Anand 
338287599cfSJerome Anand struct cea_channel_speaker_allocation {
339287599cfSJerome Anand 	int ca_index;
340287599cfSJerome Anand 	int speakers[8];
341287599cfSJerome Anand 
342287599cfSJerome Anand 	/* derived values, just for convenience */
343287599cfSJerome Anand 	int channels;
344287599cfSJerome Anand 	int spk_mask;
345287599cfSJerome Anand };
346287599cfSJerome Anand 
347287599cfSJerome Anand struct channel_map_table {
348287599cfSJerome Anand 	unsigned char map;              /* ALSA API channel map position */
349287599cfSJerome Anand 	unsigned char cea_slot;         /* CEA slot value */
350287599cfSJerome Anand 	int spk_mask;                   /* speaker position bit mask */
351287599cfSJerome Anand };
352287599cfSJerome Anand 
353287599cfSJerome Anand /**
354287599cfSJerome Anand  * union aud_cfg - Audio configuration
355287599cfSJerome Anand  *
356287599cfSJerome Anand  * @cfg_regx: individual register bits
357287599cfSJerome Anand  * @cfg_regval: full register value
358287599cfSJerome Anand  *
359287599cfSJerome Anand  */
360287599cfSJerome Anand union aud_cfg {
361287599cfSJerome Anand 	struct {
362287599cfSJerome Anand 		u32 aud_en:1;
363287599cfSJerome Anand 		u32 layout:1;
364287599cfSJerome Anand 		u32 fmt:2;
365287599cfSJerome Anand 		u32 num_ch:2;
366287599cfSJerome Anand 		u32 rsvd0:1;
367287599cfSJerome Anand 		u32 set:1;
368287599cfSJerome Anand 		u32 flat:1;
369287599cfSJerome Anand 		u32 val_bit:1;
370287599cfSJerome Anand 		u32 user_bit:1;
371287599cfSJerome Anand 		u32 underrun:1;
372287599cfSJerome Anand 		u32 rsvd1:20;
373287599cfSJerome Anand 	} cfg_regx;
374287599cfSJerome Anand 	struct {
375287599cfSJerome Anand 		u32 aud_en:1;
376287599cfSJerome Anand 		u32 layout:1;
377287599cfSJerome Anand 		u32 fmt:2;
378287599cfSJerome Anand 		u32 num_ch:3;
379287599cfSJerome Anand 		u32 set:1;
380287599cfSJerome Anand 		u32 flat:1;
381287599cfSJerome Anand 		u32 val_bit:1;
382287599cfSJerome Anand 		u32 user_bit:1;
383287599cfSJerome Anand 		u32 underrun:1;
384287599cfSJerome Anand 		u32 packet_mode:1;
385287599cfSJerome Anand 		u32 left_align:1;
386287599cfSJerome Anand 		u32 bogus_sample:1;
387287599cfSJerome Anand 		u32 dp_modei:1;
388287599cfSJerome Anand 		u32 rsvd:16;
389287599cfSJerome Anand 	} cfg_regx_v2;
390287599cfSJerome Anand 	u32 cfg_regval;
391287599cfSJerome Anand };
392287599cfSJerome Anand 
393287599cfSJerome Anand /**
394287599cfSJerome Anand  * union aud_ch_status_0 - Audio Channel Status 0 Attributes
395287599cfSJerome Anand  *
396287599cfSJerome Anand  * @status_0_regx:individual register bits
397287599cfSJerome Anand  * @status_0_regval:full register value
398287599cfSJerome Anand  *
399287599cfSJerome Anand  */
400287599cfSJerome Anand union aud_ch_status_0 {
401287599cfSJerome Anand 	struct {
402287599cfSJerome Anand 		u32 ch_status:1;
403287599cfSJerome Anand 		u32 lpcm_id:1;
404287599cfSJerome Anand 		u32 cp_info:1;
405287599cfSJerome Anand 		u32 format:3;
406287599cfSJerome Anand 		u32 mode:2;
407287599cfSJerome Anand 		u32 ctg_code:8;
408287599cfSJerome Anand 		u32 src_num:4;
409287599cfSJerome Anand 		u32 ch_num:4;
410287599cfSJerome Anand 		u32 samp_freq:4;
411287599cfSJerome Anand 		u32 clk_acc:2;
412287599cfSJerome Anand 		u32 rsvd:2;
413287599cfSJerome Anand 	} status_0_regx;
414287599cfSJerome Anand 	u32 status_0_regval;
415287599cfSJerome Anand };
416287599cfSJerome Anand 
417287599cfSJerome Anand /**
418287599cfSJerome Anand  * union aud_ch_status_1 - Audio Channel Status 1 Attributes
419287599cfSJerome Anand  *
420287599cfSJerome Anand  * @status_1_regx: individual register bits
421287599cfSJerome Anand  * @status_1_regval: full register value
422287599cfSJerome Anand  *
423287599cfSJerome Anand  */
424287599cfSJerome Anand union aud_ch_status_1 {
425287599cfSJerome Anand 	struct {
426287599cfSJerome Anand 		u32 max_wrd_len:1;
427287599cfSJerome Anand 		u32 wrd_len:3;
428287599cfSJerome Anand 		u32 rsvd:28;
429287599cfSJerome Anand 		} status_1_regx;
430287599cfSJerome Anand 	u32 status_1_regval;
431287599cfSJerome Anand };
432287599cfSJerome Anand 
433287599cfSJerome Anand /**
434287599cfSJerome Anand  * union aud_hdmi_cts - CTS register
435287599cfSJerome Anand  *
436287599cfSJerome Anand  * @cts_regx: individual register bits
437287599cfSJerome Anand  * @cts_regval: full register value
438287599cfSJerome Anand  *
439287599cfSJerome Anand  */
440287599cfSJerome Anand union aud_hdmi_cts {
441287599cfSJerome Anand 	struct {
442287599cfSJerome Anand 		u32 cts_val:20;
443287599cfSJerome Anand 		u32 en_cts_prog:1;
444287599cfSJerome Anand 		u32 rsvd:11;
445287599cfSJerome Anand 	} cts_regx;
446287599cfSJerome Anand 	struct {
447287599cfSJerome Anand 		u32 cts_val:24;
448287599cfSJerome Anand 		u32 en_cts_prog:1;
449287599cfSJerome Anand 		u32 rsvd:7;
450287599cfSJerome Anand 	} cts_regx_v2;
451287599cfSJerome Anand 	u32 cts_regval;
452287599cfSJerome Anand };
453287599cfSJerome Anand 
454287599cfSJerome Anand /**
455287599cfSJerome Anand  * union aud_hdmi_n_enable - N register
456287599cfSJerome Anand  *
457287599cfSJerome Anand  * @n_regx: individual register bits
458287599cfSJerome Anand  * @n_regval: full register value
459287599cfSJerome Anand  *
460287599cfSJerome Anand  */
461287599cfSJerome Anand union aud_hdmi_n_enable {
462287599cfSJerome Anand 	struct {
463287599cfSJerome Anand 		u32 n_val:20;
464287599cfSJerome Anand 		u32 en_n_prog:1;
465287599cfSJerome Anand 		u32 rsvd:11;
466287599cfSJerome Anand 	} n_regx;
467287599cfSJerome Anand 	struct {
468287599cfSJerome Anand 		u32 n_val:24;
469287599cfSJerome Anand 		u32 en_n_prog:1;
470287599cfSJerome Anand 		u32 rsvd:7;
471287599cfSJerome Anand 	} n_regx_v2;
472287599cfSJerome Anand 	u32 n_regval;
473287599cfSJerome Anand };
474287599cfSJerome Anand 
475287599cfSJerome Anand /**
476287599cfSJerome Anand  * union aud_buf_config -  Audio Buffer configurations
477287599cfSJerome Anand  *
478287599cfSJerome Anand  * @buf_cfg_regx: individual register bits
479287599cfSJerome Anand  * @buf_cfgval: full register value
480287599cfSJerome Anand  *
481287599cfSJerome Anand  */
482287599cfSJerome Anand union aud_buf_config {
483287599cfSJerome Anand 	struct {
484287599cfSJerome Anand 		u32 fifo_width:8;
485287599cfSJerome Anand 		u32 rsvd0:8;
486287599cfSJerome Anand 		u32 aud_delay:8;
487287599cfSJerome Anand 		u32 rsvd1:8;
488287599cfSJerome Anand 	} buf_cfg_regx;
489287599cfSJerome Anand 	struct {
490287599cfSJerome Anand 		u32 audio_fifo_watermark:8;
491287599cfSJerome Anand 		u32 dma_fifo_watermark:3;
492287599cfSJerome Anand 		u32 rsvd0:5;
493287599cfSJerome Anand 		u32 aud_delay:8;
494287599cfSJerome Anand 		u32 rsvd1:8;
495287599cfSJerome Anand 	} buf_cfg_regx_v2;
496287599cfSJerome Anand 	u32 buf_cfgval;
497287599cfSJerome Anand };
498287599cfSJerome Anand 
499287599cfSJerome Anand /**
500287599cfSJerome Anand  * union aud_buf_ch_swap - Audio Sample Swapping offset
501287599cfSJerome Anand  *
502287599cfSJerome Anand  * @buf_ch_swap_regx: individual register bits
503287599cfSJerome Anand  * @buf_ch_swap_val: full register value
504287599cfSJerome Anand  *
505287599cfSJerome Anand  */
506287599cfSJerome Anand union aud_buf_ch_swap {
507287599cfSJerome Anand 	struct {
508287599cfSJerome Anand 		u32 first_0:3;
509287599cfSJerome Anand 		u32 second_0:3;
510287599cfSJerome Anand 		u32 first_1:3;
511287599cfSJerome Anand 		u32 second_1:3;
512287599cfSJerome Anand 		u32 first_2:3;
513287599cfSJerome Anand 		u32 second_2:3;
514287599cfSJerome Anand 		u32 first_3:3;
515287599cfSJerome Anand 		u32 second_3:3;
516287599cfSJerome Anand 		u32 rsvd:8;
517287599cfSJerome Anand 	} buf_ch_swap_regx;
518287599cfSJerome Anand 	u32 buf_ch_swap_val;
519287599cfSJerome Anand };
520287599cfSJerome Anand 
521287599cfSJerome Anand /**
522287599cfSJerome Anand  * union aud_buf_addr - Address for Audio Buffer
523287599cfSJerome Anand  *
524287599cfSJerome Anand  * @buf_addr_regx: individual register bits
525287599cfSJerome Anand  * @buf_addr_val: full register value
526287599cfSJerome Anand  *
527287599cfSJerome Anand  */
528287599cfSJerome Anand union aud_buf_addr {
529287599cfSJerome Anand 	struct {
530287599cfSJerome Anand 		u32 valid:1;
531287599cfSJerome Anand 		u32 intr_en:1;
532287599cfSJerome Anand 		u32 rsvd:4;
533287599cfSJerome Anand 		u32 addr:26;
534287599cfSJerome Anand 	} buf_addr_regx;
535287599cfSJerome Anand 	u32 buf_addr_val;
536287599cfSJerome Anand };
537287599cfSJerome Anand 
538287599cfSJerome Anand /**
539287599cfSJerome Anand  * union aud_buf_len - Length of Audio Buffer
540287599cfSJerome Anand  *
541287599cfSJerome Anand  * @buf_len_regx: individual register bits
542287599cfSJerome Anand  * @buf_len_val: full register value
543287599cfSJerome Anand  *
544287599cfSJerome Anand  */
545287599cfSJerome Anand union aud_buf_len {
546287599cfSJerome Anand 	struct {
547287599cfSJerome Anand 		u32 buf_len:20;
548287599cfSJerome Anand 		u32 rsvd:12;
549287599cfSJerome Anand 	} buf_len_regx;
550287599cfSJerome Anand 	u32 buf_len_val;
551287599cfSJerome Anand };
552287599cfSJerome Anand 
553287599cfSJerome Anand /**
554287599cfSJerome Anand  * union aud_ctrl_st - Audio Control State Register offset
555287599cfSJerome Anand  *
556287599cfSJerome Anand  * @ctrl_regx: individual register bits
557287599cfSJerome Anand  * @ctrl_val: full register value
558287599cfSJerome Anand  *
559287599cfSJerome Anand  */
560287599cfSJerome Anand union aud_ctrl_st {
561287599cfSJerome Anand 	struct {
562287599cfSJerome Anand 		u32 ram_addr:4;
563287599cfSJerome Anand 		u32 eld_ack:1;
564287599cfSJerome Anand 		u32 eld_addr:4;
565287599cfSJerome Anand 		u32 eld_buf_size:5;
566287599cfSJerome Anand 		u32 eld_valid:1;
567287599cfSJerome Anand 		u32 cp_ready:1;
568287599cfSJerome Anand 		u32 dip_freq:2;
569287599cfSJerome Anand 		u32 dip_idx:3;
570287599cfSJerome Anand 		u32 dip_en_sta:4;
571287599cfSJerome Anand 		u32 rsvd:7;
572287599cfSJerome Anand 	} ctrl_regx;
573287599cfSJerome Anand 	u32 ctrl_val;
574287599cfSJerome Anand };
575287599cfSJerome Anand 
576287599cfSJerome Anand /**
577287599cfSJerome Anand  * union aud_info_frame1 - Audio HDMI Widget Data Island Packet offset
578287599cfSJerome Anand  *
579287599cfSJerome Anand  * @fr1_regx: individual register bits
580287599cfSJerome Anand  * @fr1_val: full register value
581287599cfSJerome Anand  *
582287599cfSJerome Anand  */
583287599cfSJerome Anand union aud_info_frame1 {
584287599cfSJerome Anand 	struct {
585287599cfSJerome Anand 		u32 pkt_type:8;
586287599cfSJerome Anand 		u32 ver_num:8;
587287599cfSJerome Anand 		u32 len:5;
588287599cfSJerome Anand 		u32 rsvd:11;
589287599cfSJerome Anand 	} fr1_regx;
590287599cfSJerome Anand 	u32 fr1_val;
591287599cfSJerome Anand };
592287599cfSJerome Anand 
593287599cfSJerome Anand /**
594287599cfSJerome Anand  * union aud_info_frame2 - DIP frame 2
595287599cfSJerome Anand  *
596287599cfSJerome Anand  * @fr2_regx: individual register bits
597287599cfSJerome Anand  * @fr2_val: full register value
598287599cfSJerome Anand  *
599287599cfSJerome Anand  */
600287599cfSJerome Anand union aud_info_frame2 {
601287599cfSJerome Anand 	struct {
602287599cfSJerome Anand 		u32 chksum:8;
603287599cfSJerome Anand 		u32 chnl_cnt:3;
604287599cfSJerome Anand 		u32 rsvd0:1;
605287599cfSJerome Anand 		u32 coding_type:4;
606287599cfSJerome Anand 		u32 smpl_size:2;
607287599cfSJerome Anand 		u32 smpl_freq:3;
608287599cfSJerome Anand 		u32 rsvd1:3;
609287599cfSJerome Anand 		u32 format:8;
610287599cfSJerome Anand 	} fr2_regx;
611287599cfSJerome Anand 	u32 fr2_val;
612287599cfSJerome Anand };
613287599cfSJerome Anand 
614287599cfSJerome Anand /**
615287599cfSJerome Anand  * union aud_info_frame3 - DIP frame 3
616287599cfSJerome Anand  *
617287599cfSJerome Anand  * @fr3_regx: individual register bits
618287599cfSJerome Anand  * @fr3_val: full register value
619287599cfSJerome Anand  *
620287599cfSJerome Anand  */
621287599cfSJerome Anand union aud_info_frame3 {
622287599cfSJerome Anand 	struct {
623287599cfSJerome Anand 		u32 chnl_alloc:8;
624287599cfSJerome Anand 		u32 rsvd0:3;
625287599cfSJerome Anand 		u32 lsv:4;
626287599cfSJerome Anand 		u32 dm_inh:1;
627287599cfSJerome Anand 		u32 rsvd1:16;
628287599cfSJerome Anand 	} fr3_regx;
629287599cfSJerome Anand 	u32 fr3_val;
630287599cfSJerome Anand };
631287599cfSJerome Anand 
632287599cfSJerome Anand enum hdmi_connector_status {
633287599cfSJerome Anand 	hdmi_connector_status_connected = 1,
634287599cfSJerome Anand 	hdmi_connector_status_disconnected = 2,
635287599cfSJerome Anand 	hdmi_connector_status_unknown = 3,
636287599cfSJerome Anand };
637287599cfSJerome Anand 
638287599cfSJerome Anand #define HDMI_AUDIO_UNDERRUN     (1UL<<31)
639287599cfSJerome Anand #define HDMI_AUDIO_BUFFER_DONE  (1UL<<29)
640287599cfSJerome Anand 
641287599cfSJerome Anand 
642287599cfSJerome Anand #define PORT_ENABLE			(1 << 31)
643287599cfSJerome Anand #define SDVO_AUDIO_ENABLE	(1 << 6)
644287599cfSJerome Anand 
645287599cfSJerome Anand enum had_caps_list {
646287599cfSJerome Anand 	HAD_GET_ELD = 1,
647287599cfSJerome Anand 	HAD_GET_DISPLAY_RATE,
648*964ca808SPierre-Louis Bossart 	HAD_GET_DP_OUTPUT,
649*964ca808SPierre-Louis Bossart 	HAD_GET_LINK_RATE,
650287599cfSJerome Anand 	HAD_SET_ENABLE_AUDIO,
651287599cfSJerome Anand 	HAD_SET_DISABLE_AUDIO,
652287599cfSJerome Anand 	HAD_SET_ENABLE_AUDIO_INT,
653287599cfSJerome Anand 	HAD_SET_DISABLE_AUDIO_INT,
654287599cfSJerome Anand };
655287599cfSJerome Anand 
656287599cfSJerome Anand enum had_event_type {
657287599cfSJerome Anand 	HAD_EVENT_HOT_PLUG = 1,
658287599cfSJerome Anand 	HAD_EVENT_HOT_UNPLUG,
659287599cfSJerome Anand 	HAD_EVENT_MODE_CHANGING,
660287599cfSJerome Anand 	HAD_EVENT_AUDIO_BUFFER_DONE,
661287599cfSJerome Anand 	HAD_EVENT_AUDIO_BUFFER_UNDERRUN,
662287599cfSJerome Anand 	HAD_EVENT_QUERY_IS_AUDIO_BUSY,
663287599cfSJerome Anand 	HAD_EVENT_QUERY_IS_AUDIO_SUSPENDED,
664287599cfSJerome Anand };
665287599cfSJerome Anand 
666287599cfSJerome Anand /*
667287599cfSJerome Anand  * HDMI Display Controller Audio Interface
668287599cfSJerome Anand  *
669287599cfSJerome Anand  */
670287599cfSJerome Anand typedef int (*had_event_call_back) (enum had_event_type event_type,
671287599cfSJerome Anand 		void *ctxt_info);
672287599cfSJerome Anand 
673287599cfSJerome Anand struct hdmi_audio_registers_ops {
674287599cfSJerome Anand 	int (*hdmi_audio_get_register_base)(u32 **reg_base,
675287599cfSJerome Anand 			u32 *config_offset);
676287599cfSJerome Anand 	int (*hdmi_audio_read_register)(u32 reg_addr, u32 *data);
677287599cfSJerome Anand 	int (*hdmi_audio_write_register)(u32 reg_addr, u32 data);
678287599cfSJerome Anand 	int (*hdmi_audio_read_modify)(u32 reg_addr, u32 data,
679287599cfSJerome Anand 			u32 mask);
680287599cfSJerome Anand };
681287599cfSJerome Anand 
682287599cfSJerome Anand struct hdmi_audio_query_set_ops {
683287599cfSJerome Anand 	int (*hdmi_audio_get_caps)(enum had_caps_list query_element,
684287599cfSJerome Anand 			void *capabilties);
685287599cfSJerome Anand 	int (*hdmi_audio_set_caps)(enum had_caps_list set_element,
686287599cfSJerome Anand 			void *capabilties);
687287599cfSJerome Anand };
688287599cfSJerome Anand 
689287599cfSJerome Anand struct hdmi_audio_event {
690287599cfSJerome Anand 	int type;
691287599cfSJerome Anand };
692287599cfSJerome Anand 
693287599cfSJerome Anand struct snd_intel_had_interface {
694287599cfSJerome Anand 	const char *name;
695287599cfSJerome Anand 	int (*query)(void *had_data, struct hdmi_audio_event event);
696287599cfSJerome Anand 	int (*suspend)(void *had_data, struct hdmi_audio_event event);
697287599cfSJerome Anand 	int (*resume)(void *had_data);
698287599cfSJerome Anand };
699287599cfSJerome Anand 
700287599cfSJerome Anand bool mid_hdmi_audio_is_busy(void *dev);
701287599cfSJerome Anand bool mid_hdmi_audio_suspend(void *dev);
702287599cfSJerome Anand void mid_hdmi_audio_resume(void *dev);
703287599cfSJerome Anand void mid_hdmi_audio_signal_event(enum had_event_type event);
704287599cfSJerome Anand int mid_hdmi_audio_setup(
705287599cfSJerome Anand 	had_event_call_back audio_callbacks,
706287599cfSJerome Anand 	struct hdmi_audio_registers_ops *reg_ops,
707287599cfSJerome Anand 	struct hdmi_audio_query_set_ops *query_ops);
708287599cfSJerome Anand int mid_hdmi_audio_register(
709287599cfSJerome Anand 	struct snd_intel_had_interface *driver,
710287599cfSJerome Anand 	void *had_data);
711287599cfSJerome Anand 
712287599cfSJerome Anand #endif
713