diff options
Diffstat (limited to 'include/linux/iio')
-rw-r--r-- | include/linux/iio/adc/ad_sigma_delta.h | 173 | ||||
-rw-r--r-- | include/linux/iio/buffer.h | 6 | ||||
-rw-r--r-- | include/linux/iio/consumer.h | 44 | ||||
-rw-r--r-- | include/linux/iio/iio.h | 65 | ||||
-rw-r--r-- | include/linux/iio/kfifo_buf.h | 3 | ||||
-rw-r--r-- | include/linux/iio/machine.h | 5 | ||||
-rw-r--r-- | include/linux/iio/trigger.h | 13 | ||||
-rw-r--r-- | include/linux/iio/trigger_consumer.h | 11 | ||||
-rw-r--r-- | include/linux/iio/types.h | 1 |
9 files changed, 301 insertions, 20 deletions
diff --git a/include/linux/iio/adc/ad_sigma_delta.h b/include/linux/iio/adc/ad_sigma_delta.h new file mode 100644 index 000000000000..2e4eab9868a3 --- /dev/null +++ b/include/linux/iio/adc/ad_sigma_delta.h @@ -0,0 +1,173 @@ +/* + * Support code for Analog Devices Sigma-Delta ADCs + * + * Copyright 2012 Analog Devices Inc. + * Author: Lars-Peter Clausen <lars@metafoo.de> + * + * Licensed under the GPL-2. + */ +#ifndef __AD_SIGMA_DELTA_H__ +#define __AD_SIGMA_DELTA_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 iio_dev; + +/** + * 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. + * @set_mode: Will be called to select the current mode, may be NULL. + * @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. + * @addr_shift: Shift of the register address in the communications register. + * @read_mask: Mask for the communications register having the read bit set. + */ +struct ad_sigma_delta_info { + int (*set_channel)(struct ad_sigma_delta *, unsigned int channel); + int (*set_mode)(struct ad_sigma_delta *, enum ad_sigma_delta_mode mode); + int (*postprocess_sample)(struct ad_sigma_delta *, unsigned int raw_sample); + bool has_registers; + unsigned int addr_shift; + unsigned int read_mask; +}; + +/** + * 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; + bool irq_dis; + + bool bus_locked; + + uint8_t comm; + + const struct ad_sigma_delta_info *info; + + /* + * DMA (thus cache coherency maintenance) requires the + * transfer buffers to live in their own cache lines. + */ + uint8_t data[4] ____cacheline_aligned; +}; + +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_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, uint8_t 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_sigma_delta_single_conversion(struct iio_dev *indio_dev, + const struct iio_chan_spec *chan, int *val); +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 ad_sd_setup_buffer_and_trigger(struct iio_dev *indio_dev); +void ad_sd_cleanup_buffer_and_trigger(struct iio_dev *indio_dev); + +int ad_sd_validate_trigger(struct iio_dev *indio_dev, struct iio_trigger *trig); + +#define __AD_SD_CHANNEL(_si, _channel1, _channel2, _address, _bits, \ + _storagebits, _shift, _extend_name, _type) \ + { \ + .type = (_type), \ + .differential = (_channel2 == -1 ? 0 : 1), \ + .indexed = 1, \ + .channel = (_channel1), \ + .channel2 = (_channel2), \ + .address = (_address), \ + .extend_name = (_extend_name), \ + .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ + IIO_CHAN_INFO_SCALE_SHARED_BIT | \ + IIO_CHAN_INFO_OFFSET_SEPARATE_BIT, \ + .scan_index = (_si), \ + .scan_type = { \ + .sign = 'u', \ + .realbits = (_bits), \ + .storagebits = (_storagebits), \ + .shift = (_shift), \ + .endianness = IIO_BE, \ + }, \ + } + +#define AD_SD_DIFF_CHANNEL(_si, _channel1, _channel2, _address, _bits, \ + _storagebits, _shift) \ + __AD_SD_CHANNEL(_si, _channel1, _channel2, _address, _bits, \ + _storagebits, _shift, NULL, IIO_VOLTAGE) + +#define AD_SD_SHORTED_CHANNEL(_si, _channel, _address, _bits, \ + _storagebits, _shift) \ + __AD_SD_CHANNEL(_si, _channel, _channel, _address, _bits, \ + _storagebits, _shift, "shorted", IIO_VOLTAGE) + +#define AD_SD_CHANNEL(_si, _channel, _address, _bits, \ + _storagebits, _shift) \ + __AD_SD_CHANNEL(_si, _channel, -1, _address, _bits, \ + _storagebits, _shift, NULL, IIO_VOLTAGE) + +#define AD_SD_TEMP_CHANNEL(_si, _address, _bits, _storagebits, _shift) \ + __AD_SD_CHANNEL(_si, 0, -1, _address, _bits, \ + _storagebits, _shift, NULL, IIO_TEMP) + +#define AD_SD_SUPPLY_CHANNEL(_si, _channel, _address, _bits, _storagebits, \ + _shift) \ + __AD_SD_CHANNEL(_si, _channel, -1, _address, _bits, \ + _storagebits, _shift, "supply", IIO_VOLTAGE) + +#endif diff --git a/include/linux/iio/buffer.h b/include/linux/iio/buffer.h index 8ba516fc2ec6..c629b3a1d9a9 100644 --- a/include/linux/iio/buffer.h +++ b/include/linux/iio/buffer.h @@ -36,7 +36,7 @@ struct iio_buffer; * any of them not existing. **/ struct iio_buffer_access_funcs { - int (*store_to)(struct iio_buffer *buffer, u8 *data, s64 timestamp); + int (*store_to)(struct iio_buffer *buffer, u8 *data); int (*read_first_n)(struct iio_buffer *buffer, size_t n, char __user *buf); @@ -118,10 +118,8 @@ int iio_scan_mask_set(struct iio_dev *indio_dev, * iio_push_to_buffer() - push to a registered buffer. * @buffer: IIO buffer structure for device * @data: the data to push to the buffer - * @timestamp: timestamp to associate with the data */ -int iio_push_to_buffer(struct iio_buffer *buffer, unsigned char *data, - s64 timestamp); +int iio_push_to_buffer(struct iio_buffer *buffer, unsigned char *data); int iio_update_demux(struct iio_dev *indio_dev); diff --git a/include/linux/iio/consumer.h b/include/linux/iio/consumer.h index e2657e6d4d26..e875bcf0478f 100644 --- a/include/linux/iio/consumer.h +++ b/include/linux/iio/consumer.h @@ -8,7 +8,7 @@ * the Free Software Foundation. */ #ifndef _IIO_INKERN_CONSUMER_H_ -#define _IIO_INKERN_CONSUMER_H +#define _IIO_INKERN_CONSUMER_H_ #include <linux/iio/types.h> struct iio_dev; @@ -61,7 +61,7 @@ void iio_channel_release_all(struct iio_channel *chan); /** * iio_read_channel_raw() - read from a given channel - * @channel: The channel being queried. + * @chan: The channel being queried. * @val: Value read back. * * Note raw reads from iio channels are in adc counts and hence @@ -71,6 +71,21 @@ int iio_read_channel_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_get_channel_type() - get the type of a channel * @channel: The channel being queried. * @type: The type of the channel. @@ -82,7 +97,7 @@ int iio_get_channel_type(struct iio_channel *channel, /** * iio_read_channel_scale() - read the scale value for a channel - * @channel: The channel being queried. + * @chan: The channel being queried. * @val: First part of value read back. * @val2: Second part of value read back. * @@ -93,4 +108,27 @@ int iio_get_channel_type(struct iio_channel *channel, int iio_read_channel_scale(struct iio_channel *chan, 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 1000 as the scale factor. + */ +int iio_convert_raw_to_processed(struct iio_channel *chan, int raw, + int *processed, unsigned int scale); + #endif diff --git a/include/linux/iio/iio.h b/include/linux/iio/iio.h index be82936c4089..c0ae76ac4e0b 100644 --- a/include/linux/iio/iio.h +++ b/include/linux/iio/iio.h @@ -35,10 +35,13 @@ enum iio_chan_info_enum { IIO_CHAN_INFO_FREQUENCY, IIO_CHAN_INFO_PHASE, IIO_CHAN_INFO_HARDWAREGAIN, + IIO_CHAN_INFO_HYSTERESIS, }; #define IIO_CHAN_INFO_SHARED_BIT(type) BIT(type*2) #define IIO_CHAN_INFO_SEPARATE_BIT(type) BIT(type*2 + 1) +#define IIO_CHAN_INFO_BITS(type) (IIO_CHAN_INFO_SHARED_BIT(type) | \ + IIO_CHAN_INFO_SEPARATE_BIT(type)) #define IIO_CHAN_INFO_RAW_SEPARATE_BIT \ IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_RAW) @@ -100,6 +103,10 @@ enum iio_chan_info_enum { IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_HARDWAREGAIN) #define IIO_CHAN_INFO_HARDWAREGAIN_SHARED_BIT \ IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_HARDWAREGAIN) +#define IIO_CHAN_INFO_HYSTERESIS_SEPARATE_BIT \ + IIO_CHAN_INFO_SEPARATE_BIT(IIO_CHAN_INFO_HYSTERESIS) +#define IIO_CHAN_INFO_HYSTERESIS_SHARED_BIT \ + IIO_CHAN_INFO_SHARED_BIT(IIO_CHAN_INFO_HYSTERESIS) enum iio_endian { IIO_CPU, @@ -164,7 +171,7 @@ ssize_t iio_enum_write(struct iio_dev *indio_dev, * IIO_ENUM() - Initialize enum extended channel attribute * @_name: Attribute name * @_shared: Whether the attribute is shared between all channels - * @_e: Pointer to a iio_enum struct + * @_e: Pointer to an iio_enum struct * * This should usually be used together with IIO_ENUM_AVAILABLE() */ @@ -180,9 +187,9 @@ ssize_t iio_enum_write(struct iio_dev *indio_dev, /** * IIO_ENUM_AVAILABLE() - Initialize enum available extended channel attribute * @_name: Attribute name ("_available" will be appended to the name) - * @_e: Pointer to a iio_enum struct + * @_e: Pointer to an iio_enum struct * - * Creates a read only attribute which list all the available enum items in a + * Creates a read only attribute which lists all the available enum items in a * space separated list. This should usually be used together with IIO_ENUM() */ #define IIO_ENUM_AVAILABLE(_name, _e) \ @@ -229,6 +236,7 @@ ssize_t iio_enum_write(struct iio_dev *indio_dev, * @indexed: Specify the channel has a numerical index. If not, * the channel index number will be suppressed for sysfs * attributes but not for event codes. + * @output: Channel is output. * @differential: Channel is differential. */ struct iio_chan_spec { @@ -255,6 +263,21 @@ struct iio_chan_spec { unsigned differential:1; }; + +/** + * iio_channel_has_info() - Checks whether a channel supports a info attribute + * @chan: The channel to be queried + * @type: Type of the info attribute to be checked + * + * Returns true if the channels supports reporting values for the given info + * attribute type, false otherwise. + */ +static inline bool iio_channel_has_info(const struct iio_chan_spec *chan, + enum iio_chan_info_enum type) +{ + return chan->info_mask & IIO_CHAN_INFO_BITS(type); +} + #define IIO_ST(si, rb, sb, sh) \ { .sign = si, .realbits = rb, .storagebits = sb, .shift = sh } @@ -312,6 +335,9 @@ struct iio_dev; * Meaning is event dependent. * @validate_trigger: function to validate the trigger when the * current trigger gets changed. + * @update_scan_mode: function to configure device and scan buffer when + * channels have changed + * @debugfs_reg_access: function to read or write register value of device **/ struct iio_info { struct module *driver_module; @@ -367,10 +393,10 @@ struct iio_info { * scan mask is valid for the device. */ struct iio_buffer_setup_ops { - int (*preenable)(struct iio_dev *); - int (*postenable)(struct iio_dev *); - int (*predisable)(struct iio_dev *); - int (*postdisable)(struct iio_dev *); + int (*preenable)(struct iio_dev *); + int (*postenable)(struct iio_dev *); + int (*predisable)(struct iio_dev *); + int (*postdisable)(struct iio_dev *); bool (*validate_scan_mask)(struct iio_dev *indio_dev, const unsigned long *scan_mask); }; @@ -516,6 +542,31 @@ static inline struct iio_dev *iio_device_get(struct iio_dev *indio_dev) return indio_dev ? dev_to_iio_dev(get_device(&indio_dev->dev)) : NULL; } + +/** + * iio_device_set_drvdata() - Set device driver data + * @indio_dev: IIO device structure + * @data: Driver specific data + * + * Allows to attach an arbitrary pointer to an IIO device, which can later be + * retrieved by iio_device_get_drvdata(). + */ +static inline void iio_device_set_drvdata(struct iio_dev *indio_dev, void *data) +{ + dev_set_drvdata(&indio_dev->dev, data); +} + +/** + * iio_device_get_drvdata() - Get device driver data + * @indio_dev: IIO device structure + * + * Returns the data previously set with iio_device_set_drvdata() + */ +static inline void *iio_device_get_drvdata(struct iio_dev *indio_dev) +{ + return dev_get_drvdata(&indio_dev->dev); +} + /* Can we make this smaller? */ #define IIO_ALIGN L1_CACHE_BYTES /** diff --git a/include/linux/iio/kfifo_buf.h b/include/linux/iio/kfifo_buf.h index 014d5a13b32b..25eeac762e84 100644 --- a/include/linux/iio/kfifo_buf.h +++ b/include/linux/iio/kfifo_buf.h @@ -1,3 +1,5 @@ +#ifndef __LINUX_IIO_KFIFO_BUF_H__ +#define __LINUX_IIO_KFIFO_BUF_H__ #include <linux/kfifo.h> #include <linux/iio/iio.h> @@ -6,3 +8,4 @@ struct iio_buffer *iio_kfifo_allocate(struct iio_dev *indio_dev); void iio_kfifo_free(struct iio_buffer *r); +#endif diff --git a/include/linux/iio/machine.h b/include/linux/iio/machine.h index 400a453ff67b..809a3f08d5a5 100644 --- a/include/linux/iio/machine.h +++ b/include/linux/iio/machine.h @@ -8,6 +8,9 @@ * the Free Software Foundation. */ +#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. @@ -22,3 +25,5 @@ struct iio_map { const char *consumer_dev_name; const char *consumer_channel; }; + +#endif diff --git a/include/linux/iio/trigger.h b/include/linux/iio/trigger.h index a9819940a84c..20239da1d0f7 100644 --- a/include/linux/iio/trigger.h +++ b/include/linux/iio/trigger.h @@ -29,7 +29,7 @@ struct iio_subirq { * instances of a given device. **/ struct iio_trigger_ops { - struct module *owner; + struct module *owner; int (*set_trigger_state)(struct iio_trigger *trig, bool state); int (*try_reenable)(struct iio_trigger *trig); int (*validate_device)(struct iio_trigger *trig, @@ -39,7 +39,7 @@ struct iio_trigger_ops { /** * struct iio_trigger - industrial I/O trigger device - * + * @ops: [DRIVER] operations structure * @id: [INTERN] unique id number * @name: [DRIVER] unique name * @dev: [DRIVER] associated device (if relevant) @@ -76,19 +76,19 @@ struct iio_trigger { 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->ops->owner); put_device(&trig->dev); -}; +} static inline void iio_trigger_get(struct iio_trigger *trig) { get_device(&trig->dev); __module_get(trig->ops->owner); -}; +} /** * iio_trigger_register() - register a trigger with the IIO core @@ -104,7 +104,8 @@ void iio_trigger_unregister(struct iio_trigger *trig_info); /** * iio_trigger_poll() - called on a trigger occurring - * @trig: trigger which occurred + * @trig: trigger which occurred + * @time: timestamp when trigger occurred * * Typically called in relevant hardware interrupt handler. **/ diff --git a/include/linux/iio/trigger_consumer.h b/include/linux/iio/trigger_consumer.h index 60d64b356945..c4f8c7409666 100644 --- a/include/linux/iio/trigger_consumer.h +++ b/include/linux/iio/trigger_consumer.h @@ -7,6 +7,15 @@ * the Free Software Foundation. */ +#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 * @@ -50,3 +59,5 @@ void iio_trigger_notify_done(struct iio_trigger *trig); */ int iio_triggered_buffer_postenable(struct iio_dev *indio_dev); int iio_triggered_buffer_predisable(struct iio_dev *indio_dev); + +#endif diff --git a/include/linux/iio/types.h b/include/linux/iio/types.h index 44e397705d7f..5c647ecfd5ba 100644 --- a/include/linux/iio/types.h +++ b/include/linux/iio/types.h @@ -57,5 +57,6 @@ enum iio_modifier { #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_FRACTIONAL 10 #endif /* _IIO_TYPES_H_ */ |