Message ID | 20200129085356.28899-1-mircea.caprioru@analog.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [V3] iio: adc: ad7124: Add direct reg access | expand |
[...] > > +static int ad7124_reg_access(struct iio_dev *indio_dev, > + unsigned int reg, > + unsigned int writeval, > + unsigned int *readval) > +{ > + struct ad7124_state *st = iio_priv(indio_dev); > + int ret; > + > + if (reg >= AD7124_REG_NO) How about ARRAY_SIZE(ad7124_reg_size)? That will make sure that the check is always correct and does not depend on an extra constant that might go out-of-sync with the array. It also makes it easier for reviewers to check that the code is correct. Otherwise they'll have to count how many entries there are in ad7124_reg_size. > + return -EINVAL; > + > + if (readval) > + ret = ad_sd_read_reg(&st->sd, reg, ad7124_reg_size[reg], > + readval); > + else > + ret = ad_sd_write_reg(&st->sd, reg, ad7124_reg_size[reg], > + writeval); > + > + return ret; > +} > + > static IIO_CONST_ATTR(in_voltage_scale_available, > "0.000001164 0.000002328 0.000004656 0.000009313 0.000018626 0.000037252 0.000074505 0.000149011 0.000298023"); > > @@ -375,6 +406,7 @@ static const struct attribute_group ad7124_attrs_group = { > static const struct iio_info ad7124_info = { > .read_raw = ad7124_read_raw, > .write_raw = ad7124_write_raw, > + .debugfs_reg_access = &ad7124_reg_access, > .validate_trigger = ad_sd_validate_trigger, > .attrs = &ad7124_attrs_group, > }; >
diff --git a/drivers/iio/adc/ad7124.c b/drivers/iio/adc/ad7124.c index 52f45b13da4a..26e2677c97c5 100644 --- a/drivers/iio/adc/ad7124.c +++ b/drivers/iio/adc/ad7124.c @@ -71,6 +71,8 @@ #define AD7124_FILTER_FS_MSK GENMASK(10, 0) #define AD7124_FILTER_FS(x) FIELD_PREP(AD7124_FILTER_FS_MSK, x) +#define AD7124_REG_NO 57 + enum ad7124_ids { ID_AD7124_4, ID_AD7124_8, @@ -93,6 +95,14 @@ static const unsigned int ad7124_gain[8] = { 1, 2, 4, 8, 16, 32, 64, 128 }; +static const unsigned int ad7124_reg_size[] = { + 1, 2, 3, 3, 2, 1, 3, 3, 1, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3 +}; + static const int ad7124_master_clk_freq_hz[3] = { [AD7124_LOW_POWER] = 76800, [AD7124_MID_POWER] = 153600, @@ -360,6 +370,27 @@ static int ad7124_write_raw(struct iio_dev *indio_dev, } } +static int ad7124_reg_access(struct iio_dev *indio_dev, + unsigned int reg, + unsigned int writeval, + unsigned int *readval) +{ + struct ad7124_state *st = iio_priv(indio_dev); + int ret; + + if (reg >= AD7124_REG_NO) + return -EINVAL; + + if (readval) + ret = ad_sd_read_reg(&st->sd, reg, ad7124_reg_size[reg], + readval); + else + ret = ad_sd_write_reg(&st->sd, reg, ad7124_reg_size[reg], + writeval); + + return ret; +} + static IIO_CONST_ATTR(in_voltage_scale_available, "0.000001164 0.000002328 0.000004656 0.000009313 0.000018626 0.000037252 0.000074505 0.000149011 0.000298023"); @@ -375,6 +406,7 @@ static const struct attribute_group ad7124_attrs_group = { static const struct iio_info ad7124_info = { .read_raw = ad7124_read_raw, .write_raw = ad7124_write_raw, + .debugfs_reg_access = &ad7124_reg_access, .validate_trigger = ad_sd_validate_trigger, .attrs = &ad7124_attrs_group, };
This patch adds the possibility to read and write registers from userspace using the kernel debug direct register access option. Signed-off-by: Mircea Caprioru <mircea.caprioru@analog.com> --- Changelog v2 -> v3 - fix typo in commit message - add bounds check for ad7124_reg_size drivers/iio/adc/ad7124.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+)