Commit bad4f537 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge tag 'iio-for-3.12b' of...

Merge tag 'iio-for-3.12b' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-next

Jonathan writes:

Second round of new drivers, features and cleanups for IIO in the 3.12 cycle.

New driver:

1) tmp006 IR thermopile driver.  This is an unusual temperature sensor
   and was taken in to IIO with the knowledge and agreement of a hwmon
   maintainer.
   It measures remote temperature using infrared emissions.
   I guess taking this may mean we have to fight off submissions of
   devices much more suited to hwmon but such is life and we end up
   doing this from time to time already.

2) twl6030 adc driver.

Cleanups:

1) More devm_* cleanups following on from the introduction of
   devm_iio_device_alloc.  Mostly an heroic effort from
   Sachin Kamat!

2) Introduce devm_iio_trigger_alloc etc to handle trigger
   allocation and deallocation in a managed fashion.  There
   aren't as many instances of triggers as devices, but this
   will allow futher reduction in error patch complexity in
   some of our most complex drivers making it a very good thing.
3) Trivial removal of unused defines in adjd_s311

4) Drop some write_raw_get_fmt callbacks where they were only
   returning the default value.

5) Change mxs-lradc realbits to 12.  Whilst an 18bit register
   is used on the device, in its current mode only 12 bits of
   useful data are returned.  For now the packing is unchanged
   in the buffer and this change mainly effects the input support
   in the driver.
