18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-1.0+ */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Renesas USB driver 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 2011 Renesas Solutions Corp. 68c2ecf20Sopenharmony_ci * Copyright (C) 2019 Renesas Electronics Corporation 78c2ecf20Sopenharmony_ci * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> 88c2ecf20Sopenharmony_ci */ 98c2ecf20Sopenharmony_ci#ifndef RENESAS_USB_MOD_H 108c2ecf20Sopenharmony_ci#define RENESAS_USB_MOD_H 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#include <linux/spinlock.h> 138c2ecf20Sopenharmony_ci#include <linux/usb/renesas_usbhs.h> 148c2ecf20Sopenharmony_ci#include "common.h" 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_ci/* 178c2ecf20Sopenharmony_ci * struct 188c2ecf20Sopenharmony_ci */ 198c2ecf20Sopenharmony_cistruct usbhs_irq_state { 208c2ecf20Sopenharmony_ci u16 intsts0; 218c2ecf20Sopenharmony_ci u16 intsts1; 228c2ecf20Sopenharmony_ci u16 brdysts; 238c2ecf20Sopenharmony_ci u16 nrdysts; 248c2ecf20Sopenharmony_ci u16 bempsts; 258c2ecf20Sopenharmony_ci}; 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_cistruct usbhs_mod { 288c2ecf20Sopenharmony_ci char *name; 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci /* 318c2ecf20Sopenharmony_ci * entry point from common.c 328c2ecf20Sopenharmony_ci */ 338c2ecf20Sopenharmony_ci int (*start)(struct usbhs_priv *priv); 348c2ecf20Sopenharmony_ci int (*stop)(struct usbhs_priv *priv); 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci /* 378c2ecf20Sopenharmony_ci * INTSTS0 388c2ecf20Sopenharmony_ci */ 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci /* DVST (DVSQ) */ 418c2ecf20Sopenharmony_ci int (*irq_dev_state)(struct usbhs_priv *priv, 428c2ecf20Sopenharmony_ci struct usbhs_irq_state *irq_state); 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci /* CTRT (CTSQ) */ 458c2ecf20Sopenharmony_ci int (*irq_ctrl_stage)(struct usbhs_priv *priv, 468c2ecf20Sopenharmony_ci struct usbhs_irq_state *irq_state); 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci /* BEMP / BEMPSTS */ 498c2ecf20Sopenharmony_ci int (*irq_empty)(struct usbhs_priv *priv, 508c2ecf20Sopenharmony_ci struct usbhs_irq_state *irq_state); 518c2ecf20Sopenharmony_ci u16 irq_bempsts; 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci /* BRDY / BRDYSTS */ 548c2ecf20Sopenharmony_ci int (*irq_ready)(struct usbhs_priv *priv, 558c2ecf20Sopenharmony_ci struct usbhs_irq_state *irq_state); 568c2ecf20Sopenharmony_ci u16 irq_brdysts; 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci /* 598c2ecf20Sopenharmony_ci * INTSTS1 608c2ecf20Sopenharmony_ci */ 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci /* ATTCHE */ 638c2ecf20Sopenharmony_ci int (*irq_attch)(struct usbhs_priv *priv, 648c2ecf20Sopenharmony_ci struct usbhs_irq_state *irq_state); 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_ci /* DTCHE */ 678c2ecf20Sopenharmony_ci int (*irq_dtch)(struct usbhs_priv *priv, 688c2ecf20Sopenharmony_ci struct usbhs_irq_state *irq_state); 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci /* SIGN */ 718c2ecf20Sopenharmony_ci int (*irq_sign)(struct usbhs_priv *priv, 728c2ecf20Sopenharmony_ci struct usbhs_irq_state *irq_state); 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci /* SACK */ 758c2ecf20Sopenharmony_ci int (*irq_sack)(struct usbhs_priv *priv, 768c2ecf20Sopenharmony_ci struct usbhs_irq_state *irq_state); 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci struct usbhs_priv *priv; 798c2ecf20Sopenharmony_ci}; 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_cistruct usbhs_mod_info { 828c2ecf20Sopenharmony_ci struct usbhs_mod *mod[USBHS_MAX]; 838c2ecf20Sopenharmony_ci struct usbhs_mod *curt; /* current mod */ 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ci /* 868c2ecf20Sopenharmony_ci * INTSTS0 :: VBINT 878c2ecf20Sopenharmony_ci * 888c2ecf20Sopenharmony_ci * This function will be used as autonomy mode (runtime_pwctrl == 0) 898c2ecf20Sopenharmony_ci * when the platform doesn't have own get_vbus function. 908c2ecf20Sopenharmony_ci * 918c2ecf20Sopenharmony_ci * This callback cannot be member of "struct usbhs_mod" because it 928c2ecf20Sopenharmony_ci * will be used even though host/gadget has not been selected. 938c2ecf20Sopenharmony_ci */ 948c2ecf20Sopenharmony_ci int (*irq_vbus)(struct usbhs_priv *priv, 958c2ecf20Sopenharmony_ci struct usbhs_irq_state *irq_state); 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci /* 988c2ecf20Sopenharmony_ci * This function will be used on any gadget mode. To simplify the code, 998c2ecf20Sopenharmony_ci * this member is in here. 1008c2ecf20Sopenharmony_ci */ 1018c2ecf20Sopenharmony_ci int (*get_vbus)(struct platform_device *pdev); 1028c2ecf20Sopenharmony_ci}; 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_ci/* 1058c2ecf20Sopenharmony_ci * for host/gadget module 1068c2ecf20Sopenharmony_ci */ 1078c2ecf20Sopenharmony_cistruct usbhs_mod *usbhs_mod_get(struct usbhs_priv *priv, int id); 1088c2ecf20Sopenharmony_cistruct usbhs_mod *usbhs_mod_get_current(struct usbhs_priv *priv); 1098c2ecf20Sopenharmony_civoid usbhs_mod_register(struct usbhs_priv *priv, struct usbhs_mod *usb, int id); 1108c2ecf20Sopenharmony_ciint usbhs_mod_is_host(struct usbhs_priv *priv); 1118c2ecf20Sopenharmony_ciint usbhs_mod_change(struct usbhs_priv *priv, int id); 1128c2ecf20Sopenharmony_ciint usbhs_mod_probe(struct usbhs_priv *priv); 1138c2ecf20Sopenharmony_civoid usbhs_mod_remove(struct usbhs_priv *priv); 1148c2ecf20Sopenharmony_ci 1158c2ecf20Sopenharmony_civoid usbhs_mod_autonomy_mode(struct usbhs_priv *priv); 1168c2ecf20Sopenharmony_civoid usbhs_mod_non_autonomy_mode(struct usbhs_priv *priv); 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci/* 1198c2ecf20Sopenharmony_ci * status functions 1208c2ecf20Sopenharmony_ci */ 1218c2ecf20Sopenharmony_ciint usbhs_status_get_device_state(struct usbhs_irq_state *irq_state); 1228c2ecf20Sopenharmony_ciint usbhs_status_get_ctrl_stage(struct usbhs_irq_state *irq_state); 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_ci/* 1258c2ecf20Sopenharmony_ci * callback functions 1268c2ecf20Sopenharmony_ci */ 1278c2ecf20Sopenharmony_civoid usbhs_irq_callback_update(struct usbhs_priv *priv, struct usbhs_mod *mod); 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci#define usbhs_mod_call(priv, func, param...) \ 1318c2ecf20Sopenharmony_ci ({ \ 1328c2ecf20Sopenharmony_ci struct usbhs_mod *mod; \ 1338c2ecf20Sopenharmony_ci mod = usbhs_mod_get_current(priv); \ 1348c2ecf20Sopenharmony_ci !mod ? -ENODEV : \ 1358c2ecf20Sopenharmony_ci !mod->func ? 0 : \ 1368c2ecf20Sopenharmony_ci mod->func(param); \ 1378c2ecf20Sopenharmony_ci }) 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ci#define usbhs_priv_to_modinfo(priv) (&priv->mod_info) 1408c2ecf20Sopenharmony_ci#define usbhs_mod_info_call(priv, func, param...) \ 1418c2ecf20Sopenharmony_ci({ \ 1428c2ecf20Sopenharmony_ci struct usbhs_mod_info *info; \ 1438c2ecf20Sopenharmony_ci info = usbhs_priv_to_modinfo(priv); \ 1448c2ecf20Sopenharmony_ci !info->func ? 0 : \ 1458c2ecf20Sopenharmony_ci info->func(param); \ 1468c2ecf20Sopenharmony_ci}) 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci/* 1498c2ecf20Sopenharmony_ci * host / gadget control 1508c2ecf20Sopenharmony_ci */ 1518c2ecf20Sopenharmony_ci#if defined(CONFIG_USB_RENESAS_USBHS_HCD) || \ 1528c2ecf20Sopenharmony_ci defined(CONFIG_USB_RENESAS_USBHS_HCD_MODULE) 1538c2ecf20Sopenharmony_ciextern int usbhs_mod_host_probe(struct usbhs_priv *priv); 1548c2ecf20Sopenharmony_ciextern int usbhs_mod_host_remove(struct usbhs_priv *priv); 1558c2ecf20Sopenharmony_ci#else 1568c2ecf20Sopenharmony_cistatic inline int usbhs_mod_host_probe(struct usbhs_priv *priv) 1578c2ecf20Sopenharmony_ci{ 1588c2ecf20Sopenharmony_ci return 0; 1598c2ecf20Sopenharmony_ci} 1608c2ecf20Sopenharmony_cistatic inline void usbhs_mod_host_remove(struct usbhs_priv *priv) 1618c2ecf20Sopenharmony_ci{ 1628c2ecf20Sopenharmony_ci} 1638c2ecf20Sopenharmony_ci#endif 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_ci#if defined(CONFIG_USB_RENESAS_USBHS_UDC) || \ 1668c2ecf20Sopenharmony_ci defined(CONFIG_USB_RENESAS_USBHS_UDC_MODULE) 1678c2ecf20Sopenharmony_ciextern int usbhs_mod_gadget_probe(struct usbhs_priv *priv); 1688c2ecf20Sopenharmony_ciextern void usbhs_mod_gadget_remove(struct usbhs_priv *priv); 1698c2ecf20Sopenharmony_ci#else 1708c2ecf20Sopenharmony_cistatic inline int usbhs_mod_gadget_probe(struct usbhs_priv *priv) 1718c2ecf20Sopenharmony_ci{ 1728c2ecf20Sopenharmony_ci return 0; 1738c2ecf20Sopenharmony_ci} 1748c2ecf20Sopenharmony_cistatic inline void usbhs_mod_gadget_remove(struct usbhs_priv *priv) 1758c2ecf20Sopenharmony_ci{ 1768c2ecf20Sopenharmony_ci} 1778c2ecf20Sopenharmony_ci#endif 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ci#endif /* RENESAS_USB_MOD_H */ 180