diff --git a/arch/arm64/configs/vendor/holi_GKI.config b/arch/arm64/configs/vendor/holi_GKI.config index 91f0b81f510d..c696947c802d 100644 --- a/arch/arm64/configs/vendor/holi_GKI.config +++ b/arch/arm64/configs/vendor/holi_GKI.config @@ -197,3 +197,5 @@ CONFIG_QPNP_QG=m CONFIG_QPNP_SMB5=m # CONFIG_SMB1398_CHARGER is not set # CONFIG_SMB1355_SLAVE_CHARGER is not set +CONFIG_USB_PD_POLICY=m +CONFIG_QPNP_USB_PDPHY=m diff --git a/drivers/usb/pd/Kconfig b/drivers/usb/pd/Kconfig index 19b5228aec63..09f8a7c7a4ea 100644 --- a/drivers/usb/pd/Kconfig +++ b/drivers/usb/pd/Kconfig @@ -11,6 +11,7 @@ config USB_PD_POLICY tristate "USB Power Delivery Protocol and Policy Engine" depends on EXTCON depends on TYPEC + depends on IIO select USB_PD help Say Y here to enable USB PD protocol and policy engine. diff --git a/drivers/usb/pd/policy_engine.c b/drivers/usb/pd/policy_engine.c index 48a38c6555b2..9bdc9070fef0 100644 --- a/drivers/usb/pd/policy_engine.c +++ b/drivers/usb/pd/policy_engine.c @@ -504,6 +504,8 @@ struct usbpd { u8 get_battery_status_db; bool send_get_battery_status; u32 battery_sts_dobj; + + struct pd_phy_ops *pdphy_ops; }; static LIST_HEAD(_usbpd); /* useful for debugging */ @@ -772,7 +774,8 @@ static int pd_send_msg(struct usbpd *pd, u8 msg_type, const u32 *data, } spin_unlock_irqrestore(&pd->rx_lock, flags); - ret = pd_phy_write(hdr, (u8 *)data, num_data * sizeof(u32), sop); + ret = pd->pdphy_ops->write(hdr, (u8 *)data, + num_data * sizeof(u32), sop); if (ret) { if (pd->pd_connected) usbpd_err(&pd->dev, "Error sending %s: %d\n", @@ -818,7 +821,7 @@ static int pd_send_ext_msg(struct usbpd *pd, u8 msg_type, hdr = PD_MSG_HDR(msg_type, pd->current_dr, pd->current_pr, pd->tx_msgid[sop], num_objs, pd->spec_rev) | PD_MSG_HDR_EXTENDED; - ret = pd_phy_write(hdr, chunked_payload, + ret = pd->pdphy_ops->write(hdr, chunked_payload, num_objs * sizeof(u32), sop); if (ret) { usbpd_err(&pd->dev, "Error sending %s: %d\n", @@ -945,7 +948,7 @@ static void pd_send_hard_reset(struct usbpd *pd) usbpd_dbg(&pd->dev, "send hard reset"); pd->hard_reset_count++; - pd_phy_signal(HARD_RESET_SIG); + pd->pdphy_ops->signal(HARD_RESET_SIG); pd->in_pr_swap = false; pd->pd_connected = false; usbpd_set_psy_iio_property(pd, POWER_SUPPLY_PROP_PR_SWAP, &val); @@ -1006,7 +1009,7 @@ static void pd_request_chunk_work(struct work_struct *w) *(u16 *)payload = PD_MSG_EXT_HDR(1, req->chunk_num, 1, 0); - ret = pd_phy_write(hdr, payload, sizeof(payload), req->sop); + ret = pd->pdphy_ops->write(hdr, payload, sizeof(payload), req->sop); if (!ret) { pd->tx_msgid[req->sop] = (pd->tx_msgid[req->sop] + 1) & PD_MAX_MSG_ID; @@ -1915,7 +1918,7 @@ static void dr_swap(struct usbpd *pd) if (pd->current_dr == DR_DFP) { pd->current_dr = DR_UFP; - pd_phy_update_roles(pd->current_dr, pd->current_pr); + pd->pdphy_ops->update_roles(pd->current_dr, pd->current_pr); stop_usb_host(pd); if (pd->peer_usb_comm) @@ -1923,7 +1926,7 @@ static void dr_swap(struct usbpd *pd) typec_set_data_role(pd->typec_port, TYPEC_DEVICE); } else if (pd->current_dr == DR_UFP) { pd->current_dr = DR_DFP; - pd_phy_update_roles(pd->current_dr, pd->current_pr); + pd->pdphy_ops->update_roles(pd->current_dr, pd->current_pr); stop_usb_peripheral(pd); if (pd->peer_usb_comm) @@ -1942,7 +1945,7 @@ static void vconn_swap(struct usbpd *pd) int ret; if (pd->vconn_enabled) { - pd_phy_update_frame_filter(FRAME_FILTER_EN_SOP | + pd->pdphy_ops->update_frame_filter(FRAME_FILTER_EN_SOP | FRAME_FILTER_EN_HARD_RESET); pd->current_state = PE_VCS_WAIT_FOR_VCONN; @@ -1963,7 +1966,7 @@ static void vconn_swap(struct usbpd *pd) pd->vconn_enabled = true; - pd_phy_update_frame_filter(FRAME_FILTER_EN_SOP | + pd->pdphy_ops->update_frame_filter(FRAME_FILTER_EN_SOP | FRAME_FILTER_EN_SOPI | FRAME_FILTER_EN_HARD_RESET); @@ -2126,7 +2129,7 @@ static int usbpd_startup_common(struct usbpd *pd, pd->spec_rev = USBPD_REV_30; if (pd->pd_phy_opened) { - pd_phy_close(); + pd->pdphy_ops->close(); pd->pd_phy_opened = false; } @@ -2136,7 +2139,10 @@ static int usbpd_startup_common(struct usbpd *pd, if (pd->vconn_enabled) phy_params->frame_filter_val |= FRAME_FILTER_EN_SOPI; - ret = pd_phy_open(phy_params); + if (!pd->pdphy_ops->open) + return -ENODEV; + + ret = pd->pdphy_ops->open(phy_params); if (ret) { WARN_ON_ONCE(1); usbpd_err(&pd->dev, "error opening PD PHY %d\n", @@ -2576,7 +2582,7 @@ static void handle_state_src_transition_to_default(struct usbpd *pd, if (pd->current_dr != DR_DFP) { extcon_set_state_sync(pd->extcon, EXTCON_USB, 0); pd->current_dr = DR_DFP; - pd_phy_update_roles(pd->current_dr, pd->current_pr); + pd->pdphy_ops->update_roles(pd->current_dr, pd->current_pr); } /* PE_UNKNOWN will turn on VBUS and go back to PE_SRC_STARTUP */ @@ -3144,7 +3150,7 @@ static void enter_state_snk_transition_to_default(struct usbpd *pd) stop_usb_host(pd); start_usb_peripheral(pd); pd->current_dr = DR_UFP; - pd_phy_update_roles(pd->current_dr, pd->current_pr); + pd->pdphy_ops->update_roles(pd->current_dr, pd->current_pr); } if (pd->vconn_enabled) { regulator_disable(pd->vconn); @@ -3203,7 +3209,7 @@ static void enter_state_prs_snk_src_transition_to_off(struct usbpd *pd) * need to update PR bit in message header so that * proper GoodCRC is sent when receiving next PS_RDY */ - pd_phy_update_roles(pd->current_dr, PR_SRC); + pd->pdphy_ops->update_roles(pd->current_dr, PR_SRC); /* wait for PS_RDY */ kick_sm(pd, PS_SOURCE_OFF); @@ -3280,7 +3286,7 @@ static void handle_state_prs_src_snk_transition_to_off(struct usbpd *pd, /* PE_PRS_SRC_SNK_Assert_Rd */ pd->current_pr = PR_SINK; set_power_role(pd, pd->current_pr); - pd_phy_update_roles(pd->current_dr, pd->current_pr); + pd->pdphy_ops->update_roles(pd->current_dr, pd->current_pr); /* allow time for Vbus discharge, must be < tSrcSwapStdby */ msleep(500); @@ -3442,7 +3448,7 @@ static void handle_disconnect(struct usbpd *pd) usbpd_info(&pd->dev, "USB Type-C disconnect\n"); if (pd->pd_phy_opened) { - pd_phy_close(); + pd->pdphy_ops->close(); pd->pd_phy_opened = false; } @@ -4634,7 +4640,8 @@ const struct typec_operations typec_ops = { * * Return: struct usbpd pointer, or an ERR_PTR value */ -struct usbpd *usbpd_create(struct device *parent) +struct usbpd *usbpd_create(struct device *parent, + struct pd_phy_ops *pdphy_ops) { int ret; struct usbpd *pd; @@ -4797,6 +4804,7 @@ struct usbpd *usbpd_create(struct device *parent) } } + pd->pdphy_ops = pdphy_ops; pd->current_pr = PR_NONE; pd->current_dr = DR_NONE; list_add_tail(&pd->instance, &_usbpd); diff --git a/drivers/usb/pd/qpnp-pdphy.c b/drivers/usb/pd/qpnp-pdphy.c index fd798920676c..e59d865e8ed0 100644 --- a/drivers/usb/pd/qpnp-pdphy.c +++ b/drivers/usb/pd/qpnp-pdphy.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2018, 2020 The Linux Foundation. All rights reserved. */ #include @@ -601,6 +601,15 @@ void pd_phy_close(void) } EXPORT_SYMBOL(pd_phy_close); +struct pd_phy_ops pdphy_ops = { + .open = pd_phy_open, + .write = pd_phy_write, + .close = pd_phy_close, + .signal = pd_phy_signal, + .update_roles = pd_phy_update_roles, + .update_frame_filter = pd_phy_update_frame_filter, +}; + static irqreturn_t pdphy_msg_tx_irq(int irq, void *data) { struct usb_pdphy *pdphy = data; @@ -867,7 +876,7 @@ static int pdphy_probe(struct platform_device *pdev) /* usbpd_create() could call back to us, so have __pdphy ready */ __pdphy = pdphy; - pdphy->usbpd = usbpd_create(&pdev->dev); + pdphy->usbpd = usbpd_create(&pdev->dev, &pdphy_ops); if (IS_ERR(pdphy->usbpd)) { dev_err(&pdev->dev, "usbpd_create failed: %ld\n", PTR_ERR(pdphy->usbpd)); diff --git a/drivers/usb/pd/usbpd.h b/drivers/usb/pd/usbpd.h index 84c66955cfeb..2bdfa58217a8 100644 --- a/drivers/usb/pd/usbpd.h +++ b/drivers/usb/pd/usbpd.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2018, 2020 The Linux Foundation. All rights reserved. */ #ifndef _USBPD_H @@ -10,17 +10,6 @@ struct usbpd; -#if IS_ENABLED(CONFIG_USB_PD_POLICY) -struct usbpd *usbpd_create(struct device *parent); -void usbpd_destroy(struct usbpd *pd); -#else -static inline struct usbpd *usbpd_create(struct device *parent) -{ - return ERR_PTR(-ENODEV); -} -static inline void usbpd_destroy(struct usbpd *pd) { } -#endif - enum data_role { DR_NONE = -1, DR_UFP = 0, @@ -64,43 +53,27 @@ struct pd_phy_params { u8 frame_filter_val; }; -#if IS_ENABLED(CONFIG_QPNP_USB_PDPHY) -int pd_phy_open(struct pd_phy_params *params); -int pd_phy_signal(enum pd_sig_type sig); -int pd_phy_write(u16 hdr, const u8 *data, size_t data_len, - enum pd_sop_type sop); -int pd_phy_update_roles(enum data_role dr, enum power_role pr); -int pd_phy_update_frame_filter(u8 frame_filter_val); -void pd_phy_close(void); +struct pd_phy_ops { + int (*open)(struct pd_phy_params *params); + int (*signal)(enum pd_sig_type sig); + int (*write)(u16 hdr, const u8 *data, size_t data_len, + enum pd_sop_type sop); + int (*update_roles)(enum data_role dr, enum power_role pr); + int (*update_frame_filter)(u8 frame_filter_val); + void (*close)(void); +}; + +#if IS_ENABLED(CONFIG_USB_PD_POLICY) +struct usbpd *usbpd_create(struct device *parent, + struct pd_phy_ops *pdphy_ops); +void usbpd_destroy(struct usbpd *pd); #else -static inline int pd_phy_open(struct pd_phy_params *params) -{ - return -ENODEV; -} - -static inline int pd_phy_signal(enum pd_sig_type type) -{ - return -ENODEV; -} - -static inline int pd_phy_write(u16 hdr, const u8 *data, size_t data_len, - enum pd_sop_type sop) -{ - return -ENODEV; -} - -static inline int pd_phy_update_roles(enum data_role dr, enum power_role pr) -{ - return -ENODEV; -} - -static inline int pd_phy_update_frame_filter(u8 frame_filter_val) -{ - return -ENODEV; -} - -static inline void pd_phy_close(void) +static inline struct usbpd *usbpd_create(struct device *parent, + struct pd_phy_ops *pdphy_ops) { + return ERR_PTR(-ENODEV); } +static inline void usbpd_destroy(struct usbpd *pd) { } #endif + #endif /* _USBPD_H */