1 // SPDX-License-Identifier: GPL-2.0+
3 * VEML3235 Ambient Light Sensor
5 * Copyright (c) 2024, Javier Carrasco <javier.carrasco.cruz@gmail.com>
7 * Datasheet: https://www.vishay.com/docs/80131/veml3235.pdf
8 * Appnote-80222: https://www.vishay.com/docs/80222/designingveml3235.pdf
11 #include <linux/err.h>
12 #include <linux/i2c.h>
13 #include <linux/iio/iio.h>
14 #include <linux/module.h>
15 #include <linux/pm_runtime.h>
16 #include <linux/regmap.h>
17 #include <linux/regulator/consumer.h>
19 #define VEML3235_REG_CONF 0x00
20 #define VEML3235_REG_WH_DATA 0x04
21 #define VEML3235_REG_ALS_DATA 0x05
22 #define VEML3235_REG_ID 0x09
24 #define VEML3235_CONF_SD BIT(0)
25 #define VEML3235_CONF_SD0 BIT(15)
28 struct regmap_field
*it
;
29 struct regmap_field
*gain
;
30 struct regmap_field
*id
;
33 struct veml3235_data
{
34 struct i2c_client
*client
;
36 struct regmap
*regmap
;
37 struct veml3235_rf rf
;
40 static const int veml3235_it_times
[][2] = {
48 static const int veml3235_scale_vals
[] = { 1, 2, 4, 8 };
50 static int veml3235_power_on(struct veml3235_data
*data
)
54 ret
= regmap_clear_bits(data
->regmap
, VEML3235_REG_CONF
,
55 VEML3235_CONF_SD
| VEML3235_CONF_SD0
);
59 /* Wait 4 ms to let processor & oscillator start correctly */
65 static int veml3235_shut_down(struct veml3235_data
*data
)
67 return regmap_set_bits(data
->regmap
, VEML3235_REG_CONF
,
68 VEML3235_CONF_SD
| VEML3235_CONF_SD0
);
71 static void veml3235_shut_down_action(void *data
)
73 veml3235_shut_down(data
);
81 static const struct iio_chan_spec veml3235_channels
[] = {
85 .info_mask_separate
= BIT(IIO_CHAN_INFO_RAW
),
86 .info_mask_shared_by_all
= BIT(IIO_CHAN_INFO_INT_TIME
) |
87 BIT(IIO_CHAN_INFO_SCALE
),
88 .info_mask_shared_by_all_available
= BIT(IIO_CHAN_INFO_INT_TIME
) |
89 BIT(IIO_CHAN_INFO_SCALE
),
92 .type
= IIO_INTENSITY
,
95 .channel2
= IIO_MOD_LIGHT_BOTH
,
96 .info_mask_separate
= BIT(IIO_CHAN_INFO_RAW
),
97 .info_mask_shared_by_all
= BIT(IIO_CHAN_INFO_INT_TIME
) |
98 BIT(IIO_CHAN_INFO_SCALE
),
99 .info_mask_shared_by_all_available
= BIT(IIO_CHAN_INFO_INT_TIME
) |
100 BIT(IIO_CHAN_INFO_SCALE
),
104 static const struct regmap_config veml3235_regmap_config
= {
105 .name
= "veml3235_regmap",
108 .max_register
= VEML3235_REG_ID
,
109 .val_format_endian
= REGMAP_ENDIAN_LITTLE
,
112 static int veml3235_get_it(struct veml3235_data
*data
, int *val
, int *val2
)
116 ret
= regmap_field_read(data
->rf
.it
, ®
);
142 return IIO_VAL_INT_PLUS_MICRO
;
145 static int veml3235_set_it(struct iio_dev
*indio_dev
, int val
, int val2
)
147 struct veml3235_data
*data
= iio_priv(indio_dev
);
173 ret
= regmap_field_write(data
->rf
.it
, new_it
);
176 "failed to update integration time: %d\n", ret
);
183 static int veml3235_set_gain(struct iio_dev
*indio_dev
, int val
, int val2
)
185 struct veml3235_data
*data
= iio_priv(indio_dev
);
208 ret
= regmap_field_write(data
->rf
.gain
, new_gain
);
210 dev_err(data
->dev
, "failed to set gain: %d\n", ret
);
217 static int veml3235_get_gain(struct veml3235_data
*data
, int *val
)
221 ret
= regmap_field_read(data
->rf
.gain
, ®
);
223 dev_err(data
->dev
, "failed to read gain %d\n", ret
);
227 switch (reg
& 0x03) {
248 static int veml3235_read_raw(struct iio_dev
*indio_dev
,
249 struct iio_chan_spec
const *chan
, int *val
,
250 int *val2
, long mask
)
252 struct veml3235_data
*data
= iio_priv(indio_dev
);
253 struct regmap
*regmap
= data
->regmap
;
257 case IIO_CHAN_INFO_RAW
:
258 switch (chan
->type
) {
260 ret
= regmap_read(regmap
, VEML3235_REG_ALS_DATA
, ®
);
267 ret
= regmap_read(regmap
, VEML3235_REG_WH_DATA
, ®
);
276 case IIO_CHAN_INFO_INT_TIME
:
277 return veml3235_get_it(data
, val
, val2
);
278 case IIO_CHAN_INFO_SCALE
:
279 return veml3235_get_gain(data
, val
);
285 static int veml3235_read_avail(struct iio_dev
*indio_dev
,
286 struct iio_chan_spec
const *chan
,
287 const int **vals
, int *type
, int *length
,
291 case IIO_CHAN_INFO_INT_TIME
:
292 *vals
= (int *)&veml3235_it_times
;
293 *length
= 2 * ARRAY_SIZE(veml3235_it_times
);
294 *type
= IIO_VAL_INT_PLUS_MICRO
;
295 return IIO_AVAIL_LIST
;
296 case IIO_CHAN_INFO_SCALE
:
297 *vals
= (int *)&veml3235_scale_vals
;
298 *length
= ARRAY_SIZE(veml3235_scale_vals
);
300 return IIO_AVAIL_LIST
;
306 static int veml3235_write_raw(struct iio_dev
*indio_dev
,
307 struct iio_chan_spec
const *chan
,
308 int val
, int val2
, long mask
)
311 case IIO_CHAN_INFO_INT_TIME
:
312 return veml3235_set_it(indio_dev
, val
, val2
);
313 case IIO_CHAN_INFO_SCALE
:
314 return veml3235_set_gain(indio_dev
, val
, val2
);
320 static void veml3235_read_id(struct veml3235_data
*data
)
324 ret
= regmap_field_read(data
->rf
.id
, ®
);
326 dev_info(data
->dev
, "failed to read ID\n");
331 dev_info(data
->dev
, "Unknown ID %d\n", reg
);
334 static const struct reg_field veml3235_rf_it
=
335 REG_FIELD(VEML3235_REG_CONF
, 4, 6);
337 static const struct reg_field veml3235_rf_gain
=
338 REG_FIELD(VEML3235_REG_CONF
, 11, 13);
340 static const struct reg_field veml3235_rf_id
=
341 REG_FIELD(VEML3235_REG_ID
, 0, 7);
343 static int veml3235_regfield_init(struct veml3235_data
*data
)
345 struct regmap
*regmap
= data
->regmap
;
346 struct device
*dev
= data
->dev
;
347 struct regmap_field
*rm_field
;
348 struct veml3235_rf
*rf
= &data
->rf
;
350 rm_field
= devm_regmap_field_alloc(dev
, regmap
, veml3235_rf_it
);
351 if (IS_ERR(rm_field
))
352 return PTR_ERR(rm_field
);
355 rm_field
= devm_regmap_field_alloc(dev
, regmap
, veml3235_rf_gain
);
356 if (IS_ERR(rm_field
))
357 return PTR_ERR(rm_field
);
360 rm_field
= devm_regmap_field_alloc(dev
, regmap
, veml3235_rf_id
);
361 if (IS_ERR(rm_field
))
362 return PTR_ERR(rm_field
);
368 static int veml3235_hw_init(struct iio_dev
*indio_dev
)
370 struct veml3235_data
*data
= iio_priv(indio_dev
);
371 struct device
*dev
= data
->dev
;
374 /* Set gain to 1 and integration time to 100 ms */
375 ret
= regmap_field_write(data
->rf
.gain
, 0x00);
377 return dev_err_probe(data
->dev
, ret
, "failed to set gain\n");
379 ret
= regmap_field_write(data
->rf
.it
, 0x01);
381 return dev_err_probe(data
->dev
, ret
,
382 "failed to set integration time\n");
384 ret
= veml3235_power_on(data
);
386 return dev_err_probe(dev
, ret
, "failed to power on\n");
388 return devm_add_action_or_reset(dev
, veml3235_shut_down_action
, data
);
391 static const struct iio_info veml3235_info
= {
392 .read_raw
= veml3235_read_raw
,
393 .read_avail
= veml3235_read_avail
,
394 .write_raw
= veml3235_write_raw
,
397 static int veml3235_probe(struct i2c_client
*client
)
399 struct device
*dev
= &client
->dev
;
400 struct veml3235_data
*data
;
401 struct iio_dev
*indio_dev
;
402 struct regmap
*regmap
;
405 regmap
= devm_regmap_init_i2c(client
, &veml3235_regmap_config
);
407 return dev_err_probe(dev
, PTR_ERR(regmap
),
408 "failed to setup regmap\n");
410 indio_dev
= devm_iio_device_alloc(dev
, sizeof(*data
));
414 data
= iio_priv(indio_dev
);
415 i2c_set_clientdata(client
, indio_dev
);
416 data
->client
= client
;
418 data
->regmap
= regmap
;
420 ret
= veml3235_regfield_init(data
);
422 return dev_err_probe(dev
, ret
, "failed to init regfield\n");
424 ret
= devm_regulator_get_enable(dev
, "vdd");
426 return dev_err_probe(dev
, ret
, "failed to enable regulator\n");
428 indio_dev
->name
= "veml3235";
429 indio_dev
->channels
= veml3235_channels
;
430 indio_dev
->num_channels
= ARRAY_SIZE(veml3235_channels
);
431 indio_dev
->modes
= INDIO_DIRECT_MODE
;
432 indio_dev
->info
= &veml3235_info
;
434 veml3235_read_id(data
);
436 ret
= veml3235_hw_init(indio_dev
);
440 return devm_iio_device_register(dev
, indio_dev
);
443 static int veml3235_runtime_suspend(struct device
*dev
)
445 struct veml3235_data
*data
= iio_priv(dev_get_drvdata(dev
));
448 ret
= veml3235_shut_down(data
);
450 dev_err(data
->dev
, "failed to suspend: %d\n", ret
);
455 static int veml3235_runtime_resume(struct device
*dev
)
457 struct veml3235_data
*data
= iio_priv(dev_get_drvdata(dev
));
460 ret
= veml3235_power_on(data
);
462 dev_err(data
->dev
, "failed to resume: %d\n", ret
);
467 static DEFINE_RUNTIME_DEV_PM_OPS(veml3235_pm_ops
, veml3235_runtime_suspend
,
468 veml3235_runtime_resume
, NULL
);
470 static const struct of_device_id veml3235_of_match
[] = {
471 { .compatible
= "vishay,veml3235" },
474 MODULE_DEVICE_TABLE(of
, veml3235_of_match
);
476 static const struct i2c_device_id veml3235_id
[] = {
480 MODULE_DEVICE_TABLE(i2c
, veml3235_id
);
482 static struct i2c_driver veml3235_driver
= {
485 .of_match_table
= veml3235_of_match
,
486 .pm
= pm_ptr(&veml3235_pm_ops
),
488 .probe
= veml3235_probe
,
489 .id_table
= veml3235_id
,
491 module_i2c_driver(veml3235_driver
);
493 MODULE_AUTHOR("Javier Carrasco <javier.carrasco.cruz@gmail.com>");
494 MODULE_DESCRIPTION("VEML3235 Ambient Light Sensor");
495 MODULE_LICENSE("GPL");