mirror of
				https://github.com/smaeul/u-boot.git
				synced 2025-11-04 05:50:17 +00:00 
			
		
		
		
	Merge tag 'i2cfixes-for-v2024-01-rc2' of https://source.denx.de/u-boot/custodians/u-boot-i2c
i2c updates for v2024.01-rc2 - nuvoton: support standard/fast/fast plus mode - bootcount: remove legacy i2c driver and implement DM based version Bugfixes: - designware_i2c: adjust timing calculation SPL probing failed on the StarFive VisionFive 2 board Heinrich fixed this, by syncing timing calculation with linux implementation.
This commit is contained in:
		
						commit
						07fe79c93c
					
				@ -79,14 +79,6 @@ config BOOTCOUNT_RAM
 | 
			
		||||
	  Store the bootcount in DRAM protected against bit errors
 | 
			
		||||
	  due to short power loss or holding a system in RESET.
 | 
			
		||||
 | 
			
		||||
config BOOTCOUNT_I2C
 | 
			
		||||
	bool "Boot counter on I2C device"
 | 
			
		||||
	help
 | 
			
		||||
	  Enable support for the bootcounter on an i2c (like RTC) device.
 | 
			
		||||
	  CFG_SYS_I2C_RTC_ADDR = i2c chip address
 | 
			
		||||
	  CONFIG_SYS_BOOTCOUNT_ADDR = i2c addr which is used for
 | 
			
		||||
	                              the bootcounter.
 | 
			
		||||
 | 
			
		||||
config BOOTCOUNT_AT91
 | 
			
		||||
	bool "Boot counter for Atmel AT91SAM9XE"
 | 
			
		||||
	depends on AT91SAM9XE
 | 
			
		||||
@ -117,6 +109,16 @@ config DM_BOOTCOUNT_RTC
 | 
			
		||||
	  Accesses to the backing store are performed using the write16
 | 
			
		||||
	  and read16 ops of DM RTC devices.
 | 
			
		||||
 | 
			
		||||
config DM_BOOTCOUNT_I2C
 | 
			
		||||
	bool "Driver Model boot counter on I2C device"
 | 
			
		||||
	depends on DM_I2C
 | 
			
		||||
	help
 | 
			
		||||
	  Enable support for the bootcounter on a generic i2c device, like a RTC
 | 
			
		||||
	  or PMIC. The bootcounter is configured in the device tree using the
 | 
			
		||||
	  "u-boot,bootcount-i2c" compatible string. It requires a phandle
 | 
			
		||||
	  'i2cbcdev' for the i2c device and an 'offset' property used within the
 | 
			
		||||
	  device.
 | 
			
		||||
 | 
			
		||||
config DM_BOOTCOUNT_I2C_EEPROM
 | 
			
		||||
	bool "Support i2c eeprom devices as a backing store for bootcount"
 | 
			
		||||
	depends on I2C_EEPROM
 | 
			
		||||
@ -175,14 +177,6 @@ config BOOTCOUNT_BOOTLIMIT
 | 
			
		||||
	  counter being cleared.
 | 
			
		||||
	  If set to 0, do not set a boot limit in the environment.
 | 
			
		||||
 | 
			
		||||
config BOOTCOUNT_ALEN
 | 
			
		||||
	int "I2C address length"
 | 
			
		||||
	default 1
 | 
			
		||||
	depends on BOOTCOUNT_I2C
 | 
			
		||||
	help
 | 
			
		||||
	  Length of the the I2C address at SYS_BOOTCOUNT_ADDR for storing
 | 
			
		||||
	  the boot counter.
 | 
			
		||||
 | 
			
		||||
config SYS_BOOTCOUNT_SINGLEWORD
 | 
			
		||||
	bool "Use single word to pack boot count and magic value"
 | 
			
		||||
	depends on BOOTCOUNT_GENERIC
 | 
			
		||||
