int axp_gpio_set_io(int gpio, int io_state)
{
	if(io_state == 1){
		switch(gpio)
		{
			case 0: return axp_clr_bits(&axp->dev,AXP20_GPIO0_CFG, 0x06);
			case 1: return axp_clr_bits(&axp->dev,AXP20_GPIO1_CFG, 0x06);
			case 2: return axp_clr_bits(&axp->dev,AXP20_GPIO2_CFG, 0x07);
			case 3: return axp_clr_bits(&axp->dev,AXP20_GPIO3_CFG, 0x04);
			default:return -ENXIO;
		}
	}
	else if(io_state == 0){
		switch(gpio)
		{
			case 0: axp_clr_bits(&axp->dev,AXP20_GPIO0_CFG,0x05);
					return axp_set_bits(&axp->dev,AXP20_GPIO0_CFG,0x02);
			case 1: axp_clr_bits(&axp->dev,AXP20_GPIO1_CFG,0x05);
					return axp_set_bits(&axp->dev,AXP20_GPIO1_CFG,0x02);
			case 2: axp_clr_bits(&axp->dev,AXP20_GPIO2_CFG,0x05);
					return axp_set_bits(&axp->dev,AXP20_GPIO2_CFG,0x02);
			case 3: return axp_set_bits(&axp->dev,AXP20_GPIO3_CFG,0x04);
			default:return -ENXIO;
		}
	}
	return -EINVAL;
}
int axp_gpio_set_value(int gpio, int value)
{
	int io_state,ret;
	ret = axp_gpio_get_io(gpio,&io_state);
	if(ret)
		return ret;
	if(io_state){
		if(value){
			switch(gpio)
			{
				case 0: axp_clr_bits(&axp->dev,AXP20_GPIO0_CFG,0x06);
						return axp_set_bits(&axp->dev,AXP20_GPIO0_CFG,0x01);
				case 1: axp_clr_bits(&axp->dev,AXP20_GPIO1_CFG,0x06);
						return axp_set_bits(&axp->dev,AXP20_GPIO1_CFG,0x01);
				case 2: return -EINVAL;
				case 3: return axp_set_bits(&axp->dev,AXP20_GPIO3_CFG,0x02);
				default:break;
			}
		}
		else{
			switch(gpio)
			{
				case 0: return axp_clr_bits(&axp->dev,AXP20_GPIO0_CFG,0x03);
				case 1: return axp_clr_bits(&axp->dev,AXP20_GPIO1_CFG,0x03);
				case 2: return axp_clr_bits(&axp->dev,AXP20_GPIO1_CFG,0x03);
				case 3: return axp_clr_bits(&axp->dev,AXP20_GPIO3_CFG,0x02);
				default:break;
			}
		}
		return -ENXIO;
	}
	return -ENXIO;
}
static void axp_lateresume(struct early_suspend *h)
{
	uint8_t tmp;
	int value;

	value = axp_powerkey_get();
	if (0 != value)
		axp_powerkey_set(0);

	DBG_PSY_MSG(DEBUG_SPLY, "======late resume=======\n");
#if defined (CONFIG_AXP_CHGCHANGE)
	early_suspend_flag = 0;
	if(axp81x_config.pmu_runtime_chgcur == 0)
		axp_clr_bits(axp_charger->master,AXP81X_CHARGE_CONTROL1,0x80);
	else
		axp_set_bits(axp_charger->master,AXP81X_CHARGE_CONTROL1,0x80);
	if(axp81x_config.pmu_runtime_chgcur >= 300000 && axp81x_config.pmu_runtime_chgcur <= 2550000){
		tmp = (axp81x_config.pmu_runtime_chgcur -200001)/150000;
		axp_update(axp_charger->master, AXP81X_CHARGE_CONTROL1, tmp,0x0F);
	}else if(axp81x_config.pmu_runtime_chgcur < 300000){
		axp_clr_bits(axp_charger->master, AXP81X_CHARGE_CONTROL1,0x0F);
	}else{
		axp_set_bits(axp_charger->master, AXP81X_CHARGE_CONTROL1,0x0F);
	}
#endif
}
int axp_gpio_set_io(int gpio, int io_state)
{
	if (!axp) {
		WARN_ON_ONCE("axp gpio used without AXP");
		return -ENODEV;
	}

	if(io_state == 1){
		switch(gpio)
		{
			case 0: return axp_clr_bits(&axp->dev,AXP20_GPIO0_CFG, 0x06);
			case 1: return axp_clr_bits(&axp->dev,AXP20_GPIO1_CFG, 0x06);
			case 2: return axp_clr_bits(&axp->dev,AXP20_GPIO2_CFG, 0x06);
			case 3: return axp_clr_bits(&axp->dev,AXP20_GPIO3_CFG, 0x04);
			default:return -ENXIO;
		}
	}
	else if(io_state == 0){
		switch(gpio)
		{
			case 0: axp_clr_bits(&axp->dev,AXP20_GPIO0_CFG,0x05);
					return axp_set_bits(&axp->dev,AXP20_GPIO0_CFG,0x02);
			case 1: axp_clr_bits(&axp->dev,AXP20_GPIO1_CFG,0x05);
					return axp_set_bits(&axp->dev,AXP20_GPIO1_CFG,0x02);
			case 2: axp_clr_bits(&axp->dev,AXP20_GPIO2_CFG,0x05);
					return axp_set_bits(&axp->dev,AXP20_GPIO2_CFG,0x02);
			case 3: return axp_set_bits(&axp->dev,AXP20_GPIO3_CFG,0x04);
			default:return -ENXIO;
		}
	}
	return -EINVAL;
}
Example #5
0
static ssize_t workmode_store(struct device *dev,
				struct device_attribute *attr, const char *buf, size_t count)
{
	struct regulator_dev *rdev = dev_get_drvdata(dev);
	struct axp_regulator_info *info = rdev_get_drvdata(rdev);
	struct device *axp_dev = to_axp_dev(rdev);
	char mode;
	uint8_t val;
	if(  buf[0] > '0' && buf[0] < '9' )// 1/AUTO: auto mode; 2/PWM: pwm mode;
		mode = buf[0];
	else
		mode = buf[1];

	switch(mode){
	 case 'U':
	 case 'u':
	 case '1':
		val = 0;break;
	 case 'W':
	 case 'w':
	 case '2':
	 	val = 1;break;
	 default:
	    val =0;
	}

	if(info->desc.id == AXP15_ID_DCDC1){
		if(val)
			axp_set_bits(axp_dev, AXP15_BUCKMODE,0x08);
		else
			axp_clr_bits(axp_dev, AXP15_BUCKMODE,0x08);
	}
	if(info->desc.id == AXP15_ID_DCDC2){
		if(val)
			axp_set_bits(axp_dev, AXP15_BUCKMODE,0x04);
		else
			axp_clr_bits(axp_dev, AXP15_BUCKMODE,0x04);
	}
	if(info->desc.id == AXP15_ID_DCDC3){
		if(val)
			axp_set_bits(axp_dev, AXP15_BUCKMODE,0x02);
		else
			axp_clr_bits(axp_dev, AXP15_BUCKMODE,0x02);
	}
	else if(info->desc.id == AXP15_ID_DCDC4){
		if(val)
			axp_set_bits(axp_dev, AXP15_BUCKMODE,0x01);
		else
			axp_clr_bits(axp_dev, AXP15_BUCKMODE,0x01);
	}

