File Index
Files and directories
Sign in
FILE

ltr390.c

File preview with syntax highlighting.

linux-6.19.14/drivers/iio/light/ltr390.c C
  1// SPDX-License-Identifier: GPL-2.0-or-later
  2/*
  3 * IIO driver for Lite-On LTR390 ALS and UV sensor
  4 * (7-bit I2C slave address 0x53)
  5 *
  6 * Based on the work of:
  7 *   Shreeya Patel and Shi Zhigang (LTRF216 Driver)
  8 *
  9 * Copyright (C) 2023 Anshul Dalal <anshulusr@gmail.com>
 10 *
 11 * Datasheet:
 12 *   https://optoelectronics.liteon.com/upload/download/DS86-2015-0004/LTR-390UV_Final_%20DS_V1%201.pdf
 13 *
 14 * TODO:
 15 *   - Support for configurable gain and resolution
 16 *   - Sensor suspend/resume support
 17 *   - Add support for reading the ALS
 18 *   - Interrupt support
 19 */
 20
 21#include <linux/bitfield.h>
 22#include <linux/device.h>
 23#include <linux/i2c.h>
 24#include <linux/irq.h>
 25#include <linux/interrupt.h>
 26#include <linux/math.h>
 27#include <linux/module.h>
 28#include <linux/mutex.h>
 29#include <linux/pm_runtime.h>
 30#include <linux/regmap.h>
 31
 32#include <linux/iio/iio.h>
 33#include <linux/iio/events.h>
 34
 35#include <linux/unaligned.h>
 36
 37#define LTR390_MAIN_CTRL		0x00
 38#define LTR390_ALS_UVS_MEAS_RATE	0x04
 39#define LTR390_ALS_UVS_GAIN		0x05
 40#define LTR390_PART_ID			0x06
 41#define LTR390_MAIN_STATUS		0x07
 42
 43#define LTR390_ALS_DATA			0x0D
 44#define LTR390_ALS_DATA_BYTE(n)		(LTR390_ALS_DATA + (n))
 45
 46#define LTR390_UVS_DATA			0x10
 47#define LTR390_UVS_DATA_BYTE(n)		(LTR390_UVS_DATA + (n))
 48
 49#define LTR390_INT_CFG			0x19
 50#define LTR390_INT_PST			0x1A
 51
 52#define LTR390_THRESH_UP		0x21
 53#define LTR390_THRESH_UP_BYTE(n)	(LTR390_THRESH_UP + (n))
 54
 55#define LTR390_THRESH_LOW		0x24
 56#define LTR390_THRESH_LOW_BYTE(n)	(LTR390_THRESH_LOW + (n))
 57
 58#define LTR390_PART_NUMBER_ID		0xb
 59#define LTR390_ALS_UVS_GAIN_MASK	GENMASK(2, 0)
 60#define LTR390_ALS_UVS_MEAS_RATE_MASK	GENMASK(2, 0)
 61#define LTR390_ALS_UVS_INT_TIME_MASK	GENMASK(6, 4)
 62#define LTR390_ALS_UVS_INT_TIME(x)	FIELD_PREP(LTR390_ALS_UVS_INT_TIME_MASK, (x))
 63#define LTR390_INT_PST_MASK		GENMASK(7, 4)
 64#define LTR390_INT_PST_VAL(x)		FIELD_PREP(LTR390_INT_PST_MASK, (x))
 65
 66#define LTR390_SW_RESET	      BIT(4)
 67#define LTR390_UVS_MODE	      BIT(3)
 68#define LTR390_SENSOR_ENABLE  BIT(1)
 69#define LTR390_LS_INT_EN      BIT(2)
 70#define LTR390_LS_INT_SEL_UVS BIT(5)
 71
 72#define LTR390_FRACTIONAL_PRECISION 100
 73
 74/*
 75 * At 20-bit resolution (integration time: 400ms) and 18x gain, 2300 counts of
 76 * the sensor are equal to 1 UV Index [Datasheet Page#8].
 77 *
 78 * For the default resolution of 18-bit (integration time: 100ms) and default
 79 * gain of 3x, the counts/uvi are calculated as follows:
 80 * 2300 / ((3/18) * (100/400)) = 95.83
 81 */
 82#define LTR390_COUNTS_PER_UVI 96
 83
 84/*
 85 * Window Factor is needed when the device is under Window glass with coated
 86 * tinted ink. This is to compensate for the light loss due to the lower
 87 * transmission rate of the window glass and helps * in calculating lux.
 88 */
 89#define LTR390_WINDOW_FACTOR 1
 90
 91enum ltr390_mode {
 92	LTR390_SET_ALS_MODE,
 93	LTR390_SET_UVS_MODE,
 94};
 95
 96enum ltr390_meas_rate {
 97	LTR390_GET_FREQ,
 98	LTR390_GET_PERIOD,
 99};
