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 /* Ensure timestamp is naturally aligned */
59 s64 timestamp
__aligned(8);
63 #define TCS3414_CHANNEL(_color, _si, _addr) { \
64 .type = IIO_INTENSITY, \
66 .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
67 .info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE) | \
68 BIT(IIO_CHAN_INFO_INT_TIME), \
69 .channel2 = IIO_MOD_LIGHT_##_color, \
76 .endianness = IIO_CPU, \
80 /* scale factors: 1/gain */
81 static const int tcs3414_scales
[][2] = {
82 {1, 0}, {0, 250000}, {0, 62500}, {0, 15625}
85 /* integration time in ms */
86 static const int tcs3414_times
[] = { 12, 100, 400 };
88 static const struct iio_chan_spec tcs3414_channels
[] = {
89 TCS3414_CHANNEL(GREEN
, 0, TCS3414_DATA_GREEN
),
90 TCS3414_CHANNEL(RED
, 1, TCS3414_DATA_RED
),
91 TCS3414_CHANNEL(BLUE
, 2, TCS3414_DATA_BLUE
),
92 TCS3414_CHANNEL(CLEAR
, 3, TCS3414_DATA_CLEAR
),
93 IIO_CHAN_SOFT_TIMESTAMP(4),
96 static int tcs3414_req_data(struct tcs3414_data
*data
)
101 ret
= i2c_smbus_write_byte_data(data
->client
, TCS3414_CONTROL
,
102 data
->control
| TCS3414_CONTROL_ADC_EN
);
107 ret
= i2c_smbus_read_byte_data(data
->client
, TCS3414_CONTROL
);
110 if (ret
& TCS3414_CONTROL_ADC_VALID
)
115 ret
= i2c_smbus_write_byte_data(data
->client
, TCS3414_CONTROL
,
121 dev_err(&data
->client
->dev
, "data not ready\n");
128 static int tcs3414_read_raw(struct iio_dev
*indio_dev
,
129 struct iio_chan_spec
const *chan
,
130 int *val
, int *val2
, long mask
)
132 struct tcs3414_data
*data
= iio_priv(indio_dev
);
136 case IIO_CHAN_INFO_RAW
:
137 ret
= iio_device_claim_direct_mode(indio_dev
);
140 ret
= tcs3414_req_data(data
);
142 iio_device_release_direct_mode(indio_dev
);
145 ret
= i2c_smbus_read_word_data(data
->client
, chan
->address
);
146 iio_device_release_direct_mode(indio_dev
);
151 case IIO_CHAN_INFO_SCALE
:
152 i
= (data
->gain
& TCS3414_GAIN_MASK
) >> TCS3414_GAIN_SHIFT
;
153 *val
= tcs3414_scales
[i
][0];
154 *val2
= tcs3414_scales
[i
][1];
155 return IIO_VAL_INT_PLUS_MICRO
;
156 case IIO_CHAN_INFO_INT_TIME
:
158 *val2
= tcs3414_times
[data
->timing
& TCS3414_INTEG_MASK
] * 1000;
159 return IIO_VAL_INT_PLUS_MICRO
;
164 static int tcs3414_write_raw(struct iio_dev
*indio_dev
,
165 struct iio_chan_spec
const *chan
,
166 int val
, int val2
, long mask
)
168 struct tcs3414_data
*data
= iio_priv(indio_dev
);
172 case IIO_CHAN_INFO_SCALE
:
173 for (i
= 0; i
< ARRAY_SIZE(tcs3414_scales
); i
++) {
174 if (val
== tcs3414_scales
[i
][0] &&
175 val2
== tcs3414_scales
[i
][1]) {
176 data
->gain
&= ~TCS3414_GAIN_MASK
;
177 data
->gain
|= i
<< TCS3414_GAIN_SHIFT
;
178 return i2c_smbus_write_byte_data(
179 data
->client
, TCS3414_GAIN
,
184 case IIO_CHAN_INFO_INT_TIME
:
187 for (i
= 0; i
< ARRAY_SIZE(tcs3414_times
); i
++) {
188 if (val2
== tcs3414_times
[i
] * 1000) {
189 data
->timing
&= ~TCS3414_INTEG_MASK
;
191 return i2c_smbus_write_byte_data(
192 data
->client
, TCS3414_TIMING
,
202 static irqreturn_t
tcs3414_trigger_handler(int irq
, void *p
)
204 struct iio_poll_func
*pf
= p
;
205 struct iio_dev
*indio_dev
= pf
->indio_dev
;
206 struct tcs3414_data
*data
= iio_priv(indio_dev
);
209 iio_for_each_active_channel(indio_dev
, i
) {
210 int ret
= i2c_smbus_read_word_data(data
->client
,
211 TCS3414_DATA_GREEN
+ 2*i
);
215 data
->scan
.chans
[j
++] = ret
;
218 iio_push_to_buffers_with_timestamp(indio_dev
, &data
->scan
,
219 iio_get_time_ns(indio_dev
));
222 iio_trigger_notify_done(indio_dev
->trig
);
227 static IIO_CONST_ATTR(scale_available
, "1 0.25 0.0625 0.015625");
228 static IIO_CONST_ATTR_INT_TIME_AVAIL("0.012 0.1 0.4");
230 static struct attribute
*tcs3414_attributes
[] = {
231 &iio_const_attr_scale_available
.dev_attr
.attr
,
232 &iio_const_attr_integration_time_available
.dev_attr
.attr
,
236 static const struct attribute_group tcs3414_attribute_group
= {
237 .attrs
= tcs3414_attributes
,
240 static const struct iio_info tcs3414_info
= {
241 .read_raw
= tcs3414_read_raw
,
242 .write_raw
= tcs3414_write_raw
,
243 .attrs
= &tcs3414_attribute_group
,
246 static int tcs3414_buffer_postenable(struct iio_dev
*indio_dev
)
248 struct tcs3414_data
*data
= iio_priv(indio_dev
);
250 data
->control
|= TCS3414_CONTROL_ADC_EN
;
251 return i2c_smbus_write_byte_data(data
->client
, TCS3414_CONTROL
,
255 static int tcs3414_buffer_predisable(struct iio_dev
*indio_dev
)
257 struct tcs3414_data
*data
= iio_priv(indio_dev
);
259 data
->control
&= ~TCS3414_CONTROL_ADC_EN
;
260 return i2c_smbus_write_byte_data(data
->client
, TCS3414_CONTROL
,
264 static const struct iio_buffer_setup_ops tcs3414_buffer_setup_ops
= {
265 .postenable
= tcs3414_buffer_postenable
,
266 .predisable
= tcs3414_buffer_predisable
,
269 static int tcs3414_powerdown(struct tcs3414_data
*data
)
271 return i2c_smbus_write_byte_data(data
->client
, TCS3414_CONTROL
,
272 data
->control
& ~(TCS3414_CONTROL_POWER
|
273 TCS3414_CONTROL_ADC_EN
));
276 static void tcs3414_powerdown_cleanup(void *data
)
278 tcs3414_powerdown(data
);
281 static int tcs3414_probe(struct i2c_client
*client
)
283 struct tcs3414_data
*data
;
284 struct iio_dev
*indio_dev
;
287 indio_dev
= devm_iio_device_alloc(&client
->dev
, sizeof(*data
));
288 if (indio_dev
== NULL
)
291 data
= iio_priv(indio_dev
);
292 i2c_set_clientdata(client
, indio_dev
);
293 data
->client
= client
;
295 indio_dev
->info
= &tcs3414_info
;
296 indio_dev
->name
= TCS3414_DRV_NAME
;
297 indio_dev
->channels
= tcs3414_channels
;
298 indio_dev
->num_channels
= ARRAY_SIZE(tcs3414_channels
);
299 indio_dev
->modes
= INDIO_DIRECT_MODE
;
301 ret
= i2c_smbus_read_byte_data(data
->client
, TCS3414_ID
);
305 switch (ret
& 0xf0) {
307 dev_info(&client
->dev
, "TCS3404 found\n");
310 dev_info(&client
->dev
, "TCS3413/14/15/16 found\n");
316 data
->control
= TCS3414_CONTROL_POWER
;
317 ret
= i2c_smbus_write_byte_data(data
->client
, TCS3414_CONTROL
,
322 ret
= devm_add_action_or_reset(&client
->dev
, tcs3414_powerdown_cleanup
,
327 data
->timing
= TCS3414_INTEG_12MS
; /* free running */
328 ret
= i2c_smbus_write_byte_data(data
->client
, TCS3414_TIMING
,
333 ret
= i2c_smbus_read_byte_data(data
->client
, TCS3414_GAIN
);
338 ret
= devm_iio_triggered_buffer_setup(&client
->dev
, indio_dev
, NULL
,
339 tcs3414_trigger_handler
, &tcs3414_buffer_setup_ops
);
343 return devm_iio_device_register(&client
->dev
, indio_dev
);
346 static int tcs3414_suspend(struct device
*dev
)
348 struct tcs3414_data
*data
= iio_priv(i2c_get_clientdata(
349 to_i2c_client(dev
)));
350 return tcs3414_powerdown(data
);
353 static int tcs3414_resume(struct device
*dev
)
355 struct tcs3414_data
*data
= iio_priv(i2c_get_clientdata(
356 to_i2c_client(dev
)));
357 return i2c_smbus_write_byte_data(data
->client
, TCS3414_CONTROL
,
361 static DEFINE_SIMPLE_DEV_PM_OPS(tcs3414_pm_ops
, tcs3414_suspend
,
364 static const struct i2c_device_id tcs3414_id
[] = {
368 MODULE_DEVICE_TABLE(i2c
, tcs3414_id
);
370 static struct i2c_driver tcs3414_driver
= {
372 .name
= TCS3414_DRV_NAME
,
373 .pm
= pm_sleep_ptr(&tcs3414_pm_ops
),
375 .probe
= tcs3414_probe
,
376 .id_table
= tcs3414_id
,
378 module_i2c_driver(tcs3414_driver
);
380 MODULE_AUTHOR("Peter Meerwald <pmeerw@pmeerw.net>");
381 MODULE_DESCRIPTION("TCS3414 digital color sensors driver");
382 MODULE_LICENSE("GPL");