diff options
author | Chris Hudson <chudson@kionix.com> | 2011-07-06 21:36:51 -0400 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2011-07-07 00:23:54 -0400 |
commit | e8e70d83912b40c5c9ea7b85a6110b9925fbed62 (patch) | |
tree | 2609ca5262ae720be29dad2c0ea4d450ae678514 /drivers/input | |
parent | 7bed4b2c97d548c652ada6111604568ea6b0c423 (diff) |
Input: add support for Kionix KXTJ9 accelerometer
Signed-off-by: Chris Hudson <chudson@kionix.com>
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input')
-rw-r--r-- | drivers/input/misc/Kconfig | 17 | ||||
-rw-r--r-- | drivers/input/misc/Makefile | 1 | ||||
-rw-r--r-- | drivers/input/misc/kxtj9.c | 671 |
3 files changed, 689 insertions, 0 deletions
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig index 6fdce4b86856..01344280e145 100644 --- a/drivers/input/misc/Kconfig +++ b/drivers/input/misc/Kconfig | |||
@@ -230,6 +230,23 @@ config INPUT_KEYSPAN_REMOTE | |||
230 | To compile this driver as a module, choose M here: the module will | 230 | To compile this driver as a module, choose M here: the module will |
231 | be called keyspan_remote. | 231 | be called keyspan_remote. |
232 | 232 | ||
233 | config INPUT_KXTJ9 | ||
234 | tristate "Kionix KXTJ9 tri-axis digital accelerometer" | ||
235 | depends on I2C | ||
236 | help | ||
237 | Say Y here to enable support for the Kionix KXTJ9 digital tri-axis | ||
238 | accelerometer. | ||
239 | |||
240 | To compile this driver as a module, choose M here: the module will | ||
241 | be called kxtj9. | ||
242 | |||
243 | config INPUT_KXTJ9_POLLED_MODE | ||
244 | bool "Enable polling mode support" | ||
245 | depends on INPUT_KXTJ9 | ||
246 | select INPUT_POLLDEV | ||
247 | help | ||
248 | Say Y here if you need accelerometer to work in polling mode. | ||
249 | |||
233 | config INPUT_POWERMATE | 250 | config INPUT_POWERMATE |
234 | tristate "Griffin PowerMate and Contour Jog support" | 251 | tristate "Griffin PowerMate and Contour Jog support" |
235 | depends on USB_ARCH_HAS_HCD | 252 | depends on USB_ARCH_HAS_HCD |
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile index b7e227aa117a..be39d813354d 100644 --- a/drivers/input/misc/Makefile +++ b/drivers/input/misc/Makefile | |||
@@ -25,6 +25,7 @@ obj-$(CONFIG_INPUT_DM355EVM) += dm355evm_keys.o | |||
25 | obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o | 25 | obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o |
26 | obj-$(CONFIG_INPUT_IXP4XX_BEEPER) += ixp4xx-beeper.o | 26 | obj-$(CONFIG_INPUT_IXP4XX_BEEPER) += ixp4xx-beeper.o |
27 | obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o | 27 | obj-$(CONFIG_INPUT_KEYSPAN_REMOTE) += keyspan_remote.o |
28 | obj-$(CONFIG_INPUT_KXTJ9) += kxtj9.o | ||
28 | obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o | 29 | obj-$(CONFIG_INPUT_M68K_BEEP) += m68kspkr.o |
29 | obj-$(CONFIG_INPUT_MAX8925_ONKEY) += max8925_onkey.o | 30 | obj-$(CONFIG_INPUT_MAX8925_ONKEY) += max8925_onkey.o |
30 | obj-$(CONFIG_INPUT_MMA8450) += mma8450.o | 31 | obj-$(CONFIG_INPUT_MMA8450) += mma8450.o |
diff --git a/drivers/input/misc/kxtj9.c b/drivers/input/misc/kxtj9.c new file mode 100644 index 000000000000..a416f7f06738 --- /dev/null +++ b/drivers/input/misc/kxtj9.c | |||
@@ -0,0 +1,671 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2011 Kionix, Inc. | ||
3 | * Written by Chris Hudson <chudson@kionix.com> | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License version 2 as | ||
7 | * published by the Free Software Foundation. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||
17 | * 02111-1307, USA | ||
18 | */ | ||
19 | |||
20 | #include <linux/delay.h> | ||
21 | #include <linux/i2c.h> | ||
22 | #include <linux/input.h> | ||
23 | #include <linux/interrupt.h> | ||
24 | #include <linux/slab.h> | ||
25 | #include <linux/input/kxtj9.h> | ||
26 | #include <linux/input-polldev.h> | ||
27 | |||
28 | #define NAME "kxtj9" | ||
29 | #define G_MAX 8000 | ||
30 | /* OUTPUT REGISTERS */ | ||
31 | #define XOUT_L 0x06 | ||
32 | #define WHO_AM_I 0x0F | ||
33 | /* CONTROL REGISTERS */ | ||
34 | #define INT_REL 0x1A | ||
35 | #define CTRL_REG1 0x1B | ||
36 | #define INT_CTRL1 0x1E | ||
37 | #define DATA_CTRL 0x21 | ||
38 | /* CONTROL REGISTER 1 BITS */ | ||
39 | #define PC1_OFF 0x7F | ||
40 | #define PC1_ON (1 << 7) | ||
41 | /* Data ready funtion enable bit: set during probe if using irq mode */ | ||
42 | #define DRDYE (1 << 5) | ||
43 | /* INTERRUPT CONTROL REGISTER 1 BITS */ | ||
44 | /* Set these during probe if using irq mode */ | ||
45 | #define KXTJ9_IEL (1 << 3) | ||
46 | #define KXTJ9_IEA (1 << 4) | ||
47 | #define KXTJ9_IEN (1 << 5) | ||
48 | /* INPUT_ABS CONSTANTS */ | ||
49 | #define FUZZ 3 | ||
50 | #define FLAT 3 | ||
51 | /* RESUME STATE INDICES */ | ||
52 | #define RES_DATA_CTRL 0 | ||
53 | #define RES_CTRL_REG1 1 | ||
54 | #define RES_INT_CTRL1 2 | ||
55 | #define RESUME_ENTRIES 3 | ||
56 | |||
57 | /* | ||
58 | * The following table lists the maximum appropriate poll interval for each | ||
59 | * available output data rate. | ||
60 | */ | ||
61 | static const struct { | ||
62 | unsigned int cutoff; | ||
63 | u8 mask; | ||
64 | } kxtj9_odr_table[] = { | ||
65 | { 3, ODR800F }, | ||
66 | { 5, ODR400F }, | ||
67 | { 10, ODR200F }, | ||
68 | { 20, ODR100F }, | ||
69 | { 40, ODR50F }, | ||
70 | { 80, ODR25F }, | ||
71 | { 0, ODR12_5F}, | ||
72 | }; | ||
73 | |||
74 | struct kxtj9_data { | ||
75 | struct i2c_client *client; | ||
76 | struct kxtj9_platform_data pdata; | ||
77 | struct input_dev *input_dev; | ||
78 | #ifdef CONFIG_INPUT_KXTJ9_POLLED_MODE | ||
79 | struct input_polled_dev *poll_dev; | ||
80 | #endif | ||
81 | unsigned int last_poll_interval; | ||
82 | u8 shift; | ||
83 | u8 ctrl_reg1; | ||
84 | u8 data_ctrl; | ||
85 | u8 int_ctrl; | ||
86 | }; | ||
87 | |||
88 | static int kxtj9_i2c_read(struct kxtj9_data *tj9, u8 addr, u8 *data, int len) | ||
89 | { | ||
90 | struct i2c_msg msgs[] = { | ||
91 | { | ||
92 | .addr = tj9->client->addr, | ||
93 | .flags = tj9->client->flags, | ||
94 | .len = 1, | ||
95 | .buf = &addr, | ||
96 | }, | ||
97 | { | ||
98 | .addr = tj9->client->addr, | ||
99 | .flags = tj9->client->flags | I2C_M_RD, | ||
100 | .len = len, | ||
101 | .buf = data, | ||
102 | }, | ||
103 | }; | ||
104 | |||
105 | return i2c_transfer(tj9->client->adapter, msgs, 2); | ||
106 | } | ||
107 | |||
108 | static void kxtj9_report_acceleration_data(struct kxtj9_data *tj9) | ||
109 | { | ||
110 | s16 acc_data[3]; /* Data bytes from hardware xL, xH, yL, yH, zL, zH */ | ||
111 | s16 x, y, z; | ||
112 | int err; | ||
113 | |||
114 | err = kxtj9_i2c_read(tj9, XOUT_L, (u8 *)acc_data, 6); | ||
115 | if (err < 0) | ||
116 | dev_err(&tj9->client->dev, "accelerometer data read failed\n"); | ||
117 | |||
118 | x = le16_to_cpu(acc_data[tj9->pdata.axis_map_x]) >> tj9->shift; | ||
119 | y = le16_to_cpu(acc_data[tj9->pdata.axis_map_y]) >> tj9->shift; | ||
120 | z = le16_to_cpu(acc_data[tj9->pdata.axis_map_z]) >> tj9->shift; | ||
121 | |||
122 | input_report_abs(tj9->input_dev, ABS_X, tj9->pdata.negate_x ? -x : x); | ||
123 | input_report_abs(tj9->input_dev, ABS_Y, tj9->pdata.negate_y ? -y : y); | ||
124 | input_report_abs(tj9->input_dev, ABS_Z, tj9->pdata.negate_z ? -z : z); | ||
125 | input_sync(tj9->input_dev); | ||
126 | } | ||
127 | |||
128 | static irqreturn_t kxtj9_isr(int irq, void *dev) | ||
129 | { | ||
130 | struct kxtj9_data *tj9 = dev; | ||
131 | int err; | ||
132 | |||
133 | /* data ready is the only possible interrupt type */ | ||
134 | kxtj9_report_acceleration_data(tj9); | ||
135 | |||
136 | err = i2c_smbus_read_byte_data(tj9->client, INT_REL); | ||
137 | if (err < 0) | ||
138 | dev_err(&tj9->client->dev, | ||
139 | "error clearing interrupt status: %d\n", err); | ||
140 | |||
141 | return IRQ_HANDLED; | ||
142 | } | ||
143 | |||
144 | static int kxtj9_update_g_range(struct kxtj9_data *tj9, u8 new_g_range) | ||
145 | { | ||
146 | switch (new_g_range) { | ||
147 | case KXTJ9_G_2G: | ||
148 | tj9->shift = 4; | ||
149 | break; | ||
150 | case KXTJ9_G_4G: | ||
151 | tj9->shift = 3; | ||
152 | break; | ||
153 | case KXTJ9_G_8G: | ||
154 | tj9->shift = 2; | ||
155 | break; | ||
156 | default: | ||
157 | return -EINVAL; | ||
158 | } | ||
159 | |||
160 | tj9->ctrl_reg1 &= 0xe7; | ||
161 | tj9->ctrl_reg1 |= new_g_range; | ||
162 | |||
163 | return 0; | ||
164 | } | ||
165 | |||
166 | static int kxtj9_update_odr(struct kxtj9_data *tj9, unsigned int poll_interval) | ||
167 | { | ||
168 | int err; | ||
169 | int i; | ||
170 | |||
171 | /* Use the lowest ODR that can support the requested poll interval */ | ||
172 | for (i = 0; i < ARRAY_SIZE(kxtj9_odr_table); i++) { | ||
173 | tj9->data_ctrl = kxtj9_odr_table[i].mask; | ||
174 | if (poll_interval < kxtj9_odr_table[i].cutoff) | ||
175 | break; | ||
176 | } | ||
177 | |||
178 | err = i2c_smbus_write_byte_data(tj9->client, CTRL_REG1, 0); | ||
179 | if (err < 0) | ||
180 | return err; | ||
181 | |||
182 | err = i2c_smbus_write_byte_data(tj9->client, DATA_CTRL, tj9->data_ctrl); | ||
183 | if (err < 0) | ||
184 | return err; | ||
185 | |||
186 | err = i2c_smbus_write_byte_data(tj9->client, CTRL_REG1, tj9->ctrl_reg1); | ||
187 | if (err < 0) | ||
188 | return err; | ||
189 | |||
190 | return 0; | ||
191 | } | ||
192 | |||
193 | static int kxtj9_device_power_on(struct kxtj9_data *tj9) | ||
194 | { | ||
195 | if (tj9->pdata.power_on) | ||
196 | return tj9->pdata.power_on(); | ||
197 | |||
198 | return 0; | ||
199 | } | ||
200 | |||
201 | static void kxtj9_device_power_off(struct kxtj9_data *tj9) | ||
202 | { | ||
203 | int err; | ||
204 | |||
205 | tj9->ctrl_reg1 &= PC1_OFF; | ||
206 | err = i2c_smbus_write_byte_data(tj9->client, CTRL_REG1, tj9->ctrl_reg1); | ||
207 | if (err < 0) | ||
208 | dev_err(&tj9->client->dev, "soft power off failed\n"); | ||
209 | |||
210 | if (tj9->pdata.power_off) | ||
211 | tj9->pdata.power_off(); | ||
212 | } | ||
213 | |||
214 | static int kxtj9_enable(struct kxtj9_data *tj9) | ||
215 | { | ||
216 | int err; | ||
217 | |||
218 | err = kxtj9_device_power_on(tj9); | ||
219 | if (err < 0) | ||
220 | return err; | ||
221 | |||
222 | /* ensure that PC1 is cleared before updating control registers */ | ||
223 | err = i2c_smbus_write_byte_data(tj9->client, CTRL_REG1, 0); | ||
224 | if (err < 0) | ||
225 | return err; | ||
226 | |||
227 | /* only write INT_CTRL_REG1 if in irq mode */ | ||
228 | if (tj9->client->irq) { | ||
229 | err = i2c_smbus_write_byte_data(tj9->client, | ||
230 | INT_CTRL1, tj9->int_ctrl); | ||
231 | if (err < 0) | ||
232 | return err; | ||
233 | } | ||
234 | |||
235 | err = kxtj9_update_g_range(tj9, tj9->pdata.g_range); | ||
236 | if (err < 0) | ||
237 | return err; | ||
238 | |||
239 | /* turn on outputs */ | ||
240 | tj9->ctrl_reg1 |= PC1_ON; | ||
241 | err = i2c_smbus_write_byte_data(tj9->client, CTRL_REG1, tj9->ctrl_reg1); | ||
242 | if (err < 0) | ||
243 | return err; | ||
244 | |||
245 | err = kxtj9_update_odr(tj9, tj9->last_poll_interval); | ||
246 | if (err < 0) | ||
247 | return err; | ||
248 | |||
249 | /* clear initial interrupt if in irq mode */ | ||
250 | if (tj9->client->irq) { | ||
251 | err = i2c_smbus_read_byte_data(tj9->client, INT_REL); | ||
252 | if (err < 0) { | ||
253 | dev_err(&tj9->client->dev, | ||
254 | "error clearing interrupt: %d\n", err); | ||
255 | goto fail; | ||
256 | } | ||
257 | } | ||
258 | |||
259 | return 0; | ||
260 | |||
261 | fail: | ||
262 | kxtj9_device_power_off(tj9); | ||
263 | return err; | ||
264 | } | ||
265 | |||
266 | static void kxtj9_disable(struct kxtj9_data *tj9) | ||
267 | { | ||
268 | kxtj9_device_power_off(tj9); | ||
269 | } | ||
270 | |||
271 | static int kxtj9_input_open(struct input_dev *input) | ||
272 | { | ||
273 | struct kxtj9_data *tj9 = input_get_drvdata(input); | ||
274 | |||
275 | return kxtj9_enable(tj9); | ||
276 | } | ||
277 | |||
278 | static void kxtj9_input_close(struct input_dev *dev) | ||
279 | { | ||
280 | struct kxtj9_data *tj9 = input_get_drvdata(dev); | ||
281 | |||
282 | kxtj9_disable(tj9); | ||
283 | } | ||
284 | |||
285 | static void __devinit kxtj9_init_input_device(struct kxtj9_data *tj9, | ||
286 | struct input_dev *input_dev) | ||
287 | { | ||
288 | __set_bit(EV_ABS, input_dev->evbit); | ||
289 | input_set_abs_params(input_dev, ABS_X, -G_MAX, G_MAX, FUZZ, FLAT); | ||
290 | input_set_abs_params(input_dev, ABS_Y, -G_MAX, G_MAX, FUZZ, FLAT); | ||
291 | input_set_abs_params(input_dev, ABS_Z, -G_MAX, G_MAX, FUZZ, FLAT); | ||
292 | |||
293 | input_dev->name = "kxtj9_accel"; | ||
294 | input_dev->id.bustype = BUS_I2C; | ||
295 | input_dev->dev.parent = &tj9->client->dev; | ||
296 | } | ||
297 | |||
298 | static int __devinit kxtj9_setup_input_device(struct kxtj9_data *tj9) | ||
299 | { | ||
300 | struct input_dev *input_dev; | ||
301 | int err; | ||
302 | |||
303 | input_dev = input_allocate_device(); | ||
304 | if (!tj9->input_dev) { | ||
305 | dev_err(&tj9->client->dev, "input device allocate failed\n"); | ||
306 | return -ENOMEM; | ||
307 | } | ||
308 | |||
309 | tj9->input_dev = input_dev; | ||
310 | |||
311 | input_dev->open = kxtj9_input_open; | ||
312 | input_dev->close = kxtj9_input_close; | ||
313 | input_set_drvdata(input_dev, tj9); | ||
314 | |||
315 | kxtj9_init_input_device(tj9, input_dev); | ||
316 | |||
317 | err = input_register_device(tj9->input_dev); | ||
318 | if (err) { | ||
319 | dev_err(&tj9->client->dev, | ||
320 | "unable to register input polled device %s: %d\n", | ||
321 | tj9->input_dev->name, err); | ||
322 | input_free_device(tj9->input_dev); | ||
323 | return err; | ||
324 | } | ||
325 | |||
326 | return 0; | ||
327 | } | ||
328 | |||
329 | /* | ||
330 | * When IRQ mode is selected, we need to provide an interface to allow the user | ||
331 | * to change the output data rate of the part. For consistency, we are using | ||
332 | * the set_poll method, which accepts a poll interval in milliseconds, and then | ||
333 | * calls update_odr() while passing this value as an argument. In IRQ mode, the | ||
334 | * data outputs will not be read AT the requested poll interval, rather, the | ||
335 | * lowest ODR that can support the requested interval. The client application | ||
336 | * will be responsible for retrieving data from the input node at the desired | ||
337 | * interval. | ||
338 | */ | ||
339 | |||
340 | /* Returns currently selected poll interval (in ms) */ | ||
341 | static ssize_t kxtj9_get_poll(struct device *dev, | ||
342 | struct device_attribute *attr, char *buf) | ||
343 | { | ||
344 | struct i2c_client *client = to_i2c_client(dev); | ||
345 | struct kxtj9_data *tj9 = i2c_get_clientdata(client); | ||
346 | |||
347 | return sprintf(buf, "%d\n", tj9->last_poll_interval); | ||
348 | } | ||
349 | |||
350 | /* Allow users to select a new poll interval (in ms) */ | ||
351 | static ssize_t kxtj9_set_poll(struct device *dev, struct device_attribute *attr, | ||
352 | const char *buf, size_t count) | ||
353 | { | ||
354 | struct i2c_client *client = to_i2c_client(dev); | ||
355 | struct kxtj9_data *tj9 = i2c_get_clientdata(client); | ||
356 | struct input_dev *input_dev = tj9->input_dev; | ||
357 | unsigned int interval; | ||
358 | int error; | ||
359 | |||
360 | error = kstrtouint(buf, 10, &interval); | ||
361 | if (error < 0) | ||
362 | return error; | ||
363 | |||
364 | /* Lock the device to prevent races with open/close (and itself) */ | ||
365 | mutex_unlock(&input_dev->mutex); | ||
366 | |||
367 | disable_irq(client->irq); | ||
368 | |||
369 | /* | ||
370 | * Set current interval to the greater of the minimum interval or | ||
371 | * the requested interval | ||
372 | */ | ||
373 | tj9->last_poll_interval = max(interval, tj9->pdata.min_interval); | ||
374 | |||
375 | kxtj9_update_odr(tj9, tj9->last_poll_interval); | ||
376 | |||
377 | enable_irq(client->irq); | ||
378 | mutex_unlock(&input_dev->mutex); | ||
379 | |||
380 | return count; | ||
381 | } | ||
382 | |||
383 | static DEVICE_ATTR(poll, S_IRUGO|S_IWUSR, kxtj9_get_poll, kxtj9_set_poll); | ||
384 | |||
385 | static struct attribute *kxtj9_attributes[] = { | ||
386 | &dev_attr_poll.attr, | ||
387 | NULL | ||
388 | }; | ||
389 | |||
390 | static struct attribute_group kxtj9_attribute_group = { | ||
391 | .attrs = kxtj9_attributes | ||
392 | }; | ||
393 | |||
394 | |||
395 | #ifdef CONFIG_INPUT_KXTJ9_POLLED_MODE | ||
396 | static void kxtj9_poll(struct input_polled_dev *dev) | ||
397 | { | ||
398 | struct kxtj9_data *tj9 = dev->private; | ||
399 | unsigned int poll_interval = dev->poll_interval; | ||
400 | |||
401 | kxtj9_report_acceleration_data(tj9); | ||
402 | |||
403 | if (poll_interval != tj9->last_poll_interval) { | ||
404 | kxtj9_update_odr(tj9, poll_interval); | ||
405 | tj9->last_poll_interval = poll_interval; | ||
406 | } | ||
407 | } | ||
408 | |||
409 | static void kxtj9_polled_input_open(struct input_polled_dev *dev) | ||
410 | { | ||
411 | struct kxtj9_data *tj9 = dev->private; | ||
412 | |||
413 | kxtj9_enable(tj9); | ||
414 | } | ||
415 | |||
416 | static void kxtj9_polled_input_close(struct input_polled_dev *dev) | ||
417 | { | ||
418 | struct kxtj9_data *tj9 = dev->private; | ||
419 | |||
420 | kxtj9_disable(tj9); | ||
421 | } | ||
422 | |||
423 | static int __devinit kxtj9_setup_polled_device(struct kxtj9_data *tj9) | ||
424 | { | ||
425 | int err; | ||
426 | struct input_polled_dev *poll_dev; | ||
427 | poll_dev = input_allocate_polled_device(); | ||
428 | |||
429 | if (!poll_dev) { | ||
430 | dev_err(&tj9->client->dev, | ||
431 | "Failed to allocate polled device\n"); | ||
432 | return -ENOMEM; | ||
433 | } | ||
434 | |||
435 | tj9->poll_dev = poll_dev; | ||
436 | tj9->input_dev = poll_dev->input; | ||
437 | |||
438 | poll_dev->private = tj9; | ||
439 | poll_dev->poll = kxtj9_poll; | ||
440 | poll_dev->open = kxtj9_polled_input_open; | ||
441 | poll_dev->close = kxtj9_polled_input_close; | ||
442 | |||
443 | kxtj9_init_input_device(tj9, poll_dev->input); | ||
444 | |||
445 | err = input_register_polled_device(poll_dev); | ||
446 | if (err) { | ||
447 | dev_err(&tj9->client->dev, | ||
448 | "Unable to register polled device, err=%d\n", err); | ||
449 | input_free_polled_device(poll_dev); | ||
450 | return err; | ||
451 | } | ||
452 | |||
453 | return 0; | ||
454 | } | ||
455 | |||
456 | static void __devexit kxtj9_teardown_polled_device(struct kxtj9_data *tj9) | ||
457 | { | ||
458 | input_unregister_polled_device(tj9->poll_dev); | ||
459 | input_free_polled_device(tj9->poll_dev); | ||
460 | } | ||
461 | |||
462 | #else | ||
463 | |||
464 | static inline int kxtj9_setup_polled_device(struct kxtj9_data *tj9) | ||
465 | { | ||
466 | return -ENOSYS; | ||
467 | } | ||
468 | |||
469 | static inline void kxtj9_teardown_polled_device(struct kxtj9_data *tj9) | ||
470 | { | ||
471 | } | ||
472 | |||
473 | #endif | ||
474 | |||
475 | static int __devinit kxtj9_verify(struct kxtj9_data *tj9) | ||
476 | { | ||
477 | int retval; | ||
478 | |||
479 | retval = kxtj9_device_power_on(tj9); | ||
480 | if (retval < 0) | ||
481 | return retval; | ||
482 | |||
483 | retval = i2c_smbus_read_byte_data(tj9->client, WHO_AM_I); | ||
484 | if (retval < 0) { | ||
485 | dev_err(&tj9->client->dev, "read err int source\n"); | ||
486 | goto out; | ||
487 | } | ||
488 | |||
489 | retval = retval != 0x06 ? -EIO : 0; | ||
490 | |||
491 | out: | ||
492 | kxtj9_device_power_off(tj9); | ||
493 | return retval; | ||
494 | } | ||
495 | |||
496 | static int __devinit kxtj9_probe(struct i2c_client *client, | ||
497 | const struct i2c_device_id *id) | ||
498 | { | ||
499 | const struct kxtj9_platform_data *pdata = client->dev.platform_data; | ||
500 | struct kxtj9_data *tj9; | ||
501 | int err; | ||
502 | |||
503 | if (!i2c_check_functionality(client->adapter, | ||
504 | I2C_FUNC_I2C | I2C_FUNC_SMBUS_BYTE_DATA)) { | ||
505 | dev_err(&client->dev, "client is not i2c capable\n"); | ||
506 | return -ENXIO; | ||
507 | } | ||
508 | |||
509 | if (!pdata) { | ||
510 | dev_err(&client->dev, "platform data is NULL; exiting\n"); | ||
511 | return -EINVAL; | ||
512 | } | ||
513 | |||
514 | tj9 = kzalloc(sizeof(*tj9), GFP_KERNEL); | ||
515 | if (!tj9) { | ||
516 | dev_err(&client->dev, | ||
517 | "failed to allocate memory for module data\n"); | ||
518 | return -ENOMEM; | ||
519 | } | ||
520 | |||
521 | tj9->client = client; | ||
522 | tj9->pdata = *pdata; | ||
523 | |||
524 | if (pdata->init) { | ||
525 | err = pdata->init(); | ||
526 | if (err < 0) | ||
527 | goto err_free_mem; | ||
528 | } | ||
529 | |||
530 | err = kxtj9_verify(tj9); | ||
531 | if (err < 0) { | ||
532 | dev_err(&client->dev, "device not recognized\n"); | ||
533 | goto err_pdata_exit; | ||
534 | } | ||
535 | |||
536 | i2c_set_clientdata(client, tj9); | ||
537 | |||
538 | tj9->ctrl_reg1 = tj9->pdata.res_12bit | tj9->pdata.g_range; | ||
539 | tj9->data_ctrl = tj9->pdata.data_odr_init; | ||
540 | |||
541 | if (client->irq) { | ||
542 | /* If in irq mode, populate INT_CTRL_REG1 and enable DRDY. */ | ||
543 | tj9->int_ctrl |= KXTJ9_IEN | KXTJ9_IEA | KXTJ9_IEL; | ||
544 | tj9->ctrl_reg1 |= DRDYE; | ||
545 | |||
546 | err = kxtj9_setup_input_device(tj9); | ||
547 | if (err) | ||
548 | goto err_pdata_exit; | ||
549 | |||
550 | err = request_threaded_irq(client->irq, NULL, kxtj9_isr, | ||
551 | IRQF_TRIGGER_RISING | IRQF_ONESHOT, | ||
552 | "kxtj9-irq", tj9); | ||
553 | if (err) { | ||
554 | dev_err(&client->dev, "request irq failed: %d\n", err); | ||
555 | goto err_destroy_input; | ||
556 | } | ||
557 | |||
558 | err = sysfs_create_group(&client->dev.kobj, &kxtj9_attribute_group); | ||
559 | if (err) { | ||
560 | dev_err(&client->dev, "sysfs create failed: %d\n", err); | ||
561 | goto err_free_irq; | ||
562 | } | ||
563 | |||
564 | } else { | ||
565 | err = kxtj9_setup_polled_device(tj9); | ||
566 | if (err) | ||
567 | goto err_pdata_exit; | ||
568 | } | ||
569 | |||
570 | return 0; | ||
571 | |||
572 | err_free_irq: | ||
573 | free_irq(client->irq, tj9); | ||
574 | err_destroy_input: | ||
575 | input_unregister_device(tj9->input_dev); | ||
576 | err_pdata_exit: | ||
577 | if (tj9->pdata.exit) | ||
578 | tj9->pdata.exit(); | ||
579 | err_free_mem: | ||
580 | kfree(tj9); | ||
581 | return err; | ||
582 | } | ||
583 | |||
584 | static int __devexit kxtj9_remove(struct i2c_client *client) | ||
585 | { | ||
586 | struct kxtj9_data *tj9 = i2c_get_clientdata(client); | ||
587 | |||
588 | if (client->irq) { | ||
589 | sysfs_remove_group(&client->dev.kobj, &kxtj9_attribute_group); | ||
590 | free_irq(client->irq, tj9); | ||
591 | input_unregister_device(tj9->input_dev); | ||
592 | } else { | ||
593 | kxtj9_teardown_polled_device(tj9); | ||
594 | } | ||
595 | |||
596 | if (tj9->pdata.exit) | ||
597 | tj9->pdata.exit(); | ||
598 | |||
599 | kfree(tj9); | ||
600 | |||
601 | return 0; | ||
602 | } | ||
603 | |||
604 | #ifdef CONFIG_PM_SLEEP | ||
605 | static int kxtj9_suspend(struct device *dev) | ||
606 | { | ||
607 | struct i2c_client *client = to_i2c_client(dev); | ||
608 | struct kxtj9_data *tj9 = i2c_get_clientdata(client); | ||
609 | struct input_dev *input_dev = tj9->input_dev; | ||
610 | |||
611 | mutex_lock(&input_dev->mutex); | ||
612 | |||
613 | if (input_dev->users) | ||
614 | kxtj9_disable(tj9); | ||
615 | |||
616 | mutex_unlock(&input_dev->mutex); | ||
617 | return 0; | ||
618 | } | ||
619 | |||
620 | static int kxtj9_resume(struct device *dev) | ||
621 | { | ||
622 | struct i2c_client *client = to_i2c_client(dev); | ||
623 | struct kxtj9_data *tj9 = i2c_get_clientdata(client); | ||
624 | struct input_dev *input_dev = tj9->input_dev; | ||
625 | int retval = 0; | ||
626 | |||
627 | mutex_lock(&input_dev->mutex); | ||
628 | |||
629 | if (input_dev->users) | ||
630 | kxtj9_enable(tj9); | ||
631 | |||
632 | mutex_unlock(&input_dev->mutex); | ||
633 | return retval; | ||
634 | } | ||
635 | #endif | ||
636 | |||
637 | static SIMPLE_DEV_PM_OPS(kxtj9_pm_ops, kxtj9_suspend, kxtj9_resume); | ||
638 | |||
639 | static const struct i2c_device_id kxtj9_id[] = { | ||
640 | { NAME, 0 }, | ||
641 | { }, | ||
642 | }; | ||
643 | |||
644 | MODULE_DEVICE_TABLE(i2c, kxtj9_id); | ||
645 | |||
646 | static struct i2c_driver kxtj9_driver = { | ||
647 | .driver = { | ||
648 | .name = NAME, | ||
649 | .owner = THIS_MODULE, | ||
650 | .pm = &kxtj9_pm_ops, | ||
651 | }, | ||
652 | .probe = kxtj9_probe, | ||
653 | .remove = __devexit_p(kxtj9_remove), | ||
654 | .id_table = kxtj9_id, | ||
655 | }; | ||
656 | |||
657 | static int __init kxtj9_init(void) | ||
658 | { | ||
659 | return i2c_add_driver(&kxtj9_driver); | ||
660 | } | ||
661 | module_init(kxtj9_init); | ||
662 | |||
663 | static void __exit kxtj9_exit(void) | ||
664 | { | ||
665 | i2c_del_driver(&kxtj9_driver); | ||
666 | } | ||
667 | module_exit(kxtj9_exit); | ||
668 | |||
669 | MODULE_DESCRIPTION("KXTJ9 accelerometer driver"); | ||
670 | MODULE_AUTHOR("Chris Hudson <chudson@kionix.com>"); | ||
671 | MODULE_LICENSE("GPL"); | ||