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:
parent
2d6676ecbe
commit
059ff0f9a1
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue