// SPDX-License-Identifier: GPL-2.0-only
/*
 * Driver for the Yamaha YAS magnetic sensors, often used in Samsung
 * mobile phones. While all are not yet handled because of lacking
 * hardware, expand this driver to handle the different variants:
 *
 * YAS530 MS-3E (2011 Samsung Galaxy S Advance)
 * YAS532 MS-3R (2011 Samsung Galaxy S4)
 * YAS533 MS-3F (Vivo 1633, 1707, V3, Y21L)
 * (YAS534 is a magnetic switch, not handled)
 * YAS535 MS-6C
 * YAS536 MS-3W
 * YAS537 MS-3T (2015 Samsung Galaxy S6, Note 5, Xiaomi)
 * YAS539 MS-3S (2018 Samsung Galaxy A7 SM-A750FN)
 *
 * Code functions found in the MPU3050 YAS530 and YAS532 drivers
 * named "inv_compass" in the Tegra Android kernel tree.
 * Copyright (C) 2012 InvenSense Corporation
 *
 * Author: Linus Walleij <linus.walleij@linaro.org>
 */
#include <linux/bitfield.h>
#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/gpio/consumer.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/mod_devicetable.h>
#include <linux/mutex.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/random.h>

#include <linux/iio/buffer.h>
#include <linux/iio/iio.h>
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>

#include <asm/unaligned.h>

/* This register map covers YAS530 and YAS532 but differs in YAS 537 and YAS539 */
#define YAS5XX_DEVICE_ID		0x80
#define YAS5XX_ACTUATE_INIT_COIL	0x81
#define YAS5XX_MEASURE			0x82
#define YAS5XX_CONFIG			0x83
#define YAS5XX_MEASURE_INTERVAL		0x84
#define YAS5XX_OFFSET_X			0x85 /* [-31 .. 31] */
#define YAS5XX_OFFSET_Y1		0x86 /* [-31 .. 31] */
#define YAS5XX_OFFSET_Y2		0x87 /* [-31 .. 31] */
#define YAS5XX_TEST1			0x88
#define YAS5XX_TEST2			0x89
#define YAS5XX_CAL			0x90
#define YAS5XX_MEASURE_DATA		0xB0

/* Bits in the YAS5xx config register */
#define YAS5XX_CONFIG_INTON		BIT(0) /* Interrupt on? */
#define YAS5XX_CONFIG_INTHACT		BIT(1) /* Interrupt active high? */
#define YAS5XX_CONFIG_CCK_MASK		GENMASK(4, 2)
#define YAS5XX_CONFIG_CCK_SHIFT		2

/* Bits in the measure command register */
#define YAS5XX_MEASURE_START		BIT(0)
#define YAS5XX_MEASURE_LDTC		BIT(1)
#define YAS5XX_MEASURE_FORS		BIT(2)
#define YAS5XX_MEASURE_DLYMES		BIT(4)

/* Bits in the measure data register */
#define YAS5XX_MEASURE_DATA_BUSY	BIT(7)

#define YAS530_DEVICE_ID		0x01 /* YAS530 (MS-3E) */
#define YAS530_VERSION_A		0 /* YAS530 (MS-3E A) */
#define YAS530_VERSION_B		1 /* YAS530B (MS-3E B) */
#define YAS530_VERSION_A_COEF		380
#define YAS530_VERSION_B_COEF		550
#define YAS530_DATA_BITS		12
#define YAS530_DATA_CENTER		BIT(YAS530_DATA_BITS - 1)
#define YAS530_DATA_OVERFLOW		(BIT(YAS530_DATA_BITS) - 1)

#define YAS532_DEVICE_ID		0x02 /* YAS532/YAS533 (MS-3R/F) */
#define YAS532_VERSION_AB		0 /* YAS532/533 AB (MS-3R/F AB) */
#define YAS532_VERSION_AC		1 /* YAS532/533 AC (MS-3R/F AC) */
#define YAS532_VERSION_AB_COEF		1800
#define YAS532_VERSION_AC_COEF_X	850
#define YAS532_VERSION_AC_COEF_Y1	750
#define YAS532_VERSION_AC_COEF_Y2	750
#define YAS532_DATA_BITS		13
#define YAS532_DATA_CENTER		BIT(YAS532_DATA_BITS - 1)
#define YAS532_DATA_OVERFLOW		(BIT(YAS532_DATA_BITS) - 1)
#define YAS532_20DEGREES		390 /* Looks like Kelvin */

/* These variant IDs are known from code dumps */
#define YAS537_DEVICE_ID		0x07 /* YAS537 (MS-3T) */
#define YAS539_DEVICE_ID		0x08 /* YAS539 (MS-3S) */

/* Turn off device regulators etc after 5 seconds of inactivity */
#define YAS5XX_AUTOSUSPEND_DELAY_MS	5000

struct yas5xx_calibration {
	/* Linearization calibration x, y1, y2 */
	s32 r[3];
	u32 f[3];
	/* Temperature compensation calibration */
	s32 Cx, Cy1, Cy2;
	/* Misc calibration coefficients */
	s32 a2, a3, a4, a5, a6, a7, a8, a9, k;
	/* clock divider */
	u8 dck;
};

