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:
@@ -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 >s->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 >s->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_ */
|
||||
Reference in New Issue
Block a user