1/* 2 * Copyright 2017, Data61 3 * Commonwealth Scientific and Industrial Research Organisation (CSIRO) 4 * ABN 41 687 119 230. 5 * 6 * This software may be distributed and modified according to the terms of 7 * the BSD 2-Clause license. Note that NO WARRANTY is provided. 8 * See "LICENSE_BSD2.txt" for details. 9 * 10 * @TAG(DATA61_BSD) 11 */ 12 13/** 14 * @brief Microchip USB3503 USB 2.0 hub controller 15 * @see http://www.microchip.com/wwwproducts/en/USB3503 16 */ 17 18#include <usb/drivers/usb3503_hub.h> 19#include "../../../services.h" 20 21#define REG_VIDL 0x00 22#define REG_VIDM 0x01 23#define REG_PIDL 0x02 24#define REG_PIDM 0x03 25#define REG_DIDL 0x04 26#define REG_DIDM 0x05 27#define REG_CFG1 0x06 28#define REG_CFG2 0x07 29#define REG_CFG3 0x08 30#define REG_NRD 0x09 31#define REG_PDS 0x0A 32#define REG_PDB 0x0B 33#define REG_MAXPS 0x0C 34#define REG_MAXPB 0x0D 35#define REG_HCMCS 0x0E 36#define REG_HCMCB 0x0F 37#define REG_PWRT 0x10 38#define REG_LANG_ID_H 0x11 39#define REG_LANG_ID_L 0x12 40#define REG_MFR_STR_LEN 0x13 41#define REG_PRD_STR_LEN 0x14 42#define REG_SER_STR_LEN 0x15 43#define REG_MFR_STR 0x16 44#define REG_PROD_STR 0x54 45#define REG_SER_STR 0x92 46#define REG_BC_EN 0xD0 47#define REG_PRTPWR 0xE5 48#define REG_OCS 0xE6 49#define REG_SP_ILOCK 0xE7 50#define REG_INT_STATUS 0xE8 51#define REG_INT_MASK 0xE9 52#define REG_CFGP 0xEE 53#define REG_VSNSUP3 0xF4 54#define REG_VSNS21 0xF5 55#define REG_BSTUP3 0xF6 56#define REG_BST21 0xF8 57#define REG_PRTSP 0xFA 58#define REG_PRTR12 0xFB 59#define REG_PRTR34 0xFC 60#define REG_STCD 0xFF 61 62static int read_reg(usb3503_t *hub, int addr) 63{ 64 int count; 65 char data; 66 count = i2c_kvslave_read(&hub->kvslave, addr, &data, 1); 67 if (count != 1) { 68 return -1; 69 } else { 70 return data; 71 } 72} 73 74static int write_reg(usb3503_t *hub, int addr, int data) 75{ 76 int count; 77 char cdata; 78 cdata = data; 79 count = i2c_kvslave_write(&hub->kvslave, addr, &cdata, 1); 80 if (count != 1) { 81 return -1; 82 } else { 83 return 0; 84 } 85} 86 87int 88usb3503_init(i2c_bus_t *i2c_bus, gpio_sys_t *gpio_sys, gpio_id_t o_nreset, 89 gpio_id_t o_hubconnect, gpio_id_t i_nint, usb3503_t *hub) 90{ 91 if (i2c_slave_init 92 (i2c_bus, USB3503_I2C_ADDR, I2C_SLAVE_ADDR_7BIT, I2C_SLAVE_SPEED_FAST, 0, &hub->i2c_slave)) { 93 ZF_LOGE("Failed to intialize slave handle."); 94 return -1; 95 } 96 if (i2c_kvslave_init(&hub->i2c_slave, BIG8, BIG8, &hub->kvslave)) { 97 ZF_LOGE("Failed to initialize lib KV-Slave instance handle."); 98 return -1; 99 } 100 if (gpio_new(gpio_sys, o_nreset, GPIO_DIR_OUT, &hub->o_nreset)) { 101 return -1; 102 } 103 if (gpio_new(gpio_sys, o_hubconnect, GPIO_DIR_OUT, &hub->o_hubconnect)) { 104 return -1; 105 } 106 if (gpio_new(gpio_sys, i_nint, GPIO_DIR_OUT, &hub->i_nint)) { 107 return -1; 108 } 109 /* Turn off the HUB */ 110 gpio_clr(&hub->o_nreset); 111 gpio_clr(&hub->o_hubconnect); 112 113 /* Select Primary or Secondary reference clock 114 * Primary reference clock freq (NINT high during init) 115 * SEL -> FREQ 116 * 00 -> 38.4 MHz 117 * 01 -> 26.0 MHz 118 * 10 -> 19.2 MHz 119 * 11 -> 12.0 MHz 120 * 121 * Secondary reference clock freq (NINT low during init) 122 * SEL -> FREQ 123 * 00 -> 24.0 MHz 124 * 01 -> 27.0 MHz 125 * 10 -> 25.0 MHz 126 * 11 -> 50.0 MHz 127 * 128 * Known platforms: 129 * Odroid - SEL = 00 130 */ 131 gpio_clr(&hub->i_nint); 132 /* TODO set clock frequency */ 133 134 /* Start the init process */ 135 gpio_set(&hub->o_nreset); 136 return 0; 137} 138 139void usb3503_reset(usb3503_t *hub) 140{ 141 write_reg(hub, REG_STCD, BIT(1)); 142} 143 144void usb3503_hard_reset(usb3503_t *hub) 145{ 146 gpio_clr(&hub->o_nreset); 147 ps_udelay(100); 148 gpio_set(&hub->o_nreset); 149} 150 151void usb3503_connect(usb3503_t *hub) 152{ 153 gpio_set(&hub->o_hubconnect); 154} 155 156void usb3503_disconnect(usb3503_t *hub) 157{ 158 gpio_clr(&hub->o_hubconnect); 159} 160 161void usb3503_handle_irq(usb3503_t *hub) 162{ 163 uint8_t status, mask; 164 status = read_reg(hub, REG_INT_STATUS); 165 mask = read_reg(hub, REG_INT_MASK); 166 printf("HUB IRQ status: 0x%02x/0x%02x\n", status, mask); 167} 168 169