xref: /linux/sound/soc/sdca/sdca_class.c (revision af0bc3ac9a9e830cb52b718ecb237c4e76a466be)
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/mod_devicetable.h>
13 #include <linux/module.h>
14 #include <linux/pm.h>
15 #include <linux/pm_runtime.h>
16 #include <linux/regmap.h>
17 #include <linux/soundwire/sdw.h>
18 #include <linux/soundwire/sdw_registers.h>
19 #include <linux/soundwire/sdw_type.h>
20 #include <sound/sdca.h>
21 #include <sound/sdca_function.h>
22 #include <sound/sdca_interrupts.h>
23 #include <sound/sdca_regmap.h>
24 #include "sdca_class.h"
25 
26 #define CLASS_SDW_ATTACH_TIMEOUT_MS	5000
27 
28 static int class_read_prop(struct sdw_slave *sdw)
29 {
30 	struct sdw_slave_prop *prop = &sdw->prop;
31 
32 	sdw_slave_read_prop(sdw);
33 
34 	prop->use_domain_irq = true;
35 	prop->scp_int1_mask = SDW_SCP_INT1_BUS_CLASH | SDW_SCP_INT1_PARITY |
36 			      SDW_SCP_INT1_IMPL_DEF;
37 
38 	return 0;
39 }
40 
41 static int class_sdw_update_status(struct sdw_slave *sdw, enum sdw_slave_status status)
42 {
43 	struct sdca_class_drv *drv = dev_get_drvdata(&sdw->dev);
44 
45 	switch (status) {
46 	case SDW_SLAVE_ATTACHED:
47 		dev_dbg(drv->dev, "device attach\n");
48 
49 		drv->attached = true;
50 
51 		complete(&drv->device_attach);
52 		break;
53 	case SDW_SLAVE_UNATTACHED:
54 		dev_dbg(drv->dev, "device detach\n");
55 
56 		drv->attached = false;
57 
58 		reinit_completion(&drv->device_attach);
59 		break;
60 	default:
61 		break;
62 	}
63 
64 	return 0;
65 }
66 
67 static const struct sdw_slave_ops class_sdw_ops = {
68 	.read_prop	= class_read_prop,
69 	.update_status	= class_sdw_update_status,
70 };
71 
72 static void class_regmap_lock(void *data)
73 {
74 	struct mutex *lock = data;
75 
76 	mutex_lock(lock);
77 }
78 
79 static void class_regmap_unlock(void *data)
80 {
81 	struct mutex *lock = data;
82 
83 	mutex_unlock(lock);
84 }
85 
86 static int class_wait_for_attach(struct sdca_class_drv *drv)
87 {
88 	if (!drv->attached) {
89 		unsigned long timeout = msecs_to_jiffies(CLASS_SDW_ATTACH_TIMEOUT_MS);
90 		unsigned long time;
91 
92 		time = wait_for_completion_timeout(&drv->device_attach, timeout);
93 		if (!time) {
94 			dev_err(drv->dev, "timed out waiting for device re-attach\n");
95 			return -ETIMEDOUT;
96 		}
97 	}
98 
99 	regcache_cache_only(drv->dev_regmap, false);
100 
101 	return 0;
102 }
103 
104 static bool class_dev_regmap_volatile(struct device *dev, unsigned int reg)
105 {
106 	switch (reg) {
107 	case SDW_SCP_SDCA_INTMASK1 ... SDW_SCP_SDCA_INTMASK4:
108 		return false;
109 	default:
110 		return true;
111 	}
112 }
113 
114 static bool class_dev_regmap_precious(struct device *dev, unsigned int reg)
115 {
116 	switch (reg) {
117 	case SDW_SCP_SDCA_INT1 ... SDW_SCP_SDCA_INT4:
118 	case SDW_SCP_SDCA_INTMASK1 ... SDW_SCP_SDCA_INTMASK4:
119 		return false;
120 	default:
121 		return true;
122 	}
123 }
124 
125 static const struct regmap_config class_dev_regmap_config = {
126 	.name			= "sdca-device",
127 	.reg_bits		= 32,
128 	.val_bits		= 8,
129 
130 	.max_register		= SDW_SDCA_MAX_REGISTER,
131 	.volatile_reg		= class_dev_regmap_volatile,
132 	.precious_reg		= class_dev_regmap_precious,
133 
134 	.cache_type		= REGCACHE_MAPLE,
135 
136 	.lock			= class_regmap_lock,
137 	.unlock			= class_regmap_unlock,
138 };
139 
140 static void class_boot_work(struct work_struct *work)
141 {
142 	struct sdca_class_drv *drv = container_of(work,
143 						  struct sdca_class_drv,
144 						  boot_work);
145 	int ret;
146 
147 	ret = class_wait_for_attach(drv);
148 	if (ret)
149 		goto err;
150 
151 	drv->irq_info = sdca_irq_allocate(drv->dev, drv->dev_regmap,
152 					  drv->sdw->irq);
153 	if (IS_ERR(drv->irq_info))
154 		goto err;
155 
156 	ret = sdca_dev_register_functions(drv->sdw);
157 	if (ret)
158 		goto err;
159 
160 	dev_dbg(drv->dev, "boot work complete\n");
161 
162 	pm_runtime_mark_last_busy(drv->dev);
163 	pm_runtime_put_autosuspend(drv->dev);
164 
165 	return;
166 
167 err:
168 	pm_runtime_put_sync(drv->dev);
169 }
170 
171 static void class_dev_remove(void *data)
172 {
173 	struct sdca_class_drv *drv = data;
174 
175 	cancel_work_sync(&drv->boot_work);
176 
177 	sdca_dev_unregister_functions(drv->sdw);
178 }
179 
180 static int class_sdw_probe(struct sdw_slave *sdw, const struct sdw_device_id *id)
181 {
182 	struct device *dev = &sdw->dev;
183 	struct sdca_device_data *data = &sdw->sdca_data;
184 	struct regmap_config *dev_config;
185 	struct sdca_class_drv *drv;
186 	int ret;
187 
188 	sdca_lookup_swft(sdw);
189 
190 	drv = devm_kzalloc(dev, sizeof(*drv), GFP_KERNEL);
191 	if (!drv)
192 		return -ENOMEM;
193 
194 	dev_config = devm_kmemdup(dev, &class_dev_regmap_config,
195 				  sizeof(*dev_config), GFP_KERNEL);
196 	if (!dev_config)
197 		return -ENOMEM;
198 
199 	drv->functions = devm_kcalloc(dev, data->num_functions,
200 				      sizeof(*drv->functions),
201 				      GFP_KERNEL);
202 	if (!drv->functions)
203 		return -ENOMEM;
204 
205 	drv->dev = dev;
206 	drv->sdw = sdw;
207 	mutex_init(&drv->regmap_lock);
208 	mutex_init(&drv->init_lock);
209 
210 	dev_set_drvdata(drv->dev, drv);
211 
212 	INIT_WORK(&drv->boot_work, class_boot_work);
213 	init_completion(&drv->device_attach);
214 
215 	dev_config->lock_arg = &drv->regmap_lock;
216 
217 	drv->dev_regmap = devm_regmap_init_sdw(sdw, dev_config);
218 	if (IS_ERR(drv->dev_regmap))
219 		return dev_err_probe(drv->dev, PTR_ERR(drv->dev_regmap),
220 				     "failed to create device regmap\n");
221 
222 	regcache_cache_only(drv->dev_regmap, true);
223 
224 	pm_runtime_set_autosuspend_delay(dev, 250);
225 	pm_runtime_use_autosuspend(dev);
226 	pm_runtime_set_active(dev);
227 	pm_runtime_get_noresume(dev);
228 
229 	ret = devm_pm_runtime_enable(dev);
230 	if (ret)
231 		return ret;
232 
233 	ret = devm_add_action_or_reset(dev, class_dev_remove, drv);
234 	if (ret)
235 		return ret;
236 
237 	queue_work(system_long_wq, &drv->boot_work);
238 
239 	return 0;
240 }
241 
242 static int class_suspend(struct device *dev)
243 {
244 	struct sdca_class_drv *drv = dev_get_drvdata(dev);
245 	int ret;
246 
247 	disable_irq(drv->sdw->irq);
248 
249 	ret = pm_runtime_force_suspend(dev);
250 	if (ret) {
251 		dev_err(dev, "failed to force suspend: %d\n", ret);
252 		return ret;
253 	}
254 
255 	return 0;
256 }
257 
258 static int class_resume(struct device *dev)
259 {
260 	struct sdca_class_drv *drv = dev_get_drvdata(dev);
261 	int ret;
262 
263 	ret = pm_runtime_force_resume(dev);
264 	if (ret) {
265 		dev_err(dev, "failed to force resume: %d\n", ret);
266 		return ret;
267 	}
268 
269 	enable_irq(drv->sdw->irq);
270 
271 	return 0;
272 }
273 
274 static int class_runtime_suspend(struct device *dev)
275 {
276 	struct sdca_class_drv *drv = dev_get_drvdata(dev);
277 
278 	/*
279 	 * Whilst the driver doesn't power the chip down here, going into runtime
280 	 * suspend lets the SoundWire bus power down, which means the driver
281 	 * can't communicate with the device any more.
282 	 */
283 	regcache_cache_only(drv->dev_regmap, true);
284 
285 	return 0;
286 }
287 
288 static int class_runtime_resume(struct device *dev)
289 {
290 	struct sdca_class_drv *drv = dev_get_drvdata(dev);
291 	int ret;
292 
293 	ret = class_wait_for_attach(drv);
294 	if (ret)
295 		goto err;
296 
297 	regcache_mark_dirty(drv->dev_regmap);
298 
299 	ret = regcache_sync(drv->dev_regmap);
300 	if (ret) {
301 		dev_err(drv->dev, "failed to restore cache: %d\n", ret);
302 		goto err;
303 	}
304 
305 	return 0;
306 
307 err:
308 	regcache_cache_only(drv->dev_regmap, true);
309 
310 	return ret;
311 }
312 
313 static const struct dev_pm_ops class_pm_ops = {
314 	SYSTEM_SLEEP_PM_OPS(class_suspend, class_resume)
315 	RUNTIME_PM_OPS(class_runtime_suspend, class_runtime_resume, NULL)
316 };
317 
318 static const struct sdw_device_id class_sdw_id[] = {
319 	SDW_SLAVE_ENTRY(0x01FA, 0x4245, 0),
320 	{}
321 };
322 MODULE_DEVICE_TABLE(sdw, class_sdw_id);
323 
324 static struct sdw_driver class_sdw_driver = {
325 	.driver = {
326 		.name		= "sdca_class",
327 		.pm		= pm_ptr(&class_pm_ops),
328 	},
329 
330 	.probe		= class_sdw_probe,
331 	.id_table	= class_sdw_id,
332 	.ops		= &class_sdw_ops,
333 };
334 module_sdw_driver(class_sdw_driver);
335 
336 MODULE_LICENSE("GPL");
337 MODULE_DESCRIPTION("SDCA Class Driver");
338 MODULE_IMPORT_NS("SND_SOC_SDCA");
339