Add IT5570E support with correct I2C channel

This commit is contained in:
Jeremy Soller 2020-01-10 08:07:18 -07:00
parent 26d01841d1
commit 89e3f3894f
No known key found for this signature in database
GPG Key ID: E988B49EE78A7FB1
21 changed files with 874 additions and 25 deletions

View File

@ -1,4 +1,4 @@
EC=it8587e
EC=it5570e
# Add keymaps to include
INCLUDE+=$(wildcard $(BOARD_DIR)/keymap/*.h)

BIN
src/ec/it5570e/.i2c.c.swp Normal file

Binary file not shown.

1
src/ec/it5570e/ec.mk Normal file
View File

@ -0,0 +1 @@
ARCH=8051

17
src/ec/it5570e/gpio.c Normal file
View File

@ -0,0 +1,17 @@
#include <ec/gpio.h>
bool gpio_get(struct Gpio * gpio) {
if (*(gpio->data) & gpio->value) {
return true;
} else {
return false;
}
}
void gpio_set(struct Gpio * gpio, bool value) {
if (value) {
*(gpio->data) |= gpio->value;
} else {
*(gpio->data) &= ~(gpio->value);
}
}

132
src/ec/it5570e/i2c.c Normal file
View File

@ -0,0 +1,132 @@
#include <stdbool.h>
#include <common/i2c.h>
#include <ec/smbus.h>
//TODO: find best value
#define I2C_TIMEOUT 10000
#define HOSTA HOSTAE
#define HOCTL HOCTLE
#define HOCTL2 HOCTL2E
#define HOBDB HOBDBE
#define TRASLA TRASLAE
void i2c_reset(bool kill) {
if (HOSTA & HOSTA_BUSY) {
// Set kill bit
if (kill) HOCTL |= (1 << 1);
// Wait for host to finish
while (HOSTA & HOSTA_BUSY) {}
}
// Clear status register
HOSTA = HOSTA;
// Clear current command
HOCTL = 0;
// Disable host interface
HOCTL2 = 0;
}
int i2c_start(uint8_t addr, bool read) {
// If we are already in a transaction
if (HOSTA & HOSTA_BYTE_DONE) {
// If we are switching direction
if ((TRASLA & 1) != read) {
// If we are switching to read mode
if (read) {
// Enable direction switch
HOCTL2 |= (1 << 3) | (1 << 2);
} else {
// Unsupported!
i2c_reset(true);
return -1;
}
}
} else {
i2c_reset(true);
// Enable host controller with i2c compatibility
HOCTL2 = (1 << 1) | 1;
// Set address
TRASLA = (addr << 1) | read;
}
return 0;
}
void i2c_stop(void) {
// Disable i2c compatibility
HOCTL2 &= ~(1 << 1);
// Clear status
HOSTA = HOSTA;
i2c_reset(false);
}
static int i2c_transaction(uint8_t * data, int length, bool read) {
int i;
for (i = 0; i < length; i++) {
if (read) {
// If last byte
if ((i + 1) == length) {
// Set last byte bit
HOCTL |= (1 << 5);
}
} else {
// Write byte
HOBDB = data[i];
}
// If we are already in a transaction
if (HOSTA & HOSTA_BYTE_DONE) {
// Clear status to process next byte
HOSTA = HOSTA;
} else {
// Start new transaction
HOCTL = (1 << 6) | (0b111 << 2);
}
// If we are waiting on direction switch
if (HOCTL2 & (1 << 2)) {
// Complete direction switch
HOCTL2 &= ~(1 << 2);
}
// Wait for byte done, timeout, or error
uint8_t status;
uint32_t timeout = I2C_TIMEOUT;
for(timeout = I2C_TIMEOUT; timeout > 0; timeout--) {
status = HOSTA;
// If error occured, kill transaction and return error
if (status & HOSTA_ERR) {
i2c_reset(true);
return -(int)(status);
} else
// If byte done, break
if (status & HOSTA_BYTE_DONE) {
break;
}
}
// If timeout occured, kill transaction and return error
if (timeout == 0) {
i2c_reset(true);
return -(0x1000 | (int)status);
}
if (read) {
// Read byte
data[i] = HOBDB;
}
}
return i;
}
int i2c_read(uint8_t * data, int length) {
return i2c_transaction(data, length, true);
}
int i2c_write(uint8_t * data, int length) {
return i2c_transaction(data, length, false);
}

View File

@ -0,0 +1,10 @@
#ifndef _EC_GCTRL_H
#define _EC_GCTRL_H
#include <stdint.h>
volatile uint8_t __xdata __at(0x2006) RSTS;
volatile uint8_t __xdata __at(0x200A) BADRSEL;
volatile uint8_t __xdata __at(0x200D) SPCTRL1;
#endif // _EC_GCTRL_H

View File

@ -0,0 +1,178 @@
#ifndef _EC_GPIO_H
#define _EC_GPIO_H
#include <stdbool.h>
#include <stdint.h>
struct Gpio {
volatile uint8_t __xdata * data;
volatile uint8_t __xdata * mirror;
volatile uint8_t __xdata * control;
uint8_t value;
};
#define GPIO(BLOCK, NUMBER) { \
.data = &GPDR ## BLOCK, \
.mirror = &GPDMR ## BLOCK, \
.control = &GPCR ## BLOCK ## NUMBER, \
.value = (1 << NUMBER), \
}
bool gpio_get(struct Gpio * gpio);
void gpio_set(struct Gpio * gpio, bool value);
volatile uint8_t __xdata __at(0x1600) GCR;
volatile uint8_t __xdata __at(0x16F0) GCR1;
volatile uint8_t __xdata __at(0x16F1) GCR2;
volatile uint8_t __xdata __at(0x16F2) GCR3;
volatile uint8_t __xdata __at(0x16F3) GCR4;
volatile uint8_t __xdata __at(0x16F4) GCR5;
volatile uint8_t __xdata __at(0x16F5) GCR6;
volatile uint8_t __xdata __at(0x16F6) GCR7;
volatile uint8_t __xdata __at(0x16F7) GCR8;
volatile uint8_t __xdata __at(0x16F8) GCR9;
volatile uint8_t __xdata __at(0x16F9) GCR10;
volatile uint8_t __xdata __at(0x16FA) GCR11;
volatile uint8_t __xdata __at(0x16FB) GCR12;
volatile uint8_t __xdata __at(0x16FC) GCR13;
volatile uint8_t __xdata __at(0x16FD) GCR14;
volatile uint8_t __xdata __at(0x16FE) GCR15;
volatile uint8_t __xdata __at(0x16E0) GCR16;
volatile uint8_t __xdata __at(0x16E1) GCR17;
volatile uint8_t __xdata __at(0x16E2) GCR18;
volatile uint8_t __xdata __at(0x1601) GPDRA;
volatile uint8_t __xdata __at(0x1602) GPDRB;
volatile uint8_t __xdata __at(0x1603) GPDRC;
volatile uint8_t __xdata __at(0x1604) GPDRD;
volatile uint8_t __xdata __at(0x1605) GPDRE;
volatile uint8_t __xdata __at(0x1606) GPDRF;
volatile uint8_t __xdata __at(0x1607) GPDRG;
volatile uint8_t __xdata __at(0x1608) GPDRH;
volatile uint8_t __xdata __at(0x1609) GPDRI;
volatile uint8_t __xdata __at(0x160A) GPDRJ;
volatile uint8_t __xdata __at(0x160D) GPDRM;
volatile uint8_t __xdata __at(0x1661) GPDMRA;
volatile uint8_t __xdata __at(0x1662) GPDMRB;
volatile uint8_t __xdata __at(0x1663) GPDMRC;
volatile uint8_t __xdata __at(0x1664) GPDMRD;
volatile uint8_t __xdata __at(0x1665) GPDMRE;
volatile uint8_t __xdata __at(0x1666) GPDMRF;
volatile uint8_t __xdata __at(0x1667) GPDMRG;
volatile uint8_t __xdata __at(0x1668) GPDMRH;
volatile uint8_t __xdata __at(0x1669) GPDMRI;
volatile uint8_t __xdata __at(0x166A) GPDMRJ;
volatile uint8_t __xdata __at(0x166D) GPDMRM;
volatile uint8_t __xdata __at(0x1671) GPOTA;
volatile uint8_t __xdata __at(0x1672) GPOTB;
volatile uint8_t __xdata __at(0x1673) GPOTC;
volatile uint8_t __xdata __at(0x1674) GPOTD;
volatile uint8_t __xdata __at(0x1675) GPOTE;
volatile uint8_t __xdata __at(0x1676) GPOTF;
volatile uint8_t __xdata __at(0x1677) GPOTG;
volatile uint8_t __xdata __at(0x1678) GPOTH;
volatile uint8_t __xdata __at(0x1679) GPOTI;
volatile uint8_t __xdata __at(0x167A) GPOTJ;
// GPOTM does not exist
volatile uint8_t __xdata __at(0x1610) GPCRA0;
volatile uint8_t __xdata __at(0x1611) GPCRA1;
volatile uint8_t __xdata __at(0x1612) GPCRA2;
volatile uint8_t __xdata __at(0x1613) GPCRA3;
volatile uint8_t __xdata __at(0x1614) GPCRA4;
volatile uint8_t __xdata __at(0x1615) GPCRA5;
volatile uint8_t __xdata __at(0x1616) GPCRA6;
volatile uint8_t __xdata __at(0x1617) GPCRA7;
volatile uint8_t __xdata __at(0x1618) GPCRB0;
volatile uint8_t __xdata __at(0x1619) GPCRB1;
volatile uint8_t __xdata __at(0x161A) GPCRB2;
volatile uint8_t __xdata __at(0x161B) GPCRB3;
volatile uint8_t __xdata __at(0x161C) GPCRB4;
volatile uint8_t __xdata __at(0x161D) GPCRB5;
volatile uint8_t __xdata __at(0x161E) GPCRB6;
volatile uint8_t __xdata __at(0x161F) GPCRB7;
volatile uint8_t __xdata __at(0x1620) GPCRC0;
volatile uint8_t __xdata __at(0x1621) GPCRC1;
volatile uint8_t __xdata __at(0x1622) GPCRC2;
volatile uint8_t __xdata __at(0x1623) GPCRC3;
volatile uint8_t __xdata __at(0x1624) GPCRC4;
volatile uint8_t __xdata __at(0x1625) GPCRC5;
volatile uint8_t __xdata __at(0x1626) GPCRC6;
volatile uint8_t __xdata __at(0x1627) GPCRC7;
volatile uint8_t __xdata __at(0x1628) GPCRD0;
volatile uint8_t __xdata __at(0x1629) GPCRD1;
volatile uint8_t __xdata __at(0x162A) GPCRD2;
volatile uint8_t __xdata __at(0x162B) GPCRD3;
volatile uint8_t __xdata __at(0x162C) GPCRD4;
volatile uint8_t __xdata __at(0x162D) GPCRD5;
volatile uint8_t __xdata __at(0x162E) GPCRD6;
volatile uint8_t __xdata __at(0x162F) GPCRD7;
volatile uint8_t __xdata __at(0x1630) GPCRE0;
volatile uint8_t __xdata __at(0x1631) GPCRE1;
volatile uint8_t __xdata __at(0x1632) GPCRE2;
volatile uint8_t __xdata __at(0x1633) GPCRE3;
volatile uint8_t __xdata __at(0x1634) GPCRE4;
volatile uint8_t __xdata __at(0x1635) GPCRE5;
volatile uint8_t __xdata __at(0x1636) GPCRE6;
volatile uint8_t __xdata __at(0x1637) GPCRE7;
volatile uint8_t __xdata __at(0x1638) GPCRF0;
volatile uint8_t __xdata __at(0x1639) GPCRF1;
volatile uint8_t __xdata __at(0x163A) GPCRF2;
volatile uint8_t __xdata __at(0x163B) GPCRF3;
volatile uint8_t __xdata __at(0x163C) GPCRF4;
volatile uint8_t __xdata __at(0x163D) GPCRF5;
volatile uint8_t __xdata __at(0x163E) GPCRF6;
volatile uint8_t __xdata __at(0x163F) GPCRF7;
volatile uint8_t __xdata __at(0x1640) GPCRG0;
volatile uint8_t __xdata __at(0x1641) GPCRG1;
volatile uint8_t __xdata __at(0x1642) GPCRG2;
volatile uint8_t __xdata __at(0x1643) GPCRG3;
volatile uint8_t __xdata __at(0x1644) GPCRG4;
volatile uint8_t __xdata __at(0x1645) GPCRG5;
volatile uint8_t __xdata __at(0x1646) GPCRG6;
volatile uint8_t __xdata __at(0x1647) GPCRG7;
volatile uint8_t __xdata __at(0x1648) GPCRH0;
volatile uint8_t __xdata __at(0x1649) GPCRH1;
volatile uint8_t __xdata __at(0x164A) GPCRH2;
volatile uint8_t __xdata __at(0x164B) GPCRH3;
volatile uint8_t __xdata __at(0x164C) GPCRH4;
volatile uint8_t __xdata __at(0x164D) GPCRH5;
volatile uint8_t __xdata __at(0x164E) GPCRH6;
volatile uint8_t __xdata __at(0x164F) GPCRH7;
volatile uint8_t __xdata __at(0x1650) GPCRI0;
volatile uint8_t __xdata __at(0x1651) GPCRI1;
volatile uint8_t __xdata __at(0x1652) GPCRI2;
volatile uint8_t __xdata __at(0x1653) GPCRI3;
volatile uint8_t __xdata __at(0x1654) GPCRI4;
volatile uint8_t __xdata __at(0x1655) GPCRI5;
volatile uint8_t __xdata __at(0x1656) GPCRI6;
volatile uint8_t __xdata __at(0x1657) GPCRI7;
volatile uint8_t __xdata __at(0x1658) GPCRJ0;
volatile uint8_t __xdata __at(0x1659) GPCRJ1;
volatile uint8_t __xdata __at(0x165A) GPCRJ2;
volatile uint8_t __xdata __at(0x165B) GPCRJ3;
volatile uint8_t __xdata __at(0x165C) GPCRJ4;
volatile uint8_t __xdata __at(0x165D) GPCRJ5;
volatile uint8_t __xdata __at(0x165E) GPCRJ6;
volatile uint8_t __xdata __at(0x165F) GPCRJ7;
volatile uint8_t __xdata __at(0x16A0) GPCRM0;
volatile uint8_t __xdata __at(0x16A1) GPCRM1;
volatile uint8_t __xdata __at(0x16A2) GPCRM2;
volatile uint8_t __xdata __at(0x16A3) GPCRM3;
volatile uint8_t __xdata __at(0x16A4) GPCRM4;
volatile uint8_t __xdata __at(0x16A5) GPCRM5;
volatile uint8_t __xdata __at(0x16A6) GPCRM6;
#endif // _EC_GPIO_H

View File

@ -0,0 +1,8 @@
#ifndef _EC_I2C_H
#define _EC_I2C_H
#include <common/i2c.h>
void i2c_reset(bool kill);
#endif // _EC_I2C_H

View File

@ -0,0 +1,42 @@
#ifndef _EC_KBC_H
#define _EC_KBC_H
#include <stdbool.h>
#include <stdint.h>
void kbc_init(void);
struct Kbc {
// Control register
volatile uint8_t * control;
// Interrupt control register
volatile uint8_t * irq;
// Status register
volatile uint8_t * status;
// Keyboard out register
volatile uint8_t * keyboard_out;
// Mouse out register
volatile uint8_t * mouse_out;
// Data in register
volatile uint8_t * data_in;
};
extern struct Kbc __code KBC;
#define KBC_STS_OBF (1 << 0)
#define KBC_STS_IBF (1 << 1)
#define KBC_STS_CMD (1 << 3)
uint8_t kbc_status(struct Kbc * kbc);
uint8_t kbc_read(struct Kbc * kbc);
bool kbc_keyboard(struct Kbc * kbc, uint8_t data, int timeout);
bool kbc_mouse(struct Kbc * kbc, uint8_t data, int timeout);
volatile uint8_t __xdata __at(0x1300) KBHICR;
volatile uint8_t __xdata __at(0x1302) KBIRQR;
volatile uint8_t __xdata __at(0x1304) KBHISR;
volatile uint8_t __xdata __at(0x1306) KBHIKDOR;
volatile uint8_t __xdata __at(0x1308) KBHIMDOR;
volatile uint8_t __xdata __at(0x130A) KBHIDIR;
#endif // _EC_KBC_H

View File

@ -0,0 +1,47 @@
#ifndef _EC_KBSCAN_H
#define _EC_KBSCAN_H
#include <stdint.h>
volatile uint8_t __xdata __at(0x1D00) KSOL;
volatile uint8_t __xdata __at(0x1D01) KSOH1;
volatile uint8_t __xdata __at(0x1D02) KSOCTRL;
volatile uint8_t __xdata __at(0x1D03) KSOH2;
volatile uint8_t __xdata __at(0x1D04) KSI;
volatile uint8_t __xdata __at(0x1D05) KSICTRLR;
volatile uint8_t __xdata __at(0x1D06) KSIGCTRL;
volatile uint8_t __xdata __at(0x1D07) KSIGOEN;
volatile uint8_t __xdata __at(0x1D08) KSIGDAT;
volatile uint8_t __xdata __at(0x1D09) KSIGDMRR;
volatile uint8_t __xdata __at(0x1D0A) KSOHGCTRL;
volatile uint8_t __xdata __at(0x1D0B) KSOHGOEN;
volatile uint8_t __xdata __at(0x1D0C) KSOHGDMRR;
volatile uint8_t __xdata __at(0x1D0D) KSOLGCTRL;
volatile uint8_t __xdata __at(0x1D0E) KSOLGOEN;
volatile uint8_t __xdata __at(0x1D0F) KSOLGDMRR;
volatile uint8_t __xdata __at(0x1D10) KSO0LSDR;
volatile uint8_t __xdata __at(0x1D11) KSO1LSDR;
volatile uint8_t __xdata __at(0x1D12) KSO2LSDR;
volatile uint8_t __xdata __at(0x1D13) KSO3LSDR;
volatile uint8_t __xdata __at(0x1D14) KSO4LSDR;
volatile uint8_t __xdata __at(0x1D15) KSO5LSDR;
volatile uint8_t __xdata __at(0x1D16) KSO6LSDR;
volatile uint8_t __xdata __at(0x1D17) KSO7LSDR;
volatile uint8_t __xdata __at(0x1D18) KSO8LSDR;
volatile uint8_t __xdata __at(0x1D19) KSO9LSDR;
volatile uint8_t __xdata __at(0x1D1A) KSO10LSDR;
volatile uint8_t __xdata __at(0x1D1B) KSO11LSDR;
volatile uint8_t __xdata __at(0x1D1C) KSO12LSDR;
volatile uint8_t __xdata __at(0x1D1D) KSO13LSDR;
volatile uint8_t __xdata __at(0x1D1E) KSO14LSDR;
volatile uint8_t __xdata __at(0x1D1F) KSO15LSDR;
volatile uint8_t __xdata __at(0x1D20) KSO16LSDR;
volatile uint8_t __xdata __at(0x1D21) KSO17LSDR;
volatile uint8_t __xdata __at(0x1D22) SDC1R;
volatile uint8_t __xdata __at(0x1D23) SDC2R;
volatile uint8_t __xdata __at(0x1D24) SDC3R;
volatile uint8_t __xdata __at(0x1D25) SDSR;
#endif // _EC_KBSCAN_H

View File

@ -0,0 +1,17 @@
#ifndef _EC_PECI_H
#define _EC_PECI_H
#include <stdint.h>
static volatile uint8_t __xdata __at(0x3000) HOSTAR;
static volatile uint8_t __xdata __at(0x3001) HOCTLR;
static volatile uint8_t __xdata __at(0x3002) HOCMDR;
static volatile uint8_t __xdata __at(0x3003) HOTRADDR;
static volatile uint8_t __xdata __at(0x3004) HOWRLR;
static volatile uint8_t __xdata __at(0x3005) HORDLR;
static volatile uint8_t __xdata __at(0x3006) HOWRDR;
static volatile uint8_t __xdata __at(0x3007) HORDDR;
static volatile uint8_t __xdata __at(0x3008) HOCTL2R;
static volatile uint8_t __xdata __at(0x3009) RWFCSV;
#endif // _EC_PECI_H

View File

@ -0,0 +1,40 @@
#ifndef _EC_PMC_H
#define _EC_PMC_H
#include <stdbool.h>
#include <stdint.h>
struct Pmc {
// Status register
volatile uint8_t * status;
// Data out register
volatile uint8_t * data_out;
// Data in register
volatile uint8_t * data_in;
// Control register
volatile uint8_t * control;
};
extern struct Pmc __code PMC_1;
extern struct Pmc __code PMC_2;
#define PMC_STS_OBF (1 << 0)
#define PMC_STS_IBF (1 << 1)
#define PMC_STS_CMD (1 << 3)
uint8_t pmc_status(struct Pmc * pmc);
void pmc_set_status(struct Pmc * pmc, uint8_t status);
uint8_t pmc_read(struct Pmc * pmc);
bool pmc_write(struct Pmc * pmc, uint8_t data, int timeout);
volatile uint8_t __xdata __at(0x1500) PM1STS;
volatile uint8_t __xdata __at(0x1501) PM1DO;
volatile uint8_t __xdata __at(0x1504) PM1DI;
volatile uint8_t __xdata __at(0x1506) PM1CTL;
volatile uint8_t __xdata __at(0x1510) PM2STS;
volatile uint8_t __xdata __at(0x1511) PM2DO;
volatile uint8_t __xdata __at(0x1514) PM2DI;
volatile uint8_t __xdata __at(0x1516) PM2CTL;
#endif // _EC_PMC_H

View File

@ -0,0 +1,37 @@
#ifndef _EC_PS2_H
#define _EC_PS2_H
#include <stdint.h>
struct Ps2 {
volatile uint8_t * control;
volatile uint8_t * interrupt;
volatile uint8_t * status;
volatile uint8_t * data;
};
extern struct Ps2 __code PS2_1;
extern struct Ps2 __code PS2_2;
extern struct Ps2 __code PS2_3;
void ps2_reset(struct Ps2 * ps2);
int ps2_read(struct Ps2 * ps2, uint8_t * data, int length);
int ps2_write(struct Ps2 * ps2, uint8_t * data, int length);
volatile uint8_t __xdata __at(0x1700) PSCTL1;
volatile uint8_t __xdata __at(0x1701) PSCTL2;
volatile uint8_t __xdata __at(0x1702) PSCTL3;
volatile uint8_t __xdata __at(0x1704) PSINT1;
volatile uint8_t __xdata __at(0x1705) PSINT2;
volatile uint8_t __xdata __at(0x1706) PSINT3;
volatile uint8_t __xdata __at(0x1708) PSSTS1;
volatile uint8_t __xdata __at(0x1709) PSSTS2;
volatile uint8_t __xdata __at(0x170A) PSSTS3;
volatile uint8_t __xdata __at(0x170C) PSDAT1;
volatile uint8_t __xdata __at(0x170D) PSDAT2;
volatile uint8_t __xdata __at(0x170E) PSDAT3;
#endif // _EC_PS2_H

View File

@ -0,0 +1,63 @@
#ifndef _EC_PWM_H
#define _EC_PWM_H
#include <stdint.h>
// Channel 0 clock prescaler register
volatile uint8_t __xdata __at(0x1800) C0CPRS;
// Channel 6 clock prescaler register (low byte)
volatile uint8_t __xdata __at(0x182B) C6CPRS;
// Channel 6 clock prescaler register (high byte)
volatile uint8_t __xdata __at(0x182C) C6MCPRS;
// Cycle Time 0
volatile uint8_t __xdata __at(0x1801) CTR0;
// Cycle Time 1
volatile uint8_t __xdata __at(0x1841) CTR1;
// Cycle Time 2
volatile uint8_t __xdata __at(0x1842) CTR2;
// Cycle Time 3
volatile uint8_t __xdata __at(0x1843) CTR3;
// Duty cycle register 0
volatile uint8_t __xdata __at(0x1802) DCR0;
// Duty cycle register 1
volatile uint8_t __xdata __at(0x1803) DCR1;
// Duty cycle register 2
volatile uint8_t __xdata __at(0x1804) DCR2;
// Duty cycle register 3
volatile uint8_t __xdata __at(0x1805) DCR3;
// Duty cycle register 4
volatile uint8_t __xdata __at(0x1806) DCR4;
// Duty cycle register 5
volatile uint8_t __xdata __at(0x1807) DCR5;
// Duty cycle register 6
volatile uint8_t __xdata __at(0x1808) DCR6;
// Duty cycle register 7
volatile uint8_t __xdata __at(0x1809) DCR7;
// Fan one tachometer least significant byte reading register
volatile uint8_t __xdata __at(0x181E) F1TLRR;
// Fan one tachometer most significant byte reading register
volatile uint8_t __xdata __at(0x181F) F1TMRR;
// Fan two tachometer least significant byte reading register
volatile uint8_t __xdata __at(0x1820) F2TLRR;
// Fan two tachometer most significant byte reading register
volatile uint8_t __xdata __at(0x1821) F2TMRR;
// PWM polarity register
volatile uint8_t __xdata __at(0x180A) PWMPOL;
// Prescaler clock frequency select register
volatile uint8_t __xdata __at(0x180B) PCFSR;
// Prescaler clock source select group low
volatile uint8_t __xdata __at(0x180C) PCSSGL;
// Prescaler clock source select group high
volatile uint8_t __xdata __at(0x180D) PCSSGH;
// Prescaler clock source gating register
volatile uint8_t __xdata __at(0x180F) PCSGR;
// PWM clock control register with weird name
volatile uint8_t __xdata __at(0x1823) ZTIER;
// Tachometer switch control register
volatile uint8_t __xdata __at(0x1848) TSWCTLR;
#endif // _EC_PWM_H

View File

@ -0,0 +1,85 @@
#ifndef _EC_SMBUS_H
#define _EC_SMBUS_H
#include <stdint.h>
#define HOSTA_BYTE_DONE (1 << 7)
#define HOSTA_TIMEOUT (1 << 6)
#define HOSTA_NACK (1 << 5)
#define HOSTA_FAIL (1 << 4)
#define HOSTA_BUS_ERR (1 << 3)
#define HOSTA_DEV_ERR (1 << 2)
#define HOSTA_FINISH (1 << 1)
#define HOSTA_BUSY (1 << 0)
#define HOSTA_ERR (HOSTA_TIMEOUT | HOSTA_NACK | HOSTA_FAIL | HOSTA_BUS_ERR | HOSTA_DEV_ERR)
// Host status for channel A
volatile uint8_t __xdata __at(0x1C00) HOSTAA;
// Host control for channel A
volatile uint8_t __xdata __at(0x1C01) HOCTLA;
// Host command for channel A
volatile uint8_t __xdata __at(0x1C02) HOCMDA;
// Transmit slave address for channel A
volatile uint8_t __xdata __at(0x1C03) TRASLAA;
// Host data 0 for channel A
volatile uint8_t __xdata __at(0x1C04) D0REGA;
// Host data 1 for channel A
volatile uint8_t __xdata __at(0x1C05) D1REGA;
// Host block data byte for channel A
volatile uint8_t __xdata __at(0x1C06) HOBDBA;
// Packet error check for channel A
volatile uint8_t __xdata __at(0x1C07) PECERCA;
// Receive slave address for channel A
volatile uint8_t __xdata __at(0x1C08) RESLADRA;
// Slave data for channel A
volatile uint8_t __xdata __at(0x1C09) SLDAA;
// SMBus pin control for channel A
volatile uint8_t __xdata __at(0x1C0A) SMBPCTLA;
// Slave status for channel A
volatile uint8_t __xdata __at(0x1C0B) SLSTAA;
// Slave interrupt control for channel A
volatile uint8_t __xdata __at(0x1C0C) SICRA;
// Notify device address for channel A
volatile uint8_t __xdata __at(0x1C0D) NDADRA;
// Notify data low byte for channel A
volatile uint8_t __xdata __at(0x1C0E) NDLBA;
// Notify data high byte for channel A
volatile uint8_t __xdata __at(0x1C0F) NDHBA;
// Host control 2 for channel A
volatile uint8_t __xdata __at(0x1C10) HOCTL2A;
// Receive slave address 2 for channel A
volatile uint8_t __xdata __at(0x1C3F) RESLADR2A;
// SMCLK timing setting for channel A
volatile uint8_t __xdata __at(0x1C40) SCLKTSA;
// Host status for channel E
volatile uint8_t __xdata __at(0x1CA0) HOSTAE;
// Host control for channel E
volatile uint8_t __xdata __at(0x1CA1) HOCTLE;
// Host command for channel E
volatile uint8_t __xdata __at(0x1CA2) HOCMDE;
// Transmit slave address for channel E
volatile uint8_t __xdata __at(0x1CA3) TRASLAE;
// Host data 0 for channel E
volatile uint8_t __xdata __at(0x1CA4) D0REGE;
// Host data 1 for channel E
volatile uint8_t __xdata __at(0x1CA6) D1REGE;
// Host block data byte for channel E
volatile uint8_t __xdata __at(0x1CA7) HOBDBE;
// Packet error check for channel E
volatile uint8_t __xdata __at(0x1CA8) PECERCE;
// SMBus pin control for channel E
volatile uint8_t __xdata __at(0x1CA9) SMBPCTLE;
// Host control 2 for channel E
volatile uint8_t __xdata __at(0x1CAA) HOCTL2E;
// Timing registers
volatile uint8_t __xdata __at(0x1C22) SMB4P7USL;
volatile uint8_t __xdata __at(0x1C23) SMB4P0USL;
volatile uint8_t __xdata __at(0x1C24) SMB300NS;
volatile uint8_t __xdata __at(0x1C25) SMB250NS;
volatile uint8_t __xdata __at(0x1C26) SMB25MS;
volatile uint8_t __xdata __at(0x1C27) SMB45P3USL;
volatile uint8_t __xdata __at(0x1C28) SMB45P3USH;
#endif // _EC_SMBUS_H

41
src/ec/it5570e/kbc.c Normal file
View File

@ -0,0 +1,41 @@
#include <ec/kbc.h>
struct Kbc __code KBC = {
.control = &KBHICR,
.irq = &KBIRQR,
.status = &KBHISR,
.keyboard_out = &KBHIKDOR,
.mouse_out = &KBHIMDOR,
.data_in = &KBHIDIR,
};
uint8_t kbc_status(struct Kbc * kbc) {
return *(kbc->status);
}
uint8_t kbc_read(struct Kbc * kbc) {
return *(kbc->data_in);
}
static bool kbc_wait(struct Kbc * kbc, int timeout) {
while (kbc_status(kbc) & KBC_STS_OBF) {
if (timeout == 0) return false;
timeout -= 1;
}
return true;
}
bool kbc_keyboard(struct Kbc * kbc, uint8_t data, int timeout) {
if (!kbc_wait(kbc, timeout)) return false;
*(kbc->status) &= ~0x20;
*(kbc->keyboard_out) = data;
return true;
}
bool kbc_mouse(struct Kbc * kbc, uint8_t data, int timeout) {
if (!kbc_wait(kbc, timeout)) return false;
*(kbc->status) |= 0x20;
*(kbc->mouse_out) = data;
return true;
}

37
src/ec/it5570e/pmc.c Normal file
View File

@ -0,0 +1,37 @@
#include <ec/pmc.h>
#define PMC(NUM) { \
.status = &PM ## NUM ## STS, \
.data_out = &PM ## NUM ## DO, \
.data_in = &PM ## NUM ## DI, \
.control = &PM ## NUM ## CTL, \
}
struct Pmc __code PMC_1 = PMC(1);
struct Pmc __code PMC_2 = PMC(2);
uint8_t pmc_status(struct Pmc * pmc) {
return *(pmc->status);
}
void pmc_set_status(struct Pmc * pmc, uint8_t status) {
*(pmc->status) = status;
}
uint8_t pmc_read(struct Pmc * pmc) {
return *(pmc->data_in);
}
static bool pmc_wait(struct Pmc * pmc, int timeout) {
while (pmc_status(pmc) & PMC_STS_OBF) {
if (timeout == 0) return false;
timeout -= 1;
}
return true;
}
bool pmc_write(struct Pmc * pmc, uint8_t data, int timeout) {
if (!pmc_wait(pmc, timeout)) return false;
*(pmc->data_out) = data;
return true;
}

81
src/ec/it5570e/ps2.c Normal file
View File

@ -0,0 +1,81 @@
#include <stdbool.h>
#include <ec/ps2.h>
#define PS2(NUM) { \
.control = &PSCTL ## NUM, \
.interrupt = &PSINT ## NUM, \
.status = &PSSTS ## NUM, \
.data = &PSDAT ## NUM, \
}
#define PS2_TIMEOUT 10000
#define PSSTS_TIMEOUT_ERR (1 << 6)
#define PSSTS_FRAME_ERR (1 << 5)
#define PSSTS_PARITY_ERR (1 << 4)
#define PSSTS_ALL_ERR (PSSTS_TIMEOUT_ERR | PSSTS_FRAME_ERR | PSSTS_PARITY_ERR)
#define PSSTS_DONE (1 << 3)
struct Ps2 __code PS2_1 = PS2(1);
struct Ps2 __code PS2_2 = PS2(2);
struct Ps2 __code PS2_3 = PS2(3);
void ps2_reset(struct Ps2 * ps2) {
// Reset interface to defaults
*(ps2->control) = 1;
// Clear status
*(ps2->status) = *(ps2->status);
}
static int ps2_transaction(struct Ps2 * ps2, uint8_t * data, int length, bool read) {
int i;
for (i = 0; i < length; i++) {
if (read) {
// Begin read
*(ps2->control) = 0x07;
} else {
// Begin write
*(ps2->control) = 0x0D;
*(ps2->data) = data[i];
// Pull data line low
*(ps2->control) = 0x0C;
// Pull clock line high
*(ps2->control) = 0x0E;
}
uint32_t timeout;
for (timeout = PS2_TIMEOUT; timeout > 0; timeout--) {
uint8_t status = *(ps2->status);
// If an error happened, clear status and return the error
if (status & PSSTS_ALL_ERR) {
ps2_reset(ps2);
return -(int)status;
}
// If transaction is done, break
if (status & PSSTS_DONE) {
break;
}
}
// If a timeout happened, return the error
if (timeout == 0) {
ps2_reset(ps2);
return -0x1000;
}
if (read) {
data[i] = *(ps2->data);
}
// Set interface to defaults
ps2_reset(ps2);
}
return i;
}
int ps2_read(struct Ps2 * ps2, uint8_t * data, int length) {
return ps2_transaction(ps2, data, length, true);
}
int ps2_write(struct Ps2 * ps2, uint8_t * data, int length) {
return ps2_transaction(ps2, data, length, false);
}

View File

@ -0,0 +1,7 @@
static __code char __at(0x40) SIGNATURE[32] = {
0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0xA5, 0x94,
0x85, 0x12, 0x5A, 0x5A, 0xAA, 0x00, 0x55, 0x55,
0x49, 0x54, 0x45, 0x20, 0x54, 0x65, 0x63, 0x68,
0x2E, 0x20, 0x49, 0x6E, 0x63, 0x2E, 0x20, 0x20
};

View File

@ -6,30 +6,36 @@
//TODO: find best value
#define I2C_TIMEOUT 10000
#define HOSTA HOSTAA
#define HOCTL HOCTLA
#define HOCTL2 HOCTL2A
#define HOBDB HOBDBA
#define TRASLA TRASLAA
void i2c_reset(bool kill) {
if (HOSTAA & HOSTA_BUSY) {
if (HOSTA & HOSTA_BUSY) {
// Set kill bit
if (kill) HOCTLA |= (1 << 1);
if (kill) HOCTL |= (1 << 1);
// Wait for host to finish
while (HOSTAA & HOSTA_BUSY) {}
while (HOSTA & HOSTA_BUSY) {}
}
// Clear status register
HOSTAA = HOSTAA;
HOSTA = HOSTA;
// Clear current command
HOCTLA = 0;
HOCTL = 0;
// Disable host interface
HOCTL2A = 0;
HOCTL2 = 0;
}
int i2c_start(uint8_t addr, bool read) {
// If we are already in a transaction
if (HOSTAA & HOSTA_BYTE_DONE) {
if (HOSTA & HOSTA_BYTE_DONE) {
// If we are switching direction
if ((TRASLAA & 1) != read) {
if ((TRASLA & 1) != read) {
// If we are switching to read mode
if (read) {
// Enable direction switch
HOCTL2A |= (1 << 3) | (1 << 2);
HOCTL2 |= (1 << 3) | (1 << 2);
} else {
// Unsupported!
i2c_reset(true);
@ -40,10 +46,10 @@ int i2c_start(uint8_t addr, bool read) {
i2c_reset(true);
// Enable host controller with i2c compatibility
HOCTL2A = (1 << 1) | 1;
HOCTL2 = (1 << 1) | 1;
// Set address
TRASLAA = (addr << 1) | read;
TRASLA = (addr << 1) | read;
}
return 0;
@ -51,9 +57,9 @@ int i2c_start(uint8_t addr, bool read) {
void i2c_stop(void) {
// Disable i2c compatibility
HOCTL2A &= ~(1 << 1);
HOCTL2 &= ~(1 << 1);
// Clear status
HOSTAA = HOSTAA;
HOSTA = HOSTA;
i2c_reset(false);
}
@ -65,33 +71,33 @@ static int i2c_transaction(uint8_t * data, int length, bool read) {
// If last byte
if ((i + 1) == length) {
// Set last byte bit
HOCTLA |= (1 << 5);
HOCTL |= (1 << 5);
}
} else {
// Write byte
HOBDBA = data[i];
HOBDB = data[i];
}
// If we are already in a transaction
if (HOSTAA & HOSTA_BYTE_DONE) {
if (HOSTA & HOSTA_BYTE_DONE) {
// Clear status to process next byte
HOSTAA = HOSTAA;
HOSTA = HOSTA;
} else {
// Start new transaction
HOCTLA = (1 << 6) | (0b111 << 2);
HOCTL = (1 << 6) | (0b111 << 2);
}
// If we are waiting on direction switch
if (HOCTL2A & (1 << 2)) {
if (HOCTL2 & (1 << 2)) {
// Complete direction switch
HOCTL2A &= ~(1 << 2);
HOCTL2 &= ~(1 << 2);
}
// Wait for byte done, timeout, or error
uint8_t status;
uint32_t timeout = I2C_TIMEOUT;
for(timeout = I2C_TIMEOUT; timeout > 0; timeout--) {
status = HOSTAA;
status = HOSTA;
// If error occured, kill transaction and return error
if (status & HOSTA_ERR) {
i2c_reset(true);
@ -110,7 +116,7 @@ static int i2c_transaction(uint8_t * data, int length, bool read) {
if (read) {
// Read byte
data[i] = HOBDBA;
data[i] = HOBDB;
}
}

View File

@ -31,8 +31,6 @@ volatile uint8_t __xdata __at(0x1C06) HOBDBA;
volatile uint8_t __xdata __at(0x1C07) PECERCA;
// Receive slave address for channel A
volatile uint8_t __xdata __at(0x1C08) RESLADRA;
// Receive slave address 2 for channel A
volatile uint8_t __xdata __at(0x1C3F) RESLADR2A;
// Slave data for channel A
volatile uint8_t __xdata __at(0x1C09) SLDAA;
// SMBus pin control for channel A
@ -49,6 +47,8 @@ volatile uint8_t __xdata __at(0x1C0E) NDLBA;
volatile uint8_t __xdata __at(0x1C0F) NDHBA;
// Host control 2 for channel A
volatile uint8_t __xdata __at(0x1C10) HOCTL2A;
// Receive slave address 2 for channel A
volatile uint8_t __xdata __at(0x1C3F) RESLADR2A;
// SMCLK timing setting for channel A
volatile uint8_t __xdata __at(0x1C40) SCLKTSA;