iio: magnetometer: yas530: Add function pointers to "chip_info"
authorJakob Hauser <jahau@rocketmail.com>
Fri, 12 Aug 2022 22:05:02 +0000 (00:05 +0200)
committerJonathan Cameron <Jonathan.Cameron@huawei.com>
Mon, 15 Aug 2022 21:30:04 +0000 (22:30 +0100)
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@rocketmail.com>
Reviewed-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Link: https://lore.kernel.org/r/4bd3f96262e0132b7f9720521a801da3c18abd95.1660337264.git.jahau@rocketmail.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
drivers/iio/magnetometer/yamaha-yas530.c

index a5d3f0bff0248a340343d27a9178c969a8bf9c6d..18933d8937aeb646b9aefcac1a0d0329b8f6e72b 100644 (file)
@@ -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;