Merge branch 'master' of git://git.denx.de/u-boot-i2c
- DM_I2C_COMPAT removal for all ti platforms from Jean-Jacques Hiblot - Fix in i2c command help output from Chirstoph Muellner.
This commit is contained in:
commit
7ff485c68b
@ -36,3 +36,7 @@
|
||||
&phy_sel {
|
||||
u-boot,dm-spl;
|
||||
};
|
||||
|
||||
&i2c0 {
|
||||
u-boot,dm-spl;
|
||||
};
|
||||
|
@ -95,3 +95,7 @@
|
||||
&gpio7 {
|
||||
u-boot,dm-spl;
|
||||
};
|
||||
|
||||
&i2c1 {
|
||||
u-boot,dm-spl;
|
||||
};
|
||||
|
@ -6,57 +6,14 @@
|
||||
#ifndef _I2C_AM33XX_H_
|
||||
#define _I2C_AM33XX_H_
|
||||
|
||||
#include <asm/omap_i2c.h>
|
||||
|
||||
#define I2C_BASE1 0x44E0B000
|
||||
#define I2C_BASE2 0x4802A000
|
||||
#define I2C_BASE3 0x4819C000
|
||||
|
||||
#define I2C_DEFAULT_BASE I2C_BASE1
|
||||
|
||||
struct i2c {
|
||||
unsigned short revnb_lo; /* 0x00 */
|
||||
unsigned short res1;
|
||||
unsigned short revnb_hi; /* 0x04 */
|
||||
unsigned short res2[5];
|
||||
unsigned short sysc; /* 0x10 */
|
||||
unsigned short res3[9];
|
||||
unsigned short irqstatus_raw; /* 0x24 */
|
||||
unsigned short res4;
|
||||
unsigned short stat; /* 0x28 */
|
||||
unsigned short res5;
|
||||
unsigned short ie; /* 0x2C */
|
||||
unsigned short res6;
|
||||
unsigned short irqenable_clr; /* 0x30 */
|
||||
unsigned short res7;
|
||||
unsigned short iv; /* 0x34 */
|
||||
unsigned short res8[45];
|
||||
unsigned short syss; /* 0x90 */
|
||||
unsigned short res9;
|
||||
unsigned short buf; /* 0x94 */
|
||||
unsigned short res10;
|
||||
unsigned short cnt; /* 0x98 */
|
||||
unsigned short res11;
|
||||
unsigned short data; /* 0x9C */
|
||||
unsigned short res13;
|
||||
unsigned short res14; /* 0xA0 */
|
||||
unsigned short res15;
|
||||
unsigned short con; /* 0xA4 */
|
||||
unsigned short res16;
|
||||
unsigned short oa; /* 0xA8 */
|
||||
unsigned short res17;
|
||||
unsigned short sa; /* 0xAC */
|
||||
unsigned short res18;
|
||||
unsigned short psc; /* 0xB0 */
|
||||
unsigned short res19;
|
||||
unsigned short scll; /* 0xB4 */
|
||||
unsigned short res20;
|
||||
unsigned short sclh; /* 0xB8 */
|
||||
unsigned short res21;
|
||||
unsigned short systest; /* 0xBC */
|
||||
unsigned short res22;
|
||||
unsigned short bufstat; /* 0xC0 */
|
||||
unsigned short res23;
|
||||
};
|
||||
|
||||
#define I2C_IP_CLK 48000000
|
||||
#define I2C_INTERNAL_SAMPLING_CLK 12000000
|
||||
|
||||
|
@ -8,51 +8,4 @@
|
||||
|
||||
#define I2C_DEFAULT_BASE I2C_BASE1
|
||||
|
||||
struct i2c {
|
||||
unsigned short rev; /* 0x00 */
|
||||
unsigned short res1;
|
||||
unsigned short ie; /* 0x04 */
|
||||
unsigned short res2;
|
||||
unsigned short stat; /* 0x08 */
|
||||
unsigned short res3;
|
||||
unsigned short we; /* 0x0C */
|
||||
unsigned short res4;
|
||||
unsigned short syss; /* 0x10 */
|
||||
unsigned short res4a;
|
||||
unsigned short buf; /* 0x14 */
|
||||
unsigned short res5;
|
||||
unsigned short cnt; /* 0x18 */
|
||||
unsigned short res6;
|
||||
unsigned short data; /* 0x1C */
|
||||
unsigned short res7;
|
||||
unsigned short sysc; /* 0x20 */
|
||||
unsigned short res8;
|
||||
unsigned short con; /* 0x24 */
|
||||
unsigned short res9;
|
||||
unsigned short oa; /* 0x28 */
|
||||
unsigned short res10;
|
||||
unsigned short sa; /* 0x2C */
|
||||
unsigned short res11;
|
||||
unsigned short psc; /* 0x30 */
|
||||
unsigned short res12;
|
||||
unsigned short scll; /* 0x34 */
|
||||
unsigned short res13;
|
||||
unsigned short sclh; /* 0x38 */
|
||||
unsigned short res14;
|
||||
unsigned short systest; /* 0x3c */
|
||||
unsigned short res15;
|
||||
unsigned short bufstat; /* 0x40 */
|
||||
unsigned short res16;
|
||||
unsigned short oa1; /* 0x44 */
|
||||
unsigned short res17;
|
||||
unsigned short oa2; /* 0x48 */
|
||||
unsigned short res18;
|
||||
unsigned short oa3; /* 0x4c */
|
||||
unsigned short res19;
|
||||
unsigned short actoa; /* 0x50 */
|
||||
unsigned short res20;
|
||||
unsigned short sblock; /* 0x54 */
|
||||
unsigned short res21;
|
||||
};
|
||||
|
||||
#endif /* _OMAP3_I2C_H_ */
|
||||
|
@ -8,49 +8,4 @@
|
||||
|
||||
#define I2C_DEFAULT_BASE I2C_BASE1
|
||||
|
||||
struct i2c {
|
||||
unsigned short revnb_lo; /* 0x00 */
|
||||
unsigned short res1;
|
||||
unsigned short revnb_hi; /* 0x04 */
|
||||
unsigned short res2[5];
|
||||
unsigned short sysc; /* 0x10 */
|
||||
unsigned short res3[9];
|
||||
unsigned short irqstatus_raw; /* 0x24 */
|
||||
unsigned short res4;
|
||||
unsigned short stat; /* 0x28 */
|
||||
unsigned short res5;
|
||||
unsigned short ie; /* 0x2C */
|
||||
unsigned short res6;
|
||||
unsigned short irqenable_clr; /* 0x30 */
|
||||
unsigned short res7;
|
||||
unsigned short iv; /* 0x34 */
|
||||
unsigned short res8[45];
|
||||
unsigned short syss; /* 0x90 */
|
||||
unsigned short res9;
|
||||
unsigned short buf; /* 0x94 */
|
||||
unsigned short res10;
|
||||
unsigned short cnt; /* 0x98 */
|
||||
unsigned short res11;
|
||||
unsigned short data; /* 0x9C */
|
||||
unsigned short res13;
|
||||
unsigned short res14; /* 0xA0 */
|
||||
unsigned short res15;
|
||||
unsigned short con; /* 0xA4 */
|
||||
unsigned short res16;
|
||||
unsigned short oa; /* 0xA8 */
|
||||
unsigned short res17;
|
||||
unsigned short sa; /* 0xAC */
|
||||
unsigned short res18;
|
||||
unsigned short psc; /* 0xB0 */
|
||||
unsigned short res19;
|
||||
unsigned short scll; /* 0xB4 */
|
||||
unsigned short res20;
|
||||
unsigned short sclh; /* 0xB8 */
|
||||
unsigned short res21;
|
||||
unsigned short systest; /* 0xBC */
|
||||
unsigned short res22;
|
||||
unsigned short bufstat; /* 0xC0 */
|
||||
unsigned short res23;
|
||||
};
|
||||
|
||||
#endif /* _OMAP4_I2C_H_ */
|
||||
|
@ -8,49 +8,4 @@
|
||||
|
||||
#define I2C_DEFAULT_BASE I2C_BASE1
|
||||
|
||||
struct i2c {
|
||||
unsigned short revnb_lo; /* 0x00 */
|
||||
unsigned short res1;
|
||||
unsigned short revnb_hi; /* 0x04 */
|
||||
unsigned short res2[5];
|
||||
unsigned short sysc; /* 0x10 */
|
||||
unsigned short res3[9];
|
||||
unsigned short irqstatus_raw; /* 0x24 */
|
||||
unsigned short res4;
|
||||
unsigned short stat; /* 0x28 */
|
||||
unsigned short res5;
|
||||
unsigned short ie; /* 0x2C */
|
||||
unsigned short res6;
|
||||
unsigned short irqenable_clr; /* 0x30 */
|
||||
unsigned short res7;
|
||||
unsigned short iv; /* 0x34 */
|
||||
unsigned short res8[45];
|
||||
unsigned short syss; /* 0x90 */
|
||||
unsigned short res9;
|
||||
unsigned short buf; /* 0x94 */
|
||||
unsigned short res10;
|
||||
unsigned short cnt; /* 0x98 */
|
||||
unsigned short res11;
|
||||
unsigned short data; /* 0x9C */
|
||||
unsigned short res13;
|
||||
unsigned short res14; /* 0xA0 */
|
||||
unsigned short res15;
|
||||
unsigned short con; /* 0xA4 */
|
||||
unsigned short res16;
|
||||
unsigned short oa; /* 0xA8 */
|
||||
unsigned short res17;
|
||||
unsigned short sa; /* 0xAC */
|
||||
unsigned short res18;
|
||||
unsigned short psc; /* 0xB0 */
|
||||
unsigned short res19;
|
||||
unsigned short scll; /* 0xB4 */
|
||||
unsigned short res20;
|
||||
unsigned short sclh; /* 0xB8 */
|
||||
unsigned short res21;
|
||||
unsigned short systest; /* 0xBC */
|
||||
unsigned short res22;
|
||||
unsigned short bufstat; /* 0xC0 */
|
||||
unsigned short res23;
|
||||
};
|
||||
|
||||
#endif /* _OMAP5_I2C_H_ */
|
||||
|
24
arch/arm/include/asm/omap_i2c.h
Normal file
24
arch/arm/include/asm/omap_i2c.h
Normal file
@ -0,0 +1,24 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
|
||||
#ifndef _OMAP_I2C_H
|
||||
#define _OMAP_I2C_H
|
||||
|
||||
#include <asm/arch/cpu.h>
|
||||
|
||||
#ifdef CONFIG_DM_I2C
|
||||
|
||||
/* Information about a GPIO bank */
|
||||
struct omap_i2c_platdata {
|
||||
ulong base; /* address of registers in physical memory */
|
||||
int speed;
|
||||
int ip_rev;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
enum {
|
||||
OMAP_I2C_REV_V1 = 0,
|
||||
OMAP_I2C_REV_V2 = 1,
|
||||
};
|
||||
|
||||
#endif /* _OMAP_I2C_H */
|
@ -403,6 +403,7 @@ static void init_ddr3param(struct ddr3_spd_cb *spd_cb,
|
||||
static int ddr3_read_spd(ddr3_spd_eeprom_t *spd_params)
|
||||
{
|
||||
int ret;
|
||||
#ifndef CONFIG_DM_I2C
|
||||
int old_bus;
|
||||
|
||||
i2c_init(CONFIG_SYS_DAVINCI_I2C_SPEED, CONFIG_SYS_DAVINCI_I2C_SLAVE);
|
||||
@ -413,7 +414,13 @@ static int ddr3_read_spd(ddr3_spd_eeprom_t *spd_params)
|
||||
ret = i2c_read(0x53, 0, 1, (unsigned char *)spd_params, 256);
|
||||
|
||||
i2c_set_bus_num(old_bus);
|
||||
#else
|
||||
struct udevice *dev;
|
||||
|
||||
ret = i2c_get_chip_for_busnum(1, 0x53, 1, &dev);
|
||||
if (!ret)
|
||||
ret = dm_i2c_read(dev, 0, (unsigned char *)spd_params, 256);
|
||||
#endif
|
||||
if (ret) {
|
||||
printf("Cannot read DIMM params\n");
|
||||
return 1;
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <asm/arch/ddr_defs.h>
|
||||
#include <asm/arch/clock.h>
|
||||
#include <asm/arch/gpio.h>
|
||||
#include <asm/arch/i2c.h>
|
||||
#include <asm/arch/mem.h>
|
||||
#include <asm/arch/mmc_host_def.h>
|
||||
#include <asm/arch/sys_proto.h>
|
||||
@ -93,6 +94,20 @@ U_BOOT_DEVICES(am33xx_uarts) = {
|
||||
# endif
|
||||
};
|
||||
|
||||
#ifdef CONFIG_DM_I2C
|
||||
static const struct omap_i2c_platdata am33xx_i2c[] = {
|
||||
{ I2C_BASE1, 100000, OMAP_I2C_REV_V2},
|
||||
{ I2C_BASE2, 100000, OMAP_I2C_REV_V2},
|
||||
{ I2C_BASE3, 100000, OMAP_I2C_REV_V2},
|
||||
};
|
||||
|
||||
U_BOOT_DEVICES(am33xx_i2c) = {
|
||||
{ "i2c_omap", &am33xx_i2c[0] },
|
||||
{ "i2c_omap", &am33xx_i2c[1] },
|
||||
{ "i2c_omap", &am33xx_i2c[2] },
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DM_GPIO
|
||||
static const struct omap_gpio_platdata am33xx_gpio[] = {
|
||||
{ 0, AM33XX_GPIO0_BASE },
|
||||
@ -457,12 +472,15 @@ void early_system_init(void)
|
||||
#ifdef CONFIG_DEBUG_UART_OMAP
|
||||
debug_uart_init();
|
||||
#endif
|
||||
#ifdef CONFIG_TI_I2C_BOARD_DETECT
|
||||
do_board_detect();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SPL_BUILD
|
||||
spl_early_init();
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_TI_I2C_BOARD_DETECT
|
||||
do_board_detect();
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_SPL_AM33XX_ENABLE_RTC32K_OSC)
|
||||
/* Enable RTC32K clock */
|
||||
rtc32k_enable();
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
/**
|
||||
* clk_synthesizer_reg_read - Read register from synthesizer.
|
||||
* dev: i2c bus device (not used if CONFIG_DM_I2C is not set)
|
||||
* @addr: addr within the i2c device
|
||||
* buf: Buffer to which value is to be read.
|
||||
*
|
||||
@ -21,13 +22,14 @@
|
||||
* be send along with enabling byte read more, and then read can happen.
|
||||
* Returns 0 on success
|
||||
*/
|
||||
static int clk_synthesizer_reg_read(int addr, uint8_t *buf)
|
||||
static int clk_synthesizer_reg_read(struct udevice *dev, int addr, u8 *buf)
|
||||
{
|
||||
int rc;
|
||||
|
||||
/* Enable Bye read */
|
||||
addr = addr | CLK_SYNTHESIZER_BYTE_MODE;
|
||||
|
||||
#ifndef CONFIG_DM_I2C
|
||||
/* Send the command byte */
|
||||
rc = i2c_write(CLK_SYNTHESIZER_I2C_ADDR, addr, 1, buf, 1);
|
||||
if (rc)
|
||||
@ -35,26 +37,46 @@ static int clk_synthesizer_reg_read(int addr, uint8_t *buf)
|
||||
|
||||
/* Read the Data */
|
||||
return i2c_read(CLK_SYNTHESIZER_I2C_ADDR, addr, 1, buf, 1);
|
||||
#else
|
||||
/* Send the command byte */
|
||||
rc = dm_i2c_reg_write(dev, addr, *buf);
|
||||
if (rc)
|
||||
printf("Failed to send command to clock synthesizer\n");
|
||||
|
||||
/* Read the Data */
|
||||
rc = dm_i2c_reg_read(dev, addr);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
|
||||
*buf = (u8)rc;
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* clk_synthesizer_reg_write - Write a value to register in synthesizer.
|
||||
* dev: i2c bus device (not used if CONFIG_DM_I2C is not set)
|
||||
* @addr: addr within the i2c device
|
||||
* val: Value to be written in the addr.
|
||||
*
|
||||
* Enable the byte read mode in the address and start the i2c transfer.
|
||||
* Returns 0 on success
|
||||
*/
|
||||
static int clk_synthesizer_reg_write(int addr, uint8_t val)
|
||||
static int clk_synthesizer_reg_write(struct udevice *dev, int addr, u8 val)
|
||||
{
|
||||
uint8_t cmd[2];
|
||||
u8 cmd[2];
|
||||
int rc = 0;
|
||||
|
||||
/* Enable byte write */
|
||||
cmd[0] = addr | CLK_SYNTHESIZER_BYTE_MODE;
|
||||
cmd[1] = val;
|
||||
|
||||
#ifndef CONFIG_DM_I2C
|
||||
rc = i2c_write(CLK_SYNTHESIZER_I2C_ADDR, addr, 1, cmd, 2);
|
||||
#else
|
||||
rc = dm_i2c_write(dev, addr, cmd, 2);
|
||||
#endif
|
||||
if (rc)
|
||||
printf("Clock synthesizer reg write failed at addr = 0x%x\n",
|
||||
addr);
|
||||
@ -72,30 +94,42 @@ static int clk_synthesizer_reg_write(int addr, uint8_t val)
|
||||
int setup_clock_synthesizer(struct clk_synth *data)
|
||||
{
|
||||
int rc;
|
||||
uint8_t val;
|
||||
|
||||
u8 val = 0;
|
||||
struct udevice *dev = NULL;
|
||||
#ifndef CONFIG_DM_I2C
|
||||
rc = i2c_probe(CLK_SYNTHESIZER_I2C_ADDR);
|
||||
if (rc) {
|
||||
printf("i2c probe failed at address 0x%x\n",
|
||||
CLK_SYNTHESIZER_I2C_ADDR);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = clk_synthesizer_reg_read(CLK_SYNTHESIZER_ID_REG, &val);
|
||||
#else
|
||||
rc = i2c_get_chip_for_busnum(0, CLK_SYNTHESIZER_I2C_ADDR, 1, &dev);
|
||||
if (rc) {
|
||||
printf("failed to get device for synthesizer at address 0x%x\n",
|
||||
CLK_SYNTHESIZER_I2C_ADDR);
|
||||
return rc;
|
||||
}
|
||||
#endif
|
||||
rc = clk_synthesizer_reg_read(dev, CLK_SYNTHESIZER_ID_REG, &val);
|
||||
if (val != data->id)
|
||||
return rc;
|
||||
|
||||
/* Crystal Load capacitor selection */
|
||||
rc = clk_synthesizer_reg_write(CLK_SYNTHESIZER_XCSEL, data->capacitor);
|
||||
rc = clk_synthesizer_reg_write(dev, CLK_SYNTHESIZER_XCSEL,
|
||||
data->capacitor);
|
||||
if (rc)
|
||||
return rc;
|
||||
rc = clk_synthesizer_reg_write(CLK_SYNTHESIZER_MUX_REG, data->mux);
|
||||
rc = clk_synthesizer_reg_write(dev, CLK_SYNTHESIZER_MUX_REG,
|
||||
data->mux);
|
||||
if (rc)
|
||||
return rc;
|
||||
rc = clk_synthesizer_reg_write(CLK_SYNTHESIZER_PDIV2_REG, data->pdiv2);
|
||||
rc = clk_synthesizer_reg_write(dev, CLK_SYNTHESIZER_PDIV2_REG,
|
||||
data->pdiv2);
|
||||
if (rc)
|
||||
return rc;
|
||||
rc = clk_synthesizer_reg_write(CLK_SYNTHESIZER_PDIV3_REG, data->pdiv3);
|
||||
rc = clk_synthesizer_reg_write(dev, CLK_SYNTHESIZER_PDIV3_REG,
|
||||
data->pdiv3);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
|
@ -909,6 +909,7 @@ void prcm_init(void)
|
||||
enable_basic_uboot_clocks();
|
||||
}
|
||||
|
||||
#if !defined(CONFIG_DM_I2C)
|
||||
void gpi2c_init(void)
|
||||
{
|
||||
static int gpi2c = 1;
|
||||
@ -919,3 +920,4 @@ void gpi2c_init(void)
|
||||
gpi2c = 0;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -12,6 +12,7 @@
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <debug_uart.h>
|
||||
#include <fdtdec.h>
|
||||
#include <spl.h>
|
||||
#include <asm/arch/sys_proto.h>
|
||||
#include <linux/sizes.h>
|
||||
@ -19,6 +20,7 @@
|
||||
#include <asm/omap_common.h>
|
||||
#include <linux/compiler.h>
|
||||
#include <asm/system.h>
|
||||
#include <dm/root.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
@ -171,6 +173,10 @@ void __weak init_package_revision(void)
|
||||
*/
|
||||
void early_system_init(void)
|
||||
{
|
||||
#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_MULTI_DTB_FIT)
|
||||
int ret;
|
||||
int rescan;
|
||||
#endif
|
||||
init_omap_revision();
|
||||
hw_data_init();
|
||||
init_package_revision();
|
||||
@ -186,6 +192,7 @@ void early_system_init(void)
|
||||
do_io_settings();
|
||||
#endif
|
||||
setup_early_clocks();
|
||||
|
||||
#ifdef CONFIG_SPL_BUILD
|
||||
/*
|
||||
* Save the boot parameters passed from romcode.
|
||||
@ -193,11 +200,23 @@ void early_system_init(void)
|
||||
* to prevent overwrites.
|
||||
*/
|
||||
save_omap_boot_params();
|
||||
#endif
|
||||
do_board_detect();
|
||||
#ifdef CONFIG_SPL_BUILD
|
||||
spl_early_init();
|
||||
#endif
|
||||
do_board_detect();
|
||||
|
||||
#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_SPL_MULTI_DTB_FIT)
|
||||
/*
|
||||
* Board detection has been done.
|
||||
* Let us see if another dtb wouldn't be a better match
|
||||
* for our board
|
||||
*/
|
||||
ret = fdtdec_resetup(&rescan);
|
||||
if (!ret && rescan) {
|
||||
dm_uninit();
|
||||
dm_init_and_scan(true);
|
||||
}
|
||||
#endif
|
||||
|
||||
vcores_init();
|
||||
#ifdef CONFIG_DEBUG_UART_OMAP
|
||||
debug_uart_init();
|
||||
|
@ -209,7 +209,6 @@ void am33xx_spl_board_init(void)
|
||||
const struct dpll_params *get_dpll_ddr_params(void)
|
||||
{
|
||||
enable_i2c0_pin_mux();
|
||||
i2c_init(CONFIG_SYS_OMAP24_I2C_SPEED, CONFIG_SYS_OMAP24_I2C_SLAVE);
|
||||
|
||||
return &dpll_ddr;
|
||||
}
|
||||
|
@ -70,8 +70,9 @@ static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
|
||||
void do_board_detect(void)
|
||||
{
|
||||
enable_i2c0_pin_mux();
|
||||
#ifndef CONFIG_DM_I2C
|
||||
i2c_init(CONFIG_SYS_OMAP24_I2C_SPEED, CONFIG_SYS_OMAP24_I2C_SLAVE);
|
||||
|
||||
#endif
|
||||
if (ti_i2c_eeprom_am_get(CONFIG_EEPROM_BUS_ADDRESS,
|
||||
CONFIG_EEPROM_CHIP_ADDRESS))
|
||||
printf("ti_i2c_eeprom_init failed\n");
|
||||
@ -328,8 +329,14 @@ static void scale_vcores_bone(int freq)
|
||||
if (board_is_bone() && !strncmp(board_ti_get_rev(), "00A1", 4))
|
||||
return;
|
||||
|
||||
#ifndef CONFIG_DM_I2C
|
||||
if (i2c_probe(TPS65217_CHIP_PM))
|
||||
return;
|
||||
#else
|
||||
if (power_tps65217_init(0))
|
||||
return;
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* On Beaglebone White we need to ensure we have AC power
|
||||
@ -421,9 +428,13 @@ void scale_vcores_generic(int freq)
|
||||
* 1.10V. For MPU voltage we need to switch based on
|
||||
* the frequency we are running at.
|
||||
*/
|
||||
#ifndef CONFIG_DM_I2C
|
||||
if (i2c_probe(TPS65910_CTRL_I2C_ADDR))
|
||||
return;
|
||||
|
||||
#else
|
||||
if (power_tps65910_init(0))
|
||||
return;
|
||||
#endif
|
||||
/*
|
||||
* Depending on MPU clock and PG we will need a different
|
||||
* VDD to drive at that speed.
|
||||
@ -451,8 +462,10 @@ void gpi2c_init(void)
|
||||
|
||||
if (first_time) {
|
||||
enable_i2c0_pin_mux();
|
||||
#ifndef CONFIG_DM_I2C
|
||||
i2c_init(CONFIG_SYS_OMAP24_I2C_SPEED,
|
||||
CONFIG_SYS_OMAP24_I2C_SLAVE);
|
||||
#endif
|
||||
first_time = false;
|
||||
}
|
||||
}
|
||||
|
@ -329,12 +329,23 @@ static unsigned short detect_daughter_board_profile(void)
|
||||
{
|
||||
unsigned short val;
|
||||
|
||||
#ifndef CONFIG_DM_I2C
|
||||
if (i2c_probe(I2C_CPLD_ADDR))
|
||||
return PROFILE_NONE;
|
||||
|
||||
if (i2c_read(I2C_CPLD_ADDR, CFG_REG, 1, (unsigned char *)(&val), 2))
|
||||
return PROFILE_NONE;
|
||||
#else
|
||||
struct udevice *dev = NULL;
|
||||
int rc;
|
||||
|
||||
rc = i2c_get_chip_for_busnum(0, I2C_CPLD_ADDR, 1, &dev);
|
||||
if (rc)
|
||||
return PROFILE_NONE;
|
||||
rc = dm_i2c_read(dev, CFG_REG, (unsigned char *)(&val), 2);
|
||||
if (rc)
|
||||
return PROFILE_NONE;
|
||||
#endif
|
||||
return (1 << (val & PROFILE_MASK));
|
||||
}
|
||||
|
||||
|
@ -43,6 +43,8 @@ static struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
|
||||
#ifdef CONFIG_TI_I2C_BOARD_DETECT
|
||||
void do_board_detect(void)
|
||||
{
|
||||
/* Ensure I2C is initialized for EEPROM access*/
|
||||
gpi2c_init();
|
||||
if (ti_i2c_eeprom_am_get(CONFIG_EEPROM_BUS_ADDRESS,
|
||||
CONFIG_EEPROM_CHIP_ADDRESS))
|
||||
printf("ti_i2c_eeprom_init failed\n");
|
||||
@ -386,8 +388,13 @@ void scale_vcores_generic(u32 m)
|
||||
{
|
||||
int mpu_vdd, ddr_volt;
|
||||
|
||||
#ifndef CONFIG_DM_I2C
|
||||
if (i2c_probe(TPS65218_CHIP_PM))
|
||||
return;
|
||||
#else
|
||||
if (power_tps65218_init(0))
|
||||
return;
|
||||
#endif
|
||||
|
||||
switch (m) {
|
||||
case 1000:
|
||||
@ -439,8 +446,13 @@ void scale_vcores_idk(u32 m)
|
||||
{
|
||||
int mpu_vdd;
|
||||
|
||||
#ifndef CONFIG_DM_I2C
|
||||
if (i2c_probe(TPS62362_I2C_ADDR))
|
||||
return;
|
||||
#else
|
||||
if (power_tps62362_init(0))
|
||||
return;
|
||||
#endif
|
||||
|
||||
switch (m) {
|
||||
case 1000:
|
||||
@ -462,14 +474,12 @@ void scale_vcores_idk(u32 m)
|
||||
puts("Unknown MPU clock, not scaling\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Set VDD_MPU voltage */
|
||||
if (tps62362_voltage_update(TPS62362_SET3, mpu_vdd)) {
|
||||
printf("%s failure\n", __func__);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void gpi2c_init(void)
|
||||
{
|
||||
/* When needed to be invoked prior to BSS initialization */
|
||||
@ -477,8 +487,10 @@ void gpi2c_init(void)
|
||||
|
||||
if (first_time) {
|
||||
enable_i2c0_pin_mux();
|
||||
#ifndef CONFIG_DM_I2C
|
||||
i2c_init(CONFIG_SYS_OMAP24_I2C_SPEED,
|
||||
CONFIG_SYS_OMAP24_I2C_SLAVE);
|
||||
#endif
|
||||
first_time = false;
|
||||
}
|
||||
}
|
||||
@ -614,20 +626,32 @@ void sdram_init(void)
|
||||
/* setup board specific PMIC */
|
||||
int power_init_board(void)
|
||||
{
|
||||
struct pmic *p;
|
||||
|
||||
int rc;
|
||||
#ifndef CONFIG_DM_I2C
|
||||
struct pmic *p = NULL;
|
||||
#endif
|
||||
if (board_is_idk()) {
|
||||
power_tps62362_init(I2C_PMIC);
|
||||
rc = power_tps62362_init(0);
|
||||
if (rc)
|
||||
goto done;
|
||||
#ifndef CONFIG_DM_I2C
|
||||
p = pmic_get("TPS62362");
|
||||
if (p && !pmic_probe(p))
|
||||
puts("PMIC: TPS62362\n");
|
||||
if (!p || pmic_probe(p))
|
||||
goto done;
|
||||
#endif
|
||||
puts("PMIC: TPS62362\n");
|
||||
} else {
|
||||
power_tps65218_init(I2C_PMIC);
|
||||
rc = power_tps65218_init(0);
|
||||
if (rc)
|
||||
goto done;
|
||||
#ifndef CONFIG_DM_I2C
|
||||
p = pmic_get("TPS65218_PMIC");
|
||||
if (p && !pmic_probe(p))
|
||||
puts("PMIC: TPS65218\n");
|
||||
if (!p || pmic_probe(p))
|
||||
goto done;
|
||||
#endif
|
||||
puts("PMIC: TPS65218\n");
|
||||
}
|
||||
|
||||
done:
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -623,7 +623,7 @@ void am57x_idk_lcd_detect(void)
|
||||
{
|
||||
int r = -ENODEV;
|
||||
char *idk_lcd = "no";
|
||||
uint8_t buf = 0;
|
||||
struct udevice *dev;
|
||||
|
||||
/* Only valid for IDKs */
|
||||
if (board_is_x15() || board_is_am572x_evm())
|
||||
@ -633,32 +633,29 @@ void am57x_idk_lcd_detect(void)
|
||||
if (board_is_am571x_idk() && !am571x_idk_needs_lcd())
|
||||
goto out;
|
||||
|
||||
r = i2c_set_bus_num(OSD_TS_FT_BUS_ADDRESS);
|
||||
if (r) {
|
||||
printf("%s: Failed to set bus address to %d: %d\n",
|
||||
__func__, OSD_TS_FT_BUS_ADDRESS, r);
|
||||
goto out;
|
||||
}
|
||||
r = i2c_probe(OSD_TS_FT_CHIP_ADDRESS);
|
||||
r = i2c_get_chip_for_busnum(OSD_TS_FT_BUS_ADDRESS,
|
||||
OSD_TS_FT_CHIP_ADDRESS, 1, &dev);
|
||||
if (r) {
|
||||
printf("%s: Failed to get I2C device %d/%d (ret %d)\n",
|
||||
__func__, OSD_TS_FT_BUS_ADDRESS, OSD_TS_FT_CHIP_ADDRESS,
|
||||
r);
|
||||
/* AM572x IDK has no explicit settings for optional LCD kit */
|
||||
if (board_is_am571x_idk()) {
|
||||
if (board_is_am571x_idk())
|
||||
printf("%s: Touch screen detect failed: %d!\n",
|
||||
__func__, r);
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Read FT ID */
|
||||
r = i2c_read(OSD_TS_FT_CHIP_ADDRESS, OSD_TS_FT_REG_ID, 1, &buf, 1);
|
||||
if (r) {
|
||||
r = dm_i2c_reg_read(dev, OSD_TS_FT_REG_ID);
|
||||
if (r < 0) {
|
||||
printf("%s: Touch screen ID read %d:0x%02x[0x%02x] failed:%d\n",
|
||||
__func__, OSD_TS_FT_BUS_ADDRESS, OSD_TS_FT_CHIP_ADDRESS,
|
||||
OSD_TS_FT_REG_ID, r);
|
||||
goto out;
|
||||
}
|
||||
|
||||
switch (buf) {
|
||||
switch (r) {
|
||||
case OSD_TS_FT_ID_5606:
|
||||
idk_lcd = "osd101t2045";
|
||||
break;
|
||||
@ -667,7 +664,7 @@ void am57x_idk_lcd_detect(void)
|
||||
break;
|
||||
default:
|
||||
printf("%s: Unidentifed Touch screen ID 0x%02x\n",
|
||||
__func__, buf);
|
||||
__func__, r);
|
||||
/* we will let default be "no lcd" */
|
||||
}
|
||||
out:
|
||||
|
@ -14,42 +14,7 @@
|
||||
|
||||
#include "board_detect.h"
|
||||
|
||||
#if defined(CONFIG_DM_I2C_COMPAT)
|
||||
/**
|
||||
* ti_i2c_set_alen - Set chip's i2c address length
|
||||
* @bus_addr - I2C bus number
|
||||
* @dev_addr - I2C eeprom id
|
||||
* @alen - I2C address length in bytes
|
||||
*
|
||||
* DM_I2C by default sets the address length to be used to 1. This
|
||||
* function allows this address length to be changed to match the
|
||||
* eeprom used for board detection.
|
||||
*/
|
||||
int __maybe_unused ti_i2c_set_alen(int bus_addr, int dev_addr, int alen)
|
||||
{
|
||||
struct udevice *dev;
|
||||
struct udevice *bus;
|
||||
int rc;
|
||||
|
||||
rc = uclass_get_device_by_seq(UCLASS_I2C, bus_addr, &bus);
|
||||
if (rc)
|
||||
return rc;
|
||||
rc = i2c_get_chip(bus, dev_addr, 1, &dev);
|
||||
if (rc)
|
||||
return rc;
|
||||
rc = i2c_set_chip_offset_len(dev, alen);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int __maybe_unused ti_i2c_set_alen(int bus_addr, int dev_addr, int alen)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(CONFIG_DM_I2C)
|
||||
/**
|
||||
* ti_i2c_eeprom_init - Initialize an i2c bus and probe for a device
|
||||
* @i2c_bus: i2c bus number to initialize
|
||||
@ -82,18 +47,9 @@ static int __maybe_unused ti_i2c_eeprom_init(int i2c_bus, int dev_addr)
|
||||
static int __maybe_unused ti_i2c_eeprom_read(int dev_addr, int offset,
|
||||
uchar *ep, int epsize)
|
||||
{
|
||||
int bus_num, rc, alen;
|
||||
|
||||
bus_num = i2c_get_bus_num();
|
||||
|
||||
alen = 2;
|
||||
|
||||
rc = ti_i2c_set_alen(bus_num, dev_addr, alen);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
return i2c_read(dev_addr, offset, alen, ep, epsize);
|
||||
return i2c_read(dev_addr, offset, 2, ep, epsize);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* ti_eeprom_string_cleanup() - Handle eeprom programming errors
|
||||
@ -122,9 +78,57 @@ __weak void gpi2c_init(void)
|
||||
static int __maybe_unused ti_i2c_eeprom_get(int bus_addr, int dev_addr,
|
||||
u32 header, u32 size, uint8_t *ep)
|
||||
{
|
||||
u32 byte, hdr_read;
|
||||
u32 hdr_read;
|
||||
int rc;
|
||||
|
||||
#if defined(CONFIG_DM_I2C)
|
||||
struct udevice *dev;
|
||||
struct udevice *bus;
|
||||
|
||||
rc = uclass_get_device_by_seq(UCLASS_I2C, bus_addr, &bus);
|
||||
if (rc)
|
||||
return rc;
|
||||
rc = i2c_get_chip(bus, dev_addr, 1, &dev);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
/*
|
||||
* Read the header first then only read the other contents.
|
||||
*/
|
||||
rc = i2c_set_chip_offset_len(dev, 2);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = dm_i2c_read(dev, 0, (uint8_t *)&hdr_read, 4);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
/* Corrupted data??? */
|
||||
if (hdr_read != header) {
|
||||
rc = dm_i2c_read(dev, 0, (uint8_t *)&hdr_read, 4);
|
||||
/*
|
||||
* read the eeprom header using i2c again, but use only a
|
||||
* 1 byte address (some legacy boards need this..)
|
||||
*/
|
||||
if (rc) {
|
||||
rc = i2c_set_chip_offset_len(dev, 1);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = dm_i2c_read(dev, 0, (uint8_t *)&hdr_read, 4);
|
||||
}
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
if (hdr_read != header)
|
||||
return -1;
|
||||
|
||||
rc = dm_i2c_read(dev, 0, ep, size);
|
||||
if (rc)
|
||||
return rc;
|
||||
#else
|
||||
u32 byte;
|
||||
|
||||
gpi2c_init();
|
||||
rc = ti_i2c_eeprom_init(bus_addr, dev_addr);
|
||||
if (rc)
|
||||
@ -135,10 +139,6 @@ static int __maybe_unused ti_i2c_eeprom_get(int bus_addr, int dev_addr,
|
||||
*/
|
||||
byte = 2;
|
||||
|
||||
rc = ti_i2c_set_alen(bus_addr, dev_addr, byte);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = i2c_read(dev_addr, 0x0, byte, (uint8_t *)&hdr_read, 4);
|
||||
if (rc)
|
||||
return rc;
|
||||
@ -152,10 +152,6 @@ static int __maybe_unused ti_i2c_eeprom_get(int bus_addr, int dev_addr,
|
||||
*/
|
||||
byte = 1;
|
||||
if (rc) {
|
||||
rc = ti_i2c_set_alen(bus_addr, dev_addr, byte);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
rc = i2c_read(dev_addr, 0x0, byte, (uint8_t *)&hdr_read,
|
||||
4);
|
||||
}
|
||||
@ -168,7 +164,7 @@ static int __maybe_unused ti_i2c_eeprom_get(int bus_addr, int dev_addr,
|
||||
rc = i2c_read(dev_addr, 0x0, byte, ep, size);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -251,6 +251,7 @@ int board_fit_config_name_match(const char *name)
|
||||
#if defined(CONFIG_DTB_RESELECT)
|
||||
static int k2g_alt_board_detect(void)
|
||||
{
|
||||
#ifndef CONFIG_DM_I2C
|
||||
int rc;
|
||||
|
||||
rc = i2c_set_bus_num(1);
|
||||
@ -260,7 +261,17 @@ static int k2g_alt_board_detect(void)
|
||||
rc = i2c_probe(K2G_GP_AUDIO_CODEC_ADDRESS);
|
||||
if (rc)
|
||||
return rc;
|
||||
#else
|
||||
struct udevice *bus, *dev;
|
||||
int rc;
|
||||
|
||||
rc = uclass_get_device_by_seq(UCLASS_I2C, 1, &bus);
|
||||
if (rc)
|
||||
return rc;
|
||||
rc = dm_i2c_probe(bus, K2G_GP_AUDIO_CODEC_ADDRESS, 0, &dev);
|
||||
if (rc)
|
||||
return rc;
|
||||
#endif
|
||||
ti_i2c_eeprom_am_set("66AK2GGP", "1.0X");
|
||||
|
||||
return 0;
|
||||
|
@ -445,6 +445,7 @@ config CRC32_VERIFY
|
||||
|
||||
config CMD_EEPROM
|
||||
bool "eeprom - EEPROM subsystem"
|
||||
depends on !DM_I2C || DM_I2C_COMPAT
|
||||
help
|
||||
(deprecated, needs conversion to driver model)
|
||||
Provides commands to read and write EEPROM (Electrically Erasable
|
||||
|
@ -2023,6 +2023,7 @@ static int do_i2c(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
|
||||
static char i2c_help_text[] =
|
||||
#if defined(CONFIG_SYS_I2C) || defined(CONFIG_DM_I2C)
|
||||
"bus [muxtype:muxaddr:muxchannel] - show I2C bus info\n"
|
||||
"i2c " /* That's the prefix for the crc32 command below. */
|
||||
#endif
|
||||
"crc32 chip address[.0, .1, .2] count - compute CRC32 checksum\n"
|
||||
#if defined(CONFIG_SYS_I2C) || \
|
||||
|
@ -36,6 +36,7 @@ CONFIG_OF_EMBED=y
|
||||
CONFIG_DEFAULT_DEVICE_TREE="am335x-pdu001"
|
||||
# CONFIG_NET is not set
|
||||
CONFIG_SPL_DM=y
|
||||
CONFIG_SPL_DM_SEQ_ALIAS=y
|
||||
CONFIG_DM_GPIO=y
|
||||
CONFIG_DM_I2C=y
|
||||
CONFIG_BLK=y
|
||||
|
@ -37,6 +37,7 @@ CONFIG_ENV_IS_IN_MMC=y
|
||||
CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
|
||||
CONFIG_DM=y
|
||||
CONFIG_SPL_DM=y
|
||||
CONFIG_SPL_DM_SEQ_ALIAS=y
|
||||
CONFIG_SCSI_AHCI=y
|
||||
# CONFIG_BLK is not set
|
||||
CONFIG_DFU_MMC=y
|
||||
|
@ -40,6 +40,7 @@ CONFIG_ENV_IS_IN_MMC=y
|
||||
CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
|
||||
CONFIG_DM=y
|
||||
CONFIG_SPL_DM=y
|
||||
CONFIG_SPL_DM_SEQ_ALIAS=y
|
||||
CONFIG_SCSI_AHCI=y
|
||||
# CONFIG_BLK is not set
|
||||
CONFIG_DFU_MMC=y
|
||||
|
@ -1,7 +1,7 @@
|
||||
CONFIG_ARM=y
|
||||
CONFIG_ARCH_OMAP2PLUS=y
|
||||
CONFIG_TI_COMMON_CMD_OPTIONS=y
|
||||
CONFIG_SYS_MALLOC_F_LEN=0x2000
|
||||
CONFIG_SYS_MALLOC_F_LEN=0x18000
|
||||
CONFIG_OMAP54XX=y
|
||||
CONFIG_TARGET_DRA7XX_EVM=y
|
||||
CONFIG_SPL=y
|
||||
@ -34,11 +34,13 @@ CONFIG_SPL_OF_CONTROL=y
|
||||
CONFIG_DEFAULT_DEVICE_TREE="dra7-evm"
|
||||
CONFIG_OF_LIST="dra7-evm dra72-evm dra72-evm-revc dra71-evm dra76-evm"
|
||||
CONFIG_SPL_MULTI_DTB_FIT=y
|
||||
CONFIG_SPL_MULTI_DTB_FIT_UNCOMPRESS_SZ=0x9000
|
||||
CONFIG_OF_SPL_REMOVE_PROPS="clocks clock-names interrupt-parent"
|
||||
CONFIG_ENV_IS_IN_MMC=y
|
||||
CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
|
||||
CONFIG_DM=y
|
||||
CONFIG_SPL_DM=y
|
||||
CONFIG_SPL_DM_DEVICE_REMOVE=y
|
||||
CONFIG_SPL_DM_SEQ_ALIAS=y
|
||||
CONFIG_SPL_REGMAP=y
|
||||
CONFIG_SPL_SYSCON=y
|
||||
|
@ -41,6 +41,7 @@ CONFIG_ENV_IS_IN_MMC=y
|
||||
CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG=y
|
||||
CONFIG_DM=y
|
||||
CONFIG_SPL_DM=y
|
||||
CONFIG_SPL_DM_SEQ_ALIAS=y
|
||||
CONFIG_SPL_REGMAP=y
|
||||
CONFIG_SPL_SYSCON=y
|
||||
CONFIG_DWC_AHCI=y
|
||||
|
@ -34,6 +34,7 @@ CONFIG_DEFAULT_DEVICE_TREE="logicpd-torpedo-37xx-devkit"
|
||||
# CONFIG_ENV_IS_IN_FAT is not set
|
||||
CONFIG_ENV_IS_IN_NAND=y
|
||||
CONFIG_SPL_DM=y
|
||||
CONFIG_SPL_DM_SEQ_ALIAS=y
|
||||
CONFIG_USB_FUNCTION_FASTBOOT=y
|
||||
CONFIG_FASTBOOT_BUF_ADDR=0x82000000
|
||||
CONFIG_DM_I2C=y
|
||||
|
@ -184,6 +184,24 @@ The full device tree is available to U-Boot proper, but normally only a subset
|
||||
'SPL Support' in doc/driver-model/README.txt for more details.
|
||||
|
||||
|
||||
Using several DTBs in the SPL (CONFIG_SPL_MULTI_DTB)
|
||||
----------------------------------------------------
|
||||
In some rare cases it is desirable to let SPL be able to select one DTB among
|
||||
many. This usually not very useful as the DTB for the SPL is small and usually
|
||||
fits several platforms. However the DTB sometimes include information that do
|
||||
work on several platforms (like IO tuning parameters).
|
||||
In this case it is possible to use CONFIG_SPL_MULTI_DTB. This option appends to
|
||||
the SPL a FIT image containing several DTBs listed in SPL_OF_LIST.
|
||||
board_fit_config_name_match() is called to select the right DTB.
|
||||
|
||||
If board_fit_config_name_match() relies on DM (DM driver to access an EEPROM
|
||||
containing the board ID for example), it possible to start with a generic DTB
|
||||
and then switch over to the right DTB after the detection. For this purpose,
|
||||
the platform code must call fdtdec_resetup(). Based on the returned flag, the
|
||||
platform may have to re-initiliaze the DM subusystem using dm_uninit() and
|
||||
dm_init_and_scan().
|
||||
|
||||
|
||||
Limitations
|
||||
-----------
|
||||
|
||||
|
@ -57,13 +57,21 @@ config DM_DEVICE_REMOVE
|
||||
default y
|
||||
help
|
||||
We can save some code space by dropping support for removing a
|
||||
device. This is not normally required in SPL, so by default this
|
||||
option is disabled for SPL.
|
||||
device.
|
||||
|
||||
Note that this may have undesirable results in the USB subsystem as
|
||||
it causes unplugged devices to linger around in the dm-tree, and it
|
||||
causes USB host controllers to not be stopped when booting the OS.
|
||||
|
||||
config SPL_DM_DEVICE_REMOVE
|
||||
bool "Support device removal in SPL"
|
||||
depends on SPL_DM
|
||||
default n
|
||||
help
|
||||
We can save some code space by dropping support for removing a
|
||||
device. This is not normally required in SPL, so by default this
|
||||
option is disabled for SPL.
|
||||
|
||||
config DM_STDIO
|
||||
bool "Support stdio registration"
|
||||
depends on DM
|
||||
|
@ -70,7 +70,8 @@ static int device_bind_common(struct udevice *parent, const struct driver *drv,
|
||||
|
||||
dev->seq = -1;
|
||||
dev->req_seq = -1;
|
||||
if (CONFIG_IS_ENABLED(OF_CONTROL) && CONFIG_IS_ENABLED(DM_SEQ_ALIAS)) {
|
||||
if (CONFIG_IS_ENABLED(DM_SEQ_ALIAS) &&
|
||||
(uc->uc_drv->flags & DM_UC_FLAG_SEQ_ALIAS)) {
|
||||
/*
|
||||
* Some devices, such as a SPI bus, I2C bus and serial ports
|
||||
* are numbered using aliases.
|
||||
@ -78,10 +79,11 @@ static int device_bind_common(struct udevice *parent, const struct driver *drv,
|
||||
* This is just a 'requested' sequence, and will be
|
||||
* resolved (and ->seq updated) when the device is probed.
|
||||
*/
|
||||
if (uc->uc_drv->flags & DM_UC_FLAG_SEQ_ALIAS) {
|
||||
if (uc->uc_drv->name && ofnode_valid(node)) {
|
||||
if (CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)) {
|
||||
if (uc->uc_drv->name && ofnode_valid(node))
|
||||
dev_read_alias_seq(dev, &dev->req_seq);
|
||||
}
|
||||
} else {
|
||||
dev->req_seq = uclass_find_next_free_req_seq(drv->id);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -187,6 +187,7 @@ int dm_uninit(void)
|
||||
{
|
||||
device_remove(dm_root(), DM_REMOVE_NORMAL);
|
||||
device_unbind(dm_root());
|
||||
gd->dm_root = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -269,6 +269,30 @@ int uclass_find_device_by_name(enum uclass_id id, const char *name,
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
#if !CONFIG_IS_ENABLED(OF_CONTROL) || CONFIG_IS_ENABLED(OF_PLATDATA)
|
||||
int uclass_find_next_free_req_seq(enum uclass_id id)
|
||||
{
|
||||
struct uclass *uc;
|
||||
struct udevice *dev;
|
||||
int ret;
|
||||
int max = -1;
|
||||
|
||||
ret = uclass_get(id, &uc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
list_for_each_entry(dev, &uc->dev_head, uclass_node) {
|
||||
if ((dev->req_seq != -1) && (dev->req_seq > max))
|
||||
max = dev->req_seq;
|
||||
}
|
||||
|
||||
if (max == -1)
|
||||
return 0;
|
||||
|
||||
return max + 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
int uclass_find_device_by_seq(enum uclass_id id, int seq_or_req_seq,
|
||||
bool find_req_seq, struct udevice **devp)
|
||||
{
|
||||
|
@ -347,6 +347,17 @@ int i2c_get_chip_for_busnum(int busnum, int chip_addr, uint offset_len,
|
||||
debug("Cannot find I2C bus %d\n", busnum);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* detect the presence of the chip on the bus */
|
||||
ret = i2c_probe_chip(bus, chip_addr, 0);
|
||||
debug("%s: bus='%s', address %02x, ret=%d\n", __func__, bus->name,
|
||||
chip_addr, ret);
|
||||
if (ret) {
|
||||
debug("Cannot detect I2C chip %02x on bus %d\n", chip_addr,
|
||||
busnum);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = i2c_get_chip(bus, chip_addr, offset_len, devp);
|
||||
if (ret) {
|
||||
debug("Cannot find I2C chip %02x on bus %d\n", chip_addr,
|
||||
|
@ -42,8 +42,18 @@
|
||||
#include <dm.h>
|
||||
#include <i2c.h>
|
||||
|
||||
#include <asm/arch/i2c.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/omap_i2c.h>
|
||||
|
||||
/*
|
||||
* Provide access to architecture-specific I2C header files for platforms
|
||||
* that are NOT yet solely relying on CONFIG_DM_I2C, CONFIG_OF_CONTROL, and
|
||||
* the defaults provided in 'omap24xx_i2c.h' for all U-Boot stages where I2C
|
||||
* access is desired.
|
||||
*/
|
||||
#ifndef CONFIG_ARCH_K3
|
||||
#include <asm/arch/i2c.h>
|
||||
#endif
|
||||
|
||||
#include "omap24xx_i2c.h"
|
||||
|
||||
@ -52,14 +62,107 @@
|
||||
/* Absolutely safe for status update at 100 kHz I2C: */
|
||||
#define I2C_WAIT 200
|
||||
|
||||
enum {
|
||||
OMAP_I2C_REV_REG = 0, /* Only on IP V1 (OMAP34XX) */
|
||||
OMAP_I2C_IE_REG, /* Only on IP V1 (OMAP34XX) */
|
||||
OMAP_I2C_STAT_REG,
|
||||
OMAP_I2C_WE_REG,
|
||||
OMAP_I2C_SYSS_REG,
|
||||
OMAP_I2C_BUF_REG,
|
||||
OMAP_I2C_CNT_REG,
|
||||
OMAP_I2C_DATA_REG,
|
||||
OMAP_I2C_SYSC_REG,
|
||||
OMAP_I2C_CON_REG,
|
||||
OMAP_I2C_OA_REG,
|
||||
OMAP_I2C_SA_REG,
|
||||
OMAP_I2C_PSC_REG,
|
||||
OMAP_I2C_SCLL_REG,
|
||||
OMAP_I2C_SCLH_REG,
|
||||
OMAP_I2C_SYSTEST_REG,
|
||||
OMAP_I2C_BUFSTAT_REG,
|
||||
/* Only on IP V2 (OMAP4430, etc.) */
|
||||
OMAP_I2C_IP_V2_REVNB_LO,
|
||||
OMAP_I2C_IP_V2_REVNB_HI,
|
||||
OMAP_I2C_IP_V2_IRQSTATUS_RAW,
|
||||
OMAP_I2C_IP_V2_IRQENABLE_SET,
|
||||
OMAP_I2C_IP_V2_IRQENABLE_CLR,
|
||||
};
|
||||
|
||||
static const u8 __maybe_unused reg_map_ip_v1[] = {
|
||||
[OMAP_I2C_REV_REG] = 0x00,
|
||||
[OMAP_I2C_IE_REG] = 0x04,
|
||||
[OMAP_I2C_STAT_REG] = 0x08,
|
||||
[OMAP_I2C_WE_REG] = 0x0c,
|
||||
[OMAP_I2C_SYSS_REG] = 0x10,
|
||||
[OMAP_I2C_BUF_REG] = 0x14,
|
||||
[OMAP_I2C_CNT_REG] = 0x18,
|
||||
[OMAP_I2C_DATA_REG] = 0x1c,
|
||||
[OMAP_I2C_SYSC_REG] = 0x20,
|
||||
[OMAP_I2C_CON_REG] = 0x24,
|
||||
[OMAP_I2C_OA_REG] = 0x28,
|
||||
[OMAP_I2C_SA_REG] = 0x2c,
|
||||
[OMAP_I2C_PSC_REG] = 0x30,
|
||||
[OMAP_I2C_SCLL_REG] = 0x34,
|
||||
[OMAP_I2C_SCLH_REG] = 0x38,
|
||||
[OMAP_I2C_SYSTEST_REG] = 0x3c,
|
||||
[OMAP_I2C_BUFSTAT_REG] = 0x40,
|
||||
};
|
||||
|
||||
static const u8 __maybe_unused reg_map_ip_v2[] = {
|
||||
[OMAP_I2C_STAT_REG] = 0x28,
|
||||
[OMAP_I2C_WE_REG] = 0x34,
|
||||
[OMAP_I2C_SYSS_REG] = 0x90,
|
||||
[OMAP_I2C_BUF_REG] = 0x94,
|
||||
[OMAP_I2C_CNT_REG] = 0x98,
|
||||
[OMAP_I2C_DATA_REG] = 0x9c,
|
||||
[OMAP_I2C_SYSC_REG] = 0x10,
|
||||
[OMAP_I2C_CON_REG] = 0xa4,
|
||||
[OMAP_I2C_OA_REG] = 0xa8,
|
||||
[OMAP_I2C_SA_REG] = 0xac,
|
||||
[OMAP_I2C_PSC_REG] = 0xb0,
|
||||
[OMAP_I2C_SCLL_REG] = 0xb4,
|
||||
[OMAP_I2C_SCLH_REG] = 0xb8,
|
||||
[OMAP_I2C_SYSTEST_REG] = 0xbc,
|
||||
[OMAP_I2C_BUFSTAT_REG] = 0xc0,
|
||||
[OMAP_I2C_IP_V2_REVNB_LO] = 0x00,
|
||||
[OMAP_I2C_IP_V2_REVNB_HI] = 0x04,
|
||||
[OMAP_I2C_IP_V2_IRQSTATUS_RAW] = 0x24,
|
||||
[OMAP_I2C_IP_V2_IRQENABLE_SET] = 0x2c,
|
||||
[OMAP_I2C_IP_V2_IRQENABLE_CLR] = 0x30,
|
||||
};
|
||||
|
||||
struct omap_i2c {
|
||||
struct udevice *clk;
|
||||
int ip_rev;
|
||||
struct i2c *regs;
|
||||
unsigned int speed;
|
||||
int waitdelay;
|
||||
int clk_id;
|
||||
};
|
||||
|
||||
static inline const u8 *omap_i2c_get_ip_reg_map(int ip_rev)
|
||||
{
|
||||
switch (ip_rev) {
|
||||
case OMAP_I2C_REV_V1:
|
||||
return reg_map_ip_v1;
|
||||
case OMAP_I2C_REV_V2:
|
||||
/* Fall through... */
|
||||
default:
|
||||
return reg_map_ip_v2;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void omap_i2c_write_reg(void __iomem *base, int ip_rev,
|
||||
u16 val, int reg)
|
||||
{
|
||||
writew(val, base + omap_i2c_get_ip_reg_map(ip_rev)[reg]);
|
||||
}
|
||||
|
||||
static inline u16 omap_i2c_read_reg(void __iomem *base, int ip_rev, int reg)
|
||||
{
|
||||
return readw(base + omap_i2c_get_ip_reg_map(ip_rev)[reg]);
|
||||
}
|
||||
|
||||
static int omap24_i2c_findpsc(u32 *pscl, u32 *psch, uint speed)
|
||||
{
|
||||
unsigned long internal_clk = 0, fclk;
|
||||
@ -114,29 +217,31 @@ static int omap24_i2c_findpsc(u32 *pscl, u32 *psch, uint speed)
|
||||
* Wait for the bus to be free by checking the Bus Busy (BB)
|
||||
* bit to become clear
|
||||
*/
|
||||
static int wait_for_bb(struct i2c *i2c_base, int waitdelay)
|
||||
static int wait_for_bb(void __iomem *i2c_base, int ip_rev, int waitdelay)
|
||||
{
|
||||
int timeout = I2C_TIMEOUT;
|
||||
int irq_stat_reg;
|
||||
u16 stat;
|
||||
|
||||
writew(0xFFFF, &i2c_base->stat); /* clear current interrupts...*/
|
||||
#if defined(CONFIG_OMAP34XX)
|
||||
while ((stat = readw(&i2c_base->stat) & I2C_STAT_BB) && timeout--) {
|
||||
#else
|
||||
/* Read RAW status */
|
||||
while ((stat = readw(&i2c_base->irqstatus_raw) &
|
||||
irq_stat_reg = (ip_rev == OMAP_I2C_REV_V1) ?
|
||||
OMAP_I2C_STAT_REG : OMAP_I2C_IP_V2_IRQSTATUS_RAW;
|
||||
|
||||
/* clear current interrupts */
|
||||
omap_i2c_write_reg(i2c_base, ip_rev, 0xFFFF, OMAP_I2C_STAT_REG);
|
||||
|
||||
while ((stat = omap_i2c_read_reg(i2c_base, ip_rev, irq_stat_reg) &
|
||||
I2C_STAT_BB) && timeout--) {
|
||||
#endif
|
||||
writew(stat, &i2c_base->stat);
|
||||
omap_i2c_write_reg(i2c_base, ip_rev, stat, OMAP_I2C_STAT_REG);
|
||||
udelay(waitdelay);
|
||||
}
|
||||
|
||||
if (timeout <= 0) {
|
||||
printf("Timed out in wait_for_bb: status=%04x\n",
|
||||
stat);
|
||||
printf("Timed out in %s: status=%04x\n", __func__, stat);
|
||||
return 1;
|
||||
}
|
||||
writew(0xFFFF, &i2c_base->stat); /* clear delayed stuff*/
|
||||
|
||||
/* clear delayed stuff */
|
||||
omap_i2c_write_reg(i2c_base, ip_rev, 0xFFFF, OMAP_I2C_STAT_REG);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -144,40 +249,37 @@ static int wait_for_bb(struct i2c *i2c_base, int waitdelay)
|
||||
* Wait for the I2C controller to complete current action
|
||||
* and update status
|
||||
*/
|
||||
static u16 wait_for_event(struct i2c *i2c_base, int waitdelay)
|
||||
static u16 wait_for_event(void __iomem *i2c_base, int ip_rev, int waitdelay)
|
||||
{
|
||||
u16 status;
|
||||
int timeout = I2C_TIMEOUT;
|
||||
int irq_stat_reg;
|
||||
|
||||
irq_stat_reg = (ip_rev == OMAP_I2C_REV_V1) ?
|
||||
OMAP_I2C_STAT_REG : OMAP_I2C_IP_V2_IRQSTATUS_RAW;
|
||||
do {
|
||||
udelay(waitdelay);
|
||||
#if defined(CONFIG_OMAP34XX)
|
||||
status = readw(&i2c_base->stat);
|
||||
#else
|
||||
/* Read RAW status */
|
||||
status = readw(&i2c_base->irqstatus_raw);
|
||||
#endif
|
||||
status = omap_i2c_read_reg(i2c_base, ip_rev, irq_stat_reg);
|
||||
} while (!(status &
|
||||
(I2C_STAT_ROVR | I2C_STAT_XUDF | I2C_STAT_XRDY |
|
||||
I2C_STAT_RRDY | I2C_STAT_ARDY | I2C_STAT_NACK |
|
||||
I2C_STAT_AL)) && timeout--);
|
||||
|
||||
if (timeout <= 0) {
|
||||
printf("Timed out in wait_for_event: status=%04x\n",
|
||||
status);
|
||||
printf("Timed out in %s: status=%04x\n", __func__, status);
|
||||
/*
|
||||
* If status is still 0 here, probably the bus pads have
|
||||
* not been configured for I2C, and/or pull-ups are missing.
|
||||
*/
|
||||
printf("Check if pads/pull-ups of bus are properly configured\n");
|
||||
writew(0xFFFF, &i2c_base->stat);
|
||||
omap_i2c_write_reg(i2c_base, ip_rev, 0xFFFF, OMAP_I2C_STAT_REG);
|
||||
status = 0;
|
||||
}
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static void flush_fifo(struct i2c *i2c_base)
|
||||
static void flush_fifo(void __iomem *i2c_base, int ip_rev)
|
||||
{
|
||||
u16 stat;
|
||||
|
||||
@ -186,17 +288,18 @@ static void flush_fifo(struct i2c *i2c_base)
|
||||
* you get a bus error
|
||||
*/
|
||||
while (1) {
|
||||
stat = readw(&i2c_base->stat);
|
||||
stat = omap_i2c_read_reg(i2c_base, ip_rev, OMAP_I2C_STAT_REG);
|
||||
if (stat == I2C_STAT_RRDY) {
|
||||
readb(&i2c_base->data);
|
||||
writew(I2C_STAT_RRDY, &i2c_base->stat);
|
||||
omap_i2c_read_reg(i2c_base, ip_rev, OMAP_I2C_DATA_REG);
|
||||
omap_i2c_write_reg(i2c_base, ip_rev,
|
||||
I2C_STAT_RRDY, OMAP_I2C_STAT_REG);
|
||||
udelay(1000);
|
||||
} else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int __omap24_i2c_setspeed(struct i2c *i2c_base, uint speed,
|
||||
static int __omap24_i2c_setspeed(void __iomem *i2c_base, int ip_rev, uint speed,
|
||||
int *waitdelay)
|
||||
{
|
||||
int psc, fsscll = 0, fssclh = 0;
|
||||
@ -248,79 +351,89 @@ static int __omap24_i2c_setspeed(struct i2c *i2c_base, uint speed,
|
||||
}
|
||||
}
|
||||
|
||||
*waitdelay = (10000000 / speed) * 2; /* wait for 20 clkperiods */
|
||||
writew(0, &i2c_base->con);
|
||||
writew(psc, &i2c_base->psc);
|
||||
writew(scll, &i2c_base->scll);
|
||||
writew(sclh, &i2c_base->sclh);
|
||||
writew(I2C_CON_EN, &i2c_base->con);
|
||||
writew(0xFFFF, &i2c_base->stat); /* clear all pending status */
|
||||
/* wait for 20 clkperiods */
|
||||
*waitdelay = (10000000 / speed) * 2;
|
||||
|
||||
omap_i2c_write_reg(i2c_base, ip_rev, 0, OMAP_I2C_CON_REG);
|
||||
omap_i2c_write_reg(i2c_base, ip_rev, psc, OMAP_I2C_PSC_REG);
|
||||
omap_i2c_write_reg(i2c_base, ip_rev, scll, OMAP_I2C_SCLL_REG);
|
||||
omap_i2c_write_reg(i2c_base, ip_rev, sclh, OMAP_I2C_SCLH_REG);
|
||||
omap_i2c_write_reg(i2c_base, ip_rev, I2C_CON_EN, OMAP_I2C_CON_REG);
|
||||
|
||||
/* clear all pending status */
|
||||
omap_i2c_write_reg(i2c_base, ip_rev, 0xFFFF, OMAP_I2C_STAT_REG);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void omap24_i2c_deblock(struct i2c *i2c_base)
|
||||
static void omap24_i2c_deblock(void __iomem *i2c_base, int ip_rev)
|
||||
{
|
||||
int i;
|
||||
u16 systest;
|
||||
u16 orgsystest;
|
||||
|
||||
/* set test mode ST_EN = 1 */
|
||||
orgsystest = readw(&i2c_base->systest);
|
||||
orgsystest = omap_i2c_read_reg(i2c_base, ip_rev, OMAP_I2C_SYSTEST_REG);
|
||||
systest = orgsystest;
|
||||
|
||||
/* enable testmode */
|
||||
systest |= I2C_SYSTEST_ST_EN;
|
||||
writew(systest, &i2c_base->systest);
|
||||
omap_i2c_write_reg(i2c_base, ip_rev, systest, OMAP_I2C_SYSTEST_REG);
|
||||
systest &= ~I2C_SYSTEST_TMODE_MASK;
|
||||
systest |= 3 << I2C_SYSTEST_TMODE_SHIFT;
|
||||
writew(systest, &i2c_base->systest);
|
||||
omap_i2c_write_reg(i2c_base, ip_rev, systest, OMAP_I2C_SYSTEST_REG);
|
||||
|
||||
/* set SCL, SDA = 1 */
|
||||
systest |= I2C_SYSTEST_SCL_O | I2C_SYSTEST_SDA_O;
|
||||
writew(systest, &i2c_base->systest);
|
||||
omap_i2c_write_reg(i2c_base, ip_rev, systest, OMAP_I2C_SYSTEST_REG);
|
||||
udelay(10);
|
||||
|
||||
/* toggle scl 9 clocks */
|
||||
for (i = 0; i < 9; i++) {
|
||||
/* SCL = 0 */
|
||||
systest &= ~I2C_SYSTEST_SCL_O;
|
||||
writew(systest, &i2c_base->systest);
|
||||
omap_i2c_write_reg(i2c_base, ip_rev,
|
||||
systest, OMAP_I2C_SYSTEST_REG);
|
||||
udelay(10);
|
||||
/* SCL = 1 */
|
||||
systest |= I2C_SYSTEST_SCL_O;
|
||||
writew(systest, &i2c_base->systest);
|
||||
omap_i2c_write_reg(i2c_base, ip_rev,
|
||||
systest, OMAP_I2C_SYSTEST_REG);
|
||||
udelay(10);
|
||||
}
|
||||
|
||||
/* send stop */
|
||||
systest &= ~I2C_SYSTEST_SDA_O;
|
||||
writew(systest, &i2c_base->systest);
|
||||
omap_i2c_write_reg(i2c_base, ip_rev, systest, OMAP_I2C_SYSTEST_REG);
|
||||
udelay(10);
|
||||
systest |= I2C_SYSTEST_SCL_O | I2C_SYSTEST_SDA_O;
|
||||
writew(systest, &i2c_base->systest);
|
||||
omap_i2c_write_reg(i2c_base, ip_rev, systest, OMAP_I2C_SYSTEST_REG);
|
||||
udelay(10);
|
||||
|
||||
/* restore original mode */
|
||||
writew(orgsystest, &i2c_base->systest);
|
||||
omap_i2c_write_reg(i2c_base, ip_rev, orgsystest, OMAP_I2C_SYSTEST_REG);
|
||||
}
|
||||
|
||||
static void __omap24_i2c_init(struct i2c *i2c_base, int speed, int slaveadd,
|
||||
int *waitdelay)
|
||||
static void __omap24_i2c_init(void __iomem *i2c_base, int ip_rev, int speed,
|
||||
int slaveadd, int *waitdelay)
|
||||
{
|
||||
int timeout = I2C_TIMEOUT;
|
||||
int deblock = 1;
|
||||
|
||||
retry:
|
||||
if (readw(&i2c_base->con) & I2C_CON_EN) {
|
||||
writew(0, &i2c_base->con);
|
||||
if (omap_i2c_read_reg(i2c_base, ip_rev, OMAP_I2C_CON_REG) &
|
||||
I2C_CON_EN) {
|
||||
omap_i2c_write_reg(i2c_base, ip_rev, 0, OMAP_I2C_CON_REG);
|
||||
udelay(50000);
|
||||
}
|
||||
|
||||
writew(0x2, &i2c_base->sysc); /* for ES2 after soft reset */
|
||||
/* for ES2 after soft reset */
|
||||
omap_i2c_write_reg(i2c_base, ip_rev, 0x2, OMAP_I2C_SYSC_REG);
|
||||
udelay(1000);
|
||||
|
||||
writew(I2C_CON_EN, &i2c_base->con);
|
||||
while (!(readw(&i2c_base->syss) & I2C_SYSS_RDONE) && timeout--) {
|
||||
omap_i2c_write_reg(i2c_base, ip_rev, I2C_CON_EN, OMAP_I2C_CON_REG);
|
||||
while (!(omap_i2c_read_reg(i2c_base, ip_rev, OMAP_I2C_SYSS_REG) &
|
||||
I2C_SYSS_RDONE) && timeout--) {
|
||||
if (timeout <= 0) {
|
||||
puts("ERROR: Timeout in soft-reset\n");
|
||||
return;
|
||||
@ -328,30 +441,33 @@ retry:
|
||||
udelay(1000);
|
||||
}
|
||||
|
||||
if (0 != __omap24_i2c_setspeed(i2c_base, speed, waitdelay)) {
|
||||
if (__omap24_i2c_setspeed(i2c_base, ip_rev, speed, waitdelay)) {
|
||||
printf("ERROR: failed to setup I2C bus-speed!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* own address */
|
||||
writew(slaveadd, &i2c_base->oa);
|
||||
omap_i2c_write_reg(i2c_base, ip_rev, slaveadd, OMAP_I2C_OA_REG);
|
||||
|
||||
if (ip_rev == OMAP_I2C_REV_V1) {
|
||||
/*
|
||||
* Have to enable interrupts for OMAP2/3, these IPs don't have
|
||||
* an 'irqstatus_raw' register and we shall have to poll 'stat'
|
||||
*/
|
||||
omap_i2c_write_reg(i2c_base, ip_rev, I2C_IE_XRDY_IE |
|
||||
I2C_IE_RRDY_IE | I2C_IE_ARDY_IE |
|
||||
I2C_IE_NACK_IE | I2C_IE_AL_IE,
|
||||
OMAP_I2C_IE_REG);
|
||||
}
|
||||
|
||||
#if defined(CONFIG_OMAP34XX)
|
||||
/*
|
||||
* Have to enable interrupts for OMAP2/3, these IPs don't have
|
||||
* an 'irqstatus_raw' register and we shall have to poll 'stat'
|
||||
*/
|
||||
writew(I2C_IE_XRDY_IE | I2C_IE_RRDY_IE | I2C_IE_ARDY_IE |
|
||||
I2C_IE_NACK_IE | I2C_IE_AL_IE, &i2c_base->ie);
|
||||
#endif
|
||||
udelay(1000);
|
||||
flush_fifo(i2c_base);
|
||||
writew(0xFFFF, &i2c_base->stat);
|
||||
flush_fifo(i2c_base, ip_rev);
|
||||
omap_i2c_write_reg(i2c_base, ip_rev, 0xFFFF, OMAP_I2C_STAT_REG);
|
||||
|
||||
/* Handle possible failed I2C state */
|
||||
if (wait_for_bb(i2c_base, *waitdelay))
|
||||
if (wait_for_bb(i2c_base, ip_rev, *waitdelay))
|
||||
if (deblock == 1) {
|
||||
omap24_i2c_deblock(i2c_base);
|
||||
omap24_i2c_deblock(i2c_base, ip_rev);
|
||||
deblock = 0;
|
||||
goto retry;
|
||||
}
|
||||
@ -361,25 +477,28 @@ retry:
|
||||
* i2c_probe: Use write access. Allows to identify addresses that are
|
||||
* write-only (like the config register of dual-port EEPROMs)
|
||||
*/
|
||||
static int __omap24_i2c_probe(struct i2c *i2c_base, int waitdelay, uchar chip)
|
||||
static int __omap24_i2c_probe(void __iomem *i2c_base, int ip_rev, int waitdelay,
|
||||
uchar chip)
|
||||
{
|
||||
u16 status;
|
||||
int res = 1; /* default = fail */
|
||||
|
||||
if (chip == readw(&i2c_base->oa))
|
||||
if (chip == omap_i2c_read_reg(i2c_base, ip_rev, OMAP_I2C_OA_REG))
|
||||
return res;
|
||||
|
||||
/* Wait until bus is free */
|
||||
if (wait_for_bb(i2c_base, waitdelay))
|
||||
if (wait_for_bb(i2c_base, ip_rev, waitdelay))
|
||||
return res;
|
||||
|
||||
/* No data transfer, slave addr only */
|
||||
writew(chip, &i2c_base->sa);
|
||||
/* Stop bit needed here */
|
||||
writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX |
|
||||
I2C_CON_STP, &i2c_base->con);
|
||||
omap_i2c_write_reg(i2c_base, ip_rev, chip, OMAP_I2C_SA_REG);
|
||||
|
||||
status = wait_for_event(i2c_base, waitdelay);
|
||||
/* Stop bit needed here */
|
||||
omap_i2c_write_reg(i2c_base, ip_rev, I2C_CON_EN | I2C_CON_MST |
|
||||
I2C_CON_STT | I2C_CON_TRX | I2C_CON_STP,
|
||||
OMAP_I2C_CON_REG);
|
||||
|
||||
status = wait_for_event(i2c_base, ip_rev, waitdelay);
|
||||
|
||||
if ((status & ~I2C_STAT_XRDY) == 0 || (status & I2C_STAT_AL)) {
|
||||
/*
|
||||
@ -400,14 +519,17 @@ static int __omap24_i2c_probe(struct i2c *i2c_base, int waitdelay, uchar chip)
|
||||
res = 0; /* Device found */
|
||||
udelay(waitdelay);/* Required by AM335X in SPL */
|
||||
/* Abort transfer (force idle state) */
|
||||
writew(I2C_CON_MST | I2C_CON_TRX, &i2c_base->con); /* Reset */
|
||||
omap_i2c_write_reg(i2c_base, ip_rev, I2C_CON_MST | I2C_CON_TRX,
|
||||
OMAP_I2C_CON_REG); /* Reset */
|
||||
udelay(1000);
|
||||
writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_TRX |
|
||||
I2C_CON_STP, &i2c_base->con); /* STP */
|
||||
omap_i2c_write_reg(i2c_base, ip_rev, I2C_CON_EN | I2C_CON_MST |
|
||||
I2C_CON_TRX | I2C_CON_STP,
|
||||
OMAP_I2C_CON_REG); /* STP */
|
||||
}
|
||||
|
||||
pr_exit:
|
||||
flush_fifo(i2c_base);
|
||||
writew(0xFFFF, &i2c_base->stat);
|
||||
flush_fifo(i2c_base, ip_rev);
|
||||
omap_i2c_write_reg(i2c_base, ip_rev, 0xFFFF, OMAP_I2C_STAT_REG);
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -424,8 +546,9 @@ pr_exit:
|
||||
* or that do not need a register address at all (such as some clock
|
||||
* distributors).
|
||||
*/
|
||||
static int __omap24_i2c_read(struct i2c *i2c_base, int waitdelay, uchar chip,
|
||||
uint addr, int alen, uchar *buffer, int len)
|
||||
static int __omap24_i2c_read(void __iomem *i2c_base, int ip_rev, int waitdelay,
|
||||
uchar chip, uint addr, int alen, uchar *buffer,
|
||||
int len)
|
||||
{
|
||||
int i2c_error = 0;
|
||||
u16 status;
|
||||
@ -434,10 +557,12 @@ static int __omap24_i2c_read(struct i2c *i2c_base, int waitdelay, uchar chip,
|
||||
puts("I2C read: addr len < 0\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (len < 0) {
|
||||
puts("I2C read: data len < 0\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (buffer == NULL) {
|
||||
puts("I2C read: NULL pointer passed\n");
|
||||
return 1;
|
||||
@ -471,28 +596,29 @@ static int __omap24_i2c_read(struct i2c *i2c_base, int waitdelay, uchar chip,
|
||||
#endif
|
||||
|
||||
/* Wait until bus not busy */
|
||||
if (wait_for_bb(i2c_base, waitdelay))
|
||||
if (wait_for_bb(i2c_base, ip_rev, waitdelay))
|
||||
return 1;
|
||||
|
||||
/* Zero, one or two bytes reg address (offset) */
|
||||
writew(alen, &i2c_base->cnt);
|
||||
omap_i2c_write_reg(i2c_base, ip_rev, alen, OMAP_I2C_CNT_REG);
|
||||
/* Set slave address */
|
||||
writew(chip, &i2c_base->sa);
|
||||
omap_i2c_write_reg(i2c_base, ip_rev, chip, OMAP_I2C_SA_REG);
|
||||
|
||||
if (alen) {
|
||||
/* Must write reg offset first */
|
||||
#ifdef CONFIG_I2C_REPEATED_START
|
||||
/* No stop bit, use Repeated Start (Sr) */
|
||||
writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT |
|
||||
I2C_CON_TRX, &i2c_base->con);
|
||||
omap_i2c_write_reg(i2c_base, ip_rev, I2C_CON_EN | I2C_CON_MST |
|
||||
I2C_CON_STT | I2C_CON_TRX, OMAP_I2C_CON_REG);
|
||||
#else
|
||||
/* Stop - Start (P-S) */
|
||||
writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_STP |
|
||||
I2C_CON_TRX, &i2c_base->con);
|
||||
omap_i2c_write_reg(i2c_base, ip_rev, I2C_CON_EN | I2C_CON_MST |
|
||||
I2C_CON_STT | I2C_CON_STP | I2C_CON_TRX,
|
||||
OMAP_I2C_CON_REG);
|
||||
#endif
|
||||
/* Send register offset */
|
||||
while (1) {
|
||||
status = wait_for_event(i2c_base, waitdelay);
|
||||
status = wait_for_event(i2c_base, ip_rev, waitdelay);
|
||||
/* Try to identify bus that is not padconf'd for I2C */
|
||||
if (status == I2C_STAT_XRDY) {
|
||||
i2c_error = 2;
|
||||
@ -508,31 +634,37 @@ static int __omap24_i2c_read(struct i2c *i2c_base, int waitdelay, uchar chip,
|
||||
}
|
||||
if (alen) {
|
||||
if (status & I2C_STAT_XRDY) {
|
||||
u8 addr_byte;
|
||||
alen--;
|
||||
/* Do we have to use byte access? */
|
||||
writeb((addr >> (8 * alen)) & 0xff,
|
||||
&i2c_base->data);
|
||||
writew(I2C_STAT_XRDY, &i2c_base->stat);
|
||||
addr_byte = (addr >> (8 * alen)) & 0xff;
|
||||
omap_i2c_write_reg(i2c_base, ip_rev,
|
||||
addr_byte,
|
||||
OMAP_I2C_DATA_REG);
|
||||
omap_i2c_write_reg(i2c_base, ip_rev,
|
||||
I2C_STAT_XRDY,
|
||||
OMAP_I2C_STAT_REG);
|
||||
}
|
||||
}
|
||||
if (status & I2C_STAT_ARDY) {
|
||||
writew(I2C_STAT_ARDY, &i2c_base->stat);
|
||||
omap_i2c_write_reg(i2c_base, ip_rev,
|
||||
I2C_STAT_ARDY,
|
||||
OMAP_I2C_STAT_REG);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Set slave address */
|
||||
writew(chip, &i2c_base->sa);
|
||||
omap_i2c_write_reg(i2c_base, ip_rev, chip, OMAP_I2C_SA_REG);
|
||||
/* Read len bytes from slave */
|
||||
writew(len, &i2c_base->cnt);
|
||||
omap_i2c_write_reg(i2c_base, ip_rev, len, OMAP_I2C_CNT_REG);
|
||||
/* Need stop bit here */
|
||||
writew(I2C_CON_EN | I2C_CON_MST |
|
||||
I2C_CON_STT | I2C_CON_STP,
|
||||
&i2c_base->con);
|
||||
omap_i2c_write_reg(i2c_base, ip_rev, I2C_CON_EN | I2C_CON_MST |
|
||||
I2C_CON_STT | I2C_CON_STP, OMAP_I2C_CON_REG);
|
||||
|
||||
/* Receive data */
|
||||
while (1) {
|
||||
status = wait_for_event(i2c_base, waitdelay);
|
||||
status = wait_for_event(i2c_base, ip_rev, waitdelay);
|
||||
/*
|
||||
* Try to identify bus that is not padconf'd for I2C. This
|
||||
* state could be left over from previous transactions if
|
||||
@ -549,24 +681,28 @@ static int __omap24_i2c_read(struct i2c *i2c_base, int waitdelay, uchar chip,
|
||||
goto rd_exit;
|
||||
}
|
||||
if (status & I2C_STAT_RRDY) {
|
||||
*buffer++ = readb(&i2c_base->data);
|
||||
writew(I2C_STAT_RRDY, &i2c_base->stat);
|
||||
*buffer++ = omap_i2c_read_reg(i2c_base, ip_rev,
|
||||
OMAP_I2C_DATA_REG);
|
||||
omap_i2c_write_reg(i2c_base, ip_rev,
|
||||
I2C_STAT_RRDY, OMAP_I2C_STAT_REG);
|
||||
}
|
||||
if (status & I2C_STAT_ARDY) {
|
||||
writew(I2C_STAT_ARDY, &i2c_base->stat);
|
||||
omap_i2c_write_reg(i2c_base, ip_rev,
|
||||
I2C_STAT_ARDY, OMAP_I2C_STAT_REG);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
rd_exit:
|
||||
flush_fifo(i2c_base);
|
||||
writew(0xFFFF, &i2c_base->stat);
|
||||
flush_fifo(i2c_base, ip_rev);
|
||||
omap_i2c_write_reg(i2c_base, ip_rev, 0xFFFF, OMAP_I2C_STAT_REG);
|
||||
return i2c_error;
|
||||
}
|
||||
|
||||
/* i2c_write: Address (reg offset) may be 0, 1 or 2 bytes long. */
|
||||
static int __omap24_i2c_write(struct i2c *i2c_base, int waitdelay, uchar chip,
|
||||
uint addr, int alen, uchar *buffer, int len)
|
||||
static int __omap24_i2c_write(void __iomem *i2c_base, int ip_rev, int waitdelay,
|
||||
uchar chip, uint addr, int alen, uchar *buffer,
|
||||
int len)
|
||||
{
|
||||
int i;
|
||||
u16 status;
|
||||
@ -617,20 +753,21 @@ static int __omap24_i2c_write(struct i2c *i2c_base, int waitdelay, uchar chip,
|
||||
#endif
|
||||
|
||||
/* Wait until bus not busy */
|
||||
if (wait_for_bb(i2c_base, waitdelay))
|
||||
if (wait_for_bb(i2c_base, ip_rev, waitdelay))
|
||||
return 1;
|
||||
|
||||
/* Start address phase - will write regoffset + len bytes data */
|
||||
writew(alen + len, &i2c_base->cnt);
|
||||
omap_i2c_write_reg(i2c_base, ip_rev, alen + len, OMAP_I2C_CNT_REG);
|
||||
/* Set slave address */
|
||||
writew(chip, &i2c_base->sa);
|
||||
omap_i2c_write_reg(i2c_base, ip_rev, chip, OMAP_I2C_SA_REG);
|
||||
/* Stop bit needed here */
|
||||
writew(I2C_CON_EN | I2C_CON_MST | I2C_CON_STT | I2C_CON_TRX |
|
||||
I2C_CON_STP, &i2c_base->con);
|
||||
omap_i2c_write_reg(i2c_base, ip_rev, I2C_CON_EN | I2C_CON_MST |
|
||||
I2C_CON_STT | I2C_CON_TRX | I2C_CON_STP,
|
||||
OMAP_I2C_CON_REG);
|
||||
|
||||
while (alen) {
|
||||
/* Must write reg offset (one or two bytes) */
|
||||
status = wait_for_event(i2c_base, waitdelay);
|
||||
status = wait_for_event(i2c_base, ip_rev, waitdelay);
|
||||
/* Try to identify bus that is not padconf'd for I2C */
|
||||
if (status == I2C_STAT_XRDY) {
|
||||
i2c_error = 2;
|
||||
@ -646,8 +783,11 @@ static int __omap24_i2c_write(struct i2c *i2c_base, int waitdelay, uchar chip,
|
||||
}
|
||||
if (status & I2C_STAT_XRDY) {
|
||||
alen--;
|
||||
writeb((addr >> (8 * alen)) & 0xff, &i2c_base->data);
|
||||
writew(I2C_STAT_XRDY, &i2c_base->stat);
|
||||
omap_i2c_write_reg(i2c_base, ip_rev,
|
||||
(addr >> (8 * alen)) & 0xff,
|
||||
OMAP_I2C_DATA_REG);
|
||||
omap_i2c_write_reg(i2c_base, ip_rev,
|
||||
I2C_STAT_XRDY, OMAP_I2C_STAT_REG);
|
||||
} else {
|
||||
i2c_error = 1;
|
||||
printf("i2c_write: bus not ready for addr Tx (status=0x%x)\n",
|
||||
@ -655,9 +795,10 @@ static int __omap24_i2c_write(struct i2c *i2c_base, int waitdelay, uchar chip,
|
||||
goto wr_exit;
|
||||
}
|
||||
}
|
||||
|
||||
/* Address phase is over, now write data */
|
||||
for (i = 0; i < len; i++) {
|
||||
status = wait_for_event(i2c_base, waitdelay);
|
||||
status = wait_for_event(i2c_base, ip_rev, waitdelay);
|
||||
if (status == 0 || (status & I2C_STAT_NACK)) {
|
||||
i2c_error = 1;
|
||||
printf("i2c_write: error waiting for data ACK (status=0x%x)\n",
|
||||
@ -665,8 +806,10 @@ static int __omap24_i2c_write(struct i2c *i2c_base, int waitdelay, uchar chip,
|
||||
goto wr_exit;
|
||||
}
|
||||
if (status & I2C_STAT_XRDY) {
|
||||
writeb(buffer[i], &i2c_base->data);
|
||||
writew(I2C_STAT_XRDY, &i2c_base->stat);
|
||||
omap_i2c_write_reg(i2c_base, ip_rev,
|
||||
buffer[i], OMAP_I2C_DATA_REG);
|
||||
omap_i2c_write_reg(i2c_base, ip_rev,
|
||||
I2C_STAT_XRDY, OMAP_I2C_STAT_REG);
|
||||
} else {
|
||||
i2c_error = 1;
|
||||
printf("i2c_write: bus not ready for data Tx (i=%d)\n",
|
||||
@ -674,19 +817,20 @@ static int __omap24_i2c_write(struct i2c *i2c_base, int waitdelay, uchar chip,
|
||||
goto wr_exit;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* poll ARDY bit for making sure that last byte really has been
|
||||
* transferred on the bus.
|
||||
*/
|
||||
do {
|
||||
status = wait_for_event(i2c_base, waitdelay);
|
||||
status = wait_for_event(i2c_base, ip_rev, waitdelay);
|
||||
} while (!(status & I2C_STAT_ARDY) && timeout--);
|
||||
if (timeout <= 0)
|
||||
printf("i2c_write: timed out writig last byte!\n");
|
||||
|
||||
wr_exit:
|
||||
flush_fifo(i2c_base);
|
||||
writew(0xFFFF, &i2c_base->stat);
|
||||
flush_fifo(i2c_base, ip_rev);
|
||||
omap_i2c_write_reg(i2c_base, ip_rev, 0xFFFF, OMAP_I2C_STAT_REG);
|
||||
return i2c_error;
|
||||
}
|
||||
|
||||
@ -695,26 +839,26 @@ wr_exit:
|
||||
* The legacy I2C functions. These need to get removed once
|
||||
* all users of this driver are converted to DM.
|
||||
*/
|
||||
static struct i2c *omap24_get_base(struct i2c_adapter *adap)
|
||||
static void __iomem *omap24_get_base(struct i2c_adapter *adap)
|
||||
{
|
||||
switch (adap->hwadapnr) {
|
||||
case 0:
|
||||
return (struct i2c *)I2C_BASE1;
|
||||
return (void __iomem *)I2C_BASE1;
|
||||
break;
|
||||
case 1:
|
||||
return (struct i2c *)I2C_BASE2;
|
||||
return (void __iomem *)I2C_BASE2;
|
||||
break;
|
||||
#if (CONFIG_SYS_I2C_BUS_MAX > 2)
|
||||
case 2:
|
||||
return (struct i2c *)I2C_BASE3;
|
||||
return (void __iomem *)I2C_BASE3;
|
||||
break;
|
||||
#if (CONFIG_SYS_I2C_BUS_MAX > 3)
|
||||
case 3:
|
||||
return (struct i2c *)I2C_BASE4;
|
||||
return (void __iomem *)I2C_BASE4;
|
||||
break;
|
||||
#if (CONFIG_SYS_I2C_BUS_MAX > 4)
|
||||
case 4:
|
||||
return (struct i2c *)I2C_BASE5;
|
||||
return (void __iomem *)I2C_BASE5;
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
@ -723,35 +867,46 @@ static struct i2c *omap24_get_base(struct i2c_adapter *adap)
|
||||
printf("wrong hwadapnr: %d\n", adap->hwadapnr);
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int omap24_get_ip_rev(void)
|
||||
{
|
||||
#ifdef CONFIG_OMAP34XX
|
||||
return OMAP_I2C_REV_V1;
|
||||
#else
|
||||
return OMAP_I2C_REV_V2;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int omap24_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
|
||||
int alen, uchar *buffer, int len)
|
||||
{
|
||||
struct i2c *i2c_base = omap24_get_base(adap);
|
||||
void __iomem *i2c_base = omap24_get_base(adap);
|
||||
int ip_rev = omap24_get_ip_rev();
|
||||
|
||||
return __omap24_i2c_read(i2c_base, adap->waitdelay, chip, addr,
|
||||
return __omap24_i2c_read(i2c_base, ip_rev, adap->waitdelay, chip, addr,
|
||||
alen, buffer, len);
|
||||
}
|
||||
|
||||
|
||||
static int omap24_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
|
||||
int alen, uchar *buffer, int len)
|
||||
{
|
||||
struct i2c *i2c_base = omap24_get_base(adap);
|
||||
void __iomem *i2c_base = omap24_get_base(adap);
|
||||
int ip_rev = omap24_get_ip_rev();
|
||||
|
||||
return __omap24_i2c_write(i2c_base, adap->waitdelay, chip, addr,
|
||||
return __omap24_i2c_write(i2c_base, ip_rev, adap->waitdelay, chip, addr,
|
||||
alen, buffer, len);
|
||||
}
|
||||
|
||||
static uint omap24_i2c_setspeed(struct i2c_adapter *adap, uint speed)
|
||||
{
|
||||
struct i2c *i2c_base = omap24_get_base(adap);
|
||||
void __iomem *i2c_base = omap24_get_base(adap);
|
||||
int ip_rev = omap24_get_ip_rev();
|
||||
int ret;
|
||||
|
||||
ret = __omap24_i2c_setspeed(i2c_base, speed, &adap->waitdelay);
|
||||
ret = __omap24_i2c_setspeed(i2c_base, ip_rev, speed, &adap->waitdelay);
|
||||
if (ret) {
|
||||
pr_err("%s: set i2c speed failed\n", __func__);
|
||||
return ret;
|
||||
@ -764,16 +919,19 @@ static uint omap24_i2c_setspeed(struct i2c_adapter *adap, uint speed)
|
||||
|
||||
static void omap24_i2c_init(struct i2c_adapter *adap, int speed, int slaveadd)
|
||||
{
|
||||
struct i2c *i2c_base = omap24_get_base(adap);
|
||||
void __iomem *i2c_base = omap24_get_base(adap);
|
||||
int ip_rev = omap24_get_ip_rev();
|
||||
|
||||
return __omap24_i2c_init(i2c_base, speed, slaveadd, &adap->waitdelay);
|
||||
return __omap24_i2c_init(i2c_base, ip_rev, speed, slaveadd,
|
||||
&adap->waitdelay);
|
||||
}
|
||||
|
||||
static int omap24_i2c_probe(struct i2c_adapter *adap, uchar chip)
|
||||
{
|
||||
struct i2c *i2c_base = omap24_get_base(adap);
|
||||
void __iomem *i2c_base = omap24_get_base(adap);
|
||||
int ip_rev = omap24_get_ip_rev();
|
||||
|
||||
return __omap24_i2c_probe(i2c_base, adap->waitdelay, chip);
|
||||
return __omap24_i2c_probe(i2c_base, ip_rev, adap->waitdelay, chip);
|
||||
}
|
||||
|
||||
#if !defined(CONFIG_SYS_OMAP24_I2C_SPEED1)
|
||||
@ -793,6 +951,7 @@ U_BOOT_I2C_ADAP_COMPLETE(omap24_1, omap24_i2c_init, omap24_i2c_probe,
|
||||
CONFIG_SYS_OMAP24_I2C_SPEED1,
|
||||
CONFIG_SYS_OMAP24_I2C_SLAVE1,
|
||||
1)
|
||||
|
||||
#if (CONFIG_SYS_I2C_BUS_MAX > 2)
|
||||
#if !defined(CONFIG_SYS_OMAP24_I2C_SPEED2)
|
||||
#define CONFIG_SYS_OMAP24_I2C_SPEED2 CONFIG_SYS_OMAP24_I2C_SPEED
|
||||
@ -847,11 +1006,13 @@ static int omap_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, int nmsgs)
|
||||
for (; nmsgs > 0; nmsgs--, msg++) {
|
||||
debug("i2c_xfer: chip=0x%x, len=0x%x\n", msg->addr, msg->len);
|
||||
if (msg->flags & I2C_M_RD) {
|
||||
ret = __omap24_i2c_read(priv->regs, priv->waitdelay,
|
||||
ret = __omap24_i2c_read(priv->regs, priv->ip_rev,
|
||||
priv->waitdelay,
|
||||
msg->addr, 0, 0, msg->buf,
|
||||
msg->len);
|
||||
} else {
|
||||
ret = __omap24_i2c_write(priv->regs, priv->waitdelay,
|
||||
ret = __omap24_i2c_write(priv->regs, priv->ip_rev,
|
||||
priv->waitdelay,
|
||||
msg->addr, 0, 0, msg->buf,
|
||||
msg->len);
|
||||
}
|
||||
@ -870,7 +1031,8 @@ static int omap_i2c_set_bus_speed(struct udevice *bus, unsigned int speed)
|
||||
|
||||
priv->speed = speed;
|
||||
|
||||
return __omap24_i2c_setspeed(priv->regs, speed, &priv->waitdelay);
|
||||
return __omap24_i2c_setspeed(priv->regs, priv->ip_rev, speed,
|
||||
&priv->waitdelay);
|
||||
}
|
||||
|
||||
static int omap_i2c_probe_chip(struct udevice *bus, uint chip_addr,
|
||||
@ -878,14 +1040,22 @@ static int omap_i2c_probe_chip(struct udevice *bus, uint chip_addr,
|
||||
{
|
||||
struct omap_i2c *priv = dev_get_priv(bus);
|
||||
|
||||
return __omap24_i2c_probe(priv->regs, priv->waitdelay, chip_addr);
|
||||
return __omap24_i2c_probe(priv->regs, priv->ip_rev, priv->waitdelay,
|
||||
chip_addr);
|
||||
}
|
||||
|
||||
static int omap_i2c_probe(struct udevice *bus)
|
||||
{
|
||||
struct omap_i2c *priv = dev_get_priv(bus);
|
||||
struct omap_i2c_platdata *plat = dev_get_platdata(bus);
|
||||
|
||||
__omap24_i2c_init(priv->regs, priv->speed, 0, &priv->waitdelay);
|
||||
priv->speed = plat->speed;
|
||||
priv->regs = map_physmem(plat->base, sizeof(void *),
|
||||
MAP_NOCACHE);
|
||||
priv->ip_rev = plat->ip_rev;
|
||||
|
||||
__omap24_i2c_init(priv->regs, priv->ip_rev, priv->speed, 0,
|
||||
&priv->waitdelay);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -893,18 +1063,18 @@ static int omap_i2c_probe(struct udevice *bus)
|
||||
#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
|
||||
static int omap_i2c_ofdata_to_platdata(struct udevice *bus)
|
||||
{
|
||||
struct omap_i2c *priv = dev_get_priv(bus);
|
||||
struct omap_i2c_platdata *plat = dev_get_platdata(bus);
|
||||
|
||||
priv->regs = map_physmem(devfdt_get_addr(bus), sizeof(void *),
|
||||
MAP_NOCACHE);
|
||||
priv->speed = CONFIG_SYS_OMAP24_I2C_SPEED;
|
||||
plat->base = devfdt_get_addr(bus);
|
||||
plat->speed = dev_read_u32_default(bus, "clock-frequency", 100000);
|
||||
plat->ip_rev = dev_get_driver_data(bus);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct udevice_id omap_i2c_ids[] = {
|
||||
{ .compatible = "ti,omap3-i2c" },
|
||||
{ .compatible = "ti,omap4-i2c" },
|
||||
{ .compatible = "ti,omap3-i2c", .data = OMAP_I2C_REV_V1 },
|
||||
{ .compatible = "ti,omap4-i2c", .data = OMAP_I2C_REV_V2 },
|
||||
{ }
|
||||
};
|
||||
#endif
|
||||
@ -921,6 +1091,7 @@ U_BOOT_DRIVER(i2c_omap) = {
|
||||
#if CONFIG_IS_ENABLED(OF_CONTROL) && !CONFIG_IS_ENABLED(OF_PLATDATA)
|
||||
.of_match = omap_i2c_ids,
|
||||
.ofdata_to_platdata = omap_i2c_ofdata_to_platdata,
|
||||
.platdata_auto_alloc_size = sizeof(struct omap_i2c_platdata),
|
||||
#endif
|
||||
.probe = omap_i2c_probe,
|
||||
.priv_auto_alloc_size = sizeof(struct omap_i2c),
|
||||
|
@ -175,3 +175,42 @@ int twl603x_enable_bb_charge(u8 bb_fields)
|
||||
val, err);
|
||||
return err;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DM_I2C
|
||||
int palmas_i2c_write_u8(u8 chip_no, u8 reg, u8 val)
|
||||
{
|
||||
struct udevice *dev;
|
||||
int ret;
|
||||
|
||||
ret = i2c_get_chip_for_busnum(0, chip_no, 1, &dev);
|
||||
if (ret) {
|
||||
pr_err("unable to get I2C bus. ret %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
ret = dm_i2c_reg_write(dev, reg, val);
|
||||
if (ret) {
|
||||
pr_err("writing to palmas failed. ret %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int palmas_i2c_read_u8(u8 chip_no, u8 reg, u8 *valp)
|
||||
{
|
||||
struct udevice *dev;
|
||||
int ret;
|
||||
|
||||
ret = i2c_get_chip_for_busnum(0, chip_no, 1, &dev);
|
||||
if (ret) {
|
||||
pr_err("unable to get I2C bus. ret %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
ret = dm_i2c_reg_read(dev, reg);
|
||||
if (ret < 0) {
|
||||
pr_err("reading from palmas failed. ret %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
*valp = (u8)ret;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -10,6 +10,10 @@
|
||||
#include <power/pmic.h>
|
||||
#include <power/tps62362.h>
|
||||
|
||||
#ifdef CONFIG_DM_I2C
|
||||
struct udevice *tps62362_dev __attribute__((section(".data"))) = NULL;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* tps62362_voltage_update() - Function to change a voltage level, as this
|
||||
* is a multi-step process.
|
||||
@ -22,9 +26,16 @@ int tps62362_voltage_update(unsigned char reg, unsigned char volt_sel)
|
||||
if (reg > TPS62362_NUM_REGS)
|
||||
return 1;
|
||||
|
||||
#ifndef CONFIG_DM_I2C
|
||||
return i2c_write(TPS62362_I2C_ADDR, reg, 1, &volt_sel, 1);
|
||||
#else
|
||||
if (!tps62362_dev)
|
||||
return -ENODEV;
|
||||
return dm_i2c_reg_write(tps62362_dev, reg, volt_sel);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef CONFIG_DM_I2C
|
||||
int power_tps62362_init(unsigned char bus)
|
||||
{
|
||||
static const char name[] = "TPS62362";
|
||||
@ -44,3 +55,16 @@ int power_tps62362_init(unsigned char bus)
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int power_tps62362_init(unsigned char bus)
|
||||
{
|
||||
struct udevice *dev = NULL;
|
||||
int rc;
|
||||
|
||||
rc = i2c_get_chip_for_busnum(bus, TPS62362_I2C_ADDR, 1, &dev);
|
||||
if (rc)
|
||||
return rc;
|
||||
tps62362_dev = dev;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -8,6 +8,8 @@
|
||||
#include <i2c.h>
|
||||
#include <power/tps65217.h>
|
||||
|
||||
struct udevice *tps65217_dev __attribute__((section(".data"))) = NULL;
|
||||
|
||||
/**
|
||||
* tps65217_reg_read() - Generic function that can read a TPS65217 register
|
||||
* @src_reg: Source register address
|
||||
@ -16,7 +18,11 @@
|
||||
*/
|
||||
int tps65217_reg_read(uchar src_reg, uchar *src_val)
|
||||
{
|
||||
#ifndef CONFIG_DM_I2C
|
||||
return i2c_read(TPS65217_CHIP_PM, src_reg, 1, src_val, 1);
|
||||
#else
|
||||
return dm_i2c_read(tps65217_dev, src_reg, src_val, 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
@ -46,9 +52,14 @@ int tps65217_reg_write(uchar prot_level, uchar dest_reg, uchar dest_val,
|
||||
* mask
|
||||
*/
|
||||
if (mask != TPS65217_MASK_ALL_BITS) {
|
||||
#ifndef CONFIG_DM_I2C
|
||||
ret = i2c_read(TPS65217_CHIP_PM, dest_reg, 1, &read_val, 1);
|
||||
#else
|
||||
ret = dm_i2c_read(tps65217_dev, dest_reg, &read_val, 1);
|
||||
#endif
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
read_val &= (~mask);
|
||||
read_val |= (dest_val & mask);
|
||||
dest_val = read_val;
|
||||
@ -56,23 +67,40 @@ int tps65217_reg_write(uchar prot_level, uchar dest_reg, uchar dest_val,
|
||||
|
||||
if (prot_level > 0) {
|
||||
xor_reg = dest_reg ^ TPS65217_PASSWORD_UNLOCK;
|
||||
#ifndef CONFIG_DM_I2C
|
||||
ret = i2c_write(TPS65217_CHIP_PM, TPS65217_PASSWORD, 1,
|
||||
&xor_reg, 1);
|
||||
#else
|
||||
ret = dm_i2c_write(tps65217_dev, TPS65217_PASSWORD,
|
||||
&xor_reg, 1);
|
||||
#endif
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_DM_I2C
|
||||
ret = i2c_write(TPS65217_CHIP_PM, dest_reg, 1, &dest_val, 1);
|
||||
#else
|
||||
ret = dm_i2c_write(tps65217_dev, dest_reg, &dest_val, 1);
|
||||
#endif
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (prot_level == TPS65217_PROT_LEVEL_2) {
|
||||
#ifndef CONFIG_DM_I2C
|
||||
ret = i2c_write(TPS65217_CHIP_PM, TPS65217_PASSWORD, 1,
|
||||
&xor_reg, 1);
|
||||
#else
|
||||
ret = dm_i2c_write(tps65217_dev, TPS65217_PASSWORD,
|
||||
&xor_reg, 1);
|
||||
#endif
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
#ifndef CONFIG_DM_I2C
|
||||
ret = i2c_write(TPS65217_CHIP_PM, dest_reg, 1, &dest_val, 1);
|
||||
#else
|
||||
ret = dm_i2c_write(tps65217_dev, dest_reg, &dest_val, 1);
|
||||
#endif
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
@ -106,3 +134,17 @@ int tps65217_voltage_update(uchar dc_cntrl_reg, uchar volt_sel)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int power_tps65217_init(unsigned char bus)
|
||||
{
|
||||
#ifdef CONFIG_DM_I2C
|
||||
struct udevice *dev = NULL;
|
||||
int rc;
|
||||
|
||||
rc = i2c_get_chip_for_busnum(bus, TPS65217_CHIP_PM, 1, &dev);
|
||||
if (rc)
|
||||
return rc;
|
||||
tps65217_dev = dev;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <power/pmic.h>
|
||||
#include <power/tps65218.h>
|
||||
|
||||
#ifndef CONFIG_DM_I2C
|
||||
int tps65218_reg_read(uchar dest_reg, uchar *dest_val)
|
||||
{
|
||||
uchar read_val;
|
||||
@ -84,6 +85,76 @@ int tps65218_reg_write(uchar prot_level, uchar dest_reg, uchar dest_val,
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
struct udevice *tps65218_dev __attribute__((section(".data"))) = NULL;
|
||||
|
||||
int tps65218_reg_read(uchar dest_reg, uchar *dest_val)
|
||||
{
|
||||
uchar read_val;
|
||||
int ret;
|
||||
|
||||
if (!tps65218_dev)
|
||||
return -ENODEV;
|
||||
|
||||
ret = dm_i2c_read(tps65218_dev, dest_reg, &read_val, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
*dest_val = read_val;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tps65218_reg_write(uchar prot_level, uchar dest_reg, uchar dest_val,
|
||||
uchar mask)
|
||||
{
|
||||
uchar read_val;
|
||||
uchar xor_reg;
|
||||
int ret;
|
||||
|
||||
if (!tps65218_dev)
|
||||
return -ENODEV;
|
||||
|
||||
/*
|
||||
* If we are affecting only a bit field, read dest_reg and apply the
|
||||
* mask
|
||||
*/
|
||||
if (mask != TPS65218_MASK_ALL_BITS) {
|
||||
ret = dm_i2c_read(tps65218_dev, dest_reg, &read_val, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
read_val &= (~mask);
|
||||
read_val |= (dest_val & mask);
|
||||
dest_val = read_val;
|
||||
}
|
||||
|
||||
if (prot_level > 0) {
|
||||
xor_reg = dest_reg ^ TPS65218_PASSWORD_UNLOCK;
|
||||
ret = dm_i2c_write(tps65218_dev, TPS65218_PASSWORD, &xor_reg,
|
||||
1);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = dm_i2c_write(tps65218_dev, dest_reg, &dest_val, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (prot_level == TPS65218_PROT_LEVEL_2) {
|
||||
ret = dm_i2c_write(tps65218_dev, TPS65218_PASSWORD, &xor_reg,
|
||||
1);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = dm_i2c_write(tps65218_dev, dest_reg, &dest_val, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* tps65218_voltage_update() - Function to change a voltage level, as this
|
||||
@ -154,6 +225,7 @@ int tps65218_lock_fseal(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_DM_I2C
|
||||
int power_tps65218_init(unsigned char bus)
|
||||
{
|
||||
static const char name[] = "TPS65218_PMIC";
|
||||
@ -173,3 +245,16 @@ int power_tps65218_init(unsigned char bus)
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
int power_tps65218_init(unsigned char bus)
|
||||
{
|
||||
struct udevice *dev = NULL;
|
||||
int rc;
|
||||
|
||||
rc = i2c_get_chip_for_busnum(bus, TPS65218_CHIP_PM, 1, &dev);
|
||||
if (rc)
|
||||
return rc;
|
||||
tps65218_dev = dev;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -8,6 +8,47 @@
|
||||
#include <i2c.h>
|
||||
#include <power/tps65910.h>
|
||||
|
||||
struct udevice *tps65910_dev __attribute__((section(".data"))) = NULL;
|
||||
|
||||
static inline int tps65910_read_reg(int addr, uchar *buf)
|
||||
{
|
||||
#ifndef CONFIG_DM_I2C
|
||||
return i2c_read(TPS65910_CTRL_I2C_ADDR, addr, 1, buf, 1);
|
||||
#else
|
||||
int rc;
|
||||
|
||||
rc = dm_i2c_reg_read(tps65910_dev, addr);
|
||||
if (rc < 0)
|
||||
return rc;
|
||||
*buf = (uchar)rc;
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline int tps65910_write_reg(int addr, uchar *buf)
|
||||
{
|
||||
#ifndef CONFIG_DM_I2C
|
||||
return i2c_write(TPS65910_CTRL_I2C_ADDR, addr, 1, buf, 1);
|
||||
#else
|
||||
return dm_i2c_reg_write(tps65910_dev, addr, *buf);
|
||||
#endif
|
||||
}
|
||||
|
||||
int power_tps65910_init(unsigned char bus)
|
||||
{
|
||||
#ifdef CONFIG_DM_I2C
|
||||
struct udevice *dev = NULL;
|
||||
int rc;
|
||||
|
||||
rc = i2c_get_chip_for_busnum(bus, TPS65910_CTRL_I2C_ADDR, 1, &dev);
|
||||
|
||||
if (rc)
|
||||
return rc;
|
||||
tps65910_dev = dev;
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* tps65910_set_i2c_control() - Set the TPS65910 to be controlled via the I2C
|
||||
* interface.
|
||||
@ -19,16 +60,14 @@ int tps65910_set_i2c_control(void)
|
||||
uchar buf;
|
||||
|
||||
/* VDD1/2 voltage selection register access by control i/f */
|
||||
ret = i2c_read(TPS65910_CTRL_I2C_ADDR, TPS65910_DEVCTRL_REG, 1,
|
||||
&buf, 1);
|
||||
ret = tps65910_read_reg(TPS65910_DEVCTRL_REG, &buf);
|
||||
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
buf |= TPS65910_DEVCTRL_REG_SR_CTL_I2C_SEL_CTL_I2C;
|
||||
|
||||
return i2c_write(TPS65910_CTRL_I2C_ADDR, TPS65910_DEVCTRL_REG, 1,
|
||||
&buf, 1);
|
||||
return tps65910_write_reg(TPS65910_DEVCTRL_REG, &buf);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -49,29 +88,29 @@ int tps65910_voltage_update(unsigned int module, unsigned char vddx_op_vol_sel)
|
||||
reg_offset = TPS65910_VDD2_OP_REG;
|
||||
|
||||
/* Select VDDx OP */
|
||||
ret = i2c_read(TPS65910_CTRL_I2C_ADDR, reg_offset, 1, &buf, 1);
|
||||
ret = tps65910_read_reg(reg_offset, &buf);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
buf &= ~TPS65910_OP_REG_CMD_MASK;
|
||||
|
||||
ret = i2c_write(TPS65910_CTRL_I2C_ADDR, reg_offset, 1, &buf, 1);
|
||||
ret = tps65910_write_reg(reg_offset, &buf);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Configure VDDx OP Voltage */
|
||||
ret = i2c_read(TPS65910_CTRL_I2C_ADDR, reg_offset, 1, &buf, 1);
|
||||
ret = tps65910_read_reg(reg_offset, &buf);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
buf &= ~TPS65910_OP_REG_SEL_MASK;
|
||||
buf |= vddx_op_vol_sel;
|
||||
|
||||
ret = i2c_write(TPS65910_CTRL_I2C_ADDR, reg_offset, 1, &buf, 1);
|
||||
ret = tps65910_write_reg(reg_offset, &buf);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = i2c_read(TPS65910_CTRL_I2C_ADDR, reg_offset, 1, &buf, 1);
|
||||
ret = tps65910_read_reg(reg_offset, &buf);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -179,3 +179,42 @@ int do_poweroff(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DM_I2C
|
||||
int twl4030_i2c_write_u8(u8 chip_no, u8 reg, u8 val)
|
||||
{
|
||||
struct udevice *dev;
|
||||
int ret;
|
||||
|
||||
ret = i2c_get_chip_for_busnum(0, chip_no, 1, &dev);
|
||||
if (ret) {
|
||||
pr_err("unable to get I2C bus. ret %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
ret = dm_i2c_reg_write(dev, reg, val);
|
||||
if (ret) {
|
||||
pr_err("writing to twl4030 failed. ret %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int twl4030_i2c_read_u8(u8 chip_no, u8 reg, u8 *valp)
|
||||
{
|
||||
struct udevice *dev;
|
||||
int ret;
|
||||
|
||||
ret = i2c_get_chip_for_busnum(0, chip_no, 1, &dev);
|
||||
if (ret) {
|
||||
pr_err("unable to get I2C bus. ret %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
ret = dm_i2c_reg_read(dev, reg);
|
||||
if (ret < 0) {
|
||||
pr_err("reading from twl4030 failed. ret %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
*valp = (u8)ret;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -268,3 +268,42 @@ void twl6030_usb_device_settings()
|
||||
value &= ~TWL6030_MISC2_VUSB_IN_PMID;
|
||||
twl6030_i2c_write_u8(TWL6030_CHIP_PM, TWL6030_MISC2, value);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DM_I2C
|
||||
int twl6030_i2c_write_u8(u8 chip_no, u8 reg, u8 val)
|
||||
{
|
||||
struct udevice *dev;
|
||||
int ret;
|
||||
|
||||
ret = i2c_get_chip_for_busnum(0, chip_no, 1, &dev);
|
||||
if (ret) {
|
||||
pr_err("unable to get I2C bus. ret %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
ret = dm_i2c_reg_write(dev, reg, val);
|
||||
if (ret) {
|
||||
pr_err("writing to twl6030 failed. ret %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int twl6030_i2c_read_u8(u8 chip_no, u8 reg, u8 *valp)
|
||||
{
|
||||
struct udevice *dev;
|
||||
int ret;
|
||||
|
||||
ret = i2c_get_chip_for_busnum(0, chip_no, 1, &dev);
|
||||
if (ret) {
|
||||
pr_err("unable to get I2C bus. ret %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
ret = dm_i2c_reg_read(dev, reg);
|
||||
if (ret < 0) {
|
||||
pr_err("reading from twl6030 failed. ret %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
*valp = (u8)ret;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
@ -77,6 +77,10 @@ typedef struct global_data {
|
||||
#ifdef CONFIG_OF_LIVE
|
||||
struct device_node *of_root;
|
||||
#endif
|
||||
|
||||
#if CONFIG_IS_ENABLED(MULTI_DTB_FIT)
|
||||
const void *multi_dtb_fit; /* uncompressed multi-dtb FIT image */
|
||||
#endif
|
||||
struct jt_funcs *jt; /* jump table */
|
||||
char env_buf[32]; /* buffer for env_get() before reloc. */
|
||||
#ifdef CONFIG_TRACE
|
||||
|
@ -27,8 +27,10 @@
|
||||
#define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2
|
||||
|
||||
/* Power */
|
||||
#ifndef CONFIG_DM_I2C
|
||||
#define CONFIG_POWER
|
||||
#define CONFIG_POWER_I2C
|
||||
#endif
|
||||
#define CONFIG_POWER_TPS65218
|
||||
#define CONFIG_POWER_TPS62362
|
||||
|
||||
|
@ -12,12 +12,6 @@
|
||||
|
||||
#include <configs/ti_am335x_common.h>
|
||||
|
||||
/* No more need for I2C legacy compatibility for this board.
|
||||
* CONFIG_DM_I2C_COMPAT is defined in ti_armv7_common.h. See the comment there
|
||||
* for the right moment to delete the following line.
|
||||
*/
|
||||
#undef CONFIG_DM_I2C_COMPAT
|
||||
|
||||
/* Using 32K of volatile storage for environment */
|
||||
#define CONFIG_ENV_SIZE 0x4000
|
||||
|
||||
|
@ -74,24 +74,10 @@
|
||||
/* Timer information. */
|
||||
#define CONFIG_SYS_PTV 2 /* Divisor: 2^(PTV+1) => 8 */
|
||||
|
||||
/*
|
||||
* Disable DM_* for SPL build and can be re-enabled after adding
|
||||
* DM support in SPL
|
||||
*/
|
||||
#ifdef CONFIG_SPL_BUILD
|
||||
#undef CONFIG_DM_I2C
|
||||
#endif
|
||||
|
||||
/* I2C IP block */
|
||||
/* If DM_I2C, enable non-DM I2C support */
|
||||
#if !defined(CONFIG_DM_I2C)
|
||||
#define CONFIG_I2C
|
||||
#ifndef CONFIG_DM_I2C
|
||||
#define CONFIG_SYS_I2C
|
||||
#else
|
||||
/*
|
||||
* Enable CONFIG_DM_I2C_COMPAT temporarily until all the i2c client
|
||||
* devices are adopted to DM
|
||||
*/
|
||||
#define CONFIG_DM_I2C_COMPAT
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
@ -11,6 +11,19 @@
|
||||
|
||||
#include <dm/ofnode.h>
|
||||
|
||||
/**
|
||||
* uclass_find_next_free_req_seq() - Get the next free req_seq number
|
||||
*
|
||||
* This returns the next free req_seq number. This is useful only if
|
||||
* OF_CONTROL is not used. The next free req_seq number is simply the
|
||||
* maximum req_seq of the uclass + 1.
|
||||
* This allows assiging req_seq number in the binding order.
|
||||
*
|
||||
* @id: Id number of the uclass
|
||||
* @return The next free req_seq number
|
||||
*/
|
||||
int uclass_find_next_free_req_seq(enum uclass_id id);
|
||||
|
||||
/**
|
||||
* uclass_get_device_tail() - handle the end of a get_device call
|
||||
*
|
||||
|
@ -951,6 +951,27 @@ int fdtdec_setup_memory_banksize(void);
|
||||
*/
|
||||
int fdtdec_setup(void);
|
||||
|
||||
#if CONFIG_IS_ENABLED(MULTI_DTB_FIT)
|
||||
/**
|
||||
* fdtdec_resetup() - Set up the device tree again
|
||||
*
|
||||
* The main difference with fdtdec_setup() is that it returns if the fdt has
|
||||
* changed because a better match has been found.
|
||||
* This is typically used for boards that rely on a DM driver to detect the
|
||||
* board type. This function sould be called by the board code after the stuff
|
||||
* needed by board_fit_config_name_match() to operate porperly is available.
|
||||
* If this functions signals that a rescan is necessary, the board code must
|
||||
* unbind all the drivers using dm_uninit() and then rescan the DT with
|
||||
* dm_init_and_scan().
|
||||
*
|
||||
* @param rescan Returns a flag indicating that fdt has changed and rescanning
|
||||
* the fdt is required
|
||||
*
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int fdtdec_resetup(int *rescan);
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Board-specific FDT initialization. Returns the address to a device tree blob.
|
||||
* Called when CONFIG_OF_BOARD is defined, or if CONFIG_OF_SEPARATE is defined
|
||||
|
@ -117,6 +117,7 @@
|
||||
#define BB_VSEL_VBAT (3 << 1)
|
||||
#define BB_CHRG_EN (1 << 0)
|
||||
|
||||
#ifndef CONFIG_DM_I2C
|
||||
/*
|
||||
* Functions to read and write from TPS659038/TWL6035/TWL6037
|
||||
* or other Palmas family of TI PMICs
|
||||
@ -130,6 +131,10 @@ static inline int palmas_i2c_read_u8(u8 chip_no, u8 reg, u8 *val)
|
||||
{
|
||||
return i2c_read(chip_no, reg, 1, val, 1);
|
||||
}
|
||||
#else
|
||||
int palmas_i2c_write_u8(u8 chip_no, u8 reg, u8 val);
|
||||
int palmas_i2c_read_u8(u8 chip_no, u8 reg, u8 *val);
|
||||
#endif
|
||||
|
||||
void palmas_init_settings(void);
|
||||
int palmas_mmc1_poweron_ldo(uint ldo_volt, uint ldo_ctrl, uint voltage);
|
||||
|
@ -80,6 +80,8 @@ enum {
|
||||
#define TPS65217_PWR_SRC_USB_BITMASK 0x4
|
||||
#define TPS65217_PWR_SRC_AC_BITMASK 0x8
|
||||
|
||||
int power_tps65217_init(unsigned char bus);
|
||||
|
||||
int tps65217_reg_read(uchar src_reg, uchar *src_val);
|
||||
int tps65217_reg_write(uchar prot_level, uchar dest_reg, uchar dest_val,
|
||||
uchar mask);
|
||||
|
@ -72,6 +72,7 @@ enum {
|
||||
#define TPS65910_DEVCTRL_REG_SR_CTL_I2C_SEL_SR_I2C (0x0 << 4)
|
||||
#define TPS65910_DEVCTRL_REG_SR_CTL_I2C_SEL_CTL_I2C (0x1 << 4)
|
||||
|
||||
int power_tps65910_init(unsigned char bus);
|
||||
int tps65910_set_i2c_control(void);
|
||||
int tps65910_voltage_update(unsigned int module, unsigned char vddx_op_vol_sel);
|
||||
#endif /* __POWER_TPS65910_H__ */
|
||||
|
@ -648,6 +648,7 @@
|
||||
* examples are TWL4030_PM_RECEIVER_VMMC1_DEV_GRP and
|
||||
* TWL4030_LED_LEDEN.
|
||||
*/
|
||||
#ifndef CONFIG_DM_I2C
|
||||
static inline int twl4030_i2c_write_u8(u8 chip_no, u8 reg, u8 val)
|
||||
{
|
||||
return i2c_write(chip_no, reg, 1, &val, 1);
|
||||
@ -657,7 +658,10 @@ static inline int twl4030_i2c_read_u8(u8 chip_no, u8 reg, u8 *val)
|
||||
{
|
||||
return i2c_read(chip_no, reg, 1, val, 1);
|
||||
}
|
||||
|
||||
#else
|
||||
int twl4030_i2c_write_u8(u8 chip_no, u8 reg, u8 val);
|
||||
int twl4030_i2c_read_u8(u8 chip_no, u8 reg, u8 *val);
|
||||
#endif
|
||||
/*
|
||||
* Power
|
||||
*/
|
||||
|
@ -186,6 +186,7 @@ struct twl6030_data{
|
||||
};
|
||||
|
||||
/* Functions to read and write from TWL6030 */
|
||||
#ifndef CONFIG_DM_I2C
|
||||
static inline int twl6030_i2c_write_u8(u8 chip_no, u8 reg, u8 val)
|
||||
{
|
||||
return i2c_write(chip_no, reg, 1, &val, 1);
|
||||
@ -195,6 +196,10 @@ static inline int twl6030_i2c_read_u8(u8 chip_no, u8 reg, u8 *val)
|
||||
{
|
||||
return i2c_read(chip_no, reg, 1, val, 1);
|
||||
}
|
||||
#else
|
||||
int twl6030_i2c_write_u8(u8 chip_no, u8 reg, u8 val);
|
||||
int twl6030_i2c_read_u8(u8 chip_no, u8 reg, u8 *val);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Power
|
||||
|
43
lib/fdtdec.c
43
lib/fdtdec.c
@ -1275,14 +1275,55 @@ int fdtdec_setup(void)
|
||||
* If so, pick the most relevant
|
||||
*/
|
||||
fdt_blob = locate_dtb_in_fit(gd->fdt_blob);
|
||||
if (fdt_blob)
|
||||
if (fdt_blob) {
|
||||
gd->multi_dtb_fit = gd->fdt_blob;
|
||||
gd->fdt_blob = fdt_blob;
|
||||
}
|
||||
|
||||
# endif
|
||||
#endif
|
||||
|
||||
return fdtdec_prepare_fdt();
|
||||
}
|
||||
|
||||
#if CONFIG_IS_ENABLED(MULTI_DTB_FIT)
|
||||
int fdtdec_resetup(int *rescan)
|
||||
{
|
||||
void *fdt_blob;
|
||||
|
||||
/*
|
||||
* If the current DTB is part of a compressed FIT image,
|
||||
* try to locate the best match from the uncompressed
|
||||
* FIT image stillpresent there. Save the time and space
|
||||
* required to uncompress it again.
|
||||
*/
|
||||
if (gd->multi_dtb_fit) {
|
||||
fdt_blob = locate_dtb_in_fit(gd->multi_dtb_fit);
|
||||
|
||||
if (fdt_blob == gd->fdt_blob) {
|
||||
/*
|
||||
* The best match did not change. no need to tear down
|
||||
* the DM and rescan the fdt.
|
||||
*/
|
||||
*rescan = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
*rescan = 1;
|
||||
gd->fdt_blob = fdt_blob;
|
||||
return fdtdec_prepare_fdt();
|
||||
}
|
||||
|
||||
/*
|
||||
* If multi_dtb_fit is NULL, it means that blob appended to u-boot is
|
||||
* not a FIT image containings DTB, but a single DTB. There is no need
|
||||
* to teard down DM and rescan the DT in this case.
|
||||
*/
|
||||
*rescan = 0;
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_NR_DRAM_BANKS
|
||||
int fdtdec_decode_ram_size(const void *blob, const char *area, int board_id,
|
||||
phys_addr_t *basep, phys_size_t *sizep, bd_t *bd)
|
||||
|
Loading…
Reference in New Issue
Block a user