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 }
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 }
static int axp_ldoio0_disable(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) return axp_clr_bits(axp_dev, info->enable_reg,0x07); #endif #if defined (CONFIG_KP_AXP19) axp_set_bits(axp_dev, info->enable_reg,0x05); return axp_clr_bits(axp_dev, info->enable_reg,0x02); #endif }
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; }
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_adc_set(struct axp_charger *charger) { int ret ; uint8_t val; /*enable adc and set adc */ val= AXP81X_ADC_BATVOL_ENABLE | AXP81X_ADC_BATCUR_ENABLE; if (0 != axp81x_config.pmu_temp_enable) val = val | AXP81X_ADC_TSVOL_ENABLE; ret = axp_update(charger->master, AXP81X_ADC_CONTROL, val , AXP81X_ADC_BATVOL_ENABLE | AXP81X_ADC_BATCUR_ENABLE | AXP81X_ADC_TSVOL_ENABLE); if (ret) return ret; val = 0; switch (charger->sample_time/100){ case 1: val &= ~(3 << 4);break; case 2: val &= ~(3 << 4);val |= 1 << 4;break; case 4: val &= ~(3 << 4);val |= 2 << 4;break; case 8: val |= 3 << 4;break; default: break; } ret = axp_update(charger->master, AXP81X_ADC_CONTROL4, val, 0x30); if (ret) return ret; if (0 != axp81x_config.pmu_temp_enable){ ret = axp_clr_bits(axp_charger->master, AXP81X_ADC_CONTROL3, 0x04); if (ret) return ret; } return 0; }
static int axp_ldoio0_disable(struct regulator_dev *rdev) { struct axp_regulator_info *info = rdev_get_drvdata(rdev); struct device *axp_dev = to_axp_dev(rdev); return axp_clr_bits(axp_dev, info->enable_reg,0x07); }
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; }
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_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; }
static int axp_pmx_set(int gpio, int mux) { struct axp_dev *axp = NULL; #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; } if(mux == 1){//output switch(gpio){ case 0: return axp_clr_bits_sync(axp->dev,AXP_GPIO0_CFG, 0x06); case 1: return axp_clr_bits_sync(axp->dev,AXP_GPIO1_CFG, 0x06); case 2: return 0; case 3: return axp_clr_bits(axp->dev,AXP_GPIO3_CFG, 0x08); case 4: return axp_clr_bits(axp->dev,AXP_GPIO4_CFG, 0x10); case 5: return 0; default:return -ENXIO; } } else if(mux == 0){//input switch(gpio){ case 0: axp_clr_bits_sync(axp->dev,AXP_GPIO0_CFG,0x05); return axp_set_bits_sync(axp->dev,AXP_GPIO0_CFG,0x02); case 1: axp_clr_bits_sync(axp->dev,AXP_GPIO1_CFG,0x05); return axp_set_bits_sync(axp->dev,AXP_GPIO1_CFG,0x02); case 2: printk("This IO can not config as an input!"); return -EINVAL; case 3: printk("This IO can not config as an input!"); return -EINVAL; case 4: printk("This IO can not config as an input!"); return -EINVAL; case 5: printk("This IO can not config as an input!"); return -EINVAL; default:return -ENXIO; } } return -ENXIO; }
void axp_chg_exit(struct axp_charger *charger) { if (axp_config->pmu_init_bc_en) { /* enable BC */ axp_clr_bits(charger->master, AXP_BC_SET, 0x01); } else { cancel_delayed_work_sync(&(charger->usbwork)); del_timer_sync(&(charger->usb_status_timer)); } return; }
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; }
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 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;
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;
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 }
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; }
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; }
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; }
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; }
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 }
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; case 'F': case 'f': case '4': val = 2; break; default: val = 3; break; } if(info->desc.id == AXP18_ID_BUCK1) { if(val == 0) axp_clr_bits(axp_dev, AXP18_BUCKMODE,0x80); else if(val == 1) axp_update(axp_dev, AXP18_BUCKMODE,0x80,0x84); else if(val == 2) axp_update(axp_dev,AXP18_BUCKMODE,0x84,0x84); else return -EINVAL; } else if(info->desc.id == AXP18_ID_BUCK2) { if(val == 0) axp_clr_bits(axp_dev, AXP19_BUCKMODE,0x40); else if(val == 1) axp_update(axp_dev, AXP18_BUCKMODE,0x40,0x42); else if(val == 2) axp_update(axp_dev,AXP18_BUCKMODE,0x42,0x42); else return -EINVAL; } else if(info->desc.id == AXP18_ID_BUCK3) { if(val == 0) axp_clr_bits(axp_dev, AXP18_BUCKMODE,0x20); else if(val == 1) axp_update(axp_dev, AXP19_BUCKMODE,0x20,0x21); else if(val == 2) axp_update(axp_dev, AXP19_BUCKMODE,0x21,0x21); else return -EINVAL; } else return -ENXIO; return count; }
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); }
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; }
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); } }
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; }
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"); }