// SPDX-License-Identifier: GPL-2.0-only
/*
 * Driver for the TI TMAG5273 Low-Power Linear 3D Hall-Effect Sensor
 *
 * Copyright (C) 2022 WolfVision GmbH
 *
 * Author: Gerald Loacker <gerald.loacker@wolfvision.net>
 */

#include <linux/bitfield.h>
#include <linux/bits.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/regmap.h>
#include <linux/pm_runtime.h>

#include <linux/iio/iio.h>
#include <linux/iio/sysfs.h>

#define TMAG5273_DEVICE_CONFIG_1	 0x00
#define TMAG5273_DEVICE_CONFIG_2	 0x01
#define TMAG5273_SENSOR_CONFIG_1	 0x02
#define TMAG5273_SENSOR_CONFIG_2	 0x03
#define TMAG5273_X_THR_CONFIG		 0x04
#define TMAG5273_Y_THR_CONFIG		 0x05
#define TMAG5273_Z_THR_CONFIG		 0x06
#define TMAG5273_T_CONFIG		 0x07
#define TMAG5273_INT_CONFIG_1		 0x08
#define TMAG5273_MAG_GAIN_CONFIG	 0x09
#define TMAG5273_MAG_OFFSET_CONFIG_1	 0x0A
#define TMAG5273_MAG_OFFSET_CONFIG_2	 0x0B
#define TMAG5273_I2C_ADDRESS		 0x0C
#define TMAG5273_DEVICE_ID		 0x0D
#define TMAG5273_MANUFACTURER_ID_LSB	 0x0E
#define TMAG5273_MANUFACTURER_ID_MSB	 0x0F
#define TMAG5273_T_MSB_RESULT		 0x10
#define TMAG5273_T_LSB_RESULT		 0x11
#define TMAG5273_X_MSB_RESULT		 0x12
#define TMAG5273_X_LSB_RESULT		 0x13
#define TMAG5273_Y_MSB_RESULT		 0x14
#define TMAG5273_Y_LSB_RESULT		 0x15
#define TMAG5273_Z_MSB_RESULT		 0x16
#define TMAG5273_Z_LSB_RESULT		 0x17
#define TMAG5273_CONV_STATUS		 0x18
#define TMAG5273_ANGLE_RESULT_MSB	 0x19
#define TMAG5273_ANGLE_RESULT_LSB	 0x1A
#define TMAG5273_MAGNITUDE_RESULT	 0x1B
#define TMAG5273_DEVICE_STATUS		 0x1C
#define TMAG5273_MAX_REG		 TMAG5273_DEVICE_STATUS

#define TMAG5273_AUTOSLEEP_DELAY_MS	 5000
#define TMAG5273_MAX_AVERAGE             32

/*
 * bits in the TMAG5273_MANUFACTURER_ID_LSB / MSB register
 * 16-bit unique manufacturer ID 0x49 / 0x54 = "TI"
 */
#define TMAG5273_MANUFACTURER_ID	 0x5449

/* bits in the TMAG5273_DEVICE_CONFIG_1 register */
#define TMAG5273_AVG_MODE_MASK		 GENMASK(4, 2)
#define TMAG5273_AVG_1_MODE		 FIELD_PREP(TMAG5273_AVG_MODE_MASK, 0)
#define TMAG5273_AVG_2_MODE		 FIELD_PREP(TMAG5273_AVG_MODE_MASK, 1)
#define TMAG5273_AVG_4_MODE		 FIELD_PREP(TMAG5273_AVG_MODE_MASK, 2)
#define TMAG5273_AVG_8_MODE		 FIELD_PREP(TMAG5273_AVG_MODE_MASK, 3)
#define TMAG5273_AVG_16_MODE		 FIELD_PREP(TMAG5273_AVG_MODE_MASK, 4)
#define TMAG5273_AVG_32_MODE		 FIELD_PREP(TMAG5273_AVG_MODE_MASK, 5)

/* bits in the TMAG5273_DEVICE_CONFIG_2 register */
#define TMAG5273_OP_MODE_MASK		 GENMASK(1, 0)
#define TMAG5273_OP_MODE_STANDBY	 FIELD_PREP(TMAG5273_OP_MODE_MASK, 0)
#define TMAG5273_OP_MODE_SLEEP		 FIELD_PREP(TMAG5273_OP_MODE_MASK, 1)
#define TMAG5273_OP_MODE_CONT		 FIELD_PREP(TMAG5273_OP_MODE_MASK, 2)
#define TMAG5273_OP_MODE_WAKEUP		 FIELD_PREP(TMAG5273_OP_MODE_MASK, 3)

