Commit 059ff0f9 authored by Jakob Hauser's avatar Jakob Hauser Committed by Jonathan Cameron
Browse files

iio: magnetometer: yas530: Add function pointers to "chip_info"



Add function pointers to the "chip_info" structure to ease the handling of
different YAS variants.

In the function yas5xx_probe(), the function call for "measure_offsets" was
added as a conditional "if (ci->measure_offsets)". This is a preparatory step
for YAS537, as this variant doesn't need an offset measurement.

Signed-off-by: default avatarJakob Hauser <jahau@rocketmail.com>
Reviewed-by: default avatarAndy Shevchenko <andy.shevchenko@gmail.com>
Reviewed-by: default avatarLinus Walleij <linus.walleij@linaro.org>
Link: https://lore.kernel.org/r/4bd3f96262e0132b7f9720521a801da3c18abd95.1660337264.git.jahau@rocketmail.com


Signed-off-by: default avatarJonathan Cameron <Jonathan.Cameron@huawei.com>
parent 2d6676ec
Loading
Loading
Loading
Loading
+42 −24
Original line number Diff line number Diff line
@@ -131,6 +131,11 @@ struct yas5xx;
 * @scaling_val2: scaling value for IIO_CHAN_INFO_SCALE
 * @t_ref: number of counts at reference temperature 20 °C
 * @min_temp_x10: starting point of temperature counting in 1/10:s degrees Celsius
 * @get_measure: function pointer to get a measurement
 * @get_calibration_data: function pointer to get calibration data
 * @dump_calibration: function pointer to dump calibration for debugging
 * @measure_offsets: function pointer to measure the offsets
 * @power_on: function pointer to power-on procedure
 *
 * The "t_ref" value for YAS532/533 is known from the Android driver.
 * For YAS530 it was approximately measured.
@@ -147,12 +152,17 @@ struct yas5xx_chip_info {
	u32 scaling_val2;
	u16 t_ref;
	s16 min_temp_x10;
	int (*get_measure)(struct yas5xx *yas5xx, s32 *to, s32 *xo, s32 *yo, s32 *zo);
	int (*get_calibration_data)(struct yas5xx *yas5xx);
	void (*dump_calibration)(struct yas5xx *yas5xx);
	int (*measure_offsets)(struct yas5xx *yas5xx);
	int (*power_on)(struct yas5xx *yas5xx);
};

