diff options
Diffstat (limited to 'drivers/iio/accel/bmc150-accel.c')
-rw-r--r-- | drivers/iio/accel/bmc150-accel.c | 591 |
1 files changed, 306 insertions, 285 deletions
diff --git a/drivers/iio/accel/bmc150-accel.c b/drivers/iio/accel/bmc150-accel.c index 066d0c04072c..f1b80c4c0b35 100644 --- a/drivers/iio/accel/bmc150-accel.c +++ b/drivers/iio/accel/bmc150-accel.c | |||
@@ -147,10 +147,37 @@ struct bmc150_accel_chip_info { | |||
147 | const struct bmc150_scale_info scale_table[4]; | 147 | const struct bmc150_scale_info scale_table[4]; |
148 | }; | 148 | }; |
149 | 149 | ||
150 | struct bmc150_accel_interrupt { | ||
151 | const struct bmc150_accel_interrupt_info *info; | ||
152 | atomic_t users; | ||
153 | }; | ||
154 | |||
155 | struct bmc150_accel_trigger { | ||
156 | struct bmc150_accel_data *data; | ||
157 | struct iio_trigger *indio_trig; | ||
158 | int (*setup)(struct bmc150_accel_trigger *t, bool state); | ||
159 | int intr; | ||
160 | bool enabled; | ||
161 | }; | ||
162 | |||
163 | enum bmc150_accel_interrupt_id { | ||
164 | BMC150_ACCEL_INT_DATA_READY, | ||
165 | BMC150_ACCEL_INT_ANY_MOTION, | ||
166 | BMC150_ACCEL_INT_WATERMARK, | ||
167 | BMC150_ACCEL_INTERRUPTS, | ||
168 | }; | ||
169 | |||
170 | enum bmc150_accel_trigger_id { | ||
171 | BMC150_ACCEL_TRIGGER_DATA_READY, | ||
172 | BMC150_ACCEL_TRIGGER_ANY_MOTION, | ||
173 | BMC150_ACCEL_TRIGGERS, | ||
174 | }; | ||
175 | |||
150 | struct bmc150_accel_data { | 176 | struct bmc150_accel_data { |
151 | struct i2c_client *client; | 177 | struct i2c_client *client; |
152 | struct iio_trigger *dready_trig; | 178 | struct bmc150_accel_interrupt interrupts[BMC150_ACCEL_INTERRUPTS]; |
153 | struct iio_trigger *motion_trig; | 179 | atomic_t active_intr; |
180 | struct bmc150_accel_trigger triggers[BMC150_ACCEL_TRIGGERS]; | ||
154 | struct mutex mutex; | 181 | struct mutex mutex; |
155 | s16 buffer[8]; | 182 | s16 buffer[8]; |
156 | u8 bw_bits; | 183 | u8 bw_bits; |
@@ -158,8 +185,6 @@ struct bmc150_accel_data { | |||
158 | u32 slope_thres; | 185 | u32 slope_thres; |
159 | u32 range; | 186 | u32 range; |
160 | int ev_enable_state; | 187 | int ev_enable_state; |
161 | bool dready_trigger_on; | ||
162 | bool motion_trigger_on; | ||
163 | int64_t timestamp; | 188 | int64_t timestamp; |
164 | const struct bmc150_accel_chip_info *chip_info; | 189 | const struct bmc150_accel_chip_info *chip_info; |
165 | }; | 190 | }; |
@@ -269,6 +294,46 @@ static int bmc150_accel_set_bw(struct bmc150_accel_data *data, int val, | |||
269 | return -EINVAL; | 294 | return -EINVAL; |
270 | } | 295 | } |
271 | 296 | ||
297 | static int bmc150_accel_update_slope(struct bmc150_accel_data *data) | ||
298 | { | ||
299 | int ret, val; | ||
300 | |||
301 | ret = i2c_smbus_write_byte_data(data->client, BMC150_ACCEL_REG_INT_6, | ||
302 | data->slope_thres); | ||
303 | if (ret < 0) { | ||
304 | dev_err(&data->client->dev, "Error writing reg_int_6\n"); | ||
305 | return ret; | ||
306 | } | ||
307 | |||
308 | ret = i2c_smbus_read_byte_data(data->client, BMC150_ACCEL_REG_INT_5); | ||
309 | if (ret < 0) { | ||
310 | dev_err(&data->client->dev, "Error reading reg_int_5\n"); | ||
311 | return ret; | ||
312 | } | ||
313 | |||
314 | val = (ret & ~BMC150_ACCEL_SLOPE_DUR_MASK) | data->slope_dur; | ||
315 | ret = i2c_smbus_write_byte_data(data->client, BMC150_ACCEL_REG_INT_5, | ||
316 | val); | ||
317 | if (ret < 0) { | ||
318 | dev_err(&data->client->dev, "Error write reg_int_5\n"); | ||
319 | return ret; | ||
320 | } | ||
321 | |||
322 | dev_dbg(&data->client->dev, "%s: %x %x\n", __func__, data->slope_thres, | ||
323 | data->slope_dur); | ||
324 | |||
325 | return ret; | ||
326 | } | ||
327 | |||
328 | static int bmc150_accel_any_motion_setup(struct bmc150_accel_trigger *t, | ||
329 | bool state) | ||
330 | { | ||
331 | if (state) | ||
332 | return bmc150_accel_update_slope(t->data); | ||
333 | |||
334 | return 0; | ||
335 | } | ||
336 | |||
272 | static int bmc150_accel_chip_init(struct bmc150_accel_data *data) | 337 | static int bmc150_accel_chip_init(struct bmc150_accel_data *data) |
273 | { | 338 | { |
274 | int ret; | 339 | int ret; |
@@ -307,32 +372,12 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data) | |||
307 | 372 | ||
308 | data->range = BMC150_ACCEL_DEF_RANGE_4G; | 373 | data->range = BMC150_ACCEL_DEF_RANGE_4G; |
309 | 374 | ||
310 | /* Set default slope duration */ | 375 | /* Set default slope duration and thresholds */ |
311 | ret = i2c_smbus_read_byte_data(data->client, BMC150_ACCEL_REG_INT_5); | ||
312 | if (ret < 0) { | ||
313 | dev_err(&data->client->dev, "Error reading reg_int_5\n"); | ||
314 | return ret; | ||
315 | } | ||
316 | data->slope_dur |= BMC150_ACCEL_DEF_SLOPE_DURATION; | ||
317 | ret = i2c_smbus_write_byte_data(data->client, | ||
318 | BMC150_ACCEL_REG_INT_5, | ||
319 | data->slope_dur); | ||
320 | if (ret < 0) { | ||
321 | dev_err(&data->client->dev, "Error writing reg_int_5\n"); | ||
322 | return ret; | ||
323 | } | ||
324 | dev_dbg(&data->client->dev, "slope_dur %x\n", data->slope_dur); | ||
325 | |||
326 | /* Set default slope thresholds */ | ||
327 | ret = i2c_smbus_write_byte_data(data->client, | ||
328 | BMC150_ACCEL_REG_INT_6, | ||
329 | BMC150_ACCEL_DEF_SLOPE_THRESHOLD); | ||
330 | if (ret < 0) { | ||
331 | dev_err(&data->client->dev, "Error writing reg_int_6\n"); | ||
332 | return ret; | ||
333 | } | ||
334 | data->slope_thres = BMC150_ACCEL_DEF_SLOPE_THRESHOLD; | 376 | data->slope_thres = BMC150_ACCEL_DEF_SLOPE_THRESHOLD; |
335 | dev_dbg(&data->client->dev, "slope_thres %x\n", data->slope_thres); | 377 | data->slope_dur = BMC150_ACCEL_DEF_SLOPE_DURATION; |
378 | ret = bmc150_accel_update_slope(data); | ||
379 | if (ret < 0) | ||
380 | return ret; | ||
336 | 381 | ||
337 | /* Set default as latched interrupts */ | 382 | /* Set default as latched interrupts */ |
338 | ret = i2c_smbus_write_byte_data(data->client, | 383 | ret = i2c_smbus_write_byte_data(data->client, |
@@ -348,155 +393,6 @@ static int bmc150_accel_chip_init(struct bmc150_accel_data *data) | |||
348 | return 0; | 393 | return 0; |
349 | } | 394 | } |
350 | 395 | ||
351 | static int bmc150_accel_setup_any_motion_interrupt( | ||
352 | struct bmc150_accel_data *data, | ||
353 | bool status) | ||
354 | { | ||
355 | int ret; | ||
356 | |||
357 | /* Enable/Disable INT1 mapping */ | ||
358 | ret = i2c_smbus_read_byte_data(data->client, | ||
359 | BMC150_ACCEL_REG_INT_MAP_0); | ||
360 | if (ret < 0) { | ||
361 | dev_err(&data->client->dev, "Error reading reg_int_map_0\n"); | ||
362 | return ret; | ||
363 | } | ||
364 | if (status) | ||
365 | ret |= BMC150_ACCEL_INT_MAP_0_BIT_SLOPE; | ||
366 | else | ||
367 | ret &= ~BMC150_ACCEL_INT_MAP_0_BIT_SLOPE; | ||
368 | |||
369 | ret = i2c_smbus_write_byte_data(data->client, | ||
370 | BMC150_ACCEL_REG_INT_MAP_0, | ||
371 | ret); | ||
372 | if (ret < 0) { | ||
373 | dev_err(&data->client->dev, "Error writing reg_int_map_0\n"); | ||
374 | return ret; | ||
375 | } | ||
376 | |||
377 | if (status) { | ||
378 | /* Set slope duration (no of samples) */ | ||
379 | ret = i2c_smbus_write_byte_data(data->client, | ||
380 | BMC150_ACCEL_REG_INT_5, | ||
381 | data->slope_dur); | ||
382 | if (ret < 0) { | ||
383 | dev_err(&data->client->dev, "Error write reg_int_5\n"); | ||
384 | return ret; | ||
385 | } | ||
386 | |||
387 | /* Set slope thresholds */ | ||
388 | ret = i2c_smbus_write_byte_data(data->client, | ||
389 | BMC150_ACCEL_REG_INT_6, | ||
390 | data->slope_thres); | ||
391 | if (ret < 0) { | ||
392 | dev_err(&data->client->dev, "Error write reg_int_6\n"); | ||
393 | return ret; | ||
394 | } | ||
395 | |||
396 | /* | ||
397 | * New data interrupt is always non-latched, | ||
398 | * which will have higher priority, so no need | ||
399 | * to set latched mode, we will be flooded anyway with INTR | ||
400 | */ | ||
401 | if (!data->dready_trigger_on) { | ||
402 | ret = i2c_smbus_write_byte_data(data->client, | ||
403 | BMC150_ACCEL_REG_INT_RST_LATCH, | ||
404 | BMC150_ACCEL_INT_MODE_LATCH_INT | | ||
405 | BMC150_ACCEL_INT_MODE_LATCH_RESET); | ||
406 | if (ret < 0) { | ||
407 | dev_err(&data->client->dev, | ||
408 | "Error writing reg_int_rst_latch\n"); | ||
409 | return ret; | ||
410 | } | ||
411 | } | ||
412 | |||
413 | ret = i2c_smbus_write_byte_data(data->client, | ||
414 | BMC150_ACCEL_REG_INT_EN_0, | ||
415 | BMC150_ACCEL_INT_EN_BIT_SLP_X | | ||
416 | BMC150_ACCEL_INT_EN_BIT_SLP_Y | | ||
417 | BMC150_ACCEL_INT_EN_BIT_SLP_Z); | ||
418 | } else | ||
419 | ret = i2c_smbus_write_byte_data(data->client, | ||
420 | BMC150_ACCEL_REG_INT_EN_0, | ||
421 | 0); | ||
422 | |||
423 | if (ret < 0) { | ||
424 | dev_err(&data->client->dev, "Error writing reg_int_en_0\n"); | ||
425 | return ret; | ||
426 | } | ||
427 | |||
428 | return 0; | ||
429 | } | ||
430 | |||
431 | static int bmc150_accel_setup_new_data_interrupt(struct bmc150_accel_data *data, | ||
432 | bool status) | ||
433 | { | ||
434 | int ret; | ||
435 | |||
436 | /* Enable/Disable INT1 mapping */ | ||
437 | ret = i2c_smbus_read_byte_data(data->client, | ||
438 | BMC150_ACCEL_REG_INT_MAP_1); | ||
439 | if (ret < 0) { | ||
440 | dev_err(&data->client->dev, "Error reading reg_int_map_1\n"); | ||
441 | return ret; | ||
442 | } | ||
443 | if (status) | ||
444 | ret |= BMC150_ACCEL_INT_MAP_1_BIT_DATA; | ||
445 | else | ||
446 | ret &= ~BMC150_ACCEL_INT_MAP_1_BIT_DATA; | ||
447 | |||
448 | ret = i2c_smbus_write_byte_data(data->client, | ||
449 | BMC150_ACCEL_REG_INT_MAP_1, | ||
450 | ret); | ||
451 | if (ret < 0) { | ||
452 | dev_err(&data->client->dev, "Error writing reg_int_map_1\n"); | ||
453 | return ret; | ||
454 | } | ||
455 | |||
456 | if (status) { | ||
457 | /* | ||
458 | * Set non latched mode interrupt and clear any latched | ||
459 | * interrupt | ||
460 | */ | ||
461 | ret = i2c_smbus_write_byte_data(data->client, | ||
462 | BMC150_ACCEL_REG_INT_RST_LATCH, | ||
463 | BMC150_ACCEL_INT_MODE_NON_LATCH_INT | | ||
464 | BMC150_ACCEL_INT_MODE_LATCH_RESET); | ||
465 | if (ret < 0) { | ||
466 | dev_err(&data->client->dev, | ||
467 | "Error writing reg_int_rst_latch\n"); | ||
468 | return ret; | ||
469 | } | ||
470 | |||
471 | ret = i2c_smbus_write_byte_data(data->client, | ||
472 | BMC150_ACCEL_REG_INT_EN_1, | ||
473 | BMC150_ACCEL_INT_EN_BIT_DATA_EN); | ||
474 | |||
475 | } else { | ||
476 | /* Restore default interrupt mode */ | ||
477 | ret = i2c_smbus_write_byte_data(data->client, | ||
478 | BMC150_ACCEL_REG_INT_RST_LATCH, | ||
479 | BMC150_ACCEL_INT_MODE_LATCH_INT | | ||
480 | BMC150_ACCEL_INT_MODE_LATCH_RESET); | ||
481 | if (ret < 0) { | ||
482 | dev_err(&data->client->dev, | ||
483 | "Error writing reg_int_rst_latch\n"); | ||
484 | return ret; | ||
485 | } | ||
486 | |||
487 | ret = i2c_smbus_write_byte_data(data->client, | ||
488 | BMC150_ACCEL_REG_INT_EN_1, | ||
489 | 0); | ||
490 | } | ||
491 | |||
492 | if (ret < 0) { | ||
493 | dev_err(&data->client->dev, "Error writing reg_int_en_1\n"); | ||
494 | return ret; | ||
495 | } | ||
496 | |||
497 | return 0; | ||
498 | } | ||
499 | |||
500 | static int bmc150_accel_get_bw(struct bmc150_accel_data *data, int *val, | 396 | static int bmc150_accel_get_bw(struct bmc150_accel_data *data, int *val, |
501 | int *val2) | 397 | int *val2) |
502 | { | 398 | { |
@@ -554,6 +450,114 @@ static int bmc150_accel_set_power_state(struct bmc150_accel_data *data, bool on) | |||
554 | } | 450 | } |
555 | #endif | 451 | #endif |
556 | 452 | ||
453 | static const struct bmc150_accel_interrupt_info { | ||
454 | u8 map_reg; | ||
455 | u8 map_bitmask; | ||
456 | u8 en_reg; | ||
457 | u8 en_bitmask; | ||
458 | } bmc150_accel_interrupts[BMC150_ACCEL_INTERRUPTS] = { | ||
459 | { /* data ready interrupt */ | ||
460 | .map_reg = BMC150_ACCEL_REG_INT_MAP_1, | ||
461 | .map_bitmask = BMC150_ACCEL_INT_MAP_1_BIT_DATA, | ||
462 | .en_reg = BMC150_ACCEL_REG_INT_EN_1, | ||
463 | .en_bitmask = BMC150_ACCEL_INT_EN_BIT_DATA_EN, | ||
464 | }, | ||
465 | { /* motion interrupt */ | ||
466 | .map_reg = BMC150_ACCEL_REG_INT_MAP_0, | ||
467 | .map_bitmask = BMC150_ACCEL_INT_MAP_0_BIT_SLOPE, | ||
468 | .en_reg = BMC150_ACCEL_REG_INT_EN_0, | ||
469 | .en_bitmask = BMC150_ACCEL_INT_EN_BIT_SLP_X | | ||
470 | BMC150_ACCEL_INT_EN_BIT_SLP_Y | | ||
471 | BMC150_ACCEL_INT_EN_BIT_SLP_Z | ||
472 | }, | ||
473 | }; | ||
474 | |||
475 | static void bmc150_accel_interrupts_setup(struct iio_dev *indio_dev, | ||
476 | struct bmc150_accel_data *data) | ||
477 | { | ||
478 | int i; | ||
479 | |||
480 | for (i = 0; i < BMC150_ACCEL_INTERRUPTS; i++) | ||
481 | data->interrupts[i].info = &bmc150_accel_interrupts[i]; | ||
482 | } | ||
483 | |||
484 | static int bmc150_accel_set_interrupt(struct bmc150_accel_data *data, int i, | ||
485 | bool state) | ||
486 | { | ||
487 | struct bmc150_accel_interrupt *intr = &data->interrupts[i]; | ||
488 | const struct bmc150_accel_interrupt_info *info = intr->info; | ||
489 | int ret; | ||
490 | |||
491 | if (state) { | ||
492 | if (atomic_inc_return(&intr->users) > 1) | ||
493 | return 0; | ||
494 | } else { | ||
495 | if (atomic_dec_return(&intr->users) > 0) | ||
496 | return 0; | ||
497 | } | ||
498 | |||
499 | /* | ||
500 | * We will expect the enable and disable to do operation in | ||
501 | * in reverse order. This will happen here anyway as our | ||
502 | * resume operation uses sync mode runtime pm calls, the | ||
503 | * suspend operation will be delayed by autosuspend delay | ||
504 | * So the disable operation will still happen in reverse of | ||
505 | * enable operation. When runtime pm is disabled the mode | ||
506 | * is always on so sequence doesn't matter | ||
507 | */ | ||
508 | ret = bmc150_accel_set_power_state(data, state); | ||
509 | if (ret < 0) | ||
510 | return ret; | ||
511 | |||
512 | /* map the interrupt to the appropriate pins */ | ||
513 | ret = i2c_smbus_read_byte_data(data->client, info->map_reg); | ||
514 | if (ret < 0) { | ||
515 | dev_err(&data->client->dev, "Error reading reg_int_map\n"); | ||
516 | goto out_fix_power_state; | ||
517 | } | ||
518 | if (state) | ||
519 | ret |= info->map_bitmask; | ||
520 | else | ||
521 | ret &= ~info->map_bitmask; | ||
522 | |||
523 | ret = i2c_smbus_write_byte_data(data->client, info->map_reg, | ||
524 | ret); | ||
525 | if (ret < 0) { | ||
526 | dev_err(&data->client->dev, "Error writing reg_int_map\n"); | ||
527 | goto out_fix_power_state; | ||
528 | } | ||
529 | |||
530 | /* enable/disable the interrupt */ | ||
531 | ret = i2c_smbus_read_byte_data(data->client, info->en_reg); | ||
532 | if (ret < 0) { | ||
533 | dev_err(&data->client->dev, "Error reading reg_int_en\n"); | ||
534 | goto out_fix_power_state; | ||
535 | } | ||
536 | |||
537 | if (state) | ||
538 | ret |= info->en_bitmask; | ||
539 | else | ||
540 | ret &= ~info->en_bitmask; | ||
541 | |||
542 | ret = i2c_smbus_write_byte_data(data->client, info->en_reg, ret); | ||
543 | if (ret < 0) { | ||
544 | dev_err(&data->client->dev, "Error writing reg_int_en\n"); | ||
545 | goto out_fix_power_state; | ||
546 | } | ||
547 | |||
548 | if (state) | ||
549 | atomic_inc(&data->active_intr); | ||
550 | else | ||
551 | atomic_dec(&data->active_intr); | ||
552 | |||
553 | return 0; | ||
554 | |||
555 | out_fix_power_state: | ||
556 | bmc150_accel_set_power_state(data, false); | ||
557 | return ret; | ||
558 | } | ||
559 | |||
560 | |||
557 | static int bmc150_accel_set_scale(struct bmc150_accel_data *data, int val) | 561 | static int bmc150_accel_set_scale(struct bmc150_accel_data *data, int val) |
558 | { | 562 | { |
559 | int ret, i; | 563 | int ret, i; |
@@ -732,7 +736,7 @@ static int bmc150_accel_read_event(struct iio_dev *indio_dev, | |||
732 | *val = data->slope_thres; | 736 | *val = data->slope_thres; |
733 | break; | 737 | break; |
734 | case IIO_EV_INFO_PERIOD: | 738 | case IIO_EV_INFO_PERIOD: |
735 | *val = data->slope_dur & BMC150_ACCEL_SLOPE_DUR_MASK; | 739 | *val = data->slope_dur; |
736 | break; | 740 | break; |
737 | default: | 741 | default: |
738 | return -EINVAL; | 742 | return -EINVAL; |
@@ -755,11 +759,10 @@ static int bmc150_accel_write_event(struct iio_dev *indio_dev, | |||
755 | 759 | ||
756 | switch (info) { | 760 | switch (info) { |
757 | case IIO_EV_INFO_VALUE: | 761 | case IIO_EV_INFO_VALUE: |
758 | data->slope_thres = val; | 762 | data->slope_thres = val & 0xFF; |
759 | break; | 763 | break; |
760 | case IIO_EV_INFO_PERIOD: | 764 | case IIO_EV_INFO_PERIOD: |
761 | data->slope_dur &= ~BMC150_ACCEL_SLOPE_DUR_MASK; | 765 | data->slope_dur = val & BMC150_ACCEL_SLOPE_DUR_MASK; |
762 | data->slope_dur |= val & BMC150_ACCEL_SLOPE_DUR_MASK; | ||
763 | break; | 766 | break; |
764 | default: | 767 | default: |
765 | return -EINVAL; | 768 | return -EINVAL; |
@@ -788,36 +791,14 @@ static int bmc150_accel_write_event_config(struct iio_dev *indio_dev, | |||
788 | struct bmc150_accel_data *data = iio_priv(indio_dev); | 791 | struct bmc150_accel_data *data = iio_priv(indio_dev); |
789 | int ret; | 792 | int ret; |
790 | 793 | ||
791 | if (state && data->ev_enable_state) | 794 | if (state == data->ev_enable_state) |
792 | return 0; | 795 | return 0; |
793 | 796 | ||
794 | mutex_lock(&data->mutex); | 797 | mutex_lock(&data->mutex); |
795 | 798 | ||
796 | if (!state && data->motion_trigger_on) { | 799 | ret = bmc150_accel_set_interrupt(data, BMC150_ACCEL_INT_ANY_MOTION, |
797 | data->ev_enable_state = 0; | 800 | state); |
798 | mutex_unlock(&data->mutex); | ||
799 | return 0; | ||
800 | } | ||
801 | |||
802 | /* | ||
803 | * We will expect the enable and disable to do operation in | ||
804 | * in reverse order. This will happen here anyway as our | ||
805 | * resume operation uses sync mode runtime pm calls, the | ||
806 | * suspend operation will be delayed by autosuspend delay | ||
807 | * So the disable operation will still happen in reverse of | ||
808 | * enable operation. When runtime pm is disabled the mode | ||
809 | * is always on so sequence doesn't matter | ||
810 | */ | ||
811 | |||
812 | ret = bmc150_accel_set_power_state(data, state); | ||
813 | if (ret < 0) { | ||
814 | mutex_unlock(&data->mutex); | ||
815 | return ret; | ||
816 | } | ||
817 | |||
818 | ret = bmc150_accel_setup_any_motion_interrupt(data, state); | ||
819 | if (ret < 0) { | 801 | if (ret < 0) { |
820 | bmc150_accel_set_power_state(data, false); | ||
821 | mutex_unlock(&data->mutex); | 802 | mutex_unlock(&data->mutex); |
822 | return ret; | 803 | return ret; |
823 | } | 804 | } |
@@ -832,11 +813,14 @@ static int bmc150_accel_validate_trigger(struct iio_dev *indio_dev, | |||
832 | struct iio_trigger *trig) | 813 | struct iio_trigger *trig) |
833 | { | 814 | { |
834 | struct bmc150_accel_data *data = iio_priv(indio_dev); | 815 | struct bmc150_accel_data *data = iio_priv(indio_dev); |
816 | int i; | ||
835 | 817 | ||
836 | if (data->dready_trig != trig && data->motion_trig != trig) | 818 | for (i = 0; i < BMC150_ACCEL_TRIGGERS; i++) { |
837 | return -EINVAL; | 819 | if (data->triggers[i].indio_trig == trig) |
820 | return 0; | ||
821 | } | ||
838 | 822 | ||
839 | return 0; | 823 | return -EINVAL; |
840 | } | 824 | } |
841 | 825 | ||
842 | static IIO_CONST_ATTR_SAMP_FREQ_AVAIL( | 826 | static IIO_CONST_ATTR_SAMP_FREQ_AVAIL( |
@@ -1008,12 +992,12 @@ err_read: | |||
1008 | 992 | ||
1009 | static int bmc150_accel_trig_try_reen(struct iio_trigger *trig) | 993 | static int bmc150_accel_trig_try_reen(struct iio_trigger *trig) |
1010 | { | 994 | { |
1011 | struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); | 995 | struct bmc150_accel_trigger *t = iio_trigger_get_drvdata(trig); |
1012 | struct bmc150_accel_data *data = iio_priv(indio_dev); | 996 | struct bmc150_accel_data *data = t->data; |
1013 | int ret; | 997 | int ret; |
1014 | 998 | ||
1015 | /* new data interrupts don't need ack */ | 999 | /* new data interrupts don't need ack */ |
1016 | if (data->dready_trigger_on) | 1000 | if (t == &t->data->triggers[BMC150_ACCEL_TRIGGER_DATA_READY]) |
1017 | return 0; | 1001 | return 0; |
1018 | 1002 | ||
1019 | mutex_lock(&data->mutex); | 1003 | mutex_lock(&data->mutex); |
@@ -1032,43 +1016,35 @@ static int bmc150_accel_trig_try_reen(struct iio_trigger *trig) | |||
1032 | return 0; | 1016 | return 0; |
1033 | } | 1017 | } |
1034 | 1018 | ||
1035 | static int bmc150_accel_data_rdy_trigger_set_state(struct iio_trigger *trig, | 1019 | static int bmc150_accel_trigger_set_state(struct iio_trigger *trig, |
1036 | bool state) | 1020 | bool state) |
1037 | { | 1021 | { |
1038 | struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig); | 1022 | struct bmc150_accel_trigger *t = iio_trigger_get_drvdata(trig); |
1039 | struct bmc150_accel_data *data = iio_priv(indio_dev); | 1023 | struct bmc150_accel_data *data = t->data; |
1040 | int ret; | 1024 | int ret; |
1041 | 1025 | ||
1042 | mutex_lock(&data->mutex); | 1026 | mutex_lock(&data->mutex); |
1043 | 1027 | ||
1044 | if (!state && data->ev_enable_state && data->motion_trigger_on) { | 1028 | if (t->enabled == state) { |
1045 | data->motion_trigger_on = false; | ||
1046 | mutex_unlock(&data->mutex); | 1029 | mutex_unlock(&data->mutex); |
1047 | return 0; | 1030 | return 0; |
1048 | } | 1031 | } |
1049 | 1032 | ||
1050 | /* | 1033 | if (t->setup) { |
1051 | * Refer to comment in bmc150_accel_write_event_config for | 1034 | ret = t->setup(t, state); |
1052 | * enable/disable operation order | 1035 | if (ret < 0) { |
1053 | */ | 1036 | mutex_unlock(&data->mutex); |
1054 | ret = bmc150_accel_set_power_state(data, state); | 1037 | return ret; |
1055 | if (ret < 0) { | 1038 | } |
1056 | mutex_unlock(&data->mutex); | ||
1057 | return ret; | ||
1058 | } | 1039 | } |
1059 | if (data->motion_trig == trig) | 1040 | |
1060 | ret = bmc150_accel_setup_any_motion_interrupt(data, state); | 1041 | ret = bmc150_accel_set_interrupt(data, t->intr, state); |
1061 | else | ||
1062 | ret = bmc150_accel_setup_new_data_interrupt(data, state); | ||
1063 | if (ret < 0) { | 1042 | if (ret < 0) { |
1064 | bmc150_accel_set_power_state(data, false); | ||
1065 | mutex_unlock(&data->mutex); | 1043 | mutex_unlock(&data->mutex); |
1066 | return ret; | 1044 | return ret; |
1067 | } | 1045 | } |
1068 | if (data->motion_trig == trig) | 1046 | |
1069 | data->motion_trigger_on = state; | 1047 | t->enabled = state; |
1070 | else | ||
1071 | data->dready_trigger_on = state; | ||
1072 | 1048 | ||
1073 | mutex_unlock(&data->mutex); | 1049 | mutex_unlock(&data->mutex); |
1074 | 1050 | ||
@@ -1076,7 +1052,7 @@ static int bmc150_accel_data_rdy_trigger_set_state(struct iio_trigger *trig, | |||
1076 | } | 1052 | } |
1077 | 1053 | ||
1078 | static const struct iio_trigger_ops bmc150_accel_trigger_ops = { | 1054 | static const struct iio_trigger_ops bmc150_accel_trigger_ops = { |
1079 | .set_trigger_state = bmc150_accel_data_rdy_trigger_set_state, | 1055 | .set_trigger_state = bmc150_accel_trigger_set_state, |
1080 | .try_reenable = bmc150_accel_trig_try_reen, | 1056 | .try_reenable = bmc150_accel_trig_try_reen, |
1081 | .owner = THIS_MODULE, | 1057 | .owner = THIS_MODULE, |
1082 | }; | 1058 | }; |
@@ -1122,7 +1098,7 @@ static irqreturn_t bmc150_accel_event_handler(int irq, void *private) | |||
1122 | dir), | 1098 | dir), |
1123 | data->timestamp); | 1099 | data->timestamp); |
1124 | ack_intr_status: | 1100 | ack_intr_status: |
1125 | if (!data->dready_trigger_on) | 1101 | if (!data->triggers[BMC150_ACCEL_TRIGGER_DATA_READY].enabled) |
1126 | ret = i2c_smbus_write_byte_data(data->client, | 1102 | ret = i2c_smbus_write_byte_data(data->client, |
1127 | BMC150_ACCEL_REG_INT_RST_LATCH, | 1103 | BMC150_ACCEL_REG_INT_RST_LATCH, |
1128 | BMC150_ACCEL_INT_MODE_LATCH_INT | | 1104 | BMC150_ACCEL_INT_MODE_LATCH_INT | |
@@ -1135,13 +1111,16 @@ static irqreturn_t bmc150_accel_data_rdy_trig_poll(int irq, void *private) | |||
1135 | { | 1111 | { |
1136 | struct iio_dev *indio_dev = private; | 1112 | struct iio_dev *indio_dev = private; |
1137 | struct bmc150_accel_data *data = iio_priv(indio_dev); | 1113 | struct bmc150_accel_data *data = iio_priv(indio_dev); |
1114 | int i; | ||
1138 | 1115 | ||
1139 | data->timestamp = iio_get_time_ns(); | 1116 | data->timestamp = iio_get_time_ns(); |
1140 | 1117 | ||
1141 | if (data->dready_trigger_on) | 1118 | for (i = 0; i < BMC150_ACCEL_TRIGGERS; i++) { |
1142 | iio_trigger_poll(data->dready_trig); | 1119 | if (data->triggers[i].enabled) { |
1143 | else if (data->motion_trigger_on) | 1120 | iio_trigger_poll(data->triggers[i].indio_trig); |
1144 | iio_trigger_poll(data->motion_trig); | 1121 | break; |
1122 | } | ||
1123 | } | ||
1145 | 1124 | ||
1146 | if (data->ev_enable_state) | 1125 | if (data->ev_enable_state) |
1147 | return IRQ_WAKE_THREAD; | 1126 | return IRQ_WAKE_THREAD; |
@@ -1176,16 +1155,12 @@ static int bmc150_accel_gpio_probe(struct i2c_client *client, | |||
1176 | dev = &client->dev; | 1155 | dev = &client->dev; |
1177 | 1156 | ||
1178 | /* data ready gpio interrupt pin */ | 1157 | /* data ready gpio interrupt pin */ |
1179 | gpio = devm_gpiod_get_index(dev, BMC150_ACCEL_GPIO_NAME, 0); | 1158 | gpio = devm_gpiod_get_index(dev, BMC150_ACCEL_GPIO_NAME, 0, GPIOD_IN); |
1180 | if (IS_ERR(gpio)) { | 1159 | if (IS_ERR(gpio)) { |
1181 | dev_err(dev, "Failed: gpio get index\n"); | 1160 | dev_err(dev, "Failed: gpio get index\n"); |
1182 | return PTR_ERR(gpio); | 1161 | return PTR_ERR(gpio); |
1183 | } | 1162 | } |
1184 | 1163 | ||
1185 | ret = gpiod_direction_input(gpio); | ||
1186 | if (ret) | ||
1187 | return ret; | ||
1188 | |||
1189 | ret = gpiod_to_irq(gpio); | 1164 | ret = gpiod_to_irq(gpio); |
1190 | 1165 | ||
1191 | dev_dbg(dev, "GPIO resource, no:%d irq:%d\n", desc_to_gpio(gpio), ret); | 1166 | dev_dbg(dev, "GPIO resource, no:%d irq:%d\n", desc_to_gpio(gpio), ret); |
@@ -1193,6 +1168,70 @@ static int bmc150_accel_gpio_probe(struct i2c_client *client, | |||
1193 | return ret; | 1168 | return ret; |
1194 | } | 1169 | } |
1195 | 1170 | ||
1171 | static const struct { | ||
1172 | int intr; | ||
1173 | const char *name; | ||
1174 | int (*setup)(struct bmc150_accel_trigger *t, bool state); | ||
1175 | } bmc150_accel_triggers[BMC150_ACCEL_TRIGGERS] = { | ||
1176 | { | ||
1177 | .intr = 0, | ||
1178 | .name = "%s-dev%d", | ||
1179 | }, | ||
1180 | { | ||
1181 | .intr = 1, | ||
1182 | .name = "%s-any-motion-dev%d", | ||
1183 | .setup = bmc150_accel_any_motion_setup, | ||
1184 | }, | ||
1185 | }; | ||
1186 | |||
1187 | static void bmc150_accel_unregister_triggers(struct bmc150_accel_data *data, | ||
1188 | int from) | ||
1189 | { | ||
1190 | int i; | ||
1191 | |||
1192 | for (i = from; i >= 0; i++) { | ||
1193 | if (data->triggers[i].indio_trig) { | ||
1194 | iio_trigger_unregister(data->triggers[i].indio_trig); | ||
1195 | data->triggers[i].indio_trig = NULL; | ||
1196 | } | ||
1197 | } | ||
1198 | } | ||
1199 | |||
1200 | static int bmc150_accel_triggers_setup(struct iio_dev *indio_dev, | ||
1201 | struct bmc150_accel_data *data) | ||
1202 | { | ||
1203 | int i, ret; | ||
1204 | |||
1205 | for (i = 0; i < BMC150_ACCEL_TRIGGERS; i++) { | ||
1206 | struct bmc150_accel_trigger *t = &data->triggers[i]; | ||
1207 | |||
1208 | t->indio_trig = devm_iio_trigger_alloc(&data->client->dev, | ||
1209 | bmc150_accel_triggers[i].name, | ||
1210 | indio_dev->name, | ||
1211 | indio_dev->id); | ||
1212 | if (!t->indio_trig) { | ||
1213 | ret = -ENOMEM; | ||
1214 | break; | ||
1215 | } | ||
1216 | |||
1217 | t->indio_trig->dev.parent = &data->client->dev; | ||
1218 | t->indio_trig->ops = &bmc150_accel_trigger_ops; | ||
1219 | t->intr = bmc150_accel_triggers[i].intr; | ||
1220 | t->data = data; | ||
1221 | t->setup = bmc150_accel_triggers[i].setup; | ||
1222 | iio_trigger_set_drvdata(t->indio_trig, t); | ||
1223 | |||
1224 | ret = iio_trigger_register(t->indio_trig); | ||
1225 | if (ret) | ||
1226 | break; | ||
1227 | } | ||
1228 | |||
1229 | if (ret) | ||
1230 | bmc150_accel_unregister_triggers(data, i - 1); | ||
1231 | |||
1232 | return ret; | ||
1233 | } | ||
1234 | |||
1196 | static int bmc150_accel_probe(struct i2c_client *client, | 1235 | static int bmc150_accel_probe(struct i2c_client *client, |
1197 | const struct i2c_device_id *id) | 1236 | const struct i2c_device_id *id) |
1198 | { | 1237 | { |
@@ -1247,36 +1286,26 @@ static int bmc150_accel_probe(struct i2c_client *client, | |||
1247 | if (ret) | 1286 | if (ret) |
1248 | return ret; | 1287 | return ret; |
1249 | 1288 | ||
1250 | data->dready_trig = devm_iio_trigger_alloc(&client->dev, | 1289 | /* |
1251 | "%s-dev%d", | 1290 | * Set latched mode interrupt. While certain interrupts are |
1252 | indio_dev->name, | 1291 | * non-latched regardless of this settings (e.g. new data) we |
1253 | indio_dev->id); | 1292 | * want to use latch mode when we can to prevent interrupt |
1254 | if (!data->dready_trig) | 1293 | * flooding. |
1255 | return -ENOMEM; | 1294 | */ |
1256 | 1295 | ret = i2c_smbus_write_byte_data(data->client, | |
1257 | data->motion_trig = devm_iio_trigger_alloc(&client->dev, | 1296 | BMC150_ACCEL_REG_INT_RST_LATCH, |
1258 | "%s-any-motion-dev%d", | 1297 | BMC150_ACCEL_INT_MODE_LATCH_RESET); |
1259 | indio_dev->name, | 1298 | if (ret < 0) { |
1260 | indio_dev->id); | 1299 | dev_err(&data->client->dev, "Error writing reg_int_rst_latch\n"); |
1261 | if (!data->motion_trig) | ||
1262 | return -ENOMEM; | ||
1263 | |||
1264 | data->dready_trig->dev.parent = &client->dev; | ||
1265 | data->dready_trig->ops = &bmc150_accel_trigger_ops; | ||
1266 | iio_trigger_set_drvdata(data->dready_trig, indio_dev); | ||
1267 | ret = iio_trigger_register(data->dready_trig); | ||
1268 | if (ret) | ||
1269 | return ret; | 1300 | return ret; |
1270 | |||
1271 | data->motion_trig->dev.parent = &client->dev; | ||
1272 | data->motion_trig->ops = &bmc150_accel_trigger_ops; | ||
1273 | iio_trigger_set_drvdata(data->motion_trig, indio_dev); | ||
1274 | ret = iio_trigger_register(data->motion_trig); | ||
1275 | if (ret) { | ||
1276 | data->motion_trig = NULL; | ||
1277 | goto err_trigger_unregister; | ||
1278 | } | 1301 | } |
1279 | 1302 | ||
1303 | bmc150_accel_interrupts_setup(indio_dev, data); | ||
1304 | |||
1305 | ret = bmc150_accel_triggers_setup(indio_dev, data); | ||
1306 | if (ret) | ||
1307 | return ret; | ||
1308 | |||
1280 | ret = iio_triggered_buffer_setup(indio_dev, | 1309 | ret = iio_triggered_buffer_setup(indio_dev, |
1281 | &iio_pollfunc_store_time, | 1310 | &iio_pollfunc_store_time, |
1282 | bmc150_accel_trigger_handler, | 1311 | bmc150_accel_trigger_handler, |
@@ -1308,13 +1337,10 @@ static int bmc150_accel_probe(struct i2c_client *client, | |||
1308 | err_iio_unregister: | 1337 | err_iio_unregister: |
1309 | iio_device_unregister(indio_dev); | 1338 | iio_device_unregister(indio_dev); |
1310 | err_buffer_cleanup: | 1339 | err_buffer_cleanup: |
1311 | if (data->dready_trig) | 1340 | if (indio_dev->pollfunc) |
1312 | iio_triggered_buffer_cleanup(indio_dev); | 1341 | iio_triggered_buffer_cleanup(indio_dev); |
1313 | err_trigger_unregister: | 1342 | err_trigger_unregister: |
1314 | if (data->dready_trig) | 1343 | bmc150_accel_unregister_triggers(data, BMC150_ACCEL_TRIGGERS - 1); |
1315 | iio_trigger_unregister(data->dready_trig); | ||
1316 | if (data->motion_trig) | ||
1317 | iio_trigger_unregister(data->motion_trig); | ||
1318 | 1344 | ||
1319 | return ret; | 1345 | return ret; |
1320 | } | 1346 | } |
@@ -1330,11 +1356,7 @@ static int bmc150_accel_remove(struct i2c_client *client) | |||
1330 | 1356 | ||
1331 | iio_device_unregister(indio_dev); | 1357 | iio_device_unregister(indio_dev); |
1332 | 1358 | ||
1333 | if (data->dready_trig) { | 1359 | bmc150_accel_unregister_triggers(data, BMC150_ACCEL_TRIGGERS - 1); |
1334 | iio_triggered_buffer_cleanup(indio_dev); | ||
1335 | iio_trigger_unregister(data->dready_trig); | ||
1336 | iio_trigger_unregister(data->motion_trig); | ||
1337 | } | ||
1338 | 1360 | ||
1339 | mutex_lock(&data->mutex); | 1361 | mutex_lock(&data->mutex); |
1340 | bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_DEEP_SUSPEND, 0); | 1362 | bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_DEEP_SUSPEND, 0); |
@@ -1362,8 +1384,7 @@ static int bmc150_accel_resume(struct device *dev) | |||
1362 | struct bmc150_accel_data *data = iio_priv(indio_dev); | 1384 | struct bmc150_accel_data *data = iio_priv(indio_dev); |
1363 | 1385 | ||
1364 | mutex_lock(&data->mutex); | 1386 | mutex_lock(&data->mutex); |
1365 | if (data->dready_trigger_on || data->motion_trigger_on || | 1387 | if (atomic_read(&data->active_intr)) |
1366 | data->ev_enable_state) | ||
1367 | bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_NORMAL, 0); | 1388 | bmc150_accel_set_mode(data, BMC150_ACCEL_SLEEP_MODE_NORMAL, 0); |
1368 | mutex_unlock(&data->mutex); | 1389 | mutex_unlock(&data->mutex); |
1369 | 1390 | ||