mirror of
https://github.com/torvalds/linux.git
synced 2024-10-30 16:51:45 +00:00
IIO driver fixes for 4.17-rc8
Here are some old IIO driver fixes that were sitting in my tree for a few weeks. Sorry about not getting them to you sooner. They fix a number of small IIO driver issues that have been reported. All of these have been in linux-next for a while with no reported problems. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- iG0EABECAC0WIQT0tgzFv3jCIUoxPcsxR9QN2y37KQUCWxKN4g8cZ3JlZ0Brcm9h aC5jb20ACgkQMUfUDdst+ymkogCfbe2/iQJcT8kXD0s/73A/KqkKPksAn0NbVWyh HEroVoD7yDcdm2A+t36A =OWdB -----END PGP SIGNATURE----- Merge tag 'staging-4.17-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging Pull IIO driver fixes from Greg KH: "Here are some old IIO driver fixes that were sitting in my tree for a few weeks. Sorry about not getting them to you sooner. They fix a number of small IIO driver issues that have been reported. All of these have been in linux-next for a while with no reported problems" * tag 'staging-4.17-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: iio: adc: select buffer for at91-sama5d2_adc iio: hid-sensor-trigger: Fix sometimes not powering up the sensor after resume iio: adc: at91-sama5d2_adc: fix channel configuration for differential channels iio:kfifo_buf: check for uint overflow iio:buffer: make length types match kfifo types iio: adc: stm32-dfsdm: fix sample rate for div2 spi clock iio: adc: stm32-dfsdm: fix successive oversampling settings iio: ad7793: implement IIO_CHAN_INFO_SAMP_FREQ
This commit is contained in:
commit
34a8e640d1
@ -158,6 +158,7 @@ config AT91_SAMA5D2_ADC
|
||||
depends on ARCH_AT91 || COMPILE_TEST
|
||||
depends on HAS_IOMEM
|
||||
depends on HAS_DMA
|
||||
select IIO_BUFFER
|
||||
select IIO_TRIGGERED_BUFFER
|
||||
help
|
||||
Say yes here to build support for Atmel SAMA5D2 ADC which is
|
||||
|
@ -348,55 +348,6 @@ static const u16 ad7793_sample_freq_avail[16] = {0, 470, 242, 123, 62, 50, 39,
|
||||
static const u16 ad7797_sample_freq_avail[16] = {0, 0, 0, 123, 62, 50, 0,
|
||||
33, 0, 17, 16, 12, 10, 8, 6, 4};
|
||||
|
||||
static ssize_t ad7793_read_frequency(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
||||
struct ad7793_state *st = iio_priv(indio_dev);
|
||||
|
||||
return sprintf(buf, "%d\n",
|
||||
st->chip_info->sample_freq_avail[AD7793_MODE_RATE(st->mode)]);
|
||||
}
|
||||
|
||||
static ssize_t ad7793_write_frequency(struct device *dev,
|
||||
struct device_attribute *attr,
|
||||
const char *buf,
|
||||
size_t len)
|
||||
{
|
||||
struct iio_dev *indio_dev = dev_to_iio_dev(dev);
|
||||
struct ad7793_state *st = iio_priv(indio_dev);
|
||||
long lval;
|
||||
int i, ret;
|
||||
|
||||
ret = kstrtol(buf, 10, &lval);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (lval == 0)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
if (lval == st->chip_info->sample_freq_avail[i])
|
||||
break;
|
||||
if (i == 16)
|
||||
return -EINVAL;
|
||||
|
||||
ret = iio_device_claim_direct_mode(indio_dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
st->mode &= ~AD7793_MODE_RATE(-1);
|
||||
st->mode |= AD7793_MODE_RATE(i);
|
||||
ad_sd_write_reg(&st->sd, AD7793_REG_MODE, sizeof(st->mode), st->mode);
|
||||
iio_device_release_direct_mode(indio_dev);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static IIO_DEV_ATTR_SAMP_FREQ(S_IWUSR | S_IRUGO,
|
||||
ad7793_read_frequency,
|
||||
ad7793_write_frequency);
|
||||
|
||||
static IIO_CONST_ATTR_SAMP_FREQ_AVAIL(
|
||||
"470 242 123 62 50 39 33 19 17 16 12 10 8 6 4");
|
||||
|
||||
@ -424,7 +375,6 @@ static IIO_DEVICE_ATTR_NAMED(in_m_in_scale_available,
|
||||
ad7793_show_scale_available, NULL, 0);
|
||||
|
||||
static struct attribute *ad7793_attributes[] = {
|
||||
&iio_dev_attr_sampling_frequency.dev_attr.attr,
|
||||
&iio_const_attr_sampling_frequency_available.dev_attr.attr,
|
||||
&iio_dev_attr_in_m_in_scale_available.dev_attr.attr,
|
||||
NULL
|
||||
@ -435,7 +385,6 @@ static const struct attribute_group ad7793_attribute_group = {
|
||||
};
|
||||
|
||||
static struct attribute *ad7797_attributes[] = {
|
||||
&iio_dev_attr_sampling_frequency.dev_attr.attr,
|
||||
&iio_const_attr_sampling_frequency_available_ad7797.dev_attr.attr,
|
||||
NULL
|
||||
};
|
||||
@ -505,6 +454,10 @@ static int ad7793_read_raw(struct iio_dev *indio_dev,
|
||||
*val -= offset;
|
||||
}
|
||||
return IIO_VAL_INT;
|
||||
case IIO_CHAN_INFO_SAMP_FREQ:
|
||||
*val = st->chip_info
|
||||
->sample_freq_avail[AD7793_MODE_RATE(st->mode)];
|
||||
return IIO_VAL_INT;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
@ -542,6 +495,26 @@ static int ad7793_write_raw(struct iio_dev *indio_dev,
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case IIO_CHAN_INFO_SAMP_FREQ:
|
||||
if (!val) {
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
for (i = 0; i < 16; i++)
|
||||
if (val == st->chip_info->sample_freq_avail[i])
|
||||
break;
|
||||
|
||||
if (i == 16) {
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
st->mode &= ~AD7793_MODE_RATE(-1);
|
||||
st->mode |= AD7793_MODE_RATE(i);
|
||||
ad_sd_write_reg(&st->sd, AD7793_REG_MODE, sizeof(st->mode),
|
||||
st->mode);
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
@ -333,6 +333,27 @@ static const struct iio_chan_spec at91_adc_channels[] = {
|
||||
+ AT91_SAMA5D2_DIFF_CHAN_CNT + 1),
|
||||
};
|
||||
|
||||
static int at91_adc_chan_xlate(struct iio_dev *indio_dev, int chan)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < indio_dev->num_channels; i++) {
|
||||
if (indio_dev->channels[i].scan_index == chan)
|
||||
return i;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
static inline struct iio_chan_spec const *
|
||||
at91_adc_chan_get(struct iio_dev *indio_dev, int chan)
|
||||
{
|
||||
int index = at91_adc_chan_xlate(indio_dev, chan);
|
||||
|
||||
if (index < 0)
|
||||
return NULL;
|
||||
return indio_dev->channels + index;
|
||||
}
|
||||
|
||||
static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state)
|
||||
{
|
||||
struct iio_dev *indio = iio_trigger_get_drvdata(trig);
|
||||
@ -350,8 +371,10 @@ static int at91_adc_configure_trigger(struct iio_trigger *trig, bool state)
|
||||
at91_adc_writel(st, AT91_SAMA5D2_TRGR, status);
|
||||
|
||||
for_each_set_bit(bit, indio->active_scan_mask, indio->num_channels) {
|
||||
struct iio_chan_spec const *chan = indio->channels + bit;
|
||||
struct iio_chan_spec const *chan = at91_adc_chan_get(indio, bit);
|
||||
|
||||
if (!chan)
|
||||
continue;
|
||||
if (state) {
|
||||
at91_adc_writel(st, AT91_SAMA5D2_CHER,
|
||||
BIT(chan->channel));
|
||||
@ -448,7 +471,11 @@ static int at91_adc_dma_start(struct iio_dev *indio_dev)
|
||||
|
||||
for_each_set_bit(bit, indio_dev->active_scan_mask,
|
||||
indio_dev->num_channels) {
|
||||
struct iio_chan_spec const *chan = indio_dev->channels + bit;
|
||||
struct iio_chan_spec const *chan =
|
||||
at91_adc_chan_get(indio_dev, bit);
|
||||
|
||||
if (!chan)
|
||||
continue;
|
||||
|
||||
st->dma_st.rx_buf_sz += chan->scan_type.storagebits / 8;
|
||||
}
|
||||
@ -526,8 +553,11 @@ static int at91_adc_buffer_predisable(struct iio_dev *indio_dev)
|
||||
*/
|
||||
for_each_set_bit(bit, indio_dev->active_scan_mask,
|
||||
indio_dev->num_channels) {
|
||||
struct iio_chan_spec const *chan = indio_dev->channels + bit;
|
||||
struct iio_chan_spec const *chan =
|
||||
at91_adc_chan_get(indio_dev, bit);
|
||||
|
||||
if (!chan)
|
||||
continue;
|
||||
if (st->dma_st.dma_chan)
|
||||
at91_adc_readl(st, chan->address);
|
||||
}
|
||||
@ -587,8 +617,11 @@ static void at91_adc_trigger_handler_nodma(struct iio_dev *indio_dev,
|
||||
|
||||
for_each_set_bit(bit, indio_dev->active_scan_mask,
|
||||
indio_dev->num_channels) {
|
||||
struct iio_chan_spec const *chan = indio_dev->channels + bit;
|
||||
struct iio_chan_spec const *chan =
|
||||
at91_adc_chan_get(indio_dev, bit);
|
||||
|
||||
if (!chan)
|
||||
continue;
|
||||
st->buffer[i] = at91_adc_readl(st, chan->address);
|
||||
i++;
|
||||
}
|
||||
|
@ -144,6 +144,7 @@ static int stm32_dfsdm_set_osrs(struct stm32_dfsdm_filter *fl,
|
||||
* Leave as soon as if exact resolution if reached.
|
||||
* Otherwise the higher resolution below 32 bits is kept.
|
||||
*/
|
||||
fl->res = 0;
|
||||
for (fosr = 1; fosr <= DFSDM_MAX_FL_OVERSAMPLING; fosr++) {
|
||||
for (iosr = 1; iosr <= DFSDM_MAX_INT_OVERSAMPLING; iosr++) {
|
||||
if (fast)
|
||||
@ -193,7 +194,7 @@ static int stm32_dfsdm_set_osrs(struct stm32_dfsdm_filter *fl,
|
||||
}
|
||||
}
|
||||
|
||||
if (!fl->fosr)
|
||||
if (!fl->res)
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
@ -770,7 +771,7 @@ static int stm32_dfsdm_write_raw(struct iio_dev *indio_dev,
|
||||
struct stm32_dfsdm_adc *adc = iio_priv(indio_dev);
|
||||
struct stm32_dfsdm_filter *fl = &adc->dfsdm->fl_list[adc->fl_id];
|
||||
struct stm32_dfsdm_channel *ch = &adc->dfsdm->ch_list[chan->channel];
|
||||
unsigned int spi_freq = adc->spi_freq;
|
||||
unsigned int spi_freq;
|
||||
int ret = -EINVAL;
|
||||
|
||||
switch (mask) {
|
||||
@ -784,8 +785,18 @@ static int stm32_dfsdm_write_raw(struct iio_dev *indio_dev,
|
||||
case IIO_CHAN_INFO_SAMP_FREQ:
|
||||
if (!val)
|
||||
return -EINVAL;
|
||||
if (ch->src != DFSDM_CHANNEL_SPI_CLOCK_EXTERNAL)
|
||||
|
||||
switch (ch->src) {
|
||||
case DFSDM_CHANNEL_SPI_CLOCK_INTERNAL:
|
||||
spi_freq = adc->dfsdm->spi_master_freq;
|
||||
break;
|
||||
case DFSDM_CHANNEL_SPI_CLOCK_INTERNAL_DIV2_FALLING:
|
||||
case DFSDM_CHANNEL_SPI_CLOCK_INTERNAL_DIV2_RISING:
|
||||
spi_freq = adc->dfsdm->spi_master_freq / 2;
|
||||
break;
|
||||
default:
|
||||
spi_freq = adc->spi_freq;
|
||||
}
|
||||
|
||||
if (spi_freq % val)
|
||||
dev_warn(&indio_dev->dev,
|
||||
|
@ -587,7 +587,7 @@ EXPORT_SYMBOL_GPL(iio_dma_buffer_set_bytes_per_datum);
|
||||
* Should be used as the set_length callback for iio_buffer_access_ops
|
||||
* struct for DMA buffers.
|
||||
*/
|
||||
int iio_dma_buffer_set_length(struct iio_buffer *buffer, int length)
|
||||
int iio_dma_buffer_set_length(struct iio_buffer *buffer, unsigned int length)
|
||||
{
|
||||
/* Avoid an invalid state */
|
||||
if (length < 2)
|
||||
|
@ -22,11 +22,18 @@ struct iio_kfifo {
|
||||
#define iio_to_kfifo(r) container_of(r, struct iio_kfifo, buffer)
|
||||
|
||||
static inline int __iio_allocate_kfifo(struct iio_kfifo *buf,
|
||||
int bytes_per_datum, int length)
|
||||
size_t bytes_per_datum, unsigned int length)
|
||||
{
|
||||
if ((length == 0) || (bytes_per_datum == 0))
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* Make sure we don't overflow an unsigned int after kfifo rounds up to
|
||||
* the next power of 2.
|
||||
*/
|
||||
if (roundup_pow_of_two(length) > UINT_MAX / bytes_per_datum)
|
||||
return -EINVAL;
|
||||
|
||||
return __kfifo_alloc((struct __kfifo *)&buf->kf, length,
|
||||
bytes_per_datum, GFP_KERNEL);
|
||||
}
|
||||
@ -67,7 +74,7 @@ static int iio_set_bytes_per_datum_kfifo(struct iio_buffer *r, size_t bpd)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iio_set_length_kfifo(struct iio_buffer *r, int length)
|
||||
static int iio_set_length_kfifo(struct iio_buffer *r, unsigned int length)
|
||||
{
|
||||
/* Avoid an invalid state */
|
||||
if (length < 2)
|
||||
|
@ -178,14 +178,14 @@ int hid_sensor_power_state(struct hid_sensor_common *st, bool state)
|
||||
#ifdef CONFIG_PM
|
||||
int ret;
|
||||
|
||||
atomic_set(&st->user_requested_state, state);
|
||||
|
||||
if (atomic_add_unless(&st->runtime_pm_enable, 1, 1))
|
||||
pm_runtime_enable(&st->pdev->dev);
|
||||
|
||||
if (state)
|
||||
if (state) {
|
||||
atomic_inc(&st->user_requested_state);
|
||||
ret = pm_runtime_get_sync(&st->pdev->dev);
|
||||
else {
|
||||
} else {
|
||||
atomic_dec(&st->user_requested_state);
|
||||
pm_runtime_mark_last_busy(&st->pdev->dev);
|
||||
pm_runtime_use_autosuspend(&st->pdev->dev);
|
||||
ret = pm_runtime_put_autosuspend(&st->pdev->dev);
|
||||
|
@ -53,7 +53,7 @@ struct iio_buffer_access_funcs {
|
||||
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, int length);
|
||||
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);
|
||||
@ -72,10 +72,10 @@ struct iio_buffer_access_funcs {
|
||||
*/
|
||||
struct iio_buffer {
|
||||
/** @length: Number of datums in buffer. */
|
||||
int length;
|
||||
unsigned int length;
|
||||
|
||||
/** @bytes_per_datum: Size of individual datum including timestamp. */
|
||||
int bytes_per_datum;
|
||||
size_t bytes_per_datum;
|
||||
|
||||
/**
|
||||
* @access: Buffer access functions associated with the
|
||||
|
Loading…
Reference in New Issue
Block a user