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: 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>
This commit is contained in:
Jakob Hauser 2022-08-13 00:05:02 +02:00 committed by Jonathan Cameron
parent 2d6676ecbe
commit 059ff0f9a1
1 changed files with 42 additions and 24 deletions

View 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;