1 | /* |
2 | * Copyright (c) 2011 Bosch Sensortec GmbH |
3 | * Copyright (c) 2011 Unixphere |
4 | * |
5 | * This driver adds support for Bosch Sensortec's digital acceleration |
6 | * sensors BMA150 and SMB380. |
7 | * The SMB380 is fully compatible with BMA150 and only differs in packaging. |
8 | * |
9 | * The datasheet for the BMA150 chip can be found here: |
10 | * http://www.bosch-sensortec.com/content/language1/downloads/BST-BMA150-DS000-07.pdf |
11 | * |
12 | * This program is free software; you can redistribute it and/or modify |
13 | * it under the terms of the GNU General Public License as published by |
14 | * the Free Software Foundation; either version 2 of the License, or |
15 | * (at your option) any later version. |
16 | * |
17 | * This program is distributed in the hope that it will be useful, |
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
20 | * GNU General Public License for more details. |
21 | * |
22 | * You should have received a copy of the GNU General Public License |
23 | * along with this program; if not, write to the Free Software |
24 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
25 | */ |
26 | #include <linux/kernel.h> |
27 | #include <linux/module.h> |
28 | #include <linux/i2c.h> |
29 | #include <linux/input.h> |
30 | #include <linux/input-polldev.h> |
31 | #include <linux/interrupt.h> |
32 | #include <linux/delay.h> |
33 | #include <linux/slab.h> |
34 | #include <linux/pm.h> |
35 | #include <linux/pm_runtime.h> |
36 | #include <linux/bma150.h> |
37 | |
38 | #define ABSMAX_ACC_VAL 0x01FF |
39 | #define ABSMIN_ACC_VAL -(ABSMAX_ACC_VAL) |
40 | |
41 | /* Each axis is represented by a 2-byte data word */ |
42 | #define BMA150_XYZ_DATA_SIZE 6 |
43 | |
44 | /* Input poll interval in milliseconds */ |
45 | #define BMA150_POLL_INTERVAL 10 |
46 | #define BMA150_POLL_MAX 200 |
47 | #define BMA150_POLL_MIN 0 |
48 | |
49 | #define BMA150_MODE_NORMAL 0 |
50 | #define BMA150_MODE_SLEEP 2 |
51 | #define BMA150_MODE_WAKE_UP 3 |
52 | |
53 | /* Data register addresses */ |
54 | #define BMA150_DATA_0_REG 0x00 |
55 | #define BMA150_DATA_1_REG 0x01 |
56 | #define BMA150_DATA_2_REG 0x02 |
57 | |
58 | /* Control register addresses */ |
59 | #define BMA150_CTRL_0_REG 0x0A |
60 | #define BMA150_CTRL_1_REG 0x0B |
61 | #define BMA150_CTRL_2_REG 0x14 |
62 | #define BMA150_CTRL_3_REG 0x15 |
63 | |
64 | /* Configuration/Setting register addresses */ |
65 | #define BMA150_CFG_0_REG 0x0C |
66 | #define BMA150_CFG_1_REG 0x0D |
67 | #define BMA150_CFG_2_REG 0x0E |
68 | #define BMA150_CFG_3_REG 0x0F |
69 | #define BMA150_CFG_4_REG 0x10 |
70 | #define BMA150_CFG_5_REG 0x11 |
71 | |
72 | #define BMA150_CHIP_ID 2 |
73 | #define BMA150_CHIP_ID_REG BMA150_DATA_0_REG |
74 | |
75 | #define BMA150_ACC_X_LSB_REG BMA150_DATA_2_REG |
76 | |
77 | #define BMA150_SLEEP_POS 0 |
78 | #define BMA150_SLEEP_MSK 0x01 |
79 | #define BMA150_SLEEP_REG BMA150_CTRL_0_REG |
80 | |
81 | #define BMA150_BANDWIDTH_POS 0 |
82 | #define BMA150_BANDWIDTH_MSK 0x07 |
83 | #define BMA150_BANDWIDTH_REG BMA150_CTRL_2_REG |
84 | |
85 | #define BMA150_RANGE_POS 3 |
86 | #define BMA150_RANGE_MSK 0x18 |
87 | #define BMA150_RANGE_REG BMA150_CTRL_2_REG |
88 | |
89 | #define BMA150_WAKE_UP_POS 0 |
90 | #define BMA150_WAKE_UP_MSK 0x01 |
91 | #define BMA150_WAKE_UP_REG BMA150_CTRL_3_REG |
92 | |
93 | #define BMA150_SW_RES_POS 1 |
94 | #define BMA150_SW_RES_MSK 0x02 |
95 | #define BMA150_SW_RES_REG BMA150_CTRL_0_REG |
96 | |
97 | /* Any-motion interrupt register fields */ |
98 | #define BMA150_ANY_MOTION_EN_POS 6 |
99 | #define BMA150_ANY_MOTION_EN_MSK 0x40 |
100 | #define BMA150_ANY_MOTION_EN_REG BMA150_CTRL_1_REG |
101 | |
102 | #define BMA150_ANY_MOTION_DUR_POS 6 |
103 | #define BMA150_ANY_MOTION_DUR_MSK 0xC0 |
104 | #define BMA150_ANY_MOTION_DUR_REG BMA150_CFG_5_REG |
105 | |
106 | #define BMA150_ANY_MOTION_THRES_REG BMA150_CFG_4_REG |
107 | |
108 | /* Advanced interrupt register fields */ |
109 | #define BMA150_ADV_INT_EN_POS 6 |
110 | #define BMA150_ADV_INT_EN_MSK 0x40 |
111 | #define BMA150_ADV_INT_EN_REG BMA150_CTRL_3_REG |
112 | |
113 | /* High-G interrupt register fields */ |
114 | #define BMA150_HIGH_G_EN_POS 1 |
115 | #define BMA150_HIGH_G_EN_MSK 0x02 |
116 | #define BMA150_HIGH_G_EN_REG BMA150_CTRL_1_REG |
117 | |
118 | #define BMA150_HIGH_G_HYST_POS 3 |
119 | #define BMA150_HIGH_G_HYST_MSK 0x38 |
120 | #define BMA150_HIGH_G_HYST_REG BMA150_CFG_5_REG |
121 | |
122 | #define BMA150_HIGH_G_DUR_REG BMA150_CFG_3_REG |
123 | #define BMA150_HIGH_G_THRES_REG BMA150_CFG_2_REG |
124 | |
125 | /* Low-G interrupt register fields */ |
126 | #define BMA150_LOW_G_EN_POS 0 |
127 | #define BMA150_LOW_G_EN_MSK 0x01 |
128 | #define BMA150_LOW_G_EN_REG BMA150_CTRL_1_REG |
129 | |
130 | #define BMA150_LOW_G_HYST_POS 0 |
131 | #define BMA150_LOW_G_HYST_MSK 0x07 |
132 | #define BMA150_LOW_G_HYST_REG BMA150_CFG_5_REG |
133 | |
134 | #define BMA150_LOW_G_DUR_REG BMA150_CFG_1_REG |
135 | #define BMA150_LOW_G_THRES_REG BMA150_CFG_0_REG |
136 | |
137 | struct bma150_data { |
138 | struct i2c_client *client; |
139 | struct input_polled_dev *input_polled; |
140 | struct input_dev *input; |
141 | u8 mode; |
142 | }; |
143 | |
144 | /* |
145 | * The settings for the given range, bandwidth and interrupt features |
146 | * are stated and verified by Bosch Sensortec where they are configured |
147 | * to provide a generic sensitivity performance. |
148 | */ |
149 | static const struct bma150_cfg default_cfg = { |
150 | .any_motion_int = 1, |
151 | .hg_int = 1, |
152 | .lg_int = 1, |
153 | .any_motion_dur = 0, |
154 | .any_motion_thres = 0, |
155 | .hg_hyst = 0, |
156 | .hg_dur = 150, |
157 | .hg_thres = 160, |
158 | .lg_hyst = 0, |
159 | .lg_dur = 150, |
160 | .lg_thres = 20, |
161 | .range = BMA150_RANGE_2G, |
162 | .bandwidth = BMA150_BW_50HZ |
163 | }; |
164 | |
165 | static int bma150_write_byte(struct i2c_client *client, u8 reg, u8 val) |
166 | { |
167 | s32 ret; |
168 | |
169 | /* As per specification, disable irq in between register writes */ |
170 | if (client->irq) |
171 | disable_irq_nosync(client->irq); |
172 | |
173 | ret = i2c_smbus_write_byte_data(client, reg, val); |
174 | |
175 | if (client->irq) |
176 | enable_irq(client->irq); |
177 | |
178 | return ret; |
179 | } |
180 | |
181 | static int bma150_set_reg_bits(struct i2c_client *client, |
182 | int val, int shift, u8 mask, u8 reg) |
183 | { |
184 | int data; |
185 | |
186 | data = i2c_smbus_read_byte_data(client, reg); |
187 | if (data < 0) |
188 | return data; |
189 | |
190 | data = (data & ~mask) | ((val << shift) & mask); |
191 | return bma150_write_byte(client, reg, data); |
192 | } |
193 | |
194 | static int bma150_set_mode(struct bma150_data *bma150, u8 mode) |
195 | { |
196 | int error; |
197 | |
198 | error = bma150_set_reg_bits(bma150->client, mode, BMA150_WAKE_UP_POS, |
199 | BMA150_WAKE_UP_MSK, BMA150_WAKE_UP_REG); |
200 | if (error) |
201 | return error; |
202 | |
203 | error = bma150_set_reg_bits(bma150->client, mode, BMA150_SLEEP_POS, |
204 | BMA150_SLEEP_MSK, BMA150_SLEEP_REG); |
205 | if (error) |
206 | return error; |
207 | |
208 | if (mode == BMA150_MODE_NORMAL) |
209 | usleep_range(2000, 2100); |
210 | |
211 | bma150->mode = mode; |
212 | return 0; |
213 | } |
214 | |
215 | static int bma150_soft_reset(struct bma150_data *bma150) |
216 | { |
217 | int error; |
218 | |
219 | error = bma150_set_reg_bits(bma150->client, 1, BMA150_SW_RES_POS, |
220 | BMA150_SW_RES_MSK, BMA150_SW_RES_REG); |
221 | if (error) |
222 | return error; |
223 | |
224 | usleep_range(2000, 2100); |
225 | return 0; |
226 | } |
227 | |
228 | static int bma150_set_range(struct bma150_data *bma150, u8 range) |
229 | { |
230 | return bma150_set_reg_bits(bma150->client, range, BMA150_RANGE_POS, |
231 | BMA150_RANGE_MSK, BMA150_RANGE_REG); |
232 | } |
233 | |
234 | static int bma150_set_bandwidth(struct bma150_data *bma150, u8 bw) |
235 | { |
236 | return bma150_set_reg_bits(bma150->client, bw, BMA150_BANDWIDTH_POS, |
237 | BMA150_BANDWIDTH_MSK, BMA150_BANDWIDTH_REG); |
238 | } |
239 | |
240 | static int bma150_set_low_g_interrupt(struct bma150_data *bma150, |
241 | u8 enable, u8 hyst, u8 dur, u8 thres) |
242 | { |
243 | int error; |
244 | |
245 | error = bma150_set_reg_bits(bma150->client, hyst, |
246 | BMA150_LOW_G_HYST_POS, BMA150_LOW_G_HYST_MSK, |
247 | BMA150_LOW_G_HYST_REG); |
248 | if (error) |
249 | return error; |
250 | |
251 | error = bma150_write_byte(bma150->client, BMA150_LOW_G_DUR_REG, dur); |
252 | if (error) |
253 | return error; |
254 | |
255 | error = bma150_write_byte(bma150->client, BMA150_LOW_G_THRES_REG, thres); |
256 | if (error) |
257 | return error; |
258 | |
259 | return bma150_set_reg_bits(bma150->client, !!enable, |
260 | BMA150_LOW_G_EN_POS, BMA150_LOW_G_EN_MSK, |
261 | BMA150_LOW_G_EN_REG); |
262 | } |
263 | |
264 | static int bma150_set_high_g_interrupt(struct bma150_data *bma150, |
265 | u8 enable, u8 hyst, u8 dur, u8 thres) |
266 | { |
267 | int error; |
268 | |
269 | error = bma150_set_reg_bits(bma150->client, hyst, |
270 | BMA150_HIGH_G_HYST_POS, BMA150_HIGH_G_HYST_MSK, |
271 | BMA150_HIGH_G_HYST_REG); |
272 | if (error) |
273 | return error; |
274 | |
275 | error = bma150_write_byte(bma150->client, |
276 | BMA150_HIGH_G_DUR_REG, dur); |
277 | if (error) |
278 | return error; |
279 | |
280 | error = bma150_write_byte(bma150->client, |
281 | BMA150_HIGH_G_THRES_REG, thres); |
282 | if (error) |
283 | return error; |
284 | |
285 | return bma150_set_reg_bits(bma150->client, !!enable, |
286 | BMA150_HIGH_G_EN_POS, BMA150_HIGH_G_EN_MSK, |
287 | BMA150_HIGH_G_EN_REG); |
288 | } |
289 | |
290 | |
291 | static int bma150_set_any_motion_interrupt(struct bma150_data *bma150, |
292 | u8 enable, u8 dur, u8 thres) |
293 | { |
294 | int error; |
295 | |
296 | error = bma150_set_reg_bits(bma150->client, dur, |
297 | BMA150_ANY_MOTION_DUR_POS, |
298 | BMA150_ANY_MOTION_DUR_MSK, |
299 | BMA150_ANY_MOTION_DUR_REG); |
300 | if (error) |
301 | return error; |
302 | |
303 | error = bma150_write_byte(bma150->client, |
304 | BMA150_ANY_MOTION_THRES_REG, thres); |
305 | if (error) |
306 | return error; |
307 | |
308 | error = bma150_set_reg_bits(bma150->client, !!enable, |
309 | BMA150_ADV_INT_EN_POS, BMA150_ADV_INT_EN_MSK, |
310 | BMA150_ADV_INT_EN_REG); |
311 | if (error) |
312 | return error; |
313 | |
314 | return bma150_set_reg_bits(bma150->client, !!enable, |
315 | BMA150_ANY_MOTION_EN_POS, |
316 | BMA150_ANY_MOTION_EN_MSK, |
317 | BMA150_ANY_MOTION_EN_REG); |
318 | } |
319 | |
320 | static void bma150_report_xyz(struct bma150_data *bma150) |
321 | { |
322 | u8 data[BMA150_XYZ_DATA_SIZE]; |
323 | s16 x, y, z; |
324 | s32 ret; |
325 | |
326 | ret = i2c_smbus_read_i2c_block_data(bma150->client, |
327 | BMA150_ACC_X_LSB_REG, BMA150_XYZ_DATA_SIZE, data); |
328 | if (ret != BMA150_XYZ_DATA_SIZE) |
329 | return; |
330 | |
331 | x = ((0xc0 & data[0]) >> 6) | (data[1] << 2); |
332 | y = ((0xc0 & data[2]) >> 6) | (data[3] << 2); |
333 | z = ((0xc0 & data[4]) >> 6) | (data[5] << 2); |
334 | |
335 | x = sign_extend32(x, 9); |
336 | y = sign_extend32(y, 9); |
337 | z = sign_extend32(z, 9); |
338 | |
339 | input_report_abs(bma150->input, ABS_X, x); |
340 | input_report_abs(bma150->input, ABS_Y, y); |
341 | input_report_abs(bma150->input, ABS_Z, z); |
342 | input_sync(bma150->input); |
343 | } |
344 | |
345 | static irqreturn_t bma150_irq_thread(int irq, void *dev) |
346 | { |
347 | bma150_report_xyz(dev); |
348 | |
349 | return IRQ_HANDLED; |
350 | } |
351 | |
352 | static void bma150_poll(struct input_polled_dev *dev) |
353 | { |
354 | bma150_report_xyz(dev->private); |
355 | } |
356 | |
357 | static int bma150_open(struct bma150_data *bma150) |
358 | { |
359 | int error; |
360 | |
361 | error = pm_runtime_get_sync(&bma150->client->dev); |
362 | if (error < 0 && error != -ENOSYS) |
363 | return error; |
364 | |
365 | /* |
366 | * See if runtime PM woke up the device. If runtime PM |
367 | * is disabled we need to do it ourselves. |
368 | */ |
369 | if (bma150->mode != BMA150_MODE_NORMAL) { |
370 | error = bma150_set_mode(bma150, BMA150_MODE_NORMAL); |
371 | if (error) |
372 | return error; |
373 | } |
374 | |
375 | return 0; |
376 | } |
377 | |
378 | static void bma150_close(struct bma150_data *bma150) |
379 | { |
380 | pm_runtime_put_sync(&bma150->client->dev); |
381 | |
382 | if (bma150->mode != BMA150_MODE_SLEEP) |
383 | bma150_set_mode(bma150, BMA150_MODE_SLEEP); |
384 | } |
385 | |
386 | static int bma150_irq_open(struct input_dev *input) |
387 | { |
388 | struct bma150_data *bma150 = input_get_drvdata(input); |
389 | |
390 | return bma150_open(bma150); |
391 | } |
392 | |
393 | static void bma150_irq_close(struct input_dev *input) |
394 | { |
395 | struct bma150_data *bma150 = input_get_drvdata(input); |
396 | |
397 | bma150_close(bma150); |
398 | } |
399 | |
400 | static void bma150_poll_open(struct input_polled_dev *ipoll_dev) |
401 | { |
402 | struct bma150_data *bma150 = ipoll_dev->private; |
403 | |
404 | bma150_open(bma150); |
405 | } |
406 | |
407 | static void bma150_poll_close(struct input_polled_dev *ipoll_dev) |
408 | { |
409 | struct bma150_data *bma150 = ipoll_dev->private; |
410 | |
411 | bma150_close(bma150); |
412 | } |
413 | |
414 | static int bma150_initialize(struct bma150_data *bma150, |
415 | const struct bma150_cfg *cfg) |
416 | { |
417 | int error; |
418 | |
419 | error = bma150_soft_reset(bma150); |
420 | if (error) |
421 | return error; |
422 | |
423 | error = bma150_set_bandwidth(bma150, cfg->bandwidth); |
424 | if (error) |
425 | return error; |
426 | |
427 | error = bma150_set_range(bma150, cfg->range); |
428 | if (error) |
429 | return error; |
430 | |
431 | if (bma150->client->irq) { |
432 | error = bma150_set_any_motion_interrupt(bma150, |
433 | cfg->any_motion_int, |
434 | cfg->any_motion_dur, |
435 | cfg->any_motion_thres); |
436 | if (error) |
437 | return error; |
438 | |
439 | error = bma150_set_high_g_interrupt(bma150, |
440 | cfg->hg_int, cfg->hg_hyst, |
441 | cfg->hg_dur, cfg->hg_thres); |
442 | if (error) |
443 | return error; |
444 | |
445 | error = bma150_set_low_g_interrupt(bma150, |
446 | cfg->lg_int, cfg->lg_hyst, |
447 | cfg->lg_dur, cfg->lg_thres); |
448 | if (error) |
449 | return error; |
450 | } |
451 | |
452 | return bma150_set_mode(bma150, BMA150_MODE_SLEEP); |
453 | } |
454 | |
455 | static void bma150_init_input_device(struct bma150_data *bma150, |
456 | struct input_dev *idev) |
457 | { |
458 | idev->name = BMA150_DRIVER; |
459 | idev->phys = BMA150_DRIVER "/input0" ; |
460 | idev->id.bustype = BUS_I2C; |
461 | idev->dev.parent = &bma150->client->dev; |
462 | |
463 | idev->evbit[0] = BIT_MASK(EV_ABS); |
464 | input_set_abs_params(idev, ABS_X, ABSMIN_ACC_VAL, ABSMAX_ACC_VAL, 0, 0); |
465 | input_set_abs_params(idev, ABS_Y, ABSMIN_ACC_VAL, ABSMAX_ACC_VAL, 0, 0); |
466 | input_set_abs_params(idev, ABS_Z, ABSMIN_ACC_VAL, ABSMAX_ACC_VAL, 0, 0); |
467 | } |
468 | |
469 | static int bma150_register_input_device(struct bma150_data *bma150) |
470 | { |
471 | struct input_dev *idev; |
472 | int error; |
473 | |
474 | idev = input_allocate_device(); |
475 | if (!idev) |
476 | return -ENOMEM; |
477 | |
478 | bma150_init_input_device(bma150, idev); |
479 | |
480 | idev->open = bma150_irq_open; |
481 | idev->close = bma150_irq_close; |
482 | input_set_drvdata(idev, bma150); |
483 | |
484 | bma150->input = idev; |
485 | |
486 | error = input_register_device(idev); |
487 | if (error) { |
488 | input_free_device(idev); |
489 | return error; |
490 | } |
491 | |
492 | return 0; |
493 | } |
494 | |
495 | static int bma150_register_polled_device(struct bma150_data *bma150) |
496 | { |
497 | struct input_polled_dev *ipoll_dev; |
498 | int error; |
499 | |
500 | ipoll_dev = input_allocate_polled_device(); |
501 | if (!ipoll_dev) |
502 | return -ENOMEM; |
503 | |
504 | ipoll_dev->private = bma150; |
505 | ipoll_dev->open = bma150_poll_open; |
506 | ipoll_dev->close = bma150_poll_close; |
507 | ipoll_dev->poll = bma150_poll; |
508 | ipoll_dev->poll_interval = BMA150_POLL_INTERVAL; |
509 | ipoll_dev->poll_interval_min = BMA150_POLL_MIN; |
510 | ipoll_dev->poll_interval_max = BMA150_POLL_MAX; |
511 | |
512 | bma150_init_input_device(bma150, ipoll_dev->input); |
513 | |
514 | bma150->input_polled = ipoll_dev; |
515 | bma150->input = ipoll_dev->input; |
516 | |
517 | error = input_register_polled_device(ipoll_dev); |
518 | if (error) { |
519 | input_free_polled_device(ipoll_dev); |
520 | return error; |
521 | } |
522 | |
523 | return 0; |
524 | } |
525 | |
526 | static int bma150_probe(struct i2c_client *client, |
527 | const struct i2c_device_id *id) |
528 | { |
529 | const struct bma150_platform_data *pdata = |
530 | dev_get_platdata(&client->dev); |
531 | const struct bma150_cfg *cfg; |
532 | struct bma150_data *bma150; |
533 | int chip_id; |
534 | int error; |
535 | |
536 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { |
537 | dev_err(&client->dev, "i2c_check_functionality error\n" ); |
538 | return -EIO; |
539 | } |
540 | |
541 | chip_id = i2c_smbus_read_byte_data(client, BMA150_CHIP_ID_REG); |
542 | if (chip_id != BMA150_CHIP_ID) { |
543 | dev_err(&client->dev, "BMA150 chip id error: %d\n" , chip_id); |
544 | return -EINVAL; |
545 | } |
546 | |
547 | bma150 = kzalloc(sizeof(struct bma150_data), GFP_KERNEL); |
548 | if (!bma150) |
549 | return -ENOMEM; |
550 | |
551 | bma150->client = client; |
552 | |
553 | if (pdata) { |
554 | if (pdata->irq_gpio_cfg) { |
555 | error = pdata->irq_gpio_cfg(); |
556 | if (error) { |
557 | dev_err(&client->dev, |
558 | "IRQ GPIO conf. error %d, error %d\n" , |
559 | client->irq, error); |
560 | goto err_free_mem; |
561 | } |
562 | } |
563 | cfg = &pdata->cfg; |
564 | } else { |
565 | cfg = &default_cfg; |
566 | } |
567 | |
568 | error = bma150_initialize(bma150, cfg); |
569 | if (error) |
570 | goto err_free_mem; |
571 | |
572 | if (client->irq > 0) { |
573 | error = bma150_register_input_device(bma150); |
574 | if (error) |
575 | goto err_free_mem; |
576 | |
577 | error = request_threaded_irq(client->irq, |
578 | NULL, bma150_irq_thread, |
579 | IRQF_TRIGGER_RISING | IRQF_ONESHOT, |
580 | BMA150_DRIVER, bma150); |
581 | if (error) { |
582 | dev_err(&client->dev, |
583 | "irq request failed %d, error %d\n" , |
584 | client->irq, error); |
585 | input_unregister_device(bma150->input); |
586 | goto err_free_mem; |
587 | } |
588 | } else { |
589 | error = bma150_register_polled_device(bma150); |
590 | if (error) |
591 | goto err_free_mem; |
592 | } |
593 | |
594 | i2c_set_clientdata(client, bma150); |
595 | |
596 | pm_runtime_enable(&client->dev); |
597 | |
598 | return 0; |
599 | |
600 | err_free_mem: |
601 | kfree(bma150); |
602 | return error; |
603 | } |
604 | |
605 | static int bma150_remove(struct i2c_client *client) |
606 | { |
607 | struct bma150_data *bma150 = i2c_get_clientdata(client); |
608 | |
609 | pm_runtime_disable(&client->dev); |
610 | |
611 | if (client->irq > 0) { |
612 | free_irq(client->irq, bma150); |
613 | input_unregister_device(bma150->input); |
614 | } else { |
615 | input_unregister_polled_device(bma150->input_polled); |
616 | input_free_polled_device(bma150->input_polled); |
617 | } |
618 | |
619 | kfree(bma150); |
620 | |
621 | return 0; |
622 | } |
623 | |
624 | #ifdef CONFIG_PM |
625 | static int bma150_suspend(struct device *dev) |
626 | { |
627 | struct i2c_client *client = to_i2c_client(dev); |
628 | struct bma150_data *bma150 = i2c_get_clientdata(client); |
629 | |
630 | return bma150_set_mode(bma150, BMA150_MODE_SLEEP); |
631 | } |
632 | |
633 | static int bma150_resume(struct device *dev) |
634 | { |
635 | struct i2c_client *client = to_i2c_client(dev); |
636 | struct bma150_data *bma150 = i2c_get_clientdata(client); |
637 | |
638 | return bma150_set_mode(bma150, BMA150_MODE_NORMAL); |
639 | } |
640 | #endif |
641 | |
642 | static UNIVERSAL_DEV_PM_OPS(bma150_pm, bma150_suspend, bma150_resume, NULL); |
643 | |
644 | static const struct i2c_device_id bma150_id[] = { |
645 | { "bma150" , 0 }, |
646 | { "smb380" , 0 }, |
647 | { "bma023" , 0 }, |
648 | { } |
649 | }; |
650 | |
651 | MODULE_DEVICE_TABLE(i2c, bma150_id); |
652 | |
653 | static struct i2c_driver bma150_driver = { |
654 | .driver = { |
655 | .name = BMA150_DRIVER, |
656 | .pm = &bma150_pm, |
657 | }, |
658 | .class = I2C_CLASS_HWMON, |
659 | .id_table = bma150_id, |
660 | .probe = bma150_probe, |
661 | .remove = bma150_remove, |
662 | }; |
663 | |
664 | module_i2c_driver(bma150_driver); |
665 | |
666 | MODULE_AUTHOR("Albert Zhang <xu.zhang@bosch-sensortec.com>" ); |
667 | MODULE_DESCRIPTION("BMA150 driver" ); |
668 | MODULE_LICENSE("GPL" ); |
669 | |