summaryrefslogtreecommitdiff
path: root/drivers/iio/adc/ad7606.h
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/iio/adc/ad7606.h')
-rw-r--r--drivers/iio/adc/ad7606.h134
1 files changed, 107 insertions, 27 deletions
diff --git a/drivers/iio/adc/ad7606.h b/drivers/iio/adc/ad7606.h
index 6649e84d25de..998814a92b82 100644
--- a/drivers/iio/adc/ad7606.h
+++ b/drivers/iio/adc/ad7606.h
@@ -8,7 +8,9 @@
#ifndef IIO_ADC_AD7606_H_
#define IIO_ADC_AD7606_H_
-#define AD760X_CHANNEL(num, mask_sep, mask_type, mask_all) { \
+#define AD760X_MAX_CHANNELS 16
+
+#define AD760X_CHANNEL(num, mask_sep, mask_type, mask_all, bits) { \
.type = IIO_VOLTAGE, \
.indexed = 1, \
.channel = num, \
@@ -19,39 +21,79 @@
.scan_index = num, \
.scan_type = { \
.sign = 's', \
- .realbits = 16, \
- .storagebits = 16, \
+ .realbits = (bits), \
+ .storagebits = (bits) > 16 ? 32 : 16, \
+ .endianness = IIO_CPU, \
+ }, \
+}
+
+#define AD7606_SW_CHANNEL(num, bits) { \
+ .type = IIO_VOLTAGE, \
+ .indexed = 1, \
+ .channel = num, \
+ .address = num, \
+ .info_mask_separate = \
+ BIT(IIO_CHAN_INFO_RAW) | \
+ BIT(IIO_CHAN_INFO_SCALE), \
+ .info_mask_separate_available = \
+ BIT(IIO_CHAN_INFO_SCALE), \
+ .info_mask_shared_by_all = \
+ BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
+ .info_mask_shared_by_all_available = \
+ BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
+ .scan_index = num, \
+ .scan_type = { \
+ .sign = 's', \
+ .realbits = (bits), \
+ .storagebits = (bits) > 16 ? 32 : 16, \
.endianness = IIO_CPU, \
}, \
}
#define AD7605_CHANNEL(num) \
AD760X_CHANNEL(num, BIT(IIO_CHAN_INFO_RAW), \
- BIT(IIO_CHAN_INFO_SCALE), 0)
+ BIT(IIO_CHAN_INFO_SCALE), 0, 16)
-#define AD7606_CHANNEL(num) \
+#define AD7606_CHANNEL(num, bits) \
AD760X_CHANNEL(num, BIT(IIO_CHAN_INFO_RAW), \
BIT(IIO_CHAN_INFO_SCALE), \
- BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO))
+ BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), bits)
+
+#define AD7616_CHANNEL(num) AD7606_SW_CHANNEL(num, 16)
+
+#define AD7606_BI_CHANNEL(num) \
+ AD760X_CHANNEL(num, 0, \
+ BIT(IIO_CHAN_INFO_SCALE), \
+ BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
+ BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), 16)
-#define AD7616_CHANNEL(num) \
- AD760X_CHANNEL(num, BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),\
- 0, BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO))
+struct ad7606_state;
+
+typedef int (*ad7606_scale_setup_cb_t)(struct ad7606_state *st,
+ struct iio_chan_spec *chan, int ch);
/**
* struct ad7606_chip_info - chip specific information
* @channels: channel specification
+ * @max_samplerate: maximum supported samplerate
+ * @name device name
* @num_channels: number of channels
+ * @num_adc_channels the number of channels the ADC actually inputs.
+ * @scale_setup_cb: callback to setup the scales for each channel
* @oversampling_avail pointer to the array which stores the available
* oversampling ratios.
* @oversampling_num number of elements stored in oversampling_avail array
* @os_req_reset some devices require a reset to update oversampling
- * @init_delay_ms required delay in miliseconds for initialization
+ * @init_delay_ms required delay in milliseconds for initialization
* after a restart
*/
struct ad7606_chip_info {
const struct iio_chan_spec *channels;
+ unsigned int max_samplerate;
+ const char *name;
+ unsigned int num_adc_channels;
unsigned int num_channels;
+ ad7606_scale_setup_cb_t scale_setup_cb;
const unsigned int *oversampling_avail;
unsigned int oversampling_num;
bool os_req_reset;
@@ -59,16 +101,31 @@ struct ad7606_chip_info {
};
/**
+ * struct ad7606_chan_scale - channel scale configuration
+ * @scale_avail pointer to the array which stores the available scales
+ * @num_scales number of elements stored in the scale_avail array
+ * @range voltage range selection, selects which scale to apply
+ * @reg_offset offset for the register value, to be applied when
+ * writing the value of 'range' to the register value
+ */
+struct ad7606_chan_scale {
+#define AD760X_MAX_SCALES 16
+ const unsigned int (*scale_avail)[2];
+ unsigned int num_scales;
+ unsigned int range;
+ unsigned int reg_offset;
+};
+
+/**
* struct ad7606_state - driver instance specific data
* @dev pointer to kernel device
* @chip_info entry in the table of chips that describes this device
* @bops bus operations (SPI or parallel)
- * @range voltage range selection, selects which scale to apply
+ * @chan_scales scale configuration for channels
* @oversampling oversampling selection
+ * @cnvst_pwm pointer to the PWM device connected to the cnvst pin
* @base_address address from where to read data in parallel operation
* @sw_mode_en software mode enabled
- * @scale_avail pointer to the array which stores the available scales
- * @num_scales number of elements stored in the scale_avail array
* @oversampling_avail pointer to the array which stores the available
* oversampling ratios.
* @num_os_ratios number of elements stored in oversampling_avail array
@@ -92,14 +149,14 @@ struct ad7606_state {
struct device *dev;
const struct ad7606_chip_info *chip_info;
const struct ad7606_bus_ops *bops;
- unsigned int range[16];
+ struct ad7606_chan_scale chan_scales[AD760X_MAX_CHANNELS];
unsigned int oversampling;
+ struct pwm_device *cnvst_pwm;
void __iomem *base_address;
bool sw_mode_en;
- const unsigned int *scale_avail;
- unsigned int num_scales;
const unsigned int *oversampling_avail;
unsigned int num_os_ratios;
+ struct iio_backend *back;
int (*write_scale)(struct iio_dev *indio_dev, int ch, int val);
int (*write_os)(struct iio_dev *indio_dev, int val);
@@ -116,24 +173,33 @@ struct ad7606_state {
/*
* DMA (thus cache coherency maintenance) may require the
* transfer buffers to live in their own cache lines.
- * 16 * 16-bit samples + 64-bit timestamp
+ * 16 * 16-bit samples + 64-bit timestamp - for AD7616
+ * 8 * 32-bit samples + 64-bit timestamp - for AD7616C-18 (and similar)
*/
- unsigned short data[20] __aligned(IIO_DMA_MINALIGN);
+ union {
+ u16 buf16[20];
+ u32 buf32[10];
+ } data __aligned(IIO_DMA_MINALIGN);
__be16 d16[2];
};
/**
* struct ad7606_bus_ops - driver bus operations
+ * @iio_backend_config function pointer for configuring the iio_backend for
+ * the compatibles that use it
* @read_block function pointer for reading blocks of data
* @sw_mode_config: pointer to a function which configured the device
* for software mode
* @reg_read function pointer for reading spi register
* @reg_write function pointer for writing spi register
* @write_mask function pointer for write spi register with mask
+ * @update_scan_mode function pointer for handling the calls to iio_info's update_scan
+ * mode when enabling/disabling channels.
* @rd_wr_cmd pointer to the function which calculates the spi address
*/
struct ad7606_bus_ops {
/* more methods added in future? */
+ int (*iio_backend_config)(struct device *dev, struct iio_dev *indio_dev);
int (*read_block)(struct device *dev, int num, void *data);
int (*sw_mode_config)(struct iio_dev *indio_dev);
int (*reg_read)(struct ad7606_state *st, unsigned int addr);
@@ -144,23 +210,37 @@ struct ad7606_bus_ops {
unsigned int addr,
unsigned long mask,
unsigned int val);
+ int (*update_scan_mode)(struct iio_dev *indio_dev, const unsigned long *scan_mask);
u16 (*rd_wr_cmd)(int addr, char isWriteOp);
};
+/**
+ * struct ad7606_bus_info - agregate ad7606_chip_info and ad7606_bus_ops
+ * @chip_info entry in the table of chips that describes this device
+ * @bops bus operations (SPI or parallel)
+ */
+struct ad7606_bus_info {
+ const struct ad7606_chip_info *chip_info;
+ const struct ad7606_bus_ops *bops;
+};
+
int ad7606_probe(struct device *dev, int irq, void __iomem *base_address,
- const char *name, unsigned int id,
+ const struct ad7606_chip_info *info,
const struct ad7606_bus_ops *bops);
int ad7606_reset(struct ad7606_state *st);
-enum ad7606_supported_device_ids {
- ID_AD7605_4,
- ID_AD7606_8,
- ID_AD7606_6,
- ID_AD7606_4,
- ID_AD7606B,
- ID_AD7616,
-};
+extern const struct ad7606_chip_info ad7605_4_info;
+extern const struct ad7606_chip_info ad7606_8_info;
+extern const struct ad7606_chip_info ad7606_6_info;
+extern const struct ad7606_chip_info ad7606_4_info;
+extern const struct ad7606_chip_info ad7606b_info;
+extern const struct ad7606_chip_info ad7606c_16_info;
+extern const struct ad7606_chip_info ad7606c_18_info;
+extern const struct ad7606_chip_info ad7607_info;
+extern const struct ad7606_chip_info ad7608_info;
+extern const struct ad7606_chip_info ad7609_info;
+extern const struct ad7606_chip_info ad7616_info;
#ifdef CONFIG_PM_SLEEP
extern const struct dev_pm_ops ad7606_pm_ops;