| #include "i2c_driver.h" |
| #include "global.h" |
| #include "io.h" |
| #include "debug.h" |
| #include "memmap.h" |
| #include "chip_voltage_info.h" |
| #include "SysMgr.h" |
| #include "apbRegBase.h" |
| |
| #ifndef VOUT_CPU_ID |
| #define VOUT_CPU_ID (2) |
| #endif |
| |
| #ifndef VOUT_CORE_ID |
| #define VOUT_CORE_ID (0) |
| #endif |
| |
| #ifndef VOUT_CPU_CHANNEL |
| #define VOUT_CPU_CHANNEL (0) |
| #endif |
| |
| #ifndef VOUT_CORE_CHANNEL |
| #define VOUT_CORE_CHANNEL (1) |
| #endif |
| |
| // For PMIC SY8824B/SYS20276/SYS20278 |
| #define RSVD 0xFFFFFFFF |
| #define REG_VSEL0 0x0 |
| |
| #define UNUSED(var) do { (void)(var); } while(0) |
| extern int lgpl_printf(const char *format, ...); |
| extern void delay_ms(unsigned int ms); |
| extern void udelay(unsigned long usec); |
| |
| |
| #if defined(I2C_SWITCH_CHANNEL) |
| #define I2C_CHANNEL_0 0 |
| #define I2C_CHANNEL_1 1 |
| #if defined(I2C_BUS_SWITCH_PCA9543) |
| int diag_i2c_set_ctrl_mux(int master_id, unsigned char mux) |
| { |
| int mux_7bit_addr = (0xE0 >> 1); |
| int ret = 0; |
| unsigned char buff[2]; |
| buff[0] = 0x00; |
| if (mux == I2C_CHANNEL_0) |
| { |
| buff[0] = 0x01; |
| } |
| else if (mux == I2C_CHANNEL_1) |
| { |
| buff[0] = 0x02; |
| } |
| ret = diag_i2c_master_writeread_bytes(master_id, mux_7bit_addr, (unsigned char*)&buff, 1, NULL, 0); |
| return ret; |
| } |
| #else |
| int diag_i2c_set_ctrl_mux(int master_id, unsigned char mux) |
| { |
| int ret = 0; |
| //set slave channel according to Switch IC. |
| return ret; |
| } |
| #endif |
| |
| #endif |
| |
| #ifdef I2C_NEWDRIVER |
| extern int i2c_master_init(int id, int speed, int b_10bit_addr); |
| extern int i2c_master_write_and_read(int id, int target_addr, unsigned char* send_buff, int send_len, unsigned char* recv_buff, int recv_len); |
| #endif |
| |
| int i2c_pre_volt_ctrl(int master_id, int slave_channel) |
| { |
| int ret = 0; |
| #if defined(BERLIN_SOC_BG3CD) |
| |
| #elif defined(BERLIN_SOC_BG2CD) |
| // set pinmux group 9 to be 3 |
| TGbl_pinMux pinmux; |
| // read current pinmux |
| REG_READ32((MEMMAP_CHIP_CTRL_REG_BASE + RA_Gbl_pinMux), &(pinmux.u32[0])); |
| REG_READ32((MEMMAP_CHIP_CTRL_REG_BASE + RA_Gbl_pinMux1), &(pinmux.u32[1])); |
| REG_READ32((MEMMAP_CHIP_CTRL_REG_BASE + RA_Gbl_pinMux2), &(pinmux.u32[2])); |
| pinmux.upinMux_gp9 = 3; |
| |
| REG_WRITE32((MEMMAP_CHIP_CTRL_REG_BASE + RA_Gbl_pinMux), (pinmux.u32[0])); |
| REG_WRITE32((MEMMAP_CHIP_CTRL_REG_BASE + RA_Gbl_pinMux1), (pinmux.u32[1])); |
| REG_WRITE32((MEMMAP_CHIP_CTRL_REG_BASE + RA_Gbl_pinMux2), (pinmux.u32[2])); |
| #elif defined(BERLIN_SOC_BG2Q) || defined(BERLIN_SOC_BG2DTV) |
| if (master_id == 0){ |
| T32Gbl_pinMux pinmux_soc; |
| pinmux_soc.u32 = readl(MEMMAP_CHIP_CTRL_REG_BASE + RA_Gbl_pinMux); |
| pinmux_soc.upinMux_gp6 = 1; |
| writel(pinmux_soc.u32, (MEMMAP_CHIP_CTRL_REG_BASE + RA_Gbl_pinMux)); |
| }else if (master_id == 1){ |
| T32Gbl_pinMux pinmux_soc; |
| pinmux_soc.u32 = readl(MEMMAP_CHIP_CTRL_REG_BASE + RA_Gbl_pinMux); |
| pinmux_soc.upinMux_gp7 = 1; |
| writel(pinmux_soc.u32, (MEMMAP_CHIP_CTRL_REG_BASE + RA_Gbl_pinMux)); |
| }else if (master_id == 2){ |
| T32smSysCtl_SM_GSM_SEL pinmux_sm; |
| pinmux_sm.u32 = readl(SM_SYS_CTRL_REG_BASE + RA_smSysCtl_SM_GSM_SEL); |
| pinmux_sm.uSM_GSM_SEL_GSM13_SEL = 3; |
| writel(pinmux_sm.u32, (SM_SYS_CTRL_REG_BASE + RA_smSysCtl_SM_GSM_SEL)); |
| }else if (master_id == 3){ |
| T32smSysCtl_SM_GSM_SEL pinmux_sm; |
| pinmux_sm.u32 = readl(SM_SYS_CTRL_REG_BASE + RA_smSysCtl_SM_GSM_SEL); |
| pinmux_sm.uSM_GSM_SEL_GSM14_SEL = 3; |
| writel(pinmux_sm.u32, (SM_SYS_CTRL_REG_BASE + RA_smSysCtl_SM_GSM_SEL)); |
| } |
| //#elif defined() |
| #else |
| UNUSED(master_id); |
| UNUSED(slave_channel); |
| #endif |
| |
| #if defined(I2C_SWITCH_CHANNEL) |
| ret = diag_i2c_set_ctrl_mux(master_id, slave_channel); |
| #endif |
| |
| return ret; |
| } |
| int i2c_pre_set_cpu_volt() |
| { |
| return i2c_pre_volt_ctrl(VOUT_CPU_ID, VOUT_CPU_CHANNEL); |
| } |
| |
| int i2c_pre_set_core_volt() |
| { |
| return i2c_pre_volt_ctrl(VOUT_CORE_ID, VOUT_CORE_CHANNEL); |
| } |
| |
| int i2c_get_volt(int master_id) |
| { |
| int ret; |
| unsigned char buff; |
| unsigned char read = 0xff; |
| unsigned char slaveAddr = 0x19; // PG867 slave address is 0x19 |
| buff = 0x24; |
| |
| #ifdef I2C_NEWDRIVER |
| i2c_master_init(master_id, 100, 0); |
| ret = i2c_master_write_and_read(master_id, (int)slaveAddr, (unsigned char*)&buff, 1, (unsigned char*)&read, 1); |
| #else |
| diag_i2c_master_init(master_id); |
| diag_i2c_master_set_addr_type(I2C_7BIT_SLAVE_ADDR); |
| |
| ret = diag_i2c_master_writeread_bytes(master_id, (int)slaveAddr, (unsigned char*)&buff, 1, (unsigned char*)&read, 1); |
| #endif |
| if (ret != 0) |
| { |
| lgpl_printf(" i2c read fail\n"); |
| return -ret; |
| } |
| |
| return read; |
| } |
| |
| int diag_i2c_volt_control(int master_id, int volt_index) |
| { |
| unsigned char buff[2]; |
| unsigned char read = 0xff; |
| int ret; |
| // VIndex: [0-0.90,1-0.925,2-0.95(default),3-0.975,4-1.00,5-1.025,6-1.050] |
| unsigned char slaveAddr = 0x19; // PG867 slave address is 0x19 |
| buff[0] = 0x24; // PG867 buck1 target voltage 2 (active) register |
| buff[1] = 0x7 + volt_index; // 0x7 is 0.90v. each step is 0.025 |
| #ifdef I2C_NEWDRIVER |
| i2c_master_init(master_id, 100, 0); |
| ret = i2c_master_write_and_read(master_id, (int)slaveAddr, buff, 2, (unsigned char*)0, 0); |
| #else |
| diag_i2c_master_init(master_id); |
| diag_i2c_master_set_addr_type(I2C_7BIT_SLAVE_ADDR); |
| // write |
| ret = diag_i2c_master_writeread_bytes(master_id, (int)slaveAddr, buff, 2, (unsigned char*)0, 0); |
| #endif |
| if (ret != 0) |
| { |
| lgpl_printf(" i2c write fail\n"); |
| return ret; |
| } |
| |
| #ifdef I2C_NEWDRIVER |
| ret = i2c_master_write_and_read(master_id, (int)slaveAddr, buff, 1, (unsigned char*)&read, 1); |
| #else |
| ret = diag_i2c_master_writeread_bytes(master_id, (int)slaveAddr, buff, 1, (unsigned char*)&read, 1); |
| #endif |
| if (ret != 0) |
| { |
| lgpl_printf(" i2c read fail\n"); |
| return ret; |
| } |
| |
| if (buff[1] != read) |
| { |
| lgpl_printf(" i2c vcore control fail, read:0x%02x != write:0x%02x\n", read, buff[1]); |
| return 1; |
| } |
| lgpl_printf(" vcore is %4d.%03dv\n", (900+25*volt_index) / 1000, (900+25*volt_index) % 1000); |
| |
| return 0; |
| } |
| |
| int i2c_set_volt(int master_id, int vout) |
| { |
| int volt_index; |
| if ((vout - 900) % 25) |
| volt_index = (vout - 900) / 25 + 1; |
| else |
| volt_index = (vout - 900) / 25; |
| return diag_i2c_volt_control(master_id, volt_index); |
| } |
| |
| int i2c_get_cpu_volt(void) |
| { |
| int volt_index = i2c_get_volt(VOUT_CPU_ID); |
| |
| if(volt_index < 0) |
| return 0; |
| return (900 + (volt_index - 0x7) * 25); |
| } |
| |
| int i2c_get_core_volt(void) |
| { |
| int volt_index = i2c_get_volt(VOUT_CORE_ID); |
| |
| if(volt_index < 0) |
| return 0; |
| return (900 + (volt_index - 0x7) * 25); |
| } |
| |
| int i2c_set_cpu_volt(int vout) |
| { |
| return i2c_set_volt(VOUT_CPU_ID, vout); |
| } |
| |
| int i2c_set_core_volt(int vout) |
| { |
| return i2c_set_volt(VOUT_CORE_ID, vout); |
| } |
| |
| |
| //FIXME: due to INT Data limit, resolution can only support 25mv although |
| //FIXME: although hardware can support up to 12.5mv |
| static int sy8824b_data2vol(unsigned int *p_data, unsigned int *p_vol) |
| { |
| unsigned int vol; |
| unsigned int data = *p_data; |
| |
| data = data & 0x3F; |
| if (data <= 0x3f) |
| vol = 1550 - ((63 - data)/2)*25; |
| else |
| vol = RSVD; |
| |
| if (vol == RSVD) |
| return -1; |
| else { |
| *p_vol = vol; |
| } |
| |
| return 0; |
| } |
| |
| static int sy8824b_vol2data(unsigned int *p_vol, unsigned int *p_data) |
| { |
| unsigned int vol = *p_vol; |
| unsigned int data; |
| |
| if ((vol >= 775) && (vol <= 1550)) |
| data = 63 - ((1550 - vol)*2)/25; |
| else |
| data = RSVD; |
| |
| if (data == RSVD) |
| return -1; |
| else { |
| *p_data = data; |
| } |
| |
| return 0; |
| } |
| |
| #ifdef I2C_NEWDRIVER |
| int sy8824b_get_vol(int master_id, int slaveAddr) |
| { |
| unsigned int read = 0xff; |
| unsigned int volt; |
| unsigned int bulk_reg = REG_VSEL0; |
| int ret = 1; |
| |
| i2c_master_init(master_id, 100, 0); //int id, int speed, int b_10bit_addr |
| // read, SY8824b slave address is 0x66 |
| ret = i2c_master_write_and_read(master_id, slaveAddr, (unsigned char*)&bulk_reg, 1, (unsigned char*)&read, 1); |
| |
| lgpl_printf( "\nREG_VSEL0 = 0x%x \n", read); |
| ret |= sy8824b_data2vol(&read, &volt); |
| if(ret) { |
| lgpl_printf(" i2c read fail\n"); |
| return -1; |
| } |
| |
| return volt; |
| } |
| #endif |
| |
| #ifdef I2C_NEWDRIVER |
| int sy8824b_set_vol(int master_id, int slaveAddr, int volt) |
| { |
| unsigned int target = volt; |
| unsigned char buff[2]; |
| unsigned int data_reg0, data; |
| unsigned int bulk_reg0 = REG_VSEL0; |
| int ret = 1; |
| |
| // read, SY8824b slave address is 0x66 |
| i2c_master_init(master_id, 100, 0); //int id, int speed, int b_10bit_addr |
| ret = i2c_master_write_and_read(master_id, slaveAddr, (unsigned char*)&bulk_reg0, 1, (unsigned char*)&data_reg0, 1); |
| if (ret) |
| { |
| lgpl_printf("PMIC i2c read fail !\n"); |
| return ret; |
| } |
| data_reg0 = data_reg0 & 0xc0; |
| |
| ret = sy8824b_vol2data(&target, &data); |
| if (ret == 0) { |
| data_reg0 = data_reg0 | data; |
| lgpl_printf( "data_reg0 = 0x%x \n", data_reg0); |
| |
| buff[0] = (unsigned char)REG_VSEL0; |
| buff[1] = (unsigned char)data_reg0; |
| |
| // write |
| ret = i2c_master_write_and_read(master_id, slaveAddr, buff, 2, (unsigned char*)0, 0); |
| if (ret) { |
| lgpl_printf("PMIC i2c write fail !\n"); |
| return ret; |
| } |
| |
| // read |
| buff[0] = (unsigned char)REG_VSEL0; |
| ret = i2c_master_write_and_read(master_id, slaveAddr, buff, 1, (unsigned char *)&data, 1); |
| if (ret) { |
| lgpl_printf("PMIC i2c read fail !\n"); |
| return ret; |
| } |
| |
| if (data_reg0 != data) { |
| lgpl_printf( "PMIC sy8824b: read:0x%02x != write:0x%02x\n", data, data_reg0); |
| return -1; |
| } |
| |
| lgpl_printf( "set to %d mv\n", target); |
| delay_ms(1); |
| } |
| else { |
| lgpl_printf( "Illegal target voltage for PMIC sy8824b !\n"); |
| return -1; |
| } |
| return ret; |
| } |
| #endif |
| |
| static int set_volt_sy8824b(int master_id, int final_volt, int default_volt) |
| { |
| #if defined(I2C_NEWDRIVER) |
| int volt = default_volt; |
| int ret = -1; |
| if(volt == final_volt) |
| return 0; |
| |
| while(volt != final_volt) { |
| if (volt > final_volt){ |
| volt -= 25; |
| if (volt < final_volt) |
| volt = final_volt; |
| } else { |
| volt += 25; |
| if (volt > final_volt) |
| volt = final_volt; |
| } |
| ret = sy8824b_set_vol(master_id, 0x66, volt); |
| if(ret != 0) |
| return ret; |
| udelay(50); // delay 50us to wait it stable |
| } |
| return 0; |
| #else |
| UNUSED(volt); |
| //#error "PV compensation mothod is not supported." |
| return -1; |
| #endif |
| } |
| |
| int set_core_volt_sy8824b(int volt, int default_volt) |
| { |
| return set_volt_sy8824b(VOUT_CORE_ID, volt, default_volt); |
| } |
| |
| int set_cpu_volt_sy8824b(int volt, int default_volt) |
| { |
| return set_volt_sy8824b(VOUT_CPU_ID, volt, default_volt); |
| } |
| |
| int get_core_volt_sy8824b(void) |
| { |
| #if defined(I2C_NEWDRIVER) |
| int volt = sy8824b_get_vol(VOUT_CORE_ID, 0x66); |
| return volt; |
| #else |
| return get_default_core_voltage(); |
| #endif |
| } |
| |
| int get_cpu_volt_sy8824b(void) |
| { |
| #if defined(I2C_NEWDRIVER) |
| int volt = sy8824b_get_vol(VOUT_CPU_ID, 0x66); |
| return volt; |
| #else |
| return get_default_cpu_voltage(); |
| #endif |
| } |
| |
| static int sy20276_data2vol(unsigned int *p_data, unsigned int *p_vol) |
| { |
| unsigned int vol; |
| unsigned int data = *p_data; |
| |
| data = data & 0x7F; |
| if (data <= 0x7f && 0x5a <= data) |
| vol = 1500; |
| else if (data < 0x5a) |
| vol = 600 + data * 10; |
| else |
| vol = RSVD; |
| |
| if (vol == RSVD) |
| return -1; |
| else { |
| *p_vol = vol; |
| } |
| |
| return 0; |
| } |
| |
| static int sy20276_vol2data(unsigned int *p_vol, unsigned int *p_data) |
| { |
| unsigned int vol = *p_vol; |
| unsigned int data; |
| |
| if ((vol >= 600) && (vol <= 1500)) |
| data = (vol - 600) / 10; |
| else |
| data = RSVD; |
| |
| if (data == RSVD) |
| return -1; |
| else { |
| *p_data = data; |
| } |
| |
| return 0; |
| } |
| |
| #ifdef I2C_NEWDRIVER |
| int sy20276_get_vol(int master_id, int slaveAddr) |
| { |
| unsigned int read = 0xff; |
| unsigned int volt; |
| unsigned int bulk_reg = REG_VSEL0; |
| int ret = 1; |
| |
| i2c_master_init(master_id, 100, 0); //int id, int speed, int b_10bit_addr |
| // read, SY20276 slave address is 0x60 |
| ret = i2c_master_write_and_read(master_id, slaveAddr, (unsigned char*)&bulk_reg, 1, (unsigned char*)&read, 1); |
| |
| lgpl_printf( "\nREG_VSEL0 = 0x%x \n", read); |
| ret |= sy20276_data2vol(&read, &volt); |
| if(ret) { |
| lgpl_printf(" i2c read fail\n"); |
| return -1; |
| } |
| |
| return volt; |
| } |
| #endif |
| |
| #ifdef I2C_NEWDRIVER |
| int sy20276_set_vol(int master_id, int slaveAddr, int volt) |
| { |
| unsigned int target = volt; |
| unsigned char buff[2]; |
| unsigned int data_reg0, data; |
| unsigned int bulk_reg0 = REG_VSEL0; |
| int ret = 1; |
| |
| // read, SY20276b slave address is 0x60 |
| i2c_master_init(master_id, 100, 0); //int id, int speed, int b_10bit_addr |
| ret = i2c_master_write_and_read(master_id, slaveAddr, (unsigned char*)&bulk_reg0, 1, (unsigned char*)&data_reg0, 1); |
| if (ret) |
| { |
| lgpl_printf("PMIC i2c read fail !\n"); |
| return ret; |
| } |
| data_reg0 = data_reg0 & 0x80; |
| |
| ret = sy20276_vol2data(&target, &data); |
| if (ret == 0) { |
| data_reg0 = data_reg0 | data; |
| lgpl_printf( "data_reg0 = 0x%x \n", data_reg0); |
| |
| buff[0] = (unsigned char)REG_VSEL0; |
| buff[1] = (unsigned char)data_reg0; |
| |
| // write |
| ret = i2c_master_write_and_read(master_id, slaveAddr, buff, 2, (unsigned char*)0, 0); |
| if (ret) { |
| lgpl_printf("PMIC i2c write fail !\n"); |
| return ret; |
| } |
| |
| // read |
| buff[0] = (unsigned char)REG_VSEL0; |
| ret = i2c_master_write_and_read(master_id, slaveAddr, buff, 1, (unsigned char *)&data, 1); |
| if (ret) { |
| lgpl_printf("PMIC i2c read fail !\n"); |
| return ret; |
| } |
| |
| if (data_reg0 != data) { |
| lgpl_printf( "PMIC sy20276: read:0x%02x != write:0x%02x\n", data, data_reg0); |
| return -1; |
| } |
| |
| lgpl_printf( "set to %d mv\n", target); |
| delay_ms(1); |
| } |
| else { |
| lgpl_printf( "Illegal target voltage for PMIC sy20276 !\n"); |
| return -1; |
| } |
| return ret; |
| } |
| #endif |
| |
| static int set_volt_sy20276(int master_id, int final_volt, int default_volt) |
| { |
| #if defined(I2C_NEWDRIVER) |
| int volt = default_volt; |
| int ret = -1; |
| if(volt == final_volt) |
| return 0; |
| |
| while(volt != final_volt) { |
| if (volt > final_volt){ |
| volt -= 10; |
| if (volt < final_volt) |
| volt = final_volt; |
| } else { |
| volt += 10; |
| if (volt > final_volt) |
| volt = final_volt; |
| } |
| ret = sy20276_set_vol(master_id, 0x60, volt); |
| if(ret != 0) |
| return ret; |
| udelay(50); // delay 50us to wait it stable |
| } |
| return 0; |
| #else |
| UNUSED(volt); |
| //#error "PV compensation mothod is not supported." |
| return -1; |
| #endif |
| } |
| |
| int set_core_volt_sy20276(int volt, int default_volt) |
| { |
| return set_volt_sy20276(VOUT_CORE_ID, volt, default_volt); |
| } |
| |
| int set_cpu_volt_sy20276(int volt, int default_volt) |
| { |
| return set_volt_sy20276(VOUT_CPU_ID, volt, default_volt); |
| } |
| |
| int get_core_volt_sy20276(void) |
| { |
| #if defined(I2C_NEWDRIVER) |
| int volt = sy20276_get_vol(VOUT_CORE_ID, 0x60); |
| return volt; |
| #else |
| return get_default_core_voltage(); |
| #endif |
| } |
| |
| int get_cpu_volt_sy20276(void) |
| { |
| #if defined(I2C_NEWDRIVER) |
| int volt = sy20276_get_vol(VOUT_CPU_ID, 0x60); |
| return volt; |
| #else |
| return get_default_cpu_voltage(); |
| #endif |
| } |
| |
| //FIXME: due to INT Data limit, resolution can only support 25mv although |
| //FIXME: although hardware can support up to 12.5mv |
| static int sy20278_data2vol(unsigned int *p_data, unsigned int *p_vol) |
| { |
| unsigned int vol; |
| unsigned int data = *p_data; |
| |
| data = data & 0x3F; |
| if (data <= 0x3f && 0x17 <= data) |
| vol = 1050000; |
| else if (data < 0x17) |
| vol = 762500 + data * 12500; |
| else |
| vol = RSVD; |
| |
| if (vol == RSVD) |
| return -1; |
| else { |
| *p_vol = vol; |
| } |
| |
| return 0; |
| } |
| |
| static int sy20278_vol2data(unsigned int *p_vol, unsigned int *p_data) |
| { |
| unsigned int vol = *p_vol; |
| unsigned int data; |
| |
| if ((vol >= 762500) && (vol <= 1050000)) |
| data = (vol - 762500) / 12500; |
| else |
| data = RSVD; |
| |
| if (data == RSVD) |
| return -1; |
| else { |
| *p_data = data; |
| } |
| |
| return 0; |
| } |
| |
| #ifdef I2C_NEWDRIVER |
| int sy20278_get_vol(int master_id, int slaveAddr) |
| { |
| unsigned int read = 0xff; |
| unsigned int volt; |
| unsigned int bulk_reg = REG_VSEL0; |
| int ret = 1; |
| |
| i2c_master_init(master_id, 100, 0); //int id, int speed, int b_10bit_addr |
| // read, sy20278 slave address is 0x61 |
| ret = i2c_master_write_and_read(master_id, slaveAddr, (unsigned char*)&bulk_reg, 1, (unsigned char*)&read, 1); |
| |
| lgpl_printf( "\nREG_VSEL0 = 0x%x \n", read); |
| ret |= sy20278_data2vol(&read, &volt); |
| if(ret) { |
| lgpl_printf(" i2c read fail\n"); |
| return -1; |
| } |
| |
| return volt; |
| } |
| #endif |
| |
| #ifdef I2C_NEWDRIVER |
| int sy20278_set_vol(int master_id, int slaveAddr, int volt) |
| { |
| unsigned int target = volt; |
| unsigned char buff[2]; |
| unsigned int data_reg0, data; |
| unsigned int bulk_reg0 = REG_VSEL0; |
| int ret = 1; |
| |
| // read, sy20278 slave address is 0x61 |
| i2c_master_init(master_id, 100, 0); //int id, int speed, int b_10bit_addr |
| ret = i2c_master_write_and_read(master_id, slaveAddr, (unsigned char*)&bulk_reg0, 1, (unsigned char*)&data_reg0, 1); |
| if (ret) |
| { |
| lgpl_printf("PMIC i2c read fail !\n"); |
| return ret; |
| } |
| data_reg0 = data_reg0 & 0xc0; |
| |
| ret = sy20278_vol2data(&target, &data); |
| if (ret == 0) { |
| data_reg0 = data_reg0 | data; |
| lgpl_printf( "data_reg0 = 0x%x \n", data_reg0); |
| |
| buff[0] = (unsigned char)REG_VSEL0; |
| buff[1] = (unsigned char)data_reg0; |
| |
| // write |
| ret = i2c_master_write_and_read(master_id, slaveAddr, buff, 2, (unsigned char*)0, 0); |
| if (ret) { |
| lgpl_printf("PMIC i2c write fail !\n"); |
| return ret; |
| } |
| |
| // read |
| buff[0] = (unsigned char)REG_VSEL0; |
| ret = i2c_master_write_and_read(master_id, slaveAddr, buff, 1, (unsigned char *)&data, 1); |
| if (ret) { |
| lgpl_printf("PMIC i2c read fail !\n"); |
| return ret; |
| } |
| |
| if (data_reg0 != data) { |
| lgpl_printf( "PMIC sy20278: read:0x%02x != write:0x%02x\n", data, data_reg0); |
| return -1; |
| } |
| |
| lgpl_printf( "set to %d mv\n", target); |
| delay_ms(1); |
| } |
| else { |
| lgpl_printf( "Illegal target voltage for PMIC sy20278 !\n"); |
| return -1; |
| } |
| return ret; |
| } |
| #endif |
| |
| static int set_volt_sy20278(int master_id, int final_volt, int default_volt) |
| { |
| #if defined(I2C_NEWDRIVER) |
| int volt = default_volt; |
| int ret = -1; |
| if(volt == final_volt) |
| return 0; |
| |
| while(volt != final_volt) { |
| if (volt > final_volt){ |
| volt -= 12500; |
| if (volt < final_volt) |
| volt = final_volt; |
| } else { |
| volt += 12500; |
| if (volt > final_volt) |
| volt = final_volt; |
| } |
| ret = sy20278_set_vol(master_id, 0x61, volt); |
| if(ret != 0) |
| return ret; |
| udelay(50); // delay 50us to wait it stable |
| } |
| return 0; |
| #else |
| UNUSED(volt); |
| //#error "PV compensation mothod is not supported." |
| return -1; |
| #endif |
| } |
| |
| int set_core_volt_sy20278(int volt, int default_volt) |
| { |
| return set_volt_sy20278(VOUT_CORE_ID, volt, default_volt); |
| } |
| |
| int set_cpu_volt_sy20278(int volt, int default_volt) |
| { |
| return set_volt_sy20278(VOUT_CPU_ID, volt, default_volt); |
| } |
| |
| int get_core_volt_sy20278(void) |
| { |
| #if defined(I2C_NEWDRIVER) |
| int volt = sy20278_get_vol(VOUT_CORE_ID, 0x61); |
| return volt; |
| #else |
| return get_default_core_voltage(); |
| #endif |
| } |
| |
| int get_cpu_volt_sy20278(void) |
| { |
| #if defined(I2C_NEWDRIVER) |
| int volt = sy20278_get_vol(VOUT_CPU_ID, 0x61); |
| return volt; |
| #else |
| return get_default_cpu_voltage(); |
| #endif |
| } |
| |
| |
| #if defined(I2C_NEWDRIVER) |
| static int ncp6335d_vol2data(unsigned int *p_vol, unsigned int *p_data) |
| { |
| unsigned int vol = *p_vol; |
| unsigned int data; |
| |
| if ((vol >= 600) && (vol <= 1375)) |
| data = ((vol - 600)/25)*4; |
| else |
| return -1; |
| |
| data = data & 0x7f; |
| *p_data = data; |
| return 0; |
| } |
| |
| static int ncp6335d_set_vol(int master_id, int volt_sel, int vol) |
| { |
| unsigned int target = vol; |
| unsigned int data,data_read = 0; |
| unsigned int buck_reg0; |
| const char slaveAddr = 0x1C; |
| unsigned char buff[2]; |
| int ret = 0; |
| |
| if (volt_sel == 0){ |
| buck_reg0 = 0x11; |
| } else { |
| lgpl_printf( "Don't support BUCK2\n"); |
| return 0; |
| } |
| |
| ret = ncp6335d_vol2data(&target, &data); |
| |
| if (ret == 0) { |
| data = 0x80 | data; |
| |
| buff[0] = (unsigned char)buck_reg0; |
| buff[1] = (unsigned char)data; |
| i2c_master_init(master_id, 100, 0); |
| // write |
| ret = i2c_master_write_and_read(master_id, slaveAddr, buff, 2, (unsigned char*)0, 0); |
| if (ret) { |
| lgpl_printf("PMIC i2c write fail !\n"); |
| return ret; |
| } |
| |
| // read |
| buff[0] = (unsigned char)buck_reg0; |
| ret = i2c_master_write_and_read(master_id, slaveAddr, buff, 1, (unsigned char *)&data_read, 1); |
| if (ret) { |
| lgpl_printf("PMIC i2c read fail !\n"); |
| return ret; |
| } |
| |
| if (data_read != data) { |
| lgpl_printf( "PMIC ncp6335: read:0x%02x != write:0x%02x\n", data, data_read); |
| return -1; |
| } |
| |
| lgpl_printf( "set to %d mv\n", target); |
| delay_ms(1); |
| } |
| |
| return ret; |
| } |
| |
| static int ncp6335d_get_vol(int master_id, int volt_sel) |
| { |
| unsigned int read = 0xff; |
| unsigned int buck_reg; |
| const char slaveAddr = 0x1C; |
| int ret; |
| |
| if (volt_sel == 0){ |
| buck_reg = 0x11; |
| } else { |
| lgpl_printf( "Don't support BUCK2\n"); |
| return -1; |
| } |
| |
| i2c_master_init(master_id, 100, 0); //int id, int speed, int b_10bit_addr |
| ret = i2c_master_write_and_read(master_id, slaveAddr, (unsigned char*)&buck_reg, 1, (unsigned char*)&read, 1); |
| if (ret != 0) |
| { |
| lgpl_printf(" i2c read fail\n"); |
| return -ret; |
| } |
| lgpl_printf( "\nREG_VSEL0 = 0x%x \n", read); |
| |
| read = read & 0x7F; |
| return ((read/4)*25 + 600); |
| } |
| #endif |
| |
| static int set_volt_ncp6335d(int master_id, int final_volt, int default_volt) |
| { |
| #if defined(I2C_NEWDRIVER) |
| int volt = default_volt; |
| int ret = -1; |
| if(volt == final_volt) |
| return 0; |
| |
| while(volt != final_volt) { |
| if (volt > final_volt){ |
| volt -= 25; |
| if (volt < final_volt) |
| volt = final_volt; |
| } else { |
| volt += 25; |
| if (volt > final_volt) |
| volt = final_volt; |
| } |
| ret = ncp6335d_set_vol(master_id, 0x0, volt); |
| if(ret != 0) |
| return ret; |
| udelay(50); // delay 50us to wait it stable |
| } |
| return 0; |
| #else |
| UNUSED(volt); |
| //#error "PV compensation mothod is not supported." |
| return -1; |
| #endif |
| } |
| |
| int set_core_volt_ncp6335d(int volt, int default_volt) |
| { |
| return set_volt_ncp6335d(VOUT_CORE_ID, volt, default_volt); |
| } |
| |
| int set_cpu_volt_ncp6335d(int volt, int default_volt) |
| { |
| return set_volt_ncp6335d(VOUT_CPU_ID, volt, default_volt); |
| } |
| |
| int get_core_volt_ncp6335d(void) |
| { |
| #if defined(I2C_NEWDRIVER) |
| int volt = ncp6335d_get_vol(VOUT_CORE_ID, 0x0); |
| //if(volt <= 0) |
| // volt = get_default_core_voltage(); |
| return volt; |
| #else |
| return get_default_core_voltage(); |
| #endif |
| } |
| |
| int get_cpu_volt_ncp6335d(void) |
| { |
| #if defined(I2C_NEWDRIVER) |
| int volt = ncp6335d_get_vol(VOUT_CPU_ID, 0x0); |
| //if(volt <= 0) |
| // volt = get_default_cpu_voltage(); |
| return volt; |
| #else |
| return get_default_cpu_voltage(); |
| #endif |
| } |