Linux-libre 5.3.12-gnu
[librecmc/linux-libre.git] / drivers / misc / tsl2550.c
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         /*
152          * Calculate ratio.
153          * Note: the "128" is a scaling factor
154          */
155         u8 r = 128;
156
157         /* Avoid division by 0 and count 1 cannot be greater than count 0 */
158         if (c1 <= c0)
159                 if (c0) {
160                         r = c1 * 128 / c0;
161
162                         /* Calculate LUX */
163                         lux = ((c0 - c1) * ratio_lut[r]) / 256;
164                 } else
165                         lux = 0;
166         else
167                 return 0;
168
169         /* LUX range check */
170         return lux > TSL2550_MAX_LUX ? TSL2550_MAX_LUX : lux;
171 }
172
173 /*
174  * SysFS support
175  */
176
177 static ssize_t tsl2550_show_power_state(struct device *dev,
178                 struct device_attribute *attr, char *buf)
179 {
180         struct tsl2550_data *data = i2c_get_clientdata(to_i2c_client(dev));
181
182         return sprintf(buf, "%u\n", data->power_state);
183 }
184
185 static ssize_t tsl2550_store_power_state(struct device *dev,
186                 struct device_attribute *attr, const char *buf, size_t count)
187 {
188         struct i2c_client *client = to_i2c_client(dev);
189         struct tsl2550_data *data = i2c_get_clientdata(client);
190         unsigned long val = simple_strtoul(buf, NULL, 10);
191         int ret;
192
193         if (val > 1)
194                 return -EINVAL;
195
196         mutex_lock(&data->update_lock);
197         ret = tsl2550_set_power_state(client, val);
198         mutex_unlock(&data->update_lock);
199
200         if (ret < 0)
201                 return ret;
202
203         return count;
204 }
205
206 static DEVICE_ATTR(power_state, S_IWUSR | S_IRUGO,
207                    tsl2550_show_power_state, tsl2550_store_power_state);
208
209 static ssize_t tsl2550_show_operating_mode(struct device *dev,
210                 struct device_attribute *attr, char *buf)
211 {
212         struct tsl2550_data *data = i2c_get_clientdata(to_i2c_client(dev));
213
214         return sprintf(buf, "%u\n", data->operating_mode);
215 }
216
217 static ssize_t tsl2550_store_operating_mode(struct device *dev,
218                 struct device_attribute *attr, const char *buf, size_t count)
219 {
220         struct i2c_client *client = to_i2c_client(dev);
221         struct tsl2550_data *data = i2c_get_clientdata(client);
222         unsigned long val = simple_strtoul(buf, NULL, 10);
223         int ret;
224
225         if (val > 1)
226                 return -EINVAL;
227
228         if (data->power_state == 0)
229                 return -EBUSY;
230
231         mutex_lock(&data->update_lock);
232         ret = tsl2550_set_operating_mode(client, val);
233         mutex_unlock(&data->update_lock);
234
235         if (ret < 0)
236                 return ret;
237
238         return count;
239 }
240
241 static DEVICE_ATTR(operating_mode, S_IWUSR | S_IRUGO,
242                    tsl2550_show_operating_mode, tsl2550_store_operating_mode);
243
244 static ssize_t __tsl2550_show_lux(struct i2c_client *client, char *buf)
245 {
246         struct tsl2550_data *data = i2c_get_clientdata(client);
247         u8 ch0, ch1;
248         int ret;
249
250         ret = tsl2550_get_adc_value(client, TSL2550_READ_ADC0);
251         if (ret < 0)
252                 return ret;
253         ch0 = ret;
254
255         ret = tsl2550_get_adc_value(client, TSL2550_READ_ADC1);
256         if (ret < 0)
257                 return ret;
258         ch1 = ret;
259
260         /* Do the job */
261         ret = tsl2550_calculate_lux(ch0, ch1);
262         if (ret < 0)
263                 return ret;
264         if (data->operating_mode == 1)
265                 ret *= 5;
266
267         return sprintf(buf, "%d\n", ret);
268 }
269
270 static ssize_t tsl2550_show_lux1_input(struct device *dev,
271                         struct device_attribute *attr, char *buf)
272 {
273         struct i2c_client *client = to_i2c_client(dev);
274         struct tsl2550_data *data = i2c_get_clientdata(client);
275         int ret;
276
277         /* No LUX data if not operational */
278         if (!data->power_state)
279                 return -EBUSY;
280
281         mutex_lock(&data->update_lock);
282         ret = __tsl2550_show_lux(client, buf);
283         mutex_unlock(&data->update_lock);
284
285         return ret;
286 }
287
288 static DEVICE_ATTR(lux1_input, S_IRUGO,
289                    tsl2550_show_lux1_input, NULL);
290
291 static struct attribute *tsl2550_attributes[] = {
292         &dev_attr_power_state.attr,
293         &dev_attr_operating_mode.attr,
294         &dev_attr_lux1_input.attr,
295         NULL
296 };
297
298 static const struct attribute_group tsl2550_attr_group = {
299         .attrs = tsl2550_attributes,
300 };
301
302 /*
303  * Initialization function
304  */
305
306 static int tsl2550_init_client(struct i2c_client *client)
307 {
308         struct tsl2550_data *data = i2c_get_clientdata(client);
309         int err;
310
311         /*
312          * Probe the chip. To do so we try to power up the device and then to
313          * read back the 0x03 code
314          */
315         err = i2c_smbus_read_byte_data(client, TSL2550_POWER_UP);
316         if (err < 0)
317                 return err;
318         if (err != TSL2550_POWER_UP)
319                 return -ENODEV;
320         data->power_state = 1;
321
322         /* Set the default operating mode */
323         err = i2c_smbus_write_byte(client,
324                                    TSL2550_MODE_RANGE[data->operating_mode]);
325         if (err < 0)
326                 return err;
327
328         return 0;
329 }
330
331 /*
332  * I2C init/probing/exit functions
333  */
334
335 static struct i2c_driver tsl2550_driver;
336 static int tsl2550_probe(struct i2c_client *client,
337                                    const struct i2c_device_id *id)
338 {
339         struct i2c_adapter *adapter = client->adapter;
340         struct tsl2550_data *data;
341         int *opmode, err = 0;
342
343         if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WRITE_BYTE
344                                             | I2C_FUNC_SMBUS_READ_BYTE_DATA)) {
345                 err = -EIO;
346                 goto exit;
347         }
348
349         data = kzalloc(sizeof(struct tsl2550_data), GFP_KERNEL);
350         if (!data) {
351                 err = -ENOMEM;
352                 goto exit;
353         }
354         data->client = client;
355         i2c_set_clientdata(client, data);
356
357         /* Check platform data */
358         opmode = client->dev.platform_data;
359         if (opmode) {
360                 if (*opmode < 0 || *opmode > 1) {
361                         dev_err(&client->dev, "invalid operating_mode (%d)\n",
362                                         *opmode);
363                         err = -EINVAL;
364                         goto exit_kfree;
365                 }
366                 data->operating_mode = *opmode;
367         } else
368                 data->operating_mode = 0;       /* default mode is standard */
369         dev_info(&client->dev, "%s operating mode\n",
370                         data->operating_mode ? "extended" : "standard");
371
372         mutex_init(&data->update_lock);
373
374         /* Initialize the TSL2550 chip */
375         err = tsl2550_init_client(client);
376         if (err)
377                 goto exit_kfree;
378
379         /* Register sysfs hooks */
380         err = sysfs_create_group(&client->dev.kobj, &tsl2550_attr_group);
381         if (err)
382                 goto exit_kfree;
383
384         dev_info(&client->dev, "support ver. %s enabled\n", DRIVER_VERSION);
385
386         return 0;
387
388 exit_kfree:
389         kfree(data);
390 exit:
391         return err;
392 }
393
394 static int tsl2550_remove(struct i2c_client *client)
395 {
396         sysfs_remove_group(&client->dev.kobj, &tsl2550_attr_group);
397
398         /* Power down the device */
399         tsl2550_set_power_state(client, 0);
400
401         kfree(i2c_get_clientdata(client));
402
403         return 0;
404 }
405
406 #ifdef CONFIG_PM_SLEEP
407
408 static int tsl2550_suspend(struct device *dev)
409 {
410         return tsl2550_set_power_state(to_i2c_client(dev), 0);
411 }
412
413 static int tsl2550_resume(struct device *dev)
414 {
415         return tsl2550_set_power_state(to_i2c_client(dev), 1);
416 }
417
418 static SIMPLE_DEV_PM_OPS(tsl2550_pm_ops, tsl2550_suspend, tsl2550_resume);
419 #define TSL2550_PM_OPS (&tsl2550_pm_ops)
420
421 #else
422
423 #define TSL2550_PM_OPS NULL
424
425 #endif /* CONFIG_PM_SLEEP */
426
427 static const struct i2c_device_id tsl2550_id[] = {
428         { "tsl2550", 0 },
429         { }
430 };
431 MODULE_DEVICE_TABLE(i2c, tsl2550_id);
432
433 static const struct of_device_id tsl2550_of_match[] = {
434         { .compatible = "taos,tsl2550" },
435         { }
436 };
437 MODULE_DEVICE_TABLE(of, tsl2550_of_match);
438
439 static struct i2c_driver tsl2550_driver = {
440         .driver = {
441                 .name   = TSL2550_DRV_NAME,
442                 .of_match_table = tsl2550_of_match,
443                 .pm     = TSL2550_PM_OPS,
444         },
445         .probe  = tsl2550_probe,
446         .remove = tsl2550_remove,
447         .id_table = tsl2550_id,
448 };
449
450 module_i2c_driver(tsl2550_driver);
451
452 MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
453 MODULE_DESCRIPTION("TSL2550 ambient light sensor driver");
454 MODULE_LICENSE("GPL");
455 MODULE_VERSION(DRIVER_VERSION);