Commit | Line | Data |
---|---|---|
7d2a5f9a SF |
1 | // SPDX-License-Identifier: GPL-2.0 |
2 | // | |
3 | // rt700-sdw.c -- rt700 ALSA SoC audio driver | |
4 | // | |
5 | // Copyright(c) 2019 Realtek Semiconductor Corp. | |
6 | // | |
7 | // | |
8 | ||
9 | #include <linux/delay.h> | |
10 | #include <linux/device.h> | |
11 | #include <linux/mod_devicetable.h> | |
12 | #include <linux/soundwire/sdw.h> | |
13 | #include <linux/soundwire/sdw_type.h> | |
2acd30b9 | 14 | #include <linux/soundwire/sdw_registers.h> |
7d2a5f9a | 15 | #include <linux/module.h> |
ac63716d | 16 | #include <linux/pm_runtime.h> |
7d2a5f9a SF |
17 | #include <linux/regmap.h> |
18 | #include <sound/soc.h> | |
19 | #include "rt700.h" | |
20 | #include "rt700-sdw.h" | |
21 | ||
22 | static bool rt700_readable_register(struct device *dev, unsigned int reg) | |
23 | { | |
24 | switch (reg) { | |
25 | case 0x00e0: | |
26 | case 0x00f0: | |
27 | case 0x2000 ... 0x200e: | |
28 | case 0x2012 ... 0x2016: | |
29 | case 0x201a ... 0x2027: | |
30 | case 0x2029 ... 0x202a: | |
31 | case 0x202d ... 0x2034: | |
32 | case 0x2200 ... 0x2204: | |
33 | case 0x2206 ... 0x2212: | |
34 | case 0x2220 ... 0x2223: | |
35 | case 0x2230 ... 0x2231: | |
36 | case 0x3000 ... 0x3fff: | |
37 | case 0x7000 ... 0x7fff: | |
38 | case 0x8300 ... 0x83ff: | |
39 | case 0x9c00 ... 0x9cff: | |
40 | case 0xb900 ... 0xb9ff: | |
41 | case 0x75201a: | |
42 | case 0x752045: | |
43 | case 0x752046: | |
44 | case 0x752048: | |
45 | case 0x75204a: | |
46 | case 0x75206b: | |
47 | case 0x752080: | |
48 | case 0x752081: | |
49 | return true; | |
50 | default: | |
51 | return false; | |
52 | } | |
53 | } | |
54 | ||
55 | static bool rt700_volatile_register(struct device *dev, unsigned int reg) | |
56 | { | |
57 | switch (reg) { | |
58 | case 0x2009: | |
59 | case 0x2016: | |
60 | case 0x201b: | |
61 | case 0x201c: | |
62 | case 0x201d: | |
63 | case 0x201f: | |
64 | case 0x2021: | |
65 | case 0x2023: | |
66 | case 0x2230: | |
67 | case 0x200b ... 0x200e: /* i2c read */ | |
68 | case 0x2012 ... 0x2015: /* HD-A read */ | |
69 | case 0x202d ... 0x202f: /* BRA */ | |
70 | case 0x2201 ... 0x2212: /* i2c debug */ | |
71 | case 0x2220 ... 0x2223: /* decoded HD-A */ | |
72 | case 0x9c00 ... 0x9cff: | |
73 | case 0xb900 ... 0xb9ff: | |
74 | case 0xff01: | |
75 | case 0x75201a: | |
76 | case 0x752046: | |
77 | case 0x752080: | |
78 | case 0x752081: | |
79 | return true; | |
80 | default: | |
81 | return false; | |
82 | } | |
83 | } | |
84 | ||
85 | static int rt700_sdw_read(void *context, unsigned int reg, unsigned int *val) | |
86 | { | |
87 | struct device *dev = context; | |
88 | struct rt700_priv *rt700 = dev_get_drvdata(dev); | |
89 | unsigned int sdw_data_3, sdw_data_2, sdw_data_1, sdw_data_0; | |
90 | unsigned int reg2 = 0, reg3 = 0, reg4 = 0, mask, nid, val2; | |
91 | unsigned int is_hda_reg = 1, is_index_reg = 0; | |
92 | int ret; | |
93 | ||
94 | if (reg > 0xffff) | |
95 | is_index_reg = 1; | |
96 | ||
97 | mask = reg & 0xf000; | |
98 | ||
99 | if (is_index_reg) { /* index registers */ | |
100 | val2 = reg & 0xff; | |
101 | reg = reg >> 8; | |
102 | nid = reg & 0xff; | |
103 | ret = regmap_write(rt700->sdw_regmap, reg, 0); | |
104 | if (ret < 0) | |
105 | return ret; | |
106 | reg2 = reg + 0x1000; | |
107 | reg2 |= 0x80; | |
108 | ret = regmap_write(rt700->sdw_regmap, reg2, val2); | |
109 | if (ret < 0) | |
110 | return ret; | |
111 | ||
112 | reg3 = RT700_PRIV_DATA_R_H | nid; | |
113 | ret = regmap_write(rt700->sdw_regmap, | |
114 | reg3, ((*val >> 8) & 0xff)); | |
115 | if (ret < 0) | |
116 | return ret; | |
117 | reg4 = reg3 + 0x1000; | |
118 | reg4 |= 0x80; | |
119 | ret = regmap_write(rt700->sdw_regmap, reg4, (*val & 0xff)); | |
120 | if (ret < 0) | |
121 | return ret; | |
122 | } else if (mask == 0x3000) { | |
123 | reg += 0x8000; | |
124 | ret = regmap_write(rt700->sdw_regmap, reg, *val); | |
125 | if (ret < 0) | |
126 | return ret; | |
127 | } else if (mask == 0x7000) { | |
128 | reg += 0x2000; | |
129 | reg |= 0x800; | |
130 | ret = regmap_write(rt700->sdw_regmap, | |
131 | reg, ((*val >> 8) & 0xff)); | |
132 | if (ret < 0) | |
133 | return ret; | |
134 | reg2 = reg + 0x1000; | |
135 | reg2 |= 0x80; | |
136 | ret = regmap_write(rt700->sdw_regmap, reg2, (*val & 0xff)); | |
137 | if (ret < 0) | |
138 | return ret; | |
139 | } else if ((reg & 0xff00) == 0x8300) { /* for R channel */ | |
140 | reg2 = reg - 0x1000; | |
141 | reg2 &= ~0x80; | |
142 | ret = regmap_write(rt700->sdw_regmap, | |
143 | reg2, ((*val >> 8) & 0xff)); | |
144 | if (ret < 0) | |
145 | return ret; | |
146 | ret = regmap_write(rt700->sdw_regmap, reg, (*val & 0xff)); | |
147 | if (ret < 0) | |
148 | return ret; | |
149 | } else if (mask == 0x9000) { | |
150 | ret = regmap_write(rt700->sdw_regmap, | |
151 | reg, ((*val >> 8) & 0xff)); | |
152 | if (ret < 0) | |
153 | return ret; | |
154 | reg2 = reg + 0x1000; | |
155 | reg2 |= 0x80; | |
156 | ret = regmap_write(rt700->sdw_regmap, reg2, (*val & 0xff)); | |
157 | if (ret < 0) | |
158 | return ret; | |
159 | } else if (mask == 0xb000) { | |
160 | ret = regmap_write(rt700->sdw_regmap, reg, *val); | |
161 | if (ret < 0) | |
162 | return ret; | |
163 | } else { | |
164 | ret = regmap_read(rt700->sdw_regmap, reg, val); | |
165 | if (ret < 0) | |
166 | return ret; | |
167 | is_hda_reg = 0; | |
168 | } | |
169 | ||
170 | if (is_hda_reg || is_index_reg) { | |
171 | sdw_data_3 = 0; | |
172 | sdw_data_2 = 0; | |
173 | sdw_data_1 = 0; | |
174 | sdw_data_0 = 0; | |
175 | ret = regmap_read(rt700->sdw_regmap, | |
176 | RT700_READ_HDA_3, &sdw_data_3); | |
177 | if (ret < 0) | |
178 | return ret; | |
179 | ret = regmap_read(rt700->sdw_regmap, | |
180 | RT700_READ_HDA_2, &sdw_data_2); | |
181 | if (ret < 0) | |
182 | return ret; | |
183 | ret = regmap_read(rt700->sdw_regmap, | |
184 | RT700_READ_HDA_1, &sdw_data_1); | |
185 | if (ret < 0) | |
186 | return ret; | |
187 | ret = regmap_read(rt700->sdw_regmap, | |
188 | RT700_READ_HDA_0, &sdw_data_0); | |
189 | if (ret < 0) | |
190 | return ret; | |
191 | *val = ((sdw_data_3 & 0xff) << 24) | | |
192 | ((sdw_data_2 & 0xff) << 16) | | |
193 | ((sdw_data_1 & 0xff) << 8) | (sdw_data_0 & 0xff); | |
194 | } | |
195 | ||
196 | if (is_hda_reg == 0) | |
197 | dev_dbg(dev, "[%s] %04x => %08x\n", __func__, reg, *val); | |
198 | else if (is_index_reg) | |
199 | dev_dbg(dev, "[%s] %04x %04x %04x %04x => %08x\n", | |
200 | __func__, reg, reg2, reg3, reg4, *val); | |
201 | else | |
202 | dev_dbg(dev, "[%s] %04x %04x => %08x\n", | |
203 | __func__, reg, reg2, *val); | |
204 | ||
205 | return 0; | |
206 | } | |
207 | ||
208 | static int rt700_sdw_write(void *context, unsigned int reg, unsigned int val) | |
209 | { | |
210 | struct device *dev = context; | |
211 | struct rt700_priv *rt700 = dev_get_drvdata(dev); | |
212 | unsigned int reg2 = 0, reg3, reg4, nid, mask, val2; | |
213 | unsigned int is_index_reg = 0; | |
214 | int ret; | |
215 | ||
216 | if (reg > 0xffff) | |
217 | is_index_reg = 1; | |
218 | ||
219 | mask = reg & 0xf000; | |
220 | ||
221 | if (is_index_reg) { /* index registers */ | |
222 | val2 = reg & 0xff; | |
223 | reg = reg >> 8; | |
224 | nid = reg & 0xff; | |
225 | ret = regmap_write(rt700->sdw_regmap, reg, 0); | |
226 | if (ret < 0) | |
227 | return ret; | |
228 | reg2 = reg + 0x1000; | |
229 | reg2 |= 0x80; | |
230 | ret = regmap_write(rt700->sdw_regmap, reg2, val2); | |
231 | if (ret < 0) | |
232 | return ret; | |
233 | ||
234 | reg3 = RT700_PRIV_DATA_W_H | nid; | |
235 | ret = regmap_write(rt700->sdw_regmap, | |
236 | reg3, ((val >> 8) & 0xff)); | |
237 | if (ret < 0) | |
238 | return ret; | |
239 | reg4 = reg3 + 0x1000; | |
240 | reg4 |= 0x80; | |
241 | ret = regmap_write(rt700->sdw_regmap, reg4, (val & 0xff)); | |
242 | if (ret < 0) | |
243 | return ret; | |
244 | is_index_reg = 1; | |
245 | } else if (reg < 0x4fff) { | |
246 | ret = regmap_write(rt700->sdw_regmap, reg, val); | |
247 | if (ret < 0) | |
248 | return ret; | |
249 | } else if (reg == 0xff01) { | |
250 | ret = regmap_write(rt700->sdw_regmap, reg, val); | |
251 | if (ret < 0) | |
252 | return ret; | |
253 | } else if (mask == 0x7000) { | |
254 | ret = regmap_write(rt700->sdw_regmap, | |
255 | reg, ((val >> 8) & 0xff)); | |
256 | if (ret < 0) | |
257 | return ret; | |
258 | reg2 = reg + 0x1000; | |
259 | reg2 |= 0x80; | |
260 | ret = regmap_write(rt700->sdw_regmap, reg2, (val & 0xff)); | |
261 | if (ret < 0) | |
262 | return ret; | |
263 | } else if ((reg & 0xff00) == 0x8300) { /* for R channel */ | |
264 | reg2 = reg - 0x1000; | |
265 | reg2 &= ~0x80; | |
266 | ret = regmap_write(rt700->sdw_regmap, | |
267 | reg2, ((val >> 8) & 0xff)); | |
268 | if (ret < 0) | |
269 | return ret; | |
270 | ret = regmap_write(rt700->sdw_regmap, reg, (val & 0xff)); | |
271 | if (ret < 0) | |
272 | return ret; | |
273 | } | |
274 | ||
275 | if (reg2 == 0) | |
276 | dev_dbg(dev, "[%s] %04x <= %04x\n", __func__, reg, val); | |
277 | else if (is_index_reg) | |
278 | dev_dbg(dev, "[%s] %04x %04x %04x %04x <= %04x %04x\n", | |
279 | __func__, reg, reg2, reg3, reg4, val2, val); | |
280 | else | |
281 | dev_dbg(dev, "[%s] %04x %04x <= %04x\n", | |
282 | __func__, reg, reg2, val); | |
283 | ||
284 | return 0; | |
285 | } | |
286 | ||
287 | static const struct regmap_config rt700_regmap = { | |
288 | .reg_bits = 24, | |
289 | .val_bits = 32, | |
290 | .readable_reg = rt700_readable_register, | |
291 | .volatile_reg = rt700_volatile_register, | |
292 | .max_register = 0x755800, | |
293 | .reg_defaults = rt700_reg_defaults, | |
294 | .num_reg_defaults = ARRAY_SIZE(rt700_reg_defaults), | |
295 | .cache_type = REGCACHE_RBTREE, | |
296 | .use_single_read = true, | |
297 | .use_single_write = true, | |
298 | .reg_read = rt700_sdw_read, | |
299 | .reg_write = rt700_sdw_write, | |
300 | }; | |
301 | ||
302 | static const struct regmap_config rt700_sdw_regmap = { | |
303 | .name = "sdw", | |
304 | .reg_bits = 32, | |
305 | .val_bits = 8, | |
306 | .readable_reg = rt700_readable_register, | |
307 | .max_register = 0xff01, | |
308 | .cache_type = REGCACHE_NONE, | |
309 | .use_single_read = true, | |
310 | .use_single_write = true, | |
311 | }; | |
312 | ||
313 | static int rt700_update_status(struct sdw_slave *slave, | |
314 | enum sdw_slave_status status) | |
315 | { | |
316 | struct rt700_priv *rt700 = dev_get_drvdata(&slave->dev); | |
317 | ||
7d2a5f9a SF |
318 | if (status == SDW_SLAVE_UNATTACHED) |
319 | rt700->hw_init = false; | |
320 | ||
321 | /* | |
322 | * Perform initialization only if slave status is present and | |
323 | * hw_init flag is false | |
324 | */ | |
9564c9f6 | 325 | if (rt700->hw_init || status != SDW_SLAVE_ATTACHED) |
7d2a5f9a SF |
326 | return 0; |
327 | ||
328 | /* perform I/O transfers required for Slave initialization */ | |
329 | return rt700_io_init(&slave->dev, slave); | |
330 | } | |
331 | ||
332 | static int rt700_read_prop(struct sdw_slave *slave) | |
333 | { | |
334 | struct sdw_slave_prop *prop = &slave->prop; | |
d0bbcb4e | 335 | int nval, i; |
7d2a5f9a SF |
336 | u32 bit; |
337 | unsigned long addr; | |
338 | struct sdw_dpn_prop *dpn; | |
339 | ||
2acd30b9 PLB |
340 | prop->scp_int1_mask = SDW_SCP_INT1_IMPL_DEF | SDW_SCP_INT1_BUS_CLASH | |
341 | SDW_SCP_INT1_PARITY; | |
38edbfae | 342 | prop->quirks = SDW_SLAVE_QUIRKS_INVALID_INITIAL_PARITY; |
2acd30b9 | 343 | |
7d2a5f9a SF |
344 | prop->paging_support = false; |
345 | ||
346 | /* first we need to allocate memory for set bits in port lists */ | |
347 | prop->source_ports = 0x14; /* BITMAP: 00010100 */ | |
348 | prop->sink_ports = 0xA; /* BITMAP: 00001010 */ | |
349 | ||
350 | nval = hweight32(prop->source_ports); | |
7d2a5f9a SF |
351 | prop->src_dpn_prop = devm_kcalloc(&slave->dev, nval, |
352 | sizeof(*prop->src_dpn_prop), | |
353 | GFP_KERNEL); | |
354 | if (!prop->src_dpn_prop) | |
355 | return -ENOMEM; | |
356 | ||
357 | i = 0; | |
358 | dpn = prop->src_dpn_prop; | |
359 | addr = prop->source_ports; | |
360 | for_each_set_bit(bit, &addr, 32) { | |
361 | dpn[i].num = bit; | |
362 | dpn[i].type = SDW_DPN_FULL; | |
363 | dpn[i].simple_ch_prep_sm = true; | |
364 | dpn[i].ch_prep_timeout = 10; | |
365 | i++; | |
366 | } | |
367 | ||
368 | /* do this again for sink now */ | |
369 | nval = hweight32(prop->sink_ports); | |
7d2a5f9a SF |
370 | prop->sink_dpn_prop = devm_kcalloc(&slave->dev, nval, |
371 | sizeof(*prop->sink_dpn_prop), | |
372 | GFP_KERNEL); | |
373 | if (!prop->sink_dpn_prop) | |
374 | return -ENOMEM; | |
375 | ||
376 | i = 0; | |
377 | dpn = prop->sink_dpn_prop; | |
378 | addr = prop->sink_ports; | |
379 | for_each_set_bit(bit, &addr, 32) { | |
380 | dpn[i].num = bit; | |
381 | dpn[i].type = SDW_DPN_FULL; | |
382 | dpn[i].simple_ch_prep_sm = true; | |
383 | dpn[i].ch_prep_timeout = 10; | |
384 | i++; | |
385 | } | |
386 | ||
7d2a5f9a SF |
387 | /* set the timeout values */ |
388 | prop->clk_stop_timeout = 20; | |
389 | ||
390 | /* wake-up event */ | |
391 | prop->wake_capable = 1; | |
392 | ||
393 | return 0; | |
394 | } | |
395 | ||
396 | static int rt700_bus_config(struct sdw_slave *slave, | |
397 | struct sdw_bus_params *params) | |
398 | { | |
399 | struct rt700_priv *rt700 = dev_get_drvdata(&slave->dev); | |
400 | int ret; | |
401 | ||
402 | memcpy(&rt700->params, params, sizeof(*params)); | |
403 | ||
404 | ret = rt700_clock_config(&slave->dev); | |
405 | if (ret < 0) | |
406 | dev_err(&slave->dev, "Invalid clk config"); | |
407 | ||
408 | return ret; | |
409 | } | |
410 | ||
411 | static int rt700_interrupt_callback(struct sdw_slave *slave, | |
412 | struct sdw_slave_intr_status *status) | |
413 | { | |
414 | struct rt700_priv *rt700 = dev_get_drvdata(&slave->dev); | |
415 | ||
416 | dev_dbg(&slave->dev, | |
417 | "%s control_port_stat=%x", __func__, status->control_port); | |
418 | ||
60888ef8 PLB |
419 | mutex_lock(&rt700->disable_irq_lock); |
420 | if (status->control_port & 0x4 && !rt700->disable_irq) { | |
7d2a5f9a SF |
421 | mod_delayed_work(system_power_efficient_wq, |
422 | &rt700->jack_detect_work, msecs_to_jiffies(250)); | |
423 | } | |
60888ef8 | 424 | mutex_unlock(&rt700->disable_irq_lock); |
7d2a5f9a SF |
425 | |
426 | return 0; | |
427 | } | |
428 | ||
429 | /* | |
430 | * slave_ops: callbacks for get_clock_stop_mode, clock_stop and | |
431 | * port_prep are not defined for now | |
432 | */ | |
628fc9d9 | 433 | static const struct sdw_slave_ops rt700_slave_ops = { |
7d2a5f9a SF |
434 | .read_prop = rt700_read_prop, |
435 | .interrupt_callback = rt700_interrupt_callback, | |
436 | .update_status = rt700_update_status, | |
437 | .bus_config = rt700_bus_config, | |
438 | }; | |
439 | ||
440 | static int rt700_sdw_probe(struct sdw_slave *slave, | |
441 | const struct sdw_device_id *id) | |
442 | { | |
443 | struct regmap *sdw_regmap, *regmap; | |
444 | ||
7d2a5f9a SF |
445 | /* Regmap Initialization */ |
446 | sdw_regmap = devm_regmap_init_sdw(slave, &rt700_sdw_regmap); | |
db1a4250 VK |
447 | if (IS_ERR(sdw_regmap)) |
448 | return PTR_ERR(sdw_regmap); | |
7d2a5f9a SF |
449 | |
450 | regmap = devm_regmap_init(&slave->dev, NULL, | |
451 | &slave->dev, &rt700_regmap); | |
20435df1 WY |
452 | if (IS_ERR(regmap)) |
453 | return PTR_ERR(regmap); | |
7d2a5f9a SF |
454 | |
455 | rt700_init(&slave->dev, sdw_regmap, regmap, slave); | |
456 | ||
457 | return 0; | |
458 | } | |
459 | ||
460 | static int rt700_sdw_remove(struct sdw_slave *slave) | |
461 | { | |
462 | struct rt700_priv *rt700 = dev_get_drvdata(&slave->dev); | |
463 | ||
ac63716d | 464 | if (rt700->hw_init) { |
737ee8bd PLB |
465 | cancel_delayed_work_sync(&rt700->jack_detect_work); |
466 | cancel_delayed_work_sync(&rt700->jack_btn_check_work); | |
7d2a5f9a SF |
467 | } |
468 | ||
ac63716d PLB |
469 | if (rt700->first_hw_init) |
470 | pm_runtime_disable(&slave->dev); | |
471 | ||
7d2a5f9a SF |
472 | return 0; |
473 | } | |
474 | ||
475 | static const struct sdw_device_id rt700_id[] = { | |
9e473058 | 476 | SDW_SLAVE_ENTRY_EXT(0x025d, 0x700, 0x1, 0, 0), |
7d2a5f9a SF |
477 | {}, |
478 | }; | |
479 | MODULE_DEVICE_TABLE(sdw, rt700_id); | |
480 | ||
809a9b63 | 481 | static int __maybe_unused rt700_dev_suspend(struct device *dev) |
7d2a5f9a SF |
482 | { |
483 | struct rt700_priv *rt700 = dev_get_drvdata(dev); | |
484 | ||
485 | if (!rt700->hw_init) | |
486 | return 0; | |
487 | ||
5f2df2a4 SF |
488 | cancel_delayed_work_sync(&rt700->jack_detect_work); |
489 | cancel_delayed_work_sync(&rt700->jack_btn_check_work); | |
490 | ||
7d2a5f9a SF |
491 | regcache_cache_only(rt700->regmap, true); |
492 | ||
493 | return 0; | |
494 | } | |
495 | ||
60888ef8 PLB |
496 | static int __maybe_unused rt700_dev_system_suspend(struct device *dev) |
497 | { | |
498 | struct sdw_slave *slave = dev_to_sdw_dev(dev); | |
499 | struct rt700_priv *rt700 = dev_get_drvdata(dev); | |
500 | int ret; | |
501 | ||
502 | if (!rt700->hw_init) | |
503 | return 0; | |
504 | ||
505 | /* | |
506 | * prevent new interrupts from being handled after the | |
507 | * deferred work completes and before the parent disables | |
508 | * interrupts on the link | |
509 | */ | |
510 | mutex_lock(&rt700->disable_irq_lock); | |
511 | rt700->disable_irq = true; | |
512 | ret = sdw_update_no_pm(slave, SDW_SCP_INTMASK1, | |
513 | SDW_SCP_INT1_IMPL_DEF, 0); | |
514 | mutex_unlock(&rt700->disable_irq_lock); | |
515 | ||
516 | if (ret < 0) { | |
517 | /* log but don't prevent suspend from happening */ | |
518 | dev_dbg(&slave->dev, "%s: could not disable imp-def interrupts\n:", __func__); | |
519 | } | |
520 | ||
521 | return rt700_dev_suspend(dev); | |
522 | } | |
523 | ||
7ef8c9ed | 524 | #define RT700_PROBE_TIMEOUT 5000 |
7d2a5f9a | 525 | |
809a9b63 | 526 | static int __maybe_unused rt700_dev_resume(struct device *dev) |
7d2a5f9a SF |
527 | { |
528 | struct sdw_slave *slave = dev_to_sdw_dev(dev); | |
529 | struct rt700_priv *rt700 = dev_get_drvdata(dev); | |
530 | unsigned long time; | |
531 | ||
a9e54e5f | 532 | if (!rt700->first_hw_init) |
7d2a5f9a SF |
533 | return 0; |
534 | ||
535 | if (!slave->unattach_request) | |
536 | goto regmap_sync; | |
537 | ||
538 | time = wait_for_completion_timeout(&slave->initialization_complete, | |
539 | msecs_to_jiffies(RT700_PROBE_TIMEOUT)); | |
540 | if (!time) { | |
541 | dev_err(&slave->dev, "Initialization not complete, timed out\n"); | |
917df025 PLB |
542 | sdw_show_ping_status(slave->bus, true); |
543 | ||
7d2a5f9a SF |
544 | return -ETIMEDOUT; |
545 | } | |
546 | ||
547 | regmap_sync: | |
548 | slave->unattach_request = 0; | |
549 | regcache_cache_only(rt700->regmap, false); | |
550 | regcache_sync_region(rt700->regmap, 0x3000, 0x8fff); | |
551 | regcache_sync_region(rt700->regmap, 0x752010, 0x75206b); | |
552 | ||
553 | return 0; | |
554 | } | |
555 | ||
556 | static const struct dev_pm_ops rt700_pm = { | |
60888ef8 | 557 | SET_SYSTEM_SLEEP_PM_OPS(rt700_dev_system_suspend, rt700_dev_resume) |
7d2a5f9a SF |
558 | SET_RUNTIME_PM_OPS(rt700_dev_suspend, rt700_dev_resume, NULL) |
559 | }; | |
560 | ||
561 | static struct sdw_driver rt700_sdw_driver = { | |
562 | .driver = { | |
563 | .name = "rt700", | |
564 | .owner = THIS_MODULE, | |
565 | .pm = &rt700_pm, | |
566 | }, | |
567 | .probe = rt700_sdw_probe, | |
568 | .remove = rt700_sdw_remove, | |
569 | .ops = &rt700_slave_ops, | |
570 | .id_table = rt700_id, | |
571 | }; | |
572 | module_sdw_driver(rt700_sdw_driver); | |
573 | ||
574 | MODULE_DESCRIPTION("ASoC RT700 driver SDW"); | |
575 | MODULE_AUTHOR("Shuming Fan <shumingf@realtek.com>"); | |
576 | MODULE_LICENSE("GPL v2"); |