GNU Linux-libre 5.19-rc6-gnu
[releases.git] / sound / soc / codecs / wcd938x-sdw.c
1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2021, Linaro Limited
3
4 #include <linux/module.h>
5 #include <linux/slab.h>
6 #include <linux/platform_device.h>
7 #include <linux/device.h>
8 #include <linux/kernel.h>
9 #include <linux/component.h>
10 #include <linux/pm_runtime.h>
11 #include <linux/irq.h>
12 #include <linux/irqdomain.h>
13 #include <linux/of.h>
14 #include <linux/soundwire/sdw.h>
15 #include <linux/soundwire/sdw_type.h>
16 #include <linux/soundwire/sdw_registers.h>
17 #include <linux/regmap.h>
18 #include <sound/soc.h>
19 #include <sound/soc-dapm.h>
20 #include "wcd938x.h"
21
22 #define SWRS_SCP_HOST_CLK_DIV2_CTL_BANK(m) (0xE0 + 0x10 * (m))
23
24 static struct wcd938x_sdw_ch_info wcd938x_sdw_rx_ch_info[] = {
25         WCD_SDW_CH(WCD938X_HPH_L, WCD938X_HPH_PORT, BIT(0)),
26         WCD_SDW_CH(WCD938X_HPH_R, WCD938X_HPH_PORT, BIT(1)),
27         WCD_SDW_CH(WCD938X_CLSH, WCD938X_CLSH_PORT, BIT(0)),
28         WCD_SDW_CH(WCD938X_COMP_L, WCD938X_COMP_PORT, BIT(0)),
29         WCD_SDW_CH(WCD938X_COMP_R, WCD938X_COMP_PORT, BIT(1)),
30         WCD_SDW_CH(WCD938X_LO, WCD938X_LO_PORT, BIT(0)),
31         WCD_SDW_CH(WCD938X_DSD_L, WCD938X_DSD_PORT, BIT(0)),
32         WCD_SDW_CH(WCD938X_DSD_R, WCD938X_DSD_PORT, BIT(1)),
33 };
34
35 static struct wcd938x_sdw_ch_info wcd938x_sdw_tx_ch_info[] = {
36         WCD_SDW_CH(WCD938X_ADC1, WCD938X_ADC_1_2_PORT, BIT(0)),
37         WCD_SDW_CH(WCD938X_ADC2, WCD938X_ADC_1_2_PORT, BIT(1)),
38         WCD_SDW_CH(WCD938X_ADC3, WCD938X_ADC_3_4_PORT, BIT(0)),
39         WCD_SDW_CH(WCD938X_ADC4, WCD938X_ADC_3_4_PORT, BIT(1)),
40         WCD_SDW_CH(WCD938X_DMIC0, WCD938X_DMIC_0_3_MBHC_PORT, BIT(0)),
41         WCD_SDW_CH(WCD938X_DMIC1, WCD938X_DMIC_0_3_MBHC_PORT, BIT(1)),
42         WCD_SDW_CH(WCD938X_MBHC, WCD938X_DMIC_0_3_MBHC_PORT, BIT(2)),
43         WCD_SDW_CH(WCD938X_DMIC2, WCD938X_DMIC_0_3_MBHC_PORT, BIT(2)),
44         WCD_SDW_CH(WCD938X_DMIC3, WCD938X_DMIC_0_3_MBHC_PORT, BIT(3)),
45         WCD_SDW_CH(WCD938X_DMIC4, WCD938X_DMIC_4_7_PORT, BIT(0)),
46         WCD_SDW_CH(WCD938X_DMIC5, WCD938X_DMIC_4_7_PORT, BIT(1)),
47         WCD_SDW_CH(WCD938X_DMIC6, WCD938X_DMIC_4_7_PORT, BIT(2)),
48         WCD_SDW_CH(WCD938X_DMIC7, WCD938X_DMIC_4_7_PORT, BIT(3)),
49 };
50
51 static struct sdw_dpn_prop wcd938x_dpn_prop[WCD938X_MAX_SWR_PORTS] = {
52         {
53                 .num = 1,
54                 .type = SDW_DPN_SIMPLE,
55                 .min_ch = 1,
56                 .max_ch = 8,
57                 .simple_ch_prep_sm = true,
58         }, {
59                 .num = 2,
60                 .type = SDW_DPN_SIMPLE,
61                 .min_ch = 1,
62                 .max_ch = 4,
63                 .simple_ch_prep_sm = true,
64         }, {
65                 .num = 3,
66                 .type = SDW_DPN_SIMPLE,
67                 .min_ch = 1,
68                 .max_ch = 4,
69                 .simple_ch_prep_sm = true,
70         }, {
71                 .num = 4,
72                 .type = SDW_DPN_SIMPLE,
73                 .min_ch = 1,
74                 .max_ch = 4,
75                 .simple_ch_prep_sm = true,
76         }, {
77                 .num = 5,
78                 .type = SDW_DPN_SIMPLE,
79                 .min_ch = 1,
80                 .max_ch = 4,
81                 .simple_ch_prep_sm = true,
82         }
83 };
84
85 struct device *wcd938x_sdw_device_get(struct device_node *np)
86 {
87         return bus_find_device_by_of_node(&sdw_bus_type, np);
88
89 }
90 EXPORT_SYMBOL_GPL(wcd938x_sdw_device_get);
91
92 int wcd938x_swr_get_current_bank(struct sdw_slave *sdev)
93 {
94         int bank;
95
96         bank  = sdw_read(sdev, SDW_SCP_CTRL);
97
98         return ((bank & 0x40) ? 1 : 0);
99 }
100 EXPORT_SYMBOL_GPL(wcd938x_swr_get_current_bank);
101
102 int wcd938x_sdw_hw_params(struct wcd938x_sdw_priv *wcd,
103                           struct snd_pcm_substream *substream,
104                           struct snd_pcm_hw_params *params,
105                           struct snd_soc_dai *dai)
106 {
107         struct sdw_port_config port_config[WCD938X_MAX_SWR_PORTS];
108         unsigned long ch_mask;
109         int i, j;
110
111         wcd->sconfig.ch_count = 1;
112         wcd->active_ports = 0;
113         for (i = 0; i < WCD938X_MAX_SWR_PORTS; i++) {
114                 ch_mask = wcd->port_config[i].ch_mask;
115
116                 if (!ch_mask)
117                         continue;
118
119                 for_each_set_bit(j, &ch_mask, 4)
120                         wcd->sconfig.ch_count++;
121
122                 port_config[wcd->active_ports] = wcd->port_config[i];
123                 wcd->active_ports++;
124         }
125
126         wcd->sconfig.bps = 1;
127         wcd->sconfig.frame_rate =  params_rate(params);
128         if (wcd->is_tx)
129                 wcd->sconfig.direction = SDW_DATA_DIR_TX;
130         else
131                 wcd->sconfig.direction = SDW_DATA_DIR_RX;
132
133         wcd->sconfig.type = SDW_STREAM_PCM;
134
135         return sdw_stream_add_slave(wcd->sdev, &wcd->sconfig,
136                                     &port_config[0], wcd->active_ports,
137                                     wcd->sruntime);
138 }
139 EXPORT_SYMBOL_GPL(wcd938x_sdw_hw_params);
140
141 int wcd938x_sdw_free(struct wcd938x_sdw_priv *wcd,
142                      struct snd_pcm_substream *substream,
143                      struct snd_soc_dai *dai)
144 {
145         sdw_stream_remove_slave(wcd->sdev, wcd->sruntime);
146
147         return 0;
148 }
149 EXPORT_SYMBOL_GPL(wcd938x_sdw_free);
150
151 int wcd938x_sdw_set_sdw_stream(struct wcd938x_sdw_priv *wcd,
152                                struct snd_soc_dai *dai,
153                                void *stream, int direction)
154 {
155         wcd->sruntime = stream;
156
157         return 0;
158 }
159 EXPORT_SYMBOL_GPL(wcd938x_sdw_set_sdw_stream);
160
161 static int wcd9380_update_status(struct sdw_slave *slave,
162                                  enum sdw_slave_status status)
163 {
164         return 0;
165 }
166
167 static int wcd9380_bus_config(struct sdw_slave *slave,
168                               struct sdw_bus_params *params)
169 {
170         sdw_write(slave, SWRS_SCP_HOST_CLK_DIV2_CTL_BANK(params->next_bank),  0x01);
171
172         return 0;
173 }
174
175 static int wcd9380_interrupt_callback(struct sdw_slave *slave,
176                                       struct sdw_slave_intr_status *status)
177 {
178         struct wcd938x_sdw_priv *wcd = dev_get_drvdata(&slave->dev);
179         struct irq_domain *slave_irq = wcd->slave_irq;
180         struct regmap *regmap = dev_get_regmap(&slave->dev, NULL);
181         u32 sts1, sts2, sts3;
182
183         do {
184                 handle_nested_irq(irq_find_mapping(slave_irq, 0));
185                 regmap_read(regmap, WCD938X_DIGITAL_INTR_STATUS_0, &sts1);
186                 regmap_read(regmap, WCD938X_DIGITAL_INTR_STATUS_1, &sts2);
187                 regmap_read(regmap, WCD938X_DIGITAL_INTR_STATUS_2, &sts3);
188
189         } while (sts1 || sts2 || sts3);
190
191         return IRQ_HANDLED;
192 }
193
194 static struct sdw_slave_ops wcd9380_slave_ops = {
195         .update_status = wcd9380_update_status,
196         .interrupt_callback = wcd9380_interrupt_callback,
197         .bus_config = wcd9380_bus_config,
198 };
199
200 static int wcd938x_sdw_component_bind(struct device *dev,
201                                       struct device *master, void *data)
202 {
203         return 0;
204 }
205
206 static void wcd938x_sdw_component_unbind(struct device *dev,
207                                          struct device *master, void *data)
208 {
209 }
210
211 static const struct component_ops wcd938x_sdw_component_ops = {
212         .bind   = wcd938x_sdw_component_bind,
213         .unbind = wcd938x_sdw_component_unbind,
214 };
215
216 static int wcd9380_probe(struct sdw_slave *pdev,
217                          const struct sdw_device_id *id)
218 {
219         struct device *dev = &pdev->dev;
220         struct wcd938x_sdw_priv *wcd;
221         int ret;
222
223         wcd = devm_kzalloc(dev, sizeof(*wcd), GFP_KERNEL);
224         if (!wcd)
225                 return -ENOMEM;
226
227         /**
228          * Port map index starts with 0, however the data port for this codec
229          * are from index 1
230          */
231         if (of_property_read_bool(dev->of_node, "qcom,tx-port-mapping")) {
232                 wcd->is_tx = true;
233                 ret = of_property_read_u32_array(dev->of_node, "qcom,tx-port-mapping",
234                                                  &pdev->m_port_map[1],
235                                                  WCD938X_MAX_TX_SWR_PORTS);
236         } else {
237                 ret = of_property_read_u32_array(dev->of_node, "qcom,rx-port-mapping",
238                                                  &pdev->m_port_map[1],
239                                                  WCD938X_MAX_SWR_PORTS);
240         }
241
242         if (ret < 0)
243                 dev_info(dev, "Static Port mapping not specified\n");
244
245         wcd->sdev = pdev;
246         dev_set_drvdata(dev, wcd);
247
248         pdev->prop.scp_int1_mask = SDW_SCP_INT1_IMPL_DEF |
249                                         SDW_SCP_INT1_BUS_CLASH |
250                                         SDW_SCP_INT1_PARITY;
251         pdev->prop.lane_control_support = true;
252         pdev->prop.simple_clk_stop_capable = true;
253         if (wcd->is_tx) {
254                 pdev->prop.source_ports = GENMASK(WCD938X_MAX_SWR_PORTS, 0);
255                 pdev->prop.src_dpn_prop = wcd938x_dpn_prop;
256                 wcd->ch_info = &wcd938x_sdw_tx_ch_info[0];
257                 pdev->prop.wake_capable = true;
258         } else {
259                 pdev->prop.sink_ports = GENMASK(WCD938X_MAX_SWR_PORTS, 0);
260                 pdev->prop.sink_dpn_prop = wcd938x_dpn_prop;
261                 wcd->ch_info = &wcd938x_sdw_rx_ch_info[0];
262         }
263
264         pm_runtime_set_autosuspend_delay(dev, 3000);
265         pm_runtime_use_autosuspend(dev);
266         pm_runtime_mark_last_busy(dev);
267         pm_runtime_set_active(dev);
268         pm_runtime_enable(dev);
269
270         return component_add(dev, &wcd938x_sdw_component_ops);
271 }
272
273 static const struct sdw_device_id wcd9380_slave_id[] = {
274         SDW_SLAVE_ENTRY(0x0217, 0x10d, 0),
275         {},
276 };
277 MODULE_DEVICE_TABLE(sdw, wcd9380_slave_id);
278
279 static int __maybe_unused wcd938x_sdw_runtime_suspend(struct device *dev)
280 {
281         struct regmap *regmap = dev_get_regmap(dev, NULL);
282
283         if (regmap) {
284                 regcache_cache_only(regmap, true);
285                 regcache_mark_dirty(regmap);
286         }
287         return 0;
288 }
289
290 static int __maybe_unused wcd938x_sdw_runtime_resume(struct device *dev)
291 {
292         struct regmap *regmap = dev_get_regmap(dev, NULL);
293
294         if (regmap) {
295                 regcache_cache_only(regmap, false);
296                 regcache_sync(regmap);
297         }
298
299         pm_runtime_mark_last_busy(dev);
300
301         return 0;
302 }
303
304 static const struct dev_pm_ops wcd938x_sdw_pm_ops = {
305         SET_RUNTIME_PM_OPS(wcd938x_sdw_runtime_suspend, wcd938x_sdw_runtime_resume, NULL)
306 };
307
308
309 static struct sdw_driver wcd9380_codec_driver = {
310         .probe  = wcd9380_probe,
311         .ops = &wcd9380_slave_ops,
312         .id_table = wcd9380_slave_id,
313         .driver = {
314                 .name   = "wcd9380-codec",
315                 .pm = &wcd938x_sdw_pm_ops,
316         }
317 };
318 module_sdw_driver(wcd9380_codec_driver);
319
320 MODULE_DESCRIPTION("WCD938X SDW codec driver");
321 MODULE_LICENSE("GPL");