@ -218,7 +212,7 @@ config SYS_BOOTCOUNT_ADDR
 | 
			
		||||
	default 0x44E3E000 if BOOTCOUNT_AM33XX || BOOTCOUNT_AM33XX_NVMEM
 | 
			
		||||
	default 0xE0115FF8 if ARCH_LS1043A || ARCH_LS1021A
 | 
			
		||||
	depends on BOOTCOUNT_AM33XX || BOOTCOUNT_GENERIC || BOOTCOUNT_EXT || \
 | 
			
		||||
		   BOOTCOUNT_I2C || BOOTCOUNT_AM33XX_NVMEM
 | 
			
		||||
		   BOOTCOUNT_AM33XX_NVMEM
 | 
			
		||||
	help
 | 
			
		||||
	  Set the address used for reading and writing the boot counter.
 | 
			
		||||
 | 
			
		||||
@ -226,13 +220,11 @@ config SYS_BOOTCOUNT_MAGIC
 | 
			
		||||
	hex "Magic value for the boot counter"
 | 
			
		||||
	default 0xB001C041 if BOOTCOUNT_GENERIC || BOOTCOUNT_EXT || \
 | 
			
		||||
			      BOOTCOUNT_AM33XX || BOOTCOUNT_ENV || \
 | 
			
		||||
			      BOOTCOUNT_RAM || BOOTCOUNT_I2C || \
 | 
			
		||||
			      BOOTCOUNT_AT91 || DM_BOOTCOUNT
 | 
			
		||||
			      BOOTCOUNT_RAM || BOOTCOUNT_AT91 || DM_BOOTCOUNT
 | 
			
		||||
	default 0xB0 if BOOTCOUNT_AM33XX_NVMEM
 | 
			
		||||
	depends on BOOTCOUNT_GENERIC || BOOTCOUNT_EXT || \
 | 
			
		||||
		   BOOTCOUNT_AM33XX || BOOTCOUNT_ENV || \
 | 
			
		||||
		   BOOTCOUNT_RAM || BOOTCOUNT_I2C || \
 | 
			
		||||
		   BOOTCOUNT_AT91 || DM_BOOTCOUNT || \
 | 
			
		||||
		   BOOTCOUNT_RAM || BOOTCOUNT_AT91 || DM_BOOTCOUNT || \
 | 
			
		||||
		   BOOTCOUNT_AM33XX_NVMEM
 | 
			
		||||
	help
 | 
			
		||||
	  Set the magic value used for the boot counter.
 | 
			
		||||
 | 
			
		||||
@ -6,7 +6,6 @@ obj-$(CONFIG_BOOTCOUNT_AT91)	+= bootcount_at91.o
 | 
			
		||||
obj-$(CONFIG_BOOTCOUNT_AM33XX)	+= bootcount_davinci.o
 | 
			
		||||
obj-$(CONFIG_BOOTCOUNT_RAM)	+= bootcount_ram.o
 | 
			
		||||
obj-$(CONFIG_BOOTCOUNT_ENV)	+= bootcount_env.o
 | 
			
		||||
obj-$(CONFIG_BOOTCOUNT_I2C)	+= bootcount_i2c.o
 | 
			
		||||
obj-$(CONFIG_BOOTCOUNT_EXT)	+= bootcount_ext.o
 | 
			
		||||
obj-$(CONFIG_BOOTCOUNT_AM33XX_NVMEM)	+= bootcount_nvmem.o
 | 
			
		||||
 | 
			
		||||
@ -14,5 +13,6 @@ obj-$(CONFIG_DM_BOOTCOUNT)      += bootcount-uclass.o
 | 
			
		||||
obj-$(CONFIG_DM_BOOTCOUNT_PMIC_PFUZE100) += pmic_pfuze100.o
 | 
			
		||||
obj-$(CONFIG_DM_BOOTCOUNT_RTC)  += rtc.o
 | 
			
		||||
obj-$(CONFIG_DM_BOOTCOUNT_I2C_EEPROM)	+= i2c-eeprom.o
 | 
			
		||||
obj-$(CONFIG_DM_BOOTCOUNT_I2C)	+= bootcount_dm_i2c.o
 | 
			
		||||
obj-$(CONFIG_DM_BOOTCOUNT_SPI_FLASH)	+= spi-flash.o
 | 
			
		||||