/**
 * struct yas5xx - state container for the YAS5xx driver
 * @dev: parent device pointer
 * @devid: device ID number
 * @version: device version
 * @name: device name
 * @calibration: calibration settings from the OTP storage
 * @hard_offsets: offsets for each axis measured with initcoil actuated
 * @orientation: mounting matrix, flipped axis etc
 * @map: regmap to access the YAX5xx registers over I2C
 * @regs: the vdd and vddio power regulators
 * @reset: optional GPIO line used for handling RESET
 * @lock: locks the magnetometer for exclusive use during a measurement (which
 * involves several register transactions so the regmap lock is not enough)
 * so that measurements get serialized in a first-come-first serve manner
 * @scan: naturally aligned measurements
 */
struct yas5xx {
	struct device *dev;
	unsigned int devid;
	unsigned int version;
	char name[16];
	struct yas5xx_calibration calibration;
	s8 hard_offsets[3];
	struct iio_mount_matrix orientation;
	struct regmap *map;
	struct regulator_bulk_data regs[2];
	struct gpio_desc *reset;
	struct mutex lock;
	/*
	 * The scanout is 4 x 32 bits in CPU endianness.
	 * Ensure timestamp is naturally aligned
	 */
	struct {
		s32 channels[4];
		s64 ts __aligned(8);
	} scan;
};

/* On YAS530 the x, y1 and y2 values are 12 bits */
static u16 yas530_extract_axis(u8 *data)
{
	u16 val;

	/*
	 * These are the bits used in a 16bit word:
	 * 15 14 13 12 11 10 9  8  7  6  5  4  3  2  1  0
	 *    x  x  x  x  x  x  x  x  x  x  x  x
	 */
	val = get_unaligned_be16(&data[0]);
	val = FIELD_GET(GENMASK(14, 3), val);
	return val;
}

/* On YAS532 the x, y1 and y2 values are 13 bits */
static u16 yas532_extract_axis(u8 *data)
{
	u16 val;

	/*
	 * These are the bits used in a 16bit word:
	 * 15 14 13 12 11 10 9  8  7  6  5  4  3  2  1  0
	 *    x  x  x  x  x  x  x  x  x  x  x  x  x
	 */
	val = get_unaligned_be16(&data[0]);
	val = FIELD_GET(GENMASK(14, 2), val);
	return val;
}

/**
 * yas5xx_measure() - Make a measure from the hardware
 * @yas5xx: The device state
 * @t: the raw temperature measurement
 * @x: the raw x axis measurement
 * @y1: the y1 axis measurement
 * @y2: the y2 axis measurement
 * @return: 0 on success or error code
 */
static int yas5xx_measure(struct yas5xx *yas5xx, u16 *t, u16 *x, u16 *y1, u16 *y2)
{
	unsigned int busy;
	u8 data[8];
	int ret;
	u16 val;

	mutex_lock(&yas5xx->lock);
	ret = regmap_write(yas5xx->map, YAS5XX_MEASURE, YAS5XX_MEASURE_START);
	if (ret < 0)
		goto out_unlock;

	/*
	 * Typical time to measure 1500 us, max 2000 us so wait min 500 us
	 * and at most 20000 us (one magnitude more than the datsheet max)
	 * before timeout.
	 */
	ret = regmap_read_poll_timeout(yas5xx->map, YAS5XX_MEASURE_DATA, busy,
				       !(busy & YAS5XX_MEASURE_DATA_BUSY),
				       500, 20000);
	if (ret) {
		dev_err(yas5xx->dev, "timeout waiting for measurement\n");
		goto out_unlock;
	}

	ret = regmap_bulk_read(yas5xx->map, YAS5XX_MEASURE_DATA,
			       data, sizeof(data));
	if (ret)
		goto out_unlock;

	mutex_unlock(&yas5xx->lock);

	switch (yas5xx->devid) {
	case YAS530_DEVICE_ID:
		/*
		 * The t value is 9 bits in big endian format
		 * These are the bits used in a 16bit word:
		 * 15 14 13 12 11 10 9  8  7  6  5  4  3  2  1  0
		 *    x  x  x  x  x  x  x  x  x
		 */
		val = get_unaligned_be16(&data[0]);
		val = FIELD_GET(GENMASK(14, 6), val);
		*t = val;
		*x = yas530_extract_axis(&data[2]);
		*y1 = yas530_extract_axis(&data[4]);
		*y2 = yas530_extract_axis(&data[6]);
		break;
	case YAS532_DEVICE_ID:
		/*
		 * The t value is 10 bits in big endian format
		 * These are the bits used in a 16bit word:
		 * 15 14 13 12 11 10 9  8  7  6  5  4  3  2  1  0
		 *    x  x  x  x  x  x  x  x  x  x
		 */
		val = get_unaligned_be16(&data[0]);
		val = FIELD_GET(GENMASK(14, 5), val);
		*t = val;
		*x = yas532_extract_axis(&data[2]);
		*y1 = yas532_extract_axis(&data[4]);
		*y2 = yas532_extract_axis(&data[6]);
		break;
	default:
		dev_err(yas5xx->dev, "unknown data format\n");
		ret = -EINVAL;
		break;
	}

	return ret;

out_unlock:
	mutex_unlock(&yas5xx->lock);
	return ret;
}

