xref: /linux/drivers/iio/light/veml3235.c (revision 2eff01ee2881becc9daaa0d53477ec202136b1f4)
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/module.h>
15 #include <linux/pm_runtime.h>
16 #include <linux/regmap.h>
17 #include <linux/regulator/consumer.h>
18 
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
23 
24 #define VEML3235_CONF_SD        BIT(0)
25 #define VEML3235_CONF_SD0       BIT(15)
26 
27 struct veml3235_rf {
28 	struct regmap_field *it;
29 	struct regmap_field *gain;
30 	struct regmap_field *id;
31 };
32 
33 struct veml3235_data {
34 	struct i2c_client *client;
35 	struct device *dev;
36 	struct regmap *regmap;
37 	struct veml3235_rf rf;
38 };
39 
40 static const int veml3235_it_times[][2] = {
41 	{ 0, 50000 },
42 	{ 0, 100000 },
43 	{ 0, 200000 },
44 	{ 0, 400000 },
45 	{ 0, 800000 },
46 };
47 
48 static const int veml3235_scale_vals[] = { 1, 2, 4, 8 };
49 
50 static int veml3235_power_on(struct veml3235_data *data)
51 {
52 	int ret;
53 
54 	ret = regmap_clear_bits(data->regmap, VEML3235_REG_CONF,
55 				VEML3235_CONF_SD | VEML3235_CONF_SD0);
56 	if (ret)
57 		return ret;
58 
59 	/* Wait 4 ms to let processor & oscillator start correctly */
60 	fsleep(4000);
61 
62 	return 0;
63 }
64 
65 static int veml3235_shut_down(struct veml3235_data *data)
66 {
67 	return regmap_set_bits(data->regmap, VEML3235_REG_CONF,
68 			       VEML3235_CONF_SD | VEML3235_CONF_SD0);
69 }
70 
71 static void veml3235_shut_down_action(void *data)
72 {
73 	veml3235_shut_down(data);
74 }
75 
76 enum veml3235_chan {
77 	CH_ALS,
78 	CH_WHITE,
79 };
80 
81 static const struct iio_chan_spec veml3235_channels[] = {
82 	{
83 		.type = IIO_LIGHT,
84 		.channel = CH_ALS,
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),
90 	},
91 	{
92 		.type = IIO_INTENSITY,
93 		.channel = CH_WHITE,
94 		.modified = 1,
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),
101 	},
102 };
103 
104 static const struct regmap_config veml3235_regmap_config = {
105 	.name = "veml3235_regmap",
106 	.reg_bits = 8,
107 	.val_bits = 16,
108 	.max_register = VEML3235_REG_ID,
109 	.val_format_endian = REGMAP_ENDIAN_LITTLE,
110 };
111 
112 static int veml3235_get_it(struct veml3235_data *data, int *val, int *val2)
113 {
114 	int ret, reg;
115 
116 	ret = regmap_field_read(data->rf.it, &reg);
117 	if (ret)
118 		return ret;
119 
120 	switch (reg) {
121 	case 0:
122 		*val2 = 50000;
123 		break;
124 	case 1:
125 		*val2 = 100000;
126 		break;
127 	case 2:
128 		*val2 = 200000;
129 		break;
130 	case 3:
131 		*val2 = 400000;
132 		break;
133 	case 4:
134 		*val2 = 800000;
135 		break;
136 	default:
137 		return -EINVAL;
138 	}
139 
140 	*val = 0;
141 
142 	return IIO_VAL_INT_PLUS_MICRO;
143 }
144 
145 static int veml3235_set_it(struct iio_dev *indio_dev, int val, int val2)
146 {
147 	struct veml3235_data *data = iio_priv(indio_dev);
148 	int ret, new_it;
149 
150 	if (val)
151 		return -EINVAL;
152 
153 	switch (val2) {
154 	case 50000:
155 		new_it = 0x00;
156 		break;
157 	case 100000:
158 		new_it = 0x01;
159 		break;
160 	case 200000:
161 		new_it = 0x02;
162 		break;
163 	case 400000:
164 		new_it = 0x03;
165 		break;
166 	case 800000:
167 		new_it = 0x04;
168 		break;
169 	default:
170 		return -EINVAL;
171 	}
172 
173 	ret = regmap_field_write(data->rf.it, new_it);
174 	if (ret) {
175 		dev_err(data->dev,
176 			"failed to update integration time: %d\n", ret);
177 		return ret;
178 	}
179 
180 	return 0;
181 }
182 
183 static int veml3235_set_gain(struct iio_dev *indio_dev, int val, int val2)
184 {
185 	struct veml3235_data *data = iio_priv(indio_dev);
186 	int ret, new_gain;
187 
188 	if (val2 != 0)
189 		return -EINVAL;
190 
191 	switch (val) {
192 	case 1:
193 		new_gain = 0x00;
194 		break;
195 	case 2:
196 		new_gain = 0x01;
197 		break;
198 	case 4:
199 		new_gain = 0x03;
200 		break;
201 	case 8:
202 		new_gain = 0x07;
203 		break;
204 	default:
205 		return -EINVAL;
206 	}
207 
208 	ret = regmap_field_write(data->rf.gain, new_gain);
209 	if (ret) {
210 		dev_err(data->dev, "failed to set gain: %d\n", ret);
211 		return ret;
212 	}
213 
214 	return 0;
215 }
216 
217 static int veml3235_get_gain(struct veml3235_data *data, int *val)
218 {
219 	int ret, reg;
220 
221 	ret = regmap_field_read(data->rf.gain, &reg);
222 	if (ret) {
223 		dev_err(data->dev, "failed to read gain %d\n", ret);
224 		return ret;
225 	}
226 
227 	switch (reg & 0x03) {
228 	case 0:
229 		*val = 1;
230 		break;
231 	case 1:
232 		*val = 2;
233 		break;
234 	case 3:
235 		*val = 4;
236 		break;
237 	default:
238 		return -EINVAL;
239 	}
240 
241 	/* Double gain */
242 	if (reg & 0x04)
243 		*val *= 2;
244 
245 	return IIO_VAL_INT;
246 }
247 
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)
251 {
252 	struct veml3235_data *data = iio_priv(indio_dev);
253 	struct regmap *regmap = data->regmap;
254 	int ret, reg;
255 
256 	switch (mask) {
257 	case IIO_CHAN_INFO_RAW:
258 		switch (chan->type) {
259 		case IIO_LIGHT:
260 			ret = regmap_read(regmap, VEML3235_REG_ALS_DATA, &reg);
261 			if (ret < 0)
262 				return ret;
263 
264 			*val = reg;
265 			return IIO_VAL_INT;
266 		case IIO_INTENSITY:
267 			ret = regmap_read(regmap, VEML3235_REG_WH_DATA, &reg);
268 			if (ret < 0)
269 				return ret;
270 
271 			*val = reg;
272 			return IIO_VAL_INT;
273 		default:
274 			return -EINVAL;
275 		}
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);
280 	default:
281 		return -EINVAL;
282 	}
283 }
284 
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,
288 			       long mask)
289 {
290 	switch (mask) {
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);
299 		*type = IIO_VAL_INT;
300 		return IIO_AVAIL_LIST;
301 	default:
302 		return -EINVAL;
303 	}
304 }
305 
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)
309 {
310 	switch (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);
315 	}
316 
317 	return -EINVAL;
318 }
319 
320 static void veml3235_read_id(struct veml3235_data *data)
321 {
322 	int ret, reg;
323 
324 	ret = regmap_field_read(data->rf.id,  &reg);
325 	if (ret) {
326 		dev_info(data->dev, "failed to read ID\n");
327 		return;
328 	}
329 
330 	if (reg != 0x35)
331 		dev_info(data->dev, "Unknown ID %d\n", reg);
332 }
333 
334 static const struct reg_field veml3235_rf_it =
335 	REG_FIELD(VEML3235_REG_CONF, 4, 6);
336 
337 static const struct reg_field veml3235_rf_gain =
338 	REG_FIELD(VEML3235_REG_CONF, 11, 13);
339 
340 static const struct reg_field veml3235_rf_id =
341 	REG_FIELD(VEML3235_REG_ID, 0, 7);
342 
343 static int veml3235_regfield_init(struct veml3235_data *data)
344 {
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;
349 
350 	rm_field = devm_regmap_field_alloc(dev, regmap, veml3235_rf_it);
351 	if (IS_ERR(rm_field))
352 		return PTR_ERR(rm_field);
353 	rf->it = rm_field;
354 
355 	rm_field = devm_regmap_field_alloc(dev, regmap, veml3235_rf_gain);
356 	if (IS_ERR(rm_field))
357 		return PTR_ERR(rm_field);
358 	rf->gain = rm_field;
359 
360 	rm_field = devm_regmap_field_alloc(dev, regmap, veml3235_rf_id);
361 	if (IS_ERR(rm_field))
362 		return PTR_ERR(rm_field);
363 	rf->id = rm_field;
364 
365 	return 0;
366 }
367 
368 static int veml3235_hw_init(struct iio_dev *indio_dev)
369 {
370 	struct veml3235_data *data = iio_priv(indio_dev);
371 	struct device *dev = data->dev;
372 	int ret;
373 
374 	/* Set gain to 1 and integration time to 100 ms */
375 	ret = regmap_field_write(data->rf.gain, 0x00);
376 	if (ret)
377 		return dev_err_probe(data->dev, ret, "failed to set gain\n");
378 
379 	ret = regmap_field_write(data->rf.it, 0x01);
380 	if (ret)
381 		return dev_err_probe(data->dev, ret,
382 				     "failed to set integration time\n");
383 
384 	ret = veml3235_power_on(data);
385 	if (ret)
386 		return dev_err_probe(dev, ret, "failed to power on\n");
387 
388 	return devm_add_action_or_reset(dev, veml3235_shut_down_action, data);
389 }
390 
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,
395 };
396 
397 static int veml3235_probe(struct i2c_client *client)
398 {
399 	struct device *dev = &client->dev;
400 	struct veml3235_data *data;
401 	struct iio_dev *indio_dev;
402 	struct regmap *regmap;
403 	int ret;
404 
405 	regmap = devm_regmap_init_i2c(client, &veml3235_regmap_config);
406 	if (IS_ERR(regmap))
407 		return dev_err_probe(dev, PTR_ERR(regmap),
408 				     "failed to setup regmap\n");
409 
410 	indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
411 	if (!indio_dev)
412 		return -ENOMEM;
413 
414 	data = iio_priv(indio_dev);
415 	i2c_set_clientdata(client, indio_dev);
416 	data->client = client;
417 	data->dev = dev;
418 	data->regmap = regmap;
419 
420 	ret = veml3235_regfield_init(data);
421 	if (ret)
422 		return dev_err_probe(dev, ret, "failed to init regfield\n");
423 
424 	ret = devm_regulator_get_enable(dev, "vdd");
425 	if (ret)
426 		return dev_err_probe(dev, ret, "failed to enable regulator\n");
427 
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;
433 
434 	veml3235_read_id(data);
435 
436 	ret = veml3235_hw_init(indio_dev);
437 	if (ret < 0)
438 		return ret;
439 
440 	return devm_iio_device_register(dev, indio_dev);
441 }
442 
443 static int veml3235_runtime_suspend(struct device *dev)
444 {
445 	struct veml3235_data *data = iio_priv(dev_get_drvdata(dev));
446 	int ret;
447 
448 	ret = veml3235_shut_down(data);
449 	if (ret < 0)
450 		dev_err(data->dev, "failed to suspend: %d\n", ret);
451 
452 	return ret;
453 }
454 
455 static int veml3235_runtime_resume(struct device *dev)
456 {
457 	struct veml3235_data *data = iio_priv(dev_get_drvdata(dev));
458 	int ret;
459 
460 	ret = veml3235_power_on(data);
461 	if (ret < 0)
462 		dev_err(data->dev, "failed to resume: %d\n", ret);
463 
464 	return ret;
465 }
466 
467 static DEFINE_RUNTIME_DEV_PM_OPS(veml3235_pm_ops, veml3235_runtime_suspend,
468 				 veml3235_runtime_resume, NULL);
469 
470 static const struct of_device_id veml3235_of_match[] = {
471 	{ .compatible = "vishay,veml3235" },
472 	{ }
473 };
474 MODULE_DEVICE_TABLE(of, veml3235_of_match);
475 
476 static const struct i2c_device_id veml3235_id[] = {
477 	{ "veml3235" },
478 	{ }
479 };
480 MODULE_DEVICE_TABLE(i2c, veml3235_id);
481 
482 static struct i2c_driver veml3235_driver = {
483 	.driver = {
484 		.name = "veml3235",
485 		.of_match_table = veml3235_of_match,
486 		.pm = pm_ptr(&veml3235_pm_ops),
487 	},
488 	.probe = veml3235_probe,
489 	.id_table = veml3235_id,
490 };
491 module_i2c_driver(veml3235_driver);
492 
493 MODULE_AUTHOR("Javier Carrasco <javier.carrasco.cruz@gmail.com>");
494 MODULE_DESCRIPTION("VEML3235 Ambient Light Sensor");
495 MODULE_LICENSE("GPL");
496