Esempio n. 1
0
int d2083_audio_hs_preamp_gain(enum d2083_preamp_gain_val hsgain_val)
{
	u8 regval = 0;
	int ret = 0;

	dlg_info("d2083_audio_hs_preamp_gain hs_pre_gain=0x%x \n",hsgain_val);
	//if(0 <  hsgain_val && D2083_PREAMP_GAIN_MUTE > hsgain_val ) 
		//dlg_audio->hs_pre_gain = hsgain_val;

	if(0 >  hsgain_val || D2083_PREAMP_GAIN_MUTE < hsgain_val ) {
		dlg_info("[%s]- Invalid preamp gain, so set to 0dB \n", __func__);
		hsgain_val = D2083_PREAMP_GAIN_0DB;				
	}

	if(dlg_audio->HSenabled==true)
	{
#ifdef USE_AUDIO_DIFFERENTIAL
		if(!dlg_audio->IHFenabled) 
		{
			regval = audio_read(D2083_PREAMP_A_CTRL1_REG) & ~D2083_PREAMP_VOL;
			regval |= (hsgain_val << D2083_PREAMP_VOL_SHIFT) & D2083_PREAMP_VOL;
			ret = audio_write(D2083_PREAMP_A_CTRL1_REG,regval);
		}
#endif		
		regval = audio_read(D2083_PREAMP_B_CTRL1_REG) & ~D2083_PREAMP_VOL;
		regval |= (hsgain_val << D2083_PREAMP_VOL_SHIFT) & D2083_PREAMP_VOL;
		ret = audio_write(D2083_PREAMP_B_CTRL1_REG,regval);
	}
	dlg_audio->hs_pre_gain = hsgain_val;

	return ret;
}
Esempio n. 2
0
int d2083_audio_hs_set_gain(enum d2083_audio_output_sel hs_path_sel, enum d2083_hp_vol_val hs_gain_val)
{
	int ret = 0;
	u8 regval;
	
	if(D2083_HPVOL_NEG_57DB > hs_gain_val || D2083_HPVOL_MUTE < hs_gain_val) {
		dlg_info("[%s]- Invalid gain, so set to -1dB \n", __func__);
		hs_gain_val = D2083_HPVOL_NEG_1DB;				
	}
	
	dlg_info("d2083_audio_hs_set_gain path=%d hs_pga_gain=0x%x \n", hs_path_sel, hs_gain_val);
	
	if(dlg_audio->HSenabled==true)
	{
		if (hs_path_sel & D2083_OUT_HPL) 
		{
			regval = audio_read(D2083_HP_L_GAIN_REG) & ~D2042_HP_AMP_GAIN;
			ret |= audio_write(D2083_HP_L_GAIN_REG, regval | (hs_gain_val & D2042_HP_AMP_GAIN));
			ret |= audio_clear_bits(D2083_HP_L_CTRL_REG, D2083_HP_AMP_MUTE_EN);
		}

		if (hs_path_sel & D2083_OUT_HPR) 
		{
			regval = audio_read(D2083_HP_R_GAIN_REG) & ~D2042_HP_AMP_GAIN;
			ret |= audio_write(D2083_HP_R_GAIN_REG, regval | (hs_gain_val & D2042_HP_AMP_GAIN));
			ret |= audio_clear_bits(D2083_HP_R_CTRL_REG, D2083_HP_AMP_MUTE_EN);
		}            

	}
	dlg_audio->hs_pga_gain=hs_gain_val;

	return ret;
}
static ssize_t d2083_ioctl_write(struct file *file, const char __user *buffer,
	size_t len, loff_t *offset)
{
	struct d2083 *d2083 = file->private_data;
	struct pmu_debug dbg;
	char cmd[MAX_USER_INPUT_LEN];
	int ret, i;

	dlg_info("%s\n", __func__);

	if (!d2083) {
		dlg_err("%s: driver not initialized\n", __func__);
		return -EINVAL;
	}

	if (len > MAX_USER_INPUT_LEN)
		len = MAX_USER_INPUT_LEN;

	if (copy_from_user(cmd, buffer, len)) {
		dlg_err("%s: copy_from_user failed\n", __func__);
		return -EFAULT;
	}

	/* chop of '\n' introduced by echo at the end of the input */
	if (cmd[len - 1] == '\n')
		cmd[len - 1] = '\0';

	if (d2083_dbg_parse_args(cmd, &dbg) < 0) {
		d2083_dbg_usage();
		return -EINVAL;
	}

	dlg_info("operation: %s\n", (dbg.read_write == PMUDBG_READ_REG) ?
		"read" : "write");
	dlg_info("address  : 0x%x\n", dbg.addr);
	dlg_info("length   : %d\n", dbg.len);

	if (dbg.read_write == PMUDBG_READ_REG) {
		ret = d2083_read(d2083, dbg.addr, dbg.len, dbg.val);
		if (ret < 0) {
			dlg_err("%s: pmu reg read failed\n", __func__);
			return -EFAULT;
		}

		for (i = 0; i < dbg.len; i++, dbg.addr++)
			dlg_info("[%x] = 0x%02x\n", dbg.addr,
				dbg.val[i]);
	} else {
		ret = d2083_write(d2083, dbg.addr, dbg.len, dbg.val);
		if (ret < 0) {
			dlg_err("%s: pmu reg write failed\n", __func__);
			return -EFAULT;
		}
	}

	*offset += len;

	return len;
}
Esempio n. 4
0
int d2083_audio_hs_ihf_poweroff(void)
{
	int ret = 0;
	u8 regval;

	if(ihf_power_status ==0){
		return ret;
	}
	ihf_power_status = 0;
	dlg_info("%s, HP =%d, status:%d \n", __func__,dlg_audio->HSenabled,ihf_power_status);

	audio_write(D2083_SP_CTRL_REG,0x32);

#ifdef USE_AUDIO_DIFFERENTIAL
	if (dlg_audio->HSenabled == false) 
#endif
	{
		regval = audio_read(D2083_PREAMP_A_CTRL1_REG) & ~D2083_PREAMP_VOL;
		regval |= (D2083_PREAMP_MUTE);
		regval &= (~D2083_PREAMP_EN);
		ret |= audio_write(D2083_PREAMP_A_CTRL1_REG,regval);
	}

	audio_write(D2083_SP_PWR_REG, 0x00);
	audio_write(D2083_SP_NON_CLIP_ZC_REG, 0x00);
	audio_write(D2083_SP_NON_CLIP_REG, 0x00);
	audio_write(D2083_SP_NG1_REG, 0x00);
	audio_write(D2083_SP_NG2_REG, 0x00);
	
	dlg_audio->IHFenabled = false;
	//if(dlg_audio->HSenabled==false)
	//    audio_write(D2083_LDO_AUD_MCTL_REG, 0x00); //AUD_LDO off

	return ret;
}
Esempio n. 5
0
static unsigned int d2041_regulator_get_mode(struct regulator_dev *rdev)
{
    struct d2041 *d2041 = rdev_get_drvdata(rdev);
    unsigned int regulator_id = rdev_get_id(rdev);
    unsigned int mode = 0;

    if (regulator_id >= D2041_NUMBER_OF_REGULATORS)
            return -EINVAL;

    mode = get_regulator_mctl_mode(d2041, regulator_id);

    /* Map d2041 regulator mode to Linux framework mode */
    switch(mode) {
        case REGULATOR_MCTL_TURBO:
            mode = REGULATOR_MODE_FAST;
            break;
        case REGULATOR_MCTL_ON:
            mode = REGULATOR_MODE_NORMAL;
            break;
        case REGULATOR_MCTL_SLEEP:
            mode = REGULATOR_MODE_IDLE;
            break;
        case REGULATOR_MCTL_OFF:
            mode = REGULATOR_MODE_STANDBY;
            break;
        default:
            /* unsupported or unknown mode */
            break;
    }

    dlg_info("[REGULATOR] : [%s] >> MODE(%d)\n", __func__, mode);

    return mode;
}
Esempio n. 6
0
/*
TODO
Set mode is it software controlled?
if yes then following implementation is useful ??
if no then we dont need following implementation ??
*/
static int d2041_regulator_set_mode(struct regulator_dev *rdev, unsigned int mode)
{
    struct d2041 *d2041 = rdev_get_drvdata(rdev);
    unsigned int regulator_id = rdev_get_id(rdev);
    int ret;
    u8 mctl_mode;

    dlg_info("[REGULATOR] : regulator_set_mode. mode is %d\n", mode);

    switch(mode) {
        case REGULATOR_MODE_FAST :
            mctl_mode = REGULATOR_MCTL_TURBO;
            break;
        case REGULATOR_MODE_NORMAL :
            mctl_mode = REGULATOR_MCTL_ON;
            break;
        case REGULATOR_MODE_IDLE :
            mctl_mode = REGULATOR_MCTL_SLEEP;
            break;
        case REGULATOR_MODE_STANDBY:
            mctl_mode = REGULATOR_MCTL_OFF;
            break;
        default:
            return -EINVAL;
    }
    
    ret = set_regulator_mctl_mode(d2041, regulator_id, mode);

    return ret;
}
/* D2083 poweroff function */
void d2083_system_poweroff(void)
{
	dlg_info("%s\n", __func__);
	
	if(d2083_dev_info) {
		d2083_shutdown(d2083_dev_info);
	}
}
Esempio n. 8
0
int d2083_audio_ihf_preamp_gain(enum d2083_preamp_gain_val ihfgain_val)
{
	u8 regval;

	dlg_info("d2083_audio_ihf_preamp_gain gain=%d \n", ihfgain_val);

	if(0 >  ihfgain_val || D2083_PREAMP_GAIN_MUTE < ihfgain_val ) {
		dlg_info("[%s]- Invalid preamp gain, so set to 0dB \n", __func__);
		ihfgain_val = D2083_PREAMP_GAIN_0DB;				
	}

	regval = audio_read(D2083_PREAMP_A_CTRL1_REG) & ~D2083_PREAMP_VOL;
	regval |= (ihfgain_val << D2083_PREAMP_VOL_SHIFT) & D2083_PREAMP_VOL;

	return audio_write(D2083_PREAMP_A_CTRL1_REG,regval);

}
int d2083_shutdown(struct d2083 *d2083)
{
	u8 dst;
	//int ret;
	int last_adc;

	dlg_info("%s\n", __func__);

	if (d2083->read_dev == NULL)
		return -ENODEV;

	last_adc=d2083_get_last_vbat_adc();
		
	d2083_reg_write(d2083, D2083_GPID3_REG, (0xFF&last_adc)); //8 LSB
	d2083_reg_write(d2083, D2083_GPID4_REG, (0xF&(last_adc>>8))); // 4 MSB

	last_adc=d2083_get_last_temp_adc();
		
	d2083_reg_write(d2083, D2083_GPID5_REG, (0xFF&last_adc)); //8 LSB
	d2083_reg_write(d2083, D2083_GPID6_REG, (0xF&(last_adc>>8))); // 4 MSB
	
	d2083_clear_bits(d2083,D2083_CONTROLB_REG,D2083_CONTROLB_OTPREADEN); //otp reload disable
	d2083_clear_bits(d2083,D2083_POWERCONT_REG,D2083_POWERCONT_MCTRLEN); //mctl disable

	d2083_reg_write(d2083, D2083_BUCK1_REG, 0x54); //buck1 1.0 V 0x14

	// 20120221 Go deepsleep : Manual LDO off
	d2083_reg_write(d2083, D2083_IRQMASKB_REG, 0x0);	//onkey mask clear


	// buck4, ldo1, ldo3, ldo6, 7, 8, 9, 11, 13, 14, 15, 16, 17
	d2083_clear_bits(d2083, D2083_LDO1_REG, (1<<6)); //LDO 1 disable
	d2083_clear_bits(d2083, D2083_LDO3_REG, (1<<6)); //LDO 3 disable
	d2083_clear_bits(d2083, D2083_LDO6_REG, (1<<6)); //LDO 6 disable
	d2083_clear_bits(d2083, D2083_LDO7_REG, (1<<6)); //LDO 7 disable
	d2083_clear_bits(d2083, D2083_LDO8_REG, (1<<6)); //LDO 8 disable
	d2083_clear_bits(d2083, D2083_LDO9_REG, (1<<6)); //LDO 9 disable

	d2083_clear_bits(d2083, D2083_LDO11_REG, (1<<6)); //LDO 11 disable
	d2083_clear_bits(d2083, D2083_LDO13_REG, (1<<6)); //LDO 13 disable
	d2083_clear_bits(d2083, D2083_LDO14_REG, (1<<6)); //LDO 14 disable
	d2083_clear_bits(d2083, D2083_LDO15_REG, (1<<6)); //LDO 15 disable
	d2083_clear_bits(d2083, D2083_LDO16_REG, (1<<6)); //LDO 16 disable
	d2083_clear_bits(d2083, D2083_LDO17_REG, (1<<6)); //LDO 17 disable
	d2083_clear_bits(d2083, D2083_LDO_AUD_REG, (1<<6)); //LDO_AUD disable

	d2083_reg_write(d2083, D2083_BUCK4_REG, 0x0);	//BUCK 4
	d2083_reg_write(d2083, D2083_SUPPLY_REG, 0x10);
	d2083_reg_write(d2083, D2083_POWERCONT_REG, 0x0E);
	d2083_reg_write(d2083, D2083_PDDIS_REG, 0xCF);

	d2083_reg_read(d2083, D2083_CONTROLB_REG, &dst);
	dst |= D2083_CONTROLB_DEEPSLEEP;
	d2083_reg_write(d2083, D2083_CONTROLB_REG, dst);

	return 0;
}
Esempio n. 10
0
int d2083_set_hs_noise_gate(u16 regval)		
{
	int ret = 0;
#ifdef NOISE_GATE_USE
	dlg_info("d2083_set_hs_noise_gate regval=%d \n",regval);
	if(dlg_audio->HSenabled==true) {

		ret |= audio_write(D2083_HP_NG1_REG, (u8)(regval & 0x00FF));
		ret |= audio_write(D2083_HP_NG2_REG, (u8)((regval >> 8) & 0x00FF));
	}
Esempio n. 11
0
int d2083_audio_hs_ihf_set_gain(enum d2083_sp_vol_val ihfgain_val)
{
	u8 regval;

	dlg_info("[%s]-ihfgain_val[0x%x]\n", __func__, ihfgain_val);
	
	if(0 > ihfgain_val || D2083_SPVOL_MUTE < ihfgain_val) {
		dlg_info("[%s]- Invalid gain, so set to 4dB \n", __func__);
		ihfgain_val = D2083_SPVOL_0DB;				
	}

	regval = audio_read(D2083_SP_CTRL_REG);
	if (ihfgain_val == D2083_SPVOL_MUTE) 
	{
		regval |= D2083_SP_MUTE;
	} 
	else 
	{
		regval &= ~(D2083_SP_VOL | D2083_SP_MUTE);
		regval |= (ihfgain_val << D2083_SP_VOL_SHIFT) & D2083_SP_VOL;			
	}
	return  audio_write(D2083_SP_CTRL_REG,regval);
}
Esempio n. 12
0
int d2083_audio_enable_zcd(int enable)
{
	int ret = 0;

	dlg_info("d2083_audio_enable_zcd =%d \n",enable);

	ret |= audio_set_bits(D2083_PREAMP_A_CTRL1_REG, D2083_PREAMP_ZC_EN);
	ret |= audio_set_bits(D2083_PREAMP_B_CTRL1_REG, D2083_PREAMP_ZC_EN);
	ret |= audio_set_bits(D2083_HP_L_CTRL_REG, D2083_HP_AMP_ZC_EN);
	ret |= audio_set_bits(D2083_HP_R_CTRL_REG, D2083_HP_AMP_ZC_EN);
	ret |= audio_set_bits(D2083_SP_NON_CLIP_ZC_REG, D2083_SP_ZC_EN);

	return ret;
}
Esempio n. 13
0
int d2083_core_reg2volt(int reg)
{
	int volt = -EINVAL;
	int i;

	for (i = 0; i < ARRAY_SIZE(core_vol_list); i++) {
		if (core_vol_list[i][1] == reg) {
			volt = core_vol_list[i][0];
			break;
		}
	}

	dlg_info("[DLG] [%s]-volt[%d]\n", __func__, volt);

	return volt;
}
Esempio n. 14
0
static int d2041_regulator_get_voltage(struct regulator_dev *rdev)
{
    struct d2041 *d2041 = rdev_get_drvdata(rdev);
    unsigned int reg_num, regulator_id = rdev_get_id(rdev);
    int ret;
    u8 val;

	dlg_info("[[%s]], regulator_id[%d]\n", __func__, regulator_id);
	

    reg_num = get_regulator_reg(regulator_id);
    ret = d2041_reg_read(d2041, reg_num, &val);
    val &= D2041_MAX_VSEL;
    ret = mV_to_uV(d2041_regulator_val_to_mvolts(val, regulator_id, rdev));

    return ret;
}
Esempio n. 15
0
int d2083_audio_set_input_preamp_gain(enum d2083_input_path_sel inpath_sel, enum d2083_preamp_gain_val pagain_val)
{
	int reg;
	u8 regval;

	if (inpath_sel == D2083_INPUTA)
		reg = D2083_PREAMP_A_CTRL1_REG;
	else if (inpath_sel == D2083_INPUTB)
		reg = D2083_PREAMP_B_CTRL1_REG;
	else
		return -EINVAL;

	regval = audio_read(reg) & ~D2083_PREAMP_VOL;
	regval |= (pagain_val << D2083_PREAMP_VOL_SHIFT) & D2083_PREAMP_VOL;

	dlg_info("[%s]-addr[0x%x] ihfgain_val[0x%x]\n", __func__, reg,regval);

	return audio_write(reg,regval);
}
Esempio n. 16
0
// speaker on/off
int d2083_audio_hs_ihf_poweron1(void)
{
	int ret = 0;
	u8 regval;

	if(ihf_power_status == true)
	 return ret;
	ihf_power_status = true;
	 
	dlg_info("%s HP =%d \n",__func__, dlg_audio->HSenabled);

	// if(dlg_audio->HSenabled==false)
	//     audio_write(D2083_LDO_AUD_MCTL_REG, 0x44); //AUD_LDO on

	audio_write(D2083_MXHPL_CTRL_REG,0x19); 

	regval = audio_read(D2083_PREAMP_A_CTRL1_REG);
	regval = (regval | D2083_PREAMP_EN) & ~D2083_PREAMP_MUTE;
	ret |= audio_write(D2083_PREAMP_A_CTRL1_REG,regval);
	ret |= audio_write(D2083_PREAMP_A_CTRL2_REG,0x03); //pre amp A fully differential

	regval = audio_read(D2083_SP_CTRL_REG);
	regval &= ~D2083_SP_MUTE;
	regval |= D2083_SP_EN;
	ret |= audio_write(D2083_SP_CTRL_REG,regval);

	ret |= audio_write(D2083_SP_CFG1_REG,0x00); 
	ret |= audio_write(D2083_SP_CFG2_REG,0x00); 
	//ret |= audio_write(D2083_SP_NG1_REG,0x0F); 
	//ret |= audio_write(D2083_SP_NG2_REG,0x07); 
	ret |= audio_write(D2083_SP_NON_CLIP_ZC_REG,0x00);
	ret |= audio_write(D2083_SP_NON_CLIP_REG,0x00); 
	ret |= audio_write(D2083_SP_PWR_REG,0x00);

	ret |= audio_write(D2083_BIAS_CTRL_REG,0x3F); 
	dlg_audio->IHFenabled = true;

	return ret;
}
Esempio n. 17
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;
}
Esempio n. 18
0
int d2083_audio_multicast(u8 flag)
{
	u8 regval;
	int ret = 0;
	
	dlg_info("%s = %d\n",__func__, flag);
	
	switch(flag)
	{
		case DLG_REMOVE_IHF:
		if(!is_playback_stop) {
			ret = audio_write(D2083_MXHPL_CTRL_REG,0x07);
			regval = audio_read(D2083_PREAMP_B_CTRL1_REG);
			ret = audio_write(D2083_PREAMP_A_CTRL1_REG,regval);
		}
		ret |= d2083_audio_hs_ihf_poweroff();
		break;

		case DLG_REMOVE_HS:
		ret = d2083_audio_hs_poweron1(0);
		break;
		
		case DLG_ADD_IHF:
		ret = audio_write(D2083_MXHPL_CTRL_REG,0x19);
		ret |= d2083_audio_hs_ihf_poweron1();
		break;
		
		case DLG_ADD_HS: 
		ret = d2083_audio_hs_poweron1(1);
		break;

		default:
		break;
	}
	
	return ret;
}
static long d2083_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	struct d2083 *d2083 =  file->private_data;
	pmu_reg reg;
	int ret = 0;
	u8 reg_val, event_reg[4];

	if (!d2083)
		return -ENOTTY;
		
	// _kg TODO: Checking if d2083_reg_write() and d2083_reg_read()
	// return with success. 
	switch (cmd) {
    	case BCM_PMU_IOCTL_ENABLE_INTS:
		ret = d2083_block_read(d2083, D2083_EVENTA_REG, 4, event_reg);
		dlg_info("int register 0x%X = 0x%X\n", D2083_EVENTA_REG, event_reg[0]);
		dlg_info("int register 0x%X = 0x%X\n", D2083_EVENTB_REG, event_reg[1]);
		dlg_info("int register 0x%X = 0x%X\n", D2083_EVENTC_REG, event_reg[2]);
		dlg_info("int register 0x%X = 0x%X\n", D2083_EVENTD_REG, event_reg[3]);

		/* Clear all latched interrupts if any */
		d2083_reg_write(d2083, D2083_EVENTA_REG, 0xFF);
		d2083_reg_write(d2083, D2083_EVENTB_REG, 0xFF);
		d2083_reg_write(d2083, D2083_EVENTC_REG, 0xFF);
		d2083_reg_write(d2083, D2083_EVENTD_REG, 0xFF);

		enable_irq(d2083->chip_irq);
		break;

    	case BCM_PMU_IOCTL_DISABLE_INTS:
		disable_irq_nosync(d2083->chip_irq);
		break;

    	case BCM_PMU_IOCTL_READ_REG:
		if (copy_from_user(&reg, (pmu_reg *)arg, sizeof(pmu_reg)) != 0)
			return -EFAULT;
		// DLG eric. 03/Nov/2011. Change prototype
		//reg.val = d2083_reg_read(d2083, reg.reg);
		// TODO: Check parameter. &reg.val
		ret = d2083_reg_read(d2083, reg.reg, &reg_val);
		reg.val = (unsigned short)reg_val;
		if (copy_to_user((pmu_reg *)arg, &reg, sizeof(pmu_reg)) != 0)
			return -EFAULT;
		break;

	case BCM_PMU_IOCTL_WRITE_REG:
		if (copy_from_user(&reg, (pmu_reg *)arg, sizeof(pmu_reg)) != 0)
			return -EFAULT;
		d2083_reg_write(d2083, reg.reg, (u8)reg.val);
		break;

#if 0
	case BCM_PMU_IOCTL_SET_VOLTAGE:
	case BCM_PMU_IOCTL_GET_VOLTAGE:
	case BCM_PMU_IOCTL_GET_REGULATOR_STATE:
	case BCM_PMU_IOCTL_SET_REGULATOR_STATE:
	case BCM_PMU_IOCTL_ACTIVATESIM:
	case BCM_PMU_IOCTL_DEACTIVATESIM:
		ret = d2083_ioctl_regulator(d2083, cmd, arg);
		break;
#endif
	case BCM_PMU_IOCTL_POWERONOFF:
		//    d2083_set_bits(d2083,D2083_POWERCONT_REG,D2083_POWERCONT_RTCAUTOEN);
		d2083_shutdown(d2083);
		break;

	default:
		dlg_err("%s: unsupported cmd\n", __func__);
		ret = -ENOTTY;
	}

	return ret;
}
static int d2083_dbg_parse_args(char *cmd, struct pmu_debug *dbg)
{
	char *tok;                 /* used to separate tokens             */
	const char ct[] = " \t";   /* space or tab delimits the tokens    */
	bool count_flag = false;   /* whether -c option is present or not */
	int tok_count = 0;         /* total number of tokens parsed       */
	int i = 0;

	dbg->len        = 0;

	/* parse the input string */
	while ((tok = strsep(&cmd, ct)) != NULL) {
		dlg_info("token: %s\n", tok);

		/* first token is always address */
		if (tok_count == 0) {
			sscanf(tok, "%x", &dbg->addr);
		} else if (strnicmp(tok, "-c", 2) == 0) {
			/* the next token will be number of regs to read */
			tok = strsep(&cmd, ct);
			if (tok == NULL)
				return -EINVAL;

			tok_count++;
			sscanf(tok, "%d", &dbg->len);
			count_flag = true;
			break;
		} else {
			int val;

			/* this is a value to be written to the pmu register */
			sscanf(tok, "%x", &val);
			if (i < MAX_REGS_READ_WRITE) {
				dbg->val[i] = val;
				i++;
			}
		}

		tok_count++;
	}

	/* decide whether it is a read or write operation based on the
	 * value of tok_count and count_flag.
	 * tok_count = 0: no inputs, invalid case.
	 * tok_count = 1: only reg address is given, so do a read.
	 * tok_count > 1, count_flag = false: reg address and atleast one
	 *     value is present, so do a write operation.
	 * tok_count > 1, count_flag = true: to a multiple reg read operation.
	 */
	switch (tok_count) {
	case 0:
		return -EINVAL;
	case 1:
		dbg->read_write = PMUDBG_READ_REG;
		dbg->len = 1;
		break;
	default:
		if (count_flag == true) {
			dbg->read_write = PMUDBG_READ_REG;
		} else {
			dbg->read_write = PMUDBG_WRITE_REG;
			dbg->len = i;
		}
	}

	return 0;
}
int d2083_device_init(struct d2083 *d2083, int irq,
		       struct d2083_platform_data *pdata)
{
	int ret = 0;//, tmp;
	//struct regulator *regulator;
#ifdef D2083_REG_DEBUG 
	int i;
	u8 data;
#endif

