1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * VEML3235 Ambient Light Sensor 4 * 5 * Copyright (c) 2024, Javier Carrasco <javier.carrasco.cruz@gmail.com> 6 * 7 * Datasheet: https://www.vishay.com/docs/80131/veml3235.pdf 8 * Appnote-80222: https://www.vishay.com/docs/80222/designingveml3235.pdf 9 */ 10 11 #include <linux/err.h> 12 #include <linux/i2c.h> 13 #include <linux/iio/iio.h> 14 #include <linux/iio/iio-gts-helper.h> 15 #include <linux/module.h> 16 #include <linux/pm_runtime.h> 17 #include <linux/regmap.h> 18 #include <linux/regulator/consumer.h> 19 20 #define VEML3235_REG_CONF 0x00 21 #define VEML3235_REG_WH_DATA 0x04 22 #define VEML3235_REG_ALS_DATA 0x05 23 #define VEML3235_REG_ID 0x09 24 25 #define VEML3235_CONF_SD BIT(0) 26 #define VEML3235_CONF_SD0 BIT(15) 27 28 struct veml3235_rf { 29 struct regmap_field *it; 30 struct regmap_field *gain; 31 struct regmap_field *id; 32 }; 33 34 struct veml3235_data { 35 struct i2c_client *client; 36 struct device *dev; 37 struct regmap *regmap; 38 struct veml3235_rf rf; 39 struct iio_gts gts; 40 }; 41 42 static const struct iio_itime_sel_mul veml3235_it_sel[] = { 43 GAIN_SCALE_ITIME_US(50000, 0, 1), 44 GAIN_SCALE_ITIME_US(100000, 1, 2), 45 GAIN_SCALE_ITIME_US(200000, 2, 4), 46 GAIN_SCALE_ITIME_US(400000, 3, 8), 47 GAIN_SCALE_ITIME_US(800000, 4, 16), 48 }; 49 50 /* 51 * The MSB (DG) doubles the value of the rest of the field, which leads to 52 * two possible combinations to obtain gain = 2 and gain = 4. The gain 53 * handling can be simplified by restricting DG = 1 to the only gain that 54 * really requires it, gain = 8. Note that "X10" is a reserved value. 55 */ 56 #define VEML3235_SEL_GAIN_X1 0 57 #define VEML3235_SEL_GAIN_X2 1 58 #define VEML3235_SEL_GAIN_X4 3 59 #define VEML3235_SEL_GAIN_X8 7 60 static const struct iio_gain_sel_pair veml3235_gain_sel[] = { 61 GAIN_SCALE_GAIN(1, VEML3235_SEL_GAIN_X1), 62 GAIN_SCALE_GAIN(2, VEML3235_SEL_GAIN_X2), 63 GAIN_SCALE_GAIN(4, VEML3235_SEL_GAIN_X4), 64 GAIN_SCALE_GAIN(8, VEML3235_SEL_GAIN_X8), 65 }; 66 67 static int veml3235_power_on(struct veml3235_data *data) 68 { 69 int ret; 70 71 ret = regmap_clear_bits(data->regmap, VEML3235_REG_CONF, 72 VEML3235_CONF_SD | VEML3235_CONF_SD0); 73 if (ret) 74 return ret; 75 76 /* Wait 4 ms to let processor & oscillator start correctly */ 77 fsleep(4000); 78 79 return 0; 80 } 81 82 static int veml3235_shut_down(struct veml3235_data *data) 83 { 84 return regmap_set_bits(data->regmap, VEML3235_REG_CONF, 85 VEML3235_CONF_SD | VEML3235_CONF_SD0); 86 } 87 88 static void veml3235_shut_down_action(void *data) 89 { 90 veml3235_shut_down(data); 91 } 92 93 enum veml3235_chan { 94 CH_ALS, 95 CH_WHITE, 96 }; 97 98 static const struct iio_chan_spec veml3235_channels[] = { 99 { 100 .type = IIO_LIGHT, 101 .channel = CH_ALS, 102 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), 103 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_INT_TIME) | 104 BIT(IIO_CHAN_INFO_SCALE), 105 .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_INT_TIME) | 106 BIT(IIO_CHAN_INFO_SCALE), 107 }, 108 { 109 .type = IIO_INTENSITY, 110 .channel = CH_WHITE, 111 .modified = 1, 112 .channel2 = IIO_MOD_LIGHT_BOTH, 113 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), 114 .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_INT_TIME) | 115 BIT(IIO_CHAN_INFO_SCALE), 116 .info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_INT_TIME) | 117 BIT(IIO_CHAN_INFO_SCALE), 118 }, 119 }; 120 121 static const struct regmap_range veml3235_readable_ranges[] = { 122 regmap_reg_range(VEML3235_REG_CONF, VEML3235_REG_ID), 123 }; 124 125 static const struct regmap_access_table veml3235_readable_table = { 126 .yes_ranges = veml3235_readable_ranges, 127 .n_yes_ranges = ARRAY_SIZE(veml3235_readable_ranges), 128 }; 129 130 static const struct regmap_range veml3235_writable_ranges[] = { 131 regmap_reg_range(VEML3235_REG_CONF, VEML3235_REG_CONF), 132 }; 133 134 static const struct regmap_access_table veml3235_writable_table = { 135 .yes_ranges = veml3235_writable_ranges, 136 .n_yes_ranges = ARRAY_SIZE(veml3235_writable_ranges), 137 }; 138 139 static const struct regmap_range veml3235_volatile_ranges[] = { 140 regmap_reg_range(VEML3235_REG_WH_DATA, VEML3235_REG_ALS_DATA), 141 }; 142 143 static const struct regmap_access_table veml3235_volatile_table = { 144 .yes_ranges = veml3235_volatile_ranges, 145 .n_yes_ranges = ARRAY_SIZE(veml3235_volatile_ranges), 146 }; 147 148 static const struct regmap_config veml3235_regmap_config = { 149 .name = "veml3235_regmap", 150 .reg_bits = 8, 151 .val_bits = 16, 152 .max_register = VEML3235_REG_ID, 153 .val_format_endian = REGMAP_ENDIAN_LITTLE, 154 .rd_table = &veml3235_readable_table, 155 .wr_table = &veml3235_writable_table, 156 .volatile_table = &veml3235_volatile_table, 157 .cache_type = REGCACHE_RBTREE, 158 }; 159 160 static int veml3235_get_it(struct veml3235_data *data, int *val, int *val2) 161 { 162 int ret, it_idx; 163 164 ret = regmap_field_read(data->rf.it, &it_idx); 165 if (ret) 166 return ret; 167 168 ret = iio_gts_find_int_time_by_sel(&data->gts, it_idx); 169 if (ret < 0) 170 return ret; 171 172 *val2 = ret; 173 *val = 0; 174 175 return IIO_VAL_INT_PLUS_MICRO; 176 } 177 178 static int veml3235_set_it(struct iio_dev *indio_dev, int val, int val2) 179 { 180 struct veml3235_data *data = iio_priv(indio_dev); 181 int ret, gain_idx, it_idx, new_gain, prev_gain, prev_it; 182 bool in_range; 183 184 if (val || !iio_gts_valid_time(&data->gts, val2)) 185 return -EINVAL; 186 187 ret = regmap_field_read(data->rf.it, &it_idx); 188 if (ret) 189 return ret; 190 191 ret = regmap_field_read(data->rf.gain, &gain_idx); 192 if (ret) 193 return ret; 194 195 prev_it = iio_gts_find_int_time_by_sel(&data->gts, it_idx); 196 if (prev_it < 0) 197 return prev_it; 198 199 if (prev_it == val2) 200 return 0; 201 202 prev_gain = iio_gts_find_gain_by_sel(&data->gts, gain_idx); 203 if (prev_gain < 0) 204 return prev_gain; 205 206 ret = iio_gts_find_new_gain_by_gain_time_min(&data->gts, prev_gain, prev_it, 207 val2, &new_gain, &in_range); 208 if (ret) 209 return ret; 210 211 if (!in_range) 212 dev_dbg(data->dev, "Optimal gain out of range\n"); 213 214 ret = iio_gts_find_sel_by_int_time(&data->gts, val2); 215 if (ret < 0) 216 return ret; 217 218 ret = regmap_field_write(data->rf.it, ret); 219 if (ret) 220 return ret; 221 222 ret = iio_gts_find_sel_by_gain(&data->gts, new_gain); 223 if (ret < 0) 224 return ret; 225 226 return regmap_field_write(data->rf.gain, ret); 227 } 228 229 static int veml3235_set_scale(struct iio_dev *indio_dev, int val, int val2) 230 { 231 struct veml3235_data *data = iio_priv(indio_dev); 232 int ret, it_idx, gain_sel, time_sel; 233 234 ret = regmap_field_read(data->rf.it, &it_idx); 235 if (ret) 236 return ret; 237 238 ret = iio_gts_find_gain_time_sel_for_scale(&data->gts, val, val2, 239 &gain_sel, &time_sel); 240 if (ret) 241 return ret; 242 243 ret = regmap_field_write(data->rf.it, time_sel); 244 if (ret) 245 return ret; 246 247 return regmap_field_write(data->rf.gain, gain_sel); 248 } 249 250 static int veml3235_get_scale(struct veml3235_data *data, int *val, int *val2) 251 { 252 int gain, it, reg, ret; 253 254 ret = regmap_field_read(data->rf.gain, ®); 255 if (ret) { 256 dev_err(data->dev, "failed to read gain %d\n", ret); 257 return ret; 258 } 259 260 gain = iio_gts_find_gain_by_sel(&data->gts, reg); 261 if (gain < 0) 262 return gain; 263 264 ret = regmap_field_read(data->rf.it, ®); 265 if (ret) { 266 dev_err(data->dev, "failed to read integration time %d\n", ret); 267 return ret; 268 } 269 270 it = iio_gts_find_int_time_by_sel(&data->gts, reg); 271 if (it < 0) 272 return it; 273 274 ret = iio_gts_get_scale(&data->gts, gain, it, val, val2); 275 if (ret) 276 return ret; 277 278 return IIO_VAL_INT_PLUS_NANO; 279 } 280 281 static int veml3235_read_raw(struct iio_dev *indio_dev, 282 struct iio_chan_spec const *chan, int *val, 283 int *val2, long mask) 284 { 285 struct veml3235_data *data = iio_priv(indio_dev); 286 struct regmap *regmap = data->regmap; 287 int ret, reg; 288 289 switch (mask) { 290 case IIO_CHAN_INFO_RAW: 291 switch (chan->type) { 292 case IIO_LIGHT: 293 ret = regmap_read(regmap, VEML3235_REG_ALS_DATA, ®); 294 if (ret < 0) 295 return ret; 296 297 *val = reg; 298 return IIO_VAL_INT; 299 case IIO_INTENSITY: 300 ret = regmap_read(regmap, VEML3235_REG_WH_DATA, ®); 301 if (ret < 0) 302 return ret; 303 304 *val = reg; 305 return IIO_VAL_INT; 306 default: 307 return -EINVAL; 308 } 309 case IIO_CHAN_INFO_INT_TIME: 310 return veml3235_get_it(data, val, val2); 311 case IIO_CHAN_INFO_SCALE: 312 return veml3235_get_scale(data, val, val2); 313 default: 314 return -EINVAL; 315 } 316 } 317 318 static int veml3235_read_avail(struct iio_dev *indio_dev, 319 struct iio_chan_spec const *chan, 320 const int **vals, int *type, int *length, 321 long mask) 322 { 323 struct veml3235_data *data = iio_priv(indio_dev); 324 325 switch (mask) { 326 case IIO_CHAN_INFO_INT_TIME: 327 return iio_gts_avail_times(&data->gts, vals, type, length); 328 case IIO_CHAN_INFO_SCALE: 329 return iio_gts_all_avail_scales(&data->gts, vals, type, length); 330 default: 331 return -EINVAL; 332 } 333 } 334 335 static int veml3235_write_raw_get_fmt(struct iio_dev *indio_dev, 336 struct iio_chan_spec const *chan, 337 long mask) 338 { 339 switch (mask) { 340 case IIO_CHAN_INFO_SCALE: 341 return IIO_VAL_INT_PLUS_NANO; 342 case IIO_CHAN_INFO_INT_TIME: 343 return IIO_VAL_INT_PLUS_MICRO; 344 default: 345 return -EINVAL; 346 } 347 } 348 349 static int veml3235_write_raw(struct iio_dev *indio_dev, 350 struct iio_chan_spec const *chan, 351 int val, int val2, long mask) 352 { 353 switch (mask) { 354 case IIO_CHAN_INFO_INT_TIME: 355 return veml3235_set_it(indio_dev, val, val2); 356 case IIO_CHAN_INFO_SCALE: 357 return veml3235_set_scale(indio_dev, val, val2); 358 } 359 360 return -EINVAL; 361 } 362 363 static void veml3235_read_id(struct veml3235_data *data) 364 { 365 int ret, reg; 366 367 ret = regmap_field_read(data->rf.id, ®); 368 if (ret) { 369 dev_info(data->dev, "failed to read ID\n"); 370 return; 371 } 372 373 if (reg != 0x35) 374 dev_info(data->dev, "Unknown ID %d\n", reg); 375 } 376 377 static const struct reg_field veml3235_rf_it = 378 REG_FIELD(VEML3235_REG_CONF, 4, 6); 379 380 static const struct reg_field veml3235_rf_gain = 381 REG_FIELD(VEML3235_REG_CONF, 11, 13); 382 383 static const struct reg_field veml3235_rf_id = 384 REG_FIELD(VEML3235_REG_ID, 0, 7); 385 386 static int veml3235_regfield_init(struct veml3235_data *data) 387 { 388 struct regmap *regmap = data->regmap; 389 struct device *dev = data->dev; 390 struct regmap_field *rm_field; 391 struct veml3235_rf *rf = &data->rf; 392 393 rm_field = devm_regmap_field_alloc(dev, regmap, veml3235_rf_it); 394 if (IS_ERR(rm_field)) 395 return PTR_ERR(rm_field); 396 rf->it = rm_field; 397 398 rm_field = devm_regmap_field_alloc(dev, regmap, veml3235_rf_gain); 399 if (IS_ERR(rm_field)) 400 return PTR_ERR(rm_field); 401 rf->gain = rm_field; 402 403 rm_field = devm_regmap_field_alloc(dev, regmap, veml3235_rf_id); 404 if (IS_ERR(rm_field)) 405 return PTR_ERR(rm_field); 406 rf->id = rm_field; 407 408 return 0; 409 } 410 411 static int veml3235_hw_init(struct iio_dev *indio_dev) 412 { 413 struct veml3235_data *data = iio_priv(indio_dev); 414 struct device *dev = data->dev; 415 int ret; 416 417 ret = devm_iio_init_iio_gts(data->dev, 0, 272640000, 418 veml3235_gain_sel, ARRAY_SIZE(veml3235_gain_sel), 419 veml3235_it_sel, ARRAY_SIZE(veml3235_it_sel), 420 &data->gts); 421 if (ret) 422 return dev_err_probe(data->dev, ret, "failed to init iio gts\n"); 423 424 /* Set gain to 1 and integration time to 100 ms */ 425 ret = regmap_field_write(data->rf.gain, 0x00); 426 if (ret) 427 return dev_err_probe(data->dev, ret, "failed to set gain\n"); 428 429 ret = regmap_field_write(data->rf.it, 0x01); 430 if (ret) 431 return dev_err_probe(data->dev, ret, 432 "failed to set integration time\n"); 433 434 ret = veml3235_power_on(data); 435 if (ret) 436 return dev_err_probe(dev, ret, "failed to power on\n"); 437 438 return devm_add_action_or_reset(dev, veml3235_shut_down_action, data); 439 } 440 441 static const struct iio_info veml3235_info = { 442 .read_raw = veml3235_read_raw, 443 .read_avail = veml3235_read_avail, 444 .write_raw = veml3235_write_raw, 445 .write_raw_get_fmt = veml3235_write_raw_get_fmt, 446 }; 447 448 static int veml3235_probe(struct i2c_client *client) 449 { 450 struct device *dev = &client->dev; 451 struct veml3235_data *data; 452 struct iio_dev *indio_dev; 453 struct regmap *regmap; 454 int ret; 455 456 regmap = devm_regmap_init_i2c(client, &veml3235_regmap_config); 457 if (IS_ERR(regmap)) 458 return dev_err_probe(dev, PTR_ERR(regmap), 459 "failed to setup regmap\n"); 460 461 indio_dev = devm_iio_device_alloc(dev, sizeof(*data)); 462 if (!indio_dev) 463 return -ENOMEM; 464 465 data = iio_priv(indio_dev); 466 i2c_set_clientdata(client, indio_dev); 467 data->client = client; 468 data->dev = dev; 469 data->regmap = regmap; 470 471 ret = veml3235_regfield_init(data); 472 if (ret) 473 return dev_err_probe(dev, ret, "failed to init regfield\n"); 474 475 ret = devm_regulator_get_enable(dev, "vdd"); 476 if (ret) 477 return dev_err_probe(dev, ret, "failed to enable regulator\n"); 478 479 indio_dev->name = "veml3235"; 480 indio_dev->channels = veml3235_channels; 481 indio_dev->num_channels = ARRAY_SIZE(veml3235_channels); 482 indio_dev->modes = INDIO_DIRECT_MODE; 483 indio_dev->info = &veml3235_info; 484 485 veml3235_read_id(data); 486 487 ret = veml3235_hw_init(indio_dev); 488 if (ret < 0) 489 return ret; 490 491 return devm_iio_device_register(dev, indio_dev); 492 } 493 494 static int veml3235_runtime_suspend(struct device *dev) 495 { 496 struct veml3235_data *data = iio_priv(dev_get_drvdata(dev)); 497 int ret; 498 499 ret = veml3235_shut_down(data); 500 if (ret < 0) 501 dev_err(data->dev, "failed to suspend: %d\n", ret); 502 503 return ret; 504 } 505 506 static int veml3235_runtime_resume(struct device *dev) 507 { 508 struct veml3235_data *data = iio_priv(dev_get_drvdata(dev)); 509 int ret; 510 511 ret = veml3235_power_on(data); 512 if (ret < 0) 513 dev_err(data->dev, "failed to resume: %d\n", ret); 514 515 return ret; 516 } 517 518 static DEFINE_RUNTIME_DEV_PM_OPS(veml3235_pm_ops, veml3235_runtime_suspend, 519 veml3235_runtime_resume, NULL); 520 521 static const struct of_device_id veml3235_of_match[] = { 522 { .compatible = "vishay,veml3235" }, 523 { } 524 }; 525 MODULE_DEVICE_TABLE(of, veml3235_of_match); 526 527 static const struct i2c_device_id veml3235_id[] = { 528 { "veml3235" }, 529 { } 530 }; 531 MODULE_DEVICE_TABLE(i2c, veml3235_id); 532 533 static struct i2c_driver veml3235_driver = { 534 .driver = { 535 .name = "veml3235", 536 .of_match_table = veml3235_of_match, 537 .pm = pm_ptr(&veml3235_pm_ops), 538 }, 539 .probe = veml3235_probe, 540 .id_table = veml3235_id, 541 }; 542 module_i2c_driver(veml3235_driver); 543 544 MODULE_AUTHOR("Javier Carrasco <javier.carrasco.cruz@gmail.com>"); 545 MODULE_DESCRIPTION("VEML3235 Ambient Light Sensor"); 546 MODULE_LICENSE("GPL"); 547 MODULE_IMPORT_NS("IIO_GTS_HELPER"); 548