File Index
Files and directories
Sign in
FILE

bh1745.c

File preview with syntax highlighting.

linux-6.19.14/drivers/iio/light/bh1745.c C
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 * ROHM BH1745 digital colour sensor driver
  4 *
  5 * Copyright (C) Mudit Sharma <muditsharma.info@gmail.com>
  6 *
  7 * 7-bit I2C slave addresses:
  8 *  0x38 (ADDR pin low)
  9 *  0x39 (ADDR pin high)
 10 */
 11
 12#include <linux/i2c.h>
 13#include <linux/mutex.h>
 14#include <linux/util_macros.h>
 15#include <linux/iio/events.h>
 16#include <linux/regmap.h>
 17#include <linux/bits.h>
 18#include <linux/bitfield.h>
 19
 20#include <linux/iio/iio.h>
 21#include <linux/iio/sysfs.h>
 22#include <linux/iio/trigger.h>
 23#include <linux/iio/trigger_consumer.h>
 24#include <linux/iio/triggered_buffer.h>
 25#include <linux/iio/iio-gts-helper.h>
 26
 27/* BH1745 configuration registers */
 28
 29/* System control */
 30#define BH1745_SYS_CTRL 0x40
 31#define BH1745_SYS_CTRL_SW_RESET BIT(7)
 32#define BH1745_SYS_CTRL_INTR_RESET BIT(6)
 33#define BH1745_SYS_CTRL_PART_ID_MASK GENMASK(5, 0)
 34#define BH1745_PART_ID 0x0B
 35
 36/* Mode control 1 */
 37#define BH1745_MODE_CTRL1 0x41
 38#define BH1745_CTRL1_MEASUREMENT_TIME_MASK GENMASK(2, 0)
 39
 40/* Mode control 2 */
 41#define BH1745_MODE_CTRL2 0x42
 42#define BH1745_CTRL2_RGBC_EN BIT(4)
 43#define BH1745_CTRL2_ADC_GAIN_MASK GENMASK(1, 0)
 44
 45/* Interrupt */
 46#define BH1745_INTR 0x60
 47#define BH1745_INTR_STATUS BIT(7)
 48#define BH1745_INTR_SOURCE_MASK GENMASK(3, 2)
 49#define BH1745_INTR_ENABLE BIT(0)
 50
 51#define BH1745_PERSISTENCE 0x61
 52
 53/* Threshold high */
 54#define BH1745_TH_LSB 0x62
 55#define BH1745_TH_MSB 0x63
 56
 57/* Threshold low */
 58#define BH1745_TL_LSB 0x64
 59#define BH1745_TL_MSB 0x65
 60
 61/* BH1745 data output regs */
 62#define BH1745_RED_LSB 0x50
 63#define BH1745_RED_MSB 0x51
 64#define BH1745_GREEN_LSB 0x52
 65#define BH1745_GREEN_MSB 0x53
 66#define BH1745_BLUE_LSB 0x54
 67#define BH1745_BLUE_MSB 0x55
 68#define BH1745_CLEAR_LSB 0x56
 69#define BH1745_CLEAR_MSB 0x57
 70
 71#define BH1745_MANU_ID_REG 0x92
 72
 73/* From 16x max HW gain and 32x max integration time */
 74#define BH1745_MAX_GAIN 512
 75
 76enum bh1745_int_source {
 77	BH1745_INTR_SOURCE_RED,
 78	BH1745_INTR_SOURCE_GREEN,
 79	BH1745_INTR_SOURCE_BLUE,
 80	BH1745_INTR_SOURCE_CLEAR,
 81};
 82
 83enum bh1745_gain {
 84	BH1745_ADC_GAIN_1X,
 85	BH1745_ADC_GAIN_2X,
 86	BH1745_ADC_GAIN_16X,
 87};
 88
 89enum bh1745_measurement_time {
 90	BH1745_MEASUREMENT_TIME_160MS,
 91	BH1745_MEASUREMENT_TIME_320MS,
 92	BH1745_MEASUREMENT_TIME_640MS,
 93	BH1745_MEASUREMENT_TIME_1280MS,
 94	BH1745_MEASUREMENT_TIME_2560MS,
 95	BH1745_MEASUREMENT_TIME_5120MS,
 96};
 97
 98enum bh1745_presistence_value {
 99	BH1745_PRESISTENCE_UPDATE_TOGGLE,
100	BH1745_PRESISTENCE_UPDATE_EACH_MEASUREMENT,
101	BH1745_PRESISTENCE_UPDATE_FOUR_MEASUREMENT,
102	BH1745_PRESISTENCE_UPDATE_EIGHT_MEASUREMENT,
103};
104
105static const struct iio_gain_sel_pair bh1745_gain[] = {
106	GAIN_SCALE_GAIN(1, BH1745_ADC_GAIN_1X),
107	GAIN_SCALE_GAIN(2, BH1745_ADC_GAIN_2X),
108	GAIN_SCALE_GAIN(16, BH1745_ADC_GAIN_16X),
109};
110
111static const struct iio_itime_sel_mul bh1745_itimes[] = {
112	GAIN_SCALE_ITIME_US(5120000, BH1745_MEASUREMENT_TIME_5120MS, 32),
113	GAIN_SCALE_ITIME_US(2560000, BH1745_MEASUREMENT_TIME_2560MS, 16),
114	GAIN_SCALE_ITIME_US(1280000, BH1745_MEASUREMENT_TIME_1280MS, 8),
115	GAIN_SCALE_ITIME_US(640000, BH1745_MEASUREMENT_TIME_640MS, 4),
116	GAIN_SCALE_ITIME_US(320000, BH1745_MEASUREMENT_TIME_320MS, 2),
117	GAIN_SCALE_ITIME_US(160000, BH1745_MEASUREMENT_TIME_160MS, 1),
118};
119
120struct bh1745_data {
121	/*
122	 * Lock to prevent device setting update or read before
123	 * related calculations are completed
124	 */
125	struct mutex lock;
126	struct regmap *regmap;
127	struct device *dev;
128	struct iio_trigger *trig;
129	struct iio_gts gts;
130};
131
132static const struct regmap_range bh1745_volatile_ranges[] = {
133	regmap_reg_range(BH1745_MODE_CTRL2, BH1745_MODE_CTRL2), /* VALID */
134	regmap_reg_range(BH1745_RED_LSB, BH1745_CLEAR_MSB), /* Data */
135	regmap_reg_range(BH1745_INTR, BH1745_INTR), /* Interrupt */
136};
137
138static const struct regmap_access_table bh1745_volatile_regs = {
139	.yes_ranges = bh1745_volatile_ranges,
140	.n_yes_ranges = ARRAY_SIZE(bh1745_volatile_ranges),
141};
142
143static const struct regmap_range bh1745_readable_ranges[] = {
144	regmap_reg_range(BH1745_SYS_CTRL, BH1745_MODE_CTRL2),
145	regmap_reg_range(BH1745_RED_LSB, BH1745_CLEAR_MSB),
146	regmap_reg_range(BH1745_INTR, BH1745_INTR),
147	regmap_reg_range(BH1745_PERSISTENCE, BH1745_TL_MSB),
148	regmap_reg_range(BH1745_MANU_ID_REG, BH1745_MANU_ID_REG),
149};
150
151static const struct regmap_access_table bh1745_readable_regs = {
152	.yes_ranges = bh1745_readable_ranges,
153	.n_yes_ranges = ARRAY_SIZE(bh1745_readable_ranges),
154};
155
156static const struct regmap_range bh1745_writable_ranges[] = {
157	regmap_reg_range(BH1745_SYS_CTRL, BH1745_MODE_CTRL2),
158	regmap_reg_range(BH1745_INTR, BH1745_INTR),
159	regmap_reg_range(BH1745_PERSISTENCE, BH1745_TL_MSB),
160};
161
162static const struct regmap_access_table bh1745_writable_regs = {
163	.yes_ranges = bh1745_writable_ranges,
164	.n_yes_ranges = ARRAY_SIZE(bh1745_writable_ranges),
165};
166
167static const struct regmap_config bh1745_regmap = {
168	.reg_bits = 8,
169	.val_bits = 8,
170	.max_register = BH1745_MANU_ID_REG,
171	.cache_type = REGCACHE_RBTREE,
172	.volatile_table = &bh1745_volatile_regs,
173	.wr_table = &bh1745_writable_regs,
174	.rd_table = &bh1745_readable_regs,
175};
176
177static const struct iio_event_spec bh1745_event_spec[] = {
178	{
179		.type = IIO_EV_TYPE_THRESH,
180		.dir = IIO_EV_DIR_RISING,
181		.mask_shared_by_type = BIT(IIO_EV_INFO_VALUE),
182	},
183	{
184		.type = IIO_EV_TYPE_THRESH,
185		.dir = IIO_EV_DIR_FALLING,
186		.mask_shared_by_type = BIT(IIO_EV_INFO_VALUE),
187	},
188	{
189		.type = IIO_EV_TYPE_THRESH,
190		.dir = IIO_EV_DIR_EITHER,
191		.mask_shared_by_type = BIT(IIO_EV_INFO_PERIOD),
192		.mask_separate = BIT(IIO_EV_INFO_ENABLE),
193	},
194};
195
196#define BH1745_CHANNEL(_colour, _si, _addr)                             \
197	{                                                               \
198		.type = IIO_INTENSITY, .modified = 1,                   \
199		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),           \
200		.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SCALE) |   \
201					   BIT(IIO_CHAN_INFO_INT_TIME), \
202		.info_mask_shared_by_all_available =                    \
203			BIT(IIO_CHAN_INFO_SCALE) |                      \
204			BIT(IIO_CHAN_INFO_INT_TIME),                    \
205		.event_spec = bh1745_event_spec,                        \
206		.num_event_specs = ARRAY_SIZE(bh1745_event_spec),       \
207		.channel2 = IIO_MOD_LIGHT_##_colour, .address = _addr,  \
208		.scan_index = _si,                                      \
209		.scan_type = {                                          \
210			.sign = 'u',                                    \
211			.realbits = 16,                                 \
212			.storagebits = 16,                              \
213			.endianness = IIO_CPU,                          \
214		},                                                      \
215	}
216
217static const struct iio_chan_spec bh1745_channels[] = {
218	BH1745_CHANNEL(RED, 0, BH1745_RED_LSB),
219	BH1745_CHANNEL(GREEN, 1, BH1745_GREEN_LSB),
220	BH1745_CHANNEL(BLUE, 2, BH1745_BLUE_LSB),
221	BH1745_CHANNEL(CLEAR, 3, BH1745_CLEAR_LSB),
222	IIO_CHAN_SOFT_TIMESTAMP(4),
223};
224
225static int bh1745_reset(struct bh1745_data *data)
226{
227	return regmap_set_bits(data->regmap, BH1745_SYS_CTRL,
228			       BH1745_SYS_CTRL_SW_RESET |
229			       BH1745_SYS_CTRL_INTR_RESET);
230}
231
232static int bh1745_power_on(struct bh1745_data *data)
233{
234	return regmap_set_bits(data->regmap, BH1745_MODE_CTRL2,
235			       BH1745_CTRL2_RGBC_EN);
236}
237
238static void bh1745_power_off(void *data_ptr)
239{
240	struct bh1745_data *data = data_ptr;
241	struct device *dev = data->dev;
242	int ret;
243
244	ret = regmap_clear_bits(data->regmap, BH1745_MODE_CTRL2,
245				BH1745_CTRL2_RGBC_EN);
246	if (ret)
247		dev_err(dev, "Failed to turn off device\n");
248}
249
250static int bh1745_get_scale(struct bh1745_data *data, int *val, int *val2)
251{
252	int ret;
253	int value;
254	int gain_sel, int_time_sel;
255	int gain;
256	const struct iio_itime_sel_mul *int_time;
257
258	ret = regmap_read(data->regmap, BH1745_MODE_CTRL2, &value);
259	if (ret)
260		return ret;
261
262	gain_sel = FIELD_GET(BH1745_CTRL2_ADC_GAIN_MASK, value);
263	gain = iio_gts_find_gain_by_sel(&data->gts, gain_sel);
264
265	ret = regmap_read(data->regmap, BH1745_MODE_CTRL1, &value);
266	if (ret)
267		return ret;
268
269	int_time_sel = FIELD_GET(BH1745_CTRL1_MEASUREMENT_TIME_MASK, value);
270	int_time = iio_gts_find_itime_by_sel(&data->gts, int_time_sel);
271
272	return iio_gts_get_scale(&data->gts, gain, int_time->time_us, val,
273				 val2);
274}
275
276static int bh1745_set_scale(struct bh1745_data *data, int val)
277{
278	struct device *dev = data->dev;
279	int ret;
280	int value;
281	int hw_gain_sel, current_int_time_sel, new_int_time_sel;
282
283	ret = regmap_read(data->regmap, BH1745_MODE_CTRL1, &value);
284	if (ret)
285		return ret;
286
287	current_int_time_sel = FIELD_GET(BH1745_CTRL1_MEASUREMENT_TIME_MASK,
288					 value);
289	ret = iio_gts_find_gain_sel_for_scale_using_time(&data->gts,
290							 current_int_time_sel,
291							 val, 0, &hw_gain_sel);
292	if (ret) {
293		for (int i = 0; i < data->gts.num_itime; i++) {
294			new_int_time_sel = data->gts.itime_table[i].sel;
295
296			if (new_int_time_sel == current_int_time_sel)
297				continue;
298
299			ret = iio_gts_find_gain_sel_for_scale_using_time(&data->gts,
300									 new_int_time_sel,
301									 val, 0,
302									 &hw_gain_sel);
303			if (!ret)
304				break;
305		}
306
307		if (ret) {
308			dev_dbg(dev, "Unsupported scale value requested: %d\n",
309				val);
310			return -EINVAL;
311		}
312
313		ret = regmap_write_bits(data->regmap, BH1745_MODE_CTRL1,
314					BH1745_CTRL1_MEASUREMENT_TIME_MASK,
315					new_int_time_sel);
316		if (ret)
317			return ret;
318	}
319
320	return regmap_write_bits(data->regmap, BH1745_MODE_CTRL2,
321				 BH1745_CTRL2_ADC_GAIN_MASK, hw_gain_sel);
322}
323
324static int bh1745_get_int_time(struct bh1745_data *data, int *val)
325{
326	int ret;
327	int value;
328	int int_time, int_time_sel;
329
330	ret = regmap_read(data->regmap, BH1745_MODE_CTRL1, &value);
331	if (ret)
332		return ret;
333
334	int_time_sel = FIELD_GET(BH1745_CTRL1_MEASUREMENT_TIME_MASK, value);
335	int_time = iio_gts_find_int_time_by_sel(&data->gts, int_time_sel);
336	if (int_time < 0)
337		return int_time;
338
339	*val = int_time;
340
341	return 0;
342}
343
344static int bh1745_set_int_time(struct bh1745_data *data, int val, int val2)
345{
346	struct device *dev = data->dev;
347	int ret;
348	int value;
349	int current_int_time, current_hwgain_sel, current_hwgain;
350	int new_hwgain, new_hwgain_sel, new_int_time_sel;
351	int req_int_time = (1000000 * val) + val2;
352
353	if (!iio_gts_valid_time(&data->gts, req_int_time)) {
354		dev_dbg(dev, "Unsupported integration time requested: %d\n",
355			req_int_time);
356		return -EINVAL;
357	}
358
359	ret = bh1745_get_int_time(data, &current_int_time);
360	if (ret)
361		return ret;
362
363	if (current_int_time == req_int_time)
364		return 0;
365
366	ret = regmap_read(data->regmap, BH1745_MODE_CTRL2, &value);
367	if (ret)
368		return ret;
369
370	current_hwgain_sel = FIELD_GET(BH1745_CTRL2_ADC_GAIN_MASK, value);
371	current_hwgain = iio_gts_find_gain_by_sel(&data->gts,
372						  current_hwgain_sel);
373	ret = iio_gts_find_new_gain_by_old_gain_time(&data->gts, current_hwgain,
374						     current_int_time,
375						     req_int_time,
376						     &new_hwgain);
377	if (new_hwgain < 0) {
378		dev_dbg(dev, "No corresponding gain for requested integration time\n");
379		return ret;
380	}
381
382	if (ret) {
383		bool in_range;
384
385		new_hwgain = iio_find_closest_gain_low(&data->gts, new_hwgain,
386						       &in_range);
387		if (new_hwgain < 0) {
388			new_hwgain = iio_gts_get_min_gain(&data->gts);
389			if (new_hwgain < 0)
390				return ret;
391		}
392
393		if (!in_range)
394			dev_dbg(dev, "Optimal gain out of range\n");
395
396		dev_dbg(dev, "Scale changed, new hw_gain %d\n", new_hwgain);
397	}
398
399	new_hwgain_sel = iio_gts_find_sel_by_gain(&data->gts, new_hwgain);
400	if (new_hwgain_sel < 0)
401		return new_hwgain_sel;
402
403	ret = regmap_write_bits(data->regmap, BH1745_MODE_CTRL2,
404				BH1745_CTRL2_ADC_GAIN_MASK,
405				new_hwgain_sel);
406	if (ret)
407		return ret;
408
409	new_int_time_sel = iio_gts_find_sel_by_int_time(&data->gts,
410							req_int_time);
411	if (new_int_time_sel < 0)
412		return new_int_time_sel;
413
414	return regmap_write_bits(data->regmap, BH1745_MODE_CTRL1,
415				 BH1745_CTRL1_MEASUREMENT_TIME_MASK,
416				 new_int_time_sel);
417}
418
419static int bh1745_read_raw(struct iio_dev *indio_dev,
420			   struct iio_chan_spec const *chan,
421			   int *val, int *val2, long mask)
422{
423	struct bh1745_data *data = iio_priv(indio_dev);
424	int ret;
425	int value;
426
427	switch (mask) {
428	case IIO_CHAN_INFO_RAW:
429		if (!iio_device_claim_direct(indio_dev))
430			return -EBUSY;
431
432		ret = regmap_bulk_read(data->regmap, chan->address, &value, 2);
433		iio_device_release_direct(indio_dev);
434		if (ret)
435			return ret;
436		*val = value;
437
438		return IIO_VAL_INT;
439
440	case IIO_CHAN_INFO_SCALE: {
441			guard(mutex)(&data->lock);
442			ret = bh1745_get_scale(data, val, val2);
443			if (ret)
444				return ret;
445
446			return IIO_VAL_INT;
447		}
448
449	case IIO_CHAN_INFO_INT_TIME: {
450			guard(mutex)(&data->lock);
451			*val = 0;
452			ret = bh1745_get_int_time(data, val2);
453			if (ret)
454				return 0;
455
456			return IIO_VAL_INT_PLUS_MICRO;
457		}
458
459	default:
460		return -EINVAL;
461	}
462}
463
464static int bh1745_write_raw(struct iio_dev *indio_dev,
465			    struct iio_chan_spec const *chan,
466			    int val, int val2, long mask)
467{
468	struct bh1745_data *data = iio_priv(indio_dev);
469
470	guard(mutex)(&data->lock);
471	switch (mask) {
472	case IIO_CHAN_INFO_SCALE:
473		return bh1745_set_scale(data, val);
474
475	case IIO_CHAN_INFO_INT_TIME:
476		return bh1745_set_int_time(data, val, val2);
477
478	default:
479		return -EINVAL;
480	}
481}
482
483static int bh1745_write_raw_get_fmt(struct iio_dev *indio_dev,
484				    struct iio_chan_spec const *chan,
485				    long mask)
486{
487	switch (mask) {
488	case IIO_CHAN_INFO_SCALE:
489		return IIO_VAL_INT;
490
491	case IIO_CHAN_INFO_INT_TIME:
492		return IIO_VAL_INT_PLUS_MICRO;
493
494	default:
495		return -EINVAL;
496	}
497}
498
499static int bh1745_read_thresh(struct iio_dev *indio_dev,
500			      const struct iio_chan_spec *chan,
501			      enum iio_event_type type,
502			      enum iio_event_direction dir,
503			      enum iio_event_info info, int *val, int *val2)
504{
505	struct bh1745_data *data = iio_priv(indio_dev);
506	int ret;
507
508	switch (info) {
509	case IIO_EV_INFO_VALUE:
510		switch (dir) {
511		case IIO_EV_DIR_RISING:
512			ret = regmap_bulk_read(data->regmap, BH1745_TH_LSB,
513					       val, 2);
514			if (ret)
515				return ret;
516
517			return IIO_VAL_INT;
518
519		case IIO_EV_DIR_FALLING:
520			ret = regmap_bulk_read(data->regmap, BH1745_TL_LSB,
521					       val, 2);
522			if (ret)
523				return ret;
524
525			return IIO_VAL_INT;
526
527		default:
528			return -EINVAL;
529		}
530
531	case IIO_EV_INFO_PERIOD:
532		ret = regmap_read(data->regmap, BH1745_PERSISTENCE, val);
533		if (ret)
534			return ret;
535
536		return IIO_VAL_INT;
537
538	default:
539		return -EINVAL;
540	}
541}
542
543static int bh1745_write_thresh(struct iio_dev *indio_dev,
544			       const struct iio_chan_spec *chan,
545			       enum iio_event_type type,
546			       enum iio_event_direction dir,
547			       enum iio_event_info info, int val, int val2)
548{
549	struct bh1745_data *data = iio_priv(indio_dev);
550	int ret;
551
552	switch (info) {
553	case IIO_EV_INFO_VALUE:
554		if (val < 0x0 || val > 0xFFFF)
555			return -EINVAL;
556
557		switch (dir) {
558		case IIO_EV_DIR_RISING:
559			ret = regmap_bulk_write(data->regmap, BH1745_TH_LSB,
560						&val, 2);
561			if (ret)
562				return ret;
563
564			return IIO_VAL_INT;
565
566		case IIO_EV_DIR_FALLING:
567			ret = regmap_bulk_write(data->regmap, BH1745_TL_LSB,
568						&val, 2);
569			if (ret)
570				return ret;
571
572			return IIO_VAL_INT;
573
574		default:
575			return -EINVAL;
576		}
577
578	case IIO_EV_INFO_PERIOD:
579		if (val < BH1745_PRESISTENCE_UPDATE_TOGGLE ||
580		    val > BH1745_PRESISTENCE_UPDATE_EIGHT_MEASUREMENT)
581			return -EINVAL;
582		ret = regmap_write(data->regmap, BH1745_PERSISTENCE, val);
583		if (ret)
584			return ret;
585
586		return IIO_VAL_INT;
587
588	default:
589		return -EINVAL;
590	}
591}
592
593static int bh1745_read_event_config(struct iio_dev *indio_dev,
594				    const struct iio_chan_spec *chan,
595				    enum iio_event_type type,
596				    enum iio_event_direction dir)
597{
598	struct bh1745_data *data = iio_priv(indio_dev);
599	int ret;
600	int value;
601	int int_src;
602
603	ret = regmap_read(data->regmap, BH1745_INTR, &value);
604	if (ret)
605		return ret;
606
607	if (!FIELD_GET(BH1745_INTR_ENABLE, value))
608		return 0;
609
610	int_src = FIELD_GET(BH1745_INTR_SOURCE_MASK, value);
611
612	switch (chan->channel2) {
613	case IIO_MOD_LIGHT_RED:
614		if (int_src == BH1745_INTR_SOURCE_RED)
615			return 1;
616		return 0;
617
618	case IIO_MOD_LIGHT_GREEN:
619		if (int_src == BH1745_INTR_SOURCE_GREEN)
620			return 1;
621		return 0;
622
623	case IIO_MOD_LIGHT_BLUE:
624		if (int_src == BH1745_INTR_SOURCE_BLUE)
625			return 1;
626		return 0;
627
628	case IIO_MOD_LIGHT_CLEAR:
629		if (int_src == BH1745_INTR_SOURCE_CLEAR)
630			return 1;
631		return 0;
632
633	default:
634		return -EINVAL;
635	}
636}
637
638static int bh1745_write_event_config(struct iio_dev *indio_dev,
639				     const struct iio_chan_spec *chan,
640				     enum iio_event_type type,
641				     enum iio_event_direction dir, bool state)
642{
643	struct bh1745_data *data = iio_priv(indio_dev);
644	int value;
645
646	if (!state)
647		return regmap_clear_bits(data->regmap,
648					 BH1745_INTR, BH1745_INTR_ENABLE);
649
650	/* Latch is always enabled when enabling interrupt */
651	value = BH1745_INTR_ENABLE;
652
653	switch (chan->channel2) {
654	case IIO_MOD_LIGHT_RED:
655		return regmap_write(data->regmap, BH1745_INTR,
656				    value | FIELD_PREP(BH1745_INTR_SOURCE_MASK,
657						       BH1745_INTR_SOURCE_RED));
658
659	case IIO_MOD_LIGHT_GREEN:
660		return regmap_write(data->regmap, BH1745_INTR,
661				    value | FIELD_PREP(BH1745_INTR_SOURCE_MASK,
662						       BH1745_INTR_SOURCE_GREEN));
663
664	case IIO_MOD_LIGHT_BLUE:
665		return regmap_write(data->regmap, BH1745_INTR,
666				    value | FIELD_PREP(BH1745_INTR_SOURCE_MASK,
667						       BH1745_INTR_SOURCE_BLUE));
668
669	case IIO_MOD_LIGHT_CLEAR:
670		return regmap_write(data->regmap, BH1745_INTR,
671				    value | FIELD_PREP(BH1745_INTR_SOURCE_MASK,
672						       BH1745_INTR_SOURCE_CLEAR));
673
674	default:
675		return -EINVAL;
676	}
677}
678
679static int bh1745_read_avail(struct iio_dev *indio_dev,
680			     struct iio_chan_spec const *chan, const int **vals,
681			     int *type, int *length, long mask)
682{
683	struct bh1745_data *data = iio_priv(indio_dev);
684
685	switch (mask) {
686	case IIO_CHAN_INFO_INT_TIME:
687		return iio_gts_avail_times(&data->gts, vals, type, length);
688
689	case IIO_CHAN_INFO_SCALE:
690		return iio_gts_all_avail_scales(&data->gts, vals, type, length);
691
692	default:
693		return -EINVAL;
694	}
695}
696
697static const struct iio_info bh1745_info = {
698	.read_raw = bh1745_read_raw,
699	.write_raw = bh1745_write_raw,
700	.write_raw_get_fmt = bh1745_write_raw_get_fmt,
701	.read_event_value = bh1745_read_thresh,
702	.write_event_value = bh1745_write_thresh,
703	.read_event_config = bh1745_read_event_config,
704	.write_event_config = bh1745_write_event_config,
705	.read_avail = bh1745_read_avail,
706};
707
708static irqreturn_t bh1745_interrupt_handler(int interrupt, void *p)
709{
710	struct iio_dev *indio_dev = p;
711	struct bh1745_data *data = iio_priv(indio_dev);
712	int ret;
713	int value;
714	int int_src;
715
716	ret = regmap_read(data->regmap, BH1745_INTR, &value);
717	if (ret)
718		return IRQ_NONE;
719
720	int_src = FIELD_GET(BH1745_INTR_SOURCE_MASK, value);
721
722	if (value & BH1745_INTR_STATUS) {
723		iio_push_event(indio_dev,
724			       IIO_UNMOD_EVENT_CODE(IIO_INTENSITY, int_src,
725						    IIO_EV_TYPE_THRESH,
726						    IIO_EV_DIR_EITHER),
727			       iio_get_time_ns(indio_dev));
728
729		return IRQ_HANDLED;
730	}
731
732	return IRQ_NONE;
733}
734
735static irqreturn_t bh1745_trigger_handler(int interrupt, void *p)
736{
737	struct iio_poll_func *pf = p;
738	struct iio_dev *indio_dev = pf->indio_dev;
739	struct bh1745_data *data = iio_priv(indio_dev);
740	struct {
741		u16 chans[4];
742		aligned_s64 timestamp;
743	} scan = { };
744	u16 value;
745	int ret;
746	int i;
747	int j = 0;
748
749	iio_for_each_active_channel(indio_dev, i) {
750		ret = regmap_bulk_read(data->regmap, BH1745_RED_LSB + 2 * i,
751				       &value, 2);
752		if (ret)
753			goto err;
754
755		scan.chans[j++] = value;
756	}
757
758	iio_push_to_buffers_with_ts(indio_dev, &scan, sizeof(scan),
759				    iio_get_time_ns(indio_dev));
760
761err:
762	iio_trigger_notify_done(indio_dev->trig);
763
764	return IRQ_HANDLED;
765}
766
767static int bh1745_setup_triggered_buffer(struct iio_dev *indio_dev,
768					 struct device *parent,
769					 int irq)
770{
771	struct bh1745_data *data = iio_priv(indio_dev);
772	struct device *dev = data->dev;
773	int ret;
774
775	ret = devm_iio_triggered_buffer_setup(parent, indio_dev, NULL,
776					      bh1745_trigger_handler, NULL);
777	if (ret)
778		return dev_err_probe(dev, ret,
779				     "Triggered buffer setup failed\n");
780
781	if (irq) {
782		ret = devm_request_threaded_irq(dev, irq, NULL,
783						bh1745_interrupt_handler,
784						IRQF_ONESHOT,
785						"bh1745_interrupt", indio_dev);
786		if (ret)
787			return dev_err_probe(dev, ret,
788					     "Request for IRQ failed\n");
789	}
790
791	return 0;
792}
793
794static int bh1745_init(struct bh1745_data *data)
795{
796	int ret;
797	struct device *dev = data->dev;
798
799	mutex_init(&data->lock);
800
801	ret = devm_iio_init_iio_gts(dev, BH1745_MAX_GAIN, 0, bh1745_gain,
802				    ARRAY_SIZE(bh1745_gain), bh1745_itimes,
803				    ARRAY_SIZE(bh1745_itimes), &data->gts);
804	if (ret)
805		return ret;
806
807	ret = bh1745_reset(data);
808	if (ret)
809		return dev_err_probe(dev, ret, "Failed to reset sensor\n");
810
811	ret = bh1745_power_on(data);
812	if (ret)
813		return dev_err_probe(dev, ret, "Failed to turn on sensor\n");
814
815	ret = devm_add_action_or_reset(dev, bh1745_power_off, data);
816	if (ret)
817		return ret;
818
819	return 0;
820}
821
822static int bh1745_probe(struct i2c_client *client)
823{
824	int ret;
825	int value;
826	int part_id;
827	struct bh1745_data *data;
828	struct iio_dev *indio_dev;
829	struct device *dev = &client->dev;
830
831	indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
832	if (!indio_dev)
833		return -ENOMEM;
834
835	indio_dev->info = &bh1745_info;
836	indio_dev->name = "bh1745";
837	indio_dev->channels = bh1745_channels;
838	indio_dev->modes = INDIO_DIRECT_MODE;
839	indio_dev->num_channels = ARRAY_SIZE(bh1745_channels);
840	data = iio_priv(indio_dev);
841	data->dev = &client->dev;
842	data->regmap = devm_regmap_init_i2c(client, &bh1745_regmap);
843	if (IS_ERR(data->regmap))
844		return dev_err_probe(dev, PTR_ERR(data->regmap),
845				     "Failed to initialize Regmap\n");
846
847	ret = regmap_read(data->regmap, BH1745_SYS_CTRL, &value);
848	if (ret)
849		return ret;
850
851	part_id = FIELD_GET(BH1745_SYS_CTRL_PART_ID_MASK, value);
852	if (part_id != BH1745_PART_ID)
853		dev_warn(dev, "Unknown part ID 0x%x\n", part_id);
854
855	ret = devm_regulator_get_enable(dev, "vdd");
856	if (ret)
857		return dev_err_probe(dev, ret,
858				     "Failed to get and enable regulator\n");
859
860	ret = bh1745_init(data);
861	if (ret)
862		return ret;
863
864	ret = bh1745_setup_triggered_buffer(indio_dev, indio_dev->dev.parent,
865					    client->irq);
866	if (ret)
867		return ret;
868
869	ret = devm_iio_device_register(dev, indio_dev);
870	if (ret)
871		return dev_err_probe(dev, ret, "Failed to register device\n");
872
873	return 0;
874}
875
876static const struct i2c_device_id bh1745_idtable[] = {
877	{ "bh1745" },
878	{ }
879};
880MODULE_DEVICE_TABLE(i2c, bh1745_idtable);
881
882static const struct of_device_id bh1745_of_match[] = {
883	{ .compatible = "rohm,bh1745" },
884	{ }
885};
886MODULE_DEVICE_TABLE(of, bh1745_of_match);
887
888static struct i2c_driver bh1745_driver = {
889	.driver = {
890		.name = "bh1745",
891		.of_match_table = bh1745_of_match,
892	},
893	.probe = bh1745_probe,
894	.id_table = bh1745_idtable,
895};
896module_i2c_driver(bh1745_driver);
897
898MODULE_LICENSE("GPL");
899MODULE_AUTHOR("Mudit Sharma <muditsharma.info@gmail.com>");
900MODULE_DESCRIPTION("BH1745 colour sensor driver");
901MODULE_IMPORT_NS("IIO_GTS_HELPER");
~/ Read-only file preview.