18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright (c) 2010-2011,2013-2015,2020 The Linux Foundation. All rights reserved.
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * lpass.h - Definitions for the QTi LPASS
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#ifndef __LPASS_H__
98c2ecf20Sopenharmony_ci#define __LPASS_H__
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#include <linux/clk.h>
128c2ecf20Sopenharmony_ci#include <linux/compiler.h>
138c2ecf20Sopenharmony_ci#include <linux/platform_device.h>
148c2ecf20Sopenharmony_ci#include <linux/regmap.h>
158c2ecf20Sopenharmony_ci#include <dt-bindings/sound/qcom,lpass.h>
168c2ecf20Sopenharmony_ci#include "lpass-hdmi.h"
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_ci#define LPASS_AHBIX_CLOCK_FREQUENCY		131072000
198c2ecf20Sopenharmony_ci#define LPASS_MAX_MI2S_PORTS			(8)
208c2ecf20Sopenharmony_ci#define LPASS_MAX_DMA_CHANNELS			(8)
218c2ecf20Sopenharmony_ci#define LPASS_MAX_HDMI_DMA_CHANNELS		(4)
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci#define QCOM_REGMAP_FIELD_ALLOC(d, m, f, mf)    \
248c2ecf20Sopenharmony_ci	do { \
258c2ecf20Sopenharmony_ci		mf = devm_regmap_field_alloc(d, m, f);     \
268c2ecf20Sopenharmony_ci		if (IS_ERR(mf))                \
278c2ecf20Sopenharmony_ci			return -EINVAL;         \
288c2ecf20Sopenharmony_ci	} while (0)
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_cistruct lpaif_i2sctl {
318c2ecf20Sopenharmony_ci	struct regmap_field *loopback;
328c2ecf20Sopenharmony_ci	struct regmap_field *spken;
338c2ecf20Sopenharmony_ci	struct regmap_field *spkmode;
348c2ecf20Sopenharmony_ci	struct regmap_field *spkmono;
358c2ecf20Sopenharmony_ci	struct regmap_field *micen;
368c2ecf20Sopenharmony_ci	struct regmap_field *micmode;
378c2ecf20Sopenharmony_ci	struct regmap_field *micmono;
388c2ecf20Sopenharmony_ci	struct regmap_field *wssrc;
398c2ecf20Sopenharmony_ci	struct regmap_field *bitwidth;
408c2ecf20Sopenharmony_ci};
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_cistruct lpaif_dmactl {
448c2ecf20Sopenharmony_ci	struct regmap_field *intf;
458c2ecf20Sopenharmony_ci	struct regmap_field *bursten;
468c2ecf20Sopenharmony_ci	struct regmap_field *wpscnt;
478c2ecf20Sopenharmony_ci	struct regmap_field *fifowm;
488c2ecf20Sopenharmony_ci	struct regmap_field *enable;
498c2ecf20Sopenharmony_ci	struct regmap_field *dyncclk;
508c2ecf20Sopenharmony_ci	struct regmap_field *burst8;
518c2ecf20Sopenharmony_ci	struct regmap_field *burst16;
528c2ecf20Sopenharmony_ci	struct regmap_field *dynburst;
538c2ecf20Sopenharmony_ci};
548c2ecf20Sopenharmony_ci
558c2ecf20Sopenharmony_ci/* Both the CPU DAI and platform drivers will access this data */
568c2ecf20Sopenharmony_cistruct lpass_data {
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_ci	/* AHB-I/X bus clocks inside the low-power audio subsystem (LPASS) */
598c2ecf20Sopenharmony_ci	struct clk *ahbix_clk;
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_ci	/* MI2S system clock */
628c2ecf20Sopenharmony_ci	struct clk *mi2s_osr_clk[LPASS_MAX_MI2S_PORTS];
638c2ecf20Sopenharmony_ci
648c2ecf20Sopenharmony_ci	/* MI2S bit clock (derived from system clock by a divider */
658c2ecf20Sopenharmony_ci	struct clk *mi2s_bit_clk[LPASS_MAX_MI2S_PORTS];
668c2ecf20Sopenharmony_ci
678c2ecf20Sopenharmony_ci	/* MI2S SD lines to use for playback/capture */
688c2ecf20Sopenharmony_ci	unsigned int mi2s_playback_sd_mode[LPASS_MAX_MI2S_PORTS];
698c2ecf20Sopenharmony_ci	unsigned int mi2s_capture_sd_mode[LPASS_MAX_MI2S_PORTS];
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_ci	/* The state of MI2S prepare dai_ops was called */
728c2ecf20Sopenharmony_ci	bool mi2s_was_prepared[LPASS_MAX_MI2S_PORTS];
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ci	int hdmi_port_enable;
758c2ecf20Sopenharmony_ci
768c2ecf20Sopenharmony_ci	/* low-power audio interface (LPAIF) registers */
778c2ecf20Sopenharmony_ci	void __iomem *lpaif;
788c2ecf20Sopenharmony_ci	void __iomem *hdmiif;
798c2ecf20Sopenharmony_ci
808c2ecf20Sopenharmony_ci	/* regmap backed by the low-power audio interface (LPAIF) registers */
818c2ecf20Sopenharmony_ci	struct regmap *lpaif_map;
828c2ecf20Sopenharmony_ci	struct regmap *hdmiif_map;
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_ci	/* interrupts from the low-power audio interface (LPAIF) */
858c2ecf20Sopenharmony_ci	int lpaif_irq;
868c2ecf20Sopenharmony_ci	int hdmiif_irq;
878c2ecf20Sopenharmony_ci	/* SOC specific variations in the LPASS IP integration */
888c2ecf20Sopenharmony_ci	struct lpass_variant *variant;
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_ci	/* bit map to keep track of static channel allocations */
918c2ecf20Sopenharmony_ci	unsigned long dma_ch_bit_map;
928c2ecf20Sopenharmony_ci	unsigned long hdmi_dma_ch_bit_map;
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_ci	/* used it for handling interrupt per dma channel */
958c2ecf20Sopenharmony_ci	struct snd_pcm_substream *substream[LPASS_MAX_DMA_CHANNELS];
968c2ecf20Sopenharmony_ci	struct snd_pcm_substream *hdmi_substream[LPASS_MAX_HDMI_DMA_CHANNELS];
978c2ecf20Sopenharmony_ci
988c2ecf20Sopenharmony_ci	/* SOC specific clock list */
998c2ecf20Sopenharmony_ci	struct clk_bulk_data *clks;
1008c2ecf20Sopenharmony_ci	int num_clks;
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_ci	/* Regmap fields of I2SCTL & DMACTL registers bitfields */
1038c2ecf20Sopenharmony_ci	struct lpaif_i2sctl *i2sctl;
1048c2ecf20Sopenharmony_ci	struct lpaif_dmactl *rd_dmactl;
1058c2ecf20Sopenharmony_ci	struct lpaif_dmactl *wr_dmactl;
1068c2ecf20Sopenharmony_ci	struct lpaif_dmactl *hdmi_rd_dmactl;
1078c2ecf20Sopenharmony_ci	/* Regmap fields of HDMI_CTRL registers*/
1088c2ecf20Sopenharmony_ci	struct regmap_field *hdmitx_legacy_en;
1098c2ecf20Sopenharmony_ci	struct regmap_field *hdmitx_parity_calc_en;
1108c2ecf20Sopenharmony_ci	struct regmap_field *hdmitx_ch_msb[LPASS_MAX_HDMI_DMA_CHANNELS];
1118c2ecf20Sopenharmony_ci	struct regmap_field *hdmitx_ch_lsb[LPASS_MAX_HDMI_DMA_CHANNELS];
1128c2ecf20Sopenharmony_ci	struct lpass_hdmi_tx_ctl *tx_ctl;
1138c2ecf20Sopenharmony_ci	struct lpass_vbit_ctrl *vbit_ctl;
1148c2ecf20Sopenharmony_ci	struct lpass_hdmitx_dmactl *hdmi_tx_dmactl[LPASS_MAX_HDMI_DMA_CHANNELS];
1158c2ecf20Sopenharmony_ci	struct lpass_dp_metadata_ctl *meta_ctl;
1168c2ecf20Sopenharmony_ci	struct lpass_sstream_ctl *sstream_ctl;
1178c2ecf20Sopenharmony_ci};
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_ci/* Vairant data per each SOC */
1208c2ecf20Sopenharmony_cistruct lpass_variant {
1218c2ecf20Sopenharmony_ci	u32	irq_reg_base;
1228c2ecf20Sopenharmony_ci	u32	irq_reg_stride;
1238c2ecf20Sopenharmony_ci	u32	irq_ports;
1248c2ecf20Sopenharmony_ci	u32	rdma_reg_base;
1258c2ecf20Sopenharmony_ci	u32	rdma_reg_stride;
1268c2ecf20Sopenharmony_ci	u32	rdma_channels;
1278c2ecf20Sopenharmony_ci	u32	hdmi_rdma_reg_base;
1288c2ecf20Sopenharmony_ci	u32	hdmi_rdma_reg_stride;
1298c2ecf20Sopenharmony_ci	u32	hdmi_rdma_channels;
1308c2ecf20Sopenharmony_ci	u32	wrdma_reg_base;
1318c2ecf20Sopenharmony_ci	u32	wrdma_reg_stride;
1328c2ecf20Sopenharmony_ci	u32	wrdma_channels;
1338c2ecf20Sopenharmony_ci	u32	i2sctrl_reg_base;
1348c2ecf20Sopenharmony_ci	u32	i2sctrl_reg_stride;
1358c2ecf20Sopenharmony_ci	u32	i2s_ports;
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_ci	/* I2SCTL Register fields */
1388c2ecf20Sopenharmony_ci	struct reg_field loopback;
1398c2ecf20Sopenharmony_ci	struct reg_field spken;
1408c2ecf20Sopenharmony_ci	struct reg_field spkmode;
1418c2ecf20Sopenharmony_ci	struct reg_field spkmono;
1428c2ecf20Sopenharmony_ci	struct reg_field micen;
1438c2ecf20Sopenharmony_ci	struct reg_field micmode;
1448c2ecf20Sopenharmony_ci	struct reg_field micmono;
1458c2ecf20Sopenharmony_ci	struct reg_field wssrc;
1468c2ecf20Sopenharmony_ci	struct reg_field bitwidth;
1478c2ecf20Sopenharmony_ci
1488c2ecf20Sopenharmony_ci	u32	hdmi_irq_reg_base;
1498c2ecf20Sopenharmony_ci	u32	hdmi_irq_reg_stride;
1508c2ecf20Sopenharmony_ci	u32	hdmi_irq_ports;
1518c2ecf20Sopenharmony_ci
1528c2ecf20Sopenharmony_ci	/* HDMI specific controls */
1538c2ecf20Sopenharmony_ci	u32	hdmi_tx_ctl_addr;
1548c2ecf20Sopenharmony_ci	u32	hdmi_legacy_addr;
1558c2ecf20Sopenharmony_ci	u32	hdmi_vbit_addr;
1568c2ecf20Sopenharmony_ci	u32	hdmi_ch_lsb_addr;
1578c2ecf20Sopenharmony_ci	u32	hdmi_ch_msb_addr;
1588c2ecf20Sopenharmony_ci	u32	ch_stride;
1598c2ecf20Sopenharmony_ci	u32	hdmi_parity_addr;
1608c2ecf20Sopenharmony_ci	u32	hdmi_dmactl_addr;
1618c2ecf20Sopenharmony_ci	u32	hdmi_dma_stride;
1628c2ecf20Sopenharmony_ci	u32	hdmi_DP_addr;
1638c2ecf20Sopenharmony_ci	u32	hdmi_sstream_addr;
1648c2ecf20Sopenharmony_ci
1658c2ecf20Sopenharmony_ci	/* HDMI SSTREAM CTRL fields  */
1668c2ecf20Sopenharmony_ci	struct reg_field sstream_en;
1678c2ecf20Sopenharmony_ci	struct reg_field dma_sel;
1688c2ecf20Sopenharmony_ci	struct reg_field auto_bbit_en;
1698c2ecf20Sopenharmony_ci	struct reg_field layout;
1708c2ecf20Sopenharmony_ci	struct reg_field layout_sp;
1718c2ecf20Sopenharmony_ci	struct reg_field set_sp_on_en;
1728c2ecf20Sopenharmony_ci	struct reg_field dp_audio;
1738c2ecf20Sopenharmony_ci	struct reg_field dp_staffing_en;
1748c2ecf20Sopenharmony_ci	struct reg_field dp_sp_b_hw_en;
1758c2ecf20Sopenharmony_ci
1768c2ecf20Sopenharmony_ci	/* HDMI DP METADATA CTL fields */
1778c2ecf20Sopenharmony_ci	struct reg_field mute;
1788c2ecf20Sopenharmony_ci	struct reg_field as_sdp_cc;
1798c2ecf20Sopenharmony_ci	struct reg_field as_sdp_ct;
1808c2ecf20Sopenharmony_ci	struct reg_field aif_db4;
1818c2ecf20Sopenharmony_ci	struct reg_field frequency;
1828c2ecf20Sopenharmony_ci	struct reg_field mst_index;
1838c2ecf20Sopenharmony_ci	struct reg_field dptx_index;
1848c2ecf20Sopenharmony_ci
1858c2ecf20Sopenharmony_ci	/* HDMI TX CTRL fields */
1868c2ecf20Sopenharmony_ci	struct reg_field soft_reset;
1878c2ecf20Sopenharmony_ci	struct reg_field force_reset;
1888c2ecf20Sopenharmony_ci
1898c2ecf20Sopenharmony_ci	/* HDMI TX DMA CTRL */
1908c2ecf20Sopenharmony_ci	struct reg_field use_hw_chs;
1918c2ecf20Sopenharmony_ci	struct reg_field use_hw_usr;
1928c2ecf20Sopenharmony_ci	struct reg_field hw_chs_sel;
1938c2ecf20Sopenharmony_ci	struct reg_field hw_usr_sel;
1948c2ecf20Sopenharmony_ci
1958c2ecf20Sopenharmony_ci	/* HDMI VBIT CTRL */
1968c2ecf20Sopenharmony_ci	struct reg_field replace_vbit;
1978c2ecf20Sopenharmony_ci	struct reg_field vbit_stream;
1988c2ecf20Sopenharmony_ci
1998c2ecf20Sopenharmony_ci	/* HDMI TX LEGACY */
2008c2ecf20Sopenharmony_ci	struct reg_field legacy_en;
2018c2ecf20Sopenharmony_ci
2028c2ecf20Sopenharmony_ci	/* HDMI TX PARITY */
2038c2ecf20Sopenharmony_ci	struct reg_field calc_en;
2048c2ecf20Sopenharmony_ci
2058c2ecf20Sopenharmony_ci	/* HDMI CH LSB */
2068c2ecf20Sopenharmony_ci	struct reg_field lsb_bits;
2078c2ecf20Sopenharmony_ci
2088c2ecf20Sopenharmony_ci	/* HDMI CH MSB */
2098c2ecf20Sopenharmony_ci	struct reg_field msb_bits;
2108c2ecf20Sopenharmony_ci
2118c2ecf20Sopenharmony_ci	struct reg_field hdmi_rdma_bursten;
2128c2ecf20Sopenharmony_ci	struct reg_field hdmi_rdma_wpscnt;
2138c2ecf20Sopenharmony_ci	struct reg_field hdmi_rdma_fifowm;
2148c2ecf20Sopenharmony_ci	struct reg_field hdmi_rdma_enable;
2158c2ecf20Sopenharmony_ci	struct reg_field hdmi_rdma_dyncclk;
2168c2ecf20Sopenharmony_ci	struct reg_field hdmi_rdma_burst8;
2178c2ecf20Sopenharmony_ci	struct reg_field hdmi_rdma_burst16;
2188c2ecf20Sopenharmony_ci	struct reg_field hdmi_rdma_dynburst;
2198c2ecf20Sopenharmony_ci
2208c2ecf20Sopenharmony_ci	/* RD_DMA Register fields */
2218c2ecf20Sopenharmony_ci	struct reg_field rdma_intf;
2228c2ecf20Sopenharmony_ci	struct reg_field rdma_bursten;
2238c2ecf20Sopenharmony_ci	struct reg_field rdma_wpscnt;
2248c2ecf20Sopenharmony_ci	struct reg_field rdma_fifowm;
2258c2ecf20Sopenharmony_ci	struct reg_field rdma_enable;
2268c2ecf20Sopenharmony_ci	struct reg_field rdma_dyncclk;
2278c2ecf20Sopenharmony_ci
2288c2ecf20Sopenharmony_ci	/* WR_DMA Register fields */
2298c2ecf20Sopenharmony_ci	struct reg_field wrdma_intf;
2308c2ecf20Sopenharmony_ci	struct reg_field wrdma_bursten;
2318c2ecf20Sopenharmony_ci	struct reg_field wrdma_wpscnt;
2328c2ecf20Sopenharmony_ci	struct reg_field wrdma_fifowm;
2338c2ecf20Sopenharmony_ci	struct reg_field wrdma_enable;
2348c2ecf20Sopenharmony_ci	struct reg_field wrdma_dyncclk;
2358c2ecf20Sopenharmony_ci
2368c2ecf20Sopenharmony_ci	/**
2378c2ecf20Sopenharmony_ci	 * on SOCs like APQ8016 the channel control bits start
2388c2ecf20Sopenharmony_ci	 * at different offset to ipq806x
2398c2ecf20Sopenharmony_ci	 **/
2408c2ecf20Sopenharmony_ci	u32	dmactl_audif_start;
2418c2ecf20Sopenharmony_ci	u32	wrdma_channel_start;
2428c2ecf20Sopenharmony_ci	/* SOC specific initialization like clocks */
2438c2ecf20Sopenharmony_ci	int (*init)(struct platform_device *pdev);
2448c2ecf20Sopenharmony_ci	int (*exit)(struct platform_device *pdev);
2458c2ecf20Sopenharmony_ci	int (*alloc_dma_channel)(struct lpass_data *data, int direction, unsigned int dai_id);
2468c2ecf20Sopenharmony_ci	int (*free_dma_channel)(struct lpass_data *data, int ch, unsigned int dai_id);
2478c2ecf20Sopenharmony_ci
2488c2ecf20Sopenharmony_ci	/* SOC specific dais */
2498c2ecf20Sopenharmony_ci	struct snd_soc_dai_driver *dai_driver;
2508c2ecf20Sopenharmony_ci	int num_dai;
2518c2ecf20Sopenharmony_ci	const char * const *dai_osr_clk_names;
2528c2ecf20Sopenharmony_ci	const char * const *dai_bit_clk_names;
2538c2ecf20Sopenharmony_ci
2548c2ecf20Sopenharmony_ci	/* SOC specific clocks configuration */
2558c2ecf20Sopenharmony_ci	const char **clk_name;
2568c2ecf20Sopenharmony_ci	int num_clks;
2578c2ecf20Sopenharmony_ci};
2588c2ecf20Sopenharmony_ci
2598c2ecf20Sopenharmony_ci/* register the platform driver from the CPU DAI driver */
2608c2ecf20Sopenharmony_ciint asoc_qcom_lpass_platform_register(struct platform_device *);
2618c2ecf20Sopenharmony_ciint asoc_qcom_lpass_cpu_platform_remove(struct platform_device *pdev);
2628c2ecf20Sopenharmony_ciint asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev);
2638c2ecf20Sopenharmony_ciint asoc_qcom_lpass_cpu_dai_probe(struct snd_soc_dai *dai);
2648c2ecf20Sopenharmony_ciextern const struct snd_soc_dai_ops asoc_qcom_lpass_cpu_dai_ops;
2658c2ecf20Sopenharmony_ci
2668c2ecf20Sopenharmony_ci#endif /* __LPASS_H__ */
267