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 --- --- 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);