	if(d2083 != NULL)
		d2083_regl_info = d2083;
	else
		goto err;

	dlg_info("D2083 Driver version : %s\n", D2083_VERSION);

	d2083->pmic.max_dcdc = 25; //
	d2083->pdata = pdata;

#if defined(CONFIG_KONA_PMU_BSC_HS_MODE) || defined(CONFIG_KONA_PMU_BSC_HS_1625KHZ)
    d2083_set_bits(d2083, D2083_CONTROLB_REG, D2083_CONTROLB_I2C_SPEED);

	/* Page write for I2C we donot support repeated write and I2C speed set to 1.7MHz */
	d2083_clear_bits(d2083, D2083_CONTROLB_REG, D2083_CONTROLB_WRITEMODE);
#else
	/* Page write for I2C we donot support repeated write and I2C speed set to 400KHz */
	d2083_clear_bits(d2083, D2083_CONTROLB_REG, D2083_CONTROLB_WRITEMODE | D2083_CONTROLB_I2C_SPEED);
#endif

#if 0	// TEST ONLY
	{	// register dump
		int i=0;
		u8 reg_val;
		
		for(i=0; i<=D2083_BIAS_CTRL_REG; i++)
		{
			d2083_reg_read(d2083, i, &reg_val);
			printk(KERN_ERR "addr[0x%x] = [0x%x]\n", i, reg_val);
		}
	}
#endif

