xref: /linux/drivers/iio/light/bh1745.c (revision 3a39d672e7f48b8d6b91a09afa4b55352773b4b5)
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 
76 enum 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 
83 enum bh1745_gain {
84 	BH1745_ADC_GAIN_1X,
85 	BH1745_ADC_GAIN_2X,
86 	BH1745_ADC_GAIN_16X,
87 };
88 
89 enum 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 
98 enum 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 
105 static 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 
111 static 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 
120 struct 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 
132 static 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 
138 static 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 
143 static 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 
151 static 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 
156 static 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 
162 static 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 
167 static 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 
177 static 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 
217 static 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 
bh1745_reset(struct bh1745_data * data)225 static 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 
bh1745_power_on(struct bh1745_data * data)232 static 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 
bh1745_power_off(void * data_ptr)238 static 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 
bh1745_get_scale(struct bh1745_data * data,int * val,int * val2)250 static 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 
bh1745_set_scale(struct bh1745_data * data,int val)276 static 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 
bh1745_get_int_time(struct bh1745_data * data,int * val)324 static 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 
bh1745_set_int_time(struct bh1745_data * data,int val,int val2)344 static 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 
bh1745_read_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int * val,int * val2,long mask)419 static 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 		iio_device_claim_direct_scoped(return -EBUSY, indio_dev) {
430 			ret = regmap_bulk_read(data->regmap, chan->address,
431 					       &value, 2);
432 			if (ret)
433 				return ret;
434 			*val = value;
435 
436 			return IIO_VAL_INT;
437 		}
438 		unreachable();
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 
bh1745_write_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int val,int val2,long mask)464 static 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 
bh1745_write_raw_get_fmt(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,long mask)483 static 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 
bh1745_read_thresh(struct iio_dev * indio_dev,const struct iio_chan_spec * chan,enum iio_event_type type,enum iio_event_direction dir,enum iio_event_info info,int * val,int * val2)499 static 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 
bh1745_write_thresh(struct iio_dev * indio_dev,const struct iio_chan_spec * chan,enum iio_event_type type,enum iio_event_direction dir,enum iio_event_info info,int val,int val2)543 static 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 
bh1745_read_event_config(struct iio_dev * indio_dev,const struct iio_chan_spec * chan,enum iio_event_type type,enum iio_event_direction dir)593 static 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 
bh1745_write_event_config(struct iio_dev * indio_dev,const struct iio_chan_spec * chan,enum iio_event_type type,enum iio_event_direction dir,int state)638 static 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, int state)
642 {
643 	struct bh1745_data *data = iio_priv(indio_dev);
644 	int value;
645 
646 	if (state == 0)
647 		return regmap_clear_bits(data->regmap,
648 					 BH1745_INTR, BH1745_INTR_ENABLE);
649 
650 	if (state == 1) {
651 		/* Latch is always enabled when enabling interrupt */
652 		value = BH1745_INTR_ENABLE;
653 
654 		switch (chan->channel2) {
655 		case IIO_MOD_LIGHT_RED:
656 			return regmap_write(data->regmap, BH1745_INTR,
657 					    value | FIELD_PREP(BH1745_INTR_SOURCE_MASK,
658 							       BH1745_INTR_SOURCE_RED));
659 
660 		case IIO_MOD_LIGHT_GREEN:
661 			return regmap_write(data->regmap, BH1745_INTR,
662 					    value | FIELD_PREP(BH1745_INTR_SOURCE_MASK,
663 							       BH1745_INTR_SOURCE_GREEN));
664 
665 		case IIO_MOD_LIGHT_BLUE:
666 			return regmap_write(data->regmap, BH1745_INTR,
667 					    value | FIELD_PREP(BH1745_INTR_SOURCE_MASK,
668 							       BH1745_INTR_SOURCE_BLUE));
669 
670 		case IIO_MOD_LIGHT_CLEAR:
671 			return regmap_write(data->regmap, BH1745_INTR,
672 					    value | FIELD_PREP(BH1745_INTR_SOURCE_MASK,
673 							       BH1745_INTR_SOURCE_CLEAR));
674 
675 		default:
676 			return -EINVAL;
677 		}
678 	}
679 
680 	return -EINVAL;
681 }
682 
bh1745_read_avail(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,const int ** vals,int * type,int * length,long mask)683 static int bh1745_read_avail(struct iio_dev *indio_dev,
684 			     struct iio_chan_spec const *chan, const int **vals,
685 			     int *type, int *length, long mask)
686 {
687 	struct bh1745_data *data = iio_priv(indio_dev);
688 
689 	switch (mask) {
690 	case IIO_CHAN_INFO_INT_TIME:
691 		return iio_gts_avail_times(&data->gts, vals, type, length);
692 
693 	case IIO_CHAN_INFO_SCALE:
694 		return iio_gts_all_avail_scales(&data->gts, vals, type, length);
695 
696 	default:
697 		return -EINVAL;
698 	}
699 }
700 
701 static const struct iio_info bh1745_info = {
702 	.read_raw = bh1745_read_raw,
703 	.write_raw = bh1745_write_raw,
704 	.write_raw_get_fmt = bh1745_write_raw_get_fmt,
705 	.read_event_value = bh1745_read_thresh,
706 	.write_event_value = bh1745_write_thresh,
707 	.read_event_config = bh1745_read_event_config,
708 	.write_event_config = bh1745_write_event_config,
709 	.read_avail = bh1745_read_avail,
710 };
711 
bh1745_interrupt_handler(int interrupt,void * p)712 static irqreturn_t bh1745_interrupt_handler(int interrupt, void *p)
713 {
714 	struct iio_dev *indio_dev = p;
715 	struct bh1745_data *data = iio_priv(indio_dev);
716 	int ret;
717 	int value;
718 	int int_src;
719 
720 	ret = regmap_read(data->regmap, BH1745_INTR, &value);
721 	if (ret)
722 		return IRQ_NONE;
723 
724 	int_src = FIELD_GET(BH1745_INTR_SOURCE_MASK, value);
725 
726 	if (value & BH1745_INTR_STATUS) {
727 		iio_push_event(indio_dev,
728 			       IIO_UNMOD_EVENT_CODE(IIO_INTENSITY, int_src,
729 						    IIO_EV_TYPE_THRESH,
730 						    IIO_EV_DIR_EITHER),
731 			       iio_get_time_ns(indio_dev));
732 
733 		return IRQ_HANDLED;
734 	}
735 
736 	return IRQ_NONE;
737 }
738 
bh1745_trigger_handler(int interrupt,void * p)739 static irqreturn_t bh1745_trigger_handler(int interrupt, void *p)
740 {
741 	struct iio_poll_func *pf = p;
742 	struct iio_dev *indio_dev = pf->indio_dev;
743 	struct bh1745_data *data = iio_priv(indio_dev);
744 	struct {
745 		u16 chans[4];
746 		s64 timestamp __aligned(8);
747 	} scan;
748 	u16 value;
749 	int ret;
750 	int i;
751 	int j = 0;
752 
753 	iio_for_each_active_channel(indio_dev, i) {
754 		ret = regmap_bulk_read(data->regmap, BH1745_RED_LSB + 2 * i,
755 				       &value, 2);
756 		if (ret)
757 			goto err;
758 
759 		scan.chans[j++] = value;
760 	}
761 
762 	iio_push_to_buffers_with_timestamp(indio_dev, &scan,
763 					   iio_get_time_ns(indio_dev));
764 
765 err:
766 	iio_trigger_notify_done(indio_dev->trig);
767 
768 	return IRQ_HANDLED;
769 }
770 
bh1745_setup_triggered_buffer(struct iio_dev * indio_dev,struct device * parent,int irq)771 static int bh1745_setup_triggered_buffer(struct iio_dev *indio_dev,
772 					 struct device *parent,
773 					 int irq)
774 {
775 	struct bh1745_data *data = iio_priv(indio_dev);
776 	struct device *dev = data->dev;
777 	int ret;
778 
779 	ret = devm_iio_triggered_buffer_setup(parent, indio_dev, NULL,
780 					      bh1745_trigger_handler, NULL);
781 	if (ret)
782 		return dev_err_probe(dev, ret,
783 				     "Triggered buffer setup failed\n");
784 
785 	if (irq) {
786 		ret = devm_request_threaded_irq(dev, irq, NULL,
787 						bh1745_interrupt_handler,
788 						IRQF_ONESHOT,
789 						"bh1745_interrupt", indio_dev);
790 		if (ret)
791 			return dev_err_probe(dev, ret,
792 					     "Request for IRQ failed\n");
793 	}
794 
795 	return 0;
796 }
797 
bh1745_init(struct bh1745_data * data)798 static int bh1745_init(struct bh1745_data *data)
799 {
800 	int ret;
801 	struct device *dev = data->dev;
802 
803 	mutex_init(&data->lock);
804 
805 	ret = devm_iio_init_iio_gts(dev, BH1745_MAX_GAIN, 0, bh1745_gain,
806 				    ARRAY_SIZE(bh1745_gain), bh1745_itimes,
807 				    ARRAY_SIZE(bh1745_itimes), &data->gts);
808 	if (ret)
809 		return ret;
810 
811 	ret = bh1745_reset(data);
812 	if (ret)
813 		return dev_err_probe(dev, ret, "Failed to reset sensor\n");
814 
815 	ret = bh1745_power_on(data);
816 	if (ret)
817 		return dev_err_probe(dev, ret, "Failed to turn on sensor\n");
818 
819 	ret = devm_add_action_or_reset(dev, bh1745_power_off, data);
820 	if (ret)
821 		return dev_err_probe(dev, ret,
822 				     "Failed to add action or reset\n");
823 
824 	return 0;
825 }
826 
bh1745_probe(struct i2c_client * client)827 static int bh1745_probe(struct i2c_client *client)
828 {
829 	int ret;
830 	int value;
831 	int part_id;
832 	struct bh1745_data *data;
833 	struct iio_dev *indio_dev;
834 	struct device *dev = &client->dev;
835 
836 	indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
837 	if (!indio_dev)
838 		return -ENOMEM;
839 
840 	indio_dev->info = &bh1745_info;
841 	indio_dev->name = "bh1745";
842 	indio_dev->channels = bh1745_channels;
843 	indio_dev->modes = INDIO_DIRECT_MODE;
844 	indio_dev->num_channels = ARRAY_SIZE(bh1745_channels);
845 	data = iio_priv(indio_dev);
846 	data->dev = &client->dev;
847 	data->regmap = devm_regmap_init_i2c(client, &bh1745_regmap);
848 	if (IS_ERR(data->regmap))
849 		return dev_err_probe(dev, PTR_ERR(data->regmap),
850 				     "Failed to initialize Regmap\n");
851 
852 	ret = regmap_read(data->regmap, BH1745_SYS_CTRL, &value);
853 	if (ret)
854 		return ret;
855 
856 	part_id = FIELD_GET(BH1745_SYS_CTRL_PART_ID_MASK, value);
857 	if (part_id != BH1745_PART_ID)
858 		dev_warn(dev, "Unknown part ID 0x%x\n", part_id);
859 
860 	ret = devm_regulator_get_enable(dev, "vdd");
861 	if (ret)
862 		return dev_err_probe(dev, ret,
863 				     "Failed to get and enable regulator\n");
864 
865 	ret = bh1745_init(data);
866 	if (ret)
867 		return ret;
868 
869 	ret = bh1745_setup_triggered_buffer(indio_dev, indio_dev->dev.parent,
870 					    client->irq);
871 	if (ret)
872 		return ret;
873 
874 	ret = devm_iio_device_register(dev, indio_dev);
875 	if (ret)
876 		return dev_err_probe(dev, ret, "Failed to register device\n");
877 
878 	return 0;
879 }
880 
881 static const struct i2c_device_id bh1745_idtable[] = {
882 	{ "bh1745" },
883 	{ }
884 };
885 MODULE_DEVICE_TABLE(i2c, bh1745_idtable);
886 
887 static const struct of_device_id bh1745_of_match[] = {
888 	{ .compatible = "rohm,bh1745" },
889 	{ }
890 };
891 MODULE_DEVICE_TABLE(of, bh1745_of_match);
892 
893 static struct i2c_driver bh1745_driver = {
894 	.driver = {
895 		.name = "bh1745",
896 		.of_match_table = bh1745_of_match,
897 	},
898 	.probe = bh1745_probe,
899 	.id_table = bh1745_idtable,
900 };
901 module_i2c_driver(bh1745_driver);
902 
903 MODULE_LICENSE("GPL");
904 MODULE_AUTHOR("Mudit Sharma <muditsharma.info@gmail.com>");
905 MODULE_DESCRIPTION("BH1745 colour sensor driver");
906 MODULE_IMPORT_NS(IIO_GTS_HELPER);
907