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>
This commit is contained in:
Husni Faiz 2022-09-09 17:49:53 +05:30 committed by Martin L Roth
parent 22baa3352c
commit b80535a135
5 changed files with 99 additions and 1 deletions

View File

@ -311,14 +311,29 @@ if CONSOLE_I2C_SMBUS
config CONSOLE_I2C_SMBUS_SLAVE_ADDRESS config CONSOLE_I2C_SMBUS_SLAVE_ADDRESS
hex "I2C slave address of the logging device" hex "I2C slave address of the logging device"
default 0x48 if SC16IS7XX_INIT
help help
I2C address of the device which logs the data. I2C address of the device which logs the data.
config CONSOLE_I2C_SMBUS_SLAVE_DATA_REGISTER config CONSOLE_I2C_SMBUS_SLAVE_DATA_REGISTER
hex "Data register address of the I2C logging device" hex "Data register address of the I2C logging device"
default 0x00 if SC16IS7XX_INIT
help help
This an 8-bit data register. 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 endif # CONSOLE_I2C_SMBUS
config CONSOLE_QEMU_DEBUGCON config CONSOLE_QEMU_DEBUGCON

View File

@ -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) ifeq ($(CONFIG_CONSOLE_I2C_SMBUS),y)
all-y += i2c_smbus_console.c all-y += i2c_smbus_console.c
endif endif

View File

@ -3,8 +3,13 @@
#include <console/i2c_smbus.h> #include <console/i2c_smbus.h>
#include <device/smbus_host.h> #include <device/smbus_host.h>
#include <southbridge/intel/bd82x6x/pch.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) void i2c_smbus_console_tx_byte(unsigned char c)
{ {

View File

@ -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-sheet/SC16IS740_750_760.pdf
*/
// 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));
}

View File

@ -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__ */