d8d4caf48dc7eac7ba5c8bf9f8d991e3bb4f6ddf
[linux-2.6-microblaze.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 <sound/soc.h>
11 #include <linux/pm_runtime.h>
12 #include <linux/irq.h>
13 #include <linux/irqdomain.h>
14 #include <linux/of.h>
15 #include <linux/soundwire/sdw.h>
16 #include <linux/soundwire/sdw_type.h>
17 #include <linux/soundwire/sdw_registers.h>
18 #include <linux/regmap.h>
19 #include <sound/soc.h>
20 #include <sound/soc-dapm.h>
21 #include "wcd938x.h"
22
23 #define SWRS_SCP_HOST_CLK_DIV2_CTL_BANK(m) (0xE0 + 0x10 * (m))
24
25 static struct wcd938x_sdw_ch_info wcd938x_sdw_rx_ch_info[] = {
26         WCD_SDW_CH(WCD938X_HPH_L, WCD938X_HPH_PORT, BIT(0)),
27         WCD_SDW_CH(WCD938X_HPH_R, WCD938X_HPH_PORT, BIT(1)),
28         WCD_SDW_CH(WCD938X_CLSH, WCD938X_CLSH_PORT, BIT(0)),
29         WCD_SDW_CH(WCD938X_COMP_L, WCD938X_COMP_PORT, BIT(0)),
30         WCD_SDW_CH(WCD938X_COMP_R, WCD938X_COMP_PORT, BIT(1)),
31         WCD_SDW_CH(WCD938X_LO, WCD938X_LO_PORT, BIT(0)),
32         WCD_SDW_CH(WCD938X_DSD_L, WCD938X_DSD_PORT, BIT(0)),
33         WCD_SDW_CH(WCD938X_DSD_R, WCD938X_DSD_PORT, BIT(1)),
34 };
35
36 static struct wcd938x_sdw_ch_info wcd938x_sdw_tx_ch_info[] = {
37         WCD_SDW_CH(WCD938X_ADC1, WCD938X_ADC_1_2_PORT, BIT(0)),
38         WCD_SDW_CH(WCD938X_ADC2, WCD938X_ADC_1_2_PORT, BIT(1)),
39         WCD_SDW_CH(WCD938X_ADC3, WCD938X_ADC_3_4_PORT, BIT(0)),
40         WCD_SDW_CH(WCD938X_ADC4, WCD938X_ADC_3_4_PORT, BIT(1)),
41         WCD_SDW_CH(WCD938X_DMIC0, WCD938X_DMIC_0_3_MBHC_PORT, BIT(0)),
42         WCD_SDW_CH(WCD938X_DMIC1, WCD938X_DMIC_0_3_MBHC_PORT, BIT(1)),
43         WCD_SDW_CH(WCD938X_MBHC, WCD938X_DMIC_0_3_MBHC_PORT, BIT(2)),
44         WCD_SDW_CH(WCD938X_DMIC2, WCD938X_DMIC_0_3_MBHC_PORT, BIT(2)),
45         WCD_SDW_CH(WCD938X_DMIC3, WCD938X_DMIC_0_3_MBHC_PORT, BIT(3)),
46         WCD_SDW_CH(WCD938X_DMIC4, WCD938X_DMIC_4_7_PORT, BIT(0)),
47         WCD_SDW_CH(WCD938X_DMIC5, WCD938X_DMIC_4_7_PORT, BIT(1)),
48         WCD_SDW_CH(WCD938X_DMIC6, WCD938X_DMIC_4_7_PORT, BIT(2)),
49         WCD_SDW_CH(WCD938X_DMIC7, WCD938X_DMIC_4_7_PORT, BIT(3)),
50 };
51
52 static struct sdw_dpn_prop wcd938x_dpn_prop[WCD938X_MAX_SWR_PORTS] = {
53         {
54                 .num = 1,
55                 .type = SDW_DPN_SIMPLE,
56                 .min_ch = 1,
57                 .max_ch = 8,
58                 .simple_ch_prep_sm = true,
59         }, {
60                 .num = 2,
61                 .type = SDW_DPN_SIMPLE,
62                 .min_ch = 1,
63                 .max_ch = 4,
64                 .simple_ch_prep_sm = true,
65         }, {
66                 .num = 3,
67                 .type = SDW_DPN_SIMPLE,
68                 .min_ch = 1,
69                 .max_ch = 4,
70                 .simple_ch_prep_sm = true,
71         }, {
72                 .num = 4,
73                 .type = SDW_DPN_SIMPLE,
74                 .min_ch = 1,
75                 .max_ch = 4,
76                 .simple_ch_prep_sm = true,
77         }, {
78                 .num = 5,
79                 .type = SDW_DPN_SIMPLE,
80                 .min_ch = 1,
81                 .max_ch = 4,
82                 .simple_ch_prep_sm = true,
83         }
84 };
85
86 struct device *wcd938x_sdw_device_get(struct device_node *np)
87 {
88         return bus_find_device_by_of_node(&sdw_bus_type, np);
89
90 }
91 EXPORT_SYMBOL_GPL(wcd938x_sdw_device_get);
92
93 int wcd938x_swr_get_current_bank(struct sdw_slave *sdev)
94 {
95         int bank;
96
97         bank  = sdw_read(sdev, SDW_SCP_CTRL);
98
99         return ((bank & 0x40) ? 1 : 0);
100 }
101 EXPORT_SYMBOL_GPL(wcd938x_swr_get_current_bank);
102
103 int wcd938x_sdw_hw_params(struct wcd938x_sdw_priv *wcd,
104                           struct snd_pcm_substream *substream,
105                           struct snd_pcm_hw_params *params,
106                           struct snd_soc_dai *dai)
107 {
108         struct sdw_port_config port_config[WCD938X_MAX_SWR_PORTS];
109         unsigned long ch_mask;
110         int i, j;
111
112         wcd->sconfig.ch_count = 1;
113         wcd->active_ports = 0;
114         for (i = 0; i < WCD938X_MAX_SWR_PORTS; i++) {
115                 ch_mask = wcd->port_config[i].ch_mask;
116
117                 if (!ch_mask)
118                         continue;
119
120                 for_each_set_bit(j, &ch_mask, 4)
121                         wcd->sconfig.ch_count++;
122
123                 port_config[wcd->active_ports] = wcd->port_config[i];
124                 wcd->active_ports++;
125         }
126
127         wcd->sconfig.bps = 1;
128         wcd->sconfig.frame_rate =  params_rate(params);
129         if (wcd->is_tx)
130                 wcd->sconfig.direction = SDW_DATA_DIR_TX;
131         else
132                 wcd->sconfig.direction = SDW_DATA_DIR_RX;
133
134         wcd->sconfig.type = SDW_STREAM_PCM;
135
136         return sdw_stream_add_slave(wcd->sdev, &wcd->sconfig,
137                                     &port_config[0], wcd->active_ports,
138                                     wcd->sruntime);
139 }
140 EXPORT_SYMBOL_GPL(wcd938x_sdw_hw_params);
141
142 int wcd938x_sdw_free(struct wcd938x_sdw_priv *wcd,
143                      struct snd_pcm_substream *substream,
144                      struct snd_soc_dai *dai)
145 {
146         sdw_stream_remove_slave(wcd->sdev, wcd->sruntime);
147
148         return 0;
149 }
150 EXPORT_SYMBOL_GPL(wcd938x_sdw_free);
151
152 int wcd938x_sdw_set_sdw_stream(struct wcd938x_sdw_priv *wcd,
153                                struct snd_soc_dai *dai,
154                                void *stream, int direction)
155 {
156         wcd->sruntime = stream;
157
158         return 0;
159 }
160 EXPORT_SYMBOL_GPL(wcd938x_sdw_set_sdw_stream);
161
162 static int wcd9380_update_status(struct sdw_slave *slave,
163                                  enum sdw_slave_status status)
164 {
165         return 0;
166 }
167
168 static int wcd9380_bus_config(struct sdw_slave *slave,
169                               struct sdw_bus_params *params)
170 {
171         sdw_write(slave, SWRS_SCP_HOST_CLK_DIV2_CTL_BANK(params->next_bank),  0x01);
172
173         return 0;
174 }
175
176 static int wcd9380_interrupt_callback(struct sdw_slave *slave,
177                                       struct sdw_slave_intr_status *status)
178 {
179         struct wcd938x_sdw_priv *wcd = dev_get_drvdata(&slave->dev);
180         struct irq_domain *slave_irq = wcd->slave_irq;
181         struct regmap *regmap = dev_get_regmap(&slave->dev, NULL);
182         u32 sts1, sts2, sts3;
183
184         do {
185                 handle_nested_irq(irq_find_mapping(slave_irq, 0));
186                 regmap_read(regmap, WCD938X_DIGITAL_INTR_STATUS_0, &sts1);
187                 regmap_read(regmap, WCD938X_DIGITAL_INTR_STATUS_1, &sts2);
188                 regmap_read(regmap, WCD938X_DIGITAL_INTR_STATUS_2, &sts3);
189
190         } while (sts1 || sts2 || sts3);
191
192         return IRQ_HANDLED;
193 }
194
195 static struct sdw_slave_ops wcd9380_slave_ops = {
196         .update_status = wcd9380_update_status,
197         .interrupt_callback = wcd9380_interrupt_callback,
198         .bus_config = wcd9380_bus_config,
199 };
200
201 static int wcd938x_sdw_component_bind(struct device *dev,
202                                       struct device *master, void *data)
203 {
204         return 0;
205 }
206
207 static void wcd938x_sdw_component_unbind(struct device *dev,
208                                          struct device *master, void *data)
209 {
210 }
211
212 static const struct component_ops wcd938x_sdw_component_ops = {
213         .bind   = wcd938x_sdw_component_bind,
214         .unbind = wcd938x_sdw_component_unbind,
215 };
216
217 static int wcd9380_probe(struct sdw_slave *pdev,
218                          const struct sdw_device_id *id)
219 {
220         struct device *dev = &pdev->dev;
221         struct wcd938x_sdw_priv *wcd;
222         int ret;
223
224         wcd = devm_kzalloc(dev, sizeof(*wcd), GFP_KERNEL);
225         if (!wcd)
226                 return -ENOMEM;
227
228         /**
229          * Port map index starts with 0, however the data port for this codec
230          * are from index 1
231          */
232         if (of_property_read_bool(dev->of_node, "qcom,tx-port-mapping")) {
233                 wcd->is_tx = true;
234                 ret = of_property_read_u32_array(dev->of_node, "qcom,tx-port-mapping",
235                                                  &pdev->m_port_map[1],
236                                                  WCD938X_MAX_TX_SWR_PORTS);
237         } else {
238                 ret = of_property_read_u32_array(dev->of_node, "qcom,rx-port-mapping",
239                                                  &pdev->m_port_map[1],
240                                                  WCD938X_MAX_SWR_PORTS);
241         }
242
243         if (ret < 0)
244                 dev_info(dev, "Static Port mapping not specified\n");
245
246         wcd->sdev = pdev;
247         dev_set_drvdata(dev, wcd);
248
249         pdev->prop.scp_int1_mask = SDW_SCP_INT1_IMPL_DEF |
250                                         SDW_SCP_INT1_BUS_CLASH |
251                                         SDW_SCP_INT1_PARITY;
252         pdev->prop.lane_control_support = 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");