.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Driver for the Asahi Kasei EMD Corporation AK8974 |
---|
3 | 4 | * and Aichi Steel AMI305 magnetometer chips. |
---|
.. | .. |
---|
11 | 12 | * Author: Linus Walleij <linus.walleij@linaro.org> |
---|
12 | 13 | */ |
---|
13 | 14 | #include <linux/module.h> |
---|
| 15 | +#include <linux/mod_devicetable.h> |
---|
14 | 16 | #include <linux/kernel.h> |
---|
15 | 17 | #include <linux/i2c.h> |
---|
16 | 18 | #include <linux/interrupt.h> |
---|
.. | .. |
---|
48 | 50 | #define AK8974_WHOAMI_VALUE_AMI306 0x46 |
---|
49 | 51 | #define AK8974_WHOAMI_VALUE_AMI305 0x47 |
---|
50 | 52 | #define AK8974_WHOAMI_VALUE_AK8974 0x48 |
---|
| 53 | +#define AK8974_WHOAMI_VALUE_HSCDTD008A 0x49 |
---|
51 | 54 | |
---|
52 | 55 | #define AK8974_DATA_X 0x10 |
---|
53 | 56 | #define AK8974_DATA_Y 0x12 |
---|
.. | .. |
---|
139 | 142 | #define AK8974_INT_CTRL_PULSE BIT(1) /* 0 = latched; 1 = pulse (50 usec) */ |
---|
140 | 143 | #define AK8974_INT_CTRL_RESDEF (AK8974_INT_CTRL_XYZEN | AK8974_INT_CTRL_POL) |
---|
141 | 144 | |
---|
| 145 | +/* HSCDTD008A-specific control register */ |
---|
| 146 | +#define HSCDTD008A_CTRL4 0x1E |
---|
| 147 | +#define HSCDTD008A_CTRL4_MMD BIT(7) /* must be set to 1 */ |
---|
| 148 | +#define HSCDTD008A_CTRL4_RANGE BIT(4) /* 0 = 14-bit output; 1 = 15-bit output */ |
---|
| 149 | +#define HSCDTD008A_CTRL4_RESDEF (HSCDTD008A_CTRL4_MMD | HSCDTD008A_CTRL4_RANGE) |
---|
| 150 | + |
---|
142 | 151 | /* The AMI305 has elaborate FW version and serial number registers */ |
---|
143 | 152 | #define AMI305_VER 0xE8 |
---|
144 | 153 | #define AMI305_SN 0xEA |
---|
.. | .. |
---|
172 | 181 | * @drdy_irq: uses the DRDY IRQ line |
---|
173 | 182 | * @drdy_complete: completion for DRDY |
---|
174 | 183 | * @drdy_active_low: the DRDY IRQ is active low |
---|
| 184 | + * @scan: timestamps |
---|
175 | 185 | */ |
---|
176 | 186 | struct ak8974 { |
---|
177 | 187 | struct i2c_client *i2c; |
---|
.. | .. |
---|
245 | 255 | ret = regmap_write(ak8974->map, AK8974_CTRL3, AK8974_CTRL3_RESDEF); |
---|
246 | 256 | if (ret) |
---|
247 | 257 | return ret; |
---|
248 | | - ret = regmap_write(ak8974->map, AK8974_INT_CTRL, |
---|
249 | | - AK8974_INT_CTRL_RESDEF); |
---|
250 | | - if (ret) |
---|
251 | | - return ret; |
---|
| 258 | + if (ak8974->variant != AK8974_WHOAMI_VALUE_HSCDTD008A) { |
---|
| 259 | + ret = regmap_write(ak8974->map, AK8974_INT_CTRL, |
---|
| 260 | + AK8974_INT_CTRL_RESDEF); |
---|
| 261 | + if (ret) |
---|
| 262 | + return ret; |
---|
| 263 | + } else { |
---|
| 264 | + ret = regmap_write(ak8974->map, HSCDTD008A_CTRL4, |
---|
| 265 | + HSCDTD008A_CTRL4_RESDEF); |
---|
| 266 | + if (ret) |
---|
| 267 | + return ret; |
---|
| 268 | + } |
---|
252 | 269 | |
---|
253 | 270 | /* After reset, power off is default state */ |
---|
254 | 271 | return ak8974_set_power(ak8974, AK8974_PWR_OFF); |
---|
.. | .. |
---|
271 | 288 | if (ret) |
---|
272 | 289 | return ret; |
---|
273 | 290 | } |
---|
| 291 | + if (ak8974->variant == AK8974_WHOAMI_VALUE_HSCDTD008A) |
---|
| 292 | + return 0; |
---|
274 | 293 | ret = regmap_write(ak8974->map, AK8974_INT_CTRL, AK8974_INT_CTRL_POL); |
---|
275 | 294 | if (ret) |
---|
276 | 295 | return ret; |
---|
.. | .. |
---|
481 | 500 | switch (whoami) { |
---|
482 | 501 | case AK8974_WHOAMI_VALUE_AMI306: |
---|
483 | 502 | name = "ami306"; |
---|
484 | | - /* fall-through */ |
---|
| 503 | + fallthrough; |
---|
485 | 504 | case AK8974_WHOAMI_VALUE_AMI305: |
---|
486 | 505 | ret = regmap_read(ak8974->map, AMI305_VER, &fw); |
---|
487 | 506 | if (ret) |
---|
.. | .. |
---|
498 | 517 | case AK8974_WHOAMI_VALUE_AK8974: |
---|
499 | 518 | name = "ak8974"; |
---|
500 | 519 | dev_info(&ak8974->i2c->dev, "detected AK8974\n"); |
---|
| 520 | + break; |
---|
| 521 | + case AK8974_WHOAMI_VALUE_HSCDTD008A: |
---|
| 522 | + name = "hscdtd008a"; |
---|
| 523 | + dev_info(&ak8974->i2c->dev, "detected hscdtd008a\n"); |
---|
501 | 524 | break; |
---|
502 | 525 | default: |
---|
503 | 526 | dev_err(&ak8974->i2c->dev, "unsupported device (%02x) ", |
---|
.. | .. |
---|
538 | 561 | return 0; |
---|
539 | 562 | } |
---|
540 | 563 | |
---|
| 564 | +static int ak8974_measure_channel(struct ak8974 *ak8974, unsigned long address, |
---|
| 565 | + int *val) |
---|
| 566 | +{ |
---|
| 567 | + __le16 hw_values[3]; |
---|
| 568 | + int ret; |
---|
| 569 | + |
---|
| 570 | + pm_runtime_get_sync(&ak8974->i2c->dev); |
---|
| 571 | + mutex_lock(&ak8974->lock); |
---|
| 572 | + |
---|
| 573 | + /* |
---|
| 574 | + * We read all axes and discard all but one, for optimized |
---|
| 575 | + * reading, use the triggered buffer. |
---|
| 576 | + */ |
---|
| 577 | + ret = ak8974_trigmeas(ak8974); |
---|
| 578 | + if (ret) |
---|
| 579 | + goto out_unlock; |
---|
| 580 | + ret = ak8974_getresult(ak8974, hw_values); |
---|
| 581 | + if (ret) |
---|
| 582 | + goto out_unlock; |
---|
| 583 | + /* |
---|
| 584 | + * This explicit cast to (s16) is necessary as the measurement |
---|
| 585 | + * is done in 2's complement with positive and negative values. |
---|
| 586 | + * The follwing assignment to *val will then convert the signed |
---|
| 587 | + * s16 value to a signed int value. |
---|
| 588 | + */ |
---|
| 589 | + *val = (s16)le16_to_cpu(hw_values[address]); |
---|
| 590 | +out_unlock: |
---|
| 591 | + mutex_unlock(&ak8974->lock); |
---|
| 592 | + pm_runtime_mark_last_busy(&ak8974->i2c->dev); |
---|
| 593 | + pm_runtime_put_autosuspend(&ak8974->i2c->dev); |
---|
| 594 | + |
---|
| 595 | + return ret; |
---|
| 596 | +} |
---|
| 597 | + |
---|
541 | 598 | static int ak8974_read_raw(struct iio_dev *indio_dev, |
---|
542 | 599 | struct iio_chan_spec const *chan, |
---|
543 | 600 | int *val, int *val2, |
---|
544 | 601 | long mask) |
---|
545 | 602 | { |
---|
546 | 603 | struct ak8974 *ak8974 = iio_priv(indio_dev); |
---|
547 | | - __le16 hw_values[3]; |
---|
548 | | - int ret = -EINVAL; |
---|
549 | | - |
---|
550 | | - pm_runtime_get_sync(&ak8974->i2c->dev); |
---|
551 | | - mutex_lock(&ak8974->lock); |
---|
| 604 | + int ret; |
---|
552 | 605 | |
---|
553 | 606 | switch (mask) { |
---|
554 | 607 | case IIO_CHAN_INFO_RAW: |
---|
555 | 608 | if (chan->address > 2) { |
---|
556 | 609 | dev_err(&ak8974->i2c->dev, "faulty channel address\n"); |
---|
557 | | - ret = -EIO; |
---|
558 | | - goto out_unlock; |
---|
| 610 | + return -EIO; |
---|
559 | 611 | } |
---|
560 | | - ret = ak8974_trigmeas(ak8974); |
---|
| 612 | + ret = ak8974_measure_channel(ak8974, chan->address, val); |
---|
561 | 613 | if (ret) |
---|
562 | | - goto out_unlock; |
---|
563 | | - ret = ak8974_getresult(ak8974, hw_values); |
---|
564 | | - if (ret) |
---|
565 | | - goto out_unlock; |
---|
566 | | - |
---|
567 | | - /* |
---|
568 | | - * We read all axes and discard all but one, for optimized |
---|
569 | | - * reading, use the triggered buffer. |
---|
570 | | - */ |
---|
571 | | - *val = (s16)le16_to_cpu(hw_values[chan->address]); |
---|
572 | | - |
---|
573 | | - ret = IIO_VAL_INT; |
---|
| 614 | + return ret; |
---|
| 615 | + return IIO_VAL_INT; |
---|
| 616 | + case IIO_CHAN_INFO_SCALE: |
---|
| 617 | + switch (ak8974->variant) { |
---|
| 618 | + case AK8974_WHOAMI_VALUE_AMI306: |
---|
| 619 | + case AK8974_WHOAMI_VALUE_AMI305: |
---|
| 620 | + /* |
---|
| 621 | + * The datasheet for AMI305 and AMI306, page 6 |
---|
| 622 | + * specifies the range of the sensor to be |
---|
| 623 | + * +/- 12 Gauss. |
---|
| 624 | + */ |
---|
| 625 | + *val = 12; |
---|
| 626 | + /* |
---|
| 627 | + * 12 bits are used, +/- 2^11 |
---|
| 628 | + * [ -2048 .. 2047 ] (manual page 20) |
---|
| 629 | + * [ 0xf800 .. 0x07ff ] |
---|
| 630 | + */ |
---|
| 631 | + *val2 = 11; |
---|
| 632 | + return IIO_VAL_FRACTIONAL_LOG2; |
---|
| 633 | + case AK8974_WHOAMI_VALUE_HSCDTD008A: |
---|
| 634 | + /* |
---|
| 635 | + * The datasheet for HSCDTF008A, page 3 specifies the |
---|
| 636 | + * range of the sensor as +/- 2.4 mT per axis, which |
---|
| 637 | + * corresponds to +/- 2400 uT = +/- 24 Gauss. |
---|
| 638 | + */ |
---|
| 639 | + *val = 24; |
---|
| 640 | + /* |
---|
| 641 | + * 15 bits are used (set up in CTRL4), +/- 2^14 |
---|
| 642 | + * [ -16384 .. 16383 ] (manual page 24) |
---|
| 643 | + * [ 0xc000 .. 0x3fff ] |
---|
| 644 | + */ |
---|
| 645 | + *val2 = 14; |
---|
| 646 | + return IIO_VAL_FRACTIONAL_LOG2; |
---|
| 647 | + default: |
---|
| 648 | + /* GUESSING +/- 12 Gauss */ |
---|
| 649 | + *val = 12; |
---|
| 650 | + /* GUESSING 12 bits ADC +/- 2^11 */ |
---|
| 651 | + *val2 = 11; |
---|
| 652 | + return IIO_VAL_FRACTIONAL_LOG2; |
---|
| 653 | + } |
---|
| 654 | + break; |
---|
| 655 | + default: |
---|
| 656 | + /* Unknown request */ |
---|
| 657 | + break; |
---|
574 | 658 | } |
---|
575 | 659 | |
---|
576 | | - out_unlock: |
---|
577 | | - mutex_unlock(&ak8974->lock); |
---|
578 | | - pm_runtime_mark_last_busy(&ak8974->i2c->dev); |
---|
579 | | - pm_runtime_put_autosuspend(&ak8974->i2c->dev); |
---|
580 | | - |
---|
581 | | - return ret; |
---|
| 660 | + return -EINVAL; |
---|
582 | 661 | } |
---|
583 | 662 | |
---|
584 | 663 | static void ak8974_fill_buffer(struct iio_dev *indio_dev) |
---|
.. | .. |
---|
634 | 713 | { }, |
---|
635 | 714 | }; |
---|
636 | 715 | |
---|
637 | | -#define AK8974_AXIS_CHANNEL(axis, index) \ |
---|
| 716 | +#define AK8974_AXIS_CHANNEL(axis, index, bits) \ |
---|
638 | 717 | { \ |
---|
639 | 718 | .type = IIO_MAGN, \ |
---|
640 | 719 | .modified = 1, \ |
---|
641 | 720 | .channel2 = IIO_MOD_##axis, \ |
---|
642 | | - .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ |
---|
| 721 | + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ |
---|
| 722 | + BIT(IIO_CHAN_INFO_SCALE), \ |
---|
643 | 723 | .ext_info = ak8974_ext_info, \ |
---|
644 | 724 | .address = index, \ |
---|
645 | 725 | .scan_index = index, \ |
---|
646 | 726 | .scan_type = { \ |
---|
647 | 727 | .sign = 's', \ |
---|
648 | | - .realbits = 16, \ |
---|
| 728 | + .realbits = bits, \ |
---|
649 | 729 | .storagebits = 16, \ |
---|
650 | 730 | .endianness = IIO_LE \ |
---|
651 | 731 | }, \ |
---|
652 | 732 | } |
---|
653 | 733 | |
---|
654 | | -static const struct iio_chan_spec ak8974_channels[] = { |
---|
655 | | - AK8974_AXIS_CHANNEL(X, 0), |
---|
656 | | - AK8974_AXIS_CHANNEL(Y, 1), |
---|
657 | | - AK8974_AXIS_CHANNEL(Z, 2), |
---|
| 734 | +/* |
---|
| 735 | + * We have no datasheet for the AK8974 but we guess that its |
---|
| 736 | + * ADC is 12 bits. The AMI305 and AMI306 certainly has 12bit |
---|
| 737 | + * ADC. |
---|
| 738 | + */ |
---|
| 739 | +static const struct iio_chan_spec ak8974_12_bits_channels[] = { |
---|
| 740 | + AK8974_AXIS_CHANNEL(X, 0, 12), |
---|
| 741 | + AK8974_AXIS_CHANNEL(Y, 1, 12), |
---|
| 742 | + AK8974_AXIS_CHANNEL(Z, 2, 12), |
---|
| 743 | + IIO_CHAN_SOFT_TIMESTAMP(3), |
---|
| 744 | +}; |
---|
| 745 | + |
---|
| 746 | +/* |
---|
| 747 | + * The HSCDTD008A has 15 bits resolution the way we set it up |
---|
| 748 | + * in CTRL4. |
---|
| 749 | + */ |
---|
| 750 | +static const struct iio_chan_spec ak8974_15_bits_channels[] = { |
---|
| 751 | + AK8974_AXIS_CHANNEL(X, 0, 15), |
---|
| 752 | + AK8974_AXIS_CHANNEL(Y, 1, 15), |
---|
| 753 | + AK8974_AXIS_CHANNEL(Z, 2, 15), |
---|
658 | 754 | IIO_CHAN_SOFT_TIMESTAMP(3), |
---|
659 | 755 | }; |
---|
660 | 756 | |
---|
.. | .. |
---|
677 | 773 | case AK8974_INT_CTRL: |
---|
678 | 774 | case AK8974_INT_THRES: |
---|
679 | 775 | case AK8974_INT_THRES + 1: |
---|
| 776 | + return true; |
---|
680 | 777 | case AK8974_PRESET: |
---|
681 | 778 | case AK8974_PRESET + 1: |
---|
682 | | - return true; |
---|
| 779 | + return ak8974->variant != AK8974_WHOAMI_VALUE_HSCDTD008A; |
---|
683 | 780 | case AK8974_OFFSET_X: |
---|
684 | 781 | case AK8974_OFFSET_X + 1: |
---|
685 | 782 | case AK8974_OFFSET_Y: |
---|
686 | 783 | case AK8974_OFFSET_Y + 1: |
---|
687 | 784 | case AK8974_OFFSET_Z: |
---|
688 | 785 | case AK8974_OFFSET_Z + 1: |
---|
689 | | - if (ak8974->variant == AK8974_WHOAMI_VALUE_AK8974) |
---|
690 | | - return true; |
---|
691 | | - return false; |
---|
| 786 | + return ak8974->variant == AK8974_WHOAMI_VALUE_AK8974 || |
---|
| 787 | + ak8974->variant == AK8974_WHOAMI_VALUE_HSCDTD008A; |
---|
692 | 788 | case AMI305_OFFSET_X: |
---|
693 | 789 | case AMI305_OFFSET_X + 1: |
---|
694 | 790 | case AMI305_OFFSET_Y: |
---|
.. | .. |
---|
737 | 833 | ak8974->i2c = i2c; |
---|
738 | 834 | mutex_init(&ak8974->lock); |
---|
739 | 835 | |
---|
740 | | - ret = of_iio_read_mount_matrix(&i2c->dev, |
---|
741 | | - "mount-matrix", |
---|
742 | | - &ak8974->orientation); |
---|
| 836 | + ret = iio_read_mount_matrix(&i2c->dev, "mount-matrix", |
---|
| 837 | + &ak8974->orientation); |
---|
743 | 838 | if (ret) |
---|
744 | 839 | return ret; |
---|
745 | 840 | |
---|
.. | .. |
---|
749 | 844 | ret = devm_regulator_bulk_get(&i2c->dev, |
---|
750 | 845 | ARRAY_SIZE(ak8974->regs), |
---|
751 | 846 | ak8974->regs); |
---|
752 | | - if (ret < 0) { |
---|
753 | | - dev_err(&i2c->dev, "cannot get regulators\n"); |
---|
754 | | - return ret; |
---|
755 | | - } |
---|
| 847 | + if (ret < 0) |
---|
| 848 | + return dev_err_probe(&i2c->dev, ret, "cannot get regulators\n"); |
---|
756 | 849 | |
---|
757 | 850 | ret = regulator_bulk_enable(ARRAY_SIZE(ak8974->regs), ak8974->regs); |
---|
758 | 851 | if (ret < 0) { |
---|
.. | .. |
---|
795 | 888 | goto disable_pm; |
---|
796 | 889 | } |
---|
797 | 890 | |
---|
798 | | - indio_dev->dev.parent = &i2c->dev; |
---|
799 | | - indio_dev->channels = ak8974_channels; |
---|
800 | | - indio_dev->num_channels = ARRAY_SIZE(ak8974_channels); |
---|
| 891 | + switch (ak8974->variant) { |
---|
| 892 | + case AK8974_WHOAMI_VALUE_AMI306: |
---|
| 893 | + case AK8974_WHOAMI_VALUE_AMI305: |
---|
| 894 | + indio_dev->channels = ak8974_12_bits_channels; |
---|
| 895 | + indio_dev->num_channels = ARRAY_SIZE(ak8974_12_bits_channels); |
---|
| 896 | + break; |
---|
| 897 | + case AK8974_WHOAMI_VALUE_HSCDTD008A: |
---|
| 898 | + indio_dev->channels = ak8974_15_bits_channels; |
---|
| 899 | + indio_dev->num_channels = ARRAY_SIZE(ak8974_15_bits_channels); |
---|
| 900 | + break; |
---|
| 901 | + default: |
---|
| 902 | + indio_dev->channels = ak8974_12_bits_channels; |
---|
| 903 | + indio_dev->num_channels = ARRAY_SIZE(ak8974_12_bits_channels); |
---|
| 904 | + break; |
---|
| 905 | + } |
---|
801 | 906 | indio_dev->info = &ak8974_info; |
---|
802 | 907 | indio_dev->available_scan_masks = ak8974_scan_masks; |
---|
803 | 908 | indio_dev->modes = INDIO_DIRECT_MODE; |
---|
.. | .. |
---|
931 | 1036 | {"ami305", 0 }, |
---|
932 | 1037 | {"ami306", 0 }, |
---|
933 | 1038 | {"ak8974", 0 }, |
---|
| 1039 | + {"hscdtd008a", 0 }, |
---|
934 | 1040 | {} |
---|
935 | 1041 | }; |
---|
936 | 1042 | MODULE_DEVICE_TABLE(i2c, ak8974_id); |
---|
937 | 1043 | |
---|
938 | 1044 | static const struct of_device_id ak8974_of_match[] = { |
---|
939 | 1045 | { .compatible = "asahi-kasei,ak8974", }, |
---|
| 1046 | + { .compatible = "alps,hscdtd008a", }, |
---|
940 | 1047 | {} |
---|
941 | 1048 | }; |
---|
942 | 1049 | MODULE_DEVICE_TABLE(of, ak8974_of_match); |
---|
.. | .. |
---|
945 | 1052 | .driver = { |
---|
946 | 1053 | .name = "ak8974", |
---|
947 | 1054 | .pm = &ak8974_dev_pm_ops, |
---|
948 | | - .of_match_table = of_match_ptr(ak8974_of_match), |
---|
| 1055 | + .of_match_table = ak8974_of_match, |
---|
949 | 1056 | }, |
---|
950 | 1057 | .probe = ak8974_probe, |
---|
951 | 1058 | .remove = ak8974_remove, |
---|