Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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 <jahau@rocketmail.com>
Reviewed-by: Linus Walleij <linus.walleij@linaro.org>
Link: https://lore.kernel.org/r/57236545107286771d351b95091bf56815d3717d.1660337264.git.jahau@rocketmail.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Jakob Hauser and committed by
Jonathan Cameron
a70f60e5 92d9c05c

+74 -24
+74 -24
drivers/iio/magnetometer/yamaha-yas530.c
··· 96 96 /* Turn off device regulators etc after 5 seconds of inactivity */ 97 97 #define YAS5XX_AUTOSUSPEND_DELAY_MS 5000 98 98 99 + enum chip_ids { 100 + yas530, 101 + yas532, 102 + yas533, 103 + }; 104 + 99 105 struct yas5xx_calibration { 100 106 /* Linearization calibration x, y1, y2 */ 101 107 s32 r[3]; ··· 116 110 u8 dck; 117 111 }; 118 112 113 + struct yas5xx; 114 + 115 + /** 116 + * struct yas5xx_chip_info - device-specific data and function pointers 117 + * @devid: device ID number 118 + * @product_name: product name of the YAS variant 119 + * @version_names: version letters or namings 120 + */ 121 + struct yas5xx_chip_info { 122 + unsigned int devid; 123 + char *product_name; 124 + char *version_names[2]; 125 + }; 126 + 119 127 /** 120 128 * struct yas5xx - state container for the YAS5xx driver 121 129 * @dev: parent device pointer 122 - * @devid: device ID number 130 + * @chip_info: device-specific data 123 131 * @version: device version 124 - * @name: device name 125 132 * @calibration: calibration settings from the OTP storage 126 133 * @hard_offsets: offsets for each axis measured with initcoil actuated 127 134 * @orientation: mounting matrix, flipped axis etc ··· 148 129 */ 149 130 struct yas5xx { 150 131 struct device *dev; 151 - unsigned int devid; 132 + const struct yas5xx_chip_info *chip_info; 152 133 unsigned int version; 153 - char name[16]; 154 134 struct yas5xx_calibration calibration; 155 135 s8 hard_offsets[3]; 156 136 struct iio_mount_matrix orientation; ··· 210 192 */ 211 193 static int yas530_measure(struct yas5xx *yas5xx, u16 *t, u16 *x, u16 *y1, u16 *y2) 212 194 { 195 + const struct yas5xx_chip_info *ci = yas5xx->chip_info; 213 196 unsigned int busy; 214 197 u8 data[8]; 215 198 int ret; ··· 241 222 242 223 mutex_unlock(&yas5xx->lock); 243 224 244 - switch (yas5xx->devid) { 225 + switch (ci->devid) { 245 226 case YAS530_DEVICE_ID: 246 227 /* 247 228 * The t value is 9 bits in big endian format ··· 286 267 /* Used by YAS530, YAS532 and YAS533 */ 287 268 static s32 yas530_linearize(struct yas5xx *yas5xx, u16 val, int axis) 288 269 { 270 + const struct yas5xx_chip_info *ci = yas5xx->chip_info; 289 271 struct yas5xx_calibration *c = &yas5xx->calibration; 290 272 static const s32 yas532ac_coef[] = { 291 273 YAS532_VERSION_AC_COEF_X, ··· 296 276 s32 coef; 297 277 298 278 /* Select coefficients */ 299 - switch (yas5xx->devid) { 279 + switch (ci->devid) { 300 280 case YAS530_DEVICE_ID: 301 281 if (yas5xx->version == YAS530_VERSION_A) 302 282 coef = YAS530_VERSION_A_COEF; ··· 339 319 */ 340 320 static int yas530_get_measure(struct yas5xx *yas5xx, s32 *to, s32 *xo, s32 *yo, s32 *zo) 341 321 { 322 + const struct yas5xx_chip_info *ci = yas5xx->chip_info; 342 323 struct yas5xx_calibration *c = &yas5xx->calibration; 343 324 u16 t_ref, t, x, y1, y2; 344 325 /* These are signed x, signed y1 etc */ ··· 357 336 sy2 = yas530_linearize(yas5xx, y2, 2); 358 337 359 338 /* Set the temperature reference value (unit: counts) */ 360 - switch (yas5xx->devid) { 339 + switch (ci->devid) { 361 340 case YAS530_DEVICE_ID: 362 341 t_ref = YAS530_20DEGREES; 363 342 break; ··· 370 349 } 371 350 372 351 /* Temperature compensation for x, y1, y2 respectively */ 373 - if (yas5xx->devid == YAS532_DEVICE_ID && 352 + if (ci->devid == YAS532_DEVICE_ID && 374 353 yas5xx->version == YAS532_VERSION_AC) { 375 354 /* 376 355 * YAS532 version AC uses the temperature deviation as a ··· 405 384 sz = -sy1 - sy2; 406 385 407 386 /* Process temperature readout */ 408 - switch (yas5xx->devid) { 387 + switch (ci->devid) { 409 388 case YAS530_DEVICE_ID: 410 389 /* 411 390 * Raw temperature value t is the number of counts starting ··· 463 442 long mask) 464 443 { 465 444 struct yas5xx *yas5xx = iio_priv(indio_dev); 445 + const struct yas5xx_chip_info *ci = yas5xx->chip_info; 466 446 s32 t, x, y, z; 467 447 int ret; 468 448 ··· 495 473 } 496 474 return IIO_VAL_INT; 497 475 case IIO_CHAN_INFO_SCALE: 498 - switch (yas5xx->devid) { 476 + switch (ci->devid) { 499 477 case YAS530_DEVICE_ID: 500 478 /* 501 479 * Raw values of YAS530 are in picotesla. Divide by ··· 824 802 /* Used by YAS530, YAS532 and YAS533 */ 825 803 static int yas530_measure_offsets(struct yas5xx *yas5xx) 826 804 { 805 + const struct yas5xx_chip_info *ci = yas5xx->chip_info; 827 806 int ret; 828 807 u16 center; 829 808 u16 t, x, y1, y2; ··· 837 814 return ret; 838 815 839 816 /* When the initcoil is active this should be around the center */ 840 - switch (yas5xx->devid) { 817 + switch (ci->devid) { 841 818 case YAS530_DEVICE_ID: 842 819 center = YAS530_DATA_CENTER; 843 820 break; ··· 918 895 return regmap_write(yas5xx->map, YAS530_MEASURE_INTERVAL, 0); 919 896 } 920 897 898 + static const struct yas5xx_chip_info yas5xx_chip_info_tbl[] = { 899 + [yas530] = { 900 + .devid = YAS530_DEVICE_ID, 901 + .product_name = "YAS530 MS-3E", 902 + .version_names = { "A", "B" }, 903 + }, 904 + [yas532] = { 905 + .devid = YAS532_DEVICE_ID, 906 + .product_name = "YAS532 MS-3R", 907 + .version_names = { "AB", "AC" }, 908 + }, 909 + [yas533] = { 910 + .devid = YAS532_DEVICE_ID, 911 + .product_name = "YAS533 MS-3F", 912 + .version_names = { "AB", "AC" }, 913 + }, 914 + }; 915 + 921 916 static int yas5xx_probe(struct i2c_client *i2c, 922 917 const struct i2c_device_id *id) 923 918 { 924 919 struct iio_dev *indio_dev; 925 920 struct device *dev = &i2c->dev; 926 921 struct yas5xx *yas5xx; 922 + const struct yas5xx_chip_info *ci; 923 + int id_check; 927 924 int ret; 928 925 929 926 indio_dev = devm_iio_device_alloc(dev, sizeof(*yas5xx)); ··· 990 947 goto assert_reset; 991 948 } 992 949 993 - ret = regmap_read(yas5xx->map, YAS5XX_DEVICE_ID, &yas5xx->devid); 950 + yas5xx->chip_info = &yas5xx_chip_info_tbl[id->driver_data]; 951 + ci = yas5xx->chip_info; 952 + 953 + ret = regmap_read(yas5xx->map, YAS5XX_DEVICE_ID, &id_check); 994 954 if (ret) 995 955 goto assert_reset; 996 956 997 - switch (yas5xx->devid) { 957 + if (id_check != ci->devid) { 958 + ret = dev_err_probe(dev, -ENODEV, 959 + "device ID %02x doesn't match %s\n", 960 + id_check, id->name); 961 + goto assert_reset; 962 + } 963 + 964 + switch (ci->devid) { 998 965 case YAS530_DEVICE_ID: 999 966 ret = yas530_get_calibration_data(yas5xx); 1000 967 if (ret) 1001 968 goto assert_reset; 1002 - dev_info(dev, "detected YAS530 MS-3E %s", 1003 - yas5xx->version ? "B" : "A"); 1004 - strncpy(yas5xx->name, "yas530", sizeof(yas5xx->name)); 1005 969 break; 1006 970 case YAS532_DEVICE_ID: 1007 971 ret = yas532_get_calibration_data(yas5xx); 1008 972 if (ret) 1009 973 goto assert_reset; 1010 - dev_info(dev, "detected YAS532/YAS533 MS-3R/F %s", 1011 - yas5xx->version ? "AC" : "AB"); 1012 - strncpy(yas5xx->name, "yas532", sizeof(yas5xx->name)); 1013 974 break; 1014 975 default: 1015 976 ret = -ENODEV; 1016 - dev_err(dev, "unhandled device ID %02x\n", yas5xx->devid); 977 + dev_err(dev, "unhandled device ID %02x\n", ci->devid); 1017 978 goto assert_reset; 1018 979 } 980 + 981 + dev_info(dev, "detected %s %s\n", ci->product_name, 982 + ci->version_names[yas5xx->version]); 1019 983 1020 984 yas530_dump_calibration(yas5xx); 1021 985 ret = yas530_power_on(yas5xx); ··· 1035 985 indio_dev->info = &yas5xx_info; 1036 986 indio_dev->available_scan_masks = yas5xx_scan_masks; 1037 987 indio_dev->modes = INDIO_DIRECT_MODE; 1038 - indio_dev->name = yas5xx->name; 988 + indio_dev->name = id->name; 1039 989 indio_dev->channels = yas5xx_channels; 1040 990 indio_dev->num_channels = ARRAY_SIZE(yas5xx_channels); 1041 991 ··· 1146 1096 yas5xx_runtime_resume, NULL); 1147 1097 1148 1098 static const struct i2c_device_id yas5xx_id[] = { 1149 - {"yas530", }, 1150 - {"yas532", }, 1151 - {"yas533", }, 1099 + {"yas530", yas530 }, 1100 + {"yas532", yas532 }, 1101 + {"yas533", yas533 }, 1152 1102 {} 1153 1103 }; 1154 1104 MODULE_DEVICE_TABLE(i2c, yas5xx_id);