static s32 yas5xx_linearize(struct yas5xx *yas5xx, u16 val, int axis)
{
	struct yas5xx_calibration *c = &yas5xx->calibration;
	static const s32 yas532ac_coef[] = {
		YAS532_VERSION_AC_COEF_X,
		YAS532_VERSION_AC_COEF_Y1,
		YAS532_VERSION_AC_COEF_Y2,
	};
	s32 coef;

	/* Select coefficients */
	switch (yas5xx->devid) {
	case YAS530_DEVICE_ID:
		if (yas5xx->version == YAS530_VERSION_A)
			coef = YAS530_VERSION_A_COEF;
		else
			coef = YAS530_VERSION_B_COEF;
		break;
	case YAS532_DEVICE_ID:
		if (yas5xx->version == YAS532_VERSION_AB)
			coef = YAS532_VERSION_AB_COEF;
		else
			/* Elaborate coefficients */
			coef = yas532ac_coef[axis];
		break;
	default:
		dev_err(yas5xx->dev, "unknown device type\n");
		return val;
	}
	/*
	 * Linearization formula:
	 *
	 * x' = x - (3721 + 50 * f) + (xoffset - r) * c
	 *
	 * Where f and r are calibration values, c is a per-device
	 * and sometimes per-axis coefficient.
	 */
	return val - (3721 + 50 * c->f[axis]) +
		(yas5xx->hard_offsets[axis] - c->r[axis]) * coef;
}

/**
 * yas5xx_get_measure() - Measure a sample of all axis and process
 * @yas5xx: The device state
 * @to: Temperature out
 * @xo: X axis out
 * @yo: Y axis out
 * @zo: Z axis out
 * @return: 0 on success or error code
 *
 * Returned values are in nanotesla according to some code.
 */
static int yas5xx_get_measure(struct yas5xx *yas5xx, s32 *to, s32 *xo, s32 *yo, s32 *zo)
{
	struct yas5xx_calibration *c = &yas5xx->calibration;
	u16 t, x, y1, y2;
	/* These are "signed x, signed y1 etc */
	s32 sx, sy1, sy2, sy, sz;
	int ret;

	/* We first get raw data that needs to be translated to [x,y,z] */
	ret = yas5xx_measure(yas5xx, &t, &x, &y1, &y2);
	if (ret)
		return ret;

	/* Do some linearization if available */
	sx = yas5xx_linearize(yas5xx, x, 0);
	sy1 = yas5xx_linearize(yas5xx, y1, 1);
	sy2 = yas5xx_linearize(yas5xx, y2, 2);

	/*
	 * Temperature compensation for x, y1, y2 respectively:
	 *
	 *          Cx * t
	 * x' = x - ------
	 *           100
	 */
	sx = sx - (c->Cx * t) / 100;
	sy1 = sy1 - (c->Cy1 * t) / 100;
	sy2 = sy2 - (c->Cy2 * t) / 100;

	/*
	 * Break y1 and y2 into y and z, y1 and y2 are apparently encoding
	 * y and z.
	 */
	sy = sy1 - sy2;
	sz = -sy1 - sy2;

	/*
	 * FIXME: convert to Celsius? Just guessing this is given
	 * as 1/10:s of degrees so multiply by 100 to get millicentigrades.
	 */
	*to = t * 100;
	/*
	 * Calibrate [x,y,z] with some formulas like this:
	 *
	 *            100 * x + a_2 * y + a_3 * z
	 *  x' = k *  ---------------------------
	 *                        10
	 *
	 *           a_4 * x + a_5 * y + a_6 * z
	 *  y' = k * ---------------------------
	 *                        10
	 *
	 *           a_7 * x + a_8 * y + a_9 * z
	 *  z' = k * ---------------------------
	 *                        10
	 */
	*xo = c->k * ((100 * sx + c->a2 * sy + c->a3 * sz) / 10);
	*yo = c->k * ((c->a4 * sx + c->a5 * sy + c->a6 * sz) / 10);
	*zo = c->k * ((c->a7 * sx + c->a8 * sy + c->a9 * sz) / 10);

	return 0;
}

