isl29028.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * IIO driver for the light sensor ISL29028.
  4. * ISL29028 is Concurrent Ambient Light and Proximity Sensor
  5. *
  6. * Copyright (c) 2012, NVIDIA CORPORATION. All rights reserved.
  7. * Copyright (c) 2016-2017 Brian Masney <masneyb@onstation.org>
  8. *
  9. * Datasheets:
  10. * - http://www.intersil.com/content/dam/Intersil/documents/isl2/isl29028.pdf
  11. * - http://www.intersil.com/content/dam/Intersil/documents/isl2/isl29030.pdf
  12. */
  13. #include <linux/module.h>
  14. #include <linux/i2c.h>
  15. #include <linux/err.h>
  16. #include <linux/mutex.h>
  17. #include <linux/delay.h>
  18. #include <linux/slab.h>
  19. #include <linux/regmap.h>
  20. #include <linux/iio/iio.h>
  21. #include <linux/iio/sysfs.h>
  22. #include <linux/pm_runtime.h>
  23. #define ISL29028_CONV_TIME_MS 100
  24. #define ISL29028_REG_CONFIGURE 0x01
  25. #define ISL29028_CONF_ALS_IR_MODE_ALS 0
  26. #define ISL29028_CONF_ALS_IR_MODE_IR BIT(0)
  27. #define ISL29028_CONF_ALS_IR_MODE_MASK BIT(0)
  28. #define ISL29028_CONF_ALS_RANGE_LOW_LUX 0
  29. #define ISL29028_CONF_ALS_RANGE_HIGH_LUX BIT(1)
  30. #define ISL29028_CONF_ALS_RANGE_MASK BIT(1)
  31. #define ISL29028_CONF_ALS_DIS 0
  32. #define ISL29028_CONF_ALS_EN BIT(2)
  33. #define ISL29028_CONF_ALS_EN_MASK BIT(2)
  34. #define ISL29028_CONF_PROX_SLP_SH 4
  35. #define ISL29028_CONF_PROX_SLP_MASK (7 << ISL29028_CONF_PROX_SLP_SH)
  36. #define ISL29028_CONF_PROX_EN BIT(7)
  37. #define ISL29028_CONF_PROX_EN_MASK BIT(7)
  38. #define ISL29028_REG_INTERRUPT 0x02
  39. #define ISL29028_REG_PROX_DATA 0x08
  40. #define ISL29028_REG_ALSIR_L 0x09
  41. #define ISL29028_REG_ALSIR_U 0x0A
  42. #define ISL29028_REG_TEST1_MODE 0x0E
  43. #define ISL29028_REG_TEST2_MODE 0x0F
  44. #define ISL29028_NUM_REGS (ISL29028_REG_TEST2_MODE + 1)
  45. #define ISL29028_POWER_OFF_DELAY_MS 2000
  46. struct isl29028_prox_data {
  47. int sampling_int;
  48. int sampling_fract;
  49. int sleep_time;
  50. };
  51. static const struct isl29028_prox_data isl29028_prox_data[] = {
  52. { 1, 250000, 800 },
  53. { 2, 500000, 400 },
  54. { 5, 0, 200 },
  55. { 10, 0, 100 },
  56. { 13, 300000, 75 },
  57. { 20, 0, 50 },
  58. { 80, 0, 13 }, /*
  59. * Note: Data sheet lists 12.5 ms sleep time.
  60. * Round up a half millisecond for msleep().
  61. */
  62. { 100, 0, 0 }
  63. };
  64. enum isl29028_als_ir_mode {
  65. ISL29028_MODE_NONE = 0,
  66. ISL29028_MODE_ALS,
  67. ISL29028_MODE_IR,
  68. };
  69. struct isl29028_chip {
  70. struct mutex lock;
  71. struct regmap *regmap;
  72. int prox_sampling_int;
  73. int prox_sampling_frac;
  74. bool enable_prox;
  75. int lux_scale;
  76. enum isl29028_als_ir_mode als_ir_mode;
  77. };
  78. static int isl29028_find_prox_sleep_index(int sampling_int, int sampling_fract)
  79. {
  80. int i;
  81. for (i = 0; i < ARRAY_SIZE(isl29028_prox_data); ++i) {
  82. if (isl29028_prox_data[i].sampling_int == sampling_int &&
  83. isl29028_prox_data[i].sampling_fract == sampling_fract)
  84. return i;
  85. }
  86. return -EINVAL;
  87. }
  88. static int isl29028_set_proxim_sampling(struct isl29028_chip *chip,
  89. int sampling_int, int sampling_fract)
  90. {
  91. struct device *dev = regmap_get_device(chip->regmap);
  92. int sleep_index, ret;
  93. sleep_index = isl29028_find_prox_sleep_index(sampling_int,
  94. sampling_fract);
  95. if (sleep_index < 0)
  96. return sleep_index;
  97. ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
  98. ISL29028_CONF_PROX_SLP_MASK,
  99. sleep_index << ISL29028_CONF_PROX_SLP_SH);
  100. if (ret < 0) {
  101. dev_err(dev, "%s(): Error %d setting the proximity sampling\n",
  102. __func__, ret);
  103. return ret;
  104. }
  105. chip->prox_sampling_int = sampling_int;
  106. chip->prox_sampling_frac = sampling_fract;
  107. return ret;
  108. }
  109. static int isl29028_enable_proximity(struct isl29028_chip *chip)
  110. {
  111. int prox_index, ret;
  112. ret = isl29028_set_proxim_sampling(chip, chip->prox_sampling_int,
  113. chip->prox_sampling_frac);
  114. if (ret < 0)
  115. return ret;
  116. ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
  117. ISL29028_CONF_PROX_EN_MASK,
  118. ISL29028_CONF_PROX_EN);
  119. if (ret < 0)
  120. return ret;
  121. /* Wait for conversion to be complete for first sample */
  122. prox_index = isl29028_find_prox_sleep_index(chip->prox_sampling_int,
  123. chip->prox_sampling_frac);
  124. if (prox_index < 0)
  125. return prox_index;
  126. msleep(isl29028_prox_data[prox_index].sleep_time);
  127. return 0;
  128. }
  129. static int isl29028_set_als_scale(struct isl29028_chip *chip, int lux_scale)
  130. {
  131. struct device *dev = regmap_get_device(chip->regmap);
  132. int val = (lux_scale == 2000) ? ISL29028_CONF_ALS_RANGE_HIGH_LUX :
  133. ISL29028_CONF_ALS_RANGE_LOW_LUX;
  134. int ret;
  135. ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
  136. ISL29028_CONF_ALS_RANGE_MASK, val);
  137. if (ret < 0) {
  138. dev_err(dev, "%s(): Error %d setting the ALS scale\n", __func__,
  139. ret);
  140. return ret;
  141. }
  142. chip->lux_scale = lux_scale;
  143. return ret;
  144. }
  145. static int isl29028_set_als_ir_mode(struct isl29028_chip *chip,
  146. enum isl29028_als_ir_mode mode)
  147. {
  148. int ret;
  149. if (chip->als_ir_mode == mode)
  150. return 0;
  151. ret = isl29028_set_als_scale(chip, chip->lux_scale);
  152. if (ret < 0)
  153. return ret;
  154. switch (mode) {
  155. case ISL29028_MODE_ALS:
  156. ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
  157. ISL29028_CONF_ALS_IR_MODE_MASK,
  158. ISL29028_CONF_ALS_IR_MODE_ALS);
  159. if (ret < 0)
  160. return ret;
  161. ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
  162. ISL29028_CONF_ALS_RANGE_MASK,
  163. ISL29028_CONF_ALS_RANGE_HIGH_LUX);
  164. break;
  165. case ISL29028_MODE_IR:
  166. ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
  167. ISL29028_CONF_ALS_IR_MODE_MASK,
  168. ISL29028_CONF_ALS_IR_MODE_IR);
  169. break;
  170. case ISL29028_MODE_NONE:
  171. return regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
  172. ISL29028_CONF_ALS_EN_MASK,
  173. ISL29028_CONF_ALS_DIS);
  174. }
  175. if (ret < 0)
  176. return ret;
  177. /* Enable the ALS/IR */
  178. ret = regmap_update_bits(chip->regmap, ISL29028_REG_CONFIGURE,
  179. ISL29028_CONF_ALS_EN_MASK,
  180. ISL29028_CONF_ALS_EN);
  181. if (ret < 0)
  182. return ret;
  183. /* Need to wait for conversion time if ALS/IR mode enabled */
  184. msleep(ISL29028_CONV_TIME_MS);
  185. chip->als_ir_mode = mode;
  186. return 0;
  187. }
  188. static int isl29028_read_als_ir(struct isl29028_chip *chip, int *als_ir)
  189. {
  190. struct device *dev = regmap_get_device(chip->regmap);
  191. unsigned int lsb;
  192. unsigned int msb;
  193. int ret;
  194. ret = regmap_read(chip->regmap, ISL29028_REG_ALSIR_L, &lsb);
  195. if (ret < 0) {
  196. dev_err(dev,
  197. "%s(): Error %d reading register ALSIR_L\n",
  198. __func__, ret);
  199. return ret;
  200. }
  201. ret = regmap_read(chip->regmap, ISL29028_REG_ALSIR_U, &msb);
  202. if (ret < 0) {
  203. dev_err(dev,
  204. "%s(): Error %d reading register ALSIR_U\n",
  205. __func__, ret);
  206. return ret;
  207. }
  208. *als_ir = ((msb & 0xF) << 8) | (lsb & 0xFF);
  209. return 0;
  210. }
  211. static int isl29028_read_proxim(struct isl29028_chip *chip, int *prox)
  212. {
  213. struct device *dev = regmap_get_device(chip->regmap);
  214. unsigned int data;
  215. int ret;
  216. if (!chip->enable_prox) {
  217. ret = isl29028_enable_proximity(chip);
  218. if (ret < 0)
  219. return ret;
  220. chip->enable_prox = true;
  221. }
  222. ret = regmap_read(chip->regmap, ISL29028_REG_PROX_DATA, &data);
  223. if (ret < 0) {
  224. dev_err(dev, "%s(): Error %d reading register PROX_DATA\n",
  225. __func__, ret);
  226. return ret;
  227. }
  228. *prox = data;
  229. return 0;
  230. }
  231. static int isl29028_als_get(struct isl29028_chip *chip, int *als_data)
  232. {
  233. struct device *dev = regmap_get_device(chip->regmap);
  234. int ret;
  235. int als_ir_data;
  236. ret = isl29028_set_als_ir_mode(chip, ISL29028_MODE_ALS);
  237. if (ret < 0) {
  238. dev_err(dev, "%s(): Error %d enabling ALS mode\n", __func__,
  239. ret);
  240. return ret;
  241. }
  242. ret = isl29028_read_als_ir(chip, &als_ir_data);
  243. if (ret < 0)
  244. return ret;
  245. /*
  246. * convert als data count to lux.
  247. * if lux_scale = 125, lux = count * 0.031
  248. * if lux_scale = 2000, lux = count * 0.49
  249. */
  250. if (chip->lux_scale == 125)
  251. als_ir_data = (als_ir_data * 31) / 1000;
  252. else
  253. als_ir_data = (als_ir_data * 49) / 100;
  254. *als_data = als_ir_data;
  255. return 0;
  256. }
  257. static int isl29028_ir_get(struct isl29028_chip *chip, int *ir_data)
  258. {
  259. struct device *dev = regmap_get_device(chip->regmap);
  260. int ret;
  261. ret = isl29028_set_als_ir_mode(chip, ISL29028_MODE_IR);
  262. if (ret < 0) {
  263. dev_err(dev, "%s(): Error %d enabling IR mode\n", __func__,
  264. ret);
  265. return ret;
  266. }
  267. return isl29028_read_als_ir(chip, ir_data);
  268. }
  269. static int isl29028_set_pm_runtime_busy(struct isl29028_chip *chip, bool on)
  270. {
  271. struct device *dev = regmap_get_device(chip->regmap);
  272. int ret;
  273. if (on) {
  274. ret = pm_runtime_resume_and_get(dev);
  275. } else {
  276. pm_runtime_mark_last_busy(dev);
  277. ret = pm_runtime_put_autosuspend(dev);
  278. }
  279. return ret;
  280. }
  281. /* Channel IO */
  282. static int isl29028_write_raw(struct iio_dev *indio_dev,
  283. struct iio_chan_spec const *chan,
  284. int val, int val2, long mask)
  285. {
  286. struct isl29028_chip *chip = iio_priv(indio_dev);
  287. struct device *dev = regmap_get_device(chip->regmap);
  288. int ret;
  289. ret = isl29028_set_pm_runtime_busy(chip, true);
  290. if (ret < 0)
  291. return ret;
  292. mutex_lock(&chip->lock);
  293. ret = -EINVAL;
  294. switch (chan->type) {
  295. case IIO_PROXIMITY:
  296. if (mask != IIO_CHAN_INFO_SAMP_FREQ) {
  297. dev_err(dev,
  298. "%s(): proximity: Mask value 0x%08lx is not supported\n",
  299. __func__, mask);
  300. break;
  301. }
  302. if (val < 1 || val > 100) {
  303. dev_err(dev,
  304. "%s(): proximity: Sampling frequency %d is not in the range [1:100]\n",
  305. __func__, val);
  306. break;
  307. }
  308. ret = isl29028_set_proxim_sampling(chip, val, val2);
  309. break;
  310. case IIO_LIGHT:
  311. if (mask != IIO_CHAN_INFO_SCALE) {
  312. dev_err(dev,
  313. "%s(): light: Mask value 0x%08lx is not supported\n",
  314. __func__, mask);
  315. break;
  316. }
  317. if (val != 125 && val != 2000) {
  318. dev_err(dev,
  319. "%s(): light: Lux scale %d is not in the set {125, 2000}\n",
  320. __func__, val);
  321. break;
  322. }
  323. ret = isl29028_set_als_scale(chip, val);
  324. break;
  325. default:
  326. dev_err(dev, "%s(): Unsupported channel type %x\n",
  327. __func__, chan->type);
  328. break;
  329. }
  330. mutex_unlock(&chip->lock);
  331. if (ret < 0)
  332. return ret;
  333. ret = isl29028_set_pm_runtime_busy(chip, false);
  334. if (ret < 0)
  335. return ret;
  336. return ret;
  337. }
  338. static int isl29028_read_raw(struct iio_dev *indio_dev,
  339. struct iio_chan_spec const *chan,
  340. int *val, int *val2, long mask)
  341. {
  342. struct isl29028_chip *chip = iio_priv(indio_dev);
  343. struct device *dev = regmap_get_device(chip->regmap);
  344. int ret, pm_ret;
  345. ret = isl29028_set_pm_runtime_busy(chip, true);
  346. if (ret < 0)
  347. return ret;
  348. mutex_lock(&chip->lock);
  349. ret = -EINVAL;
  350. switch (mask) {
  351. case IIO_CHAN_INFO_RAW:
  352. case IIO_CHAN_INFO_PROCESSED:
  353. switch (chan->type) {
  354. case IIO_LIGHT:
  355. ret = isl29028_als_get(chip, val);
  356. break;
  357. case IIO_INTENSITY:
  358. ret = isl29028_ir_get(chip, val);
  359. break;
  360. case IIO_PROXIMITY:
  361. ret = isl29028_read_proxim(chip, val);
  362. break;
  363. default:
  364. break;
  365. }
  366. if (ret < 0)
  367. break;
  368. ret = IIO_VAL_INT;
  369. break;
  370. case IIO_CHAN_INFO_SAMP_FREQ:
  371. if (chan->type != IIO_PROXIMITY)
  372. break;
  373. *val = chip->prox_sampling_int;
  374. *val2 = chip->prox_sampling_frac;
  375. ret = IIO_VAL_INT;
  376. break;
  377. case IIO_CHAN_INFO_SCALE:
  378. if (chan->type != IIO_LIGHT)
  379. break;
  380. *val = chip->lux_scale;
  381. ret = IIO_VAL_INT;
  382. break;
  383. default:
  384. dev_err(dev, "%s(): mask value 0x%08lx is not supported\n",
  385. __func__, mask);
  386. break;
  387. }
  388. mutex_unlock(&chip->lock);
  389. if (ret < 0)
  390. return ret;
  391. /**
  392. * Preserve the ret variable if the call to
  393. * isl29028_set_pm_runtime_busy() is successful so the reading
  394. * (if applicable) is returned to user space.
  395. */
  396. pm_ret = isl29028_set_pm_runtime_busy(chip, false);
  397. if (pm_ret < 0)
  398. return pm_ret;
  399. return ret;
  400. }
  401. static IIO_CONST_ATTR(in_proximity_sampling_frequency_available,
  402. "1.25 2.5 5 10 13.3 20 80 100");
  403. static IIO_CONST_ATTR(in_illuminance_scale_available, "125 2000");
  404. #define ISL29028_CONST_ATTR(name) (&iio_const_attr_##name.dev_attr.attr)
  405. static struct attribute *isl29028_attributes[] = {
  406. ISL29028_CONST_ATTR(in_proximity_sampling_frequency_available),
  407. ISL29028_CONST_ATTR(in_illuminance_scale_available),
  408. NULL,
  409. };
  410. static const struct attribute_group isl29108_group = {
  411. .attrs = isl29028_attributes,
  412. };
  413. static const struct iio_chan_spec isl29028_channels[] = {
  414. {
  415. .type = IIO_LIGHT,
  416. .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED) |
  417. BIT(IIO_CHAN_INFO_SCALE),
  418. }, {
  419. .type = IIO_INTENSITY,
  420. .info_mask_separate = BIT(IIO_CHAN_INFO_RAW),
  421. }, {
  422. .type = IIO_PROXIMITY,
  423. .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
  424. BIT(IIO_CHAN_INFO_SAMP_FREQ),
  425. }
  426. };
  427. static const struct iio_info isl29028_info = {
  428. .attrs = &isl29108_group,
  429. .read_raw = isl29028_read_raw,
  430. .write_raw = isl29028_write_raw,
  431. };
  432. static int isl29028_clear_configure_reg(struct isl29028_chip *chip)
  433. {
  434. struct device *dev = regmap_get_device(chip->regmap);
  435. int ret;
  436. ret = regmap_write(chip->regmap, ISL29028_REG_CONFIGURE, 0x0);
  437. if (ret < 0)
  438. dev_err(dev, "%s(): Error %d clearing the CONFIGURE register\n",
  439. __func__, ret);
  440. chip->als_ir_mode = ISL29028_MODE_NONE;
  441. chip->enable_prox = false;
  442. return ret;
  443. }
  444. static bool isl29028_is_volatile_reg(struct device *dev, unsigned int reg)
  445. {
  446. switch (reg) {
  447. case ISL29028_REG_INTERRUPT:
  448. case ISL29028_REG_PROX_DATA:
  449. case ISL29028_REG_ALSIR_L:
  450. case ISL29028_REG_ALSIR_U:
  451. return true;
  452. default:
  453. return false;
  454. }
  455. }
  456. static const struct regmap_config isl29028_regmap_config = {
  457. .reg_bits = 8,
  458. .val_bits = 8,
  459. .volatile_reg = isl29028_is_volatile_reg,
  460. .max_register = ISL29028_NUM_REGS - 1,
  461. .num_reg_defaults_raw = ISL29028_NUM_REGS,
  462. .cache_type = REGCACHE_RBTREE,
  463. };
  464. static int isl29028_probe(struct i2c_client *client)
  465. {
  466. const struct i2c_device_id *id = i2c_client_get_device_id(client);
  467. struct isl29028_chip *chip;
  468. struct iio_dev *indio_dev;
  469. int ret;
  470. indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*chip));
  471. if (!indio_dev)
  472. return -ENOMEM;
  473. chip = iio_priv(indio_dev);
  474. i2c_set_clientdata(client, indio_dev);
  475. mutex_init(&chip->lock);
  476. chip->regmap = devm_regmap_init_i2c(client, &isl29028_regmap_config);
  477. if (IS_ERR(chip->regmap)) {
  478. ret = PTR_ERR(chip->regmap);
  479. dev_err(&client->dev, "%s: Error %d initializing regmap\n",
  480. __func__, ret);
  481. return ret;
  482. }
  483. chip->enable_prox = false;
  484. chip->prox_sampling_int = 20;
  485. chip->prox_sampling_frac = 0;
  486. chip->lux_scale = 2000;
  487. ret = regmap_write(chip->regmap, ISL29028_REG_TEST1_MODE, 0x0);
  488. if (ret < 0) {
  489. dev_err(&client->dev,
  490. "%s(): Error %d writing to TEST1_MODE register\n",
  491. __func__, ret);
  492. return ret;
  493. }
  494. ret = regmap_write(chip->regmap, ISL29028_REG_TEST2_MODE, 0x0);
  495. if (ret < 0) {
  496. dev_err(&client->dev,
  497. "%s(): Error %d writing to TEST2_MODE register\n",
  498. __func__, ret);
  499. return ret;
  500. }
  501. ret = isl29028_clear_configure_reg(chip);
  502. if (ret < 0)
  503. return ret;
  504. indio_dev->info = &isl29028_info;
  505. indio_dev->channels = isl29028_channels;
  506. indio_dev->num_channels = ARRAY_SIZE(isl29028_channels);
  507. indio_dev->name = id->name;
  508. indio_dev->modes = INDIO_DIRECT_MODE;
  509. pm_runtime_enable(&client->dev);
  510. pm_runtime_set_autosuspend_delay(&client->dev,
  511. ISL29028_POWER_OFF_DELAY_MS);
  512. pm_runtime_use_autosuspend(&client->dev);
  513. ret = iio_device_register(indio_dev);
  514. if (ret < 0) {
  515. dev_err(&client->dev,
  516. "%s(): iio registration failed with error %d\n",
  517. __func__, ret);
  518. return ret;
  519. }
  520. return 0;
  521. }
  522. static void isl29028_remove(struct i2c_client *client)
  523. {
  524. struct iio_dev *indio_dev = i2c_get_clientdata(client);
  525. struct isl29028_chip *chip = iio_priv(indio_dev);
  526. iio_device_unregister(indio_dev);
  527. pm_runtime_disable(&client->dev);
  528. pm_runtime_set_suspended(&client->dev);
  529. isl29028_clear_configure_reg(chip);
  530. }
  531. static int isl29028_suspend(struct device *dev)
  532. {
  533. struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
  534. struct isl29028_chip *chip = iio_priv(indio_dev);
  535. int ret;
  536. mutex_lock(&chip->lock);
  537. ret = isl29028_clear_configure_reg(chip);
  538. mutex_unlock(&chip->lock);
  539. return ret;
  540. }
  541. static int isl29028_resume(struct device *dev)
  542. {
  543. /**
  544. * The specific component (ALS/IR or proximity) will enable itself as
  545. * needed the next time that the user requests a reading. This is done
  546. * above in isl29028_set_als_ir_mode() and isl29028_enable_proximity().
  547. */
  548. return 0;
  549. }
  550. static DEFINE_RUNTIME_DEV_PM_OPS(isl29028_pm_ops, isl29028_suspend,
  551. isl29028_resume, NULL);
  552. static const struct i2c_device_id isl29028_id[] = {
  553. { "isl29028" },
  554. { "isl29030" },
  555. {}
  556. };
  557. MODULE_DEVICE_TABLE(i2c, isl29028_id);
  558. static const struct of_device_id isl29028_of_match[] = {
  559. { .compatible = "isl,isl29028", }, /* for backward compat., don't use */
  560. { .compatible = "isil,isl29028", },
  561. { .compatible = "isil,isl29030", },
  562. { },
  563. };
  564. MODULE_DEVICE_TABLE(of, isl29028_of_match);
  565. static struct i2c_driver isl29028_driver = {
  566. .driver = {
  567. .name = "isl29028",
  568. .pm = pm_ptr(&isl29028_pm_ops),
  569. .of_match_table = isl29028_of_match,
  570. },
  571. .probe = isl29028_probe,
  572. .remove = isl29028_remove,
  573. .id_table = isl29028_id,
  574. };
  575. module_i2c_driver(isl29028_driver);
  576. MODULE_DESCRIPTION("ISL29028 Ambient Light and Proximity Sensor driver");
  577. MODULE_LICENSE("GPL v2");
  578. MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>");