129e9ead2SNishad Kamdar /* SPDX-License-Identifier: GPL-2.0 */ 20316ca63SLaurent Pinchart /* 30316ca63SLaurent Pinchart * Driver for the NXP ISP1761 device controller 40316ca63SLaurent Pinchart * 560d789f3SRui Miguel Silva * Copyright 2021 Linaro, Rui Miguel Silva 60316ca63SLaurent Pinchart * Copyright 2014 Ideas on Board Oy 70316ca63SLaurent Pinchart * 80316ca63SLaurent Pinchart * Contacts: 90316ca63SLaurent Pinchart * Laurent Pinchart <laurent.pinchart@ideasonboard.com> 1060d789f3SRui Miguel Silva * Rui Miguel Silva <rui.silva@linaro.org> 110316ca63SLaurent Pinchart */ 120316ca63SLaurent Pinchart 130316ca63SLaurent Pinchart #ifndef _ISP1760_UDC_H_ 140316ca63SLaurent Pinchart #define _ISP1760_UDC_H_ 150316ca63SLaurent Pinchart 160316ca63SLaurent Pinchart #include <linux/ioport.h> 170316ca63SLaurent Pinchart #include <linux/list.h> 180316ca63SLaurent Pinchart #include <linux/spinlock.h> 190316ca63SLaurent Pinchart #include <linux/timer.h> 200316ca63SLaurent Pinchart #include <linux/usb/gadget.h> 210316ca63SLaurent Pinchart 221da9e1c0SRui Miguel Silva #include "isp1760-regs.h" 231da9e1c0SRui Miguel Silva 240316ca63SLaurent Pinchart struct isp1760_device; 250316ca63SLaurent Pinchart struct isp1760_udc; 260316ca63SLaurent Pinchart 270316ca63SLaurent Pinchart enum isp1760_ctrl_state { 280316ca63SLaurent Pinchart ISP1760_CTRL_SETUP, /* Waiting for a SETUP transaction */ 290316ca63SLaurent Pinchart ISP1760_CTRL_DATA_IN, /* Setup received, data IN stage */ 300316ca63SLaurent Pinchart ISP1760_CTRL_DATA_OUT, /* Setup received, data OUT stage */ 310316ca63SLaurent Pinchart ISP1760_CTRL_STATUS, /* 0-length request in status stage */ 320316ca63SLaurent Pinchart }; 330316ca63SLaurent Pinchart 340316ca63SLaurent Pinchart struct isp1760_ep { 350316ca63SLaurent Pinchart struct isp1760_udc *udc; 360316ca63SLaurent Pinchart struct usb_ep ep; 370316ca63SLaurent Pinchart 380316ca63SLaurent Pinchart struct list_head queue; 390316ca63SLaurent Pinchart 400316ca63SLaurent Pinchart unsigned int addr; 410316ca63SLaurent Pinchart unsigned int maxpacket; 420316ca63SLaurent Pinchart char name[7]; 430316ca63SLaurent Pinchart 440316ca63SLaurent Pinchart const struct usb_endpoint_descriptor *desc; 450316ca63SLaurent Pinchart 460316ca63SLaurent Pinchart bool rx_pending; 470316ca63SLaurent Pinchart bool halted; 480316ca63SLaurent Pinchart bool wedged; 490316ca63SLaurent Pinchart }; 500316ca63SLaurent Pinchart 510316ca63SLaurent Pinchart /** 520316ca63SLaurent Pinchart * struct isp1760_udc - UDC state information 530316ca63SLaurent Pinchart * irq: IRQ number 540316ca63SLaurent Pinchart * irqname: IRQ name (as passed to request_irq) 551da9e1c0SRui Miguel Silva * regs: regmap for UDC registers 560316ca63SLaurent Pinchart * driver: Gadget driver 570316ca63SLaurent Pinchart * gadget: Gadget device 580316ca63SLaurent Pinchart * lock: Protects driver, vbus_timer, ep, ep0_*, DC_EPINDEX register 590316ca63SLaurent Pinchart * ep: Array of endpoints 600316ca63SLaurent Pinchart * ep0_state: Control request state for endpoint 0 610316ca63SLaurent Pinchart * ep0_dir: Direction of the current control request 620316ca63SLaurent Pinchart * ep0_length: Length of the current control request 630316ca63SLaurent Pinchart * connected: Tracks gadget driver bus connection state 640316ca63SLaurent Pinchart */ 650316ca63SLaurent Pinchart struct isp1760_udc { 660316ca63SLaurent Pinchart struct isp1760_device *isp; 670316ca63SLaurent Pinchart 680316ca63SLaurent Pinchart int irq; 690316ca63SLaurent Pinchart char *irqname; 701da9e1c0SRui Miguel Silva 711da9e1c0SRui Miguel Silva struct regmap *regs; 721da9e1c0SRui Miguel Silva struct regmap_field *fields[DC_FIELD_MAX]; 730316ca63SLaurent Pinchart 740316ca63SLaurent Pinchart struct usb_gadget_driver *driver; 750316ca63SLaurent Pinchart struct usb_gadget gadget; 760316ca63SLaurent Pinchart 770316ca63SLaurent Pinchart spinlock_t lock; 780316ca63SLaurent Pinchart struct timer_list vbus_timer; 790316ca63SLaurent Pinchart 800316ca63SLaurent Pinchart struct isp1760_ep ep[15]; 810316ca63SLaurent Pinchart 820316ca63SLaurent Pinchart enum isp1760_ctrl_state ep0_state; 830316ca63SLaurent Pinchart u8 ep0_dir; 840316ca63SLaurent Pinchart u16 ep0_length; 850316ca63SLaurent Pinchart 860316ca63SLaurent Pinchart bool connected; 87*d369c918SRui Miguel Silva bool is_isp1763; 880316ca63SLaurent Pinchart 890316ca63SLaurent Pinchart unsigned int devstatus; 900316ca63SLaurent Pinchart }; 910316ca63SLaurent Pinchart 92100832abSLaurent Pinchart #ifdef CONFIG_USB_ISP1761_UDC 930316ca63SLaurent Pinchart int isp1760_udc_register(struct isp1760_device *isp, int irq, 940316ca63SLaurent Pinchart unsigned long irqflags); 950316ca63SLaurent Pinchart void isp1760_udc_unregister(struct isp1760_device *isp); 960316ca63SLaurent Pinchart #else 970316ca63SLaurent Pinchart static inline int isp1760_udc_register(struct isp1760_device *isp, int irq, 980316ca63SLaurent Pinchart unsigned long irqflags) 990316ca63SLaurent Pinchart { 1000316ca63SLaurent Pinchart return 0; 1010316ca63SLaurent Pinchart } 1020316ca63SLaurent Pinchart 1030316ca63SLaurent Pinchart static inline void isp1760_udc_unregister(struct isp1760_device *isp) 1040316ca63SLaurent Pinchart { 1050316ca63SLaurent Pinchart } 1060316ca63SLaurent Pinchart #endif 1070316ca63SLaurent Pinchart 1080316ca63SLaurent Pinchart #endif 109