static int yas5xx_read_raw(struct iio_dev *indio_dev,
			   struct iio_chan_spec const *chan,
			   int *val, int *val2,
			   long mask)
{
	struct yas5xx *yas5xx = iio_priv(indio_dev);
	s32 t, x, y, z;
	int ret;

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		pm_runtime_get_sync(yas5xx->dev);
		ret = yas5xx_get_measure(yas5xx, &t, &x, &y, &z);
		pm_runtime_mark_last_busy(yas5xx->dev);
		pm_runtime_put_autosuspend(yas5xx->dev);
		if (ret)
			return ret;
		switch (chan->address) {
		case 0:
			*val = t;
			break;
		case 1:
			*val = x;
			break;
		case 2:
			*val = y;
			break;
		case 3:
			*val = z;
			break;
		default:
			dev_err(yas5xx->dev, "unknown channel\n");
			return -EINVAL;
		}
		return IIO_VAL_INT;
	case IIO_CHAN_INFO_SCALE:
		if (chan->address == 0) {
			/* Temperature is unscaled */
			*val = 1;
			return IIO_VAL_INT;
		}
		/*
		 * The axis values are in nanotesla according to the vendor
		 * drivers, but is clearly in microtesla according to
		 * experiments. Since 1 uT = 0.01 Gauss, we need to divide
		 * by 100000000 (10^8) to get to Gauss from the raw value.
		 */
		*val = 1;
		*val2 = 100000000;
		return IIO_VAL_FRACTIONAL;
	default:
		/* Unknown request */
		return -EINVAL;
	}
}

static void yas5xx_fill_buffer(struct iio_dev *indio_dev)
{
	struct yas5xx *yas5xx = iio_priv(indio_dev);
	s32 t, x, y, z;
	int ret;

	pm_runtime_get_sync(yas5xx->dev);
	ret = yas5xx_get_measure(yas5xx, &t, &x, &y, &z);
	pm_runtime_mark_last_busy(yas5xx->dev);
	pm_runtime_put_autosuspend(yas5xx->dev);
	if (ret) {
		dev_err(yas5xx->dev, "error refilling buffer\n");
		return;
	}
	yas5xx->scan.channels[0] = t;
	yas5xx->scan.channels[1] = x;
	yas5xx->scan.channels[2] = y;
	yas5xx->scan.channels[3] = z;
	iio_push_to_buffers_with_timestamp(indio_dev, &yas5xx->scan,
					   iio_get_time_ns(indio_dev));
}

static irqreturn_t yas5xx_handle_trigger(int irq, void *p)
{
	const struct iio_poll_func *pf = p;
	struct iio_dev *indio_dev = pf->indio_dev;

	yas5xx_fill_buffer(indio_dev);
	iio_trigger_notify_done(indio_dev->trig);

	return IRQ_HANDLED;
}


static const struct iio_mount_matrix *
yas5xx_get_mount_matrix(const struct iio_dev *indio_dev,
			const struct iio_chan_spec *chan)
{
	struct yas5xx *yas5xx = iio_priv(indio_dev);

	return &yas5xx->orientation;
}

static const struct iio_chan_spec_ext_info yas5xx_ext_info[] = {
	IIO_MOUNT_MATRIX(IIO_SHARED_BY_DIR, yas5xx_get_mount_matrix),
	{ }
};

#define YAS5XX_AXIS_CHANNEL(axis, index)				\
	{								\
		.type = IIO_MAGN,					\
		.modified = 1,						\
		.channel2 = IIO_MOD_##axis,				\
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |		\
			BIT(IIO_CHAN_INFO_SCALE),			\
		.ext_info = yas5xx_ext_info,				\
		.address = index,					\
		.scan_index = index,					\
		.scan_type = {						\
			.sign = 's',					\
			.realbits = 32,					\
			.storagebits = 32,				\
			.endianness = IIO_CPU,				\
		},							\
	}

static const struct iio_chan_spec yas5xx_channels[] = {
	{
		.type = IIO_TEMP,
		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
		.address = 0,
		.scan_index = 0,
		.scan_type = {
			.sign = 'u',
			.realbits = 32,
			.storagebits = 32,
			.endianness = IIO_CPU,
		},
	},
	YAS5XX_AXIS_CHANNEL(X, 1),
	YAS5XX_AXIS_CHANNEL(Y, 2),
	YAS5XX_AXIS_CHANNEL(Z, 3),
	IIO_CHAN_SOFT_TIMESTAMP(4),
};

static const unsigned long yas5xx_scan_masks[] = { GENMASK(3, 0), 0 };

static const struct iio_info yas5xx_info = {
	.read_raw = &yas5xx_read_raw,
};

static bool yas5xx_volatile_reg(struct device *dev, unsigned int reg)
{
	return reg == YAS5XX_ACTUATE_INIT_COIL ||
		reg == YAS5XX_MEASURE ||
		(reg >= YAS5XX_MEASURE_DATA && reg <= YAS5XX_MEASURE_DATA + 8);
}

/* TODO: enable regmap cache, using mark dirty and sync at runtime resume */
static const struct regmap_config yas5xx_regmap_config = {
	.reg_bits = 8,
	.val_bits = 8,
	.max_register = 0xff,
	.volatile_reg = yas5xx_volatile_reg,
};

/**
 * yas53x_extract_calibration() - extracts the a2-a9 and k calibration
 * @data: the bitfield to use
 * @c: the calibration to populate
 */