	d2083_reg_write(d2083, D2083_BUCKA_REG,0x9A);

#if 1	// 20120221 LDO13 issue
    d2083_reg_write(d2083, D2083_PDDIS_REG,0x0);
    d2083_reg_write(d2083, D2083_PULLDOWN_REG_D,0x0);
    // audio
    d2083_reg_write(d2083, D2083_PREAMP_A_CTRL1_REG,0x34);
    d2083_reg_write(d2083, D2083_PREAMP_A_CTRL2_REG,0x0);
    d2083_reg_write(d2083, D2083_SP_CTRL_REG,0xCC);
    
    // LDO 
    d2083_reg_write(d2083, D2083_LDO1_REG, 0x00); //LDO 1 1.2V    // spare
    d2083_reg_write(d2083, D2083_LDO3_REG, 0x24); //LDO 3 3.0V    // VDD_SENSOR_3.0V
    d2083_reg_write(d2083, D2083_LDO6_REG, 0x20); //LDO 6 2.8V    // VCAM_A_2.8V
    d2083_reg_write(d2083, D2083_LDO7_REG, 0x2A); //LDO 7 3.3V    // VDD_VIB_3.3V
    d2083_reg_write(d2083, D2083_LDO8_REG, 0x64); //LDO 8 3.0V    // VLCD_3.0V
    d2083_reg_write(d2083, D2083_LDO9_REG, 0x24); //LDO 9 3.0V    // VDD_SDXC