/**
 * struct yas5xx - state container for the YAS5xx driver
 * @dev: parent device pointer
 * @chip_info: device-specific data
 * @chip_info: device-specific data and function pointers
 * @version: device version
 * @calibration: calibration settings from the OTP storage
 * @hard_offsets: offsets for each axis measured with initcoil actuated
@@ -461,7 +471,7 @@ static int yas5xx_read_raw(struct iio_dev *indio_dev,
	case IIO_CHAN_INFO_PROCESSED:
	case IIO_CHAN_INFO_RAW:
		pm_runtime_get_sync(yas5xx->dev);
		ret = yas530_get_measure(yas5xx, &t, &x, &y, &z);
		ret = ci->get_measure(yas5xx, &t, &x, &y, &z);
		pm_runtime_mark_last_busy(yas5xx->dev);
		pm_runtime_put_autosuspend(yas5xx->dev);
		if (ret)
@@ -497,11 +507,12 @@ static int yas5xx_read_raw(struct iio_dev *indio_dev,
static void yas5xx_fill_buffer(struct iio_dev *indio_dev)
{
	struct yas5xx *yas5xx = iio_priv(indio_dev);
	const struct yas5xx_chip_info *ci = yas5xx->chip_info;
	s32 t, x, y, z;
	int ret;

	pm_runtime_get_sync(yas5xx->dev);
	ret = yas530_get_measure(yas5xx, &t, &x, &y, &z);
	ret = ci->get_measure(yas5xx, &t, &x, &y, &z);
	pm_runtime_mark_last_busy(yas5xx->dev);
	pm_runtime_put_autosuspend(yas5xx->dev);
	if (ret) {
@@ -916,6 +927,11 @@ static const struct yas5xx_chip_info yas5xx_chip_info_tbl[] = {
		.scaling_val2 = 100000000, /* picotesla to Gauss */
		.t_ref = 182, /* counts */
		.min_temp_x10 = -620, /* 1/10:s degrees Celsius */
		.get_measure = yas530_get_measure,
		.get_calibration_data = yas530_get_calibration_data,
		.dump_calibration = yas530_dump_calibration,
		.measure_offsets = yas530_measure_offsets,
		.power_on = yas530_power_on,
	},
	[yas532] = {
		.devid = YAS532_DEVICE_ID,
@@ -926,6 +942,11 @@ static const struct yas5xx_chip_info yas5xx_chip_info_tbl[] = {
		.scaling_val2 = 100000, /* nanotesla to Gauss */
		.t_ref = 390, /* counts */
		.min_temp_x10 = -500, /* 1/10:s degrees Celsius */
		.get_measure = yas530_get_measure,
		.get_calibration_data = yas532_get_calibration_data,
		.dump_calibration = yas530_dump_calibration,
		.measure_offsets = yas530_measure_offsets,
		.power_on = yas530_power_on,
	},
	[yas533] = {
		.devid = YAS532_DEVICE_ID,
@@ -936,6 +957,11 @@ static const struct yas5xx_chip_info yas5xx_chip_info_tbl[] = {
		.scaling_val2 = 100000, /* nanotesla to Gauss */
		.t_ref = 390, /* counts */
		.min_temp_x10 = -500, /* 1/10:s degrees Celsius */
		.get_measure = yas530_get_measure,
		.get_calibration_data = yas532_get_calibration_data,
		.dump_calibration = yas530_dump_calibration,
		.measure_offsets = yas530_measure_offsets,
		.power_on = yas530_power_on,
	},
};

@@ -1007,33 +1033,24 @@ static int yas5xx_probe(struct i2c_client *i2c,
		goto assert_reset;
	}

	switch (ci->devid) {
	case YAS530_DEVICE_ID:
		ret = yas530_get_calibration_data(yas5xx);
		if (ret)
			goto assert_reset;
		break;
	case YAS532_DEVICE_ID:
		ret = yas532_get_calibration_data(yas5xx);
	ret = ci->get_calibration_data(yas5xx);
	if (ret)
		goto assert_reset;
		break;
	default:
		ret = -ENODEV;
		dev_err(dev, "unhandled device ID %02x\n", ci->devid);
		goto assert_reset;
	}

	dev_info(dev, "detected %s %s\n", ci->product_name,
		 ci->version_names[yas5xx->version]);

	yas530_dump_calibration(yas5xx);
	ret = yas530_power_on(yas5xx);
	ci->dump_calibration(yas5xx);

	ret = ci->power_on(yas5xx);
	if (ret)
		goto assert_reset;
	ret = yas530_measure_offsets(yas5xx);

	if (ci->measure_offsets) {
		ret = ci->measure_offsets(yas5xx);
		if (ret)
			goto assert_reset;
	}

	indio_dev->info = &yas5xx_info;
	indio_dev->available_scan_masks = yas5xx_scan_masks;
@@ -1114,6 +1131,7 @@ static int yas5xx_runtime_resume(struct device *dev)
{
	struct iio_dev *indio_dev = dev_get_drvdata(dev);
	struct yas5xx *yas5xx = iio_priv(indio_dev);
	const struct yas5xx_chip_info *ci = yas5xx->chip_info;
	int ret;

	ret = regulator_bulk_enable(ARRAY_SIZE(yas5xx->regs), yas5xx->regs);
@@ -1130,7 +1148,7 @@ static int yas5xx_runtime_resume(struct device *dev)
	usleep_range(31000, 40000);
	gpiod_set_value_cansleep(yas5xx->reset, 0);

	ret = yas530_power_on(yas5xx);
	ret = ci->power_on(yas5xx);
	if (ret) {
		dev_err(dev, "cannot power on\n");
		goto out_reset;