static void yas53x_extract_calibration(u8 *data, struct yas5xx_calibration *c)
{
	u64 val = get_unaligned_be64(data);

	/*
	 * Bitfield layout for the axis calibration data, for factor
	 * a2 = 2 etc, k = k, c = clock divider
	 *
	 * n   7 6 5 4 3 2 1 0
	 * 0 [ 2 2 2 2 2 2 3 3 ] bits 63 .. 56
	 * 1 [ 3 3 4 4 4 4 4 4 ] bits 55 .. 48
	 * 2 [ 5 5 5 5 5 5 6 6 ] bits 47 .. 40
	 * 3 [ 6 6 6 6 7 7 7 7 ] bits 39 .. 32
	 * 4 [ 7 7 7 8 8 8 8 8 ] bits 31 .. 24
	 * 5 [ 8 9 9 9 9 9 9 9 ] bits 23 .. 16
	 * 6 [ 9 k k k k k c c ] bits 15 .. 8
	 * 7 [ c x x x x x x x ] bits  7 .. 0
	 */
	c->a2 = FIELD_GET(GENMASK_ULL(63, 58), val) - 32;
	c->a3 = FIELD_GET(GENMASK_ULL(57, 54), val) - 8;
	c->a4 = FIELD_GET(GENMASK_ULL(53, 48), val) - 32;
	c->a5 = FIELD_GET(GENMASK_ULL(47, 42), val) + 38;
	c->a6 = FIELD_GET(GENMASK_ULL(41, 36), val) - 32;
	c->a7 = FIELD_GET(GENMASK_ULL(35, 29), val) - 64;
	c->a8 = FIELD_GET(GENMASK_ULL(28, 23), val) - 32;
	c->a9 = FIELD_GET(GENMASK_ULL(22, 15), val);
	c->k = FIELD_GET(GENMASK_ULL(14, 10), val) + 10;
	c->dck = FIELD_GET(GENMASK_ULL(9, 7), val);
}

static int yas530_get_calibration_data(struct yas5xx *yas5xx)
{
	struct yas5xx_calibration *c = &yas5xx->calibration;
	u8 data[16];
	u32 val;
	int ret;

	/* Dummy read, first read is ALWAYS wrong */
	ret = regmap_bulk_read(yas5xx->map, YAS5XX_CAL, data, sizeof(data));
	if (ret)
		return ret;

	/* Actual calibration readout */
	ret = regmap_bulk_read(yas5xx->map, YAS5XX_CAL, data, sizeof(data));
	if (ret)
		return ret;
	dev_dbg(yas5xx->dev, "calibration data: %*ph\n", 14, data);

	add_device_randomness(data, sizeof(data));
	yas5xx->version = data[15] & GENMASK(1, 0);

	/* Extract the calibration from the bitfield */
	c->Cx = data[0] * 6 - 768;
	c->Cy1 = data[1] * 6 - 768;
	c->Cy2 = data[2] * 6 - 768;
	yas53x_extract_calibration(&data[3], c);

	/*
	 * Extract linearization:
	 * Linearization layout in the 32 bits at byte 11:
	 * The r factors are 6 bit values where bit 5 is the sign
	 *
	 * n    7  6  5  4  3  2  1  0
	 * 0 [ xx xx xx r0 r0 r0 r0 r0 ] bits 31 .. 24
	 * 1 [ r0 f0 f0 r1 r1 r1 r1 r1 ] bits 23 .. 16
	 * 2 [ r1 f1 f1 r2 r2 r2 r2 r2 ] bits 15 .. 8
	 * 3 [ r2 f2 f2 xx xx xx xx xx ] bits  7 .. 0
	 */
	val = get_unaligned_be32(&data[11]);
	c->f[0] = FIELD_GET(GENMASK(22, 21), val);
	c->f[1] = FIELD_GET(GENMASK(14, 13), val);
	c->f[2] = FIELD_GET(GENMASK(6, 5), val);
	c->r[0] = sign_extend32(FIELD_GET(GENMASK(28, 23), val), 5);
	c->r[1] = sign_extend32(FIELD_GET(GENMASK(20, 15), val), 5);
	c->r[2] = sign_extend32(FIELD_GET(GENMASK(12, 7), val), 5);
	return 0;
}

