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