Skip to content

Commit a70f60e

Browse files
Jakko3jic23
authored andcommitted
iio: magnetometer: yas530: Introduce "chip_info" structure
Introduce the "chip_info" structure approach for better variant handling. The variant to be used is now chosen by the Device Tree (enum "chip_ids"), not by the chip ID in the register. However, there is a check to make sure they match (using integer "id_check"). Signed-off-by: Jakob Hauser <[email protected]> Reviewed-by: Linus Walleij <[email protected]> Link: https://lore.kernel.org/r/57236545107286771d351b95091bf56815d3717d.1660337264.git.jahau@rocketmail.com Signed-off-by: Jonathan Cameron <[email protected]>
1 parent 92d9c05 commit a70f60e

File tree

1 file changed

+74
-24
lines changed

1 file changed

+74
-24
lines changed

drivers/iio/magnetometer/yamaha-yas530.c

Lines changed: 74 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,12 @@
9696
/* Turn off device regulators etc after 5 seconds of inactivity */
9797
#define YAS5XX_AUTOSUSPEND_DELAY_MS 5000
9898

99+
enum chip_ids {
100+
yas530,
101+
yas532,
102+
yas533,
103+
};
104+
99105
struct yas5xx_calibration {
100106
/* Linearization calibration x, y1, y2 */
101107
s32 r[3];
@@ -110,12 +116,25 @@ struct yas5xx_calibration {
110116
u8 dck;
111117
};
112118

119+
struct yas5xx;
120+
121+
/**
122+
* struct yas5xx_chip_info - device-specific data and function pointers
123+
* @devid: device ID number
124+
* @product_name: product name of the YAS variant
125+
* @version_names: version letters or namings
126+
*/
127+
struct yas5xx_chip_info {
128+
unsigned int devid;
129+
char *product_name;
130+
char *version_names[2];
131+
};
132+
113133
/**
114134
* struct yas5xx - state container for the YAS5xx driver
115135
* @dev: parent device pointer
116-
* @devid: device ID number
136+
* @chip_info: device-specific data
117137
* @version: device version
118-
* @name: device name
119138
* @calibration: calibration settings from the OTP storage
120139
* @hard_offsets: offsets for each axis measured with initcoil actuated
121140
* @orientation: mounting matrix, flipped axis etc
@@ -129,9 +148,8 @@ struct yas5xx_calibration {
129148
*/
130149
struct yas5xx {
131150
struct device *dev;
132-
unsigned int devid;
151+
const struct yas5xx_chip_info *chip_info;
133152
unsigned int version;
134-
char name[16];
135153
struct yas5xx_calibration calibration;
136154
s8 hard_offsets[3];
137155
struct iio_mount_matrix orientation;
@@ -192,6 +210,7 @@ static u16 yas532_extract_axis(u8 *data)
192210
*/
193211
static int yas530_measure(struct yas5xx *yas5xx, u16 *t, u16 *x, u16 *y1, u16 *y2)
194212
{
213+
const struct yas5xx_chip_info *ci = yas5xx->chip_info;
195214
unsigned int busy;
196215
u8 data[8];
197216
int ret;
@@ -222,7 +241,7 @@ static int yas530_measure(struct yas5xx *yas5xx, u16 *t, u16 *x, u16 *y1, u16 *y
222241

223242
mutex_unlock(&yas5xx->lock);
224243

225-
switch (yas5xx->devid) {
244+
switch (ci->devid) {
226245
case YAS530_DEVICE_ID:
227246
/*
228247
* The t value is 9 bits in big endian format
@@ -267,6 +286,7 @@ static int yas530_measure(struct yas5xx *yas5xx, u16 *t, u16 *x, u16 *y1, u16 *y
267286
/* Used by YAS530, YAS532 and YAS533 */
268287
static s32 yas530_linearize(struct yas5xx *yas5xx, u16 val, int axis)
269288
{
289+
const struct yas5xx_chip_info *ci = yas5xx->chip_info;
270290
struct yas5xx_calibration *c = &yas5xx->calibration;
271291
static const s32 yas532ac_coef[] = {
272292
YAS532_VERSION_AC_COEF_X,
@@ -276,7 +296,7 @@ static s32 yas530_linearize(struct yas5xx *yas5xx, u16 val, int axis)
276296
s32 coef;
277297

278298
/* Select coefficients */
279-
switch (yas5xx->devid) {
299+
switch (ci->devid) {
280300
case YAS530_DEVICE_ID:
281301
if (yas5xx->version == YAS530_VERSION_A)
282302
coef = YAS530_VERSION_A_COEF;
@@ -319,6 +339,7 @@ static s32 yas530_linearize(struct yas5xx *yas5xx, u16 val, int axis)
319339
*/
320340
static int yas530_get_measure(struct yas5xx *yas5xx, s32 *to, s32 *xo, s32 *yo, s32 *zo)
321341
{
342+
const struct yas5xx_chip_info *ci = yas5xx->chip_info;
322343
struct yas5xx_calibration *c = &yas5xx->calibration;
323344
u16 t_ref, t, x, y1, y2;
324345
/* These are signed x, signed y1 etc */
@@ -336,7 +357,7 @@ static int yas530_get_measure(struct yas5xx *yas5xx, s32 *to, s32 *xo, s32 *yo,
336357
sy2 = yas530_linearize(yas5xx, y2, 2);
337358

338359
/* Set the temperature reference value (unit: counts) */
339-
switch (yas5xx->devid) {
360+
switch (ci->devid) {
340361
case YAS530_DEVICE_ID:
341362
t_ref = YAS530_20DEGREES;
342363
break;
@@ -349,7 +370,7 @@ static int yas530_get_measure(struct yas5xx *yas5xx, s32 *to, s32 *xo, s32 *yo,
349370
}
350371

351372
/* Temperature compensation for x, y1, y2 respectively */
352-
if (yas5xx->devid == YAS532_DEVICE_ID &&
373+
if (ci->devid == YAS532_DEVICE_ID &&
353374
yas5xx->version == YAS532_VERSION_AC) {
354375
/*
355376
* YAS532 version AC uses the temperature deviation as a
@@ -384,7 +405,7 @@ static int yas530_get_measure(struct yas5xx *yas5xx, s32 *to, s32 *xo, s32 *yo,
384405
sz = -sy1 - sy2;
385406

386407
/* Process temperature readout */
387-
switch (yas5xx->devid) {
408+
switch (ci->devid) {
388409
case YAS530_DEVICE_ID:
389410
/*
390411
* Raw temperature value t is the number of counts starting
@@ -442,6 +463,7 @@ static int yas5xx_read_raw(struct iio_dev *indio_dev,
442463
long mask)
443464
{
444465
struct yas5xx *yas5xx = iio_priv(indio_dev);
466+
const struct yas5xx_chip_info *ci = yas5xx->chip_info;
445467
s32 t, x, y, z;
446468
int ret;
447469

@@ -473,7 +495,7 @@ static int yas5xx_read_raw(struct iio_dev *indio_dev,
473495
}
474496
return IIO_VAL_INT;
475497
case IIO_CHAN_INFO_SCALE:
476-
switch (yas5xx->devid) {
498+
switch (ci->devid) {
477499
case YAS530_DEVICE_ID:
478500
/*
479501
* Raw values of YAS530 are in picotesla. Divide by
@@ -802,6 +824,7 @@ static s8 yas530_adjust_offset(s8 old, int bit, u16 center, u16 measure)
802824
/* Used by YAS530, YAS532 and YAS533 */
803825
static int yas530_measure_offsets(struct yas5xx *yas5xx)
804826
{
827+
const struct yas5xx_chip_info *ci = yas5xx->chip_info;
805828
int ret;
806829
u16 center;
807830
u16 t, x, y1, y2;
@@ -814,7 +837,7 @@ static int yas530_measure_offsets(struct yas5xx *yas5xx)
814837
return ret;
815838

816839
/* When the initcoil is active this should be around the center */
817-
switch (yas5xx->devid) {
840+
switch (ci->devid) {
818841
case YAS530_DEVICE_ID:
819842
center = YAS530_DATA_CENTER;
820843
break;
@@ -895,12 +918,32 @@ static int yas530_power_on(struct yas5xx *yas5xx)
895918
return regmap_write(yas5xx->map, YAS530_MEASURE_INTERVAL, 0);
896919
}
897920

921+
static const struct yas5xx_chip_info yas5xx_chip_info_tbl[] = {
922+
[yas530] = {
923+
.devid = YAS530_DEVICE_ID,
924+
.product_name = "YAS530 MS-3E",
925+
.version_names = { "A", "B" },
926+
},
927+
[yas532] = {
928+
.devid = YAS532_DEVICE_ID,
929+
.product_name = "YAS532 MS-3R",
930+
.version_names = { "AB", "AC" },
931+
},
932+
[yas533] = {
933+
.devid = YAS532_DEVICE_ID,
934+
.product_name = "YAS533 MS-3F",
935+
.version_names = { "AB", "AC" },
936+
},
937+
};
938+
898939
static int yas5xx_probe(struct i2c_client *i2c,
899940
const struct i2c_device_id *id)
900941
{
901942
struct iio_dev *indio_dev;
902943
struct device *dev = &i2c->dev;
903944
struct yas5xx *yas5xx;
945+
const struct yas5xx_chip_info *ci;
946+
int id_check;
904947
int ret;
905948

906949
indio_dev = devm_iio_device_alloc(dev, sizeof(*yas5xx));
@@ -947,33 +990,40 @@ static int yas5xx_probe(struct i2c_client *i2c,
947990
goto assert_reset;
948991
}
949992

950-
ret = regmap_read(yas5xx->map, YAS5XX_DEVICE_ID, &yas5xx->devid);
993+
yas5xx->chip_info = &yas5xx_chip_info_tbl[id->driver_data];
994+
ci = yas5xx->chip_info;
995+
996+
ret = regmap_read(yas5xx->map, YAS5XX_DEVICE_ID, &id_check);
951997
if (ret)
952998
goto assert_reset;
953999

954-
switch (yas5xx->devid) {
1000+
if (id_check != ci->devid) {
1001+
ret = dev_err_probe(dev, -ENODEV,
1002+
"device ID %02x doesn't match %s\n",
1003+
id_check, id->name);
1004+
goto assert_reset;
1005+
}
1006+
1007+
switch (ci->devid) {
9551008
case YAS530_DEVICE_ID:
9561009
ret = yas530_get_calibration_data(yas5xx);
9571010
if (ret)
9581011
goto assert_reset;
959-
dev_info(dev, "detected YAS530 MS-3E %s",
960-
yas5xx->version ? "B" : "A");
961-
strncpy(yas5xx->name, "yas530", sizeof(yas5xx->name));
9621012
break;
9631013
case YAS532_DEVICE_ID:
9641014
ret = yas532_get_calibration_data(yas5xx);
9651015
if (ret)
9661016
goto assert_reset;
967-
dev_info(dev, "detected YAS532/YAS533 MS-3R/F %s",
968-
yas5xx->version ? "AC" : "AB");
969-
strncpy(yas5xx->name, "yas532", sizeof(yas5xx->name));
9701017
break;
9711018
default:
9721019
ret = -ENODEV;
973-
dev_err(dev, "unhandled device ID %02x\n", yas5xx->devid);
1020+
dev_err(dev, "unhandled device ID %02x\n", ci->devid);
9741021
goto assert_reset;
9751022
}
9761023

1024+
dev_info(dev, "detected %s %s\n", ci->product_name,
1025+
ci->version_names[yas5xx->version]);
1026+
9771027
yas530_dump_calibration(yas5xx);
9781028
ret = yas530_power_on(yas5xx);
9791029
if (ret)
@@ -985,7 +1035,7 @@ static int yas5xx_probe(struct i2c_client *i2c,
9851035
indio_dev->info = &yas5xx_info;
9861036
indio_dev->available_scan_masks = yas5xx_scan_masks;
9871037
indio_dev->modes = INDIO_DIRECT_MODE;
988-
indio_dev->name = yas5xx->name;
1038+
indio_dev->name = id->name;
9891039
indio_dev->channels = yas5xx_channels;
9901040
indio_dev->num_channels = ARRAY_SIZE(yas5xx_channels);
9911041

@@ -1096,9 +1146,9 @@ static DEFINE_RUNTIME_DEV_PM_OPS(yas5xx_dev_pm_ops, yas5xx_runtime_suspend,
10961146
yas5xx_runtime_resume, NULL);
10971147

10981148
static const struct i2c_device_id yas5xx_id[] = {
1099-
{"yas530", },
1100-
{"yas532", },
1101-
{"yas533", },
1149+
{"yas530", yas530 },
1150+
{"yas532", yas532 },
1151+
{"yas533", yas533 },
11021152
{}
11031153
};
11041154
MODULE_DEVICE_TABLE(i2c, yas5xx_id);

0 commit comments

Comments
 (0)