mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-20 02:34:23 +08:00
2nd set of new device support, features and cleanups for IIO in the 4.12 cycle
A good collection of outreachy related patches in here - mostly staging driver cleanup. Also a fair number of patches added explicit OF device ID tables for i2c drivers - a precursor to dropping (eventually) the implicit probing. New Device Support * Allwinner SoC ADC. - So far covers the sun4i-a10, sun5i-a13 and sun6i-a31 general purpose ADCs, including thermal side of things. This missed the last cycle due to my incompetence, so good to get in now, particularly as various patches dependent on it are appearing. * ltc2632 - new driver supporting ltc2632-l12, ltc2632-l10, ltc2632-l8, ltc2632-h12, ltc-2632-h10, ltc-2632-h8 dacs Cleanups * Documentation - drop a broken reference to i2c/trivial-devices * ad2s1200 - drop & from function pointers for consistency. * ad2s1210 - formatting fixes. * ad7152 - octal permissions instead of symbolic. - drop & from function pointers for consistent usage. * ad7192 - drop & from function pointers for consistent usage. * ad7280 - replace core mlock usage with a local lock as mlock is intended only to protect the current device state (direct reads, or triggered and buffered) * ad7746 - drop & from function pointers for consistent usage. - replace core mlock usage with a local lock as mlock is intended only to protect the current device state (direct reads, or triggered and buffered) * ad7754 - move contents of header file into source file as not used anywhere else. * ad7759 - move contents of header file into source file as not used anywhere else. * ad7780 - drop & from function pointers for consistent usage. * ad7832 - replace core mlock usage with a local lock as mlock is intended only to protect the current device state (direct reads, or triggered and buffered) * ad9834 - replace core mlock usage with a local lock as mlock is intended only to protect the current device state (direct reads, or triggered and buffered) - drop an unnecessary goto in favour of direct return. * adis16060 - drop & from function pointers as inconsistent. * adis16201 - drop a local mutex as the adis core already protects everything necessary. - drop & from function pointers for consistent usage. * adis16203 - drop & from function pointers for consistent usage. * adis16209 - drop a local mutex as the adis core already protects everything necessary. - use an enum for scan index giving slightly nicer code. - drop & from function pointers for consistent usage. * adis16240 - drop a local mutex as the adis core already protects everything necessary. - use an enum for scan index giving slightly nicer code. - drop & from function pointers for consistent usage. * apds9960 - add OF device ID table. * bma180 - add OF device ID table. - prefer unsigned int to bare use of unsigned. * bmc150_magn - add OF device ID table. * hmp03 - add OF device ID table. * ina2xx - add OF device ID table. * itg3200 - add OF device ID table. * mag3110 - add OF device ID table. * max11100 - remove .owner field as it is set by the spi core. * max5821 - add .of_match_table set to the ID table which was present but not used. * mcp4725 - add OF device ID table. * mlx96014 - add OF device ID table. * mma7455 - add OF device ID table. * mma7660 - add OF device ID table. * mpl3115 - add OF device ID table. * mpu6050 - add OF device ID table. * pc104 - mask pc104 drivers behind a global pc104 config option. * ti-ads1015 - add OF device ID table. * tsl2563 - add OF device ID table. * us5182d - add OF device ID table. -----BEGIN PGP SIGNATURE----- iQJFBAABCAAvFiEEbilms4eEBlKRJoGxVIU0mcT0FogFAljRe1MRHGppYzIzQGtl cm5lbC5vcmcACgkQVIU0mcT0Foh41xAAgVPrPnMF3vzHZADKbZRdvc0XPRoDl4Hf 6Z9sL+5hFNskwH2tPGxCDigz/RZA6gjB5XLxv+gA/UYPyiYSRnlLNeslzL0HSkPL ACKN2f8mutzz0fJ9z5E14M7h+7y5/d3Chj3BmcCeVdHq900kgJaB0aJ7/YWEsvdj HGwDvpMvOXzLnVTFTPmJLqryQVZun4kSlpUFxieQlsNNkfkwJS5owdj2R2z/P/y/ wNsUzeTmmACSbH2JLPrOd8krYnDnmP7xvkTUEfM5W4bOCI8sSRqlxKRseaWc4IPF dyxujpwKave+Yq4evmZi9k/BMvq4a5pqKI0TsHoA+LdGWc9vILO6av1S0xa/bM/L PAvjwPaDmJ9vfgUSQFsHLnYY2ZFF93Z1kGnGk28lwFKCcQT3qC0t9UjqBf1cyYuo yXjotmKeqn9fjgZcUW3HT9vGr6TLROsd3zjgBvrUg0cuBcv2i04nADHEtITS4ZQx oDgDqgxBbnbrjxM9DC91uPF8uMJRu+95OKjHe9p+MOzyg+BlquBjaIrg1XBsJpo/ 229PSOjg/g3KeVDS4op6+kyTr2fhn0hFdgiUdXDlnKdsOAbB9mhr9uGHFM3wm5PF CkXtHA2ke1ys9ygJzu/1FSKBZJhJRfcl46BUbO+Ea2VEvuTtKDXCTPeFD7vG5tHV 1s6OUVuaZHw= =PwhQ -----END PGP SIGNATURE----- Merge tag 'iio-for-4.12b' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-next Jonathan writes: 2nd set of new device support, features and cleanups for IIO in the 4.12 cycle A good collection of outreachy related patches in here - mostly staging driver cleanup. Also a fair number of patches added explicit OF device ID tables for i2c drivers - a precursor to dropping (eventually) the implicit probing. New Device Support * Allwinner SoC ADC. - So far covers the sun4i-a10, sun5i-a13 and sun6i-a31 general purpose ADCs, including thermal side of things. This missed the last cycle due to my incompetence, so good to get in now, particularly as various patches dependent on it are appearing. * ltc2632 - new driver supporting ltc2632-l12, ltc2632-l10, ltc2632-l8, ltc2632-h12, ltc-2632-h10, ltc-2632-h8 dacs Cleanups * Documentation - drop a broken reference to i2c/trivial-devices * ad2s1200 - drop & from function pointers for consistency. * ad2s1210 - formatting fixes. * ad7152 - octal permissions instead of symbolic. - drop & from function pointers for consistent usage. * ad7192 - drop & from function pointers for consistent usage. * ad7280 - replace core mlock usage with a local lock as mlock is intended only to protect the current device state (direct reads, or triggered and buffered) * ad7746 - drop & from function pointers for consistent usage. - replace core mlock usage with a local lock as mlock is intended only to protect the current device state (direct reads, or triggered and buffered) * ad7754 - move contents of header file into source file as not used anywhere else. * ad7759 - move contents of header file into source file as not used anywhere else. * ad7780 - drop & from function pointers for consistent usage. * ad7832 - replace core mlock usage with a local lock as mlock is intended only to protect the current device state (direct reads, or triggered and buffered) * ad9834 - replace core mlock usage with a local lock as mlock is intended only to protect the current device state (direct reads, or triggered and buffered) - drop an unnecessary goto in favour of direct return. * adis16060 - drop & from function pointers as inconsistent. * adis16201 - drop a local mutex as the adis core already protects everything necessary. - drop & from function pointers for consistent usage. * adis16203 - drop & from function pointers for consistent usage. * adis16209 - drop a local mutex as the adis core already protects everything necessary. - use an enum for scan index giving slightly nicer code. - drop & from function pointers for consistent usage. * adis16240 - drop a local mutex as the adis core already protects everything necessary. - use an enum for scan index giving slightly nicer code. - drop & from function pointers for consistent usage. * apds9960 - add OF device ID table. * bma180 - add OF device ID table. - prefer unsigned int to bare use of unsigned. * bmc150_magn - add OF device ID table. * hmp03 - add OF device ID table. * ina2xx - add OF device ID table. * itg3200 - add OF device ID table. * mag3110 - add OF device ID table. * max11100 - remove .owner field as it is set by the spi core. * max5821 - add .of_match_table set to the ID table which was present but not used. * mcp4725 - add OF device ID table. * mlx96014 - add OF device ID table. * mma7455 - add OF device ID table. * mma7660 - add OF device ID table. * mpl3115 - add OF device ID table. * mpu6050 - add OF device ID table. * pc104 - mask pc104 drivers behind a global pc104 config option. * ti-ads1015 - add OF device ID table. * tsl2563 - add OF device ID table. * us5182d - add OF device ID table.
This commit is contained in:
commit
c831c583f8
23
Documentation/devicetree/bindings/iio/dac/ltc2632.txt
Normal file
23
Documentation/devicetree/bindings/iio/dac/ltc2632.txt
Normal file
@ -0,0 +1,23 @@
|
||||
Linear Technology LTC2632 DAC device driver
|
||||
|
||||
Required properties:
|
||||
- compatible: Has to contain one of the following:
|
||||
lltc,ltc2632-l12
|
||||
lltc,ltc2632-l10
|
||||
lltc,ltc2632-l8
|
||||
lltc,ltc2632-h12
|
||||
lltc,ltc2632-h10
|
||||
lltc,ltc2632-h8
|
||||
|
||||
Property rules described in Documentation/devicetree/bindings/spi/spi-bus.txt
|
||||
apply. In particular, "reg" and "spi-max-frequency" properties must be given.
|
||||
|
||||
Example:
|
||||
|
||||
spi_master {
|
||||
dac: ltc2632@0 {
|
||||
compatible = "lltc,ltc2632-l12";
|
||||
reg = <0>; /* CS0 */
|
||||
spi-max-frequency = <1000000>;
|
||||
};
|
||||
};
|
@ -3024,7 +3024,6 @@ CAPELLA MICROSYSTEMS LIGHT SENSOR DRIVER
|
||||
M: Kevin Tsai <ktsai@capellamicro.com>
|
||||
S: Maintained
|
||||
F: drivers/iio/light/cm*
|
||||
F: Documentation/devicetree/bindings/i2c/trivial-admin-guide/devices.rst
|
||||
|
||||
CAVIUM THUNDERX2 ARM64 SOC
|
||||
M: Jayachandran C <jnair@caviumnetworks.com>
|
||||
|
@ -18,6 +18,7 @@
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/slab.h>
|
||||
@ -32,7 +33,7 @@
|
||||
#define BMA180_DRV_NAME "bma180"
|
||||
#define BMA180_IRQ_NAME "bma180_event"
|
||||
|
||||
enum {
|
||||
enum chip_ids {
|
||||
BMA180,
|
||||
BMA250,
|
||||
};
|
||||
@ -41,11 +42,11 @@ struct bma180_data;
|
||||
|
||||
struct bma180_part_info {
|
||||
const struct iio_chan_spec *channels;
|
||||
unsigned num_channels;
|
||||
unsigned int num_channels;
|
||||
const int *scale_table;
|
||||
unsigned num_scales;
|
||||
unsigned int num_scales;
|
||||
const int *bw_table;
|
||||
unsigned num_bw;
|
||||
unsigned int num_bw;
|
||||
|
||||
u8 int_reset_reg, int_reset_mask;
|
||||
u8 sleep_reg, sleep_mask;
|
||||
@ -408,7 +409,7 @@ err:
|
||||
dev_err(&data->client->dev, "failed to disable the chip\n");
|
||||
}
|
||||
|
||||
static ssize_t bma180_show_avail(char *buf, const int *vals, unsigned n,
|
||||
static ssize_t bma180_show_avail(char *buf, const int *vals, unsigned int n,
|
||||
bool micros)
|
||||
{
|
||||
size_t len = 0;
|
||||
@ -707,6 +708,7 @@ static int bma180_probe(struct i2c_client *client,
|
||||
{
|
||||
struct bma180_data *data;
|
||||
struct iio_dev *indio_dev;
|
||||
enum chip_ids chip;
|
||||
int ret;
|
||||
|
||||
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
|
||||
@ -716,7 +718,11 @@ static int bma180_probe(struct i2c_client *client,
|
||||
data = iio_priv(indio_dev);
|
||||
i2c_set_clientdata(client, indio_dev);
|
||||
data->client = client;
|
||||
data->part_info = &bma180_part_info[id->driver_data];
|
||||
if (client->dev.of_node)
|
||||
chip = (enum chip_ids)of_device_get_match_data(&client->dev);
|
||||
else
|
||||
chip = id->driver_data;
|
||||
data->part_info = &bma180_part_info[chip];
|
||||
|
||||
ret = data->part_info->chip_config(data);
|
||||
if (ret < 0)
|
||||
@ -844,10 +850,24 @@ static struct i2c_device_id bma180_ids[] = {
|
||||
|
||||
MODULE_DEVICE_TABLE(i2c, bma180_ids);
|
||||
|
||||
static const struct of_device_id bma180_of_match[] = {
|
||||
{
|
||||
.compatible = "bosch,bma180",
|
||||
.data = (void *)BMA180
|
||||
},
|
||||
{
|
||||
.compatible = "bosch,bma250",
|
||||
.data = (void *)BMA250
|
||||
},
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, bma180_of_match);
|
||||
|
||||
static struct i2c_driver bma180_driver = {
|
||||
.driver = {
|
||||
.name = "bma180",
|
||||
.pm = BMA180_PM_OPS,
|
||||
.of_match_table = bma180_of_match,
|
||||
},
|
||||
.probe = bma180_probe,
|
||||
.remove = bma180_remove,
|
||||
|
@ -41,12 +41,20 @@ static const struct i2c_device_id mma7455_i2c_ids[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, mma7455_i2c_ids);
|
||||
|
||||
static const struct of_device_id mma7455_of_match[] = {
|
||||
{ .compatible = "fsl,mma7455" },
|
||||
{ .compatible = "fsl,mma7456" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mma7455_of_match);
|
||||
|
||||
static struct i2c_driver mma7455_i2c_driver = {
|
||||
.probe = mma7455_i2c_probe,
|
||||
.remove = mma7455_i2c_remove,
|
||||
.id_table = mma7455_i2c_ids,
|
||||
.driver = {
|
||||
.name = "mma7455-i2c",
|
||||
.of_match_table = mma7455_of_match,
|
||||
},
|
||||
};
|
||||
module_i2c_driver(mma7455_i2c_driver);
|
||||
|
@ -253,6 +253,12 @@ static const struct i2c_device_id mma7660_i2c_id[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, mma7660_i2c_id);
|
||||
|
||||
static const struct of_device_id mma7660_of_match[] = {
|
||||
{ .compatible = "fsl,mma7660" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mma7660_of_match);
|
||||
|
||||
static const struct acpi_device_id mma7660_acpi_id[] = {
|
||||
{"MMA7660", 0},
|
||||
{}
|
||||
@ -264,6 +270,7 @@ static struct i2c_driver mma7660_driver = {
|
||||
.driver = {
|
||||
.name = "mma7660",
|
||||
.pm = MMA7660_PM_OPS,
|
||||
.of_match_table = mma7660_of_match,
|
||||
.acpi_match_table = ACPI_PTR(mma7660_acpi_id),
|
||||
},
|
||||
.probe = mma7660_probe,
|
||||
|
@ -546,7 +546,7 @@ config STM32_ADC
|
||||
|
||||
config STX104
|
||||
tristate "Apex Embedded Systems STX104 driver"
|
||||
depends on X86 && ISA_BUS_API
|
||||
depends on PC104 && X86 && ISA_BUS_API
|
||||
select GPIOLIB
|
||||
help
|
||||
Say yes here to build support for the Apex Embedded Systems STX104
|
||||
@ -559,6 +559,23 @@ config STX104
|
||||
The base port addresses for the devices may be configured via the base
|
||||
array module parameter.
|
||||
|
||||
config SUN4I_GPADC
|
||||
tristate "Support for the Allwinner SoCs GPADC"
|
||||
depends on IIO
|
||||
depends on MFD_SUN4I_GPADC
|
||||
help
|
||||
Say yes here to build support for Allwinner (A10, A13 and A31) SoCs
|
||||
GPADC. This ADC provides 4 channels which can be used as an ADC or as
|
||||
a touchscreen input and one channel for thermal sensor.
|
||||
|
||||
The thermal sensor slows down ADC readings and can be disabled by
|
||||
disabling CONFIG_THERMAL_OF. However, the thermal sensor should be
|
||||
enabled by default since the SoC temperature is usually more critical
|
||||
than ADC readings.
|
||||
|
||||
To compile this driver as a module, choose M here: the module will be
|
||||
called sun4i-gpadc-iio.
|
||||
|
||||
config TI_ADC081C
|
||||
tristate "Texas Instruments ADC081C/ADC101C/ADC121C family"
|
||||
depends on I2C
|
||||
|
@ -49,6 +49,7 @@ obj-$(CONFIG_RCAR_GYRO_ADC) += rcar-gyroadc.o
|
||||
obj-$(CONFIG_ROCKCHIP_SARADC) += rockchip_saradc.o
|
||||
obj-$(CONFIG_SPEAR_ADC) += spear_adc.o
|
||||
obj-$(CONFIG_STX104) += stx104.o
|
||||
obj-$(CONFIG_SUN4I_GPADC) += sun4i-gpadc-iio.o
|
||||
obj-$(CONFIG_STM32_ADC_CORE) += stm32-adc-core.o
|
||||
obj-$(CONFIG_STM32_ADC) += stm32-adc.o
|
||||
obj-$(CONFIG_TI_ADC081C) += ti-adc081c.o
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include <linux/iio/sysfs.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/util_macros.h>
|
||||
|
||||
@ -635,6 +636,7 @@ static int ina2xx_probe(struct i2c_client *client,
|
||||
struct iio_dev *indio_dev;
|
||||
struct iio_buffer *buffer;
|
||||
unsigned int val;
|
||||
enum ina2xx_ids type;
|
||||
int ret;
|
||||
|
||||
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip));
|
||||
@ -652,7 +654,11 @@ static int ina2xx_probe(struct i2c_client *client,
|
||||
return PTR_ERR(chip->regmap);
|
||||
}
|
||||
|
||||
chip->config = &ina2xx_config[id->driver_data];
|
||||
if (client->dev.of_node)
|
||||
type = (enum ina2xx_ids)of_device_get_match_data(&client->dev);
|
||||
else
|
||||
type = id->driver_data;
|
||||
chip->config = &ina2xx_config[type];
|
||||
|
||||
mutex_init(&chip->state_lock);
|
||||
|
||||
@ -726,9 +732,35 @@ static const struct i2c_device_id ina2xx_id[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, ina2xx_id);
|
||||
|
||||
static const struct of_device_id ina2xx_of_match[] = {
|
||||
{
|
||||
.compatible = "ti,ina219",
|
||||
.data = (void *)ina219
|
||||
},
|
||||
{
|
||||
.compatible = "ti,ina220",
|
||||
.data = (void *)ina219
|
||||
},
|
||||
{
|
||||
.compatible = "ti,ina226",
|
||||
.data = (void *)ina226
|
||||
},
|
||||
{
|
||||
.compatible = "ti,ina230",
|
||||
.data = (void *)ina226
|
||||
},
|
||||
{
|
||||
.compatible = "ti,ina231",
|
||||
.data = (void *)ina226
|
||||
},
|
||||
{},
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ina2xx_of_match);
|
||||
|
||||
static struct i2c_driver ina2xx_driver = {
|
||||
.driver = {
|
||||
.name = KBUILD_MODNAME,
|
||||
.of_match_table = ina2xx_of_match,
|
||||
},
|
||||
.probe = ina2xx_probe,
|
||||
.remove = ina2xx_remove,
|
||||
|
@ -167,7 +167,6 @@ MODULE_DEVICE_TABLE(of, max11100_ids);
|
||||
static struct spi_driver max11100_driver = {
|
||||
.driver = {
|
||||
.name = "max11100",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = of_match_ptr(max11100_ids),
|
||||
},
|
||||
.probe = max11100_probe,
|
||||
|
613
drivers/iio/adc/sun4i-gpadc-iio.c
Normal file
613
drivers/iio/adc/sun4i-gpadc-iio.c
Normal file
@ -0,0 +1,613 @@
|
||||
/* ADC driver for sunxi platforms' (A10, A13 and A31) GPADC
|
||||
*
|
||||
* Copyright (c) 2016 Quentin Schulz <quentin.schulz@free-electrons.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it under
|
||||
* the terms of the GNU General Public License version 2 as published by the
|
||||
* Free Software Foundation.
|
||||
*
|
||||
* The Allwinner SoCs all have an ADC that can also act as a touchscreen
|
||||
* controller and a thermal sensor.
|
||||
* The thermal sensor works only when the ADC acts as a touchscreen controller
|
||||
* and is configured to throw an interrupt every fixed periods of time (let say
|
||||
* every X seconds).
|
||||
* One would be tempted to disable the IP on the hardware side rather than
|
||||
* disabling interrupts to save some power but that resets the internal clock of
|
||||
* the IP, resulting in having to wait X seconds every time we want to read the
|
||||
* value of the thermal sensor.
|
||||
* This is also the reason of using autosuspend in pm_runtime. If there was no
|
||||
* autosuspend, the thermal sensor would need X seconds after every
|
||||
* pm_runtime_get_sync to get a value from the ADC. The autosuspend allows the
|
||||
* thermal sensor to be requested again in a certain time span before it gets
|
||||
* shutdown for not being used.
|
||||
*/
|
||||
|
||||
#include <linux/completion.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/thermal.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include <linux/iio/iio.h>
|
||||
#include <linux/iio/driver.h>
|
||||
#include <linux/iio/machine.h>
|
||||
#include <linux/mfd/sun4i-gpadc.h>
|
||||
|
||||
static unsigned int sun4i_gpadc_chan_select(unsigned int chan)
|
||||
{
|
||||
return SUN4I_GPADC_CTRL1_ADC_CHAN_SELECT(chan);
|
||||
}
|
||||
|
||||
static unsigned int sun6i_gpadc_chan_select(unsigned int chan)
|
||||
{
|
||||
return SUN6I_GPADC_CTRL1_ADC_CHAN_SELECT(chan);
|
||||
}
|
||||
|
||||
struct gpadc_data {
|
||||
int temp_offset;
|
||||
int temp_scale;
|
||||
unsigned int tp_mode_en;
|
||||
unsigned int tp_adc_select;
|
||||
unsigned int (*adc_chan_select)(unsigned int chan);
|
||||
unsigned int adc_chan_mask;
|
||||
};
|
||||
|
||||
static const struct gpadc_data sun4i_gpadc_data = {
|
||||
.temp_offset = -1932,
|
||||
.temp_scale = 133,
|
||||
.tp_mode_en = SUN4I_GPADC_CTRL1_TP_MODE_EN,
|
||||
.tp_adc_select = SUN4I_GPADC_CTRL1_TP_ADC_SELECT,
|
||||
.adc_chan_select = &sun4i_gpadc_chan_select,
|
||||
.adc_chan_mask = SUN4I_GPADC_CTRL1_ADC_CHAN_MASK,
|
||||
};
|
||||
|
||||
static const struct gpadc_data sun5i_gpadc_data = {
|
||||
.temp_offset = -1447,
|
||||
.temp_scale = 100,
|
||||
.tp_mode_en = SUN4I_GPADC_CTRL1_TP_MODE_EN,
|
||||
.tp_adc_select = SUN4I_GPADC_CTRL1_TP_ADC_SELECT,
|
||||
.adc_chan_select = &sun4i_gpadc_chan_select,
|
||||
.adc_chan_mask = SUN4I_GPADC_CTRL1_ADC_CHAN_MASK,
|
||||
};
|
||||
|
||||
static const struct gpadc_data sun6i_gpadc_data = {
|
||||
.temp_offset = -1623,
|
||||
.temp_scale = 167,
|
||||
.tp_mode_en = SUN6I_GPADC_CTRL1_TP_MODE_EN,
|
||||
.tp_adc_select = SUN6I_GPADC_CTRL1_TP_ADC_SELECT,
|
||||
.adc_chan_select = &sun6i_gpadc_chan_select,
|
||||
.adc_chan_mask = SUN6I_GPADC_CTRL1_ADC_CHAN_MASK,
|
||||
};
|
||||
|
||||
struct sun4i_gpadc_iio {
|
||||
struct iio_dev *indio_dev;
|
||||
struct completion completion;
|
||||
int temp_data;
|
||||
u32 adc_data;
|
||||
struct regmap *regmap;
|
||||
unsigned int fifo_data_irq;
|
||||
atomic_t ignore_fifo_data_irq;
|
||||
unsigned int temp_data_irq;
|
||||
atomic_t ignore_temp_data_irq;
|
||||
const struct gpadc_data *data;
|
||||
/* prevents concurrent reads of temperature and ADC */
|
||||
struct mutex mutex;
|
||||
};
|
||||
|
||||
#define SUN4I_GPADC_ADC_CHANNEL(_channel, _name) { \
|
||||
.type = IIO_VOLTAGE, \
|
||||
.indexed = 1, \
|
||||
.channel = _channel, \
|
||||
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
|
||||
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
|
||||
.datasheet_name = _name, \
|
||||
}
|
||||
|
||||
static struct iio_map sun4i_gpadc_hwmon_maps[] = {
|
||||
{
|
||||
.adc_channel_label = "temp_adc",
|
||||
.consumer_dev_name = "iio_hwmon.0",
|
||||
},
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
|
||||
static const struct iio_chan_spec sun4i_gpadc_channels[] = {
|
||||
SUN4I_GPADC_ADC_CHANNEL(0, "adc_chan0"),
|
||||
SUN4I_GPADC_ADC_CHANNEL(1, "adc_chan1"),
|
||||
SUN4I_GPADC_ADC_CHANNEL(2, "adc_chan2"),
|
||||
SUN4I_GPADC_ADC_CHANNEL(3, "adc_chan3"),
|
||||
{
|
||||
.type = IIO_TEMP,
|
||||
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
|
||||
BIT(IIO_CHAN_INFO_SCALE) |
|
||||
BIT(IIO_CHAN_INFO_OFFSET),
|
||||
.datasheet_name = "temp_adc",
|
||||
},
|
||||
};
|
||||
|
||||
static const struct iio_chan_spec sun4i_gpadc_channels_no_temp[] = {
|
||||
SUN4I_GPADC_ADC_CHANNEL(0, "adc_chan0"),
|
||||
SUN4I_GPADC_ADC_CHANNEL(1, "adc_chan1"),
|
||||
SUN4I_GPADC_ADC_CHANNEL(2, "adc_chan2"),
|
||||
SUN4I_GPADC_ADC_CHANNEL(3, "adc_chan3"),
|
||||
};
|
||||
|
||||
static int sun4i_prepare_for_irq(struct iio_dev *indio_dev, int channel,
|
||||
unsigned int irq)
|
||||
{
|
||||
struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
|
||||
int ret;
|
||||
u32 reg;
|
||||
|
||||
pm_runtime_get_sync(indio_dev->dev.parent);
|
||||
|
||||
reinit_completion(&info->completion);
|
||||
|
||||
ret = regmap_write(info->regmap, SUN4I_GPADC_INT_FIFOC,
|
||||
SUN4I_GPADC_INT_FIFOC_TP_FIFO_TRIG_LEVEL(1) |
|
||||
SUN4I_GPADC_INT_FIFOC_TP_FIFO_FLUSH);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = regmap_read(info->regmap, SUN4I_GPADC_CTRL1, ®);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (irq == info->fifo_data_irq) {
|
||||
ret = regmap_write(info->regmap, SUN4I_GPADC_CTRL1,
|
||||
info->data->tp_mode_en |
|
||||
info->data->tp_adc_select |
|
||||
info->data->adc_chan_select(channel));
|
||||
/*
|
||||
* When the IP changes channel, it needs a bit of time to get
|
||||
* correct values.
|
||||
*/
|
||||
if ((reg & info->data->adc_chan_mask) !=
|
||||
info->data->adc_chan_select(channel))
|
||||
mdelay(10);
|
||||
|
||||
} else {
|
||||
/*
|
||||
* The temperature sensor returns valid data only when the ADC
|
||||
* operates in touchscreen mode.
|
||||
*/
|
||||
ret = regmap_write(info->regmap, SUN4I_GPADC_CTRL1,
|
||||
info->data->tp_mode_en);
|
||||
}
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* When the IP changes mode between ADC or touchscreen, it
|
||||
* needs a bit of time to get correct values.
|
||||
*/
|
||||
if ((reg & info->data->tp_adc_select) != info->data->tp_adc_select)
|
||||
mdelay(100);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sun4i_gpadc_read(struct iio_dev *indio_dev, int channel, int *val,
|
||||
unsigned int irq)
|
||||
{
|
||||
struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
|
||||
int ret;
|
||||
|
||||
mutex_lock(&info->mutex);
|
||||
|
||||
ret = sun4i_prepare_for_irq(indio_dev, channel, irq);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
enable_irq(irq);
|
||||
|
||||
/*
|
||||
* The temperature sensor throws an interruption periodically (currently
|
||||
* set at periods of ~0.6s in sun4i_gpadc_runtime_resume). A 1s delay
|
||||
* makes sure an interruption occurs in normal conditions. If it doesn't
|
||||
* occur, then there is a timeout.
|
||||
*/
|
||||
if (!wait_for_completion_timeout(&info->completion,
|
||||
msecs_to_jiffies(1000))) {
|
||||
ret = -ETIMEDOUT;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (irq == info->fifo_data_irq)
|
||||
*val = info->adc_data;
|
||||
else
|
||||
*val = info->temp_data;
|
||||
|
||||
ret = 0;
|
||||
pm_runtime_mark_last_busy(indio_dev->dev.parent);
|
||||
|
||||
err:
|
||||
pm_runtime_put_autosuspend(indio_dev->dev.parent);
|
||||
mutex_unlock(&info->mutex);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sun4i_gpadc_adc_read(struct iio_dev *indio_dev, int channel,
|
||||
int *val)
|
||||
{
|
||||
struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
|
||||
|
||||
return sun4i_gpadc_read(indio_dev, channel, val, info->fifo_data_irq);
|
||||
}
|
||||
|
||||
static int sun4i_gpadc_temp_read(struct iio_dev *indio_dev, int *val)
|
||||
{
|
||||
struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
|
||||
|
||||
return sun4i_gpadc_read(indio_dev, 0, val, info->temp_data_irq);
|
||||
}
|
||||
|
||||
static int sun4i_gpadc_temp_offset(struct iio_dev *indio_dev, int *val)
|
||||
{
|
||||
struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
|
||||
|
||||
*val = info->data->temp_offset;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sun4i_gpadc_temp_scale(struct iio_dev *indio_dev, int *val)
|
||||
{
|
||||
struct sun4i_gpadc_iio *info = iio_priv(indio_dev);
|
||||
|
||||
*val = info->data->temp_scale;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sun4i_gpadc_read_raw(struct iio_dev *indio_dev,
|
||||
struct iio_chan_spec const *chan, int *val,
|
||||
int *val2, long mask)
|
||||
{
|
||||
int ret;
|
||||
|
||||
switch (mask) {
|
||||
case IIO_CHAN_INFO_OFFSET:
|
||||
ret = sun4i_gpadc_temp_offset(indio_dev, val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return IIO_VAL_INT;
|
||||
case IIO_CHAN_INFO_RAW:
|
||||
if (chan->type == IIO_VOLTAGE)
|
||||
ret = sun4i_gpadc_adc_read(indio_dev, chan->channel,
|
||||
val);
|
||||
else
|
||||
ret = sun4i_gpadc_temp_read(indio_dev, val);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return IIO_VAL_INT;
|
||||
case IIO_CHAN_INFO_SCALE:
|
||||
if (chan->type == IIO_VOLTAGE) {
|
||||
/* 3000mV / 4096 * raw */
|
||||
*val = 0;
|
||||
*val2 = 732421875;
|
||||
return IIO_VAL_INT_PLUS_NANO;
|
||||
}
|
||||
|
||||
ret = sun4i_gpadc_temp_scale(indio_dev, val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return IIO_VAL_INT;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static const struct iio_info sun4i_gpadc_iio_info = {
|
||||
.read_raw = sun4i_gpadc_read_raw,
|
||||
.driver_module = THIS_MODULE,
|
||||
};
|
||||
|
||||
static irqreturn_t sun4i_gpadc_temp_data_irq_handler(int irq, void *dev_id)
|
||||
{
|
||||
struct sun4i_gpadc_iio *info = dev_id;
|
||||
|
||||
if (atomic_read(&info->ignore_temp_data_irq))
|
||||
goto out;
|
||||
|
||||
if (!regmap_read(info->regmap, SUN4I_GPADC_TEMP_DATA, &info->temp_data))
|
||||
complete(&info->completion);
|
||||
|
||||
out:
|
||||
disable_irq_nosync(info->temp_data_irq);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static irqreturn_t sun4i_gpadc_fifo_data_irq_handler(int irq, void *dev_id)
|
||||
{
|
||||
struct sun4i_gpadc_iio *info = dev_id;
|
||||
|
||||
if (atomic_read(&info->ignore_fifo_data_irq))
|
||||
goto out;
|
||||
|
||||
if (!regmap_read(info->regmap, SUN4I_GPADC_DATA, &info->adc_data))
|
||||
complete(&info->completion);
|
||||
|
||||
out:
|
||||
disable_irq_nosync(info->fifo_data_irq);
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
static int sun4i_gpadc_runtime_suspend(struct device *dev)
|
||||
{
|
||||
struct sun4i_gpadc_iio *info = iio_priv(dev_get_drvdata(dev));
|
||||
|
||||
/* Disable the ADC on IP */
|
||||
regmap_write(info->regmap, SUN4I_GPADC_CTRL1, 0);
|
||||
/* Disable temperature sensor on IP */
|
||||
regmap_write(info->regmap, SUN4I_GPADC_TPR, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sun4i_gpadc_runtime_resume(struct device *dev)
|
||||
{
|
||||
struct sun4i_gpadc_iio *info = iio_priv(dev_get_drvdata(dev));
|
||||
|
||||
/* clkin = 6MHz */
|
||||
regmap_write(info->regmap, SUN4I_GPADC_CTRL0,
|
||||
SUN4I_GPADC_CTRL0_ADC_CLK_DIVIDER(2) |
|
||||
SUN4I_GPADC_CTRL0_FS_DIV(7) |
|
||||
SUN4I_GPADC_CTRL0_T_ACQ(63));
|
||||
regmap_write(info->regmap, SUN4I_GPADC_CTRL1, info->data->tp_mode_en);
|
||||
regmap_write(info->regmap, SUN4I_GPADC_CTRL3,
|
||||
SUN4I_GPADC_CTRL3_FILTER_EN |
|
||||
SUN4I_GPADC_CTRL3_FILTER_TYPE(1));
|
||||
/* period = SUN4I_GPADC_TPR_TEMP_PERIOD * 256 * 16 / clkin; ~0.6s */
|
||||
regmap_write(info->regmap, SUN4I_GPADC_TPR,
|
||||
SUN4I_GPADC_TPR_TEMP_ENABLE |
|
||||
SUN4I_GPADC_TPR_TEMP_PERIOD(800));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sun4i_gpadc_get_temp(void *data, int *temp)
|
||||
{
|
||||
struct sun4i_gpadc_iio *info = (struct sun4i_gpadc_iio *)data;
|
||||
int val, scale, offset;
|
||||
|
||||
if (sun4i_gpadc_temp_read(info->indio_dev, &val))
|
||||
return -ETIMEDOUT;
|
||||
|
||||
sun4i_gpadc_temp_scale(info->indio_dev, &scale);
|
||||
sun4i_gpadc_temp_offset(info->indio_dev, &offset);
|
||||
|
||||
*temp = (val + offset) * scale;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct thermal_zone_of_device_ops sun4i_ts_tz_ops = {
|
||||
.get_temp = &sun4i_gpadc_get_temp,
|
||||
};
|
||||
|
||||
static const struct dev_pm_ops sun4i_gpadc_pm_ops = {
|
||||
.runtime_suspend = &sun4i_gpadc_runtime_suspend,
|
||||
.runtime_resume = &sun4i_gpadc_runtime_resume,
|
||||
};
|
||||
|
||||
static int sun4i_irq_init(struct platform_device *pdev, const char *name,
|
||||
irq_handler_t handler, const char *devname,
|
||||
unsigned int *irq, atomic_t *atomic)
|
||||
{
|
||||
int ret;
|
||||
struct sun4i_gpadc_dev *mfd_dev = dev_get_drvdata(pdev->dev.parent);
|
||||
struct sun4i_gpadc_iio *info = iio_priv(dev_get_drvdata(&pdev->dev));
|
||||
|
||||
/*
|
||||
* Once the interrupt is activated, the IP continuously performs
|
||||
* conversions thus throws interrupts. The interrupt is activated right
|
||||
* after being requested but we want to control when these interrupts
|
||||
* occur thus we disable it right after being requested. However, an
|
||||
* interrupt might occur between these two instructions and we have to
|
||||
* make sure that does not happen, by using atomic flags. We set the
|
||||
* flag before requesting the interrupt and unset it right after
|
||||
* disabling the interrupt. When an interrupt occurs between these two
|
||||
* instructions, reading the atomic flag will tell us to ignore the
|
||||
* interrupt.
|
||||
*/
|
||||
atomic_set(atomic, 1);
|
||||
|
||||
ret = platform_get_irq_byname(pdev, name);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "no %s interrupt registered\n", name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = regmap_irq_get_virq(mfd_dev->regmap_irqc, ret);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "failed to get virq for irq %s\n", name);
|
||||
return ret;
|
||||
}
|
||||
|
||||
*irq = ret;
|
||||
ret = devm_request_any_context_irq(&pdev->dev, *irq, handler, 0,
|
||||
devname, info);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "could not request %s interrupt: %d\n",
|
||||
name, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
disable_irq(*irq);
|
||||
atomic_set(atomic, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sun4i_gpadc_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct sun4i_gpadc_iio *info;
|
||||
struct iio_dev *indio_dev;
|
||||
int ret;
|
||||
struct sun4i_gpadc_dev *sun4i_gpadc_dev;
|
||||
|
||||
sun4i_gpadc_dev = dev_get_drvdata(pdev->dev.parent);
|
||||
|
||||
indio_dev = devm_iio_device_alloc(&pdev->dev, sizeof(*info));
|
||||
if (!indio_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
info = iio_priv(indio_dev);
|
||||
platform_set_drvdata(pdev, indio_dev);
|
||||
|
||||
mutex_init(&info->mutex);
|
||||
info->regmap = sun4i_gpadc_dev->regmap;
|
||||
info->indio_dev = indio_dev;
|
||||
init_completion(&info->completion);
|
||||
indio_dev->name = dev_name(&pdev->dev);
|
||||
indio_dev->dev.parent = &pdev->dev;
|
||||
indio_dev->dev.of_node = pdev->dev.of_node;
|
||||
indio_dev->info = &sun4i_gpadc_iio_info;
|
||||
indio_dev->modes = INDIO_DIRECT_MODE;
|
||||
indio_dev->num_channels = ARRAY_SIZE(sun4i_gpadc_channels);
|
||||
indio_dev->channels = sun4i_gpadc_channels;
|
||||
|
||||
info->data = (struct gpadc_data *)platform_get_device_id(pdev)->driver_data;
|
||||
|
||||
/*
|
||||
* Since the controller needs to be in touchscreen mode for its thermal
|
||||
* sensor to operate properly, and that switching between the two modes
|
||||
* needs a delay, always registering in the thermal framework will
|
||||
* significantly slow down the conversion rate of the ADCs.
|
||||
*
|
||||
* Therefore, instead of depending on THERMAL_OF in Kconfig, we only
|
||||
* register the sensor if that option is enabled, eventually leaving
|
||||
* that choice to the user.
|
||||
*/
|
||||
|
||||
if (IS_ENABLED(CONFIG_THERMAL_OF)) {
|
||||
/*
|
||||
* This driver is a child of an MFD which has a node in the DT
|
||||
* but not its children, because of DT backward compatibility
|
||||
* for A10, A13 and A31 SoCs. Therefore, the resulting devices
|
||||
* of this driver do not have an of_node variable.
|
||||
* However, its parent (the MFD driver) has an of_node variable
|
||||
* and since devm_thermal_zone_of_sensor_register uses its first
|
||||
* argument to match the phandle defined in the node of the
|
||||
* thermal driver with the of_node of the device passed as first
|
||||
* argument and the third argument to call ops from
|
||||
* thermal_zone_of_device_ops, the solution is to use the parent
|
||||
* device as first argument to match the phandle with its
|
||||
* of_node, and the device from this driver as third argument to
|
||||
* return the temperature.
|
||||
*/
|
||||
struct thermal_zone_device *tzd;
|
||||
tzd = devm_thermal_zone_of_sensor_register(pdev->dev.parent, 0,
|
||||
info,
|
||||
&sun4i_ts_tz_ops);
|
||||
if (IS_ERR(tzd)) {
|
||||
dev_err(&pdev->dev,
|
||||
"could not register thermal sensor: %ld\n",
|
||||
PTR_ERR(tzd));
|
||||
ret = PTR_ERR(tzd);
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
indio_dev->num_channels =
|
||||
ARRAY_SIZE(sun4i_gpadc_channels_no_temp);
|
||||
indio_dev->channels = sun4i_gpadc_channels_no_temp;
|
||||
}
|
||||
|
||||
pm_runtime_set_autosuspend_delay(&pdev->dev,
|
||||
SUN4I_GPADC_AUTOSUSPEND_DELAY);
|
||||
pm_runtime_use_autosuspend(&pdev->dev);
|
||||
pm_runtime_set_suspended(&pdev->dev);
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
|
||||
if (IS_ENABLED(CONFIG_THERMAL_OF)) {
|
||||
ret = sun4i_irq_init(pdev, "TEMP_DATA_PENDING",
|
||||
sun4i_gpadc_temp_data_irq_handler,
|
||||
"temp_data", &info->temp_data_irq,
|
||||
&info->ignore_temp_data_irq);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = sun4i_irq_init(pdev, "FIFO_DATA_PENDING",
|
||||
sun4i_gpadc_fifo_data_irq_handler, "fifo_data",
|
||||
&info->fifo_data_irq, &info->ignore_fifo_data_irq);
|
||||
if (ret < 0)
|
||||
goto err;
|
||||
|
||||
if (IS_ENABLED(CONFIG_THERMAL_OF)) {
|
||||
ret = iio_map_array_register(indio_dev, sun4i_gpadc_hwmon_maps);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev,
|
||||
"failed to register iio map array\n");
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
ret = devm_iio_device_register(&pdev->dev, indio_dev);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "could not register the device\n");
|
||||
goto err_map;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err_map:
|
||||
if (IS_ENABLED(CONFIG_THERMAL_OF))
|
||||
iio_map_array_unregister(indio_dev);
|
||||
|
||||
err:
|
||||
pm_runtime_put(&pdev->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int sun4i_gpadc_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct iio_dev *indio_dev = platform_get_drvdata(pdev);
|
||||
|
||||
pm_runtime_put(&pdev->dev);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
if (IS_ENABLED(CONFIG_THERMAL_OF))
|
||||
iio_map_array_unregister(indio_dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct platform_device_id sun4i_gpadc_id[] = {
|
||||
{ "sun4i-a10-gpadc-iio", (kernel_ulong_t)&sun4i_gpadc_data },
|
||||
{ "sun5i-a13-gpadc-iio", (kernel_ulong_t)&sun5i_gpadc_data },
|
||||
{ "sun6i-a31-gpadc-iio", (kernel_ulong_t)&sun6i_gpadc_data },
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
|
||||
static struct platform_driver sun4i_gpadc_driver = {
|
||||
.driver = {
|
||||
.name = "sun4i-gpadc-iio",
|
||||
.pm = &sun4i_gpadc_pm_ops,
|
||||
},
|
||||
.id_table = sun4i_gpadc_id,
|
||||
.probe = sun4i_gpadc_probe,
|
||||
.remove = sun4i_gpadc_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(sun4i_gpadc_driver);
|
||||
|
||||
MODULE_DESCRIPTION("ADC driver for sunxi platforms");
|
||||
MODULE_AUTHOR("Quentin Schulz <quentin.schulz@free-electrons.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -15,6 +15,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/regmap.h>
|
||||
@ -55,7 +56,7 @@
|
||||
#define ADS1015_DEFAULT_DATA_RATE 4
|
||||
#define ADS1015_DEFAULT_CHAN 0
|
||||
|
||||
enum {
|
||||
enum chip_ids {
|
||||
ADS1015,
|
||||
ADS1115,
|
||||
};
|
||||
@ -578,6 +579,7 @@ static int ads1015_probe(struct i2c_client *client,
|
||||
struct iio_dev *indio_dev;
|
||||
struct ads1015_data *data;
|
||||
int ret;
|
||||
enum chip_ids chip;
|
||||
|
||||
indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
|
||||
if (!indio_dev)
|
||||
@ -593,7 +595,11 @@ static int ads1015_probe(struct i2c_client *client,
|
||||
indio_dev->name = ADS1015_DRV_NAME;
|
||||
indio_dev->modes = INDIO_DIRECT_MODE;
|
||||
|
||||
switch (id->driver_data) {
|
||||
if (client->dev.of_node)
|
||||
chip = (enum chip_ids)of_device_get_match_data(&client->dev);
|
||||
else
|
||||
chip = id->driver_data;
|
||||
switch (chip) {
|
||||
case ADS1015:
|
||||
indio_dev->channels = ads1015_channels;
|
||||
indio_dev->num_channels = ARRAY_SIZE(ads1015_channels);
|
||||
@ -698,9 +704,23 @@ static const struct i2c_device_id ads1015_id[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, ads1015_id);
|
||||
|
||||
static const struct of_device_id ads1015_of_match[] = {
|
||||
{
|
||||
.compatible = "ti,ads1015",
|
||||
.data = (void *)ADS1015
|
||||
},
|
||||
{
|
||||
.compatible = "ti,ads1115",
|
||||
.data = (void *)ADS1115
|
||||
},
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ads1015_of_match);
|
||||
|
||||
static struct i2c_driver ads1015_driver = {
|
||||
.driver = {
|
||||
.name = ADS1015_DRV_NAME,
|
||||
.of_match_table = ads1015_of_match,
|
||||
.pm = &ads1015_pm_ops,
|
||||
},
|
||||
.probe = ads1015_probe,
|
||||
|
@ -7,7 +7,7 @@ menu "Counters"
|
||||
|
||||
config 104_QUAD_8
|
||||
tristate "ACCES 104-QUAD-8 driver"
|
||||
depends on X86 && ISA_BUS_API
|
||||
depends on PC104 && X86 && ISA_BUS_API
|
||||
help
|
||||
Say yes here to build support for the ACCES 104-QUAD-8 quadrature
|
||||
encoder counter/interface device family (104-QUAD-8, 104-QUAD-4).
|
||||
|
@ -118,6 +118,16 @@ config AD5624R_SPI
|
||||
Say yes here to build support for Analog Devices AD5624R, AD5644R and
|
||||
AD5664R converters (DAC). This driver uses the common SPI interface.
|
||||
|
||||
config LTC2632
|
||||
tristate "Linear Technology LTC2632-12/10/8 DAC spi driver"
|
||||
depends on SPI
|
||||
help
|
||||
Say yes here to build support for Linear Technology
|
||||
LTC2632-12, LTC2632-10, LTC2632-8 converters (DAC).
|
||||
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called ltc2632.
|
||||
|
||||
config AD5686
|
||||
tristate "Analog Devices AD5686R/AD5685R/AD5684R DAC SPI driver"
|
||||
depends on SPI
|
||||
|
@ -24,6 +24,7 @@ obj-$(CONFIG_AD8801) += ad8801.o
|
||||
obj-$(CONFIG_CIO_DAC) += cio-dac.o
|
||||
obj-$(CONFIG_DPOT_DAC) += dpot-dac.o
|
||||
obj-$(CONFIG_LPC18XX_DAC) += lpc18xx_dac.o
|
||||
obj-$(CONFIG_LTC2632) += ltc2632.o
|
||||
obj-$(CONFIG_M62332) += m62332.o
|
||||
obj-$(CONFIG_MAX517) += max517.o
|
||||
obj-$(CONFIG_MAX5821) += max5821.o
|
||||
|
314
drivers/iio/dac/ltc2632.c
Normal file
314
drivers/iio/dac/ltc2632.c
Normal file
@ -0,0 +1,314 @@
|
||||
/*
|
||||
* LTC2632 Digital to analog convertors spi driver
|
||||
*
|
||||
* Copyright 2017 Maxime Roussin-Bélanger
|
||||
*
|
||||
* Licensed under the GPL-2.
|
||||
*/
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/iio/iio.h>
|
||||
|
||||
#define LTC2632_DAC_CHANNELS 2
|
||||
|
||||
#define LTC2632_ADDR_DAC0 0x0
|
||||
#define LTC2632_ADDR_DAC1 0x1
|
||||
|
||||
#define LTC2632_CMD_WRITE_INPUT_N 0x0
|
||||
#define LTC2632_CMD_UPDATE_DAC_N 0x1
|
||||
#define LTC2632_CMD_WRITE_INPUT_N_UPDATE_ALL 0x2
|
||||
#define LTC2632_CMD_WRITE_INPUT_N_UPDATE_N 0x3
|
||||
#define LTC2632_CMD_POWERDOWN_DAC_N 0x4
|
||||
#define LTC2632_CMD_POWERDOWN_CHIP 0x5
|
||||
#define LTC2632_CMD_INTERNAL_REFER 0x6
|
||||
#define LTC2632_CMD_EXTERNAL_REFER 0x7
|
||||
|
||||
/**
|
||||
* struct ltc2632_chip_info - chip specific information
|
||||
* @channels: channel spec for the DAC
|
||||
* @vref_mv: reference voltage
|
||||
*/
|
||||
struct ltc2632_chip_info {
|
||||
const struct iio_chan_spec *channels;
|
||||
const int vref_mv;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ltc2632_state - driver instance specific data
|
||||
* @spi_dev: pointer to the spi_device struct
|
||||
* @powerdown_cache_mask used to show current channel powerdown state
|
||||
*/
|
||||
struct ltc2632_state {
|
||||
struct spi_device *spi_dev;
|
||||
unsigned int powerdown_cache_mask;
|
||||
};
|
||||
|
||||
enum ltc2632_supported_device_ids {
|
||||
ID_LTC2632L12,
|
||||
ID_LTC2632L10,
|
||||
ID_LTC2632L8,
|
||||
ID_LTC2632H12,
|
||||
ID_LTC2632H10,
|
||||
ID_LTC2632H8,
|
||||
};
|
||||
|
||||
static int ltc2632_spi_write(struct spi_device *spi,
|
||||
u8 cmd, u8 addr, u16 val, u8 shift)
|
||||
{
|
||||
u32 data;
|
||||
u8 msg[3];
|
||||
|
||||
/*
|
||||
* The input shift register is 24 bits wide.
|
||||
* The next four are the command bits, C3 to C0,
|
||||
* followed by the 4-bit DAC address, A3 to A0, and then the
|
||||
* 12-, 10-, 8-bit data-word. The data-word comprises the 12-,
|
||||
* 10-, 8-bit input code followed by 4, 6, or 8 don't care bits.
|
||||
*/
|
||||
data = (cmd << 20) | (addr << 16) | (val << shift);
|
||||
msg[0] = data >> 16;
|
||||
msg[1] = data >> 8;
|
||||
msg[2] = data;
|
||||
|
||||
return spi_write(spi, msg, sizeof(msg));
|
||||
}
|
||||
|
||||
static int ltc2632_read_raw(struct iio_dev *indio_dev,
|
||||
struct iio_chan_spec const *chan,
|
||||
int *val,
|
||||
int *val2,
|
||||
long m)
|
||||
{
|
||||
struct ltc2632_chip_info *chip_info;
|
||||
|
||||
const struct ltc2632_state *st = iio_priv(indio_dev);
|
||||
const struct spi_device_id *spi_dev_id = spi_get_device_id(st->spi_dev);
|
||||
|
||||
chip_info = (struct ltc2632_chip_info *)spi_dev_id->driver_data;
|
||||
|
||||
switch (m) {
|
||||
case IIO_CHAN_INFO_SCALE:
|
||||
*val = chip_info->vref_mv;
|
||||
*val2 = chan->scan_type.realbits;
|
||||
return IIO_VAL_FRACTIONAL_LOG2;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static int ltc2632_write_raw(struct iio_dev *indio_dev,
|
||||
struct iio_chan_spec const *chan,
|
||||
int val,
|
||||
int val2,
|
||||
long mask)
|
||||
{
|
||||
struct ltc2632_state *st = iio_priv(indio_dev);
|
||||
|
||||
switch (mask) {
|
||||
case IIO_CHAN_INFO_RAW:
|
||||
if (val >= (1 << chan->scan_type.realbits) || val < 0)
|
||||
return -EINVAL;
|
||||
|
||||
return ltc2632_spi_write(st->spi_dev,
|
||||
LTC2632_CMD_WRITE_INPUT_N_UPDATE_N,
|
||||
chan->address, val,
|
||||
chan->scan_type.shift);
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
static ssize_t ltc2632_read_dac_powerdown(struct iio_dev *indio_dev,
|
||||
uintptr_t private,
|
||||
const struct iio_chan_spec *chan,
|
||||
char *buf)
|
||||
{
|
||||
struct ltc2632_state *st = iio_priv(indio_dev);
|
||||
|
||||
return sprintf(buf, "%d\n",
|
||||
!!(st->powerdown_cache_mask & (1 << chan->channel)));
|
||||
}
|
||||
|
||||
static ssize_t ltc2632_write_dac_powerdown(struct iio_dev *indio_dev,
|
||||
uintptr_t private,
|
||||
const struct iio_chan_spec *chan,
|
||||
const char *buf,
|
||||
size_t len)
|
||||
{
|
||||
bool pwr_down;
|
||||
int ret;
|
||||
struct ltc2632_state *st = iio_priv(indio_dev);
|
||||
|
||||
ret = strtobool(buf, &pwr_down);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (pwr_down)
|
||||
st->powerdown_cache_mask |= (1 << chan->channel);
|
||||
else
|
||||
st->powerdown_cache_mask &= ~(1 << chan->channel);
|
||||
|
||||
ret = ltc2632_spi_write(st->spi_dev,
|
||||
LTC2632_CMD_POWERDOWN_DAC_N,
|
||||
chan->channel, 0, 0);
|
||||
|
||||
return ret ? ret : len;
|
||||
}
|
||||
|
||||
static const struct iio_info ltc2632_info = {
|
||||
.write_raw = ltc2632_write_raw,
|
||||
.read_raw = ltc2632_read_raw,
|
||||
.driver_module = THIS_MODULE,
|
||||
};
|
||||
|
||||
static const struct iio_chan_spec_ext_info ltc2632_ext_info[] = {
|
||||
{
|
||||
.name = "powerdown",
|
||||
.read = ltc2632_read_dac_powerdown,
|
||||
.write = ltc2632_write_dac_powerdown,
|
||||
.shared = IIO_SEPARATE,
|
||||
},
|
||||
{ },
|
||||
};
|
||||
|
||||
#define LTC2632_CHANNEL(_chan, _bits) { \
|
||||
.type = IIO_VOLTAGE, \
|
||||
.indexed = 1, \
|
||||
.output = 1, \
|
||||
.channel = (_chan), \
|
||||
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
|
||||
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
|
||||
.address = (_chan), \
|
||||
.scan_type = { \
|
||||
.realbits = (_bits), \
|
||||
.shift = 16 - (_bits), \
|
||||
}, \
|
||||
.ext_info = ltc2632_ext_info, \
|
||||
}
|
||||
|
||||
#define DECLARE_LTC2632_CHANNELS(_name, _bits) \
|
||||
const struct iio_chan_spec _name ## _channels[] = { \
|
||||
LTC2632_CHANNEL(0, _bits), \
|
||||
LTC2632_CHANNEL(1, _bits), \
|
||||
}
|
||||
|
||||
static DECLARE_LTC2632_CHANNELS(ltc2632l12, 12);
|
||||
static DECLARE_LTC2632_CHANNELS(ltc2632l10, 10);
|
||||
static DECLARE_LTC2632_CHANNELS(ltc2632l8, 8);
|
||||
|
||||
static DECLARE_LTC2632_CHANNELS(ltc2632h12, 12);
|
||||
static DECLARE_LTC2632_CHANNELS(ltc2632h10, 10);
|
||||
static DECLARE_LTC2632_CHANNELS(ltc2632h8, 8);
|
||||
|
||||
static const struct ltc2632_chip_info ltc2632_chip_info_tbl[] = {
|
||||
[ID_LTC2632L12] = {
|
||||
.channels = ltc2632l12_channels,
|
||||
.vref_mv = 2500,
|
||||
},
|
||||
[ID_LTC2632L10] = {
|
||||
.channels = ltc2632l10_channels,
|
||||
.vref_mv = 2500,
|
||||
},
|
||||
[ID_LTC2632L8] = {
|
||||
.channels = ltc2632l8_channels,
|
||||
.vref_mv = 2500,
|
||||
},
|
||||
[ID_LTC2632H12] = {
|
||||
.channels = ltc2632h12_channels,
|
||||
.vref_mv = 4096,
|
||||
},
|
||||
[ID_LTC2632H10] = {
|
||||
.channels = ltc2632h10_channels,
|
||||
.vref_mv = 4096,
|
||||
},
|
||||
[ID_LTC2632H8] = {
|
||||
.channels = ltc2632h8_channels,
|
||||
.vref_mv = 4096,
|
||||
},
|
||||
};
|
||||
|
||||
static int ltc2632_probe(struct spi_device *spi)
|
||||
{
|
||||
struct ltc2632_state *st;
|
||||
struct iio_dev *indio_dev;
|
||||
struct ltc2632_chip_info *chip_info;
|
||||
int ret;
|
||||
|
||||
indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st));
|
||||
if (!indio_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
st = iio_priv(indio_dev);
|
||||
|
||||
spi_set_drvdata(spi, indio_dev);
|
||||
st->spi_dev = spi;
|
||||
|
||||
chip_info = (struct ltc2632_chip_info *)
|
||||
spi_get_device_id(spi)->driver_data;
|
||||
|
||||
indio_dev->dev.parent = &spi->dev;
|
||||
indio_dev->name = dev_of_node(&spi->dev) ? dev_of_node(&spi->dev)->name
|
||||
: spi_get_device_id(spi)->name;
|
||||
indio_dev->info = <c2632_info;
|
||||
indio_dev->modes = INDIO_DIRECT_MODE;
|
||||
indio_dev->channels = chip_info->channels;
|
||||
indio_dev->num_channels = LTC2632_DAC_CHANNELS;
|
||||
|
||||
ret = ltc2632_spi_write(spi, LTC2632_CMD_INTERNAL_REFER, 0, 0, 0);
|
||||
if (ret) {
|
||||
dev_err(&spi->dev,
|
||||
"Set internal reference command failed, %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return devm_iio_device_register(&spi->dev, indio_dev);
|
||||
}
|
||||
|
||||
static const struct spi_device_id ltc2632_id[] = {
|
||||
{ "ltc2632-l12", (kernel_ulong_t)<c2632_chip_info_tbl[ID_LTC2632L12] },
|
||||
{ "ltc2632-l10", (kernel_ulong_t)<c2632_chip_info_tbl[ID_LTC2632L10] },
|
||||
{ "ltc2632-l8", (kernel_ulong_t)<c2632_chip_info_tbl[ID_LTC2632L8] },
|
||||
{ "ltc2632-h12", (kernel_ulong_t)<c2632_chip_info_tbl[ID_LTC2632H12] },
|
||||
{ "ltc2632-h10", (kernel_ulong_t)<c2632_chip_info_tbl[ID_LTC2632H10] },
|
||||
{ "ltc2632-h8", (kernel_ulong_t)<c2632_chip_info_tbl[ID_LTC2632H8] },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(spi, ltc2632_id);
|
||||
|
||||
static struct spi_driver ltc2632_driver = {
|
||||
.driver = {
|
||||
.name = "ltc2632",
|
||||
},
|
||||
.probe = ltc2632_probe,
|
||||
.id_table = ltc2632_id,
|
||||
};
|
||||
module_spi_driver(ltc2632_driver);
|
||||
|
||||
static const struct of_device_id ltc2632_of_match[] = {
|
||||
{
|
||||
.compatible = "lltc,ltc2632-l12",
|
||||
.data = <c2632_chip_info_tbl[ID_LTC2632L12]
|
||||
}, {
|
||||
.compatible = "lltc,ltc2632-l10",
|
||||
.data = <c2632_chip_info_tbl[ID_LTC2632L10]
|
||||
}, {
|
||||
.compatible = "lltc,ltc2632-l8",
|
||||
.data = <c2632_chip_info_tbl[ID_LTC2632L8]
|
||||
}, {
|
||||
.compatible = "lltc,ltc2632-h12",
|
||||
.data = <c2632_chip_info_tbl[ID_LTC2632H12]
|
||||
}, {
|
||||
.compatible = "lltc,ltc2632-h10",
|
||||
.data = <c2632_chip_info_tbl[ID_LTC2632H10]
|
||||
}, {
|
||||
.compatible = "lltc,ltc2632-h8",
|
||||
.data = <c2632_chip_info_tbl[ID_LTC2632H8]
|
||||
},
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, ltc2632_of_match);
|
||||
|
||||
MODULE_AUTHOR("Maxime Roussin-Belanger <maxime.roussinbelanger@gmail.com>");
|
||||
MODULE_DESCRIPTION("LTC2632 DAC SPI driver");
|
||||
MODULE_LICENSE("GPL v2");
|
@ -392,6 +392,7 @@ MODULE_DEVICE_TABLE(of, max5821_of_match);
|
||||
static struct i2c_driver max5821_driver = {
|
||||
.driver = {
|
||||
.name = "max5821",
|
||||
.of_match_table = max5821_of_match,
|
||||
.pm = MAX5821_PM_OPS,
|
||||
},
|
||||
.probe = max5821_probe,
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <linux/err.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
#include <linux/iio/iio.h>
|
||||
@ -199,7 +200,7 @@ static ssize_t mcp4725_write_powerdown(struct iio_dev *indio_dev,
|
||||
return len;
|
||||
}
|
||||
|
||||
enum {
|
||||
enum chip_id {
|
||||
MCP4725,
|
||||
MCP4726,
|
||||
};
|
||||
@ -406,7 +407,10 @@ static int mcp4725_probe(struct i2c_client *client,
|
||||
data = iio_priv(indio_dev);
|
||||
i2c_set_clientdata(client, indio_dev);
|
||||
data->client = client;
|
||||
data->id = id->driver_data;
|
||||
if (client->dev.of_node)
|
||||
data->id = (enum chip_id)of_device_get_match_data(&client->dev);
|
||||
else
|
||||
data->id = id->driver_data;
|
||||
pdata = dev_get_platdata(&client->dev);
|
||||
|
||||
if (!pdata) {
|
||||
@ -525,9 +529,25 @@ static const struct i2c_device_id mcp4725_id[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, mcp4725_id);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id mcp4725_of_match[] = {
|
||||
{
|
||||
.compatible = "microchip,mcp4725",
|
||||
.data = (void *)MCP4725
|
||||
},
|
||||
{
|
||||
.compatible = "microchip,mcp4726",
|
||||
.data = (void *)MCP4726
|
||||
},
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mcp4725_of_match);
|
||||
#endif
|
||||
|
||||
static struct i2c_driver mcp4725_driver = {
|
||||
.driver = {
|
||||
.name = MCP4725_DRV_NAME,
|
||||
.of_match_table = of_match_ptr(mcp4725_of_match),
|
||||
.pm = MCP4725_PM_OPS,
|
||||
},
|
||||
.probe = mcp4725_probe,
|
||||
|
@ -377,9 +377,16 @@ static const struct i2c_device_id itg3200_id[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, itg3200_id);
|
||||
|
||||
static const struct of_device_id itg3200_of_match[] = {
|
||||
{ .compatible = "invensense,itg3200" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, itg3200_of_match);
|
||||
|
||||
static struct i2c_driver itg3200_driver = {
|
||||
.driver = {
|
||||
.name = "itg3200",
|
||||
.of_match_table = itg3200_of_match,
|
||||
.pm = &itg3200_pm_ops,
|
||||
},
|
||||
.id_table = itg3200_id,
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/iio/iio.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include "inv_mpu_iio.h"
|
||||
|
||||
static const struct regmap_config inv_mpu_regmap_config = {
|
||||
@ -69,7 +70,8 @@ static int inv_mpu6050_deselect_bypass(struct i2c_mux_core *muxc, u32 chan_id)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *inv_mpu_match_acpi_device(struct device *dev, int *chip_id)
|
||||
static const char *inv_mpu_match_acpi_device(struct device *dev,
|
||||
enum inv_devices *chip_id)
|
||||
{
|
||||
const struct acpi_device_id *id;
|
||||
|
||||
@ -93,7 +95,8 @@ static int inv_mpu_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct inv_mpu6050_state *st;
|
||||
int result, chip_type;
|
||||
int result;
|
||||
enum inv_devices chip_type;
|
||||
struct regmap *regmap;
|
||||
const char *name;
|
||||
|
||||
@ -101,8 +104,13 @@ static int inv_mpu_probe(struct i2c_client *client,
|
||||
I2C_FUNC_SMBUS_I2C_BLOCK))
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (id) {
|
||||
chip_type = (int)id->driver_data;
|
||||
if (client->dev.of_node) {
|
||||
chip_type = (enum inv_devices)
|
||||
of_device_get_match_data(&client->dev);
|
||||
name = client->name;
|
||||
} else if (id) {
|
||||
chip_type = (enum inv_devices)
|
||||
id->driver_data;
|
||||
name = id->name;
|
||||
} else if (ACPI_HANDLE(&client->dev)) {
|
||||
name = inv_mpu_match_acpi_device(&client->dev, &chip_type);
|
||||
@ -176,6 +184,27 @@ static const struct i2c_device_id inv_mpu_id[] = {
|
||||
|
||||
MODULE_DEVICE_TABLE(i2c, inv_mpu_id);
|
||||
|
||||
static const struct of_device_id inv_of_match[] = {
|
||||
{
|
||||
.compatible = "invensense,mpu6050",
|
||||
.data = (void *)INV_MPU6050
|
||||
},
|
||||
{
|
||||
.compatible = "invensense,mpu6500",
|
||||
.data = (void *)INV_MPU6500
|
||||
},
|
||||
{
|
||||
.compatible = "invensense,mpu9150",
|
||||
.data = (void *)INV_MPU9150
|
||||
},
|
||||
{
|
||||
.compatible = "invensense,icm20608",
|
||||
.data = (void *)INV_ICM20608
|
||||
},
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, inv_of_match);
|
||||
|
||||
static const struct acpi_device_id inv_acpi_match[] = {
|
||||
{"INVN6500", INV_MPU6500},
|
||||
{ },
|
||||
@ -188,6 +217,7 @@ static struct i2c_driver inv_mpu_driver = {
|
||||
.remove = inv_mpu_remove,
|
||||
.id_table = inv_mpu_id,
|
||||
.driver = {
|
||||
.of_match_table = inv_of_match,
|
||||
.acpi_match_table = ACPI_PTR(inv_acpi_match),
|
||||
.name = "inv-mpu6050-i2c",
|
||||
.pm = &inv_mpu_pmops,
|
||||
|
@ -1122,9 +1122,16 @@ static const struct i2c_device_id apds9960_id[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, apds9960_id);
|
||||
|
||||
static const struct of_device_id apds9960_of_match[] = {
|
||||
{ .compatible = "avago,apds9960" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, apds9960_of_match);
|
||||
|
||||
static struct i2c_driver apds9960_driver = {
|
||||
.driver = {
|
||||
.name = APDS9960_DRV_NAME,
|
||||
.of_match_table = apds9960_of_match,
|
||||
.pm = &apds9960_pm_ops,
|
||||
},
|
||||
.probe = apds9960_probe,
|
||||
|
@ -884,9 +884,19 @@ static const struct i2c_device_id tsl2563_id[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, tsl2563_id);
|
||||
|
||||
static const struct of_device_id tsl2563_of_match[] = {
|
||||
{ .compatible = "amstaos,tsl2560" },
|
||||
{ .compatible = "amstaos,tsl2561" },
|
||||
{ .compatible = "amstaos,tsl2562" },
|
||||
{ .compatible = "amstaos,tsl2563" },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, tsl2563_of_match);
|
||||
|
||||
static struct i2c_driver tsl2563_i2c_driver = {
|
||||
.driver = {
|
||||
.name = "tsl2563",
|
||||
.of_match_table = tsl2563_of_match,
|
||||
.pm = TSL2563_PM_OPS,
|
||||
},
|
||||
.probe = tsl2563_probe,
|
||||
|
@ -972,10 +972,17 @@ static const struct i2c_device_id us5182d_id[] = {
|
||||
|
||||
MODULE_DEVICE_TABLE(i2c, us5182d_id);
|
||||
|
||||
static const struct of_device_id us5182d_of_match[] = {
|
||||
{ .compatible = "upisemi,usd5182" },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, us5182d_of_match);
|
||||
|
||||
static struct i2c_driver us5182d_driver = {
|
||||
.driver = {
|
||||
.name = US5182D_DRV_NAME,
|
||||
.pm = &us5182d_pm_ops,
|
||||
.of_match_table = us5182d_of_match,
|
||||
.acpi_match_table = ACPI_PTR(us5182d_acpi_match),
|
||||
},
|
||||
.probe = us5182d_probe,
|
||||
|
@ -63,9 +63,18 @@ static const struct i2c_device_id bmc150_magn_i2c_id[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, bmc150_magn_i2c_id);
|
||||
|
||||
static const struct of_device_id bmc150_magn_of_match[] = {
|
||||
{ .compatible = "bosch,bmc150_magn" },
|
||||
{ .compatible = "bosch,bmc156_magn" },
|
||||
{ .compatible = "bosch,bmm150_magn" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, bmc150_magn_of_match);
|
||||
|
||||
static struct i2c_driver bmc150_magn_driver = {
|
||||
.driver = {
|
||||
.name = "bmc150_magn_i2c",
|
||||
.of_match_table = bmc150_magn_of_match,
|
||||
.acpi_match_table = ACPI_PTR(bmc150_magn_acpi_match),
|
||||
.pm = &bmc150_magn_pm_ops,
|
||||
},
|
||||
|
@ -441,9 +441,16 @@ static const struct i2c_device_id mag3110_id[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, mag3110_id);
|
||||
|
||||
static const struct of_device_id mag3110_of_match[] = {
|
||||
{ .compatible = "fsl,mag3110" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mag3110_of_match);
|
||||
|
||||
static struct i2c_driver mag3110_driver = {
|
||||
.driver = {
|
||||
.name = "mag3110",
|
||||
.of_match_table = mag3110_of_match,
|
||||
.pm = MAG3110_PM_OPS,
|
||||
},
|
||||
.probe = mag3110_probe,
|
||||
|
@ -297,9 +297,16 @@ static const struct i2c_device_id hp03_id[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, hp03_id);
|
||||
|
||||
static const struct of_device_id hp03_of_match[] = {
|
||||
{ .compatible = "hoperf,hp03" },
|
||||
{ },
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, hp03_of_match);
|
||||
|
||||
static struct i2c_driver hp03_driver = {
|
||||
.driver = {
|
||||
.name = "hp03",
|
||||
.of_match_table = hp03_of_match,
|
||||
},
|
||||
.probe = hp03_probe,
|
||||
.remove = hp03_remove,
|
||||
|
@ -321,9 +321,16 @@ static const struct i2c_device_id mpl3115_id[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, mpl3115_id);
|
||||
|
||||
static const struct of_device_id mpl3115_of_match[] = {
|
||||
{ .compatible = "fsl,mpl3115" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mpl3115_of_match);
|
||||
|
||||
static struct i2c_driver mpl3115_driver = {
|
||||
.driver = {
|
||||
.name = "mpl3115",
|
||||
.of_match_table = mpl3115_of_match,
|
||||
.pm = MPL3115_PM_OPS,
|
||||
},
|
||||
.probe = mpl3115_probe,
|
||||
|
@ -585,6 +585,12 @@ static const struct i2c_device_id mlx90614_id[] = {
|
||||
};
|
||||
MODULE_DEVICE_TABLE(i2c, mlx90614_id);
|
||||
|
||||
static const struct of_device_id mlx90614_of_match[] = {
|
||||
{ .compatible = "melexis,mlx90614" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, mlx90614_of_match);
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int mlx90614_pm_suspend(struct device *dev)
|
||||
{
|
||||
@ -644,6 +650,7 @@ static const struct dev_pm_ops mlx90614_pm_ops = {
|
||||
static struct i2c_driver mlx90614_driver = {
|
||||
.driver = {
|
||||
.name = "mlx90614",
|
||||
.of_match_table = mlx90614_of_match,
|
||||
.pm = &mlx90614_pm_ops,
|
||||
},
|
||||
.probe = mlx90614_probe,
|
||||
|
@ -223,17 +223,13 @@ static int adis16201_read_raw(struct iio_dev *indio_dev,
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
mutex_lock(&indio_dev->mlock);
|
||||
addr = adis16201_addresses[chan->scan_index];
|
||||
ret = adis_read_reg_16(st, addr, &val16);
|
||||
if (ret) {
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
val16 &= (1 << bits) - 1;
|
||||
val16 = (s16)(val16 << (16 - bits)) >> (16 - bits);
|
||||
*val = val16;
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
return IIO_VAL_INT;
|
||||
}
|
||||
return -EINVAL;
|
||||
@ -285,8 +281,8 @@ static const struct iio_chan_spec adis16201_channels[] = {
|
||||
};
|
||||
|
||||
static const struct iio_info adis16201_info = {
|
||||
.read_raw = &adis16201_read_raw,
|
||||
.write_raw = &adis16201_write_raw,
|
||||
.read_raw = adis16201_read_raw,
|
||||
.write_raw = adis16201_write_raw,
|
||||
.update_scan_mode = adis_update_scan_mode,
|
||||
.driver_module = THIS_MODULE,
|
||||
};
|
||||
|
@ -233,8 +233,8 @@ static const struct iio_chan_spec adis16203_channels[] = {
|
||||
};
|
||||
|
||||
static const struct iio_info adis16203_info = {
|
||||
.read_raw = &adis16203_read_raw,
|
||||
.write_raw = &adis16203_write_raw,
|
||||
.read_raw = adis16203_read_raw,
|
||||
.write_raw = adis16203_write_raw,
|
||||
.update_scan_mode = adis_update_scan_mode,
|
||||
.driver_module = THIS_MODULE,
|
||||
};
|
||||
|
@ -7,7 +7,6 @@
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/spi/spi.h>
|
||||
@ -152,14 +151,16 @@
|
||||
|
||||
#define ADIS16209_ERROR_ACTIVE BIT(14)
|
||||
|
||||
#define ADIS16209_SCAN_SUPPLY 0
|
||||
#define ADIS16209_SCAN_ACC_X 1
|
||||
#define ADIS16209_SCAN_ACC_Y 2
|
||||
#define ADIS16209_SCAN_AUX_ADC 3
|
||||
#define ADIS16209_SCAN_TEMP 4
|
||||
#define ADIS16209_SCAN_INCLI_X 5
|
||||
#define ADIS16209_SCAN_INCLI_Y 6
|
||||
#define ADIS16209_SCAN_ROT 7
|
||||
enum adis16209_scan {
|
||||
ADIS16209_SCAN_SUPPLY,
|
||||
ADIS16209_SCAN_ACC_X,
|
||||
ADIS16209_SCAN_ACC_Y,
|
||||
ADIS16209_SCAN_AUX_ADC,
|
||||
ADIS16209_SCAN_TEMP,
|
||||
ADIS16209_SCAN_INCLI_X,
|
||||
ADIS16209_SCAN_INCLI_Y,
|
||||
ADIS16209_SCAN_ROT,
|
||||
};
|
||||
|
||||
static const u8 adis16209_addresses[8][1] = {
|
||||
[ADIS16209_SCAN_SUPPLY] = { },
|
||||
@ -252,17 +253,14 @@ static int adis16209_read_raw(struct iio_dev *indio_dev,
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
mutex_lock(&indio_dev->mlock);
|
||||
addr = adis16209_addresses[chan->scan_index][0];
|
||||
ret = adis_read_reg_16(st, addr, &val16);
|
||||
if (ret) {
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
return ret;
|
||||
}
|
||||
val16 &= (1 << bits) - 1;
|
||||
val16 = (s16)(val16 << (16 - bits)) >> (16 - bits);
|
||||
*val = val16;
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
return IIO_VAL_INT;
|
||||
}
|
||||
return -EINVAL;
|
||||
@ -285,8 +283,8 @@ static const struct iio_chan_spec adis16209_channels[] = {
|
||||
};
|
||||
|
||||
static const struct iio_info adis16209_info = {
|
||||
.read_raw = &adis16209_read_raw,
|
||||
.write_raw = &adis16209_write_raw,
|
||||
.read_raw = adis16209_read_raw,
|
||||
.write_raw = adis16209_write_raw,
|
||||
.update_scan_mode = adis_update_scan_mode,
|
||||
.driver_module = THIS_MODULE,
|
||||
};
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include <linux/irq.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/spi/spi.h>
|
||||
@ -192,12 +191,14 @@
|
||||
* filling. This may change!
|
||||
*/
|
||||
|
||||
#define ADIS16240_SCAN_ACC_X 0
|
||||
#define ADIS16240_SCAN_ACC_Y 1
|
||||
#define ADIS16240_SCAN_ACC_Z 2
|
||||
#define ADIS16240_SCAN_SUPPLY 3
|
||||
#define ADIS16240_SCAN_AUX_ADC 4
|
||||
#define ADIS16240_SCAN_TEMP 5
|
||||
enum adis16240_scan {
|
||||
ADIS16240_SCAN_ACC_X,
|
||||
ADIS16240_SCAN_ACC_Y,
|
||||
ADIS16240_SCAN_ACC_Z,
|
||||
ADIS16240_SCAN_SUPPLY,
|
||||
ADIS16240_SCAN_AUX_ADC,
|
||||
ADIS16240_SCAN_TEMP,
|
||||
};
|
||||
|
||||
static ssize_t adis16240_spi_read_signed(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
@ -227,15 +228,7 @@ static ssize_t adis16240_read_12bit_signed(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
ssize_t ret;
|
||||
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
||||
|
||||
/* Take the iio_dev status lock */
|
||||
mutex_lock(&indio_dev->mlock);
|
||||
ret = adis16240_spi_read_signed(dev, attr, buf, 12);
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
|
||||
return ret;
|
||||
return adis16240_spi_read_signed(dev, attr, buf, 12);
|
||||
}
|
||||
|
||||
static IIO_DEVICE_ATTR(in_accel_xyz_squared_peak_raw, 0444,
|
||||
@ -295,31 +288,25 @@ static int adis16240_read_raw(struct iio_dev *indio_dev,
|
||||
return IIO_VAL_INT;
|
||||
case IIO_CHAN_INFO_CALIBBIAS:
|
||||
bits = 10;
|
||||
mutex_lock(&indio_dev->mlock);
|
||||
addr = adis16240_addresses[chan->scan_index][0];
|
||||
ret = adis_read_reg_16(st, addr, &val16);
|
||||
if (ret) {
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
return ret;
|
||||
}
|
||||
val16 &= (1 << bits) - 1;
|
||||
val16 = (s16)(val16 << (16 - bits)) >> (16 - bits);
|
||||
*val = val16;
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
return IIO_VAL_INT;
|
||||
case IIO_CHAN_INFO_PEAK:
|
||||
bits = 10;
|
||||
mutex_lock(&indio_dev->mlock);
|
||||
addr = adis16240_addresses[chan->scan_index][1];
|
||||
ret = adis_read_reg_16(st, addr, &val16);
|
||||
if (ret) {
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
return ret;
|
||||
}
|
||||
val16 &= (1 << bits) - 1;
|
||||
val16 = (s16)(val16 << (16 - bits)) >> (16 - bits);
|
||||
*val = val16;
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
return IIO_VAL_INT;
|
||||
}
|
||||
return -EINVAL;
|
||||
@ -373,8 +360,8 @@ static const struct attribute_group adis16240_attribute_group = {
|
||||
|
||||
static const struct iio_info adis16240_info = {
|
||||
.attrs = &adis16240_attribute_group,
|
||||
.read_raw = &adis16240_read_raw,
|
||||
.write_raw = &adis16240_write_raw,
|
||||
.read_raw = adis16240_read_raw,
|
||||
.write_raw = adis16240_write_raw,
|
||||
.update_scan_mode = adis_update_scan_mode,
|
||||
.driver_module = THIS_MODULE,
|
||||
};
|
||||
|
@ -564,18 +564,18 @@ static int ad7192_write_raw_get_fmt(struct iio_dev *indio_dev,
|
||||
}
|
||||
|
||||
static const struct iio_info ad7192_info = {
|
||||
.read_raw = &ad7192_read_raw,
|
||||
.write_raw = &ad7192_write_raw,
|
||||
.write_raw_get_fmt = &ad7192_write_raw_get_fmt,
|
||||
.read_raw = ad7192_read_raw,
|
||||
.write_raw = ad7192_write_raw,
|
||||
.write_raw_get_fmt = ad7192_write_raw_get_fmt,
|
||||
.attrs = &ad7192_attribute_group,
|
||||
.validate_trigger = ad_sd_validate_trigger,
|
||||
.driver_module = THIS_MODULE,
|
||||
};
|
||||
|
||||
static const struct iio_info ad7195_info = {
|
||||
.read_raw = &ad7192_read_raw,
|
||||
.write_raw = &ad7192_write_raw,
|
||||
.write_raw_get_fmt = &ad7192_write_raw_get_fmt,
|
||||
.read_raw = ad7192_read_raw,
|
||||
.write_raw = ad7192_write_raw,
|
||||
.write_raw_get_fmt = ad7192_write_raw_get_fmt,
|
||||
.attrs = &ad7195_attribute_group,
|
||||
.validate_trigger = ad_sd_validate_trigger,
|
||||
.driver_module = THIS_MODULE,
|
||||
|
@ -134,6 +134,7 @@ struct ad7280_state {
|
||||
unsigned char aux_threshhigh;
|
||||
unsigned char aux_threshlow;
|
||||
unsigned char cb_mask[AD7280A_MAX_CHAIN];
|
||||
struct mutex lock; /* protect sensor state */
|
||||
|
||||
__be32 buf[2] ____cacheline_aligned;
|
||||
};
|
||||
@ -410,7 +411,7 @@ static ssize_t ad7280_store_balance_sw(struct device *dev,
|
||||
devaddr = this_attr->address >> 8;
|
||||
ch = this_attr->address & 0xFF;
|
||||
|
||||
mutex_lock(&indio_dev->mlock);
|
||||
mutex_lock(&st->lock);
|
||||
if (readin)
|
||||
st->cb_mask[devaddr] |= 1 << (ch + 2);
|
||||
else
|
||||
@ -418,7 +419,7 @@ static ssize_t ad7280_store_balance_sw(struct device *dev,
|
||||
|
||||
ret = ad7280_write(st, devaddr, AD7280A_CELL_BALANCE,
|
||||
0, st->cb_mask[devaddr]);
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
mutex_unlock(&st->lock);
|
||||
|
||||
return ret ? ret : len;
|
||||
}
|
||||
@ -433,10 +434,10 @@ static ssize_t ad7280_show_balance_timer(struct device *dev,
|
||||
int ret;
|
||||
unsigned int msecs;
|
||||
|
||||
mutex_lock(&indio_dev->mlock);
|
||||
mutex_lock(&st->lock);
|
||||
ret = ad7280_read(st, this_attr->address >> 8,
|
||||
this_attr->address & 0xFF);
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
mutex_unlock(&st->lock);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@ -466,11 +467,11 @@ static ssize_t ad7280_store_balance_timer(struct device *dev,
|
||||
if (val > 31)
|
||||
return -EINVAL;
|
||||
|
||||
mutex_lock(&indio_dev->mlock);
|
||||
mutex_lock(&st->lock);
|
||||
ret = ad7280_write(st, this_attr->address >> 8,
|
||||
this_attr->address & 0xFF,
|
||||
0, (val & 0x1F) << 3);
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
mutex_unlock(&st->lock);
|
||||
|
||||
return ret ? ret : len;
|
||||
}
|
||||
@ -655,7 +656,7 @@ static ssize_t ad7280_write_channel_config(struct device *dev,
|
||||
|
||||
val = clamp(val, 0L, 0xFFL);
|
||||
|
||||
mutex_lock(&indio_dev->mlock);
|
||||
mutex_lock(&st->lock);
|
||||
switch ((u32)this_attr->address) {
|
||||
case AD7280A_CELL_OVERVOLTAGE:
|
||||
st->cell_threshhigh = val;
|
||||
@ -674,7 +675,7 @@ static ssize_t ad7280_write_channel_config(struct device *dev,
|
||||
ret = ad7280_write(st, AD7280A_DEVADDR_MASTER,
|
||||
this_attr->address, 1, val);
|
||||
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
mutex_unlock(&st->lock);
|
||||
|
||||
return ret ? ret : len;
|
||||
}
|
||||
@ -792,13 +793,13 @@ static int ad7280_read_raw(struct iio_dev *indio_dev,
|
||||
|
||||
switch (m) {
|
||||
case IIO_CHAN_INFO_RAW:
|
||||
mutex_lock(&indio_dev->mlock);
|
||||
mutex_lock(&st->lock);
|
||||
if (chan->address == AD7280A_ALL_CELLS)
|
||||
ret = ad7280_read_all_channels(st, st->scan_cnt, NULL);
|
||||
else
|
||||
ret = ad7280_read_channel(st, chan->address >> 8,
|
||||
chan->address & 0xFF);
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
mutex_unlock(&st->lock);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
@ -847,6 +848,7 @@ static int ad7280_probe(struct spi_device *spi)
|
||||
st = iio_priv(indio_dev);
|
||||
spi_set_drvdata(spi, indio_dev);
|
||||
st->spi = spi;
|
||||
mutex_init(&st->lock);
|
||||
|
||||
if (!pdata)
|
||||
pdata = &ad7793_default_pdata;
|
||||
|
@ -154,7 +154,7 @@ static const struct ad7780_chip_info ad7780_chip_info_tbl[] = {
|
||||
};
|
||||
|
||||
static const struct iio_info ad7780_info = {
|
||||
.read_raw = &ad7780_read_raw,
|
||||
.read_raw = ad7780_read_raw,
|
||||
.driver_module = THIS_MODULE,
|
||||
};
|
||||
|
||||
|
@ -155,13 +155,13 @@ static ssize_t ad7152_start_gain_calib(struct device *dev,
|
||||
}
|
||||
|
||||
static IIO_DEVICE_ATTR(in_capacitance0_calibbias_calibration,
|
||||
S_IWUSR, NULL, ad7152_start_offset_calib, 0);
|
||||
0200, NULL, ad7152_start_offset_calib, 0);
|
||||
static IIO_DEVICE_ATTR(in_capacitance1_calibbias_calibration,
|
||||
S_IWUSR, NULL, ad7152_start_offset_calib, 1);
|
||||
0200, NULL, ad7152_start_offset_calib, 1);
|
||||
static IIO_DEVICE_ATTR(in_capacitance0_calibscale_calibration,
|
||||
S_IWUSR, NULL, ad7152_start_gain_calib, 0);
|
||||
0200, NULL, ad7152_start_gain_calib, 0);
|
||||
static IIO_DEVICE_ATTR(in_capacitance1_calibscale_calibration,
|
||||
S_IWUSR, NULL, ad7152_start_gain_calib, 1);
|
||||
0200, NULL, ad7152_start_gain_calib, 1);
|
||||
|
||||
/* Values are Update Rate (Hz), Conversion Time (ms) + 1*/
|
||||
static const unsigned char ad7152_filter_rate_table[][2] = {
|
||||
@ -441,9 +441,9 @@ static int ad7152_write_raw_get_fmt(struct iio_dev *indio_dev,
|
||||
|
||||
static const struct iio_info ad7152_info = {
|
||||
.attrs = &ad7152_attribute_group,
|
||||
.read_raw = &ad7152_read_raw,
|
||||
.write_raw = &ad7152_write_raw,
|
||||
.write_raw_get_fmt = &ad7152_write_raw_get_fmt,
|
||||
.read_raw = ad7152_read_raw,
|
||||
.write_raw = ad7152_write_raw,
|
||||
.write_raw_get_fmt = ad7152_write_raw_get_fmt,
|
||||
.driver_module = THIS_MODULE,
|
||||
};
|
||||
|
||||
|
@ -91,6 +91,7 @@
|
||||
|
||||
struct ad7746_chip_info {
|
||||
struct i2c_client *client;
|
||||
struct mutex lock; /* protect sensor state */
|
||||
/*
|
||||
* Capacitive channel digital filter setup;
|
||||
* conversion time/update rate setup per channel
|
||||
@ -298,11 +299,11 @@ static inline ssize_t ad7746_start_calib(struct device *dev,
|
||||
if (!doit)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&indio_dev->mlock);
|
||||
mutex_lock(&chip->lock);
|
||||
regval |= chip->config;
|
||||
ret = i2c_smbus_write_byte_data(chip->client, AD7746_REG_CFG, regval);
|
||||
if (ret < 0) {
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
mutex_unlock(&chip->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -310,12 +311,12 @@ static inline ssize_t ad7746_start_calib(struct device *dev,
|
||||
msleep(20);
|
||||
ret = i2c_smbus_read_byte_data(chip->client, AD7746_REG_CFG);
|
||||
if (ret < 0) {
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
mutex_unlock(&chip->lock);
|
||||
return ret;
|
||||
}
|
||||
} while ((ret == regval) && timeout--);
|
||||
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
mutex_unlock(&chip->lock);
|
||||
|
||||
return len;
|
||||
}
|
||||
@ -351,15 +352,15 @@ static ssize_t ad7746_start_gain_calib(struct device *dev,
|
||||
}
|
||||
|
||||
static IIO_DEVICE_ATTR(in_capacitance0_calibbias_calibration,
|
||||
S_IWUSR, NULL, ad7746_start_offset_calib, CIN1);
|
||||
0200, NULL, ad7746_start_offset_calib, CIN1);
|
||||
static IIO_DEVICE_ATTR(in_capacitance1_calibbias_calibration,
|
||||
S_IWUSR, NULL, ad7746_start_offset_calib, CIN2);
|
||||
0200, NULL, ad7746_start_offset_calib, CIN2);
|
||||
static IIO_DEVICE_ATTR(in_capacitance0_calibscale_calibration,
|
||||
S_IWUSR, NULL, ad7746_start_gain_calib, CIN1);
|
||||
0200, NULL, ad7746_start_gain_calib, CIN1);
|
||||
static IIO_DEVICE_ATTR(in_capacitance1_calibscale_calibration,
|
||||
S_IWUSR, NULL, ad7746_start_gain_calib, CIN2);
|
||||
0200, NULL, ad7746_start_gain_calib, CIN2);
|
||||
static IIO_DEVICE_ATTR(in_voltage0_calibscale_calibration,
|
||||
S_IWUSR, NULL, ad7746_start_gain_calib, VIN);
|
||||
0200, NULL, ad7746_start_gain_calib, VIN);
|
||||
|
||||
static int ad7746_store_cap_filter_rate_setup(struct ad7746_chip_info *chip,
|
||||
int val)
|
||||
@ -426,7 +427,7 @@ static int ad7746_write_raw(struct iio_dev *indio_dev,
|
||||
struct ad7746_chip_info *chip = iio_priv(indio_dev);
|
||||
int ret, reg;
|
||||
|
||||
mutex_lock(&indio_dev->mlock);
|
||||
mutex_lock(&chip->lock);
|
||||
|
||||
switch (mask) {
|
||||
case IIO_CHAN_INFO_CALIBSCALE:
|
||||
@ -521,7 +522,7 @@ static int ad7746_write_raw(struct iio_dev *indio_dev,
|
||||
}
|
||||
|
||||
out:
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
mutex_unlock(&chip->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -534,7 +535,7 @@ static int ad7746_read_raw(struct iio_dev *indio_dev,
|
||||
int ret, delay, idx;
|
||||
u8 regval, reg;
|
||||
|
||||
mutex_lock(&indio_dev->mlock);
|
||||
mutex_lock(&chip->lock);
|
||||
|
||||
switch (mask) {
|
||||
case IIO_CHAN_INFO_RAW:
|
||||
@ -658,14 +659,14 @@ static int ad7746_read_raw(struct iio_dev *indio_dev,
|
||||
ret = -EINVAL;
|
||||
}
|
||||
out:
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
mutex_unlock(&chip->lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct iio_info ad7746_info = {
|
||||
.attrs = &ad7746_attribute_group,
|
||||
.read_raw = &ad7746_read_raw,
|
||||
.write_raw = &ad7746_write_raw,
|
||||
.read_raw = ad7746_read_raw,
|
||||
.write_raw = ad7746_write_raw,
|
||||
.driver_module = THIS_MODULE,
|
||||
};
|
||||
|
||||
@ -686,6 +687,7 @@ static int ad7746_probe(struct i2c_client *client,
|
||||
if (!indio_dev)
|
||||
return -ENOMEM;
|
||||
chip = iio_priv(indio_dev);
|
||||
mutex_init(&chip->lock);
|
||||
/* this is only used for device removal purposes */
|
||||
i2c_set_clientdata(client, indio_dev);
|
||||
|
||||
|
@ -84,6 +84,7 @@
|
||||
* @freq_msg: tuning word spi message
|
||||
* @phase_xfer: tuning word spi transfer
|
||||
* @phase_msg: tuning word spi message
|
||||
* @lock protect sensor state
|
||||
* @data: spi transmit buffer
|
||||
* @phase_data: tuning word spi transmit buffer
|
||||
* @freq_data: tuning word spi transmit buffer
|
||||
@ -103,6 +104,7 @@ struct ad9832_state {
|
||||
struct spi_message freq_msg;
|
||||
struct spi_transfer phase_xfer[2];
|
||||
struct spi_message phase_msg;
|
||||
struct mutex lock; /* protect sensor state */
|
||||
/*
|
||||
* DMA (thus cache coherency maintenance) requires the
|
||||
* transfer buffers to live in their own cache lines.
|
||||
@ -177,7 +179,7 @@ static ssize_t ad9832_write(struct device *dev, struct device_attribute *attr,
|
||||
if (ret)
|
||||
goto error_ret;
|
||||
|
||||
mutex_lock(&indio_dev->mlock);
|
||||
mutex_lock(&st->lock);
|
||||
switch ((u32)this_attr->address) {
|
||||
case AD9832_FREQ0HM:
|
||||
case AD9832_FREQ1HM:
|
||||
@ -238,7 +240,7 @@ static ssize_t ad9832_write(struct device *dev, struct device_attribute *attr,
|
||||
default:
|
||||
ret = -ENODEV;
|
||||
}
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
mutex_unlock(&st->lock);
|
||||
|
||||
error_ret:
|
||||
return ret ? ret : len;
|
||||
@ -334,6 +336,7 @@ static int ad9832_probe(struct spi_device *spi)
|
||||
|
||||
st->mclk = pdata->mclk;
|
||||
st->spi = spi;
|
||||
mutex_init(&st->lock);
|
||||
|
||||
indio_dev->dev.parent = &spi->dev;
|
||||
indio_dev->name = spi_get_device_id(spi)->name;
|
||||
|
@ -63,6 +63,7 @@
|
||||
* @msg: default spi message
|
||||
* @freq_xfer: tuning word spi transfer
|
||||
* @freq_msg: tuning word spi message
|
||||
* @lock: protect sensor state
|
||||
* @data: spi transmit buffer
|
||||
* @freq_data: tuning word spi transmit buffer
|
||||
*/
|
||||
@ -77,6 +78,7 @@ struct ad9834_state {
|
||||
struct spi_message msg;
|
||||
struct spi_transfer freq_xfer[2];
|
||||
struct spi_message freq_msg;
|
||||
struct mutex lock; /* protect sensor state */
|
||||
|
||||
/*
|
||||
* DMA (thus cache coherency maintenance) requires the
|
||||
@ -147,9 +149,9 @@ static ssize_t ad9834_write(struct device *dev,
|
||||
|
||||
ret = kstrtoul(buf, 10, &val);
|
||||
if (ret)
|
||||
goto error_ret;
|
||||
return ret;
|
||||
|
||||
mutex_lock(&indio_dev->mlock);
|
||||
mutex_lock(&st->lock);
|
||||
switch ((u32)this_attr->address) {
|
||||
case AD9834_REG_FREQ0:
|
||||
case AD9834_REG_FREQ1:
|
||||
@ -207,9 +209,8 @@ static ssize_t ad9834_write(struct device *dev,
|
||||
default:
|
||||
ret = -ENODEV;
|
||||
}
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
mutex_unlock(&st->lock);
|
||||
|
||||
error_ret:
|
||||
return ret ? ret : len;
|
||||
}
|
||||
|
||||
@ -224,7 +225,7 @@ static ssize_t ad9834_store_wavetype(struct device *dev,
|
||||
int ret = 0;
|
||||
bool is_ad9833_7 = (st->devid == ID_AD9833) || (st->devid == ID_AD9837);
|
||||
|
||||
mutex_lock(&indio_dev->mlock);
|
||||
mutex_lock(&st->lock);
|
||||
|
||||
switch ((u32)this_attr->address) {
|
||||
case 0:
|
||||
@ -267,7 +268,7 @@ static ssize_t ad9834_store_wavetype(struct device *dev,
|
||||
st->data = cpu_to_be16(AD9834_REG_CMD | st->control);
|
||||
ret = spi_sync(st->spi, &st->msg);
|
||||
}
|
||||
mutex_unlock(&indio_dev->mlock);
|
||||
mutex_unlock(&st->lock);
|
||||
|
||||
return ret ? ret : len;
|
||||
}
|
||||
@ -418,6 +419,7 @@ static int ad9834_probe(struct spi_device *spi)
|
||||
}
|
||||
spi_set_drvdata(spi, indio_dev);
|
||||
st = iio_priv(indio_dev);
|
||||
mutex_init(&st->lock);
|
||||
st->mclk = pdata->mclk;
|
||||
st->spi = spi;
|
||||
st->devid = spi_get_device_id(spi)->driver_data;
|
||||
|
@ -117,7 +117,7 @@ out_unlock:
|
||||
}
|
||||
|
||||
static const struct iio_info adis16060_info = {
|
||||
.read_raw = &adis16060_read_raw,
|
||||
.read_raw = adis16060_read_raw,
|
||||
.driver_module = THIS_MODULE,
|
||||
};
|
||||
|
||||
|
@ -21,7 +21,92 @@
|
||||
#include <linux/iio/iio.h>
|
||||
#include <linux/iio/sysfs.h>
|
||||
#include "meter.h"
|
||||
#include "ade7754.h"
|
||||
|
||||
#define ADE7754_AENERGY 0x01
|
||||
#define ADE7754_RAENERGY 0x02
|
||||
#define ADE7754_LAENERGY 0x03
|
||||
#define ADE7754_VAENERGY 0x04
|
||||
#define ADE7754_RVAENERGY 0x05
|
||||
#define ADE7754_LVAENERGY 0x06
|
||||
#define ADE7754_PERIOD 0x07
|
||||
#define ADE7754_TEMP 0x08
|
||||
#define ADE7754_WFORM 0x09
|
||||
#define ADE7754_OPMODE 0x0A
|
||||
#define ADE7754_MMODE 0x0B
|
||||
#define ADE7754_WAVMODE 0x0C
|
||||
#define ADE7754_WATMODE 0x0D
|
||||
#define ADE7754_VAMODE 0x0E
|
||||
#define ADE7754_IRQEN 0x0F
|
||||
#define ADE7754_STATUS 0x10
|
||||
#define ADE7754_RSTATUS 0x11
|
||||
#define ADE7754_ZXTOUT 0x12
|
||||
#define ADE7754_LINCYC 0x13
|
||||
#define ADE7754_SAGCYC 0x14
|
||||
#define ADE7754_SAGLVL 0x15
|
||||
#define ADE7754_VPEAK 0x16
|
||||
#define ADE7754_IPEAK 0x17
|
||||
#define ADE7754_GAIN 0x18
|
||||
#define ADE7754_AWG 0x19
|
||||
#define ADE7754_BWG 0x1A
|
||||
#define ADE7754_CWG 0x1B
|
||||
#define ADE7754_AVAG 0x1C
|
||||
#define ADE7754_BVAG 0x1D
|
||||
#define ADE7754_CVAG 0x1E
|
||||
#define ADE7754_APHCAL 0x1F
|
||||
#define ADE7754_BPHCAL 0x20
|
||||
#define ADE7754_CPHCAL 0x21
|
||||
#define ADE7754_AAPOS 0x22
|
||||
#define ADE7754_BAPOS 0x23
|
||||
#define ADE7754_CAPOS 0x24
|
||||
#define ADE7754_CFNUM 0x25
|
||||
#define ADE7754_CFDEN 0x26
|
||||
#define ADE7754_WDIV 0x27
|
||||
#define ADE7754_VADIV 0x28
|
||||
#define ADE7754_AIRMS 0x29
|
||||
#define ADE7754_BIRMS 0x2A
|
||||
#define ADE7754_CIRMS 0x2B
|
||||
#define ADE7754_AVRMS 0x2C
|
||||
#define ADE7754_BVRMS 0x2D
|
||||
#define ADE7754_CVRMS 0x2E
|
||||
#define ADE7754_AIRMSOS 0x2F
|
||||
#define ADE7754_BIRMSOS 0x30
|
||||
#define ADE7754_CIRMSOS 0x31
|
||||
#define ADE7754_AVRMSOS 0x32
|
||||
#define ADE7754_BVRMSOS 0x33
|
||||
#define ADE7754_CVRMSOS 0x34
|
||||
#define ADE7754_AAPGAIN 0x35
|
||||
#define ADE7754_BAPGAIN 0x36
|
||||
#define ADE7754_CAPGAIN 0x37
|
||||
#define ADE7754_AVGAIN 0x38
|
||||
#define ADE7754_BVGAIN 0x39
|
||||
#define ADE7754_CVGAIN 0x3A
|
||||
#define ADE7754_CHKSUM 0x3E
|
||||
#define ADE7754_VERSION 0x3F
|
||||
|
||||
#define ADE7754_READ_REG(a) a
|
||||
#define ADE7754_WRITE_REG(a) ((a) | 0x80)
|
||||
|
||||
#define ADE7754_MAX_TX 4
|
||||
#define ADE7754_MAX_RX 4
|
||||
#define ADE7754_STARTUP_DELAY 1000
|
||||
|
||||
#define ADE7754_SPI_SLOW (u32)(300 * 1000)
|
||||
#define ADE7754_SPI_BURST (u32)(1000 * 1000)
|
||||
#define ADE7754_SPI_FAST (u32)(2000 * 1000)
|
||||
|
||||
/**
|
||||
* struct ade7754_state - device instance specific data
|
||||
* @us: actual spi_device
|
||||
* @buf_lock: mutex to protect tx and rx
|
||||
* @tx: transmit buffer
|
||||
* @rx: receive buffer
|
||||
**/
|
||||
struct ade7754_state {
|
||||
struct spi_device *us;
|
||||
struct mutex buf_lock;
|
||||
u8 tx[ADE7754_MAX_TX] ____cacheline_aligned;
|
||||
u8 rx[ADE7754_MAX_RX];
|
||||
};
|
||||
|
||||
static int ade7754_spi_write_reg_8(struct device *dev, u8 reg_address, u8 val)
|
||||
{
|
||||
@ -349,9 +434,7 @@ static int ade7754_set_irq(struct device *dev, bool enable)
|
||||
else
|
||||
irqen &= ~BIT(14);
|
||||
|
||||
ret = ade7754_spi_write_reg_16(dev, ADE7754_IRQEN, irqen);
|
||||
|
||||
return ret;
|
||||
return ade7754_spi_write_reg_16(dev, ADE7754_IRQEN, irqen);
|
||||
}
|
||||
|
||||
/* Power down the device */
|
||||
|
@ -1,90 +0,0 @@
|
||||
#ifndef _ADE7754_H
|
||||
#define _ADE7754_H
|
||||
|
||||
#define ADE7754_AENERGY 0x01
|
||||
#define ADE7754_RAENERGY 0x02
|
||||
#define ADE7754_LAENERGY 0x03
|
||||
#define ADE7754_VAENERGY 0x04
|
||||
#define ADE7754_RVAENERGY 0x05
|
||||
#define ADE7754_LVAENERGY 0x06
|
||||
#define ADE7754_PERIOD 0x07
|
||||
#define ADE7754_TEMP 0x08
|
||||
#define ADE7754_WFORM 0x09
|
||||
#define ADE7754_OPMODE 0x0A
|
||||
#define ADE7754_MMODE 0x0B
|
||||
#define ADE7754_WAVMODE 0x0C
|
||||
#define ADE7754_WATMODE 0x0D
|
||||
#define ADE7754_VAMODE 0x0E
|
||||
#define ADE7754_IRQEN 0x0F
|
||||
#define ADE7754_STATUS 0x10
|
||||
#define ADE7754_RSTATUS 0x11
|
||||
#define ADE7754_ZXTOUT 0x12
|
||||
#define ADE7754_LINCYC 0x13
|
||||
#define ADE7754_SAGCYC 0x14
|
||||
#define ADE7754_SAGLVL 0x15
|
||||
#define ADE7754_VPEAK 0x16
|
||||
#define ADE7754_IPEAK 0x17
|
||||
#define ADE7754_GAIN 0x18
|
||||
#define ADE7754_AWG 0x19
|
||||
#define ADE7754_BWG 0x1A
|
||||
#define ADE7754_CWG 0x1B
|
||||
#define ADE7754_AVAG 0x1C
|
||||
#define ADE7754_BVAG 0x1D
|
||||
#define ADE7754_CVAG 0x1E
|
||||
#define ADE7754_APHCAL 0x1F
|
||||
#define ADE7754_BPHCAL 0x20
|
||||
#define ADE7754_CPHCAL 0x21
|
||||
#define ADE7754_AAPOS 0x22
|
||||
#define ADE7754_BAPOS 0x23
|
||||
#define ADE7754_CAPOS 0x24
|
||||
#define ADE7754_CFNUM 0x25
|
||||
#define ADE7754_CFDEN 0x26
|
||||
#define ADE7754_WDIV 0x27
|
||||
#define ADE7754_VADIV 0x28
|
||||
#define ADE7754_AIRMS 0x29
|
||||
#define ADE7754_BIRMS 0x2A
|
||||
#define ADE7754_CIRMS 0x2B
|
||||
#define ADE7754_AVRMS 0x2C
|
||||
#define ADE7754_BVRMS 0x2D
|
||||
#define ADE7754_CVRMS 0x2E
|
||||
#define ADE7754_AIRMSOS 0x2F
|
||||
#define ADE7754_BIRMSOS 0x30
|
||||
#define ADE7754_CIRMSOS 0x31
|
||||
#define ADE7754_AVRMSOS 0x32
|
||||
#define ADE7754_BVRMSOS 0x33
|
||||
#define ADE7754_CVRMSOS 0x34
|
||||
#define ADE7754_AAPGAIN 0x35
|
||||
#define ADE7754_BAPGAIN 0x36
|
||||
#define ADE7754_CAPGAIN 0x37
|
||||
#define ADE7754_AVGAIN 0x38
|
||||
#define ADE7754_BVGAIN 0x39
|
||||
#define ADE7754_CVGAIN 0x3A
|
||||
#define ADE7754_CHKSUM 0x3E
|
||||
#define ADE7754_VERSION 0x3F
|
||||
|
||||
#define ADE7754_READ_REG(a) a
|
||||
#define ADE7754_WRITE_REG(a) ((a) | 0x80)
|
||||
|
||||
#define ADE7754_MAX_TX 4
|
||||
#define ADE7754_MAX_RX 4
|
||||
#define ADE7754_STARTUP_DELAY 1000
|
||||
|
||||
#define ADE7754_SPI_SLOW (u32)(300 * 1000)
|
||||
#define ADE7754_SPI_BURST (u32)(1000 * 1000)
|
||||
#define ADE7754_SPI_FAST (u32)(2000 * 1000)
|
||||
|
||||
/**
|
||||
* struct ade7754_state - device instance specific data
|
||||
* @us: actual spi_device
|
||||
* @buf_lock: mutex to protect tx and rx
|
||||
* @tx: transmit buffer
|
||||
* @rx: receive buffer
|
||||
**/
|
||||
struct ade7754_state {
|
||||
struct spi_device *us;
|
||||
struct mutex buf_lock;
|
||||
u8 tx[ADE7754_MAX_TX] ____cacheline_aligned;
|
||||
u8 rx[ADE7754_MAX_RX];
|
||||
};
|
||||
|
||||
#endif
|
@ -21,7 +21,55 @@
|
||||
#include <linux/iio/iio.h>
|
||||
#include <linux/iio/sysfs.h>
|
||||
#include "meter.h"
|
||||
#include "ade7759.h"
|
||||
|
||||
#define ADE7759_WAVEFORM 0x01
|
||||
#define ADE7759_AENERGY 0x02
|
||||
#define ADE7759_RSTENERGY 0x03
|
||||
#define ADE7759_STATUS 0x04
|
||||
#define ADE7759_RSTSTATUS 0x05
|
||||
#define ADE7759_MODE 0x06
|
||||
#define ADE7759_CFDEN 0x07
|
||||
#define ADE7759_CH1OS 0x08
|
||||
#define ADE7759_CH2OS 0x09
|
||||
#define ADE7759_GAIN 0x0A
|
||||
#define ADE7759_APGAIN 0x0B
|
||||
#define ADE7759_PHCAL 0x0C
|
||||
#define ADE7759_APOS 0x0D
|
||||
#define ADE7759_ZXTOUT 0x0E
|
||||
#define ADE7759_SAGCYC 0x0F
|
||||
#define ADE7759_IRQEN 0x10
|
||||
#define ADE7759_SAGLVL 0x11
|
||||
#define ADE7759_TEMP 0x12
|
||||
#define ADE7759_LINECYC 0x13
|
||||
#define ADE7759_LENERGY 0x14
|
||||
#define ADE7759_CFNUM 0x15
|
||||
#define ADE7759_CHKSUM 0x1E
|
||||
#define ADE7759_DIEREV 0x1F
|
||||
|
||||
#define ADE7759_READ_REG(a) a
|
||||
#define ADE7759_WRITE_REG(a) ((a) | 0x80)
|
||||
|
||||
#define ADE7759_MAX_TX 6
|
||||
#define ADE7759_MAX_RX 6
|
||||
#define ADE7759_STARTUP_DELAY 1000
|
||||
|
||||
#define ADE7759_SPI_SLOW (u32)(300 * 1000)
|
||||
#define ADE7759_SPI_BURST (u32)(1000 * 1000)
|
||||
#define ADE7759_SPI_FAST (u32)(2000 * 1000)
|
||||
|
||||
/**
|
||||
* struct ade7759_state - device instance specific data
|
||||
* @us: actual spi_device
|
||||
* @buf_lock: mutex to protect tx and rx
|
||||
* @tx: transmit buffer
|
||||
* @rx: receive buffer
|
||||
**/
|
||||
struct ade7759_state {
|
||||
struct spi_device *us;
|
||||
struct mutex buf_lock;
|
||||
u8 tx[ADE7759_MAX_TX] ____cacheline_aligned;
|
||||
u8 rx[ADE7759_MAX_RX];
|
||||
};
|
||||
|
||||
static int ade7759_spi_write_reg_8(struct device *dev,
|
||||
u8 reg_address,
|
||||
|
@ -1,53 +0,0 @@
|
||||
#ifndef _ADE7759_H
|
||||
#define _ADE7759_H
|
||||
|
||||
#define ADE7759_WAVEFORM 0x01
|
||||
#define ADE7759_AENERGY 0x02
|
||||
#define ADE7759_RSTENERGY 0x03
|
||||
#define ADE7759_STATUS 0x04
|
||||
#define ADE7759_RSTSTATUS 0x05
|
||||
#define ADE7759_MODE 0x06
|
||||
#define ADE7759_CFDEN 0x07
|
||||
#define ADE7759_CH1OS 0x08
|
||||
#define ADE7759_CH2OS 0x09
|
||||
#define ADE7759_GAIN 0x0A
|
||||
#define ADE7759_APGAIN 0x0B
|
||||
#define ADE7759_PHCAL 0x0C
|
||||
#define ADE7759_APOS 0x0D
|
||||
#define ADE7759_ZXTOUT 0x0E
|
||||
#define ADE7759_SAGCYC 0x0F
|
||||
#define ADE7759_IRQEN 0x10
|
||||
#define ADE7759_SAGLVL 0x11
|
||||
#define ADE7759_TEMP 0x12
|
||||
#define ADE7759_LINECYC 0x13
|
||||
#define ADE7759_LENERGY 0x14
|
||||
#define ADE7759_CFNUM 0x15
|
||||
#define ADE7759_CHKSUM 0x1E
|
||||
#define ADE7759_DIEREV 0x1F
|
||||
|
||||
#define ADE7759_READ_REG(a) a
|
||||
#define ADE7759_WRITE_REG(a) ((a) | 0x80)
|
||||
|
||||
#define ADE7759_MAX_TX 6
|
||||
#define ADE7759_MAX_RX 6
|
||||
#define ADE7759_STARTUP_DELAY 1000
|
||||
|
||||
#define ADE7759_SPI_SLOW (u32)(300 * 1000)
|
||||
#define ADE7759_SPI_BURST (u32)(1000 * 1000)
|
||||
#define ADE7759_SPI_FAST (u32)(2000 * 1000)
|
||||
|
||||
/**
|
||||
* struct ade7759_state - device instance specific data
|
||||
* @us: actual spi_device
|
||||
* @buf_lock: mutex to protect tx and rx
|
||||
* @tx: transmit buffer
|
||||
* @rx: receive buffer
|
||||
**/
|
||||
struct ade7759_state {
|
||||
struct spi_device *us;
|
||||
struct mutex buf_lock;
|
||||
u8 tx[ADE7759_MAX_TX] ____cacheline_aligned;
|
||||
u8 rx[ADE7759_MAX_RX];
|
||||
};
|
||||
|
||||
#endif
|
@ -97,7 +97,7 @@ static const struct iio_chan_spec ad2s1200_channels[] = {
|
||||
};
|
||||
|
||||
static const struct iio_info ad2s1200_info = {
|
||||
.read_raw = &ad2s1200_read_raw,
|
||||
.read_raw = ad2s1200_read_raw,
|
||||
.driver_module = THIS_MODULE,
|
||||
};
|
||||
|
||||
|
@ -490,8 +490,8 @@ static int ad2s1210_read_raw(struct iio_dev *indio_dev,
|
||||
ad2s1210_set_mode(MOD_VEL, st);
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
if (ret < 0)
|
||||
goto error_ret;
|
||||
|
@ -47,7 +47,7 @@ error_ret:
|
||||
}
|
||||
|
||||
static const struct iio_info ad2s90_info = {
|
||||
.read_raw = &ad2s90_read_raw,
|
||||
.read_raw = ad2s90_read_raw,
|
||||
.driver_module = THIS_MODULE,
|
||||
};
|
||||
|
||||
|
@ -28,6 +28,7 @@
|
||||
#define SUN4I_GPADC_CTRL1_TP_MODE_EN BIT(4)
|
||||
#define SUN4I_GPADC_CTRL1_TP_ADC_SELECT BIT(3)
|
||||
#define SUN4I_GPADC_CTRL1_ADC_CHAN_SELECT(x) (GENMASK(2, 0) & (x))
|
||||
#define SUN4I_GPADC_CTRL1_ADC_CHAN_MASK GENMASK(2, 0)
|
||||
|
||||
/* TP_CTRL1 bits for sun6i SOCs */
|
||||
#define SUN6I_GPADC_CTRL1_TOUCH_PAN_CALI_EN BIT(7)
|
||||
@ -35,6 +36,7 @@
|
||||
#define SUN6I_GPADC_CTRL1_TP_MODE_EN BIT(5)
|
||||
#define SUN6I_GPADC_CTRL1_TP_ADC_SELECT BIT(4)
|
||||
#define SUN6I_GPADC_CTRL1_ADC_CHAN_SELECT(x) (GENMASK(3, 0) & BIT(x))
|
||||
#define SUN6I_GPADC_CTRL1_ADC_CHAN_MASK GENMASK(3, 0)
|
||||
|
||||
#define SUN4I_GPADC_CTRL2 0x08
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user