xref: /openbmc/linux/drivers/misc/tsl2550.c (revision 0c6dfa75)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *  tsl2550.c - Linux kernel modules for ambient light sensor
4  *
5  *  Copyright (C) 2007 Rodolfo Giometti <giometti@linux.it>
6  *  Copyright (C) 2007 Eurotech S.p.A. <info@eurotech.it>
7  */
8 
9 #include <linux/module.h>
10 #include <linux/slab.h>
11 #include <linux/i2c.h>
12 #include <linux/mutex.h>
13 
14 #define TSL2550_DRV_NAME	"tsl2550"
15 #define DRIVER_VERSION		"1.2"
16 
17 /*
18  * Defines
19  */
20 
21 #define TSL2550_POWER_DOWN		0x00
22 #define TSL2550_POWER_UP		0x03
23 #define TSL2550_STANDARD_RANGE		0x18
24 #define TSL2550_EXTENDED_RANGE		0x1d
25 #define TSL2550_READ_ADC0		0x43
26 #define TSL2550_READ_ADC1		0x83
27 
28 /*
29  * Structs
30  */
31 
32 struct tsl2550_data {
33 	struct i2c_client *client;
34 	struct mutex update_lock;
35 
36 	unsigned int power_state:1;
37 	unsigned int operating_mode:1;
38 };
39 
40 /*
41  * Global data
42  */
43 
44 static const u8 TSL2550_MODE_RANGE[2] = {
45 	TSL2550_STANDARD_RANGE, TSL2550_EXTENDED_RANGE,
46 };
47 
48 /*
49  * Management functions
50  */
51 
52 static int tsl2550_set_operating_mode(struct i2c_client *client, int mode)
53 {
54 	struct tsl2550_data *data = i2c_get_clientdata(client);
55 
56 	int ret = i2c_smbus_write_byte(client, TSL2550_MODE_RANGE[mode]);
57 
58 	data->operating_mode = mode;
59 
60 	return ret;
61 }
62 
63 static int tsl2550_set_power_state(struct i2c_client *client, int state)
64 {
65 	struct tsl2550_data *data = i2c_get_clientdata(client);
66 	int ret;
67 
68 	if (state == 0)
69 		ret = i2c_smbus_write_byte(client, TSL2550_POWER_DOWN);
70 	else {
71 		ret = i2c_smbus_write_byte(client, TSL2550_POWER_UP);
72 
73 		/* On power up we should reset operating mode also... */
74 		tsl2550_set_operating_mode(client, data->operating_mode);
75 	}
76 
77 	data->power_state = state;
78 
79 	return ret;
80 }
81 
82 static int tsl2550_get_adc_value(struct i2c_client *client, u8 cmd)
83 {
84 	int ret;
85 
86 	ret = i2c_smbus_read_byte_data(client, cmd);
87 	if (ret < 0)
88 		return ret;
89 	if (!(ret & 0x80))
90 		return -EAGAIN;
91 	return ret & 0x7f;	/* remove the "valid" bit */
92 }
93 
94 /*
95  * LUX calculation
96  */
97 
98 #define	TSL2550_MAX_LUX		1846
99 
100 static const u8 ratio_lut[] = {
101 	100, 100, 100, 100, 100, 100, 100, 100,
102 	100, 100, 100, 100, 100, 100, 99, 99,
103 	99, 99, 99, 99, 99, 99, 99, 99,
104 	99, 99, 99, 98, 98, 98, 98, 98,
105 	98, 98, 97, 97, 97, 97, 97, 96,
106 	96, 96, 96, 95, 95, 95, 94, 94,
107 	93, 93, 93, 92, 92, 91, 91, 90,
108 	89, 89, 88, 87, 87, 86, 85, 84,
109 	83, 82, 81, 80, 79, 78, 77, 75,
110 	74, 73, 71, 69, 68, 66, 64, 62,
111 	60, 58, 56, 54, 52, 49, 47, 44,
112 	42, 41, 40, 40, 39, 39, 38, 38,
113 	37, 37, 37, 36, 36, 36, 35, 35,
114 	35, 35, 34, 34, 34, 34, 33, 33,
115 	33, 33, 32, 32, 32, 32, 32, 31,
116 	31, 31, 31, 31, 30, 30, 30, 30,
117 	30,
118 };
119 
120 static const u16 count_lut[] = {
121 	0, 1, 2, 3, 4, 5, 6, 7,
122 	8, 9, 10, 11, 12, 13, 14, 15,
123 	16, 18, 20, 22, 24, 26, 28, 30,
124 	32, 34, 36, 38, 40, 42, 44, 46,
125 	49, 53, 57, 61, 65, 69, 73, 77,
126 	81, 85, 89, 93, 97, 101, 105, 109,
127 	115, 123, 131, 139, 147, 155, 163, 171,
128 	179, 187, 195, 203, 211, 219, 227, 235,
129 	247, 263, 279, 295, 311, 327, 343, 359,
130 	375, 391, 407, 423, 439, 455, 471, 487,
131 	511, 543, 575, 607, 639, 671, 703, 735,
132 	767, 799, 831, 863, 895, 927, 959, 991,
133 	1039, 1103, 1167, 1231, 1295, 1359, 1423, 1487,
134 	1551, 1615, 1679, 1743, 1807, 1871, 1935, 1999,
135 	2095, 2223, 2351, 2479, 2607, 2735, 2863, 2991,
136 	3119, 3247, 3375, 3503, 3631, 3759, 3887, 4015,
137 };
138 
139 /*
140  * This function is described into Taos TSL2550 Designer's Notebook
141  * pages 2, 3.
142  */
143 static int tsl2550_calculate_lux(u8 ch0, u8 ch1)
144 {
145 	unsigned int lux;
146 
147 	/* Look up count from channel values */
148 	u16 c0 = count_lut[ch0];
149 	u16 c1 = count_lut[ch1];
150 
151 	/* Avoid division by 0 and count 1 cannot be greater than count 0 */
152 	if (c1 <= c0)
153 		if (c0) {
154 			/*
155 			 * Calculate ratio.
156 			 * Note: the "128" is a scaling factor
157 			 */
158 			u8 r = c1 * 128 / c0;
159 
160 			/* Calculate LUX */
161 			lux = ((c0 - c1) * ratio_lut[r]) / 256;
162 		} else
163 			lux = 0;
164 	else
165 		return 0;
166 
167 	/* LUX range check */
168 	return lux > TSL2550_MAX_LUX ? TSL2550_MAX_LUX : lux;
169 }
170 
171 /*
172  * SysFS support
173  */
174 
175 static ssize_t tsl2550_show_power_state(struct device *dev,
176 		struct device_attribute *attr, char *buf)
177 {
178 	struct tsl2550_data *data = i2c_get_clientdata(to_i2c_client(dev));
179 
180 	return sprintf(buf, "%u\n", data->power_state);
181 }
182 
183 static ssize_t tsl2550_store_power_state(struct device *dev,
184 		struct device_attribute *attr, const char *buf, size_t count)
185 {
186 	struct i2c_client *client = to_i2c_client(dev);
187 	struct tsl2550_data *data = i2c_get_clientdata(client);
188 	unsigned long val = simple_strtoul(buf, NULL, 10);
189 	int ret;
190 
191 	if (val > 1)
192 		return -EINVAL;
193 
194 	mutex_lock(&data->update_lock);
195 	ret = tsl2550_set_power_state(client, val);
196 	mutex_unlock(&data->update_lock);
197 
198 	if (ret < 0)
199 		return ret;
200 
201 	return count;
202 }
203 
204 static DEVICE_ATTR(power_state, S_IWUSR | S_IRUGO,
205 		   tsl2550_show_power_state, tsl2550_store_power_state);
206 
207 static ssize_t tsl2550_show_operating_mode(struct device *dev,
208 		struct device_attribute *attr, char *buf)
209 {
210 	struct tsl2550_data *data = i2c_get_clientdata(to_i2c_client(dev));
211 
212 	return sprintf(buf, "%u\n", data->operating_mode);
213 }
214 
215 static ssize_t tsl2550_store_operating_mode(struct device *dev,
216 		struct device_attribute *attr, const char *buf, size_t count)
217 {
218 	struct i2c_client *client = to_i2c_client(dev);
219 	struct tsl2550_data *data = i2c_get_clientdata(client);
220 	unsigned long val = simple_strtoul(buf, NULL, 10);
221 	int ret;
222 
223 	if (val > 1)
224 		return -EINVAL;
225 
226 	if (data->power_state == 0)
227 		return -EBUSY;
228 
229 	mutex_lock(&data->update_lock);
230 	ret = tsl2550_set_operating_mode(client, val);
231 	mutex_unlock(&data->update_lock);
232 
233 	if (ret < 0)
234 		return ret;
235 
236 	return count;
237 }
238 
239 static DEVICE_ATTR(operating_mode, S_IWUSR | S_IRUGO,
240 		   tsl2550_show_operating_mode, tsl2550_store_operating_mode);
241 
242 static ssize_t __tsl2550_show_lux(struct i2c_client *client, char *buf)
243 {
244 	struct tsl2550_data *data = i2c_get_clientdata(client);
245 	u8 ch0, ch1;
246 	int ret;
247 
248 	ret = tsl2550_get_adc_value(client, TSL2550_READ_ADC0);
249 	if (ret < 0)
250 		return ret;
251 	ch0 = ret;
252 
253 	ret = tsl2550_get_adc_value(client, TSL2550_READ_ADC1);
254 	if (ret < 0)
255 		return ret;
256 	ch1 = ret;
257 
258 	/* Do the job */
259 	ret = tsl2550_calculate_lux(ch0, ch1);
260 	if (ret < 0)
261 		return ret;
262 	if (data->operating_mode == 1)
263 		ret *= 5;
264 
265 	return sprintf(buf, "%d\n", ret);
266 }
267 
268 static ssize_t tsl2550_show_lux1_input(struct device *dev,
269 			struct device_attribute *attr, char *buf)
270 {
271 	struct i2c_client *client = to_i2c_client(dev);
272 	struct tsl2550_data *data = i2c_get_clientdata(client);
273 	int ret;
274 
275 	/* No LUX data if not operational */
276 	if (!data->power_state)
277 		return -EBUSY;
278 
279 	mutex_lock(&data->update_lock);
280 	ret = __tsl2550_show_lux(client, buf);
281 	mutex_unlock(&data->update_lock);
282 
283 	return ret;
284 }
285 
286 static DEVICE_ATTR(lux1_input, S_IRUGO,
287 		   tsl2550_show_lux1_input, NULL);
288 
289 static struct attribute *tsl2550_attributes[] = {
290 	&dev_attr_power_state.attr,
291 	&dev_attr_operating_mode.attr,
292 	&dev_attr_lux1_input.attr,
293 	NULL
294 };
295 
296 static const struct attribute_group tsl2550_attr_group = {
297 	.attrs = tsl2550_attributes,
298 };
299 
300 /*
301  * Initialization function
302  */
303 
304 static int tsl2550_init_client(struct i2c_client *client)
305 {
306 	struct tsl2550_data *data = i2c_get_clientdata(client);
307 	int err;
308 
309 	/*
310 	 * Probe the chip. To do so we try to power up the device and then to
311 	 * read back the 0x03 code
312 	 */
313 	err = i2c_smbus_read_byte_data(client, TSL2550_POWER_UP);
314 	if (err < 0)
315 		return err;
316 	if (err != TSL2550_POWER_UP)
317 		return -ENODEV;
318 	data->power_state = 1;
319 
320 	/* Set the default operating mode */
321 	err = i2c_smbus_write_byte(client,
322 				   TSL2550_MODE_RANGE[data->operating_mode]);
323 	if (err < 0)
324 		return err;
325 
326 	return 0;
327 }
328 
329 /*
330  * I2C init/probing/exit functions
331  */
332 
333 static struct i2c_driver tsl2550_driver;
334 static int tsl2550_probe(struct i2c_client *client)
335 {
336 	struct i2c_adapter *adapter = client->adapter;
337 	struct tsl2550_data *data;
338 	int *opmode, err = 0;
339 
340 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE
341 					    | I2C_FUNC_SMBUS_READ_BYTE_DATA)) {
342 		err = -EIO;
343 		goto exit;
344 	}
345 
346 	data = kzalloc(sizeof(struct tsl2550_data), GFP_KERNEL);
347 	if (!data) {
348 		err = -ENOMEM;
349 		goto exit;
350 	}
351 	data->client = client;
352 	i2c_set_clientdata(client, data);
353 
354 	/* Check platform data */
355 	opmode = client->dev.platform_data;
356 	if (opmode) {
357 		if (*opmode < 0 || *opmode > 1) {
358 			dev_err(&client->dev, "invalid operating_mode (%d)\n",
359 					*opmode);
360 			err = -EINVAL;
361 			goto exit_kfree;
362 		}
363 		data->operating_mode = *opmode;
364 	} else
365 		data->operating_mode = 0;	/* default mode is standard */
366 	dev_info(&client->dev, "%s operating mode\n",
367 			data->operating_mode ? "extended" : "standard");
368 
369 	mutex_init(&data->update_lock);
370 
371 	/* Initialize the TSL2550 chip */
372 	err = tsl2550_init_client(client);
373 	if (err)
374 		goto exit_kfree;
375 
376 	/* Register sysfs hooks */
377 	err = sysfs_create_group(&client->dev.kobj, &tsl2550_attr_group);
378 	if (err)
379 		goto exit_kfree;
380 
381 	dev_info(&client->dev, "support ver. %s enabled\n", DRIVER_VERSION);
382 
383 	return 0;
384 
385 exit_kfree:
386 	kfree(data);
387 exit:
388 	return err;
389 }
390 
391 static void tsl2550_remove(struct i2c_client *client)
392 {
393 	sysfs_remove_group(&client->dev.kobj, &tsl2550_attr_group);
394 
395 	/* Power down the device */
396 	tsl2550_set_power_state(client, 0);
397 
398 	kfree(i2c_get_clientdata(client));
399 }
400 
401 #ifdef CONFIG_PM_SLEEP
402 
403 static int tsl2550_suspend(struct device *dev)
404 {
405 	return tsl2550_set_power_state(to_i2c_client(dev), 0);
406 }
407 
408 static int tsl2550_resume(struct device *dev)
409 {
410 	return tsl2550_set_power_state(to_i2c_client(dev), 1);
411 }
412 
413 static SIMPLE_DEV_PM_OPS(tsl2550_pm_ops, tsl2550_suspend, tsl2550_resume);
414 #define TSL2550_PM_OPS (&tsl2550_pm_ops)
415 
416 #else
417 
418 #define TSL2550_PM_OPS NULL
419 
420 #endif /* CONFIG_PM_SLEEP */
421 
422 static const struct i2c_device_id tsl2550_id[] = {
423 	{ "tsl2550", 0 },
424 	{ }
425 };
426 MODULE_DEVICE_TABLE(i2c, tsl2550_id);
427 
428 static const struct of_device_id tsl2550_of_match[] = {
429 	{ .compatible = "taos,tsl2550" },
430 	{ }
431 };
432 MODULE_DEVICE_TABLE(of, tsl2550_of_match);
433 
434 static struct i2c_driver tsl2550_driver = {
435 	.driver = {
436 		.name	= TSL2550_DRV_NAME,
437 		.of_match_table = tsl2550_of_match,
438 		.pm	= TSL2550_PM_OPS,
439 	},
440 	.probe = tsl2550_probe,
441 	.remove	= tsl2550_remove,
442 	.id_table = tsl2550_id,
443 };
444 
445 module_i2c_driver(tsl2550_driver);
446 
447 MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
448 MODULE_DESCRIPTION("TSL2550 ambient light sensor driver");
449 MODULE_LICENSE("GPL");
450 MODULE_VERSION(DRIVER_VERSION);
451