xref: /openbmc/linux/sound/x86/intel_hdmi_audio.h (revision 964ca8083c0239b5a729ed08c9f50b6c31ab3a93)
15dab11d8SJerome Anand /*
25dab11d8SJerome Anand  * Copyright (C) 2016 Intel Corporation
35dab11d8SJerome Anand  *  Authors:	Sailaja Bandarupalli <sailaja.bandarupalli@intel.com>
45dab11d8SJerome Anand  *		Ramesh Babu K V	<ramesh.babu@intel.com>
55dab11d8SJerome Anand  *		Vaibhav Agarwal <vaibhav.agarwal@intel.com>
65dab11d8SJerome Anand  *		Jerome Anand <jerome.anand@intel.com>
75dab11d8SJerome Anand  *
85dab11d8SJerome Anand  * Permission is hereby granted, free of charge, to any person obtaining
95dab11d8SJerome Anand  * a copy of this software and associated documentation files
105dab11d8SJerome Anand  * (the "Software"), to deal in the Software without restriction,
115dab11d8SJerome Anand  * including without limitation the rights to use, copy, modify, merge,
125dab11d8SJerome Anand  * publish, distribute, sublicense, and/or sell copies of the Software,
135dab11d8SJerome Anand  * and to permit persons to whom the Software is furnished to do so,
145dab11d8SJerome Anand  * subject to the following conditions:
155dab11d8SJerome Anand  *
165dab11d8SJerome Anand  * The above copyright notice and this permission notice (including the
175dab11d8SJerome Anand  * next paragraph) shall be included in all copies or substantial
185dab11d8SJerome Anand  * portions of the Software.
195dab11d8SJerome Anand  *
205dab11d8SJerome Anand  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
215dab11d8SJerome Anand  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
225dab11d8SJerome Anand  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
235dab11d8SJerome Anand  * NONINFRINGEMENT.  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
245dab11d8SJerome Anand  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
255dab11d8SJerome Anand  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
265dab11d8SJerome Anand  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
275dab11d8SJerome Anand  * SOFTWARE.
285dab11d8SJerome Anand  */
295dab11d8SJerome Anand 
305dab11d8SJerome Anand #ifndef _INTEL_HDMI_AUDIO_H_
315dab11d8SJerome Anand #define _INTEL_HDMI_AUDIO_H_
325dab11d8SJerome Anand 
335dab11d8SJerome Anand #include <linux/types.h>
345dab11d8SJerome Anand #include <sound/initval.h>
355dab11d8SJerome Anand #include <linux/version.h>
365dab11d8SJerome Anand #include <linux/pm_runtime.h>
375dab11d8SJerome Anand #include <sound/asoundef.h>
385dab11d8SJerome Anand #include <sound/control.h>
395dab11d8SJerome Anand #include <sound/pcm.h>
405dab11d8SJerome Anand #include "intel_hdmi_lpe_audio.h"
415dab11d8SJerome Anand 
425dab11d8SJerome Anand #define PCM_INDEX		0
435dab11d8SJerome Anand #define MAX_PB_STREAMS		1
445dab11d8SJerome Anand #define MAX_CAP_STREAMS		0
455dab11d8SJerome Anand #define HDMI_AUDIO_DRIVER	"hdmi-audio"
465dab11d8SJerome Anand 
47*964ca808SPierre-Louis Bossart #define HDMI_INFO_FRAME_WORD1	0x000a0184
48*964ca808SPierre-Louis Bossart #define DP_INFO_FRAME_WORD1	0x00441b84
495dab11d8SJerome Anand #define FIFO_THRESHOLD		0xFE
505dab11d8SJerome Anand #define DMA_FIFO_THRESHOLD	0x7
515dab11d8SJerome Anand #define BYTES_PER_WORD		0x4
525dab11d8SJerome Anand 
535dab11d8SJerome Anand /* Sampling rate as per IEC60958 Ver 3 */
545dab11d8SJerome Anand #define CH_STATUS_MAP_32KHZ	0x3
555dab11d8SJerome Anand #define CH_STATUS_MAP_44KHZ	0x0
565dab11d8SJerome Anand #define CH_STATUS_MAP_48KHZ	0x2
575dab11d8SJerome Anand #define CH_STATUS_MAP_88KHZ	0x8
585dab11d8SJerome Anand #define CH_STATUS_MAP_96KHZ	0xA
595dab11d8SJerome Anand #define CH_STATUS_MAP_176KHZ	0xC
605dab11d8SJerome Anand #define CH_STATUS_MAP_192KHZ	0xE
615dab11d8SJerome Anand 
625dab11d8SJerome Anand #define MAX_SMPL_WIDTH_20	0x0
635dab11d8SJerome Anand #define MAX_SMPL_WIDTH_24	0x1
645dab11d8SJerome Anand #define SMPL_WIDTH_16BITS	0x1
655dab11d8SJerome Anand #define SMPL_WIDTH_24BITS	0x5
665dab11d8SJerome Anand #define CHANNEL_ALLOCATION	0x1F
675dab11d8SJerome Anand #define MASK_BYTE0		0x000000FF
685dab11d8SJerome Anand #define VALID_DIP_WORDS		3
695dab11d8SJerome Anand #define LAYOUT0			0
705dab11d8SJerome Anand #define LAYOUT1			1
715dab11d8SJerome Anand #define SWAP_LFE_CENTER		0x00fac4c8
725dab11d8SJerome Anand #define AUD_CONFIG_CH_MASK_V2	0x70
735dab11d8SJerome Anand 
745dab11d8SJerome Anand struct pcm_stream_info {
755dab11d8SJerome Anand 	int		str_id;
765dab11d8SJerome Anand 	void	*had_substream;
775dab11d8SJerome Anand 	void	(*period_elapsed)(void *had_substream);
785dab11d8SJerome Anand 	u32		buffer_ptr;
795dab11d8SJerome Anand 	u64		buffer_rendered;
805dab11d8SJerome Anand 	u32		ring_buf_size;
815dab11d8SJerome Anand 	int		sfreq;
825dab11d8SJerome Anand };
835dab11d8SJerome Anand 
845dab11d8SJerome Anand struct ring_buf_info {
855dab11d8SJerome Anand 	u32	buf_addr;
865dab11d8SJerome Anand 	u32	buf_size;
875dab11d8SJerome Anand 	u8	is_valid;
885dab11d8SJerome Anand };
895dab11d8SJerome Anand 
905dab11d8SJerome Anand struct had_stream_pvt {
915dab11d8SJerome Anand 	enum had_stream_status		stream_status;
925dab11d8SJerome Anand 	int				stream_ops;
935dab11d8SJerome Anand 	ssize_t				dbg_cum_bytes;
945dab11d8SJerome Anand };
955dab11d8SJerome Anand 
965dab11d8SJerome Anand struct had_pvt_data {
975dab11d8SJerome Anand 	enum had_status_stream		stream_type;
985dab11d8SJerome Anand };
995dab11d8SJerome Anand 
1005dab11d8SJerome Anand struct had_callback_ops {
1015dab11d8SJerome Anand 	had_event_call_back intel_had_event_call_back;
1025dab11d8SJerome Anand };
1035dab11d8SJerome Anand 
1045dab11d8SJerome Anand /**
1055dab11d8SJerome Anand  * struct snd_intelhad - intelhad driver structure
1065dab11d8SJerome Anand  *
1075dab11d8SJerome Anand  * @card: ptr to hold card details
1085dab11d8SJerome Anand  * @card_index: sound card index
1095dab11d8SJerome Anand  * @card_id: detected sound card id
1105dab11d8SJerome Anand  * @reg_ops: register operations to program registers
1115dab11d8SJerome Anand  * @query_ops: caps call backs for get/set operations
1125dab11d8SJerome Anand  * @drv_status: driver status
1135dab11d8SJerome Anand  * @buf_info: ring buffer info
1145dab11d8SJerome Anand  * @stream_info: stream information
1155dab11d8SJerome Anand  * @eeld: holds EELD info
1165dab11d8SJerome Anand  * @curr_buf: pointer to hold current active ring buf
1175dab11d8SJerome Anand  * @valid_buf_cnt: ring buffer count for stream
1185dab11d8SJerome Anand  * @had_spinlock: driver lock
1195dab11d8SJerome Anand  * @aes_bits: IEC958 status bits
1205dab11d8SJerome Anand  * @buff_done: id of current buffer done intr
1215dab11d8SJerome Anand  * @dev: platoform device handle
1225dab11d8SJerome Anand  * @kctl: holds kctl ptrs used for channel map
1235dab11d8SJerome Anand  * @chmap: holds channel map info
1245dab11d8SJerome Anand  * @audio_reg_base: hdmi audio register base offset
1255dab11d8SJerome Anand  * @hw_silence: flag indicates SoC support for HW silence/Keep alive
1265dab11d8SJerome Anand  * @ops: holds ops functions based on platform
1275dab11d8SJerome Anand  */
1285dab11d8SJerome Anand struct snd_intelhad {
1295dab11d8SJerome Anand 	struct snd_card	*card;
1305dab11d8SJerome Anand 	int		card_index;
1315dab11d8SJerome Anand 	char		*card_id;
1325dab11d8SJerome Anand 	struct hdmi_audio_registers_ops	reg_ops;
1335dab11d8SJerome Anand 	struct hdmi_audio_query_set_ops	query_ops;
1345dab11d8SJerome Anand 	enum had_drv_status	drv_status;
1355dab11d8SJerome Anand 	struct		ring_buf_info buf_info[HAD_NUM_OF_RING_BUFS];
1365dab11d8SJerome Anand 	struct		pcm_stream_info stream_info;
1375dab11d8SJerome Anand 	union otm_hdmi_eld_t	eeld;
138*964ca808SPierre-Louis Bossart 	bool dp_output;
1395dab11d8SJerome Anand 	enum		intel_had_aud_buf_type curr_buf;
1405dab11d8SJerome Anand 	int		valid_buf_cnt;
1415dab11d8SJerome Anand 	unsigned int	aes_bits;
1425dab11d8SJerome Anand 	int flag_underrun;
1435dab11d8SJerome Anand 	struct had_pvt_data *private_data;
1445dab11d8SJerome Anand 	spinlock_t had_spinlock;
1455dab11d8SJerome Anand 	enum		intel_had_aud_buf_type buff_done;
1465dab11d8SJerome Anand 	struct device *dev;
1475dab11d8SJerome Anand 	struct snd_kcontrol *kctl;
1485dab11d8SJerome Anand 	struct snd_pcm_chmap *chmap;
1495dab11d8SJerome Anand 	unsigned int	*audio_reg_base;
1505dab11d8SJerome Anand 	unsigned int	audio_cfg_offset;
1515dab11d8SJerome Anand 	bool		hw_silence;
1525dab11d8SJerome Anand 	struct had_ops	*ops;
1535dab11d8SJerome Anand };
1545dab11d8SJerome Anand 
1555dab11d8SJerome Anand struct had_ops {
1565dab11d8SJerome Anand 	void (*enable_audio)(struct snd_pcm_substream *substream,
1575dab11d8SJerome Anand 			u8 enable);
1585dab11d8SJerome Anand 	void (*reset_audio)(u8 reset);
1595dab11d8SJerome Anand 	int (*prog_n)(u32 aud_samp_freq, u32 *n_param,
1605dab11d8SJerome Anand 			struct snd_intelhad *intelhaddata);
161*964ca808SPierre-Louis Bossart 	void (*prog_cts)(u32 aud_samp_freq, u32 tmds, u32 link_rate,
162*964ca808SPierre-Louis Bossart 			 u32 n_param, struct snd_intelhad *intelhaddata);
1635dab11d8SJerome Anand 	int (*audio_ctrl)(struct snd_pcm_substream *substream,
1645dab11d8SJerome Anand 				struct snd_intelhad *intelhaddata);
1655dab11d8SJerome Anand 	void (*prog_dip)(struct snd_pcm_substream *substream,
1665dab11d8SJerome Anand 				struct snd_intelhad *intelhaddata);
1675dab11d8SJerome Anand 	void (*handle_underrun)(struct snd_intelhad *intelhaddata);
1685dab11d8SJerome Anand };
1695dab11d8SJerome Anand 
1705dab11d8SJerome Anand 
1715dab11d8SJerome Anand int had_event_handler(enum had_event_type event_type, void *data);
1725dab11d8SJerome Anand 
1735dab11d8SJerome Anand int hdmi_audio_query(void *drv_data, struct hdmi_audio_event event);
1745dab11d8SJerome Anand int hdmi_audio_suspend(void *drv_data, struct hdmi_audio_event event);
1755dab11d8SJerome Anand int hdmi_audio_resume(void *drv_data);
1765dab11d8SJerome Anand int hdmi_audio_mode_change(struct snd_pcm_substream *substream);
1775dab11d8SJerome Anand extern struct snd_pcm_ops snd_intelhad_playback_ops;
1785dab11d8SJerome Anand 
1795dab11d8SJerome Anand int snd_intelhad_init_audio_ctrl(struct snd_pcm_substream *substream,
1805dab11d8SJerome Anand 					struct snd_intelhad *intelhaddata,
1815dab11d8SJerome Anand 					int flag_silence);
1825dab11d8SJerome Anand int snd_intelhad_prog_buffer(struct snd_intelhad *intelhaddata,
1835dab11d8SJerome Anand 					int start, int end);
1845dab11d8SJerome Anand int snd_intelhad_invd_buffer(int start, int end);
1855dab11d8SJerome Anand int snd_intelhad_read_len(struct snd_intelhad *intelhaddata);
1865dab11d8SJerome Anand void had_build_channel_allocation_map(struct snd_intelhad *intelhaddata);
1875dab11d8SJerome Anand 
1885dab11d8SJerome Anand /* Register access functions */
1895dab11d8SJerome Anand int had_get_hwstate(struct snd_intelhad *intelhaddata);
1905dab11d8SJerome Anand int had_get_caps(enum had_caps_list query_element, void *capabilties);
1915dab11d8SJerome Anand int had_set_caps(enum had_caps_list set_element, void *capabilties);
1925dab11d8SJerome Anand int had_read_register(u32 reg_addr, u32 *data);
1935dab11d8SJerome Anand int had_write_register(u32 reg_addr, u32 data);
1945dab11d8SJerome Anand int had_read_modify(u32 reg_addr, u32 data, u32 mask);
1955dab11d8SJerome Anand 
1965dab11d8SJerome Anand int hdmi_audio_probe(void *devptr);
1975dab11d8SJerome Anand int hdmi_audio_remove(void *pdev);
1985dab11d8SJerome Anand 
1995dab11d8SJerome Anand #endif /* _INTEL_HDMI_AUDIO_ */
200