bh1745.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * ROHM BH1745 digital colour sensor driver
  4. *
  5. * Copyright (C) Mudit Sharma <muditsharma.info@gmail.com>
  6. *
  7. * 7-bit I2C slave addresses:
  8. * 0x38 (ADDR pin low)
  9. * 0x39 (ADDR pin high)
  10. */
  11. #include <linux/i2c.h>
  12. #include <linux/mutex.h>
  13. #include <linux/util_macros.h>
  14. #include <linux/iio/events.h>
  15. #include <linux/regmap.h>
  16. #include <linux/bits.h>
  17. #include <linux/bitfield.h>
  18. #include <linux/iio/iio.h>
  19. #include <linux/iio/sysfs.h>
  20. #include <linux/iio/trigger.h>
  21. #include <linux/iio/trigger_consumer.h>
  22. #include <linux/iio/triggered_buffer.h>
  23. #include <linux/iio/iio-gts-helper.h>
  24. /* BH1745 configuration registers */
  25. /* System control */
  26. #define BH1745_SYS_CTRL 0x40
  27. #define BH1745_SYS_CTRL_SW_RESET BIT(7)
  28. #define BH1745_SYS_CTRL_INTR_RESET BIT(6)
  29. #define BH1745_SYS_CTRL_PART_ID_MASK GENMASK(5, 0)
  30. #define BH1745_PART_ID 0x0B
  31. /* Mode control 1 */
  32. #define BH1745_MODE_CTRL1 0x41
  33. #define BH1745_CTRL1_MEASUREMENT_TIME_MASK GENMASK(2, 0)
  34. /* Mode control 2 */
  35. #define BH1745_MODE_CTRL2 0x42
  36. #define BH1745_CTRL2_RGBC_EN BIT(4)
  37. #define BH1745_CTRL2_ADC_GAIN_MASK GENMASK(1, 0)
  38. /* Interrupt */
  39. #define BH1745_INTR 0x60
  40. #define BH1745_INTR_STATUS BIT(7)
  41. #define BH1745_INTR_SOURCE_MASK GENMASK(3, 2)
  42. #define BH1745_INTR_ENABLE BIT(0)
  43. #define BH1745_PERSISTENCE 0x61
  44. /* Threshold high */
  45. #define BH1745_TH_LSB 0x62
  46. #define BH1745_TH_MSB 0x63
  47. /* Threshold low */
  48. #define BH1745_TL_LSB 0x64
  49. #define BH1745_TL_MSB 0x65
  50. /* BH1745 data output regs */
  51. #define BH1745_RED_LSB 0x50
  52. #define BH1745_RED_MSB 0x51
  53. #define BH1745_GREEN_LSB 0x52
  54. #define BH1745_GREEN_MSB 0x53
  55. #define BH1745_BLUE_LSB 0x54
  56. #define BH1745_BLUE_MSB 0x55
  57. #define BH1745_CLEAR_LSB 0x56
  58. #define BH1745_CLEAR_MSB 0x57
  59. #define BH1745_MANU_ID_REG 0x92
  60. /* From 16x max HW gain and 32x max integration time */
  61. #define BH1745_MAX_GAIN 512
  62. enum bh1745_int_source {
  63. BH1745_INTR_SOURCE_RED,
  64. BH1745_INTR_SOURCE_GREEN,
  65. BH1745_INTR_SOURCE_BLUE,
  66. BH1745_INTR_SOURCE_CLEAR,
  67. };
  68. enum bh1745_gain {
  69. BH1745_ADC_GAIN_1X,
  70. BH1745_ADC_GAIN_2X,
  71. BH1745_ADC_GAIN_16X,
  72. };
  73. enum bh1745_measurement_time {
  74. BH1745_MEASUREMENT_TIME_160MS,
  75. BH1745_MEASUREMENT_TIME_320MS,
  76. BH1745_MEASUREMENT_TIME_640MS,
  77. BH1745_MEASUREMENT_TIME_1280MS,
  78. BH1745_MEASUREMENT_TIME_2560MS,
  79. BH1745_MEASUREMENT_TIME_5120MS,
  80. };
  81. enum bh1745_presistence_value {
  82. BH1745_PRESISTENCE_UPDATE_TOGGLE,
  83. BH1745_PRESISTENCE_UPDATE_EACH_MEASUREMENT,
  84. BH1745_PRESISTENCE_UPDATE_FOUR_MEASUREMENT,
  85. BH1745_PRESISTENCE_UPDATE_EIGHT_MEASUREMENT,
  86. };
  87. static const struct iio_gain_sel_pair bh1745_gain[] = {
  88. GAIN_SCALE_GAIN(1, BH1745_ADC_GAIN_1X),
  89. GAIN_SCALE_GAIN(2, BH1745_ADC_GAIN_2X),
  90. GAIN_SCALE_GAIN(16, BH1745_ADC_GAIN_16X),
  91. };
  92. static const struct iio_itime_sel_mul bh1745_itimes[] = {
  93. GAIN_SCALE_ITIME_US(5120000, BH1745_MEASUREMENT_TIME_5120MS, 32),
  94. GAIN_SCALE_ITIME_US(2560000, BH1745_MEASUREMENT_TIME_2560MS, 16),
  95. GAIN_SCALE_ITIME_US(1280000, BH1745_MEASUREMENT_TIME_1280MS, 8),
  96. GAIN_SCALE_ITIME_US(640000, BH1745_MEASUREMENT_TIME_640MS, 4),
  97. GAIN_SCALE_ITIME_US(320000, BH1745_MEASUREMENT_TIME_320MS, 2),
  98. GAIN_SCALE_ITIME_US(160000, BH1745_MEASUREMENT_TIME_160MS, 1),
  99. };
  100. struct bh1745_data {
  101. /*
  102. * Lock to prevent device setting update or read before
  103. * related calculations are completed
  104. */
  105. struct mutex lock;
  106. struct regmap *regmap;
  107. struct device *dev;
  108. struct iio_trigger *trig;
  109. struct iio_gts gts;
  110. };
  111. static const struct regmap_range bh1745_volatile_ranges[] = {
  112. regmap_reg_range(BH1745_MODE_CTRL2, BH1745_MODE_CTRL2), /* VALID */
  113. regmap_reg_range(BH1745_RED_LSB, BH1745_CLEAR_MSB), /* Data */
  114. regmap_reg_range(BH1745_INTR, BH1745_INTR), /* Interrupt */
  115. };
  116. static const struct regmap_access_table bh1745_volatile_regs = {
  117. .yes_ranges = bh1745_volatile_ranges,
  118. .n_yes_ranges = ARRAY_SIZE(bh1745_volatile_ranges),
  119. };
  120. static const struct regmap_range bh1745_readable_ranges[] = {
  121. regmap_reg_range(BH1745_SYS_CTRL, BH1745_MODE_CTRL2),
  122. regmap_reg_range(BH1745_RED_LSB, BH1745_CLEAR_MSB),
  123. regmap_reg_range(BH1745_INTR, BH1745_INTR),
  124. regmap_reg_range(BH1745_PERSISTENCE, BH1745_TL_MSB),
  125. regmap_reg_range(BH1745_MANU_ID_REG, BH1745_MANU_ID_REG),
  126. };
  127. static const struct regmap_access_table bh1745_readable_regs = {
  128. .yes_ranges = bh1745_readable_ranges,
  129. .n_yes_ranges = ARRAY_SIZE(bh1745_readable_ranges),
  130. };
  131. static const struct regmap_range bh1745_writable_ranges[] = {
  132. regmap_reg_range(BH1745_SYS_CTRL, BH1745_MODE_CTRL2),
  133. regmap_reg_range(BH1745_INTR, BH1745_INTR),
  134. regmap_reg_range(BH1745_PERSISTENCE, BH1745_TL_MSB),
  135. };
  136. static const struct regmap_access_table bh1745_writable_regs = {
  137. .yes_ranges = bh1745_writable_ranges,
  138. .n_yes_ranges = ARRAY_SIZE(bh1745_writable_ranges),
  139. };
  140. static const struct regmap_config bh1745_regmap = {
  141. .reg_bits = 8,
  142. .val_bits = 8,
  143. .max_register = BH1745_MANU_ID_REG,
  144. .cache_type = REGCACHE_RBTREE,
  145. .volatile_table = &bh1745_volatile_regs,
  146. .wr_table = &bh1745_writable_regs,
  147. .rd_table = &bh1745_readable_regs,
  148. };
  149. static const struct iio_event_spec bh1745_event_spec[] = {
  150. {
  151. .type = IIO_EV_TYPE_THRESH,
  152. .dir = IIO_EV_DIR_RISING,
  153. .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE),
  154. },
  155. {
  156. .type = IIO_EV_TYPE_THRESH,
  157. .dir = IIO_EV_DIR_FALLING,
  158. .mask_shared_by_type = BIT(IIO_EV_INFO_VALUE),
  159. },
  160. {
  161. .type = IIO_EV_TYPE_THRESH,
  162. .dir = IIO_EV_DIR_EITHER,
  163. .mask_shared_by_type = BIT(IIO_EV_INFO_PERIOD),
  164. .mask_separate = BIT(IIO_EV_INFO_ENABLE),
  165. },
  166. };
  167. #define BH1745_CHANNEL(_colour, _si, _addr) \
  168. { \
  169. .type = IIO_INTENSITY, .modified = 1, \
  170. .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
  171. .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_SCALE) | \
  172. BIT(IIO_CHAN_INFO_INT_TIME), \
  173. .info_mask_shared_by_all_available = \
  174. BIT(IIO_CHAN_INFO_SCALE) | \
  175. BIT(IIO_CHAN_INFO_INT_TIME), \
  176. .event_spec = bh1745_event_spec, \
  177. .num_event_specs = ARRAY_SIZE(bh1745_event_spec), \
  178. .channel2 = IIO_MOD_LIGHT_##_colour, .address = _addr, \
  179. .scan_index = _si, \
  180. .scan_type = { \
  181. .sign = 'u', \
  182. .realbits = 16, \
  183. .storagebits = 16, \
  184. .endianness = IIO_CPU, \
  185. }, \
  186. }
  187. static const struct iio_chan_spec bh1745_channels[] = {
  188. BH1745_CHANNEL(RED, 0, BH1745_RED_LSB),
  189. BH1745_CHANNEL(GREEN, 1, BH1745_GREEN_LSB),
  190. BH1745_CHANNEL(BLUE, 2, BH1745_BLUE_LSB),
  191. BH1745_CHANNEL(CLEAR, 3, BH1745_CLEAR_LSB),
  192. IIO_CHAN_SOFT_TIMESTAMP(4),
  193. };
  194. static int bh1745_reset(struct bh1745_data *data)
  195. {
  196. return regmap_set_bits(data->regmap, BH1745_SYS_CTRL,
  197. BH1745_SYS_CTRL_SW_RESET |
  198. BH1745_SYS_CTRL_INTR_RESET);
  199. }
  200. static int bh1745_power_on(struct bh1745_data *data)
  201. {
  202. return regmap_set_bits(data->regmap, BH1745_MODE_CTRL2,
  203. BH1745_CTRL2_RGBC_EN);
  204. }
  205. static void bh1745_power_off(void *data_ptr)
  206. {
  207. struct bh1745_data *data = data_ptr;
  208. struct device *dev = data->dev;
  209. int ret;
  210. ret = regmap_clear_bits(data->regmap, BH1745_MODE_CTRL2,
  211. BH1745_CTRL2_RGBC_EN);
  212. if (ret)
  213. dev_err(dev, "Failed to turn off device\n");
  214. }
  215. static int bh1745_get_scale(struct bh1745_data *data, int *val, int *val2)
  216. {
  217. int ret;
  218. int value;
  219. int gain_sel, int_time_sel;
  220. int gain;
  221. const struct iio_itime_sel_mul *int_time;
  222. ret = regmap_read(data->regmap, BH1745_MODE_CTRL2, &value);
  223. if (ret)
  224. return ret;
  225. gain_sel = FIELD_GET(BH1745_CTRL2_ADC_GAIN_MASK, value);
  226. gain = iio_gts_find_gain_by_sel(&data->gts, gain_sel);
  227. ret = regmap_read(data->regmap, BH1745_MODE_CTRL1, &value);
  228. if (ret)
  229. return ret;
  230. int_time_sel = FIELD_GET(BH1745_CTRL1_MEASUREMENT_TIME_MASK, value);
  231. int_time = iio_gts_find_itime_by_sel(&data->gts, int_time_sel);
  232. return iio_gts_get_scale(&data->gts, gain, int_time->time_us, val,
  233. val2);
  234. }
  235. static int bh1745_set_scale(struct bh1745_data *data, int val)
  236. {
  237. struct device *dev = data->dev;
  238. int ret;
  239. int value;
  240. int hw_gain_sel, current_int_time_sel, new_int_time_sel;
  241. ret = regmap_read(data->regmap, BH1745_MODE_CTRL1, &value);
  242. if (ret)
  243. return ret;
  244. current_int_time_sel = FIELD_GET(BH1745_CTRL1_MEASUREMENT_TIME_MASK,
  245. value);
  246. ret = iio_gts_find_gain_sel_for_scale_using_time(&data->gts,
  247. current_int_time_sel,
  248. val, 0, &hw_gain_sel);
  249. if (ret) {
  250. for (int i = 0; i < data->gts.num_itime; i++) {
  251. new_int_time_sel = data->gts.itime_table[i].sel;
  252. if (new_int_time_sel == current_int_time_sel)
  253. continue;
  254. ret = iio_gts_find_gain_sel_for_scale_using_time(&data->gts,
  255. new_int_time_sel,
  256. val, 0,
  257. &hw_gain_sel);
  258. if (!ret)
  259. break;
  260. }
  261. if (ret) {
  262. dev_dbg(dev, "Unsupported scale value requested: %d\n",
  263. val);
  264. return -EINVAL;
  265. }
  266. ret = regmap_write_bits(data->regmap, BH1745_MODE_CTRL1,
  267. BH1745_CTRL1_MEASUREMENT_TIME_MASK,
  268. new_int_time_sel);
  269. if (ret)
  270. return ret;
  271. }
  272. return regmap_write_bits(data->regmap, BH1745_MODE_CTRL2,
  273. BH1745_CTRL2_ADC_GAIN_MASK, hw_gain_sel);
  274. }
  275. static int bh1745_get_int_time(struct bh1745_data *data, int *val)
  276. {
  277. int ret;
  278. int value;
  279. int int_time, int_time_sel;
  280. ret = regmap_read(data->regmap, BH1745_MODE_CTRL1, &value);
  281. if (ret)
  282. return ret;
  283. int_time_sel = FIELD_GET(BH1745_CTRL1_MEASUREMENT_TIME_MASK, value);
  284. int_time = iio_gts_find_int_time_by_sel(&data->gts, int_time_sel);
  285. if (int_time < 0)
  286. return int_time;
  287. *val = int_time;
  288. return 0;
  289. }
  290. static int bh1745_set_int_time(struct bh1745_data *data, int val, int val2)
  291. {
  292. struct device *dev = data->dev;
  293. int ret;
  294. int value;
  295. int current_int_time, current_hwgain_sel, current_hwgain;
  296. int new_hwgain, new_hwgain_sel, new_int_time_sel;
  297. int req_int_time = (1000000 * val) + val2;
  298. if (!iio_gts_valid_time(&data->gts, req_int_time)) {
  299. dev_dbg(dev, "Unsupported integration time requested: %d\n",
  300. req_int_time);
  301. return -EINVAL;
  302. }
  303. ret = bh1745_get_int_time(data, &current_int_time);
  304. if (ret)
  305. return ret;
  306. if (current_int_time == req_int_time)
  307. return 0;
  308. ret = regmap_read(data->regmap, BH1745_MODE_CTRL2, &value);
  309. if (ret)
  310. return ret;
  311. current_hwgain_sel = FIELD_GET(BH1745_CTRL2_ADC_GAIN_MASK, value);
  312. current_hwgain = iio_gts_find_gain_by_sel(&data->gts,
  313. current_hwgain_sel);
  314. ret = iio_gts_find_new_gain_by_old_gain_time(&data->gts, current_hwgain,
  315. current_int_time,
  316. req_int_time,
  317. &new_hwgain);
  318. if (new_hwgain < 0) {
  319. dev_dbg(dev, "No corresponding gain for requested integration time\n");
  320. return ret;
  321. }
  322. if (ret) {
  323. bool in_range;
  324. new_hwgain = iio_find_closest_gain_low(&data->gts, new_hwgain,
  325. &in_range);
  326. if (new_hwgain < 0) {
  327. new_hwgain = iio_gts_get_min_gain(&data->gts);
  328. if (new_hwgain < 0)
  329. return ret;
  330. }
  331. if (!in_range)
  332. dev_dbg(dev, "Optimal gain out of range\n");
  333. dev_dbg(dev, "Scale changed, new hw_gain %d\n", new_hwgain);
  334. }
  335. new_hwgain_sel = iio_gts_find_sel_by_gain(&data->gts, new_hwgain);
  336. if (new_hwgain_sel < 0)
  337. return new_hwgain_sel;
  338. ret = regmap_write_bits(data->regmap, BH1745_MODE_CTRL2,
  339. BH1745_CTRL2_ADC_GAIN_MASK,
  340. new_hwgain_sel);
  341. if (ret)
  342. return ret;
  343. new_int_time_sel = iio_gts_find_sel_by_int_time(&data->gts,
  344. req_int_time);
  345. if (new_int_time_sel < 0)
  346. return new_int_time_sel;
  347. return regmap_write_bits(data->regmap, BH1745_MODE_CTRL1,
  348. BH1745_CTRL1_MEASUREMENT_TIME_MASK,
  349. new_int_time_sel);
  350. }
  351. static int bh1745_read_raw(struct iio_dev *indio_dev,
  352. struct iio_chan_spec const *chan,
  353. int *val, int *val2, long mask)
  354. {
  355. struct bh1745_data *data = iio_priv(indio_dev);
  356. int ret;
  357. int value;
  358. switch (mask) {
  359. case IIO_CHAN_INFO_RAW:
  360. iio_device_claim_direct_scoped(return -EBUSY, indio_dev) {
  361. ret = regmap_bulk_read(data->regmap, chan->address,
  362. &value, 2);
  363. if (ret)
  364. return ret;
  365. *val = value;
  366. return IIO_VAL_INT;
  367. }
  368. unreachable();
  369. case IIO_CHAN_INFO_SCALE: {
  370. guard(mutex)(&data->lock);
  371. ret = bh1745_get_scale(data, val, val2);
  372. if (ret)
  373. return ret;
  374. return IIO_VAL_INT;
  375. }
  376. case IIO_CHAN_INFO_INT_TIME: {
  377. guard(mutex)(&data->lock);
  378. *val = 0;
  379. ret = bh1745_get_int_time(data, val2);
  380. if (ret)
  381. return 0;
  382. return IIO_VAL_INT_PLUS_MICRO;
  383. }
  384. default:
  385. return -EINVAL;
  386. }
  387. }
  388. static int bh1745_write_raw(struct iio_dev *indio_dev,
  389. struct iio_chan_spec const *chan,
  390. int val, int val2, long mask)
  391. {
  392. struct bh1745_data *data = iio_priv(indio_dev);
  393. guard(mutex)(&data->lock);
  394. switch (mask) {
  395. case IIO_CHAN_INFO_SCALE:
  396. return bh1745_set_scale(data, val);
  397. case IIO_CHAN_INFO_INT_TIME:
  398. return bh1745_set_int_time(data, val, val2);
  399. default:
  400. return -EINVAL;
  401. }
  402. }
  403. static int bh1745_write_raw_get_fmt(struct iio_dev *indio_dev,
  404. struct iio_chan_spec const *chan,
  405. long mask)
  406. {
  407. switch (mask) {
  408. case IIO_CHAN_INFO_SCALE:
  409. return IIO_VAL_INT;
  410. case IIO_CHAN_INFO_INT_TIME:
  411. return IIO_VAL_INT_PLUS_MICRO;
  412. default:
  413. return -EINVAL;
  414. }
  415. }
  416. static int bh1745_read_thresh(struct iio_dev *indio_dev,
  417. const struct iio_chan_spec *chan,
  418. enum iio_event_type type,
  419. enum iio_event_direction dir,
  420. enum iio_event_info info, int *val, int *val2)
  421. {
  422. struct bh1745_data *data = iio_priv(indio_dev);
  423. int ret;
  424. switch (info) {
  425. case IIO_EV_INFO_VALUE:
  426. switch (dir) {
  427. case IIO_EV_DIR_RISING:
  428. ret = regmap_bulk_read(data->regmap, BH1745_TH_LSB,
  429. val, 2);
  430. if (ret)
  431. return ret;
  432. return IIO_VAL_INT;
  433. case IIO_EV_DIR_FALLING:
  434. ret = regmap_bulk_read(data->regmap, BH1745_TL_LSB,
  435. val, 2);
  436. if (ret)
  437. return ret;
  438. return IIO_VAL_INT;
  439. default:
  440. return -EINVAL;
  441. }
  442. case IIO_EV_INFO_PERIOD:
  443. ret = regmap_read(data->regmap, BH1745_PERSISTENCE, val);
  444. if (ret)
  445. return ret;
  446. return IIO_VAL_INT;
  447. default:
  448. return -EINVAL;
  449. }
  450. }
  451. static int bh1745_write_thresh(struct iio_dev *indio_dev,
  452. const struct iio_chan_spec *chan,
  453. enum iio_event_type type,
  454. enum iio_event_direction dir,
  455. enum iio_event_info info, int val, int val2)
  456. {
  457. struct bh1745_data *data = iio_priv(indio_dev);
  458. int ret;
  459. switch (info) {
  460. case IIO_EV_INFO_VALUE:
  461. if (val < 0x0 || val > 0xFFFF)
  462. return -EINVAL;
  463. switch (dir) {
  464. case IIO_EV_DIR_RISING:
  465. ret = regmap_bulk_write(data->regmap, BH1745_TH_LSB,
  466. &val, 2);
  467. if (ret)
  468. return ret;
  469. return IIO_VAL_INT;
  470. case IIO_EV_DIR_FALLING:
  471. ret = regmap_bulk_write(data->regmap, BH1745_TL_LSB,
  472. &val, 2);
  473. if (ret)
  474. return ret;
  475. return IIO_VAL_INT;
  476. default:
  477. return -EINVAL;
  478. }
  479. case IIO_EV_INFO_PERIOD:
  480. if (val < BH1745_PRESISTENCE_UPDATE_TOGGLE ||
  481. val > BH1745_PRESISTENCE_UPDATE_EIGHT_MEASUREMENT)
  482. return -EINVAL;
  483. ret = regmap_write(data->regmap, BH1745_PERSISTENCE, val);
  484. if (ret)
  485. return ret;
  486. return IIO_VAL_INT;
  487. default:
  488. return -EINVAL;
  489. }
  490. }
  491. static int bh1745_read_event_config(struct iio_dev *indio_dev,
  492. const struct iio_chan_spec *chan,
  493. enum iio_event_type type,
  494. enum iio_event_direction dir)
  495. {
  496. struct bh1745_data *data = iio_priv(indio_dev);
  497. int ret;
  498. int value;
  499. int int_src;
  500. ret = regmap_read(data->regmap, BH1745_INTR, &value);
  501. if (ret)
  502. return ret;
  503. if (!FIELD_GET(BH1745_INTR_ENABLE, value))
  504. return 0;
  505. int_src = FIELD_GET(BH1745_INTR_SOURCE_MASK, value);
  506. switch (chan->channel2) {
  507. case IIO_MOD_LIGHT_RED:
  508. if (int_src == BH1745_INTR_SOURCE_RED)
  509. return 1;
  510. return 0;
  511. case IIO_MOD_LIGHT_GREEN:
  512. if (int_src == BH1745_INTR_SOURCE_GREEN)
  513. return 1;
  514. return 0;
  515. case IIO_MOD_LIGHT_BLUE:
  516. if (int_src == BH1745_INTR_SOURCE_BLUE)
  517. return 1;
  518. return 0;
  519. case IIO_MOD_LIGHT_CLEAR:
  520. if (int_src == BH1745_INTR_SOURCE_CLEAR)
  521. return 1;
  522. return 0;
  523. default:
  524. return -EINVAL;
  525. }
  526. }
  527. static int bh1745_write_event_config(struct iio_dev *indio_dev,
  528. const struct iio_chan_spec *chan,
  529. enum iio_event_type type,
  530. enum iio_event_direction dir, int state)
  531. {
  532. struct bh1745_data *data = iio_priv(indio_dev);
  533. int value;
  534. if (state == 0)
  535. return regmap_clear_bits(data->regmap,
  536. BH1745_INTR, BH1745_INTR_ENABLE);
  537. if (state == 1) {
  538. /* Latch is always enabled when enabling interrupt */
  539. value = BH1745_INTR_ENABLE;
  540. switch (chan->channel2) {
  541. case IIO_MOD_LIGHT_RED:
  542. return regmap_write(data->regmap, BH1745_INTR,
  543. value | FIELD_PREP(BH1745_INTR_SOURCE_MASK,
  544. BH1745_INTR_SOURCE_RED));
  545. case IIO_MOD_LIGHT_GREEN:
  546. return regmap_write(data->regmap, BH1745_INTR,
  547. value | FIELD_PREP(BH1745_INTR_SOURCE_MASK,
  548. BH1745_INTR_SOURCE_GREEN));
  549. case IIO_MOD_LIGHT_BLUE:
  550. return regmap_write(data->regmap, BH1745_INTR,
  551. value | FIELD_PREP(BH1745_INTR_SOURCE_MASK,
  552. BH1745_INTR_SOURCE_BLUE));
  553. case IIO_MOD_LIGHT_CLEAR:
  554. return regmap_write(data->regmap, BH1745_INTR,
  555. value | FIELD_PREP(BH1745_INTR_SOURCE_MASK,
  556. BH1745_INTR_SOURCE_CLEAR));
  557. default:
  558. return -EINVAL;
  559. }
  560. }
  561. return -EINVAL;
  562. }
  563. static int bh1745_read_avail(struct iio_dev *indio_dev,
  564. struct iio_chan_spec const *chan, const int **vals,
  565. int *type, int *length, long mask)
  566. {
  567. struct bh1745_data *data = iio_priv(indio_dev);
  568. switch (mask) {
  569. case IIO_CHAN_INFO_INT_TIME:
  570. return iio_gts_avail_times(&data->gts, vals, type, length);
  571. case IIO_CHAN_INFO_SCALE:
  572. return iio_gts_all_avail_scales(&data->gts, vals, type, length);
  573. default:
  574. return -EINVAL;
  575. }
  576. }
  577. static const struct iio_info bh1745_info = {
  578. .read_raw = bh1745_read_raw,
  579. .write_raw = bh1745_write_raw,
  580. .write_raw_get_fmt = bh1745_write_raw_get_fmt,
  581. .read_event_value = bh1745_read_thresh,
  582. .write_event_value = bh1745_write_thresh,
  583. .read_event_config = bh1745_read_event_config,
  584. .write_event_config = bh1745_write_event_config,
  585. .read_avail = bh1745_read_avail,
  586. };
  587. static irqreturn_t bh1745_interrupt_handler(int interrupt, void *p)
  588. {
  589. struct iio_dev *indio_dev = p;
  590. struct bh1745_data *data = iio_priv(indio_dev);
  591. int ret;
  592. int value;
  593. int int_src;
  594. ret = regmap_read(data->regmap, BH1745_INTR, &value);
  595. if (ret)
  596. return IRQ_NONE;
  597. int_src = FIELD_GET(BH1745_INTR_SOURCE_MASK, value);
  598. if (value & BH1745_INTR_STATUS) {
  599. iio_push_event(indio_dev,
  600. IIO_UNMOD_EVENT_CODE(IIO_INTENSITY, int_src,
  601. IIO_EV_TYPE_THRESH,
  602. IIO_EV_DIR_EITHER),
  603. iio_get_time_ns(indio_dev));
  604. return IRQ_HANDLED;
  605. }
  606. return IRQ_NONE;
  607. }
  608. static irqreturn_t bh1745_trigger_handler(int interrupt, void *p)
  609. {
  610. struct iio_poll_func *pf = p;
  611. struct iio_dev *indio_dev = pf->indio_dev;
  612. struct bh1745_data *data = iio_priv(indio_dev);
  613. struct {
  614. u16 chans[4];
  615. s64 timestamp __aligned(8);
  616. } scan;
  617. u16 value;
  618. int ret;
  619. int i;
  620. int j = 0;
  621. memset(&scan, 0, sizeof(scan));
  622. iio_for_each_active_channel(indio_dev, i) {
  623. ret = regmap_bulk_read(data->regmap, BH1745_RED_LSB + 2 * i,
  624. &value, 2);
  625. if (ret)
  626. goto err;
  627. scan.chans[j++] = value;
  628. }
  629. iio_push_to_buffers_with_timestamp(indio_dev, &scan,
  630. iio_get_time_ns(indio_dev));
  631. err:
  632. iio_trigger_notify_done(indio_dev->trig);
  633. return IRQ_HANDLED;
  634. }
  635. static int bh1745_setup_triggered_buffer(struct iio_dev *indio_dev,
  636. struct device *parent,
  637. int irq)
  638. {
  639. struct bh1745_data *data = iio_priv(indio_dev);
  640. struct device *dev = data->dev;
  641. int ret;
  642. ret = devm_iio_triggered_buffer_setup(parent, indio_dev, NULL,
  643. bh1745_trigger_handler, NULL);
  644. if (ret)
  645. return dev_err_probe(dev, ret,
  646. "Triggered buffer setup failed\n");
  647. if (irq) {
  648. ret = devm_request_threaded_irq(dev, irq, NULL,
  649. bh1745_interrupt_handler,
  650. IRQF_ONESHOT,
  651. "bh1745_interrupt", indio_dev);
  652. if (ret)
  653. return dev_err_probe(dev, ret,
  654. "Request for IRQ failed\n");
  655. }
  656. return 0;
  657. }
  658. static int bh1745_init(struct bh1745_data *data)
  659. {
  660. int ret;
  661. struct device *dev = data->dev;
  662. mutex_init(&data->lock);
  663. ret = devm_iio_init_iio_gts(dev, BH1745_MAX_GAIN, 0, bh1745_gain,
  664. ARRAY_SIZE(bh1745_gain), bh1745_itimes,
  665. ARRAY_SIZE(bh1745_itimes), &data->gts);
  666. if (ret)
  667. return ret;
  668. ret = bh1745_reset(data);
  669. if (ret)
  670. return dev_err_probe(dev, ret, "Failed to reset sensor\n");
  671. ret = bh1745_power_on(data);
  672. if (ret)
  673. return dev_err_probe(dev, ret, "Failed to turn on sensor\n");
  674. ret = devm_add_action_or_reset(dev, bh1745_power_off, data);
  675. if (ret)
  676. return dev_err_probe(dev, ret,
  677. "Failed to add action or reset\n");
  678. return 0;
  679. }
  680. static int bh1745_probe(struct i2c_client *client)
  681. {
  682. int ret;
  683. int value;
  684. int part_id;
  685. struct bh1745_data *data;
  686. struct iio_dev *indio_dev;
  687. struct device *dev = &client->dev;
  688. indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
  689. if (!indio_dev)
  690. return -ENOMEM;
  691. indio_dev->info = &bh1745_info;
  692. indio_dev->name = "bh1745";
  693. indio_dev->channels = bh1745_channels;
  694. indio_dev->modes = INDIO_DIRECT_MODE;
  695. indio_dev->num_channels = ARRAY_SIZE(bh1745_channels);
  696. data = iio_priv(indio_dev);
  697. data->dev = &client->dev;
  698. data->regmap = devm_regmap_init_i2c(client, &bh1745_regmap);
  699. if (IS_ERR(data->regmap))
  700. return dev_err_probe(dev, PTR_ERR(data->regmap),
  701. "Failed to initialize Regmap\n");
  702. ret = regmap_read(data->regmap, BH1745_SYS_CTRL, &value);
  703. if (ret)
  704. return ret;
  705. part_id = FIELD_GET(BH1745_SYS_CTRL_PART_ID_MASK, value);
  706. if (part_id != BH1745_PART_ID)
  707. dev_warn(dev, "Unknown part ID 0x%x\n", part_id);
  708. ret = devm_regulator_get_enable(dev, "vdd");
  709. if (ret)
  710. return dev_err_probe(dev, ret,
  711. "Failed to get and enable regulator\n");
  712. ret = bh1745_init(data);
  713. if (ret)
  714. return ret;
  715. ret = bh1745_setup_triggered_buffer(indio_dev, indio_dev->dev.parent,
  716. client->irq);
  717. if (ret)
  718. return ret;
  719. ret = devm_iio_device_register(dev, indio_dev);
  720. if (ret)
  721. return dev_err_probe(dev, ret, "Failed to register device\n");
  722. return 0;
  723. }
  724. static const struct i2c_device_id bh1745_idtable[] = {
  725. { "bh1745" },
  726. { }
  727. };
  728. MODULE_DEVICE_TABLE(i2c, bh1745_idtable);
  729. static const struct of_device_id bh1745_of_match[] = {
  730. { .compatible = "rohm,bh1745" },
  731. { }
  732. };
  733. MODULE_DEVICE_TABLE(of, bh1745_of_match);
  734. static struct i2c_driver bh1745_driver = {
  735. .driver = {
  736. .name = "bh1745",
  737. .of_match_table = bh1745_of_match,
  738. },
  739. .probe = bh1745_probe,
  740. .id_table = bh1745_idtable,
  741. };
  742. module_i2c_driver(bh1745_driver);
  743. MODULE_LICENSE("GPL");
  744. MODULE_AUTHOR("Mudit Sharma <muditsharma.info@gmail.com>");
  745. MODULE_DESCRIPTION("BH1745 colour sensor driver");
  746. MODULE_IMPORT_NS(IIO_GTS_HELPER);