ms_sensors_i2c.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653
  1. /*
  2. * Measurements Specialties driver common i2c functions
  3. *
  4. * Copyright (c) 2015 Measurement-Specialties
  5. *
  6. * Licensed under the GPL-2.
  7. */
  8. #include <linux/module.h>
  9. #include <linux/iio/iio.h>
  10. #include <linux/device.h>
  11. #include <linux/delay.h>
  12. #include "ms_sensors_i2c.h"
  13. /* Conversion times in us */
  14. static const u16 ms_sensors_ht_t_conversion_time[] = { 50000, 25000,
  15. 13000, 7000 };
  16. static const u16 ms_sensors_ht_h_conversion_time[] = { 16000, 3000,
  17. 5000, 8000 };
  18. static const u16 ms_sensors_tp_conversion_time[] = { 500, 1100, 2100,
  19. 4100, 8220, 16440 };
  20. #define MS_SENSORS_SERIAL_READ_MSB 0xFA0F
  21. #define MS_SENSORS_SERIAL_READ_LSB 0xFCC9
  22. #define MS_SENSORS_CONFIG_REG_WRITE 0xE6
  23. #define MS_SENSORS_CONFIG_REG_READ 0xE7
  24. #define MS_SENSORS_HT_T_CONVERSION_START 0xF3
  25. #define MS_SENSORS_HT_H_CONVERSION_START 0xF5
  26. #define MS_SENSORS_TP_PROM_READ 0xA0
  27. #define MS_SENSORS_TP_T_CONVERSION_START 0x50
  28. #define MS_SENSORS_TP_P_CONVERSION_START 0x40
  29. #define MS_SENSORS_TP_ADC_READ 0x00
  30. #define MS_SENSORS_NO_READ_CMD 0xFF
  31. /**
  32. * ms_sensors_reset() - Reset function
  33. * @cli: pointer to device client
  34. * @cmd: reset cmd. Depends on device in use
  35. * @delay: usleep minimal delay after reset command is issued
  36. *
  37. * Generic I2C reset function for Measurement Specialties devices.
  38. *
  39. * Return: 0 on success, negative errno otherwise.
  40. */
  41. int ms_sensors_reset(void *cli, u8 cmd, unsigned int delay)
  42. {
  43. int ret;
  44. struct i2c_client *client = cli;
  45. ret = i2c_smbus_write_byte(client, cmd);
  46. if (ret) {
  47. dev_err(&client->dev, "Failed to reset device\n");
  48. return ret;
  49. }
  50. usleep_range(delay, delay + 1000);
  51. return 0;
  52. }
  53. EXPORT_SYMBOL(ms_sensors_reset);
  54. /**
  55. * ms_sensors_read_prom_word() - PROM word read function
  56. * @cli: pointer to device client
  57. * @cmd: PROM read cmd. Depends on device and prom id
  58. * @word: pointer to word destination value
  59. *
  60. * Generic i2c prom word read function for Measurement Specialties devices.
  61. *
  62. * Return: 0 on success, negative errno otherwise.
  63. */
  64. int ms_sensors_read_prom_word(void *cli, int cmd, u16 *word)
  65. {
  66. int ret;
  67. struct i2c_client *client = (struct i2c_client *)cli;
  68. ret = i2c_smbus_read_word_swapped(client, cmd);
  69. if (ret < 0) {
  70. dev_err(&client->dev, "Failed to read prom word\n");
  71. return ret;
  72. }
  73. *word = ret;
  74. return 0;
  75. }
  76. EXPORT_SYMBOL(ms_sensors_read_prom_word);
  77. /**
  78. * ms_sensors_convert_and_read() - ADC conversion & read function
  79. * @cli: pointer to device client
  80. * @conv: ADC conversion command. Depends on device in use
  81. * @rd: ADC read command. Depends on device in use
  82. * @delay: usleep minimal delay after conversion command is issued
  83. * @adc: pointer to ADC destination value
  84. *
  85. * Generic ADC conversion & read function for Measurement Specialties
  86. * devices.
  87. * The function will issue conversion command, sleep appopriate delay, and
  88. * issue command to read ADC.
  89. *
  90. * Return: 0 on success, negative errno otherwise.
  91. */
  92. int ms_sensors_convert_and_read(void *cli, u8 conv, u8 rd,
  93. unsigned int delay, u32 *adc)
  94. {
  95. int ret;
  96. __be32 buf = 0;
  97. struct i2c_client *client = (struct i2c_client *)cli;
  98. /* Trigger conversion */
  99. ret = i2c_smbus_write_byte(client, conv);
  100. if (ret)
  101. goto err;
  102. usleep_range(delay, delay + 1000);
  103. /* Retrieve ADC value */
  104. if (rd != MS_SENSORS_NO_READ_CMD)
  105. ret = i2c_smbus_read_i2c_block_data(client, rd, 3, (u8 *)&buf);
  106. else
  107. ret = i2c_master_recv(client, (u8 *)&buf, 3);
  108. if (ret < 0)
  109. goto err;
  110. dev_dbg(&client->dev, "ADC raw value : %x\n", be32_to_cpu(buf) >> 8);
  111. *adc = be32_to_cpu(buf) >> 8;
  112. return 0;
  113. err:
  114. dev_err(&client->dev, "Unable to make sensor adc conversion\n");
  115. return ret;
  116. }
  117. EXPORT_SYMBOL(ms_sensors_convert_and_read);
  118. /**
  119. * ms_sensors_crc_valid() - CRC check function
  120. * @value: input and CRC compare value
  121. *
  122. * Cyclic Redundancy Check function used in TSYS02D, HTU21, MS8607.
  123. * This function performs a x^8 + x^5 + x^4 + 1 polynomial CRC.
  124. * The argument contains CRC value in LSB byte while the bytes 1 and 2
  125. * are used for CRC computation.
  126. *
  127. * Return: 1 if CRC is valid, 0 otherwise.
  128. */
  129. static bool ms_sensors_crc_valid(u32 value)
  130. {
  131. u32 polynom = 0x988000; /* x^8 + x^5 + x^4 + 1 */
  132. u32 msb = 0x800000;
  133. u32 mask = 0xFF8000;
  134. u32 result = value & 0xFFFF00;
  135. u8 crc = value & 0xFF;
  136. while (msb != 0x80) {
  137. if (result & msb)
  138. result = ((result ^ polynom) & mask)
  139. | (result & ~mask);
  140. msb >>= 1;
  141. mask >>= 1;
  142. polynom >>= 1;
  143. }
  144. return result == crc;
  145. }
  146. /**
  147. * ms_sensors_read_serial() - Serial number read function
  148. * @cli: pointer to i2c client
  149. * @sn: pointer to 64-bits destination value
  150. *
  151. * Generic i2c serial number read function for Measurement Specialties devices.
  152. * This function is used for TSYS02d, HTU21, MS8607 chipset.
  153. * Refer to datasheet:
  154. * http://www.meas-spec.com/downloads/HTU2X_Serial_Number_Reading.pdf
  155. *
  156. * Sensor raw MSB serial number format is the following :
  157. * [ SNB3, CRC, SNB2, CRC, SNB1, CRC, SNB0, CRC]
  158. * Sensor raw LSB serial number format is the following :
  159. * [ X, X, SNC1, SNC0, CRC, SNA1, SNA0, CRC]
  160. * The resulting serial number is following :
  161. * [ SNA1, SNA0, SNB3, SNB2, SNB1, SNB0, SNC1, SNC0]
  162. *
  163. * Return: 0 on success, negative errno otherwise.
  164. */
  165. int ms_sensors_read_serial(struct i2c_client *client, u64 *sn)
  166. {
  167. u8 i;
  168. __be64 rcv_buf = 0;
  169. u64 rcv_val;
  170. __be16 send_buf;
  171. int ret;
  172. struct i2c_msg msg[2] = {
  173. {
  174. .addr = client->addr,
  175. .flags = client->flags,
  176. .len = 2,
  177. .buf = (__u8 *)&send_buf,
  178. },
  179. {
  180. .addr = client->addr,
  181. .flags = client->flags | I2C_M_RD,
  182. .buf = (__u8 *)&rcv_buf,
  183. },
  184. };
  185. /* Read MSB part of serial number */
  186. send_buf = cpu_to_be16(MS_SENSORS_SERIAL_READ_MSB);
  187. msg[1].len = 8;
  188. ret = i2c_transfer(client->adapter, msg, 2);
  189. if (ret < 0) {
  190. dev_err(&client->dev, "Unable to read device serial number");
  191. return ret;
  192. }
  193. rcv_val = be64_to_cpu(rcv_buf);
  194. dev_dbg(&client->dev, "Serial MSB raw : %llx\n", rcv_val);
  195. for (i = 0; i < 64; i += 16) {
  196. if (!ms_sensors_crc_valid((rcv_val >> i) & 0xFFFF))
  197. return -ENODEV;
  198. }
  199. *sn = (((rcv_val >> 32) & 0xFF000000) |
  200. ((rcv_val >> 24) & 0x00FF0000) |
  201. ((rcv_val >> 16) & 0x0000FF00) |
  202. ((rcv_val >> 8) & 0x000000FF)) << 16;
  203. /* Read LSB part of serial number */
  204. send_buf = cpu_to_be16(MS_SENSORS_SERIAL_READ_LSB);
  205. msg[1].len = 6;
  206. rcv_buf = 0;
  207. ret = i2c_transfer(client->adapter, msg, 2);
  208. if (ret < 0) {
  209. dev_err(&client->dev, "Unable to read device serial number");
  210. return ret;
  211. }
  212. rcv_val = be64_to_cpu(rcv_buf) >> 16;
  213. dev_dbg(&client->dev, "Serial MSB raw : %llx\n", rcv_val);
  214. for (i = 0; i < 48; i += 24) {
  215. if (!ms_sensors_crc_valid((rcv_val >> i) & 0xFFFFFF))
  216. return -ENODEV;
  217. }
  218. *sn |= (rcv_val & 0xFFFF00) << 40 | (rcv_val >> 32);
  219. return 0;
  220. }
  221. EXPORT_SYMBOL(ms_sensors_read_serial);
  222. static int ms_sensors_read_config_reg(struct i2c_client *client,
  223. u8 *config_reg)
  224. {
  225. int ret;
  226. ret = i2c_smbus_write_byte(client, MS_SENSORS_CONFIG_REG_READ);
  227. if (ret) {
  228. dev_err(&client->dev, "Unable to read config register");
  229. return ret;
  230. }
  231. ret = i2c_master_recv(client, config_reg, 1);
  232. if (ret < 0) {
  233. dev_err(&client->dev, "Unable to read config register");
  234. return ret;
  235. }
  236. dev_dbg(&client->dev, "Config register :%x\n", *config_reg);
  237. return 0;
  238. }
  239. /**
  240. * ms_sensors_write_resolution() - Set resolution function
  241. * @dev_data: pointer to temperature/humidity device data
  242. * @i: resolution index to set
  243. *
  244. * This function will program the appropriate resolution based on the index
  245. * provided when user space will set samp_freq channel.
  246. * This function is used for TSYS02D, HTU21 and MS8607 chipsets.
  247. *
  248. * Return: 0 on success, negative errno otherwise.
  249. */
  250. ssize_t ms_sensors_write_resolution(struct ms_ht_dev *dev_data,
  251. u8 i)
  252. {
  253. u8 config_reg;
  254. int ret;
  255. ret = ms_sensors_read_config_reg(dev_data->client, &config_reg);
  256. if (ret)
  257. return ret;
  258. config_reg &= 0x7E;
  259. config_reg |= ((i & 1) << 7) + ((i & 2) >> 1);
  260. return i2c_smbus_write_byte_data(dev_data->client,
  261. MS_SENSORS_CONFIG_REG_WRITE,
  262. config_reg);
  263. }
  264. EXPORT_SYMBOL(ms_sensors_write_resolution);
  265. /**
  266. * ms_sensors_show_battery_low() - Show device battery low indicator
  267. * @dev_data: pointer to temperature/humidity device data
  268. * @buf: pointer to char buffer to write result
  269. *
  270. * This function will read battery indicator value in the device and
  271. * return 1 if the device voltage is below 2.25V.
  272. * This function is used for TSYS02D, HTU21 and MS8607 chipsets.
  273. *
  274. * Return: length of sprintf on success, negative errno otherwise.
  275. */
  276. ssize_t ms_sensors_show_battery_low(struct ms_ht_dev *dev_data,
  277. char *buf)
  278. {
  279. int ret;
  280. u8 config_reg;
  281. mutex_lock(&dev_data->lock);
  282. ret = ms_sensors_read_config_reg(dev_data->client, &config_reg);
  283. mutex_unlock(&dev_data->lock);
  284. if (ret)
  285. return ret;
  286. return sprintf(buf, "%d\n", (config_reg & 0x40) >> 6);
  287. }
  288. EXPORT_SYMBOL(ms_sensors_show_battery_low);
  289. /**
  290. * ms_sensors_show_heater() - Show device heater
  291. * @dev_data: pointer to temperature/humidity device data
  292. * @buf: pointer to char buffer to write result
  293. *
  294. * This function will read heater enable value in the device and
  295. * return 1 if the heater is enabled.
  296. * This function is used for HTU21 and MS8607 chipsets.
  297. *
  298. * Return: length of sprintf on success, negative errno otherwise.
  299. */
  300. ssize_t ms_sensors_show_heater(struct ms_ht_dev *dev_data,
  301. char *buf)
  302. {
  303. u8 config_reg;
  304. int ret;
  305. mutex_lock(&dev_data->lock);
  306. ret = ms_sensors_read_config_reg(dev_data->client, &config_reg);
  307. mutex_unlock(&dev_data->lock);
  308. if (ret)
  309. return ret;
  310. return sprintf(buf, "%d\n", (config_reg & 0x4) >> 2);
  311. }
  312. EXPORT_SYMBOL(ms_sensors_show_heater);
  313. /**
  314. * ms_sensors_write_heater() - Write device heater
  315. * @dev_data: pointer to temperature/humidity device data
  316. * @buf: pointer to char buffer from user space
  317. * @len: length of buf
  318. *
  319. * This function will write 1 or 0 value in the device
  320. * to enable or disable heater.
  321. * This function is used for HTU21 and MS8607 chipsets.
  322. *
  323. * Return: length of buffer, negative errno otherwise.
  324. */
  325. ssize_t ms_sensors_write_heater(struct ms_ht_dev *dev_data,
  326. const char *buf, size_t len)
  327. {
  328. u8 val, config_reg;
  329. int ret;
  330. ret = kstrtou8(buf, 10, &val);
  331. if (ret)
  332. return ret;
  333. if (val > 1)
  334. return -EINVAL;
  335. mutex_lock(&dev_data->lock);
  336. ret = ms_sensors_read_config_reg(dev_data->client, &config_reg);
  337. if (ret) {
  338. mutex_unlock(&dev_data->lock);
  339. return ret;
  340. }
  341. config_reg &= 0xFB;
  342. config_reg |= val << 2;
  343. ret = i2c_smbus_write_byte_data(dev_data->client,
  344. MS_SENSORS_CONFIG_REG_WRITE,
  345. config_reg);
  346. mutex_unlock(&dev_data->lock);
  347. if (ret) {
  348. dev_err(&dev_data->client->dev, "Unable to write config register\n");
  349. return ret;
  350. }
  351. return len;
  352. }
  353. EXPORT_SYMBOL(ms_sensors_write_heater);
  354. /**
  355. * ms_sensors_ht_read_temperature() - Read temperature
  356. * @dev_data: pointer to temperature/humidity device data
  357. * @temperature:pointer to temperature destination value
  358. *
  359. * This function will get temperature ADC value from the device,
  360. * check the CRC and compute the temperature value.
  361. * This function is used for TSYS02D, HTU21 and MS8607 chipsets.
  362. *
  363. * Return: 0 on success, negative errno otherwise.
  364. */
  365. int ms_sensors_ht_read_temperature(struct ms_ht_dev *dev_data,
  366. s32 *temperature)
  367. {
  368. int ret;
  369. u32 adc;
  370. u16 delay;
  371. mutex_lock(&dev_data->lock);
  372. delay = ms_sensors_ht_t_conversion_time[dev_data->res_index];
  373. ret = ms_sensors_convert_and_read(dev_data->client,
  374. MS_SENSORS_HT_T_CONVERSION_START,
  375. MS_SENSORS_NO_READ_CMD,
  376. delay, &adc);
  377. mutex_unlock(&dev_data->lock);
  378. if (ret)
  379. return ret;
  380. if (!ms_sensors_crc_valid(adc)) {
  381. dev_err(&dev_data->client->dev,
  382. "Temperature read crc check error\n");
  383. return -ENODEV;
  384. }
  385. /* Temperature algorithm */
  386. *temperature = (((s64)(adc >> 8) * 175720) >> 16) - 46850;
  387. return 0;
  388. }
  389. EXPORT_SYMBOL(ms_sensors_ht_read_temperature);
  390. /**
  391. * ms_sensors_ht_read_humidity() - Read humidity
  392. * @dev_data: pointer to temperature/humidity device data
  393. * @humidity: pointer to humidity destination value
  394. *
  395. * This function will get humidity ADC value from the device,
  396. * check the CRC and compute the temperature value.
  397. * This function is used for HTU21 and MS8607 chipsets.
  398. *
  399. * Return: 0 on success, negative errno otherwise.
  400. */
  401. int ms_sensors_ht_read_humidity(struct ms_ht_dev *dev_data,
  402. u32 *humidity)
  403. {
  404. int ret;
  405. u32 adc;
  406. u16 delay;
  407. mutex_lock(&dev_data->lock);
  408. delay = ms_sensors_ht_h_conversion_time[dev_data->res_index];
  409. ret = ms_sensors_convert_and_read(dev_data->client,
  410. MS_SENSORS_HT_H_CONVERSION_START,
  411. MS_SENSORS_NO_READ_CMD,
  412. delay, &adc);
  413. mutex_unlock(&dev_data->lock);
  414. if (ret)
  415. return ret;
  416. if (!ms_sensors_crc_valid(adc)) {
  417. dev_err(&dev_data->client->dev,
  418. "Humidity read crc check error\n");
  419. return -ENODEV;
  420. }
  421. /* Humidity algorithm */
  422. *humidity = (((s32)(adc >> 8) * 12500) >> 16) * 10 - 6000;
  423. if (*humidity >= 100000)
  424. *humidity = 100000;
  425. return 0;
  426. }
  427. EXPORT_SYMBOL(ms_sensors_ht_read_humidity);
  428. /**
  429. * ms_sensors_tp_crc_valid() - CRC check function for
  430. * Temperature and pressure devices.
  431. * This function is only used when reading PROM coefficients
  432. *
  433. * @prom: pointer to PROM coefficients array
  434. * @len: length of PROM coefficients array
  435. *
  436. * Return: True if CRC is ok.
  437. */
  438. static bool ms_sensors_tp_crc_valid(u16 *prom, u8 len)
  439. {
  440. unsigned int cnt, n_bit;
  441. u16 n_rem = 0x0000, crc_read = prom[0], crc = (*prom & 0xF000) >> 12;
  442. prom[len - 1] = 0;
  443. prom[0] &= 0x0FFF; /* Clear the CRC computation part */
  444. for (cnt = 0; cnt < len * 2; cnt++) {
  445. if (cnt % 2 == 1)
  446. n_rem ^= prom[cnt >> 1] & 0x00FF;
  447. else
  448. n_rem ^= prom[cnt >> 1] >> 8;
  449. for (n_bit = 8; n_bit > 0; n_bit--) {
  450. if (n_rem & 0x8000)
  451. n_rem = (n_rem << 1) ^ 0x3000;
  452. else
  453. n_rem <<= 1;
  454. }
  455. }
  456. n_rem >>= 12;
  457. prom[0] = crc_read;
  458. return n_rem == crc;
  459. }
  460. /**
  461. * ms_sensors_tp_read_prom() - prom coeff read function
  462. * @dev_data: pointer to temperature/pressure device data
  463. *
  464. * This function will read prom coefficients and check CRC.
  465. * This function is used for MS5637 and MS8607 chipsets.
  466. *
  467. * Return: 0 on success, negative errno otherwise.
  468. */
  469. int ms_sensors_tp_read_prom(struct ms_tp_dev *dev_data)
  470. {
  471. int i, ret;
  472. for (i = 0; i < MS_SENSORS_TP_PROM_WORDS_NB; i++) {
  473. ret = ms_sensors_read_prom_word(
  474. dev_data->client,
  475. MS_SENSORS_TP_PROM_READ + (i << 1),
  476. &dev_data->prom[i]);
  477. if (ret)
  478. return ret;
  479. }
  480. if (!ms_sensors_tp_crc_valid(dev_data->prom,
  481. MS_SENSORS_TP_PROM_WORDS_NB + 1)) {
  482. dev_err(&dev_data->client->dev,
  483. "Calibration coefficients crc check error\n");
  484. return -ENODEV;
  485. }
  486. return 0;
  487. }
  488. EXPORT_SYMBOL(ms_sensors_tp_read_prom);
  489. /**
  490. * ms_sensors_read_temp_and_pressure() - read temp and pressure
  491. * @dev_data: pointer to temperature/pressure device data
  492. * @temperature:pointer to temperature destination value
  493. * @pressure: pointer to pressure destination value
  494. *
  495. * This function will read ADC and compute pressure and temperature value.
  496. * This function is used for MS5637 and MS8607 chipsets.
  497. *
  498. * Return: 0 on success, negative errno otherwise.
  499. */
  500. int ms_sensors_read_temp_and_pressure(struct ms_tp_dev *dev_data,
  501. int *temperature,
  502. unsigned int *pressure)
  503. {
  504. int ret;
  505. u32 t_adc, p_adc;
  506. s32 dt, temp;
  507. s64 off, sens, t2, off2, sens2;
  508. u16 *prom = dev_data->prom, delay;
  509. mutex_lock(&dev_data->lock);
  510. delay = ms_sensors_tp_conversion_time[dev_data->res_index];
  511. ret = ms_sensors_convert_and_read(
  512. dev_data->client,
  513. MS_SENSORS_TP_T_CONVERSION_START +
  514. dev_data->res_index * 2,
  515. MS_SENSORS_TP_ADC_READ,
  516. delay, &t_adc);
  517. if (ret) {
  518. mutex_unlock(&dev_data->lock);
  519. return ret;
  520. }
  521. ret = ms_sensors_convert_and_read(
  522. dev_data->client,
  523. MS_SENSORS_TP_P_CONVERSION_START +
  524. dev_data->res_index * 2,
  525. MS_SENSORS_TP_ADC_READ,
  526. delay, &p_adc);
  527. mutex_unlock(&dev_data->lock);
  528. if (ret)
  529. return ret;
  530. dt = (s32)t_adc - (prom[5] << 8);
  531. /* Actual temperature = 2000 + dT * TEMPSENS */
  532. temp = 2000 + (((s64)dt * prom[6]) >> 23);
  533. /* Second order temperature compensation */
  534. if (temp < 2000) {
  535. s64 tmp = (s64)temp - 2000;
  536. t2 = (3 * ((s64)dt * (s64)dt)) >> 33;
  537. off2 = (61 * tmp * tmp) >> 4;
  538. sens2 = (29 * tmp * tmp) >> 4;
  539. if (temp < -1500) {
  540. s64 tmp = (s64)temp + 1500;
  541. off2 += 17 * tmp * tmp;
  542. sens2 += 9 * tmp * tmp;
  543. }
  544. } else {
  545. t2 = (5 * ((s64)dt * (s64)dt)) >> 38;
  546. off2 = 0;
  547. sens2 = 0;
  548. }
  549. /* OFF = OFF_T1 + TCO * dT */
  550. off = (((s64)prom[2]) << 17) + ((((s64)prom[4]) * (s64)dt) >> 6);
  551. off -= off2;
  552. /* Sensitivity at actual temperature = SENS_T1 + TCS * dT */
  553. sens = (((s64)prom[1]) << 16) + (((s64)prom[3] * dt) >> 7);
  554. sens -= sens2;
  555. /* Temperature compensated pressure = D1 * SENS - OFF */
  556. *temperature = (temp - t2) * 10;
  557. *pressure = (u32)(((((s64)p_adc * sens) >> 21) - off) >> 15);
  558. return 0;
  559. }
  560. EXPORT_SYMBOL(ms_sensors_read_temp_and_pressure);
  561. MODULE_DESCRIPTION("Measurement-Specialties common i2c driver");
  562. MODULE_AUTHOR("William Markezana <william.markezana@meas-spec.com>");
  563. MODULE_AUTHOR("Ludovic Tancerel <ludovic.tancerel@maplehightech.com>");
  564. MODULE_LICENSE("GPL v2");