si1133.c 25 KB

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