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: adc: ad4062: Add IIO Events support

Adds support for IIO Events. Optionally, gp0 is assigned as Threshold
Either signal, if not present, fallback to an I3C IBI with the same
role.

Signed-off-by: Jorge Marques <jorge.marques@analog.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Jorge Marques and committed by
Jonathan Cameron
ba3a34b1 c894e058

+406 -1
+406 -1
drivers/iio/adc/ad4062.c
··· 14 14 #include <linux/i3c/device.h> 15 15 #include <linux/i3c/master.h> 16 16 #include <linux/iio/buffer.h> 17 + #include <linux/iio/events.h> 17 18 #include <linux/iio/iio.h> 19 + #include <linux/iio/sysfs.h> 18 20 #include <linux/iio/trigger.h> 19 21 #include <linux/iio/trigger_consumer.h> 20 22 #include <linux/iio/triggered_buffer.h> ··· 53 51 #define AD4062_REG_ADC_CONFIG_SCALE_EN_MSK BIT(4) 54 52 #define AD4062_REG_AVG_CONFIG 0x23 55 53 #define AD4062_REG_GP_CONF 0x24 54 + #define AD4062_REG_GP_CONF_MODE_MSK_0 GENMASK(2, 0) 56 55 #define AD4062_REG_GP_CONF_MODE_MSK_1 GENMASK(6, 4) 57 56 #define AD4062_REG_INTR_CONF 0x25 57 + #define AD4062_REG_INTR_CONF_EN_MSK_0 GENMASK(1, 0) 58 58 #define AD4062_REG_INTR_CONF_EN_MSK_1 GENMASK(5, 4) 59 59 #define AD4062_REG_TIMER_CONFIG 0x27 60 60 #define AD4062_REG_TIMER_CONFIG_FS_MASK GENMASK(7, 4) 61 + #define AD4062_REG_MAX_LIMIT 0x29 62 + #define AD4062_REG_MIN_LIMIT 0x2B 63 + #define AD4062_REG_MAX_HYST 0x2C 64 + #define AD4062_REG_MIN_HYST 0x2D 61 65 #define AD4062_REG_MON_VAL 0x2F 62 66 #define AD4062_REG_ADC_IBI_EN 0x31 63 67 #define AD4062_REG_ADC_IBI_EN_CONV_TRIGGER BIT(2) 68 + #define AD4062_REG_ADC_IBI_EN_MAX BIT(1) 69 + #define AD4062_REG_ADC_IBI_EN_MIN BIT(0) 64 70 #define AD4062_REG_FUSE_CRC 0x40 65 71 #define AD4062_REG_DEVICE_STATUS 0x41 66 72 #define AD4062_REG_DEVICE_STATUS_DEVICE_RESET BIT(6) ··· 88 78 #define AD4060_PROD_ID 0x7A 89 79 #define AD4062_PROD_ID 0x7C 90 80 81 + #define AD4062_GP_INTR 0x1 91 82 #define AD4062_GP_DRDY 0x2 92 83 84 + #define AD4062_LIMIT_BITS 12 85 + 93 86 #define AD4062_INTR_EN_NEITHER 0x0 87 + #define AD4062_INTR_EN_EITHER 0x3 94 88 95 89 #define AD4062_TCONV_NS 270 96 90 ··· 163 149 struct iio_dev *indio_dev; 164 150 struct i3c_device *i3cdev; 165 151 struct regmap *regmap; 152 + bool wait_event; 166 153 int vref_uV; 167 154 unsigned int samp_freqs[ARRAY_SIZE(ad4062_conversion_freqs)]; 168 155 bool gpo_irq[2]; 169 156 u16 sampling_frequency; 157 + u16 events_frequency; 170 158 u8 oversamp_ratio; 171 159 u8 conv_sizeof; 172 160 u8 conv_addr; ··· 204 188 .n_yes_ranges = ARRAY_SIZE(ad4062_regmap_wr_ranges), 205 189 }; 206 190 191 + static const struct iio_event_spec ad4062_events[] = { 192 + { 193 + .type = IIO_EV_TYPE_THRESH, 194 + .dir = IIO_EV_DIR_EITHER, 195 + .mask_shared_by_all = BIT(IIO_EV_INFO_ENABLE), 196 + }, 197 + { 198 + .type = IIO_EV_TYPE_THRESH, 199 + .dir = IIO_EV_DIR_RISING, 200 + .mask_shared_by_all = BIT(IIO_EV_INFO_VALUE) | 201 + BIT(IIO_EV_INFO_HYSTERESIS), 202 + }, 203 + { 204 + .type = IIO_EV_TYPE_THRESH, 205 + .dir = IIO_EV_DIR_FALLING, 206 + .mask_shared_by_all = BIT(IIO_EV_INFO_VALUE) | 207 + BIT(IIO_EV_INFO_HYSTERESIS), 208 + }, 209 + }; 210 + 207 211 #define AD4062_CHAN(bits) { \ 208 212 .type = IIO_VOLTAGE, \ 209 213 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_RAW) | \ ··· 235 199 .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ 236 200 .indexed = 1, \ 237 201 .channel = 0, \ 202 + .event_spec = ad4062_events, \ 203 + .num_event_specs = ARRAY_SIZE(ad4062_events), \ 238 204 .has_ext_scan_type = 1, \ 239 205 .ext_scan_type = ad4062_scan_type_##bits##_s, \ 240 206 .num_ext_scan_type = ARRAY_SIZE(ad4062_scan_type_##bits##_s), \ ··· 254 216 .channels = { AD4062_CHAN(16) }, 255 217 .prod_id = AD4062_PROD_ID, 256 218 .avg_max = 4096, 219 + }; 220 + 221 + static ssize_t sampling_frequency_show(struct device *dev, 222 + struct device_attribute *attr, char *buf) 223 + { 224 + struct ad4062_state *st = iio_priv(dev_to_iio_dev(dev)); 225 + 226 + return sysfs_emit(buf, "%d\n", ad4062_conversion_freqs[st->events_frequency]); 227 + } 228 + 229 + static int sampling_frequency_store_dispatch(struct iio_dev *indio_dev, 230 + const char *buf) 231 + { 232 + struct ad4062_state *st = iio_priv(indio_dev); 233 + int val, ret; 234 + 235 + if (st->wait_event) 236 + return -EBUSY; 237 + 238 + ret = kstrtoint(buf, 10, &val); 239 + if (ret) 240 + return ret; 241 + 242 + st->events_frequency = find_closest_descending(val, ad4062_conversion_freqs, 243 + ARRAY_SIZE(ad4062_conversion_freqs)); 244 + return 0; 245 + } 246 + 247 + static ssize_t sampling_frequency_store(struct device *dev, 248 + struct device_attribute *attr, 249 + const char *buf, size_t len) 250 + { 251 + struct iio_dev *indio_dev = dev_to_iio_dev(dev); 252 + int ret; 253 + 254 + if (!iio_device_claim_direct(indio_dev)) 255 + return -EBUSY; 256 + 257 + ret = sampling_frequency_store_dispatch(indio_dev, buf); 258 + iio_device_release_direct(indio_dev); 259 + return ret ?: len; 260 + } 261 + 262 + static IIO_DEVICE_ATTR_RW(sampling_frequency, 0); 263 + 264 + static ssize_t sampling_frequency_available_show(struct device *dev, 265 + struct device_attribute *attr, 266 + char *buf) 267 + { 268 + int ret = 0; 269 + 270 + for (u8 i = 0; i < ARRAY_SIZE(ad4062_conversion_freqs); i++) 271 + ret += sysfs_emit_at(buf, ret, "%d%s", ad4062_conversion_freqs[i], 272 + i != (ARRAY_SIZE(ad4062_conversion_freqs) - 1) ? " " : "\n"); 273 + return ret; 274 + } 275 + 276 + static IIO_DEVICE_ATTR_RO(sampling_frequency_available, 0); 277 + 278 + static struct attribute *ad4062_event_attributes[] = { 279 + &iio_dev_attr_sampling_frequency.dev_attr.attr, 280 + &iio_dev_attr_sampling_frequency_available.dev_attr.attr, 281 + NULL 282 + }; 283 + 284 + static const struct attribute_group ad4062_event_attribute_group = { 285 + .attrs = ad4062_event_attributes, 257 286 }; 258 287 259 288 static int ad4062_set_oversampling_ratio(struct ad4062_state *st, int val, int val2) ··· 449 344 static int ad4062_set_operation_mode(struct ad4062_state *st, 450 345 enum ad4062_operation_mode mode) 451 346 { 347 + const unsigned int samp_freq = mode == AD4062_MONITOR_MODE ? 348 + st->events_frequency : st->sampling_frequency; 452 349 int ret; 453 350 454 - ret = ad4062_conversion_frequency_set(st, st->sampling_frequency); 351 + ret = ad4062_conversion_frequency_set(st, samp_freq); 455 352 if (ret) 456 353 return ret; 457 354 ··· 461 354 AD4062_REG_ADC_MODES_MODE_MSK, mode); 462 355 if (ret) 463 356 return ret; 357 + 358 + if (mode == AD4062_MONITOR_MODE) { 359 + /* Change address pointer to enter monitor mode */ 360 + struct i3c_priv_xfer xfer_trigger = { 361 + .data.out = &st->conv_addr, 362 + .len = sizeof(st->conv_addr), 363 + .rnw = false, 364 + }; 365 + st->conv_addr = AD4062_REG_CONV_TRIGGER_32BITS; 366 + return i3c_device_do_priv_xfers(st->i3cdev, &xfer_trigger, 1); 367 + } 464 368 465 369 return regmap_write(st->regmap, AD4062_REG_MODE_SET, 466 370 AD4062_REG_MODE_SET_ENTER_ADC); ··· 504 386 return PTR_ERR(scan_type); 505 387 506 388 ret = regmap_update_bits(st->regmap, AD4062_REG_GP_CONF, 389 + AD4062_REG_GP_CONF_MODE_MSK_0, 390 + FIELD_PREP(AD4062_REG_GP_CONF_MODE_MSK_0, 391 + AD4062_GP_INTR)); 392 + if (ret) 393 + return ret; 394 + 395 + ret = regmap_update_bits(st->regmap, AD4062_REG_GP_CONF, 507 396 AD4062_REG_GP_CONF_MODE_MSK_1, 508 397 FIELD_PREP(AD4062_REG_GP_CONF_MODE_MSK_1, 509 398 AD4062_GP_DRDY)); ··· 530 405 return ret; 531 406 532 407 ret = regmap_update_bits(st->regmap, AD4062_REG_INTR_CONF, 408 + AD4062_REG_INTR_CONF_EN_MSK_0, 409 + FIELD_PREP(AD4062_REG_INTR_CONF_EN_MSK_0, 410 + AD4062_INTR_EN_EITHER)); 411 + if (ret) 412 + return ret; 413 + 414 + ret = regmap_update_bits(st->regmap, AD4062_REG_INTR_CONF, 533 415 AD4062_REG_INTR_CONF_EN_MSK_1, 534 416 FIELD_PREP(AD4062_REG_INTR_CONF_EN_MSK_1, 535 417 AD4062_INTR_EN_NEITHER)); ··· 546 414 st->buf.be16 = cpu_to_be16(AD4062_MON_VAL_MIDDLE_POINT); 547 415 return regmap_bulk_write(st->regmap, AD4062_REG_MON_VAL, 548 416 &st->buf.be16, sizeof(st->buf.be16)); 417 + } 418 + 419 + static irqreturn_t ad4062_irq_handler_thresh(int irq, void *private) 420 + { 421 + struct iio_dev *indio_dev = private; 422 + 423 + iio_push_event(indio_dev, 424 + IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 0, 425 + IIO_EV_TYPE_THRESH, 426 + IIO_EV_DIR_EITHER), 427 + iio_get_time_ns(indio_dev)); 428 + 429 + return IRQ_HANDLED; 549 430 } 550 431 551 432 static irqreturn_t ad4062_irq_handler_drdy(int irq, void *private) ··· 579 434 { 580 435 struct ad4062_state *st = i3cdev_get_drvdata(i3cdev); 581 436 437 + if (st->wait_event) { 438 + iio_push_event(st->indio_dev, 439 + IIO_UNMOD_EVENT_CODE(IIO_VOLTAGE, 0, 440 + IIO_EV_TYPE_THRESH, 441 + IIO_EV_DIR_EITHER), 442 + iio_get_time_ns(st->indio_dev)); 443 + return; 444 + } 582 445 if (iio_buffer_enabled(st->indio_dev)) 583 446 iio_trigger_poll_nested(st->trigger); 584 447 else ··· 681 528 struct ad4062_state *st = iio_priv(indio_dev); 682 529 struct device *dev = &st->i3cdev->dev; 683 530 int ret; 531 + 532 + ret = fwnode_irq_get_byname(dev_fwnode(&st->i3cdev->dev), "gp0"); 533 + if (ret == -EPROBE_DEFER) 534 + return ret; 535 + 536 + if (ret < 0) { 537 + ret = regmap_update_bits(st->regmap, AD4062_REG_ADC_IBI_EN, 538 + AD4062_REG_ADC_IBI_EN_MAX | AD4062_REG_ADC_IBI_EN_MIN, 539 + AD4062_REG_ADC_IBI_EN_MAX | AD4062_REG_ADC_IBI_EN_MIN); 540 + if (ret) 541 + return ret; 542 + } else { 543 + ret = devm_request_threaded_irq(dev, ret, NULL, 544 + ad4062_irq_handler_thresh, 545 + IRQF_ONESHOT, indio_dev->name, 546 + indio_dev); 547 + if (ret) 548 + return ret; 549 + } 684 550 685 551 ret = fwnode_irq_get_byname(dev_fwnode(&st->i3cdev->dev), "gp1"); 686 552 if (ret == -EPROBE_DEFER) ··· 892 720 static int ad4062_read_raw_dispatch(struct ad4062_state *st, 893 721 int *val, int *val2, long info) 894 722 { 723 + if (st->wait_event) 724 + return -EBUSY; 725 + 895 726 switch (info) { 896 727 case IIO_CHAN_INFO_RAW: 897 728 return ad4062_read_chan_raw(st, val); ··· 936 761 static int ad4062_write_raw_dispatch(struct ad4062_state *st, int val, int val2, 937 762 long info) 938 763 { 764 + if (st->wait_event) 765 + return -EBUSY; 766 + 939 767 switch (info) { 940 768 case IIO_CHAN_INFO_OVERSAMPLING_RATIO: 941 769 return ad4062_set_oversampling_ratio(st, val, val2); ··· 967 789 return -EBUSY; 968 790 969 791 ret = ad4062_write_raw_dispatch(st, val, val2, info); 792 + iio_device_release_direct(indio_dev); 793 + return ret; 794 + } 970 795 796 + static int pm_ad4062_monitor_mode_enable(struct ad4062_state *st) 797 + { 798 + int ret; 799 + 800 + PM_RUNTIME_ACQUIRE(&st->i3cdev->dev, pm); 801 + ret = PM_RUNTIME_ACQUIRE_ERR(&pm); 802 + if (ret) 803 + return ret; 804 + 805 + return ad4062_set_operation_mode(st, AD4062_MONITOR_MODE); 806 + } 807 + 808 + static int ad4062_monitor_mode_enable(struct ad4062_state *st) 809 + { 810 + int ret; 811 + 812 + ret = pm_ad4062_monitor_mode_enable(st); 813 + if (ret) 814 + return ret; 815 + 816 + pm_runtime_get_noresume(&st->i3cdev->dev); 817 + return 0; 818 + } 819 + 820 + static int ad4062_monitor_mode_disable(struct ad4062_state *st) 821 + { 822 + pm_runtime_put_autosuspend(&st->i3cdev->dev); 823 + return 0; 824 + } 825 + 826 + static int ad4062_read_event_config(struct iio_dev *indio_dev, 827 + const struct iio_chan_spec *chan, 828 + enum iio_event_type type, 829 + enum iio_event_direction dir) 830 + { 831 + struct ad4062_state *st = iio_priv(indio_dev); 832 + 833 + return st->wait_event; 834 + } 835 + 836 + static int ad4062_write_event_config_dispatch(struct iio_dev *indio_dev, 837 + bool state) 838 + { 839 + struct ad4062_state *st = iio_priv(indio_dev); 840 + int ret; 841 + 842 + if (st->wait_event == state) 843 + ret = 0; 844 + else if (state) 845 + ret = ad4062_monitor_mode_enable(st); 846 + else 847 + ret = ad4062_monitor_mode_disable(st); 848 + if (ret) 849 + return ret; 850 + 851 + st->wait_event = state; 852 + return 0; 853 + } 854 + 855 + static int ad4062_write_event_config(struct iio_dev *indio_dev, 856 + const struct iio_chan_spec *chan, 857 + enum iio_event_type type, 858 + enum iio_event_direction dir, 859 + bool state) 860 + { 861 + int ret; 862 + 863 + if (!iio_device_claim_direct(indio_dev)) 864 + return -EBUSY; 865 + 866 + ret = ad4062_write_event_config_dispatch(indio_dev, state); 867 + iio_device_release_direct(indio_dev); 868 + return ret; 869 + } 870 + 871 + static int __ad4062_read_event_info_value(struct ad4062_state *st, 872 + enum iio_event_direction dir, int *val) 873 + { 874 + int ret; 875 + u8 reg; 876 + 877 + if (dir == IIO_EV_DIR_RISING) 878 + reg = AD4062_REG_MAX_LIMIT; 879 + else 880 + reg = AD4062_REG_MIN_LIMIT; 881 + 882 + ret = regmap_bulk_read(st->regmap, reg, &st->buf.be16, 883 + sizeof(st->buf.be16)); 884 + if (ret) 885 + return ret; 886 + 887 + *val = sign_extend32(be16_to_cpu(st->buf.be16), AD4062_LIMIT_BITS - 1); 888 + 889 + return 0; 890 + } 891 + 892 + static int __ad4062_read_event_info_hysteresis(struct ad4062_state *st, 893 + enum iio_event_direction dir, int *val) 894 + { 895 + u8 reg; 896 + 897 + if (dir == IIO_EV_DIR_RISING) 898 + reg = AD4062_REG_MAX_HYST; 899 + else 900 + reg = AD4062_REG_MIN_HYST; 901 + return regmap_read(st->regmap, reg, val); 902 + } 903 + 904 + static int ad4062_read_event_config_dispatch(struct iio_dev *indio_dev, 905 + enum iio_event_direction dir, 906 + enum iio_event_info info, int *val) 907 + { 908 + struct ad4062_state *st = iio_priv(indio_dev); 909 + 910 + if (st->wait_event) 911 + return -EBUSY; 912 + 913 + switch (info) { 914 + case IIO_EV_INFO_VALUE: 915 + return __ad4062_read_event_info_value(st, dir, val); 916 + case IIO_EV_INFO_HYSTERESIS: 917 + return __ad4062_read_event_info_hysteresis(st, dir, val); 918 + default: 919 + return -EINVAL; 920 + } 921 + } 922 + 923 + static int ad4062_read_event_value(struct iio_dev *indio_dev, 924 + const struct iio_chan_spec *chan, 925 + enum iio_event_type type, 926 + enum iio_event_direction dir, 927 + enum iio_event_info info, int *val, 928 + int *val2) 929 + { 930 + int ret; 931 + 932 + if (!iio_device_claim_direct(indio_dev)) 933 + return -EBUSY; 934 + 935 + ret = ad4062_read_event_config_dispatch(indio_dev, dir, info, val); 936 + iio_device_release_direct(indio_dev); 937 + return ret ?: IIO_VAL_INT; 938 + } 939 + 940 + static int __ad4062_write_event_info_value(struct ad4062_state *st, 941 + enum iio_event_direction dir, int val) 942 + { 943 + u8 reg; 944 + 945 + if (val != sign_extend32(val, AD4062_LIMIT_BITS - 1)) 946 + return -EINVAL; 947 + if (dir == IIO_EV_DIR_RISING) 948 + reg = AD4062_REG_MAX_LIMIT; 949 + else 950 + reg = AD4062_REG_MIN_LIMIT; 951 + st->buf.be16 = cpu_to_be16(val); 952 + 953 + return regmap_bulk_write(st->regmap, reg, &st->buf.be16, 954 + sizeof(st->buf.be16)); 955 + } 956 + 957 + static int __ad4062_write_event_info_hysteresis(struct ad4062_state *st, 958 + enum iio_event_direction dir, int val) 959 + { 960 + u8 reg; 961 + 962 + if (val > BIT(7) - 1) 963 + return -EINVAL; 964 + if (dir == IIO_EV_DIR_RISING) 965 + reg = AD4062_REG_MAX_HYST; 966 + else 967 + reg = AD4062_REG_MIN_HYST; 968 + 969 + return regmap_write(st->regmap, reg, val); 970 + } 971 + 972 + static int ad4062_write_event_value_dispatch(struct iio_dev *indio_dev, 973 + enum iio_event_type type, 974 + enum iio_event_direction dir, 975 + enum iio_event_info info, int val) 976 + { 977 + struct ad4062_state *st = iio_priv(indio_dev); 978 + 979 + if (st->wait_event) 980 + return -EBUSY; 981 + 982 + switch (type) { 983 + case IIO_EV_TYPE_THRESH: 984 + switch (info) { 985 + case IIO_EV_INFO_VALUE: 986 + return __ad4062_write_event_info_value(st, dir, val); 987 + case IIO_EV_INFO_HYSTERESIS: 988 + return __ad4062_write_event_info_hysteresis(st, dir, val); 989 + default: 990 + return -EINVAL; 991 + } 992 + default: 993 + return -EINVAL; 994 + } 995 + } 996 + 997 + static int ad4062_write_event_value(struct iio_dev *indio_dev, 998 + const struct iio_chan_spec *chan, 999 + enum iio_event_type type, 1000 + enum iio_event_direction dir, 1001 + enum iio_event_info info, int val, 1002 + int val2) 1003 + { 1004 + int ret; 1005 + 1006 + if (!iio_device_claim_direct(indio_dev)) 1007 + return -EBUSY; 1008 + 1009 + ret = ad4062_write_event_value_dispatch(indio_dev, type, dir, info, val); 971 1010 iio_device_release_direct(indio_dev); 972 1011 return ret; 973 1012 } ··· 1219 824 ret = PM_RUNTIME_ACQUIRE_ERR(&pm); 1220 825 if (ret) 1221 826 return ret; 827 + 828 + if (st->wait_event) 829 + return -EBUSY; 1222 830 1223 831 ret = ad4062_set_operation_mode(st, st->mode); 1224 832 if (ret) ··· 1298 900 .read_raw = ad4062_read_raw, 1299 901 .write_raw = ad4062_write_raw, 1300 902 .read_avail = ad4062_read_avail, 903 + .read_event_config = ad4062_read_event_config, 904 + .write_event_config = ad4062_write_event_config, 905 + .read_event_value = ad4062_read_event_value, 906 + .write_event_value = ad4062_write_event_value, 907 + .event_attrs = &ad4062_event_attribute_group, 1301 908 .get_current_scan_type = ad4062_get_current_scan_type, 1302 909 .debugfs_reg_access = ad4062_debugfs_reg_access, 1303 910 }; ··· 1383 980 "Failed to initialize regmap\n"); 1384 981 1385 982 st->mode = AD4062_SAMPLE_MODE; 983 + st->wait_event = false; 1386 984 st->chip = chip; 1387 985 st->sampling_frequency = 0; 986 + st->events_frequency = 0; 1388 987 st->oversamp_ratio = 0; 1389 988 st->indio_dev = indio_dev; 1390 989