1265908Shselasky/* $FreeBSD$ */ 2265908Shselasky/*- 3266051Shselasky * Copyright (c) 2014 Hans Petter Selasky <hselasky@FreeBSD.org> 4265908Shselasky * All rights reserved. 5265908Shselasky * 6265908Shselasky * This software was developed by SRI International and the University of 7265908Shselasky * Cambridge Computer Laboratory under DARPA/AFRL contract (FA8750-10-C-0237) 8265908Shselasky * ("CTSRD"), as part of the DARPA CRASH research programme. 9265908Shselasky * 10265908Shselasky * Redistribution and use in source and binary forms, with or without 11265908Shselasky * modification, are permitted provided that the following conditions 12265908Shselasky * are met: 13265908Shselasky * 1. Redistributions of source code must retain the above copyright 14265908Shselasky * notice, this list of conditions and the following disclaimer. 15265908Shselasky * 2. Redistributions in binary form must reproduce the above copyright 16265908Shselasky * notice, this list of conditions and the following disclaimer in the 17265908Shselasky * documentation and/or other materials provided with the distribution. 18265908Shselasky * 19265908Shselasky * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 20265908Shselasky * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21265908Shselasky * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22265908Shselasky * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 23265908Shselasky * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24265908Shselasky * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25265908Shselasky * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26265908Shselasky * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27265908Shselasky * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28265908Shselasky * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29265908Shselasky * SUCH DAMAGE. 30265908Shselasky */ 31265908Shselasky 32266244Shselasky#ifndef _SAF1761_OTG_H_ 33266244Shselasky#define _SAF1761_OTG_H_ 34265908Shselasky 35266741Shselasky#define SOTG_MAX_DEVICES MIN(USB_MAX_DEVICES, 32) 36266051Shselasky#define SOTG_FS_MAX_PACKET_SIZE 64 37266051Shselasky#define SOTG_HS_MAX_PACKET_SIZE 512 38266241Shselasky#define SOTG_NUM_PORTS 2 /* one Device and one Host port */ 39266241Shselasky#define SOTG_HOST_PORT_NUM 1 40266241Shselasky#define SOTG_DEVICE_PORT_NUM 2 41266241Shselasky#define SOTG_HOST_CHANNEL_MAX (3 * 32) 42265908Shselasky 43266741Shselasky/* Macros used for reading and writing little endian registers */ 44266051Shselasky 45266741Shselasky#define SAF1761_READ_LE_4(sc, reg) ({ uint32_t _temp; \ 46266644Shselasky _temp = bus_space_read_4((sc)->sc_io_tag, (sc)->sc_io_hdl, (reg)); \ 47266644Shselasky le32toh(_temp); }) 48266644Shselasky 49266741Shselasky#define SAF1761_WRITE_LE_4(sc, reg, data) do { \ 50266644Shselasky uint32_t _temp = (data); \ 51266644Shselasky bus_space_write_4((sc)->sc_io_tag, (sc)->sc_io_hdl, (reg), htole32(_temp)); \ 52266644Shselasky} while (0) 53266051Shselasky 54266741Shselasky/* 90ns delay macro */ 55266741Shselasky 56266741Shselasky#define SAF1761_90NS_DELAY(sc) do { \ 57266741Shselasky (void) SAF1761_READ_LE_4(sc, SOTG_VEND_PROD_ID); \ 58266741Shselasky (void) SAF1761_READ_LE_4(sc, SOTG_VEND_PROD_ID); \ 59266741Shselasky (void) SAF1761_READ_LE_4(sc, SOTG_VEND_PROD_ID); \ 60266741Shselasky (void) SAF1761_READ_LE_4(sc, SOTG_VEND_PROD_ID); \ 61266741Shselasky} while (0) 62266741Shselasky 63266244Shselaskystruct saf1761_otg_softc; 64266244Shselaskystruct saf1761_otg_td; 65266051Shselasky 66266244Shselaskytypedef uint8_t (saf1761_otg_cmd_t)(struct saf1761_otg_softc *, struct saf1761_otg_td *td); 67266051Shselasky 68266244Shselaskystruct saf1761_otg_td { 69266244Shselasky struct saf1761_otg_td *obj_next; 70266244Shselasky saf1761_otg_cmd_t *func; 71266051Shselasky struct usb_page_cache *pc; 72266051Shselasky uint32_t offset; 73266051Shselasky uint32_t remainder; 74266241Shselasky uint32_t dw1_value; 75266051Shselasky uint16_t max_packet_size; 76266051Shselasky uint8_t ep_index; 77266241Shselasky uint8_t ep_type; 78266241Shselasky uint8_t channel; 79266508Shselasky uint8_t uframe; 80266508Shselasky uint8_t interval; 81266241Shselasky uint8_t error_any:1; 82266241Shselasky uint8_t error_stall:1; 83266051Shselasky uint8_t alt_next:1; 84266051Shselasky uint8_t short_pkt:1; 85266051Shselasky uint8_t did_stall:1; 86266241Shselasky uint8_t toggle:1; 87266241Shselasky uint8_t set_toggle:1; 88266051Shselasky}; 89266051Shselasky 90266244Shselaskystruct saf1761_otg_std_temp { 91266244Shselasky saf1761_otg_cmd_t *func; 92266051Shselasky struct usb_page_cache *pc; 93266244Shselasky struct saf1761_otg_td *td; 94266244Shselasky struct saf1761_otg_td *td_next; 95266051Shselasky uint32_t len; 96266051Shselasky uint32_t offset; 97266051Shselasky uint16_t max_frame_size; 98266051Shselasky uint8_t short_pkt; 99266051Shselasky /* 100266051Shselasky * short_pkt = 0: transfer should be short terminated 101266051Shselasky * short_pkt = 1: transfer should not be short terminated 102266051Shselasky */ 103266051Shselasky uint8_t setup_alt_next; 104266051Shselasky uint8_t did_stall; 105266051Shselasky}; 106266051Shselasky 107266244Shselaskystruct saf1761_otg_config_desc { 108266051Shselasky struct usb_config_descriptor confd; 109266051Shselasky struct usb_interface_descriptor ifcd; 110266051Shselasky struct usb_endpoint_descriptor endpd; 111266051Shselasky} __packed; 112266051Shselasky 113266244Shselaskyunion saf1761_otg_hub_temp { 114266051Shselasky uWord wValue; 115266051Shselasky struct usb_port_status ps; 116266051Shselasky}; 117266051Shselasky 118266244Shselaskystruct saf1761_otg_flags { 119266051Shselasky uint8_t change_connect:1; 120266051Shselasky uint8_t change_suspend:1; 121266051Shselasky uint8_t status_suspend:1; /* set if suspended */ 122266051Shselasky uint8_t status_vbus:1; /* set if present */ 123266051Shselasky uint8_t status_bus_reset:1; /* set if reset complete */ 124266051Shselasky uint8_t clocks_off:1; 125266051Shselasky uint8_t port_powered:1; 126266051Shselasky uint8_t port_enabled:1; 127266051Shselasky uint8_t d_pulled_up:1; 128266051Shselasky}; 129266051Shselasky 130266244Shselaskystruct saf1761_otg_softc { 131266051Shselasky struct usb_bus sc_bus; 132266244Shselasky union saf1761_otg_hub_temp sc_hub_temp; 133266051Shselasky 134266051Shselasky struct usb_device *sc_devices[SOTG_MAX_DEVICES]; 135266051Shselasky struct resource *sc_io_res; 136266051Shselasky struct resource *sc_irq_res; 137266051Shselasky void *sc_intr_hdl; 138266051Shselasky bus_size_t sc_io_size; 139266051Shselasky bus_space_tag_t sc_io_tag; 140266051Shselasky bus_space_handle_t sc_io_hdl; 141266051Shselasky 142275467Shselasky uint32_t sc_host_async_busy_map[2]; 143266241Shselasky uint32_t sc_host_async_map; 144266831Shselasky uint32_t sc_host_async_suspend_map; 145275467Shselasky uint32_t sc_host_intr_busy_map[2]; 146266241Shselasky uint32_t sc_host_intr_map; 147266831Shselasky uint32_t sc_host_intr_suspend_map; 148275467Shselasky uint32_t sc_host_isoc_busy_map[2]; 149266241Shselasky uint32_t sc_host_isoc_map; 150266831Shselasky uint32_t sc_host_isoc_suspend_map; 151266051Shselasky uint32_t sc_intr_enable; /* enabled interrupts */ 152266214Shselasky uint32_t sc_hw_mode; /* hardware mode */ 153266742Shselasky uint32_t sc_interrupt_cfg; /* interrupt configuration */ 154266831Shselasky uint32_t sc_xfer_complete; 155266051Shselasky 156266741Shselasky uint32_t sc_bounce_buffer[1024 / 4]; 157266741Shselasky 158266051Shselasky uint8_t sc_rt_addr; /* root HUB address */ 159266051Shselasky uint8_t sc_dv_addr; /* device address */ 160266051Shselasky uint8_t sc_conf; /* root HUB config */ 161266241Shselasky uint8_t sc_isreset; /* host mode */ 162266051Shselasky 163266051Shselasky uint8_t sc_hub_idata[1]; 164266051Shselasky 165266244Shselasky struct saf1761_otg_flags sc_flags; 166266051Shselasky}; 167266051Shselasky 168266051Shselasky/* prototypes */ 169266051Shselasky 170266244Shselaskyusb_error_t saf1761_otg_init(struct saf1761_otg_softc *sc); 171266244Shselaskyvoid saf1761_otg_uninit(struct saf1761_otg_softc *sc); 172266831Shselaskydriver_filter_t saf1761_otg_filter_interrupt; 173266831Shselaskydriver_intr_t saf1761_otg_interrupt; 174266051Shselasky 175266244Shselasky#endif /* _SAF1761_OTG_H_ */ 176