static int twlreg_disable(struct regulator_dev *rdev)
{
	struct twlreg_info	*info = rdev_get_drvdata(rdev);
	int			grp;
	int			ret;

	grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP);
	if (grp < 0)
		return grp;

	/* For 6030, set the off state for all grps enabled */
	if (twl_class_is_6030()) {
		ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_STATE,
			(grp & (P1_GRP_6030 | P2_GRP_6030 | P3_GRP_6030)) <<
				TWL6030_CFG_STATE_GRP_SHIFT |
			TWL6030_CFG_STATE_OFF);
		if (ret)
			return ret;
	}

	if (twl_class_is_4030())
		grp &= ~(P1_GRP_4030 | P2_GRP_4030 | P3_GRP_4030);
	else
		grp &= ~(P1_GRP_6030 | P2_GRP_6030 | P3_GRP_6030);

	ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp);

	/* Next, associate cleared grp in state register */
	if (!ret && twl_class_is_6030())
		ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_STATE,
				grp << TWL6030_CFG_STATE_GRP_SHIFT |
				TWL6030_CFG_STATE_OFF);

	return ret;
}
static int twlreg_enable(struct regulator_dev *rdev)
{
	struct twlreg_info	*info = rdev_get_drvdata(rdev);
	int			grp;
	int			ret;

	grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP);
	if (grp < 0)
		return grp;

	if (twl_class_is_4030())
		grp |= P1_GRP_4030;
	else
		grp |= P1_GRP_6030;

	ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp);

	if (!ret && twl_class_is_6030())
		ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_STATE,
				grp << TWL6030_CFG_STATE_GRP_SHIFT |
				TWL6030_CFG_STATE_ON);

	udelay(info->delay);

	return ret;
}
예제 #3
0
int twlreg_refresh(struct regulator_dev *rdev)
{
	struct twlreg_info	*info = rdev_get_drvdata(rdev);
	u16			delay=1000;
	int			stat;	
	int			grp;
	int			backup_stat;	
	int			backup_grp;
	int 		ret=0;

	
	grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP);
	if (grp < 0)
		return grp;
	backup_grp = grp;
	grp |= 0x07;
	ret=twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp);	
	if (ret < 0)
		return ret;
	stat = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_STATE);
	if (stat < 0)
		return stat;	
	backup_stat = stat;
	stat = 0xE0;
	ret=twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_STATE, stat);	
	if (ret < 0)
	{		
		twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, backup_grp);	
		return ret;
	}
			

	udelay(delay);

	


	grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP);
	grp |= 0x07;
	ret=twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp);	
	stat = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_STATE);
	stat = 0xE1;
	ret=twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_STATE, stat);	
	
	udelay(delay/2);

	ret=twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, backup_grp);	
	if (ret < 0)
	{
		twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_STATE, backup_stat);	
		return ret;
	}
    ret=twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_STATE, backup_stat);	
	if (ret < 0)
		return ret;
    return ret;

	
}
static int
twl4030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV)
{
	struct twlreg_info	*info = rdev_get_drvdata(rdev);
	int			vsel;

	for (vsel = 0; vsel < info->table_len; vsel++) {
		int mV = info->table[vsel];
		int uV;

		if (IS_UNSUP(mV))
			continue;
		uV = LDO_MV(mV) * 1000;

		/* REVISIT for VAUX2, first match may not be best/lowest */

		/* use the first in-range value */
		if (min_uV <= uV && uV <= max_uV){
            printk("%s : %s  uV=%d\n",__func__,rdev->desc->name,uV);
			return twlreg_write(info, TWL_MODULE_PM_RECEIVER,
							VREG_VOLTAGE, vsel);
        }
	}

	return -EDOM;
}
예제 #5
0
static int twl6030reg_enable(struct regulator_dev *rdev)
{
	struct twlreg_info	*info = rdev_get_drvdata(rdev);
	int			grp = 0;
	int			ret;

	if (!(twl_class_is_6030() && (info->features & TWL6032_SUBCLASS)))
		grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP);
	if (grp < 0)
		return grp;

	ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_STATE,
			grp << TWL6030_CFG_STATE_GRP_SHIFT |
			TWL6030_CFG_STATE_ON);
	/*
	 * Ensure it stays in Auto mode when we enter suspend state.
	 * (TWL6030 in sleep mode).
	 */
	if (!ret)
		ret = twl6030reg_set_trans_state(rdev,
				TWL6030_CFG_TRANS_SLEEP_SHIFT,
				TWL6030_CFG_TRANS_STATE_AUTO);
	udelay(info->delay);

	return ret;
}
예제 #6
0
static int twl6030reg_set_trans_state(struct regulator_dev *rdev,
				      u8 shift, u8 val)
{
	struct twlreg_info	*info = rdev_get_drvdata(rdev);
	int			rval;
	u8			mask;

	/* Read CFG_TRANS register of TWL6030 */
	rval = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_TRANS);

	if (rval < 0)
		return rval;

	mask = TWL6030_CFG_TRANS_STATE_MASK << shift;
	val = (val << shift) & mask;

	/* If value is already set, no need to write to reg */
	if (val == (rval & mask))
		return 0;

	rval &= ~mask;
	rval |= val;

	return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_TRANS, rval);
}
예제 #7
0
static int twl6030reg_set_mode(struct regulator_dev *rdev, unsigned mode)
{
	struct twlreg_info	*info = rdev_get_drvdata(rdev);
	int grp = 0;
	int val;

	if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS)))
		grp = twlreg_grp(rdev);

	if (grp < 0)
		return grp;

	/* Compose the state register settings */
	val = grp << TWL6030_CFG_STATE_GRP_SHIFT;
	/* We can only set the mode through state machine commands... */
	switch (mode) {
	case REGULATOR_MODE_NORMAL:
		val |= TWL6030_CFG_STATE_ON;
		break;
	case REGULATOR_MODE_STANDBY:
		val |= TWL6030_CFG_STATE_SLEEP;
		break;

	default:
		return -EINVAL;
	}

	return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_STATE, val);
}
static int
twl4030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
		       unsigned *selector)
{
	struct twlreg_info	*info = rdev_get_drvdata(rdev);
	int			vsel;

	for (vsel = 0; vsel < info->table_len; vsel++) {
		int mV = info->table[vsel];
		int uV;

		if (IS_UNSUP(mV))
			continue;
		uV = LDO_MV(mV) * 1000;

		

		
		if (min_uV <= uV && uV <= max_uV) {
			*selector = vsel;
			return twlreg_write(info, TWL_MODULE_PM_RECEIVER,
							VREG_VOLTAGE, vsel);
		}
	}

	return -EDOM;
}
static int twl6030reg_set_mode(struct regulator_dev *rdev, unsigned mode)
{
	struct twlreg_info	*info = rdev_get_drvdata(rdev);
	int grp = 0;
	int val;

	if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS)))
		grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP);

	if (grp < 0)
		return grp;

	
	val = grp << TWL6030_CFG_STATE_GRP_SHIFT;
	
	switch (mode) {
	case REGULATOR_MODE_NORMAL:
		val |= TWL6030_CFG_STATE_ON;
		break;
	case REGULATOR_MODE_STANDBY:
		val |= TWL6030_CFG_STATE_SLEEP;
		break;

	default:
		return -EINVAL;
	}

	return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_STATE, val);
}
예제 #10
0
static int twl6030smps_set_voltage_sel(struct regulator_dev *rdev,
				       unsigned int selector)
{
	struct twlreg_info *info = rdev_get_drvdata(rdev);

	return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE_SMPS,
			    selector);
}
예제 #11
0
static int
twl4030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
			unsigned *selector)
{
	struct twlreg_info *info = rdev_get_drvdata(rdev);
	int vsel = DIV_ROUND_UP(min_uV - 600000, 12500);

	twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE_SMPS_4030, vsel);

	return 0;
}
static int twl6030_enable(struct regulator_dev *rdev)
{
	struct twlreg_info	*info = rdev_get_drvdata(rdev);
	int			state;
	int			ret;
    state = twlreg_read(info, TWL_MODULE_PM_RECEIVER, 2);
    state |= 1;
	ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, 2 , state);
    state = twlreg_read(info, TWL_MODULE_PM_RECEIVER, 2);
    printk("%s: %s state=0x%x\n",__func__,rdev->desc->name,state);
	udelay(info->delay);
	return ret;
}
static int twl6030reg_set_mode(struct regulator_dev *rdev, unsigned mode)
{
	struct twlreg_info	*info = rdev_get_drvdata(rdev);
	int grp;
	int val = 0;
	int trans_val = 0;

	grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP);

	if (grp < 0)
		return grp;

	trans_val = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_TRANS);
	/* For ACT map to ACT and SLEEP map to AMS */
	trans_val |= (0x1 << TWL6030_CFG_TRANS_SLEEP) |
				(0x3 << TWL6030_CFG_TRANS_ACT);
	trans_val = twlreg_write(info, TWL_MODULE_PM_RECEIVER,
				 VREG_TRANS, trans_val);
	if (trans_val < 0)
		return trans_val;

	/* Compose the state register settings */
	val = grp << TWL6030_CFG_STATE_GRP_SHIFT;
	/* We can only set the mode through state machine commands... */
	switch (mode) {
	case REGULATOR_MODE_NORMAL:
		val |= TWL6030_CFG_STATE_ON;
		break;
	case REGULATOR_MODE_STANDBY:
		val |= TWL6030_CFG_STATE_SLEEP;
		break;

	default:
		return -EINVAL;
	}

	return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_STATE, val);
}
static int
twl6030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
		       unsigned *selector)
{
	struct twlreg_info	*info = rdev_get_drvdata(rdev);
	int			vsel;

	if ((min_uV/1000 < info->min_mV) || (max_uV/1000 > info->max_mV))
		return -EDOM;

	vsel = (min_uV/1000 - 1000)/100 + 1;
	*selector = vsel;
	return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE, vsel);

}
static int twl6030_disable(struct regulator_dev *rdev)
{
	struct twlreg_info	*info = rdev_get_drvdata(rdev);
	int			state;
    int         ret;
	state = twlreg_read(info, TWL_MODULE_PM_RECEIVER, 2);
//	if (state < 0)
//		return state;
    //state &= ~ 3;
    state=0;
    printk("%s: %s state=0x%x\n",__func__,rdev->desc->name,state);
    ret= twlreg_write(info, TWL_MODULE_PM_RECEIVER, 2, 0);

	return ret;
}
static int twlreg_disable(struct regulator_dev *rdev)
{
	struct twlreg_info	*info = rdev_get_drvdata(rdev);
	int			grp;

	grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP);
	if (grp < 0)
		return grp;

	if (twl_class_is_4030())
		grp &= ~(P1_GRP_4030 | P2_GRP_4030 | P3_GRP_4030);
	else
		grp &= ~(P1_GRP_6030 | P2_GRP_6030 | P3_GRP_6030);

	return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp);
}
예제 #17
0
static int twl4030reg_disable(struct regulator_dev *rdev)
{
	struct twlreg_info	*info = rdev_get_drvdata(rdev);
	int			grp;
	int			ret;

	grp = twlreg_grp(rdev);
	if (grp < 0)
		return grp;

	grp &= ~(P1_GRP_4030 | P2_GRP_4030 | P3_GRP_4030);

	ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp);

	return ret;
}
예제 #18
0
static int twl6030reg_disable(struct regulator_dev *rdev)
{
	struct twlreg_info	*info = rdev_get_drvdata(rdev);
	int			grp = 0;
	int			ret;

	if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS)))
		grp = P1_GRP_6030 | P2_GRP_6030 | P3_GRP_6030;

	/* For 6030, set the off state for all grps enabled */
	ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_STATE,
			(grp) << TWL6030_CFG_STATE_GRP_SHIFT |
			TWL6030_CFG_STATE_OFF);

	return ret;
}
예제 #19
0
static int twl6030reg_enable(struct regulator_dev *rdev)
{
	struct twlreg_info	*info = rdev_get_drvdata(rdev);
	int			grp = 0;
	int			ret;

	if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS)))
		grp = twlreg_grp(rdev);
	if (grp < 0)
		return grp;

	ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_STATE,
			grp << TWL6030_CFG_STATE_GRP_SHIFT |
			TWL6030_CFG_STATE_ON);
	return ret;
}
static int
twl6030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV)
{
	struct twlreg_info	*info = rdev_get_drvdata(rdev);
	int			vsel;

	if ((min_uV/1000 < info->min_mV) || (max_uV/1000 > info->max_mV))
		return -EDOM;

	/*
	 * Use the below formula to calculate vsel
	 * mV = 1000mv + 100mv * (vsel - 1)
	 */
	vsel = (min_uV/1000 - 1000)/100 + 1;
	return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE, vsel);

}
static int twlreg_disable(struct regulator_dev *rdev)
{
	struct twlreg_info	*info = rdev_get_drvdata(rdev);
	int			grp;
    int ret;
	grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP);
	if (grp < 0)
		return grp;

	if (twl_class_is_4030())
		grp &= ~(P1_GRP_4030 | P2_GRP_4030 | P3_GRP_4030);
	else
		grp &= ~(P1_GRP_6030 | P2_GRP_6030 | P3_GRP_6030);

    ret= twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp);
