mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-13 00:00:00 -04:00
power: qti_typec_class: Add typec class support for micro USB
Add typec class support for micro USB to show the data/power role options in UI. Change-Id: I83c0afa6ef9098a85d6c66e076e6a506d945c7fd Signed-off-by: Kiran Gunda <kgunda@codeaurora.org>
This commit is contained in:
parent
6e9701d99a
commit
b5b08a09f7
4 changed files with 120 additions and 1 deletions
|
|
@ -92,5 +92,6 @@ obj-$(CONFIG_FUEL_GAUGE_SC27XX) += sc27xx_fuel_gauge.o
|
|||
obj-$(CONFIG_CHARGER_UCS1002) += ucs1002_power.o
|
||||
obj-$(CONFIG_CHARGER_BD70528) += bd70528-charger.o
|
||||
obj-$(CONFIG_CHARGER_WILCO) += wilco-charger.o
|
||||
obj-$(CONFIG_QTI_BATTERY_CHARGER) += qti_battery_charger.o
|
||||
obj-$(CONFIG_QTI_BATTERY_CHARGER) += qti_battery_charger_main.o
|
||||
qti_battery_charger_main-y += qti_battery_charger.o qti_typec_class.o
|
||||
obj-$(CONFIG_QCOM_POWER_SUPPLY) += qcom/
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#include <linux/power_supply.h>
|
||||
#include <linux/soc/qcom/pmic_glink.h>
|
||||
#include <linux/soc/qcom/battery_charger.h>
|
||||
#include "qti_typec_class.h"
|
||||
|
||||
#define MSG_OWNER_BC 32778
|
||||
#define MSG_TYPE_REQ_RESP 1
|
||||
|
|
@ -223,6 +224,7 @@ struct battery_chg_dev {
|
|||
struct device *dev;
|
||||
struct class battery_class;
|
||||
struct pmic_glink_client *client;
|
||||
struct typec_role_class *typec_class;
|
||||
struct mutex rw_lock;
|
||||
struct completion ack;
|
||||
struct completion fw_buf_ack;
|
||||
|
|
@ -666,12 +668,21 @@ static void battery_chg_update_uusb_type(struct battery_chg_dev *bcdev,
|
|||
/* Device mode connect notification */
|
||||
extcon_set_state_sync(bcdev->extcon, EXTCON_USB, 1);
|
||||
bcdev->usb_prev_mode = EXTCON_USB;
|
||||
rc = qti_typec_partner_register(bcdev->typec_class,
|
||||
TYPEC_DEVICE);
|
||||
if (rc < 0)
|
||||
pr_err("Failed to register typec partner rc=%d\n",
|
||||
rc);
|
||||
}
|
||||
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;
|
||||
rc = qti_typec_partner_register(bcdev->typec_class, TYPEC_HOST);
|
||||
if (rc < 0)
|
||||
pr_err("Failed to register typec partner rc=%d\n",
|
||||
rc);
|
||||
break;
|
||||
default:
|
||||
if (bcdev->usb_prev_mode == EXTCON_USB ||
|
||||
|
|
@ -680,6 +691,7 @@ static void battery_chg_update_uusb_type(struct battery_chg_dev *bcdev,
|
|||
extcon_set_state_sync(bcdev->extcon,
|
||||
bcdev->usb_prev_mode, 0);
|
||||
bcdev->usb_prev_mode = EXTCON_NONE;
|
||||
qti_typec_partner_unregister(bcdev->typec_class);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -2059,6 +2071,15 @@ static int battery_chg_probe(struct platform_device *pdev)
|
|||
if (rc < 0)
|
||||
dev_warn(dev, "Failed to register extcon rc=%d\n", rc);
|
||||
|
||||
if (bcdev->connector_type == USB_CONNECTOR_TYPE_MICRO_USB) {
|
||||
bcdev->typec_class = qti_typec_class_init(bcdev->dev);
|
||||
if (IS_ERR_OR_NULL(bcdev->typec_class)) {
|
||||
dev_err(dev, "Failed to init typec class err=%d\n",
|
||||
PTR_ERR(bcdev->typec_class));
|
||||
return PTR_ERR(bcdev->typec_class);
|
||||
}
|
||||
}
|
||||
|
||||
schedule_work(&bcdev->usb_type_work);
|
||||
|
||||
return 0;
|
||||
|
|
@ -2079,6 +2100,7 @@ static int battery_chg_remove(struct platform_device *pdev)
|
|||
debugfs_remove_recursive(bcdev->debugfs_dir);
|
||||
class_unregister(&bcdev->battery_class);
|
||||
unregister_reboot_notifier(&bcdev->reboot_notifier);
|
||||
qti_typec_class_deinit(bcdev->typec_class);
|
||||
rc = pmic_glink_unregister_client(bcdev->client);
|
||||
if (rc < 0) {
|
||||
pr_err("Error unregistering from pmic_glink, rc=%d\n", rc);
|
||||
|
|
|
|||
75
drivers/power/supply/qti_typec_class.c
Normal file
75
drivers/power/supply/qti_typec_class.c
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include "qti_typec_class.h"
|
||||
|
||||
int qti_typec_partner_register(struct typec_role_class *chip, int mode)
|
||||
{
|
||||
|
||||
if (!chip || !chip->typec_port)
|
||||
return -ENODEV;
|
||||
|
||||
if (!chip->typec_partner) {
|
||||
chip->typec_partner = typec_register_partner(chip->typec_port,
|
||||
&chip->typec_partner_desc);
|
||||
if (IS_ERR_OR_NULL(chip->typec_partner))
|
||||
return PTR_ERR(chip->typec_partner);
|
||||
}
|
||||
|
||||
if (mode == TYPEC_DEVICE) {
|
||||
typec_set_data_role(chip->typec_port, TYPEC_DEVICE);
|
||||
typec_set_pwr_role(chip->typec_port, TYPEC_SINK);
|
||||
} else {
|
||||
typec_set_data_role(chip->typec_port, TYPEC_HOST);
|
||||
typec_set_pwr_role(chip->typec_port, TYPEC_SOURCE);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void qti_typec_partner_unregister(struct typec_role_class *chip)
|
||||
{
|
||||
if (!chip || !chip->typec_port)
|
||||
return;
|
||||
|
||||
if (chip->typec_partner) {
|
||||
typec_unregister_partner(chip->typec_partner);
|
||||
chip->typec_partner = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
struct typec_role_class *qti_typec_class_init(struct device *dev)
|
||||
{
|
||||
struct typec_role_class *chip;
|
||||
|
||||
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
|
||||
if (!chip)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
chip->typec_caps.type = TYPEC_PORT_DRP;
|
||||
chip->typec_caps.data = TYPEC_PORT_DRD;
|
||||
chip->typec_caps.revision = 0x0130;
|
||||
chip->typec_partner_desc.usb_pd = false;
|
||||
chip->typec_partner_desc.accessory = TYPEC_ACCESSORY_NONE;
|
||||
|
||||
chip->typec_port = typec_register_port(dev, &chip->typec_caps);
|
||||
if (IS_ERR_OR_NULL(chip->typec_port))
|
||||
return ERR_PTR(-ENODEV);
|
||||
|
||||
return chip;
|
||||
}
|
||||
|
||||
void qti_typec_class_deinit(struct typec_role_class *chip)
|
||||
{
|
||||
if (!chip || !chip->typec_port)
|
||||
return;
|
||||
|
||||
qti_typec_partner_unregister(chip);
|
||||
typec_unregister_port(chip->typec_port);
|
||||
chip->typec_port = NULL;
|
||||
}
|
||||
21
drivers/power/supply/qti_typec_class.h
Normal file
21
drivers/power/supply/qti_typec_class.h
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2021 The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
#ifndef __QTI_TYPEC_CLASS_H
|
||||
#define __QTI_TYPEC_CLASS_H
|
||||
|
||||
#include <linux/usb/typec.h>
|
||||
|
||||
struct typec_role_class {
|
||||
struct typec_port *typec_port;
|
||||
struct typec_capability typec_caps;
|
||||
struct typec_partner *typec_partner;
|
||||
struct typec_partner_desc typec_partner_desc;
|
||||
};
|
||||
|
||||
int qti_typec_partner_register(struct typec_role_class *chip, int mode);
|
||||
void qti_typec_partner_unregister(struct typec_role_class *chip);
|
||||
struct typec_role_class *qti_typec_class_init(struct device *dev);
|
||||
void qti_typec_class_deinit(struct typec_role_class *chip);
|
||||
#endif /* __QTI_TYPEC_CLASS_H */
|
||||
Loading…
Reference in a new issue