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: add support for pac1921

Add support for Microchip PAC1921 Power/Current monitor.

Implemented features:
* capture of bus voltage, sense voltage, current and power measurements
in free-run integration mode
* support for both raw and triggered buffer reading
* support for overflow events
* scale attributes to control voltage and current gains
* oversampling ratio attribute to control the number of integration
samples
* sampling rate attribute that reflects the integration period
* userspace attribute and DT parameter to control shunt resistor
* simple power management support

Limitations:
* operation mode fixed to free-run integration
* READ/INT pin and OUT pin not supported
* no controls for measurement resolutions and filters

Signed-off-by: Matteo Martelli <matteomartelli3@gmail.com>
Link: https://patch.msgid.link/20240724-iio-pac1921-v4-3-723698e903a3@gmail.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Matteo Martelli and committed by
Jonathan Cameron
371f778b e5535ccf

+1282
+7
MAINTAINERS
··· 15054 15054 F: drivers/nvmem/microchip-otpc.c 15055 15055 F: include/dt-bindings/nvmem/microchip,sama7g5-otpc.h 15056 15056 15057 + MICROCHIP PAC1921 POWER/CURRENT MONITOR DRIVER 15058 + M: Matteo Martelli <matteomartelli3@gmail.com> 15059 + L: linux-iio@vger.kernel.org 15060 + S: Supported 15061 + F: Documentation/devicetree/bindings/iio/adc/microchip,pac1921.yaml 15062 + F: drivers/iio/adc/pac1921.c 15063 + 15057 15064 MICROCHIP PAC1934 POWER/ENERGY MONITOR DRIVER 15058 15065 M: Marius Cristea <marius.cristea@microchip.com> 15059 15066 L: linux-iio@vger.kernel.org
+13
drivers/iio/adc/Kconfig
··· 1002 1002 This driver can also be built as a module. If so, the module 1003 1003 will be called npcm_adc. 1004 1004 1005 + config PAC1921 1006 + tristate "Microchip Technology PAC1921 driver" 1007 + depends on I2C 1008 + select REGMAP_I2C 1009 + select IIO_BUFFER 1010 + select IIO_TRIGGERED_BUFFER 1011 + help 1012 + Say yes here to build support for Microchip Technology's PAC1921 1013 + High-Side Power/Current Monitor with Analog Output. 1014 + 1015 + This driver can also be built as a module. If so, the module 1016 + will be called pac1921. 1017 + 1005 1018 config PAC1934 1006 1019 tristate "Microchip Technology PAC1934 driver" 1007 1020 depends on I2C
+1
drivers/iio/adc/Makefile
··· 91 91 obj-$(CONFIG_MXS_LRADC_ADC) += mxs-lradc-adc.o 92 92 obj-$(CONFIG_NAU7802) += nau7802.o 93 93 obj-$(CONFIG_NPCM_ADC) += npcm_adc.o 94 + obj-$(CONFIG_PAC1921) += pac1921.o 94 95 obj-$(CONFIG_PAC1934) += pac1934.o 95 96 obj-$(CONFIG_PALMAS_GPADC) += palmas_gpadc.o 96 97 obj-$(CONFIG_QCOM_PM8XXX_XOADC) += qcom-pm8xxx-xoadc.o
+1261
drivers/iio/adc/pac1921.c
··· 1 + // SPDX-License-Identifier: GPL-2.0+ 2 + /* 3 + * IIO driver for PAC1921 High-Side Power/Current Monitor 4 + * 5 + * Copyright (C) 2024 Matteo Martelli <matteomartelli3@gmail.com> 6 + */ 7 + 8 + #include <asm/unaligned.h> 9 + #include <linux/bitfield.h> 10 + #include <linux/i2c.h> 11 + #include <linux/iio/events.h> 12 + #include <linux/iio/iio.h> 13 + #include <linux/iio/trigger_consumer.h> 14 + #include <linux/iio/triggered_buffer.h> 15 + #include <linux/regmap.h> 16 + #include <linux/units.h> 17 + 18 + /* pac1921 registers */ 19 + #define PAC1921_REG_GAIN_CFG 0x00 20 + #define PAC1921_REG_INT_CFG 0x01 21 + #define PAC1921_REG_CONTROL 0x02 22 + #define PAC1921_REG_VBUS 0x10 23 + #define PAC1921_REG_VSENSE 0x12 24 + #define PAC1921_REG_OVERFLOW_STS 0x1C 25 + #define PAC1921_REG_VPOWER 0x1D 26 + 27 + /* pac1921 gain configuration bits */ 28 + #define PAC1921_GAIN_DI_GAIN_MASK GENMASK(5, 3) 29 + #define PAC1921_GAIN_DV_GAIN_MASK GENMASK(2, 0) 30 + 31 + /* pac1921 integration configuration bits */ 32 + #define PAC1921_INT_CFG_SMPL_MASK GENMASK(7, 4) 33 + #define PAC1921_INT_CFG_VSFEN BIT(3) 34 + #define PAC1921_INT_CFG_VBFEN BIT(2) 35 + #define PAC1921_INT_CFG_RIOV BIT(1) 36 + #define PAC1921_INT_CFG_INTEN BIT(0) 37 + 38 + /* pac1921 control bits */ 39 + #define PAC1921_CONTROL_MXSL_MASK GENMASK(7, 6) 40 + enum pac1921_mxsl { 41 + PAC1921_MXSL_VPOWER_PIN = 0, 42 + PAC1921_MXSL_VSENSE_FREE_RUN = 1, 43 + PAC1921_MXSL_VBUS_FREE_RUN = 2, 44 + PAC1921_MXSL_VPOWER_FREE_RUN = 3, 45 + }; 46 + #define PAC1921_CONTROL_SLEEP BIT(2) 47 + 48 + /* pac1921 result registers mask and resolution */ 49 + #define PAC1921_RES_MASK GENMASK(15, 6) 50 + #define PAC1921_RES_RESOLUTION 1023 51 + 52 + /* pac1921 overflow status bits */ 53 + #define PAC1921_OVERFLOW_VSOV BIT(2) 54 + #define PAC1921_OVERFLOW_VBOV BIT(1) 55 + #define PAC1921_OVERFLOW_VPOV BIT(0) 56 + 57 + /* pac1921 constants */ 58 + #define PAC1921_MAX_VSENSE_MV 100 59 + #define PAC1921_MAX_VBUS_V 32 60 + /* Time to first communication after power up (tINT_T) */ 61 + #define PAC1921_POWERUP_TIME_MS 20 62 + /* Time from Sleep State to Start of Integration Period (tSLEEP_TO_INT) */ 63 + #define PAC1921_SLEEP_TO_INT_TIME_US 86 64 + 65 + /* pac1921 defaults */ 66 + #define PAC1921_DEFAULT_DV_GAIN 0 /* 2^(value): 1x gain (HW default) */ 67 + #define PAC1921_DEFAULT_DI_GAIN 0 /* 2^(value): 1x gain (HW default) */ 68 + #define PAC1921_DEFAULT_NUM_SAMPLES 0 /* 2^(value): 1 sample (HW default) */ 69 + 70 + /* 71 + * Pre-computed scale factors for BUS voltage 72 + * format: IIO_VAL_INT_PLUS_NANO 73 + * unit: mV 74 + * 75 + * Vbus scale (mV) = max_vbus (mV) / dv_gain / resolution 76 + */ 77 + static const int pac1921_vbus_scales[][2] = { 78 + { 31, 280547409 }, /* dv_gain x1 */ 79 + { 15, 640273704 }, /* dv_gain x2 */ 80 + { 7, 820136852 }, /* dv_gain x4 */ 81 + { 3, 910068426 }, /* dv_gain x8 */ 82 + { 1, 955034213 }, /* dv_gain x16 */ 83 + { 0, 977517106 }, /* dv_gain x32 */ 84 + }; 85 + 86 + /* 87 + * Pre-computed scales for SENSE voltage 88 + * format: IIO_VAL_INT_PLUS_NANO 89 + * unit: mV 90 + * 91 + * Vsense scale (mV) = max_vsense (mV) / di_gain / resolution 92 + */ 93 + static const int pac1921_vsense_scales[][2] = { 94 + { 0, 97751710 }, /* di_gain x1 */ 95 + { 0, 48875855 }, /* di_gain x2 */ 96 + { 0, 24437927 }, /* di_gain x4 */ 97 + { 0, 12218963 }, /* di_gain x8 */ 98 + { 0, 6109481 }, /* di_gain x16 */ 99 + { 0, 3054740 }, /* di_gain x32 */ 100 + { 0, 1527370 }, /* di_gain x64 */ 101 + { 0, 763685 }, /* di_gain x128 */ 102 + }; 103 + 104 + /* 105 + * Numbers of samples used to integrate measurements at the end of an 106 + * integration period. 107 + * 108 + * Changing the number of samples affects the integration period: higher the 109 + * number of samples, longer the integration period. 110 + * 111 + * These correspond to the oversampling ratios available exposed to userspace. 112 + */ 113 + static const int pac1921_int_num_samples[] = { 114 + 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048 115 + }; 116 + 117 + /* 118 + * The integration period depends on the configuration of number of integration 119 + * samples, measurement resolution and post filters. The following array 120 + * contains integration periods, in microsecs unit, based on table 4-5 from 121 + * datasheet considering power integration mode, 14-Bit resolution and post 122 + * filters on. Each index corresponds to a specific number of samples from 1 123 + * to 2048. 124 + */ 125 + static const unsigned int pac1921_int_periods_usecs[] = { 126 + 2720, /* 1 sample */ 127 + 4050, /* 2 samples */ 128 + 6790, /* 4 samples */ 129 + 12200, /* 8 samples */ 130 + 23000, /* 16 samples */ 131 + 46000, /* 32 samples */ 132 + 92000, /* 64 samples */ 133 + 184000, /* 128 samples */ 134 + 368000, /* 256 samples */ 135 + 736000, /* 512 samples */ 136 + 1471000, /* 1024 samples */ 137 + 2941000 /* 2048 samples */ 138 + }; 139 + 140 + /* pac1921 regmap configuration */ 141 + static const struct regmap_range pac1921_regmap_wr_ranges[] = { 142 + regmap_reg_range(PAC1921_REG_GAIN_CFG, PAC1921_REG_CONTROL), 143 + }; 144 + 145 + static const struct regmap_access_table pac1921_regmap_wr_table = { 146 + .yes_ranges = pac1921_regmap_wr_ranges, 147 + .n_yes_ranges = ARRAY_SIZE(pac1921_regmap_wr_ranges), 148 + }; 149 + 150 + static const struct regmap_range pac1921_regmap_rd_ranges[] = { 151 + regmap_reg_range(PAC1921_REG_GAIN_CFG, PAC1921_REG_CONTROL), 152 + regmap_reg_range(PAC1921_REG_VBUS, PAC1921_REG_VPOWER + 1), 153 + }; 154 + 155 + static const struct regmap_access_table pac1921_regmap_rd_table = { 156 + .yes_ranges = pac1921_regmap_rd_ranges, 157 + .n_yes_ranges = ARRAY_SIZE(pac1921_regmap_rd_ranges), 158 + }; 159 + 160 + static const struct regmap_config pac1921_regmap_config = { 161 + .reg_bits = 8, 162 + .val_bits = 8, 163 + .rd_table = &pac1921_regmap_rd_table, 164 + .wr_table = &pac1921_regmap_wr_table, 165 + }; 166 + 167 + enum pac1921_channels { 168 + PAC1921_CHAN_VBUS = 0, 169 + PAC1921_CHAN_VSENSE = 1, 170 + PAC1921_CHAN_CURRENT = 2, 171 + PAC1921_CHAN_POWER = 3, 172 + }; 173 + #define PAC1921_NUM_MEAS_CHANS 4 174 + 175 + struct pac1921_priv { 176 + struct i2c_client *client; 177 + struct regmap *regmap; 178 + struct regulator *vdd; 179 + struct iio_info iio_info; 180 + 181 + /* 182 + * Synchronize access to private members, and ensure atomicity of 183 + * consecutive regmap operations. 184 + */ 185 + struct mutex lock; 186 + 187 + u32 rshunt_uohm; /* uOhm */ 188 + u8 dv_gain; 189 + u8 di_gain; 190 + u8 n_samples; 191 + u8 prev_ovf_flags; 192 + u8 ovf_enabled_events; 193 + 194 + bool first_integr_started; 195 + bool first_integr_done; 196 + unsigned long integr_started_time_jiffies; 197 + unsigned int integr_period_usecs; 198 + 199 + int current_scales[ARRAY_SIZE(pac1921_vsense_scales)][2]; 200 + 201 + struct { 202 + u16 chan[PAC1921_NUM_MEAS_CHANS]; 203 + s64 timestamp __aligned(8); 204 + } scan; 205 + }; 206 + 207 + /* 208 + * Check if first integration after configuration update has completed. 209 + * 210 + * Must be called with lock held. 211 + */ 212 + static bool pac1921_data_ready(struct pac1921_priv *priv) 213 + { 214 + if (!priv->first_integr_started) 215 + return false; 216 + 217 + if (!priv->first_integr_done) { 218 + unsigned long t_ready; 219 + 220 + /* 221 + * Data valid after the device entered into integration state, 222 + * considering worst case where the device was in sleep state, 223 + * and completed the first integration period. 224 + */ 225 + t_ready = priv->integr_started_time_jiffies + 226 + usecs_to_jiffies(PAC1921_SLEEP_TO_INT_TIME_US) + 227 + usecs_to_jiffies(priv->integr_period_usecs); 228 + 229 + if (time_before(jiffies, t_ready)) 230 + return false; 231 + 232 + priv->first_integr_done = true; 233 + } 234 + 235 + return true; 236 + } 237 + 238 + static inline void pac1921_calc_scale(int dividend, int divisor, int *val, 239 + int *val2) 240 + { 241 + s64 tmp; 242 + 243 + tmp = div_s64(dividend * (s64)NANO, divisor); 244 + *val = (int)div_s64_rem(tmp, NANO, val2); 245 + } 246 + 247 + /* 248 + * Fill the table of scale factors for current 249 + * format: IIO_VAL_INT_PLUS_NANO 250 + * unit: mA 251 + * 252 + * Vsense LSB (nV) = max_vsense (nV) * di_gain / resolution 253 + * Current scale (mA) = Vsense LSB (nV) / shunt (uOhm) 254 + * 255 + * Must be called with held lock when updating after first initialization. 256 + */ 257 + static void pac1921_calc_current_scales(struct pac1921_priv *priv) 258 + { 259 + for (unsigned int i = 0; i < ARRAY_SIZE(priv->current_scales); i++) { 260 + int max = (PAC1921_MAX_VSENSE_MV * MICRO) >> i; 261 + int vsense_lsb = DIV_ROUND_CLOSEST(max, PAC1921_RES_RESOLUTION); 262 + 263 + pac1921_calc_scale(vsense_lsb, (int)priv->rshunt_uohm, 264 + &priv->current_scales[i][0], 265 + &priv->current_scales[i][1]); 266 + } 267 + } 268 + 269 + /* 270 + * Check if overflow occurred and if so, push the corresponding events. 271 + * 272 + * Must be called with lock held. 273 + */ 274 + static int pac1921_check_push_overflow(struct iio_dev *indio_dev, s64 timestamp) 275 + { 276 + struct pac1921_priv *priv = iio_priv(indio_dev); 277 + unsigned int flags; 278 + int ret; 279 + 280 + ret = regmap_read(priv->regmap, PAC1921_REG_OVERFLOW_STS, &flags); 281 + if (ret) 282 + return ret; 283 + 284 + if (flags & PAC1921_OVERFLOW_VBOV && 285 + !(priv->prev_ovf_flags & PAC1921_OVERFLOW_VBOV) && 286 + priv->ovf_enabled_events & PAC1921_OVERFLOW_VBOV) { 287 + iio_push_event(indio_dev, 288 + IIO_UNMOD_EVENT_CODE( 289 + IIO_VOLTAGE, PAC1921_CHAN_VBUS, 290 + IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), 291 + timestamp); 292 + } 293 + if (flags & PAC1921_OVERFLOW_VSOV && 294 + !(priv->prev_ovf_flags & PAC1921_OVERFLOW_VSOV) && 295 + priv->ovf_enabled_events & PAC1921_OVERFLOW_VSOV) { 296 + iio_push_event(indio_dev, 297 + IIO_UNMOD_EVENT_CODE( 298 + IIO_VOLTAGE, PAC1921_CHAN_VSENSE, 299 + IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), 300 + timestamp); 301 + iio_push_event(indio_dev, 302 + IIO_UNMOD_EVENT_CODE( 303 + IIO_CURRENT, PAC1921_CHAN_CURRENT, 304 + IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), 305 + timestamp); 306 + } 307 + if (flags & PAC1921_OVERFLOW_VPOV && 308 + !(priv->prev_ovf_flags & PAC1921_OVERFLOW_VPOV) && 309 + priv->ovf_enabled_events & PAC1921_OVERFLOW_VPOV) { 310 + iio_push_event(indio_dev, 311 + IIO_UNMOD_EVENT_CODE( 312 + IIO_POWER, PAC1921_CHAN_POWER, 313 + IIO_EV_TYPE_THRESH, IIO_EV_DIR_RISING), 314 + timestamp); 315 + } 316 + 317 + priv->prev_ovf_flags = (u8)flags; 318 + 319 + return 0; 320 + } 321 + 322 + /* 323 + * Read the value from a result register 324 + * 325 + * Result registers contain the most recent averaged values of Vbus, Vsense and 326 + * Vpower. Each value is 10 bits wide and spread across two consecutive 8 bit 327 + * registers, with 6 bit LSB zero padding. 328 + */ 329 + static int pac1921_read_res(struct pac1921_priv *priv, unsigned long reg, 330 + u16 *val) 331 + { 332 + int ret = regmap_bulk_read(priv->regmap, (unsigned int)reg, val, 333 + sizeof(*val)); 334 + if (ret) 335 + return ret; 336 + 337 + *val = FIELD_GET(PAC1921_RES_MASK, get_unaligned_be16(val)); 338 + 339 + return 0; 340 + } 341 + 342 + static int pac1921_read_raw(struct iio_dev *indio_dev, 343 + struct iio_chan_spec const *chan, int *val, 344 + int *val2, long mask) 345 + { 346 + struct pac1921_priv *priv = iio_priv(indio_dev); 347 + 348 + guard(mutex)(&priv->lock); 349 + 350 + switch (mask) { 351 + case IIO_CHAN_INFO_RAW: { 352 + s64 ts; 353 + u16 res_val; 354 + int ret; 355 + 356 + if (!pac1921_data_ready(priv)) 357 + return -EBUSY; 358 + 359 + ts = iio_get_time_ns(indio_dev); 360 + 361 + ret = pac1921_check_push_overflow(indio_dev, ts); 362 + if (ret) 363 + return ret; 364 + 365 + ret = pac1921_read_res(priv, chan->address, &res_val); 366 + if (ret) 367 + return ret; 368 + 369 + *val = (int)res_val; 370 + 371 + return IIO_VAL_INT; 372 + } 373 + case IIO_CHAN_INFO_SCALE: 374 + switch (chan->channel) { 375 + case PAC1921_CHAN_VBUS: 376 + *val = pac1921_vbus_scales[priv->dv_gain][0]; 377 + *val2 = pac1921_vbus_scales[priv->dv_gain][1]; 378 + return IIO_VAL_INT_PLUS_NANO; 379 + 380 + case PAC1921_CHAN_VSENSE: 381 + *val = pac1921_vsense_scales[priv->di_gain][0]; 382 + *val2 = pac1921_vsense_scales[priv->di_gain][1]; 383 + return IIO_VAL_INT_PLUS_NANO; 384 + 385 + case PAC1921_CHAN_CURRENT: 386 + *val = priv->current_scales[priv->di_gain][0]; 387 + *val2 = priv->current_scales[priv->di_gain][1]; 388 + return IIO_VAL_INT_PLUS_NANO; 389 + 390 + case PAC1921_CHAN_POWER: { 391 + /* 392 + * Power scale factor in mW: 393 + * Current scale (mA) * max_vbus (V) / dv_gain 394 + */ 395 + 396 + /* Get current scale based on di_gain */ 397 + int *curr_scale = priv->current_scales[priv->di_gain]; 398 + 399 + /* Convert current_scale from INT_PLUS_NANO to INT */ 400 + s64 tmp = curr_scale[0] * (s64)NANO + curr_scale[1]; 401 + 402 + /* Multiply by max_vbus (V) / dv_gain */ 403 + tmp *= PAC1921_MAX_VBUS_V >> (int)priv->dv_gain; 404 + 405 + /* Convert back to INT_PLUS_NANO */ 406 + *val = (int)div_s64_rem(tmp, NANO, val2); 407 + 408 + return IIO_VAL_INT_PLUS_NANO; 409 + } 410 + default: 411 + return -EINVAL; 412 + } 413 + 414 + case IIO_CHAN_INFO_OVERSAMPLING_RATIO: 415 + *val = pac1921_int_num_samples[priv->n_samples]; 416 + return IIO_VAL_INT; 417 + 418 + case IIO_CHAN_INFO_SAMP_FREQ: 419 + /* 420 + * The sampling frequency (Hz) is read-only and corresponds to 421 + * how often the device provides integrated measurements into 422 + * the result registers, thus it's 1/integration_period. 423 + * The integration period depends on the number of integration 424 + * samples, measurement resolution and post filters. 425 + * 426 + * 1/(integr_period_usecs/MICRO) = MICRO/integr_period_usecs 427 + */ 428 + *val = MICRO; 429 + *val2 = (int)priv->integr_period_usecs; 430 + return IIO_VAL_FRACTIONAL; 431 + 432 + default: 433 + return -EINVAL; 434 + } 435 + } 436 + 437 + static int pac1921_read_avail(struct iio_dev *indio_dev, 438 + struct iio_chan_spec const *chan, 439 + const int **vals, int *type, int *length, 440 + long mask) 441 + { 442 + switch (mask) { 443 + case IIO_CHAN_INFO_OVERSAMPLING_RATIO: 444 + *type = IIO_VAL_INT; 445 + *vals = pac1921_int_num_samples; 446 + *length = ARRAY_SIZE(pac1921_int_num_samples); 447 + return IIO_AVAIL_LIST; 448 + default: 449 + return -EINVAL; 450 + } 451 + } 452 + 453 + /* 454 + * Perform configuration update sequence: set the device into read state, then 455 + * write the config register and set the device back into integration state. 456 + * Also reset integration start time and mark first integration to be yet 457 + * completed. 458 + * 459 + * Must be called with lock held. 460 + */ 461 + static int pac1921_update_cfg_reg(struct pac1921_priv *priv, unsigned int reg, 462 + unsigned int mask, unsigned int val) 463 + { 464 + /* Enter READ state before configuration */ 465 + int ret = regmap_update_bits(priv->regmap, PAC1921_REG_INT_CFG, 466 + PAC1921_INT_CFG_INTEN, 0); 467 + if (ret) 468 + return ret; 469 + 470 + /* Update configuration value */ 471 + ret = regmap_update_bits(priv->regmap, reg, mask, val); 472 + if (ret) 473 + return ret; 474 + 475 + /* Re-enable integration */ 476 + ret = regmap_update_bits(priv->regmap, PAC1921_REG_INT_CFG, 477 + PAC1921_INT_CFG_INTEN, PAC1921_INT_CFG_INTEN); 478 + if (ret) 479 + return ret; 480 + 481 + /* 482 + * Reset integration started time and mark this integration period as 483 + * the first one so that new measurements will be considered as valid 484 + * only at the end of this integration period. 485 + */ 486 + priv->integr_started_time_jiffies = jiffies; 487 + priv->first_integr_done = false; 488 + 489 + return 0; 490 + } 491 + 492 + /* 493 + * Retrieve the index of the given scale (represented by scale_val and 494 + * scale_val2) from scales_tbl. The returned index (if found) is the log2 of 495 + * the gain corresponding to the given scale. 496 + * 497 + * Must be called with lock held if the scales_tbl can change runtime (e.g. for 498 + * the current scales table) 499 + */ 500 + static int pac1921_lookup_scale(const int (*const scales_tbl)[2], size_t size, 501 + int scale_val, int scale_val2) 502 + { 503 + for (unsigned int i = 0; i < size; i++) 504 + if (scales_tbl[i][0] == scale_val && 505 + scales_tbl[i][1] == scale_val2) 506 + return (int)i; 507 + 508 + return -EINVAL; 509 + } 510 + 511 + /* 512 + * Configure device with the given gain (only if changed) 513 + * 514 + * Must be called with lock held. 515 + */ 516 + static int pac1921_update_gain(struct pac1921_priv *priv, u8 *priv_val, u8 gain, 517 + unsigned int mask) 518 + { 519 + unsigned int reg_val; 520 + int ret; 521 + 522 + if (*priv_val == gain) 523 + return 0; 524 + 525 + reg_val = (gain << __ffs(mask)) & mask; 526 + ret = pac1921_update_cfg_reg(priv, PAC1921_REG_GAIN_CFG, mask, reg_val); 527 + if (ret) 528 + return ret; 529 + 530 + *priv_val = gain; 531 + 532 + return 0; 533 + } 534 + 535 + /* 536 + * Given a scale factor represented by scale_val and scale_val2 with format 537 + * IIO_VAL_INT_PLUS_NANO, find the corresponding gain value and write it to the 538 + * device. 539 + * 540 + * Must be called with lock held. 541 + */ 542 + static int pac1921_update_gain_from_scale(struct pac1921_priv *priv, 543 + struct iio_chan_spec const *chan, 544 + int scale_val, int scale_val2) 545 + { 546 + int ret; 547 + 548 + switch (chan->channel) { 549 + case PAC1921_CHAN_VBUS: 550 + ret = pac1921_lookup_scale(pac1921_vbus_scales, 551 + ARRAY_SIZE(pac1921_vbus_scales), 552 + scale_val, scale_val2); 553 + if (ret < 0) 554 + return ret; 555 + 556 + return pac1921_update_gain(priv, &priv->dv_gain, (u8)ret, 557 + PAC1921_GAIN_DV_GAIN_MASK); 558 + case PAC1921_CHAN_VSENSE: 559 + ret = pac1921_lookup_scale(pac1921_vsense_scales, 560 + ARRAY_SIZE(pac1921_vsense_scales), 561 + scale_val, scale_val2); 562 + if (ret < 0) 563 + return ret; 564 + 565 + return pac1921_update_gain(priv, &priv->di_gain, (u8)ret, 566 + PAC1921_GAIN_DI_GAIN_MASK); 567 + case PAC1921_CHAN_CURRENT: 568 + ret = pac1921_lookup_scale(priv->current_scales, 569 + ARRAY_SIZE(priv->current_scales), 570 + scale_val, scale_val2); 571 + if (ret < 0) 572 + return ret; 573 + 574 + return pac1921_update_gain(priv, &priv->di_gain, (u8)ret, 575 + PAC1921_GAIN_DI_GAIN_MASK); 576 + default: 577 + return -EINVAL; 578 + } 579 + } 580 + 581 + /* 582 + * Retrieve the index of the given number of samples from the constant table. 583 + * The returned index (if found) is the log2 of the given num_samples. 584 + */ 585 + static int pac1921_lookup_int_num_samples(int num_samples) 586 + { 587 + for (unsigned int i = 0; i < ARRAY_SIZE(pac1921_int_num_samples); i++) 588 + if (pac1921_int_num_samples[i] == num_samples) 589 + return (int)i; 590 + 591 + return -EINVAL; 592 + } 593 + 594 + /* 595 + * Update the device with the given number of integration samples. 596 + * 597 + * Must be called with lock held. 598 + */ 599 + static int pac1921_update_int_num_samples(struct pac1921_priv *priv, 600 + int num_samples) 601 + { 602 + unsigned int reg_val; 603 + u8 n_samples; 604 + int ret; 605 + 606 + ret = pac1921_lookup_int_num_samples(num_samples); 607 + if (ret < 0) 608 + return ret; 609 + 610 + n_samples = (u8)ret; 611 + 612 + if (priv->n_samples == n_samples) 613 + return 0; 614 + 615 + reg_val = FIELD_PREP(PAC1921_INT_CFG_SMPL_MASK, n_samples); 616 + 617 + ret = pac1921_update_cfg_reg(priv, PAC1921_REG_INT_CFG, 618 + PAC1921_INT_CFG_SMPL_MASK, reg_val); 619 + if (ret) 620 + return ret; 621 + 622 + priv->n_samples = n_samples; 623 + 624 + priv->integr_period_usecs = pac1921_int_periods_usecs[priv->n_samples]; 625 + 626 + return 0; 627 + } 628 + 629 + static int pac1921_write_raw_get_fmt(struct iio_dev *indio_dev, 630 + struct iio_chan_spec const *chan, 631 + long info) 632 + { 633 + switch (info) { 634 + case IIO_CHAN_INFO_SCALE: 635 + return IIO_VAL_INT_PLUS_NANO; 636 + case IIO_CHAN_INFO_OVERSAMPLING_RATIO: 637 + return IIO_VAL_INT; 638 + default: 639 + return -EINVAL; 640 + } 641 + } 642 + 643 + static int pac1921_write_raw(struct iio_dev *indio_dev, 644 + struct iio_chan_spec const *chan, int val, 645 + int val2, long mask) 646 + { 647 + struct pac1921_priv *priv = iio_priv(indio_dev); 648 + 649 + guard(mutex)(&priv->lock); 650 + 651 + switch (mask) { 652 + case IIO_CHAN_INFO_SCALE: 653 + return pac1921_update_gain_from_scale(priv, chan, val, val2); 654 + case IIO_CHAN_INFO_OVERSAMPLING_RATIO: 655 + return pac1921_update_int_num_samples(priv, val); 656 + default: 657 + return -EINVAL; 658 + } 659 + } 660 + 661 + static int pac1921_read_label(struct iio_dev *indio_dev, 662 + struct iio_chan_spec const *chan, char *label) 663 + { 664 + switch (chan->channel) { 665 + case PAC1921_CHAN_VBUS: 666 + return sprintf(label, "vbus\n"); 667 + case PAC1921_CHAN_VSENSE: 668 + return sprintf(label, "vsense\n"); 669 + case PAC1921_CHAN_CURRENT: 670 + return sprintf(label, "current\n"); 671 + case PAC1921_CHAN_POWER: 672 + return sprintf(label, "power\n"); 673 + default: 674 + return -EINVAL; 675 + } 676 + } 677 + 678 + static int pac1921_read_event_config(struct iio_dev *indio_dev, 679 + const struct iio_chan_spec *chan, 680 + enum iio_event_type type, 681 + enum iio_event_direction dir) 682 + { 683 + struct pac1921_priv *priv = iio_priv(indio_dev); 684 + 685 + guard(mutex)(&priv->lock); 686 + 687 + switch (chan->channel) { 688 + case PAC1921_CHAN_VBUS: 689 + return !!(priv->ovf_enabled_events & PAC1921_OVERFLOW_VBOV); 690 + case PAC1921_CHAN_VSENSE: 691 + case PAC1921_CHAN_CURRENT: 692 + return !!(priv->ovf_enabled_events & PAC1921_OVERFLOW_VSOV); 693 + case PAC1921_CHAN_POWER: 694 + return !!(priv->ovf_enabled_events & PAC1921_OVERFLOW_VPOV); 695 + default: 696 + return -EINVAL; 697 + } 698 + } 699 + 700 + static int pac1921_write_event_config(struct iio_dev *indio_dev, 701 + const struct iio_chan_spec *chan, 702 + enum iio_event_type type, 703 + enum iio_event_direction dir, int state) 704 + { 705 + struct pac1921_priv *priv = iio_priv(indio_dev); 706 + u8 ovf_bit; 707 + 708 + guard(mutex)(&priv->lock); 709 + 710 + switch (chan->channel) { 711 + case PAC1921_CHAN_VBUS: 712 + ovf_bit = PAC1921_OVERFLOW_VBOV; 713 + break; 714 + case PAC1921_CHAN_VSENSE: 715 + case PAC1921_CHAN_CURRENT: 716 + ovf_bit = PAC1921_OVERFLOW_VSOV; 717 + break; 718 + case PAC1921_CHAN_POWER: 719 + ovf_bit = PAC1921_OVERFLOW_VPOV; 720 + break; 721 + default: 722 + return -EINVAL; 723 + } 724 + 725 + if (state) 726 + priv->ovf_enabled_events |= ovf_bit; 727 + else 728 + priv->ovf_enabled_events &= ~ovf_bit; 729 + 730 + return 0; 731 + } 732 + 733 + static int pac1921_read_event_value(struct iio_dev *indio_dev, 734 + const struct iio_chan_spec *chan, 735 + enum iio_event_type type, 736 + enum iio_event_direction dir, 737 + enum iio_event_info info, int *val, 738 + int *val2) 739 + { 740 + switch (info) { 741 + case IIO_EV_INFO_VALUE: 742 + *val = PAC1921_RES_RESOLUTION; 743 + return IIO_VAL_INT; 744 + default: 745 + return -EINVAL; 746 + } 747 + } 748 + 749 + static const struct iio_info pac1921_iio = { 750 + .read_raw = pac1921_read_raw, 751 + .read_avail = pac1921_read_avail, 752 + .write_raw = pac1921_write_raw, 753 + .write_raw_get_fmt = pac1921_write_raw_get_fmt, 754 + .read_label = pac1921_read_label, 755 + .read_event_config = pac1921_read_event_config, 756 + .write_event_config = pac1921_write_event_config, 757 + .read_event_value = pac1921_read_event_value, 758 + }; 759 + 760 + static ssize_t pac1921_read_shunt_resistor(struct iio_dev *indio_dev, 761 + uintptr_t private, 762 + const struct iio_chan_spec *chan, 763 + char *buf) 764 + { 765 + struct pac1921_priv *priv = iio_priv(indio_dev); 766 + int vals[2]; 767 + 768 + if (chan->channel != PAC1921_CHAN_CURRENT) 769 + return -EINVAL; 770 + 771 + guard(mutex)(&priv->lock); 772 + 773 + vals[0] = (int)priv->rshunt_uohm; 774 + vals[1] = MICRO; 775 + 776 + return iio_format_value(buf, IIO_VAL_FRACTIONAL, 1, vals); 777 + } 778 + 779 + static ssize_t pac1921_write_shunt_resistor(struct iio_dev *indio_dev, 780 + uintptr_t private, 781 + const struct iio_chan_spec *chan, 782 + const char *buf, size_t len) 783 + { 784 + struct pac1921_priv *priv = iio_priv(indio_dev); 785 + u64 rshunt_uohm; 786 + int val, val_fract; 787 + int ret; 788 + 789 + if (chan->channel != PAC1921_CHAN_CURRENT) 790 + return -EINVAL; 791 + 792 + ret = iio_str_to_fixpoint(buf, 100000, &val, &val_fract); 793 + if (ret) 794 + return ret; 795 + 796 + rshunt_uohm = (u32)val * MICRO + (u32)val_fract; 797 + if (rshunt_uohm == 0 || rshunt_uohm > INT_MAX) 798 + return -EINVAL; 799 + 800 + guard(mutex)(&priv->lock); 801 + 802 + priv->rshunt_uohm = (u32)rshunt_uohm; 803 + 804 + pac1921_calc_current_scales(priv); 805 + 806 + return len; 807 + } 808 + 809 + /* 810 + * Emit on sysfs the list of available scales contained in scales_tbl 811 + * 812 + * TODO:: this function can be replaced with iio_format_avail_list() if the 813 + * latter will ever be exported. 814 + * 815 + * Must be called with lock held if the scales_tbl can change runtime (e.g. for 816 + * the current scales table) 817 + */ 818 + static ssize_t pac1921_format_scale_avail(const int (*const scales_tbl)[2], 819 + size_t size, char *buf) 820 + { 821 + ssize_t len = 0; 822 + 823 + for (unsigned int i = 0; i < size; i++) { 824 + if (i != 0) { 825 + len += sysfs_emit_at(buf, len, " "); 826 + if (len >= PAGE_SIZE) 827 + return -EFBIG; 828 + } 829 + len += sysfs_emit_at(buf, len, "%d.%09d", scales_tbl[i][0], 830 + scales_tbl[i][1]); 831 + if (len >= PAGE_SIZE) 832 + return -EFBIG; 833 + } 834 + 835 + len += sysfs_emit_at(buf, len, "\n"); 836 + return len; 837 + } 838 + 839 + /* 840 + * Read available scales for a specific channel 841 + * 842 + * NOTE: using extended info insted of iio.read_avail() because access to 843 + * current scales must be locked as they depend on shunt resistor which may 844 + * change runtime. Caller of iio.read_avail() would access the table unlocked 845 + * instead. 846 + */ 847 + static ssize_t pac1921_read_scale_avail(struct iio_dev *indio_dev, 848 + uintptr_t private, 849 + const struct iio_chan_spec *chan, 850 + char *buf) 851 + { 852 + struct pac1921_priv *priv = iio_priv(indio_dev); 853 + const int (*scales_tbl)[2]; 854 + size_t size; 855 + 856 + switch (chan->channel) { 857 + case PAC1921_CHAN_VBUS: 858 + scales_tbl = pac1921_vbus_scales; 859 + size = ARRAY_SIZE(pac1921_vbus_scales); 860 + return pac1921_format_scale_avail(scales_tbl, size, buf); 861 + 862 + case PAC1921_CHAN_VSENSE: 863 + scales_tbl = pac1921_vsense_scales; 864 + size = ARRAY_SIZE(pac1921_vsense_scales); 865 + return pac1921_format_scale_avail(scales_tbl, size, buf); 866 + 867 + case PAC1921_CHAN_CURRENT: { 868 + guard(mutex)(&priv->lock); 869 + scales_tbl = priv->current_scales; 870 + size = ARRAY_SIZE(priv->current_scales); 871 + return pac1921_format_scale_avail(scales_tbl, size, buf); 872 + } 873 + default: 874 + return -EINVAL; 875 + } 876 + } 877 + 878 + #define PAC1921_EXT_INFO_SCALE_AVAIL { \ 879 + .name = "scale_available", \ 880 + .read = pac1921_read_scale_avail, \ 881 + .shared = IIO_SEPARATE, \ 882 + } 883 + 884 + static const struct iio_chan_spec_ext_info pac1921_ext_info_voltage[] = { 885 + PAC1921_EXT_INFO_SCALE_AVAIL, 886 + {} 887 + }; 888 + 889 + static const struct iio_chan_spec_ext_info pac1921_ext_info_current[] = { 890 + PAC1921_EXT_INFO_SCALE_AVAIL, 891 + { 892 + .name = "shunt_resistor", 893 + .read = pac1921_read_shunt_resistor, 894 + .write = pac1921_write_shunt_resistor, 895 + .shared = IIO_SEPARATE, 896 + }, 897 + {} 898 + }; 899 + 900 + static const struct iio_event_spec pac1921_overflow_event[] = { 901 + { 902 + .type = IIO_EV_TYPE_THRESH, 903 + .dir = IIO_EV_DIR_RISING, 904 + .mask_shared_by_all = BIT(IIO_EV_INFO_VALUE), 905 + .mask_separate = BIT(IIO_EV_INFO_ENABLE), 906 + }, 907 + }; 908 + 909 + static const struct iio_chan_spec pac1921_channels[] = { 910 + { 911 + .type = IIO_VOLTAGE, 912 + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 913 + BIT(IIO_CHAN_INFO_SCALE), 914 + .info_mask_shared_by_all = 915 + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO) | 916 + BIT(IIO_CHAN_INFO_SAMP_FREQ), 917 + .info_mask_shared_by_all_available = 918 + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), 919 + .channel = PAC1921_CHAN_VBUS, 920 + .address = PAC1921_REG_VBUS, 921 + .scan_index = PAC1921_CHAN_VBUS, 922 + .scan_type = { 923 + .sign = 'u', 924 + .realbits = 10, 925 + .storagebits = 16, 926 + .endianness = IIO_CPU 927 + }, 928 + .indexed = 1, 929 + .event_spec = pac1921_overflow_event, 930 + .num_event_specs = ARRAY_SIZE(pac1921_overflow_event), 931 + .ext_info = pac1921_ext_info_voltage, 932 + }, 933 + { 934 + .type = IIO_VOLTAGE, 935 + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 936 + BIT(IIO_CHAN_INFO_SCALE), 937 + .info_mask_shared_by_all = 938 + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO) | 939 + BIT(IIO_CHAN_INFO_SAMP_FREQ), 940 + .info_mask_shared_by_all_available = 941 + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), 942 + .channel = PAC1921_CHAN_VSENSE, 943 + .address = PAC1921_REG_VSENSE, 944 + .scan_index = PAC1921_CHAN_VSENSE, 945 + .scan_type = { 946 + .sign = 'u', 947 + .realbits = 10, 948 + .storagebits = 16, 949 + .endianness = IIO_CPU 950 + }, 951 + .indexed = 1, 952 + .event_spec = pac1921_overflow_event, 953 + .num_event_specs = ARRAY_SIZE(pac1921_overflow_event), 954 + .ext_info = pac1921_ext_info_voltage, 955 + }, 956 + { 957 + .type = IIO_CURRENT, 958 + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 959 + BIT(IIO_CHAN_INFO_SCALE), 960 + .info_mask_shared_by_all = 961 + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO) | 962 + BIT(IIO_CHAN_INFO_SAMP_FREQ), 963 + .info_mask_shared_by_all_available = 964 + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), 965 + .channel = PAC1921_CHAN_CURRENT, 966 + .address = PAC1921_REG_VSENSE, 967 + .scan_index = PAC1921_CHAN_CURRENT, 968 + .scan_type = { 969 + .sign = 'u', 970 + .realbits = 10, 971 + .storagebits = 16, 972 + .endianness = IIO_CPU 973 + }, 974 + .event_spec = pac1921_overflow_event, 975 + .num_event_specs = ARRAY_SIZE(pac1921_overflow_event), 976 + .ext_info = pac1921_ext_info_current, 977 + }, 978 + { 979 + .type = IIO_POWER, 980 + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | 981 + BIT(IIO_CHAN_INFO_SCALE), 982 + .info_mask_shared_by_all = 983 + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO) | 984 + BIT(IIO_CHAN_INFO_SAMP_FREQ), 985 + .info_mask_shared_by_all_available = 986 + BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), 987 + .channel = PAC1921_CHAN_POWER, 988 + .address = PAC1921_REG_VPOWER, 989 + .scan_index = PAC1921_CHAN_POWER, 990 + .scan_type = { 991 + .sign = 'u', 992 + .realbits = 10, 993 + .storagebits = 16, 994 + .endianness = IIO_CPU 995 + }, 996 + .event_spec = pac1921_overflow_event, 997 + .num_event_specs = ARRAY_SIZE(pac1921_overflow_event), 998 + }, 999 + IIO_CHAN_SOFT_TIMESTAMP(PAC1921_NUM_MEAS_CHANS), 1000 + }; 1001 + 1002 + static irqreturn_t pac1921_trigger_handler(int irq, void *p) 1003 + { 1004 + struct iio_poll_func *pf = p; 1005 + struct iio_dev *idev = pf->indio_dev; 1006 + struct pac1921_priv *priv = iio_priv(idev); 1007 + int ret; 1008 + int bit; 1009 + int ch = 0; 1010 + 1011 + guard(mutex)(&priv->lock); 1012 + 1013 + if (!pac1921_data_ready(priv)) 1014 + goto done; 1015 + 1016 + ret = pac1921_check_push_overflow(idev, pf->timestamp); 1017 + if (ret) 1018 + goto done; 1019 + 1020 + iio_for_each_active_channel(idev, bit) { 1021 + u16 val; 1022 + 1023 + ret = pac1921_read_res(priv, idev->channels[ch].address, &val); 1024 + if (ret) 1025 + goto done; 1026 + 1027 + priv->scan.chan[ch++] = val; 1028 + } 1029 + 1030 + iio_push_to_buffers_with_timestamp(idev, &priv->scan, pf->timestamp); 1031 + 1032 + done: 1033 + iio_trigger_notify_done(idev->trig); 1034 + 1035 + return IRQ_HANDLED; 1036 + } 1037 + 1038 + /* 1039 + * Initialize device by writing initial configuration and putting it into 1040 + * integration state. 1041 + * 1042 + * Must be called with lock held when called after first initialization 1043 + * (e.g. from pm resume) 1044 + */ 1045 + static int pac1921_init(struct pac1921_priv *priv) 1046 + { 1047 + unsigned int val; 1048 + int ret; 1049 + 1050 + /* Enter READ state before configuration */ 1051 + ret = regmap_update_bits(priv->regmap, PAC1921_REG_INT_CFG, 1052 + PAC1921_INT_CFG_INTEN, 0); 1053 + if (ret) 1054 + return ret; 1055 + 1056 + /* Configure gains, use 14-bits measurement resolution (HW default) */ 1057 + val = FIELD_PREP(PAC1921_GAIN_DI_GAIN_MASK, priv->di_gain) | 1058 + FIELD_PREP(PAC1921_GAIN_DV_GAIN_MASK, priv->dv_gain); 1059 + ret = regmap_write(priv->regmap, PAC1921_REG_GAIN_CFG, val); 1060 + if (ret) 1061 + return ret; 1062 + 1063 + /* 1064 + * Configure integration: 1065 + * - num of integration samples 1066 + * - filters enabled (HW default) 1067 + * - set READ/INT pin override (RIOV) to control operation mode via 1068 + * register instead of pin 1069 + */ 1070 + val = FIELD_PREP(PAC1921_INT_CFG_SMPL_MASK, priv->n_samples) | 1071 + PAC1921_INT_CFG_VSFEN | PAC1921_INT_CFG_VBFEN | 1072 + PAC1921_INT_CFG_RIOV; 1073 + ret = regmap_write(priv->regmap, PAC1921_REG_INT_CFG, val); 1074 + if (ret) 1075 + return ret; 1076 + 1077 + /* 1078 + * Init control register: 1079 + * - VPower free run integration mode 1080 + * - OUT pin full scale range: 3V (HW detault) 1081 + * - no timeout, no sleep, no sleep override, no recalc (HW defaults) 1082 + */ 1083 + val = FIELD_PREP(PAC1921_CONTROL_MXSL_MASK, 1084 + PAC1921_MXSL_VPOWER_FREE_RUN); 1085 + ret = regmap_write(priv->regmap, PAC1921_REG_CONTROL, val); 1086 + if (ret) 1087 + return ret; 1088 + 1089 + /* Enable integration */ 1090 + ret = regmap_update_bits(priv->regmap, PAC1921_REG_INT_CFG, 1091 + PAC1921_INT_CFG_INTEN, PAC1921_INT_CFG_INTEN); 1092 + if (ret) 1093 + return ret; 1094 + 1095 + priv->first_integr_started = true; 1096 + priv->integr_started_time_jiffies = jiffies; 1097 + priv->integr_period_usecs = pac1921_int_periods_usecs[priv->n_samples]; 1098 + 1099 + return 0; 1100 + } 1101 + 1102 + static int pac1921_suspend(struct device *dev) 1103 + { 1104 + struct iio_dev *indio_dev = dev_get_drvdata(dev); 1105 + struct pac1921_priv *priv = iio_priv(indio_dev); 1106 + int ret; 1107 + 1108 + guard(mutex)(&priv->lock); 1109 + 1110 + priv->first_integr_started = false; 1111 + priv->first_integr_done = false; 1112 + 1113 + ret = regmap_update_bits(priv->regmap, PAC1921_REG_INT_CFG, 1114 + PAC1921_INT_CFG_INTEN, 0); 1115 + if (ret) 1116 + return ret; 1117 + 1118 + ret = regmap_update_bits(priv->regmap, PAC1921_REG_CONTROL, 1119 + PAC1921_CONTROL_SLEEP, PAC1921_CONTROL_SLEEP); 1120 + if (ret) 1121 + return ret; 1122 + 1123 + return regulator_disable(priv->vdd); 1124 + 1125 + } 1126 + 1127 + static int pac1921_resume(struct device *dev) 1128 + { 1129 + struct iio_dev *indio_dev = dev_get_drvdata(dev); 1130 + struct pac1921_priv *priv = iio_priv(indio_dev); 1131 + int ret; 1132 + 1133 + guard(mutex)(&priv->lock); 1134 + 1135 + ret = regulator_enable(priv->vdd); 1136 + if (ret) 1137 + return ret; 1138 + 1139 + msleep(PAC1921_POWERUP_TIME_MS); 1140 + 1141 + return pac1921_init(priv); 1142 + } 1143 + 1144 + static DEFINE_SIMPLE_DEV_PM_OPS(pac1921_pm_ops, pac1921_suspend, 1145 + pac1921_resume); 1146 + 1147 + static void pac1921_regulator_disable(void *data) 1148 + { 1149 + struct regulator *regulator = data; 1150 + 1151 + regulator_disable(regulator); 1152 + } 1153 + 1154 + static int pac1921_probe(struct i2c_client *client) 1155 + { 1156 + struct device *dev = &client->dev; 1157 + struct pac1921_priv *priv; 1158 + struct iio_dev *indio_dev; 1159 + int ret; 1160 + 1161 + indio_dev = devm_iio_device_alloc(dev, sizeof(*priv)); 1162 + if (!indio_dev) 1163 + return -ENOMEM; 1164 + 1165 + priv = iio_priv(indio_dev); 1166 + priv->client = client; 1167 + i2c_set_clientdata(client, indio_dev); 1168 + 1169 + priv->regmap = devm_regmap_init_i2c(client, &pac1921_regmap_config); 1170 + if (IS_ERR(priv->regmap)) 1171 + dev_err_probe(dev, (int)PTR_ERR(priv->regmap), 1172 + "Cannot initialize register map\n"); 1173 + 1174 + devm_mutex_init(dev, &priv->lock); 1175 + 1176 + priv->dv_gain = PAC1921_DEFAULT_DV_GAIN; 1177 + priv->di_gain = PAC1921_DEFAULT_DI_GAIN; 1178 + priv->n_samples = PAC1921_DEFAULT_NUM_SAMPLES; 1179 + 1180 + ret = device_property_read_u32(dev, "shunt-resistor-micro-ohms", 1181 + &priv->rshunt_uohm); 1182 + if (ret) 1183 + return dev_err_probe(dev, ret, 1184 + "Cannot read shunt resistor property\n"); 1185 + if (priv->rshunt_uohm == 0 || priv->rshunt_uohm > INT_MAX) 1186 + return dev_err_probe(dev, -EINVAL, 1187 + "Invalid shunt resistor: %u\n", 1188 + priv->rshunt_uohm); 1189 + 1190 + pac1921_calc_current_scales(priv); 1191 + 1192 + priv->vdd = devm_regulator_get(dev, "vdd"); 1193 + if (IS_ERR(priv->vdd)) 1194 + return dev_err_probe(dev, (int)PTR_ERR(priv->vdd), 1195 + "Cannot get vdd regulator\n"); 1196 + 1197 + ret = regulator_enable(priv->vdd); 1198 + if (ret) 1199 + return dev_err_probe(dev, ret, "Cannot enable vdd regulator\n"); 1200 + 1201 + ret = devm_add_action_or_reset(dev, pac1921_regulator_disable, 1202 + priv->vdd); 1203 + if (ret) 1204 + return dev_err_probe(dev, ret, 1205 + "Cannot add action for vdd regulator disposal\n"); 1206 + 1207 + msleep(PAC1921_POWERUP_TIME_MS); 1208 + 1209 + ret = pac1921_init(priv); 1210 + if (ret) 1211 + return dev_err_probe(dev, ret, "Cannot initialize device\n"); 1212 + 1213 + priv->iio_info = pac1921_iio; 1214 + 1215 + indio_dev->name = "pac1921"; 1216 + indio_dev->info = &priv->iio_info; 1217 + indio_dev->modes = INDIO_DIRECT_MODE; 1218 + indio_dev->channels = pac1921_channels; 1219 + indio_dev->num_channels = ARRAY_SIZE(pac1921_channels); 1220 + 1221 + ret = devm_iio_triggered_buffer_setup(dev, indio_dev, 1222 + &iio_pollfunc_store_time, 1223 + &pac1921_trigger_handler, NULL); 1224 + if (ret) 1225 + return dev_err_probe(dev, ret, 1226 + "Cannot setup IIO triggered buffer\n"); 1227 + 1228 + ret = devm_iio_device_register(dev, indio_dev); 1229 + if (ret) 1230 + return dev_err_probe(dev, ret, "Cannot register IIO device\n"); 1231 + 1232 + return 0; 1233 + } 1234 + 1235 + static const struct i2c_device_id pac1921_id[] = { 1236 + { .name = "pac1921", 0 }, 1237 + {} 1238 + }; 1239 + MODULE_DEVICE_TABLE(i2c, pac1921_id); 1240 + 1241 + static const struct of_device_id pac1921_of_match[] = { 1242 + { .compatible = "microchip,pac1921" }, 1243 + {} 1244 + }; 1245 + MODULE_DEVICE_TABLE(of, pac1921_of_match); 1246 + 1247 + static struct i2c_driver pac1921_driver = { 1248 + .driver = { 1249 + .name = "pac1921", 1250 + .pm = pm_sleep_ptr(&pac1921_pm_ops), 1251 + .of_match_table = pac1921_of_match, 1252 + }, 1253 + .probe = pac1921_probe, 1254 + .id_table = pac1921_id, 1255 + }; 1256 + 1257 + module_i2c_driver(pac1921_driver); 1258 + 1259 + MODULE_AUTHOR("Matteo Martelli <matteomartelli3@gmail.com>"); 1260 + MODULE_DESCRIPTION("IIO driver for PAC1921 High-Side Power/Current Monitor"); 1261 + MODULE_LICENSE("GPL");