    d2083_reg_write(d2083, D2083_LDO11_REG, 0x24); //LDO 11 3.0V    // VSIM1_3.0V
    d2083_reg_write(d2083, D2083_LDO13_REG, 0x24); //LDO 13 3.0V    // VDD_SDIO_3.0V
    d2083_reg_write(d2083, D2083_LDO14_REG, 0xC ); //LDO 14 1.8V    // VTOUCH_1.8V
    d2083_reg_write(d2083, D2083_LDO15_REG, 0x2A); //LDO 15 3.3V    // VTOUCH_3.3V
    d2083_reg_write(d2083, D2083_LDO16_REG, 0xC ); //LDO 16 1.8V    // VCAMC_IO_1.8V
    d2083_reg_write(d2083, D2083_LDO17_REG, 0x20); //LDO 17 2.8V    // VCAM_AF_2.8V
    d2083_reg_write(d2083, D2083_BUCK4_REG, 0x54); //BUCK 4 3.3V	// VDD_3G_PAM_3.3V
#endif

    d2083_reg_write(d2083,D2083_BBATCONT_REG,0x1F);
    d2083_set_bits(d2083,D2083_SUPPLY_REG,D2083_SUPPLY_BBCHGEN);

	/* DLG todo */
	if (pdata && pdata->irq_init) {
		dlg_crit("\nD2083-core.c: IRQ PIN Configuration \n");
		ret = pdata->irq_init(d2083);
		if (ret != 0) {
			dev_err(d2083->dev, "Platform init() failed: %d\n", ret);
			goto err_irq;
		}
	}