/* bits in the TMAG5273_SENSOR_CONFIG_1 register */
#define TMAG5273_MAG_CH_EN_MASK		 GENMASK(7, 4)
#define TMAG5273_MAG_CH_EN_X_Y_Z	 7

/* bits in the TMAG5273_SENSOR_CONFIG_2 register */
#define TMAG5273_Z_RANGE_MASK		 BIT(0)
#define TMAG5273_X_Y_RANGE_MASK		 BIT(1)
#define TMAG5273_ANGLE_EN_MASK		 GENMASK(3, 2)
#define TMAG5273_ANGLE_EN_OFF		 0
#define TMAG5273_ANGLE_EN_X_Y		 1
#define TMAG5273_ANGLE_EN_Y_Z		 2
#define TMAG5273_ANGLE_EN_X_Z		 3

/* bits in the TMAG5273_T_CONFIG register */
#define TMAG5273_T_CH_EN		 BIT(0)

/* bits in the TMAG5273_DEVICE_ID register */
#define TMAG5273_VERSION_MASK		 GENMASK(1, 0)

/* bits in the TMAG5273_CONV_STATUS register */
#define TMAG5273_CONV_STATUS_COMPLETE	 BIT(0)

enum tmag5273_channels {
	TEMPERATURE = 0,
	AXIS_X,
	AXIS_Y,
	AXIS_Z,
	ANGLE,
	MAGNITUDE,
};

enum tmag5273_scale_index {
	MAGN_RANGE_LOW = 0,
	MAGN_RANGE_HIGH,
	MAGN_RANGE_NUM
};

/* state container for the TMAG5273 driver */
struct tmag5273_data {
	struct device *dev;
	unsigned int devid;
	unsigned int version;
	char name[16];
	unsigned int conv_avg;
	unsigned int scale;
	enum tmag5273_scale_index scale_index;
	unsigned int angle_measurement;
	struct regmap *map;
	struct regulator *vcc;

	/*
	 * Locks the sensor 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.
	 */
	struct mutex lock;
};

static const char *const tmag5273_angle_names[] = { "off", "x-y", "y-z", "x-z" };

/*
 * Averaging enables additional sampling of the sensor data to reduce the noise
 * effect, but also increases conversion time.
 */
static const unsigned int tmag5273_avg_table[] = {
	1, 2, 4, 8, 16, 32,
};

/*
 * Magnetic resolution in Gauss for different TMAG5273 versions.
 * Scale[Gauss] = Range[mT] * 1000 / 2^15 * 10, (1 mT = 10 Gauss)
 * Only version 1 and 2 are valid, version 0 and 3 are reserved.
 */
static const struct iio_val_int_plus_micro tmag5273_scale[][MAGN_RANGE_NUM] = {
	{ { 0,     0 }, { 0,     0 } },
	{ { 0, 12200 }, { 0, 24400 } },
	{ { 0, 40600 }, { 0, 81200 } },
	{ { 0,     0 }, { 0,     0 } },
};

