| .. | .. |
|---|
| 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, |
|---|