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