1 /* 2 * tsl2550.c - Linux kernel modules for ambient light sensor 3 * 4 * Copyright (C) 2007 Rodolfo Giometti <giometti@linux.it> 5 * Copyright (C) 2007 Eurotech S.p.A. <info@eurotech.it> 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; 48 struct mutex update_lock; 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] = { 59 TSL2550_STANDARD_RANGE, TSL2550_EXTENDED_RANGE, 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) 83 ret = i2c_smbus_write_byte(client, TSL2550_POWER_DOWN); 84 else { 85 ret = i2c_smbus_write_byte(client, TSL2550_POWER_UP); 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 220 static DEVICE_ATTR(power_state, S_IWUSR | S_IRUGO, 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 255 static DEVICE_ATTR(operating_mode, S_IWUSR | S_IRUGO, 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 */ 329 err = i2c_smbus_read_byte_data(client, TSL2550_POWER_UP); 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 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 358 | I2C_FUNC_SMBUS_READ_BYTE_DATA)) { 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 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 = tsl2550_remove, 454 .id_table = tsl2550_id, 455 }; 456 457 module_i2c_driver(tsl2550_driver); 458 459 MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>"); 460 MODULE_DESCRIPTION("TSL2550 ambient light sensor driver"); 461 MODULE_LICENSE("GPL"); 462 MODULE_VERSION(DRIVER_VERSION); 463