|
|
|
@ -1,4 +1,9 @@ |
|
|
|
|
/*
|
|
|
|
|
* (C) Copyright 2009 |
|
|
|
|
* Sergey Kubushyn, himself, ksi@koi8.net |
|
|
|
|
* |
|
|
|
|
* Changes for unified multibus/multiadapter I2C support. |
|
|
|
|
* |
|
|
|
|
* (C) Copyright 2001 |
|
|
|
|
* Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com. |
|
|
|
|
* |
|
|
|
@ -85,6 +90,8 @@ |
|
|
|
|
#include <asm/byteorder.h> |
|
|
|
|
#include <linux/compiler.h> |
|
|
|
|
|
|
|
|
|
DECLARE_GLOBAL_DATA_PTR; |
|
|
|
|
|
|
|
|
|
/* Display values from last command.
|
|
|
|
|
* Memory modify remembered values are different from display memory. |
|
|
|
|
*/ |
|
|
|
@ -103,7 +110,8 @@ static uint i2c_mm_last_alen; |
|
|
|
|
* pairs. The following macros take care of this */ |
|
|
|
|
|
|
|
|
|
#if defined(CONFIG_SYS_I2C_NOPROBES) |
|
|
|
|
#if defined(CONFIG_I2C_MULTI_BUS) |
|
|
|
|
#if defined(CONFIG_SYS_I2C) || defined(CONFIG_I2C_MUX) || \ |
|
|
|
|
defined(CONFIG_I2C_MULTI_BUS) |
|
|
|
|
static struct |
|
|
|
|
{ |
|
|
|
|
uchar bus; |
|
|
|
@ -119,7 +127,7 @@ static uchar i2c_no_probes[] = CONFIG_SYS_I2C_NOPROBES; |
|
|
|
|
#define COMPARE_BUS(b,i) ((b) == 0) /* Make compiler happy */ |
|
|
|
|
#define COMPARE_ADDR(a,i) (i2c_no_probes[(i)] == (a)) |
|
|
|
|
#define NO_PROBE_ADDR(i) i2c_no_probes[(i)] |
|
|
|
|
#endif /* CONFIG_MULTI_BUS */ |
|
|
|
|
#endif /* defined(CONFIG_SYS_I2C) */ |
|
|
|
|
|
|
|
|
|
#define NUM_ELEMENTS_NOPROBE (sizeof(i2c_no_probes)/sizeof(i2c_no_probes[0])) |
|
|
|
|
#endif |
|
|
|
@ -127,9 +135,6 @@ static uchar i2c_no_probes[] = CONFIG_SYS_I2C_NOPROBES; |
|
|
|
|
#if defined(CONFIG_I2C_MUX) |
|
|
|
|
static I2C_MUX_DEVICE *i2c_mux_devices = NULL; |
|
|
|
|
static int i2c_mux_busid = CONFIG_SYS_MAX_I2C_BUS; |
|
|
|
|
|
|
|
|
|
DECLARE_GLOBAL_DATA_PTR; |
|
|
|
|
|
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#define DISP_LINE_LEN 16 |
|
|
|
@ -144,7 +149,6 @@ DECLARE_GLOBAL_DATA_PTR; |
|
|
|
|
__weak |
|
|
|
|
void i2c_init_board(void) |
|
|
|
|
{ |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/* TODO: Implement architecture-specific get/set functions */ |
|
|
|
@ -161,6 +165,11 @@ void i2c_init_board(void) |
|
|
|
|
* |
|
|
|
|
* Returns I2C bus speed in Hz. |
|
|
|
|
*/ |
|
|
|
|
#if !defined(CONFIG_SYS_I2C) |
|
|
|
|
/*
|
|
|
|
|
* TODO: Implement architecture-specific get/set functions |
|
|
|
|
* Should go away, if we switched completely to new multibus support |
|
|
|
|
*/ |
|
|
|
|
__weak |
|
|
|
|
unsigned int i2c_get_bus_speed(void) |
|
|
|
|
{ |
|
|
|
@ -188,6 +197,7 @@ int i2c_set_bus_speed(unsigned int speed) |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* get_alen() - Small parser helper function to get address length |
|
|
|
@ -700,7 +710,7 @@ static int do_i2c_probe (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv |
|
|
|
|
int found = 0; |
|
|
|
|
#if defined(CONFIG_SYS_I2C_NOPROBES) |
|
|
|
|
int k, skip; |
|
|
|
|
uchar bus = GET_BUS_NUM; |
|
|
|
|
unsigned int bus = GET_BUS_NUM; |
|
|
|
|
#endif /* NOPROBES */ |
|
|
|
|
|
|
|
|
|
if (argc == 2) |
|
|
|
@ -1373,9 +1383,8 @@ int do_edid(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) |
|
|
|
|
} |
|
|
|
|
#endif /* CONFIG_I2C_EDID */ |
|
|
|
|
|
|
|
|
|
#if defined(CONFIG_I2C_MUX) |
|
|
|
|
/**
|
|
|
|
|
* do_i2c_add_bus() - Handle the "i2c bus" command-line command |
|
|
|
|
* do_i2c_show_bus() - Handle the "i2c bus" command-line command |
|
|
|
|
* @cmdtp: Command data struct pointer |
|
|
|
|
* @flag: Command flag |
|
|
|
|
* @argc: Command-line argument count |
|
|
|
@ -1383,35 +1392,55 @@ int do_edid(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) |
|
|
|
|
* |
|
|
|
|
* Returns zero always. |
|
|
|
|
*/ |
|
|
|
|
static int do_i2c_add_bus(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) |
|
|
|
|
#if defined(CONFIG_SYS_I2C) |
|
|
|
|
int do_i2c_show_bus(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
|
|
|
|
{ |
|
|
|
|
int ret=0; |
|
|
|
|
int i; |
|
|
|
|
#ifndef CONFIG_SYS_I2C_DIRECT_BUS |
|
|
|
|
int j; |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
if (argc == 1) { |
|
|
|
|
/* show all busses */ |
|
|
|
|
I2C_MUX *mux; |
|
|
|
|
I2C_MUX_DEVICE *device = i2c_mux_devices; |
|
|
|
|
|
|
|
|
|
printf ("Busses reached over muxes:\n"); |
|
|
|
|
while (device != NULL) { |
|
|
|
|
printf ("Bus ID: %x\n", device->busid); |
|
|
|
|
printf (" reached over Mux(es):\n"); |
|
|
|
|
mux = device->mux; |
|
|
|
|
while (mux != NULL) { |
|
|
|
|
printf (" %s@%x ch: %x\n", mux->name, mux->chip, mux->channel); |
|
|
|
|
mux = mux->next; |
|
|
|
|
for (i = 0; i < CONFIG_SYS_NUM_I2C_BUSES; i++) { |
|
|
|
|
printf("Bus %d:\t%s", i, I2C_ADAP_NR(i)->name); |
|
|
|
|
#ifndef CONFIG_SYS_I2C_DIRECT_BUS |
|
|
|
|
for (j = 0; j < CONFIG_SYS_I2C_MAX_HOPS; j++) { |
|
|
|
|
if (i2c_bus[i].next_hop[j].chip == 0) |
|
|
|
|
break; |
|
|
|
|
printf("->%s@0x%2x:%d", |
|
|
|
|
i2c_bus[i].next_hop[j].mux.name, |
|
|
|
|
i2c_bus[i].next_hop[j].chip, |
|
|
|
|
i2c_bus[i].next_hop[j].channel); |
|
|
|
|
} |
|
|
|
|
device = device->next; |
|
|
|
|
#endif |
|
|
|
|
printf("\n"); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
(void)i2c_mux_ident_muxstring ((uchar *)argv[1]); |
|
|
|
|
ret = 0; |
|
|
|
|
/* show specific bus */ |
|
|
|
|
i = simple_strtoul(argv[1], NULL, 10); |
|
|
|
|
if (i >= CONFIG_SYS_NUM_I2C_BUSES) { |
|
|
|
|
printf("Invalid bus %d\n", i); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
printf("Bus %d:\t%s", i, I2C_ADAP_NR(i)->name); |
|
|
|
|
#ifndef CONFIG_SYS_I2C_DIRECT_BUS |
|
|
|
|
for (j = 0; j < CONFIG_SYS_I2C_MAX_HOPS; j++) { |
|
|
|
|
if (i2c_bus[i].next_hop[j].chip == 0) |
|
|
|
|
break; |
|
|
|
|
printf("->%s@0x%2x:%d", |
|
|
|
|
i2c_bus[i].next_hop[j].mux.name, |
|
|
|
|
i2c_bus[i].next_hop[j].chip, |
|
|
|
|
i2c_bus[i].next_hop[j].channel); |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
printf("\n"); |
|
|
|
|
} |
|
|
|
|
return ret; |
|
|
|
|
|
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
#endif /* CONFIG_I2C_MUX */ |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
#if defined(CONFIG_I2C_MULTI_BUS) |
|
|
|
|
/**
|
|
|
|
|
* do_i2c_bus_num() - Handle the "i2c dev" command-line command |
|
|
|
|
* @cmdtp: Command data struct pointer |
|
|
|
@ -1422,23 +1451,29 @@ static int do_i2c_add_bus(cmd_tbl_t * cmdtp, int flag, int argc, char * const ar |
|
|
|
|
* Returns zero on success, CMD_RET_USAGE in case of misuse and negative |
|
|
|
|
* on error. |
|
|
|
|
*/ |
|
|
|
|
static int do_i2c_bus_num(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) |
|
|
|
|
#if defined(CONFIG_SYS_I2C) || defined(CONFIG_I2C_MULTI_BUS) |
|
|
|
|
int do_i2c_bus_num(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
|
|
|
|
{ |
|
|
|
|
int bus_idx, ret=0; |
|
|
|
|
int ret = 0; |
|
|
|
|
unsigned int bus_no; |
|
|
|
|
|
|
|
|
|
if (argc == 1) |
|
|
|
|
/* querying current setting */ |
|
|
|
|
printf("Current bus is %d\n", i2c_get_bus_num()); |
|
|
|
|
else { |
|
|
|
|
bus_idx = simple_strtoul(argv[1], NULL, 10); |
|
|
|
|
printf("Setting bus to %d\n", bus_idx); |
|
|
|
|
ret = i2c_set_bus_num(bus_idx); |
|
|
|
|
bus_no = simple_strtoul(argv[1], NULL, 10); |
|
|
|
|
if (bus_no >= CONFIG_SYS_NUM_I2C_BUSES) { |
|
|
|
|
printf("Invalid bus %d\n", bus_no); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
printf("Setting bus to %d\n", bus_no); |
|
|
|
|
ret = i2c_set_bus_num(bus_no); |
|
|
|
|
if (ret) |
|
|
|
|
printf("Failure changing bus number (%d)\n", ret); |
|
|
|
|
} |
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
|
#endif /* CONFIG_I2C_MULTI_BUS */ |
|
|
|
|
#endif /* defined(CONFIG_SYS_I2C) */ |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* do_i2c_bus_speed() - Handle the "i2c speed" command-line command |
|
|
|
@ -1508,16 +1543,21 @@ static int do_i2c_nm(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) |
|
|
|
|
*/ |
|
|
|
|
static int do_i2c_reset(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) |
|
|
|
|
{ |
|
|
|
|
#if defined(CONFIG_SYS_I2C) |
|
|
|
|
i2c_init(I2C_ADAP->speed, I2C_ADAP->slaveaddr); |
|
|
|
|
#else |
|
|
|
|
i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); |
|
|
|
|
#endif |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static cmd_tbl_t cmd_i2c_sub[] = { |
|
|
|
|
#if defined(CONFIG_I2C_MUX) |
|
|
|
|
U_BOOT_CMD_MKENT(bus, 1, 1, do_i2c_add_bus, "", ""), |
|
|
|
|
#if defined(CONFIG_SYS_I2C) |
|
|
|
|
U_BOOT_CMD_MKENT(bus, 1, 1, do_i2c_show_bus, "", ""), |
|
|
|
|
#endif /* CONFIG_I2C_MUX */ |
|
|
|
|
U_BOOT_CMD_MKENT(crc32, 3, 1, do_i2c_crc, "", ""), |
|
|
|
|
#if defined(CONFIG_I2C_MULTI_BUS) |
|
|
|
|
#if defined(CONFIG_SYS_I2C) || \ |
|
|
|
|
defined(CONFIG_I2C_MULTI_BUS) |
|
|
|
|
U_BOOT_CMD_MKENT(dev, 1, 1, do_i2c_bus_num, "", ""), |
|
|
|
|
#endif /* CONFIG_I2C_MULTI_BUS */ |
|
|
|
|
#if defined(CONFIG_I2C_EDID) |
|
|
|
@ -1576,11 +1616,12 @@ static int do_i2c(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) |
|
|
|
|
/***************************************************/ |
|
|
|
|
#ifdef CONFIG_SYS_LONGHELP |
|
|
|
|
static char i2c_help_text[] = |
|
|
|
|
#if defined(CONFIG_I2C_MUX) |
|
|
|
|
"bus [muxtype:muxaddr:muxchannel] - add a new bus reached over muxes\ni2c " |
|
|
|
|
#if defined(CONFIG_SYS_I2C) |
|
|
|
|
"bus [muxtype:muxaddr:muxchannel] - show I2C bus info\n" |
|
|
|
|
#endif /* CONFIG_I2C_MUX */ |
|
|
|
|
"crc32 chip address[.0, .1, .2] count - compute CRC32 checksum\n" |
|
|
|
|
#if defined(CONFIG_I2C_MULTI_BUS) |
|
|
|
|
#if defined(CONFIG_SYS_I2C) || \ |
|
|
|
|
defined(CONFIG_I2C_MULTI_BUS) |
|
|
|
|
"i2c dev [dev] - show or set current I2C bus\n" |
|
|
|
|
#endif /* CONFIG_I2C_MULTI_BUS */ |
|
|
|
|
#if defined(CONFIG_I2C_EDID) |
|
|
|
|