parents 9c6cd3b3 cc566fd5
......@@ -240,6 +240,8 @@ MEM
IIO
devm_iio_device_alloc()
devm_iio_device_free()
devm_iio_trigger_alloc()
devm_iio_trigger_free()
IO region
devm_request_region()
......
......@@ -73,5 +73,6 @@ if IIO_TRIGGER
source "drivers/iio/trigger/Kconfig"
endif #IIO_TRIGGER
source "drivers/iio/pressure/Kconfig"
source "drivers/iio/temperature/Kconfig"
endif # IIO
......@@ -21,5 +21,6 @@ obj-y += frequency/
obj-y += imu/
obj-y += light/
obj-y += magnetometer/
obj-y += trigger/
obj-y += pressure/
obj-y += temperature/
obj-y += trigger/
......@@ -175,18 +175,10 @@ static int accel_3d_write_raw(struct iio_dev *indio_dev,
return ret;
}
static int accel_3d_write_raw_get_fmt(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
long mask)
{
return IIO_VAL_INT_PLUS_MICRO;
}
static const struct iio_info accel_3d_info = {
.driver_module = THIS_MODULE,
.read_raw = &accel_3d_read_raw,
.write_raw = &accel_3d_write_raw,
.write_raw_get_fmt = &accel_3d_write_raw_get_fmt,
};
/* Function to push data to buffer */
......
......@@ -171,6 +171,20 @@ config TI_AM335X_ADC
Say yes here to build support for Texas Instruments ADC
driver which is also a MFD client.
config TWL6030_GPADC
tristate "TWL6030 GPADC (General Purpose A/D Converter) Support"
depends on TWL4030_CORE
default n
help
Say yes here if you want support for the TWL6030/TWL6032 General
Purpose A/D Converter. This will add support for battery type
detection, battery voltage and temperature measurement, die
temperature measurement, system supply voltage, audio accessory,
USB ID detection.
This driver can also be built as a module. If so, the module will be
called twl6030-gpadc.
config VIPERBOARD_ADC
tristate "Viperboard ADC support"
depends on MFD_VIPERBOARD && USB
......
......@@ -19,4 +19,5 @@ obj-$(CONFIG_MCP320X) += mcp320x.o
obj-$(CONFIG_NAU7802) += nau7802.o
obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o
obj-$(CONFIG_TWL6030_GPADC) += twl6030-gpadc.o
obj-$(CONFIG_VIPERBOARD_ADC) += viperboard_adc.o
This diff is collapsed.
......@@ -442,7 +442,7 @@ static int ad5064_probe(struct device *dev, enum ad5064_type type,
unsigned int i;
int ret;
indio_dev = iio_device_alloc(sizeof(*st));
indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
if (indio_dev == NULL)
return -ENOMEM;
......@@ -456,23 +456,23 @@ static int ad5064_probe(struct device *dev, enum ad5064_type type,
for (i = 0; i < ad5064_num_vref(st); ++i)
st->vref_reg[i].supply = ad5064_vref_name(st, i);
ret = regulator_bulk_get(dev, ad5064_num_vref(st),
ret = devm_regulator_bulk_get(dev, ad5064_num_vref(st),
st->vref_reg);
if (ret) {
if (!st->chip_info->internal_vref)
goto error_free;
return ret;
st->use_internal_vref = true;
ret = ad5064_write(st, AD5064_CMD_CONFIG, 0,
AD5064_CONFIG_INT_VREF_ENABLE, 0);
if (ret) {
dev_err(dev, "Failed to enable internal vref: %d\n",
ret);
goto error_free;
return ret;
}
} else {
ret = regulator_bulk_enable(ad5064_num_vref(st), st->vref_reg);
if (ret)
goto error_free_reg;
return ret;
}
indio_dev->dev.parent = dev;
......@@ -498,11 +498,6 @@ static int ad5064_probe(struct device *dev, enum ad5064_type type,
error_disable_reg:
if (!st->use_internal_vref)
regulator_bulk_disable(ad5064_num_vref(st), st->vref_reg);
error_free_reg:
if (!st->use_internal_vref)
regulator_bulk_free(ad5064_num_vref(st), st->vref_reg);
error_free:
iio_device_free(indio_dev);
return ret;
}
......@@ -514,12 +509,8 @@ static int ad5064_remove(struct device *dev)
iio_device_unregister(indio_dev);
if (!st->use_internal_vref) {
if (!st->use_internal_vref)
regulator_bulk_disable(ad5064_num_vref(st), st->vref_reg);
regulator_bulk_free(ad5064_num_vref(st), st->vref_reg);
}
iio_device_free(indio_dev);
return 0;
}
......
......@@ -459,7 +459,7 @@ static int ad5360_probe(struct spi_device *spi)
unsigned int i;
int ret;
indio_dev = iio_device_alloc(sizeof(*st));
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (indio_dev == NULL) {
dev_err(&spi->dev, "Failed to allocate iio device\n");
return -ENOMEM;
......@@ -480,13 +480,13 @@ static int ad5360_probe(struct spi_device *spi)
ret = ad5360_alloc_channels(indio_dev);
if (ret) {
dev_err(&spi->dev, "Failed to allocate channel spec: %d\n", ret);
goto error_free;
return ret;
}
for (i = 0; i < st->chip_info->num_vrefs; ++i)
st->vref_reg[i].supply = ad5360_vref_name[i];
ret = regulator_bulk_get(&st->spi->dev, st->chip_info->num_vrefs,
ret = devm_regulator_bulk_get(&st->spi->dev, st->chip_info->num_vrefs,
st->vref_reg);
if (ret) {
dev_err(&spi->dev, "Failed to request vref regulators: %d\n", ret);
......@@ -496,7 +496,7 @@ static int ad5360_probe(struct spi_device *spi)
ret = regulator_bulk_enable(st->chip_info->num_vrefs, st->vref_reg);
if (ret) {
dev_err(&spi->dev, "Failed to enable vref regulators: %d\n", ret);
goto error_free_reg;
goto error_free_channels;
}
ret = iio_device_register(indio_dev);
......@@ -509,12 +509,8 @@ static int ad5360_probe(struct spi_device *spi)
error_disable_reg:
regulator_bulk_disable(st->chip_info->num_vrefs, st->vref_reg);
error_free_reg:
regulator_bulk_free(st->chip_info->num_vrefs, st->vref_reg);
error_free_channels:
kfree(indio_dev->channels);
error_free:
iio_device_free(indio_dev);
return ret;
}
......@@ -529,9 +525,6 @@ static int ad5360_remove(struct spi_device *spi)
kfree(indio_dev->channels);
regulator_bulk_disable(st->chip_info->num_vrefs, st->vref_reg);
regulator_bulk_free(st->chip_info->num_vrefs, st->vref_reg);
iio_device_free(indio_dev);
return 0;
}
......
......@@ -369,11 +369,10 @@ static int ad5380_probe(struct device *dev, struct regmap *regmap,
unsigned int ctrl = 0;
int ret;
indio_dev = iio_device_alloc(sizeof(*st));
indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
if (indio_dev == NULL) {
dev_err(dev, "Failed to allocate iio device\n");
ret = -ENOMEM;
goto error_out;
return -ENOMEM;
}
st = iio_priv(indio_dev);
......@@ -391,13 +390,13 @@ static int ad5380_probe(struct device *dev, struct regmap *regmap,
ret = ad5380_alloc_channels(indio_dev);
if (ret) {
dev_err(dev, "Failed to allocate channel spec: %d\n", ret);
goto error_free;
return ret;
}
if (st->chip_info->int_vref == 2500000)
ctrl |= AD5380_CTRL_INT_VREF_2V5;
st->vref_reg = regulator_get(dev, "vref");
st->vref_reg = devm_regulator_get(dev, "vref");
if (!IS_ERR(st->vref_reg)) {
ret = regulator_enable(st->vref_reg);
if (ret) {
......@@ -434,13 +433,7 @@ static int ad5380_probe(struct device *dev, struct regmap *regmap,
if (!IS_ERR(st->vref_reg))
regulator_disable(st->vref_reg);
error_free_reg:
if (!IS_ERR(st->vref_reg))
regulator_put(st->vref_reg);
kfree(indio_dev->channels);
error_free:
iio_device_free(indio_dev);
error_out:
return ret;
}
......@@ -456,11 +449,8 @@ static int ad5380_remove(struct device *dev)
if (!IS_ERR(st->vref_reg)) {
regulator_disable(st->vref_reg);
regulator_put(st->vref_reg);
}
iio_device_free(indio_dev);
return 0;
}
......
......@@ -451,7 +451,7 @@ static int ad5421_probe(struct spi_device *spi)
struct ad5421_state *st;
int ret;
indio_dev = iio_device_alloc(sizeof(*st));
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (indio_dev == NULL) {
dev_err(&spi->dev, "Failed to allocate iio device\n");
return -ENOMEM;
......@@ -484,31 +484,23 @@ static int ad5421_probe(struct spi_device *spi)
ad5421_update_ctrl(indio_dev, 0, 0);
if (spi->irq) {
ret = request_threaded_irq(spi->irq,
ret = devm_request_threaded_irq(&spi->dev, spi->irq,
NULL,
ad5421_fault_handler,
IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
"ad5421 fault",
indio_dev);
if (ret)
goto error_free;
return ret;
}
ret = iio_device_register(indio_dev);
if (ret) {
dev_err(&spi->dev, "Failed to register iio device: %d\n", ret);
goto error_free_irq;
return ret;
}
return 0;
error_free_irq:
if (spi->irq)
free_irq(spi->irq, indio_dev);
error_free:
iio_device_free(indio_dev);
return ret;
}
static int ad5421_remove(struct spi_device *spi)
......@@ -516,9 +508,6 @@ static int ad5421_remove(struct spi_device *spi)
struct iio_dev *indio_dev = spi_get_drvdata(spi);
iio_device_unregister(indio_dev);
if (spi->irq)
free_irq(spi->irq, indio_dev);
iio_device_free(indio_dev);
return 0;
}
......
......@@ -220,11 +220,11 @@ static int ad5446_probe(struct device *dev, const char *name,
struct regulator *reg;
int ret, voltage_uv = 0;
reg = regulator_get(dev, "vcc");
reg = devm_regulator_get(dev, "vcc");
if (!IS_ERR(reg)) {
ret = regulator_enable(reg);
if (ret)
goto error_put_reg;
return ret;
ret = regulator_get_voltage(reg);
if (ret < 0)
......@@ -233,7 +233,7 @@ static int ad5446_probe(struct device *dev, const char *name,
voltage_uv = ret;
}
indio_dev = iio_device_alloc(sizeof(*st));
indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
if (indio_dev == NULL) {
ret = -ENOMEM;
goto error_disable_reg;
......@@ -264,19 +264,13 @@ static int ad5446_probe(struct device *dev, const char *name,
ret = iio_device_register(indio_dev);
if (ret)
goto error_free_device;
goto error_disable_reg;
return 0;
error_free_device:
iio_device_free(indio_dev);
error_disable_reg:
if (!IS_ERR(reg))
regulator_disable(reg);
error_put_reg:
if (!IS_ERR(reg))
regulator_put(reg);
return ret;
}
......@@ -286,11 +280,8 @@ static int ad5446_remove(struct device *dev)
struct ad5446_state *st = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
if (!IS_ERR(st->reg)) {
if (!IS_ERR(st->reg))
regulator_disable(st->reg);
regulator_put(st->reg);
}
iio_device_free(indio_dev);
return 0;
}
......
......@@ -275,7 +275,7 @@ static int ad5449_spi_probe(struct spi_device *spi)
unsigned int i;
int ret;
indio_dev = iio_device_alloc(sizeof(*st));
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (indio_dev == NULL)
return -ENOMEM;
......@@ -288,14 +288,14 @@ static int ad5449_spi_probe(struct spi_device *spi)
for (i = 0; i < st->chip_info->num_channels; ++i)
st->vref_reg[i].supply = ad5449_vref_name(st, i);
ret = regulator_bulk_get(&spi->dev, st->chip_info->num_channels,
ret = devm_regulator_bulk_get(&spi->dev, st->chip_info->num_channels,
st->vref_reg);
if (ret)
goto error_free;
return ret;
ret = regulator_bulk_enable(st->chip_info->num_channels, st->vref_reg);
if (ret)
goto error_free_reg;
return ret;
indio_dev->dev.parent = &spi->dev;
indio_dev->name = id->name;
......@@ -325,10 +325,6 @@ static int ad5449_spi_probe(struct spi_device *spi)
error_disable_reg:
regulator_bulk_disable(st->chip_info->num_channels, st->vref_reg);
error_free_reg:
regulator_bulk_free(st->chip_info->num_channels, st->vref_reg);
error_free:
iio_device_free(indio_dev);
return ret;
}
......@@ -341,9 +337,6 @@ static int ad5449_spi_remove(struct spi_device *spi)
iio_device_unregister(indio_dev);
regulator_bulk_disable(st->chip_info->num_channels, st->vref_reg);
regulator_bulk_free(st->chip_info->num_channels, st->vref_reg);
iio_device_free(indio_dev);
return 0;
}
......
......@@ -281,16 +281,14 @@ static int ad5504_probe(struct spi_device *spi)
struct regulator *reg;
int ret, voltage_uv = 0;
indio_dev = iio_device_alloc(sizeof(*st));
if (indio_dev == NULL) {
ret = -ENOMEM;
goto error_ret;
}
reg = regulator_get(&spi->dev, "vcc");
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (!indio_dev)
return -ENOMEM;
reg = devm_regulator_get(&spi->dev, "vcc");
if (!IS_ERR(reg)) {
ret = regulator_enable(reg);
if (ret)
goto error_put_reg;
return ret;
ret = regulator_get_voltage(reg);
if (ret < 0)
......@@ -321,7 +319,7 @@ static int ad5504_probe(struct spi_device *spi)
indio_dev->modes = INDIO_DIRECT_MODE;
if (spi->irq) {
ret = request_threaded_irq(spi->irq,
ret = devm_request_threaded_irq(&spi->dev, spi->irq,
NULL,
&ad5504_event_handler,
IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
......@@ -333,22 +331,14 @@ static int ad5504_probe(struct spi_device *spi)
ret = iio_device_register(indio_dev);
if (ret)
goto error_free_irq;
goto error_disable_reg;
return 0;
error_free_irq:
if (spi->irq)
free_irq(spi->irq, indio_dev);
error_disable_reg:
if (!IS_ERR(reg))
regulator_disable(reg);
error_put_reg:
if (!IS_ERR(reg))
regulator_put(reg);
iio_device_free(indio_dev);
error_ret:
return ret;
}
......@@ -358,14 +348,9 @@ static int ad5504_remove(struct spi_device *spi)
struct ad5504_state *st = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
if (spi->irq)
free_irq(spi->irq, indio_dev);
if (!IS_ERR(st->reg)) {
if (!IS_ERR(st->reg))
regulator_disable(st->reg);
regulator_put(st->reg);
}
iio_device_free(indio_dev);
return 0;
}
......
......@@ -226,17 +226,15 @@ static int ad5624r_probe(struct spi_device *spi)
struct iio_dev *indio_dev;
int ret, voltage_uv = 0;
indio_dev = iio_device_alloc(sizeof(*st));
if (indio_dev == NULL) {
ret = -ENOMEM;
goto error_ret;
}
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (!indio_dev)
return -ENOMEM;
st = iio_priv(indio_dev);
st->reg = regulator_get(&spi->dev, "vcc");
st->reg = devm_regulator_get(&spi->dev, "vcc");
if (!IS_ERR(st->reg)) {
ret = regulator_enable(st->reg);
if (ret)
goto error_put_reg;
return ret;
ret = regulator_get_voltage(st->reg);
if (ret < 0)
......@@ -277,11 +275,6 @@ static int ad5624r_probe(struct spi_device *spi)
error_disable_reg:
if (!IS_ERR(st->reg))
regulator_disable(st->reg);
error_put_reg:
if (!IS_ERR(st->reg))
regulator_put(st->reg);
iio_device_free(indio_dev);
error_ret:
return ret;
}
......@@ -292,11 +285,8 @@ static int ad5624r_remove(struct spi_device *spi)
struct ad5624r_state *st = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
if (!IS_ERR(st->reg)) {
if (!IS_ERR(st->reg))
regulator_disable(st->reg);
regulator_put(st->reg);
}
iio_device_free(indio_dev);
return 0;
}
......
......@@ -314,18 +314,18 @@ static int ad5686_probe(struct spi_device *spi)
struct iio_dev *indio_dev;
int ret, regdone = 0, voltage_uv = 0;
indio_dev = iio_device_alloc(sizeof(*st));
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (indio_dev == NULL)
return -ENOMEM;
st = iio_priv(indio_dev);
spi_set_drvdata(spi, indio_dev);
st->reg = regulator_get(&spi->dev, "vcc");
st->reg = devm_regulator_get(&spi->dev, "vcc");
if (!IS_ERR(st->reg)) {
ret = regulator_enable(st->reg);
if (ret)
goto error_put_reg;
return ret;
ret = regulator_get_voltage(st->reg);
if (ret < 0)
......@@ -369,12 +369,6 @@ static int ad5686_probe(struct spi_device *spi)
error_disable_reg:
if (!IS_ERR(st->reg))
regulator_disable(st->reg);
error_put_reg:
if (!IS_ERR(st->reg))
regulator_put(st->reg);
iio_device_free(indio_dev);
return ret;
}
......@@ -384,11 +378,8 @@ static int ad5686_remove(struct spi_device *spi)
struct ad5686_state *st = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
if (!IS_ERR(st->reg)) {
if (!IS_ERR(st->reg))
regulator_disable(st->reg);
regulator_put(st->reg);
}
iio_device_free(indio_dev);
return 0;
}
......
......@@ -565,7 +565,7 @@ static int ad5755_probe(struct spi_device *spi)
struct ad5755_state *st;
int ret;
indio_dev = iio_device_alloc(sizeof(*st));
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (indio_dev == NULL) {
dev_err(&spi->dev, "Failed to allocate iio device\n");
return -ENOMEM;
......@@ -589,24 +589,19 @@ static int ad5755_probe(struct spi_device *spi)
ret = ad5755_init_channels(indio_dev, pdata);
if (ret)
goto error_free;
return ret;
ret = ad5755_setup_pdata(indio_dev, pdata);
if (ret)
goto error_free;
return ret;
ret = iio_device_register(indio_dev);
if (ret) {
dev_err(&spi->dev, "Failed to register iio device: %d\n", ret);
goto error_free;
return ret;
}
return 0;
error_free:
iio_device_free(indio_dev);
return ret;
}
static int ad5755_remove(struct spi_device *spi)
......@@ -614,7 +609,6 @@ static int ad5755_remove(struct spi_device *spi)
struct iio_dev *indio_dev = spi_get_drvdata(spi);
iio_device_unregister(indio_dev);
iio_device_free(indio_dev);
return 0;
}
......
......@@ -275,7 +275,7 @@ static int ad5764_probe(struct spi_device *spi)
struct ad5764_state *st;
int ret;
indio_dev = iio_device_alloc(sizeof(*st));
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (indio_dev == NULL) {
dev_err(&spi->dev, "Failed to allocate iio device\n");
return -ENOMEM;
......@@ -298,12 +298,12 @@ static int ad5764_probe(struct spi_device *spi)
st->vref_reg[0].supply = "vrefAB";
st->vref_reg[1].supply = "vrefCD";
ret = regulator_bulk_get(&st->spi->dev,
ret = devm_regulator_bulk_get(&st->spi->dev,
ARRAY_SIZE(st->vref_reg), st->vref_reg);
if (ret) {
dev_err(&spi->dev, "Failed to request vref regulators: %d\n",
ret);
goto error_free;
return ret;
}
ret = regulator_bulk_enable(ARRAY_SIZE(st->vref_reg),
......@@ -311,7 +311,7 @@ static int ad5764_probe(struct spi_device *spi)
if (ret) {
dev_err(&spi->dev, "Failed to enable vref regulators: %d\n",
ret);
goto error_free_reg;
return ret;
}
}
......@@ -326,12 +326,6 @@ static int ad5764_probe(struct spi_device *spi)
error_disable_reg:
if (st->chip_info->int_vref == 0)
regulator_bulk_disable(ARRAY_SIZE(st->vref_reg), st->vref_reg);
error_free_reg:
if (st->chip_info->int_vref == 0)
regulator_bulk_free(ARRAY_SIZE(st->vref_reg), st->vref_reg);
error_free:
iio_device_free(indio_dev);
return ret;
}
......@@ -342,12 +336,8 @@ static int ad5764_remove(struct spi_device *spi)
iio_device_unregister(indio_dev);
if (st->chip_info->int_vref == 0) {
if (st->chip_info->int_vref == 0)
regulator_bulk_disable(ARRAY_SIZE(st->vref_reg), st->vref_reg);
regulator_bulk_free(ARRAY_SIZE(st->vref_reg), st->vref_reg);
}
iio_device_free(indio_dev);
return 0;
}
......
......@@ -349,17 +349,15 @@ static int ad5791_probe(struct spi_device *spi)
struct ad5791_state *st;
int ret, pos_voltage_uv = 0, neg_voltage_uv = 0;
indio_dev = iio_device_alloc(sizeof(*st));
if (indio_dev == NULL) {
ret = -ENOMEM;
goto error_ret;
}
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (!indio_dev)
return -ENOMEM;
st = iio_priv(indio_dev);
st->reg_vdd = regulator_get(&spi->dev, "vdd");
st->reg_vdd = devm_regulator_get(&spi->dev, "vdd");
if (!IS_ERR(st->reg_vdd)) {
ret = regulator_enable(st->reg_vdd);
if (ret)
goto error_put_reg_pos;
return ret;
ret = regulator_get_voltage(st->reg_vdd);
if (ret < 0)
......@@ -368,11 +366,11 @@ static int ad5791_probe(struct spi_device *spi)
pos_voltage_uv = ret;
}
st->reg_vss = regulator_get(&spi->dev, "vss");
st->reg_vss = devm_regulator_get(&spi->dev, "vss");
if (!IS_ERR(st->reg_vss)) {
ret = regulator_enable(st->reg_vss);
if (ret)
goto error_put_reg_neg;
goto error_disable_reg_pos;
ret = regulator_get_voltage(st->reg_vss);
if (ret < 0)
......@@ -428,19 +426,9 @@ static int ad5791_probe(struct spi_device *spi)
error_disable_reg_neg:
if (!IS_ERR(st->reg_vss))
regulator_disable(st->reg_vss);
error_put_reg_neg:
if (!IS_ERR(st->reg_vss))
regulator_put(st->reg_vss);
error_disable_reg_pos:
if (!IS_ERR(st->reg_vdd))
regulator_disable(st->reg_vdd);
error_put_reg_pos:
if (!IS_ERR(st->reg_vdd))
regulator_put(st->reg_vdd);
iio_device_free(indio_dev);
error_ret:
return ret;
}
......@@ -450,16 +438,11 @@ static int ad5791_remove(struct spi_device *spi)
struct ad5791_state *st = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
if (!IS_ERR(st->reg_vdd)) {
if (!IS_ERR(st->reg_vdd))
regulator_disable(st->reg_vdd);
regulator_put(st->reg_vdd);
}
if (!IS_ERR(st->reg_vss)) {
if (!IS_ERR(st->reg_vss))
regulator_disable(st->reg_vss);
regulator_put(st->reg_vss);
}
iio_device_free(indio_dev);
return 0;
}
......
......@@ -203,7 +203,7 @@ static int ad7303_probe(struct spi_device *spi)
bool ext_ref;
int ret;
indio_dev = iio_device_alloc(sizeof(*st));
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (indio_dev == NULL)
return -ENOMEM;
......@@ -212,15 +212,13 @@ static int ad7303_probe(struct spi_device *spi)
st->spi = spi;
st->vdd_reg = regulator_get(&spi->dev, "Vdd");
if (IS_ERR(st->vdd_reg)) {
ret = PTR_ERR(st->vdd_reg);
goto err_free;
}
st->vdd_reg = devm_regulator_get(&spi->dev, "Vdd");
if (IS_ERR(st->vdd_reg))
return PTR_ERR(st->vdd_reg);
ret = regulator_enable(st->vdd_reg);
if (ret)
goto err_put_vdd_reg;
return ret;
if (spi->dev.of_node) {
ext_ref = of_property_read_bool(spi->dev.of_node,
......@@ -234,7 +232,7 @@ static int ad7303_probe(struct spi_device *spi)
}
if (ext_ref) {
st->vref_reg = regulator_get(&spi->dev, "REF");
st->vref_reg = devm_regulator_get(&spi->dev, "REF");
if (IS_ERR(st->vref_reg)) {
ret = PTR_ERR(st->vref_reg);
goto err_disable_vdd_reg;
......@@ -242,7 +240,7 @@ static int ad7303_probe(struct spi_device *spi)
ret = regulator_enable(st->vref_reg);
if (ret)
goto err_put_vref_reg;
goto err_disable_vdd_reg;
st->config |= AD7303_CFG_EXTERNAL_VREF;
}
......@@ -263,16 +261,8 @@ static int ad7303_probe(struct spi_device *spi)
err_disable_vref_reg:
if (st->vref_reg)
regulator_disable(st->vref_reg);
err_put_vref_reg:
if (st->vref_reg)
regulator_put(st->vref_reg);
err_disable_vdd_reg:
regulator_disable(st->vdd_reg);
err_put_vdd_reg:
regulator_put(st->vdd_reg);
err_free:
iio_device_free(indio_dev);
return ret;
}
......@@ -283,14 +273,9 @@ static int ad7303_remove(struct spi_device *spi)
iio_device_unregister(indio_dev);
if (st->vref_reg) {
if (st->vref_reg)
regulator_disable(st->vref_reg);
regulator_put(st->vref_reg);
}
regulator_disable(st->vdd_reg);
regulator_put(st->vdd_reg);
iio_device_free(indio_dev);
return 0;
}
......
......@@ -164,11 +164,9 @@ static int max517_probe(struct i2c_client *client,
struct max517_platform_data *platform_data = client->dev.platform_data;
int err;
indio_dev = iio_device_alloc(sizeof(*data));
if (indio_dev == NULL) {
err = -ENOMEM;
goto exit;
}
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
if (!indio_dev)
return -ENOMEM;
data = iio_priv(indio_dev);
i2c_set_clientdata(client, indio_dev);
data->client = client;
......@@ -198,23 +196,16 @@ static int max517_probe(struct i2c_client *client,
err = iio_device_register(indio_dev);
if (err)
goto exit_free_device;
return err;
dev_info(&client->dev, "DAC registered\n");
return 0;
exit_free_device:
iio_device_free(indio_dev);
exit:
return err;
}
static int max517_remove(struct i2c_client *client)
{
iio_device_unregister(i2c_get_clientdata(client));
iio_device_free(i2c_get_clientdata(client));
return 0;
}
......
......@@ -192,16 +192,13 @@ static const struct adis16080_chip_info adis16080_chip_info[] = {
static int adis16080_probe(struct spi_device *spi)
{
const struct spi_device_id *id = spi_get_device_id(spi);
int ret;
struct adis16080_state *st;
struct iio_dev *indio_dev;
/* setup the industrialio driver allocated elements */
indio_dev = iio_device_alloc(sizeof(*st));
if (indio_dev == NULL) {
ret = -ENOMEM;
goto error_ret;
}
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (!indio_dev)
return -ENOMEM;
st = iio_priv(indio_dev);
/* this is only used for removal purposes */
spi_set_drvdata(spi, indio_dev);
......@@ -217,22 +214,12 @@ static int adis16080_probe(struct spi_device *spi)
indio_dev->info = &adis16080_info;
indio_dev->modes = INDIO_DIRECT_MODE;
ret = iio_device_register(indio_dev);
if (ret)
goto error_free_dev;
return 0;
error_free_dev:
iio_device_free(indio_dev);
error_ret:
return ret;
return iio_device_register(indio_dev);
}
static int adis16080_remove(struct spi_device *spi)
{
iio_device_unregister(spi_get_drvdata(spi));
iio_device_free(spi_get_drvdata(spi));
return 0;
}
......
......@@ -148,16 +148,13 @@ static const struct iio_info adis16130_info = {
static int adis16130_probe(struct spi_device *spi)
{
int ret;
struct adis16130_state *st;
struct iio_dev *indio_dev;
/* setup the industrialio driver allocated elements */
indio_dev = iio_device_alloc(sizeof(*st));
if (indio_dev == NULL) {
ret = -ENOMEM;
goto error_ret;
}
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (!indio_dev)
return -ENOMEM;
st = iio_priv(indio_dev);
/* this is only used for removal purposes */
spi_set_drvdata(spi, indio_dev);
......@@ -170,24 +167,12 @@ static int adis16130_probe(struct spi_device *spi)
indio_dev->info = &adis16130_info;
indio_dev->modes = INDIO_DIRECT_MODE;
ret = iio_device_register(indio_dev);
if (ret)
goto error_free_dev;
return 0;
error_free_dev:
iio_device_free(indio_dev);
error_ret:
return ret;
return iio_device_register(indio_dev);
}
static int adis16130_remove(struct spi_device *spi)
{
iio_device_unregister(spi_get_drvdata(spi));
iio_device_free(spi_get_drvdata(spi));
return 0;
}
......
......@@ -497,7 +497,7 @@ static int adis16136_probe(struct spi_device *spi)
struct iio_dev *indio_dev;
int ret;
indio_dev = iio_device_alloc(sizeof(*adis16136));
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adis16136));
if (indio_dev == NULL)
return -ENOMEM;
......@@ -515,11 +515,11 @@ static int adis16136_probe(struct spi_device *spi)
ret = adis_init(&adis16136->adis, indio_dev, spi, &adis16136_data);
if (ret)
goto error_free_dev;
return ret;
ret = adis_setup_buffer_and_trigger(&adis16136->adis, indio_dev, NULL);
if (ret)
goto error_free_dev;
return ret;
ret = adis16136_initial_setup(indio_dev);
if (ret)
......@@ -537,8 +537,6 @@ static int adis16136_probe(struct spi_device *spi)
adis16136_stop_device(indio_dev);
error_cleanup_buffer:
adis_cleanup_buffer_and_trigger(&adis16136->adis, indio_dev);
error_free_dev:
iio_device_free(indio_dev);
return ret;
}
......@@ -552,8 +550,6 @@ static int adis16136_remove(struct spi_device *spi)
adis_cleanup_buffer_and_trigger(&adis16136->adis, indio_dev);
iio_device_free(indio_dev);
return 0;
}
......
......@@ -343,11 +343,9 @@ static int adis16260_probe(struct spi_device *spi)
int ret;
/* setup the industrialio driver allocated elements */
indio_dev = iio_device_alloc(sizeof(*adis));
if (indio_dev == NULL) {
ret = -ENOMEM;
goto error_ret;
}
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*adis));
if (!indio_dev)
return -ENOMEM;
adis = iio_priv(indio_dev);
/* this is only used for removal purposes */
spi_set_drvdata(spi, indio_dev);
......@@ -361,11 +359,11 @@ static int adis16260_probe(struct spi_device *spi)
ret = adis_init(adis, indio_dev, spi, &adis16260_data);
if (ret)
goto error_free_dev;
return ret;
ret = adis_setup_buffer_and_trigger(adis, indio_dev, NULL);
if (ret)
goto error_free_dev;
return ret;
/* Get the device into a sane initial state */
ret = adis_initial_startup(adis);
......@@ -379,9 +377,6 @@ static int adis16260_probe(struct spi_device *spi)
error_cleanup_buffer_trigger:
adis_cleanup_buffer_and_trigger(adis, indio_dev);
error_free_dev:
iio_device_free(indio_dev);
error_ret:
return ret;
}
......@@ -393,7 +388,6 @@ static int adis16260_remove(struct spi_device *spi)
iio_device_unregister(indio_dev);
adis16260_stop_device(indio_dev);
adis_cleanup_buffer_and_trigger(adis, indio_dev);
iio_device_free(indio_dev);
return 0;
}
......
......@@ -426,11 +426,9 @@ static int adxrs450_probe(struct spi_device *spi)
struct iio_dev *indio_dev;
/* setup the industrialio driver allocated elements */
indio_dev = iio_device_alloc(sizeof(*st));
if (indio_dev == NULL) {
ret = -ENOMEM;
goto error_ret;
}
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (!indio_dev)
return -ENOMEM;
st = iio_priv(indio_dev);
st->us = spi;
mutex_init(&st->buf_lock);
......@@ -447,7 +445,7 @@ static int adxrs450_probe(struct spi_device *spi)
ret = iio_device_register(indio_dev);
if (ret)
goto error_free_dev;
return ret;
/* Get the device into a sane initial state */
ret = adxrs450_initial_setup(indio_dev);
......@@ -456,17 +454,12 @@ static int adxrs450_probe(struct spi_device *spi)
return 0;
error_initial:
iio_device_unregister(indio_dev);
error_free_dev:
iio_device_free(indio_dev);
error_ret:
return ret;
}
static int adxrs450_remove(struct spi_device *spi)
{
iio_device_unregister(spi_get_drvdata(spi));
iio_device_free(spi_get_drvdata(spi));
return 0;
}
......
......@@ -175,18 +175,10 @@ static int gyro_3d_write_raw(struct iio_dev *indio_dev,
return ret;
}
static int gyro_3d_write_raw_get_fmt(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
long mask)
{
return IIO_VAL_INT_PLUS_MICRO;
}
static const struct iio_info gyro_3d_info = {
.driver_module = THIS_MODULE,
.read_raw = &gyro_3d_read_raw,
.write_raw = &gyro_3d_write_raw,
.write_raw_get_fmt = &gyro_3d_write_raw_get_fmt,
};
/* Function to push data to buffer */
......@@ -282,11 +274,9 @@ static int hid_gyro_3d_probe(struct platform_device *pdev)
struct hid_sensor_hub_device *hsdev = pdev->dev.platform_data;
struct iio_chan_spec *channels;
indio_dev = iio_device_alloc(sizeof(struct gyro_3d_state));
if (indio_dev == NULL) {
ret = -ENOMEM;
goto error_ret;
}
indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*gyro_state));
if (!indio_dev)
return -ENOMEM;
platform_set_drvdata(pdev, indio_dev);
gyro_state = iio_priv(indio_dev);
......@@ -298,15 +288,14 @@ static int hid_gyro_3d_probe(struct platform_device *pdev)
&gyro_state->common_attributes);
if (ret) {
dev_err(&pdev->dev, "failed to setup common attributes\n");
goto error_free_dev;
return ret;
}
channels = kmemdup(gyro_3d_channels, sizeof(gyro_3d_channels),
GFP_KERNEL);
if (!channels) {
ret = -ENOMEM;
dev_err(&pdev->dev, "failed to duplicate channels\n");
goto error_free_dev;
return -ENOMEM;
}
ret = gyro_3d_parse_report(pdev, hsdev, channels,
......@@ -363,9 +352,6 @@ static int hid_gyro_3d_probe(struct platform_device *pdev)
iio_triggered_buffer_cleanup(indio_dev);
error_free_dev_mem:
kfree(indio_dev->channels);
error_free_dev:
iio_device_free(indio_dev);
error_ret:
return ret;
}
......@@ -380,7 +366,6 @@ static int hid_gyro_3d_remove(struct platform_device *pdev)
hid_sensor_remove_trigger(indio_dev);
iio_triggered_buffer_cleanup(indio_dev);
kfree(indio_dev->channels);
iio_device_free(indio_dev);
return 0;
}
......
......@@ -309,11 +309,9 @@ static int itg3200_probe(struct i2c_client *client,
dev_dbg(&client->dev, "probe I2C dev with IRQ %i", client->irq);
indio_dev = iio_device_alloc(sizeof(*st));
if (indio_dev == NULL) {
ret = -ENOMEM;
goto error_ret;
}
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st));
if (!indio_dev)
return -ENOMEM;
st = iio_priv(indio_dev);
......@@ -330,7 +328,7 @@ static int itg3200_probe(struct i2c_client *client,
ret = itg3200_buffer_configure(indio_dev);
if (ret)
goto error_free_dev;
return ret;
if (client->irq) {
ret = itg3200_probe_trigger(indio_dev);
......@@ -353,9 +351,6 @@ static int itg3200_probe(struct i2c_client *client,
itg3200_remove_trigger(indio_dev);
error_unconfigure_buffer:
itg3200_buffer_unconfigure(indio_dev);
error_free_dev:
iio_device_free(indio_dev);
error_ret:
return ret;
}
......@@ -370,8 +365,6 @@ static int itg3200_remove(struct i2c_client *client)
itg3200_buffer_unconfigure(indio_dev);
iio_device_free(indio_dev);
return 0;
}
......
......@@ -366,7 +366,6 @@ void st_gyro_common_remove(struct iio_dev *indio_dev)
st_sensors_deallocate_trigger(indio_dev);
st_gyro_deallocate_ring(indio_dev);
}
iio_device_free(indio_dev);
}
EXPORT_SYMBOL(st_gyro_common_remove);
......
......@@ -25,11 +25,9 @@ static int st_gyro_i2c_probe(struct i2c_client *client,
struct st_sensor_data *gdata;
int err;
indio_dev = iio_device_alloc(sizeof(*gdata));
if (indio_dev == NULL) {
err = -ENOMEM;
goto iio_device_alloc_error;
}
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*gdata));
if (!indio_dev)
return -ENOMEM;
gdata = iio_priv(indio_dev);
gdata->dev = &client->dev;
......@@ -39,14 +37,9 @@ static int st_gyro_i2c_probe(struct i2c_client *client,
err = st_gyro_common_probe(indio_dev,
(struct st_sensors_platform_data *)&gyro_pdata);
if (err < 0)
goto st_gyro_common_probe_error;
return err;
return 0;
st_gyro_common_probe_error:
iio_device_free(indio_dev);
iio_device_alloc_error:
return err;
}
static int st_gyro_i2c_remove(struct i2c_client *client)
......
......@@ -24,11 +24,9 @@ static int st_gyro_spi_probe(struct spi_device *spi)
struct st_sensor_data *gdata;
int err;
indio_dev = iio_device_alloc(sizeof(*gdata));
if (indio_dev == NULL) {
err = -ENOMEM;
goto iio_device_alloc_error;
}
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*gdata));
if (!indio_dev)
return -ENOMEM;
gdata = iio_priv(indio_dev);
gdata->dev = &spi->dev;
......@@ -38,14 +36,9 @@ static int st_gyro_spi_probe(struct spi_device *spi)
err = st_gyro_common_probe(indio_dev,
(struct st_sensors_platform_data *)&gyro_pdata);
if (err < 0)
goto st_gyro_common_probe_error;
return err;
return 0;
st_gyro_common_probe_error:
iio_device_free(indio_dev);
iio_device_alloc_error:
return err;
}
static int st_gyro_spi_remove(struct spi_device *spi)
......
......@@ -424,9 +424,8 @@ static void iio_trig_subirqunmask(struct irq_data *d)
trig->subirqs[d->irq - trig->subirq_base].enabled = true;
}
struct iio_trigger *iio_trigger_alloc(const char *fmt, ...)
static struct iio_trigger *viio_trigger_alloc(const char *fmt, va_list vargs)
{
va_list vargs;
struct iio_trigger *trig;
trig = kzalloc(sizeof *trig, GFP_KERNEL);
if (trig) {
......@@ -444,9 +443,8 @@ struct iio_trigger *iio_trigger_alloc(const char *fmt, ...)
kfree(trig);
return NULL;
}
va_start(vargs, fmt);
trig->name = kvasprintf(GFP_KERNEL, fmt, vargs);
va_end(vargs);
if (trig->name == NULL) {
irq_free_descs(trig->subirq_base,
CONFIG_IIO_CONSUMERS_PER_TRIGGER);
......@@ -467,6 +465,19 @@ struct iio_trigger *iio_trigger_alloc(const char *fmt, ...)
}
get_device(&trig->dev);
}
return trig;
}
struct iio_trigger *iio_trigger_alloc(const char *fmt, ...)
{
struct iio_trigger *trig;
va_list vargs;
va_start(vargs, fmt);
trig = viio_trigger_alloc(fmt, vargs);
va_end(vargs);
return trig;
}
EXPORT_SYMBOL(iio_trigger_alloc);
......@@ -478,6 +489,59 @@ void iio_trigger_free(struct iio_trigger *trig)
}
EXPORT_SYMBOL(iio_trigger_free);
static void devm_iio_trigger_release(struct device *dev, void *res)
{
iio_trigger_free(*(struct iio_trigger **)res);
}
static int devm_iio_trigger_match(struct device *dev, void *res, void *data)
{
struct iio_trigger **r = res;
if (!r || !*r) {
WARN_ON(!r || !*r);
return 0;
}
return *r == data;
}
struct iio_trigger *devm_iio_trigger_alloc(struct device *dev,
const char *fmt, ...)
{
struct iio_trigger **ptr, *trig;
va_list vargs;
ptr = devres_alloc(devm_iio_trigger_release, sizeof(*ptr),
GFP_KERNEL);
if (!ptr)
return NULL;
/* use raw alloc_dr for kmalloc caller tracing */
va_start(vargs, fmt);
trig = viio_trigger_alloc(fmt, vargs);
va_end(vargs);
if (trig) {
*ptr = trig;
devres_add(dev, ptr);
} else {
devres_free(ptr);
}
return trig;
}
EXPORT_SYMBOL_GPL(devm_iio_trigger_alloc);
void devm_iio_trigger_free(struct device *dev, struct iio_trigger *iio_trig)
{
int rc;
rc = devres_release(dev, devm_iio_trigger_release,
devm_iio_trigger_match, iio_trig);
WARN_ON(rc);
}
EXPORT_SYMBOL_GPL(devm_iio_trigger_free);
void iio_device_register_trigger_consumer(struct iio_dev *indio_dev)
{
indio_dev->groups[indio_dev->groupcounter++] =
......
......@@ -37,22 +37,14 @@
#define ADJD_S311_CAP_GREEN 0x07
#define ADJD_S311_CAP_BLUE 0x08
#define ADJD_S311_CAP_CLEAR 0x09
#define ADJD_S311_INT_RED_LO 0x0a
#define ADJD_S311_INT_RED_HI 0x0b
#define ADJD_S311_INT_GREEN_LO 0x0c
#define ADJD_S311_INT_GREEN_HI 0x0d
#define ADJD_S311_INT_BLUE_LO 0x0e
#define ADJD_S311_INT_BLUE_HI 0x0f
#define ADJD_S311_INT_CLEAR_LO 0x10
#define ADJD_S311_INT_CLEAR_HI 0x11
#define ADJD_S311_DATA_RED_LO 0x40
#define ADJD_S311_DATA_RED_HI 0x41
#define ADJD_S311_DATA_GREEN_LO 0x42
#define ADJD_S311_DATA_GREEN_HI 0x43
#define ADJD_S311_DATA_BLUE_LO 0x44
#define ADJD_S311_DATA_BLUE_HI 0x45
#define ADJD_S311_DATA_CLEAR_LO 0x46
#define ADJD_S311_DATA_CLEAR_HI 0x47
#define ADJD_S311_INT_RED 0x0a
#define ADJD_S311_INT_GREEN 0x0c
#define ADJD_S311_INT_BLUE 0x0e
#define ADJD_S311_INT_CLEAR 0x10
#define ADJD_S311_DATA_RED 0x40
#define ADJD_S311_DATA_GREEN 0x42
#define ADJD_S311_DATA_BLUE 0x44
#define ADJD_S311_DATA_CLEAR 0x46
#define ADJD_S311_OFFSET_RED 0x48
#define ADJD_S311_OFFSET_GREEN 0x49
#define ADJD_S311_OFFSET_BLUE 0x4a
......@@ -73,8 +65,8 @@ enum adjd_s311_channel_idx {
IDX_RED, IDX_GREEN, IDX_BLUE, IDX_CLEAR
};
#define ADJD_S311_DATA_REG(chan) (ADJD_S311_DATA_RED_LO + (chan) * 2)
#define ADJD_S311_INT_REG(chan) (ADJD_S311_INT_RED_LO + (chan) * 2)
#define ADJD_S311_DATA_REG(chan) (ADJD_S311_DATA_RED + (chan) * 2)
#define ADJD_S311_INT_REG(chan) (ADJD_S311_INT_RED + (chan) * 2)
#define ADJD_S311_CAP_REG(chan) (ADJD_S311_CAP_RED + (chan))
static int adjd_s311_req_data(struct iio_dev *indio_dev)
......
......@@ -154,18 +154,10 @@ static int als_write_raw(struct iio_dev *indio_dev,
return ret;
}
static int als_write_raw_get_fmt(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
long mask)
{
return IIO_VAL_INT_PLUS_MICRO;
}
static const struct iio_info als_info = {
.driver_module = THIS_MODULE,
.read_raw = &als_read_raw,
.write_raw = &als_write_raw,
.write_raw_get_fmt = &als_write_raw_get_fmt,
};
/* Function to push data to buffer */
......
......@@ -176,18 +176,10 @@ static int magn_3d_write_raw(struct iio_dev *indio_dev,
return ret;
}
static int magn_3d_write_raw_get_fmt(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
long mask)
{
return IIO_VAL_INT_PLUS_MICRO;
}
static const struct iio_info magn_3d_info = {
.driver_module = THIS_MODULE,
.read_raw = &magn_3d_read_raw,
.write_raw = &magn_3d_write_raw,
.write_raw_get_fmt = &magn_3d_write_raw_get_fmt,
};
/* Function to push data to buffer */
......
#
# Temperature sensor drivers
#
menu "Temperature sensors"
config TMP006
tristate "TMP006 infrared thermopile sensor"
depends on I2C
help
If you say yes here you get support for the Texas Instruments
TMP006 infrared thermopile sensor.
This driver can also be built as a module. If so, the module will
be called tmp006.
endmenu
#
# Makefile for industrial I/O temperature drivers
#
obj-$(CONFIG_TMP006) += tmp006.o
/*
* tmp006.c - Support for TI TMP006 IR thermopile sensor
*
* Copyright (c) 2013 Peter Meerwald <pmeerw@pmeerw.net>
*
* This file is subject to the terms and conditions of version 2 of
* the GNU General Public License. See the file COPYING in the main
* directory of this archive for more details.
*
* Driver for the Texas Instruments I2C 16-bit IR thermopile sensor
*
* (7-bit I2C slave address 0x40, changeable via ADR pins)
*
* TODO: data ready irq
*/
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/pm.h>
#include <linux/bitops.h>
#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>
#define TMP006_VOBJECT 0x00
#define TMP006_TAMBIENT 0x01
#define TMP006_CONFIG 0x02
#define TMP006_MANUFACTURER_ID 0xfe
#define TMP006_DEVICE_ID 0xff
#define TMP006_TAMBIENT_SHIFT 2
#define TMP006_CONFIG_RESET BIT(15)
#define TMP006_CONFIG_DRDY_EN BIT(8)
#define TMP006_CONFIG_DRDY BIT(7)
#define TMP006_CONFIG_MOD_MASK 0x7000
#define TMP006_CONFIG_CR_MASK 0x0e00
#define TMP006_CONFIG_CR_SHIFT 9
#define MANUFACTURER_MAGIC 0x5449
#define DEVICE_MAGIC 0x0067
struct tmp006_data {
struct i2c_client *client;
u16 config;
};
static int tmp006_read_measurement(struct tmp006_data *data, u8 reg)
{
s32 ret;
int tries = 50;
while (tries-- > 0) {
ret = i2c_smbus_read_word_swapped(data->client,
TMP006_CONFIG);
if (ret < 0)
return ret;
if (ret & TMP006_CONFIG_DRDY)
break;
msleep(100);
}
if (tries < 0)
return -EIO;
return i2c_smbus_read_word_swapped(data->client, reg);
}
static int tmp006_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *channel, int *val,
int *val2, long mask)
{
struct tmp006_data *data = iio_priv(indio_dev);
s32 ret;
switch (mask) {
case IIO_CHAN_INFO_RAW:
if (channel->type == IIO_VOLTAGE) {
/* LSB is 156.25 nV */
ret = tmp006_read_measurement(data, TMP006_VOBJECT);
if (ret < 0)
return ret;
*val = sign_extend32(ret, 15);
} else if (channel->type == IIO_TEMP) {
/* LSB is 0.03125 degrees Celsius */
ret = tmp006_read_measurement(data, TMP006_TAMBIENT);
if (ret < 0)
return ret;
*val = sign_extend32(ret, 15) >> TMP006_TAMBIENT_SHIFT;
} else {
break;
}
return IIO_VAL_INT;
case IIO_CHAN_INFO_SCALE:
if (channel->type == IIO_VOLTAGE) {
*val = 0;
*val2 = 156250;
} else if (channel->type == IIO_TEMP) {
*val = 31;
*val2 = 250000;
} else {
break;
}
return IIO_VAL_INT_PLUS_MICRO;
default:
break;
}
return -EINVAL;
}
static const char * const tmp006_freqs[] = { "4", "2", "1", "0.5", "0.25" };
static ssize_t tmp006_show_freq(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct tmp006_data *data = iio_priv(dev_to_iio_dev(dev));
int cr = (data->config & TMP006_CONFIG_CR_MASK)
>> TMP006_CONFIG_CR_SHIFT;
return sprintf(buf, "%s\n", tmp006_freqs[cr]);
}
static ssize_t tmp006_store_freq(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t len)
{
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct tmp006_data *data = iio_priv(indio_dev);
int i;
bool found = false;
for (i = 0; i < ARRAY_SIZE(tmp006_freqs); i++)
if (sysfs_streq(buf, tmp006_freqs[i])) {
found = true;
break;
}
if (!found)
return -EINVAL;
data->config &= ~TMP006_CONFIG_CR_MASK;
data->config |= i << TMP006_CONFIG_CR_SHIFT;
return i2c_smbus_write_word_swapped(data->client, TMP006_CONFIG,
data->config);
}
static IIO_DEV_ATTR_SAMP_FREQ(S_IRUGO | S_IWUSR,
tmp006_show_freq, tmp006_store_freq);
static IIO_CONST_ATTR(sampling_frequency_available, "4 2 1 0.5 0.25");
static struct attribute *tmp006_attributes[] = {
&iio_dev_attr_sampling_frequency.dev_attr.attr,
&iio_const_attr_sampling_frequency_available.dev_attr.attr,
NULL
};
static const struct attribute_group tmp006_attribute_group = {
.attrs = tmp006_attributes,
};
static const struct iio_chan_spec tmp006_channels[] = {
{
.type = IIO_VOLTAGE,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_SCALE),
},
{
.type = IIO_TEMP,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_SCALE),
}
};
static const struct iio_info tmp006_info = {
.read_raw = tmp006_read_raw,
.attrs = &tmp006_attribute_group,
.driver_module = THIS_MODULE,
};
static bool tmp006_check_identification(struct i2c_client *client)
{
int mid, did;
mid = i2c_smbus_read_word_swapped(client, TMP006_MANUFACTURER_ID);
if (mid < 0)
return false;
did = i2c_smbus_read_word_swapped(client, TMP006_DEVICE_ID);
if (did < 0)
return false;
return mid == MANUFACTURER_MAGIC && did == DEVICE_MAGIC;
}
static int tmp006_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct iio_dev *indio_dev;
struct tmp006_data *data;
int ret;
if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA))
return -ENODEV;
if (!tmp006_check_identification(client)) {
dev_err(&client->dev, "no TMP006 sensor\n");
return -ENODEV;
}
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
if (!indio_dev)
return -ENOMEM;
data = iio_priv(indio_dev);
i2c_set_clientdata(client, indio_dev);
data->client = client;
indio_dev->dev.parent = &client->dev;
indio_dev->name = dev_name(&client->dev);
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->info = &tmp006_info;
indio_dev->channels = tmp006_channels;
indio_dev->num_channels = ARRAY_SIZE(tmp006_channels);
ret = i2c_smbus_read_word_swapped(data->client, TMP006_CONFIG);
if (ret < 0)
return ret;
data->config = ret;
return iio_device_register(indio_dev);
}
static int tmp006_powerdown(struct tmp006_data *data)
{
return i2c_smbus_write_word_swapped(data->client, TMP006_CONFIG,
data->config & ~TMP006_CONFIG_MOD_MASK);
}
static int tmp006_remove(struct i2c_client *client)
{
struct iio_dev *indio_dev = i2c_get_clientdata(client);
iio_device_unregister(indio_dev);
tmp006_powerdown(iio_priv(indio_dev));
return 0;
}
#ifdef CONFIG_PM_SLEEP
static int tmp006_suspend(struct device *dev)
{
return tmp006_powerdown(iio_priv(dev_to_iio_dev(dev)));
}
static int tmp006_resume(struct device *dev)
{
struct tmp006_data *data = iio_priv(dev_to_iio_dev(dev));
return i2c_smbus_write_word_swapped(data->client, TMP006_CONFIG,
data->config | TMP006_CONFIG_MOD_MASK);
}
#endif
static SIMPLE_DEV_PM_OPS(tmp006_pm_ops, tmp006_suspend, tmp006_resume);
static const struct i2c_device_id tmp006_id[] = {
{ "tmp006", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, tmp006_id);
static struct i2c_driver tmp006_driver = {
.driver = {
.name = "tmp006",
.pm = &tmp006_pm_ops,
.owner = THIS_MODULE,
},
.probe = tmp006_probe,
.remove = tmp006_remove,
.id_table = tmp006_id,
};
module_i2c_driver(tmp006_driver);
MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>");
MODULE_DESCRIPTION("TI TMP006 IR thermopile sensor driver");
MODULE_LICENSE("GPL");
......@@ -225,6 +225,9 @@ struct mxs_lradc {
#define LRADC_CTRL4_LRADCSELECT_MASK(n) (0xf << ((n) * 4))
#define LRADC_CTRL4_LRADCSELECT_OFFSET(n) ((n) * 4)
#define LRADC_RESOLUTION 12
#define LRADC_SINGLE_SAMPLE_MASK ((1 << LRADC_RESOLUTION) - 1)
/*
* Raw I/O operations
*/
......@@ -540,9 +543,10 @@ static int mxs_lradc_ts_register(struct mxs_lradc *lradc)
__set_bit(EV_ABS, input->evbit);
__set_bit(EV_KEY, input->evbit);
__set_bit(BTN_TOUCH, input->keybit);
input_set_abs_params(input, ABS_X, 0, LRADC_CH_VALUE_MASK, 0, 0);
input_set_abs_params(input, ABS_Y, 0, LRADC_CH_VALUE_MASK, 0, 0);
input_set_abs_params(input, ABS_PRESSURE, 0, LRADC_CH_VALUE_MASK, 0, 0);
input_set_abs_params(input, ABS_X, 0, LRADC_SINGLE_SAMPLE_MASK, 0, 0);
input_set_abs_params(input, ABS_Y, 0, LRADC_SINGLE_SAMPLE_MASK, 0, 0);
input_set_abs_params(input, ABS_PRESSURE, 0, LRADC_SINGLE_SAMPLE_MASK,
0, 0);
lradc->ts_input = input;
input_set_drvdata(input, lradc);
......@@ -817,7 +821,7 @@ static const struct iio_buffer_setup_ops mxs_lradc_buffer_ops = {
.channel = (idx), \
.scan_type = { \
.sign = 'u', \
.realbits = 18, \
.realbits = LRADC_RESOLUTION, \
.storagebits = 32, \
}, \
}
......
......@@ -151,11 +151,9 @@ static int adis16060_r_probe(struct spi_device *spi)
struct iio_dev *indio_dev;
/* setup the industrialio driver allocated elements */
indio_dev = iio_device_alloc(sizeof(*st));
if (indio_dev == NULL) {
ret = -ENOMEM;
goto error_ret;
}
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
if (!indio_dev)
return -ENOMEM;
/* this is only used for removal purposes */
spi_set_drvdata(spi, indio_dev);
st = iio_priv(indio_dev);
......@@ -171,23 +169,16 @@ static int adis16060_r_probe(struct spi_device *spi)
ret = iio_device_register(indio_dev);
if (ret)
goto error_free_dev;
return ret;
adis16060_iio_dev = indio_dev;
return 0;
error_free_dev:
iio_device_free(indio_dev);
error_ret:
return ret;
}
/* fixme, confirm ordering in this function */
static int adis16060_r_remove(struct spi_device *spi)
{
iio_device_unregister(spi_get_drvdata(spi));
iio_device_free(spi_get_drvdata(spi));
return 0;
}
......
......@@ -556,6 +556,35 @@ struct iio_dev *devm_iio_device_alloc(struct device *dev, int sizeof_priv);
*/
void devm_iio_device_free(struct device *dev, struct iio_dev *indio_dev);
/**
* devm_iio_trigger_alloc - Resource-managed iio_trigger_alloc()
* @dev: Device to allocate iio_trigger for
* @fmt: trigger name format. If it includes format
* specifiers, the additional arguments following
* format are formatted and inserted in the resulting
* string replacing their respective specifiers.
*
* Managed iio_trigger_alloc. iio_trigger allocated with this function is
* automatically freed on driver detach.
*
* If an iio_trigger allocated with this function needs to be freed separately,
* devm_iio_trigger_free() must be used.
*
* RETURNS:
* Pointer to allocated iio_trigger on success, NULL on failure.
*/
struct iio_trigger *devm_iio_trigger_alloc(struct device *dev,
const char *fmt, ...);
/**
* devm_iio_trigger_free - Resource-managed iio_trigger_free()
* @dev: Device this iio_dev belongs to
* @iio_trig: the iio_trigger associated with the device
*
* Free iio_trigger allocated with devm_iio_trigger_alloc().
*/
void devm_iio_trigger_free(struct device *dev, struct iio_trigger *iio_trig);
/**
* iio_buffer_enabled() - helper function to test if the buffer is enabled
* @indio_dev: IIO device structure for device
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment