21 #include "pedigree/kernel/Log.h" 22 #include "pedigree/kernel/process/Semaphore.h" 23 #include "pedigree/kernel/processor/PhysicalMemoryManager.h" 24 #include "pedigree/kernel/processor/VirtualAddressSpace.h" 25 #include "pedigree/kernel/time/Time.h" 34 bool usbWriteTwl4030(uint8_t addr, uint8_t data)
36 return I2C::instance(0).write(0x48, addr, data);
39 uint8_t usbReadTwl4030(uint8_t addr)
41 return I2C::instance(0).read(0x48, addr);
47 bool usbSetBits(uint8_t reg, uint8_t bits)
49 return usbWriteTwl4030(reg + 1, bits);
53 bool usbClearBits(uint8_t reg, uint8_t bits)
55 return usbWriteTwl4030(reg + 2, bits);
59 void enablePhyAccess(
bool which)
61 uint8_t clock = usbReadTwl4030(0xFE);
67 usbWriteTwl4030(0xFE, clock);
68 while (!(usbReadTwl4030(0xFF) & 1))
69 Time::delay(10 * Time::Multiplier::MILLISECOND);
74 usbWriteTwl4030(0xFE, clock);
88 ERROR(
"USB UHH_CONFIG: Couldn't get a memory region!");
97 ERROR(
"USB TLL: Couldn't get a memory region!");
106 ERROR(
"USB Power Control: Couldn't get a memory region!");
110 NOTICE(
"Initialising USB Controller...");
115 uint8_t buffer[2] = {0xEE, 0x33};
116 I2C::instance(0).transmit(0x4A, reinterpret_cast<uintptr_t>(buffer), 2);
120 I2C::instance(0).write(0x4b, 0x44, 0xC0);
121 I2C::instance(0).write(0x4b, 0x44, 0x0C);
124 I2C::instance(0).write(0x4b, VUSB_DEDICATED2, 0);
127 I2C::instance(0).write(0x4b, VUSB_DEDICATED1, 0x14);
130 I2C::instance(0).write(0x4b, VUSB3V1_DEV_GRP, 0x20);
131 I2C::instance(0).write(0x4b, VUSB3V1_TYPE, 0);
134 I2C::instance(0).write(0x4b, VUSB1V5_DEV_GRP, 0x20);
135 I2C::instance(0).write(0x4b, VUSB1V5_TYPE, 0);
138 I2C::instance(0).write(0x4b, VUSB1V8_DEV_GRP, 0x20);
139 I2C::instance(0).write(0x4b, VUSB1V8_TYPE, 0);
142 I2C::instance(0).write(0x4b, 0x44, 0);
145 uint8_t power = usbReadTwl4030(0xFD);
147 usbWriteTwl4030(0xFD, power);
148 usbWriteTwl4030(0xFE, usbReadTwl4030(0xFE) | (1 << 2) | (1 << 1));
151 enablePhyAccess(
true);
152 usbClearBits(InterfaceControl, 1 << 2);
157 usbSetBits(0xAC, 1 << 5);
158 usbSetBits(FunctionControl, 4);
159 usbClearBits(FunctionControl, 0x1B);
160 enablePhyAccess(
false);
173 volatile uint32_t *pctl_base =
174 reinterpret_cast<volatile uint32_t *
>(m_MemRegionPCtl.
virtualAddress());
175 pctl_base[(0x400) / 4] = 3;
176 pctl_base[(0x400 + 0x10) / 4] = 1;
177 pctl_base[(0x400 + 0x30) / 4] =
180 volatile uint32_t *tll_base =
181 reinterpret_cast<volatile uint32_t *
>(m_MemRegionTLL.
virtualAddress());
182 volatile uint8_t *ulpi_base =
reinterpret_cast<volatile uint8_t *
>(
183 reinterpret_cast<uintptr_t
>(m_MemRegionTLL.
virtualAddress()) + 0x800);
186 Gpio::instance().enableoutput(147);
187 Gpio::instance().clearpin(147);
188 Time::delay(10 * Time::Multiplier::MILLISECOND);
199 uint32_t rev = tll_base[0];
201 "USB TLL: Revision " <<
Dec << ((rev >> 4) & 0xF) <<
"." << (rev & 0xF)
203 tll_base[0x10 / 4] = 2;
204 while (!(tll_base[0x14 / 4]))
205 Time::delay(5 * Time::Multiplier::MILLISECOND);
208 tll_base[0x10 / 4] = (1 << 2) | (1 << 3) | (1 << 8);
210 volatile uint32_t *uhh_base =
211 reinterpret_cast<volatile uint32_t *
>(m_MemRegionUHH.
virtualAddress());
212 uint32_t uhh_version = uhh_base[0];
214 "USB UHH: Revision " <<
Dec << ((uhh_version >> 4) & 0xF) <<
"." 215 << (uhh_version & 0xF) <<
Hex <<
".");
218 uhh_base[0x10 / 4] = 2;
219 while (!(uhh_base[0x14 / 4]))
220 Time::delay(5 * Time::Multiplier::MILLISECOND);
223 uint32_t cfg = (1 << 2) | (1 << 3) | (1 << 8) | (1 << 12);
224 uhh_base[0x10 / 4] = cfg;
227 cfg = (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5) | (1 << 8) | (1 << 9) |
229 uhh_base[0x40 / 4] = cfg;
232 Time::delay(10 * Time::Multiplier::MILLISECOND);
233 Gpio::instance().drivepin(147);
static UsbUlpi m_Instance
static PhysicalMemoryManager & instance()
void WaitPllIdleStatus(size_t n, size_t clock, bool waitForOn)
void SetClockPLL(size_t n, size_t value)
static const size_t continuous
void SelectClockPLL(size_t n, size_t value)
void SetFuncClockCORE(size_t n, size_t clock, bool enabled)
static const size_t force
static const size_t Write
void SelectClockCORE(size_t clock, Clock which)
static const size_t KernelMode
void WaitCoreIdleStatus(size_t n, size_t clock, bool waitForOn)
void SetIfaceClockCORE(size_t n, size_t clock, bool enabled)
void * virtualAddress() const