Beispiel #1
0
static int d2041_regulator_disable(struct regulator_dev *rdev)
{
    struct d2041 *d2041 = rdev_get_drvdata(rdev);
    unsigned int regulator_id = rdev_get_id(rdev);
    unsigned int reg_num = 0;
    int ret = 0;
    u8 reg_val;

    if (regulator_id >= D2041_NUMBER_OF_REGULATORS)
        return -EINVAL;

	if(!is_mode_control_enabled()){
	
		reg_num = get_regulator_reg(regulator_id);
		
		d2041_reg_read(d2041, reg_num, &reg_val);
		reg_val &= ~(1<<6);
		d2041_reg_write(d2041, reg_num, reg_val);
	}else{

    reg_num = get_regulator_mctl_reg(regulator_id);
    /* 0x00 ==  D2041_REGULATOR_MCTL0_OFF | D2041_REGULATOR_MCTL1_OFF 
     *        | D2041_REGULATOR_MCTL2_OFF | D2041_REGULATOR_MCTL3_OFF 
     */

    ret = d2041_reg_write(d2041, reg_num, 0x00);

	}

    return ret;
}
Beispiel #2
0
static unsigned int get_regulator_mctl_mode(struct d2041 *d2041, int regulator_id)
{
    //TODO: Make sure we can assume we have always current value in the buffer and do this:
    u8 reg_val, regulator_mctl_reg = get_regulator_mctl_reg(regulator_id);
    int ret = 0;

    ret = d2041_reg_read(d2041, regulator_mctl_reg, &reg_val);
    reg_val &= D2041_REGULATOR_MCTL0;
    reg_val >>= MCTL0_SHIFT;
    
    return reg_val;
 }
