1 // SPDX-License-Identifier: GPL-2.0-only
3 * tcs3414.c - Support for TAOS TCS3414 digital color sensor
5 * Copyright (c) 2014 Peter Meerwald <pmeerw@pmeerw.net>
7 * Digital color sensor with 16-bit channels for red, green, blue, clear);
8 * 7-bit I2C slave address 0x39 (TCS3414) or 0x29, 0x49, 0x59 (TCS3413,
9 * TCS3415, TCS3416, resp.)
11 * TODO: sync, interrupt support, thresholds, prescaler
14 #include <linux/module.h>
15 #include <linux/i2c.h>
16 #include <linux/delay.h>
19 #include <linux/iio/iio.h>
20 #include <linux/iio/sysfs.h>
21 #include <linux/iio/trigger_consumer.h>
22 #include <linux/iio/buffer.h>
23 #include <linux/iio/triggered_buffer.h>
25 #define TCS3414_DRV_NAME "tcs3414"
27 #define TCS3414_COMMAND BIT(7)
28 #define TCS3414_COMMAND_WORD (TCS3414_COMMAND | BIT(5))
30 #define TCS3414_CONTROL (TCS3414_COMMAND | 0x00)
31 #define TCS3414_TIMING (TCS3414_COMMAND | 0x01)
32 #define TCS3414_ID (TCS3414_COMMAND | 0x04)
33 #define TCS3414_GAIN (TCS3414_COMMAND | 0x07)
34 #define TCS3414_DATA_GREEN (TCS3414_COMMAND_WORD | 0x10)
35 #define TCS3414_DATA_RED (TCS3414_COMMAND_WORD | 0x12)
36 #define TCS3414_DATA_BLUE (TCS3414_COMMAND_WORD | 0x14)
37 #define TCS3414_DATA_CLEAR (TCS3414_COMMAND_WORD | 0x16)
39 #define TCS3414_CONTROL_ADC_VALID BIT(4)
40 #define TCS3414_CONTROL_ADC_EN BIT(1)
41 #define TCS3414_CONTROL_POWER BIT(0)
43 #define TCS3414_INTEG_MASK GENMASK(1, 0)
44 #define TCS3414_INTEG_12MS 0x0
45 #define TCS3414_INTEG_100MS 0x1
46 #define TCS3414_INTEG_400MS 0x2
48 #define TCS3414_GAIN_MASK GENMASK(5, 4)
49 #define TCS3414_GAIN_SHIFT 4
52 struct i2c_client
*client
;
56 u16 buffer
[8]; /* 4x 16-bit + 8 bytes timestamp */
59 #define TCS3414_CHANNEL(_color, _si, _addr) { \
60 .type = IIO_INTENSITY, \
62 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
63 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
64 BIT(IIO_CHAN_INFO_INT_TIME), \
65 .channel2 = IIO_MOD_LIGHT_##_color, \
72 .endianness = IIO_CPU, \
76 /* scale factors: 1/gain */
77 static const int tcs3414_scales
[][2] = {
78 {1, 0}, {0, 250000}, {0, 62500}, {0, 15625}
81 /* integration time in ms */
82 static const int tcs3414_times
[] = { 12, 100, 400 };
84 static const struct iio_chan_spec tcs3414_channels
[] = {
85 TCS3414_CHANNEL(GREEN
, 0, TCS3414_DATA_GREEN
),
86 TCS3414_CHANNEL(RED
, 1, TCS3414_DATA_RED
),
87 TCS3414_CHANNEL(BLUE
, 2, TCS3414_DATA_BLUE
),
88 TCS3414_CHANNEL(CLEAR
, 3, TCS3414_DATA_CLEAR
),
89 IIO_CHAN_SOFT_TIMESTAMP(4),
92 static int tcs3414_req_data(struct tcs3414_data
*data
)
97 ret
= i2c_smbus_write_byte_data(data
->client
, TCS3414_CONTROL
,
98 data
->control
| TCS3414_CONTROL_ADC_EN
);
103 ret
= i2c_smbus_read_byte_data(data
->client
, TCS3414_CONTROL
);
106 if (ret
& TCS3414_CONTROL_ADC_VALID
)
111 ret
= i2c_smbus_write_byte_data(data
->client
, TCS3414_CONTROL
,
117 dev_err(&data
->client
->dev
, "data not ready\n");
124 static int tcs3414_read_raw(struct iio_dev
*indio_dev
,
125 struct iio_chan_spec
const *chan
,
126 int *val
, int *val2
, long mask
)
128 struct tcs3414_data
*data
= iio_priv(indio_dev
);
132 case IIO_CHAN_INFO_RAW
:
133 ret
= iio_device_claim_direct_mode(indio_dev
);
136 ret
= tcs3414_req_data(data
);
138 iio_device_release_direct_mode(indio_dev
);
141 ret
= i2c_smbus_read_word_data(data
->client
, chan
->address
);
142 iio_device_release_direct_mode(indio_dev
);
147 case IIO_CHAN_INFO_SCALE
:
148 i
= (data
->gain
& TCS3414_GAIN_MASK
) >> TCS3414_GAIN_SHIFT
;
149 *val
= tcs3414_scales
[i
][0];
150 *val2
= tcs3414_scales
[i
][1];
151 return IIO_VAL_INT_PLUS_MICRO
;
152 case IIO_CHAN_INFO_INT_TIME
:
154 *val2
= tcs3414_times
[data
->timing
& TCS3414_INTEG_MASK
] * 1000;
155 return IIO_VAL_INT_PLUS_MICRO
;
160 static int tcs3414_write_raw(struct iio_dev
*indio_dev
,
161 struct iio_chan_spec
const *chan
,
162 int val
, int val2
, long mask
)
164 struct tcs3414_data
*data
= iio_priv(indio_dev
);
168 case IIO_CHAN_INFO_SCALE
:
169 for (i
= 0; i
< ARRAY_SIZE(tcs3414_scales
); i
++) {
170 if (val
== tcs3414_scales
[i
][0] &&
171 val2
== tcs3414_scales
[i
][1]) {
172 data
->gain
&= ~TCS3414_GAIN_MASK
;
173 data
->gain
|= i
<< TCS3414_GAIN_SHIFT
;
174 return i2c_smbus_write_byte_data(
175 data
->client
, TCS3414_GAIN
,
180 case IIO_CHAN_INFO_INT_TIME
:
183 for (i
= 0; i
< ARRAY_SIZE(tcs3414_times
); i
++) {
184 if (val2
== tcs3414_times
[i
] * 1000) {
185 data
->timing
&= ~TCS3414_INTEG_MASK
;
187 return i2c_smbus_write_byte_data(
188 data
->client
, TCS3414_TIMING
,
198 static irqreturn_t
tcs3414_trigger_handler(int irq
, void *p
)
200 struct iio_poll_func
*pf
= p
;
201 struct iio_dev
*indio_dev
= pf
->indio_dev
;
202 struct tcs3414_data
*data
= iio_priv(indio_dev
);
205 for_each_set_bit(i
, indio_dev
->active_scan_mask
,
206 indio_dev
->masklength
) {
207 int ret
= i2c_smbus_read_word_data(data
->client
,
208 TCS3414_DATA_GREEN
+ 2*i
);
212 data
->buffer
[j
++] = ret
;
215 iio_push_to_buffers_with_timestamp(indio_dev
, data
->buffer
,
216 iio_get_time_ns(indio_dev
));
219 iio_trigger_notify_done(indio_dev
->trig
);
224 static IIO_CONST_ATTR(scale_available
, "1 0.25 0.0625 0.015625");
225 static IIO_CONST_ATTR_INT_TIME_AVAIL("0.012 0.1 0.4");
227 static struct attribute
*tcs3414_attributes
[] = {
228 &iio_const_attr_scale_available
.dev_attr
.attr
,
229 &iio_const_attr_integration_time_available
.dev_attr
.attr
,
233 static const struct attribute_group tcs3414_attribute_group
= {
234 .attrs
= tcs3414_attributes
,
237 static const struct iio_info tcs3414_info
= {
238 .read_raw
= tcs3414_read_raw
,
239 .write_raw
= tcs3414_write_raw
,
240 .attrs
= &tcs3414_attribute_group
,
243 static int tcs3414_buffer_postenable(struct iio_dev
*indio_dev
)
245 struct tcs3414_data
*data
= iio_priv(indio_dev
);
248 ret
= iio_triggered_buffer_postenable(indio_dev
);
252 data
->control
|= TCS3414_CONTROL_ADC_EN
;
253 ret
= i2c_smbus_write_byte_data(data
->client
, TCS3414_CONTROL
,
256 iio_triggered_buffer_predisable(indio_dev
);
261 static int tcs3414_buffer_predisable(struct iio_dev
*indio_dev
)
263 struct tcs3414_data
*data
= iio_priv(indio_dev
);
266 data
->control
&= ~TCS3414_CONTROL_ADC_EN
;
267 ret
= i2c_smbus_write_byte_data(data
->client
, TCS3414_CONTROL
,
270 ret2
= iio_triggered_buffer_predisable(indio_dev
);
277 static const struct iio_buffer_setup_ops tcs3414_buffer_setup_ops
= {
278 .postenable
= tcs3414_buffer_postenable
,
279 .predisable
= tcs3414_buffer_predisable
,
282 static int tcs3414_probe(struct i2c_client
*client
,
283 const struct i2c_device_id
*id
)
285 struct tcs3414_data
*data
;
286 struct iio_dev
*indio_dev
;
289 indio_dev
= devm_iio_device_alloc(&client
->dev
, sizeof(*data
));
290 if (indio_dev
== NULL
)
293 data
= iio_priv(indio_dev
);
294 i2c_set_clientdata(client
, indio_dev
);
295 data
->client
= client
;
297 indio_dev
->dev
.parent
= &client
->dev
;
298 indio_dev
->info
= &tcs3414_info
;
299 indio_dev
->name
= TCS3414_DRV_NAME
;
300 indio_dev
->channels
= tcs3414_channels
;
301 indio_dev
->num_channels
= ARRAY_SIZE(tcs3414_channels
);
302 indio_dev
->modes
= INDIO_DIRECT_MODE
;
304 ret
= i2c_smbus_read_byte_data(data
->client
, TCS3414_ID
);
308 switch (ret
& 0xf0) {
310 dev_info(&client
->dev
, "TCS3404 found\n");
313 dev_info(&client
->dev
, "TCS3413/14/15/16 found\n");
319 data
->control
= TCS3414_CONTROL_POWER
;
320 ret
= i2c_smbus_write_byte_data(data
->client
, TCS3414_CONTROL
,
325 data
->timing
= TCS3414_INTEG_12MS
; /* free running */
326 ret
= i2c_smbus_write_byte_data(data
->client
, TCS3414_TIMING
,
331 ret
= i2c_smbus_read_byte_data(data
->client
, TCS3414_GAIN
);
336 ret
= iio_triggered_buffer_setup(indio_dev
, NULL
,
337 tcs3414_trigger_handler
, &tcs3414_buffer_setup_ops
);
341 ret
= iio_device_register(indio_dev
);
348 iio_triggered_buffer_cleanup(indio_dev
);
352 static int tcs3414_powerdown(struct tcs3414_data
*data
)
354 return i2c_smbus_write_byte_data(data
->client
, TCS3414_CONTROL
,
355 data
->control
& ~(TCS3414_CONTROL_POWER
|
356 TCS3414_CONTROL_ADC_EN
));
359 static int tcs3414_remove(struct i2c_client
*client
)
361 struct iio_dev
*indio_dev
= i2c_get_clientdata(client
);
363 iio_device_unregister(indio_dev
);
364 iio_triggered_buffer_cleanup(indio_dev
);
365 tcs3414_powerdown(iio_priv(indio_dev
));
370 #ifdef CONFIG_PM_SLEEP
371 static int tcs3414_suspend(struct device
*dev
)
373 struct tcs3414_data
*data
= iio_priv(i2c_get_clientdata(
374 to_i2c_client(dev
)));
375 return tcs3414_powerdown(data
);
378 static int tcs3414_resume(struct device
*dev
)
380 struct tcs3414_data
*data
= iio_priv(i2c_get_clientdata(
381 to_i2c_client(dev
)));
382 return i2c_smbus_write_byte_data(data
->client
, TCS3414_CONTROL
,
387 static SIMPLE_DEV_PM_OPS(tcs3414_pm_ops
, tcs3414_suspend
, tcs3414_resume
);
389 static const struct i2c_device_id tcs3414_id
[] = {
393 MODULE_DEVICE_TABLE(i2c
, tcs3414_id
);
395 static struct i2c_driver tcs3414_driver
= {
397 .name
= TCS3414_DRV_NAME
,
398 .pm
= &tcs3414_pm_ops
,
400 .probe
= tcs3414_probe
,
401 .remove
= tcs3414_remove
,
402 .id_table
= tcs3414_id
,
404 module_i2c_driver(tcs3414_driver
);
406 MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>");
407 MODULE_DESCRIPTION("TCS3414 digital color sensors driver");
408 MODULE_LICENSE("GPL");