diff options
Diffstat (limited to 'drivers/iio/trigger/stm32-timer-trigger.c')
-rw-r--r-- | drivers/iio/trigger/stm32-timer-trigger.c | 82 |
1 files changed, 59 insertions, 23 deletions
diff --git a/drivers/iio/trigger/stm32-timer-trigger.c b/drivers/iio/trigger/stm32-timer-trigger.c index a9bc5b603b86..9b9053494daf 100644 --- a/drivers/iio/trigger/stm32-timer-trigger.c +++ b/drivers/iio/trigger/stm32-timer-trigger.c | |||
@@ -402,34 +402,32 @@ static int stm32_counter_read_raw(struct iio_dev *indio_dev, | |||
402 | int *val, int *val2, long mask) | 402 | int *val, int *val2, long mask) |
403 | { | 403 | { |
404 | struct stm32_timer_trigger *priv = iio_priv(indio_dev); | 404 | struct stm32_timer_trigger *priv = iio_priv(indio_dev); |
405 | u32 dat; | ||
405 | 406 | ||
406 | switch (mask) { | 407 | switch (mask) { |
407 | case IIO_CHAN_INFO_RAW: | 408 | case IIO_CHAN_INFO_RAW: |
408 | { | 409 | regmap_read(priv->regmap, TIM_CNT, &dat); |
409 | u32 cnt; | 410 | *val = dat; |
410 | 411 | return IIO_VAL_INT; | |
411 | regmap_read(priv->regmap, TIM_CNT, &cnt); | ||
412 | *val = cnt; | ||
413 | 412 | ||
413 | case IIO_CHAN_INFO_ENABLE: | ||
414 | regmap_read(priv->regmap, TIM_CR1, &dat); | ||
415 | *val = (dat & TIM_CR1_CEN) ? 1 : 0; | ||
414 | return IIO_VAL_INT; | 416 | return IIO_VAL_INT; |
415 | } | ||
416 | case IIO_CHAN_INFO_SCALE: | ||
417 | { | ||
418 | u32 smcr; | ||
419 | 417 | ||
420 | regmap_read(priv->regmap, TIM_SMCR, &smcr); | 418 | case IIO_CHAN_INFO_SCALE: |
421 | smcr &= TIM_SMCR_SMS; | 419 | regmap_read(priv->regmap, TIM_SMCR, &dat); |
420 | dat &= TIM_SMCR_SMS; | ||
422 | 421 | ||
423 | *val = 1; | 422 | *val = 1; |
424 | *val2 = 0; | 423 | *val2 = 0; |
425 | 424 | ||
426 | /* in quadrature case scale = 0.25 */ | 425 | /* in quadrature case scale = 0.25 */ |
427 | if (smcr == 3) | 426 | if (dat == 3) |
428 | *val2 = 2; | 427 | *val2 = 2; |
429 | 428 | ||
430 | return IIO_VAL_FRACTIONAL_LOG2; | 429 | return IIO_VAL_FRACTIONAL_LOG2; |
431 | } | 430 | } |
432 | } | ||
433 | 431 | ||
434 | return -EINVAL; | 432 | return -EINVAL; |
435 | } | 433 | } |
@@ -439,15 +437,31 @@ static int stm32_counter_write_raw(struct iio_dev *indio_dev, | |||
439 | int val, int val2, long mask) | 437 | int val, int val2, long mask) |
440 | { | 438 | { |
441 | struct stm32_timer_trigger *priv = iio_priv(indio_dev); | 439 | struct stm32_timer_trigger *priv = iio_priv(indio_dev); |
440 | u32 dat; | ||
442 | 441 | ||
443 | switch (mask) { | 442 | switch (mask) { |
444 | case IIO_CHAN_INFO_RAW: | 443 | case IIO_CHAN_INFO_RAW: |
445 | regmap_write(priv->regmap, TIM_CNT, val); | 444 | return regmap_write(priv->regmap, TIM_CNT, val); |
446 | 445 | ||
447 | return IIO_VAL_INT; | ||
448 | case IIO_CHAN_INFO_SCALE: | 446 | case IIO_CHAN_INFO_SCALE: |
449 | /* fixed scale */ | 447 | /* fixed scale */ |
450 | return -EINVAL; | 448 | return -EINVAL; |
449 | |||
450 | case IIO_CHAN_INFO_ENABLE: | ||
451 | if (val) { | ||
452 | regmap_read(priv->regmap, TIM_CR1, &dat); | ||
453 | if (!(dat & TIM_CR1_CEN)) | ||
454 | clk_enable(priv->clk); | ||
455 | regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, | ||
456 | TIM_CR1_CEN); | ||
457 | } else { | ||
458 | regmap_read(priv->regmap, TIM_CR1, &dat); | ||
459 | regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_CEN, | ||
460 | 0); | ||
461 | if (dat & TIM_CR1_CEN) | ||
462 | clk_disable(priv->clk); | ||
463 | } | ||
464 | return 0; | ||
451 | } | 465 | } |
452 | 466 | ||
453 | return -EINVAL; | 467 | return -EINVAL; |
@@ -507,7 +521,7 @@ static int stm32_get_trigger_mode(struct iio_dev *indio_dev, | |||
507 | 521 | ||
508 | regmap_read(priv->regmap, TIM_SMCR, &smcr); | 522 | regmap_read(priv->regmap, TIM_SMCR, &smcr); |
509 | 523 | ||
510 | return smcr == TIM_SMCR_SMS ? 0 : -EINVAL; | 524 | return (smcr & TIM_SMCR_SMS) == TIM_SMCR_SMS ? 0 : -EINVAL; |
511 | } | 525 | } |
512 | 526 | ||
513 | static const struct iio_enum stm32_trigger_mode_enum = { | 527 | static const struct iio_enum stm32_trigger_mode_enum = { |
@@ -543,9 +557,19 @@ static int stm32_set_enable_mode(struct iio_dev *indio_dev, | |||
543 | { | 557 | { |
544 | struct stm32_timer_trigger *priv = iio_priv(indio_dev); | 558 | struct stm32_timer_trigger *priv = iio_priv(indio_dev); |
545 | int sms = stm32_enable_mode2sms(mode); | 559 | int sms = stm32_enable_mode2sms(mode); |
560 | u32 val; | ||
546 | 561 | ||
547 | if (sms < 0) | 562 | if (sms < 0) |
548 | return sms; | 563 | return sms; |
564 | /* | ||
565 | * Triggered mode sets CEN bit automatically by hardware. So, first | ||
566 | * enable counter clock, so it can use it. Keeps it in sync with CEN. | ||
567 | */ | ||
568 | if (sms == 6) { | ||
569 | regmap_read(priv->regmap, TIM_CR1, &val); | ||
570 | if (!(val & TIM_CR1_CEN)) | ||
571 | clk_enable(priv->clk); | ||
572 | } | ||
549 | 573 | ||
550 | regmap_update_bits(priv->regmap, TIM_SMCR, TIM_SMCR_SMS, sms); | 574 | regmap_update_bits(priv->regmap, TIM_SMCR, TIM_SMCR_SMS, sms); |
551 | 575 | ||
@@ -607,11 +631,14 @@ static int stm32_get_quadrature_mode(struct iio_dev *indio_dev, | |||
607 | { | 631 | { |
608 | struct stm32_timer_trigger *priv = iio_priv(indio_dev); | 632 | struct stm32_timer_trigger *priv = iio_priv(indio_dev); |
609 | u32 smcr; | 633 | u32 smcr; |
634 | int mode; | ||
610 | 635 | ||
611 | regmap_read(priv->regmap, TIM_SMCR, &smcr); | 636 | regmap_read(priv->regmap, TIM_SMCR, &smcr); |
612 | smcr &= TIM_SMCR_SMS; | 637 | mode = (smcr & TIM_SMCR_SMS) - 1; |
638 | if ((mode < 0) || (mode > ARRAY_SIZE(stm32_quadrature_modes))) | ||
639 | return -EINVAL; | ||
613 | 640 | ||
614 | return smcr - 1; | 641 | return mode; |
615 | } | 642 | } |
616 | 643 | ||
617 | static const struct iio_enum stm32_quadrature_mode_enum = { | 644 | static const struct iio_enum stm32_quadrature_mode_enum = { |
@@ -628,13 +655,20 @@ static const char *const stm32_count_direction_states[] = { | |||
628 | 655 | ||
629 | static int stm32_set_count_direction(struct iio_dev *indio_dev, | 656 | static int stm32_set_count_direction(struct iio_dev *indio_dev, |
630 | const struct iio_chan_spec *chan, | 657 | const struct iio_chan_spec *chan, |
631 | unsigned int mode) | 658 | unsigned int dir) |
632 | { | 659 | { |
633 | struct stm32_timer_trigger *priv = iio_priv(indio_dev); | 660 | struct stm32_timer_trigger *priv = iio_priv(indio_dev); |
661 | u32 val; | ||
662 | int mode; | ||
634 | 663 | ||
635 | regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_DIR, mode); | 664 | /* In encoder mode, direction is RO (given by TI1/TI2 signals) */ |
665 | regmap_read(priv->regmap, TIM_SMCR, &val); | ||
666 | mode = (val & TIM_SMCR_SMS) - 1; | ||
667 | if ((mode >= 0) || (mode < ARRAY_SIZE(stm32_quadrature_modes))) | ||
668 | return -EBUSY; | ||
636 | 669 | ||
637 | return 0; | 670 | return regmap_update_bits(priv->regmap, TIM_CR1, TIM_CR1_DIR, |
671 | dir ? TIM_CR1_DIR : 0); | ||
638 | } | 672 | } |
639 | 673 | ||
640 | static int stm32_get_count_direction(struct iio_dev *indio_dev, | 674 | static int stm32_get_count_direction(struct iio_dev *indio_dev, |
@@ -645,7 +679,7 @@ static int stm32_get_count_direction(struct iio_dev *indio_dev, | |||
645 | 679 | ||
646 | regmap_read(priv->regmap, TIM_CR1, &cr1); | 680 | regmap_read(priv->regmap, TIM_CR1, &cr1); |
647 | 681 | ||
648 | return (cr1 & TIM_CR1_DIR); | 682 | return ((cr1 & TIM_CR1_DIR) ? 1 : 0); |
649 | } | 683 | } |
650 | 684 | ||
651 | static const struct iio_enum stm32_count_direction_enum = { | 685 | static const struct iio_enum stm32_count_direction_enum = { |
@@ -708,7 +742,9 @@ static const struct iio_chan_spec_ext_info stm32_trigger_count_info[] = { | |||
708 | static const struct iio_chan_spec stm32_trigger_channel = { | 742 | static const struct iio_chan_spec stm32_trigger_channel = { |
709 | .type = IIO_COUNT, | 743 | .type = IIO_COUNT, |
710 | .channel = 0, | 744 | .channel = 0, |
711 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), | 745 | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | |
746 | BIT(IIO_CHAN_INFO_ENABLE) | | ||
747 | BIT(IIO_CHAN_INFO_SCALE), | ||
712 | .ext_info = stm32_trigger_count_info, | 748 | .ext_info = stm32_trigger_count_info, |
713 | .indexed = 1 | 749 | .indexed = 1 |
714 | }; | 750 | }; |