summaryrefslogtreecommitdiff
path: root/drivers/iio/magnetometer
diff options
context:
space:
mode:
authorJakob Hauser <jahau@rocketmail.com>2022-08-13 00:05:02 +0200
committerJonathan Cameron <Jonathan.Cameron@huawei.com>2022-08-15 22:30:04 +0100
commit059ff0f9a10508c39f2c22d4144e88156bbf86ef (patch)
tree93cf767c11e2e112a0c4536d66bff796db53a7eb /drivers/iio/magnetometer
parent2d6676ecbe6a39fb1e002b89781e4158e77a784e (diff)
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>
Diffstat (limited to 'drivers/iio/magnetometer')
-rw-r--r--drivers/iio/magnetometer/yamaha-yas530.c66
1 files 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;