bh1750.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. /*
  2. * ROHM BH1710/BH1715/BH1721/BH1750/BH1751 ambient light sensor driver
  3. *
  4. * Copyright (c) Tomasz Duszynski <tduszyns@gmail.com>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2 as
  8. * published by the Free Software Foundation.
  9. *
  10. * Data sheets:
  11. * http://rohmfs.rohm.com/en/products/databook/datasheet/ic/sensor/light/bh1710fvc-e.pdf
  12. * http://rohmfs.rohm.com/en/products/databook/datasheet/ic/sensor/light/bh1715fvc-e.pdf
  13. * http://rohmfs.rohm.com/en/products/databook/datasheet/ic/sensor/light/bh1721fvc-e.pdf
  14. * http://rohmfs.rohm.com/en/products/databook/datasheet/ic/sensor/light/bh1750fvi-e.pdf
  15. * http://rohmfs.rohm.com/en/products/databook/datasheet/ic/sensor/light/bh1751fvi-e.pdf
  16. *
  17. * 7-bit I2C slave addresses:
  18. * 0x23 (ADDR pin low)
  19. * 0x5C (ADDR pin high)
  20. *
  21. */
  22. #include <linux/delay.h>
  23. #include <linux/i2c.h>
  24. #include <linux/iio/iio.h>
  25. #include <linux/iio/sysfs.h>
  26. #include <linux/module.h>
  27. #define BH1750_POWER_DOWN 0x00
  28. #define BH1750_ONE_TIME_H_RES_MODE 0x20 /* auto-mode for BH1721 */
  29. #define BH1750_CHANGE_INT_TIME_H_BIT 0x40
  30. #define BH1750_CHANGE_INT_TIME_L_BIT 0x60
  31. enum {
  32. BH1710,
  33. BH1721,
  34. BH1750,
  35. };
  36. struct bh1750_chip_info;
  37. struct bh1750_data {
  38. struct i2c_client *client;
  39. struct mutex lock;
  40. const struct bh1750_chip_info *chip_info;
  41. u16 mtreg;
  42. };
  43. struct bh1750_chip_info {
  44. u16 mtreg_min;
  45. u16 mtreg_max;
  46. u16 mtreg_default;
  47. int mtreg_to_usec;
  48. int mtreg_to_scale;
  49. /*
  50. * For BH1710/BH1721 all possible integration time values won't fit
  51. * into one page so displaying is limited to every second one.
  52. * Note, that user can still write proper values which were not
  53. * listed.
  54. */
  55. int inc;
  56. u16 int_time_low_mask;
  57. u16 int_time_high_mask;
  58. };
  59. static const struct bh1750_chip_info bh1750_chip_info_tbl[] = {
  60. [BH1710] = { 140, 1022, 300, 400, 250000000, 2, 0x001F, 0x03E0 },
  61. [BH1721] = { 140, 1020, 300, 400, 250000000, 2, 0x0010, 0x03E0 },
  62. [BH1750] = { 31, 254, 69, 1740, 57500000, 1, 0x001F, 0x00E0 },
  63. };
  64. static int bh1750_change_int_time(struct bh1750_data *data, int usec)
  65. {
  66. int ret;
  67. u16 val;
  68. u8 regval;
  69. const struct bh1750_chip_info *chip_info = data->chip_info;
  70. if ((usec % chip_info->mtreg_to_usec) != 0)
  71. return -EINVAL;
  72. val = usec / chip_info->mtreg_to_usec;
  73. if (val < chip_info->mtreg_min || val > chip_info->mtreg_max)
  74. return -EINVAL;
  75. ret = i2c_smbus_write_byte(data->client, BH1750_POWER_DOWN);
  76. if (ret < 0)
  77. return ret;
  78. regval = (val & chip_info->int_time_high_mask) >> 5;
  79. ret = i2c_smbus_write_byte(data->client,
  80. BH1750_CHANGE_INT_TIME_H_BIT | regval);
  81. if (ret < 0)
  82. return ret;
  83. regval = val & chip_info->int_time_low_mask;
  84. ret = i2c_smbus_write_byte(data->client,
  85. BH1750_CHANGE_INT_TIME_L_BIT | regval);
  86. if (ret < 0)
  87. return ret;
  88. data->mtreg = val;
  89. return 0;
  90. }
  91. static int bh1750_read(struct bh1750_data *data, int *val)
  92. {
  93. int ret;
  94. __be16 result;
  95. const struct bh1750_chip_info *chip_info = data->chip_info;
  96. unsigned long delay = chip_info->mtreg_to_usec * data->mtreg;
  97. /*
  98. * BH1721 will enter continuous mode on receiving this command.
  99. * Note, that this eliminates need for bh1750_resume().
  100. */
  101. ret = i2c_smbus_write_byte(data->client, BH1750_ONE_TIME_H_RES_MODE);
  102. if (ret < 0)
  103. return ret;
  104. usleep_range(delay + 15000, delay + 40000);
  105. ret = i2c_master_recv(data->client, (char *)&result, 2);
  106. if (ret < 0)
  107. return ret;
  108. *val = be16_to_cpu(result);
  109. return 0;
  110. }
  111. static int bh1750_read_raw(struct iio_dev *indio_dev,
  112. struct iio_chan_spec const *chan,
  113. int *val, int *val2, long mask)
  114. {
  115. int ret, tmp;
  116. struct bh1750_data *data = iio_priv(indio_dev);
  117. const struct bh1750_chip_info *chip_info = data->chip_info;
  118. switch (mask) {
  119. case IIO_CHAN_INFO_RAW:
  120. switch (chan->type) {
  121. case IIO_LIGHT:
  122. mutex_lock(&data->lock);
  123. ret = bh1750_read(data, val);
  124. mutex_unlock(&data->lock);
  125. if (ret < 0)
  126. return ret;
  127. return IIO_VAL_INT;
  128. default:
  129. return -EINVAL;
  130. }
  131. case IIO_CHAN_INFO_SCALE:
  132. tmp = chip_info->mtreg_to_scale / data->mtreg;
  133. *val = tmp / 1000000;
  134. *val2 = tmp % 1000000;
  135. return IIO_VAL_INT_PLUS_MICRO;
  136. case IIO_CHAN_INFO_INT_TIME:
  137. *val = 0;
  138. *val2 = chip_info->mtreg_to_usec * data->mtreg;
  139. return IIO_VAL_INT_PLUS_MICRO;
  140. default:
  141. return -EINVAL;
  142. }
  143. }
  144. static int bh1750_write_raw(struct iio_dev *indio_dev,
  145. struct iio_chan_spec const *chan,
  146. int val, int val2, long mask)
  147. {
  148. int ret;
  149. struct bh1750_data *data = iio_priv(indio_dev);
  150. switch (mask) {
  151. case IIO_CHAN_INFO_INT_TIME:
  152. if (val != 0)
  153. return -EINVAL;
  154. mutex_lock(&data->lock);
  155. ret = bh1750_change_int_time(data, val2);
  156. mutex_unlock(&data->lock);
  157. return ret;
  158. default:
  159. return -EINVAL;
  160. }
  161. }
  162. static ssize_t bh1750_show_int_time_available(struct device *dev,
  163. struct device_attribute *attr, char *buf)
  164. {
  165. int i;
  166. size_t len = 0;
  167. struct bh1750_data *data = iio_priv(dev_to_iio_dev(dev));
  168. const struct bh1750_chip_info *chip_info = data->chip_info;
  169. for (i = chip_info->mtreg_min; i <= chip_info->mtreg_max; i += chip_info->inc)
  170. len += scnprintf(buf + len, PAGE_SIZE - len, "0.%06d ",
  171. chip_info->mtreg_to_usec * i);
  172. buf[len - 1] = '\n';
  173. return len;
  174. }
  175. static IIO_DEV_ATTR_INT_TIME_AVAIL(bh1750_show_int_time_available);
  176. static struct attribute *bh1750_attributes[] = {
  177. &iio_dev_attr_integration_time_available.dev_attr.attr,
  178. NULL,
  179. };
  180. static const struct attribute_group bh1750_attribute_group = {
  181. .attrs = bh1750_attributes,
  182. };
  183. static const struct iio_info bh1750_info = {
  184. .attrs = &bh1750_attribute_group,
  185. .read_raw = bh1750_read_raw,
  186. .write_raw = bh1750_write_raw,
  187. };
  188. static const struct iio_chan_spec bh1750_channels[] = {
  189. {
  190. .type = IIO_LIGHT,
  191. .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
  192. BIT(IIO_CHAN_INFO_SCALE) |
  193. BIT(IIO_CHAN_INFO_INT_TIME)
  194. }
  195. };
  196. static int bh1750_probe(struct i2c_client *client,
  197. const struct i2c_device_id *id)
  198. {
  199. int ret, usec;
  200. struct bh1750_data *data;
  201. struct iio_dev *indio_dev;
  202. if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C |
  203. I2C_FUNC_SMBUS_WRITE_BYTE))
  204. return -EOPNOTSUPP;
  205. indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
  206. if (!indio_dev)
  207. return -ENOMEM;
  208. data = iio_priv(indio_dev);
  209. i2c_set_clientdata(client, indio_dev);
  210. data->client = client;
  211. data->chip_info = &bh1750_chip_info_tbl[id->driver_data];
  212. usec = data->chip_info->mtreg_to_usec * data->chip_info->mtreg_default;
  213. ret = bh1750_change_int_time(data, usec);
  214. if (ret < 0)
  215. return ret;
  216. mutex_init(&data->lock);
  217. indio_dev->dev.parent = &client->dev;
  218. indio_dev->info = &bh1750_info;
  219. indio_dev->name = id->name;
  220. indio_dev->channels = bh1750_channels;
  221. indio_dev->num_channels = ARRAY_SIZE(bh1750_channels);
  222. indio_dev->modes = INDIO_DIRECT_MODE;
  223. return iio_device_register(indio_dev);
  224. }
  225. static int bh1750_remove(struct i2c_client *client)
  226. {
  227. struct iio_dev *indio_dev = i2c_get_clientdata(client);
  228. struct bh1750_data *data = iio_priv(indio_dev);
  229. iio_device_unregister(indio_dev);
  230. mutex_lock(&data->lock);
  231. i2c_smbus_write_byte(client, BH1750_POWER_DOWN);
  232. mutex_unlock(&data->lock);
  233. return 0;
  234. }
  235. #ifdef CONFIG_PM_SLEEP
  236. static int bh1750_suspend(struct device *dev)
  237. {
  238. int ret;
  239. struct bh1750_data *data =
  240. iio_priv(i2c_get_clientdata(to_i2c_client(dev)));
  241. /*
  242. * This is mainly for BH1721 which doesn't enter power down
  243. * mode automatically.
  244. */
  245. mutex_lock(&data->lock);
  246. ret = i2c_smbus_write_byte(data->client, BH1750_POWER_DOWN);
  247. mutex_unlock(&data->lock);
  248. return ret;
  249. }
  250. static SIMPLE_DEV_PM_OPS(bh1750_pm_ops, bh1750_suspend, NULL);
  251. #define BH1750_PM_OPS (&bh1750_pm_ops)
  252. #else
  253. #define BH1750_PM_OPS NULL
  254. #endif
  255. static const struct i2c_device_id bh1750_id[] = {
  256. { "bh1710", BH1710 },
  257. { "bh1715", BH1750 },
  258. { "bh1721", BH1721 },
  259. { "bh1750", BH1750 },
  260. { "bh1751", BH1750 },
  261. { }
  262. };
  263. MODULE_DEVICE_TABLE(i2c, bh1750_id);
  264. static struct i2c_driver bh1750_driver = {
  265. .driver = {
  266. .name = "bh1750",
  267. .pm = BH1750_PM_OPS,
  268. },
  269. .probe = bh1750_probe,
  270. .remove = bh1750_remove,
  271. .id_table = bh1750_id,
  272. };
  273. module_i2c_driver(bh1750_driver);
  274. MODULE_AUTHOR("Tomasz Duszynski <tduszyns@gmail.com>");
  275. MODULE_DESCRIPTION("ROHM BH1710/BH1715/BH1721/BH1750/BH1751 als driver");
  276. MODULE_LICENSE("GPL v2");