Skip to content

Commit c7fe871

Browse files
ukleineknunojsa
authored andcommitted
iio: adc: ad7124: Implement temperature measurement
If the maximal count of channels the driver supports isn't fully utilized, add an attribute providing the internal temperature. Signed-off-by: Uwe Kleine-König <[email protected]> Link: https://patch.msgid.link/433211af8ac3f02dee58586ecb51d2e98246a095.1733504533.git.u.kleine-koenig@baylibre.com Signed-off-by: Jonathan Cameron <[email protected]> Origin: next-20241216~37^2~16, commit:6eaf3f60ab45a5740ed4e1a7d41c4f0c10f6ac3c
1 parent a64317b commit c7fe871

File tree

1 file changed

+91
-23
lines changed

1 file changed

+91
-23
lines changed

drivers/iio/adc/ad7124.c

Lines changed: 91 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@
9494
#define AD7124_MAX_CONFIGS 8
9595
#define AD7124_MAX_CHANNELS 16
9696

97+
/* AD7124 input sources */
98+
#define AD7124_INPUT_TEMPSENSOR 16
99+
#define AD7124_INPUT_AVSS 17
100+
97101
enum ad7124_ids {
98102
ID_AD7124_4,
99103
ID_AD7124_8,
@@ -596,26 +600,59 @@ static int ad7124_read_raw(struct iio_dev *indio_dev,
596600

597601
return IIO_VAL_INT;
598602
case IIO_CHAN_INFO_SCALE:
599-
mutex_lock(&st->cfgs_lock);
603+
switch (chan->type) {
604+
case IIO_VOLTAGE:
605+
mutex_lock(&st->cfgs_lock);
600606

601-
idx = st->channels[chan->address].cfg.pga_bits;
602-
*val = st->channels[chan->address].cfg.vref_mv;
603-
if (st->channels[chan->address].cfg.bipolar)
604-
*val2 = chan->scan_type.realbits - 1 + idx;
605-
else
606-
*val2 = chan->scan_type.realbits + idx;
607+
idx = st->channels[chan->address].cfg.pga_bits;
608+
*val = st->channels[chan->address].cfg.vref_mv;
609+
if (st->channels[chan->address].cfg.bipolar)
610+
*val2 = chan->scan_type.realbits - 1 + idx;
611+
else
612+
*val2 = chan->scan_type.realbits + idx;
613+
614+
mutex_unlock(&st->cfgs_lock);
615+
return IIO_VAL_FRACTIONAL_LOG2;
616+
617+
case IIO_TEMP:
618+
/*
619+
* According to the data sheet
620+
* Temperature (°C)
621+
* = ((Conversion − 0x800000)/13584) − 272.5
622+
* = (Conversion − 0x800000 - 13584 * 272.5) / 13584
623+
* = (Conversion − 12090248) / 13584
624+
* So scale with 1000/13584 to yield °mC. Reduce by 8 to
625+
* 125/1698.
626+
*/
627+
*val = 125;
628+
*val2 = 1698;
629+
return IIO_VAL_FRACTIONAL;
630+
631+
default:
632+
return -EINVAL;
633+
}
607634

608-
mutex_unlock(&st->cfgs_lock);
609-
return IIO_VAL_FRACTIONAL_LOG2;
610635
case IIO_CHAN_INFO_OFFSET:
611-
mutex_lock(&st->cfgs_lock);
612-
if (st->channels[chan->address].cfg.bipolar)
613-
*val = -(1 << (chan->scan_type.realbits - 1));
614-
else
615-
*val = 0;
636+
switch (chan->type) {
637+
case IIO_VOLTAGE:
638+
mutex_lock(&st->cfgs_lock);
639+
if (st->channels[chan->address].cfg.bipolar)
640+
*val = -(1 << (chan->scan_type.realbits - 1));
641+
else
642+
*val = 0;
643+
644+
mutex_unlock(&st->cfgs_lock);
645+
return IIO_VAL_INT;
646+
647+
case IIO_TEMP:
648+
/* see calculation above */
649+
*val = -12090248;
650+
return IIO_VAL_INT;
651+
652+
default:
653+
return -EINVAL;
654+
}
616655

617-
mutex_unlock(&st->cfgs_lock);
618-
return IIO_VAL_INT;
619656
case IIO_CHAN_INFO_SAMP_FREQ:
620657
mutex_lock(&st->cfgs_lock);
621658
*val = st->channels[chan->address].cfg.odr;
@@ -837,13 +874,10 @@ static int ad7124_of_parse_channel_config(struct iio_dev *indio_dev,
837874
struct device_node *child;
838875
struct iio_chan_spec *chan;
839876
unsigned int ain[2], channel = 0, tmp;
877+
unsigned int num_channels;
840878
int ret;
841879

842-
st->num_channels = of_get_available_child_count(np);
843-
if (!st->num_channels) {
844-
dev_err(indio_dev->dev.parent, "no channel children\n");
845-
return -ENODEV;
846-
}
880+
num_channels = of_get_available_child_count(np);
847881

848882
/*
849883
* The driver assigns each logical channel defined in the device tree
@@ -852,9 +886,12 @@ static int ad7124_of_parse_channel_config(struct iio_dev *indio_dev,
852886
* CHANNEL_15) as an additional channel register. The driver could be
853887
* improved to lift this limitation.
854888
*/
855-
if (st->num_channels > AD7124_MAX_CHANNELS)
889+
if (num_channels > AD7124_MAX_CHANNELS)
856890
return dev_err_probe(indio_dev->dev.parent, -EINVAL, "Too many channels defined\n");
857891

892+
/* Add one for temperature */
893+
st->num_channels = min(num_channels + 1, (unsigned int)AD7124_MAX_CHANNELS);
894+
858895
chan = devm_kcalloc(indio_dev->dev.parent, st->num_channels,
859896
sizeof(*chan), GFP_KERNEL);
860897
if (!chan)
@@ -874,7 +911,7 @@ static int ad7124_of_parse_channel_config(struct iio_dev *indio_dev,
874911
if (ret)
875912
goto err;
876913

877-
if (channel >= indio_dev->num_channels) {
914+
if (channel >= num_channels) {
878915
dev_err(indio_dev->dev.parent,
879916
"Channel index >= number of channels\n");
880917
ret = -EINVAL;
@@ -914,6 +951,37 @@ static int ad7124_of_parse_channel_config(struct iio_dev *indio_dev,
914951
chan[channel].channel2 = ain[1];
915952
}
916953

954+
if (num_channels < AD7124_MAX_CHANNELS) {
955+
st->channels[num_channels] = (struct ad7124_channel) {
956+
.nr = num_channels,
957+
.ain = AD7124_CHANNEL_AINP(AD7124_INPUT_TEMPSENSOR) |
958+
AD7124_CHANNEL_AINM(AD7124_INPUT_AVSS),
959+
.cfg = {
960+
.bipolar = true,
961+
},
962+
};
963+
964+
chan[num_channels] = (struct iio_chan_spec) {
965+
.type = IIO_TEMP,
966+
.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
967+
BIT(IIO_CHAN_INFO_SCALE) | BIT(IIO_CHAN_INFO_OFFSET) |
968+
BIT(IIO_CHAN_INFO_SAMP_FREQ),
969+
.scan_type = {
970+
/*
971+
* You might find it strange that a bipolar
972+
* measurement yields an unsigned value, but
973+
* this matches the device's manual.
974+
*/
975+
.sign = 'u',
976+
.realbits = 24,
977+
.storagebits = 32,
978+
.endianness = IIO_BE,
979+
},
980+
.address = num_channels,
981+
.scan_index = num_channels,
982+
};
983+
}
984+
917985
return 0;
918986
err:
919987
of_node_put(child);

0 commit comments

Comments
 (0)