restore lost packages from 0.2.3 + fix overwritten 0.2.4 files

- Restore 29 recipe symlinks (libdrm, qtbase, dbus, sddm, pipewire, etc.)
- Restore 33 patches (KDE, libdrm, mesa, pipewire, sddm, wireplumber)
- Restore 20+ local/scripts (audit, lint, test, build helpers)
- Restore src/cook/scheduler.rs, status.rs, gnu-config/
- Restore scripts/patch-inclusion-gate.sh, run_mini1.sh, validate-collision-log.sh
- Recover TLC source from HEAD (was overwritten by 0.2.3 checkout)
- Recover 11 local/docs plans from HEAD (were overwritten)
- Recover qt6-wayland-smoke symlink from HEAD
- Fix MOTD: remove garbled ASCII art, use clean text
- Update version: 0.2.0 -> 0.2.4 in os-release, motd, config
- Reduce filesystem_size: 1536 -> 512 MiB
- Add ABSOLUTE RULE to AGENTS.md: never delete/ignore packages
- Reduce pcid scheme log verbosity: info -> debug
This commit is contained in:
2026-06-19 12:39:14 +03:00
parent ffbe098ef8
commit dc68054305
6418 changed files with 7066233 additions and 8670 deletions
@@ -0,0 +1,17 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* KXCJK-1013 3-axis accelerometer Interface
* Copyright (c) 2014, Intel Corporation.
*/
#ifndef __IIO_KXCJK_1013_H__
#define __IIO_KXCJK_1013_H__
#include <linux/iio/iio.h>
struct kxcjk_1013_platform_data {
bool active_high_intr;
struct iio_mount_matrix orientation;
};
#endif
@@ -0,0 +1,27 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* The industrial I/O ADC firmware property parsing helpers
*
* Copyright (c) 2025 Matti Vaittinen <mazziesaccount@gmail.com>
*/
#ifndef _INDUSTRIAL_IO_ADC_HELPERS_H_
#define _INDUSTRIAL_IO_ADC_HELPERS_H_
#include <linux/property.h>
struct device;
struct iio_chan_spec;
static inline int iio_adc_device_num_channels(struct device *dev)
{
return device_get_named_child_node_count(dev, "channel");
}
int devm_iio_adc_device_alloc_chaninfo_se(struct device *dev,
const struct iio_chan_spec *template,
int max_chan_id,
struct iio_chan_spec **cs);
#endif /* _INDUSTRIAL_IO_ADC_HELPERS_H_ */
@@ -0,0 +1,218 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Support code for Analog Devices Sigma-Delta ADCs
*
* Copyright 2012 Analog Devices Inc.
* Author: Lars-Peter Clausen <lars@metafoo.de>
*/
#ifndef __AD_SIGMA_DELTA_H__
#define __AD_SIGMA_DELTA_H__
#include <linux/iio/iio.h>
enum ad_sigma_delta_mode {
AD_SD_MODE_CONTINUOUS = 0,
AD_SD_MODE_SINGLE = 1,
AD_SD_MODE_IDLE = 2,
AD_SD_MODE_POWERDOWN = 3,
};
/**
* struct ad_sigma_delta_calib_data - Calibration data for Sigma Delta devices
* @mode: Calibration mode.
* @channel: Calibration channel.
*/
struct ad_sd_calib_data {
unsigned int mode;
unsigned int channel;
};
struct ad_sigma_delta;
struct device;
struct gpio_desc;
struct iio_dev;
struct spi_offload;
struct spi_offload_trigger;
/**
* struct ad_sigma_delta_info - Sigma Delta driver specific callbacks and options
* @set_channel: Will be called to select the current channel, may be NULL.
* @append_status: Will be called to enable status append at the end of the sample, may be NULL.
* @set_mode: Will be called to select the current mode, may be NULL.
* @disable_all: Will be called to disable all channels, may be NULL.
* @disable_one: Will be called to disable a single channel after
* ad_sigma_delta_single_conversion(), may be NULL.
* Usage of this callback expects iio_chan_spec.address to contain
* the value required for the driver to identify the channel.
* @postprocess_sample: Is called for each sampled data word, can be used to
* modify or drop the sample data, it, may be NULL.
* @has_registers: true if the device has writable and readable registers, false
* if there is just one read-only sample data shift register.
* @has_named_irqs: Set to true if there is more than one IRQ line.
* @supports_spi_offload: Set to true if the driver supports SPI offload. Often
* special considerations are needed for scan_type and other channel
* info, so individual drivers have to set this to let the core
* code know that it can use SPI offload if it is available.
* @addr_shift: Shift of the register address in the communications register.
* @read_mask: Mask for the communications register having the read bit set.
* @status_ch_mask: Mask for the channel number stored in status register.
* @data_reg: Address of the data register, if 0 the default address of 0x3 will
* be used.
* @irq_flags: flags for the interrupt used by the triggered buffer
* @num_slots: Number of sequencer slots
* @num_resetclks: Number of SPI clk cycles with MOSI=1 to reset the chip.
*/
struct ad_sigma_delta_info {
int (*set_channel)(struct ad_sigma_delta *, unsigned int channel);
int (*append_status)(struct ad_sigma_delta *, bool append);
int (*set_mode)(struct ad_sigma_delta *, enum ad_sigma_delta_mode mode);
int (*disable_all)(struct ad_sigma_delta *);
int (*disable_one)(struct ad_sigma_delta *, unsigned int chan);
int (*postprocess_sample)(struct ad_sigma_delta *, unsigned int raw_sample);
bool has_registers;
bool has_named_irqs;
bool supports_spi_offload;
unsigned int addr_shift;
unsigned int read_mask;
unsigned int status_ch_mask;
unsigned int data_reg;
unsigned long irq_flags;
unsigned int num_slots;
unsigned int num_resetclks;
};
/**
* struct ad_sigma_delta - Sigma Delta device struct
* @spi: The spi device associated with the Sigma Delta device.
* @trig: The IIO trigger associated with the Sigma Delta device.
*
* Most of the fields are private to the sigma delta library code and should not
* be accessed by individual drivers.
*/
struct ad_sigma_delta {
struct spi_device *spi;
struct iio_trigger *trig;
/* private: */
struct completion completion;
spinlock_t irq_lock; /* protects .irq_dis and irq en/disable state */
bool irq_dis;
bool bus_locked;
bool keep_cs_asserted;
u8 comm;
const struct ad_sigma_delta_info *info;
unsigned int active_slots;
unsigned int current_slot;
unsigned int num_slots;
struct gpio_desc *rdy_gpiod;
int irq_line;
bool status_appended;
/* map slots to channels in order to know what to expect from devices */
unsigned int *slots;
struct spi_message sample_msg;
struct spi_transfer sample_xfer[2];
u8 *samples_buf;
struct spi_offload *offload;
struct spi_offload_trigger *offload_trigger;
/*
* DMA (thus cache coherency maintenance) requires the
* transfer buffers to live in their own cache lines.
* 'tx_buf' is up to 32 bits.
* 'rx_buf' is up to 32 bits per sample + 64 bit timestamp,
* rounded to 16 bytes to take into account padding.
*/
u8 tx_buf[4] __aligned(IIO_DMA_MINALIGN);
u8 rx_buf[16] __aligned(8);
u8 sample_addr;
};
static inline bool ad_sigma_delta_has_spi_offload(struct ad_sigma_delta *sd)
{
return sd->offload != NULL;
}
static inline int ad_sigma_delta_set_channel(struct ad_sigma_delta *sd,
unsigned int channel)
{
if (sd->info->set_channel)
return sd->info->set_channel(sd, channel);
return 0;
}
static inline int ad_sigma_delta_append_status(struct ad_sigma_delta *sd, bool append)
{
int ret;
if (sd->info->append_status) {
ret = sd->info->append_status(sd, append);
if (ret < 0)
return ret;
sd->status_appended = append;
}
return 0;
}
static inline int ad_sigma_delta_disable_all(struct ad_sigma_delta *sd)
{
if (sd->info->disable_all)
return sd->info->disable_all(sd);
return 0;
}
static inline int ad_sigma_delta_disable_one(struct ad_sigma_delta *sd,
unsigned int chan)
{
if (sd->info->disable_one)
return sd->info->disable_one(sd, chan);
return 0;
}
static inline int ad_sigma_delta_set_mode(struct ad_sigma_delta *sd,
unsigned int mode)
{
if (sd->info->set_mode)
return sd->info->set_mode(sd, mode);
return 0;
}
static inline int ad_sigma_delta_postprocess_sample(struct ad_sigma_delta *sd,
unsigned int raw_sample)
{
if (sd->info->postprocess_sample)
return sd->info->postprocess_sample(sd, raw_sample);
return 0;
}
void ad_sd_set_comm(struct ad_sigma_delta *sigma_delta, u8 comm);
int ad_sd_write_reg(struct ad_sigma_delta *sigma_delta, unsigned int reg,
unsigned int size, unsigned int val);
int ad_sd_read_reg(struct ad_sigma_delta *sigma_delta, unsigned int reg,
unsigned int size, unsigned int *val);
int ad_sd_reset(struct ad_sigma_delta *sigma_delta);
int ad_sigma_delta_single_conversion(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan, int *val);
int ad_sd_calibrate(struct ad_sigma_delta *sigma_delta,
unsigned int mode, unsigned int channel);
int ad_sd_calibrate_all(struct ad_sigma_delta *sigma_delta,
const struct ad_sd_calib_data *cd, unsigned int n);
int ad_sd_init(struct ad_sigma_delta *sigma_delta, struct iio_dev *indio_dev,
struct spi_device *spi, const struct ad_sigma_delta_info *info);
int devm_ad_sd_setup_buffer_and_trigger(struct device *dev, struct iio_dev *indio_dev);
int ad_sd_validate_trigger(struct iio_dev *indio_dev, struct iio_trigger *trig);
#endif
@@ -0,0 +1,211 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
*
* Code used in the main and auxiliary Qualcomm PMIC voltage ADCs
* of type ADC5 Gen3.
*/
#ifndef QCOM_ADC5_GEN3_COMMON_H
#define QCOM_ADC5_GEN3_COMMON_H
#include <linux/auxiliary_bus.h>
#include <linux/bitfield.h>
#include <linux/bits.h>
#include <linux/device.h>
#include <linux/iio/adc/qcom-vadc-common.h>
#include <linux/regmap.h>
#include <linux/types.h>
#define ADC5_GEN3_HS 0x45
#define ADC5_GEN3_HS_BUSY BIT(7)
#define ADC5_GEN3_HS_READY BIT(0)
#define ADC5_GEN3_STATUS1 0x46
#define ADC5_GEN3_STATUS1_CONV_FAULT BIT(7)
#define ADC5_GEN3_STATUS1_THR_CROSS BIT(6)
#define ADC5_GEN3_STATUS1_EOC BIT(0)
#define ADC5_GEN3_TM_EN_STS 0x47
#define ADC5_GEN3_TM_HIGH_STS 0x48
#define ADC5_GEN3_TM_LOW_STS 0x49
#define ADC5_GEN3_EOC_STS 0x4a
#define ADC5_GEN3_EOC_CHAN_0 BIT(0)
#define ADC5_GEN3_EOC_CLR 0x4b
#define ADC5_GEN3_TM_HIGH_STS_CLR 0x4c
#define ADC5_GEN3_TM_LOW_STS_CLR 0x4d
#define ADC5_GEN3_CONV_ERR_CLR 0x4e
#define ADC5_GEN3_CONV_ERR_CLR_REQ BIT(0)
#define ADC5_GEN3_SID 0x4f
#define ADC5_GEN3_SID_MASK GENMASK(3, 0)
#define ADC5_GEN3_PERPH_CH 0x50
#define ADC5_GEN3_CHAN_CONV_REQ BIT(7)
#define ADC5_GEN3_TIMER_SEL 0x51
#define ADC5_GEN3_TIME_IMMEDIATE 0x1
#define ADC5_GEN3_DIG_PARAM 0x52
#define ADC5_GEN3_DIG_PARAM_CAL_SEL_MASK GENMASK(5, 4)
#define ADC5_GEN3_DIG_PARAM_DEC_RATIO_SEL_MASK GENMASK(3, 2)
#define ADC5_GEN3_FAST_AVG 0x53
#define ADC5_GEN3_FAST_AVG_CTL_EN BIT(7)
#define ADC5_GEN3_FAST_AVG_CTL_SAMPLES_MASK GENMASK(2, 0)
#define ADC5_GEN3_ADC_CH_SEL_CTL 0x54
#define ADC5_GEN3_DELAY_CTL 0x55
#define ADC5_GEN3_HW_SETTLE_DELAY_MASK GENMASK(3, 0)
#define ADC5_GEN3_CH_EN 0x56
#define ADC5_GEN3_HIGH_THR_INT_EN BIT(1)
#define ADC5_GEN3_LOW_THR_INT_EN BIT(0)
#define ADC5_GEN3_LOW_THR0 0x57
#define ADC5_GEN3_LOW_THR1 0x58
#define ADC5_GEN3_HIGH_THR0 0x59
#define ADC5_GEN3_HIGH_THR1 0x5a
#define ADC5_GEN3_CH_DATA0(channel) (0x5c + (channel) * 2)
#define ADC5_GEN3_CH_DATA1(channel) (0x5d + (channel) * 2)
#define ADC5_GEN3_CONV_REQ 0xe5
#define ADC5_GEN3_CONV_REQ_REQ BIT(0)
#define ADC5_GEN3_VIRTUAL_SID_MASK GENMASK(15, 8)
#define ADC5_GEN3_CHANNEL_MASK GENMASK(7, 0)
#define ADC5_GEN3_V_CHAN(x) \
(FIELD_PREP(ADC5_GEN3_VIRTUAL_SID_MASK, (x).sid) | (x).channel)
/* ADC channels for PMIC5 Gen3 */
#define ADC5_GEN3_REF_GND 0x00
#define ADC5_GEN3_1P25VREF 0x01
#define ADC5_GEN3_DIE_TEMP 0x03
#define ADC5_GEN3_USB_SNS_V_16 0x11
#define ADC5_GEN3_VIN_DIV16_MUX 0x12
#define ADC5_GEN3_VPH_PWR 0x8e
#define ADC5_GEN3_VBAT_SNS_QBG 0x8f
/* 100k pull-up channels */
#define ADC5_GEN3_AMUX1_THM_100K_PU 0x44
#define ADC5_GEN3_AMUX2_THM_100K_PU 0x45
#define ADC5_GEN3_AMUX3_THM_100K_PU 0x46
#define ADC5_GEN3_AMUX4_THM_100K_PU 0x47
#define ADC5_GEN3_AMUX5_THM_100K_PU 0x48
#define ADC5_GEN3_AMUX6_THM_100K_PU 0x49
#define ADC5_GEN3_AMUX1_GPIO_100K_PU 0x4a
#define ADC5_GEN3_AMUX2_GPIO_100K_PU 0x4b
#define ADC5_GEN3_AMUX3_GPIO_100K_PU 0x4c
#define ADC5_GEN3_AMUX4_GPIO_100K_PU 0x4d
#define ADC5_MAX_CHANNEL 0xc0
enum adc5_cal_method {
ADC5_NO_CAL = 0,
ADC5_RATIOMETRIC_CAL,
ADC5_ABSOLUTE_CAL,
};
enum adc5_time_select {
MEAS_INT_DISABLE = 0,
MEAS_INT_IMMEDIATE,
MEAS_INT_50MS,
MEAS_INT_100MS,
MEAS_INT_1S,
MEAS_INT_NONE,
};
/**
* struct adc5_sdam_data - data per SDAM allocated for adc usage
* @base_addr: base address for the ADC SDAM peripheral.
* @irq_name: ADC IRQ name.
* @irq: ADC IRQ number.
*/
struct adc5_sdam_data {
u16 base_addr;
const char *irq_name;
int irq;
};
/**
* struct adc5_device_data - Top-level ADC device data
* @regmap: ADC peripheral register map field.
* @base: array of SDAM data.
* @num_sdams: number of ADC SDAM peripherals.
*/
struct adc5_device_data {
struct regmap *regmap;
struct adc5_sdam_data *base;
int num_sdams;
};
/**
* struct adc5_channel_common_prop - ADC channel properties (common to ADC and TM).
* @channel: channel number, refer to the channel list.
* @cal_method: calibration method.
* @decimation: sampling rate supported for the channel.
* @sid: ID of PMIC owning the channel.
* @label: Channel name used in device tree.
* @prescale: channel scaling performed on the input signal.
* @hw_settle_time_us: the time between AMUX being configured and the
* start of conversion in uS.
* @avg_samples: ability to provide single result from the ADC
* that is an average of multiple measurements.
* @scale_fn_type: Represents the scaling function to convert voltage
* physical units desired by the client for the channel.
*/
struct adc5_channel_common_prop {
unsigned int channel;
enum adc5_cal_method cal_method;
unsigned int decimation;
unsigned int sid;
const char *label;
unsigned int prescale;
unsigned int hw_settle_time_us;
unsigned int avg_samples;
enum vadc_scale_fn_type scale_fn_type;
};
/**
* struct tm5_aux_dev_wrapper - wrapper structure around TM auxiliary device
* @aux_dev: TM auxiliary device structure.
* @dev_data: Top-level ADC device data.
* @tm_props: Array of common ADC channel properties for TM channels.
* @n_tm_channels: number of TM channels.
*/
struct tm5_aux_dev_wrapper {
struct auxiliary_device aux_dev;
struct adc5_device_data *dev_data;
struct adc5_channel_common_prop *tm_props;
unsigned int n_tm_channels;
};
int adc5_gen3_read(struct adc5_device_data *adc, unsigned int sdam_index,
u16 offset, u8 *data, int len);
int adc5_gen3_write(struct adc5_device_data *adc, unsigned int sdam_index,
u16 offset, u8 *data, int len);
int adc5_gen3_poll_wait_hs(struct adc5_device_data *adc,
unsigned int sdam_index);
void adc5_gen3_update_dig_param(struct adc5_channel_common_prop *prop,
u8 *data);
int adc5_gen3_status_clear(struct adc5_device_data *adc,
int sdam_index, u16 offset, u8 *val, int len);
void adc5_gen3_mutex_lock(struct device *dev);
void adc5_gen3_mutex_unlock(struct device *dev);
int adc5_gen3_get_scaled_reading(struct device *dev,
struct adc5_channel_common_prop *common_props,
int *val);
int adc5_gen3_therm_code_to_temp(struct device *dev,
struct adc5_channel_common_prop *common_props,
u16 code, int *val);
void adc5_gen3_register_tm_event_notifier(struct device *dev,
void (*handler)(struct auxiliary_device *));
#endif /* QCOM_ADC5_GEN3_COMMON_H */
@@ -0,0 +1,168 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Code shared between the different Qualcomm PMIC voltage ADCs
*/
#ifndef QCOM_VADC_COMMON_H
#define QCOM_VADC_COMMON_H
#include <linux/math.h>
#include <linux/types.h>
#define VADC_CONV_TIME_MIN_US 2000
#define VADC_CONV_TIME_MAX_US 2100
/* Min ADC code represents 0V */
#define VADC_MIN_ADC_CODE 0x6000
/* Max ADC code represents full-scale range of 1.8V */
#define VADC_MAX_ADC_CODE 0xa800
#define VADC_ABSOLUTE_RANGE_UV 625000
#define VADC_RATIOMETRIC_RANGE 1800
#define VADC_DEF_PRESCALING 0 /* 1:1 */
#define VADC_DEF_DECIMATION 0 /* 512 */
#define VADC_DEF_HW_SETTLE_TIME 0 /* 0 us */
#define VADC_DEF_AVG_SAMPLES 0 /* 1 sample */
#define VADC_DEF_CALIB_TYPE VADC_CALIB_ABSOLUTE
#define VADC_DECIMATION_MIN 512
#define VADC_DECIMATION_MAX 4096
#define ADC5_DEF_VBAT_PRESCALING 1 /* 1:3 */
#define ADC5_DECIMATION_SHORT 250
#define ADC5_DECIMATION_MEDIUM 420
#define ADC5_DECIMATION_LONG 840
/* Default decimation - 1024 for rev2, 840 for pmic5 */
#define ADC5_DECIMATION_DEFAULT 2
#define ADC5_DECIMATION_SAMPLES_MAX 3
#define VADC_HW_SETTLE_DELAY_MAX 10000
#define VADC_HW_SETTLE_SAMPLES_MAX 16
#define VADC_AVG_SAMPLES_MAX 512
#define ADC5_AVG_SAMPLES_MAX 16
#define PMIC5_CHG_TEMP_SCALE_FACTOR 377500
#define PMIC5_SMB_TEMP_CONSTANT 419400
#define PMIC5_SMB_TEMP_SCALE_FACTOR 356
#define PMI_CHG_SCALE_1 -138890
#define PMI_CHG_SCALE_2 391750000000LL
#define VADC5_MAX_CODE 0x7fff
#define ADC5_FULL_SCALE_CODE 0x70e4
#define ADC5_USR_DATA_CHECK 0x8000
#define R_PU_100K 100000
#define RATIO_MAX_ADC7 BIT(14)
/*
* VADC_CALIB_ABSOLUTE: uses the 625mV and 1.25V as reference channels.
* VADC_CALIB_RATIOMETRIC: uses the reference voltage (1.8V) and GND for
* calibration.
*/
enum vadc_calibration {
VADC_CALIB_ABSOLUTE = 0,
VADC_CALIB_RATIOMETRIC
};
/**
* struct vadc_linear_graph - Represent ADC characteristics.
* @dy: numerator slope to calculate the gain.
* @dx: denominator slope to calculate the gain.
* @gnd: A/D word of the ground reference used for the channel.
*
* Each ADC device has different offset and gain parameters which are
* computed to calibrate the device.
*/
struct vadc_linear_graph {
s32 dy;
s32 dx;
s32 gnd;
};
/**
* enum vadc_scale_fn_type - Scaling function to convert ADC code to
* physical scaled units for the channel.
* @SCALE_DEFAULT: Default scaling to convert raw adc code to voltage (uV).
* @SCALE_THERM_100K_PULLUP: Returns temperature in millidegC.
* Uses a mapping table with 100K pullup.
* @SCALE_PMIC_THERM: Returns result in milli degree's Centigrade.
* @SCALE_XOTHERM: Returns XO thermistor voltage in millidegC.
* @SCALE_PMI_CHG_TEMP: Conversion for PMI CHG temp
* @SCALE_HW_CALIB_DEFAULT: Default scaling to convert raw adc code to
* voltage (uV) with hardware applied offset/slope values to adc code.
* @SCALE_HW_CALIB_THERM_100K_PULLUP: Returns temperature in millidegC using
* lookup table. The hardware applies offset/slope to adc code.
* @SCALE_HW_CALIB_XOTHERM: Returns XO thermistor voltage in millidegC using
* 100k pullup. The hardware applies offset/slope to adc code.
* @SCALE_HW_CALIB_THERM_100K_PU_PM7: Returns temperature in millidegC using
* lookup table for PMIC7. The hardware applies offset/slope to adc code.
* @SCALE_HW_CALIB_PMIC_THERM: Returns result in milli degree's Centigrade.
* The hardware applies offset/slope to adc code.
* @SCALE_HW_CALIB_PMIC_THERM: Returns result in milli degree's Centigrade.
* The hardware applies offset/slope to adc code. This is for PMIC7.
* @SCALE_HW_CALIB_PM5_CHG_TEMP: Returns result in millidegrees for PMIC5
* charger temperature.
* @SCALE_HW_CALIB_PM5_SMB_TEMP: Returns result in millidegrees for PMIC5
* SMB1390 temperature.
*/
enum vadc_scale_fn_type {
SCALE_DEFAULT = 0,
SCALE_THERM_100K_PULLUP,
SCALE_PMIC_THERM,
SCALE_XOTHERM,
SCALE_PMI_CHG_TEMP,
SCALE_HW_CALIB_DEFAULT,
SCALE_HW_CALIB_THERM_100K_PULLUP,
SCALE_HW_CALIB_XOTHERM,
SCALE_HW_CALIB_THERM_100K_PU_PM7,
SCALE_HW_CALIB_PMIC_THERM,
SCALE_HW_CALIB_PMIC_THERM_PM7,
SCALE_HW_CALIB_PM5_CHG_TEMP,
SCALE_HW_CALIB_PM5_SMB_TEMP,
/* private: */
SCALE_HW_CALIB_INVALID,
};
struct adc5_data {
const u32 full_scale_code_volt;
const u32 full_scale_code_cur;
const struct adc5_channels *adc_chans;
const struct iio_info *info;
unsigned int *decimation;
unsigned int *hw_settle_1;
unsigned int *hw_settle_2;
};
int qcom_vadc_scale(enum vadc_scale_fn_type scaletype,
const struct vadc_linear_graph *calib_graph,
const struct u32_fract *prescale,
bool absolute,
u16 adc_code, int *result_mdec);
struct qcom_adc5_scale_type {
int (*scale_fn)(const struct u32_fract *prescale,
const struct adc5_data *data, u16 adc_code, int *result);
};
int qcom_adc5_hw_scale(enum vadc_scale_fn_type scaletype,
unsigned int prescale_ratio,
const struct adc5_data *data,
u16 adc_code, int *result_mdec);
u16 qcom_adc_tm5_temp_volt_scale(unsigned int prescale_ratio,
u32 full_scale_code_volt, int temp);
u16 qcom_adc_tm5_gen2_temp_res_scale(int temp);
int qcom_adc5_prescaling_from_dt(u32 num, u32 den);
int qcom_adc5_hw_settle_time_from_dt(u32 value, const unsigned int *hw_settle);
int qcom_adc5_avg_samples_from_dt(u32 value);
int qcom_adc5_decimation_from_dt(u32 value, const unsigned int *decimation);
int qcom_vadc_decimation_from_dt(u32 value);
#endif /* QCOM_VADC_COMMON_H */
@@ -0,0 +1,20 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* This file discribe the STM32 DFSDM IIO driver API for audio part
*
* Copyright (C) 2017, STMicroelectronics - All Rights Reserved
* Author(s): Arnaud Pouliquen <arnaud.pouliquen@st.com>.
*/
#ifndef STM32_DFSDM_ADC_H
#define STM32_DFSDM_ADC_H
#include <linux/iio/iio.h>
int stm32_dfsdm_get_buff_cb(struct iio_dev *iio_dev,
int (*cb)(const void *data, size_t size,
void *private),
void *private);
int stm32_dfsdm_release_buff_cb(struct iio_dev *iio_dev);
#endif
@@ -0,0 +1,36 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) 2018 Axentia Technologies AB
*/
#ifndef __IIO_RESCALE_H__
#define __IIO_RESCALE_H__
#include <linux/types.h>
#include <linux/iio/iio.h>
struct device;
struct rescale;
struct rescale_cfg {
enum iio_chan_type type;
int (*props)(struct device *dev, struct rescale *rescale);
};
struct rescale {
const struct rescale_cfg *cfg;
struct iio_channel *source;
struct iio_chan_spec chan;
struct iio_chan_spec_ext_info *ext_info;
bool chan_processed;
s32 numerator;
s32 denominator;
s32 offset;
};
int rescale_process_scale(struct rescale *rescale, int scale_type,
int *val, int *val2);
int rescale_process_offset(struct rescale *rescale, int scale_type,
int scale, int scale2, int schan_off,
int *val, int *val2);
#endif /* __IIO_RESCALE_H__ */
@@ -0,0 +1,294 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef _IIO_BACKEND_H_
#define _IIO_BACKEND_H_
#include <linux/types.h>
#include <linux/iio/iio.h>
struct iio_chan_spec;
struct fwnode_handle;
struct iio_backend;
struct device;
struct iio_dev;
enum iio_backend_data_type {
IIO_BACKEND_TWOS_COMPLEMENT,
IIO_BACKEND_OFFSET_BINARY,
IIO_BACKEND_DATA_UNSIGNED,
IIO_BACKEND_DATA_TYPE_MAX
};
enum iio_backend_data_source {
IIO_BACKEND_INTERNAL_CONTINUOUS_WAVE,
IIO_BACKEND_EXTERNAL,
IIO_BACKEND_INTERNAL_RAMP_16BIT,
IIO_BACKEND_DATA_SOURCE_MAX
};
#define iio_backend_debugfs_ptr(ptr) PTR_IF(IS_ENABLED(CONFIG_DEBUG_FS), ptr)
/**
* IIO_BACKEND_EX_INFO - Helper for an IIO extended channel attribute
* @_name: Attribute name
* @_shared: Whether the attribute is shared between all channels
* @_what: Data private to the driver
*/
#define IIO_BACKEND_EX_INFO(_name, _shared, _what) { \
.name = (_name), \
.shared = (_shared), \
.read = iio_backend_ext_info_get, \
.write = iio_backend_ext_info_set, \
.private = (_what), \
}
/**
* struct iio_backend_data_fmt - Backend data format
* @type: Data type.
* @sign_extend: Bool to tell if the data is sign extended.
* @enable: Enable/Disable the data format module. If disabled,
* not formatting will happen.
*/
struct iio_backend_data_fmt {
enum iio_backend_data_type type;
bool sign_extend;
bool enable;
};
/* vendor specific from 32 */
enum iio_backend_test_pattern {
IIO_BACKEND_NO_TEST_PATTERN,
/* modified prbs9 */
IIO_BACKEND_ADI_PRBS_9A = 32,
/* modified prbs23 */
IIO_BACKEND_ADI_PRBS_23A,
IIO_BACKEND_TEST_PATTERN_MAX
};
enum iio_backend_sample_trigger {
IIO_BACKEND_SAMPLE_TRIGGER_EDGE_FALLING,
IIO_BACKEND_SAMPLE_TRIGGER_EDGE_RISING,
IIO_BACKEND_SAMPLE_TRIGGER_MAX
};
enum iio_backend_interface_type {
IIO_BACKEND_INTERFACE_SERIAL_LVDS,
IIO_BACKEND_INTERFACE_SERIAL_CMOS,
IIO_BACKEND_INTERFACE_MAX
};
enum iio_backend_filter_type {
IIO_BACKEND_FILTER_TYPE_DISABLED,
IIO_BACKEND_FILTER_TYPE_SINC1,
IIO_BACKEND_FILTER_TYPE_SINC5,
IIO_BACKEND_FILTER_TYPE_SINC5_PLUS_COMP,
IIO_BACKEND_FILTER_TYPE_MAX
};
/**
* enum iio_backend_capabilities - Backend capabilities
* Backend capabilities can be used by frontends to check if a given
* functionality is supported by the backend. This is useful for frontend
* devices which are expected to work with alternative backend
* implementations. Capabilities are loosely coupled with operations,
* meaning that a capability requires certain operations to be implemented
* by the backend. A capability might be mapped to a single operation or
* multiple operations.
*
* @IIO_BACKEND_CAP_CALIBRATION: Backend supports digital interface
* calibration. Calibration procedure is device specific.
* @IIO_BACKEND_CAP_BUFFER: Support for IIO buffer interface.
* @IIO_BACKEND_CAP_ENABLE: Backend can be explicitly enabled/disabled.
*/
enum iio_backend_capabilities {
IIO_BACKEND_CAP_CALIBRATION = BIT(0),
IIO_BACKEND_CAP_BUFFER = BIT(1),
IIO_BACKEND_CAP_ENABLE = BIT(2),
};
/**
* struct iio_backend_ops - operations structure for an iio_backend
* @enable: Enable backend.
* @disable: Disable backend.
* @chan_enable: Enable one channel.
* @chan_disable: Disable one channel.
* @data_format_set: Configure the data format for a specific channel.
* @data_source_set: Configure the data source for a specific channel.
* @data_source_get: Data source getter for a specific channel.
* @set_sample_rate: Configure the sampling rate for a specific channel.
* @test_pattern_set: Configure a test pattern.
* @chan_status: Get the channel status.
* @iodelay_set: Set digital I/O delay.
* @data_sample_trigger: Control when to sample data.
* @request_buffer: Request an IIO buffer.
* @free_buffer: Free an IIO buffer.
* @extend_chan_spec: Extend an IIO channel.
* @ext_info_set: Extended info setter.
* @ext_info_get: Extended info getter.
* @interface_type_get: Interface type.
* @data_size_set: Data size.
* @oversampling_ratio_set: Set Oversampling ratio.
* @read_raw: Read a channel attribute from a backend device
* @debugfs_print_chan_status: Print channel status into a buffer.
* @debugfs_reg_access: Read or write register value of backend.
* @filter_type_set: Set filter type.
* @interface_data_align: Perform the data alignment process.
* @num_lanes_set: Set the number of lanes enabled.
* @ddr_enable: Enable interface DDR (Double Data Rate) mode.
* @ddr_disable: Disable interface DDR (Double Data Rate) mode.
* @data_stream_enable: Enable data stream.
* @data_stream_disable: Disable data stream.
* @data_transfer_addr: Set data address.
**/
struct iio_backend_ops {
int (*enable)(struct iio_backend *back);
void (*disable)(struct iio_backend *back);
int (*chan_enable)(struct iio_backend *back, unsigned int chan);
int (*chan_disable)(struct iio_backend *back, unsigned int chan);
int (*data_format_set)(struct iio_backend *back, unsigned int chan,
const struct iio_backend_data_fmt *data);
int (*data_source_set)(struct iio_backend *back, unsigned int chan,
enum iio_backend_data_source data);
int (*data_source_get)(struct iio_backend *back, unsigned int chan,
enum iio_backend_data_source *data);
int (*set_sample_rate)(struct iio_backend *back, unsigned int chan,
u64 sample_rate_hz);
int (*test_pattern_set)(struct iio_backend *back,
unsigned int chan,
enum iio_backend_test_pattern pattern);
int (*chan_status)(struct iio_backend *back, unsigned int chan,
bool *error);
int (*iodelay_set)(struct iio_backend *back, unsigned int chan,
unsigned int taps);
int (*data_sample_trigger)(struct iio_backend *back,
enum iio_backend_sample_trigger trigger);
struct iio_buffer *(*request_buffer)(struct iio_backend *back,
struct iio_dev *indio_dev);
void (*free_buffer)(struct iio_backend *back,
struct iio_buffer *buffer);
int (*extend_chan_spec)(struct iio_backend *back,
struct iio_chan_spec *chan);
int (*ext_info_set)(struct iio_backend *back, uintptr_t private,
const struct iio_chan_spec *chan,
const char *buf, size_t len);
int (*ext_info_get)(struct iio_backend *back, uintptr_t private,
const struct iio_chan_spec *chan, char *buf);
int (*interface_type_get)(struct iio_backend *back,
enum iio_backend_interface_type *type);
int (*data_size_set)(struct iio_backend *back, unsigned int size);
int (*oversampling_ratio_set)(struct iio_backend *back,
unsigned int chan, unsigned int ratio);
int (*read_raw)(struct iio_backend *back,
struct iio_chan_spec const *chan, int *val, int *val2,
long mask);
int (*debugfs_print_chan_status)(struct iio_backend *back,
unsigned int chan, char *buf,
size_t len);
int (*debugfs_reg_access)(struct iio_backend *back, unsigned int reg,
unsigned int writeval, unsigned int *readval);
int (*filter_type_set)(struct iio_backend *back,
enum iio_backend_filter_type type);
int (*interface_data_align)(struct iio_backend *back, u32 timeout_us);
int (*num_lanes_set)(struct iio_backend *back, unsigned int num_lanes);
int (*ddr_enable)(struct iio_backend *back);
int (*ddr_disable)(struct iio_backend *back);
int (*data_stream_enable)(struct iio_backend *back);
int (*data_stream_disable)(struct iio_backend *back);
int (*data_transfer_addr)(struct iio_backend *back, u32 address);
};
/**
* struct iio_backend_info - info structure for an iio_backend
* @name: Backend name.
* @ops: Backend operations.
* @caps: Backend capabilities. (bitmask of enum iio_backend_capabilities).
*/
struct iio_backend_info {
const char *name;
const struct iio_backend_ops *ops;
u32 caps;
};
int iio_backend_chan_enable(struct iio_backend *back, unsigned int chan);
int iio_backend_chan_disable(struct iio_backend *back, unsigned int chan);
int devm_iio_backend_enable(struct device *dev, struct iio_backend *back);
int iio_backend_enable(struct iio_backend *back);
void iio_backend_disable(struct iio_backend *back);
int iio_backend_data_format_set(struct iio_backend *back, unsigned int chan,
const struct iio_backend_data_fmt *data);
int iio_backend_data_source_set(struct iio_backend *back, unsigned int chan,
enum iio_backend_data_source data);
int iio_backend_data_source_get(struct iio_backend *back, unsigned int chan,
enum iio_backend_data_source *data);
int iio_backend_set_sampling_freq(struct iio_backend *back, unsigned int chan,
u64 sample_rate_hz);
int iio_backend_test_pattern_set(struct iio_backend *back,
unsigned int chan,
enum iio_backend_test_pattern pattern);
int iio_backend_chan_status(struct iio_backend *back, unsigned int chan,
bool *error);
int iio_backend_iodelay_set(struct iio_backend *back, unsigned int lane,
unsigned int taps);
int iio_backend_data_sample_trigger(struct iio_backend *back,
enum iio_backend_sample_trigger trigger);
int devm_iio_backend_request_buffer(struct device *dev,
struct iio_backend *back,
struct iio_dev *indio_dev);
int iio_backend_filter_type_set(struct iio_backend *back,
enum iio_backend_filter_type type);
int iio_backend_interface_data_align(struct iio_backend *back, u32 timeout_us);
int iio_backend_num_lanes_set(struct iio_backend *back, unsigned int num_lanes);
int iio_backend_ddr_enable(struct iio_backend *back);
int iio_backend_ddr_disable(struct iio_backend *back);
int iio_backend_data_stream_enable(struct iio_backend *back);
int iio_backend_data_stream_disable(struct iio_backend *back);
int iio_backend_data_transfer_addr(struct iio_backend *back, u32 address);
ssize_t iio_backend_ext_info_set(struct iio_dev *indio_dev, uintptr_t private,
const struct iio_chan_spec *chan,
const char *buf, size_t len);
ssize_t iio_backend_ext_info_get(struct iio_dev *indio_dev, uintptr_t private,
const struct iio_chan_spec *chan, char *buf);
int iio_backend_interface_type_get(struct iio_backend *back,
enum iio_backend_interface_type *type);
int iio_backend_data_size_set(struct iio_backend *back, unsigned int size);
int iio_backend_oversampling_ratio_set(struct iio_backend *back,
unsigned int chan,
unsigned int ratio);
int iio_backend_read_raw(struct iio_backend *back,
struct iio_chan_spec const *chan, int *val, int *val2,
long mask);
int iio_backend_extend_chan_spec(struct iio_backend *back,
struct iio_chan_spec *chan);
bool iio_backend_has_caps(struct iio_backend *back, u32 caps);
void *iio_backend_get_priv(const struct iio_backend *conv);
struct iio_backend *devm_iio_backend_get(struct device *dev, const char *name);
struct iio_backend *devm_iio_backend_fwnode_get(struct device *dev,
const char *name,
struct fwnode_handle *fwnode);
struct iio_backend *
__devm_iio_backend_get_from_fwnode_lookup(struct device *dev,
struct fwnode_handle *fwnode);
int devm_iio_backend_register(struct device *dev,
const struct iio_backend_info *info, void *priv);
static inline int iio_backend_read_scale(struct iio_backend *back,
struct iio_chan_spec const *chan,
int *val, int *val2)
{
return iio_backend_read_raw(back, chan, val, val2, IIO_CHAN_INFO_SCALE);
}
static inline int iio_backend_read_offset(struct iio_backend *back,
struct iio_chan_spec const *chan,
int *val, int *val2)
{
return iio_backend_read_raw(back, chan, val, val2,
IIO_CHAN_INFO_OFFSET);
}
ssize_t iio_backend_debugfs_print_chan_status(struct iio_backend *back,
unsigned int chan, char *buf,
size_t len);
void iio_backend_debugfs_add(struct iio_backend *back,
struct iio_dev *indio_dev);
#endif
@@ -0,0 +1,183 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright 2013-2015 Analog Devices Inc.
* Author: Lars-Peter Clausen <lars@metafoo.de>
*/
#ifndef __INDUSTRIALIO_DMA_BUFFER_H__
#define __INDUSTRIALIO_DMA_BUFFER_H__
#include <linux/atomic.h>
#include <linux/list.h>
#include <linux/kref.h>
#include <linux/spinlock.h>
#include <linux/mutex.h>
#include <linux/iio/buffer_impl.h>
struct iio_dma_buffer_queue;
struct iio_dma_buffer_ops;
struct device;
struct dma_buf_attachment;
struct dma_fence;
struct sg_table;
/**
* enum iio_block_state - State of a struct iio_dma_buffer_block
* @IIO_BLOCK_STATE_QUEUED: Block is on the incoming queue
* @IIO_BLOCK_STATE_ACTIVE: Block is currently being processed by the DMA
* @IIO_BLOCK_STATE_DONE: Block is on the outgoing queue
* @IIO_BLOCK_STATE_DEAD: Block has been marked as to be freed
*/
enum iio_block_state {
IIO_BLOCK_STATE_QUEUED,
IIO_BLOCK_STATE_ACTIVE,
IIO_BLOCK_STATE_DONE,
IIO_BLOCK_STATE_DEAD,
};
/**
* struct iio_dma_buffer_block - IIO buffer block
* @head: List head
* @size: Total size of the block in bytes
* @bytes_used: Number of bytes that contain valid data
* @vaddr: Virutal address of the blocks memory
* @phys_addr: Physical address of the blocks memory
* @queue: Parent DMA buffer queue
* @kref: kref used to manage the lifetime of block
* @state: Current state of the block
* @cyclic: True if this is a cyclic buffer
* @fileio: True if this buffer is used for fileio mode
* @sg_table: DMA table for the transfer when transferring a DMABUF
* @fence: DMA fence to be signaled when a DMABUF transfer is complete
*/
struct iio_dma_buffer_block {
/* May only be accessed by the owner of the block */
struct list_head head;
size_t bytes_used;
/*
* Set during allocation, constant thereafter. May be accessed read-only
* by anybody holding a reference to the block.
*/
void *vaddr;
dma_addr_t phys_addr;
size_t size;
struct iio_dma_buffer_queue *queue;
/* Must not be accessed outside the core. */
struct kref kref;
/*
* Must not be accessed outside the core. Access needs to hold
* queue->list_lock if the block is not owned by the core.
*/
enum iio_block_state state;
bool cyclic;
bool fileio;
struct sg_table *sg_table;
struct dma_fence *fence;
};
/**
* struct iio_dma_buffer_queue_fileio - FileIO state for the DMA buffer
* @blocks: Buffer blocks used for fileio
* @active_block: Block being used in read()
* @pos: Read offset in the active block
* @block_size: Size of each block
* @next_dequeue: index of next block that will be dequeued
* @enabled: Whether the buffer is operating in fileio mode
*/
struct iio_dma_buffer_queue_fileio {
struct iio_dma_buffer_block *blocks[2];
struct iio_dma_buffer_block *active_block;
size_t pos;
size_t block_size;
unsigned int next_dequeue;
bool enabled;
};
/**
* struct iio_dma_buffer_queue - DMA buffer base structure
* @buffer: IIO buffer base structure
* @dev: Parent device
* @ops: DMA buffer callbacks
* @lock: Protects the incoming list, active and the fields in the fileio
* substruct
* @list_lock: Protects lists that contain blocks which can be modified in
* atomic context as well as blocks on those lists. This is the outgoing queue
* list and typically also a list of active blocks in the part that handles
* the DMA controller
* @incoming: List of buffers on the incoming queue
* @active: Whether the buffer is currently active
* @num_dmabufs: Total number of DMABUFs attached to this queue
* @fileio: FileIO state
*/
struct iio_dma_buffer_queue {
struct iio_buffer buffer;
struct device *dev;
const struct iio_dma_buffer_ops *ops;
/*
* A mutex to protect accessing, configuring (eg: enqueuing DMA blocks)
* and do file IO on struct iio_dma_buffer_queue objects.
*/
struct mutex lock;
/* A spin lock to protect adding/removing blocks to the queue list */
spinlock_t list_lock;
struct list_head incoming;
bool active;
atomic_t num_dmabufs;
struct iio_dma_buffer_queue_fileio fileio;
};
/**
* struct iio_dma_buffer_ops - DMA buffer callback operations
* @submit: Called when a block is submitted to the DMA controller
* @abort: Should abort all pending transfers
*/
struct iio_dma_buffer_ops {
int (*submit)(struct iio_dma_buffer_queue *queue,
struct iio_dma_buffer_block *block);
void (*abort)(struct iio_dma_buffer_queue *queue);
};
void iio_dma_buffer_block_done(struct iio_dma_buffer_block *block);
void iio_dma_buffer_block_list_abort(struct iio_dma_buffer_queue *queue,
struct list_head *list);
int iio_dma_buffer_enable(struct iio_buffer *buffer, struct iio_dev *indio_dev);
int iio_dma_buffer_disable(struct iio_buffer *buffer,
struct iio_dev *indio_dev);
int iio_dma_buffer_read(struct iio_buffer *buffer, size_t n,
char __user *user_buffer);
int iio_dma_buffer_write(struct iio_buffer *buffer, size_t n,
const char __user *user_buffer);
size_t iio_dma_buffer_usage(struct iio_buffer *buffer);
int iio_dma_buffer_set_bytes_per_datum(struct iio_buffer *buffer, size_t bpd);
int iio_dma_buffer_set_length(struct iio_buffer *buffer, unsigned int length);
int iio_dma_buffer_request_update(struct iio_buffer *buffer);
void iio_dma_buffer_init(struct iio_dma_buffer_queue *queue, struct device *dev,
const struct iio_dma_buffer_ops *ops);
void iio_dma_buffer_exit(struct iio_dma_buffer_queue *queue);
void iio_dma_buffer_release(struct iio_dma_buffer_queue *queue);
struct iio_dma_buffer_block *
iio_dma_buffer_attach_dmabuf(struct iio_buffer *buffer,
struct dma_buf_attachment *attach);
void iio_dma_buffer_detach_dmabuf(struct iio_buffer *buffer,
struct iio_dma_buffer_block *block);
int iio_dma_buffer_enqueue_dmabuf(struct iio_buffer *buffer,
struct iio_dma_buffer_block *block,
struct dma_fence *fence,
struct sg_table *sgt,
size_t size, bool cyclic);
void iio_dma_buffer_lock_queue(struct iio_buffer *buffer);
void iio_dma_buffer_unlock_queue(struct iio_buffer *buffer);
struct device *iio_dma_buffer_get_dma_dev(struct iio_buffer *buffer);
#endif
@@ -0,0 +1,39 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright 2014-2015 Analog Devices Inc.
* Author: Lars-Peter Clausen <lars@metafoo.de>
*/
#ifndef __IIO_DMAENGINE_H__
#define __IIO_DMAENGINE_H__
#include <linux/iio/buffer.h>
struct iio_dev;
struct device;
struct dma_chan;
void iio_dmaengine_buffer_teardown(struct iio_buffer *buffer);
struct iio_buffer *iio_dmaengine_buffer_setup_ext(struct device *dev,
struct iio_dev *indio_dev,
const char *channel,
enum iio_buffer_direction dir);
#define iio_dmaengine_buffer_setup(dev, indio_dev, channel) \
iio_dmaengine_buffer_setup_ext(dev, indio_dev, channel, \
IIO_BUFFER_DIRECTION_IN)
int devm_iio_dmaengine_buffer_setup_ext(struct device *dev,
struct iio_dev *indio_dev,
const char *channel,
enum iio_buffer_direction dir);
int devm_iio_dmaengine_buffer_setup_with_handle(struct device *dev,
struct iio_dev *indio_dev,
struct dma_chan *chan,
enum iio_buffer_direction dir);
#define devm_iio_dmaengine_buffer_setup(dev, indio_dev, channel) \
devm_iio_dmaengine_buffer_setup_ext(dev, indio_dev, channel, \
IIO_BUFFER_DIRECTION_IN)
#endif
@@ -0,0 +1,82 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* The industrial I/O core - generic buffer interfaces.
*
* Copyright (c) 2008 Jonathan Cameron
*/
#ifndef _IIO_BUFFER_GENERIC_H_
#define _IIO_BUFFER_GENERIC_H_
#include <linux/sysfs.h>
#include <linux/iio/iio.h>
struct iio_buffer;
enum iio_buffer_direction {
IIO_BUFFER_DIRECTION_IN,
IIO_BUFFER_DIRECTION_OUT,
};
int iio_push_to_buffers(struct iio_dev *indio_dev, const void *data);
int iio_pop_from_buffer(struct iio_buffer *buffer, void *data);
/**
* iio_push_to_buffers_with_timestamp() - push data and timestamp to buffers
* @indio_dev: iio_dev structure for device.
* @data: sample data
* @timestamp: timestamp for the sample data
*
* DEPRECATED: Use iio_push_to_buffers_with_ts() instead.
*
* Returns 0 on success, a negative error code otherwise.
*/
static inline int iio_push_to_buffers_with_timestamp(struct iio_dev *indio_dev,
void *data, int64_t timestamp)
{
if (ACCESS_PRIVATE(indio_dev, scan_timestamp)) {
size_t ts_offset = indio_dev->scan_bytes / sizeof(int64_t) - 1;
((int64_t *)data)[ts_offset] = timestamp;
}
return iio_push_to_buffers(indio_dev, data);
}
/**
* iio_push_to_buffers_with_ts() - push data and timestamp to buffers
* @indio_dev: iio_dev structure for device.
* @data: Pointer to sample data buffer.
* @data_total_len: The size of @data in bytes.
* @timestamp: Timestamp for the sample data.
*
* Pushes data to the IIO device's buffers. If timestamps are enabled for the
* device the function will store the supplied timestamp as the last element in
* the sample data buffer before pushing it to the device buffers. The sample
* data buffer needs to be large enough to hold the additional timestamp
* (usually the buffer should be at least indio->scan_bytes bytes large).
*
* Context: Any context.
* Return: 0 on success, a negative error code otherwise.
*/
static inline int iio_push_to_buffers_with_ts(struct iio_dev *indio_dev,
void *data, size_t data_total_len,
s64 timestamp)
{
if (unlikely(data_total_len < indio_dev->scan_bytes)) {
dev_err(&indio_dev->dev, "Undersized storage pushed to buffer\n");
return -ENOSPC;
}
return iio_push_to_buffers_with_timestamp(indio_dev, data, timestamp);
}
int iio_push_to_buffers_with_ts_unaligned(struct iio_dev *indio_dev,
const void *data, size_t data_sz,
int64_t timestamp);
bool iio_validate_scan_mask_onehot(struct iio_dev *indio_dev,
const unsigned long *mask);
int iio_device_attach_buffer(struct iio_dev *indio_dev,
struct iio_buffer *buffer);
#endif /* _IIO_BUFFER_GENERIC_H_ */
@@ -0,0 +1,206 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _IIO_BUFFER_GENERIC_IMPL_H_
#define _IIO_BUFFER_GENERIC_IMPL_H_
#include <linux/sysfs.h>
#include <linux/kref.h>
#ifdef CONFIG_IIO_BUFFER
#include <uapi/linux/iio/buffer.h>
#include <linux/iio/buffer.h>
struct dma_buf_attachment;
struct dma_fence;
struct iio_dev;
struct iio_dma_buffer_block;
struct iio_buffer;
struct sg_table;
/**
* INDIO_BUFFER_FLAG_FIXED_WATERMARK - Watermark level of the buffer can not be
* configured. It has a fixed value which will be buffer specific.
*/
#define INDIO_BUFFER_FLAG_FIXED_WATERMARK BIT(0)
/**
* struct iio_buffer_access_funcs - access functions for buffers.
* @store_to: actually store stuff to the buffer - must be safe to
* call from any context (e.g. must not sleep).
* @read: try to get a specified number of bytes (must exist)
* @data_available: indicates how much data is available for reading from
* the buffer.
* @remove_from: remove scan from buffer. Drivers should calls this to
* remove a scan from a buffer.
* @write: try to write a number of bytes
* @space_available: returns the amount of bytes available in a buffer
* @request_update: if a parameter change has been marked, update underlying
* storage.
* @set_bytes_per_datum:set number of bytes per datum
* @set_length: set number of datums in buffer
* @enable: called if the buffer is attached to a device and the
* device starts sampling. Calls are balanced with
* @disable.
* @disable: called if the buffer is attached to a device and the
* device stops sampling. Calles are balanced with @enable.
* @release: called when the last reference to the buffer is dropped,
* should free all resources allocated by the buffer.
* @attach_dmabuf: called from userspace via ioctl to attach one external
* DMABUF.
* @detach_dmabuf: called from userspace via ioctl to detach one previously
* attached DMABUF.
* @enqueue_dmabuf: called from userspace via ioctl to queue this DMABUF
* object to this buffer. Requires a valid DMABUF fd, that
* was previouly attached to this buffer.
* @get_dma_dev: called to get the DMA channel associated with this buffer.
* @lock_queue: called when the core needs to lock the buffer queue;
* it is used when enqueueing DMABUF objects.
* @unlock_queue: used to unlock a previously locked buffer queue
* @modes: Supported operating modes by this buffer type
* @flags: A bitmask combination of INDIO_BUFFER_FLAG_*
*
* The purpose of this structure is to make the buffer element
* modular as event for a given driver, different usecases may require
* different buffer designs (space efficiency vs speed for example).
*
* It is worth noting that a given buffer implementation may only support a
* small proportion of these functions. The core code 'should' cope fine with
* any of them not existing.
**/
struct iio_buffer_access_funcs {
int (*store_to)(struct iio_buffer *buffer, const void *data);
int (*read)(struct iio_buffer *buffer, size_t n, char __user *buf);
size_t (*data_available)(struct iio_buffer *buffer);
int (*remove_from)(struct iio_buffer *buffer, void *data);
int (*write)(struct iio_buffer *buffer, size_t n, const char __user *buf);
size_t (*space_available)(struct iio_buffer *buffer);
int (*request_update)(struct iio_buffer *buffer);
int (*set_bytes_per_datum)(struct iio_buffer *buffer, size_t bpd);
int (*set_length)(struct iio_buffer *buffer, unsigned int length);
int (*enable)(struct iio_buffer *buffer, struct iio_dev *indio_dev);
int (*disable)(struct iio_buffer *buffer, struct iio_dev *indio_dev);
void (*release)(struct iio_buffer *buffer);
struct iio_dma_buffer_block * (*attach_dmabuf)(struct iio_buffer *buffer,
struct dma_buf_attachment *attach);
void (*detach_dmabuf)(struct iio_buffer *buffer,
struct iio_dma_buffer_block *block);
int (*enqueue_dmabuf)(struct iio_buffer *buffer,
struct iio_dma_buffer_block *block,
struct dma_fence *fence, struct sg_table *sgt,
size_t size, bool cyclic);
struct device * (*get_dma_dev)(struct iio_buffer *buffer);
void (*lock_queue)(struct iio_buffer *buffer);
void (*unlock_queue)(struct iio_buffer *buffer);
unsigned int modes;
unsigned int flags;
};
/**
* struct iio_buffer - general buffer structure
*
* Note that the internals of this structure should only be of interest to
* those writing new buffer implementations.
*/
struct iio_buffer {
/** @length: Number of datums in buffer. */
unsigned int length;
/** @flags: File ops flags including busy flag. */
unsigned long flags;
/** @bytes_per_datum: Size of individual datum including timestamp. */
size_t bytes_per_datum;
/** @direction: Direction of the data stream (in/out). */
enum iio_buffer_direction direction;
/**
* @access: Buffer access functions associated with the
* implementation.
*/
const struct iio_buffer_access_funcs *access;
/** @scan_mask: Bitmask used in masking scan mode elements. */
long *scan_mask;
/** @demux_list: List of operations required to demux the scan. */
struct list_head demux_list;
/** @pollq: Wait queue to allow for polling on the buffer. */
wait_queue_head_t pollq;
/** @watermark: Number of datums to wait for poll/read. */
unsigned int watermark;
/* private: */
/* @scan_timestamp: Does the scan mode include a timestamp. */
bool scan_timestamp;
/* @buffer_attr_list: List of buffer attributes. */
struct list_head buffer_attr_list;
/*
* @buffer_group: Attributes of the new buffer group.
* Includes scan elements attributes.
*/
struct attribute_group buffer_group;
/* @attrs: Standard attributes of the buffer. */
const struct iio_dev_attr **attrs;
/* @demux_bounce: Buffer for doing gather from incoming scan. */
void *demux_bounce;
/* @attached_entry: Entry in the devices list of buffers attached by the driver. */
struct list_head attached_entry;
/* @buffer_list: Entry in the devices list of current buffers. */
struct list_head buffer_list;
/* @ref: Reference count of the buffer. */
struct kref ref;
/* @dmabufs: List of DMABUF attachments */
struct list_head dmabufs; /* P: dmabufs_mutex */
/* @dmabufs_mutex: Protects dmabufs */
struct mutex dmabufs_mutex;
};
/**
* iio_update_buffers() - add or remove buffer from active list
* @indio_dev: device to add buffer to
* @insert_buffer: buffer to insert
* @remove_buffer: buffer_to_remove
*
* Note this will tear down all the buffering and build it up again
*
* Returns: 0 on success or -errno on error
*/
int iio_update_buffers(struct iio_dev *indio_dev,
struct iio_buffer *insert_buffer,
struct iio_buffer *remove_buffer);
/**
* iio_buffer_init() - Initialize the buffer structure
* @buffer: buffer to be initialized
**/
void iio_buffer_init(struct iio_buffer *buffer);
struct iio_buffer *iio_buffer_get(struct iio_buffer *buffer);
void iio_buffer_put(struct iio_buffer *buffer);
void iio_buffer_signal_dmabuf_done(struct dma_fence *fence, int ret);
#else /* CONFIG_IIO_BUFFER */
static inline void iio_buffer_get(struct iio_buffer *buffer) {}
static inline void iio_buffer_put(struct iio_buffer *buffer) {}
#endif /* CONFIG_IIO_BUFFER */
#endif /* _IIO_BUFFER_GENERIC_IMPL_H_ */
@@ -0,0 +1,131 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* ChromeOS EC sensor hub
*
* Copyright (C) 2016 Google, Inc
*/
#ifndef __CROS_EC_SENSORS_CORE_H
#define __CROS_EC_SENSORS_CORE_H
#include <linux/iio/iio.h>
#include <linux/irqreturn.h>
#include <linux/platform_data/cros_ec_commands.h>
#include <linux/platform_data/cros_ec_proto.h>
#include <linux/platform_data/cros_ec_sensorhub.h>
enum {
CROS_EC_SENSOR_X,
CROS_EC_SENSOR_Y,
CROS_EC_SENSOR_Z,
CROS_EC_SENSOR_MAX_AXIS,
};
/* EC returns sensor values using signed 16 bit registers */
#define CROS_EC_SENSOR_BITS 16
/*
* 4 16 bit channels are allowed.
* Good enough for current sensors, they use up to 3 16 bit vectors.
*/
#define CROS_EC_SAMPLE_SIZE (sizeof(s64) * 2)
typedef irqreturn_t (*cros_ec_sensors_capture_t)(int irq, void *p);
/**
* struct cros_ec_sensors_core_state - state data for EC sensors IIO driver
* @ec: cros EC device structure
* @cmd_lock: lock used to prevent simultaneous access to the
* commands.
* @msg: cros EC command structure
* @param: motion sensor parameters structure
* @resp: motion sensor response structure
* @type: type of motion sensor
* @range_updated: True if the range of the sensor has been
* updated.
* @curr_range: If updated, the current range value.
* It will be reapplied at every resume.
* @calib: calibration parameters. Note that trigger
* captured data will always provide the calibrated
* data
* @samples: static array to hold data from a single capture.
* For each channel we need 2 bytes, except for
* the timestamp. The timestamp is always last and
* is always 8-byte aligned.
* @read_ec_sensors_data: function used for accessing sensors values
* @fifo_max_event_count: Size of the EC sensor FIFO
* @frequencies: Table of known available frequencies:
* 0, Min and Max in mHz
*/
struct cros_ec_sensors_core_state {
struct cros_ec_device *ec;
struct mutex cmd_lock;
struct cros_ec_command *msg;
struct ec_params_motion_sense param;
struct ec_response_motion_sense *resp;
enum motionsensor_type type;
bool range_updated;
int curr_range;
struct calib_data {
s16 offset;
u16 scale;
} calib[CROS_EC_SENSOR_MAX_AXIS];
s8 sign[CROS_EC_SENSOR_MAX_AXIS];
u8 samples[CROS_EC_SAMPLE_SIZE] __aligned(8);
int (*read_ec_sensors_data)(struct iio_dev *indio_dev,
unsigned long scan_mask, s16 *data);
u32 fifo_max_event_count;
int frequencies[6];
};
int cros_ec_sensors_read_lpc(struct iio_dev *indio_dev, unsigned long scan_mask,
s16 *data);
int cros_ec_sensors_read_cmd(struct iio_dev *indio_dev, unsigned long scan_mask,
s16 *data);
struct platform_device;
int cros_ec_sensors_core_init(struct platform_device *pdev,
struct iio_dev *indio_dev, bool physical_device,
cros_ec_sensors_capture_t trigger_capture);
int cros_ec_sensors_core_register(struct device *dev,
struct iio_dev *indio_dev,
cros_ec_sensorhub_push_data_cb_t push_data);
irqreturn_t cros_ec_sensors_capture(int irq, void *p);
int cros_ec_sensors_push_data(struct iio_dev *indio_dev,
s16 *data,
s64 timestamp);
int cros_ec_motion_send_host_cmd(struct cros_ec_sensors_core_state *st,
u16 opt_length);
int cros_ec_sensors_core_read(struct cros_ec_sensors_core_state *st,
struct iio_chan_spec const *chan,
int *val, int *val2, long mask);
int cros_ec_sensors_core_read_avail(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
const int **vals,
int *type,
int *length,
long mask);
int cros_ec_sensors_core_write(struct cros_ec_sensors_core_state *st,
struct iio_chan_spec const *chan,
int val, int val2, long mask);
extern const struct dev_pm_ops cros_ec_sensors_pm_ops;
/* List of extended channel specification for all sensors. */
extern const struct iio_chan_spec_ext_info cros_ec_sensors_ext_info[];
extern const struct iio_chan_spec_ext_info cros_ec_sensors_limited_info[];
#endif /* __CROS_EC_SENSORS_CORE_H */
@@ -0,0 +1,94 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (C) 2020 Invensense, Inc.
*/
#ifndef INV_SENSORS_TIMESTAMP_H_
#define INV_SENSORS_TIMESTAMP_H_
/**
* struct inv_sensors_timestamp_chip - chip internal properties
* @clock_period: internal clock period in ns
* @jitter: acceptable jitter in per-mille
* @init_period: chip initial period at reset in ns
*/
struct inv_sensors_timestamp_chip {
uint32_t clock_period;
uint32_t jitter;
uint32_t init_period;
};
/**
* struct inv_sensors_timestamp_interval - timestamps interval
* @lo: interval lower bound
* @up: interval upper bound
*/
struct inv_sensors_timestamp_interval {
int64_t lo;
int64_t up;
};
/**
* struct inv_sensors_timestamp_acc - accumulator for computing an estimation
* @val: current estimation of the value, the mean of all values
* @idx: current index of the next free place in values table
* @values: table of all measured values, use for computing the mean
*/
struct inv_sensors_timestamp_acc {
uint32_t val;
size_t idx;
uint32_t values[32];
};
/**
* struct inv_sensors_timestamp - timestamp management states
* @chip: chip internal characteristics
* @min_period: minimal acceptable clock period
* @max_period: maximal acceptable clock period
* @it: interrupts interval timestamps
* @timestamp: store last timestamp for computing next data timestamp
* @mult: current internal period multiplier
* @new_mult: new set internal period multiplier (not yet effective)
* @period: measured current period of the sensor
* @chip_period: accumulator for computing internal chip period
*/
struct inv_sensors_timestamp {
struct inv_sensors_timestamp_chip chip;
uint32_t min_period;
uint32_t max_period;
struct inv_sensors_timestamp_interval it;
int64_t timestamp;
uint32_t mult;
uint32_t new_mult;
uint32_t period;
struct inv_sensors_timestamp_acc chip_period;
};
void inv_sensors_timestamp_init(struct inv_sensors_timestamp *ts,
const struct inv_sensors_timestamp_chip *chip);
int inv_sensors_timestamp_update_odr(struct inv_sensors_timestamp *ts,
uint32_t period, bool fifo);
void inv_sensors_timestamp_interrupt(struct inv_sensors_timestamp *ts,
size_t sample_nb, int64_t timestamp);
static inline int64_t inv_sensors_timestamp_pop(struct inv_sensors_timestamp *ts)
{
ts->timestamp += ts->period;
return ts->timestamp;
}
void inv_sensors_timestamp_apply_odr(struct inv_sensors_timestamp *ts,
uint32_t fifo_period, size_t fifo_nb,
unsigned int fifo_no);
static inline void inv_sensors_timestamp_reset(struct inv_sensors_timestamp *ts)
{
const struct inv_sensors_timestamp_interval interval_init = {0LL, 0LL};
ts->it = interval_init;
ts->timestamp = 0;
}
#endif
@@ -0,0 +1,72 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Copyright (C) 2014, Samsung Electronics Co. Ltd. All Rights Reserved.
*/
#ifndef _SSP_SENSORS_H_
#define _SSP_SENSORS_H_
#include <linux/iio/iio.h>
#define SSP_TIME_SIZE 4
#define SSP_ACCELEROMETER_SIZE 6
#define SSP_GYROSCOPE_SIZE 6
#define SSP_BIO_HRM_RAW_SIZE 8
#define SSP_BIO_HRM_RAW_FAC_SIZE 36
#define SSP_BIO_HRM_LIB_SIZE 8
/**
* enum ssp_sensor_type - SSP sensor type
*/
enum ssp_sensor_type {
SSP_ACCELEROMETER_SENSOR = 0,
SSP_GYROSCOPE_SENSOR,
SSP_GEOMAGNETIC_UNCALIB_SENSOR,
SSP_GEOMAGNETIC_RAW,
SSP_GEOMAGNETIC_SENSOR,
SSP_PRESSURE_SENSOR,
SSP_GESTURE_SENSOR,
SSP_PROXIMITY_SENSOR,
SSP_TEMPERATURE_HUMIDITY_SENSOR,
SSP_LIGHT_SENSOR,
SSP_PROXIMITY_RAW,
SSP_ORIENTATION_SENSOR,
SSP_STEP_DETECTOR,
SSP_SIG_MOTION_SENSOR,
SSP_GYRO_UNCALIB_SENSOR,
SSP_GAME_ROTATION_VECTOR,
SSP_ROTATION_VECTOR,
SSP_STEP_COUNTER,
SSP_BIO_HRM_RAW,
SSP_BIO_HRM_RAW_FAC,
SSP_BIO_HRM_LIB,
SSP_SENSOR_MAX,
};
struct ssp_data;
/**
* struct ssp_sensor_data - Sensor object
* @process_data: Callback to feed sensor data.
* @type: Used sensor type.
* @buffer: Received data buffer.
*/
struct ssp_sensor_data {
int (*process_data)(struct iio_dev *indio_dev, void *buf,
int64_t timestamp);
enum ssp_sensor_type type;
u8 *buffer;
};
void ssp_register_consumer(struct iio_dev *indio_dev,
enum ssp_sensor_type type);
int ssp_enable_sensor(struct ssp_data *data, enum ssp_sensor_type type,
u32 delay);
int ssp_disable_sensor(struct ssp_data *data, enum ssp_sensor_type type);
u32 ssp_get_sensor_delay(struct ssp_data *data, enum ssp_sensor_type);
int ssp_change_delay(struct ssp_data *data, enum ssp_sensor_type type,
u32 delay);
#endif /* _SSP_SENSORS_H_ */
@@ -0,0 +1,338 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* STMicroelectronics sensors library driver
*
* Copyright 2012-2013 STMicroelectronics Inc.
*
* Denis Ciocca <denis.ciocca@st.com>
*/
#ifndef ST_SENSORS_H
#define ST_SENSORS_H
#include <linux/i2c.h>
#include <linux/spi/spi.h>
#include <linux/irqreturn.h>
#include <linux/iio/iio.h>
#include <linux/iio/trigger.h>
#include <linux/bitops.h>
#include <linux/regulator/consumer.h>
#include <linux/regmap.h>
#include <linux/platform_data/st_sensors_pdata.h>
#define LSM9DS0_IMU_DEV_NAME "lsm9ds0"
#define LSM303D_IMU_DEV_NAME "lsm303d"
/*
* Buffer size max case: 2bytes per channel, 3 channels in total +
* 8bytes timestamp channel (s64)
*/
#define ST_SENSORS_MAX_BUFFER_SIZE (ALIGN(2 * 3, sizeof(s64)) + \
sizeof(s64))
#define ST_SENSORS_ODR_LIST_MAX 10
#define ST_SENSORS_FULLSCALE_AVL_MAX 10
#define ST_SENSORS_NUMBER_ALL_CHANNELS 4
#define ST_SENSORS_ENABLE_ALL_AXIS 0x07
#define ST_SENSORS_SCAN_X 0
#define ST_SENSORS_SCAN_Y 1
#define ST_SENSORS_SCAN_Z 2
#define ST_SENSORS_DEFAULT_POWER_ON_VALUE 0x01
#define ST_SENSORS_DEFAULT_POWER_OFF_VALUE 0x00
#define ST_SENSORS_DEFAULT_WAI_ADDRESS 0x0f
#define ST_SENSORS_DEFAULT_AXIS_ADDR 0x20
#define ST_SENSORS_DEFAULT_AXIS_MASK 0x07
#define ST_SENSORS_DEFAULT_AXIS_N_BIT 3
#define ST_SENSORS_DEFAULT_STAT_ADDR 0x27
#define ST_SENSORS_MAX_NAME 17
#define ST_SENSORS_MAX_4WAI 8
#define ST_SENSORS_LSM_CHANNELS_EXT(device_type, mask, index, mod, \
ch2, s, endian, rbits, sbits, addr, ext) \
{ \
.type = device_type, \
.modified = mod, \
.info_mask_separate = mask, \
.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \
.scan_index = index, \
.channel2 = ch2, \
.address = addr, \
.scan_type = { \
.sign = s, \
.realbits = rbits, \
.shift = sbits - rbits, \
.storagebits = sbits, \
.endianness = endian, \
}, \
.ext_info = ext, \
}
#define ST_SENSORS_LSM_CHANNELS(device_type, mask, index, mod, \
ch2, s, endian, rbits, sbits, addr) \
ST_SENSORS_LSM_CHANNELS_EXT(device_type, mask, index, mod, \
ch2, s, endian, rbits, sbits, addr, NULL)
#define ST_SENSORS_DEV_ATTR_SAMP_FREQ_AVAIL() \
IIO_DEV_ATTR_SAMP_FREQ_AVAIL( \
st_sensors_sysfs_sampling_frequency_avail)
#define ST_SENSORS_DEV_ATTR_SCALE_AVAIL(name) \
IIO_DEVICE_ATTR(name, S_IRUGO, \
st_sensors_sysfs_scale_avail, NULL , 0);
struct st_sensor_odr_avl {
unsigned int hz;
u8 value;
};
struct st_sensor_odr {
u8 addr;
u8 mask;
struct st_sensor_odr_avl odr_avl[ST_SENSORS_ODR_LIST_MAX];
};
struct st_sensor_power {
u8 addr;
u8 mask;
u8 value_off;
u8 value_on;
};
struct st_sensor_axis {
u8 addr;
u8 mask;
};
struct st_sensor_fullscale_avl {
unsigned int num;
u8 value;
unsigned int gain;
unsigned int gain2;
};
struct st_sensor_fullscale {
u8 addr;
u8 mask;
struct st_sensor_fullscale_avl fs_avl[ST_SENSORS_FULLSCALE_AVL_MAX];
};
struct st_sensor_sim {
u8 addr;
u8 value;
};
/**
* struct st_sensor_bdu - ST sensor device block data update
* @addr: address of the register.
* @mask: mask to write the block data update flag.
*/
struct st_sensor_bdu {
u8 addr;
u8 mask;
};
/**
* struct st_sensor_das - ST sensor device data alignment selection
* @addr: address of the register.
* @mask: mask to write the das flag for left alignment.
*/
struct st_sensor_das {
u8 addr;
u8 mask;
};
/**
* struct st_sensor_int_drdy - ST sensor device drdy line parameters
* @addr: address of INT drdy register.
* @mask: mask to enable drdy line.
* @addr_od: address to enable/disable Open Drain on the INT line.
* @mask_od: mask to enable/disable Open Drain on the INT line.
*/
struct st_sensor_int_drdy {
u8 addr;
u8 mask;
u8 addr_od;
u8 mask_od;
};
/**
* struct st_sensor_data_ready_irq - ST sensor device data-ready interrupt
* @int1: data-ready configuration register for INT1 pin.
* @int2: data-ready configuration register for INT2 pin.
* @addr_ihl: address to enable/disable active low on the INT lines.
* @mask_ihl: mask to enable/disable active low on the INT lines.
* @stat_drdy: status register of DRDY (data ready) interrupt.
* @ig1: represents the Interrupt Generator 1 of sensors.
* @en_addr: address of the enable ig1 register.
* @en_mask: mask to write the on/off value for enable.
*/
struct st_sensor_data_ready_irq {
struct st_sensor_int_drdy int1;
struct st_sensor_int_drdy int2;
u8 addr_ihl;
u8 mask_ihl;
struct {
u8 addr;
u8 mask;
} stat_drdy;
struct {
u8 en_addr;
u8 en_mask;
} ig1;
};
/**
* struct st_sensor_settings - ST specific sensor settings
* @wai: Contents of WhoAmI register.
* @wai_addr: The address of WhoAmI register.
* @sensors_supported: List of supported sensors by struct itself.
* @ch: IIO channels for the sensor.
* @num_ch: Number of IIO channels in @ch
* @odr: Output data rate register and ODR list available.
* @pw: Power register of the sensor.
* @enable_axis: Enable one or more axis of the sensor.
* @fs: Full scale register and full scale list available.
* @bdu: Block data update register.
* @das: Data Alignment Selection register.
* @drdy_irq: Data ready register of the sensor.
* @sim: SPI serial interface mode register of the sensor.
* @multi_read_bit: Use or not particular bit for [I2C/SPI] multi-read.
* @bootime: samples to discard when sensor passing from power-down to power-up.
*/
struct st_sensor_settings {
u8 wai;
u8 wai_addr;
char sensors_supported[ST_SENSORS_MAX_4WAI][ST_SENSORS_MAX_NAME];
struct iio_chan_spec *ch;
int num_ch;
struct st_sensor_odr odr;
struct st_sensor_power pw;
struct st_sensor_axis enable_axis;
struct st_sensor_fullscale fs;
struct st_sensor_bdu bdu;
struct st_sensor_das das;
struct st_sensor_data_ready_irq drdy_irq;
struct st_sensor_sim sim;
bool multi_read_bit;
unsigned int bootime;
};
/**
* struct st_sensor_data - ST sensor device status
* @trig: The trigger in use by the core driver.
* @mount_matrix: The mounting matrix of the sensor.
* @sensor_settings: Pointer to the specific sensor settings in use.
* @current_fullscale: Maximum range of measure by the sensor.
* @regmap: Pointer to specific sensor regmap configuration.
* @enabled: Status of the sensor (false->off, true->on).
* @odr: Output data rate of the sensor [Hz].
* @num_data_channels: Number of data channels used in buffer.
* @drdy_int_pin: Redirect DRDY on pin 1 (1) or pin 2 (2).
* @int_pin_open_drain: Set the interrupt/DRDY to open drain.
* @irq: the IRQ number.
* @edge_irq: the IRQ triggers on edges and need special handling.
* @hw_irq_trigger: if we're using the hardware interrupt on the sensor.
* @hw_timestamp: Latest timestamp from the interrupt handler, when in use.
* @buffer_data: Data used by buffer part.
* @odr_lock: Local lock for preventing concurrent ODR accesses/changes
*/
struct st_sensor_data {
struct iio_trigger *trig;
struct iio_mount_matrix mount_matrix;
struct st_sensor_settings *sensor_settings;
struct st_sensor_fullscale_avl *current_fullscale;
struct regmap *regmap;
bool enabled;
unsigned int odr;
unsigned int num_data_channels;
u8 drdy_int_pin;
bool int_pin_open_drain;
int irq;
bool edge_irq;
bool hw_irq_trigger;
s64 hw_timestamp;
struct mutex odr_lock;
char buffer_data[ST_SENSORS_MAX_BUFFER_SIZE] __aligned(IIO_DMA_MINALIGN);
};
#ifdef CONFIG_IIO_BUFFER
irqreturn_t st_sensors_trigger_handler(int irq, void *p);
#endif
#ifdef CONFIG_IIO_TRIGGER
int st_sensors_allocate_trigger(struct iio_dev *indio_dev,
const struct iio_trigger_ops *trigger_ops);
int st_sensors_validate_device(struct iio_trigger *trig,
struct iio_dev *indio_dev);
#else
static inline int st_sensors_allocate_trigger(struct iio_dev *indio_dev,
const struct iio_trigger_ops *trigger_ops)
{
return 0;
}
#define st_sensors_validate_device NULL
#endif
int st_sensors_init_sensor(struct iio_dev *indio_dev,
struct st_sensors_platform_data *pdata);
int st_sensors_set_enable(struct iio_dev *indio_dev, bool enable);
int st_sensors_set_axis_enable(struct iio_dev *indio_dev, u8 axis_enable);
int st_sensors_power_enable(struct iio_dev *indio_dev);
int st_sensors_debugfs_reg_access(struct iio_dev *indio_dev,
unsigned reg, unsigned writeval,
unsigned *readval);
int st_sensors_set_odr(struct iio_dev *indio_dev, unsigned int odr);
int st_sensors_set_dataready_irq(struct iio_dev *indio_dev, bool enable);
int st_sensors_set_fullscale_by_gain(struct iio_dev *indio_dev, int scale);
int st_sensors_read_info_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *ch, int *val);
int st_sensors_get_settings_index(const char *name,
const struct st_sensor_settings *list,
const int list_length);
int st_sensors_verify_id(struct iio_dev *indio_dev);
ssize_t st_sensors_sysfs_sampling_frequency_avail(struct device *dev,
struct device_attribute *attr, char *buf);
ssize_t st_sensors_sysfs_scale_avail(struct device *dev,
struct device_attribute *attr, char *buf);
void st_sensors_dev_name_probe(struct device *dev, char *name, int len);
/* Accelerometer */
const struct st_sensor_settings *st_accel_get_settings(const char *name);
int st_accel_common_probe(struct iio_dev *indio_dev);
/* Gyroscope */
const struct st_sensor_settings *st_gyro_get_settings(const char *name);
int st_gyro_common_probe(struct iio_dev *indio_dev);
/* Magnetometer */
const struct st_sensor_settings *st_magn_get_settings(const char *name);
int st_magn_common_probe(struct iio_dev *indio_dev);
/* Pressure */
const struct st_sensor_settings *st_press_get_settings(const char *name);
int st_press_common_probe(struct iio_dev *indio_dev);
#endif /* ST_SENSORS_H */
@@ -0,0 +1,19 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* STMicroelectronics sensors i2c library driver
*
* Copyright 2012-2013 STMicroelectronics Inc.
*
* Denis Ciocca <denis.ciocca@st.com>
*/
#ifndef ST_SENSORS_I2C_H
#define ST_SENSORS_I2C_H
#include <linux/i2c.h>
#include <linux/iio/common/st_sensors.h>
int st_sensors_i2c_configure(struct iio_dev *indio_dev,
struct i2c_client *client);
#endif /* ST_SENSORS_I2C_H */
@@ -0,0 +1,19 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* STMicroelectronics sensors spi library driver
*
* Copyright 2012-2013 STMicroelectronics Inc.
*
* Denis Ciocca <denis.ciocca@st.com>
*/
#ifndef ST_SENSORS_SPI_H
#define ST_SENSORS_SPI_H
#include <linux/spi/spi.h>
#include <linux/iio/common/st_sensors.h>
int st_sensors_spi_configure(struct iio_dev *indio_dev,
struct spi_device *spi);
#endif /* ST_SENSORS_SPI_H */
@@ -0,0 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Industrial I/O configfs support
*
* Copyright (c) 2015 Intel Corporation
*/
#ifndef __IIO_CONFIGFS
#define __IIO_CONFIGFS
extern struct configfs_subsystem iio_configfs_subsys;
#endif /* __IIO_CONFIGFS */
@@ -0,0 +1,473 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Industrial I/O in kernel consumer interface
*
* Copyright (c) 2011 Jonathan Cameron
*/
#ifndef _IIO_INKERN_CONSUMER_H_
#define _IIO_INKERN_CONSUMER_H_
#include <linux/types.h>
#include <linux/iio/types.h>
struct iio_dev;
struct iio_chan_spec;
struct device;
struct fwnode_handle;
/**
* struct iio_channel - everything needed for a consumer to use a channel
* @indio_dev: Device on which the channel exists.
* @channel: Full description of the channel.
* @data: Data about the channel used by consumer.
*/
struct iio_channel {
struct iio_dev *indio_dev;
const struct iio_chan_spec *channel;
void *data;
};
/**
* iio_channel_get() - get description of all that is needed to access channel.
* @dev: Pointer to consumer device. Device name must match
* the name of the device as provided in the iio_map
* with which the desired provider to consumer mapping
* was registered.
* @consumer_channel: Unique name to identify the channel on the consumer
* side. This typically describes the channels use within
* the consumer. E.g. 'battery_voltage'
*/
struct iio_channel *iio_channel_get(struct device *dev,
const char *consumer_channel);
/**
* iio_channel_release() - release channels obtained via iio_channel_get
* @chan: The channel to be released.
*/
void iio_channel_release(struct iio_channel *chan);
/**
* devm_iio_channel_get() - Resource managed version of iio_channel_get().
* @dev: Pointer to consumer device. Device name must match
* the name of the device as provided in the iio_map
* with which the desired provider to consumer mapping
* was registered.
* @consumer_channel: Unique name to identify the channel on the consumer
* side. This typically describes the channels use within
* the consumer. E.g. 'battery_voltage'
*
* Returns a pointer to negative errno if it is not able to get the iio channel
* otherwise returns valid pointer for iio channel.
*
* The allocated iio channel is automatically released when the device is
* unbound.
*/
struct iio_channel *devm_iio_channel_get(struct device *dev,
const char *consumer_channel);
/**
* iio_channel_get_all() - get all channels associated with a client
* @dev: Pointer to consumer device.
*
* Returns an array of iio_channel structures terminated with one with
* null iio_dev pointer.
* This function is used by fairly generic consumers to get all the
* channels registered as having this consumer.
*/
struct iio_channel *iio_channel_get_all(struct device *dev);
/**
* iio_channel_release_all() - reverse iio_channel_get_all
* @chan: Array of channels to be released.
*/
void iio_channel_release_all(struct iio_channel *chan);
/**
* devm_iio_channel_get_all() - Resource managed version of
* iio_channel_get_all().
* @dev: Pointer to consumer device.
*
* Returns a pointer to negative errno if it is not able to get the iio channel
* otherwise returns an array of iio_channel structures terminated with one with
* null iio_dev pointer.
*
* This function is used by fairly generic consumers to get all the
* channels registered as having this consumer.
*
* The allocated iio channels are automatically released when the device is
* unbounded.
*/
struct iio_channel *devm_iio_channel_get_all(struct device *dev);
/**
* fwnode_iio_channel_get_by_name() - get description of all that is needed to access channel.
* @fwnode: Pointer to consumer Firmware node
* @consumer_channel: Unique name to identify the channel on the consumer
* side. This typically describes the channels use within
* the consumer. E.g. 'battery_voltage'
*/
struct iio_channel *fwnode_iio_channel_get_by_name(struct fwnode_handle *fwnode,
const char *name);
/**
* devm_fwnode_iio_channel_get_by_name() - Resource managed version of
* fwnode_iio_channel_get_by_name().
* @dev: Pointer to consumer device.
* @fwnode: Pointer to consumer Firmware node
* @consumer_channel: Unique name to identify the channel on the consumer
* side. This typically describes the channels use within
* the consumer. E.g. 'battery_voltage'
*
* Returns a pointer to negative errno if it is not able to get the iio channel
* otherwise returns valid pointer for iio channel.
*
* The allocated iio channel is automatically released when the device is
* unbound.
*/
struct iio_channel *devm_fwnode_iio_channel_get_by_name(struct device *dev,
struct fwnode_handle *fwnode,
const char *consumer_channel);
struct iio_cb_buffer;
/**
* iio_channel_get_all_cb() - register callback for triggered capture
* @dev: Pointer to client device.
* @cb: Callback function. Must be safe to call from any context
* (e.g. must not sleep).
* @private: Private data passed to callback.
*
* NB right now we have no ability to mux data from multiple devices.
* So if the channels requested come from different devices this will
* fail.
*/
struct iio_cb_buffer *iio_channel_get_all_cb(struct device *dev,
int (*cb)(const void *data,
void *private),
void *private);
/**
* iio_channel_cb_set_buffer_watermark() - set the buffer watermark.
* @cb_buffer: The callback buffer from whom we want the channel
* information.
* @watermark: buffer watermark in bytes.
*
* This function allows to configure the buffer watermark.
*/
int iio_channel_cb_set_buffer_watermark(struct iio_cb_buffer *cb_buffer,
size_t watermark);
/**
* iio_channel_release_all_cb() - release and unregister the callback.
* @cb_buffer: The callback buffer that was allocated.
*/
void iio_channel_release_all_cb(struct iio_cb_buffer *cb_buffer);
/**
* iio_channel_start_all_cb() - start the flow of data through callback.
* @cb_buff: The callback buffer we are starting.
*/
int iio_channel_start_all_cb(struct iio_cb_buffer *cb_buff);
/**
* iio_channel_stop_all_cb() - stop the flow of data through the callback.
* @cb_buff: The callback buffer we are stopping.
*/
void iio_channel_stop_all_cb(struct iio_cb_buffer *cb_buff);
/**
* iio_channel_cb_get_channels() - get access to the underlying channels.
* @cb_buffer: The callback buffer from whom we want the channel
* information.
*
* This function allows one to obtain information about the channels.
* Whilst this may allow direct reading if all buffers are disabled, the
* primary aim is to allow drivers that are consuming a channel to query
* things like scaling of the channel.
*/
struct iio_channel
*iio_channel_cb_get_channels(const struct iio_cb_buffer *cb_buffer);
/**
* iio_channel_cb_get_iio_dev() - get access to the underlying device.
* @cb_buffer: The callback buffer from whom we want the device
* information.
*
* This function allows one to obtain information about the device.
* The primary aim is to allow drivers that are consuming a device to query
* things like current trigger.
*/
struct iio_dev
*iio_channel_cb_get_iio_dev(const struct iio_cb_buffer *cb_buffer);
/**
* iio_read_channel_raw() - read from a given channel
* @chan: The channel being queried.
* @val: Value read back.
*
* Note, if standard units are required, raw reads from iio channels
* need the offset (default 0) and scale (default 1) to be applied
* as (raw + offset) * scale.
*/
int iio_read_channel_raw(struct iio_channel *chan,
int *val);
/**
* iio_read_channel_average_raw() - read from a given channel
* @chan: The channel being queried.
* @val: Value read back.
*
* Note, if standard units are required, raw reads from iio channels
* need the offset (default 0) and scale (default 1) to be applied
* as (raw + offset) * scale.
*
* In opposit to the normal iio_read_channel_raw this function
* returns the average of multiple reads.
*/
int iio_read_channel_average_raw(struct iio_channel *chan, int *val);
/**
* iio_read_channel_processed() - read processed value from a given channel
* @chan: The channel being queried.
* @val: Value read back.
*
* Returns an error code or 0.
*
* This function will read a processed value from a channel. A processed value
* means that this value will have the correct unit and not some device internal
* representation. If the device does not support reporting a processed value
* the function will query the raw value and the channels scale and offset and
* do the appropriate transformation.
*/
int iio_read_channel_processed(struct iio_channel *chan, int *val);
/**
* iio_read_channel_processed_scale() - read and scale a processed value
* @chan: The channel being queried.
* @val: Value read back.
* @scale: Scale factor to apply during the conversion
*
* Returns an error code or 0.
*
* This function will read a processed value from a channel. This will work
* like @iio_read_channel_processed() but also scale with an additional
* scale factor while attempting to minimize any precision loss.
*/
int iio_read_channel_processed_scale(struct iio_channel *chan, int *val,
unsigned int scale);
/**
* iio_write_channel_attribute() - Write values to the device attribute.
* @chan: The channel being queried.
* @val: Value being written.
* @val2: Value being written.val2 use depends on attribute type.
* @attribute: info attribute to be read.
*
* Returns an error code or 0.
*/
int iio_write_channel_attribute(struct iio_channel *chan, int val,
int val2, enum iio_chan_info_enum attribute);
/**
* iio_read_channel_attribute() - Read values from the device attribute.
* @chan: The channel being queried.
* @val: Value being written.
* @val2: Value being written.Val2 use depends on attribute type.
* @attribute: info attribute to be written.
*
* Returns an error code if failed. Else returns a description of what is in val
* and val2, such as IIO_VAL_INT_PLUS_MICRO telling us we have a value of val
* + val2/1e6
*/
int iio_read_channel_attribute(struct iio_channel *chan, int *val,
int *val2, enum iio_chan_info_enum attribute);
/**
* iio_write_channel_raw() - write to a given channel
* @chan: The channel being queried.
* @val: Value being written.
*
* Note that for raw writes to iio channels, if the value provided is
* in standard units, the affect of the scale and offset must be removed
* as (value / scale) - offset.
*/
int iio_write_channel_raw(struct iio_channel *chan, int val);
/**
* iio_read_max_channel_raw() - read maximum available raw value from a given
* channel, i.e. the maximum possible value.
* @chan: The channel being queried.
* @val: Value read back.
*
* Note, if standard units are required, raw reads from iio channels
* need the offset (default 0) and scale (default 1) to be applied
* as (raw + offset) * scale.
*/
int iio_read_max_channel_raw(struct iio_channel *chan, int *val);
/**
* iio_read_min_channel_raw() - read minimum available raw value from a given
* channel, i.e. the minimum possible value.
* @chan: The channel being queried.
* @val: Value read back.
*
* Note, if standard units are required, raw reads from iio channels
* need the offset (default 0) and scale (default 1) to be applied
* as (raw + offset) * scale.
*/
int iio_read_min_channel_raw(struct iio_channel *chan, int *val);
/**
* iio_read_avail_channel_raw() - read available raw values from a given channel
* @chan: The channel being queried.
* @vals: Available values read back.
* @length: Number of entries in vals.
*
* Returns an error code, IIO_AVAIL_RANGE or IIO_AVAIL_LIST.
*
* For ranges, three vals are always returned; min, step and max.
* For lists, all the possible values are enumerated.
*
* Note, if standard units are required, raw available values from iio
* channels need the offset (default 0) and scale (default 1) to be applied
* as (raw + offset) * scale.
*/
int iio_read_avail_channel_raw(struct iio_channel *chan,
const int **vals, int *length);
/**
* iio_read_avail_channel_attribute() - read available channel attribute values
* @chan: The channel being queried.
* @vals: Available values read back.
* @type: Type of values read back.
* @length: Number of entries in vals.
* @attribute: info attribute to be read back.
*
* Returns an error code, IIO_AVAIL_RANGE or IIO_AVAIL_LIST.
*/
int iio_read_avail_channel_attribute(struct iio_channel *chan,
const int **vals, int *type, int *length,
enum iio_chan_info_enum attribute);
/**
* iio_get_channel_type() - get the type of a channel
* @channel: The channel being queried.
* @type: The type of the channel.
*
* returns the enum iio_chan_type of the channel
*/
int iio_get_channel_type(struct iio_channel *channel,
enum iio_chan_type *type);
/**
* iio_read_channel_offset() - read the offset value for a channel
* @chan: The channel being queried.
* @val: First part of value read back.
* @val2: Second part of value read back.
*
* Note returns a description of what is in val and val2, such
* as IIO_VAL_INT_PLUS_MICRO telling us we have a value of val
* + val2/1e6
*/
int iio_read_channel_offset(struct iio_channel *chan, int *val,
int *val2);
/**
* iio_read_channel_scale() - read the scale value for a channel
* @chan: The channel being queried.
* @val: First part of value read back.
* @val2: Second part of value read back.
*
* Note returns a description of what is in val and val2, such
* as IIO_VAL_INT_PLUS_MICRO telling us we have a value of val
* + val2/1e6
*/
int iio_read_channel_scale(struct iio_channel *chan, int *val,
int *val2);
/**
* iio_multiply_value() - Multiply an IIO value
* @result: Destination pointer for the multiplication result
* @multiplier: Multiplier.
* @type: One of the IIO_VAL_* constants. This decides how the @val and
* @val2 parameters are interpreted.
* @val: Value being multiplied.
* @val2: Value being multiplied. @val2 use depends on type.
*
* Multiply an IIO value with a s64 multiplier storing the result as
* IIO_VAL_INT. This is typically used for scaling.
*
* Returns:
* IIO_VAL_INT on success or a negative error-number on failure.
*/
int iio_multiply_value(int *result, s64 multiplier,
unsigned int type, int val, int val2);
/**
* iio_convert_raw_to_processed() - Converts a raw value to a processed value
* @chan: The channel being queried
* @raw: The raw IIO to convert
* @processed: The result of the conversion
* @scale: Scale factor to apply during the conversion
*
* Returns an error code or 0.
*
* This function converts a raw value to processed value for a specific channel.
* A raw value is the device internal representation of a sample and the value
* returned by iio_read_channel_raw, so the unit of that value is device
* depended. A processed value on the other hand is value has a normed unit
* according with the IIO specification.
*
* The scale factor allows to increase the precession of the returned value. For
* a scale factor of 1 the function will return the result in the normal IIO
* unit for the channel type. E.g. millivolt for voltage channels, if you want
* nanovolts instead pass 1000000 as the scale factor.
*/
int iio_convert_raw_to_processed(struct iio_channel *chan, int raw,
int *processed, unsigned int scale);
/**
* iio_get_channel_ext_info_count() - get number of ext_info attributes
* connected to the channel.
* @chan: The channel being queried
*
* Returns the number of ext_info attributes
*/
unsigned int iio_get_channel_ext_info_count(struct iio_channel *chan);
/**
* iio_read_channel_ext_info() - read ext_info attribute from a given channel
* @chan: The channel being queried.
* @attr: The ext_info attribute to read.
* @buf: Where to store the attribute value. Assumed to hold
* at least PAGE_SIZE bytes and to be aligned at PAGE_SIZE.
*
* Returns the number of bytes written to buf (perhaps w/o zero termination;
* it need not even be a string), or an error code.
*/
ssize_t iio_read_channel_ext_info(struct iio_channel *chan,
const char *attr, char *buf);
/**
* iio_write_channel_ext_info() - write ext_info attribute from a given channel
* @chan: The channel being queried.
* @attr: The ext_info attribute to read.
* @buf: The new attribute value. Strings needs to be zero-
* terminated, but the terminator should not be included
* in the below len.
* @len: The size of the new attribute value.
*
* Returns the number of accepted bytes, which should be the same as len.
* An error code can also be returned.
*/
ssize_t iio_write_channel_ext_info(struct iio_channel *chan, const char *attr,
const char *buf, size_t len);
/**
* iio_read_channel_label() - read label for a given channel
* @chan: The channel being queried.
* @buf: Where to store the attribute value. Assumed to hold
* at least PAGE_SIZE bytes and to be aligned at PAGE_SIZE.
*
* Returns the number of bytes written to buf, or an error code.
*/
ssize_t iio_read_channel_label(struct iio_channel *chan, char *buf);
#endif
@@ -0,0 +1,29 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __IIO_DAC_AD5421_H__
#define __IIO_DAC_AD5421_H__
/**
* enum ad5421_current_range - Current range the AD5421 is configured for.
* @AD5421_CURRENT_RANGE_4mA_20mA: 4 mA to 20 mA (RANGE1,0 pins = 00)
* @AD5421_CURRENT_RANGE_3mA8_21mA: 3.8 mA to 21 mA (RANGE1,0 pins = x1)
* @AD5421_CURRENT_RANGE_3mA2_24mA: 3.2 mA to 24 mA (RANGE1,0 pins = 10)
*/
enum ad5421_current_range {
AD5421_CURRENT_RANGE_4mA_20mA,
AD5421_CURRENT_RANGE_3mA8_21mA,
AD5421_CURRENT_RANGE_3mA2_24mA,
};
/**
* struct ad5421_platform_data - AD5421 DAC driver platform data
* @external_vref: whether an external reference voltage is used or not
* @current_range: Current range the AD5421 is configured for
*/
struct ad5421_platform_data {
bool external_vref;
enum ad5421_current_range current_range;
};
#endif
@@ -0,0 +1,15 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* AD5504 SPI DAC driver
*
* Copyright 2011 Analog Devices Inc.
*/
#ifndef SPI_AD5504_H_
#define SPI_AD5504_H_
struct ad5504_platform_data {
u16 vref_mv;
};
#endif /* SPI_AD5504_H_ */
@@ -0,0 +1,24 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* AD5791 SPI DAC driver
*
* Copyright 2011 Analog Devices Inc.
*/
#ifndef SPI_AD5791_H_
#define SPI_AD5791_H_
/**
* struct ad5791_platform_data - platform specific information
* @vref_pos_mv: Vdd Positive Analog Supply Volatge (mV)
* @vref_neg_mv: Vdd Negative Analog Supply Volatge (mV)
* @use_rbuf_gain2: ext. amplifier connected in gain of two configuration
*/
struct ad5791_platform_data {
u16 vref_pos_mv;
u16 vref_neg_mv;
bool use_rbuf_gain2;
};
#endif /* SPI_AD5791_H_ */
@@ -0,0 +1,14 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* MAX517 DAC driver
*
* Copyright 2011 Roland Stigge <stigge@antcom.de>
*/
#ifndef IIO_DAC_MAX517_H_
#define IIO_DAC_MAX517_H_
struct max517_platform_data {
u16 vref_mv[8];
};
#endif /* IIO_DAC_MAX517_H_ */
@@ -0,0 +1,25 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* MCP4725 DAC driver
*
* Copyright (C) 2012 Peter Meerwald <pmeerw@pmeerw.net>
*/
#ifndef IIO_DAC_MCP4725_H_
#define IIO_DAC_MCP4725_H_
/**
* struct mcp4725_platform_data - MCP4725/6 DAC specific data.
* @use_vref: Whether an external reference voltage on Vref pin should be used.
* Additional vref-supply must be specified when used.
* @vref_buffered: Controls buffering of the external reference voltage.
*
* Vref related settings are available only on MCP4756. See
* Documentation/devicetree/bindings/iio/dac/microchip,mcp4725.yaml for more information.
*/
struct mcp4725_platform_data {
bool use_vref;
bool vref_buffered;
};
#endif /* IIO_DAC_MCP4725_H_ */
@@ -0,0 +1,44 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Industrial I/O in kernel access map interface.
*
* Copyright (c) 2011 Jonathan Cameron
*/
#ifndef _IIO_INKERN_H_
#define _IIO_INKERN_H_
struct device;
struct iio_dev;
struct iio_map;
/**
* iio_map_array_register() - tell the core about inkernel consumers
* @indio_dev: provider device
* @map: array of mappings specifying association of channel with client
*/
int iio_map_array_register(struct iio_dev *indio_dev,
const struct iio_map *map);
/**
* iio_map_array_unregister() - tell the core to remove consumer mappings for
* the given provider device
* @indio_dev: provider device
*/
int iio_map_array_unregister(struct iio_dev *indio_dev);
/**
* devm_iio_map_array_register - device-managed version of iio_map_array_register
* @dev: Device object to which to bind the unwinding of this registration
* @indio_dev: Pointer to the iio_dev structure
* @maps: Pointer to an IIO map object which is to be registered to this IIO device
*
* This function will call iio_map_array_register() to register an IIO map object
* and will also hook a callback to the iio_map_array_unregister() function to
* handle de-registration of the IIO map object when the device's refcount goes to
* zero.
*/
int devm_iio_map_array_register(struct device *dev, struct iio_dev *indio_dev,
const struct iio_map *maps);
#endif
@@ -0,0 +1,73 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* The industrial I/O - event passing to userspace
*
* Copyright (c) 2008-2011 Jonathan Cameron
*/
#ifndef _IIO_EVENTS_H_
#define _IIO_EVENTS_H_
#include <linux/iio/types.h>
#include <uapi/linux/iio/events.h>
/**
* _IIO_EVENT_CODE() - create event identifier
* @chan_type: Type of the channel. Should be one of enum iio_chan_type.
* @diff: Whether the event is for an differential channel or not.
* @modifier: Modifier for the channel. Should be one of enum iio_modifier.
* @direction: Direction of the event. One of enum iio_event_direction.
* @type: Type of the event. Should be one of enum iio_event_type.
* @chan: Channel number for non-differential channels.
* @chan1: First channel number for differential channels.
* @chan2: Second channel number for differential channels.
*
* Drivers should use the specialized macros below instead of using this one
* directly.
*/
#define _IIO_EVENT_CODE(chan_type, diff, modifier, direction, \
type, chan, chan1, chan2) \
(((u64)type << 56) | ((u64)diff << 55) | \
((u64)direction << 48) | ((u64)modifier << 40) | \
((u64)chan_type << 32) | (((u16)chan2) << 16) | ((u16)chan1) | \
((u16)chan))
/**
* IIO_MOD_EVENT_CODE() - create event identifier for modified (non
* differential) channels
* @chan_type: Type of the channel. Should be one of enum iio_chan_type.
* @number: Channel number.
* @modifier: Modifier for the channel. Should be one of enum iio_modifier.
* @type: Type of the event. Should be one of enum iio_event_type.
* @direction: Direction of the event. One of enum iio_event_direction.
*/
#define IIO_MOD_EVENT_CODE(chan_type, number, modifier, \
type, direction) \
_IIO_EVENT_CODE(chan_type, 0, modifier, direction, type, number, 0, 0)
/**
* IIO_UNMOD_EVENT_CODE() - create event identifier for unmodified (non
* differential) channels
* @chan_type: Type of the channel. Should be one of enum iio_chan_type.
* @number: Channel number.
* @type: Type of the event. Should be one of enum iio_event_type.
* @direction: Direction of the event. One of enum iio_event_direction.
*/
#define IIO_UNMOD_EVENT_CODE(chan_type, number, type, direction) \
_IIO_EVENT_CODE(chan_type, 0, 0, direction, type, number, 0, 0)
/**
* IIO_DIFF_EVENT_CODE() - create event identifier for differential channels
* @chan_type: Type of the channel. Should be one of enum iio_chan_type.
* @chan1: First channel number for differential channels.
* @chan2: Second channel number for differential channels.
* @type: Type of the event. Should be one of enum iio_event_type.
* @direction: Direction of the event. One of enum iio_event_direction.
*/
#define IIO_DIFF_EVENT_CODE(chan_type, chan1, chan2, type, direction) \
_IIO_EVENT_CODE(chan_type, 1, 0, direction, type, 0, chan1, chan2)
#endif
@@ -0,0 +1,194 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* AD9523 SPI Low Jitter Clock Generator
*
* Copyright 2012 Analog Devices Inc.
*/
#ifndef IIO_FREQUENCY_AD9523_H_
#define IIO_FREQUENCY_AD9523_H_
enum outp_drv_mode {
TRISTATE,
LVPECL_8mA,
LVDS_4mA,
LVDS_7mA,
HSTL0_16mA,
HSTL1_8mA,
CMOS_CONF1,
CMOS_CONF2,
CMOS_CONF3,
CMOS_CONF4,
CMOS_CONF5,
CMOS_CONF6,
CMOS_CONF7,
CMOS_CONF8,
CMOS_CONF9
};
enum ref_sel_mode {
NONEREVERTIVE_STAY_ON_REFB,
REVERT_TO_REFA,
SELECT_REFA,
SELECT_REFB,
EXT_REF_SEL
};
/**
* struct ad9523_channel_spec - Output channel configuration
*
* @channel_num: Output channel number.
* @divider_output_invert_en: Invert the polarity of the output clock.
* @sync_ignore_en: Ignore chip-level SYNC signal.
* @low_power_mode_en: Reduce power used in the differential output modes.
* @use_alt_clock_src: Channel divider uses alternative clk source.
* @output_dis: Disables, powers down the entire channel.
* @driver_mode: Output driver mode (logic level family).
* @divider_phase: Divider initial phase after a SYNC. Range 0..63
* LSB = 1/2 of a period of the divider input clock.
* @channel_divider: 10-bit channel divider.
* @extended_name: Optional descriptive channel name.
*/
struct ad9523_channel_spec {
unsigned channel_num;
bool divider_output_invert_en;
bool sync_ignore_en;
bool low_power_mode_en;
/* CH0..CH3 VCXO, CH4..CH9 VCO2 */
bool use_alt_clock_src;
bool output_dis;
enum outp_drv_mode driver_mode;
unsigned char divider_phase;
unsigned short channel_divider;
char extended_name[16];
};
enum pll1_rzero_resistor {
RZERO_883_OHM,
RZERO_677_OHM,
RZERO_341_OHM,
RZERO_135_OHM,
RZERO_10_OHM,
RZERO_USE_EXT_RES = 8,
};
enum rpole2_resistor {
RPOLE2_900_OHM,
RPOLE2_450_OHM,
RPOLE2_300_OHM,
RPOLE2_225_OHM,
};
enum rzero_resistor {
RZERO_3250_OHM,
RZERO_2750_OHM,
RZERO_2250_OHM,
RZERO_2100_OHM,
RZERO_3000_OHM,
RZERO_2500_OHM,
RZERO_2000_OHM,
RZERO_1850_OHM,
};
enum cpole1_capacitor {
CPOLE1_0_PF,
CPOLE1_8_PF,
CPOLE1_16_PF,
CPOLE1_24_PF,
_CPOLE1_24_PF, /* place holder */
CPOLE1_32_PF,
CPOLE1_40_PF,
CPOLE1_48_PF,
};
/**
* struct ad9523_platform_data - platform specific information
*
* @vcxo_freq: External VCXO frequency in Hz
* @refa_diff_rcv_en: REFA differential/single-ended input selection.
* @refb_diff_rcv_en: REFB differential/single-ended input selection.
* @zd_in_diff_en: Zero Delay differential/single-ended input selection.
* @osc_in_diff_en: OSC differential/ single-ended input selection.
* @refa_cmos_neg_inp_en: REFA single-ended neg./pos. input enable.
* @refb_cmos_neg_inp_en: REFB single-ended neg./pos. input enable.
* @zd_in_cmos_neg_inp_en: Zero Delay single-ended neg./pos. input enable.
* @osc_in_cmos_neg_inp_en: OSC single-ended neg./pos. input enable.
* @refa_r_div: PLL1 10-bit REFA R divider.
* @refb_r_div: PLL1 10-bit REFB R divider.
* @pll1_feedback_div: PLL1 10-bit Feedback N divider.
* @pll1_charge_pump_current_nA: Magnitude of PLL1 charge pump current (nA).
* @zero_delay_mode_internal_en: Internal, external Zero Delay mode selection.
* @osc_in_feedback_en: PLL1 feedback path, local feedback from
* the OSC_IN receiver or zero delay mode
* @pll1_loop_filter_rzero: PLL1 Loop Filter Zero Resistor selection.
* @ref_mode: Reference selection mode.
* @pll2_charge_pump_current_nA: Magnitude of PLL2 charge pump current (nA).
* @pll2_ndiv_a_cnt: PLL2 Feedback N-divider, A Counter, range 0..4.
* @pll2_ndiv_b_cnt: PLL2 Feedback N-divider, B Counter, range 0..63.
* @pll2_freq_doubler_en: PLL2 frequency doubler enable.
* @pll2_r2_div: PLL2 R2 divider, range 0..31.
* @pll2_vco_div_m1: VCO1 divider, range 3..5.
* @pll2_vco_div_m2: VCO2 divider, range 3..5.
* @rpole2: PLL2 loop filter Rpole resistor value.
* @rzero: PLL2 loop filter Rzero resistor value.
* @cpole1: PLL2 loop filter Cpole capacitor value.
* @rzero_bypass_en: PLL2 loop filter Rzero bypass enable.
* @num_channels: Array size of struct ad9523_channel_spec.
* @channels: Pointer to channel array.
* @name: Optional alternative iio device name.
*/
struct ad9523_platform_data {
unsigned long vcxo_freq;
/* Differential/ Single-Ended Input Configuration */
bool refa_diff_rcv_en;
bool refb_diff_rcv_en;
bool zd_in_diff_en;
bool osc_in_diff_en;
/*
* Valid if differential input disabled
* if false defaults to pos input
*/
bool refa_cmos_neg_inp_en;
bool refb_cmos_neg_inp_en;
bool zd_in_cmos_neg_inp_en;
bool osc_in_cmos_neg_inp_en;
/* PLL1 Setting */
unsigned short refa_r_div;
unsigned short refb_r_div;
unsigned short pll1_feedback_div;
unsigned short pll1_charge_pump_current_nA;
bool zero_delay_mode_internal_en;
bool osc_in_feedback_en;
enum pll1_rzero_resistor pll1_loop_filter_rzero;
/* Reference */
enum ref_sel_mode ref_mode;
/* PLL2 Setting */
unsigned int pll2_charge_pump_current_nA;
unsigned char pll2_ndiv_a_cnt;
unsigned char pll2_ndiv_b_cnt;
bool pll2_freq_doubler_en;
unsigned char pll2_r2_div;
unsigned char pll2_vco_div_m1; /* 3..5 */
unsigned char pll2_vco_div_m2; /* 3..5 */
/* Loop Filter PLL2 */
enum rpole2_resistor rpole2;
enum rzero_resistor rzero;
enum cpole1_capacitor cpole1;
bool rzero_bypass_en;
/* Output Channel Configuration */
int num_channels;
struct ad9523_channel_spec *channels;
char name[SPI_NAME_SIZE];
};
#endif /* IIO_FREQUENCY_AD9523_H_ */
@@ -0,0 +1,123 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* ADF4350/ADF4351 SPI PLL driver
*
* Copyright 2012-2013 Analog Devices Inc.
*/
#ifndef IIO_PLL_ADF4350_H_
#define IIO_PLL_ADF4350_H_
/* Registers */
#define ADF4350_REG0 0
#define ADF4350_REG1 1
#define ADF4350_REG2 2
#define ADF4350_REG3 3
#define ADF4350_REG4 4
#define ADF4350_REG5 5
/* REG0 Bit Definitions */
#define ADF4350_REG0_FRACT(x) (((x) & 0xFFF) << 3)
#define ADF4350_REG0_INT(x) (((x) & 0xFFFF) << 15)
/* REG1 Bit Definitions */
#define ADF4350_REG1_MOD(x) (((x) & 0xFFF) << 3)
#define ADF4350_REG1_PHASE(x) (((x) & 0xFFF) << 15)
#define ADF4350_REG1_PRESCALER (1 << 27)
/* REG2 Bit Definitions */
#define ADF4350_REG2_COUNTER_RESET_EN (1 << 3)
#define ADF4350_REG2_CP_THREESTATE_EN (1 << 4)
#define ADF4350_REG2_POWER_DOWN_EN (1 << 5)
#define ADF4350_REG2_PD_POLARITY_POS (1 << 6)
#define ADF4350_REG2_LDP_6ns (1 << 7)
#define ADF4350_REG2_LDP_10ns (0 << 7)
#define ADF4350_REG2_LDF_FRACT_N (0 << 8)
#define ADF4350_REG2_LDF_INT_N (1 << 8)
#define ADF4350_REG2_CHARGE_PUMP_CURR_uA(x) (((((x)-312) / 312) & 0xF) << 9)
#define ADF4350_REG2_DOUBLE_BUFF_EN (1 << 13)
#define ADF4350_REG2_10BIT_R_CNT(x) ((x) << 14)
#define ADF4350_REG2_RDIV2_EN (1 << 24)
#define ADF4350_REG2_RMULT2_EN (1 << 25)
#define ADF4350_REG2_MUXOUT(x) ((x) << 26)
#define ADF4350_REG2_NOISE_MODE(x) (((unsigned)(x)) << 29)
#define ADF4350_MUXOUT_THREESTATE 0
#define ADF4350_MUXOUT_DVDD 1
#define ADF4350_MUXOUT_GND 2
#define ADF4350_MUXOUT_R_DIV_OUT 3
#define ADF4350_MUXOUT_N_DIV_OUT 4
#define ADF4350_MUXOUT_ANALOG_LOCK_DETECT 5
#define ADF4350_MUXOUT_DIGITAL_LOCK_DETECT 6
/* REG3 Bit Definitions */
#define ADF4350_REG3_12BIT_CLKDIV(x) ((x) << 3)
#define ADF4350_REG3_12BIT_CLKDIV_MODE(x) ((x) << 15)
#define ADF4350_REG3_12BIT_CSR_EN (1 << 18)
#define ADF4351_REG3_CHARGE_CANCELLATION_EN (1 << 21)
#define ADF4351_REG3_ANTI_BACKLASH_3ns_EN (1 << 22)
#define ADF4351_REG3_BAND_SEL_CLOCK_MODE_HIGH (1 << 23)
/* REG4 Bit Definitions */
#define ADF4350_REG4_OUTPUT_PWR(x) ((x) << 3)
#define ADF4350_REG4_RF_OUT_EN (1 << 5)
#define ADF4350_REG4_AUX_OUTPUT_PWR(x) ((x) << 6)
#define ADF4350_REG4_AUX_OUTPUT_EN (1 << 8)
#define ADF4350_REG4_AUX_OUTPUT_FUND (1 << 9)
#define ADF4350_REG4_AUX_OUTPUT_DIV (0 << 9)
#define ADF4350_REG4_MUTE_TILL_LOCK_EN (1 << 10)
#define ADF4350_REG4_VCO_PWRDOWN_EN (1 << 11)
#define ADF4350_REG4_8BIT_BAND_SEL_CLKDIV(x) ((x) << 12)
#define ADF4350_REG4_RF_DIV_SEL(x) ((x) << 20)
#define ADF4350_REG4_FEEDBACK_DIVIDED (0 << 23)
#define ADF4350_REG4_FEEDBACK_FUND (1 << 23)
/* REG5 Bit Definitions */
#define ADF4350_REG5_LD_PIN_MODE_LOW (0 << 22)
#define ADF4350_REG5_LD_PIN_MODE_DIGITAL (1 << 22)
#define ADF4350_REG5_LD_PIN_MODE_HIGH (3 << 22)
/* Specifications */
#define ADF4350_MAX_OUT_FREQ 4400000000ULL /* Hz */
#define ADF4350_MIN_OUT_FREQ 137500000 /* Hz */
#define ADF4351_MIN_OUT_FREQ 34375000 /* Hz */
#define ADF4350_MIN_VCO_FREQ 2200000000ULL /* Hz */
#define ADF4350_MAX_FREQ_45_PRESC 3000000000ULL /* Hz */
#define ADF4350_MAX_FREQ_PFD 32000000 /* Hz */
#define ADF4350_MAX_BANDSEL_CLK 125000 /* Hz */
#define ADF4350_MAX_FREQ_REFIN 250000000 /* Hz */
#define ADF4350_MAX_MODULUS 4095
#define ADF4350_MAX_R_CNT 1023
/**
* struct adf4350_platform_data - platform specific information
* @name: Optional device name.
* @clkin: REFin frequency in Hz.
* @channel_spacing: Channel spacing in Hz (influences MODULUS).
* @power_up_frequency: Optional, If set in Hz the PLL tunes to the desired
* frequency on probe.
* @ref_div_factor: Optional, if set the driver skips dynamic calculation
* and uses this default value instead.
* @ref_doubler_en: Enables reference doubler.
* @ref_div2_en: Enables reference divider.
* @r2_user_settings: User defined settings for ADF4350/1 REGISTER_2.
* @r3_user_settings: User defined settings for ADF4350/1 REGISTER_3.
* @r4_user_settings: User defined settings for ADF4350/1 REGISTER_4.
*/
struct adf4350_platform_data {
char name[32];
unsigned long clkin;
unsigned long channel_spacing;
unsigned long long power_up_frequency;
unsigned short ref_div_factor; /* 10-bit R counter */
bool ref_doubler_en;
bool ref_div2_en;
unsigned r2_user_settings;
unsigned r3_user_settings;
unsigned r4_user_settings;
};
#endif /* IIO_PLL_ADF4350_H_ */
@@ -0,0 +1,154 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* itg3200.h -- support InvenSense ITG3200
* Digital 3-Axis Gyroscope driver
*
* Copyright (c) 2011 Christian Strobel <christian.strobel@iis.fraunhofer.de>
* Copyright (c) 2011 Manuel Stahl <manuel.stahl@iis.fraunhofer.de>
* Copyright (c) 2012 Thorsten Nowak <thorsten.nowak@iis.fraunhofer.de>
*/
#ifndef I2C_ITG3200_H_
#define I2C_ITG3200_H_
#include <linux/iio/iio.h>
/* Register with I2C address (34h) */
#define ITG3200_REG_ADDRESS 0x00
/* Sample rate divider
* Range: 0 to 255
* Default value: 0x00 */
#define ITG3200_REG_SAMPLE_RATE_DIV 0x15
/* Digital low pass filter settings */
#define ITG3200_REG_DLPF 0x16
/* DLPF full scale range */
#define ITG3200_DLPF_FS_SEL_2000 0x18
/* Bandwidth (Hz) and internal sample rate
* (kHz) of DLPF */
#define ITG3200_DLPF_256_8 0x00
#define ITG3200_DLPF_188_1 0x01
#define ITG3200_DLPF_98_1 0x02
#define ITG3200_DLPF_42_1 0x03
#define ITG3200_DLPF_20_1 0x04
#define ITG3200_DLPF_10_1 0x05
#define ITG3200_DLPF_5_1 0x06
#define ITG3200_DLPF_CFG_MASK 0x07
/* Configuration for interrupt operations */
#define ITG3200_REG_IRQ_CONFIG 0x17
/* Logic level */
#define ITG3200_IRQ_ACTIVE_LOW 0x80
#define ITG3200_IRQ_ACTIVE_HIGH 0x00
/* Drive type */
#define ITG3200_IRQ_OPEN_DRAIN 0x40
#define ITG3200_IRQ_PUSH_PULL 0x00
/* Latch mode */
#define ITG3200_IRQ_LATCH_UNTIL_CLEARED 0x20
#define ITG3200_IRQ_LATCH_50US_PULSE 0x00
/* Latch clear method */
#define ITG3200_IRQ_LATCH_CLEAR_ANY 0x10
#define ITG3200_IRQ_LATCH_CLEAR_STATUS 0x00
/* Enable interrupt when device is ready */
#define ITG3200_IRQ_DEVICE_RDY_ENABLE 0x04
/* Enable interrupt when data is available */
#define ITG3200_IRQ_DATA_RDY_ENABLE 0x01
/* Determine the status of ITG-3200 interrupts */
#define ITG3200_REG_IRQ_STATUS 0x1A
/* Status of 'device is ready'-interrupt */
#define ITG3200_IRQ_DEVICE_RDY_STATUS 0x04
/* Status of 'data is available'-interrupt */
#define ITG3200_IRQ_DATA_RDY_STATUS 0x01
/* Sensor registers */
#define ITG3200_REG_TEMP_OUT_H 0x1B
#define ITG3200_REG_TEMP_OUT_L 0x1C
#define ITG3200_REG_GYRO_XOUT_H 0x1D
#define ITG3200_REG_GYRO_XOUT_L 0x1E
#define ITG3200_REG_GYRO_YOUT_H 0x1F
#define ITG3200_REG_GYRO_YOUT_L 0x20
#define ITG3200_REG_GYRO_ZOUT_H 0x21
#define ITG3200_REG_GYRO_ZOUT_L 0x22
/* Power management */
#define ITG3200_REG_POWER_MANAGEMENT 0x3E
/* Reset device and internal registers to the
* power-up-default settings */
#define ITG3200_RESET 0x80
/* Enable low power sleep mode */
#define ITG3200_SLEEP 0x40
/* Put according gyroscope in standby mode */
#define ITG3200_STANDBY_GYRO_X 0x20
#define ITG3200_STANDBY_GYRO_Y 0x10
#define ITG3200_STANDBY_GYRO_Z 0x08
/* Determine the device clock source */
#define ITG3200_CLK_INTERNAL 0x00
#define ITG3200_CLK_GYRO_X 0x01
#define ITG3200_CLK_GYRO_Y 0x02
#define ITG3200_CLK_GYRO_Z 0x03
#define ITG3200_CLK_EXT_32K 0x04
#define ITG3200_CLK_EXT_19M 0x05
/**
* struct itg3200 - device instance specific data
* @i2c: actual i2c_client
* @trig: data ready trigger from itg3200 pin
**/
struct itg3200 {
struct i2c_client *i2c;
struct iio_trigger *trig;
struct iio_mount_matrix orientation;
/* lock to protect against multiple access to the device */
struct mutex lock;
};
enum ITG3200_SCAN_INDEX {
ITG3200_SCAN_TEMP,
ITG3200_SCAN_GYRO_X,
ITG3200_SCAN_GYRO_Y,
ITG3200_SCAN_GYRO_Z,
ITG3200_SCAN_ELEMENTS,
};
int itg3200_write_reg_8(struct iio_dev *indio_dev,
u8 reg_address, u8 val);
int itg3200_read_reg_8(struct iio_dev *indio_dev,
u8 reg_address, u8 *val);
#ifdef CONFIG_IIO_BUFFER
void itg3200_remove_trigger(struct iio_dev *indio_dev);
int itg3200_probe_trigger(struct iio_dev *indio_dev);
int itg3200_buffer_configure(struct iio_dev *indio_dev);
void itg3200_buffer_unconfigure(struct iio_dev *indio_dev);
#else /* CONFIG_IIO_BUFFER */
static inline void itg3200_remove_trigger(struct iio_dev *indio_dev)
{
}
static inline int itg3200_probe_trigger(struct iio_dev *indio_dev)
{
return 0;
}
static inline int itg3200_buffer_configure(struct iio_dev *indio_dev)
{
return 0;
}
static inline void itg3200_buffer_unconfigure(struct iio_dev *indio_dev)
{
}
#endif /* CONFIG_IIO_BUFFER */
#endif /* ITG3200_H_ */
@@ -0,0 +1,20 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Industrial I/O in kernel hardware consumer interface
*
* Copyright 2017 Analog Devices Inc.
* Author: Lars-Peter Clausen <lars@metafoo.de>
*/
#ifndef LINUX_IIO_HW_CONSUMER_H
#define LINUX_IIO_HW_CONSUMER_H
struct iio_hw_consumer;
struct iio_hw_consumer *iio_hw_consumer_alloc(struct device *dev);
void iio_hw_consumer_free(struct iio_hw_consumer *hwc);
struct iio_hw_consumer *devm_iio_hw_consumer_alloc(struct device *dev);
int iio_hw_consumer_enable(struct iio_hw_consumer *hwc);
void iio_hw_consumer_disable(struct iio_hw_consumer *hwc);
#endif
@@ -0,0 +1,213 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* gain-time-scale conversion helpers for IIO light sensors
*
* Copyright (c) 2023 Matti Vaittinen <mazziesaccount@gmail.com>
*/
#ifndef __IIO_GTS_HELPER__
#define __IIO_GTS_HELPER__
#include <linux/types.h>
struct device;
/**
* struct iio_gain_sel_pair - gain - selector values
*
* In many cases devices like light sensors allow setting signal amplification
* (gain) using a register interface. This structure describes amplification
* and corresponding selector (register value)
*
* @gain: Gain (multiplication) value. Gain must be positive, negative
* values are reserved for error handling.
* @sel: Selector (usually register value) used to indicate this gain.
* NOTE: Only selectors >= 0 supported.
*/
struct iio_gain_sel_pair {
int gain;
int sel;
};
/**
* struct iio_itime_sel_mul - integration time description
*
* In many cases devices like light sensors allow setting the duration of
* collecting data. Typically this duration has also an impact to the magnitude
* of measured values (gain). This structure describes the relation of
* integration time and amplification as well as corresponding selector
* (register value).
*
* An example could be a sensor allowing 50, 100, 200 and 400 mS times. The
* respective multiplication values could be 50 mS => 1, 100 mS => 2,
* 200 mS => 4 and 400 mS => 8 assuming the impact of integration time would be
* linear in a way that when collecting data for 50 mS caused value X, doubling
* the data collection time caused value 2X etc.
*
* @time_us: Integration time in microseconds. Time values must be positive,
* negative values are reserved for error handling.
* @sel: Selector (usually register value) used to indicate this time
* NOTE: Only selectors >= 0 supported.
* @mul: Multiplication to the values caused by this time.
* NOTE: Only multipliers > 0 supported.
*/
struct iio_itime_sel_mul {
int time_us;
int sel;
int mul;
};
struct iio_gts {
u64 max_scale;
const struct iio_gain_sel_pair *hwgain_table;
int num_hwgain;
const struct iio_itime_sel_mul *itime_table;
int num_itime;
int **per_time_avail_scale_tables;
int *avail_all_scales_table;
int num_avail_all_scales;
int *avail_time_tables;
int num_avail_time_tables;
};
#define GAIN_SCALE_GAIN(_gain, _sel) \
{ \
.gain = (_gain), \
.sel = (_sel), \
}
#define GAIN_SCALE_ITIME_US(_itime, _sel, _mul) \
{ \
.time_us = (_itime), \
.sel = (_sel), \
.mul = (_mul), \
}
static inline const struct iio_itime_sel_mul *
iio_gts_find_itime_by_time(struct iio_gts *gts, int time)
{
int i;
if (!gts->num_itime)
return NULL;
for (i = 0; i < gts->num_itime; i++)
if (gts->itime_table[i].time_us == time)
return &gts->itime_table[i];
return NULL;
}
static inline const struct iio_itime_sel_mul *
iio_gts_find_itime_by_sel(struct iio_gts *gts, int sel)
{
int i;
for (i = 0; i < gts->num_itime; i++)
if (gts->itime_table[i].sel == sel)
return &gts->itime_table[i];
return NULL;
}
int devm_iio_init_iio_gts(struct device *dev, int max_scale_int, int max_scale_nano,
const struct iio_gain_sel_pair *gain_tbl, int num_gain,
const struct iio_itime_sel_mul *tim_tbl, int num_times,
struct iio_gts *gts);
/**
* iio_gts_find_int_time_by_sel - find integration time matching a selector
* @gts: Gain time scale descriptor
* @sel: selector for which matching integration time is searched for
*
* Return: integration time matching given selector or -EINVAL if
* integration time was not found.
*/
static inline int iio_gts_find_int_time_by_sel(struct iio_gts *gts, int sel)
{
const struct iio_itime_sel_mul *itime;
itime = iio_gts_find_itime_by_sel(gts, sel);
if (!itime)
return -EINVAL;
return itime->time_us;
}
/**
* iio_gts_find_sel_by_int_time - find selector matching integration time
* @gts: Gain time scale descriptor
* @time: Integration time for which matching selector is searched for
*
* Return: a selector matching given integration time or -EINVAL if
* selector was not found.
*/
static inline int iio_gts_find_sel_by_int_time(struct iio_gts *gts, int time)
{
const struct iio_itime_sel_mul *itime;
itime = iio_gts_find_itime_by_time(gts, time);
if (!itime)
return -EINVAL;
return itime->sel;
}
/**
* iio_gts_valid_time - check if given integration time is valid
* @gts: Gain time scale descriptor
* @time_us: Integration time to check
*
* Return: True if given time is supported by device. False if not.
*/
static inline bool iio_gts_valid_time(struct iio_gts *gts, int time_us)
{
return iio_gts_find_itime_by_time(gts, time_us) != NULL;
}
int iio_gts_find_sel_by_gain(struct iio_gts *gts, int gain);
/**
* iio_gts_valid_gain - check if given HW-gain is valid
* @gts: Gain time scale descriptor
* @gain: HW-gain to check
*
* Return: True if given time is supported by device. False if not.
*/
static inline bool iio_gts_valid_gain(struct iio_gts *gts, int gain)
{
return iio_gts_find_sel_by_gain(gts, gain) >= 0;
}
int iio_find_closest_gain_low(struct iio_gts *gts, int gain, bool *in_range);
int iio_gts_find_gain_by_sel(struct iio_gts *gts, int sel);
int iio_gts_get_min_gain(struct iio_gts *gts);
int iio_gts_find_int_time_by_sel(struct iio_gts *gts, int sel);
int iio_gts_find_sel_by_int_time(struct iio_gts *gts, int time);
int iio_gts_total_gain_to_scale(struct iio_gts *gts, int total_gain,
int *scale_int, int *scale_nano);
int iio_gts_find_gain_sel_for_scale_using_time(struct iio_gts *gts, int time_sel,
int scale_int, int scale_nano,
int *gain_sel);
int iio_gts_find_gain_time_sel_for_scale(struct iio_gts *gts, int scale_int,
int scale_nano, int *gain_sel,
int *time_sel);
int iio_gts_get_scale(struct iio_gts *gts, int gain, int time, int *scale_int,
int *scale_nano);
int iio_gts_find_new_gain_sel_by_old_gain_time(struct iio_gts *gts,
int old_gain, int old_time_sel,
int new_time_sel, int *new_gain);
int iio_gts_find_new_gain_by_old_gain_time(struct iio_gts *gts, int old_gain,
int old_time, int new_time,
int *new_gain);
int iio_gts_find_new_gain_by_gain_time_min(struct iio_gts *gts, int old_gain,
int old_time, int new_time,
int *new_gain, bool *in_range);
int iio_gts_avail_times(struct iio_gts *gts, const int **vals, int *type,
int *length);
int iio_gts_all_avail_scales(struct iio_gts *gts, const int **vals, int *type,
int *length);
int iio_gts_avail_scales_for_time(struct iio_gts *gts, int time,
const int **vals, int *type, int *length);
int iio_gts_get_total_gain(struct iio_gts *gts, int gain, int time);
#endif
@@ -0,0 +1,84 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _INDUSTRIAL_IO_OPAQUE_H_
#define _INDUSTRIAL_IO_OPAQUE_H_
/**
* struct iio_dev_opaque - industrial I/O device opaque information
* @indio_dev: public industrial I/O device information
* @id: used to identify device internally
* @currentmode: operating mode currently in use, may be eventually
* checked by device drivers but should be considered
* read-only as this is a core internal bit
* @driver_module: used to make it harder to undercut users
* @mlock: lock used to prevent simultaneous device state changes
* @mlock_key: lockdep class for iio_dev lock
* @info_exist_lock: lock to prevent use during removal
* @info_exist_key: lockdep class for info_exist lock
* @trig_readonly: mark the current trigger immutable
* @event_interface: event chrdevs associated with interrupt lines
* @attached_buffers: array of buffers statically attached by the driver
* @attached_buffers_cnt: number of buffers in the array of statically attached buffers
* @buffer_ioctl_handler: ioctl() handler for this IIO device's buffer interface
* @buffer_list: list of all buffers currently attached
* @channel_attr_list: keep track of automatically created channel
* attributes
* @chan_attr_group: group for all attrs in base directory
* @ioctl_handlers: ioctl handlers registered with the core handler
* @groups: attribute groups
* @groupcounter: index of next attribute group
* @legacy_scan_el_group: attribute group for legacy scan elements attribute group
* @legacy_buffer_group: attribute group for legacy buffer attributes group
* @bounce_buffer: for devices that call iio_push_to_buffers_with_ts_unaligned()
* @bounce_buffer_size: size of currently allocate bounce buffer
* @scan_index_timestamp: cache of the index to the timestamp
* @clock_id: timestamping clock posix identifier
* @chrdev: associated character device
* @flags: file ops related flags including busy flag.
* @debugfs_dentry: device specific debugfs dentry
* @cached_reg_addr: cached register address for debugfs reads
* @read_buf: read buffer to be used for the initial reg read
* @read_buf_len: data length in @read_buf
*/
struct iio_dev_opaque {
struct iio_dev indio_dev;
int currentmode;
int id;
struct module *driver_module;
struct mutex mlock;
struct lock_class_key mlock_key;
struct mutex info_exist_lock;
struct lock_class_key info_exist_key;
bool trig_readonly;
struct iio_event_interface *event_interface;
struct iio_buffer **attached_buffers;
unsigned int attached_buffers_cnt;
struct iio_ioctl_handler *buffer_ioctl_handler;
struct list_head buffer_list;
struct list_head channel_attr_list;
struct attribute_group chan_attr_group;
struct list_head ioctl_handlers;
const struct attribute_group **groups;
int groupcounter;
struct attribute_group legacy_scan_el_group;
struct attribute_group legacy_buffer_group;
void *bounce_buffer;
size_t bounce_buffer_size;
unsigned int scan_index_timestamp;
clockid_t clock_id;
struct cdev chrdev;
unsigned long flags;
#if defined(CONFIG_DEBUG_FS)
struct dentry *debugfs_dentry;
unsigned int cached_reg_addr;
char read_buf[20];
unsigned int read_buf_len;
#endif
};
#define to_iio_dev_opaque(_indio_dev) \
container_of((_indio_dev), struct iio_dev_opaque, indio_dev)
#endif
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,585 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*
* Common library for ADIS16XXX devices
*
* Copyright 2012 Analog Devices Inc.
* Author: Lars-Peter Clausen <lars@metafoo.de>
*/
#ifndef __IIO_ADIS_H__
#define __IIO_ADIS_H__
#include <linux/cleanup.h>
#include <linux/spi/spi.h>
#include <linux/interrupt.h>
#include <linux/iio/iio.h>
#include <linux/iio/types.h>
#define ADIS_WRITE_REG(reg) ((0x80 | (reg)))
#define ADIS_READ_REG(reg) ((reg) & 0x7f)
#define ADIS_PAGE_SIZE 0x80
#define ADIS_REG_PAGE_ID 0x00
struct adis;
struct iio_dev_attr;
/**
* struct adis_timeouts - ADIS chip variant timeouts
* @reset_ms - Wait time after rst pin goes inactive
* @sw_reset_ms - Wait time after sw reset command
* @self_test_ms - Wait time after self test command
*/
struct adis_timeout {
u16 reset_ms;
u16 sw_reset_ms;
u16 self_test_ms;
};
/**
* struct adis_data - ADIS chip variant specific data
* @read_delay: SPI delay for read operations in us
* @write_delay: SPI delay for write operations in us
* @cs_change_delay: SPI delay between CS changes in us
* @glob_cmd_reg: Register address of the GLOB_CMD register
* @msc_ctrl_reg: Register address of the MSC_CTRL register
* @diag_stat_reg: Register address of the DIAG_STAT register
* @diag_stat_size: Length (in bytes) of the DIAG_STAT register. If 0 the
* default length is 2 bytes long.
* @prod_id_reg: Register address of the PROD_ID register
* @prod_id: Product ID code that should be expected when reading @prod_id_reg
* @self_test_mask: Bitmask of supported self-test operations
* @self_test_reg: Register address to request self test command
* @self_test_no_autoclear: True if device's self-test needs clear of ctrl reg
* @status_error_msgs: Array of error messages
* @status_error_mask: Bitmask of errors supported by the device
* @timeouts: Chip specific delays
* @enable_irq: Hook for ADIS devices that have a special IRQ enable/disable
* @unmasked_drdy: True for devices that cannot mask/unmask the data ready pin
* @has_paging: True if ADIS device has paged registers
* @has_fifo: True if ADIS device has a hardware FIFO
* @burst_reg_cmd: Register command that triggers burst
* @burst_len: Burst size in the SPI RX buffer. If @burst_max_len is defined,
* this should be the minimum size supported by the device.
* @burst_max_len: Holds the maximum burst size when the device supports
* more than one burst mode with different sizes
* @burst_max_speed_hz: Maximum spi speed that can be used in burst mode
*/
struct adis_data {
unsigned int read_delay;
unsigned int write_delay;
unsigned int cs_change_delay;
unsigned int glob_cmd_reg;
unsigned int msc_ctrl_reg;
unsigned int diag_stat_reg;
unsigned int diag_stat_size;
unsigned int prod_id_reg;
unsigned int prod_id;
unsigned int self_test_mask;
unsigned int self_test_reg;
bool self_test_no_autoclear;
const struct adis_timeout *timeouts;
const char * const *status_error_msgs;
unsigned int status_error_mask;
int (*enable_irq)(struct adis *adis, bool enable);
bool unmasked_drdy;
bool has_paging;
bool has_fifo;
unsigned int burst_reg_cmd;
unsigned int burst_len;
unsigned int burst_max_len;
unsigned int burst_max_speed_hz;
};
/**
* struct adis_ops: Custom ops for adis devices.
* @write: Custom spi write implementation.
* @read: Custom spi read implementation.
* @reset: Custom sw reset implementation. The custom implementation does not
* need to sleep after the reset. It's done by the library already.
*/
struct adis_ops {
int (*write)(struct adis *adis, unsigned int reg, unsigned int value,
unsigned int size);
int (*read)(struct adis *adis, unsigned int reg, unsigned int *value,
unsigned int size);
int (*reset)(struct adis *adis);
};
/**
* struct adis - ADIS device instance data
* @spi: Reference to SPI device which owns this ADIS IIO device
* @trig: IIO trigger object data
* @data: ADIS chip variant specific data
* @burst_extra_len: Burst extra length. Should only be used by devices that can
* dynamically change their burst mode length.
* @ops: ops struct for custom read and write functions
* @state_lock: Lock used by the device to protect state
* @msg: SPI message object
* @xfer: SPI transfer objects to be used for a @msg
* @current_page: Some ADIS devices have registers, this selects current page
* @irq_flag: IRQ handling flags as passed to request_irq()
* @buffer: Data buffer for information read from the device
* @tx: DMA safe TX buffer for SPI transfers
* @rx: DMA safe RX buffer for SPI transfers
*/
struct adis {
struct spi_device *spi;
struct iio_trigger *trig;
const struct adis_data *data;
unsigned int burst_extra_len;
const struct adis_ops *ops;
/*
* The state_lock is meant to be used during operations that require
* a sequence of SPI R/W in order to protect the SPI transfer
* information (fields 'xfer', 'msg' & 'current_page') between
* potential concurrent accesses.
* This lock is used by all "adis_{functions}" that have to read/write
* registers. These functions also have unlocked variants
* (see "__adis_{functions}"), which don't hold this lock.
* This allows users of the ADIS library to group SPI R/W into
* the drivers, but they also must manage this lock themselves.
*/
struct mutex state_lock;
struct spi_message msg;
struct spi_transfer *xfer;
unsigned int current_page;
unsigned long irq_flag;
void *buffer;
u8 tx[10] __aligned(IIO_DMA_MINALIGN);
u8 rx[4];
};
int adis_init(struct adis *adis, struct iio_dev *indio_dev,
struct spi_device *spi, const struct adis_data *data);
int __adis_reset(struct adis *adis);
/**
* adis_reset() - Reset the device
* @adis: The adis device
*
* Returns: %0 on success, a negative error code otherwise
*/
static inline int adis_reset(struct adis *adis)
{
guard(mutex)(&adis->state_lock);
return __adis_reset(adis);
}
int __adis_write_reg(struct adis *adis, unsigned int reg,
unsigned int val, unsigned int size);
int __adis_read_reg(struct adis *adis, unsigned int reg,
unsigned int *val, unsigned int size);
/**
* __adis_write_reg_8() - Write single byte to a register (unlocked)
* @adis: The adis device
* @reg: The address of the register to be written
* @val: The value to write
*
* Returns: %0 on success, a negative error code otherwise
*/
static inline int __adis_write_reg_8(struct adis *adis, unsigned int reg,
u8 val)
{
return adis->ops->write(adis, reg, val, 1);
}
/**
* __adis_write_reg_16() - Write 2 bytes to a pair of registers (unlocked)
* @adis: The adis device
* @reg: The address of the lower of the two registers
* @val: Value to be written
*
* Returns: %0 on success, a negative error code otherwise
*/
static inline int __adis_write_reg_16(struct adis *adis, unsigned int reg,
u16 val)
{
return adis->ops->write(adis, reg, val, 2);
}
/**
* __adis_write_reg_32() - write 4 bytes to four registers (unlocked)
* @adis: The adis device
* @reg: The address of the lower of the four register
* @val: Value to be written
*
* Returns: %0 on success, a negative error code otherwise
*/
static inline int __adis_write_reg_32(struct adis *adis, unsigned int reg,
u32 val)
{
return adis->ops->write(adis, reg, val, 4);
}
/**
* __adis_read_reg_16() - read 2 bytes from a 16-bit register (unlocked)
* @adis: The adis device
* @reg: The address of the lower of the two registers
* @val: The value read back from the device
*
* Returns: %0 on success, a negative error code otherwise
*/
static inline int __adis_read_reg_16(struct adis *adis, unsigned int reg,
u16 *val)
{
unsigned int tmp;
int ret;
ret = adis->ops->read(adis, reg, &tmp, 2);
if (ret == 0)
*val = tmp;
return ret;
}
/**
* __adis_read_reg_32() - read 4 bytes from a 32-bit register (unlocked)
* @adis: The adis device
* @reg: The address of the lower of the two registers
* @val: The value read back from the device
*
* Returns: %0 on success, a negative error code otherwise
*/
static inline int __adis_read_reg_32(struct adis *adis, unsigned int reg,
u32 *val)
{
unsigned int tmp;
int ret;
ret = adis->ops->read(adis, reg, &tmp, 4);
if (ret == 0)
*val = tmp;
return ret;
}
/**
* adis_write_reg() - write N bytes to register
* @adis: The adis device
* @reg: The address of the lower of the two registers
* @val: The value to write to device (up to 4 bytes)
* @size: The size of the @value (in bytes)
*
* Returns: %0 on success, a negative error code otherwise
*/
static inline int adis_write_reg(struct adis *adis, unsigned int reg,
unsigned int val, unsigned int size)
{
guard(mutex)(&adis->state_lock);
return adis->ops->write(adis, reg, val, size);
}
/**
* adis_read_reg() - read N bytes from register
* @adis: The adis device
* @reg: The address of the lower of the two registers
* @val: The value read back from the device
* @size: The size of the @val buffer
*
* Returns: %0 on success, a negative error code otherwise
*/
static int adis_read_reg(struct adis *adis, unsigned int reg,
unsigned int *val, unsigned int size)
{
guard(mutex)(&adis->state_lock);
return adis->ops->read(adis, reg, val, size);
}
/**
* adis_write_reg_8() - Write single byte to a register
* @adis: The adis device
* @reg: The address of the register to be written
* @val: The value to write
*
* Returns: %0 on success, a negative error code otherwise
*/
static inline int adis_write_reg_8(struct adis *adis, unsigned int reg,
u8 val)
{
return adis_write_reg(adis, reg, val, 1);
}
/**
* adis_write_reg_16() - Write 2 bytes to a pair of registers
* @adis: The adis device
* @reg: The address of the lower of the two registers
* @val: Value to be written
*
* Returns: %0 on success, a negative error code otherwise
*/
static inline int adis_write_reg_16(struct adis *adis, unsigned int reg,
u16 val)
{
return adis_write_reg(adis, reg, val, 2);
}
/**
* adis_write_reg_32() - write 4 bytes to four registers
* @adis: The adis device
* @reg: The address of the lower of the four register
* @val: Value to be written
*
* Returns: %0 on success, a negative error code otherwise
*/
static inline int adis_write_reg_32(struct adis *adis, unsigned int reg,
u32 val)
{
return adis_write_reg(adis, reg, val, 4);
}
/**
* adis_read_reg_16() - read 2 bytes from a 16-bit register
* @adis: The adis device
* @reg: The address of the lower of the two registers
* @val: The value read back from the device
*
* Returns: %0 on success, a negative error code otherwise
*/
static inline int adis_read_reg_16(struct adis *adis, unsigned int reg,
u16 *val)
{
unsigned int tmp;
int ret;
ret = adis_read_reg(adis, reg, &tmp, 2);
if (ret == 0)
*val = tmp;
return ret;
}
/**
* adis_read_reg_32() - read 4 bytes from a 32-bit register
* @adis: The adis device
* @reg: The address of the lower of the two registers
* @val: The value read back from the device
*
* Returns: %0 on success, a negative error code otherwise
*/
static inline int adis_read_reg_32(struct adis *adis, unsigned int reg,
u32 *val)
{
unsigned int tmp;
int ret;
ret = adis_read_reg(adis, reg, &tmp, 4);
if (ret == 0)
*val = tmp;
return ret;
}
int __adis_update_bits_base(struct adis *adis, unsigned int reg, const u32 mask,
const u32 val, u8 size);
/**
* adis_update_bits_base() - ADIS Update bits function - Locked version
* @adis: The adis device
* @reg: The address of the lower of the two registers
* @mask: Bitmask to change
* @val: Value to be written
* @size: Size of the register to update
*
* Updates the desired bits of @reg in accordance with @mask and @val.
*
* Returns: %0 on success, a negative error code otherwise
*/
static inline int adis_update_bits_base(struct adis *adis, unsigned int reg,
const u32 mask, const u32 val, u8 size)
{
guard(mutex)(&adis->state_lock);
return __adis_update_bits_base(adis, reg, mask, val, size);
}
/**
* adis_update_bits() - Wrapper macro for adis_update_bits_base - Locked version
* @adis: The adis device
* @reg: The address of the lower of the two registers
* @mask: Bitmask to change
* @val: Value to be written
*
* This macro evaluates the sizeof of @val at compile time and calls
* adis_update_bits_base() accordingly. Be aware that using MACROS/DEFINES for
* @val can lead to undesired behavior if the register to update is 16bit.
*/
#define adis_update_bits(adis, reg, mask, val) ({ \
BUILD_BUG_ON(sizeof(val) != 2 && sizeof(val) != 4); \
adis_update_bits_base(adis, reg, mask, val, sizeof(val)); \
})
/**
* adis_update_bits() - Wrapper macro for adis_update_bits_base
* @adis: The adis device
* @reg: The address of the lower of the two registers
* @mask: Bitmask to change
* @val: Value to be written
*
* This macro evaluates the sizeof of @val at compile time and calls
* adis_update_bits_base() accordingly. Be aware that using MACROS/DEFINES for
* @val can lead to undesired behavior if the register to update is 16bit.
*/
#define __adis_update_bits(adis, reg, mask, val) ({ \
BUILD_BUG_ON(sizeof(val) != 2 && sizeof(val) != 4); \
__adis_update_bits_base(adis, reg, mask, val, sizeof(val)); \
})
int __adis_check_status(struct adis *adis);
int __adis_initial_startup(struct adis *adis);
int __adis_enable_irq(struct adis *adis, bool enable);
static inline int adis_enable_irq(struct adis *adis, bool enable)
{
guard(mutex)(&adis->state_lock);
return __adis_enable_irq(adis, enable);
}
static inline int adis_check_status(struct adis *adis)
{
guard(mutex)(&adis->state_lock);
return __adis_check_status(adis);
}
#define adis_dev_auto_lock(adis) guard(mutex)(&(adis)->state_lock)
#define adis_dev_auto_scoped_lock(adis) \
scoped_guard(mutex, &(adis)->state_lock)
int adis_single_conversion(struct iio_dev *indio_dev,
const struct iio_chan_spec *chan,
unsigned int error_mask, int *val);
#define ADIS_VOLTAGE_CHAN(addr, si, chan, name, info_all, bits) { \
.type = IIO_VOLTAGE, \
.indexed = 1, \
.channel = (chan), \
.extend_name = name, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
BIT(IIO_CHAN_INFO_SCALE), \
.info_mask_shared_by_all = info_all, \
.address = (addr), \
.scan_index = (si), \
.scan_type = { \
.sign = 'u', \
.realbits = (bits), \
.storagebits = 16, \
.endianness = IIO_BE, \
}, \
}
#define ADIS_SUPPLY_CHAN(addr, si, info_all, bits) \
ADIS_VOLTAGE_CHAN(addr, si, 0, "supply", info_all, bits)
#define ADIS_AUX_ADC_CHAN(addr, si, info_all, bits) \
ADIS_VOLTAGE_CHAN(addr, si, 1, NULL, info_all, bits)
#define ADIS_TEMP_CHAN(addr, si, info_all, bits) { \
.type = IIO_TEMP, \
.indexed = 1, \
.channel = 0, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
BIT(IIO_CHAN_INFO_SCALE) | \
BIT(IIO_CHAN_INFO_OFFSET), \
.info_mask_shared_by_all = info_all, \
.address = (addr), \
.scan_index = (si), \
.scan_type = { \
.sign = 'u', \
.realbits = (bits), \
.storagebits = 16, \
.endianness = IIO_BE, \
}, \
}
#define ADIS_MOD_CHAN(_type, mod, addr, si, info_sep, info_all, bits) { \
.type = (_type), \
.modified = 1, \
.channel2 = IIO_MOD_ ## mod, \
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
(info_sep), \
.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
.info_mask_shared_by_all = info_all, \
.address = (addr), \
.scan_index = (si), \
.scan_type = { \
.sign = 's', \
.realbits = (bits), \
.storagebits = 16, \
.endianness = IIO_BE, \
}, \
}
#define ADIS_ACCEL_CHAN(mod, addr, si, info_sep, info_all, bits) \
ADIS_MOD_CHAN(IIO_ACCEL, mod, addr, si, info_sep, info_all, bits)
#define ADIS_GYRO_CHAN(mod, addr, si, info_sep, info_all, bits) \
ADIS_MOD_CHAN(IIO_ANGL_VEL, mod, addr, si, info_sep, info_all, bits)
#define ADIS_INCLI_CHAN(mod, addr, si, info_sep, info_all, bits) \
ADIS_MOD_CHAN(IIO_INCLI, mod, addr, si, info_sep, info_all, bits)
#define ADIS_ROT_CHAN(mod, addr, si, info_sep, info_all, bits) \
ADIS_MOD_CHAN(IIO_ROT, mod, addr, si, info_sep, info_all, bits)
#define devm_adis_setup_buffer_and_trigger(adis, indio_dev, trigger_handler) \
devm_adis_setup_buffer_and_trigger_with_attrs((adis), (indio_dev), \
(trigger_handler), NULL, \
NULL)
#ifdef CONFIG_IIO_ADIS_LIB_BUFFER
int
devm_adis_setup_buffer_and_trigger_with_attrs(struct adis *adis,
struct iio_dev *indio_dev,
irq_handler_t trigger_handler,
const struct iio_buffer_setup_ops *ops,
const struct iio_dev_attr **buffer_attrs);
int devm_adis_probe_trigger(struct adis *adis, struct iio_dev *indio_dev);
int adis_update_scan_mode(struct iio_dev *indio_dev,
const unsigned long *scan_mask);
#else /* CONFIG_IIO_BUFFER */
static inline int
devm_adis_setup_buffer_and_trigger_with_attrs(struct adis *adis,
struct iio_dev *indio_dev,
irq_handler_t trigger_handler,
const struct iio_buffer_setup_ops *ops,
const struct iio_dev_attr **buffer_attrs)
{
return 0;
}
static inline int devm_adis_probe_trigger(struct adis *adis,
struct iio_dev *indio_dev)
{
return 0;
}
#define adis_update_scan_mode NULL
#endif /* CONFIG_IIO_BUFFER */
#ifdef CONFIG_DEBUG_FS
int adis_debugfs_reg_access(struct iio_dev *indio_dev,
unsigned int reg, unsigned int writeval,
unsigned int *readval);
#else
#define adis_debugfs_reg_access NULL
#endif
#endif
@@ -0,0 +1,22 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __LINUX_IIO_KFIFO_BUF_H__
#define __LINUX_IIO_KFIFO_BUF_H__
struct iio_buffer;
struct iio_buffer_setup_ops;
struct iio_dev;
struct iio_dev_attr;
struct device;
struct iio_buffer *iio_kfifo_allocate(void);
void iio_kfifo_free(struct iio_buffer *r);
int devm_iio_kfifo_buffer_setup_ext(struct device *dev,
struct iio_dev *indio_dev,
const struct iio_buffer_setup_ops *setup_ops,
const struct iio_dev_attr **buffer_attrs);
#define devm_iio_kfifo_buffer_setup(dev, indio_dev, setup_ops) \
devm_iio_kfifo_buffer_setup_ext((dev), (indio_dev), (setup_ops), NULL)
#endif
@@ -0,0 +1,35 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Industrial I/O in kernel access map definitions for board files.
*
* Copyright (c) 2011 Jonathan Cameron
*/
#ifndef __LINUX_IIO_MACHINE_H__
#define __LINUX_IIO_MACHINE_H__
/**
* struct iio_map - description of link between consumer and device channels
* @adc_channel_label: Label used to identify the channel on the provider.
* This is matched against the datasheet_name element
* of struct iio_chan_spec.
* @consumer_dev_name: Name to uniquely identify the consumer device.
* @consumer_channel: Unique name used to identify the channel on the
* consumer side.
* @consumer_data: Data about the channel for use by the consumer driver.
*/
struct iio_map {
const char *adc_channel_label;
const char *consumer_dev_name;
const char *consumer_channel;
void *consumer_data;
};
#define IIO_MAP(_provider_channel, _consumer_dev_name, _consumer_channel) \
{ \
.adc_channel_label = _provider_channel, \
.consumer_dev_name = _consumer_dev_name, \
.consumer_channel = _consumer_channel, \
}
#endif
@@ -0,0 +1,64 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Industrial I/O software device interface
*
* Copyright (c) 2016 Intel Corporation
*/
#ifndef __IIO_SW_DEVICE
#define __IIO_SW_DEVICE
#include <linux/module.h>
#include <linux/device.h>
#include <linux/iio/iio.h>
#include <linux/configfs.h>
#define module_iio_sw_device_driver(__iio_sw_device_type) \
module_driver(__iio_sw_device_type, iio_register_sw_device_type, \
iio_unregister_sw_device_type)
struct iio_sw_device_ops;
struct iio_sw_device_type {
const char *name;
struct module *owner;
const struct iio_sw_device_ops *ops;
struct list_head list;
struct config_group *group;
};
struct iio_sw_device {
struct iio_dev *device;
struct iio_sw_device_type *device_type;
struct config_group group;
};
struct iio_sw_device_ops {
struct iio_sw_device* (*probe)(const char *);
int (*remove)(struct iio_sw_device *);
};
static inline
struct iio_sw_device *to_iio_sw_device(struct config_item *item)
{
return container_of(to_config_group(item), struct iio_sw_device,
group);
}
int iio_register_sw_device_type(struct iio_sw_device_type *dt);
void iio_unregister_sw_device_type(struct iio_sw_device_type *dt);
struct iio_sw_device *iio_sw_device_create(const char *, const char *);
void iio_sw_device_destroy(struct iio_sw_device *);
static inline
void iio_swd_group_init_type_name(struct iio_sw_device *d,
const char *name,
const struct config_item_type *type)
{
#if IS_ENABLED(CONFIG_CONFIGFS_FS)
config_group_init_type_name(&d->group, name, type);
#endif
}
#endif /* __IIO_SW_DEVICE */
@@ -0,0 +1,64 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Industrial I/O software trigger interface
*
* Copyright (c) 2015 Intel Corporation
*/
#ifndef __IIO_SW_TRIGGER
#define __IIO_SW_TRIGGER
#include <linux/module.h>
#include <linux/device.h>
#include <linux/iio/iio.h>
#include <linux/configfs.h>
#define module_iio_sw_trigger_driver(__iio_sw_trigger_type) \
module_driver(__iio_sw_trigger_type, iio_register_sw_trigger_type, \
iio_unregister_sw_trigger_type)
struct iio_sw_trigger_ops;
struct iio_sw_trigger_type {
const char *name;
struct module *owner;
const struct iio_sw_trigger_ops *ops;
struct list_head list;
struct config_group *group;
};
struct iio_sw_trigger {
struct iio_trigger *trigger;
struct iio_sw_trigger_type *trigger_type;
struct config_group group;
};
struct iio_sw_trigger_ops {
struct iio_sw_trigger* (*probe)(const char *);
int (*remove)(struct iio_sw_trigger *);
};
static inline
struct iio_sw_trigger *to_iio_sw_trigger(struct config_item *item)
{
return container_of(to_config_group(item), struct iio_sw_trigger,
group);
}
int iio_register_sw_trigger_type(struct iio_sw_trigger_type *tt);
void iio_unregister_sw_trigger_type(struct iio_sw_trigger_type *tt);
struct iio_sw_trigger *iio_sw_trigger_create(const char *, const char *);
void iio_sw_trigger_destroy(struct iio_sw_trigger *);
static inline
void iio_swt_group_init_type_name(struct iio_sw_trigger *t,
const char *name,
const struct config_item_type *type)
{
#if IS_ENABLED(CONFIG_CONFIGFS_FS)
config_group_init_type_name(&t->group, name, type);
#endif
}
#endif /* __IIO_SW_TRIGGER */
@@ -0,0 +1,163 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* The industrial I/O core
*
*Copyright (c) 2008 Jonathan Cameron
*
* General attributes
*/
#ifndef _INDUSTRIAL_IO_SYSFS_H_
#define _INDUSTRIAL_IO_SYSFS_H_
struct iio_buffer;
struct iio_chan_spec;
/**
* struct iio_dev_attr - iio specific device attribute
* @dev_attr: underlying device attribute
* @address: associated register address
* @l: list head for maintaining list of dynamically created attrs
* @c: specification for the underlying channel
* @buffer: the IIO buffer to which this attribute belongs to (if any)
*/
struct iio_dev_attr {
struct device_attribute dev_attr;
u64 address;
struct list_head l;
struct iio_chan_spec const *c;
struct iio_buffer *buffer;
};
#define to_iio_dev_attr(_dev_attr) \
container_of(_dev_attr, struct iio_dev_attr, dev_attr)
ssize_t iio_read_const_attr(struct device *dev,
struct device_attribute *attr,
char *len);
/**
* struct iio_const_attr - constant device specific attribute
* often used for things like available modes
* @string: attribute string
* @dev_attr: underlying device attribute
*/
struct iio_const_attr {
const char *string;
struct device_attribute dev_attr;
};
#define to_iio_const_attr(_dev_attr) \
container_of(_dev_attr, struct iio_const_attr, dev_attr)
/* Some attributes will be hard coded (device dependent) and not require an
address, in these cases pass a negative */
#define IIO_ATTR(_name, _mode, _show, _store, _addr) \
{ .dev_attr = __ATTR(_name, _mode, _show, _store), \
.address = _addr }
#define IIO_ATTR_RO(_name, _addr) \
{ .dev_attr = __ATTR_RO(_name), \
.address = _addr }
#define IIO_ATTR_WO(_name, _addr) \
{ .dev_attr = __ATTR_WO(_name), \
.address = _addr }
#define IIO_ATTR_RW(_name, _addr) \
{ .dev_attr = __ATTR_RW(_name), \
.address = _addr }
#define IIO_DEVICE_ATTR(_name, _mode, _show, _store, _addr) \
struct iio_dev_attr iio_dev_attr_##_name \
= IIO_ATTR(_name, _mode, _show, _store, _addr)
#define IIO_DEVICE_ATTR_RO(_name, _addr) \
struct iio_dev_attr iio_dev_attr_##_name \
= IIO_ATTR_RO(_name, _addr)
#define IIO_DEVICE_ATTR_WO(_name, _addr) \
struct iio_dev_attr iio_dev_attr_##_name \
= IIO_ATTR_WO(_name, _addr)
#define IIO_DEVICE_ATTR_RW(_name, _addr) \
struct iio_dev_attr iio_dev_attr_##_name \
= IIO_ATTR_RW(_name, _addr)
#define IIO_DEVICE_ATTR_NAMED(_vname, _name, _mode, _show, _store, _addr) \
struct iio_dev_attr iio_dev_attr_##_vname \
= IIO_ATTR(_name, _mode, _show, _store, _addr)
#define IIO_CONST_ATTR(_name, _string) \
struct iio_const_attr iio_const_attr_##_name \
= { .string = _string, \
.dev_attr = __ATTR(_name, S_IRUGO, iio_read_const_attr, NULL)}
#define IIO_CONST_ATTR_NAMED(_vname, _name, _string) \
struct iio_const_attr iio_const_attr_##_vname \
= { .string = _string, \
.dev_attr = __ATTR(_name, S_IRUGO, iio_read_const_attr, NULL)}
#define IIO_STATIC_CONST_DEVICE_ATTR(_name, _string) \
static ssize_t iio_const_dev_attr_show_##_name( \
struct device *dev, \
struct device_attribute *attr, \
char *buf) \
{ \
return sysfs_emit(buf, "%s\n", _string); \
} \
static IIO_DEVICE_ATTR(_name, 0444, \
iio_const_dev_attr_show_##_name, NULL, 0)
/* Generic attributes of onetype or another */
/**
* IIO_DEV_ATTR_SAMP_FREQ - sets any internal clock frequency
* @_mode: sysfs file mode/permissions
* @_show: output method for the attribute
* @_store: input method for the attribute
**/
#define IIO_DEV_ATTR_SAMP_FREQ(_mode, _show, _store) \
IIO_DEVICE_ATTR(sampling_frequency, _mode, _show, _store, 0)
/**
* IIO_DEV_ATTR_SAMP_FREQ_AVAIL - list available sampling frequencies
* @_show: output method for the attribute
*
* May be mode dependent on some devices
**/
#define IIO_DEV_ATTR_SAMP_FREQ_AVAIL(_show) \
IIO_DEVICE_ATTR(sampling_frequency_available, S_IRUGO, _show, NULL, 0)
/**
* IIO_CONST_ATTR_SAMP_FREQ_AVAIL - list available sampling frequencies
* @_string: frequency string for the attribute
*
* Constant version
**/
#define IIO_CONST_ATTR_SAMP_FREQ_AVAIL(_string) \
IIO_CONST_ATTR(sampling_frequency_available, _string)
/**
* IIO_DEV_ATTR_INT_TIME_AVAIL - list available integration times
* @_show: output method for the attribute
**/
#define IIO_DEV_ATTR_INT_TIME_AVAIL(_show) \
IIO_DEVICE_ATTR(integration_time_available, S_IRUGO, _show, NULL, 0)
/**
* IIO_CONST_ATTR_INT_TIME_AVAIL - list available integration times
* @_string: frequency string for the attribute
*
* Constant version
**/
#define IIO_CONST_ATTR_INT_TIME_AVAIL(_string) \
IIO_CONST_ATTR(integration_time_available, _string)
#define IIO_DEV_ATTR_TEMP_RAW(_show) \
IIO_DEVICE_ATTR(in_temp_raw, S_IRUGO, _show, NULL, 0)
#define IIO_CONST_ATTR_TEMP_OFFSET(_string) \
IIO_CONST_ATTR(in_temp_offset, _string)
#define IIO_CONST_ATTR_TEMP_SCALE(_string) \
IIO_CONST_ATTR(in_temp_scale, _string)
#endif /* _INDUSTRIAL_IO_SYSFS_H_ */
@@ -0,0 +1,38 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) STMicroelectronics 2017
*
* Author: Fabrice Gasnier <fabrice.gasnier@st.com>
*/
#ifndef _STM32_LPTIM_TRIGGER_H_
#define _STM32_LPTIM_TRIGGER_H_
#include <linux/iio/iio.h>
#include <linux/iio/trigger.h>
#define LPTIM1_OUT "lptim1_out"
#define LPTIM2_OUT "lptim2_out"
#define LPTIM3_OUT "lptim3_out"
#define LPTIM4_OUT "lptim4_out"
#define LPTIM5_OUT "lptim5_out"
#define LPTIM1_CH1 "lptim1_ch1"
#define LPTIM1_CH2 "lptim1_ch2"
#define LPTIM2_CH1 "lptim2_ch1"
#define LPTIM2_CH2 "lptim2_ch2"
#define LPTIM3_CH1 "lptim3_ch1"
#define LPTIM4_CH1 "lptim4_ch1"
#if IS_REACHABLE(CONFIG_IIO_STM32_LPTIMER_TRIGGER)
bool is_stm32_lptim_trigger(struct iio_trigger *trig);
#else
static inline bool is_stm32_lptim_trigger(struct iio_trigger *trig)
{
#if IS_ENABLED(CONFIG_IIO_STM32_LPTIMER_TRIGGER)
pr_warn_once("stm32 lptim_trigger not linked in\n");
#endif
return false;
}
#endif
#endif
@@ -0,0 +1,92 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (C) STMicroelectronics 2016
*
* Author: Benjamin Gaignard <benjamin.gaignard@st.com>
*/
#ifndef _STM32_TIMER_TRIGGER_H_
#define _STM32_TIMER_TRIGGER_H_
#define TIM1_TRGO "tim1_trgo"
#define TIM1_TRGO2 "tim1_trgo2"
#define TIM1_CH1 "tim1_ch1"
#define TIM1_CH2 "tim1_ch2"
#define TIM1_CH3 "tim1_ch3"
#define TIM1_CH4 "tim1_ch4"
#define TIM2_TRGO "tim2_trgo"
#define TIM2_CH1 "tim2_ch1"
#define TIM2_CH2 "tim2_ch2"
#define TIM2_CH3 "tim2_ch3"
#define TIM2_CH4 "tim2_ch4"
#define TIM3_TRGO "tim3_trgo"
#define TIM3_CH1 "tim3_ch1"
#define TIM3_CH2 "tim3_ch2"
#define TIM3_CH3 "tim3_ch3"
#define TIM3_CH4 "tim3_ch4"
#define TIM4_TRGO "tim4_trgo"
#define TIM4_CH1 "tim4_ch1"
#define TIM4_CH2 "tim4_ch2"
#define TIM4_CH3 "tim4_ch3"
#define TIM4_CH4 "tim4_ch4"
#define TIM5_TRGO "tim5_trgo"
#define TIM5_CH1 "tim5_ch1"
#define TIM5_CH2 "tim5_ch2"
#define TIM5_CH3 "tim5_ch3"
#define TIM5_CH4 "tim5_ch4"
#define TIM6_TRGO "tim6_trgo"
#define TIM7_TRGO "tim7_trgo"
#define TIM8_TRGO "tim8_trgo"
#define TIM8_TRGO2 "tim8_trgo2"
#define TIM8_CH1 "tim8_ch1"
#define TIM8_CH2 "tim8_ch2"
#define TIM8_CH3 "tim8_ch3"
#define TIM8_CH4 "tim8_ch4"
#define TIM9_TRGO "tim9_trgo"
#define TIM9_CH1 "tim9_ch1"
#define TIM9_CH2 "tim9_ch2"
#define TIM10_OC1 "tim10_oc1"
#define TIM11_OC1 "tim11_oc1"
#define TIM12_TRGO "tim12_trgo"
#define TIM12_CH1 "tim12_ch1"
#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"
#define TIM20_OC1 "tim20_oc1"
#define TIM20_OC2 "tim20_oc2"
#define TIM20_OC3 "tim20_oc3"
#define TIM20_TRGO "tim20_trgo"
#define TIM20_TRGO2 "tim20_trgo2"
#if IS_REACHABLE(CONFIG_IIO_STM32_TIMER_TRIGGER)
bool is_stm32_timer_trigger(struct iio_trigger *trig);
#else
static inline bool is_stm32_timer_trigger(struct iio_trigger *trig)
{
#if IS_ENABLED(CONFIG_IIO_STM32_TIMER_TRIGGER)
pr_warn_once("stm32-timer-trigger not linked in\n");
#endif
return false;
}
#endif
#endif
@@ -0,0 +1,182 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* The industrial I/O core, trigger handling functions
*
* Copyright (c) 2008 Jonathan Cameron
*/
#include <linux/irq.h>
#include <linux/module.h>
#include <linux/atomic.h>
#ifndef _IIO_TRIGGER_H_
#define _IIO_TRIGGER_H_
#ifdef CONFIG_IIO_TRIGGER
struct iio_subirq {
bool enabled;
};
struct iio_dev;
struct iio_trigger;
/**
* struct iio_trigger_ops - operations structure for an iio_trigger.
* @set_trigger_state: switch on/off the trigger on demand
* @reenable: function to reenable the trigger when the
* use count is zero (may be NULL)
* @validate_device: function to validate the device when the
* current trigger gets changed.
*
* This is typically static const within a driver and shared by
* instances of a given device.
**/
struct iio_trigger_ops {
int (*set_trigger_state)(struct iio_trigger *trig, bool state);
void (*reenable)(struct iio_trigger *trig);
int (*validate_device)(struct iio_trigger *trig,
struct iio_dev *indio_dev);
};
/**
* struct iio_trigger - industrial I/O trigger device
* @ops: [DRIVER] operations structure
* @owner: [INTERN] owner of this driver module
* @id: [INTERN] unique id number
* @name: [DRIVER] unique name
* @dev: [DRIVER] associated device (if relevant)
* @list: [INTERN] used in maintenance of global trigger list
* @alloc_list: [DRIVER] used for driver specific trigger list
* @use_count: [INTERN] use count for the trigger.
* @subirq_chip: [INTERN] associate 'virtual' irq chip.
* @subirq_base: [INTERN] base number for irqs provided by trigger.
* @subirqs: [INTERN] information about the 'child' irqs.
* @pool: [INTERN] bitmap of irqs currently in use.
* @pool_lock: [INTERN] protection of the irq pool.
* @attached_own_device:[INTERN] if we are using our own device as trigger,
* i.e. if we registered a poll function to the same
* device as the one providing the trigger.
* @reenable_work: [INTERN] work item used to ensure reenable can sleep.
**/
struct iio_trigger {
const struct iio_trigger_ops *ops;
struct module *owner;
int id;
const char *name;
struct device dev;
struct list_head list;
struct list_head alloc_list;
atomic_t use_count;
struct irq_chip subirq_chip;
int subirq_base;
struct iio_subirq subirqs[CONFIG_IIO_CONSUMERS_PER_TRIGGER];
unsigned long pool[BITS_TO_LONGS(CONFIG_IIO_CONSUMERS_PER_TRIGGER)];
struct mutex pool_lock;
bool attached_own_device;
struct work_struct reenable_work;
};
static inline struct iio_trigger *to_iio_trigger(struct device *d)
{
return container_of(d, struct iio_trigger, dev);
}
static inline void iio_trigger_put(struct iio_trigger *trig)
{
module_put(trig->owner);
put_device(&trig->dev);
}
static inline struct iio_trigger *iio_trigger_get(struct iio_trigger *trig)
{
get_device(&trig->dev);
WARN_ONCE(list_empty(&trig->list),
"Getting non-registered iio trigger %s is prohibited\n",
trig->name);
__module_get(trig->owner);
return trig;
}
/**
* iio_trigger_set_drvdata() - Set trigger driver data
* @trig: IIO trigger structure
* @data: Driver specific data
*
* Allows to attach an arbitrary pointer to an IIO trigger, which can later be
* retrieved by iio_trigger_get_drvdata().
*/
static inline void iio_trigger_set_drvdata(struct iio_trigger *trig, void *data)
{
dev_set_drvdata(&trig->dev, data);
}
/**
* iio_trigger_get_drvdata() - Get trigger driver data
* @trig: IIO trigger structure
*
* Returns the data previously set with iio_trigger_set_drvdata()
*/
static inline void *iio_trigger_get_drvdata(struct iio_trigger *trig)
{
return dev_get_drvdata(&trig->dev);
}
/**
* iio_trigger_register() - register a trigger with the IIO core
* @trig_info: trigger to be registered
**/
int iio_trigger_register(struct iio_trigger *trig_info);
int devm_iio_trigger_register(struct device *dev,
struct iio_trigger *trig_info);
/**
* iio_trigger_unregister() - unregister a trigger from the core
* @trig_info: trigger to be unregistered
**/
void iio_trigger_unregister(struct iio_trigger *trig_info);
/**
* iio_trigger_set_immutable() - set an immutable trigger on destination
*
* @indio_dev: IIO device structure containing the device
* @trig: trigger to assign to device
*
**/
int iio_trigger_set_immutable(struct iio_dev *indio_dev, struct iio_trigger *trig);
void iio_trigger_poll(struct iio_trigger *trig);
void iio_trigger_poll_nested(struct iio_trigger *trig);
irqreturn_t iio_trigger_generic_data_rdy_poll(int irq, void *private);
#define iio_trigger_alloc(parent, fmt, ...) \
__iio_trigger_alloc((parent), THIS_MODULE, (fmt), ##__VA_ARGS__)
__printf(3, 4)
struct iio_trigger *__iio_trigger_alloc(struct device *parent,
struct module *this_mod,
const char *fmt, ...);
void iio_trigger_free(struct iio_trigger *trig);
/**
* iio_trigger_using_own() - tells us if we use our own HW trigger ourselves
* @indio_dev: device to check
*/
bool iio_trigger_using_own(struct iio_dev *indio_dev);
int iio_validate_own_trigger(struct iio_dev *idev, struct iio_trigger *trig);
int iio_trigger_validate_own_device(struct iio_trigger *trig,
struct iio_dev *indio_dev);
#else
struct iio_trigger;
struct iio_trigger_ops;
#endif
#endif /* _IIO_TRIGGER_H_ */
@@ -0,0 +1,53 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* The industrial I/O core, trigger consumer functions
*
* Copyright (c) 2008-2011 Jonathan Cameron
*/
#ifndef __LINUX_IIO_TRIGGER_CONSUMER_H__
#define __LINUX_IIO_TRIGGER_CONSUMER_H__
#include <linux/interrupt.h>
#include <linux/types.h>
struct iio_dev;
struct iio_trigger;
/**
* struct iio_poll_func - poll function pair
*
* @indio_dev: data specific to device (passed into poll func)
* @h: the function that is actually run on trigger
* @thread: threaded interrupt part
* @type: the type of interrupt (basically if oneshot)
* @name: name used to identify the trigger consumer.
* @irq: the corresponding irq as allocated from the
* trigger pool
* @timestamp: some devices need a timestamp grabbed as soon
* as possible after the trigger - hence handler
* passes it via here.
**/
struct iio_poll_func {
struct iio_dev *indio_dev;
irqreturn_t (*h)(int irq, void *p);
irqreturn_t (*thread)(int irq, void *p);
int type;
char *name;
int irq;
s64 timestamp;
};
__printf(5, 6) struct iio_poll_func
*iio_alloc_pollfunc(irqreturn_t (*h)(int irq, void *p),
irqreturn_t (*thread)(int irq, void *p),
int type,
struct iio_dev *indio_dev,
const char *fmt,
...);
void iio_dealloc_pollfunc(struct iio_poll_func *pf);
irqreturn_t iio_pollfunc_store_time(int irq, void *p);
void iio_trigger_notify_done(struct iio_trigger *trig);
#endif
@@ -0,0 +1,38 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _LINUX_IIO_TRIGGERED_BUFFER_H_
#define _LINUX_IIO_TRIGGERED_BUFFER_H_
#include <linux/iio/buffer.h>
#include <linux/interrupt.h>
struct iio_dev;
struct iio_dev_attr;
struct iio_buffer_setup_ops;
int iio_triggered_buffer_setup_ext(struct iio_dev *indio_dev,
irqreturn_t (*h)(int irq, void *p),
irqreturn_t (*thread)(int irq, void *p),
enum iio_buffer_direction direction,
const struct iio_buffer_setup_ops *setup_ops,
const struct iio_dev_attr **buffer_attrs);
void iio_triggered_buffer_cleanup(struct iio_dev *indio_dev);
#define iio_triggered_buffer_setup(indio_dev, h, thread, setup_ops) \
iio_triggered_buffer_setup_ext((indio_dev), (h), (thread), \
IIO_BUFFER_DIRECTION_IN, (setup_ops), \
NULL)
int devm_iio_triggered_buffer_setup_ext(struct device *dev,
struct iio_dev *indio_dev,
irqreturn_t (*h)(int irq, void *p),
irqreturn_t (*thread)(int irq, void *p),
enum iio_buffer_direction direction,
const struct iio_buffer_setup_ops *ops,
const struct iio_dev_attr **buffer_attrs);
#define devm_iio_triggered_buffer_setup(dev, indio_dev, h, thread, setup_ops) \
devm_iio_triggered_buffer_setup_ext((dev), (indio_dev), (h), (thread), \
IIO_BUFFER_DIRECTION_IN, \
(setup_ops), NULL)
#endif
@@ -0,0 +1,12 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _LINUX_IIO_TRIGGERED_EVENT_H_
#define _LINUX_IIO_TRIGGERED_EVENT_H_
#include <linux/interrupt.h>
int iio_triggered_event_setup(struct iio_dev *indio_dev,
irqreturn_t (*h)(int irq, void *p),
irqreturn_t (*thread)(int irq, void *p));
void iio_triggered_event_cleanup(struct iio_dev *indio_dev);
#endif
@@ -0,0 +1,77 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/* industrial I/O data types needed both in and out of kernel
*
* Copyright (c) 2008 Jonathan Cameron
*/
#ifndef _IIO_TYPES_H_
#define _IIO_TYPES_H_
#include <uapi/linux/iio/types.h>
enum iio_event_info {
IIO_EV_INFO_ENABLE,
IIO_EV_INFO_VALUE,
IIO_EV_INFO_HYSTERESIS,
IIO_EV_INFO_PERIOD,
IIO_EV_INFO_HIGH_PASS_FILTER_3DB,
IIO_EV_INFO_LOW_PASS_FILTER_3DB,
IIO_EV_INFO_TIMEOUT,
IIO_EV_INFO_RESET_TIMEOUT,
IIO_EV_INFO_TAP2_MIN_DELAY,
IIO_EV_INFO_RUNNING_PERIOD,
IIO_EV_INFO_RUNNING_COUNT,
IIO_EV_INFO_SCALE,
};
#define IIO_VAL_INT 1
#define IIO_VAL_INT_PLUS_MICRO 2
#define IIO_VAL_INT_PLUS_NANO 3
#define IIO_VAL_INT_PLUS_MICRO_DB 4
#define IIO_VAL_INT_MULTIPLE 5
#define IIO_VAL_INT_64 6 /* 64-bit data, val is lower 32 bits */
#define IIO_VAL_FRACTIONAL 10
#define IIO_VAL_FRACTIONAL_LOG2 11
#define IIO_VAL_CHAR 12
enum iio_available_type {
IIO_AVAIL_LIST,
IIO_AVAIL_RANGE,
};
enum iio_chan_info_enum {
IIO_CHAN_INFO_RAW = 0,
IIO_CHAN_INFO_PROCESSED,
IIO_CHAN_INFO_SCALE,
IIO_CHAN_INFO_OFFSET,
IIO_CHAN_INFO_CALIBSCALE,
IIO_CHAN_INFO_CALIBBIAS,
IIO_CHAN_INFO_PEAK,
IIO_CHAN_INFO_PEAK_SCALE,
IIO_CHAN_INFO_QUADRATURE_CORRECTION_RAW,
IIO_CHAN_INFO_AVERAGE_RAW,
IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY,
IIO_CHAN_INFO_HIGH_PASS_FILTER_3DB_FREQUENCY,
IIO_CHAN_INFO_SAMP_FREQ,
IIO_CHAN_INFO_FREQUENCY,
IIO_CHAN_INFO_PHASE,
IIO_CHAN_INFO_HARDWAREGAIN,
IIO_CHAN_INFO_HYSTERESIS,
IIO_CHAN_INFO_HYSTERESIS_RELATIVE,
IIO_CHAN_INFO_INT_TIME,
IIO_CHAN_INFO_ENABLE,
IIO_CHAN_INFO_CALIBHEIGHT,
IIO_CHAN_INFO_CALIBWEIGHT,
IIO_CHAN_INFO_DEBOUNCE_COUNT,
IIO_CHAN_INFO_DEBOUNCE_TIME,
IIO_CHAN_INFO_CALIBEMISSIVITY,
IIO_CHAN_INFO_OVERSAMPLING_RATIO,
IIO_CHAN_INFO_THERMOCOUPLE_TYPE,
IIO_CHAN_INFO_CALIBAMBIENT,
IIO_CHAN_INFO_ZEROPOINT,
IIO_CHAN_INFO_TROUGH,
IIO_CHAN_INFO_CONVDELAY,
IIO_CHAN_INFO_POWERFACTOR,
};
#endif /* _IIO_TYPES_H_ */