Beispiel #3
0
int __init d2041_platform_regulator_init(struct d2041 *d2041)
{
    int i;
    u8 reg_val=0;

    for(i = D2041_BUCK_1; i < D2041_NUMBER_OF_REGULATORS; i++) {
        if (d2041->pdata != NULL &&
	    d2041->pdata->regulator_data != NULL &&
  	    d2041->pdata->regulator_data[i].supply != NULL) {
  	    
		d2041_regulators_init_data[i].consumer_supplies = &d2041->pdata->regulator_data[i];
		d2041_regulators_init_data[i].num_consumer_supplies = 1;

		dev_info(d2041->dev, "No consumers for regulator %s\n",
			d2041_regulators_init_data[i].constraints.name);
		}
		
        d2041_register_regulator(d2041, i, &(d2041_regulators_init_data[i]));
        regulator_register_map[i].dsm_opmode = d2041->pdata->regl_map[i].default_pm_mode;
		
        if(i >= D2041_BUCK_1) {
            d2041_reg_write(d2041, get_regulator_mctl_reg(i),
							d2041->pdata->regl_map[i].dsm_opmode);
        }
    }

	// set MISC_MCTL
	/*
	reg_val = (D2041_MISC_MCTL3_DIGICLK | D2041_MISC_MCTL2_DIGICLK |
			   D2041_MISC_MCTL1_DIGICLK | D2041_MISC_MCTL0_DIGICLK |
		       D2041_MISC_MCTL3_BBAT | D2041_MISC_MCTL2_BBAT |
			   D2041_MISC_MCTL1_BBAT | D2041_MISC_MCTL0_BBAT);
		*/
	reg_val = 0x0F;
	d2041_reg_write(d2041_regl_info, D2041_MISC_MCTL_REG, reg_val);

	d2041_reg_write(d2041_regl_info, D2041_BUCK1_TURBO_REG, D2041_BUCK1_NM_VOLT);
	d2041_reg_write(d2041_regl_info, D2041_BUCK1_RETENTION_REG, D2041_BUCK1_RETENTION_VOLT);

	// set AUD_LDO to 2.5v
	d2041_reg_write(d2041_regl_info, D2041_LDO_AUD_REG, 0x5A);

	// sim_vcc(LDO11) -> default 1.8v
	d2041_reg_write(d2041_regl_info, D2041_LDO11_REG, 0xC);

	// LDO_AUD pull-down disable
	d2041_reg_write(d2041_regl_info, D2041_PULLDOWN_REG_D, (1<<0));

    return 0;
}
Beispiel #4
0
static int d2041_regulator_enable(struct regulator_dev *rdev)
{
    struct d2041 *d2041 = rdev_get_drvdata(rdev);
    u8 reg_val;
    int ret = 0;
    unsigned int regulator_id = rdev_get_id(rdev);
    unsigned int reg_num;

    if (regulator_id >= D2041_NUMBER_OF_REGULATORS)
        return -EINVAL;

	if(!is_mode_control_enabled()){
		reg_num = get_regulator_reg(regulator_id);
		
		d2041_reg_read(d2041, reg_num, &reg_val);
		reg_val |= (1<<6);
		ret = d2041_reg_write(d2041, reg_num,reg_val);

	}else {
    reg_num = get_regulator_mctl_reg(regulator_id);
	    
    ret = d2041_reg_read(d2041, reg_num, &reg_val);
    if(ret < 0) {
        dlg_err("I2C read error\n");
        return ret;
    }

    reg_val &= ~(D2041_REGULATOR_MCTL1 | D2041_REGULATOR_MCTL3);   // Clear MCTL11 and MCTL01
    reg_val |= (D2041_REGULATOR_MCTL1_ON | D2041_REGULATOR_MCTL3_ON);

    switch(get_regulator_dsm_opmode(regulator_id)) {
        case D2041_REGULATOR_LPM_IN_DSM :
            reg_val &= ~(D2041_REGULATOR_MCTL0 | D2041_REGULATOR_MCTL2);
            reg_val |= (D2041_REGULATOR_MCTL0_SLEEP | D2041_REGULATOR_MCTL2_SLEEP);
            break;
        case D2041_REGULATOR_OFF_IN_DSM :
            reg_val &= ~(D2041_REGULATOR_MCTL0 | D2041_REGULATOR_MCTL2);
            break;
        case D2041_REGULATOR_ON_IN_DSM :
            reg_val &= ~(D2041_REGULATOR_MCTL0 | D2041_REGULATOR_MCTL2);
            reg_val |= (D2041_REGULATOR_MCTL0_ON | D2041_REGULATOR_MCTL2_ON);
            break;
    }

    ret |= d2041_reg_write(d2041, reg_num, reg_val);
	}

    return ret;
}
Beispiel #5
0
static int set_regulator_mctl_mode(struct d2041 *d2041, int regulator_id, u8 mode)
{
    u8 reg_val, mctl_reg;
    int ret = 0;

    if(regulator_id < 0 || regulator_id >= D2041_NUMBER_OF_REGULATORS)
        return -EINVAL;
    if(mode > REGULATOR_MCTL_TURBO)
        return -EINVAL;

    mctl_reg = get_regulator_mctl_reg(regulator_id);
    ret = d2041_reg_read(d2041, mctl_reg, &reg_val);
    if(ret < 0)
        return ret;

    reg_val &= ~(D2041_REGULATOR_MCTL0 | D2041_REGULATOR_MCTL2);
    reg_val |= ((mode << MCTL0_SHIFT) | ( mode << MCTL2_SHIFT));
    ret = d2041_reg_write(d2041, mctl_reg, reg_val);
    dlg_info("[REGULATOR] %s. reg_val = 0x%X\n", __func__, reg_val);

    return ret;
}
Beispiel #6
0
// TODO MW: consider use of kernel parameters to override defaults/boot loader settings
//TBD
static void d2041_configure_mctl(struct d2041 *d2041, struct regulator_dev *rdev)
{
//TODO MW check and test this code ! Find out this is the bahaviour we want.
    int mV_val = 0;
    u8 misc_mctlv = 0;
    int i;

    /* WARNING: we assume here that once configured, MCTL registers content doesn't change !
     * If there is any change to MCTL registers during kernel runtime,
     * the regulator_mctl[] table MUST also be updated !
     */

    if (is_mctl_preconfigured() == true)  { /* MCTL configured before (preasumably by BL code) */
        for (i = D2041_BUCK_1; i < D2041_NUMBER_OF_REGULATORS; i++) {
            /* Just copy all mctl registers to the buffer */
            d2041_reg_read((d2041, get_regulator_mctl_reg(i), &regulator_mctl[i]);
         }
    } else { /* MCTL NOT preconfigured */
        /* Use predefined defaults
         * TODO MW: Those settings should  be customized for specific platform
         */
        for (i = D2041_BUCK_1; i < D2041_NUMBER_OF_REGULATORS; i++) {
Beispiel #7
0
static int d2041_regulator_is_enabled(struct regulator_dev *rdev)
{
    struct d2041 *d2041 = rdev_get_drvdata(rdev);
    unsigned int reg_num, regulator_id = rdev_get_id(rdev);
    int ret = -EINVAL;
    u8 reg_val = 0;

	if(!is_mode_control_enabled()){

		reg_num = get_regulator_reg(regulator_id);
		
	    ret = d2041_reg_read(d2041, reg_num, &reg_val);
	    if(ret < 0) {
	        dlg_err("I2C read error. \n");
	        return ret;
	    }

		/* 0x0 : off, 0x1 : on */
		ret = reg_val & (1<<6);
	}else{
    if (regulator_id >= D2041_NUMBER_OF_REGULATORS)
        return -EINVAL;

    reg_num = get_regulator_mctl_reg(regulator_id);
    ret = d2041_reg_read(d2041, reg_num, &reg_val);
    if(ret < 0) {
        dlg_err("I2C read error. \n");
        return ret;
    }

    /* 0x0 : Off    * 0x1 : On    * 0x2 : Sleep    * 0x3 : n/a */
		ret = ((reg_val & (D2041_REGULATOR_MCTL1|D2041_REGULATOR_MCTL3)) >= 1) ? 1 : 0;
	}

    return ret;
}
int __init d2083_platform_regulator_init(struct d2083 *d2083)
{
	int i;
	u8 reg_val=0;

#if 1	//todo
	struct d2083_regl_init_data *regl_data = d2083->pdata->regulator_data;

	if(regl_data == NULL)
		return -1;

	for(i = D2083_BUCK_1; i < D2083_NUMBER_OF_REGULATORS; i++) {
		d2083_register_regulator(d2083, i, (regl_data + i)->initdata);
		
		regulator_register_map[i].dsm_opmode = d2083->pdata->regl_map[i].default_pm_mode;

		if(i >= D2083_BUCK_1) {
			d2083_reg_write(d2083, get_regulator_mctl_reg(i),
			d2083->pdata->regl_map[i].dsm_opmode);
		}
	}
#else
	for(i = D2083_BUCK_1; i < D2083_NUMBER_OF_REGULATORS; i++) {
		if (d2083->pdata != NULL &&
		d2083->pdata->regulator_data != NULL &&
		d2083->pdata->regulator_data[i].supply != NULL) {

			d2083_regulators_init_data[i].consumer_supplies = &d2083->pdata->regulator_data[i];
			d2083_regulators_init_data[i].num_consumer_supplies = 1;

			dev_info(d2083->dev, "No consumers for regulator %s\n",
			d2083_regulators_init_data[i].constraints.name);
		}

		d2083_register_regulator(d2083, i, &(d2083_regulators_init_data[i]));
		regulator_register_map[i].dsm_opmode = d2083->pdata->regl_map[i].default_pm_mode;

		if(i >= D2083_BUCK_1) {
			d2083_reg_write(d2083, get_regulator_mctl_reg(i),
			d2083->pdata->regl_map[i].dsm_opmode);
		}
	}
#endif

	// ******************************************************************************

	// set MISC_MCTL
	/*
	reg_val = (D2083_MISC_MCTL3_DIGICLK | D2083_MISC_MCTL2_DIGICLK |
	D2083_MISC_MCTL1_DIGICLK | D2083_MISC_MCTL0_DIGICLK |
	D2083_MISC_MCTL3_BBAT | D2083_MISC_MCTL2_BBAT |
	D2083_MISC_MCTL1_BBAT | D2083_MISC_MCTL0_BBAT);
	*/
	reg_val = 0x0F;
	d2083_reg_write(d2083_regl_info, D2083_MISC_MCTL_REG, reg_val);

	// 	GPADC MTCL default
	reg_val = 0x55;	// 0x55 -> 01 | 01 | 01 | 01 (01 -> On if already enabled)
	d2083_reg_write(d2083_regl_info, D2083_GPADC_MCTL_REG, reg_val);

	d2083_reg_write(d2083_regl_info, D2083_BUCK1_TURBO_REG, D2083_BUCK1_NM_VOLT);
	d2083_reg_write(d2083_regl_info, D2083_BUCK1_RETENTION_REG, D2083_BUCK1_RETENTION_VOLT);

	d2083_reg_write(d2083_regl_info, D2083_BUCK3_REG, 0x4C);	// BUCK3 : 1.23v -> 1.225v

	// set AUD_LDO to 2.5v
	d2083_reg_write(d2083_regl_info, D2083_LDO_AUD_REG, 0x5A);
	// set LDO to 1.8v
	d2083_reg_write(d2083_regl_info, D2083_LDO1_REG, 0x4C);

	// sim_vcc(LDO11) -> default 1.8v
	//d2083_reg_write(d2083_regl_info, D2083_LDO11_REG, 0xC);

	// LDO_AUD pull-down disable
	d2083_reg_write(d2083_regl_info, D2083_PULLDOWN_REG_D, (1<<0));

	// ******************************************************************************

	return 0;
}