18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Driver for the NXP ISP1761 device controller
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright 2014 Ideas on Board Oy
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci * Contacts:
88c2ecf20Sopenharmony_ci *	Laurent Pinchart <laurent.pinchart@ideasonboard.com>
98c2ecf20Sopenharmony_ci */
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#ifndef _ISP1760_UDC_H_
128c2ecf20Sopenharmony_ci#define _ISP1760_UDC_H_
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ci#include <linux/ioport.h>
158c2ecf20Sopenharmony_ci#include <linux/list.h>
168c2ecf20Sopenharmony_ci#include <linux/spinlock.h>
178c2ecf20Sopenharmony_ci#include <linux/timer.h>
188c2ecf20Sopenharmony_ci#include <linux/usb/gadget.h>
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_cistruct isp1760_device;
218c2ecf20Sopenharmony_cistruct isp1760_udc;
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_cienum isp1760_ctrl_state {
248c2ecf20Sopenharmony_ci	ISP1760_CTRL_SETUP,		/* Waiting for a SETUP transaction */
258c2ecf20Sopenharmony_ci	ISP1760_CTRL_DATA_IN,		/* Setup received, data IN stage */
268c2ecf20Sopenharmony_ci	ISP1760_CTRL_DATA_OUT,		/* Setup received, data OUT stage */
278c2ecf20Sopenharmony_ci	ISP1760_CTRL_STATUS,		/* 0-length request in status stage */
288c2ecf20Sopenharmony_ci};
298c2ecf20Sopenharmony_ci
308c2ecf20Sopenharmony_cistruct isp1760_ep {
318c2ecf20Sopenharmony_ci	struct isp1760_udc *udc;
328c2ecf20Sopenharmony_ci	struct usb_ep ep;
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ci	struct list_head queue;
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci	unsigned int addr;
378c2ecf20Sopenharmony_ci	unsigned int maxpacket;
388c2ecf20Sopenharmony_ci	char name[7];
398c2ecf20Sopenharmony_ci
408c2ecf20Sopenharmony_ci	const struct usb_endpoint_descriptor *desc;
418c2ecf20Sopenharmony_ci
428c2ecf20Sopenharmony_ci	bool rx_pending;
438c2ecf20Sopenharmony_ci	bool halted;
448c2ecf20Sopenharmony_ci	bool wedged;
458c2ecf20Sopenharmony_ci};
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci/**
488c2ecf20Sopenharmony_ci * struct isp1760_udc - UDC state information
498c2ecf20Sopenharmony_ci * irq: IRQ number
508c2ecf20Sopenharmony_ci * irqname: IRQ name (as passed to request_irq)
518c2ecf20Sopenharmony_ci * regs: Base address of the UDC registers
528c2ecf20Sopenharmony_ci * driver: Gadget driver
538c2ecf20Sopenharmony_ci * gadget: Gadget device
548c2ecf20Sopenharmony_ci * lock: Protects driver, vbus_timer, ep, ep0_*, DC_EPINDEX register
558c2ecf20Sopenharmony_ci * ep: Array of endpoints
568c2ecf20Sopenharmony_ci * ep0_state: Control request state for endpoint 0
578c2ecf20Sopenharmony_ci * ep0_dir: Direction of the current control request
588c2ecf20Sopenharmony_ci * ep0_length: Length of the current control request
598c2ecf20Sopenharmony_ci * connected: Tracks gadget driver bus connection state
608c2ecf20Sopenharmony_ci */
618c2ecf20Sopenharmony_cistruct isp1760_udc {
628c2ecf20Sopenharmony_ci#ifdef CONFIG_USB_ISP1761_UDC
638c2ecf20Sopenharmony_ci	struct isp1760_device *isp;
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci	int irq;
668c2ecf20Sopenharmony_ci	char *irqname;
678c2ecf20Sopenharmony_ci	void __iomem *regs;
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ci	struct usb_gadget_driver *driver;
708c2ecf20Sopenharmony_ci	struct usb_gadget gadget;
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ci	spinlock_t lock;
738c2ecf20Sopenharmony_ci	struct timer_list vbus_timer;
748c2ecf20Sopenharmony_ci
758c2ecf20Sopenharmony_ci	struct isp1760_ep ep[15];
768c2ecf20Sopenharmony_ci
778c2ecf20Sopenharmony_ci	enum isp1760_ctrl_state ep0_state;
788c2ecf20Sopenharmony_ci	u8 ep0_dir;
798c2ecf20Sopenharmony_ci	u16 ep0_length;
808c2ecf20Sopenharmony_ci
818c2ecf20Sopenharmony_ci	bool connected;
828c2ecf20Sopenharmony_ci
838c2ecf20Sopenharmony_ci	unsigned int devstatus;
848c2ecf20Sopenharmony_ci#endif
858c2ecf20Sopenharmony_ci};
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_ci#ifdef CONFIG_USB_ISP1761_UDC
888c2ecf20Sopenharmony_ciint isp1760_udc_register(struct isp1760_device *isp, int irq,
898c2ecf20Sopenharmony_ci			 unsigned long irqflags);
908c2ecf20Sopenharmony_civoid isp1760_udc_unregister(struct isp1760_device *isp);
918c2ecf20Sopenharmony_ci#else
928c2ecf20Sopenharmony_cistatic inline int isp1760_udc_register(struct isp1760_device *isp, int irq,
938c2ecf20Sopenharmony_ci				       unsigned long irqflags)
948c2ecf20Sopenharmony_ci{
958c2ecf20Sopenharmony_ci	return 0;
968c2ecf20Sopenharmony_ci}
978c2ecf20Sopenharmony_ci
988c2ecf20Sopenharmony_cistatic inline void isp1760_udc_unregister(struct isp1760_device *isp)
998c2ecf20Sopenharmony_ci{
1008c2ecf20Sopenharmony_ci}
1018c2ecf20Sopenharmony_ci#endif
1028c2ecf20Sopenharmony_ci
1038c2ecf20Sopenharmony_ci#endif
104