Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 50598b2f authored by Kavya Nunna's avatar Kavya Nunna Committed by Gerrit - the friendly Code Review server
Browse files

power: smb1360-chg-fg: Add support for the detection of otg



Register the interrupt for otg detection and enable it
in the handler.

Change-Id: Ib74d249dae86a007e6d9d229e46d660d20db818b
Signed-off-by: default avatarKavya Nunna <knunna@codeaurora.org>
parent 2140234e
Loading
Loading
Loading
Loading
+16 −6
Original line number Diff line number Diff line
@@ -13,12 +13,15 @@ Required Properties:

Optional Properties:

- interrupts			This indicates the IRQ number of the GPIO
				connected to the STAT pin.
- interrupts			This indicates the IRQ numbers of the GPIOs
				connected to the STAT and usb-id pins.
- interrupt-names		The irq names should be smb1360_stat_irq and
				smb1360_usb_id_irq.The stat irq is mandatory
				and usb_id irq is optional.
- pinctrl-names:		The state name of the pin configuration. Only
				support: "default".
- pinctrl-0:			The phandle of the pin configuration node in
				pinctrl for smb_int_pin.
- pinctrl-0:			The phandles of the pin configuration node in
				pinctrl for smb_int_pin and usb-id pin.
				For details of pinctrl properties, please refer to:
				"Documentation/devicetree/bindings/pinctrl/pinctrl-bindings.txt"
- qcom,float-voltage-mv	 	Float Voltage in mV - the maximum voltage up to which
@@ -177,6 +180,8 @@ Optional Properties:
				Please go through the documentation for PMIC gpio
				configuration details:
				Documentation/devicetree/bindings/gpio/qpnp-pin.txt
- qcom,usb-id-gpio		GPIO for usb-id detection.This property is mandatory
				if usb-id irq is specified.
- qcom,parallel-charging-enabled: A bool property which enables SMB1360 to
				operate in the parallel mode. SMB1360 acts
				as the primary charger.
@@ -192,9 +197,13 @@ Example:
			compatible = "qcom,smb1360-chg-fg";
			reg = <0x1b>;
			interrupt-parent = <&spmi_bus>;
			interrupts = <0x00 0xcd 0>;
			interrupts = <0x00 0xcd 0>,
					<0 0xc3 0 3>;
			interrupt-names = "smb1360_stat_irq",
					"smb1360_usb_id_irq";
			pinctrl-names = "default";
			pinctrl-0 = <&smb_int_default>;
			pinctrl-0 = <&smb_int_default>,
					<&usb_id_default>;

			/* battery-profile selection properties */
			qcom,batt-profile-select;
@@ -242,5 +251,6 @@ Example:

			qcom,otg-fet-present;
			qcom,otg-fet-enable-gpio = <&pm8916_gpios 3 0>;
			qcom,usb-id-gpio = <&pm8916_gpios 4 0>;
		};
	};
+81 −3
Original line number Diff line number Diff line
/* Copyright (c) 2013-2015, 2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2013-2015, 2018-2019, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -31,6 +31,7 @@
#include <linux/qpnp/qpnp-adc.h>
#include <linux/completion.h>
#include <linux/pm_wakeup.h>
#include <linux/of_irq.h>

#define _SMB1360_MASK(BITS, POS) \
	((unsigned char)(((1 << (BITS)) - 1) << (POS)))
@@ -405,6 +406,7 @@ struct smb1360_chip {
	bool				otg_fet_present;
	bool				fet_gain_enabled;
	int				otg_fet_enable_gpio;
	int				usb_id_gpio;

	/* status tracking */
	int				voltage_now;
@@ -466,6 +468,7 @@ struct smb1360_chip {
	int				cold_hysteresis;
	int				hot_hysteresis;
	struct extcon_dev		*extcon;
	int				usb_id_irq;
};

static int chg_time[] = {
@@ -2885,6 +2888,28 @@ static irqreturn_t smb1360_stat_handler(int irq, void *dev_id)
	return IRQ_HANDLED;
}

static irqreturn_t smb1360_usb_id_irq_handler(int irq, void *dev_id)
{
	struct smb1360_chip *chip = dev_id;
	int rc = 0;
	bool id_state;

	id_state = gpio_get_value(chip->usb_id_gpio);

	rc = smb1360_masked_write(chip, CMD_CHG_REG, CMD_OTG_EN_BIT,
					!id_state ? CMD_OTG_EN_BIT : 0);
	if (rc) {
		pr_err("Couldn't enable  OTG mode rc=%d\n", rc);
		return IRQ_HANDLED;
	}
	extcon_set_state_sync(chip->extcon, EXTCON_USB_HOST,
					!id_state ? true : false);

	pr_debug("usb_id_irq triggered, id_state = %d\n", id_state);

	return IRQ_HANDLED;
}