static int tmag5273_get_measure(struct tmag5273_data *data, s16 *t, s16 *x,
				s16 *y, s16 *z, u16 *angle, u16 *magnitude)
{
	unsigned int status, val;
	__be16 reg_data[4];
	int ret;

	mutex_lock(&data->lock);

	/*
	 * Max. conversion time is 2425 us in 32x averaging mode for all three
	 * channels. Since we are in continuous measurement mode, a measurement
	 * may already be there, so poll for completed measurement with
	 * timeout.
	 */
	ret = regmap_read_poll_timeout(data->map, TMAG5273_CONV_STATUS, status,
				       status & TMAG5273_CONV_STATUS_COMPLETE,
				       100, 10000);
	if (ret) {
		dev_err(data->dev, "timeout waiting for measurement\n");
		goto out_unlock;
	}

	ret = regmap_bulk_read(data->map, TMAG5273_T_MSB_RESULT, reg_data,
			       sizeof(reg_data));
	if (ret)
		goto out_unlock;
	*t = be16_to_cpu(reg_data[0]);
	*x = be16_to_cpu(reg_data[1]);
	*y = be16_to_cpu(reg_data[2]);
	*z = be16_to_cpu(reg_data[3]);

	ret = regmap_bulk_read(data->map, TMAG5273_ANGLE_RESULT_MSB,
			       &reg_data[0], sizeof(reg_data[0]));
	if (ret)
		goto out_unlock;
	/*
	 * angle has 9 bits integer value and 4 bits fractional part
	 * 15 14 13 12 11 10 9  8  7  6  5  4  3  2  1  0
	 * 0  0  0  a  a  a  a  a  a  a  a  a  f  f  f  f
	 */
	*angle = be16_to_cpu(reg_data[0]);

	ret = regmap_read(data->map, TMAG5273_MAGNITUDE_RESULT, &val);
	if (ret < 0)
		goto out_unlock;
	*magnitude = val;

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

static int tmag5273_write_osr(struct tmag5273_data *data, int val)
{
	int i;

	if (val == data->conv_avg)
		return 0;

	for (i = 0; i < ARRAY_SIZE(tmag5273_avg_table); i++) {
		if (tmag5273_avg_table[i] == val)
			break;
	}
	if (i == ARRAY_SIZE(tmag5273_avg_table))
		return -EINVAL;
	data->conv_avg = val;

	return regmap_update_bits(data->map, TMAG5273_DEVICE_CONFIG_1,
				  TMAG5273_AVG_MODE_MASK,
				  FIELD_PREP(TMAG5273_AVG_MODE_MASK, i));
}

static int tmag5273_write_scale(struct tmag5273_data *data, int scale_micro)
{
	u32 value;
	int i;

	for (i = 0; i < ARRAY_SIZE(tmag5273_scale[0]); i++) {
		if (tmag5273_scale[data->version][i].micro == scale_micro)
			break;
	}
	if (i == ARRAY_SIZE(tmag5273_scale[0]))
		return -EINVAL;
	data->scale_index = i;

	if (data->scale_index == MAGN_RANGE_LOW)
		value = 0;
	else
		value = TMAG5273_Z_RANGE_MASK | TMAG5273_X_Y_RANGE_MASK;

	return regmap_update_bits(data->map, TMAG5273_SENSOR_CONFIG_2,
				  TMAG5273_Z_RANGE_MASK | TMAG5273_X_Y_RANGE_MASK, value);
}

static int tmag5273_read_avail(struct iio_dev *indio_dev,
			       struct iio_chan_spec const *chan,
			       const int **vals, int *type, int *length,
			       long mask)
{
	struct tmag5273_data *data = iio_priv(indio_dev);

	switch (mask) {
	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
		*vals = tmag5273_avg_table;
		*type = IIO_VAL_INT;
		*length = ARRAY_SIZE(tmag5273_avg_table);
		return IIO_AVAIL_LIST;
	case IIO_CHAN_INFO_SCALE:
		switch (chan->type) {
		case IIO_MAGN:
			*type = IIO_VAL_INT_PLUS_MICRO;
			*vals = (int *)tmag5273_scale[data->version];
			*length = ARRAY_SIZE(tmag5273_scale[data->version]) *
				  MAGN_RANGE_NUM;
			return IIO_AVAIL_LIST;
		default:
			return -EINVAL;
		}
	default:
		return -EINVAL;
	}
}

static int tmag5273_read_raw(struct iio_dev *indio_dev,
			     const struct iio_chan_spec *chan, int *val,
			     int *val2, long mask)
{
	struct tmag5273_data *data = iio_priv(indio_dev);
	s16 t, x, y, z;
	u16 angle, magnitude;
	int ret;

	switch (mask) {
	case IIO_CHAN_INFO_PROCESSED:
	case IIO_CHAN_INFO_RAW:
		ret = pm_runtime_resume_and_get(data->dev);
		if (ret < 0)
			return ret;

		ret = tmag5273_get_measure(data, &t, &x, &y, &z, &angle, &magnitude);

		pm_runtime_mark_last_busy(data->dev);
		pm_runtime_put_autosuspend(data->dev);

		if (ret)
			return ret;

		switch (chan->address) {
		case TEMPERATURE:
			*val = t;
			return IIO_VAL_INT;
		case AXIS_X:
			*val = x;
			return IIO_VAL_INT;
		case AXIS_Y:
			*val = y;
			return IIO_VAL_INT;
		case AXIS_Z:
			*val = z;
			return IIO_VAL_INT;
		case ANGLE:
			*val = angle;
			return IIO_VAL_INT;
		case MAGNITUDE:
			*val = magnitude;
			return IIO_VAL_INT;
		default:
			return -EINVAL;
		}
	case IIO_CHAN_INFO_SCALE:
		switch (chan->type) {
		case IIO_TEMP:
			/*
			 * Convert device specific value to millicelsius.
			 * Resolution from the sensor is 60.1 LSB/celsius and
			 * the reference value at 25 celsius is 17508 LSBs.
			 */
			*val = 10000;
			*val2 = 601;
			return IIO_VAL_FRACTIONAL;
		case IIO_MAGN:
			/* Magnetic resolution in uT */
			*val = 0;
			*val2 = tmag5273_scale[data->version]
					      [data->scale_index].micro;
			return IIO_VAL_INT_PLUS_MICRO;
		case IIO_ANGL:
			/*
			 * Angle is in degrees and has four fractional bits,
			 * therefore use 1/16 * pi/180 to convert to radians.
			 */
			*val = 1000;
			*val2 = 916732;
			return IIO_VAL_FRACTIONAL;
		default:
			return -EINVAL;
		}
	case IIO_CHAN_INFO_OFFSET:
		switch (chan->type) {
		case IIO_TEMP:
			*val = -16005;
			return IIO_VAL_INT;
		default:
			return -EINVAL;
		}
	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
		*val = data->conv_avg;
		return IIO_VAL_INT;

	default:
		return -EINVAL;
	}
}

static int tmag5273_write_raw(struct iio_dev *indio_dev,
			      struct iio_chan_spec const *chan, int val,
			      int val2, long mask)
{
	struct tmag5273_data *data = iio_priv(indio_dev);

	switch (mask) {
	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:
		return tmag5273_write_osr(data, val);
	case IIO_CHAN_INFO_SCALE:
		switch (chan->type) {
		case IIO_MAGN:
			if (val)
				return -EINVAL;
			return tmag5273_write_scale(data, val2);
		default:
			return -EINVAL;
		}
	default:
		return -EINVAL;
	}
}

#define TMAG5273_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),		     \
		.info_mask_shared_by_type_available =			     \
				      BIT(IIO_CHAN_INFO_SCALE),		     \
		.info_mask_shared_by_all =				     \
				      BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
		.info_mask_shared_by_all_available =			     \
				      BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO), \
		.address = index,					     \
		.scan_index = index,					     \
		.scan_type = {						     \
			.sign = 's',					     \
			.realbits = 16,					     \
			.storagebits = 16,				     \
			.endianness = IIO_CPU,				     \
		},							     \
	}

