1262 lines · c
1// SPDX-License-Identifier: GPL-2.0+2/*3 * IIO driver for PAC1921 High-Side Power/Current Monitor4 *5 * Copyright (C) 2024 Matteo Martelli <matteomartelli3@gmail.com>6 */7 8#include <linux/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 0x0020#define PAC1921_REG_INT_CFG 0x0121#define PAC1921_REG_CONTROL 0x0222#define PAC1921_REG_VBUS 0x1023#define PAC1921_REG_VSENSE 0x1224#define PAC1921_REG_OVERFLOW_STS 0x1C25#define PAC1921_REG_VPOWER 0x1D26 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)40enum 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 102351 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 10059#define PAC1921_MAX_VBUS_V 3260/* Time to first communication after power up (tINT_T) */61#define PAC1921_POWERUP_TIME_MS 2062/* Time from Sleep State to Start of Integration Period (tSLEEP_TO_INT) */63#define PAC1921_SLEEP_TO_INT_TIME_US 8664 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 voltage72 * format: IIO_VAL_INT_PLUS_NANO73 * unit: mV74 *75 * Vbus scale (mV) = max_vbus (mV) / dv_gain / resolution76 */77static 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 voltage88 * format: IIO_VAL_INT_PLUS_NANO89 * unit: mV90 *91 * Vsense scale (mV) = max_vsense (mV) / di_gain / resolution92 */93static 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 an106 * integration period.107 *108 * Changing the number of samples affects the integration period: higher the109 * number of samples, longer the integration period.110 *111 * These correspond to the oversampling ratios available exposed to userspace.112 */113static const int pac1921_int_num_samples[] = {114 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048115};116 117/*118 * The integration period depends on the configuration of number of integration119 * samples, measurement resolution and post filters. The following array120 * contains integration periods, in microsecs unit, based on table 4-5 from121 * datasheet considering power integration mode, 14-Bit resolution and post122 * filters on. Each index corresponds to a specific number of samples from 1123 * to 2048.124 */125static 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 */141static const struct regmap_range pac1921_regmap_wr_ranges[] = {142 regmap_reg_range(PAC1921_REG_GAIN_CFG, PAC1921_REG_CONTROL),143};144 145static 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 150static 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 155static 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 160static 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 167enum 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 4174 175struct 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 of183 * 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 */212static 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 238static 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 current249 * format: IIO_VAL_INT_PLUS_NANO250 * unit: mA251 *252 * Vsense LSB (nV) = max_vsense (nV) * di_gain / resolution253 * Current scale (mA) = Vsense LSB (nV) / shunt (uOhm)254 *255 * Must be called with held lock when updating after first initialization.256 */257static 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 */274static 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 register324 *325 * Result registers contain the most recent averaged values of Vbus, Vsense and326 * Vpower. Each value is 10 bits wide and spread across two consecutive 8 bit327 * registers, with 6 bit LSB zero padding.328 */329static 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 342static 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_gain394 */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 to421 * how often the device provides integrated measurements into422 * the result registers, thus it's 1/integration_period.423 * The integration period depends on the number of integration424 * samples, measurement resolution and post filters.425 *426 * 1/(integr_period_usecs/MICRO) = MICRO/integr_period_usecs427 */428 *val = MICRO;429 *val2 = (int)priv->integr_period_usecs;430 return IIO_VAL_FRACTIONAL;431 432 default:433 return -EINVAL;434 }435}436 437static 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, then455 * write the config register and set the device back into integration state.456 * Also reset integration start time and mark first integration to be yet457 * completed.458 *459 * Must be called with lock held.460 */461static 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 as483 * the first one so that new measurements will be considered as valid484 * 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 and494 * scale_val2) from scales_tbl. The returned index (if found) is the log2 of495 * the gain corresponding to the given scale.496 *497 * Must be called with lock held if the scales_tbl can change runtime (e.g. for498 * the current scales table)499 */500static 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 */516static 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 format537 * IIO_VAL_INT_PLUS_NANO, find the corresponding gain value and write it to the538 * device.539 *540 * Must be called with lock held.541 */542static 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 */585static 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 */599static 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 629static 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 643static 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 661static 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 678static 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 700static 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 else728 priv->ovf_enabled_events &= ~ovf_bit;729 730 return 0;731}732 733static 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 749static 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 760static 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 779static 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_tbl811 *812 * TODO:: this function can be replaced with iio_format_avail_list() if the813 * latter will ever be exported.814 *815 * Must be called with lock held if the scales_tbl can change runtime (e.g. for816 * the current scales table)817 */818static 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 channel841 *842 * NOTE: using extended info insted of iio.read_avail() because access to843 * current scales must be locked as they depend on shunt resistor which may844 * change runtime. Caller of iio.read_avail() would access the table unlocked845 * instead.846 */847static 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 884static const struct iio_chan_spec_ext_info pac1921_ext_info_voltage[] = {885 PAC1921_EXT_INFO_SCALE_AVAIL,886 {}887};888 889static 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 900static 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 909static 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_CPU927 },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_CPU950 },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_CPU973 },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_CPU995 },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 1002static 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 1032done: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 into1040 * integration state.1041 *1042 * Must be called with lock held when called after first initialization1043 * (e.g. from pm resume)1044 */1045static 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 samples1066 * - filters enabled (HW default)1067 * - set READ/INT pin override (RIOV) to control operation mode via1068 * register instead of pin1069 */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 mode1080 * - 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 1102static 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 1127static 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 1144static DEFINE_SIMPLE_DEV_PM_OPS(pac1921_pm_ops, pac1921_suspend,1145 pac1921_resume);1146 1147static void pac1921_regulator_disable(void *data)1148{1149 struct regulator *regulator = data;1150 1151 regulator_disable(regulator);1152}1153 1154static 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 return 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 1235static const struct i2c_device_id pac1921_id[] = {1236 { .name = "pac1921", 0 },1237 { }1238};1239MODULE_DEVICE_TABLE(i2c, pac1921_id);1240 1241static const struct of_device_id pac1921_of_match[] = {1242 { .compatible = "microchip,pac1921" },1243 { }1244};1245MODULE_DEVICE_TABLE(of, pac1921_of_match);1246 1247static 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 1257module_i2c_driver(pac1921_driver);1258 1259MODULE_AUTHOR("Matteo Martelli <matteomartelli3@gmail.com>");1260MODULE_DESCRIPTION("IIO driver for PAC1921 High-Side Power/Current Monitor");1261MODULE_LICENSE("GPL");1262