xref: /linux/drivers/usb/isp1760/isp1760-udc.h (revision 353b7a55dcaf5fb8758e09ebe2ddf5f3adbac7c5)
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