| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137 |
- #include <stdint.h>
- #include <stdio.h>
- #include <hal_cmd.h>
- #include <hal_timer.h>
- #include <sunxi_hal_thermal.h>
- #include <sunxi_hal_common.h>
- #include <hal_log.h>
- #if 0
- #define THS_DBG(fmt,arg...) printf("THS:" fmt, ##arg)
- #else
- #define THS_DBG(fmt,arg...) do{}while(0)
- #endif
- extern int hal_efuse_get_thermal_cdata(unsigned char *buffer);
- /* Temp Unit: millidegree Celsius */
- static int hal_ths_reg2temp(int reg)
- {
- THS_DBG("OFFSET:%d[0x%x], SCALE:%d[0x%x], reg:%d[0x%x]\n", OFFSET, OFFSET, SCALE, SCALE, reg, reg);
- return (reg + OFFSET) * SCALE;
- }
- static void hal_ths_calibrate(short int *buf, unsigned int len)
- {
- unsigned int i;
- int ft_temp;
- if (!buf[0] || len < 2 + 2 * THS_NUM)
- return;
- ft_temp = buf[0] & FT_TEMP_MASK;
- for (i = 0; i < THS_NUM; i++) {
- int reg = (int)buf[i + 1];
- int sensor_temp = hal_ths_reg2temp(reg);
- int delta, cdata, calib_offest;
- /*
- * To calculate the calibration value:
- *
- * X(in Celsius) = Ts - ft_temp
- * delta = X * 10000 / TEMP_TO_REG
- * cdata = CALIBRATE_DEFAULT - delta
- *
- * cdata: calibration value
- */
- delta = (sensor_temp - ft_temp * 100) * 10 / TEMP_TO_REG;
- cdata = CALIBRATE_DEFAULT - delta;
- THS_DBG("sensor_temp:%d[0x%x], ft_temp:%d[0x%x], TEMP_TO_REG:%d[0x%x],"
- "delta:%d[0x%x], CALIBRATE_DEFAULT:%d[0x%x], cdata:%d[0x%x]\n",
- sensor_temp, sensor_temp, ft_temp, ft_temp, TEMP_TO_REG, TEMP_TO_REG,
- delta, delta, CALIBRATE_DEFAULT, CALIBRATE_DEFAULT, cdata, cdata);
- if (cdata & ~TEMP_CALIB_MASK) {
- /*
- * Calibration value more than 12-bit, but calibration
- * register is 12-bit. In this case, ths hardware can
- * still work without calibration, although the data
- * won't be so accurate.
- */
- continue;
- }
- calib_offest = THS_CALIB + (i / 2) * 0x4;
- THS_DBG("calib_offest:%d[0x%x], THS_CALIB:%d[0x%x]\n", calib_offest, calib_offest, THS_CALIB, THS_CALIB);
- if (i % 2) {
- hal_writel((hal_readl((unsigned long)THS_CALIB) & TEMP_CALIB_MASK) | (cdata << 16), (unsigned long)calib_offest);
- } else {
- hal_writel(cdata, (unsigned long)calib_offest);
- }
- }
- }
- int hal_ths_init(void)
- {
- int ret = 0;
- char buffer[8] = {0};
- //TODO: clk init
- hal_writel(0x10001, (unsigned long)0x020019fc);
- /*
- * clkin = 24MHz
- * T acquire = clkin / (x + 1)
- * = 20us
- */
- hal_log_err("0x%x, 0x%x, 0x%x, 0x%x", THS_EN, THS_CTL, THS_MFC, THS_PCTL);
- hal_writel(THS_CTRL_T_ACQ(479), (unsigned long)THS_CTL);
- /* average over 4 samples */
- hal_writel(THS_FILTER_EN | THS_FILTER_TYPE(1), (unsigned long)THS_MFC);
- /* period = (x + 1) * 4096 / clkin; ~10ms */
- hal_writel(THS_PC_TEMP_PERIOD(58), (unsigned long)THS_PCTL);
- /* enable sensor */
- hal_writel(THS_NUM, (unsigned long)THS_EN);
- ret = hal_efuse_get_thermal_cdata(buffer);
- if (ret < 0) {
- printf("get thermal calibration data failed.\n");
- return ret;
- }
- hal_ths_calibrate((short int *)buffer, 8);
- return ret ;
- }
- int hal_ths_uninit(void)
- {
- hal_writel(0x0, (unsigned long)0x020019fc);
- return 0;
- }
- int hal_ths_get_temp(unsigned int num, int *temp)
- {
- uint32_t val;
- val = hal_readl((unsigned long)THS_DATA + 0x4 * num);
- THS_DBG("num:%d[0x%x], val:%d[0x%x]\n", num, num, val, val);
- /* ths have no data yet */
- if (!val)
- return -1;
- *temp = hal_ths_reg2temp(val);
- return 0;
- }
|