static const struct iio_chan_spec tmag5273_channels[] = {
	{
		.type = IIO_TEMP,
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
			BIT(IIO_CHAN_INFO_SCALE) |
			BIT(IIO_CHAN_INFO_OFFSET),
		.address = TEMPERATURE,
		.scan_index = TEMPERATURE,
		.scan_type = {
			.sign = 'u',
			.realbits = 16,
			.storagebits = 16,
			.endianness = IIO_CPU,
		},
	},
	TMAG5273_AXIS_CHANNEL(X, AXIS_X),
	TMAG5273_AXIS_CHANNEL(Y, AXIS_Y),
	TMAG5273_AXIS_CHANNEL(Z, AXIS_Z),
	{
		.type = IIO_ANGL,
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
		.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),
		.info_mask_shared_by_all =
				      BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
		.info_mask_shared_by_all_available =
				      BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
		.address = ANGLE,
		.scan_index = ANGLE,
		.scan_type = {
			.sign = 'u',
			.realbits = 16,
			.storagebits = 16,
			.endianness = IIO_CPU,
		},
	},
	{
		.type = IIO_DISTANCE,
		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
		.info_mask_shared_by_all =
				      BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
		.info_mask_shared_by_all_available =
				      BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),
		.address = MAGNITUDE,
		.scan_index = MAGNITUDE,
		.scan_type = {
			.sign = 'u',
			.realbits = 16,
			.storagebits = 16,
			.endianness = IIO_CPU,
		},
	},
	IIO_CHAN_SOFT_TIMESTAMP(6),
};

static const struct iio_info tmag5273_info = {
	.read_avail = tmag5273_read_avail,
	.read_raw = tmag5273_read_raw,
	.write_raw = tmag5273_write_raw,
};

static bool tmag5273_volatile_reg(struct device *dev, unsigned int reg)
{
	return reg >= TMAG5273_T_MSB_RESULT && reg <= TMAG5273_MAGNITUDE_RESULT;
}