obj-$(CONFIG_DM_BOOTCOUNT_SYSCON) += bootcount_syscon.o
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										102
									
								
								drivers/bootcount/bootcount_dm_i2c.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								drivers/bootcount/bootcount_dm_i2c.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,102 @@
 | 
			
		||||
// SPDX-License-Identifier: GPL-2.0+
 | 
			
		||||
/*
 | 
			
		||||
 * (C) Copyright 2023
 | 
			
		||||
 * Philip Richard Oberfichtner <pro@denx.de>
 | 
			
		||||
 *
 | 
			
		||||
 * Based on previous work from Heiko Schocher (legacy bootcount_i2c.c driver)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <bootcount.h>
 | 
			
		||||
#include <dm.h>
 | 
			
		||||
#include <i2c.h>
 | 
			
		||||
 | 
			
		||||
#define BC_MAGIC	0x55
 | 
			
		||||
 | 
			
		||||
struct bootcount_i2c_priv {
 | 
			
		||||
	struct udevice *bcdev;
 | 
			
		||||
	unsigned int offset;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static int bootcount_i2c_set(struct udevice *dev, const u32 val)
 | 
			
		||||
{
 | 
			
		||||
	int ret;
 | 
			
		||||
	struct bootcount_i2c_priv *priv = dev_get_priv(dev);
 | 
			
		||||
 | 
			
		||||
	ret = dm_i2c_reg_write(priv->bcdev, priv->offset, BC_MAGIC);
 | 
			
		||||
	if (ret < 0)
 | 
			
		||||
		goto err_exit;
 | 
			
		||||
 | 
			
		||||
	ret = dm_i2c_reg_write(priv->bcdev, priv->offset + 1, val & 0xff);
 | 
			
		||||
	if (ret < 0)
 | 
			
		||||
		goto err_exit;
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
 | 
			
		||||
err_exit:
 | 
			
		||||
	log_debug("%s: Error writing to I2C device (%d)\n", __func__, ret);
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int bootcount_i2c_get(struct udevice *dev, u32 *val)
 | 
			
		||||
{
 | 
			
		||||
	int ret;
 | 
			
		||||
	struct bootcount_i2c_priv *priv = dev_get_priv(dev);
 | 
			
		||||
 | 
			
		||||
	ret = dm_i2c_reg_read(priv->bcdev, priv->offset);
 | 
			
		||||
	if (ret < 0)
 | 
			
		||||
		goto err_exit;
 | 
			
		||||
 | 
			
		||||
	if ((ret & 0xff) != BC_MAGIC) {
 | 
			
		||||
		log_debug("%s: Invalid Magic, reset bootcounter.\n", __func__);
 | 
			
		||||
		*val = 0;
 | 
			
		||||
		return bootcount_i2c_set(dev, 0);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ret = dm_i2c_reg_read(priv->bcdev, priv->offset + 1);
 | 
			
		||||
	if (ret < 0)
 | 
			
		||||
		goto err_exit;
 | 
			
		||||
 | 
			
		||||
	*val = ret;
 | 
			
		||||
	return 0;
 | 
			
		||||
 | 
			
		||||
err_exit:
 | 
			
		||||
	log_debug("%s: Error reading from I2C device (%d)\n", __func__, ret);
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static int bootcount_i2c_probe(struct udevice *dev)
 | 
			
		||||
{
 | 
			
		||||
	struct bootcount_i2c_priv *priv = dev_get_priv(dev);
 | 
			
		||||
	int ret;
 | 
			
		||||
 | 
			
		||||
	ret = dev_read_u32(dev, "offset", &priv->offset);
 | 
			
		||||
	if (ret)
 | 
			
		||||
		goto exit;
 | 
			
		||||
 | 
			
		||||
	ret = i2c_get_chip_by_phandle(dev, "i2cbcdev", &priv->bcdev);
 | 
			
		||||
 | 
			
		||||
exit:
 | 
			
		||||
	if (ret)
 | 
			
		||||
		log_debug("%s failed, ret = %d\n", __func__, ret);
 | 
			
		||||
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static const struct bootcount_ops bootcount_i2c_ops = {
 | 
			
		||||
	.get = bootcount_i2c_get,
 | 
			
		||||
	.set = bootcount_i2c_set,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
static const struct udevice_id bootcount_i2c_ids[] = {
 | 
			
		||||
	{ .compatible = "u-boot,bootcount-i2c" },
 | 
			
		||||
	{ }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
U_BOOT_DRIVER(bootcount_i2c) = {
 | 
			
		||||
	.name		= "bootcount-i2c",
 | 
			
		||||
	.id		= UCLASS_BOOTCOUNT,
 | 
			
		||||
	.priv_auto	= sizeof(struct bootcount_i2c_priv),
 | 
			
		||||
	.probe		= bootcount_i2c_probe,
 | 
			
		||||
	.of_match	= bootcount_i2c_ids,
 | 
			
		||||
	.ops		= &bootcount_i2c_ops,
 | 
			
		||||
};
 | 
			
		||||
@ -1,43 +0,0 @@
 | 
			
		||||
// SPDX-License-Identifier: GPL-2.0+
 | 
			
		||||
/*
 | 
			
		||||
 * (C) Copyright 2013
 | 
			
		||||
 * Heiko Schocher, DENX Software Engineering, hs@denx.de.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <bootcount.h>
 | 
			
		||||
#include <linux/compiler.h>
 | 
			
		||||
#include <i2c.h>
 | 
			
		||||
 | 
			
		||||
#define BC_MAGIC	0xbc
 | 
			
		||||
 | 
			
		||||
void bootcount_store(ulong a)
 | 
			
		||||
{
 | 
			
		||||
	unsigned char buf[3];
 | 
			
		||||
	int ret;
 | 
			
		||||
 | 
			
		||||
	buf[0] = BC_MAGIC;
 | 
			
		||||
	buf[1] = (a & 0xff);
 | 
			
		||||
	ret = i2c_write(CFG_SYS_I2C_RTC_ADDR, CONFIG_SYS_BOOTCOUNT_ADDR,
 | 
			
		||||
		  CONFIG_BOOTCOUNT_ALEN, buf, 2);
 | 
			
		||||
	if (ret != 0)
 | 
			
		||||
		puts("Error writing bootcount\n");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ulong bootcount_load(void)
 | 
			
		||||
{
 | 
			
		||||
	unsigned char buf[3];
 | 
			
		||||
	int ret;
 | 
			
		||||
 | 
			
		||||
	ret = i2c_read(CFG_SYS_I2C_RTC_ADDR, CONFIG_SYS_BOOTCOUNT_ADDR,
 | 
			
		||||
		       CONFIG_BOOTCOUNT_ALEN, buf, 2);
 | 
			
		||||
	if (ret != 0) {
 | 
			
		||||
		puts("Error loading bootcount\n");
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
	if (buf[0] == BC_MAGIC)
 | 
			
		||||
		return buf[1];
 | 
			
		||||
 | 
			
		||||
	bootcount_store(0);
 | 
			
		||||
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
@ -24,6 +24,17 @@
 | 
			
		||||
 */
 | 
			
		||||
