Commit 5e47adb9 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

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

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

Jonathan writes:

Second set of IIO new device support, features and cleanup for the 4.14 cycle.

New device support:
* ak8974
  - support the AMI306.
* st_magnetometer
  - add support for the LIS2MDL with bindings.
* rockchip-saradc
  - add binding for rv1108 SoC (no driver change).
* srf08
  - add srf02 (i2c only) and srf10 support.
* stm32-timer
  - support for the STM32H7 to existing driver.

Features:
* tools
  - move over to the tools buildsystem rather than hand rolling.
  - add an install section to the build.
* ak8974
  - use serial number to add device randomness.
  - add AMI306 calibration data output.
* ccs811
  - triggered buffer support.
* srf08
  - add a device tree table as the old style i2c probing is going away,
  - add triggered buffer support
* st32-adc
  - add optional st,min-sample-time-nsecs binding to allow control of
    sampling against analog circuitry.
* stm32-timer
  - add output compare triggers.
* ti-ads1015
  - add threshold event support.
* ti-ads7950
  - Allow use on ACPI platforms including providing a default reference
    voltage as there is no way to obtain this on ACPI currently.

Cleanup and fixes:
* ad7606
  - fix an error return code in probe.
* ads1015
  - fix incorrect data rate setting update when capture in progress,
  - fix wrong scale information for the ADS1115,
  - make conversions work when CONFIG_PM is not set,
  - make sure we don't get a stale result after a runtime resume by
    ensuring we wait long enough,
  - avoid returning a false error form the buffer setup callbacks,
  - add enough wait time to get the correct conversion,
  - remove an unnecessary config register update,
  - add a helper to set conversion mode reducing repeated boilerplate,
  - use devm_iio_triggered_buffer_setup to simplify error and remove
    paths,
  - use iio_device_claim_direct_mode instead of opencoding the same.
* ak8974
  - mark the INT_CLEAR register as precious to prevent debugfs access.
* apds9300
  - constify the i2c_device_id.
* at91-sama5 adc
  - add missing Kconfig dependency.
* bma180 accel
  - constify the i2c_device_id.
* rockchip_saradc
  - explicitly request exclusive reset control as part of the reset rework
    on going throughout the kernel.
* st_accel
  - fix drdy configuration for a load of accelerometers that only have
    the int1 line.  Fix is unimportant as presumably no deviec tree actually
    used the non existent hardware line.
* st_pressure
  - fix drdy configuration for LPS22HB and LPS25H by dropping int2 support
    as they don't have this. Fix is unimportant as presumably no device tree
    actually used the non existent hardware line.
* stm32-dac
  - explicitly request exclusive reset control (part of reset being reworked).
* tsl2583
  - constify the i2c_device_id.
* xadc
  - coding style fixes.