static int yas532_get_calibration_data(struct yas5xx *yas5xx)
{
	struct yas5xx_calibration *c = &yas5xx->calibration;
	u8 data[14];
	u32 val;
	int ret;

	/* Dummy read, first read is ALWAYS wrong */
	ret = regmap_bulk_read(yas5xx->map, YAS5XX_CAL, data, sizeof(data));
	if (ret)
		return ret;
	/* Actual calibration readout */
	ret = regmap_bulk_read(yas5xx->map, YAS5XX_CAL, data, sizeof(data));
	if (ret)
		return ret;
	dev_dbg(yas5xx->dev, "calibration data: %*ph\n", 14, data);

	/* Sanity check, is this all zeroes? */
	if (memchr_inv(data, 0x00, 13) == NULL) {
		if (!(data[13] & BIT(7)))
			dev_warn(yas5xx->dev, "calibration is blank!\n");
	}

	add_device_randomness(data, sizeof(data));
	/* Only one bit of version info reserved here as far as we know */
	yas5xx->version = data[13] & BIT(0);

	/* Extract calibration from the bitfield */
	c->Cx = data[0] * 10 - 1280;
	c->Cy1 = data[1] * 10 - 1280;
	c->Cy2 = data[2] * 10 - 1280;
	yas53x_extract_calibration(&data[3], c);
	/*
	 * Extract linearization:
	 * Linearization layout in the 32 bits at byte 10:
	 * The r factors are 6 bit values where bit 5 is the sign
	 *
	 * n    7  6  5  4  3  2  1  0
	 * 0 [ xx r0 r0 r0 r0 r0 r0 f0 ] bits 31 .. 24
	 * 1 [ f0 r1 r1 r1 r1 r1 r1 f1 ] bits 23 .. 16
	 * 2 [ f1 r2 r2 r2 r2 r2 r2 f2 ] bits 15 .. 8
	 * 3 [ f2 xx xx xx xx xx xx xx ] bits  7 .. 0
	 */
	val = get_unaligned_be32(&data[10]);
	c->f[0] = FIELD_GET(GENMASK(24, 23), val);
	c->f[1] = FIELD_GET(GENMASK(16, 15), val);
	c->f[2] = FIELD_GET(GENMASK(8, 7), val);
	c->r[0] = sign_extend32(FIELD_GET(GENMASK(30, 25), val), 5);
	c->r[1] = sign_extend32(FIELD_GET(GENMASK(22, 17), val), 5);
	c->r[2] = sign_extend32(FIELD_GET(GENMASK(14, 7), val), 5);

	return 0;
}

static void yas5xx_dump_calibration(struct yas5xx *yas5xx)
{
	struct yas5xx_calibration *c = &yas5xx->calibration;

	dev_dbg(yas5xx->dev, "f[] = [%d, %d, %d]\n",
		c->f[0], c->f[1], c->f[2]);
	dev_dbg(yas5xx->dev, "r[] = [%d, %d, %d]\n",
		c->r[0], c->r[1], c->r[2]);
	dev_dbg(yas5xx->dev, "Cx = %d\n", c->Cx);
	dev_dbg(yas5xx->dev, "Cy1 = %d\n", c->Cy1);
	dev_dbg(yas5xx->dev, "Cy2 = %d\n", c->Cy2);
	dev_dbg(yas5xx->dev, "a2 = %d\n", c->a2);
	dev_dbg(yas5xx->dev, "a3 = %d\n", c->a3);
	dev_dbg(yas5xx->dev, "a4 = %d\n", c->a4);
	dev_dbg(yas5xx->dev, "a5 = %d\n", c->a5);
	dev_dbg(yas5xx->dev, "a6 = %d\n", c->a6);
	dev_dbg(yas5xx->dev, "a7 = %d\n", c->a7);
	dev_dbg(yas5xx->dev, "a8 = %d\n", c->a8);
	dev_dbg(yas5xx->dev, "a9 = %d\n", c->a9);
	dev_dbg(yas5xx->dev, "k = %d\n", c->k);
	dev_dbg(yas5xx->dev, "dck = %d\n", c->dck);
}

static int yas5xx_set_offsets(struct yas5xx *yas5xx, s8 ox, s8 oy1, s8 oy2)
{
	int ret;

	ret = regmap_write(yas5xx->map, YAS5XX_OFFSET_X, ox);
	if (ret)
		return ret;
	ret = regmap_write(yas5xx->map, YAS5XX_OFFSET_Y1, oy1);
	if (ret)
		return ret;
	return regmap_write(yas5xx->map, YAS5XX_OFFSET_Y2, oy2);
}

static s8 yas5xx_adjust_offset(s8 old, int bit, u16 center, u16 measure)
{
	if (measure > center)
		return old + BIT(bit);
	if (measure < center)
		return old - BIT(bit);
	return old;
}

static int yas5xx_meaure_offsets(struct yas5xx *yas5xx)
{
	int ret;
	u16 center;
	u16 t, x, y1, y2;
	s8 ox, oy1, oy2;
	int i;

	/* Actuate the init coil and measure offsets */
	ret = regmap_write(yas5xx->map, YAS5XX_ACTUATE_INIT_COIL, 0);
	if (ret)
		return ret;

	/* When the initcoil is active this should be around the center */
	switch (yas5xx->devid) {
	case YAS530_DEVICE_ID:
		center = YAS530_DATA_CENTER;
		break;
	case YAS532_DEVICE_ID:
		center = YAS532_DATA_CENTER;
		break;
	default:
		dev_err(yas5xx->dev, "unknown device type\n");
		return -EINVAL;
	}

	/*
	 * We set offsets in the interval +-31 by iterating
	 * +-16, +-8, +-4, +-2, +-1 adjusting the offsets each
	 * time, then writing the final offsets into the
	 * registers.
	 *
	 * NOTE: these offsets are NOT in the same unit or magnitude
	 * as the values for [x, y1, y2]. The value is +/-31
	 * but the effect on the raw values is much larger.
	 * The effect of the offset is to bring the measure
	 * rougly to the center.
	 */
	ox = 0;
	oy1 = 0;
	oy2 = 0;

	for (i = 4; i >= 0; i--) {
		ret = yas5xx_set_offsets(yas5xx, ox, oy1, oy2);
		if (ret)
			return ret;

		ret = yas5xx_measure(yas5xx, &t, &x, &y1, &y2);
		if (ret)
			return ret;
		dev_dbg(yas5xx->dev, "measurement %d: x=%d, y1=%d, y2=%d\n",
			5-i, x, y1, y2);

		ox = yas5xx_adjust_offset(ox, i, center, x);
		oy1 = yas5xx_adjust_offset(oy1, i, center, y1);
		oy2 = yas5xx_adjust_offset(oy2, i, center, y2);
	}

	/* Needed for calibration algorithm */
	yas5xx->hard_offsets[0] = ox;
	yas5xx->hard_offsets[1] = oy1;
	yas5xx->hard_offsets[2] = oy2;
	ret = yas5xx_set_offsets(yas5xx, ox, oy1, oy2);
	if (ret)
		return ret;

	dev_info(yas5xx->dev, "discovered hard offsets: x=%d, y1=%d, y2=%d\n",
		 ox, oy1, oy2);
	return 0;
}

