Input: cyapa - add runtime power management support
[deliverable/linux.git] / drivers / input / mouse / cyapa.c
CommitLineData
d7e34d12
BL
1/*
2 * Cypress APA trackpad with I2C interface
3 *
4 * Author: Dudley Du <dudl@cypress.com>
5 * Further cleanup and restructuring by:
6 * Daniel Kurtz <djkurtz@chromium.org>
7 * Benson Leung <bleung@chromium.org>
8 *
823a11fd 9 * Copyright (C) 2011-2014 Cypress Semiconductor, Inc.
d7e34d12
BL
10 * Copyright (C) 2011-2012 Google, Inc.
11 *
12 * This file is subject to the terms and conditions of the GNU General Public
13 * License. See the file COPYING in the main directory of this archive for
14 * more details.
15 */
16
17#include <linux/delay.h>
18#include <linux/i2c.h>
19#include <linux/input.h>
20#include <linux/input/mt.h>
21#include <linux/interrupt.h>
22#include <linux/module.h>
9f1cd857 23#include <linux/mutex.h>
d7e34d12 24#include <linux/slab.h>
9f1cd857 25#include <linux/uaccess.h>
67286508 26#include <linux/pm_runtime.h>
9f1cd857 27#include "cyapa.h"
d7e34d12 28
d7e34d12 29
6ddaf744
BL
30#define CYAPA_ADAPTER_FUNC_NONE 0
31#define CYAPA_ADAPTER_FUNC_I2C 1
32#define CYAPA_ADAPTER_FUNC_SMBUS 2
33#define CYAPA_ADAPTER_FUNC_BOTH 3
34
9f1cd857 35const char product_id[] = "CYTRA";
d7e34d12 36
9f1cd857 37static int cyapa_reinitialize(struct cyapa *cyapa);
6ddaf744 38
9f1cd857 39static inline bool cyapa_is_bootloader_mode(struct cyapa *cyapa)
d7e34d12 40{
9f1cd857
DD
41 if (cyapa->gen == CYAPA_GEN5 && cyapa->state == CYAPA_STATE_GEN5_BL)
42 return true;
43
44 if (cyapa->gen == CYAPA_GEN3 &&
45 cyapa->state >= CYAPA_STATE_BL_BUSY &&
46 cyapa->state <= CYAPA_STATE_BL_ACTIVE)
47 return true;
48
49 return false;
d7e34d12
BL
50}
51
9f1cd857 52static inline bool cyapa_is_operational_mode(struct cyapa *cyapa)
d7e34d12 53{
9f1cd857
DD
54 if (cyapa->gen == CYAPA_GEN5 && cyapa->state == CYAPA_STATE_GEN5_APP)
55 return true;
56
57 if (cyapa->gen == CYAPA_GEN3 && cyapa->state == CYAPA_STATE_OP)
58 return true;
59
60 return false;
d7e34d12
BL
61}
62
9f1cd857
DD
63/* Returns 0 on success, else negative errno on failure. */
64static ssize_t cyapa_i2c_read(struct cyapa *cyapa, u8 reg, size_t len,
65 u8 *values)
6ddaf744 66{
6ddaf744 67 struct i2c_client *client = cyapa->client;
9f1cd857
DD
68 struct i2c_msg msgs[] = {
69 {
70 .addr = client->addr,
71 .flags = 0,
72 .len = 1,
73 .buf = &reg,
74 },
75 {
76 .addr = client->addr,
77 .flags = I2C_M_RD,
78 .len = len,
79 .buf = values,
80 },
81 };
82 int ret;
6ddaf744 83
9f1cd857 84 ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
6ddaf744 85
9f1cd857
DD
86 if (ret != ARRAY_SIZE(msgs))
87 return ret < 0 ? ret : -EIO;
6ddaf744 88
9f1cd857 89 return 0;
6ddaf744
BL
90}
91
9f1cd857
DD
92/**
93 * cyapa_i2c_write - Execute i2c block data write operation
94 * @cyapa: Handle to this driver
95 * @ret: Offset of the data to written in the register map
96 * @len: number of bytes to write
97 * @values: Data to be written
98 *
99 * Return negative errno code on error; return zero when success.
100 */
101static int cyapa_i2c_write(struct cyapa *cyapa, u8 reg,
102 size_t len, const void *values)
d7e34d12 103{
9f1cd857
DD
104 struct i2c_client *client = cyapa->client;
105 char buf[32];
106 int ret;
d7e34d12 107
9f1cd857
DD
108 if (len > sizeof(buf) - 1)
109 return -ENOMEM;
d7e34d12 110
9f1cd857
DD
111 buf[0] = reg;
112 memcpy(&buf[1], values, len);
d7e34d12 113
9f1cd857
DD
114 ret = i2c_master_send(client, buf, len + 1);
115 if (ret != len + 1)
116 return ret < 0 ? ret : -EIO;
117
118 return 0;
d7e34d12
BL
119}
120
9f1cd857 121static u8 cyapa_check_adapter_functionality(struct i2c_client *client)
d7e34d12 122{
9f1cd857 123 u8 ret = CYAPA_ADAPTER_FUNC_NONE;
d7e34d12 124
9f1cd857
DD
125 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
126 ret |= CYAPA_ADAPTER_FUNC_I2C;
127 if (i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA |
128 I2C_FUNC_SMBUS_BLOCK_DATA |
129 I2C_FUNC_SMBUS_I2C_BLOCK))
130 ret |= CYAPA_ADAPTER_FUNC_SMBUS;
131 return ret;
d7e34d12
BL
132}
133
134/*
135 * Query device for its current operating state.
d7e34d12
BL
136 */
137static int cyapa_get_state(struct cyapa *cyapa)
138{
d7e34d12 139 u8 status[BL_STATUS_SIZE];
9f1cd857
DD
140 u8 cmd[32];
141 /* The i2c address of gen4 and gen5 trackpad device must be even. */
142 bool even_addr = ((cyapa->client->addr & 0x0001) == 0);
143 bool smbus = false;
144 int retries = 2;
823a11fd 145 int error;
d7e34d12
BL
146
147 cyapa->state = CYAPA_STATE_NO_DEVICE;
148
149 /*
150 * Get trackpad status by reading 3 registers starting from 0.
151 * If the device is in the bootloader, this will be BL_HEAD.
152 * If the device is in operation mode, this will be the DATA regs.
153 *
154 */
823a11fd 155 error = cyapa_i2c_reg_read_block(cyapa, BL_HEAD_OFFSET, BL_STATUS_SIZE,
9f1cd857 156 status);
6ddaf744
BL
157
158 /*
159 * On smbus systems in OP mode, the i2c_reg_read will fail with
160 * -ETIMEDOUT. In this case, try again using the smbus equivalent
161 * command. This should return a BL_HEAD indicating CYAPA_STATE_OP.
162 */
9f1cd857
DD
163 if (cyapa->smbus && (error == -ETIMEDOUT || error == -ENXIO)) {
164 if (!even_addr)
165 error = cyapa_read_block(cyapa,
166 CYAPA_CMD_BL_STATUS, status);
167 smbus = true;
168 }
6ddaf744 169
823a11fd 170 if (error != BL_STATUS_SIZE)
d7e34d12
BL
171 goto error;
172
9f1cd857
DD
173 /*
174 * Detect trackpad protocol based on characteristic registers and bits.
175 */
176 do {
177 cyapa->status[REG_OP_STATUS] = status[REG_OP_STATUS];
178 cyapa->status[REG_BL_STATUS] = status[REG_BL_STATUS];
179 cyapa->status[REG_BL_ERROR] = status[REG_BL_ERROR];
180
181 if (cyapa->gen == CYAPA_GEN_UNKNOWN ||
182 cyapa->gen == CYAPA_GEN3) {
183 error = cyapa_gen3_ops.state_parse(cyapa,
184 status, BL_STATUS_SIZE);
185 if (!error)
186 goto out_detected;
d7e34d12 187 }
6972a859
DD
188 if ((cyapa->gen == CYAPA_GEN_UNKNOWN ||
189 cyapa->gen == CYAPA_GEN5) &&
190 !smbus && even_addr) {
191 error = cyapa_gen5_ops.state_parse(cyapa,
192 status, BL_STATUS_SIZE);
193 if (!error)
194 goto out_detected;
195 }
d7e34d12 196
9f1cd857
DD
197 /*
198 * Write 0x00 0x00 to trackpad device to force update its
199 * status, then redo the detection again.
200 */
201 if (!smbus) {
202 cmd[0] = 0x00;
203 cmd[1] = 0x00;
204 error = cyapa_i2c_write(cyapa, 0, 2, cmd);
205 if (error)
206 goto error;
207
208 msleep(50);
209
210 error = cyapa_i2c_read(cyapa, BL_HEAD_OFFSET,
211 BL_STATUS_SIZE, status);
212 if (error)
213 goto error;
214 }
215 } while (--retries > 0 && !smbus);
216
217 goto error;
218
219out_detected:
220 if (cyapa->state <= CYAPA_STATE_BL_BUSY)
221 return -EAGAIN;
d7e34d12 222 return 0;
9f1cd857 223
d7e34d12 224error:
823a11fd 225 return (error < 0) ? error : -EAGAIN;
d7e34d12
BL
226}
227
228/*
229 * Poll device for its status in a loop, waiting up to timeout for a response.
230 *
231 * When the device switches state, it usually takes ~300 ms.
232 * However, when running a new firmware image, the device must calibrate its
233 * sensors, which can take as long as 2 seconds.
234 *
235 * Note: The timeout has granularity of the polling rate, which is 100 ms.
236 *
237 * Returns:
238 * 0 when the device eventually responds with a valid non-busy state.
239 * -ETIMEDOUT if device never responds (too many -EAGAIN)
9f1cd857
DD
240 * -EAGAIN if bootload is busy, or unknown state.
241 * < 0 other errors
d7e34d12 242 */
9f1cd857 243int cyapa_poll_state(struct cyapa *cyapa, unsigned int timeout)
d7e34d12 244{
823a11fd 245 int error;
d7e34d12
BL
246 int tries = timeout / 100;
247
9f1cd857 248 do {
823a11fd 249 error = cyapa_get_state(cyapa);
9f1cd857
DD
250 if (!error && cyapa->state > CYAPA_STATE_BL_BUSY)
251 return 0;
d7e34d12 252
9f1cd857
DD
253 msleep(100);
254 } while (tries--);
d7e34d12 255
9f1cd857 256 return (error == -EAGAIN || error == -ETIMEDOUT) ? -ETIMEDOUT : error;
d7e34d12
BL
257}
258
259/*
260 * Check if device is operational.
261 *
262 * An operational device is responding, has exited bootloader, and has
263 * firmware supported by this driver.
264 *
265 * Returns:
9f1cd857 266 * -ENODEV no device
d7e34d12
BL
267 * -EBUSY no device or in bootloader
268 * -EIO failure while reading from device
9f1cd857 269 * -ETIMEDOUT timeout failure for bus idle or bus no response
d7e34d12
BL
270 * -EAGAIN device is still in bootloader
271 * if ->state = CYAPA_STATE_BL_IDLE, device has invalid firmware
272 * -EINVAL device is in operational mode, but not supported by this driver
273 * 0 device is supported
274 */
275static int cyapa_check_is_operational(struct cyapa *cyapa)
276{
823a11fd 277 int error;
d7e34d12 278
9f1cd857 279 error = cyapa_poll_state(cyapa, 4000);
823a11fd
DD
280 if (error)
281 return error;
d7e34d12 282
9f1cd857 283 switch (cyapa->gen) {
6972a859
DD
284 case CYAPA_GEN5:
285 cyapa->ops = &cyapa_gen5_ops;
286 break;
9f1cd857
DD
287 case CYAPA_GEN3:
288 cyapa->ops = &cyapa_gen3_ops;
289 break;
d7e34d12 290 default:
9f1cd857 291 return -ENODEV;
d7e34d12 292 }
9f1cd857
DD
293
294 error = cyapa->ops->operational_check(cyapa);
295 if (!error && cyapa_is_operational_mode(cyapa))
296 cyapa->operational = true;
297 else
298 cyapa->operational = false;
299
300 return error;
d7e34d12
BL
301}
302
9f1cd857
DD
303
304/*
305 * Returns 0 on device detected, negative errno on no device detected.
306 * And when the device is detected and opertaional, it will be reset to
307 * full power active mode automatically.
308 */
309static int cyapa_detect(struct cyapa *cyapa)
d7e34d12 310{
d7e34d12 311 struct device *dev = &cyapa->client->dev;
9f1cd857 312 int error;
d7e34d12 313
9f1cd857
DD
314 error = cyapa_check_is_operational(cyapa);
315 if (error) {
316 if (error != -ETIMEDOUT && error != -ENODEV &&
317 cyapa_is_bootloader_mode(cyapa)) {
318 dev_warn(dev, "device detected but not operational\n");
319 return 0;
320 }
d7e34d12 321
9f1cd857
DD
322 dev_err(dev, "no device detected: %d\n", error);
323 return error;
d7e34d12
BL
324 }
325
9f1cd857 326 return 0;
6ddaf744
BL
327}
328
b1cfa7b4
DD
329static int cyapa_open(struct input_dev *input)
330{
331 struct cyapa *cyapa = input_get_drvdata(input);
332 struct i2c_client *client = cyapa->client;
333 int error;
334
9f1cd857
DD
335 error = mutex_lock_interruptible(&cyapa->state_sync_lock);
336 if (error)
b1cfa7b4 337 return error;
9f1cd857
DD
338
339 if (cyapa->operational) {
340 /*
341 * though failed to set active power mode,
342 * but still may be able to work in lower scan rate
343 * when in operational mode.
344 */
345 error = cyapa->ops->set_power_mode(cyapa,
346 PWR_MODE_FULL_ACTIVE, 0);
347 if (error) {
348 dev_warn(&client->dev,
349 "set active power failed: %d\n", error);
350 goto out;
351 }
352 } else {
353 error = cyapa_reinitialize(cyapa);
354 if (error || !cyapa->operational) {
355 error = error ? error : -EAGAIN;
356 goto out;
357 }
b1cfa7b4
DD
358 }
359
360 enable_irq(client->irq);
67286508
DD
361 if (!pm_runtime_enabled(&client->dev)) {
362 pm_runtime_set_active(&client->dev);
363 pm_runtime_enable(&client->dev);
364 }
9f1cd857
DD
365out:
366 mutex_unlock(&cyapa->state_sync_lock);
367 return error;
b1cfa7b4
DD
368}
369
370static void cyapa_close(struct input_dev *input)
371{
372 struct cyapa *cyapa = input_get_drvdata(input);
9f1cd857
DD
373 struct i2c_client *client = cyapa->client;
374
375 mutex_lock(&cyapa->state_sync_lock);
b1cfa7b4 376
9f1cd857 377 disable_irq(client->irq);
67286508
DD
378 if (pm_runtime_enabled(&client->dev))
379 pm_runtime_disable(&client->dev);
380 pm_runtime_set_suspended(&client->dev);
381
9f1cd857
DD
382 if (cyapa->operational)
383 cyapa->ops->set_power_mode(cyapa, PWR_MODE_OFF, 0);
384
385 mutex_unlock(&cyapa->state_sync_lock);
b1cfa7b4
DD
386}
387
d7e34d12
BL
388static int cyapa_create_input_dev(struct cyapa *cyapa)
389{
390 struct device *dev = &cyapa->client->dev;
d7e34d12 391 struct input_dev *input;
b1cfa7b4 392 int error;
d7e34d12
BL
393
394 if (!cyapa->physical_size_x || !cyapa->physical_size_y)
395 return -EINVAL;
396
b1cfa7b4 397 input = devm_input_allocate_device(dev);
d7e34d12 398 if (!input) {
823a11fd 399 dev_err(dev, "failed to allocate memory for input device.\n");
d7e34d12
BL
400 return -ENOMEM;
401 }
402
403 input->name = CYAPA_NAME;
404 input->phys = cyapa->phys;
405 input->id.bustype = BUS_I2C;
406 input->id.version = 1;
823a11fd 407 input->id.product = 0; /* Means any product in eventcomm. */
d7e34d12
BL
408 input->dev.parent = &cyapa->client->dev;
409
b1cfa7b4
DD
410 input->open = cyapa_open;
411 input->close = cyapa_close;
412
d7e34d12
BL
413 input_set_drvdata(input, cyapa);
414
415 __set_bit(EV_ABS, input->evbit);
416
823a11fd 417 /* Finger position */
d7e34d12
BL
418 input_set_abs_params(input, ABS_MT_POSITION_X, 0, cyapa->max_abs_x, 0,
419 0);
420 input_set_abs_params(input, ABS_MT_POSITION_Y, 0, cyapa->max_abs_y, 0,
421 0);
9f1cd857
DD
422 input_set_abs_params(input, ABS_MT_PRESSURE, 0, cyapa->max_z, 0, 0);
423 if (cyapa->gen > CYAPA_GEN3) {
424 input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0);
425 input_set_abs_params(input, ABS_MT_TOUCH_MINOR, 0, 255, 0, 0);
426 /*
427 * Orientation is the angle between the vertical axis and
428 * the major axis of the contact ellipse.
429 * The range is -127 to 127.
430 * the positive direction is clockwise form the vertical axis.
431 * If the ellipse of contact degenerates into a circle,
432 * orientation is reported as 0.
433 *
434 * Also, for Gen5 trackpad the accurate of this orientation
435 * value is value + (-30 ~ 30).
436 */
437 input_set_abs_params(input, ABS_MT_ORIENTATION,
438 -127, 127, 0, 0);
439 }
440 if (cyapa->gen >= CYAPA_GEN5) {
441 input_set_abs_params(input, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0);
442 input_set_abs_params(input, ABS_MT_WIDTH_MINOR, 0, 255, 0, 0);
443 }
d7e34d12
BL
444
445 input_abs_set_res(input, ABS_MT_POSITION_X,
446 cyapa->max_abs_x / cyapa->physical_size_x);
447 input_abs_set_res(input, ABS_MT_POSITION_Y,
448 cyapa->max_abs_y / cyapa->physical_size_y);
449
450 if (cyapa->btn_capability & CAPABILITY_LEFT_BTN_MASK)
451 __set_bit(BTN_LEFT, input->keybit);
452 if (cyapa->btn_capability & CAPABILITY_MIDDLE_BTN_MASK)
453 __set_bit(BTN_MIDDLE, input->keybit);
454 if (cyapa->btn_capability & CAPABILITY_RIGHT_BTN_MASK)
455 __set_bit(BTN_RIGHT, input->keybit);
456
457 if (cyapa->btn_capability == CAPABILITY_LEFT_BTN_MASK)
458 __set_bit(INPUT_PROP_BUTTONPAD, input->propbit);
459
823a11fd 460 /* Handle pointer emulation and unused slots in core */
b1cfa7b4
DD
461 error = input_mt_init_slots(input, CYAPA_MAX_MT_SLOTS,
462 INPUT_MT_POINTER | INPUT_MT_DROP_UNUSED);
463 if (error) {
464 dev_err(dev, "failed to initialize MT slots: %d\n", error);
465 return error;
d7e34d12
BL
466 }
467
9f1cd857
DD
468 /* Register the device in input subsystem */
469 error = input_register_device(input);
470 if (error) {
471 dev_err(dev, "failed to register input device: %d\n", error);
472 return error;
473 }
474
b1cfa7b4 475 cyapa->input = input;
d7e34d12 476 return 0;
d7e34d12
BL
477}
478
9f1cd857
DD
479/*
480 * cyapa_sleep_time_to_pwr_cmd and cyapa_pwr_cmd_to_sleep_time
481 *
482 * These are helper functions that convert to and from integer idle
483 * times and register settings to write to the PowerMode register.
484 * The trackpad supports between 20ms to 1000ms scan intervals.
485 * The time will be increased in increments of 10ms from 20ms to 100ms.
486 * From 100ms to 1000ms, time will be increased in increments of 20ms.
487 *
488 * When Idle_Time < 100, the format to convert Idle_Time to Idle_Command is:
489 * Idle_Command = Idle Time / 10;
490 * When Idle_Time >= 100, the format to convert Idle_Time to Idle_Command is:
491 * Idle_Command = Idle Time / 20 + 5;
492 */
493u8 cyapa_sleep_time_to_pwr_cmd(u16 sleep_time)
494{
495 u16 encoded_time;
496
497 sleep_time = clamp_val(sleep_time, 20, 1000);
498 encoded_time = sleep_time < 100 ? sleep_time / 10 : sleep_time / 20 + 5;
499 return (encoded_time << 2) & PWR_MODE_MASK;
500}
501
502u16 cyapa_pwr_cmd_to_sleep_time(u8 pwr_mode)
503{
504 u8 encoded_time = pwr_mode >> 2;
505
506 return (encoded_time < 10) ? encoded_time * 10
507 : (encoded_time - 5) * 20;
508}
509
510/* 0 on driver initialize and detected successfully, negative on failure. */
511static int cyapa_initialize(struct cyapa *cyapa)
512{
513 int error = 0;
514
515 cyapa->state = CYAPA_STATE_NO_DEVICE;
516 cyapa->gen = CYAPA_GEN_UNKNOWN;
517 mutex_init(&cyapa->state_sync_lock);
518
519 /*
520 * Set to hard code default, they will be updated with trackpad set
521 * default values after probe and initialized.
522 */
523 cyapa->suspend_power_mode = PWR_MODE_SLEEP;
524 cyapa->suspend_sleep_time =
525 cyapa_pwr_cmd_to_sleep_time(cyapa->suspend_power_mode);
526
527 /* ops.initialize() is aimed to prepare for module communications. */
528 error = cyapa_gen3_ops.initialize(cyapa);
6972a859
DD
529 if (!error)
530 error = cyapa_gen5_ops.initialize(cyapa);
9f1cd857
DD
531 if (error)
532 return error;
533
534 error = cyapa_detect(cyapa);
535 if (error)
536 return error;
537
538 /* Power down the device until we need it. */
539 if (cyapa->operational)
540 cyapa->ops->set_power_mode(cyapa, PWR_MODE_OFF, 0);
541
542 return 0;
543}
544
545static int cyapa_reinitialize(struct cyapa *cyapa)
546{
547 struct device *dev = &cyapa->client->dev;
548 struct input_dev *input = cyapa->input;
549 int error;
550
67286508
DD
551 if (pm_runtime_enabled(dev))
552 pm_runtime_disable(dev);
553
9f1cd857
DD
554 /* Avoid command failures when TP was in OFF state. */
555 if (cyapa->operational)
556 cyapa->ops->set_power_mode(cyapa, PWR_MODE_FULL_ACTIVE, 0);
557
558 error = cyapa_detect(cyapa);
559 if (error)
560 goto out;
561
562 if (!input && cyapa->operational) {
563 error = cyapa_create_input_dev(cyapa);
564 if (error) {
565 dev_err(dev, "create input_dev instance failed: %d\n",
566 error);
567 goto out;
568 }
569 }
570
571out:
572 if (!input || !input->users) {
573 /* Reset to power OFF state to save power when no user open. */
574 if (cyapa->operational)
575 cyapa->ops->set_power_mode(cyapa, PWR_MODE_OFF, 0);
67286508
DD
576 } else if (!error && cyapa->operational) {
577 /*
578 * Make sure only enable runtime PM when device is
579 * in operational mode and input->users > 0.
580 */
581 pm_runtime_set_active(dev);
582 pm_runtime_enable(dev);
9f1cd857
DD
583 }
584
585 return error;
586}
587
588static irqreturn_t cyapa_irq(int irq, void *dev_id)
589{
590 struct cyapa *cyapa = dev_id;
591 struct device *dev = &cyapa->client->dev;
592
67286508 593 pm_runtime_get_sync(dev);
9f1cd857
DD
594 if (device_may_wakeup(dev))
595 pm_wakeup_event(dev, 0);
596
597 /* Interrupt event maybe cuased by host command to trackpad device. */
598 if (cyapa->ops->irq_cmd_handler(cyapa)) {
599 /*
600 * Interrupt event maybe from trackpad device input reporting.
601 */
602 if (!cyapa->input) {
603 /*
604 * Still in probling or in firware image
605 * udpating or reading.
606 */
607 cyapa->ops->sort_empty_output_data(cyapa,
608 NULL, NULL, NULL);
609 goto out;
610 }
611
612 if (!cyapa->operational || cyapa->ops->irq_handler(cyapa)) {
613 if (!mutex_trylock(&cyapa->state_sync_lock)) {
614 cyapa->ops->sort_empty_output_data(cyapa,
615 NULL, NULL, NULL);
616 goto out;
617 }
618 cyapa_reinitialize(cyapa);
619 mutex_unlock(&cyapa->state_sync_lock);
620 }
621 }
622
623out:
67286508
DD
624 pm_runtime_mark_last_busy(dev);
625 pm_runtime_put_sync_autosuspend(dev);
9f1cd857
DD
626 return IRQ_HANDLED;
627}
628
22e7db81
DD
629/*
630 **************************************************************
631 * sysfs interface
632 **************************************************************
633*/
634#ifdef CONFIG_PM_SLEEP
635static ssize_t cyapa_show_suspend_scanrate(struct device *dev,
636 struct device_attribute *attr,
637 char *buf)
638{
639 struct cyapa *cyapa = dev_get_drvdata(dev);
640 u8 pwr_cmd = cyapa->suspend_power_mode;
641 u16 sleep_time;
642 int len;
643 int error;
644
645 error = mutex_lock_interruptible(&cyapa->state_sync_lock);
646 if (error)
647 return error;
648
649 pwr_cmd = cyapa->suspend_power_mode;
650 sleep_time = cyapa->suspend_sleep_time;
651
652 mutex_unlock(&cyapa->state_sync_lock);
653
654 switch (pwr_cmd) {
655 case PWR_MODE_BTN_ONLY:
656 len = scnprintf(buf, PAGE_SIZE, "%s\n", BTN_ONLY_MODE_NAME);
657 break;
658
659 case PWR_MODE_OFF:
660 len = scnprintf(buf, PAGE_SIZE, "%s\n", OFF_MODE_NAME);
661 break;
662
663 default:
664 len = scnprintf(buf, PAGE_SIZE, "%u\n",
665 cyapa->gen == CYAPA_GEN3 ?
666 cyapa_pwr_cmd_to_sleep_time(pwr_cmd) :
667 sleep_time);
668 break;
669 }
670
671 return len;
672}
673
674static ssize_t cyapa_update_suspend_scanrate(struct device *dev,
675 struct device_attribute *attr,
676 const char *buf, size_t count)
677{
678 struct cyapa *cyapa = dev_get_drvdata(dev);
679 u16 sleep_time;
680 int error;
681
682 error = mutex_lock_interruptible(&cyapa->state_sync_lock);
683 if (error)
684 return error;
685
686 if (sysfs_streq(buf, BTN_ONLY_MODE_NAME)) {
687 cyapa->suspend_power_mode = PWR_MODE_BTN_ONLY;
688 } else if (sysfs_streq(buf, OFF_MODE_NAME)) {
689 cyapa->suspend_power_mode = PWR_MODE_OFF;
690 } else if (!kstrtou16(buf, 10, &sleep_time)) {
691 cyapa->suspend_sleep_time = max_t(u16, sleep_time, 1000);
692 cyapa->suspend_power_mode =
693 cyapa_sleep_time_to_pwr_cmd(cyapa->suspend_sleep_time);
694 } else {
695 count = -EINVAL;
696 }
697
698 mutex_unlock(&cyapa->state_sync_lock);
699
700 return count;
701}
702
703static DEVICE_ATTR(suspend_scanrate_ms, S_IRUGO|S_IWUSR,
704 cyapa_show_suspend_scanrate,
705 cyapa_update_suspend_scanrate);
706
707static struct attribute *cyapa_power_wakeup_entries[] = {
708 &dev_attr_suspend_scanrate_ms.attr,
709 NULL,
710};
711
712static const struct attribute_group cyapa_power_wakeup_group = {
713 .name = power_group_name,
714 .attrs = cyapa_power_wakeup_entries,
715};
716
717static void cyapa_remove_power_wakeup_group(void *data)
718{
719 struct cyapa *cyapa = data;
720
721 sysfs_unmerge_group(&cyapa->client->dev.kobj,
722 &cyapa_power_wakeup_group);
723}
724
725static int cyapa_prepare_wakeup_controls(struct cyapa *cyapa)
726{
727 struct i2c_client *client = cyapa->client;
728 struct device *dev = &client->dev;
729 int error;
730
731 if (device_can_wakeup(dev)) {
732 error = sysfs_merge_group(&client->dev.kobj,
733 &cyapa_power_wakeup_group);
734 if (error) {
735 dev_err(dev, "failed to add power wakeup group: %d\n",
736 error);
737 return error;
738 }
739
740 error = devm_add_action(dev,
741 cyapa_remove_power_wakeup_group, cyapa);
742 if (error) {
743 cyapa_remove_power_wakeup_group(cyapa);
744 dev_err(dev, "failed to add power cleanup action: %d\n",
745 error);
746 return error;
747 }
748 }
749
750 return 0;
751}
752#else
753static inline int cyapa_prepare_wakeup_controls(struct cyapa *cyapa)
754{
755 return 0;
756}
757#endif /* CONFIG_PM_SLEEP */
758
67286508
DD
759#ifdef CONFIG_PM
760static ssize_t cyapa_show_rt_suspend_scanrate(struct device *dev,
761 struct device_attribute *attr,
762 char *buf)
763{
764 struct cyapa *cyapa = dev_get_drvdata(dev);
765 u8 pwr_cmd;
766 u16 sleep_time;
767 int error;
768
769 error = mutex_lock_interruptible(&cyapa->state_sync_lock);
770 if (error)
771 return error;
772
773 pwr_cmd = cyapa->runtime_suspend_power_mode;
774 sleep_time = cyapa->runtime_suspend_sleep_time;
775
776 mutex_unlock(&cyapa->state_sync_lock);
777
778 return scnprintf(buf, PAGE_SIZE, "%u\n",
779 cyapa->gen == CYAPA_GEN3 ?
780 cyapa_pwr_cmd_to_sleep_time(pwr_cmd) :
781 sleep_time);
782}
783
784static ssize_t cyapa_update_rt_suspend_scanrate(struct device *dev,
785 struct device_attribute *attr,
786 const char *buf, size_t count)
787{
788 struct cyapa *cyapa = dev_get_drvdata(dev);
789 u16 time;
790 int error;
791
792 if (buf == NULL || count == 0 || kstrtou16(buf, 10, &time)) {
793 dev_err(dev, "invalid runtime suspend scanrate ms parameter\n");
794 return -EINVAL;
795 }
796
797 /*
798 * When the suspend scanrate is changed, pm_runtime_get to resume
799 * a potentially suspended device, update to the new pwr_cmd
800 * and then pm_runtime_put to suspend into the new power mode.
801 */
802 pm_runtime_get_sync(dev);
803
804 error = mutex_lock_interruptible(&cyapa->state_sync_lock);
805 if (error)
806 return error;
807
808 cyapa->runtime_suspend_sleep_time = max_t(u16, time, 1000);
809 cyapa->runtime_suspend_power_mode =
810 cyapa_sleep_time_to_pwr_cmd(cyapa->runtime_suspend_sleep_time);
811
812 mutex_unlock(&cyapa->state_sync_lock);
813
814 pm_runtime_put_sync_autosuspend(dev);
815
816 return count;
817}
818
819static DEVICE_ATTR(runtime_suspend_scanrate_ms, S_IRUGO|S_IWUSR,
820 cyapa_show_rt_suspend_scanrate,
821 cyapa_update_rt_suspend_scanrate);
822
823static struct attribute *cyapa_power_runtime_entries[] = {
824 &dev_attr_runtime_suspend_scanrate_ms.attr,
825 NULL,
826};
827
828static const struct attribute_group cyapa_power_runtime_group = {
829 .name = power_group_name,
830 .attrs = cyapa_power_runtime_entries,
831};
832
833static void cyapa_remove_power_runtime_group(void *data)
834{
835 struct cyapa *cyapa = data;
836
837 sysfs_unmerge_group(&cyapa->client->dev.kobj,
838 &cyapa_power_runtime_group);
839}
840
841static int cyapa_start_runtime(struct cyapa *cyapa)
842{
843 struct device *dev = &cyapa->client->dev;
844 int error;
845
846 cyapa->runtime_suspend_power_mode = PWR_MODE_IDLE;
847 cyapa->runtime_suspend_sleep_time =
848 cyapa_pwr_cmd_to_sleep_time(cyapa->runtime_suspend_power_mode);
849
850 error = sysfs_merge_group(&dev->kobj, &cyapa_power_runtime_group);
851 if (error) {
852 dev_err(dev,
853 "failed to create power runtime group: %d\n", error);
854 return error;
855 }
856
857 error = devm_add_action(dev, cyapa_remove_power_runtime_group, cyapa);
858 if (error) {
859 cyapa_remove_power_runtime_group(cyapa);
860 dev_err(dev,
861 "failed to add power runtime cleanup action: %d\n",
862 error);
863 return error;
864 }
865
866 /* runtime is enabled until device is operational and opened. */
867 pm_runtime_set_suspended(dev);
868 pm_runtime_use_autosuspend(dev);
869 pm_runtime_set_autosuspend_delay(dev, AUTOSUSPEND_DELAY);
870
871 return 0;
872}
873#else
874static inline int cyapa_start_runtime(struct cyapa *cyapa)
875{
876 return 0;
877}
878#endif /* CONFIG_PM */
879
d7e34d12
BL
880static int cyapa_probe(struct i2c_client *client,
881 const struct i2c_device_id *dev_id)
882{
d7e34d12 883 struct device *dev = &client->dev;
b1cfa7b4
DD
884 struct cyapa *cyapa;
885 u8 adapter_func;
9f1cd857 886 union i2c_smbus_data dummy;
b1cfa7b4 887 int error;
d7e34d12 888
6ddaf744
BL
889 adapter_func = cyapa_check_adapter_functionality(client);
890 if (adapter_func == CYAPA_ADAPTER_FUNC_NONE) {
891 dev_err(dev, "not a supported I2C/SMBus adapter\n");
892 return -EIO;
893 }
894
9f1cd857
DD
895 /* Make sure there is something at this address */
896 if (i2c_smbus_xfer(client->adapter, client->addr, 0,
897 I2C_SMBUS_READ, 0, I2C_SMBUS_BYTE, &dummy) < 0)
898 return -ENODEV;
899
b1cfa7b4
DD
900 cyapa = devm_kzalloc(dev, sizeof(struct cyapa), GFP_KERNEL);
901 if (!cyapa)
d7e34d12 902 return -ENOMEM;
d7e34d12 903
6ddaf744
BL
904 /* i2c isn't supported, use smbus */
905 if (adapter_func == CYAPA_ADAPTER_FUNC_SMBUS)
906 cyapa->smbus = true;
b1cfa7b4 907
9f1cd857
DD
908 cyapa->client = client;
909 i2c_set_clientdata(client, cyapa);
910 sprintf(cyapa->phys, "i2c-%d-%04x/input0", client->adapter->nr,
911 client->addr);
d7e34d12 912
9f1cd857 913 error = cyapa_initialize(cyapa);
b1cfa7b4 914 if (error) {
9f1cd857 915 dev_err(dev, "failed to detect and initialize tp device.\n");
b1cfa7b4 916 return error;
d7e34d12
BL
917 }
918
22e7db81
DD
919 error = cyapa_prepare_wakeup_controls(cyapa);
920 if (error) {
921 dev_err(dev, "failed to prepare wakeup controls: %d\n", error);
922 return error;
923 }
924
67286508
DD
925 error = cyapa_start_runtime(cyapa);
926 if (error) {
927 dev_err(dev, "failed to start pm_runtime: %d\n", error);
928 return error;
929 }
930
b1cfa7b4
DD
931 error = devm_request_threaded_irq(dev, client->irq,
932 NULL, cyapa_irq,
933 IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
934 "cyapa", cyapa);
935 if (error) {
823a11fd 936 dev_err(dev, "failed to request threaded irq: %d\n", error);
b1cfa7b4 937 return error;
d7e34d12
BL
938 }
939
b1cfa7b4
DD
940 /* Disable IRQ until the device is opened */
941 disable_irq(client->irq);
d7e34d12 942
9f1cd857
DD
943 /*
944 * Register the device in the input subsystem when it's operational.
945 * Otherwise, keep in this driver, so it can be be recovered or updated
946 * through the sysfs mode and update_fw interfaces by user or apps.
947 */
948 if (cyapa->operational) {
949 error = cyapa_create_input_dev(cyapa);
950 if (error) {
951 dev_err(dev, "create input_dev instance failed: %d\n",
952 error);
953 return error;
954 }
b1cfa7b4 955 }
d7e34d12
BL
956
957 return 0;
958}
959
572081a4 960static int __maybe_unused cyapa_suspend(struct device *dev)
d7e34d12 961{
b1cfa7b4
DD
962 struct i2c_client *client = to_i2c_client(dev);
963 struct cyapa *cyapa = i2c_get_clientdata(client);
d7e34d12 964 u8 power_mode;
b1cfa7b4
DD
965 int error;
966
9f1cd857 967 error = mutex_lock_interruptible(&cyapa->state_sync_lock);
b1cfa7b4
DD
968 if (error)
969 return error;
d7e34d12 970
67286508
DD
971 /*
972 * Runtime PM is enable only when device is in operational mode and
973 * users in use, so need check it before disable it to
974 * avoid unbalance warning.
975 */
976 if (pm_runtime_enabled(dev))
977 pm_runtime_disable(dev);
b1cfa7b4 978 disable_irq(client->irq);
d7e34d12
BL
979
980 /*
981 * Set trackpad device to idle mode if wakeup is allowed,
982 * otherwise turn off.
983 */
9f1cd857
DD
984 if (cyapa->operational) {
985 power_mode = device_may_wakeup(dev) ? cyapa->suspend_power_mode
986 : PWR_MODE_OFF;
987 error = cyapa->ops->set_power_mode(cyapa, power_mode,
988 cyapa->suspend_sleep_time);
989 if (error)
990 dev_err(dev, "suspend set power mode failed: %d\n",
991 error);
992 }
d7e34d12
BL
993
994 if (device_may_wakeup(dev))
f68a95cd 995 cyapa->irq_wake = (enable_irq_wake(client->irq) == 0);
b1cfa7b4 996
9f1cd857 997 mutex_unlock(&cyapa->state_sync_lock);
d7e34d12
BL
998 return 0;
999}
1000
572081a4 1001static int __maybe_unused cyapa_resume(struct device *dev)
d7e34d12 1002{
b1cfa7b4
DD
1003 struct i2c_client *client = to_i2c_client(dev);
1004 struct cyapa *cyapa = i2c_get_clientdata(client);
b1cfa7b4
DD
1005 int error;
1006
9f1cd857 1007 mutex_lock(&cyapa->state_sync_lock);
d7e34d12 1008
9f1cd857 1009 if (device_may_wakeup(dev) && cyapa->irq_wake) {
f68a95cd 1010 disable_irq_wake(client->irq);
9f1cd857
DD
1011 cyapa->irq_wake = false;
1012 }
d7e34d12 1013
67286508 1014 /* Update device states and runtime PM states. */
9f1cd857 1015 error = cyapa_reinitialize(cyapa);
b1cfa7b4 1016 if (error)
9f1cd857 1017 dev_warn(dev, "failed to reinitialize TP device: %d\n", error);
d7e34d12 1018
f68a95cd 1019 enable_irq(client->irq);
b1cfa7b4 1020
9f1cd857 1021 mutex_unlock(&cyapa->state_sync_lock);
d7e34d12
BL
1022 return 0;
1023}
d7e34d12 1024
67286508
DD
1025static int __maybe_unused cyapa_runtime_suspend(struct device *dev)
1026{
1027 struct cyapa *cyapa = dev_get_drvdata(dev);
1028 int error;
1029
1030 error = cyapa->ops->set_power_mode(cyapa,
1031 cyapa->runtime_suspend_power_mode,
1032 cyapa->runtime_suspend_sleep_time);
1033 if (error)
1034 dev_warn(dev, "runtime suspend failed: %d\n", error);
1035
1036 return 0;
1037}
1038
1039static int __maybe_unused cyapa_runtime_resume(struct device *dev)
1040{
1041 struct cyapa *cyapa = dev_get_drvdata(dev);
1042 int error;
1043
1044 error = cyapa->ops->set_power_mode(cyapa, PWR_MODE_FULL_ACTIVE, 0);
1045 if (error)
1046 dev_warn(dev, "runtime resume failed: %d\n", error);
1047
1048 return 0;
1049}
1050
1051static const struct dev_pm_ops cyapa_pm_ops = {
1052 SET_SYSTEM_SLEEP_PM_OPS(cyapa_suspend, cyapa_resume)
1053 SET_RUNTIME_PM_OPS(cyapa_runtime_suspend, cyapa_runtime_resume, NULL)
1054};
d7e34d12
BL
1055
1056static const struct i2c_device_id cyapa_id_table[] = {
1057 { "cyapa", 0 },
1058 { },
1059};
1060MODULE_DEVICE_TABLE(i2c, cyapa_id_table);
1061
1062static struct i2c_driver cyapa_driver = {
1063 .driver = {
1064 .name = "cyapa",
1065 .owner = THIS_MODULE,
1066 .pm = &cyapa_pm_ops,
1067 },
1068
1069 .probe = cyapa_probe,
d7e34d12
BL
1070 .id_table = cyapa_id_table,
1071};
1072
1073module_i2c_driver(cyapa_driver);
1074
1075MODULE_DESCRIPTION("Cypress APA I2C Trackpad Driver");
1076MODULE_AUTHOR("Dudley Du <dudl@cypress.com>");
1077MODULE_LICENSE("GPL");
This page took 0.094716 seconds and 5 git commands to generate.