Esempio n. 1
0
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;
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
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;
}
Esempio n. 4
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 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;
}
Esempio n. 5
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;
}