Commit 71c62902 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge tag 'iio-for-v3.7e' of...

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

Fifth round of new drivers and device support for the IIO
subsystem in the 3.7 cycle.

Here we have a mixed bag of new stuff, minor fixes and
more major fixes for drivers added earlier in this cycle.

1) A number of fixes for the HID sensors code added in previous
pull request.  Typical stuff that has become apparent as more eyes
have looked at the code post merging. Similar case for the ad5755 dac.

2) Cleanups of error handing in inkern.c - again typical stuff to see
as code comes into heavier use and people notice the naughty short
cuts that snuck in originally and kindly fix them.

3) A series from Lars that removes some incorrect error handling
from the remove functions of a number of drivers.  These have been
there for a very long time hence I'm not pushing these out for the
3.6 cycle.

4) Support for more parts in the ad7780 driver.

5) A driver for the adcs on the lp8788 power management unit

6) A client driver for IIO to allow it's ADCs to be used for
battery status measurement.  Note this driver has some dependencies
on some utility functions added to IIO in this series, hence it is
coming via this tree rather than Anton's.

7) A null pointer dereference bug in the 'fake' driver. I'm not
doing this as a fix for the 3.6 cycle because it only effects
'fake' hardware and that code is typically only used by people
investigating how IIO works as part of writing new drivers. Hence
it's hardly a critical fix.
parents 9970eeae 3fff2274
...@@ -173,7 +173,7 @@ int sensor_hub_register_callback(struct hid_sensor_hub_device *hsdev, ...@@ -173,7 +173,7 @@ int sensor_hub_register_callback(struct hid_sensor_hub_device *hsdev,
spin_unlock(&pdata->dyn_callback_lock); spin_unlock(&pdata->dyn_callback_lock);
return -EINVAL; return -EINVAL;
} }
callback = kzalloc(sizeof(*callback), GFP_KERNEL); callback = kzalloc(sizeof(*callback), GFP_ATOMIC);
if (!callback) { if (!callback) {
spin_unlock(&pdata->dyn_callback_lock); spin_unlock(&pdata->dyn_callback_lock);
return -ENOMEM; return -ENOMEM;
...@@ -214,9 +214,6 @@ int sensor_hub_set_feature(struct hid_sensor_hub_device *hsdev, u32 report_id, ...@@ -214,9 +214,6 @@ int sensor_hub_set_feature(struct hid_sensor_hub_device *hsdev, u32 report_id,
struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev); struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev);
int ret = 0; int ret = 0;
if (report_id < 0)
return -EINVAL;
mutex_lock(&data->mutex); mutex_lock(&data->mutex);
report = sensor_hub_report(report_id, hsdev->hdev, HID_FEATURE_REPORT); report = sensor_hub_report(report_id, hsdev->hdev, HID_FEATURE_REPORT);
if (!report || (field_index >= report->maxfield)) { if (!report || (field_index >= report->maxfield)) {
...@@ -241,9 +238,6 @@ int sensor_hub_get_feature(struct hid_sensor_hub_device *hsdev, u32 report_id, ...@@ -241,9 +238,6 @@ int sensor_hub_get_feature(struct hid_sensor_hub_device *hsdev, u32 report_id,
struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev); struct sensor_hub_data *data = hid_get_drvdata(hsdev->hdev);
int ret = 0; int ret = 0;
if (report_id < 0)
return -EINVAL;
mutex_lock(&data->mutex); mutex_lock(&data->mutex);
report = sensor_hub_report(report_id, hsdev->hdev, HID_FEATURE_REPORT); report = sensor_hub_report(report_id, hsdev->hdev, HID_FEATURE_REPORT);
if (!report || (field_index >= report->maxfield)) { if (!report || (field_index >= report->maxfield)) {
...@@ -271,9 +265,6 @@ int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev, ...@@ -271,9 +265,6 @@ int sensor_hub_input_attr_get_raw_value(struct hid_sensor_hub_device *hsdev,
struct hid_report *report; struct hid_report *report;
int ret_val = 0; int ret_val = 0;
if (report_id < 0)
return -EINVAL;
mutex_lock(&data->mutex); mutex_lock(&data->mutex);
memset(&data->pending, 0, sizeof(data->pending)); memset(&data->pending, 0, sizeof(data->pending));
init_completion(&data->pending.ready); init_completion(&data->pending.ready);
...@@ -462,7 +453,7 @@ static int sensor_hub_raw_event(struct hid_device *hdev, ...@@ -462,7 +453,7 @@ static int sensor_hub_raw_event(struct hid_device *hdev,
if (pdata->pending.status && pdata->pending.attr_usage_id == if (pdata->pending.status && pdata->pending.attr_usage_id ==
report->field[i]->usage->hid) { report->field[i]->usage->hid) {
hid_dbg(hdev, "data was pending ...\n"); hid_dbg(hdev, "data was pending ...\n");
pdata->pending.raw_data = kmalloc(sz, GFP_KERNEL); pdata->pending.raw_data = kmalloc(sz, GFP_ATOMIC);
if (pdata->pending.raw_data) { if (pdata->pending.raw_data) {
memcpy(pdata->pending.raw_data, ptr, sz); memcpy(pdata->pending.raw_data, ptr, sz);
pdata->pending.raw_size = sz; pdata->pending.raw_size = sz;
...@@ -539,7 +530,6 @@ static int sensor_hub_probe(struct hid_device *hdev, ...@@ -539,7 +530,6 @@ static int sensor_hub_probe(struct hid_device *hdev,
} }
INIT_LIST_HEAD(&hdev->inputs); INIT_LIST_HEAD(&hdev->inputs);
hdev->claimed = HID_CLAIMED_INPUT;
ret = hid_hw_start(hdev, 0); ret = hid_hw_start(hdev, 0);
if (ret) { if (ret) {
hid_err(hdev, "hw start failed\n"); hid_err(hdev, "hw start failed\n");
...@@ -565,8 +555,7 @@ static int sensor_hub_probe(struct hid_device *hdev, ...@@ -565,8 +555,7 @@ static int sensor_hub_probe(struct hid_device *hdev,
sizeof(struct mfd_cell), sizeof(struct mfd_cell),
GFP_KERNEL); GFP_KERNEL);
if (sd->hid_sensor_hub_client_devs == NULL) { if (sd->hid_sensor_hub_client_devs == NULL) {
hid_err(hdev, hid_err(hdev, "Failed to allocate memory for mfd cells\n");
"Failed to allocate memory for mfd cells\n");
ret = -ENOMEM; ret = -ENOMEM;
goto err_close; goto err_close;
} }
...@@ -578,10 +567,9 @@ static int sensor_hub_probe(struct hid_device *hdev, ...@@ -578,10 +567,9 @@ static int sensor_hub_probe(struct hid_device *hdev,
name = kasprintf(GFP_KERNEL, "HID-SENSOR-%x", name = kasprintf(GFP_KERNEL, "HID-SENSOR-%x",
field->physical); field->physical);
if (name == NULL) { if (name == NULL) {
hid_err(hdev, hid_err(hdev, "Failed MFD device name\n");
"Failed MFD device name\n");
ret = -ENOMEM; ret = -ENOMEM;
goto err_free_cells; goto err_free_names;
} }
sd->hid_sensor_hub_client_devs[ sd->hid_sensor_hub_client_devs[
sd->hid_sensor_client_cnt].name = name; sd->hid_sensor_client_cnt].name = name;
...@@ -596,7 +584,7 @@ static int sensor_hub_probe(struct hid_device *hdev, ...@@ -596,7 +584,7 @@ static int sensor_hub_probe(struct hid_device *hdev,
} }
} }
ret = mfd_add_devices(&hdev->dev, 0, sd->hid_sensor_hub_client_devs, ret = mfd_add_devices(&hdev->dev, 0, sd->hid_sensor_hub_client_devs,
sd->hid_sensor_client_cnt, NULL, 0); sd->hid_sensor_client_cnt, NULL, 0, NULL);
if (ret < 0) if (ret < 0)
goto err_free_names; goto err_free_names;
...@@ -605,10 +593,8 @@ static int sensor_hub_probe(struct hid_device *hdev, ...@@ -605,10 +593,8 @@ static int sensor_hub_probe(struct hid_device *hdev,
err_free_names: err_free_names:
for (i = 0; i < sd->hid_sensor_client_cnt ; ++i) for (i = 0; i < sd->hid_sensor_client_cnt ; ++i)
kfree(sd->hid_sensor_hub_client_devs[i].name); kfree(sd->hid_sensor_hub_client_devs[i].name);
err_free_cells:
kfree(sd->hid_sensor_hub_client_devs); kfree(sd->hid_sensor_hub_client_devs);
err_close: err_close:
hid_hw_stop(hdev);
hid_hw_close(hdev); hid_hw_close(hdev);
err_stop_hw: err_stop_hw:
hid_hw_stop(hdev); hid_hw_stop(hdev);
...@@ -627,9 +613,8 @@ static void sensor_hub_remove(struct hid_device *hdev) ...@@ -627,9 +613,8 @@ static void sensor_hub_remove(struct hid_device *hdev)
int i; int i;
hid_dbg(hdev, " hardware removed\n"); hid_dbg(hdev, " hardware removed\n");
hdev->claimed &= ~HID_CLAIMED_INPUT;
hid_hw_stop(hdev);
hid_hw_close(hdev); hid_hw_close(hdev);
hid_hw_stop(hdev);
spin_lock_irqsave(&data->lock, flags); spin_lock_irqsave(&data->lock, flags);
if (data->pending.status) if (data->pending.status)
complete(&data->pending.ready); complete(&data->pending.ready);
......
...@@ -54,4 +54,10 @@ config AT91_ADC ...@@ -54,4 +54,10 @@ config AT91_ADC
help help
Say yes here to build support for Atmel AT91 ADC. Say yes here to build support for Atmel AT91 ADC.
config LP8788_ADC
bool "LP8788 ADC driver"
depends on MFD_LP8788
help
Say yes here to build support for TI LP8788 ADC.
endmenu endmenu
...@@ -7,3 +7,4 @@ obj-$(CONFIG_AD7266) += ad7266.o ...@@ -7,3 +7,4 @@ obj-$(CONFIG_AD7266) += ad7266.o
obj-$(CONFIG_AD7476) += ad7476.o obj-$(CONFIG_AD7476) += ad7476.o
obj-$(CONFIG_AD7791) += ad7791.o obj-$(CONFIG_AD7791) += ad7791.o
obj-$(CONFIG_AT91_ADC) += at91_adc.o obj-$(CONFIG_AT91_ADC) += at91_adc.o
obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
/*
* TI LP8788 MFD - ADC driver
*
* Copyright 2012 Texas Instruments
*
* Author: Milo(Woogyom) Kim <milo.kim@ti.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/delay.h>
#include <linux/iio/iio.h>
#include <linux/iio/driver.h>
#include <linux/iio/machine.h>
#include <linux/mfd/lp8788.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
/* register address */
#define LP8788_ADC_CONF 0x60
#define LP8788_ADC_RAW 0x61
#define LP8788_ADC_DONE 0x63
#define ADC_CONV_START 1
struct lp8788_adc {
struct lp8788 *lp;
struct iio_map *map;
struct mutex lock;
};
static const int lp8788_scale[LPADC_MAX] = {
[LPADC_VBATT_5P5] = 1343101,
[LPADC_VIN_CHG] = 3052503,
[LPADC_IBATT] = 610500,
[LPADC_IC_TEMP] = 61050,
[LPADC_VBATT_6P0] = 1465201,
[LPADC_VBATT_5P0] = 1221001,
[LPADC_ADC1] = 610500,
[LPADC_ADC2] = 610500,
[LPADC_VDD] = 1025641,
[LPADC_VCOIN] = 757020,
[LPADC_ADC3] = 610500,
[LPADC_ADC4] = 610500,
};
static int lp8788_get_adc_result(struct lp8788_adc *adc, enum lp8788_adc_id id,
int *val)
{
unsigned int msb;
unsigned int lsb;
unsigned int result;
u8 data;
u8 rawdata[2];
int size = ARRAY_SIZE(rawdata);
int retry = 5;
int ret;
data = (id << 1) | ADC_CONV_START;
ret = lp8788_write_byte(adc->lp, LP8788_ADC_CONF, data);
if (ret)
goto err_io;
/* retry until adc conversion is done */
data = 0;
while (retry--) {
usleep_range(100, 200);
ret = lp8788_read_byte(adc->lp, LP8788_ADC_DONE, &data);
if (ret)
goto err_io;
/* conversion done */
if (data)
break;
}
ret = lp8788_read_multi_bytes(adc->lp, LP8788_ADC_RAW, rawdata, size);
if (ret)
goto err_io;
msb = (rawdata[0] << 4) & 0x00000ff0;
lsb = (rawdata[1] >> 4) & 0x0000000f;
result = msb | lsb;
*val = result;
return 0;
err_io:
return ret;
}
static int lp8788_adc_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val, int *val2, long mask)
{
struct lp8788_adc *adc = iio_priv(indio_dev);
enum lp8788_adc_id id = chan->channel;
int ret;
mutex_lock(&adc->lock);
switch (mask) {
case IIO_CHAN_INFO_RAW:
ret = lp8788_get_adc_result(adc, id, val) ? -EIO : IIO_VAL_INT;
break;
case IIO_CHAN_INFO_SCALE:
*val = lp8788_scale[id] / 1000000;
*val2 = lp8788_scale[id] % 1000000;
ret = IIO_VAL_INT_PLUS_MICRO;
break;
default:
ret = -EINVAL;
break;
}
mutex_unlock(&adc->lock);
return ret;
}
static const struct iio_info lp8788_adc_info = {
.read_raw = &lp8788_adc_read_raw,
.driver_module = THIS_MODULE,
};
#define LP8788_CHAN(_id, _type) { \
.type = _type, \
.indexed = 1, \
.channel = LPADC_##_id, \
.info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \
IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \
.datasheet_name = #_id, \
}
static const struct iio_chan_spec lp8788_adc_channels[] = {
[LPADC_VBATT_5P5] = LP8788_CHAN(VBATT_5P5, IIO_VOLTAGE),
[LPADC_VIN_CHG] = LP8788_CHAN(VIN_CHG, IIO_VOLTAGE),
[LPADC_IBATT] = LP8788_CHAN(IBATT, IIO_CURRENT),
[LPADC_IC_TEMP] = LP8788_CHAN(IC_TEMP, IIO_TEMP),
[LPADC_VBATT_6P0] = LP8788_CHAN(VBATT_6P0, IIO_VOLTAGE),
[LPADC_VBATT_5P0] = LP8788_CHAN(VBATT_5P0, IIO_VOLTAGE),
[LPADC_ADC1] = LP8788_CHAN(ADC1, IIO_VOLTAGE),
[LPADC_ADC2] = LP8788_CHAN(ADC2, IIO_VOLTAGE),
[LPADC_VDD] = LP8788_CHAN(VDD, IIO_VOLTAGE),
[LPADC_VCOIN] = LP8788_CHAN(VCOIN, IIO_VOLTAGE),
[LPADC_ADC3] = LP8788_CHAN(ADC3, IIO_VOLTAGE),
[LPADC_ADC4] = LP8788_CHAN(ADC4, IIO_VOLTAGE),
};
/* default maps used by iio consumer (lp8788-charger driver) */
static struct iio_map lp8788_default_iio_maps[] = {
{
.consumer_dev_name = "lp8788-charger",
.consumer_channel = "lp8788_vbatt_5p0",
.adc_channel_label = "VBATT_5P0",
},
{
.consumer_dev_name = "lp8788-charger",
.consumer_channel = "lp8788_adc1",
.adc_channel_label = "ADC1",
},
{ }
};
static int lp8788_iio_map_register(struct iio_dev *indio_dev,
struct lp8788_platform_data *pdata,
struct lp8788_adc *adc)
{
struct iio_map *map;
int ret;
map = (!pdata || !pdata->adc_pdata) ?
lp8788_default_iio_maps : pdata->adc_pdata;
ret = iio_map_array_register(indio_dev, map);
if (ret) {
dev_err(adc->lp->dev, "iio map err: %d\n", ret);
return ret;
}
adc->map = map;
return 0;
}
static inline void lp8788_iio_map_unregister(struct iio_dev *indio_dev,
struct lp8788_adc *adc)
{
iio_map_array_unregister(indio_dev, adc->map);
}
static int __devinit lp8788_adc_probe(struct platform_device *pdev)
{
struct lp8788 *lp = dev_get_drvdata(pdev->dev.parent);
struct iio_dev *indio_dev;
struct lp8788_adc *adc;
int ret;
indio_dev = iio_device_alloc(sizeof(*adc));
if (!indio_dev)
return -ENOMEM;
adc = iio_priv(indio_dev);
adc->lp = lp;
platform_set_drvdata(pdev, indio_dev);
ret = lp8788_iio_map_register(indio_dev, lp->pdata, adc);
if (ret)
goto err_iio_map;
mutex_init(&adc->lock);
indio_dev->dev.parent = lp->dev;
indio_dev->name = pdev->name;
indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->info = &lp8788_adc_info;
indio_dev->channels = lp8788_adc_channels;
indio_dev->num_channels = ARRAY_SIZE(lp8788_adc_channels);
ret = iio_device_register(indio_dev);
if (ret) {
dev_err(lp->dev, "iio dev register err: %d\n", ret);
goto err_iio_device;
}
return 0;
err_iio_device:
lp8788_iio_map_unregister(indio_dev, adc);
err_iio_map:
iio_device_free(indio_dev);
return ret;
}
static int __devexit lp8788_adc_remove(struct platform_device *pdev)
{
struct iio_dev *indio_dev = platform_get_drvdata(pdev);
struct lp8788_adc *adc = iio_priv(indio_dev);
iio_device_unregister(indio_dev);
lp8788_iio_map_unregister(indio_dev, adc);
iio_device_free(indio_dev);
return 0;
}
static struct platform_driver lp8788_adc_driver = {
.probe = lp8788_adc_probe,
.remove = __devexit_p(lp8788_adc_remove),
.driver = {
.name = LP8788_DEV_ADC,
.owner = THIS_MODULE,
},
};
module_platform_driver(lp8788_adc_driver);
MODULE_DESCRIPTION("Texas Instruments LP8788 ADC Driver");
MODULE_AUTHOR("Milo Kim");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:lp8788-adc");
...@@ -56,6 +56,7 @@ void hid_sensor_remove_trigger(struct iio_dev *indio_dev) ...@@ -56,6 +56,7 @@ void hid_sensor_remove_trigger(struct iio_dev *indio_dev)
{ {
iio_trigger_unregister(indio_dev->trig); iio_trigger_unregister(indio_dev->trig);
iio_trigger_free(indio_dev->trig); iio_trigger_free(indio_dev->trig);
indio_dev->trig = NULL;
} }
EXPORT_SYMBOL(hid_sensor_remove_trigger); EXPORT_SYMBOL(hid_sensor_remove_trigger);
......
...@@ -451,9 +451,9 @@ static int __devinit ad5755_setup_pdata(struct iio_dev *indio_dev, ...@@ -451,9 +451,9 @@ static int __devinit ad5755_setup_pdata(struct iio_dev *indio_dev,
const struct ad5755_platform_data *pdata) const struct ad5755_platform_data *pdata)
{ {
struct ad5755_state *st = iio_priv(indio_dev); struct ad5755_state *st = iio_priv(indio_dev);
unsigned int ret;
unsigned int val; unsigned int val;
unsigned int i; unsigned int i;
int ret;
if (pdata->dc_dc_phase > AD5755_DC_DC_PHASE_90_DEGREE || if (pdata->dc_dc_phase > AD5755_DC_DC_PHASE_90_DEGREE ||
pdata->dc_dc_freq > AD5755_DC_DC_FREQ_650kHZ || pdata->dc_dc_freq > AD5755_DC_DC_FREQ_650kHZ ||
......
...@@ -111,6 +111,7 @@ struct iio_channel *iio_channel_get(const char *name, const char *channel_name) ...@@ -111,6 +111,7 @@ struct iio_channel *iio_channel_get(const char *name, const char *channel_name)
{ {
struct iio_map_internal *c_i = NULL, *c = NULL; struct iio_map_internal *c_i = NULL, *c = NULL;
struct iio_channel *channel; struct iio_channel *channel;
int err;
if (name == NULL && channel_name == NULL) if (name == NULL && channel_name == NULL)
return ERR_PTR(-ENODEV); return ERR_PTR(-ENODEV);
...@@ -131,8 +132,10 @@ struct iio_channel *iio_channel_get(const char *name, const char *channel_name) ...@@ -131,8 +132,10 @@ struct iio_channel *iio_channel_get(const char *name, const char *channel_name)
return ERR_PTR(-ENODEV); return ERR_PTR(-ENODEV);
channel = kzalloc(sizeof(*channel), GFP_KERNEL); channel = kzalloc(sizeof(*channel), GFP_KERNEL);
if (channel == NULL) if (channel == NULL) {
return ERR_PTR(-ENOMEM); err = -ENOMEM;
goto error_no_mem;
}
channel->indio_dev = c->indio_dev; channel->indio_dev = c->indio_dev;
...@@ -141,16 +144,19 @@ struct iio_channel *iio_channel_get(const char *name, const char *channel_name) ...@@ -141,16 +144,19 @@ struct iio_channel *iio_channel_get(const char *name, const char *channel_name)
iio_chan_spec_from_name(channel->indio_dev, iio_chan_spec_from_name(channel->indio_dev,
c->map->adc_channel_label); c->map->adc_channel_label);
if (channel->channel == NULL) if (channel->channel == NULL) {
err = -EINVAL;
goto error_no_chan; goto error_no_chan;
} }
}
return channel; return channel;
error_no_chan: error_no_chan:
iio_device_put(c->indio_dev);
kfree(channel); kfree(channel);
return ERR_PTR(-EINVAL); error_no_mem:
iio_device_put(c->indio_dev);
return ERR_PTR(err);
} }
EXPORT_SYMBOL_GPL(iio_channel_get); EXPORT_SYMBOL_GPL(iio_channel_get);
......
...@@ -29,6 +29,13 @@ config APM_POWER ...@@ -29,6 +29,13 @@ config APM_POWER
Say Y here to enable support APM status emulation using Say Y here to enable support APM status emulation using
battery class devices. battery class devices.
config GENERIC_ADC_BATTERY
tristate "Generic battery support using IIO"
depends on IIO
help
Say Y here to enable support for the generic battery driver
which uses IIO framework to read adc.
config MAX8925_POWER config MAX8925_POWER
tristate "MAX8925 battery charger support" tristate "MAX8925 battery charger support"
depends on MFD_MAX8925 depends on MFD_MAX8925
......
...@@ -5,6 +5,7 @@ power_supply-$(CONFIG_SYSFS) += power_supply_sysfs.o ...@@ -5,6 +5,7 @@ power_supply-$(CONFIG_SYSFS) += power_supply_sysfs.o
power_supply-$(CONFIG_LEDS_TRIGGERS) += power_supply_leds.o power_supply-$(CONFIG_LEDS_TRIGGERS) += power_supply_leds.o
obj-$(CONFIG_POWER_SUPPLY) += power_supply.o obj-$(CONFIG_POWER_SUPPLY) += power_supply.o
obj-$(CONFIG_GENERIC_ADC_BATTERY) += generic-adc-battery.o
obj-$(CONFIG_PDA_POWER) += pda_power.o obj-$(CONFIG_PDA_POWER) += pda_power.o
obj-$(CONFIG_APM_POWER) += apm_power.o obj-$(CONFIG_APM_POWER) += apm_power.o
......
This diff is collapsed.
...@@ -782,19 +782,13 @@ static int lis3l02dq_stop_device(struct iio_dev *indio_dev) ...@@ -782,19 +782,13 @@ static int lis3l02dq_stop_device(struct iio_dev *indio_dev)
/* fixme, confirm ordering in this function */ /* fixme, confirm ordering in this function */
static int __devexit lis3l02dq_remove(struct spi_device *spi) static int __devexit lis3l02dq_remove(struct spi_device *spi)
{ {
int ret;
struct iio_dev *indio_dev = spi_get_drvdata(spi); struct iio_dev *indio_dev = spi_get_drvdata(spi);
struct lis3l02dq_state *st = iio_priv(indio_dev); struct lis3l02dq_state *st = iio_priv(indio_dev);
iio_device_unregister(indio_dev); iio_device_unregister(indio_dev);
ret = lis3l02dq_disable_all_events(indio_dev); lis3l02dq_disable_all_events(indio_dev);
if (ret) lis3l02dq_stop_device(indio_dev);
goto err_ret;
ret = lis3l02dq_stop_device(indio_dev);
if (ret)
goto err_ret;
if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0) if (spi->irq && gpio_is_valid(irq_to_gpio(spi->irq)) > 0)
free_irq(st->us->irq, indio_dev); free_irq(st->us->irq, indio_dev);
...@@ -804,8 +798,8 @@ static int __devexit lis3l02dq_remove(struct spi_device *spi) ...@@ -804,8 +798,8 @@ static int __devexit lis3l02dq_remove(struct spi_device *spi)
lis3l02dq_unconfigure_buffer(indio_dev); lis3l02dq_unconfigure_buffer(indio_dev);
iio_device_free(indio_dev); iio_device_free(indio_dev);
err_ret:
return ret; return 0;
} }
static struct spi_driver lis3l02dq_driver = { static struct spi_driver lis3l02dq_driver = {
......
...@@ -1237,11 +1237,9 @@ static int __devexit sca3000_remove(struct spi_device *spi) ...@@ -1237,11 +1237,9 @@ static int __devexit sca3000_remove(struct spi_device *spi)
{ {
struct iio_dev *indio_dev = spi_get_drvdata(spi); struct iio_dev *indio_dev = spi_get_drvdata(spi);
struct sca3000_state *st = iio_priv(indio_dev); struct sca3000_state *st = iio_priv(indio_dev);
int ret;
/* Must ensure no interrupts can be generated after this!*/ /* Must ensure no interrupts can be generated after this!*/
ret = sca3000_stop_all_interrupts(st); sca3000_stop_all_interrupts(st);
if (ret)
return ret;
if (spi->irq) if (spi->irq)
free_irq(spi->irq, indio_dev); free_irq(spi->irq, indio_dev);
iio_device_unregister(indio_dev); iio_device_unregister(indio_dev);
......
...@@ -82,12 +82,12 @@ config AD7887 ...@@ -82,12 +82,12 @@ config AD7887
module will be called ad7887. module will be called ad7887.
config AD7780 config AD7780
tristate "Analog Devices AD7780 AD7781 ADC driver" tristate "Analog Devices AD7780 and similar ADCs driver"
depends on SPI depends on SPI
depends on GPIOLIB depends on GPIOLIB
select AD_SIGMA_DELTA select AD_SIGMA_DELTA
help help
Say yes here to build support for Analog Devices Say yes here to build support for Analog Devices AD7170, AD7171,
AD7780 and AD7781 SPI analog to digital converters (ADC). AD7780 and AD7781 SPI analog to digital converters (ADC).
If unsure, say N (but it's safe to say "Y"). If unsure, say N (but it's safe to say "Y").
......
/* /*
* AD7780/AD7781 SPI ADC driver * AD7170/AD7171 and AD7780/AD7781 SPI ADC driver
* *
* Copyright 2011 Analog Devices Inc. * Copyright 2011 Analog Devices Inc.
* *
...@@ -35,6 +35,8 @@ ...@@ -35,6 +35,8 @@
struct ad7780_chip_info { struct ad7780_chip_info {
struct iio_chan_spec channel; struct iio_chan_spec channel;
unsigned int pattern_mask;
unsigned int pattern;
}; };
struct ad7780_state { struct ad7780_state {
...@@ -48,6 +50,8 @@ struct ad7780_state { ...@@ -48,6 +50,8 @@ struct ad7780_state {
}; };
enum ad7780_supported_device_ids { enum ad7780_supported_device_ids {
ID_AD7170,
ID_AD7171,
ID_AD7780, ID_AD7780,
ID_AD7781, ID_AD7781,
}; };
...@@ -73,6 +77,7 @@ static int ad7780_set_mode(struct ad_sigma_delta *sigma_delta, ...@@ -73,6 +77,7 @@ static int ad7780_set_mode(struct ad_sigma_delta *sigma_delta,
break; break;
} }
if (gpio_is_valid(st->powerdown_gpio))
gpio_set_value(st->powerdown_gpio, val); gpio_set_value(st->powerdown_gpio, val);
return 0; return 0;
...@@ -108,9 +113,10 @@ static int ad7780_postprocess_sample(struct ad_sigma_delta *sigma_delta, ...@@ -108,9 +113,10 @@ static int ad7780_postprocess_sample(struct ad_sigma_delta *sigma_delta,
unsigned int raw_sample) unsigned int raw_sample)
{ {
struct ad7780_state *st = ad_sigma_delta_to_ad7780(sigma_delta); struct ad7780_state *st = ad_sigma_delta_to_ad7780(sigma_delta);
const struct ad7780_chip_info *chip_info = st->chip_info;
if ((raw_sample & AD7780_ERR) || if ((raw_sample & AD7780_ERR) ||
!((raw_sample & AD7780_PAT0) && !(raw_sample & AD7780_PAT1))) ((raw_sample & chip_info->pattern_mask) != chip_info->pattern))
return -EIO; return -EIO;
if (raw_sample & AD7780_GAIN) if (raw_sample & AD7780_GAIN)
...@@ -127,12 +133,29 @@ static const struct ad_sigma_delta_info ad7780_sigma_delta_info = { ...@@ -127,12 +133,29 @@ static const struct ad_sigma_delta_info ad7780_sigma_delta_info = {
.has_registers = false, .has_registers = false,
}; };
#define AD7780_CHANNEL(bits, wordsize) \
AD_SD_CHANNEL(1, 0, 0, bits, 32, wordsize - bits)
static const struct ad7780_chip_info ad7780_chip_info_tbl[] = { static const struct ad7780_chip_info ad7780_chip_info_tbl[] = {
[ID_AD7170] = {
.channel = AD7780_CHANNEL(12, 24),
.pattern = 0x5,
.pattern_mask = 0x7,
},
[ID_AD7171] = {
.channel = AD7780_CHANNEL(16, 24),
.pattern = 0x5,
.pattern_mask = 0x7,
},
[ID_AD7780] = { [ID_AD7780] = {
.channel = AD_SD_CHANNEL(1, 0, 0, 24, 32, 8), .channel = AD7780_CHANNEL(24, 32),
.pattern = 0x1,
.pattern_mask = 0x3,
}, },
[ID_AD7781] = { [ID_AD7781] = {
.channel = AD_SD_CHANNEL(1, 0, 0, 20, 32, 12), .channel = AD7780_CHANNEL(20, 32),
.pattern = 0x1,
.pattern_mask = 0x3,
}, },
}; };
...@@ -148,11 +171,6 @@ static int __devinit ad7780_probe(struct spi_device *spi) ...@@ -148,11 +171,6 @@ static int __devinit ad7780_probe(struct spi_device *spi)
struct iio_dev *indio_dev; struct iio_dev *indio_dev;
int ret, voltage_uv = 0; int ret, voltage_uv = 0;
if (!pdata) {
dev_dbg(&spi->dev, "no platform data?\n");
return -ENODEV;
}
indio_dev = iio_device_alloc(sizeof(*st)); indio_dev = iio_device_alloc(sizeof(*st));
if (indio_dev == NULL) if (indio_dev == NULL)
return -ENOMEM; return -ENOMEM;
...@@ -174,8 +192,6 @@ static int __devinit ad7780_probe(struct spi_device *spi) ...@@ -174,8 +192,6 @@ static int __devinit ad7780_probe(struct spi_device *spi)
st->chip_info = st->chip_info =
&ad7780_chip_info_tbl[spi_get_device_id(spi)->driver_data]; &ad7780_chip_info_tbl[spi_get_device_id(spi)->driver_data];
st->powerdown_gpio = pdata->gpio_pdrst;
if (pdata && pdata->vref_mv) if (pdata && pdata->vref_mv)
st->int_vref_mv = pdata->vref_mv; st->int_vref_mv = pdata->vref_mv;
else if (voltage_uv) else if (voltage_uv)
...@@ -192,12 +208,18 @@ static int __devinit ad7780_probe(struct spi_device *spi) ...@@ -192,12 +208,18 @@ static int __devinit ad7780_probe(struct spi_device *spi)
indio_dev->num_channels = 1; indio_dev->num_channels = 1;
indio_dev->info = &ad7780_info; indio_dev->info = &ad7780_info;
if (pdata && gpio_is_valid(pdata->gpio_pdrst)) {
ret = gpio_request_one(pdata->gpio_pdrst, GPIOF_OUT_INIT_LOW, ret = gpio_request_one(pdata->gpio_pdrst, GPIOF_OUT_INIT_LOW,
"AD7780 /PDRST"); "AD7780 /PDRST");
if (ret) { if (ret) {
dev_err(&spi->dev, "failed to request GPIO PDRST\n"); dev_err(&spi->dev, "failed to request GPIO PDRST\n");
goto error_disable_reg; goto error_disable_reg;
} }
st->powerdown_gpio = pdata->gpio_pdrst;
} else {
st->powerdown_gpio = -1;
}
ret = ad_sd_setup_buffer_and_trigger(indio_dev); ret = ad_sd_setup_buffer_and_trigger(indio_dev);
if (ret) if (ret)
...@@ -212,6 +234,7 @@ static int __devinit ad7780_probe(struct spi_device *spi) ...@@ -212,6 +234,7 @@ static int __devinit ad7780_probe(struct spi_device *spi)
error_cleanup_buffer_and_trigger: error_cleanup_buffer_and_trigger:
ad_sd_cleanup_buffer_and_trigger(indio_dev); ad_sd_cleanup_buffer_and_trigger(indio_dev);
error_free_gpio: error_free_gpio:
if (pdata && gpio_is_valid(pdata->gpio_pdrst))
gpio_free(pdata->gpio_pdrst); gpio_free(pdata->gpio_pdrst);
error_disable_reg: error_disable_reg:
if (!IS_ERR(st->reg)) if (!IS_ERR(st->reg))
...@@ -233,7 +256,9 @@ static int __devexit ad7780_remove(struct spi_device *spi) ...@@ -233,7 +256,9 @@ static int __devexit ad7780_remove(struct spi_device *spi)
iio_device_unregister(indio_dev); iio_device_unregister(indio_dev);
ad_sd_cleanup_buffer_and_trigger(indio_dev); ad_sd_cleanup_buffer_and_trigger(indio_dev);
if (gpio_is_valid(st->powerdown_gpio))
gpio_free(st->powerdown_gpio); gpio_free(st->powerdown_gpio);
if (!IS_ERR(st->reg)) { if (!IS_ERR(st->reg)) {
regulator_disable(st->reg); regulator_disable(st->reg);
regulator_put(st->reg); regulator_put(st->reg);
...@@ -244,6 +269,8 @@ static int __devexit ad7780_remove(struct spi_device *spi) ...@@ -244,6 +269,8 @@ static int __devexit ad7780_remove(struct spi_device *spi)
} }
static const struct spi_device_id ad7780_id[] = { static const struct spi_device_id ad7780_id[] = {
{"ad7170", ID_AD7170},
{"ad7171", ID_AD7171},
{"ad7780", ID_AD7780}, {"ad7780", ID_AD7780},
{"ad7781", ID_AD7781}, {"ad7781", ID_AD7781},
{} {}
...@@ -262,5 +289,5 @@ static struct spi_driver ad7780_driver = { ...@@ -262,5 +289,5 @@ static struct spi_driver ad7780_driver = {
module_spi_driver(ad7780_driver); module_spi_driver(ad7780_driver);
MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>"); MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
MODULE_DESCRIPTION("Analog Devices AD7780/1 ADC"); MODULE_DESCRIPTION("Analog Devices AD7780 and similar ADCs");
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");
...@@ -702,22 +702,16 @@ static int __devinit adis16260_probe(struct spi_device *spi) ...@@ -702,22 +702,16 @@ static int __devinit adis16260_probe(struct spi_device *spi)
static int __devexit adis16260_remove(struct spi_device *spi) static int __devexit adis16260_remove(struct spi_device *spi)
{ {
int ret;
struct iio_dev *indio_dev = spi_get_drvdata(spi); struct iio_dev *indio_dev = spi_get_drvdata(spi);
iio_device_unregister(indio_dev); iio_device_unregister(indio_dev);
adis16260_stop_device(indio_dev);
ret = adis16260_stop_device(indio_dev);
if (ret)
goto err_ret;
adis16260_remove_trigger(indio_dev); adis16260_remove_trigger(indio_dev);
iio_buffer_unregister(indio_dev); iio_buffer_unregister(indio_dev);
adis16260_unconfigure_ring(indio_dev); adis16260_unconfigure_ring(indio_dev);
iio_device_free(indio_dev); iio_device_free(indio_dev);
err_ret: return 0;
return ret;
} }
/* /*
......
...@@ -445,26 +445,20 @@ static int __devinit iio_dummy_probe(int index) ...@@ -445,26 +445,20 @@ static int __devinit iio_dummy_probe(int index)
if (ret < 0) if (ret < 0)
goto error_free_device; goto error_free_device;
/* Configure buffered capture support. */
ret = iio_simple_dummy_configure_buffer(indio_dev);
if (ret < 0)
goto error_unregister_events;
/* /*
* Register the channels with the buffer, but avoid the output * Configure buffered capture support and register the channels with the
* channel being registered by reducing the number of channels by 1. * buffer, but avoid the output channel being registered by reducing the
* number of channels by 1.
*/ */
ret = iio_buffer_register(indio_dev, iio_dummy_channels, 5); ret = iio_simple_dummy_configure_buffer(indio_dev, iio_dummy_channels, 5);
if (ret < 0) if (ret < 0)
goto error_unconfigure_buffer; goto error_unregister_events;
ret = iio_device_register(indio_dev); ret = iio_device_register(indio_dev);
if (ret < 0) if (ret < 0)
goto error_unregister_buffer; goto error_unconfigure_buffer;
return 0; return 0;
error_unregister_buffer:
iio_buffer_unregister(indio_dev);
error_unconfigure_buffer: error_unconfigure_buffer:
iio_simple_dummy_unconfigure_buffer(indio_dev); iio_simple_dummy_unconfigure_buffer(indio_dev);
error_unregister_events: error_unregister_events:
...@@ -499,7 +493,6 @@ static int iio_dummy_remove(int index) ...@@ -499,7 +493,6 @@ static int iio_dummy_remove(int index)
/* Device specific code to power down etc */ /* Device specific code to power down etc */
/* Buffered capture related cleanup */ /* Buffered capture related cleanup */
iio_buffer_unregister(indio_dev);
iio_simple_dummy_unconfigure_buffer(indio_dev); iio_simple_dummy_unconfigure_buffer(indio_dev);
ret = iio_simple_dummy_events_unregister(indio_dev); ret = iio_simple_dummy_events_unregister(indio_dev);
...@@ -530,6 +523,7 @@ static __init int iio_dummy_init(void) ...@@ -530,6 +523,7 @@ static __init int iio_dummy_init(void)
instances = 1; instances = 1;
return -EINVAL; return -EINVAL;
} }
/* Fake a bus */ /* Fake a bus */
iio_dummy_devs = kcalloc(instances, sizeof(*iio_dummy_devs), iio_dummy_devs = kcalloc(instances, sizeof(*iio_dummy_devs),
GFP_KERNEL); GFP_KERNEL);
......
...@@ -95,10 +95,12 @@ enum iio_simple_dummy_scan_elements { ...@@ -95,10 +95,12 @@ enum iio_simple_dummy_scan_elements {
}; };
#ifdef CONFIG_IIO_SIMPLE_DUMMY_BUFFER #ifdef CONFIG_IIO_SIMPLE_DUMMY_BUFFER
int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev); int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev,
const struct iio_chan_spec *channels, unsigned int num_channels);
void iio_simple_dummy_unconfigure_buffer(struct iio_dev *indio_dev); void iio_simple_dummy_unconfigure_buffer(struct iio_dev *indio_dev);
#else #else
static inline int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev) static inline int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev,
const struct iio_chan_spec *channels, unsigned int num_channels)
{ {
return 0; return 0;
}; };
......
...@@ -126,7 +126,8 @@ static const struct iio_buffer_setup_ops iio_simple_dummy_buffer_setup_ops = { ...@@ -126,7 +126,8 @@ static const struct iio_buffer_setup_ops iio_simple_dummy_buffer_setup_ops = {
.predisable = &iio_triggered_buffer_predisable, .predisable = &iio_triggered_buffer_predisable,
}; };
int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev) int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev,
const struct iio_chan_spec *channels, unsigned int num_channels)
{ {
int ret; int ret;
struct iio_buffer *buffer; struct iio_buffer *buffer;
...@@ -182,8 +183,15 @@ int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev) ...@@ -182,8 +183,15 @@ int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev)
* driven by a trigger. * driven by a trigger.
*/ */
indio_dev->modes |= INDIO_BUFFER_TRIGGERED; indio_dev->modes |= INDIO_BUFFER_TRIGGERED;
ret = iio_buffer_register(indio_dev, channels, num_channels);
if (ret)
goto error_dealloc_pollfunc;
return 0; return 0;
error_dealloc_pollfunc:
iio_dealloc_pollfunc(indio_dev->pollfunc);
error_free_buffer: error_free_buffer:
iio_kfifo_free(indio_dev->buffer); iio_kfifo_free(indio_dev->buffer);
error_ret: error_ret:
...@@ -197,6 +205,7 @@ int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev) ...@@ -197,6 +205,7 @@ int iio_simple_dummy_configure_buffer(struct iio_dev *indio_dev)
*/ */
void iio_simple_dummy_unconfigure_buffer(struct iio_dev *indio_dev) void iio_simple_dummy_unconfigure_buffer(struct iio_dev *indio_dev)
{ {
iio_buffer_unregister(indio_dev);
iio_dealloc_pollfunc(indio_dev->pollfunc); iio_dealloc_pollfunc(indio_dev->pollfunc);
iio_kfifo_free(indio_dev->buffer); iio_kfifo_free(indio_dev->buffer);
} }
...@@ -1208,13 +1208,10 @@ static int __devinit adis16400_probe(struct spi_device *spi) ...@@ -1208,13 +1208,10 @@ static int __devinit adis16400_probe(struct spi_device *spi)
/* fixme, confirm ordering in this function */ /* fixme, confirm ordering in this function */
static int __devexit adis16400_remove(struct spi_device *spi) static int __devexit adis16400_remove(struct spi_device *spi)
{ {
int ret;
struct iio_dev *indio_dev = spi_get_drvdata(spi); struct iio_dev *indio_dev = spi_get_drvdata(spi);
iio_device_unregister(indio_dev); iio_device_unregister(indio_dev);
ret = adis16400_stop_device(indio_dev); adis16400_stop_device(indio_dev);
if (ret)
goto err_ret;
adis16400_remove_trigger(indio_dev); adis16400_remove_trigger(indio_dev);
iio_buffer_unregister(indio_dev); iio_buffer_unregister(indio_dev);
...@@ -1222,9 +1219,6 @@ static int __devexit adis16400_remove(struct spi_device *spi) ...@@ -1222,9 +1219,6 @@ static int __devexit adis16400_remove(struct spi_device *spi)
iio_device_free(indio_dev); iio_device_free(indio_dev);
return 0; return 0;
err_ret:
return ret;
} }
static const struct spi_device_id adis16400_id[] = { static const struct spi_device_id adis16400_id[] = {
......
...@@ -557,18 +557,13 @@ static int __devinit ade7753_probe(struct spi_device *spi) ...@@ -557,18 +557,13 @@ static int __devinit ade7753_probe(struct spi_device *spi)
/* fixme, confirm ordering in this function */ /* fixme, confirm ordering in this function */
static int __devexit ade7753_remove(struct spi_device *spi) static int __devexit ade7753_remove(struct spi_device *spi)
{ {
int ret;
struct iio_dev *indio_dev = spi_get_drvdata(spi); struct iio_dev *indio_dev = spi_get_drvdata(spi);
iio_device_unregister(indio_dev); iio_device_unregister(indio_dev);
ade7753_stop_device(&indio_dev->dev);
ret = ade7753_stop_device(&(indio_dev->dev));
if (ret)
goto err_ret;
iio_device_free(indio_dev); iio_device_free(indio_dev);
err_ret:
return ret; return 0;
} }
static struct spi_driver ade7753_driver = { static struct spi_driver ade7753_driver = {
......
...@@ -579,19 +579,13 @@ static int __devinit ade7754_probe(struct spi_device *spi) ...@@ -579,19 +579,13 @@ static int __devinit ade7754_probe(struct spi_device *spi)
/* fixme, confirm ordering in this function */ /* fixme, confirm ordering in this function */
static int __devexit ade7754_remove(struct spi_device *spi) static int __devexit ade7754_remove(struct spi_device *spi)
{ {
int ret;
struct iio_dev *indio_dev = spi_get_drvdata(spi); struct iio_dev *indio_dev = spi_get_drvdata(spi);
iio_device_unregister(indio_dev); iio_device_unregister(indio_dev);
ret = ade7754_stop_device(&(indio_dev->dev)); ade7754_stop_device(&indio_dev->dev);
if (ret)
goto err_ret;
iio_device_free(indio_dev); iio_device_free(indio_dev);
err_ret: return 0;
return ret;
} }
static struct spi_driver ade7754_driver = { static struct spi_driver ade7754_driver = {
......
...@@ -966,13 +966,9 @@ static int __devexit ade7758_remove(struct spi_device *spi) ...@@ -966,13 +966,9 @@ static int __devexit ade7758_remove(struct spi_device *spi)
{ {
struct iio_dev *indio_dev = spi_get_drvdata(spi); struct iio_dev *indio_dev = spi_get_drvdata(spi);
struct ade7758_state *st = iio_priv(indio_dev); struct ade7758_state *st = iio_priv(indio_dev);
int ret;
iio_device_unregister(indio_dev); iio_device_unregister(indio_dev);
ret = ade7758_stop_device(&indio_dev->dev); ade7758_stop_device(&indio_dev->dev);
if (ret)
goto err_ret;
ade7758_remove_trigger(indio_dev); ade7758_remove_trigger(indio_dev);
ade7758_uninitialize_ring(indio_dev); ade7758_uninitialize_ring(indio_dev);
ade7758_unconfigure_ring(indio_dev); ade7758_unconfigure_ring(indio_dev);
...@@ -981,8 +977,7 @@ static int __devexit ade7758_remove(struct spi_device *spi) ...@@ -981,8 +977,7 @@ static int __devexit ade7758_remove(struct spi_device *spi)
iio_device_free(indio_dev); iio_device_free(indio_dev);
err_ret: return 0;
return ret;
} }
static const struct spi_device_id ade7758_id[] = { static const struct spi_device_id ade7758_id[] = {
......
...@@ -501,18 +501,13 @@ static int __devinit ade7759_probe(struct spi_device *spi) ...@@ -501,18 +501,13 @@ static int __devinit ade7759_probe(struct spi_device *spi)
/* fixme, confirm ordering in this function */ /* fixme, confirm ordering in this function */
static int __devexit ade7759_remove(struct spi_device *spi) static int __devexit ade7759_remove(struct spi_device *spi)
{ {
int ret;
struct iio_dev *indio_dev = spi_get_drvdata(spi); struct iio_dev *indio_dev = spi_get_drvdata(spi);
iio_device_unregister(indio_dev); iio_device_unregister(indio_dev);
ret = ade7759_stop_device(&(indio_dev->dev)); ade7759_stop_device(&indio_dev->dev);
if (ret)
goto err_ret;
iio_device_free(indio_dev); iio_device_free(indio_dev);
err_ret: return 0;
return ret;
} }
static struct spi_driver ade7759_driver = { static struct spi_driver ade7759_driver = {
......
/*
* Copyright (C) 2012, Anish Kumar <anish198519851985@gmail.com>
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef GENERIC_ADC_BATTERY_H
#define GENERIC_ADC_BATTERY_H
/**
* struct gab_platform_data - platform_data for generic adc iio battery driver.
* @battery_info: recommended structure to specify static power supply
* parameters
* @cal_charge: calculate charge level.
* @gpio_charge_finished: gpio for the charger.
* @gpio_inverted: Should be 1 if the GPIO is active low otherwise 0
* @jitter_delay: delay required after the interrupt to check battery
* status.Default set is 10ms.
*/
struct gab_platform_data {
struct power_supply_info battery_info;
int (*cal_charge)(long value);
int gpio_charge_finished;
bool gpio_inverted;
int jitter_delay;
};
#endif /* GENERIC_ADC_BATTERY_H */
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