Skip to content

Commit

Permalink
iio: adc: xilinx-xadc: Correct temperature offset/scale for UltraScale
Browse files Browse the repository at this point in the history
commit e2bd8c2 upstream.

The driver was previously using offset and scale values for the
temperature sensor readings which were only valid for 7-series devices.
Add per-device-type values for offset and scale and set them appropriately
for each device type.

Note that the values used for the UltraScale family are for UltraScale+
(i.e. the SYSMONE4 primitive) using the internal reference, as that seems
to be the most common configuration and the device tree values Xilinx's
device tree generator produces don't seem to give us anything to tell us
which configuration is used. However, the differences within the UltraScale
family seem fairly minor and it's closer than using the 7-series values
instead in any case.

Fixes: c2b7720 ("iio: xilinx-xadc: Add basic support for Ultrascale System Monitor")
Signed-off-by: Robert Hancock <robert.hancock@calian.com>
Acked-by: O'Griofa, Conall <conall.ogriofa@amd.com>
Tested-by: O'Griofa, Conall <conall.ogriofa@amd.com>
Link: https://lore.kernel.org/r/20230915001019.2862964-3-robert.hancock@calian.com
Cc: <Stable@vger.kernel.org>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
robhancocksed authored and gregkh committed Nov 2, 2023
1 parent f763aa2 commit 5f6dc4a
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 3 deletions.
17 changes: 14 additions & 3 deletions drivers/iio/adc/xilinx-xadc-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,9 @@ static const struct xadc_ops xadc_zynq_ops = {
.interrupt_handler = xadc_zynq_interrupt_handler,
.update_alarm = xadc_zynq_update_alarm,
.type = XADC_TYPE_S7,
/* Temp in C = (val * 503.975) / 2**bits - 273.15 */
.temp_scale = 503975,
.temp_offset = 273150,
};

static const unsigned int xadc_axi_reg_offsets[] = {
Expand Down Expand Up @@ -566,6 +569,9 @@ static const struct xadc_ops xadc_7s_axi_ops = {
.interrupt_handler = xadc_axi_interrupt_handler,
.flags = XADC_FLAGS_BUFFERED | XADC_FLAGS_IRQ_OPTIONAL,
.type = XADC_TYPE_S7,
/* Temp in C = (val * 503.975) / 2**bits - 273.15 */
.temp_scale = 503975,
.temp_offset = 273150,
};

static const struct xadc_ops xadc_us_axi_ops = {
Expand All @@ -577,6 +583,12 @@ static const struct xadc_ops xadc_us_axi_ops = {
.interrupt_handler = xadc_axi_interrupt_handler,
.flags = XADC_FLAGS_BUFFERED | XADC_FLAGS_IRQ_OPTIONAL,
.type = XADC_TYPE_US,
/**
* Values below are for UltraScale+ (SYSMONE4) using internal reference.
* See https://docs.xilinx.com/v/u/en-US/ug580-ultrascale-sysmon
*/
.temp_scale = 509314,
.temp_offset = 280231,
};

static int _xadc_update_adc_reg(struct xadc *xadc, unsigned int reg,
Expand Down Expand Up @@ -945,16 +957,15 @@ static int xadc_read_raw(struct iio_dev *indio_dev,
*val2 = bits;
return IIO_VAL_FRACTIONAL_LOG2;
case IIO_TEMP:
/* Temp in C = (val * 503.975) / 2**bits - 273.15 */
*val = 503975;
*val = xadc->ops->temp_scale;
*val2 = bits;
return IIO_VAL_FRACTIONAL_LOG2;
default:
return -EINVAL;
}
case IIO_CHAN_INFO_OFFSET:
/* Only the temperature channel has an offset */
*val = -((273150 << bits) / 503975);
*val = -((xadc->ops->temp_offset << bits) / xadc->ops->temp_scale);
return IIO_VAL_INT;
case IIO_CHAN_INFO_SAMP_FREQ:
ret = xadc_read_samplerate(xadc);
Expand Down
2 changes: 2 additions & 0 deletions drivers/iio/adc/xilinx-xadc.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ struct xadc_ops {

unsigned int flags;
enum xadc_type type;
int temp_scale;
int temp_offset;
};

static inline int _xadc_read_adc_reg(struct xadc *xadc, unsigned int reg,
Expand Down

0 comments on commit 5f6dc4a

Please sign in to comment.