162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Driver for the NXP ISP1761 device controller 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright 2021 Linaro, Rui Miguel Silva 662306a36Sopenharmony_ci * Copyright 2014 Ideas on Board Oy 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * Contacts: 962306a36Sopenharmony_ci * Laurent Pinchart <laurent.pinchart@ideasonboard.com> 1062306a36Sopenharmony_ci * Rui Miguel Silva <rui.silva@linaro.org> 1162306a36Sopenharmony_ci */ 1262306a36Sopenharmony_ci 1362306a36Sopenharmony_ci#ifndef _ISP1760_UDC_H_ 1462306a36Sopenharmony_ci#define _ISP1760_UDC_H_ 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci#include <linux/ioport.h> 1762306a36Sopenharmony_ci#include <linux/list.h> 1862306a36Sopenharmony_ci#include <linux/spinlock.h> 1962306a36Sopenharmony_ci#include <linux/timer.h> 2062306a36Sopenharmony_ci#include <linux/usb/gadget.h> 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci#include "isp1760-regs.h" 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_cistruct isp1760_device; 2562306a36Sopenharmony_cistruct isp1760_udc; 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_cienum isp1760_ctrl_state { 2862306a36Sopenharmony_ci ISP1760_CTRL_SETUP, /* Waiting for a SETUP transaction */ 2962306a36Sopenharmony_ci ISP1760_CTRL_DATA_IN, /* Setup received, data IN stage */ 3062306a36Sopenharmony_ci ISP1760_CTRL_DATA_OUT, /* Setup received, data OUT stage */ 3162306a36Sopenharmony_ci ISP1760_CTRL_STATUS, /* 0-length request in status stage */ 3262306a36Sopenharmony_ci}; 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_cistruct isp1760_ep { 3562306a36Sopenharmony_ci struct isp1760_udc *udc; 3662306a36Sopenharmony_ci struct usb_ep ep; 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci struct list_head queue; 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci unsigned int addr; 4162306a36Sopenharmony_ci unsigned int maxpacket; 4262306a36Sopenharmony_ci char name[7]; 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci const struct usb_endpoint_descriptor *desc; 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci bool rx_pending; 4762306a36Sopenharmony_ci bool halted; 4862306a36Sopenharmony_ci bool wedged; 4962306a36Sopenharmony_ci}; 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci/** 5262306a36Sopenharmony_ci * struct isp1760_udc - UDC state information 5362306a36Sopenharmony_ci * irq: IRQ number 5462306a36Sopenharmony_ci * irqname: IRQ name (as passed to request_irq) 5562306a36Sopenharmony_ci * regs: regmap for UDC registers 5662306a36Sopenharmony_ci * driver: Gadget driver 5762306a36Sopenharmony_ci * gadget: Gadget device 5862306a36Sopenharmony_ci * lock: Protects driver, vbus_timer, ep, ep0_*, DC_EPINDEX register 5962306a36Sopenharmony_ci * ep: Array of endpoints 6062306a36Sopenharmony_ci * ep0_state: Control request state for endpoint 0 6162306a36Sopenharmony_ci * ep0_dir: Direction of the current control request 6262306a36Sopenharmony_ci * ep0_length: Length of the current control request 6362306a36Sopenharmony_ci * connected: Tracks gadget driver bus connection state 6462306a36Sopenharmony_ci */ 6562306a36Sopenharmony_cistruct isp1760_udc { 6662306a36Sopenharmony_ci struct isp1760_device *isp; 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci int irq; 6962306a36Sopenharmony_ci char *irqname; 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci struct regmap *regs; 7262306a36Sopenharmony_ci struct regmap_field *fields[DC_FIELD_MAX]; 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci struct usb_gadget_driver *driver; 7562306a36Sopenharmony_ci struct usb_gadget gadget; 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci spinlock_t lock; 7862306a36Sopenharmony_ci struct timer_list vbus_timer; 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci struct isp1760_ep ep[15]; 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci enum isp1760_ctrl_state ep0_state; 8362306a36Sopenharmony_ci u8 ep0_dir; 8462306a36Sopenharmony_ci u16 ep0_length; 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci bool connected; 8762306a36Sopenharmony_ci bool is_isp1763; 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci unsigned int devstatus; 9062306a36Sopenharmony_ci}; 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci#ifdef CONFIG_USB_ISP1761_UDC 9362306a36Sopenharmony_ciint isp1760_udc_register(struct isp1760_device *isp, int irq, 9462306a36Sopenharmony_ci unsigned long irqflags); 9562306a36Sopenharmony_civoid isp1760_udc_unregister(struct isp1760_device *isp); 9662306a36Sopenharmony_ci#else 9762306a36Sopenharmony_cistatic inline int isp1760_udc_register(struct isp1760_device *isp, int irq, 9862306a36Sopenharmony_ci unsigned long irqflags) 9962306a36Sopenharmony_ci{ 10062306a36Sopenharmony_ci return 0; 10162306a36Sopenharmony_ci} 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_cistatic inline void isp1760_udc_unregister(struct isp1760_device *isp) 10462306a36Sopenharmony_ci{ 10562306a36Sopenharmony_ci} 10662306a36Sopenharmony_ci#endif 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci#endif 109