162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-1.0+ */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Renesas USB driver 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2011 Renesas Solutions Corp. 662306a36Sopenharmony_ci * Copyright (C) 2019 Renesas Electronics Corporation 762306a36Sopenharmony_ci * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> 862306a36Sopenharmony_ci */ 962306a36Sopenharmony_ci#ifndef RENESAS_USB_MOD_H 1062306a36Sopenharmony_ci#define RENESAS_USB_MOD_H 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#include <linux/spinlock.h> 1362306a36Sopenharmony_ci#include <linux/usb/renesas_usbhs.h> 1462306a36Sopenharmony_ci#include "common.h" 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci/* 1762306a36Sopenharmony_ci * struct 1862306a36Sopenharmony_ci */ 1962306a36Sopenharmony_cistruct usbhs_irq_state { 2062306a36Sopenharmony_ci u16 intsts0; 2162306a36Sopenharmony_ci u16 intsts1; 2262306a36Sopenharmony_ci u16 brdysts; 2362306a36Sopenharmony_ci u16 nrdysts; 2462306a36Sopenharmony_ci u16 bempsts; 2562306a36Sopenharmony_ci}; 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_cistruct usbhs_mod { 2862306a36Sopenharmony_ci char *name; 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci /* 3162306a36Sopenharmony_ci * entry point from common.c 3262306a36Sopenharmony_ci */ 3362306a36Sopenharmony_ci int (*start)(struct usbhs_priv *priv); 3462306a36Sopenharmony_ci int (*stop)(struct usbhs_priv *priv); 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci /* 3762306a36Sopenharmony_ci * INTSTS0 3862306a36Sopenharmony_ci */ 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci /* DVST (DVSQ) */ 4162306a36Sopenharmony_ci int (*irq_dev_state)(struct usbhs_priv *priv, 4262306a36Sopenharmony_ci struct usbhs_irq_state *irq_state); 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci /* CTRT (CTSQ) */ 4562306a36Sopenharmony_ci int (*irq_ctrl_stage)(struct usbhs_priv *priv, 4662306a36Sopenharmony_ci struct usbhs_irq_state *irq_state); 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci /* BEMP / BEMPSTS */ 4962306a36Sopenharmony_ci int (*irq_empty)(struct usbhs_priv *priv, 5062306a36Sopenharmony_ci struct usbhs_irq_state *irq_state); 5162306a36Sopenharmony_ci u16 irq_bempsts; 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci /* BRDY / BRDYSTS */ 5462306a36Sopenharmony_ci int (*irq_ready)(struct usbhs_priv *priv, 5562306a36Sopenharmony_ci struct usbhs_irq_state *irq_state); 5662306a36Sopenharmony_ci u16 irq_brdysts; 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci /* 5962306a36Sopenharmony_ci * INTSTS1 6062306a36Sopenharmony_ci */ 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci /* ATTCHE */ 6362306a36Sopenharmony_ci int (*irq_attch)(struct usbhs_priv *priv, 6462306a36Sopenharmony_ci struct usbhs_irq_state *irq_state); 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci /* DTCHE */ 6762306a36Sopenharmony_ci int (*irq_dtch)(struct usbhs_priv *priv, 6862306a36Sopenharmony_ci struct usbhs_irq_state *irq_state); 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci /* SIGN */ 7162306a36Sopenharmony_ci int (*irq_sign)(struct usbhs_priv *priv, 7262306a36Sopenharmony_ci struct usbhs_irq_state *irq_state); 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci /* SACK */ 7562306a36Sopenharmony_ci int (*irq_sack)(struct usbhs_priv *priv, 7662306a36Sopenharmony_ci struct usbhs_irq_state *irq_state); 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci struct usbhs_priv *priv; 7962306a36Sopenharmony_ci}; 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_cistruct usbhs_mod_info { 8262306a36Sopenharmony_ci struct usbhs_mod *mod[USBHS_MAX]; 8362306a36Sopenharmony_ci struct usbhs_mod *curt; /* current mod */ 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci /* 8662306a36Sopenharmony_ci * INTSTS0 :: VBINT 8762306a36Sopenharmony_ci * 8862306a36Sopenharmony_ci * This function will be used as autonomy mode (runtime_pwctrl == 0) 8962306a36Sopenharmony_ci * when the platform doesn't have own get_vbus function. 9062306a36Sopenharmony_ci * 9162306a36Sopenharmony_ci * This callback cannot be member of "struct usbhs_mod" because it 9262306a36Sopenharmony_ci * will be used even though host/gadget has not been selected. 9362306a36Sopenharmony_ci */ 9462306a36Sopenharmony_ci int (*irq_vbus)(struct usbhs_priv *priv, 9562306a36Sopenharmony_ci struct usbhs_irq_state *irq_state); 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci /* 9862306a36Sopenharmony_ci * This function will be used on any gadget mode. To simplify the code, 9962306a36Sopenharmony_ci * this member is in here. 10062306a36Sopenharmony_ci */ 10162306a36Sopenharmony_ci int (*get_vbus)(struct platform_device *pdev); 10262306a36Sopenharmony_ci}; 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci/* 10562306a36Sopenharmony_ci * for host/gadget module 10662306a36Sopenharmony_ci */ 10762306a36Sopenharmony_cistruct usbhs_mod *usbhs_mod_get(struct usbhs_priv *priv, int id); 10862306a36Sopenharmony_cistruct usbhs_mod *usbhs_mod_get_current(struct usbhs_priv *priv); 10962306a36Sopenharmony_civoid usbhs_mod_register(struct usbhs_priv *priv, struct usbhs_mod *usb, int id); 11062306a36Sopenharmony_ciint usbhs_mod_is_host(struct usbhs_priv *priv); 11162306a36Sopenharmony_ciint usbhs_mod_change(struct usbhs_priv *priv, int id); 11262306a36Sopenharmony_ciint usbhs_mod_probe(struct usbhs_priv *priv); 11362306a36Sopenharmony_civoid usbhs_mod_remove(struct usbhs_priv *priv); 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_civoid usbhs_mod_autonomy_mode(struct usbhs_priv *priv); 11662306a36Sopenharmony_civoid usbhs_mod_non_autonomy_mode(struct usbhs_priv *priv); 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci/* 11962306a36Sopenharmony_ci * status functions 12062306a36Sopenharmony_ci */ 12162306a36Sopenharmony_ciint usbhs_status_get_device_state(struct usbhs_irq_state *irq_state); 12262306a36Sopenharmony_ciint usbhs_status_get_ctrl_stage(struct usbhs_irq_state *irq_state); 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci/* 12562306a36Sopenharmony_ci * callback functions 12662306a36Sopenharmony_ci */ 12762306a36Sopenharmony_civoid usbhs_irq_callback_update(struct usbhs_priv *priv, struct usbhs_mod *mod); 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci#define usbhs_mod_call(priv, func, param...) \ 13162306a36Sopenharmony_ci ({ \ 13262306a36Sopenharmony_ci struct usbhs_mod *mod; \ 13362306a36Sopenharmony_ci mod = usbhs_mod_get_current(priv); \ 13462306a36Sopenharmony_ci !mod ? -ENODEV : \ 13562306a36Sopenharmony_ci !mod->func ? 0 : \ 13662306a36Sopenharmony_ci mod->func(param); \ 13762306a36Sopenharmony_ci }) 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci#define usbhs_priv_to_modinfo(priv) (&priv->mod_info) 14062306a36Sopenharmony_ci#define usbhs_mod_info_call(priv, func, param...) \ 14162306a36Sopenharmony_ci({ \ 14262306a36Sopenharmony_ci struct usbhs_mod_info *info; \ 14362306a36Sopenharmony_ci info = usbhs_priv_to_modinfo(priv); \ 14462306a36Sopenharmony_ci !info->func ? 0 : \ 14562306a36Sopenharmony_ci info->func(param); \ 14662306a36Sopenharmony_ci}) 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci/* 14962306a36Sopenharmony_ci * host / gadget control 15062306a36Sopenharmony_ci */ 15162306a36Sopenharmony_ci#if defined(CONFIG_USB_RENESAS_USBHS_HCD) || \ 15262306a36Sopenharmony_ci defined(CONFIG_USB_RENESAS_USBHS_HCD_MODULE) 15362306a36Sopenharmony_ciextern int usbhs_mod_host_probe(struct usbhs_priv *priv); 15462306a36Sopenharmony_ciextern int usbhs_mod_host_remove(struct usbhs_priv *priv); 15562306a36Sopenharmony_ci#else 15662306a36Sopenharmony_cistatic inline int usbhs_mod_host_probe(struct usbhs_priv *priv) 15762306a36Sopenharmony_ci{ 15862306a36Sopenharmony_ci return 0; 15962306a36Sopenharmony_ci} 16062306a36Sopenharmony_cistatic inline void usbhs_mod_host_remove(struct usbhs_priv *priv) 16162306a36Sopenharmony_ci{ 16262306a36Sopenharmony_ci} 16362306a36Sopenharmony_ci#endif 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_ci#if defined(CONFIG_USB_RENESAS_USBHS_UDC) || \ 16662306a36Sopenharmony_ci defined(CONFIG_USB_RENESAS_USBHS_UDC_MODULE) 16762306a36Sopenharmony_ciextern int usbhs_mod_gadget_probe(struct usbhs_priv *priv); 16862306a36Sopenharmony_ciextern void usbhs_mod_gadget_remove(struct usbhs_priv *priv); 16962306a36Sopenharmony_ci#else 17062306a36Sopenharmony_cistatic inline int usbhs_mod_gadget_probe(struct usbhs_priv *priv) 17162306a36Sopenharmony_ci{ 17262306a36Sopenharmony_ci return 0; 17362306a36Sopenharmony_ci} 17462306a36Sopenharmony_cistatic inline void usbhs_mod_gadget_remove(struct usbhs_priv *priv) 17562306a36Sopenharmony_ci{ 17662306a36Sopenharmony_ci} 17762306a36Sopenharmony_ci#endif 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci#endif /* RENESAS_USB_MOD_H */ 180