Пример #1
0
static int
omap_bandgap_force_single_read(struct omap_bandgap *bg_ptr, int id)
{
	struct temp_sensor_registers *tsr;
	u32 temp = 0, counter = 1000;

	tsr = bg_ptr->conf->sensors[id].registers;
	/* Select single conversion mode */
	if (OMAP_BANDGAP_HAS(bg_ptr, MODE_CONFIG)) {
		temp = omap_bandgap_readl(bg_ptr, tsr->bgap_mode_ctrl);
		temp &= ~(1 << __ffs(tsr->mode_ctrl_mask));
		omap_bandgap_writel(bg_ptr, temp, tsr->bgap_mode_ctrl);
	}

	/* Start of Conversion = 1 */
	temp = omap_bandgap_readl(bg_ptr, tsr->temp_sensor_ctrl);
	temp |= 1 << __ffs(tsr->bgap_soc_mask);
	omap_bandgap_writel(bg_ptr, temp, tsr->temp_sensor_ctrl);
	/* Wait until DTEMP is updated */
	temp = omap_bandgap_readl(bg_ptr, tsr->temp_sensor_ctrl);
	temp &= (tsr->bgap_dtemp_mask);
	while ((temp == 0) && --counter) {
		temp = omap_bandgap_readl(bg_ptr, tsr->temp_sensor_ctrl);
		temp &= (tsr->bgap_dtemp_mask);
	}
	/* Start of Conversion = 0 */
	temp = omap_bandgap_readl(bg_ptr, tsr->temp_sensor_ctrl);
	temp &= ~(1 << __ffs(tsr->bgap_soc_mask));
	omap_bandgap_writel(bg_ptr, temp, tsr->temp_sensor_ctrl);

	return 0;
}
Пример #2
0
/* Talert Thot and Tcold thresholds. Call it only if HAS(TALERT) is set */
static
int temp_sensor_init_talert_thresholds(struct omap_bandgap *bg_ptr, int id,
				       int t_hot, int t_cold)
{
	struct temp_sensor_registers *tsr;
	u32 reg_val, thresh_val;

	tsr = bg_ptr->conf->sensors[id].registers;
	thresh_val = omap_bandgap_readl(bg_ptr, tsr->bgap_threshold);

	/* write the new t_cold value */
	reg_val = thresh_val & ~tsr->threshold_tcold_mask;
	reg_val |= (t_cold << __ffs(tsr->threshold_tcold_mask));
	omap_bandgap_writel(bg_ptr, reg_val, tsr->bgap_threshold);

	thresh_val = omap_bandgap_readl(bg_ptr, tsr->bgap_threshold);

	/* write the new t_hot value */
	reg_val = thresh_val & ~tsr->threshold_thot_mask;
	reg_val |= (t_hot << __ffs(tsr->threshold_thot_mask));
	omap_bandgap_writel(bg_ptr, reg_val, tsr->bgap_threshold);

	reg_val = omap_bandgap_readl(bg_ptr, tsr->bgap_mask_ctrl);
	reg_val |= tsr->mask_hot_mask;
	reg_val |= tsr->mask_cold_mask;
	omap_bandgap_writel(bg_ptr, reg_val, tsr->bgap_mask_ctrl);

	return 0;
}
Пример #3
0
/* Talert Thot threshold. Call it only if HAS(TALERT) is set */
static
int temp_sensor_configure_thot(struct omap_bandgap *bg_ptr, int id, int t_hot)
{
	struct temp_sensor_data *ts_data = bg_ptr->conf->sensors[id].ts_data;
	struct temp_sensor_registers *tsr;
	u32 thresh_val, reg_val;
	int cold, err = 0;

	tsr = bg_ptr->conf->sensors[id].registers;

	/* obtain the T cold value */
	thresh_val = omap_bandgap_readl(bg_ptr, tsr->bgap_threshold);
	cold = (thresh_val & tsr->threshold_tcold_mask) >>
	    __ffs(tsr->threshold_tcold_mask);
	if (t_hot <= cold) {
		/* change the t_cold to t_hot - 5000 millidegrees */
		err |= add_hyst(t_hot, -ts_data->hyst_val, bg_ptr, id, &cold);
		/* write the new t_cold value */
		reg_val = thresh_val & (~tsr->threshold_tcold_mask);
		reg_val |= cold << __ffs(tsr->threshold_tcold_mask);
		omap_bandgap_writel(bg_ptr, reg_val, tsr->bgap_threshold);
		thresh_val = reg_val;
	}

	/* write the new t_hot value */
	reg_val = thresh_val & ~tsr->threshold_thot_mask;
	reg_val |= (t_hot << __ffs(tsr->threshold_thot_mask));
	omap_bandgap_writel(bg_ptr, reg_val, tsr->bgap_threshold);
	if (err) {
		dev_err(bg_ptr->dev, "failed to reprogram thot threshold\n");
		return -EIO;
	}

	return temp_sensor_unmask_interrupts(bg_ptr, id, t_hot, cold);
}
Пример #4
0
static u32 omap_bandgap_read_temp(struct omap_bandgap *bg_ptr, int id)
{
	struct temp_sensor_registers *tsr;
	u32 temp, ctrl, reg;

	tsr = bg_ptr->conf->sensors[id].registers;
	reg = tsr->temp_sensor_ctrl;

	if (OMAP_BANDGAP_HAS(bg_ptr, FREEZE_BIT)) {
		ctrl = omap_bandgap_readl(bg_ptr, tsr->bgap_mask_ctrl);
		ctrl |= tsr->mask_freeze_mask;
		omap_bandgap_writel(bg_ptr, ctrl, tsr->bgap_mask_ctrl);
		/*
		 * In case we cannot read from cur_dtemp / dtemp_0,
		 * then we read from the last valid temp read
		 */
		reg = tsr->ctrl_dtemp_1;
	}

	/* read temperature */
	temp = omap_bandgap_readl(bg_ptr, reg);
	temp &= tsr->bgap_dtemp_mask;

	if (OMAP_BANDGAP_HAS(bg_ptr, FREEZE_BIT)) {
		ctrl = omap_bandgap_readl(bg_ptr, tsr->bgap_mask_ctrl);
		ctrl &= ~tsr->mask_freeze_mask;
		omap_bandgap_writel(bg_ptr, ctrl, tsr->bgap_mask_ctrl);
	}

	return temp;
}
Пример #5
0
/* Talert masks. Call it only if HAS(TALERT) is set */
static int temp_sensor_unmask_interrupts(struct omap_bandgap *bg_ptr, int id,
					 u32 t_hot, u32 t_cold)
{
	struct temp_sensor_registers *tsr;
	u32 temp, reg_val;

	/* Read the current on die temperature */
	tsr = bg_ptr->conf->sensors[id].registers;
	temp = omap_bandgap_readl(bg_ptr, tsr->temp_sensor_ctrl);
	temp &= tsr->bgap_dtemp_mask;

	reg_val = omap_bandgap_readl(bg_ptr, tsr->bgap_mask_ctrl);
	if (temp < t_hot)
		reg_val |= tsr->mask_hot_mask;
	else
		reg_val &= ~tsr->mask_hot_mask;

	if (t_cold < temp)
		reg_val |= tsr->mask_cold_mask;
	else
		reg_val &= ~tsr->mask_cold_mask;
	omap_bandgap_writel(bg_ptr, reg_val, tsr->bgap_mask_ctrl);

	return 0;
}
Пример #6
0
static int omap_bandgap_restore_ctxt(struct omap_bandgap *bg_ptr)
{
	int i;

	for (i = 0; i < bg_ptr->conf->sensor_count; i++) {
		struct temp_sensor_registers *tsr;
		struct temp_sensor_regval *rval;
		u32 val = 0;

		rval = &bg_ptr->conf->sensors[i].regval;
		tsr = bg_ptr->conf->sensors[i].registers;

		if (OMAP_BANDGAP_HAS(bg_ptr, COUNTER))
			val = omap_bandgap_readl(bg_ptr, tsr->bgap_counter);

		if (OMAP_BANDGAP_HAS(bg_ptr, TSHUT_CONFIG))
			omap_bandgap_writel(bg_ptr,
				rval->tshut_threshold,
					   tsr->tshut_threshold);
		/* Force immediate temperature measurement and update
		 * of the DTEMP field
		 */
		omap_bandgap_force_single_read(bg_ptr, i);

		if (OMAP_BANDGAP_HAS(bg_ptr, COUNTER))
			omap_bandgap_writel(bg_ptr, rval->bg_counter,
						   tsr->bgap_counter);
		if (OMAP_BANDGAP_HAS(bg_ptr, MODE_CONFIG))
			omap_bandgap_writel(bg_ptr, rval->bg_mode_ctrl,
						   tsr->bgap_mode_ctrl);
		if (OMAP_BANDGAP_HAS(bg_ptr, TALERT)) {
			omap_bandgap_writel(bg_ptr,
						   rval->bg_threshold,
						   tsr->bgap_threshold);
			omap_bandgap_writel(bg_ptr, rval->bg_ctrl,
						   tsr->bgap_mask_ctrl);
		}
	}

	return 0;
}
Пример #7
0
/* This is the Talert handler. Call it only if HAS(TALERT) is set */
static irqreturn_t talert_irq_handler(int irq, void *data)
{
	struct omap_bandgap *bg_ptr = data;
	struct temp_sensor_registers *tsr;
	u32 t_hot = 0, t_cold = 0, temp, ctrl;
	int i;

	bg_ptr = data;
	/* Read the status of t_hot */
	for (i = 0; i < bg_ptr->conf->sensor_count; i++) {
		tsr = bg_ptr->conf->sensors[i].registers;
		t_hot = omap_bandgap_readl(bg_ptr, tsr->bgap_status);
		t_hot &= tsr->status_hot_mask;

		/* Read the status of t_cold */
		t_cold = omap_bandgap_readl(bg_ptr, tsr->bgap_status);
		t_cold &= tsr->status_cold_mask;

		if (!t_cold && !t_hot)
			continue;

		ctrl = omap_bandgap_readl(bg_ptr, tsr->bgap_mask_ctrl);
		/*
		 * One TALERT interrupt: Two sources
		 * If the interrupt is due to t_hot then mask t_hot and
		 * and unmask t_cold else mask t_cold and unmask t_hot
		 */
		if (t_hot) {
			ctrl &= ~tsr->mask_hot_mask;
			ctrl |= tsr->mask_cold_mask;
		} else if (t_cold) {
			ctrl &= ~tsr->mask_cold_mask;
			ctrl |= tsr->mask_hot_mask;
		}

		omap_bandgap_writel(bg_ptr, ctrl, tsr->bgap_mask_ctrl);

		dev_dbg(bg_ptr->dev,
			"%s: IRQ from %s sensor: hotevent %d coldevent %d\n",
			__func__, bg_ptr->conf->sensors[i].domain,
			t_hot, t_cold);

		/* read temperature */
		temp = omap_bandgap_readl(bg_ptr, tsr->temp_sensor_ctrl);
		temp &= tsr->bgap_dtemp_mask;

		/* report temperature to whom may concern */
		if (bg_ptr->conf->report_temperature)
			bg_ptr->conf->report_temperature(bg_ptr, i);
	}

	return IRQ_HANDLED;
}
Пример #8
0
/* This is counter config. Call it only if HAS(COUNTER) is set */
static int configure_temp_sensor_counter(struct omap_bandgap *bg_ptr, int id,
					 u32 counter)
{
	struct temp_sensor_registers *tsr;
	u32 val;

	tsr = bg_ptr->conf->sensors[id].registers;
	val = omap_bandgap_readl(bg_ptr, tsr->bgap_counter);
	val &= ~tsr->counter_mask;
	val |= counter << __ffs(tsr->counter_mask);
	omap_bandgap_writel(bg_ptr, val, tsr->bgap_counter);

	return 0;
}
Пример #9
0
/* This is Tshut Tcold config. Call it only if HAS(TSHUT_CONFIG) is set */
static int temp_sensor_configure_tshut_cold(struct omap_bandgap *bg_ptr,
					    int id, int tshut_cold)
{
	struct temp_sensor_registers *tsr;
	u32 reg_val;

	tsr = bg_ptr->conf->sensors[id].registers;
	reg_val = omap_bandgap_readl(bg_ptr, tsr->tshut_threshold);
	reg_val &= ~tsr->tshut_cold_mask;
	reg_val |= tshut_cold << __ffs(tsr->tshut_cold_mask);
	omap_bandgap_writel(bg_ptr, reg_val, tsr->tshut_threshold);

	return 0;
}
Пример #10
0
/**
 * enable_continuous_mode() - One time enabling of continuous conversion mode
 * @bg_ptr - pointer to scm instance
 *
 * Call this function only if HAS(MODE_CONFIG) is set
 */
