static void omap_configure_temp_sensor_thresholds(struct omap_temp_sensor *temp_sensor) { u32 temp = 0, t_hot, t_cold, tshut_hot, tshut_cold; t_hot = temp_to_adc_conversion(BGAP_THRESHOLD_T_HOT); t_cold = temp_to_adc_conversion(BGAP_THRESHOLD_T_COLD); if ((t_hot == -EINVAL) || (t_cold == -EINVAL)) { pr_err("%s:Temp thresholds out of bounds\n", __func__); return; } temp = ((t_hot << OMAP4_T_HOT_SHIFT) | (t_cold << OMAP4_T_COLD_SHIFT)); omap_temp_sensor_writel(temp_sensor, temp, BGAP_THRESHOLD_OFFSET); tshut_hot = temp_to_adc_conversion(TSHUT_THRESHOLD_TSHUT_HOT); tshut_cold = temp_to_adc_conversion(TSHUT_THRESHOLD_TSHUT_COLD); if ((tshut_hot == -EINVAL) || (tshut_cold == -EINVAL)) { pr_err("%s:Temp shutdown thresholds out of bounds\n", __func__); return; } temp = ((tshut_hot << OMAP4_TSHUT_HOT_SHIFT) | (tshut_cold << OMAP4_TSHUT_COLD_SHIFT)); omap_temp_sensor_writel(temp_sensor, temp, BGAP_TSHUT_OFFSET); }
static int omap_set_temp_thresh(struct thermal_dev *tdev, int min, int max) { struct platform_device *pdev = to_platform_device(tdev->dev); struct scm *scm_ptr = platform_get_drvdata(pdev); int ret, t_cold, t_hot, thresh_val, hot, cold; int id = tdev->sen_id; struct omap4460plus_temp_sensor_registers *tsr; tsr = scm_ptr->registers[id]; t_cold = temp_to_adc_conversion(min, scm_ptr, id); t_hot = temp_to_adc_conversion(max, scm_ptr, id); thresh_val = omap4plus_scm_readl(scm_ptr, tsr->bgap_threshold); hot = (thresh_val & tsr->threshold_thot_mask) >> __ffs(tsr->threshold_thot_mask); cold = (thresh_val & tsr->threshold_tcold_mask) >> __ffs(tsr->threshold_tcold_mask); if (t_hot < cold) { ret = omap4460plus_scm_set_temp_max_hyst(scm_ptr, id, min); ret = omap4460plus_scm_set_temp_max(scm_ptr, id, max); } else { ret = omap4460plus_scm_set_temp_max(scm_ptr, id, max); ret = omap4460plus_scm_set_temp_max_hyst(scm_ptr, id, min); } return ret; }
static int omap_set_thresholds(struct omap_temp_sensor *temp_sensor, int min, int max) { int reg_val = 0; int new_cold; int new_hot; int curr_temp = 0; /* A too low value is not acceptable for the thresholds */ if ((min < OMAP_MIN_TEMP) || (max < OMAP_MIN_TEMP)) { pr_err("%s:Min or Max is invalid %d %d\n", __func__, min, max); return -EINVAL; } if (max < min) { pr_err("%s:Min is greater then the max\n", __func__); return -EINVAL; } new_hot = temp_to_adc_conversion(max); new_cold = temp_to_adc_conversion(min); if ((new_hot == -EINVAL) || (new_cold == -EINVAL)) { pr_err("%s: New thresh value is out of range\n", __func__); return -EINVAL; } reg_val = ((new_hot << OMAP4_T_HOT_SHIFT) | (new_cold << OMAP4_T_COLD_SHIFT)); omap_temp_sensor_writel(temp_sensor, reg_val, BGAP_THRESHOLD_OFFSET); curr_temp = temp_to_adc_conversion(temp_sensor->therm_fw->current_temp); if (new_hot >= curr_temp) { reg_val = omap_temp_sensor_readl(temp_sensor, BGAP_CTRL_OFFSET); reg_val |= OMAP4_MASK_HOT_MASK; omap_temp_sensor_writel(temp_sensor, reg_val, BGAP_CTRL_OFFSET); } if (new_cold <= curr_temp) { reg_val = omap_temp_sensor_readl(temp_sensor, BGAP_CTRL_OFFSET); reg_val |= OMAP4_MASK_COLD_MASK; omap_temp_sensor_writel(temp_sensor, reg_val, BGAP_CTRL_OFFSET); } if (curr_temp > new_cold && curr_temp < new_hot) { reg_val = omap_temp_sensor_readl(temp_sensor, BGAP_CTRL_OFFSET); reg_val |= (OMAP4_MASK_COLD_MASK | OMAP4_MASK_HOT_MASK); omap_temp_sensor_writel(temp_sensor, reg_val, BGAP_CTRL_OFFSET); } return 0; }
/** * omap_bandgap_write_tcold() - sets the sensor tcold * @bg_ptr - pointer to bandgap instance * @id - sensor id * @val - desired tcold value * * returns 0 on success or the proper error code */ int omap_bandgap_write_tcold(struct omap_bandgap *bg_ptr, int id, int val) { struct temp_sensor_data *ts_data; struct temp_sensor_registers *tsr; u32 t_cold; int ret; ret = omap_bandgap_validate(bg_ptr, id); if (ret) return ret; if (!OMAP_BANDGAP_HAS(bg_ptr, TALERT)) return -ENOTSUPP; ts_data = bg_ptr->conf->sensors[id].ts_data; tsr = bg_ptr->conf->sensors[id].registers; if (val > ts_data->max_temp + ts_data->hyst_val) return -EINVAL; ret = temp_to_adc_conversion(val, bg_ptr, id, &t_cold); if (ret < 0) return ret; mutex_lock(&bg_ptr->bg_mutex); temp_sensor_configure_tcold(bg_ptr, id, t_cold); mutex_unlock(&bg_ptr->bg_mutex); return 0; }
static ssize_t set_temp_crit_hyst(struct device *dev, struct device_attribute *devattr, const char *buf, size_t count) { struct platform_device *pdev = to_platform_device(dev); struct omap_temp_sensor *temp_sensor = platform_get_drvdata(pdev); u32 temp, reg_val; long val; if (strict_strtol(buf, 10, &val)) { count = -EINVAL; goto out; } temp = temp_to_adc_conversion(val); if ((temp < OMAP_ADC_START_VALUE || temp > OMAP_ADC_END_VALUE)) { pr_err("invalid range\n"); count = -EINVAL; goto out; } mutex_lock(&temp_sensor->sensor_mutex); reg_val = omap_temp_sensor_readl(temp_sensor, BGAP_TSHUT_OFFSET); reg_val = reg_val & ~(OMAP4_TSHUT_COLD_MASK); reg_val = reg_val | (temp << OMAP4_TSHUT_COLD_SHIFT); omap_temp_sensor_writel(temp_sensor, reg_val, BGAP_TSHUT_OFFSET); mutex_unlock(&temp_sensor->sensor_mutex); out: return count; }
static int add_hyst(int adc_val, int hyst_val, struct scm *scm_ptr, int i) { int temp = adc_to_temp_conversion(scm_ptr, i, adc_val); temp += hyst_val; return temp_to_adc_conversion(temp, scm_ptr, i); }
static void omap_configure_temp_sensor_thresholds(struct omap_temp_sensor *temp_sensor) { u32 temp = 0, t_hot, t_cold, tshut_hot, tshut_cold; t_hot = temp_to_adc_conversion(BGAP_THRESHOLD_T_HOT); t_cold = temp_to_adc_conversion(BGAP_THRESHOLD_T_COLD); if ((t_hot == -EINVAL) || (t_cold == -EINVAL)) { pr_err("%s:Temp thresholds out of bounds\n", __func__); return; } temp = ((t_hot << OMAP4_T_HOT_SHIFT) | (t_cold << OMAP4_T_COLD_SHIFT)); omap_temp_sensor_writel(temp_sensor, temp, BGAP_THRESHOLD_OFFSET); /* * Prevent multiple writing to one time writable register, assuming * that no one wrote zero into it before. */ if (cpu_is_omap447x() && omap_temp_sensor_readl(temp_sensor, BGAP_TSHUT_OFFSET) != 0) { pr_debug("%s:Shutdown thresholds are already set\n", __func__); return; } tshut_hot = temp_to_adc_conversion(TSHUT_THRESHOLD_TSHUT_HOT); tshut_cold = temp_to_adc_conversion(TSHUT_THRESHOLD_TSHUT_COLD); if ((tshut_hot == -EINVAL) || (tshut_cold == -EINVAL)) { pr_err("%s:Temp shutdown thresholds out of bounds\n", __func__); return; } temp = ((tshut_hot << OMAP4_TSHUT_HOT_SHIFT) | (tshut_cold << OMAP4_TSHUT_COLD_SHIFT)); omap_temp_sensor_writel(temp_sensor, temp, BGAP_TSHUT_OFFSET); if (omap_temp_sensor_readl(temp_sensor, BGAP_TSHUT_OFFSET) != temp) pr_err("%s:Shutdown thresholds can't be set\n", __func__); }
static int add_hyst(int adc_val, int hyst_val, struct omap_bandgap *bg_ptr, int i, u32 *sum) { int temp, ret; ret = adc_to_temp_conversion(bg_ptr, i, adc_val, &temp); if (ret < 0) return ret; temp += hyst_val; return temp_to_adc_conversion(temp, bg_ptr, i, sum); }
int omap4460plus_scm_set_temp_max_hyst(struct scm *scm_ptr, int id, int val) { struct omap4460plus_temp_sensor_registers *tsr; u32 t_cold; tsr = scm_ptr->registers[id]; if (val > scm_ptr->ts_data[id]->max_temp + scm_ptr->ts_data[id]->hyst_val) return -EINVAL; t_cold = temp_to_adc_conversion(val, scm_ptr, id); if (t_cold < 0) return t_cold; mutex_lock(&scm_ptr->scm_mutex); temp_sensor_configure_tcold(scm_ptr, id, t_cold); mutex_unlock(&scm_ptr->scm_mutex); return 0; }