xref: /openbmc/linux/sound/x86/intel_hdmi_audio.h (revision da8648097497505d05d8cff6892351f99c029791)
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 
4279dda75aSTakashi Iwai struct platform_device;
4379dda75aSTakashi Iwai 
445dab11d8SJerome Anand #define PCM_INDEX		0
455dab11d8SJerome Anand #define MAX_PB_STREAMS		1
465dab11d8SJerome Anand #define MAX_CAP_STREAMS		0
475dab11d8SJerome Anand #define HDMI_AUDIO_DRIVER	"hdmi-audio"
485dab11d8SJerome Anand 
49964ca808SPierre-Louis Bossart #define HDMI_INFO_FRAME_WORD1	0x000a0184
50964ca808SPierre-Louis Bossart #define DP_INFO_FRAME_WORD1	0x00441b84
515dab11d8SJerome Anand #define FIFO_THRESHOLD		0xFE
525dab11d8SJerome Anand #define DMA_FIFO_THRESHOLD	0x7
535dab11d8SJerome Anand #define BYTES_PER_WORD		0x4
545dab11d8SJerome Anand 
555dab11d8SJerome Anand /* Sampling rate as per IEC60958 Ver 3 */
565dab11d8SJerome Anand #define CH_STATUS_MAP_32KHZ	0x3
575dab11d8SJerome Anand #define CH_STATUS_MAP_44KHZ	0x0
585dab11d8SJerome Anand #define CH_STATUS_MAP_48KHZ	0x2
595dab11d8SJerome Anand #define CH_STATUS_MAP_88KHZ	0x8
605dab11d8SJerome Anand #define CH_STATUS_MAP_96KHZ	0xA
615dab11d8SJerome Anand #define CH_STATUS_MAP_176KHZ	0xC
625dab11d8SJerome Anand #define CH_STATUS_MAP_192KHZ	0xE
635dab11d8SJerome Anand 
645dab11d8SJerome Anand #define MAX_SMPL_WIDTH_20	0x0
655dab11d8SJerome Anand #define MAX_SMPL_WIDTH_24	0x1
665dab11d8SJerome Anand #define SMPL_WIDTH_16BITS	0x1
675dab11d8SJerome Anand #define SMPL_WIDTH_24BITS	0x5
685dab11d8SJerome Anand #define CHANNEL_ALLOCATION	0x1F
695dab11d8SJerome Anand #define MASK_BYTE0		0x000000FF
705dab11d8SJerome Anand #define VALID_DIP_WORDS		3
715dab11d8SJerome Anand #define LAYOUT0			0
725dab11d8SJerome Anand #define LAYOUT1			1
735dab11d8SJerome Anand #define SWAP_LFE_CENTER		0x00fac4c8
745dab11d8SJerome Anand #define AUD_CONFIG_CH_MASK_V2	0x70
755dab11d8SJerome Anand 
765dab11d8SJerome Anand struct pcm_stream_info {
775dab11d8SJerome Anand 	int		str_id;
785dab11d8SJerome Anand 	void	*had_substream;
795dab11d8SJerome Anand 	void	(*period_elapsed)(void *had_substream);
805dab11d8SJerome Anand 	u32		buffer_ptr;
815dab11d8SJerome Anand 	u64		buffer_rendered;
825dab11d8SJerome Anand 	u32		ring_buf_size;
835dab11d8SJerome Anand 	int		sfreq;
845dab11d8SJerome Anand };
855dab11d8SJerome Anand 
865dab11d8SJerome Anand struct ring_buf_info {
875dab11d8SJerome Anand 	u32	buf_addr;
885dab11d8SJerome Anand 	u32	buf_size;
895dab11d8SJerome Anand 	u8	is_valid;
905dab11d8SJerome Anand };
915dab11d8SJerome Anand 
925dab11d8SJerome Anand struct had_stream_pvt {
935dab11d8SJerome Anand 	enum had_stream_status		stream_status;
945dab11d8SJerome Anand 	int				stream_ops;
955dab11d8SJerome Anand 	ssize_t				dbg_cum_bytes;
965dab11d8SJerome Anand };
975dab11d8SJerome Anand 
985647aec2STakashi Iwai struct had_stream_data {
995dab11d8SJerome Anand 	enum had_status_stream		stream_type;
1005dab11d8SJerome Anand };
1015dab11d8SJerome Anand 
1025dab11d8SJerome Anand /**
1035dab11d8SJerome Anand  * struct snd_intelhad - intelhad driver structure
1045dab11d8SJerome Anand  *
1055dab11d8SJerome Anand  * @card: ptr to hold card details
1065dab11d8SJerome Anand  * @card_index: sound card index
1075dab11d8SJerome Anand  * @card_id: detected sound card id
1085dab11d8SJerome Anand  * @drv_status: driver status
1095dab11d8SJerome Anand  * @buf_info: ring buffer info
1105dab11d8SJerome Anand  * @stream_info: stream information
111*da864809STakashi Iwai  * @eld: holds ELD info
1125dab11d8SJerome Anand  * @curr_buf: pointer to hold current active ring buf
1135dab11d8SJerome Anand  * @valid_buf_cnt: ring buffer count for stream
1145dab11d8SJerome Anand  * @had_spinlock: driver lock
1155dab11d8SJerome Anand  * @aes_bits: IEC958 status bits
1165dab11d8SJerome Anand  * @buff_done: id of current buffer done intr
1175dab11d8SJerome Anand  * @dev: platoform device handle
1185dab11d8SJerome Anand  * @kctl: holds kctl ptrs used for channel map
1195dab11d8SJerome Anand  * @chmap: holds channel map info
1205dab11d8SJerome Anand  * @audio_reg_base: hdmi audio register base offset
1216ddb3ab6STakashi Iwai  * @underrun_count: PCM stream underrun counter
1225dab11d8SJerome Anand  */
1235dab11d8SJerome Anand struct snd_intelhad {
1245dab11d8SJerome Anand 	struct snd_card	*card;
1255dab11d8SJerome Anand 	int		card_index;
1265dab11d8SJerome Anand 	char		*card_id;
1275dab11d8SJerome Anand 	enum had_drv_status	drv_status;
1285dab11d8SJerome Anand 	struct		ring_buf_info buf_info[HAD_NUM_OF_RING_BUFS];
1295dab11d8SJerome Anand 	struct		pcm_stream_info stream_info;
130*da864809STakashi Iwai 	union otm_hdmi_eld_t	eld;
131964ca808SPierre-Louis Bossart 	bool dp_output;
1325dab11d8SJerome Anand 	enum		intel_had_aud_buf_type curr_buf;
1335dab11d8SJerome Anand 	int		valid_buf_cnt;
1345dab11d8SJerome Anand 	unsigned int	aes_bits;
1355dab11d8SJerome Anand 	int flag_underrun;
1365647aec2STakashi Iwai 	struct had_stream_data stream_data;
1375dab11d8SJerome Anand 	spinlock_t had_spinlock;
1385dab11d8SJerome Anand 	enum		intel_had_aud_buf_type buff_done;
1395dab11d8SJerome Anand 	struct device *dev;
1405dab11d8SJerome Anand 	struct snd_kcontrol *kctl;
1415dab11d8SJerome Anand 	struct snd_pcm_chmap *chmap;
1425dab11d8SJerome Anand 	unsigned int	*audio_reg_base;
1435dab11d8SJerome Anand 	unsigned int	audio_cfg_offset;
1446ddb3ab6STakashi Iwai 	int underrun_count;
145*da864809STakashi Iwai 	enum hdmi_connector_status state;
146*da864809STakashi Iwai 	int tmds_clock_speed;
147*da864809STakashi Iwai 	int link_rate;
148*da864809STakashi Iwai 
149*da864809STakashi Iwai 	/* internal stuff */
150*da864809STakashi Iwai 	int irq;
151*da864809STakashi Iwai 	void __iomem *mmio_start;
152*da864809STakashi Iwai 	unsigned int had_config_offset;
153*da864809STakashi Iwai 	int hdmi_audio_interrupt_mask;
154*da864809STakashi Iwai 	struct work_struct hdmi_audio_wq;
1555dab11d8SJerome Anand };
1565dab11d8SJerome Anand 
157*da864809STakashi Iwai int hdmi_lpe_audio_suspend(struct platform_device *pdev, pm_message_t state);
158*da864809STakashi Iwai int hdmi_lpe_audio_resume(struct platform_device *pdev);
1595dab11d8SJerome Anand extern struct snd_pcm_ops snd_intelhad_playback_ops;
1605dab11d8SJerome Anand 
161*da864809STakashi Iwai int had_process_buffer_done(struct snd_intelhad *intelhaddata);
162*da864809STakashi Iwai int had_process_buffer_underrun(struct snd_intelhad *intelhaddata);
163*da864809STakashi Iwai int had_process_hot_plug(struct snd_intelhad *intelhaddata);
164*da864809STakashi Iwai int had_process_hot_unplug(struct snd_intelhad *intelhaddata);
165*da864809STakashi Iwai 
1665dab11d8SJerome Anand int snd_intelhad_init_audio_ctrl(struct snd_pcm_substream *substream,
1675dab11d8SJerome Anand 					struct snd_intelhad *intelhaddata,
1685dab11d8SJerome Anand 					int flag_silence);
1695dab11d8SJerome Anand int snd_intelhad_prog_buffer(struct snd_intelhad *intelhaddata,
1705dab11d8SJerome Anand 					int start, int end);
1715dab11d8SJerome Anand int snd_intelhad_invd_buffer(int start, int end);
1725dab11d8SJerome Anand int snd_intelhad_read_len(struct snd_intelhad *intelhaddata);
1735dab11d8SJerome Anand void had_build_channel_allocation_map(struct snd_intelhad *intelhaddata);
1745dab11d8SJerome Anand 
175*da864809STakashi Iwai void snd_intelhad_enable_audio_int(struct snd_intelhad *ctx, bool enable);
176*da864809STakashi Iwai void snd_intelhad_enable_audio(struct snd_intelhad *ctx, bool enable);
17776296ef0STakashi Iwai void snd_intelhad_handle_underrun(struct snd_intelhad *intelhaddata);
17876296ef0STakashi Iwai 
1795dab11d8SJerome Anand /* Register access functions */
1805dab11d8SJerome Anand int had_get_hwstate(struct snd_intelhad *intelhaddata);
18179dda75aSTakashi Iwai int had_read_register(struct snd_intelhad *intelhaddata,
18279dda75aSTakashi Iwai 		      u32 reg_addr, u32 *data);
18379dda75aSTakashi Iwai int had_write_register(struct snd_intelhad *intelhaddata,
18479dda75aSTakashi Iwai 		       u32 reg_addr, u32 data);
18579dda75aSTakashi Iwai int had_read_modify(struct snd_intelhad *intelhaddata,
18679dda75aSTakashi Iwai 		    u32 reg_addr, u32 data, u32 mask);
1875dab11d8SJerome Anand 
1885dab11d8SJerome Anand #endif /* _INTEL_HDMI_AUDIO_ */
189