static int d2083_regulator_enable(struct regulator_dev *rdev)
{
	struct d2083 *d2083 = 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 >= D2083_NUMBER_OF_REGULATORS)
		return -EINVAL;

	if(!is_mode_control_enabled()){
		reg_num = get_regulator_reg(regulator_id);

		d2083_reg_read(d2083, reg_num, &reg_val);
		reg_val |= (1<<6);
		ret = d2083_reg_write(d2083, reg_num,reg_val);
	}else {
		reg_num = get_regulator_mctl_reg(regulator_id);

		ret = d2083_reg_read(d2083, reg_num, &reg_val);
		if(ret < 0) {
			dlg_err("I2C read error\n");
			return ret;
		}

		reg_val &= ~(D2083_REGULATOR_MCTL1 | D2083_REGULATOR_MCTL2 | D2083_REGULATOR_MCTL3);
		reg_val |= (D2083_REGULATOR_MCTL1_ON | D2083_REGULATOR_MCTL2_ON | D2083_REGULATOR_MCTL3_ON);

		switch(get_regulator_dsm_opmode(regulator_id)) {
		case D2083_REGULATOR_LPM_IN_DSM :
			reg_val &= ~(D2083_REGULATOR_MCTL0);
			reg_val |= (D2083_REGULATOR_MCTL0_SLEEP);
			break;
		case D2083_REGULATOR_OFF_IN_DSM :
			reg_val &= ~(D2083_REGULATOR_MCTL0);
			break;
		case D2083_REGULATOR_ON_IN_DSM :
			reg_val &= ~(D2083_REGULATOR_MCTL0);
			reg_val |= (D2083_REGULATOR_MCTL0_ON);
			break;
		}

		ret |= d2083_reg_write(d2083, reg_num, reg_val);
	}

	return ret;
}
static int d2083_regulator_disable(struct regulator_dev *rdev)
{
	struct d2083 *d2083 = 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 >= D2083_NUMBER_OF_REGULATORS)
		return -EINVAL;

	if(!is_mode_control_enabled()) {
		reg_num = get_regulator_reg(regulator_id);

		d2083_reg_read(d2083, reg_num, &reg_val);
		reg_val &= ~(1<<6);
		d2083_reg_write(d2083, reg_num, reg_val);
	} else {
		reg_num = get_regulator_mctl_reg(regulator_id);
		/* 0x00 ==  D2083_REGULATOR_MCTL0_OFF | D2083_REGULATOR_MCTL1_OFF 
		*        | D2083_REGULATOR_MCTL2_OFF | D2083_REGULATOR_MCTL3_OFF 
		*/

		ret = d2083_reg_write(d2083, reg_num, 0x00);
	}

	return ret;
}
Esempio n. 3
0
static inline u8 audio_read(int reg)
{
	u8 val;

	d2083_reg_read(d2083, reg, &val);

	return val;
}
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;
}
static inline int get_global_mctl_mode(struct d2083 *d2083)
{
	u8 reg_val;

	d2083_reg_read(d2083, D2083_STATUSA_REG, &reg_val);

	// Remove "NOT" operation
	return ((reg_val & D2083_STATUSA_MCTL) >> D2083_STATUSA_MCTL_SHIFT);
}
static inline bool is_mode_control_enabled(struct d2083 *d2083)
{
    u8 reg_val;
	bool ret;

    d2083_reg_read(d2083, D2083_POWERCONT_REG, &reg_val);
	ret = (reg_val & D2083_POWERCONT_MCTRLEN);
    
    return ret;
}
static unsigned int get_regulator_mctl_mode(struct d2083 *d2083, 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 = d2083_reg_read(d2083, regulator_mctl_reg, &reg_val);
	reg_val &= D2083_REGULATOR_MCTL0;
	reg_val >>= MCTL0_SHIFT;

	return reg_val;
}
static int d2083_regulator_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,unsigned *selector)
{
	struct d2083 *d2083 = rdev_get_drvdata(rdev);
	int mV_val;
	int min_mV = uV_to_mV(min_uV);
	int max_mV = uV_to_mV(max_uV);
	unsigned int reg_num, regulator_id = rdev_get_id(rdev);
	u8 val;	
	int ret = 0;
	*selector = -1;

	// Neet to implement parameter *selector : reference v_table / num_voltages

	/* before we do anything check the lock bit */
	ret = d2083_reg_read(d2083, D2083_SUPPLY_REG, &val);
	if(val & D2083_SUPPLY_VLOCK)
		d2083_clear_bits(d2083, D2083_SUPPLY_REG, D2083_SUPPLY_VLOCK);

	mV_val =  d2083_regulator_mvolts_to_val(min_mV, regulator_id, rdev);

	/* Sanity check for maximum value */
	if (d2083_regulator_val_to_mvolts(mV_val, regulator_id, rdev) > max_mV)
		return -EINVAL;

	reg_num = get_regulator_reg(regulator_id);

	ret = d2083_reg_read(d2083, reg_num, &val);
	val &= ~D2083_MAX_VSEL;
	
	d2083_reg_write(d2083, reg_num, (val | mV_val));

	/* For BUCKs enable the ramp */
	if (regulator_id <= D2083_BUCK_4)
		d2083_set_bits(d2083, D2083_SUPPLY_REG, (D2083_SUPPLY_VBUCK1GO << regulator_id));

	*selector = regulator_id;
	
	return ret;
}
void d2083_set_sType(u32 s_type)
{
	u8 val;
	u8 mV_val = 0x00;

	if(s_type == SILICON_TYPE_SLOW)
		mV_val = CSR_VAL_ECO_SS_1G;
	else if(s_type == SILICON_TYPE_TYPICAL)
		mV_val = CSR_VAL_ECO_TT_1G;
	else if(s_type == SILICON_TYPE_FAST)
		mV_val = CSR_VAL_ECO_FF_1G;
	else
		mV_val = CSR_VAL_ECO_SS_1G;

	d2083_reg_read(d2083_regl_info, D2083_BUCK1_REG, &val);
	val &= ~D2083_MAX_VSEL;
	d2083_reg_write(d2083_regl_info, D2083_BUCK1_REG, (val | mV_val));
	

	d2083_reg_read(d2083_regl_info, D2083_BUCK1_REG, &val);
	printk("Buck1 normal --> s_type = [%d], read reg[0x%x] <--, mV_val[0x%x]\n", 
			s_type, val, mV_val);
}
Esempio n. 10
0
void set_MCTL_enabled(void)
{
	u8 reg_val;

	if(d2083_regl_info==NULL){
		dlg_err("MCTRL_EN bit is not set\n");
		return;
	}
		
	d2083_reg_read(d2083_regl_info, D2083_POWERCONT_REG, &reg_val);
	reg_val |= D2083_POWERCONT_MCTRLEN;
	d2083_reg_write(d2083_regl_info, D2083_POWERCONT_REG, reg_val);

	mctl_status=1;
}
Esempio n. 11
0
static int d2083_regulator_is_enabled(struct regulator_dev *rdev)
{
	struct d2083 *d2083 = 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 = d2083_reg_read(d2083, 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 >= D2083_NUMBER_OF_REGULATORS)
			return -EINVAL;

		reg_num = get_regulator_mctl_reg(regulator_id);
		ret = d2083_reg_read(d2083, 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 & (D2083_REGULATOR_MCTL1|D2083_REGULATOR_MCTL3)) >= 1) ? 1 : 0;
	}

	return ret;
}
Esempio n. 12
0
static int d2083_regulator_get_voltage(struct regulator_dev *rdev)
{
	struct d2083 *d2083 = 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 = d2083_reg_read(d2083, reg_num, &val);
	val &= D2083_MAX_VSEL;
	ret = mV_to_uV(d2083_regulator_val_to_mvolts(val, regulator_id, rdev));

	return ret;
}
Esempio n. 13
0
static int set_regulator_mctl_mode(struct d2083 *d2083, int regulator_id, u8 mode)
{
	u8 reg_val, mctl_reg;
	int ret = 0;

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

	mctl_reg = get_regulator_mctl_reg(regulator_id);
	ret = d2083_reg_read(d2083, mctl_reg, &reg_val);
	if(ret < 0)
		return ret;

	reg_val &= ~(D2083_REGULATOR_MCTL0 | D2083_REGULATOR_MCTL2);
	reg_val |= ((mode << MCTL0_SHIFT) | ( mode << MCTL2_SHIFT));
	ret = d2083_reg_write(d2083, mctl_reg, reg_val);
	dlg_info("[REGULATOR] %s. reg_val = 0x%X\n", __func__, reg_val);

	return ret;
}
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;
}
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;
}