]>
Commit | Line | Data |
---|---|---|
2b6a321d AD |
1 | /* |
2 | * Copyright (c) 2011-2016 Synaptics Incorporated | |
3 | * Copyright (c) 2011 Unixphere | |
4 | * | |
5 | * This program is free software; you can redistribute it and/or modify it | |
6 | * under the terms of the GNU General Public License version 2 as published by | |
7 | * the Free Software Foundation. | |
8 | */ | |
9 | ||
10 | #include <linux/kernel.h> | |
11 | #include <linux/kconfig.h> | |
12 | #include <linux/rmi.h> | |
13 | #include <linux/slab.h> | |
14 | #include <linux/uaccess.h> | |
15 | #include <linux/of.h> | |
16 | #include "rmi_driver.h" | |
17 | ||
18 | #define RMI_PRODUCT_ID_LENGTH 10 | |
19 | #define RMI_PRODUCT_INFO_LENGTH 2 | |
20 | ||
21 | #define RMI_DATE_CODE_LENGTH 3 | |
22 | ||
23 | #define PRODUCT_ID_OFFSET 0x10 | |
24 | #define PRODUCT_INFO_OFFSET 0x1E | |
25 | ||
26 | ||
27 | /* Force a firmware reset of the sensor */ | |
28 | #define RMI_F01_CMD_DEVICE_RESET 1 | |
29 | ||
30 | /* Various F01_RMI_QueryX bits */ | |
31 | ||
32 | #define RMI_F01_QRY1_CUSTOM_MAP BIT(0) | |
33 | #define RMI_F01_QRY1_NON_COMPLIANT BIT(1) | |
34 | #define RMI_F01_QRY1_HAS_LTS BIT(2) | |
35 | #define RMI_F01_QRY1_HAS_SENSOR_ID BIT(3) | |
36 | #define RMI_F01_QRY1_HAS_CHARGER_INP BIT(4) | |
37 | #define RMI_F01_QRY1_HAS_ADJ_DOZE BIT(5) | |
38 | #define RMI_F01_QRY1_HAS_ADJ_DOZE_HOFF BIT(6) | |
39 | #define RMI_F01_QRY1_HAS_QUERY42 BIT(7) | |
40 | ||
41 | #define RMI_F01_QRY5_YEAR_MASK 0x1f | |
42 | #define RMI_F01_QRY6_MONTH_MASK 0x0f | |
43 | #define RMI_F01_QRY7_DAY_MASK 0x1f | |
44 | ||
45 | #define RMI_F01_QRY2_PRODINFO_MASK 0x7f | |
46 | ||
47 | #define RMI_F01_BASIC_QUERY_LEN 21 /* From Query 00 through 20 */ | |
48 | ||
49 | struct f01_basic_properties { | |
50 | u8 manufacturer_id; | |
51 | bool has_lts; | |
52 | bool has_adjustable_doze; | |
53 | bool has_adjustable_doze_holdoff; | |
54 | char dom[11]; /* YYYY/MM/DD + '\0' */ | |
55 | u8 product_id[RMI_PRODUCT_ID_LENGTH + 1]; | |
56 | u16 productinfo; | |
57 | u32 firmware_id; | |
58 | }; | |
59 | ||
60 | /* F01 device status bits */ | |
61 | ||
62 | /* Most recent device status event */ | |
63 | #define RMI_F01_STATUS_CODE(status) ((status) & 0x0f) | |
64 | /* The device has lost its configuration for some reason. */ | |
65 | #define RMI_F01_STATUS_UNCONFIGURED(status) (!!((status) & 0x80)) | |
66 | ||
67 | /* Control register bits */ | |
68 | ||
69 | /* | |
70 | * Sleep mode controls power management on the device and affects all | |
71 | * functions of the device. | |
72 | */ | |
73 | #define RMI_F01_CTRL0_SLEEP_MODE_MASK 0x03 | |
74 | ||
75 | #define RMI_SLEEP_MODE_NORMAL 0x00 | |
76 | #define RMI_SLEEP_MODE_SENSOR_SLEEP 0x01 | |
77 | #define RMI_SLEEP_MODE_RESERVED0 0x02 | |
78 | #define RMI_SLEEP_MODE_RESERVED1 0x03 | |
79 | ||
80 | /* | |
81 | * This bit disables whatever sleep mode may be selected by the sleep_mode | |
82 | * field and forces the device to run at full power without sleeping. | |
83 | */ | |
e9000b79 | 84 | #define RMI_F01_CTRL0_NOSLEEP_BIT BIT(2) |
2b6a321d AD |
85 | |
86 | /* | |
87 | * When this bit is set, the touch controller employs a noise-filtering | |
88 | * algorithm designed for use with a connected battery charger. | |
89 | */ | |
e9000b79 | 90 | #define RMI_F01_CTRL0_CHARGER_BIT BIT(5) |
2b6a321d AD |
91 | |
92 | /* | |
93 | * Sets the report rate for the device. The effect of this setting is | |
94 | * highly product dependent. Check the spec sheet for your particular | |
95 | * touch sensor. | |
96 | */ | |
e9000b79 | 97 | #define RMI_F01_CTRL0_REPORTRATE_BIT BIT(6) |
2b6a321d AD |
98 | |
99 | /* | |
100 | * Written by the host as an indicator that the device has been | |
101 | * successfully configured. | |
102 | */ | |
e9000b79 | 103 | #define RMI_F01_CTRL0_CONFIGURED_BIT BIT(7) |
2b6a321d AD |
104 | |
105 | /** | |
106 | * @ctrl0 - see the bit definitions above. | |
107 | * @doze_interval - controls the interval between checks for finger presence | |
108 | * when the touch sensor is in doze mode, in units of 10ms. | |
109 | * @wakeup_threshold - controls the capacitance threshold at which the touch | |
110 | * sensor will decide to wake up from that low power state. | |
111 | * @doze_holdoff - controls how long the touch sensor waits after the last | |
112 | * finger lifts before entering the doze state, in units of 100ms. | |
113 | */ | |
114 | struct f01_device_control { | |
115 | u8 ctrl0; | |
116 | u8 doze_interval; | |
117 | u8 wakeup_threshold; | |
118 | u8 doze_holdoff; | |
119 | }; | |
120 | ||
121 | struct f01_data { | |
122 | struct f01_basic_properties properties; | |
123 | struct f01_device_control device_control; | |
124 | ||
125 | u16 doze_interval_addr; | |
126 | u16 wakeup_threshold_addr; | |
127 | u16 doze_holdoff_addr; | |
128 | ||
129 | bool suspended; | |
130 | bool old_nosleep; | |
131 | ||
132 | unsigned int num_of_irq_regs; | |
133 | }; | |
134 | ||
135 | static int rmi_f01_read_properties(struct rmi_device *rmi_dev, | |
136 | u16 query_base_addr, | |
137 | struct f01_basic_properties *props) | |
138 | { | |
139 | u8 queries[RMI_F01_BASIC_QUERY_LEN]; | |
140 | int ret; | |
141 | int query_offset = query_base_addr; | |
142 | bool has_ds4_queries = false; | |
143 | bool has_query42 = false; | |
144 | bool has_sensor_id = false; | |
145 | bool has_package_id_query = false; | |
146 | bool has_build_id_query = false; | |
147 | u16 prod_info_addr; | |
148 | u8 ds4_query_len; | |
149 | ||
150 | ret = rmi_read_block(rmi_dev, query_offset, | |
151 | queries, RMI_F01_BASIC_QUERY_LEN); | |
152 | if (ret) { | |
153 | dev_err(&rmi_dev->dev, | |
154 | "Failed to read device query registers: %d\n", ret); | |
155 | return ret; | |
156 | } | |
157 | ||
158 | prod_info_addr = query_offset + 17; | |
159 | query_offset += RMI_F01_BASIC_QUERY_LEN; | |
160 | ||
161 | /* Now parse what we got */ | |
162 | props->manufacturer_id = queries[0]; | |
163 | ||
164 | props->has_lts = queries[1] & RMI_F01_QRY1_HAS_LTS; | |
165 | props->has_adjustable_doze = | |
166 | queries[1] & RMI_F01_QRY1_HAS_ADJ_DOZE; | |
167 | props->has_adjustable_doze_holdoff = | |
168 | queries[1] & RMI_F01_QRY1_HAS_ADJ_DOZE_HOFF; | |
169 | has_query42 = queries[1] & RMI_F01_QRY1_HAS_QUERY42; | |
170 | has_sensor_id = queries[1] & RMI_F01_QRY1_HAS_SENSOR_ID; | |
171 | ||
172 | snprintf(props->dom, sizeof(props->dom), "20%02d/%02d/%02d", | |
173 | queries[5] & RMI_F01_QRY5_YEAR_MASK, | |
174 | queries[6] & RMI_F01_QRY6_MONTH_MASK, | |
175 | queries[7] & RMI_F01_QRY7_DAY_MASK); | |
176 | ||
177 | memcpy(props->product_id, &queries[11], | |
178 | RMI_PRODUCT_ID_LENGTH); | |
179 | props->product_id[RMI_PRODUCT_ID_LENGTH] = '\0'; | |
180 | ||
181 | props->productinfo = | |
182 | ((queries[2] & RMI_F01_QRY2_PRODINFO_MASK) << 7) | | |
183 | (queries[3] & RMI_F01_QRY2_PRODINFO_MASK); | |
184 | ||
185 | if (has_sensor_id) | |
186 | query_offset++; | |
187 | ||
188 | if (has_query42) { | |
189 | ret = rmi_read(rmi_dev, query_offset, queries); | |
190 | if (ret) { | |
191 | dev_err(&rmi_dev->dev, | |
192 | "Failed to read query 42 register: %d\n", ret); | |
193 | return ret; | |
194 | } | |
195 | ||
196 | has_ds4_queries = !!(queries[0] & BIT(0)); | |
197 | query_offset++; | |
198 | } | |
199 | ||
200 | if (has_ds4_queries) { | |
201 | ret = rmi_read(rmi_dev, query_offset, &ds4_query_len); | |
202 | if (ret) { | |
203 | dev_err(&rmi_dev->dev, | |
204 | "Failed to read DS4 queries length: %d\n", ret); | |
205 | return ret; | |
206 | } | |
207 | query_offset++; | |
208 | ||
209 | if (ds4_query_len > 0) { | |
210 | ret = rmi_read(rmi_dev, query_offset, queries); | |
211 | if (ret) { | |
212 | dev_err(&rmi_dev->dev, | |
213 | "Failed to read DS4 queries: %d\n", | |
214 | ret); | |
215 | return ret; | |
216 | } | |
217 | ||
218 | has_package_id_query = !!(queries[0] & BIT(0)); | |
219 | has_build_id_query = !!(queries[0] & BIT(1)); | |
220 | } | |
221 | ||
222 | if (has_package_id_query) | |
223 | prod_info_addr++; | |
224 | ||
225 | if (has_build_id_query) { | |
226 | ret = rmi_read_block(rmi_dev, prod_info_addr, queries, | |
227 | 3); | |
228 | if (ret) { | |
229 | dev_err(&rmi_dev->dev, | |
230 | "Failed to read product info: %d\n", | |
231 | ret); | |
232 | return ret; | |
233 | } | |
234 | ||
235 | props->firmware_id = queries[1] << 8 | queries[0]; | |
236 | props->firmware_id += queries[2] * 65536; | |
237 | } | |
238 | } | |
239 | ||
240 | return 0; | |
241 | } | |
242 | ||
243 | char *rmi_f01_get_product_ID(struct rmi_function *fn) | |
244 | { | |
245 | struct f01_data *f01 = dev_get_drvdata(&fn->dev); | |
246 | ||
247 | return f01->properties.product_id; | |
248 | } | |
249 | ||
d8a8b3ed AD |
250 | #ifdef CONFIG_OF |
251 | static int rmi_f01_of_probe(struct device *dev, | |
252 | struct rmi_device_platform_data *pdata) | |
253 | { | |
254 | int retval; | |
255 | u32 val; | |
256 | ||
257 | retval = rmi_of_property_read_u32(dev, | |
258 | (u32 *)&pdata->power_management.nosleep, | |
259 | "syna,nosleep-mode", 1); | |
260 | if (retval) | |
261 | return retval; | |
262 | ||
263 | retval = rmi_of_property_read_u32(dev, &val, | |
264 | "syna,wakeup-threshold", 1); | |
265 | if (retval) | |
266 | return retval; | |
267 | ||
268 | pdata->power_management.wakeup_threshold = val; | |
269 | ||
270 | retval = rmi_of_property_read_u32(dev, &val, | |
271 | "syna,doze-holdoff-ms", 1); | |
272 | if (retval) | |
273 | return retval; | |
274 | ||
275 | pdata->power_management.doze_holdoff = val * 100; | |
276 | ||
277 | retval = rmi_of_property_read_u32(dev, &val, | |
278 | "syna,doze-interval-ms", 1); | |
279 | if (retval) | |
280 | return retval; | |
281 | ||
282 | pdata->power_management.doze_interval = val / 10; | |
283 | ||
284 | return 0; | |
285 | } | |
286 | #else | |
287 | static inline int rmi_f01_of_probe(struct device *dev, | |
288 | struct rmi_device_platform_data *pdata) | |
289 | { | |
290 | return -ENODEV; | |
291 | } | |
292 | #endif | |
293 | ||
2b6a321d AD |
294 | static int rmi_f01_probe(struct rmi_function *fn) |
295 | { | |
296 | struct rmi_device *rmi_dev = fn->rmi_dev; | |
297 | struct rmi_driver_data *driver_data = dev_get_drvdata(&rmi_dev->dev); | |
298 | struct rmi_device_platform_data *pdata = rmi_get_platform_data(rmi_dev); | |
299 | struct f01_data *f01; | |
300 | int error; | |
301 | u16 ctrl_base_addr = fn->fd.control_base_addr; | |
302 | u8 device_status; | |
303 | u8 temp; | |
304 | ||
d8a8b3ed AD |
305 | if (fn->dev.of_node) { |
306 | error = rmi_f01_of_probe(&fn->dev, pdata); | |
307 | if (error) | |
308 | return error; | |
309 | } | |
310 | ||
2b6a321d AD |
311 | f01 = devm_kzalloc(&fn->dev, sizeof(struct f01_data), GFP_KERNEL); |
312 | if (!f01) | |
313 | return -ENOMEM; | |
314 | ||
315 | f01->num_of_irq_regs = driver_data->num_of_irq_regs; | |
316 | ||
317 | /* | |
318 | * Set the configured bit and (optionally) other important stuff | |
319 | * in the device control register. | |
320 | */ | |
321 | ||
322 | error = rmi_read(rmi_dev, fn->fd.control_base_addr, | |
323 | &f01->device_control.ctrl0); | |
324 | if (error) { | |
325 | dev_err(&fn->dev, "Failed to read F01 control: %d\n", error); | |
326 | return error; | |
327 | } | |
328 | ||
329 | switch (pdata->power_management.nosleep) { | |
2775e523 | 330 | case RMI_REG_STATE_DEFAULT: |
2b6a321d | 331 | break; |
2775e523 | 332 | case RMI_REG_STATE_OFF: |
e9000b79 | 333 | f01->device_control.ctrl0 &= ~RMI_F01_CTRL0_NOSLEEP_BIT; |
2b6a321d | 334 | break; |
2775e523 | 335 | case RMI_REG_STATE_ON: |
e9000b79 | 336 | f01->device_control.ctrl0 |= RMI_F01_CTRL0_NOSLEEP_BIT; |
2b6a321d AD |
337 | break; |
338 | } | |
339 | ||
340 | /* | |
341 | * Sleep mode might be set as a hangover from a system crash or | |
342 | * reboot without power cycle. If so, clear it so the sensor | |
343 | * is certain to function. | |
344 | */ | |
345 | if ((f01->device_control.ctrl0 & RMI_F01_CTRL0_SLEEP_MODE_MASK) != | |
346 | RMI_SLEEP_MODE_NORMAL) { | |
347 | dev_warn(&fn->dev, | |
348 | "WARNING: Non-zero sleep mode found. Clearing...\n"); | |
349 | f01->device_control.ctrl0 &= ~RMI_F01_CTRL0_SLEEP_MODE_MASK; | |
350 | } | |
351 | ||
e9000b79 | 352 | f01->device_control.ctrl0 |= RMI_F01_CTRL0_CONFIGURED_BIT; |
2b6a321d AD |
353 | |
354 | error = rmi_write(rmi_dev, fn->fd.control_base_addr, | |
355 | f01->device_control.ctrl0); | |
356 | if (error) { | |
357 | dev_err(&fn->dev, "Failed to write F01 control: %d\n", error); | |
358 | return error; | |
359 | } | |
360 | ||
361 | /* Dummy read in order to clear irqs */ | |
362 | error = rmi_read(rmi_dev, fn->fd.data_base_addr + 1, &temp); | |
363 | if (error < 0) { | |
364 | dev_err(&fn->dev, "Failed to read Interrupt Status.\n"); | |
365 | return error; | |
366 | } | |
367 | ||
368 | error = rmi_f01_read_properties(rmi_dev, fn->fd.query_base_addr, | |
369 | &f01->properties); | |
370 | if (error < 0) { | |
371 | dev_err(&fn->dev, "Failed to read F01 properties.\n"); | |
372 | return error; | |
373 | } | |
374 | ||
375 | dev_info(&fn->dev, "found RMI device, manufacturer: %s, product: %s, fw id: %d\n", | |
376 | f01->properties.manufacturer_id == 1 ? "Synaptics" : "unknown", | |
377 | f01->properties.product_id, f01->properties.firmware_id); | |
378 | ||
379 | /* Advance to interrupt control registers, then skip over them. */ | |
380 | ctrl_base_addr++; | |
381 | ctrl_base_addr += f01->num_of_irq_regs; | |
382 | ||
383 | /* read control register */ | |
384 | if (f01->properties.has_adjustable_doze) { | |
385 | f01->doze_interval_addr = ctrl_base_addr; | |
386 | ctrl_base_addr++; | |
387 | ||
388 | if (pdata->power_management.doze_interval) { | |
389 | f01->device_control.doze_interval = | |
390 | pdata->power_management.doze_interval; | |
391 | error = rmi_write(rmi_dev, f01->doze_interval_addr, | |
392 | f01->device_control.doze_interval); | |
393 | if (error) { | |
394 | dev_err(&fn->dev, | |
395 | "Failed to configure F01 doze interval register: %d\n", | |
396 | error); | |
397 | return error; | |
398 | } | |
399 | } else { | |
400 | error = rmi_read(rmi_dev, f01->doze_interval_addr, | |
401 | &f01->device_control.doze_interval); | |
402 | if (error) { | |
403 | dev_err(&fn->dev, | |
404 | "Failed to read F01 doze interval register: %d\n", | |
405 | error); | |
406 | return error; | |
407 | } | |
408 | } | |
409 | ||
410 | f01->wakeup_threshold_addr = ctrl_base_addr; | |
411 | ctrl_base_addr++; | |
412 | ||
413 | if (pdata->power_management.wakeup_threshold) { | |
414 | f01->device_control.wakeup_threshold = | |
415 | pdata->power_management.wakeup_threshold; | |
416 | error = rmi_write(rmi_dev, f01->wakeup_threshold_addr, | |
417 | f01->device_control.wakeup_threshold); | |
418 | if (error) { | |
419 | dev_err(&fn->dev, | |
420 | "Failed to configure F01 wakeup threshold register: %d\n", | |
421 | error); | |
422 | return error; | |
423 | } | |
424 | } else { | |
425 | error = rmi_read(rmi_dev, f01->wakeup_threshold_addr, | |
426 | &f01->device_control.wakeup_threshold); | |
427 | if (error < 0) { | |
428 | dev_err(&fn->dev, | |
429 | "Failed to read F01 wakeup threshold register: %d\n", | |
430 | error); | |
431 | return error; | |
432 | } | |
433 | } | |
434 | } | |
435 | ||
436 | if (f01->properties.has_lts) | |
437 | ctrl_base_addr++; | |
438 | ||
439 | if (f01->properties.has_adjustable_doze_holdoff) { | |
440 | f01->doze_holdoff_addr = ctrl_base_addr; | |
441 | ctrl_base_addr++; | |
442 | ||
443 | if (pdata->power_management.doze_holdoff) { | |
444 | f01->device_control.doze_holdoff = | |
445 | pdata->power_management.doze_holdoff; | |
446 | error = rmi_write(rmi_dev, f01->doze_holdoff_addr, | |
447 | f01->device_control.doze_holdoff); | |
448 | if (error) { | |
449 | dev_err(&fn->dev, | |
450 | "Failed to configure F01 doze holdoff register: %d\n", | |
451 | error); | |
452 | return error; | |
453 | } | |
454 | } else { | |
455 | error = rmi_read(rmi_dev, f01->doze_holdoff_addr, | |
456 | &f01->device_control.doze_holdoff); | |
457 | if (error) { | |
458 | dev_err(&fn->dev, | |
459 | "Failed to read F01 doze holdoff register: %d\n", | |
460 | error); | |
461 | return error; | |
462 | } | |
463 | } | |
464 | } | |
465 | ||
466 | error = rmi_read(rmi_dev, fn->fd.data_base_addr, &device_status); | |
467 | if (error < 0) { | |
468 | dev_err(&fn->dev, | |
469 | "Failed to read device status: %d\n", error); | |
470 | return error; | |
471 | } | |
472 | ||
473 | if (RMI_F01_STATUS_UNCONFIGURED(device_status)) { | |
474 | dev_err(&fn->dev, | |
475 | "Device was reset during configuration process, status: %#02x!\n", | |
476 | RMI_F01_STATUS_CODE(device_status)); | |
477 | return -EINVAL; | |
478 | } | |
479 | ||
480 | dev_set_drvdata(&fn->dev, f01); | |
481 | ||
482 | return 0; | |
483 | } | |
484 | ||
485 | static int rmi_f01_config(struct rmi_function *fn) | |
486 | { | |
487 | struct f01_data *f01 = dev_get_drvdata(&fn->dev); | |
488 | int error; | |
489 | ||
490 | error = rmi_write(fn->rmi_dev, fn->fd.control_base_addr, | |
491 | f01->device_control.ctrl0); | |
492 | if (error) { | |
493 | dev_err(&fn->dev, | |
494 | "Failed to write device_control register: %d\n", error); | |
495 | return error; | |
496 | } | |
497 | ||
498 | if (f01->properties.has_adjustable_doze) { | |
499 | error = rmi_write(fn->rmi_dev, f01->doze_interval_addr, | |
500 | f01->device_control.doze_interval); | |
501 | if (error) { | |
502 | dev_err(&fn->dev, | |
503 | "Failed to write doze interval: %d\n", error); | |
504 | return error; | |
505 | } | |
506 | ||
507 | error = rmi_write_block(fn->rmi_dev, | |
508 | f01->wakeup_threshold_addr, | |
509 | &f01->device_control.wakeup_threshold, | |
510 | sizeof(u8)); | |
511 | if (error) { | |
512 | dev_err(&fn->dev, | |
513 | "Failed to write wakeup threshold: %d\n", | |
514 | error); | |
515 | return error; | |
516 | } | |
517 | } | |
518 | ||
519 | if (f01->properties.has_adjustable_doze_holdoff) { | |
520 | error = rmi_write(fn->rmi_dev, f01->doze_holdoff_addr, | |
521 | f01->device_control.doze_holdoff); | |
522 | if (error) { | |
523 | dev_err(&fn->dev, | |
524 | "Failed to write doze holdoff: %d\n", error); | |
525 | return error; | |
526 | } | |
527 | } | |
528 | ||
529 | return 0; | |
530 | } | |
531 | ||
532 | static int rmi_f01_suspend(struct rmi_function *fn) | |
533 | { | |
534 | struct f01_data *f01 = dev_get_drvdata(&fn->dev); | |
535 | int error; | |
536 | ||
537 | f01->old_nosleep = | |
e9000b79 ND |
538 | f01->device_control.ctrl0 & RMI_F01_CTRL0_NOSLEEP_BIT; |
539 | f01->device_control.ctrl0 &= ~RMI_F01_CTRL0_NOSLEEP_BIT; | |
2b6a321d AD |
540 | |
541 | f01->device_control.ctrl0 &= ~RMI_F01_CTRL0_SLEEP_MODE_MASK; | |
542 | if (device_may_wakeup(fn->rmi_dev->xport->dev)) | |
543 | f01->device_control.ctrl0 |= RMI_SLEEP_MODE_RESERVED1; | |
544 | else | |
545 | f01->device_control.ctrl0 |= RMI_SLEEP_MODE_SENSOR_SLEEP; | |
546 | ||
547 | error = rmi_write(fn->rmi_dev, fn->fd.control_base_addr, | |
548 | f01->device_control.ctrl0); | |
549 | if (error) { | |
550 | dev_err(&fn->dev, "Failed to write sleep mode: %d.\n", error); | |
551 | if (f01->old_nosleep) | |
e9000b79 | 552 | f01->device_control.ctrl0 |= RMI_F01_CTRL0_NOSLEEP_BIT; |
2b6a321d AD |
553 | f01->device_control.ctrl0 &= ~RMI_F01_CTRL0_SLEEP_MODE_MASK; |
554 | f01->device_control.ctrl0 |= RMI_SLEEP_MODE_NORMAL; | |
555 | return error; | |
556 | } | |
557 | ||
558 | return 0; | |
559 | } | |
560 | ||
561 | static int rmi_f01_resume(struct rmi_function *fn) | |
562 | { | |
563 | struct f01_data *f01 = dev_get_drvdata(&fn->dev); | |
564 | int error; | |
565 | ||
566 | if (f01->old_nosleep) | |
e9000b79 | 567 | f01->device_control.ctrl0 |= RMI_F01_CTRL0_NOSLEEP_BIT; |
2b6a321d AD |
568 | |
569 | f01->device_control.ctrl0 &= ~RMI_F01_CTRL0_SLEEP_MODE_MASK; | |
570 | f01->device_control.ctrl0 |= RMI_SLEEP_MODE_NORMAL; | |
571 | ||
572 | error = rmi_write(fn->rmi_dev, fn->fd.control_base_addr, | |
573 | f01->device_control.ctrl0); | |
574 | if (error) { | |
575 | dev_err(&fn->dev, | |
576 | "Failed to restore normal operation: %d.\n", error); | |
577 | return error; | |
578 | } | |
579 | ||
580 | return 0; | |
581 | } | |
582 | ||
583 | static int rmi_f01_attention(struct rmi_function *fn, | |
584 | unsigned long *irq_bits) | |
585 | { | |
586 | struct rmi_device *rmi_dev = fn->rmi_dev; | |
587 | int error; | |
588 | u8 device_status; | |
589 | ||
590 | error = rmi_read(rmi_dev, fn->fd.data_base_addr, &device_status); | |
591 | if (error) { | |
592 | dev_err(&fn->dev, | |
593 | "Failed to read device status: %d.\n", error); | |
594 | return error; | |
595 | } | |
596 | ||
597 | if (RMI_F01_STATUS_UNCONFIGURED(device_status)) { | |
598 | dev_warn(&fn->dev, "Device reset detected.\n"); | |
599 | error = rmi_dev->driver->reset_handler(rmi_dev); | |
600 | if (error) { | |
601 | dev_err(&fn->dev, "Device reset failed: %d\n", error); | |
602 | return error; | |
603 | } | |
604 | } | |
605 | ||
606 | return 0; | |
607 | } | |
608 | ||
609 | struct rmi_function_handler rmi_f01_handler = { | |
610 | .driver = { | |
611 | .name = "rmi4_f01", | |
612 | /* | |
613 | * Do not allow user unbinding F01 as it is critical | |
614 | * function. | |
615 | */ | |
616 | .suppress_bind_attrs = true, | |
617 | }, | |
618 | .func = 0x01, | |
619 | .probe = rmi_f01_probe, | |
620 | .config = rmi_f01_config, | |
621 | .attention = rmi_f01_attention, | |
622 | .suspend = rmi_f01_suspend, | |
623 | .resume = rmi_f01_resume, | |
624 | }; |