/**
 * Show the charger status.
 */
STATIC ssize_t charger_show(struct device *_dev,
              struct device_attribute *attr, char *buf)
{
    struct lm_device *lm_dev = container_of(_dev, struct lm_device, dev);
    struct hiusb_info *hiusb_info;
    int ret;
    char charger_type[10];

    hiusb_info = lm_dev->hiusb_info;
    ret = get_charger_name();
    switch (ret) {
        case CHARGER_TYPE_USB:
            strcpy(charger_type, "SDP");
            break;
        case CHARGER_TYPE_BC_USB:
            strcpy(charger_type, "CDP");
            break;
        case CHARGER_TYPE_NON_STANDARD:
            strcpy(charger_type, "SDP");
            break;
        case CHARGER_TYPE_STANDARD:
            strcpy(charger_type, "DCP");
            break;
        case CHARGER_REMOVED:
            strcpy(charger_type, "REMOVED");
            break;
        default:
            return sprintf(buf, "usb not init\n");
    }

    return sprintf(buf, "charger_type:%d(%s)\n", ret, charger_type);
}
int notify_mdm_off_to_pm(void)
{
    if (system_state != SYSTEM_RUNNING)
        return 0;
    if ((hisi_battery_voltage() < 3400) && (get_charger_name() == CHARGER_REMOVED)){
        modem_off = true;
        return 1;
    }
    return 0;
}
static int bq_charger_event(struct notifier_block *nb, unsigned long event,
            void *_data)
{
    struct bq_bci_device_info *di;
    int ret = 0;
    di = container_of(nb, struct bq_bci_device_info, nb);

    switch (event) {
    case VCHRG_START_USB_CHARGING_EVENT:
        pr_jank(JL_USBCHARGING_START, "JL_USBCHARGING_START");
        di->usb_online = 1;
        di->ac_online = 0;
        di->charge_status = POWER_SUPPLY_STATUS_CHARGING;
        di->power_supply_status = POWER_SUPPLY_HEALTH_GOOD;
        di->charge_full_count = 0;
        break;

    case VCHRG_START_AC_CHARGING_EVENT:
        di->ac_online = 1;
        di->usb_online = 0;
        di->charge_status = POWER_SUPPLY_STATUS_CHARGING;
        di->power_supply_status = POWER_SUPPLY_HEALTH_GOOD;
        di->charge_full_count = 0;
        break;

    case VCHRG_STOP_CHARGING_EVENT:
        pr_jank(JL_USBCHARGING_END, "JL_USBCHARGING_END");
        di->usb_online = 0;
        di->ac_online = 0;
        di->charge_status = POWER_SUPPLY_STATUS_DISCHARGING;
        di->power_supply_status = POWER_SUPPLY_HEALTH_UNKNOWN;
        di->charge_full_count = 0;
        break;

    case VCHRG_START_CHARGING_EVENT:
        di->charge_status = POWER_SUPPLY_STATUS_CHARGING;
        di->power_supply_status = POWER_SUPPLY_HEALTH_GOOD;
        break;

    case VCHRG_NOT_CHARGING_EVENT:
        di->charge_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
        di->power_supply_status = POWER_SUPPLY_HEALTH_GOOD;
        break;
    case VCHRG_CHARGE_DONE_EVENT:
   /****Do not need charge status change to full when bq24192 chargedone.
    because bq27510 will insure the charge status to full when capacity is 100.
        di->charge_status = POWER_SUPPLY_STATUS_FULL;
        di->power_supply_status = POWER_SUPPLY_HEALTH_GOOD;
    *****************************************************************/
        break;
    case VCHRG_POWER_SUPPLY_OVERVOLTAGE:
        di->charge_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
        di->power_supply_status = POWER_SUPPLY_HEALTH_OVERVOLTAGE;
        break;

	case VCHRG_POWER_SUPPLY_WEAKSOURCE:
        di->charge_status = POWER_SUPPLY_STATUS_NOT_CHARGING;
	    di->power_supply_status = POWER_SUPPLY_HEALTH_UNSPEC_FAILURE;
	break;

    case BATTERY_LOW_WARNING:
        break;
    case BATTERY_LOW_SHUTDOWN:
        wake_lock(&low_power_lock);
        is_low_power_locked = 1;
        break;
    default:
        dev_err(di->dev, "%s defualt run.\n", __func__);
        break;
    }

    if ((di->usb_online || di->ac_online) && di->capacity == 100)
        di->charge_status = POWER_SUPPLY_STATUS_FULL;
   /*in case charger can not get the report of charger removed, so
    * update the status of charger.*/
    if(get_charger_name() == CHARGER_REMOVED){
        di->usb_online = 0;
        di->ac_online = 0;
        di->charge_status = POWER_SUPPLY_STATUS_DISCHARGING;
        di->power_supply_status = POWER_SUPPLY_HEALTH_UNKNOWN;
        di->charge_full_count = 0;
    }

    if(event == VCHRG_CHARGE_DONE_EVENT)
        di->chargedone_stat = 1;
    else
        di->chargedone_stat = 0;
    if (VCHRG_START_CHARGING_EVENT != event)
    {
        dev_info(di->dev,"received event = %lx, charge_status = %d\n",event,di->charge_status);
    }
    power_supply_changed(&di->bat);
    return ret;
}
Example #4
0
static int __devinit k3_bq24161_charger_probe(struct i2c_client *client,
				 const struct i2c_device_id *id)
{
	u8 read_reg = 0;
	int ret = 0;
	enum usb_charger_type plugin_stat = CHARGER_REMOVED;
	struct k3_bq24161_device_info *di = NULL;
	struct k3_bq24161_platform_data *pdata = NULL;
	/*enum plugin_status plugin_stat;*/

	if (!g_battery_measure_by_bq27510_device) {
		dev_err(&client->dev, "g_battery_measure_by_bq27510_device is NULL!\n");
		return -ENOMEM;
	}

	pdata = client->dev.platform_data;
	if (!pdata) {
		dev_err(&client->dev, "pdata is NULL!\n");
		return -ENOMEM;
	}

	di = kzalloc(sizeof(*di), GFP_KERNEL);
	if (!di) {
		dev_err(&client->dev, "di is NULL!\n");
		return -ENOMEM;
	}

	di->dev = &client->dev;
	di->client = client;

	i2c_set_clientdata(client, di);

	ret = k3_bq24161_read_byte(di, &read_reg, REG_PART_REVISION);

	if (ret < 0) {
		dev_err(&client->dev, "chip not present at address %x\n",
								client->addr);
		ret = -EINVAL;
		goto err_kfree;
	}

	if (((read_reg & BQ24161_VERSION_MSK) == 0x00)
		&& (client->addr == I2C_ADDR_BQ24161))
		di->bqchip_version = BQ24161;

	if (di->bqchip_version == 0) {
		dev_err(&client->dev, "unknown bq chip\n");
		dev_err(&client->dev, "Chip address %x", client->addr);
		dev_err(&client->dev, "bq chip version reg value %x", read_reg);
		ret = -EINVAL;
		goto err_kfree;
	}

	di->max_voltagemV = pdata->max_charger_voltagemV;
	di->max_currentmA = pdata->max_charger_currentmA;
	di->voltagemV = di->max_voltagemV;
	di->currentmA = CURRENT_USB_CHARGE_IN ;
	di->term_currentmA = CURRENT_TERM_CHARGE_IN;
	di->dppm_voltagemV = VOLT_DPPM_ADJUST;
	di->cin_limit = CURRENT_USB_LIMIT_IN;
	di->gpio = pdata->gpio;

	/**********ADD BY 00186176 begin****************/
	 /* Set iomux normal */
#ifdef CONFIG_GPIO_BAT
	if (!di->piomux_block)
		di->piomux_block  = iomux_get_block("block_charger");

	if (!di->pblock_config)
		di->pblock_config = iomux_get_blockconfig("block_charger");

	ret = blockmux_set(di->piomux_block, di->pblock_config, NORMAL);
	if (ret) {
		dev_err(&client->dev, "blockmux_set NORMAL failed, ret=%d\n", ret);
		goto err_kfree;
	}
#endif

    /*set gpio_074 to control CD pin to disable/enable bq24161 IC*/
	ret = gpio_request(di->gpio, "gpio_074_cd");
	if (ret) {
		dev_err(&client->dev, "could not request irq\n");
		ret = -ENOMEM;
		goto err_io;
	}

	 /* set charger CD pin to low level and enable it to supply power normally*/
	gpio_direction_output(di->gpio, 0);

	 /**********ADD BY 00186176 END****************/

	di->enable_low_chg = ENABLE_LOW_CHG;

	/*enable low charge,100mA charging*/
	k3_bq24161_config_safety_reg(di);

	/*disable charge current termination*/
	di->enable_iterm = DISABLE_ITERM;

	di->factory_flag = 0;

	di->enable_ce = ENABLE_CE;
	di->hz_mode = 0;
	di->cd_active = 0;

#if BQ2416X_USE_WAKE_LOCK
	wake_lock_init(&di->charger_wake_lock, WAKE_LOCK_SUSPEND, "charger_wake_lock");
#endif

	INIT_DELAYED_WORK(&di->bq24161_charger_work,
				k3_bq24161_charger_work);

	INIT_WORK(&di->usb_work, k3_bq24161_usb_charger_work);

	di->active = 0;
	di->params.enable = 1;
	di->cfg_params = 1;
	/*di->enable_iterm = 1;*/

	k3_bq24161_config_control_reg(di);
	k3_bq24161_config_voltage_reg(di);
	k3_bq24161_config_current_reg(di);
	k3_bq24161_config_dppm_voltage_reg(di, di->dppm_voltagemV);
	k3_bq24161_config_safety_reg(di);

	ret = sysfs_create_group(&client->dev.kobj, &k3_bq24161_attr_group);
	if (ret) {
		dev_err(&client->dev, "could not create sysfs files\n");
		goto err_gpio;
	}

	/**********ADD BY 00186176 begin****************/

	di->nb.notifier_call = k3_bq24161_usb_notifier_call;

	ret = hiusb_charger_registe_notifier(&di->nb);
	if (ret < 0) {
		dev_err(&client->dev, "hiusb_charger_registe_notifier failed\n");
		goto err_sysfs;
	}

	plugin_stat = get_charger_name();
	if ((CHARGER_TYPE_USB == plugin_stat) || (CHARGER_TYPE_NON_STANDARD == plugin_stat)) {
		di->event = plugin_stat;
		k3_bq24161_start_500mA_charger(di);
	} else if (CHARGER_TYPE_BC_USB == plugin_stat) {
		k3_bq24161_start_BCUSB_charger(di);
	} else if (CHARGER_TYPE_STANDARD == plugin_stat) {
		k3_bq24161_start_ac_charger(di);
	} else {
		k3_bq24161_stop_charger(di);
	}

	return 0;

err_sysfs:
	sysfs_remove_group(&client->dev.kobj, &k3_bq24161_attr_group);
err_gpio:
	gpio_free(di->gpio);
err_io:
#ifdef CONFIG_GPIO_BAT
	if (blockmux_set(di->piomux_block, di->pblock_config, LOWPOWER))
		dev_err(&client->dev, "blockmux_set LOWPOWER failed\n");
#endif
	/**********ADD BY 00186176 END****************/
err_kfree:
	kfree(di);
	di = NULL;

	return ret;
}