static int yas5xx_power_on(struct yas5xx *yas5xx)
{
	unsigned int val;
	int ret;

	/* Zero the test registers */
	ret = regmap_write(yas5xx->map, YAS5XX_TEST1, 0);
	if (ret)
		return ret;
	ret = regmap_write(yas5xx->map, YAS5XX_TEST2, 0);
	if (ret)
		return ret;

	/* Set up for no interrupts, calibrated clock divider */
	val = FIELD_PREP(YAS5XX_CONFIG_CCK_MASK, yas5xx->calibration.dck);
	ret = regmap_write(yas5xx->map, YAS5XX_CONFIG, val);
	if (ret)
		return ret;

	/* Measure interval 0 (back-to-back?)  */
	return regmap_write(yas5xx->map, YAS5XX_MEASURE_INTERVAL, 0);
}

static int yas5xx_probe(struct i2c_client *i2c,
			const struct i2c_device_id *id)
{
	struct iio_dev *indio_dev;
	struct device *dev = &i2c->dev;
	struct yas5xx *yas5xx;
	int ret;

	indio_dev = devm_iio_device_alloc(dev, sizeof(*yas5xx));
	if (!indio_dev)
		return -ENOMEM;

	yas5xx = iio_priv(indio_dev);
	i2c_set_clientdata(i2c, indio_dev);
	yas5xx->dev = dev;
	mutex_init(&yas5xx->lock);

	ret = iio_read_mount_matrix(dev, &yas5xx->orientation);
	if (ret)
		return ret;

	yas5xx->regs[0].supply = "vdd";
	yas5xx->regs[1].supply = "iovdd";
	ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(yas5xx->regs),
				      yas5xx->regs);
	if (ret)
		return dev_err_probe(dev, ret, "cannot get regulators\n");

	ret = regulator_bulk_enable(ARRAY_SIZE(yas5xx->regs), yas5xx->regs);
	if (ret) {
		dev_err(dev, "cannot enable regulators\n");
		return ret;
	}

	/* See comment in runtime resume callback */
	usleep_range(31000, 40000);

	/* This will take the device out of reset if need be */
	yas5xx->reset = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
	if (IS_ERR(yas5xx->reset)) {
		ret = dev_err_probe(dev, PTR_ERR(yas5xx->reset),
				    "failed to get reset line\n");
		goto reg_off;
	}

	yas5xx->map = devm_regmap_init_i2c(i2c, &yas5xx_regmap_config);
	if (IS_ERR(yas5xx->map)) {
		dev_err(dev, "failed to allocate register map\n");
		ret = PTR_ERR(yas5xx->map);
		goto assert_reset;
	}

	ret = regmap_read(yas5xx->map, YAS5XX_DEVICE_ID, &yas5xx->devid);
	if (ret)
		goto assert_reset;

	switch (yas5xx->devid) {
	case YAS530_DEVICE_ID:
		ret = yas530_get_calibration_data(yas5xx);
		if (ret)
			goto assert_reset;
		dev_info(dev, "detected YAS530 MS-3E %s",
			 yas5xx->version ? "B" : "A");
		strncpy(yas5xx->name, "yas530", sizeof(yas5xx->name));
		break;
	case YAS532_DEVICE_ID:
		ret = yas532_get_calibration_data(yas5xx);
		if (ret)
			goto assert_reset;
		dev_info(dev, "detected YAS532/YAS533 MS-3R/F %s",
			 yas5xx->version ? "AC" : "AB");
		strncpy(yas5xx->name, "yas532", sizeof(yas5xx->name));
		break;
	default:
		ret = -ENODEV;
		dev_err(dev, "unhandled device ID %02x\n", yas5xx->devid);
		goto assert_reset;
	}

	yas5xx_dump_calibration(yas5xx);
	ret = yas5xx_power_on(yas5xx);
	if (ret)
		goto assert_reset;
	ret = yas5xx_meaure_offsets(yas5xx);
	if (ret)
		goto assert_reset;

	indio_dev->info = &yas5xx_info;
	indio_dev->available_scan_masks = yas5xx_scan_masks;
	indio_dev->modes = INDIO_DIRECT_MODE;
	indio_dev->name = yas5xx->name;
	indio_dev->channels = yas5xx_channels;
	indio_dev->num_channels = ARRAY_SIZE(yas5xx_channels);

	ret = iio_triggered_buffer_setup(indio_dev, NULL,
					 yas5xx_handle_trigger,
					 NULL);
	if (ret) {
		dev_err(dev, "triggered buffer setup failed\n");
		goto assert_reset;
	}

	ret = iio_device_register(indio_dev);
	if (ret) {
		dev_err(dev, "device register failed\n");
		goto cleanup_buffer;
	}

	/* Take runtime PM online */
	pm_runtime_get_noresume(dev);
	pm_runtime_set_active(dev);
	pm_runtime_enable(dev);

	pm_runtime_set_autosuspend_delay(dev, YAS5XX_AUTOSUSPEND_DELAY_MS);
	pm_runtime_use_autosuspend(dev);
	pm_runtime_put(dev);

	return 0;

