blob: 38a058965e0284d6f09d165ef02298e909621769 [file] [log] [blame]
#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
}