	d2083_dev_info = d2083;
	pm_power_off = d2083_system_poweroff;

	ret = d2083_irq_init(d2083, irq, pdata);
	if (ret < 0)
		goto err;
    
	//DLG todo d2083_worker_init(irq); //new for Samsung
    
	if (pdata && pdata->init) {
		ret = pdata->init(d2083);
		if (ret != 0) {
			dev_err(d2083->dev, "Platform init() failed: %d\n", ret);
			goto err_irq;
		}
	}
	
	// Regulator Specific Init
	ret = d2083_platform_regulator_init(d2083);
	if (ret != 0) {
		dev_err(d2083->dev, "Platform Regulator init() failed: %d\n", ret);
		goto err_irq;
	}

	d2083_client_dev_register(d2083, "d2083-battery", &(d2083->batt.pdev));
	d2083_client_dev_register(d2083, "d2083-rtc", &(d2083->rtc.pdev));
	d2083_client_dev_register(d2083, "d2083-onkey", &(d2083->onkey.pdev));
	d2083_client_dev_register(d2083, "d2083-audio", &(d2083->audio.pdev));

	d2083_system_event_init(d2083);
#if defined(CONFIG_MACH_RHEA_SS_IVORY) || defined(CONFIG_MACH_RHEA_SS_NEVIS) || defined(CONFIG_MACH_RHEA_SS_NEVISP)
	d2083_debug_proc_init(d2083);
#endif /* CONFIG_MACH_RHEA_SS_IVORY */

#ifdef D2083_REG_DEBUG    
	  for(i=0; i<D2083_MAX_REGISTER_CNT; i++)
	  {
	  	d2083_reg_read(d2083, i, &data);
		d2083_write_reg_cache(i,data);
	  }
#endif   

