1*2e192b24SSimon Glass /* 2*2e192b24SSimon Glass * (C) Copyright 2009 3*2e192b24SSimon Glass * Sergey Kubushyn, himself, ksi@koi8.net 4*2e192b24SSimon Glass * 5*2e192b24SSimon Glass * Changes for unified multibus/multiadapter I2C support. 6*2e192b24SSimon Glass * 7*2e192b24SSimon Glass * (C) Copyright 2001 8*2e192b24SSimon Glass * Gerald Van Baren, Custom IDEAS, vanbaren@cideas.com. 9*2e192b24SSimon Glass * 10*2e192b24SSimon Glass * SPDX-License-Identifier: GPL-2.0+ 11*2e192b24SSimon Glass */ 12*2e192b24SSimon Glass 13*2e192b24SSimon Glass /* 14*2e192b24SSimon Glass * I2C Functions similar to the standard memory functions. 15*2e192b24SSimon Glass * 16*2e192b24SSimon Glass * There are several parameters in many of the commands that bear further 17*2e192b24SSimon Glass * explanations: 18*2e192b24SSimon Glass * 19*2e192b24SSimon Glass * {i2c_chip} is the I2C chip address (the first byte sent on the bus). 20*2e192b24SSimon Glass * Each I2C chip on the bus has a unique address. On the I2C data bus, 21*2e192b24SSimon Glass * the address is the upper seven bits and the LSB is the "read/write" 22*2e192b24SSimon Glass * bit. Note that the {i2c_chip} address specified on the command 23*2e192b24SSimon Glass * line is not shifted up: e.g. a typical EEPROM memory chip may have 24*2e192b24SSimon Glass * an I2C address of 0x50, but the data put on the bus will be 0xA0 25*2e192b24SSimon Glass * for write and 0xA1 for read. This "non shifted" address notation 26*2e192b24SSimon Glass * matches at least half of the data sheets :-/. 27*2e192b24SSimon Glass * 28*2e192b24SSimon Glass * {addr} is the address (or offset) within the chip. Small memory 29*2e192b24SSimon Glass * chips have 8 bit addresses. Large memory chips have 16 bit 30*2e192b24SSimon Glass * addresses. Other memory chips have 9, 10, or 11 bit addresses. 31*2e192b24SSimon Glass * Many non-memory chips have multiple registers and {addr} is used 32*2e192b24SSimon Glass * as the register index. Some non-memory chips have only one register 33*2e192b24SSimon Glass * and therefore don't need any {addr} parameter. 34*2e192b24SSimon Glass * 35*2e192b24SSimon Glass * The default {addr} parameter is one byte (.1) which works well for 36*2e192b24SSimon Glass * memories and registers with 8 bits of address space. 37*2e192b24SSimon Glass * 38*2e192b24SSimon Glass * You can specify the length of the {addr} field with the optional .0, 39*2e192b24SSimon Glass * .1, or .2 modifier (similar to the .b, .w, .l modifier). If you are 40*2e192b24SSimon Glass * manipulating a single register device which doesn't use an address 41*2e192b24SSimon Glass * field, use "0.0" for the address and the ".0" length field will 42*2e192b24SSimon Glass * suppress the address in the I2C data stream. This also works for 43*2e192b24SSimon Glass * successive reads using the I2C auto-incrementing memory pointer. 44*2e192b24SSimon Glass * 45*2e192b24SSimon Glass * If you are manipulating a large memory with 2-byte addresses, use 46*2e192b24SSimon Glass * the .2 address modifier, e.g. 210.2 addresses location 528 (decimal). 47*2e192b24SSimon Glass * 48*2e192b24SSimon Glass * Then there are the unfortunate memory chips that spill the most 49*2e192b24SSimon Glass * significant 1, 2, or 3 bits of address into the chip address byte. 50*2e192b24SSimon Glass * This effectively makes one chip (logically) look like 2, 4, or 51*2e192b24SSimon Glass * 8 chips. This is handled (awkwardly) by #defining 52*2e192b24SSimon Glass * CONFIG_SYS_I2C_EEPROM_ADDR_OVERFLOW and using the .1 modifier on the 53*2e192b24SSimon Glass * {addr} field (since .1 is the default, it doesn't actually have to 54*2e192b24SSimon Glass * be specified). Examples: given a memory chip at I2C chip address 55*2e192b24SSimon Glass * 0x50, the following would happen... 56*2e192b24SSimon Glass * i2c md 50 0 10 display 16 bytes starting at 0x000 57*2e192b24SSimon Glass * On the bus: <S> A0 00 <E> <S> A1 <rd> ... <rd> 58*2e192b24SSimon Glass * i2c md 50 100 10 display 16 bytes starting at 0x100 59*2e192b24SSimon Glass * On the bus: <S> A2 00 <E> <S> A3 <rd> ... <rd> 60*2e192b24SSimon Glass * i2c md 50 210 10 display 16 bytes starting at 0x210 61*2e192b24SSimon Glass * On the bus: <S> A4 10 <E> <S> A5 <rd> ... <rd> 62*2e192b24SSimon Glass * This is awfully ugly. It would be nice if someone would think up 63*2e192b24SSimon Glass * a better way of handling this. 64*2e192b24SSimon Glass * 65*2e192b24SSimon Glass * Adapted from cmd_mem.c which is copyright Wolfgang Denk (wd@denx.de). 66*2e192b24SSimon Glass */ 67*2e192b24SSimon Glass 68*2e192b24SSimon Glass #include <common.h> 69*2e192b24SSimon Glass #include <bootretry.h> 70*2e192b24SSimon Glass #include <cli.h> 71*2e192b24SSimon Glass #include <command.h> 72*2e192b24SSimon Glass #include <console.h> 73*2e192b24SSimon Glass #include <dm.h> 74*2e192b24SSimon Glass #include <edid.h> 75*2e192b24SSimon Glass #include <environment.h> 76*2e192b24SSimon Glass #include <errno.h> 77*2e192b24SSimon Glass #include <i2c.h> 78*2e192b24SSimon Glass #include <malloc.h> 79*2e192b24SSimon Glass #include <asm/byteorder.h> 80*2e192b24SSimon Glass #include <linux/compiler.h> 81*2e192b24SSimon Glass 82*2e192b24SSimon Glass DECLARE_GLOBAL_DATA_PTR; 83*2e192b24SSimon Glass 84*2e192b24SSimon Glass /* Display values from last command. 85*2e192b24SSimon Glass * Memory modify remembered values are different from display memory. 86*2e192b24SSimon Glass */ 87*2e192b24SSimon Glass static uint i2c_dp_last_chip; 88*2e192b24SSimon Glass static uint i2c_dp_last_addr; 89*2e192b24SSimon Glass static uint i2c_dp_last_alen; 90*2e192b24SSimon Glass static uint i2c_dp_last_length = 0x10; 91*2e192b24SSimon Glass 92*2e192b24SSimon Glass static uint i2c_mm_last_chip; 93*2e192b24SSimon Glass static uint i2c_mm_last_addr; 94*2e192b24SSimon Glass static uint i2c_mm_last_alen; 95*2e192b24SSimon Glass 96*2e192b24SSimon Glass /* If only one I2C bus is present, the list of devices to ignore when 97*2e192b24SSimon Glass * the probe command is issued is represented by a 1D array of addresses. 98*2e192b24SSimon Glass * When multiple buses are present, the list is an array of bus-address 99*2e192b24SSimon Glass * pairs. The following macros take care of this */ 100*2e192b24SSimon Glass 101*2e192b24SSimon Glass #if defined(CONFIG_SYS_I2C_NOPROBES) 102*2e192b24SSimon Glass #if defined(CONFIG_SYS_I2C) || defined(CONFIG_I2C_MULTI_BUS) 103*2e192b24SSimon Glass static struct 104*2e192b24SSimon Glass { 105*2e192b24SSimon Glass uchar bus; 106*2e192b24SSimon Glass uchar addr; 107*2e192b24SSimon Glass } i2c_no_probes[] = CONFIG_SYS_I2C_NOPROBES; 108*2e192b24SSimon Glass #define GET_BUS_NUM i2c_get_bus_num() 109*2e192b24SSimon Glass #define COMPARE_BUS(b,i) (i2c_no_probes[(i)].bus == (b)) 110*2e192b24SSimon Glass #define COMPARE_ADDR(a,i) (i2c_no_probes[(i)].addr == (a)) 111*2e192b24SSimon Glass #define NO_PROBE_ADDR(i) i2c_no_probes[(i)].addr 112*2e192b24SSimon Glass #else /* single bus */ 113*2e192b24SSimon Glass static uchar i2c_no_probes[] = CONFIG_SYS_I2C_NOPROBES; 114*2e192b24SSimon Glass #define GET_BUS_NUM 0 115*2e192b24SSimon Glass #define COMPARE_BUS(b,i) ((b) == 0) /* Make compiler happy */ 116*2e192b24SSimon Glass #define COMPARE_ADDR(a,i) (i2c_no_probes[(i)] == (a)) 117*2e192b24SSimon Glass #define NO_PROBE_ADDR(i) i2c_no_probes[(i)] 118*2e192b24SSimon Glass #endif /* defined(CONFIG_SYS_I2C) */ 119*2e192b24SSimon Glass #endif 120*2e192b24SSimon Glass 121*2e192b24SSimon Glass #define DISP_LINE_LEN 16 122*2e192b24SSimon Glass 123*2e192b24SSimon Glass /* 124*2e192b24SSimon Glass * Default for driver model is to use the chip's existing address length. 125*2e192b24SSimon Glass * For legacy code, this is not stored, so we need to use a suitable 126*2e192b24SSimon Glass * default. 127*2e192b24SSimon Glass */ 128*2e192b24SSimon Glass #ifdef CONFIG_DM_I2C 129*2e192b24SSimon Glass #define DEFAULT_ADDR_LEN (-1) 130*2e192b24SSimon Glass #else 131*2e192b24SSimon Glass #define DEFAULT_ADDR_LEN 1 132*2e192b24SSimon Glass #endif 133*2e192b24SSimon Glass 134*2e192b24SSimon Glass #ifdef CONFIG_DM_I2C 135*2e192b24SSimon Glass static struct udevice *i2c_cur_bus; 136*2e192b24SSimon Glass 137*2e192b24SSimon Glass static int cmd_i2c_set_bus_num(unsigned int busnum) 138*2e192b24SSimon Glass { 139*2e192b24SSimon Glass struct udevice *bus; 140*2e192b24SSimon Glass int ret; 141*2e192b24SSimon Glass 142*2e192b24SSimon Glass ret = uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus); 143*2e192b24SSimon Glass if (ret) { 144*2e192b24SSimon Glass debug("%s: No bus %d\n", __func__, busnum); 145*2e192b24SSimon Glass return ret; 146*2e192b24SSimon Glass } 147*2e192b24SSimon Glass i2c_cur_bus = bus; 148*2e192b24SSimon Glass 149*2e192b24SSimon Glass return 0; 150*2e192b24SSimon Glass } 151*2e192b24SSimon Glass 152*2e192b24SSimon Glass static int i2c_get_cur_bus(struct udevice **busp) 153*2e192b24SSimon Glass { 154*2e192b24SSimon Glass if (!i2c_cur_bus) { 155*2e192b24SSimon Glass puts("No I2C bus selected\n"); 156*2e192b24SSimon Glass return -ENODEV; 157*2e192b24SSimon Glass } 158*2e192b24SSimon Glass *busp = i2c_cur_bus; 159*2e192b24SSimon Glass 160*2e192b24SSimon Glass return 0; 161*2e192b24SSimon Glass } 162*2e192b24SSimon Glass 163*2e192b24SSimon Glass static int i2c_get_cur_bus_chip(uint chip_addr, struct udevice **devp) 164*2e192b24SSimon Glass { 165*2e192b24SSimon Glass struct udevice *bus; 166*2e192b24SSimon Glass int ret; 167*2e192b24SSimon Glass 168*2e192b24SSimon Glass ret = i2c_get_cur_bus(&bus); 169*2e192b24SSimon Glass if (ret) 170*2e192b24SSimon Glass return ret; 171*2e192b24SSimon Glass 172*2e192b24SSimon Glass return i2c_get_chip(bus, chip_addr, 1, devp); 173*2e192b24SSimon Glass } 174*2e192b24SSimon Glass 175*2e192b24SSimon Glass #endif 176*2e192b24SSimon Glass 177*2e192b24SSimon Glass /** 178*2e192b24SSimon Glass * i2c_init_board() - Board-specific I2C bus init 179*2e192b24SSimon Glass * 180*2e192b24SSimon Glass * This function is the default no-op implementation of I2C bus 181*2e192b24SSimon Glass * initialization. This function can be overriden by board-specific 182*2e192b24SSimon Glass * implementation if needed. 183*2e192b24SSimon Glass */ 184*2e192b24SSimon Glass __weak 185*2e192b24SSimon Glass void i2c_init_board(void) 186*2e192b24SSimon Glass { 187*2e192b24SSimon Glass } 188*2e192b24SSimon Glass 189*2e192b24SSimon Glass /* TODO: Implement architecture-specific get/set functions */ 190*2e192b24SSimon Glass 191*2e192b24SSimon Glass /** 192*2e192b24SSimon Glass * i2c_get_bus_speed() - Return I2C bus speed 193*2e192b24SSimon Glass * 194*2e192b24SSimon Glass * This function is the default implementation of function for retrieveing 195*2e192b24SSimon Glass * the current I2C bus speed in Hz. 196*2e192b24SSimon Glass * 197*2e192b24SSimon Glass * A driver implementing runtime switching of I2C bus speed must override 198*2e192b24SSimon Glass * this function to report the speed correctly. Simple or legacy drivers 199*2e192b24SSimon Glass * can use this fallback. 200*2e192b24SSimon Glass * 201*2e192b24SSimon Glass * Returns I2C bus speed in Hz. 202*2e192b24SSimon Glass */ 203*2e192b24SSimon Glass #if !defined(CONFIG_SYS_I2C) && !defined(CONFIG_DM_I2C) 204*2e192b24SSimon Glass /* 205*2e192b24SSimon Glass * TODO: Implement architecture-specific get/set functions 206*2e192b24SSimon Glass * Should go away, if we switched completely to new multibus support 207*2e192b24SSimon Glass */ 208*2e192b24SSimon Glass __weak 209*2e192b24SSimon Glass unsigned int i2c_get_bus_speed(void) 210*2e192b24SSimon Glass { 211*2e192b24SSimon Glass return CONFIG_SYS_I2C_SPEED; 212*2e192b24SSimon Glass } 213*2e192b24SSimon Glass 214*2e192b24SSimon Glass /** 215*2e192b24SSimon Glass * i2c_set_bus_speed() - Configure I2C bus speed 216*2e192b24SSimon Glass * @speed: Newly set speed of the I2C bus in Hz 217*2e192b24SSimon Glass * 218*2e192b24SSimon Glass * This function is the default implementation of function for setting 219*2e192b24SSimon Glass * the I2C bus speed in Hz. 220*2e192b24SSimon Glass * 221*2e192b24SSimon Glass * A driver implementing runtime switching of I2C bus speed must override 222*2e192b24SSimon Glass * this function to report the speed correctly. Simple or legacy drivers 223*2e192b24SSimon Glass * can use this fallback. 224*2e192b24SSimon Glass * 225*2e192b24SSimon Glass * Returns zero on success, negative value on error. 226*2e192b24SSimon Glass */ 227*2e192b24SSimon Glass __weak 228*2e192b24SSimon Glass int i2c_set_bus_speed(unsigned int speed) 229*2e192b24SSimon Glass { 230*2e192b24SSimon Glass if (speed != CONFIG_SYS_I2C_SPEED) 231*2e192b24SSimon Glass return -1; 232*2e192b24SSimon Glass 233*2e192b24SSimon Glass return 0; 234*2e192b24SSimon Glass } 235*2e192b24SSimon Glass #endif 236*2e192b24SSimon Glass 237*2e192b24SSimon Glass /** 238*2e192b24SSimon Glass * get_alen() - Small parser helper function to get address length 239*2e192b24SSimon Glass * 240*2e192b24SSimon Glass * Returns the address length. 241*2e192b24SSimon Glass */ 242*2e192b24SSimon Glass static uint get_alen(char *arg, int default_len) 243*2e192b24SSimon Glass { 244*2e192b24SSimon Glass int j; 245*2e192b24SSimon Glass int alen; 246*2e192b24SSimon Glass 247*2e192b24SSimon Glass alen = default_len; 248*2e192b24SSimon Glass for (j = 0; j < 8; j++) { 249*2e192b24SSimon Glass if (arg[j] == '.') { 250*2e192b24SSimon Glass alen = arg[j+1] - '0'; 251*2e192b24SSimon Glass break; 252*2e192b24SSimon Glass } else if (arg[j] == '\0') 253*2e192b24SSimon Glass break; 254*2e192b24SSimon Glass } 255*2e192b24SSimon Glass return alen; 256*2e192b24SSimon Glass } 257*2e192b24SSimon Glass 258*2e192b24SSimon Glass enum i2c_err_op { 259*2e192b24SSimon Glass I2C_ERR_READ, 260*2e192b24SSimon Glass I2C_ERR_WRITE, 261*2e192b24SSimon Glass }; 262*2e192b24SSimon Glass 263*2e192b24SSimon Glass static int i2c_report_err(int ret, enum i2c_err_op op) 264*2e192b24SSimon Glass { 265*2e192b24SSimon Glass printf("Error %s the chip: %d\n", 266*2e192b24SSimon Glass op == I2C_ERR_READ ? "reading" : "writing", ret); 267*2e192b24SSimon Glass 268*2e192b24SSimon Glass return CMD_RET_FAILURE; 269*2e192b24SSimon Glass } 270*2e192b24SSimon Glass 271*2e192b24SSimon Glass /** 272*2e192b24SSimon Glass * do_i2c_read() - Handle the "i2c read" command-line command 273*2e192b24SSimon Glass * @cmdtp: Command data struct pointer 274*2e192b24SSimon Glass * @flag: Command flag 275*2e192b24SSimon Glass * @argc: Command-line argument count 276*2e192b24SSimon Glass * @argv: Array of command-line arguments 277*2e192b24SSimon Glass * 278*2e192b24SSimon Glass * Returns zero on success, CMD_RET_USAGE in case of misuse and negative 279*2e192b24SSimon Glass * on error. 280*2e192b24SSimon Glass * 281*2e192b24SSimon Glass * Syntax: 282*2e192b24SSimon Glass * i2c read {i2c_chip} {devaddr}{.0, .1, .2} {len} {memaddr} 283*2e192b24SSimon Glass */ 284*2e192b24SSimon Glass static int do_i2c_read ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 285*2e192b24SSimon Glass { 286*2e192b24SSimon Glass uint chip; 287*2e192b24SSimon Glass uint devaddr, length; 288*2e192b24SSimon Glass int alen; 289*2e192b24SSimon Glass u_char *memaddr; 290*2e192b24SSimon Glass int ret; 291*2e192b24SSimon Glass #ifdef CONFIG_DM_I2C 292*2e192b24SSimon Glass struct udevice *dev; 293*2e192b24SSimon Glass #endif 294*2e192b24SSimon Glass 295*2e192b24SSimon Glass if (argc != 5) 296*2e192b24SSimon Glass return CMD_RET_USAGE; 297*2e192b24SSimon Glass 298*2e192b24SSimon Glass /* 299*2e192b24SSimon Glass * I2C chip address 300*2e192b24SSimon Glass */ 301*2e192b24SSimon Glass chip = simple_strtoul(argv[1], NULL, 16); 302*2e192b24SSimon Glass 303*2e192b24SSimon Glass /* 304*2e192b24SSimon Glass * I2C data address within the chip. This can be 1 or 305*2e192b24SSimon Glass * 2 bytes long. Some day it might be 3 bytes long :-). 306*2e192b24SSimon Glass */ 307*2e192b24SSimon Glass devaddr = simple_strtoul(argv[2], NULL, 16); 308*2e192b24SSimon Glass alen = get_alen(argv[2], DEFAULT_ADDR_LEN); 309*2e192b24SSimon Glass if (alen > 3) 310*2e192b24SSimon Glass return CMD_RET_USAGE; 311*2e192b24SSimon Glass 312*2e192b24SSimon Glass /* 313*2e192b24SSimon Glass * Length is the number of objects, not number of bytes. 314*2e192b24SSimon Glass */ 315*2e192b24SSimon Glass length = simple_strtoul(argv[3], NULL, 16); 316*2e192b24SSimon Glass 317*2e192b24SSimon Glass /* 318*2e192b24SSimon Glass * memaddr is the address where to store things in memory 319*2e192b24SSimon Glass */ 320*2e192b24SSimon Glass memaddr = (u_char *)simple_strtoul(argv[4], NULL, 16); 321*2e192b24SSimon Glass 322*2e192b24SSimon Glass #ifdef CONFIG_DM_I2C 323*2e192b24SSimon Glass ret = i2c_get_cur_bus_chip(chip, &dev); 324*2e192b24SSimon Glass if (!ret && alen != -1) 325*2e192b24SSimon Glass ret = i2c_set_chip_offset_len(dev, alen); 326*2e192b24SSimon Glass if (!ret) 327*2e192b24SSimon Glass ret = dm_i2c_read(dev, devaddr, memaddr, length); 328*2e192b24SSimon Glass #else 329*2e192b24SSimon Glass ret = i2c_read(chip, devaddr, alen, memaddr, length); 330*2e192b24SSimon Glass #endif 331*2e192b24SSimon Glass if (ret) 332*2e192b24SSimon Glass return i2c_report_err(ret, I2C_ERR_READ); 333*2e192b24SSimon Glass 334*2e192b24SSimon Glass return 0; 335*2e192b24SSimon Glass } 336*2e192b24SSimon Glass 337*2e192b24SSimon Glass static int do_i2c_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 338*2e192b24SSimon Glass { 339*2e192b24SSimon Glass uint chip; 340*2e192b24SSimon Glass uint devaddr, length; 341*2e192b24SSimon Glass int alen; 342*2e192b24SSimon Glass u_char *memaddr; 343*2e192b24SSimon Glass int ret; 344*2e192b24SSimon Glass #ifdef CONFIG_DM_I2C 345*2e192b24SSimon Glass struct udevice *dev; 346*2e192b24SSimon Glass struct dm_i2c_chip *i2c_chip; 347*2e192b24SSimon Glass #endif 348*2e192b24SSimon Glass 349*2e192b24SSimon Glass if ((argc < 5) || (argc > 6)) 350*2e192b24SSimon Glass return cmd_usage(cmdtp); 351*2e192b24SSimon Glass 352*2e192b24SSimon Glass /* 353*2e192b24SSimon Glass * memaddr is the address where to store things in memory 354*2e192b24SSimon Glass */ 355*2e192b24SSimon Glass memaddr = (u_char *)simple_strtoul(argv[1], NULL, 16); 356*2e192b24SSimon Glass 357*2e192b24SSimon Glass /* 358*2e192b24SSimon Glass * I2C chip address 359*2e192b24SSimon Glass */ 360*2e192b24SSimon Glass chip = simple_strtoul(argv[2], NULL, 16); 361*2e192b24SSimon Glass 362*2e192b24SSimon Glass /* 363*2e192b24SSimon Glass * I2C data address within the chip. This can be 1 or 364*2e192b24SSimon Glass * 2 bytes long. Some day it might be 3 bytes long :-). 365*2e192b24SSimon Glass */ 366*2e192b24SSimon Glass devaddr = simple_strtoul(argv[3], NULL, 16); 367*2e192b24SSimon Glass alen = get_alen(argv[3], DEFAULT_ADDR_LEN); 368*2e192b24SSimon Glass if (alen > 3) 369*2e192b24SSimon Glass return cmd_usage(cmdtp); 370*2e192b24SSimon Glass 371*2e192b24SSimon Glass /* 372*2e192b24SSimon Glass * Length is the number of bytes. 373*2e192b24SSimon Glass */ 374*2e192b24SSimon Glass length = simple_strtoul(argv[4], NULL, 16); 375*2e192b24SSimon Glass 376*2e192b24SSimon Glass #ifdef CONFIG_DM_I2C 377*2e192b24SSimon Glass ret = i2c_get_cur_bus_chip(chip, &dev); 378*2e192b24SSimon Glass if (!ret && alen != -1) 379*2e192b24SSimon Glass ret = i2c_set_chip_offset_len(dev, alen); 380*2e192b24SSimon Glass if (ret) 381*2e192b24SSimon Glass return i2c_report_err(ret, I2C_ERR_WRITE); 382*2e192b24SSimon Glass i2c_chip = dev_get_parent_platdata(dev); 383*2e192b24SSimon Glass if (!i2c_chip) 384*2e192b24SSimon Glass return i2c_report_err(ret, I2C_ERR_WRITE); 385*2e192b24SSimon Glass #endif 386*2e192b24SSimon Glass 387*2e192b24SSimon Glass if (argc == 6 && !strcmp(argv[5], "-s")) { 388*2e192b24SSimon Glass /* 389*2e192b24SSimon Glass * Write all bytes in a single I2C transaction. If the target 390*2e192b24SSimon Glass * device is an EEPROM, it is your responsibility to not cross 391*2e192b24SSimon Glass * a page boundary. No write delay upon completion, take this 392*2e192b24SSimon Glass * into account if linking commands. 393*2e192b24SSimon Glass */ 394*2e192b24SSimon Glass #ifdef CONFIG_DM_I2C 395*2e192b24SSimon Glass i2c_chip->flags &= ~DM_I2C_CHIP_WR_ADDRESS; 396*2e192b24SSimon Glass ret = dm_i2c_write(dev, devaddr, memaddr, length); 397*2e192b24SSimon Glass #else 398*2e192b24SSimon Glass ret = i2c_write(chip, devaddr, alen, memaddr, length); 399*2e192b24SSimon Glass #endif 400*2e192b24SSimon Glass if (ret) 401*2e192b24SSimon Glass return i2c_report_err(ret, I2C_ERR_WRITE); 402*2e192b24SSimon Glass } else { 403*2e192b24SSimon Glass /* 404*2e192b24SSimon Glass * Repeated addressing - perform <length> separate 405*2e192b24SSimon Glass * write transactions of one byte each 406*2e192b24SSimon Glass */ 407*2e192b24SSimon Glass while (length-- > 0) { 408*2e192b24SSimon Glass #ifdef CONFIG_DM_I2C 409*2e192b24SSimon Glass i2c_chip->flags |= DM_I2C_CHIP_WR_ADDRESS; 410*2e192b24SSimon Glass ret = dm_i2c_write(dev, devaddr++, memaddr++, 1); 411*2e192b24SSimon Glass #else 412*2e192b24SSimon Glass ret = i2c_write(chip, devaddr++, alen, memaddr++, 1); 413*2e192b24SSimon Glass #endif 414*2e192b24SSimon Glass if (ret) 415*2e192b24SSimon Glass return i2c_report_err(ret, I2C_ERR_WRITE); 416*2e192b24SSimon Glass /* 417*2e192b24SSimon Glass * No write delay with FRAM devices. 418*2e192b24SSimon Glass */ 419*2e192b24SSimon Glass #if !defined(CONFIG_SYS_I2C_FRAM) 420*2e192b24SSimon Glass udelay(11000); 421*2e192b24SSimon Glass #endif 422*2e192b24SSimon Glass } 423*2e192b24SSimon Glass } 424*2e192b24SSimon Glass return 0; 425*2e192b24SSimon Glass } 426*2e192b24SSimon Glass 427*2e192b24SSimon Glass #ifdef CONFIG_DM_I2C 428*2e192b24SSimon Glass static int do_i2c_flags(cmd_tbl_t *cmdtp, int flag, int argc, 429*2e192b24SSimon Glass char *const argv[]) 430*2e192b24SSimon Glass { 431*2e192b24SSimon Glass struct udevice *dev; 432*2e192b24SSimon Glass uint flags; 433*2e192b24SSimon Glass int chip; 434*2e192b24SSimon Glass int ret; 435*2e192b24SSimon Glass 436*2e192b24SSimon Glass if (argc < 2) 437*2e192b24SSimon Glass return CMD_RET_USAGE; 438*2e192b24SSimon Glass 439*2e192b24SSimon Glass chip = simple_strtoul(argv[1], NULL, 16); 440*2e192b24SSimon Glass ret = i2c_get_cur_bus_chip(chip, &dev); 441*2e192b24SSimon Glass if (ret) 442*2e192b24SSimon Glass return i2c_report_err(ret, I2C_ERR_READ); 443*2e192b24SSimon Glass 444*2e192b24SSimon Glass if (argc > 2) { 445*2e192b24SSimon Glass flags = simple_strtoul(argv[2], NULL, 16); 446*2e192b24SSimon Glass ret = i2c_set_chip_flags(dev, flags); 447*2e192b24SSimon Glass } else { 448*2e192b24SSimon Glass ret = i2c_get_chip_flags(dev, &flags); 449*2e192b24SSimon Glass if (!ret) 450*2e192b24SSimon Glass printf("%x\n", flags); 451*2e192b24SSimon Glass } 452*2e192b24SSimon Glass if (ret) 453*2e192b24SSimon Glass return i2c_report_err(ret, I2C_ERR_READ); 454*2e192b24SSimon Glass 455*2e192b24SSimon Glass return 0; 456*2e192b24SSimon Glass } 457*2e192b24SSimon Glass 458*2e192b24SSimon Glass static int do_i2c_olen(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) 459*2e192b24SSimon Glass { 460*2e192b24SSimon Glass struct udevice *dev; 461*2e192b24SSimon Glass uint olen; 462*2e192b24SSimon Glass int chip; 463*2e192b24SSimon Glass int ret; 464*2e192b24SSimon Glass 465*2e192b24SSimon Glass if (argc < 2) 466*2e192b24SSimon Glass return CMD_RET_USAGE; 467*2e192b24SSimon Glass 468*2e192b24SSimon Glass chip = simple_strtoul(argv[1], NULL, 16); 469*2e192b24SSimon Glass ret = i2c_get_cur_bus_chip(chip, &dev); 470*2e192b24SSimon Glass if (ret) 471*2e192b24SSimon Glass return i2c_report_err(ret, I2C_ERR_READ); 472*2e192b24SSimon Glass 473*2e192b24SSimon Glass if (argc > 2) { 474*2e192b24SSimon Glass olen = simple_strtoul(argv[2], NULL, 16); 475*2e192b24SSimon Glass ret = i2c_set_chip_offset_len(dev, olen); 476*2e192b24SSimon Glass } else { 477*2e192b24SSimon Glass ret = i2c_get_chip_offset_len(dev); 478*2e192b24SSimon Glass if (ret >= 0) { 479*2e192b24SSimon Glass printf("%x\n", ret); 480*2e192b24SSimon Glass ret = 0; 481*2e192b24SSimon Glass } 482*2e192b24SSimon Glass } 483*2e192b24SSimon Glass if (ret) 484*2e192b24SSimon Glass return i2c_report_err(ret, I2C_ERR_READ); 485*2e192b24SSimon Glass 486*2e192b24SSimon Glass return 0; 487*2e192b24SSimon Glass } 488*2e192b24SSimon Glass #endif 489*2e192b24SSimon Glass 490*2e192b24SSimon Glass /** 491*2e192b24SSimon Glass * do_i2c_md() - Handle the "i2c md" command-line command 492*2e192b24SSimon Glass * @cmdtp: Command data struct pointer 493*2e192b24SSimon Glass * @flag: Command flag 494*2e192b24SSimon Glass * @argc: Command-line argument count 495*2e192b24SSimon Glass * @argv: Array of command-line arguments 496*2e192b24SSimon Glass * 497*2e192b24SSimon Glass * Returns zero on success, CMD_RET_USAGE in case of misuse and negative 498*2e192b24SSimon Glass * on error. 499*2e192b24SSimon Glass * 500*2e192b24SSimon Glass * Syntax: 501*2e192b24SSimon Glass * i2c md {i2c_chip} {addr}{.0, .1, .2} {len} 502*2e192b24SSimon Glass */ 503*2e192b24SSimon Glass static int do_i2c_md ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 504*2e192b24SSimon Glass { 505*2e192b24SSimon Glass uint chip; 506*2e192b24SSimon Glass uint addr, length; 507*2e192b24SSimon Glass int alen; 508*2e192b24SSimon Glass int j, nbytes, linebytes; 509*2e192b24SSimon Glass int ret; 510*2e192b24SSimon Glass #ifdef CONFIG_DM_I2C 511*2e192b24SSimon Glass struct udevice *dev; 512*2e192b24SSimon Glass #endif 513*2e192b24SSimon Glass 514*2e192b24SSimon Glass /* We use the last specified parameters, unless new ones are 515*2e192b24SSimon Glass * entered. 516*2e192b24SSimon Glass */ 517*2e192b24SSimon Glass chip = i2c_dp_last_chip; 518*2e192b24SSimon Glass addr = i2c_dp_last_addr; 519*2e192b24SSimon Glass alen = i2c_dp_last_alen; 520*2e192b24SSimon Glass length = i2c_dp_last_length; 521*2e192b24SSimon Glass 522*2e192b24SSimon Glass if (argc < 3) 523*2e192b24SSimon Glass return CMD_RET_USAGE; 524*2e192b24SSimon Glass 525*2e192b24SSimon Glass if ((flag & CMD_FLAG_REPEAT) == 0) { 526*2e192b24SSimon Glass /* 527*2e192b24SSimon Glass * New command specified. 528*2e192b24SSimon Glass */ 529*2e192b24SSimon Glass 530*2e192b24SSimon Glass /* 531*2e192b24SSimon Glass * I2C chip address 532*2e192b24SSimon Glass */ 533*2e192b24SSimon Glass chip = simple_strtoul(argv[1], NULL, 16); 534*2e192b24SSimon Glass 535*2e192b24SSimon Glass /* 536*2e192b24SSimon Glass * I2C data address within the chip. This can be 1 or 537*2e192b24SSimon Glass * 2 bytes long. Some day it might be 3 bytes long :-). 538*2e192b24SSimon Glass */ 539*2e192b24SSimon Glass addr = simple_strtoul(argv[2], NULL, 16); 540*2e192b24SSimon Glass alen = get_alen(argv[2], DEFAULT_ADDR_LEN); 541*2e192b24SSimon Glass if (alen > 3) 542*2e192b24SSimon Glass return CMD_RET_USAGE; 543*2e192b24SSimon Glass 544*2e192b24SSimon Glass /* 545*2e192b24SSimon Glass * If another parameter, it is the length to display. 546*2e192b24SSimon Glass * Length is the number of objects, not number of bytes. 547*2e192b24SSimon Glass */ 548*2e192b24SSimon Glass if (argc > 3) 549*2e192b24SSimon Glass length = simple_strtoul(argv[3], NULL, 16); 550*2e192b24SSimon Glass } 551*2e192b24SSimon Glass 552*2e192b24SSimon Glass #ifdef CONFIG_DM_I2C 553*2e192b24SSimon Glass ret = i2c_get_cur_bus_chip(chip, &dev); 554*2e192b24SSimon Glass if (!ret && alen != -1) 555*2e192b24SSimon Glass ret = i2c_set_chip_offset_len(dev, alen); 556*2e192b24SSimon Glass if (ret) 557*2e192b24SSimon Glass return i2c_report_err(ret, I2C_ERR_READ); 558*2e192b24SSimon Glass #endif 559*2e192b24SSimon Glass 560*2e192b24SSimon Glass /* 561*2e192b24SSimon Glass * Print the lines. 562*2e192b24SSimon Glass * 563*2e192b24SSimon Glass * We buffer all read data, so we can make sure data is read only 564*2e192b24SSimon Glass * once. 565*2e192b24SSimon Glass */ 566*2e192b24SSimon Glass nbytes = length; 567*2e192b24SSimon Glass do { 568*2e192b24SSimon Glass unsigned char linebuf[DISP_LINE_LEN]; 569*2e192b24SSimon Glass unsigned char *cp; 570*2e192b24SSimon Glass 571*2e192b24SSimon Glass linebytes = (nbytes > DISP_LINE_LEN) ? DISP_LINE_LEN : nbytes; 572*2e192b24SSimon Glass 573*2e192b24SSimon Glass #ifdef CONFIG_DM_I2C 574*2e192b24SSimon Glass ret = dm_i2c_read(dev, addr, linebuf, linebytes); 575*2e192b24SSimon Glass #else 576*2e192b24SSimon Glass ret = i2c_read(chip, addr, alen, linebuf, linebytes); 577*2e192b24SSimon Glass #endif 578*2e192b24SSimon Glass if (ret) 579*2e192b24SSimon Glass return i2c_report_err(ret, I2C_ERR_READ); 580*2e192b24SSimon Glass else { 581*2e192b24SSimon Glass printf("%04x:", addr); 582*2e192b24SSimon Glass cp = linebuf; 583*2e192b24SSimon Glass for (j=0; j<linebytes; j++) { 584*2e192b24SSimon Glass printf(" %02x", *cp++); 585*2e192b24SSimon Glass addr++; 586*2e192b24SSimon Glass } 587*2e192b24SSimon Glass puts (" "); 588*2e192b24SSimon Glass cp = linebuf; 589*2e192b24SSimon Glass for (j=0; j<linebytes; j++) { 590*2e192b24SSimon Glass if ((*cp < 0x20) || (*cp > 0x7e)) 591*2e192b24SSimon Glass puts ("."); 592*2e192b24SSimon Glass else 593*2e192b24SSimon Glass printf("%c", *cp); 594*2e192b24SSimon Glass cp++; 595*2e192b24SSimon Glass } 596*2e192b24SSimon Glass putc ('\n'); 597*2e192b24SSimon Glass } 598*2e192b24SSimon Glass nbytes -= linebytes; 599*2e192b24SSimon Glass } while (nbytes > 0); 600*2e192b24SSimon Glass 601*2e192b24SSimon Glass i2c_dp_last_chip = chip; 602*2e192b24SSimon Glass i2c_dp_last_addr = addr; 603*2e192b24SSimon Glass i2c_dp_last_alen = alen; 604*2e192b24SSimon Glass i2c_dp_last_length = length; 605*2e192b24SSimon Glass 606*2e192b24SSimon Glass return 0; 607*2e192b24SSimon Glass } 608*2e192b24SSimon Glass 609*2e192b24SSimon Glass /** 610*2e192b24SSimon Glass * do_i2c_mw() - Handle the "i2c mw" command-line command 611*2e192b24SSimon Glass * @cmdtp: Command data struct pointer 612*2e192b24SSimon Glass * @flag: Command flag 613*2e192b24SSimon Glass * @argc: Command-line argument count 614*2e192b24SSimon Glass * @argv: Array of command-line arguments 615*2e192b24SSimon Glass * 616*2e192b24SSimon Glass * Returns zero on success, CMD_RET_USAGE in case of misuse and negative 617*2e192b24SSimon Glass * on error. 618*2e192b24SSimon Glass * 619*2e192b24SSimon Glass * Syntax: 620*2e192b24SSimon Glass * i2c mw {i2c_chip} {addr}{.0, .1, .2} {data} [{count}] 621*2e192b24SSimon Glass */ 622*2e192b24SSimon Glass static int do_i2c_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 623*2e192b24SSimon Glass { 624*2e192b24SSimon Glass uint chip; 625*2e192b24SSimon Glass ulong addr; 626*2e192b24SSimon Glass int alen; 627*2e192b24SSimon Glass uchar byte; 628*2e192b24SSimon Glass int count; 629*2e192b24SSimon Glass int ret; 630*2e192b24SSimon Glass #ifdef CONFIG_DM_I2C 631*2e192b24SSimon Glass struct udevice *dev; 632*2e192b24SSimon Glass #endif 633*2e192b24SSimon Glass 634*2e192b24SSimon Glass if ((argc < 4) || (argc > 5)) 635*2e192b24SSimon Glass return CMD_RET_USAGE; 636*2e192b24SSimon Glass 637*2e192b24SSimon Glass /* 638*2e192b24SSimon Glass * Chip is always specified. 639*2e192b24SSimon Glass */ 640*2e192b24SSimon Glass chip = simple_strtoul(argv[1], NULL, 16); 641*2e192b24SSimon Glass 642*2e192b24SSimon Glass /* 643*2e192b24SSimon Glass * Address is always specified. 644*2e192b24SSimon Glass */ 645*2e192b24SSimon Glass addr = simple_strtoul(argv[2], NULL, 16); 646*2e192b24SSimon Glass alen = get_alen(argv[2], DEFAULT_ADDR_LEN); 647*2e192b24SSimon Glass if (alen > 3) 648*2e192b24SSimon Glass return CMD_RET_USAGE; 649*2e192b24SSimon Glass 650*2e192b24SSimon Glass #ifdef CONFIG_DM_I2C 651*2e192b24SSimon Glass ret = i2c_get_cur_bus_chip(chip, &dev); 652*2e192b24SSimon Glass if (!ret && alen != -1) 653*2e192b24SSimon Glass ret = i2c_set_chip_offset_len(dev, alen); 654*2e192b24SSimon Glass if (ret) 655*2e192b24SSimon Glass return i2c_report_err(ret, I2C_ERR_WRITE); 656*2e192b24SSimon Glass #endif 657*2e192b24SSimon Glass /* 658*2e192b24SSimon Glass * Value to write is always specified. 659*2e192b24SSimon Glass */ 660*2e192b24SSimon Glass byte = simple_strtoul(argv[3], NULL, 16); 661*2e192b24SSimon Glass 662*2e192b24SSimon Glass /* 663*2e192b24SSimon Glass * Optional count 664*2e192b24SSimon Glass */ 665*2e192b24SSimon Glass if (argc == 5) 666*2e192b24SSimon Glass count = simple_strtoul(argv[4], NULL, 16); 667*2e192b24SSimon Glass else 668*2e192b24SSimon Glass count = 1; 669*2e192b24SSimon Glass 670*2e192b24SSimon Glass while (count-- > 0) { 671*2e192b24SSimon Glass #ifdef CONFIG_DM_I2C 672*2e192b24SSimon Glass ret = dm_i2c_write(dev, addr++, &byte, 1); 673*2e192b24SSimon Glass #else 674*2e192b24SSimon Glass ret = i2c_write(chip, addr++, alen, &byte, 1); 675*2e192b24SSimon Glass #endif 676*2e192b24SSimon Glass if (ret) 677*2e192b24SSimon Glass return i2c_report_err(ret, I2C_ERR_WRITE); 678*2e192b24SSimon Glass /* 679*2e192b24SSimon Glass * Wait for the write to complete. The write can take 680*2e192b24SSimon Glass * up to 10mSec (we allow a little more time). 681*2e192b24SSimon Glass */ 682*2e192b24SSimon Glass /* 683*2e192b24SSimon Glass * No write delay with FRAM devices. 684*2e192b24SSimon Glass */ 685*2e192b24SSimon Glass #if !defined(CONFIG_SYS_I2C_FRAM) 686*2e192b24SSimon Glass udelay(11000); 687*2e192b24SSimon Glass #endif 688*2e192b24SSimon Glass } 689*2e192b24SSimon Glass 690*2e192b24SSimon Glass return 0; 691*2e192b24SSimon Glass } 692*2e192b24SSimon Glass 693*2e192b24SSimon Glass /** 694*2e192b24SSimon Glass * do_i2c_crc() - Handle the "i2c crc32" command-line command 695*2e192b24SSimon Glass * @cmdtp: Command data struct pointer 696*2e192b24SSimon Glass * @flag: Command flag 697*2e192b24SSimon Glass * @argc: Command-line argument count 698*2e192b24SSimon Glass * @argv: Array of command-line arguments 699*2e192b24SSimon Glass * 700*2e192b24SSimon Glass * Calculate a CRC on memory 701*2e192b24SSimon Glass * 702*2e192b24SSimon Glass * Returns zero on success, CMD_RET_USAGE in case of misuse and negative 703*2e192b24SSimon Glass * on error. 704*2e192b24SSimon Glass * 705*2e192b24SSimon Glass * Syntax: 706*2e192b24SSimon Glass * i2c crc32 {i2c_chip} {addr}{.0, .1, .2} {count} 707*2e192b24SSimon Glass */ 708*2e192b24SSimon Glass static int do_i2c_crc (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 709*2e192b24SSimon Glass { 710*2e192b24SSimon Glass uint chip; 711*2e192b24SSimon Glass ulong addr; 712*2e192b24SSimon Glass int alen; 713*2e192b24SSimon Glass int count; 714*2e192b24SSimon Glass uchar byte; 715*2e192b24SSimon Glass ulong crc; 716*2e192b24SSimon Glass ulong err; 717*2e192b24SSimon Glass int ret = 0; 718*2e192b24SSimon Glass #ifdef CONFIG_DM_I2C 719*2e192b24SSimon Glass struct udevice *dev; 720*2e192b24SSimon Glass #endif 721*2e192b24SSimon Glass 722*2e192b24SSimon Glass if (argc < 4) 723*2e192b24SSimon Glass return CMD_RET_USAGE; 724*2e192b24SSimon Glass 725*2e192b24SSimon Glass /* 726*2e192b24SSimon Glass * Chip is always specified. 727*2e192b24SSimon Glass */ 728*2e192b24SSimon Glass chip = simple_strtoul(argv[1], NULL, 16); 729*2e192b24SSimon Glass 730*2e192b24SSimon Glass /* 731*2e192b24SSimon Glass * Address is always specified. 732*2e192b24SSimon Glass */ 733*2e192b24SSimon Glass addr = simple_strtoul(argv[2], NULL, 16); 734*2e192b24SSimon Glass alen = get_alen(argv[2], DEFAULT_ADDR_LEN); 735*2e192b24SSimon Glass if (alen > 3) 736*2e192b24SSimon Glass return CMD_RET_USAGE; 737*2e192b24SSimon Glass 738*2e192b24SSimon Glass #ifdef CONFIG_DM_I2C 739*2e192b24SSimon Glass ret = i2c_get_cur_bus_chip(chip, &dev); 740*2e192b24SSimon Glass if (!ret && alen != -1) 741*2e192b24SSimon Glass ret = i2c_set_chip_offset_len(dev, alen); 742*2e192b24SSimon Glass if (ret) 743*2e192b24SSimon Glass return i2c_report_err(ret, I2C_ERR_READ); 744*2e192b24SSimon Glass #endif 745*2e192b24SSimon Glass /* 746*2e192b24SSimon Glass * Count is always specified 747*2e192b24SSimon Glass */ 748*2e192b24SSimon Glass count = simple_strtoul(argv[3], NULL, 16); 749*2e192b24SSimon Glass 750*2e192b24SSimon Glass printf ("CRC32 for %08lx ... %08lx ==> ", addr, addr + count - 1); 751*2e192b24SSimon Glass /* 752*2e192b24SSimon Glass * CRC a byte at a time. This is going to be slooow, but hey, the 753*2e192b24SSimon Glass * memories are small and slow too so hopefully nobody notices. 754*2e192b24SSimon Glass */ 755*2e192b24SSimon Glass crc = 0; 756*2e192b24SSimon Glass err = 0; 757*2e192b24SSimon Glass while (count-- > 0) { 758*2e192b24SSimon Glass #ifdef CONFIG_DM_I2C 759*2e192b24SSimon Glass ret = dm_i2c_read(dev, addr, &byte, 1); 760*2e192b24SSimon Glass #else 761*2e192b24SSimon Glass ret = i2c_read(chip, addr, alen, &byte, 1); 762*2e192b24SSimon Glass #endif 763*2e192b24SSimon Glass if (ret) 764*2e192b24SSimon Glass err++; 765*2e192b24SSimon Glass crc = crc32 (crc, &byte, 1); 766*2e192b24SSimon Glass addr++; 767*2e192b24SSimon Glass } 768*2e192b24SSimon Glass if (err > 0) 769*2e192b24SSimon Glass i2c_report_err(ret, I2C_ERR_READ); 770*2e192b24SSimon Glass else 771*2e192b24SSimon Glass printf ("%08lx\n", crc); 772*2e192b24SSimon Glass 773*2e192b24SSimon Glass return 0; 774*2e192b24SSimon Glass } 775*2e192b24SSimon Glass 776*2e192b24SSimon Glass /** 777*2e192b24SSimon Glass * mod_i2c_mem() - Handle the "i2c mm" and "i2c nm" command-line command 778*2e192b24SSimon Glass * @cmdtp: Command data struct pointer 779*2e192b24SSimon Glass * @flag: Command flag 780*2e192b24SSimon Glass * @argc: Command-line argument count 781*2e192b24SSimon Glass * @argv: Array of command-line arguments 782*2e192b24SSimon Glass * 783*2e192b24SSimon Glass * Modify memory. 784*2e192b24SSimon Glass * 785*2e192b24SSimon Glass * Returns zero on success, CMD_RET_USAGE in case of misuse and negative 786*2e192b24SSimon Glass * on error. 787*2e192b24SSimon Glass * 788*2e192b24SSimon Glass * Syntax: 789*2e192b24SSimon Glass * i2c mm{.b, .w, .l} {i2c_chip} {addr}{.0, .1, .2} 790*2e192b24SSimon Glass * i2c nm{.b, .w, .l} {i2c_chip} {addr}{.0, .1, .2} 791*2e192b24SSimon Glass */ 792*2e192b24SSimon Glass static int 793*2e192b24SSimon Glass mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const argv[]) 794*2e192b24SSimon Glass { 795*2e192b24SSimon Glass uint chip; 796*2e192b24SSimon Glass ulong addr; 797*2e192b24SSimon Glass int alen; 798*2e192b24SSimon Glass ulong data; 799*2e192b24SSimon Glass int size = 1; 800*2e192b24SSimon Glass int nbytes; 801*2e192b24SSimon Glass int ret; 802*2e192b24SSimon Glass #ifdef CONFIG_DM_I2C 803*2e192b24SSimon Glass struct udevice *dev; 804*2e192b24SSimon Glass #endif 805*2e192b24SSimon Glass 806*2e192b24SSimon Glass if (argc != 3) 807*2e192b24SSimon Glass return CMD_RET_USAGE; 808*2e192b24SSimon Glass 809*2e192b24SSimon Glass bootretry_reset_cmd_timeout(); /* got a good command to get here */ 810*2e192b24SSimon Glass /* 811*2e192b24SSimon Glass * We use the last specified parameters, unless new ones are 812*2e192b24SSimon Glass * entered. 813*2e192b24SSimon Glass */ 814*2e192b24SSimon Glass chip = i2c_mm_last_chip; 815*2e192b24SSimon Glass addr = i2c_mm_last_addr; 816*2e192b24SSimon Glass alen = i2c_mm_last_alen; 817*2e192b24SSimon Glass 818*2e192b24SSimon Glass if ((flag & CMD_FLAG_REPEAT) == 0) { 819*2e192b24SSimon Glass /* 820*2e192b24SSimon Glass * New command specified. Check for a size specification. 821*2e192b24SSimon Glass * Defaults to byte if no or incorrect specification. 822*2e192b24SSimon Glass */ 823*2e192b24SSimon Glass size = cmd_get_data_size(argv[0], 1); 824*2e192b24SSimon Glass 825*2e192b24SSimon Glass /* 826*2e192b24SSimon Glass * Chip is always specified. 827*2e192b24SSimon Glass */ 828*2e192b24SSimon Glass chip = simple_strtoul(argv[1], NULL, 16); 829*2e192b24SSimon Glass 830*2e192b24SSimon Glass /* 831*2e192b24SSimon Glass * Address is always specified. 832*2e192b24SSimon Glass */ 833*2e192b24SSimon Glass addr = simple_strtoul(argv[2], NULL, 16); 834*2e192b24SSimon Glass alen = get_alen(argv[2], DEFAULT_ADDR_LEN); 835*2e192b24SSimon Glass if (alen > 3) 836*2e192b24SSimon Glass return CMD_RET_USAGE; 837*2e192b24SSimon Glass } 838*2e192b24SSimon Glass 839*2e192b24SSimon Glass #ifdef CONFIG_DM_I2C 840*2e192b24SSimon Glass ret = i2c_get_cur_bus_chip(chip, &dev); 841*2e192b24SSimon Glass if (!ret && alen != -1) 842*2e192b24SSimon Glass ret = i2c_set_chip_offset_len(dev, alen); 843*2e192b24SSimon Glass if (ret) 844*2e192b24SSimon Glass return i2c_report_err(ret, I2C_ERR_WRITE); 845*2e192b24SSimon Glass #endif 846*2e192b24SSimon Glass 847*2e192b24SSimon Glass /* 848*2e192b24SSimon Glass * Print the address, followed by value. Then accept input for 849*2e192b24SSimon Glass * the next value. A non-converted value exits. 850*2e192b24SSimon Glass */ 851*2e192b24SSimon Glass do { 852*2e192b24SSimon Glass printf("%08lx:", addr); 853*2e192b24SSimon Glass #ifdef CONFIG_DM_I2C 854*2e192b24SSimon Glass ret = dm_i2c_read(dev, addr, (uchar *)&data, size); 855*2e192b24SSimon Glass #else 856*2e192b24SSimon Glass ret = i2c_read(chip, addr, alen, (uchar *)&data, size); 857*2e192b24SSimon Glass #endif 858*2e192b24SSimon Glass if (ret) 859*2e192b24SSimon Glass return i2c_report_err(ret, I2C_ERR_READ); 860*2e192b24SSimon Glass 861*2e192b24SSimon Glass data = cpu_to_be32(data); 862*2e192b24SSimon Glass if (size == 1) 863*2e192b24SSimon Glass printf(" %02lx", (data >> 24) & 0x000000FF); 864*2e192b24SSimon Glass else if (size == 2) 865*2e192b24SSimon Glass printf(" %04lx", (data >> 16) & 0x0000FFFF); 866*2e192b24SSimon Glass else 867*2e192b24SSimon Glass printf(" %08lx", data); 868*2e192b24SSimon Glass 869*2e192b24SSimon Glass nbytes = cli_readline(" ? "); 870*2e192b24SSimon Glass if (nbytes == 0) { 871*2e192b24SSimon Glass /* 872*2e192b24SSimon Glass * <CR> pressed as only input, don't modify current 873*2e192b24SSimon Glass * location and move to next. 874*2e192b24SSimon Glass */ 875*2e192b24SSimon Glass if (incrflag) 876*2e192b24SSimon Glass addr += size; 877*2e192b24SSimon Glass nbytes = size; 878*2e192b24SSimon Glass /* good enough to not time out */ 879*2e192b24SSimon Glass bootretry_reset_cmd_timeout(); 880*2e192b24SSimon Glass } 881*2e192b24SSimon Glass #ifdef CONFIG_BOOT_RETRY_TIME 882*2e192b24SSimon Glass else if (nbytes == -2) 883*2e192b24SSimon Glass break; /* timed out, exit the command */ 884*2e192b24SSimon Glass #endif 885*2e192b24SSimon Glass else { 886*2e192b24SSimon Glass char *endp; 887*2e192b24SSimon Glass 888*2e192b24SSimon Glass data = simple_strtoul(console_buffer, &endp, 16); 889*2e192b24SSimon Glass if (size == 1) 890*2e192b24SSimon Glass data = data << 24; 891*2e192b24SSimon Glass else if (size == 2) 892*2e192b24SSimon Glass data = data << 16; 893*2e192b24SSimon Glass data = be32_to_cpu(data); 894*2e192b24SSimon Glass nbytes = endp - console_buffer; 895*2e192b24SSimon Glass if (nbytes) { 896*2e192b24SSimon Glass /* 897*2e192b24SSimon Glass * good enough to not time out 898*2e192b24SSimon Glass */ 899*2e192b24SSimon Glass bootretry_reset_cmd_timeout(); 900*2e192b24SSimon Glass #ifdef CONFIG_DM_I2C 901*2e192b24SSimon Glass ret = dm_i2c_write(dev, addr, (uchar *)&data, 902*2e192b24SSimon Glass size); 903*2e192b24SSimon Glass #else 904*2e192b24SSimon Glass ret = i2c_write(chip, addr, alen, 905*2e192b24SSimon Glass (uchar *)&data, size); 906*2e192b24SSimon Glass #endif 907*2e192b24SSimon Glass if (ret) 908*2e192b24SSimon Glass return i2c_report_err(ret, 909*2e192b24SSimon Glass I2C_ERR_WRITE); 910*2e192b24SSimon Glass #ifdef CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS 911*2e192b24SSimon Glass udelay(CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS * 1000); 912*2e192b24SSimon Glass #endif 913*2e192b24SSimon Glass if (incrflag) 914*2e192b24SSimon Glass addr += size; 915*2e192b24SSimon Glass } 916*2e192b24SSimon Glass } 917*2e192b24SSimon Glass } while (nbytes); 918*2e192b24SSimon Glass 919*2e192b24SSimon Glass i2c_mm_last_chip = chip; 920*2e192b24SSimon Glass i2c_mm_last_addr = addr; 921*2e192b24SSimon Glass i2c_mm_last_alen = alen; 922*2e192b24SSimon Glass 923*2e192b24SSimon Glass return 0; 924*2e192b24SSimon Glass } 925*2e192b24SSimon Glass 926*2e192b24SSimon Glass /** 927*2e192b24SSimon Glass * do_i2c_probe() - Handle the "i2c probe" command-line command 928*2e192b24SSimon Glass * @cmdtp: Command data struct pointer 929*2e192b24SSimon Glass * @flag: Command flag 930*2e192b24SSimon Glass * @argc: Command-line argument count 931*2e192b24SSimon Glass * @argv: Array of command-line arguments 932*2e192b24SSimon Glass * 933*2e192b24SSimon Glass * Returns zero on success, CMD_RET_USAGE in case of misuse and negative 934*2e192b24SSimon Glass * on error. 935*2e192b24SSimon Glass * 936*2e192b24SSimon Glass * Syntax: 937*2e192b24SSimon Glass * i2c probe {addr} 938*2e192b24SSimon Glass * 939*2e192b24SSimon Glass * Returns zero (success) if one or more I2C devices was found 940*2e192b24SSimon Glass */ 941*2e192b24SSimon Glass static int do_i2c_probe (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 942*2e192b24SSimon Glass { 943*2e192b24SSimon Glass int j; 944*2e192b24SSimon Glass int addr = -1; 945*2e192b24SSimon Glass int found = 0; 946*2e192b24SSimon Glass #if defined(CONFIG_SYS_I2C_NOPROBES) 947*2e192b24SSimon Glass int k, skip; 948*2e192b24SSimon Glass unsigned int bus = GET_BUS_NUM; 949*2e192b24SSimon Glass #endif /* NOPROBES */ 950*2e192b24SSimon Glass int ret; 951*2e192b24SSimon Glass #ifdef CONFIG_DM_I2C 952*2e192b24SSimon Glass struct udevice *bus, *dev; 953*2e192b24SSimon Glass 954*2e192b24SSimon Glass if (i2c_get_cur_bus(&bus)) 955*2e192b24SSimon Glass return CMD_RET_FAILURE; 956*2e192b24SSimon Glass #endif 957*2e192b24SSimon Glass 958*2e192b24SSimon Glass if (argc == 2) 959*2e192b24SSimon Glass addr = simple_strtol(argv[1], 0, 16); 960*2e192b24SSimon Glass 961*2e192b24SSimon Glass puts ("Valid chip addresses:"); 962*2e192b24SSimon Glass for (j = 0; j < 128; j++) { 963*2e192b24SSimon Glass if ((0 <= addr) && (j != addr)) 964*2e192b24SSimon Glass continue; 965*2e192b24SSimon Glass 966*2e192b24SSimon Glass #if defined(CONFIG_SYS_I2C_NOPROBES) 967*2e192b24SSimon Glass skip = 0; 968*2e192b24SSimon Glass for (k = 0; k < ARRAY_SIZE(i2c_no_probes); k++) { 969*2e192b24SSimon Glass if (COMPARE_BUS(bus, k) && COMPARE_ADDR(j, k)) { 970*2e192b24SSimon Glass skip = 1; 971*2e192b24SSimon Glass break; 972*2e192b24SSimon Glass } 973*2e192b24SSimon Glass } 974*2e192b24SSimon Glass if (skip) 975*2e192b24SSimon Glass continue; 976*2e192b24SSimon Glass #endif 977*2e192b24SSimon Glass #ifdef CONFIG_DM_I2C 978*2e192b24SSimon Glass ret = dm_i2c_probe(bus, j, 0, &dev); 979*2e192b24SSimon Glass #else 980*2e192b24SSimon Glass ret = i2c_probe(j); 981*2e192b24SSimon Glass #endif 982*2e192b24SSimon Glass if (ret == 0) { 983*2e192b24SSimon Glass printf(" %02X", j); 984*2e192b24SSimon Glass found++; 985*2e192b24SSimon Glass } 986*2e192b24SSimon Glass } 987*2e192b24SSimon Glass putc ('\n'); 988*2e192b24SSimon Glass 989*2e192b24SSimon Glass #if defined(CONFIG_SYS_I2C_NOPROBES) 990*2e192b24SSimon Glass puts ("Excluded chip addresses:"); 991*2e192b24SSimon Glass for (k = 0; k < ARRAY_SIZE(i2c_no_probes); k++) { 992*2e192b24SSimon Glass if (COMPARE_BUS(bus,k)) 993*2e192b24SSimon Glass printf(" %02X", NO_PROBE_ADDR(k)); 994*2e192b24SSimon Glass } 995*2e192b24SSimon Glass putc ('\n'); 996*2e192b24SSimon Glass #endif 997*2e192b24SSimon Glass 998*2e192b24SSimon Glass return (0 == found); 999*2e192b24SSimon Glass } 1000*2e192b24SSimon Glass 1001*2e192b24SSimon Glass /** 1002*2e192b24SSimon Glass * do_i2c_loop() - Handle the "i2c loop" command-line command 1003*2e192b24SSimon Glass * @cmdtp: Command data struct pointer 1004*2e192b24SSimon Glass * @flag: Command flag 1005*2e192b24SSimon Glass * @argc: Command-line argument count 1006*2e192b24SSimon Glass * @argv: Array of command-line arguments 1007*2e192b24SSimon Glass * 1008*2e192b24SSimon Glass * Returns zero on success, CMD_RET_USAGE in case of misuse and negative 1009*2e192b24SSimon Glass * on error. 1010*2e192b24SSimon Glass * 1011*2e192b24SSimon Glass * Syntax: 1012*2e192b24SSimon Glass * i2c loop {i2c_chip} {addr}{.0, .1, .2} [{length}] [{delay}] 1013*2e192b24SSimon Glass * {length} - Number of bytes to read 1014*2e192b24SSimon Glass * {delay} - A DECIMAL number and defaults to 1000 uSec 1015*2e192b24SSimon Glass */ 1016*2e192b24SSimon Glass static int do_i2c_loop(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) 1017*2e192b24SSimon Glass { 1018*2e192b24SSimon Glass uint chip; 1019*2e192b24SSimon Glass int alen; 1020*2e192b24SSimon Glass uint addr; 1021*2e192b24SSimon Glass uint length; 1022*2e192b24SSimon Glass u_char bytes[16]; 1023*2e192b24SSimon Glass int delay; 1024*2e192b24SSimon Glass int ret; 1025*2e192b24SSimon Glass #ifdef CONFIG_DM_I2C 1026*2e192b24SSimon Glass struct udevice *dev; 1027*2e192b24SSimon Glass #endif 1028*2e192b24SSimon Glass 1029*2e192b24SSimon Glass if (argc < 3) 1030*2e192b24SSimon Glass return CMD_RET_USAGE; 1031*2e192b24SSimon Glass 1032*2e192b24SSimon Glass /* 1033*2e192b24SSimon Glass * Chip is always specified. 1034*2e192b24SSimon Glass */ 1035*2e192b24SSimon Glass chip = simple_strtoul(argv[1], NULL, 16); 1036*2e192b24SSimon Glass 1037*2e192b24SSimon Glass /* 1038*2e192b24SSimon Glass * Address is always specified. 1039*2e192b24SSimon Glass */ 1040*2e192b24SSimon Glass addr = simple_strtoul(argv[2], NULL, 16); 1041*2e192b24SSimon Glass alen = get_alen(argv[2], DEFAULT_ADDR_LEN); 1042*2e192b24SSimon Glass if (alen > 3) 1043*2e192b24SSimon Glass return CMD_RET_USAGE; 1044*2e192b24SSimon Glass #ifdef CONFIG_DM_I2C 1045*2e192b24SSimon Glass ret = i2c_get_cur_bus_chip(chip, &dev); 1046*2e192b24SSimon Glass if (!ret && alen != -1) 1047*2e192b24SSimon Glass ret = i2c_set_chip_offset_len(dev, alen); 1048*2e192b24SSimon Glass if (ret) 1049*2e192b24SSimon Glass return i2c_report_err(ret, I2C_ERR_WRITE); 1050*2e192b24SSimon Glass #endif 1051*2e192b24SSimon Glass 1052*2e192b24SSimon Glass /* 1053*2e192b24SSimon Glass * Length is the number of objects, not number of bytes. 1054*2e192b24SSimon Glass */ 1055*2e192b24SSimon Glass length = 1; 1056*2e192b24SSimon Glass length = simple_strtoul(argv[3], NULL, 16); 1057*2e192b24SSimon Glass if (length > sizeof(bytes)) 1058*2e192b24SSimon Glass length = sizeof(bytes); 1059*2e192b24SSimon Glass 1060*2e192b24SSimon Glass /* 1061*2e192b24SSimon Glass * The delay time (uSec) is optional. 1062*2e192b24SSimon Glass */ 1063*2e192b24SSimon Glass delay = 1000; 1064*2e192b24SSimon Glass if (argc > 3) 1065*2e192b24SSimon Glass delay = simple_strtoul(argv[4], NULL, 10); 1066*2e192b24SSimon Glass /* 1067*2e192b24SSimon Glass * Run the loop... 1068*2e192b24SSimon Glass */ 1069*2e192b24SSimon Glass while (1) { 1070*2e192b24SSimon Glass #ifdef CONFIG_DM_I2C 1071*2e192b24SSimon Glass ret = dm_i2c_read(dev, addr, bytes, length); 1072*2e192b24SSimon Glass #else 1073*2e192b24SSimon Glass ret = i2c_read(chip, addr, alen, bytes, length); 1074*2e192b24SSimon Glass #endif 1075*2e192b24SSimon Glass if (ret) 1076*2e192b24SSimon Glass i2c_report_err(ret, I2C_ERR_READ); 1077*2e192b24SSimon Glass udelay(delay); 1078*2e192b24SSimon Glass } 1079*2e192b24SSimon Glass 1080*2e192b24SSimon Glass /* NOTREACHED */ 1081*2e192b24SSimon Glass return 0; 1082*2e192b24SSimon Glass } 1083*2e192b24SSimon Glass 1084*2e192b24SSimon Glass /* 1085*2e192b24SSimon Glass * The SDRAM command is separately configured because many 1086*2e192b24SSimon Glass * (most?) embedded boards don't use SDRAM DIMMs. 1087*2e192b24SSimon Glass * 1088*2e192b24SSimon Glass * FIXME: Document and probably move elsewhere! 1089*2e192b24SSimon Glass */ 1090*2e192b24SSimon Glass #if defined(CONFIG_CMD_SDRAM) 1091*2e192b24SSimon Glass static void print_ddr2_tcyc (u_char const b) 1092*2e192b24SSimon Glass { 1093*2e192b24SSimon Glass printf ("%d.", (b >> 4) & 0x0F); 1094*2e192b24SSimon Glass switch (b & 0x0F) { 1095*2e192b24SSimon Glass case 0x0: 1096*2e192b24SSimon Glass case 0x1: 1097*2e192b24SSimon Glass case 0x2: 1098*2e192b24SSimon Glass case 0x3: 1099*2e192b24SSimon Glass case 0x4: 1100*2e192b24SSimon Glass case 0x5: 1101*2e192b24SSimon Glass case 0x6: 1102*2e192b24SSimon Glass case 0x7: 1103*2e192b24SSimon Glass case 0x8: 1104*2e192b24SSimon Glass case 0x9: 1105*2e192b24SSimon Glass printf ("%d ns\n", b & 0x0F); 1106*2e192b24SSimon Glass break; 1107*2e192b24SSimon Glass case 0xA: 1108*2e192b24SSimon Glass puts ("25 ns\n"); 1109*2e192b24SSimon Glass break; 1110*2e192b24SSimon Glass case 0xB: 1111*2e192b24SSimon Glass puts ("33 ns\n"); 1112*2e192b24SSimon Glass break; 1113*2e192b24SSimon Glass case 0xC: 1114*2e192b24SSimon Glass puts ("66 ns\n"); 1115*2e192b24SSimon Glass break; 1116*2e192b24SSimon Glass case 0xD: 1117*2e192b24SSimon Glass puts ("75 ns\n"); 1118*2e192b24SSimon Glass break; 1119*2e192b24SSimon Glass default: 1120*2e192b24SSimon Glass puts ("?? ns\n"); 1121*2e192b24SSimon Glass break; 1122*2e192b24SSimon Glass } 1123*2e192b24SSimon Glass } 1124*2e192b24SSimon Glass 1125*2e192b24SSimon Glass static void decode_bits (u_char const b, char const *str[], int const do_once) 1126*2e192b24SSimon Glass { 1127*2e192b24SSimon Glass u_char mask; 1128*2e192b24SSimon Glass 1129*2e192b24SSimon Glass for (mask = 0x80; mask != 0x00; mask >>= 1, ++str) { 1130*2e192b24SSimon Glass if (b & mask) { 1131*2e192b24SSimon Glass puts (*str); 1132*2e192b24SSimon Glass if (do_once) 1133*2e192b24SSimon Glass return; 1134*2e192b24SSimon Glass } 1135*2e192b24SSimon Glass } 1136*2e192b24SSimon Glass } 1137*2e192b24SSimon Glass 1138*2e192b24SSimon Glass /* 1139*2e192b24SSimon Glass * Syntax: 1140*2e192b24SSimon Glass * i2c sdram {i2c_chip} 1141*2e192b24SSimon Glass */ 1142*2e192b24SSimon Glass static int do_sdram (cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) 1143*2e192b24SSimon Glass { 1144*2e192b24SSimon Glass enum { unknown, EDO, SDRAM, DDR2 } type; 1145*2e192b24SSimon Glass 1146*2e192b24SSimon Glass uint chip; 1147*2e192b24SSimon Glass u_char data[128]; 1148*2e192b24SSimon Glass u_char cksum; 1149*2e192b24SSimon Glass int j; 1150*2e192b24SSimon Glass 1151*2e192b24SSimon Glass static const char *decode_CAS_DDR2[] = { 1152*2e192b24SSimon Glass " TBD", " 6", " 5", " 4", " 3", " 2", " TBD", " TBD" 1153*2e192b24SSimon Glass }; 1154*2e192b24SSimon Glass 1155*2e192b24SSimon Glass static const char *decode_CAS_default[] = { 1156*2e192b24SSimon Glass " TBD", " 7", " 6", " 5", " 4", " 3", " 2", " 1" 1157*2e192b24SSimon Glass }; 1158*2e192b24SSimon Glass 1159*2e192b24SSimon Glass static const char *decode_CS_WE_default[] = { 1160*2e192b24SSimon Glass " TBD", " 6", " 5", " 4", " 3", " 2", " 1", " 0" 1161*2e192b24SSimon Glass }; 1162*2e192b24SSimon Glass 1163*2e192b24SSimon Glass static const char *decode_byte21_default[] = { 1164*2e192b24SSimon Glass " TBD (bit 7)\n", 1165*2e192b24SSimon Glass " Redundant row address\n", 1166*2e192b24SSimon Glass " Differential clock input\n", 1167*2e192b24SSimon Glass " Registerd DQMB inputs\n", 1168*2e192b24SSimon Glass " Buffered DQMB inputs\n", 1169*2e192b24SSimon Glass " On-card PLL\n", 1170*2e192b24SSimon Glass " Registered address/control lines\n", 1171*2e192b24SSimon Glass " Buffered address/control lines\n" 1172*2e192b24SSimon Glass }; 1173*2e192b24SSimon Glass 1174*2e192b24SSimon Glass static const char *decode_byte22_DDR2[] = { 1175*2e192b24SSimon Glass " TBD (bit 7)\n", 1176*2e192b24SSimon Glass " TBD (bit 6)\n", 1177*2e192b24SSimon Glass " TBD (bit 5)\n", 1178*2e192b24SSimon Glass " TBD (bit 4)\n", 1179*2e192b24SSimon Glass " TBD (bit 3)\n", 1180*2e192b24SSimon Glass " Supports partial array self refresh\n", 1181*2e192b24SSimon Glass " Supports 50 ohm ODT\n", 1182*2e192b24SSimon Glass " Supports weak driver\n" 1183*2e192b24SSimon Glass }; 1184*2e192b24SSimon Glass 1185*2e192b24SSimon Glass static const char *decode_row_density_DDR2[] = { 1186*2e192b24SSimon Glass "512 MiB", "256 MiB", "128 MiB", "16 GiB", 1187*2e192b24SSimon Glass "8 GiB", "4 GiB", "2 GiB", "1 GiB" 1188*2e192b24SSimon Glass }; 1189*2e192b24SSimon Glass 1190*2e192b24SSimon Glass static const char *decode_row_density_default[] = { 1191*2e192b24SSimon Glass "512 MiB", "256 MiB", "128 MiB", "64 MiB", 1192*2e192b24SSimon Glass "32 MiB", "16 MiB", "8 MiB", "4 MiB" 1193*2e192b24SSimon Glass }; 1194*2e192b24SSimon Glass 1195*2e192b24SSimon Glass if (argc < 2) 1196*2e192b24SSimon Glass return CMD_RET_USAGE; 1197*2e192b24SSimon Glass 1198*2e192b24SSimon Glass /* 1199*2e192b24SSimon Glass * Chip is always specified. 1200*2e192b24SSimon Glass */ 1201*2e192b24SSimon Glass chip = simple_strtoul (argv[1], NULL, 16); 1202*2e192b24SSimon Glass 1203*2e192b24SSimon Glass if (i2c_read (chip, 0, 1, data, sizeof (data)) != 0) { 1204*2e192b24SSimon Glass puts ("No SDRAM Serial Presence Detect found.\n"); 1205*2e192b24SSimon Glass return 1; 1206*2e192b24SSimon Glass } 1207*2e192b24SSimon Glass 1208*2e192b24SSimon Glass cksum = 0; 1209*2e192b24SSimon Glass for (j = 0; j < 63; j++) { 1210*2e192b24SSimon Glass cksum += data[j]; 1211*2e192b24SSimon Glass } 1212*2e192b24SSimon Glass if (cksum != data[63]) { 1213*2e192b24SSimon Glass printf ("WARNING: Configuration data checksum failure:\n" 1214*2e192b24SSimon Glass " is 0x%02x, calculated 0x%02x\n", data[63], cksum); 1215*2e192b24SSimon Glass } 1216*2e192b24SSimon Glass printf ("SPD data revision %d.%d\n", 1217*2e192b24SSimon Glass (data[62] >> 4) & 0x0F, data[62] & 0x0F); 1218*2e192b24SSimon Glass printf ("Bytes used 0x%02X\n", data[0]); 1219*2e192b24SSimon Glass printf ("Serial memory size 0x%02X\n", 1 << data[1]); 1220*2e192b24SSimon Glass 1221*2e192b24SSimon Glass puts ("Memory type "); 1222*2e192b24SSimon Glass switch (data[2]) { 1223*2e192b24SSimon Glass case 2: 1224*2e192b24SSimon Glass type = EDO; 1225*2e192b24SSimon Glass puts ("EDO\n"); 1226*2e192b24SSimon Glass break; 1227*2e192b24SSimon Glass case 4: 1228*2e192b24SSimon Glass type = SDRAM; 1229*2e192b24SSimon Glass puts ("SDRAM\n"); 1230*2e192b24SSimon Glass break; 1231*2e192b24SSimon Glass case 8: 1232*2e192b24SSimon Glass type = DDR2; 1233*2e192b24SSimon Glass puts ("DDR2\n"); 1234*2e192b24SSimon Glass break; 1235*2e192b24SSimon Glass default: 1236*2e192b24SSimon Glass type = unknown; 1237*2e192b24SSimon Glass puts ("unknown\n"); 1238*2e192b24SSimon Glass break; 1239*2e192b24SSimon Glass } 1240*2e192b24SSimon Glass 1241*2e192b24SSimon Glass puts ("Row address bits "); 1242*2e192b24SSimon Glass if ((data[3] & 0x00F0) == 0) 1243*2e192b24SSimon Glass printf ("%d\n", data[3] & 0x0F); 1244*2e192b24SSimon Glass else 1245*2e192b24SSimon Glass printf ("%d/%d\n", data[3] & 0x0F, (data[3] >> 4) & 0x0F); 1246*2e192b24SSimon Glass 1247*2e192b24SSimon Glass puts ("Column address bits "); 1248*2e192b24SSimon Glass if ((data[4] & 0x00F0) == 0) 1249*2e192b24SSimon Glass printf ("%d\n", data[4] & 0x0F); 1250*2e192b24SSimon Glass else 1251*2e192b24SSimon Glass printf ("%d/%d\n", data[4] & 0x0F, (data[4] >> 4) & 0x0F); 1252*2e192b24SSimon Glass 1253*2e192b24SSimon Glass switch (type) { 1254*2e192b24SSimon Glass case DDR2: 1255*2e192b24SSimon Glass printf ("Number of ranks %d\n", 1256*2e192b24SSimon Glass (data[5] & 0x07) + 1); 1257*2e192b24SSimon Glass break; 1258*2e192b24SSimon Glass default: 1259*2e192b24SSimon Glass printf ("Module rows %d\n", data[5]); 1260*2e192b24SSimon Glass break; 1261*2e192b24SSimon Glass } 1262*2e192b24SSimon Glass 1263*2e192b24SSimon Glass switch (type) { 1264*2e192b24SSimon Glass case DDR2: 1265*2e192b24SSimon Glass printf ("Module data width %d bits\n", data[6]); 1266*2e192b24SSimon Glass break; 1267*2e192b24SSimon Glass default: 1268*2e192b24SSimon Glass printf ("Module data width %d bits\n", 1269*2e192b24SSimon Glass (data[7] << 8) | data[6]); 1270*2e192b24SSimon Glass break; 1271*2e192b24SSimon Glass } 1272*2e192b24SSimon Glass 1273*2e192b24SSimon Glass puts ("Interface signal levels "); 1274*2e192b24SSimon Glass switch(data[8]) { 1275*2e192b24SSimon Glass case 0: puts ("TTL 5.0 V\n"); break; 1276*2e192b24SSimon Glass case 1: puts ("LVTTL\n"); break; 1277*2e192b24SSimon Glass case 2: puts ("HSTL 1.5 V\n"); break; 1278*2e192b24SSimon Glass case 3: puts ("SSTL 3.3 V\n"); break; 1279*2e192b24SSimon Glass case 4: puts ("SSTL 2.5 V\n"); break; 1280*2e192b24SSimon Glass case 5: puts ("SSTL 1.8 V\n"); break; 1281*2e192b24SSimon Glass default: puts ("unknown\n"); break; 1282*2e192b24SSimon Glass } 1283*2e192b24SSimon Glass 1284*2e192b24SSimon Glass switch (type) { 1285*2e192b24SSimon Glass case DDR2: 1286*2e192b24SSimon Glass printf ("SDRAM cycle time "); 1287*2e192b24SSimon Glass print_ddr2_tcyc (data[9]); 1288*2e192b24SSimon Glass break; 1289*2e192b24SSimon Glass default: 1290*2e192b24SSimon Glass printf ("SDRAM cycle time %d.%d ns\n", 1291*2e192b24SSimon Glass (data[9] >> 4) & 0x0F, data[9] & 0x0F); 1292*2e192b24SSimon Glass break; 1293*2e192b24SSimon Glass } 1294*2e192b24SSimon Glass 1295*2e192b24SSimon Glass switch (type) { 1296*2e192b24SSimon Glass case DDR2: 1297*2e192b24SSimon Glass printf ("SDRAM access time 0.%d%d ns\n", 1298*2e192b24SSimon Glass (data[10] >> 4) & 0x0F, data[10] & 0x0F); 1299*2e192b24SSimon Glass break; 1300*2e192b24SSimon Glass default: 1301*2e192b24SSimon Glass printf ("SDRAM access time %d.%d ns\n", 1302*2e192b24SSimon Glass (data[10] >> 4) & 0x0F, data[10] & 0x0F); 1303*2e192b24SSimon Glass break; 1304*2e192b24SSimon Glass } 1305*2e192b24SSimon Glass 1306*2e192b24SSimon Glass puts ("EDC configuration "); 1307*2e192b24SSimon Glass switch (data[11]) { 1308*2e192b24SSimon Glass case 0: puts ("None\n"); break; 1309*2e192b24SSimon Glass case 1: puts ("Parity\n"); break; 1310*2e192b24SSimon Glass case 2: puts ("ECC\n"); break; 1311*2e192b24SSimon Glass default: puts ("unknown\n"); break; 1312*2e192b24SSimon Glass } 1313*2e192b24SSimon Glass 1314*2e192b24SSimon Glass if ((data[12] & 0x80) == 0) 1315*2e192b24SSimon Glass puts ("No self refresh, rate "); 1316*2e192b24SSimon Glass else 1317*2e192b24SSimon Glass puts ("Self refresh, rate "); 1318*2e192b24SSimon Glass 1319*2e192b24SSimon Glass switch(data[12] & 0x7F) { 1320*2e192b24SSimon Glass case 0: puts ("15.625 us\n"); break; 1321*2e192b24SSimon Glass case 1: puts ("3.9 us\n"); break; 1322*2e192b24SSimon Glass case 2: puts ("7.8 us\n"); break; 1323*2e192b24SSimon Glass case 3: puts ("31.3 us\n"); break; 1324*2e192b24SSimon Glass case 4: puts ("62.5 us\n"); break; 1325*2e192b24SSimon Glass case 5: puts ("125 us\n"); break; 1326*2e192b24SSimon Glass default: puts ("unknown\n"); break; 1327*2e192b24SSimon Glass } 1328*2e192b24SSimon Glass 1329*2e192b24SSimon Glass switch (type) { 1330*2e192b24SSimon Glass case DDR2: 1331*2e192b24SSimon Glass printf ("SDRAM width (primary) %d\n", data[13]); 1332*2e192b24SSimon Glass break; 1333*2e192b24SSimon Glass default: 1334*2e192b24SSimon Glass printf ("SDRAM width (primary) %d\n", data[13] & 0x7F); 1335*2e192b24SSimon Glass if ((data[13] & 0x80) != 0) { 1336*2e192b24SSimon Glass printf (" (second bank) %d\n", 1337*2e192b24SSimon Glass 2 * (data[13] & 0x7F)); 1338*2e192b24SSimon Glass } 1339*2e192b24SSimon Glass break; 1340*2e192b24SSimon Glass } 1341*2e192b24SSimon Glass 1342*2e192b24SSimon Glass switch (type) { 1343*2e192b24SSimon Glass case DDR2: 1344*2e192b24SSimon Glass if (data[14] != 0) 1345*2e192b24SSimon Glass printf ("EDC width %d\n", data[14]); 1346*2e192b24SSimon Glass break; 1347*2e192b24SSimon Glass default: 1348*2e192b24SSimon Glass if (data[14] != 0) { 1349*2e192b24SSimon Glass printf ("EDC width %d\n", 1350*2e192b24SSimon Glass data[14] & 0x7F); 1351*2e192b24SSimon Glass 1352*2e192b24SSimon Glass if ((data[14] & 0x80) != 0) { 1353*2e192b24SSimon Glass printf (" (second bank) %d\n", 1354*2e192b24SSimon Glass 2 * (data[14] & 0x7F)); 1355*2e192b24SSimon Glass } 1356*2e192b24SSimon Glass } 1357*2e192b24SSimon Glass break; 1358*2e192b24SSimon Glass } 1359*2e192b24SSimon Glass 1360*2e192b24SSimon Glass if (DDR2 != type) { 1361*2e192b24SSimon Glass printf ("Min clock delay, back-to-back random column addresses " 1362*2e192b24SSimon Glass "%d\n", data[15]); 1363*2e192b24SSimon Glass } 1364*2e192b24SSimon Glass 1365*2e192b24SSimon Glass puts ("Burst length(s) "); 1366*2e192b24SSimon Glass if (data[16] & 0x80) puts (" Page"); 1367*2e192b24SSimon Glass if (data[16] & 0x08) puts (" 8"); 1368*2e192b24SSimon Glass if (data[16] & 0x04) puts (" 4"); 1369*2e192b24SSimon Glass if (data[16] & 0x02) puts (" 2"); 1370*2e192b24SSimon Glass if (data[16] & 0x01) puts (" 1"); 1371*2e192b24SSimon Glass putc ('\n'); 1372*2e192b24SSimon Glass printf ("Number of banks %d\n", data[17]); 1373*2e192b24SSimon Glass 1374*2e192b24SSimon Glass switch (type) { 1375*2e192b24SSimon Glass case DDR2: 1376*2e192b24SSimon Glass puts ("CAS latency(s) "); 1377*2e192b24SSimon Glass decode_bits (data[18], decode_CAS_DDR2, 0); 1378*2e192b24SSimon Glass putc ('\n'); 1379*2e192b24SSimon Glass break; 1380*2e192b24SSimon Glass default: 1381*2e192b24SSimon Glass puts ("CAS latency(s) "); 1382*2e192b24SSimon Glass decode_bits (data[18], decode_CAS_default, 0); 1383*2e192b24SSimon Glass putc ('\n'); 1384*2e192b24SSimon Glass break; 1385*2e192b24SSimon Glass } 1386*2e192b24SSimon Glass 1387*2e192b24SSimon Glass if (DDR2 != type) { 1388*2e192b24SSimon Glass puts ("CS latency(s) "); 1389*2e192b24SSimon Glass decode_bits (data[19], decode_CS_WE_default, 0); 1390*2e192b24SSimon Glass putc ('\n'); 1391*2e192b24SSimon Glass } 1392*2e192b24SSimon Glass 1393*2e192b24SSimon Glass if (DDR2 != type) { 1394*2e192b24SSimon Glass puts ("WE latency(s) "); 1395*2e192b24SSimon Glass decode_bits (data[20], decode_CS_WE_default, 0); 1396*2e192b24SSimon Glass putc ('\n'); 1397*2e192b24SSimon Glass } 1398*2e192b24SSimon Glass 1399*2e192b24SSimon Glass switch (type) { 1400*2e192b24SSimon Glass case DDR2: 1401*2e192b24SSimon Glass puts ("Module attributes:\n"); 1402*2e192b24SSimon Glass if (data[21] & 0x80) 1403*2e192b24SSimon Glass puts (" TBD (bit 7)\n"); 1404*2e192b24SSimon Glass if (data[21] & 0x40) 1405*2e192b24SSimon Glass puts (" Analysis probe installed\n"); 1406*2e192b24SSimon Glass if (data[21] & 0x20) 1407*2e192b24SSimon Glass puts (" TBD (bit 5)\n"); 1408*2e192b24SSimon Glass if (data[21] & 0x10) 1409*2e192b24SSimon Glass puts (" FET switch external enable\n"); 1410*2e192b24SSimon Glass printf (" %d PLLs on DIMM\n", (data[21] >> 2) & 0x03); 1411*2e192b24SSimon Glass if (data[20] & 0x11) { 1412*2e192b24SSimon Glass printf (" %d active registers on DIMM\n", 1413*2e192b24SSimon Glass (data[21] & 0x03) + 1); 1414*2e192b24SSimon Glass } 1415*2e192b24SSimon Glass break; 1416*2e192b24SSimon Glass default: 1417*2e192b24SSimon Glass puts ("Module attributes:\n"); 1418*2e192b24SSimon Glass if (!data[21]) 1419*2e192b24SSimon Glass puts (" (none)\n"); 1420*2e192b24SSimon Glass else 1421*2e192b24SSimon Glass decode_bits (data[21], decode_byte21_default, 0); 1422*2e192b24SSimon Glass break; 1423*2e192b24SSimon Glass } 1424*2e192b24SSimon Glass 1425*2e192b24SSimon Glass switch (type) { 1426*2e192b24SSimon Glass case DDR2: 1427*2e192b24SSimon Glass decode_bits (data[22], decode_byte22_DDR2, 0); 1428*2e192b24SSimon Glass break; 1429*2e192b24SSimon Glass default: 1430*2e192b24SSimon Glass puts ("Device attributes:\n"); 1431*2e192b24SSimon Glass if (data[22] & 0x80) puts (" TBD (bit 7)\n"); 1432*2e192b24SSimon Glass if (data[22] & 0x40) puts (" TBD (bit 6)\n"); 1433*2e192b24SSimon Glass if (data[22] & 0x20) puts (" Upper Vcc tolerance 5%\n"); 1434*2e192b24SSimon Glass else puts (" Upper Vcc tolerance 10%\n"); 1435*2e192b24SSimon Glass if (data[22] & 0x10) puts (" Lower Vcc tolerance 5%\n"); 1436*2e192b24SSimon Glass else puts (" Lower Vcc tolerance 10%\n"); 1437*2e192b24SSimon Glass if (data[22] & 0x08) puts (" Supports write1/read burst\n"); 1438*2e192b24SSimon Glass if (data[22] & 0x04) puts (" Supports precharge all\n"); 1439*2e192b24SSimon Glass if (data[22] & 0x02) puts (" Supports auto precharge\n"); 1440*2e192b24SSimon Glass if (data[22] & 0x01) puts (" Supports early RAS# precharge\n"); 1441*2e192b24SSimon Glass break; 1442*2e192b24SSimon Glass } 1443*2e192b24SSimon Glass 1444*2e192b24SSimon Glass switch (type) { 1445*2e192b24SSimon Glass case DDR2: 1446*2e192b24SSimon Glass printf ("SDRAM cycle time (2nd highest CAS latency) "); 1447*2e192b24SSimon Glass print_ddr2_tcyc (data[23]); 1448*2e192b24SSimon Glass break; 1449*2e192b24SSimon Glass default: 1450*2e192b24SSimon Glass printf ("SDRAM cycle time (2nd highest CAS latency) %d." 1451*2e192b24SSimon Glass "%d ns\n", (data[23] >> 4) & 0x0F, data[23] & 0x0F); 1452*2e192b24SSimon Glass break; 1453*2e192b24SSimon Glass } 1454*2e192b24SSimon Glass 1455*2e192b24SSimon Glass switch (type) { 1456*2e192b24SSimon Glass case DDR2: 1457*2e192b24SSimon Glass printf ("SDRAM access from clock (2nd highest CAS latency) 0." 1458*2e192b24SSimon Glass "%d%d ns\n", (data[24] >> 4) & 0x0F, data[24] & 0x0F); 1459*2e192b24SSimon Glass break; 1460*2e192b24SSimon Glass default: 1461*2e192b24SSimon Glass printf ("SDRAM access from clock (2nd highest CAS latency) %d." 1462*2e192b24SSimon Glass "%d ns\n", (data[24] >> 4) & 0x0F, data[24] & 0x0F); 1463*2e192b24SSimon Glass break; 1464*2e192b24SSimon Glass } 1465*2e192b24SSimon Glass 1466*2e192b24SSimon Glass switch (type) { 1467*2e192b24SSimon Glass case DDR2: 1468*2e192b24SSimon Glass printf ("SDRAM cycle time (3rd highest CAS latency) "); 1469*2e192b24SSimon Glass print_ddr2_tcyc (data[25]); 1470*2e192b24SSimon Glass break; 1471*2e192b24SSimon Glass default: 1472*2e192b24SSimon Glass printf ("SDRAM cycle time (3rd highest CAS latency) %d." 1473*2e192b24SSimon Glass "%d ns\n", (data[25] >> 4) & 0x0F, data[25] & 0x0F); 1474*2e192b24SSimon Glass break; 1475*2e192b24SSimon Glass } 1476*2e192b24SSimon Glass 1477*2e192b24SSimon Glass switch (type) { 1478*2e192b24SSimon Glass case DDR2: 1479*2e192b24SSimon Glass printf ("SDRAM access from clock (3rd highest CAS latency) 0." 1480*2e192b24SSimon Glass "%d%d ns\n", (data[26] >> 4) & 0x0F, data[26] & 0x0F); 1481*2e192b24SSimon Glass break; 1482*2e192b24SSimon Glass default: 1483*2e192b24SSimon Glass printf ("SDRAM access from clock (3rd highest CAS latency) %d." 1484*2e192b24SSimon Glass "%d ns\n", (data[26] >> 4) & 0x0F, data[26] & 0x0F); 1485*2e192b24SSimon Glass break; 1486*2e192b24SSimon Glass } 1487*2e192b24SSimon Glass 1488*2e192b24SSimon Glass switch (type) { 1489*2e192b24SSimon Glass case DDR2: 1490*2e192b24SSimon Glass printf ("Minimum row precharge %d.%02d ns\n", 1491*2e192b24SSimon Glass (data[27] >> 2) & 0x3F, 25 * (data[27] & 0x03)); 1492*2e192b24SSimon Glass break; 1493*2e192b24SSimon Glass default: 1494*2e192b24SSimon Glass printf ("Minimum row precharge %d ns\n", data[27]); 1495*2e192b24SSimon Glass break; 1496*2e192b24SSimon Glass } 1497*2e192b24SSimon Glass 1498*2e192b24SSimon Glass switch (type) { 1499*2e192b24SSimon Glass case DDR2: 1500*2e192b24SSimon Glass printf ("Row active to row active min %d.%02d ns\n", 1501*2e192b24SSimon Glass (data[28] >> 2) & 0x3F, 25 * (data[28] & 0x03)); 1502*2e192b24SSimon Glass break; 1503*2e192b24SSimon Glass default: 1504*2e192b24SSimon Glass printf ("Row active to row active min %d ns\n", data[28]); 1505*2e192b24SSimon Glass break; 1506*2e192b24SSimon Glass } 1507*2e192b24SSimon Glass 1508*2e192b24SSimon Glass switch (type) { 1509*2e192b24SSimon Glass case DDR2: 1510*2e192b24SSimon Glass printf ("RAS to CAS delay min %d.%02d ns\n", 1511*2e192b24SSimon Glass (data[29] >> 2) & 0x3F, 25 * (data[29] & 0x03)); 1512*2e192b24SSimon Glass break; 1513*2e192b24SSimon Glass default: 1514*2e192b24SSimon Glass printf ("RAS to CAS delay min %d ns\n", data[29]); 1515*2e192b24SSimon Glass break; 1516*2e192b24SSimon Glass } 1517*2e192b24SSimon Glass 1518*2e192b24SSimon Glass printf ("Minimum RAS pulse width %d ns\n", data[30]); 1519*2e192b24SSimon Glass 1520*2e192b24SSimon Glass switch (type) { 1521*2e192b24SSimon Glass case DDR2: 1522*2e192b24SSimon Glass puts ("Density of each row "); 1523*2e192b24SSimon Glass decode_bits (data[31], decode_row_density_DDR2, 1); 1524*2e192b24SSimon Glass putc ('\n'); 1525*2e192b24SSimon Glass break; 1526*2e192b24SSimon Glass default: 1527*2e192b24SSimon Glass puts ("Density of each row "); 1528*2e192b24SSimon Glass decode_bits (data[31], decode_row_density_default, 1); 1529*2e192b24SSimon Glass putc ('\n'); 1530*2e192b24SSimon Glass break; 1531*2e192b24SSimon Glass } 1532*2e192b24SSimon Glass 1533*2e192b24SSimon Glass switch (type) { 1534*2e192b24SSimon Glass case DDR2: 1535*2e192b24SSimon Glass puts ("Command and Address setup "); 1536*2e192b24SSimon Glass if (data[32] >= 0xA0) { 1537*2e192b24SSimon Glass printf ("1.%d%d ns\n", 1538*2e192b24SSimon Glass ((data[32] >> 4) & 0x0F) - 10, data[32] & 0x0F); 1539*2e192b24SSimon Glass } else { 1540*2e192b24SSimon Glass printf ("0.%d%d ns\n", 1541*2e192b24SSimon Glass ((data[32] >> 4) & 0x0F), data[32] & 0x0F); 1542*2e192b24SSimon Glass } 1543*2e192b24SSimon Glass break; 1544*2e192b24SSimon Glass default: 1545*2e192b24SSimon Glass printf ("Command and Address setup %c%d.%d ns\n", 1546*2e192b24SSimon Glass (data[32] & 0x80) ? '-' : '+', 1547*2e192b24SSimon Glass (data[32] >> 4) & 0x07, data[32] & 0x0F); 1548*2e192b24SSimon Glass break; 1549*2e192b24SSimon Glass } 1550*2e192b24SSimon Glass 1551*2e192b24SSimon Glass switch (type) { 1552*2e192b24SSimon Glass case DDR2: 1553*2e192b24SSimon Glass puts ("Command and Address hold "); 1554*2e192b24SSimon Glass if (data[33] >= 0xA0) { 1555*2e192b24SSimon Glass printf ("1.%d%d ns\n", 1556*2e192b24SSimon Glass ((data[33] >> 4) & 0x0F) - 10, data[33] & 0x0F); 1557*2e192b24SSimon Glass } else { 1558*2e192b24SSimon Glass printf ("0.%d%d ns\n", 1559*2e192b24SSimon Glass ((data[33] >> 4) & 0x0F), data[33] & 0x0F); 1560*2e192b24SSimon Glass } 1561*2e192b24SSimon Glass break; 1562*2e192b24SSimon Glass default: 1563*2e192b24SSimon Glass printf ("Command and Address hold %c%d.%d ns\n", 1564*2e192b24SSimon Glass (data[33] & 0x80) ? '-' : '+', 1565*2e192b24SSimon Glass (data[33] >> 4) & 0x07, data[33] & 0x0F); 1566*2e192b24SSimon Glass break; 1567*2e192b24SSimon Glass } 1568*2e192b24SSimon Glass 1569*2e192b24SSimon Glass switch (type) { 1570*2e192b24SSimon Glass case DDR2: 1571*2e192b24SSimon Glass printf ("Data signal input setup 0.%d%d ns\n", 1572*2e192b24SSimon Glass (data[34] >> 4) & 0x0F, data[34] & 0x0F); 1573*2e192b24SSimon Glass break; 1574*2e192b24SSimon Glass default: 1575*2e192b24SSimon Glass printf ("Data signal input setup %c%d.%d ns\n", 1576*2e192b24SSimon Glass (data[34] & 0x80) ? '-' : '+', 1577*2e192b24SSimon Glass (data[34] >> 4) & 0x07, data[34] & 0x0F); 1578*2e192b24SSimon Glass break; 1579*2e192b24SSimon Glass } 1580*2e192b24SSimon Glass 1581*2e192b24SSimon Glass switch (type) { 1582*2e192b24SSimon Glass case DDR2: 1583*2e192b24SSimon Glass printf ("Data signal input hold 0.%d%d ns\n", 1584*2e192b24SSimon Glass (data[35] >> 4) & 0x0F, data[35] & 0x0F); 1585*2e192b24SSimon Glass break; 1586*2e192b24SSimon Glass default: 1587*2e192b24SSimon Glass printf ("Data signal input hold %c%d.%d ns\n", 1588*2e192b24SSimon Glass (data[35] & 0x80) ? '-' : '+', 1589*2e192b24SSimon Glass (data[35] >> 4) & 0x07, data[35] & 0x0F); 1590*2e192b24SSimon Glass break; 1591*2e192b24SSimon Glass } 1592*2e192b24SSimon Glass 1593*2e192b24SSimon Glass puts ("Manufacturer's JEDEC ID "); 1594*2e192b24SSimon Glass for (j = 64; j <= 71; j++) 1595*2e192b24SSimon Glass printf ("%02X ", data[j]); 1596*2e192b24SSimon Glass putc ('\n'); 1597*2e192b24SSimon Glass printf ("Manufacturing Location %02X\n", data[72]); 1598*2e192b24SSimon Glass puts ("Manufacturer's Part Number "); 1599*2e192b24SSimon Glass for (j = 73; j <= 90; j++) 1600*2e192b24SSimon Glass printf ("%02X ", data[j]); 1601*2e192b24SSimon Glass putc ('\n'); 1602*2e192b24SSimon Glass printf ("Revision Code %02X %02X\n", data[91], data[92]); 1603*2e192b24SSimon Glass printf ("Manufacturing Date %02X %02X\n", data[93], data[94]); 1604*2e192b24SSimon Glass puts ("Assembly Serial Number "); 1605*2e192b24SSimon Glass for (j = 95; j <= 98; j++) 1606*2e192b24SSimon Glass printf ("%02X ", data[j]); 1607*2e192b24SSimon Glass putc ('\n'); 1608*2e192b24SSimon Glass 1609*2e192b24SSimon Glass if (DDR2 != type) { 1610*2e192b24SSimon Glass printf ("Speed rating PC%d\n", 1611*2e192b24SSimon Glass data[126] == 0x66 ? 66 : data[126]); 1612*2e192b24SSimon Glass } 1613*2e192b24SSimon Glass return 0; 1614*2e192b24SSimon Glass } 1615*2e192b24SSimon Glass #endif 1616*2e192b24SSimon Glass 1617*2e192b24SSimon Glass /* 1618*2e192b24SSimon Glass * Syntax: 1619*2e192b24SSimon Glass * i2c edid {i2c_chip} 1620*2e192b24SSimon Glass */ 1621*2e192b24SSimon Glass #if defined(CONFIG_I2C_EDID) 1622*2e192b24SSimon Glass int do_edid(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[]) 1623*2e192b24SSimon Glass { 1624*2e192b24SSimon Glass uint chip; 1625*2e192b24SSimon Glass struct edid1_info edid; 1626*2e192b24SSimon Glass int ret; 1627*2e192b24SSimon Glass #ifdef CONFIG_DM_I2C 1628*2e192b24SSimon Glass struct udevice *dev; 1629*2e192b24SSimon Glass #endif 1630*2e192b24SSimon Glass 1631*2e192b24SSimon Glass if (argc < 2) { 1632*2e192b24SSimon Glass cmd_usage(cmdtp); 1633*2e192b24SSimon Glass return 1; 1634*2e192b24SSimon Glass } 1635*2e192b24SSimon Glass 1636*2e192b24SSimon Glass chip = simple_strtoul(argv[1], NULL, 16); 1637*2e192b24SSimon Glass #ifdef CONFIG_DM_I2C 1638*2e192b24SSimon Glass ret = i2c_get_cur_bus_chip(chip, &dev); 1639*2e192b24SSimon Glass if (!ret) 1640*2e192b24SSimon Glass ret = dm_i2c_read(dev, 0, (uchar *)&edid, sizeof(edid)); 1641*2e192b24SSimon Glass #else 1642*2e192b24SSimon Glass ret = i2c_read(chip, 0, 1, (uchar *)&edid, sizeof(edid)); 1643*2e192b24SSimon Glass #endif 1644*2e192b24SSimon Glass if (ret) 1645*2e192b24SSimon Glass return i2c_report_err(ret, I2C_ERR_READ); 1646*2e192b24SSimon Glass 1647*2e192b24SSimon Glass if (edid_check_info(&edid)) { 1648*2e192b24SSimon Glass puts("Content isn't valid EDID.\n"); 1649*2e192b24SSimon Glass return 1; 1650*2e192b24SSimon Glass } 1651*2e192b24SSimon Glass 1652*2e192b24SSimon Glass edid_print_info(&edid); 1653*2e192b24SSimon Glass return 0; 1654*2e192b24SSimon Glass 1655*2e192b24SSimon Glass } 1656*2e192b24SSimon Glass #endif /* CONFIG_I2C_EDID */ 1657*2e192b24SSimon Glass 1658*2e192b24SSimon Glass #ifdef CONFIG_DM_I2C 1659*2e192b24SSimon Glass static void show_bus(struct udevice *bus) 1660*2e192b24SSimon Glass { 1661*2e192b24SSimon Glass struct udevice *dev; 1662*2e192b24SSimon Glass 1663*2e192b24SSimon Glass printf("Bus %d:\t%s", bus->req_seq, bus->name); 1664*2e192b24SSimon Glass if (device_active(bus)) 1665*2e192b24SSimon Glass printf(" (active %d)", bus->seq); 1666*2e192b24SSimon Glass printf("\n"); 1667*2e192b24SSimon Glass for (device_find_first_child(bus, &dev); 1668*2e192b24SSimon Glass dev; 1669*2e192b24SSimon Glass device_find_next_child(&dev)) { 1670*2e192b24SSimon Glass struct dm_i2c_chip *chip = dev_get_parent_platdata(dev); 1671*2e192b24SSimon Glass 1672*2e192b24SSimon Glass printf(" %02x: %s, offset len %x, flags %x\n", 1673*2e192b24SSimon Glass chip->chip_addr, dev->name, chip->offset_len, 1674*2e192b24SSimon Glass chip->flags); 1675*2e192b24SSimon Glass } 1676*2e192b24SSimon Glass } 1677*2e192b24SSimon Glass #endif 1678*2e192b24SSimon Glass 1679*2e192b24SSimon Glass /** 1680*2e192b24SSimon Glass * do_i2c_show_bus() - Handle the "i2c bus" command-line command 1681*2e192b24SSimon Glass * @cmdtp: Command data struct pointer 1682*2e192b24SSimon Glass * @flag: Command flag 1683*2e192b24SSimon Glass * @argc: Command-line argument count 1684*2e192b24SSimon Glass * @argv: Array of command-line arguments 1685*2e192b24SSimon Glass * 1686*2e192b24SSimon Glass * Returns zero always. 1687*2e192b24SSimon Glass */ 1688*2e192b24SSimon Glass #if defined(CONFIG_SYS_I2C) || defined(CONFIG_DM_I2C) 1689*2e192b24SSimon Glass static int do_i2c_show_bus(cmd_tbl_t *cmdtp, int flag, int argc, 1690*2e192b24SSimon Glass char * const argv[]) 1691*2e192b24SSimon Glass { 1692*2e192b24SSimon Glass if (argc == 1) { 1693*2e192b24SSimon Glass /* show all busses */ 1694*2e192b24SSimon Glass #ifdef CONFIG_DM_I2C 1695*2e192b24SSimon Glass struct udevice *bus; 1696*2e192b24SSimon Glass struct uclass *uc; 1697*2e192b24SSimon Glass int ret; 1698*2e192b24SSimon Glass 1699*2e192b24SSimon Glass ret = uclass_get(UCLASS_I2C, &uc); 1700*2e192b24SSimon Glass if (ret) 1701*2e192b24SSimon Glass return CMD_RET_FAILURE; 1702*2e192b24SSimon Glass uclass_foreach_dev(bus, uc) 1703*2e192b24SSimon Glass show_bus(bus); 1704*2e192b24SSimon Glass #else 1705*2e192b24SSimon Glass int i; 1706*2e192b24SSimon Glass 1707*2e192b24SSimon Glass for (i = 0; i < CONFIG_SYS_NUM_I2C_BUSES; i++) { 1708*2e192b24SSimon Glass printf("Bus %d:\t%s", i, I2C_ADAP_NR(i)->name); 1709*2e192b24SSimon Glass #ifndef CONFIG_SYS_I2C_DIRECT_BUS 1710*2e192b24SSimon Glass int j; 1711*2e192b24SSimon Glass 1712*2e192b24SSimon Glass for (j = 0; j < CONFIG_SYS_I2C_MAX_HOPS; j++) { 1713*2e192b24SSimon Glass if (i2c_bus[i].next_hop[j].chip == 0) 1714*2e192b24SSimon Glass break; 1715*2e192b24SSimon Glass printf("->%s@0x%2x:%d", 1716*2e192b24SSimon Glass i2c_bus[i].next_hop[j].mux.name, 1717*2e192b24SSimon Glass i2c_bus[i].next_hop[j].chip, 1718*2e192b24SSimon Glass i2c_bus[i].next_hop[j].channel); 1719*2e192b24SSimon Glass } 1720*2e192b24SSimon Glass #endif 1721*2e192b24SSimon Glass printf("\n"); 1722*2e192b24SSimon Glass } 1723*2e192b24SSimon Glass #endif 1724*2e192b24SSimon Glass } else { 1725*2e192b24SSimon Glass int i; 1726*2e192b24SSimon Glass 1727*2e192b24SSimon Glass /* show specific bus */ 1728*2e192b24SSimon Glass i = simple_strtoul(argv[1], NULL, 10); 1729*2e192b24SSimon Glass #ifdef CONFIG_DM_I2C 1730*2e192b24SSimon Glass struct udevice *bus; 1731*2e192b24SSimon Glass int ret; 1732*2e192b24SSimon Glass 1733*2e192b24SSimon Glass ret = uclass_get_device_by_seq(UCLASS_I2C, i, &bus); 1734*2e192b24SSimon Glass if (ret) { 1735*2e192b24SSimon Glass printf("Invalid bus %d: err=%d\n", i, ret); 1736*2e192b24SSimon Glass return CMD_RET_FAILURE; 1737*2e192b24SSimon Glass } 1738*2e192b24SSimon Glass show_bus(bus); 1739*2e192b24SSimon Glass #else 1740*2e192b24SSimon Glass if (i >= CONFIG_SYS_NUM_I2C_BUSES) { 1741*2e192b24SSimon Glass printf("Invalid bus %d\n", i); 1742*2e192b24SSimon Glass return -1; 1743*2e192b24SSimon Glass } 1744*2e192b24SSimon Glass printf("Bus %d:\t%s", i, I2C_ADAP_NR(i)->name); 1745*2e192b24SSimon Glass #ifndef CONFIG_SYS_I2C_DIRECT_BUS 1746*2e192b24SSimon Glass int j; 1747*2e192b24SSimon Glass for (j = 0; j < CONFIG_SYS_I2C_MAX_HOPS; j++) { 1748*2e192b24SSimon Glass if (i2c_bus[i].next_hop[j].chip == 0) 1749*2e192b24SSimon Glass break; 1750*2e192b24SSimon Glass printf("->%s@0x%2x:%d", 1751*2e192b24SSimon Glass i2c_bus[i].next_hop[j].mux.name, 1752*2e192b24SSimon Glass i2c_bus[i].next_hop[j].chip, 1753*2e192b24SSimon Glass i2c_bus[i].next_hop[j].channel); 1754*2e192b24SSimon Glass } 1755*2e192b24SSimon Glass #endif 1756*2e192b24SSimon Glass printf("\n"); 1757*2e192b24SSimon Glass #endif 1758*2e192b24SSimon Glass } 1759*2e192b24SSimon Glass 1760*2e192b24SSimon Glass return 0; 1761*2e192b24SSimon Glass } 1762*2e192b24SSimon Glass #endif 1763*2e192b24SSimon Glass 1764*2e192b24SSimon Glass /** 1765*2e192b24SSimon Glass * do_i2c_bus_num() - Handle the "i2c dev" command-line command 1766*2e192b24SSimon Glass * @cmdtp: Command data struct pointer 1767*2e192b24SSimon Glass * @flag: Command flag 1768*2e192b24SSimon Glass * @argc: Command-line argument count 1769*2e192b24SSimon Glass * @argv: Array of command-line arguments 1770*2e192b24SSimon Glass * 1771*2e192b24SSimon Glass * Returns zero on success, CMD_RET_USAGE in case of misuse and negative 1772*2e192b24SSimon Glass * on error. 1773*2e192b24SSimon Glass */ 1774*2e192b24SSimon Glass #if defined(CONFIG_SYS_I2C) || defined(CONFIG_I2C_MULTI_BUS) || \ 1775*2e192b24SSimon Glass defined(CONFIG_DM_I2C) 1776*2e192b24SSimon Glass static int do_i2c_bus_num(cmd_tbl_t *cmdtp, int flag, int argc, 1777*2e192b24SSimon Glass char * const argv[]) 1778*2e192b24SSimon Glass { 1779*2e192b24SSimon Glass int ret = 0; 1780*2e192b24SSimon Glass int bus_no; 1781*2e192b24SSimon Glass 1782*2e192b24SSimon Glass if (argc == 1) { 1783*2e192b24SSimon Glass /* querying current setting */ 1784*2e192b24SSimon Glass #ifdef CONFIG_DM_I2C 1785*2e192b24SSimon Glass struct udevice *bus; 1786*2e192b24SSimon Glass 1787*2e192b24SSimon Glass if (!i2c_get_cur_bus(&bus)) 1788*2e192b24SSimon Glass bus_no = bus->seq; 1789*2e192b24SSimon Glass else 1790*2e192b24SSimon Glass bus_no = -1; 1791*2e192b24SSimon Glass #else 1792*2e192b24SSimon Glass bus_no = i2c_get_bus_num(); 1793*2e192b24SSimon Glass #endif 1794*2e192b24SSimon Glass printf("Current bus is %d\n", bus_no); 1795*2e192b24SSimon Glass } else { 1796*2e192b24SSimon Glass bus_no = simple_strtoul(argv[1], NULL, 10); 1797*2e192b24SSimon Glass #if defined(CONFIG_SYS_I2C) 1798*2e192b24SSimon Glass if (bus_no >= CONFIG_SYS_NUM_I2C_BUSES) { 1799*2e192b24SSimon Glass printf("Invalid bus %d\n", bus_no); 1800*2e192b24SSimon Glass return -1; 1801*2e192b24SSimon Glass } 1802*2e192b24SSimon Glass #endif 1803*2e192b24SSimon Glass printf("Setting bus to %d\n", bus_no); 1804*2e192b24SSimon Glass #ifdef CONFIG_DM_I2C 1805*2e192b24SSimon Glass ret = cmd_i2c_set_bus_num(bus_no); 1806*2e192b24SSimon Glass #else 1807*2e192b24SSimon Glass ret = i2c_set_bus_num(bus_no); 1808*2e192b24SSimon Glass #endif 1809*2e192b24SSimon Glass if (ret) 1810*2e192b24SSimon Glass printf("Failure changing bus number (%d)\n", ret); 1811*2e192b24SSimon Glass } 1812*2e192b24SSimon Glass 1813*2e192b24SSimon Glass return ret ? CMD_RET_FAILURE : 0; 1814*2e192b24SSimon Glass } 1815*2e192b24SSimon Glass #endif /* defined(CONFIG_SYS_I2C) */ 1816*2e192b24SSimon Glass 1817*2e192b24SSimon Glass /** 1818*2e192b24SSimon Glass * do_i2c_bus_speed() - Handle the "i2c speed" command-line command 1819*2e192b24SSimon Glass * @cmdtp: Command data struct pointer 1820*2e192b24SSimon Glass * @flag: Command flag 1821*2e192b24SSimon Glass * @argc: Command-line argument count 1822*2e192b24SSimon Glass * @argv: Array of command-line arguments 1823*2e192b24SSimon Glass * 1824*2e192b24SSimon Glass * Returns zero on success, CMD_RET_USAGE in case of misuse and negative 1825*2e192b24SSimon Glass * on error. 1826*2e192b24SSimon Glass */ 1827*2e192b24SSimon Glass static int do_i2c_bus_speed(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) 1828*2e192b24SSimon Glass { 1829*2e192b24SSimon Glass int speed, ret=0; 1830*2e192b24SSimon Glass 1831*2e192b24SSimon Glass #ifdef CONFIG_DM_I2C 1832*2e192b24SSimon Glass struct udevice *bus; 1833*2e192b24SSimon Glass 1834*2e192b24SSimon Glass if (i2c_get_cur_bus(&bus)) 1835*2e192b24SSimon Glass return 1; 1836*2e192b24SSimon Glass #endif 1837*2e192b24SSimon Glass if (argc == 1) { 1838*2e192b24SSimon Glass #ifdef CONFIG_DM_I2C 1839*2e192b24SSimon Glass speed = dm_i2c_get_bus_speed(bus); 1840*2e192b24SSimon Glass #else 1841*2e192b24SSimon Glass speed = i2c_get_bus_speed(); 1842*2e192b24SSimon Glass #endif 1843*2e192b24SSimon Glass /* querying current speed */ 1844*2e192b24SSimon Glass printf("Current bus speed=%d\n", speed); 1845*2e192b24SSimon Glass } else { 1846*2e192b24SSimon Glass speed = simple_strtoul(argv[1], NULL, 10); 1847*2e192b24SSimon Glass printf("Setting bus speed to %d Hz\n", speed); 1848*2e192b24SSimon Glass #ifdef CONFIG_DM_I2C 1849*2e192b24SSimon Glass ret = dm_i2c_set_bus_speed(bus, speed); 1850*2e192b24SSimon Glass #else 1851*2e192b24SSimon Glass ret = i2c_set_bus_speed(speed); 1852*2e192b24SSimon Glass #endif 1853*2e192b24SSimon Glass if (ret) 1854*2e192b24SSimon Glass printf("Failure changing bus speed (%d)\n", ret); 1855*2e192b24SSimon Glass } 1856*2e192b24SSimon Glass 1857*2e192b24SSimon Glass return ret ? CMD_RET_FAILURE : 0; 1858*2e192b24SSimon Glass } 1859*2e192b24SSimon Glass 1860*2e192b24SSimon Glass /** 1861*2e192b24SSimon Glass * do_i2c_mm() - Handle the "i2c mm" command-line command 1862*2e192b24SSimon Glass * @cmdtp: Command data struct pointer 1863*2e192b24SSimon Glass * @flag: Command flag 1864*2e192b24SSimon Glass * @argc: Command-line argument count 1865*2e192b24SSimon Glass * @argv: Array of command-line arguments 1866*2e192b24SSimon Glass * 1867*2e192b24SSimon Glass * Returns zero on success, CMD_RET_USAGE in case of misuse and negative 1868*2e192b24SSimon Glass * on error. 1869*2e192b24SSimon Glass */ 1870*2e192b24SSimon Glass static int do_i2c_mm(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) 1871*2e192b24SSimon Glass { 1872*2e192b24SSimon Glass return mod_i2c_mem (cmdtp, 1, flag, argc, argv); 1873*2e192b24SSimon Glass } 1874*2e192b24SSimon Glass 1875*2e192b24SSimon Glass /** 1876*2e192b24SSimon Glass * do_i2c_nm() - Handle the "i2c nm" command-line command 1877*2e192b24SSimon Glass * @cmdtp: Command data struct pointer 1878*2e192b24SSimon Glass * @flag: Command flag 1879*2e192b24SSimon Glass * @argc: Command-line argument count 1880*2e192b24SSimon Glass * @argv: Array of command-line arguments 1881*2e192b24SSimon Glass * 1882*2e192b24SSimon Glass * Returns zero on success, CMD_RET_USAGE in case of misuse and negative 1883*2e192b24SSimon Glass * on error. 1884*2e192b24SSimon Glass */ 1885*2e192b24SSimon Glass static int do_i2c_nm(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) 1886*2e192b24SSimon Glass { 1887*2e192b24SSimon Glass return mod_i2c_mem (cmdtp, 0, flag, argc, argv); 1888*2e192b24SSimon Glass } 1889*2e192b24SSimon Glass 1890*2e192b24SSimon Glass /** 1891*2e192b24SSimon Glass * do_i2c_reset() - Handle the "i2c reset" command-line command 1892*2e192b24SSimon Glass * @cmdtp: Command data struct pointer 1893*2e192b24SSimon Glass * @flag: Command flag 1894*2e192b24SSimon Glass * @argc: Command-line argument count 1895*2e192b24SSimon Glass * @argv: Array of command-line arguments 1896*2e192b24SSimon Glass * 1897*2e192b24SSimon Glass * Returns zero always. 1898*2e192b24SSimon Glass */ 1899*2e192b24SSimon Glass static int do_i2c_reset(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) 1900*2e192b24SSimon Glass { 1901*2e192b24SSimon Glass #if defined(CONFIG_DM_I2C) 1902*2e192b24SSimon Glass struct udevice *bus; 1903*2e192b24SSimon Glass 1904*2e192b24SSimon Glass if (i2c_get_cur_bus(&bus)) 1905*2e192b24SSimon Glass return CMD_RET_FAILURE; 1906*2e192b24SSimon Glass if (i2c_deblock(bus)) { 1907*2e192b24SSimon Glass printf("Error: Not supported by the driver\n"); 1908*2e192b24SSimon Glass return CMD_RET_FAILURE; 1909*2e192b24SSimon Glass } 1910*2e192b24SSimon Glass #elif defined(CONFIG_SYS_I2C) 1911*2e192b24SSimon Glass i2c_init(I2C_ADAP->speed, I2C_ADAP->slaveaddr); 1912*2e192b24SSimon Glass #else 1913*2e192b24SSimon Glass i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); 1914*2e192b24SSimon Glass #endif 1915*2e192b24SSimon Glass return 0; 1916*2e192b24SSimon Glass } 1917*2e192b24SSimon Glass 1918*2e192b24SSimon Glass static cmd_tbl_t cmd_i2c_sub[] = { 1919*2e192b24SSimon Glass #if defined(CONFIG_SYS_I2C) || defined(CONFIG_DM_I2C) 1920*2e192b24SSimon Glass U_BOOT_CMD_MKENT(bus, 1, 1, do_i2c_show_bus, "", ""), 1921*2e192b24SSimon Glass #endif 1922*2e192b24SSimon Glass U_BOOT_CMD_MKENT(crc32, 3, 1, do_i2c_crc, "", ""), 1923*2e192b24SSimon Glass #if defined(CONFIG_SYS_I2C) || \ 1924*2e192b24SSimon Glass defined(CONFIG_I2C_MULTI_BUS) || defined(CONFIG_DM_I2C) 1925*2e192b24SSimon Glass U_BOOT_CMD_MKENT(dev, 1, 1, do_i2c_bus_num, "", ""), 1926*2e192b24SSimon Glass #endif /* CONFIG_I2C_MULTI_BUS */ 1927*2e192b24SSimon Glass #if defined(CONFIG_I2C_EDID) 1928*2e192b24SSimon Glass U_BOOT_CMD_MKENT(edid, 1, 1, do_edid, "", ""), 1929*2e192b24SSimon Glass #endif /* CONFIG_I2C_EDID */ 1930*2e192b24SSimon Glass U_BOOT_CMD_MKENT(loop, 3, 1, do_i2c_loop, "", ""), 1931*2e192b24SSimon Glass U_BOOT_CMD_MKENT(md, 3, 1, do_i2c_md, "", ""), 1932*2e192b24SSimon Glass U_BOOT_CMD_MKENT(mm, 2, 1, do_i2c_mm, "", ""), 1933*2e192b24SSimon Glass U_BOOT_CMD_MKENT(mw, 3, 1, do_i2c_mw, "", ""), 1934*2e192b24SSimon Glass U_BOOT_CMD_MKENT(nm, 2, 1, do_i2c_nm, "", ""), 1935*2e192b24SSimon Glass U_BOOT_CMD_MKENT(probe, 0, 1, do_i2c_probe, "", ""), 1936*2e192b24SSimon Glass U_BOOT_CMD_MKENT(read, 5, 1, do_i2c_read, "", ""), 1937*2e192b24SSimon Glass U_BOOT_CMD_MKENT(write, 6, 0, do_i2c_write, "", ""), 1938*2e192b24SSimon Glass #ifdef CONFIG_DM_I2C 1939*2e192b24SSimon Glass U_BOOT_CMD_MKENT(flags, 2, 1, do_i2c_flags, "", ""), 1940*2e192b24SSimon Glass U_BOOT_CMD_MKENT(olen, 2, 1, do_i2c_olen, "", ""), 1941*2e192b24SSimon Glass #endif 1942*2e192b24SSimon Glass U_BOOT_CMD_MKENT(reset, 0, 1, do_i2c_reset, "", ""), 1943*2e192b24SSimon Glass #if defined(CONFIG_CMD_SDRAM) 1944*2e192b24SSimon Glass U_BOOT_CMD_MKENT(sdram, 1, 1, do_sdram, "", ""), 1945*2e192b24SSimon Glass #endif 1946*2e192b24SSimon Glass U_BOOT_CMD_MKENT(speed, 1, 1, do_i2c_bus_speed, "", ""), 1947*2e192b24SSimon Glass }; 1948*2e192b24SSimon Glass 1949*2e192b24SSimon Glass static __maybe_unused void i2c_reloc(void) 1950*2e192b24SSimon Glass { 1951*2e192b24SSimon Glass static int relocated; 1952*2e192b24SSimon Glass 1953*2e192b24SSimon Glass if (!relocated) { 1954*2e192b24SSimon Glass fixup_cmdtable(cmd_i2c_sub, ARRAY_SIZE(cmd_i2c_sub)); 1955*2e192b24SSimon Glass relocated = 1; 1956*2e192b24SSimon Glass }; 1957*2e192b24SSimon Glass } 1958*2e192b24SSimon Glass 1959*2e192b24SSimon Glass /** 1960*2e192b24SSimon Glass * do_i2c() - Handle the "i2c" command-line command 1961*2e192b24SSimon Glass * @cmdtp: Command data struct pointer 1962*2e192b24SSimon Glass * @flag: Command flag 1963*2e192b24SSimon Glass * @argc: Command-line argument count 1964*2e192b24SSimon Glass * @argv: Array of command-line arguments 1965*2e192b24SSimon Glass * 1966*2e192b24SSimon Glass * Returns zero on success, CMD_RET_USAGE in case of misuse and negative 1967*2e192b24SSimon Glass * on error. 1968*2e192b24SSimon Glass */ 1969*2e192b24SSimon Glass static int do_i2c(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[]) 1970*2e192b24SSimon Glass { 1971*2e192b24SSimon Glass cmd_tbl_t *c; 1972*2e192b24SSimon Glass 1973*2e192b24SSimon Glass #ifdef CONFIG_NEEDS_MANUAL_RELOC 1974*2e192b24SSimon Glass i2c_reloc(); 1975*2e192b24SSimon Glass #endif 1976*2e192b24SSimon Glass 1977*2e192b24SSimon Glass if (argc < 2) 1978*2e192b24SSimon Glass return CMD_RET_USAGE; 1979*2e192b24SSimon Glass 1980*2e192b24SSimon Glass /* Strip off leading 'i2c' command argument */ 1981*2e192b24SSimon Glass argc--; 1982*2e192b24SSimon Glass argv++; 1983*2e192b24SSimon Glass 1984*2e192b24SSimon Glass c = find_cmd_tbl(argv[0], &cmd_i2c_sub[0], ARRAY_SIZE(cmd_i2c_sub)); 1985*2e192b24SSimon Glass 1986*2e192b24SSimon Glass if (c) 1987*2e192b24SSimon Glass return c->cmd(cmdtp, flag, argc, argv); 1988*2e192b24SSimon Glass else 1989*2e192b24SSimon Glass return CMD_RET_USAGE; 1990*2e192b24SSimon Glass } 1991*2e192b24SSimon Glass 1992*2e192b24SSimon Glass /***************************************************/ 1993*2e192b24SSimon Glass #ifdef CONFIG_SYS_LONGHELP 1994*2e192b24SSimon Glass static char i2c_help_text[] = 1995*2e192b24SSimon Glass #if defined(CONFIG_SYS_I2C) || defined(CONFIG_DM_I2C) 1996*2e192b24SSimon Glass "bus [muxtype:muxaddr:muxchannel] - show I2C bus info\n" 1997*2e192b24SSimon Glass #endif 1998*2e192b24SSimon Glass "crc32 chip address[.0, .1, .2] count - compute CRC32 checksum\n" 1999*2e192b24SSimon Glass #if defined(CONFIG_SYS_I2C) || \ 2000*2e192b24SSimon Glass defined(CONFIG_I2C_MULTI_BUS) || defined(CONFIG_DM_I2C) 2001*2e192b24SSimon Glass "i2c dev [dev] - show or set current I2C bus\n" 2002*2e192b24SSimon Glass #endif /* CONFIG_I2C_MULTI_BUS */ 2003*2e192b24SSimon Glass #if defined(CONFIG_I2C_EDID) 2004*2e192b24SSimon Glass "i2c edid chip - print EDID configuration information\n" 2005*2e192b24SSimon Glass #endif /* CONFIG_I2C_EDID */ 2006*2e192b24SSimon Glass "i2c loop chip address[.0, .1, .2] [# of objects] - looping read of device\n" 2007*2e192b24SSimon Glass "i2c md chip address[.0, .1, .2] [# of objects] - read from I2C device\n" 2008*2e192b24SSimon Glass "i2c mm chip address[.0, .1, .2] - write to I2C device (auto-incrementing)\n" 2009*2e192b24SSimon Glass "i2c mw chip address[.0, .1, .2] value [count] - write to I2C device (fill)\n" 2010*2e192b24SSimon Glass "i2c nm chip address[.0, .1, .2] - write to I2C device (constant address)\n" 2011*2e192b24SSimon Glass "i2c probe [address] - test for and show device(s) on the I2C bus\n" 2012*2e192b24SSimon Glass "i2c read chip address[.0, .1, .2] length memaddress - read to memory\n" 2013*2e192b24SSimon Glass "i2c write memaddress chip address[.0, .1, .2] length [-s] - write memory\n" 2014*2e192b24SSimon Glass " to I2C; the -s option selects bulk write in a single transaction\n" 2015*2e192b24SSimon Glass #ifdef CONFIG_DM_I2C 2016*2e192b24SSimon Glass "i2c flags chip [flags] - set or get chip flags\n" 2017*2e192b24SSimon Glass "i2c olen chip [offset_length] - set or get chip offset length\n" 2018*2e192b24SSimon Glass #endif 2019*2e192b24SSimon Glass "i2c reset - re-init the I2C Controller\n" 2020*2e192b24SSimon Glass #if defined(CONFIG_CMD_SDRAM) 2021*2e192b24SSimon Glass "i2c sdram chip - print SDRAM configuration information\n" 2022*2e192b24SSimon Glass #endif 2023*2e192b24SSimon Glass "i2c speed [speed] - show or set I2C bus speed"; 2024*2e192b24SSimon Glass #endif 2025*2e192b24SSimon Glass 2026*2e192b24SSimon Glass U_BOOT_CMD( 2027*2e192b24SSimon Glass i2c, 7, 1, do_i2c, 2028*2e192b24SSimon Glass "I2C sub-system", 2029*2e192b24SSimon Glass i2c_help_text 2030*2e192b24SSimon Glass ); 2031