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: light: veml6030: extend regmap to support regfields

Add support for regfields as well to simplify register operations,
taking into account the different fields for the veml6030/veml7700 and
veml6035.

Signed-off-by: Javier Carrasco <javier.carrasco.cruz@gmail.com>
Link: https://patch.msgid.link/20250119-veml6030-scale-v2-1-6bfc4062a371@gmail.com
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>

authored by

Javier Carrasco and committed by
Jonathan Cameron
9c7eb1ab cf67879b

+70 -25
+70 -25
drivers/iio/light/veml6030.c
··· 59 59 #define VEML6035_INT_CHAN BIT(3) 60 60 #define VEML6035_CHAN_EN BIT(2) 61 61 62 + /* Regfields */ 63 + #define VEML6030_GAIN_RF REG_FIELD(VEML6030_REG_ALS_CONF, 11, 12) 64 + #define VEML6030_IT_RF REG_FIELD(VEML6030_REG_ALS_CONF, 6, 9) 65 + 66 + #define VEML6035_GAIN_RF REG_FIELD(VEML6030_REG_ALS_CONF, 10, 12) 67 + 62 68 enum veml6030_scan { 63 69 VEML6030_SCAN_ALS, 64 70 VEML6030_SCAN_WH, 65 71 VEML6030_SCAN_TIMESTAMP, 72 + }; 73 + 74 + struct veml6030_rf { 75 + struct regmap_field *it; 76 + struct regmap_field *gain; 66 77 }; 67 78 68 79 struct veml603x_chip { ··· 82 71 const int num_scale_vals; 83 72 const struct iio_chan_spec *channels; 84 73 const int num_channels; 74 + const struct reg_field gain_rf; 75 + const struct reg_field it_rf; 85 76 int (*hw_init)(struct iio_dev *indio_dev, struct device *dev); 86 77 int (*set_info)(struct iio_dev *indio_dev); 87 78 int (*set_als_gain)(struct iio_dev *indio_dev, int val, int val2); ··· 104 91 struct veml6030_data { 105 92 struct i2c_client *client; 106 93 struct regmap *regmap; 94 + struct veml6030_rf rf; 107 95 int cur_resolution; 108 96 int cur_gain; 109 97 int cur_integration_time; ··· 344 330 static int veml6030_get_intgrn_tm(struct iio_dev *indio_dev, 345 331 int *val, int *val2) 346 332 { 347 - int ret, reg; 333 + int it_idx, ret; 348 334 struct veml6030_data *data = iio_priv(indio_dev); 349 335 350 - ret = regmap_read(data->regmap, VEML6030_REG_ALS_CONF, &reg); 336 + ret = regmap_field_read(data->rf.it, &it_idx); 351 337 if (ret) { 352 338 dev_err(&data->client->dev, 353 339 "can't read als conf register %d\n", ret); 354 340 return ret; 355 341 } 356 342 357 - switch ((reg >> 6) & 0xF) { 343 + switch (it_idx) { 358 344 case 0: 359 345 *val2 = 100000; 360 346 break; ··· 419 405 return -EINVAL; 420 406 } 421 407 422 - ret = regmap_update_bits(data->regmap, VEML6030_REG_ALS_CONF, 423 - VEML6030_ALS_IT, new_int_time); 408 + ret = regmap_field_write(data->rf.it, new_int_time); 424 409 if (ret) { 425 410 dev_err(&data->client->dev, 426 411 "can't update als integration time %d\n", ret); ··· 523 510 struct veml6030_data *data = iio_priv(indio_dev); 524 511 525 512 if (val == 0 && val2 == 125000) { 526 - new_gain = 0x1000; /* 0x02 << 11 */ 513 + new_gain = 0x01; 527 514 gain_idx = 3; 528 515 } else if (val == 0 && val2 == 250000) { 529 - new_gain = 0x1800; 516 + new_gain = 0x11; 530 517 gain_idx = 2; 531 518 } else if (val == 1 && val2 == 0) { 532 519 new_gain = 0x00; 533 520 gain_idx = 1; 534 521 } else if (val == 2 && val2 == 0) { 535 - new_gain = 0x800; 522 + new_gain = 0x01; 536 523 gain_idx = 0; 537 524 } else { 538 525 return -EINVAL; 539 526 } 540 527 541 - ret = regmap_update_bits(data->regmap, VEML6030_REG_ALS_CONF, 542 - VEML6030_ALS_GAIN, new_gain); 528 + ret = regmap_field_write(data->rf.gain, new_gain); 543 529 if (ret) { 544 530 dev_err(&data->client->dev, 545 531 "can't set als gain %d\n", ret); ··· 556 544 struct veml6030_data *data = iio_priv(indio_dev); 557 545 558 546 if (val == 0 && val2 == 125000) { 559 - new_gain = VEML6035_SENS; 547 + new_gain = FIELD_GET(VEML6035_GAIN_M, VEML6035_SENS); 560 548 gain_idx = 5; 561 549 } else if (val == 0 && val2 == 250000) { 562 - new_gain = VEML6035_SENS | VEML6035_GAIN; 550 + new_gain = FIELD_GET(VEML6035_GAIN_M, VEML6035_SENS | 551 + VEML6035_GAIN); 563 552 gain_idx = 4; 564 553 } else if (val == 0 && val2 == 500000) { 565 - new_gain = VEML6035_SENS | VEML6035_GAIN | 566 - VEML6035_DG; 554 + new_gain = FIELD_GET(VEML6035_GAIN_M, VEML6035_SENS | 555 + VEML6035_GAIN | VEML6035_DG); 567 556 gain_idx = 3; 568 557 } else if (val == 1 && val2 == 0) { 569 558 new_gain = 0x0000; 570 559 gain_idx = 2; 571 560 } else if (val == 2 && val2 == 0) { 572 - new_gain = VEML6035_GAIN; 561 + new_gain = FIELD_GET(VEML6035_GAIN_M, VEML6035_GAIN); 573 562 gain_idx = 1; 574 563 } else if (val == 4 && val2 == 0) { 575 - new_gain = VEML6035_GAIN | VEML6035_DG; 564 + new_gain = FIELD_GET(VEML6035_GAIN_M, VEML6035_GAIN | 565 + VEML6035_DG); 576 566 gain_idx = 0; 577 567 } else { 578 568 return -EINVAL; 579 569 } 580 570 581 - ret = regmap_update_bits(data->regmap, VEML6030_REG_ALS_CONF, 582 - VEML6035_GAIN_M, new_gain); 571 + ret = regmap_field_write(data->rf.gain, new_gain); 583 572 if (ret) { 584 573 dev_err(&data->client->dev, "can't set als gain %d\n", ret); 585 574 return ret; ··· 594 581 static int veml6030_get_als_gain(struct iio_dev *indio_dev, 595 582 int *val, int *val2) 596 583 { 597 - int ret, reg; 584 + int gain, ret; 598 585 struct veml6030_data *data = iio_priv(indio_dev); 599 586 600 - ret = regmap_read(data->regmap, VEML6030_REG_ALS_CONF, &reg); 587 + ret = regmap_field_read(data->rf.gain, &gain); 601 588 if (ret) { 602 589 dev_err(&data->client->dev, 603 590 "can't read als conf register %d\n", ret); 604 591 return ret; 605 592 } 606 593 607 - switch ((reg >> 11) & 0x03) { 594 + switch (gain) { 608 595 case 0: 609 596 *val = 1; 610 597 *val2 = 0; ··· 630 617 631 618 static int veml6035_get_als_gain(struct iio_dev *indio_dev, int *val, int *val2) 632 619 { 633 - int ret, reg; 620 + int gain, ret; 634 621 struct veml6030_data *data = iio_priv(indio_dev); 635 622 636 - ret = regmap_read(data->regmap, VEML6030_REG_ALS_CONF, &reg); 623 + ret = regmap_field_read(data->rf.gain, &gain); 637 624 if (ret) { 638 625 dev_err(&data->client->dev, 639 - "can't read als conf register %d\n", ret); 626 + "can't read als conf register %d\n", ret); 640 627 return ret; 641 628 } 642 629 643 - switch (FIELD_GET(VEML6035_GAIN_M, reg)) { 630 + switch (gain) { 644 631 case 0: 645 632 *val = 1; 646 633 *val2 = 0; ··· 1003 990 return 0; 1004 991 } 1005 992 993 + static int veml6030_regfield_init(struct iio_dev *indio_dev) 994 + { 995 + struct veml6030_data *data = iio_priv(indio_dev); 996 + struct regmap *regmap = data->regmap; 997 + struct device *dev = &data->client->dev; 998 + struct regmap_field *rm_field; 999 + struct veml6030_rf *rf = &data->rf; 1000 + 1001 + rm_field = devm_regmap_field_alloc(dev, regmap, data->chip->it_rf); 1002 + if (IS_ERR(rm_field)) 1003 + return PTR_ERR(rm_field); 1004 + rf->it = rm_field; 1005 + 1006 + rm_field = devm_regmap_field_alloc(dev, regmap, data->chip->gain_rf); 1007 + if (IS_ERR(rm_field)) 1008 + return PTR_ERR(rm_field); 1009 + rf->gain = rm_field; 1010 + 1011 + return 0; 1012 + } 1013 + 1006 1014 /* 1007 1015 * Set ALS gain to 1/8, integration time to 100 ms, PSM to mode 2, 1008 1016 * persistence to 1 x integration time and the threshold ··· 1177 1143 if (ret < 0) 1178 1144 return ret; 1179 1145 1146 + ret = veml6030_regfield_init(indio_dev); 1147 + if (ret) 1148 + return dev_err_probe(&client->dev, ret, 1149 + "failed to init regfields\n"); 1150 + 1180 1151 ret = data->chip->hw_init(indio_dev, &client->dev); 1181 1152 if (ret < 0) 1182 1153 return ret; ··· 1230 1191 .num_scale_vals = ARRAY_SIZE(veml6030_scale_vals), 1231 1192 .channels = veml6030_channels, 1232 1193 .num_channels = ARRAY_SIZE(veml6030_channels), 1194 + .gain_rf = VEML6030_GAIN_RF, 1195 + .it_rf = VEML6030_IT_RF, 1233 1196 .hw_init = veml6030_hw_init, 1234 1197 .set_info = veml6030_set_info, 1235 1198 .set_als_gain = veml6030_set_als_gain, ··· 1244 1203 .num_scale_vals = ARRAY_SIZE(veml6035_scale_vals), 1245 1204 .channels = veml6030_channels, 1246 1205 .num_channels = ARRAY_SIZE(veml6030_channels), 1206 + .gain_rf = VEML6035_GAIN_RF, 1207 + .it_rf = VEML6030_IT_RF, 1247 1208 .hw_init = veml6035_hw_init, 1248 1209 .set_info = veml6030_set_info, 1249 1210 .set_als_gain = veml6035_set_als_gain, ··· 1258 1215 .num_scale_vals = ARRAY_SIZE(veml6030_scale_vals), 1259 1216 .channels = veml7700_channels, 1260 1217 .num_channels = ARRAY_SIZE(veml7700_channels), 1218 + .gain_rf = VEML6030_GAIN_RF, 1219 + .it_rf = VEML6030_IT_RF, 1261 1220 .hw_init = veml6030_hw_init, 1262 1221 .set_info = veml7700_set_info, 1263 1222 .set_als_gain = veml6030_set_als_gain,