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