Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

iio: adc: mcp3911: fix device dependent mappings for conversion result registers

The conversion result registers differs between devices. Make sure the
mapping is correct by using a device dependent .get_raw() callback function.

Fixes: 732ad34260d3 ("iio: adc: mcp3911: add support for the whole MCP39xx family")
Co-developed-by: Lukas Rauber <lukas.rauber@janitza.de>
Signed-off-by: Lukas Rauber <lukas.rauber@janitza.de>
Signed-off-by: Marcus Folkesson <marcus.folkesson@gmail.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Link: https://patch.msgid.link/20250428-mcp3911-fixes-v2-1-406e39330c3d@gmail.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Marcus Folkesson and committed by
Jonathan Cameron
f62c49d8 15c82338

+34 -5
+34 -5
drivers/iio/adc/mcp3911.c
··· 6 6 * Copyright (C) 2018 Kent Gustavsson <kent@minoris.se> 7 7 */ 8 8 #include <linux/bitfield.h> 9 - #include <linux/bits.h> 9 + #include <linux/bitops.h> 10 10 #include <linux/cleanup.h> 11 11 #include <linux/clk.h> 12 12 #include <linux/delay.h> ··· 79 79 #define MCP3910_CONFIG1_CLKEXT BIT(6) 80 80 #define MCP3910_CONFIG1_VREFEXT BIT(7) 81 81 82 + #define MCP3910_CHANNEL(ch) (MCP3911_REG_CHANNEL0 + (ch)) 83 + 82 84 #define MCP3910_REG_OFFCAL_CH0 0x0f 83 85 #define MCP3910_OFFCAL(ch) (MCP3910_REG_OFFCAL_CH0 + (ch) * 6) 84 86 ··· 112 110 int (*get_offset)(struct mcp3911 *adc, int channel, int *val); 113 111 int (*set_offset)(struct mcp3911 *adc, int channel, int val); 114 112 int (*set_scale)(struct mcp3911 *adc, int channel, u32 val); 113 + int (*get_raw)(struct mcp3911 *adc, int channel, int *val); 115 114 }; 116 115 117 116 struct mcp3911 { ··· 173 170 return mcp3911_write(adc, reg, val, len); 174 171 } 175 172 173 + static int mcp3911_read_s24(struct mcp3911 *const adc, u8 const reg, s32 *const val) 174 + { 175 + u32 uval; 176 + int const ret = mcp3911_read(adc, reg, &uval, 3); 177 + 178 + if (ret) 179 + return ret; 180 + 181 + *val = sign_extend32(uval, 23); 182 + return ret; 183 + } 184 + 176 185 static int mcp3910_enable_offset(struct mcp3911 *adc, bool enable) 177 186 { 178 187 unsigned int mask = MCP3910_CONFIG0_EN_OFFCAL; ··· 209 194 return adc->chip->enable_offset(adc, 1); 210 195 } 211 196 197 + static int mcp3910_get_raw(struct mcp3911 *adc, int channel, s32 *val) 198 + { 199 + return mcp3911_read_s24(adc, MCP3910_CHANNEL(channel), val); 200 + } 201 + 212 202 static int mcp3911_enable_offset(struct mcp3911 *adc, bool enable) 213 203 { 214 204 unsigned int mask = MCP3911_STATUSCOM_EN_OFFCAL; ··· 236 216 return ret; 237 217 238 218 return adc->chip->enable_offset(adc, 1); 219 + } 220 + 221 + static int mcp3911_get_raw(struct mcp3911 *adc, int channel, s32 *val) 222 + { 223 + return mcp3911_read_s24(adc, MCP3911_CHANNEL(channel), val); 239 224 } 240 225 241 226 static int mcp3910_get_osr(struct mcp3911 *adc, u32 *val) ··· 346 321 guard(mutex)(&adc->lock); 347 322 switch (mask) { 348 323 case IIO_CHAN_INFO_RAW: 349 - ret = mcp3911_read(adc, 350 - MCP3911_CHANNEL(channel->channel), val, 3); 324 + ret = adc->chip->get_raw(adc, channel->channel, val); 351 325 if (ret) 352 326 return ret; 353 - 354 - *val = sign_extend32(*val, 23); 355 327 return IIO_VAL_INT; 356 328 case IIO_CHAN_INFO_OFFSET: 357 329 ret = adc->chip->get_offset(adc, channel->channel, val); ··· 821 799 .get_offset = mcp3910_get_offset, 822 800 .set_offset = mcp3910_set_offset, 823 801 .set_scale = mcp3910_set_scale, 802 + .get_raw = mcp3910_get_raw, 824 803 }, 825 804 [MCP3911] = { 826 805 .channels = mcp3911_channels, ··· 833 810 .get_offset = mcp3911_get_offset, 834 811 .set_offset = mcp3911_set_offset, 835 812 .set_scale = mcp3911_set_scale, 813 + .get_raw = mcp3911_get_raw, 836 814 }, 837 815 [MCP3912] = { 838 816 .channels = mcp3912_channels, ··· 845 821 .get_offset = mcp3910_get_offset, 846 822 .set_offset = mcp3910_set_offset, 847 823 .set_scale = mcp3910_set_scale, 824 + .get_raw = mcp3910_get_raw, 848 825 }, 849 826 [MCP3913] = { 850 827 .channels = mcp3913_channels, ··· 857 832 .get_offset = mcp3910_get_offset, 858 833 .set_offset = mcp3910_set_offset, 859 834 .set_scale = mcp3910_set_scale, 835 + .get_raw = mcp3910_get_raw, 860 836 }, 861 837 [MCP3914] = { 862 838 .channels = mcp3914_channels, ··· 869 843 .get_offset = mcp3910_get_offset, 870 844 .set_offset = mcp3910_set_offset, 871 845 .set_scale = mcp3910_set_scale, 846 + .get_raw = mcp3910_get_raw, 872 847 }, 873 848 [MCP3918] = { 874 849 .channels = mcp3918_channels, ··· 881 854 .get_offset = mcp3910_get_offset, 882 855 .set_offset = mcp3910_set_offset, 883 856 .set_scale = mcp3910_set_scale, 857 + .get_raw = mcp3910_get_raw, 884 858 }, 885 859 [MCP3919] = { 886 860 .channels = mcp3919_channels, ··· 893 865 .get_offset = mcp3910_get_offset, 894 866 .set_offset = mcp3910_set_offset, 895 867 .set_scale = mcp3910_set_scale, 868 + .get_raw = mcp3910_get_raw, 896 869 }, 897 870 }; 898 871 static const struct of_device_id mcp3911_dt_ids[] = {