[PATCH v6 13/14] iio: magnetometer: yas530: Add function pointers to "chip_info"

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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: Jakob Hauser <jahau@xxxxxxxxxxxxxx>
Reviewed-by: Andy Shevchenko <andy.shevchenko@xxxxxxxxx>
---
 drivers/iio/magnetometer/yamaha-yas530.c | 66 +++++++++++++++---------
 1 file changed, 42 insertions(+), 24 deletions(-)

diff --git a/drivers/iio/magnetometer/yamaha-yas530.c b/drivers/iio/magnetometer/yamaha-yas530.c
index a5d3f0bff024..18933d8937ae 100644
--- a/drivers/iio/magnetometer/yamaha-yas530.c
+++ b/drivers/iio/magnetometer/yamaha-yas530.c
@@ -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,34 +1033,25 @@ 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);
-		if (ret)
-			goto assert_reset;
-		break;
-	default:
-		ret = -ENODEV;
-		dev_err(dev, "unhandled device ID %02x\n", ci->devid);
+	ret = ci->get_calibration_data(yas5xx);
+	if (ret)
 		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);
-	if (ret)
-		goto assert_reset;
-	ret = yas530_measure_offsets(yas5xx);
+	ci->dump_calibration(yas5xx);
+
+	ret = ci->power_on(yas5xx);
 	if (ret)
 		goto assert_reset;
 
+	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;
 	indio_dev->modes = INDIO_DIRECT_MODE;
@@ -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;
-- 
2.35.1




[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Input]     [Linux Kernel]     [Linux SCSI]     [X.org]

  Powered by Linux