parents 0de79ffc 87587016
...@@ -6,6 +6,7 @@ Required properties: ...@@ -6,6 +6,7 @@ Required properties:
- "rockchip,rk3066-tsadc": for rk3036 - "rockchip,rk3066-tsadc": for rk3036
- "rockchip,rk3328-saradc", "rockchip,rk3399-saradc": for rk3328 - "rockchip,rk3328-saradc", "rockchip,rk3399-saradc": for rk3328
- "rockchip,rk3399-saradc": for rk3399 - "rockchip,rk3399-saradc": for rk3399
- "rockchip,rv1108-saradc", "rockchip,rk3399-saradc": for rv1108
- reg: physical base address of the controller and length of memory mapped - reg: physical base address of the controller and length of memory mapped
region. region.
......
...@@ -74,6 +74,11 @@ Optional properties: ...@@ -74,6 +74,11 @@ Optional properties:
* can be 6, 8, 10 or 12 on stm32f4 * can be 6, 8, 10 or 12 on stm32f4
* can be 8, 10, 12, 14 or 16 on stm32h7 * can be 8, 10, 12, 14 or 16 on stm32h7
Default is maximum resolution if unset. Default is maximum resolution if unset.
- st,min-sample-time-nsecs: Minimum sampling time in nanoseconds.
Depending on hardware (board) e.g. high/low analog input source impedance,
fine tune of ADC sampling time may be recommended.
This can be either one value or an array that matches 'st,adc-channels' list,
to set sample time resp. for all channels, or independently for each channel.
Example: Example:
adc: adc@40012000 { adc: adc@40012000 {
......
...@@ -64,6 +64,7 @@ Magnetometers: ...@@ -64,6 +64,7 @@ Magnetometers:
- st,lsm303dlhc-magn - st,lsm303dlhc-magn
- st,lsm303dlm-magn - st,lsm303dlm-magn
- st,lis3mdl-magn - st,lis3mdl-magn
- st,lis2mdl
Pressure sensors: Pressure sensors:
- st,lps001wp-press - st,lps001wp-press
......
...@@ -4,7 +4,9 @@ Must be a sub-node of an STM32 Timers device tree node. ...@@ -4,7 +4,9 @@ Must be a sub-node of an STM32 Timers device tree node.
See ../mfd/stm32-timers.txt for details about the parent node. See ../mfd/stm32-timers.txt for details about the parent node.
Required parameters: Required parameters:
- compatible: Must be "st,stm32-timer-trigger". - compatible: Must be one of:
"st,stm32-timer-trigger"
"st,stm32h7-timer-trigger"
- reg: Identify trigger hardware block. - reg: Identify trigger hardware block.
Example: Example:
......
...@@ -842,7 +842,7 @@ static SIMPLE_DEV_PM_OPS(bma180_pm_ops, bma180_suspend, bma180_resume); ...@@ -842,7 +842,7 @@ static SIMPLE_DEV_PM_OPS(bma180_pm_ops, bma180_suspend, bma180_resume);
#define BMA180_PM_OPS NULL #define BMA180_PM_OPS NULL
#endif #endif
static struct i2c_device_id bma180_ids[] = { static const struct i2c_device_id bma180_ids[] = {
{ "bma180", BMA180 }, { "bma180", BMA180 },
{ "bma250", BMA250 }, { "bma250", BMA250 },
{ } { }
......
...@@ -161,7 +161,7 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = { ...@@ -161,7 +161,7 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
.drdy_irq = { .drdy_irq = {
.addr = 0x22, .addr = 0x22,
.mask_int1 = 0x10, .mask_int1 = 0x10,
.mask_int2 = 0x08, .mask_int2 = 0x00,
.addr_ihl = 0x25, .addr_ihl = 0x25,
.mask_ihl = 0x02, .mask_ihl = 0x02,
.addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR, .addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
...@@ -637,7 +637,7 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = { ...@@ -637,7 +637,7 @@ static const struct st_sensor_settings st_accel_sensors_settings[] = {
.drdy_irq = { .drdy_irq = {
.addr = 0x22, .addr = 0x22,
.mask_int1 = 0x10, .mask_int1 = 0x10,
.mask_int2 = 0x08, .mask_int2 = 0x00,
.addr_ihl = 0x25, .addr_ihl = 0x25,
.mask_ihl = 0x02, .mask_ihl = 0x02,
.addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR, .addr_stat_drdy = ST_SENSORS_DEFAULT_STAT_ADDR,
......
...@@ -158,6 +158,7 @@ config AT91_SAMA5D2_ADC ...@@ -158,6 +158,7 @@ config AT91_SAMA5D2_ADC
tristate "Atmel AT91 SAMA5D2 ADC" tristate "Atmel AT91 SAMA5D2 ADC"
depends on ARCH_AT91 || COMPILE_TEST depends on ARCH_AT91 || COMPILE_TEST
depends on HAS_IOMEM depends on HAS_IOMEM
select IIO_TRIGGERED_BUFFER
help help
Say yes here to build support for Atmel SAMA5D2 ADC which is Say yes here to build support for Atmel SAMA5D2 ADC which is
available on SAMA5D2 SoC family. available on SAMA5D2 SoC family.
......
...@@ -240,7 +240,8 @@ static int rockchip_saradc_probe(struct platform_device *pdev) ...@@ -240,7 +240,8 @@ static int rockchip_saradc_probe(struct platform_device *pdev)
* The reset should be an optional property, as it should work * The reset should be an optional property, as it should work
* with old devicetrees as well * with old devicetrees as well
*/ */
info->reset = devm_reset_control_get(&pdev->dev, "saradc-apb"); info->reset = devm_reset_control_get_exclusive(&pdev->dev,
"saradc-apb");
if (IS_ERR(info->reset)) { if (IS_ERR(info->reset)) {
ret = PTR_ERR(info->reset); ret = PTR_ERR(info->reset);
if (ret != -ENOENT) if (ret != -ENOENT)
......
This diff is collapsed.
This diff is collapsed.
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
* GNU General Public License for more details. * GNU General Public License for more details.
*/ */
#include <linux/acpi.h>
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/err.h> #include <linux/err.h>
...@@ -37,6 +38,12 @@ ...@@ -37,6 +38,12 @@
#include <linux/iio/trigger_consumer.h> #include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h> #include <linux/iio/triggered_buffer.h>
/*
* In case of ACPI, we use the 5000 mV as default for the reference pin.
* Device tree users encode that via the vref-supply regulator.
*/
#define TI_ADS7950_VA_MV_ACPI_DEFAULT 5000
#define TI_ADS7950_CR_MANUAL BIT(12) #define TI_ADS7950_CR_MANUAL BIT(12)
#define TI_ADS7950_CR_WRITE BIT(11) #define TI_ADS7950_CR_WRITE BIT(11)
#define TI_ADS7950_CR_CHAN(ch) ((ch) << 7) #define TI_ADS7950_CR_CHAN(ch) ((ch) << 7)
...@@ -58,6 +65,7 @@ struct ti_ads7950_state { ...@@ -58,6 +65,7 @@ struct ti_ads7950_state {
struct spi_message scan_single_msg; struct spi_message scan_single_msg;
struct regulator *reg; struct regulator *reg;
unsigned int vref_mv;
unsigned int settings; unsigned int settings;
...@@ -305,11 +313,15 @@ static int ti_ads7950_get_range(struct ti_ads7950_state *st) ...@@ -305,11 +313,15 @@ static int ti_ads7950_get_range(struct ti_ads7950_state *st)
{ {
int vref; int vref;
vref = regulator_get_voltage(st->reg); if (st->vref_mv) {
if (vref < 0) vref = st->vref_mv;
return vref; } else {
vref = regulator_get_voltage(st->reg);
if (vref < 0)
return vref;
vref /= 1000; vref /= 1000;
}
if (st->settings & TI_ADS7950_CR_RANGE_5V) if (st->settings & TI_ADS7950_CR_RANGE_5V)
vref *= 2; vref *= 2;
...@@ -411,6 +423,10 @@ static int ti_ads7950_probe(struct spi_device *spi) ...@@ -411,6 +423,10 @@ static int ti_ads7950_probe(struct spi_device *spi)
spi_message_init_with_transfers(&st->scan_single_msg, spi_message_init_with_transfers(&st->scan_single_msg,
st->scan_single_xfer, 3); st->scan_single_xfer, 3);
/* Use hard coded value for reference voltage in ACPI case */
if (ACPI_COMPANION(&spi->dev))
st->vref_mv = TI_ADS7950_VA_MV_ACPI_DEFAULT;
st->reg = devm_regulator_get(&spi->dev, "vref"); st->reg = devm_regulator_get(&spi->dev, "vref");
if (IS_ERR(st->reg)) { if (IS_ERR(st->reg)) {
dev_err(&spi->dev, "Failed get get regulator \"vref\"\n"); dev_err(&spi->dev, "Failed get get regulator \"vref\"\n");
...@@ -475,9 +491,27 @@ static const struct spi_device_id ti_ads7950_id[] = { ...@@ -475,9 +491,27 @@ static const struct spi_device_id ti_ads7950_id[] = {
}; };
MODULE_DEVICE_TABLE(spi, ti_ads7950_id); MODULE_DEVICE_TABLE(spi, ti_ads7950_id);
static const struct of_device_id ads7950_of_table[] = {
{ .compatible = "ti,ads7950", .data = &ti_ads7950_chip_info[TI_ADS7950] },
{ .compatible = "ti,ads7951", .data = &ti_ads7950_chip_info[TI_ADS7951] },
{ .compatible = "ti,ads7952", .data = &ti_ads7950_chip_info[TI_ADS7952] },
{ .compatible = "ti,ads7953", .data = &ti_ads7950_chip_info[TI_ADS7953] },
{ .compatible = "ti,ads7954", .data = &ti_ads7950_chip_info[TI_ADS7954] },
{ .compatible = "ti,ads7955", .data = &ti_ads7950_chip_info[TI_ADS7955] },
{ .compatible = "ti,ads7956", .data = &ti_ads7950_chip_info[TI_ADS7956] },
{ .compatible = "ti,ads7957", .data = &ti_ads7950_chip_info[TI_ADS7957] },
{ .compatible = "ti,ads7958", .data = &ti_ads7950_chip_info[TI_ADS7958] },
{ .compatible = "ti,ads7959", .data = &ti_ads7950_chip_info[TI_ADS7959] },
{ .compatible = "ti,ads7960", .data = &ti_ads7950_chip_info[TI_ADS7960] },
{ .compatible = "ti,ads7961", .data = &ti_ads7950_chip_info[TI_ADS7961] },
{ },
};
MODULE_DEVICE_TABLE(of, ads7950_of_table);
static struct spi_driver ti_ads7950_driver = { static struct spi_driver ti_ads7950_driver = {
.driver = { .driver = {
.name = "ads7950", .name = "ads7950",
.of_match_table = ads7950_of_table,
}, },
.probe = ti_ads7950_probe, .probe = ti_ads7950_probe,
.remove = ti_ads7950_remove, .remove = ti_ads7950_remove,
......
...@@ -68,7 +68,7 @@ void xadc_handle_events(struct iio_dev *indio_dev, unsigned long events) ...@@ -68,7 +68,7 @@ void xadc_handle_events(struct iio_dev *indio_dev, unsigned long events)
xadc_handle_event(indio_dev, i); xadc_handle_event(indio_dev, i);
} }
static unsigned xadc_get_threshold_offset(const struct iio_chan_spec *chan, static unsigned int xadc_get_threshold_offset(const struct iio_chan_spec *chan,
enum iio_event_direction dir) enum iio_event_direction dir)
{ {
unsigned int offset; unsigned int offset;
...@@ -90,26 +90,24 @@ static unsigned xadc_get_threshold_offset(const struct iio_chan_spec *chan, ...@@ -90,26 +90,24 @@ static unsigned xadc_get_threshold_offset(const struct iio_chan_spec *chan,
static unsigned int xadc_get_alarm_mask(const struct iio_chan_spec *chan) static unsigned int xadc_get_alarm_mask(const struct iio_chan_spec *chan)
{ {
if (chan->type == IIO_TEMP) { if (chan->type == IIO_TEMP)
return XADC_ALARM_OT_MASK; return XADC_ALARM_OT_MASK;
} else { switch (chan->channel) {
switch (chan->channel) { case 0:
case 0: return XADC_ALARM_VCCINT_MASK;
return XADC_ALARM_VCCINT_MASK; case 1:
case 1: return XADC_ALARM_VCCAUX_MASK;
return XADC_ALARM_VCCAUX_MASK; case 2:
case 2: return XADC_ALARM_VCCBRAM_MASK;
return XADC_ALARM_VCCBRAM_MASK; case 3:
case 3: return XADC_ALARM_VCCPINT_MASK;
return XADC_ALARM_VCCPINT_MASK; case 4:
case 4: return XADC_ALARM_VCCPAUX_MASK;
return XADC_ALARM_VCCPAUX_MASK; case 5:
case 5: return XADC_ALARM_VCCODDR_MASK;
return XADC_ALARM_VCCODDR_MASK; default:
default: /* We will never get here */
/* We will never get here */ return 0;
return 0;
}
} }
} }
......
...@@ -71,13 +71,13 @@ struct xadc { ...@@ -71,13 +71,13 @@ struct xadc {
}; };
struct xadc_ops { struct xadc_ops {
int (*read)(struct xadc *, unsigned int, uint16_t *); int (*read)(struct xadc *xadc, unsigned int reg, uint16_t *val);
int (*write)(struct xadc *, unsigned int, uint16_t); int (*write)(struct xadc *xadc, unsigned int reg, uint16_t val);
int (*setup)(struct platform_device *pdev, struct iio_dev *indio_dev, int (*setup)(struct platform_device *pdev, struct iio_dev *indio_dev,
int irq); int irq);
void (*update_alarm)(struct xadc *, unsigned int); void (*update_alarm)(struct xadc *xadc, unsigned int alarm);
unsigned long (*get_dclk_rate)(struct xadc *); unsigned long (*get_dclk_rate)(struct xadc *xadc);
irqreturn_t (*interrupt_handler)(int, void *); irqreturn_t (*interrupt_handler)(int irq, void *devid);
unsigned int flags; unsigned int flags;
}; };
......
...@@ -24,6 +24,8 @@ config ATLAS_PH_SENSOR ...@@ -24,6 +24,8 @@ config ATLAS_PH_SENSOR
config CCS811 config CCS811
tristate "AMS CCS811 VOC sensor" tristate "AMS CCS811 VOC sensor"
depends on I2C depends on I2C
select IIO_BUFFER
select IIO_TRIGGERED_BUFFER
help help
Say Y here to build I2C interface support for the AMS Say Y here to build I2C interface support for the AMS
CCS811 VOC (Volatile Organic Compounds) sensor CCS811 VOC (Volatile Organic Compounds) sensor
......
...@@ -21,6 +21,9 @@ ...@@ -21,6 +21,9 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/i2c.h> #include <linux/i2c.h>
#include <linux/iio/iio.h> #include <linux/iio/iio.h>
#include <linux/iio/buffer.h>
#include <linux/iio/triggered_buffer.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/module.h> #include <linux/module.h>
#define CCS811_STATUS 0x00 #define CCS811_STATUS 0x00
...@@ -76,25 +79,42 @@ static const struct iio_chan_spec ccs811_channels[] = { ...@@ -76,25 +79,42 @@ static const struct iio_chan_spec ccs811_channels[] = {
{ {
.type = IIO_CURRENT, .type = IIO_CURRENT,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_SCALE) BIT(IIO_CHAN_INFO_SCALE),
.scan_index = -1,
}, { }, {
.type = IIO_VOLTAGE, .type = IIO_VOLTAGE,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_SCALE) BIT(IIO_CHAN_INFO_SCALE),
.scan_index = -1,
}, { }, {
.type = IIO_CONCENTRATION, .type = IIO_CONCENTRATION,
.channel2 = IIO_MOD_CO2, .channel2 = IIO_MOD_CO2,
.modified = 1, .modified = 1,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_OFFSET) | BIT(IIO_CHAN_INFO_OFFSET) |
BIT(IIO_CHAN_INFO_SCALE) BIT(IIO_CHAN_INFO_SCALE),
.scan_index = 0,
.scan_type = {
.sign = 'u',
.realbits = 16,
.storagebits = 16,
.endianness = IIO_BE,
},
}, { }, {
.type = IIO_CONCENTRATION, .type = IIO_CONCENTRATION,
.channel2 = IIO_MOD_VOC, .channel2 = IIO_MOD_VOC,
.modified = 1, .modified = 1,
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_SCALE) BIT(IIO_CHAN_INFO_SCALE),
.scan_index = 1,
.scan_type = {
.sign = 'u',
.realbits = 16,
.storagebits = 16,
.endianness = IIO_BE,
},
}, },
IIO_CHAN_SOFT_TIMESTAMP(2),
}; };
/* /*
...@@ -253,6 +273,31 @@ static const struct iio_info ccs811_info = { ...@@ -253,6 +273,31 @@ static const struct iio_info ccs811_info = {
.driver_module = THIS_MODULE, .driver_module = THIS_MODULE,
}; };
static irqreturn_t ccs811_trigger_handler(int irq, void *p)
{
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct ccs811_data *data = iio_priv(indio_dev);
struct i2c_client *client = data->client;
s16 buf[8]; /* s16 eCO2 + s16 TVOC + padding + 8 byte timestamp */
int ret;
ret = i2c_smbus_read_i2c_block_data(client, CCS811_ALG_RESULT_DATA, 4,
(u8 *)&buf);
if (ret != 4) {
dev_err(&client->dev, "cannot read sensor data\n");
goto err;
}
iio_push_to_buffers_with_timestamp(indio_dev, buf,
iio_get_time_ns(indio_dev));
err:
iio_trigger_notify_done(indio_dev->trig);
return IRQ_HANDLED;
}
static int ccs811_probe(struct i2c_client *client, static int ccs811_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
...@@ -305,7 +350,27 @@ static int ccs811_probe(struct i2c_client *client, ...@@ -305,7 +350,27 @@ static int ccs811_probe(struct i2c_client *client,
indio_dev->channels = ccs811_channels; indio_dev->channels = ccs811_channels;
indio_dev->num_channels = ARRAY_SIZE(ccs811_channels); indio_dev->num_channels = ARRAY_SIZE(ccs811_channels);
return iio_device_register(indio_dev); ret = iio_triggered_buffer_setup(indio_dev, NULL,
ccs811_trigger_handler, NULL);
if (ret < 0) {
dev_err(&client->dev, "triggered buffer setup failed\n");
goto err_poweroff;
}
ret = iio_device_register(indio_dev);
if (ret < 0) {
dev_err(&client->dev, "unable to register iio device\n");
goto err_buffer_cleanup;
}
return 0;
err_buffer_cleanup:
iio_triggered_buffer_cleanup(indio_dev);
err_poweroff:
i2c_smbus_write_byte_data(client, CCS811_MEAS_MODE, CCS811_MODE_IDLE);
return ret;
} }
static int ccs811_remove(struct i2c_client *client) static int ccs811_remove(struct i2c_client *client)
...@@ -313,6 +378,7 @@ static int ccs811_remove(struct i2c_client *client) ...@@ -313,6 +378,7 @@ static int ccs811_remove(struct i2c_client *client)
struct iio_dev *indio_dev = i2c_get_clientdata(client); struct iio_dev *indio_dev = i2c_get_clientdata(client);
iio_device_unregister(indio_dev); iio_device_unregister(indio_dev);
iio_triggered_buffer_cleanup(indio_dev);
return i2c_smbus_write_byte_data(client, CCS811_MEAS_MODE, return i2c_smbus_write_byte_data(client, CCS811_MEAS_MODE,
CCS811_MODE_IDLE); CCS811_MODE_IDLE);
......
...@@ -125,7 +125,7 @@ static int stm32_dac_probe(struct platform_device *pdev) ...@@ -125,7 +125,7 @@ static int stm32_dac_probe(struct platform_device *pdev)
goto err_vref; goto err_vref;
} }
priv->rst = devm_reset_control_get(dev, NULL); priv->rst = devm_reset_control_get_exclusive(dev, NULL);
if (!IS_ERR(priv->rst)) { if (!IS_ERR(priv->rst)) {
reset_control_assert(priv->rst); reset_control_assert(priv->rst);
udelay(2); udelay(2);
......
...@@ -505,7 +505,7 @@ static SIMPLE_DEV_PM_OPS(apds9300_pm_ops, apds9300_suspend, apds9300_resume); ...@@ -505,7 +505,7 @@ static SIMPLE_DEV_PM_OPS(apds9300_pm_ops, apds9300_suspend, apds9300_resume);
#define APDS9300_PM_OPS NULL #define APDS9300_PM_OPS NULL
#endif #endif
static struct i2c_device_id apds9300_id[] = { static const struct i2c_device_id apds9300_id[] = {
{ APDS9300_DRV_NAME, 0 }, { APDS9300_DRV_NAME, 0 },
{ } { }
}; };
......
...@@ -924,7 +924,7 @@ static const struct dev_pm_ops tsl2583_pm_ops = { ...@@ -924,7 +924,7 @@ static const struct dev_pm_ops tsl2583_pm_ops = {
SET_RUNTIME_PM_OPS(tsl2583_suspend, tsl2583_resume, NULL) SET_RUNTIME_PM_OPS(tsl2583_suspend, tsl2583_resume, NULL)
}; };
static struct i2c_device_id tsl2583_idtable[] = { static const struct i2c_device_id tsl2583_idtable[] = {
{ "tsl2580", 0 }, { "tsl2580", 0 },
{ "tsl2581", 1 }, { "tsl2581", 1 },
{ "tsl2583", 2 }, { "tsl2583", 2 },
......
...@@ -13,8 +13,8 @@ config AK8974 ...@@ -13,8 +13,8 @@ config AK8974
select IIO_BUFFER select IIO_BUFFER
select IIO_TRIGGERED_BUFFER select IIO_TRIGGERED_BUFFER
help help
Say yes here to build support for Asahi Kasei AK8974 or Say yes here to build support for Asahi Kasei AK8974, AMI305 or
AMI305 I2C-based 3-axis magnetometer chips. AMI306 I2C-based 3-axis magnetometer chips.
To compile this driver as a module, choose M here: the module To compile this driver as a module, choose M here: the module
will be called ak8974. will be called ak8974.
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <linux/mutex.h> #include <linux/mutex.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/random.h>
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/regulator/consumer.h> #include <linux/regulator/consumer.h>
#include <linux/pm_runtime.h> #include <linux/pm_runtime.h>
...@@ -36,7 +37,7 @@ ...@@ -36,7 +37,7 @@
* and MSB is at the next higher address. * and MSB is at the next higher address.
*/ */
/* These registers are common for AK8974 and AMI305 */ /* These registers are common for AK8974 and AMI30x */
#define AK8974_SELFTEST 0x0C #define AK8974_SELFTEST 0x0C
#define AK8974_SELFTEST_IDLE 0x55 #define AK8974_SELFTEST_IDLE 0x55
#define AK8974_SELFTEST_OK 0xAA #define AK8974_SELFTEST_OK 0xAA
...@@ -44,6 +45,7 @@ ...@@ -44,6 +45,7 @@
#define AK8974_INFO 0x0D #define AK8974_INFO 0x0D
#define AK8974_WHOAMI 0x0F #define AK8974_WHOAMI 0x0F
#define AK8974_WHOAMI_VALUE_AMI306 0x46
#define AK8974_WHOAMI_VALUE_AMI305 0x47 #define AK8974_WHOAMI_VALUE_AMI305 0x47
#define AK8974_WHOAMI_VALUE_AK8974 0x48 #define AK8974_WHOAMI_VALUE_AK8974 0x48
...@@ -73,6 +75,35 @@ ...@@ -73,6 +75,35 @@
#define AK8974_TEMP 0x31 #define AK8974_TEMP 0x31
#define AMI305_TEMP 0x60 #define AMI305_TEMP 0x60
/* AMI306-specific control register */
#define AMI306_CTRL4 0x5C
/* AMI306 factory calibration data */
/* fine axis sensitivity */
#define AMI306_FINEOUTPUT_X 0x90
#define AMI306_FINEOUTPUT_Y 0x92
#define AMI306_FINEOUTPUT_Z 0x94
/* axis sensitivity */
#define AMI306_SENS_X 0x96
#define AMI306_SENS_Y 0x98
#define AMI306_SENS_Z 0x9A
/* axis cross-interference */
#define AMI306_GAIN_PARA_XZ 0x9C
#define AMI306_GAIN_PARA_XY 0x9D
#define AMI306_GAIN_PARA_YZ 0x9E
#define AMI306_GAIN_PARA_YX 0x9F
#define AMI306_GAIN_PARA_ZY 0xA0
#define AMI306_GAIN_PARA_ZX 0xA1
/* offset at ZERO magnetic field */
#define AMI306_OFFZERO_X 0xF8
#define AMI306_OFFZERO_Y 0xFA
#define AMI306_OFFZERO_Z 0xFC
#define AK8974_INT_X_HIGH BIT(7) /* Axis over +threshold */ #define AK8974_INT_X_HIGH BIT(7) /* Axis over +threshold */
#define AK8974_INT_Y_HIGH BIT(6) #define AK8974_INT_Y_HIGH BIT(6)
#define AK8974_INT_Z_HIGH BIT(5) #define AK8974_INT_Z_HIGH BIT(5)
...@@ -158,6 +189,26 @@ struct ak8974 { ...@@ -158,6 +189,26 @@ struct ak8974 {
static const char ak8974_reg_avdd[] = "avdd"; static const char ak8974_reg_avdd[] = "avdd";
static const char ak8974_reg_dvdd[] = "dvdd"; static const char ak8974_reg_dvdd[] = "dvdd";
static int ak8974_get_u16_val(struct ak8974 *ak8974, u8 reg, u16 *val)
{
int ret;
__le16 bulk;
ret = regmap_bulk_read(ak8974->map, reg, &bulk, 2);
if (ret)
return ret;
*val = le16_to_cpu(bulk);
return 0;
}
static int ak8974_set_u16_val(struct ak8974 *ak8974, u8 reg, u16 val)
{
__le16 bulk = cpu_to_le16(val);
return regmap_bulk_write(ak8974->map, reg, &bulk, 2);
}
static int ak8974_set_power(struct ak8974 *ak8974, bool mode) static int ak8974_set_power(struct ak8974 *ak8974, bool mode)
{ {
int ret; int ret;
...@@ -209,6 +260,12 @@ static int ak8974_configure(struct ak8974 *ak8974) ...@@ -209,6 +260,12 @@ static int ak8974_configure(struct ak8974 *ak8974)
ret = regmap_write(ak8974->map, AK8974_CTRL3, 0); ret = regmap_write(ak8974->map, AK8974_CTRL3, 0);
if (ret) if (ret)
return ret; return ret;
if (ak8974->variant == AK8974_WHOAMI_VALUE_AMI306) {
/* magic from datasheet: set high-speed measurement mode */
ret = ak8974_set_u16_val(ak8974, AMI306_CTRL4, 0xA07E);
if (ret)
return ret;
}
ret = regmap_write(ak8974->map, AK8974_INT_CTRL, AK8974_INT_CTRL_POL); ret = regmap_write(ak8974->map, AK8974_INT_CTRL, AK8974_INT_CTRL_POL);
if (ret) if (ret)
return ret; return ret;
...@@ -388,17 +445,18 @@ static int ak8974_selftest(struct ak8974 *ak8974) ...@@ -388,17 +445,18 @@ static int ak8974_selftest(struct ak8974 *ak8974)
return 0; return 0;
} }
static int ak8974_get_u16_val(struct ak8974 *ak8974, u8 reg, u16 *val) static void ak8974_read_calib_data(struct ak8974 *ak8974, unsigned int reg,
__le16 *tab, size_t tab_size)
{ {
int ret; int ret = regmap_bulk_read(ak8974->map, reg, tab, tab_size);
__le16 bulk; if (ret) {
memset(tab, 0xFF, tab_size);
ret = regmap_bulk_read(ak8974->map, reg, &bulk, 2); dev_warn(&ak8974->i2c->dev,
if (ret) "can't read calibration data (regs %u..%zu): %d\n",
return ret; reg, reg + tab_size - 1, ret);
*val = le16_to_cpu(bulk); } else {
add_device_randomness(tab, tab_size);
return 0; }
} }
static int ak8974_detect(struct ak8974 *ak8974) static int ak8974_detect(struct ak8974 *ak8974)
...@@ -413,9 +471,13 @@ static int ak8974_detect(struct ak8974 *ak8974) ...@@ -413,9 +471,13 @@ static int ak8974_detect(struct ak8974 *ak8974)
if (ret) if (ret)
return ret; return ret;
name = "ami305";
switch (whoami) { switch (whoami) {
case AK8974_WHOAMI_VALUE_AMI306:
name = "ami306";
/* fall-through */
case AK8974_WHOAMI_VALUE_AMI305: case AK8974_WHOAMI_VALUE_AMI305:
name = "ami305";
ret = regmap_read(ak8974->map, AMI305_VER, &fw); ret = regmap_read(ak8974->map, AMI305_VER, &fw);
if (ret) if (ret)
return ret; return ret;
...@@ -423,6 +485,7 @@ static int ak8974_detect(struct ak8974 *ak8974) ...@@ -423,6 +485,7 @@ static int ak8974_detect(struct ak8974 *ak8974)
ret = ak8974_get_u16_val(ak8974, AMI305_SN, &sn); ret = ak8974_get_u16_val(ak8974, AMI305_SN, &sn);
if (ret) if (ret)
return ret; return ret;
add_device_randomness(&sn, sizeof(sn));
dev_info(&ak8974->i2c->dev, dev_info(&ak8974->i2c->dev,
"detected %s, FW ver %02x, S/N: %04x\n", "detected %s, FW ver %02x, S/N: %04x\n",
name, fw, sn); name, fw, sn);
...@@ -440,6 +503,33 @@ static int ak8974_detect(struct ak8974 *ak8974) ...@@ -440,6 +503,33 @@ static int ak8974_detect(struct ak8974 *ak8974)
ak8974->name = name; ak8974->name = name;
ak8974->variant = whoami; ak8974->variant = whoami;
if (whoami == AK8974_WHOAMI_VALUE_AMI306) {
__le16 fab_data1[9], fab_data2[3];
int i;
ak8974_read_calib_data(ak8974, AMI306_FINEOUTPUT_X,
fab_data1, sizeof(fab_data1));
ak8974_read_calib_data(ak8974, AMI306_OFFZERO_X,
fab_data2, sizeof(fab_data2));
for (i = 0; i < 3; ++i) {
static const char axis[3] = "XYZ";
static const char pgaxis[6] = "ZYZXYX";
unsigned offz = le16_to_cpu(fab_data2[i]) & 0x7F;
unsigned fine = le16_to_cpu(fab_data1[i]);
unsigned sens = le16_to_cpu(fab_data1[i + 3]);
unsigned pgain1 = le16_to_cpu(fab_data1[i + 6]);
unsigned pgain2 = pgain1 >> 8;
pgain1 &= 0xFF;
dev_info(&ak8974->i2c->dev,
"factory calibration for axis %c: offz=%u sens=%u fine=%u pga%c=%u pga%c=%u\n",
axis[i], offz, sens, fine, pgaxis[i * 2],
pgain1, pgaxis[i * 2 + 1], pgain2);
}
}
return 0; return 0;
} }
...@@ -602,19 +692,27 @@ static bool ak8974_writeable_reg(struct device *dev, unsigned int reg) ...@@ -602,19 +692,27 @@ static bool ak8974_writeable_reg(struct device *dev, unsigned int reg)
case AMI305_OFFSET_Y + 1: case AMI305_OFFSET_Y + 1:
case AMI305_OFFSET_Z: case AMI305_OFFSET_Z:
case AMI305_OFFSET_Z + 1: case AMI305_OFFSET_Z + 1:
if (ak8974->variant == AK8974_WHOAMI_VALUE_AMI305) return ak8974->variant == AK8974_WHOAMI_VALUE_AMI305 ||
return true; ak8974->variant == AK8974_WHOAMI_VALUE_AMI306;
return false; case AMI306_CTRL4:
case AMI306_CTRL4 + 1:
return ak8974->variant == AK8974_WHOAMI_VALUE_AMI306;
default: default:
return false; return false;
} }
} }
static bool ak8974_precious_reg(struct device *dev, unsigned int reg)
{
return reg == AK8974_INT_CLEAR;
}
static const struct regmap_config ak8974_regmap_config = { static const struct regmap_config ak8974_regmap_config = {
.reg_bits = 8, .reg_bits = 8,
.val_bits = 8, .val_bits = 8,
.max_register = 0xff, .max_register = 0xff,
.writeable_reg = ak8974_writeable_reg, .writeable_reg = ak8974_writeable_reg,
.precious_reg = ak8974_precious_reg,
}; };
static int ak8974_probe(struct i2c_client *i2c, static int ak8974_probe(struct i2c_client *i2c,
...@@ -678,7 +776,7 @@ static int ak8974_probe(struct i2c_client *i2c, ...@@ -678,7 +776,7 @@ static int ak8974_probe(struct i2c_client *i2c,
ret = ak8974_detect(ak8974); ret = ak8974_detect(ak8974);
if (ret) { if (ret) {
dev_err(&i2c->dev, "neither AK8974 nor AMI305 found\n"); dev_err(&i2c->dev, "neither AK8974 nor AMI30x found\n");
goto power_off; goto power_off;
} }
...@@ -827,6 +925,7 @@ static const struct dev_pm_ops ak8974_dev_pm_ops = { ...@@ -827,6 +925,7 @@ static const struct dev_pm_ops ak8974_dev_pm_ops = {
static const struct i2c_device_id ak8974_id[] = { static const struct i2c_device_id ak8974_id[] = {
{"ami305", 0 }, {"ami305", 0 },
{"ami306", 0 },
{"ak8974", 0 }, {"ak8974", 0 },
{} {}
}; };
...@@ -850,7 +949,7 @@ static struct i2c_driver ak8974_driver = { ...@@ -850,7 +949,7 @@ static struct i2c_driver ak8974_driver = {
}; };
module_i2c_driver(ak8974_driver); module_i2c_driver(ak8974_driver);
MODULE_DESCRIPTION("AK8974 and AMI305 3-axis magnetometer driver"); MODULE_DESCRIPTION("AK8974 and AMI30x 3-axis magnetometer driver");
MODULE_AUTHOR("Samu Onkalo"); MODULE_AUTHOR("Samu Onkalo");
MODULE_AUTHOR("Linus Walleij"); MODULE_AUTHOR("Linus Walleij");
MODULE_LICENSE("GPL v2"); MODULE_LICENSE("GPL v2");
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#define LSM303DLM_MAGN_DEV_NAME "lsm303dlm_magn" #define LSM303DLM_MAGN_DEV_NAME "lsm303dlm_magn"
#define LIS3MDL_MAGN_DEV_NAME "lis3mdl" #define LIS3MDL_MAGN_DEV_NAME "lis3mdl"
#define LSM303AGR_MAGN_DEV_NAME "lsm303agr_magn" #define LSM303AGR_MAGN_DEV_NAME "lsm303agr_magn"
#define LIS2MDL_MAGN_DEV_NAME "lis2mdl"
int st_magn_common_probe(struct iio_dev *indio_dev); int st_magn_common_probe(struct iio_dev *indio_dev);
void st_magn_common_remove(struct iio_dev *indio_dev); void st_magn_common_remove(struct iio_dev *indio_dev);
......
...@@ -323,6 +323,7 @@ static const struct st_sensor_settings st_magn_sensors_settings[] = { ...@@ -323,6 +323,7 @@ static const struct st_sensor_settings st_magn_sensors_settings[] = {
.wai_addr = 0x4f, .wai_addr = 0x4f,
.sensors_supported = { .sensors_supported = {
[0] = LSM303AGR_MAGN_DEV_NAME, [0] = LSM303AGR_MAGN_DEV_NAME,
[1] = LIS2MDL_MAGN_DEV_NAME,
}, },
.ch = (struct iio_chan_spec *)st_magn_3_16bit_channels, .ch = (struct iio_chan_spec *)st_magn_3_16bit_channels,
.odr = { .odr = {
......
...@@ -40,6 +40,10 @@ static const struct of_device_id st_magn_of_match[] = { ...@@ -40,6 +40,10 @@ static const struct of_device_id st_magn_of_match[] = {
.compatible = "st,lsm303agr-magn", .compatible = "st,lsm303agr-magn",
.data = LSM303AGR_MAGN_DEV_NAME, .data = LSM303AGR_MAGN_DEV_NAME,
}, },
{
.compatible = "st,lis2mdl",
.data = LIS2MDL_MAGN_DEV_NAME,
},
{}, {},
}; };
MODULE_DEVICE_TABLE(of, st_magn_of_match); MODULE_DEVICE_TABLE(of, st_magn_of_match);
...@@ -85,6 +89,7 @@ static const struct i2c_device_id st_magn_id_table[] = { ...@@ -85,6 +89,7 @@ static const struct i2c_device_id st_magn_id_table[] = {
{ LSM303DLM_MAGN_DEV_NAME }, { LSM303DLM_MAGN_DEV_NAME },
{ LIS3MDL_MAGN_DEV_NAME }, { LIS3MDL_MAGN_DEV_NAME },
{ LSM303AGR_MAGN_DEV_NAME }, { LSM303AGR_MAGN_DEV_NAME },
{ LIS2MDL_MAGN_DEV_NAME },
{}, {},
}; };
MODULE_DEVICE_TABLE(i2c, st_magn_id_table); MODULE_DEVICE_TABLE(i2c, st_magn_id_table);
......
...@@ -33,6 +33,10 @@ static const struct of_device_id st_magn_of_match[] = { ...@@ -33,6 +33,10 @@ static const struct of_device_id st_magn_of_match[] = {
.compatible = "st,lsm303agr-magn", .compatible = "st,lsm303agr-magn",
.data = LSM303AGR_MAGN_DEV_NAME, .data = LSM303AGR_MAGN_DEV_NAME,
}, },
{
.compatible = "st,lis2mdl",
.data = LIS2MDL_MAGN_DEV_NAME,
},
{} {}
}; };
MODULE_DEVICE_TABLE(of, st_magn_of_match); MODULE_DEVICE_TABLE(of, st_magn_of_match);
...@@ -74,6 +78,7 @@ static int st_magn_spi_remove(struct spi_device *spi) ...@@ -74,6 +78,7 @@ static int st_magn_spi_remove(struct spi_device *spi)
static const struct spi_device_id st_magn_id_table[] = { static const struct spi_device_id st_magn_id_table[] = {
{ LIS3MDL_MAGN_DEV_NAME }, { LIS3MDL_MAGN_DEV_NAME },
{ LSM303AGR_MAGN_DEV_NAME }, { LSM303AGR_MAGN_DEV_NAME },
{ LIS2MDL_MAGN_DEV_NAME },
{}, {},
}; };
MODULE_DEVICE_TABLE(spi, st_magn_id_table); MODULE_DEVICE_TABLE(spi, st_magn_id_table);
......
...@@ -390,7 +390,7 @@ static const struct st_sensor_settings st_press_sensors_settings[] = { ...@@ -390,7 +390,7 @@ static const struct st_sensor_settings st_press_sensors_settings[] = {
.drdy_irq = { .drdy_irq = {
.addr = 0x23, .addr = 0x23,
.mask_int1 = 0x01, .mask_int1 = 0x01,
.mask_int2 = 0x10, .mask_int2 = 0x00,
.addr_ihl = 0x22, .addr_ihl = 0x22,
.mask_ihl = 0x80, .mask_ihl = 0x80,
.addr_od = 0x22, .addr_od = 0x22,
...@@ -449,7 +449,7 @@ static const struct st_sensor_settings st_press_sensors_settings[] = { ...@@ -449,7 +449,7 @@ static const struct st_sensor_settings st_press_sensors_settings[] = {
.drdy_irq = { .drdy_irq = {
.addr = 0x12, .addr = 0x12,
.mask_int1 = 0x04, .mask_int1 = 0x04,
.mask_int2 = 0x08, .mask_int2 = 0x00,
.addr_ihl = 0x12, .addr_ihl = 0x12,
.mask_ihl = 0x80, .mask_ihl = 0x80,
.addr_od = 0x12, .addr_od = 0x12,
......
...@@ -57,12 +57,12 @@ config SX9500 ...@@ -57,12 +57,12 @@ config SX9500
module will be called sx9500. module will be called sx9500.
config SRF08 config SRF08
tristate "Devantech SRF08 ultrasonic ranger sensor" tristate "Devantech SRF02/SRF08/SRF10 ultrasonic ranger sensor"
depends on I2C depends on I2C
help help
Say Y here to build a driver for Devantech SRF08 ultrasonic Say Y here to build a driver for Devantech SRF02/SRF08/SRF10
ranger sensor. This driver can be used to measure the distance ultrasonic ranger sensors with i2c interface.
of objects. This driver can be used to measure the distance of objects.
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called srf08. module will be called srf08.
......
/* /*
* srf08.c - Support for Devantech SRF08 ultrasonic ranger * srf08.c - Support for Devantech SRFxx ultrasonic ranger
* with i2c interface
* actually supported are srf02, srf08, srf10
* *
* Copyright (c) 2016 Andreas Klinger <ak@it-klinger.de> * Copyright (c) 2016, 2017 Andreas Klinger <ak@it-klinger.de>
* *
* This file is subject to the terms and conditions of version 2 of * This file is subject to the terms and conditions of version 2 of
* the GNU General Public License. See the file COPYING in the main * the GNU General Public License. See the file COPYING in the main
* directory of this archive for more details. * directory of this archive for more details.
* *
* For details about the device see: * For details about the device see:
* http://www.robot-electronics.co.uk/htm/srf08tech.html * http://www.robot-electronics.co.uk/htm/srf08tech.html
* http://www.robot-electronics.co.uk/htm/srf10tech.htm
* http://www.robot-electronics.co.uk/htm/srf02tech.htm
*/ */
#include <linux/err.h> #include <linux/err.h>
...@@ -18,6 +22,9 @@ ...@@ -18,6 +22,9 @@
#include <linux/bitops.h> #include <linux/bitops.h>
#include <linux/iio/iio.h> #include <linux/iio/iio.h>
#include <linux/iio/sysfs.h> #include <linux/iio/sysfs.h>
#include <linux/iio/buffer.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>
/* registers of SRF08 device */ /* registers of SRF08 device */
#define SRF08_WRITE_COMMAND 0x00 /* Command Register */ #define SRF08_WRITE_COMMAND 0x00 /* Command Register */
...@@ -30,14 +37,46 @@ ...@@ -30,14 +37,46 @@
#define SRF08_CMD_RANGING_CM 0x51 /* Ranging Mode - Result in cm */ #define SRF08_CMD_RANGING_CM 0x51 /* Ranging Mode - Result in cm */
#define SRF08_DEFAULT_GAIN 1025 /* default analogue value of Gain */ enum srf08_sensor_type {
#define SRF08_DEFAULT_RANGE 6020 /* default value of Range in mm */ SRF02,
SRF08,
SRF10,
SRF_MAX_TYPE
};
struct srf08_chip_info {
const int *sensitivity_avail;
int num_sensitivity_avail;
int sensitivity_default;
/* default value of Range in mm */
int range_default;
};
struct srf08_data { struct srf08_data {
struct i2c_client *client; struct i2c_client *client;
int sensitivity; /* Gain */
int range_mm; /* max. Range in mm */ /*
* Gain in the datasheet is called sensitivity here to distinct it
* from the gain used with amplifiers of adc's
*/
int sensitivity;
/* max. Range in mm */
int range_mm;
struct mutex lock; struct mutex lock;
/*
* triggered buffer
* 1x16-bit channel + 3x16 padding + 4x16 timestamp
*/
s16 buffer[8];
/* Sensor-Type */
enum srf08_sensor_type sensor_type;
/* Chip-specific information */
const struct srf08_chip_info *chip_info;
}; };
/* /*
...@@ -47,11 +86,42 @@ struct srf08_data { ...@@ -47,11 +86,42 @@ struct srf08_data {
* But with ADC's this term is already used differently and that's why it * But with ADC's this term is already used differently and that's why it
* is called "Sensitivity" here. * is called "Sensitivity" here.
*/ */
static const int srf08_sensitivity[] = { static const struct srf08_chip_info srf02_chip_info = {
.sensitivity_avail = NULL,
.num_sensitivity_avail = 0,
.sensitivity_default = 0,
.range_default = 0,
};
static const int srf08_sensitivity_avail[] = {
94, 97, 100, 103, 107, 110, 114, 118, 94, 97, 100, 103, 107, 110, 114, 118,
123, 128, 133, 139, 145, 152, 159, 168, 123, 128, 133, 139, 145, 152, 159, 168,
177, 187, 199, 212, 227, 245, 265, 288, 177, 187, 199, 212, 227, 245, 265, 288,
317, 352, 395, 450, 524, 626, 777, 1025 }; 317, 352, 395, 450, 524, 626, 777, 1025
};
static const struct srf08_chip_info srf08_chip_info = {
.sensitivity_avail = srf08_sensitivity_avail,
.num_sensitivity_avail = ARRAY_SIZE(srf08_sensitivity_avail),
.sensitivity_default = 1025,
.range_default = 6020,
};
static const int srf10_sensitivity_avail[] = {
40, 40, 50, 60, 70, 80, 100, 120,
140, 200, 250, 300, 350, 400, 500, 600,
700,
};
static const struct srf08_chip_info srf10_chip_info = {
.sensitivity_avail = srf10_sensitivity_avail,
.num_sensitivity_avail = ARRAY_SIZE(srf10_sensitivity_avail),
.sensitivity_default = 700,
.range_default = 6020,
};
static int srf08_read_ranging(struct srf08_data *data) static int srf08_read_ranging(struct srf08_data *data)
{ {
...@@ -110,6 +180,29 @@ static int srf08_read_ranging(struct srf08_data *data) ...@@ -110,6 +180,29 @@ static int srf08_read_ranging(struct srf08_data *data)
return ret; return ret;
} }
static irqreturn_t srf08_trigger_handler(int irq, void *p)
{
struct iio_poll_func *pf = p;
struct iio_dev *indio_dev = pf->indio_dev;
struct srf08_data *data = iio_priv(indio_dev);
s16 sensor_data;
sensor_data = srf08_read_ranging(data);
if (sensor_data < 0)
goto err;
mutex_lock(&data->lock);
data->buffer[0] = sensor_data;
iio_push_to_buffers_with_timestamp(indio_dev,
data->buffer, pf->timestamp);
mutex_unlock(&data->lock);
err:
iio_trigger_notify_done(indio_dev->trig);
return IRQ_HANDLED;
}
static int srf08_read_raw(struct iio_dev *indio_dev, static int srf08_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *channel, int *val, struct iio_chan_spec const *channel, int *val,
int *val2, long mask) int *val2, long mask)
...@@ -225,9 +318,13 @@ static ssize_t srf08_show_sensitivity_available(struct device *dev, ...@@ -225,9 +318,13 @@ static ssize_t srf08_show_sensitivity_available(struct device *dev,
struct device_attribute *attr, char *buf) struct device_attribute *attr, char *buf)
{ {
int i, len = 0; int i, len = 0;
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
struct srf08_data *data = iio_priv(indio_dev);
for (i = 0; i < ARRAY_SIZE(srf08_sensitivity); i++) for (i = 0; i < data->chip_info->num_sensitivity_avail; i++)
len += sprintf(buf + len, "%d ", srf08_sensitivity[i]); if (data->chip_info->sensitivity_avail[i])
len += sprintf(buf + len, "%d ",
data->chip_info->sensitivity_avail[i]);
len += sprintf(buf + len, "\n"); len += sprintf(buf + len, "\n");
...@@ -256,19 +353,21 @@ static ssize_t srf08_write_sensitivity(struct srf08_data *data, ...@@ -256,19 +353,21 @@ static ssize_t srf08_write_sensitivity(struct srf08_data *data,
int ret, i; int ret, i;
u8 regval; u8 regval;
for (i = 0; i < ARRAY_SIZE(srf08_sensitivity); i++) if (!val)
if (val == srf08_sensitivity[i]) { return -EINVAL;
for (i = 0; i < data->chip_info->num_sensitivity_avail; i++)
if (val && (val == data->chip_info->sensitivity_avail[i])) {
regval = i; regval = i;
break; break;
} }
if (i >= ARRAY_SIZE(srf08_sensitivity)) if (i >= data->chip_info->num_sensitivity_avail)
return -EINVAL; return -EINVAL;
mutex_lock(&data->lock); mutex_lock(&data->lock);
ret = i2c_smbus_write_byte_data(client, ret = i2c_smbus_write_byte_data(client, SRF08_WRITE_MAX_GAIN, regval);
SRF08_WRITE_MAX_GAIN, regval);
if (ret < 0) { if (ret < 0) {
dev_err(&client->dev, "write_sensitivity - err: %d\n", ret); dev_err(&client->dev, "write_sensitivity - err: %d\n", ret);
mutex_unlock(&data->lock); mutex_unlock(&data->lock);
...@@ -323,7 +422,15 @@ static const struct iio_chan_spec srf08_channels[] = { ...@@ -323,7 +422,15 @@ static const struct iio_chan_spec srf08_channels[] = {
.info_mask_separate = .info_mask_separate =
BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_RAW) |
BIT(IIO_CHAN_INFO_SCALE), BIT(IIO_CHAN_INFO_SCALE),
.scan_index = 0,
.scan_type = {
.sign = 's',
.realbits = 16,
.storagebits = 16,
.endianness = IIO_CPU,
},
}, },
IIO_CHAN_SOFT_TIMESTAMP(1),
}; };
static const struct iio_info srf08_info = { static const struct iio_info srf08_info = {
...@@ -332,6 +439,15 @@ static const struct iio_info srf08_info = { ...@@ -332,6 +439,15 @@ static const struct iio_info srf08_info = {
.driver_module = THIS_MODULE, .driver_module = THIS_MODULE,
}; };
/*
* srf02 don't have an adjustable range or sensitivity,
* so we don't need attributes at all
*/
static const struct iio_info srf02_info = {
.read_raw = srf08_read_raw,
.driver_module = THIS_MODULE,
};
static int srf08_probe(struct i2c_client *client, static int srf08_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
...@@ -352,34 +468,84 @@ static int srf08_probe(struct i2c_client *client, ...@@ -352,34 +468,84 @@ static int srf08_probe(struct i2c_client *client,
data = iio_priv(indio_dev); data = iio_priv(indio_dev);
i2c_set_clientdata(client, indio_dev); i2c_set_clientdata(client, indio_dev);
data->client = client; data->client = client;
data->sensor_type = (enum srf08_sensor_type)id->driver_data;
switch (data->sensor_type) {
case SRF02:
data->chip_info = &srf02_chip_info;
indio_dev->info = &srf02_info;
break;
case SRF08:
data->chip_info = &srf08_chip_info;
indio_dev->info = &srf08_info;
break;
case SRF10:
data->chip_info = &srf10_chip_info;
indio_dev->info = &srf08_info;
break;
default:
return -EINVAL;
}
indio_dev->name = "srf08"; indio_dev->name = id->name;
indio_dev->dev.parent = &client->dev; indio_dev->dev.parent = &client->dev;
indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->modes = INDIO_DIRECT_MODE;
indio_dev->info = &srf08_info;
indio_dev->channels = srf08_channels; indio_dev->channels = srf08_channels;
indio_dev->num_channels = ARRAY_SIZE(srf08_channels); indio_dev->num_channels = ARRAY_SIZE(srf08_channels);
mutex_init(&data->lock); mutex_init(&data->lock);
/* ret = devm_iio_triggered_buffer_setup(&client->dev, indio_dev,
* set default values of device here iio_pollfunc_store_time, srf08_trigger_handler, NULL);
* these register values cannot be read from the hardware if (ret < 0) {
* therefore set driver specific default values dev_err(&client->dev, "setup of iio triggered buffer failed\n");
*/
ret = srf08_write_range_mm(data, SRF08_DEFAULT_RANGE);
if (ret < 0)
return ret; return ret;
}
ret = srf08_write_sensitivity(data, SRF08_DEFAULT_GAIN); if (data->chip_info->range_default) {
if (ret < 0) /*
return ret; * set default range of device in mm here
* these register values cannot be read from the hardware
* therefore set driver specific default values
*
* srf02 don't have a default value so it'll be omitted
*/
ret = srf08_write_range_mm(data,
data->chip_info->range_default);
if (ret < 0)
return ret;
}
if (data->chip_info->sensitivity_default) {
/*
* set default sensitivity of device here
* these register values cannot be read from the hardware
* therefore set driver specific default values
*
* srf02 don't have a default value so it'll be omitted
*/
ret = srf08_write_sensitivity(data,
data->chip_info->sensitivity_default);
if (ret < 0)
return ret;
}
return devm_iio_device_register(&client->dev, indio_dev); return devm_iio_device_register(&client->dev, indio_dev);
} }
static const struct of_device_id of_srf08_match[] = {
{ .compatible = "devantech,srf02", (void *)SRF02},
{ .compatible = "devantech,srf08", (void *)SRF08},
{ .compatible = "devantech,srf10", (void *)SRF10},
{},
};
MODULE_DEVICE_TABLE(of, of_srf08_match);
static const struct i2c_device_id srf08_id[] = { static const struct i2c_device_id srf08_id[] = {
{ "srf08", 0 }, { "srf02", SRF02 },
{ "srf08", SRF08 },
{ "srf10", SRF10 },
{ } { }
}; };
MODULE_DEVICE_TABLE(i2c, srf08_id); MODULE_DEVICE_TABLE(i2c, srf08_id);
...@@ -387,6 +553,7 @@ MODULE_DEVICE_TABLE(i2c, srf08_id); ...@@ -387,6 +553,7 @@ MODULE_DEVICE_TABLE(i2c, srf08_id);
static struct i2c_driver srf08_driver = { static struct i2c_driver srf08_driver = {
.driver = { .driver = {
.name = "srf08", .name = "srf08",
.of_match_table = of_srf08_match,
}, },
.probe = srf08_probe, .probe = srf08_probe,
.id_table = srf08_id, .id_table = srf08_id,
...@@ -394,5 +561,5 @@ static struct i2c_driver srf08_driver = { ...@@ -394,5 +561,5 @@ static struct i2c_driver srf08_driver = {
module_i2c_driver(srf08_driver); module_i2c_driver(srf08_driver);
MODULE_AUTHOR("Andreas Klinger <ak@it-klinger.de>"); MODULE_AUTHOR("Andreas Klinger <ak@it-klinger.de>");
MODULE_DESCRIPTION("Devantech SRF08 ultrasonic ranger driver"); MODULE_DESCRIPTION("Devantech SRF02/SRF08/SRF10 i2c ultrasonic ranger driver");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#include <linux/mfd/stm32-timers.h> #include <linux/mfd/stm32-timers.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/of_device.h>
#define MAX_TRIGGERS 7 #define MAX_TRIGGERS 7
#define MAX_VALIDS 5 #define MAX_VALIDS 5
...@@ -28,9 +29,14 @@ static const void *triggers_table[][MAX_TRIGGERS] = { ...@@ -28,9 +29,14 @@ static const void *triggers_table[][MAX_TRIGGERS] = {
{ TIM7_TRGO,}, { TIM7_TRGO,},
{ TIM8_TRGO, TIM8_TRGO2, TIM8_CH1, TIM8_CH2, TIM8_CH3, TIM8_CH4,}, { TIM8_TRGO, TIM8_TRGO2, TIM8_CH1, TIM8_CH2, TIM8_CH3, TIM8_CH4,},
{ TIM9_TRGO, TIM9_CH1, TIM9_CH2,}, { TIM9_TRGO, TIM9_CH1, TIM9_CH2,},
{ }, /* timer 10 */ { TIM10_OC1,},
{ }, /* timer 11 */ { TIM11_OC1,},
{ TIM12_TRGO, TIM12_CH1, TIM12_CH2,}, { TIM12_TRGO, TIM12_CH1, TIM12_CH2,},
{ TIM13_OC1,},
{ TIM14_OC1,},
{ TIM15_TRGO,},
{ TIM16_OC1,},
{ TIM17_OC1,},
}; };
/* List the triggers accepted by each timer */ /* List the triggers accepted by each timer */
...@@ -43,10 +49,30 @@ static const void *valids_table[][MAX_VALIDS] = { ...@@ -43,10 +49,30 @@ static const void *valids_table[][MAX_VALIDS] = {
{ }, /* timer 6 */ { }, /* timer 6 */
{ }, /* timer 7 */ { }, /* timer 7 */
{ TIM1_TRGO, TIM2_TRGO, TIM4_TRGO, TIM5_TRGO,}, { TIM1_TRGO, TIM2_TRGO, TIM4_TRGO, TIM5_TRGO,},
{ TIM2_TRGO, TIM3_TRGO,}, { TIM2_TRGO, TIM3_TRGO, TIM10_OC1, TIM11_OC1,},
{ }, /* timer 10 */
{ }, /* timer 11 */
{ TIM4_TRGO, TIM5_TRGO, TIM13_OC1, TIM14_OC1,},
};
static const void *stm32h7_valids_table[][MAX_VALIDS] = {
{ TIM15_TRGO, TIM2_TRGO, TIM3_TRGO, TIM4_TRGO,},
{ TIM1_TRGO, TIM8_TRGO, TIM3_TRGO, TIM4_TRGO,},
{ TIM1_TRGO, TIM2_TRGO, TIM15_TRGO, TIM4_TRGO,},
{ TIM1_TRGO, TIM2_TRGO, TIM3_TRGO, TIM8_TRGO,},
{ TIM1_TRGO, TIM8_TRGO, TIM3_TRGO, TIM4_TRGO,},
{ }, /* timer 6 */
{ }, /* timer 7 */
{ TIM1_TRGO, TIM2_TRGO, TIM4_TRGO, TIM5_TRGO,},
{ }, /* timer 9 */
{ }, /* timer 10 */ { }, /* timer 10 */
{ }, /* timer 11 */ { }, /* timer 11 */
{ TIM4_TRGO, TIM5_TRGO,}, { TIM4_TRGO, TIM5_TRGO, TIM13_OC1, TIM14_OC1,},
{ }, /* timer 13 */
{ }, /* timer 14 */
{ TIM1_TRGO, TIM3_TRGO, TIM16_OC1, TIM17_OC1,},
{ }, /* timer 16 */
{ }, /* timer 17 */
}; };
struct stm32_timer_trigger { struct stm32_timer_trigger {
...@@ -59,11 +85,21 @@ struct stm32_timer_trigger { ...@@ -59,11 +85,21 @@ struct stm32_timer_trigger {
bool has_trgo2; bool has_trgo2;
}; };
struct stm32_timer_trigger_cfg {
const void *(*valids_table)[MAX_VALIDS];
const unsigned int num_valids_table;
};
static bool stm32_timer_is_trgo2_name(const char *name) static bool stm32_timer_is_trgo2_name(const char *name)
{ {
return !!strstr(name, "trgo2"); return !!strstr(name, "trgo2");
} }
static bool stm32_timer_is_trgo_name(const char *name)
{
return (!!strstr(name, "trgo") && !strstr(name, "trgo2"));
}
static int stm32_timer_start(struct stm32_timer_trigger *priv, static int stm32_timer_start(struct stm32_timer_trigger *priv,
struct iio_trigger *trig, struct iio_trigger *trig,
unsigned int frequency) unsigned int frequency)
...@@ -328,6 +364,7 @@ static int stm32_setup_iio_triggers(struct stm32_timer_trigger *priv) ...@@ -328,6 +364,7 @@ static int stm32_setup_iio_triggers(struct stm32_timer_trigger *priv)
while (cur && *cur) { while (cur && *cur) {
struct iio_trigger *trig; struct iio_trigger *trig;
bool cur_is_trgo = stm32_timer_is_trgo_name(*cur);
bool cur_is_trgo2 = stm32_timer_is_trgo2_name(*cur); bool cur_is_trgo2 = stm32_timer_is_trgo2_name(*cur);
if (cur_is_trgo2 && !priv->has_trgo2) { if (cur_is_trgo2 && !priv->has_trgo2) {
...@@ -344,10 +381,9 @@ static int stm32_setup_iio_triggers(struct stm32_timer_trigger *priv) ...@@ -344,10 +381,9 @@ static int stm32_setup_iio_triggers(struct stm32_timer_trigger *priv)
/* /*
* sampling frequency and master mode attributes * sampling frequency and master mode attributes
* should only be available on trgo trigger which * should only be available on trgo/trgo2 triggers
* is always the first in the list.
*/ */
if (cur == priv->triggers || cur_is_trgo2) if (cur_is_trgo || cur_is_trgo2)
trig->dev.groups = stm32_trigger_attr_groups; trig->dev.groups = stm32_trigger_attr_groups;
iio_trigger_set_drvdata(trig, priv); iio_trigger_set_drvdata(trig, priv);
...@@ -734,18 +770,22 @@ static int stm32_timer_trigger_probe(struct platform_device *pdev) ...@@ -734,18 +770,22 @@ static int stm32_timer_trigger_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct stm32_timer_trigger *priv; struct stm32_timer_trigger *priv;
struct stm32_timers *ddata = dev_get_drvdata(pdev->dev.parent); struct stm32_timers *ddata = dev_get_drvdata(pdev->dev.parent);
const struct stm32_timer_trigger_cfg *cfg;
unsigned int index; unsigned int index;
int ret; int ret;
if (of_property_read_u32(dev->of_node, "reg", &index)) if (of_property_read_u32(dev->of_node, "reg", &index))
return -EINVAL; return -EINVAL;
cfg = (const struct stm32_timer_trigger_cfg *)
of_match_device(dev->driver->of_match_table, dev)->data;
if (index >= ARRAY_SIZE(triggers_table) || if (index >= ARRAY_SIZE(triggers_table) ||
index >= ARRAY_SIZE(valids_table)) index >= cfg->num_valids_table)
return -EINVAL; return -EINVAL;
/* Create an IIO device only if we have triggers to be validated */ /* Create an IIO device only if we have triggers to be validated */
if (*valids_table[index]) if (*cfg->valids_table[index])
priv = stm32_setup_counter_device(dev); priv = stm32_setup_counter_device(dev);
else else
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
...@@ -758,7 +798,7 @@ static int stm32_timer_trigger_probe(struct platform_device *pdev) ...@@ -758,7 +798,7 @@ static int stm32_timer_trigger_probe(struct platform_device *pdev)
priv->clk = ddata->clk; priv->clk = ddata->clk;
priv->max_arr = ddata->max_arr; priv->max_arr = ddata->max_arr;
priv->triggers = triggers_table[index]; priv->triggers = triggers_table[index];
priv->valids = valids_table[index]; priv->valids = cfg->valids_table[index];
stm32_timer_detect_trgo2(priv); stm32_timer_detect_trgo2(priv);
ret = stm32_setup_iio_triggers(priv); ret = stm32_setup_iio_triggers(priv);
...@@ -770,8 +810,24 @@ static int stm32_timer_trigger_probe(struct platform_device *pdev) ...@@ -770,8 +810,24 @@ static int stm32_timer_trigger_probe(struct platform_device *pdev)
return 0; return 0;
} }
static const struct stm32_timer_trigger_cfg stm32_timer_trg_cfg = {
.valids_table = valids_table,
.num_valids_table = ARRAY_SIZE(valids_table),
};
static const struct stm32_timer_trigger_cfg stm32h7_timer_trg_cfg = {
.valids_table = stm32h7_valids_table,
.num_valids_table = ARRAY_SIZE(stm32h7_valids_table),
};
static const struct of_device_id stm32_trig_of_match[] = { static const struct of_device_id stm32_trig_of_match[] = {
{ .compatible = "st,stm32-timer-trigger", }, {
.compatible = "st,stm32-timer-trigger",
.data = (void *)&stm32_timer_trg_cfg,
}, {
.compatible = "st,stm32h7-timer-trigger",
.data = (void *)&stm32h7_timer_trg_cfg,
},
{ /* end node */ }, { /* end node */ },
}; };
MODULE_DEVICE_TABLE(of, stm32_trig_of_match); MODULE_DEVICE_TABLE(of, stm32_trig_of_match);
......
...@@ -57,8 +57,8 @@ static int ad7606_par_probe(struct platform_device *pdev) ...@@ -57,8 +57,8 @@ static int ad7606_par_probe(struct platform_device *pdev)
irq = platform_get_irq(pdev, 0); irq = platform_get_irq(pdev, 0);
if (irq < 0) { if (irq < 0) {
dev_err(&pdev->dev, "no irq\n"); dev_err(&pdev->dev, "no irq: %d\n", irq);
return -ENODEV; return irq;
} }
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
......
...@@ -55,10 +55,24 @@ ...@@ -55,10 +55,24 @@
#define TIM9_CH1 "tim9_ch1" #define TIM9_CH1 "tim9_ch1"
#define TIM9_CH2 "tim9_ch2" #define TIM9_CH2 "tim9_ch2"
#define TIM10_OC1 "tim10_oc1"
#define TIM11_OC1 "tim11_oc1"
#define TIM12_TRGO "tim12_trgo" #define TIM12_TRGO "tim12_trgo"
#define TIM12_CH1 "tim12_ch1" #define TIM12_CH1 "tim12_ch1"
#define TIM12_CH2 "tim12_ch2" #define TIM12_CH2 "tim12_ch2"
#define TIM13_OC1 "tim13_oc1"
#define TIM14_OC1 "tim14_oc1"
#define TIM15_TRGO "tim15_trgo"
#define TIM16_OC1 "tim16_oc1"
#define TIM17_OC1 "tim17_oc1"
bool is_stm32_timer_trigger(struct iio_trigger *trig); bool is_stm32_timer_trigger(struct iio_trigger *trig);
#endif #endif
...@@ -93,7 +93,7 @@ kvm_stat: FORCE ...@@ -93,7 +93,7 @@ kvm_stat: FORCE
all: acpi cgroup cpupower gpio hv firewire lguest liblockdep \ all: acpi cgroup cpupower gpio hv firewire lguest liblockdep \
perf selftests turbostat usb \ perf selftests turbostat usb \
virtio vm net x86_energy_perf_policy \ virtio vm net x86_energy_perf_policy \
tmon freefall objtool kvm_stat tmon freefall iio objtool kvm_stat
acpi_install: acpi_install:
$(call descend,power/$(@:_install=),install) $(call descend,power/$(@:_install=),install)
...@@ -101,7 +101,7 @@ acpi_install: ...@@ -101,7 +101,7 @@ acpi_install:
cpupower_install: cpupower_install:
$(call descend,power/$(@:_install=),install) $(call descend,power/$(@:_install=),install)
cgroup_install firewire_install gpio_install hv_install lguest_install perf_install usb_install virtio_install vm_install net_install objtool_install: cgroup_install firewire_install gpio_install hv_install iio_install lguest_install perf_install usb_install virtio_install vm_install net_install objtool_install:
$(call descend,$(@:_install=),install) $(call descend,$(@:_install=),install)
liblockdep_install: liblockdep_install:
...@@ -123,7 +123,7 @@ kvm_stat_install: ...@@ -123,7 +123,7 @@ kvm_stat_install:
$(call descend,kvm/$(@:_install=),install) $(call descend,kvm/$(@:_install=),install)
install: acpi_install cgroup_install cpupower_install gpio_install \ install: acpi_install cgroup_install cpupower_install gpio_install \
hv_install firewire_install lguest_install liblockdep_install \ hv_install firewire_install iio_install lguest_install liblockdep_install \
perf_install selftests_install turbostat_install usb_install \ perf_install selftests_install turbostat_install usb_install \
virtio_install vm_install net_install x86_energy_perf_policy_install \ virtio_install vm_install net_install x86_energy_perf_policy_install \
tmon_install freefall_install objtool_install kvm_stat_install tmon_install freefall_install objtool_install kvm_stat_install
......
lsiio-y += lsiio.o iio_utils.o
iio_event_monitor-y += iio_event_monitor.o iio_utils.o
iio_generic_buffer-y += iio_generic_buffer.o iio_utils.o
include ../scripts/Makefile.include
bindir ?= /usr/bin
ifeq ($(srctree),)
srctree := $(patsubst %/,%,$(dir $(CURDIR)))
srctree := $(patsubst %/,%,$(dir $(srctree)))
endif
# Do not use make's built-in rules
# (this improves performance and avoids hard-to-debug behaviour);
MAKEFLAGS += -r
CC = $(CROSS_COMPILE)gcc CC = $(CROSS_COMPILE)gcc
CFLAGS += -Wall -g -D_GNU_SOURCE -D__EXPORTED_HEADERS__ -I../../include/uapi -I../../include LD = $(CROSS_COMPILE)ld
CFLAGS += -O2 -Wall -g -D_GNU_SOURCE -I$(OUTPUT)include
BINDIR=usr/bin ALL_TARGETS := iio_event_monitor lsiio iio_generic_buffer
INSTALL_PROGRAM=install -m 755 -p ALL_PROGRAMS := $(patsubst %,$(OUTPUT)%,$(ALL_TARGETS))
DEL_FILE=rm -f
all: iio_event_monitor lsiio iio_generic_buffer all: $(ALL_PROGRAMS)
iio_event_monitor: iio_event_monitor.o iio_utils.o export srctree OUTPUT CC LD CFLAGS
include $(srctree)/tools/build/Makefile.include
lsiio: lsiio.o iio_utils.o #
# We need the following to be outside of kernel tree
#
$(OUTPUT)include/linux/iio: ../../include/uapi/linux/iio
mkdir -p $(OUTPUT)include/linux/iio 2>&1 || true
ln -sf $(CURDIR)/../../include/uapi/linux/iio/events.h $@
ln -sf $(CURDIR)/../../include/uapi/linux/iio/types.h $@
iio_generic_buffer: iio_generic_buffer.o iio_utils.o prepare: $(OUTPUT)include/linux/iio
%.o: %.c iio_utils.h LSIIO_IN := $(OUTPUT)lsiio-in.o
$(LSIIO_IN): prepare FORCE
$(Q)$(MAKE) $(build)=lsiio
$(OUTPUT)lsiio: $(LSIIO_IN)
$(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@
install: IIO_EVENT_MONITOR_IN := $(OUTPUT)iio_event_monitor-in.o
- mkdir -p $(INSTALL_ROOT)/$(BINDIR) $(IIO_EVENT_MONITOR_IN): prepare FORCE
- $(INSTALL_PROGRAM) "iio_event_monitor" "$(INSTALL_ROOT)/$(BINDIR)/iio_event_monitor" $(Q)$(MAKE) $(build)=iio_event_monitor
- $(INSTALL_PROGRAM) "lsiio" "$(INSTALL_ROOT)/$(BINDIR)/lsiio" $(OUTPUT)iio_event_monitor: $(IIO_EVENT_MONITOR_IN)
- $(INSTALL_PROGRAM) "iio_generic_buffer" "$(INSTALL_ROOT)/$(BINDIR)/iio_generic_buffer" $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@
uninstall: IIO_GENERIC_BUFFER_IN := $(OUTPUT)iio_generic_buffer-in.o
$(DEL_FILE) "$(INSTALL_ROOT)/$(BINDIR)/iio_event_monitor" $(IIO_GENERIC_BUFFER_IN): prepare FORCE
$(DEL_FILE) "$(INSTALL_ROOT)/$(BINDIR)/lsiio" $(Q)$(MAKE) $(build)=iio_generic_buffer
$(DEL_FILE) "$(INSTALL_ROOT)/$(BINDIR)/iio_generic_buffer" $(OUTPUT)iio_generic_buffer: $(IIO_GENERIC_BUFFER_IN)
$(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $< -o $@
.PHONY: clean
clean: clean:
rm -f *.o iio_event_monitor lsiio iio_generic_buffer rm -f $(ALL_PROGRAMS)
rm -rf $(OUTPUT)include/linux/iio
find $(if $(OUTPUT),$(OUTPUT),.) -name '*.o' -delete -o -name '\.*.d' -delete
install: $(ALL_PROGRAMS)
install -d -m 755 $(DESTDIR)$(bindir); \
for program in $(ALL_PROGRAMS); do \
install $$program $(DESTDIR)$(bindir); \
done
FORCE:
.PHONY: all install clean FORCE prepare
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment