You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
openwrt/target/linux/generic/patches-3.13/065-iio_ad799x_backport_fix...

139 lines
3.7 KiB
Diff

Backport essential fixes from 3.15
From Linux 3.10 on this driver required platform data to load, which makes it
unusable in OpenWRT. This commit backports the following fixes:
* Move to regulator framework for scaling
* Set endianness of the ADC to Big endian
* Fix device-removal path
This commit should not be moved to newer kernel versions!
Signed-off-by: Hartmut Knaack <knaack.h@gmx.de>
---
--- a/drivers/staging/iio/adc/ad799x_core.c
+++ b/drivers/staging/iio/adc/ad799x_core.c
@@ -179,7 +179,10 @@ static int ad799x_read_raw(struct iio_de
RES_MASK(chan->scan_type.realbits);
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
- *val = st->int_vref_mv;
+ ret = regulator_get_voltage(st->vref);
+ if (ret < 0)
+ return ret;
+ *val = ret / 1000;
*val2 = chan->scan_type.realbits;
return IIO_VAL_FRACTIONAL_LOG2;
}
@@ -409,7 +412,13 @@ static const struct iio_event_spec ad799
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
.scan_index = (_index), \
- .scan_type = IIO_ST('u', _realbits, 16, 12 - (_realbits)), \
+ .scan_type = { \
+ .sign = 'u', \
+ .realbits = (_realbits), \
+ .storagebits = 16, \
+ .shift = 12 - (_realbits), \
+ .endianness = IIO_BE, \
+ }, \
.event_spec = _ev_spec, \
.num_event_specs = _num_ev_spec, \
}
@@ -527,7 +536,6 @@ static int ad799x_probe(struct i2c_clien
const struct i2c_device_id *id)
{
int ret;
- struct ad799x_platform_data *pdata = client->dev.platform_data;
struct ad799x_state *st;
struct iio_dev *indio_dev;
@@ -545,17 +553,21 @@ static int ad799x_probe(struct i2c_clien
/* TODO: Add pdata options for filtering and bit delay */
- if (!pdata)
- return -EINVAL;
-
- st->int_vref_mv = pdata->vref_mv;
-
st->reg = devm_regulator_get(&client->dev, "vcc");
- if (!IS_ERR(st->reg)) {
- ret = regulator_enable(st->reg);
- if (ret)
- return ret;
+ if (IS_ERR(st->reg))
+ return PTR_ERR(st->reg);
+ ret = regulator_enable(st->reg);
+ if (ret)
+ return ret;
+ st->vref = devm_regulator_get(&client->dev, "vref");
+ if (IS_ERR(st->vref)) {
+ ret = PTR_ERR(st->vref);
+ goto error_disable_reg;
}
+ ret = regulator_enable(st->vref);
+ if (ret)
+ goto error_disable_reg;
+
st->client = client;
indio_dev->dev.parent = &client->dev;
@@ -568,7 +580,7 @@ static int ad799x_probe(struct i2c_clien
ret = ad799x_register_ring_funcs_and_init(indio_dev);
if (ret)
- goto error_disable_reg;
+ goto error_disable_vref;
if (client->irq > 0) {
ret = request_threaded_irq(client->irq,
@@ -592,9 +604,10 @@ error_free_irq:
free_irq(client->irq, indio_dev);
error_cleanup_ring:
ad799x_ring_cleanup(indio_dev);
+error_disable_vref:
+ regulator_disable(st->vref);
error_disable_reg:
- if (!IS_ERR(st->reg))
- regulator_disable(st->reg);
+ regulator_disable(st->reg);
return ret;
}
@@ -609,8 +622,8 @@ static int ad799x_remove(struct i2c_clie
free_irq(client->irq, indio_dev);
ad799x_ring_cleanup(indio_dev);
- if (!IS_ERR(st->reg))
- regulator_disable(st->reg);
+ regulator_disable(st->vref);
+ regulator_disable(st->reg);
kfree(st->rx_buf);
return 0;
--- a/drivers/staging/iio/adc/ad799x.h
+++ b/drivers/staging/iio/adc/ad799x.h
@@ -95,7 +95,7 @@ struct ad799x_state {
struct i2c_client *client;
const struct ad799x_chip_info *chip_info;
struct regulator *reg;
- u16 int_vref_mv;
+ struct regulator *vref;
unsigned id;
u16 config;
@@ -103,14 +103,6 @@ struct ad799x_state {
unsigned int transfer_size;
};
-/*
- * TODO: struct ad799x_platform_data needs to go into include/linux/iio
- */
-
-struct ad799x_platform_data {
- u16 vref_mv;
-};
-
#ifdef CONFIG_AD799X_RING_BUFFER
int ad799x_register_ring_funcs_and_init(struct iio_dev *indio_dev);
void ad799x_ring_cleanup(struct iio_dev *indio_dev);