1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * Copyright (c) 2010-2011,2013-2015,2020 The Linux Foundation. All rights reserved. 4*4882a593Smuzhiyun * 5*4882a593Smuzhiyun * lpass.h - Definitions for the QTi LPASS 6*4882a593Smuzhiyun */ 7*4882a593Smuzhiyun 8*4882a593Smuzhiyun #ifndef __LPASS_H__ 9*4882a593Smuzhiyun #define __LPASS_H__ 10*4882a593Smuzhiyun 11*4882a593Smuzhiyun #include <linux/clk.h> 12*4882a593Smuzhiyun #include <linux/compiler.h> 13*4882a593Smuzhiyun #include <linux/platform_device.h> 14*4882a593Smuzhiyun #include <linux/regmap.h> 15*4882a593Smuzhiyun #include <dt-bindings/sound/qcom,lpass.h> 16*4882a593Smuzhiyun #include "lpass-hdmi.h" 17*4882a593Smuzhiyun 18*4882a593Smuzhiyun #define LPASS_AHBIX_CLOCK_FREQUENCY 131072000 19*4882a593Smuzhiyun #define LPASS_MAX_MI2S_PORTS (8) 20*4882a593Smuzhiyun #define LPASS_MAX_DMA_CHANNELS (8) 21*4882a593Smuzhiyun #define LPASS_MAX_HDMI_DMA_CHANNELS (4) 22*4882a593Smuzhiyun 23*4882a593Smuzhiyun #define QCOM_REGMAP_FIELD_ALLOC(d, m, f, mf) \ 24*4882a593Smuzhiyun do { \ 25*4882a593Smuzhiyun mf = devm_regmap_field_alloc(d, m, f); \ 26*4882a593Smuzhiyun if (IS_ERR(mf)) \ 27*4882a593Smuzhiyun return -EINVAL; \ 28*4882a593Smuzhiyun } while (0) 29*4882a593Smuzhiyun 30*4882a593Smuzhiyun struct lpaif_i2sctl { 31*4882a593Smuzhiyun struct regmap_field *loopback; 32*4882a593Smuzhiyun struct regmap_field *spken; 33*4882a593Smuzhiyun struct regmap_field *spkmode; 34*4882a593Smuzhiyun struct regmap_field *spkmono; 35*4882a593Smuzhiyun struct regmap_field *micen; 36*4882a593Smuzhiyun struct regmap_field *micmode; 37*4882a593Smuzhiyun struct regmap_field *micmono; 38*4882a593Smuzhiyun struct regmap_field *wssrc; 39*4882a593Smuzhiyun struct regmap_field *bitwidth; 40*4882a593Smuzhiyun }; 41*4882a593Smuzhiyun 42*4882a593Smuzhiyun 43*4882a593Smuzhiyun struct lpaif_dmactl { 44*4882a593Smuzhiyun struct regmap_field *intf; 45*4882a593Smuzhiyun struct regmap_field *bursten; 46*4882a593Smuzhiyun struct regmap_field *wpscnt; 47*4882a593Smuzhiyun struct regmap_field *fifowm; 48*4882a593Smuzhiyun struct regmap_field *enable; 49*4882a593Smuzhiyun struct regmap_field *dyncclk; 50*4882a593Smuzhiyun struct regmap_field *burst8; 51*4882a593Smuzhiyun struct regmap_field *burst16; 52*4882a593Smuzhiyun struct regmap_field *dynburst; 53*4882a593Smuzhiyun }; 54*4882a593Smuzhiyun 55*4882a593Smuzhiyun /* Both the CPU DAI and platform drivers will access this data */ 56*4882a593Smuzhiyun struct lpass_data { 57*4882a593Smuzhiyun 58*4882a593Smuzhiyun /* AHB-I/X bus clocks inside the low-power audio subsystem (LPASS) */ 59*4882a593Smuzhiyun struct clk *ahbix_clk; 60*4882a593Smuzhiyun 61*4882a593Smuzhiyun /* MI2S system clock */ 62*4882a593Smuzhiyun struct clk *mi2s_osr_clk[LPASS_MAX_MI2S_PORTS]; 63*4882a593Smuzhiyun 64*4882a593Smuzhiyun /* MI2S bit clock (derived from system clock by a divider */ 65*4882a593Smuzhiyun struct clk *mi2s_bit_clk[LPASS_MAX_MI2S_PORTS]; 66*4882a593Smuzhiyun 67*4882a593Smuzhiyun /* MI2S SD lines to use for playback/capture */ 68*4882a593Smuzhiyun unsigned int mi2s_playback_sd_mode[LPASS_MAX_MI2S_PORTS]; 69*4882a593Smuzhiyun unsigned int mi2s_capture_sd_mode[LPASS_MAX_MI2S_PORTS]; 70*4882a593Smuzhiyun 71*4882a593Smuzhiyun /* The state of MI2S prepare dai_ops was called */ 72*4882a593Smuzhiyun bool mi2s_was_prepared[LPASS_MAX_MI2S_PORTS]; 73*4882a593Smuzhiyun 74*4882a593Smuzhiyun int hdmi_port_enable; 75*4882a593Smuzhiyun 76*4882a593Smuzhiyun /* low-power audio interface (LPAIF) registers */ 77*4882a593Smuzhiyun void __iomem *lpaif; 78*4882a593Smuzhiyun void __iomem *hdmiif; 79*4882a593Smuzhiyun 80*4882a593Smuzhiyun /* regmap backed by the low-power audio interface (LPAIF) registers */ 81*4882a593Smuzhiyun struct regmap *lpaif_map; 82*4882a593Smuzhiyun struct regmap *hdmiif_map; 83*4882a593Smuzhiyun 84*4882a593Smuzhiyun /* interrupts from the low-power audio interface (LPAIF) */ 85*4882a593Smuzhiyun int lpaif_irq; 86*4882a593Smuzhiyun int hdmiif_irq; 87*4882a593Smuzhiyun /* SOC specific variations in the LPASS IP integration */ 88*4882a593Smuzhiyun struct lpass_variant *variant; 89*4882a593Smuzhiyun 90*4882a593Smuzhiyun /* bit map to keep track of static channel allocations */ 91*4882a593Smuzhiyun unsigned long dma_ch_bit_map; 92*4882a593Smuzhiyun unsigned long hdmi_dma_ch_bit_map; 93*4882a593Smuzhiyun 94*4882a593Smuzhiyun /* used it for handling interrupt per dma channel */ 95*4882a593Smuzhiyun struct snd_pcm_substream *substream[LPASS_MAX_DMA_CHANNELS]; 96*4882a593Smuzhiyun struct snd_pcm_substream *hdmi_substream[LPASS_MAX_HDMI_DMA_CHANNELS]; 97*4882a593Smuzhiyun 98*4882a593Smuzhiyun /* SOC specific clock list */ 99*4882a593Smuzhiyun struct clk_bulk_data *clks; 100*4882a593Smuzhiyun int num_clks; 101*4882a593Smuzhiyun 102*4882a593Smuzhiyun /* Regmap fields of I2SCTL & DMACTL registers bitfields */ 103*4882a593Smuzhiyun struct lpaif_i2sctl *i2sctl; 104*4882a593Smuzhiyun struct lpaif_dmactl *rd_dmactl; 105*4882a593Smuzhiyun struct lpaif_dmactl *wr_dmactl; 106*4882a593Smuzhiyun struct lpaif_dmactl *hdmi_rd_dmactl; 107*4882a593Smuzhiyun /* Regmap fields of HDMI_CTRL registers*/ 108*4882a593Smuzhiyun struct regmap_field *hdmitx_legacy_en; 109*4882a593Smuzhiyun struct regmap_field *hdmitx_parity_calc_en; 110*4882a593Smuzhiyun struct regmap_field *hdmitx_ch_msb[LPASS_MAX_HDMI_DMA_CHANNELS]; 111*4882a593Smuzhiyun struct regmap_field *hdmitx_ch_lsb[LPASS_MAX_HDMI_DMA_CHANNELS]; 112*4882a593Smuzhiyun struct lpass_hdmi_tx_ctl *tx_ctl; 113*4882a593Smuzhiyun struct lpass_vbit_ctrl *vbit_ctl; 114*4882a593Smuzhiyun struct lpass_hdmitx_dmactl *hdmi_tx_dmactl[LPASS_MAX_HDMI_DMA_CHANNELS]; 115*4882a593Smuzhiyun struct lpass_dp_metadata_ctl *meta_ctl; 116*4882a593Smuzhiyun struct lpass_sstream_ctl *sstream_ctl; 117*4882a593Smuzhiyun }; 118*4882a593Smuzhiyun 119*4882a593Smuzhiyun /* Vairant data per each SOC */ 120*4882a593Smuzhiyun struct lpass_variant { 121*4882a593Smuzhiyun u32 irq_reg_base; 122*4882a593Smuzhiyun u32 irq_reg_stride; 123*4882a593Smuzhiyun u32 irq_ports; 124*4882a593Smuzhiyun u32 rdma_reg_base; 125*4882a593Smuzhiyun u32 rdma_reg_stride; 126*4882a593Smuzhiyun u32 rdma_channels; 127*4882a593Smuzhiyun u32 hdmi_rdma_reg_base; 128*4882a593Smuzhiyun u32 hdmi_rdma_reg_stride; 129*4882a593Smuzhiyun u32 hdmi_rdma_channels; 130*4882a593Smuzhiyun u32 wrdma_reg_base; 131*4882a593Smuzhiyun u32 wrdma_reg_stride; 132*4882a593Smuzhiyun u32 wrdma_channels; 133*4882a593Smuzhiyun u32 i2sctrl_reg_base; 134*4882a593Smuzhiyun u32 i2sctrl_reg_stride; 135*4882a593Smuzhiyun u32 i2s_ports; 136*4882a593Smuzhiyun 137*4882a593Smuzhiyun /* I2SCTL Register fields */ 138*4882a593Smuzhiyun struct reg_field loopback; 139*4882a593Smuzhiyun struct reg_field spken; 140*4882a593Smuzhiyun struct reg_field spkmode; 141*4882a593Smuzhiyun struct reg_field spkmono; 142*4882a593Smuzhiyun struct reg_field micen; 143*4882a593Smuzhiyun struct reg_field micmode; 144*4882a593Smuzhiyun struct reg_field micmono; 145*4882a593Smuzhiyun struct reg_field wssrc; 146*4882a593Smuzhiyun struct reg_field bitwidth; 147*4882a593Smuzhiyun 148*4882a593Smuzhiyun u32 hdmi_irq_reg_base; 149*4882a593Smuzhiyun u32 hdmi_irq_reg_stride; 150*4882a593Smuzhiyun u32 hdmi_irq_ports; 151*4882a593Smuzhiyun 152*4882a593Smuzhiyun /* HDMI specific controls */ 153*4882a593Smuzhiyun u32 hdmi_tx_ctl_addr; 154*4882a593Smuzhiyun u32 hdmi_legacy_addr; 155*4882a593Smuzhiyun u32 hdmi_vbit_addr; 156*4882a593Smuzhiyun u32 hdmi_ch_lsb_addr; 157*4882a593Smuzhiyun u32 hdmi_ch_msb_addr; 158*4882a593Smuzhiyun u32 ch_stride; 159*4882a593Smuzhiyun u32 hdmi_parity_addr; 160*4882a593Smuzhiyun u32 hdmi_dmactl_addr; 161*4882a593Smuzhiyun u32 hdmi_dma_stride; 162*4882a593Smuzhiyun u32 hdmi_DP_addr; 163*4882a593Smuzhiyun u32 hdmi_sstream_addr; 164*4882a593Smuzhiyun 165*4882a593Smuzhiyun /* HDMI SSTREAM CTRL fields */ 166*4882a593Smuzhiyun struct reg_field sstream_en; 167*4882a593Smuzhiyun struct reg_field dma_sel; 168*4882a593Smuzhiyun struct reg_field auto_bbit_en; 169*4882a593Smuzhiyun struct reg_field layout; 170*4882a593Smuzhiyun struct reg_field layout_sp; 171*4882a593Smuzhiyun struct reg_field set_sp_on_en; 172*4882a593Smuzhiyun struct reg_field dp_audio; 173*4882a593Smuzhiyun struct reg_field dp_staffing_en; 174*4882a593Smuzhiyun struct reg_field dp_sp_b_hw_en; 175*4882a593Smuzhiyun 176*4882a593Smuzhiyun /* HDMI DP METADATA CTL fields */ 177*4882a593Smuzhiyun struct reg_field mute; 178*4882a593Smuzhiyun struct reg_field as_sdp_cc; 179*4882a593Smuzhiyun struct reg_field as_sdp_ct; 180*4882a593Smuzhiyun struct reg_field aif_db4; 181*4882a593Smuzhiyun struct reg_field frequency; 182*4882a593Smuzhiyun struct reg_field mst_index; 183*4882a593Smuzhiyun struct reg_field dptx_index; 184*4882a593Smuzhiyun 185*4882a593Smuzhiyun /* HDMI TX CTRL fields */ 186*4882a593Smuzhiyun struct reg_field soft_reset; 187*4882a593Smuzhiyun struct reg_field force_reset; 188*4882a593Smuzhiyun 189*4882a593Smuzhiyun /* HDMI TX DMA CTRL */ 190*4882a593Smuzhiyun struct reg_field use_hw_chs; 191*4882a593Smuzhiyun struct reg_field use_hw_usr; 192*4882a593Smuzhiyun struct reg_field hw_chs_sel; 193*4882a593Smuzhiyun struct reg_field hw_usr_sel; 194*4882a593Smuzhiyun 195*4882a593Smuzhiyun /* HDMI VBIT CTRL */ 196*4882a593Smuzhiyun struct reg_field replace_vbit; 197*4882a593Smuzhiyun struct reg_field vbit_stream; 198*4882a593Smuzhiyun 199*4882a593Smuzhiyun /* HDMI TX LEGACY */ 200*4882a593Smuzhiyun struct reg_field legacy_en; 201*4882a593Smuzhiyun 202*4882a593Smuzhiyun /* HDMI TX PARITY */ 203*4882a593Smuzhiyun struct reg_field calc_en; 204*4882a593Smuzhiyun 205*4882a593Smuzhiyun /* HDMI CH LSB */ 206*4882a593Smuzhiyun struct reg_field lsb_bits; 207*4882a593Smuzhiyun 208*4882a593Smuzhiyun /* HDMI CH MSB */ 209*4882a593Smuzhiyun struct reg_field msb_bits; 210*4882a593Smuzhiyun 211*4882a593Smuzhiyun struct reg_field hdmi_rdma_bursten; 212*4882a593Smuzhiyun struct reg_field hdmi_rdma_wpscnt; 213*4882a593Smuzhiyun struct reg_field hdmi_rdma_fifowm; 214*4882a593Smuzhiyun struct reg_field hdmi_rdma_enable; 215*4882a593Smuzhiyun struct reg_field hdmi_rdma_dyncclk; 216*4882a593Smuzhiyun struct reg_field hdmi_rdma_burst8; 217*4882a593Smuzhiyun struct reg_field hdmi_rdma_burst16; 218*4882a593Smuzhiyun struct reg_field hdmi_rdma_dynburst; 219*4882a593Smuzhiyun 220*4882a593Smuzhiyun /* RD_DMA Register fields */ 221*4882a593Smuzhiyun struct reg_field rdma_intf; 222*4882a593Smuzhiyun struct reg_field rdma_bursten; 223*4882a593Smuzhiyun struct reg_field rdma_wpscnt; 224*4882a593Smuzhiyun struct reg_field rdma_fifowm; 225*4882a593Smuzhiyun struct reg_field rdma_enable; 226*4882a593Smuzhiyun struct reg_field rdma_dyncclk; 227*4882a593Smuzhiyun 228*4882a593Smuzhiyun /* WR_DMA Register fields */ 229*4882a593Smuzhiyun struct reg_field wrdma_intf; 230*4882a593Smuzhiyun struct reg_field wrdma_bursten; 231*4882a593Smuzhiyun struct reg_field wrdma_wpscnt; 232*4882a593Smuzhiyun struct reg_field wrdma_fifowm; 233*4882a593Smuzhiyun struct reg_field wrdma_enable; 234*4882a593Smuzhiyun struct reg_field wrdma_dyncclk; 235*4882a593Smuzhiyun 236*4882a593Smuzhiyun /** 237*4882a593Smuzhiyun * on SOCs like APQ8016 the channel control bits start 238*4882a593Smuzhiyun * at different offset to ipq806x 239*4882a593Smuzhiyun **/ 240*4882a593Smuzhiyun u32 dmactl_audif_start; 241*4882a593Smuzhiyun u32 wrdma_channel_start; 242*4882a593Smuzhiyun /* SOC specific initialization like clocks */ 243*4882a593Smuzhiyun int (*init)(struct platform_device *pdev); 244*4882a593Smuzhiyun int (*exit)(struct platform_device *pdev); 245*4882a593Smuzhiyun int (*alloc_dma_channel)(struct lpass_data *data, int direction, unsigned int dai_id); 246*4882a593Smuzhiyun int (*free_dma_channel)(struct lpass_data *data, int ch, unsigned int dai_id); 247*4882a593Smuzhiyun 248*4882a593Smuzhiyun /* SOC specific dais */ 249*4882a593Smuzhiyun struct snd_soc_dai_driver *dai_driver; 250*4882a593Smuzhiyun int num_dai; 251*4882a593Smuzhiyun const char * const *dai_osr_clk_names; 252*4882a593Smuzhiyun const char * const *dai_bit_clk_names; 253*4882a593Smuzhiyun 254*4882a593Smuzhiyun /* SOC specific clocks configuration */ 255*4882a593Smuzhiyun const char **clk_name; 256*4882a593Smuzhiyun int num_clks; 257*4882a593Smuzhiyun }; 258*4882a593Smuzhiyun 259*4882a593Smuzhiyun /* register the platform driver from the CPU DAI driver */ 260*4882a593Smuzhiyun int asoc_qcom_lpass_platform_register(struct platform_device *); 261*4882a593Smuzhiyun int asoc_qcom_lpass_cpu_platform_remove(struct platform_device *pdev); 262*4882a593Smuzhiyun int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev); 263*4882a593Smuzhiyun int asoc_qcom_lpass_cpu_dai_probe(struct snd_soc_dai *dai); 264*4882a593Smuzhiyun extern const struct snd_soc_dai_ops asoc_qcom_lpass_cpu_dai_ops; 265*4882a593Smuzhiyun 266*4882a593Smuzhiyun #endif /* __LPASS_H__ */ 267