static const struct regmap_config tmag5273_regmap_config = {
	.reg_bits = 8,
	.val_bits = 8,
	.max_register = TMAG5273_MAX_REG,
	.volatile_reg = tmag5273_volatile_reg,
};

static int tmag5273_set_operating_mode(struct tmag5273_data *data,
				       unsigned int val)
{
	return regmap_write(data->map, TMAG5273_DEVICE_CONFIG_2, val);
}

static void tmag5273_read_device_property(struct tmag5273_data *data)
{
	struct device *dev = data->dev;
	int ret;

	data->angle_measurement = TMAG5273_ANGLE_EN_X_Y;

	ret = device_property_match_property_string(dev, "ti,angle-measurement",
						    tmag5273_angle_names,
						    ARRAY_SIZE(tmag5273_angle_names));
	if (ret >= 0)
		data->angle_measurement = ret;
}

static void tmag5273_wake_up(struct tmag5273_data *data)
{
	int val;

	/* Wake up the chip by sending a dummy I2C command */
	regmap_read(data->map, TMAG5273_DEVICE_ID, &val);
	/*
	 * Time to go to stand-by mode from sleep mode is 50us
	 * typically, during this time no I2C access is possible.
	 */
	usleep_range(80, 200);
}

static int tmag5273_chip_init(struct tmag5273_data *data)
{
	int ret;

	ret = regmap_write(data->map, TMAG5273_DEVICE_CONFIG_1,
			   TMAG5273_AVG_32_MODE);
	if (ret)
		return ret;
	data->conv_avg = 32;

	ret = regmap_write(data->map, TMAG5273_DEVICE_CONFIG_2,
			   TMAG5273_OP_MODE_CONT);
	if (ret)
		return ret;

	ret = regmap_write(data->map, TMAG5273_SENSOR_CONFIG_1,
			   FIELD_PREP(TMAG5273_MAG_CH_EN_MASK,
				      TMAG5273_MAG_CH_EN_X_Y_Z));
	if (ret)
		return ret;

	ret = regmap_write(data->map, TMAG5273_SENSOR_CONFIG_2,
			   FIELD_PREP(TMAG5273_ANGLE_EN_MASK,
				      data->angle_measurement));
	if (ret)
		return ret;
	data->scale_index = MAGN_RANGE_LOW;

	return regmap_write(data->map, TMAG5273_T_CONFIG, TMAG5273_T_CH_EN);
}

static int tmag5273_check_device_id(struct tmag5273_data *data)
{
	__le16 devid;
	int val, ret;

	ret = regmap_read(data->map, TMAG5273_DEVICE_ID, &val);
	if (ret)
		return dev_err_probe(data->dev, ret, "failed to power on device\n");
	data->version = FIELD_PREP(TMAG5273_VERSION_MASK, val);

	ret = regmap_bulk_read(data->map, TMAG5273_MANUFACTURER_ID_LSB, &devid,
			       sizeof(devid));
	if (ret)
		return dev_err_probe(data->dev, ret, "failed to read device ID\n");
	data->devid = le16_to_cpu(devid);

	switch (data->devid) {
	case TMAG5273_MANUFACTURER_ID:
		/*
		 * The device name matches the orderable part number. 'x' stands
		 * for A, B, C or D devices, which have different I2C addresses.
		 * Versions 1 or 2 (0 and 3 is reserved) stands for different
		 * magnetic strengths.
		 */
		snprintf(data->name, sizeof(data->name), "tmag5273x%1u", data->version);
		if (data->version < 1 || data->version > 2)
			dev_warn(data->dev, "Unsupported device %s\n", data->name);
		return 0;
	default:
		/*
		 * Only print warning in case of unknown device ID to allow
		 * fallback compatible in device tree.
		 */
		dev_warn(data->dev, "Unknown device ID 0x%x\n", data->devid);
		return 0;
	}
}

static void tmag5273_power_down(void *data)
{
	tmag5273_set_operating_mode(data, TMAG5273_OP_MODE_SLEEP);
}

