diff options
Diffstat (limited to 'drivers/iio/potentiometer/tpl0102.c')
| -rw-r--r-- | drivers/iio/potentiometer/tpl0102.c | 66 |
1 files changed, 38 insertions, 28 deletions
diff --git a/drivers/iio/potentiometer/tpl0102.c b/drivers/iio/potentiometer/tpl0102.c index 7b6b54531ea2..a42b57733363 100644 --- a/drivers/iio/potentiometer/tpl0102.c +++ b/drivers/iio/potentiometer/tpl0102.c @@ -1,17 +1,9 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * tpl0102.c - Support for Texas Instruments digital potentiometers * - * Copyright (C) 2016 Matt Ranostay <mranostay@gmail.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * Copyright (C) 2016, 2018 + * Author: Matt Ranostay <matt.ranostay@konsulko.com> * * TODO: enable/disable hi-z output control */ @@ -23,7 +15,7 @@ struct tpl0102_cfg { int wipers; - int max_pos; + int avail[3]; int kohms; }; @@ -36,16 +28,16 @@ enum tpl0102_type { static const struct tpl0102_cfg tpl0102_cfg[] = { /* on-semiconductor parts */ - [CAT5140_503] = { .wipers = 1, .max_pos = 256, .kohms = 50, }, - [CAT5140_104] = { .wipers = 1, .max_pos = 256, .kohms = 100, }, + [CAT5140_503] = { .wipers = 1, .avail = { 0, 1, 255 }, .kohms = 50, }, + [CAT5140_104] = { .wipers = 1, .avail = { 0, 1, 255 }, .kohms = 100, }, /* ti parts */ - [TPL0102_104] = { .wipers = 2, .max_pos = 256, .kohms = 100 }, - [TPL0401_103] = { .wipers = 1, .max_pos = 128, .kohms = 10, }, + [TPL0102_104] = { .wipers = 2, .avail = { 0, 1, 255 }, .kohms = 100 }, + [TPL0401_103] = { .wipers = 1, .avail = { 0, 1, 127 }, .kohms = 10, }, }; struct tpl0102_data { struct regmap *regmap; - unsigned long devid; + const struct tpl0102_cfg *cfg; }; static const struct regmap_config tpl0102_regmap_config = { @@ -60,6 +52,7 @@ static const struct regmap_config tpl0102_regmap_config = { .channel = (ch), \ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ + .info_mask_separate_available = BIT(IIO_CHAN_INFO_RAW), \ } static const struct iio_chan_spec tpl0102_channels[] = { @@ -80,14 +73,32 @@ static int tpl0102_read_raw(struct iio_dev *indio_dev, return ret ? ret : IIO_VAL_INT; } case IIO_CHAN_INFO_SCALE: - *val = 1000 * tpl0102_cfg[data->devid].kohms; - *val2 = tpl0102_cfg[data->devid].max_pos; + *val = 1000 * data->cfg->kohms; + *val2 = data->cfg->avail[2] + 1; return IIO_VAL_FRACTIONAL; } return -EINVAL; } +static int tpl0102_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + const int **vals, int *type, int *length, + long mask) +{ + struct tpl0102_data *data = iio_priv(indio_dev); + + switch (mask) { + case IIO_CHAN_INFO_RAW: + *length = ARRAY_SIZE(data->cfg->avail); + *vals = data->cfg->avail; + *type = IIO_VAL_INT; + return IIO_AVAIL_RANGE; + } + + return -EINVAL; +} + static int tpl0102_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int val, int val2, long mask) @@ -97,7 +108,7 @@ static int tpl0102_write_raw(struct iio_dev *indio_dev, if (mask != IIO_CHAN_INFO_RAW) return -EINVAL; - if (val >= tpl0102_cfg[data->devid].max_pos || val < 0) + if (val > data->cfg->avail[2] || val < 0) return -EINVAL; return regmap_write(data->regmap, chan->channel, val); @@ -105,13 +116,13 @@ static int tpl0102_write_raw(struct iio_dev *indio_dev, static const struct iio_info tpl0102_info = { .read_raw = tpl0102_read_raw, + .read_avail = tpl0102_read_avail, .write_raw = tpl0102_write_raw, - .driver_module = THIS_MODULE, }; -static int tpl0102_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static int tpl0102_probe(struct i2c_client *client) { + const struct i2c_device_id *id = i2c_client_get_device_id(client); struct device *dev = &client->dev; struct tpl0102_data *data; struct iio_dev *indio_dev; @@ -122,17 +133,16 @@ static int tpl0102_probe(struct i2c_client *client, data = iio_priv(indio_dev); i2c_set_clientdata(client, indio_dev); - data->devid = id->driver_data; + data->cfg = &tpl0102_cfg[id->driver_data]; data->regmap = devm_regmap_init_i2c(client, &tpl0102_regmap_config); if (IS_ERR(data->regmap)) { dev_err(dev, "regmap initialization failed\n"); return PTR_ERR(data->regmap); } - indio_dev->dev.parent = dev; indio_dev->info = &tpl0102_info; indio_dev->channels = tpl0102_channels; - indio_dev->num_channels = tpl0102_cfg[data->devid].wipers; + indio_dev->num_channels = data->cfg->wipers; indio_dev->name = client->name; return devm_iio_device_register(dev, indio_dev); @@ -143,7 +153,7 @@ static const struct i2c_device_id tpl0102_id[] = { { "cat5140-104", CAT5140_104 }, { "tpl0102-104", TPL0102_104 }, { "tpl0401-103", TPL0401_103 }, - {} + { } }; MODULE_DEVICE_TABLE(i2c, tpl0102_id); @@ -157,6 +167,6 @@ static struct i2c_driver tpl0102_driver = { module_i2c_driver(tpl0102_driver); -MODULE_AUTHOR("Matt Ranostay <mranostay@gmail.com>"); +MODULE_AUTHOR("Matt Ranostay <matt.ranostay@konsulko.com>"); MODULE_DESCRIPTION("TPL0102 digital potentiometer"); MODULE_LICENSE("GPL"); |
