static int __devinit rt5025_misc_reg_init(struct i2c_client *client, struct rt5025_misc_data *md) { int ret = 0; rt5025_reg_write(client, RT5025_RESETCTRL_REG, md->RSTCtrl.val); rt5025_assign_bits(client, RT5025_VSYSULVO_REG, RT5025_VSYSOFF_MASK, md->VSYSCtrl.val); rt5025_reg_write(client, RT5025_PWRONCTRL_REG, md->PwrOnCfg.val); rt5025_reg_write(client, RT5025_SHDNCTRL_REG, md->SHDNCtrl.val); rt5025_reg_write(client, RT5025_PWROFFEN_REG, md->PwrOffCond.val); return ret; }
static int rt5025_set_voltage_sel(struct regulator_dev *rdev, unsigned selector) { struct rt5025_regulator_info *info = rdev_get_drvdata(rdev); unsigned char data; const int count = info->vol_output_size; if (selector > count) return -EINVAL; data = (unsigned char)selector; data <<= info->vol_shift; return rt5025_assign_bits(info->i2c, info->vol_reg, info->vol_mask, data); }
static int rt5025_set_charging_cv(struct i2c_client *i2c, int voltage) { int ret; u8 data; RTINFO("voltage = %d\n", voltage); if (voltage < 3500) data = 0; else if (voltage > 4440) data = 0x2f<<RT5025_CHGCV_SHIFT; else data = ((voltage-3500)/20)<<RT5025_CHGCV_SHIFT; ret = rt5025_assign_bits(i2c, RT5025_REG_CHGCTL3, RT5025_CHGCV_MASK, data); return ret; }
static int rt5025_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV, unsigned *selector) { struct rt5025_regulator_info *info = rdev_get_drvdata(rdev); unsigned char data; if (check_range(info, min_uV, max_uV)) { dev_err(&rdev->dev, "invalid voltage range (%d, %d) uV\n", min_uV, max_uV); return -EINVAL; } data = rt5025_find_voltage(rdev, min_uV, max_uV); data <<= info->vol_shift; return rt5025_assign_bits(info->i2c, info->vol_reg, info->vol_mask, data); }
static int rt5025_misc_reginit(struct i2c_client *client) { rt5025_reg_write(client, RT5025_REG_MISC1, misc_init_regval[0]); rt5025_reg_write(client, RT5025_REG_ONEVENT, misc_init_regval[1]); rt5025_assign_bits(client, RT5025_REG_DCDCONOFF, RT5025_VSYSOFF_MASK, misc_init_regval[2]); rt5025_reg_write(client, RT5025_REG_MISC2, misc_init_regval[3]); rt5025_reg_write(client, RT5025_REG_MISC3, misc_init_regval[4]); rt5025_reg_write(client, RT5025_REG_MISC4, misc_init_regval[5]); /*set all to be masked*/ rt5025_reg_write(client, RT5025_REG_IRQEN4, 0x00); rt5025_reg_write(client, RT5025_REG_IRQEN5, 0x00); /*clear the old irq status*/ rt5025_reg_read(client, RT5025_REG_IRQSTAT4); rt5025_reg_read(client, RT5025_REG_IRQSTAT5); /*set enable irqs as we want*/ rt5025_reg_write(client, RT5025_REG_IRQEN4, misc_init_regval[6]); rt5025_reg_write(client, RT5025_REG_IRQEN5, misc_init_regval[7]); return 0; }
static int rt5025_set_charging_cc(struct i2c_client *i2c, int cur_value) { int ret; u8 data; RTINFO("current value = %d\n", cur_value); if (cur_value < 500) data = 0; else if (cur_value > 2000) data = 0xf<<RT5025_CHGICC_SHIFT; else data = ((cur_value-500)/100)<<RT5025_CHGICC_SHIFT; ret = rt5025_assign_bits(i2c, RT5025_REG_CHGCTL4, RT5025_CHGICC_MASK, data); if (cur_value < 500) rt5025_set_charging_cc_switch(i2c, 0); else rt5025_set_charging_cc_switch(i2c, 1); return ret; }
struct regulator_dev *rt5025_regulator_register(struct regulator_desc *regulator_desc, struct device *dev, struct regulator_init_data *init_data, void *driver_data) { #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 5, 0)) struct regulator_config config = { .dev = dev, .init_data = init_data, .driver_data = driver_data, .of_node = dev->of_node, }; return regulator_register(regulator_desc, &config); #elif (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 37)) return regulator_register(regulator_desc, dev, init_data, driver_data, dev->of_node); #else return regulator_register(regulator_desc, dev, init_data, driver_data); #endif /* LINUX_VERSION_CODE>=KERNEL_VERSION(3,5,0)) */ } static struct regulator_init_data *of_parse_dt(struct rt5025_regulator_info *ri, struct device *dev) { struct regulator_init_data *init_data = NULL; #ifdef CONFIG_OF struct device_node *np = dev->of_node; int rc; u32 tmp; #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 3, 0)) init_data = of_get_regulator_init_data(dev, dev->of_node); #else init_data = of_get_regulator_init_data(dev); #endif /* #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0)) */ rc = of_property_read_u32(np, "rt,ramp_sel", &tmp); if (rc) { dev_info(dev, "no ramp_sel property, use default value\n"); } else { if (tmp > RT5025_DCDCRAMP_MAX) tmp = RT5025_DCDCRAMP_MAX; rt5025_assign_bits(ri->i2c, ri->ramp_reg, ri->ramp_bit, tmp); } if (of_property_read_bool(np, "rt,allow_mode_mask")) { init_data->constraints.valid_modes_mask |= (REGULATOR_MODE_FAST|\ REGULATOR_MODE_NORMAL); init_data->constraints.valid_ops_mask |= REGULATOR_CHANGE_MODE; } #endif /* #ifdef CONFIG_OF */ return init_data; } static int rt5025_regulator_probe(struct platform_device *pdev) { struct rt5025_chip *chip = dev_get_drvdata(pdev->dev.parent); struct rt5025_platform_data *pdata = (pdev->dev.parent)->platform_data; struct rt5025_regulator_info *ri; struct rt5025_regulator_ramp *ramp; struct regulator_dev *rdev; struct regulator_init_data *init_data; bool use_dt = pdev->dev.of_node; ri = find_regulator_info(pdev->id); if (ri == NULL) { dev_err(&pdev->dev, "invalid regulator ID specified\n"); return -EINVAL; } ri->i2c = chip->i2c; if (use_dt) { init_data = of_parse_dt(ri, &pdev->dev); } else { init_data = pdata->regulator[pdev->id]; ramp = init_data->driver_data; if (ramp) rt5025_assign_bits(ri->i2c, ri->ramp_reg, ri->ramp_bit, ramp->ramp_sel); } if (!init_data) { dev_err(&pdev->dev, "no initializing data\n"); return -EINVAL; } rdev = rt5025_regulator_register(&ri->desc, &pdev->dev, init_data, ri); if (IS_ERR(rdev)) { dev_err(&pdev->dev, "failed to register regulator %s\n", ri->desc.name); return PTR_ERR(rdev); } platform_set_drvdata(pdev, rdev); /* dev_info(&pdev->dev, "driver successfully loaded\n");*/ return 0; } static int rt5025_regulator_remove(struct platform_device *pdev) { struct regulator_dev *rdev = platform_get_drvdata(pdev); platform_set_drvdata(pdev, NULL); regulator_unregister(rdev); dev_info(&pdev->dev, "%s\n", __func__); return 0; } static struct of_device_id rt_match_table[] = { { .compatible = "rt,rt5025-dcdc1",}, { .compatible = "rt,rt5025-dcdc2",},