Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a405b00e authored by Guenter Roeck's avatar Guenter Roeck Committed by Jonathan Cameron
Browse files

iio/adc: (max1363) Add support for external reference voltage



Implement external reference voltage as regulator named "vref".

Signed-off-by: default avatarGuenter Roeck <linux@roeck-us.net>
Signed-off-by: default avatarJonathan Cameron <jic23@kernel.org>
parent 7c3e8675
Loading
Loading
Loading
Loading
+39 −13
Original line number Diff line number Diff line
@@ -163,6 +163,8 @@ struct max1363_chip_info {
 * @mask_low:		bitmask for enabled low thresholds
 * @thresh_high:	high threshold values
 * @thresh_low:		low threshold values
 * @vref:		Reference voltage regulator
 * @vref_uv:		Actual (external or internal) reference voltage
 */
struct max1363_state {
	struct i2c_client		*client;
@@ -182,6 +184,8 @@ struct max1363_state {
	/* 4x unipolar first then the fours bipolar ones */
	s16				thresh_high[8];
	s16				thresh_low[8];
	struct regulator		*vref;
	u32				vref_uv;
};

#define MAX1363_MODE_SINGLE(_num, _mask) {				\
@@ -393,6 +397,8 @@ static int max1363_read_raw(struct iio_dev *indio_dev,
{
	struct max1363_state *st = iio_priv(indio_dev);
	int ret;
	unsigned long scale_uv;

	switch (m) {
	case IIO_CHAN_INFO_RAW:
		ret = max1363_read_single_chan(indio_dev, chan, val, m);
@@ -400,16 +406,10 @@ static int max1363_read_raw(struct iio_dev *indio_dev,
			return ret;
		return IIO_VAL_INT;
	case IIO_CHAN_INFO_SCALE:
		if ((1 << (st->chip_info->bits + 1)) >
		    st->chip_info->int_vref_mv) {
			*val = 0;
			*val2 = 500000;
		scale_uv = st->vref_uv >> st->chip_info->bits;
		*val = scale_uv / 1000;
		*val2 = (scale_uv % 1000) * 1000;
		return IIO_VAL_INT_PLUS_MICRO;
		} else {
			*val = (st->chip_info->int_vref_mv)
				>> st->chip_info->bits;
			return IIO_VAL_INT;
		}
	default:
		return -EINVAL;
	}
@@ -1390,12 +1390,16 @@ static const struct max1363_chip_info max1363_chip_info_tbl[] = {

static int max1363_initial_setup(struct max1363_state *st)
{
	st->setupbyte = MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_VDD
		| MAX1363_SETUP_POWER_UP_INT_REF
		| MAX1363_SETUP_INT_CLOCK
	st->setupbyte = MAX1363_SETUP_INT_CLOCK
		| MAX1363_SETUP_UNIPOLAR
		| MAX1363_SETUP_NORESET;

	if (st->vref)
		st->setupbyte |= MAX1363_SETUP_AIN3_IS_REF_EXT_TO_REF;
	else
		st->setupbyte |= MAX1363_SETUP_POWER_UP_INT_REF
		  | MAX1363_SETUP_AIN3_IS_AIN3_REF_IS_INT;

	/* Set scan mode writes the config anyway so wait until then */
	st->setupbyte = MAX1363_SETUP_BYTE(st->setupbyte);
	st->current_mode = &max1363_mode_table[st->chip_info->default_mode];
@@ -1491,6 +1495,7 @@ static int max1363_probe(struct i2c_client *client,
	int ret;
	struct max1363_state *st;
	struct iio_dev *indio_dev;
	struct regulator *vref;

	indio_dev = iio_device_alloc(sizeof(struct max1363_state));
	if (indio_dev == NULL) {
@@ -1521,6 +1526,23 @@ static int max1363_probe(struct i2c_client *client,
	st->chip_info = &max1363_chip_info_tbl[id->driver_data];
	st->client = client;

	st->vref_uv = st->chip_info->int_vref_mv * 1000;
	vref = devm_regulator_get(&client->dev, "vref");
	if (!IS_ERR(vref)) {
		int vref_uv;

		ret = regulator_enable(vref);
		if (ret)
			goto error_disable_reg;
		st->vref = vref;
		vref_uv = regulator_get_voltage(vref);
		if (vref_uv <= 0) {
			ret = -EINVAL;
			goto error_disable_reg;
		}
		st->vref_uv = vref_uv;
	}

	ret = max1363_alloc_scan_masks(indio_dev);
	if (ret)
		goto error_disable_reg;
@@ -1562,6 +1584,8 @@ static int max1363_probe(struct i2c_client *client,
error_uninit_buffer:
	iio_triggered_buffer_cleanup(indio_dev);
error_disable_reg:
	if (st->vref)
		regulator_disable(st->vref);
	regulator_disable(st->reg);
error_unregister_map:
	iio_map_array_unregister(indio_dev);
@@ -1578,6 +1602,8 @@ static int max1363_remove(struct i2c_client *client)

	iio_device_unregister(indio_dev);
	iio_triggered_buffer_cleanup(indio_dev);
	if (st->vref)
		regulator_disable(st->vref);
	regulator_disable(st->reg);
	iio_map_array_unregister(indio_dev);
	iio_device_free(indio_dev);