	return count;
}
Example #6
0
static int axp_ldoio0_enable(struct regulator_dev *rdev)
{
	struct axp_regulator_info *info = rdev_get_drvdata(rdev);
	struct device *axp_dev = to_axp_dev(rdev);
#if defined (CONFIG_KP_AXP20)
	 axp_set_bits(axp_dev, info->enable_reg,0x03);
	 return axp_clr_bits(axp_dev, info->enable_reg,0x04);
#endif
#if defined (CONFIG_KP_AXP19)
	 axp_set_bits(axp_dev, info->enable_reg,0x02);
	 return axp_clr_bits(axp_dev, info->enable_reg,0x05);
#endif
}
int axp_gpio_set_value(int gpio, int value)
{
	if(value){
		switch(gpio)
		{
			case 0: return axp_set_bits(&axp->dev,AXP19_GPIO012_STATE,0x01);
			case 1: return axp_set_bits(&axp->dev,AXP19_GPIO012_STATE,0x02);
			case 2: return axp_set_bits(&axp->dev,AXP19_GPIO012_STATE,0x04);
			case 3: return axp_set_bits(&axp->dev,AXP19_GPIO34_STATE,0x01);
			case 4: return axp_set_bits(&axp->dev,AXP19_GPIO34_STATE,0x02);
			case 5: return axp_set_bits(&axp->dev,AXP19_GPIO5_STATE,0x20);
			case 6: return axp_set_bits(&axp->dev,AXP19_GPIO67_STATE,0x20);
			case 7: return axp_set_bits(&axp->dev,AXP19_GPIO67_STATE,0x02);
			default:break;
		}
	}
	else {
		switch(gpio)
		{
			case 0: return axp_clr_bits(&axp->dev,AXP19_GPIO012_STATE,0x01);
			case 1: return axp_clr_bits(&axp->dev,AXP19_GPIO012_STATE,0x02);
			case 2: return axp_clr_bits(&axp->dev,AXP19_GPIO012_STATE,0x04);
			case 3: return axp_clr_bits(&axp->dev,AXP19_GPIO34_STATE,0x01);
			case 4: return axp_clr_bits(&axp->dev,AXP19_GPIO34_STATE,0x02);
			case 5: return axp_clr_bits(&axp->dev,AXP19_GPIO5_STATE,0x20);
			case 6: return axp_clr_bits(&axp->dev,AXP19_GPIO67_STATE,0x20);
			case 7: return axp_clr_bits(&axp->dev,AXP19_GPIO67_STATE,0x02);
			default:break;
		}
	}
	return -ENXIO;
}
static int axp_battery_event(struct notifier_block *nb, unsigned long event,
				void *data)
{
	struct axp_charger *charger =
		container_of(nb, struct axp_charger, nb);

	axp_charger_update_state(charger);

	switch (event) {
	case AXP19_IRQ_BATIN:
	case AXP19_IRQ_ACIN:
	case AXP19_IRQ_USBIN:
		axp_set_bits(charger->master,AXP19_CHARGE_CONTROL1,0x80);
		break;
	case AXP19_IRQ_BATRE:
	case AXP19_IRQ_ACOV:
	case AXP19_IRQ_ACRE:
	case AXP19_IRQ_USBOV:
	case AXP19_IRQ_USBRE:
    case AXP19_IRQ_TEMOV:
	case AXP19_IRQ_TEMLO:
		axp_clr_bits(charger->master,AXP19_CHARGE_CONTROL1,0x80);
		break;
    default:
		break;
	}

	return 0;
}
Example #9
0
static int axp_ldoio0_enable(struct regulator_dev *rdev)
{
	struct axp_regulator_info *info = rdev_get_drvdata(rdev);
	struct device *axp_dev = to_axp_dev(rdev);

	 axp_set_bits(axp_dev, info->enable_reg,0x03);
	 return axp_clr_bits(axp_dev, info->enable_reg,0x04);
}
 void axp_power_off(void)
{
    printk("[axp] send power-off command!\n");
    mdelay(20);
	axp_set_bits(&axp->dev, POWER20_OFF_CTL, 0x80);
    mdelay(20);
    printk("[axp] warning!!! axp can't power-off, maybe some error happend!\n");
}
static int axp_enable(struct regulator_dev *rdev)
{
    struct axp_regulator_info *info = rdev_get_drvdata(rdev);
    struct device *axp_dev = to_axp_dev(rdev);

    return axp_set_bits(axp_dev, info->enable_reg,
                        1 << info->enable_bit);
}
Example #12
0
void axp81x_power_off(int power_start)
{
	uint8_t val;
	struct axp_dev *axp;
	axp = axp_dev_lookup(AXP81X);
	if (NULL == axp) {
		printk("%s: axp data is null\n", __func__);
		return;
	}
	if(axp81x_config.pmu_pwroff_vol >= 2600 && axp81x_config.pmu_pwroff_vol <= 3300){
		if (axp81x_config.pmu_pwroff_vol > 3200){
			val = 0x7;
		}else if (axp81x_config.pmu_pwroff_vol > 3100){
			val = 0x6;
		}else if (axp81x_config.pmu_pwroff_vol > 3000){
			val = 0x5;
		}else if (axp81x_config.pmu_pwroff_vol > 2900){
			val = 0x4;
		}else if (axp81x_config.pmu_pwroff_vol > 2800){
			val = 0x3;
		}else if (axp81x_config.pmu_pwroff_vol > 2700){
			val = 0x2;
		}else if (axp81x_config.pmu_pwroff_vol > 2600){
			val = 0x1;
		}else
			val = 0x0;
		axp_update(axp->dev, AXP81X_VOFF_SET, val, 0x7);
	}
	val = 0xff;
	printk("[axp] send power-off command!\n");

	mdelay(20);

	if(axp81x_config.power_start != 1){
		axp_read(axp->dev, AXP81X_STATUS, &val);
		if(val & 0xF0){
			axp_read(axp->dev, AXP81X_MODE_CHGSTATUS, &val);
			if(val & 0x20) {
				printk("[axp] set flag!\n");
				axp_read(axp->dev, AXP81X_BUFFERC, &val);
				if (0x0d != val)
					axp_write(axp->dev, AXP81X_BUFFERC, 0x0f);
				mdelay(20);
				printk("[axp] reboot!\n");
				machine_restart(NULL);
				printk("[axp] warning!!! arch can't ,reboot, maybe some error happend!\n");
			}
		}
	}
	axp_read(axp->dev, AXP81X_BUFFERC, &val);
	if (0x0d != val)
		axp_write(axp->dev, AXP81X_BUFFERC, 0x00);

	mdelay(20);
	axp_set_bits(axp->dev, AXP81X_OFF_CTL, 0x80);
	mdelay(20);
	printk("[axp] warning!!! axp can't power-off, maybe some error happend!\n");
}
Example #13
0
void axp_set_rdc(int rdc)
{
    uint32_t rdc_tmp = (rdc * 10000 + 5371) / 10742;
    //char    buf[100];

    axp_set_bits(0xB9, 0x80);                           // stop
    axp_clr_bits(0xBA, 0x80);
    axp_write(0xBB, rdc_tmp & 0xff);
    axp_write(0xBA, (rdc_tmp >> 8) & 0x1F);
    axp_clr_bits(0xB9, 0x80);                           // start
}
Example #14
0
static int axp81x_resume(struct platform_device *dev)
{
	struct axp_charger *charger = platform_get_drvdata(dev);
	int pre_rest_vol;
	uint8_t val,tmp;

	axp_enable_irq(charger);
	pre_rest_vol = charger->rest_vol;
	axp_read(charger->master, AXP81X_CAP,&val);
	charger->rest_vol = val & 0x7f;
	if(charger->rest_vol - pre_rest_vol){
		printk("battery vol change: %d->%d \n", pre_rest_vol, charger->rest_vol);
		pre_rest_vol = charger->rest_vol;
		axp_write(charger->master,AXP81X_DATA_BUFFER1,charger->rest_vol | 0x80);
	}
#if defined (CONFIG_AXP_CHGCHANGE)
	if(axp81x_config.pmu_runtime_chgcur == 0)
		axp_clr_bits(charger->master,AXP81X_CHARGE_CONTROL1,0x80);
	else
		axp_set_bits(charger->master,AXP81X_CHARGE_CONTROL1,0x80);
	printk("pmu_runtime_chgcur = %d\n", axp81x_config.pmu_runtime_chgcur);
	if(axp81x_config.pmu_runtime_chgcur >= 300000 && axp81x_config.pmu_runtime_chgcur <= 2550000){
		tmp = (axp81x_config.pmu_runtime_chgcur -200001)/150000;
		charger->chgcur = tmp *150000 + 300000;
		axp_update(charger->master, AXP81X_CHARGE_CONTROL1, tmp,0x0F);
	}else if(axp81x_config.pmu_runtime_chgcur < 300000){
		axp_clr_bits(axp_charger->master, AXP81X_CHARGE_CONTROL1,0x0F);
	}else{
		axp_set_bits(axp_charger->master, AXP81X_CHARGE_CONTROL1,0x0F);
	}
#endif
	charger->disvbat = 0;
	charger->disibat = 0;
	axp_charger_update_state(charger);
	axp_charger_update(charger, &axp81x_config);
	power_supply_changed(&charger->batt);
	power_supply_changed(&charger->ac);
	power_supply_changed(&charger->usb);
	schedule_delayed_work(&charger->work, charger->interval);
	return 0;
}
static int axp_get_rdc(struct axp_charger *charger)
{
	uint8_t val[3];
	unsigned int i,temp,pre_temp;
	int averPreVol = 0, averPreCur = 0,averNextVol = 0,averNextCur = 0;

	//axp_reads(charger->master,AXP18_DATA_BUFFER1,2,val);
	axp_read(charger->master,AXP18_DATA_BUFFER1,val);
	axp_read(charger->master,AXP18_DATA_BUFFER2,val+1);
	pre_temp = (((val[0] & 0x7F) << 8 ) + val[1]);

	printk("%d:pre_temp = %d\n",__LINE__,pre_temp);

	if( charger->is_on){
		for(i = 0; i< AXP18_RDC_COUNT; i++){
			axp_charger_update(charger);
			averPreVol += charger->vbat;
			averPreCur += charger->ibat;
			msleep(50);
		}
		averPreVol /= AXP18_RDC_COUNT;
		averPreCur /= AXP18_RDC_COUNT;
		axp_clr_bits(charger->master,AXP18_CHARGE_CONTROL2,0x80);
		msleep(500);
		for(i = 0; i< AXP18_RDC_COUNT; i++){
			axp_charger_update(charger);
			averNextVol += charger->vbat;
			averNextCur += charger->ibat;
			msleep(50);
		}
		averNextVol /= AXP18_RDC_COUNT;
		averNextVol /= AXP18_RDC_COUNT;
		axp_set_bits(charger->master,AXP18_CHARGE_CONTROL2,0x80);
		msleep(500);
		if(ABS(averPreCur - averNextCur) > 200){
			temp = 1000 * ABS(averPreVol - averNextVol) / ABS(averPreCur);
			if((temp < 5) || (temp > 5000)){
				return pre_temp;
			}
			else {
				temp += pre_temp;
				temp >>= 1;
				val[0] = ((temp & 0xFF00) | 0x8000) >> 8;
				val[1] = AXP18_DATA_BUFFER2;
				val[2] =  temp & 0x00FF;
				axp_writes(charger->master,AXP18_DATA_BUFFER1,3,val );
				return temp;
			}
		}
		else
			return pre_temp;
Example #16
0
int axp81x_chg_current_limit(int current_limit)
{
	uint8_t tmp = 0;
#if defined (CONFIG_AXP_CHGCHANGE)
	if(current_limit == 0)
		axp_clr_bits(axp_charger->master,AXP81X_CHARGE_CONTROL1,0x80);
	else
		axp_set_bits(axp_charger->master,AXP81X_CHARGE_CONTROL1,0x80);
	DBG_PSY_MSG(DEBUG_SPLY, "current_limit = %d\n", current_limit);
	if(current_limit >= AXP81X_CHARGE_CURRENT_MIN && current_limit <= AXP81X_CHARGE_CURRENT_MAX){
		tmp = (current_limit -AXP81X_CHARGE_CURRENT_STEP)/AXP81X_CHARGE_CURRENT_STEP;
		spin_lock(&axp_charger->charger_lock);
		axp_charger->chgcur = tmp *AXP81X_CHARGE_CURRENT_STEP + AXP81X_CHARGE_CURRENT_MIN;
		spin_unlock(&axp_charger->charger_lock);
		axp_update(axp_charger->master, AXP81X_CHARGE_CONTROL1, tmp,0x0F);
	}else if(current_limit < AXP81X_CHARGE_CURRENT_MIN){
		axp_clr_bits(axp_charger->master, AXP81X_CHARGE_CONTROL1,0x0F);
	}else{
		axp_set_bits(axp_charger->master, AXP81X_CHARGE_CONTROL1,0x0F);
	}
#endif
	return 0;
}
static int axp_get_rdc(struct axp_charger *charger)
{
    uint8_t val[2];
    unsigned int i,temp,pre_temp;
    int averPreVol = 0, averPreCur = 0,averNextVol = 0,averNextCur = 0;

	axp_reads(charger->master,AXP19_DATA_BUFFER2,2,val);

	pre_temp = (((val[0] & 0x07) << 8 ) + val[1]);

	if(!charger->bat_det){
        return pre_temp;
	}
	if( charger->ext_valid){
		for(i = 0; i< AXP19_RDC_COUNT; i++){
            axp_charger_update(charger);
			averPreVol += charger->vbat;
			averPreCur += charger->ibat;
			msleep(200);
        }
        averPreVol /= AXP19_RDC_COUNT;
        averPreCur /= AXP19_RDC_COUNT;
		axp_clr_bits(charger->master,AXP20_CHARGE_CONTROL1,0x80);
		msleep(3000);
		for(i = 0; i< AXP19_RDC_COUNT; i++){
            axp_charger_update(charger);
			averNextVol += charger->vbat;
			averNextCur += charger->ibat;
			msleep(200);
        }
		averNextVol /= AXP19_RDC_COUNT;
		averNextCur /= AXP19_RDC_COUNT;
		axp_set_bits(charger->master,AXP20_CHARGE_CONTROL1,0x80);
		if(ABS(averPreCur - averNextCur) > 200){
            temp = 1000 * ABS(averPreVol - averNextVol) / ABS(averPreCur - averNextCur);
			if((temp < 5) || (temp > 5000)){
                return pre_temp;
			}
			else {
				temp += pre_temp;
			 	temp >>= 1;
			  axp_write(charger->master,AXP19_DATA_BUFFER2,((temp & 0xFF00) | 0x800) >> 8);
		    axp_write(charger->master,AXP19_DATA_BUFFER3,temp & 0x00FF);
				return temp;
			}
		}
		else {
			return pre_temp;
Example #18
0
int axp_chg_init(struct axp_charger *charger)
{
	int ret = 0;

	if (axp_config->pmu_init_bc_en) {
		/* enable BC */
		axp_set_bits(charger->master, AXP_BC_SET, 0x01);
	} else {
		setup_timer(&charger->usb_status_timer, axp_charger_update_usb_state, (unsigned long)charger);
		/* set usb cur-vol limit*/
		INIT_DELAYED_WORK(&(charger->usbwork), axp_usb);
		axp_usb_ac_check_status(charger);
		power_supply_changed(&charger->ac);
		power_supply_changed(&charger->usb);
		schedule_delayed_work(&(charger->usbwork), msecs_to_jiffies(30* 1000));
	}
	return ret;
}
Example #19
0
static void axp_earlysuspend(struct early_suspend *h)
{
	uint8_t tmp;

	DBG_PSY_MSG(DEBUG_SPLY, "======early suspend=======\n");

#if defined (CONFIG_AXP_CHGCHANGE)
	early_suspend_flag = 1;
	if(axp81x_config.pmu_earlysuspend_chgcur == 0)
		axp_clr_bits(axp_charger->master,AXP81X_CHARGE_CONTROL1,0x80);
	else
		axp_set_bits(axp_charger->master,AXP81X_CHARGE_CONTROL1,0x80);
	if(axp81x_config.pmu_earlysuspend_chgcur >= 300000 && axp81x_config.pmu_earlysuspend_chgcur <= 2550000){
		tmp = (axp81x_config.pmu_earlysuspend_chgcur -200001)/150000;
		axp_update(axp_charger->master, AXP81X_CHARGE_CONTROL1, tmp,0x0F);
	}
#endif
}
Example #20
0
static void axp81x_shutdown(struct platform_device *dev)
{
	uint8_t tmp;
	struct axp_charger *charger = platform_get_drvdata(dev);

	cancel_delayed_work_sync(&charger->work);
#if defined (CONFIG_AXP_CHGCHANGE)
	if(axp81x_config.pmu_shutdown_chgcur == 0)
		axp_clr_bits(charger->master,AXP81X_CHARGE_CONTROL1,0x80);
	else
		axp_set_bits(charger->master,AXP81X_CHARGE_CONTROL1,0x80);
	printk("pmu_shutdown_chgcur = %d\n", axp81x_config.pmu_shutdown_chgcur);
	if(axp81x_config.pmu_shutdown_chgcur >= 300000 && axp81x_config.pmu_shutdown_chgcur <= 2550000){
		tmp = (axp81x_config.pmu_shutdown_chgcur -200001)/150000;
		charger->chgcur = tmp *150000 + 300000;
		axp_update(charger->master, AXP81X_CHARGE_CONTROL1, tmp, 0x0F);
	}
#endif
	return;
}
Example #21
0
static int axp_gpio_set_data(int gpio, int value)
{
	struct axp_dev *axp = NULL;

	axp = axp_dev_lookup(AXP19);
	if (NULL == axp) {
		printk("%s: %d axp data is null\n", __func__, __LINE__);
		return -ENXIO;
	}

	if(value){//high
		switch(gpio) {
			case 0: return axp_set_bits(axp->dev,AXP19_GPIO012_STATE,0x01);
			case 1: return axp_set_bits(axp->dev,AXP19_GPIO012_STATE,0x02);
			case 2: return axp_set_bits(axp->dev,AXP19_GPIO012_STATE,0x04);
			case 3: return axp_set_bits(axp->dev,AXP19_GPIO34_STATE,0x01);
			case 4: return axp_set_bits(axp->dev,AXP19_GPIO34_STATE,0x02);
			case 5: return axp_set_bits(axp->dev,AXP19_GPIO5_STATE,0x20);
			case 6: return axp_set_bits(axp->dev,AXP19_GPIO67_STATE,0x20);
			case 7: return axp_set_bits(axp->dev,AXP19_GPIO67_STATE,0x02);
			default:break;
		}
	}else{//low
		switch(gpio){
			case 0: return axp_clr_bits(axp->dev,AXP19_GPIO012_STATE,0x01);
			case 1: return axp_clr_bits(axp->dev,AXP19_GPIO012_STATE,0x02);
			case 2: return axp_clr_bits(axp->dev,AXP19_GPIO012_STATE,0x04);
			case 3: return axp_clr_bits(axp->dev,AXP19_GPIO34_STATE,0x01);
			case 4: return axp_clr_bits(axp->dev,AXP19_GPIO34_STATE,0x02);
			case 5: return axp_clr_bits(axp->dev,AXP19_GPIO5_STATE,0x20);
			case 6: return axp_clr_bits(axp->dev,AXP19_GPIO67_STATE,0x20);
			case 7: return axp_clr_bits(axp->dev,AXP19_GPIO67_STATE,0x02);
			default:break;
		}
	}
	return -ENXIO;
}
Example #22
0
static int axp81x_suspend(struct platform_device *dev, pm_message_t state)
{
	uint8_t tmp, ret;
	struct axp_charger *charger = platform_get_drvdata(dev);

	ret = axp_disable_irq(charger);
	if (ret < 0)
		return ret;
	cancel_delayed_work_sync(&charger->work);
#if defined (CONFIG_AXP_CHGCHANGE)
	if(axp81x_config.pmu_suspend_chgcur == 0)
		axp_clr_bits(charger->master,AXP81X_CHARGE_CONTROL1,0x80);
	else
		axp_set_bits(charger->master,AXP81X_CHARGE_CONTROL1,0x80);
	printk("pmu_suspend_chgcur = %d\n", axp81x_config.pmu_suspend_chgcur);
	if(axp81x_config.pmu_suspend_chgcur >= 300000 && axp81x_config.pmu_suspend_chgcur <= 2550000){
		tmp = (axp81x_config.pmu_suspend_chgcur -200001)/150000;
		charger->chgcur = tmp *150000 + 300000;
		axp_update(charger->master, AXP81X_CHARGE_CONTROL1, tmp,0x0F);
	}
#endif
	return 0;
}
Example #23
0
static void axp_power_off(void)
{
	uint8_t val;

	preempt_count() = 0;

#if defined (CONFIG_AW_AXP18)
	axp_set_bits(&axp->dev, POWER18_ONOFF, 0x80);
#endif

#if defined (CONFIG_AW_AXP19)
	axp_set_bits(&axp->dev, POWER19_OFF_CTL, 0x80);
#endif

#if defined (CONFIG_AW_AXP20)
	if(pmu_pwroff_vol >= 2600 && pmu_pwroff_vol <= 3300){
		if (pmu_pwroff_vol > 3200){
			val = 0x7;
		}
		else if (pmu_pwroff_vol > 3100){
			val = 0x6;
		}
		else if (pmu_pwroff_vol > 3000){
			val = 0x5;
		}
		else if (pmu_pwroff_vol > 2900){
			val = 0x4;
		}
		else if (pmu_pwroff_vol > 2800){
			val = 0x3;
		}
		else if (pmu_pwroff_vol > 2700){
			val = 0x2;
		}
		else if (pmu_pwroff_vol > 2600){
			val = 0x1;
		}
		else
			val = 0x0;

		axp_update(&axp->dev, POWER20_VOFF_SET, val, 0x7);
	}
	val = 0xff;

	axp_read(&axp->dev, POWER20_COULOMB_CTL, &val);
	val &= 0x3f;
	axp_write(&axp->dev, POWER20_COULOMB_CTL, val);
	val |= 0x80;
	val &= 0xbf;
	axp_write(&axp->dev, POWER20_COULOMB_CTL, val);

    //led auto
    axp_clr_bits(&axp->dev,0x32,0x38);
	axp_clr_bits(&axp->dev,0xb9,0x80);

    printk("[axp] send power-off command!\n");
    mdelay(20);
    if(power_start != 1){
		axp_read(&axp->dev, POWER20_STATUS, &val);
		if(val & 0xF0){
	    	axp_read(&axp->dev, POWER20_MODE_CHGSTATUS, &val);
	    	if(val & 0x20){
            	printk("[axp] set flag!\n");
	        	axp_write(&axp->dev, POWER20_DATA_BUFFERC, 0x0f);
            	mdelay(20);
		    	printk("[axp] reboot!\n");
			machine_restart(NULL);
		    	printk("[axp] warning!!! arch can't ,reboot, maybe some error happend!\n");
	    	}
		}
	}
    axp_write(&axp->dev, POWER20_DATA_BUFFERC, 0x00);
    mdelay(20);
	axp_set_bits(&axp->dev, POWER20_OFF_CTL, 0x80);
    mdelay(20);
    printk("[axp] warning!!! axp can't power-off, maybe some error happend!\n");

#endif
}
Example #24
0
static int axp_pmx_set(int gpio, int mux)
{
	struct axp_dev *axp = NULL;

	axp = axp_dev_lookup(AXP19);
	if (NULL == axp) {
		printk("%s: %d axp data is null\n", __func__, __LINE__);
		return -ENXIO;
	}
	if(mux == 1){//output
		switch(gpio){
			case 0: return axp_clr_bits(axp->dev,AXP19_GPIO0_CFG,0x07);
			case 1: return axp_clr_bits(axp->dev,AXP19_GPIO1_CFG,0x07);
			case 2: return axp_clr_bits(axp->dev,AXP19_GPIO2_CFG,0x07);
			case 3: axp_set_bits(axp->dev,AXP19_GPIO34_CFG,0x81);
					return axp_clr_bits(axp->dev,AXP19_GPIO34_CFG,0x02);
			case 4: axp_set_bits(axp->dev,AXP19_GPIO34_CFG,0x84);
					return axp_clr_bits(axp->dev,AXP19_GPIO34_CFG,0x08);
			case 5: axp_set_bits(axp->dev,AXP19_GPIO5_CFG,0x80);
					return axp_clr_bits(axp->dev,AXP19_GPIO5_CFG,0x40);
			case 6: axp_set_bits(axp->dev,AXP19_GPIO67_CFG0,0x01);
					return axp_clr_bits(axp->dev,AXP19_GPIO67_CFG1,0x40);
			case 7: axp_set_bits(axp->dev,AXP19_GPIO67_CFG0,0x01);
					return axp_clr_bits(axp->dev,AXP19_GPIO67_CFG1,0x04);
			default:return -ENXIO;
		}
	}
	else if(mux == 0){//input
		switch(gpio){
			case 0: axp_clr_bits(axp->dev,AXP19_GPIO0_CFG,0x06);
					return axp_set_bits(axp->dev,AXP19_GPIO0_CFG,0x01);
			case 1: axp_clr_bits(axp->dev,AXP19_GPIO1_CFG,0x06);
					return axp_set_bits(axp->dev,AXP19_GPIO1_CFG,0x01);
			case 2: axp_clr_bits(axp->dev,AXP19_GPIO2_CFG,0x06);
					return axp_set_bits(axp->dev,AXP19_GPIO2_CFG,0x01);
			case 3: axp_set_bits(axp->dev,AXP19_GPIO34_CFG,0x82);
					return axp_clr_bits(axp->dev,AXP19_GPIO34_CFG,0x01);
			case 4: axp_set_bits(axp->dev,AXP19_GPIO34_CFG,0x88);
					return axp_clr_bits(axp->dev,AXP19_GPIO34_CFG,0x04);
			case 5: axp_set_bits(axp->dev,AXP19_GPIO5_CFG,0xC0);
			case 6: axp_set_bits(axp->dev,AXP19_GPIO67_CFG0,0x01);
					return axp_set_bits(axp->dev,AXP19_GPIO67_CFG1,0x40);
			case 7: axp_set_bits(axp->dev,AXP19_GPIO67_CFG0,0x01);
					return axp_set_bits(axp->dev,AXP19_GPIO67_CFG1,0x04);
			default:return -ENXIO;
		}
	}
	return -ENXIO;
}
Example #25
0
static int axp_gpio_set_data(int gpio, int value)
{
	struct axp_dev *axp = NULL;

	if ((0 <= gpio) && (4 >= gpio)) {
#ifdef CONFIG_AW_AXP22
		axp = axp_dev_lookup(AXP22);
#elif defined(CONFIG_AW_AXP81X)
		axp = axp_dev_lookup(AXP81X);
#endif
		if (NULL == axp) {
			printk("%s: %d axp data is null\n", __func__, __LINE__);
			return -ENXIO;
		}
	} else if ((5 <= gpio) && (6 >= gpio)) {
		axp = axp_dev_lookup(AXP15);
		if (NULL == axp) {
			printk("%s: %d axp data is null\n", __func__, __LINE__);
			return -ENXIO;
		}
	} else {
		return -ENXIO;
	}

	if(value){//high
		switch(gpio) {
			case 0: 
				return axp_update_sync(axp->dev,AXP_GPIO0_CFG,0x01,0x07);
			case 1: 
				return axp_update_sync(axp->dev,AXP_GPIO1_CFG,0x01,0x07);
			case 2: 
				return axp_set_bits(axp->dev,AXP_GPIO2_CFG,0x80);
			case 3: 
				axp_clr_bits(axp->dev,AXP_GPIO3_CFG,0x30);
				return axp_clr_bits(axp->dev,AXP_GPIO3_CFG, 0x08);
			case 4: 
				axp_clr_bits(axp->dev,AXP_GPIO4_CFG, 0x10);
				return axp_set_bits(axp->dev,AXP_GPIO4_STA,0x04);
			case 5:
				return axp_set_bits(axp->dev,AXP_GPIO5_CFG,0x03);
			case 6:
				return axp_set_bits(axp->dev,AXP_GPIO6_CFG,0x80);
			default:break;
		}
	}else{//low
		switch(gpio){
			case 0:
				return axp_update_sync(axp->dev,AXP_GPIO0_CFG,0x0,0x07);
			case 1: 
				return axp_update_sync(axp->dev,AXP_GPIO1_CFG,0x0,0x07);
			case 2: 
				return axp_clr_bits(axp->dev,AXP_GPIO2_CFG,0x80);
			case 3: 
				axp_set_bits(axp->dev,AXP_GPIO3_CFG,0x30);
				return axp_clr_bits(axp->dev,AXP_GPIO3_CFG, 0x08);
			case 4: 
				axp_clr_bits(axp->dev,AXP_GPIO4_CFG, 0x10);
				return axp_clr_bits(axp->dev,AXP_GPIO4_STA,0x04);
			case 5:
				return axp_update_sync(axp->dev,AXP_GPIO5_CFG,0x02,0x07);
			case 6:
				return axp_clr_bits(axp->dev,AXP_GPIO6_CFG,0x80);
			default:break;
		}
	}
	return -ENXIO;
}
Example #26
0
static void axp_usb(struct work_struct *work)
{
	int var;
	uint8_t tmp,val;

	DBG_PSY_MSG(DEBUG_CHG, "[axp_usb]axp_usbcurflag = %d\n",axp_usbcurflag);

	axp_read(axp_charger->master, AXP_CHARGE_STATUS, &val);
	if((val & 0x10) == 0x00){/*usb or usb adapter can not be used*/
		DBG_PSY_MSG(DEBUG_CHG, "USB not insert!\n");
		axp_clr_bits(axp_charger->master, AXP_CHARGE_VBUS, 0x02);
		axp_set_bits(axp_charger->master, AXP_CHARGE_VBUS, 0x01);
	}else if(CHARGE_USB_20 == axp_usbcurflag){
		DBG_PSY_MSG(DEBUG_CHG, "set usbcur_pc %d mA\n",axp_config->pmu_usbcur_pc);
		if(axp_config->pmu_usbcur_pc){
			var = axp_config->pmu_usbcur_pc * 1000;
			if(var >= 900000)
				axp_clr_bits(axp_charger->master, AXP_CHARGE_VBUS, 0x03);
			else if (var < 900000){
				axp_clr_bits(axp_charger->master, AXP_CHARGE_VBUS, 0x02);
				axp_set_bits(axp_charger->master, AXP_CHARGE_VBUS, 0x01);
			}
		}else//not limit
			axp_set_bits(axp_charger->master, AXP_CHARGE_VBUS, 0x03);
	}else if (CHARGE_USB_30 == axp_usbcurflag){
		axp_clr_bits(axp_charger->master, AXP_CHARGE_VBUS, 0x03);
	}else {
		DBG_PSY_MSG(DEBUG_CHG, "set usbcur %d mA\n",axp_config->pmu_usbcur);
		if((axp_config->pmu_usbcur) && (axp_config->pmu_usbcur_limit)){
			var = axp_config->pmu_usbcur * 1000;
			if(var >= 900000)
				axp_clr_bits(axp_charger->master, AXP_CHARGE_VBUS, 0x03);
			else if (var < 900000){
				axp_clr_bits(axp_charger->master, AXP_CHARGE_VBUS, 0x02);
				axp_set_bits(axp_charger->master, AXP_CHARGE_VBUS, 0x01);
			}
		}else //not limit
			axp_set_bits(axp_charger->master, AXP_CHARGE_VBUS, 0x03);
	}

	if(!vbus_curr_limit_debug){ //usb current not limit
		DBG_PSY_MSG(DEBUG_CHG, "vbus_curr_limit_debug = %d\n",vbus_curr_limit_debug);
		axp_set_bits(axp_charger->master, AXP_CHARGE_VBUS, 0x03);
	}

	if(CHARGE_USB_20 == axp_usbvolflag){
		DBG_PSY_MSG(DEBUG_CHG, "set usbvol_pc %d mV\n",axp_config->pmu_usbvol_pc);
		if(axp_config->pmu_usbvol_pc){
			axp_set_bits(axp_charger->master, AXP_CHARGE_VBUS, 0x40);
			var = axp_config->pmu_usbvol_pc * 1000;
			if(var >= 4000000 && var <=4700000){
				tmp = (var - 4000000)/100000;
				axp_read(axp_charger->master, AXP_CHARGE_VBUS,&val);
				val &= 0xC7;
				val |= tmp << 3;
				axp_write(axp_charger->master, AXP_CHARGE_VBUS,val);
			}else
				DBG_PSY_MSG(DEBUG_CHG, "set usb limit voltage error,%d mV\n",axp_config->pmu_usbvol_pc);
		}else
		    axp_clr_bits(axp_charger->master, AXP_CHARGE_VBUS, 0x40);
	}else if(CHARGE_USB_30 == axp_usbvolflag) {
		axp_read(axp_charger->master, AXP_CHARGE_VBUS,&val);
		val &= 0xC7;
		val |= 7 << 3;
		axp_write(axp_charger->master, AXP_CHARGE_VBUS,val);
	}else {
		DBG_PSY_MSG(DEBUG_CHG, "set usbvol %d mV\n",axp_config->pmu_usbvol);
		if((axp_config->pmu_usbvol) && (axp_config->pmu_usbvol_limit)){
			axp_set_bits(axp_charger->master, AXP_CHARGE_VBUS, 0x40);
			var = axp_config->pmu_usbvol * 1000;
			if(var >= 4000000 && var <=4700000){
				tmp = (var - 4000000)/100000;
				axp_read(axp_charger->master, AXP_CHARGE_VBUS,&val);
				val &= 0xC7;
				val |= tmp << 3;
				axp_write(axp_charger->master, AXP_CHARGE_VBUS,val);
			}else
				DBG_PSY_MSG(DEBUG_CHG, "set usb limit voltage error,%d mV\n",axp_config->pmu_usbvol);
		}else
		    axp_clr_bits(axp_charger->master, AXP_CHARGE_VBUS, 0x40);
	}
}
Example #27
0
int axp81x_init(struct axp_charger *charger)
{
	int ret = 0, var = 0;
	uint8_t val = 0;
	uint8_t ocv_cap[63];
	int Cur_CoulombCounter,rdc;

	ret = axp_battery_first_init(charger);
	if (ret)
		goto err_charger_init;

	/* usb /ac voltage limit */
	if(axp81x_config.pmu_usbvol){
		axp81x_usb_ac_vol_limit(charger, CHARGE_AC, axp81x_config.pmu_usbvol);
	}
	if(axp81x_config.pmu_usbvol_pc){
		axp81x_usb_ac_vol_limit(charger, CHARGE_USB_20, axp81x_config.pmu_usbvol_pc);
	}

	/* ac current limit */
	if(axp81x_config.pmu_usbcur){
		axp81x_usb_ac_current_limit(charger, CHARGE_AC, axp81x_config.pmu_usbcur);
	} else {
#ifdef BPI-M3
		axp81x_usb_ac_current_limit(charger, CHARGE_AC, 2500);
#else
		axp81x_usb_ac_current_limit(charger, CHARGE_AC, 4000);
#endif
	}
#ifdef BPI-M3
#else
printk("BPI-M3: set PMIC AC 4000mA\n");
	axp81x_usb_ac_current_limit(charger, CHARGE_AC, 4000);
#endif

	axp81x_chg_current_limit(axp81x_config.pmu_runtime_chgcur);

	/* set lowe power warning/shutdown level */
	axp_write(charger->master, AXP81X_WARNING_LEVEL,((axp81x_config.pmu_battery_warning_level1-5) << 4)+axp81x_config.pmu_battery_warning_level2);
	ocv_cap[0]  = axp81x_config.pmu_bat_para1;
	ocv_cap[1]  = 0xC1;
	ocv_cap[2]  = axp81x_config.pmu_bat_para2;
	ocv_cap[3]  = 0xC2;
	ocv_cap[4]  = axp81x_config.pmu_bat_para3;
	ocv_cap[5]  = 0xC3;
	ocv_cap[6]  = axp81x_config.pmu_bat_para4;
	ocv_cap[7]  = 0xC4;
	ocv_cap[8]  = axp81x_config.pmu_bat_para5;
	ocv_cap[9]  = 0xC5;
	ocv_cap[10] = axp81x_config.pmu_bat_para6;
	ocv_cap[11] = 0xC6;
	ocv_cap[12] = axp81x_config.pmu_bat_para7;
	ocv_cap[13] = 0xC7;
	ocv_cap[14] = axp81x_config.pmu_bat_para8;
	ocv_cap[15] = 0xC8;
	ocv_cap[16] = axp81x_config.pmu_bat_para9;
	ocv_cap[17] = 0xC9;
	ocv_cap[18] = axp81x_config.pmu_bat_para10;
	ocv_cap[19] = 0xCA;
	ocv_cap[20] = axp81x_config.pmu_bat_para11;
	ocv_cap[21] = 0xCB;
	ocv_cap[22] = axp81x_config.pmu_bat_para12;
	ocv_cap[23] = 0xCC;
	ocv_cap[24] = axp81x_config.pmu_bat_para13;
	ocv_cap[25] = 0xCD;
	ocv_cap[26] = axp81x_config.pmu_bat_para14;
	ocv_cap[27] = 0xCE;
	ocv_cap[28] = axp81x_config.pmu_bat_para15;
	ocv_cap[29] = 0xCF;
	ocv_cap[30] = axp81x_config.pmu_bat_para16;
	ocv_cap[31] = 0xD0;
	ocv_cap[32] = axp81x_config.pmu_bat_para17;
	ocv_cap[33] = 0xD1;
	ocv_cap[34] = axp81x_config.pmu_bat_para18;
	ocv_cap[35] = 0xD2;
	ocv_cap[36] = axp81x_config.pmu_bat_para19;
	ocv_cap[37] = 0xD3;
	ocv_cap[38] = axp81x_config.pmu_bat_para20;
	ocv_cap[39] = 0xD4;
	ocv_cap[40] = axp81x_config.pmu_bat_para21;
	ocv_cap[41] = 0xD5;
	ocv_cap[42] = axp81x_config.pmu_bat_para22;
	ocv_cap[43] = 0xD6;
	ocv_cap[44] = axp81x_config.pmu_bat_para23;
	ocv_cap[45] = 0xD7;
	ocv_cap[46] = axp81x_config.pmu_bat_para24;
	ocv_cap[47] = 0xD8;
	ocv_cap[48] = axp81x_config.pmu_bat_para25;
	ocv_cap[49] = 0xD9;
	ocv_cap[50] = axp81x_config.pmu_bat_para26;
	ocv_cap[51] = 0xDA;
	ocv_cap[52] = axp81x_config.pmu_bat_para27;
	ocv_cap[53] = 0xDB;
	ocv_cap[54] = axp81x_config.pmu_bat_para28;
	ocv_cap[55] = 0xDC;
	ocv_cap[56] = axp81x_config.pmu_bat_para29;
	ocv_cap[57] = 0xDD;
	ocv_cap[58] = axp81x_config.pmu_bat_para30;
	ocv_cap[59] = 0xDE;
	ocv_cap[60] = axp81x_config.pmu_bat_para31;
	ocv_cap[61] = 0xDF;
	ocv_cap[62] = axp81x_config.pmu_bat_para32;
	axp_writes(charger->master, 0xC0,63,ocv_cap);
	/* pok open time set */
	if(axp81x_config.pmu_pekon_time < 1000)
		val = 0x00;
	else if(axp81x_config.pmu_pekon_time < 2000){
		val = 0x40;
	}else if(axp81x_config.pmu_pekon_time < 3000){
		val = 0x80;
	}else {
		val = 0xc0;
	}
	axp_update(charger->master, AXP81X_POK_SET, val, 0xc0);
	var = axp81x_config.pmu_peklong_time;
	/* pok long time set*/
	if(axp81x_config.pmu_peklong_time < 1000)
		var = 1000;
	if(axp81x_config.pmu_peklong_time > 2500)
		var = 2500;
	val = (((var - 1000) / 500) << 4);
	axp_update(charger->master, AXP81X_POK_SET, val, 0x30);
	/* pek offlevel poweroff en set*/
	if(axp81x_config.pmu_pekoff_en)
		var = 1;
	else
		var = 0;
	val = (var << 3);
	axp_update(charger->master, AXP81X_POK_SET, val, 0x8);
	/*Init offlevel restart or not */
	if(axp81x_config.pmu_pekoff_func)
		axp_set_bits(charger->master,AXP81X_POK_SET,0x04); //restart
	else
		axp_clr_bits(charger->master,AXP81X_POK_SET,0x04); //not restart

	if(10 > axp81x_config.pmu_pekoff_delay_time)
		val = 0x00;
	else if(20 > axp81x_config.pmu_pekoff_delay_time)
		val = 0x01;
	else if(30 > axp81x_config.pmu_pekoff_delay_time)
		val = 0x02;
	else if(40 > axp81x_config.pmu_pekoff_delay_time)
		val = 0x03;
	else if(50 > axp81x_config.pmu_pekoff_delay_time)
		val = 0x04;
	else if(60 > axp81x_config.pmu_pekoff_delay_time)
		val = 0x05;
	else if(70 > axp81x_config.pmu_pekoff_delay_time)
		val = 0x06;
	else
		val = 0x07;
	axp_write(charger->master,AXP81X_POK_DELAY_SET,val);

	/* pek delay set */
	if (axp81x_config.pmu_pwrok_time < 32)
		val = ((axp81x_config.pmu_pwrok_time / 8) - 1);
	else
		val = ((axp81x_config.pmu_pwrok_time / 32) + 1);
	axp_update(charger->master, AXP81X_OFF_CTL, val, 0x3);

	//axp_read(charger->master,AXP81X_DCDC_MONITOR,&val);
	//if(axp81x_config.pmu_pwrok_shutdown_en)
	//	val |= 0x40;
	//axp_write(charger->master,AXP81X_DCDC_MONITOR,val);

	if(axp81x_config.pmu_reset_shutdown_en)
		axp_set_bits(charger->master,AXP81X_HOTOVER_CTL,0x01); //restart shutdown ldo/dcdc

	/* pek offlevel time set */
	if(axp81x_config.pmu_pekoff_time < 4000)
		var = 4000;
	if(axp81x_config.pmu_pekoff_time > 10000)
		var =10000;
	var = (axp81x_config.pmu_pekoff_time - 4000) / 2000 ;
	val = var ;
	axp_update(charger->master, AXP81X_POK_SET, val, 0x3);
	/*Init 16's Reset PMU en */
	if(axp81x_config.pmu_reset)
		axp_set_bits(charger->master,0x8F,0x08); //enable
	else
		axp_clr_bits(charger->master,0x8F,0x08); //disable
	/*Init IRQ wakeup en*/
	if(axp81x_config.pmu_IRQ_wakeup)
		axp_set_bits(charger->master,0x8F,0x80); //enable
	else
		axp_clr_bits(charger->master,0x8F,0x80); //disable
	/*Init N_VBUSEN status*/
	if(axp81x_config.pmu_vbusen_func)
		axp_set_bits(charger->master,0x8F,0x10); //output
	else
		axp_clr_bits(charger->master,0x8F,0x10); //input
	/*Init InShort status*/
	if(axp81x_config.pmu_inshort)
		axp_set_bits(charger->master,0x8F,0x60); //InShort
	else
		axp_clr_bits(charger->master,0x8F,0x60); //auto detect
	/*Init CHGLED function*/
	if(axp81x_config.pmu_chgled_func)
		axp_set_bits(charger->master,0x32,0x08); //control by charger
	else
		axp_clr_bits(charger->master,0x32,0x08); //drive MOTO
	/*set CHGLED Indication Type*/
	if(axp81x_config.pmu_chgled_type)
		axp_set_bits(charger->master,0x34,0x10); //Type B
	else
		axp_clr_bits(charger->master,0x34,0x10); //Type A
	/*Init PMU Over Temperature protection*/
	if(axp81x_config.pmu_hot_shutdowm)
		axp_set_bits(charger->master,0x8f,0x04); //enable
	else
		axp_clr_bits(charger->master,0x8f,0x04); //disable
	/*Init battery capacity correct function*/
	if(axp81x_config.pmu_batt_cap_correct)
		axp_set_bits(charger->master,0xb8,0x20); //enable
	else
		axp_clr_bits(charger->master,0xb8,0x20); //disable
	/* Init battery regulator enable or not when charge finish*/
	if(axp81x_config.pmu_bat_regu_en)
		axp_set_bits(charger->master,0x34,0x20); //enable
	else
		axp_clr_bits(charger->master,0x34,0x20); //disable
	if(!axp81x_config.pmu_batdeten)
		axp_clr_bits(charger->master,AXP81X_PDBC,0x40);
	else
		axp_set_bits(charger->master,AXP81X_PDBC,0x40);
	/* RDC initial */
	axp_read(charger->master, AXP81X_RDC0,&val);
	if((axp81x_config.pmu_battery_rdc) && (!(val & 0x40))){
		rdc = (axp81x_config.pmu_battery_rdc * 10000 + 5371) / 10742;
		axp_write(charger->master, AXP81X_RDC0, ((rdc >> 8) & 0x1F)|0x80);
		axp_write(charger->master,AXP81X_RDC1,rdc & 0x00FF);
	}
int axp_gpio_set_io(int gpio, int io_state)
{
	if(io_state == 1){
		switch(gpio)
		{
			case 0: return axp_clr_bits(&axp->dev,AXP19_GPIO0_CFG,0x07);
			case 1: return axp_clr_bits(&axp->dev,AXP19_GPIO1_CFG,0x07);
			case 2: return axp_clr_bits(&axp->dev,AXP19_GPIO2_CFG,0x07);
			case 3: axp_set_bits(&axp->dev,AXP19_GPIO34_CFG,0x81);
					return axp_clr_bits(&axp->dev,AXP19_GPIO34_CFG,0x02);
			case 4: axp_set_bits(&axp->dev,AXP19_GPIO34_CFG,0x84);
					return axp_clr_bits(&axp->dev,AXP19_GPIO34_CFG,0x08);
			case 5: axp_set_bits(&axp->dev,AXP19_GPIO5_CFG,0x80);
					return axp_clr_bits(&axp->dev,AXP19_GPIO5_CFG,0x40);
			case 6: axp_set_bits(&axp->dev,AXP19_GPIO67_CFG0,0x01);
					return axp_clr_bits(&axp->dev,AXP19_GPIO67_CFG1,0x40);
			case 7: axp_set_bits(&axp->dev,AXP19_GPIO67_CFG0,0x01);
					return axp_clr_bits(&axp->dev,AXP19_GPIO67_CFG1,0x04);
			default:return -ENXIO;
		}
	}
	else if(io_state == 0){
		switch(gpio)
		{
			case 0: axp_clr_bits(&axp->dev,AXP19_GPIO0_CFG,0x06);
					return axp_set_bits(&axp->dev,AXP19_GPIO0_CFG,0x01);
			case 1: axp_clr_bits(&axp->dev,AXP19_GPIO1_CFG,0x06);
					return axp_set_bits(&axp->dev,AXP19_GPIO1_CFG,0x01);
			case 2: axp_clr_bits(&axp->dev,AXP19_GPIO2_CFG,0x06);
					return axp_set_bits(&axp->dev,AXP19_GPIO2_CFG,0x01);
			case 3: axp_set_bits(&axp->dev,AXP19_GPIO34_CFG,0x82);
					return axp_clr_bits(&axp->dev,AXP19_GPIO34_CFG,0x01);
			case 4: axp_set_bits(&axp->dev,AXP19_GPIO34_CFG,0x88);
					return axp_clr_bits(&axp->dev,AXP19_GPIO34_CFG,0x04);
			case 5: axp_set_bits(&axp->dev,AXP19_GPIO5_CFG,0xC0);
			case 6: axp_set_bits(&axp->dev,AXP19_GPIO67_CFG0,0x01);
					return axp_set_bits(&axp->dev,AXP19_GPIO67_CFG1,0x40);
			case 7: axp_set_bits(&axp->dev,AXP19_GPIO67_CFG0,0x01);
					return axp_set_bits(&axp->dev,AXP19_GPIO67_CFG1,0x04);
			default:return -ENXIO;
		}
	}
	return -EINVAL;
}
Example #29
0
void axp20_power_off(int power_start)
{
	uint8_t val;
	struct axp_dev *axp;
	axp = axp_dev_lookup(AXP20);
	if (NULL == axp) {
		printk("%s: axp data is null\n", __func__);
		return;
	}
	if(axp20_config.pmu_pwroff_vol >= 2600 && axp20_config.pmu_pwroff_vol <= 3300){
		if (axp20_config.pmu_pwroff_vol > 3200){
			val = 0x7;
		}
		else if (axp20_config.pmu_pwroff_vol > 3100){
			val = 0x6;
		}
		else if (axp20_config.pmu_pwroff_vol > 3000){
			val = 0x5;
		}
		else if (axp20_config.pmu_pwroff_vol > 2900){
			val = 0x4;
		}
		else if (axp20_config.pmu_pwroff_vol > 2800){
			val = 0x3;
		}
		else if (axp20_config.pmu_pwroff_vol > 2700){
			val = 0x2;
		}
		else if (axp20_config.pmu_pwroff_vol > 2600){
			val = 0x1;
		}
		else
			val = 0x0;

		axp_update(axp->dev, POWER20_VOFF_SET, val, 0x7);
	}
	val = 0xff;
	if (!use_cou){
		axp_read(axp->dev, POWER20_COULOMB_CTL, &val);
		val &= 0x3f;
		axp_write(axp->dev, POWER20_COULOMB_CTL, val);
		val |= 0x80;
		val &= 0xbf;
		axp_write(axp->dev, POWER20_COULOMB_CTL, val);
	}
	//led auto
	axp_clr_bits(axp->dev,0x32,0x38);
	axp_clr_bits(axp->dev,0xb9,0x80);

	printk("[axp] send power-off command!\n");
	mdelay(20);
	if(axp20_config.power_start != 1){
		axp_write(axp->dev, POWER20_INTSTS3, 0x03);
		axp_read(axp->dev, POWER20_STATUS, &val);
		if(val & 0xF0){
			axp_read(axp->dev, POWER20_MODE_CHGSTATUS, &val);
		    	if(val & 0x20){
				printk("[axp] set flag!\n");
		        	axp_write(axp->dev, POWER20_DATA_BUFFERC, 0x0f);
	            		mdelay(20);
			    	printk("[axp] reboot!\n");
			    	machine_restart(NULL);
			    	printk("[axp] warning!!! arch can't ,reboot, maybe some error happend!\n");
		    	}
		}
	}
	axp_write(axp->dev, POWER20_DATA_BUFFERC, 0x00);
	//axp_write(&axp->dev, 0xf4, 0x06);
	//axp_write(&axp->dev, 0xf2, 0x04);
	//axp_write(&axp->dev, 0xff, 0x01);
	//axp_write(&axp->dev, 0x04, 0x01);
	//axp_clr_bits(&axp->dev, 0x03, 0xc0);
	//axp_write(&axp->dev, 0xff, 0x00);
	//mdelay(20);
	axp_set_bits(axp->dev, POWER20_OFF_CTL, 0x80);
	mdelay(20);
	printk("[axp] warning!!! axp can't power-off, maybe some error happend!\n");
}