1184610Salfred/* $FreeBSD$ */
2184610Salfred/*-
3189002Sed * Copyright (c) 2007 Hans Petter Selasky <hselasky@FreeBSD.org>
4184610Salfred * All rights reserved.
5184610Salfred *
6184610Salfred * Redistribution and use in source and binary forms, with or without
7184610Salfred * modification, are permitted provided that the following conditions
8184610Salfred * are met:
9184610Salfred * 1. Redistributions of source code must retain the above copyright
10184610Salfred *    notice, this list of conditions and the following disclaimer.
11184610Salfred * 2. Redistributions in binary form must reproduce the above copyright
12184610Salfred *    notice, this list of conditions and the following disclaimer in the
13184610Salfred *    documentation and/or other materials provided with the distribution.
14184610Salfred *
15184610Salfred * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16184610Salfred * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17184610Salfred * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18184610Salfred * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19184610Salfred * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20184610Salfred * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21184610Salfred * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22184610Salfred * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23184610Salfred * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24184610Salfred * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25184610Salfred * SUCH DAMAGE.
26184610Salfred */
27184610Salfred
28184610Salfred#ifndef _USS820_DCI_H_
29184610Salfred#define	_USS820_DCI_H_
30184610Salfred
31187170Sthompsa#define	USS820_MAX_DEVICES (USB_MIN_DEVICES + 1)
32187170Sthompsa
33184610Salfred#define	USS820_EP_MAX 8			/* maximum number of endpoints */
34184610Salfred
35184610Salfred#define	USS820_TXDAT 0x00		/* Transmit FIFO data */
36184610Salfred
37184610Salfred#define	USS820_TXCNTL 0x01		/* Transmit FIFO byte count low */
38184610Salfred#define	USS820_TXCNTL_MASK 0xFF
39184610Salfred
40184610Salfred#define	USS820_TXCNTH 0x02		/* Transmit FIFO byte count high */
41184610Salfred#define	USS820_TXCNTH_MASK 0x03
42184610Salfred#define	USS820_TXCNTH_UNUSED 0xFC
43184610Salfred
44184610Salfred#define	USS820_TXCON 0x03		/* USB transmit FIFO control */
45184610Salfred#define	USS820_TXCON_REVRP 0x01
46184610Salfred#define	USS820_TXCON_ADVRM 0x02
47184610Salfred#define	USS820_TXCON_ATM 0x04		/* Automatic Transmit Management */
48184610Salfred#define	USS820_TXCON_TXISO 0x08		/* Transmit Isochronous Data */
49184610Salfred#define	USS820_TXCON_UNUSED 0x10
50184610Salfred#define	USS820_TXCON_FFSZ_16_64 0x00
51184610Salfred#define	USS820_TXCON_FFSZ_64_256 0x20
52184610Salfred#define	USS820_TXCON_FFSZ_8_512 0x40
53184610Salfred#define	USS820_TXCON_FFSZ_32_1024 0x60
54184610Salfred#define	USS820_TXCON_FFSZ_MASK 0x60
55184610Salfred#define	USS820_TXCON_TXCLR 0x80		/* Transmit FIFO clear */
56184610Salfred
57184610Salfred#define	USS820_TXFLG 0x04		/* Transmit FIFO flag (Read Only) */
58184610Salfred#define	USS820_TXFLG_TXOVF 0x01		/* TX overrun */
59184610Salfred#define	USS820_TXFLG_TXURF 0x02		/* TX underrun */
60184610Salfred#define	USS820_TXFLG_TXFULL 0x04	/* TX full */
61184610Salfred#define	USS820_TXFLG_TXEMP 0x08		/* TX empty */
62184610Salfred#define	USS820_TXFLG_UNUSED 0x30
63184610Salfred#define	USS820_TXFLG_TXFIF0 0x40
64184610Salfred#define	USS820_TXFLG_TXFIF1 0x80
65184610Salfred
66184610Salfred#define	USS820_RXDAT 0x05		/* Receive FIFO data */
67184610Salfred
68184610Salfred#define	USS820_RXCNTL 0x06		/* Receive FIFO byte count low */
69184610Salfred#define	USS820_RXCNTL_MASK 0xFF
70184610Salfred
71184610Salfred#define	USS820_RXCNTH 0x07		/* Receive FIFO byte count high */
72184610Salfred#define	USS820_RXCNTH_MASK 0x03
73184610Salfred#define	USS820_RXCNTH_UNUSED 0xFC
74184610Salfred
75184610Salfred#define	USS820_RXCON 0x08		/* Receive FIFO control */
76184610Salfred#define	USS820_RXCON_REVWP 0x01
77184610Salfred#define	USS820_RXCON_ADVWM 0x02
78184610Salfred#define	USS820_RXCON_ARM 0x04		/* Auto Receive Management */
79184610Salfred#define	USS820_RXCON_RXISO 0x08		/* Receive Isochronous Data */
80184610Salfred#define	USS820_RXCON_RXFFRC 0x10	/* FIFO Read Complete */
81184610Salfred#define	USS820_RXCON_FFSZ_16_64 0x00
82184610Salfred#define	USS820_RXCON_FFSZ_64_256 0x20
83184610Salfred#define	USS820_RXCON_FFSZ_8_512 0x40
84184610Salfred#define	USS820_RXCON_FFSZ_32_1024 0x60
85184610Salfred#define	USS820_RXCON_RXCLR 0x80		/* Receive FIFO clear */
86184610Salfred
87184610Salfred#define	USS820_RXFLG 0x09		/* Receive FIFO flag (Read Only) */
88184610Salfred#define	USS820_RXFLG_RXOVF 0x01		/* RX overflow */
89184610Salfred#define	USS820_RXFLG_RXURF 0x02		/* RX underflow */
90184610Salfred#define	USS820_RXFLG_RXFULL 0x04	/* RX full */
91184610Salfred#define	USS820_RXFLG_RXEMP 0x08		/* RX empty */
92184610Salfred#define	USS820_RXFLG_RXFLUSH 0x10	/* RX flush */
93184610Salfred#define	USS820_RXFLG_UNUSED 0x20
94184610Salfred#define	USS820_RXFLG_RXFIF0 0x40
95184610Salfred#define	USS820_RXFLG_RXFIF1 0x80
96184610Salfred
97184610Salfred#define	USS820_EPINDEX 0x0a		/* Endpoint index selection */
98184610Salfred#define	USS820_EPINDEX_MASK 0x07
99184610Salfred#define	USS820_EPINDEX_UNUSED 0xF8
100184610Salfred
101184610Salfred#define	USS820_EPCON 0x0b		/* Endpoint control */
102184610Salfred#define	USS820_EPCON_TXEPEN 0x01	/* Transmit Endpoint Enable */
103184610Salfred#define	USS820_EPCON_TXOE 0x02		/* Transmit Output Enable */
104184610Salfred#define	USS820_EPCON_RXEPEN 0x04	/* Receive Endpoint Enable */
105184610Salfred#define	USS820_EPCON_RXIE 0x08		/* Receive Input Enable */
106184610Salfred#define	USS820_EPCON_RXSPM 0x10		/* Receive Single-Packet Mode */
107184610Salfred#define	USS820_EPCON_CTLEP 0x20		/* Control Endpoint */
108184610Salfred#define	USS820_EPCON_TXSTL 0x40		/* Stall Transmit Endpoint */
109184610Salfred#define	USS820_EPCON_RXSTL 0x80		/* Stall Receive Endpoint */
110184610Salfred
111184610Salfred#define	USS820_TXSTAT 0x0c		/* Transmit status */
112184610Salfred#define	USS820_TXSTAT_TXACK 0x01	/* Transmit Acknowledge */
113184610Salfred#define	USS820_TXSTAT_TXERR 0x02	/* Transmit Error */
114184610Salfred#define	USS820_TXSTAT_TXVOID 0x04	/* Transmit Void */
115184610Salfred#define	USS820_TXSTAT_TXSOVW 0x08	/* Transmit Data Sequence Overwrite
116184610Salfred					 * Bit */
117184610Salfred#define	USS820_TXSTAT_TXFLUSH 0x10	/* Transmit FIFO Packet Flushed */
118184610Salfred#define	USS820_TXSTAT_TXNAKE 0x20	/* Transmit NAK Mode Enable */
119184610Salfred#define	USS820_TXSTAT_TXDSAM 0x40	/* Transmit Data-Set-Available Mode */
120184610Salfred#define	USS820_TXSTAT_TXSEQ 0x80	/* Transmitter Current Sequence Bit */
121184610Salfred
122184610Salfred#define	USS820_RXSTAT 0x0d		/* Receive status */
123184610Salfred#define	USS820_RXSTAT_RXACK 0x01	/* Receive Acknowledge */
124184610Salfred#define	USS820_RXSTAT_RXERR 0x02	/* Receive Error */
125184610Salfred#define	USS820_RXSTAT_RXVOID 0x04	/* Receive Void */
126184610Salfred#define	USS820_RXSTAT_RXSOVW 0x08	/* Receive Data Sequence Overwrite Bit */
127184610Salfred#define	USS820_RXSTAT_EDOVW 0x10	/* End Overwrite Flag */
128184610Salfred#define	USS820_RXSTAT_STOVW 0x20	/* Start Overwrite Flag */
129184610Salfred#define	USS820_RXSTAT_RXSETUP 0x40	/* Received SETUP token */
130184610Salfred#define	USS820_RXSTAT_RXSEQ 0x80	/* Receiver Endpoint Sequence Bit */
131184610Salfred
132184610Salfred#define	USS820_SOFL 0x0e		/* Start Of Frame counter low */
133184610Salfred#define	USS820_SOFL_MASK 0xFF
134184610Salfred
135184610Salfred#define	USS820_SOFH 0x0f		/* Start Of Frame counter high */
136184610Salfred#define	USS820_SOFH_MASK 0x07
137184610Salfred#define	USS820_SOFH_SOFDIS 0x08		/* SOF Pin Output Disable */
138184610Salfred#define	USS820_SOFH_FTLOCK 0x10		/* Frame Timer Lock */
139184610Salfred#define	USS820_SOFH_SOFIE 0x20		/* SOF Interrupt Enable */
140184610Salfred#define	USS820_SOFH_ASOF 0x40		/* Any Start of Frame */
141184610Salfred#define	USS820_SOFH_SOFACK 0x80		/* SOF Token Received Without Error */
142184610Salfred
143184610Salfred#define	USS820_FADDR 0x10		/* Function Address */
144184610Salfred#define	USS820_FADDR_MASK 0x7F
145184610Salfred#define	USS820_FADDR_UNUSED 0x80
146184610Salfred
147184610Salfred#define	USS820_SCR 0x11			/* System Control */
148184610Salfred#define	USS820_SCR_UNUSED 0x01
149184610Salfred#define	USS820_SCR_T_IRQ 0x02		/* Global Interrupt Enable */
150184610Salfred#define	USS820_SCR_IRQLVL 0x04		/* Interrupt Mode */
151184610Salfred#define	USS820_SCR_SRESET 0x08		/* Software reset */
152184610Salfred#define	USS820_SCR_IE_RESET 0x10	/* Enable Reset Interrupt */
153184610Salfred#define	USS820_SCR_IE_SUSP 0x20		/* Enable Suspend Interrupt */
154184610Salfred#define	USS820_SCR_RWUPE 0x40		/* Enable Remote Wake-Up Feature */
155184610Salfred#define	USS820_SCR_IRQPOL 0x80		/* IRQ polarity */
156184610Salfred
157184610Salfred#define	USS820_SSR 0x12			/* System Status */
158184610Salfred#define	USS820_SSR_RESET 0x01		/* Reset Condition Detected on USB
159184610Salfred					 * cable */
160184610Salfred#define	USS820_SSR_SUSPEND 0x02		/* Suspend Detected */
161184610Salfred#define	USS820_SSR_RESUME 0x04		/* Resume Detected */
162184610Salfred#define	USS820_SSR_SUSPDIS 0x08		/* Suspend Disable */
163184610Salfred#define	USS820_SSR_SUSPPO 0x10		/* Suspend Power Off */
164184610Salfred#define	USS820_SSR_UNUSED 0xE0
165184610Salfred
166184610Salfred#define	USS820_UNK0 0x13		/* Unknown */
167184610Salfred#define	USS820_UNK0_UNUSED 0xFF
168184610Salfred
169184610Salfred#define	USS820_SBI 0x14			/* Serial bus interrupt low */
170184610Salfred#define	USS820_SBI_FTXD0 0x01		/* Function Transmit Done, EP 0 */
171184610Salfred#define	USS820_SBI_FRXD0 0x02		/* Function Receive Done, EP 0 */
172184610Salfred#define	USS820_SBI_FTXD1 0x04
173184610Salfred#define	USS820_SBI_FRXD1 0x08
174184610Salfred#define	USS820_SBI_FTXD2 0x10
175184610Salfred#define	USS820_SBI_FRXD2 0x20
176184610Salfred#define	USS820_SBI_FTXD3 0x40
177184610Salfred#define	USS820_SBI_FRXD3 0x80
178184610Salfred
179184610Salfred#define	USS820_SBI1 0x15		/* Serial bus interrupt high */
180184610Salfred#define	USS820_SBI1_FTXD4 0x01
181184610Salfred#define	USS820_SBI1_FRXD4 0x02
182184610Salfred#define	USS820_SBI1_FTXD5 0x04
183184610Salfred#define	USS820_SBI1_FRXD5 0x08
184184610Salfred#define	USS820_SBI1_FTXD6 0x10
185184610Salfred#define	USS820_SBI1_FRXD6 0x20
186184610Salfred#define	USS820_SBI1_FTXD7 0x40
187184610Salfred#define	USS820_SBI1_FRXD7 0x80
188184610Salfred
189184610Salfred#define	USS820_SBIE 0x16		/* Serial bus interrupt enable low */
190184610Salfred#define	USS820_SBIE_FTXIE0 0x01
191184610Salfred#define	USS820_SBIE_FRXIE0 0x02
192184610Salfred#define	USS820_SBIE_FTXIE1 0x04
193184610Salfred#define	USS820_SBIE_FRXIE1 0x08
194184610Salfred#define	USS820_SBIE_FTXIE2 0x10
195184610Salfred#define	USS820_SBIE_FRXIE2 0x20
196184610Salfred#define	USS820_SBIE_FTXIE3 0x40
197184610Salfred#define	USS820_SBIE_FRXIE3 0x80
198184610Salfred
199184610Salfred#define	USS820_SBIE1 0x17		/* Serial bus interrupt enable high */
200184610Salfred#define	USS820_SBIE1_FTXIE4 0x01
201184610Salfred#define	USS820_SBIE1_FRXIE4 0x02
202184610Salfred#define	USS820_SBIE1_FTXIE5 0x04
203184610Salfred#define	USS820_SBIE1_FRXIE5 0x08
204184610Salfred#define	USS820_SBIE1_FTXIE6 0x10
205184610Salfred#define	USS820_SBIE1_FRXIE6 0x20
206184610Salfred#define	USS820_SBIE1_FTXIE7 0x40
207184610Salfred#define	USS820_SBIE1_FRXIE7 0x80
208184610Salfred
209184610Salfred#define	USS820_REV 0x18			/* Hardware revision */
210184610Salfred#define	USS820_REV_MIN 0x0F
211184610Salfred#define	USS820_REV_MAJ 0xF0
212184610Salfred
213184610Salfred#define	USS820_LOCK 0x19		/* Suspend power-off locking */
214184610Salfred#define	USS820_LOCK_UNLOCKED 0x01
215184610Salfred#define	USS820_LOCK_UNUSED 0xFE
216184610Salfred
217184610Salfred#define	USS820_PEND 0x1a		/* Pend hardware status update */
218184610Salfred#define	USS820_PEND_PEND 0x01
219184610Salfred#define	USS820_PEND_UNUSED 0xFE
220184610Salfred
221184610Salfred#define	USS820_SCRATCH 0x1b		/* Scratch firmware information */
222184610Salfred#define	USS820_SCRATCH_MASK 0x7F
223184610Salfred#define	USS820_SCRATCH_IE_RESUME 0x80	/* Enable Resume Interrupt */
224184610Salfred
225184610Salfred#define	USS820_MCSR 0x1c		/* Miscellaneous control and status */
226184610Salfred#define	USS820_MCSR_DPEN 0x01		/* DPLS Pull-Up Enable */
227184610Salfred#define	USS820_MCSR_SUSPLOE 0x02	/* Suspend Lock Out Enable */
228184610Salfred#define	USS820_MCSR_BDFEAT 0x04		/* Board Feature Enable */
229184610Salfred#define	USS820_MCSR_FEAT 0x08		/* Feature Enable */
230184610Salfred#define	USS820_MCSR_PKGID 0x10		/* Package Identification */
231184610Salfred#define	USS820_MCSR_SUSPS 0x20		/* Suspend Status */
232184610Salfred#define	USS820_MCSR_INIT 0x40		/* Device Initialized */
233184610Salfred#define	USS820_MCSR_RWUPR 0x80		/* Remote Wakeup-Up Remember */
234184610Salfred
235184610Salfred#define	USS820_DSAV 0x1d		/* Data set available low (Read Only) */
236184610Salfred#define	USS820_DSAV_TXAV0 0x01
237184610Salfred#define	USS820_DSAV_RXAV0 0x02
238184610Salfred#define	USS820_DSAV_TXAV1 0x04
239184610Salfred#define	USS820_DSAV_RXAV1 0x08
240184610Salfred#define	USS820_DSAV_TXAV2 0x10
241184610Salfred#define	USS820_DSAV_RXAV2 0x20
242184610Salfred#define	USS820_DSAV_TXAV3 0x40
243184610Salfred#define	USS820_DSAV_RXAV3 0x80
244184610Salfred
245184610Salfred#define	USS820_DSAV1 0x1e		/* Data set available high */
246184610Salfred#define	USS820_DSAV1_TXAV4 0x01
247184610Salfred#define	USS820_DSAV1_RXAV4 0x02
248184610Salfred#define	USS820_DSAV1_TXAV5 0x04
249184610Salfred#define	USS820_DSAV1_RXAV5 0x08
250184610Salfred#define	USS820_DSAV1_TXAV6 0x10
251184610Salfred#define	USS820_DSAV1_RXAV6 0x20
252184610Salfred#define	USS820_DSAV1_TXAV7 0x40
253184610Salfred#define	USS820_DSAV1_RXAV7 0x80
254184610Salfred
255184610Salfred#define	USS820_UNK1 0x1f		/* Unknown */
256184610Salfred#define	USS820_UNK1_UNKNOWN 0xFF
257184610Salfred
258184610Salfred#define	USS820_READ_1(sc, reg) \
259192448Sthompsa  bus_space_read_1((sc)->sc_io_tag, (sc)->sc_io_hdl, reg)
260184610Salfred
261184610Salfred#define	USS820_WRITE_1(sc, reg, data)	\
262192448Sthompsa  bus_space_write_1((sc)->sc_io_tag, (sc)->sc_io_hdl, reg, data)
263184610Salfred
264184610Salfredstruct uss820dci_td;
265184610Salfred
266184610Salfredtypedef uint8_t (uss820dci_cmd_t)(struct uss820dci_td *td);
267184610Salfred
268184610Salfredstruct uss820dci_td {
269184610Salfred	bus_space_tag_t io_tag;
270184610Salfred	bus_space_handle_t io_hdl;
271184610Salfred	struct uss820dci_td *obj_next;
272184610Salfred	uss820dci_cmd_t *func;
273192984Sthompsa	struct usb_page_cache *pc;
274184610Salfred	uint32_t offset;
275184610Salfred	uint32_t remainder;
276184610Salfred	uint16_t max_packet_size;
277184610Salfred	uint8_t	ep_index;
278184610Salfred	uint8_t	error:1;
279184610Salfred	uint8_t	alt_next:1;
280184610Salfred	uint8_t	short_pkt:1;
281184610Salfred	uint8_t	support_multi_buffer:1;
282184610Salfred	uint8_t	did_stall:1;
283192552Sthompsa	uint8_t	did_enable:1;
284184610Salfred};
285184610Salfred
286184610Salfredstruct uss820_std_temp {
287184610Salfred	uss820dci_cmd_t *func;
288192984Sthompsa	struct usb_page_cache *pc;
289184610Salfred	struct uss820dci_td *td;
290184610Salfred	struct uss820dci_td *td_next;
291184610Salfred	uint32_t len;
292184610Salfred	uint32_t offset;
293184610Salfred	uint16_t max_frame_size;
294184610Salfred	uint8_t	short_pkt;
295184610Salfred	/*
296184610Salfred         * short_pkt = 0: transfer should be short terminated
297184610Salfred         * short_pkt = 1: transfer should not be short terminated
298184610Salfred         */
299184610Salfred	uint8_t	setup_alt_next;
300192552Sthompsa	uint8_t did_stall;
301184610Salfred};
302184610Salfred
303184610Salfredstruct uss820dci_config_desc {
304192984Sthompsa	struct usb_config_descriptor confd;
305192984Sthompsa	struct usb_interface_descriptor ifcd;
306192984Sthompsa	struct usb_endpoint_descriptor endpd;
307184610Salfred} __packed;
308184610Salfred
309184610Salfredunion uss820_hub_temp {
310184610Salfred	uWord	wValue;
311192984Sthompsa	struct usb_port_status ps;
312184610Salfred};
313184610Salfred
314184610Salfredstruct uss820_flags {
315184610Salfred	uint8_t	change_connect:1;
316184610Salfred	uint8_t	change_suspend:1;
317184610Salfred	uint8_t	status_suspend:1;	/* set if suspended */
318184610Salfred	uint8_t	status_vbus:1;		/* set if present */
319184610Salfred	uint8_t	status_bus_reset:1;	/* set if reset complete */
320184610Salfred	uint8_t	clocks_off:1;
321184610Salfred	uint8_t	port_powered:1;
322184610Salfred	uint8_t	port_enabled:1;
323184610Salfred	uint8_t	d_pulled_up:1;
324184610Salfred	uint8_t	mcsr_feat:1;
325184610Salfred};
326184610Salfred
327184610Salfredstruct uss820dci_softc {
328192984Sthompsa	struct usb_bus sc_bus;
329184610Salfred	union uss820_hub_temp sc_hub_temp;
330184610Salfred
331192984Sthompsa	struct usb_device *sc_devices[USS820_MAX_DEVICES];
332184610Salfred	struct resource *sc_io_res;
333184610Salfred	struct resource *sc_irq_res;
334184610Salfred	void   *sc_intr_hdl;
335184610Salfred	bus_size_t sc_io_size;
336184610Salfred	bus_space_tag_t sc_io_tag;
337184610Salfred	bus_space_handle_t sc_io_hdl;
338184610Salfred
339184610Salfred	uint8_t	sc_rt_addr;		/* root HUB address */
340184610Salfred	uint8_t	sc_dv_addr;		/* device address */
341184610Salfred	uint8_t	sc_conf;		/* root HUB config */
342184610Salfred
343184610Salfred	uint8_t	sc_hub_idata[1];
344184610Salfred
345184610Salfred	struct uss820_flags sc_flags;
346184610Salfred};
347184610Salfred
348184610Salfred/* prototypes */
349184610Salfred
350193045Sthompsausb_error_t uss820dci_init(struct uss820dci_softc *sc);
351184610Salfredvoid	uss820dci_uninit(struct uss820dci_softc *sc);
352184610Salfredvoid	uss820dci_interrupt(struct uss820dci_softc *sc);
353184610Salfred
354184610Salfred#endif					/* _USS820_DCI_H_ */
355