diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-10-31 20:46:07 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-10-31 20:46:07 -0400 |
commit | 094803e0aab3fe75bbf8202a8f4b5280eaade375 (patch) | |
tree | 278528ca9245a767fcfcfa97d977bd5714c082fd /drivers/misc | |
parent | 32087d4eeca14b82660dab288b1d659963b954bd (diff) | |
parent | d8805e633e054c816c47cb6e727c81f156d9253d (diff) |
Merge branch 'akpm' (Andrew's incoming)
Quoth Andrew:
- Most of MM. Still waiting for the poweroc guys to get off their
butts and review some threaded hugepages patches.
- alpha
- vfs bits
- drivers/misc
- a few core kerenl tweaks
- printk() features
- MAINTAINERS updates
- backlight merge
- leds merge
- various lib/ updates
- checkpatch updates
* akpm: (127 commits)
epoll: fix spurious lockdep warnings
checkpatch: add a --strict check for utf-8 in commit logs
kernel.h/checkpatch: mark strict_strto<foo> and simple_strto<foo> as obsolete
llist-return-whether-list-is-empty-before-adding-in-llist_add-fix
wireless: at76c50x: follow rename pack_hex_byte to hex_byte_pack
fat: follow rename pack_hex_byte() to hex_byte_pack()
security: follow rename pack_hex_byte() to hex_byte_pack()
kgdb: follow rename pack_hex_byte() to hex_byte_pack()
lib: rename pack_hex_byte() to hex_byte_pack()
lib/string.c: fix strim() semantics for strings that have only blanks
lib/idr.c: fix comment for ida_get_new_above()
lib/percpu_counter.c: enclose hotplug only variables in hotplug ifdef
lib/bitmap.c: quiet sparse noise about address space
lib/spinlock_debug.c: print owner on spinlock lockup
lib/kstrtox: common code between kstrto*() and simple_strto*() functions
drivers/leds/leds-lp5521.c: check if reset is successful
leds: turn the blink_timer off before starting to blink
leds: save the delay values after a successful call to blink_set()
drivers/leds/leds-gpio.c: use gpio_get_value_cansleep() when initializing
drivers/leds/leds-lm3530.c: add __devexit_p where needed
...
Diffstat (limited to 'drivers/misc')
-rw-r--r-- | drivers/misc/ad525x_dpot-i2c.c | 1 | ||||
-rw-r--r-- | drivers/misc/fsa9480.c | 3 | ||||
-rw-r--r-- | drivers/misc/lis3lv02d/lis3lv02d.c | 389 | ||||
-rw-r--r-- | drivers/misc/lis3lv02d/lis3lv02d.h | 9 | ||||
-rw-r--r-- | drivers/misc/lis3lv02d/lis3lv02d_i2c.c | 45 | ||||
-rw-r--r-- | drivers/misc/lis3lv02d/lis3lv02d_spi.c | 2 |
6 files changed, 250 insertions, 199 deletions
diff --git a/drivers/misc/ad525x_dpot-i2c.c b/drivers/misc/ad525x_dpot-i2c.c index 4ff73c215746..a39e0555df63 100644 --- a/drivers/misc/ad525x_dpot-i2c.c +++ b/drivers/misc/ad525x_dpot-i2c.c | |||
@@ -98,6 +98,7 @@ static const struct i2c_device_id ad_dpot_id[] = { | |||
98 | {"ad5282", AD5282_ID}, | 98 | {"ad5282", AD5282_ID}, |
99 | {"adn2860", ADN2860_ID}, | 99 | {"adn2860", ADN2860_ID}, |
100 | {"ad5273", AD5273_ID}, | 100 | {"ad5273", AD5273_ID}, |
101 | {"ad5161", AD5161_ID}, | ||
101 | {"ad5171", AD5171_ID}, | 102 | {"ad5171", AD5171_ID}, |
102 | {"ad5170", AD5170_ID}, | 103 | {"ad5170", AD5170_ID}, |
103 | {"ad5172", AD5172_ID}, | 104 | {"ad5172", AD5172_ID}, |
diff --git a/drivers/misc/fsa9480.c b/drivers/misc/fsa9480.c index 27dc0d21aafa..f6586d53e1a3 100644 --- a/drivers/misc/fsa9480.c +++ b/drivers/misc/fsa9480.c | |||
@@ -400,7 +400,8 @@ static int fsa9480_irq_init(struct fsa9480_usbsw *usbsw) | |||
400 | return ret; | 400 | return ret; |
401 | } | 401 | } |
402 | 402 | ||
403 | device_init_wakeup(&client->dev, pdata->wakeup); | 403 | if (pdata) |
404 | device_init_wakeup(&client->dev, pdata->wakeup); | ||
404 | } | 405 | } |
405 | 406 | ||
406 | return 0; | 407 | return 0; |
diff --git a/drivers/misc/lis3lv02d/lis3lv02d.c b/drivers/misc/lis3lv02d/lis3lv02d.c index 8b51cd62d067..29d12a70eb1b 100644 --- a/drivers/misc/lis3lv02d/lis3lv02d.c +++ b/drivers/misc/lis3lv02d/lis3lv02d.c | |||
@@ -163,7 +163,7 @@ static void lis3lv02d_get_xyz(struct lis3lv02d *lis3, int *x, int *y, int *z) | |||
163 | int i; | 163 | int i; |
164 | 164 | ||
165 | if (lis3->blkread) { | 165 | if (lis3->blkread) { |
166 | if (lis3_dev.whoami == WAI_12B) { | 166 | if (lis3->whoami == WAI_12B) { |
167 | u16 data[3]; | 167 | u16 data[3]; |
168 | lis3->blkread(lis3, OUTX_L, 6, (u8 *)data); | 168 | lis3->blkread(lis3, OUTX_L, 6, (u8 *)data); |
169 | for (i = 0; i < 3; i++) | 169 | for (i = 0; i < 3; i++) |
@@ -195,18 +195,30 @@ static int lis3_8_rates[2] = {100, 400}; | |||
195 | static int lis3_3dc_rates[16] = {0, 1, 10, 25, 50, 100, 200, 400, 1600, 5000}; | 195 | static int lis3_3dc_rates[16] = {0, 1, 10, 25, 50, 100, 200, 400, 1600, 5000}; |
196 | 196 | ||
197 | /* ODR is Output Data Rate */ | 197 | /* ODR is Output Data Rate */ |
198 | static int lis3lv02d_get_odr(void) | 198 | static int lis3lv02d_get_odr(struct lis3lv02d *lis3) |
199 | { | 199 | { |
200 | u8 ctrl; | 200 | u8 ctrl; |
201 | int shift; | 201 | int shift; |
202 | 202 | ||
203 | lis3_dev.read(&lis3_dev, CTRL_REG1, &ctrl); | 203 | lis3->read(lis3, CTRL_REG1, &ctrl); |
204 | ctrl &= lis3_dev.odr_mask; | 204 | ctrl &= lis3->odr_mask; |
205 | shift = ffs(lis3_dev.odr_mask) - 1; | 205 | shift = ffs(lis3->odr_mask) - 1; |
206 | return lis3_dev.odrs[(ctrl >> shift)]; | 206 | return lis3->odrs[(ctrl >> shift)]; |
207 | } | 207 | } |
208 | 208 | ||
209 | static int lis3lv02d_set_odr(int rate) | 209 | static int lis3lv02d_get_pwron_wait(struct lis3lv02d *lis3) |
210 | { | ||
211 | int div = lis3lv02d_get_odr(lis3); | ||
212 | |||
213 | if (WARN_ONCE(div == 0, "device returned spurious data")) | ||
214 | return -ENXIO; | ||
215 | |||
216 | /* LIS3 power on delay is quite long */ | ||
217 | msleep(lis3->pwron_delay / div); | ||
218 | return 0; | ||
219 | } | ||
220 | |||
221 | static int lis3lv02d_set_odr(struct lis3lv02d *lis3, int rate) | ||
210 | { | 222 | { |
211 | u8 ctrl; | 223 | u8 ctrl; |
212 | int i, len, shift; | 224 | int i, len, shift; |
@@ -214,14 +226,14 @@ static int lis3lv02d_set_odr(int rate) | |||
214 | if (!rate) | 226 | if (!rate) |
215 | return -EINVAL; | 227 | return -EINVAL; |
216 | 228 | ||
217 | lis3_dev.read(&lis3_dev, CTRL_REG1, &ctrl); | 229 | lis3->read(lis3, CTRL_REG1, &ctrl); |
218 | ctrl &= ~lis3_dev.odr_mask; | 230 | ctrl &= ~lis3->odr_mask; |
219 | len = 1 << hweight_long(lis3_dev.odr_mask); /* # of possible values */ | 231 | len = 1 << hweight_long(lis3->odr_mask); /* # of possible values */ |
220 | shift = ffs(lis3_dev.odr_mask) - 1; | 232 | shift = ffs(lis3->odr_mask) - 1; |
221 | 233 | ||
222 | for (i = 0; i < len; i++) | 234 | for (i = 0; i < len; i++) |
223 | if (lis3_dev.odrs[i] == rate) { | 235 | if (lis3->odrs[i] == rate) { |
224 | lis3_dev.write(&lis3_dev, CTRL_REG1, | 236 | lis3->write(lis3, CTRL_REG1, |
225 | ctrl | (i << shift)); | 237 | ctrl | (i << shift)); |
226 | return 0; | 238 | return 0; |
227 | } | 239 | } |
@@ -240,12 +252,12 @@ static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3]) | |||
240 | mutex_lock(&lis3->mutex); | 252 | mutex_lock(&lis3->mutex); |
241 | 253 | ||
242 | irq_cfg = lis3->irq_cfg; | 254 | irq_cfg = lis3->irq_cfg; |
243 | if (lis3_dev.whoami == WAI_8B) { | 255 | if (lis3->whoami == WAI_8B) { |
244 | lis3->data_ready_count[IRQ_LINE0] = 0; | 256 | lis3->data_ready_count[IRQ_LINE0] = 0; |
245 | lis3->data_ready_count[IRQ_LINE1] = 0; | 257 | lis3->data_ready_count[IRQ_LINE1] = 0; |
246 | 258 | ||
247 | /* Change interrupt cfg to data ready for selftest */ | 259 | /* Change interrupt cfg to data ready for selftest */ |
248 | atomic_inc(&lis3_dev.wake_thread); | 260 | atomic_inc(&lis3->wake_thread); |
249 | lis3->irq_cfg = LIS3_IRQ1_DATA_READY | LIS3_IRQ2_DATA_READY; | 261 | lis3->irq_cfg = LIS3_IRQ1_DATA_READY | LIS3_IRQ2_DATA_READY; |
250 | lis3->read(lis3, CTRL_REG3, &ctrl_reg_data); | 262 | lis3->read(lis3, CTRL_REG3, &ctrl_reg_data); |
251 | lis3->write(lis3, CTRL_REG3, (ctrl_reg_data & | 263 | lis3->write(lis3, CTRL_REG3, (ctrl_reg_data & |
@@ -253,12 +265,12 @@ static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3]) | |||
253 | (LIS3_IRQ1_DATA_READY | LIS3_IRQ2_DATA_READY)); | 265 | (LIS3_IRQ1_DATA_READY | LIS3_IRQ2_DATA_READY)); |
254 | } | 266 | } |
255 | 267 | ||
256 | if (lis3_dev.whoami == WAI_3DC) { | 268 | if (lis3->whoami == WAI_3DC) { |
257 | ctlreg = CTRL_REG4; | 269 | ctlreg = CTRL_REG4; |
258 | selftest = CTRL4_ST0; | 270 | selftest = CTRL4_ST0; |
259 | } else { | 271 | } else { |
260 | ctlreg = CTRL_REG1; | 272 | ctlreg = CTRL_REG1; |
261 | if (lis3_dev.whoami == WAI_12B) | 273 | if (lis3->whoami == WAI_12B) |
262 | selftest = CTRL1_ST; | 274 | selftest = CTRL1_ST; |
263 | else | 275 | else |
264 | selftest = CTRL1_STP; | 276 | selftest = CTRL1_STP; |
@@ -266,7 +278,9 @@ static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3]) | |||
266 | 278 | ||
267 | lis3->read(lis3, ctlreg, ®); | 279 | lis3->read(lis3, ctlreg, ®); |
268 | lis3->write(lis3, ctlreg, (reg | selftest)); | 280 | lis3->write(lis3, ctlreg, (reg | selftest)); |
269 | msleep(lis3->pwron_delay / lis3lv02d_get_odr()); | 281 | ret = lis3lv02d_get_pwron_wait(lis3); |
282 | if (ret) | ||
283 | goto fail; | ||
270 | 284 | ||
271 | /* Read directly to avoid axis remap */ | 285 | /* Read directly to avoid axis remap */ |
272 | x = lis3->read_data(lis3, OUTX); | 286 | x = lis3->read_data(lis3, OUTX); |
@@ -275,7 +289,9 @@ static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3]) | |||
275 | 289 | ||
276 | /* back to normal settings */ | 290 | /* back to normal settings */ |
277 | lis3->write(lis3, ctlreg, reg); | 291 | lis3->write(lis3, ctlreg, reg); |
278 | msleep(lis3->pwron_delay / lis3lv02d_get_odr()); | 292 | ret = lis3lv02d_get_pwron_wait(lis3); |
293 | if (ret) | ||
294 | goto fail; | ||
279 | 295 | ||
280 | results[0] = x - lis3->read_data(lis3, OUTX); | 296 | results[0] = x - lis3->read_data(lis3, OUTX); |
281 | results[1] = y - lis3->read_data(lis3, OUTY); | 297 | results[1] = y - lis3->read_data(lis3, OUTY); |
@@ -283,9 +299,9 @@ static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3]) | |||
283 | 299 | ||
284 | ret = 0; | 300 | ret = 0; |
285 | 301 | ||
286 | if (lis3_dev.whoami == WAI_8B) { | 302 | if (lis3->whoami == WAI_8B) { |
287 | /* Restore original interrupt configuration */ | 303 | /* Restore original interrupt configuration */ |
288 | atomic_dec(&lis3_dev.wake_thread); | 304 | atomic_dec(&lis3->wake_thread); |
289 | lis3->write(lis3, CTRL_REG3, ctrl_reg_data); | 305 | lis3->write(lis3, CTRL_REG3, ctrl_reg_data); |
290 | lis3->irq_cfg = irq_cfg; | 306 | lis3->irq_cfg = irq_cfg; |
291 | 307 | ||
@@ -363,8 +379,9 @@ void lis3lv02d_poweroff(struct lis3lv02d *lis3) | |||
363 | } | 379 | } |
364 | EXPORT_SYMBOL_GPL(lis3lv02d_poweroff); | 380 | EXPORT_SYMBOL_GPL(lis3lv02d_poweroff); |
365 | 381 | ||
366 | void lis3lv02d_poweron(struct lis3lv02d *lis3) | 382 | int lis3lv02d_poweron(struct lis3lv02d *lis3) |
367 | { | 383 | { |
384 | int err; | ||
368 | u8 reg; | 385 | u8 reg; |
369 | 386 | ||
370 | lis3->init(lis3); | 387 | lis3->init(lis3); |
@@ -384,35 +401,41 @@ void lis3lv02d_poweron(struct lis3lv02d *lis3) | |||
384 | lis3->write(lis3, CTRL_REG2, reg); | 401 | lis3->write(lis3, CTRL_REG2, reg); |
385 | } | 402 | } |
386 | 403 | ||
387 | /* LIS3 power on delay is quite long */ | 404 | err = lis3lv02d_get_pwron_wait(lis3); |
388 | msleep(lis3->pwron_delay / lis3lv02d_get_odr()); | 405 | if (err) |
406 | return err; | ||
389 | 407 | ||
390 | if (lis3->reg_ctrl) | 408 | if (lis3->reg_ctrl) |
391 | lis3_context_restore(lis3); | 409 | lis3_context_restore(lis3); |
410 | |||
411 | return 0; | ||
392 | } | 412 | } |
393 | EXPORT_SYMBOL_GPL(lis3lv02d_poweron); | 413 | EXPORT_SYMBOL_GPL(lis3lv02d_poweron); |
394 | 414 | ||
395 | 415 | ||
396 | static void lis3lv02d_joystick_poll(struct input_polled_dev *pidev) | 416 | static void lis3lv02d_joystick_poll(struct input_polled_dev *pidev) |
397 | { | 417 | { |
418 | struct lis3lv02d *lis3 = pidev->private; | ||
398 | int x, y, z; | 419 | int x, y, z; |
399 | 420 | ||
400 | mutex_lock(&lis3_dev.mutex); | 421 | mutex_lock(&lis3->mutex); |
401 | lis3lv02d_get_xyz(&lis3_dev, &x, &y, &z); | 422 | lis3lv02d_get_xyz(lis3, &x, &y, &z); |
402 | input_report_abs(pidev->input, ABS_X, x); | 423 | input_report_abs(pidev->input, ABS_X, x); |
403 | input_report_abs(pidev->input, ABS_Y, y); | 424 | input_report_abs(pidev->input, ABS_Y, y); |
404 | input_report_abs(pidev->input, ABS_Z, z); | 425 | input_report_abs(pidev->input, ABS_Z, z); |
405 | input_sync(pidev->input); | 426 | input_sync(pidev->input); |
406 | mutex_unlock(&lis3_dev.mutex); | 427 | mutex_unlock(&lis3->mutex); |
407 | } | 428 | } |
408 | 429 | ||
409 | static void lis3lv02d_joystick_open(struct input_polled_dev *pidev) | 430 | static void lis3lv02d_joystick_open(struct input_polled_dev *pidev) |
410 | { | 431 | { |
411 | if (lis3_dev.pm_dev) | 432 | struct lis3lv02d *lis3 = pidev->private; |
412 | pm_runtime_get_sync(lis3_dev.pm_dev); | ||
413 | 433 | ||
414 | if (lis3_dev.pdata && lis3_dev.whoami == WAI_8B && lis3_dev.idev) | 434 | if (lis3->pm_dev) |
415 | atomic_set(&lis3_dev.wake_thread, 1); | 435 | pm_runtime_get_sync(lis3->pm_dev); |
436 | |||
437 | if (lis3->pdata && lis3->whoami == WAI_8B && lis3->idev) | ||
438 | atomic_set(&lis3->wake_thread, 1); | ||
416 | /* | 439 | /* |
417 | * Update coordinates for the case where poll interval is 0 and | 440 | * Update coordinates for the case where poll interval is 0 and |
418 | * the chip in running purely under interrupt control | 441 | * the chip in running purely under interrupt control |
@@ -422,14 +445,18 @@ static void lis3lv02d_joystick_open(struct input_polled_dev *pidev) | |||
422 | 445 | ||
423 | static void lis3lv02d_joystick_close(struct input_polled_dev *pidev) | 446 | static void lis3lv02d_joystick_close(struct input_polled_dev *pidev) |
424 | { | 447 | { |
425 | atomic_set(&lis3_dev.wake_thread, 0); | 448 | struct lis3lv02d *lis3 = pidev->private; |
426 | if (lis3_dev.pm_dev) | 449 | |
427 | pm_runtime_put(lis3_dev.pm_dev); | 450 | atomic_set(&lis3->wake_thread, 0); |
451 | if (lis3->pm_dev) | ||
452 | pm_runtime_put(lis3->pm_dev); | ||
428 | } | 453 | } |
429 | 454 | ||
430 | static irqreturn_t lis302dl_interrupt(int irq, void *dummy) | 455 | static irqreturn_t lis302dl_interrupt(int irq, void *data) |
431 | { | 456 | { |
432 | if (!test_bit(0, &lis3_dev.misc_opened)) | 457 | struct lis3lv02d *lis3 = data; |
458 | |||
459 | if (!test_bit(0, &lis3->misc_opened)) | ||
433 | goto out; | 460 | goto out; |
434 | 461 | ||
435 | /* | 462 | /* |
@@ -437,12 +464,12 @@ static irqreturn_t lis302dl_interrupt(int irq, void *dummy) | |||
437 | * the lid is closed. This leads to interrupts as soon as a little move | 464 | * the lid is closed. This leads to interrupts as soon as a little move |
438 | * is done. | 465 | * is done. |
439 | */ | 466 | */ |
440 | atomic_inc(&lis3_dev.count); | 467 | atomic_inc(&lis3->count); |
441 | 468 | ||
442 | wake_up_interruptible(&lis3_dev.misc_wait); | 469 | wake_up_interruptible(&lis3->misc_wait); |
443 | kill_fasync(&lis3_dev.async_queue, SIGIO, POLL_IN); | 470 | kill_fasync(&lis3->async_queue, SIGIO, POLL_IN); |
444 | out: | 471 | out: |
445 | if (atomic_read(&lis3_dev.wake_thread)) | 472 | if (atomic_read(&lis3->wake_thread)) |
446 | return IRQ_WAKE_THREAD; | 473 | return IRQ_WAKE_THREAD; |
447 | return IRQ_HANDLED; | 474 | return IRQ_HANDLED; |
448 | } | 475 | } |
@@ -514,28 +541,37 @@ static irqreturn_t lis302dl_interrupt_thread2_8b(int irq, void *data) | |||
514 | 541 | ||
515 | static int lis3lv02d_misc_open(struct inode *inode, struct file *file) | 542 | static int lis3lv02d_misc_open(struct inode *inode, struct file *file) |
516 | { | 543 | { |
517 | if (test_and_set_bit(0, &lis3_dev.misc_opened)) | 544 | struct lis3lv02d *lis3 = container_of(file->private_data, |
545 | struct lis3lv02d, miscdev); | ||
546 | |||
547 | if (test_and_set_bit(0, &lis3->misc_opened)) | ||
518 | return -EBUSY; /* already open */ | 548 | return -EBUSY; /* already open */ |
519 | 549 | ||
520 | if (lis3_dev.pm_dev) | 550 | if (lis3->pm_dev) |
521 | pm_runtime_get_sync(lis3_dev.pm_dev); | 551 | pm_runtime_get_sync(lis3->pm_dev); |
522 | 552 | ||
523 | atomic_set(&lis3_dev.count, 0); | 553 | atomic_set(&lis3->count, 0); |
524 | return 0; | 554 | return 0; |
525 | } | 555 | } |
526 | 556 | ||
527 | static int lis3lv02d_misc_release(struct inode *inode, struct file *file) | 557 | static int lis3lv02d_misc_release(struct inode *inode, struct file *file) |
528 | { | 558 | { |
529 | fasync_helper(-1, file, 0, &lis3_dev.async_queue); | 559 | struct lis3lv02d *lis3 = container_of(file->private_data, |
530 | clear_bit(0, &lis3_dev.misc_opened); /* release the device */ | 560 | struct lis3lv02d, miscdev); |
531 | if (lis3_dev.pm_dev) | 561 | |
532 | pm_runtime_put(lis3_dev.pm_dev); | 562 | fasync_helper(-1, file, 0, &lis3->async_queue); |
563 | clear_bit(0, &lis3->misc_opened); /* release the device */ | ||
564 | if (lis3->pm_dev) | ||
565 | pm_runtime_put(lis3->pm_dev); | ||
533 | return 0; | 566 | return 0; |
534 | } | 567 | } |
535 | 568 | ||
536 | static ssize_t lis3lv02d_misc_read(struct file *file, char __user *buf, | 569 | static ssize_t lis3lv02d_misc_read(struct file *file, char __user *buf, |
537 | size_t count, loff_t *pos) | 570 | size_t count, loff_t *pos) |
538 | { | 571 | { |
572 | struct lis3lv02d *lis3 = container_of(file->private_data, | ||
573 | struct lis3lv02d, miscdev); | ||
574 | |||
539 | DECLARE_WAITQUEUE(wait, current); | 575 | DECLARE_WAITQUEUE(wait, current); |
540 | u32 data; | 576 | u32 data; |
541 | unsigned char byte_data; | 577 | unsigned char byte_data; |
@@ -544,10 +580,10 @@ static ssize_t lis3lv02d_misc_read(struct file *file, char __user *buf, | |||
544 | if (count < 1) | 580 | if (count < 1) |
545 | return -EINVAL; | 581 | return -EINVAL; |
546 | 582 | ||
547 | add_wait_queue(&lis3_dev.misc_wait, &wait); | 583 | add_wait_queue(&lis3->misc_wait, &wait); |
548 | while (true) { | 584 | while (true) { |
549 | set_current_state(TASK_INTERRUPTIBLE); | 585 | set_current_state(TASK_INTERRUPTIBLE); |
550 | data = atomic_xchg(&lis3_dev.count, 0); | 586 | data = atomic_xchg(&lis3->count, 0); |
551 | if (data) | 587 | if (data) |
552 | break; | 588 | break; |
553 | 589 | ||
@@ -577,22 +613,28 @@ static ssize_t lis3lv02d_misc_read(struct file *file, char __user *buf, | |||
577 | 613 | ||
578 | out: | 614 | out: |
579 | __set_current_state(TASK_RUNNING); | 615 | __set_current_state(TASK_RUNNING); |
580 | remove_wait_queue(&lis3_dev.misc_wait, &wait); | 616 | remove_wait_queue(&lis3->misc_wait, &wait); |
581 | 617 | ||
582 | return retval; | 618 | return retval; |
583 | } | 619 | } |
584 | 620 | ||
585 | static unsigned int lis3lv02d_misc_poll(struct file *file, poll_table *wait) | 621 | static unsigned int lis3lv02d_misc_poll(struct file *file, poll_table *wait) |
586 | { | 622 | { |
587 | poll_wait(file, &lis3_dev.misc_wait, wait); | 623 | struct lis3lv02d *lis3 = container_of(file->private_data, |
588 | if (atomic_read(&lis3_dev.count)) | 624 | struct lis3lv02d, miscdev); |
625 | |||
626 | poll_wait(file, &lis3->misc_wait, wait); | ||
627 | if (atomic_read(&lis3->count)) | ||
589 | return POLLIN | POLLRDNORM; | 628 | return POLLIN | POLLRDNORM; |
590 | return 0; | 629 | return 0; |
591 | } | 630 | } |
592 | 631 | ||
593 | static int lis3lv02d_misc_fasync(int fd, struct file *file, int on) | 632 | static int lis3lv02d_misc_fasync(int fd, struct file *file, int on) |
594 | { | 633 | { |
595 | return fasync_helper(fd, file, on, &lis3_dev.async_queue); | 634 | struct lis3lv02d *lis3 = container_of(file->private_data, |
635 | struct lis3lv02d, miscdev); | ||
636 | |||
637 | return fasync_helper(fd, file, on, &lis3->async_queue); | ||
596 | } | 638 | } |
597 | 639 | ||
598 | static const struct file_operations lis3lv02d_misc_fops = { | 640 | static const struct file_operations lis3lv02d_misc_fops = { |
@@ -605,85 +647,80 @@ static const struct file_operations lis3lv02d_misc_fops = { | |||
605 | .fasync = lis3lv02d_misc_fasync, | 647 | .fasync = lis3lv02d_misc_fasync, |
606 | }; | 648 | }; |
607 | 649 | ||
608 | static struct miscdevice lis3lv02d_misc_device = { | 650 | int lis3lv02d_joystick_enable(struct lis3lv02d *lis3) |
609 | .minor = MISC_DYNAMIC_MINOR, | ||
610 | .name = "freefall", | ||
611 | .fops = &lis3lv02d_misc_fops, | ||
612 | }; | ||
613 | |||
614 | int lis3lv02d_joystick_enable(void) | ||
615 | { | 651 | { |
616 | struct input_dev *input_dev; | 652 | struct input_dev *input_dev; |
617 | int err; | 653 | int err; |
618 | int max_val, fuzz, flat; | 654 | int max_val, fuzz, flat; |
619 | int btns[] = {BTN_X, BTN_Y, BTN_Z}; | 655 | int btns[] = {BTN_X, BTN_Y, BTN_Z}; |
620 | 656 | ||
621 | if (lis3_dev.idev) | 657 | if (lis3->idev) |
622 | return -EINVAL; | 658 | return -EINVAL; |
623 | 659 | ||
624 | lis3_dev.idev = input_allocate_polled_device(); | 660 | lis3->idev = input_allocate_polled_device(); |
625 | if (!lis3_dev.idev) | 661 | if (!lis3->idev) |
626 | return -ENOMEM; | 662 | return -ENOMEM; |
627 | 663 | ||
628 | lis3_dev.idev->poll = lis3lv02d_joystick_poll; | 664 | lis3->idev->poll = lis3lv02d_joystick_poll; |
629 | lis3_dev.idev->open = lis3lv02d_joystick_open; | 665 | lis3->idev->open = lis3lv02d_joystick_open; |
630 | lis3_dev.idev->close = lis3lv02d_joystick_close; | 666 | lis3->idev->close = lis3lv02d_joystick_close; |
631 | lis3_dev.idev->poll_interval = MDPS_POLL_INTERVAL; | 667 | lis3->idev->poll_interval = MDPS_POLL_INTERVAL; |
632 | lis3_dev.idev->poll_interval_min = MDPS_POLL_MIN; | 668 | lis3->idev->poll_interval_min = MDPS_POLL_MIN; |
633 | lis3_dev.idev->poll_interval_max = MDPS_POLL_MAX; | 669 | lis3->idev->poll_interval_max = MDPS_POLL_MAX; |
634 | input_dev = lis3_dev.idev->input; | 670 | lis3->idev->private = lis3; |
671 | input_dev = lis3->idev->input; | ||
635 | 672 | ||
636 | input_dev->name = "ST LIS3LV02DL Accelerometer"; | 673 | input_dev->name = "ST LIS3LV02DL Accelerometer"; |
637 | input_dev->phys = DRIVER_NAME "/input0"; | 674 | input_dev->phys = DRIVER_NAME "/input0"; |
638 | input_dev->id.bustype = BUS_HOST; | 675 | input_dev->id.bustype = BUS_HOST; |
639 | input_dev->id.vendor = 0; | 676 | input_dev->id.vendor = 0; |
640 | input_dev->dev.parent = &lis3_dev.pdev->dev; | 677 | input_dev->dev.parent = &lis3->pdev->dev; |
641 | 678 | ||
642 | set_bit(EV_ABS, input_dev->evbit); | 679 | set_bit(EV_ABS, input_dev->evbit); |
643 | max_val = (lis3_dev.mdps_max_val * lis3_dev.scale) / LIS3_ACCURACY; | 680 | max_val = (lis3->mdps_max_val * lis3->scale) / LIS3_ACCURACY; |
644 | if (lis3_dev.whoami == WAI_12B) { | 681 | if (lis3->whoami == WAI_12B) { |
645 | fuzz = LIS3_DEFAULT_FUZZ_12B; | 682 | fuzz = LIS3_DEFAULT_FUZZ_12B; |
646 | flat = LIS3_DEFAULT_FLAT_12B; | 683 | flat = LIS3_DEFAULT_FLAT_12B; |
647 | } else { | 684 | } else { |
648 | fuzz = LIS3_DEFAULT_FUZZ_8B; | 685 | fuzz = LIS3_DEFAULT_FUZZ_8B; |
649 | flat = LIS3_DEFAULT_FLAT_8B; | 686 | flat = LIS3_DEFAULT_FLAT_8B; |
650 | } | 687 | } |
651 | fuzz = (fuzz * lis3_dev.scale) / LIS3_ACCURACY; | 688 | fuzz = (fuzz * lis3->scale) / LIS3_ACCURACY; |
652 | flat = (flat * lis3_dev.scale) / LIS3_ACCURACY; | 689 | flat = (flat * lis3->scale) / LIS3_ACCURACY; |
653 | 690 | ||
654 | input_set_abs_params(input_dev, ABS_X, -max_val, max_val, fuzz, flat); | 691 | input_set_abs_params(input_dev, ABS_X, -max_val, max_val, fuzz, flat); |
655 | input_set_abs_params(input_dev, ABS_Y, -max_val, max_val, fuzz, flat); | 692 | input_set_abs_params(input_dev, ABS_Y, -max_val, max_val, fuzz, flat); |
656 | input_set_abs_params(input_dev, ABS_Z, -max_val, max_val, fuzz, flat); | 693 | input_set_abs_params(input_dev, ABS_Z, -max_val, max_val, fuzz, flat); |
657 | 694 | ||
658 | lis3_dev.mapped_btns[0] = lis3lv02d_get_axis(abs(lis3_dev.ac.x), btns); | 695 | lis3->mapped_btns[0] = lis3lv02d_get_axis(abs(lis3->ac.x), btns); |
659 | lis3_dev.mapped_btns[1] = lis3lv02d_get_axis(abs(lis3_dev.ac.y), btns); | 696 | lis3->mapped_btns[1] = lis3lv02d_get_axis(abs(lis3->ac.y), btns); |
660 | lis3_dev.mapped_btns[2] = lis3lv02d_get_axis(abs(lis3_dev.ac.z), btns); | 697 | lis3->mapped_btns[2] = lis3lv02d_get_axis(abs(lis3->ac.z), btns); |
661 | 698 | ||
662 | err = input_register_polled_device(lis3_dev.idev); | 699 | err = input_register_polled_device(lis3->idev); |
663 | if (err) { | 700 | if (err) { |
664 | input_free_polled_device(lis3_dev.idev); | 701 | input_free_polled_device(lis3->idev); |
665 | lis3_dev.idev = NULL; | 702 | lis3->idev = NULL; |
666 | } | 703 | } |
667 | 704 | ||
668 | return err; | 705 | return err; |
669 | } | 706 | } |
670 | EXPORT_SYMBOL_GPL(lis3lv02d_joystick_enable); | 707 | EXPORT_SYMBOL_GPL(lis3lv02d_joystick_enable); |
671 | 708 | ||
672 | void lis3lv02d_joystick_disable(void) | 709 | void lis3lv02d_joystick_disable(struct lis3lv02d *lis3) |
673 | { | 710 | { |
674 | if (lis3_dev.irq) | 711 | if (lis3->irq) |
675 | free_irq(lis3_dev.irq, &lis3_dev); | 712 | free_irq(lis3->irq, lis3); |
676 | if (lis3_dev.pdata && lis3_dev.pdata->irq2) | 713 | if (lis3->pdata && lis3->pdata->irq2) |
677 | free_irq(lis3_dev.pdata->irq2, &lis3_dev); | 714 | free_irq(lis3->pdata->irq2, lis3); |
678 | 715 | ||
679 | if (!lis3_dev.idev) | 716 | if (!lis3->idev) |
680 | return; | 717 | return; |
681 | 718 | ||
682 | if (lis3_dev.irq) | 719 | if (lis3->irq) |
683 | misc_deregister(&lis3lv02d_misc_device); | 720 | misc_deregister(&lis3->miscdev); |
684 | input_unregister_polled_device(lis3_dev.idev); | 721 | input_unregister_polled_device(lis3->idev); |
685 | input_free_polled_device(lis3_dev.idev); | 722 | input_free_polled_device(lis3->idev); |
686 | lis3_dev.idev = NULL; | 723 | lis3->idev = NULL; |
687 | } | 724 | } |
688 | EXPORT_SYMBOL_GPL(lis3lv02d_joystick_disable); | 725 | EXPORT_SYMBOL_GPL(lis3lv02d_joystick_disable); |
689 | 726 | ||
@@ -708,6 +745,7 @@ static void lis3lv02d_sysfs_poweron(struct lis3lv02d *lis3) | |||
708 | static ssize_t lis3lv02d_selftest_show(struct device *dev, | 745 | static ssize_t lis3lv02d_selftest_show(struct device *dev, |
709 | struct device_attribute *attr, char *buf) | 746 | struct device_attribute *attr, char *buf) |
710 | { | 747 | { |
748 | struct lis3lv02d *lis3 = dev_get_drvdata(dev); | ||
711 | s16 values[3]; | 749 | s16 values[3]; |
712 | 750 | ||
713 | static const char ok[] = "OK"; | 751 | static const char ok[] = "OK"; |
@@ -715,8 +753,8 @@ static ssize_t lis3lv02d_selftest_show(struct device *dev, | |||
715 | static const char irq[] = "FAIL_IRQ"; | 753 | static const char irq[] = "FAIL_IRQ"; |
716 | const char *res; | 754 | const char *res; |
717 | 755 | ||
718 | lis3lv02d_sysfs_poweron(&lis3_dev); | 756 | lis3lv02d_sysfs_poweron(lis3); |
719 | switch (lis3lv02d_selftest(&lis3_dev, values)) { | 757 | switch (lis3lv02d_selftest(lis3, values)) { |
720 | case SELFTEST_FAIL: | 758 | case SELFTEST_FAIL: |
721 | res = fail; | 759 | res = fail; |
722 | break; | 760 | break; |
@@ -735,33 +773,37 @@ static ssize_t lis3lv02d_selftest_show(struct device *dev, | |||
735 | static ssize_t lis3lv02d_position_show(struct device *dev, | 773 | static ssize_t lis3lv02d_position_show(struct device *dev, |
736 | struct device_attribute *attr, char *buf) | 774 | struct device_attribute *attr, char *buf) |
737 | { | 775 | { |
776 | struct lis3lv02d *lis3 = dev_get_drvdata(dev); | ||
738 | int x, y, z; | 777 | int x, y, z; |
739 | 778 | ||
740 | lis3lv02d_sysfs_poweron(&lis3_dev); | 779 | lis3lv02d_sysfs_poweron(lis3); |
741 | mutex_lock(&lis3_dev.mutex); | 780 | mutex_lock(&lis3->mutex); |
742 | lis3lv02d_get_xyz(&lis3_dev, &x, &y, &z); | 781 | lis3lv02d_get_xyz(lis3, &x, &y, &z); |
743 | mutex_unlock(&lis3_dev.mutex); | 782 | mutex_unlock(&lis3->mutex); |
744 | return sprintf(buf, "(%d,%d,%d)\n", x, y, z); | 783 | return sprintf(buf, "(%d,%d,%d)\n", x, y, z); |
745 | } | 784 | } |
746 | 785 | ||
747 | static ssize_t lis3lv02d_rate_show(struct device *dev, | 786 | static ssize_t lis3lv02d_rate_show(struct device *dev, |
748 | struct device_attribute *attr, char *buf) | 787 | struct device_attribute *attr, char *buf) |
749 | { | 788 | { |
750 | lis3lv02d_sysfs_poweron(&lis3_dev); | 789 | struct lis3lv02d *lis3 = dev_get_drvdata(dev); |
751 | return sprintf(buf, "%d\n", lis3lv02d_get_odr()); | 790 | |
791 | lis3lv02d_sysfs_poweron(lis3); | ||
792 | return sprintf(buf, "%d\n", lis3lv02d_get_odr(lis3)); | ||
752 | } | 793 | } |
753 | 794 | ||
754 | static ssize_t lis3lv02d_rate_set(struct device *dev, | 795 | static ssize_t lis3lv02d_rate_set(struct device *dev, |
755 | struct device_attribute *attr, const char *buf, | 796 | struct device_attribute *attr, const char *buf, |
756 | size_t count) | 797 | size_t count) |
757 | { | 798 | { |
799 | struct lis3lv02d *lis3 = dev_get_drvdata(dev); | ||
758 | unsigned long rate; | 800 | unsigned long rate; |
759 | 801 | ||
760 | if (strict_strtoul(buf, 0, &rate)) | 802 | if (strict_strtoul(buf, 0, &rate)) |
761 | return -EINVAL; | 803 | return -EINVAL; |
762 | 804 | ||
763 | lis3lv02d_sysfs_poweron(&lis3_dev); | 805 | lis3lv02d_sysfs_poweron(lis3); |
764 | if (lis3lv02d_set_odr(rate)) | 806 | if (lis3lv02d_set_odr(lis3, rate)) |
765 | return -EINVAL; | 807 | return -EINVAL; |
766 | 808 | ||
767 | return count; | 809 | return count; |
@@ -790,6 +832,7 @@ static int lis3lv02d_add_fs(struct lis3lv02d *lis3) | |||
790 | if (IS_ERR(lis3->pdev)) | 832 | if (IS_ERR(lis3->pdev)) |
791 | return PTR_ERR(lis3->pdev); | 833 | return PTR_ERR(lis3->pdev); |
792 | 834 | ||
835 | platform_set_drvdata(lis3->pdev, lis3); | ||
793 | return sysfs_create_group(&lis3->pdev->dev.kobj, &lis3lv02d_attribute_group); | 836 | return sysfs_create_group(&lis3->pdev->dev.kobj, &lis3lv02d_attribute_group); |
794 | } | 837 | } |
795 | 838 | ||
@@ -803,7 +846,7 @@ int lis3lv02d_remove_fs(struct lis3lv02d *lis3) | |||
803 | 846 | ||
804 | /* SYSFS may have left chip running. Turn off if necessary */ | 847 | /* SYSFS may have left chip running. Turn off if necessary */ |
805 | if (!pm_runtime_suspended(lis3->pm_dev)) | 848 | if (!pm_runtime_suspended(lis3->pm_dev)) |
806 | lis3lv02d_poweroff(&lis3_dev); | 849 | lis3lv02d_poweroff(lis3); |
807 | 850 | ||
808 | pm_runtime_disable(lis3->pm_dev); | 851 | pm_runtime_disable(lis3->pm_dev); |
809 | pm_runtime_set_suspended(lis3->pm_dev); | 852 | pm_runtime_set_suspended(lis3->pm_dev); |
@@ -813,24 +856,24 @@ int lis3lv02d_remove_fs(struct lis3lv02d *lis3) | |||
813 | } | 856 | } |
814 | EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs); | 857 | EXPORT_SYMBOL_GPL(lis3lv02d_remove_fs); |
815 | 858 | ||
816 | static void lis3lv02d_8b_configure(struct lis3lv02d *dev, | 859 | static void lis3lv02d_8b_configure(struct lis3lv02d *lis3, |
817 | struct lis3lv02d_platform_data *p) | 860 | struct lis3lv02d_platform_data *p) |
818 | { | 861 | { |
819 | int err; | 862 | int err; |
820 | int ctrl2 = p->hipass_ctrl; | 863 | int ctrl2 = p->hipass_ctrl; |
821 | 864 | ||
822 | if (p->click_flags) { | 865 | if (p->click_flags) { |
823 | dev->write(dev, CLICK_CFG, p->click_flags); | 866 | lis3->write(lis3, CLICK_CFG, p->click_flags); |
824 | dev->write(dev, CLICK_TIMELIMIT, p->click_time_limit); | 867 | lis3->write(lis3, CLICK_TIMELIMIT, p->click_time_limit); |
825 | dev->write(dev, CLICK_LATENCY, p->click_latency); | 868 | lis3->write(lis3, CLICK_LATENCY, p->click_latency); |
826 | dev->write(dev, CLICK_WINDOW, p->click_window); | 869 | lis3->write(lis3, CLICK_WINDOW, p->click_window); |
827 | dev->write(dev, CLICK_THSZ, p->click_thresh_z & 0xf); | 870 | lis3->write(lis3, CLICK_THSZ, p->click_thresh_z & 0xf); |
828 | dev->write(dev, CLICK_THSY_X, | 871 | lis3->write(lis3, CLICK_THSY_X, |
829 | (p->click_thresh_x & 0xf) | | 872 | (p->click_thresh_x & 0xf) | |
830 | (p->click_thresh_y << 4)); | 873 | (p->click_thresh_y << 4)); |
831 | 874 | ||
832 | if (dev->idev) { | 875 | if (lis3->idev) { |
833 | struct input_dev *input_dev = lis3_dev.idev->input; | 876 | struct input_dev *input_dev = lis3->idev->input; |
834 | input_set_capability(input_dev, EV_KEY, BTN_X); | 877 | input_set_capability(input_dev, EV_KEY, BTN_X); |
835 | input_set_capability(input_dev, EV_KEY, BTN_Y); | 878 | input_set_capability(input_dev, EV_KEY, BTN_Y); |
836 | input_set_capability(input_dev, EV_KEY, BTN_Z); | 879 | input_set_capability(input_dev, EV_KEY, BTN_Z); |
@@ -838,22 +881,22 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *dev, | |||
838 | } | 881 | } |
839 | 882 | ||
840 | if (p->wakeup_flags) { | 883 | if (p->wakeup_flags) { |
841 | dev->write(dev, FF_WU_CFG_1, p->wakeup_flags); | 884 | lis3->write(lis3, FF_WU_CFG_1, p->wakeup_flags); |
842 | dev->write(dev, FF_WU_THS_1, p->wakeup_thresh & 0x7f); | 885 | lis3->write(lis3, FF_WU_THS_1, p->wakeup_thresh & 0x7f); |
843 | /* pdata value + 1 to keep this backward compatible*/ | 886 | /* pdata value + 1 to keep this backward compatible*/ |
844 | dev->write(dev, FF_WU_DURATION_1, p->duration1 + 1); | 887 | lis3->write(lis3, FF_WU_DURATION_1, p->duration1 + 1); |
845 | ctrl2 ^= HP_FF_WU1; /* Xor to keep compatible with old pdata*/ | 888 | ctrl2 ^= HP_FF_WU1; /* Xor to keep compatible with old pdata*/ |
846 | } | 889 | } |
847 | 890 | ||
848 | if (p->wakeup_flags2) { | 891 | if (p->wakeup_flags2) { |
849 | dev->write(dev, FF_WU_CFG_2, p->wakeup_flags2); | 892 | lis3->write(lis3, FF_WU_CFG_2, p->wakeup_flags2); |
850 | dev->write(dev, FF_WU_THS_2, p->wakeup_thresh2 & 0x7f); | 893 | lis3->write(lis3, FF_WU_THS_2, p->wakeup_thresh2 & 0x7f); |
851 | /* pdata value + 1 to keep this backward compatible*/ | 894 | /* pdata value + 1 to keep this backward compatible*/ |
852 | dev->write(dev, FF_WU_DURATION_2, p->duration2 + 1); | 895 | lis3->write(lis3, FF_WU_DURATION_2, p->duration2 + 1); |
853 | ctrl2 ^= HP_FF_WU2; /* Xor to keep compatible with old pdata*/ | 896 | ctrl2 ^= HP_FF_WU2; /* Xor to keep compatible with old pdata*/ |
854 | } | 897 | } |
855 | /* Configure hipass filters */ | 898 | /* Configure hipass filters */ |
856 | dev->write(dev, CTRL_REG2, ctrl2); | 899 | lis3->write(lis3, CTRL_REG2, ctrl2); |
857 | 900 | ||
858 | if (p->irq2) { | 901 | if (p->irq2) { |
859 | err = request_threaded_irq(p->irq2, | 902 | err = request_threaded_irq(p->irq2, |
@@ -861,7 +904,7 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *dev, | |||
861 | lis302dl_interrupt_thread2_8b, | 904 | lis302dl_interrupt_thread2_8b, |
862 | IRQF_TRIGGER_RISING | IRQF_ONESHOT | | 905 | IRQF_TRIGGER_RISING | IRQF_ONESHOT | |
863 | (p->irq_flags2 & IRQF_TRIGGER_MASK), | 906 | (p->irq_flags2 & IRQF_TRIGGER_MASK), |
864 | DRIVER_NAME, &lis3_dev); | 907 | DRIVER_NAME, lis3); |
865 | if (err < 0) | 908 | if (err < 0) |
866 | pr_err("No second IRQ. Limited functionality\n"); | 909 | pr_err("No second IRQ. Limited functionality\n"); |
867 | } | 910 | } |
@@ -871,93 +914,97 @@ static void lis3lv02d_8b_configure(struct lis3lv02d *dev, | |||
871 | * Initialise the accelerometer and the various subsystems. | 914 | * Initialise the accelerometer and the various subsystems. |
872 | * Should be rather independent of the bus system. | 915 | * Should be rather independent of the bus system. |
873 | */ | 916 | */ |
874 | int lis3lv02d_init_device(struct lis3lv02d *dev) | 917 | int lis3lv02d_init_device(struct lis3lv02d *lis3) |
875 | { | 918 | { |
876 | int err; | 919 | int err; |
877 | irq_handler_t thread_fn; | 920 | irq_handler_t thread_fn; |
878 | int irq_flags = 0; | 921 | int irq_flags = 0; |
879 | 922 | ||
880 | dev->whoami = lis3lv02d_read_8(dev, WHO_AM_I); | 923 | lis3->whoami = lis3lv02d_read_8(lis3, WHO_AM_I); |
881 | 924 | ||
882 | switch (dev->whoami) { | 925 | switch (lis3->whoami) { |
883 | case WAI_12B: | 926 | case WAI_12B: |
884 | pr_info("12 bits sensor found\n"); | 927 | pr_info("12 bits sensor found\n"); |
885 | dev->read_data = lis3lv02d_read_12; | 928 | lis3->read_data = lis3lv02d_read_12; |
886 | dev->mdps_max_val = 2048; | 929 | lis3->mdps_max_val = 2048; |
887 | dev->pwron_delay = LIS3_PWRON_DELAY_WAI_12B; | 930 | lis3->pwron_delay = LIS3_PWRON_DELAY_WAI_12B; |
888 | dev->odrs = lis3_12_rates; | 931 | lis3->odrs = lis3_12_rates; |
889 | dev->odr_mask = CTRL1_DF0 | CTRL1_DF1; | 932 | lis3->odr_mask = CTRL1_DF0 | CTRL1_DF1; |
890 | dev->scale = LIS3_SENSITIVITY_12B; | 933 | lis3->scale = LIS3_SENSITIVITY_12B; |
891 | dev->regs = lis3_wai12_regs; | 934 | lis3->regs = lis3_wai12_regs; |
892 | dev->regs_size = ARRAY_SIZE(lis3_wai12_regs); | 935 | lis3->regs_size = ARRAY_SIZE(lis3_wai12_regs); |
893 | break; | 936 | break; |
894 | case WAI_8B: | 937 | case WAI_8B: |
895 | pr_info("8 bits sensor found\n"); | 938 | pr_info("8 bits sensor found\n"); |
896 | dev->read_data = lis3lv02d_read_8; | 939 | lis3->read_data = lis3lv02d_read_8; |
897 | dev->mdps_max_val = 128; | 940 | lis3->mdps_max_val = 128; |
898 | dev->pwron_delay = LIS3_PWRON_DELAY_WAI_8B; | 941 | lis3->pwron_delay = LIS3_PWRON_DELAY_WAI_8B; |
899 | dev->odrs = lis3_8_rates; | 942 | lis3->odrs = lis3_8_rates; |
900 | dev->odr_mask = CTRL1_DR; | 943 | lis3->odr_mask = CTRL1_DR; |
901 | dev->scale = LIS3_SENSITIVITY_8B; | 944 | lis3->scale = LIS3_SENSITIVITY_8B; |
902 | dev->regs = lis3_wai8_regs; | 945 | lis3->regs = lis3_wai8_regs; |
903 | dev->regs_size = ARRAY_SIZE(lis3_wai8_regs); | 946 | lis3->regs_size = ARRAY_SIZE(lis3_wai8_regs); |
904 | break; | 947 | break; |
905 | case WAI_3DC: | 948 | case WAI_3DC: |
906 | pr_info("8 bits 3DC sensor found\n"); | 949 | pr_info("8 bits 3DC sensor found\n"); |
907 | dev->read_data = lis3lv02d_read_8; | 950 | lis3->read_data = lis3lv02d_read_8; |
908 | dev->mdps_max_val = 128; | 951 | lis3->mdps_max_val = 128; |
909 | dev->pwron_delay = LIS3_PWRON_DELAY_WAI_8B; | 952 | lis3->pwron_delay = LIS3_PWRON_DELAY_WAI_8B; |
910 | dev->odrs = lis3_3dc_rates; | 953 | lis3->odrs = lis3_3dc_rates; |
911 | dev->odr_mask = CTRL1_ODR0|CTRL1_ODR1|CTRL1_ODR2|CTRL1_ODR3; | 954 | lis3->odr_mask = CTRL1_ODR0|CTRL1_ODR1|CTRL1_ODR2|CTRL1_ODR3; |
912 | dev->scale = LIS3_SENSITIVITY_8B; | 955 | lis3->scale = LIS3_SENSITIVITY_8B; |
913 | break; | 956 | break; |
914 | default: | 957 | default: |
915 | pr_err("unknown sensor type 0x%X\n", dev->whoami); | 958 | pr_err("unknown sensor type 0x%X\n", lis3->whoami); |
916 | return -EINVAL; | 959 | return -EINVAL; |
917 | } | 960 | } |
918 | 961 | ||
919 | dev->reg_cache = kzalloc(max(sizeof(lis3_wai8_regs), | 962 | lis3->reg_cache = kzalloc(max(sizeof(lis3_wai8_regs), |
920 | sizeof(lis3_wai12_regs)), GFP_KERNEL); | 963 | sizeof(lis3_wai12_regs)), GFP_KERNEL); |
921 | 964 | ||
922 | if (dev->reg_cache == NULL) { | 965 | if (lis3->reg_cache == NULL) { |
923 | printk(KERN_ERR DRIVER_NAME "out of memory\n"); | 966 | printk(KERN_ERR DRIVER_NAME "out of memory\n"); |
924 | return -ENOMEM; | 967 | return -ENOMEM; |
925 | } | 968 | } |
926 | 969 | ||
927 | mutex_init(&dev->mutex); | 970 | mutex_init(&lis3->mutex); |
928 | atomic_set(&dev->wake_thread, 0); | 971 | atomic_set(&lis3->wake_thread, 0); |
929 | 972 | ||
930 | lis3lv02d_add_fs(dev); | 973 | lis3lv02d_add_fs(lis3); |
931 | lis3lv02d_poweron(dev); | 974 | err = lis3lv02d_poweron(lis3); |
975 | if (err) { | ||
976 | lis3lv02d_remove_fs(lis3); | ||
977 | return err; | ||
978 | } | ||
932 | 979 | ||
933 | if (dev->pm_dev) { | 980 | if (lis3->pm_dev) { |
934 | pm_runtime_set_active(dev->pm_dev); | 981 | pm_runtime_set_active(lis3->pm_dev); |
935 | pm_runtime_enable(dev->pm_dev); | 982 | pm_runtime_enable(lis3->pm_dev); |
936 | } | 983 | } |
937 | 984 | ||
938 | if (lis3lv02d_joystick_enable()) | 985 | if (lis3lv02d_joystick_enable(lis3)) |
939 | pr_err("joystick initialization failed\n"); | 986 | pr_err("joystick initialization failed\n"); |
940 | 987 | ||
941 | /* passing in platform specific data is purely optional and only | 988 | /* passing in platform specific data is purely optional and only |
942 | * used by the SPI transport layer at the moment */ | 989 | * used by the SPI transport layer at the moment */ |
943 | if (dev->pdata) { | 990 | if (lis3->pdata) { |
944 | struct lis3lv02d_platform_data *p = dev->pdata; | 991 | struct lis3lv02d_platform_data *p = lis3->pdata; |
945 | 992 | ||
946 | if (dev->whoami == WAI_8B) | 993 | if (lis3->whoami == WAI_8B) |
947 | lis3lv02d_8b_configure(dev, p); | 994 | lis3lv02d_8b_configure(lis3, p); |
948 | 995 | ||
949 | irq_flags = p->irq_flags1 & IRQF_TRIGGER_MASK; | 996 | irq_flags = p->irq_flags1 & IRQF_TRIGGER_MASK; |
950 | 997 | ||
951 | dev->irq_cfg = p->irq_cfg; | 998 | lis3->irq_cfg = p->irq_cfg; |
952 | if (p->irq_cfg) | 999 | if (p->irq_cfg) |
953 | dev->write(dev, CTRL_REG3, p->irq_cfg); | 1000 | lis3->write(lis3, CTRL_REG3, p->irq_cfg); |
954 | 1001 | ||
955 | if (p->default_rate) | 1002 | if (p->default_rate) |
956 | lis3lv02d_set_odr(p->default_rate); | 1003 | lis3lv02d_set_odr(lis3, p->default_rate); |
957 | } | 1004 | } |
958 | 1005 | ||
959 | /* bail if we did not get an IRQ from the bus layer */ | 1006 | /* bail if we did not get an IRQ from the bus layer */ |
960 | if (!dev->irq) { | 1007 | if (!lis3->irq) { |
961 | pr_debug("No IRQ. Disabling /dev/freefall\n"); | 1008 | pr_debug("No IRQ. Disabling /dev/freefall\n"); |
962 | goto out; | 1009 | goto out; |
963 | } | 1010 | } |
@@ -973,23 +1020,27 @@ int lis3lv02d_init_device(struct lis3lv02d *dev) | |||
973 | * io-apic is not configurable (and generates a warning) but I keep it | 1020 | * io-apic is not configurable (and generates a warning) but I keep it |
974 | * in case of support for other hardware. | 1021 | * in case of support for other hardware. |
975 | */ | 1022 | */ |
976 | if (dev->pdata && dev->whoami == WAI_8B) | 1023 | if (lis3->pdata && lis3->whoami == WAI_8B) |
977 | thread_fn = lis302dl_interrupt_thread1_8b; | 1024 | thread_fn = lis302dl_interrupt_thread1_8b; |
978 | else | 1025 | else |
979 | thread_fn = NULL; | 1026 | thread_fn = NULL; |
980 | 1027 | ||
981 | err = request_threaded_irq(dev->irq, lis302dl_interrupt, | 1028 | err = request_threaded_irq(lis3->irq, lis302dl_interrupt, |
982 | thread_fn, | 1029 | thread_fn, |
983 | IRQF_TRIGGER_RISING | IRQF_ONESHOT | | 1030 | IRQF_TRIGGER_RISING | IRQF_ONESHOT | |
984 | irq_flags, | 1031 | irq_flags, |
985 | DRIVER_NAME, &lis3_dev); | 1032 | DRIVER_NAME, lis3); |
986 | 1033 | ||
987 | if (err < 0) { | 1034 | if (err < 0) { |
988 | pr_err("Cannot get IRQ\n"); | 1035 | pr_err("Cannot get IRQ\n"); |
989 | goto out; | 1036 | goto out; |
990 | } | 1037 | } |
991 | 1038 | ||
992 | if (misc_register(&lis3lv02d_misc_device)) | 1039 | lis3->miscdev.minor = MISC_DYNAMIC_MINOR; |
1040 | lis3->miscdev.name = "freefall"; | ||
1041 | lis3->miscdev.fops = &lis3lv02d_misc_fops; | ||
1042 | |||
1043 | if (misc_register(&lis3->miscdev)) | ||
993 | pr_err("misc_register failed\n"); | 1044 | pr_err("misc_register failed\n"); |
994 | out: | 1045 | out: |
995 | return 0; | 1046 | return 0; |
diff --git a/drivers/misc/lis3lv02d/lis3lv02d.h b/drivers/misc/lis3lv02d/lis3lv02d.h index a1939589eb2c..2b1482ad3f16 100644 --- a/drivers/misc/lis3lv02d/lis3lv02d.h +++ b/drivers/misc/lis3lv02d/lis3lv02d.h | |||
@@ -21,6 +21,7 @@ | |||
21 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
22 | #include <linux/input-polldev.h> | 22 | #include <linux/input-polldev.h> |
23 | #include <linux/regulator/consumer.h> | 23 | #include <linux/regulator/consumer.h> |
24 | #include <linux/miscdevice.h> | ||
24 | 25 | ||
25 | /* | 26 | /* |
26 | * This driver tries to support the "digital" accelerometer chips from | 27 | * This driver tries to support the "digital" accelerometer chips from |
@@ -273,6 +274,8 @@ struct lis3lv02d { | |||
273 | struct fasync_struct *async_queue; /* queue for the misc device */ | 274 | struct fasync_struct *async_queue; /* queue for the misc device */ |
274 | wait_queue_head_t misc_wait; /* Wait queue for the misc device */ | 275 | wait_queue_head_t misc_wait; /* Wait queue for the misc device */ |
275 | unsigned long misc_opened; /* bit0: whether the device is open */ | 276 | unsigned long misc_opened; /* bit0: whether the device is open */ |
277 | struct miscdevice miscdev; | ||
278 | |||
276 | int data_ready_count[2]; | 279 | int data_ready_count[2]; |
277 | atomic_t wake_thread; | 280 | atomic_t wake_thread; |
278 | unsigned char irq_cfg; | 281 | unsigned char irq_cfg; |
@@ -282,10 +285,10 @@ struct lis3lv02d { | |||
282 | }; | 285 | }; |
283 | 286 | ||
284 | int lis3lv02d_init_device(struct lis3lv02d *lis3); | 287 | int lis3lv02d_init_device(struct lis3lv02d *lis3); |
285 | int lis3lv02d_joystick_enable(void); | 288 | int lis3lv02d_joystick_enable(struct lis3lv02d *lis3); |
286 | void lis3lv02d_joystick_disable(void); | 289 | void lis3lv02d_joystick_disable(struct lis3lv02d *lis3); |
287 | void lis3lv02d_poweroff(struct lis3lv02d *lis3); | 290 | void lis3lv02d_poweroff(struct lis3lv02d *lis3); |
288 | void lis3lv02d_poweron(struct lis3lv02d *lis3); | 291 | int lis3lv02d_poweron(struct lis3lv02d *lis3); |
289 | int lis3lv02d_remove_fs(struct lis3lv02d *lis3); | 292 | int lis3lv02d_remove_fs(struct lis3lv02d *lis3); |
290 | 293 | ||
291 | extern struct lis3lv02d lis3_dev; | 294 | extern struct lis3lv02d lis3_dev; |
diff --git a/drivers/misc/lis3lv02d/lis3lv02d_i2c.c b/drivers/misc/lis3lv02d/lis3lv02d_i2c.c index b20dfb4522d2..c02fea029dcf 100644 --- a/drivers/misc/lis3lv02d/lis3lv02d_i2c.c +++ b/drivers/misc/lis3lv02d/lis3lv02d_i2c.c | |||
@@ -79,8 +79,7 @@ static int lis3_i2c_init(struct lis3lv02d *lis3) | |||
79 | u8 reg; | 79 | u8 reg; |
80 | int ret; | 80 | int ret; |
81 | 81 | ||
82 | if (lis3->reg_ctrl) | 82 | lis3_reg_ctrl(lis3, LIS3_REG_ON); |
83 | lis3_reg_ctrl(lis3, LIS3_REG_ON); | ||
84 | 83 | ||
85 | lis3->read(lis3, WHO_AM_I, ®); | 84 | lis3->read(lis3, WHO_AM_I, ®); |
86 | if (reg != lis3->whoami) | 85 | if (reg != lis3->whoami) |
@@ -106,10 +105,6 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client, | |||
106 | struct lis3lv02d_platform_data *pdata = client->dev.platform_data; | 105 | struct lis3lv02d_platform_data *pdata = client->dev.platform_data; |
107 | 106 | ||
108 | if (pdata) { | 107 | if (pdata) { |
109 | /* Regulator control is optional */ | ||
110 | if (pdata->driver_features & LIS3_USE_REGULATOR_CTRL) | ||
111 | lis3_dev.reg_ctrl = lis3_reg_ctrl; | ||
112 | |||
113 | if ((pdata->driver_features & LIS3_USE_BLOCK_READ) && | 108 | if ((pdata->driver_features & LIS3_USE_BLOCK_READ) && |
114 | (i2c_check_functionality(client->adapter, | 109 | (i2c_check_functionality(client->adapter, |
115 | I2C_FUNC_SMBUS_I2C_BLOCK))) | 110 | I2C_FUNC_SMBUS_I2C_BLOCK))) |
@@ -131,15 +126,13 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client, | |||
131 | goto fail; | 126 | goto fail; |
132 | } | 127 | } |
133 | 128 | ||
134 | if (lis3_dev.reg_ctrl) { | 129 | lis3_dev.regulators[0].supply = reg_vdd; |
135 | lis3_dev.regulators[0].supply = reg_vdd; | 130 | lis3_dev.regulators[1].supply = reg_vdd_io; |
136 | lis3_dev.regulators[1].supply = reg_vdd_io; | 131 | ret = regulator_bulk_get(&client->dev, |
137 | ret = regulator_bulk_get(&client->dev, | 132 | ARRAY_SIZE(lis3_dev.regulators), |
138 | ARRAY_SIZE(lis3_dev.regulators), | 133 | lis3_dev.regulators); |
139 | lis3_dev.regulators); | 134 | if (ret < 0) |
140 | if (ret < 0) | 135 | goto fail; |
141 | goto fail; | ||
142 | } | ||
143 | 136 | ||
144 | lis3_dev.pdata = pdata; | 137 | lis3_dev.pdata = pdata; |
145 | lis3_dev.bus_priv = client; | 138 | lis3_dev.bus_priv = client; |
@@ -153,16 +146,19 @@ static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client, | |||
153 | i2c_set_clientdata(client, &lis3_dev); | 146 | i2c_set_clientdata(client, &lis3_dev); |
154 | 147 | ||
155 | /* Provide power over the init call */ | 148 | /* Provide power over the init call */ |
156 | if (lis3_dev.reg_ctrl) | 149 | lis3_reg_ctrl(&lis3_dev, LIS3_REG_ON); |
157 | lis3_reg_ctrl(&lis3_dev, LIS3_REG_ON); | ||
158 | 150 | ||
159 | ret = lis3lv02d_init_device(&lis3_dev); | 151 | ret = lis3lv02d_init_device(&lis3_dev); |
160 | 152 | ||
161 | if (lis3_dev.reg_ctrl) | 153 | lis3_reg_ctrl(&lis3_dev, LIS3_REG_OFF); |
162 | lis3_reg_ctrl(&lis3_dev, LIS3_REG_OFF); | ||
163 | 154 | ||
164 | if (ret == 0) | 155 | if (ret) |
165 | return 0; | 156 | goto fail2; |
157 | return 0; | ||
158 | |||
159 | fail2: | ||
160 | regulator_bulk_free(ARRAY_SIZE(lis3_dev.regulators), | ||
161 | lis3_dev.regulators); | ||
166 | fail: | 162 | fail: |
167 | if (pdata && pdata->release_resources) | 163 | if (pdata && pdata->release_resources) |
168 | pdata->release_resources(); | 164 | pdata->release_resources(); |
@@ -177,12 +173,11 @@ static int __devexit lis3lv02d_i2c_remove(struct i2c_client *client) | |||
177 | if (pdata && pdata->release_resources) | 173 | if (pdata && pdata->release_resources) |
178 | pdata->release_resources(); | 174 | pdata->release_resources(); |
179 | 175 | ||
180 | lis3lv02d_joystick_disable(); | 176 | lis3lv02d_joystick_disable(lis3); |
181 | lis3lv02d_remove_fs(&lis3_dev); | 177 | lis3lv02d_remove_fs(&lis3_dev); |
182 | 178 | ||
183 | if (lis3_dev.reg_ctrl) | 179 | regulator_bulk_free(ARRAY_SIZE(lis3->regulators), |
184 | regulator_bulk_free(ARRAY_SIZE(lis3->regulators), | 180 | lis3_dev.regulators); |
185 | lis3_dev.regulators); | ||
186 | return 0; | 181 | return 0; |
187 | } | 182 | } |
188 | 183 | ||
diff --git a/drivers/misc/lis3lv02d/lis3lv02d_spi.c b/drivers/misc/lis3lv02d/lis3lv02d_spi.c index c1f8a8fbf694..b2c1be12d16f 100644 --- a/drivers/misc/lis3lv02d/lis3lv02d_spi.c +++ b/drivers/misc/lis3lv02d/lis3lv02d_spi.c | |||
@@ -83,7 +83,7 @@ static int __devinit lis302dl_spi_probe(struct spi_device *spi) | |||
83 | static int __devexit lis302dl_spi_remove(struct spi_device *spi) | 83 | static int __devexit lis302dl_spi_remove(struct spi_device *spi) |
84 | { | 84 | { |
85 | struct lis3lv02d *lis3 = spi_get_drvdata(spi); | 85 | struct lis3lv02d *lis3 = spi_get_drvdata(spi); |
86 | lis3lv02d_joystick_disable(); | 86 | lis3lv02d_joystick_disable(lis3); |
87 | lis3lv02d_poweroff(lis3); | 87 | lis3lv02d_poweroff(lis3); |
88 | 88 | ||
89 | return lis3lv02d_remove_fs(&lis3_dev); | 89 | return lis3lv02d_remove_fs(&lis3_dev); |