4 Written by GraÅžvydas Ignotas <notasas@gmail.com>
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; version 2 of the License.
11 #include <linux/kernel.h>
12 #include <linux/init.h>
13 #include <linux/module.h>
14 #include <linux/i2c.h>
15 #include <linux/input.h>
16 #include <linux/interrupt.h>
17 #include <linux/timer.h>
18 #include <linux/uaccess.h>
19 #include <linux/ctype.h>
20 #include <linux/proc_fs.h>
21 #include <linux/idr.h>
22 #include <linux/i2c/vsense.h>
23 #include <linux/gpio.h>
24 #include <linux/regulator/consumer.h>
26 #define VSENSE_INTERVAL 25
28 #define VSENSE_MODE_ABS 0
29 #define VSENSE_MODE_MOUSE 1
30 #define VSENSE_MODE_SCROLL 2
31 #define VSENSE_MODE_MBUTTONS 3
33 static DEFINE_IDR(vsense_proc_id);
34 static DEFINE_MUTEX(vsense_mutex);
36 /* Reset state is shared between both nubs, so we keep
39 static int vsense_reset_state;
40 static int vsense_reset_refcount;
42 struct vsense_drvdata {
44 struct input_dev *input;
45 struct i2c_client *client;
46 struct regulator *reg;
47 struct delayed_work work;
52 struct proc_dir_entry *proc_root;
53 int mouse_multiplier; /* 24.8 */
54 int scrollx_multiplier;
55 int scrolly_multiplier;
68 int pos_stable_counter;
80 static void release_mbuttons(struct vsense_drvdata *ddata)
82 if (ddata->mbutton.state_l) {
83 input_report_key(ddata->input, BTN_LEFT, 0);
84 ddata->mbutton.state_l = 0;
86 if (ddata->mbutton.state_m) {
87 input_report_key(ddata->input, BTN_MIDDLE, 0);
88 ddata->mbutton.state_m = 0;
90 if (ddata->mbutton.state_r) {
91 input_report_key(ddata->input, BTN_RIGHT, 0);
92 ddata->mbutton.state_r = 0;
94 ddata->mbutton.pos_active = NUB_POS_CENTER;
97 static void vsense_work(struct work_struct *work)
99 struct vsense_drvdata *ddata;
100 int ax = 0, ay = 0, rx = 0, ry = 0;
101 int update_pending = 0;
103 int ret, pos, l, m, r;
105 ddata = container_of(work, struct vsense_drvdata, work.work);
107 if (unlikely(gpio_get_value(ddata->irq_gpio)))
110 ret = i2c_master_recv(ddata->client, buff, sizeof(buff));
111 if (unlikely(ret != sizeof(buff))) {
112 dev_err(&ddata->client->dev, "read failed with %i\n", ret);
116 rx = (signed int)buff[0];
117 ry = (signed int)buff[1];
118 ax = (signed int)buff[2];
119 ay = (signed int)buff[3];
121 schedule_delayed_work(&ddata->work, msecs_to_jiffies(VSENSE_INTERVAL));
125 switch (ddata->mode) {
126 case VSENSE_MODE_MOUSE:
127 rx = rx * ddata->mouse_multiplier / 256;
128 ry = -ry * ddata->mouse_multiplier / 256;
129 input_report_rel(ddata->input, REL_X, rx);
130 input_report_rel(ddata->input, REL_Y, ry);
132 case VSENSE_MODE_SCROLL:
133 if (++(ddata->scroll_counter) < ddata->scroll_steps)
135 ddata->scroll_counter = 0;
136 ax = ax * ddata->scrollx_multiplier / 256;
137 ay = ay * ddata->scrolly_multiplier / 256;
138 input_report_rel(ddata->input, REL_HWHEEL, ax);
139 input_report_rel(ddata->input, REL_WHEEL, ay);
141 case VSENSE_MODE_MBUTTONS:
142 if (!update_pending) {
143 release_mbuttons(ddata);
147 pos = NUB_POS_CENTER;
148 if (ax >= ddata->mbutton.threshold_x) pos = NUB_POS_RIGHT;
149 else if (ax <= -ddata->mbutton.threshold_x) pos = NUB_POS_LEFT;
150 else if (ay >= ddata->mbutton.threshold_y) pos = NUB_POS_UP;
151 else if (ay <= -ddata->mbutton.threshold_y) pos = NUB_POS_DOWN;
153 if (pos != ddata->mbutton.pos_prev) {
154 ddata->mbutton.pos_prev = pos;
155 ddata->mbutton.pos_stable_counter = 0;
158 ddata->mbutton.pos_stable_counter++;
160 if (ddata->mbutton.pos_stable_counter < ddata->mbutton.delay)
161 pos = ddata->mbutton.pos_active;
163 if (pos != NUB_POS_UP)
164 ddata->mbutton.dblclick_stage = 0;
169 ddata->mbutton.dblclick_stage++;
170 switch (ddata->mbutton.dblclick_stage) {
171 case 1: case 2: case 5: case 6:
186 input_report_key(ddata->input, BTN_LEFT, l);
187 input_report_key(ddata->input, BTN_RIGHT, r);
188 input_report_key(ddata->input, BTN_MIDDLE, m);
189 ddata->mbutton.pos_active = pos;
190 ddata->mbutton.state_l = l;
191 ddata->mbutton.state_m = m;
192 ddata->mbutton.state_r = r;
195 input_report_abs(ddata->input, ABS_X, ax * 8);
196 input_report_abs(ddata->input, ABS_Y, -ay * 8);
199 input_sync(ddata->input);
202 static irqreturn_t vsense_isr(int irq, void *dev_id)
204 struct vsense_drvdata *ddata = dev_id;
206 schedule_delayed_work(&ddata->work, 0);
211 static int vsense_reset(struct vsense_drvdata *ddata, int val)
215 dev_dbg(&ddata->client->dev, "vsense_reset: %i\n", val);
217 if (ddata->mode != VSENSE_MODE_ABS)
218 release_mbuttons(ddata);
220 ret = gpio_direction_output(ddata->reset_gpio, val);
222 dev_err(&ddata->client->dev, "failed to configure direction "
223 "for GPIO %d, error %d\n", ddata->reset_gpio, ret);
226 vsense_reset_state = val;
232 static int vsense_open(struct input_dev *dev)
234 dev_dbg(&dev->dev, "vsense_open\n");
236 /* get out of reset and stay there until user wants to reset it */
237 if (vsense_reset_state != 0)
238 vsense_reset(input_get_drvdata(dev), 0);
243 static int vsense_input_register(struct vsense_drvdata *ddata, int mode)
245 struct input_dev *input;
248 input = input_allocate_device();
252 if (mode != VSENSE_MODE_ABS) {
253 /* pretend to be a mouse */
254 input_set_capability(input, EV_REL, REL_X);
255 input_set_capability(input, EV_REL, REL_Y);
256 input_set_capability(input, EV_REL, REL_WHEEL);
257 input_set_capability(input, EV_REL, REL_HWHEEL);
258 /* add fake buttons to fool X that this is a mouse */
259 input_set_capability(input, EV_KEY, BTN_LEFT);
260 input_set_capability(input, EV_KEY, BTN_RIGHT);
261 input_set_capability(input, EV_KEY, BTN_MIDDLE);
263 input->evbit[BIT_WORD(EV_ABS)] = BIT_MASK(EV_ABS);
264 input_set_abs_params(input, ABS_X, -256, 256, 0, 0);
265 input_set_abs_params(input, ABS_Y, -256, 256, 0, 0);
268 input->name = ddata->dev_name;
269 input->dev.parent = &ddata->client->dev;
271 input->id.bustype = BUS_I2C;
272 input->id.version = 0x0092;
274 input->open = vsense_open;
276 ddata->input = input;
277 input_set_drvdata(input, ddata);
279 ret = input_register_device(input);
281 dev_err(&ddata->client->dev, "failed to register input device,"
283 input_free_device(input);
290 static void vsense_input_unregister(struct vsense_drvdata *ddata)
292 cancel_delayed_work_sync(&ddata->work);
293 input_unregister_device(ddata->input);
296 static int vsense_proc_mode_read(char *page, char **start, off_t off, int count,
297 int *eof, void *data)
299 struct vsense_drvdata *ddata = data;
303 switch (ddata->mode) {
304 case VSENSE_MODE_MOUSE:
305 len = sprintf(p, "mouse\n");
307 case VSENSE_MODE_SCROLL:
308 len = sprintf(p, "scroll\n");
310 case VSENSE_MODE_MBUTTONS:
311 len = sprintf(p, "mbuttons\n");
314 len = sprintf(p, "absolute\n");
322 static int vsense_proc_mode_write(struct file *file, const char __user *buffer,
323 unsigned long count, void *data)
325 struct vsense_drvdata *ddata = data;
326 int mode = ddata->mode;
330 count = strncpy_from_user(buff, buffer,
331 count < sizeof(buff) ? count : sizeof(buff) - 1);
334 p = buff + strlen(buff) - 1;
335 while (p > buff && isspace(*p))
339 if (strcasecmp(buff, "mouse") == 0)
340 mode = VSENSE_MODE_MOUSE;
341 else if (strcasecmp(buff, "scroll") == 0)
342 mode = VSENSE_MODE_SCROLL;
343 else if (strcasecmp(buff, "mbuttons") == 0)
344 mode = VSENSE_MODE_MBUTTONS;
345 else if (strcasecmp(buff, "absolute") == 0)
346 mode = VSENSE_MODE_ABS;
348 dev_err(&ddata->client->dev, "unknown mode: %s\n", buff);
352 if (ddata->mode != VSENSE_MODE_ABS)
353 release_mbuttons(ddata);
355 if ((mode == VSENSE_MODE_ABS && ddata->mode != VSENSE_MODE_ABS) ||
356 (mode != VSENSE_MODE_ABS && ddata->mode == VSENSE_MODE_ABS)) {
357 disable_irq(ddata->client->irq);
358 vsense_input_unregister(ddata);
359 ret = vsense_input_register(ddata, mode);
361 dev_err(&ddata->client->dev, "failed to re-register "
362 "input as %d, code %d\n", mode, ret);
364 enable_irq(ddata->client->irq);
371 static int vsense_proc_int_read(char *page, char **start, off_t off,
372 int count, int *eof, void *data)
377 len = sprintf(page, "%d\n", *val);
382 static int vsense_proc_int_write(struct file *file, const char __user *buffer,
383 unsigned long count, void *data)
390 count = strncpy_from_user(buff, buffer,
391 count < sizeof(buff) ? count : sizeof(buff) - 1);
394 ret = strict_strtol(buff, 0, &val);
401 static int vsense_proc_mult_read(char *page, char **start, off_t off,
402 int count, int *eof, void *data)
404 int *multiplier = data;
405 int val = *multiplier * 100 / 256;
406 return vsense_proc_int_read(page, start, off, count, eof, &val);
409 static int vsense_proc_mult_write(struct file *file, const char __user *buffer,
410 unsigned long count, void *data)
412 int *multiplier = data;
415 ret = vsense_proc_int_write(file, buffer, count, &val);
421 /* round to higher absolute value */
422 adj = val < 0 ? -99 : 99;
423 *multiplier = (val * 256 + adj) / 100;
428 static int vsense_proc_rate_read(char *page, char **start, off_t off,
429 int count, int *eof, void *data)
432 int val = 1000 / VSENSE_INTERVAL / *steps;
433 return vsense_proc_int_read(page, start, off, count, eof, &val);
436 static int vsense_proc_rate_write(struct file *file, const char __user *buffer,
437 unsigned long count, void *data)
442 ret = vsense_proc_int_write(file, buffer, count, &val);
448 *steps = 1000 / VSENSE_INTERVAL / val;
454 static int vsense_proc_treshold_write(struct file *file, const char __user *buffer,
455 unsigned long count, void *data)
460 ret = vsense_proc_int_write(file, buffer, count, &val);
463 if (val < 1 || val > 32)
471 vsense_show_reset(struct device *dev, struct device_attribute *attr, char *buf)
473 return sprintf(buf, "%d\n", vsense_reset_state);
477 vsense_set_reset(struct device *dev, struct device_attribute *attr,
478 const char *buf, size_t count)
480 unsigned long new_reset;
481 struct i2c_client *client;
482 struct vsense_drvdata *ddata;
485 ret = strict_strtoul(buf, 10, &new_reset);
489 client = to_i2c_client(dev);
490 ddata = i2c_get_clientdata(client);
492 vsense_reset(ddata, new_reset ? 1 : 0);
496 static DEVICE_ATTR(reset, S_IRUGO | S_IWUSR,
497 vsense_show_reset, vsense_set_reset);
499 static void vsense_create_proc(struct vsense_drvdata *ddata,
500 void *pdata, const char *name,
501 read_proc_t *read_proc, write_proc_t *write_proc)
503 struct proc_dir_entry *pret;
505 pret = create_proc_entry(name, S_IWUGO | S_IRUGO, ddata->proc_root);
507 dev_err(&ddata->client->dev, "failed to create proc file %s\n", name);
512 pret->read_proc = read_proc;
513 pret->write_proc = write_proc;
516 static int vsense_probe(struct i2c_client *client,
517 const struct i2c_device_id *id)
519 struct vsense_platform_data *pdata = client->dev.platform_data;
520 struct vsense_drvdata *ddata;
525 dev_err(&client->dev, "no platform data?\n");
529 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) {
530 dev_err(&client->dev, "can't talk I2C?\n");
534 ddata = kzalloc(sizeof(struct vsense_drvdata), GFP_KERNEL);
538 ret = idr_pre_get(&vsense_proc_id, GFP_KERNEL);
544 mutex_lock(&vsense_mutex);
546 ret = idr_get_new(&vsense_proc_id, client, &ddata->proc_id);
548 mutex_unlock(&vsense_mutex);
552 if (!vsense_reset_refcount) {
553 ret = gpio_request_one(pdata->gpio_reset, GPIOF_OUT_INIT_HIGH,
556 dev_err(&client->dev, "gpio_request error: %d, %d\n",
557 pdata->gpio_reset, ret);
558 mutex_unlock(&vsense_mutex);
562 vsense_reset_refcount++;
564 mutex_unlock(&vsense_mutex);
566 ret = gpio_request_one(pdata->gpio_irq, GPIOF_IN, client->name);
568 dev_err(&client->dev, "failed to request GPIO %d,"
569 " error %d\n", pdata->gpio_irq, ret);
573 ret = gpio_to_irq(pdata->gpio_irq);
575 dev_err(&client->dev, "unable to get irq number for GPIO %d, "
576 "error %d\n", pdata->gpio_irq, ret);
577 goto err_gpio_to_irq;
581 snprintf(ddata->dev_name, sizeof(ddata->dev_name),
582 "nub%d", ddata->proc_id);
584 INIT_DELAYED_WORK(&ddata->work, vsense_work);
585 ddata->mode = VSENSE_MODE_ABS;
586 ddata->client = client;
587 ddata->reset_gpio = pdata->gpio_reset;
588 ddata->irq_gpio = pdata->gpio_irq;
589 ddata->mouse_multiplier = 170 * 256 / 100;
590 ddata->scrollx_multiplier =
591 ddata->scrolly_multiplier = 8 * 256 / 100;
592 ddata->scroll_steps = 1000 / VSENSE_INTERVAL / 3;
593 ddata->mbutton.threshold_x = 20;
594 ddata->mbutton.threshold_y = 26;
595 ddata->mbutton.delay = 1;
596 i2c_set_clientdata(client, ddata);
598 ddata->reg = regulator_get(&client->dev, "vcc");
599 if (IS_ERR(ddata->reg)) {
600 ret = PTR_ERR(ddata->reg);
601 dev_err(&client->dev, "unable to get regulator: %d\n", ret);
602 goto err_regulator_get;
605 ret = regulator_enable(ddata->reg);
607 dev_err(&client->dev, "unable to enable regulator: %d\n", ret);
608 goto err_regulator_enable;
612 if (vsense_reset_refcount == 2)
613 /* resetting drains power, as well as disabling supply,
614 * so keep it powered and out of reset at all times */
615 vsense_reset(ddata, 0);
617 ret = vsense_input_register(ddata, ddata->mode);
619 dev_err(&client->dev, "failed to register input device, "
621 goto err_input_register;
624 ret = request_irq(client->irq, vsense_isr,
625 IRQF_SAMPLE_RANDOM | IRQF_TRIGGER_FALLING,
626 client->name, ddata);
628 dev_err(&client->dev, "unable to claim irq %d, error %d\n",
630 goto err_request_irq;
633 dev_dbg(&client->dev, "probe %02x, gpio %i, irq %i, \"%s\"\n",
634 client->addr, pdata->gpio_irq, client->irq, client->name);
636 snprintf(buff, sizeof(buff), "pandora/nub%d", ddata->proc_id);
637 ddata->proc_root = proc_mkdir(buff, NULL);
638 if (ddata->proc_root != NULL) {
639 vsense_create_proc(ddata, ddata, "mode",
640 vsense_proc_mode_read, vsense_proc_mode_write);
641 vsense_create_proc(ddata, &ddata->mouse_multiplier, "mouse_sensitivity",
642 vsense_proc_mult_read, vsense_proc_mult_write);
643 vsense_create_proc(ddata, &ddata->scrollx_multiplier, "scrollx_sensitivity",
644 vsense_proc_mult_read, vsense_proc_mult_write);
645 vsense_create_proc(ddata, &ddata->scrolly_multiplier, "scrolly_sensitivity",
646 vsense_proc_mult_read, vsense_proc_mult_write);
647 vsense_create_proc(ddata, &ddata->scroll_steps, "scroll_rate",
648 vsense_proc_rate_read, vsense_proc_rate_write);
649 vsense_create_proc(ddata, &ddata->mbutton.threshold_x, "mbutton_threshold",
650 vsense_proc_int_read, vsense_proc_treshold_write);
651 vsense_create_proc(ddata, &ddata->mbutton.threshold_y, "mbutton_threshold_y",
652 vsense_proc_int_read, vsense_proc_treshold_write);
653 vsense_create_proc(ddata, &ddata->mbutton.delay, "mbutton_delay",
654 vsense_proc_int_read, vsense_proc_int_write);
656 dev_err(&client->dev, "can't create proc dir");
658 ret = device_create_file(&client->dev, &dev_attr_reset);
663 vsense_input_unregister(ddata);
665 err_regulator_enable:
666 regulator_put(ddata->reg);
669 gpio_free(pdata->gpio_irq);
671 gpio_free(pdata->gpio_reset);
673 idr_remove(&vsense_proc_id, ddata->proc_id);
679 static int __devexit vsense_remove(struct i2c_client *client)
681 struct vsense_drvdata *ddata;
684 dev_dbg(&client->dev, "remove\n");
686 ddata = i2c_get_clientdata(client);
688 mutex_lock(&vsense_mutex);
690 vsense_reset_refcount--;
691 if (!vsense_reset_refcount)
692 gpio_free(ddata->reset_gpio);
694 mutex_unlock(&vsense_mutex);
696 device_remove_file(&client->dev, &dev_attr_reset);
698 remove_proc_entry("mode", ddata->proc_root);
699 remove_proc_entry("mouse_sensitivity", ddata->proc_root);
700 remove_proc_entry("scrollx_sensitivity", ddata->proc_root);
701 remove_proc_entry("scrolly_sensitivity", ddata->proc_root);
702 remove_proc_entry("scroll_rate", ddata->proc_root);
703 remove_proc_entry("mbutton_threshold", ddata->proc_root);
704 remove_proc_entry("mbutton_threshold_y", ddata->proc_root);
705 remove_proc_entry("mbutton_delay", ddata->proc_root);
706 snprintf(buff, sizeof(buff), "pandora/nub%d", ddata->proc_id);
707 remove_proc_entry(buff, NULL);
708 idr_remove(&vsense_proc_id, ddata->proc_id);
710 free_irq(client->irq, ddata);
711 vsense_input_unregister(ddata);
712 gpio_free(ddata->irq_gpio);
713 regulator_put(ddata->reg);
719 #ifdef CONFIG_PM_SLEEP
720 static int vsense_i2c_suspend(struct device *dev)
722 struct i2c_client *client = to_i2c_client(dev);
723 struct vsense_drvdata *ddata = i2c_get_clientdata(client);
725 /* we can't process irqs while i2c is suspended and we can't
726 * ask the device to not generate them, so just disable instead */
727 cancel_delayed_work_sync(&ddata->work);
728 disable_irq(client->irq);
733 static int vsense_i2c_resume(struct device *dev)
735 struct i2c_client *client = to_i2c_client(dev);
737 enable_irq(client->irq);
741 #endif /* CONFIG_PM_SLEEP */
743 static SIMPLE_DEV_PM_OPS(vsense_pm_ops, vsense_i2c_suspend, vsense_i2c_resume);
745 static const struct i2c_device_id vsense_id[] = {
750 static struct i2c_driver vsense_driver = {
753 .owner = THIS_MODULE,
754 .pm = &vsense_pm_ops,
756 .probe = vsense_probe,
757 .remove = __devexit_p(vsense_remove),
758 .id_table = vsense_id,
761 static int __init vsense_init(void)
763 return i2c_add_driver(&vsense_driver);
766 static void __exit vsense_exit(void)
768 i2c_del_driver(&vsense_driver);
772 MODULE_AUTHOR("Grazvydas Ignotas");
773 MODULE_DESCRIPTION("VSense navigation device driver");
774 MODULE_LICENSE("GPL");
776 module_init(vsense_init);
777 module_exit(vsense_exit);