static int enable_continuous_mode(struct omap_bandgap *bg_ptr)
{
	struct temp_sensor_registers *tsr;
	int i;
	u32 val;

	for (i = 0; i < bg_ptr->conf->sensor_count; i++) {
		/* Perform a single read just before enabling continuous */
		omap_bandgap_force_single_read(bg_ptr, i);
		tsr = bg_ptr->conf->sensors[i].registers;
		val = omap_bandgap_readl(bg_ptr, tsr->bgap_mode_ctrl);
		val |= 1 << __ffs(tsr->mode_ctrl_mask);
		omap_bandgap_writel(bg_ptr, val, tsr->bgap_mode_ctrl);
	}

	return 0;
}
Пример #11
0
static int omap_bandgap_power(struct omap_bandgap *bg_ptr, bool on)
{
	struct temp_sensor_registers *tsr;
	int i;
	u32 ctrl;

	if (!OMAP_BANDGAP_HAS(bg_ptr, POWER_SWITCH))
		return 0;

	for (i = 0; i < bg_ptr->conf->sensor_count; i++) {
		tsr = bg_ptr->conf->sensors[i].registers;
		ctrl = omap_bandgap_readl(bg_ptr, tsr->temp_sensor_ctrl);
		ctrl &= ~tsr->bgap_tempsoff_mask;
		/* active on 0 */
		ctrl |= !on << __ffs(tsr->bgap_tempsoff_mask);

		/* write BGAP_TEMPSOFF should be reset to 0 */
		omap_bandgap_writel(bg_ptr, ctrl, tsr->temp_sensor_ctrl);
	}

	return 0;
}