From 15347d2dea32d88e9d1553e26b7eb3553550f424 Mon Sep 17 00:00:00 2001 From: Stephen Carlson Date: Tue, 22 Jun 2021 16:35:20 -0700 Subject: [PATCH] board: freescale: Refactor NXP common mux code Refactors similar mux code from multiple NXP boards into a common location, and allows it to be disabled in config. New config: CONFIG_FSL_USE_PCA9547_MUX to enable PCA9547 mux functionality. Signed-off-by: Stephen Carlson Reviewed-by: Priyanka Jain --- board/freescale/common/Kconfig | 6 +++ board/freescale/common/Makefile | 11 ++++++ board/freescale/common/i2c_common.c | 34 +++++++++++++++++ board/freescale/common/i2c_common.h | 30 +++++++++++++++ board/freescale/common/i2c_mux.c | 40 ++++++++++++++++++++ board/freescale/common/i2c_mux.h | 15 ++++++++ board/freescale/common/vid.c | 58 ++++++----------------------- 7 files changed, 148 insertions(+), 46 deletions(-) create mode 100644 board/freescale/common/i2c_common.c create mode 100644 board/freescale/common/i2c_common.h create mode 100644 board/freescale/common/i2c_mux.c create mode 100644 board/freescale/common/i2c_mux.h diff --git a/board/freescale/common/Kconfig b/board/freescale/common/Kconfig index 17db755951..ab9c14ae88 100644 --- a/board/freescale/common/Kconfig +++ b/board/freescale/common/Kconfig @@ -21,6 +21,12 @@ config CMD_ESBC_VALIDATE esbc_validate - validate signature using RSA verification esbc_halt - put the core in spin loop (Secure Boot Only) +config FSL_USE_PCA9547_MUX + bool "Enable PCA9547 I2C Mux on Freescale boards" + default n + help + This option enables the PCA9547 I2C mux on Freescale boards. + config VID depends on DM_I2C bool "Enable Freescale VID" diff --git a/board/freescale/common/Makefile b/board/freescale/common/Makefile index 7862a791ac..116c1e71cc 100644 --- a/board/freescale/common/Makefile +++ b/board/freescale/common/Makefile @@ -15,6 +15,15 @@ ifdef MINIMAL # necessary to create built-in.o obj- := __dummy__.o else +# include i2c_common.o once if either VID or FSL_USE_PCA9547_MUX +I2C_COMMON= +ifdef CONFIG_VID +I2C_COMMON=y +endif +ifdef CONFIG_FSL_USE_PCA9547_MUX +I2C_COMMON=y +endif + obj-$(CONFIG_FSL_CADMUS) += cadmus.o obj-$(CONFIG_FSL_VIA) += cds_via.o obj-$(CONFIG_FMAN_ENET) += fman.o @@ -22,6 +31,8 @@ obj-$(CONFIG_FSL_PIXIS) += pixis.o ifndef CONFIG_SPL_BUILD obj-$(CONFIG_FSL_NGPIXIS) += ngpixis.o endif +obj-$(I2C_COMMON) += i2c_common.o +obj-$(CONFIG_FSL_USE_PCA9547_MUX) += i2c_mux.o obj-$(CONFIG_VID) += vid.o obj-$(CONFIG_FSL_QIXIS) += qixis.o obj-$(CONFIG_PQ_MDS_PIB) += pq-mds-pib.o diff --git a/board/freescale/common/i2c_common.c b/board/freescale/common/i2c_common.c new file mode 100644 index 0000000000..0f09ed7d34 --- /dev/null +++ b/board/freescale/common/i2c_common.c @@ -0,0 +1,34 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * Copyright 2020-21 NXP + * Copyright 2021 Microsoft Corporation + */ + +#include +#include +#include "i2c_common.h" + +#ifdef CONFIG_DM_I2C + +/* If DM is in use, retrieve the chip for the specified bus number */ +int fsl_i2c_get_device(int address, int bus, DEVICE_HANDLE_T *dev) +{ + int ret = i2c_get_chip_for_busnum(bus, address, 1, dev); + + if (ret) + printf("I2C: Bus %d has no device with address 0x%02X\n", + bus, address); + return ret; +} + +#else + +/* Handle is passed directly */ +int fsl_i2c_get_device(int address, int bus, DEVICE_HANDLE_T *dev) +{ + *dev = address; + return 0; +} + +#endif diff --git a/board/freescale/common/i2c_common.h b/board/freescale/common/i2c_common.h new file mode 100644 index 0000000000..840ad66183 --- /dev/null +++ b/board/freescale/common/i2c_common.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * Copyright 2020-21 NXP + * Copyright 2021 Microsoft Corporation + */ + +#ifndef __NXP_I2C_COMMON_H__ +#define __NXP_I2C_COMMON_H__ + +/* Common functionality shared by the I2C drivers for VID and the mux. */ +#ifdef CONFIG_DM_I2C +#define DEVICE_HANDLE_T struct udevice * + +#define I2C_READ(dev, register, data, length) \ + dm_i2c_read(dev, register, data, length) +#define I2C_WRITE(dev, register, data, length) \ + dm_i2c_write(dev, register, data, length) +#else +#define DEVICE_HANDLE_T int + +#define I2C_READ(dev, register, data, length) \ + i2c_read(dev, register, 1, data, length) +#define I2C_WRITE(dev, register, data, length) \ + i2c_write(dev, register, 1, data, length) +#endif + +int fsl_i2c_get_device(int address, int bus, DEVICE_HANDLE_T *dev); + +#endif diff --git a/board/freescale/common/i2c_mux.c b/board/freescale/common/i2c_mux.c new file mode 100644 index 0000000000..54f89e2576 --- /dev/null +++ b/board/freescale/common/i2c_mux.c @@ -0,0 +1,40 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * Copyright 2020-21 NXP + * Copyright 2021 Microsoft Corporation + */ + +#include +#include +#include "i2c_common.h" +#include "i2c_mux.h" + +/* + * A new Kconfig option for something that used to always be built should be + * “default y”. + */ +#ifdef CONFIG_FSL_USE_PCA9547_MUX + +int select_i2c_ch_pca9547(u8 ch, int bus) +{ + int ret; + DEVICE_HANDLE_T dev; + + /* Open device handle */ + ret = fsl_i2c_get_device(I2C_MUX_PCA_ADDR_PRI, bus, &dev); + if (ret) { + printf("PCA: No PCA9547 device found\n"); + return ret; + } + + ret = I2C_WRITE(dev, 0, &ch, sizeof(ch)); + if (ret) { + printf("PCA: Unable to select channel %d (%d)\n", (int)ch, ret); + return ret; + } + + return 0; +} + +#endif diff --git a/board/freescale/common/i2c_mux.h b/board/freescale/common/i2c_mux.h new file mode 100644 index 0000000000..0870c1918e --- /dev/null +++ b/board/freescale/common/i2c_mux.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2014 Freescale Semiconductor, Inc. + * Copyright 2020-21 NXP + * Copyright 2021 Microsoft Corporation + */ + +#ifndef __NXP_I2C_MUX_H__ +#define __NXP_I2C_MUX_H__ + +#ifdef CONFIG_FSL_USE_PCA9547_MUX +int select_i2c_ch_pca9547(u8 ch, int bus); +#endif + +#endif diff --git a/board/freescale/common/vid.c b/board/freescale/common/vid.c index 13ef101e7f..d2c9bbbfe9 100644 --- a/board/freescale/common/vid.c +++ b/board/freescale/common/vid.c @@ -20,8 +20,13 @@ #include #endif #include +#include "i2c_common.h" #include "vid.h" +#ifndef I2C_VOL_MONITOR_BUS +#define I2C_VOL_MONITOR_BUS 0 +#endif + /* Voltages are generally handled in mV to keep them as integers */ #define MV_PER_V 1000 @@ -95,44 +100,6 @@ u16 __weak soc_get_fuse_vid(int vid_index) #define I2C_VOL_MONITOR_ADDR 0 #endif -#if CONFIG_IS_ENABLED(DM_I2C) -#define DEVICE_HANDLE_T struct udevice * - -#ifndef I2C_VOL_MONITOR_BUS -#define I2C_VOL_MONITOR_BUS 0 -#endif - -/* If DM is in use, retrieve the udevice chip for the specified bus number */ -static int vid_get_device(int address, DEVICE_HANDLE_T *dev) -{ - int ret = i2c_get_chip_for_busnum(I2C_VOL_MONITOR_BUS, address, 1, dev); - - if (ret) - printf("VID: Bus %d has no device with address 0x%02X\n", - I2C_VOL_MONITOR_BUS, address); - return ret; -} - -#define I2C_READ(dev, register, data, length) \ - dm_i2c_read(dev, register, data, length) -#define I2C_WRITE(dev, register, data, length) \ - dm_i2c_write(dev, register, data, length) -#else -#define DEVICE_HANDLE_T int - -/* If DM is not in use, I2C addresses are passed directly */ -static int vid_get_device(int address, DEVICE_HANDLE_T *dev) -{ - *dev = address; - return 0; -} - -#define I2C_READ(dev, register, data, length) \ - i2c_read(dev, register, 1, data, length) -#define I2C_WRITE(dev, register, data, length) \ - i2c_write(dev, register, 1, data, length) -#endif - #if defined(CONFIG_VOL_MONITOR_IR36021_SET) || \ defined(CONFIG_VOL_MONITOR_IR36021_READ) /* @@ -158,7 +125,7 @@ static int find_ir_chip_on_i2c(void) /* Check all the address */ for (i = 0; i < (sizeof(ir_i2c_addr)/sizeof(ir_i2c_addr[0])); i++) { i2caddress = ir_i2c_addr[i]; - ret = vid_get_device(i2caddress, &dev); + ret = fsl_i2c_get_device(i2caddress, I2C_VOL_MONITOR_BUS, &dev); if (!ret) { ret = I2C_READ(dev, IR36021_MFR_ID_OFFSET, (void *)&mfrID, sizeof(mfrID)); @@ -202,7 +169,7 @@ static int read_voltage_from_INA220(int i2caddress) DEVICE_HANDLE_T dev; /* Open device handle */ - ret = vid_get_device(i2caddress, &dev); + ret = fsl_i2c_get_device(i2caddress, I2C_VOL_MONITOR_BUS, &dev); if (ret) return ret; @@ -243,7 +210,7 @@ static int read_voltage_from_IR(int i2caddress) DEVICE_HANDLE_T dev; /* Open device handle */ - ret = vid_get_device(i2caddress, &dev); + ret = fsl_i2c_get_device(i2caddress, I2C_VOL_MONITOR_BUS, &dev); if (ret) return ret; @@ -344,7 +311,7 @@ static int read_voltage_from_pmbus(int i2caddress) DEVICE_HANDLE_T dev; /* Open device handle */ - ret = vid_get_device(i2caddress, &dev); + ret = fsl_i2c_get_device(i2caddress, I2C_VOL_MONITOR_BUS, &dev); if (ret) return ret; @@ -457,7 +424,7 @@ static int set_voltage_to_IR(int i2caddress, int vdd) DEVICE_HANDLE_T dev; /* Open device handle */ - ret = vid_get_device(i2caddress, &dev); + ret = fsl_i2c_get_device(i2caddress, I2C_VOL_MONITOR_BUS, &dev); if (ret) return ret; @@ -503,7 +470,7 @@ static int set_voltage_to_pmbus(int i2caddress, int vdd) DEVICE_HANDLE_T dev; /* Open device handle */ - ret = vid_get_device(i2caddress, &dev); + ret = fsl_i2c_get_device(i2caddress, I2C_VOL_MONITOR_BUS, &dev); if (ret) return ret; @@ -653,7 +620,7 @@ int adjust_vdd(ulong vdd_override) debug("VID: IR Chip found on I2C address 0x%02x\n", i2caddress); } - ret = vid_get_device(i2caddress, &dev); + ret = fsl_i2c_get_device(i2caddress, I2C_VOL_MONITOR_BUS, &dev); if (ret) return ret; @@ -785,7 +752,6 @@ exit: i2c_multiplexer_select_vid_channel(I2C_MUX_CH_DEFAULT); return ret < 0 ? -1 : 0; - } static int do_vdd_override(struct cmd_tbl *cmdtp, -- 2.39.5