aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorZhang Rui <rui.zhang@intel.com>2017-01-17 02:51:21 -0500
committerZhang Rui <rui.zhang@intel.com>2017-01-17 02:51:21 -0500
commit6c75a5d1131eba90fcf04adc586167e65afc79b0 (patch)
treef8614b9fd8f9662c39c7673e6578d271c85834e7
parent0c744ea4f77d72b3dcebb7a8f2684633ec79be88 (diff)
parentdb8318865e2c04dbe3d95089c7215b94a5b879b7 (diff)
Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/evalenti/linux-soc-thermal into thermal-soc
-rw-r--r--drivers/thermal/rockchip_thermal.c153
1 files changed, 100 insertions, 53 deletions
diff --git a/drivers/thermal/rockchip_thermal.c b/drivers/thermal/rockchip_thermal.c
index b811b0fb61b1..4c7796512453 100644
--- a/drivers/thermal/rockchip_thermal.c
+++ b/drivers/thermal/rockchip_thermal.c
@@ -118,12 +118,12 @@ struct rockchip_tsadc_chip {
118 void (*control)(void __iomem *reg, bool on); 118 void (*control)(void __iomem *reg, bool on);
119 119
120 /* Per-sensor methods */ 120 /* Per-sensor methods */
121 int (*get_temp)(struct chip_tsadc_table table, 121 int (*get_temp)(const struct chip_tsadc_table *table,
122 int chn, void __iomem *reg, int *temp); 122 int chn, void __iomem *reg, int *temp);
123 void (*set_alarm_temp)(struct chip_tsadc_table table, 123 int (*set_alarm_temp)(const struct chip_tsadc_table *table,
124 int chn, void __iomem *reg, int temp); 124 int chn, void __iomem *reg, int temp);
125 void (*set_tshut_temp)(struct chip_tsadc_table table, 125 int (*set_tshut_temp)(const struct chip_tsadc_table *table,
126 int chn, void __iomem *reg, int temp); 126 int chn, void __iomem *reg, int temp);
127 void (*set_tshut_mode)(int chn, void __iomem *reg, enum tshut_mode m); 127 void (*set_tshut_mode)(int chn, void __iomem *reg, enum tshut_mode m);
128 128
129 /* Per-table methods */ 129 /* Per-table methods */
@@ -317,6 +317,7 @@ static const struct tsadc_table rk3288_code_table[] = {
317 {3452, 115000}, 317 {3452, 115000},
318 {3437, 120000}, 318 {3437, 120000},
319 {3421, 125000}, 319 {3421, 125000},
320 {0, 125000},
320}; 321};
321 322
322static const struct tsadc_table rk3368_code_table[] = { 323static const struct tsadc_table rk3368_code_table[] = {
@@ -397,59 +398,80 @@ static const struct tsadc_table rk3399_code_table[] = {
397 {TSADCV3_DATA_MASK, 125000}, 398 {TSADCV3_DATA_MASK, 125000},
398}; 399};
399 400
400static u32 rk_tsadcv2_temp_to_code(struct chip_tsadc_table table, 401static u32 rk_tsadcv2_temp_to_code(const struct chip_tsadc_table *table,
401 int temp) 402 int temp)
402{ 403{
403 int high, low, mid; 404 int high, low, mid;
404 u32 error = 0; 405 unsigned long num;
406 unsigned int denom;
407 u32 error = table->data_mask;
405 408
406 low = 0; 409 low = 0;
407 high = table.length - 1; 410 high = (table->length - 1) - 1; /* ignore the last check for table */
408 mid = (high + low) / 2; 411 mid = (high + low) / 2;
409 412
410 /* Return mask code data when the temp is over table range */ 413 /* Return mask code data when the temp is over table range */
411 if (temp < table.id[low].temp || temp > table.id[high].temp) { 414 if (temp < table->id[low].temp || temp > table->id[high].temp)
412 error = table.data_mask;
413 goto exit; 415 goto exit;
414 }
415 416
416 while (low <= high) { 417 while (low <= high) {
417 if (temp == table.id[mid].temp) 418 if (temp == table->id[mid].temp)
418 return table.id[mid].code; 419 return table->id[mid].code;
419 else if (temp < table.id[mid].temp) 420 else if (temp < table->id[mid].temp)
420 high = mid - 1; 421 high = mid - 1;
421 else 422 else
422 low = mid + 1; 423 low = mid + 1;
423 mid = (low + high) / 2; 424 mid = (low + high) / 2;
424 } 425 }
425 426
427 /*
428 * The conversion code granularity provided by the table. Let's
429 * assume that the relationship between temperature and
430 * analog value between 2 table entries is linear and interpolate
431 * to produce less granular result.
432 */
433 num = abs(table->id[mid + 1].code - table->id[mid].code);
434 num *= temp - table->id[mid].temp;
435 denom = table->id[mid + 1].temp - table->id[mid].temp;
436
437 switch (table->mode) {
438 case ADC_DECREMENT:
439 return table->id[mid].code - (num / denom);
440 case ADC_INCREMENT:
441 return table->id[mid].code + (num / denom);
442 default:
443 pr_err("%s: unknown table mode: %d\n", __func__, table->mode);
444 return error;
445 }
446
426exit: 447exit:
427 pr_err("Invalid the conversion, error=%d\n", error); 448 pr_err("%s: invalid temperature, temp=%d error=%d\n",
449 __func__, temp, error);
428 return error; 450 return error;
429} 451}
430 452
431static int rk_tsadcv2_code_to_temp(struct chip_tsadc_table table, u32 code, 453static int rk_tsadcv2_code_to_temp(const struct chip_tsadc_table *table,
432 int *temp) 454 u32 code, int *temp)
433{ 455{
434 unsigned int low = 1; 456 unsigned int low = 1;
435 unsigned int high = table.length - 1; 457 unsigned int high = table->length - 1;
436 unsigned int mid = (low + high) / 2; 458 unsigned int mid = (low + high) / 2;
437 unsigned int num; 459 unsigned int num;
438 unsigned long denom; 460 unsigned long denom;
439 461
440 WARN_ON(table.length < 2); 462 WARN_ON(table->length < 2);
441 463
442 switch (table.mode) { 464 switch (table->mode) {
443 case ADC_DECREMENT: 465 case ADC_DECREMENT:
444 code &= table.data_mask; 466 code &= table->data_mask;
445 if (code < table.id[high].code) 467 if (code <= table->id[high].code)
446 return -EAGAIN; /* Incorrect reading */ 468 return -EAGAIN; /* Incorrect reading */
447 469
448 while (low <= high) { 470 while (low <= high) {
449 if (code >= table.id[mid].code && 471 if (code >= table->id[mid].code &&
450 code < table.id[mid - 1].code) 472 code < table->id[mid - 1].code)
451 break; 473 break;
452 else if (code < table.id[mid].code) 474 else if (code < table->id[mid].code)
453 low = mid + 1; 475 low = mid + 1;
454 else 476 else
455 high = mid - 1; 477 high = mid - 1;
@@ -458,15 +480,15 @@ static int rk_tsadcv2_code_to_temp(struct chip_tsadc_table table, u32 code,
458 } 480 }
459 break; 481 break;
460 case ADC_INCREMENT: 482 case ADC_INCREMENT:
461 code &= table.data_mask; 483 code &= table->data_mask;
462 if (code < table.id[low].code) 484 if (code < table->id[low].code)
463 return -EAGAIN; /* Incorrect reading */ 485 return -EAGAIN; /* Incorrect reading */
464 486
465 while (low <= high) { 487 while (low <= high) {
466 if (code <= table.id[mid].code && 488 if (code <= table->id[mid].code &&
467 code > table.id[mid - 1].code) 489 code > table->id[mid - 1].code)
468 break; 490 break;
469 else if (code > table.id[mid].code) 491 else if (code > table->id[mid].code)
470 low = mid + 1; 492 low = mid + 1;
471 else 493 else
472 high = mid - 1; 494 high = mid - 1;
@@ -475,7 +497,8 @@ static int rk_tsadcv2_code_to_temp(struct chip_tsadc_table table, u32 code,
475 } 497 }
476 break; 498 break;
477 default: 499 default:
478 pr_err("Invalid the conversion table\n"); 500 pr_err("%s: unknown table mode: %d\n", __func__, table->mode);
501 return -EINVAL;
479 } 502 }
480 503
481 /* 504 /*
@@ -484,10 +507,10 @@ static int rk_tsadcv2_code_to_temp(struct chip_tsadc_table table, u32 code,
484 * temperature between 2 table entries is linear and interpolate 507 * temperature between 2 table entries is linear and interpolate
485 * to produce less granular result. 508 * to produce less granular result.
486 */ 509 */
487 num = table.id[mid].temp - table.id[mid - 1].temp; 510 num = table->id[mid].temp - table->id[mid - 1].temp;
488 num *= abs(table.id[mid - 1].code - code); 511 num *= abs(table->id[mid - 1].code - code);
489 denom = abs(table.id[mid - 1].code - table.id[mid].code); 512 denom = abs(table->id[mid - 1].code - table->id[mid].code);
490 *temp = table.id[mid - 1].temp + (num / denom); 513 *temp = table->id[mid - 1].temp + (num / denom);
491 514
492 return 0; 515 return 0;
493} 516}
@@ -638,7 +661,7 @@ static void rk_tsadcv3_control(void __iomem *regs, bool enable)
638 writel_relaxed(val, regs + TSADCV2_AUTO_CON); 661 writel_relaxed(val, regs + TSADCV2_AUTO_CON);
639} 662}
640 663
641static int rk_tsadcv2_get_temp(struct chip_tsadc_table table, 664static int rk_tsadcv2_get_temp(const struct chip_tsadc_table *table,
642 int chn, void __iomem *regs, int *temp) 665 int chn, void __iomem *regs, int *temp)
643{ 666{
644 u32 val; 667 u32 val;
@@ -648,39 +671,57 @@ static int rk_tsadcv2_get_temp(struct chip_tsadc_table table,
648 return rk_tsadcv2_code_to_temp(table, val, temp); 671 return rk_tsadcv2_code_to_temp(table, val, temp);
649} 672}
650 673
651static void rk_tsadcv2_alarm_temp(struct chip_tsadc_table table, 674static int rk_tsadcv2_alarm_temp(const struct chip_tsadc_table *table,
652 int chn, void __iomem *regs, int temp) 675 int chn, void __iomem *regs, int temp)
653{ 676{
654 u32 alarm_value, int_en; 677 u32 alarm_value;
678 u32 int_en, int_clr;
679
680 /*
681 * In some cases, some sensors didn't need the trip points, the
682 * set_trips will pass {-INT_MAX, INT_MAX} to trigger tsadc alarm
683 * in the end, ignore this case and disable the high temperature
684 * interrupt.
685 */
686 if (temp == INT_MAX) {
687 int_clr = readl_relaxed(regs + TSADCV2_INT_EN);
688 int_clr &= ~TSADCV2_INT_SRC_EN(chn);
689 writel_relaxed(int_clr, regs + TSADCV2_INT_EN);
690 return 0;
691 }
655 692
656 /* Make sure the value is valid */ 693 /* Make sure the value is valid */
657 alarm_value = rk_tsadcv2_temp_to_code(table, temp); 694 alarm_value = rk_tsadcv2_temp_to_code(table, temp);
658 if (alarm_value == table.data_mask) 695 if (alarm_value == table->data_mask)
659 return; 696 return -ERANGE;
660 697
661 writel_relaxed(alarm_value & table.data_mask, 698 writel_relaxed(alarm_value & table->data_mask,
662 regs + TSADCV2_COMP_INT(chn)); 699 regs + TSADCV2_COMP_INT(chn));
663 700
664 int_en = readl_relaxed(regs + TSADCV2_INT_EN); 701 int_en = readl_relaxed(regs + TSADCV2_INT_EN);
665 int_en |= TSADCV2_INT_SRC_EN(chn); 702 int_en |= TSADCV2_INT_SRC_EN(chn);
666 writel_relaxed(int_en, regs + TSADCV2_INT_EN); 703 writel_relaxed(int_en, regs + TSADCV2_INT_EN);
704
705 return 0;
667} 706}
668 707
669static void rk_tsadcv2_tshut_temp(struct chip_tsadc_table table, 708static int rk_tsadcv2_tshut_temp(const struct chip_tsadc_table *table,
670 int chn, void __iomem *regs, int temp) 709 int chn, void __iomem *regs, int temp)
671{ 710{
672 u32 tshut_value, val; 711 u32 tshut_value, val;
673 712
674 /* Make sure the value is valid */ 713 /* Make sure the value is valid */
675 tshut_value = rk_tsadcv2_temp_to_code(table, temp); 714 tshut_value = rk_tsadcv2_temp_to_code(table, temp);
676 if (tshut_value == table.data_mask) 715 if (tshut_value == table->data_mask)
677 return; 716 return -ERANGE;
678 717
679 writel_relaxed(tshut_value, regs + TSADCV2_COMP_SHUT(chn)); 718 writel_relaxed(tshut_value, regs + TSADCV2_COMP_SHUT(chn));
680 719
681 /* TSHUT will be valid */ 720 /* TSHUT will be valid */
682 val = readl_relaxed(regs + TSADCV2_AUTO_CON); 721 val = readl_relaxed(regs + TSADCV2_AUTO_CON);
683 writel_relaxed(val | TSADCV2_AUTO_SRC_EN(chn), regs + TSADCV2_AUTO_CON); 722 writel_relaxed(val | TSADCV2_AUTO_SRC_EN(chn), regs + TSADCV2_AUTO_CON);
723
724 return 0;
684} 725}
685 726
686static void rk_tsadcv2_tshut_mode(int chn, void __iomem *regs, 727static void rk_tsadcv2_tshut_mode(int chn, void __iomem *regs,
@@ -883,10 +924,8 @@ static int rockchip_thermal_set_trips(void *_sensor, int low, int high)
883 dev_dbg(&thermal->pdev->dev, "%s: sensor %d: low: %d, high %d\n", 924 dev_dbg(&thermal->pdev->dev, "%s: sensor %d: low: %d, high %d\n",
884 __func__, sensor->id, low, high); 925 __func__, sensor->id, low, high);
885 926
886 tsadc->set_alarm_temp(tsadc->table, 927 return tsadc->set_alarm_temp(&tsadc->table,
887 sensor->id, thermal->regs, high); 928 sensor->id, thermal->regs, high);
888
889 return 0;
890} 929}
891 930
892static int rockchip_thermal_get_temp(void *_sensor, int *out_temp) 931static int rockchip_thermal_get_temp(void *_sensor, int *out_temp)
@@ -896,7 +935,7 @@ static int rockchip_thermal_get_temp(void *_sensor, int *out_temp)
896 const struct rockchip_tsadc_chip *tsadc = sensor->thermal->chip; 935 const struct rockchip_tsadc_chip *tsadc = sensor->thermal->chip;
897 int retval; 936 int retval;
898 937
899 retval = tsadc->get_temp(tsadc->table, 938 retval = tsadc->get_temp(&tsadc->table,
900 sensor->id, thermal->regs, out_temp); 939 sensor->id, thermal->regs, out_temp);
901 dev_dbg(&thermal->pdev->dev, "sensor %d - temp: %d, retval: %d\n", 940 dev_dbg(&thermal->pdev->dev, "sensor %d - temp: %d, retval: %d\n",
902 sensor->id, *out_temp, retval); 941 sensor->id, *out_temp, retval);
@@ -982,8 +1021,12 @@ rockchip_thermal_register_sensor(struct platform_device *pdev,
982 int error; 1021 int error;
983 1022
984 tsadc->set_tshut_mode(id, thermal->regs, thermal->tshut_mode); 1023 tsadc->set_tshut_mode(id, thermal->regs, thermal->tshut_mode);
985 tsadc->set_tshut_temp(tsadc->table, id, thermal->regs, 1024
1025 error = tsadc->set_tshut_temp(&tsadc->table, id, thermal->regs,
986 thermal->tshut_temp); 1026 thermal->tshut_temp);
1027 if (error)
1028 dev_err(&pdev->dev, "%s: invalid tshut=%d, error=%d\n",
1029 __func__, thermal->tshut_temp, error);
987 1030
988 sensor->thermal = thermal; 1031 sensor->thermal = thermal;
989 sensor->id = id; 1032 sensor->id = id;
@@ -1196,9 +1239,13 @@ static int __maybe_unused rockchip_thermal_resume(struct device *dev)
1196 1239
1197 thermal->chip->set_tshut_mode(id, thermal->regs, 1240 thermal->chip->set_tshut_mode(id, thermal->regs,
1198 thermal->tshut_mode); 1241 thermal->tshut_mode);
1199 thermal->chip->set_tshut_temp(thermal->chip->table, 1242
1243 error = thermal->chip->set_tshut_temp(&thermal->chip->table,
1200 id, thermal->regs, 1244 id, thermal->regs,
1201 thermal->tshut_temp); 1245 thermal->tshut_temp);
1246 if (error)
1247 dev_err(&pdev->dev, "%s: invalid tshut=%d, error=%d\n",
1248 __func__, thermal->tshut_temp, error);
1202 } 1249 }
1203 1250
1204 thermal->chip->control(thermal->regs, true); 1251 thermal->chip->control(thermal->regs, true);