On Mon, Aug 8, 2022 at 1:07 AM Jakob Hauser <jahau@xxxxxxxxxxxxxx> wrote: > > Add funtion pointers to the "chip_info" structure to ease the handling of function > different YAS variants. > > In the function yas5xx_probe(), the function call for "measure_offsets" was > added as a conditional "if (yas5xx->chip_info->measure_offsets)". This is a > preparatory step for YAS537, as this variant doesn't need an offset > measurement. Reviewed-by: Andy Shevchenko <andy.shevchenko@xxxxxxxxx> > Signed-off-by: Jakob Hauser <jahau@xxxxxxxxxxxxxx> > --- > drivers/iio/magnetometer/yamaha-yas530.c | 65 +++++++++++++++--------- > 1 file changed, 40 insertions(+), 25 deletions(-) > > diff --git a/drivers/iio/magnetometer/yamaha-yas530.c b/drivers/iio/magnetometer/yamaha-yas530.c > index 780c7f4d1eff..62d5f23d8e08 100644 > --- a/drivers/iio/magnetometer/yamaha-yas530.c > +++ b/drivers/iio/magnetometer/yamaha-yas530.c > @@ -168,6 +168,11 @@ struct yas5xx; > * @scaling_val2: scaling value for IIO_CHAN_INFO_SCALE > * @t_ref: number of counts at reference temperature > * @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 > */ > struct yas5xx_chip_info { > unsigned int devid; > @@ -178,13 +183,18 @@ 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: enumeration of the device variant > - * @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 > @@ -488,7 +498,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 = yas5xx->chip_info->get_measure(yas5xx, &t, &x, &y, &z); > pm_runtime_mark_last_busy(yas5xx->dev); > pm_runtime_put_autosuspend(yas5xx->dev); > if (ret) > @@ -528,7 +538,7 @@ static void yas5xx_fill_buffer(struct iio_dev *indio_dev) > int ret; > > pm_runtime_get_sync(yas5xx->dev); > - ret = yas530_get_measure(yas5xx, &t, &x, &y, &z); > + ret = yas5xx->chip_info->get_measure(yas5xx, &t, &x, &y, &z); > pm_runtime_mark_last_busy(yas5xx->dev); > pm_runtime_put_autosuspend(yas5xx->dev); > if (ret) { > @@ -941,6 +951,11 @@ static const struct yas5xx_chip_info yas5xx_chip_info_tbl[] = { > .scaling_val2 = 100000000, /* picotesla to Gauss */ > .t_ref = t_ref_counts[yas530], > .min_temp_x10 = min_temp_celsius_x10[yas530], > + .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, > @@ -951,6 +966,11 @@ static const struct yas5xx_chip_info yas5xx_chip_info_tbl[] = { > .scaling_val2 = 100000, /* nanotesla to Gauss */ > .t_ref = t_ref_counts[yas532], > .min_temp_x10 = min_temp_celsius_x10[yas532], > + .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, > @@ -961,6 +981,11 @@ static const struct yas5xx_chip_info yas5xx_chip_info_tbl[] = { > .scaling_val2 = 100000, /* nanotesla to Gauss */ > .t_ref = t_ref_counts[yas533], > .min_temp_x10 = min_temp_celsius_x10[yas533], > + .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, > }, > }; > > @@ -1031,35 +1056,25 @@ static int yas5xx_probe(struct i2c_client *i2c, > goto assert_reset; > } > > - switch (yas5xx->chip_info->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", > - yas5xx->chip_info->devid); > + ret = yas5xx->chip_info->get_calibration_data(yas5xx); > + if (ret) > goto assert_reset; > - } > > dev_info(dev, "detected %s %s\n", yas5xx->chip_info->product_name, > yas5xx->chip_info->version_name[yas5xx->version]); > > - yas530_dump_calibration(yas5xx); > - ret = yas530_power_on(yas5xx); > - if (ret) > - goto assert_reset; > - ret = yas530_measure_offsets(yas5xx); > + yas5xx->chip_info->dump_calibration(yas5xx); > + > + ret = yas5xx->chip_info->power_on(yas5xx); > if (ret) > goto assert_reset; > > + if (yas5xx->chip_info->measure_offsets) { > + ret = yas5xx->chip_info->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; > @@ -1155,7 +1170,7 @@ static int __maybe_unused yas5xx_runtime_resume(struct device *dev) > usleep_range(31000, 40000); > gpiod_set_value_cansleep(yas5xx->reset, 0); > > - ret = yas530_power_on(yas5xx); > + ret = yas5xx->chip_info->power_on(yas5xx); > if (ret) { > dev_err(dev, "cannot power on\n"); > goto out_reset; > -- > 2.35.1 > -- With Best Regards, Andy Shevchenko