static int anatop_thermal_get_trip_temp(struct thermal_zone_device *thermal, int trip, unsigned long *temp) { struct anatop_thermal *tz = thermal->devdata; if (!tz || trip < 0) return -EINVAL; if (tz->trips.critical.flags.valid) { if (!trip) { *temp = KELVIN_TO_CEL( tz->trips.critical.temperature, tz->kelvin_offset); return 0; } trip--; } if (tz->trips.hot.flags.valid) { if (!trip) { *temp = KELVIN_TO_CEL( tz->trips.hot.temperature, tz->kelvin_offset); return 0; } trip--; } if (tz->trips.passive.flags.valid) { if (!trip) { *temp = KELVIN_TO_CEL( tz->trips.passive.temperature, tz->kelvin_offset); return 0; } trip--; } if (tz->trips.active.flags.valid) { if (!trip) { *temp = KELVIN_TO_CEL( tz->trips.active.temperature, tz->kelvin_offset); return 0; } trip--; } return -EINVAL; }
static int anatop_thermal_get_crit_temp(struct thermal_zone_device *thermal, unsigned long *temperature) { struct anatop_thermal *tz = thermal->devdata; if (tz->trips.critical.flags.valid) { *temperature = KELVIN_TO_CEL( tz->trips.critical.temperature, tz->kelvin_offset); return 0; } else return -EINVAL; }
static int anatop_thermal_counting_ratio(unsigned int fuse_data) { int ret = -EINVAL; pr_info("Thermal calibration data is 0x%x\n", fuse_data); if (fuse_data == 0 || fuse_data == 0xffffffff || (fuse_data & 0xfff00000) == 0) { pr_info("%s: invalid calibration data, disable cooling!!!\n", __func__); cooling_device_disable = true; ratio = DEFAULT_RATIO; disable_irq(thermal_irq); return ret; } ret = 0; /* Fuse data layout: * [31:20] sensor value @ 25C * [19:8] sensor value of hot * [7:0] hot temperature value */ raw_25c = fuse_data >> 20; raw_hot = (fuse_data & 0xfff00) >> 8; hot_temp = fuse_data & 0xff; if (!calibration_valid && !cpu_is_mx6sl()) /* * The universal equation for thermal sensor * is slope = 0.4297157 - (0.0015976 * 25C fuse), * here we convert them to integer to make them * easy for counting, FACTOR1 is 15976, * FACTOR2 is 4297157. Our ratio = -100 * slope. */ ratio = ((FACTOR1 * raw_25c - FACTOR2) + 50000) / 100000; else ratio = ((raw_25c - raw_hot) * 100) / (hot_temp - 25); pr_info("Thermal sensor with ratio = %d\n", ratio); raw_n40c = raw_25c + (13 * ratio) / 20; raw_125c = raw_25c - ratio; /* Init default critical temp to set alarm */ raw_critical = raw_25c - ratio * (KELVIN_TO_CEL(TEMP_CRITICAL, KELVIN_OFFSET) - 25) / 100; clk_enable(pll3_clk); anatop_update_alarm(raw_critical); return ret; }
static int anatop_thermal_get_temp(struct thermal_zone_device *thermal, long *temp) { struct anatop_thermal *tz = thermal->devdata; unsigned int tmp; unsigned int reg; unsigned int val; if (!tz) return -EINVAL; if (!ratio || suspend_flag) { *temp = KELVIN_TO_CEL(TEMP_ACTIVE, MKELVIN_OFFSET); return 0; } tz->last_temperature = tz->temperature; if ((__raw_readl(anatop_base + HW_ANADIG_TEMPSENSE0) & BM_ANADIG_TEMPSENSE0_POWER_DOWN) != 0) { /* need to keep sensor power up as we enable alarm function */ __raw_writel(BM_ANADIG_TEMPSENSE0_POWER_DOWN, anatop_base + HW_ANADIG_TEMPSENSE0_CLR); __raw_writel(BM_ANADIG_ANA_MISC0_REFTOP_SELBIASOFF, anatop_base + HW_ANADIG_ANA_MISC0_SET); /* write measure freq */ reg = __raw_readl(anatop_base + HW_ANADIG_TEMPSENSE1); reg &= ~BM_ANADIG_TEMPSENSE1_MEASURE_FREQ; reg |= MEASURE_FREQ; __raw_writel(reg, anatop_base + HW_ANADIG_TEMPSENSE1); } __raw_writel(BM_ANADIG_TEMPSENSE0_MEASURE_TEMP, anatop_base + HW_ANADIG_TEMPSENSE0_CLR); __raw_writel(BM_ANADIG_TEMPSENSE0_FINISHED, anatop_base + HW_ANADIG_TEMPSENSE0_CLR); __raw_writel(BM_ANADIG_TEMPSENSE0_MEASURE_TEMP, anatop_base + HW_ANADIG_TEMPSENSE0_SET); tmp = 0; val = jiffies; /* read temperature values */ while ((__raw_readl(anatop_base + HW_ANADIG_TEMPSENSE0) & BM_ANADIG_TEMPSENSE0_FINISHED) == 0) { if (time_after(jiffies, (unsigned long)(val + HZ / 2))) { pr_info("Thermal sensor timeout, retry!\n"); return 0; } msleep(10); } reg = __raw_readl(anatop_base + HW_ANADIG_TEMPSENSE0); tmp = (reg & BM_ANADIG_TEMPSENSE0_TEMP_VALUE) >> BP_ANADIG_TEMPSENSE0_TEMP_VALUE; __raw_writel(BM_ANADIG_TEMPSENSE0_FINISHED, anatop_base + HW_ANADIG_TEMPSENSE0_CLR); if (ANATOP_DEBUG) anatop_dump_temperature_register(); /* only the temp between -40C and 125C is valid, this is for save */ if (tmp <= raw_n40c && tmp >= raw_125c) tz->temperature = REG_VALUE_TO_MCEL(ratio, tmp); else { printk(KERN_WARNING "Invalid temperature, force it to 25C\n"); tz->temperature = 25000; } if (debug_mask & DEBUG_VERBOSE) pr_info("Cooling device Temperature is %lu C\n", tz->temperature); *temp = (cooling_device_disable && tz->temperature >= KELVIN_TO_CEL(TEMP_CRITICAL, MKELVIN_OFFSET)) ? KELVIN_TO_CEL(TEMP_CRITICAL - 1, MKELVIN_OFFSET) : tz->temperature; /* Set alarm threshold if necessary */ if ((__raw_readl(anatop_base + HW_ANADIG_TEMPSENSE0) & BM_ANADIG_TEMPSENSE0_ALARM_VALUE) == 0) anatop_update_alarm(raw_critical); return 0; }
static int anatop_thermal_get_temp(struct thermal_zone_device *thermal, long *temp) { struct anatop_thermal *tz = thermal->devdata; unsigned int tmp; unsigned int reg; unsigned int i; if (!tz) return -EINVAL; #ifdef CONFIG_FSL_OTP if (!ratio) { anatop_thermal_get_calibration_data(&tmp); *temp = KELVIN_TO_CEL(TEMP_ACTIVE, KELVIN_OFFSET); return 0; } #else if (!cooling_device_disable) pr_info("%s: can't get calibration data, disable cooling!!!\n", __func__); cooling_device_disable = true; ratio = DEFAULT_RATIO; #endif tz->last_temperature = tz->temperature; /* now we only using single measure, every time we measure the temperature, we will power on/down the anadig module*/ __raw_writel(BM_ANADIG_TEMPSENSE0_POWER_DOWN, anatop_base + HW_ANADIG_TEMPSENSE0_CLR); __raw_writel(BM_ANADIG_ANA_MISC0_REFTOP_SELBIASOFF, anatop_base + HW_ANADIG_ANA_MISC0_SET); /* write measure freq */ reg = __raw_readl(anatop_base + HW_ANADIG_TEMPSENSE1); reg &= ~BM_ANADIG_TEMPSENSE1_MEASURE_FREQ; reg |= MEASURE_FREQ; __raw_writel(reg, anatop_base + HW_ANADIG_TEMPSENSE1); __raw_writel(BM_ANADIG_TEMPSENSE0_MEASURE_TEMP, anatop_base + HW_ANADIG_TEMPSENSE0_CLR); __raw_writel(BM_ANADIG_TEMPSENSE0_FINISHED, anatop_base + HW_ANADIG_TEMPSENSE0_CLR); __raw_writel(BM_ANADIG_TEMPSENSE0_MEASURE_TEMP, anatop_base + HW_ANADIG_TEMPSENSE0_SET); tmp = 0; /* read five times of temperature values to get average*/ for (i = 0; i < 5; i++) { while ((__raw_readl(anatop_base + HW_ANADIG_TEMPSENSE0) & BM_ANADIG_TEMPSENSE0_FINISHED) == 0) msleep(10); reg = __raw_readl(anatop_base + HW_ANADIG_TEMPSENSE0); tmp += (reg & BM_ANADIG_TEMPSENSE0_TEMP_VALUE) >> BP_ANADIG_TEMPSENSE0_TEMP_VALUE; __raw_writel(BM_ANADIG_TEMPSENSE0_FINISHED, anatop_base + HW_ANADIG_TEMPSENSE0_CLR); if (ANATOP_DEBUG) anatop_dump_temperature_register(); } tmp = tmp / 5; if (tmp <= raw_n25c) tz->temperature = REG_VALUE_TO_CEL(ratio, tmp); else tz->temperature = -25; if (debug_mask & DEBUG_VERBOSE) pr_info("Cooling device Temperature is %lu C\n", tz->temperature); /* power down anatop thermal sensor */ __raw_writel(BM_ANADIG_TEMPSENSE0_POWER_DOWN, anatop_base + HW_ANADIG_TEMPSENSE0_SET); __raw_writel(BM_ANADIG_ANA_MISC0_REFTOP_SELBIASOFF, anatop_base + HW_ANADIG_ANA_MISC0_CLR); *temp = (cooling_device_disable && tz->temperature >= KELVIN_TO_CEL(TEMP_CRITICAL, KELVIN_OFFSET)) ? KELVIN_TO_CEL(TEMP_CRITICAL - 1, KELVIN_OFFSET) : tz->temperature; return 0; }