brintos

brintos / linux-shallow public Read only

0
0
Text · 34.5 KiB · 66abda0 Raw
1363 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * si1145.c - Support for Silabs SI1132 and SI1141/2/3/5/6/7 combined ambient4 * light, UV index and proximity sensors5 *6 * Copyright 2014-16 Peter Meerwald-Stadler <pmeerw@pmeerw.net>7 * Copyright 2016 Crestez Dan Leonard <leonard.crestez@intel.com>8 *9 * SI1132 (7-bit I2C slave address 0x60)10 * SI1141/2/3 (7-bit I2C slave address 0x5a)11 * SI1145/6/6 (7-bit I2C slave address 0x60)12 */13 14#include <linux/module.h>15#include <linux/i2c.h>16#include <linux/err.h>17#include <linux/slab.h>18#include <linux/delay.h>19#include <linux/irq.h>20 21#include <linux/iio/iio.h>22#include <linux/iio/sysfs.h>23#include <linux/iio/trigger.h>24#include <linux/iio/trigger_consumer.h>25#include <linux/iio/triggered_buffer.h>26#include <linux/iio/buffer.h>27#include <linux/util_macros.h>28 29#define SI1145_REG_PART_ID		0x0030#define SI1145_REG_REV_ID		0x0131#define SI1145_REG_SEQ_ID		0x0232#define SI1145_REG_INT_CFG		0x0333#define SI1145_REG_IRQ_ENABLE		0x0434#define SI1145_REG_IRQ_MODE		0x0535#define SI1145_REG_HW_KEY		0x0736#define SI1145_REG_MEAS_RATE		0x0837#define SI1145_REG_PS_LED21		0x0f38#define SI1145_REG_PS_LED3		0x1039#define SI1145_REG_UCOEF1		0x1340#define SI1145_REG_UCOEF2		0x1441#define SI1145_REG_UCOEF3		0x1542#define SI1145_REG_UCOEF4		0x1643#define SI1145_REG_PARAM_WR		0x1744#define SI1145_REG_COMMAND		0x1845#define SI1145_REG_RESPONSE		0x2046#define SI1145_REG_IRQ_STATUS		0x2147#define SI1145_REG_ALSVIS_DATA		0x2248#define SI1145_REG_ALSIR_DATA		0x2449#define SI1145_REG_PS1_DATA		0x2650#define SI1145_REG_PS2_DATA		0x2851#define SI1145_REG_PS3_DATA		0x2a52#define SI1145_REG_AUX_DATA		0x2c53#define SI1145_REG_PARAM_RD		0x2e54#define SI1145_REG_CHIP_STAT		0x3055 56#define SI1145_UCOEF1_DEFAULT		0x7b57#define SI1145_UCOEF2_DEFAULT		0x6b58#define SI1145_UCOEF3_DEFAULT		0x0159#define SI1145_UCOEF4_DEFAULT		0x0060 61/* Helper to figure out PS_LED register / shift per channel */62#define SI1145_PS_LED_REG(ch) \63	(((ch) == 2) ? SI1145_REG_PS_LED3 : SI1145_REG_PS_LED21)64#define SI1145_PS_LED_SHIFT(ch) \65	(((ch) == 1) ? 4 : 0)66 67/* Parameter offsets */68#define SI1145_PARAM_CHLIST		0x0169#define SI1145_PARAM_PSLED12_SELECT	0x0270#define SI1145_PARAM_PSLED3_SELECT	0x0371#define SI1145_PARAM_PS_ENCODING	0x0572#define SI1145_PARAM_ALS_ENCODING	0x0673#define SI1145_PARAM_PS1_ADC_MUX	0x0774#define SI1145_PARAM_PS2_ADC_MUX	0x0875#define SI1145_PARAM_PS3_ADC_MUX	0x0976#define SI1145_PARAM_PS_ADC_COUNTER	0x0a77#define SI1145_PARAM_PS_ADC_GAIN	0x0b78#define SI1145_PARAM_PS_ADC_MISC	0x0c79#define SI1145_PARAM_ALS_ADC_MUX	0x0d80#define SI1145_PARAM_ALSIR_ADC_MUX	0x0e81#define SI1145_PARAM_AUX_ADC_MUX	0x0f82#define SI1145_PARAM_ALSVIS_ADC_COUNTER	0x1083#define SI1145_PARAM_ALSVIS_ADC_GAIN	0x1184#define SI1145_PARAM_ALSVIS_ADC_MISC	0x1285#define SI1145_PARAM_LED_RECOVERY	0x1c86#define SI1145_PARAM_ALSIR_ADC_COUNTER	0x1d87#define SI1145_PARAM_ALSIR_ADC_GAIN	0x1e88#define SI1145_PARAM_ALSIR_ADC_MISC	0x1f89#define SI1145_PARAM_ADC_OFFSET		0x1a90 91/* Channel enable masks for CHLIST parameter */92#define SI1145_CHLIST_EN_PS1		BIT(0)93#define SI1145_CHLIST_EN_PS2		BIT(1)94#define SI1145_CHLIST_EN_PS3		BIT(2)95#define SI1145_CHLIST_EN_ALSVIS		BIT(4)96#define SI1145_CHLIST_EN_ALSIR		BIT(5)97#define SI1145_CHLIST_EN_AUX		BIT(6)98#define SI1145_CHLIST_EN_UV		BIT(7)99 100/* Proximity measurement mode for ADC_MISC parameter */101#define SI1145_PS_ADC_MODE_NORMAL	BIT(2)102/* Signal range mask for ADC_MISC parameter */103#define SI1145_ADC_MISC_RANGE		BIT(5)104 105/* Commands for REG_COMMAND */106#define SI1145_CMD_NOP			0x00107#define SI1145_CMD_RESET		0x01108#define SI1145_CMD_PS_FORCE		0x05109#define SI1145_CMD_ALS_FORCE		0x06110#define SI1145_CMD_PSALS_FORCE		0x07111#define SI1145_CMD_PS_PAUSE		0x09112#define SI1145_CMD_ALS_PAUSE		0x0a113#define SI1145_CMD_PSALS_PAUSE		0x0b114#define SI1145_CMD_PS_AUTO		0x0d115#define SI1145_CMD_ALS_AUTO		0x0e116#define SI1145_CMD_PSALS_AUTO		0x0f117#define SI1145_CMD_PARAM_QUERY		0x80118#define SI1145_CMD_PARAM_SET		0xa0119 120#define SI1145_RSP_INVALID_SETTING	0x80121#define SI1145_RSP_COUNTER_MASK		0x0F122 123/* Minimum sleep after each command to ensure it's received */124#define SI1145_COMMAND_MINSLEEP_MS	5125/* Return -ETIMEDOUT after this long */126#define SI1145_COMMAND_TIMEOUT_MS	25127 128/* Interrupt configuration masks for INT_CFG register */129#define SI1145_INT_CFG_OE		BIT(0) /* enable interrupt */130#define SI1145_INT_CFG_MODE		BIT(1) /* auto reset interrupt pin */131 132/* Interrupt enable masks for IRQ_ENABLE register */133#define SI1145_MASK_ALL_IE		(BIT(4) | BIT(3) | BIT(2) | BIT(0))134 135#define SI1145_MUX_TEMP			0x65136#define SI1145_MUX_VDD			0x75137 138/* Proximity LED current; see Table 2 in datasheet */139#define SI1145_LED_CURRENT_45mA		0x04140 141enum {142	SI1132,143	SI1141,144	SI1142,145	SI1143,146	SI1145,147	SI1146,148	SI1147,149};150 151struct si1145_part_info {152	u8 part;153	const struct iio_info *iio_info;154	const struct iio_chan_spec *channels;155	unsigned int num_channels;156	unsigned int num_leds;157	bool uncompressed_meas_rate;158};159 160/**161 * struct si1145_data - si1145 chip state data162 * @client:	I2C client163 * @lock:	mutex to protect shared state.164 * @cmdlock:	Low-level mutex to protect command execution only165 * @rsp_seq:	Next expected response number or -1 if counter reset required166 * @scan_mask:	Saved scan mask to avoid duplicate set_chlist167 * @autonomous: If automatic measurements are active (for buffer support)168 * @part_info:	Part information169 * @trig:	Pointer to iio trigger170 * @meas_rate:	Value of MEAS_RATE register. Only set in HW in auto mode171 * @buffer:	Used to pack data read from sensor.172 */173struct si1145_data {174	struct i2c_client *client;175	struct mutex lock;176	struct mutex cmdlock;177	int rsp_seq;178	const struct si1145_part_info *part_info;179	unsigned long scan_mask;180	bool autonomous;181	struct iio_trigger *trig;182	int meas_rate;183	/*184	 * Ensure timestamp will be naturally aligned if present.185	 * Maximum buffer size (may be only partly used if not all186	 * channels are enabled):187	 *   6*2 bytes channels data + 4 bytes alignment +188	 *   8 bytes timestamp189	 */190	u8 buffer[24] __aligned(8);191};192 193/*194 * __si1145_command_reset() - Send CMD_NOP and wait for response 0195 *196 * Does not modify data->rsp_seq197 *198 * Return: 0 on success and -errno on error.199 */200static int __si1145_command_reset(struct si1145_data *data)201{202	struct device *dev = &data->client->dev;203	unsigned long stop_jiffies;204	int ret;205 206	ret = i2c_smbus_write_byte_data(data->client, SI1145_REG_COMMAND,207						      SI1145_CMD_NOP);208	if (ret < 0)209		return ret;210	msleep(SI1145_COMMAND_MINSLEEP_MS);211 212	stop_jiffies = jiffies + SI1145_COMMAND_TIMEOUT_MS * HZ / 1000;213	while (true) {214		ret = i2c_smbus_read_byte_data(data->client,215					       SI1145_REG_RESPONSE);216		if (ret <= 0)217			return ret;218		if (time_after(jiffies, stop_jiffies)) {219			dev_warn(dev, "timeout on reset\n");220			return -ETIMEDOUT;221		}222		msleep(SI1145_COMMAND_MINSLEEP_MS);223	}224}225 226/*227 * si1145_command() - Execute a command and poll the response register228 *229 * All conversion overflows are reported as -EOVERFLOW230 * INVALID_SETTING is reported as -EINVAL231 * Timeouts are reported as -ETIMEDOUT232 *233 * Return: 0 on success or -errno on failure234 */235static int si1145_command(struct si1145_data *data, u8 cmd)236{237	struct device *dev = &data->client->dev;238	unsigned long stop_jiffies;239	int ret;240 241	mutex_lock(&data->cmdlock);242 243	if (data->rsp_seq < 0) {244		ret = __si1145_command_reset(data);245		if (ret < 0) {246			dev_err(dev, "failed to reset command counter, ret=%d\n",247				ret);248			goto out;249		}250		data->rsp_seq = 0;251	}252 253	ret = i2c_smbus_write_byte_data(data->client, SI1145_REG_COMMAND, cmd);254	if (ret) {255		dev_warn(dev, "failed to write command, ret=%d\n", ret);256		goto out;257	}258	/* Sleep a little to ensure the command is received */259	msleep(SI1145_COMMAND_MINSLEEP_MS);260 261	stop_jiffies = jiffies + SI1145_COMMAND_TIMEOUT_MS * HZ / 1000;262	while (true) {263		ret = i2c_smbus_read_byte_data(data->client,264					       SI1145_REG_RESPONSE);265		if (ret < 0) {266			dev_warn(dev, "failed to read response, ret=%d\n", ret);267			break;268		}269 270		if ((ret & ~SI1145_RSP_COUNTER_MASK) == 0) {271			if (ret == data->rsp_seq) {272				if (time_after(jiffies, stop_jiffies)) {273					dev_warn(dev, "timeout on command 0x%02x\n",274						 cmd);275					ret = -ETIMEDOUT;276					break;277				}278				msleep(SI1145_COMMAND_MINSLEEP_MS);279				continue;280			}281			if (ret == ((data->rsp_seq + 1) &282				SI1145_RSP_COUNTER_MASK)) {283				data->rsp_seq = ret;284				ret = 0;285				break;286			}287			dev_warn(dev, "unexpected response counter %d instead of %d\n",288				 ret, (data->rsp_seq + 1) &289					SI1145_RSP_COUNTER_MASK);290			ret = -EIO;291		} else {292			if (ret == SI1145_RSP_INVALID_SETTING) {293				dev_warn(dev, "INVALID_SETTING error on command 0x%02x\n",294					 cmd);295				ret = -EINVAL;296			} else {297				/* All overflows are treated identically */298				dev_dbg(dev, "overflow, ret=%d, cmd=0x%02x\n",299					ret, cmd);300				ret = -EOVERFLOW;301			}302		}303 304		/* Force a counter reset next time */305		data->rsp_seq = -1;306		break;307	}308 309out:310	mutex_unlock(&data->cmdlock);311 312	return ret;313}314 315static int si1145_param_update(struct si1145_data *data, u8 op, u8 param,316			       u8 value)317{318	int ret;319 320	ret = i2c_smbus_write_byte_data(data->client,321		SI1145_REG_PARAM_WR, value);322	if (ret < 0)323		return ret;324 325	return si1145_command(data, op | (param & 0x1F));326}327 328static int si1145_param_set(struct si1145_data *data, u8 param, u8 value)329{330	return si1145_param_update(data, SI1145_CMD_PARAM_SET, param, value);331}332 333/* Set param. Returns negative errno or current value */334static int si1145_param_query(struct si1145_data *data, u8 param)335{336	int ret;337 338	ret = si1145_command(data, SI1145_CMD_PARAM_QUERY | (param & 0x1F));339	if (ret < 0)340		return ret;341 342	return i2c_smbus_read_byte_data(data->client, SI1145_REG_PARAM_RD);343}344 345/* Expand 8 bit compressed value to 16 bit, see Silabs AN498 */346static u16 si1145_uncompress(u8 x)347{348	u16 result = 0;349	u8 exponent = 0;350 351	if (x < 8)352		return 0;353 354	exponent = (x & 0xf0) >> 4;355	result = 0x10 | (x & 0x0f);356 357	if (exponent >= 4)358		return result << (exponent - 4);359	return result >> (4 - exponent);360}361 362/* Compress 16 bit value to 8 bit, see Silabs AN498 */363static u8 si1145_compress(u16 x)364{365	u32 exponent = 0;366	u32 significand = 0;367	u32 tmp = x;368 369	if (x == 0x0000)370		return 0x00;371	if (x == 0x0001)372		return 0x08;373 374	while (1) {375		tmp >>= 1;376		exponent += 1;377		if (tmp == 1)378			break;379	}380 381	if (exponent < 5) {382		significand = x << (4 - exponent);383		return (exponent << 4) | (significand & 0xF);384	}385 386	significand = x >> (exponent - 5);387	if (significand & 1) {388		significand += 2;389		if (significand & 0x0040) {390			exponent += 1;391			significand >>= 1;392		}393	}394 395	return (exponent << 4) | ((significand >> 1) & 0xF);396}397 398/* Write meas_rate in hardware */399static int si1145_set_meas_rate(struct si1145_data *data, int interval)400{401	if (data->part_info->uncompressed_meas_rate)402		return i2c_smbus_write_word_data(data->client,403			SI1145_REG_MEAS_RATE, interval);404	else405		return i2c_smbus_write_byte_data(data->client,406			SI1145_REG_MEAS_RATE, interval);407}408 409static int si1145_read_samp_freq(struct si1145_data *data, int *val, int *val2)410{411	*val = 32000;412	if (data->part_info->uncompressed_meas_rate)413		*val2 = data->meas_rate;414	else415		*val2 = si1145_uncompress(data->meas_rate);416	return IIO_VAL_FRACTIONAL;417}418 419/* Set the samp freq in driver private data */420static int si1145_store_samp_freq(struct si1145_data *data, int val)421{422	int ret = 0;423	int meas_rate;424 425	if (val <= 0 || val > 32000)426		return -ERANGE;427	meas_rate = 32000 / val;428 429	mutex_lock(&data->lock);430	if (data->autonomous) {431		ret = si1145_set_meas_rate(data, meas_rate);432		if (ret)433			goto out;434	}435	if (data->part_info->uncompressed_meas_rate)436		data->meas_rate = meas_rate;437	else438		data->meas_rate = si1145_compress(meas_rate);439 440out:441	mutex_unlock(&data->lock);442 443	return ret;444}445 446static irqreturn_t si1145_trigger_handler(int irq, void *private)447{448	struct iio_poll_func *pf = private;449	struct iio_dev *indio_dev = pf->indio_dev;450	struct si1145_data *data = iio_priv(indio_dev);451	int i, j = 0;452	int ret;453	u8 irq_status = 0;454 455	if (!data->autonomous) {456		ret = si1145_command(data, SI1145_CMD_PSALS_FORCE);457		if (ret < 0 && ret != -EOVERFLOW)458			goto done;459	} else {460		irq_status = ret = i2c_smbus_read_byte_data(data->client,461				SI1145_REG_IRQ_STATUS);462		if (ret < 0)463			goto done;464		if (!(irq_status & SI1145_MASK_ALL_IE))465			goto done;466	}467 468	iio_for_each_active_channel(indio_dev, i) {469		int run = 1;470 471		while (i + run < iio_get_masklength(indio_dev)) {472			if (!test_bit(i + run, indio_dev->active_scan_mask))473				break;474			if (indio_dev->channels[i + run].address !=475				indio_dev->channels[i].address + 2 * run)476				break;477			run++;478		}479 480		ret = i2c_smbus_read_i2c_block_data_or_emulated(481				data->client, indio_dev->channels[i].address,482				sizeof(u16) * run, &data->buffer[j]);483		if (ret < 0)484			goto done;485		j += run * sizeof(u16);486		i += run - 1;487	}488 489	if (data->autonomous) {490		ret = i2c_smbus_write_byte_data(data->client,491				SI1145_REG_IRQ_STATUS,492				irq_status & SI1145_MASK_ALL_IE);493		if (ret < 0)494			goto done;495	}496 497	iio_push_to_buffers_with_timestamp(indio_dev, data->buffer,498		iio_get_time_ns(indio_dev));499 500done:501	iio_trigger_notify_done(indio_dev->trig);502	return IRQ_HANDLED;503}504 505static int si1145_set_chlist(struct iio_dev *indio_dev, unsigned long scan_mask)506{507	struct si1145_data *data = iio_priv(indio_dev);508	u8 reg = 0, mux;509	int ret;510	int i;511 512	/* channel list already set, no need to reprogram */513	if (data->scan_mask == scan_mask)514		return 0;515 516	for_each_set_bit(i, &scan_mask, iio_get_masklength(indio_dev)) {517		switch (indio_dev->channels[i].address) {518		case SI1145_REG_ALSVIS_DATA:519			reg |= SI1145_CHLIST_EN_ALSVIS;520			break;521		case SI1145_REG_ALSIR_DATA:522			reg |= SI1145_CHLIST_EN_ALSIR;523			break;524		case SI1145_REG_PS1_DATA:525			reg |= SI1145_CHLIST_EN_PS1;526			break;527		case SI1145_REG_PS2_DATA:528			reg |= SI1145_CHLIST_EN_PS2;529			break;530		case SI1145_REG_PS3_DATA:531			reg |= SI1145_CHLIST_EN_PS3;532			break;533		case SI1145_REG_AUX_DATA:534			switch (indio_dev->channels[i].type) {535			case IIO_UVINDEX:536				reg |= SI1145_CHLIST_EN_UV;537				break;538			default:539				reg |= SI1145_CHLIST_EN_AUX;540				if (indio_dev->channels[i].type == IIO_TEMP)541					mux = SI1145_MUX_TEMP;542				else543					mux = SI1145_MUX_VDD;544				ret = si1145_param_set(data,545					SI1145_PARAM_AUX_ADC_MUX, mux);546				if (ret < 0)547					return ret;548 549				break;550			}551		}552	}553 554	data->scan_mask = scan_mask;555	ret = si1145_param_set(data, SI1145_PARAM_CHLIST, reg);556 557	return ret < 0 ? ret : 0;558}559 560static int si1145_measure(struct iio_dev *indio_dev,561			  struct iio_chan_spec const *chan)562{563	struct si1145_data *data = iio_priv(indio_dev);564	u8 cmd;565	int ret;566 567	ret = si1145_set_chlist(indio_dev, BIT(chan->scan_index));568	if (ret < 0)569		return ret;570 571	cmd = (chan->type == IIO_PROXIMITY) ? SI1145_CMD_PS_FORCE :572		SI1145_CMD_ALS_FORCE;573	ret = si1145_command(data, cmd);574	if (ret < 0 && ret != -EOVERFLOW)575		return ret;576 577	return i2c_smbus_read_word_data(data->client, chan->address);578}579 580/*581 * Conversion between iio scale and ADC_GAIN values582 * These could be further adjusted but proximity/intensity are dimensionless583 */584static const int si1145_proximity_scale_available[] = {585	128, 64, 32, 16, 8, 4};586static const int si1145_intensity_scale_available[] = {587	128, 64, 32, 16, 8, 4, 2, 1};588static IIO_CONST_ATTR(in_proximity_scale_available,589	"128 64 32 16 8 4");590static IIO_CONST_ATTR(in_intensity_scale_available,591	"128 64 32 16 8 4 2 1");592static IIO_CONST_ATTR(in_intensity_ir_scale_available,593	"128 64 32 16 8 4 2 1");594 595static int si1145_scale_from_adcgain(int regval)596{597	return 128 >> regval;598}599 600static int si1145_proximity_adcgain_from_scale(int val, int val2)601{602	val = find_closest_descending(val, si1145_proximity_scale_available,603				ARRAY_SIZE(si1145_proximity_scale_available));604	if (val < 0 || val > 5 || val2 != 0)605		return -EINVAL;606 607	return val;608}609 610static int si1145_intensity_adcgain_from_scale(int val, int val2)611{612	val = find_closest_descending(val, si1145_intensity_scale_available,613				ARRAY_SIZE(si1145_intensity_scale_available));614	if (val < 0 || val > 7 || val2 != 0)615		return -EINVAL;616 617	return val;618}619 620static int si1145_read_raw(struct iio_dev *indio_dev,621				struct iio_chan_spec const *chan,622				int *val, int *val2, long mask)623{624	struct si1145_data *data = iio_priv(indio_dev);625	int ret;626	u8 reg;627 628	switch (mask) {629	case IIO_CHAN_INFO_RAW:630		switch (chan->type) {631		case IIO_INTENSITY:632		case IIO_PROXIMITY:633		case IIO_VOLTAGE:634		case IIO_TEMP:635		case IIO_UVINDEX:636			ret = iio_device_claim_direct_mode(indio_dev);637			if (ret)638				return ret;639			ret = si1145_measure(indio_dev, chan);640			iio_device_release_direct_mode(indio_dev);641 642			if (ret < 0)643				return ret;644 645			*val = ret;646 647			return IIO_VAL_INT;648		case IIO_CURRENT:649			ret = i2c_smbus_read_byte_data(data->client,650				SI1145_PS_LED_REG(chan->channel));651			if (ret < 0)652				return ret;653 654			*val = (ret >> SI1145_PS_LED_SHIFT(chan->channel))655				& 0x0f;656 657			return IIO_VAL_INT;658		default:659			return -EINVAL;660		}661	case IIO_CHAN_INFO_SCALE:662		switch (chan->type) {663		case IIO_PROXIMITY:664			reg = SI1145_PARAM_PS_ADC_GAIN;665			break;666		case IIO_INTENSITY:667			if (chan->channel2 == IIO_MOD_LIGHT_IR)668				reg = SI1145_PARAM_ALSIR_ADC_GAIN;669			else670				reg = SI1145_PARAM_ALSVIS_ADC_GAIN;671			break;672		case IIO_TEMP:673			*val = 28;674			*val2 = 571429;675			return IIO_VAL_INT_PLUS_MICRO;676		case IIO_UVINDEX:677			*val = 0;678			*val2 = 10000;679			return IIO_VAL_INT_PLUS_MICRO;680		default:681			return -EINVAL;682		}683 684		ret = si1145_param_query(data, reg);685		if (ret < 0)686			return ret;687 688		*val = si1145_scale_from_adcgain(ret & 0x07);689 690		return IIO_VAL_INT;691	case IIO_CHAN_INFO_OFFSET:692		switch (chan->type) {693		case IIO_TEMP:694			/*695			 * -ADC offset - ADC counts @ 25°C -696			 *   35 * ADC counts / °C697			 */698			*val = -256 - 11136 + 25 * 35;699			return IIO_VAL_INT;700		default:701			/*702			 * All ADC measurements have are by default offset703			 * by -256704			 * See AN498 5.6.3705			 */706			ret = si1145_param_query(data, SI1145_PARAM_ADC_OFFSET);707			if (ret < 0)708				return ret;709			*val = -si1145_uncompress(ret);710			return IIO_VAL_INT;711		}712	case IIO_CHAN_INFO_SAMP_FREQ:713		return si1145_read_samp_freq(data, val, val2);714	default:715		return -EINVAL;716	}717}718 719static int si1145_write_raw(struct iio_dev *indio_dev,720			       struct iio_chan_spec const *chan,721			       int val, int val2, long mask)722{723	struct si1145_data *data = iio_priv(indio_dev);724	u8 reg1, reg2, shift;725	int ret;726 727	switch (mask) {728	case IIO_CHAN_INFO_SCALE:729		switch (chan->type) {730		case IIO_PROXIMITY:731			val = si1145_proximity_adcgain_from_scale(val, val2);732			if (val < 0)733				return val;734			reg1 = SI1145_PARAM_PS_ADC_GAIN;735			reg2 = SI1145_PARAM_PS_ADC_COUNTER;736			break;737		case IIO_INTENSITY:738			val = si1145_intensity_adcgain_from_scale(val, val2);739			if (val < 0)740				return val;741			if (chan->channel2 == IIO_MOD_LIGHT_IR) {742				reg1 = SI1145_PARAM_ALSIR_ADC_GAIN;743				reg2 = SI1145_PARAM_ALSIR_ADC_COUNTER;744			} else {745				reg1 = SI1145_PARAM_ALSVIS_ADC_GAIN;746				reg2 = SI1145_PARAM_ALSVIS_ADC_COUNTER;747			}748			break;749		default:750			return -EINVAL;751		}752 753		ret = iio_device_claim_direct_mode(indio_dev);754		if (ret)755			return ret;756 757		ret = si1145_param_set(data, reg1, val);758		if (ret < 0) {759			iio_device_release_direct_mode(indio_dev);760			return ret;761		}762		/* Set recovery period to one's complement of gain */763		ret = si1145_param_set(data, reg2, (~val & 0x07) << 4);764		iio_device_release_direct_mode(indio_dev);765		return ret;766	case IIO_CHAN_INFO_RAW:767		if (chan->type != IIO_CURRENT)768			return -EINVAL;769 770		if (val < 0 || val > 15 || val2 != 0)771			return -EINVAL;772 773		reg1 = SI1145_PS_LED_REG(chan->channel);774		shift = SI1145_PS_LED_SHIFT(chan->channel);775 776		ret = iio_device_claim_direct_mode(indio_dev);777		if (ret)778			return ret;779 780		ret = i2c_smbus_read_byte_data(data->client, reg1);781		if (ret < 0) {782			iio_device_release_direct_mode(indio_dev);783			return ret;784		}785		ret = i2c_smbus_write_byte_data(data->client, reg1,786			(ret & ~(0x0f << shift)) |787			((val & 0x0f) << shift));788		iio_device_release_direct_mode(indio_dev);789		return ret;790	case IIO_CHAN_INFO_SAMP_FREQ:791		return si1145_store_samp_freq(data, val);792	default:793		return -EINVAL;794	}795}796 797#define SI1145_ST { \798	.sign = 'u', \799	.realbits = 16, \800	.storagebits = 16, \801	.endianness = IIO_LE, \802}803 804#define SI1145_INTENSITY_CHANNEL(_si) { \805	.type = IIO_INTENSITY, \806	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \807			      BIT(IIO_CHAN_INFO_OFFSET) | \808			      BIT(IIO_CHAN_INFO_SCALE), \809	.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \810	.scan_type = SI1145_ST, \811	.scan_index = _si, \812	.address = SI1145_REG_ALSVIS_DATA, \813}814 815#define SI1145_INTENSITY_IR_CHANNEL(_si) { \816	.type = IIO_INTENSITY, \817	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \818			      BIT(IIO_CHAN_INFO_OFFSET) | \819			      BIT(IIO_CHAN_INFO_SCALE), \820	.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \821	.modified = 1, \822	.channel2 = IIO_MOD_LIGHT_IR, \823	.scan_type = SI1145_ST, \824	.scan_index = _si, \825	.address = SI1145_REG_ALSIR_DATA, \826}827 828#define SI1145_TEMP_CHANNEL(_si) { \829	.type = IIO_TEMP, \830	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \831			      BIT(IIO_CHAN_INFO_OFFSET) | \832			      BIT(IIO_CHAN_INFO_SCALE), \833	.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \834	.scan_type = SI1145_ST, \835	.scan_index = _si, \836	.address = SI1145_REG_AUX_DATA, \837}838 839#define SI1145_UV_CHANNEL(_si) { \840	.type = IIO_UVINDEX, \841	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \842			      BIT(IIO_CHAN_INFO_SCALE), \843	.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \844	.scan_type = SI1145_ST, \845	.scan_index = _si, \846	.address = SI1145_REG_AUX_DATA, \847}848 849#define SI1145_PROXIMITY_CHANNEL(_si, _ch) { \850	.type = IIO_PROXIMITY, \851	.indexed = 1, \852	.channel = _ch, \853	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \854	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \855				    BIT(IIO_CHAN_INFO_OFFSET), \856	.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \857	.scan_type = SI1145_ST, \858	.scan_index = _si, \859	.address = SI1145_REG_PS1_DATA + _ch * 2, \860}861 862#define SI1145_VOLTAGE_CHANNEL(_si) { \863	.type = IIO_VOLTAGE, \864	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \865	.info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SAMP_FREQ), \866	.scan_type = SI1145_ST, \867	.scan_index = _si, \868	.address = SI1145_REG_AUX_DATA, \869}870 871#define SI1145_CURRENT_CHANNEL(_ch) { \872	.type = IIO_CURRENT, \873	.indexed = 1, \874	.channel = _ch, \875	.output = 1, \876	.scan_index = -1, \877	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \878}879 880static const struct iio_chan_spec si1132_channels[] = {881	SI1145_INTENSITY_CHANNEL(0),882	SI1145_INTENSITY_IR_CHANNEL(1),883	SI1145_TEMP_CHANNEL(2),884	SI1145_VOLTAGE_CHANNEL(3),885	SI1145_UV_CHANNEL(4),886	IIO_CHAN_SOFT_TIMESTAMP(6),887};888 889static const struct iio_chan_spec si1141_channels[] = {890	SI1145_INTENSITY_CHANNEL(0),891	SI1145_INTENSITY_IR_CHANNEL(1),892	SI1145_PROXIMITY_CHANNEL(2, 0),893	SI1145_TEMP_CHANNEL(3),894	SI1145_VOLTAGE_CHANNEL(4),895	IIO_CHAN_SOFT_TIMESTAMP(5),896	SI1145_CURRENT_CHANNEL(0),897};898 899static const struct iio_chan_spec si1142_channels[] = {900	SI1145_INTENSITY_CHANNEL(0),901	SI1145_INTENSITY_IR_CHANNEL(1),902	SI1145_PROXIMITY_CHANNEL(2, 0),903	SI1145_PROXIMITY_CHANNEL(3, 1),904	SI1145_TEMP_CHANNEL(4),905	SI1145_VOLTAGE_CHANNEL(5),906	IIO_CHAN_SOFT_TIMESTAMP(6),907	SI1145_CURRENT_CHANNEL(0),908	SI1145_CURRENT_CHANNEL(1),909};910 911static const struct iio_chan_spec si1143_channels[] = {912	SI1145_INTENSITY_CHANNEL(0),913	SI1145_INTENSITY_IR_CHANNEL(1),914	SI1145_PROXIMITY_CHANNEL(2, 0),915	SI1145_PROXIMITY_CHANNEL(3, 1),916	SI1145_PROXIMITY_CHANNEL(4, 2),917	SI1145_TEMP_CHANNEL(5),918	SI1145_VOLTAGE_CHANNEL(6),919	IIO_CHAN_SOFT_TIMESTAMP(7),920	SI1145_CURRENT_CHANNEL(0),921	SI1145_CURRENT_CHANNEL(1),922	SI1145_CURRENT_CHANNEL(2),923};924 925static const struct iio_chan_spec si1145_channels[] = {926	SI1145_INTENSITY_CHANNEL(0),927	SI1145_INTENSITY_IR_CHANNEL(1),928	SI1145_PROXIMITY_CHANNEL(2, 0),929	SI1145_TEMP_CHANNEL(3),930	SI1145_VOLTAGE_CHANNEL(4),931	SI1145_UV_CHANNEL(5),932	IIO_CHAN_SOFT_TIMESTAMP(6),933	SI1145_CURRENT_CHANNEL(0),934};935 936static const struct iio_chan_spec si1146_channels[] = {937	SI1145_INTENSITY_CHANNEL(0),938	SI1145_INTENSITY_IR_CHANNEL(1),939	SI1145_TEMP_CHANNEL(2),940	SI1145_VOLTAGE_CHANNEL(3),941	SI1145_UV_CHANNEL(4),942	SI1145_PROXIMITY_CHANNEL(5, 0),943	SI1145_PROXIMITY_CHANNEL(6, 1),944	IIO_CHAN_SOFT_TIMESTAMP(7),945	SI1145_CURRENT_CHANNEL(0),946	SI1145_CURRENT_CHANNEL(1),947};948 949static const struct iio_chan_spec si1147_channels[] = {950	SI1145_INTENSITY_CHANNEL(0),951	SI1145_INTENSITY_IR_CHANNEL(1),952	SI1145_PROXIMITY_CHANNEL(2, 0),953	SI1145_PROXIMITY_CHANNEL(3, 1),954	SI1145_PROXIMITY_CHANNEL(4, 2),955	SI1145_TEMP_CHANNEL(5),956	SI1145_VOLTAGE_CHANNEL(6),957	SI1145_UV_CHANNEL(7),958	IIO_CHAN_SOFT_TIMESTAMP(8),959	SI1145_CURRENT_CHANNEL(0),960	SI1145_CURRENT_CHANNEL(1),961	SI1145_CURRENT_CHANNEL(2),962};963 964static struct attribute *si1132_attributes[] = {965	&iio_const_attr_in_intensity_scale_available.dev_attr.attr,966	&iio_const_attr_in_intensity_ir_scale_available.dev_attr.attr,967	NULL,968};969 970static struct attribute *si114x_attributes[] = {971	&iio_const_attr_in_intensity_scale_available.dev_attr.attr,972	&iio_const_attr_in_intensity_ir_scale_available.dev_attr.attr,973	&iio_const_attr_in_proximity_scale_available.dev_attr.attr,974	NULL,975};976 977static const struct attribute_group si1132_attribute_group = {978	.attrs = si1132_attributes,979};980 981static const struct attribute_group si114x_attribute_group = {982	.attrs = si114x_attributes,983};984 985 986static const struct iio_info si1132_info = {987	.read_raw = si1145_read_raw,988	.write_raw = si1145_write_raw,989	.attrs = &si1132_attribute_group,990};991 992static const struct iio_info si114x_info = {993	.read_raw = si1145_read_raw,994	.write_raw = si1145_write_raw,995	.attrs = &si114x_attribute_group,996};997 998#define SI1145_PART(id, iio_info, chans, leds, uncompressed_meas_rate) \999	{id, iio_info, chans, ARRAY_SIZE(chans), leds, uncompressed_meas_rate}1000 1001static const struct si1145_part_info si1145_part_info[] = {1002	[SI1132] = SI1145_PART(0x32, &si1132_info, si1132_channels, 0, true),1003	[SI1141] = SI1145_PART(0x41, &si114x_info, si1141_channels, 1, false),1004	[SI1142] = SI1145_PART(0x42, &si114x_info, si1142_channels, 2, false),1005	[SI1143] = SI1145_PART(0x43, &si114x_info, si1143_channels, 3, false),1006	[SI1145] = SI1145_PART(0x45, &si114x_info, si1145_channels, 1, true),1007	[SI1146] = SI1145_PART(0x46, &si114x_info, si1146_channels, 2, true),1008	[SI1147] = SI1145_PART(0x47, &si114x_info, si1147_channels, 3, true),1009};1010 1011static int si1145_initialize(struct si1145_data *data)1012{1013	struct i2c_client *client = data->client;1014	int ret;1015 1016	ret = i2c_smbus_write_byte_data(client, SI1145_REG_COMMAND,1017					SI1145_CMD_RESET);1018	if (ret < 0)1019		return ret;1020	msleep(SI1145_COMMAND_TIMEOUT_MS);1021 1022	/* Hardware key, magic value */1023	ret = i2c_smbus_write_byte_data(client, SI1145_REG_HW_KEY, 0x17);1024	if (ret < 0)1025		return ret;1026	msleep(SI1145_COMMAND_TIMEOUT_MS);1027 1028	/* Turn off autonomous mode */1029	ret = si1145_set_meas_rate(data, 0);1030	if (ret < 0)1031		return ret;1032 1033	/* Initialize sampling freq to 10 Hz */1034	ret = si1145_store_samp_freq(data, 10);1035	if (ret < 0)1036		return ret;1037 1038	/* Set LED currents to 45 mA; have 4 bits, see Table 2 in datasheet */1039	switch (data->part_info->num_leds) {1040	case 3:1041		ret = i2c_smbus_write_byte_data(client,1042						SI1145_REG_PS_LED3,1043						SI1145_LED_CURRENT_45mA);1044		if (ret < 0)1045			return ret;1046		fallthrough;1047	case 2:1048		ret = i2c_smbus_write_byte_data(client,1049						SI1145_REG_PS_LED21,1050						(SI1145_LED_CURRENT_45mA << 4) |1051						SI1145_LED_CURRENT_45mA);1052		break;1053	case 1:1054		ret = i2c_smbus_write_byte_data(client,1055						SI1145_REG_PS_LED21,1056						SI1145_LED_CURRENT_45mA);1057		break;1058	default:1059		ret = 0;1060		break;1061	}1062	if (ret < 0)1063		return ret;1064 1065	/* Set normal proximity measurement mode */1066	ret = si1145_param_set(data, SI1145_PARAM_PS_ADC_MISC,1067			       SI1145_PS_ADC_MODE_NORMAL);1068	if (ret < 0)1069		return ret;1070 1071	ret = si1145_param_set(data, SI1145_PARAM_PS_ADC_GAIN, 0x01);1072	if (ret < 0)1073		return ret;1074 1075	/* ADC_COUNTER should be one complement of ADC_GAIN */1076	ret = si1145_param_set(data, SI1145_PARAM_PS_ADC_COUNTER, 0x06 << 4);1077	if (ret < 0)1078		return ret;1079 1080	/* Set ALS visible measurement mode */1081	ret = si1145_param_set(data, SI1145_PARAM_ALSVIS_ADC_MISC,1082			       SI1145_ADC_MISC_RANGE);1083	if (ret < 0)1084		return ret;1085 1086	ret = si1145_param_set(data, SI1145_PARAM_ALSVIS_ADC_GAIN, 0x03);1087	if (ret < 0)1088		return ret;1089 1090	ret = si1145_param_set(data, SI1145_PARAM_ALSVIS_ADC_COUNTER,1091			       0x04 << 4);1092	if (ret < 0)1093		return ret;1094 1095	/* Set ALS IR measurement mode */1096	ret = si1145_param_set(data, SI1145_PARAM_ALSIR_ADC_MISC,1097			       SI1145_ADC_MISC_RANGE);1098	if (ret < 0)1099		return ret;1100 1101	ret = si1145_param_set(data, SI1145_PARAM_ALSIR_ADC_GAIN, 0x01);1102	if (ret < 0)1103		return ret;1104 1105	ret = si1145_param_set(data, SI1145_PARAM_ALSIR_ADC_COUNTER,1106			       0x06 << 4);1107	if (ret < 0)1108		return ret;1109 1110	/*1111	 * Initialize UCOEF to default values in datasheet1112	 * These registers are normally zero on reset1113	 */1114	if (data->part_info == &si1145_part_info[SI1132] ||1115		data->part_info == &si1145_part_info[SI1145] ||1116		data->part_info == &si1145_part_info[SI1146] ||1117		data->part_info == &si1145_part_info[SI1147]) {1118		ret = i2c_smbus_write_byte_data(data->client,1119						SI1145_REG_UCOEF1,1120						SI1145_UCOEF1_DEFAULT);1121		if (ret < 0)1122			return ret;1123		ret = i2c_smbus_write_byte_data(data->client,1124				SI1145_REG_UCOEF2, SI1145_UCOEF2_DEFAULT);1125		if (ret < 0)1126			return ret;1127		ret = i2c_smbus_write_byte_data(data->client,1128				SI1145_REG_UCOEF3, SI1145_UCOEF3_DEFAULT);1129		if (ret < 0)1130			return ret;1131		ret = i2c_smbus_write_byte_data(data->client,1132				SI1145_REG_UCOEF4, SI1145_UCOEF4_DEFAULT);1133		if (ret < 0)1134			return ret;1135	}1136 1137	return 0;1138}1139 1140/*1141 * Program the channels we want to measure with CMD_PSALS_AUTO. No need for1142 * _postdisable as we stop with CMD_PSALS_PAUSE; single measurement (direct)1143 * mode reprograms the channels list anyway...1144 */1145static int si1145_buffer_preenable(struct iio_dev *indio_dev)1146{1147	struct si1145_data *data = iio_priv(indio_dev);1148	int ret;1149 1150	mutex_lock(&data->lock);1151	ret = si1145_set_chlist(indio_dev, *indio_dev->active_scan_mask);1152	mutex_unlock(&data->lock);1153 1154	return ret;1155}1156 1157static bool si1145_validate_scan_mask(struct iio_dev *indio_dev,1158			       const unsigned long *scan_mask)1159{1160	struct si1145_data *data = iio_priv(indio_dev);1161	unsigned int count = 0;1162	int i;1163 1164	/* Check that at most one AUX channel is enabled */1165	for_each_set_bit(i, scan_mask, data->part_info->num_channels) {1166		if (indio_dev->channels[i].address == SI1145_REG_AUX_DATA)1167			count++;1168	}1169 1170	return count <= 1;1171}1172 1173static const struct iio_buffer_setup_ops si1145_buffer_setup_ops = {1174	.preenable = si1145_buffer_preenable,1175	.validate_scan_mask = si1145_validate_scan_mask,1176};1177 1178/*1179 * si1145_trigger_set_state() - Set trigger state1180 *1181 * When not using triggers interrupts are disabled and measurement rate is1182 * set to zero in order to minimize power consumption.1183 */1184static int si1145_trigger_set_state(struct iio_trigger *trig, bool state)1185{1186	struct iio_dev *indio_dev = iio_trigger_get_drvdata(trig);1187	struct si1145_data *data = iio_priv(indio_dev);1188	int err = 0, ret;1189 1190	mutex_lock(&data->lock);1191 1192	if (state) {1193		data->autonomous = true;1194		err = i2c_smbus_write_byte_data(data->client,1195				SI1145_REG_INT_CFG, SI1145_INT_CFG_OE);1196		if (err < 0)1197			goto disable;1198		err = i2c_smbus_write_byte_data(data->client,1199				SI1145_REG_IRQ_ENABLE, SI1145_MASK_ALL_IE);1200		if (err < 0)1201			goto disable;1202		err = si1145_set_meas_rate(data, data->meas_rate);1203		if (err < 0)1204			goto disable;1205		err = si1145_command(data, SI1145_CMD_PSALS_AUTO);1206		if (err < 0)1207			goto disable;1208	} else {1209disable:1210		/* Disable as much as possible skipping errors */1211		ret = si1145_command(data, SI1145_CMD_PSALS_PAUSE);1212		if (ret < 0 && !err)1213			err = ret;1214		ret = si1145_set_meas_rate(data, 0);1215		if (ret < 0 && !err)1216			err = ret;1217		ret = i2c_smbus_write_byte_data(data->client,1218						SI1145_REG_IRQ_ENABLE, 0);1219		if (ret < 0 && !err)1220			err = ret;1221		ret = i2c_smbus_write_byte_data(data->client,1222						SI1145_REG_INT_CFG, 0);1223		if (ret < 0 && !err)1224			err = ret;1225		data->autonomous = false;1226	}1227 1228	mutex_unlock(&data->lock);1229	return err;1230}1231 1232static const struct iio_trigger_ops si1145_trigger_ops = {1233	.set_trigger_state = si1145_trigger_set_state,1234};1235 1236static int si1145_probe_trigger(struct iio_dev *indio_dev)1237{1238	struct si1145_data *data = iio_priv(indio_dev);1239	struct i2c_client *client = data->client;1240	struct iio_trigger *trig;1241	int ret;1242 1243	trig = devm_iio_trigger_alloc(&client->dev,1244			"%s-dev%d", indio_dev->name, iio_device_id(indio_dev));1245	if (!trig)1246		return -ENOMEM;1247 1248	trig->ops = &si1145_trigger_ops;1249	iio_trigger_set_drvdata(trig, indio_dev);1250 1251	ret = devm_request_irq(&client->dev, client->irq,1252			  iio_trigger_generic_data_rdy_poll,1253			  IRQF_TRIGGER_FALLING,1254			  "si1145_irq",1255			  trig);1256	if (ret < 0) {1257		dev_err(&client->dev, "irq request failed\n");1258		return ret;1259	}1260 1261	ret = devm_iio_trigger_register(&client->dev, trig);1262	if (ret)1263		return ret;1264 1265	data->trig = trig;1266	indio_dev->trig = iio_trigger_get(data->trig);1267 1268	return 0;1269}1270 1271static int si1145_probe(struct i2c_client *client)1272{1273	const struct i2c_device_id *id = i2c_client_get_device_id(client);1274	struct si1145_data *data;1275	struct iio_dev *indio_dev;1276	u8 part_id, rev_id, seq_id;1277	int ret;1278 1279	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));1280	if (!indio_dev)1281		return -ENOMEM;1282 1283	data = iio_priv(indio_dev);1284	i2c_set_clientdata(client, indio_dev);1285	data->client = client;1286	data->part_info = &si1145_part_info[id->driver_data];1287 1288	part_id = ret = i2c_smbus_read_byte_data(data->client,1289						 SI1145_REG_PART_ID);1290	if (ret < 0)1291		return ret;1292	rev_id = ret = i2c_smbus_read_byte_data(data->client,1293						SI1145_REG_REV_ID);1294	if (ret < 0)1295		return ret;1296	seq_id = ret = i2c_smbus_read_byte_data(data->client,1297						SI1145_REG_SEQ_ID);1298	if (ret < 0)1299		return ret;1300	dev_info(&client->dev, "device ID part 0x%02x rev 0x%02x seq 0x%02x\n",1301			part_id, rev_id, seq_id);1302	if (part_id != data->part_info->part) {1303		dev_err(&client->dev, "part ID mismatch got 0x%02x, expected 0x%02x\n",1304				part_id, data->part_info->part);1305		return -ENODEV;1306	}1307 1308	indio_dev->name = id->name;1309	indio_dev->channels = data->part_info->channels;1310	indio_dev->num_channels = data->part_info->num_channels;1311	indio_dev->info = data->part_info->iio_info;1312	indio_dev->modes = INDIO_DIRECT_MODE;1313 1314	mutex_init(&data->lock);1315	mutex_init(&data->cmdlock);1316 1317	ret = si1145_initialize(data);1318	if (ret < 0)1319		return ret;1320 1321	ret = devm_iio_triggered_buffer_setup(&client->dev,1322		indio_dev, NULL,1323		si1145_trigger_handler, &si1145_buffer_setup_ops);1324	if (ret < 0)1325		return ret;1326 1327	if (client->irq) {1328		ret = si1145_probe_trigger(indio_dev);1329		if (ret < 0)1330			return ret;1331	} else {1332		dev_info(&client->dev, "no irq, using polling\n");1333	}1334 1335	return devm_iio_device_register(&client->dev, indio_dev);1336}1337 1338static const struct i2c_device_id si1145_ids[] = {1339	{ "si1132", SI1132 },1340	{ "si1141", SI1141 },1341	{ "si1142", SI1142 },1342	{ "si1143", SI1143 },1343	{ "si1145", SI1145 },1344	{ "si1146", SI1146 },1345	{ "si1147", SI1147 },1346	{ }1347};1348MODULE_DEVICE_TABLE(i2c, si1145_ids);1349 1350static struct i2c_driver si1145_driver = {1351	.driver = {1352		.name   = "si1145",1353	},1354	.probe = si1145_probe,1355	.id_table = si1145_ids,1356};1357 1358module_i2c_driver(si1145_driver);1359 1360MODULE_AUTHOR("Peter Meerwald-Stadler <pmeerw@pmeerw.net>");1361MODULE_DESCRIPTION("Silabs SI1132 and SI1141/2/3/5/6/7 proximity, ambient light and UV index sensor driver");1362MODULE_LICENSE("GPL");1363