isl29003.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * isl29003.c - Linux kernel module for
  4. * Intersil ISL29003 ambient light sensor
  5. *
  6. * See file:Documentation/misc-devices/isl29003.rst
  7. *
  8. * Copyright (c) 2009 Daniel Mack <daniel@caiaq.de>
  9. *
  10. * Based on code written by
  11. * Rodolfo Giometti <giometti@linux.it>
  12. * Eurotech S.p.A. <info@eurotech.it>
  13. */
  14. #include <linux/module.h>
  15. #include <linux/slab.h>
  16. #include <linux/i2c.h>
  17. #include <linux/mutex.h>
  18. #include <linux/delay.h>
  19. #define ISL29003_DRV_NAME "isl29003"
  20. #define DRIVER_VERSION "1.0"
  21. #define ISL29003_REG_COMMAND 0x00
  22. #define ISL29003_ADC_ENABLED (1 << 7)
  23. #define ISL29003_ADC_PD (1 << 6)
  24. #define ISL29003_TIMING_INT (1 << 5)
  25. #define ISL29003_MODE_SHIFT (2)
  26. #define ISL29003_MODE_MASK (0x3 << ISL29003_MODE_SHIFT)
  27. #define ISL29003_RES_SHIFT (0)
  28. #define ISL29003_RES_MASK (0x3 << ISL29003_RES_SHIFT)
  29. #define ISL29003_REG_CONTROL 0x01
  30. #define ISL29003_INT_FLG (1 << 5)
  31. #define ISL29003_RANGE_SHIFT (2)
  32. #define ISL29003_RANGE_MASK (0x3 << ISL29003_RANGE_SHIFT)
  33. #define ISL29003_INT_PERSISTS_SHIFT (0)
  34. #define ISL29003_INT_PERSISTS_MASK (0xf << ISL29003_INT_PERSISTS_SHIFT)
  35. #define ISL29003_REG_IRQ_THRESH_HI 0x02
  36. #define ISL29003_REG_IRQ_THRESH_LO 0x03
  37. #define ISL29003_REG_LSB_SENSOR 0x04
  38. #define ISL29003_REG_MSB_SENSOR 0x05
  39. #define ISL29003_REG_LSB_TIMER 0x06
  40. #define ISL29003_REG_MSB_TIMER 0x07
  41. #define ISL29003_NUM_CACHABLE_REGS 4
  42. struct isl29003_data {
  43. struct i2c_client *client;
  44. struct mutex lock;
  45. u8 reg_cache[ISL29003_NUM_CACHABLE_REGS];
  46. u8 power_state_before_suspend;
  47. };
  48. static int gain_range[] = {
  49. 1000, 4000, 16000, 64000
  50. };
  51. /*
  52. * register access helpers
  53. */
  54. static int __isl29003_read_reg(struct i2c_client *client,
  55. u32 reg, u8 mask, u8 shift)
  56. {
  57. struct isl29003_data *data = i2c_get_clientdata(client);
  58. return (data->reg_cache[reg] & mask) >> shift;
  59. }
  60. static int __isl29003_write_reg(struct i2c_client *client,
  61. u32 reg, u8 mask, u8 shift, u8 val)
  62. {
  63. struct isl29003_data *data = i2c_get_clientdata(client);
  64. int ret = 0;
  65. u8 tmp;
  66. if (reg >= ISL29003_NUM_CACHABLE_REGS)
  67. return -EINVAL;
  68. mutex_lock(&data->lock);
  69. tmp = data->reg_cache[reg];
  70. tmp &= ~mask;
  71. tmp |= val << shift;
  72. ret = i2c_smbus_write_byte_data(client, reg, tmp);
  73. if (!ret)
  74. data->reg_cache[reg] = tmp;
  75. mutex_unlock(&data->lock);
  76. return ret;
  77. }
  78. /*
  79. * internally used functions
  80. */
  81. /* range */
  82. static int isl29003_get_range(struct i2c_client *client)
  83. {
  84. return __isl29003_read_reg(client, ISL29003_REG_CONTROL,
  85. ISL29003_RANGE_MASK, ISL29003_RANGE_SHIFT);
  86. }
  87. static int isl29003_set_range(struct i2c_client *client, int range)
  88. {
  89. return __isl29003_write_reg(client, ISL29003_REG_CONTROL,
  90. ISL29003_RANGE_MASK, ISL29003_RANGE_SHIFT, range);
  91. }
  92. /* resolution */
  93. static int isl29003_get_resolution(struct i2c_client *client)
  94. {
  95. return __isl29003_read_reg(client, ISL29003_REG_COMMAND,
  96. ISL29003_RES_MASK, ISL29003_RES_SHIFT);
  97. }
  98. static int isl29003_set_resolution(struct i2c_client *client, int res)
  99. {
  100. return __isl29003_write_reg(client, ISL29003_REG_COMMAND,
  101. ISL29003_RES_MASK, ISL29003_RES_SHIFT, res);
  102. }
  103. /* mode */
  104. static int isl29003_get_mode(struct i2c_client *client)
  105. {
  106. return __isl29003_read_reg(client, ISL29003_REG_COMMAND,
  107. ISL29003_RES_MASK, ISL29003_RES_SHIFT);
  108. }
  109. static int isl29003_set_mode(struct i2c_client *client, int mode)
  110. {
  111. return __isl29003_write_reg(client, ISL29003_REG_COMMAND,
  112. ISL29003_RES_MASK, ISL29003_RES_SHIFT, mode);
  113. }
  114. /* power_state */
  115. static int isl29003_set_power_state(struct i2c_client *client, int state)
  116. {
  117. return __isl29003_write_reg(client, ISL29003_REG_COMMAND,
  118. ISL29003_ADC_ENABLED | ISL29003_ADC_PD, 0,
  119. state ? ISL29003_ADC_ENABLED : ISL29003_ADC_PD);
  120. }
  121. static int isl29003_get_power_state(struct i2c_client *client)
  122. {
  123. struct isl29003_data *data = i2c_get_clientdata(client);
  124. u8 cmdreg = data->reg_cache[ISL29003_REG_COMMAND];
  125. return ~cmdreg & ISL29003_ADC_PD;
  126. }
  127. static int isl29003_get_adc_value(struct i2c_client *client)
  128. {
  129. struct isl29003_data *data = i2c_get_clientdata(client);
  130. int lsb, msb, range, bitdepth;
  131. mutex_lock(&data->lock);
  132. lsb = i2c_smbus_read_byte_data(client, ISL29003_REG_LSB_SENSOR);
  133. if (lsb < 0) {
  134. mutex_unlock(&data->lock);
  135. return lsb;
  136. }
  137. msb = i2c_smbus_read_byte_data(client, ISL29003_REG_MSB_SENSOR);
  138. mutex_unlock(&data->lock);
  139. if (msb < 0)
  140. return msb;
  141. range = isl29003_get_range(client);
  142. bitdepth = (4 - isl29003_get_resolution(client)) * 4;
  143. return (((msb << 8) | lsb) * gain_range[range]) >> bitdepth;
  144. }
  145. /*
  146. * sysfs layer
  147. */
  148. /* range */
  149. static ssize_t isl29003_show_range(struct device *dev,
  150. struct device_attribute *attr, char *buf)
  151. {
  152. struct i2c_client *client = to_i2c_client(dev);
  153. return sprintf(buf, "%i\n", isl29003_get_range(client));
  154. }
  155. static ssize_t isl29003_store_range(struct device *dev,
  156. struct device_attribute *attr,
  157. const char *buf, size_t count)
  158. {
  159. struct i2c_client *client = to_i2c_client(dev);
  160. unsigned long val;
  161. int ret;
  162. ret = kstrtoul(buf, 10, &val);
  163. if (ret)
  164. return ret;
  165. if (val > 3)
  166. return -EINVAL;
  167. ret = isl29003_set_range(client, val);
  168. if (ret < 0)
  169. return ret;
  170. return count;
  171. }
  172. static DEVICE_ATTR(range, S_IWUSR | S_IRUGO,
  173. isl29003_show_range, isl29003_store_range);
  174. /* resolution */
  175. static ssize_t isl29003_show_resolution(struct device *dev,
  176. struct device_attribute *attr,
  177. char *buf)
  178. {
  179. struct i2c_client *client = to_i2c_client(dev);
  180. return sprintf(buf, "%d\n", isl29003_get_resolution(client));
  181. }
  182. static ssize_t isl29003_store_resolution(struct device *dev,
  183. struct device_attribute *attr,
  184. const char *buf, size_t count)
  185. {
  186. struct i2c_client *client = to_i2c_client(dev);
  187. unsigned long val;
  188. int ret;
  189. ret = kstrtoul(buf, 10, &val);
  190. if (ret)
  191. return ret;
  192. if (val > 3)
  193. return -EINVAL;
  194. ret = isl29003_set_resolution(client, val);
  195. if (ret < 0)
  196. return ret;
  197. return count;
  198. }
  199. static DEVICE_ATTR(resolution, S_IWUSR | S_IRUGO,
  200. isl29003_show_resolution, isl29003_store_resolution);
  201. /* mode */
  202. static ssize_t isl29003_show_mode(struct device *dev,
  203. struct device_attribute *attr, char *buf)
  204. {
  205. struct i2c_client *client = to_i2c_client(dev);
  206. return sprintf(buf, "%d\n", isl29003_get_mode(client));
  207. }
  208. static ssize_t isl29003_store_mode(struct device *dev,
  209. struct device_attribute *attr, const char *buf, size_t count)
  210. {
  211. struct i2c_client *client = to_i2c_client(dev);
  212. unsigned long val;
  213. int ret;
  214. ret = kstrtoul(buf, 10, &val);
  215. if (ret)
  216. return ret;
  217. if (val > 2)
  218. return -EINVAL;
  219. ret = isl29003_set_mode(client, val);
  220. if (ret < 0)
  221. return ret;
  222. return count;
  223. }
  224. static DEVICE_ATTR(mode, S_IWUSR | S_IRUGO,
  225. isl29003_show_mode, isl29003_store_mode);
  226. /* power state */
  227. static ssize_t isl29003_show_power_state(struct device *dev,
  228. struct device_attribute *attr,
  229. char *buf)
  230. {
  231. struct i2c_client *client = to_i2c_client(dev);
  232. return sprintf(buf, "%d\n", isl29003_get_power_state(client));
  233. }
  234. static ssize_t isl29003_store_power_state(struct device *dev,
  235. struct device_attribute *attr,
  236. const char *buf, size_t count)
  237. {
  238. struct i2c_client *client = to_i2c_client(dev);
  239. unsigned long val;
  240. int ret;
  241. ret = kstrtoul(buf, 10, &val);
  242. if (ret)
  243. return ret;
  244. if (val > 1)
  245. return -EINVAL;
  246. ret = isl29003_set_power_state(client, val);
  247. return ret ? ret : count;
  248. }
  249. static DEVICE_ATTR(power_state, S_IWUSR | S_IRUGO,
  250. isl29003_show_power_state, isl29003_store_power_state);
  251. /* lux */
  252. static ssize_t isl29003_show_lux(struct device *dev,
  253. struct device_attribute *attr, char *buf)
  254. {
  255. struct i2c_client *client = to_i2c_client(dev);
  256. /* No LUX data if not operational */
  257. if (!isl29003_get_power_state(client))
  258. return -EBUSY;
  259. return sprintf(buf, "%d\n", isl29003_get_adc_value(client));
  260. }
  261. static DEVICE_ATTR(lux, S_IRUGO, isl29003_show_lux, NULL);
  262. static struct attribute *isl29003_attributes[] = {
  263. &dev_attr_range.attr,
  264. &dev_attr_resolution.attr,
  265. &dev_attr_mode.attr,
  266. &dev_attr_power_state.attr,
  267. &dev_attr_lux.attr,
  268. NULL
  269. };
  270. static const struct attribute_group isl29003_attr_group = {
  271. .attrs = isl29003_attributes,
  272. };
  273. static int isl29003_init_client(struct i2c_client *client)
  274. {
  275. struct isl29003_data *data = i2c_get_clientdata(client);
  276. int i;
  277. /* read all the registers once to fill the cache.
  278. * if one of the reads fails, we consider the init failed */
  279. for (i = 0; i < ARRAY_SIZE(data->reg_cache); i++) {
  280. int v = i2c_smbus_read_byte_data(client, i);
  281. if (v < 0)
  282. return -ENODEV;
  283. data->reg_cache[i] = v;
  284. }
  285. /* set defaults */
  286. isl29003_set_range(client, 0);
  287. isl29003_set_resolution(client, 0);
  288. isl29003_set_mode(client, 0);
  289. isl29003_set_power_state(client, 0);
  290. return 0;
  291. }
  292. /*
  293. * I2C layer
  294. */
  295. static int isl29003_probe(struct i2c_client *client,
  296. const struct i2c_device_id *id)
  297. {
  298. struct i2c_adapter *adapter = client->adapter;
  299. struct isl29003_data *data;
  300. int err = 0;
  301. if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE))
  302. return -EIO;
  303. data = kzalloc(sizeof(struct isl29003_data), GFP_KERNEL);
  304. if (!data)
  305. return -ENOMEM;
  306. data->client = client;
  307. i2c_set_clientdata(client, data);
  308. mutex_init(&data->lock);
  309. /* initialize the ISL29003 chip */
  310. err = isl29003_init_client(client);
  311. if (err)
  312. goto exit_kfree;
  313. /* register sysfs hooks */
  314. err = sysfs_create_group(&client->dev.kobj, &isl29003_attr_group);
  315. if (err)
  316. goto exit_kfree;
  317. dev_info(&client->dev, "driver version %s enabled\n", DRIVER_VERSION);
  318. return 0;
  319. exit_kfree:
  320. kfree(data);
  321. return err;
  322. }
  323. static int isl29003_remove(struct i2c_client *client)
  324. {
  325. sysfs_remove_group(&client->dev.kobj, &isl29003_attr_group);
  326. isl29003_set_power_state(client, 0);
  327. kfree(i2c_get_clientdata(client));
  328. return 0;
  329. }
  330. #ifdef CONFIG_PM_SLEEP
  331. static int isl29003_suspend(struct device *dev)
  332. {
  333. struct i2c_client *client = to_i2c_client(dev);
  334. struct isl29003_data *data = i2c_get_clientdata(client);
  335. data->power_state_before_suspend = isl29003_get_power_state(client);
  336. return isl29003_set_power_state(client, 0);
  337. }
  338. static int isl29003_resume(struct device *dev)
  339. {
  340. int i;
  341. struct i2c_client *client = to_i2c_client(dev);
  342. struct isl29003_data *data = i2c_get_clientdata(client);
  343. /* restore registers from cache */
  344. for (i = 0; i < ARRAY_SIZE(data->reg_cache); i++)
  345. if (i2c_smbus_write_byte_data(client, i, data->reg_cache[i]))
  346. return -EIO;
  347. return isl29003_set_power_state(client,
  348. data->power_state_before_suspend);
  349. }
  350. static SIMPLE_DEV_PM_OPS(isl29003_pm_ops, isl29003_suspend, isl29003_resume);
  351. #define ISL29003_PM_OPS (&isl29003_pm_ops)
  352. #else
  353. #define ISL29003_PM_OPS NULL
  354. #endif /* CONFIG_PM_SLEEP */
  355. static const struct i2c_device_id isl29003_id[] = {
  356. { "isl29003", 0 },
  357. {}
  358. };
  359. MODULE_DEVICE_TABLE(i2c, isl29003_id);
  360. static struct i2c_driver isl29003_driver = {
  361. .driver = {
  362. .name = ISL29003_DRV_NAME,
  363. .pm = ISL29003_PM_OPS,
  364. },
  365. .probe = isl29003_probe,
  366. .remove = isl29003_remove,
  367. .id_table = isl29003_id,
  368. };
  369. module_i2c_driver(isl29003_driver);
  370. MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
  371. MODULE_DESCRIPTION("ISL29003 ambient light sensor driver");
  372. MODULE_LICENSE("GPL v2");
  373. MODULE_VERSION(DRIVER_VERSION);