X-Git-Url: https://git.kernelconcepts.de/?a=blobdiff_plain;f=common%2Fcmd_i2c.c;h=1bc0db860c3344dad85466fc52c0c61cddca3998;hb=28dbcc15dcd0a2a1541ab8dce59e3f20bd59d43a;hp=22db1bb47c137fd4fe08fc20e3e2f75fba72f16f;hpb=bd5053ffa5b8162257537bdb79ba829372423096;p=karo-tx-uboot.git diff --git a/common/cmd_i2c.c b/common/cmd_i2c.c index 22db1bb47c..1bc0db860c 100644 --- a/common/cmd_i2c.c +++ b/common/cmd_i2c.c @@ -83,12 +83,12 @@ DECLARE_GLOBAL_DATA_PTR; /* Display values from last command. * Memory modify remembered values are different from display memory. */ -static uchar i2c_dp_last_chip; +static uint i2c_dp_last_chip; static uint i2c_dp_last_addr; static uint i2c_dp_last_alen; static uint i2c_dp_last_length = 0x10; -static uchar i2c_mm_last_chip; +static uint i2c_mm_last_chip; static uint i2c_mm_last_addr; static uint i2c_mm_last_alen; @@ -133,7 +133,7 @@ static uchar i2c_no_probes[] = CONFIG_SYS_I2C_NOPROBES; #ifdef CONFIG_DM_I2C static struct udevice *i2c_cur_bus; -static int i2c_set_bus_num(unsigned int busnum) +static int cmd_i2c_set_bus_num(unsigned int busnum) { struct udevice *bus; int ret; @@ -168,7 +168,7 @@ static int i2c_get_cur_bus_chip(uint chip_addr, struct udevice **devp) if (ret) return ret; - return i2c_get_chip(bus, chip_addr, devp); + return i2c_get_chip(bus, chip_addr, 1, devp); } #endif @@ -282,7 +282,7 @@ static int i2c_report_err(int ret, enum i2c_err_op op) */ static int do_i2c_read ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - u_char chip; + uint chip; uint devaddr, length; int alen; u_char *memaddr; @@ -323,7 +323,7 @@ static int do_i2c_read ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv if (!ret && alen != -1) ret = i2c_set_chip_offset_len(dev, alen); if (!ret) - ret = i2c_read(dev, devaddr, memaddr, length); + ret = dm_i2c_read(dev, devaddr, memaddr, length); #else ret = i2c_read(chip, devaddr, alen, memaddr, length); #endif @@ -335,16 +335,17 @@ static int do_i2c_read ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv static int do_i2c_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - u_char chip; + uint chip; uint devaddr, length; int alen; u_char *memaddr; int ret; #ifdef CONFIG_DM_I2C struct udevice *dev; + struct dm_i2c_chip *i2c_chip; #endif - if (argc != 5) + if ((argc < 5) || (argc > 6)) return cmd_usage(cmdtp); /* @@ -367,7 +368,7 @@ static int do_i2c_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[ return cmd_usage(cmdtp); /* - * Length is the number of objects, not number of bytes. + * Length is the number of bytes. */ length = simple_strtoul(argv[4], NULL, 16); @@ -377,22 +378,47 @@ static int do_i2c_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[ ret = i2c_set_chip_offset_len(dev, alen); if (ret) return i2c_report_err(ret, I2C_ERR_WRITE); + i2c_chip = dev_get_parent_platdata(dev); + if (!i2c_chip) + return i2c_report_err(ret, I2C_ERR_WRITE); #endif - while (length-- > 0) { + if (argc == 6 && !strcmp(argv[5], "-s")) { + /* + * Write all bytes in a single I2C transaction. If the target + * device is an EEPROM, it is your responsibility to not cross + * a page boundary. No write delay upon completion, take this + * into account if linking commands. + */ #ifdef CONFIG_DM_I2C - ret = i2c_write(dev, devaddr++, memaddr++, 1); + i2c_chip->flags &= ~DM_I2C_CHIP_WR_ADDRESS; + ret = dm_i2c_write(dev, devaddr, memaddr, length); #else - ret = i2c_write(chip, devaddr++, alen, memaddr++, 1); + ret = i2c_write(chip, devaddr, alen, memaddr, length); #endif if (ret) return i2c_report_err(ret, I2C_ERR_WRITE); + } else { + /* + * Repeated addressing - perform separate + * write transactions of one byte each + */ + while (length-- > 0) { +#ifdef CONFIG_DM_I2C + i2c_chip->flags |= DM_I2C_CHIP_WR_ADDRESS; + ret = dm_i2c_write(dev, devaddr++, memaddr++, 1); +#else + ret = i2c_write(chip, devaddr++, alen, memaddr++, 1); +#endif + if (ret) + return i2c_report_err(ret, I2C_ERR_WRITE); /* * No write delay with FRAM devices. */ #if !defined(CONFIG_SYS_I2C_FRAM) - udelay(11000); + udelay(11000); #endif + } } return 0; } @@ -444,7 +470,7 @@ static int do_i2c_flags(cmd_tbl_t *cmdtp, int flag, int argc, */ static int do_i2c_md ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - u_char chip; + uint chip; uint addr, length; int alen; int j, nbytes, linebytes; @@ -513,12 +539,12 @@ static int do_i2c_md ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] linebytes = (nbytes > DISP_LINE_LEN) ? DISP_LINE_LEN : nbytes; #ifdef CONFIG_DM_I2C - ret = i2c_read(dev, addr, linebuf, linebytes); + ret = dm_i2c_read(dev, addr, linebuf, linebytes); #else ret = i2c_read(chip, addr, alen, linebuf, linebytes); #endif if (ret) - i2c_report_err(ret, I2C_ERR_READ); + return i2c_report_err(ret, I2C_ERR_READ); else { printf("%04x:", addr); cp = linebuf; @@ -563,7 +589,7 @@ static int do_i2c_md ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] */ static int do_i2c_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - uchar chip; + uint chip; ulong addr; int alen; uchar byte; @@ -611,12 +637,12 @@ static int do_i2c_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] while (count-- > 0) { #ifdef CONFIG_DM_I2C - ret = i2c_write(dev, addr++, &byte, 1); + ret = dm_i2c_write(dev, addr++, &byte, 1); #else ret = i2c_write(chip, addr++, alen, &byte, 1); #endif if (ret) - i2c_report_err(ret, I2C_ERR_WRITE); + return i2c_report_err(ret, I2C_ERR_WRITE); /* * Wait for the write to complete. The write can take * up to 10mSec (we allow a little more time). @@ -649,7 +675,7 @@ static int do_i2c_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] */ static int do_i2c_crc (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - uchar chip; + uint chip; ulong addr; int alen; int count; @@ -698,7 +724,7 @@ static int do_i2c_crc (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] err = 0; while (count-- > 0) { #ifdef CONFIG_DM_I2C - ret = i2c_read(dev, addr, &byte, 1); + ret = dm_i2c_read(dev, addr, &byte, 1); #else ret = i2c_read(chip, addr, alen, &byte, 1); #endif @@ -734,7 +760,7 @@ static int do_i2c_crc (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] static int mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[]) { - uchar chip; + uint chip; ulong addr; int alen; ulong data; @@ -793,21 +819,20 @@ mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const arg do { printf("%08lx:", addr); #ifdef CONFIG_DM_I2C - ret = i2c_read(dev, addr, (uchar *)&data, size); + ret = dm_i2c_read(dev, addr, (uchar *)&data, size); #else ret = i2c_read(chip, addr, alen, (uchar *)&data, size); #endif if (ret) - i2c_report_err(ret, I2C_ERR_READ); - else { - data = cpu_to_be32(data); - if (size == 1) - printf(" %02lx", (data >> 24) & 0x000000FF); - else if (size == 2) - printf(" %04lx", (data >> 16) & 0x0000FFFF); - else - printf(" %08lx", data); - } + return i2c_report_err(ret, I2C_ERR_READ); + + data = cpu_to_be32(data); + if (size == 1) + printf(" %02lx", (data >> 24) & 0x000000FF); + else if (size == 2) + printf(" %04lx", (data >> 16) & 0x0000FFFF); + else + printf(" %08lx", data); nbytes = cli_readline(" ? "); if (nbytes == 0) { @@ -841,14 +866,15 @@ mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const arg */ bootretry_reset_cmd_timeout(); #ifdef CONFIG_DM_I2C - ret = i2c_write(dev, addr, (uchar *)&data, - size); + ret = dm_i2c_write(dev, addr, (uchar *)&data, + size); #else ret = i2c_write(chip, addr, alen, (uchar *)&data, size); #endif if (ret) - i2c_report_err(ret, I2C_ERR_WRITE); + return i2c_report_err(ret, + I2C_ERR_WRITE); #ifdef CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS udelay(CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS * 1000); #endif @@ -917,7 +943,7 @@ static int do_i2c_probe (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv continue; #endif #ifdef CONFIG_DM_I2C - ret = i2c_probe(bus, j, 0, &dev); + ret = dm_i2c_probe(bus, j, 0, &dev); #else ret = i2c_probe(j); #endif @@ -957,7 +983,7 @@ static int do_i2c_probe (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv */ static int do_i2c_loop(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - u_char chip; + uint chip; int alen; uint addr; uint length; @@ -1010,7 +1036,7 @@ static int do_i2c_loop(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[] */ while (1) { #ifdef CONFIG_DM_I2C - ret = i2c_read(dev, addr, bytes, length); + ret = dm_i2c_read(dev, addr, bytes, length); #else ret = i2c_read(chip, addr, alen, bytes, length); #endif @@ -1085,7 +1111,7 @@ static int do_sdram (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) { enum { unknown, EDO, SDRAM, DDR2 } type; - u_char chip; + uint chip; u_char data[128]; u_char cksum; int j; @@ -1563,7 +1589,7 @@ static int do_sdram (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) #if defined(CONFIG_I2C_EDID) int do_edid(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) { - u_char chip; + uint chip; struct edid1_info edid; int ret; #ifdef CONFIG_DM_I2C @@ -1579,7 +1605,7 @@ int do_edid(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) #ifdef CONFIG_DM_I2C ret = i2c_get_cur_bus_chip(chip, &dev); if (!ret) - ret = i2c_read(dev, 0, (uchar *)&edid, sizeof(edid)); + ret = dm_i2c_read(dev, 0, (uchar *)&edid, sizeof(edid)); #else ret = i2c_read(chip, 0, 1, (uchar *)&edid, sizeof(edid)); #endif @@ -1597,6 +1623,27 @@ int do_edid(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) } #endif /* CONFIG_I2C_EDID */ +#ifdef CONFIG_DM_I2C +static void show_bus(struct udevice *bus) +{ + struct udevice *dev; + + printf("Bus %d:\t%s", bus->req_seq, bus->name); + if (device_active(bus)) + printf(" (active %d)", bus->seq); + printf("\n"); + for (device_find_first_child(bus, &dev); + dev; + device_find_next_child(&dev)) { + struct dm_i2c_chip *chip = dev_get_parent_platdata(dev); + + printf(" %02x: %s, offset len %x, flags %x\n", + chip->chip_addr, dev->name, chip->offset_len, + chip->flags); + } +} +#endif + /** * do_i2c_show_bus() - Handle the "i2c bus" command-line command * @cmdtp: Command data struct pointer @@ -1606,20 +1653,30 @@ int do_edid(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) * * Returns zero always. */ -#if defined(CONFIG_SYS_I2C) +#if defined(CONFIG_SYS_I2C) || defined(CONFIG_DM_I2C) static int do_i2c_show_bus(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - int i; -#ifndef CONFIG_SYS_I2C_DIRECT_BUS - int j; -#endif - if (argc == 1) { /* show all busses */ +#ifdef CONFIG_DM_I2C + struct udevice *bus; + struct uclass *uc; + int ret; + + ret = uclass_get(UCLASS_I2C, &uc); + if (ret) + return CMD_RET_FAILURE; + uclass_foreach_dev(bus, uc) + show_bus(bus); +#else + int i; + 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 + int j; + for (j = 0; j < CONFIG_SYS_I2C_MAX_HOPS; j++) { if (i2c_bus[i].next_hop[j].chip == 0) break; @@ -1631,15 +1688,30 @@ static int do_i2c_show_bus(cmd_tbl_t *cmdtp, int flag, int argc, #endif printf("\n"); } +#endif } else { + int i; + /* show specific bus */ i = simple_strtoul(argv[1], NULL, 10); +#ifdef CONFIG_DM_I2C + struct udevice *bus; + int ret; + + ret = uclass_get_device_by_seq(UCLASS_I2C, i, &bus); + if (ret) { + printf("Invalid bus %d: err=%d\n", i, ret); + return CMD_RET_FAILURE; + } + show_bus(bus); +#else 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 + int j; for (j = 0; j < CONFIG_SYS_I2C_MAX_HOPS; j++) { if (i2c_bus[i].next_hop[j].chip == 0) break; @@ -1650,6 +1722,7 @@ static int do_i2c_show_bus(cmd_tbl_t *cmdtp, int flag, int argc, } #endif printf("\n"); +#endif } return 0; @@ -1696,7 +1769,11 @@ static int do_i2c_bus_num(cmd_tbl_t *cmdtp, int flag, int argc, } #endif printf("Setting bus to %d\n", bus_no); +#ifdef CONFIG_DM_I2C + ret = cmd_i2c_set_bus_num(bus_no); +#else ret = i2c_set_bus_num(bus_no); +#endif if (ret) printf("Failure changing bus number (%d)\n", ret); } @@ -1726,7 +1803,7 @@ static int do_i2c_bus_speed(cmd_tbl_t * cmdtp, int flag, int argc, char * const #endif if (argc == 1) { #ifdef CONFIG_DM_I2C - speed = i2c_get_bus_speed(bus); + speed = dm_i2c_get_bus_speed(bus); #else speed = i2c_get_bus_speed(); #endif @@ -1736,7 +1813,7 @@ static int do_i2c_bus_speed(cmd_tbl_t * cmdtp, int flag, int argc, char * const speed = simple_strtoul(argv[1], NULL, 10); printf("Setting bus speed to %d Hz\n", speed); #ifdef CONFIG_DM_I2C - ret = i2c_set_bus_speed(bus, speed); + ret = dm_i2c_set_bus_speed(bus, speed); #else ret = i2c_set_bus_speed(speed); #endif @@ -1805,7 +1882,7 @@ static int do_i2c_reset(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv } static cmd_tbl_t cmd_i2c_sub[] = { -#if defined(CONFIG_SYS_I2C) +#if defined(CONFIG_SYS_I2C) || defined(CONFIG_DM_I2C) U_BOOT_CMD_MKENT(bus, 1, 1, do_i2c_show_bus, "", ""), #endif U_BOOT_CMD_MKENT(crc32, 3, 1, do_i2c_crc, "", ""), @@ -1823,7 +1900,7 @@ static cmd_tbl_t cmd_i2c_sub[] = { U_BOOT_CMD_MKENT(nm, 2, 1, do_i2c_nm, "", ""), U_BOOT_CMD_MKENT(probe, 0, 1, do_i2c_probe, "", ""), U_BOOT_CMD_MKENT(read, 5, 1, do_i2c_read, "", ""), - U_BOOT_CMD_MKENT(write, 5, 0, do_i2c_write, "", ""), + U_BOOT_CMD_MKENT(write, 6, 0, do_i2c_write, "", ""), #ifdef CONFIG_DM_I2C U_BOOT_CMD_MKENT(flags, 2, 1, do_i2c_flags, "", ""), #endif @@ -1872,7 +1949,7 @@ 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_SYS_I2C) +#if defined(CONFIG_SYS_I2C) || defined(CONFIG_DM_I2C) "bus [muxtype:muxaddr:muxchannel] - show I2C bus info\n" #endif "crc32 chip address[.0, .1, .2] count - compute CRC32 checksum\n" @@ -1890,7 +1967,8 @@ static char i2c_help_text[] = "i2c nm chip address[.0, .1, .2] - write to I2C device (constant address)\n" "i2c probe [address] - test for and show device(s) on the I2C bus\n" "i2c read chip address[.0, .1, .2] length memaddress - read to memory\n" - "i2c write memaddress chip address[.0, .1, .2] length - write memory to i2c\n" + "i2c write memaddress chip address[.0, .1, .2] length [-s] - write memory\n" + " to I2C; the -s option selects bulk write in a single transaction\n" #ifdef CONFIG_DM_I2C "i2c flags chip [flags] - set or get chip flags\n" #endif @@ -1902,7 +1980,7 @@ static char i2c_help_text[] = #endif U_BOOT_CMD( - i2c, 6, 1, do_i2c, + i2c, 7, 1, do_i2c, "I2C sub-system", i2c_help_text );