/**
 * mid_read_temp - read sensors for temperature
 * @temp: holds the current temperature for the sensor after reading
 *
 * reads the adc_code from the channel and converts it to real
 * temperature. The converted value is stored in temp.
 *
 * Can sleep
 */
static int mid_read_temp(struct thermal_zone_device *tzd, unsigned long *temp)
{
	struct thermal_device_info *td_info = tzd->devdata;
	int ret;
	long curr_temp, bp_temp = 0;
	int indx = td_info->sensor_index; /* Required Index */

	mutex_lock(&ipcinfo->cacheinfo.lock);

	if (!ipcinfo->cacheinfo.is_cached_data_initialized ||
	time_after(jiffies, ipcinfo->cacheinfo.last_updated + HZ)) {
		ret = intel_mid_gpadc_sample(
			ipcinfo->therm_adc_handle, 1,
			&ipcinfo->cacheinfo.cached_values[0],
			&ipcinfo->cacheinfo.cached_values[1],
			&ipcinfo->cacheinfo.cached_values[2],
			&ipcinfo->cacheinfo.cached_values[3]);
		if (ret)
			goto exit;
		ipcinfo->cacheinfo.last_updated = jiffies;
		ipcinfo->cacheinfo.is_cached_data_initialized = true;
	}

	/* Convert ADC value to temperature */
	ret = adc_to_temp(td_info->direct,
		ipcinfo->cacheinfo.cached_values[indx],
		&curr_temp);
	if (ret)
		goto exit;

	switch (indx) {
	case SKIN0_INDEX:
		*temp = SKIN0_TEMP(curr_temp);
		break;
	case SKIN1_INDEX:
#ifdef CONFIG_BOARD_CTP
		ret = adc_to_temp(td_info->direct,
			ipcinfo->cacheinfo.cached_values[BPTHERM_INDEX],
			&bp_temp);
		if (ret)
			goto exit;
		bp_temp = (bp_temp * BPTHERM_SLOPE)/1000 + BPTHERM_INTERCEPT;
#endif
		*temp = SKIN1_TEMP(curr_temp);

		/* Max(Back Skin Thermistor temp, BPTHERM value) */
		if (bp_temp > *temp)
			*temp = bp_temp;
		break;
	default:
		*temp = curr_temp;
	}

exit:
	mutex_unlock(&ipcinfo->cacheinfo.lock);
	return ret;
}
Exemple #2
0
/* Convert ADC result to temperature in celsius */
test_export_static int bd99992gw_get_temp(uint16_t adc)
{
	int temp;
	int head, tail, mid;
	uint8_t delta, step;

	/* Is ADC result in linear range? */
	if (adc >= ADC_DISCREET_RANGE_START_RESULT) {
		temp = adc_to_temp(adc);
	}
	/* Hotter than our discreet range limit? */
	else if (adc <= ADC_DISCREET_RANGE_LIMIT_RESULT) {
		temp = ADC_DISCREET_RANGE_LIMIT_TEMP;
	}
	/* We're in the discreet range */
	else {
		/* Table uses 9 bit ADC values */
		adc /= 2;

		/* Binary search to find proper table entry */
		head = 0;
		tail = ARRAY_SIZE(adc_result) - 1;
		while (head != tail) {
			mid = (head + tail) / 2;
			if (adc_result[mid] >= adc &&
			    adc_result[mid+1] < adc)
				break;
			if (adc_result[mid] > adc)
				head = mid + 1;
			else
				tail = mid;
		}

		/* Now fit between table entries using linear interpolation. */
		if (head != tail) {
			delta = adc_result[mid] - adc_result[mid + 1];
			step = ((adc_result[mid] - adc) *
				ADC_DISCREET_RANGE_STEP + delta / 2) / delta;
		} else {
			/* Edge case where adc = max */
			mid = head;
			step = 0;
		}

		temp = ADC_DISCREET_RANGE_START_TEMP +
		       ADC_DISCREET_RANGE_STEP * mid + step;
	}

	return temp;
}
/**
 * mid_read_temp - read sensors for temperature
 * @temp: holds the current temperature for the sensor after reading
 *
 * reads the adc_code from the channel and converts it to real
 * temperature. The converted value is stored in temp.
 *
 * Can sleep
 */
static int mid_read_temp(struct thermal_zone_device *tzd, unsigned long *temp)
{
	struct thermal_device_info *td_info = tzd->devdata;
	uint16_t adc_val, addr;
	uint8_t data = 0;
	int ret;
	unsigned long curr_temp;


	addr = td_info->chnl_addr;

	/* Enable the msic for conversion before reading */
	ret = intel_msic_reg_write(INTEL_MSIC_ADC1CNTL3, MSIC_ADCRRDATA_ENBL);
	if (ret)
		return ret;

	/* Re-toggle the RRDATARD bit (temporary workaround) */
	ret = intel_msic_reg_write(INTEL_MSIC_ADC1CNTL3, MSIC_ADCTHERM_ENBL);
	if (ret)
		return ret;

	/* Read the higher bits of data */
	ret = intel_msic_reg_read(addr, &data);
	if (ret)
		return ret;

	/* Shift bits to accommodate the lower two data bits */
	adc_val = (data << 2);
	addr++;

	ret = intel_msic_reg_read(addr, &data);/* Read lower bits */
	if (ret)
		return ret;

	/* Adding lower two bits to the higher bits */
	data &= 03;
	adc_val += data;

	/* Convert ADC value to temperature */
	ret = adc_to_temp(td_info->direct, adc_val, &curr_temp);
	if (ret == 0)
		*temp = td_info->curr_temp = curr_temp;
	return ret;
}
static int mid_read_temp(struct thermal_zone_device *tzd, unsigned long *temp)
{
	struct thermal_device_info *td_info = tzd->devdata;
	uint16_t adc_val, addr;
	uint8_t data = 0;
	int ret;
	unsigned long curr_temp;


	addr = td_info->chnl_addr;

	
	ret = intel_msic_reg_write(INTEL_MSIC_ADC1CNTL3, MSIC_ADCRRDATA_ENBL);
	if (ret)
		return ret;

	
	ret = intel_msic_reg_write(INTEL_MSIC_ADC1CNTL3, MSIC_ADCTHERM_ENBL);
	if (ret)
		return ret;

	
	ret = intel_msic_reg_read(addr, &data);
	if (ret)
		return ret;

	
	adc_val = (data << 2);
	addr++;

	ret = intel_msic_reg_read(addr, &data);
	if (ret)
		return ret;

	
	data &= 03;
	adc_val += data;

	
	ret = adc_to_temp(td_info->direct, adc_val, &curr_temp);
	if (ret == 0)
		*temp = td_info->curr_temp = curr_temp;
	return ret;
}