mirror of
https://github.com/logicog/RTLPlayground.git
synced 2026-08-30 14:52:51 +08:00
Advanced I2C pin definition
RTL has up to 3 SCL pins and up to 4 SDA pins. Lets allow configuring I2C with individual BUS numbers instead of 0/1 I2C. This enables support for devices where SCL line is not shared between SFP modules. MUX registry is now initialized depending on needed pin function. More over, some SFP pins require special MUX settings, lets initialize those depending on SFP configuration. This adds TX Disable pin, which right now is set to low at startup. Caveats: - We may still override MUX registry later - Not sure how to handle invalid bus definitions - Without SFP is it fine to *not* initialize anything? - Do to RAM limitation we do inititalize output GPIO to low
This commit is contained in:
+98
-6
@@ -807,7 +807,7 @@ uint8_t sfp_read_reg(uint8_t slot, uint8_t reg)
|
||||
}
|
||||
|
||||
reg_read_m(RTL837X_REG_I2C_CTRL);
|
||||
sfr_mask_data(1, 0xfc, machine.sfp_port[slot].i2c == 0 ? SCL_PIN << 5 | SDA_PIN_0 << 2 : SCL_PIN << 5 | SDA_PIN_1 << 2 );
|
||||
sfr_mask_data(1, 0xfc, machine.sfp_port[slot].i2c_bus.scl << 5 | machine.sfp_port[slot].i2c_bus.sda << 2);
|
||||
reg_write_m(RTL837X_REG_I2C_CTRL);
|
||||
|
||||
REG_WRITE(RTL837X_REG_I2C_IN, 0, 0, 0, reg);
|
||||
@@ -1009,6 +1009,59 @@ bool gpio_pin_test(uint8_t pin)
|
||||
return sfr_data[3-((pin >> 3) & 3)] & (1 << (pin & 7));
|
||||
}
|
||||
|
||||
void gpio_mux_setup(uint8_t pin)
|
||||
{
|
||||
// Some GPIOs require setting MUX registers to enable GPIO
|
||||
if (pin == 36) {
|
||||
reg_bit_set(RTL837X_PIN_MUX_1, 30);
|
||||
} else if ( pin == 50 ) {
|
||||
// Bit 15-16 0b00 -> GPIO
|
||||
reg_read_m(RTL837X_PIN_MUX_1);
|
||||
sfr_mask_data(1, 0x80, 0x00);
|
||||
sfr_mask_data(2, 0x01, 0x00);
|
||||
reg_write_m(RTL837X_PIN_MUX_1);
|
||||
} else if ( pin == 51 ) {
|
||||
// Bit 17-18 0b00 -> GPIO
|
||||
reg_read_m(RTL837X_PIN_MUX_1);
|
||||
sfr_mask_data(2, 0x06, 0x00);
|
||||
reg_write_m(RTL837X_PIN_MUX_1);
|
||||
} else if ( pin == 54 ) {
|
||||
reg_bit_clear(RTL837X_PIN_MUX_2, 2);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup a GPIO pin as input
|
||||
* pin: GPIO pin number 0-63
|
||||
*/
|
||||
void gpio_input_setup(uint8_t pin) {
|
||||
gpio_mux_setup(pin);
|
||||
reg_bit_clear(pin < 32 ? RTL837X_REG_GPIO_00_31_DIRECTION : RTL837X_REG_GPIO_32_63_DIRECTION, (pin % 32));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Setup a GPIO pin as output
|
||||
* pin: GPIO pin number 0-63
|
||||
*/
|
||||
void gpio_output_setup(uint8_t pin) {
|
||||
gpio_mux_setup(pin);
|
||||
// Default output to low
|
||||
reg_bit_clear(pin < 32 ? RTL837X_REG_GPIO_00_31_OUTPUT : RTL837X_REG_GPIO_32_63_OUTPUT, (pin % 32));
|
||||
reg_bit_set(pin < 32 ? RTL837X_REG_GPIO_00_31_DIRECTION : RTL837X_REG_GPIO_32_63_DIRECTION, (pin % 32));
|
||||
}
|
||||
|
||||
/* Inititalize SFP GPIOs */
|
||||
void setup_sfp_gpio(void)
|
||||
{
|
||||
for (uint8_t sfp = 0; sfp < machine.n_sfp; sfp++) {
|
||||
gpio_input_setup(machine.sfp_port[sfp].pin_detect);
|
||||
gpio_input_setup(machine.sfp_port[sfp].pin_los);
|
||||
if (machine.sfp_port[sfp].pin_tx_disable != 0xFF) {
|
||||
gpio_output_setup(machine.sfp_port[sfp].pin_tx_disable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void handle_sfp(void)
|
||||
{
|
||||
@@ -1538,7 +1591,6 @@ void led_config(void)
|
||||
reg_write_m(RTL837X_REG_LED3_0_SET1);
|
||||
}
|
||||
|
||||
|
||||
void rtl8373_revision(void)
|
||||
{
|
||||
reg_read_m(RTL837X_REG_CHIP_INFO);
|
||||
@@ -1811,11 +1863,50 @@ void setup_i2c(void)
|
||||
|
||||
REG_SET(RTL837X_REG_I2C_CTRL2, 0);
|
||||
|
||||
// HW Control register, enable I2C?
|
||||
// HW Control register, enable I2C depending on PIN configuration
|
||||
reg_read_m(RTL837X_PIN_MUX_1);
|
||||
sfr_mask_data(3, 0x20, 0x00); // Clear bit 29
|
||||
sfr_mask_data(0, 0x60, 0x40); // Set bits 5-6 to 0b10
|
||||
reg_write_m(RTL837X_PIN_MUX_1);
|
||||
for (uint8_t sfp = 0; sfp < machine.n_sfp; sfp++) {
|
||||
const uint8_t scl_bus = machine.sfp_port[sfp].i2c_bus.scl;
|
||||
const uint8_t sda_bus = machine.sfp_port[sfp].i2c_bus.sda;
|
||||
print_string("Configuring I2C for SFP idx="); print_byte(sfp); print_string(" SCL="); print_byte(scl_bus); print_string(", SDA="); print_byte(sda_bus); write_char('\n');
|
||||
if (scl_bus == 3) {
|
||||
// Bit 5-6 0b10 -> SCL (implies enabled SDA on bus 3)
|
||||
sfr_mask_data(0, 0x60, 0x40);
|
||||
} else if (scl_bus == 2) {
|
||||
// Bit 15-16 0b01 -> SCL
|
||||
sfr_mask_data(1, 0x80, 0x80);
|
||||
sfr_mask_data(2, 0x01, 0x00);
|
||||
} else if (scl_bus == 1) {
|
||||
// Bit 11-12 0b01 -> SCL
|
||||
sfr_mask_data(1, 0x18, 0x08);
|
||||
} else if (scl_bus == 0) {
|
||||
// Bit 7-8 0b01 -> SCL
|
||||
sfr_mask_data(0, 0x80, 0x80);
|
||||
sfr_mask_data(1, 0x01, 0x00);
|
||||
} else {
|
||||
print_string("Invalid SCL bus number: "); print_byte(scl_bus); write_char('\n');
|
||||
}
|
||||
|
||||
if (sda_bus == 4) {
|
||||
// Bit 29 0b0 -> SDA
|
||||
sfr_mask_data(3, 0x20, 0x00);
|
||||
} else if (sda_bus == 3) {
|
||||
// Bit 5-6 0b10 -> SDA (implies enabled SCL on bus 3)
|
||||
sfr_mask_data(0, 0x60, 0x40);
|
||||
} else if (sda_bus == 2) {
|
||||
// Bit 17-18 0b01 -> SDA
|
||||
sfr_mask_data(2, 0x06, 0x02);
|
||||
} else if (sda_bus == 1) {
|
||||
// Bit 13-14 0b01 -> SDA
|
||||
sfr_mask_data(1, 0x60, 0x20);
|
||||
} else if (sda_bus == 0) {
|
||||
// Bit 9-10 0b01 -> SDA
|
||||
sfr_mask_data(1, 0x06, 0x02);
|
||||
} else {
|
||||
print_string("Invalid SDA bus number: "); print_byte(sda_bus); write_char('\n');
|
||||
}
|
||||
}
|
||||
reg_write_m(RTL837X_PIN_MUX_1);
|
||||
}
|
||||
|
||||
|
||||
@@ -2009,6 +2100,7 @@ void bootloader(void)
|
||||
management_vlan = 0; // Disabled
|
||||
|
||||
setup_i2c();
|
||||
setup_sfp_gpio();
|
||||
|
||||
print_string(greeting);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user