printk("%s : %s  info->base=0x%x  grp=0x%x \n",__func__,rdev->desc->name,info->base , grp);
	return ret;
}
예제 #22
0
static int twl4030reg_enable(struct regulator_dev *rdev)
{
	struct twlreg_info	*info = rdev_get_drvdata(rdev);
	int			grp;
	int			ret;

	grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP);
	if (grp < 0)
		return grp;

	grp |= P1_GRP_4030;

	ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp);

	udelay(info->delay);

	return ret;
}
예제 #23
0
static int twl6030reg_disable(struct regulator_dev *rdev)
{
	struct twlreg_info	*info = rdev_get_drvdata(rdev);
	int			grp = 0;
	int			ret;

	if (!(twl_class_is_6030() && (info->features & TWL6032_SUBCLASS)))
		grp = P1_GRP_6030 | P2_GRP_6030 | P3_GRP_6030;

	/* For 6030, set the off state for all grps enabled */
	ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_STATE,
			(grp) << TWL6030_CFG_STATE_GRP_SHIFT |
			TWL6030_CFG_STATE_OFF);

	/* Ensure it remains OFF when we enter suspend (TWL6030 in sleep). */
	if (!ret)
		ret = twl6030reg_set_trans_state(rdev,
				TWL6030_CFG_TRANS_SLEEP_SHIFT,
				TWL6030_CFG_TRANS_STATE_OFF);
	return ret;
}
예제 #24
0
static int
twl6030ldo_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
		       unsigned *selector)
{
	struct twlreg_info	*info = rdev_get_drvdata(rdev);
	int			vsel;

	if ((min_uV/1000 < info->min_mV) || (max_uV/1000 > info->max_mV))
		return -EDOM;

	/*
	 * Use the below formula to calculate vsel
	 * mV = 1000mv + 100mv * (vsel - 1)
	 */
	vsel = (min_uV/1000 - 1000)/100 + 1;
	*selector = vsel;
#ifdef CONFIG_JET_V2
	if(info->base == 0x68) // LDO5
		vsel |= TWL6030_CFG_VOLTAGE_WR_S_BIT;  // WR_S Keep the voltage configuration settings, same VSEL [5:0] value justbefore the warm reset event.
#endif
	return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE, vsel);

}
예제 #25
0
static int __devinit twlreg_probe(struct platform_device *pdev)
{
	int				i;
	struct twlreg_info		*info;
	struct regulator_init_data	*initdata;
	struct regulation_constraints	*c;
	struct regulator_dev		*rdev;
	int ret;

	for (i = 0, info = NULL; i < ARRAY_SIZE(twl_regs); i++) {
		if (twl_regs[i].desc.id != pdev->id)
			continue;
		info = twl_regs + i;
		break;
	}
	if (!info)
		return -ENODEV;

	initdata = pdev->dev.platform_data;
	if (!initdata)
		return -EINVAL;

	/* copy the features into regulator data */
	info->features = (unsigned long)initdata->driver_data;

	/* Constrain board-specific capabilities according to what
	 * this driver and the chip itself can actually do.
	 */
	c = &initdata->constraints;
	c->valid_modes_mask &= REGULATOR_MODE_NORMAL | REGULATOR_MODE_STANDBY;
	c->valid_ops_mask &= REGULATOR_CHANGE_VOLTAGE
				| REGULATOR_CHANGE_MODE
				| REGULATOR_CHANGE_STATUS;
	switch (pdev->id) {
	case TWL4030_REG_VIO:
	case TWL4030_REG_VDD1:
	case TWL4030_REG_VDD2:
	case TWL4030_REG_VPLL1:
	case TWL4030_REG_VINTANA1:
	case TWL4030_REG_VINTANA2:
	case TWL4030_REG_VINTDIG:
		c->always_on = true;
		break;
	case TWL6030_REG_VUSB:
		/* Program CFG_LDO_PD2 register and set VUSB bit */
		ret = twl_i2c_write_u8(TWL6030_MODULE_ID0, 0x1,
				TWL6030_CFG_LDO_PD2);
		if (ret < 0)
			return ret;

		/* Program MISC2 register and set bit VUSB_IN_VBAT */
		ret = twl_i2c_write_u8(TWL6030_MODULE_ID0, 0x10, TWL6030_MISC2);
		if (ret < 0)
			return ret;
		break;
	default:
		break;
	}

	switch (pdev->id) {
	case TWL6032_REG_SMPS3:
		if (twl_get_smps_mult() & SMPS_MULTOFFSET_SMPS3)
			info->flags |= SMPS_EXTENDED_EN;
		if (twl_get_smps_offset() & SMPS_MULTOFFSET_SMPS3)
			info->flags |= SMPS_OFFSET_EN;
		break;
	case TWL6032_REG_SMPS4:
		if (twl_get_smps_mult() & SMPS_MULTOFFSET_SMPS4)
			info->flags |= SMPS_EXTENDED_EN;
		if (twl_get_smps_offset() & SMPS_MULTOFFSET_SMPS4)
			info->flags |= SMPS_OFFSET_EN;
		break;
	case TWL6032_REG_VIO:
		if (twl_get_smps_mult() & SMPS_MULTOFFSET_VIO)
			info->flags |= SMPS_EXTENDED_EN;
		if (twl_get_smps_offset() & SMPS_MULTOFFSET_VIO)
			info->flags |= SMPS_OFFSET_EN;
		break;
	}

	rdev = regulator_register(&info->desc, &pdev->dev, initdata, info);
	if (IS_ERR(rdev)) {
		dev_err(&pdev->dev, "can't register %s, %ld\n",
				info->desc.name, PTR_ERR(rdev));
		return PTR_ERR(rdev);
	}
	platform_set_drvdata(pdev, rdev);

	if (twl_class_is_4030())
		twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_REMAP,
						info->remap);

	/* NOTE:  many regulators support short-circuit IRQs (presentable
	 * as REGULATOR_OVER_CURRENT notifications?) configured via:
	 *  - SC_CONFIG
	 *  - SC_DETECT1 (vintana2, vmmc1/2, vaux1/2/3/4)
	 *  - SC_DETECT2 (vusb, vdac, vio, vdd1/2, vpll2)
	 *  - IT_CONFIG
	 */

	return 0;
}
예제 #26
0
static int __devinit twlreg_probe(struct platform_device *pdev)
{
	int				i, id;
	struct twlreg_info		*info;
	struct regulator_init_data	*initdata;
	struct regulation_constraints	*c;
	struct regulator_dev		*rdev;
	struct twl_regulator_driver_data	*drvdata;
	const struct of_device_id	*match;
	u32 twl_errata = 0;

	match = of_match_device(twl_of_match, &pdev->dev);
	if (match) {
		info = match->data;
		id = info->desc.id;
		initdata = of_get_regulator_init_data(&pdev->dev,
						      pdev->dev.of_node);
		drvdata = NULL;
	} else {
		id = pdev->id;
		initdata = pdev->dev.platform_data;
		for (i = 0, info = NULL; i < ARRAY_SIZE(twl_of_match); i++) {
			info = twl_of_match[i].data;
			if (!info || info->desc.id != id)
				continue;
			break;
		}
		drvdata = initdata->driver_data;
		if (!drvdata)
			return -EINVAL;
	}

	if (!info)
		return -ENODEV;

	if (!initdata)
		return -EINVAL;

	if (drvdata) {
		/* copy the driver data into regulator data */
		info->features = drvdata->features;
		twl_errata = drvdata->errata;
		info->data = drvdata->data;
		info->set_voltage = drvdata->set_voltage;
		info->get_voltage = drvdata->get_voltage;
	}

	/* Constrain board-specific capabilities according to what
	 * this driver and the chip itself can actually do.
	 */
	c = &initdata->constraints;
	c->valid_modes_mask &= REGULATOR_MODE_NORMAL | REGULATOR_MODE_STANDBY;
	c->valid_ops_mask &= REGULATOR_CHANGE_VOLTAGE
				| REGULATOR_CHANGE_MODE
				| REGULATOR_CHANGE_STATUS;
	switch (id) {
	case TWL4030_REG_VIO:
	case TWL4030_REG_VDD1:
	case TWL4030_REG_VDD2:
	case TWL4030_REG_VPLL1:
	case TWL4030_REG_VINTANA1:
	case TWL4030_REG_VINTANA2:
	case TWL4030_REG_VINTDIG:
		c->always_on = true;
		break;
	default:
		break;
	}

	switch (id) {
	case TWL6032_REG_SMPS3:
		if (twl_get_smps_mult() & SMPS_MULTOFFSET_SMPS3)
			info->flags |= SMPS_EXTENDED_EN;
		if (twl_get_smps_offset() & SMPS_MULTOFFSET_SMPS3)
			info->flags |= SMPS_OFFSET_EN;
		break;
	case TWL6032_REG_SMPS4:
		if (twl_get_smps_mult() & SMPS_MULTOFFSET_SMPS4)
			info->flags |= SMPS_EXTENDED_EN;
		if (twl_get_smps_offset() & SMPS_MULTOFFSET_SMPS4)
			info->flags |= SMPS_OFFSET_EN;
		break;
	case TWL6032_REG_VIO:
		if (twl_get_smps_mult() & SMPS_MULTOFFSET_VIO)
			info->flags |= SMPS_EXTENDED_EN;
		if (twl_get_smps_offset() & SMPS_MULTOFFSET_VIO)
			info->flags |= SMPS_OFFSET_EN;
		break;
	case TWL6030_REG_SYSEN:
	case TWL6032_REG_LDO6:
	case TWL6032_REG_LDOLN:
		if (twl_errata & TWL6032_ERRATA_LDO_MUST_BE_ALWAYS_ON) {
			c->state_mem.enabled = true;
			c->state_mem.disabled = false;
		}
		break;
	}

	rdev = regulator_register(&info->desc, &pdev->dev, initdata, info,
							pdev->dev.of_node);
	if (IS_ERR(rdev)) {
		dev_err(&pdev->dev, "can't register %s, %ld\n",
				info->desc.name, PTR_ERR(rdev));
		return PTR_ERR(rdev);
	}
	platform_set_drvdata(pdev, rdev);

	if (twl_class_is_4030())
		twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_REMAP,
						info->remap);

	/* NOTE:  many regulators support short-circuit IRQs (presentable
	 * as REGULATOR_OVER_CURRENT notifications?) configured via:
	 *  - SC_CONFIG
	 *  - SC_DETECT1 (vintana2, vmmc1/2, vaux1/2/3/4)
	 *  - SC_DETECT2 (vusb, vdac, vio, vdd1/2, vpll2)
	 *  - IT_CONFIG
	 */

	return 0;
}
static int __devinit twlreg_probe(struct platform_device *pdev)
{
	int				i;
	struct twlreg_info		*info;
	struct regulator_init_data	*initdata;
	struct regulation_constraints	*c;
	struct regulator_dev		*rdev;

	for (i = 0, info = NULL; i < ARRAY_SIZE(twl_regs); i++) {
		if (twl_regs[i].desc.id != pdev->id)
			continue;
		info = twl_regs + i;
		break;
	}
	if (!info)
		return -ENODEV;

	initdata = pdev->dev.platform_data;
	if (!initdata)
		return -EINVAL;

	/* Constrain board-specific capabilities according to what
	 * this driver and the chip itself can actually do.
	 */
	c = &initdata->constraints;
	c->valid_modes_mask &= REGULATOR_MODE_NORMAL | REGULATOR_MODE_STANDBY;
	c->valid_ops_mask &= REGULATOR_CHANGE_VOLTAGE
				| REGULATOR_CHANGE_MODE
				| REGULATOR_CHANGE_STATUS;
	switch (pdev->id) {
	case TWL4030_REG_VIO:
	case TWL4030_REG_VDD1:
	case TWL4030_REG_VDD2:
	case TWL4030_REG_VPLL1:
	case TWL4030_REG_VINTANA1:
	case TWL4030_REG_VINTANA2:
	case TWL4030_REG_VINTDIG:
		c->always_on = true;
		break;
	/*
	 * TODO: This is needed for a Phoenix ES1.0 Errata.
	 * Once, ES check for Phoenix is implemented. Make
	 * this conditional only for ES1.
	 */
	case TWL6030_REG_VAUX3_6030:
		/* Set duty-cycle to 100% */
		twl_i2c_write_u8(TWL6030_MODULE_ID1, 0, TWL6030_VIBCTRL);
		/* Enable the Vibrator driver */
		twl_i2c_write_u8(TWL6030_MODULE_ID1, 128, TWL6030_TOGGLE2);
		break;
	default:
		break;
	}

	rdev = regulator_register(&info->desc, &pdev->dev, initdata, info);
	if (IS_ERR(rdev)) {
		dev_err(&pdev->dev, "can't register %s, %ld\n",
				info->desc.name, PTR_ERR(rdev));
		return PTR_ERR(rdev);
	}
	platform_set_drvdata(pdev, rdev);

	if (twl_class_is_4030())
		twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_REMAP,
						info->remap);

	/* NOTE:  many regulators support short-circuit IRQs (presentable
	 * as REGULATOR_OVER_CURRENT notifications?) configured via:
	 *  - SC_CONFIG
	 *  - SC_DETECT1 (vintana2, vmmc1/2, vaux1/2/3/4)
	 *  - SC_DETECT2 (vusb, vdac, vio, vdd1/2, vpll2)
	 *  - IT_CONFIG
	 */

	return 0;
}
예제 #28
0
static int
twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
			unsigned int *selector)
{
	struct twlreg_info	*info = rdev_get_drvdata(rdev);
	int	vsel = 0;

	switch (info->flags) {
	case 0:
		if (min_uV == 0)
			vsel = 0;
		else if ((min_uV >= 600000) && (min_uV <= 1300000)) {
			int calc_uV;
			vsel = (min_uV - 600000) / 125;
			if (vsel % 100)
				vsel += 100;
			vsel /= 100;
			vsel++;
			calc_uV = twl6030smps_list_voltage(rdev, vsel);
			if (calc_uV > max_uV)
				return -EINVAL;
		}
		/* Values 1..57 for vsel are linear and can be calculated
		 * values 58..62 are non linear.
		 */
		else if ((min_uV > 1900000) && (max_uV >= 2100000))
			vsel = 62;
		else if ((min_uV > 1800000) && (max_uV >= 1900000))
			vsel = 61;
		else if ((min_uV > 1500000) && (max_uV >= 1800000))
			vsel = 60;
		else if ((min_uV > 1350000) && (max_uV >= 1500000))
			vsel = 59;
		else if ((min_uV > 1300000) && (max_uV >= 1350000))
			vsel = 58;
		else
			return -EINVAL;
		break;
	case SMPS_OFFSET_EN:
		if (min_uV == 0)
			vsel = 0;
		else if ((min_uV >= 700000) && (min_uV <= 1420000)) {
			int calc_uV;
			vsel = (min_uV - 700000) / 125;
			if (vsel % 100)
				vsel += 100;
			vsel /= 100;
			vsel++;
			calc_uV = twl6030smps_list_voltage(rdev, vsel);
			if (calc_uV > max_uV)
				return -EINVAL;
		}
		/* Values 1..57 for vsel are linear and can be calculated
		 * values 58..62 are non linear.
		 */
		else if ((min_uV > 1900000) && (max_uV >= 2100000))
			vsel = 62;
		else if ((min_uV > 1800000) && (max_uV >= 1900000))
			vsel = 61;
		else if ((min_uV > 1350000) && (max_uV >= 1800000))
			vsel = 60;
		else if ((min_uV > 1350000) && (max_uV >= 1500000))
			vsel = 59;
		else if ((min_uV > 1300000) && (max_uV >= 1350000))
			vsel = 58;
		else
			return -EINVAL;
		break;
	case SMPS_EXTENDED_EN:
		if (min_uV == 0)
			vsel = 0;
		else if ((min_uV >= 1852000) && (max_uV <= 4013600)) {
			vsel = (min_uV - 1852000) / 386;
			if (vsel % 100)
				vsel += 100;
			vsel /= 100;
			vsel++;
		}
		break;
	case SMPS_OFFSET_EN|SMPS_EXTENDED_EN:
		if (min_uV == 0)
			vsel = 0;
		else if ((min_uV >= 2161000) && (max_uV <= 4321000)) {
			vsel = (min_uV - 2161000) / 386;
			if (vsel % 100)
				vsel += 100;
			vsel /= 100;
			vsel++;
		}
		break;
	}

	*selector = vsel;

	return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE_SMPS,
							vsel);
}
static int __devinit twlreg_probe(struct platform_device *pdev)
{
	int				i;
	struct twlreg_info		*info;
	struct regulator_init_data	*initdata;
	struct regulation_constraints	*c;
	struct regulator_dev		*rdev;

	for (i = 0, info = NULL; i < ARRAY_SIZE(twl_regs); i++) {
		if (twl_regs[i].desc.id != pdev->id)
			continue;
		info = twl_regs + i;
		break;
	}
	if (!info)
		return -ENODEV;

	initdata = pdev->dev.platform_data;
	if (!initdata)
		return -EINVAL;

	/* Constrain board-specific capabilities according to what
	 * this driver and the chip itself can actually do.
	 */
	c = &initdata->constraints;
	c->valid_modes_mask &= REGULATOR_MODE_NORMAL | REGULATOR_MODE_STANDBY;
	c->valid_ops_mask &= REGULATOR_CHANGE_VOLTAGE
				| REGULATOR_CHANGE_MODE
				| REGULATOR_CHANGE_STATUS;
	switch (pdev->id) {
	case TWL4030_REG_VIO:
	case TWL4030_REG_VDD1:
	case TWL4030_REG_VDD2:
	case TWL4030_REG_VPLL1:
	case TWL4030_REG_VINTANA1:
	case TWL4030_REG_VINTANA2:
	case TWL4030_REG_VINTDIG:
		c->always_on = true;
		break;
	default:
		break;
	}

	rdev = regulator_register(&info->desc, &pdev->dev, initdata, info);
	if (IS_ERR(rdev)) {
		dev_err(&pdev->dev, "can't register %s, %ld\n",
				info->desc.name, PTR_ERR(rdev));
		return PTR_ERR(rdev);
	}
	platform_set_drvdata(pdev, rdev);

	twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_REMAP,
						info->remap);

	/* NOTE:  many regulators support short-circuit IRQs (presentable
	 * as REGULATOR_OVER_CURRENT notifications?) configured via:
	 *  - SC_CONFIG
	 *  - SC_DETECT1 (vintana2, vmmc1/2, vaux1/2/3/4)
	 *  - SC_DETECT2 (vusb, vdac, vio, vdd1/2, vpll2)
	 *  - IT_CONFIG
	 */

	return 0;
}
static int __devinit twlreg_probe(struct platform_device *pdev)
{
	int				i, id;
	struct twlreg_info		*info;
	struct regulator_init_data	*initdata;
	struct regulation_constraints	*c;
	struct regulator_dev		*rdev;
	struct twl_regulator_driver_data	*drvdata;
	const struct of_device_id	*match;

	match = of_match_device(twl_of_match, &pdev->dev);
	if (match) {
		info = match->data;
		id = info->desc.id;
		initdata = of_get_regulator_init_data(&pdev->dev,
						      pdev->dev.of_node);
		drvdata = NULL;
	} else {
		id = pdev->id;
		initdata = pdev->dev.platform_data;
		for (i = 0, info = NULL; i < ARRAY_SIZE(twl_of_match); i++) {
			info = twl_of_match[i].data;
			if (!info || info->desc.id != id)
				continue;
			break;
		}
		drvdata = initdata->driver_data;
		if (!drvdata)
			return -EINVAL;
	}

	if (!info)
		return -ENODEV;

	if (!initdata)
		return -EINVAL;

	if (drvdata) {
		
		info->features = drvdata->features;
		info->data = drvdata->data;
		info->set_voltage = drvdata->set_voltage;
		info->get_voltage = drvdata->get_voltage;
	}

	c = &initdata->constraints;
	c->valid_modes_mask &= REGULATOR_MODE_NORMAL | REGULATOR_MODE_STANDBY;
	c->valid_ops_mask &= REGULATOR_CHANGE_VOLTAGE
				| REGULATOR_CHANGE_MODE
				| REGULATOR_CHANGE_STATUS;
	switch (id) {
	case TWL4030_REG_VIO:
	case TWL4030_REG_VDD1:
	case TWL4030_REG_VDD2:
	case TWL4030_REG_VPLL1:
	case TWL4030_REG_VINTANA1:
	case TWL4030_REG_VINTANA2:
	case TWL4030_REG_VINTDIG:
		c->always_on = true;
		break;
	default:
		break;
	}

	switch (id) {
	case TWL6025_REG_SMPS3:
		if (twl_get_smps_mult() & SMPS_MULTOFFSET_SMPS3)
			info->flags |= SMPS_EXTENDED_EN;
		if (twl_get_smps_offset() & SMPS_MULTOFFSET_SMPS3)
			info->flags |= SMPS_OFFSET_EN;
		break;
	case TWL6025_REG_SMPS4:
		if (twl_get_smps_mult() & SMPS_MULTOFFSET_SMPS4)
			info->flags |= SMPS_EXTENDED_EN;
		if (twl_get_smps_offset() & SMPS_MULTOFFSET_SMPS4)
			info->flags |= SMPS_OFFSET_EN;
		break;
	case TWL6025_REG_VIO:
		if (twl_get_smps_mult() & SMPS_MULTOFFSET_VIO)
			info->flags |= SMPS_EXTENDED_EN;
		if (twl_get_smps_offset() & SMPS_MULTOFFSET_VIO)
			info->flags |= SMPS_OFFSET_EN;
		break;
	}

	rdev = regulator_register(&info->desc, &pdev->dev, initdata, info,
							pdev->dev.of_node);
	if (IS_ERR(rdev)) {
		dev_err(&pdev->dev, "can't register %s, %ld\n",
				info->desc.name, PTR_ERR(rdev));
		return PTR_ERR(rdev);
	}
	platform_set_drvdata(pdev, rdev);

	if (twl_class_is_4030())
		twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_REMAP,
						info->remap);


	return 0;
}