xref: /OK3568_Linux_fs/kernel/drivers/iio/light/isl29125.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-only
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * isl29125.c - Support for Intersil ISL29125 RGB light sensor
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (c) 2014 Peter Meerwald <pmeerw@pmeerw.net>
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  * RGB light sensor with 16-bit channels for red, green, blue);
8*4882a593Smuzhiyun  * 7-bit I2C slave address 0x44
9*4882a593Smuzhiyun  *
10*4882a593Smuzhiyun  * TODO: interrupt support, IR compensation, thresholds, 12bit
11*4882a593Smuzhiyun  */
12*4882a593Smuzhiyun 
13*4882a593Smuzhiyun #include <linux/module.h>
14*4882a593Smuzhiyun #include <linux/i2c.h>
15*4882a593Smuzhiyun #include <linux/delay.h>
16*4882a593Smuzhiyun #include <linux/pm.h>
17*4882a593Smuzhiyun 
18*4882a593Smuzhiyun #include <linux/iio/iio.h>
19*4882a593Smuzhiyun #include <linux/iio/sysfs.h>
20*4882a593Smuzhiyun #include <linux/iio/trigger_consumer.h>
21*4882a593Smuzhiyun #include <linux/iio/buffer.h>
22*4882a593Smuzhiyun #include <linux/iio/triggered_buffer.h>
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun #define ISL29125_DRV_NAME "isl29125"
25*4882a593Smuzhiyun 
26*4882a593Smuzhiyun #define ISL29125_DEVICE_ID 0x00
27*4882a593Smuzhiyun #define ISL29125_CONF1 0x01
28*4882a593Smuzhiyun #define ISL29125_CONF2 0x02
29*4882a593Smuzhiyun #define ISL29125_CONF3 0x03
30*4882a593Smuzhiyun #define ISL29125_STATUS 0x08
31*4882a593Smuzhiyun #define ISL29125_GREEN_DATA 0x09
32*4882a593Smuzhiyun #define ISL29125_RED_DATA 0x0b
33*4882a593Smuzhiyun #define ISL29125_BLUE_DATA 0x0d
34*4882a593Smuzhiyun 
35*4882a593Smuzhiyun #define ISL29125_ID 0x7d
36*4882a593Smuzhiyun 
37*4882a593Smuzhiyun #define ISL29125_MODE_MASK GENMASK(2, 0)
38*4882a593Smuzhiyun #define ISL29125_MODE_PD 0x0
39*4882a593Smuzhiyun #define ISL29125_MODE_G 0x1
40*4882a593Smuzhiyun #define ISL29125_MODE_R 0x2
41*4882a593Smuzhiyun #define ISL29125_MODE_B 0x3
42*4882a593Smuzhiyun #define ISL29125_MODE_RGB 0x5
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun #define ISL29125_SENSING_RANGE_0 5722   /* 375 lux full range */
45*4882a593Smuzhiyun #define ISL29125_SENSING_RANGE_1 152590 /* 10k lux full range */
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun #define ISL29125_MODE_RANGE BIT(3)
48*4882a593Smuzhiyun 
49*4882a593Smuzhiyun #define ISL29125_STATUS_CONV BIT(1)
50*4882a593Smuzhiyun 
51*4882a593Smuzhiyun struct isl29125_data {
52*4882a593Smuzhiyun 	struct i2c_client *client;
53*4882a593Smuzhiyun 	u8 conf1;
54*4882a593Smuzhiyun 	/* Ensure timestamp is naturally aligned */
55*4882a593Smuzhiyun 	struct {
56*4882a593Smuzhiyun 		u16 chans[3];
57*4882a593Smuzhiyun 		s64 timestamp __aligned(8);
58*4882a593Smuzhiyun 	} scan;
59*4882a593Smuzhiyun };
60*4882a593Smuzhiyun 
61*4882a593Smuzhiyun #define ISL29125_CHANNEL(_color, _si) { \
62*4882a593Smuzhiyun 	.type = IIO_INTENSITY, \
63*4882a593Smuzhiyun 	.modified = 1, \
64*4882a593Smuzhiyun 	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
65*4882a593Smuzhiyun 	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE), \
66*4882a593Smuzhiyun 	.channel2 = IIO_MOD_LIGHT_##_color, \
67*4882a593Smuzhiyun 	.scan_index = _si, \
68*4882a593Smuzhiyun 	.scan_type = { \
69*4882a593Smuzhiyun 		.sign = 'u', \
70*4882a593Smuzhiyun 		.realbits = 16, \
71*4882a593Smuzhiyun 		.storagebits = 16, \
72*4882a593Smuzhiyun 		.endianness = IIO_CPU, \
73*4882a593Smuzhiyun 	}, \
74*4882a593Smuzhiyun }
75*4882a593Smuzhiyun 
76*4882a593Smuzhiyun static const struct iio_chan_spec isl29125_channels[] = {
77*4882a593Smuzhiyun 	ISL29125_CHANNEL(GREEN, 0),
78*4882a593Smuzhiyun 	ISL29125_CHANNEL(RED, 1),
79*4882a593Smuzhiyun 	ISL29125_CHANNEL(BLUE, 2),
80*4882a593Smuzhiyun 	IIO_CHAN_SOFT_TIMESTAMP(3),
81*4882a593Smuzhiyun };
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun static const struct {
84*4882a593Smuzhiyun 	u8 mode, data;
85*4882a593Smuzhiyun } isl29125_regs[] = {
86*4882a593Smuzhiyun 	{ISL29125_MODE_G, ISL29125_GREEN_DATA},
87*4882a593Smuzhiyun 	{ISL29125_MODE_R, ISL29125_RED_DATA},
88*4882a593Smuzhiyun 	{ISL29125_MODE_B, ISL29125_BLUE_DATA},
89*4882a593Smuzhiyun };
90*4882a593Smuzhiyun 
isl29125_read_data(struct isl29125_data * data,int si)91*4882a593Smuzhiyun static int isl29125_read_data(struct isl29125_data *data, int si)
92*4882a593Smuzhiyun {
93*4882a593Smuzhiyun 	int tries = 5;
94*4882a593Smuzhiyun 	int ret;
95*4882a593Smuzhiyun 
96*4882a593Smuzhiyun 	ret = i2c_smbus_write_byte_data(data->client, ISL29125_CONF1,
97*4882a593Smuzhiyun 		data->conf1 | isl29125_regs[si].mode);
98*4882a593Smuzhiyun 	if (ret < 0)
99*4882a593Smuzhiyun 		return ret;
100*4882a593Smuzhiyun 
101*4882a593Smuzhiyun 	msleep(101);
102*4882a593Smuzhiyun 
103*4882a593Smuzhiyun 	while (tries--) {
104*4882a593Smuzhiyun 		ret = i2c_smbus_read_byte_data(data->client, ISL29125_STATUS);
105*4882a593Smuzhiyun 		if (ret < 0)
106*4882a593Smuzhiyun 			goto fail;
107*4882a593Smuzhiyun 		if (ret & ISL29125_STATUS_CONV)
108*4882a593Smuzhiyun 			break;
109*4882a593Smuzhiyun 		msleep(20);
110*4882a593Smuzhiyun 	}
111*4882a593Smuzhiyun 
112*4882a593Smuzhiyun 	if (tries < 0) {
113*4882a593Smuzhiyun 		dev_err(&data->client->dev, "data not ready\n");
114*4882a593Smuzhiyun 		ret = -EIO;
115*4882a593Smuzhiyun 		goto fail;
116*4882a593Smuzhiyun 	}
117*4882a593Smuzhiyun 
118*4882a593Smuzhiyun 	ret = i2c_smbus_read_word_data(data->client, isl29125_regs[si].data);
119*4882a593Smuzhiyun 
120*4882a593Smuzhiyun fail:
121*4882a593Smuzhiyun 	i2c_smbus_write_byte_data(data->client, ISL29125_CONF1, data->conf1);
122*4882a593Smuzhiyun 	return ret;
123*4882a593Smuzhiyun }
124*4882a593Smuzhiyun 
isl29125_read_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int * val,int * val2,long mask)125*4882a593Smuzhiyun static int isl29125_read_raw(struct iio_dev *indio_dev,
126*4882a593Smuzhiyun 			   struct iio_chan_spec const *chan,
127*4882a593Smuzhiyun 			   int *val, int *val2, long mask)
128*4882a593Smuzhiyun {
129*4882a593Smuzhiyun 	struct isl29125_data *data = iio_priv(indio_dev);
130*4882a593Smuzhiyun 	int ret;
131*4882a593Smuzhiyun 
132*4882a593Smuzhiyun 	switch (mask) {
133*4882a593Smuzhiyun 	case IIO_CHAN_INFO_RAW:
134*4882a593Smuzhiyun 		ret = iio_device_claim_direct_mode(indio_dev);
135*4882a593Smuzhiyun 		if (ret)
136*4882a593Smuzhiyun 			return ret;
137*4882a593Smuzhiyun 		ret = isl29125_read_data(data, chan->scan_index);
138*4882a593Smuzhiyun 		iio_device_release_direct_mode(indio_dev);
139*4882a593Smuzhiyun 		if (ret < 0)
140*4882a593Smuzhiyun 			return ret;
141*4882a593Smuzhiyun 		*val = ret;
142*4882a593Smuzhiyun 		return IIO_VAL_INT;
143*4882a593Smuzhiyun 	case IIO_CHAN_INFO_SCALE:
144*4882a593Smuzhiyun 		*val = 0;
145*4882a593Smuzhiyun 		if (data->conf1 & ISL29125_MODE_RANGE)
146*4882a593Smuzhiyun 			*val2 = ISL29125_SENSING_RANGE_1; /*10k lux full range*/
147*4882a593Smuzhiyun 		else
148*4882a593Smuzhiyun 			*val2 = ISL29125_SENSING_RANGE_0; /*375 lux full range*/
149*4882a593Smuzhiyun 		return IIO_VAL_INT_PLUS_MICRO;
150*4882a593Smuzhiyun 	}
151*4882a593Smuzhiyun 	return -EINVAL;
152*4882a593Smuzhiyun }
153*4882a593Smuzhiyun 
isl29125_write_raw(struct iio_dev * indio_dev,struct iio_chan_spec const * chan,int val,int val2,long mask)154*4882a593Smuzhiyun static int isl29125_write_raw(struct iio_dev *indio_dev,
155*4882a593Smuzhiyun 			       struct iio_chan_spec const *chan,
156*4882a593Smuzhiyun 			       int val, int val2, long mask)
157*4882a593Smuzhiyun {
158*4882a593Smuzhiyun 	struct isl29125_data *data = iio_priv(indio_dev);
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun 	switch (mask) {
161*4882a593Smuzhiyun 	case IIO_CHAN_INFO_SCALE:
162*4882a593Smuzhiyun 		if (val != 0)
163*4882a593Smuzhiyun 			return -EINVAL;
164*4882a593Smuzhiyun 		if (val2 == ISL29125_SENSING_RANGE_1)
165*4882a593Smuzhiyun 			data->conf1 |= ISL29125_MODE_RANGE;
166*4882a593Smuzhiyun 		else if (val2 == ISL29125_SENSING_RANGE_0)
167*4882a593Smuzhiyun 			data->conf1 &= ~ISL29125_MODE_RANGE;
168*4882a593Smuzhiyun 		else
169*4882a593Smuzhiyun 			return -EINVAL;
170*4882a593Smuzhiyun 		return i2c_smbus_write_byte_data(data->client, ISL29125_CONF1,
171*4882a593Smuzhiyun 			data->conf1);
172*4882a593Smuzhiyun 	default:
173*4882a593Smuzhiyun 		return -EINVAL;
174*4882a593Smuzhiyun 	}
175*4882a593Smuzhiyun }
176*4882a593Smuzhiyun 
isl29125_trigger_handler(int irq,void * p)177*4882a593Smuzhiyun static irqreturn_t isl29125_trigger_handler(int irq, void *p)
178*4882a593Smuzhiyun {
179*4882a593Smuzhiyun 	struct iio_poll_func *pf = p;
180*4882a593Smuzhiyun 	struct iio_dev *indio_dev = pf->indio_dev;
181*4882a593Smuzhiyun 	struct isl29125_data *data = iio_priv(indio_dev);
182*4882a593Smuzhiyun 	int i, j = 0;
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun 	for_each_set_bit(i, indio_dev->active_scan_mask,
185*4882a593Smuzhiyun 		indio_dev->masklength) {
186*4882a593Smuzhiyun 		int ret = i2c_smbus_read_word_data(data->client,
187*4882a593Smuzhiyun 			isl29125_regs[i].data);
188*4882a593Smuzhiyun 		if (ret < 0)
189*4882a593Smuzhiyun 			goto done;
190*4882a593Smuzhiyun 
191*4882a593Smuzhiyun 		data->scan.chans[j++] = ret;
192*4882a593Smuzhiyun 	}
193*4882a593Smuzhiyun 
194*4882a593Smuzhiyun 	iio_push_to_buffers_with_timestamp(indio_dev, &data->scan,
195*4882a593Smuzhiyun 		iio_get_time_ns(indio_dev));
196*4882a593Smuzhiyun 
197*4882a593Smuzhiyun done:
198*4882a593Smuzhiyun 	iio_trigger_notify_done(indio_dev->trig);
199*4882a593Smuzhiyun 
200*4882a593Smuzhiyun 	return IRQ_HANDLED;
201*4882a593Smuzhiyun }
202*4882a593Smuzhiyun 
203*4882a593Smuzhiyun static IIO_CONST_ATTR(scale_available, "0.005722 0.152590");
204*4882a593Smuzhiyun 
205*4882a593Smuzhiyun static struct attribute *isl29125_attributes[] = {
206*4882a593Smuzhiyun 	&iio_const_attr_scale_available.dev_attr.attr,
207*4882a593Smuzhiyun 	NULL
208*4882a593Smuzhiyun };
209*4882a593Smuzhiyun 
210*4882a593Smuzhiyun static const struct attribute_group isl29125_attribute_group = {
211*4882a593Smuzhiyun 	.attrs = isl29125_attributes,
212*4882a593Smuzhiyun };
213*4882a593Smuzhiyun 
214*4882a593Smuzhiyun static const struct iio_info isl29125_info = {
215*4882a593Smuzhiyun 	.read_raw = isl29125_read_raw,
216*4882a593Smuzhiyun 	.write_raw = isl29125_write_raw,
217*4882a593Smuzhiyun 	.attrs = &isl29125_attribute_group,
218*4882a593Smuzhiyun };
219*4882a593Smuzhiyun 
isl29125_buffer_postenable(struct iio_dev * indio_dev)220*4882a593Smuzhiyun static int isl29125_buffer_postenable(struct iio_dev *indio_dev)
221*4882a593Smuzhiyun {
222*4882a593Smuzhiyun 	struct isl29125_data *data = iio_priv(indio_dev);
223*4882a593Smuzhiyun 
224*4882a593Smuzhiyun 	data->conf1 |= ISL29125_MODE_RGB;
225*4882a593Smuzhiyun 	return i2c_smbus_write_byte_data(data->client, ISL29125_CONF1,
226*4882a593Smuzhiyun 		data->conf1);
227*4882a593Smuzhiyun }
228*4882a593Smuzhiyun 
isl29125_buffer_predisable(struct iio_dev * indio_dev)229*4882a593Smuzhiyun static int isl29125_buffer_predisable(struct iio_dev *indio_dev)
230*4882a593Smuzhiyun {
231*4882a593Smuzhiyun 	struct isl29125_data *data = iio_priv(indio_dev);
232*4882a593Smuzhiyun 
233*4882a593Smuzhiyun 	data->conf1 &= ~ISL29125_MODE_MASK;
234*4882a593Smuzhiyun 	data->conf1 |= ISL29125_MODE_PD;
235*4882a593Smuzhiyun 	return i2c_smbus_write_byte_data(data->client, ISL29125_CONF1,
236*4882a593Smuzhiyun 		data->conf1);
237*4882a593Smuzhiyun }
238*4882a593Smuzhiyun 
239*4882a593Smuzhiyun static const struct iio_buffer_setup_ops isl29125_buffer_setup_ops = {
240*4882a593Smuzhiyun 	.postenable = isl29125_buffer_postenable,
241*4882a593Smuzhiyun 	.predisable = isl29125_buffer_predisable,
242*4882a593Smuzhiyun };
243*4882a593Smuzhiyun 
isl29125_probe(struct i2c_client * client,const struct i2c_device_id * id)244*4882a593Smuzhiyun static int isl29125_probe(struct i2c_client *client,
245*4882a593Smuzhiyun 			   const struct i2c_device_id *id)
246*4882a593Smuzhiyun {
247*4882a593Smuzhiyun 	struct isl29125_data *data;
248*4882a593Smuzhiyun 	struct iio_dev *indio_dev;
249*4882a593Smuzhiyun 	int ret;
250*4882a593Smuzhiyun 
251*4882a593Smuzhiyun 	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
252*4882a593Smuzhiyun 	if (indio_dev == NULL)
253*4882a593Smuzhiyun 		return -ENOMEM;
254*4882a593Smuzhiyun 
255*4882a593Smuzhiyun 	data = iio_priv(indio_dev);
256*4882a593Smuzhiyun 	i2c_set_clientdata(client, indio_dev);
257*4882a593Smuzhiyun 	data->client = client;
258*4882a593Smuzhiyun 
259*4882a593Smuzhiyun 	indio_dev->info = &isl29125_info;
260*4882a593Smuzhiyun 	indio_dev->name = ISL29125_DRV_NAME;
261*4882a593Smuzhiyun 	indio_dev->channels = isl29125_channels;
262*4882a593Smuzhiyun 	indio_dev->num_channels = ARRAY_SIZE(isl29125_channels);
263*4882a593Smuzhiyun 	indio_dev->modes = INDIO_DIRECT_MODE;
264*4882a593Smuzhiyun 
265*4882a593Smuzhiyun 	ret = i2c_smbus_read_byte_data(data->client, ISL29125_DEVICE_ID);
266*4882a593Smuzhiyun 	if (ret < 0)
267*4882a593Smuzhiyun 		return ret;
268*4882a593Smuzhiyun 	if (ret != ISL29125_ID)
269*4882a593Smuzhiyun 		return -ENODEV;
270*4882a593Smuzhiyun 
271*4882a593Smuzhiyun 	data->conf1 = ISL29125_MODE_PD | ISL29125_MODE_RANGE;
272*4882a593Smuzhiyun 	ret = i2c_smbus_write_byte_data(data->client, ISL29125_CONF1,
273*4882a593Smuzhiyun 		data->conf1);
274*4882a593Smuzhiyun 	if (ret < 0)
275*4882a593Smuzhiyun 		return ret;
276*4882a593Smuzhiyun 
277*4882a593Smuzhiyun 	ret = i2c_smbus_write_byte_data(data->client, ISL29125_STATUS, 0);
278*4882a593Smuzhiyun 	if (ret < 0)
279*4882a593Smuzhiyun 		return ret;
280*4882a593Smuzhiyun 
281*4882a593Smuzhiyun 	ret = iio_triggered_buffer_setup(indio_dev, NULL,
282*4882a593Smuzhiyun 		isl29125_trigger_handler, &isl29125_buffer_setup_ops);
283*4882a593Smuzhiyun 	if (ret < 0)
284*4882a593Smuzhiyun 		return ret;
285*4882a593Smuzhiyun 
286*4882a593Smuzhiyun 	ret = iio_device_register(indio_dev);
287*4882a593Smuzhiyun 	if (ret < 0)
288*4882a593Smuzhiyun 		goto buffer_cleanup;
289*4882a593Smuzhiyun 
290*4882a593Smuzhiyun 	return 0;
291*4882a593Smuzhiyun 
292*4882a593Smuzhiyun buffer_cleanup:
293*4882a593Smuzhiyun 	iio_triggered_buffer_cleanup(indio_dev);
294*4882a593Smuzhiyun 	return ret;
295*4882a593Smuzhiyun }
296*4882a593Smuzhiyun 
isl29125_powerdown(struct isl29125_data * data)297*4882a593Smuzhiyun static int isl29125_powerdown(struct isl29125_data *data)
298*4882a593Smuzhiyun {
299*4882a593Smuzhiyun 	return i2c_smbus_write_byte_data(data->client, ISL29125_CONF1,
300*4882a593Smuzhiyun 		(data->conf1 & ~ISL29125_MODE_MASK) | ISL29125_MODE_PD);
301*4882a593Smuzhiyun }
302*4882a593Smuzhiyun 
isl29125_remove(struct i2c_client * client)303*4882a593Smuzhiyun static int isl29125_remove(struct i2c_client *client)
304*4882a593Smuzhiyun {
305*4882a593Smuzhiyun 	struct iio_dev *indio_dev = i2c_get_clientdata(client);
306*4882a593Smuzhiyun 
307*4882a593Smuzhiyun 	iio_device_unregister(indio_dev);
308*4882a593Smuzhiyun 	iio_triggered_buffer_cleanup(indio_dev);
309*4882a593Smuzhiyun 	isl29125_powerdown(iio_priv(indio_dev));
310*4882a593Smuzhiyun 
311*4882a593Smuzhiyun 	return 0;
312*4882a593Smuzhiyun }
313*4882a593Smuzhiyun 
314*4882a593Smuzhiyun #ifdef CONFIG_PM_SLEEP
isl29125_suspend(struct device * dev)315*4882a593Smuzhiyun static int isl29125_suspend(struct device *dev)
316*4882a593Smuzhiyun {
317*4882a593Smuzhiyun 	struct isl29125_data *data = iio_priv(i2c_get_clientdata(
318*4882a593Smuzhiyun 		to_i2c_client(dev)));
319*4882a593Smuzhiyun 	return isl29125_powerdown(data);
320*4882a593Smuzhiyun }
321*4882a593Smuzhiyun 
isl29125_resume(struct device * dev)322*4882a593Smuzhiyun static int isl29125_resume(struct device *dev)
323*4882a593Smuzhiyun {
324*4882a593Smuzhiyun 	struct isl29125_data *data = iio_priv(i2c_get_clientdata(
325*4882a593Smuzhiyun 		to_i2c_client(dev)));
326*4882a593Smuzhiyun 	return i2c_smbus_write_byte_data(data->client, ISL29125_CONF1,
327*4882a593Smuzhiyun 		data->conf1);
328*4882a593Smuzhiyun }
329*4882a593Smuzhiyun #endif
330*4882a593Smuzhiyun 
331*4882a593Smuzhiyun static SIMPLE_DEV_PM_OPS(isl29125_pm_ops, isl29125_suspend, isl29125_resume);
332*4882a593Smuzhiyun 
333*4882a593Smuzhiyun static const struct i2c_device_id isl29125_id[] = {
334*4882a593Smuzhiyun 	{ "isl29125", 0 },
335*4882a593Smuzhiyun 	{ }
336*4882a593Smuzhiyun };
337*4882a593Smuzhiyun MODULE_DEVICE_TABLE(i2c, isl29125_id);
338*4882a593Smuzhiyun 
339*4882a593Smuzhiyun static struct i2c_driver isl29125_driver = {
340*4882a593Smuzhiyun 	.driver = {
341*4882a593Smuzhiyun 		.name	= ISL29125_DRV_NAME,
342*4882a593Smuzhiyun 		.pm	= &isl29125_pm_ops,
343*4882a593Smuzhiyun 	},
344*4882a593Smuzhiyun 	.probe		= isl29125_probe,
345*4882a593Smuzhiyun 	.remove		= isl29125_remove,
346*4882a593Smuzhiyun 	.id_table	= isl29125_id,
347*4882a593Smuzhiyun };
348*4882a593Smuzhiyun module_i2c_driver(isl29125_driver);
349*4882a593Smuzhiyun 
350*4882a593Smuzhiyun MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>");
351*4882a593Smuzhiyun MODULE_DESCRIPTION("ISL29125 RGB light sensor driver");
352*4882a593Smuzhiyun MODULE_LICENSE("GPL");
353