tsl2550.c 10.0 KB

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