#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regmap.h>
+#include <linux/syscore_ops.h>
#if 0
{
.name = "rk818-rtc",
},
- /*
+
{
.name = "rk818-battery",
},
- {
+ /* {
.name = "rk818-power",
},
*/
#define rk818_LDO_SET_SLP_VOL_REG(x) (ldo_set_slp_vol_base_addr[x])
const static int buck_voltage_map[] = {
- 700, 712, 725, 737, 750, 762, 775, 787, 800,
+ 712, 725, 737, 750, 762, 775, 787, 800,
812, 825, 837, 850,862, 875, 887, 900, 912,
925, 937, 950, 962, 975, 987, 1000, 1012, 1025,
1037, 1050,1062, 1075, 1087, 1100, 1112, 1125, 1137,
return rk818_set_bits(rk818, RK818_SLEEP_SET_OFF_REG2, 1 << ldo, 1 << ldo);
}
+
+int rk818_ldo_slp_enable(int ldo_id)
+{
+ int ldo = ldo_id - 1;
+
+ if (ldo == 8)
+ return rk818_set_bits(g_rk818, RK818_SLEEP_SET_OFF_REG1,
+ 1 << 5, 0); /*ldo9*/
+ else if (ldo == 9)
+ return rk818_set_bits(g_rk818, RK818_SLEEP_SET_OFF_REG1,
+ 1 << 6, 0); /*ldo10 switch*/
+ else
+ return rk818_set_bits(g_rk818, RK818_SLEEP_SET_OFF_REG2,
+ 1 << ldo, 0);
+}
+
+int rk818_ldo_slp_disable(int ldo_id)
+{
+ int ldo = ldo_id - 1;
+
+ if (ldo == 8)
+ return rk818_set_bits(g_rk818, RK818_SLEEP_SET_OFF_REG1,
+ 1 << 5, 1 << 5); /*ldo9*/
+ else if (ldo == 9)
+ return rk818_set_bits(g_rk818, RK818_SLEEP_SET_OFF_REG1,
+ 1 << 6, 1 << 6); /*ldo10 switch*/
+ else
+ return rk818_set_bits(g_rk818, RK818_SLEEP_SET_OFF_REG2,
+ 1 << ldo, 1 << ldo);
+}
+
static int rk818_ldo_set_sleep_voltage(struct regulator_dev *dev,
int uV)
{
switch (buck) {
case 0:
case 1:
- volt = 700000 + selector * 12500;
+ volt = 712500 + selector * 12500;
break;
case 3:
volt = 1800000 + selector * 100000;
u16 vsel =0;
if (buck == 0 || buck == 1){
- if (min_uV < 700000)
+ if (min_uV < 712500)
vsel = 0;
else if (min_uV <= 1500000)
- vsel = ((min_uV - 700000) / 12500) ;
+ vsel = ((min_uV - 712500) / 12500) ;
else
return -EINVAL;
}
struct rk818 *rk818 = rdev_get_drvdata(dev);
int buck = rdev_get_id(dev) - RK818_DCDC1;
u16 val;
- int ret = 0,old_voltage =0,vol_temp =0;
+ int ret = 0;
if (buck ==2){
return 0;
const char *buf, size_t n)
{
u32 getdata[8];
- u16 regAddr;
+ u8 regAddr;
u8 data;
char cmd;
const char *buftmp = buf;
* R regAddr(8Bit)
* C gpio_name(poweron/powerhold/sleep/boot0/boot1) value(H/L)
*/
- regAddr = (u16)(getdata[0] & 0xff);
- if (strncmp(buf, "start", 5) == 0) {
-
-
- } else if (strncmp(buf, "stop", 4== 0) ){
-
- } else{
- sscanf(buftmp, "%c ", &cmd);
- printk("------zhangqing: get cmd = %c\n", cmd);
- switch(cmd) {
-
- case 'w':
- sscanf(buftmp, "%c %x %x ", &cmd, &getdata[0],&getdata[1]);
- regAddr = (u16)(getdata[0] & 0xff);
- data = (u8)(getdata[1] & 0xff);
- printk("get value = %x\n", data);
-
- rk818_i2c_write(rk818, regAddr, 1, data);
- rk818_i2c_read(rk818, regAddr, 1, &data);
- printk("%x %x\n", getdata[1],data);
-
- break;
-
- case 'r':
- sscanf(buftmp, "%c %x ", &cmd, &getdata[0]);
- printk("CMD : %c %x\n", cmd, getdata[0]);
-
- regAddr = (u16)(getdata[0] & 0xff);
- rk818_i2c_read(rk818, regAddr, 1, &data);
- printk("%x %x\n", getdata[0],data);
-
- break;
+ sscanf(buftmp, "%c ", &cmd);
+ printk("------zhangqing: get cmd = %c\n", cmd);
+ switch (cmd) {
+ case 'w':
+ sscanf(buftmp, "%c %x %x ", &cmd, &getdata[0], &getdata[1]);
+ regAddr = (u8)(getdata[0] & 0xff);
+ data = (u8)(getdata[1] & 0xff);
+ printk("get value = %x\n", data);
+
+ rk818_i2c_write(rk818, regAddr, 1, data);
+ rk818_i2c_read(rk818, regAddr, 1, &data);
+ printk("%x %x\n", getdata[1], data);
+ break;
+ case 'r':
+ sscanf(buftmp, "%c %x ", &cmd, &getdata[0]);
+ printk("CMD : %c %x\n", cmd, getdata[0]);
- default:
- printk("Unknown command\n");
- break;
- }
-}
- return n;
+ regAddr = (u8)(getdata[0] & 0xff);
+ rk818_i2c_read(rk818, regAddr, 1, &data);
+ printk("%x %x\n", getdata[0], data);
+ break;
+ default:
+ printk("Unknown command\n");
+ break;
+ }
+ return n;
}
static ssize_t rk818_test_show(struct kobject *kobj, struct kobj_attribute *attr,
};
#endif
-extern void rk_send_wakeup_key(void);
+#if 0
static irqreturn_t rk818_vbat_lo_irq(int irq, void *data)
{
printk("rk818 vbat low %s:irq=%d\n",__func__,irq);
rk_send_wakeup_key();
return IRQ_HANDLED;
}
+#endif
#ifdef CONFIG_OF
static struct of_device_id rk818_of_match[] = {
}
#endif
-int rk818_device_shutdown(void)
+static void rk818_shutdown(void)
{
int ret;
- int err = -1;
struct rk818 *rk818 = g_rk818;
-
- printk("%s\n",__func__);
+
+ pr_info("%s\n", __func__);
ret = rk818_set_bits(rk818, RK818_INT_STS_MSK_REG1,(0x3<<5),(0x3<<5)); //close rtc int when power off
ret = rk818_clear_bits(rk818, RK818_RTC_INT_REG,(0x3<<2)); //close rtc int when power off
- ret = rk818_reg_read(rk818,RK818_DEVCTRL_REG);
- ret = rk818_set_bits(rk818, RK818_DEVCTRL_REG,(0x1<<0),(0x1<<0));
-// ret = rk818_set_bits(rk818, RK818_DEVCTRL_REG,(0x1<<4),(0x1<<4));
- if (ret < 0) {
- printk("rk818 power off error!\n");
- return err;
+ /*disable otg_en*/
+ ret = rk818_clear_bits(rk818, RK818_DCDC_EN_REG, (0x1<<7));
+
+ mutex_lock(&rk818->io_lock);
+ mdelay(100);
+}
+
+static struct syscore_ops rk818_syscore_ops = {
+ .shutdown = rk818_shutdown,
+};
+
+void rk818_device_shutdown(void)
+{
+ int ret, i;
+ u8 reg = 0;
+ struct rk818 *rk818 = g_rk818;
+
+ for (i = 0; i < 10; i++) {
+ pr_info("%s\n", __func__);
+ ret = rk818_i2c_read(rk818, RK818_DEVCTRL_REG, 1, ®);
+ if (ret < 0)
+ continue;
+ ret = rk818_i2c_write(rk818, RK818_DEVCTRL_REG, 1,
+ (reg | (0x1 << 0)));
+ if (ret < 0) {
+ pr_err("rk818 power off error!\n");
+ continue;
+ }
}
- return 0;
+ while(1) wfi();
}
EXPORT_SYMBOL_GPL(rk818_device_shutdown);
__weak void rk818_device_resume(void) {}
#ifdef CONFIG_PM
static int rk818_suspend(struct i2c_client *i2c, pm_message_t mesg)
-{
+{
+ int ret, val;
+ struct rk818 *rk818 = g_rk818;
+
rk818_device_suspend();
+ /************set vbat low 3v4 to irq**********/
+ val = rk818_reg_read(rk818, RK818_VB_MON_REG);
+ val &= (~(VBAT_LOW_VOL_MASK | VBAT_LOW_ACT_MASK));
+ val |= (RK818_VBAT_LOW_3V4 | EN_VBAT_LOW_IRQ);
+ ret = rk818_reg_write(rk818, RK818_VB_MON_REG, val);
+ if (ret < 0) {
+ pr_err("Unable to write RK818_VB_MON_REG reg\n");
+ return ret;
+ }
+ /*enable low irq*/
+ rk818_set_bits(rk818, 0x4d, (0x1 << 1), (0x0 << 1));
return 0;
}
static int rk818_resume(struct i2c_client *i2c)
{
+ int ret, val;
+ struct rk818 *rk818 = g_rk818;
+
rk818_device_resume();
+ /********set vbat low 3v0 to shutdown**********/
+ val = rk818_reg_read(rk818, RK818_VB_MON_REG);
+ val &= (~(VBAT_LOW_VOL_MASK | VBAT_LOW_ACT_MASK));
+ val |= (RK818_VBAT_LOW_3V0 | EN_VABT_LOW_SHUT_DOWN);
+ ret = rk818_reg_write(rk818, RK818_VB_MON_REG, val);
+ if (ret < 0) {
+ pr_err("Unable to write RK818_VB_MON_REG reg\n");
+ return ret;
+ }
+ /*disable low irq*/
+ rk818_set_bits(rk818, 0x4d, (0x1 << 1), (0x1 << 1));
+
return 0;
}
#else
static int rk818_pre_init(struct rk818 *rk818)
{
int ret,val;
- printk("%s,line=%d\n", __func__,__LINE__);
+ printk("%s,line=%d\n", __func__,__LINE__);
+ ret = rk818_set_bits(rk818, 0xa1, (0xF<<0),(0x7));
ret = rk818_set_bits(rk818, 0xa1,(0x7<<4),(0x7<<4)); //close charger when usb low then 3.4V
- ret = rk818_set_bits(rk818, 0x52,(0x1<<1),(0x1<<1)); //no action when vref
-
+ ret = rk818_set_bits(rk818, 0x52,(0x1<<1),(0x1<<1)); //no action when vref
+ ret = rk818_set_bits(rk818, 0x52,(0x1<<0),(0x1<<0)); //enable HDMI 5V
+
/*******enable switch and boost***********/
val = rk818_reg_read(rk818,RK818_DCDC_EN_REG);
- val |= (0x3 << 5); //enable switch1/2
+ val |= (0x3 << 5); //enable switch1/2
val |= (0x1 << 4); //enable boost
- ret = rk818_reg_write(rk818,RK818_DCDC_EN_REG,val);
- if (ret <0) {
- printk(KERN_ERR "Unable to write RK818_DCDC_EN_REG reg\n");
- return ret;
+ ret = rk818_reg_write(rk818,RK818_DCDC_EN_REG,val);
+ if (ret <0) {
+ printk(KERN_ERR "Unable to write RK818_DCDC_EN_REG reg\n");
+ return ret;
}
/****************************************/
-
/****************set vbat low **********/
val = rk818_reg_read(rk818,RK818_VB_MON_REG);
- val &=(~(VBAT_LOW_VOL_MASK | VBAT_LOW_ACT_MASK));
- val |= (RK818_VBAT_LOW_3V5 | EN_VBAT_LOW_IRQ);
- ret = rk818_reg_write(rk818,RK818_VB_MON_REG,val);
- if (ret <0) {
- printk(KERN_ERR "Unable to write RK818_VB_MON_REG reg\n");
- return ret;
- }
+ val &=(~(VBAT_LOW_VOL_MASK | VBAT_LOW_ACT_MASK));
+ val |= (RK818_VBAT_LOW_3V0 | EN_VABT_LOW_SHUT_DOWN);
+ ret = rk818_reg_write(rk818,RK818_VB_MON_REG,val);
+ if (ret <0) {
+ printk(KERN_ERR "Unable to write RK818_VB_MON_REG reg\n");
+ return ret;
+ }
/**************************************/
-
+
/**********mask int****************/
- val = rk818_reg_read(rk818,RK818_INT_STS_MSK_REG1);
- val |= (0x1<<0); //mask vout_lo_int
- ret = rk818_reg_write(rk818,RK818_INT_STS_MSK_REG1,val);
- if (ret <0) {
- printk(KERN_ERR "Unable to write RK818_INT_STS_MSK_REG1 reg\n");
- return ret;
- }
+
+ val = rk818_reg_read(rk818,RK818_INT_STS_MSK_REG1);
+ val |= (0x1<<0); //mask vout_lo_int
+ ret = rk818_reg_write(rk818,RK818_INT_STS_MSK_REG1,val);
+ if (ret <0) {
+ printk(KERN_ERR "Unable to write RK818_INT_STS_MSK_REG1 reg\n");
+ return ret;
+ }
+
/**********************************/
/**********enable clkout2****************/
- ret = rk818_reg_write(rk818,RK818_CLK32OUT_REG,0x01);
- if (ret <0) {
- printk(KERN_ERR "Unable to write RK818_CLK32OUT_REG reg\n");
- return ret;
- }
+ ret = rk818_reg_write(rk818,RK818_CLK32OUT_REG,0x01);
+ if (ret <0) {
+ printk(KERN_ERR "Unable to write RK818_CLK32OUT_REG reg\n");
+ return ret;
+ }
/**********************************/
ret = rk818_clear_bits(rk818, RK818_INT_STS_MSK_REG1,(0x3<<5)); //open rtc int when power on
- ret = rk818_set_bits(rk818, RK818_RTC_INT_REG,(0x1<<3),(0x1<<3)); //open rtc int when power on
+ ret = rk818_set_bits(rk818, RK818_RTC_INT_REG,(0x1<<3),(0x1<<3)); //open rtc int when power on
+
+ /*****disable otg when in sleep mode****/
+ val = rk818_reg_read(rk818, RK818_SLEEP_SET_OFF_REG1);
+ val |= (0x1 << 7);
+ ret = rk818_reg_write(rk818, RK818_SLEEP_SET_OFF_REG1, val);
+ if (ret < 0) {
+ pr_err("Unable to write RK818_SLEEP_SET_OFF_REG1 reg\n");
+ return ret;
+ }
+
+ /*************** improve efficiency **********************/
+ ret = rk818_reg_write(rk818, RK818_BUCK2_CONFIG_REG, 0x1c);
+ if (ret < 0) {
+ pr_err("Unable to write RK818_BUCK2_CONFIG_REG reg\n");
+ return ret;
+ }
+
+ ret = rk818_reg_write(rk818, RK818_BUCK4_CONFIG_REG, 0x04);
+ if (ret < 0) {
+ pr_err("Unable to write RK818_BUCK4_CONFIG_REG reg\n");
+ return ret;
+ }
+
return 0;
}
struct regulator_dev *rk818_rdev;
struct regulator_init_data *reg_data;
const char *rail_name = NULL;
- int ret,vlow_irq,i=0;
+ int ret, i = 0;
printk("%s,line=%d\n", __func__,__LINE__);
}
#endif
+ register_syscore_ops(&rk818_syscore_ops);
+
return 0;
err:
struct rk818 *rk818 = i2c_get_clientdata(i2c);
int i;
+ unregister_syscore_ops(&rk818_syscore_ops);
for (i = 0; i < rk818->num_regulators; i++)
if (rk818->rdev[i])
regulator_unregister(rk818->rdev[i]);
i2c_set_clientdata(i2c, NULL);
- kfree(rk818);
return 0;
}