22 #include "pedigree/kernel/Log.h" 23 #include "pedigree/kernel/process/Semaphore.h" 24 #include "pedigree/kernel/processor/PhysicalMemoryManager.h" 25 #include "pedigree/kernel/processor/Processor.h" 26 #include "pedigree/kernel/processor/VirtualAddressSpace.h" 27 #include "pedigree/kernel/time/Time.h" 29 I2C I2C::m_Instance[3];
31 void I2C::initialise(uintptr_t baseAddr)
55 volatile uint16_t *base =
56 reinterpret_cast<volatile uint16_t *
>(m_MmioBase.
virtualAddress());
58 "I2C Module at " << baseAddr <<
" (" 59 << reinterpret_cast<uintptr_t>(
61 <<
"): Revision " <<
Dec 62 << ((base[I2C_REV] >> 4) & 0xF) <<
"." 63 << (base[I2C_REV] & 0xF) <<
Hex <<
".");
67 base[I2C_CON] = 0x8000;
68 while (!(base[I2C_SYSS] & 1))
93 base[I2C_STAT] = 0xFFFF;
97 bool I2C::write(uint8_t addr, uint8_t reg, uint8_t data)
99 uint8_t buffer[] = {reg, data};
100 return transmit(addr, reinterpret_cast<uintptr_t>(buffer), 2);
103 uint8_t I2C::read(uint8_t addr, uint8_t reg)
105 uint8_t buffer[] = {reg};
106 if (!transmit(addr, reinterpret_cast<uintptr_t>(buffer), 1))
108 if (!receive(addr, reinterpret_cast<uintptr_t>(buffer), 1))
113 bool I2C::transmit(uint8_t addr, uintptr_t buffer,
size_t len)
115 volatile uint16_t *base =
116 reinterpret_cast<volatile uint16_t *
>(m_MmioBase.
virtualAddress());
117 uint8_t *buf =
reinterpret_cast<uint8_t *
>(buffer);
124 base[I2C_CON] = 0x8603;
130 Time::delay(1 * Time::Multiplier::MILLISECOND);
131 uint16_t status = base[I2C_STAT];
135 NOTICE(
"I2C: Arbitration lost");
139 else if (status & 0x2)
146 else if (status & 0x4)
151 else if (status & 0x10)
154 *
reinterpret_cast<volatile uint8_t *
>(&base[I2C_DATA]) = *buf++;
157 Time::delay(50 * Time::Multiplier::MILLISECOND);
158 base[I2C_STAT] = status;
161 base[I2C_STAT] = 0xFFFF;
167 bool I2C::receive(uint8_t addr, uintptr_t buffer,
size_t maxlen)
169 volatile uint16_t *base =
170 reinterpret_cast<volatile uint16_t *
>(m_MmioBase.
virtualAddress());
171 uint8_t *buf =
reinterpret_cast<uint8_t *
>(buffer);
177 base[I2C_CNT] = maxlen;
178 base[I2C_CON] = 0x8403;
184 Time::delay(1 * Time::Multiplier::MILLISECOND);
185 uint16_t status = base[I2C_STAT];
189 NOTICE(
"I2C: Arbitration lost");
193 else if (status & 0x2)
200 else if (status & 0x4)
208 *buf++ = *
reinterpret_cast<volatile uint8_t *
>(&base[I2C_DATA]);
211 Time::delay(50 * Time::Multiplier::MILLISECOND);
212 base[I2C_STAT] = status;
215 base[I2C_STAT] = 0xFFFF;
221 void I2C::waitForBus()
223 volatile uint16_t *base =
224 reinterpret_cast<volatile uint16_t *
>(m_MmioBase.
virtualAddress());
227 base[I2C_STAT] = 0xFFFF;
229 while ((status = base[I2C_STAT]) & 0x1000)
231 base[I2C_STAT] = status;
232 Time::delay(50 * Time::Multiplier::MILLISECOND);
234 base[I2C_STAT] = 0xFFFF;
static PhysicalMemoryManager & instance()
static const size_t continuous
void SetFuncClockCORE(size_t n, size_t clock, bool enabled)
static const size_t Write
static const size_t KernelMode
void SetIfaceClockCORE(size_t n, size_t clock, bool enabled)
void * virtualAddress() const