static int tmag5273_probe(struct i2c_client *i2c)
{
	struct device *dev = &i2c->dev;
	struct tmag5273_data *data;
	struct iio_dev *indio_dev;
	int ret;

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

	data = iio_priv(indio_dev);
	data->dev = dev;
	i2c_set_clientdata(i2c, indio_dev);

	data->map = devm_regmap_init_i2c(i2c, &tmag5273_regmap_config);
	if (IS_ERR(data->map))
		return dev_err_probe(dev, PTR_ERR(data->map),
				     "failed to allocate register map\n");

	mutex_init(&data->lock);

	ret = devm_regulator_get_enable(dev, "vcc");
	if (ret)
		return dev_err_probe(dev, ret, "failed to enable regulator\n");

	tmag5273_wake_up(data);

	ret = tmag5273_check_device_id(data);
	if (ret)
		return ret;

	ret = tmag5273_set_operating_mode(data, TMAG5273_OP_MODE_CONT);
	if (ret)
		return dev_err_probe(dev, ret, "failed to power on device\n");

	/*
	 * Register powerdown deferred callback which suspends the chip
	 * after module unloaded.
	 *
	 * TMAG5273 should be in SUSPEND mode in the two cases:
	 * 1) When driver is loaded, but we do not have any data or
	 *    configuration requests to it (we are solving it using
	 *    autosuspend feature).
	 * 2) When driver is unloaded and device is not used (devm action is
	 *    used in this case).
	 */
	ret = devm_add_action_or_reset(dev, tmag5273_power_down, data);
	if (ret)
		return dev_err_probe(dev, ret, "failed to add powerdown action\n");

	ret = pm_runtime_set_active(dev);
	if (ret < 0)
		return ret;

	ret = devm_pm_runtime_enable(dev);
	if (ret)
		return ret;

	pm_runtime_get_noresume(dev);
	pm_runtime_set_autosuspend_delay(dev, TMAG5273_AUTOSLEEP_DELAY_MS);
	pm_runtime_use_autosuspend(dev);

	tmag5273_read_device_property(data);

	ret = tmag5273_chip_init(data);
	if (ret)
		return dev_err_probe(dev, ret, "failed to init device\n");

	indio_dev->info = &tmag5273_info;
	indio_dev->modes = INDIO_DIRECT_MODE;
	indio_dev->name = data->name;
	indio_dev->channels = tmag5273_channels;
	indio_dev->num_channels = ARRAY_SIZE(tmag5273_channels);

	pm_runtime_mark_last_busy(dev);
	pm_runtime_put_autosuspend(dev);

	ret = devm_iio_device_register(dev, indio_dev);
	if (ret)
		return dev_err_probe(dev, ret, "device register failed\n");

	return 0;
}

static int tmag5273_runtime_suspend(struct device *dev)
{
	struct iio_dev *indio_dev = dev_get_drvdata(dev);
	struct tmag5273_data *data = iio_priv(indio_dev);
	int ret;

	ret = tmag5273_set_operating_mode(data, TMAG5273_OP_MODE_SLEEP);
	if (ret)
		dev_err(dev, "failed to power off device (%pe)\n", ERR_PTR(ret));

	return ret;
}

static int tmag5273_runtime_resume(struct device *dev)
{
	struct iio_dev *indio_dev = dev_get_drvdata(dev);
	struct tmag5273_data *data = iio_priv(indio_dev);
	int ret;

	tmag5273_wake_up(data);

	ret = tmag5273_set_operating_mode(data, TMAG5273_OP_MODE_CONT);
	if (ret)
		dev_err(dev, "failed to power on device (%pe)\n", ERR_PTR(ret));

	return ret;
}

static DEFINE_RUNTIME_DEV_PM_OPS(tmag5273_pm_ops,
				 tmag5273_runtime_suspend, tmag5273_runtime_resume,
				 NULL);

static const struct i2c_device_id tmag5273_id[] = {
	{ "tmag5273" },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(i2c, tmag5273_id);

static const struct of_device_id tmag5273_of_match[] = {
	{ .compatible = "ti,tmag5273" },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, tmag5273_of_match);

static struct i2c_driver tmag5273_driver = {
	.driver	 = {
		.name = "tmag5273",
		.of_match_table = tmag5273_of_match,
		.pm = pm_ptr(&tmag5273_pm_ops),
	},
	.probe = tmag5273_probe,
	.id_table = tmag5273_id,
};
module_i2c_driver(tmag5273_driver);

MODULE_DESCRIPTION("TI TMAG5273 Low-Power Linear 3D Hall-Effect Sensor driver");
MODULE_AUTHOR("Gerald Loacker <gerald.loacker@wolfvision.net>");
MODULE_LICENSE("GPL");
