diff options
author | Bitan Biswas <bbiswas@nvidia.com> | 2011-09-07 21:00:14 +0530 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2011-11-30 21:49:21 -0800 |
commit | 8b88af9e95c112d5751c1ab4c84524b57fc894da (patch) | |
tree | 77127dc2cb69927ba7647d31ff8b70f7db1c3f0c /drivers/hwmon | |
parent | 868eeb9407311af0ca9e9ed8e08d30003b053de4 (diff) |
hwmon: tegra: tsensor: coefficient update
m, n and p coefficients updated for fuse revision 21 and beyond.
- code cleanup done. fixed checkpatch warnings.
bug 842208
Reviewed-on: http://git-master/r/53808
(cherry picked from commit 488785f279a5642fffde3d48d62c77f46a20b63a)
Reviewed-on: http://git-master/r/55026
(cherry picked from commit 49a5b4cf51ed43e2a9d25a2603e84ed835446832)
Change-Id: I83db5a746d5960c799fbf09e2334ecc608c44d39
Reviewed-on: http://git-master/r/57367
Reviewed-by: Bitan Biswas <bbiswas@nvidia.com>
Tested-by: Bitan Biswas <bbiswas@nvidia.com>
Reviewed-by: Diwakar Tundlam <dtundlam@nvidia.com>
Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com>
Rebase-Id: R49c36a57132c60260e1ab9d9f2aa68bf3602c962
Diffstat (limited to 'drivers/hwmon')
-rw-r--r-- | drivers/hwmon/tegra-tsensor.c | 161 |
1 files changed, 93 insertions, 68 deletions
diff --git a/drivers/hwmon/tegra-tsensor.c b/drivers/hwmon/tegra-tsensor.c index 4bf104e9ef95..c7dfd966aaaa 100644 --- a/drivers/hwmon/tegra-tsensor.c +++ b/drivers/hwmon/tegra-tsensor.c @@ -120,6 +120,8 @@ struct tsensor_state { enum { /* temperature is sensed from 2 points on tegra */ TSENSOR_COUNT = 2, + TSENSOR_INSTANCE1 = 0, + TSENSOR_INSTANCE2 = 1, /* divide by 2 temperature threshold */ DIV2_CELSIUS_TEMP_THRESHOLD_DEFAULT = 70, /* reset chip temperature threshold */ @@ -179,10 +181,23 @@ struct tegra_tsensor_data { unsigned int config0[TSENSOR_COUNT]; unsigned int config1[TSENSOR_COUNT]; unsigned int config2[TSENSOR_COUNT]; + /* temperature readings from tsensor_index tsensor - 0/1 */ + unsigned int tsensor_index; + int A_e_minus6; + int B_e_minus2; + unsigned int fuse_T1; + unsigned int fuse_F1; + unsigned int fuse_T2; + unsigned int fuse_F2; + /* Quadratic fit coefficients: m=-0.003512 n=1.528943 p=-11.1 */ + int m_e_minus6; + int n_e_minus6; + int p_e_minus2; }; enum { TSENSOR_COEFF_SET1 = 0, + TSENSOR_COEFF_SET2, TSENSOR_COEFF_END }; @@ -193,22 +208,23 @@ struct tegra_tsensor_coeff { }; static struct tegra_tsensor_coeff coeff_table[] = { + /* Quadratic fit coefficients: m=-0.002775 n=1.338811 p=-7.30 */ [TSENSOR_COEFF_SET1] = { -2775, 1338811, -730 + }, + /* Quadratic fit coefficients: m=-0.003512 n=1.528943 p=-11.1 */ + [TSENSOR_COEFF_SET2] = { + -3512, + 1528943, + -1110 } /* FIXME: add tsensor coefficients after chip characterization */ }; -static unsigned int tsensor_index; static char my_fixed_str[LOCAL_STR_SIZE1] = "YYYYYY"; static char error_str[LOCAL_STR_SIZE1] = "ERROR:"; -static unsigned int fuse_T1, fuse_F1, fuse_T2, fuse_F2; -static int A_e_minus6, B_e_minus2; -static int m_e_minus6; -static int n_e_minus6; -static int p_e_minus2; static unsigned int init_flag; static int tsensor_count_2_temp(struct tegra_tsensor_data *data, @@ -309,7 +325,7 @@ static void get_chip_rev(unsigned short *p_id, unsigned short *p_major, * function to get chip revision specific tsensor coefficients * obtained after chip characterization */ -static void get_chip_tsensor_coeff(void) +static void get_chip_tsensor_coeff(struct tegra_tsensor_data *data) { unsigned short chip_id, major_rev, minor_rev; unsigned short coeff_index; @@ -322,9 +338,11 @@ static void get_chip_tsensor_coeff(void) coeff_index = TSENSOR_COEFF_SET1; break; } - m_e_minus6 = coeff_table[coeff_index].e_minus6_m; - n_e_minus6 = coeff_table[coeff_index].e_minus6_n; - p_e_minus2 = coeff_table[coeff_index].e_minus2_p; + if (data->tsensor_index == TSENSOR_INSTANCE1) + coeff_index = TSENSOR_COEFF_SET2; + data->m_e_minus6 = coeff_table[coeff_index].e_minus6_m; + data->n_e_minus6 = coeff_table[coeff_index].e_minus6_n; + data->p_e_minus2 = coeff_table[coeff_index].e_minus2_p; } /* tsensor counter read function */ @@ -361,7 +379,7 @@ static unsigned int tsensor_read_counter( } if (!(iter_count % 10)) dev_dbg(data->hwmon_dev, "retry %d\n", iter_count); - msleep(1); + msleep(21); iter_count++; } while (iter_count < max_loop); if (iter_count == max_loop) @@ -437,8 +455,8 @@ static ssize_t tsensor_show_counters(struct device *dev, "%s " "[%d]: current counter=0x%x, %d.%d" " deg Celsius ", fixed_str, - tsensor_index, - ((curr_avg[tsensor_index] & 0xFFFF0000) >> 16), + data->tsensor_index, + ((curr_avg[data->tsensor_index] & 0xFFFF0000) >> 16), get_temperature_int(temp1), get_temperature_fraction(temp1)); } @@ -468,30 +486,31 @@ static bool cclkg_check_hwdiv2_sensor(struct tegra_tsensor_data *data) * function with table to return register, field shift and mask * values for supported parameters */ -static int get_param_values(unsigned int indx, +static int get_param_values( + struct tegra_tsensor_data *data, unsigned int indx, unsigned int *p_reg, unsigned int *p_sft, unsigned int *p_msk) { switch (indx) { case TSENSOR_PARAM_TH1: - *p_reg = ((tsensor_index << 16) | SENSOR_CFG1); + *p_reg = ((data->tsensor_index << 16) | SENSOR_CFG1); *p_sft = SENSOR_CFG1_TH1_SHIFT; *p_msk = SENSOR_CFG_X_TH_X_MASK; snprintf(my_fixed_str, LOCAL_STR_SIZE1, "TH1[%d]: ", - tsensor_index); + data->tsensor_index); break; case TSENSOR_PARAM_TH2: - *p_reg = ((tsensor_index << 16) | SENSOR_CFG1); + *p_reg = ((data->tsensor_index << 16) | SENSOR_CFG1); *p_sft = SENSOR_CFG1_TH2_SHIFT; *p_msk = SENSOR_CFG_X_TH_X_MASK; snprintf(my_fixed_str, LOCAL_STR_SIZE1, "TH2[%d]: ", - tsensor_index); + data->tsensor_index); break; case TSENSOR_PARAM_TH3: - *p_reg = ((tsensor_index << 16) | SENSOR_CFG2); + *p_reg = ((data->tsensor_index << 16) | SENSOR_CFG2); *p_sft = SENSOR_CFG2_TH3_SHIFT; *p_msk = SENSOR_CFG_X_TH_X_MASK; snprintf(my_fixed_str, LOCAL_STR_SIZE1, "TH3[%d]: ", - tsensor_index); + data->tsensor_index); break; default: return -ENOENT; @@ -513,7 +532,7 @@ static ssize_t show_tsensor_param(struct device *dev, int err; int temp; - err = get_param_values(attr->index, ®, &sft, &msk); + err = get_param_values(data, attr->index, ®, &sft, &msk); if (err < 0) goto labelErr; val = tsensor_get_reg_field(data, reg, sft, msk); @@ -560,7 +579,7 @@ static ssize_t set_tsensor_param(struct device *dev, counter = tsensor_get_threshold_counter(data, num); - err = get_param_values(attr->index, ®, &sft, &msk); + err = get_param_values(data, attr->index, ®, &sft, &msk); if (err < 0) goto labelErr; @@ -570,7 +589,7 @@ static ssize_t set_tsensor_param(struct device *dev, /* TH2 clk divide check */ if (attr->index == TSENSOR_PARAM_TH2) { - msleep(20); + msleep(21); (void)cclkg_check_hwdiv2_sensor(data); } val = tsensor_get_reg_field(data, reg, sft, msk); @@ -669,8 +688,8 @@ static int read_tsensor_fuse_regs(struct tegra_tsensor_data *data) err = tegra_fuse_get_tsensor_calibration_data(®1); if (err) goto errLabel; - fuse_F1 = reg1 & 0xFFFF; - fuse_F2 = (reg1 >> 16) & 0xFFFF; + data->fuse_F1 = reg1 & 0xFFFF; + data->fuse_F2 = (reg1 >> 16) & 0xFFFF; err = tegra_fuse_get_tsensor_spare_bits(&spare_bits); if (err) { @@ -697,9 +716,9 @@ static int read_tsensor_fuse_regs(struct tegra_tsensor_data *data) dev_vdbg(data->hwmon_dev, "Tsensor low temp (T2) fuse :\n"); T2 = (spare_bits & 0x7F) | ((spare_bits >> 7) & 0x7F); pr_info("Tsensor fuse calibration F1=%d, F2=%d, T1=%d, T2=%d\n" - , fuse_F1, fuse_F2, T1, T2); - fuse_T1 = T1; - fuse_T2 = T2; + , data->fuse_F1, data->fuse_F2, T1, T2); + data->fuse_T1 = T1; + data->fuse_T2 = T2; return 0; errLabel: return err; @@ -714,20 +733,22 @@ static int calc_interim_temp(struct tegra_tsensor_data *data, * T-int = A * Counter + B * (Counter is the sensor frequency output) */ - if ((fuse_F2 - fuse_F1) <= (fuse_T2 - fuse_T1)) { + if ((data->fuse_F2 - data->fuse_F1) <= (data->fuse_T2 - + data->fuse_T1)) { dev_err(data->hwmon_dev, "Error: F2=%d, F1=%d " "difference unexpectedly low. " - "Aborting temperature processing\n", fuse_F2, fuse_F1); + "Aborting temperature processing\n", data->fuse_F2, + data->fuse_F1); return -EINVAL; } else { /* expression modified after assuming s_A is 10^6 times, * s_B is 10^2 times and want end result to be 10^2 times * actual value */ - val1 = DIV_ROUND_CLOSEST((A_e_minus6 * counter) , 10000); + val1 = DIV_ROUND_CLOSEST((data->A_e_minus6 * counter) , 10000); dev_vdbg(data->hwmon_dev, "A*counter / 100 = %d\n", val1); - *p_interim_temp = (val1 + B_e_minus2); + *p_interim_temp = (val1 + data->B_e_minus2); } dev_dbg(data->hwmon_dev, "tsensor: counter=0x%x, interim " "temp*100=%d\n", @@ -753,7 +774,7 @@ static void calc_final_temp(struct tegra_tsensor_data *data, dev_vdbg(data->hwmon_dev, "interim_temp=%d\n", interim_temp); temp1 = (DIV_ROUND_CLOSEST((interim_temp * interim_temp) , 100)); dev_vdbg(data->hwmon_dev, "temp1=%d\n", temp1); - temp1 *= (DIV_ROUND_CLOSEST(m_e_minus6 , 10)); + temp1 *= (DIV_ROUND_CLOSEST(data->m_e_minus6 , 10)); dev_vdbg(data->hwmon_dev, "m*T-int^2=%d\n", temp1); temp1 = (DIV_ROUND_CLOSEST(temp1, 10000)); /* we want to keep 3 decimal point digits */ @@ -761,13 +782,13 @@ static void calc_final_temp(struct tegra_tsensor_data *data, dev_dbg(data->hwmon_dev, "temp1*100=%d\n", temp1); temp2 = (DIV_ROUND_CLOSEST(interim_temp * ( - DIV_ROUND_CLOSEST(n_e_minus6, 100) + DIV_ROUND_CLOSEST(data->n_e_minus6, 100) ), 1000)); /* 1000 times actual */ dev_vdbg(data->hwmon_dev, "n*T-int =%d\n", temp2); temp = temp1 + temp2; dev_vdbg(data->hwmon_dev, "m*T-int^2 + n*T-int =%d\n", temp); - temp += (p_e_minus2 * 10); + temp += (data->p_e_minus2 * 10); temp = DIV_ROUND_CLOSEST(temp, 10); /* final temperature(temp) is 100 times actual value * to preserve 2 decimal digits and enable fixed point @@ -800,24 +821,26 @@ static int tsensor_get_const_AB(struct tegra_tsensor_data *data) return err; } - if (fuse_F2 != fuse_F1) { - if ((fuse_F2 - fuse_F1) <= (fuse_T2 - fuse_T1)) { + if (data->fuse_F2 != data->fuse_F1) { + if ((data->fuse_F2 - data->fuse_F1) <= (data->fuse_T2 - + data->fuse_T1)) { dev_err(data->hwmon_dev, "Error: F2=%d, " "F1=%d, difference" " unexpectedly low. Aborting temperature" - "computation\n", fuse_F2, fuse_F1); + "computation\n", data->fuse_F2, data->fuse_F1); return -EINVAL; } else { - A_e_minus6 = ((fuse_T2 - fuse_T1) * 1000000); - A_e_minus6 /= (fuse_F2 - fuse_F1); - B_e_minus2 = (fuse_T1 * 100) - ( - DIV_ROUND_CLOSEST((A_e_minus6 * - fuse_F1), 10000)); + data->A_e_minus6 = ((data->fuse_T2 - data->fuse_T1) * + 1000000); + data->A_e_minus6 /= (data->fuse_F2 - data->fuse_F1); + data->B_e_minus2 = (data->fuse_T1 * 100) - ( + DIV_ROUND_CLOSEST((data->A_e_minus6 * + data->fuse_F1), 10000)); /* B is 100 times now */ } } - dev_dbg(data->hwmon_dev, "A_e_minus6 = %d\n", A_e_minus6); - dev_dbg(data->hwmon_dev, "B_e_minus2 = %d\n", B_e_minus2); + dev_dbg(data->hwmon_dev, "A_e_minus6 = %d\n", data->A_e_minus6); + dev_dbg(data->hwmon_dev, "B_e_minus2 = %d\n", data->B_e_minus2); return 0; } @@ -899,33 +922,33 @@ static void get_quadratic_roots(struct tegra_tsensor_data *data, dev_vdbg(data->hwmon_dev, "A_e_minus6=%d, B_e_minus2=%d, " "m_e_minus6=%d, n_e_minus6=%d, p_e_minus2=%d, " - "temp=%d\n", A_e_minus6, B_e_minus2, m_e_minus6, - n_e_minus6, p_e_minus2, (int)temp); - expr1_e_minus6 = (DIV_ROUND_CLOSEST((2 * m_e_minus6 * B_e_minus2), - 100) + n_e_minus6); + "temp=%d\n", data->A_e_minus6, data->B_e_minus2, + data->m_e_minus6, + data->n_e_minus6, data->p_e_minus2, (int)temp); + expr1_e_minus6 = (DIV_ROUND_CLOSEST((2 * data->m_e_minus6 * + data->B_e_minus2), 100) + data->n_e_minus6); dev_vdbg(data->hwmon_dev, "2_m_B_plun_e_minus6=%d\n", expr1_e_minus6); expr2_e_minus6 = (DIV_ROUND_CLOSEST(expr1_e_minus6, 1000)) * (DIV_ROUND_CLOSEST(expr1_e_minus6, 1000)); dev_vdbg(data->hwmon_dev, "expr1^2=%d\n", expr2_e_minus6); expr3_e_minus4_1 = (DIV_ROUND_CLOSEST(( - (DIV_ROUND_CLOSEST((m_e_minus6 * B_e_minus2), 1000)) * - (DIV_ROUND_CLOSEST(B_e_minus2, 10)) - ), 100)); + (DIV_ROUND_CLOSEST((data->m_e_minus6 * data->B_e_minus2), + 1000)) * (DIV_ROUND_CLOSEST(data->B_e_minus2, 10))), 100)); dev_vdbg(data->hwmon_dev, "expr3_e_minus4_1=%d\n", expr3_e_minus4_1); expr3_e_minus4_2 = DIV_ROUND_CLOSEST( - (DIV_ROUND_CLOSEST(n_e_minus6, 100) * B_e_minus2), + (DIV_ROUND_CLOSEST(data->n_e_minus6, 100) * data->B_e_minus2), 100); dev_vdbg(data->hwmon_dev, "expr3_e_minus4_2=%d\n", expr3_e_minus4_2); expr3_e_minus4 = expr3_e_minus4_1 + expr3_e_minus4_2; dev_vdbg(data->hwmon_dev, "expr3=%d\n", expr3_e_minus4); expr4_e_minus2_1 = DIV_ROUND_CLOSEST((expr3_e_minus4 + - (p_e_minus2 * 100)), 100); + (data->p_e_minus2 * 100)), 100); dev_vdbg(data->hwmon_dev, "expr4_e_minus2_1=%d\n", expr4_e_minus2_1); - expr4_e_minus6_2 = (4 * m_e_minus6); + expr4_e_minus6_2 = (4 * data->m_e_minus6); dev_vdbg(data->hwmon_dev, "expr4_e_minus6_2=%d\n", expr4_e_minus6_2); expr4_e_minus6 = DIV_ROUND_CLOSEST((expr4_e_minus2_1 * @@ -956,8 +979,8 @@ static void get_quadratic_roots(struct tegra_tsensor_data *data, dev_vdbg(data->hwmon_dev, "sqrt final=%d\n", expr8_e_minus6); dev_vdbg(data->hwmon_dev, "2_m_B_plus_n_e_minus6=%d\n", expr1_e_minus6); - expr9_e_minus6 = DIV_ROUND_CLOSEST((2 * m_e_minus6 * A_e_minus6), - 1000000); + expr9_e_minus6 = DIV_ROUND_CLOSEST((2 * data->m_e_minus6 * + data->A_e_minus6), 1000000); dev_vdbg(data->hwmon_dev, "denominator=%d\n", expr9_e_minus6); if (expr9_e_minus6 == 0) { pr_err("Error: %s line=%d, expr9_e_minus6=%d\n", @@ -1125,7 +1148,8 @@ static int test_temperature_algo(struct tegra_tsensor_data *data) bool result = false; /* read actual counter */ - err = tsensor_read_counter(data, tsensor_index, &curr_avg, &min_max); + err = tsensor_read_counter(data, data->tsensor_index, &curr_avg, + &min_max); if (err < 0) { pr_err("Error: tsensor0 counter read, err=%d\n", err); goto endLabel; @@ -1188,7 +1212,8 @@ static unsigned int tsensor_get_threshold_counter( if (temp_threshold < 0) return MAX_THRESHOLD; tsensor_temp_2_count(data, temp_threshold, &counter1, &counter2); - err = tsensor_read_counter(data, tsensor_index, &curr_avg, &min_max); + err = tsensor_read_counter(data, data->tsensor_index, &curr_avg, + &min_max); if (err < 0) { pr_err("Error: tsensor0 counter read, err=%d\n", err); return MAX_THRESHOLD; @@ -1224,7 +1249,7 @@ static void tsensor_threshold_setup( /* Choose thresholds for sensor0 and sensor1 */ /* set to very high values initially - DEFAULT_THRESHOLD */ - if ((!is_default_threshold) && (i == tsensor_index)) { + if ((!is_default_threshold) && (i == data->tsensor_index)) { dev_dbg(data->hwmon_dev, "before div2 temp_2_count\n"); th2_count = tsensor_get_threshold_counter(data, data->div2_temp); @@ -1339,7 +1364,7 @@ static int tsensor_config_setup(struct tegra_tsensor_data *data) SENSOR_STATUS_AVG_VALID_SHIFT)) && (status_reg & (1 << SENSOR_STATUS_CURR_VALID_SHIFT))) { - msleep(1); + msleep(21); loop_count++; if (!(loop_count % 200)) dev_err(data->hwmon_dev, @@ -1364,7 +1389,7 @@ static int tsensor_config_setup(struct tegra_tsensor_data *data) data->ts_state_saved[i] = curr_state.state; } /* initialize tsensor chip coefficients */ - get_chip_tsensor_coeff(); + get_chip_tsensor_coeff(data); skip_all: return err; } @@ -1430,9 +1455,9 @@ static int tegra_tsensor_setup(struct platform_device *pdev) /* Reset tsensor */ dev_dbg(&pdev->dev, "before tsensor reset %s\n", __func__); tegra_periph_reset_assert(data->dev_clk); - msleep(1); + udelay(100); tegra_periph_reset_deassert(data->dev_clk); - msleep(1); + udelay(100); dev_dbg(&pdev->dev, "before tsensor chk pmc reset %s\n", __func__); @@ -1517,7 +1542,7 @@ static int tegra_tsensor_setup(struct platform_device *pdev) dev_dbg(&pdev->dev, "before tsensor_threshold_setup\n"); /* change tsensor threshold for active instance */ - tsensor_threshold_setup(data, tsensor_index, false); + tsensor_threshold_setup(data, data->tsensor_index, false); dev_dbg(&pdev->dev, "end tsensor_threshold_setup\n"); return 0; @@ -1631,13 +1656,13 @@ static int __devinit tegra_tsensor_probe(struct platform_device *pdev) /* instance 0 is used for fuse revision TSENSOR_FUSE_REVISION_DECIMAL_REV2 onwards */ if (reg >= TSENSOR_FUSE_REVISION_DECIMAL_REV2) - tsensor_index = 0; + data->tsensor_index = 0; /* instance 1 is used for fuse revision TSENSOR_FUSE_REVISION_DECIMAL_REV1 till TSENSOR_FUSE_REVISION_DECIMAL_REV2 */ else if (reg >= TSENSOR_FUSE_REVISION_DECIMAL_REV1) - tsensor_index = 1; - pr_info("tsensor active instance=%d\n", tsensor_index); + data->tsensor_index = 1; + pr_info("tsensor active instance=%d\n", data->tsensor_index); /* tegra tsensor - setup and init */ err = tegra_tsensor_setup(pdev); |