summaryrefslogtreecommitdiff
path: root/drivers/iio/adc/max1363.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/iio/adc/max1363.c')
-rw-r--r--drivers/iio/adc/max1363.c81
1 files changed, 49 insertions, 32 deletions
diff --git a/drivers/iio/adc/max1363.c b/drivers/iio/adc/max1363.c
index 08e4feb..6c1cfb7 100644
--- a/drivers/iio/adc/max1363.c
+++ b/drivers/iio/adc/max1363.c
@@ -163,6 +163,8 @@ struct max1363_chip_info {
* @mask_low: bitmask for enabled low thresholds
* @thresh_high: high threshold values
* @thresh_low: low threshold values
+ * @vref: Reference voltage regulator
+ * @vref_uv: Actual (external or internal) reference voltage
*/
struct max1363_state {
struct i2c_client *client;
@@ -182,6 +184,8 @@ struct max1363_state {
/* 4x unipolar first then the fours bipolar ones */
s16 thresh_high[8];
s16 thresh_low[8];
+ struct regulator *vref;
+ u32 vref_uv;
};
#define MAX1363_MODE_SINGLE(_num, _mask) { \
@@ -393,6 +397,8 @@ static int max1363_read_raw(struct iio_dev *indio_dev,
{
struct max1363_state *st = iio_priv(indio_dev);
int ret;
+ unsigned long scale_uv;
+
switch (m) {
case IIO_CHAN_INFO_RAW:
ret = max1363_read_single_chan(indio_dev, chan, val, m);
@@ -400,16 +406,10 @@ static int max1363_read_raw(struct iio_dev *indio_dev,
return ret;
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
- if ((1 << (st->chip_info->bits + 1)) >
- st->chip_info->int_vref_mv) {
- *val = 0;
- *val2 = 500000;
- return IIO_VAL_INT_PLUS_MICRO;
- } else {
- *val = (st->chip_info->int_vref_mv)
- >> st->chip_info->bits;
- return IIO_VAL_INT;
- }
+ scale_uv = st->vref_uv >> st->chip_info->bits;
+ *val = scale_uv / 1000;
+ *val2 = (scale_uv % 1000) * 1000;
+ return IIO_VAL_INT_PLUS_MICRO;
default:
return -EINVAL;
}
@@ -1390,12 +1390,16 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {
static int max1363_initial_setup(struct max1363_state *st)
{
- st->setupbyte = MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_VDD
- | MAX1363_SETUP_POWER_UP_INT_REF
- | MAX1363_SETUP_INT_CLOCK
+ st->setupbyte = MAX1363_SETUP_INT_CLOCK
| MAX1363_SETUP_UNIPOLAR
| MAX1363_SETUP_NORESET;
+ if (st->vref)
+ st->setupbyte |= MAX1363_SETUP_AIN3_IS_REF_EXT_TO_REF;
+ else
+ st->setupbyte |= MAX1363_SETUP_POWER_UP_INT_REF
+ | MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_INT;
+
/* Set scan mode writes the config anyway so wait until then */
st->setupbyte = MAX1363_SETUP_BYTE(st->setupbyte);
st->current_mode = &max1363_mode_table[st->chip_info->default_mode];
@@ -1410,8 +1414,9 @@ static int max1363_alloc_scan_masks(struct iio_dev *indio_dev)
unsigned long *masks;
int i;
- masks = kzalloc(BITS_TO_LONGS(MAX1363_MAX_CHANNELS)*sizeof(long)*
- (st->chip_info->num_modes + 1), GFP_KERNEL);
+ masks = devm_kzalloc(&indio_dev->dev,
+ BITS_TO_LONGS(MAX1363_MAX_CHANNELS) * sizeof(long) *
+ (st->chip_info->num_modes + 1), GFP_KERNEL);
if (!masks)
return -ENOMEM;
@@ -1490,6 +1495,7 @@ static int max1363_probe(struct i2c_client *client,
int ret;
struct max1363_state *st;
struct iio_dev *indio_dev;
+ struct regulator *vref;
indio_dev = iio_device_alloc(sizeof(struct max1363_state));
if (indio_dev == NULL) {
@@ -1504,7 +1510,7 @@ static int max1363_probe(struct i2c_client *client,
st = iio_priv(indio_dev);
- st->reg = regulator_get(&client->dev, "vcc");
+ st->reg = devm_regulator_get(&client->dev, "vcc");
if (IS_ERR(st->reg)) {
ret = PTR_ERR(st->reg);
goto error_unregister_map;
@@ -1512,7 +1518,7 @@ static int max1363_probe(struct i2c_client *client,
ret = regulator_enable(st->reg);
if (ret)
- goto error_put_reg;
+ goto error_unregister_map;
/* this is only used for device removal purposes */
i2c_set_clientdata(client, indio_dev);
@@ -1520,6 +1526,23 @@ static int max1363_probe(struct i2c_client *client,
st->chip_info = &max1363_chip_info_tbl[id->driver_data];
st->client = client;
+ st->vref_uv = st->chip_info->int_vref_mv * 1000;
+ vref = devm_regulator_get(&client->dev, "vref");
+ if (!IS_ERR(vref)) {
+ int vref_uv;
+
+ ret = regulator_enable(vref);
+ if (ret)
+ goto error_disable_reg;
+ st->vref = vref;
+ vref_uv = regulator_get_voltage(vref);
+ if (vref_uv <= 0) {
+ ret = -EINVAL;
+ goto error_disable_reg;
+ }
+ st->vref_uv = vref_uv;
+ }
+
ret = max1363_alloc_scan_masks(indio_dev);
if (ret)
goto error_disable_reg;
@@ -1533,15 +1556,15 @@ static int max1363_probe(struct i2c_client *client,
indio_dev->modes = INDIO_DIRECT_MODE;
ret = max1363_initial_setup(st);
if (ret < 0)
- goto error_free_available_scan_masks;
+ goto error_disable_reg;
ret = iio_triggered_buffer_setup(indio_dev, NULL,
&max1363_trigger_handler, &max1363_buffered_setup_ops);
if (ret)
- goto error_free_available_scan_masks;
+ goto error_disable_reg;
if (client->irq) {
- ret = request_threaded_irq(st->client->irq,
+ ret = devm_request_threaded_irq(&client->dev, st->client->irq,
NULL,
&max1363_event_handler,
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
@@ -1554,20 +1577,16 @@ static int max1363_probe(struct i2c_client *client,
ret = iio_device_register(indio_dev);
if (ret < 0)
- goto error_free_irq;
+ goto error_uninit_buffer;
return 0;
-error_free_irq:
- if (client->irq)
- free_irq(st->client->irq, indio_dev);
+
error_uninit_buffer:
iio_triggered_buffer_cleanup(indio_dev);
-error_free_available_scan_masks:
- kfree(indio_dev->available_scan_masks);
error_disable_reg:
+ if (st->vref)
+ regulator_disable(st->vref);
regulator_disable(st->reg);
-error_put_reg:
- regulator_put(st->reg);
error_unregister_map:
iio_map_array_unregister(indio_dev);
error_free_device:
@@ -1582,12 +1601,10 @@ static int max1363_remove(struct i2c_client *client)
struct max1363_state *st = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
- if (client->irq)
- free_irq(st->client->irq, indio_dev);
iio_triggered_buffer_cleanup(indio_dev);
- kfree(indio_dev->available_scan_masks);
+ if (st->vref)
+ regulator_disable(st->vref);
regulator_disable(st->reg);
- regulator_put(st->reg);
iio_map_array_unregister(indio_dev);
iio_device_free(indio_dev);