hal_thermal.c 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. #include <stdint.h>
  2. #include <stdio.h>
  3. #include <hal_cmd.h>
  4. #include <hal_timer.h>
  5. #include <sunxi_hal_thermal.h>
  6. #include <sunxi_hal_common.h>
  7. #include <hal_log.h>
  8. #if 0
  9. #define THS_DBG(fmt,arg...) printf("THS:" fmt, ##arg)
  10. #else
  11. #define THS_DBG(fmt,arg...) do{}while(0)
  12. #endif
  13. extern int hal_efuse_get_thermal_cdata(unsigned char *buffer);
  14. /* Temp Unit: millidegree Celsius */
  15. static int hal_ths_reg2temp(int reg)
  16. {
  17. THS_DBG("OFFSET:%d[0x%x], SCALE:%d[0x%x], reg:%d[0x%x]\n", OFFSET, OFFSET, SCALE, SCALE, reg, reg);
  18. return (reg + OFFSET) * SCALE;
  19. }
  20. static void hal_ths_calibrate(short int *buf, unsigned int len)
  21. {
  22. unsigned int i;
  23. int ft_temp;
  24. if (!buf[0] || len < 2 + 2 * THS_NUM)
  25. return;
  26. ft_temp = buf[0] & FT_TEMP_MASK;
  27. for (i = 0; i < THS_NUM; i++) {
  28. int reg = (int)buf[i + 1];
  29. int sensor_temp = hal_ths_reg2temp(reg);
  30. int delta, cdata, calib_offest;
  31. /*
  32. * To calculate the calibration value:
  33. *
  34. * X(in Celsius) = Ts - ft_temp
  35. * delta = X * 10000 / TEMP_TO_REG
  36. * cdata = CALIBRATE_DEFAULT - delta
  37. *
  38. * cdata: calibration value
  39. */
  40. delta = (sensor_temp - ft_temp * 100) * 10 / TEMP_TO_REG;
  41. cdata = CALIBRATE_DEFAULT - delta;
  42. THS_DBG("sensor_temp:%d[0x%x], ft_temp:%d[0x%x], TEMP_TO_REG:%d[0x%x],"
  43. "delta:%d[0x%x], CALIBRATE_DEFAULT:%d[0x%x], cdata:%d[0x%x]\n",
  44. sensor_temp, sensor_temp, ft_temp, ft_temp, TEMP_TO_REG, TEMP_TO_REG,
  45. delta, delta, CALIBRATE_DEFAULT, CALIBRATE_DEFAULT, cdata, cdata);
  46. if (cdata & ~TEMP_CALIB_MASK) {
  47. /*
  48. * Calibration value more than 12-bit, but calibration
  49. * register is 12-bit. In this case, ths hardware can
  50. * still work without calibration, although the data
  51. * won't be so accurate.
  52. */
  53. continue;
  54. }
  55. calib_offest = THS_CALIB + (i / 2) * 0x4;
  56. THS_DBG("calib_offest:%d[0x%x], THS_CALIB:%d[0x%x]\n", calib_offest, calib_offest, THS_CALIB, THS_CALIB);
  57. if (i % 2) {
  58. hal_writel((hal_readl((unsigned long)THS_CALIB) & TEMP_CALIB_MASK) | (cdata << 16), (unsigned long)calib_offest);
  59. } else {
  60. hal_writel(cdata, (unsigned long)calib_offest);
  61. }
  62. }
  63. }
  64. int hal_ths_init(void)
  65. {
  66. int ret = 0;
  67. char buffer[8] = {0};
  68. //TODO: clk init
  69. hal_writel(0x10001, (unsigned long)0x020019fc);
  70. /*
  71. * clkin = 24MHz
  72. * T acquire = clkin / (x + 1)
  73. * = 20us
  74. */
  75. hal_log_err("0x%x, 0x%x, 0x%x, 0x%x", THS_EN, THS_CTL, THS_MFC, THS_PCTL);
  76. hal_writel(THS_CTRL_T_ACQ(479), (unsigned long)THS_CTL);
  77. /* average over 4 samples */
  78. hal_writel(THS_FILTER_EN | THS_FILTER_TYPE(1), (unsigned long)THS_MFC);
  79. /* period = (x + 1) * 4096 / clkin; ~10ms */
  80. hal_writel(THS_PC_TEMP_PERIOD(58), (unsigned long)THS_PCTL);
  81. /* enable sensor */
  82. hal_writel(THS_NUM, (unsigned long)THS_EN);
  83. ret = hal_efuse_get_thermal_cdata(buffer);
  84. if (ret < 0) {
  85. printf("get thermal calibration data failed.\n");
  86. return ret;
  87. }
  88. hal_ths_calibrate((short int *)buffer, 8);
  89. return ret ;
  90. }
  91. int hal_ths_uninit(void)
  92. {
  93. hal_writel(0x0, (unsigned long)0x020019fc);
  94. return 0;
  95. }
  96. int hal_ths_get_temp(unsigned int num, int *temp)
  97. {
  98. uint32_t val;
  99. val = hal_readl((unsigned long)THS_DATA + 0x4 * num);
  100. THS_DBG("num:%d[0x%x], val:%d[0x%x]\n", num, num, val, val);
  101. /* ths have no data yet */
  102. if (!val)
  103. return -1;
  104. *temp = hal_ths_reg2temp(val);
  105. return 0;
  106. }