cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

ms_sensors_i2c.c (18391B)


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