Commit | Line | Data |
---|---|---|
23859465 PLB |
1 | /* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */ |
2 | /* Copyright(c) 2015-17 Intel Corporation. */ | |
5d6b3c8b | 3 | #include <sound/soc.h> |
2f52a517 VK |
4 | |
5 | #ifndef __SDW_CADENCE_H | |
6 | #define __SDW_CADENCE_H | |
7 | ||
1dd6a17f PLB |
8 | #define SDW_CADENCE_GSYNC_KHZ 4 /* 4 kHz */ |
9 | #define SDW_CADENCE_GSYNC_HZ (SDW_CADENCE_GSYNC_KHZ * 1000) | |
10 | ||
827c32d0 RF |
11 | /* |
12 | * The Cadence IP supports up to 32 entries in the FIFO, though implementations | |
13 | * can configure the IP to have a smaller FIFO. | |
14 | */ | |
15 | #define CDNS_MCP_IP_MAX_CMD_LEN 32 | |
16 | ||
07abeff1 VK |
17 | /** |
18 | * struct sdw_cdns_pdi: PDI (Physical Data Interface) instance | |
19 | * | |
07abeff1 VK |
20 | * @num: pdi number |
21 | * @intel_alh_id: link identifier | |
22 | * @l_ch_num: low channel for PDI | |
23 | * @h_ch_num: high channel for PDI | |
24 | * @ch_count: total channel count for PDI | |
25 | * @dir: data direction | |
63a6aa96 | 26 | * @type: stream type, (only PCM supported) |
07abeff1 VK |
27 | */ |
28 | struct sdw_cdns_pdi { | |
07abeff1 VK |
29 | int num; |
30 | int intel_alh_id; | |
31 | int l_ch_num; | |
32 | int h_ch_num; | |
33 | int ch_count; | |
34 | enum sdw_data_direction dir; | |
35 | enum sdw_stream_type type; | |
36 | }; | |
37 | ||
07abeff1 VK |
38 | /** |
39 | * struct sdw_cdns_streams: Cadence stream data structure | |
40 | * | |
41 | * @num_bd: number of bidirectional streams | |
42 | * @num_in: number of input streams | |
43 | * @num_out: number of output streams | |
44 | * @num_ch_bd: number of bidirectional stream channels | |
45 | * @num_ch_bd: number of input stream channels | |
46 | * @num_ch_bd: number of output stream channels | |
47 | * @num_pdi: total number of PDIs | |
48 | * @bd: bidirectional streams | |
49 | * @in: input streams | |
50 | * @out: output streams | |
51 | */ | |
52 | struct sdw_cdns_streams { | |
53 | unsigned int num_bd; | |
54 | unsigned int num_in; | |
55 | unsigned int num_out; | |
56 | unsigned int num_ch_bd; | |
57 | unsigned int num_ch_in; | |
58 | unsigned int num_ch_out; | |
59 | unsigned int num_pdi; | |
60 | struct sdw_cdns_pdi *bd; | |
61 | struct sdw_cdns_pdi *in; | |
62 | struct sdw_cdns_pdi *out; | |
63 | }; | |
64 | ||
65 | /** | |
66 | * struct sdw_cdns_stream_config: stream configuration | |
67 | * | |
68 | * @pcm_bd: number of bidirectional PCM streams supported | |
69 | * @pcm_in: number of input PCM streams supported | |
70 | * @pcm_out: number of output PCM streams supported | |
07abeff1 VK |
71 | */ |
72 | struct sdw_cdns_stream_config { | |
73 | unsigned int pcm_bd; | |
74 | unsigned int pcm_in; | |
75 | unsigned int pcm_out; | |
07abeff1 VK |
76 | }; |
77 | ||
5d6b3c8b | 78 | /** |
e0767e39 | 79 | * struct sdw_cdns_dai_runtime: Cadence DAI runtime data |
5d6b3c8b VK |
80 | * |
81 | * @name: SoundWire stream name | |
57a34790 PLB |
82 | * @stream: stream runtime |
83 | * @pdi: PDI used for this dai | |
5d6b3c8b VK |
84 | * @bus: Bus handle |
85 | * @stream_type: Stream type | |
86 | * @link_id: Master link id | |
a5a0239c | 87 | * @suspended: status set when suspended, to be used in .prepare |
8ddeafb9 | 88 | * @paused: status set in .trigger, to be used in suspend |
7dddead7 | 89 | * @direction: stream direction |
5d6b3c8b | 90 | */ |
e0767e39 | 91 | struct sdw_cdns_dai_runtime { |
5d6b3c8b VK |
92 | char *name; |
93 | struct sdw_stream_runtime *stream; | |
57a34790 | 94 | struct sdw_cdns_pdi *pdi; |
5d6b3c8b VK |
95 | struct sdw_bus *bus; |
96 | enum sdw_stream_type stream_type; | |
97 | int link_id; | |
a5a0239c | 98 | bool suspended; |
8ddeafb9 | 99 | bool paused; |
7dddead7 | 100 | int direction; |
5d6b3c8b VK |
101 | }; |
102 | ||
2f52a517 VK |
103 | /** |
104 | * struct sdw_cdns - Cadence driver context | |
105 | * @dev: Linux device | |
106 | * @bus: Bus handle | |
107 | * @instance: instance number | |
9402e25d | 108 | * @ip_offset: version-dependent offset to access IP_MCP registers and fields |
956baa19 SK |
109 | * @response_buf: SoundWire response buffer |
110 | * @tx_complete: Tx completion | |
07abeff1 VK |
111 | * @ports: Data ports |
112 | * @num_ports: Total number of data ports | |
113 | * @pcm: PCM streams | |
2f52a517 VK |
114 | * @registers: Cadence registers |
115 | * @link_up: Link status | |
956baa19 | 116 | * @msg_count: Messages sent on bus |
7dddead7 | 117 | * @dai_runtime_array: runtime context for each allocated DAI. |
2f52a517 VK |
118 | */ |
119 | struct sdw_cdns { | |
120 | struct device *dev; | |
121 | struct sdw_bus bus; | |
122 | unsigned int instance; | |
123 | ||
9402e25d PLB |
124 | u32 ip_offset; |
125 | ||
827c32d0 RF |
126 | /* |
127 | * The datasheet says the RX FIFO AVAIL can be 2 entries more | |
128 | * than the FIFO capacity, so allow for this. | |
129 | */ | |
130 | u32 response_buf[CDNS_MCP_IP_MAX_CMD_LEN + 2]; | |
131 | ||
956baa19 | 132 | struct completion tx_complete; |
956baa19 | 133 | |
07abeff1 VK |
134 | struct sdw_cdns_port *ports; |
135 | int num_ports; | |
136 | ||
137 | struct sdw_cdns_streams pcm; | |
07abeff1 | 138 | |
8fba8acd PLB |
139 | int pdi_loopback_source; |
140 | int pdi_loopback_target; | |
141 | ||
2f52a517 VK |
142 | void __iomem *registers; |
143 | ||
144 | bool link_up; | |
956baa19 | 145 | unsigned int msg_count; |
d2068da5 | 146 | bool interrupt_enabled; |
4a98a6b2 BL |
147 | |
148 | struct work_struct work; | |
149 | ||
150 | struct list_head list; | |
7dddead7 PLB |
151 | |
152 | struct sdw_cdns_dai_runtime **dai_runtime_array; | |
2f52a517 VK |
153 | }; |
154 | ||
155 | #define bus_to_cdns(_bus) container_of(_bus, struct sdw_cdns, bus) | |
156 | ||
157 | /* Exported symbols */ | |
158 | ||
956baa19 | 159 | int sdw_cdns_probe(struct sdw_cdns *cdns); |
956baa19 | 160 | |
2f52a517 VK |
161 | irqreturn_t sdw_cdns_irq(int irq, void *dev_id); |
162 | irqreturn_t sdw_cdns_thread(int irq, void *dev_id); | |
163 | ||
7b174f24 | 164 | int sdw_cdns_init(struct sdw_cdns *cdns); |
07abeff1 | 165 | int sdw_cdns_pdi_init(struct sdw_cdns *cdns, |
806a11f0 | 166 | struct sdw_cdns_stream_config config); |
49ea07d3 | 167 | int sdw_cdns_exit_reset(struct sdw_cdns *cdns); |
9e3d47fb | 168 | int sdw_cdns_enable_interrupt(struct sdw_cdns *cdns, bool state); |
956baa19 | 169 | |
5a885c52 | 170 | bool sdw_cdns_is_clock_stop(struct sdw_cdns *cdns); |
1032504f RW |
171 | int sdw_cdns_clock_stop(struct sdw_cdns *cdns, bool block_wake); |
172 | int sdw_cdns_clock_restart(struct sdw_cdns *cdns, bool bus_reset); | |
5a885c52 | 173 | |
aa85066e PLB |
174 | #ifdef CONFIG_DEBUG_FS |
175 | void sdw_cdns_debugfs_init(struct sdw_cdns *cdns, struct dentry *root); | |
176 | #endif | |
177 | ||
57a34790 PLB |
178 | struct sdw_cdns_pdi *sdw_cdns_alloc_pdi(struct sdw_cdns *cdns, |
179 | struct sdw_cdns_streams *stream, | |
1b53385e | 180 | u32 ch, u32 dir, int dai_id); |
57a34790 | 181 | void sdw_cdns_config_stream(struct sdw_cdns *cdns, |
806a11f0 | 182 | u32 ch, u32 dir, struct sdw_cdns_pdi *pdi); |
5d6b3c8b | 183 | |
c91605f4 SN |
184 | enum sdw_command_response |
185 | cdns_xfer_msg(struct sdw_bus *bus, struct sdw_msg *msg); | |
2f52a517 | 186 | |
c91605f4 | 187 | enum sdw_command_response |
66f95de7 | 188 | cdns_xfer_msg_defer(struct sdw_bus *bus); |
c91605f4 | 189 | |
133547a1 PLB |
190 | u32 cdns_read_ping_status(struct sdw_bus *bus); |
191 | ||
07abeff1 | 192 | int cdns_bus_conf(struct sdw_bus *bus, struct sdw_bus_params *params); |
5d6b3c8b VK |
193 | |
194 | int cdns_set_sdw_stream(struct snd_soc_dai *dai, | |
63a6aa96 | 195 | void *stream, int direction); |
ff560946 PLB |
196 | |
197 | void sdw_cdns_check_self_clearing_bits(struct sdw_cdns *cdns, const char *string, | |
198 | bool initial_delay, int reset_iterations); | |
199 | ||
2f52a517 | 200 | #endif /* __SDW_CADENCE_H */ |