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/i2c/vsense.h>
21 /* hack for Pandora: keep track of usage to prevent reset
22 * while other nub is in use
24 static int reference_count;
26 struct vsense_drvdata {
27 struct input_dev *input;
28 struct i2c_client *client;
29 struct delayed_work work;
34 static void vsense_work(struct work_struct *work)
36 struct vsense_drvdata *ddata;
38 int ret, x = 0, y = 0;
40 ddata = container_of(work, struct vsense_drvdata, work.work);
42 // dev_dbg(&ddata->client->dev, "!!! work, gpio val %i\n",
43 // gpio_get_value(ddata->irq_gpio));
45 if (unlikely(gpio_get_value(ddata->irq_gpio)))
50 ret = i2c_master_recv(ddata->client, buff, 8);
51 if (unlikely(ret != 8)) {
52 dev_err(&ddata->client->dev, "read failed with %i\n", ret);
56 x = (signed int)buff[2] * 8;
57 y = (signed int)buff[3] * 8;
59 schedule_delayed_work(&ddata->work, msecs_to_jiffies(25));
62 input_report_abs(ddata->input, ABS_X, x);
63 input_report_abs(ddata->input, ABS_Y, y);
64 input_sync(ddata->input);
67 static irqreturn_t vsense_isr(int irq, void *dev_id)
69 struct vsense_drvdata *ddata = dev_id;
71 // dev_dbg(dev, "!!! irq %i\n", irq);
73 schedule_delayed_work(&ddata->work, 0);
78 static int vsense_reset(struct input_dev *dev, int val)
80 struct vsense_drvdata *ddata;
83 ddata = input_get_drvdata(dev);
85 dev_dbg(&dev->dev, "vsense_reset: %i\n", val);
87 ret = gpio_request(ddata->reset_gpio, "vsense reset");
89 dev_err(&dev->dev, "failed to request GPIO %d,"
90 " error %d\n", ddata->reset_gpio, ret);
94 ret = gpio_direction_output(ddata->reset_gpio, val);
96 dev_err(&dev->dev, "failed to configure input direction "
97 "for GPIO %d, error %d\n", ddata->reset_gpio, ret);
100 gpio_free(ddata->reset_gpio);
104 static int vsense_open(struct input_dev *dev)
106 dev_dbg(&dev->dev, "vsense_open\n");
108 if (reference_count++ == 0)
109 vsense_reset(dev, 0);
114 static void vsense_close(struct input_dev *dev)
116 dev_dbg(&dev->dev, "vsense_close\n");
118 if (--reference_count == 0)
119 vsense_reset(dev, 1);
120 BUG_ON(reference_count < 0);
123 static int vsense_probe(struct i2c_client *client,
124 const struct i2c_device_id *id)
126 struct vsense_platform_data *pdata = client->dev.platform_data;
127 struct vsense_drvdata *ddata;
128 struct input_dev *input;
132 dev_err(&client->dev, "no platform data?\n");
136 if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) {
137 dev_err(&client->dev, "can't talk I2C?\n");
141 input = input_allocate_device();
145 ddata = kzalloc(sizeof(struct vsense_drvdata), GFP_KERNEL);
152 input->evbit[0] = BIT_MASK(EV_ABS);
153 input_set_abs_params(input, ABS_X, -256, 256, 0, 0);
154 input_set_abs_params(input, ABS_Y, -256, 256, 0, 0);
156 input->name = client->name;
157 input->dev.parent = &client->dev;
159 input->id.bustype = BUS_I2C;
160 input->id.product = client->addr;
161 input->id.version = 0x0090;
163 input->open = vsense_open;
164 input->close = vsense_close;
166 ret = gpio_request(pdata->gpio_irq, client->name);
168 dev_err(&client->dev, "failed to request GPIO %d,"
169 " error %d\n", pdata->gpio_irq, ret);
173 ret = gpio_direction_input(pdata->gpio_irq);
175 dev_err(&client->dev, "failed to configure input direction "
176 "for GPIO %d, error %d\n", pdata->gpio_irq, ret);
180 ret = gpio_to_irq(pdata->gpio_irq);
182 dev_err(&client->dev, "unable to get irq number for GPIO %d, "
183 "error %d\n", pdata->gpio_irq, ret);
188 ret = request_irq(client->irq, vsense_isr,
189 IRQF_SAMPLE_RANDOM | IRQF_TRIGGER_FALLING,
190 client->name, ddata);
192 dev_err(&client->dev, "unable to claim irq %d, error %d\n",
197 INIT_DELAYED_WORK(&ddata->work, vsense_work);
199 ret = input_register_device(input);
201 dev_err(&client->dev, "failed to register input device, "
206 ddata->input = input;
207 ddata->client = client;
208 ddata->reset_gpio = pdata->gpio_reset;
209 ddata->irq_gpio = pdata->gpio_irq;
210 i2c_set_clientdata(client, ddata);
211 input_set_drvdata(input, ddata);
213 dev_dbg(&client->dev, "probe %02x, gpio %i, irq %i, \"%s\"\n",
214 client->addr, pdata->gpio_irq, client->irq, client->name);
219 free_irq(client->irq, ddata);
221 gpio_free(pdata->gpio_irq);
225 input_free_device(input);
229 static int __devexit vsense_remove(struct i2c_client *client)
231 struct vsense_drvdata *ddata;
233 dev_dbg(&client->dev, "remove\n");
235 ddata = i2c_get_clientdata(client);
237 free_irq(client->irq, ddata);
238 cancel_delayed_work_sync(&ddata->work);
239 input_unregister_device(ddata->input);
240 gpio_free(ddata->irq_gpio);
246 static const struct i2c_device_id vsense_id[] = {
251 static struct i2c_driver vsense_driver = {
255 .probe = vsense_probe,
256 .remove = __devexit_p(vsense_remove),
257 .id_table = vsense_id,
260 static int __init vsense_init(void)
262 return i2c_add_driver(&vsense_driver);
265 static void __exit vsense_exit(void)
267 i2c_del_driver(&vsense_driver);
271 MODULE_AUTHOR("Grazvydas Ignotas");
272 MODULE_DESCRIPTION("VSense navigation device driver");
273 MODULE_LICENSE("GPL");
275 module_init(vsense_init);
276 module_exit(vsense_exit);