2 * Copyright (C) 2012 Spreadtrum Communications Inc.
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
15 #include <asm/arch/sprd_reg.h>
16 #include <asm/arch/adi.h>
17 #include "asm/arch/efuse_drv.h"
20 #define REG32(x) (*((volatile uint32 *)(x)))
23 static inline void efuse_udelay(unsigned long usec)
26 for (i = 0; i < (usec << 1); i++);
29 //static void __iomem *ctl_efuse_base = 0;
30 void sci_efuse_poweron(void)
33 /* enable efuse clock */
34 REG32(REG_AON_APB_APB_EB0) |= BIT_EFUSE_EB;
37 REG32(REG_AON_APB_APB_RST0) |= BIT_EFUSE_SOFT_RST;
38 for(i = 0; i < 100; i++);
39 REG32(REG_AON_APB_APB_RST0) &= ~BIT_EFUSE_SOFT_RST;
42 REG32(EFUSE_PGM_PARA) |= BIT_EFS_VDD_ON;
43 REG32(EFUSE_PGM_PARA) |= BIT_CLK_EFS_EN;
46 void sci_efuse_poweroff(void)
48 REG32(EFUSE_PGM_PARA) &= ~BIT_CLK_EFS_EN;
49 REG32(EFUSE_PGM_PARA) &= ~BIT_EFS_VDD_ON;
50 REG32(REG_AON_APB_APB_EB0) &= ~BIT_EFUSE_EB;
53 int sci_efuse_read(unsigned blk)
57 if (blk > (MASK_READ_INDEX >> SHIFT_READ_INDEX))
62 REG32(EFUSE_BLOCK_INDEX) = BITS_READ_INDEX(blk);
63 REG32(EFUSE_MODE_CTRL) |= BIT_RD_START;
67 busy = REG32(EFUSE_STATUS) & BIT_READ_BUSY;
70 return REG32(EFUSE_DATA_RD);
74 #define EFUSE_MAGIC_VAL 0x8810
75 int sci_efuse_program(unsigned blk, int data)
79 if (blk > (MASK_PGM_INDEX >> SHIFT_PGM_INDEX))
84 REG32(EFUSE_BLOCK_INDEX) = BITS_PGM_INDEX(blk);
85 REG32(EFUSE_DATA_WR) = data;
86 REG32(EFUSE_MODE_CTRL) |= BIT_PG_START;
90 busy = REG32(EFUSE_STATUS) & BIT_PGM_BUSY;
97 int sci_efuse_raw_write(unsigned blk, int data, u32 magic)
101 REG32(REG_AON_APB_PWR_CTRL) |= BIT_EFUSE0_PWR_ON;
102 REG32(REG_AON_APB_PWR_CTRL) |= BIT_EFUSE1_PWR_ON;
104 REG32(EFUSE_PGM_PARA) |= BIT_PGM_EN;
105 REG32(EFUSE_MAGIC_NUMBER) = BITS_MAGIC_NUMBER(magic);
109 retVal = sci_efuse_program(blk, data);
110 REG32(EFUSE_PGM_PARA) &= ~BIT_PGM_EN;
115 int sci_efuse_program(unsigned blk, int data)
120 int sci_efuse_raw_write(unsigned blk, int data, u32 magic)
126 #define CAL_DATA_BLK 7
127 #define BASE_ADC_P0 711 /* 3.6V */
128 #define BASE_ADC_P1 830 /* 4.2V */
131 #define ADC_DATA_OFFSET 128
132 /* they were stored in afuse of shark*/
133 int sci_efuse_calibration_get(unsigned int * p_cal_data)
137 unsigned short adc_temp;
138 #if defined(CONFIG_SPX15)||defined(CONFIG_ARCH_SCX35L)
140 data = sci_efuse_read(CAL_DATA_BLK);
141 sci_efuse_poweroff();
144 /* wait for maximum of 100 msec */
145 sci_adi_raw_write(ANA_REG_GLB_AFUSE_CTRL, BIT_AFUSE_READ_REQ);
148 while(BIT_AFUSE_READ_REQ & sci_adi_read(ANA_REG_GLB_AFUSE_CTRL)) {
161 data = sci_adi_read(ANA_REG_GLB_AFUSE_OUT0);
162 data |= (sci_adi_read(ANA_REG_GLB_AFUSE_OUT1)) << 16;
170 printf("afuse: data = 0x%x\n\r",data);
172 adc_temp = ((data & 0xFF00) >> 8) + BASE_ADC_P0 - ADC_DATA_OFFSET;
173 p_cal_data[1] = (VOL_P0) | ((adc_temp << 2) << 16);
176 adc_temp = (data & 0xFF) + BASE_ADC_P1 - ADC_DATA_OFFSET;
177 p_cal_data[0] = (VOL_P1)|((adc_temp << 2) << 16);