diff options
Diffstat (limited to 'drivers/misc/lis3lv02d')
-rw-r--r-- | drivers/misc/lis3lv02d/lis3lv02d.c | 36 | ||||
-rw-r--r-- | drivers/misc/lis3lv02d/lis3lv02d.h | 2 |
2 files changed, 31 insertions, 7 deletions
diff --git a/drivers/misc/lis3lv02d/lis3lv02d.c b/drivers/misc/lis3lv02d/lis3lv02d.c index 8b51cd62d067..1fc671566562 100644 --- a/drivers/misc/lis3lv02d/lis3lv02d.c +++ b/drivers/misc/lis3lv02d/lis3lv02d.c | |||
@@ -206,6 +206,18 @@ static int lis3lv02d_get_odr(void) | |||
206 | return lis3_dev.odrs[(ctrl >> shift)]; | 206 | return lis3_dev.odrs[(ctrl >> shift)]; |
207 | } | 207 | } |
208 | 208 | ||
209 | static int lis3lv02d_get_pwron_wait(struct lis3lv02d *lis3) | ||
210 | { | ||
211 | int div = lis3lv02d_get_odr(); | ||
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 | |||
209 | static int lis3lv02d_set_odr(int rate) | 221 | static int lis3lv02d_set_odr(int rate) |
210 | { | 222 | { |
211 | u8 ctrl; | 223 | u8 ctrl; |
@@ -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); |
@@ -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,11 +401,14 @@ 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 | ||
@@ -928,7 +948,11 @@ int lis3lv02d_init_device(struct lis3lv02d *dev) | |||
928 | atomic_set(&dev->wake_thread, 0); | 948 | atomic_set(&dev->wake_thread, 0); |
929 | 949 | ||
930 | lis3lv02d_add_fs(dev); | 950 | lis3lv02d_add_fs(dev); |
931 | lis3lv02d_poweron(dev); | 951 | err = lis3lv02d_poweron(dev); |
952 | if (err) { | ||
953 | lis3lv02d_remove_fs(dev); | ||
954 | return err; | ||
955 | } | ||
932 | 956 | ||
933 | if (dev->pm_dev) { | 957 | if (dev->pm_dev) { |
934 | pm_runtime_set_active(dev->pm_dev); | 958 | pm_runtime_set_active(dev->pm_dev); |
diff --git a/drivers/misc/lis3lv02d/lis3lv02d.h b/drivers/misc/lis3lv02d/lis3lv02d.h index a1939589eb2c..57c64bbcf5f7 100644 --- a/drivers/misc/lis3lv02d/lis3lv02d.h +++ b/drivers/misc/lis3lv02d/lis3lv02d.h | |||
@@ -285,7 +285,7 @@ int lis3lv02d_init_device(struct lis3lv02d *lis3); | |||
285 | int lis3lv02d_joystick_enable(void); | 285 | int lis3lv02d_joystick_enable(void); |
286 | void lis3lv02d_joystick_disable(void); | 286 | void lis3lv02d_joystick_disable(void); |
287 | void lis3lv02d_poweroff(struct lis3lv02d *lis3); | 287 | void lis3lv02d_poweroff(struct lis3lv02d *lis3); |
288 | void lis3lv02d_poweron(struct lis3lv02d *lis3); | 288 | int lis3lv02d_poweron(struct lis3lv02d *lis3); |
289 | int lis3lv02d_remove_fs(struct lis3lv02d *lis3); | 289 | int lis3lv02d_remove_fs(struct lis3lv02d *lis3); |
290 | 290 | ||
291 | extern struct lis3lv02d lis3_dev; | 291 | extern struct lis3lv02d lis3_dev; |