1 /* 2 * Copyright (C) 2011 Jana Rapava <fermata7@gmail.com> 3 * Copyright (C) 2011 CompuLab, Ltd. <www.compulab.co.il> 4 * 5 * Authors: Jana Rapava <fermata7@gmail.com> 6 * Igor Grinberg <grinberg@compulab.co.il> 7 * 8 * Based on: 9 * linux/drivers/usb/otg/ulpi.c 10 * Generic ULPI USB transceiver support 11 * 12 * Original Copyright follow: 13 * Copyright (C) 2009 Daniel Mack <daniel@caiaq.de> 14 * 15 * Based on sources from 16 * 17 * Sascha Hauer <s.hauer@pengutronix.de> 18 * Freescale Semiconductors 19 * 20 * This program is free software; you can redistribute it and/or modify 21 * it under the terms of the GNU General Public License as published by 22 * the Free Software Foundation; either version 2 of the License, or 23 * (at your option) any later version. 24 * 25 * This program is distributed in the hope that it will be useful, 26 * but WITHOUT ANY WARRANTY; without even the implied warranty of 27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 28 * GNU General Public License for more details. 29 */ 30 31 #include <common.h> 32 #include <exports.h> 33 #include <usb/ulpi.h> 34 35 #define ULPI_ID_REGS_COUNT 4 36 #define ULPI_TEST_VALUE 0x55 /* 0x55 == 0b01010101 */ 37 38 static struct ulpi_regs *ulpi = (struct ulpi_regs *)0; 39 40 static int ulpi_integrity_check(struct ulpi_viewport *ulpi_vp) 41 { 42 u32 val, tval = ULPI_TEST_VALUE; 43 int err, i; 44 45 /* Use the 'special' test value to check all bits */ 46 for (i = 0; i < 2; i++, tval <<= 1) { 47 err = ulpi_write(ulpi_vp, &ulpi->scratch, tval); 48 if (err) 49 return err; 50 51 val = ulpi_read(ulpi_vp, &ulpi->scratch); 52 if (val != tval) { 53 printf("ULPI integrity check failed\n"); 54 return val; 55 } 56 } 57 58 return 0; 59 } 60 61 int ulpi_init(struct ulpi_viewport *ulpi_vp) 62 { 63 u32 val, id = 0; 64 u8 *reg = &ulpi->product_id_high; 65 int i; 66 67 /* Assemble ID from four ULPI ID registers (8 bits each). */ 68 for (i = 0; i < ULPI_ID_REGS_COUNT; i++) { 69 val = ulpi_read(ulpi_vp, reg - i); 70 if (val == ULPI_ERROR) 71 return val; 72 73 id = (id << 8) | val; 74 } 75 76 /* Split ID into vendor and product ID. */ 77 debug("ULPI transceiver ID 0x%04x:0x%04x\n", id >> 16, id & 0xffff); 78 79 return ulpi_integrity_check(ulpi_vp); 80 } 81 82 int ulpi_select_transceiver(struct ulpi_viewport *ulpi_vp, unsigned speed) 83 { 84 u32 tspeed = ULPI_FC_FULL_SPEED; 85 u32 val; 86 87 switch (speed) { 88 case ULPI_FC_HIGH_SPEED: 89 case ULPI_FC_FULL_SPEED: 90 case ULPI_FC_LOW_SPEED: 91 case ULPI_FC_FS4LS: 92 tspeed = speed; 93 break; 94 default: 95 printf("ULPI: %s: wrong transceiver speed specified: %u, " 96 "falling back to full speed\n", __func__, speed); 97 } 98 99 val = ulpi_read(ulpi_vp, &ulpi->function_ctrl); 100 if (val == ULPI_ERROR) 101 return val; 102 103 /* clear the previous speed setting */ 104 val = (val & ~ULPI_FC_XCVRSEL_MASK) | tspeed; 105 106 return ulpi_write(ulpi_vp, &ulpi->function_ctrl, val); 107 } 108 109 int ulpi_set_vbus(struct ulpi_viewport *ulpi_vp, int on, int ext_power) 110 { 111 u32 flags = ULPI_OTG_DRVVBUS; 112 u8 *reg = on ? &ulpi->otg_ctrl_set : &ulpi->otg_ctrl_clear; 113 114 if (ext_power) 115 flags |= ULPI_OTG_DRVVBUS_EXT; 116 117 return ulpi_write(ulpi_vp, reg, flags); 118 } 119 120 int ulpi_set_vbus_indicator(struct ulpi_viewport *ulpi_vp, int external, 121 int passthu, int complement) 122 { 123 u32 flags, val; 124 u8 *reg; 125 126 reg = external ? &ulpi->otg_ctrl_set : &ulpi->otg_ctrl_clear; 127 val = ulpi_write(ulpi_vp, reg, ULPI_OTG_EXTVBUSIND); 128 if (val) 129 return val; 130 131 flags = passthu ? ULPI_IFACE_PASSTHRU : 0; 132 flags |= complement ? ULPI_IFACE_EXTVBUS_COMPLEMENT : 0; 133 134 val = ulpi_read(ulpi_vp, &ulpi->iface_ctrl); 135 if (val == ULPI_ERROR) 136 return val; 137 138 val = val & ~(ULPI_IFACE_PASSTHRU & ULPI_IFACE_EXTVBUS_COMPLEMENT); 139 val |= flags; 140 val = ulpi_write(ulpi_vp, &ulpi->iface_ctrl, val); 141 if (val) 142 return val; 143 144 return 0; 145 } 146 147 int ulpi_set_pd(struct ulpi_viewport *ulpi_vp, int enable) 148 { 149 u32 val = ULPI_OTG_DP_PULLDOWN | ULPI_OTG_DM_PULLDOWN; 150 u8 *reg = enable ? &ulpi->otg_ctrl_set : &ulpi->otg_ctrl_clear; 151 152 return ulpi_write(ulpi_vp, reg, val); 153 } 154 155 int ulpi_opmode_sel(struct ulpi_viewport *ulpi_vp, unsigned opmode) 156 { 157 u32 topmode = ULPI_FC_OPMODE_NORMAL; 158 u32 val; 159 160 switch (opmode) { 161 case ULPI_FC_OPMODE_NORMAL: 162 case ULPI_FC_OPMODE_NONDRIVING: 163 case ULPI_FC_OPMODE_DISABLE_NRZI: 164 case ULPI_FC_OPMODE_NOSYNC_NOEOP: 165 topmode = opmode; 166 break; 167 default: 168 printf("ULPI: %s: wrong OpMode specified: %u, " 169 "falling back to OpMode Normal\n", __func__, opmode); 170 } 171 172 val = ulpi_read(ulpi_vp, &ulpi->function_ctrl); 173 if (val == ULPI_ERROR) 174 return val; 175 176 /* clear the previous opmode setting */ 177 val = (val & ~ULPI_FC_OPMODE_MASK) | topmode; 178 179 return ulpi_write(ulpi_vp, &ulpi->function_ctrl, val); 180 } 181 182 int ulpi_serial_mode_enable(struct ulpi_viewport *ulpi_vp, unsigned smode) 183 { 184 switch (smode) { 185 case ULPI_IFACE_6_PIN_SERIAL_MODE: 186 case ULPI_IFACE_3_PIN_SERIAL_MODE: 187 break; 188 default: 189 printf("ULPI: %s: unrecognized Serial Mode specified: %u\n", 190 __func__, smode); 191 return ULPI_ERROR; 192 } 193 194 return ulpi_write(ulpi_vp, &ulpi->iface_ctrl_set, smode); 195 } 196 197 int ulpi_suspend(struct ulpi_viewport *ulpi_vp) 198 { 199 int err; 200 201 err = ulpi_write(ulpi_vp, &ulpi->function_ctrl_clear, 202 ULPI_FC_SUSPENDM); 203 if (err) 204 printf("ULPI: %s: failed writing the suspend bit\n", __func__); 205 206 return err; 207 } 208 209 /* 210 * Wait for ULPI PHY reset to complete. 211 * Actual wait for reset must be done in a view port specific way, 212 * because it involves checking the DIR line. 213 */ 214 static int __ulpi_reset_wait(struct ulpi_viewport *ulpi_vp) 215 { 216 u32 val; 217 int timeout = CONFIG_USB_ULPI_TIMEOUT; 218 219 /* Wait for the RESET bit to become zero */ 220 while (--timeout) { 221 /* 222 * This function is generic and suppose to work 223 * with any viewport, so we cheat here and don't check 224 * for the error of ulpi_read(), if there is one, then 225 * there will be a timeout. 226 */ 227 val = ulpi_read(ulpi_vp, &ulpi->function_ctrl); 228 if (!(val & ULPI_FC_RESET)) 229 return 0; 230 231 udelay(1); 232 } 233 234 printf("ULPI: %s: reset timed out\n", __func__); 235 236 return ULPI_ERROR; 237 } 238 int ulpi_reset_wait(struct ulpi_viewport *ulpi_vp) 239 __attribute__((weak, alias("__ulpi_reset_wait"))); 240 241 int ulpi_reset(struct ulpi_viewport *ulpi_vp) 242 { 243 int err; 244 245 err = ulpi_write(ulpi_vp, 246 &ulpi->function_ctrl_set, ULPI_FC_RESET); 247 if (err) { 248 printf("ULPI: %s: failed writing reset bit\n", __func__); 249 return err; 250 } 251 252 return ulpi_reset_wait(ulpi_vp); 253 } 254