Exemplo n.º 1
0
static int anatop_thermal_resume(struct platform_device *pdev)
{
	/* Power up anatop thermal sensor */
	__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);
	suspend_flag = false;
	/* turn on alarm */
	anatop_update_alarm(raw_critical);
	return 0;
}
Exemplo n.º 2
0
static int anatop_thermal_suspend(struct platform_device *pdev,
		pm_message_t state)
{
	/* turn off alarm */
	anatop_update_alarm(0);
	suspend_flag = true;
	/* Power down anatop thermal sensor */
	__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_POWER_DOWN,
		anatop_base + HW_ANADIG_TEMPSENSE0_SET);
	__raw_writel(BM_ANADIG_ANA_MISC0_REFTOP_SELBIASOFF,
		anatop_base + HW_ANADIG_ANA_MISC0_CLR);
	return 0;
}
Exemplo 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;
}
Exemplo n.º 4
0
static int anatop_thermal_set_trip_temp(struct thermal_zone_device *thermal,
				 int trip, unsigned long *temp)
{
	struct anatop_thermal *tz = thermal->devdata;

	if (!tz || trip < 0)
		return -EINVAL;

	switch (trip) {
	case ANATOP_TRIPS_POINT_CRITICAL:
		/* Critical Shutdown */
		if (tz->trips.critical.flags.valid) {
			tz->trips.critical.temperature = CEL_TO_KELVIN(
				*temp, tz->kelvin_offset);
			raw_critical = raw_25c - ratio * (*temp - 25000) / 100000;
			anatop_update_alarm(raw_critical);
		}
		break;
	case ANATOP_TRIPS_POINT_HOT:
		/* Hot */
		if (tz->trips.hot.flags.valid)
				tz->trips.hot.temperature = CEL_TO_KELVIN(
				*temp, tz->kelvin_offset);
		break;
	case ANATOP_TRIPS_POINT_ACTIVE:
		/* Active */
		if (tz->trips.active.flags.valid)
				tz->trips.active.temperature = CEL_TO_KELVIN(
				*temp, tz->kelvin_offset);
		break;
	default:
		break;
	}

	return 0;
}
Exemplo 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 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;
}