#define DW_I2C_COMP_TYPE	0x44570140
 | 
			
		||||
 | 
			
		||||
/*
 | 
			
		||||
 * This constant is used to calculate when during the clock high phase the data
 | 
			
		||||
 * bit shall be read. The value was copied from the Linux v6.5 function
 | 
			
		||||
 * i2c_dw_scl_hcnt() which provides the following explanation:
 | 
			
		||||
 *
 | 
			
		||||
 * "This is just an experimental rule: the tHD;STA period turned out to be
 | 
			
		||||
 * proportinal to (_HCNT + 3). With this setting, we could meet both tHIGH and
 | 
			
		||||
 * tHD;STA timing specs."
 | 
			
		||||
 */
 | 
			
		||||
#define T_HD_STA_OFFSET 3
 | 
			
		||||
 | 
			
		||||
static int dw_i2c_enable(struct i2c_regs *i2c_base, bool enable)
 | 
			
		||||
{
 | 
			
		||||
	u32 ena = enable ? IC_ENABLE_0B : 0;
 | 
			
		||||
@ -155,10 +166,10 @@ static int dw_i2c_calc_timing(struct dw_i2c *priv, enum i2c_speed_mode mode,
 | 
			
		||||
 | 
			
		||||
	/*
 | 
			
		||||
	 * Back-solve for hcnt and lcnt according to the following equations:
 | 
			
		||||
	 * SCL_High_time = [(HCNT + IC_*_SPKLEN + 7) * ic_clk] + SCL_Fall_time
 | 
			
		||||
	 * SCL_High_time = [(HCNT + IC_*_SPKLEN + T_HD_STA_OFFSET) * ic_clk] + SCL_Fall_time
 | 
			
		||||
	 * SCL_Low_time = [(LCNT + 1) * ic_clk] - SCL_Fall_time + SCL_Rise_time
 | 
			
		||||
	 */
 | 
			
		||||
	hcnt = min_thigh_cnt - fall_cnt - 7 - spk_cnt;
 | 
			
		||||
	hcnt = min_thigh_cnt - fall_cnt - T_HD_STA_OFFSET - spk_cnt;
 | 
			
		||||
	lcnt = min_tlow_cnt - rise_cnt + fall_cnt - 1;
 | 
			
		||||
 | 
			
		||||
	if (hcnt < 0 || lcnt < 0) {
 | 
			
		||||
@ -170,13 +181,13 @@ static int dw_i2c_calc_timing(struct dw_i2c *priv, enum i2c_speed_mode mode,
 | 
			
		||||
	 * Now add things back up to ensure the period is hit. If it is off,
 | 
			
		||||
	 * split the difference and bias to lcnt for remainder
 | 
			
		||||
	 */
 | 
			
		||||
	tot = hcnt + lcnt + 7 + spk_cnt + rise_cnt + 1;
 | 
			
		||||
	tot = hcnt + lcnt + T_HD_STA_OFFSET + spk_cnt + rise_cnt + 1;
 | 
			
		||||
 | 
			
		||||
	if (tot < period_cnt) {
 | 
			
		||||
		diff = (period_cnt - tot) / 2;
 | 
			
		||||
		hcnt += diff;
 | 
			
		||||
		lcnt += diff;
 | 
			
		||||
		tot = hcnt + lcnt + 7 + spk_cnt + rise_cnt + 1;
 | 
			
		||||
		tot = hcnt + lcnt + T_HD_STA_OFFSET + spk_cnt + rise_cnt + 1;
 | 
			
		||||
		lcnt += period_cnt - tot;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -388,6 +388,81 @@ int i2c_get_chip_for_busnum(int busnum, int chip_addr, uint offset_len,
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/* Find and probe I2C bus based on a chip attached to it */
 | 
			
		||||
static int i2c_get_parent_bus(ofnode chip, struct udevice **devp)
 | 
			
		||||
{
 | 
			
		||||
	ofnode node;
 | 
			
		||||
	struct udevice *dev;
 | 
			
		||||
	int ret;
 | 
			
		||||
 | 
			
		||||
	node = ofnode_get_parent(chip);
 | 
			
		||||
	if (!ofnode_valid(node))
 | 
			
		||||
		return -ENODEV;
 | 
			
		||||
 | 
			
		||||
	ret = uclass_get_device_by_ofnode(UCLASS_I2C, node, &dev);
 | 
			
		||||
	if (ret) {
 | 
			
		||||
		*devp = NULL;
 | 
			
		||||
		return ret;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	*devp = dev;
 | 
			
		||||
	return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int i2c_get_chip_by_phandle(const struct udevice *parent, const char *prop_name,
 | 
			
		||||
			    struct udevice **devp)
 | 
			
		||||
{
 | 
			
		||||
	ofnode node;
 | 
			
		||||
	uint phandle;
 | 
			
		||||
	struct udevice *bus, *chip;
 | 
			
		||||
	char *dev_name;
 | 
			
		||||
	int ret;
 | 
			
		||||
 | 
			
		||||
	debug("%s: Searching I2C chip for phandle \"%s\"\n",
 | 
			
		||||
	      __func__, prop_name);
 | 
			
		||||
 | 
			
		||||
	dev_name = strdup(prop_name);
 | 
			
		||||
	if (!dev_name) {
 | 
			
		||||
		ret = -ENOMEM;
 | 
			
		||||
		goto err_exit;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ret = dev_read_u32(parent, "i2cbcdev", &phandle);
 | 
			
		||||
	if (ret)
 | 
			
		||||
		goto err_exit;
 | 
			
		||||
 | 
			
		||||
	node = ofnode_get_by_phandle(phandle);
 | 
			
		||||
	if (!ofnode_valid(node)) {
 | 
			
		||||
		ret = -ENODEV;
 | 
			
		||||
		goto err_exit;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ret = i2c_get_parent_bus(node, &bus);
 | 
			
		||||
	if (ret)
 | 
			
		||||
		goto err_exit;
 | 
			
		||||
 | 
			
		||||
	ret = device_bind_driver_to_node(bus, "i2c_generic_chip_drv",
 | 
			
		||||
					 dev_name, node, &chip);
 | 
			
		||||
	if (ret)
 | 
			
		||||
		goto err_exit;
 | 
			
		||||
 | 
			
		||||
	ret = device_probe(chip);
 | 
			
		||||
	if (ret) {
 | 
			
		||||
		device_unbind(chip);
 | 
			
		||||
		goto err_exit;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	debug("%s succeeded\n", __func__);
 | 
			
		||||
	*devp = chip;
 | 
			
		||||
	return 0;
 | 
			
		||||
 | 
			
		||||
err_exit:
 | 
			
		||||
	free(dev_name);
 | 
			
		||||
	debug("%s failed, ret = %d\n", __func__, ret);
 | 
			
		||||
	*devp = NULL;
 | 
			
		||||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int dm_i2c_probe(struct udevice *bus, uint chip_addr, uint chip_flags,
 | 
			
		||||
		 struct udevice **devp)
 | 
			
		||||
{
 | 
			
		||||
 | 
			
		||||
@ -517,11 +517,6 @@ static int npcm_i2c_init_clk(struct npcm_i2c_bus *bus, u32 bus_freq)
 | 
			
		||||
	u32 sclfrq;
 | 
			
		||||
	u8 hldt, val;
 | 
			
		||||
 | 
			
		||||
	if (bus_freq > I2C_FREQ_100K) {
 | 
			
		||||
		printf("Support standard mode only\n");
 | 
			
		||||
		return -EINVAL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* SCLFRQ = T(SCL)/4/T(CLK) = FREQ(CLK)/4/FREQ(SCL) */
 | 
			
		||||
	sclfrq = freq / (bus_freq * 4);
 | 
			
		||||
	if (sclfrq < SCLFRQ_MIN || sclfrq > SCLFRQ_MAX)
 | 
			
		||||
 | 
			
		||||
@ -537,6 +537,18 @@ int i2c_get_chip(struct udevice *bus, uint chip_addr, uint offset_len,
 | 
			
		||||
int i2c_get_chip_for_busnum(int busnum, int chip_addr, uint offset_len,
 | 
			
		||||
			    struct udevice **devp);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * i2c_get_chip_by_phandle() - get a device to use to access a chip
 | 
			
		||||
 *			       based on a phandle property pointing to it
 | 
			
		||||
 *
 | 
			
		||||
 * @parent: Parent device containing the phandle pointer
 | 
			
		||||
 * @name:   Name of phandle property in the parent device node
 | 
			
		||||
 * @devp:   Returns pointer to new device or NULL if not found
 | 
			
		||||
 * Return:  0 on success, -ve on failure
 | 
			
		||||
 */
 | 
			
		||||
int i2c_get_chip_by_phandle(const struct udevice *parent, const char *prop_name,
 | 
			
		||||
			    struct udevice **devp);
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * i2c_chip_of_to_plat() - Decode standard I2C platform data
 | 
			
		||||
 *
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user