veml6030.c (46e28867540434f94ddb745c74466f40669bcc48) | veml6030.c (22eaca4283b216f5e1f7721e4ad0ecb3d23c6774) |
---|---|
1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * VEML6030, VMEL6035 and VEML7700 Ambient Light Sensors 4 * 5 * Copyright (c) 2019, Rishi Gupta <gupt21@gmail.com> 6 * 7 * VEML6030: 8 * Datasheet: https://www.vishay.com/docs/84366/veml6030.pdf --- 10 unchanged lines hidden (view full) --- 19 20#include <linux/bitfield.h> 21#include <linux/module.h> 22#include <linux/i2c.h> 23#include <linux/err.h> 24#include <linux/regmap.h> 25#include <linux/interrupt.h> 26#include <linux/pm_runtime.h> | 1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * VEML6030, VMEL6035 and VEML7700 Ambient Light Sensors 4 * 5 * Copyright (c) 2019, Rishi Gupta <gupt21@gmail.com> 6 * 7 * VEML6030: 8 * Datasheet: https://www.vishay.com/docs/84366/veml6030.pdf --- 10 unchanged lines hidden (view full) --- 19 20#include <linux/bitfield.h> 21#include <linux/module.h> 22#include <linux/i2c.h> 23#include <linux/err.h> 24#include <linux/regmap.h> 25#include <linux/interrupt.h> 26#include <linux/pm_runtime.h> |
27#include <linux/units.h> |
|
27#include <linux/regulator/consumer.h> 28#include <linux/iio/iio.h> 29#include <linux/iio/sysfs.h> 30#include <linux/iio/events.h> | 28#include <linux/regulator/consumer.h> 29#include <linux/iio/iio.h> 30#include <linux/iio/sysfs.h> 31#include <linux/iio/events.h> |
32#include <linux/iio/iio-gts-helper.h> |
|
31#include <linux/iio/trigger_consumer.h> 32#include <linux/iio/triggered_buffer.h> 33 34/* Device registers */ 35#define VEML6030_REG_ALS_CONF 0x00 36#define VEML6030_REG_ALS_WH 0x01 37#define VEML6030_REG_ALS_WL 0x02 38#define VEML6030_REG_ALS_PSM 0x03 --- 21 unchanged lines hidden (view full) --- 60#define VEML6035_CHAN_EN BIT(2) 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 | 33#include <linux/iio/trigger_consumer.h> 34#include <linux/iio/triggered_buffer.h> 35 36/* Device registers */ 37#define VEML6030_REG_ALS_CONF 0x00 38#define VEML6030_REG_ALS_WH 0x01 39#define VEML6030_REG_ALS_WL 0x02 40#define VEML6030_REG_ALS_PSM 0x03 --- 21 unchanged lines hidden (view full) --- 62#define VEML6035_CHAN_EN BIT(2) 63 64/* Regfields */ 65#define VEML6030_GAIN_RF REG_FIELD(VEML6030_REG_ALS_CONF, 11, 12) 66#define VEML6030_IT_RF REG_FIELD(VEML6030_REG_ALS_CONF, 6, 9) 67 68#define VEML6035_GAIN_RF REG_FIELD(VEML6030_REG_ALS_CONF, 10, 12) 69 |
70/* Maximum scales x 10000 to work with integers */ 71#define VEML6030_MAX_SCALE 21504 72#define VEML6035_MAX_SCALE 4096 73 |
|
68enum veml6030_scan { 69 VEML6030_SCAN_ALS, 70 VEML6030_SCAN_WH, 71 VEML6030_SCAN_TIMESTAMP, 72}; 73 74struct veml6030_rf { 75 struct regmap_field *it; 76 struct regmap_field *gain; 77}; 78 79struct veml603x_chip { 80 const char *name; | 74enum veml6030_scan { 75 VEML6030_SCAN_ALS, 76 VEML6030_SCAN_WH, 77 VEML6030_SCAN_TIMESTAMP, 78}; 79 80struct veml6030_rf { 81 struct regmap_field *it; 82 struct regmap_field *gain; 83}; 84 85struct veml603x_chip { 86 const char *name; |
81 const int(*scale_vals)[][2]; 82 const int num_scale_vals; | |
83 const struct iio_chan_spec *channels; 84 const int num_channels; 85 const struct reg_field gain_rf; 86 const struct reg_field it_rf; | 87 const struct iio_chan_spec *channels; 88 const int num_channels; 89 const struct reg_field gain_rf; 90 const struct reg_field it_rf; |
91 const int max_scale; |
|
87 int (*hw_init)(struct iio_dev *indio_dev, struct device *dev); 88 int (*set_info)(struct iio_dev *indio_dev); | 92 int (*hw_init)(struct iio_dev *indio_dev, struct device *dev); 93 int (*set_info)(struct iio_dev *indio_dev); |
89 int (*set_als_gain)(struct iio_dev *indio_dev, int val, int val2); 90 int (*get_als_gain)(struct iio_dev *indio_dev, int *val, int *val2); | |
91}; 92 93/* 94 * The resolution depends on both gain and integration time. The 95 * cur_resolution stores one of the resolution mentioned in the 96 * table during startup and gets updated whenever integration time 97 * or gain is changed. 98 * 99 * Table 'resolution and maximum detection range' in the appnotes 100 * is visualized as a 2D array. The cur_gain stores index of gain 101 * in this table (0-3 for VEML6030, 0-5 for VEML6035) while the 102 * cur_integration_time holds index of integration time (0-5). 103 */ 104struct veml6030_data { 105 struct i2c_client *client; 106 struct regmap *regmap; 107 struct veml6030_rf rf; | 94}; 95 96/* 97 * The resolution depends on both gain and integration time. The 98 * cur_resolution stores one of the resolution mentioned in the 99 * table during startup and gets updated whenever integration time 100 * or gain is changed. 101 * 102 * Table 'resolution and maximum detection range' in the appnotes 103 * is visualized as a 2D array. The cur_gain stores index of gain 104 * in this table (0-3 for VEML6030, 0-5 for VEML6035) while the 105 * cur_integration_time holds index of integration time (0-5). 106 */ 107struct veml6030_data { 108 struct i2c_client *client; 109 struct regmap *regmap; 110 struct veml6030_rf rf; |
108 int cur_resolution; 109 int cur_gain; 110 int cur_integration_time; | |
111 const struct veml603x_chip *chip; | 111 const struct veml603x_chip *chip; |
112 struct iio_gts gts; 113 |
|
112}; 113 | 114}; 115 |
114static const int veml6030_it_times[][2] = { 115 { 0, 25000 }, 116 { 0, 50000 }, 117 { 0, 100000 }, 118 { 0, 200000 }, 119 { 0, 400000 }, 120 { 0, 800000 }, | 116#define VEML6030_SEL_IT_25MS 0x0C 117#define VEML6030_SEL_IT_50MS 0x08 118#define VEML6030_SEL_IT_100MS 0x00 119#define VEML6030_SEL_IT_200MS 0x01 120#define VEML6030_SEL_IT_400MS 0x02 121#define VEML6030_SEL_IT_800MS 0x03 122static const struct iio_itime_sel_mul veml6030_it_sel[] = { 123 GAIN_SCALE_ITIME_US(25000, VEML6030_SEL_IT_25MS, 1), 124 GAIN_SCALE_ITIME_US(50000, VEML6030_SEL_IT_50MS, 2), 125 GAIN_SCALE_ITIME_US(100000, VEML6030_SEL_IT_100MS, 4), 126 GAIN_SCALE_ITIME_US(200000, VEML6030_SEL_IT_200MS, 8), 127 GAIN_SCALE_ITIME_US(400000, VEML6030_SEL_IT_400MS, 16), 128 GAIN_SCALE_ITIME_US(800000, VEML6030_SEL_IT_800MS, 32), |
121}; 122 | 129}; 130 |
123/* 124 * Scale is 1/gain. Value 0.125 is ALS gain x (1/8), 0.25 is 125 * ALS gain x (1/4), 0.5 is ALS gain x (1/2), 1.0 is ALS gain x 1, 126 * 2.0 is ALS gain x2, and 4.0 is ALS gain x 4. | 131/* Gains are multiplied by 8 to work with integers. The values in the 132 * iio-gts tables don't need corrections because the maximum value of 133 * the scale refers to GAIN = x1, and the rest of the values are 134 * obtained from the resulting linear function. |
127 */ | 135 */ |
128static const int veml6030_scale_vals[][2] = { 129 { 0, 125000 }, 130 { 0, 250000 }, 131 { 1, 0 }, 132 { 2, 0 }, | 136#define VEML6030_SEL_MILLI_GAIN_X125 2 137#define VEML6030_SEL_MILLI_GAIN_X250 3 138#define VEML6030_SEL_MILLI_GAIN_X1000 0 139#define VEML6030_SEL_MILLI_GAIN_X2000 1 140static const struct iio_gain_sel_pair veml6030_gain_sel[] = { 141 GAIN_SCALE_GAIN(1, VEML6030_SEL_MILLI_GAIN_X125), 142 GAIN_SCALE_GAIN(2, VEML6030_SEL_MILLI_GAIN_X250), 143 GAIN_SCALE_GAIN(8, VEML6030_SEL_MILLI_GAIN_X1000), 144 GAIN_SCALE_GAIN(16, VEML6030_SEL_MILLI_GAIN_X2000), |
133}; 134 | 145}; 146 |
135static const int veml6035_scale_vals[][2] = { 136 { 0, 125000 }, 137 { 0, 250000 }, 138 { 0, 500000 }, 139 { 1, 0 }, 140 { 2, 0 }, 141 { 4, 0 }, | 147#define VEML6035_SEL_MILLI_GAIN_X125 4 148#define VEML6035_SEL_MILLI_GAIN_X250 5 149#define VEML6035_SEL_MILLI_GAIN_X500 7 150#define VEML6035_SEL_MILLI_GAIN_X1000 0 151#define VEML6035_SEL_MILLI_GAIN_X2000 1 152#define VEML6035_SEL_MILLI_GAIN_X4000 3 153static const struct iio_gain_sel_pair veml6035_gain_sel[] = { 154 GAIN_SCALE_GAIN(1, VEML6035_SEL_MILLI_GAIN_X125), 155 GAIN_SCALE_GAIN(2, VEML6035_SEL_MILLI_GAIN_X250), 156 GAIN_SCALE_GAIN(4, VEML6035_SEL_MILLI_GAIN_X500), 157 GAIN_SCALE_GAIN(8, VEML6035_SEL_MILLI_GAIN_X1000), 158 GAIN_SCALE_GAIN(16, VEML6035_SEL_MILLI_GAIN_X2000), 159 GAIN_SCALE_GAIN(32, VEML6035_SEL_MILLI_GAIN_X4000), |
142}; 143 144/* 145 * Persistence = 1/2/4/8 x integration time 146 * Minimum time for which light readings must stay above configured 147 * threshold to assert the interrupt. 148 */ 149static const char * const period_values[] = { --- 217 unchanged lines hidden (view full) --- 367 .max_register = VEML6030_REG_ALS_INT, 368 .val_format_endian = REGMAP_ENDIAN_LITTLE, 369 .rd_table = &veml6030_readable_table, 370 .wr_table = &veml6030_writable_table, 371 .volatile_table = &veml6030_volatile_table, 372 .cache_type = REGCACHE_RBTREE, 373}; 374 | 160}; 161 162/* 163 * Persistence = 1/2/4/8 x integration time 164 * Minimum time for which light readings must stay above configured 165 * threshold to assert the interrupt. 166 */ 167static const char * const period_values[] = { --- 217 unchanged lines hidden (view full) --- 385 .max_register = VEML6030_REG_ALS_INT, 386 .val_format_endian = REGMAP_ENDIAN_LITTLE, 387 .rd_table = &veml6030_readable_table, 388 .wr_table = &veml6030_writable_table, 389 .volatile_table = &veml6030_volatile_table, 390 .cache_type = REGCACHE_RBTREE, 391}; 392 |
375static int veml6030_get_intgrn_tm(struct iio_dev *indio_dev, 376 int *val, int *val2) | 393static int veml6030_get_it(struct veml6030_data *data, int *val, int *val2) |
377{ | 394{ |
378 int it_idx, ret; 379 struct veml6030_data *data = iio_priv(indio_dev); | 395 int ret, it_idx; |
380 381 ret = regmap_field_read(data->rf.it, &it_idx); | 396 397 ret = regmap_field_read(data->rf.it, &it_idx); |
382 if (ret) { 383 dev_err(&data->client->dev, 384 "can't read als conf register %d\n", ret); | 398 if (ret) |
385 return ret; | 399 return ret; |
386 } | |
387 | 400 |
388 switch (it_idx) { 389 case 0: 390 *val2 = 100000; 391 break; 392 case 1: 393 *val2 = 200000; 394 break; 395 case 2: 396 *val2 = 400000; 397 break; 398 case 3: 399 *val2 = 800000; 400 break; 401 case 8: 402 *val2 = 50000; 403 break; 404 case 12: 405 *val2 = 25000; 406 break; 407 default: 408 return -EINVAL; 409 } | 401 ret = iio_gts_find_int_time_by_sel(&data->gts, it_idx); 402 if (ret < 0) 403 return ret; |
410 | 404 |
405 *val2 = ret; |
|
411 *val = 0; | 406 *val = 0; |
407 |
|
412 return IIO_VAL_INT_PLUS_MICRO; 413} 414 | 408 return IIO_VAL_INT_PLUS_MICRO; 409} 410 |
415static int veml6030_set_intgrn_tm(struct iio_dev *indio_dev, 416 int val, int val2) | 411static int veml6030_set_it(struct iio_dev *indio_dev, int val, int val2) |
417{ | 412{ |
418 int ret, new_int_time, int_idx; | |
419 struct veml6030_data *data = iio_priv(indio_dev); | 413 struct veml6030_data *data = iio_priv(indio_dev); |
414 int ret, gain_idx, it_idx, new_gain, prev_gain, prev_it; 415 bool in_range; |
|
420 | 416 |
421 if (val) | 417 if (val || !iio_gts_valid_time(&data->gts, val2)) |
422 return -EINVAL; 423 | 418 return -EINVAL; 419 |
424 switch (val2) { 425 case 25000: 426 new_int_time = 0x300; 427 int_idx = 5; 428 break; 429 case 50000: 430 new_int_time = 0x200; 431 int_idx = 4; 432 break; 433 case 100000: 434 new_int_time = 0x00; 435 int_idx = 3; 436 break; 437 case 200000: 438 new_int_time = 0x40; 439 int_idx = 2; 440 break; 441 case 400000: 442 new_int_time = 0x80; 443 int_idx = 1; 444 break; 445 case 800000: 446 new_int_time = 0xC0; 447 int_idx = 0; 448 break; 449 default: 450 return -EINVAL; 451 } | 420 ret = regmap_field_read(data->rf.it, &it_idx); 421 if (ret) 422 return ret; |
452 | 423 |
453 ret = regmap_field_write(data->rf.it, new_int_time); 454 if (ret) { 455 dev_err(&data->client->dev, 456 "can't update als integration time %d\n", ret); | 424 ret = regmap_field_read(data->rf.gain, &gain_idx); 425 if (ret) |
457 return ret; | 426 return ret; |
458 } | |
459 | 427 |
460 /* 461 * Cache current integration time and update resolution. For every 462 * increase in integration time to next level, resolution is halved 463 * and vice-versa. 464 */ 465 if (data->cur_integration_time < int_idx) 466 data->cur_resolution <<= int_idx - data->cur_integration_time; 467 else if (data->cur_integration_time > int_idx) 468 data->cur_resolution >>= data->cur_integration_time - int_idx; | 428 prev_it = iio_gts_find_int_time_by_sel(&data->gts, it_idx); 429 if (prev_it < 0) 430 return prev_it; |
469 | 431 |
470 data->cur_integration_time = int_idx; | 432 if (prev_it == val2) 433 return 0; |
471 | 434 |
472 return ret; | 435 prev_gain = iio_gts_find_gain_by_sel(&data->gts, gain_idx); 436 if (prev_gain < 0) 437 return prev_gain; 438 439 ret = iio_gts_find_new_gain_by_gain_time_min(&data->gts, prev_gain, prev_it, 440 val2, &new_gain, &in_range); 441 if (ret) 442 return ret; 443 444 if (!in_range) 445 dev_dbg(&data->client->dev, "Optimal gain out of range\n"); 446 447 ret = iio_gts_find_sel_by_int_time(&data->gts, val2); 448 if (ret < 0) 449 return ret; 450 451 ret = regmap_field_write(data->rf.it, ret); 452 if (ret) 453 return ret; 454 455 ret = iio_gts_find_sel_by_gain(&data->gts, new_gain); 456 if (ret < 0) 457 return ret; 458 459 return regmap_field_write(data->rf.gain, ret); |
473} 474 475static int veml6030_read_persistence(struct iio_dev *indio_dev, 476 int *val, int *val2) 477{ 478 int ret, reg, period, x, y; 479 struct veml6030_data *data = iio_priv(indio_dev); 480 | 460} 461 462static int veml6030_read_persistence(struct iio_dev *indio_dev, 463 int *val, int *val2) 464{ 465 int ret, reg, period, x, y; 466 struct veml6030_data *data = iio_priv(indio_dev); 467 |
481 ret = veml6030_get_intgrn_tm(indio_dev, &x, &y); | 468 ret = veml6030_get_it(data, &x, &y); |
482 if (ret < 0) 483 return ret; 484 485 ret = regmap_read(data->regmap, VEML6030_REG_ALS_CONF, ®); 486 if (ret) { 487 dev_err(&data->client->dev, 488 "can't read als conf register %d\n", ret); 489 } --- 8 unchanged lines hidden (view full) --- 498} 499 500static int veml6030_write_persistence(struct iio_dev *indio_dev, 501 int val, int val2) 502{ 503 int ret, period, x, y; 504 struct veml6030_data *data = iio_priv(indio_dev); 505 | 469 if (ret < 0) 470 return ret; 471 472 ret = regmap_read(data->regmap, VEML6030_REG_ALS_CONF, ®); 473 if (ret) { 474 dev_err(&data->client->dev, 475 "can't read als conf register %d\n", ret); 476 } --- 8 unchanged lines hidden (view full) --- 485} 486 487static int veml6030_write_persistence(struct iio_dev *indio_dev, 488 int val, int val2) 489{ 490 int ret, period, x, y; 491 struct veml6030_data *data = iio_priv(indio_dev); 492 |
506 ret = veml6030_get_intgrn_tm(indio_dev, &x, &y); | 493 ret = veml6030_get_it(data, &x, &y); |
507 if (ret < 0) 508 return ret; 509 510 if (!val) { 511 period = val2 / y; 512 } else { 513 if ((val == 1) && (val2 == 600000)) 514 period = 1600000 / y; --- 12 unchanged lines hidden (view full) --- 527 VEML6030_ALS_PERS, (ffs(period) - 1) << 4); 528 if (ret) 529 dev_err(&data->client->dev, 530 "can't set persistence value %d\n", ret); 531 532 return ret; 533} 534 | 494 if (ret < 0) 495 return ret; 496 497 if (!val) { 498 period = val2 / y; 499 } else { 500 if ((val == 1) && (val2 == 600000)) 501 period = 1600000 / y; --- 12 unchanged lines hidden (view full) --- 514 VEML6030_ALS_PERS, (ffs(period) - 1) << 4); 515 if (ret) 516 dev_err(&data->client->dev, 517 "can't set persistence value %d\n", ret); 518 519 return ret; 520} 521 |
535/* 536 * Cache currently set gain & update resolution. For every 537 * increase in the gain to next level, resolution is halved 538 * and vice-versa. 539 */ 540static void veml6030_update_gain_res(struct veml6030_data *data, int gain_idx) | 522static int veml6030_set_scale(struct iio_dev *indio_dev, int val, int val2) |
541{ | 523{ |
542 if (data->cur_gain < gain_idx) 543 data->cur_resolution <<= gain_idx - data->cur_gain; 544 else if (data->cur_gain > gain_idx) 545 data->cur_resolution >>= data->cur_gain - gain_idx; 546 547 data->cur_gain = gain_idx; 548} 549 550static int veml6030_set_als_gain(struct iio_dev *indio_dev, 551 int val, int val2) 552{ 553 int ret, new_gain, gain_idx; | 524 int ret, gain_sel, it_idx, it_sel; |
554 struct veml6030_data *data = iio_priv(indio_dev); 555 | 525 struct veml6030_data *data = iio_priv(indio_dev); 526 |
556 if (val == 0 && val2 == 125000) { 557 new_gain = 0x01; 558 gain_idx = 3; 559 } else if (val == 0 && val2 == 250000) { 560 new_gain = 0x11; 561 gain_idx = 2; 562 } else if (val == 1 && val2 == 0) { 563 new_gain = 0x00; 564 gain_idx = 1; 565 } else if (val == 2 && val2 == 0) { 566 new_gain = 0x01; 567 gain_idx = 0; 568 } else { 569 return -EINVAL; 570 } 571 572 ret = regmap_field_write(data->rf.gain, new_gain); 573 if (ret) { 574 dev_err(&data->client->dev, 575 "can't set als gain %d\n", ret); | 527 ret = regmap_field_read(data->rf.it, &it_idx); 528 if (ret) |
576 return ret; | 529 return ret; |
577 } | |
578 | 530 |
579 veml6030_update_gain_res(data, gain_idx); 580 581 return 0; 582} 583 584static int veml6035_set_als_gain(struct iio_dev *indio_dev, int val, int val2) 585{ 586 int ret, new_gain, gain_idx; 587 struct veml6030_data *data = iio_priv(indio_dev); 588 589 if (val == 0 && val2 == 125000) { 590 new_gain = FIELD_GET(VEML6035_GAIN_M, VEML6035_SENS); 591 gain_idx = 5; 592 } else if (val == 0 && val2 == 250000) { 593 new_gain = FIELD_GET(VEML6035_GAIN_M, VEML6035_SENS | 594 VEML6035_GAIN); 595 gain_idx = 4; 596 } else if (val == 0 && val2 == 500000) { 597 new_gain = FIELD_GET(VEML6035_GAIN_M, VEML6035_SENS | 598 VEML6035_GAIN | VEML6035_DG); 599 gain_idx = 3; 600 } else if (val == 1 && val2 == 0) { 601 new_gain = 0x0000; 602 gain_idx = 2; 603 } else if (val == 2 && val2 == 0) { 604 new_gain = FIELD_GET(VEML6035_GAIN_M, VEML6035_GAIN); 605 gain_idx = 1; 606 } else if (val == 4 && val2 == 0) { 607 new_gain = FIELD_GET(VEML6035_GAIN_M, VEML6035_GAIN | 608 VEML6035_DG); 609 gain_idx = 0; 610 } else { 611 return -EINVAL; 612 } 613 614 ret = regmap_field_write(data->rf.gain, new_gain); 615 if (ret) { 616 dev_err(&data->client->dev, "can't set als gain %d\n", ret); | 531 ret = iio_gts_find_gain_time_sel_for_scale(&data->gts, val, val2, 532 &gain_sel, &it_sel); 533 if (ret) |
617 return ret; | 534 return ret; |
618 } | |
619 | 535 |
620 veml6030_update_gain_res(data, gain_idx); 621 622 return 0; 623} 624 625static int veml6030_get_als_gain(struct iio_dev *indio_dev, 626 int *val, int *val2) 627{ 628 int gain, ret; 629 struct veml6030_data *data = iio_priv(indio_dev); 630 631 ret = regmap_field_read(data->rf.gain, &gain); 632 if (ret) { 633 dev_err(&data->client->dev, 634 "can't read als conf register %d\n", ret); | 536 ret = regmap_field_write(data->rf.it, it_sel); 537 if (ret) |
635 return ret; | 538 return ret; |
636 } | |
637 | 539 |
638 switch (gain) { 639 case 0: 640 *val = 1; 641 *val2 = 0; 642 break; 643 case 1: 644 *val = 2; 645 *val2 = 0; 646 break; 647 case 2: 648 *val = 0; 649 *val2 = 125000; 650 break; 651 case 3: 652 *val = 0; 653 *val2 = 250000; 654 break; 655 default: 656 return -EINVAL; 657 } 658 659 return IIO_VAL_INT_PLUS_MICRO; 660} 661 662static int veml6035_get_als_gain(struct iio_dev *indio_dev, int *val, int *val2) 663{ 664 int gain, ret; 665 struct veml6030_data *data = iio_priv(indio_dev); 666 667 ret = regmap_field_read(data->rf.gain, &gain); 668 if (ret) { 669 dev_err(&data->client->dev, 670 "can't read als conf register %d\n", ret); | 540 ret = regmap_field_write(data->rf.gain, gain_sel); 541 if (ret) |
671 return ret; | 542 return ret; |
672 } | |
673 | 543 |
674 switch (gain) { 675 case 0: 676 *val = 1; 677 *val2 = 0; 678 break; 679 case 1: 680 case 2: 681 *val = 2; 682 *val2 = 0; 683 break; 684 case 3: 685 *val = 4; 686 *val2 = 0; 687 break; 688 case 4: 689 *val = 0; 690 *val2 = 125000; 691 break; 692 case 5: 693 case 6: 694 *val = 0; 695 *val2 = 250000; 696 break; 697 case 7: 698 *val = 0; 699 *val2 = 500000; 700 break; 701 default: 702 return -EINVAL; 703 } 704 705 return IIO_VAL_INT_PLUS_MICRO; | 544 return 0; |
706} 707 708static int veml6030_read_thresh(struct iio_dev *indio_dev, 709 int *val, int *val2, int dir) 710{ 711 int ret, reg; 712 struct veml6030_data *data = iio_priv(indio_dev); 713 --- 30 unchanged lines hidden (view full) --- 744 if (ret) 745 dev_err(&data->client->dev, 746 "can't set low threshold %d\n", ret); 747 } 748 749 return ret; 750} 751 | 545} 546 547static int veml6030_read_thresh(struct iio_dev *indio_dev, 548 int *val, int *val2, int dir) 549{ 550 int ret, reg; 551 struct veml6030_data *data = iio_priv(indio_dev); 552 --- 30 unchanged lines hidden (view full) --- 583 if (ret) 584 dev_err(&data->client->dev, 585 "can't set low threshold %d\n", ret); 586 } 587 588 return ret; 589} 590 |
591static int veml6030_get_total_gain(struct veml6030_data *data) 592{ 593 int gain, it, reg, ret; 594 595 ret = regmap_field_read(data->rf.gain, ®); 596 if (ret) 597 return ret; 598 599 gain = iio_gts_find_gain_by_sel(&data->gts, reg); 600 if (gain < 0) 601 return gain; 602 603 ret = regmap_field_read(data->rf.it, ®); 604 if (ret) 605 return ret; 606 607 it = iio_gts_find_int_time_by_sel(&data->gts, reg); 608 if (it < 0) 609 return it; 610 611 return iio_gts_get_total_gain(&data->gts, gain, it); 612} 613 614static int veml6030_get_scale(struct veml6030_data *data, int *val, int *val2) 615{ 616 int gain, it, reg, ret; 617 618 ret = regmap_field_read(data->rf.gain, ®); 619 if (ret) 620 return ret; 621 622 gain = iio_gts_find_gain_by_sel(&data->gts, reg); 623 if (gain < 0) 624 return gain; 625 626 ret = regmap_field_read(data->rf.it, ®); 627 if (ret) 628 return ret; 629 630 it = iio_gts_find_int_time_by_sel(&data->gts, reg); 631 if (it < 0) 632 return it; 633 634 ret = iio_gts_get_scale(&data->gts, gain, it, val, val2); 635 if (ret) 636 return ret; 637 638 return IIO_VAL_INT_PLUS_NANO; 639} 640 641static int veml6030_process_als(struct veml6030_data *data, int raw, 642 int *val, int *val2) 643{ 644 int total_gain; 645 646 total_gain = veml6030_get_total_gain(data); 647 if (total_gain < 0) 648 return total_gain; 649 650 *val = raw * data->chip->max_scale / total_gain / 10000; 651 *val2 = raw * data->chip->max_scale / total_gain % 10000 * 100; 652 653 return IIO_VAL_INT_PLUS_MICRO; 654} 655 |
|
752/* 753 * Provide both raw as well as light reading in lux. 754 * light (in lux) = resolution * raw reading 755 */ 756static int veml6030_read_raw(struct iio_dev *indio_dev, 757 struct iio_chan_spec const *chan, int *val, 758 int *val2, long mask) 759{ --- 7 unchanged lines hidden (view full) --- 767 case IIO_CHAN_INFO_PROCESSED: 768 switch (chan->type) { 769 case IIO_LIGHT: 770 ret = regmap_read(regmap, VEML6030_REG_ALS_DATA, ®); 771 if (ret < 0) { 772 dev_err(dev, "can't read als data %d\n", ret); 773 return ret; 774 } | 656/* 657 * Provide both raw as well as light reading in lux. 658 * light (in lux) = resolution * raw reading 659 */ 660static int veml6030_read_raw(struct iio_dev *indio_dev, 661 struct iio_chan_spec const *chan, int *val, 662 int *val2, long mask) 663{ --- 7 unchanged lines hidden (view full) --- 671 case IIO_CHAN_INFO_PROCESSED: 672 switch (chan->type) { 673 case IIO_LIGHT: 674 ret = regmap_read(regmap, VEML6030_REG_ALS_DATA, ®); 675 if (ret < 0) { 676 dev_err(dev, "can't read als data %d\n", ret); 677 return ret; 678 } |
775 if (mask == IIO_CHAN_INFO_PROCESSED) { 776 *val = (reg * data->cur_resolution) / 10000; 777 *val2 = (reg * data->cur_resolution) % 10000 * 100; 778 return IIO_VAL_INT_PLUS_MICRO; 779 } | 679 if (mask == IIO_CHAN_INFO_PROCESSED) 680 return veml6030_process_als(data, reg, val, val2); 681 |
780 *val = reg; 781 return IIO_VAL_INT; 782 case IIO_INTENSITY: 783 ret = regmap_read(regmap, VEML6030_REG_WH_DATA, ®); 784 if (ret < 0) { 785 dev_err(dev, "can't read white data %d\n", ret); 786 return ret; 787 } 788 *val = reg; 789 return IIO_VAL_INT; 790 default: 791 return -EINVAL; 792 } 793 case IIO_CHAN_INFO_INT_TIME: | 682 *val = reg; 683 return IIO_VAL_INT; 684 case IIO_INTENSITY: 685 ret = regmap_read(regmap, VEML6030_REG_WH_DATA, ®); 686 if (ret < 0) { 687 dev_err(dev, "can't read white data %d\n", ret); 688 return ret; 689 } 690 *val = reg; 691 return IIO_VAL_INT; 692 default: 693 return -EINVAL; 694 } 695 case IIO_CHAN_INFO_INT_TIME: |
794 return veml6030_get_intgrn_tm(indio_dev, val, val2); | 696 return veml6030_get_it(data, val, val2); |
795 case IIO_CHAN_INFO_SCALE: | 697 case IIO_CHAN_INFO_SCALE: |
796 return data->chip->get_als_gain(indio_dev, val, val2); | 698 return veml6030_get_scale(data, val, val2); |
797 default: 798 return -EINVAL; 799 } 800} 801 802static int veml6030_read_avail(struct iio_dev *indio_dev, 803 struct iio_chan_spec const *chan, 804 const int **vals, int *type, int *length, 805 long mask) 806{ 807 struct veml6030_data *data = iio_priv(indio_dev); 808 809 switch (mask) { 810 case IIO_CHAN_INFO_INT_TIME: | 699 default: 700 return -EINVAL; 701 } 702} 703 704static int veml6030_read_avail(struct iio_dev *indio_dev, 705 struct iio_chan_spec const *chan, 706 const int **vals, int *type, int *length, 707 long mask) 708{ 709 struct veml6030_data *data = iio_priv(indio_dev); 710 711 switch (mask) { 712 case IIO_CHAN_INFO_INT_TIME: |
811 *vals = (int *)&veml6030_it_times; 812 *length = 2 * ARRAY_SIZE(veml6030_it_times); 813 *type = IIO_VAL_INT_PLUS_MICRO; 814 return IIO_AVAIL_LIST; | 713 return iio_gts_avail_times(&data->gts, vals, type, length); |
815 case IIO_CHAN_INFO_SCALE: | 714 case IIO_CHAN_INFO_SCALE: |
816 *vals = (int *)*data->chip->scale_vals; 817 *length = 2 * data->chip->num_scale_vals; 818 *type = IIO_VAL_INT_PLUS_MICRO; 819 return IIO_AVAIL_LIST; | 715 return iio_gts_all_avail_scales(&data->gts, vals, type, length); |
820 } 821 822 return -EINVAL; 823} 824 825static int veml6030_write_raw(struct iio_dev *indio_dev, 826 struct iio_chan_spec const *chan, 827 int val, int val2, long mask) 828{ | 716 } 717 718 return -EINVAL; 719} 720 721static int veml6030_write_raw(struct iio_dev *indio_dev, 722 struct iio_chan_spec const *chan, 723 int val, int val2, long mask) 724{ |
829 struct veml6030_data *data = iio_priv(indio_dev); 830 | |
831 switch (mask) { 832 case IIO_CHAN_INFO_INT_TIME: | 725 switch (mask) { 726 case IIO_CHAN_INFO_INT_TIME: |
833 return veml6030_set_intgrn_tm(indio_dev, val, val2); | 727 return veml6030_set_it(indio_dev, val, val2); |
834 case IIO_CHAN_INFO_SCALE: | 728 case IIO_CHAN_INFO_SCALE: |
835 return data->chip->set_als_gain(indio_dev, val, val2); | 729 return veml6030_set_scale(indio_dev, val, val2); |
836 default: 837 return -EINVAL; 838 } 839} 840 | 730 default: 731 return -EINVAL; 732 } 733} 734 |
735static int veml6030_write_raw_get_fmt(struct iio_dev *indio_dev, 736 struct iio_chan_spec const *chan, 737 long mask) 738{ 739 switch (mask) { 740 case IIO_CHAN_INFO_SCALE: 741 return IIO_VAL_INT_PLUS_NANO; 742 case IIO_CHAN_INFO_INT_TIME: 743 return IIO_VAL_INT_PLUS_MICRO; 744 default: 745 return -EINVAL; 746 } 747} 748 |
|
841static int veml6030_read_event_val(struct iio_dev *indio_dev, 842 const struct iio_chan_spec *chan, enum iio_event_type type, 843 enum iio_event_direction dir, enum iio_event_info info, 844 int *val, int *val2) 845{ 846 switch (info) { 847 case IIO_EV_INFO_VALUE: 848 switch (dir) { --- 76 unchanged lines hidden (view full) --- 925 926 return ret; 927} 928 929static const struct iio_info veml6030_info = { 930 .read_raw = veml6030_read_raw, 931 .read_avail = veml6030_read_avail, 932 .write_raw = veml6030_write_raw, | 749static int veml6030_read_event_val(struct iio_dev *indio_dev, 750 const struct iio_chan_spec *chan, enum iio_event_type type, 751 enum iio_event_direction dir, enum iio_event_info info, 752 int *val, int *val2) 753{ 754 switch (info) { 755 case IIO_EV_INFO_VALUE: 756 switch (dir) { --- 76 unchanged lines hidden (view full) --- 833 834 return ret; 835} 836 837static const struct iio_info veml6030_info = { 838 .read_raw = veml6030_read_raw, 839 .read_avail = veml6030_read_avail, 840 .write_raw = veml6030_write_raw, |
841 .write_raw_get_fmt = veml6030_write_raw_get_fmt, |
|
933 .read_event_value = veml6030_read_event_val, 934 .write_event_value = veml6030_write_event_val, 935 .read_event_config = veml6030_read_interrupt_config, 936 .write_event_config = veml6030_write_interrupt_config, 937 .event_attrs = &veml6030_event_attr_group, 938}; 939 940static const struct iio_info veml6030_info_no_irq = { 941 .read_raw = veml6030_read_raw, 942 .read_avail = veml6030_read_avail, 943 .write_raw = veml6030_write_raw, | 842 .read_event_value = veml6030_read_event_val, 843 .write_event_value = veml6030_write_event_val, 844 .read_event_config = veml6030_read_interrupt_config, 845 .write_event_config = veml6030_write_interrupt_config, 846 .event_attrs = &veml6030_event_attr_group, 847}; 848 849static const struct iio_info veml6030_info_no_irq = { 850 .read_raw = veml6030_read_raw, 851 .read_avail = veml6030_read_avail, 852 .write_raw = veml6030_write_raw, |
853 .write_raw_get_fmt = veml6030_write_raw_get_fmt, |
|
944}; 945 946static irqreturn_t veml6030_event_handler(int irq, void *private) 947{ 948 int ret, reg, evtdir; 949 struct iio_dev *indio_dev = private; 950 struct veml6030_data *data = iio_priv(indio_dev); 951 --- 109 unchanged lines hidden (view full) --- 1061 * interrupt disabled by default. First shutdown the sensor, 1062 * update registers and then power on the sensor. 1063 */ 1064static int veml6030_hw_init(struct iio_dev *indio_dev, struct device *dev) 1065{ 1066 int ret, val; 1067 struct veml6030_data *data = iio_priv(indio_dev); 1068 | 854}; 855 856static irqreturn_t veml6030_event_handler(int irq, void *private) 857{ 858 int ret, reg, evtdir; 859 struct iio_dev *indio_dev = private; 860 struct veml6030_data *data = iio_priv(indio_dev); 861 --- 109 unchanged lines hidden (view full) --- 971 * interrupt disabled by default. First shutdown the sensor, 972 * update registers and then power on the sensor. 973 */ 974static int veml6030_hw_init(struct iio_dev *indio_dev, struct device *dev) 975{ 976 int ret, val; 977 struct veml6030_data *data = iio_priv(indio_dev); 978 |
979 ret = devm_iio_init_iio_gts(dev, 2, 150400000, 980 veml6030_gain_sel, ARRAY_SIZE(veml6030_gain_sel), 981 veml6030_it_sel, ARRAY_SIZE(veml6030_it_sel), 982 &data->gts); 983 if (ret) 984 return dev_err_probe(dev, ret, "failed to init iio gts\n"); 985 |
|
1069 ret = veml6030_als_shut_down(data); 1070 if (ret) 1071 return dev_err_probe(dev, ret, "can't shutdown als\n"); 1072 1073 ret = regmap_write(data->regmap, VEML6030_REG_ALS_CONF, 0x1001); 1074 if (ret) 1075 return dev_err_probe(dev, ret, "can't setup als configs\n"); 1076 --- 19 unchanged lines hidden (view full) --- 1096 return ret; 1097 1098 /* Clear stale interrupt status bits if any during start */ 1099 ret = regmap_read(data->regmap, VEML6030_REG_ALS_INT, &val); 1100 if (ret < 0) 1101 return dev_err_probe(dev, ret, 1102 "can't clear als interrupt status\n"); 1103 | 986 ret = veml6030_als_shut_down(data); 987 if (ret) 988 return dev_err_probe(dev, ret, "can't shutdown als\n"); 989 990 ret = regmap_write(data->regmap, VEML6030_REG_ALS_CONF, 0x1001); 991 if (ret) 992 return dev_err_probe(dev, ret, "can't setup als configs\n"); 993 --- 19 unchanged lines hidden (view full) --- 1013 return ret; 1014 1015 /* Clear stale interrupt status bits if any during start */ 1016 ret = regmap_read(data->regmap, VEML6030_REG_ALS_INT, &val); 1017 if (ret < 0) 1018 return dev_err_probe(dev, ret, 1019 "can't clear als interrupt status\n"); 1020 |
1104 /* Cache currently active measurement parameters */ 1105 data->cur_gain = 3; 1106 data->cur_resolution = 5376; 1107 data->cur_integration_time = 3; 1108 | |
1109 return ret; 1110} 1111 1112/* 1113 * Set ALS gain to 1/8, integration time to 100 ms, ALS and WHITE 1114 * channel enabled, ALS channel interrupt, PSM enabled, 1115 * PSM_WAIT = 0.8 s, persistence to 1 x integration time and the 1116 * threshold interrupt disabled by default. First shutdown the sensor, 1117 * update registers and then power on the sensor. 1118 */ 1119static int veml6035_hw_init(struct iio_dev *indio_dev, struct device *dev) 1120{ 1121 int ret, val; 1122 struct veml6030_data *data = iio_priv(indio_dev); 1123 | 1021 return ret; 1022} 1023 1024/* 1025 * Set ALS gain to 1/8, integration time to 100 ms, ALS and WHITE 1026 * channel enabled, ALS channel interrupt, PSM enabled, 1027 * PSM_WAIT = 0.8 s, persistence to 1 x integration time and the 1028 * threshold interrupt disabled by default. First shutdown the sensor, 1029 * update registers and then power on the sensor. 1030 */ 1031static int veml6035_hw_init(struct iio_dev *indio_dev, struct device *dev) 1032{ 1033 int ret, val; 1034 struct veml6030_data *data = iio_priv(indio_dev); 1035 |
1036 ret = devm_iio_init_iio_gts(dev, 0, 409600000, 1037 veml6035_gain_sel, ARRAY_SIZE(veml6035_gain_sel), 1038 veml6030_it_sel, ARRAY_SIZE(veml6030_it_sel), 1039 &data->gts); 1040 if (ret) 1041 return dev_err_probe(dev, ret, "failed to init iio gts\n"); 1042 |
|
1124 ret = veml6030_als_shut_down(data); 1125 if (ret) 1126 return dev_err_probe(dev, ret, "can't shutdown als\n"); 1127 1128 ret = regmap_write(data->regmap, VEML6030_REG_ALS_CONF, 1129 VEML6035_SENS | VEML6035_CHAN_EN | VEML6030_ALS_SD); 1130 if (ret) 1131 return dev_err_probe(dev, ret, "can't setup als configs\n"); --- 20 unchanged lines hidden (view full) --- 1152 return ret; 1153 1154 /* Clear stale interrupt status bits if any during start */ 1155 ret = regmap_read(data->regmap, VEML6030_REG_ALS_INT, &val); 1156 if (ret < 0) 1157 return dev_err_probe(dev, ret, 1158 "can't clear als interrupt status\n"); 1159 | 1043 ret = veml6030_als_shut_down(data); 1044 if (ret) 1045 return dev_err_probe(dev, ret, "can't shutdown als\n"); 1046 1047 ret = regmap_write(data->regmap, VEML6030_REG_ALS_CONF, 1048 VEML6035_SENS | VEML6035_CHAN_EN | VEML6030_ALS_SD); 1049 if (ret) 1050 return dev_err_probe(dev, ret, "can't setup als configs\n"); --- 20 unchanged lines hidden (view full) --- 1071 return ret; 1072 1073 /* Clear stale interrupt status bits if any during start */ 1074 ret = regmap_read(data->regmap, VEML6030_REG_ALS_INT, &val); 1075 if (ret < 0) 1076 return dev_err_probe(dev, ret, 1077 "can't clear als interrupt status\n"); 1078 |
1160 /* Cache currently active measurement parameters */ 1161 data->cur_gain = 5; 1162 data->cur_resolution = 1024; 1163 data->cur_integration_time = 3; 1164 | |
1165 return 0; 1166} 1167 1168static int veml6030_probe(struct i2c_client *client) 1169{ 1170 int ret; 1171 struct veml6030_data *data; 1172 struct iio_dev *indio_dev; --- 79 unchanged lines hidden (view full) --- 1252 return ret; 1253} 1254 1255static DEFINE_RUNTIME_DEV_PM_OPS(veml6030_pm_ops, veml6030_runtime_suspend, 1256 veml6030_runtime_resume, NULL); 1257 1258static const struct veml603x_chip veml6030_chip = { 1259 .name = "veml6030", | 1079 return 0; 1080} 1081 1082static int veml6030_probe(struct i2c_client *client) 1083{ 1084 int ret; 1085 struct veml6030_data *data; 1086 struct iio_dev *indio_dev; --- 79 unchanged lines hidden (view full) --- 1166 return ret; 1167} 1168 1169static DEFINE_RUNTIME_DEV_PM_OPS(veml6030_pm_ops, veml6030_runtime_suspend, 1170 veml6030_runtime_resume, NULL); 1171 1172static const struct veml603x_chip veml6030_chip = { 1173 .name = "veml6030", |
1260 .scale_vals = &veml6030_scale_vals, 1261 .num_scale_vals = ARRAY_SIZE(veml6030_scale_vals), | |
1262 .channels = veml6030_channels, 1263 .num_channels = ARRAY_SIZE(veml6030_channels), 1264 .gain_rf = VEML6030_GAIN_RF, 1265 .it_rf = VEML6030_IT_RF, | 1174 .channels = veml6030_channels, 1175 .num_channels = ARRAY_SIZE(veml6030_channels), 1176 .gain_rf = VEML6030_GAIN_RF, 1177 .it_rf = VEML6030_IT_RF, |
1178 .max_scale = VEML6030_MAX_SCALE, |
|
1266 .hw_init = veml6030_hw_init, 1267 .set_info = veml6030_set_info, | 1179 .hw_init = veml6030_hw_init, 1180 .set_info = veml6030_set_info, |
1268 .set_als_gain = veml6030_set_als_gain, 1269 .get_als_gain = veml6030_get_als_gain, | |
1270}; 1271 1272static const struct veml603x_chip veml6035_chip = { 1273 .name = "veml6035", | 1181}; 1182 1183static const struct veml603x_chip veml6035_chip = { 1184 .name = "veml6035", |
1274 .scale_vals = &veml6035_scale_vals, 1275 .num_scale_vals = ARRAY_SIZE(veml6035_scale_vals), | |
1276 .channels = veml6030_channels, 1277 .num_channels = ARRAY_SIZE(veml6030_channels), 1278 .gain_rf = VEML6035_GAIN_RF, 1279 .it_rf = VEML6030_IT_RF, | 1185 .channels = veml6030_channels, 1186 .num_channels = ARRAY_SIZE(veml6030_channels), 1187 .gain_rf = VEML6035_GAIN_RF, 1188 .it_rf = VEML6030_IT_RF, |
1189 .max_scale = VEML6035_MAX_SCALE, |
|
1280 .hw_init = veml6035_hw_init, 1281 .set_info = veml6030_set_info, | 1190 .hw_init = veml6035_hw_init, 1191 .set_info = veml6030_set_info, |
1282 .set_als_gain = veml6035_set_als_gain, 1283 .get_als_gain = veml6035_get_als_gain, | |
1284}; 1285 1286static const struct veml603x_chip veml7700_chip = { 1287 .name = "veml7700", | 1192}; 1193 1194static const struct veml603x_chip veml7700_chip = { 1195 .name = "veml7700", |
1288 .scale_vals = &veml6030_scale_vals, 1289 .num_scale_vals = ARRAY_SIZE(veml6030_scale_vals), | |
1290 .channels = veml7700_channels, 1291 .num_channels = ARRAY_SIZE(veml7700_channels), 1292 .gain_rf = VEML6030_GAIN_RF, 1293 .it_rf = VEML6030_IT_RF, | 1196 .channels = veml7700_channels, 1197 .num_channels = ARRAY_SIZE(veml7700_channels), 1198 .gain_rf = VEML6030_GAIN_RF, 1199 .it_rf = VEML6030_IT_RF, |
1200 .max_scale = VEML6030_MAX_SCALE, |
|
1294 .hw_init = veml6030_hw_init, 1295 .set_info = veml7700_set_info, | 1201 .hw_init = veml6030_hw_init, 1202 .set_info = veml7700_set_info, |
1296 .set_als_gain = veml6030_set_als_gain, 1297 .get_als_gain = veml6030_get_als_gain, | |
1298}; 1299 1300static const struct of_device_id veml6030_of_match[] = { 1301 { 1302 .compatible = "vishay,veml6030", 1303 .data = &veml6030_chip, 1304 }, 1305 { --- 25 unchanged lines hidden (view full) --- 1331 .probe = veml6030_probe, 1332 .id_table = veml6030_id, 1333}; 1334module_i2c_driver(veml6030_driver); 1335 1336MODULE_AUTHOR("Rishi Gupta <gupt21@gmail.com>"); 1337MODULE_DESCRIPTION("VEML6030 Ambient Light Sensor"); 1338MODULE_LICENSE("GPL v2"); | 1203}; 1204 1205static const struct of_device_id veml6030_of_match[] = { 1206 { 1207 .compatible = "vishay,veml6030", 1208 .data = &veml6030_chip, 1209 }, 1210 { --- 25 unchanged lines hidden (view full) --- 1236 .probe = veml6030_probe, 1237 .id_table = veml6030_id, 1238}; 1239module_i2c_driver(veml6030_driver); 1240 1241MODULE_AUTHOR("Rishi Gupta <gupt21@gmail.com>"); 1242MODULE_DESCRIPTION("VEML6030 Ambient Light Sensor"); 1243MODULE_LICENSE("GPL v2"); |
1244MODULE_IMPORT_NS("IIO_GTS_HELPER"); |
|