cleanup_buffer:
	iio_triggered_buffer_cleanup(indio_dev);
assert_reset:
	gpiod_set_value_cansleep(yas5xx->reset, 1);
reg_off:
	regulator_bulk_disable(ARRAY_SIZE(yas5xx->regs), yas5xx->regs);

	return ret;
}

static int yas5xx_remove(struct i2c_client *i2c)
{
	struct iio_dev *indio_dev = i2c_get_clientdata(i2c);
	struct yas5xx *yas5xx = iio_priv(indio_dev);
	struct device *dev = &i2c->dev;

	iio_device_unregister(indio_dev);
	iio_triggered_buffer_cleanup(indio_dev);
	/*
	 * Now we can't get any more reads from the device, which would
	 * also call pm_runtime* functions and race with our disable
	 * code. Disable PM runtime in orderly fashion and power down.
	 */
	pm_runtime_get_sync(dev);
	pm_runtime_put_noidle(dev);
	pm_runtime_disable(dev);
	gpiod_set_value_cansleep(yas5xx->reset, 1);
	regulator_bulk_disable(ARRAY_SIZE(yas5xx->regs), yas5xx->regs);

	return 0;
}

static int __maybe_unused yas5xx_runtime_suspend(struct device *dev)
{
	struct iio_dev *indio_dev = dev_get_drvdata(dev);
	struct yas5xx *yas5xx = iio_priv(indio_dev);

	gpiod_set_value_cansleep(yas5xx->reset, 1);
	regulator_bulk_disable(ARRAY_SIZE(yas5xx->regs), yas5xx->regs);

	return 0;
}

static int __maybe_unused yas5xx_runtime_resume(struct device *dev)
{
	struct iio_dev *indio_dev = dev_get_drvdata(dev);
	struct yas5xx *yas5xx = iio_priv(indio_dev);
	int ret;

	ret = regulator_bulk_enable(ARRAY_SIZE(yas5xx->regs), yas5xx->regs);
	if (ret) {
		dev_err(dev, "cannot enable regulators\n");
		return ret;
	}

	/*
	 * The YAS530 datasheet says TVSKW is up to 30 ms, after that 1 ms
	 * for all voltages to settle. The YAS532 is 10ms then 4ms for the
	 * I2C to come online. Let's keep it safe and put this at 31ms.
	 */
	usleep_range(31000, 40000);
	gpiod_set_value_cansleep(yas5xx->reset, 0);

	ret = yas5xx_power_on(yas5xx);
	if (ret) {
		dev_err(dev, "cannot power on\n");
		goto out_reset;
	}

	return 0;

out_reset:
	gpiod_set_value_cansleep(yas5xx->reset, 1);
	regulator_bulk_disable(ARRAY_SIZE(yas5xx->regs), yas5xx->regs);

	return ret;
}

static const struct dev_pm_ops yas5xx_dev_pm_ops = {
	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
				pm_runtime_force_resume)
	SET_RUNTIME_PM_OPS(yas5xx_runtime_suspend,
			   yas5xx_runtime_resume, NULL)
};

static const struct i2c_device_id yas5xx_id[] = {
	{"yas530", },
	{"yas532", },
	{"yas533", },
	{}
};
MODULE_DEVICE_TABLE(i2c, yas5xx_id);

static const struct of_device_id yas5xx_of_match[] = {
	{ .compatible = "yamaha,yas530", },
	{ .compatible = "yamaha,yas532", },
	{ .compatible = "yamaha,yas533", },
	{}
};
MODULE_DEVICE_TABLE(of, yas5xx_of_match);

static struct i2c_driver yas5xx_driver = {
	.driver	 = {
		.name	= "yas5xx",
		.of_match_table = yas5xx_of_match,
		.pm = &yas5xx_dev_pm_ops,
	},
	.probe	  = yas5xx_probe,
	.remove	  = yas5xx_remove,
	.id_table = yas5xx_id,
};
module_i2c_driver(yas5xx_driver);

MODULE_DESCRIPTION("Yamaha YAS53x 3-axis magnetometer driver");
MODULE_AUTHOR("Linus Walleij");
MODULE_LICENSE("GPL v2");