100
101struct ltr390_data {
102	struct regmap *regmap;
103	struct i2c_client *client;
104	/* Protects device from simulataneous reads */
105	struct mutex lock;
106	enum ltr390_mode mode;
107	int gain;
108	int int_time_us;
109	bool irq_enabled;
110};
111
112static const struct regmap_range ltr390_readable_reg_ranges[] = {
113	regmap_reg_range(LTR390_MAIN_CTRL, LTR390_MAIN_CTRL),
114	regmap_reg_range(LTR390_ALS_UVS_MEAS_RATE, LTR390_MAIN_STATUS),
115	regmap_reg_range(LTR390_ALS_DATA_BYTE(0), LTR390_UVS_DATA_BYTE(2)),
116	regmap_reg_range(LTR390_INT_CFG, LTR390_INT_PST),
117	regmap_reg_range(LTR390_THRESH_UP_BYTE(0), LTR390_THRESH_LOW_BYTE(2)),
118};
119
120static const struct regmap_access_table ltr390_readable_reg_table = {
121	.yes_ranges = ltr390_readable_reg_ranges,
122	.n_yes_ranges = ARRAY_SIZE(ltr390_readable_reg_ranges),
123};
124
125static const struct regmap_range ltr390_writeable_reg_ranges[] = {
126	regmap_reg_range(LTR390_MAIN_CTRL, LTR390_MAIN_CTRL),
127	regmap_reg_range(LTR390_ALS_UVS_MEAS_RATE, LTR390_ALS_UVS_GAIN),
128	regmap_reg_range(LTR390_INT_CFG, LTR390_INT_PST),
129	regmap_reg_range(LTR390_THRESH_UP_BYTE(0), LTR390_THRESH_LOW_BYTE(2)),
130};
131
132static const struct regmap_access_table ltr390_writeable_reg_table = {
133	.yes_ranges = ltr390_writeable_reg_ranges,
134	.n_yes_ranges = ARRAY_SIZE(ltr390_writeable_reg_ranges),
135};
136
137static const struct regmap_config ltr390_regmap_config = {
138	.name = "ltr390",
139	.reg_bits = 8,
140	.reg_stride = 1,
141	.val_bits = 8,
142	.max_register = LTR390_THRESH_LOW_BYTE(2),
143	.rd_table = &ltr390_readable_reg_table,
144	.wr_table = &ltr390_writeable_reg_table,
145};
146
147/* Sampling frequency is in mili Hz and mili Seconds */
148static const int ltr390_samp_freq_table[][2] = {
149		[0] = { 40000, 25 },
150		[1] = { 20000, 50 },
151		[2] = { 10000, 100 },
152		[3] = { 5000, 200 },
153		[4] = { 2000, 500 },
154		[5] = { 1000, 1000 },
155		[6] = { 500, 2000 },
156		[7] = { 500, 2000 },
157};
158
159static int ltr390_register_read(struct ltr390_data *data, u8 register_address)
160{
161	struct device *dev = &data->client->dev;
162	int ret;
163	u8 receive_buffer[3];
164
165	ret = regmap_bulk_read(data->regmap, register_address, receive_buffer,
166			       sizeof(receive_buffer));
167	if (ret) {
168		dev_err(dev, "failed to read measurement data");
169		return ret;
170	}
171
172	return get_unaligned_le24(receive_buffer);
173}
174
175static int ltr390_set_mode(struct ltr390_data *data, enum ltr390_mode mode)
176{
177	int ret;
178
179	if (data->mode == mode)
180		return 0;
181
182	switch (mode) {
183	case LTR390_SET_ALS_MODE:
184		ret = regmap_clear_bits(data->regmap, LTR390_MAIN_CTRL, LTR390_UVS_MODE);
185		break;
186
187	case LTR390_SET_UVS_MODE:
188		ret = regmap_set_bits(data->regmap, LTR390_MAIN_CTRL, LTR390_UVS_MODE);
189		break;
190	}
191
192	if (ret)
193		return ret;
194
195	data->mode = mode;
196	return 0;
197}
198
199static int ltr390_counts_per_uvi(struct ltr390_data *data)
200{
201	const int orig_gain = 18;
202	const int orig_int_time = 400;
203
204	return DIV_ROUND_CLOSEST(23 * data->gain * data->int_time_us, 10 * orig_gain * orig_int_time);
205}
206
207static int ltr390_get_samp_freq_or_period(struct ltr390_data *data,
208					enum ltr390_meas_rate option)
209{
210	int ret, value;
211
212	ret = regmap_read(data->regmap, LTR390_ALS_UVS_MEAS_RATE, &value);
213	if (ret < 0)
214		return ret;
215	value = FIELD_GET(LTR390_ALS_UVS_MEAS_RATE_MASK, value);
216
217	return ltr390_samp_freq_table[value][option];
218}
219
220
221static int ltr390_do_read_raw(struct iio_dev *iio_device,
222			      struct iio_chan_spec const *chan, int *val,
223			      int *val2, long mask)
224{
225	int ret;
226	struct ltr390_data *data = iio_priv(iio_device);
227
228	guard(mutex)(&data->lock);
229	switch (mask) {
230	case IIO_CHAN_INFO_RAW:
231		switch (chan->type) {
232		case IIO_UVINDEX:
233			ret = ltr390_set_mode(data, LTR390_SET_UVS_MODE);
234			if (ret < 0)
235				return ret;
236
237			ret = ltr390_register_read(data, LTR390_UVS_DATA);
238			if (ret < 0)
239				return ret;
240			break;
241
242		case IIO_LIGHT:
243			ret = ltr390_set_mode(data, LTR390_SET_ALS_MODE);
244			if (ret < 0)
245				return ret;
246
247			ret = ltr390_register_read(data, LTR390_ALS_DATA);
248			if (ret < 0)
249				return ret;
250			break;
251
252		default:
253			return -EINVAL;
254		}
255		*val = ret;
256		return IIO_VAL_INT;
257	case IIO_CHAN_INFO_SCALE:
258		switch (chan->type) {
259		case IIO_UVINDEX:
260			*val = LTR390_WINDOW_FACTOR * LTR390_FRACTIONAL_PRECISION;
261			*val2 = ltr390_counts_per_uvi(data);
262			return IIO_VAL_FRACTIONAL;
263
264		case IIO_LIGHT:
265			*val = LTR390_WINDOW_FACTOR * 6 * 100;
266			*val2 = data->gain * data->int_time_us;
267			return IIO_VAL_FRACTIONAL;
268
269		default:
270			return -EINVAL;
271		}
272
273	case IIO_CHAN_INFO_INT_TIME:
274		*val = data->int_time_us;
275		return IIO_VAL_INT;
276
277	case IIO_CHAN_INFO_SAMP_FREQ:
278		*val = ltr390_get_samp_freq_or_period(data, LTR390_GET_FREQ);
279		return IIO_VAL_INT;
280
281	default:
282		return -EINVAL;
283	}
284}
285
286static int ltr390_read_raw(struct iio_dev *iio_device,
287			   struct iio_chan_spec const *chan,
288			   int *val, int *val2, long mask)
289{
290	int ret;
291	struct ltr390_data *data = iio_priv(iio_device);
292	struct device *dev = &data->client->dev;
293
294	ret = pm_runtime_resume_and_get(dev);
295	if (ret < 0) {
296		dev_err(dev, "runtime PM failed to resume: %d\n", ret);
297		return ret;
298	}
299
300	ret = ltr390_do_read_raw(iio_device, chan, val, val2, mask);
301
302	pm_runtime_put_autosuspend(dev);
303
304	return ret;
305}
306
307/* integration time in us */
308static const int ltr390_int_time_map_us[] = { 400000, 200000, 100000, 50000, 25000, 12500 };
309static const int ltr390_gain_map[] = { 1, 3, 6, 9, 18 };
310static const int ltr390_freq_map[] = { 40000, 20000, 10000, 5000, 2000, 1000, 500, 500 };
311
312static const struct iio_event_spec ltr390_event_spec[] = {
313	{
314		.type = IIO_EV_TYPE_THRESH,
315		.dir = IIO_EV_DIR_RISING,
316		.mask_separate = BIT(IIO_EV_INFO_VALUE),
317	}, {
318		.type = IIO_EV_TYPE_THRESH,
319		.dir = IIO_EV_DIR_FALLING,
320		.mask_separate = BIT(IIO_EV_INFO_VALUE),
321	}, {
322		.type = IIO_EV_TYPE_THRESH,
323		.dir = IIO_EV_DIR_EITHER,
324		.mask_separate = BIT(IIO_EV_INFO_ENABLE) |
325				BIT(IIO_EV_INFO_PERIOD),
326	}
327};
328
329static const struct iio_chan_spec ltr390_channels[] = {
330	/* UV sensor */
331	{
332		.type = IIO_UVINDEX,
333		.scan_index = 0,
334		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
335		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_INT_TIME) | BIT(IIO_CHAN_INFO_SAMP_FREQ),
336		.info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_INT_TIME) |
337							BIT(IIO_CHAN_INFO_SCALE) |
338							BIT(IIO_CHAN_INFO_SAMP_FREQ),
339		.event_spec = ltr390_event_spec,
340		.num_event_specs = ARRAY_SIZE(ltr390_event_spec),
341	},
342	/* ALS sensor */
343	{
344		.type = IIO_LIGHT,
345		.scan_index = 1,
346		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE),
347		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_INT_TIME) | BIT(IIO_CHAN_INFO_SAMP_FREQ),
348		.info_mask_shared_by_all_available = BIT(IIO_CHAN_INFO_INT_TIME) |
349							BIT(IIO_CHAN_INFO_SCALE) |
350							BIT(IIO_CHAN_INFO_SAMP_FREQ),
351		.event_spec = ltr390_event_spec,
352		.num_event_specs = ARRAY_SIZE(ltr390_event_spec),
353	},
354};
355
356static int ltr390_set_gain(struct ltr390_data *data, int val)
357{
358	int ret, idx;
359
360	for (idx = 0; idx < ARRAY_SIZE(ltr390_gain_map); idx++) {
361		if (ltr390_gain_map[idx] != val)
362			continue;
363
364		guard(mutex)(&data->lock);
365		ret = regmap_update_bits(data->regmap,
366					LTR390_ALS_UVS_GAIN,
367					LTR390_ALS_UVS_GAIN_MASK, idx);
368		if (ret)
369			return ret;
370
371		data->gain = ltr390_gain_map[idx];
372		return 0;
373	}
374
375	return -EINVAL;
376}
377
378static int ltr390_set_int_time(struct ltr390_data *data, int val)
379{
380	int ret, idx;
381
382	for (idx = 0; idx < ARRAY_SIZE(ltr390_int_time_map_us); idx++) {
383		if (ltr390_int_time_map_us[idx] != val)
384			continue;
385
386		guard(mutex)(&data->lock);
387		ret = regmap_update_bits(data->regmap,
388					LTR390_ALS_UVS_MEAS_RATE,
389					LTR390_ALS_UVS_INT_TIME_MASK,
390					LTR390_ALS_UVS_INT_TIME(idx));
391		if (ret)
392			return ret;
393
394		data->int_time_us = ltr390_int_time_map_us[idx];
395		return 0;
396	}
397
398	return -EINVAL;
399}
400
401static int ltr390_set_samp_freq(struct ltr390_data *data, int val)
402{
403	int idx;
404
405	for (idx = 0; idx < ARRAY_SIZE(ltr390_samp_freq_table); idx++) {
406		if (ltr390_samp_freq_table[idx][0] != val)
407			continue;
408
409		guard(mutex)(&data->lock);
410		return regmap_update_bits(data->regmap,
411					LTR390_ALS_UVS_MEAS_RATE,
412					LTR390_ALS_UVS_MEAS_RATE_MASK, idx);
413	}
414
415	return -EINVAL;
416}
417
418static int ltr390_read_avail(struct iio_dev *indio_dev, struct iio_chan_spec const *chan,
419				const int **vals, int *type, int *length, long mask)
420{
421	switch (mask) {
422	case IIO_CHAN_INFO_SCALE:
423		*length = ARRAY_SIZE(ltr390_gain_map);
424		*type = IIO_VAL_INT;
425		*vals = ltr390_gain_map;
426		return IIO_AVAIL_LIST;
427	case IIO_CHAN_INFO_INT_TIME:
428		*length = ARRAY_SIZE(ltr390_int_time_map_us);
429		*type = IIO_VAL_INT;
430		*vals = ltr390_int_time_map_us;
431		return IIO_AVAIL_LIST;
432	case IIO_CHAN_INFO_SAMP_FREQ:
433		*length = ARRAY_SIZE(ltr390_freq_map);
434		*type = IIO_VAL_INT;
435		*vals = ltr390_freq_map;
436		return IIO_AVAIL_LIST;
437	default:
438		return -EINVAL;
439	}
440}
441
442static int ltr390_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan,
443				int val, int val2, long mask)
444{
445	struct ltr390_data *data = iio_priv(indio_dev);
446
447	switch (mask) {
448	case IIO_CHAN_INFO_SCALE:
449		if (val2 != 0)
450			return -EINVAL;
451
452		return ltr390_set_gain(data, val);
453
454	case IIO_CHAN_INFO_INT_TIME:
455		if (val2 != 0)
456			return -EINVAL;
457
458		return ltr390_set_int_time(data, val);
459
460	case IIO_CHAN_INFO_SAMP_FREQ:
461		if (val2 != 0)
462			return -EINVAL;
463
464		return ltr390_set_samp_freq(data, val);
465
466	default:
467		return -EINVAL;
468	}
469}
470
471static int ltr390_read_intr_prst(struct ltr390_data *data, int *val)
472{
473	int ret, prst, samp_period;
474
475	samp_period = ltr390_get_samp_freq_or_period(data, LTR390_GET_PERIOD);
476	ret = regmap_read(data->regmap, LTR390_INT_PST, &prst);
477	if (ret < 0)
478		return ret;
479	*val = prst * samp_period;
480
481	return IIO_VAL_INT;
482}
483
484static int ltr390_write_intr_prst(struct ltr390_data *data, int val)
485{
486	int ret, samp_period, new_val;
487
488	samp_period = ltr390_get_samp_freq_or_period(data, LTR390_GET_PERIOD);
489
490	/* persist period should be greater than or equal to samp period */
491	if (val < samp_period)
492		return -EINVAL;
493
494	new_val = DIV_ROUND_UP(val, samp_period);
495	if (new_val < 0 || new_val > 0x0f)
496		return -EINVAL;
497
498	guard(mutex)(&data->lock);
499	ret = regmap_update_bits(data->regmap,
500				LTR390_INT_PST,
501				LTR390_INT_PST_MASK,
502				LTR390_INT_PST_VAL(new_val));
503	if (ret)
504		return ret;
505
506	return 0;
507}
508
509static int ltr390_read_threshold(struct iio_dev *indio_dev,
510				enum iio_event_direction dir,
511				int *val, int *val2)
512{
513	struct ltr390_data *data = iio_priv(indio_dev);
514	int ret;
515
516	switch (dir) {
517	case IIO_EV_DIR_RISING:
518		ret = ltr390_register_read(data, LTR390_THRESH_UP);
519		if (ret < 0)
520			return ret;
521		*val = ret;
522		return IIO_VAL_INT;
523
524	case IIO_EV_DIR_FALLING:
525		ret = ltr390_register_read(data, LTR390_THRESH_LOW);
526		if (ret < 0)
527			return ret;
528		*val = ret;
529		return IIO_VAL_INT;
530	default:
531		return -EINVAL;
532	}
533}
534
535static int ltr390_write_threshold(struct iio_dev *indio_dev,
536				enum iio_event_direction dir,
537				int val, int val2)
538{
539	struct ltr390_data *data = iio_priv(indio_dev);
540
541	guard(mutex)(&data->lock);
542	switch (dir) {
543	case IIO_EV_DIR_RISING:
544		return regmap_bulk_write(data->regmap, LTR390_THRESH_UP, &val, 3);
545
546	case IIO_EV_DIR_FALLING:
547		return regmap_bulk_write(data->regmap, LTR390_THRESH_LOW, &val, 3);
548
549	default:
550		return -EINVAL;
551	}
552}
553
554static int ltr390_read_event_value(struct iio_dev *indio_dev,
555				const struct iio_chan_spec *chan,
556				enum iio_event_type type,
557				enum iio_event_direction dir,
558				enum iio_event_info info,
559				int *val, int *val2)
560{
561	switch (info) {
562	case IIO_EV_INFO_VALUE:
563		return ltr390_read_threshold(indio_dev, dir, val, val2);
564
565	case IIO_EV_INFO_PERIOD:
566		return ltr390_read_intr_prst(iio_priv(indio_dev), val);
567
568	default:
569		return -EINVAL;
570	}
571}
572
573static int ltr390_write_event_value(struct iio_dev *indio_dev,
574				const struct iio_chan_spec *chan,
575				enum iio_event_type type,
576				enum iio_event_direction dir,
577				enum iio_event_info info,
578				int val, int val2)
579{
580	switch (info) {
581	case IIO_EV_INFO_VALUE:
582		if (val2 != 0)
583			return -EINVAL;
584
585		return ltr390_write_threshold(indio_dev, dir, val, val2);
586
587	case IIO_EV_INFO_PERIOD:
588		if (val2 != 0)
589			return -EINVAL;
590
591		return ltr390_write_intr_prst(iio_priv(indio_dev), val);
592
593	default:
594		return -EINVAL;
595	}
596}
597
598static int ltr390_read_event_config(struct iio_dev *indio_dev,
599				const struct iio_chan_spec *chan,
600				enum iio_event_type type,
601				enum iio_event_direction dir)
602{
603	struct ltr390_data *data = iio_priv(indio_dev);
604	int ret, status;
605
606	ret = regmap_read(data->regmap, LTR390_INT_CFG, &status);
607	if (ret < 0)
608		return ret;
609
610	return FIELD_GET(LTR390_LS_INT_EN, status);
611}
612
613static int ltr390_do_event_config(struct iio_dev *indio_dev,
614				  const struct iio_chan_spec *chan,
615				  enum iio_event_type type,
616				  enum iio_event_direction dir,
617				  bool state)
618{
619	struct ltr390_data *data = iio_priv(indio_dev);
620	int ret;
621
622	if (!state)
623		return regmap_clear_bits(data->regmap, LTR390_INT_CFG, LTR390_LS_INT_EN);
624
625	ret = regmap_set_bits(data->regmap, LTR390_INT_CFG, LTR390_LS_INT_EN);
626	if (ret < 0)
627		return ret;
628
629	switch (chan->type) {
630	case IIO_LIGHT:
631		ret = ltr390_set_mode(data, LTR390_SET_ALS_MODE);
632		if (ret < 0)
633			return ret;
634
635		return regmap_clear_bits(data->regmap, LTR390_INT_CFG, LTR390_LS_INT_SEL_UVS);
636
637	case IIO_UVINDEX:
638		ret = ltr390_set_mode(data, LTR390_SET_UVS_MODE);
639		if (ret < 0)
640			return ret;
641
642		return regmap_set_bits(data->regmap, LTR390_INT_CFG, LTR390_LS_INT_SEL_UVS);
643
644	default:
645		return -EINVAL;
646	}
647}
648
649static int ltr390_write_event_config(struct iio_dev *indio_dev,
650				     const struct iio_chan_spec *chan,
651				     enum iio_event_type type,
652				     enum iio_event_direction dir,
653				     bool state)
654{
655	int ret;
656	struct ltr390_data *data = iio_priv(indio_dev);
657	struct device *dev = &data->client->dev;
658
659	guard(mutex)(&data->lock);
660
661	if (state && !data->irq_enabled) {
662		ret = pm_runtime_resume_and_get(dev);
663		if (ret < 0) {
664			dev_err(dev, "runtime PM failed to resume: %d\n", ret);
665			return ret;
666		}
667		data->irq_enabled = true;
668	}
669
670	ret = ltr390_do_event_config(indio_dev, chan, type, dir, state);
671
672	if (!state && data->irq_enabled) {
673		data->irq_enabled = false;
674		pm_runtime_put_autosuspend(dev);
675	}
676
677	return ret;
678}
679
680static int ltr390_debugfs_reg_access(struct iio_dev *indio_dev,
681						unsigned int reg, unsigned int writeval,
682						unsigned int *readval)
683{
684	struct ltr390_data *data = iio_priv(indio_dev);
685
686	guard(mutex)(&data->lock);
687
688	if (readval)
689		return regmap_read(data->regmap, reg, readval);
690
691	return regmap_write(data->regmap, reg, writeval);
692}
693
694static const struct iio_info ltr390_info = {
695	.read_raw = ltr390_read_raw,
696	.write_raw = ltr390_write_raw,
697	.read_avail = ltr390_read_avail,
698	.read_event_value = ltr390_read_event_value,
699	.read_event_config = ltr390_read_event_config,
700	.write_event_value = ltr390_write_event_value,
701	.write_event_config = ltr390_write_event_config,
702	.debugfs_reg_access = ltr390_debugfs_reg_access,
703};
704
705static irqreturn_t ltr390_interrupt_handler(int irq, void *private)
706{
707	struct iio_dev *indio_dev = private;
708	struct ltr390_data *data = iio_priv(indio_dev);
709	int ret, status;
710
711	/* Reading the status register to clear the interrupt flag, Datasheet pg: 17*/
712	ret = regmap_read(data->regmap, LTR390_MAIN_STATUS, &status);
713	if (ret < 0)
714		return ret;
715
716	switch (data->mode) {
717	case LTR390_SET_ALS_MODE:
718		iio_push_event(indio_dev,
719				IIO_UNMOD_EVENT_CODE(IIO_LIGHT, 0,
720				IIO_EV_TYPE_THRESH,
721				IIO_EV_DIR_EITHER),
722				iio_get_time_ns(indio_dev));
723		break;
724
725	case LTR390_SET_UVS_MODE:
726		iio_push_event(indio_dev,
727				IIO_UNMOD_EVENT_CODE(IIO_UVINDEX, 0,
728				IIO_EV_TYPE_THRESH,
729				IIO_EV_DIR_EITHER),
730				iio_get_time_ns(indio_dev));
731		break;
732	}
733
734	return IRQ_HANDLED;
735}
736
737static void ltr390_powerdown(void *priv)
738{
739	struct ltr390_data *data = priv;
740	struct device *dev = &data->client->dev;
741	int ret;
742
743	guard(mutex)(&data->lock);
744
745	/* Ensure that power off and interrupts are disabled */
746	if (data->irq_enabled) {
747		ret = regmap_clear_bits(data->regmap, LTR390_INT_CFG, LTR390_LS_INT_EN);
748		if (ret < 0)
749			dev_err(dev, "failed to disable interrupts\n");
750
751		data->irq_enabled = false;
752		pm_runtime_put_autosuspend(dev);
753	}
754
755	ret = regmap_clear_bits(data->regmap, LTR390_MAIN_CTRL, LTR390_SENSOR_ENABLE);
756	if (ret < 0)
757		dev_err(dev, "failed to disable sensor\n");
758}
759
760static int ltr390_pm_init(struct ltr390_data *data)
761{
762	int ret;
763	struct device *dev = &data->client->dev;
764
765	ret = devm_pm_runtime_set_active_enabled(dev);
766	if (ret)
767		return dev_err_probe(dev, ret, "failed to enable runtime PM\n");
768
769	pm_runtime_set_autosuspend_delay(dev, 1000);
770	pm_runtime_use_autosuspend(dev);
771	return 0;
772}
773
774static int ltr390_probe(struct i2c_client *client)
775{
776	struct ltr390_data *data;
777	struct iio_dev *indio_dev;
778	struct device *dev;
779	int ret, part_number;
780
781	dev = &client->dev;
782	indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
783	if (!indio_dev)
784		return -ENOMEM;
785
786	i2c_set_clientdata(client, indio_dev);
787
788	data = iio_priv(indio_dev);
789	data->regmap = devm_regmap_init_i2c(client, &ltr390_regmap_config);
790	if (IS_ERR(data->regmap))
791		return dev_err_probe(dev, PTR_ERR(data->regmap),
792				     "regmap initialization failed\n");
793
794	data->client = client;
795	/* default value of integration time from pg: 15 of the datasheet */
796	data->int_time_us = 100000;
797	/* default value of gain from pg: 16 of the datasheet */
798	data->gain = 3;
799	/* default mode for ltr390 is ALS mode */
800	data->mode = LTR390_SET_ALS_MODE;
801	/* default value of irq_enabled is false */
802	data->irq_enabled = false;
803
804	mutex_init(&data->lock);
805
806	indio_dev->info = &ltr390_info;
807	indio_dev->channels = ltr390_channels;
808	indio_dev->num_channels = ARRAY_SIZE(ltr390_channels);
809	indio_dev->name = "ltr390";
810
811	ret = regmap_read(data->regmap, LTR390_PART_ID, &part_number);
812	if (ret)
813		return dev_err_probe(dev, ret,
814				     "failed to get sensor's part id\n");
815	/* Lower 4 bits of `part_number` change with hardware revisions */
816	if (part_number >> 4 != LTR390_PART_NUMBER_ID)
817		dev_info(dev, "received invalid product id: 0x%x", part_number);
818	dev_dbg(dev, "LTR390, product id: 0x%x\n", part_number);
819
820	/* reset sensor, chip fails to respond to this, so ignore any errors */
821	regmap_set_bits(data->regmap, LTR390_MAIN_CTRL, LTR390_SW_RESET);
822
823	/* Wait for the registers to reset before proceeding */
824	usleep_range(1000, 2000);
825
826	ret = regmap_set_bits(data->regmap, LTR390_MAIN_CTRL, LTR390_SENSOR_ENABLE);
827	if (ret)
828		return dev_err_probe(dev, ret, "failed to enable the sensor\n");
829
830	ret = devm_add_action_or_reset(dev, ltr390_powerdown, data);
831	if (ret)
832		return dev_err_probe(dev, ret, "failed to add action or reset\n");
833
834	if (client->irq) {
835		ret = devm_request_threaded_irq(dev, client->irq,
836						NULL, ltr390_interrupt_handler,
837						IRQF_ONESHOT,
838						"ltr390_thresh_event",
839						indio_dev);
840		if (ret)
841			return dev_err_probe(dev, ret,
842					     "request irq (%d) failed\n", client->irq);
843	}
844
845	ret = ltr390_pm_init(data);
846	if (ret)
847		return dev_err_probe(dev, ret, "failed to initialize runtime PM\n");
848
849	return devm_iio_device_register(dev, indio_dev);
850}
851
852static int ltr390_suspend(struct device *dev)
853{
854	struct iio_dev *indio_dev = dev_get_drvdata(dev);
855	struct ltr390_data *data = iio_priv(indio_dev);
856
857	return regmap_clear_bits(data->regmap, LTR390_MAIN_CTRL,
858				LTR390_SENSOR_ENABLE);
859}
860
861static int ltr390_resume(struct device *dev)
862{
863	struct iio_dev *indio_dev = dev_get_drvdata(dev);
864	struct ltr390_data *data = iio_priv(indio_dev);
865
866	return regmap_set_bits(data->regmap, LTR390_MAIN_CTRL,
867				LTR390_SENSOR_ENABLE);
868}
869
870static int ltr390_runtime_suspend(struct device *dev)
871{
872	struct iio_dev *indio_dev = dev_get_drvdata(dev);
873	struct ltr390_data *data = iio_priv(indio_dev);
874
875	return regmap_clear_bits(data->regmap, LTR390_MAIN_CTRL, LTR390_SENSOR_ENABLE);
876}
877
878static int ltr390_runtime_resume(struct device *dev)
879{
880	struct iio_dev *indio_dev = dev_get_drvdata(dev);
881	struct ltr390_data *data = iio_priv(indio_dev);
882
883	return regmap_set_bits(data->regmap, LTR390_MAIN_CTRL, LTR390_SENSOR_ENABLE);
884}
885
886static const struct dev_pm_ops ltr390_pm_ops = {
887	SYSTEM_SLEEP_PM_OPS(ltr390_suspend, ltr390_resume)
888	RUNTIME_PM_OPS(ltr390_runtime_suspend, ltr390_runtime_resume, NULL)
889};
890
891static const struct i2c_device_id ltr390_id[] = {
892	{ "ltr390" },
893	{ }
894};
895MODULE_DEVICE_TABLE(i2c, ltr390_id);
896
897static const struct of_device_id ltr390_of_table[] = {
898	{ .compatible = "liteon,ltr390" },
899	{ }
900};
901MODULE_DEVICE_TABLE(of, ltr390_of_table);
902
903static struct i2c_driver ltr390_driver = {
904	.driver = {
905		.name = "ltr390",
906		.of_match_table = ltr390_of_table,
907		.pm = pm_ptr(&ltr390_pm_ops),
908	},
909	.probe = ltr390_probe,
910	.id_table = ltr390_id,
911};
912module_i2c_driver(ltr390_driver);
913
914MODULE_AUTHOR("Anshul Dalal <anshulusr@gmail.com>");
915MODULE_DESCRIPTION("Lite-On LTR390 ALS and UV sensor Driver");
916MODULE_LICENSE("GPL");
~/ Read-only file preview.