brintos

brintos / linux-shallow public Read only

0
0
Text · 32.6 KiB · 36e813d Raw
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