/** * 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; }
/* 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; }