mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-25 06:03:36 -04:00
Merge "power: supply: qti_battery_charger: Add extcon support"
This commit is contained in:
commit
974aae1fea
2 changed files with 111 additions and 2 deletions
|
|
@ -407,7 +407,7 @@ config BATTERY_TWL4030_MADC
|
|||
|
||||
config QTI_BATTERY_CHARGER
|
||||
tristate "QTI Glink battery charger"
|
||||
depends on QTI_PMIC_GLINK
|
||||
depends on QTI_PMIC_GLINK && EXTCON
|
||||
help
|
||||
Say Y here to enable Qualcomm Technologies, Inc. battery charger
|
||||
driver which interfaces with the charger firmware running on the
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2019-2020, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#define pr_fmt(fmt) "BATTERY_CHG: %s: " fmt, __func__
|
||||
|
|
@ -8,6 +8,7 @@
|
|||
#include <linux/debugfs.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/extcon-provider.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
|
|
@ -51,6 +52,11 @@
|
|||
#define WLS_FW_BUF_SIZE 128
|
||||
#define DEFAULT_RESTRICT_FCC_UA 1000000
|
||||
|
||||
enum usb_connector_type {
|
||||
USB_CONNECTOR_TYPE_TYPEC,
|
||||
USB_CONNECTOR_TYPE_MICRO_USB,
|
||||
};
|
||||
|
||||
enum psy_type {
|
||||
PSY_TYPE_BATTERY,
|
||||
PSY_TYPE_USB,
|
||||
|
|
@ -106,6 +112,8 @@ enum usb_property_id {
|
|||
USB_TEMP,
|
||||
USB_REAL_TYPE,
|
||||
USB_TYPEC_COMPLIANT,
|
||||
USB_SCOPE,
|
||||
USB_CONNECTOR_TYPE,
|
||||
USB_PROP_MAX,
|
||||
};
|
||||
|
||||
|
|
@ -221,6 +229,8 @@ struct battery_chg_dev {
|
|||
struct completion fw_update_ack;
|
||||
struct psy_state psy_list[PSY_TYPE_MAX];
|
||||
struct dentry *debugfs_dir;
|
||||
/* extcon for VBUS/ID notification for USB for micro USB */
|
||||
struct extcon_dev *extcon;
|
||||
u32 *thermal_levels;
|
||||
const char *wls_fw_name;
|
||||
int curr_thermal_level;
|
||||
|
|
@ -240,6 +250,8 @@ struct battery_chg_dev {
|
|||
u32 restrict_fcc_ua;
|
||||
u32 last_fcc_ua;
|
||||
u32 usb_icl_ua;
|
||||
u32 connector_type;
|
||||
u32 usb_prev_mode;
|
||||
bool restrict_chg_en;
|
||||
/* To track the driver initialization status */
|
||||
bool initialized;
|
||||
|
|
@ -279,6 +291,7 @@ static const int usb_prop_map[USB_PROP_MAX] = {
|
|||
[USB_INPUT_CURR_LIMIT] = POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
|
||||
[USB_ADAP_TYPE] = POWER_SUPPLY_PROP_USB_TYPE,
|
||||
[USB_TEMP] = POWER_SUPPLY_PROP_TEMP,
|
||||
[USB_SCOPE] = POWER_SUPPLY_PROP_SCOPE,
|
||||
};
|
||||
|
||||
static const int wls_prop_map[WLS_PROP_MAX] = {
|
||||
|
|
@ -289,6 +302,12 @@ static const int wls_prop_map[WLS_PROP_MAX] = {
|
|||
[WLS_CURR_MAX] = POWER_SUPPLY_PROP_CURRENT_MAX,
|
||||
};
|
||||
|
||||
static const unsigned int bcdev_usb_extcon_cable[] = {
|
||||
EXTCON_USB,
|
||||
EXTCON_USB_HOST,
|
||||
EXTCON_NONE,
|
||||
};
|
||||
|
||||
/* Standard usb_type definitions similar to power_supply_sysfs.c */
|
||||
static const char * const power_supply_usb_type_text[] = {
|
||||
"Unknown", "SDP", "DCP", "CDP", "ACA", "C",
|
||||
|
|
@ -624,6 +643,48 @@ static void handle_message(struct battery_chg_dev *bcdev, void *data,
|
|||
complete(&bcdev->ack);
|
||||
}
|
||||
|
||||
static void battery_chg_update_uusb_type(struct battery_chg_dev *bcdev,
|
||||
u32 adap_type)
|
||||
{
|
||||
struct psy_state *pst = &bcdev->psy_list[PSY_TYPE_USB];
|
||||
int rc;
|
||||
|
||||
/* Handle the extcon notification for uUSB case only */
|
||||
if (bcdev->connector_type != USB_CONNECTOR_TYPE_MICRO_USB)
|
||||
return;
|
||||
|
||||
rc = read_property_id(bcdev, pst, USB_SCOPE);
|
||||
if (rc < 0) {
|
||||
pr_err("Failed to read USB_SCOPE rc=%d\n", rc);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (pst->prop[USB_SCOPE]) {
|
||||
case POWER_SUPPLY_SCOPE_DEVICE:
|
||||
if (adap_type == POWER_SUPPLY_USB_TYPE_SDP ||
|
||||
adap_type == POWER_SUPPLY_USB_TYPE_CDP) {
|
||||
/* Device mode connect notification */
|
||||
extcon_set_state_sync(bcdev->extcon, EXTCON_USB, 1);
|
||||
bcdev->usb_prev_mode = EXTCON_USB;
|
||||
}
|
||||
break;
|
||||
case POWER_SUPPLY_SCOPE_SYSTEM:
|
||||
/* Host mode connect notification */
|
||||
extcon_set_state_sync(bcdev->extcon, EXTCON_USB_HOST, 1);
|
||||
bcdev->usb_prev_mode = EXTCON_USB_HOST;
|
||||
break;
|
||||
default:
|
||||
if (bcdev->usb_prev_mode == EXTCON_USB ||
|
||||
bcdev->usb_prev_mode == EXTCON_USB_HOST) {
|
||||
/* Disconnect notification */
|
||||
extcon_set_state_sync(bcdev->extcon,
|
||||
bcdev->usb_prev_mode, 0);
|
||||
bcdev->usb_prev_mode = EXTCON_NONE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static struct power_supply_desc usb_psy_desc;
|
||||
|
||||
static void battery_chg_update_usb_type_work(struct work_struct *work)
|
||||
|
|
@ -675,6 +736,8 @@ static void battery_chg_update_usb_type_work(struct work_struct *work)
|
|||
usb_psy_desc.type = POWER_SUPPLY_TYPE_USB;
|
||||
break;
|
||||
}
|
||||
|
||||
battery_chg_update_uusb_type(bcdev, pst->prop[USB_ADAP_TYPE]);
|
||||
}
|
||||
|
||||
static void handle_notification(struct battery_chg_dev *bcdev, void *data,
|
||||
|
|
@ -927,6 +990,7 @@ static enum power_supply_property usb_props[] = {
|
|||
POWER_SUPPLY_PROP_INPUT_CURRENT_LIMIT,
|
||||
POWER_SUPPLY_PROP_USB_TYPE,
|
||||
POWER_SUPPLY_PROP_TEMP,
|
||||
POWER_SUPPLY_PROP_SCOPE,
|
||||
};
|
||||
|
||||
static enum power_supply_usb_type usb_psy_supported_types[] = {
|
||||
|
|
@ -1860,6 +1924,47 @@ static int battery_chg_ship_mode(struct notifier_block *nb, unsigned long code,
|
|||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static int register_extcon_conn_type(struct battery_chg_dev *bcdev)
|
||||
{
|
||||
struct psy_state *pst = &bcdev->psy_list[PSY_TYPE_USB];
|
||||
int rc;
|
||||
|
||||
rc = read_property_id(bcdev, pst, USB_CONNECTOR_TYPE);
|
||||
if (rc < 0) {
|
||||
pr_err("Failed to read prop USB_CONNECTOR_TYPE, rc=%d\n",
|
||||
rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (pst->prop[USB_CONNECTOR_TYPE] != USB_CONNECTOR_TYPE_MICRO_USB)
|
||||
return 0;
|
||||
|
||||
bcdev->connector_type = USB_CONNECTOR_TYPE_MICRO_USB;
|
||||
bcdev->usb_prev_mode = EXTCON_NONE;
|
||||
|
||||
bcdev->extcon = devm_extcon_dev_allocate(bcdev->dev,
|
||||
bcdev_usb_extcon_cable);
|
||||
if (IS_ERR(bcdev->extcon)) {
|
||||
rc = PTR_ERR(bcdev->extcon);
|
||||
pr_err("Failed to allocate extcon device rc=%d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = devm_extcon_dev_register(bcdev->dev, bcdev->extcon);
|
||||
if (rc < 0) {
|
||||
pr_err("Failed to register extcon device rc=%d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
rc = extcon_set_property_capability(bcdev->extcon, EXTCON_USB,
|
||||
EXTCON_PROP_USB_SS);
|
||||
rc |= extcon_set_property_capability(bcdev->extcon,
|
||||
EXTCON_USB_HOST, EXTCON_PROP_USB_SS);
|
||||
if (rc < 0)
|
||||
pr_err("failed to configure extcon capabilities rc=%d\n", rc);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int battery_chg_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct battery_chg_dev *bcdev;
|
||||
|
|
@ -1950,6 +2055,10 @@ static int battery_chg_probe(struct platform_device *pdev)
|
|||
battery_chg_add_debugfs(bcdev);
|
||||
battery_chg_notify_enable(bcdev);
|
||||
device_init_wakeup(bcdev->dev, true);
|
||||
rc = register_extcon_conn_type(bcdev);
|
||||
if (rc < 0)
|
||||
dev_warn(dev, "Failed to register extcon rc=%d\n", rc);
|
||||
|
||||
schedule_work(&bcdev->usb_type_work);
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
Loading…
Reference in a new issue