Commit 42776c14 authored by Mircea Caprioru's avatar Mircea Caprioru Committed by Jonathan Cameron

staging: iio: adc: ad7192: Add system calibration support

This patch will add a system calibration attribute for each channel. Using
this option the user will have the ability to calibrate each channel for
zero scale and full scale. It uses the iio_chan_spec_ext_info and IIO_ENUM
to implement the functionality.
Signed-off-by: default avatarMircea Caprioru <mircea.caprioru@analog.com>
Signed-off-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
parent c88c8cd8
...@@ -13,3 +13,27 @@ Description: ...@@ -13,3 +13,27 @@ Description:
need to minimize the system current consumption. need to minimize the system current consumption.
Reading gives the state of the bridge switch. Reading gives the state of the bridge switch.
Writing '1' enables the bridge switch. Writing '1' enables the bridge switch.
What: /sys/bus/iio/devices/iio:deviceX/in_voltagex_sys_calibration
KernelVersion:
Contact: linux-iio@vger.kernel.org
Description:
Initiates the system calibration procedure. This is done on a
single channel at a time. Write '1' to start the calibration.
What: /sys/bus/iio/devices/iio:deviceX/in_voltagex_sys_calibration_mode_available
KernelVersion:
Contact: linux-iio@vger.kernel.org
Description:
Reading returns a list with the possible calibration modes.
There are two available options:
"zero_scale" - calibrate to zero scale
"full_scale" - calibrate to full scale
What: /sys/bus/iio/devices/iio:deviceX/in_voltagex_sys_calibration_mode
KernelVersion:
Contact: linux-iio@vger.kernel.org
Description:
Sets up the calibration mode used in the system calibration
procedure. Reading returns the current calibration mode.
Writing sets the system calibration mode.
...@@ -155,6 +155,11 @@ ...@@ -155,6 +155,11 @@
* The DOUT/RDY output must also be wired to an interrupt capable GPIO. * The DOUT/RDY output must also be wired to an interrupt capable GPIO.
*/ */
enum {
AD7192_SYSCALIB_ZERO_SCALE,
AD7192_SYSCALIB_FULL_SCALE,
};
struct ad7192_state { struct ad7192_state {
struct regulator *avdd; struct regulator *avdd;
struct regulator *dvdd; struct regulator *dvdd;
...@@ -169,10 +174,80 @@ struct ad7192_state { ...@@ -169,10 +174,80 @@ struct ad7192_state {
u8 devid; u8 devid;
u8 clock_sel; u8 clock_sel;
struct mutex lock; /* protect sensor state */ struct mutex lock; /* protect sensor state */
u8 syscalib_mode[8];
struct ad_sigma_delta sd; struct ad_sigma_delta sd;
}; };
static const char * const ad7192_syscalib_modes[] = {
[AD7192_SYSCALIB_ZERO_SCALE] = "zero_scale",
[AD7192_SYSCALIB_FULL_SCALE] = "full_scale",
};
static int ad7192_set_syscalib_mode(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan,
unsigned int mode)
{
struct ad7192_state *st = iio_priv(indio_dev);
st->syscalib_mode[chan->channel] = mode;
return 0;
}
static int ad7192_get_syscalib_mode(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan)
{
struct ad7192_state *st = iio_priv(indio_dev);
return st->syscalib_mode[chan->channel];
}
static ssize_t ad7192_write_syscalib(struct iio_dev *indio_dev,
uintptr_t private,
const struct iio_chan_spec *chan,
const char *buf, size_t len)
{
struct ad7192_state *st = iio_priv(indio_dev);
bool sys_calib;
int ret, temp;
ret = strtobool(buf, &sys_calib);
if (ret)
return ret;
temp = st->syscalib_mode[chan->channel];
if (sys_calib) {
if (temp == AD7192_SYSCALIB_ZERO_SCALE)
ret = ad_sd_calibrate(&st->sd, AD7192_MODE_CAL_SYS_ZERO,
chan->address);
else
ret = ad_sd_calibrate(&st->sd, AD7192_MODE_CAL_SYS_FULL,
chan->address);
}
return ret ? ret : len;
}
static const struct iio_enum ad7192_syscalib_mode_enum = {
.items = ad7192_syscalib_modes,
.num_items = ARRAY_SIZE(ad7192_syscalib_modes),
.set = ad7192_set_syscalib_mode,
.get = ad7192_get_syscalib_mode
};
static const struct iio_chan_spec_ext_info ad7192_calibsys_ext_info[] = {
{
.name = "sys_calibration",
.write = ad7192_write_syscalib,
.shared = IIO_SEPARATE,
},
IIO_ENUM("sys_calibration_mode", IIO_SEPARATE,
&ad7192_syscalib_mode_enum),
IIO_ENUM_AVAILABLE("sys_calibration_mode", &ad7192_syscalib_mode_enum),
{}
};
static struct ad7192_state *ad_sigma_delta_to_ad7192(struct ad_sigma_delta *sd) static struct ad7192_state *ad_sigma_delta_to_ad7192(struct ad_sigma_delta *sd)
{ {
return container_of(sd, struct ad7192_state, sd); return container_of(sd, struct ad7192_state, sd);
...@@ -770,9 +845,11 @@ static int ad7192_channels_config(struct iio_dev *indio_dev) ...@@ -770,9 +845,11 @@ static int ad7192_channels_config(struct iio_dev *indio_dev)
*chan = channels[i]; *chan = channels[i];
chan->info_mask_shared_by_all |= chan->info_mask_shared_by_all |=
BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY); BIT(IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY);
if (chan->type != IIO_TEMP) if (chan->type != IIO_TEMP) {
chan->info_mask_shared_by_type_available |= chan->info_mask_shared_by_type_available |=
BIT(IIO_CHAN_INFO_SCALE); BIT(IIO_CHAN_INFO_SCALE);
chan->ext_info = ad7192_calibsys_ext_info;
}
chan++; chan++;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment