brintos

brintos / linux-shallow public Read only

0
0
Text · 22.1 KiB · 2e458e9 Raw
907 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * ROHM BH1745 digital colour sensor driver4 *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 0x4031#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 0x0B35 36/* Mode control 1 */37#define BH1745_MODE_CTRL1 0x4138#define BH1745_CTRL1_MEASUREMENT_TIME_MASK GENMASK(2, 0)39 40/* Mode control 2 */41#define BH1745_MODE_CTRL2 0x4242#define BH1745_CTRL2_RGBC_EN BIT(4)43#define BH1745_CTRL2_ADC_GAIN_MASK GENMASK(1, 0)44 45/* Interrupt */46#define BH1745_INTR 0x6047#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 0x6152 53/* Threshold high */54#define BH1745_TH_LSB 0x6255#define BH1745_TH_MSB 0x6356 57/* Threshold low */58#define BH1745_TL_LSB 0x6459#define BH1745_TL_MSB 0x6560 61/* BH1745 data output regs */62#define BH1745_RED_LSB 0x5063#define BH1745_RED_MSB 0x5164#define BH1745_GREEN_LSB 0x5265#define BH1745_GREEN_MSB 0x5366#define BH1745_BLUE_LSB 0x5467#define BH1745_BLUE_MSB 0x5568#define BH1745_CLEAR_LSB 0x5669#define BH1745_CLEAR_MSB 0x5770 71#define BH1745_MANU_ID_REG 0x9272 73/* From 16x max HW gain and 32x max integration time */74#define BH1745_MAX_GAIN 51275 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 before123	 * related calculations are completed124	 */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		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 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, 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 683static 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 701static 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 712static 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 739static 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 765err:766	iio_trigger_notify_done(indio_dev->trig);767 768	return IRQ_HANDLED;769}770 771static 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 798static 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 827static 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 881static const struct i2c_device_id bh1745_idtable[] = {882	{ "bh1745" },883	{ }884};885MODULE_DEVICE_TABLE(i2c, bh1745_idtable);886 887static const struct of_device_id bh1745_of_match[] = {888	{ .compatible = "rohm,bh1745" },889	{ }890};891MODULE_DEVICE_TABLE(of, bh1745_of_match);892 893static 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};901module_i2c_driver(bh1745_driver);902 903MODULE_LICENSE("GPL");904MODULE_AUTHOR("Mudit Sharma <muditsharma.info@gmail.com>");905MODULE_DESCRIPTION("BH1745 colour sensor driver");906MODULE_IMPORT_NS(IIO_GTS_HELPER);907