Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

iio: imu: adis16475.c: Add delta angle and delta velocity channels

Add support for delta angle and delta velocity raw and buffer
readings to adis16475 driver.

Signed-off-by: Ramona Bolboaca <ramona.bolboaca@analog.com>
Reviewed-by: Nuno Sa <nuno.sa@analog.com>
Link: https://lore.kernel.org/r/20230808075059.645525-4-ramona.bolboaca@analog.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Ramona Bolboaca and committed by
Jonathan Cameron
8f6bc87d 94a39f2c

+146 -19
+146 -19
drivers/iio/imu/adis16475.c
··· 31 31 #define ADIS16475_REG_Y_ACCEL_L 0x14 32 32 #define ADIS16475_REG_Z_ACCEL_L 0x18 33 33 #define ADIS16475_REG_TEMP_OUT 0x1c 34 + #define ADIS16475_REG_X_DELTANG_L 0x24 35 + #define ADIS16475_REG_Y_DELTANG_L 0x28 36 + #define ADIS16475_REG_Z_DELTANG_L 0x2C 37 + #define ADIS16475_REG_X_DELTVEL_L 0x30 38 + #define ADIS16475_REG_Y_DELTVEL_L 0x34 39 + #define ADIS16475_REG_Z_DELTVEL_L 0x38 34 40 #define ADIS16475_REG_X_GYRO_BIAS_L 0x40 35 41 #define ADIS16475_REG_Y_GYRO_BIAS_L 0x44 36 42 #define ADIS16475_REG_Z_GYRO_BIAS_L 0x48 ··· 61 55 #define ADIS16475_REG_PROD_ID 0x72 62 56 #define ADIS16475_REG_SERIAL_NUM 0x74 63 57 #define ADIS16475_REG_FLASH_CNT 0x7c 58 + #define ADIS16500_BURST_DATA_SEL_MASK BIT(8) 64 59 #define ADIS16500_BURST32_MASK BIT(9) 65 60 #define ADIS16500_BURST32(x) FIELD_PREP(ADIS16500_BURST32_MASK, x) 66 61 /* number of data elements in burst mode */ ··· 72 65 #define ADIS16475_BURST_MAX_SPEED 1000000 73 66 #define ADIS16475_LSB_DEC_MASK BIT(0) 74 67 #define ADIS16475_LSB_FIR_MASK BIT(1) 68 + #define ADIS16500_BURST_DATA_SEL_0_CHN_MASK GENMASK(5, 0) 69 + #define ADIS16500_BURST_DATA_SEL_1_CHN_MASK GENMASK(12, 7) 75 70 76 71 enum { 77 72 ADIS16475_SYNC_DIRECT = 1, ··· 93 84 const struct adis16475_sync *sync; 94 85 const struct adis_data adis_data; 95 86 const char *name; 87 + #define ADIS16475_HAS_BURST32 BIT(0) 88 + #define ADIS16475_HAS_BURST_DELTA_DATA BIT(1) 89 + const long flags; 96 90 u32 num_channels; 97 91 u32 gyro_max_val; 98 92 u32 gyro_max_scale; 99 93 u32 accel_max_val; 100 94 u32 accel_max_scale; 101 95 u32 temp_scale; 96 + u32 deltang_max_val; 97 + u32 deltvel_max_val; 102 98 u32 int_clk; 103 99 u16 max_dec; 104 100 u8 num_sync; 105 - bool has_burst32; 106 101 }; 107 102 108 103 struct adis16475 { ··· 128 115 ADIS16475_SCAN_ACCEL_Y, 129 116 ADIS16475_SCAN_ACCEL_Z, 130 117 ADIS16475_SCAN_TEMP, 118 + ADIS16475_SCAN_DELTANG_X, 119 + ADIS16475_SCAN_DELTANG_Y, 120 + ADIS16475_SCAN_DELTANG_Z, 121 + ADIS16475_SCAN_DELTVEL_X, 122 + ADIS16475_SCAN_DELTVEL_Y, 123 + ADIS16475_SCAN_DELTVEL_Z, 131 124 }; 132 125 133 126 static bool low_rate_allow; ··· 470 451 case IIO_TEMP: 471 452 *val = st->info->temp_scale; 472 453 return IIO_VAL_INT; 454 + case IIO_DELTA_ANGL: 455 + *val = st->info->deltang_max_val; 456 + *val2 = 31; 457 + return IIO_VAL_FRACTIONAL_LOG2; 458 + case IIO_DELTA_VELOCITY: 459 + *val = st->info->deltvel_max_val; 460 + *val2 = 31; 461 + return IIO_VAL_FRACTIONAL_LOG2; 473 462 default: 474 463 return -EINVAL; 475 464 } ··· 578 551 }, \ 579 552 } 580 553 554 + #define ADIS16475_MOD_CHAN_DELTA(_type, _mod, _address, _si, _r_bits, _s_bits) { \ 555 + .type = (_type), \ 556 + .modified = 1, \ 557 + .channel2 = (_mod), \ 558 + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ 559 + .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ 560 + .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ) | \ 561 + BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY), \ 562 + .address = (_address), \ 563 + .scan_index = _si, \ 564 + .scan_type = { \ 565 + .sign = 's', \ 566 + .realbits = (_r_bits), \ 567 + .storagebits = (_s_bits), \ 568 + .endianness = IIO_BE, \ 569 + }, \ 570 + } 571 + 572 + #define ADIS16475_DELTANG_CHAN(_mod) \ 573 + ADIS16475_MOD_CHAN_DELTA(IIO_DELTA_ANGL, IIO_MOD_ ## _mod, \ 574 + ADIS16475_REG_ ## _mod ## _DELTANG_L, ADIS16475_SCAN_DELTANG_ ## _mod, 32, 32) 575 + 576 + #define ADIS16475_DELTVEL_CHAN(_mod) \ 577 + ADIS16475_MOD_CHAN_DELTA(IIO_DELTA_VELOCITY, IIO_MOD_ ## _mod, \ 578 + ADIS16475_REG_ ## _mod ## _DELTVEL_L, ADIS16475_SCAN_DELTVEL_ ## _mod, 32, 32) 579 + 581 580 static const struct iio_chan_spec adis16475_channels[] = { 582 581 ADIS16475_GYRO_CHANNEL(X), 583 582 ADIS16475_GYRO_CHANNEL(Y), ··· 612 559 ADIS16475_ACCEL_CHANNEL(Y), 613 560 ADIS16475_ACCEL_CHANNEL(Z), 614 561 ADIS16475_TEMP_CHANNEL(), 615 - IIO_CHAN_SOFT_TIMESTAMP(7) 562 + ADIS16475_DELTANG_CHAN(X), 563 + ADIS16475_DELTANG_CHAN(Y), 564 + ADIS16475_DELTANG_CHAN(Z), 565 + ADIS16475_DELTVEL_CHAN(X), 566 + ADIS16475_DELTVEL_CHAN(Y), 567 + ADIS16475_DELTVEL_CHAN(Z), 568 + IIO_CHAN_SOFT_TIMESTAMP(13) 616 569 }; 617 570 618 571 enum adis16475_variant { ··· 721 662 .accel_max_val = 1, 722 663 .accel_max_scale = IIO_M_S_2_TO_G(800 << 16), 723 664 .temp_scale = 100, 665 + .deltang_max_val = IIO_DEGREE_TO_RAD(2160), 666 + .deltvel_max_val = 400, 724 667 .int_clk = 2000, 725 668 .max_dec = 1999, 726 669 .sync = adis16475_sync_mode, ··· 738 677 .accel_max_val = 1, 739 678 .accel_max_scale = IIO_M_S_2_TO_G(4000 << 16), 740 679 .temp_scale = 100, 680 + .deltang_max_val = IIO_DEGREE_TO_RAD(360), 681 + .deltvel_max_val = 100, 741 682 .int_clk = 2000, 742 683 .max_dec = 1999, 743 684 .sync = adis16475_sync_mode, ··· 755 692 .accel_max_val = 1, 756 693 .accel_max_scale = IIO_M_S_2_TO_G(4000 << 16), 757 694 .temp_scale = 100, 695 + .deltang_max_val = IIO_DEGREE_TO_RAD(720), 696 + .deltvel_max_val = 100, 758 697 .int_clk = 2000, 759 698 .max_dec = 1999, 760 699 .sync = adis16475_sync_mode, ··· 772 707 .accel_max_val = 1, 773 708 .accel_max_scale = IIO_M_S_2_TO_G(4000 << 16), 774 709 .temp_scale = 100, 710 + .deltang_max_val = IIO_DEGREE_TO_RAD(2160), 711 + .deltvel_max_val = 100, 775 712 .int_clk = 2000, 776 713 .max_dec = 1999, 777 714 .sync = adis16475_sync_mode, ··· 789 722 .accel_max_val = 1, 790 723 .accel_max_scale = IIO_M_S_2_TO_G(800 << 16), 791 724 .temp_scale = 100, 725 + .deltang_max_val = IIO_DEGREE_TO_RAD(360), 726 + .deltvel_max_val = 400, 792 727 .int_clk = 2000, 793 728 .max_dec = 1999, 794 729 .sync = adis16475_sync_mode, 795 730 .num_sync = ARRAY_SIZE(adis16475_sync_mode), 796 - .has_burst32 = true, 731 + .flags = ADIS16475_HAS_BURST32 | ADIS16475_HAS_BURST_DELTA_DATA, 797 732 .adis_data = ADIS16475_DATA(16477, &adis16475_timeouts), 798 733 }, 799 734 [ADIS16477_2] = { ··· 807 738 .accel_max_val = 1, 808 739 .accel_max_scale = IIO_M_S_2_TO_G(800 << 16), 809 740 .temp_scale = 100, 741 + .deltang_max_val = IIO_DEGREE_TO_RAD(720), 742 + .deltvel_max_val = 400, 810 743 .int_clk = 2000, 811 744 .max_dec = 1999, 812 745 .sync = adis16475_sync_mode, 813 746 .num_sync = ARRAY_SIZE(adis16475_sync_mode), 814 - .has_burst32 = true, 747 + .flags = ADIS16475_HAS_BURST32 | ADIS16475_HAS_BURST_DELTA_DATA, 815 748 .adis_data = ADIS16475_DATA(16477, &adis16475_timeouts), 816 749 }, 817 750 [ADIS16477_3] = { ··· 825 754 .accel_max_val = 1, 826 755 .accel_max_scale = IIO_M_S_2_TO_G(800 << 16), 827 756 .temp_scale = 100, 757 + .deltang_max_val = IIO_DEGREE_TO_RAD(2160), 758 + .deltvel_max_val = 400, 828 759 .int_clk = 2000, 829 760 .max_dec = 1999, 830 761 .sync = adis16475_sync_mode, 831 762 .num_sync = ARRAY_SIZE(adis16475_sync_mode), 832 - .has_burst32 = true, 763 + .flags = ADIS16475_HAS_BURST32 | ADIS16475_HAS_BURST_DELTA_DATA, 833 764 .adis_data = ADIS16475_DATA(16477, &adis16475_timeouts), 834 765 }, 835 766 [ADIS16465_1] = { ··· 843 770 .accel_max_val = 1, 844 771 .accel_max_scale = IIO_M_S_2_TO_G(4000 << 16), 845 772 .temp_scale = 100, 773 + .deltang_max_val = IIO_DEGREE_TO_RAD(360), 774 + .deltvel_max_val = 100, 846 775 .int_clk = 2000, 847 776 .max_dec = 1999, 848 777 .sync = adis16475_sync_mode, ··· 860 785 .accel_max_val = 1, 861 786 .accel_max_scale = IIO_M_S_2_TO_G(4000 << 16), 862 787 .temp_scale = 100, 788 + .deltang_max_val = IIO_DEGREE_TO_RAD(720), 789 + .deltvel_max_val = 100, 863 790 .int_clk = 2000, 864 791 .max_dec = 1999, 865 792 .sync = adis16475_sync_mode, ··· 877 800 .accel_max_val = 1, 878 801 .accel_max_scale = IIO_M_S_2_TO_G(4000 << 16), 879 802 .temp_scale = 100, 803 + .deltang_max_val = IIO_DEGREE_TO_RAD(2160), 804 + .deltvel_max_val = 100, 880 805 .int_clk = 2000, 881 806 .max_dec = 1999, 882 807 .sync = adis16475_sync_mode, ··· 894 815 .accel_max_val = 1, 895 816 .accel_max_scale = IIO_M_S_2_TO_G(800 << 16), 896 817 .temp_scale = 100, 818 + .deltang_max_val = IIO_DEGREE_TO_RAD(360), 819 + .deltvel_max_val = 400, 897 820 .int_clk = 2000, 898 821 .max_dec = 1999, 899 822 .sync = adis16475_sync_mode, ··· 911 830 .accel_max_val = 1, 912 831 .accel_max_scale = IIO_M_S_2_TO_G(800 << 16), 913 832 .temp_scale = 100, 833 + .deltang_max_val = IIO_DEGREE_TO_RAD(720), 834 + .deltvel_max_val = 400, 914 835 .int_clk = 2000, 915 836 .max_dec = 1999, 916 837 .sync = adis16475_sync_mode, ··· 928 845 .accel_max_val = 1, 929 846 .accel_max_scale = IIO_M_S_2_TO_G(800 << 16), 930 847 .temp_scale = 100, 848 + .deltang_max_val = IIO_DEGREE_TO_RAD(2160), 849 + .deltvel_max_val = 400, 931 850 .int_clk = 2000, 932 851 .max_dec = 1999, 933 852 .sync = adis16475_sync_mode, ··· 945 860 .accel_max_val = 392, 946 861 .accel_max_scale = 32000 << 16, 947 862 .temp_scale = 100, 863 + .deltang_max_val = IIO_DEGREE_TO_RAD(2160), 864 + .deltvel_max_val = 400, 948 865 .int_clk = 2000, 949 866 .max_dec = 1999, 950 867 .sync = adis16475_sync_mode, 951 868 /* pulse sync not supported */ 952 869 .num_sync = ARRAY_SIZE(adis16475_sync_mode) - 1, 953 - .has_burst32 = true, 870 + .flags = ADIS16475_HAS_BURST32 | ADIS16475_HAS_BURST_DELTA_DATA, 954 871 .adis_data = ADIS16475_DATA(16500, &adis1650x_timeouts), 955 872 }, 956 873 [ADIS16505_1] = { ··· 964 877 .accel_max_val = 78, 965 878 .accel_max_scale = 32000 << 16, 966 879 .temp_scale = 100, 880 + .deltang_max_val = IIO_DEGREE_TO_RAD(360), 881 + .deltvel_max_val = 100, 967 882 .int_clk = 2000, 968 883 .max_dec = 1999, 969 884 .sync = adis16475_sync_mode, 970 885 /* pulse sync not supported */ 971 886 .num_sync = ARRAY_SIZE(adis16475_sync_mode) - 1, 972 - .has_burst32 = true, 887 + .flags = ADIS16475_HAS_BURST32 | ADIS16475_HAS_BURST_DELTA_DATA, 973 888 .adis_data = ADIS16475_DATA(16505, &adis1650x_timeouts), 974 889 }, 975 890 [ADIS16505_2] = { ··· 983 894 .accel_max_val = 78, 984 895 .accel_max_scale = 32000 << 16, 985 896 .temp_scale = 100, 897 + .deltang_max_val = IIO_DEGREE_TO_RAD(720), 898 + .deltvel_max_val = 100, 986 899 .int_clk = 2000, 987 900 .max_dec = 1999, 988 901 .sync = adis16475_sync_mode, 989 902 /* pulse sync not supported */ 990 903 .num_sync = ARRAY_SIZE(adis16475_sync_mode) - 1, 991 - .has_burst32 = true, 904 + .flags = ADIS16475_HAS_BURST32 | ADIS16475_HAS_BURST_DELTA_DATA, 992 905 .adis_data = ADIS16475_DATA(16505, &adis1650x_timeouts), 993 906 }, 994 907 [ADIS16505_3] = { ··· 1002 911 .accel_max_val = 78, 1003 912 .accel_max_scale = 32000 << 16, 1004 913 .temp_scale = 100, 914 + .deltang_max_val = IIO_DEGREE_TO_RAD(2160), 915 + .deltvel_max_val = 100, 1005 916 .int_clk = 2000, 1006 917 .max_dec = 1999, 1007 918 .sync = adis16475_sync_mode, 1008 919 /* pulse sync not supported */ 1009 920 .num_sync = ARRAY_SIZE(adis16475_sync_mode) - 1, 1010 - .has_burst32 = true, 921 + .flags = ADIS16475_HAS_BURST32 | ADIS16475_HAS_BURST_DELTA_DATA, 1011 922 .adis_data = ADIS16475_DATA(16505, &adis1650x_timeouts), 1012 923 }, 1013 924 [ADIS16507_1] = { ··· 1021 928 .accel_max_val = 392, 1022 929 .accel_max_scale = 32000 << 16, 1023 930 .temp_scale = 100, 931 + .deltang_max_val = IIO_DEGREE_TO_RAD(360), 932 + .deltvel_max_val = 400, 1024 933 .int_clk = 2000, 1025 934 .max_dec = 1999, 1026 935 .sync = adis16475_sync_mode, 1027 936 /* pulse sync not supported */ 1028 937 .num_sync = ARRAY_SIZE(adis16475_sync_mode) - 1, 1029 - .has_burst32 = true, 938 + .flags = ADIS16475_HAS_BURST32 | ADIS16475_HAS_BURST_DELTA_DATA, 1030 939 .adis_data = ADIS16475_DATA(16507, &adis1650x_timeouts), 1031 940 }, 1032 941 [ADIS16507_2] = { ··· 1040 945 .accel_max_val = 392, 1041 946 .accel_max_scale = 32000 << 16, 1042 947 .temp_scale = 100, 948 + .deltang_max_val = IIO_DEGREE_TO_RAD(720), 949 + .deltvel_max_val = 400, 1043 950 .int_clk = 2000, 1044 951 .max_dec = 1999, 1045 952 .sync = adis16475_sync_mode, 1046 953 /* pulse sync not supported */ 1047 954 .num_sync = ARRAY_SIZE(adis16475_sync_mode) - 1, 1048 - .has_burst32 = true, 955 + .flags = ADIS16475_HAS_BURST32 | ADIS16475_HAS_BURST_DELTA_DATA, 1049 956 .adis_data = ADIS16475_DATA(16507, &adis1650x_timeouts), 1050 957 }, 1051 958 [ADIS16507_3] = { ··· 1059 962 .accel_max_val = 392, 1060 963 .accel_max_scale = 32000 << 16, 1061 964 .temp_scale = 100, 965 + .deltang_max_val = IIO_DEGREE_TO_RAD(2160), 966 + .deltvel_max_val = 400, 1062 967 .int_clk = 2000, 1063 968 .max_dec = 1999, 1064 969 .sync = adis16475_sync_mode, 1065 970 /* pulse sync not supported */ 1066 971 .num_sync = ARRAY_SIZE(adis16475_sync_mode) - 1, 1067 - .has_burst32 = true, 972 + .flags = ADIS16475_HAS_BURST32 | ADIS16475_HAS_BURST_DELTA_DATA, 1068 973 .adis_data = ADIS16475_DATA(16507, &adis1650x_timeouts), 1069 974 }, 1070 975 }; 1071 976 977 + static int adis16475_update_scan_mode(struct iio_dev *indio_dev, 978 + const unsigned long *scan_mask) 979 + { 980 + u16 en; 981 + int ret; 982 + struct adis16475 *st = iio_priv(indio_dev); 983 + 984 + if (st->info->flags & ADIS16475_HAS_BURST_DELTA_DATA) { 985 + if ((*scan_mask & ADIS16500_BURST_DATA_SEL_0_CHN_MASK) && 986 + (*scan_mask & ADIS16500_BURST_DATA_SEL_1_CHN_MASK)) 987 + return -EINVAL; 988 + if (*scan_mask & ADIS16500_BURST_DATA_SEL_0_CHN_MASK) 989 + en = FIELD_PREP(ADIS16500_BURST_DATA_SEL_MASK, 0); 990 + else 991 + en = FIELD_PREP(ADIS16500_BURST_DATA_SEL_MASK, 1); 992 + 993 + ret = __adis_update_bits(&st->adis, ADIS16475_REG_MSG_CTRL, 994 + ADIS16500_BURST_DATA_SEL_MASK, en); 995 + if (ret) 996 + return ret; 997 + } 998 + 999 + return adis_update_scan_mode(indio_dev, scan_mask); 1000 + } 1001 + 1072 1002 static const struct iio_info adis16475_info = { 1073 1003 .read_raw = &adis16475_read_raw, 1074 1004 .write_raw = &adis16475_write_raw, 1075 - .update_scan_mode = adis_update_scan_mode, 1005 + .update_scan_mode = adis16475_update_scan_mode, 1076 1006 .debugfs_reg_access = adis_debugfs_reg_access, 1077 1007 }; 1078 1008 ··· 1122 998 int ret; 1123 999 struct adis *adis = &st->adis; 1124 1000 1125 - if (!st->info->has_burst32) 1001 + if (!(st->info->flags & ADIS16475_HAS_BURST32)) 1126 1002 return; 1127 1003 1128 1004 if (st->lsb_flag && !st->burst32) { ··· 1168 1044 struct iio_dev *indio_dev = pf->indio_dev; 1169 1045 struct adis16475 *st = iio_priv(indio_dev); 1170 1046 struct adis *adis = &st->adis; 1171 - int ret, bit, i = 0; 1047 + int ret, bit, buff_offset = 0, i = 0; 1172 1048 __be16 *buffer; 1173 1049 u16 crc; 1174 1050 bool valid; ··· 1198 1074 case ADIS16475_SCAN_TEMP: 1199 1075 st->data[i++] = buffer[offset]; 1200 1076 break; 1077 + case ADIS16475_SCAN_DELTANG_X ... ADIS16475_SCAN_DELTVEL_Z: 1078 + buff_offset = ADIS16475_SCAN_DELTANG_X; 1079 + fallthrough; 1201 1080 case ADIS16475_SCAN_GYRO_X ... ADIS16475_SCAN_ACCEL_Z: 1202 1081 /* 1203 1082 * The first 2 bytes on the received data are the ··· 1208 1081 */ 1209 1082 if (st->burst32) { 1210 1083 /* upper 16 */ 1211 - st->data[i++] = buffer[bit * 2 + 2]; 1084 + st->data[i++] = buffer[(bit - buff_offset) * 2 + 2]; 1212 1085 /* lower 16 */ 1213 - st->data[i++] = buffer[bit * 2 + 1]; 1086 + st->data[i++] = buffer[(bit - buff_offset) * 2 + 1]; 1214 1087 } else { 1215 - st->data[i++] = buffer[bit + 1]; 1088 + st->data[i++] = buffer[(bit - buff_offset) + 1]; 1216 1089 /* 1217 1090 * Don't bother in doing the manual read if the 1218 1091 * device supports burst32. burst32 will be 1219 1092 * enabled in the next call to 1220 1093 * adis16475_burst32_check()... 1221 1094 */ 1222 - if (st->lsb_flag && !st->info->has_burst32) { 1095 + if (st->lsb_flag && !(st->info->flags & ADIS16475_HAS_BURST32)) { 1223 1096 u16 val = 0; 1224 1097 const u32 reg = ADIS16475_REG_X_GYRO_L + 1225 1098 bit * 4;