    // temporary code
	if (pdata->pmu_event_cb)
		pdata->pmu_event_cb(0, 0);		//PMU_EVENT_INIT_PLATFORM

	// set MCTRL_EN enabled
	set_MCTL_enabled();

	return 0;

err_irq:
	d2083_irq_exit(d2083);
	d2083_dev_info = NULL;
	pm_power_off = NULL;
err:
	dlg_crit("\n\nD2083-core.c: device init failed ! \n\n");
	return ret;
}
Esempio n. 22
0
int d2041_ioctl_regulator(struct d2041 *d2041, unsigned int cmd, unsigned long arg)
{
	//struct max8986_regl_priv *regl_priv = (struct max8986_regl_priv *) pri_data;
	int ret = -EINVAL;
	int regid;

	dlg_info("Inside %s, IOCTL command is %d\n", __func__, cmd);
	switch (cmd) {
    	case BCM_PMU_IOCTL_SET_VOLTAGE:
    	{
    		pmu_regl_volt regulator;
    		if (copy_from_user(&regulator, (pmu_regl_volt *)arg,
    				   sizeof(pmu_regl_volt)) != 0) 
    		{
    			return -EFAULT;
    		}

    		if (regulator.regl_id < 0 
    		    || regulator.regl_id >= ARRAY_SIZE(d2041->pdata->regl_map))
    			return -EINVAL;
    		regid = d2041->pdata->regl_map[regulator.regl_id].reg_id;
    		if (regid < 0) 
    			return -EINVAL;

    		ret = d2041_regulator_set_voltage(d2041_rdev[regid],
    			regulator.voltage, regulator.voltage);
    		break;
    	}
    	case BCM_PMU_IOCTL_GET_VOLTAGE:
    	{
    		pmu_regl_volt regulator;
    		int volt;
    		if (copy_from_user(&regulator, (pmu_regl_volt *)arg,
    				   sizeof(pmu_regl_volt)) != 0) 
    		{
    			return -EFAULT;
    		}
    		if (regulator.regl_id < 0 
    		    || regulator.regl_id >= ARRAY_SIZE(d2041->pdata->regl_map))
    			return -EINVAL;
    		regid = d2041->pdata->regl_map[regulator.regl_id].reg_id;
    		if (regid < 0) 
    			return -EINVAL;

    		volt = d2041_regulator_get_voltage(d2041_rdev[regid]);
    		if (volt > 0) {
    			regulator.voltage = volt;
    			ret = copy_to_user((pmu_regl_volt *)arg, &regulator,
    					   sizeof(regulator));
    		} else {
    			ret = volt;
    		}
    		break;
    	}
    	case BCM_PMU_IOCTL_GET_REGULATOR_STATE:
    	{
    		pmu_regl rmode;
    		unsigned int mode;
    		if (copy_from_user(&rmode, (pmu_regl *)arg, 
    				   sizeof(pmu_regl)) != 0)
    			return -EFAULT;
    		
    		if (rmode.regl_id < 0 
    		    || rmode.regl_id >= ARRAY_SIZE(d2041->pdata->regl_map))
    			return -EINVAL;
    		regid = d2041->pdata->regl_map[rmode.regl_id].reg_id;
    		if (regid < 0) 
    			return -EINVAL;

    		mode = d2041_regulator_get_mode(d2041_rdev[regid]);
    		switch (mode) {
    		    case REGULATOR_MODE_FAST:
    			    rmode.state = PMU_REGL_TURBO;
    			    break;
    		    case REGULATOR_MODE_NORMAL:
    			    rmode.state = PMU_REGL_ON;
    			    break;
    		    case REGULATOR_MODE_STANDBY:
    			    rmode.state = PMU_REGL_ECO;
    			    break;
    		    default:
    			    rmode.state = PMU_REGL_OFF;
    			    break;
    		};
    		ret = copy_to_user((pmu_regl *)arg, &rmode, sizeof(rmode));
    		break;
    	}
    	case BCM_PMU_IOCTL_SET_REGULATOR_STATE:
    	{
    		pmu_regl rmode;
    		unsigned int mode;
    		if (copy_from_user(&rmode, (pmu_regl *)arg,
    					sizeof(pmu_regl)) != 0)
    			return -EFAULT;
    		if (rmode.regl_id < 0 
    		    || rmode.regl_id >= ARRAY_SIZE(d2041->pdata->regl_map))
    			return -EINVAL;
    		regid = d2041->pdata->regl_map[rmode.regl_id].reg_id;
    		if (regid < 0) 
    			return -EINVAL;
    		
    		switch (rmode.state) {
    		    case PMU_REGL_TURBO:
    			    mode = REGULATOR_MODE_FAST;
    			    break;
    		    case PMU_REGL_ON:
    			    mode = REGULATOR_MODE_NORMAL;
    			    break;
    		    case PMU_REGL_ECO:
    			    mode = REGULATOR_MODE_STANDBY;
    			    break;
    		    default:
    			    mode = REGULATOR_MCTL_OFF;
    			    break;
    		};
    		ret = d2041_regulator_set_mode(d2041_rdev[regid], mode);
    		break;
    	}
    	case BCM_PMU_IOCTL_ACTIVATESIM:
    	{
    		int id = 16;	/*check the status of SIMLDO*/
    		pmu_sim_volt sim_volt;
    		int value;
    		if (copy_from_user(&sim_volt, (int *)arg, sizeof(int)) != 0)
    			return -EFAULT;
    		regid = d2041->pdata->regl_map[id].reg_id;
    		if (regid < 0) 
    			return -EINVAL;
    		
    		/*check the status of SIMLDO*/
    		ret = d2041_regulator_is_enabled(d2041_rdev[regid]);
    		if (ret) {
    			dlg_info("SIMLDO is activated already\n");
    			return -EPERM;
    		}
    		/* Put SIMLDO in ON State */
    		ret = d2041_regulator_enable(d2041_rdev[regid]);
    		if (ret)
    			return ret;
    		/* Set SIMLDO voltage */
    		value = 2500000;			// 2.5V
    		ret = d2041_regulator_set_voltage(d2041_rdev[regid], value, value);
    		break;
    	}
    	case BCM_PMU_IOCTL_DEACTIVATESIM:
    	{
    		int id = 16;	/*check the status of SIMLDO*/
    		ret = d2041_regulator_is_enabled(d2041_rdev[id]);
    		if (!ret) {
    			dlg_info("SIMLDFO is already disabled\n");
    			return -EPERM;
    		}
    		regid = d2041->pdata->regl_map[id].reg_id;
    		if (regid < 0) 
    			return -EINVAL;
    		
    		ret = d2041_regulator_disable(d2041_rdev[regid]);
    		if (ret)
    			return ret;
    		break;
    	}
	}	/*end of switch*/
	return ret;
}
Esempio n. 23
0
int d2083_audio_hs_poweron1(bool on)
{
    int ret = 0;
    u8 regval;

	//dlg_info("%s status:%d, cmd:%d\n",__func__,hs_pw_status, on);     
	
	if ( hs_pw_status == on){
		return ret;
	}
	hs_pw_status = on;
	
	dlg_info("%s HP=%d speaker_power=%d \n",__func__,on,dlg_audio->IHFenabled);     

    if(on) 
	{
		//if(dlg_audio->IHFenabled==false)
		//{
		    //audio_write(D2083_LDO_AUD_MCTL_REG, 0x44); //AUD_LDO on
		    //audio_write(D2083_LDO1_MCTL_REG, 0x54);
		    //mdelay(20);
		//}

		if (!dlg_audio_sleep) {
			ret |= audio_write(D2083_HP_L_CTRL_REG,0xF0);
			ret |= audio_write(D2083_HP_R_CTRL_REG,0xF0);

			ret = audio_write(D2083_HP_L_GAIN_REG,0x00);
			ret = audio_write(D2083_HP_R_GAIN_REG,0x00); 

			ret = audio_write(D2083_HP_NG1_REG,0x10);
			msleep(30); // will test for pop noise newly
		}

		//dlg_audio->hs_pga_gain -= (LIMITED_SWAP_PRE - dlg_audio->hs_pre_gain-1);
		//dlg_audio->hs_pre_gain += (LIMITED_SWAP_PRE - dlg_audio->hs_pre_gain);
#ifndef USE_AUDIO_DIFFERENTIAL
		regval = audio_read(D2083_PREAMP_B_CTRL1_REG) & ~D2083_PREAMP_VOL;
		regval |= ((dlg_audio->hs_pre_gain << D2083_PREAMP_VOL_SHIFT) & D2083_PREAMP_VOL);
		regval |= (D2083_PREAMP_EN | D2083_PREAMP_ZC_EN);
		regval &= ~D2083_PREAMP_MUTE;

		ret |= audio_write(D2083_PREAMP_B_CTRL1_REG,regval);
		ret |= audio_write(D2083_PREAMP_B_CTRL2_REG,0x00); 

		ret |= audio_write(D2083_MXHPR_CTRL_REG,0x11);
		ret |= audio_write(D2083_MXHPL_CTRL_REG,0x09);   

#else
		regval = audio_read(D2083_PREAMP_B_CTRL1_REG) & ~D2083_PREAMP_VOL;
		regval |= ((dlg_audio->hs_pre_gain << D2083_PREAMP_VOL_SHIFT) & D2083_PREAMP_VOL);
		regval |= (D2083_PREAMP_EN | D2083_PREAMP_ZC_EN);
		regval &= ~D2083_PREAMP_MUTE;

		ret |= audio_write(D2083_PREAMP_B_CTRL1_REG,regval);
		ret |= audio_write(D2083_PREAMP_B_CTRL2_REG,0x03); 

		    if(dlg_audio->IHFenabled == false) {
		regval = audio_read(D2083_PREAMP_A_CTRL1_REG) & ~D2083_PREAMP_VOL;
		regval |= ((dlg_audio->hs_pre_gain << D2083_PREAMP_VOL_SHIFT) & D2083_PREAMP_VOL);
		regval |= (D2083_PREAMP_EN | D2083_PREAMP_ZC_EN);
		regval &= ~D2083_PREAMP_MUTE;

		ret |= audio_write(D2083_PREAMP_A_CTRL1_REG,regval);
		ret |= audio_write(D2083_PREAMP_A_CTRL2_REG,0x03); 
		    }

		    // HP Mixer controll
		    if(dlg_audio->IHFenabled == false){
			    audio_write(D2083_MXHPL_CTRL_REG,0x07); 
		    } else {
			    audio_write(D2083_MXHPL_CTRL_REG,0x19); 
		    }
			    audio_write(D2083_MXHPR_CTRL_REG,0x19);
#endif

		regval = audio_read(D2083_HP_L_GAIN_REG) & ~D2042_HP_AMP_GAIN & ~D2083_HP_AMP_MUTE_EN; 
		ret |= audio_write(D2083_HP_L_GAIN_REG, regval | (dlg_audio->hs_pga_gain & D2042_HP_AMP_GAIN));

		regval = audio_read(D2083_HP_R_GAIN_REG) & ~D2042_HP_AMP_GAIN & ~D2083_HP_AMP_MUTE_EN;
		ret |= audio_write(D2083_HP_R_GAIN_REG, regval | (dlg_audio->hs_pga_gain & D2042_HP_AMP_GAIN));

		ret |= audio_write(D2083_CP_CTRL_REG,0xC9);
		ret |= audio_write(D2083_CP_DELAY_REG,0x85);

		ret |= audio_write(D2083_CP_DETECTOR_REG,0x00);
		ret |= audio_write(D2083_CP_VOL_THRESHOLD_REG,0x32);
		ret |= audio_write(D2083_BIAS_CTRL_REG,0x3F);

		msleep(65);
		
#ifndef USE_AUDIO_DIFFERENTIAL
		regval = audio_read(D2083_PREAMP_B_CTRL1_REG);
		regval &= ~D2083_PREAMP_ZC_EN;       
		ret |= audio_write(D2083_PREAMP_B_CTRL1_REG,regval);
#else
		regval = audio_read(D2083_PREAMP_B_CTRL1_REG);
		regval &= ~D2083_PREAMP_ZC_EN;       
		ret |= audio_write(D2083_PREAMP_B_CTRL1_REG,regval);
		
		if(dlg_audio->IHFenabled == false){
		regval = audio_read(D2083_PREAMP_A_CTRL1_REG);
		regval &= ~D2083_PREAMP_ZC_EN;       
		ret |= audio_write(D2083_PREAMP_A_CTRL1_REG,regval);
		}
#endif
		ret = audio_write(D2083_HP_NG1_REG, dlg_set_ng1);
		ret = audio_write(D2083_HP_NG2_REG, dlg_set_ng2);

		ret |= audio_write(D2083_HP_L_CTRL_REG,0xa0);
		ret |= audio_write(D2083_HP_R_CTRL_REG,0xa0);

		msleep(25);
		ret |= audio_write(D2083_CP_CTRL_REG,0xCD);

		msleep(40);
		dlg_audio->HSenabled = true;

	}
	else
	{

#ifndef USE_AUDIO_DIFFERENTIAL
		regval = audio_read(D2083_PREAMP_B_CTRL1_REG) & ~D2083_PREAMP_VOL;
		regval |= (D2083_PREAMP_MUTE);
		ret |= audio_write(D2083_PREAMP_B_CTRL1_REG,regval);
#else		
		regval = audio_read(D2083_PREAMP_B_CTRL1_REG) & ~D2083_PREAMP_VOL;
		regval |= (D2083_PREAMP_MUTE);
		ret |= audio_write(D2083_PREAMP_B_CTRL1_REG,regval);
		
		if(dlg_audio->IHFenabled != true) {
		regval = audio_read(D2083_PREAMP_A_CTRL1_REG) & ~D2083_PREAMP_VOL;
		regval |= (D2083_PREAMP_MUTE);
		ret |= audio_write(D2083_PREAMP_A_CTRL1_REG,regval);
		}
#endif
		ret = audio_write(D2083_HP_L_GAIN_REG, dlg_audio->hs_pga_gain -2);
		ret = audio_write(D2083_HP_R_GAIN_REG, dlg_audio->hs_pga_gain -2); 
		msleep(10);

		ret = audio_write(D2083_HP_L_GAIN_REG, dlg_audio->hs_pga_gain -5);
		ret = audio_write(D2083_HP_R_GAIN_REG, dlg_audio->hs_pga_gain -5); 
		msleep(10);

		ret = audio_write(D2083_HP_L_GAIN_REG, dlg_audio->hs_pga_gain -10);
		ret = audio_write(D2083_HP_R_GAIN_REG, dlg_audio->hs_pga_gain -10); 
		msleep(10);

		ret = audio_write(D2083_HP_NG1_REG,0x11); 
		ret = audio_write(D2083_HP_NG2_REG,0x07);    

		if(dlg_audio->IHFenabled != true)
		msleep(50);

		ret = audio_write(D2083_HP_L_GAIN_REG,0x00);
		ret = audio_write(D2083_HP_R_GAIN_REG,0x00); 
		msleep(10);

		audio_write(D2083_CP_CTRL_REG,0xC9);
			
		dlg_audio_sleep = false;
		dlg_audio->HSenabled = false;

		// if(dlg_audio->IHFenabled==false) {
		//     audio_write(D2083_LDO_AUD_MCTL_REG, 0x00); //AUD_LDO off
		//	 audio_write(D2083_LDO1_MCTL_REG, 0x54);
		// }

	}

	return ret;
}
static int d2083_ioctl_open(struct inode *inode, struct file *file)
{
	dlg_info("%s\n", __func__);
	file->private_data = PDE(inode)->data;
	return 0;
}