/**
 * ti_bandgap_get_trend() - To fetch the temperature trend of a sensor
 * @bgp: pointer to struct ti_bandgap
 * @id: id of the individual sensor
 * @trend: Pointer to trend.
 *
 * This function needs to be called to fetch the temperature trend of a
 * Particular sensor. The function computes the difference in temperature
 * w.r.t time. For the bandgaps with built in history buffer the temperatures
 * are read from the buffer and for those without the Buffer -ENOTSUPP is
 * returned.
 *
 * Return: 0 if no error, else return corresponding error. If no
 *		error then the trend value is passed on to trend parameter
 */
int ti_bandgap_get_trend(struct ti_bandgap *bgp, int id, int *trend)
{
	struct temp_sensor_registers *tsr;
	u32 temp1, temp2, reg1, reg2;
	int t1, t2, interval, ret = 0;

	ret = ti_bandgap_validate(bgp, id);
	if (ret)
		goto exit;

	if (!TI_BANDGAP_HAS(bgp, HISTORY_BUFFER) ||
	    !TI_BANDGAP_HAS(bgp, FREEZE_BIT)) {
		ret = -ENOTSUPP;
		goto exit;
	}

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

	/* Freeze and read the last 2 valid readings */
	reg1 = tsr->ctrl_dtemp_1;
	reg2 = tsr->ctrl_dtemp_2;

	/* read temperature from history buffer */
	temp1 = ti_bandgap_readl(bgp, reg1);
	temp1 &= tsr->bgap_dtemp_mask;

	temp2 = ti_bandgap_readl(bgp, reg2);
	temp2 &= tsr->bgap_dtemp_mask;

	/* Convert from adc values to mCelsius temperature */
	ret = ti_bandgap_adc_to_mcelsius(bgp, temp1, &t1);
	if (ret)
		goto exit;

	ret = ti_bandgap_adc_to_mcelsius(bgp, temp2, &t2);
	if (ret)
		goto exit;

	/* Fetch the update interval */
	ret = ti_bandgap_read_update_interval(bgp, id, &interval);
	if (ret || !interval)
		goto exit;

	*trend = (t1 - t2) / interval;

	dev_dbg(bgp->dev, "The temperatures are t1 = %d and t2 = %d and trend =%d\n",
		t1, t2, *trend);

exit:
	return ret;
}
Beispiel #2
0
/**
 * ti_bandgap_add_hyst() - add hysteresis (in mCelsius) to an ADC value
 * @bgp: struct ti_bandgap pointer
 * @adc_val: temperature value in ADC representation
 * @hyst_val: hysteresis value in mCelsius
 * @sum: address where to write the resulting temperature (in ADC scale)
 *
 * Adds an hysteresis value (in mCelsius) to a ADC temperature value.
 *
 * Return: 0 on success, -ERANGE otherwise.
 */
static
int ti_bandgap_add_hyst(struct ti_bandgap *bgp, int adc_val, int hyst_val,
			u32 *sum)
{
	int temp, ret;

	/*
	 * Need to add in the mcelsius domain, so we have a temperature
	 * the conv_table range
	 */
	ret = ti_bandgap_adc_to_mcelsius(bgp, adc_val, &temp);
	if (ret < 0)
		goto exit;

	temp += hyst_val;

	ret = ti_bandgap_mcelsius_to_adc(bgp, temp, sum);

exit:
	return ret;
}
Beispiel #3
0
/**
 * ti_bandgap_read_temperature() - report current temperature
 * @bgp: pointer to bandgap instance
 * @id: sensor id
 * @temperature: resulting temperature
 *
 * Return: 0 on success or the proper error code
 */
int ti_bandgap_read_temperature(struct ti_bandgap *bgp, int id,
				int *temperature)
{
	u32 temp;
	int ret;

	ret = ti_bandgap_validate(bgp, id);
	if (ret)
		return ret;

	spin_lock(&bgp->lock);
	temp = ti_bandgap_read_temp(bgp, id);
	spin_unlock(&bgp->lock);

	ret |= ti_bandgap_adc_to_mcelsius(bgp, temp, &temp);
	if (ret)
		return -EIO;

	*temperature = temp;

	return 0;
}
Beispiel #4
0
/**
 * _ti_bandgap_read_threshold() - helper to read TALERT t_cold or t_hot
 * @bgp: struct ti_bandgap pointer
 * @id: bandgap sensor id
 * @val: value (mCelsius) of a threshold
 * @hot: desired threshold to be read. true if threshold hot, false if
 *       threshold cold
 *
 * It will fetch the required thresholds (hot and cold) for TALERT signal.
 * This function can be used to read t_hot or t_cold, depending on @hot value.
 * Call this function only if bandgap features HAS(TALERT).
 *
 * Return: 0 if no error, -ENOTSUPP if it has no TALERT support, or the
 * corresponding error value if some operation fails.
 */
static int _ti_bandgap_read_threshold(struct ti_bandgap *bgp, int id,
				      int *val, bool hot)
{
	struct temp_sensor_registers *tsr;
	u32 temp, mask;
	int ret = 0;

	ret = ti_bandgap_validate(bgp, id);
	if (ret)
		goto exit;

	if (!TI_BANDGAP_HAS(bgp, TALERT)) {
		ret = -ENOTSUPP;
		goto exit;
	}

	tsr = bgp->conf->sensors[id].registers;
	if (hot)
		mask = tsr->threshold_thot_mask;
	else
		mask = tsr->threshold_tcold_mask;

	temp = ti_bandgap_readl(bgp, tsr->bgap_threshold);
	temp = (temp & mask) >> __ffs(mask);
	ret |= ti_bandgap_adc_to_mcelsius(bgp, temp, &temp);
	if (ret) {
		dev_err(bgp->dev, "failed to read thot\n");
		ret = -EIO;
		goto exit;
	}

	*val = temp;

exit:
	return ret;
}