First round of new drivers, functionality and cleanups for IIO in the 3.13 cycle
A number of new drivers and some new functionality + a lot of cleanups all over IIO. New Core Elements 1) New INT_TIME info_mask element for integration time, which may have different effects on measurement noise and similar, than an amplifier and hence is different from existing SCALE. Already existed in some drivers as a custom attribute. 2) Introduce a iio_push_buffers_with_timestamp helper to cover the common case of filling the last 64 bits of data to be passed to the buffer with a timestamp. Applied to lots of drivers. Cuts down on repeated code and moves a slightly fiddly bit of logic into a single location. 3) Introduce info_mask_[shared_by_dir/shared_by_all] elements to allow support of elements such as sampling_frequency which is typically shared by all input channels on a device. This reduces code and makes these controls available from in kernel consumers of IIO devices. New drivers 1) MCP3422/3/4 ADC 2) TSL4531 ambient light sensor 3) TCS3472/5 color light sensor 4) GP2AP020A00F ambient light / proximity sensor 5) LPS001WP support added to ST pressure sensor driver. New driver functionality 1) ti_am335x_adc Add buffered sampling support. This device has a hardware fifo that is fed directly into an IIO kfifo buffer based on a watershed interrupt. Note this will act as an example of how to handle this increasingly common type of device. The only previous example - sca3000 - take a less than optimal approach which is largely why it is still in staging. A couple of little cleanups for that new functionality followed later. Core cleanups: 1) MAINTAINERS - Sachin actually brought my email address up to date because I said I'd do it and never got around to it :) 2) Assign buffer list elements as single element lists to simplify the iio_buffer_is_active logic. 3) wake_up_interruptible_poll instead of wake_up_interruptible to only wake up threads waiting for poll notifications. 4) Add O_CLOEXEC flag to anon_inode_get_fd call for IIO event interface. 5) Change iio_push_to_buffers to take a void * pointer so as to avoid some annoying and unnecessary type casts. 6) iio_compute_scan_bytes incorrectly took a long rather than unsigned long. 7) Various minor tidy ups. Driver cleanups (in no particular order) 1) Another set of devm_ allocations patches from Sachin Kamat. 2) tsl2x7x - 0 to NULL cleanup. 3) hmc5843 - fix missing > in MODULE_AUTHOR 4) Set of strict_strto* to kstrto* conversions. 5) mxs-lradc - fix ordering of resource removal to match creation 6) mxs-lradc - add MODULE_ALIAS 7) adc7606 - drop a work pending test duplicated in core functions. 8) hmc5843 - devm_ allocation patch 9) Series of redundant breaks removed. 10) ad2s1200 - pr_err -> dev_err 11) adjd_s311 - use INT_TIME 12) ST sensors - large set of cleanups from Lee Jones and removed restriction to using only triggers provided by the st_sensors themselves from Dennis Ciocca. 13) dummy and tmp006 provide sampling_frequency via info_mask_shared_by_all. 14) tcs3472 - fix incorrect buffer size and wrong device pointer used in suspend / resume functions. 15) max1363 - use defaults for buffer setup ops as provided by the triggered buffer helpers as they are the same as were specified in max1363 driver. 16) Trivial tidy ups in a number of other drivers. -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.21 (GNU/Linux) iQIcBAABAgAGBQJSP0HUAAoJEFSFNJnE9BaIwiQQAKuJaoPrdMezm1TDaqgrzQWQ U95mSJ19xPYVSQVNHFLFidcajhADRMFhMUGOJF64VZObEdOtFWI0UkrJjFhYtJTt n1B6qAqPjatmruj434+n5PW32XtareOPThso5EDCAW0X+CNgSOgda+TVj+9g1Ilg Onltb3wugMcs27FakZpKv1YuGyKAKE6uT/33qr++cuynR89JZOlp0QmLgIXobVRR WdjuiH8OXFA4LsP7dWQhoSejs6+JPMn992qkACUc5fztQfFfCk0eJsgQIsOXkz1e U6MFvab0LtdPKDRyzT1kIpK/Jxf1OVNiOYaQNIGuNMipa+5WRz2lF1sZyERQTJWR HOZehkikBdL73WaaKwyaLTsYyDMbYM9ZkpLrBEFRr7ocZpg/0LA84BWYYDWu1Nok 9Ib9xNAxcAgFwQMJpiz9J3ap/IzV2qJT9rv78q1chVwhNhVDs2CbwcuZKAB4UvWs Oz7C0Xx5DA/K7DlpJMLaVB1+BRJ3C1I9Jbr84mnu0clgOqFE+nrdKZcUTrOTFXdy 2yTp7Bkc2JiRtOYhI40UL79N08KCGNTUfigmUDQseF2dsaNlz5rTOiMifYQCRw9+ C1kxY00emzlGTvfUDdPwkiQTtz8tWf9Ahvjx/ufGfed68KWDMs1VuGNcqEzgqKNI SMP0VTEXbCiLeWYMqGep =mMgm -----END PGP SIGNATURE----- Merge tag 'iio-for-3.13a' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-next Jonathan writes: First round of new drivers, functionality and cleanups for IIO in the 3.13 cycle A number of new drivers and some new functionality + a lot of cleanups all over IIO. New Core Elements 1) New INT_TIME info_mask element for integration time, which may have different effects on measurement noise and similar, than an amplifier and hence is different from existing SCALE. Already existed in some drivers as a custom attribute. 2) Introduce a iio_push_buffers_with_timestamp helper to cover the common case of filling the last 64 bits of data to be passed to the buffer with a timestamp. Applied to lots of drivers. Cuts down on repeated code and moves a slightly fiddly bit of logic into a single location. 3) Introduce info_mask_[shared_by_dir/shared_by_all] elements to allow support of elements such as sampling_frequency which is typically shared by all input channels on a device. This reduces code and makes these controls available from in kernel consumers of IIO devices. New drivers 1) MCP3422/3/4 ADC 2) TSL4531 ambient light sensor 3) TCS3472/5 color light sensor 4) GP2AP020A00F ambient light / proximity sensor 5) LPS001WP support added to ST pressure sensor driver. New driver functionality 1) ti_am335x_adc Add buffered sampling support. This device has a hardware fifo that is fed directly into an IIO kfifo buffer based on a watershed interrupt. Note this will act as an example of how to handle this increasingly common type of device. The only previous example - sca3000 - take a less than optimal approach which is largely why it is still in staging. A couple of little cleanups for that new functionality followed later. Core cleanups: 1) MAINTAINERS - Sachin actually brought my email address up to date because I said I'd do it and never got around to it :) 2) Assign buffer list elements as single element lists to simplify the iio_buffer_is_active logic. 3) wake_up_interruptible_poll instead of wake_up_interruptible to only wake up threads waiting for poll notifications. 4) Add O_CLOEXEC flag to anon_inode_get_fd call for IIO event interface. 5) Change iio_push_to_buffers to take a void * pointer so as to avoid some annoying and unnecessary type casts. 6) iio_compute_scan_bytes incorrectly took a long rather than unsigned long. 7) Various minor tidy ups. Driver cleanups (in no particular order) 1) Another set of devm_ allocations patches from Sachin Kamat. 2) tsl2x7x - 0 to NULL cleanup. 3) hmc5843 - fix missing > in MODULE_AUTHOR 4) Set of strict_strto* to kstrto* conversions. 5) mxs-lradc - fix ordering of resource removal to match creation 6) mxs-lradc - add MODULE_ALIAS 7) adc7606 - drop a work pending test duplicated in core functions. 8) hmc5843 - devm_ allocation patch 9) Series of redundant breaks removed. 10) ad2s1200 - pr_err -> dev_err 11) adjd_s311 - use INT_TIME 12) ST sensors - large set of cleanups from Lee Jones and removed restriction to using only triggers provided by the st_sensors themselves from Dennis Ciocca. 13) dummy and tmp006 provide sampling_frequency via info_mask_shared_by_all. 14) tcs3472 - fix incorrect buffer size and wrong device pointer used in suspend / resume functions. 15) max1363 - use defaults for buffer setup ops as provided by the triggered buffer helpers as they are the same as were specified in max1363 driver. 16) Trivial tidy ups in a number of other drivers.
This commit is contained in:
commit
3ffdea3fec
|
@ -811,3 +811,14 @@ Description:
|
||||||
Writing '1' stores the current device configuration into
|
Writing '1' stores the current device configuration into
|
||||||
on-chip EEPROM. After power-up or chip reset the device will
|
on-chip EEPROM. After power-up or chip reset the device will
|
||||||
automatically load the saved configuration.
|
automatically load the saved configuration.
|
||||||
|
|
||||||
|
What: /sys/.../iio:deviceX/in_intensity_red_integration_time
|
||||||
|
What: /sys/.../iio:deviceX/in_intensity_green_integration_time
|
||||||
|
What: /sys/.../iio:deviceX/in_intensity_blue_integration_time
|
||||||
|
What: /sys/.../iio:deviceX/in_intensity_clear_integration_time
|
||||||
|
What: /sys/.../iio:deviceX/in_illuminance_integration_time
|
||||||
|
KernelVersion: 3.12
|
||||||
|
Contact: linux-iio@vger.kernel.org
|
||||||
|
Description:
|
||||||
|
This attribute is used to get/set the integration time in
|
||||||
|
seconds.
|
||||||
|
|
21
Documentation/devicetree/bindings/iio/light/gp2ap020a00f.txt
Normal file
21
Documentation/devicetree/bindings/iio/light/gp2ap020a00f.txt
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
* Sharp GP2AP020A00F I2C Proximity/ALS sensor
|
||||||
|
|
||||||
|
The proximity detector sensor requires power supply
|
||||||
|
for its built-in led. It is also defined by this binding.
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
|
||||||
|
- compatible : should be "sharp,gp2ap020a00f"
|
||||||
|
- reg : the I2C slave address of the light sensor
|
||||||
|
- interrupts : interrupt specifier for the sole interrupt generated
|
||||||
|
by the device
|
||||||
|
- vled-supply : VLED power supply, as covered in ../regulator/regulator.txt
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
gp2ap020a00f@39 {
|
||||||
|
compatible = "sharp,gp2ap020a00f";
|
||||||
|
reg = <0x39>;
|
||||||
|
interrupts = <2 0>;
|
||||||
|
vled-supply = <...>;
|
||||||
|
};
|
|
@ -4195,7 +4195,7 @@ S: Maintained
|
||||||
F: drivers/media/rc/iguanair.c
|
F: drivers/media/rc/iguanair.c
|
||||||
|
|
||||||
IIO SUBSYSTEM AND DRIVERS
|
IIO SUBSYSTEM AND DRIVERS
|
||||||
M: Jonathan Cameron <jic23@cam.ac.uk>
|
M: Jonathan Cameron <jic23@kernel.org>
|
||||||
L: linux-iio@vger.kernel.org
|
L: linux-iio@vger.kernel.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
F: drivers/iio/
|
F: drivers/iio/
|
||||||
|
@ -7947,7 +7947,7 @@ S: Maintained
|
||||||
F: drivers/staging/media/go7007/
|
F: drivers/staging/media/go7007/
|
||||||
|
|
||||||
STAGING - INDUSTRIAL IO
|
STAGING - INDUSTRIAL IO
|
||||||
M: Jonathan Cameron <jic23@cam.ac.uk>
|
M: Jonathan Cameron <jic23@kernel.org>
|
||||||
L: linux-iio@vger.kernel.org
|
L: linux-iio@vger.kernel.org
|
||||||
S: Odd Fixes
|
S: Odd Fixes
|
||||||
F: drivers/staging/iio/
|
F: drivers/staging/iio/
|
||||||
|
|
|
@ -471,13 +471,10 @@ static irqreturn_t bma180_trigger_handler(int irq, void *p)
|
||||||
struct iio_poll_func *pf = p;
|
struct iio_poll_func *pf = p;
|
||||||
struct iio_dev *indio_dev = pf->indio_dev;
|
struct iio_dev *indio_dev = pf->indio_dev;
|
||||||
struct bma180_data *data = iio_priv(indio_dev);
|
struct bma180_data *data = iio_priv(indio_dev);
|
||||||
|
int64_t time_ns = iio_get_time_ns();
|
||||||
int bit, ret, i = 0;
|
int bit, ret, i = 0;
|
||||||
|
|
||||||
mutex_lock(&data->mutex);
|
mutex_lock(&data->mutex);
|
||||||
if (indio_dev->scan_timestamp) {
|
|
||||||
ret = indio_dev->scan_bytes / sizeof(s64) - 1;
|
|
||||||
((s64 *)data->buff)[ret] = iio_get_time_ns();
|
|
||||||
}
|
|
||||||
|
|
||||||
for_each_set_bit(bit, indio_dev->buffer->scan_mask,
|
for_each_set_bit(bit, indio_dev->buffer->scan_mask,
|
||||||
indio_dev->masklength) {
|
indio_dev->masklength) {
|
||||||
|
@ -490,7 +487,7 @@ static irqreturn_t bma180_trigger_handler(int irq, void *p)
|
||||||
}
|
}
|
||||||
mutex_unlock(&data->mutex);
|
mutex_unlock(&data->mutex);
|
||||||
|
|
||||||
iio_push_to_buffers(indio_dev, (u8 *)data->buff);
|
iio_push_to_buffers_with_timestamp(indio_dev, data->buff, time_ns);
|
||||||
err:
|
err:
|
||||||
iio_trigger_notify_done(indio_dev->trig);
|
iio_trigger_notify_done(indio_dev->trig);
|
||||||
|
|
||||||
|
|
|
@ -182,10 +182,11 @@ static const struct iio_info accel_3d_info = {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Function to push data to buffer */
|
/* Function to push data to buffer */
|
||||||
static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len)
|
static void hid_sensor_push_data(struct iio_dev *indio_dev, const void *data,
|
||||||
|
int len)
|
||||||
{
|
{
|
||||||
dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n");
|
dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n");
|
||||||
iio_push_to_buffers(indio_dev, (u8 *)data);
|
iio_push_to_buffers(indio_dev, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Callback handler to send event after all samples are received and captured */
|
/* Callback handler to send event after all samples are received and captured */
|
||||||
|
@ -200,7 +201,7 @@ static int accel_3d_proc_event(struct hid_sensor_hub_device *hsdev,
|
||||||
accel_state->common_attributes.data_ready);
|
accel_state->common_attributes.data_ready);
|
||||||
if (accel_state->common_attributes.data_ready)
|
if (accel_state->common_attributes.data_ready)
|
||||||
hid_sensor_push_data(indio_dev,
|
hid_sensor_push_data(indio_dev,
|
||||||
(u8 *)accel_state->accel_val,
|
accel_state->accel_val,
|
||||||
sizeof(accel_state->accel_val));
|
sizeof(accel_state->accel_val));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -452,8 +452,9 @@ static const struct iio_trigger_ops st_accel_trigger_ops = {
|
||||||
int st_accel_common_probe(struct iio_dev *indio_dev,
|
int st_accel_common_probe(struct iio_dev *indio_dev,
|
||||||
struct st_sensors_platform_data *plat_data)
|
struct st_sensors_platform_data *plat_data)
|
||||||
{
|
{
|
||||||
int err;
|
|
||||||
struct st_sensor_data *adata = iio_priv(indio_dev);
|
struct st_sensor_data *adata = iio_priv(indio_dev);
|
||||||
|
int irq = adata->get_irq_data_ready(indio_dev);
|
||||||
|
int err;
|
||||||
|
|
||||||
indio_dev->modes = INDIO_DIRECT_MODE;
|
indio_dev->modes = INDIO_DIRECT_MODE;
|
||||||
indio_dev->info = &accel_info;
|
indio_dev->info = &accel_info;
|
||||||
|
@ -461,7 +462,7 @@ int st_accel_common_probe(struct iio_dev *indio_dev,
|
||||||
err = st_sensors_check_device_support(indio_dev,
|
err = st_sensors_check_device_support(indio_dev,
|
||||||
ARRAY_SIZE(st_accel_sensors), st_accel_sensors);
|
ARRAY_SIZE(st_accel_sensors), st_accel_sensors);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto st_accel_common_probe_error;
|
return err;
|
||||||
|
|
||||||
adata->num_data_channels = ST_ACCEL_NUMBER_DATA_CHANNELS;
|
adata->num_data_channels = ST_ACCEL_NUMBER_DATA_CHANNELS;
|
||||||
adata->multiread_bit = adata->sensor->multi_read_bit;
|
adata->multiread_bit = adata->sensor->multi_read_bit;
|
||||||
|
@ -478,13 +479,13 @@ int st_accel_common_probe(struct iio_dev *indio_dev,
|
||||||
|
|
||||||
err = st_sensors_init_sensor(indio_dev, plat_data);
|
err = st_sensors_init_sensor(indio_dev, plat_data);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto st_accel_common_probe_error;
|
return err;
|
||||||
|
|
||||||
if (adata->get_irq_data_ready(indio_dev) > 0) {
|
err = st_accel_allocate_ring(indio_dev);
|
||||||
err = st_accel_allocate_ring(indio_dev);
|
if (err < 0)
|
||||||
if (err < 0)
|
return err;
|
||||||
goto st_accel_common_probe_error;
|
|
||||||
|
|
||||||
|
if (irq > 0) {
|
||||||
err = st_sensors_allocate_trigger(indio_dev,
|
err = st_sensors_allocate_trigger(indio_dev,
|
||||||
ST_ACCEL_TRIGGER_OPS);
|
ST_ACCEL_TRIGGER_OPS);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
|
@ -495,15 +496,14 @@ int st_accel_common_probe(struct iio_dev *indio_dev,
|
||||||
if (err)
|
if (err)
|
||||||
goto st_accel_device_register_error;
|
goto st_accel_device_register_error;
|
||||||
|
|
||||||
return err;
|
return 0;
|
||||||
|
|
||||||
st_accel_device_register_error:
|
st_accel_device_register_error:
|
||||||
if (adata->get_irq_data_ready(indio_dev) > 0)
|
if (irq > 0)
|
||||||
st_sensors_deallocate_trigger(indio_dev);
|
st_sensors_deallocate_trigger(indio_dev);
|
||||||
st_accel_probe_trigger_error:
|
st_accel_probe_trigger_error:
|
||||||
if (adata->get_irq_data_ready(indio_dev) > 0)
|
st_accel_deallocate_ring(indio_dev);
|
||||||
st_accel_deallocate_ring(indio_dev);
|
|
||||||
st_accel_common_probe_error:
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(st_accel_common_probe);
|
EXPORT_SYMBOL(st_accel_common_probe);
|
||||||
|
@ -513,10 +513,10 @@ void st_accel_common_remove(struct iio_dev *indio_dev)
|
||||||
struct st_sensor_data *adata = iio_priv(indio_dev);
|
struct st_sensor_data *adata = iio_priv(indio_dev);
|
||||||
|
|
||||||
iio_device_unregister(indio_dev);
|
iio_device_unregister(indio_dev);
|
||||||
if (adata->get_irq_data_ready(indio_dev) > 0) {
|
if (adata->get_irq_data_ready(indio_dev) > 0)
|
||||||
st_sensors_deallocate_trigger(indio_dev);
|
st_sensors_deallocate_trigger(indio_dev);
|
||||||
st_accel_deallocate_ring(indio_dev);
|
|
||||||
}
|
st_accel_deallocate_ring(indio_dev);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(st_accel_common_remove);
|
EXPORT_SYMBOL(st_accel_common_remove);
|
||||||
|
|
||||||
|
|
|
@ -145,6 +145,16 @@ config MCP320X
|
||||||
This driver can also be built as a module. If so, the module will be
|
This driver can also be built as a module. If so, the module will be
|
||||||
called mcp320x.
|
called mcp320x.
|
||||||
|
|
||||||
|
config MCP3422
|
||||||
|
tristate "Microchip Technology MCP3422/3/4 driver"
|
||||||
|
depends on I2C
|
||||||
|
help
|
||||||
|
Say yes here to build support for Microchip Technology's MCP3422,
|
||||||
|
MCP3423 or MCP3424 analog to digital converters.
|
||||||
|
|
||||||
|
This driver can also be built as a module. If so, the module will be
|
||||||
|
called mcp3422.
|
||||||
|
|
||||||
config NAU7802
|
config NAU7802
|
||||||
tristate "Nuvoton NAU7802 ADC driver"
|
tristate "Nuvoton NAU7802 ADC driver"
|
||||||
depends on I2C
|
depends on I2C
|
||||||
|
@ -167,6 +177,7 @@ config TI_ADC081C
|
||||||
config TI_AM335X_ADC
|
config TI_AM335X_ADC
|
||||||
tristate "TI's AM335X ADC driver"
|
tristate "TI's AM335X ADC driver"
|
||||||
depends on MFD_TI_AM335X_TSCADC
|
depends on MFD_TI_AM335X_TSCADC
|
||||||
|
select IIO_KFIFO_BUF
|
||||||
help
|
help
|
||||||
Say yes here to build support for Texas Instruments ADC
|
Say yes here to build support for Texas Instruments ADC
|
||||||
driver which is also a MFD client.
|
driver which is also a MFD client.
|
||||||
|
|
|
@ -16,6 +16,7 @@ obj-$(CONFIG_EXYNOS_ADC) += exynos_adc.o
|
||||||
obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
|
obj-$(CONFIG_LP8788_ADC) += lp8788_adc.o
|
||||||
obj-$(CONFIG_MAX1363) += max1363.o
|
obj-$(CONFIG_MAX1363) += max1363.o
|
||||||
obj-$(CONFIG_MCP320X) += mcp320x.o
|
obj-$(CONFIG_MCP320X) += mcp320x.o
|
||||||
|
obj-$(CONFIG_MCP3422) += mcp3422.o
|
||||||
obj-$(CONFIG_NAU7802) += nau7802.o
|
obj-$(CONFIG_NAU7802) += nau7802.o
|
||||||
obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
|
obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
|
||||||
obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o
|
obj-$(CONFIG_TI_AM335X_ADC) += ti_am335x_adc.o
|
||||||
|
|
|
@ -96,9 +96,8 @@ static irqreturn_t ad7266_trigger_handler(int irq, void *p)
|
||||||
|
|
||||||
ret = spi_read(st->spi, st->data, 4);
|
ret = spi_read(st->spi, st->data, 4);
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
if (indio_dev->scan_timestamp)
|
iio_push_to_buffers_with_timestamp(indio_dev, st->data,
|
||||||
((s64 *)st->data)[1] = pf->timestamp;
|
pf->timestamp);
|
||||||
iio_push_to_buffers(indio_dev, (u8 *)st->data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
iio_trigger_notify_done(indio_dev->trig);
|
iio_trigger_notify_done(indio_dev->trig);
|
||||||
|
@ -293,7 +292,7 @@ static const struct iio_info ad7266_info = {
|
||||||
.driver_module = THIS_MODULE,
|
.driver_module = THIS_MODULE,
|
||||||
};
|
};
|
||||||
|
|
||||||
static unsigned long ad7266_available_scan_masks[] = {
|
static const unsigned long ad7266_available_scan_masks[] = {
|
||||||
0x003,
|
0x003,
|
||||||
0x00c,
|
0x00c,
|
||||||
0x030,
|
0x030,
|
||||||
|
@ -303,14 +302,14 @@ static unsigned long ad7266_available_scan_masks[] = {
|
||||||
0x000,
|
0x000,
|
||||||
};
|
};
|
||||||
|
|
||||||
static unsigned long ad7266_available_scan_masks_diff[] = {
|
static const unsigned long ad7266_available_scan_masks_diff[] = {
|
||||||
0x003,
|
0x003,
|
||||||
0x00c,
|
0x00c,
|
||||||
0x030,
|
0x030,
|
||||||
0x000,
|
0x000,
|
||||||
};
|
};
|
||||||
|
|
||||||
static unsigned long ad7266_available_scan_masks_fixed[] = {
|
static const unsigned long ad7266_available_scan_masks_fixed[] = {
|
||||||
0x003,
|
0x003,
|
||||||
0x000,
|
0x000,
|
||||||
};
|
};
|
||||||
|
@ -318,7 +317,7 @@ static unsigned long ad7266_available_scan_masks_fixed[] = {
|
||||||
struct ad7266_chan_info {
|
struct ad7266_chan_info {
|
||||||
const struct iio_chan_spec *channels;
|
const struct iio_chan_spec *channels;
|
||||||
unsigned int num_channels;
|
unsigned int num_channels;
|
||||||
unsigned long *scan_masks;
|
const unsigned long *scan_masks;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define AD7266_CHAN_INFO_INDEX(_differential, _signed, _fixed) \
|
#define AD7266_CHAN_INFO_INDEX(_differential, _signed, _fixed) \
|
||||||
|
|
|
@ -159,20 +159,14 @@ static irqreturn_t ad7298_trigger_handler(int irq, void *p)
|
||||||
struct iio_poll_func *pf = p;
|
struct iio_poll_func *pf = p;
|
||||||
struct iio_dev *indio_dev = pf->indio_dev;
|
struct iio_dev *indio_dev = pf->indio_dev;
|
||||||
struct ad7298_state *st = iio_priv(indio_dev);
|
struct ad7298_state *st = iio_priv(indio_dev);
|
||||||
s64 time_ns = 0;
|
|
||||||
int b_sent;
|
int b_sent;
|
||||||
|
|
||||||
b_sent = spi_sync(st->spi, &st->ring_msg);
|
b_sent = spi_sync(st->spi, &st->ring_msg);
|
||||||
if (b_sent)
|
if (b_sent)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
if (indio_dev->scan_timestamp) {
|
iio_push_to_buffers_with_timestamp(indio_dev, st->rx_buf,
|
||||||
time_ns = iio_get_time_ns();
|
iio_get_time_ns());
|
||||||
memcpy((u8 *)st->rx_buf + indio_dev->scan_bytes - sizeof(s64),
|
|
||||||
&time_ns, sizeof(time_ns));
|
|
||||||
}
|
|
||||||
|
|
||||||
iio_push_to_buffers(indio_dev, (u8 *)st->rx_buf);
|
|
||||||
|
|
||||||
done:
|
done:
|
||||||
iio_trigger_notify_done(indio_dev->trig);
|
iio_trigger_notify_done(indio_dev->trig);
|
||||||
|
|
|
@ -64,19 +64,14 @@ static irqreturn_t ad7476_trigger_handler(int irq, void *p)
|
||||||
struct iio_poll_func *pf = p;
|
struct iio_poll_func *pf = p;
|
||||||
struct iio_dev *indio_dev = pf->indio_dev;
|
struct iio_dev *indio_dev = pf->indio_dev;
|
||||||
struct ad7476_state *st = iio_priv(indio_dev);
|
struct ad7476_state *st = iio_priv(indio_dev);
|
||||||
s64 time_ns;
|
|
||||||
int b_sent;
|
int b_sent;
|
||||||
|
|
||||||
b_sent = spi_sync(st->spi, &st->msg);
|
b_sent = spi_sync(st->spi, &st->msg);
|
||||||
if (b_sent < 0)
|
if (b_sent < 0)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
time_ns = iio_get_time_ns();
|
iio_push_to_buffers_with_timestamp(indio_dev, st->data,
|
||||||
|
iio_get_time_ns());
|
||||||
if (indio_dev->scan_timestamp)
|
|
||||||
((s64 *)st->data)[1] = time_ns;
|
|
||||||
|
|
||||||
iio_push_to_buffers(indio_dev, st->data);
|
|
||||||
done:
|
done:
|
||||||
iio_trigger_notify_done(indio_dev->trig);
|
iio_trigger_notify_done(indio_dev->trig);
|
||||||
|
|
||||||
|
|
|
@ -121,20 +121,14 @@ static irqreturn_t ad7887_trigger_handler(int irq, void *p)
|
||||||
struct iio_poll_func *pf = p;
|
struct iio_poll_func *pf = p;
|
||||||
struct iio_dev *indio_dev = pf->indio_dev;
|
struct iio_dev *indio_dev = pf->indio_dev;
|
||||||
struct ad7887_state *st = iio_priv(indio_dev);
|
struct ad7887_state *st = iio_priv(indio_dev);
|
||||||
s64 time_ns;
|
|
||||||
int b_sent;
|
int b_sent;
|
||||||
|
|
||||||
b_sent = spi_sync(st->spi, st->ring_msg);
|
b_sent = spi_sync(st->spi, st->ring_msg);
|
||||||
if (b_sent)
|
if (b_sent)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
time_ns = iio_get_time_ns();
|
iio_push_to_buffers_with_timestamp(indio_dev, st->data,
|
||||||
|
iio_get_time_ns());
|
||||||
if (indio_dev->scan_timestamp)
|
|
||||||
memcpy(st->data + indio_dev->scan_bytes - sizeof(s64),
|
|
||||||
&time_ns, sizeof(time_ns));
|
|
||||||
|
|
||||||
iio_push_to_buffers(indio_dev, st->data);
|
|
||||||
done:
|
done:
|
||||||
iio_trigger_notify_done(indio_dev->trig);
|
iio_trigger_notify_done(indio_dev->trig);
|
||||||
|
|
||||||
|
|
|
@ -174,20 +174,14 @@ static irqreturn_t ad7923_trigger_handler(int irq, void *p)
|
||||||
struct iio_poll_func *pf = p;
|
struct iio_poll_func *pf = p;
|
||||||
struct iio_dev *indio_dev = pf->indio_dev;
|
struct iio_dev *indio_dev = pf->indio_dev;
|
||||||
struct ad7923_state *st = iio_priv(indio_dev);
|
struct ad7923_state *st = iio_priv(indio_dev);
|
||||||
s64 time_ns = 0;
|
|
||||||
int b_sent;
|
int b_sent;
|
||||||
|
|
||||||
b_sent = spi_sync(st->spi, &st->ring_msg);
|
b_sent = spi_sync(st->spi, &st->ring_msg);
|
||||||
if (b_sent)
|
if (b_sent)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
if (indio_dev->scan_timestamp) {
|
iio_push_to_buffers_with_timestamp(indio_dev, st->rx_buf,
|
||||||
time_ns = iio_get_time_ns();
|
iio_get_time_ns());
|
||||||
memcpy((u8 *)st->rx_buf + indio_dev->scan_bytes - sizeof(s64),
|
|
||||||
&time_ns, sizeof(time_ns));
|
|
||||||
}
|
|
||||||
|
|
||||||
iio_push_to_buffers(indio_dev, (u8 *)st->rx_buf);
|
|
||||||
|
|
||||||
done:
|
done:
|
||||||
iio_trigger_notify_done(indio_dev->trig);
|
iio_trigger_notify_done(indio_dev->trig);
|
||||||
|
|
|
@ -368,10 +368,6 @@ static irqreturn_t ad_sd_trigger_handler(int irq, void *p)
|
||||||
|
|
||||||
memset(data, 0x00, 16);
|
memset(data, 0x00, 16);
|
||||||
|
|
||||||
/* Guaranteed to be aligned with 8 byte boundary */
|
|
||||||
if (indio_dev->scan_timestamp)
|
|
||||||
((s64 *)data)[1] = pf->timestamp;
|
|
||||||
|
|
||||||
reg_size = indio_dev->channels[0].scan_type.realbits +
|
reg_size = indio_dev->channels[0].scan_type.realbits +
|
||||||
indio_dev->channels[0].scan_type.shift;
|
indio_dev->channels[0].scan_type.shift;
|
||||||
reg_size = DIV_ROUND_UP(reg_size, 8);
|
reg_size = DIV_ROUND_UP(reg_size, 8);
|
||||||
|
@ -391,7 +387,7 @@ static irqreturn_t ad_sd_trigger_handler(int irq, void *p)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
iio_push_to_buffers(indio_dev, (uint8_t *)data);
|
iio_push_to_buffers_with_timestamp(indio_dev, data, pf->timestamp);
|
||||||
|
|
||||||
iio_trigger_notify_done(indio_dev->trig);
|
iio_trigger_notify_done(indio_dev->trig);
|
||||||
sigma_delta->irq_dis = false;
|
sigma_delta->irq_dis = false;
|
||||||
|
|
|
@ -83,13 +83,7 @@ static irqreturn_t at91_adc_trigger_handler(int irq, void *p)
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (idev->scan_timestamp) {
|
iio_push_to_buffers_with_timestamp(idev, st->buffer, pf->timestamp);
|
||||||
s64 *timestamp = (s64 *)((u8 *)st->buffer +
|
|
||||||
ALIGN(j, sizeof(s64)));
|
|
||||||
*timestamp = pf->timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
iio_push_to_buffers(idev, (u8 *)st->buffer);
|
|
||||||
|
|
||||||
iio_trigger_notify_done(idev->trig);
|
iio_trigger_notify_done(idev->trig);
|
||||||
|
|
||||||
|
@ -279,7 +273,7 @@ static int at91_adc_trigger_init(struct iio_dev *idev)
|
||||||
int i, ret;
|
int i, ret;
|
||||||
|
|
||||||
st->trig = devm_kzalloc(&idev->dev,
|
st->trig = devm_kzalloc(&idev->dev,
|
||||||
st->trigger_number * sizeof(st->trig),
|
st->trigger_number * sizeof(*st->trig),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
|
|
||||||
if (st->trig == NULL) {
|
if (st->trig == NULL) {
|
||||||
|
|
|
@ -1436,7 +1436,6 @@ static irqreturn_t max1363_trigger_handler(int irq, void *p)
|
||||||
struct iio_poll_func *pf = p;
|
struct iio_poll_func *pf = p;
|
||||||
struct iio_dev *indio_dev = pf->indio_dev;
|
struct iio_dev *indio_dev = pf->indio_dev;
|
||||||
struct max1363_state *st = iio_priv(indio_dev);
|
struct max1363_state *st = iio_priv(indio_dev);
|
||||||
s64 time_ns;
|
|
||||||
__u8 *rxbuf;
|
__u8 *rxbuf;
|
||||||
int b_sent;
|
int b_sent;
|
||||||
size_t d_size;
|
size_t d_size;
|
||||||
|
@ -1470,11 +1469,7 @@ static irqreturn_t max1363_trigger_handler(int irq, void *p)
|
||||||
if (b_sent < 0)
|
if (b_sent < 0)
|
||||||
goto done_free;
|
goto done_free;
|
||||||
|
|
||||||
time_ns = iio_get_time_ns();
|
iio_push_to_buffers_with_timestamp(indio_dev, rxbuf, iio_get_time_ns());
|
||||||
|
|
||||||
if (indio_dev->scan_timestamp)
|
|
||||||
memcpy(rxbuf + d_size - sizeof(s64), &time_ns, sizeof(time_ns));
|
|
||||||
iio_push_to_buffers(indio_dev, rxbuf);
|
|
||||||
|
|
||||||
done_free:
|
done_free:
|
||||||
kfree(rxbuf);
|
kfree(rxbuf);
|
||||||
|
@ -1484,12 +1479,6 @@ done:
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct iio_buffer_setup_ops max1363_buffered_setup_ops = {
|
|
||||||
.postenable = &iio_triggered_buffer_postenable,
|
|
||||||
.preenable = &iio_sw_buffer_preenable,
|
|
||||||
.predisable = &iio_triggered_buffer_predisable,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int max1363_probe(struct i2c_client *client,
|
static int max1363_probe(struct i2c_client *client,
|
||||||
const struct i2c_device_id *id)
|
const struct i2c_device_id *id)
|
||||||
{
|
{
|
||||||
|
@ -1559,7 +1548,7 @@ static int max1363_probe(struct i2c_client *client,
|
||||||
goto error_disable_reg;
|
goto error_disable_reg;
|
||||||
|
|
||||||
ret = iio_triggered_buffer_setup(indio_dev, NULL,
|
ret = iio_triggered_buffer_setup(indio_dev, NULL,
|
||||||
&max1363_trigger_handler, &max1363_buffered_setup_ops);
|
&max1363_trigger_handler, NULL);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_disable_reg;
|
goto error_disable_reg;
|
||||||
|
|
||||||
|
|
409
drivers/iio/adc/mcp3422.c
Normal file
409
drivers/iio/adc/mcp3422.c
Normal file
|
@ -0,0 +1,409 @@
|
||||||
|
/*
|
||||||
|
* mcp3422.c - driver for the Microchip mcp3422/3/4 chip family
|
||||||
|
*
|
||||||
|
* Copyright (C) 2013, Angelo Compagnucci
|
||||||
|
* Author: Angelo Compagnucci <angelo.compagnucci@gmail.com>
|
||||||
|
*
|
||||||
|
* Datasheet: http://ww1.microchip.com/downloads/en/devicedoc/22088b.pdf
|
||||||
|
*
|
||||||
|
* This driver exports the value of analog input voltage to sysfs, the
|
||||||
|
* voltage unit is nV.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/err.h>
|
||||||
|
#include <linux/i2c.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
|
#include <linux/sysfs.h>
|
||||||
|
|
||||||
|
#include <linux/iio/iio.h>
|
||||||
|
#include <linux/iio/sysfs.h>
|
||||||
|
|
||||||
|
/* Masks */
|
||||||
|
#define MCP3422_CHANNEL_MASK 0x60
|
||||||
|
#define MCP3422_PGA_MASK 0x03
|
||||||
|
#define MCP3422_SRATE_MASK 0x0C
|
||||||
|
#define MCP3422_SRATE_240 0x0
|
||||||
|
#define MCP3422_SRATE_60 0x1
|
||||||
|
#define MCP3422_SRATE_15 0x2
|
||||||
|
#define MCP3422_SRATE_3 0x3
|
||||||
|
#define MCP3422_PGA_1 0
|
||||||
|
#define MCP3422_PGA_2 1
|
||||||
|
#define MCP3422_PGA_4 2
|
||||||
|
#define MCP3422_PGA_8 3
|
||||||
|
#define MCP3422_CONT_SAMPLING 0x10
|
||||||
|
|
||||||
|
#define MCP3422_CHANNEL(config) (((config) & MCP3422_CHANNEL_MASK) >> 5)
|
||||||
|
#define MCP3422_PGA(config) ((config) & MCP3422_PGA_MASK)
|
||||||
|
#define MCP3422_SAMPLE_RATE(config) (((config) & MCP3422_SRATE_MASK) >> 2)
|
||||||
|
|
||||||
|
#define MCP3422_CHANNEL_VALUE(value) (((value) << 5) & MCP3422_CHANNEL_MASK)
|
||||||
|
#define MCP3422_PGA_VALUE(value) ((value) & MCP3422_PGA_MASK)
|
||||||
|
#define MCP3422_SAMPLE_RATE_VALUE(value) ((value << 2) & MCP3422_SRATE_MASK)
|
||||||
|
|
||||||
|
#define MCP3422_CHAN(_index) \
|
||||||
|
{ \
|
||||||
|
.type = IIO_VOLTAGE, \
|
||||||
|
.indexed = 1, \
|
||||||
|
.channel = _index, \
|
||||||
|
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) \
|
||||||
|
| BIT(IIO_CHAN_INFO_SCALE), \
|
||||||
|
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
|
||||||
|
}
|
||||||
|
|
||||||
|
/* LSB is in nV to eliminate floating point */
|
||||||
|
static const u32 rates_to_lsb[] = {1000000, 250000, 62500, 15625};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* scales calculated as:
|
||||||
|
* rates_to_lsb[sample_rate] / (1 << pga);
|
||||||
|
* pga is 1 for 0, 2
|
||||||
|
*/
|
||||||
|
|
||||||
|
static const int mcp3422_scales[4][4] = {
|
||||||
|
{ 1000000, 250000, 62500, 15625 },
|
||||||
|
{ 500000 , 125000, 31250, 7812 },
|
||||||
|
{ 250000 , 62500 , 15625, 3906 },
|
||||||
|
{ 125000 , 31250 , 7812 , 1953 } };
|
||||||
|
|
||||||
|
/* Constant msleep times for data acquisitions */
|
||||||
|
static const int mcp3422_read_times[4] = {
|
||||||
|
[MCP3422_SRATE_240] = 1000 / 240,
|
||||||
|
[MCP3422_SRATE_60] = 1000 / 60,
|
||||||
|
[MCP3422_SRATE_15] = 1000 / 15,
|
||||||
|
[MCP3422_SRATE_3] = 1000 / 3 };
|
||||||
|
|
||||||
|
/* sample rates to integer conversion table */
|
||||||
|
static const int mcp3422_sample_rates[4] = {
|
||||||
|
[MCP3422_SRATE_240] = 240,
|
||||||
|
[MCP3422_SRATE_60] = 60,
|
||||||
|
[MCP3422_SRATE_15] = 15,
|
||||||
|
[MCP3422_SRATE_3] = 3 };
|
||||||
|
|
||||||
|
/* sample rates to sign extension table */
|
||||||
|
static const int mcp3422_sign_extend[4] = {
|
||||||
|
[MCP3422_SRATE_240] = 12,
|
||||||
|
[MCP3422_SRATE_60] = 14,
|
||||||
|
[MCP3422_SRATE_15] = 16,
|
||||||
|
[MCP3422_SRATE_3] = 18 };
|
||||||
|
|
||||||
|
/* Client data (each client gets its own) */
|
||||||
|
struct mcp3422 {
|
||||||
|
struct i2c_client *i2c;
|
||||||
|
u8 config;
|
||||||
|
u8 pga[4];
|
||||||
|
struct mutex lock;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int mcp3422_update_config(struct mcp3422 *adc, u8 newconfig)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
mutex_lock(&adc->lock);
|
||||||
|
|
||||||
|
ret = i2c_master_send(adc->i2c, &newconfig, 1);
|
||||||
|
if (ret > 0) {
|
||||||
|
adc->config = newconfig;
|
||||||
|
ret = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
mutex_unlock(&adc->lock);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mcp3422_read(struct mcp3422 *adc, int *value, u8 *config)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
u8 sample_rate = MCP3422_SAMPLE_RATE(adc->config);
|
||||||
|
u8 buf[4] = {0, 0, 0, 0};
|
||||||
|
u32 temp;
|
||||||
|
|
||||||
|
if (sample_rate == MCP3422_SRATE_3) {
|
||||||
|
ret = i2c_master_recv(adc->i2c, buf, 4);
|
||||||
|
temp = buf[0] << 16 | buf[1] << 8 | buf[2];
|
||||||
|
*config = buf[3];
|
||||||
|
} else {
|
||||||
|
ret = i2c_master_recv(adc->i2c, buf, 3);
|
||||||
|
temp = buf[0] << 8 | buf[1];
|
||||||
|
*config = buf[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
*value = sign_extend32(temp, mcp3422_sign_extend[sample_rate]);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mcp3422_read_channel(struct mcp3422 *adc,
|
||||||
|
struct iio_chan_spec const *channel, int *value)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
u8 config;
|
||||||
|
u8 req_channel = channel->channel;
|
||||||
|
|
||||||
|
if (req_channel != MCP3422_CHANNEL(adc->config)) {
|
||||||
|
config = adc->config;
|
||||||
|
config &= ~MCP3422_CHANNEL_MASK;
|
||||||
|
config |= MCP3422_CHANNEL_VALUE(req_channel);
|
||||||
|
config &= ~MCP3422_PGA_MASK;
|
||||||
|
config |= MCP3422_PGA_VALUE(adc->pga[req_channel]);
|
||||||
|
ret = mcp3422_update_config(adc, config);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
msleep(mcp3422_read_times[MCP3422_SAMPLE_RATE(adc->config)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return mcp3422_read(adc, value, &config);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mcp3422_read_raw(struct iio_dev *iio,
|
||||||
|
struct iio_chan_spec const *channel, int *val1,
|
||||||
|
int *val2, long mask)
|
||||||
|
{
|
||||||
|
struct mcp3422 *adc = iio_priv(iio);
|
||||||
|
int err;
|
||||||
|
|
||||||
|
u8 sample_rate = MCP3422_SAMPLE_RATE(adc->config);
|
||||||
|
u8 pga = MCP3422_PGA(adc->config);
|
||||||
|
|
||||||
|
switch (mask) {
|
||||||
|
case IIO_CHAN_INFO_RAW:
|
||||||
|
err = mcp3422_read_channel(adc, channel, val1);
|
||||||
|
if (err < 0)
|
||||||
|
return -EINVAL;
|
||||||
|
return IIO_VAL_INT;
|
||||||
|
|
||||||
|
case IIO_CHAN_INFO_SCALE:
|
||||||
|
|
||||||
|
*val1 = 0;
|
||||||
|
*val2 = mcp3422_scales[sample_rate][pga];
|
||||||
|
return IIO_VAL_INT_PLUS_NANO;
|
||||||
|
|
||||||
|
case IIO_CHAN_INFO_SAMP_FREQ:
|
||||||
|
*val1 = mcp3422_sample_rates[MCP3422_SAMPLE_RATE(adc->config)];
|
||||||
|
return IIO_VAL_INT;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mcp3422_write_raw(struct iio_dev *iio,
|
||||||
|
struct iio_chan_spec const *channel, int val1,
|
||||||
|
int val2, long mask)
|
||||||
|
{
|
||||||
|
struct mcp3422 *adc = iio_priv(iio);
|
||||||
|
u8 temp;
|
||||||
|
u8 config = adc->config;
|
||||||
|
u8 req_channel = channel->channel;
|
||||||
|
u8 sample_rate = MCP3422_SAMPLE_RATE(config);
|
||||||
|
u8 i;
|
||||||
|
|
||||||
|
switch (mask) {
|
||||||
|
case IIO_CHAN_INFO_SCALE:
|
||||||
|
if (val1 != 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(mcp3422_scales[0]); i++) {
|
||||||
|
if (val2 == mcp3422_scales[sample_rate][i]) {
|
||||||
|
adc->pga[req_channel] = i;
|
||||||
|
|
||||||
|
config &= ~MCP3422_CHANNEL_MASK;
|
||||||
|
config |= MCP3422_CHANNEL_VALUE(req_channel);
|
||||||
|
config &= ~MCP3422_PGA_MASK;
|
||||||
|
config |= MCP3422_PGA_VALUE(adc->pga[req_channel]);
|
||||||
|
|
||||||
|
return mcp3422_update_config(adc, config);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
case IIO_CHAN_INFO_SAMP_FREQ:
|
||||||
|
switch (val1) {
|
||||||
|
case 240:
|
||||||
|
temp = MCP3422_SRATE_240;
|
||||||
|
break;
|
||||||
|
case 60:
|
||||||
|
temp = MCP3422_SRATE_60;
|
||||||
|
break;
|
||||||
|
case 15:
|
||||||
|
temp = MCP3422_SRATE_15;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
temp = MCP3422_SRATE_3;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
config &= ~MCP3422_CHANNEL_MASK;
|
||||||
|
config |= MCP3422_CHANNEL_VALUE(req_channel);
|
||||||
|
config &= ~MCP3422_SRATE_MASK;
|
||||||
|
config |= MCP3422_SAMPLE_RATE_VALUE(temp);
|
||||||
|
|
||||||
|
return mcp3422_update_config(adc, config);
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mcp3422_write_raw_get_fmt(struct iio_dev *indio_dev,
|
||||||
|
struct iio_chan_spec const *chan, long mask)
|
||||||
|
{
|
||||||
|
switch (mask) {
|
||||||
|
case IIO_CHAN_INFO_SCALE:
|
||||||
|
return IIO_VAL_INT_PLUS_NANO;
|
||||||
|
case IIO_CHAN_INFO_SAMP_FREQ:
|
||||||
|
return IIO_VAL_INT_PLUS_MICRO;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t mcp3422_show_scales(struct device *dev,
|
||||||
|
struct device_attribute *attr, char *buf)
|
||||||
|
{
|
||||||
|
struct mcp3422 *adc = iio_priv(dev_to_iio_dev(dev));
|
||||||
|
u8 sample_rate = MCP3422_SAMPLE_RATE(adc->config);
|
||||||
|
|
||||||
|
return sprintf(buf, "0.%09u 0.%09u 0.%09u 0.%09u\n",
|
||||||
|
mcp3422_scales[sample_rate][0],
|
||||||
|
mcp3422_scales[sample_rate][1],
|
||||||
|
mcp3422_scales[sample_rate][2],
|
||||||
|
mcp3422_scales[sample_rate][3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static IIO_CONST_ATTR_SAMP_FREQ_AVAIL("240 60 15 3");
|
||||||
|
static IIO_DEVICE_ATTR(in_voltage_scale_available, S_IRUGO,
|
||||||
|
mcp3422_show_scales, NULL, 0);
|
||||||
|
|
||||||
|
static struct attribute *mcp3422_attributes[] = {
|
||||||
|
&iio_const_attr_sampling_frequency_available.dev_attr.attr,
|
||||||
|
&iio_dev_attr_in_voltage_scale_available.dev_attr.attr,
|
||||||
|
NULL,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct attribute_group mcp3422_attribute_group = {
|
||||||
|
.attrs = mcp3422_attributes,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct iio_chan_spec mcp3422_channels[] = {
|
||||||
|
MCP3422_CHAN(0),
|
||||||
|
MCP3422_CHAN(1),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct iio_chan_spec mcp3424_channels[] = {
|
||||||
|
MCP3422_CHAN(0),
|
||||||
|
MCP3422_CHAN(1),
|
||||||
|
MCP3422_CHAN(2),
|
||||||
|
MCP3422_CHAN(3),
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct iio_info mcp3422_info = {
|
||||||
|
.read_raw = mcp3422_read_raw,
|
||||||
|
.write_raw = mcp3422_write_raw,
|
||||||
|
.write_raw_get_fmt = mcp3422_write_raw_get_fmt,
|
||||||
|
.attrs = &mcp3422_attribute_group,
|
||||||
|
.driver_module = THIS_MODULE,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int mcp3422_probe(struct i2c_client *client,
|
||||||
|
const struct i2c_device_id *id)
|
||||||
|
{
|
||||||
|
struct iio_dev *indio_dev;
|
||||||
|
struct mcp3422 *adc;
|
||||||
|
int err;
|
||||||
|
u8 config;
|
||||||
|
|
||||||
|
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*adc));
|
||||||
|
if (!indio_dev)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
adc = iio_priv(indio_dev);
|
||||||
|
adc->i2c = client;
|
||||||
|
|
||||||
|
mutex_init(&adc->lock);
|
||||||
|
|
||||||
|
indio_dev->dev.parent = &client->dev;
|
||||||
|
indio_dev->name = dev_name(&client->dev);
|
||||||
|
indio_dev->modes = INDIO_DIRECT_MODE;
|
||||||
|
indio_dev->info = &mcp3422_info;
|
||||||
|
|
||||||
|
switch ((unsigned int)(id->driver_data)) {
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
indio_dev->channels = mcp3422_channels;
|
||||||
|
indio_dev->num_channels = ARRAY_SIZE(mcp3422_channels);
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
indio_dev->channels = mcp3424_channels;
|
||||||
|
indio_dev->num_channels = ARRAY_SIZE(mcp3424_channels);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* meaningful default configuration */
|
||||||
|
config = (MCP3422_CONT_SAMPLING
|
||||||
|
| MCP3422_CHANNEL_VALUE(1)
|
||||||
|
| MCP3422_PGA_VALUE(MCP3422_PGA_1)
|
||||||
|
| MCP3422_SAMPLE_RATE_VALUE(MCP3422_SRATE_240));
|
||||||
|
mcp3422_update_config(adc, config);
|
||||||
|
|
||||||
|
err = iio_device_register(indio_dev);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
i2c_set_clientdata(client, indio_dev);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mcp3422_remove(struct i2c_client *client)
|
||||||
|
{
|
||||||
|
iio_device_unregister(i2c_get_clientdata(client));
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct i2c_device_id mcp3422_id[] = {
|
||||||
|
{ "mcp3422", 2 },
|
||||||
|
{ "mcp3423", 3 },
|
||||||
|
{ "mcp3424", 4 },
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(i2c, mcp3422_id);
|
||||||
|
|
||||||
|
#ifdef CONFIG_OF
|
||||||
|
static const struct of_device_id mcp3422_of_match[] = {
|
||||||
|
{ .compatible = "mcp3422" },
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(of, mcp3422_of_match);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static struct i2c_driver mcp3422_driver = {
|
||||||
|
.driver = {
|
||||||
|
.name = "mcp3422",
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
.of_match_table = of_match_ptr(mcp3422_of_match),
|
||||||
|
},
|
||||||
|
.probe = mcp3422_probe,
|
||||||
|
.remove = mcp3422_remove,
|
||||||
|
.id_table = mcp3422_id,
|
||||||
|
};
|
||||||
|
module_i2c_driver(mcp3422_driver);
|
||||||
|
|
||||||
|
MODULE_AUTHOR("Angelo Compagnucci <angelo.compagnucci@gmail.com>");
|
||||||
|
MODULE_DESCRIPTION("Microchip mcp3422/3/4 driver");
|
||||||
|
MODULE_LICENSE("GPL v2");
|
|
@ -28,12 +28,16 @@
|
||||||
#include <linux/iio/driver.h>
|
#include <linux/iio/driver.h>
|
||||||
|
|
||||||
#include <linux/mfd/ti_am335x_tscadc.h>
|
#include <linux/mfd/ti_am335x_tscadc.h>
|
||||||
|
#include <linux/iio/buffer.h>
|
||||||
|
#include <linux/iio/kfifo_buf.h>
|
||||||
|
|
||||||
struct tiadc_device {
|
struct tiadc_device {
|
||||||
struct ti_tscadc_dev *mfd_tscadc;
|
struct ti_tscadc_dev *mfd_tscadc;
|
||||||
int channels;
|
int channels;
|
||||||
u8 channel_line[8];
|
u8 channel_line[8];
|
||||||
u8 channel_step[8];
|
u8 channel_step[8];
|
||||||
|
int buffer_en_ch_steps;
|
||||||
|
u16 data[8];
|
||||||
};
|
};
|
||||||
|
|
||||||
static unsigned int tiadc_readl(struct tiadc_device *adc, unsigned int reg)
|
static unsigned int tiadc_readl(struct tiadc_device *adc, unsigned int reg)
|
||||||
|
@ -56,8 +60,14 @@ static u32 get_adc_step_mask(struct tiadc_device *adc_dev)
|
||||||
return step_en;
|
return step_en;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tiadc_step_config(struct tiadc_device *adc_dev)
|
static u32 get_adc_step_bit(struct tiadc_device *adc_dev, int chan)
|
||||||
{
|
{
|
||||||
|
return 1 << adc_dev->channel_step[chan];
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tiadc_step_config(struct iio_dev *indio_dev)
|
||||||
|
{
|
||||||
|
struct tiadc_device *adc_dev = iio_priv(indio_dev);
|
||||||
unsigned int stepconfig;
|
unsigned int stepconfig;
|
||||||
int i, steps;
|
int i, steps;
|
||||||
|
|
||||||
|
@ -72,7 +82,11 @@ static void tiadc_step_config(struct tiadc_device *adc_dev)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
steps = TOTAL_STEPS - adc_dev->channels;
|
steps = TOTAL_STEPS - adc_dev->channels;
|
||||||
stepconfig = STEPCONFIG_AVG_16 | STEPCONFIG_FIFO1;
|
if (iio_buffer_enabled(indio_dev))
|
||||||
|
stepconfig = STEPCONFIG_AVG_16 | STEPCONFIG_FIFO1
|
||||||
|
| STEPCONFIG_MODE_SWCNT;
|
||||||
|
else
|
||||||
|
stepconfig = STEPCONFIG_AVG_16 | STEPCONFIG_FIFO1;
|
||||||
|
|
||||||
for (i = 0; i < adc_dev->channels; i++) {
|
for (i = 0; i < adc_dev->channels; i++) {
|
||||||
int chan;
|
int chan;
|
||||||
|
@ -85,9 +99,175 @@ static void tiadc_step_config(struct tiadc_device *adc_dev)
|
||||||
adc_dev->channel_step[i] = steps;
|
adc_dev->channel_step[i] = steps;
|
||||||
steps++;
|
steps++;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static irqreturn_t tiadc_irq_h(int irq, void *private)
|
||||||
|
{
|
||||||
|
struct iio_dev *indio_dev = private;
|
||||||
|
struct tiadc_device *adc_dev = iio_priv(indio_dev);
|
||||||
|
unsigned int status, config;
|
||||||
|
status = tiadc_readl(adc_dev, REG_IRQSTATUS);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ADC and touchscreen share the IRQ line.
|
||||||
|
* FIFO0 interrupts are used by TSC. Handle FIFO1 IRQs here only
|
||||||
|
*/
|
||||||
|
if (status & IRQENB_FIFO1OVRRUN) {
|
||||||
|
/* FIFO Overrun. Clear flag. Disable/Enable ADC to recover */
|
||||||
|
config = tiadc_readl(adc_dev, REG_CTRL);
|
||||||
|
config &= ~(CNTRLREG_TSCSSENB);
|
||||||
|
tiadc_writel(adc_dev, REG_CTRL, config);
|
||||||
|
tiadc_writel(adc_dev, REG_IRQSTATUS, IRQENB_FIFO1OVRRUN
|
||||||
|
| IRQENB_FIFO1UNDRFLW | IRQENB_FIFO1THRES);
|
||||||
|
tiadc_writel(adc_dev, REG_CTRL, (config | CNTRLREG_TSCSSENB));
|
||||||
|
return IRQ_HANDLED;
|
||||||
|
} else if (status & IRQENB_FIFO1THRES) {
|
||||||
|
/* Disable irq and wake worker thread */
|
||||||
|
tiadc_writel(adc_dev, REG_IRQCLR, IRQENB_FIFO1THRES);
|
||||||
|
return IRQ_WAKE_THREAD;
|
||||||
|
}
|
||||||
|
|
||||||
|
return IRQ_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static irqreturn_t tiadc_worker_h(int irq, void *private)
|
||||||
|
{
|
||||||
|
struct iio_dev *indio_dev = private;
|
||||||
|
struct tiadc_device *adc_dev = iio_priv(indio_dev);
|
||||||
|
int i, k, fifo1count, read;
|
||||||
|
u16 *data = adc_dev->data;
|
||||||
|
|
||||||
|
fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
|
||||||
|
for (k = 0; k < fifo1count; k = k + i) {
|
||||||
|
for (i = 0; i < (indio_dev->scan_bytes)/2; i++) {
|
||||||
|
read = tiadc_readl(adc_dev, REG_FIFO1);
|
||||||
|
data[i] = read & FIFOREAD_DATA_MASK;
|
||||||
|
}
|
||||||
|
iio_push_to_buffers(indio_dev, (u8 *) data);
|
||||||
|
}
|
||||||
|
|
||||||
|
tiadc_writel(adc_dev, REG_IRQSTATUS, IRQENB_FIFO1THRES);
|
||||||
|
tiadc_writel(adc_dev, REG_IRQENABLE, IRQENB_FIFO1THRES);
|
||||||
|
|
||||||
|
return IRQ_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tiadc_buffer_preenable(struct iio_dev *indio_dev)
|
||||||
|
{
|
||||||
|
struct tiadc_device *adc_dev = iio_priv(indio_dev);
|
||||||
|
int i, fifo1count, read;
|
||||||
|
|
||||||
|
tiadc_writel(adc_dev, REG_IRQCLR, (IRQENB_FIFO1THRES |
|
||||||
|
IRQENB_FIFO1OVRRUN |
|
||||||
|
IRQENB_FIFO1UNDRFLW));
|
||||||
|
|
||||||
|
/* Flush FIFO. Needed in corner cases in simultaneous tsc/adc use */
|
||||||
|
fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
|
||||||
|
for (i = 0; i < fifo1count; i++)
|
||||||
|
read = tiadc_readl(adc_dev, REG_FIFO1);
|
||||||
|
|
||||||
|
return iio_sw_buffer_preenable(indio_dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tiadc_buffer_postenable(struct iio_dev *indio_dev)
|
||||||
|
{
|
||||||
|
struct tiadc_device *adc_dev = iio_priv(indio_dev);
|
||||||
|
struct iio_buffer *buffer = indio_dev->buffer;
|
||||||
|
unsigned int enb = 0;
|
||||||
|
u8 bit;
|
||||||
|
|
||||||
|
tiadc_step_config(indio_dev);
|
||||||
|
for_each_set_bit(bit, buffer->scan_mask, adc_dev->channels)
|
||||||
|
enb |= (get_adc_step_bit(adc_dev, bit) << 1);
|
||||||
|
adc_dev->buffer_en_ch_steps = enb;
|
||||||
|
|
||||||
|
am335x_tsc_se_set(adc_dev->mfd_tscadc, enb);
|
||||||
|
|
||||||
|
tiadc_writel(adc_dev, REG_IRQSTATUS, IRQENB_FIFO1THRES
|
||||||
|
| IRQENB_FIFO1OVRRUN | IRQENB_FIFO1UNDRFLW);
|
||||||
|
tiadc_writel(adc_dev, REG_IRQENABLE, IRQENB_FIFO1THRES
|
||||||
|
| IRQENB_FIFO1OVRRUN);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tiadc_buffer_predisable(struct iio_dev *indio_dev)
|
||||||
|
{
|
||||||
|
struct tiadc_device *adc_dev = iio_priv(indio_dev);
|
||||||
|
int fifo1count, i, read;
|
||||||
|
|
||||||
|
tiadc_writel(adc_dev, REG_IRQCLR, (IRQENB_FIFO1THRES |
|
||||||
|
IRQENB_FIFO1OVRRUN | IRQENB_FIFO1UNDRFLW));
|
||||||
|
am335x_tsc_se_clr(adc_dev->mfd_tscadc, adc_dev->buffer_en_ch_steps);
|
||||||
|
|
||||||
|
/* Flush FIFO of leftover data in the time it takes to disable adc */
|
||||||
|
fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
|
||||||
|
for (i = 0; i < fifo1count; i++)
|
||||||
|
read = tiadc_readl(adc_dev, REG_FIFO1);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tiadc_buffer_postdisable(struct iio_dev *indio_dev)
|
||||||
|
{
|
||||||
|
tiadc_step_config(indio_dev);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct iio_buffer_setup_ops tiadc_buffer_setup_ops = {
|
||||||
|
.preenable = &tiadc_buffer_preenable,
|
||||||
|
.postenable = &tiadc_buffer_postenable,
|
||||||
|
.predisable = &tiadc_buffer_predisable,
|
||||||
|
.postdisable = &tiadc_buffer_postdisable,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int tiadc_iio_buffered_hardware_setup(struct iio_dev *indio_dev,
|
||||||
|
irqreturn_t (*pollfunc_bh)(int irq, void *p),
|
||||||
|
irqreturn_t (*pollfunc_th)(int irq, void *p),
|
||||||
|
int irq,
|
||||||
|
unsigned long flags,
|
||||||
|
const struct iio_buffer_setup_ops *setup_ops)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
indio_dev->buffer = iio_kfifo_allocate(indio_dev);
|
||||||
|
if (!indio_dev->buffer)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
ret = request_threaded_irq(irq, pollfunc_th, pollfunc_bh,
|
||||||
|
flags, indio_dev->name, indio_dev);
|
||||||
|
if (ret)
|
||||||
|
goto error_kfifo_free;
|
||||||
|
|
||||||
|
indio_dev->setup_ops = setup_ops;
|
||||||
|
indio_dev->modes |= INDIO_BUFFER_HARDWARE;
|
||||||
|
|
||||||
|
ret = iio_buffer_register(indio_dev,
|
||||||
|
indio_dev->channels,
|
||||||
|
indio_dev->num_channels);
|
||||||
|
if (ret)
|
||||||
|
goto error_free_irq;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
error_free_irq:
|
||||||
|
free_irq(irq, indio_dev);
|
||||||
|
error_kfifo_free:
|
||||||
|
iio_kfifo_free(indio_dev->buffer);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tiadc_iio_buffered_hardware_remove(struct iio_dev *indio_dev)
|
||||||
|
{
|
||||||
|
struct tiadc_device *adc_dev = iio_priv(indio_dev);
|
||||||
|
|
||||||
|
free_irq(adc_dev->mfd_tscadc->irq, indio_dev);
|
||||||
|
iio_kfifo_free(indio_dev->buffer);
|
||||||
|
iio_buffer_unregister(indio_dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static const char * const chan_name_ain[] = {
|
static const char * const chan_name_ain[] = {
|
||||||
"AIN0",
|
"AIN0",
|
||||||
"AIN1",
|
"AIN1",
|
||||||
|
@ -120,9 +300,10 @@ static int tiadc_channel_init(struct iio_dev *indio_dev, int channels)
|
||||||
chan->channel = adc_dev->channel_line[i];
|
chan->channel = adc_dev->channel_line[i];
|
||||||
chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW);
|
chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW);
|
||||||
chan->datasheet_name = chan_name_ain[chan->channel];
|
chan->datasheet_name = chan_name_ain[chan->channel];
|
||||||
|
chan->scan_index = i;
|
||||||
chan->scan_type.sign = 'u';
|
chan->scan_type.sign = 'u';
|
||||||
chan->scan_type.realbits = 12;
|
chan->scan_type.realbits = 12;
|
||||||
chan->scan_type.storagebits = 32;
|
chan->scan_type.storagebits = 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
indio_dev->channels = chan_array;
|
indio_dev->channels = chan_array;
|
||||||
|
@ -142,11 +323,14 @@ static int tiadc_read_raw(struct iio_dev *indio_dev,
|
||||||
struct tiadc_device *adc_dev = iio_priv(indio_dev);
|
struct tiadc_device *adc_dev = iio_priv(indio_dev);
|
||||||
int i, map_val;
|
int i, map_val;
|
||||||
unsigned int fifo1count, read, stepid;
|
unsigned int fifo1count, read, stepid;
|
||||||
u32 step = UINT_MAX;
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
u32 step_en;
|
u32 step_en;
|
||||||
unsigned long timeout = jiffies + usecs_to_jiffies
|
unsigned long timeout = jiffies + usecs_to_jiffies
|
||||||
(IDLE_TIMEOUT * adc_dev->channels);
|
(IDLE_TIMEOUT * adc_dev->channels);
|
||||||
|
|
||||||
|
if (iio_buffer_enabled(indio_dev))
|
||||||
|
return -EBUSY;
|
||||||
|
|
||||||
step_en = get_adc_step_mask(adc_dev);
|
step_en = get_adc_step_mask(adc_dev);
|
||||||
am335x_tsc_se_set(adc_dev->mfd_tscadc, step_en);
|
am335x_tsc_se_set(adc_dev->mfd_tscadc, step_en);
|
||||||
|
|
||||||
|
@ -168,15 +352,6 @@ static int tiadc_read_raw(struct iio_dev *indio_dev,
|
||||||
* Hence we need to flush out this data.
|
* Hence we need to flush out this data.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(adc_dev->channel_step); i++) {
|
|
||||||
if (chan->channel == adc_dev->channel_line[i]) {
|
|
||||||
step = adc_dev->channel_step[i];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (WARN_ON_ONCE(step == UINT_MAX))
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
|
fifo1count = tiadc_readl(adc_dev, REG_FIFO1CNT);
|
||||||
for (i = 0; i < fifo1count; i++) {
|
for (i = 0; i < fifo1count; i++) {
|
||||||
read = tiadc_readl(adc_dev, REG_FIFO1);
|
read = tiadc_readl(adc_dev, REG_FIFO1);
|
||||||
|
@ -186,7 +361,7 @@ static int tiadc_read_raw(struct iio_dev *indio_dev,
|
||||||
if (stepid == map_val) {
|
if (stepid == map_val) {
|
||||||
read = read & FIFOREAD_DATA_MASK;
|
read = read & FIFOREAD_DATA_MASK;
|
||||||
found = true;
|
found = true;
|
||||||
*val = read;
|
*val = (u16) read;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,20 +412,33 @@ static int tiadc_probe(struct platform_device *pdev)
|
||||||
indio_dev->modes = INDIO_DIRECT_MODE;
|
indio_dev->modes = INDIO_DIRECT_MODE;
|
||||||
indio_dev->info = &tiadc_info;
|
indio_dev->info = &tiadc_info;
|
||||||
|
|
||||||
tiadc_step_config(adc_dev);
|
tiadc_step_config(indio_dev);
|
||||||
|
tiadc_writel(adc_dev, REG_FIFO1THR, FIFO1_THRESHOLD);
|
||||||
|
|
||||||
err = tiadc_channel_init(indio_dev, adc_dev->channels);
|
err = tiadc_channel_init(indio_dev, adc_dev->channels);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
err = iio_device_register(indio_dev);
|
err = tiadc_iio_buffered_hardware_setup(indio_dev,
|
||||||
|
&tiadc_worker_h,
|
||||||
|
&tiadc_irq_h,
|
||||||
|
adc_dev->mfd_tscadc->irq,
|
||||||
|
IRQF_SHARED,
|
||||||
|
&tiadc_buffer_setup_ops);
|
||||||
|
|
||||||
if (err)
|
if (err)
|
||||||
goto err_free_channels;
|
goto err_free_channels;
|
||||||
|
|
||||||
|
err = iio_device_register(indio_dev);
|
||||||
|
if (err)
|
||||||
|
goto err_buffer_unregister;
|
||||||
|
|
||||||
platform_set_drvdata(pdev, indio_dev);
|
platform_set_drvdata(pdev, indio_dev);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err_buffer_unregister:
|
||||||
|
tiadc_iio_buffered_hardware_remove(indio_dev);
|
||||||
err_free_channels:
|
err_free_channels:
|
||||||
tiadc_channels_remove(indio_dev);
|
tiadc_channels_remove(indio_dev);
|
||||||
return err;
|
return err;
|
||||||
|
@ -263,6 +451,7 @@ static int tiadc_remove(struct platform_device *pdev)
|
||||||
u32 step_en;
|
u32 step_en;
|
||||||
|
|
||||||
iio_device_unregister(indio_dev);
|
iio_device_unregister(indio_dev);
|
||||||
|
tiadc_iio_buffered_hardware_remove(indio_dev);
|
||||||
tiadc_channels_remove(indio_dev);
|
tiadc_channels_remove(indio_dev);
|
||||||
|
|
||||||
step_en = get_adc_step_mask(adc_dev);
|
step_en = get_adc_step_mask(adc_dev);
|
||||||
|
@ -301,7 +490,7 @@ static int tiadc_resume(struct device *dev)
|
||||||
restore &= ~(CNTRLREG_POWERDOWN);
|
restore &= ~(CNTRLREG_POWERDOWN);
|
||||||
tiadc_writel(adc_dev, REG_CTRL, restore);
|
tiadc_writel(adc_dev, REG_CTRL, restore);
|
||||||
|
|
||||||
tiadc_step_config(adc_dev);
|
tiadc_step_config(indio_dev);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,12 +7,12 @@
|
||||||
|
|
||||||
struct iio_cb_buffer {
|
struct iio_cb_buffer {
|
||||||
struct iio_buffer buffer;
|
struct iio_buffer buffer;
|
||||||
int (*cb)(u8 *data, void *private);
|
int (*cb)(const void *data, void *private);
|
||||||
void *private;
|
void *private;
|
||||||
struct iio_channel *channels;
|
struct iio_channel *channels;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int iio_buffer_cb_store_to(struct iio_buffer *buffer, u8 *data)
|
static int iio_buffer_cb_store_to(struct iio_buffer *buffer, const void *data)
|
||||||
{
|
{
|
||||||
struct iio_cb_buffer *cb_buff = container_of(buffer,
|
struct iio_cb_buffer *cb_buff = container_of(buffer,
|
||||||
struct iio_cb_buffer,
|
struct iio_cb_buffer,
|
||||||
|
@ -21,12 +21,12 @@ static int iio_buffer_cb_store_to(struct iio_buffer *buffer, u8 *data)
|
||||||
return cb_buff->cb(data, cb_buff->private);
|
return cb_buff->cb(data, cb_buff->private);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct iio_buffer_access_funcs iio_cb_access = {
|
static const struct iio_buffer_access_funcs iio_cb_access = {
|
||||||
.store_to = &iio_buffer_cb_store_to,
|
.store_to = &iio_buffer_cb_store_to,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct iio_cb_buffer *iio_channel_get_all_cb(struct device *dev,
|
struct iio_cb_buffer *iio_channel_get_all_cb(struct device *dev,
|
||||||
int (*cb)(u8 *data,
|
int (*cb)(const void *data,
|
||||||
void *private),
|
void *private),
|
||||||
void *private)
|
void *private)
|
||||||
{
|
{
|
||||||
|
|
|
@ -113,11 +113,8 @@ irqreturn_t st_sensors_trigger_handler(int irq, void *p)
|
||||||
if (len < 0)
|
if (len < 0)
|
||||||
goto st_sensors_get_buffer_element_error;
|
goto st_sensors_get_buffer_element_error;
|
||||||
|
|
||||||
if (indio_dev->scan_timestamp)
|
iio_push_to_buffers_with_timestamp(indio_dev, sdata->buffer_data,
|
||||||
*(s64 *)((u8 *)sdata->buffer_data +
|
pf->timestamp);
|
||||||
ALIGN(len, sizeof(s64))) = pf->timestamp;
|
|
||||||
|
|
||||||
iio_push_to_buffers(indio_dev, sdata->buffer_data);
|
|
||||||
|
|
||||||
st_sensors_get_buffer_element_error:
|
st_sensors_get_buffer_element_error:
|
||||||
iio_trigger_notify_done(indio_dev->trig);
|
iio_trigger_notify_done(indio_dev->trig);
|
||||||
|
|
|
@ -198,21 +198,17 @@ int st_sensors_set_axis_enable(struct iio_dev *indio_dev, u8 axis_enable)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(st_sensors_set_axis_enable);
|
EXPORT_SYMBOL(st_sensors_set_axis_enable);
|
||||||
|
|
||||||
int st_sensors_init_sensor(struct iio_dev *indio_dev,
|
static int st_sensors_set_drdy_int_pin(struct iio_dev *indio_dev,
|
||||||
struct st_sensors_platform_data *pdata)
|
struct st_sensors_platform_data *pdata)
|
||||||
{
|
{
|
||||||
int err;
|
|
||||||
struct st_sensor_data *sdata = iio_priv(indio_dev);
|
struct st_sensor_data *sdata = iio_priv(indio_dev);
|
||||||
|
|
||||||
mutex_init(&sdata->tb.buf_lock);
|
|
||||||
|
|
||||||
switch (pdata->drdy_int_pin) {
|
switch (pdata->drdy_int_pin) {
|
||||||
case 1:
|
case 1:
|
||||||
if (sdata->sensor->drdy_irq.mask_int1 == 0) {
|
if (sdata->sensor->drdy_irq.mask_int1 == 0) {
|
||||||
dev_err(&indio_dev->dev,
|
dev_err(&indio_dev->dev,
|
||||||
"DRDY on INT1 not available.\n");
|
"DRDY on INT1 not available.\n");
|
||||||
err = -EINVAL;
|
return -EINVAL;
|
||||||
goto init_error;
|
|
||||||
}
|
}
|
||||||
sdata->drdy_int_pin = 1;
|
sdata->drdy_int_pin = 1;
|
||||||
break;
|
break;
|
||||||
|
@ -220,39 +216,53 @@ int st_sensors_init_sensor(struct iio_dev *indio_dev,
|
||||||
if (sdata->sensor->drdy_irq.mask_int2 == 0) {
|
if (sdata->sensor->drdy_irq.mask_int2 == 0) {
|
||||||
dev_err(&indio_dev->dev,
|
dev_err(&indio_dev->dev,
|
||||||
"DRDY on INT2 not available.\n");
|
"DRDY on INT2 not available.\n");
|
||||||
err = -EINVAL;
|
return -EINVAL;
|
||||||
goto init_error;
|
|
||||||
}
|
}
|
||||||
sdata->drdy_int_pin = 2;
|
sdata->drdy_int_pin = 2;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dev_err(&indio_dev->dev, "DRDY on pdata not valid.\n");
|
dev_err(&indio_dev->dev, "DRDY on pdata not valid.\n");
|
||||||
err = -EINVAL;
|
return -EINVAL;
|
||||||
goto init_error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int st_sensors_init_sensor(struct iio_dev *indio_dev,
|
||||||
|
struct st_sensors_platform_data *pdata)
|
||||||
|
{
|
||||||
|
struct st_sensor_data *sdata = iio_priv(indio_dev);
|
||||||
|
int err = 0;
|
||||||
|
|
||||||
|
mutex_init(&sdata->tb.buf_lock);
|
||||||
|
|
||||||
|
if (pdata)
|
||||||
|
err = st_sensors_set_drdy_int_pin(indio_dev, pdata);
|
||||||
|
|
||||||
err = st_sensors_set_enable(indio_dev, false);
|
err = st_sensors_set_enable(indio_dev, false);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto init_error;
|
return err;
|
||||||
|
|
||||||
err = st_sensors_set_fullscale(indio_dev,
|
if (sdata->current_fullscale) {
|
||||||
sdata->current_fullscale->num);
|
err = st_sensors_set_fullscale(indio_dev,
|
||||||
if (err < 0)
|
sdata->current_fullscale->num);
|
||||||
goto init_error;
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
} else
|
||||||
|
dev_info(&indio_dev->dev, "Full-scale not possible\n");
|
||||||
|
|
||||||
err = st_sensors_set_odr(indio_dev, sdata->odr);
|
err = st_sensors_set_odr(indio_dev, sdata->odr);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto init_error;
|
return err;
|
||||||
|
|
||||||
/* set BDU */
|
/* set BDU */
|
||||||
err = st_sensors_write_data_with_mask(indio_dev,
|
err = st_sensors_write_data_with_mask(indio_dev,
|
||||||
sdata->sensor->bdu.addr, sdata->sensor->bdu.mask, true);
|
sdata->sensor->bdu.addr, sdata->sensor->bdu.mask, true);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto init_error;
|
return err;
|
||||||
|
|
||||||
err = st_sensors_set_axis_enable(indio_dev, ST_SENSORS_ENABLE_ALL_AXIS);
|
err = st_sensors_set_axis_enable(indio_dev, ST_SENSORS_ENABLE_ALL_AXIS);
|
||||||
|
|
||||||
init_error:
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(st_sensors_init_sensor);
|
EXPORT_SYMBOL(st_sensors_init_sensor);
|
||||||
|
@ -263,6 +273,9 @@ int st_sensors_set_dataready_irq(struct iio_dev *indio_dev, bool enable)
|
||||||
u8 drdy_mask;
|
u8 drdy_mask;
|
||||||
struct st_sensor_data *sdata = iio_priv(indio_dev);
|
struct st_sensor_data *sdata = iio_priv(indio_dev);
|
||||||
|
|
||||||
|
if (!sdata->sensor->drdy_irq.addr)
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* Enable/Disable the interrupt generator 1. */
|
/* Enable/Disable the interrupt generator 1. */
|
||||||
if (sdata->sensor->drdy_irq.ig1.en_addr > 0) {
|
if (sdata->sensor->drdy_irq.ig1.en_addr > 0) {
|
||||||
err = st_sensors_write_data_with_mask(indio_dev,
|
err = st_sensors_write_data_with_mask(indio_dev,
|
||||||
|
@ -318,10 +331,8 @@ static int st_sensors_read_axis_data(struct iio_dev *indio_dev,
|
||||||
unsigned int byte_for_channel = ch->scan_type.storagebits >> 3;
|
unsigned int byte_for_channel = ch->scan_type.storagebits >> 3;
|
||||||
|
|
||||||
outdata = kmalloc(byte_for_channel, GFP_KERNEL);
|
outdata = kmalloc(byte_for_channel, GFP_KERNEL);
|
||||||
if (!outdata) {
|
if (!outdata)
|
||||||
err = -EINVAL;
|
return -ENOMEM;
|
||||||
goto st_sensors_read_axis_data_error;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = sdata->tf->read_multiple_byte(&sdata->tb, sdata->dev,
|
err = sdata->tf->read_multiple_byte(&sdata->tb, sdata->dev,
|
||||||
ch->address, byte_for_channel,
|
ch->address, byte_for_channel,
|
||||||
|
@ -336,7 +347,7 @@ static int st_sensors_read_axis_data(struct iio_dev *indio_dev,
|
||||||
|
|
||||||
st_sensors_free_memory:
|
st_sensors_free_memory:
|
||||||
kfree(outdata);
|
kfree(outdata);
|
||||||
st_sensors_read_axis_data_error:
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -349,28 +360,25 @@ int st_sensors_read_info_raw(struct iio_dev *indio_dev,
|
||||||
mutex_lock(&indio_dev->mlock);
|
mutex_lock(&indio_dev->mlock);
|
||||||
if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) {
|
if (indio_dev->currentmode == INDIO_BUFFER_TRIGGERED) {
|
||||||
err = -EBUSY;
|
err = -EBUSY;
|
||||||
goto read_error;
|
goto out;
|
||||||
} else {
|
} else {
|
||||||
err = st_sensors_set_enable(indio_dev, true);
|
err = st_sensors_set_enable(indio_dev, true);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto read_error;
|
goto out;
|
||||||
|
|
||||||
msleep((sdata->sensor->bootime * 1000) / sdata->odr);
|
msleep((sdata->sensor->bootime * 1000) / sdata->odr);
|
||||||
err = st_sensors_read_axis_data(indio_dev, ch, val);
|
err = st_sensors_read_axis_data(indio_dev, ch, val);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto read_error;
|
goto out;
|
||||||
|
|
||||||
*val = *val >> ch->scan_type.shift;
|
*val = *val >> ch->scan_type.shift;
|
||||||
|
|
||||||
err = st_sensors_set_enable(indio_dev, false);
|
err = st_sensors_set_enable(indio_dev, false);
|
||||||
}
|
}
|
||||||
|
out:
|
||||||
mutex_unlock(&indio_dev->mlock);
|
mutex_unlock(&indio_dev->mlock);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
read_error:
|
|
||||||
mutex_unlock(&indio_dev->mlock);
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(st_sensors_read_info_raw);
|
EXPORT_SYMBOL(st_sensors_read_info_raw);
|
||||||
|
|
||||||
|
|
|
@ -285,8 +285,9 @@ static const struct iio_chan_spec_ext_info ad5064_ext_info[] = {
|
||||||
.name = "powerdown",
|
.name = "powerdown",
|
||||||
.read = ad5064_read_dac_powerdown,
|
.read = ad5064_read_dac_powerdown,
|
||||||
.write = ad5064_write_dac_powerdown,
|
.write = ad5064_write_dac_powerdown,
|
||||||
|
.shared = IIO_SEPARATE,
|
||||||
},
|
},
|
||||||
IIO_ENUM("powerdown_mode", false, &ad5064_powerdown_mode_enum),
|
IIO_ENUM("powerdown_mode", IIO_SEPARATE, &ad5064_powerdown_mode_enum),
|
||||||
IIO_ENUM_AVAILABLE("powerdown_mode", &ad5064_powerdown_mode_enum),
|
IIO_ENUM_AVAILABLE("powerdown_mode", &ad5064_powerdown_mode_enum),
|
||||||
{ },
|
{ },
|
||||||
};
|
};
|
||||||
|
|
|
@ -247,8 +247,10 @@ static struct iio_chan_spec_ext_info ad5380_ext_info[] = {
|
||||||
.name = "powerdown",
|
.name = "powerdown",
|
||||||
.read = ad5380_read_dac_powerdown,
|
.read = ad5380_read_dac_powerdown,
|
||||||
.write = ad5380_write_dac_powerdown,
|
.write = ad5380_write_dac_powerdown,
|
||||||
|
.shared = IIO_SEPARATE,
|
||||||
},
|
},
|
||||||
IIO_ENUM("powerdown_mode", true, &ad5380_powerdown_mode_enum),
|
IIO_ENUM("powerdown_mode", IIO_SHARED_BY_TYPE,
|
||||||
|
&ad5380_powerdown_mode_enum),
|
||||||
IIO_ENUM_AVAILABLE("powerdown_mode", &ad5380_powerdown_mode_enum),
|
IIO_ENUM_AVAILABLE("powerdown_mode", &ad5380_powerdown_mode_enum),
|
||||||
{ },
|
{ },
|
||||||
};
|
};
|
||||||
|
|
|
@ -132,8 +132,9 @@ static const struct iio_chan_spec_ext_info ad5446_ext_info_powerdown[] = {
|
||||||
.name = "powerdown",
|
.name = "powerdown",
|
||||||
.read = ad5446_read_dac_powerdown,
|
.read = ad5446_read_dac_powerdown,
|
||||||
.write = ad5446_write_dac_powerdown,
|
.write = ad5446_write_dac_powerdown,
|
||||||
|
.shared = IIO_SEPARATE,
|
||||||
},
|
},
|
||||||
IIO_ENUM("powerdown_mode", false, &ad5446_powerdown_mode_enum),
|
IIO_ENUM("powerdown_mode", IIO_SEPARATE, &ad5446_powerdown_mode_enum),
|
||||||
IIO_ENUM_AVAILABLE("powerdown_mode", &ad5446_powerdown_mode_enum),
|
IIO_ENUM_AVAILABLE("powerdown_mode", &ad5446_powerdown_mode_enum),
|
||||||
{ },
|
{ },
|
||||||
};
|
};
|
||||||
|
|
|
@ -248,8 +248,10 @@ static const struct iio_chan_spec_ext_info ad5504_ext_info[] = {
|
||||||
.name = "powerdown",
|
.name = "powerdown",
|
||||||
.read = ad5504_read_dac_powerdown,
|
.read = ad5504_read_dac_powerdown,
|
||||||
.write = ad5504_write_dac_powerdown,
|
.write = ad5504_write_dac_powerdown,
|
||||||
|
.shared = IIO_SEPARATE,
|
||||||
},
|
},
|
||||||
IIO_ENUM("powerdown_mode", true, &ad5504_powerdown_mode_enum),
|
IIO_ENUM("powerdown_mode", IIO_SHARED_BY_TYPE,
|
||||||
|
&ad5504_powerdown_mode_enum),
|
||||||
IIO_ENUM_AVAILABLE("powerdown_mode", &ad5504_powerdown_mode_enum),
|
IIO_ENUM_AVAILABLE("powerdown_mode", &ad5504_powerdown_mode_enum),
|
||||||
{ },
|
{ },
|
||||||
};
|
};
|
||||||
|
|
|
@ -163,8 +163,10 @@ static const struct iio_chan_spec_ext_info ad5624r_ext_info[] = {
|
||||||
.name = "powerdown",
|
.name = "powerdown",
|
||||||
.read = ad5624r_read_dac_powerdown,
|
.read = ad5624r_read_dac_powerdown,
|
||||||
.write = ad5624r_write_dac_powerdown,
|
.write = ad5624r_write_dac_powerdown,
|
||||||
|
.shared = IIO_SEPARATE,
|
||||||
},
|
},
|
||||||
IIO_ENUM("powerdown_mode", true, &ad5624r_powerdown_mode_enum),
|
IIO_ENUM("powerdown_mode", IIO_SHARED_BY_TYPE,
|
||||||
|
&ad5624r_powerdown_mode_enum),
|
||||||
IIO_ENUM_AVAILABLE("powerdown_mode", &ad5624r_powerdown_mode_enum),
|
IIO_ENUM_AVAILABLE("powerdown_mode", &ad5624r_powerdown_mode_enum),
|
||||||
{ },
|
{ },
|
||||||
};
|
};
|
||||||
|
|
|
@ -213,7 +213,6 @@ static int ad5686_read_raw(struct iio_dev *indio_dev,
|
||||||
return ret;
|
return ret;
|
||||||
*val = ret;
|
*val = ret;
|
||||||
return IIO_VAL_INT;
|
return IIO_VAL_INT;
|
||||||
break;
|
|
||||||
case IIO_CHAN_INFO_SCALE:
|
case IIO_CHAN_INFO_SCALE:
|
||||||
scale_uv = (st->vref_mv * 100000)
|
scale_uv = (st->vref_mv * 100000)
|
||||||
>> (chan->scan_type.realbits);
|
>> (chan->scan_type.realbits);
|
||||||
|
@ -265,8 +264,9 @@ static const struct iio_chan_spec_ext_info ad5686_ext_info[] = {
|
||||||
.name = "powerdown",
|
.name = "powerdown",
|
||||||
.read = ad5686_read_dac_powerdown,
|
.read = ad5686_read_dac_powerdown,
|
||||||
.write = ad5686_write_dac_powerdown,
|
.write = ad5686_write_dac_powerdown,
|
||||||
|
.shared = IIO_SEPARATE,
|
||||||
},
|
},
|
||||||
IIO_ENUM("powerdown_mode", false, &ad5686_powerdown_mode_enum),
|
IIO_ENUM("powerdown_mode", IIO_SEPARATE, &ad5686_powerdown_mode_enum),
|
||||||
IIO_ENUM_AVAILABLE("powerdown_mode", &ad5686_powerdown_mode_enum),
|
IIO_ENUM_AVAILABLE("powerdown_mode", &ad5686_powerdown_mode_enum),
|
||||||
{ },
|
{ },
|
||||||
};
|
};
|
||||||
|
|
|
@ -386,6 +386,7 @@ static const struct iio_chan_spec_ext_info ad5755_ext_info[] = {
|
||||||
.name = "powerdown",
|
.name = "powerdown",
|
||||||
.read = ad5755_read_powerdown,
|
.read = ad5755_read_powerdown,
|
||||||
.write = ad5755_write_powerdown,
|
.write = ad5755_write_powerdown,
|
||||||
|
.shared = IIO_SEPARATE,
|
||||||
},
|
},
|
||||||
{ },
|
{ },
|
||||||
};
|
};
|
||||||
|
|
|
@ -287,11 +287,12 @@ static int ad5791_read_raw(struct iio_dev *indio_dev,
|
||||||
static const struct iio_chan_spec_ext_info ad5791_ext_info[] = {
|
static const struct iio_chan_spec_ext_info ad5791_ext_info[] = {
|
||||||
{
|
{
|
||||||
.name = "powerdown",
|
.name = "powerdown",
|
||||||
.shared = true,
|
.shared = IIO_SHARED_BY_TYPE,
|
||||||
.read = ad5791_read_dac_powerdown,
|
.read = ad5791_read_dac_powerdown,
|
||||||
.write = ad5791_write_dac_powerdown,
|
.write = ad5791_write_dac_powerdown,
|
||||||
},
|
},
|
||||||
IIO_ENUM("powerdown_mode", true, &ad5791_powerdown_mode_enum),
|
IIO_ENUM("powerdown_mode", IIO_SHARED_BY_TYPE,
|
||||||
|
&ad5791_powerdown_mode_enum),
|
||||||
IIO_ENUM_AVAILABLE("powerdown_mode", &ad5791_powerdown_mode_enum),
|
IIO_ENUM_AVAILABLE("powerdown_mode", &ad5791_powerdown_mode_enum),
|
||||||
{ },
|
{ },
|
||||||
};
|
};
|
||||||
|
|
|
@ -169,6 +169,7 @@ static const struct iio_chan_spec_ext_info ad7303_ext_info[] = {
|
||||||
.name = "powerdown",
|
.name = "powerdown",
|
||||||
.read = ad7303_read_dac_powerdown,
|
.read = ad7303_read_dac_powerdown,
|
||||||
.write = ad7303_write_dac_powerdown,
|
.write = ad7303_write_dac_powerdown,
|
||||||
|
.shared = IIO_SEPARATE,
|
||||||
},
|
},
|
||||||
{ },
|
{ },
|
||||||
};
|
};
|
||||||
|
|
|
@ -195,8 +195,9 @@ static const struct iio_chan_spec_ext_info mcp4725_ext_info[] = {
|
||||||
.name = "powerdown",
|
.name = "powerdown",
|
||||||
.read = mcp4725_read_powerdown,
|
.read = mcp4725_read_powerdown,
|
||||||
.write = mcp4725_write_powerdown,
|
.write = mcp4725_write_powerdown,
|
||||||
|
.shared = IIO_SEPARATE,
|
||||||
},
|
},
|
||||||
IIO_ENUM("powerdown_mode", false, &mcp4725_powerdown_mode_enum),
|
IIO_ENUM("powerdown_mode", IIO_SEPARATE, &mcp4725_powerdown_mode_enum),
|
||||||
IIO_ENUM_AVAILABLE("powerdown_mode", &mcp4725_powerdown_mode_enum),
|
IIO_ENUM_AVAILABLE("powerdown_mode", &mcp4725_powerdown_mode_enum),
|
||||||
{ },
|
{ },
|
||||||
};
|
};
|
||||||
|
|
|
@ -351,6 +351,7 @@ static ssize_t adf4350_read(struct iio_dev *indio_dev,
|
||||||
.read = adf4350_read, \
|
.read = adf4350_read, \
|
||||||
.write = adf4350_write, \
|
.write = adf4350_write, \
|
||||||
.private = _ident, \
|
.private = _ident, \
|
||||||
|
.shared = IIO_SEPARATE, \
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct iio_chan_spec_ext_info adf4350_ext_info[] = {
|
static const struct iio_chan_spec_ext_info adf4350_ext_info[] = {
|
||||||
|
|
|
@ -103,7 +103,6 @@ static int adis16130_read_raw(struct iio_dev *indio_dev,
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case IIO_CHAN_INFO_OFFSET:
|
case IIO_CHAN_INFO_OFFSET:
|
||||||
switch (chan->type) {
|
switch (chan->type) {
|
||||||
case IIO_ANGL_VEL:
|
case IIO_ANGL_VEL:
|
||||||
|
@ -115,7 +114,6 @@ static int adis16130_read_raw(struct iio_dev *indio_dev,
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
|
@ -239,7 +239,6 @@ static int adis16260_read_raw(struct iio_dev *indio_dev,
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case IIO_CHAN_INFO_OFFSET:
|
case IIO_CHAN_INFO_OFFSET:
|
||||||
*val = 250000 / 1453; /* 25 C = 0x00 */
|
*val = 250000 / 1453; /* 25 C = 0x00 */
|
||||||
return IIO_VAL_INT;
|
return IIO_VAL_INT;
|
||||||
|
|
|
@ -354,7 +354,6 @@ static int adxrs450_read_raw(struct iio_dev *indio_dev,
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
case IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW:
|
case IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW:
|
||||||
ret = adxrs450_spi_read_reg_16(indio_dev, ADXRS450_QUAD1, &t);
|
ret = adxrs450_spi_read_reg_16(indio_dev, ADXRS450_QUAD1, &t);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
|
|
@ -182,10 +182,11 @@ static const struct iio_info gyro_3d_info = {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Function to push data to buffer */
|
/* Function to push data to buffer */
|
||||||
static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len)
|
static void hid_sensor_push_data(struct iio_dev *indio_dev, const void *data,
|
||||||
|
int len)
|
||||||
{
|
{
|
||||||
dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n");
|
dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n");
|
||||||
iio_push_to_buffers(indio_dev, (u8 *)data);
|
iio_push_to_buffers(indio_dev, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Callback handler to send event after all samples are received and captured */
|
/* Callback handler to send event after all samples are received and captured */
|
||||||
|
@ -200,7 +201,7 @@ static int gyro_3d_proc_event(struct hid_sensor_hub_device *hsdev,
|
||||||
gyro_state->common_attributes.data_ready);
|
gyro_state->common_attributes.data_ready);
|
||||||
if (gyro_state->common_attributes.data_ready)
|
if (gyro_state->common_attributes.data_ready)
|
||||||
hid_sensor_push_data(indio_dev,
|
hid_sensor_push_data(indio_dev,
|
||||||
(u8 *)gyro_state->gyro_val,
|
gyro_state->gyro_val,
|
||||||
sizeof(gyro_state->gyro_val));
|
sizeof(gyro_state->gyro_val));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -55,11 +55,8 @@ static irqreturn_t itg3200_trigger_handler(int irq, void *p)
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto error_ret;
|
goto error_ret;
|
||||||
|
|
||||||
if (indio_dev->scan_timestamp)
|
iio_push_to_buffers_with_timestamp(indio_dev, buf, pf->timestamp);
|
||||||
memcpy(buf + indio_dev->scan_bytes - sizeof(s64),
|
|
||||||
&pf->timestamp, sizeof(pf->timestamp));
|
|
||||||
|
|
||||||
iio_push_to_buffers(indio_dev, (u8 *)buf);
|
|
||||||
iio_trigger_notify_done(indio_dev->trig);
|
iio_trigger_notify_done(indio_dev->trig);
|
||||||
|
|
||||||
error_ret:
|
error_ret:
|
||||||
|
|
|
@ -305,8 +305,9 @@ static const struct iio_trigger_ops st_gyro_trigger_ops = {
|
||||||
int st_gyro_common_probe(struct iio_dev *indio_dev,
|
int st_gyro_common_probe(struct iio_dev *indio_dev,
|
||||||
struct st_sensors_platform_data *pdata)
|
struct st_sensors_platform_data *pdata)
|
||||||
{
|
{
|
||||||
int err;
|
|
||||||
struct st_sensor_data *gdata = iio_priv(indio_dev);
|
struct st_sensor_data *gdata = iio_priv(indio_dev);
|
||||||
|
int irq = gdata->get_irq_data_ready(indio_dev);
|
||||||
|
int err;
|
||||||
|
|
||||||
indio_dev->modes = INDIO_DIRECT_MODE;
|
indio_dev->modes = INDIO_DIRECT_MODE;
|
||||||
indio_dev->info = &gyro_info;
|
indio_dev->info = &gyro_info;
|
||||||
|
@ -314,7 +315,7 @@ int st_gyro_common_probe(struct iio_dev *indio_dev,
|
||||||
err = st_sensors_check_device_support(indio_dev,
|
err = st_sensors_check_device_support(indio_dev,
|
||||||
ARRAY_SIZE(st_gyro_sensors), st_gyro_sensors);
|
ARRAY_SIZE(st_gyro_sensors), st_gyro_sensors);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto st_gyro_common_probe_error;
|
return err;
|
||||||
|
|
||||||
gdata->num_data_channels = ST_GYRO_NUMBER_DATA_CHANNELS;
|
gdata->num_data_channels = ST_GYRO_NUMBER_DATA_CHANNELS;
|
||||||
gdata->multiread_bit = gdata->sensor->multi_read_bit;
|
gdata->multiread_bit = gdata->sensor->multi_read_bit;
|
||||||
|
@ -327,13 +328,13 @@ int st_gyro_common_probe(struct iio_dev *indio_dev,
|
||||||
|
|
||||||
err = st_sensors_init_sensor(indio_dev, pdata);
|
err = st_sensors_init_sensor(indio_dev, pdata);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto st_gyro_common_probe_error;
|
return err;
|
||||||
|
|
||||||
if (gdata->get_irq_data_ready(indio_dev) > 0) {
|
err = st_gyro_allocate_ring(indio_dev);
|
||||||
err = st_gyro_allocate_ring(indio_dev);
|
if (err < 0)
|
||||||
if (err < 0)
|
return err;
|
||||||
goto st_gyro_common_probe_error;
|
|
||||||
|
|
||||||
|
if (irq > 0) {
|
||||||
err = st_sensors_allocate_trigger(indio_dev,
|
err = st_sensors_allocate_trigger(indio_dev,
|
||||||
ST_GYRO_TRIGGER_OPS);
|
ST_GYRO_TRIGGER_OPS);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
|
@ -344,15 +345,14 @@ int st_gyro_common_probe(struct iio_dev *indio_dev,
|
||||||
if (err)
|
if (err)
|
||||||
goto st_gyro_device_register_error;
|
goto st_gyro_device_register_error;
|
||||||
|
|
||||||
return err;
|
return 0;
|
||||||
|
|
||||||
st_gyro_device_register_error:
|
st_gyro_device_register_error:
|
||||||
if (gdata->get_irq_data_ready(indio_dev) > 0)
|
if (irq > 0)
|
||||||
st_sensors_deallocate_trigger(indio_dev);
|
st_sensors_deallocate_trigger(indio_dev);
|
||||||
st_gyro_probe_trigger_error:
|
st_gyro_probe_trigger_error:
|
||||||
if (gdata->get_irq_data_ready(indio_dev) > 0)
|
st_gyro_deallocate_ring(indio_dev);
|
||||||
st_gyro_deallocate_ring(indio_dev);
|
|
||||||
st_gyro_common_probe_error:
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(st_gyro_common_probe);
|
EXPORT_SYMBOL(st_gyro_common_probe);
|
||||||
|
@ -362,10 +362,10 @@ void st_gyro_common_remove(struct iio_dev *indio_dev)
|
||||||
struct st_sensor_data *gdata = iio_priv(indio_dev);
|
struct st_sensor_data *gdata = iio_priv(indio_dev);
|
||||||
|
|
||||||
iio_device_unregister(indio_dev);
|
iio_device_unregister(indio_dev);
|
||||||
if (gdata->get_irq_data_ready(indio_dev) > 0) {
|
if (gdata->get_irq_data_ready(indio_dev) > 0)
|
||||||
st_sensors_deallocate_trigger(indio_dev);
|
st_sensors_deallocate_trigger(indio_dev);
|
||||||
st_gyro_deallocate_ring(indio_dev);
|
|
||||||
}
|
st_gyro_deallocate_ring(indio_dev);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(st_gyro_common_remove);
|
EXPORT_SYMBOL(st_gyro_common_remove);
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ int __iio_add_chan_devattr(const char *postfix,
|
||||||
const char *buf,
|
const char *buf,
|
||||||
size_t len),
|
size_t len),
|
||||||
u64 mask,
|
u64 mask,
|
||||||
bool generic,
|
enum iio_shared_by shared_by,
|
||||||
struct device *dev,
|
struct device *dev,
|
||||||
struct list_head *attr_list);
|
struct list_head *attr_list);
|
||||||
|
|
||||||
|
|
|
@ -82,13 +82,8 @@ irqreturn_t adis16400_trigger_handler(int irq, void *p)
|
||||||
spi_setup(st->adis.spi);
|
spi_setup(st->adis.spi);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Guaranteed to be aligned with 8 byte boundary */
|
iio_push_to_buffers_with_timestamp(indio_dev, adis->buffer,
|
||||||
if (indio_dev->scan_timestamp) {
|
pf->timestamp);
|
||||||
void *b = adis->buffer + indio_dev->scan_bytes - sizeof(s64);
|
|
||||||
*(s64 *)b = pf->timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
iio_push_to_buffers(indio_dev, adis->buffer);
|
|
||||||
|
|
||||||
iio_trigger_notify_done(indio_dev->trig);
|
iio_trigger_notify_done(indio_dev->trig);
|
||||||
|
|
||||||
|
|
|
@ -102,13 +102,8 @@ static irqreturn_t adis_trigger_handler(int irq, void *p)
|
||||||
mutex_unlock(&adis->txrx_lock);
|
mutex_unlock(&adis->txrx_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Guaranteed to be aligned with 8 byte boundary */
|
iio_push_to_buffers_with_timestamp(indio_dev, adis->buffer,
|
||||||
if (indio_dev->scan_timestamp) {
|
pf->timestamp);
|
||||||
void *b = adis->buffer + indio_dev->scan_bytes - sizeof(s64);
|
|
||||||
*(s64 *)b = pf->timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
iio_push_to_buffers(indio_dev, adis->buffer);
|
|
||||||
|
|
||||||
iio_trigger_notify_done(indio_dev->trig);
|
iio_trigger_notify_done(indio_dev->trig);
|
||||||
|
|
||||||
|
|
|
@ -124,7 +124,6 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p)
|
||||||
u8 data[INV_MPU6050_OUTPUT_DATA_SIZE];
|
u8 data[INV_MPU6050_OUTPUT_DATA_SIZE];
|
||||||
u16 fifo_count;
|
u16 fifo_count;
|
||||||
s64 timestamp;
|
s64 timestamp;
|
||||||
u64 *tmp;
|
|
||||||
|
|
||||||
mutex_lock(&indio_dev->mlock);
|
mutex_lock(&indio_dev->mlock);
|
||||||
if (!(st->chip_config.accl_fifo_enable |
|
if (!(st->chip_config.accl_fifo_enable |
|
||||||
|
@ -170,9 +169,8 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p)
|
||||||
if (0 == result)
|
if (0 == result)
|
||||||
timestamp = 0;
|
timestamp = 0;
|
||||||
|
|
||||||
tmp = (u64 *)data;
|
result = iio_push_to_buffers_with_timestamp(indio_dev, data,
|
||||||
tmp[DIV_ROUND_UP(bytes_per_datum, 8)] = timestamp;
|
timestamp);
|
||||||
result = iio_push_to_buffers(indio_dev, data);
|
|
||||||
if (result)
|
if (result)
|
||||||
goto flush_fifo;
|
goto flush_fifo;
|
||||||
fifo_count -= bytes_per_datum;
|
fifo_count -= bytes_per_datum;
|
||||||
|
|
|
@ -31,16 +31,9 @@ static const char * const iio_endian_prefix[] = {
|
||||||
[IIO_LE] = "le",
|
[IIO_LE] = "le",
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool iio_buffer_is_active(struct iio_dev *indio_dev,
|
static bool iio_buffer_is_active(struct iio_buffer *buf)
|
||||||
struct iio_buffer *buf)
|
|
||||||
{
|
{
|
||||||
struct list_head *p;
|
return !list_empty(&buf->buffer_list);
|
||||||
|
|
||||||
list_for_each(p, &indio_dev->buffer_list)
|
|
||||||
if (p == &buf->buffer_list)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -79,6 +72,7 @@ unsigned int iio_buffer_poll(struct file *filp,
|
||||||
void iio_buffer_init(struct iio_buffer *buffer)
|
void iio_buffer_init(struct iio_buffer *buffer)
|
||||||
{
|
{
|
||||||
INIT_LIST_HEAD(&buffer->demux_list);
|
INIT_LIST_HEAD(&buffer->demux_list);
|
||||||
|
INIT_LIST_HEAD(&buffer->buffer_list);
|
||||||
init_waitqueue_head(&buffer->pollq);
|
init_waitqueue_head(&buffer->pollq);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(iio_buffer_init);
|
EXPORT_SYMBOL(iio_buffer_init);
|
||||||
|
@ -146,7 +140,7 @@ static ssize_t iio_scan_el_store(struct device *dev,
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
mutex_lock(&indio_dev->mlock);
|
mutex_lock(&indio_dev->mlock);
|
||||||
if (iio_buffer_is_active(indio_dev, indio_dev->buffer)) {
|
if (iio_buffer_is_active(indio_dev->buffer)) {
|
||||||
ret = -EBUSY;
|
ret = -EBUSY;
|
||||||
goto error_ret;
|
goto error_ret;
|
||||||
}
|
}
|
||||||
|
@ -192,7 +186,7 @@ static ssize_t iio_scan_el_ts_store(struct device *dev,
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
mutex_lock(&indio_dev->mlock);
|
mutex_lock(&indio_dev->mlock);
|
||||||
if (iio_buffer_is_active(indio_dev, indio_dev->buffer)) {
|
if (iio_buffer_is_active(indio_dev->buffer)) {
|
||||||
ret = -EBUSY;
|
ret = -EBUSY;
|
||||||
goto error_ret;
|
goto error_ret;
|
||||||
}
|
}
|
||||||
|
@ -214,7 +208,7 @@ static int iio_buffer_add_channel_sysfs(struct iio_dev *indio_dev,
|
||||||
&iio_show_scan_index,
|
&iio_show_scan_index,
|
||||||
NULL,
|
NULL,
|
||||||
0,
|
0,
|
||||||
0,
|
IIO_SEPARATE,
|
||||||
&indio_dev->dev,
|
&indio_dev->dev,
|
||||||
&buffer->scan_el_dev_attr_list);
|
&buffer->scan_el_dev_attr_list);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -249,6 +243,8 @@ static int iio_buffer_add_channel_sysfs(struct iio_dev *indio_dev,
|
||||||
0,
|
0,
|
||||||
&indio_dev->dev,
|
&indio_dev->dev,
|
||||||
&buffer->scan_el_dev_attr_list);
|
&buffer->scan_el_dev_attr_list);
|
||||||
|
if (ret)
|
||||||
|
goto error_ret;
|
||||||
attrcount++;
|
attrcount++;
|
||||||
ret = attrcount;
|
ret = attrcount;
|
||||||
error_ret:
|
error_ret:
|
||||||
|
@ -396,7 +392,7 @@ ssize_t iio_buffer_write_length(struct device *dev,
|
||||||
return len;
|
return len;
|
||||||
|
|
||||||
mutex_lock(&indio_dev->mlock);
|
mutex_lock(&indio_dev->mlock);
|
||||||
if (iio_buffer_is_active(indio_dev, indio_dev->buffer)) {
|
if (iio_buffer_is_active(indio_dev->buffer)) {
|
||||||
ret = -EBUSY;
|
ret = -EBUSY;
|
||||||
} else {
|
} else {
|
||||||
if (buffer->access->set_length)
|
if (buffer->access->set_length)
|
||||||
|
@ -414,13 +410,11 @@ ssize_t iio_buffer_show_enable(struct device *dev,
|
||||||
char *buf)
|
char *buf)
|
||||||
{
|
{
|
||||||
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
||||||
return sprintf(buf, "%d\n",
|
return sprintf(buf, "%d\n", iio_buffer_is_active(indio_dev->buffer));
|
||||||
iio_buffer_is_active(indio_dev,
|
|
||||||
indio_dev->buffer));
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(iio_buffer_show_enable);
|
EXPORT_SYMBOL(iio_buffer_show_enable);
|
||||||
|
|
||||||
/* note NULL used as error indicator as it doesn't make sense. */
|
/* Note NULL used as error indicator as it doesn't make sense. */
|
||||||
static const unsigned long *iio_scan_mask_match(const unsigned long *av_masks,
|
static const unsigned long *iio_scan_mask_match(const unsigned long *av_masks,
|
||||||
unsigned int masklength,
|
unsigned int masklength,
|
||||||
const unsigned long *mask)
|
const unsigned long *mask)
|
||||||
|
@ -435,8 +429,8 @@ static const unsigned long *iio_scan_mask_match(const unsigned long *av_masks,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int iio_compute_scan_bytes(struct iio_dev *indio_dev, const long *mask,
|
static int iio_compute_scan_bytes(struct iio_dev *indio_dev,
|
||||||
bool timestamp)
|
const unsigned long *mask, bool timestamp)
|
||||||
{
|
{
|
||||||
const struct iio_chan_spec *ch;
|
const struct iio_chan_spec *ch;
|
||||||
unsigned bytes = 0;
|
unsigned bytes = 0;
|
||||||
|
@ -490,7 +484,7 @@ int iio_update_buffers(struct iio_dev *indio_dev,
|
||||||
indio_dev->active_scan_mask = NULL;
|
indio_dev->active_scan_mask = NULL;
|
||||||
|
|
||||||
if (remove_buffer)
|
if (remove_buffer)
|
||||||
list_del(&remove_buffer->buffer_list);
|
list_del_init(&remove_buffer->buffer_list);
|
||||||
if (insert_buffer)
|
if (insert_buffer)
|
||||||
list_add(&insert_buffer->buffer_list, &indio_dev->buffer_list);
|
list_add(&insert_buffer->buffer_list, &indio_dev->buffer_list);
|
||||||
|
|
||||||
|
@ -502,7 +496,7 @@ int iio_update_buffers(struct iio_dev *indio_dev,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* What scan mask do we actually have ?*/
|
/* What scan mask do we actually have? */
|
||||||
compound_mask = kcalloc(BITS_TO_LONGS(indio_dev->masklength),
|
compound_mask = kcalloc(BITS_TO_LONGS(indio_dev->masklength),
|
||||||
sizeof(long), GFP_KERNEL);
|
sizeof(long), GFP_KERNEL);
|
||||||
if (compound_mask == NULL) {
|
if (compound_mask == NULL) {
|
||||||
|
@ -527,7 +521,7 @@ int iio_update_buffers(struct iio_dev *indio_dev,
|
||||||
* Roll back.
|
* Roll back.
|
||||||
* Note can only occur when adding a buffer.
|
* Note can only occur when adding a buffer.
|
||||||
*/
|
*/
|
||||||
list_del(&insert_buffer->buffer_list);
|
list_del_init(&insert_buffer->buffer_list);
|
||||||
indio_dev->active_scan_mask = old_mask;
|
indio_dev->active_scan_mask = old_mask;
|
||||||
success = -EINVAL;
|
success = -EINVAL;
|
||||||
}
|
}
|
||||||
|
@ -568,7 +562,7 @@ int iio_update_buffers(struct iio_dev *indio_dev,
|
||||||
goto error_run_postdisable;
|
goto error_run_postdisable;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Definitely possible for devices to support both of these.*/
|
/* Definitely possible for devices to support both of these. */
|
||||||
if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) {
|
if (indio_dev->modes & INDIO_BUFFER_TRIGGERED) {
|
||||||
if (!indio_dev->trig) {
|
if (!indio_dev->trig) {
|
||||||
printk(KERN_INFO "Buffer not started: no trigger\n");
|
printk(KERN_INFO "Buffer not started: no trigger\n");
|
||||||
|
@ -579,7 +573,7 @@ int iio_update_buffers(struct iio_dev *indio_dev,
|
||||||
indio_dev->currentmode = INDIO_BUFFER_TRIGGERED;
|
indio_dev->currentmode = INDIO_BUFFER_TRIGGERED;
|
||||||
} else if (indio_dev->modes & INDIO_BUFFER_HARDWARE) {
|
} else if (indio_dev->modes & INDIO_BUFFER_HARDWARE) {
|
||||||
indio_dev->currentmode = INDIO_BUFFER_HARDWARE;
|
indio_dev->currentmode = INDIO_BUFFER_HARDWARE;
|
||||||
} else { /* should never be reached */
|
} else { /* Should never be reached */
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto error_run_postdisable;
|
goto error_run_postdisable;
|
||||||
}
|
}
|
||||||
|
@ -611,7 +605,7 @@ error_run_postdisable:
|
||||||
error_remove_inserted:
|
error_remove_inserted:
|
||||||
|
|
||||||
if (insert_buffer)
|
if (insert_buffer)
|
||||||
list_del(&insert_buffer->buffer_list);
|
list_del_init(&insert_buffer->buffer_list);
|
||||||
indio_dev->active_scan_mask = old_mask;
|
indio_dev->active_scan_mask = old_mask;
|
||||||
kfree(compound_mask);
|
kfree(compound_mask);
|
||||||
error_ret:
|
error_ret:
|
||||||
|
@ -628,7 +622,6 @@ ssize_t iio_buffer_store_enable(struct device *dev,
|
||||||
int ret;
|
int ret;
|
||||||
bool requested_state;
|
bool requested_state;
|
||||||
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
||||||
struct iio_buffer *pbuf = indio_dev->buffer;
|
|
||||||
bool inlist;
|
bool inlist;
|
||||||
|
|
||||||
ret = strtobool(buf, &requested_state);
|
ret = strtobool(buf, &requested_state);
|
||||||
|
@ -638,7 +631,7 @@ ssize_t iio_buffer_store_enable(struct device *dev,
|
||||||
mutex_lock(&indio_dev->mlock);
|
mutex_lock(&indio_dev->mlock);
|
||||||
|
|
||||||
/* Find out if it is in the list */
|
/* Find out if it is in the list */
|
||||||
inlist = iio_buffer_is_active(indio_dev, pbuf);
|
inlist = iio_buffer_is_active(indio_dev->buffer);
|
||||||
/* Already in desired state */
|
/* Already in desired state */
|
||||||
if (inlist == requested_state)
|
if (inlist == requested_state)
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -703,6 +696,7 @@ static bool iio_validate_scan_mask(struct iio_dev *indio_dev,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* iio_scan_mask_set() - set particular bit in the scan mask
|
* iio_scan_mask_set() - set particular bit in the scan mask
|
||||||
|
* @indio_dev: the iio device
|
||||||
* @buffer: the buffer whose scan mask we are interested in
|
* @buffer: the buffer whose scan mask we are interested in
|
||||||
* @bit: the bit to be set.
|
* @bit: the bit to be set.
|
||||||
*
|
*
|
||||||
|
@ -723,7 +717,7 @@ int iio_scan_mask_set(struct iio_dev *indio_dev,
|
||||||
if (trialmask == NULL)
|
if (trialmask == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
if (!indio_dev->masklength) {
|
if (!indio_dev->masklength) {
|
||||||
WARN_ON("trying to set scanmask prior to registering buffer\n");
|
WARN_ON("Trying to set scanmask prior to registering buffer\n");
|
||||||
goto err_invalid_mask;
|
goto err_invalid_mask;
|
||||||
}
|
}
|
||||||
bitmap_copy(trialmask, buffer->scan_mask, indio_dev->masklength);
|
bitmap_copy(trialmask, buffer->scan_mask, indio_dev->masklength);
|
||||||
|
@ -778,8 +772,8 @@ struct iio_demux_table {
|
||||||
struct list_head l;
|
struct list_head l;
|
||||||
};
|
};
|
||||||
|
|
||||||
static unsigned char *iio_demux(struct iio_buffer *buffer,
|
static const void *iio_demux(struct iio_buffer *buffer,
|
||||||
unsigned char *datain)
|
const void *datain)
|
||||||
{
|
{
|
||||||
struct iio_demux_table *t;
|
struct iio_demux_table *t;
|
||||||
|
|
||||||
|
@ -792,9 +786,9 @@ static unsigned char *iio_demux(struct iio_buffer *buffer,
|
||||||
return buffer->demux_bounce;
|
return buffer->demux_bounce;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int iio_push_to_buffer(struct iio_buffer *buffer, unsigned char *data)
|
static int iio_push_to_buffer(struct iio_buffer *buffer, const void *data)
|
||||||
{
|
{
|
||||||
unsigned char *dataout = iio_demux(buffer, data);
|
const void *dataout = iio_demux(buffer, data);
|
||||||
|
|
||||||
return buffer->access->store_to(buffer, dataout);
|
return buffer->access->store_to(buffer, dataout);
|
||||||
}
|
}
|
||||||
|
@ -809,7 +803,7 @@ static void iio_buffer_demux_free(struct iio_buffer *buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int iio_push_to_buffers(struct iio_dev *indio_dev, unsigned char *data)
|
int iio_push_to_buffers(struct iio_dev *indio_dev, const void *data)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct iio_buffer *buf;
|
struct iio_buffer *buf;
|
||||||
|
|
|
@ -101,6 +101,7 @@ static const char * const iio_chan_info_postfix[] = {
|
||||||
[IIO_CHAN_INFO_PHASE] = "phase",
|
[IIO_CHAN_INFO_PHASE] = "phase",
|
||||||
[IIO_CHAN_INFO_HARDWAREGAIN] = "hardwaregain",
|
[IIO_CHAN_INFO_HARDWAREGAIN] = "hardwaregain",
|
||||||
[IIO_CHAN_INFO_HYSTERESIS] = "hysteresis",
|
[IIO_CHAN_INFO_HYSTERESIS] = "hysteresis",
|
||||||
|
[IIO_CHAN_INFO_INT_TIME] = "integration_time",
|
||||||
};
|
};
|
||||||
|
|
||||||
const struct iio_chan_spec
|
const struct iio_chan_spec
|
||||||
|
@ -516,14 +517,15 @@ int __iio_device_attr_init(struct device_attribute *dev_attr,
|
||||||
struct device_attribute *attr,
|
struct device_attribute *attr,
|
||||||
const char *buf,
|
const char *buf,
|
||||||
size_t len),
|
size_t len),
|
||||||
bool generic)
|
enum iio_shared_by shared_by)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret = 0;
|
||||||
char *name_format, *full_postfix;
|
char *name_format = NULL;
|
||||||
|
char *full_postfix;
|
||||||
sysfs_attr_init(&dev_attr->attr);
|
sysfs_attr_init(&dev_attr->attr);
|
||||||
|
|
||||||
/* Build up postfix of <extend_name>_<modifier>_postfix */
|
/* Build up postfix of <extend_name>_<modifier>_postfix */
|
||||||
if (chan->modified && !generic) {
|
if (chan->modified && (shared_by == IIO_SEPARATE)) {
|
||||||
if (chan->extend_name)
|
if (chan->extend_name)
|
||||||
full_postfix = kasprintf(GFP_KERNEL, "%s_%s_%s",
|
full_postfix = kasprintf(GFP_KERNEL, "%s_%s_%s",
|
||||||
iio_modifier_names[chan
|
iio_modifier_names[chan
|
||||||
|
@ -544,53 +546,78 @@ int __iio_device_attr_init(struct device_attribute *dev_attr,
|
||||||
chan->extend_name,
|
chan->extend_name,
|
||||||
postfix);
|
postfix);
|
||||||
}
|
}
|
||||||
if (full_postfix == NULL) {
|
if (full_postfix == NULL)
|
||||||
ret = -ENOMEM;
|
return -ENOMEM;
|
||||||
goto error_ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (chan->differential) { /* Differential can not have modifier */
|
if (chan->differential) { /* Differential can not have modifier */
|
||||||
if (generic)
|
switch (shared_by) {
|
||||||
|
case IIO_SHARED_BY_ALL:
|
||||||
|
name_format = kasprintf(GFP_KERNEL, "%s", full_postfix);
|
||||||
|
break;
|
||||||
|
case IIO_SHARED_BY_DIR:
|
||||||
|
name_format = kasprintf(GFP_KERNEL, "%s_%s",
|
||||||
|
iio_direction[chan->output],
|
||||||
|
full_postfix);
|
||||||
|
break;
|
||||||
|
case IIO_SHARED_BY_TYPE:
|
||||||
name_format
|
name_format
|
||||||
= kasprintf(GFP_KERNEL, "%s_%s-%s_%s",
|
= kasprintf(GFP_KERNEL, "%s_%s-%s_%s",
|
||||||
iio_direction[chan->output],
|
iio_direction[chan->output],
|
||||||
iio_chan_type_name_spec[chan->type],
|
iio_chan_type_name_spec[chan->type],
|
||||||
iio_chan_type_name_spec[chan->type],
|
iio_chan_type_name_spec[chan->type],
|
||||||
full_postfix);
|
full_postfix);
|
||||||
else if (chan->indexed)
|
break;
|
||||||
|
case IIO_SEPARATE:
|
||||||
|
if (!chan->indexed) {
|
||||||
|
WARN_ON("Differential channels must be indexed\n");
|
||||||
|
ret = -EINVAL;
|
||||||
|
goto error_free_full_postfix;
|
||||||
|
}
|
||||||
name_format
|
name_format
|
||||||
= kasprintf(GFP_KERNEL, "%s_%s%d-%s%d_%s",
|
= kasprintf(GFP_KERNEL,
|
||||||
|
"%s_%s%d-%s%d_%s",
|
||||||
iio_direction[chan->output],
|
iio_direction[chan->output],
|
||||||
iio_chan_type_name_spec[chan->type],
|
iio_chan_type_name_spec[chan->type],
|
||||||
chan->channel,
|
chan->channel,
|
||||||
iio_chan_type_name_spec[chan->type],
|
iio_chan_type_name_spec[chan->type],
|
||||||
chan->channel2,
|
chan->channel2,
|
||||||
full_postfix);
|
full_postfix);
|
||||||
else {
|
break;
|
||||||
WARN_ON("Differential channels must be indexed\n");
|
|
||||||
ret = -EINVAL;
|
|
||||||
goto error_free_full_postfix;
|
|
||||||
}
|
}
|
||||||
} else { /* Single ended */
|
} else { /* Single ended */
|
||||||
if (generic)
|
switch (shared_by) {
|
||||||
name_format
|
case IIO_SHARED_BY_ALL:
|
||||||
= kasprintf(GFP_KERNEL, "%s_%s_%s",
|
name_format = kasprintf(GFP_KERNEL, "%s", full_postfix);
|
||||||
iio_direction[chan->output],
|
break;
|
||||||
iio_chan_type_name_spec[chan->type],
|
case IIO_SHARED_BY_DIR:
|
||||||
full_postfix);
|
name_format = kasprintf(GFP_KERNEL, "%s_%s",
|
||||||
else if (chan->indexed)
|
iio_direction[chan->output],
|
||||||
name_format
|
full_postfix);
|
||||||
= kasprintf(GFP_KERNEL, "%s_%s%d_%s",
|
break;
|
||||||
iio_direction[chan->output],
|
case IIO_SHARED_BY_TYPE:
|
||||||
iio_chan_type_name_spec[chan->type],
|
|
||||||
chan->channel,
|
|
||||||
full_postfix);
|
|
||||||
else
|
|
||||||
name_format
|
name_format
|
||||||
= kasprintf(GFP_KERNEL, "%s_%s_%s",
|
= kasprintf(GFP_KERNEL, "%s_%s_%s",
|
||||||
iio_direction[chan->output],
|
iio_direction[chan->output],
|
||||||
iio_chan_type_name_spec[chan->type],
|
iio_chan_type_name_spec[chan->type],
|
||||||
full_postfix);
|
full_postfix);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IIO_SEPARATE:
|
||||||
|
if (chan->indexed)
|
||||||
|
name_format
|
||||||
|
= kasprintf(GFP_KERNEL, "%s_%s%d_%s",
|
||||||
|
iio_direction[chan->output],
|
||||||
|
iio_chan_type_name_spec[chan->type],
|
||||||
|
chan->channel,
|
||||||
|
full_postfix);
|
||||||
|
else
|
||||||
|
name_format
|
||||||
|
= kasprintf(GFP_KERNEL, "%s_%s_%s",
|
||||||
|
iio_direction[chan->output],
|
||||||
|
iio_chan_type_name_spec[chan->type],
|
||||||
|
full_postfix);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (name_format == NULL) {
|
if (name_format == NULL) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
|
@ -614,16 +641,11 @@ int __iio_device_attr_init(struct device_attribute *dev_attr,
|
||||||
dev_attr->attr.mode |= S_IWUSR;
|
dev_attr->attr.mode |= S_IWUSR;
|
||||||
dev_attr->store = writefunc;
|
dev_attr->store = writefunc;
|
||||||
}
|
}
|
||||||
kfree(name_format);
|
|
||||||
kfree(full_postfix);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
error_free_name_format:
|
error_free_name_format:
|
||||||
kfree(name_format);
|
kfree(name_format);
|
||||||
error_free_full_postfix:
|
error_free_full_postfix:
|
||||||
kfree(full_postfix);
|
kfree(full_postfix);
|
||||||
error_ret:
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -642,7 +664,7 @@ int __iio_add_chan_devattr(const char *postfix,
|
||||||
const char *buf,
|
const char *buf,
|
||||||
size_t len),
|
size_t len),
|
||||||
u64 mask,
|
u64 mask,
|
||||||
bool generic,
|
enum iio_shared_by shared_by,
|
||||||
struct device *dev,
|
struct device *dev,
|
||||||
struct list_head *attr_list)
|
struct list_head *attr_list)
|
||||||
{
|
{
|
||||||
|
@ -656,7 +678,7 @@ int __iio_add_chan_devattr(const char *postfix,
|
||||||
}
|
}
|
||||||
ret = __iio_device_attr_init(&iio_attr->dev_attr,
|
ret = __iio_device_attr_init(&iio_attr->dev_attr,
|
||||||
postfix, chan,
|
postfix, chan,
|
||||||
readfunc, writefunc, generic);
|
readfunc, writefunc, shared_by);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_iio_dev_attr_free;
|
goto error_iio_dev_attr_free;
|
||||||
iio_attr->c = chan;
|
iio_attr->c = chan;
|
||||||
|
@ -664,7 +686,7 @@ int __iio_add_chan_devattr(const char *postfix,
|
||||||
list_for_each_entry(t, attr_list, l)
|
list_for_each_entry(t, attr_list, l)
|
||||||
if (strcmp(t->dev_attr.attr.name,
|
if (strcmp(t->dev_attr.attr.name,
|
||||||
iio_attr->dev_attr.attr.name) == 0) {
|
iio_attr->dev_attr.attr.name) == 0) {
|
||||||
if (!generic)
|
if (shared_by == IIO_SEPARATE)
|
||||||
dev_err(dev, "tried to double register : %s\n",
|
dev_err(dev, "tried to double register : %s\n",
|
||||||
t->dev_attr.attr.name);
|
t->dev_attr.attr.name);
|
||||||
ret = -EBUSY;
|
ret = -EBUSY;
|
||||||
|
@ -682,45 +704,67 @@ error_ret:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int iio_device_add_info_mask_type(struct iio_dev *indio_dev,
|
||||||
|
struct iio_chan_spec const *chan,
|
||||||
|
enum iio_shared_by shared_by,
|
||||||
|
const long *infomask)
|
||||||
|
{
|
||||||
|
int i, ret, attrcount = 0;
|
||||||
|
|
||||||
|
for_each_set_bit(i, infomask, sizeof(infomask)*8) {
|
||||||
|
ret = __iio_add_chan_devattr(iio_chan_info_postfix[i],
|
||||||
|
chan,
|
||||||
|
&iio_read_channel_info,
|
||||||
|
&iio_write_channel_info,
|
||||||
|
i,
|
||||||
|
shared_by,
|
||||||
|
&indio_dev->dev,
|
||||||
|
&indio_dev->channel_attr_list);
|
||||||
|
if ((ret == -EBUSY) && (shared_by != IIO_SEPARATE))
|
||||||
|
continue;
|
||||||
|
else if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
attrcount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return attrcount;
|
||||||
|
}
|
||||||
|
|
||||||
static int iio_device_add_channel_sysfs(struct iio_dev *indio_dev,
|
static int iio_device_add_channel_sysfs(struct iio_dev *indio_dev,
|
||||||
struct iio_chan_spec const *chan)
|
struct iio_chan_spec const *chan)
|
||||||
{
|
{
|
||||||
int ret, attrcount = 0;
|
int ret, attrcount = 0;
|
||||||
int i;
|
|
||||||
const struct iio_chan_spec_ext_info *ext_info;
|
const struct iio_chan_spec_ext_info *ext_info;
|
||||||
|
|
||||||
if (chan->channel < 0)
|
if (chan->channel < 0)
|
||||||
return 0;
|
return 0;
|
||||||
for_each_set_bit(i, &chan->info_mask_separate, sizeof(long)*8) {
|
ret = iio_device_add_info_mask_type(indio_dev, chan,
|
||||||
ret = __iio_add_chan_devattr(iio_chan_info_postfix[i],
|
IIO_SEPARATE,
|
||||||
chan,
|
&chan->info_mask_separate);
|
||||||
&iio_read_channel_info,
|
if (ret < 0)
|
||||||
&iio_write_channel_info,
|
return ret;
|
||||||
i,
|
attrcount += ret;
|
||||||
0,
|
|
||||||
&indio_dev->dev,
|
ret = iio_device_add_info_mask_type(indio_dev, chan,
|
||||||
&indio_dev->channel_attr_list);
|
IIO_SHARED_BY_TYPE,
|
||||||
if (ret < 0)
|
&chan->info_mask_shared_by_type);
|
||||||
goto error_ret;
|
if (ret < 0)
|
||||||
attrcount++;
|
return ret;
|
||||||
}
|
attrcount += ret;
|
||||||
for_each_set_bit(i, &chan->info_mask_shared_by_type, sizeof(long)*8) {
|
|
||||||
ret = __iio_add_chan_devattr(iio_chan_info_postfix[i],
|
ret = iio_device_add_info_mask_type(indio_dev, chan,
|
||||||
chan,
|
IIO_SHARED_BY_DIR,
|
||||||
&iio_read_channel_info,
|
&chan->info_mask_shared_by_dir);
|
||||||
&iio_write_channel_info,
|
if (ret < 0)
|
||||||
i,
|
return ret;
|
||||||
1,
|
attrcount += ret;
|
||||||
&indio_dev->dev,
|
|
||||||
&indio_dev->channel_attr_list);
|
ret = iio_device_add_info_mask_type(indio_dev, chan,
|
||||||
if (ret == -EBUSY) {
|
IIO_SHARED_BY_ALL,
|
||||||
ret = 0;
|
&chan->info_mask_shared_by_all);
|
||||||
continue;
|
if (ret < 0)
|
||||||
} else if (ret < 0) {
|
return ret;
|
||||||
goto error_ret;
|
attrcount += ret;
|
||||||
}
|
|
||||||
attrcount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (chan->ext_info) {
|
if (chan->ext_info) {
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
|
@ -740,15 +784,13 @@ static int iio_device_add_channel_sysfs(struct iio_dev *indio_dev,
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_ret;
|
return ret;
|
||||||
|
|
||||||
attrcount++;
|
attrcount++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = attrcount;
|
return attrcount;
|
||||||
error_ret:
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void iio_device_remove_and_free_read_attr(struct iio_dev *indio_dev,
|
static void iio_device_remove_and_free_read_attr(struct iio_dev *indio_dev,
|
||||||
|
|
|
@ -159,7 +159,7 @@ int iio_event_getfd(struct iio_dev *indio_dev)
|
||||||
}
|
}
|
||||||
spin_unlock_irq(&ev_int->wait.lock);
|
spin_unlock_irq(&ev_int->wait.lock);
|
||||||
fd = anon_inode_getfd("iio:event",
|
fd = anon_inode_getfd("iio:event",
|
||||||
&iio_event_chrdev_fileops, ev_int, O_RDONLY);
|
&iio_event_chrdev_fileops, ev_int, O_RDONLY | O_CLOEXEC);
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
spin_lock_irq(&ev_int->wait.lock);
|
spin_lock_irq(&ev_int->wait.lock);
|
||||||
__clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags);
|
__clear_bit(IIO_BUSY_BIT_POS, &ev_int->flags);
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#include <linux/mutex.h>
|
#include <linux/mutex.h>
|
||||||
#include <linux/iio/kfifo_buf.h>
|
#include <linux/iio/kfifo_buf.h>
|
||||||
#include <linux/sched.h>
|
#include <linux/sched.h>
|
||||||
|
#include <linux/poll.h>
|
||||||
|
|
||||||
struct iio_kfifo {
|
struct iio_kfifo {
|
||||||
struct iio_buffer buffer;
|
struct iio_buffer buffer;
|
||||||
|
@ -94,7 +95,7 @@ static int iio_set_length_kfifo(struct iio_buffer *r, int length)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int iio_store_to_kfifo(struct iio_buffer *r,
|
static int iio_store_to_kfifo(struct iio_buffer *r,
|
||||||
u8 *data)
|
const void *data)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct iio_kfifo *kf = iio_to_kfifo(r);
|
struct iio_kfifo *kf = iio_to_kfifo(r);
|
||||||
|
@ -102,7 +103,7 @@ static int iio_store_to_kfifo(struct iio_buffer *r,
|
||||||
if (ret != 1)
|
if (ret != 1)
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
r->stufftoread = true;
|
r->stufftoread = true;
|
||||||
wake_up_interruptible(&r->pollq);
|
wake_up_interruptible_poll(&r->pollq, POLLIN | POLLRDNORM);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,6 +27,18 @@ config APDS9300
|
||||||
To compile this driver as a module, choose M here: the
|
To compile this driver as a module, choose M here: the
|
||||||
module will be called apds9300.
|
module will be called apds9300.
|
||||||
|
|
||||||
|
config GP2AP020A00F
|
||||||
|
tristate "Sharp GP2AP020A00F Proximity/ALS sensor"
|
||||||
|
depends on I2C
|
||||||
|
select IIO_BUFFER
|
||||||
|
select IIO_TRIGGERED_BUFFER
|
||||||
|
help
|
||||||
|
Say Y here if you have a Sharp GP2AP020A00F proximity/ALS combo-chip
|
||||||
|
hooked to an I2C bus.
|
||||||
|
|
||||||
|
To compile this driver as a module, choose M here: the
|
||||||
|
module will be called gp2ap020a00f.
|
||||||
|
|
||||||
config HID_SENSOR_ALS
|
config HID_SENSOR_ALS
|
||||||
depends on HID_SENSOR_HUB
|
depends on HID_SENSOR_HUB
|
||||||
select IIO_BUFFER
|
select IIO_BUFFER
|
||||||
|
@ -55,6 +67,16 @@ config SENSORS_LM3533
|
||||||
changes. The ALS-control output values can be set per zone for the
|
changes. The ALS-control output values can be set per zone for the
|
||||||
three current output channels.
|
three current output channels.
|
||||||
|
|
||||||
|
config TCS3472
|
||||||
|
tristate "TAOS TCS3472 color light-to-digital converter"
|
||||||
|
depends on I2C
|
||||||
|
help
|
||||||
|
If you say yes here you get support for the TAOS TCS3472
|
||||||
|
family of color light-to-digital converters with IR filter.
|
||||||
|
|
||||||
|
This driver can also be built as a module. If so, the module
|
||||||
|
will be called tcs3472.
|
||||||
|
|
||||||
config SENSORS_TSL2563
|
config SENSORS_TSL2563
|
||||||
tristate "TAOS TSL2560, TSL2561, TSL2562 and TSL2563 ambient light sensors"
|
tristate "TAOS TSL2560, TSL2561, TSL2562 and TSL2563 ambient light sensors"
|
||||||
depends on I2C
|
depends on I2C
|
||||||
|
@ -65,6 +87,16 @@ config SENSORS_TSL2563
|
||||||
This driver can also be built as a module. If so, the module
|
This driver can also be built as a module. If so, the module
|
||||||
will be called tsl2563.
|
will be called tsl2563.
|
||||||
|
|
||||||
|
config TSL4531
|
||||||
|
tristate "TAOS TSL4531 ambient light sensors"
|
||||||
|
depends on I2C
|
||||||
|
help
|
||||||
|
Say Y here if you want to build a driver for the TAOS TSL4531 family
|
||||||
|
of ambient light sensors with direct lux output.
|
||||||
|
|
||||||
|
To compile this driver as a module, choose M here: the
|
||||||
|
module will be called tsl4531.
|
||||||
|
|
||||||
config VCNL4000
|
config VCNL4000
|
||||||
tristate "VCNL4000 combined ALS and proximity sensor"
|
tristate "VCNL4000 combined ALS and proximity sensor"
|
||||||
depends on I2C
|
depends on I2C
|
||||||
|
|
|
@ -5,7 +5,10 @@
|
||||||
# When adding new entries keep the list in alphabetical order
|
# When adding new entries keep the list in alphabetical order
|
||||||
obj-$(CONFIG_ADJD_S311) += adjd_s311.o
|
obj-$(CONFIG_ADJD_S311) += adjd_s311.o
|
||||||
obj-$(CONFIG_APDS9300) += apds9300.o
|
obj-$(CONFIG_APDS9300) += apds9300.o
|
||||||
|
obj-$(CONFIG_GP2AP020A00F) += gp2ap020a00f.o
|
||||||
obj-$(CONFIG_HID_SENSOR_ALS) += hid-sensor-als.o
|
obj-$(CONFIG_HID_SENSOR_ALS) += hid-sensor-als.o
|
||||||
obj-$(CONFIG_SENSORS_LM3533) += lm3533-als.o
|
obj-$(CONFIG_SENSORS_LM3533) += lm3533-als.o
|
||||||
obj-$(CONFIG_SENSORS_TSL2563) += tsl2563.o
|
obj-$(CONFIG_SENSORS_TSL2563) += tsl2563.o
|
||||||
|
obj-$(CONFIG_TCS3472) += tcs3472.o
|
||||||
|
obj-$(CONFIG_TSL4531) += tsl4531.o
|
||||||
obj-$(CONFIG_VCNL4000) += vcnl4000.o
|
obj-$(CONFIG_VCNL4000) += vcnl4000.o
|
||||||
|
|
|
@ -114,43 +114,6 @@ static int adjd_s311_read_data(struct iio_dev *indio_dev, u8 reg, int *val)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t adjd_s311_read_int_time(struct iio_dev *indio_dev,
|
|
||||||
uintptr_t private, const struct iio_chan_spec *chan, char *buf)
|
|
||||||
{
|
|
||||||
struct adjd_s311_data *data = iio_priv(indio_dev);
|
|
||||||
s32 ret;
|
|
||||||
|
|
||||||
ret = i2c_smbus_read_word_data(data->client,
|
|
||||||
ADJD_S311_INT_REG(chan->address));
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
return sprintf(buf, "%d\n", ret & ADJD_S311_INT_MASK);
|
|
||||||
}
|
|
||||||
|
|
||||||
static ssize_t adjd_s311_write_int_time(struct iio_dev *indio_dev,
|
|
||||||
uintptr_t private, const struct iio_chan_spec *chan, const char *buf,
|
|
||||||
size_t len)
|
|
||||||
{
|
|
||||||
struct adjd_s311_data *data = iio_priv(indio_dev);
|
|
||||||
unsigned long int_time;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = kstrtoul(buf, 10, &int_time);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
if (int_time > ADJD_S311_INT_MASK)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
ret = i2c_smbus_write_word_data(data->client,
|
|
||||||
ADJD_S311_INT_REG(chan->address), int_time);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
return len;
|
|
||||||
}
|
|
||||||
|
|
||||||
static irqreturn_t adjd_s311_trigger_handler(int irq, void *p)
|
static irqreturn_t adjd_s311_trigger_handler(int irq, void *p)
|
||||||
{
|
{
|
||||||
struct iio_poll_func *pf = p;
|
struct iio_poll_func *pf = p;
|
||||||
|
@ -175,10 +138,7 @@ static irqreturn_t adjd_s311_trigger_handler(int irq, void *p)
|
||||||
len += 2;
|
len += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (indio_dev->scan_timestamp)
|
iio_push_to_buffers_with_timestamp(indio_dev, data->buffer, time_ns);
|
||||||
*(s64 *)((u8 *)data->buffer + ALIGN(len, sizeof(s64)))
|
|
||||||
= time_ns;
|
|
||||||
iio_push_to_buffers(indio_dev, (u8 *)data->buffer);
|
|
||||||
|
|
||||||
done:
|
done:
|
||||||
iio_trigger_notify_done(indio_dev->trig);
|
iio_trigger_notify_done(indio_dev->trig);
|
||||||
|
@ -186,25 +146,16 @@ done:
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct iio_chan_spec_ext_info adjd_s311_ext_info[] = {
|
|
||||||
{
|
|
||||||
.name = "integration_time",
|
|
||||||
.read = adjd_s311_read_int_time,
|
|
||||||
.write = adjd_s311_write_int_time,
|
|
||||||
},
|
|
||||||
{ }
|
|
||||||
};
|
|
||||||
|
|
||||||
#define ADJD_S311_CHANNEL(_color, _scan_idx) { \
|
#define ADJD_S311_CHANNEL(_color, _scan_idx) { \
|
||||||
.type = IIO_INTENSITY, \
|
.type = IIO_INTENSITY, \
|
||||||
.modified = 1, \
|
.modified = 1, \
|
||||||
.address = (IDX_##_color), \
|
.address = (IDX_##_color), \
|
||||||
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
|
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
|
||||||
BIT(IIO_CHAN_INFO_HARDWAREGAIN), \
|
BIT(IIO_CHAN_INFO_HARDWAREGAIN) | \
|
||||||
|
BIT(IIO_CHAN_INFO_INT_TIME), \
|
||||||
.channel2 = (IIO_MOD_LIGHT_##_color), \
|
.channel2 = (IIO_MOD_LIGHT_##_color), \
|
||||||
.scan_index = (_scan_idx), \
|
.scan_index = (_scan_idx), \
|
||||||
.scan_type = IIO_ST('u', 10, 16, 0), \
|
.scan_type = IIO_ST('u', 10, 16, 0), \
|
||||||
.ext_info = adjd_s311_ext_info, \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct iio_chan_spec adjd_s311_channels[] = {
|
static const struct iio_chan_spec adjd_s311_channels[] = {
|
||||||
|
@ -236,6 +187,18 @@ static int adjd_s311_read_raw(struct iio_dev *indio_dev,
|
||||||
return ret;
|
return ret;
|
||||||
*val = ret & ADJD_S311_CAP_MASK;
|
*val = ret & ADJD_S311_CAP_MASK;
|
||||||
return IIO_VAL_INT;
|
return IIO_VAL_INT;
|
||||||
|
case IIO_CHAN_INFO_INT_TIME:
|
||||||
|
ret = i2c_smbus_read_word_data(data->client,
|
||||||
|
ADJD_S311_INT_REG(chan->address));
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
*val = 0;
|
||||||
|
/*
|
||||||
|
* not documented, based on measurement:
|
||||||
|
* 4095 LSBs correspond to roughly 4 ms
|
||||||
|
*/
|
||||||
|
*val2 = ret & ADJD_S311_INT_MASK;
|
||||||
|
return IIO_VAL_INT_PLUS_MICRO;
|
||||||
}
|
}
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
@ -245,16 +208,20 @@ static int adjd_s311_write_raw(struct iio_dev *indio_dev,
|
||||||
int val, int val2, long mask)
|
int val, int val2, long mask)
|
||||||
{
|
{
|
||||||
struct adjd_s311_data *data = iio_priv(indio_dev);
|
struct adjd_s311_data *data = iio_priv(indio_dev);
|
||||||
int ret;
|
|
||||||
|
|
||||||
switch (mask) {
|
switch (mask) {
|
||||||
case IIO_CHAN_INFO_HARDWAREGAIN:
|
case IIO_CHAN_INFO_HARDWAREGAIN:
|
||||||
if (val < 0 || val > ADJD_S311_CAP_MASK)
|
if (val < 0 || val > ADJD_S311_CAP_MASK)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
ret = i2c_smbus_write_byte_data(data->client,
|
return i2c_smbus_write_byte_data(data->client,
|
||||||
ADJD_S311_CAP_REG(chan->address), val);
|
ADJD_S311_CAP_REG(chan->address), val);
|
||||||
return ret;
|
case IIO_CHAN_INFO_INT_TIME:
|
||||||
|
if (val != 0 || val2 < 0 || val2 > ADJD_S311_INT_MASK)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
return i2c_smbus_write_word_data(data->client,
|
||||||
|
ADJD_S311_INT_REG(chan->address), val2);
|
||||||
}
|
}
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
1617
drivers/iio/light/gp2ap020a00f.c
Normal file
1617
drivers/iio/light/gp2ap020a00f.c
Normal file
File diff suppressed because it is too large
Load diff
|
@ -161,10 +161,11 @@ static const struct iio_info als_info = {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Function to push data to buffer */
|
/* Function to push data to buffer */
|
||||||
static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len)
|
static void hid_sensor_push_data(struct iio_dev *indio_dev, const void *data,
|
||||||
|
int len)
|
||||||
{
|
{
|
||||||
dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n");
|
dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n");
|
||||||
iio_push_to_buffers(indio_dev, (u8 *)data);
|
iio_push_to_buffers(indio_dev, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Callback handler to send event after all samples are received and captured */
|
/* Callback handler to send event after all samples are received and captured */
|
||||||
|
@ -179,7 +180,7 @@ static int als_proc_event(struct hid_sensor_hub_device *hsdev,
|
||||||
als_state->common_attributes.data_ready);
|
als_state->common_attributes.data_ready);
|
||||||
if (als_state->common_attributes.data_ready)
|
if (als_state->common_attributes.data_ready)
|
||||||
hid_sensor_push_data(indio_dev,
|
hid_sensor_push_data(indio_dev,
|
||||||
(u8 *)&als_state->illum,
|
&als_state->illum,
|
||||||
sizeof(als_state->illum));
|
sizeof(als_state->illum));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
367
drivers/iio/light/tcs3472.c
Normal file
367
drivers/iio/light/tcs3472.c
Normal file
|
@ -0,0 +1,367 @@
|
||||||
|
/*
|
||||||
|
* tcs3472.c - Support for TAOS TCS3472 color light-to-digital converter
|
||||||
|
*
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* Color light sensor with 16-bit channels for red, green, blue, clear);
|
||||||
|
* 7-bit I2C slave address 0x39 (TCS34721, TCS34723) or 0x29 (TCS34725,
|
||||||
|
* TCS34727)
|
||||||
|
*
|
||||||
|
* TODO: interrupt support, thresholds, wait time
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/i2c.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
|
#include <linux/pm.h>
|
||||||
|
|
||||||
|
#include <linux/iio/iio.h>
|
||||||
|
#include <linux/iio/sysfs.h>
|
||||||
|
#include <linux/iio/trigger_consumer.h>
|
||||||
|
#include <linux/iio/buffer.h>
|
||||||
|
#include <linux/iio/triggered_buffer.h>
|
||||||
|
|
||||||
|
#define TCS3472_DRV_NAME "tcs3472"
|
||||||
|
|
||||||
|
#define TCS3472_COMMAND BIT(7)
|
||||||
|
#define TCS3472_AUTO_INCR BIT(5)
|
||||||
|
|
||||||
|
#define TCS3472_ENABLE (TCS3472_COMMAND | 0x00)
|
||||||
|
#define TCS3472_ATIME (TCS3472_COMMAND | 0x01)
|
||||||
|
#define TCS3472_WTIME (TCS3472_COMMAND | 0x03)
|
||||||
|
#define TCS3472_AILT (TCS3472_COMMAND | 0x04)
|
||||||
|
#define TCS3472_AIHT (TCS3472_COMMAND | 0x06)
|
||||||
|
#define TCS3472_PERS (TCS3472_COMMAND | 0x0c)
|
||||||
|
#define TCS3472_CONFIG (TCS3472_COMMAND | 0x0d)
|
||||||
|
#define TCS3472_CONTROL (TCS3472_COMMAND | 0x0f)
|
||||||
|
#define TCS3472_ID (TCS3472_COMMAND | 0x12)
|
||||||
|
#define TCS3472_STATUS (TCS3472_COMMAND | 0x13)
|
||||||
|
#define TCS3472_CDATA (TCS3472_COMMAND | TCS3472_AUTO_INCR | 0x14)
|
||||||
|
#define TCS3472_RDATA (TCS3472_COMMAND | TCS3472_AUTO_INCR | 0x16)
|
||||||
|
#define TCS3472_GDATA (TCS3472_COMMAND | TCS3472_AUTO_INCR | 0x18)
|
||||||
|
#define TCS3472_BDATA (TCS3472_COMMAND | TCS3472_AUTO_INCR | 0x1a)
|
||||||
|
|
||||||
|
#define TCS3472_STATUS_AVALID BIT(0)
|
||||||
|
#define TCS3472_ENABLE_AEN BIT(1)
|
||||||
|
#define TCS3472_ENABLE_PON BIT(0)
|
||||||
|
#define TCS3472_CONTROL_AGAIN_MASK (BIT(0) | BIT(1))
|
||||||
|
|
||||||
|
struct tcs3472_data {
|
||||||
|
struct i2c_client *client;
|
||||||
|
u8 enable;
|
||||||
|
u8 control;
|
||||||
|
u8 atime;
|
||||||
|
u16 buffer[8]; /* 4 16-bit channels + 64-bit timestamp */
|
||||||
|
};
|
||||||
|
|
||||||
|
#define TCS3472_CHANNEL(_color, _si, _addr) { \
|
||||||
|
.type = IIO_INTENSITY, \
|
||||||
|
.modified = 1, \
|
||||||
|
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
|
||||||
|
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_CALIBSCALE) | \
|
||||||
|
BIT(IIO_CHAN_INFO_INT_TIME), \
|
||||||
|
.channel2 = IIO_MOD_LIGHT_##_color, \
|
||||||
|
.address = _addr, \
|
||||||
|
.scan_index = _si, \
|
||||||
|
.scan_type = IIO_ST('u', 16, 16, 0), \
|
||||||
|
}
|
||||||
|
|
||||||
|
static const int tcs3472_agains[] = { 1, 4, 16, 60 };
|
||||||
|
|
||||||
|
static const struct iio_chan_spec tcs3472_channels[] = {
|
||||||
|
TCS3472_CHANNEL(CLEAR, 0, TCS3472_CDATA),
|
||||||
|
TCS3472_CHANNEL(RED, 1, TCS3472_RDATA),
|
||||||
|
TCS3472_CHANNEL(GREEN, 2, TCS3472_GDATA),
|
||||||
|
TCS3472_CHANNEL(BLUE, 3, TCS3472_BDATA),
|
||||||
|
IIO_CHAN_SOFT_TIMESTAMP(4),
|
||||||
|
};
|
||||||
|
|
||||||
|
static int tcs3472_req_data(struct tcs3472_data *data)
|
||||||
|
{
|
||||||
|
int tries = 50;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
while (tries--) {
|
||||||
|
ret = i2c_smbus_read_byte_data(data->client, TCS3472_STATUS);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
if (ret & TCS3472_STATUS_AVALID)
|
||||||
|
break;
|
||||||
|
msleep(20);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tries < 0) {
|
||||||
|
dev_err(&data->client->dev, "data not ready\n");
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tcs3472_read_raw(struct iio_dev *indio_dev,
|
||||||
|
struct iio_chan_spec const *chan,
|
||||||
|
int *val, int *val2, long mask)
|
||||||
|
{
|
||||||
|
struct tcs3472_data *data = iio_priv(indio_dev);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
switch (mask) {
|
||||||
|
case IIO_CHAN_INFO_RAW:
|
||||||
|
ret = tcs3472_req_data(data);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
ret = i2c_smbus_read_word_data(data->client, chan->address);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
*val = ret;
|
||||||
|
return IIO_VAL_INT;
|
||||||
|
case IIO_CHAN_INFO_CALIBSCALE:
|
||||||
|
*val = tcs3472_agains[data->control &
|
||||||
|
TCS3472_CONTROL_AGAIN_MASK];
|
||||||
|
return IIO_VAL_INT;
|
||||||
|
case IIO_CHAN_INFO_INT_TIME:
|
||||||
|
*val = 0;
|
||||||
|
*val2 = (256 - data->atime) * 2400;
|
||||||
|
return IIO_VAL_INT_PLUS_MICRO;
|
||||||
|
}
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tcs3472_write_raw(struct iio_dev *indio_dev,
|
||||||
|
struct iio_chan_spec const *chan,
|
||||||
|
int val, int val2, long mask)
|
||||||
|
{
|
||||||
|
struct tcs3472_data *data = iio_priv(indio_dev);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
switch (mask) {
|
||||||
|
case IIO_CHAN_INFO_CALIBSCALE:
|
||||||
|
if (val2 != 0)
|
||||||
|
return -EINVAL;
|
||||||
|
for (i = 0; i < ARRAY_SIZE(tcs3472_agains); i++) {
|
||||||
|
if (val == tcs3472_agains[i]) {
|
||||||
|
data->control &= ~TCS3472_CONTROL_AGAIN_MASK;
|
||||||
|
data->control |= i;
|
||||||
|
return i2c_smbus_write_byte_data(
|
||||||
|
data->client, TCS3472_CONTROL,
|
||||||
|
data->control);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -EINVAL;
|
||||||
|
case IIO_CHAN_INFO_INT_TIME:
|
||||||
|
if (val != 0)
|
||||||
|
return -EINVAL;
|
||||||
|
for (i = 0; i < 256; i++) {
|
||||||
|
if (val2 == (256 - i) * 2400) {
|
||||||
|
data->atime = i;
|
||||||
|
return i2c_smbus_write_word_data(
|
||||||
|
data->client, TCS3472_ATIME,
|
||||||
|
data->atime);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static irqreturn_t tcs3472_trigger_handler(int irq, void *p)
|
||||||
|
{
|
||||||
|
struct iio_poll_func *pf = p;
|
||||||
|
struct iio_dev *indio_dev = pf->indio_dev;
|
||||||
|
struct tcs3472_data *data = iio_priv(indio_dev);
|
||||||
|
int len = 0;
|
||||||
|
int i, j = 0;
|
||||||
|
|
||||||
|
int ret = tcs3472_req_data(data);
|
||||||
|
if (ret < 0)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
for_each_set_bit(i, indio_dev->active_scan_mask,
|
||||||
|
indio_dev->masklength) {
|
||||||
|
ret = i2c_smbus_read_word_data(data->client,
|
||||||
|
TCS3472_CDATA + 2*i);
|
||||||
|
if (ret < 0)
|
||||||
|
goto done;
|
||||||
|
|
||||||
|
data->buffer[j++] = ret;
|
||||||
|
len += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,
|
||||||
|
iio_get_time_ns());
|
||||||
|
|
||||||
|
done:
|
||||||
|
iio_trigger_notify_done(indio_dev->trig);
|
||||||
|
|
||||||
|
return IRQ_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t tcs3472_show_int_time_available(struct device *dev,
|
||||||
|
struct device_attribute *attr,
|
||||||
|
char *buf)
|
||||||
|
{
|
||||||
|
size_t len = 0;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 1; i <= 256; i++)
|
||||||
|
len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06d ",
|
||||||
|
2400 * i);
|
||||||
|
|
||||||
|
/* replace trailing space by newline */
|
||||||
|
buf[len - 1] = '\n';
|
||||||
|
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
|
||||||
|
static IIO_CONST_ATTR(calibscale_available, "1 4 16 60");
|
||||||
|
static IIO_DEV_ATTR_INT_TIME_AVAIL(tcs3472_show_int_time_available);
|
||||||
|
|
||||||
|
static struct attribute *tcs3472_attributes[] = {
|
||||||
|
&iio_const_attr_calibscale_available.dev_attr.attr,
|
||||||
|
&iio_dev_attr_integration_time_available.dev_attr.attr,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct attribute_group tcs3472_attribute_group = {
|
||||||
|
.attrs = tcs3472_attributes,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct iio_info tcs3472_info = {
|
||||||
|
.read_raw = tcs3472_read_raw,
|
||||||
|
.write_raw = tcs3472_write_raw,
|
||||||
|
.attrs = &tcs3472_attribute_group,
|
||||||
|
.driver_module = THIS_MODULE,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int tcs3472_probe(struct i2c_client *client,
|
||||||
|
const struct i2c_device_id *id)
|
||||||
|
{
|
||||||
|
struct tcs3472_data *data;
|
||||||
|
struct iio_dev *indio_dev;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
|
||||||
|
if (indio_dev == NULL)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
data = iio_priv(indio_dev);
|
||||||
|
i2c_set_clientdata(client, indio_dev);
|
||||||
|
data->client = client;
|
||||||
|
|
||||||
|
indio_dev->dev.parent = &client->dev;
|
||||||
|
indio_dev->info = &tcs3472_info;
|
||||||
|
indio_dev->name = TCS3472_DRV_NAME;
|
||||||
|
indio_dev->channels = tcs3472_channels;
|
||||||
|
indio_dev->num_channels = ARRAY_SIZE(tcs3472_channels);
|
||||||
|
indio_dev->modes = INDIO_DIRECT_MODE;
|
||||||
|
|
||||||
|
ret = i2c_smbus_read_byte_data(data->client, TCS3472_ID);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (ret == 0x44)
|
||||||
|
dev_info(&client->dev, "TCS34721/34725 found\n");
|
||||||
|
else if (ret == 0x4d)
|
||||||
|
dev_info(&client->dev, "TCS34723/34727 found\n");
|
||||||
|
else
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
ret = i2c_smbus_read_byte_data(data->client, TCS3472_CONTROL);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
data->control = ret;
|
||||||
|
|
||||||
|
ret = i2c_smbus_read_byte_data(data->client, TCS3472_ATIME);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
data->atime = ret;
|
||||||
|
|
||||||
|
ret = i2c_smbus_read_byte_data(data->client, TCS3472_ENABLE);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
/* enable device */
|
||||||
|
data->enable = ret | TCS3472_ENABLE_PON | TCS3472_ENABLE_AEN;
|
||||||
|
ret = i2c_smbus_write_byte_data(data->client, TCS3472_ENABLE,
|
||||||
|
data->enable);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = iio_triggered_buffer_setup(indio_dev, NULL,
|
||||||
|
tcs3472_trigger_handler, NULL);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = iio_device_register(indio_dev);
|
||||||
|
if (ret < 0)
|
||||||
|
goto buffer_cleanup;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
buffer_cleanup:
|
||||||
|
iio_triggered_buffer_cleanup(indio_dev);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tcs3472_powerdown(struct tcs3472_data *data)
|
||||||
|
{
|
||||||
|
return i2c_smbus_write_byte_data(data->client, TCS3472_ENABLE,
|
||||||
|
data->enable & ~(TCS3472_ENABLE_AEN | TCS3472_ENABLE_PON));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tcs3472_remove(struct i2c_client *client)
|
||||||
|
{
|
||||||
|
struct iio_dev *indio_dev = i2c_get_clientdata(client);
|
||||||
|
|
||||||
|
iio_device_unregister(indio_dev);
|
||||||
|
iio_triggered_buffer_cleanup(indio_dev);
|
||||||
|
tcs3472_powerdown(iio_priv(indio_dev));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM_SLEEP
|
||||||
|
static int tcs3472_suspend(struct device *dev)
|
||||||
|
{
|
||||||
|
struct tcs3472_data *data = iio_priv(i2c_get_clientdata(
|
||||||
|
to_i2c_client(dev)));
|
||||||
|
return tcs3472_powerdown(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tcs3472_resume(struct device *dev)
|
||||||
|
{
|
||||||
|
struct tcs3472_data *data = iio_priv(i2c_get_clientdata(
|
||||||
|
to_i2c_client(dev)));
|
||||||
|
return i2c_smbus_write_byte_data(data->client, TCS3472_ENABLE,
|
||||||
|
data->enable | (TCS3472_ENABLE_AEN | TCS3472_ENABLE_PON));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static SIMPLE_DEV_PM_OPS(tcs3472_pm_ops, tcs3472_suspend, tcs3472_resume);
|
||||||
|
|
||||||
|
static const struct i2c_device_id tcs3472_id[] = {
|
||||||
|
{ "tcs3472", 0 },
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(i2c, tcs3472_id);
|
||||||
|
|
||||||
|
static struct i2c_driver tcs3472_driver = {
|
||||||
|
.driver = {
|
||||||
|
.name = TCS3472_DRV_NAME,
|
||||||
|
.pm = &tcs3472_pm_ops,
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
},
|
||||||
|
.probe = tcs3472_probe,
|
||||||
|
.remove = tcs3472_remove,
|
||||||
|
.id_table = tcs3472_id,
|
||||||
|
};
|
||||||
|
module_i2c_driver(tcs3472_driver);
|
||||||
|
|
||||||
|
MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>");
|
||||||
|
MODULE_DESCRIPTION("TCS3472 color light sensors driver");
|
||||||
|
MODULE_LICENSE("GPL");
|
258
drivers/iio/light/tsl4531.c
Normal file
258
drivers/iio/light/tsl4531.c
Normal file
|
@ -0,0 +1,258 @@
|
||||||
|
/*
|
||||||
|
* tsl4531.c - Support for TAOS TSL4531 ambient light sensor
|
||||||
|
*
|
||||||
|
* Copyright 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.
|
||||||
|
*
|
||||||
|
* IIO driver for the TSL4531x family
|
||||||
|
* TSL45311/TSL45313: 7-bit I2C slave address 0x39
|
||||||
|
* TSL45315/TSL45317: 7-bit I2C slave address 0x29
|
||||||
|
*
|
||||||
|
* TODO: single cycle measurement
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/i2c.h>
|
||||||
|
#include <linux/err.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
|
|
||||||
|
#include <linux/iio/iio.h>
|
||||||
|
#include <linux/iio/sysfs.h>
|
||||||
|
|
||||||
|
#define TSL4531_DRV_NAME "tsl4531"
|
||||||
|
|
||||||
|
#define TCS3472_COMMAND BIT(7)
|
||||||
|
|
||||||
|
#define TSL4531_CONTROL (TCS3472_COMMAND | 0x00)
|
||||||
|
#define TSL4531_CONFIG (TCS3472_COMMAND | 0x01)
|
||||||
|
#define TSL4531_DATA (TCS3472_COMMAND | 0x04)
|
||||||
|
#define TSL4531_ID (TCS3472_COMMAND | 0x0a)
|
||||||
|
|
||||||
|
/* operating modes in control register */
|
||||||
|
#define TSL4531_MODE_POWERDOWN 0x00
|
||||||
|
#define TSL4531_MODE_SINGLE_ADC 0x02
|
||||||
|
#define TSL4531_MODE_NORMAL 0x03
|
||||||
|
|
||||||
|
/* integration time control in config register */
|
||||||
|
#define TSL4531_TCNTRL_400MS 0x00
|
||||||
|
#define TSL4531_TCNTRL_200MS 0x01
|
||||||
|
#define TSL4531_TCNTRL_100MS 0x02
|
||||||
|
|
||||||
|
/* part number in id register */
|
||||||
|
#define TSL45311_ID 0x8
|
||||||
|
#define TSL45313_ID 0x9
|
||||||
|
#define TSL45315_ID 0xa
|
||||||
|
#define TSL45317_ID 0xb
|
||||||
|
#define TSL4531_ID_SHIFT 4
|
||||||
|
|
||||||
|
struct tsl4531_data {
|
||||||
|
struct i2c_client *client;
|
||||||
|
struct mutex lock;
|
||||||
|
int int_time;
|
||||||
|
};
|
||||||
|
|
||||||
|
static IIO_CONST_ATTR_INT_TIME_AVAIL("0.1 0.2 0.4");
|
||||||
|
|
||||||
|
static struct attribute *tsl4531_attributes[] = {
|
||||||
|
&iio_const_attr_integration_time_available.dev_attr.attr,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct attribute_group tsl4531_attribute_group = {
|
||||||
|
.attrs = tsl4531_attributes,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct iio_chan_spec tsl4531_channels[] = {
|
||||||
|
{
|
||||||
|
.type = IIO_LIGHT,
|
||||||
|
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
|
||||||
|
BIT(IIO_CHAN_INFO_SCALE) |
|
||||||
|
BIT(IIO_CHAN_INFO_INT_TIME)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static int tsl4531_read_raw(struct iio_dev *indio_dev,
|
||||||
|
struct iio_chan_spec const *chan,
|
||||||
|
int *val, int *val2, long mask)
|
||||||
|
{
|
||||||
|
struct tsl4531_data *data = iio_priv(indio_dev);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
switch (mask) {
|
||||||
|
case IIO_CHAN_INFO_RAW:
|
||||||
|
ret = i2c_smbus_read_word_data(data->client,
|
||||||
|
TSL4531_DATA);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
*val = ret;
|
||||||
|
return IIO_VAL_INT;
|
||||||
|
case IIO_CHAN_INFO_SCALE:
|
||||||
|
/* 0.. 1x, 1 .. 2x, 2 .. 4x */
|
||||||
|
*val = 1 << data->int_time;
|
||||||
|
return IIO_VAL_INT;
|
||||||
|
case IIO_CHAN_INFO_INT_TIME:
|
||||||
|
if (data->int_time == 0)
|
||||||
|
*val2 = 400000;
|
||||||
|
else if (data->int_time == 1)
|
||||||
|
*val2 = 200000;
|
||||||
|
else if (data->int_time == 2)
|
||||||
|
*val2 = 100000;
|
||||||
|
else
|
||||||
|
return -EINVAL;
|
||||||
|
*val = 0;
|
||||||
|
return IIO_VAL_INT_PLUS_MICRO;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tsl4531_write_raw(struct iio_dev *indio_dev,
|
||||||
|
struct iio_chan_spec const *chan,
|
||||||
|
int val, int val2, long mask)
|
||||||
|
{
|
||||||
|
struct tsl4531_data *data = iio_priv(indio_dev);
|
||||||
|
int int_time, ret;
|
||||||
|
|
||||||
|
switch (mask) {
|
||||||
|
case IIO_CHAN_INFO_INT_TIME:
|
||||||
|
if (val != 0)
|
||||||
|
return -EINVAL;
|
||||||
|
if (val2 == 400000)
|
||||||
|
int_time = 0;
|
||||||
|
else if (val2 == 200000)
|
||||||
|
int_time = 1;
|
||||||
|
else if (val2 == 100000)
|
||||||
|
int_time = 2;
|
||||||
|
else
|
||||||
|
return -EINVAL;
|
||||||
|
mutex_lock(&data->lock);
|
||||||
|
ret = i2c_smbus_write_byte_data(data->client,
|
||||||
|
TSL4531_CONFIG, int_time);
|
||||||
|
if (ret >= 0)
|
||||||
|
data->int_time = int_time;
|
||||||
|
mutex_unlock(&data->lock);
|
||||||
|
return ret;
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct iio_info tsl4531_info = {
|
||||||
|
.read_raw = tsl4531_read_raw,
|
||||||
|
.write_raw = tsl4531_write_raw,
|
||||||
|
.attrs = &tsl4531_attribute_group,
|
||||||
|
.driver_module = THIS_MODULE,
|
||||||
|
};
|
||||||
|
|
||||||
|
static int tsl4531_check_id(struct i2c_client *client)
|
||||||
|
{
|
||||||
|
int ret = i2c_smbus_read_byte_data(client, TSL4531_ID);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
switch (ret >> TSL4531_ID_SHIFT) {
|
||||||
|
case TSL45311_ID:
|
||||||
|
case TSL45313_ID:
|
||||||
|
case TSL45315_ID:
|
||||||
|
case TSL45317_ID:
|
||||||
|
return 1;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tsl4531_probe(struct i2c_client *client,
|
||||||
|
const struct i2c_device_id *id)
|
||||||
|
{
|
||||||
|
struct tsl4531_data *data;
|
||||||
|
struct iio_dev *indio_dev;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
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;
|
||||||
|
mutex_init(&data->lock);
|
||||||
|
|
||||||
|
if (!tsl4531_check_id(client)) {
|
||||||
|
dev_err(&client->dev, "no TSL4531 sensor\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = i2c_smbus_write_byte_data(data->client, TSL4531_CONTROL,
|
||||||
|
TSL4531_MODE_NORMAL);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
ret = i2c_smbus_write_byte_data(data->client, TSL4531_CONFIG,
|
||||||
|
TSL4531_TCNTRL_400MS);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
indio_dev->dev.parent = &client->dev;
|
||||||
|
indio_dev->info = &tsl4531_info;
|
||||||
|
indio_dev->channels = tsl4531_channels;
|
||||||
|
indio_dev->num_channels = ARRAY_SIZE(tsl4531_channels);
|
||||||
|
indio_dev->name = TSL4531_DRV_NAME;
|
||||||
|
indio_dev->modes = INDIO_DIRECT_MODE;
|
||||||
|
|
||||||
|
return iio_device_register(indio_dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tsl4531_powerdown(struct i2c_client *client)
|
||||||
|
{
|
||||||
|
return i2c_smbus_write_byte_data(client, TSL4531_CONTROL,
|
||||||
|
TSL4531_MODE_POWERDOWN);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tsl4531_remove(struct i2c_client *client)
|
||||||
|
{
|
||||||
|
iio_device_unregister(i2c_get_clientdata(client));
|
||||||
|
tsl4531_powerdown(client);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM_SLEEP
|
||||||
|
static int tsl4531_suspend(struct device *dev)
|
||||||
|
{
|
||||||
|
return tsl4531_powerdown(to_i2c_client(dev));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int tsl4531_resume(struct device *dev)
|
||||||
|
{
|
||||||
|
return i2c_smbus_write_byte_data(to_i2c_client(dev), TSL4531_CONTROL,
|
||||||
|
TSL4531_MODE_NORMAL);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static SIMPLE_DEV_PM_OPS(tsl4531_pm_ops, tsl4531_suspend, tsl4531_resume);
|
||||||
|
|
||||||
|
static const struct i2c_device_id tsl4531_id[] = {
|
||||||
|
{ "tsl4531", 0 },
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(i2c, tsl4531_id);
|
||||||
|
|
||||||
|
static struct i2c_driver tsl4531_driver = {
|
||||||
|
.driver = {
|
||||||
|
.name = TSL4531_DRV_NAME,
|
||||||
|
.pm = &tsl4531_pm_ops,
|
||||||
|
.owner = THIS_MODULE,
|
||||||
|
},
|
||||||
|
.probe = tsl4531_probe,
|
||||||
|
.remove = tsl4531_remove,
|
||||||
|
.id_table = tsl4531_id,
|
||||||
|
};
|
||||||
|
|
||||||
|
module_i2c_driver(tsl4531_driver);
|
||||||
|
|
||||||
|
MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>");
|
||||||
|
MODULE_DESCRIPTION("TAOS TSL4531 ambient light sensors driver");
|
||||||
|
MODULE_LICENSE("GPL");
|
|
@ -183,10 +183,11 @@ static const struct iio_info magn_3d_info = {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Function to push data to buffer */
|
/* Function to push data to buffer */
|
||||||
static void hid_sensor_push_data(struct iio_dev *indio_dev, u8 *data, int len)
|
static void hid_sensor_push_data(struct iio_dev *indio_dev, const void *data,
|
||||||
|
int len)
|
||||||
{
|
{
|
||||||
dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n");
|
dev_dbg(&indio_dev->dev, "hid_sensor_push_data\n");
|
||||||
iio_push_to_buffers(indio_dev, (u8 *)data);
|
iio_push_to_buffers(indio_dev, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Callback handler to send event after all samples are received and captured */
|
/* Callback handler to send event after all samples are received and captured */
|
||||||
|
@ -201,7 +202,7 @@ static int magn_3d_proc_event(struct hid_sensor_hub_device *hsdev,
|
||||||
magn_state->common_attributes.data_ready);
|
magn_state->common_attributes.data_ready);
|
||||||
if (magn_state->common_attributes.data_ready)
|
if (magn_state->common_attributes.data_ready)
|
||||||
hid_sensor_push_data(indio_dev,
|
hid_sensor_push_data(indio_dev,
|
||||||
(u8 *)magn_state->magn_val,
|
magn_state->magn_val,
|
||||||
sizeof(magn_state->magn_val));
|
sizeof(magn_state->magn_val));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -348,8 +348,9 @@ static const struct iio_info magn_info = {
|
||||||
int st_magn_common_probe(struct iio_dev *indio_dev,
|
int st_magn_common_probe(struct iio_dev *indio_dev,
|
||||||
struct st_sensors_platform_data *pdata)
|
struct st_sensors_platform_data *pdata)
|
||||||
{
|
{
|
||||||
int err;
|
|
||||||
struct st_sensor_data *mdata = iio_priv(indio_dev);
|
struct st_sensor_data *mdata = iio_priv(indio_dev);
|
||||||
|
int irq = mdata->get_irq_data_ready(indio_dev);
|
||||||
|
int err;
|
||||||
|
|
||||||
indio_dev->modes = INDIO_DIRECT_MODE;
|
indio_dev->modes = INDIO_DIRECT_MODE;
|
||||||
indio_dev->info = &magn_info;
|
indio_dev->info = &magn_info;
|
||||||
|
@ -357,7 +358,7 @@ int st_magn_common_probe(struct iio_dev *indio_dev,
|
||||||
err = st_sensors_check_device_support(indio_dev,
|
err = st_sensors_check_device_support(indio_dev,
|
||||||
ARRAY_SIZE(st_magn_sensors), st_magn_sensors);
|
ARRAY_SIZE(st_magn_sensors), st_magn_sensors);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto st_magn_common_probe_error;
|
return err;
|
||||||
|
|
||||||
mdata->num_data_channels = ST_MAGN_NUMBER_DATA_CHANNELS;
|
mdata->num_data_channels = ST_MAGN_NUMBER_DATA_CHANNELS;
|
||||||
mdata->multiread_bit = mdata->sensor->multi_read_bit;
|
mdata->multiread_bit = mdata->sensor->multi_read_bit;
|
||||||
|
@ -370,12 +371,13 @@ int st_magn_common_probe(struct iio_dev *indio_dev,
|
||||||
|
|
||||||
err = st_sensors_init_sensor(indio_dev, pdata);
|
err = st_sensors_init_sensor(indio_dev, pdata);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto st_magn_common_probe_error;
|
return err;
|
||||||
|
|
||||||
if (mdata->get_irq_data_ready(indio_dev) > 0) {
|
err = st_magn_allocate_ring(indio_dev);
|
||||||
err = st_magn_allocate_ring(indio_dev);
|
if (err < 0)
|
||||||
if (err < 0)
|
return err;
|
||||||
goto st_magn_common_probe_error;
|
|
||||||
|
if (irq > 0) {
|
||||||
err = st_sensors_allocate_trigger(indio_dev, NULL);
|
err = st_sensors_allocate_trigger(indio_dev, NULL);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto st_magn_probe_trigger_error;
|
goto st_magn_probe_trigger_error;
|
||||||
|
@ -385,15 +387,14 @@ int st_magn_common_probe(struct iio_dev *indio_dev,
|
||||||
if (err)
|
if (err)
|
||||||
goto st_magn_device_register_error;
|
goto st_magn_device_register_error;
|
||||||
|
|
||||||
return err;
|
return 0;
|
||||||
|
|
||||||
st_magn_device_register_error:
|
st_magn_device_register_error:
|
||||||
if (mdata->get_irq_data_ready(indio_dev) > 0)
|
if (irq > 0)
|
||||||
st_sensors_deallocate_trigger(indio_dev);
|
st_sensors_deallocate_trigger(indio_dev);
|
||||||
st_magn_probe_trigger_error:
|
st_magn_probe_trigger_error:
|
||||||
if (mdata->get_irq_data_ready(indio_dev) > 0)
|
st_magn_deallocate_ring(indio_dev);
|
||||||
st_magn_deallocate_ring(indio_dev);
|
|
||||||
st_magn_common_probe_error:
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(st_magn_common_probe);
|
EXPORT_SYMBOL(st_magn_common_probe);
|
||||||
|
@ -403,10 +404,10 @@ void st_magn_common_remove(struct iio_dev *indio_dev)
|
||||||
struct st_sensor_data *mdata = iio_priv(indio_dev);
|
struct st_sensor_data *mdata = iio_priv(indio_dev);
|
||||||
|
|
||||||
iio_device_unregister(indio_dev);
|
iio_device_unregister(indio_dev);
|
||||||
if (mdata->get_irq_data_ready(indio_dev) > 0) {
|
if (mdata->get_irq_data_ready(indio_dev) > 0)
|
||||||
st_sensors_deallocate_trigger(indio_dev);
|
st_sensors_deallocate_trigger(indio_dev);
|
||||||
st_magn_deallocate_ring(indio_dev);
|
|
||||||
}
|
st_magn_deallocate_ring(indio_dev);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(st_magn_common_remove);
|
EXPORT_SYMBOL(st_magn_common_remove);
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/iio/common/st_sensors.h>
|
#include <linux/iio/common/st_sensors.h>
|
||||||
|
|
||||||
|
#define LPS001WP_PRESS_DEV_NAME "lps001wp"
|
||||||
#define LPS331AP_PRESS_DEV_NAME "lps331ap"
|
#define LPS331AP_PRESS_DEV_NAME "lps331ap"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -36,94 +36,200 @@
|
||||||
ST_PRESS_LSB_PER_CELSIUS)
|
ST_PRESS_LSB_PER_CELSIUS)
|
||||||
#define ST_PRESS_NUMBER_DATA_CHANNELS 1
|
#define ST_PRESS_NUMBER_DATA_CHANNELS 1
|
||||||
|
|
||||||
/* DEFAULT VALUE FOR SENSORS */
|
|
||||||
#define ST_PRESS_DEFAULT_OUT_XL_ADDR 0x28
|
|
||||||
#define ST_TEMP_DEFAULT_OUT_L_ADDR 0x2b
|
|
||||||
|
|
||||||
/* FULLSCALE */
|
/* FULLSCALE */
|
||||||
#define ST_PRESS_FS_AVL_1260MB 1260
|
#define ST_PRESS_FS_AVL_1260MB 1260
|
||||||
|
|
||||||
/* CUSTOM VALUES FOR SENSOR 1 */
|
/* CUSTOM VALUES FOR LPS331AP SENSOR */
|
||||||
#define ST_PRESS_1_WAI_EXP 0xbb
|
#define ST_PRESS_LPS331AP_WAI_EXP 0xbb
|
||||||
#define ST_PRESS_1_ODR_ADDR 0x20
|
#define ST_PRESS_LPS331AP_ODR_ADDR 0x20
|
||||||
#define ST_PRESS_1_ODR_MASK 0x70
|
#define ST_PRESS_LPS331AP_ODR_MASK 0x70
|
||||||
#define ST_PRESS_1_ODR_AVL_1HZ_VAL 0x01
|
#define ST_PRESS_LPS331AP_ODR_AVL_1HZ_VAL 0x01
|
||||||
#define ST_PRESS_1_ODR_AVL_7HZ_VAL 0x05
|
#define ST_PRESS_LPS331AP_ODR_AVL_7HZ_VAL 0x05
|
||||||
#define ST_PRESS_1_ODR_AVL_13HZ_VAL 0x06
|
#define ST_PRESS_LPS331AP_ODR_AVL_13HZ_VAL 0x06
|
||||||
#define ST_PRESS_1_ODR_AVL_25HZ_VAL 0x07
|
#define ST_PRESS_LPS331AP_ODR_AVL_25HZ_VAL 0x07
|
||||||
#define ST_PRESS_1_PW_ADDR 0x20
|
#define ST_PRESS_LPS331AP_PW_ADDR 0x20
|
||||||
#define ST_PRESS_1_PW_MASK 0x80
|
#define ST_PRESS_LPS331AP_PW_MASK 0x80
|
||||||
#define ST_PRESS_1_FS_ADDR 0x23
|
#define ST_PRESS_LPS331AP_FS_ADDR 0x23
|
||||||
#define ST_PRESS_1_FS_MASK 0x30
|
#define ST_PRESS_LPS331AP_FS_MASK 0x30
|
||||||
#define ST_PRESS_1_FS_AVL_1260_VAL 0x00
|
#define ST_PRESS_LPS331AP_FS_AVL_1260_VAL 0x00
|
||||||
#define ST_PRESS_1_FS_AVL_1260_GAIN ST_PRESS_KPASCAL_NANO_SCALE
|
#define ST_PRESS_LPS331AP_FS_AVL_1260_GAIN ST_PRESS_KPASCAL_NANO_SCALE
|
||||||
#define ST_PRESS_1_FS_AVL_TEMP_GAIN ST_PRESS_CELSIUS_NANO_SCALE
|
#define ST_PRESS_LPS331AP_FS_AVL_TEMP_GAIN ST_PRESS_CELSIUS_NANO_SCALE
|
||||||
#define ST_PRESS_1_BDU_ADDR 0x20
|
#define ST_PRESS_LPS331AP_BDU_ADDR 0x20
|
||||||
#define ST_PRESS_1_BDU_MASK 0x04
|
#define ST_PRESS_LPS331AP_BDU_MASK 0x04
|
||||||
#define ST_PRESS_1_DRDY_IRQ_ADDR 0x22
|
#define ST_PRESS_LPS331AP_DRDY_IRQ_ADDR 0x22
|
||||||
#define ST_PRESS_1_DRDY_IRQ_INT1_MASK 0x04
|
#define ST_PRESS_LPS331AP_DRDY_IRQ_INT1_MASK 0x04
|
||||||
#define ST_PRESS_1_DRDY_IRQ_INT2_MASK 0x20
|
#define ST_PRESS_LPS331AP_DRDY_IRQ_INT2_MASK 0x20
|
||||||
#define ST_PRESS_1_MULTIREAD_BIT true
|
#define ST_PRESS_LPS331AP_MULTIREAD_BIT true
|
||||||
#define ST_PRESS_1_TEMP_OFFSET 42500
|
#define ST_PRESS_LPS331AP_TEMP_OFFSET 42500
|
||||||
|
#define ST_PRESS_LPS331AP_OUT_XL_ADDR 0x28
|
||||||
|
#define ST_TEMP_LPS331AP_OUT_L_ADDR 0x2b
|
||||||
|
|
||||||
static const struct iio_chan_spec st_press_channels[] = {
|
/* CUSTOM VALUES FOR LPS001WP SENSOR */
|
||||||
ST_SENSORS_LSM_CHANNELS(IIO_PRESSURE,
|
#define ST_PRESS_LPS001WP_WAI_EXP 0xba
|
||||||
|
#define ST_PRESS_LPS001WP_ODR_ADDR 0x20
|
||||||
|
#define ST_PRESS_LPS001WP_ODR_MASK 0x30
|
||||||
|
#define ST_PRESS_LPS001WP_ODR_AVL_1HZ_VAL 0x01
|
||||||
|
#define ST_PRESS_LPS001WP_ODR_AVL_7HZ_VAL 0x02
|
||||||
|
#define ST_PRESS_LPS001WP_ODR_AVL_13HZ_VAL 0x03
|
||||||
|
#define ST_PRESS_LPS001WP_PW_ADDR 0x20
|
||||||
|
#define ST_PRESS_LPS001WP_PW_MASK 0x40
|
||||||
|
#define ST_PRESS_LPS001WP_BDU_ADDR 0x20
|
||||||
|
#define ST_PRESS_LPS001WP_BDU_MASK 0x04
|
||||||
|
#define ST_PRESS_LPS001WP_MULTIREAD_BIT true
|
||||||
|
#define ST_PRESS_LPS001WP_OUT_L_ADDR 0x28
|
||||||
|
#define ST_TEMP_LPS001WP_OUT_L_ADDR 0x2a
|
||||||
|
|
||||||
|
static const struct iio_chan_spec st_press_lps331ap_channels[] = {
|
||||||
|
{
|
||||||
|
.type = IIO_PRESSURE,
|
||||||
|
.channel2 = IIO_NO_MOD,
|
||||||
|
.address = ST_PRESS_LPS331AP_OUT_XL_ADDR,
|
||||||
|
.scan_index = ST_SENSORS_SCAN_X,
|
||||||
|
.scan_type = {
|
||||||
|
.sign = 'u',
|
||||||
|
.realbits = 24,
|
||||||
|
.storagebits = 24,
|
||||||
|
.endianness = IIO_LE,
|
||||||
|
},
|
||||||
|
.info_mask_separate =
|
||||||
BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
|
BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
|
||||||
ST_SENSORS_SCAN_X, 0, IIO_NO_MOD, 'u', IIO_LE, 24, 24,
|
.modified = 0,
|
||||||
ST_PRESS_DEFAULT_OUT_XL_ADDR),
|
},
|
||||||
ST_SENSORS_LSM_CHANNELS(IIO_TEMP,
|
{
|
||||||
BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE) |
|
.type = IIO_TEMP,
|
||||||
BIT(IIO_CHAN_INFO_OFFSET),
|
.channel2 = IIO_NO_MOD,
|
||||||
-1, 0, IIO_NO_MOD, 's', IIO_LE, 16, 16,
|
.address = ST_TEMP_LPS331AP_OUT_L_ADDR,
|
||||||
ST_TEMP_DEFAULT_OUT_L_ADDR),
|
.scan_index = -1,
|
||||||
|
.scan_type = {
|
||||||
|
.sign = 'u',
|
||||||
|
.realbits = 16,
|
||||||
|
.storagebits = 16,
|
||||||
|
.endianness = IIO_LE,
|
||||||
|
},
|
||||||
|
.info_mask_separate =
|
||||||
|
BIT(IIO_CHAN_INFO_RAW) |
|
||||||
|
BIT(IIO_CHAN_INFO_SCALE) |
|
||||||
|
BIT(IIO_CHAN_INFO_OFFSET),
|
||||||
|
.modified = 0,
|
||||||
|
},
|
||||||
|
IIO_CHAN_SOFT_TIMESTAMP(1)
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct iio_chan_spec st_press_lps001wp_channels[] = {
|
||||||
|
{
|
||||||
|
.type = IIO_PRESSURE,
|
||||||
|
.channel2 = IIO_NO_MOD,
|
||||||
|
.address = ST_PRESS_LPS001WP_OUT_L_ADDR,
|
||||||
|
.scan_index = ST_SENSORS_SCAN_X,
|
||||||
|
.scan_type = {
|
||||||
|
.sign = 'u',
|
||||||
|
.realbits = 16,
|
||||||
|
.storagebits = 16,
|
||||||
|
.endianness = IIO_LE,
|
||||||
|
},
|
||||||
|
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
|
||||||
|
.modified = 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.type = IIO_TEMP,
|
||||||
|
.channel2 = IIO_NO_MOD,
|
||||||
|
.address = ST_TEMP_LPS001WP_OUT_L_ADDR,
|
||||||
|
.scan_index = -1,
|
||||||
|
.scan_type = {
|
||||||
|
.sign = 'u',
|
||||||
|
.realbits = 16,
|
||||||
|
.storagebits = 16,
|
||||||
|
.endianness = IIO_LE,
|
||||||
|
},
|
||||||
|
.info_mask_separate =
|
||||||
|
BIT(IIO_CHAN_INFO_RAW) |
|
||||||
|
BIT(IIO_CHAN_INFO_OFFSET),
|
||||||
|
.modified = 0,
|
||||||
|
},
|
||||||
IIO_CHAN_SOFT_TIMESTAMP(1)
|
IIO_CHAN_SOFT_TIMESTAMP(1)
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct st_sensors st_press_sensors[] = {
|
static const struct st_sensors st_press_sensors[] = {
|
||||||
{
|
{
|
||||||
.wai = ST_PRESS_1_WAI_EXP,
|
.wai = ST_PRESS_LPS331AP_WAI_EXP,
|
||||||
.sensors_supported = {
|
.sensors_supported = {
|
||||||
[0] = LPS331AP_PRESS_DEV_NAME,
|
[0] = LPS331AP_PRESS_DEV_NAME,
|
||||||
},
|
},
|
||||||
.ch = (struct iio_chan_spec *)st_press_channels,
|
.ch = (struct iio_chan_spec *)st_press_lps331ap_channels,
|
||||||
|
.num_ch = ARRAY_SIZE(st_press_lps331ap_channels),
|
||||||
.odr = {
|
.odr = {
|
||||||
.addr = ST_PRESS_1_ODR_ADDR,
|
.addr = ST_PRESS_LPS331AP_ODR_ADDR,
|
||||||
.mask = ST_PRESS_1_ODR_MASK,
|
.mask = ST_PRESS_LPS331AP_ODR_MASK,
|
||||||
.odr_avl = {
|
.odr_avl = {
|
||||||
{ 1, ST_PRESS_1_ODR_AVL_1HZ_VAL, },
|
{ 1, ST_PRESS_LPS331AP_ODR_AVL_1HZ_VAL, },
|
||||||
{ 7, ST_PRESS_1_ODR_AVL_7HZ_VAL, },
|
{ 7, ST_PRESS_LPS331AP_ODR_AVL_7HZ_VAL, },
|
||||||
{ 13, ST_PRESS_1_ODR_AVL_13HZ_VAL, },
|
{ 13, ST_PRESS_LPS331AP_ODR_AVL_13HZ_VAL, },
|
||||||
{ 25, ST_PRESS_1_ODR_AVL_25HZ_VAL, },
|
{ 25, ST_PRESS_LPS331AP_ODR_AVL_25HZ_VAL, },
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
.pw = {
|
.pw = {
|
||||||
.addr = ST_PRESS_1_PW_ADDR,
|
.addr = ST_PRESS_LPS331AP_PW_ADDR,
|
||||||
.mask = ST_PRESS_1_PW_MASK,
|
.mask = ST_PRESS_LPS331AP_PW_MASK,
|
||||||
.value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
|
.value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
|
||||||
.value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
|
.value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
|
||||||
},
|
},
|
||||||
.fs = {
|
.fs = {
|
||||||
.addr = ST_PRESS_1_FS_ADDR,
|
.addr = ST_PRESS_LPS331AP_FS_ADDR,
|
||||||
.mask = ST_PRESS_1_FS_MASK,
|
.mask = ST_PRESS_LPS331AP_FS_MASK,
|
||||||
.fs_avl = {
|
.fs_avl = {
|
||||||
[0] = {
|
[0] = {
|
||||||
.num = ST_PRESS_FS_AVL_1260MB,
|
.num = ST_PRESS_FS_AVL_1260MB,
|
||||||
.value = ST_PRESS_1_FS_AVL_1260_VAL,
|
.value = ST_PRESS_LPS331AP_FS_AVL_1260_VAL,
|
||||||
.gain = ST_PRESS_1_FS_AVL_1260_GAIN,
|
.gain = ST_PRESS_LPS331AP_FS_AVL_1260_GAIN,
|
||||||
.gain2 = ST_PRESS_1_FS_AVL_TEMP_GAIN,
|
.gain2 = ST_PRESS_LPS331AP_FS_AVL_TEMP_GAIN,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
.bdu = {
|
.bdu = {
|
||||||
.addr = ST_PRESS_1_BDU_ADDR,
|
.addr = ST_PRESS_LPS331AP_BDU_ADDR,
|
||||||
.mask = ST_PRESS_1_BDU_MASK,
|
.mask = ST_PRESS_LPS331AP_BDU_MASK,
|
||||||
},
|
},
|
||||||
.drdy_irq = {
|
.drdy_irq = {
|
||||||
.addr = ST_PRESS_1_DRDY_IRQ_ADDR,
|
.addr = ST_PRESS_LPS331AP_DRDY_IRQ_ADDR,
|
||||||
.mask_int1 = ST_PRESS_1_DRDY_IRQ_INT1_MASK,
|
.mask_int1 = ST_PRESS_LPS331AP_DRDY_IRQ_INT1_MASK,
|
||||||
.mask_int2 = ST_PRESS_1_DRDY_IRQ_INT2_MASK,
|
.mask_int2 = ST_PRESS_LPS331AP_DRDY_IRQ_INT2_MASK,
|
||||||
},
|
},
|
||||||
.multi_read_bit = ST_PRESS_1_MULTIREAD_BIT,
|
.multi_read_bit = ST_PRESS_LPS331AP_MULTIREAD_BIT,
|
||||||
|
.bootime = 2,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.wai = ST_PRESS_LPS001WP_WAI_EXP,
|
||||||
|
.sensors_supported = {
|
||||||
|
[0] = LPS001WP_PRESS_DEV_NAME,
|
||||||
|
},
|
||||||
|
.ch = (struct iio_chan_spec *)st_press_lps001wp_channels,
|
||||||
|
.num_ch = ARRAY_SIZE(st_press_lps001wp_channels),
|
||||||
|
.odr = {
|
||||||
|
.addr = ST_PRESS_LPS001WP_ODR_ADDR,
|
||||||
|
.mask = ST_PRESS_LPS001WP_ODR_MASK,
|
||||||
|
.odr_avl = {
|
||||||
|
{ 1, ST_PRESS_LPS001WP_ODR_AVL_1HZ_VAL, },
|
||||||
|
{ 7, ST_PRESS_LPS001WP_ODR_AVL_7HZ_VAL, },
|
||||||
|
{ 13, ST_PRESS_LPS001WP_ODR_AVL_13HZ_VAL, },
|
||||||
|
},
|
||||||
|
},
|
||||||
|
.pw = {
|
||||||
|
.addr = ST_PRESS_LPS001WP_PW_ADDR,
|
||||||
|
.mask = ST_PRESS_LPS001WP_PW_MASK,
|
||||||
|
.value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE,
|
||||||
|
.value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE,
|
||||||
|
},
|
||||||
|
.fs = {
|
||||||
|
.addr = 0,
|
||||||
|
},
|
||||||
|
.bdu = {
|
||||||
|
.addr = ST_PRESS_LPS001WP_BDU_ADDR,
|
||||||
|
.mask = ST_PRESS_LPS001WP_BDU_MASK,
|
||||||
|
},
|
||||||
|
.drdy_irq = {
|
||||||
|
.addr = 0,
|
||||||
|
},
|
||||||
|
.multi_read_bit = ST_PRESS_LPS001WP_MULTIREAD_BIT,
|
||||||
.bootime = 2,
|
.bootime = 2,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -210,41 +316,46 @@ static const struct iio_trigger_ops st_press_trigger_ops = {
|
||||||
int st_press_common_probe(struct iio_dev *indio_dev,
|
int st_press_common_probe(struct iio_dev *indio_dev,
|
||||||
struct st_sensors_platform_data *plat_data)
|
struct st_sensors_platform_data *plat_data)
|
||||||
{
|
{
|
||||||
int err;
|
|
||||||
struct st_sensor_data *pdata = iio_priv(indio_dev);
|
struct st_sensor_data *pdata = iio_priv(indio_dev);
|
||||||
|
int irq = pdata->get_irq_data_ready(indio_dev);
|
||||||
|
int err;
|
||||||
|
|
||||||
indio_dev->modes = INDIO_DIRECT_MODE;
|
indio_dev->modes = INDIO_DIRECT_MODE;
|
||||||
indio_dev->info = &press_info;
|
indio_dev->info = &press_info;
|
||||||
|
|
||||||
err = st_sensors_check_device_support(indio_dev,
|
err = st_sensors_check_device_support(indio_dev,
|
||||||
ARRAY_SIZE(st_press_sensors), st_press_sensors);
|
ARRAY_SIZE(st_press_sensors),
|
||||||
|
st_press_sensors);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto st_press_common_probe_error;
|
return err;
|
||||||
|
|
||||||
pdata->num_data_channels = ST_PRESS_NUMBER_DATA_CHANNELS;
|
pdata->num_data_channels = ST_PRESS_NUMBER_DATA_CHANNELS;
|
||||||
pdata->multiread_bit = pdata->sensor->multi_read_bit;
|
pdata->multiread_bit = pdata->sensor->multi_read_bit;
|
||||||
indio_dev->channels = pdata->sensor->ch;
|
indio_dev->channels = pdata->sensor->ch;
|
||||||
indio_dev->num_channels = ARRAY_SIZE(st_press_channels);
|
indio_dev->num_channels = pdata->sensor->num_ch;
|
||||||
|
|
||||||
|
if (pdata->sensor->fs.addr != 0)
|
||||||
|
pdata->current_fullscale = (struct st_sensor_fullscale_avl *)
|
||||||
|
&pdata->sensor->fs.fs_avl[0];
|
||||||
|
|
||||||
pdata->current_fullscale = (struct st_sensor_fullscale_avl *)
|
|
||||||
&pdata->sensor->fs.fs_avl[0];
|
|
||||||
pdata->odr = pdata->sensor->odr.odr_avl[0].hz;
|
pdata->odr = pdata->sensor->odr.odr_avl[0].hz;
|
||||||
|
|
||||||
if (!plat_data)
|
/* Some devices don't support a data ready pin. */
|
||||||
|
if (!plat_data && pdata->sensor->drdy_irq.addr)
|
||||||
plat_data =
|
plat_data =
|
||||||
(struct st_sensors_platform_data *)&default_press_pdata;
|
(struct st_sensors_platform_data *)&default_press_pdata;
|
||||||
|
|
||||||
err = st_sensors_init_sensor(indio_dev, plat_data);
|
err = st_sensors_init_sensor(indio_dev, plat_data);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto st_press_common_probe_error;
|
return err;
|
||||||
|
|
||||||
if (pdata->get_irq_data_ready(indio_dev) > 0) {
|
err = st_press_allocate_ring(indio_dev);
|
||||||
err = st_press_allocate_ring(indio_dev);
|
if (err < 0)
|
||||||
if (err < 0)
|
return err;
|
||||||
goto st_press_common_probe_error;
|
|
||||||
|
|
||||||
|
if (irq > 0) {
|
||||||
err = st_sensors_allocate_trigger(indio_dev,
|
err = st_sensors_allocate_trigger(indio_dev,
|
||||||
ST_PRESS_TRIGGER_OPS);
|
ST_PRESS_TRIGGER_OPS);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto st_press_probe_trigger_error;
|
goto st_press_probe_trigger_error;
|
||||||
}
|
}
|
||||||
|
@ -256,12 +367,11 @@ int st_press_common_probe(struct iio_dev *indio_dev,
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
st_press_device_register_error:
|
st_press_device_register_error:
|
||||||
if (pdata->get_irq_data_ready(indio_dev) > 0)
|
if (irq > 0)
|
||||||
st_sensors_deallocate_trigger(indio_dev);
|
st_sensors_deallocate_trigger(indio_dev);
|
||||||
st_press_probe_trigger_error:
|
st_press_probe_trigger_error:
|
||||||
if (pdata->get_irq_data_ready(indio_dev) > 0)
|
st_press_deallocate_ring(indio_dev);
|
||||||
st_press_deallocate_ring(indio_dev);
|
|
||||||
st_press_common_probe_error:
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(st_press_common_probe);
|
EXPORT_SYMBOL(st_press_common_probe);
|
||||||
|
@ -271,10 +381,10 @@ void st_press_common_remove(struct iio_dev *indio_dev)
|
||||||
struct st_sensor_data *pdata = iio_priv(indio_dev);
|
struct st_sensor_data *pdata = iio_priv(indio_dev);
|
||||||
|
|
||||||
iio_device_unregister(indio_dev);
|
iio_device_unregister(indio_dev);
|
||||||
if (pdata->get_irq_data_ready(indio_dev) > 0) {
|
if (pdata->get_irq_data_ready(indio_dev) > 0)
|
||||||
st_sensors_deallocate_trigger(indio_dev);
|
st_sensors_deallocate_trigger(indio_dev);
|
||||||
st_press_deallocate_ring(indio_dev);
|
|
||||||
}
|
st_press_deallocate_ring(indio_dev);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(st_press_common_remove);
|
EXPORT_SYMBOL(st_press_common_remove);
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,7 @@ static int st_press_i2c_remove(struct i2c_client *client)
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct i2c_device_id st_press_id_table[] = {
|
static const struct i2c_device_id st_press_id_table[] = {
|
||||||
|
{ LPS001WP_PRESS_DEV_NAME },
|
||||||
{ LPS331AP_PRESS_DEV_NAME },
|
{ LPS331AP_PRESS_DEV_NAME },
|
||||||
{},
|
{},
|
||||||
};
|
};
|
||||||
|
|
|
@ -70,12 +70,16 @@ static int tmp006_read_measurement(struct tmp006_data *data, u8 reg)
|
||||||
return i2c_smbus_read_word_swapped(data->client, reg);
|
return i2c_smbus_read_word_swapped(data->client, reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const int tmp006_freqs[5][2] = { {4, 0}, {2, 0}, {1, 0},
|
||||||
|
{0, 500000}, {0, 250000} };
|
||||||
|
|
||||||
static int tmp006_read_raw(struct iio_dev *indio_dev,
|
static int tmp006_read_raw(struct iio_dev *indio_dev,
|
||||||
struct iio_chan_spec const *channel, int *val,
|
struct iio_chan_spec const *channel, int *val,
|
||||||
int *val2, long mask)
|
int *val2, long mask)
|
||||||
{
|
{
|
||||||
struct tmp006_data *data = iio_priv(indio_dev);
|
struct tmp006_data *data = iio_priv(indio_dev);
|
||||||
s32 ret;
|
s32 ret;
|
||||||
|
int cr;
|
||||||
|
|
||||||
switch (mask) {
|
switch (mask) {
|
||||||
case IIO_CHAN_INFO_RAW:
|
case IIO_CHAN_INFO_RAW:
|
||||||
|
@ -106,6 +110,12 @@ static int tmp006_read_raw(struct iio_dev *indio_dev,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return IIO_VAL_INT_PLUS_MICRO;
|
return IIO_VAL_INT_PLUS_MICRO;
|
||||||
|
case IIO_CHAN_INFO_SAMP_FREQ:
|
||||||
|
cr = (data->config & TMP006_CONFIG_CR_MASK)
|
||||||
|
>> TMP006_CONFIG_CR_SHIFT;
|
||||||
|
*val = tmp006_freqs[cr][0];
|
||||||
|
*val2 = tmp006_freqs[cr][1];
|
||||||
|
return IIO_VAL_INT_PLUS_MICRO;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -113,48 +123,32 @@ static int tmp006_read_raw(struct iio_dev *indio_dev,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char * const tmp006_freqs[] = { "4", "2", "1", "0.5", "0.25" };
|
static int tmp006_write_raw(struct iio_dev *indio_dev,
|
||||||
|
struct iio_chan_spec const *chan,
|
||||||
static ssize_t tmp006_show_freq(struct device *dev,
|
int val,
|
||||||
struct device_attribute *attr, char *buf)
|
int val2,
|
||||||
|
long mask)
|
||||||
{
|
{
|
||||||
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);
|
struct tmp006_data *data = iio_priv(indio_dev);
|
||||||
int i;
|
int i;
|
||||||
bool found = false;
|
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(tmp006_freqs); i++)
|
for (i = 0; i < ARRAY_SIZE(tmp006_freqs); i++)
|
||||||
if (sysfs_streq(buf, tmp006_freqs[i])) {
|
if ((val == tmp006_freqs[i][0]) &&
|
||||||
found = true;
|
(val2 == tmp006_freqs[i][1])) {
|
||||||
break;
|
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);
|
||||||
|
|
||||||
}
|
}
|
||||||
if (!found)
|
return -EINVAL;
|
||||||
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 IIO_CONST_ATTR(sampling_frequency_available, "4 2 1 0.5 0.25");
|
||||||
|
|
||||||
static struct attribute *tmp006_attributes[] = {
|
static struct attribute *tmp006_attributes[] = {
|
||||||
&iio_dev_attr_sampling_frequency.dev_attr.attr,
|
|
||||||
&iio_const_attr_sampling_frequency_available.dev_attr.attr,
|
&iio_const_attr_sampling_frequency_available.dev_attr.attr,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
@ -168,16 +162,19 @@ static const struct iio_chan_spec tmp006_channels[] = {
|
||||||
.type = IIO_VOLTAGE,
|
.type = IIO_VOLTAGE,
|
||||||
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
|
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
|
||||||
BIT(IIO_CHAN_INFO_SCALE),
|
BIT(IIO_CHAN_INFO_SCALE),
|
||||||
|
.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
.type = IIO_TEMP,
|
.type = IIO_TEMP,
|
||||||
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
|
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
|
||||||
BIT(IIO_CHAN_INFO_SCALE),
|
BIT(IIO_CHAN_INFO_SCALE),
|
||||||
|
.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct iio_info tmp006_info = {
|
static const struct iio_info tmp006_info = {
|
||||||
.read_raw = tmp006_read_raw,
|
.read_raw = tmp006_read_raw,
|
||||||
|
.write_raw = tmp006_write_raw,
|
||||||
.attrs = &tmp006_attribute_group,
|
.attrs = &tmp006_attribute_group,
|
||||||
.driver_module = THIS_MODULE,
|
.driver_module = THIS_MODULE,
|
||||||
};
|
};
|
||||||
|
|
|
@ -52,6 +52,7 @@ struct titsc {
|
||||||
u32 config_inp[4];
|
u32 config_inp[4];
|
||||||
u32 bit_xp, bit_xn, bit_yp, bit_yn;
|
u32 bit_xp, bit_xn, bit_yp, bit_yn;
|
||||||
u32 inp_xp, inp_xn, inp_yp, inp_yn;
|
u32 inp_xp, inp_xn, inp_yp, inp_yn;
|
||||||
|
u32 step_mask;
|
||||||
};
|
};
|
||||||
|
|
||||||
static unsigned int titsc_readl(struct titsc *ts, unsigned int reg)
|
static unsigned int titsc_readl(struct titsc *ts, unsigned int reg)
|
||||||
|
@ -196,7 +197,8 @@ static void titsc_step_config(struct titsc *ts_dev)
|
||||||
|
|
||||||
/* The steps1 … end and bit 0 for TS_Charge */
|
/* The steps1 … end and bit 0 for TS_Charge */
|
||||||
stepenable = (1 << (end_step + 2)) - 1;
|
stepenable = (1 << (end_step + 2)) - 1;
|
||||||
am335x_tsc_se_set(ts_dev->mfd_tscadc, stepenable);
|
ts_dev->step_mask = stepenable;
|
||||||
|
am335x_tsc_se_set(ts_dev->mfd_tscadc, ts_dev->step_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void titsc_read_coordinates(struct titsc *ts_dev,
|
static void titsc_read_coordinates(struct titsc *ts_dev,
|
||||||
|
@ -260,6 +262,10 @@ static irqreturn_t titsc_irq(int irq, void *dev)
|
||||||
unsigned int fsm;
|
unsigned int fsm;
|
||||||
|
|
||||||
status = titsc_readl(ts_dev, REG_IRQSTATUS);
|
status = titsc_readl(ts_dev, REG_IRQSTATUS);
|
||||||
|
/*
|
||||||
|
* ADC and touchscreen share the IRQ line.
|
||||||
|
* FIFO1 interrupts are used by ADC. Handle FIFO0 IRQs here only
|
||||||
|
*/
|
||||||
if (status & IRQENB_FIFO0THRES) {
|
if (status & IRQENB_FIFO0THRES) {
|
||||||
|
|
||||||
titsc_read_coordinates(ts_dev, &x, &y, &z1, &z2);
|
titsc_read_coordinates(ts_dev, &x, &y, &z1, &z2);
|
||||||
|
@ -316,7 +322,7 @@ static irqreturn_t titsc_irq(int irq, void *dev)
|
||||||
|
|
||||||
if (irqclr) {
|
if (irqclr) {
|
||||||
titsc_writel(ts_dev, REG_IRQSTATUS, irqclr);
|
titsc_writel(ts_dev, REG_IRQSTATUS, irqclr);
|
||||||
am335x_tsc_se_update(ts_dev->mfd_tscadc);
|
am335x_tsc_se_set(ts_dev->mfd_tscadc, ts_dev->step_mask);
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
return IRQ_NONE;
|
return IRQ_NONE;
|
||||||
|
@ -389,7 +395,7 @@ static int titsc_probe(struct platform_device *pdev)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = request_irq(ts_dev->irq, titsc_irq,
|
err = request_irq(ts_dev->irq, titsc_irq,
|
||||||
0, pdev->dev.driver->name, ts_dev);
|
IRQF_SHARED, pdev->dev.driver->name, ts_dev);
|
||||||
if (err) {
|
if (err) {
|
||||||
dev_err(&pdev->dev, "failed to allocate irq.\n");
|
dev_err(&pdev->dev, "failed to allocate irq.\n");
|
||||||
goto err_free_mem;
|
goto err_free_mem;
|
||||||
|
|
|
@ -146,11 +146,7 @@ static irqreturn_t lis3l02dq_trigger_handler(int irq, void *p)
|
||||||
if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
|
if (!bitmap_empty(indio_dev->active_scan_mask, indio_dev->masklength))
|
||||||
len = lis3l02dq_get_buffer_element(indio_dev, data);
|
len = lis3l02dq_get_buffer_element(indio_dev, data);
|
||||||
|
|
||||||
/* Guaranteed to be aligned with 8 byte boundary */
|
iio_push_to_buffers_with_timestamp(indio_dev, data, pf->timestamp);
|
||||||
if (indio_dev->scan_timestamp)
|
|
||||||
*(s64 *)((u8 *)data + ALIGN(len, sizeof(s64)))
|
|
||||||
= pf->timestamp;
|
|
||||||
iio_push_to_buffers(indio_dev, (u8 *)data);
|
|
||||||
|
|
||||||
kfree(data);
|
kfree(data);
|
||||||
done:
|
done:
|
||||||
|
|
|
@ -624,9 +624,9 @@ static ssize_t sca3000_set_frequency(struct device *dev,
|
||||||
struct sca3000_state *st = iio_priv(indio_dev);
|
struct sca3000_state *st = iio_priv(indio_dev);
|
||||||
int ret, base_freq = 0;
|
int ret, base_freq = 0;
|
||||||
int ctrlval;
|
int ctrlval;
|
||||||
long val;
|
int val;
|
||||||
|
|
||||||
ret = strict_strtol(buf, 10, &val);
|
ret = kstrtoint(buf, 10, &val);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@ -931,12 +931,12 @@ static ssize_t sca3000_set_free_fall_mode(struct device *dev,
|
||||||
{
|
{
|
||||||
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
||||||
struct sca3000_state *st = iio_priv(indio_dev);
|
struct sca3000_state *st = iio_priv(indio_dev);
|
||||||
long val;
|
u8 val;
|
||||||
int ret;
|
int ret;
|
||||||
u8 protect_mask = SCA3000_FREE_FALL_DETECT;
|
u8 protect_mask = SCA3000_FREE_FALL_DETECT;
|
||||||
|
|
||||||
mutex_lock(&st->lock);
|
mutex_lock(&st->lock);
|
||||||
ret = strict_strtol(buf, 10, &val);
|
ret = kstrtou8(buf, 10, &val);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_ret;
|
goto error_ret;
|
||||||
|
|
||||||
|
|
|
@ -177,11 +177,11 @@ static ssize_t sca3000_set_ring_int(struct device *dev,
|
||||||
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
||||||
struct sca3000_state *st = iio_priv(indio_dev);
|
struct sca3000_state *st = iio_priv(indio_dev);
|
||||||
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
|
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
|
||||||
long val;
|
u8 val;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
mutex_lock(&st->lock);
|
mutex_lock(&st->lock);
|
||||||
ret = strict_strtol(buf, 10, &val);
|
ret = kstrtou8(buf, 10, &val);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_ret;
|
goto error_ret;
|
||||||
ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_INT_MASK, 1);
|
ret = sca3000_read_data_short(st, SCA3000_REG_ADDR_INT_MASK, 1);
|
||||||
|
|
|
@ -623,17 +623,17 @@ static int ad7192_probe(struct spi_device *spi)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
indio_dev = iio_device_alloc(sizeof(*st));
|
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
|
||||||
if (indio_dev == NULL)
|
if (indio_dev == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
st = iio_priv(indio_dev);
|
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)) {
|
if (!IS_ERR(st->reg)) {
|
||||||
ret = regulator_enable(st->reg);
|
ret = regulator_enable(st->reg);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_put_reg;
|
return ret;
|
||||||
|
|
||||||
voltage_uv = regulator_get_voltage(st->reg);
|
voltage_uv = regulator_get_voltage(st->reg);
|
||||||
}
|
}
|
||||||
|
@ -677,11 +677,6 @@ error_remove_trigger:
|
||||||
error_disable_reg:
|
error_disable_reg:
|
||||||
if (!IS_ERR(st->reg))
|
if (!IS_ERR(st->reg))
|
||||||
regulator_disable(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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -694,10 +689,8 @@ static int ad7192_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 (!IS_ERR(st->reg)) {
|
if (!IS_ERR(st->reg))
|
||||||
regulator_disable(st->reg);
|
regulator_disable(st->reg);
|
||||||
regulator_put(st->reg);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -835,8 +835,9 @@ static int ad7280_probe(struct spi_device *spi)
|
||||||
int ret;
|
int ret;
|
||||||
const unsigned short tACQ_ns[4] = {465, 1010, 1460, 1890};
|
const unsigned short tACQ_ns[4] = {465, 1010, 1460, 1890};
|
||||||
const unsigned short nAVG[4] = {1, 2, 4, 8};
|
const unsigned short nAVG[4] = {1, 2, 4, 8};
|
||||||
struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
|
struct iio_dev *indio_dev;
|
||||||
|
|
||||||
|
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
|
||||||
if (indio_dev == NULL)
|
if (indio_dev == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
@ -860,7 +861,7 @@ static int ad7280_probe(struct spi_device *spi)
|
||||||
|
|
||||||
ret = ad7280_chain_setup(st);
|
ret = ad7280_chain_setup(st);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto error_free_device;
|
return ret;
|
||||||
|
|
||||||
st->slave_num = ret;
|
st->slave_num = ret;
|
||||||
st->scan_cnt = (st->slave_num + 1) * AD7280A_NUM_CH;
|
st->scan_cnt = (st->slave_num + 1) * AD7280A_NUM_CH;
|
||||||
|
@ -891,7 +892,7 @@ static int ad7280_probe(struct spi_device *spi)
|
||||||
|
|
||||||
ret = ad7280_channel_init(st);
|
ret = ad7280_channel_init(st);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto error_free_device;
|
return ret;
|
||||||
|
|
||||||
indio_dev->num_channels = ret;
|
indio_dev->num_channels = ret;
|
||||||
indio_dev->channels = st->channels;
|
indio_dev->channels = st->channels;
|
||||||
|
@ -940,9 +941,6 @@ error_free_attr:
|
||||||
error_free_channels:
|
error_free_channels:
|
||||||
kfree(st->channels);
|
kfree(st->channels);
|
||||||
|
|
||||||
error_free_device:
|
|
||||||
iio_device_free(indio_dev);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -960,7 +958,6 @@ static int ad7280_remove(struct spi_device *spi)
|
||||||
|
|
||||||
kfree(st->channels);
|
kfree(st->channels);
|
||||||
kfree(st->iio_attr);
|
kfree(st->iio_attr);
|
||||||
iio_device_free(indio_dev);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -528,21 +528,19 @@ static int ad7291_probe(struct i2c_client *client,
|
||||||
struct iio_dev *indio_dev;
|
struct iio_dev *indio_dev;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
indio_dev = iio_device_alloc(sizeof(*chip));
|
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip));
|
||||||
if (indio_dev == NULL) {
|
if (!indio_dev)
|
||||||
ret = -ENOMEM;
|
return -ENOMEM;
|
||||||
goto error_ret;
|
|
||||||
}
|
|
||||||
chip = iio_priv(indio_dev);
|
chip = iio_priv(indio_dev);
|
||||||
|
|
||||||
if (pdata && pdata->use_external_ref) {
|
if (pdata && pdata->use_external_ref) {
|
||||||
chip->reg = regulator_get(&client->dev, "vref");
|
chip->reg = devm_regulator_get(&client->dev, "vref");
|
||||||
if (IS_ERR(chip->reg))
|
if (IS_ERR(chip->reg))
|
||||||
goto error_free;
|
return ret;
|
||||||
|
|
||||||
ret = regulator_enable(chip->reg);
|
ret = regulator_enable(chip->reg);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_put_reg;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_init(&chip->state_lock);
|
mutex_init(&chip->state_lock);
|
||||||
|
@ -601,12 +599,7 @@ error_unreg_irq:
|
||||||
error_disable_reg:
|
error_disable_reg:
|
||||||
if (chip->reg)
|
if (chip->reg)
|
||||||
regulator_disable(chip->reg);
|
regulator_disable(chip->reg);
|
||||||
error_put_reg:
|
|
||||||
if (chip->reg)
|
|
||||||
regulator_put(chip->reg);
|
|
||||||
error_free:
|
|
||||||
iio_device_free(indio_dev);
|
|
||||||
error_ret:
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -620,12 +613,8 @@ static int ad7291_remove(struct i2c_client *client)
|
||||||
if (client->irq)
|
if (client->irq)
|
||||||
free_irq(client->irq, indio_dev);
|
free_irq(client->irq, indio_dev);
|
||||||
|
|
||||||
if (chip->reg) {
|
if (chip->reg)
|
||||||
regulator_disable(chip->reg);
|
regulator_disable(chip->reg);
|
||||||
regulator_put(chip->reg);
|
|
||||||
}
|
|
||||||
|
|
||||||
iio_device_free(indio_dev);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -425,8 +425,7 @@ static irqreturn_t ad7606_interrupt(int irq, void *dev_id)
|
||||||
struct ad7606_state *st = iio_priv(indio_dev);
|
struct ad7606_state *st = iio_priv(indio_dev);
|
||||||
|
|
||||||
if (iio_buffer_enabled(indio_dev)) {
|
if (iio_buffer_enabled(indio_dev)) {
|
||||||
if (!work_pending(&st->poll_work))
|
schedule_work(&st->poll_work);
|
||||||
schedule_work(&st->poll_work);
|
|
||||||
} else {
|
} else {
|
||||||
st->done = true;
|
st->done = true;
|
||||||
wake_up_interruptible(&st->wq_data_avail);
|
wake_up_interruptible(&st->wq_data_avail);
|
||||||
|
@ -466,12 +465,11 @@ struct iio_dev *ad7606_probe(struct device *dev, int irq,
|
||||||
struct ad7606_platform_data *pdata = dev->platform_data;
|
struct ad7606_platform_data *pdata = dev->platform_data;
|
||||||
struct ad7606_state *st;
|
struct ad7606_state *st;
|
||||||
int ret;
|
int ret;
|
||||||
struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
|
struct iio_dev *indio_dev;
|
||||||
|
|
||||||
if (indio_dev == NULL) {
|
indio_dev = devm_iio_device_alloc(dev, sizeof(*st));
|
||||||
ret = -ENOMEM;
|
if (!indio_dev)
|
||||||
goto error_ret;
|
return ERR_PTR(-ENOMEM);
|
||||||
}
|
|
||||||
|
|
||||||
st = iio_priv(indio_dev);
|
st = iio_priv(indio_dev);
|
||||||
|
|
||||||
|
@ -489,11 +487,11 @@ struct iio_dev *ad7606_probe(struct device *dev, int irq,
|
||||||
st->oversampling = pdata->default_os;
|
st->oversampling = pdata->default_os;
|
||||||
}
|
}
|
||||||
|
|
||||||
st->reg = regulator_get(dev, "vcc");
|
st->reg = devm_regulator_get(dev, "vcc");
|
||||||
if (!IS_ERR(st->reg)) {
|
if (!IS_ERR(st->reg)) {
|
||||||
ret = regulator_enable(st->reg);
|
ret = regulator_enable(st->reg);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_put_reg;
|
return ERR_PTR(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
st->pdata = pdata;
|
st->pdata = pdata;
|
||||||
|
@ -554,11 +552,6 @@ error_free_gpios:
|
||||||
error_disable_reg:
|
error_disable_reg:
|
||||||
if (!IS_ERR(st->reg))
|
if (!IS_ERR(st->reg))
|
||||||
regulator_disable(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 ERR_PTR(ret);
|
return ERR_PTR(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -570,13 +563,10 @@ int ad7606_remove(struct iio_dev *indio_dev, int irq)
|
||||||
ad7606_ring_cleanup(indio_dev);
|
ad7606_ring_cleanup(indio_dev);
|
||||||
|
|
||||||
free_irq(irq, indio_dev);
|
free_irq(irq, indio_dev);
|
||||||
if (!IS_ERR(st->reg)) {
|
if (!IS_ERR(st->reg))
|
||||||
regulator_disable(st->reg);
|
regulator_disable(st->reg);
|
||||||
regulator_put(st->reg);
|
|
||||||
}
|
|
||||||
|
|
||||||
ad7606_free_gpios(st);
|
ad7606_free_gpios(st);
|
||||||
iio_device_free(indio_dev);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,6 @@ static void ad7606_poll_bh_to_ring(struct work_struct *work_s)
|
||||||
struct ad7606_state *st = container_of(work_s, struct ad7606_state,
|
struct ad7606_state *st = container_of(work_s, struct ad7606_state,
|
||||||
poll_work);
|
poll_work);
|
||||||
struct iio_dev *indio_dev = iio_priv_to_dev(st);
|
struct iio_dev *indio_dev = iio_priv_to_dev(st);
|
||||||
s64 time_ns;
|
|
||||||
__u8 *buf;
|
__u8 *buf;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -78,12 +77,7 @@ static void ad7606_poll_bh_to_ring(struct work_struct *work_s)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
time_ns = iio_get_time_ns();
|
iio_push_to_buffers_with_timestamp(indio_dev, buf, iio_get_time_ns());
|
||||||
|
|
||||||
if (indio_dev->scan_timestamp)
|
|
||||||
*((s64 *)(buf + indio_dev->scan_bytes - sizeof(s64))) = time_ns;
|
|
||||||
|
|
||||||
iio_push_to_buffers(indio_dev, buf);
|
|
||||||
done:
|
done:
|
||||||
gpio_set_value(st->pdata->gpio_convst, 0);
|
gpio_set_value(st->pdata->gpio_convst, 0);
|
||||||
iio_trigger_notify_done(indio_dev->trig);
|
iio_trigger_notify_done(indio_dev->trig);
|
||||||
|
|
|
@ -171,7 +171,7 @@ static int 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;
|
||||||
|
|
||||||
indio_dev = iio_device_alloc(sizeof(*st));
|
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
|
||||||
if (indio_dev == NULL)
|
if (indio_dev == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
@ -180,11 +180,11 @@ static int ad7780_probe(struct spi_device *spi)
|
||||||
|
|
||||||
ad_sd_init(&st->sd, indio_dev, spi, &ad7780_sigma_delta_info);
|
ad_sd_init(&st->sd, indio_dev, spi, &ad7780_sigma_delta_info);
|
||||||
|
|
||||||
st->reg = regulator_get(&spi->dev, "vcc");
|
st->reg = devm_regulator_get(&spi->dev, "vcc");
|
||||||
if (!IS_ERR(st->reg)) {
|
if (!IS_ERR(st->reg)) {
|
||||||
ret = regulator_enable(st->reg);
|
ret = regulator_enable(st->reg);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_put_reg;
|
return ret;
|
||||||
|
|
||||||
voltage_uv = regulator_get_voltage(st->reg);
|
voltage_uv = regulator_get_voltage(st->reg);
|
||||||
}
|
}
|
||||||
|
@ -210,8 +210,8 @@ static int ad7780_probe(struct spi_device *spi)
|
||||||
|
|
||||||
if (pdata && gpio_is_valid(pdata->gpio_pdrst)) {
|
if (pdata && gpio_is_valid(pdata->gpio_pdrst)) {
|
||||||
|
|
||||||
ret = gpio_request_one(pdata->gpio_pdrst, GPIOF_OUT_INIT_LOW,
|
ret = devm_gpio_request_one(&spi->dev, pdata->gpio_pdrst,
|
||||||
"AD7780 /PDRST");
|
GPIOF_OUT_INIT_LOW, "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;
|
||||||
|
@ -223,7 +223,7 @@ static int ad7780_probe(struct spi_device *spi)
|
||||||
|
|
||||||
ret = ad_sd_setup_buffer_and_trigger(indio_dev);
|
ret = ad_sd_setup_buffer_and_trigger(indio_dev);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_free_gpio;
|
goto error_disable_reg;
|
||||||
|
|
||||||
ret = iio_device_register(indio_dev);
|
ret = iio_device_register(indio_dev);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -233,17 +233,9 @@ static int 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:
|
|
||||||
if (pdata && gpio_is_valid(pdata->gpio_pdrst))
|
|
||||||
gpio_free(pdata->gpio_pdrst);
|
|
||||||
error_disable_reg:
|
error_disable_reg:
|
||||||
if (!IS_ERR(st->reg))
|
if (!IS_ERR(st->reg))
|
||||||
regulator_disable(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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -256,14 +248,8 @@ static int 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))
|
if (!IS_ERR(st->reg))
|
||||||
gpio_free(st->powerdown_gpio);
|
|
||||||
|
|
||||||
if (!IS_ERR(st->reg)) {
|
|
||||||
regulator_disable(st->reg);
|
regulator_disable(st->reg);
|
||||||
regulator_put(st->reg);
|
|
||||||
}
|
|
||||||
iio_device_free(indio_dev);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -356,11 +356,9 @@ static int ad7816_probe(struct spi_device *spi_dev)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
indio_dev = iio_device_alloc(sizeof(*chip));
|
indio_dev = devm_iio_device_alloc(&spi_dev->dev, sizeof(*chip));
|
||||||
if (indio_dev == NULL) {
|
if (!indio_dev)
|
||||||
ret = -ENOMEM;
|
return -ENOMEM;
|
||||||
goto error_ret;
|
|
||||||
}
|
|
||||||
chip = iio_priv(indio_dev);
|
chip = iio_priv(indio_dev);
|
||||||
/* this is only used for device removal purposes */
|
/* this is only used for device removal purposes */
|
||||||
dev_set_drvdata(&spi_dev->dev, indio_dev);
|
dev_set_drvdata(&spi_dev->dev, indio_dev);
|
||||||
|
@ -372,25 +370,28 @@ static int ad7816_probe(struct spi_device *spi_dev)
|
||||||
chip->convert_pin = pins[1];
|
chip->convert_pin = pins[1];
|
||||||
chip->busy_pin = pins[2];
|
chip->busy_pin = pins[2];
|
||||||
|
|
||||||
ret = gpio_request(chip->rdwr_pin, spi_get_device_id(spi_dev)->name);
|
ret = devm_gpio_request(&spi_dev->dev, chip->rdwr_pin,
|
||||||
|
spi_get_device_id(spi_dev)->name);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(&spi_dev->dev, "Fail to request rdwr gpio PIN %d.\n",
|
dev_err(&spi_dev->dev, "Fail to request rdwr gpio PIN %d.\n",
|
||||||
chip->rdwr_pin);
|
chip->rdwr_pin);
|
||||||
goto error_free_device;
|
return ret;
|
||||||
}
|
}
|
||||||
gpio_direction_input(chip->rdwr_pin);
|
gpio_direction_input(chip->rdwr_pin);
|
||||||
ret = gpio_request(chip->convert_pin, spi_get_device_id(spi_dev)->name);
|
ret = devm_gpio_request(&spi_dev->dev, chip->convert_pin,
|
||||||
|
spi_get_device_id(spi_dev)->name);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(&spi_dev->dev, "Fail to request convert gpio PIN %d.\n",
|
dev_err(&spi_dev->dev, "Fail to request convert gpio PIN %d.\n",
|
||||||
chip->convert_pin);
|
chip->convert_pin);
|
||||||
goto error_free_gpio_rdwr;
|
return ret;
|
||||||
}
|
}
|
||||||
gpio_direction_input(chip->convert_pin);
|
gpio_direction_input(chip->convert_pin);
|
||||||
ret = gpio_request(chip->busy_pin, spi_get_device_id(spi_dev)->name);
|
ret = devm_gpio_request(&spi_dev->dev, chip->busy_pin,
|
||||||
|
spi_get_device_id(spi_dev)->name);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(&spi_dev->dev, "Fail to request busy gpio PIN %d.\n",
|
dev_err(&spi_dev->dev, "Fail to request busy gpio PIN %d.\n",
|
||||||
chip->busy_pin);
|
chip->busy_pin);
|
||||||
goto error_free_gpio_convert;
|
return ret;
|
||||||
}
|
}
|
||||||
gpio_direction_input(chip->busy_pin);
|
gpio_direction_input(chip->busy_pin);
|
||||||
|
|
||||||
|
@ -401,51 +402,31 @@ static int ad7816_probe(struct spi_device *spi_dev)
|
||||||
|
|
||||||
if (spi_dev->irq) {
|
if (spi_dev->irq) {
|
||||||
/* Only low trigger is supported in ad7816/7/8 */
|
/* Only low trigger is supported in ad7816/7/8 */
|
||||||
ret = request_threaded_irq(spi_dev->irq,
|
ret = devm_request_threaded_irq(&spi_dev->dev, spi_dev->irq,
|
||||||
NULL,
|
NULL,
|
||||||
&ad7816_event_handler,
|
&ad7816_event_handler,
|
||||||
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
|
IRQF_TRIGGER_LOW | IRQF_ONESHOT,
|
||||||
indio_dev->name,
|
indio_dev->name,
|
||||||
indio_dev);
|
indio_dev);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_free_gpio;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = iio_device_register(indio_dev);
|
ret = iio_device_register(indio_dev);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_free_irq;
|
return ret;
|
||||||
|
|
||||||
dev_info(&spi_dev->dev, "%s temperature sensor and ADC registered.\n",
|
dev_info(&spi_dev->dev, "%s temperature sensor and ADC registered.\n",
|
||||||
indio_dev->name);
|
indio_dev->name);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
error_free_irq:
|
|
||||||
free_irq(spi_dev->irq, indio_dev);
|
|
||||||
error_free_gpio:
|
|
||||||
gpio_free(chip->busy_pin);
|
|
||||||
error_free_gpio_convert:
|
|
||||||
gpio_free(chip->convert_pin);
|
|
||||||
error_free_gpio_rdwr:
|
|
||||||
gpio_free(chip->rdwr_pin);
|
|
||||||
error_free_device:
|
|
||||||
iio_device_free(indio_dev);
|
|
||||||
error_ret:
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ad7816_remove(struct spi_device *spi_dev)
|
static int ad7816_remove(struct spi_device *spi_dev)
|
||||||
{
|
{
|
||||||
struct iio_dev *indio_dev = dev_get_drvdata(&spi_dev->dev);
|
struct iio_dev *indio_dev = dev_get_drvdata(&spi_dev->dev);
|
||||||
struct ad7816_chip_info *chip = iio_priv(indio_dev);
|
|
||||||
|
|
||||||
iio_device_unregister(indio_dev);
|
iio_device_unregister(indio_dev);
|
||||||
dev_set_drvdata(&spi_dev->dev, NULL);
|
|
||||||
if (spi_dev->irq)
|
|
||||||
free_irq(spi_dev->irq, indio_dev);
|
|
||||||
gpio_free(chip->busy_pin);
|
|
||||||
gpio_free(chip->convert_pin);
|
|
||||||
gpio_free(chip->rdwr_pin);
|
|
||||||
iio_device_free(indio_dev);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -586,8 +586,9 @@ static int ad799x_probe(struct i2c_client *client,
|
||||||
int ret;
|
int ret;
|
||||||
struct ad799x_platform_data *pdata = client->dev.platform_data;
|
struct ad799x_platform_data *pdata = client->dev.platform_data;
|
||||||
struct ad799x_state *st;
|
struct ad799x_state *st;
|
||||||
struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
|
struct iio_dev *indio_dev;
|
||||||
|
|
||||||
|
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st));
|
||||||
if (indio_dev == NULL)
|
if (indio_dev == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
@ -606,11 +607,11 @@ static int ad799x_probe(struct i2c_client *client,
|
||||||
|
|
||||||
st->int_vref_mv = pdata->vref_mv;
|
st->int_vref_mv = pdata->vref_mv;
|
||||||
|
|
||||||
st->reg = regulator_get(&client->dev, "vcc");
|
st->reg = devm_regulator_get(&client->dev, "vcc");
|
||||||
if (!IS_ERR(st->reg)) {
|
if (!IS_ERR(st->reg)) {
|
||||||
ret = regulator_enable(st->reg);
|
ret = regulator_enable(st->reg);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_put_reg;
|
return ret;
|
||||||
}
|
}
|
||||||
st->client = client;
|
st->client = client;
|
||||||
|
|
||||||
|
@ -650,10 +651,6 @@ error_cleanup_ring:
|
||||||
error_disable_reg:
|
error_disable_reg:
|
||||||
if (!IS_ERR(st->reg))
|
if (!IS_ERR(st->reg))
|
||||||
regulator_disable(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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -668,12 +665,9 @@ static int ad799x_remove(struct i2c_client *client)
|
||||||
free_irq(client->irq, indio_dev);
|
free_irq(client->irq, indio_dev);
|
||||||
|
|
||||||
ad799x_ring_cleanup(indio_dev);
|
ad799x_ring_cleanup(indio_dev);
|
||||||
if (!IS_ERR(st->reg)) {
|
if (!IS_ERR(st->reg))
|
||||||
regulator_disable(st->reg);
|
regulator_disable(st->reg);
|
||||||
regulator_put(st->reg);
|
|
||||||
}
|
|
||||||
kfree(st->rx_buf);
|
kfree(st->rx_buf);
|
||||||
iio_device_free(indio_dev);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,6 @@ static irqreturn_t ad799x_trigger_handler(int irq, void *p)
|
||||||
struct iio_poll_func *pf = p;
|
struct iio_poll_func *pf = p;
|
||||||
struct iio_dev *indio_dev = pf->indio_dev;
|
struct iio_dev *indio_dev = pf->indio_dev;
|
||||||
struct ad799x_state *st = iio_priv(indio_dev);
|
struct ad799x_state *st = iio_priv(indio_dev);
|
||||||
s64 time_ns;
|
|
||||||
int b_sent;
|
int b_sent;
|
||||||
u8 cmd;
|
u8 cmd;
|
||||||
|
|
||||||
|
@ -65,13 +64,8 @@ static irqreturn_t ad799x_trigger_handler(int irq, void *p)
|
||||||
if (b_sent < 0)
|
if (b_sent < 0)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
time_ns = iio_get_time_ns();
|
iio_push_to_buffers_with_timestamp(indio_dev, st->rx_buf,
|
||||||
|
iio_get_time_ns());
|
||||||
if (indio_dev->scan_timestamp)
|
|
||||||
memcpy(st->rx_buf + indio_dev->scan_bytes - sizeof(s64),
|
|
||||||
&time_ns, sizeof(time_ns));
|
|
||||||
|
|
||||||
iio_push_to_buffers(indio_dev, st->rx_buf);
|
|
||||||
out:
|
out:
|
||||||
iio_trigger_notify_done(indio_dev->trig);
|
iio_trigger_notify_done(indio_dev->trig);
|
||||||
|
|
||||||
|
|
|
@ -137,43 +137,39 @@ static int lpc32xx_adc_probe(struct platform_device *pdev)
|
||||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
if (!res) {
|
if (!res) {
|
||||||
dev_err(&pdev->dev, "failed to get platform I/O memory\n");
|
dev_err(&pdev->dev, "failed to get platform I/O memory\n");
|
||||||
retval = -EBUSY;
|
return -EBUSY;
|
||||||
goto errout1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
iodev = iio_device_alloc(sizeof(struct lpc32xx_adc_info));
|
iodev = devm_iio_device_alloc(&pdev->dev, sizeof(*info));
|
||||||
if (!iodev) {
|
if (!iodev)
|
||||||
dev_err(&pdev->dev, "failed allocating iio device\n");
|
return -ENOMEM;
|
||||||
retval = -ENOMEM;
|
|
||||||
goto errout1;
|
|
||||||
}
|
|
||||||
|
|
||||||
info = iio_priv(iodev);
|
info = iio_priv(iodev);
|
||||||
|
|
||||||
info->adc_base = ioremap(res->start, resource_size(res));
|
info->adc_base = devm_ioremap(&pdev->dev, res->start,
|
||||||
|
resource_size(res));
|
||||||
if (!info->adc_base) {
|
if (!info->adc_base) {
|
||||||
dev_err(&pdev->dev, "failed mapping memory\n");
|
dev_err(&pdev->dev, "failed mapping memory\n");
|
||||||
retval = -EBUSY;
|
return -EBUSY;
|
||||||
goto errout2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
info->clk = clk_get(&pdev->dev, NULL);
|
info->clk = devm_clk_get(&pdev->dev, NULL);
|
||||||
if (IS_ERR(info->clk)) {
|
if (IS_ERR(info->clk)) {
|
||||||
dev_err(&pdev->dev, "failed getting clock\n");
|
dev_err(&pdev->dev, "failed getting clock\n");
|
||||||
goto errout3;
|
return PTR_ERR(info->clk);
|
||||||
}
|
}
|
||||||
|
|
||||||
irq = platform_get_irq(pdev, 0);
|
irq = platform_get_irq(pdev, 0);
|
||||||
if ((irq < 0) || (irq >= NR_IRQS)) {
|
if ((irq < 0) || (irq >= NR_IRQS)) {
|
||||||
dev_err(&pdev->dev, "failed getting interrupt resource\n");
|
dev_err(&pdev->dev, "failed getting interrupt resource\n");
|
||||||
retval = -EINVAL;
|
return -EINVAL;
|
||||||
goto errout4;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = request_irq(irq, lpc32xx_adc_isr, 0, MOD_NAME, info);
|
retval = devm_request_irq(&pdev->dev, irq, lpc32xx_adc_isr, 0,
|
||||||
|
MOD_NAME, info);
|
||||||
if (retval < 0) {
|
if (retval < 0) {
|
||||||
dev_err(&pdev->dev, "failed requesting interrupt\n");
|
dev_err(&pdev->dev, "failed requesting interrupt\n");
|
||||||
goto errout4;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
platform_set_drvdata(pdev, iodev);
|
platform_set_drvdata(pdev, iodev);
|
||||||
|
@ -189,35 +185,18 @@ static int lpc32xx_adc_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
retval = iio_device_register(iodev);
|
retval = iio_device_register(iodev);
|
||||||
if (retval)
|
if (retval)
|
||||||
goto errout5;
|
return retval;
|
||||||
|
|
||||||
dev_info(&pdev->dev, "LPC32XX ADC driver loaded, IRQ %d\n", irq);
|
dev_info(&pdev->dev, "LPC32XX ADC driver loaded, IRQ %d\n", irq);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
errout5:
|
|
||||||
free_irq(irq, info);
|
|
||||||
errout4:
|
|
||||||
clk_put(info->clk);
|
|
||||||
errout3:
|
|
||||||
iounmap(info->adc_base);
|
|
||||||
errout2:
|
|
||||||
iio_device_free(iodev);
|
|
||||||
errout1:
|
|
||||||
return retval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lpc32xx_adc_remove(struct platform_device *pdev)
|
static int lpc32xx_adc_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct iio_dev *iodev = platform_get_drvdata(pdev);
|
struct iio_dev *iodev = platform_get_drvdata(pdev);
|
||||||
struct lpc32xx_adc_info *info = iio_priv(iodev);
|
|
||||||
int irq = platform_get_irq(pdev, 0);
|
|
||||||
|
|
||||||
iio_device_unregister(iodev);
|
iio_device_unregister(iodev);
|
||||||
free_irq(irq, info);
|
|
||||||
clk_put(info->clk);
|
|
||||||
iounmap(info->adc_base);
|
|
||||||
iio_device_free(iodev);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -625,13 +625,7 @@ static irqreturn_t mxs_lradc_trigger_handler(int irq, void *p)
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iio->scan_timestamp) {
|
iio_push_to_buffers_with_timestamp(iio, lradc->buffer, pf->timestamp);
|
||||||
s64 *timestamp = (s64 *)((u8 *)lradc->buffer +
|
|
||||||
ALIGN(j, sizeof(s64)));
|
|
||||||
*timestamp = pf->timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
iio_push_to_buffers(iio, (u8 *)lradc->buffer);
|
|
||||||
|
|
||||||
iio_trigger_notify_done(iio->trig);
|
iio_trigger_notify_done(iio->trig);
|
||||||
|
|
||||||
|
@ -987,7 +981,7 @@ static int mxs_lradc_probe(struct platform_device *pdev)
|
||||||
/* Register the touchscreen input device. */
|
/* Register the touchscreen input device. */
|
||||||
ret = mxs_lradc_ts_register(lradc);
|
ret = mxs_lradc_ts_register(lradc);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto err_dev;
|
goto err_ts_register;
|
||||||
|
|
||||||
/* Register IIO device. */
|
/* Register IIO device. */
|
||||||
ret = iio_device_register(iio);
|
ret = iio_device_register(iio);
|
||||||
|
@ -1000,6 +994,8 @@ static int mxs_lradc_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
err_ts:
|
err_ts:
|
||||||
mxs_lradc_ts_unregister(lradc);
|
mxs_lradc_ts_unregister(lradc);
|
||||||
|
err_ts_register:
|
||||||
|
mxs_lradc_hw_stop(lradc);
|
||||||
err_dev:
|
err_dev:
|
||||||
mxs_lradc_trigger_remove(iio);
|
mxs_lradc_trigger_remove(iio);
|
||||||
err_trig:
|
err_trig:
|
||||||
|
@ -1012,13 +1008,11 @@ static int mxs_lradc_remove(struct platform_device *pdev)
|
||||||
struct iio_dev *iio = platform_get_drvdata(pdev);
|
struct iio_dev *iio = platform_get_drvdata(pdev);
|
||||||
struct mxs_lradc *lradc = iio_priv(iio);
|
struct mxs_lradc *lradc = iio_priv(iio);
|
||||||
|
|
||||||
mxs_lradc_ts_unregister(lradc);
|
|
||||||
|
|
||||||
mxs_lradc_hw_stop(lradc);
|
|
||||||
|
|
||||||
iio_device_unregister(iio);
|
iio_device_unregister(iio);
|
||||||
iio_triggered_buffer_cleanup(iio);
|
mxs_lradc_ts_unregister(lradc);
|
||||||
|
mxs_lradc_hw_stop(lradc);
|
||||||
mxs_lradc_trigger_remove(iio);
|
mxs_lradc_trigger_remove(iio);
|
||||||
|
iio_triggered_buffer_cleanup(iio);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1038,3 +1032,4 @@ module_platform_driver(mxs_lradc_driver);
|
||||||
MODULE_AUTHOR("Marek Vasut <marex@denx.de>");
|
MODULE_AUTHOR("Marek Vasut <marex@denx.de>");
|
||||||
MODULE_DESCRIPTION("Freescale i.MX28 LRADC driver");
|
MODULE_DESCRIPTION("Freescale i.MX28 LRADC driver");
|
||||||
MODULE_LICENSE("GPL v2");
|
MODULE_LICENSE("GPL v2");
|
||||||
|
MODULE_ALIAS("platform:" DRIVER_NAME);
|
||||||
|
|
|
@ -412,13 +412,13 @@ static ssize_t adt7316_store_ad_channel(struct device *dev,
|
||||||
struct iio_dev *dev_info = dev_to_iio_dev(dev);
|
struct iio_dev *dev_info = dev_to_iio_dev(dev);
|
||||||
struct adt7316_chip_info *chip = iio_priv(dev_info);
|
struct adt7316_chip_info *chip = iio_priv(dev_info);
|
||||||
u8 config2;
|
u8 config2;
|
||||||
unsigned long data = 0;
|
u8 data;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!(chip->config2 & ADT7316_AD_SINGLE_CH_MODE))
|
if (!(chip->config2 & ADT7316_AD_SINGLE_CH_MODE))
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
||||||
ret = strict_strtoul(buf, 10, &data);
|
ret = kstrtou8(buf, 10, &data);
|
||||||
if (ret)
|
if (ret)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
@ -823,10 +823,10 @@ static ssize_t adt7316_store_DAC_2Vref_ch_mask(struct device *dev,
|
||||||
struct iio_dev *dev_info = dev_to_iio_dev(dev);
|
struct iio_dev *dev_info = dev_to_iio_dev(dev);
|
||||||
struct adt7316_chip_info *chip = iio_priv(dev_info);
|
struct adt7316_chip_info *chip = iio_priv(dev_info);
|
||||||
u8 dac_config;
|
u8 dac_config;
|
||||||
unsigned long data = 0;
|
u8 data;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = strict_strtoul(buf, 16, &data);
|
ret = kstrtou8(buf, 16, &data);
|
||||||
if (ret || data > ADT7316_DA_2VREF_CH_MASK)
|
if (ret || data > ADT7316_DA_2VREF_CH_MASK)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
@ -878,13 +878,13 @@ static ssize_t adt7316_store_DAC_update_mode(struct device *dev,
|
||||||
struct iio_dev *dev_info = dev_to_iio_dev(dev);
|
struct iio_dev *dev_info = dev_to_iio_dev(dev);
|
||||||
struct adt7316_chip_info *chip = iio_priv(dev_info);
|
struct adt7316_chip_info *chip = iio_priv(dev_info);
|
||||||
u8 dac_config;
|
u8 dac_config;
|
||||||
unsigned long data;
|
u8 data;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (!(chip->config3 & ADT7316_DA_EN_VIA_DAC_LDCA))
|
if (!(chip->config3 & ADT7316_DA_EN_VIA_DAC_LDCA))
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
||||||
ret = strict_strtoul(buf, 10, &data);
|
ret = kstrtou8(buf, 10, &data);
|
||||||
if (ret || data > ADT7316_DA_EN_MODE_MASK)
|
if (ret || data > ADT7316_DA_EN_MODE_MASK)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
@ -933,7 +933,7 @@ static ssize_t adt7316_store_update_DAC(struct device *dev,
|
||||||
struct iio_dev *dev_info = dev_to_iio_dev(dev);
|
struct iio_dev *dev_info = dev_to_iio_dev(dev);
|
||||||
struct adt7316_chip_info *chip = iio_priv(dev_info);
|
struct adt7316_chip_info *chip = iio_priv(dev_info);
|
||||||
u8 ldac_config;
|
u8 ldac_config;
|
||||||
unsigned long data;
|
u8 data;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (chip->config3 & ADT7316_DA_EN_VIA_DAC_LDCA) {
|
if (chip->config3 & ADT7316_DA_EN_VIA_DAC_LDCA) {
|
||||||
|
@ -941,7 +941,7 @@ static ssize_t adt7316_store_update_DAC(struct device *dev,
|
||||||
ADT7316_DA_EN_MODE_LDAC)
|
ADT7316_DA_EN_MODE_LDAC)
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
||||||
ret = strict_strtoul(buf, 16, &data);
|
ret = kstrtou8(buf, 16, &data);
|
||||||
if (ret || data > ADT7316_LDAC_EN_DA_MASK)
|
if (ret || data > ADT7316_LDAC_EN_DA_MASK)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
@ -1079,11 +1079,11 @@ static ssize_t adt7316_store_DAC_internal_Vref(struct device *dev,
|
||||||
struct iio_dev *dev_info = dev_to_iio_dev(dev);
|
struct iio_dev *dev_info = dev_to_iio_dev(dev);
|
||||||
struct adt7316_chip_info *chip = iio_priv(dev_info);
|
struct adt7316_chip_info *chip = iio_priv(dev_info);
|
||||||
u8 ldac_config;
|
u8 ldac_config;
|
||||||
unsigned long data;
|
u8 data;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) {
|
if ((chip->id & ID_FAMILY_MASK) == ID_ADT75XX) {
|
||||||
ret = strict_strtoul(buf, 16, &data);
|
ret = kstrtou8(buf, 16, &data);
|
||||||
if (ret || data > 3)
|
if (ret || data > 3)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
@ -1093,7 +1093,7 @@ static ssize_t adt7316_store_DAC_internal_Vref(struct device *dev,
|
||||||
else if (data & 0x2)
|
else if (data & 0x2)
|
||||||
ldac_config |= ADT7516_DAC_CD_IN_VREF;
|
ldac_config |= ADT7516_DAC_CD_IN_VREF;
|
||||||
} else {
|
} else {
|
||||||
ret = strict_strtoul(buf, 16, &data);
|
ret = kstrtou8(buf, 16, &data);
|
||||||
if (ret)
|
if (ret)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
@ -1281,11 +1281,11 @@ static ssize_t adt7316_show_temp_offset(struct adt7316_chip_info *chip,
|
||||||
static ssize_t adt7316_store_temp_offset(struct adt7316_chip_info *chip,
|
static ssize_t adt7316_store_temp_offset(struct adt7316_chip_info *chip,
|
||||||
int offset_addr, const char *buf, size_t len)
|
int offset_addr, const char *buf, size_t len)
|
||||||
{
|
{
|
||||||
long data;
|
int data;
|
||||||
u8 val;
|
u8 val;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = strict_strtol(buf, 10, &data);
|
ret = kstrtoint(buf, 10, &data);
|
||||||
if (ret || data > 127 || data < -128)
|
if (ret || data > 127 || data < -128)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
@ -1442,7 +1442,7 @@ static ssize_t adt7316_store_DAC(struct adt7316_chip_info *chip,
|
||||||
int channel, const char *buf, size_t len)
|
int channel, const char *buf, size_t len)
|
||||||
{
|
{
|
||||||
u8 msb, lsb, offset;
|
u8 msb, lsb, offset;
|
||||||
unsigned long data;
|
u16 data;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
if (channel >= ADT7316_DA_MSB_DATA_REGS ||
|
if (channel >= ADT7316_DA_MSB_DATA_REGS ||
|
||||||
|
@ -1454,7 +1454,7 @@ static ssize_t adt7316_store_DAC(struct adt7316_chip_info *chip,
|
||||||
|
|
||||||
offset = chip->dac_bits - 8;
|
offset = chip->dac_bits - 8;
|
||||||
|
|
||||||
ret = strict_strtoul(buf, 10, &data);
|
ret = kstrtou16(buf, 10, &data);
|
||||||
if (ret || data >= (1 << chip->dac_bits))
|
if (ret || data >= (1 << chip->dac_bits))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
@ -1830,11 +1830,11 @@ static ssize_t adt7316_set_int_mask(struct device *dev,
|
||||||
{
|
{
|
||||||
struct iio_dev *dev_info = dev_to_iio_dev(dev);
|
struct iio_dev *dev_info = dev_to_iio_dev(dev);
|
||||||
struct adt7316_chip_info *chip = iio_priv(dev_info);
|
struct adt7316_chip_info *chip = iio_priv(dev_info);
|
||||||
unsigned long data;
|
u16 data;
|
||||||
int ret;
|
int ret;
|
||||||
u8 mask;
|
u8 mask;
|
||||||
|
|
||||||
ret = strict_strtoul(buf, 16, &data);
|
ret = kstrtou16(buf, 16, &data);
|
||||||
if (ret || data >= ADT7316_VDD_INT_MASK + 1)
|
if (ret || data >= ADT7316_VDD_INT_MASK + 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
@ -1901,7 +1901,7 @@ static inline ssize_t adt7316_set_ad_bound(struct device *dev,
|
||||||
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
|
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
|
||||||
struct iio_dev *dev_info = dev_to_iio_dev(dev);
|
struct iio_dev *dev_info = dev_to_iio_dev(dev);
|
||||||
struct adt7316_chip_info *chip = iio_priv(dev_info);
|
struct adt7316_chip_info *chip = iio_priv(dev_info);
|
||||||
long data;
|
int data;
|
||||||
u8 val;
|
u8 val;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -1909,7 +1909,7 @@ static inline ssize_t adt7316_set_ad_bound(struct device *dev,
|
||||||
this_attr->address > ADT7316_EX_TEMP_LOW)
|
this_attr->address > ADT7316_EX_TEMP_LOW)
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
||||||
ret = strict_strtol(buf, 10, &data);
|
ret = kstrtoint(buf, 10, &data);
|
||||||
if (ret)
|
if (ret)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
@ -2106,11 +2106,9 @@ int adt7316_probe(struct device *dev, struct adt7316_bus *bus,
|
||||||
unsigned short *adt7316_platform_data = dev->platform_data;
|
unsigned short *adt7316_platform_data = dev->platform_data;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
indio_dev = iio_device_alloc(sizeof(*chip));
|
indio_dev = devm_iio_device_alloc(dev, sizeof(*chip));
|
||||||
if (indio_dev == NULL) {
|
if (!indio_dev)
|
||||||
ret = -ENOMEM;
|
return -ENOMEM;
|
||||||
goto error_ret;
|
|
||||||
}
|
|
||||||
chip = iio_priv(indio_dev);
|
chip = iio_priv(indio_dev);
|
||||||
/* this is only used for device removal purposes */
|
/* this is only used for device removal purposes */
|
||||||
dev_set_drvdata(dev, indio_dev);
|
dev_set_drvdata(dev, indio_dev);
|
||||||
|
@ -2146,58 +2144,44 @@ int adt7316_probe(struct device *dev, struct adt7316_bus *bus,
|
||||||
if (adt7316_platform_data[0])
|
if (adt7316_platform_data[0])
|
||||||
chip->bus.irq_flags = adt7316_platform_data[0];
|
chip->bus.irq_flags = adt7316_platform_data[0];
|
||||||
|
|
||||||
ret = request_threaded_irq(chip->bus.irq,
|
ret = devm_request_threaded_irq(dev, chip->bus.irq,
|
||||||
NULL,
|
NULL,
|
||||||
&adt7316_event_handler,
|
&adt7316_event_handler,
|
||||||
chip->bus.irq_flags | IRQF_ONESHOT,
|
chip->bus.irq_flags |
|
||||||
indio_dev->name,
|
IRQF_ONESHOT,
|
||||||
indio_dev);
|
indio_dev->name,
|
||||||
|
indio_dev);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_free_dev;
|
return ret;
|
||||||
|
|
||||||
if (chip->bus.irq_flags & IRQF_TRIGGER_HIGH)
|
if (chip->bus.irq_flags & IRQF_TRIGGER_HIGH)
|
||||||
chip->config1 |= ADT7316_INT_POLARITY;
|
chip->config1 |= ADT7316_INT_POLARITY;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG1, chip->config1);
|
ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG1, chip->config1);
|
||||||
if (ret) {
|
if (ret)
|
||||||
ret = -EIO;
|
return -EIO;
|
||||||
goto error_unreg_irq;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG3, chip->config3);
|
ret = chip->bus.write(chip->bus.client, ADT7316_CONFIG3, chip->config3);
|
||||||
if (ret) {
|
if (ret)
|
||||||
ret = -EIO;
|
return -EIO;
|
||||||
goto error_unreg_irq;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = iio_device_register(indio_dev);
|
ret = iio_device_register(indio_dev);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_unreg_irq;
|
return ret;
|
||||||
|
|
||||||
dev_info(dev, "%s temperature sensor, ADC and DAC registered.\n",
|
dev_info(dev, "%s temperature sensor, ADC and DAC registered.\n",
|
||||||
indio_dev->name);
|
indio_dev->name);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error_unreg_irq:
|
|
||||||
free_irq(chip->bus.irq, indio_dev);
|
|
||||||
error_free_dev:
|
|
||||||
iio_device_free(indio_dev);
|
|
||||||
error_ret:
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(adt7316_probe);
|
EXPORT_SYMBOL(adt7316_probe);
|
||||||
|
|
||||||
int adt7316_remove(struct device *dev)
|
int adt7316_remove(struct device *dev)
|
||||||
{
|
{
|
||||||
struct iio_dev *indio_dev = dev_get_drvdata(dev);
|
struct iio_dev *indio_dev = dev_get_drvdata(dev);
|
||||||
struct adt7316_chip_info *chip = iio_priv(indio_dev);
|
|
||||||
|
|
||||||
iio_device_unregister(indio_dev);
|
iio_device_unregister(indio_dev);
|
||||||
if (chip->bus.irq)
|
|
||||||
free_irq(chip->bus.irq, indio_dev);
|
|
||||||
iio_device_free(indio_dev);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -94,11 +94,9 @@ static int ad5930_probe(struct spi_device *spi)
|
||||||
struct iio_dev *idev;
|
struct iio_dev *idev;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
idev = iio_device_alloc(sizeof(*st));
|
idev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
|
||||||
if (idev == NULL) {
|
if (!idev)
|
||||||
ret = -ENOMEM;
|
return -ENOMEM;
|
||||||
goto error_ret;
|
|
||||||
}
|
|
||||||
spi_set_drvdata(spi, idev);
|
spi_set_drvdata(spi, idev);
|
||||||
st = iio_priv(idev);
|
st = iio_priv(idev);
|
||||||
|
|
||||||
|
@ -110,24 +108,18 @@ static int ad5930_probe(struct spi_device *spi)
|
||||||
|
|
||||||
ret = iio_device_register(idev);
|
ret = iio_device_register(idev);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_free_dev;
|
return ret;
|
||||||
spi->max_speed_hz = 2000000;
|
spi->max_speed_hz = 2000000;
|
||||||
spi->mode = SPI_MODE_3;
|
spi->mode = SPI_MODE_3;
|
||||||
spi->bits_per_word = 16;
|
spi->bits_per_word = 16;
|
||||||
spi_setup(spi);
|
spi_setup(spi);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error_free_dev:
|
|
||||||
iio_device_free(idev);
|
|
||||||
error_ret:
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ad5930_remove(struct spi_device *spi)
|
static int ad5930_remove(struct spi_device *spi)
|
||||||
{
|
{
|
||||||
iio_device_unregister(spi_get_drvdata(spi));
|
iio_device_unregister(spi_get_drvdata(spi));
|
||||||
iio_device_free(spi_get_drvdata(spi));
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,9 +81,9 @@ static ssize_t ad9832_write(struct device *dev,
|
||||||
struct ad9832_state *st = iio_priv(indio_dev);
|
struct ad9832_state *st = iio_priv(indio_dev);
|
||||||
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
|
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
|
||||||
int ret;
|
int ret;
|
||||||
long val;
|
unsigned long val;
|
||||||
|
|
||||||
ret = strict_strtoul(buf, 10, &val);
|
ret = kstrtoul(buf, 10, &val);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_ret;
|
goto error_ret;
|
||||||
|
|
||||||
|
@ -214,14 +214,14 @@ static int ad9832_probe(struct spi_device *spi)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
reg = regulator_get(&spi->dev, "vcc");
|
reg = devm_regulator_get(&spi->dev, "vcc");
|
||||||
if (!IS_ERR(reg)) {
|
if (!IS_ERR(reg)) {
|
||||||
ret = regulator_enable(reg);
|
ret = regulator_enable(reg);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_put_reg;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
indio_dev = iio_device_alloc(sizeof(*st));
|
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
|
||||||
if (indio_dev == NULL) {
|
if (indio_dev == NULL) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto error_disable_reg;
|
goto error_disable_reg;
|
||||||
|
@ -279,47 +279,42 @@ static int ad9832_probe(struct spi_device *spi)
|
||||||
ret = spi_sync(st->spi, &st->msg);
|
ret = spi_sync(st->spi, &st->msg);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(&spi->dev, "device init failed\n");
|
dev_err(&spi->dev, "device init failed\n");
|
||||||
goto error_free_device;
|
goto error_disable_reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = ad9832_write_frequency(st, AD9832_FREQ0HM, pdata->freq0);
|
ret = ad9832_write_frequency(st, AD9832_FREQ0HM, pdata->freq0);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_free_device;
|
goto error_disable_reg;
|
||||||
|
|
||||||
ret = ad9832_write_frequency(st, AD9832_FREQ1HM, pdata->freq1);
|
ret = ad9832_write_frequency(st, AD9832_FREQ1HM, pdata->freq1);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_free_device;
|
goto error_disable_reg;
|
||||||
|
|
||||||
ret = ad9832_write_phase(st, AD9832_PHASE0H, pdata->phase0);
|
ret = ad9832_write_phase(st, AD9832_PHASE0H, pdata->phase0);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_free_device;
|
goto error_disable_reg;
|
||||||
|
|
||||||
ret = ad9832_write_phase(st, AD9832_PHASE1H, pdata->phase1);
|
ret = ad9832_write_phase(st, AD9832_PHASE1H, pdata->phase1);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_free_device;
|
goto error_disable_reg;
|
||||||
|
|
||||||
ret = ad9832_write_phase(st, AD9832_PHASE2H, pdata->phase2);
|
ret = ad9832_write_phase(st, AD9832_PHASE2H, pdata->phase2);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_free_device;
|
goto error_disable_reg;
|
||||||
|
|
||||||
ret = ad9832_write_phase(st, AD9832_PHASE3H, pdata->phase3);
|
ret = ad9832_write_phase(st, AD9832_PHASE3H, pdata->phase3);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_free_device;
|
goto error_disable_reg;
|
||||||
|
|
||||||
ret = iio_device_register(indio_dev);
|
ret = iio_device_register(indio_dev);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_free_device;
|
goto error_disable_reg;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error_free_device:
|
|
||||||
iio_device_free(indio_dev);
|
|
||||||
error_disable_reg:
|
error_disable_reg:
|
||||||
if (!IS_ERR(reg))
|
if (!IS_ERR(reg))
|
||||||
regulator_disable(reg);
|
regulator_disable(reg);
|
||||||
error_put_reg:
|
|
||||||
if (!IS_ERR(reg))
|
|
||||||
regulator_put(reg);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -330,11 +325,8 @@ static int ad9832_remove(struct spi_device *spi)
|
||||||
struct ad9832_state *st = iio_priv(indio_dev);
|
struct ad9832_state *st = iio_priv(indio_dev);
|
||||||
|
|
||||||
iio_device_unregister(indio_dev);
|
iio_device_unregister(indio_dev);
|
||||||
if (!IS_ERR(st->reg)) {
|
if (!IS_ERR(st->reg))
|
||||||
regulator_disable(st->reg);
|
regulator_disable(st->reg);
|
||||||
regulator_put(st->reg);
|
|
||||||
}
|
|
||||||
iio_device_free(indio_dev);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -70,9 +70,9 @@ static ssize_t ad9834_write(struct device *dev,
|
||||||
struct ad9834_state *st = iio_priv(indio_dev);
|
struct ad9834_state *st = iio_priv(indio_dev);
|
||||||
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
|
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
|
||||||
int ret;
|
int ret;
|
||||||
long val;
|
unsigned long val;
|
||||||
|
|
||||||
ret = strict_strtoul(buf, 10, &val);
|
ret = kstrtoul(buf, 10, &val);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_ret;
|
goto error_ret;
|
||||||
|
|
||||||
|
@ -327,14 +327,14 @@ static int ad9834_probe(struct spi_device *spi)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
reg = regulator_get(&spi->dev, "vcc");
|
reg = devm_regulator_get(&spi->dev, "vcc");
|
||||||
if (!IS_ERR(reg)) {
|
if (!IS_ERR(reg)) {
|
||||||
ret = regulator_enable(reg);
|
ret = regulator_enable(reg);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_put_reg;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
indio_dev = iio_device_alloc(sizeof(*st));
|
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
|
||||||
if (indio_dev == NULL) {
|
if (indio_dev == NULL) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto error_disable_reg;
|
goto error_disable_reg;
|
||||||
|
@ -388,39 +388,35 @@ static int ad9834_probe(struct spi_device *spi)
|
||||||
ret = spi_sync(st->spi, &st->msg);
|
ret = spi_sync(st->spi, &st->msg);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(&spi->dev, "device init failed\n");
|
dev_err(&spi->dev, "device init failed\n");
|
||||||
goto error_free_device;
|
goto error_disable_reg;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = ad9834_write_frequency(st, AD9834_REG_FREQ0, pdata->freq0);
|
ret = ad9834_write_frequency(st, AD9834_REG_FREQ0, pdata->freq0);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_free_device;
|
goto error_disable_reg;
|
||||||
|
|
||||||
ret = ad9834_write_frequency(st, AD9834_REG_FREQ1, pdata->freq1);
|
ret = ad9834_write_frequency(st, AD9834_REG_FREQ1, pdata->freq1);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_free_device;
|
goto error_disable_reg;
|
||||||
|
|
||||||
ret = ad9834_write_phase(st, AD9834_REG_PHASE0, pdata->phase0);
|
ret = ad9834_write_phase(st, AD9834_REG_PHASE0, pdata->phase0);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_free_device;
|
goto error_disable_reg;
|
||||||
|
|
||||||
ret = ad9834_write_phase(st, AD9834_REG_PHASE1, pdata->phase1);
|
ret = ad9834_write_phase(st, AD9834_REG_PHASE1, pdata->phase1);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_free_device;
|
goto error_disable_reg;
|
||||||
|
|
||||||
ret = iio_device_register(indio_dev);
|
ret = iio_device_register(indio_dev);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_free_device;
|
goto error_disable_reg;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error_free_device:
|
|
||||||
iio_device_free(indio_dev);
|
|
||||||
error_disable_reg:
|
error_disable_reg:
|
||||||
if (!IS_ERR(reg))
|
if (!IS_ERR(reg))
|
||||||
regulator_disable(reg);
|
regulator_disable(reg);
|
||||||
error_put_reg:
|
|
||||||
if (!IS_ERR(reg))
|
|
||||||
regulator_put(reg);
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -430,11 +426,8 @@ static int ad9834_remove(struct spi_device *spi)
|
||||||
struct ad9834_state *st = iio_priv(indio_dev);
|
struct ad9834_state *st = iio_priv(indio_dev);
|
||||||
|
|
||||||
iio_device_unregister(indio_dev);
|
iio_device_unregister(indio_dev);
|
||||||
if (!IS_ERR(st->reg)) {
|
if (!IS_ERR(st->reg))
|
||||||
regulator_disable(st->reg);
|
regulator_disable(st->reg);
|
||||||
regulator_put(st->reg);
|
|
||||||
}
|
|
||||||
iio_device_free(indio_dev);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,11 +80,9 @@ static int ad9850_probe(struct spi_device *spi)
|
||||||
struct iio_dev *idev;
|
struct iio_dev *idev;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
idev = iio_device_alloc(sizeof(*st));
|
idev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
|
||||||
if (idev == NULL) {
|
if (!idev)
|
||||||
ret = -ENOMEM;
|
return -ENOMEM;
|
||||||
goto error_ret;
|
|
||||||
}
|
|
||||||
spi_set_drvdata(spi, idev);
|
spi_set_drvdata(spi, idev);
|
||||||
st = iio_priv(idev);
|
st = iio_priv(idev);
|
||||||
mutex_init(&st->lock);
|
mutex_init(&st->lock);
|
||||||
|
@ -96,24 +94,18 @@ static int ad9850_probe(struct spi_device *spi)
|
||||||
|
|
||||||
ret = iio_device_register(idev);
|
ret = iio_device_register(idev);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_free_dev;
|
return ret;
|
||||||
spi->max_speed_hz = 2000000;
|
spi->max_speed_hz = 2000000;
|
||||||
spi->mode = SPI_MODE_3;
|
spi->mode = SPI_MODE_3;
|
||||||
spi->bits_per_word = 16;
|
spi->bits_per_word = 16;
|
||||||
spi_setup(spi);
|
spi_setup(spi);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error_free_dev:
|
|
||||||
iio_device_free(idev);
|
|
||||||
error_ret:
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ad9850_remove(struct spi_device *spi)
|
static int ad9850_remove(struct spi_device *spi)
|
||||||
{
|
{
|
||||||
iio_device_unregister(spi_get_drvdata(spi));
|
iio_device_unregister(spi_get_drvdata(spi));
|
||||||
iio_device_free(spi_get_drvdata(spi));
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -229,11 +229,9 @@ static int ad9852_probe(struct spi_device *spi)
|
||||||
struct iio_dev *idev;
|
struct iio_dev *idev;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
idev = iio_device_alloc(sizeof(*st));
|
idev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
|
||||||
if (idev == NULL) {
|
if (!idev)
|
||||||
ret = -ENOMEM;
|
return -ENOMEM;
|
||||||
goto error_ret;
|
|
||||||
}
|
|
||||||
st = iio_priv(idev);
|
st = iio_priv(idev);
|
||||||
spi_set_drvdata(spi, idev);
|
spi_set_drvdata(spi, idev);
|
||||||
mutex_init(&st->lock);
|
mutex_init(&st->lock);
|
||||||
|
@ -245,7 +243,7 @@ static int ad9852_probe(struct spi_device *spi)
|
||||||
|
|
||||||
ret = iio_device_register(idev);
|
ret = iio_device_register(idev);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_free_dev;
|
return ret;
|
||||||
spi->max_speed_hz = 2000000;
|
spi->max_speed_hz = 2000000;
|
||||||
spi->mode = SPI_MODE_3;
|
spi->mode = SPI_MODE_3;
|
||||||
spi->bits_per_word = 8;
|
spi->bits_per_word = 8;
|
||||||
|
@ -253,18 +251,11 @@ static int ad9852_probe(struct spi_device *spi)
|
||||||
ad9852_init(st);
|
ad9852_init(st);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error_free_dev:
|
|
||||||
iio_device_free(idev);
|
|
||||||
|
|
||||||
error_ret:
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ad9852_remove(struct spi_device *spi)
|
static int ad9852_remove(struct spi_device *spi)
|
||||||
{
|
{
|
||||||
iio_device_unregister(spi_get_drvdata(spi));
|
iio_device_unregister(spi_get_drvdata(spi));
|
||||||
iio_device_free(spi_get_drvdata(spi));
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -367,11 +367,9 @@ static int ad9910_probe(struct spi_device *spi)
|
||||||
struct iio_dev *idev;
|
struct iio_dev *idev;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
idev = iio_device_alloc(sizeof(*st));
|
idev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
|
||||||
if (idev == NULL) {
|
if (!idev)
|
||||||
ret = -ENOMEM;
|
return -ENOMEM;
|
||||||
goto error_ret;
|
|
||||||
}
|
|
||||||
spi_set_drvdata(spi, idev);
|
spi_set_drvdata(spi, idev);
|
||||||
st = iio_priv(idev);
|
st = iio_priv(idev);
|
||||||
mutex_init(&st->lock);
|
mutex_init(&st->lock);
|
||||||
|
@ -383,24 +381,18 @@ static int ad9910_probe(struct spi_device *spi)
|
||||||
|
|
||||||
ret = iio_device_register(idev);
|
ret = iio_device_register(idev);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_free_dev;
|
return ret;
|
||||||
spi->max_speed_hz = 2000000;
|
spi->max_speed_hz = 2000000;
|
||||||
spi->mode = SPI_MODE_3;
|
spi->mode = SPI_MODE_3;
|
||||||
spi->bits_per_word = 8;
|
spi->bits_per_word = 8;
|
||||||
spi_setup(spi);
|
spi_setup(spi);
|
||||||
ad9910_init(st);
|
ad9910_init(st);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error_free_dev:
|
|
||||||
iio_device_free(idev);
|
|
||||||
error_ret:
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ad9910_remove(struct spi_device *spi)
|
static int ad9910_remove(struct spi_device *spi)
|
||||||
{
|
{
|
||||||
iio_device_unregister(spi_get_drvdata(spi));
|
iio_device_unregister(spi_get_drvdata(spi));
|
||||||
iio_device_free(spi_get_drvdata(spi));
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -176,11 +176,9 @@ static int ad9951_probe(struct spi_device *spi)
|
||||||
struct iio_dev *idev;
|
struct iio_dev *idev;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
idev = iio_device_alloc(sizeof(*st));
|
idev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
|
||||||
if (idev == NULL) {
|
if (!idev)
|
||||||
ret = -ENOMEM;
|
return -ENOMEM;
|
||||||
goto error_ret;
|
|
||||||
}
|
|
||||||
spi_set_drvdata(spi, idev);
|
spi_set_drvdata(spi, idev);
|
||||||
st = iio_priv(idev);
|
st = iio_priv(idev);
|
||||||
mutex_init(&st->lock);
|
mutex_init(&st->lock);
|
||||||
|
@ -193,25 +191,18 @@ static int ad9951_probe(struct spi_device *spi)
|
||||||
|
|
||||||
ret = iio_device_register(idev);
|
ret = iio_device_register(idev);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_free_dev;
|
return ret;
|
||||||
spi->max_speed_hz = 2000000;
|
spi->max_speed_hz = 2000000;
|
||||||
spi->mode = SPI_MODE_3;
|
spi->mode = SPI_MODE_3;
|
||||||
spi->bits_per_word = 8;
|
spi->bits_per_word = 8;
|
||||||
spi_setup(spi);
|
spi_setup(spi);
|
||||||
ad9951_init(st);
|
ad9951_init(st);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error_free_dev:
|
|
||||||
iio_device_free(idev);
|
|
||||||
|
|
||||||
error_ret:
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ad9951_remove(struct spi_device *spi)
|
static int ad9951_remove(struct spi_device *spi)
|
||||||
{
|
{
|
||||||
iio_device_unregister(spi_get_drvdata(spi));
|
iio_device_unregister(spi_get_drvdata(spi));
|
||||||
iio_device_free(spi_get_drvdata(spi));
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,6 +90,11 @@ static const struct iio_chan_spec iio_dummy_channels[] = {
|
||||||
* when converting to standard units (microvolts)
|
* when converting to standard units (microvolts)
|
||||||
*/
|
*/
|
||||||
BIT(IIO_CHAN_INFO_SCALE),
|
BIT(IIO_CHAN_INFO_SCALE),
|
||||||
|
/*
|
||||||
|
* sampling_frequency
|
||||||
|
* The frequency in Hz at which the channels are sampled
|
||||||
|
*/
|
||||||
|
.info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ),
|
||||||
/* The ordering of elements in the buffer via an enum */
|
/* The ordering of elements in the buffer via an enum */
|
||||||
.scan_index = voltage0,
|
.scan_index = voltage0,
|
||||||
.scan_type = { /* Description of storage in buffer */
|
.scan_type = { /* Description of storage in buffer */
|
||||||
|
@ -130,6 +135,10 @@ static const struct iio_chan_spec iio_dummy_channels[] = {
|
||||||
* input channels of type IIO_VOLTAGE.
|
* input channels of type IIO_VOLTAGE.
|
||||||
*/
|
*/
|
||||||
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
|
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
|
||||||
|
/*
|
||||||
|
* sampling_frequency
|
||||||
|
* The frequency in Hz at which the channels are sampled
|
||||||
|
*/
|
||||||
.scan_index = diffvoltage1m2,
|
.scan_index = diffvoltage1m2,
|
||||||
.scan_type = { /* Description of storage in buffer */
|
.scan_type = { /* Description of storage in buffer */
|
||||||
.sign = 's', /* signed */
|
.sign = 's', /* signed */
|
||||||
|
@ -147,6 +156,7 @@ static const struct iio_chan_spec iio_dummy_channels[] = {
|
||||||
.channel2 = 4,
|
.channel2 = 4,
|
||||||
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
|
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
|
||||||
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
|
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
|
||||||
|
.info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ),
|
||||||
.scan_index = diffvoltage3m4,
|
.scan_index = diffvoltage3m4,
|
||||||
.scan_type = {
|
.scan_type = {
|
||||||
.sign = 's',
|
.sign = 's',
|
||||||
|
@ -173,6 +183,7 @@ static const struct iio_chan_spec iio_dummy_channels[] = {
|
||||||
*/
|
*/
|
||||||
BIT(IIO_CHAN_INFO_CALIBSCALE) |
|
BIT(IIO_CHAN_INFO_CALIBSCALE) |
|
||||||
BIT(IIO_CHAN_INFO_CALIBBIAS),
|
BIT(IIO_CHAN_INFO_CALIBBIAS),
|
||||||
|
.info_mask_shared_by_dir = BIT(IIO_CHAN_INFO_SAMP_FREQ),
|
||||||
.scan_index = accelx,
|
.scan_index = accelx,
|
||||||
.scan_type = { /* Description of storage in buffer */
|
.scan_type = { /* Description of storage in buffer */
|
||||||
.sign = 's', /* signed */
|
.sign = 's', /* signed */
|
||||||
|
@ -272,6 +283,11 @@ static int iio_dummy_read_raw(struct iio_dev *indio_dev,
|
||||||
*val2 = st->accel_calibscale->val2;
|
*val2 = st->accel_calibscale->val2;
|
||||||
ret = IIO_VAL_INT_PLUS_MICRO;
|
ret = IIO_VAL_INT_PLUS_MICRO;
|
||||||
break;
|
break;
|
||||||
|
case IIO_CHAN_INFO_SAMP_FREQ:
|
||||||
|
*val = 3;
|
||||||
|
*val2 = 33;
|
||||||
|
ret = IIO_VAL_INT_PLUS_NANO;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,11 +82,8 @@ static irqreturn_t iio_simple_dummy_trigger_h(int irq, void *p)
|
||||||
len += 2;
|
len += 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Store the timestamp at an 8 byte aligned offset */
|
|
||||||
if (indio_dev->scan_timestamp)
|
iio_push_to_buffers_with_timestamp(indio_dev, data, iio_get_time_ns());
|
||||||
*(s64 *)((u8 *)data + ALIGN(len, sizeof(s64)))
|
|
||||||
= iio_get_time_ns();
|
|
||||||
iio_push_to_buffers(indio_dev, (u8 *)data);
|
|
||||||
|
|
||||||
kfree(data);
|
kfree(data);
|
||||||
|
|
||||||
|
|
|
@ -323,10 +323,10 @@ static ssize_t ad5933_store_frequency(struct device *dev,
|
||||||
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
||||||
struct ad5933_state *st = iio_priv(indio_dev);
|
struct ad5933_state *st = iio_priv(indio_dev);
|
||||||
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
|
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
|
||||||
long val;
|
unsigned long val;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = strict_strtoul(buf, 10, &val);
|
ret = kstrtoul(buf, 10, &val);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@ -400,12 +400,12 @@ static ssize_t ad5933_store(struct device *dev,
|
||||||
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
||||||
struct ad5933_state *st = iio_priv(indio_dev);
|
struct ad5933_state *st = iio_priv(indio_dev);
|
||||||
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
|
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
|
||||||
long val;
|
u16 val;
|
||||||
int i, ret = 0;
|
int i, ret = 0;
|
||||||
unsigned short dat;
|
unsigned short dat;
|
||||||
|
|
||||||
if (this_attr->address != AD5933_IN_PGA_GAIN) {
|
if (this_attr->address != AD5933_IN_PGA_GAIN) {
|
||||||
ret = strict_strtol(buf, 10, &val);
|
ret = kstrtou16(buf, 10, &val);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -434,7 +434,7 @@ static ssize_t ad5933_store(struct device *dev,
|
||||||
ret = ad5933_cmd(st, 0);
|
ret = ad5933_cmd(st, 0);
|
||||||
break;
|
break;
|
||||||
case AD5933_OUT_SETTLING_CYCLES:
|
case AD5933_OUT_SETTLING_CYCLES:
|
||||||
val = clamp(val, 0L, 0x7FFL);
|
val = clamp(val, (u16)0, (u16)0x7FF);
|
||||||
st->settling_cycles = val;
|
st->settling_cycles = val;
|
||||||
|
|
||||||
/* 2x, 4x handling, see datasheet */
|
/* 2x, 4x handling, see datasheet */
|
||||||
|
@ -448,7 +448,7 @@ static ssize_t ad5933_store(struct device *dev,
|
||||||
AD5933_REG_SETTLING_CYCLES, 2, (u8 *)&dat);
|
AD5933_REG_SETTLING_CYCLES, 2, (u8 *)&dat);
|
||||||
break;
|
break;
|
||||||
case AD5933_FREQ_POINTS:
|
case AD5933_FREQ_POINTS:
|
||||||
val = clamp(val, 0L, 511L);
|
val = clamp(val, (u16)0, (u16)511);
|
||||||
st->freq_points = val;
|
st->freq_points = val;
|
||||||
|
|
||||||
dat = cpu_to_be16(val);
|
dat = cpu_to_be16(val);
|
||||||
|
@ -676,7 +676,7 @@ static void ad5933_work(struct work_struct *work)
|
||||||
} else {
|
} else {
|
||||||
buf[0] = be16_to_cpu(buf[0]);
|
buf[0] = be16_to_cpu(buf[0]);
|
||||||
}
|
}
|
||||||
iio_push_to_buffers(indio_dev, (u8 *)buf);
|
iio_push_to_buffers(indio_dev, buf);
|
||||||
} else {
|
} else {
|
||||||
/* no data available - try again later */
|
/* no data available - try again later */
|
||||||
schedule_delayed_work(&st->work, st->poll_time_jiffies);
|
schedule_delayed_work(&st->work, st->poll_time_jiffies);
|
||||||
|
@ -703,7 +703,9 @@ static int ad5933_probe(struct i2c_client *client,
|
||||||
int ret, voltage_uv = 0;
|
int ret, voltage_uv = 0;
|
||||||
struct ad5933_platform_data *pdata = client->dev.platform_data;
|
struct ad5933_platform_data *pdata = client->dev.platform_data;
|
||||||
struct ad5933_state *st;
|
struct ad5933_state *st;
|
||||||
struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
|
struct iio_dev *indio_dev;
|
||||||
|
|
||||||
|
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st));
|
||||||
if (indio_dev == NULL)
|
if (indio_dev == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
@ -716,11 +718,11 @@ static int ad5933_probe(struct i2c_client *client,
|
||||||
else
|
else
|
||||||
st->pdata = pdata;
|
st->pdata = pdata;
|
||||||
|
|
||||||
st->reg = regulator_get(&client->dev, "vcc");
|
st->reg = devm_regulator_get(&client->dev, "vcc");
|
||||||
if (!IS_ERR(st->reg)) {
|
if (!IS_ERR(st->reg)) {
|
||||||
ret = regulator_enable(st->reg);
|
ret = regulator_enable(st->reg);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_put_reg;
|
return ret;
|
||||||
voltage_uv = regulator_get_voltage(st->reg);
|
voltage_uv = regulator_get_voltage(st->reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -778,11 +780,6 @@ error_unreg_ring:
|
||||||
error_disable_reg:
|
error_disable_reg:
|
||||||
if (!IS_ERR(st->reg))
|
if (!IS_ERR(st->reg))
|
||||||
regulator_disable(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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -795,11 +792,8 @@ static int ad5933_remove(struct i2c_client *client)
|
||||||
iio_device_unregister(indio_dev);
|
iio_device_unregister(indio_dev);
|
||||||
iio_buffer_unregister(indio_dev);
|
iio_buffer_unregister(indio_dev);
|
||||||
iio_kfifo_free(indio_dev->buffer);
|
iio_kfifo_free(indio_dev->buffer);
|
||||||
if (!IS_ERR(st->reg)) {
|
if (!IS_ERR(st->reg))
|
||||||
regulator_disable(st->reg);
|
regulator_disable(st->reg);
|
||||||
regulator_put(st->reg);
|
|
||||||
}
|
|
||||||
iio_device_free(indio_dev);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -240,7 +240,7 @@ static ssize_t store_range(struct device *dev,
|
||||||
unsigned long lval;
|
unsigned long lval;
|
||||||
unsigned int new_range;
|
unsigned int new_range;
|
||||||
|
|
||||||
if (strict_strtoul(buf, 10, &lval))
|
if (kstrtoul(buf, 10, &lval))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (!(lval == 1000UL || lval == 4000UL ||
|
if (!(lval == 1000UL || lval == 4000UL ||
|
||||||
|
@ -279,18 +279,18 @@ static ssize_t store_resolution(struct device *dev,
|
||||||
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
||||||
struct isl29018_chip *chip = iio_priv(indio_dev);
|
struct isl29018_chip *chip = iio_priv(indio_dev);
|
||||||
int status;
|
int status;
|
||||||
unsigned long lval;
|
unsigned int val;
|
||||||
unsigned int new_adc_bit;
|
unsigned int new_adc_bit;
|
||||||
|
|
||||||
if (strict_strtoul(buf, 10, &lval))
|
if (kstrtouint(buf, 10, &val))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (!(lval == 4 || lval == 8 || lval == 12 || lval == 16)) {
|
if (!(val == 4 || val == 8 || val == 12 || val == 16)) {
|
||||||
dev_err(dev, "The resolution is not supported\n");
|
dev_err(dev, "The resolution is not supported\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
mutex_lock(&chip->lock);
|
mutex_lock(&chip->lock);
|
||||||
status = isl29018_set_resolution(chip, lval, &new_adc_bit);
|
status = isl29018_set_resolution(chip, val, &new_adc_bit);
|
||||||
if (status < 0) {
|
if (status < 0) {
|
||||||
mutex_unlock(&chip->lock);
|
mutex_unlock(&chip->lock);
|
||||||
dev_err(dev, "Error in setting resolution\n");
|
dev_err(dev, "Error in setting resolution\n");
|
||||||
|
@ -319,11 +319,11 @@ static ssize_t store_prox_infrared_suppression(struct device *dev,
|
||||||
{
|
{
|
||||||
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
||||||
struct isl29018_chip *chip = iio_priv(indio_dev);
|
struct isl29018_chip *chip = iio_priv(indio_dev);
|
||||||
unsigned long lval;
|
int val;
|
||||||
|
|
||||||
if (strict_strtoul(buf, 10, &lval))
|
if (kstrtoint(buf, 10, &val))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (!(lval == 0UL || lval == 1UL)) {
|
if (!(val == 0 || val == 1)) {
|
||||||
dev_err(dev, "The mode is not supported\n");
|
dev_err(dev, "The mode is not supported\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
@ -331,7 +331,7 @@ static ssize_t store_prox_infrared_suppression(struct device *dev,
|
||||||
/* get the "proximity scheme" i.e. if the chip does on chip
|
/* get the "proximity scheme" i.e. if the chip does on chip
|
||||||
infrared suppression (1 means perform on chip suppression) */
|
infrared suppression (1 means perform on chip suppression) */
|
||||||
mutex_lock(&chip->lock);
|
mutex_lock(&chip->lock);
|
||||||
chip->prox_scheme = (int)lval;
|
chip->prox_scheme = val;
|
||||||
mutex_unlock(&chip->lock);
|
mutex_unlock(&chip->lock);
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
|
|
|
@ -493,9 +493,9 @@ static ssize_t taos_power_state_store(struct device *dev,
|
||||||
struct device_attribute *attr, const char *buf, size_t len)
|
struct device_attribute *attr, const char *buf, size_t len)
|
||||||
{
|
{
|
||||||
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
||||||
unsigned long value;
|
int value;
|
||||||
|
|
||||||
if (strict_strtoul(buf, 0, &value))
|
if (kstrtoint(buf, 0, &value))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (value == 0)
|
if (value == 0)
|
||||||
|
@ -536,9 +536,9 @@ static ssize_t taos_gain_store(struct device *dev,
|
||||||
{
|
{
|
||||||
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
||||||
struct tsl2583_chip *chip = iio_priv(indio_dev);
|
struct tsl2583_chip *chip = iio_priv(indio_dev);
|
||||||
unsigned long value;
|
int value;
|
||||||
|
|
||||||
if (strict_strtoul(buf, 0, &value))
|
if (kstrtoint(buf, 0, &value))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
switch (value) {
|
switch (value) {
|
||||||
|
@ -582,9 +582,9 @@ static ssize_t taos_als_time_store(struct device *dev,
|
||||||
{
|
{
|
||||||
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
||||||
struct tsl2583_chip *chip = iio_priv(indio_dev);
|
struct tsl2583_chip *chip = iio_priv(indio_dev);
|
||||||
unsigned long value;
|
int value;
|
||||||
|
|
||||||
if (strict_strtoul(buf, 0, &value))
|
if (kstrtoint(buf, 0, &value))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if ((value < 50) || (value > 650))
|
if ((value < 50) || (value > 650))
|
||||||
|
@ -619,9 +619,9 @@ static ssize_t taos_als_trim_store(struct device *dev,
|
||||||
{
|
{
|
||||||
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
||||||
struct tsl2583_chip *chip = iio_priv(indio_dev);
|
struct tsl2583_chip *chip = iio_priv(indio_dev);
|
||||||
unsigned long value;
|
int value;
|
||||||
|
|
||||||
if (strict_strtoul(buf, 0, &value))
|
if (kstrtoint(buf, 0, &value))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (value)
|
if (value)
|
||||||
|
@ -644,9 +644,9 @@ static ssize_t taos_als_cal_target_store(struct device *dev,
|
||||||
{
|
{
|
||||||
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
||||||
struct tsl2583_chip *chip = iio_priv(indio_dev);
|
struct tsl2583_chip *chip = iio_priv(indio_dev);
|
||||||
unsigned long value;
|
int value;
|
||||||
|
|
||||||
if (strict_strtoul(buf, 0, &value))
|
if (kstrtoint(buf, 0, &value))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (value)
|
if (value)
|
||||||
|
@ -671,9 +671,9 @@ static ssize_t taos_do_calibrate(struct device *dev,
|
||||||
struct device_attribute *attr, const char *buf, size_t len)
|
struct device_attribute *attr, const char *buf, size_t len)
|
||||||
{
|
{
|
||||||
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
||||||
unsigned long value;
|
int value;
|
||||||
|
|
||||||
if (strict_strtoul(buf, 0, &value))
|
if (kstrtoint(buf, 0, &value))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (value == 1)
|
if (value == 1)
|
||||||
|
@ -815,12 +815,9 @@ static int taos_probe(struct i2c_client *clientp,
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
indio_dev = iio_device_alloc(sizeof(*chip));
|
indio_dev = devm_iio_device_alloc(&clientp->dev, sizeof(*chip));
|
||||||
if (indio_dev == NULL) {
|
if (!indio_dev)
|
||||||
ret = -ENOMEM;
|
return -ENOMEM;
|
||||||
dev_err(&clientp->dev, "iio allocation failed\n");
|
|
||||||
goto fail1;
|
|
||||||
}
|
|
||||||
chip = iio_priv(indio_dev);
|
chip = iio_priv(indio_dev);
|
||||||
chip->client = clientp;
|
chip->client = clientp;
|
||||||
i2c_set_clientdata(clientp, indio_dev);
|
i2c_set_clientdata(clientp, indio_dev);
|
||||||
|
@ -835,14 +832,14 @@ static int taos_probe(struct i2c_client *clientp,
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(&clientp->dev, "i2c_smbus_write_bytes() to cmd "
|
dev_err(&clientp->dev, "i2c_smbus_write_bytes() to cmd "
|
||||||
"reg failed in taos_probe(), err = %d\n", ret);
|
"reg failed in taos_probe(), err = %d\n", ret);
|
||||||
goto fail2;
|
return ret;
|
||||||
}
|
}
|
||||||
ret = i2c_smbus_read_byte(clientp);
|
ret = i2c_smbus_read_byte(clientp);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(&clientp->dev, "i2c_smbus_read_byte from "
|
dev_err(&clientp->dev, "i2c_smbus_read_byte from "
|
||||||
"reg failed in taos_probe(), err = %d\n", ret);
|
"reg failed in taos_probe(), err = %d\n", ret);
|
||||||
|
|
||||||
goto fail2;
|
return ret;
|
||||||
}
|
}
|
||||||
buf[i] = ret;
|
buf[i] = ret;
|
||||||
}
|
}
|
||||||
|
@ -850,14 +847,14 @@ static int taos_probe(struct i2c_client *clientp,
|
||||||
if (!taos_tsl258x_device(buf)) {
|
if (!taos_tsl258x_device(buf)) {
|
||||||
dev_info(&clientp->dev, "i2c device found but does not match "
|
dev_info(&clientp->dev, "i2c device found but does not match "
|
||||||
"expected id in taos_probe()\n");
|
"expected id in taos_probe()\n");
|
||||||
goto fail2;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = i2c_smbus_write_byte(clientp, (TSL258X_CMD_REG | TSL258X_CNTRL));
|
ret = i2c_smbus_write_byte(clientp, (TSL258X_CMD_REG | TSL258X_CNTRL));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(&clientp->dev, "i2c_smbus_write_byte() to cmd reg "
|
dev_err(&clientp->dev, "i2c_smbus_write_byte() to cmd reg "
|
||||||
"failed in taos_probe(), err = %d\n", ret);
|
"failed in taos_probe(), err = %d\n", ret);
|
||||||
goto fail2;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
indio_dev->info = &tsl2583_info;
|
indio_dev->info = &tsl2583_info;
|
||||||
|
@ -867,7 +864,7 @@ static int taos_probe(struct i2c_client *clientp,
|
||||||
ret = iio_device_register(indio_dev);
|
ret = iio_device_register(indio_dev);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(&clientp->dev, "iio registration failed\n");
|
dev_err(&clientp->dev, "iio registration failed\n");
|
||||||
goto fail2;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Load up the V2 defaults (these are hard coded defaults for now) */
|
/* Load up the V2 defaults (these are hard coded defaults for now) */
|
||||||
|
@ -878,10 +875,6 @@ static int taos_probe(struct i2c_client *clientp,
|
||||||
|
|
||||||
dev_info(&clientp->dev, "Light sensor found.\n");
|
dev_info(&clientp->dev, "Light sensor found.\n");
|
||||||
return 0;
|
return 0;
|
||||||
fail1:
|
|
||||||
iio_device_free(indio_dev);
|
|
||||||
fail2:
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PM_SLEEP
|
#ifdef CONFIG_PM_SLEEP
|
||||||
|
@ -926,7 +919,6 @@ static SIMPLE_DEV_PM_OPS(taos_pm_ops, taos_suspend, taos_resume);
|
||||||
static int taos_remove(struct i2c_client *client)
|
static int taos_remove(struct i2c_client *client)
|
||||||
{
|
{
|
||||||
iio_device_unregister(i2c_get_clientdata(client));
|
iio_device_unregister(i2c_get_clientdata(client));
|
||||||
iio_device_free(i2c_get_clientdata(client));
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -550,7 +550,7 @@ prox_poll_err:
|
||||||
static void tsl2x7x_defaults(struct tsl2X7X_chip *chip)
|
static void tsl2x7x_defaults(struct tsl2X7X_chip *chip)
|
||||||
{
|
{
|
||||||
/* If Operational settings defined elsewhere.. */
|
/* If Operational settings defined elsewhere.. */
|
||||||
if (chip->pdata && chip->pdata->platform_default_settings != 0)
|
if (chip->pdata && chip->pdata->platform_default_settings)
|
||||||
memcpy(&(chip->tsl2x7x_settings),
|
memcpy(&(chip->tsl2x7x_settings),
|
||||||
chip->pdata->platform_default_settings,
|
chip->pdata->platform_default_settings,
|
||||||
sizeof(tsl2x7x_default_settings));
|
sizeof(tsl2x7x_default_settings));
|
||||||
|
@ -951,7 +951,6 @@ static ssize_t tsl2x7x_gain_available_show(struct device *dev,
|
||||||
case tsl2771:
|
case tsl2771:
|
||||||
case tmd2771:
|
case tmd2771:
|
||||||
return snprintf(buf, PAGE_SIZE, "%s\n", "1 8 16 128");
|
return snprintf(buf, PAGE_SIZE, "%s\n", "1 8 16 128");
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return snprintf(buf, PAGE_SIZE, "%s\n", "1 8 16 120");
|
return snprintf(buf, PAGE_SIZE, "%s\n", "1 8 16 120");
|
||||||
|
@ -1346,7 +1345,6 @@ static int tsl2x7x_read_raw(struct iio_dev *indio_dev,
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IIO_CHAN_INFO_RAW:
|
case IIO_CHAN_INFO_RAW:
|
||||||
|
@ -1366,7 +1364,6 @@ static int tsl2x7x_read_raw(struct iio_dev *indio_dev,
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IIO_CHAN_INFO_CALIBSCALE:
|
case IIO_CHAN_INFO_CALIBSCALE:
|
||||||
|
@ -1419,7 +1416,6 @@ static int tsl2x7x_write_raw(struct iio_dev *indio_dev,
|
||||||
case tsl2772:
|
case tsl2772:
|
||||||
case tmd2772:
|
case tmd2772:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
chip->tsl2x7x_settings.als_gain = 3;
|
chip->tsl2x7x_settings.als_gain = 3;
|
||||||
break;
|
break;
|
||||||
|
@ -1431,7 +1427,6 @@ static int tsl2x7x_write_raw(struct iio_dev *indio_dev,
|
||||||
case tsl2771:
|
case tsl2771:
|
||||||
case tmd2771:
|
case tmd2771:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
chip->tsl2x7x_settings.als_gain = 3;
|
chip->tsl2x7x_settings.als_gain = 3;
|
||||||
break;
|
break;
|
||||||
|
@ -1508,18 +1503,15 @@ static int tsl2x7x_device_id(unsigned char *id, int target)
|
||||||
case tsl2671:
|
case tsl2671:
|
||||||
case tsl2771:
|
case tsl2771:
|
||||||
return ((*id & 0xf0) == TRITON_ID);
|
return ((*id & 0xf0) == TRITON_ID);
|
||||||
break;
|
|
||||||
case tmd2671:
|
case tmd2671:
|
||||||
case tmd2771:
|
case tmd2771:
|
||||||
return ((*id & 0xf0) == HALIBUT_ID);
|
return ((*id & 0xf0) == HALIBUT_ID);
|
||||||
break;
|
|
||||||
case tsl2572:
|
case tsl2572:
|
||||||
case tsl2672:
|
case tsl2672:
|
||||||
case tmd2672:
|
case tmd2672:
|
||||||
case tsl2772:
|
case tsl2772:
|
||||||
case tmd2772:
|
case tmd2772:
|
||||||
return ((*id & 0xf0) == SWORDFISH_ID);
|
return ((*id & 0xf0) == SWORDFISH_ID);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -1851,7 +1843,7 @@ static int tsl2x7x_probe(struct i2c_client *clientp,
|
||||||
struct iio_dev *indio_dev;
|
struct iio_dev *indio_dev;
|
||||||
struct tsl2X7X_chip *chip;
|
struct tsl2X7X_chip *chip;
|
||||||
|
|
||||||
indio_dev = iio_device_alloc(sizeof(*chip));
|
indio_dev = devm_iio_device_alloc(&clientp->dev, sizeof(*chip));
|
||||||
if (!indio_dev)
|
if (!indio_dev)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
@ -1862,22 +1854,21 @@ static int tsl2x7x_probe(struct i2c_client *clientp,
|
||||||
ret = tsl2x7x_i2c_read(chip->client,
|
ret = tsl2x7x_i2c_read(chip->client,
|
||||||
TSL2X7X_CHIPID, &device_id);
|
TSL2X7X_CHIPID, &device_id);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto fail1;
|
return ret;
|
||||||
|
|
||||||
if ((!tsl2x7x_device_id(&device_id, id->driver_data)) ||
|
if ((!tsl2x7x_device_id(&device_id, id->driver_data)) ||
|
||||||
(tsl2x7x_device_id(&device_id, id->driver_data) == -EINVAL)) {
|
(tsl2x7x_device_id(&device_id, id->driver_data) == -EINVAL)) {
|
||||||
dev_info(&chip->client->dev,
|
dev_info(&chip->client->dev,
|
||||||
"%s: i2c device found does not match expected id\n",
|
"%s: i2c device found does not match expected id\n",
|
||||||
__func__);
|
__func__);
|
||||||
ret = -EINVAL;
|
return -EINVAL;
|
||||||
goto fail1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = i2c_smbus_write_byte(clientp, (TSL2X7X_CMD_REG | TSL2X7X_CNTRL));
|
ret = i2c_smbus_write_byte(clientp, (TSL2X7X_CMD_REG | TSL2X7X_CNTRL));
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(&clientp->dev, "%s: write to cmd reg failed. err = %d\n",
|
dev_err(&clientp->dev, "%s: write to cmd reg failed. err = %d\n",
|
||||||
__func__, ret);
|
__func__, ret);
|
||||||
goto fail1;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ALS and PROX functions can be invoked via user space poll
|
/* ALS and PROX functions can be invoked via user space poll
|
||||||
|
@ -1899,16 +1890,17 @@ static int tsl2x7x_probe(struct i2c_client *clientp,
|
||||||
indio_dev->num_channels = chip->chip_info->chan_table_elements;
|
indio_dev->num_channels = chip->chip_info->chan_table_elements;
|
||||||
|
|
||||||
if (clientp->irq) {
|
if (clientp->irq) {
|
||||||
ret = request_threaded_irq(clientp->irq,
|
ret = devm_request_threaded_irq(&clientp->dev, clientp->irq,
|
||||||
NULL,
|
NULL,
|
||||||
&tsl2x7x_event_handler,
|
&tsl2x7x_event_handler,
|
||||||
IRQF_TRIGGER_RISING | IRQF_ONESHOT,
|
IRQF_TRIGGER_RISING |
|
||||||
"TSL2X7X_event",
|
IRQF_ONESHOT,
|
||||||
indio_dev);
|
"TSL2X7X_event",
|
||||||
|
indio_dev);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(&clientp->dev,
|
dev_err(&clientp->dev,
|
||||||
"%s: irq request failed", __func__);
|
"%s: irq request failed", __func__);
|
||||||
goto fail1;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1921,20 +1913,12 @@ static int tsl2x7x_probe(struct i2c_client *clientp,
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(&clientp->dev,
|
dev_err(&clientp->dev,
|
||||||
"%s: iio registration failed\n", __func__);
|
"%s: iio registration failed\n", __func__);
|
||||||
goto fail2;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
dev_info(&clientp->dev, "%s Light sensor found.\n", id->name);
|
dev_info(&clientp->dev, "%s Light sensor found.\n", id->name);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail2:
|
|
||||||
if (clientp->irq)
|
|
||||||
free_irq(clientp->irq, indio_dev);
|
|
||||||
fail1:
|
|
||||||
iio_device_free(indio_dev);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int tsl2x7x_suspend(struct device *dev)
|
static int tsl2x7x_suspend(struct device *dev)
|
||||||
|
@ -1980,10 +1964,6 @@ static int tsl2x7x_remove(struct i2c_client *client)
|
||||||
tsl2x7x_chip_off(indio_dev);
|
tsl2x7x_chip_off(indio_dev);
|
||||||
|
|
||||||
iio_device_unregister(indio_dev);
|
iio_device_unregister(indio_dev);
|
||||||
if (client->irq)
|
|
||||||
free_irq(client->irq, indio_dev);
|
|
||||||
|
|
||||||
iio_device_free(indio_dev);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -643,11 +643,9 @@ static int hmc5843_probe(struct i2c_client *client,
|
||||||
struct iio_dev *indio_dev;
|
struct iio_dev *indio_dev;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
indio_dev = iio_device_alloc(sizeof(*data));
|
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
|
||||||
if (indio_dev == NULL) {
|
if (indio_dev == NULL)
|
||||||
err = -ENOMEM;
|
return -ENOMEM;
|
||||||
goto exit;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* default settings at probe */
|
/* default settings at probe */
|
||||||
data = iio_priv(indio_dev);
|
data = iio_priv(indio_dev);
|
||||||
|
@ -665,24 +663,16 @@ static int hmc5843_probe(struct i2c_client *client,
|
||||||
|
|
||||||
err = iio_device_register(indio_dev);
|
err = iio_device_register(indio_dev);
|
||||||
if (err)
|
if (err)
|
||||||
goto exit_free2;
|
return err;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
exit_free2:
|
|
||||||
iio_device_free(indio_dev);
|
|
||||||
exit:
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hmc5843_remove(struct i2c_client *client)
|
static int hmc5843_remove(struct i2c_client *client)
|
||||||
{
|
{
|
||||||
struct iio_dev *indio_dev = i2c_get_clientdata(client);
|
iio_device_unregister(i2c_get_clientdata(client));
|
||||||
|
|
||||||
iio_device_unregister(indio_dev);
|
|
||||||
/* sleep mode to save power */
|
/* sleep mode to save power */
|
||||||
hmc5843_configure(client, HMC5843_MODE_SLEEP);
|
hmc5843_configure(client, HMC5843_MODE_SLEEP);
|
||||||
iio_device_free(indio_dev);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -691,14 +681,14 @@ static int hmc5843_remove(struct i2c_client *client)
|
||||||
static int hmc5843_suspend(struct device *dev)
|
static int hmc5843_suspend(struct device *dev)
|
||||||
{
|
{
|
||||||
hmc5843_configure(to_i2c_client(dev), HMC5843_MODE_SLEEP);
|
hmc5843_configure(to_i2c_client(dev), HMC5843_MODE_SLEEP);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int hmc5843_resume(struct device *dev)
|
static int hmc5843_resume(struct device *dev)
|
||||||
{
|
{
|
||||||
struct i2c_client *client = to_i2c_client(dev);
|
struct i2c_client *client = to_i2c_client(dev);
|
||||||
struct iio_dev *indio_dev = i2c_get_clientdata(client);
|
struct hmc5843_data *data = iio_priv(i2c_get_clientdata(client));
|
||||||
struct hmc5843_data *data = iio_priv(indio_dev);
|
|
||||||
|
|
||||||
hmc5843_configure(client, data->operating_mode);
|
hmc5843_configure(client, data->operating_mode);
|
||||||
|
|
||||||
|
@ -730,6 +720,6 @@ static struct i2c_driver hmc5843_driver = {
|
||||||
};
|
};
|
||||||
module_i2c_driver(hmc5843_driver);
|
module_i2c_driver(hmc5843_driver);
|
||||||
|
|
||||||
MODULE_AUTHOR("Shubhrajyoti Datta <shubhrajyoti@ti.com");
|
MODULE_AUTHOR("Shubhrajyoti Datta <shubhrajyoti@ti.com>");
|
||||||
MODULE_DESCRIPTION("HMC5843/5883/5883L driver");
|
MODULE_DESCRIPTION("HMC5843/5883/5883L driver");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
|
@ -186,9 +186,9 @@ static ssize_t ade7753_write_8bit(struct device *dev,
|
||||||
{
|
{
|
||||||
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
|
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
|
||||||
int ret;
|
int ret;
|
||||||
long val;
|
u8 val;
|
||||||
|
|
||||||
ret = strict_strtol(buf, 10, &val);
|
ret = kstrtou8(buf, 10, &val);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_ret;
|
goto error_ret;
|
||||||
ret = ade7753_spi_write_reg_8(dev, this_attr->address, val);
|
ret = ade7753_spi_write_reg_8(dev, this_attr->address, val);
|
||||||
|
@ -204,9 +204,9 @@ static ssize_t ade7753_write_16bit(struct device *dev,
|
||||||
{
|
{
|
||||||
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
|
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
|
||||||
int ret;
|
int ret;
|
||||||
long val;
|
u16 val;
|
||||||
|
|
||||||
ret = strict_strtol(buf, 10, &val);
|
ret = kstrtou16(buf, 10, &val);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_ret;
|
goto error_ret;
|
||||||
ret = ade7753_spi_write_reg_16(dev, this_attr->address, val);
|
ret = ade7753_spi_write_reg_16(dev, this_attr->address, val);
|
||||||
|
@ -399,11 +399,11 @@ static ssize_t ade7753_write_frequency(struct device *dev,
|
||||||
{
|
{
|
||||||
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
||||||
struct ade7753_state *st = iio_priv(indio_dev);
|
struct ade7753_state *st = iio_priv(indio_dev);
|
||||||
unsigned long val;
|
u16 val;
|
||||||
int ret;
|
int ret;
|
||||||
u16 reg, t;
|
u16 reg, t;
|
||||||
|
|
||||||
ret = strict_strtol(buf, 10, &val);
|
ret = kstrtou16(buf, 10, &val);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
if (val == 0)
|
if (val == 0)
|
||||||
|
@ -497,11 +497,9 @@ static int ade7753_probe(struct spi_device *spi)
|
||||||
struct iio_dev *indio_dev;
|
struct iio_dev *indio_dev;
|
||||||
|
|
||||||
/* setup the industrialio driver allocated elements */
|
/* setup the industrialio driver allocated elements */
|
||||||
indio_dev = iio_device_alloc(sizeof(*st));
|
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
|
||||||
if (indio_dev == NULL) {
|
if (!indio_dev)
|
||||||
ret = -ENOMEM;
|
return -ENOMEM;
|
||||||
goto error_ret;
|
|
||||||
}
|
|
||||||
/* this is only used for removal purposes */
|
/* this is only used for removal purposes */
|
||||||
spi_set_drvdata(spi, indio_dev);
|
spi_set_drvdata(spi, indio_dev);
|
||||||
|
|
||||||
|
@ -517,19 +515,13 @@ static int ade7753_probe(struct spi_device *spi)
|
||||||
/* Get the device into a sane initial state */
|
/* Get the device into a sane initial state */
|
||||||
ret = ade7753_initial_setup(indio_dev);
|
ret = ade7753_initial_setup(indio_dev);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_free_dev;
|
return ret;
|
||||||
|
|
||||||
ret = iio_device_register(indio_dev);
|
ret = iio_device_register(indio_dev);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_free_dev;
|
return ret;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error_free_dev:
|
|
||||||
iio_device_free(indio_dev);
|
|
||||||
|
|
||||||
error_ret:
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fixme, confirm ordering in this function */
|
/* fixme, confirm ordering in this function */
|
||||||
|
@ -539,7 +531,6 @@ static int ade7753_remove(struct spi_device *spi)
|
||||||
|
|
||||||
iio_device_unregister(indio_dev);
|
iio_device_unregister(indio_dev);
|
||||||
ade7753_stop_device(&indio_dev->dev);
|
ade7753_stop_device(&indio_dev->dev);
|
||||||
iio_device_free(indio_dev);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -186,9 +186,9 @@ static ssize_t ade7754_write_8bit(struct device *dev,
|
||||||
{
|
{
|
||||||
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
|
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
|
||||||
int ret;
|
int ret;
|
||||||
long val;
|
u8 val;
|
||||||
|
|
||||||
ret = strict_strtol(buf, 10, &val);
|
ret = kstrtou8(buf, 10, &val);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_ret;
|
goto error_ret;
|
||||||
ret = ade7754_spi_write_reg_8(dev, this_attr->address, val);
|
ret = ade7754_spi_write_reg_8(dev, this_attr->address, val);
|
||||||
|
@ -204,9 +204,9 @@ static ssize_t ade7754_write_16bit(struct device *dev,
|
||||||
{
|
{
|
||||||
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
|
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
|
||||||
int ret;
|
int ret;
|
||||||
long val;
|
u16 val;
|
||||||
|
|
||||||
ret = strict_strtol(buf, 10, &val);
|
ret = kstrtou16(buf, 10, &val);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_ret;
|
goto error_ret;
|
||||||
ret = ade7754_spi_write_reg_16(dev, this_attr->address, val);
|
ret = ade7754_spi_write_reg_16(dev, this_attr->address, val);
|
||||||
|
@ -419,11 +419,11 @@ static ssize_t ade7754_write_frequency(struct device *dev,
|
||||||
{
|
{
|
||||||
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
||||||
struct ade7754_state *st = iio_priv(indio_dev);
|
struct ade7754_state *st = iio_priv(indio_dev);
|
||||||
unsigned long val;
|
u16 val;
|
||||||
int ret;
|
int ret;
|
||||||
u8 reg, t;
|
u8 reg, t;
|
||||||
|
|
||||||
ret = strict_strtol(buf, 10, &val);
|
ret = kstrtou16(buf, 10, &val);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
if (val == 0)
|
if (val == 0)
|
||||||
|
@ -520,11 +520,9 @@ static int ade7754_probe(struct spi_device *spi)
|
||||||
struct iio_dev *indio_dev;
|
struct iio_dev *indio_dev;
|
||||||
|
|
||||||
/* setup the industrialio driver allocated elements */
|
/* setup the industrialio driver allocated elements */
|
||||||
indio_dev = iio_device_alloc(sizeof(*st));
|
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
|
||||||
if (indio_dev == NULL) {
|
if (!indio_dev)
|
||||||
ret = -ENOMEM;
|
return -ENOMEM;
|
||||||
goto error_ret;
|
|
||||||
}
|
|
||||||
/* this is only used for removal purposes */
|
/* this is only used for removal purposes */
|
||||||
spi_set_drvdata(spi, indio_dev);
|
spi_set_drvdata(spi, indio_dev);
|
||||||
|
|
||||||
|
@ -540,18 +538,12 @@ static int ade7754_probe(struct spi_device *spi)
|
||||||
/* Get the device into a sane initial state */
|
/* Get the device into a sane initial state */
|
||||||
ret = ade7754_initial_setup(indio_dev);
|
ret = ade7754_initial_setup(indio_dev);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_free_dev;
|
return ret;
|
||||||
ret = iio_device_register(indio_dev);
|
ret = iio_device_register(indio_dev);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_free_dev;
|
return ret;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error_free_dev:
|
|
||||||
iio_device_free(indio_dev);
|
|
||||||
|
|
||||||
error_ret:
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fixme, confirm ordering in this function */
|
/* fixme, confirm ordering in this function */
|
||||||
|
@ -561,7 +553,6 @@ static int ade7754_remove(struct spi_device *spi)
|
||||||
|
|
||||||
iio_device_unregister(indio_dev);
|
iio_device_unregister(indio_dev);
|
||||||
ade7754_stop_device(&indio_dev->dev);
|
ade7754_stop_device(&indio_dev->dev);
|
||||||
iio_device_free(indio_dev);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -269,9 +269,9 @@ static ssize_t ade7758_write_8bit(struct device *dev,
|
||||||
{
|
{
|
||||||
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
|
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
|
||||||
int ret;
|
int ret;
|
||||||
long val;
|
u8 val;
|
||||||
|
|
||||||
ret = strict_strtol(buf, 10, &val);
|
ret = kstrtou8(buf, 10, &val);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_ret;
|
goto error_ret;
|
||||||
ret = ade7758_spi_write_reg_8(dev, this_attr->address, val);
|
ret = ade7758_spi_write_reg_8(dev, this_attr->address, val);
|
||||||
|
@ -287,9 +287,9 @@ static ssize_t ade7758_write_16bit(struct device *dev,
|
||||||
{
|
{
|
||||||
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
|
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
|
||||||
int ret;
|
int ret;
|
||||||
long val;
|
u16 val;
|
||||||
|
|
||||||
ret = strict_strtol(buf, 10, &val);
|
ret = kstrtou16(buf, 10, &val);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_ret;
|
goto error_ret;
|
||||||
ret = ade7758_spi_write_reg_16(dev, this_attr->address, val);
|
ret = ade7758_spi_write_reg_16(dev, this_attr->address, val);
|
||||||
|
@ -502,11 +502,11 @@ static ssize_t ade7758_write_frequency(struct device *dev,
|
||||||
size_t len)
|
size_t len)
|
||||||
{
|
{
|
||||||
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
||||||
unsigned long val;
|
u16 val;
|
||||||
int ret;
|
int ret;
|
||||||
u8 reg, t;
|
u8 reg, t;
|
||||||
|
|
||||||
ret = strict_strtol(buf, 10, &val);
|
ret = kstrtou16(buf, 10, &val);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
@ -849,12 +849,11 @@ static int ade7758_probe(struct spi_device *spi)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
struct ade7758_state *st;
|
struct ade7758_state *st;
|
||||||
struct iio_dev *indio_dev = iio_device_alloc(sizeof(*st));
|
struct iio_dev *indio_dev;
|
||||||
|
|
||||||
if (indio_dev == NULL) {
|
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
|
||||||
ret = -ENOMEM;
|
if (!indio_dev)
|
||||||
goto error_ret;
|
return -ENOMEM;
|
||||||
}
|
|
||||||
|
|
||||||
st = iio_priv(indio_dev);
|
st = iio_priv(indio_dev);
|
||||||
/* this is only used for removal purposes */
|
/* this is only used for removal purposes */
|
||||||
|
@ -862,10 +861,8 @@ static int ade7758_probe(struct spi_device *spi)
|
||||||
|
|
||||||
/* Allocate the comms buffers */
|
/* Allocate the comms buffers */
|
||||||
st->rx = kcalloc(ADE7758_MAX_RX, sizeof(*st->rx), GFP_KERNEL);
|
st->rx = kcalloc(ADE7758_MAX_RX, sizeof(*st->rx), GFP_KERNEL);
|
||||||
if (st->rx == NULL) {
|
if (!st->rx)
|
||||||
ret = -ENOMEM;
|
return -ENOMEM;
|
||||||
goto error_free_dev;
|
|
||||||
}
|
|
||||||
st->tx = kcalloc(ADE7758_MAX_TX, sizeof(*st->tx), GFP_KERNEL);
|
st->tx = kcalloc(ADE7758_MAX_TX, sizeof(*st->tx), GFP_KERNEL);
|
||||||
if (st->tx == NULL) {
|
if (st->tx == NULL) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
|
@ -920,9 +917,6 @@ error_free_tx:
|
||||||
kfree(st->tx);
|
kfree(st->tx);
|
||||||
error_free_rx:
|
error_free_rx:
|
||||||
kfree(st->rx);
|
kfree(st->rx);
|
||||||
error_free_dev:
|
|
||||||
iio_device_free(indio_dev);
|
|
||||||
error_ret:
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -939,8 +933,6 @@ static int ade7758_remove(struct spi_device *spi)
|
||||||
kfree(st->tx);
|
kfree(st->tx);
|
||||||
kfree(st->rx);
|
kfree(st->rx);
|
||||||
|
|
||||||
iio_device_free(indio_dev);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -69,11 +69,7 @@ static irqreturn_t ade7758_trigger_handler(int irq, void *p)
|
||||||
if (ade7758_spi_read_burst(indio_dev) >= 0)
|
if (ade7758_spi_read_burst(indio_dev) >= 0)
|
||||||
*dat32 = get_unaligned_be32(&st->rx_buf[5]) & 0xFFFFFF;
|
*dat32 = get_unaligned_be32(&st->rx_buf[5]) & 0xFFFFFF;
|
||||||
|
|
||||||
/* Guaranteed to be aligned with 8 byte boundary */
|
iio_push_to_buffers_with_timestamp(indio_dev, dat64, pf->timestamp);
|
||||||
if (indio_dev->scan_timestamp)
|
|
||||||
dat64[1] = pf->timestamp;
|
|
||||||
|
|
||||||
iio_push_to_buffers(indio_dev, (u8 *)dat64);
|
|
||||||
|
|
||||||
iio_trigger_notify_done(indio_dev->trig);
|
iio_trigger_notify_done(indio_dev->trig);
|
||||||
|
|
||||||
|
|
|
@ -185,9 +185,9 @@ static ssize_t ade7759_write_8bit(struct device *dev,
|
||||||
{
|
{
|
||||||
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
|
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
|
||||||
int ret;
|
int ret;
|
||||||
long val;
|
u8 val;
|
||||||
|
|
||||||
ret = strict_strtol(buf, 10, &val);
|
ret = kstrtou8(buf, 10, &val);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_ret;
|
goto error_ret;
|
||||||
ret = ade7759_spi_write_reg_8(dev, this_attr->address, val);
|
ret = ade7759_spi_write_reg_8(dev, this_attr->address, val);
|
||||||
|
@ -203,9 +203,9 @@ static ssize_t ade7759_write_16bit(struct device *dev,
|
||||||
{
|
{
|
||||||
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
|
struct iio_dev_attr *this_attr = to_iio_dev_attr(attr);
|
||||||
int ret;
|
int ret;
|
||||||
long val;
|
u16 val;
|
||||||
|
|
||||||
ret = strict_strtol(buf, 10, &val);
|
ret = kstrtou16(buf, 10, &val);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_ret;
|
goto error_ret;
|
||||||
ret = ade7759_spi_write_reg_16(dev, this_attr->address, val);
|
ret = ade7759_spi_write_reg_16(dev, this_attr->address, val);
|
||||||
|
@ -360,11 +360,11 @@ static ssize_t ade7759_write_frequency(struct device *dev,
|
||||||
{
|
{
|
||||||
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
||||||
struct ade7759_state *st = iio_priv(indio_dev);
|
struct ade7759_state *st = iio_priv(indio_dev);
|
||||||
unsigned long val;
|
u16 val;
|
||||||
int ret;
|
int ret;
|
||||||
u16 reg, t;
|
u16 reg, t;
|
||||||
|
|
||||||
ret = strict_strtol(buf, 10, &val);
|
ret = kstrtou16(buf, 10, &val);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
if (val == 0)
|
if (val == 0)
|
||||||
|
@ -444,11 +444,9 @@ static int ade7759_probe(struct spi_device *spi)
|
||||||
struct iio_dev *indio_dev;
|
struct iio_dev *indio_dev;
|
||||||
|
|
||||||
/* setup the industrialio driver allocated elements */
|
/* setup the industrialio driver allocated elements */
|
||||||
indio_dev = iio_device_alloc(sizeof(*st));
|
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
|
||||||
if (indio_dev == NULL) {
|
if (!indio_dev)
|
||||||
ret = -ENOMEM;
|
return -ENOMEM;
|
||||||
goto error_ret;
|
|
||||||
}
|
|
||||||
/* this is only used for removal purposes */
|
/* this is only used for removal purposes */
|
||||||
spi_set_drvdata(spi, indio_dev);
|
spi_set_drvdata(spi, indio_dev);
|
||||||
|
|
||||||
|
@ -463,18 +461,13 @@ static int ade7759_probe(struct spi_device *spi)
|
||||||
/* Get the device into a sane initial state */
|
/* Get the device into a sane initial state */
|
||||||
ret = ade7759_initial_setup(indio_dev);
|
ret = ade7759_initial_setup(indio_dev);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_free_dev;
|
return ret;
|
||||||
|
|
||||||
ret = iio_device_register(indio_dev);
|
ret = iio_device_register(indio_dev);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_free_dev;
|
return ret;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error_free_dev:
|
|
||||||
iio_device_free(indio_dev);
|
|
||||||
error_ret:
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fixme, confirm ordering in this function */
|
/* fixme, confirm ordering in this function */
|
||||||
|
@ -484,7 +477,6 @@ static int ade7759_remove(struct spi_device *spi)
|
||||||
|
|
||||||
iio_device_unregister(indio_dev);
|
iio_device_unregister(indio_dev);
|
||||||
ade7759_stop_device(&indio_dev->dev);
|
ade7759_stop_device(&indio_dev->dev);
|
||||||
iio_device_free(indio_dev);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -208,7 +208,7 @@ static int ade7854_i2c_probe(struct i2c_client *client,
|
||||||
struct ade7854_state *st;
|
struct ade7854_state *st;
|
||||||
struct iio_dev *indio_dev;
|
struct iio_dev *indio_dev;
|
||||||
|
|
||||||
indio_dev = iio_device_alloc(sizeof(*st));
|
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st));
|
||||||
if (indio_dev == NULL)
|
if (indio_dev == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
st = iio_priv(indio_dev);
|
st = iio_priv(indio_dev);
|
||||||
|
@ -225,8 +225,6 @@ static int ade7854_i2c_probe(struct i2c_client *client,
|
||||||
st->irq = client->irq;
|
st->irq = client->irq;
|
||||||
|
|
||||||
ret = ade7854_probe(indio_dev, &client->dev);
|
ret = ade7854_probe(indio_dev, &client->dev);
|
||||||
if (ret)
|
|
||||||
iio_device_free(indio_dev);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -278,7 +278,7 @@ static int ade7854_spi_probe(struct spi_device *spi)
|
||||||
struct ade7854_state *st;
|
struct ade7854_state *st;
|
||||||
struct iio_dev *indio_dev;
|
struct iio_dev *indio_dev;
|
||||||
|
|
||||||
indio_dev = iio_device_alloc(sizeof(*st));
|
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
|
||||||
if (indio_dev == NULL)
|
if (indio_dev == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
st = iio_priv(indio_dev);
|
st = iio_priv(indio_dev);
|
||||||
|
@ -296,8 +296,6 @@ static int ade7854_spi_probe(struct spi_device *spi)
|
||||||
|
|
||||||
|
|
||||||
ret = ade7854_probe(indio_dev, &spi->dev);
|
ret = ade7854_probe(indio_dev, &spi->dev);
|
||||||
if (ret)
|
|
||||||
iio_device_free(indio_dev);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -100,9 +100,9 @@ static ssize_t ade7854_write_8bit(struct device *dev,
|
||||||
struct ade7854_state *st = iio_priv(indio_dev);
|
struct ade7854_state *st = iio_priv(indio_dev);
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
long val;
|
u8 val;
|
||||||
|
|
||||||
ret = strict_strtol(buf, 10, &val);
|
ret = kstrtou8(buf, 10, &val);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_ret;
|
goto error_ret;
|
||||||
ret = st->write_reg_8(dev, this_attr->address, val);
|
ret = st->write_reg_8(dev, this_attr->address, val);
|
||||||
|
@ -121,9 +121,9 @@ static ssize_t ade7854_write_16bit(struct device *dev,
|
||||||
struct ade7854_state *st = iio_priv(indio_dev);
|
struct ade7854_state *st = iio_priv(indio_dev);
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
long val;
|
u16 val;
|
||||||
|
|
||||||
ret = strict_strtol(buf, 10, &val);
|
ret = kstrtou16(buf, 10, &val);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_ret;
|
goto error_ret;
|
||||||
ret = st->write_reg_16(dev, this_attr->address, val);
|
ret = st->write_reg_16(dev, this_attr->address, val);
|
||||||
|
@ -142,9 +142,9 @@ static ssize_t ade7854_write_24bit(struct device *dev,
|
||||||
struct ade7854_state *st = iio_priv(indio_dev);
|
struct ade7854_state *st = iio_priv(indio_dev);
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
long val;
|
u32 val;
|
||||||
|
|
||||||
ret = strict_strtol(buf, 10, &val);
|
ret = kstrtou32(buf, 10, &val);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_ret;
|
goto error_ret;
|
||||||
ret = st->write_reg_24(dev, this_attr->address, val);
|
ret = st->write_reg_24(dev, this_attr->address, val);
|
||||||
|
@ -163,9 +163,9 @@ static ssize_t ade7854_write_32bit(struct device *dev,
|
||||||
struct ade7854_state *st = iio_priv(indio_dev);
|
struct ade7854_state *st = iio_priv(indio_dev);
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
long val;
|
u32 val;
|
||||||
|
|
||||||
ret = strict_strtol(buf, 10, &val);
|
ret = kstrtou32(buf, 10, &val);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_ret;
|
goto error_ret;
|
||||||
ret = st->write_reg_32(dev, this_attr->address, val);
|
ret = st->write_reg_32(dev, this_attr->address, val);
|
||||||
|
@ -550,7 +550,7 @@ int ade7854_probe(struct iio_dev *indio_dev, struct device *dev)
|
||||||
|
|
||||||
ret = iio_device_register(indio_dev);
|
ret = iio_device_register(indio_dev);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_free_dev;
|
return ret;
|
||||||
|
|
||||||
/* Get the device into a sane initial state */
|
/* Get the device into a sane initial state */
|
||||||
ret = ade7854_initial_setup(indio_dev);
|
ret = ade7854_initial_setup(indio_dev);
|
||||||
|
@ -561,9 +561,6 @@ int ade7854_probe(struct iio_dev *indio_dev, struct device *dev)
|
||||||
|
|
||||||
error_unreg_dev:
|
error_unreg_dev:
|
||||||
iio_device_unregister(indio_dev);
|
iio_device_unregister(indio_dev);
|
||||||
error_free_dev:
|
|
||||||
iio_device_free(indio_dev);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(ade7854_probe);
|
EXPORT_SYMBOL(ade7854_probe);
|
||||||
|
@ -571,7 +568,6 @@ EXPORT_SYMBOL(ade7854_probe);
|
||||||
int ade7854_remove(struct iio_dev *indio_dev)
|
int ade7854_remove(struct iio_dev *indio_dev)
|
||||||
{
|
{
|
||||||
iio_device_unregister(indio_dev);
|
iio_device_unregister(indio_dev);
|
||||||
iio_device_free(indio_dev);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -107,16 +107,16 @@ static int ad2s1200_probe(struct spi_device *spi)
|
||||||
unsigned short *pins = spi->dev.platform_data;
|
unsigned short *pins = spi->dev.platform_data;
|
||||||
|
|
||||||
for (pn = 0; pn < AD2S1200_PN; pn++)
|
for (pn = 0; pn < AD2S1200_PN; pn++)
|
||||||
if (gpio_request_one(pins[pn], GPIOF_DIR_OUT, DRV_NAME)) {
|
ret = devm_gpio_request_one(&spi->dev, pins[pn], GPIOF_DIR_OUT,
|
||||||
pr_err("%s: request gpio pin %d failed\n",
|
DRV_NAME);
|
||||||
DRV_NAME, pins[pn]);
|
if (ret) {
|
||||||
goto error_ret;
|
dev_err(&spi->dev, "request gpio pin %d failed\n",
|
||||||
|
pins[pn]);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
indio_dev = iio_device_alloc(sizeof(*st));
|
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
|
||||||
if (indio_dev == NULL) {
|
if (!indio_dev)
|
||||||
ret = -ENOMEM;
|
return -ENOMEM;
|
||||||
goto error_ret;
|
|
||||||
}
|
|
||||||
spi_set_drvdata(spi, indio_dev);
|
spi_set_drvdata(spi, indio_dev);
|
||||||
st = iio_priv(indio_dev);
|
st = iio_priv(indio_dev);
|
||||||
mutex_init(&st->lock);
|
mutex_init(&st->lock);
|
||||||
|
@ -133,26 +133,18 @@ static int ad2s1200_probe(struct spi_device *spi)
|
||||||
|
|
||||||
ret = iio_device_register(indio_dev);
|
ret = iio_device_register(indio_dev);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_free_dev;
|
return ret;
|
||||||
|
|
||||||
spi->max_speed_hz = AD2S1200_HZ;
|
spi->max_speed_hz = AD2S1200_HZ;
|
||||||
spi->mode = SPI_MODE_3;
|
spi->mode = SPI_MODE_3;
|
||||||
spi_setup(spi);
|
spi_setup(spi);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error_free_dev:
|
|
||||||
iio_device_free(indio_dev);
|
|
||||||
error_ret:
|
|
||||||
for (--pn; pn >= 0; pn--)
|
|
||||||
gpio_free(pins[pn]);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ad2s1200_remove(struct spi_device *spi)
|
static int ad2s1200_remove(struct spi_device *spi)
|
||||||
{
|
{
|
||||||
iio_device_unregister(spi_get_drvdata(spi));
|
iio_device_unregister(spi_get_drvdata(spi));
|
||||||
iio_device_free(spi_get_drvdata(spi));
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -206,10 +206,10 @@ static ssize_t ad2s1210_store_fclkin(struct device *dev,
|
||||||
size_t len)
|
size_t len)
|
||||||
{
|
{
|
||||||
struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
|
struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
|
||||||
unsigned long fclkin;
|
unsigned int fclkin;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = strict_strtoul(buf, 10, &fclkin);
|
ret = kstrtouint(buf, 10, &fclkin);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
if (fclkin < AD2S1210_MIN_CLKIN || fclkin > AD2S1210_MAX_CLKIN) {
|
if (fclkin < AD2S1210_MIN_CLKIN || fclkin > AD2S1210_MAX_CLKIN) {
|
||||||
|
@ -243,10 +243,10 @@ static ssize_t ad2s1210_store_fexcit(struct device *dev,
|
||||||
const char *buf, size_t len)
|
const char *buf, size_t len)
|
||||||
{
|
{
|
||||||
struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
|
struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
|
||||||
unsigned long fexcit;
|
unsigned int fexcit;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = strict_strtoul(buf, 10, &fexcit);
|
ret = kstrtouint(buf, 10, &fexcit);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
if (fexcit < AD2S1210_MIN_EXCIT || fexcit > AD2S1210_MAX_EXCIT) {
|
if (fexcit < AD2S1210_MIN_EXCIT || fexcit > AD2S1210_MAX_EXCIT) {
|
||||||
|
@ -282,11 +282,11 @@ static ssize_t ad2s1210_store_control(struct device *dev,
|
||||||
const char *buf, size_t len)
|
const char *buf, size_t len)
|
||||||
{
|
{
|
||||||
struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
|
struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
|
||||||
unsigned long udata;
|
unsigned char udata;
|
||||||
unsigned char data;
|
unsigned char data;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = strict_strtoul(buf, 16, &udata);
|
ret = kstrtou8(buf, 16, &udata);
|
||||||
if (ret)
|
if (ret)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
@ -337,10 +337,10 @@ static ssize_t ad2s1210_store_resolution(struct device *dev,
|
||||||
{
|
{
|
||||||
struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
|
struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
|
||||||
unsigned char data;
|
unsigned char data;
|
||||||
unsigned long udata;
|
unsigned char udata;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = strict_strtoul(buf, 10, &udata);
|
ret = kstrtou8(buf, 10, &udata);
|
||||||
if (ret || udata < 10 || udata > 16) {
|
if (ret || udata < 10 || udata > 16) {
|
||||||
pr_err("ad2s1210: resolution out of range\n");
|
pr_err("ad2s1210: resolution out of range\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -438,11 +438,11 @@ static ssize_t ad2s1210_store_reg(struct device *dev,
|
||||||
struct device_attribute *attr, const char *buf, size_t len)
|
struct device_attribute *attr, const char *buf, size_t len)
|
||||||
{
|
{
|
||||||
struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
|
struct ad2s1210_state *st = iio_priv(dev_to_iio_dev(dev));
|
||||||
unsigned long data;
|
unsigned char data;
|
||||||
int ret;
|
int ret;
|
||||||
struct iio_dev_attr *iattr = to_iio_dev_attr(attr);
|
struct iio_dev_attr *iattr = to_iio_dev_attr(attr);
|
||||||
|
|
||||||
ret = strict_strtoul(buf, 10, &data);
|
ret = kstrtou8(buf, 10, &data);
|
||||||
if (ret)
|
if (ret)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
mutex_lock(&st->lock);
|
mutex_lock(&st->lock);
|
||||||
|
@ -669,16 +669,14 @@ static int ad2s1210_probe(struct spi_device *spi)
|
||||||
if (spi->dev.platform_data == NULL)
|
if (spi->dev.platform_data == NULL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
indio_dev = iio_device_alloc(sizeof(*st));
|
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
|
||||||
if (indio_dev == NULL) {
|
if (!indio_dev)
|
||||||
ret = -ENOMEM;
|
return -ENOMEM;
|
||||||
goto error_ret;
|
|
||||||
}
|
|
||||||
st = iio_priv(indio_dev);
|
st = iio_priv(indio_dev);
|
||||||
st->pdata = spi->dev.platform_data;
|
st->pdata = spi->dev.platform_data;
|
||||||
ret = ad2s1210_setup_gpios(st);
|
ret = ad2s1210_setup_gpios(st);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto error_free_dev;
|
return ret;
|
||||||
|
|
||||||
spi_set_drvdata(spi, indio_dev);
|
spi_set_drvdata(spi, indio_dev);
|
||||||
|
|
||||||
|
@ -709,9 +707,6 @@ static int ad2s1210_probe(struct spi_device *spi)
|
||||||
|
|
||||||
error_free_gpios:
|
error_free_gpios:
|
||||||
ad2s1210_free_gpios(st);
|
ad2s1210_free_gpios(st);
|
||||||
error_free_dev:
|
|
||||||
iio_device_free(indio_dev);
|
|
||||||
error_ret:
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -721,7 +716,6 @@ static int ad2s1210_remove(struct spi_device *spi)
|
||||||
|
|
||||||
iio_device_unregister(indio_dev);
|
iio_device_unregister(indio_dev);
|
||||||
ad2s1210_free_gpios(iio_priv(indio_dev));
|
ad2s1210_free_gpios(iio_priv(indio_dev));
|
||||||
iio_device_free(indio_dev);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,11 +64,9 @@ static int ad2s90_probe(struct spi_device *spi)
|
||||||
struct ad2s90_state *st;
|
struct ad2s90_state *st;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
indio_dev = iio_device_alloc(sizeof(*st));
|
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
|
||||||
if (indio_dev == NULL) {
|
if (!indio_dev)
|
||||||
ret = -ENOMEM;
|
return -ENOMEM;
|
||||||
goto error_ret;
|
|
||||||
}
|
|
||||||
st = iio_priv(indio_dev);
|
st = iio_priv(indio_dev);
|
||||||
spi_set_drvdata(spi, indio_dev);
|
spi_set_drvdata(spi, indio_dev);
|
||||||
|
|
||||||
|
@ -83,7 +81,7 @@ static int ad2s90_probe(struct spi_device *spi)
|
||||||
|
|
||||||
ret = iio_device_register(indio_dev);
|
ret = iio_device_register(indio_dev);
|
||||||
if (ret)
|
if (ret)
|
||||||
goto error_free_dev;
|
return ret;
|
||||||
|
|
||||||
/* need 600ns between CS and the first falling edge of SCLK */
|
/* need 600ns between CS and the first falling edge of SCLK */
|
||||||
spi->max_speed_hz = 830000;
|
spi->max_speed_hz = 830000;
|
||||||
|
@ -91,17 +89,11 @@ static int ad2s90_probe(struct spi_device *spi)
|
||||||
spi_setup(spi);
|
spi_setup(spi);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error_free_dev:
|
|
||||||
iio_device_free(indio_dev);
|
|
||||||
error_ret:
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ad2s90_remove(struct spi_device *spi)
|
static int ad2s90_remove(struct spi_device *spi)
|
||||||
{
|
{
|
||||||
iio_device_unregister(spi_get_drvdata(spi));
|
iio_device_unregister(spi_get_drvdata(spi));
|
||||||
iio_device_free(spi_get_drvdata(spi));
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue