xref: /OK3568_Linux_fs/kernel/drivers/soundwire/cadence_master.h (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
2*4882a593Smuzhiyun /* Copyright(c) 2015-17 Intel Corporation. */
3*4882a593Smuzhiyun #include <sound/soc.h>
4*4882a593Smuzhiyun 
5*4882a593Smuzhiyun #ifndef __SDW_CADENCE_H
6*4882a593Smuzhiyun #define __SDW_CADENCE_H
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #define SDW_CADENCE_GSYNC_KHZ		4 /* 4 kHz */
9*4882a593Smuzhiyun #define SDW_CADENCE_GSYNC_HZ		(SDW_CADENCE_GSYNC_KHZ * 1000)
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun /**
12*4882a593Smuzhiyun  * struct sdw_cdns_pdi: PDI (Physical Data Interface) instance
13*4882a593Smuzhiyun  *
14*4882a593Smuzhiyun  * @num: pdi number
15*4882a593Smuzhiyun  * @intel_alh_id: link identifier
16*4882a593Smuzhiyun  * @l_ch_num: low channel for PDI
17*4882a593Smuzhiyun  * @h_ch_num: high channel for PDI
18*4882a593Smuzhiyun  * @ch_count: total channel count for PDI
19*4882a593Smuzhiyun  * @dir: data direction
20*4882a593Smuzhiyun  * @type: stream type, PDM or PCM
21*4882a593Smuzhiyun  */
22*4882a593Smuzhiyun struct sdw_cdns_pdi {
23*4882a593Smuzhiyun 	int num;
24*4882a593Smuzhiyun 	int intel_alh_id;
25*4882a593Smuzhiyun 	int l_ch_num;
26*4882a593Smuzhiyun 	int h_ch_num;
27*4882a593Smuzhiyun 	int ch_count;
28*4882a593Smuzhiyun 	enum sdw_data_direction dir;
29*4882a593Smuzhiyun 	enum sdw_stream_type type;
30*4882a593Smuzhiyun };
31*4882a593Smuzhiyun 
32*4882a593Smuzhiyun /**
33*4882a593Smuzhiyun  * struct sdw_cdns_streams: Cadence stream data structure
34*4882a593Smuzhiyun  *
35*4882a593Smuzhiyun  * @num_bd: number of bidirectional streams
36*4882a593Smuzhiyun  * @num_in: number of input streams
37*4882a593Smuzhiyun  * @num_out: number of output streams
38*4882a593Smuzhiyun  * @num_ch_bd: number of bidirectional stream channels
39*4882a593Smuzhiyun  * @num_ch_bd: number of input stream channels
40*4882a593Smuzhiyun  * @num_ch_bd: number of output stream channels
41*4882a593Smuzhiyun  * @num_pdi: total number of PDIs
42*4882a593Smuzhiyun  * @bd: bidirectional streams
43*4882a593Smuzhiyun  * @in: input streams
44*4882a593Smuzhiyun  * @out: output streams
45*4882a593Smuzhiyun  */
46*4882a593Smuzhiyun struct sdw_cdns_streams {
47*4882a593Smuzhiyun 	unsigned int num_bd;
48*4882a593Smuzhiyun 	unsigned int num_in;
49*4882a593Smuzhiyun 	unsigned int num_out;
50*4882a593Smuzhiyun 	unsigned int num_ch_bd;
51*4882a593Smuzhiyun 	unsigned int num_ch_in;
52*4882a593Smuzhiyun 	unsigned int num_ch_out;
53*4882a593Smuzhiyun 	unsigned int num_pdi;
54*4882a593Smuzhiyun 	struct sdw_cdns_pdi *bd;
55*4882a593Smuzhiyun 	struct sdw_cdns_pdi *in;
56*4882a593Smuzhiyun 	struct sdw_cdns_pdi *out;
57*4882a593Smuzhiyun };
58*4882a593Smuzhiyun 
59*4882a593Smuzhiyun /**
60*4882a593Smuzhiyun  * struct sdw_cdns_stream_config: stream configuration
61*4882a593Smuzhiyun  *
62*4882a593Smuzhiyun  * @pcm_bd: number of bidirectional PCM streams supported
63*4882a593Smuzhiyun  * @pcm_in: number of input PCM streams supported
64*4882a593Smuzhiyun  * @pcm_out: number of output PCM streams supported
65*4882a593Smuzhiyun  * @pdm_bd: number of bidirectional PDM streams supported
66*4882a593Smuzhiyun  * @pdm_in: number of input PDM streams supported
67*4882a593Smuzhiyun  * @pdm_out: number of output PDM streams supported
68*4882a593Smuzhiyun  */
69*4882a593Smuzhiyun struct sdw_cdns_stream_config {
70*4882a593Smuzhiyun 	unsigned int pcm_bd;
71*4882a593Smuzhiyun 	unsigned int pcm_in;
72*4882a593Smuzhiyun 	unsigned int pcm_out;
73*4882a593Smuzhiyun 	unsigned int pdm_bd;
74*4882a593Smuzhiyun 	unsigned int pdm_in;
75*4882a593Smuzhiyun 	unsigned int pdm_out;
76*4882a593Smuzhiyun };
77*4882a593Smuzhiyun 
78*4882a593Smuzhiyun /**
79*4882a593Smuzhiyun  * struct sdw_cdns_dma_data: Cadence DMA data
80*4882a593Smuzhiyun  *
81*4882a593Smuzhiyun  * @name: SoundWire stream name
82*4882a593Smuzhiyun  * @stream: stream runtime
83*4882a593Smuzhiyun  * @pdi: PDI used for this dai
84*4882a593Smuzhiyun  * @bus: Bus handle
85*4882a593Smuzhiyun  * @stream_type: Stream type
86*4882a593Smuzhiyun  * @link_id: Master link id
87*4882a593Smuzhiyun  * @hw_params: hw_params to be applied in .prepare step
88*4882a593Smuzhiyun  * @suspended: status set when suspended, to be used in .prepare
89*4882a593Smuzhiyun  */
90*4882a593Smuzhiyun struct sdw_cdns_dma_data {
91*4882a593Smuzhiyun 	char *name;
92*4882a593Smuzhiyun 	struct sdw_stream_runtime *stream;
93*4882a593Smuzhiyun 	struct sdw_cdns_pdi *pdi;
94*4882a593Smuzhiyun 	struct sdw_bus *bus;
95*4882a593Smuzhiyun 	enum sdw_stream_type stream_type;
96*4882a593Smuzhiyun 	int link_id;
97*4882a593Smuzhiyun 	struct snd_pcm_hw_params *hw_params;
98*4882a593Smuzhiyun 	bool suspended;
99*4882a593Smuzhiyun };
100*4882a593Smuzhiyun 
101*4882a593Smuzhiyun /**
102*4882a593Smuzhiyun  * struct sdw_cdns - Cadence driver context
103*4882a593Smuzhiyun  * @dev: Linux device
104*4882a593Smuzhiyun  * @bus: Bus handle
105*4882a593Smuzhiyun  * @instance: instance number
106*4882a593Smuzhiyun  * @response_buf: SoundWire response buffer
107*4882a593Smuzhiyun  * @tx_complete: Tx completion
108*4882a593Smuzhiyun  * @defer: Defer pointer
109*4882a593Smuzhiyun  * @ports: Data ports
110*4882a593Smuzhiyun  * @num_ports: Total number of data ports
111*4882a593Smuzhiyun  * @pcm: PCM streams
112*4882a593Smuzhiyun  * @pdm: PDM streams
113*4882a593Smuzhiyun  * @registers: Cadence registers
114*4882a593Smuzhiyun  * @link_up: Link status
115*4882a593Smuzhiyun  * @msg_count: Messages sent on bus
116*4882a593Smuzhiyun  */
117*4882a593Smuzhiyun struct sdw_cdns {
118*4882a593Smuzhiyun 	struct device *dev;
119*4882a593Smuzhiyun 	struct sdw_bus bus;
120*4882a593Smuzhiyun 	unsigned int instance;
121*4882a593Smuzhiyun 
122*4882a593Smuzhiyun 	u32 response_buf[0x80];
123*4882a593Smuzhiyun 	struct completion tx_complete;
124*4882a593Smuzhiyun 	struct sdw_defer *defer;
125*4882a593Smuzhiyun 
126*4882a593Smuzhiyun 	struct sdw_cdns_port *ports;
127*4882a593Smuzhiyun 	int num_ports;
128*4882a593Smuzhiyun 
129*4882a593Smuzhiyun 	struct sdw_cdns_streams pcm;
130*4882a593Smuzhiyun 	struct sdw_cdns_streams pdm;
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun 	void __iomem *registers;
133*4882a593Smuzhiyun 
134*4882a593Smuzhiyun 	bool link_up;
135*4882a593Smuzhiyun 	unsigned int msg_count;
136*4882a593Smuzhiyun 	bool interrupt_enabled;
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun 	struct work_struct work;
139*4882a593Smuzhiyun 
140*4882a593Smuzhiyun 	struct list_head list;
141*4882a593Smuzhiyun };
142*4882a593Smuzhiyun 
143*4882a593Smuzhiyun #define bus_to_cdns(_bus) container_of(_bus, struct sdw_cdns, bus)
144*4882a593Smuzhiyun 
145*4882a593Smuzhiyun /* Exported symbols */
146*4882a593Smuzhiyun 
147*4882a593Smuzhiyun int sdw_cdns_probe(struct sdw_cdns *cdns);
148*4882a593Smuzhiyun extern struct sdw_master_ops sdw_cdns_master_ops;
149*4882a593Smuzhiyun 
150*4882a593Smuzhiyun irqreturn_t sdw_cdns_irq(int irq, void *dev_id);
151*4882a593Smuzhiyun irqreturn_t sdw_cdns_thread(int irq, void *dev_id);
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun int sdw_cdns_init(struct sdw_cdns *cdns);
154*4882a593Smuzhiyun int sdw_cdns_pdi_init(struct sdw_cdns *cdns,
155*4882a593Smuzhiyun 		      struct sdw_cdns_stream_config config);
156*4882a593Smuzhiyun int sdw_cdns_exit_reset(struct sdw_cdns *cdns);
157*4882a593Smuzhiyun int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns, bool state);
158*4882a593Smuzhiyun 
159*4882a593Smuzhiyun bool sdw_cdns_is_clock_stop(struct sdw_cdns *cdns);
160*4882a593Smuzhiyun int sdw_cdns_clock_stop(struct sdw_cdns *cdns, bool block_wake);
161*4882a593Smuzhiyun int sdw_cdns_clock_restart(struct sdw_cdns *cdns, bool bus_reset);
162*4882a593Smuzhiyun 
163*4882a593Smuzhiyun #ifdef CONFIG_DEBUG_FS
164*4882a593Smuzhiyun void sdw_cdns_debugfs_init(struct sdw_cdns *cdns, struct dentry *root);
165*4882a593Smuzhiyun #endif
166*4882a593Smuzhiyun 
167*4882a593Smuzhiyun struct sdw_cdns_pdi *sdw_cdns_alloc_pdi(struct sdw_cdns *cdns,
168*4882a593Smuzhiyun 					struct sdw_cdns_streams *stream,
169*4882a593Smuzhiyun 					u32 ch, u32 dir, int dai_id);
170*4882a593Smuzhiyun void sdw_cdns_config_stream(struct sdw_cdns *cdns,
171*4882a593Smuzhiyun 			    u32 ch, u32 dir, struct sdw_cdns_pdi *pdi);
172*4882a593Smuzhiyun 
173*4882a593Smuzhiyun enum sdw_command_response
174*4882a593Smuzhiyun cdns_reset_page_addr(struct sdw_bus *bus, unsigned int dev_num);
175*4882a593Smuzhiyun 
176*4882a593Smuzhiyun enum sdw_command_response
177*4882a593Smuzhiyun cdns_xfer_msg(struct sdw_bus *bus, struct sdw_msg *msg);
178*4882a593Smuzhiyun 
179*4882a593Smuzhiyun enum sdw_command_response
180*4882a593Smuzhiyun cdns_xfer_msg_defer(struct sdw_bus *bus,
181*4882a593Smuzhiyun 		    struct sdw_msg *msg, struct sdw_defer *defer);
182*4882a593Smuzhiyun 
183*4882a593Smuzhiyun enum sdw_command_response
184*4882a593Smuzhiyun cdns_reset_page_addr(struct sdw_bus *bus, unsigned int dev_num);
185*4882a593Smuzhiyun 
186*4882a593Smuzhiyun int cdns_bus_conf(struct sdw_bus *bus, struct sdw_bus_params *params);
187*4882a593Smuzhiyun 
188*4882a593Smuzhiyun int cdns_set_sdw_stream(struct snd_soc_dai *dai,
189*4882a593Smuzhiyun 			void *stream, bool pcm, int direction);
190*4882a593Smuzhiyun #endif /* __SDW_CADENCE_H */
191