static int show_irq_count(struct seq_file *m, void *data)
{
	int i, j, total = 0;
@@ -3421,6 +3446,10 @@ static int smb1360_regulator_init(struct smb1360_chip *chip)
	int rc = 0;
	struct regulator_config cfg = {};

	/* OTG is enabled by SMB1360 if usb-id config is defined */
	if (chip->usb_id_gpio > 0 && chip->usb_id_irq > 0)
		return 0;

	chip->otg_vreg.rdesc.owner = THIS_MODULE;
	chip->otg_vreg.rdesc.type = REGULATOR_VOLTAGE;
	chip->otg_vreg.rdesc.ops = &smb1360_otg_reg_ops;
@@ -3557,6 +3586,7 @@ static int determine_initial_status(struct smb1360_chip *chip)
{
	int rc;
	u8 reg = 0;
	bool id_state;

	/*
	 * It is okay to read the IRQ status as the irq's are
@@ -3621,6 +3651,25 @@ static int determine_initial_status(struct smb1360_chip *chip)
	else
		extcon_set_cable_state_(chip->extcon, EXTCON_USB, true);

	pr_debug("usb %s at boot\n", chip->usb_present ? "present" : "absent");

	/*check otg presence and notify*/
	if (chip->usb_id_gpio != -EINVAL) {
		id_state = gpio_get_value(chip->usb_id_gpio);
		/* usb-id is low, enable OTG */
		if (!id_state) {
			rc = smb1360_masked_write(chip, CMD_CHG_REG,
						CMD_OTG_EN_BIT, CMD_OTG_EN_BIT);
			if (rc) {
				pr_err("Couldn't enable  OTG mode rc=%d\n", rc);
				return rc;
			}
			extcon_set_state_sync(chip->extcon, EXTCON_USB_HOST,
									true);
			pr_debug("OTG enabled at boot\n");
		}
	}

	power_supply_changed(chip->usb_psy);
	return 0;
}
@@ -4752,6 +4801,11 @@ static int smb_parse_dt(struct smb1360_chip *chip)
			return rc;
		}
	}
	chip->usb_id_gpio = -EINVAL;
	if (of_find_property(node, "qcom,usb-id-gpio", NULL)) {
		chip->usb_id_gpio = of_get_named_gpio(node,
					"qcom,usb-id-gpio", 0);
	}

	chip->pulsed_irq = of_property_read_bool(node, "qcom,stat-pulsed-irq");

@@ -5073,6 +5127,28 @@ static int smb1360_probe(struct i2c_client *client,
		enable_irq_wake(client->irq);
	}

	chip->usb_id_irq = of_irq_get_byname(chip->dev->of_node,
						"smb1360_usb_id_irq");
	if (chip->usb_id_irq > 0) {
		if (chip->usb_id_gpio == -EINVAL) {
			pr_err("usb-id gpio not defined\n");
		} else {
			rc = devm_request_threaded_irq(&client->dev,
						chip->usb_id_irq, NULL,
						smb1360_usb_id_irq_handler,
						IRQF_ONESHOT
						| IRQF_TRIGGER_FALLING
						| IRQF_TRIGGER_RISING,
						"smb1360_usb_id_irq", chip);
			if (rc < 0) {
				dev_err(&client->dev,
					"usb-id request_irq for irq=%d  failed rc = %d\n",
					chip->usb_id_irq, rc);
				goto unregister_batt_psy;
			}
			enable_irq_wake(chip->usb_id_irq);
		}
	}
	chip->debug_root = debugfs_create_dir("smb1360", NULL);
	if (!chip->debug_root)
		dev_err(chip->dev, "Couldn't create debug dir\n");
@@ -5201,6 +5277,7 @@ static int smb1360_probe(struct i2c_client *client,
unregister_batt_psy:
	power_supply_unregister(chip->batt_psy);
fail_hw_init:
	if (chip->otg_vreg.rdev)
		regulator_unregister(chip->otg_vreg.rdev);
destroy_mutex:
	power_supply_unregister(chip->usb_psy);
@@ -5218,8 +5295,9 @@ static int smb1360_probe(struct i2c_client *client,
static int smb1360_remove(struct i2c_client *client)
{
	struct smb1360_chip *chip = i2c_get_clientdata(client);

	if (chip->otg_vreg.rdev)
		regulator_unregister(chip->otg_vreg.rdev);

	power_supply_unregister(chip->usb_psy);
	power_supply_unregister(chip->batt_psy);
	wakeup_source_trash(&chip->smb1360_ws.source);