1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (C) 2025 Cirrus Logic, Inc. and
3 // Cirrus Logic International Semiconductor Ltd.
4
5 /*
6 * The MIPI SDCA specification is available for public downloads at
7 * https://www.mipi.org/mipi-sdca-v1-0-download
8 */
9
10 #include <linux/device.h>
11 #include <linux/err.h>
12 #include <linux/module.h>
13 #include <linux/pm.h>
14 #include <linux/pm_runtime.h>
15 #include <linux/regmap.h>
16 #include <linux/soundwire/sdw.h>
17 #include <linux/soundwire/sdw_registers.h>
18 #include <linux/soundwire/sdw_type.h>
19 #include <sound/sdca.h>
20 #include <sound/sdca_function.h>
21 #include <sound/sdca_interrupts.h>
22 #include <sound/sdca_regmap.h>
23 #include "sdca_class.h"
24
25 #define CLASS_SDW_ATTACH_TIMEOUT_MS 5000
26
class_read_prop(struct sdw_slave * sdw)27 static int class_read_prop(struct sdw_slave *sdw)
28 {
29 struct sdw_slave_prop *prop = &sdw->prop;
30
31 sdw_slave_read_prop(sdw);
32
33 prop->use_domain_irq = true;
34 prop->scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY |
35 SDW_SCP_INT1_IMPL_DEF;
36
37 return 0;
38 }
39
40 static const struct sdw_slave_ops class_sdw_ops = {
41 .read_prop = class_read_prop,
42 };
43
class_regmap_lock(void * data)44 static void class_regmap_lock(void *data)
45 {
46 struct mutex *lock = data;
47
48 mutex_lock(lock);
49 }
50
class_regmap_unlock(void * data)51 static void class_regmap_unlock(void *data)
52 {
53 struct mutex *lock = data;
54
55 mutex_unlock(lock);
56 }
57
class_dev_regmap_volatile(struct device * dev,unsigned int reg)58 static bool class_dev_regmap_volatile(struct device *dev, unsigned int reg)
59 {
60 switch (reg) {
61 case SDW_SCP_SDCA_INTMASK1 ... SDW_SCP_SDCA_INTMASK4:
62 return false;
63 default:
64 return true;
65 }
66 }
67
class_dev_regmap_precious(struct device * dev,unsigned int reg)68 static bool class_dev_regmap_precious(struct device *dev, unsigned int reg)
69 {
70 switch (reg) {
71 case SDW_SCP_SDCA_INT1 ... SDW_SCP_SDCA_INT4:
72 case SDW_SCP_SDCA_INTMASK1 ... SDW_SCP_SDCA_INTMASK4:
73 return false;
74 default:
75 return true;
76 }
77 }
78
79 static const struct regmap_config class_dev_regmap_config = {
80 .name = "sdca-device",
81 .reg_bits = 32,
82 .val_bits = 8,
83
84 .max_register = SDW_SDCA_MAX_REGISTER,
85 .volatile_reg = class_dev_regmap_volatile,
86 .precious_reg = class_dev_regmap_precious,
87
88 .cache_type = REGCACHE_MAPLE,
89
90 .lock = class_regmap_lock,
91 .unlock = class_regmap_unlock,
92 };
93
class_remove_functions(void * data)94 static void class_remove_functions(void *data)
95 {
96 struct sdca_class_drv *drv = data;
97
98 sdca_dev_unregister_functions(drv->sdw);
99 }
100
class_boot_work(struct work_struct * work)101 static void class_boot_work(struct work_struct *work)
102 {
103 struct sdca_class_drv *drv = container_of(work,
104 struct sdca_class_drv,
105 boot_work);
106 int ret;
107
108 ret = sdw_slave_wait_for_init(drv->sdw, CLASS_SDW_ATTACH_TIMEOUT_MS);
109 if (ret)
110 goto err;
111
112 regcache_cache_only(drv->dev_regmap, false);
113
114 drv->irq_info = devm_sdca_irq_allocate(drv->dev, drv->dev_regmap,
115 drv->sdw->irq);
116 if (IS_ERR(drv->irq_info))
117 goto err;
118
119 ret = sdca_dev_register_functions(drv->sdw);
120 if (ret)
121 goto err;
122
123 /* Ensure function drivers are removed before the IRQ is destroyed */
124 ret = devm_add_action_or_reset(drv->dev, class_remove_functions, drv);
125 if (ret)
126 goto err;
127
128 dev_dbg(drv->dev, "boot work complete\n");
129
130 pm_runtime_mark_last_busy(drv->dev);
131 pm_runtime_put_autosuspend(drv->dev);
132
133 return;
134
135 err:
136 pm_runtime_put_sync(drv->dev);
137 }
138
class_sdw_probe(struct sdw_slave * sdw,const struct sdw_device_id * id)139 static int class_sdw_probe(struct sdw_slave *sdw, const struct sdw_device_id *id)
140 {
141 struct device *dev = &sdw->dev;
142 struct regmap_config *dev_config;
143 struct sdca_class_drv *drv;
144 int ret;
145
146 sdca_lookup_swft(sdw);
147
148 drv = devm_kzalloc(dev, sizeof(*drv), GFP_KERNEL);
149 if (!drv)
150 return -ENOMEM;
151
152 dev_config = devm_kmemdup(dev, &class_dev_regmap_config,
153 sizeof(*dev_config), GFP_KERNEL);
154 if (!dev_config)
155 return -ENOMEM;
156
157 drv->dev = dev;
158 drv->sdw = sdw;
159 mutex_init(&drv->regmap_lock);
160 mutex_init(&drv->init_lock);
161
162 dev_set_drvdata(drv->dev, drv);
163
164 INIT_WORK(&drv->boot_work, class_boot_work);
165
166 dev_config->lock_arg = &drv->regmap_lock;
167
168 drv->dev_regmap = devm_regmap_init_sdw(sdw, dev_config);
169 if (IS_ERR(drv->dev_regmap))
170 return dev_err_probe(drv->dev, PTR_ERR(drv->dev_regmap),
171 "failed to create device regmap\n");
172
173 regcache_cache_only(drv->dev_regmap, true);
174
175 pm_runtime_set_autosuspend_delay(dev, 250);
176 pm_runtime_use_autosuspend(dev);
177 pm_runtime_set_active(dev);
178 pm_runtime_get_noresume(dev);
179
180 ret = devm_pm_runtime_enable(dev);
181 if (ret)
182 return ret;
183
184 queue_work(system_long_wq, &drv->boot_work);
185
186 return 0;
187 }
188
class_sdw_remove(struct sdw_slave * sdw)189 static void class_sdw_remove(struct sdw_slave *sdw)
190 {
191 struct device *dev = &sdw->dev;
192 struct sdca_class_drv *drv = dev_get_drvdata(dev);
193
194 cancel_work_sync(&drv->boot_work);
195 }
196
class_suspend(struct device * dev)197 static int class_suspend(struct device *dev)
198 {
199 struct sdca_class_drv *drv = dev_get_drvdata(dev);
200 int ret;
201
202 disable_irq(drv->sdw->irq);
203
204 ret = pm_runtime_force_suspend(dev);
205 if (ret) {
206 dev_err(dev, "failed to force suspend: %d\n", ret);
207 return ret;
208 }
209
210 return 0;
211 }
212
class_resume(struct device * dev)213 static int class_resume(struct device *dev)
214 {
215 struct sdca_class_drv *drv = dev_get_drvdata(dev);
216 int ret;
217
218 ret = pm_runtime_force_resume(dev);
219 if (ret) {
220 dev_err(dev, "failed to force resume: %d\n", ret);
221 return ret;
222 }
223
224 enable_irq(drv->sdw->irq);
225
226 return 0;
227 }
228
class_runtime_suspend(struct device * dev)229 static int class_runtime_suspend(struct device *dev)
230 {
231 struct sdca_class_drv *drv = dev_get_drvdata(dev);
232
233 /*
234 * Whilst the driver doesn't power the chip down here, going into runtime
235 * suspend lets the SoundWire bus power down, which means the driver
236 * can't communicate with the device any more.
237 */
238 regcache_cache_only(drv->dev_regmap, true);
239
240 return 0;
241 }
242
class_runtime_resume(struct device * dev)243 static int class_runtime_resume(struct device *dev)
244 {
245 struct sdca_class_drv *drv = dev_get_drvdata(dev);
246 int ret;
247
248 ret = sdw_slave_wait_for_init(drv->sdw, CLASS_SDW_ATTACH_TIMEOUT_MS);
249 if (ret)
250 goto err;
251
252 regcache_cache_only(drv->dev_regmap, false);
253 regcache_mark_dirty(drv->dev_regmap);
254
255 ret = regcache_sync(drv->dev_regmap);
256 if (ret) {
257 dev_err(drv->dev, "failed to restore cache: %d\n", ret);
258 goto err;
259 }
260
261 return 0;
262
263 err:
264 regcache_cache_only(drv->dev_regmap, true);
265
266 return ret;
267 }
268
269 static const struct dev_pm_ops class_pm_ops = {
270 SYSTEM_SLEEP_PM_OPS(class_suspend, class_resume)
271 RUNTIME_PM_OPS(class_runtime_suspend, class_runtime_resume, NULL)
272 };
273
274 static const struct sdw_device_id class_sdw_id[] = {
275 SDW_SLAVE_ENTRY(0x01FA, 0x4245, 0),
276 SDW_SLAVE_ENTRY(0x01FA, 0x4249, 0),
277 SDW_SLAVE_ENTRY(0x01FA, 0x4747, 0),
278 {}
279 };
280 MODULE_DEVICE_TABLE(sdw, class_sdw_id);
281
282 static struct sdw_driver class_sdw_driver = {
283 .driver = {
284 .name = "sdca_class",
285 .pm = pm_ptr(&class_pm_ops),
286 },
287
288 .probe = class_sdw_probe,
289 .remove = class_sdw_remove,
290 .id_table = class_sdw_id,
291 .ops = &class_sdw_ops,
292 };
293 module_sdw_driver(class_sdw_driver);
294
295 MODULE_LICENSE("GPL");
296 MODULE_DESCRIPTION("SDCA Class Driver");
297 MODULE_IMPORT_NS("SND_SOC_SDCA");
298