Martin L Roth has submitted this change. ( https://review.coreboot.org/c/coreboot/+/67342 )
Change subject: drivers/smbus: initialize SC16IS7XX I2C to UART converter chip ......................................................................
drivers/smbus: initialize SC16IS7XX I2C to UART converter chip
This patch adds the functionality to initialize the sc16is750 i2c to uart converter chip with a 14.7MHz input clock to support 115200 baud rate.
Change-Id: Ib31188b8c0f9b0ce9454da984e630eca9101d145 Signed-off-by: Husni Faiz ahamedhusni73@gmail.com Reviewed-on: https://review.coreboot.org/c/coreboot/+/67342 Tested-by: build bot (Jenkins) no-reply@coreboot.org Reviewed-by: Tim Wawrzynczak inforichland@gmail.com Reviewed-by: Raul Rangel rrangel@chromium.org --- M src/console/Kconfig M src/drivers/smbus/Makefile.inc M src/drivers/smbus/i2c_smbus_console.c A src/drivers/smbus/sc16is7xx_init.c A src/drivers/smbus/sc16is7xx_init.h 5 files changed, 117 insertions(+), 1 deletion(-)
Approvals: build bot (Jenkins): Verified Raul Rangel: Looks good to me, approved Tim Wawrzynczak: Looks good to me, but someone else must approve
diff --git a/src/console/Kconfig b/src/console/Kconfig index 9b8e9f8..c6aec18 100644 --- a/src/console/Kconfig +++ b/src/console/Kconfig @@ -311,14 +311,29 @@
config CONSOLE_I2C_SMBUS_SLAVE_ADDRESS hex "I2C slave address of the logging device" + default 0x48 if SC16IS7XX_INIT help I2C address of the device which logs the data.
config CONSOLE_I2C_SMBUS_SLAVE_DATA_REGISTER hex "Data register address of the I2C logging device" + default 0x00 if SC16IS7XX_INIT help This an 8-bit data register.
+config SC16IS7XX_INIT + bool "Initialize SC16IS7XX I2C to UART converter chip" + help + SC16IS7XX is a slave I2C to UART converter chip. Enabling + this option will initialize the chip. + + The default I2C slave address value 0x48 is the address of + SC16IS7XX I2C to UART converter chip when the A1 and A0 pins + are set to Vcc. + + The default data register address value 0x00 is the data + register address of SC16IS7XX I2C to UART converter chip. + endif # CONSOLE_I2C_SMBUS
config CONSOLE_QEMU_DEBUGCON diff --git a/src/drivers/smbus/Makefile.inc b/src/drivers/smbus/Makefile.inc index e14d59c..d478889 100644 --- a/src/drivers/smbus/Makefile.inc +++ b/src/drivers/smbus/Makefile.inc @@ -1,3 +1,8 @@ +ifeq ($(CONFIG_SC16IS7XX_INIT),y) +bootblock-y += sc16is7xx_init.c +romstage-y += sc16is7xx_init.c +endif + ifeq ($(CONFIG_CONSOLE_I2C_SMBUS),y) all-y += i2c_smbus_console.c endif diff --git a/src/drivers/smbus/i2c_smbus_console.c b/src/drivers/smbus/i2c_smbus_console.c index c223028..d651790 100644 --- a/src/drivers/smbus/i2c_smbus_console.c +++ b/src/drivers/smbus/i2c_smbus_console.c @@ -3,8 +3,13 @@ #include <console/i2c_smbus.h> #include <device/smbus_host.h> #include <southbridge/intel/bd82x6x/pch.h> +#include "sc16is7xx_init.h"
-void i2c_smbus_console_init(void) {} +void i2c_smbus_console_init(void) +{ + if (CONFIG(SC16IS7XX_INIT)) + sc16is7xx_init(); +}
void i2c_smbus_console_tx_byte(unsigned char c) { diff --git a/src/drivers/smbus/sc16is7xx_init.c b/src/drivers/smbus/sc16is7xx_init.c new file mode 100644 index 0000000..c350b25 --- /dev/null +++ b/src/drivers/smbus/sc16is7xx_init.c @@ -0,0 +1,62 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#include <console/i2c_smbus.h> +#include <device/i2c.h> +#include <device/smbus_host.h> +#include <southbridge/intel/bd82x6x/pch.h> +#include "sc16is7xx_init.h" + +/* + * Datasheet - SC16IS740/750/760, Rev. 7 - 9 June 2011 + * https://web.archive.org/web/20210612105830/https://www.nxp.com/docs/en/data-... + */ + +// Bits [6:3] of the subaddress is to address device internal registers +#define INTERNAL_REG_SUB_ADDR_SHIFT 3 + +#define REG_THR 0x00 // Transmit Holding Register +#define REG_LCR 0x03 // Line Control Register + +// Special Register Set is accessible only when LCR[7] is logic 1 +#define REG_DLL 0x00 // divisor latch LSB +#define REG_DLH 0x01 // divisor latch MSB + +#define LCR_WORD_LEN_BIT_0 BIT(0) +#define LCR_WORD_LEN_BIT_1 BIT(1) +#define LCR_STOP_BIT BIT(2) +#define LCR_PARITY_BIT_0 BIT(3) +#define LCR_PARITY_BIT_1 BIT(4) +#define LCR_PARITY_BIT_2 BIT(5) +#define LCR_BREAK_CTL_BIT BIT(6) +#define LCR_SPEC_REG_SET_EN BIT(7) + +#define UART_8_N_1 (LCR_WORD_LEN_BIT_0 | LCR_WORD_LEN_BIT_1) + +/* + * UART configuration: 8 bit word length, No parity, 1 stop bit (8-N-1) + * Divisor value set here is calculated for 115200 baud rate + * in 14.7MHz clock input to chip. + */ + +#define BAUD_115200_DLL 0x08 +#define BAUD_115200_DLH 0x00 + +void sc16is7xx_write_byte(uint8_t reg, unsigned char c) +{ + do_smbus_write_byte(CONFIG_FIXED_SMBUS_IO_BASE, + CONFIG_CONSOLE_I2C_SMBUS_SLAVE_ADDRESS, reg, c); +} + +void sc16is7xx_init(void) +{ + // Configure 8-N-1 and enable special register set + sc16is7xx_write_byte(REG_LCR << INTERNAL_REG_SUB_ADDR_SHIFT, + (UART_8_N_1 | LCR_SPEC_REG_SET_EN)); + + sc16is7xx_write_byte(REG_DLL << INTERNAL_REG_SUB_ADDR_SHIFT, BAUD_115200_DLL); + sc16is7xx_write_byte(REG_DLH << INTERNAL_REG_SUB_ADDR_SHIFT, BAUD_115200_DLH); + + // Disable special register set + sc16is7xx_write_byte(REG_LCR << INTERNAL_REG_SUB_ADDR_SHIFT, + (UART_8_N_1 & ~LCR_SPEC_REG_SET_EN)); +} diff --git a/src/drivers/smbus/sc16is7xx_init.h b/src/drivers/smbus/sc16is7xx_init.h new file mode 100644 index 0000000..f57c82a --- /dev/null +++ b/src/drivers/smbus/sc16is7xx_init.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +#ifndef __DRIVERS_SMBUS_SC16IS7XX_INIT__ +#define __DRIVERS_SMBUS_SC16IS7XX_INIT__ + +#include <types.h> + +void sc16is7xx_write_byte(uint8_t reg, unsigned char c); +void sc16is7xx_init(void); + +#endif /* __DRIVERS_SMBUS_SC16IS7XX_INIT__ */