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: dac: adding support for Microchip MCP47FEB02

This is the iio driver for Microchip MCP47F(E/V)B(0/1/2)1,
MCP47F(E/V)B(0/1/2)2, MCP47F(E/V)B(0/1/2)4 and MCP47F(E/V)B(0/1/2)8 series
of buffered voltage output Digital-to-Analog Converters with nonvolatile or
volatile memory and an I2C Interface.

The families support up to 8 output channels.

The devices can be 8-bit, 10-bit and 12-bit.

Signed-off-by: Ariana Lazar <ariana.lazar@microchip.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Ariana Lazar and committed by
Jonathan Cameron
bf394cc8 4ba12d30

+1272
+1
MAINTAINERS
··· 15660 15660 L: linux-iio@vger.kernel.org 15661 15661 S: Supported 15662 15662 F: Documentation/devicetree/bindings/iio/dac/microchip,mcp47feb02.yaml 15663 + F: drivers/iio/dac/mcp47feb02.c 15663 15664 15664 15665 MCP4821 DAC DRIVER 15665 15666 M: Anshul Dalal <anshulusr@gmail.com>
+20
drivers/iio/dac/Kconfig
··· 524 524 To compile this driver as a module, choose M here: the module 525 525 will be called mcp4728. 526 526 527 + config MCP47FEB02 528 + tristate "MCP47F(E/V)B01/02/04/08/11/12/14/18/21/22/24/28 DAC driver" 529 + depends on I2C 530 + help 531 + Say yes here if you want to build the driver for the Microchip: 532 + - 8-bit DAC: 533 + MCP47FEB01, MCP47FEB02, MCP47FEB04, MCP47FEB08, 534 + MCP47FVB01, MCP47FVB02, MCP47FVB04, MCP47FVB08 535 + - 10-bit DAC: 536 + MCP47FEB11, MCP47FEB12, MCP47FEB14, MCP47FEB18, 537 + MCP47FVB11, MCP47FVB12, MCP47FVB14, MCP47FVB18 538 + - 12-bit DAC: 539 + MCP47FEB21, MCP47FEB22, MCP47FEB24, MCP47FEB28, 540 + MCP47FVB21, MCP47FVB22, MCP47FVB24, MCP47FVB28 541 + having 1 to 8 channels, 8/10/12-bit digital-to-analog converter 542 + (DAC) with I2C interface. 543 + 544 + To compile this driver as a module, choose M here: the module 545 + will be called mcp47feb02. 546 + 527 547 config MCP4821 528 548 tristate "MCP4801/02/11/12/21/22 DAC driver" 529 549 depends on SPI
+1
drivers/iio/dac/Makefile
··· 52 52 obj-$(CONFIG_MAX5821) += max5821.o 53 53 obj-$(CONFIG_MCP4725) += mcp4725.o 54 54 obj-$(CONFIG_MCP4728) += mcp4728.o 55 + obj-$(CONFIG_MCP47FEB02) += mcp47feb02.o 55 56 obj-$(CONFIG_MCP4821) += mcp4821.o 56 57 obj-$(CONFIG_MCP4922) += mcp4922.o 57 58 obj-$(CONFIG_STM32_DAC_CORE) += stm32-dac-core.o
+1250
drivers/iio/dac/mcp47feb02.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * IIO driver for MCP47FEB02 Multi-Channel DAC with I2C interface 4 + * 5 + * Copyright (C) 2025 Microchip Technology Inc. and its subsidiaries 6 + * 7 + * Author: Ariana Lazar <ariana.lazar@microchip.com> 8 + * 9 + * Datasheet links: 10 + * [MCP47FEBxx] https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/20005375A.pdf 11 + * [MCP47FVBxx] https://ww1.microchip.com/downloads/aemDocuments/documents/OTH/ProductDocuments/DataSheets/20005405A.pdf 12 + * [MCP47FxBx4/8] https://ww1.microchip.com/downloads/aemDocuments/documents/MSLD/ProductDocuments/DataSheets/MCP47FXBX48-Data-Sheet-DS200006368A.pdf 13 + */ 14 + #include <linux/array_size.h> 15 + #include <linux/bits.h> 16 + #include <linux/bitfield.h> 17 + #include <linux/delay.h> 18 + #include <linux/err.h> 19 + #include <linux/i2c.h> 20 + #include <linux/iio/iio.h> 21 + #include <linux/iio/sysfs.h> 22 + #include <linux/kstrtox.h> 23 + #include <linux/module.h> 24 + #include <linux/mod_devicetable.h> 25 + #include <linux/mutex.h> 26 + #include <linux/property.h> 27 + #include <linux/regmap.h> 28 + #include <linux/regulator/consumer.h> 29 + #include <linux/time64.h> 30 + #include <linux/types.h> 31 + #include <linux/units.h> 32 + 33 + /* Register addresses must be left shifted with 3 positions in order to append command mask */ 34 + #define MCP47FEB02_DAC0_REG_ADDR 0x00 35 + #define MCP47FEB02_VREF_REG_ADDR 0x40 36 + #define MCP47FEB02_POWER_DOWN_REG_ADDR 0x48 37 + #define MCP47FEB02_DAC_CTRL_MASK GENMASK(1, 0) 38 + 39 + #define MCP47FEB02_GAIN_CTRL_STATUS_REG_ADDR 0x50 40 + #define MCP47FEB02_GAIN_BIT_MASK BIT(0) 41 + #define MCP47FEB02_GAIN_BIT_STATUS_EEWA_MASK BIT(6) 42 + #define MCP47FEB02_GAIN_BITS_MASK GENMASK(15, 8) 43 + 44 + #define MCP47FEB02_WIPERLOCK_STATUS_REG_ADDR 0x58 45 + 46 + #define MCP47FEB02_NV_DAC0_REG_ADDR 0x80 47 + #define MCP47FEB02_NV_VREF_REG_ADDR 0xC0 48 + #define MCP47FEB02_NV_POWER_DOWN_REG_ADDR 0xC8 49 + #define MCP47FEB02_NV_GAIN_CTRL_I2C_SLAVE_REG_ADDR 0xD0 50 + #define MCP47FEB02_NV_I2C_SLAVE_ADDR_MASK GENMASK(7, 0) 51 + 52 + /* Voltage reference, Power-Down control register and DAC Wiperlock status register fields */ 53 + #define DAC_CTRL_MASK(ch) (GENMASK(1, 0) << (2 * (ch))) 54 + #define DAC_CTRL_VAL(ch, val) ((val) << (2 * (ch))) 55 + 56 + /* Gain Control and I2C Slave Address Reguster fields */ 57 + #define DAC_GAIN_MASK(ch) (BIT(0) << (8 + (ch))) 58 + #define DAC_GAIN_VAL(ch, val) ((val) << (8 + (ch))) 59 + 60 + #define REG_ADDR(reg) ((reg) << 3) 61 + #define NV_REG_ADDR(reg) ((NV_DAC_ADDR_OFFSET + (reg)) << 3) 62 + #define READFLAG_MASK GENMASK(2, 1) 63 + 64 + #define MCP47FEB02_MAX_CH 8 65 + #define MCP47FEB02_MAX_SCALES_CH 3 66 + #define MCP47FEB02_DAC_WIPER_UNLOCKED 0 67 + #define MCP47FEB02_NORMAL_OPERATION 0 68 + #define MCP47FEB02_INTERNAL_BAND_GAP_mV 2440 69 + #define NV_DAC_ADDR_OFFSET 0x10 70 + 71 + enum mcp47feb02_vref_mode { 72 + MCP47FEB02_VREF_VDD = 0, 73 + MCP47FEB02_INTERNAL_BAND_GAP = 1, 74 + MCP47FEB02_EXTERNAL_VREF_UNBUFFERED = 2, 75 + MCP47FEB02_EXTERNAL_VREF_BUFFERED = 3, 76 + }; 77 + 78 + enum mcp47feb02_scale { 79 + MCP47FEB02_SCALE_VDD = 0, 80 + MCP47FEB02_SCALE_GAIN_X1 = 1, 81 + MCP47FEB02_SCALE_GAIN_X2 = 2, 82 + }; 83 + 84 + enum mcp47feb02_gain_bit_mode { 85 + MCP47FEB02_GAIN_BIT_X1 = 0, 86 + MCP47FEB02_GAIN_BIT_X2 = 1, 87 + }; 88 + 89 + static const char * const mcp47feb02_powerdown_modes[] = { 90 + "1kohm_to_gnd", 91 + "100kohm_to_gnd", 92 + "open_circuit", 93 + }; 94 + 95 + /** 96 + * struct mcp47feb02_features - chip specific data 97 + * @name: device name 98 + * @phys_channels: number of hardware channels 99 + * @resolution: DAC resolution 100 + * @have_ext_vref1: does the hardware have an the second external voltage reference? 101 + * @have_eeprom: does the hardware have an internal eeprom? 102 + */ 103 + struct mcp47feb02_features { 104 + const char *name; 105 + unsigned int phys_channels; 106 + unsigned int resolution; 107 + bool have_ext_vref1; 108 + bool have_eeprom; 109 + }; 110 + 111 + static const struct mcp47feb02_features mcp47feb01_chip_features = { 112 + .name = "mcp47feb01", 113 + .phys_channels = 1, 114 + .resolution = 8, 115 + .have_ext_vref1 = false, 116 + .have_eeprom = true, 117 + }; 118 + 119 + static const struct mcp47feb02_features mcp47feb02_chip_features = { 120 + .name = "mcp47feb02", 121 + .phys_channels = 2, 122 + .resolution = 8, 123 + .have_ext_vref1 = false, 124 + .have_eeprom = true, 125 + }; 126 + 127 + static const struct mcp47feb02_features mcp47feb04_chip_features = { 128 + .name = "mcp47feb04", 129 + .phys_channels = 4, 130 + .resolution = 8, 131 + .have_ext_vref1 = true, 132 + .have_eeprom = true, 133 + }; 134 + 135 + static const struct mcp47feb02_features mcp47feb08_chip_features = { 136 + .name = "mcp47feb08", 137 + .phys_channels = 8, 138 + .resolution = 8, 139 + .have_ext_vref1 = true, 140 + .have_eeprom = true, 141 + }; 142 + 143 + static const struct mcp47feb02_features mcp47feb11_chip_features = { 144 + .name = "mcp47feb11", 145 + .phys_channels = 1, 146 + .resolution = 10, 147 + .have_ext_vref1 = false, 148 + .have_eeprom = true, 149 + }; 150 + 151 + static const struct mcp47feb02_features mcp47feb12_chip_features = { 152 + .name = "mcp47feb12", 153 + .phys_channels = 2, 154 + .resolution = 10, 155 + .have_ext_vref1 = false, 156 + .have_eeprom = true, 157 + }; 158 + 159 + static const struct mcp47feb02_features mcp47feb14_chip_features = { 160 + .name = "mcp47feb14", 161 + .phys_channels = 4, 162 + .resolution = 10, 163 + .have_ext_vref1 = true, 164 + .have_eeprom = true, 165 + }; 166 + 167 + static const struct mcp47feb02_features mcp47feb18_chip_features = { 168 + .name = "mcp47feb18", 169 + .phys_channels = 8, 170 + .resolution = 10, 171 + .have_ext_vref1 = true, 172 + .have_eeprom = true, 173 + }; 174 + 175 + static const struct mcp47feb02_features mcp47feb21_chip_features = { 176 + .name = "mcp47feb21", 177 + .phys_channels = 1, 178 + .resolution = 12, 179 + .have_ext_vref1 = false, 180 + .have_eeprom = true, 181 + }; 182 + 183 + static const struct mcp47feb02_features mcp47feb22_chip_features = { 184 + .name = "mcp47feb22", 185 + .phys_channels = 2, 186 + .resolution = 12, 187 + .have_ext_vref1 = false, 188 + .have_eeprom = true, 189 + }; 190 + 191 + static const struct mcp47feb02_features mcp47feb24_chip_features = { 192 + .name = "mcp47feb24", 193 + .phys_channels = 4, 194 + .resolution = 12, 195 + .have_ext_vref1 = true, 196 + .have_eeprom = true, 197 + }; 198 + 199 + static const struct mcp47feb02_features mcp47feb28_chip_features = { 200 + .name = "mcp47feb28", 201 + .phys_channels = 8, 202 + .resolution = 12, 203 + .have_ext_vref1 = true, 204 + .have_eeprom = true, 205 + }; 206 + 207 + static const struct mcp47feb02_features mcp47fvb01_chip_features = { 208 + .name = "mcp47fvb01", 209 + .phys_channels = 1, 210 + .resolution = 8, 211 + .have_ext_vref1 = false, 212 + .have_eeprom = false, 213 + }; 214 + 215 + static const struct mcp47feb02_features mcp47fvb02_chip_features = { 216 + .name = "mcp47fvb02", 217 + .phys_channels = 2, 218 + .resolution = 8, 219 + .have_ext_vref1 = false, 220 + .have_eeprom = false, 221 + }; 222 + 223 + static const struct mcp47feb02_features mcp47fvb04_chip_features = { 224 + .name = "mcp47fvb04", 225 + .phys_channels = 4, 226 + .resolution = 8, 227 + .have_ext_vref1 = true, 228 + .have_eeprom = false, 229 + }; 230 + 231 + static const struct mcp47feb02_features mcp47fvb08_chip_features = { 232 + .name = "mcp47fvb08", 233 + .phys_channels = 8, 234 + .resolution = 8, 235 + .have_ext_vref1 = true, 236 + .have_eeprom = false, 237 + }; 238 + 239 + static const struct mcp47feb02_features mcp47fvb11_chip_features = { 240 + .name = "mcp47fvb11", 241 + .phys_channels = 1, 242 + .resolution = 10, 243 + .have_ext_vref1 = false, 244 + .have_eeprom = false, 245 + }; 246 + 247 + static const struct mcp47feb02_features mcp47fvb12_chip_features = { 248 + .name = "mcp47fvb12", 249 + .phys_channels = 2, 250 + .resolution = 10, 251 + .have_ext_vref1 = false, 252 + .have_eeprom = false, 253 + }; 254 + 255 + static const struct mcp47feb02_features mcp47fvb14_chip_features = { 256 + .name = "mcp47fvb14", 257 + .phys_channels = 4, 258 + .resolution = 10, 259 + .have_ext_vref1 = true, 260 + .have_eeprom = false, 261 + }; 262 + 263 + static const struct mcp47feb02_features mcp47fvb18_chip_features = { 264 + .name = "mcp47fvb18", 265 + .phys_channels = 8, 266 + .resolution = 10, 267 + .have_ext_vref1 = true, 268 + .have_eeprom = false, 269 + }; 270 + 271 + static const struct mcp47feb02_features mcp47fvb21_chip_features = { 272 + .name = "mcp47fvb21", 273 + .phys_channels = 1, 274 + .resolution = 12, 275 + .have_ext_vref1 = false, 276 + .have_eeprom = false, 277 + }; 278 + 279 + static const struct mcp47feb02_features mcp47fvb22_chip_features = { 280 + .name = "mcp47fvb22", 281 + .phys_channels = 2, 282 + .resolution = 12, 283 + .have_ext_vref1 = false, 284 + .have_eeprom = false, 285 + }; 286 + 287 + static const struct mcp47feb02_features mcp47fvb24_chip_features = { 288 + .name = "mcp47fvb24", 289 + .phys_channels = 4, 290 + .resolution = 12, 291 + .have_ext_vref1 = true, 292 + .have_eeprom = false, 293 + }; 294 + 295 + static const struct mcp47feb02_features mcp47fvb28_chip_features = { 296 + .name = "mcp47fvb28", 297 + .phys_channels = 8, 298 + .resolution = 12, 299 + .have_ext_vref1 = true, 300 + .have_eeprom = false, 301 + }; 302 + 303 + /** 304 + * struct mcp47feb02_channel_data - channel configuration 305 + * @ref_mode: chosen voltage for reference 306 + * @use_2x_gain: output driver gain control 307 + * @powerdown: is false if the channel is in normal operation mode 308 + * @powerdown_mode: selected power-down mode 309 + * @dac_data: dac value 310 + */ 311 + struct mcp47feb02_channel_data { 312 + u8 ref_mode; 313 + bool use_2x_gain; 314 + bool powerdown; 315 + u8 powerdown_mode; 316 + u16 dac_data; 317 + }; 318 + 319 + /** 320 + * struct mcp47feb02_data - chip configuration 321 + * @chdata: options configured for each channel on the device 322 + * @lock: prevents concurrent reads/writes to driver's state members 323 + * @chip_features: pointer to features struct 324 + * @scale_1: scales set on channels that are based on Vref1 325 + * @scale: scales set on channels that are based on Vref/Vref0 326 + * @active_channels_mask: enabled channels 327 + * @regmap: regmap for directly accessing device register 328 + * @labels: table with channels labels 329 + * @phys_channels: physical channels on the device 330 + * @vref1_buffered: Vref1 buffer is enabled 331 + * @vref_buffered: Vref/Vref0 buffer is enabled 332 + * @use_vref1: vref1-supply is defined 333 + * @use_vref: vref-supply is defined 334 + */ 335 + struct mcp47feb02_data { 336 + struct mcp47feb02_channel_data chdata[MCP47FEB02_MAX_CH]; 337 + struct mutex lock; /* prevents concurrent reads/writes to driver's state members */ 338 + const struct mcp47feb02_features *chip_features; 339 + int scale_1[2 * MCP47FEB02_MAX_SCALES_CH]; 340 + int scale[2 * MCP47FEB02_MAX_SCALES_CH]; 341 + unsigned long active_channels_mask; 342 + struct regmap *regmap; 343 + const char *labels[MCP47FEB02_MAX_CH]; 344 + u16 phys_channels; 345 + bool vref1_buffered; 346 + bool vref_buffered; 347 + bool use_vref1; 348 + bool use_vref; 349 + }; 350 + 351 + static const struct regmap_range mcp47feb02_readable_ranges[] = { 352 + regmap_reg_range(MCP47FEB02_DAC0_REG_ADDR, MCP47FEB02_WIPERLOCK_STATUS_REG_ADDR), 353 + regmap_reg_range(MCP47FEB02_NV_DAC0_REG_ADDR, MCP47FEB02_NV_GAIN_CTRL_I2C_SLAVE_REG_ADDR), 354 + }; 355 + 356 + static const struct regmap_range mcp47feb02_writable_ranges[] = { 357 + regmap_reg_range(MCP47FEB02_DAC0_REG_ADDR, MCP47FEB02_WIPERLOCK_STATUS_REG_ADDR), 358 + regmap_reg_range(MCP47FEB02_NV_DAC0_REG_ADDR, MCP47FEB02_NV_GAIN_CTRL_I2C_SLAVE_REG_ADDR), 359 + }; 360 + 361 + static const struct regmap_range mcp47feb02_volatile_ranges[] = { 362 + regmap_reg_range(MCP47FEB02_DAC0_REG_ADDR, MCP47FEB02_WIPERLOCK_STATUS_REG_ADDR), 363 + regmap_reg_range(MCP47FEB02_NV_DAC0_REG_ADDR, MCP47FEB02_NV_GAIN_CTRL_I2C_SLAVE_REG_ADDR), 364 + regmap_reg_range(MCP47FEB02_DAC0_REG_ADDR, MCP47FEB02_WIPERLOCK_STATUS_REG_ADDR), 365 + regmap_reg_range(MCP47FEB02_NV_DAC0_REG_ADDR, MCP47FEB02_NV_GAIN_CTRL_I2C_SLAVE_REG_ADDR), 366 + }; 367 + 368 + static const struct regmap_access_table mcp47feb02_readable_table = { 369 + .yes_ranges = mcp47feb02_readable_ranges, 370 + .n_yes_ranges = ARRAY_SIZE(mcp47feb02_readable_ranges), 371 + }; 372 + 373 + static const struct regmap_access_table mcp47feb02_writable_table = { 374 + .yes_ranges = mcp47feb02_writable_ranges, 375 + .n_yes_ranges = ARRAY_SIZE(mcp47feb02_writable_ranges), 376 + }; 377 + 378 + static const struct regmap_access_table mcp47feb02_volatile_table = { 379 + .yes_ranges = mcp47feb02_volatile_ranges, 380 + .n_yes_ranges = ARRAY_SIZE(mcp47feb02_volatile_ranges), 381 + }; 382 + 383 + static const struct regmap_config mcp47feb02_regmap_config = { 384 + .name = "mcp47feb02_regmap", 385 + .reg_bits = 8, 386 + .val_bits = 16, 387 + .rd_table = &mcp47feb02_readable_table, 388 + .wr_table = &mcp47feb02_writable_table, 389 + .volatile_table = &mcp47feb02_volatile_table, 390 + .max_register = MCP47FEB02_NV_GAIN_CTRL_I2C_SLAVE_REG_ADDR, 391 + .read_flag_mask = READFLAG_MASK, 392 + .cache_type = REGCACHE_MAPLE, 393 + .val_format_endian = REGMAP_ENDIAN_BIG, 394 + }; 395 + 396 + /* For devices that doesn't have nonvolatile memory */ 397 + static const struct regmap_range mcp47fvb02_readable_ranges[] = { 398 + regmap_reg_range(MCP47FEB02_DAC0_REG_ADDR, MCP47FEB02_WIPERLOCK_STATUS_REG_ADDR), 399 + }; 400 + 401 + static const struct regmap_range mcp47fvb02_writable_ranges[] = { 402 + regmap_reg_range(MCP47FEB02_DAC0_REG_ADDR, MCP47FEB02_WIPERLOCK_STATUS_REG_ADDR), 403 + }; 404 + 405 + static const struct regmap_range mcp47fvb02_volatile_ranges[] = { 406 + regmap_reg_range(MCP47FEB02_DAC0_REG_ADDR, MCP47FEB02_WIPERLOCK_STATUS_REG_ADDR), 407 + regmap_reg_range(MCP47FEB02_DAC0_REG_ADDR, MCP47FEB02_WIPERLOCK_STATUS_REG_ADDR), 408 + }; 409 + 410 + static const struct regmap_access_table mcp47fvb02_readable_table = { 411 + .yes_ranges = mcp47fvb02_readable_ranges, 412 + .n_yes_ranges = ARRAY_SIZE(mcp47fvb02_readable_ranges), 413 + }; 414 + 415 + static const struct regmap_access_table mcp47fvb02_writable_table = { 416 + .yes_ranges = mcp47fvb02_writable_ranges, 417 + .n_yes_ranges = ARRAY_SIZE(mcp47fvb02_writable_ranges), 418 + }; 419 + 420 + static const struct regmap_access_table mcp47fvb02_volatile_table = { 421 + .yes_ranges = mcp47fvb02_volatile_ranges, 422 + .n_yes_ranges = ARRAY_SIZE(mcp47fvb02_volatile_ranges), 423 + }; 424 + 425 + static const struct regmap_config mcp47fvb02_regmap_config = { 426 + .name = "mcp47fvb02_regmap", 427 + .reg_bits = 8, 428 + .val_bits = 16, 429 + .rd_table = &mcp47fvb02_readable_table, 430 + .wr_table = &mcp47fvb02_writable_table, 431 + .volatile_table = &mcp47fvb02_volatile_table, 432 + .max_register = MCP47FEB02_WIPERLOCK_STATUS_REG_ADDR, 433 + .read_flag_mask = READFLAG_MASK, 434 + .cache_type = REGCACHE_MAPLE, 435 + .val_format_endian = REGMAP_ENDIAN_BIG, 436 + }; 437 + 438 + static int mcp47feb02_write_to_eeprom(struct mcp47feb02_data *data, unsigned int reg, 439 + unsigned int val) 440 + { 441 + int eewa_val, ret; 442 + 443 + /* 444 + * Wait until the currently occurring EEPROM Write Cycle is completed. 445 + * Only serial commands to the volatile memory are allowed. 446 + */ 447 + guard(mutex)(&data->lock); 448 + 449 + ret = regmap_read_poll_timeout(data->regmap, MCP47FEB02_GAIN_CTRL_STATUS_REG_ADDR, 450 + eewa_val, 451 + !(eewa_val & MCP47FEB02_GAIN_BIT_STATUS_EEWA_MASK), 452 + USEC_PER_MSEC, USEC_PER_MSEC * 5); 453 + if (ret) 454 + return ret; 455 + 456 + return regmap_write(data->regmap, reg, val); 457 + } 458 + 459 + static ssize_t store_eeprom_store(struct device *dev, struct device_attribute *attr, 460 + const char *buf, size_t len) 461 + { 462 + struct mcp47feb02_data *data = iio_priv(dev_to_iio_dev(dev)); 463 + unsigned int i, val, val1, eewa_val; 464 + bool state; 465 + int ret; 466 + 467 + ret = kstrtobool(buf, &state); 468 + if (ret) 469 + return ret; 470 + 471 + if (!state) 472 + return 0; 473 + 474 + /* 475 + * Verify DAC Wiper and DAC Configuration are unlocked. If both are disabled, 476 + * writing to EEPROM is available. 477 + */ 478 + ret = regmap_read(data->regmap, MCP47FEB02_WIPERLOCK_STATUS_REG_ADDR, &val); 479 + if (ret) 480 + return ret; 481 + 482 + if (val) { 483 + dev_err(dev, "DAC Wiper and DAC Configuration not are unlocked.\n"); 484 + return -EINVAL; 485 + } 486 + 487 + for_each_set_bit(i, &data->active_channels_mask, data->phys_channels) { 488 + ret = mcp47feb02_write_to_eeprom(data, NV_REG_ADDR(i), 489 + data->chdata[i].dac_data); 490 + if (ret) 491 + return ret; 492 + } 493 + 494 + ret = regmap_read(data->regmap, MCP47FEB02_VREF_REG_ADDR, &val); 495 + if (ret) 496 + return ret; 497 + 498 + ret = mcp47feb02_write_to_eeprom(data, MCP47FEB02_NV_VREF_REG_ADDR, val); 499 + if (ret) 500 + return ret; 501 + 502 + ret = regmap_read(data->regmap, MCP47FEB02_POWER_DOWN_REG_ADDR, &val); 503 + if (ret) 504 + return ret; 505 + 506 + ret = mcp47feb02_write_to_eeprom(data, MCP47FEB02_NV_POWER_DOWN_REG_ADDR, val); 507 + if (ret) 508 + return ret; 509 + 510 + ret = regmap_read_poll_timeout(data->regmap, MCP47FEB02_GAIN_CTRL_STATUS_REG_ADDR, eewa_val, 511 + !(eewa_val & MCP47FEB02_GAIN_BIT_STATUS_EEWA_MASK), 512 + USEC_PER_MSEC, USEC_PER_MSEC * 5); 513 + if (ret) 514 + return ret; 515 + 516 + ret = regmap_read(data->regmap, MCP47FEB02_NV_GAIN_CTRL_I2C_SLAVE_REG_ADDR, &val); 517 + if (ret) 518 + return ret; 519 + 520 + ret = regmap_read(data->regmap, MCP47FEB02_GAIN_CTRL_STATUS_REG_ADDR, &val1); 521 + if (ret) 522 + return ret; 523 + 524 + ret = mcp47feb02_write_to_eeprom(data, MCP47FEB02_NV_GAIN_CTRL_I2C_SLAVE_REG_ADDR, 525 + (val1 & MCP47FEB02_GAIN_BITS_MASK) | 526 + (val & MCP47FEB02_NV_I2C_SLAVE_ADDR_MASK)); 527 + if (ret) 528 + return ret; 529 + 530 + return len; 531 + } 532 + 533 + static IIO_DEVICE_ATTR_WO(store_eeprom, 0); 534 + 535 + static struct attribute *mcp47feb02_attributes[] = { 536 + &iio_dev_attr_store_eeprom.dev_attr.attr, 537 + NULL 538 + }; 539 + 540 + static const struct attribute_group mcp47feb02_attribute_group = { 541 + .attrs = mcp47feb02_attributes, 542 + }; 543 + 544 + static int mcp47feb02_suspend(struct device *dev) 545 + { 546 + struct iio_dev *indio_dev = dev_get_drvdata(dev); 547 + struct mcp47feb02_data *data = iio_priv(indio_dev); 548 + int ret; 549 + u8 ch; 550 + 551 + guard(mutex)(&data->lock); 552 + 553 + for_each_set_bit(ch, &data->active_channels_mask, data->phys_channels) { 554 + u8 pd_mode; 555 + 556 + data->chdata[ch].powerdown = true; 557 + pd_mode = data->chdata[ch].powerdown_mode + 1; 558 + ret = regmap_update_bits(data->regmap, MCP47FEB02_POWER_DOWN_REG_ADDR, 559 + DAC_CTRL_MASK(ch), DAC_CTRL_VAL(ch, pd_mode)); 560 + if (ret) 561 + return ret; 562 + 563 + ret = regmap_write(data->regmap, REG_ADDR(ch), data->chdata[ch].dac_data); 564 + if (ret) 565 + return ret; 566 + } 567 + 568 + return 0; 569 + } 570 + 571 + static int mcp47feb02_resume(struct device *dev) 572 + { 573 + struct iio_dev *indio_dev = dev_get_drvdata(dev); 574 + struct mcp47feb02_data *data = iio_priv(indio_dev); 575 + u8 ch; 576 + 577 + guard(mutex)(&data->lock); 578 + 579 + for_each_set_bit(ch, &data->active_channels_mask, data->phys_channels) { 580 + u8 pd_mode; 581 + int ret; 582 + 583 + data->chdata[ch].powerdown = false; 584 + pd_mode = data->chdata[ch].powerdown_mode + 1; 585 + 586 + ret = regmap_write(data->regmap, REG_ADDR(ch), data->chdata[ch].dac_data); 587 + if (ret) 588 + return ret; 589 + 590 + ret = regmap_update_bits(data->regmap, MCP47FEB02_VREF_REG_ADDR, 591 + DAC_CTRL_MASK(ch), DAC_CTRL_VAL(ch, pd_mode)); 592 + if (ret) 593 + return ret; 594 + 595 + ret = regmap_update_bits(data->regmap, MCP47FEB02_GAIN_CTRL_STATUS_REG_ADDR, 596 + DAC_GAIN_MASK(ch), 597 + DAC_GAIN_VAL(ch, data->chdata[ch].use_2x_gain)); 598 + if (ret) 599 + return ret; 600 + 601 + ret = regmap_update_bits(data->regmap, MCP47FEB02_POWER_DOWN_REG_ADDR, 602 + DAC_CTRL_MASK(ch), 603 + DAC_CTRL_VAL(ch, MCP47FEB02_NORMAL_OPERATION)); 604 + if (ret) 605 + return ret; 606 + } 607 + 608 + return 0; 609 + } 610 + 611 + static int mcp47feb02_get_powerdown_mode(struct iio_dev *indio_dev, 612 + const struct iio_chan_spec *chan) 613 + { 614 + struct mcp47feb02_data *data = iio_priv(indio_dev); 615 + 616 + return data->chdata[chan->address].powerdown_mode; 617 + } 618 + 619 + static int mcp47feb02_set_powerdown_mode(struct iio_dev *indio_dev, const struct iio_chan_spec *ch, 620 + unsigned int mode) 621 + { 622 + struct mcp47feb02_data *data = iio_priv(indio_dev); 623 + 624 + data->chdata[ch->address].powerdown_mode = mode; 625 + 626 + return 0; 627 + } 628 + 629 + static ssize_t mcp47feb02_read_powerdown(struct iio_dev *indio_dev, uintptr_t private, 630 + const struct iio_chan_spec *ch, char *buf) 631 + { 632 + struct mcp47feb02_data *data = iio_priv(indio_dev); 633 + 634 + /* Print if channel is in a power-down mode or not */ 635 + return sysfs_emit(buf, "%d\n", data->chdata[ch->address].powerdown); 636 + } 637 + 638 + static ssize_t mcp47feb02_write_powerdown(struct iio_dev *indio_dev, uintptr_t private, 639 + const struct iio_chan_spec *ch, const char *buf, 640 + size_t len) 641 + { 642 + struct mcp47feb02_data *data = iio_priv(indio_dev); 643 + u32 reg = ch->address; 644 + u8 tmp_pd_mode; 645 + bool state; 646 + int ret; 647 + 648 + guard(mutex)(&data->lock); 649 + 650 + ret = kstrtobool(buf, &state); 651 + if (ret) 652 + return ret; 653 + 654 + /* 655 + * Set the channel to the specified power-down mode. Exiting power-down mode 656 + * requires writing normal operation mode (0) to the channel-specific register bits. 657 + */ 658 + tmp_pd_mode = state ? (data->chdata[reg].powerdown_mode + 1) : MCP47FEB02_NORMAL_OPERATION; 659 + ret = regmap_update_bits(data->regmap, MCP47FEB02_POWER_DOWN_REG_ADDR, 660 + DAC_CTRL_MASK(reg), DAC_CTRL_VAL(reg, tmp_pd_mode)); 661 + if (ret) 662 + return ret; 663 + 664 + data->chdata[reg].powerdown = state; 665 + 666 + return len; 667 + } 668 + 669 + static DEFINE_SIMPLE_DEV_PM_OPS(mcp47feb02_pm_ops, mcp47feb02_suspend, mcp47feb02_resume); 670 + 671 + static const struct iio_enum mcp47febxx_powerdown_mode_enum = { 672 + .items = mcp47feb02_powerdown_modes, 673 + .num_items = ARRAY_SIZE(mcp47feb02_powerdown_modes), 674 + .get = mcp47feb02_get_powerdown_mode, 675 + .set = mcp47feb02_set_powerdown_mode, 676 + }; 677 + 678 + static const struct iio_chan_spec_ext_info mcp47feb02_ext_info[] = { 679 + { 680 + .name = "powerdown", 681 + .read = mcp47feb02_read_powerdown, 682 + .write = mcp47feb02_write_powerdown, 683 + .shared = IIO_SEPARATE, 684 + }, 685 + IIO_ENUM("powerdown_mode", IIO_SEPARATE, &mcp47febxx_powerdown_mode_enum), 686 + IIO_ENUM_AVAILABLE("powerdown_mode", IIO_SHARED_BY_TYPE, &mcp47febxx_powerdown_mode_enum), 687 + { } 688 + }; 689 + 690 + static const struct iio_chan_spec mcp47febxx_ch_template = { 691 + .type = IIO_VOLTAGE, 692 + .output = 1, 693 + .indexed = 1, 694 + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), 695 + .info_mask_separate_available = BIT(IIO_CHAN_INFO_SCALE), 696 + .ext_info = mcp47feb02_ext_info, 697 + }; 698 + 699 + static void mcp47feb02_init_scale(struct mcp47feb02_data *data, enum mcp47feb02_scale scale, 700 + int vref_mV, int scale_avail[]) 701 + { 702 + u32 value_micro, value_int; 703 + u64 tmp; 704 + 705 + /* vref_mV should not be negative */ 706 + tmp = (u64)vref_mV * MICRO >> data->chip_features->resolution; 707 + value_int = div_u64_rem(tmp, MICRO, &value_micro); 708 + scale_avail[scale * 2] = value_int; 709 + scale_avail[scale * 2 + 1] = value_micro; 710 + } 711 + 712 + static int mcp47feb02_init_scales_avail(struct mcp47feb02_data *data, int vdd_mV, 713 + int vref_mV, int vref1_mV) 714 + { 715 + struct device *dev = regmap_get_device(data->regmap); 716 + int tmp_vref; 717 + 718 + mcp47feb02_init_scale(data, MCP47FEB02_SCALE_VDD, vdd_mV, data->scale); 719 + 720 + if (data->use_vref) 721 + tmp_vref = vref_mV; 722 + else 723 + tmp_vref = MCP47FEB02_INTERNAL_BAND_GAP_mV; 724 + 725 + mcp47feb02_init_scale(data, MCP47FEB02_SCALE_GAIN_X1, tmp_vref, data->scale); 726 + mcp47feb02_init_scale(data, MCP47FEB02_SCALE_GAIN_X2, tmp_vref * 2, data->scale); 727 + 728 + if (data->phys_channels >= 4) { 729 + mcp47feb02_init_scale(data, MCP47FEB02_SCALE_VDD, vdd_mV, data->scale_1); 730 + 731 + if (data->use_vref1 && vref1_mV <= 0) 732 + return dev_err_probe(dev, vref1_mV, "Invalid voltage for Vref1\n"); 733 + 734 + if (data->use_vref1) 735 + tmp_vref = vref1_mV; 736 + else 737 + tmp_vref = MCP47FEB02_INTERNAL_BAND_GAP_mV; 738 + 739 + mcp47feb02_init_scale(data, MCP47FEB02_SCALE_GAIN_X1, 740 + tmp_vref, data->scale_1); 741 + mcp47feb02_init_scale(data, MCP47FEB02_SCALE_GAIN_X2, 742 + tmp_vref * 2, data->scale_1); 743 + } 744 + 745 + return 0; 746 + } 747 + 748 + static int mcp47feb02_read_avail(struct iio_dev *indio_dev, struct iio_chan_spec const *ch, 749 + const int **vals, int *type, int *length, long info) 750 + { 751 + struct mcp47feb02_data *data = iio_priv(indio_dev); 752 + 753 + switch (info) { 754 + case IIO_CHAN_INFO_SCALE: 755 + switch (ch->type) { 756 + case IIO_VOLTAGE: 757 + if (data->phys_channels >= 4 && (ch->address % 2)) 758 + *vals = data->scale_1; 759 + else 760 + *vals = data->scale; 761 + 762 + *length = 2 * MCP47FEB02_MAX_SCALES_CH; 763 + *type = IIO_VAL_INT_PLUS_MICRO; 764 + return IIO_AVAIL_LIST; 765 + default: 766 + return -EINVAL; 767 + } 768 + default: 769 + return -EINVAL; 770 + } 771 + } 772 + 773 + static void mcp47feb02_get_scale(int ch, struct mcp47feb02_data *data, int *val, int *val2) 774 + { 775 + enum mcp47feb02_scale current_scale; 776 + 777 + if (data->chdata[ch].ref_mode == MCP47FEB02_VREF_VDD) 778 + current_scale = MCP47FEB02_SCALE_VDD; 779 + else if (data->chdata[ch].use_2x_gain) 780 + current_scale = MCP47FEB02_SCALE_GAIN_X2; 781 + else 782 + current_scale = MCP47FEB02_SCALE_GAIN_X1; 783 + 784 + if (data->phys_channels >= 4 && (ch % 2)) { 785 + *val = data->scale_1[current_scale * 2]; 786 + *val2 = data->scale_1[current_scale * 2 + 1]; 787 + } else { 788 + *val = data->scale[current_scale * 2]; 789 + *val2 = data->scale[current_scale * 2 + 1]; 790 + } 791 + } 792 + 793 + static int mcp47feb02_check_scale(struct mcp47feb02_data *data, int val, int val2, int scale[]) 794 + { 795 + unsigned int i; 796 + 797 + for (i = 0; i < MCP47FEB02_MAX_SCALES_CH; i++) { 798 + if (scale[i * 2] == val && scale[i * 2 + 1] == val2) 799 + return i; 800 + } 801 + 802 + return -EINVAL; 803 + } 804 + 805 + static int mcp47feb02_ch_scale(struct mcp47feb02_data *data, int ch, int scale) 806 + { 807 + int tmp_val, ret; 808 + 809 + if (scale == MCP47FEB02_SCALE_VDD) { 810 + tmp_val = MCP47FEB02_VREF_VDD; 811 + } else if (data->phys_channels >= 4 && (ch % 2)) { 812 + if (data->use_vref1) { 813 + if (data->vref1_buffered) 814 + tmp_val = MCP47FEB02_EXTERNAL_VREF_BUFFERED; 815 + else 816 + tmp_val = MCP47FEB02_EXTERNAL_VREF_UNBUFFERED; 817 + } else { 818 + tmp_val = MCP47FEB02_INTERNAL_BAND_GAP; 819 + } 820 + } else if (data->use_vref) { 821 + if (data->vref_buffered) 822 + tmp_val = MCP47FEB02_EXTERNAL_VREF_BUFFERED; 823 + else 824 + tmp_val = MCP47FEB02_EXTERNAL_VREF_UNBUFFERED; 825 + } else { 826 + tmp_val = MCP47FEB02_INTERNAL_BAND_GAP; 827 + } 828 + 829 + ret = regmap_update_bits(data->regmap, MCP47FEB02_VREF_REG_ADDR, 830 + DAC_CTRL_MASK(ch), DAC_CTRL_VAL(ch, tmp_val)); 831 + if (ret) 832 + return ret; 833 + 834 + data->chdata[ch].ref_mode = tmp_val; 835 + 836 + return 0; 837 + } 838 + 839 + /* 840 + * Setting the scale in order to choose between VDD and (Vref or Band Gap) from the user 841 + * space. The VREF pin is either an input or an output, therefore the user cannot 842 + * simultaneously connect an external voltage reference to the pin and select the 843 + * internal Band Gap. 844 + * When the DAC’s voltage reference is configured as the VREF pin, the pin is an input. 845 + * When the DAC’s voltage reference is configured as the internal Band Gap, 846 + * the VREF pin is an output. 847 + * If Vref/Vref1 voltage is not available, then the internal Band Gap will be used 848 + * to calculate the values for the scale. 849 + */ 850 + static int mcp47feb02_set_scale(struct mcp47feb02_data *data, int ch, int scale) 851 + { 852 + int tmp_val, ret; 853 + 854 + ret = mcp47feb02_ch_scale(data, ch, scale); 855 + if (ret) 856 + return ret; 857 + 858 + if (scale == MCP47FEB02_SCALE_GAIN_X2) 859 + tmp_val = MCP47FEB02_GAIN_BIT_X2; 860 + else 861 + tmp_val = MCP47FEB02_GAIN_BIT_X1; 862 + 863 + ret = regmap_update_bits(data->regmap, MCP47FEB02_GAIN_CTRL_STATUS_REG_ADDR, 864 + DAC_GAIN_MASK(ch), DAC_GAIN_VAL(ch, tmp_val)); 865 + if (ret) 866 + return ret; 867 + 868 + data->chdata[ch].use_2x_gain = tmp_val; 869 + 870 + return 0; 871 + } 872 + 873 + static int mcp47feb02_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *ch, 874 + int *val, int *val2, long mask) 875 + { 876 + struct mcp47feb02_data *data = iio_priv(indio_dev); 877 + int ret; 878 + 879 + switch (mask) { 880 + case IIO_CHAN_INFO_RAW: 881 + ret = regmap_read(data->regmap, REG_ADDR(ch->address), val); 882 + if (ret) 883 + return ret; 884 + return IIO_VAL_INT; 885 + case IIO_CHAN_INFO_SCALE: 886 + mcp47feb02_get_scale(ch->address, data, val, val2); 887 + return IIO_VAL_INT_PLUS_MICRO; 888 + default: 889 + return -EINVAL; 890 + } 891 + } 892 + 893 + static int mcp47feb02_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *ch, 894 + int val, int val2, long mask) 895 + { 896 + struct mcp47feb02_data *data = iio_priv(indio_dev); 897 + int *tmp_scale, ret; 898 + 899 + guard(mutex)(&data->lock); 900 + 901 + switch (mask) { 902 + case IIO_CHAN_INFO_RAW: 903 + ret = regmap_write(data->regmap, REG_ADDR(ch->address), val); 904 + if (ret) 905 + return ret; 906 + 907 + data->chdata[ch->address].dac_data = val; 908 + return 0; 909 + case IIO_CHAN_INFO_SCALE: 910 + if (data->phys_channels >= 4 && (ch->address % 2)) 911 + tmp_scale = data->scale_1; 912 + else 913 + tmp_scale = data->scale; 914 + 915 + ret = mcp47feb02_check_scale(data, val, val2, tmp_scale); 916 + if (ret < 0) 917 + return ret; 918 + 919 + return mcp47feb02_set_scale(data, ch->address, ret); 920 + default: 921 + return -EINVAL; 922 + } 923 + } 924 + 925 + static int mcp47feb02_read_label(struct iio_dev *indio_dev, struct iio_chan_spec const *ch, 926 + char *label) 927 + { 928 + struct mcp47feb02_data *data = iio_priv(indio_dev); 929 + 930 + return sysfs_emit(label, "%s\n", data->labels[ch->address]); 931 + } 932 + 933 + static const struct iio_info mcp47feb02_info = { 934 + .read_raw = mcp47feb02_read_raw, 935 + .write_raw = mcp47feb02_write_raw, 936 + .read_label = mcp47feb02_read_label, 937 + .read_avail = &mcp47feb02_read_avail, 938 + .attrs = &mcp47feb02_attribute_group, 939 + }; 940 + 941 + static const struct iio_info mcp47fvb02_info = { 942 + .read_raw = mcp47feb02_read_raw, 943 + .write_raw = mcp47feb02_write_raw, 944 + .read_label = mcp47feb02_read_label, 945 + .read_avail = &mcp47feb02_read_avail, 946 + }; 947 + 948 + static int mcp47feb02_parse_fw(struct iio_dev *indio_dev, 949 + const struct mcp47feb02_features *chip_features) 950 + { 951 + struct iio_chan_spec chanspec = mcp47febxx_ch_template; 952 + struct mcp47feb02_data *data = iio_priv(indio_dev); 953 + struct device *dev = regmap_get_device(data->regmap); 954 + struct iio_chan_spec *channels; 955 + u32 num_channels; 956 + u8 chan_idx = 0; 957 + 958 + guard(mutex)(&data->lock); 959 + 960 + num_channels = device_get_child_node_count(dev); 961 + if (num_channels > chip_features->phys_channels) 962 + return dev_err_probe(dev, -EINVAL, "More channels than the chip supports\n"); 963 + 964 + if (!num_channels) 965 + return dev_err_probe(dev, -EINVAL, "No channel specified in the devicetree.\n"); 966 + 967 + channels = devm_kcalloc(dev, num_channels, sizeof(*channels), GFP_KERNEL); 968 + if (!channels) 969 + return -ENOMEM; 970 + 971 + device_for_each_child_node_scoped(dev, child) { 972 + u32 reg = 0; 973 + int ret; 974 + 975 + ret = fwnode_property_read_u32(child, "reg", &reg); 976 + if (ret) 977 + return dev_err_probe(dev, ret, "Invalid channel number\n"); 978 + 979 + if (reg >= chip_features->phys_channels) 980 + return dev_err_probe(dev, -EINVAL, 981 + "The index of the channels does not match the chip\n"); 982 + 983 + set_bit(reg, &data->active_channels_mask); 984 + 985 + ret = fwnode_property_read_string(child, "label", &data->labels[reg]); 986 + if (ret) 987 + return dev_err_probe(dev, ret, "%pfw: invalid label\n", 988 + fwnode_get_name(child)); 989 + 990 + chanspec.address = reg; 991 + chanspec.channel = reg; 992 + channels[chan_idx] = chanspec; 993 + chan_idx++; 994 + } 995 + 996 + indio_dev->num_channels = num_channels; 997 + indio_dev->channels = channels; 998 + indio_dev->modes = INDIO_DIRECT_MODE; 999 + data->phys_channels = chip_features->phys_channels; 1000 + 1001 + data->vref_buffered = device_property_read_bool(dev, "microchip,vref-buffered"); 1002 + 1003 + if (chip_features->have_ext_vref1) 1004 + data->vref1_buffered = device_property_read_bool(dev, "microchip,vref1-buffered"); 1005 + 1006 + return 0; 1007 + } 1008 + 1009 + static int mcp47feb02_init_ctrl_regs(struct mcp47feb02_data *data) 1010 + { 1011 + unsigned int i, vref_ch, gain_ch, pd_ch; 1012 + int ret; 1013 + 1014 + ret = regmap_read(data->regmap, MCP47FEB02_VREF_REG_ADDR, &vref_ch); 1015 + if (ret) 1016 + return ret; 1017 + 1018 + ret = regmap_read(data->regmap, MCP47FEB02_GAIN_CTRL_STATUS_REG_ADDR, &gain_ch); 1019 + if (ret) 1020 + return ret; 1021 + 1022 + ret = regmap_read(data->regmap, MCP47FEB02_POWER_DOWN_REG_ADDR, &pd_ch); 1023 + if (ret) 1024 + return ret; 1025 + 1026 + gain_ch = gain_ch & MCP47FEB02_GAIN_BITS_MASK; 1027 + for_each_set_bit(i, &data->active_channels_mask, data->phys_channels) { 1028 + struct device *dev = regmap_get_device(data->regmap); 1029 + unsigned int pd_tmp; 1030 + 1031 + data->chdata[i].ref_mode = (vref_ch >> (2 * i)) & MCP47FEB02_DAC_CTRL_MASK; 1032 + data->chdata[i].use_2x_gain = (gain_ch >> i) & MCP47FEB02_GAIN_BIT_MASK; 1033 + 1034 + /* 1035 + * Inform the user that the current voltage reference read from the volatile 1036 + * register of the chip is different from the one specified in the device tree. 1037 + * Considering that the user cannot have an external voltage reference connected 1038 + * to the pin and select the internal Band Gap at the same time, in order to avoid 1039 + * miscofiguring the reference voltage, the volatile register will not be written. 1040 + * In order to overwrite the setting from volatile register with the one from the 1041 + * device tree, the user needs to write the chosen scale. 1042 + */ 1043 + switch (data->chdata[i].ref_mode) { 1044 + case MCP47FEB02_INTERNAL_BAND_GAP: 1045 + if (data->phys_channels >= 4 && (i % 2) && data->use_vref1) { 1046 + dev_dbg(dev, "ch[%u]: was configured to use internal band gap", i); 1047 + dev_dbg(dev, "ch[%u]: reference voltage set to VREF1", i); 1048 + break; 1049 + } 1050 + if ((data->phys_channels < 4 || (data->phys_channels >= 4 && !(i % 2))) && 1051 + data->use_vref) { 1052 + dev_dbg(dev, "ch[%u]: was configured to use internal band gap", i); 1053 + dev_dbg(dev, "ch[%u]: reference voltage set to VREF", i); 1054 + break; 1055 + } 1056 + break; 1057 + case MCP47FEB02_EXTERNAL_VREF_UNBUFFERED: 1058 + case MCP47FEB02_EXTERNAL_VREF_BUFFERED: 1059 + if (data->phys_channels >= 4 && (i % 2) && !data->use_vref1) { 1060 + dev_dbg(dev, "ch[%u]: was configured to use VREF1", i); 1061 + dev_dbg(dev, 1062 + "ch[%u]: reference voltage set to internal band gap", i); 1063 + break; 1064 + } 1065 + if ((data->phys_channels < 4 || (data->phys_channels >= 4 && !(i % 2))) && 1066 + !data->use_vref) { 1067 + dev_dbg(dev, "ch[%u]: was configured to use VREF", i); 1068 + dev_dbg(dev, 1069 + "ch[%u]: reference voltage set to internal band gap", i); 1070 + break; 1071 + } 1072 + break; 1073 + } 1074 + 1075 + pd_tmp = (pd_ch >> (2 * i)) & MCP47FEB02_DAC_CTRL_MASK; 1076 + data->chdata[i].powerdown_mode = pd_tmp ? (pd_tmp - 1) : pd_tmp; 1077 + data->chdata[i].powerdown = !!(data->chdata[i].powerdown_mode); 1078 + } 1079 + 1080 + return 0; 1081 + } 1082 + 1083 + static int mcp47feb02_init_ch_scales(struct mcp47feb02_data *data, int vdd_mV, 1084 + int vref_mV, int vref1_mV) 1085 + { 1086 + unsigned int i; 1087 + 1088 + for_each_set_bit(i, &data->active_channels_mask, data->phys_channels) { 1089 + struct device *dev = regmap_get_device(data->regmap); 1090 + int ret; 1091 + 1092 + ret = mcp47feb02_init_scales_avail(data, vdd_mV, vref_mV, vref1_mV); 1093 + if (ret) 1094 + return dev_err_probe(dev, ret, "failed to init scales for ch %u\n", i); 1095 + } 1096 + 1097 + return 0; 1098 + } 1099 + 1100 + static int mcp47feb02_probe(struct i2c_client *client) 1101 + { 1102 + const struct mcp47feb02_features *chip_features; 1103 + struct device *dev = &client->dev; 1104 + struct mcp47feb02_data *data; 1105 + struct iio_dev *indio_dev; 1106 + int vref1_mV = 0; 1107 + int vref_mV = 0; 1108 + int vdd_mV; 1109 + int ret; 1110 + 1111 + indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); 1112 + if (!indio_dev) 1113 + return -ENOMEM; 1114 + 1115 + data = iio_priv(indio_dev); 1116 + chip_features = i2c_get_match_data(client); 1117 + if (!chip_features) 1118 + return -EINVAL; 1119 + 1120 + data->chip_features = chip_features; 1121 + 1122 + if (chip_features->have_eeprom) { 1123 + data->regmap = devm_regmap_init_i2c(client, &mcp47feb02_regmap_config); 1124 + indio_dev->info = &mcp47feb02_info; 1125 + } else { 1126 + data->regmap = devm_regmap_init_i2c(client, &mcp47fvb02_regmap_config); 1127 + indio_dev->info = &mcp47fvb02_info; 1128 + } 1129 + if (IS_ERR(data->regmap)) 1130 + return dev_err_probe(dev, PTR_ERR(data->regmap), "Error initializing i2c regmap\n"); 1131 + 1132 + indio_dev->name = chip_features->name; 1133 + 1134 + ret = mcp47feb02_parse_fw(indio_dev, chip_features); 1135 + if (ret) 1136 + return dev_err_probe(dev, ret, "Error parsing firmware data\n"); 1137 + 1138 + ret = devm_mutex_init(dev, &data->lock); 1139 + if (ret) 1140 + return ret; 1141 + 1142 + ret = devm_regulator_get_enable_read_voltage(dev, "vdd"); 1143 + if (ret < 0) 1144 + return ret; 1145 + 1146 + vdd_mV = ret / MILLI; 1147 + 1148 + ret = devm_regulator_get_enable_read_voltage(dev, "vref"); 1149 + if (ret > 0) { 1150 + vref_mV = ret / MILLI; 1151 + data->use_vref = true; 1152 + } else { 1153 + dev_dbg(dev, "using internal band gap as voltage reference.\n"); 1154 + dev_dbg(dev, "Vref is unavailable.\n"); 1155 + } 1156 + 1157 + if (chip_features->have_ext_vref1) { 1158 + ret = devm_regulator_get_enable_read_voltage(dev, "vref1"); 1159 + if (ret > 0) { 1160 + vref1_mV = ret / MILLI; 1161 + data->use_vref1 = true; 1162 + } else { 1163 + dev_dbg(dev, "using internal band gap as voltage reference 1.\n"); 1164 + dev_dbg(dev, "Vref1 is unavailable.\n"); 1165 + } 1166 + } 1167 + 1168 + ret = mcp47feb02_init_ctrl_regs(data); 1169 + if (ret) 1170 + return dev_err_probe(dev, ret, "Error initialising vref register\n"); 1171 + 1172 + ret = mcp47feb02_init_ch_scales(data, vdd_mV, vref_mV, vref1_mV); 1173 + if (ret) 1174 + return ret; 1175 + 1176 + return devm_iio_device_register(dev, indio_dev); 1177 + } 1178 + 1179 + static const struct i2c_device_id mcp47feb02_id[] = { 1180 + { "mcp47feb01", (kernel_ulong_t)&mcp47feb01_chip_features }, 1181 + { "mcp47feb02", (kernel_ulong_t)&mcp47feb02_chip_features }, 1182 + { "mcp47feb04", (kernel_ulong_t)&mcp47feb04_chip_features }, 1183 + { "mcp47feb08", (kernel_ulong_t)&mcp47feb08_chip_features }, 1184 + { "mcp47feb11", (kernel_ulong_t)&mcp47feb11_chip_features }, 1185 + { "mcp47feb12", (kernel_ulong_t)&mcp47feb12_chip_features }, 1186 + { "mcp47feb14", (kernel_ulong_t)&mcp47feb14_chip_features }, 1187 + { "mcp47feb18", (kernel_ulong_t)&mcp47feb18_chip_features }, 1188 + { "mcp47feb21", (kernel_ulong_t)&mcp47feb21_chip_features }, 1189 + { "mcp47feb22", (kernel_ulong_t)&mcp47feb22_chip_features }, 1190 + { "mcp47feb24", (kernel_ulong_t)&mcp47feb24_chip_features }, 1191 + { "mcp47feb28", (kernel_ulong_t)&mcp47feb28_chip_features }, 1192 + { "mcp47fvb01", (kernel_ulong_t)&mcp47fvb01_chip_features }, 1193 + { "mcp47fvb02", (kernel_ulong_t)&mcp47fvb02_chip_features }, 1194 + { "mcp47fvb04", (kernel_ulong_t)&mcp47fvb04_chip_features }, 1195 + { "mcp47fvb08", (kernel_ulong_t)&mcp47fvb08_chip_features }, 1196 + { "mcp47fvb11", (kernel_ulong_t)&mcp47fvb11_chip_features }, 1197 + { "mcp47fvb12", (kernel_ulong_t)&mcp47fvb12_chip_features }, 1198 + { "mcp47fvb14", (kernel_ulong_t)&mcp47fvb14_chip_features }, 1199 + { "mcp47fvb18", (kernel_ulong_t)&mcp47fvb18_chip_features }, 1200 + { "mcp47fvb21", (kernel_ulong_t)&mcp47fvb21_chip_features }, 1201 + { "mcp47fvb22", (kernel_ulong_t)&mcp47fvb22_chip_features }, 1202 + { "mcp47fvb24", (kernel_ulong_t)&mcp47fvb24_chip_features }, 1203 + { "mcp47fvb28", (kernel_ulong_t)&mcp47fvb28_chip_features }, 1204 + { } 1205 + }; 1206 + MODULE_DEVICE_TABLE(i2c, mcp47feb02_id); 1207 + 1208 + static const struct of_device_id mcp47feb02_of_match[] = { 1209 + { .compatible = "microchip,mcp47feb01", .data = &mcp47feb01_chip_features }, 1210 + { .compatible = "microchip,mcp47feb02", .data = &mcp47feb02_chip_features }, 1211 + { .compatible = "microchip,mcp47feb04", .data = &mcp47feb04_chip_features }, 1212 + { .compatible = "microchip,mcp47feb08", .data = &mcp47feb08_chip_features }, 1213 + { .compatible = "microchip,mcp47feb11", .data = &mcp47feb11_chip_features }, 1214 + { .compatible = "microchip,mcp47feb12", .data = &mcp47feb12_chip_features }, 1215 + { .compatible = "microchip,mcp47feb14", .data = &mcp47feb14_chip_features }, 1216 + { .compatible = "microchip,mcp47feb18", .data = &mcp47feb18_chip_features }, 1217 + { .compatible = "microchip,mcp47feb21", .data = &mcp47feb21_chip_features }, 1218 + { .compatible = "microchip,mcp47feb22", .data = &mcp47feb22_chip_features }, 1219 + { .compatible = "microchip,mcp47feb24", .data = &mcp47feb24_chip_features }, 1220 + { .compatible = "microchip,mcp47feb28", .data = &mcp47feb28_chip_features }, 1221 + { .compatible = "microchip,mcp47fvb01", .data = &mcp47fvb01_chip_features }, 1222 + { .compatible = "microchip,mcp47fvb02", .data = &mcp47fvb02_chip_features }, 1223 + { .compatible = "microchip,mcp47fvb04", .data = &mcp47fvb04_chip_features }, 1224 + { .compatible = "microchip,mcp47fvb08", .data = &mcp47fvb08_chip_features }, 1225 + { .compatible = "microchip,mcp47fvb11", .data = &mcp47fvb11_chip_features }, 1226 + { .compatible = "microchip,mcp47fvb12", .data = &mcp47fvb12_chip_features }, 1227 + { .compatible = "microchip,mcp47fvb14", .data = &mcp47fvb14_chip_features }, 1228 + { .compatible = "microchip,mcp47fvb18", .data = &mcp47fvb18_chip_features }, 1229 + { .compatible = "microchip,mcp47fvb21", .data = &mcp47fvb21_chip_features }, 1230 + { .compatible = "microchip,mcp47fvb22", .data = &mcp47fvb22_chip_features }, 1231 + { .compatible = "microchip,mcp47fvb24", .data = &mcp47fvb24_chip_features }, 1232 + { .compatible = "microchip,mcp47fvb28", .data = &mcp47fvb28_chip_features }, 1233 + { } 1234 + }; 1235 + MODULE_DEVICE_TABLE(of, mcp47feb02_of_match); 1236 + 1237 + static struct i2c_driver mcp47feb02_driver = { 1238 + .driver = { 1239 + .name = "mcp47feb02", 1240 + .of_match_table = mcp47feb02_of_match, 1241 + .pm = pm_sleep_ptr(&mcp47feb02_pm_ops), 1242 + }, 1243 + .probe = mcp47feb02_probe, 1244 + .id_table = mcp47feb02_id, 1245 + }; 1246 + module_i2c_driver(mcp47feb02_driver); 1247 + 1248 + MODULE_AUTHOR("Ariana Lazar <ariana.lazar@microchip.com>"); 1249 + MODULE_DESCRIPTION("IIO driver for MCP47FEB02 Multi-Channel DAC with I2C interface"); 1250 + MODULE_LICENSE("GPL");