diff options
author | Hauke Mehrtens <hauke@openwrt.org> | 2014-09-13 20:34:44 +0000 |
---|---|---|
committer | Hauke Mehrtens <hauke@openwrt.org> | 2014-09-13 20:34:44 +0000 |
commit | 0e4a30a311ec76db382c1d05b62b349f74fc019c (patch) | |
tree | 6cac83e4dde4d36e92f313175557abbb66c146e2 /target/linux/generic/patches-3.13 | |
parent | 21e8979db9c46ff08c8da9cccd5c11fdf60a8969 (diff) | |
download | upstream-0e4a30a311ec76db382c1d05b62b349f74fc019c.tar.gz upstream-0e4a30a311ec76db382c1d05b62b349f74fc019c.tar.bz2 upstream-0e4a30a311ec76db382c1d05b62b349f74fc019c.zip |
kernel: Backport essential fixes for ad799x
This series of patches ports back some fixes of the ad799x driver, which were
commited between 3.10 and 3.15.
Signed-off-by: Hartmut Knaack <knaack.h@gmx.de>
git-svn-id: svn://svn.openwrt.org/openwrt/trunk@42523 3c298f89-4303-0410-b956-a3cf2f4a3e73
Diffstat (limited to 'target/linux/generic/patches-3.13')
-rw-r--r-- | target/linux/generic/patches-3.13/065-iio_ad799x_backport_fixes.patch | 138 |
1 files changed, 138 insertions, 0 deletions
diff --git a/target/linux/generic/patches-3.13/065-iio_ad799x_backport_fixes.patch b/target/linux/generic/patches-3.13/065-iio_ad799x_backport_fixes.patch new file mode 100644 index 0000000000..36844ce7d8 --- /dev/null +++ b/target/linux/generic/patches-3.13/065-iio_ad799x_backport_fixes.patch @@ -0,0 +1,138 @@ +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); |