1af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen/* 2af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen * Support code for Analog Devices Sigma-Delta ADCs 3af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen * 4af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen * Copyright 2012 Analog Devices Inc. 5af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen * Author: Lars-Peter Clausen <lars@metafoo.de> 6af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen * 7af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen * Licensed under the GPL-2. 8af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen */ 9af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen#ifndef __AD_SIGMA_DELTA_H__ 10af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen#define __AD_SIGMA_DELTA_H__ 11af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen 12af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausenenum ad_sigma_delta_mode { 13af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen AD_SD_MODE_CONTINUOUS = 0, 14af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen AD_SD_MODE_SINGLE = 1, 15af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen AD_SD_MODE_IDLE = 2, 16af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen AD_SD_MODE_POWERDOWN = 3, 17af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen}; 18af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen 19af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen/** 20af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen * struct ad_sigma_delta_calib_data - Calibration data for Sigma Delta devices 21af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen * @mode: Calibration mode. 22af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen * @channel: Calibration channel. 23af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen */ 24af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausenstruct ad_sd_calib_data { 25af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen unsigned int mode; 26af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen unsigned int channel; 27af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen}; 28af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen 29af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausenstruct ad_sigma_delta; 30af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausenstruct iio_dev; 31af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen 32af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen/** 33af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen * struct ad_sigma_delta_info - Sigma Delta driver specific callbacks and options 34af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen * @set_channel: Will be called to select the current channel, may be NULL. 35af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen * @set_mode: Will be called to select the current mode, may be NULL. 36af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen * @postprocess_sample: Is called for each sampled data word, can be used to 37af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen * modify or drop the sample data, it, may be NULL. 38af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen * @has_registers: true if the device has writable and readable registers, false 39af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen * if there is just one read-only sample data shift register. 40af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen * @addr_shift: Shift of the register address in the communications register. 41af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen * @read_mask: Mask for the communications register having the read bit set. 42af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen */ 43af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausenstruct ad_sigma_delta_info { 44af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen int (*set_channel)(struct ad_sigma_delta *, unsigned int channel); 45af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen int (*set_mode)(struct ad_sigma_delta *, enum ad_sigma_delta_mode mode); 46af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen int (*postprocess_sample)(struct ad_sigma_delta *, unsigned int raw_sample); 47af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen bool has_registers; 48af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen unsigned int addr_shift; 49af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen unsigned int read_mask; 50af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen}; 51af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen 52af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen/** 53af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen * struct ad_sigma_delta - Sigma Delta device struct 54af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen * @spi: The spi device associated with the Sigma Delta device. 55af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen * @trig: The IIO trigger associated with the Sigma Delta device. 56af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen * 57af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen * Most of the fields are private to the sigma delta library code and should not 58af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen * be accessed by individual drivers. 59af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen */ 60af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausenstruct ad_sigma_delta { 61af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen struct spi_device *spi; 62af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen struct iio_trigger *trig; 63af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen 64af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen/* private: */ 65af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen struct completion completion; 66af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen bool irq_dis; 67af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen 68af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen bool bus_locked; 69af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen 70af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen uint8_t comm; 71af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen 72af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen const struct ad_sigma_delta_info *info; 73af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen 74af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen /* 75af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen * DMA (thus cache coherency maintenance) requires the 76af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen * transfer buffers to live in their own cache lines. 77af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen */ 78af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen uint8_t data[4] ____cacheline_aligned; 79af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen}; 80af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen 81af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausenstatic inline int ad_sigma_delta_set_channel(struct ad_sigma_delta *sd, 82af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen unsigned int channel) 83af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen{ 84af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen if (sd->info->set_channel) 85af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen return sd->info->set_channel(sd, channel); 86af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen 87af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen return 0; 88af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen} 89af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen 90af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausenstatic inline int ad_sigma_delta_set_mode(struct ad_sigma_delta *sd, 91af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen unsigned int mode) 92af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen{ 93af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen if (sd->info->set_mode) 94af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen return sd->info->set_mode(sd, mode); 95af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen 96af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen return 0; 97af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen} 98af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen 99af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausenstatic inline int ad_sigma_delta_postprocess_sample(struct ad_sigma_delta *sd, 100af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen unsigned int raw_sample) 101af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen{ 102af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen if (sd->info->postprocess_sample) 103af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen return sd->info->postprocess_sample(sd, raw_sample); 104af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen 105af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen return 0; 106af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen} 107af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen 108af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausenvoid ad_sd_set_comm(struct ad_sigma_delta *sigma_delta, uint8_t comm); 109af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausenint ad_sd_write_reg(struct ad_sigma_delta *sigma_delta, unsigned int reg, 110af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen unsigned int size, unsigned int val); 111af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausenint ad_sd_read_reg(struct ad_sigma_delta *sigma_delta, unsigned int reg, 112af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen unsigned int size, unsigned int *val); 113af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen 114af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausenint ad_sigma_delta_single_conversion(struct iio_dev *indio_dev, 115af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen const struct iio_chan_spec *chan, int *val); 116af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausenint ad_sd_calibrate_all(struct ad_sigma_delta *sigma_delta, 117af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen const struct ad_sd_calib_data *cd, unsigned int n); 118af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausenint ad_sd_init(struct ad_sigma_delta *sigma_delta, struct iio_dev *indio_dev, 119af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen struct spi_device *spi, const struct ad_sigma_delta_info *info); 120af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen 121af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausenint ad_sd_setup_buffer_and_trigger(struct iio_dev *indio_dev); 122af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausenvoid ad_sd_cleanup_buffer_and_trigger(struct iio_dev *indio_dev); 123af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen 124af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausenint ad_sd_validate_trigger(struct iio_dev *indio_dev, struct iio_trigger *trig); 125af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen 126af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen#define __AD_SD_CHANNEL(_si, _channel1, _channel2, _address, _bits, \ 127af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen _storagebits, _shift, _extend_name, _type) \ 128af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen { \ 129af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen .type = (_type), \ 130af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen .differential = (_channel2 == -1 ? 0 : 1), \ 131af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen .indexed = 1, \ 132af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen .channel = (_channel1), \ 133af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen .channel2 = (_channel2), \ 134af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen .address = (_address), \ 135af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen .extend_name = (_extend_name), \ 136ea0c68006321eea78a3702a9d68ff9395e06da38Jonathan Cameron .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \ 137ea0c68006321eea78a3702a9d68ff9395e06da38Jonathan Cameron BIT(IIO_CHAN_INFO_OFFSET), \ 138ea0c68006321eea78a3702a9d68ff9395e06da38Jonathan Cameron .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \ 139af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen .scan_index = (_si), \ 140af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen .scan_type = { \ 141af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen .sign = 'u', \ 142af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen .realbits = (_bits), \ 143af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen .storagebits = (_storagebits), \ 144af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen .shift = (_shift), \ 145af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen .endianness = IIO_BE, \ 146af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen }, \ 147af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen } 148af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen 149af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen#define AD_SD_DIFF_CHANNEL(_si, _channel1, _channel2, _address, _bits, \ 150af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen _storagebits, _shift) \ 151af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen __AD_SD_CHANNEL(_si, _channel1, _channel2, _address, _bits, \ 152af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen _storagebits, _shift, NULL, IIO_VOLTAGE) 153af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen 154af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen#define AD_SD_SHORTED_CHANNEL(_si, _channel, _address, _bits, \ 155af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen _storagebits, _shift) \ 156af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen __AD_SD_CHANNEL(_si, _channel, _channel, _address, _bits, \ 157af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen _storagebits, _shift, "shorted", IIO_VOLTAGE) 158af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen 159af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen#define AD_SD_CHANNEL(_si, _channel, _address, _bits, \ 160af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen _storagebits, _shift) \ 161af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen __AD_SD_CHANNEL(_si, _channel, -1, _address, _bits, \ 162af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen _storagebits, _shift, NULL, IIO_VOLTAGE) 163af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen 164af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen#define AD_SD_TEMP_CHANNEL(_si, _address, _bits, _storagebits, _shift) \ 165af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen __AD_SD_CHANNEL(_si, 0, -1, _address, _bits, \ 166af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen _storagebits, _shift, NULL, IIO_TEMP) 167af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen 168af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen#define AD_SD_SUPPLY_CHANNEL(_si, _channel, _address, _bits, _storagebits, \ 169af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen _shift) \ 170af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen __AD_SD_CHANNEL(_si, _channel, -1, _address, _bits, \ 171af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen _storagebits, _shift, "supply", IIO_VOLTAGE) 172af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen 173af3008485ea0372fb9ce1f69f3768617d39eb4e6Lars-Peter Clausen#endif 174