as73211.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Support for AMS AS73211 JENCOLOR(R) Digital XYZ Sensor and AMS AS7331
  4. * UVA, UVB and UVC (DUV) Ultraviolet Sensor
  5. *
  6. * Author: Christian Eggers <ceggers@arri.de>
  7. *
  8. * Copyright (c) 2020 ARRI Lighting
  9. *
  10. * Color light sensor with 16-bit channels for x, y, z and temperature);
  11. * 7-bit I2C slave address 0x74 .. 0x77.
  12. *
  13. * Datasheets:
  14. * AS73211: https://ams.com/documents/20143/36005/AS73211_DS000556_3-01.pdf
  15. * AS7331: https://ams.com/documents/20143/9106314/AS7331_DS001047_4-00.pdf
  16. */
  17. #include <linux/bitfield.h>
  18. #include <linux/completion.h>
  19. #include <linux/delay.h>
  20. #include <linux/i2c.h>
  21. #include <linux/iio/buffer.h>
  22. #include <linux/iio/iio.h>
  23. #include <linux/iio/sysfs.h>
  24. #include <linux/iio/trigger_consumer.h>
  25. #include <linux/iio/triggered_buffer.h>
  26. #include <linux/module.h>
  27. #include <linux/mutex.h>
  28. #include <linux/pm.h>
  29. #include <linux/units.h>
  30. #define AS73211_DRV_NAME "as73211"
  31. /* AS73211 configuration registers */
  32. #define AS73211_REG_OSR 0x0
  33. #define AS73211_REG_AGEN 0x2
  34. #define AS73211_REG_CREG1 0x6
  35. #define AS73211_REG_CREG2 0x7
  36. #define AS73211_REG_CREG3 0x8
  37. /* AS73211 output register bank */
  38. #define AS73211_OUT_OSR_STATUS 0
  39. #define AS73211_OUT_TEMP 1
  40. #define AS73211_OUT_MRES1 2
  41. #define AS73211_OUT_MRES2 3
  42. #define AS73211_OUT_MRES3 4
  43. #define AS73211_OSR_SS BIT(7)
  44. #define AS73211_OSR_PD BIT(6)
  45. #define AS73211_OSR_SW_RES BIT(3)
  46. #define AS73211_OSR_DOS_MASK GENMASK(2, 0)
  47. #define AS73211_OSR_DOS_CONFIG FIELD_PREP(AS73211_OSR_DOS_MASK, 0x2)
  48. #define AS73211_OSR_DOS_MEASURE FIELD_PREP(AS73211_OSR_DOS_MASK, 0x3)
  49. #define AS73211_AGEN_DEVID_MASK GENMASK(7, 4)
  50. #define AS73211_AGEN_DEVID(x) FIELD_PREP(AS73211_AGEN_DEVID_MASK, (x))
  51. #define AS73211_AGEN_MUT_MASK GENMASK(3, 0)
  52. #define AS73211_AGEN_MUT(x) FIELD_PREP(AS73211_AGEN_MUT_MASK, (x))
  53. #define AS73211_CREG1_GAIN_MASK GENMASK(7, 4)
  54. #define AS73211_CREG1_GAIN_1 11
  55. #define AS73211_CREG1_TIME_MASK GENMASK(3, 0)
  56. #define AS73211_CREG3_CCLK_MASK GENMASK(1, 0)
  57. #define AS73211_OSR_STATUS_OUTCONVOF BIT(15)
  58. #define AS73211_OSR_STATUS_MRESOF BIT(14)
  59. #define AS73211_OSR_STATUS_ADCOF BIT(13)
  60. #define AS73211_OSR_STATUS_LDATA BIT(12)
  61. #define AS73211_OSR_STATUS_NDATA BIT(11)
  62. #define AS73211_OSR_STATUS_NOTREADY BIT(10)
  63. #define AS73211_SAMPLE_FREQ_BASE 1024000
  64. #define AS73211_SAMPLE_TIME_NUM 15
  65. #define AS73211_SAMPLE_TIME_MAX_MS BIT(AS73211_SAMPLE_TIME_NUM - 1)
  66. /* Available sample frequencies are 1.024MHz multiplied by powers of two. */
  67. static const int as73211_samp_freq_avail[] = {
  68. AS73211_SAMPLE_FREQ_BASE * 1,
  69. AS73211_SAMPLE_FREQ_BASE * 2,
  70. AS73211_SAMPLE_FREQ_BASE * 4,
  71. AS73211_SAMPLE_FREQ_BASE * 8,
  72. };
  73. static const int as73211_hardwaregain_avail[] = {
  74. 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048,
  75. };
  76. struct as73211_data;
  77. /**
  78. * struct as73211_spec_dev_data - device-specific data
  79. * @intensity_scale: Function to retrieve intensity scale values.
  80. * @channels: Device channels.
  81. * @num_channels: Number of channels of the device.
  82. */
  83. struct as73211_spec_dev_data {
  84. int (*intensity_scale)(struct as73211_data *data, int chan, int *val, int *val2);
  85. struct iio_chan_spec const *channels;
  86. int num_channels;
  87. };
  88. /**
  89. * struct as73211_data - Instance data for one AS73211
  90. * @client: I2C client.
  91. * @osr: Cached Operational State Register.
  92. * @creg1: Cached Configuration Register 1.
  93. * @creg2: Cached Configuration Register 2.
  94. * @creg3: Cached Configuration Register 3.
  95. * @mutex: Keeps cached registers in sync with the device.
  96. * @completion: Completion to wait for interrupt.
  97. * @int_time_avail: Available integration times (depend on sampling frequency).
  98. * @spec_dev: device-specific configuration.
  99. */
  100. struct as73211_data {
  101. struct i2c_client *client;
  102. u8 osr;
  103. u8 creg1;
  104. u8 creg2;
  105. u8 creg3;
  106. struct mutex mutex;
  107. struct completion completion;
  108. int int_time_avail[AS73211_SAMPLE_TIME_NUM * 2];
  109. const struct as73211_spec_dev_data *spec_dev;
  110. };
  111. #define AS73211_COLOR_CHANNEL(_color, _si, _addr) { \
  112. .type = IIO_INTENSITY, \
  113. .modified = 1, \
  114. .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | BIT(IIO_CHAN_INFO_SCALE), \
  115. .info_mask_shared_by_type = \
  116. BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
  117. BIT(IIO_CHAN_INFO_HARDWAREGAIN) | \
  118. BIT(IIO_CHAN_INFO_INT_TIME), \
  119. .info_mask_shared_by_type_available = \
  120. BIT(IIO_CHAN_INFO_SAMP_FREQ) | \
  121. BIT(IIO_CHAN_INFO_HARDWAREGAIN) | \
  122. BIT(IIO_CHAN_INFO_INT_TIME), \
  123. .channel2 = IIO_MOD_##_color, \
  124. .address = _addr, \
  125. .scan_index = _si, \
  126. .scan_type = { \
  127. .sign = 'u', \
  128. .realbits = 16, \
  129. .storagebits = 16, \
  130. .endianness = IIO_LE, \
  131. }, \
  132. }
  133. #define AS73211_OFFSET_TEMP_INT (-66)
  134. #define AS73211_OFFSET_TEMP_MICRO 900000
  135. #define AS73211_SCALE_TEMP_INT 0
  136. #define AS73211_SCALE_TEMP_MICRO 50000
  137. #define AS73211_SCALE_X 277071108 /* nW/m^2 */
  138. #define AS73211_SCALE_Y 298384270 /* nW/m^2 */
  139. #define AS73211_SCALE_Z 160241927 /* nW/m^2 */
  140. #define AS7331_SCALE_UVA 340000 /* nW/cm^2 */
  141. #define AS7331_SCALE_UVB 378000 /* nW/cm^2 */
  142. #define AS7331_SCALE_UVC 166000 /* nW/cm^2 */
  143. /* Channel order MUST match devices result register order */
  144. #define AS73211_SCAN_INDEX_TEMP 0
  145. #define AS73211_SCAN_INDEX_X 1
  146. #define AS73211_SCAN_INDEX_Y 2
  147. #define AS73211_SCAN_INDEX_Z 3
  148. #define AS73211_SCAN_INDEX_TS 4
  149. #define AS73211_SCAN_MASK_COLOR ( \
  150. BIT(AS73211_SCAN_INDEX_X) | \
  151. BIT(AS73211_SCAN_INDEX_Y) | \
  152. BIT(AS73211_SCAN_INDEX_Z))
  153. #define AS73211_SCAN_MASK_ALL ( \
  154. BIT(AS73211_SCAN_INDEX_TEMP) | \
  155. AS73211_SCAN_MASK_COLOR)
  156. static const unsigned long as73211_scan_masks[] = {
  157. AS73211_SCAN_MASK_COLOR,
  158. AS73211_SCAN_MASK_ALL,
  159. 0
  160. };
  161. static const struct iio_chan_spec as73211_channels[] = {
  162. {
  163. .type = IIO_TEMP,
  164. .info_mask_separate =
  165. BIT(IIO_CHAN_INFO_RAW) |
  166. BIT(IIO_CHAN_INFO_OFFSET) |
  167. BIT(IIO_CHAN_INFO_SCALE),
  168. .address = AS73211_OUT_TEMP,
  169. .scan_index = AS73211_SCAN_INDEX_TEMP,
  170. .scan_type = {
  171. .sign = 'u',
  172. .realbits = 16,
  173. .storagebits = 16,
  174. .endianness = IIO_LE,
  175. }
  176. },
  177. AS73211_COLOR_CHANNEL(X, AS73211_SCAN_INDEX_X, AS73211_OUT_MRES1),
  178. AS73211_COLOR_CHANNEL(Y, AS73211_SCAN_INDEX_Y, AS73211_OUT_MRES2),
  179. AS73211_COLOR_CHANNEL(Z, AS73211_SCAN_INDEX_Z, AS73211_OUT_MRES3),
  180. IIO_CHAN_SOFT_TIMESTAMP(AS73211_SCAN_INDEX_TS),
  181. };
  182. static const struct iio_chan_spec as7331_channels[] = {
  183. {
  184. .type = IIO_TEMP,
  185. .info_mask_separate =
  186. BIT(IIO_CHAN_INFO_RAW) |
  187. BIT(IIO_CHAN_INFO_OFFSET) |
  188. BIT(IIO_CHAN_INFO_SCALE),
  189. .address = AS73211_OUT_TEMP,
  190. .scan_index = AS73211_SCAN_INDEX_TEMP,
  191. .scan_type = {
  192. .sign = 'u',
  193. .realbits = 16,
  194. .storagebits = 16,
  195. .endianness = IIO_LE,
  196. }
  197. },
  198. AS73211_COLOR_CHANNEL(LIGHT_UVA, AS73211_SCAN_INDEX_X, AS73211_OUT_MRES1),
  199. AS73211_COLOR_CHANNEL(LIGHT_UVB, AS73211_SCAN_INDEX_Y, AS73211_OUT_MRES2),
  200. AS73211_COLOR_CHANNEL(LIGHT_DUV, AS73211_SCAN_INDEX_Z, AS73211_OUT_MRES3),
  201. IIO_CHAN_SOFT_TIMESTAMP(AS73211_SCAN_INDEX_TS),
  202. };
  203. static unsigned int as73211_integration_time_1024cyc(struct as73211_data *data)
  204. {
  205. /*
  206. * Return integration time in units of 1024 clock cycles. Integration time
  207. * in CREG1 is in powers of 2 (x 1024 cycles).
  208. */
  209. return BIT(FIELD_GET(AS73211_CREG1_TIME_MASK, data->creg1));
  210. }
  211. static unsigned int as73211_integration_time_us(struct as73211_data *data,
  212. unsigned int integration_time_1024cyc)
  213. {
  214. /*
  215. * f_samp is configured in CREG3 in powers of 2 (x 1.024 MHz)
  216. * t_cycl is configured in CREG1 in powers of 2 (x 1024 cycles)
  217. * t_int_us = 1 / (f_samp) * t_cycl * US_PER_SEC
  218. * = 1 / (2^CREG3_CCLK * 1,024,000) * 2^CREG1_CYCLES * 1,024 * US_PER_SEC
  219. * = 2^(-CREG3_CCLK) * 2^CREG1_CYCLES * 1,000
  220. * In order to get rid of negative exponents, we extend the "fraction"
  221. * by 2^3 (CREG3_CCLK,max = 3)
  222. * t_int_us = 2^(3-CREG3_CCLK) * 2^CREG1_CYCLES * 125
  223. */
  224. return BIT(3 - FIELD_GET(AS73211_CREG3_CCLK_MASK, data->creg3)) *
  225. integration_time_1024cyc * 125;
  226. }
  227. static void as73211_integration_time_calc_avail(struct as73211_data *data)
  228. {
  229. int i;
  230. for (i = 0; i < ARRAY_SIZE(data->int_time_avail) / 2; i++) {
  231. unsigned int time_us = as73211_integration_time_us(data, BIT(i));
  232. data->int_time_avail[i * 2 + 0] = time_us / USEC_PER_SEC;
  233. data->int_time_avail[i * 2 + 1] = time_us % USEC_PER_SEC;
  234. }
  235. }
  236. static unsigned int as73211_gain(struct as73211_data *data)
  237. {
  238. /* gain can be calculated from CREG1 as 2^(11 - CREG1_GAIN) */
  239. return BIT(AS73211_CREG1_GAIN_1 - FIELD_GET(AS73211_CREG1_GAIN_MASK, data->creg1));
  240. }
  241. /* must be called with as73211_data::mutex held. */
  242. static int as73211_req_data(struct as73211_data *data)
  243. {
  244. unsigned int time_us = as73211_integration_time_us(data,
  245. as73211_integration_time_1024cyc(data));
  246. struct device *dev = &data->client->dev;
  247. union i2c_smbus_data smbus_data;
  248. u16 osr_status;
  249. int ret;
  250. if (data->client->irq)
  251. reinit_completion(&data->completion);
  252. /*
  253. * During measurement, there should be no traffic on the i2c bus as the
  254. * electrical noise would disturb the measurement process.
  255. */
  256. i2c_lock_bus(data->client->adapter, I2C_LOCK_SEGMENT);
  257. data->osr &= ~AS73211_OSR_DOS_MASK;
  258. data->osr |= AS73211_OSR_DOS_MEASURE | AS73211_OSR_SS;
  259. smbus_data.byte = data->osr;
  260. ret = __i2c_smbus_xfer(data->client->adapter, data->client->addr,
  261. data->client->flags, I2C_SMBUS_WRITE,
  262. AS73211_REG_OSR, I2C_SMBUS_BYTE_DATA, &smbus_data);
  263. if (ret < 0) {
  264. i2c_unlock_bus(data->client->adapter, I2C_LOCK_SEGMENT);
  265. return ret;
  266. }
  267. /*
  268. * Reset AS73211_OSR_SS (is self clearing) in order to avoid unintentional
  269. * triggering of further measurements later.
  270. */
  271. data->osr &= ~AS73211_OSR_SS;
  272. /*
  273. * Add 33% extra margin for the timeout. fclk,min = fclk,typ - 27%.
  274. */
  275. time_us += time_us / 3;
  276. if (data->client->irq) {
  277. ret = wait_for_completion_timeout(&data->completion, usecs_to_jiffies(time_us));
  278. if (!ret) {
  279. dev_err(dev, "timeout waiting for READY IRQ\n");
  280. i2c_unlock_bus(data->client->adapter, I2C_LOCK_SEGMENT);
  281. return -ETIMEDOUT;
  282. }
  283. } else {
  284. /* Wait integration time */
  285. usleep_range(time_us, 2 * time_us);
  286. }
  287. i2c_unlock_bus(data->client->adapter, I2C_LOCK_SEGMENT);
  288. ret = i2c_smbus_read_word_data(data->client, AS73211_OUT_OSR_STATUS);
  289. if (ret < 0)
  290. return ret;
  291. osr_status = ret;
  292. if (osr_status != (AS73211_OSR_DOS_MEASURE | AS73211_OSR_STATUS_NDATA)) {
  293. if (osr_status & AS73211_OSR_SS) {
  294. dev_err(dev, "%s() Measurement has not stopped\n", __func__);
  295. return -ETIME;
  296. }
  297. if (osr_status & AS73211_OSR_STATUS_NOTREADY) {
  298. dev_err(dev, "%s() Data is not ready\n", __func__);
  299. return -ENODATA;
  300. }
  301. if (!(osr_status & AS73211_OSR_STATUS_NDATA)) {
  302. dev_err(dev, "%s() No new data available\n", __func__);
  303. return -ENODATA;
  304. }
  305. if (osr_status & AS73211_OSR_STATUS_LDATA) {
  306. dev_err(dev, "%s() Result buffer overrun\n", __func__);
  307. return -ENOBUFS;
  308. }
  309. if (osr_status & AS73211_OSR_STATUS_ADCOF) {
  310. dev_err(dev, "%s() ADC overflow\n", __func__);
  311. return -EOVERFLOW;
  312. }
  313. if (osr_status & AS73211_OSR_STATUS_MRESOF) {
  314. dev_err(dev, "%s() Measurement result overflow\n", __func__);
  315. return -EOVERFLOW;
  316. }
  317. if (osr_status & AS73211_OSR_STATUS_OUTCONVOF) {
  318. dev_err(dev, "%s() Timer overflow\n", __func__);
  319. return -EOVERFLOW;
  320. }
  321. dev_err(dev, "%s() Unexpected status value\n", __func__);
  322. return -EIO;
  323. }
  324. return 0;
  325. }
  326. static int as73211_intensity_scale(struct as73211_data *data, int chan,
  327. int *val, int *val2)
  328. {
  329. switch (chan) {
  330. case IIO_MOD_X:
  331. *val = AS73211_SCALE_X;
  332. break;
  333. case IIO_MOD_Y:
  334. *val = AS73211_SCALE_Y;
  335. break;
  336. case IIO_MOD_Z:
  337. *val = AS73211_SCALE_Z;
  338. break;
  339. default:
  340. return -EINVAL;
  341. }
  342. *val2 = as73211_integration_time_1024cyc(data) * as73211_gain(data);
  343. return IIO_VAL_FRACTIONAL;
  344. }
  345. static int as7331_intensity_scale(struct as73211_data *data, int chan,
  346. int *val, int *val2)
  347. {
  348. switch (chan) {
  349. case IIO_MOD_LIGHT_UVA:
  350. *val = AS7331_SCALE_UVA;
  351. break;
  352. case IIO_MOD_LIGHT_UVB:
  353. *val = AS7331_SCALE_UVB;
  354. break;
  355. case IIO_MOD_LIGHT_DUV:
  356. *val = AS7331_SCALE_UVC;
  357. break;
  358. default:
  359. return -EINVAL;
  360. }
  361. *val2 = as73211_integration_time_1024cyc(data) * as73211_gain(data);
  362. return IIO_VAL_FRACTIONAL;
  363. }
  364. static int as73211_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan,
  365. int *val, int *val2, long mask)
  366. {
  367. struct as73211_data *data = iio_priv(indio_dev);
  368. switch (mask) {
  369. case IIO_CHAN_INFO_RAW: {
  370. int ret;
  371. ret = iio_device_claim_direct_mode(indio_dev);
  372. if (ret < 0)
  373. return ret;
  374. ret = as73211_req_data(data);
  375. if (ret < 0) {
  376. iio_device_release_direct_mode(indio_dev);
  377. return ret;
  378. }
  379. ret = i2c_smbus_read_word_data(data->client, chan->address);
  380. iio_device_release_direct_mode(indio_dev);
  381. if (ret < 0)
  382. return ret;
  383. *val = ret;
  384. return IIO_VAL_INT;
  385. }
  386. case IIO_CHAN_INFO_OFFSET:
  387. *val = AS73211_OFFSET_TEMP_INT;
  388. *val2 = AS73211_OFFSET_TEMP_MICRO;
  389. return IIO_VAL_INT_PLUS_MICRO;
  390. case IIO_CHAN_INFO_SCALE:
  391. switch (chan->type) {
  392. case IIO_TEMP:
  393. *val = AS73211_SCALE_TEMP_INT;
  394. *val2 = AS73211_SCALE_TEMP_MICRO;
  395. return IIO_VAL_INT_PLUS_MICRO;
  396. case IIO_INTENSITY:
  397. return data->spec_dev->intensity_scale(data, chan->channel2,
  398. val, val2);
  399. default:
  400. return -EINVAL;
  401. }
  402. case IIO_CHAN_INFO_SAMP_FREQ:
  403. /* f_samp is configured in CREG3 in powers of 2 (x 1.024 MHz) */
  404. *val = BIT(FIELD_GET(AS73211_CREG3_CCLK_MASK, data->creg3)) *
  405. AS73211_SAMPLE_FREQ_BASE;
  406. return IIO_VAL_INT;
  407. case IIO_CHAN_INFO_HARDWAREGAIN:
  408. *val = as73211_gain(data);
  409. return IIO_VAL_INT;
  410. case IIO_CHAN_INFO_INT_TIME: {
  411. unsigned int time_us;
  412. mutex_lock(&data->mutex);
  413. time_us = as73211_integration_time_us(data, as73211_integration_time_1024cyc(data));
  414. mutex_unlock(&data->mutex);
  415. *val = time_us / USEC_PER_SEC;
  416. *val2 = time_us % USEC_PER_SEC;
  417. return IIO_VAL_INT_PLUS_MICRO;
  418. default:
  419. return -EINVAL;
  420. }}
  421. }
  422. static int as73211_read_avail(struct iio_dev *indio_dev, struct iio_chan_spec const *chan,
  423. const int **vals, int *type, int *length, long mask)
  424. {
  425. struct as73211_data *data = iio_priv(indio_dev);
  426. switch (mask) {
  427. case IIO_CHAN_INFO_SAMP_FREQ:
  428. *length = ARRAY_SIZE(as73211_samp_freq_avail);
  429. *vals = as73211_samp_freq_avail;
  430. *type = IIO_VAL_INT;
  431. return IIO_AVAIL_LIST;
  432. case IIO_CHAN_INFO_HARDWAREGAIN:
  433. *length = ARRAY_SIZE(as73211_hardwaregain_avail);
  434. *vals = as73211_hardwaregain_avail;
  435. *type = IIO_VAL_INT;
  436. return IIO_AVAIL_LIST;
  437. case IIO_CHAN_INFO_INT_TIME:
  438. *length = ARRAY_SIZE(data->int_time_avail);
  439. *vals = data->int_time_avail;
  440. *type = IIO_VAL_INT_PLUS_MICRO;
  441. return IIO_AVAIL_LIST;
  442. default:
  443. return -EINVAL;
  444. }
  445. }
  446. static int _as73211_write_raw(struct iio_dev *indio_dev,
  447. struct iio_chan_spec const *chan __always_unused,
  448. int val, int val2, long mask)
  449. {
  450. struct as73211_data *data = iio_priv(indio_dev);
  451. int ret;
  452. switch (mask) {
  453. case IIO_CHAN_INFO_SAMP_FREQ: {
  454. int reg_bits, freq_kHz = val / HZ_PER_KHZ; /* 1024, 2048, ... */
  455. /* val must be 1024 * 2^x */
  456. if (val < 0 || (freq_kHz * HZ_PER_KHZ) != val ||
  457. !is_power_of_2(freq_kHz) || val2)
  458. return -EINVAL;
  459. /* f_samp is configured in CREG3 in powers of 2 (x 1.024 MHz (=2^10)) */
  460. reg_bits = ilog2(freq_kHz) - 10;
  461. if (!FIELD_FIT(AS73211_CREG3_CCLK_MASK, reg_bits))
  462. return -EINVAL;
  463. data->creg3 &= ~AS73211_CREG3_CCLK_MASK;
  464. data->creg3 |= FIELD_PREP(AS73211_CREG3_CCLK_MASK, reg_bits);
  465. as73211_integration_time_calc_avail(data);
  466. ret = i2c_smbus_write_byte_data(data->client, AS73211_REG_CREG3, data->creg3);
  467. if (ret < 0)
  468. return ret;
  469. return 0;
  470. }
  471. case IIO_CHAN_INFO_HARDWAREGAIN: {
  472. unsigned int reg_bits;
  473. if (val < 0 || !is_power_of_2(val) || val2)
  474. return -EINVAL;
  475. /* gain can be calculated from CREG1 as 2^(11 - CREG1_GAIN) */
  476. reg_bits = AS73211_CREG1_GAIN_1 - ilog2(val);
  477. if (!FIELD_FIT(AS73211_CREG1_GAIN_MASK, reg_bits))
  478. return -EINVAL;
  479. data->creg1 &= ~AS73211_CREG1_GAIN_MASK;
  480. data->creg1 |= FIELD_PREP(AS73211_CREG1_GAIN_MASK, reg_bits);
  481. ret = i2c_smbus_write_byte_data(data->client, AS73211_REG_CREG1, data->creg1);
  482. if (ret < 0)
  483. return ret;
  484. return 0;
  485. }
  486. case IIO_CHAN_INFO_INT_TIME: {
  487. int val_us = val * USEC_PER_SEC + val2;
  488. int time_ms;
  489. int reg_bits;
  490. /* f_samp is configured in CREG3 in powers of 2 (x 1.024 MHz) */
  491. int f_samp_1_024mhz = BIT(FIELD_GET(AS73211_CREG3_CCLK_MASK, data->creg3));
  492. /*
  493. * time_ms = time_us * US_PER_MS * f_samp_1_024mhz / MHZ_PER_HZ
  494. * = time_us * f_samp_1_024mhz / 1000
  495. */
  496. time_ms = (val_us * f_samp_1_024mhz) / 1000; /* 1 ms, 2 ms, ... (power of two) */
  497. if (time_ms < 0 || !is_power_of_2(time_ms) || time_ms > AS73211_SAMPLE_TIME_MAX_MS)
  498. return -EINVAL;
  499. reg_bits = ilog2(time_ms);
  500. if (!FIELD_FIT(AS73211_CREG1_TIME_MASK, reg_bits))
  501. return -EINVAL; /* not possible due to previous tests */
  502. data->creg1 &= ~AS73211_CREG1_TIME_MASK;
  503. data->creg1 |= FIELD_PREP(AS73211_CREG1_TIME_MASK, reg_bits);
  504. ret = i2c_smbus_write_byte_data(data->client, AS73211_REG_CREG1, data->creg1);
  505. if (ret < 0)
  506. return ret;
  507. return 0;
  508. default:
  509. return -EINVAL;
  510. }}
  511. }
  512. static int as73211_write_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan,
  513. int val, int val2, long mask)
  514. {
  515. struct as73211_data *data = iio_priv(indio_dev);
  516. int ret;
  517. mutex_lock(&data->mutex);
  518. ret = iio_device_claim_direct_mode(indio_dev);
  519. if (ret < 0)
  520. goto error_unlock;
  521. /* Need to switch to config mode ... */
  522. if ((data->osr & AS73211_OSR_DOS_MASK) != AS73211_OSR_DOS_CONFIG) {
  523. data->osr &= ~AS73211_OSR_DOS_MASK;
  524. data->osr |= AS73211_OSR_DOS_CONFIG;
  525. ret = i2c_smbus_write_byte_data(data->client, AS73211_REG_OSR, data->osr);
  526. if (ret < 0)
  527. goto error_release;
  528. }
  529. ret = _as73211_write_raw(indio_dev, chan, val, val2, mask);
  530. error_release:
  531. iio_device_release_direct_mode(indio_dev);
  532. error_unlock:
  533. mutex_unlock(&data->mutex);
  534. return ret;
  535. }
  536. static irqreturn_t as73211_ready_handler(int irq __always_unused, void *priv)
  537. {
  538. struct as73211_data *data = iio_priv(priv);
  539. complete(&data->completion);
  540. return IRQ_HANDLED;
  541. }
  542. static irqreturn_t as73211_trigger_handler(int irq __always_unused, void *p)
  543. {
  544. struct iio_poll_func *pf = p;
  545. struct iio_dev *indio_dev = pf->indio_dev;
  546. struct as73211_data *data = iio_priv(indio_dev);
  547. struct {
  548. __le16 chan[4];
  549. s64 ts __aligned(8);
  550. } scan;
  551. int data_result, ret;
  552. mutex_lock(&data->mutex);
  553. data_result = as73211_req_data(data);
  554. if (data_result < 0 && data_result != -EOVERFLOW)
  555. goto done; /* don't push any data for errors other than EOVERFLOW */
  556. if (*indio_dev->active_scan_mask == AS73211_SCAN_MASK_ALL) {
  557. /* Optimization for reading all (color + temperature) channels */
  558. u8 addr = as73211_channels[0].address;
  559. struct i2c_msg msgs[] = {
  560. {
  561. .addr = data->client->addr,
  562. .flags = 0,
  563. .len = 1,
  564. .buf = &addr,
  565. },
  566. {
  567. .addr = data->client->addr,
  568. .flags = I2C_M_RD,
  569. .len = sizeof(scan.chan),
  570. .buf = (u8 *)&scan.chan,
  571. },
  572. };
  573. ret = i2c_transfer(data->client->adapter, msgs, ARRAY_SIZE(msgs));
  574. if (ret < 0)
  575. goto done;
  576. } else {
  577. /* Optimization for reading only color channels */
  578. /* AS73211 starts reading at address 2 */
  579. ret = i2c_master_recv(data->client,
  580. (char *)&scan.chan[0], 3 * sizeof(scan.chan[0]));
  581. if (ret < 0)
  582. goto done;
  583. /* Avoid pushing uninitialized data */
  584. scan.chan[3] = 0;
  585. }
  586. if (data_result) {
  587. /*
  588. * Saturate all channels (in case of overflows). Temperature channel
  589. * is not affected by overflows.
  590. */
  591. if (*indio_dev->active_scan_mask == AS73211_SCAN_MASK_ALL) {
  592. scan.chan[1] = cpu_to_le16(U16_MAX);
  593. scan.chan[2] = cpu_to_le16(U16_MAX);
  594. scan.chan[3] = cpu_to_le16(U16_MAX);
  595. } else {
  596. scan.chan[0] = cpu_to_le16(U16_MAX);
  597. scan.chan[1] = cpu_to_le16(U16_MAX);
  598. scan.chan[2] = cpu_to_le16(U16_MAX);
  599. }
  600. }
  601. iio_push_to_buffers_with_timestamp(indio_dev, &scan, iio_get_time_ns(indio_dev));
  602. done:
  603. mutex_unlock(&data->mutex);
  604. iio_trigger_notify_done(indio_dev->trig);
  605. return IRQ_HANDLED;
  606. }
  607. static const struct iio_info as73211_info = {
  608. .read_raw = as73211_read_raw,
  609. .read_avail = as73211_read_avail,
  610. .write_raw = as73211_write_raw,
  611. };
  612. static int as73211_power(struct iio_dev *indio_dev, bool state)
  613. {
  614. struct as73211_data *data = iio_priv(indio_dev);
  615. int ret;
  616. mutex_lock(&data->mutex);
  617. if (state)
  618. data->osr &= ~AS73211_OSR_PD;
  619. else
  620. data->osr |= AS73211_OSR_PD;
  621. ret = i2c_smbus_write_byte_data(data->client, AS73211_REG_OSR, data->osr);
  622. mutex_unlock(&data->mutex);
  623. if (ret < 0)
  624. return ret;
  625. return 0;
  626. }
  627. static void as73211_power_disable(void *data)
  628. {
  629. struct iio_dev *indio_dev = data;
  630. as73211_power(indio_dev, false);
  631. }
  632. static int as73211_probe(struct i2c_client *client)
  633. {
  634. struct device *dev = &client->dev;
  635. struct as73211_data *data;
  636. struct iio_dev *indio_dev;
  637. int ret;
  638. indio_dev = devm_iio_device_alloc(dev, sizeof(*data));
  639. if (!indio_dev)
  640. return -ENOMEM;
  641. data = iio_priv(indio_dev);
  642. i2c_set_clientdata(client, indio_dev);
  643. data->client = client;
  644. data->spec_dev = i2c_get_match_data(client);
  645. if (!data->spec_dev)
  646. return -EINVAL;
  647. mutex_init(&data->mutex);
  648. init_completion(&data->completion);
  649. indio_dev->info = &as73211_info;
  650. indio_dev->name = AS73211_DRV_NAME;
  651. indio_dev->channels = data->spec_dev->channels;
  652. indio_dev->num_channels = data->spec_dev->num_channels;
  653. indio_dev->modes = INDIO_DIRECT_MODE;
  654. indio_dev->available_scan_masks = as73211_scan_masks;
  655. ret = i2c_smbus_read_byte_data(data->client, AS73211_REG_OSR);
  656. if (ret < 0)
  657. return ret;
  658. data->osr = ret;
  659. /* reset device */
  660. data->osr |= AS73211_OSR_SW_RES;
  661. ret = i2c_smbus_write_byte_data(data->client, AS73211_REG_OSR, data->osr);
  662. if (ret < 0)
  663. return ret;
  664. ret = i2c_smbus_read_byte_data(data->client, AS73211_REG_OSR);
  665. if (ret < 0)
  666. return ret;
  667. data->osr = ret;
  668. /*
  669. * Reading AGEN is only possible after reset (AGEN is not available if
  670. * device is in measurement mode).
  671. */
  672. ret = i2c_smbus_read_byte_data(data->client, AS73211_REG_AGEN);
  673. if (ret < 0)
  674. return ret;
  675. /* At the time of writing this driver, only DEVID 2 and MUT 1 are known. */
  676. if ((ret & AS73211_AGEN_DEVID_MASK) != AS73211_AGEN_DEVID(2) ||
  677. (ret & AS73211_AGEN_MUT_MASK) != AS73211_AGEN_MUT(1))
  678. return -ENODEV;
  679. ret = i2c_smbus_read_byte_data(data->client, AS73211_REG_CREG1);
  680. if (ret < 0)
  681. return ret;
  682. data->creg1 = ret;
  683. ret = i2c_smbus_read_byte_data(data->client, AS73211_REG_CREG2);
  684. if (ret < 0)
  685. return ret;
  686. data->creg2 = ret;
  687. ret = i2c_smbus_read_byte_data(data->client, AS73211_REG_CREG3);
  688. if (ret < 0)
  689. return ret;
  690. data->creg3 = ret;
  691. as73211_integration_time_calc_avail(data);
  692. ret = as73211_power(indio_dev, true);
  693. if (ret < 0)
  694. return ret;
  695. ret = devm_add_action_or_reset(dev, as73211_power_disable, indio_dev);
  696. if (ret)
  697. return ret;
  698. ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL, as73211_trigger_handler, NULL);
  699. if (ret)
  700. return ret;
  701. if (client->irq) {
  702. ret = devm_request_threaded_irq(&client->dev, client->irq,
  703. NULL,
  704. as73211_ready_handler,
  705. IRQF_ONESHOT,
  706. client->name, indio_dev);
  707. if (ret)
  708. return ret;
  709. }
  710. return devm_iio_device_register(dev, indio_dev);
  711. }
  712. static int as73211_suspend(struct device *dev)
  713. {
  714. struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
  715. return as73211_power(indio_dev, false);
  716. }
  717. static int as73211_resume(struct device *dev)
  718. {
  719. struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev));
  720. return as73211_power(indio_dev, true);
  721. }
  722. static DEFINE_SIMPLE_DEV_PM_OPS(as73211_pm_ops, as73211_suspend,
  723. as73211_resume);
  724. static const struct as73211_spec_dev_data as73211_spec = {
  725. .intensity_scale = as73211_intensity_scale,
  726. .channels = as73211_channels,
  727. .num_channels = ARRAY_SIZE(as73211_channels),
  728. };
  729. static const struct as73211_spec_dev_data as7331_spec = {
  730. .intensity_scale = as7331_intensity_scale,
  731. .channels = as7331_channels,
  732. .num_channels = ARRAY_SIZE(as7331_channels),
  733. };
  734. static const struct of_device_id as73211_of_match[] = {
  735. { .compatible = "ams,as73211", &as73211_spec },
  736. { .compatible = "ams,as7331", &as7331_spec },
  737. { }
  738. };
  739. MODULE_DEVICE_TABLE(of, as73211_of_match);
  740. static const struct i2c_device_id as73211_id[] = {
  741. { "as73211", (kernel_ulong_t)&as73211_spec },
  742. { "as7331", (kernel_ulong_t)&as7331_spec },
  743. { }
  744. };
  745. MODULE_DEVICE_TABLE(i2c, as73211_id);
  746. static struct i2c_driver as73211_driver = {
  747. .driver = {
  748. .name = AS73211_DRV_NAME,
  749. .of_match_table = as73211_of_match,
  750. .pm = pm_sleep_ptr(&as73211_pm_ops),
  751. },
  752. .probe = as73211_probe,
  753. .id_table = as73211_id,
  754. };
  755. module_i2c_driver(as73211_driver);
  756. MODULE_AUTHOR("Christian Eggers <ceggers@arri.de>");
  757. MODULE_DESCRIPTION("AS73211 XYZ True Color Sensor driver");
  758. MODULE_LICENSE("GPL");