si1133.c 25 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * si1133.c - Support for Silabs SI1133 combined ambient
  4. * light and UV index sensors
  5. *
  6. * Copyright 2018 Maxime Roussin-Belanger <maxime.roussinbelanger@gmail.com>
  7. */
  8. #include <linux/delay.h>
  9. #include <linux/i2c.h>
  10. #include <linux/interrupt.h>
  11. #include <linux/module.h>
  12. #include <linux/regmap.h>
  13. #include <linux/iio/iio.h>
  14. #include <linux/iio/sysfs.h>
  15. #include <linux/util_macros.h>
  16. #define SI1133_REG_PART_ID 0x00
  17. #define SI1133_REG_REV_ID 0x01
  18. #define SI1133_REG_MFR_ID 0x02
  19. #define SI1133_REG_INFO0 0x03
  20. #define SI1133_REG_INFO1 0x04
  21. #define SI1133_PART_ID 0x33
  22. #define SI1133_REG_HOSTIN0 0x0A
  23. #define SI1133_REG_COMMAND 0x0B
  24. #define SI1133_REG_IRQ_ENABLE 0x0F
  25. #define SI1133_REG_RESPONSE1 0x10
  26. #define SI1133_REG_RESPONSE0 0x11
  27. #define SI1133_REG_IRQ_STATUS 0x12
  28. #define SI1133_REG_MEAS_RATE 0x1A
  29. #define SI1133_IRQ_CHANNEL_ENABLE 0xF
  30. #define SI1133_CMD_RESET_CTR 0x00
  31. #define SI1133_CMD_RESET_SW 0x01
  32. #define SI1133_CMD_FORCE 0x11
  33. #define SI1133_CMD_START_AUTONOMOUS 0x13
  34. #define SI1133_CMD_PARAM_SET 0x80
  35. #define SI1133_CMD_PARAM_QUERY 0x40
  36. #define SI1133_CMD_PARAM_MASK 0x3F
  37. #define SI1133_CMD_ERR_MASK BIT(4)
  38. #define SI1133_CMD_SEQ_MASK 0xF
  39. #define SI1133_MAX_CMD_CTR 0xF
  40. #define SI1133_PARAM_REG_CHAN_LIST 0x01
  41. #define SI1133_PARAM_REG_ADCCONFIG(x) ((x) * 4) + 2
  42. #define SI1133_PARAM_REG_ADCSENS(x) ((x) * 4) + 3
  43. #define SI1133_PARAM_REG_ADCPOST(x) ((x) * 4) + 4
  44. #define SI1133_ADCMUX_MASK 0x1F
  45. #define SI1133_ADCCONFIG_DECIM_RATE(x) (x) << 5
  46. #define SI1133_ADCSENS_SCALE_MASK 0x70
  47. #define SI1133_ADCSENS_SCALE_SHIFT 4
  48. #define SI1133_ADCSENS_HSIG_MASK BIT(7)
  49. #define SI1133_ADCSENS_HSIG_SHIFT 7
  50. #define SI1133_ADCSENS_HW_GAIN_MASK 0xF
  51. #define SI1133_ADCSENS_NB_MEAS(x) fls(x) << SI1133_ADCSENS_SCALE_SHIFT
  52. #define SI1133_ADCPOST_24BIT_EN BIT(6)
  53. #define SI1133_ADCPOST_POSTSHIFT_BITQTY(x) (x & GENMASK(2, 0)) << 3
  54. #define SI1133_PARAM_ADCMUX_SMALL_IR 0x0
  55. #define SI1133_PARAM_ADCMUX_MED_IR 0x1
  56. #define SI1133_PARAM_ADCMUX_LARGE_IR 0x2
  57. #define SI1133_PARAM_ADCMUX_WHITE 0xB
  58. #define SI1133_PARAM_ADCMUX_LARGE_WHITE 0xD
  59. #define SI1133_PARAM_ADCMUX_UV 0x18
  60. #define SI1133_PARAM_ADCMUX_UV_DEEP 0x19
  61. #define SI1133_ERR_INVALID_CMD 0x0
  62. #define SI1133_ERR_INVALID_LOCATION_CMD 0x1
  63. #define SI1133_ERR_SATURATION_ADC_OR_OVERFLOW_ACCUMULATION 0x2
  64. #define SI1133_ERR_OUTPUT_BUFFER_OVERFLOW 0x3
  65. #define SI1133_COMPLETION_TIMEOUT_MS 500
  66. #define SI1133_CMD_MINSLEEP_US_LOW 5000
  67. #define SI1133_CMD_MINSLEEP_US_HIGH 7500
  68. #define SI1133_CMD_TIMEOUT_MS 25
  69. #define SI1133_CMD_LUX_TIMEOUT_MS 5000
  70. #define SI1133_CMD_TIMEOUT_US SI1133_CMD_TIMEOUT_MS * 1000
  71. #define SI1133_REG_HOSTOUT(x) (x) + 0x13
  72. #define SI1133_MEASUREMENT_FREQUENCY 1250
  73. #define SI1133_X_ORDER_MASK 0x0070
  74. #define SI1133_Y_ORDER_MASK 0x0007
  75. #define si1133_get_x_order(m) ((m) & SI1133_X_ORDER_MASK) >> 4
  76. #define si1133_get_y_order(m) ((m) & SI1133_Y_ORDER_MASK)
  77. #define SI1133_LUX_ADC_MASK 0xE
  78. #define SI1133_ADC_THRESHOLD 16000
  79. #define SI1133_INPUT_FRACTION_HIGH 7
  80. #define SI1133_INPUT_FRACTION_LOW 15
  81. #define SI1133_LUX_OUTPUT_FRACTION 12
  82. #define SI1133_LUX_BUFFER_SIZE 9
  83. static const int si1133_scale_available[] = {
  84. 1, 2, 4, 8, 16, 32, 64, 128};
  85. static IIO_CONST_ATTR(scale_available, "1 2 4 8 16 32 64 128");
  86. static IIO_CONST_ATTR_INT_TIME_AVAIL("0.0244 0.0488 0.0975 0.195 0.390 0.780 "
  87. "1.560 3.120 6.24 12.48 25.0 50.0");
  88. /* A.K.A. HW_GAIN in datasheet */
  89. enum si1133_int_time {
  90. _24_4_us = 0,
  91. _48_8_us = 1,
  92. _97_5_us = 2,
  93. _195_0_us = 3,
  94. _390_0_us = 4,
  95. _780_0_us = 5,
  96. _1_560_0_us = 6,
  97. _3_120_0_us = 7,
  98. _6_240_0_us = 8,
  99. _12_480_0_us = 9,
  100. _25_ms = 10,
  101. _50_ms = 11,
  102. };
  103. /* Integration time in milliseconds, nanoseconds */
  104. static const int si1133_int_time_table[][2] = {
  105. [_24_4_us] = {0, 24400},
  106. [_48_8_us] = {0, 48800},
  107. [_97_5_us] = {0, 97500},
  108. [_195_0_us] = {0, 195000},
  109. [_390_0_us] = {0, 390000},
  110. [_780_0_us] = {0, 780000},
  111. [_1_560_0_us] = {1, 560000},
  112. [_3_120_0_us] = {3, 120000},
  113. [_6_240_0_us] = {6, 240000},
  114. [_12_480_0_us] = {12, 480000},
  115. [_25_ms] = {25, 000000},
  116. [_50_ms] = {50, 000000},
  117. };
  118. static const struct regmap_range si1133_reg_ranges[] = {
  119. regmap_reg_range(0x00, 0x02),
  120. regmap_reg_range(0x0A, 0x0B),
  121. regmap_reg_range(0x0F, 0x0F),
  122. regmap_reg_range(0x10, 0x12),
  123. regmap_reg_range(0x13, 0x2C),
  124. };
  125. static const struct regmap_range si1133_reg_ro_ranges[] = {
  126. regmap_reg_range(0x00, 0x02),
  127. regmap_reg_range(0x10, 0x2C),
  128. };
  129. static const struct regmap_range si1133_precious_ranges[] = {
  130. regmap_reg_range(0x12, 0x12),
  131. };
  132. static const struct regmap_access_table si1133_write_ranges_table = {
  133. .yes_ranges = si1133_reg_ranges,
  134. .n_yes_ranges = ARRAY_SIZE(si1133_reg_ranges),
  135. .no_ranges = si1133_reg_ro_ranges,
  136. .n_no_ranges = ARRAY_SIZE(si1133_reg_ro_ranges),
  137. };
  138. static const struct regmap_access_table si1133_read_ranges_table = {
  139. .yes_ranges = si1133_reg_ranges,
  140. .n_yes_ranges = ARRAY_SIZE(si1133_reg_ranges),
  141. };
  142. static const struct regmap_access_table si1133_precious_table = {
  143. .yes_ranges = si1133_precious_ranges,
  144. .n_yes_ranges = ARRAY_SIZE(si1133_precious_ranges),
  145. };
  146. static const struct regmap_config si1133_regmap_config = {
  147. .reg_bits = 8,
  148. .val_bits = 8,
  149. .max_register = 0x2C,
  150. .wr_table = &si1133_write_ranges_table,
  151. .rd_table = &si1133_read_ranges_table,
  152. .precious_table = &si1133_precious_table,
  153. };
  154. struct si1133_data {
  155. struct regmap *regmap;
  156. struct i2c_client *client;
  157. /* Lock protecting one command at a time can be processed */
  158. struct mutex mutex;
  159. int rsp_seq;
  160. u8 scan_mask;
  161. u8 adc_sens[6];
  162. u8 adc_config[6];
  163. struct completion completion;
  164. };
  165. struct si1133_coeff {
  166. s16 info;
  167. u16 mag;
  168. };
  169. struct si1133_lux_coeff {
  170. struct si1133_coeff coeff_high[4];
  171. struct si1133_coeff coeff_low[9];
  172. };
  173. static const struct si1133_lux_coeff lux_coeff = {
  174. {
  175. { 0, 209},
  176. { 1665, 93},
  177. { 2064, 65},
  178. {-2671, 234}
  179. },
  180. {
  181. { 0, 0},
  182. { 1921, 29053},
  183. {-1022, 36363},
  184. { 2320, 20789},
  185. { -367, 57909},
  186. {-1774, 38240},
  187. { -608, 46775},
  188. {-1503, 51831},
  189. {-1886, 58928}
  190. }
  191. };
  192. static int si1133_calculate_polynomial_inner(u32 input, u8 fraction, u16 mag,
  193. s8 shift)
  194. {
  195. return ((input << fraction) / mag) << shift;
  196. }
  197. static int si1133_calculate_output(u32 x, u32 y, u8 x_order, u8 y_order,
  198. u8 input_fraction, s8 sign,
  199. const struct si1133_coeff *coeffs)
  200. {
  201. s8 shift;
  202. int x1 = 1;
  203. int x2 = 1;
  204. int y1 = 1;
  205. int y2 = 1;
  206. shift = ((u16)coeffs->info & 0xFF00) >> 8;
  207. shift ^= 0xFF;
  208. shift += 1;
  209. shift = -shift;
  210. if (x_order > 0) {
  211. x1 = si1133_calculate_polynomial_inner(x, input_fraction,
  212. coeffs->mag, shift);
  213. if (x_order > 1)
  214. x2 = x1;
  215. }
  216. if (y_order > 0) {
  217. y1 = si1133_calculate_polynomial_inner(y, input_fraction,
  218. coeffs->mag, shift);
  219. if (y_order > 1)
  220. y2 = y1;
  221. }
  222. return sign * x1 * x2 * y1 * y2;
  223. }
  224. /*
  225. * The algorithm is from:
  226. * https://siliconlabs.github.io/Gecko_SDK_Doc/efm32zg/html/si1133_8c_source.html#l00716
  227. */
  228. static int si1133_calc_polynomial(u32 x, u32 y, u8 input_fraction, u8 num_coeff,
  229. const struct si1133_coeff *coeffs)
  230. {
  231. u8 x_order, y_order;
  232. u8 counter;
  233. s8 sign;
  234. int output = 0;
  235. for (counter = 0; counter < num_coeff; counter++) {
  236. if (coeffs->info < 0)
  237. sign = -1;
  238. else
  239. sign = 1;
  240. x_order = si1133_get_x_order(coeffs->info);
  241. y_order = si1133_get_y_order(coeffs->info);
  242. if ((x_order == 0) && (y_order == 0))
  243. output +=
  244. sign * coeffs->mag << SI1133_LUX_OUTPUT_FRACTION;
  245. else
  246. output += si1133_calculate_output(x, y, x_order,
  247. y_order,
  248. input_fraction, sign,
  249. coeffs);
  250. coeffs++;
  251. }
  252. return abs(output);
  253. }
  254. static int si1133_cmd_reset_sw(struct si1133_data *data)
  255. {
  256. struct device *dev = &data->client->dev;
  257. unsigned int resp;
  258. unsigned long timeout;
  259. int err;
  260. err = regmap_write(data->regmap, SI1133_REG_COMMAND,
  261. SI1133_CMD_RESET_SW);
  262. if (err)
  263. return err;
  264. timeout = jiffies + msecs_to_jiffies(SI1133_CMD_TIMEOUT_MS);
  265. while (true) {
  266. err = regmap_read(data->regmap, SI1133_REG_RESPONSE0, &resp);
  267. if (err == -ENXIO) {
  268. usleep_range(SI1133_CMD_MINSLEEP_US_LOW,
  269. SI1133_CMD_MINSLEEP_US_HIGH);
  270. continue;
  271. }
  272. if ((resp & SI1133_MAX_CMD_CTR) == SI1133_MAX_CMD_CTR)
  273. break;
  274. if (time_after(jiffies, timeout)) {
  275. dev_warn(dev, "Timeout on reset ctr resp: %d\n", resp);
  276. return -ETIMEDOUT;
  277. }
  278. }
  279. if (!err)
  280. data->rsp_seq = SI1133_MAX_CMD_CTR;
  281. return err;
  282. }
  283. static int si1133_parse_response_err(struct device *dev, u32 resp, u8 cmd)
  284. {
  285. resp &= 0xF;
  286. switch (resp) {
  287. case SI1133_ERR_OUTPUT_BUFFER_OVERFLOW:
  288. dev_warn(dev, "Output buffer overflow: %#02hhx\n", cmd);
  289. return -EOVERFLOW;
  290. case SI1133_ERR_SATURATION_ADC_OR_OVERFLOW_ACCUMULATION:
  291. dev_warn(dev, "Saturation of the ADC or overflow of accumulation: %#02hhx\n",
  292. cmd);
  293. return -EOVERFLOW;
  294. case SI1133_ERR_INVALID_LOCATION_CMD:
  295. dev_warn(dev,
  296. "Parameter access to an invalid location: %#02hhx\n",
  297. cmd);
  298. return -EINVAL;
  299. case SI1133_ERR_INVALID_CMD:
  300. dev_warn(dev, "Invalid command %#02hhx\n", cmd);
  301. return -EINVAL;
  302. default:
  303. dev_warn(dev, "Unknown error %#02hhx\n", cmd);
  304. return -EINVAL;
  305. }
  306. }
  307. static int si1133_cmd_reset_counter(struct si1133_data *data)
  308. {
  309. int err = regmap_write(data->regmap, SI1133_REG_COMMAND,
  310. SI1133_CMD_RESET_CTR);
  311. if (err)
  312. return err;
  313. data->rsp_seq = 0;
  314. return 0;
  315. }
  316. static int si1133_command(struct si1133_data *data, u8 cmd)
  317. {
  318. struct device *dev = &data->client->dev;
  319. u32 resp;
  320. int err;
  321. int expected_seq;
  322. mutex_lock(&data->mutex);
  323. expected_seq = (data->rsp_seq + 1) & SI1133_MAX_CMD_CTR;
  324. if (cmd == SI1133_CMD_FORCE)
  325. reinit_completion(&data->completion);
  326. err = regmap_write(data->regmap, SI1133_REG_COMMAND, cmd);
  327. if (err) {
  328. dev_warn(dev, "Failed to write command %#02hhx, ret=%d\n", cmd,
  329. err);
  330. goto out;
  331. }
  332. if (cmd == SI1133_CMD_FORCE) {
  333. /* wait for irq */
  334. if (!wait_for_completion_timeout(&data->completion,
  335. msecs_to_jiffies(SI1133_COMPLETION_TIMEOUT_MS))) {
  336. err = -ETIMEDOUT;
  337. goto out;
  338. }
  339. err = regmap_read(data->regmap, SI1133_REG_RESPONSE0, &resp);
  340. if (err)
  341. goto out;
  342. } else {
  343. err = regmap_read_poll_timeout(data->regmap,
  344. SI1133_REG_RESPONSE0, resp,
  345. (resp & SI1133_CMD_SEQ_MASK) ==
  346. expected_seq ||
  347. (resp & SI1133_CMD_ERR_MASK),
  348. SI1133_CMD_MINSLEEP_US_LOW,
  349. SI1133_CMD_TIMEOUT_MS * 1000);
  350. if (err) {
  351. dev_warn(dev,
  352. "Failed to read command %#02hhx, ret=%d\n",
  353. cmd, err);
  354. goto out;
  355. }
  356. }
  357. if (resp & SI1133_CMD_ERR_MASK) {
  358. err = si1133_parse_response_err(dev, resp, cmd);
  359. si1133_cmd_reset_counter(data);
  360. } else {
  361. data->rsp_seq = expected_seq;
  362. }
  363. out:
  364. mutex_unlock(&data->mutex);
  365. return err;
  366. }
  367. static int si1133_param_set(struct si1133_data *data, u8 param, u32 value)
  368. {
  369. int err = regmap_write(data->regmap, SI1133_REG_HOSTIN0, value);
  370. if (err)
  371. return err;
  372. return si1133_command(data, SI1133_CMD_PARAM_SET |
  373. (param & SI1133_CMD_PARAM_MASK));
  374. }
  375. static int si1133_param_query(struct si1133_data *data, u8 param, u32 *result)
  376. {
  377. int err = si1133_command(data, SI1133_CMD_PARAM_QUERY |
  378. (param & SI1133_CMD_PARAM_MASK));
  379. if (err)
  380. return err;
  381. return regmap_read(data->regmap, SI1133_REG_RESPONSE1, result);
  382. }
  383. #define SI1133_CHANNEL(_ch, _type) \
  384. .type = _type, \
  385. .channel = _ch, \
  386. .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \
  387. .info_mask_shared_by_all = BIT(IIO_CHAN_INFO_INT_TIME) | \
  388. BIT(IIO_CHAN_INFO_SCALE) | \
  389. BIT(IIO_CHAN_INFO_HARDWAREGAIN), \
  390. static const struct iio_chan_spec si1133_channels[] = {
  391. {
  392. .type = IIO_LIGHT,
  393. .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),
  394. .channel = 0,
  395. },
  396. {
  397. SI1133_CHANNEL(SI1133_PARAM_ADCMUX_WHITE, IIO_INTENSITY)
  398. .channel2 = IIO_MOD_LIGHT_BOTH,
  399. },
  400. {
  401. SI1133_CHANNEL(SI1133_PARAM_ADCMUX_LARGE_WHITE, IIO_INTENSITY)
  402. .channel2 = IIO_MOD_LIGHT_BOTH,
  403. .extend_name = "large",
  404. },
  405. {
  406. SI1133_CHANNEL(SI1133_PARAM_ADCMUX_SMALL_IR, IIO_INTENSITY)
  407. .extend_name = "small",
  408. .modified = 1,
  409. .channel2 = IIO_MOD_LIGHT_IR,
  410. },
  411. {
  412. SI1133_CHANNEL(SI1133_PARAM_ADCMUX_MED_IR, IIO_INTENSITY)
  413. .modified = 1,
  414. .channel2 = IIO_MOD_LIGHT_IR,
  415. },
  416. {
  417. SI1133_CHANNEL(SI1133_PARAM_ADCMUX_LARGE_IR, IIO_INTENSITY)
  418. .extend_name = "large",
  419. .modified = 1,
  420. .channel2 = IIO_MOD_LIGHT_IR,
  421. },
  422. {
  423. SI1133_CHANNEL(SI1133_PARAM_ADCMUX_UV, IIO_UVINDEX)
  424. },
  425. {
  426. SI1133_CHANNEL(SI1133_PARAM_ADCMUX_UV_DEEP, IIO_UVINDEX)
  427. .modified = 1,
  428. .channel2 = IIO_MOD_LIGHT_DUV,
  429. }
  430. };
  431. static int si1133_get_int_time_index(int milliseconds, int nanoseconds)
  432. {
  433. int i;
  434. for (i = 0; i < ARRAY_SIZE(si1133_int_time_table); i++) {
  435. if (milliseconds == si1133_int_time_table[i][0] &&
  436. nanoseconds == si1133_int_time_table[i][1])
  437. return i;
  438. }
  439. return -EINVAL;
  440. }
  441. static int si1133_set_integration_time(struct si1133_data *data, u8 adc,
  442. int milliseconds, int nanoseconds)
  443. {
  444. int index;
  445. index = si1133_get_int_time_index(milliseconds, nanoseconds);
  446. if (index < 0)
  447. return index;
  448. data->adc_sens[adc] &= 0xF0;
  449. data->adc_sens[adc] |= index;
  450. return si1133_param_set(data, SI1133_PARAM_REG_ADCSENS(0),
  451. data->adc_sens[adc]);
  452. }
  453. static int si1133_set_chlist(struct si1133_data *data, u8 scan_mask)
  454. {
  455. /* channel list already set, no need to reprogram */
  456. if (data->scan_mask == scan_mask)
  457. return 0;
  458. data->scan_mask = scan_mask;
  459. return si1133_param_set(data, SI1133_PARAM_REG_CHAN_LIST, scan_mask);
  460. }
  461. static int si1133_chan_set_adcconfig(struct si1133_data *data, u8 adc,
  462. u8 adc_config)
  463. {
  464. int err;
  465. err = si1133_param_set(data, SI1133_PARAM_REG_ADCCONFIG(adc),
  466. adc_config);
  467. if (err)
  468. return err;
  469. data->adc_config[adc] = adc_config;
  470. return 0;
  471. }
  472. static int si1133_update_adcconfig(struct si1133_data *data, uint8_t adc,
  473. u8 mask, u8 shift, u8 value)
  474. {
  475. u32 adc_config;
  476. int err;
  477. err = si1133_param_query(data, SI1133_PARAM_REG_ADCCONFIG(adc),
  478. &adc_config);
  479. if (err)
  480. return err;
  481. adc_config &= ~mask;
  482. adc_config |= (value << shift);
  483. return si1133_chan_set_adcconfig(data, adc, adc_config);
  484. }
  485. static int si1133_set_adcmux(struct si1133_data *data, u8 adc, u8 mux)
  486. {
  487. if ((mux & data->adc_config[adc]) == mux)
  488. return 0; /* mux already set to correct value */
  489. return si1133_update_adcconfig(data, adc, SI1133_ADCMUX_MASK, 0, mux);
  490. }
  491. static int si1133_force_measurement(struct si1133_data *data)
  492. {
  493. return si1133_command(data, SI1133_CMD_FORCE);
  494. }
  495. static int si1133_bulk_read(struct si1133_data *data, u8 start_reg, u8 length,
  496. u8 *buffer)
  497. {
  498. int err;
  499. err = si1133_force_measurement(data);
  500. if (err)
  501. return err;
  502. return regmap_bulk_read(data->regmap, start_reg, buffer, length);
  503. }
  504. static int si1133_measure(struct si1133_data *data,
  505. struct iio_chan_spec const *chan,
  506. int *val)
  507. {
  508. int err;
  509. __be16 resp;
  510. err = si1133_set_adcmux(data, 0, chan->channel);
  511. if (err)
  512. return err;
  513. /* Deactivate lux measurements if they were active */
  514. err = si1133_set_chlist(data, BIT(0));
  515. if (err)
  516. return err;
  517. err = si1133_bulk_read(data, SI1133_REG_HOSTOUT(0), sizeof(resp),
  518. (u8 *)&resp);
  519. if (err)
  520. return err;
  521. *val = be16_to_cpu(resp);
  522. return err;
  523. }
  524. static irqreturn_t si1133_threaded_irq_handler(int irq, void *private)
  525. {
  526. struct iio_dev *iio_dev = private;
  527. struct si1133_data *data = iio_priv(iio_dev);
  528. u32 irq_status;
  529. int err;
  530. err = regmap_read(data->regmap, SI1133_REG_IRQ_STATUS, &irq_status);
  531. if (err) {
  532. dev_err_ratelimited(&iio_dev->dev, "Error reading IRQ\n");
  533. goto out;
  534. }
  535. if (irq_status != data->scan_mask)
  536. return IRQ_NONE;
  537. out:
  538. complete(&data->completion);
  539. return IRQ_HANDLED;
  540. }
  541. static int si1133_scale_to_swgain(int scale_integer, int scale_fractional)
  542. {
  543. scale_integer = find_closest(scale_integer, si1133_scale_available,
  544. ARRAY_SIZE(si1133_scale_available));
  545. if (scale_integer < 0 ||
  546. scale_integer > ARRAY_SIZE(si1133_scale_available) ||
  547. scale_fractional != 0)
  548. return -EINVAL;
  549. return scale_integer;
  550. }
  551. static int si1133_chan_set_adcsens(struct si1133_data *data, u8 adc,
  552. u8 adc_sens)
  553. {
  554. int err;
  555. err = si1133_param_set(data, SI1133_PARAM_REG_ADCSENS(adc), adc_sens);
  556. if (err)
  557. return err;
  558. data->adc_sens[adc] = adc_sens;
  559. return 0;
  560. }
  561. static int si1133_update_adcsens(struct si1133_data *data, u8 mask,
  562. u8 shift, u8 value)
  563. {
  564. int err;
  565. u32 adc_sens;
  566. err = si1133_param_query(data, SI1133_PARAM_REG_ADCSENS(0),
  567. &adc_sens);
  568. if (err)
  569. return err;
  570. adc_sens &= ~mask;
  571. adc_sens |= (value << shift);
  572. return si1133_chan_set_adcsens(data, 0, adc_sens);
  573. }
  574. static int si1133_get_lux(struct si1133_data *data, int *val)
  575. {
  576. int err;
  577. int lux;
  578. u32 high_vis;
  579. u32 low_vis;
  580. u32 ir;
  581. u8 buffer[SI1133_LUX_BUFFER_SIZE];
  582. /* Activate lux channels */
  583. err = si1133_set_chlist(data, SI1133_LUX_ADC_MASK);
  584. if (err)
  585. return err;
  586. err = si1133_bulk_read(data, SI1133_REG_HOSTOUT(0),
  587. SI1133_LUX_BUFFER_SIZE, buffer);
  588. if (err)
  589. return err;
  590. high_vis = (buffer[0] << 16) | (buffer[1] << 8) | buffer[2];
  591. low_vis = (buffer[3] << 16) | (buffer[4] << 8) | buffer[5];
  592. ir = (buffer[6] << 16) | (buffer[7] << 8) | buffer[8];
  593. if (high_vis > SI1133_ADC_THRESHOLD || ir > SI1133_ADC_THRESHOLD)
  594. lux = si1133_calc_polynomial(high_vis, ir,
  595. SI1133_INPUT_FRACTION_HIGH,
  596. ARRAY_SIZE(lux_coeff.coeff_high),
  597. &lux_coeff.coeff_high[0]);
  598. else
  599. lux = si1133_calc_polynomial(low_vis, ir,
  600. SI1133_INPUT_FRACTION_LOW,
  601. ARRAY_SIZE(lux_coeff.coeff_low),
  602. &lux_coeff.coeff_low[0]);
  603. *val = lux >> SI1133_LUX_OUTPUT_FRACTION;
  604. return err;
  605. }
  606. static int si1133_read_raw(struct iio_dev *iio_dev,
  607. struct iio_chan_spec const *chan,
  608. int *val, int *val2, long mask)
  609. {
  610. struct si1133_data *data = iio_priv(iio_dev);
  611. u8 adc_sens = data->adc_sens[0];
  612. int err;
  613. switch (mask) {
  614. case IIO_CHAN_INFO_PROCESSED:
  615. switch (chan->type) {
  616. case IIO_LIGHT:
  617. err = si1133_get_lux(data, val);
  618. if (err)
  619. return err;
  620. return IIO_VAL_INT;
  621. default:
  622. return -EINVAL;
  623. }
  624. case IIO_CHAN_INFO_RAW:
  625. switch (chan->type) {
  626. case IIO_INTENSITY:
  627. case IIO_UVINDEX:
  628. err = si1133_measure(data, chan, val);
  629. if (err)
  630. return err;
  631. return IIO_VAL_INT;
  632. default:
  633. return -EINVAL;
  634. }
  635. case IIO_CHAN_INFO_INT_TIME:
  636. switch (chan->type) {
  637. case IIO_INTENSITY:
  638. case IIO_UVINDEX:
  639. adc_sens &= SI1133_ADCSENS_HW_GAIN_MASK;
  640. *val = si1133_int_time_table[adc_sens][0];
  641. *val2 = si1133_int_time_table[adc_sens][1];
  642. return IIO_VAL_INT_PLUS_MICRO;
  643. default:
  644. return -EINVAL;
  645. }
  646. case IIO_CHAN_INFO_SCALE:
  647. switch (chan->type) {
  648. case IIO_INTENSITY:
  649. case IIO_UVINDEX:
  650. adc_sens &= SI1133_ADCSENS_SCALE_MASK;
  651. adc_sens >>= SI1133_ADCSENS_SCALE_SHIFT;
  652. *val = BIT(adc_sens);
  653. return IIO_VAL_INT;
  654. default:
  655. return -EINVAL;
  656. }
  657. case IIO_CHAN_INFO_HARDWAREGAIN:
  658. switch (chan->type) {
  659. case IIO_INTENSITY:
  660. case IIO_UVINDEX:
  661. adc_sens >>= SI1133_ADCSENS_HSIG_SHIFT;
  662. *val = adc_sens;
  663. return IIO_VAL_INT;
  664. default:
  665. return -EINVAL;
  666. }
  667. default:
  668. return -EINVAL;
  669. }
  670. }
  671. static int si1133_write_raw(struct iio_dev *iio_dev,
  672. struct iio_chan_spec const *chan,
  673. int val, int val2, long mask)
  674. {
  675. struct si1133_data *data = iio_priv(iio_dev);
  676. switch (mask) {
  677. case IIO_CHAN_INFO_SCALE:
  678. switch (chan->type) {
  679. case IIO_INTENSITY:
  680. case IIO_UVINDEX:
  681. val = si1133_scale_to_swgain(val, val2);
  682. if (val < 0)
  683. return val;
  684. return si1133_update_adcsens(data,
  685. SI1133_ADCSENS_SCALE_MASK,
  686. SI1133_ADCSENS_SCALE_SHIFT,
  687. val);
  688. default:
  689. return -EINVAL;
  690. }
  691. case IIO_CHAN_INFO_INT_TIME:
  692. return si1133_set_integration_time(data, 0, val, val2);
  693. case IIO_CHAN_INFO_HARDWAREGAIN:
  694. switch (chan->type) {
  695. case IIO_INTENSITY:
  696. case IIO_UVINDEX:
  697. if (val != 0 && val != 1)
  698. return -EINVAL;
  699. return si1133_update_adcsens(data,
  700. SI1133_ADCSENS_HSIG_MASK,
  701. SI1133_ADCSENS_HSIG_SHIFT,
  702. val);
  703. default:
  704. return -EINVAL;
  705. }
  706. default:
  707. return -EINVAL;
  708. }
  709. }
  710. static struct attribute *si1133_attributes[] = {
  711. &iio_const_attr_integration_time_available.dev_attr.attr,
  712. &iio_const_attr_scale_available.dev_attr.attr,
  713. NULL,
  714. };
  715. static const struct attribute_group si1133_attribute_group = {
  716. .attrs = si1133_attributes,
  717. };
  718. static const struct iio_info si1133_info = {
  719. .read_raw = si1133_read_raw,
  720. .write_raw = si1133_write_raw,
  721. .attrs = &si1133_attribute_group,
  722. };
  723. /*
  724. * si1133_init_lux_channels - Configure 3 different channels(adc) (1,2 and 3)
  725. * The channel configuration for the lux measurement was taken from :
  726. * https://siliconlabs.github.io/Gecko_SDK_Doc/efm32zg/html/si1133_8c_source.html#l00578
  727. *
  728. * Reserved the channel 0 for the other raw measurements
  729. */
  730. static int si1133_init_lux_channels(struct si1133_data *data)
  731. {
  732. int err;
  733. err = si1133_chan_set_adcconfig(data, 1,
  734. SI1133_ADCCONFIG_DECIM_RATE(1) |
  735. SI1133_PARAM_ADCMUX_LARGE_WHITE);
  736. if (err)
  737. return err;
  738. err = si1133_param_set(data, SI1133_PARAM_REG_ADCPOST(1),
  739. SI1133_ADCPOST_24BIT_EN |
  740. SI1133_ADCPOST_POSTSHIFT_BITQTY(0));
  741. if (err)
  742. return err;
  743. err = si1133_chan_set_adcsens(data, 1, SI1133_ADCSENS_HSIG_MASK |
  744. SI1133_ADCSENS_NB_MEAS(64) | _48_8_us);
  745. if (err)
  746. return err;
  747. err = si1133_chan_set_adcconfig(data, 2,
  748. SI1133_ADCCONFIG_DECIM_RATE(1) |
  749. SI1133_PARAM_ADCMUX_LARGE_WHITE);
  750. if (err)
  751. return err;
  752. err = si1133_param_set(data, SI1133_PARAM_REG_ADCPOST(2),
  753. SI1133_ADCPOST_24BIT_EN |
  754. SI1133_ADCPOST_POSTSHIFT_BITQTY(2));
  755. if (err)
  756. return err;
  757. err = si1133_chan_set_adcsens(data, 2, SI1133_ADCSENS_HSIG_MASK |
  758. SI1133_ADCSENS_NB_MEAS(1) | _3_120_0_us);
  759. if (err)
  760. return err;
  761. err = si1133_chan_set_adcconfig(data, 3,
  762. SI1133_ADCCONFIG_DECIM_RATE(1) |
  763. SI1133_PARAM_ADCMUX_MED_IR);
  764. if (err)
  765. return err;
  766. err = si1133_param_set(data, SI1133_PARAM_REG_ADCPOST(3),
  767. SI1133_ADCPOST_24BIT_EN |
  768. SI1133_ADCPOST_POSTSHIFT_BITQTY(2));
  769. if (err)
  770. return err;
  771. return si1133_chan_set_adcsens(data, 3, SI1133_ADCSENS_HSIG_MASK |
  772. SI1133_ADCSENS_NB_MEAS(64) | _48_8_us);
  773. }
  774. static int si1133_initialize(struct si1133_data *data)
  775. {
  776. int err;
  777. err = si1133_cmd_reset_sw(data);
  778. if (err)
  779. return err;
  780. /* Turn off autonomous mode */
  781. err = si1133_param_set(data, SI1133_REG_MEAS_RATE, 0);
  782. if (err)
  783. return err;
  784. err = si1133_init_lux_channels(data);
  785. if (err)
  786. return err;
  787. return regmap_write(data->regmap, SI1133_REG_IRQ_ENABLE,
  788. SI1133_IRQ_CHANNEL_ENABLE);
  789. }
  790. static int si1133_validate_ids(struct iio_dev *iio_dev)
  791. {
  792. struct si1133_data *data = iio_priv(iio_dev);
  793. unsigned int part_id, rev_id, mfr_id;
  794. int err;
  795. err = regmap_read(data->regmap, SI1133_REG_PART_ID, &part_id);
  796. if (err)
  797. return err;
  798. err = regmap_read(data->regmap, SI1133_REG_REV_ID, &rev_id);
  799. if (err)
  800. return err;
  801. err = regmap_read(data->regmap, SI1133_REG_MFR_ID, &mfr_id);
  802. if (err)
  803. return err;
  804. dev_info(&iio_dev->dev,
  805. "Device ID part %#02hhx rev %#02hhx mfr %#02hhx\n",
  806. part_id, rev_id, mfr_id);
  807. if (part_id != SI1133_PART_ID) {
  808. dev_err(&iio_dev->dev,
  809. "Part ID mismatch got %#02hhx, expected %#02x\n",
  810. part_id, SI1133_PART_ID);
  811. return -ENODEV;
  812. }
  813. return 0;
  814. }
  815. static int si1133_probe(struct i2c_client *client,
  816. const struct i2c_device_id *id)
  817. {
  818. struct si1133_data *data;
  819. struct iio_dev *iio_dev;
  820. int err;
  821. iio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
  822. if (!iio_dev)
  823. return -ENOMEM;
  824. data = iio_priv(iio_dev);
  825. init_completion(&data->completion);
  826. data->regmap = devm_regmap_init_i2c(client, &si1133_regmap_config);
  827. if (IS_ERR(data->regmap)) {
  828. err = PTR_ERR(data->regmap);
  829. dev_err(&client->dev, "Failed to initialise regmap: %d\n", err);
  830. return err;
  831. }
  832. i2c_set_clientdata(client, iio_dev);
  833. data->client = client;
  834. iio_dev->dev.parent = &client->dev;
  835. iio_dev->name = id->name;
  836. iio_dev->channels = si1133_channels;
  837. iio_dev->num_channels = ARRAY_SIZE(si1133_channels);
  838. iio_dev->info = &si1133_info;
  839. iio_dev->modes = INDIO_DIRECT_MODE;
  840. mutex_init(&data->mutex);
  841. err = si1133_validate_ids(iio_dev);
  842. if (err)
  843. return err;
  844. err = si1133_initialize(data);
  845. if (err) {
  846. dev_err(&client->dev,
  847. "Error when initializing chip: %d\n", err);
  848. return err;
  849. }
  850. if (!client->irq) {
  851. dev_err(&client->dev,
  852. "Required interrupt not provided, cannot proceed\n");
  853. return -EINVAL;
  854. }
  855. err = devm_request_threaded_irq(&client->dev, client->irq,
  856. NULL,
  857. si1133_threaded_irq_handler,
  858. IRQF_ONESHOT | IRQF_SHARED,
  859. client->name, iio_dev);
  860. if (err) {
  861. dev_warn(&client->dev, "Request irq %d failed: %i\n",
  862. client->irq, err);
  863. return err;
  864. }
  865. return devm_iio_device_register(&client->dev, iio_dev);
  866. }
  867. static const struct i2c_device_id si1133_ids[] = {
  868. { "si1133", 0 },
  869. { }
  870. };
  871. MODULE_DEVICE_TABLE(i2c, si1133_ids);
  872. static struct i2c_driver si1133_driver = {
  873. .driver = {
  874. .name = "si1133",
  875. },
  876. .probe = si1133_probe,
  877. .id_table = si1133_ids,
  878. };
  879. module_i2c_driver(si1133_driver);
  880. MODULE_AUTHOR("Maxime Roussin-Belanger <maxime.roussinbelanger@gmail.com>");
  881. MODULE_DESCRIPTION("Silabs SI1133, UV index sensor and ambient light sensor driver");
  882. MODULE_LICENSE("GPL");