Beispiel #1
0
static irqreturn_t max8925_charger_handler(int irq, void *data)
{
	struct max8925_power_info *info = (struct max8925_power_info *)data;
	struct max8925_chip *chip = info->chip;

	switch (irq - chip->irq_base) {
	case MAX8925_IRQ_VCHG_DC_R:
		info->ac_online = 1;
		__set_charger(info, 1);
		dev_dbg(chip->dev, "Adapter inserted\n");
		break;
	case MAX8925_IRQ_VCHG_DC_F:
		info->ac_online = 0;
		__set_charger(info, 0);
		dev_dbg(chip->dev, "Adapter removed\n");
		break;
	case MAX8925_IRQ_VCHG_THM_OK_F:
		/* Battery is not ready yet */
		dev_dbg(chip->dev, "Battery temperature is out of range\n");
		/* Fall through */
	case MAX8925_IRQ_VCHG_DC_OVP:
		dev_dbg(chip->dev, "Error detection\n");
		__set_charger(info, 0);
		break;
	case MAX8925_IRQ_VCHG_THM_OK_R:
		/* Battery is ready now */
		dev_dbg(chip->dev, "Battery temperature is in range\n");
		break;
	case MAX8925_IRQ_VCHG_SYSLOW_R:
		/* VSYS is low */
		dev_info(chip->dev, "Sys power is too low\n");
		break;
	case MAX8925_IRQ_VCHG_SYSLOW_F:
		dev_dbg(chip->dev, "Sys power is above low threshold\n");
		break;
	case MAX8925_IRQ_VCHG_DONE:
		__set_charger(info, 0);
		dev_dbg(chip->dev, "Charging is done\n");
		break;
	case MAX8925_IRQ_VCHG_TOPOFF:
		dev_dbg(chip->dev, "Charging in top-off mode\n");
		break;
	case MAX8925_IRQ_VCHG_TMR_FAULT:
		__set_charger(info, 0);
		dev_dbg(chip->dev, "Safe timer is expired\n");
		break;
	case MAX8925_IRQ_VCHG_RST:
		__set_charger(info, 0);
		dev_dbg(chip->dev, "Charger is reset\n");
		break;
	}
	return IRQ_HANDLED;
}
static __devinit int rt9536_probe(struct platform_device *pdev)
{
	struct rt9536_chip *chip;
	int ret = 0;

	printk("@@@@ Inside rt9536_probe @@@@\n");

	chip = kzalloc(sizeof(*chip), GFP_KERNEL);
	if (!chip)
		return -ENOMEM;

	/* INIT_DELAYED_WORK(&chip->charge_work, rt9536_charge);
	INIT_DELAYED_WORK(&chip->charge_done_work, rt9536_charge_done); */

	/* chip->pdata = client->dev.platform_data; */
	wake_lock_init(&chip->wl, WAKE_LOCK_SUSPEND, "rt9536");
	spin_lock_init(&chip->enable_lock);
	ret = qpnp_is_pon_ready();

	if (ret)
		goto out;

	if (pdev->dev.of_node) {
		chip->pdata = devm_kzalloc(&pdev->dev,
				sizeof(struct rt9536_platform_data),
				GFP_KERNEL);
		if (chip->pdata == NULL) {
			pr_err("%s: no pdata\n", __func__);
			return -ENOMEM;
		}
		pdev->dev.platform_data = chip->pdata;
		rt9536_parse_dt(&pdev->dev, chip->pdata);

		if (!gpio_is_valid(chip->pdata->wlc_en_set_pin)) {
			pr_err("Fail to get named gpio for wlc_en_set_pin.\n");
			goto err_qpio_request;
		} else {
			ret = gpio_request(chip->pdata->wlc_en_set_pin, "wlc_en_set_pin");

			if (ret) {
				pr_err("request wlc_en_set_pin gpio failed, ret=%d\n", ret);
				/* gpio_free(chip->pdata->wlc_en_set_pin); */
				goto err_qpio_request;
			}
			gpio_tlmm_config(GPIO_CFG(chip->pdata->wlc_en_set_pin, 0, GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL, GPIO_CFG_4MA), GPIO_CFG_ENABLE);
		}
			/* initialize irq of gpio_hall */
		if (chip->pdata->wlc_irq_pin > 0) {
			ret = gpio_request(chip->pdata->wlc_irq_pin,
						"wlc_irq");
			if (ret) {
				pr_err("%s :gpio request fail for wlc_irq and ret is %d\n", __func__, ret);
				gpio_free(chip->pdata->wlc_irq_pin);
				goto err_request_irq;
			}
			ret = gpio_direction_input(chip->pdata->wlc_irq_pin);
			gpio_tlmm_config(GPIO_CFG(chip->pdata->wlc_irq_pin, 0, GPIO_CFG_INPUT, GPIO_CFG_PULL_UP, GPIO_CFG_4MA), GPIO_CFG_ENABLE);
				chip->chg_online = gpio_get_value(chip->pdata->wlc_irq_pin);
				printk("[RT9536] %s: chg_online is %d\n", __func__, chip->chg_online);

			if (ret) {
				pr_err("%s :gpio_direction_input fail for wlc_irq and ret is %d\n", __func__, ret);
				gpio_free(chip->pdata->wlc_irq_pin);
				goto err_request_irq;
			}

			ret = request_irq(chip->pdata->wlc_irq, wlc_irq_handler, chip->pdata->irq_flags, "rt9536", chip);
			if (ret) {
				pr_err("%s :request_irq and ret is %d\n", __func__, ret);
				gpio_free(chip->pdata->wlc_irq_pin);
				goto err_request_irq;
			}

#if 0
			if (enable_irq_wake(chip->pdata->wlc_irq) == 0) {
				pr_err("%s :enable_irq_wake Enable(1)\n", __func__);
			} else {
				pr_err("%s :enable_irq_wake failed(1)\n", __func__);
				if (chip->pdata->wlc_irq)
					free_irq(chip->pdata->wlc_irq, 0);
				goto out;
			}
#endif
		}
	}

	/* i2c_set_clientdata(client, chip); */

	chip->charger = rt9536_charger_ps;
#if 1
	ret = power_supply_register(&pdev->dev, &chip->charger);
	if (ret) {
		dev_err(&pdev->dev, "failed: power supply register\n");
		/* i2c_set_clientdata(client, NULL); */
		goto out;
	}
#endif
	chip->chg_done = 0;
	chip->chg_online = 0;

	INIT_WORK(&chip->wireless_interrupt_work, wlc_interrupt_worker);
	INIT_WORK(&chip->wireless_set_online_work, wlc_set_online_work);
	INIT_WORK(&chip->wireless_set_offline_work, wlc_set_offline_work);
	INIT_WORK(&chip->wireless_eoc_work, wlc_eoc_work);

#ifndef BIGLAKE_TEST
	printk("[RT9536] wlc_is_connected is %d\n", wlc_is_connected());
#endif

	printk("%s : chip->pdata->irq_flags = [%d]\n", __func__, (int)chip->pdata->irq_flags);

	the_chip = chip;
#if 0
	disable_irq(chip->pdata->wlc_irq);
#endif
	/* disable_irq(chip->pdata->wlc_irq); */
	wlc_enable_irq(chip, 0);
	if (rt9536_set_charger_enable(chip, 0)) {
		pr_err("%s : charger disable fail!!!\n", __func__);
	}
	msleep(10);
	if (rt9536_set_charger_enable(chip, 1)) {
		pr_err("%s : charger enable fail!!!\n", __func__);
	}
	/* msleep(3); */
	if (rt9536_set_cc_mode_4_35V(chip)) {
		pr_err("%s : CC mode setting fail!!!\n", __func__);
	}
	/* schedule_work(&chip->wireless_interrupt_work); */
	msleep(100);
	/* enable_irq(chip->pdata->wlc_irq); */
	wlc_enable_irq(chip, 1);
	if (wlc_is_connected()) {
		/* disable_irq(chip->pdata->wlc_irq); */
		if (wlc_check_irq_pin(chip) == 0) {
			/* enable_irq(chip->pdata->wlc_irq); */
			wake_lock(&chip->wl);
			chip->chg_online = 1;
			power_supply_changed(&chip->charger);
			printk("[RT9536] WLC is connected\n");
		} else {
			schedule_work(&chip->wireless_eoc_work);
		}
	} else {
		schedule_work(&chip->wireless_set_offline_work);
		printk("[RT9536] WLC is disconnected\n");
	}

	/* disable_irq(chip->pdata->wlc_irq); */

#if 0
	__set_charger(chip, 1);	/* just for test */

#ifdef BQ24160_CABLE_PWRON_INT
	ret = request_threaded_irq(client->irq, NULL, bq24160_valid_handler,
		IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, client->name, chip);
#else
	ret = request_threaded_irq(client->irq, NULL, bq24160_charger_handler,
		IRQF_ONESHOT | IRQF_TRIGGER_LOW, client->name, chip);
#endif

	if (unlikely(ret < 0)) {
		dev_err(&client->dev, "%s failed to request IRQ %d\n", __func__, ret);
		goto out;
	}
	irq_set_irq_wake(client->irq, 1);
#endif

	printk("[RT9536] rt9536_probe done\n");
	return 0;

err_request_irq:
	if (chip->pdata->wlc_irq)
		free_irq(chip->pdata->wlc_irq, 0);

err_qpio_request:
	 gpio_free(chip->pdata->wlc_en_set_pin);

out:

	wake_lock_destroy(&chip->wl);
	kfree(chip);
	the_chip = NULL;
	return ret;
}