General improvements: - allow setting gain and sampling per channel - setting scale can also set sampling rate (combined setting) - use per channel config setting - do not update mcp register on setting write (we might be reading it...) instead it's updated on next value read - output all scale values (sample rates x gain) Signed-off-by: Mitja Spes <mitja@xxxxxxxxx> --- drivers/iio/adc/mcp3422.c | 119 ++++++++++++++++++++------------------ 1 file changed, 64 insertions(+), 55 deletions(-) diff --git a/drivers/iio/adc/mcp3422.c b/drivers/iio/adc/mcp3422.c index 3d53de300c89..cfb629b964af 100644 --- a/drivers/iio/adc/mcp3422.c +++ b/drivers/iio/adc/mcp3422.c @@ -28,14 +28,19 @@ #define MCP3422_CHANNEL_MASK 0x60 #define MCP3422_PGA_MASK 0x03 #define MCP3422_SRATE_MASK 0x0C -#define MCP3422_SRATE_240 0x0 -#define MCP3422_SRATE_60 0x1 -#define MCP3422_SRATE_15 0x2 -#define MCP3422_SRATE_3 0x3 -#define MCP3422_PGA_1 0 -#define MCP3422_PGA_2 1 -#define MCP3422_PGA_4 2 -#define MCP3422_PGA_8 3 + +#define MCP3422_SRATE_240 0 +#define MCP3422_SRATE_60 1 +#define MCP3422_SRATE_15 2 +#define MCP3422_SRATE_3 3 +#define MCP3422_SRATE_COUNT 4 + +#define MCP3422_PGA_1 0 +#define MCP3422_PGA_2 1 +#define MCP3422_PGA_4 2 +#define MCP3422_PGA_8 3 +#define MCP3422_PGA_COUNT 4 + #define MCP3422_CONT_SAMPLING 0x10 #define MCP3422_CHANNEL(config) (((config) & MCP3422_CHANNEL_MASK) >> 5) @@ -52,32 +57,32 @@ .indexed = 1, \ .channel = _index, \ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) \ - | BIT(IIO_CHAN_INFO_SCALE), \ - .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + | BIT(IIO_CHAN_INFO_SCALE) \ + | BIT(IIO_CHAN_INFO_SAMP_FREQ), \ } -static const int mcp3422_scales[4][4] = { +static const int mcp3422_scales[MCP3422_SRATE_COUNT][MCP3422_PGA_COUNT] = { { 1000000, 500000, 250000, 125000 }, { 250000, 125000, 62500, 31250 }, { 62500, 31250, 15625, 7812 }, { 15625, 7812, 3906, 1953 } }; /* Constant msleep times for data acquisitions */ -static const int mcp3422_read_times[4] = { +static const int mcp3422_read_times[MCP3422_SRATE_COUNT] = { [MCP3422_SRATE_240] = 1000 / 240, [MCP3422_SRATE_60] = 1000 / 60, [MCP3422_SRATE_15] = 1000 / 15, [MCP3422_SRATE_3] = 1000 / 3 }; /* sample rates to integer conversion table */ -static const int mcp3422_sample_rates[4] = { +static const int mcp3422_sample_rates[MCP3422_SRATE_COUNT] = { [MCP3422_SRATE_240] = 240, [MCP3422_SRATE_60] = 60, [MCP3422_SRATE_15] = 15, [MCP3422_SRATE_3] = 3 }; /* sample rates to sign extension table */ -static const int mcp3422_sign_extend[4] = { +static const int mcp3422_sign_extend[MCP3422_SRATE_COUNT] = { [MCP3422_SRATE_240] = 11, [MCP3422_SRATE_60] = 13, [MCP3422_SRATE_15] = 15, @@ -87,8 +92,8 @@ static const int mcp3422_sign_extend[4] = { struct mcp3422 { struct i2c_client *i2c; u8 id; - u8 config; - u8 pga[4]; + u8 active_config; // config currently set on mcp + u8 ch_config[4]; // per channel config struct mutex lock; }; @@ -98,7 +103,7 @@ static int mcp3422_update_config(struct mcp3422 *adc, u8 newconfig) ret = i2c_master_send(adc->i2c, &newconfig, 1); if (ret > 0) { - adc->config = newconfig; + adc->active_config = newconfig; ret = 0; } @@ -108,7 +113,7 @@ static int mcp3422_update_config(struct mcp3422 *adc, u8 newconfig) static int mcp3422_read(struct mcp3422 *adc, int *value, u8 *config) { int ret = 0; - u8 sample_rate = MCP3422_SAMPLE_RATE(adc->config); + u8 sample_rate = MCP3422_SAMPLE_RATE(adc->active_config); u8 buf[4] = {0, 0, 0, 0}; u32 temp; @@ -136,18 +141,13 @@ static int mcp3422_read_channel(struct mcp3422 *adc, mutex_lock(&adc->lock); - if (req_channel != MCP3422_CHANNEL(adc->config)) { - config = adc->config; - config &= ~MCP3422_CHANNEL_MASK; - config |= MCP3422_CHANNEL_VALUE(req_channel); - config &= ~MCP3422_PGA_MASK; - config |= MCP3422_PGA_VALUE(adc->pga[req_channel]); - ret = mcp3422_update_config(adc, config); + if (adc->ch_config[req_channel] != adc->active_config) { + ret = mcp3422_update_config(adc, adc->ch_config[req_channel]); if (ret < 0) { mutex_unlock(&adc->lock); return ret; } - msleep(mcp3422_read_times[MCP3422_SAMPLE_RATE(adc->config)]); + msleep(mcp3422_read_times[MCP3422_SAMPLE_RATE(adc->active_config)]); } ret = mcp3422_read(adc, value, &config); @@ -164,9 +164,9 @@ static int mcp3422_read_raw(struct iio_dev *iio, struct mcp3422 *adc = iio_priv(iio); int err; - u8 req_channel = channel->channel; - u8 sample_rate = MCP3422_SAMPLE_RATE(adc->config); - u8 pga = adc->pga[req_channel]; + u8 config = adc->ch_config[channel->channel]; + u8 sample_rate = MCP3422_SAMPLE_RATE(config); + u8 pga = MCP3422_PGA(config); switch (mask) { case IIO_CHAN_INFO_RAW: @@ -181,7 +181,7 @@ static int mcp3422_read_raw(struct iio_dev *iio, return IIO_VAL_INT_PLUS_NANO; case IIO_CHAN_INFO_SAMP_FREQ: - *val1 = mcp3422_sample_rates[MCP3422_SAMPLE_RATE(adc->config)]; + *val1 = mcp3422_sample_rates[sample_rate]; return IIO_VAL_INT; default: @@ -197,26 +197,25 @@ static int mcp3422_write_raw(struct iio_dev *iio, { struct mcp3422 *adc = iio_priv(iio); u8 temp; - u8 config = adc->config; u8 req_channel = channel->channel; - u8 sample_rate = MCP3422_SAMPLE_RATE(config); - u8 i; + u8 config = adc->ch_config[req_channel]; + u8 i, j; switch (mask) { case IIO_CHAN_INFO_SCALE: if (val1 != 0) return -EINVAL; - for (i = 0; i < ARRAY_SIZE(mcp3422_scales[0]); i++) { - if (val2 == mcp3422_scales[sample_rate][i]) { - adc->pga[req_channel] = i; - - config &= ~MCP3422_CHANNEL_MASK; - config |= MCP3422_CHANNEL_VALUE(req_channel); - config &= ~MCP3422_PGA_MASK; - config |= MCP3422_PGA_VALUE(adc->pga[req_channel]); - - return mcp3422_update_config(adc, config); + for (j = 0; j < MCP3422_SRATE_COUNT; j++) { + for (i = 0; i < MCP3422_PGA_COUNT; i++) { + if (val2 == mcp3422_scales[j][i]) { + config &= ~MCP3422_PGA_MASK; + config |= MCP3422_PGA_VALUE(i); + config &= ~MCP3422_SRATE_MASK; + config |= MCP3422_SAMPLE_RATE_VALUE(j); + adc->ch_config[req_channel] = config; + return 0; + } } } return -EINVAL; @@ -241,12 +240,10 @@ static int mcp3422_write_raw(struct iio_dev *iio, return -EINVAL; } - config &= ~MCP3422_CHANNEL_MASK; - config |= MCP3422_CHANNEL_VALUE(req_channel); config &= ~MCP3422_SRATE_MASK; config |= MCP3422_SAMPLE_RATE_VALUE(temp); - - return mcp3422_update_config(adc, config); + adc->ch_config[req_channel] = config; + return 0; default: break; @@ -282,14 +279,18 @@ static ssize_t mcp3422_show_samp_freqs(struct device *dev, static ssize_t mcp3422_show_scales(struct device *dev, struct device_attribute *attr, char *buf) { - struct mcp3422 *adc = iio_priv(dev_to_iio_dev(dev)); - u8 sample_rate = MCP3422_SAMPLE_RATE(adc->config); - - return sprintf(buf, "0.%09u 0.%09u 0.%09u 0.%09u\n", - mcp3422_scales[sample_rate][0], - mcp3422_scales[sample_rate][1], - mcp3422_scales[sample_rate][2], - mcp3422_scales[sample_rate][3]); + ssize_t count = 0; + int i; + + for (i = 0; i < MCP3422_SRATE_COUNT; i++) { + count += sprintf(buf + count, "0.%09u 0.%09u 0.%09u 0.%09u%s", + mcp3422_scales[i][0], + mcp3422_scales[i][1], + mcp3422_scales[i][2], + mcp3422_scales[i][3], + (i < MCP3422_SRATE_COUNT - 1 ? " " : "\n")); + } + return count; } static IIO_DEVICE_ATTR(sampling_frequency_available, S_IRUGO, @@ -336,6 +337,7 @@ static int mcp3422_probe(struct i2c_client *client, struct iio_dev *indio_dev; struct mcp3422 *adc; int err; + int i; u8 config; if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) @@ -376,6 +378,13 @@ static int mcp3422_probe(struct i2c_client *client, } /* meaningful default configuration */ + for (i = 0; i < 4; i++) { + adc->ch_config[i] = (MCP3422_CONT_SAMPLING + | MCP3422_CHANNEL_VALUE(i) + | MCP3422_PGA_VALUE(MCP3422_PGA_1) + | MCP3422_SAMPLE_RATE_VALUE(MCP3422_SRATE_240)); + } + config = (MCP3422_CONT_SAMPLING | MCP3422_CHANNEL_VALUE(0) | MCP3422_PGA_VALUE(MCP3422_PGA_1) -- 2.34.1