xref: /linux/sound/soc/sdca/sdca_class.c (revision 84318277d6334c6981ab326d4acc87c6a6ddc9b8)
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 
209 	dev_set_drvdata(drv->dev, drv);
210 
211 	INIT_WORK(&drv->boot_work, class_boot_work);
212 	init_completion(&drv->device_attach);
213 
214 	dev_config->lock_arg = &drv->regmap_lock;
215 
216 	drv->dev_regmap = devm_regmap_init_sdw(sdw, dev_config);
217 	if (IS_ERR(drv->dev_regmap))
218 		return dev_err_probe(drv->dev, PTR_ERR(drv->dev_regmap),
219 				     "failed to create device regmap\n");
220 
221 	regcache_cache_only(drv->dev_regmap, true);
222 
223 	pm_runtime_set_autosuspend_delay(dev, 250);
224 	pm_runtime_use_autosuspend(dev);
225 	pm_runtime_set_active(dev);
226 	pm_runtime_get_noresume(dev);
227 
228 	ret = devm_pm_runtime_enable(dev);
229 	if (ret)
230 		return ret;
231 
232 	ret = devm_add_action_or_reset(dev, class_dev_remove, drv);
233 	if (ret)
234 		return ret;
235 
236 	queue_work(system_long_wq, &drv->boot_work);
237 
238 	return 0;
239 }
240 
241 static int class_runtime_suspend(struct device *dev)
242 {
243 	struct sdca_class_drv *drv = dev_get_drvdata(dev);
244 
245 	/*
246 	 * Whilst the driver doesn't power the chip down here, going into runtime
247 	 * suspend lets the SoundWire bus power down, which means the driver
248 	 * can't communicate with the device any more.
249 	 */
250 	regcache_cache_only(drv->dev_regmap, true);
251 
252 	return 0;
253 }
254 
255 static int class_runtime_resume(struct device *dev)
256 {
257 	struct sdca_class_drv *drv = dev_get_drvdata(dev);
258 	int ret;
259 
260 	ret = class_wait_for_attach(drv);
261 	if (ret)
262 		goto err;
263 
264 	regcache_mark_dirty(drv->dev_regmap);
265 
266 	ret = regcache_sync(drv->dev_regmap);
267 	if (ret) {
268 		dev_err(drv->dev, "failed to restore cache: %d\n", ret);
269 		goto err;
270 	}
271 
272 	return 0;
273 
274 err:
275 	regcache_cache_only(drv->dev_regmap, true);
276 
277 	return ret;
278 }
279 
280 static const struct dev_pm_ops class_pm_ops = {
281 	RUNTIME_PM_OPS(class_runtime_suspend, class_runtime_resume, NULL)
282 };
283 
284 static const struct sdw_device_id class_sdw_id[] = {
285 	SDW_SLAVE_ENTRY(0x01FA, 0x4245, 0),
286 	{}
287 };
288 MODULE_DEVICE_TABLE(sdw, class_sdw_id);
289 
290 static struct sdw_driver class_sdw_driver = {
291 	.driver = {
292 		.name		= "sdca_class",
293 		.pm		= pm_ptr(&class_pm_ops),
294 	},
295 
296 	.probe		= class_sdw_probe,
297 	.id_table	= class_sdw_id,
298 	.ops		= &class_sdw_ops,
299 };
300 module_sdw_driver(class_sdw_driver);
301 
302 MODULE_LICENSE("GPL");
303 MODULE_DESCRIPTION("SDCA Class Driver");
304 MODULE_IMPORT_NS("SND_SOC_SDCA");
305