static int cmd_ec_console(int argc, const char **argv) { char data[128]; int rv; if (!get_ec()) return -ENODEV; /* Snapshot the EC console */ rv = flash_cmd(ec, EC_CMD_CONSOLE_SNAPSHOT, 0, NULL, 0, NULL, 0); if (rv < 0) return rv; /* Loop and read from the snapshot until it's done */ while (1) { memset(data, 0, sizeof(data)); rv = flash_cmd(ec, EC_CMD_CONSOLE_READ, 0, NULL, 0, data, sizeof(data)); if (rv) return rv; /* Empty response means done */ if (!data[0]) break; /* Make sure output is null-terminated, then dump it */ data[sizeof(data) - 1] = '\0'; fputs(data, stdout); } printf("\n"); return 0; }
static int cmd_ec_usbpdpower(int argc, const char **argv) { struct ec_params_usb_pd_power_info p; struct ec_response_usb_pd_power_info r; struct ec_response_usb_pd_ports rp; int i, rv; if (!get_ec()) return -ENODEV; rv = flash_cmd(ec, EC_CMD_USB_PD_PORTS, 0, NULL, 0, &rp, sizeof(rp)); if (rv) return rv; for (i = 0; i < rp.num_ports; i++) { p.port = i; rv = flash_cmd(ec, EC_CMD_USB_PD_POWER_INFO, 0, &p, sizeof(p), &r, sizeof(r)); if (rv) return rv; printf("Port %d: ", i); print_pd_power_info(&r); } return 0; }
static int bq27742_read(int reg, int size, int *value) { int rv; struct ec_response_i2c_read r; struct ec_params_i2c_read p = { .port = 0, .read_size = size, .addr = BQ27742_ADDR, .offset = reg }; rv = flash_cmd(ec, EC_CMD_I2C_READ, 0, &p, sizeof(p), &r, sizeof(r)); if (rv < 0) { *value = -1; return rv; } *value = r.data; return 0; } static int bq27742_write(int reg, int size, int value) { int rv; struct ec_params_i2c_write p = { .port = 0, .write_size = size, .addr = BQ27742_ADDR, .offset = reg, .data = value }; rv = flash_cmd(ec, EC_CMD_I2C_WRITE, 0, &p, sizeof(p), NULL, 0); return rv < 0 ? rv : 0; } static int cmd_ec_bq27742(int argc, const char **argv) { int i; int value; int rv; int chg_mv, chg_ma; if (!get_ec()) return -ENODEV; /* Get chip ID in Control subcommand DEVICE_TYPE (0x1) */ bq27742_write(BQ27742_REG_CTRL, 16, 0x1); bq27742_read(BQ27742_REG_CTRL, 16, &value); printf("ID: BQ27%3x\n", value); bq27742_read(BQ27742_REG_CHARGING_MV, 16, &chg_mv); bq27742_read(BQ27742_REG_CHARGING_MA, 16, &chg_ma); printf("Requested charge: %d mV %d mA\n", chg_mv, chg_ma); bq27742_read(BQ27742_REG_FLAGS, 16, &value); printf("Flags: %04x\n", value); bq27742_read(BQ27742_REG_PROTECTOR, 8, &value); printf("ProtectorState: %02x\n", value); return 0; }
int error_code(short errno) { pulse_flash_cs(); flash_cmd(PAGE_TO_BUFFER_XFER,0,0,0); pulse_flash_cs(); flash_cmd(BUFFER_WRITE, 0,0,8); flash_spi(errno & 0xff); flash_spi((errno >> 8) & 0xff); return 1; }
/********************************************************************* * @fn flash_page_program * * @brief program flash, limit inside 1 page * * @param address: where to start write data * p: data in array * cnt: number of byte want to write * * @return none: */ void flash_page_program(unsigned long address, unsigned char* p, unsigned int cnt) { unsigned char temp; flash_WIP_poll(); flash_cmd(WRITE_ENABLE, 0); flash_cmd(PAGE_PROGRAM, address); do { temp = spi_rw(*p++); } while (--cnt); DESELECT(); }
static int cmd_ec_gpioset(int argc, const char **argv) { struct ec_params_gpio_set p; char *e; int rv; if (!get_ec()) return -ENODEV; if (argc != 3) { fprintf(stderr, "Usage: %s <GPIO name> <0 | 1>\n", argv[0]); return -1; } if (strlen(argv[1]) + 1 > sizeof(p.name)) { fprintf(stderr, "GPIO name too long.\n"); return -1; } strcpy(p.name, argv[1]); p.val = strtol(argv[2], &e, 0); if (e && *e) { fprintf(stderr, "Bad value.\n"); return -1; } rv = flash_cmd(ec, EC_CMD_GPIO_SET, 0, &p, sizeof(p), NULL, 0); if (rv < 0) return rv; printf("GPIO %s set to %d\n", p.name, p.val); return 0; }
/********************************************************************* * @fn flash_read * * @brief read flash data * * @param address: where to start read data out * p: where to save read data * cnt: number of byte want to read * * @return none: */ void flash_read(unsigned long address, unsigned char* p, unsigned int cnt) { flash_WIP_poll(); flash_cmd(READ_DATA, address); do { *p++ = spi_rw(0xFF); } while (--cnt); DESELECT(); }
/********************************************************************* * @fn flash_WIP_poll * * @brief check and wait until write process is done * * @param none * * @return none */ void flash_WIP_poll(void) { unsigned char stat; flash_cmd(READ_STAT, 0); do { stat = spi_rw(0xFF); } while ((stat & 0x01) || stat == 0xFF); DESELECT(); }
/********************************************************************* * @fn flash_read_id * * @brief read device ID * * @param p: buffer to read device id out * * @return none: */ void flash_read_id(unsigned char *p) { unsigned char cnt = 4; flash_WIP_poll(); flash_cmd(READ_ID, 0); do { *p++ = spi_rw(0xFF); } while (--cnt); DESELECT(); }
/********************************************************************* * @fn flash_read_stat * * @brief read flash status register * * @param none * * @return stat value */ unsigned char flash_read_stat(void) { unsigned char rcv; flash_cmd(READ_STAT, 0); rcv = spi_rw(0xFF); DESELECT(); return rcv; }
static int ec_readmem(int offset, int bytes, void *dest) { struct ec_params_read_memmap r_mem; int r; r_mem.offset = offset; r_mem.size = bytes; return flash_cmd(ec, EC_CMD_READ_MEMMAP, 0, &r_mem, sizeof(r_mem), dest, bytes); }
static int lb_do_cmd(enum lightbar_command cmd, struct ec_params_lightbar *in, struct ec_response_lightbar *out) { int rv; in->cmd = cmd; rv = flash_cmd(ec, EC_CMD_LIGHTBAR_CMD, 0, in, 120, out, 120); return (rv < 0 ? rv : 0); }
int flash_id_read(uint8_t *id) { int ret; flash_spi_select(); ret = flash_cmd(FLASH_RDID); if (ret == 0) { ret = flash_spi_receive(id, 3); } flash_spi_unselect(); return ret; }
int flash_chip_erase(void) { int ret; flash_write_enable(); flash_spi_select(); ret = flash_cmd(FLASH_BE); flash_spi_unselect(); if (ret == 0) { ret = flash_wait_until_done(FLASH_CHIP_ERASE_TIMEOUT_MS); } flash_write_disable(); return ret; }
static int cmd_ec_version(int argc, const char **argv) { static const char * const image_names[] = {"unknown", "RO", "RW"}; struct ec_response_get_version r; char build_string[128]; int rv; if (!get_ec()) return -ENODEV; rv = flash_cmd(ec, EC_CMD_GET_VERSION, 0, NULL, 0, &r, sizeof(r)); if (rv < 0) { fprintf(stderr, "ERROR: EC_CMD_GET_VERSION failed: %d\n", rv); return rv; } rv = flash_cmd(ec, EC_CMD_GET_BUILD_INFO, 0, NULL, 0, build_string, sizeof(build_string)); if (rv < 0) { fprintf(stderr, "ERROR: EC_CMD_GET_BUILD_INFO failed: %d\n", rv); return rv; } /* Ensure versions are null-terminated before we print them */ r.version_string_ro[sizeof(r.version_string_ro) - 1] = '\0'; r.version_string_rw[sizeof(r.version_string_rw) - 1] = '\0'; build_string[sizeof(build_string) - 1] = '\0'; /* Print versions */ printf("RO version: %s\n", r.version_string_ro); printf("RW version: %s\n", r.version_string_rw); printf("Firmware copy: %s\n", (r.current_image < ARRAY_SIZE(image_names) ? image_names[r.current_image] : "?")); printf("Build info: %s\n", build_string); return 0; }
static int flash_cmd_w_addr(uint8_t cmd, uint32_t addr) { if (addr >= (1<<24)) { return -1; } uint8_t buf[4] = {cmd, (addr>>16) & 0xff, (addr>>8) & 0xff, addr & 0xff}; return flash_spi_send(buf, sizeof(buf)); } static void flash_write_enable(void) { flash_spi_select(); flash_cmd(FLASH_WREN); flash_spi_unselect(); }
// read the parameters from the flash; right now just reads the length of the // program. int read_params() { int i; int retval; flash_cmd(ARRAY_READ, 0,0, 4); /* flash_spi(ARRAY_READ); flash_spi(0); flash_spi(0); flash_spi(4);*/ for (i=0; i < 4; i++) { flash_spi(0); } retval = flash_spi(0) & 0xff; retval += (flash_spi(0) << 8); return retval; }
char program_enable() { int ntries, end,i; unsigned char foo; unsigned char resp[6]; #ifdef FULLPC __sda_string_[0] = 0; __mosi_string_[0] = 0; #endif MAKE_BIG_GUY_RESET_OUTPUT(); CLR_SCK_PIN(); CLR_BIG_GUY_RESET_PIN(); wait(); wait(); i = 0; pulse_flash_cs(); for (end=0; end < 5000; end++) { wait(); } for(end = 0, ntries = 32; (end == 0) && (ntries >0); ntries--) { bg_spi(0xac); bg_spi(0x53); foo = bg_spi(0x00); if (foo == 0x53) { end = 1; } else { CLR_SCK_PIN(); wait(); wait(); SET_SCK_PIN(); wait(); wait(); } bg_spi(0x00); if (i <6) resp[i++] = foo; } if (end == 0) { flash_cmd(BUFFER_WRITE, 0,0,10); for (i=0; i < 6; i++) flash_spi(resp[i]); pulse_flash_cs(); wait_ms(20); return 0; } printf("%s\n", __mosi_string_); printf("%s\n", __sda_string_); return 1; }
static int cmd_ec_chargecontrol(int argc, const char **argv) { struct ec_params_charge_control p; int rv; if (argc != 2) { fprintf(stderr, "Usage: %s <normal | idle | discharge>\n", argv[0]); return -EINVAL; } if (!strcasecmp(argv[1], "normal")) { p.mode = CHARGE_CONTROL_NORMAL; } else if (!strcasecmp(argv[1], "idle")) { p.mode = CHARGE_CONTROL_IDLE; } else if (!strcasecmp(argv[1], "discharge")) { p.mode = CHARGE_CONTROL_DISCHARGE; } else { fprintf(stderr, "Bad value.\n"); return -EINVAL; } if (!get_ec()) return -ENODEV; rv = flash_cmd(ec, EC_CMD_CHARGE_CONTROL, 1, &p, sizeof(p), NULL, 0); if (rv < 0) { fprintf(stderr, "Is AC connected?\n"); return rv; } switch (p.mode) { case CHARGE_CONTROL_NORMAL: printf("Charge state machine normal mode.\n"); break; case CHARGE_CONTROL_IDLE: printf("Charge state machine force idle.\n"); break; case CHARGE_CONTROL_DISCHARGE: printf("Charge state machine force discharge.\n"); break; default: break; } return 0; }
static int bq25892_read(int reg, int *value) { int rv; struct ec_response_i2c_read r; struct ec_params_i2c_read p = { .port = 0, .read_size = 8, .addr = BQ2589X_ADDR, .offset = reg }; rv = flash_cmd(ec, EC_CMD_I2C_READ, 0, &p, sizeof(p), &r, sizeof(r)); if (rv < 0) { *value = -1; return rv; } *value = r.data; return 0; } static int bq25892_write(int reg, int value) { int rv; struct ec_params_i2c_write p = { .port = 0, .write_size = 8, .addr = BQ2589X_ADDR, .offset = reg, .data = value }; rv = flash_cmd(ec, EC_CMD_I2C_WRITE, 0, &p, sizeof(p), NULL, 0); return rv < 0 ? rv : 0; } static int cmd_ec_bq25892(int argc, const char **argv) { int i; int value; int rv; int batt_mv, sys_mv, vbus_mv, chg_ma, input_ma; if (!get_ec()) return -ENODEV; /* Trigger one ADC conversion */ bq25892_read(BQ2589X_REG_CFG1, &value); bq25892_write(BQ2589X_REG_CFG1, value | BQ2589X_CFG1_CONV_START); do { rv = bq25892_read(BQ2589X_REG_CFG1, &value); } while ((value & BQ2589X_CFG1_CONV_START) || (rv < 0)); bq25892_read(BQ2589X_REG_ADC_BATT_VOLT, &batt_mv); bq25892_read(BQ2589X_REG_ADC_SYS_VOLT, &sys_mv); bq25892_read(BQ2589X_REG_ADC_VBUS_VOLT, &vbus_mv); bq25892_read(BQ2589X_REG_ADC_CHG_CURR, &chg_ma); bq25892_read(BQ2589X_REG_ADC_INPUT_CURR, &input_ma); printf("ADC Batt %dmV Sys %dmV VBUS %dmV Chg %dmA Input %dmA\n", 2304 + (batt_mv & 0x7f) * 20, 2304 + sys_mv * 20, 2600 + (vbus_mv & 0x7f) * 100, chg_ma * 50, 100 + (input_ma & 0x3f) * 50); printf("REG:"); for (i = 0; i <= 0x14; ++i) printf(" %02x", i); printf("\n"); printf("VAL:"); for (i = 0; i <= 0x14; ++i) { rv = bq25892_read(i, &value); if (rv) return rv; printf(" %02x", value); } printf("\n"); return 0; }
static int cmd_ec_echash(int argc, const char **argv) { struct ec_params_vboot_hash p; struct ec_response_vboot_hash r; char *e; int rv; if (!get_ec()) return -ENODEV; if (argc < 2) { /* Get hash status */ p.cmd = EC_VBOOT_HASH_GET; rv = flash_cmd(ec, EC_CMD_VBOOT_HASH, 0, &p, sizeof(p), &r, sizeof(r)); if (rv < 0) return rv; return ec_hash_print(&r); } if (argc == 2 && !strcasecmp(argv[1], "abort")) { /* Abort hash calculation */ p.cmd = EC_VBOOT_HASH_ABORT; rv = flash_cmd(ec, EC_CMD_VBOOT_HASH, 0, &p, sizeof(p), &r, sizeof(r)); return (rv < 0 ? rv : 0); } /* The only other commands are start and recalc */ if (!strcasecmp(argv[1], "start")) p.cmd = EC_VBOOT_HASH_START; else if (!strcasecmp(argv[1], "recalc")) p.cmd = EC_VBOOT_HASH_RECALC; else return -EINVAL; p.hash_type = EC_VBOOT_HASH_TYPE_SHA256; if (argc < 3) { fprintf(stderr, "Must specify offset\n"); return -1; } if (!strcasecmp(argv[2], "ro")) { p.offset = EC_VBOOT_HASH_OFFSET_RO; p.size = 0; printf("Hashing EC-RO...\n"); } else if (!strcasecmp(argv[2], "rw")) { p.offset = EC_VBOOT_HASH_OFFSET_RW; p.size = 0; printf("Hashing EC-RW...\n"); } else if (argc < 4) { fprintf(stderr, "Must specify size\n"); return -1; } else { p.offset = strtol(argv[2], &e, 0); if (e && *e) { fprintf(stderr, "Bad offset.\n"); return -1; } p.size = strtol(argv[3], &e, 0); if (e && *e) { fprintf(stderr, "Bad size.\n"); return -1; } printf("Hashing %d bytes at offset %d...\n", p.size, p.offset); } if (argc == 5) { /* * Technically nonce can be any binary data up to 64 bytes, * but this command only supports a 32-bit value. */ uint32_t nonce = strtol(argv[4], &e, 0); if (e && *e) { fprintf(stderr, "Bad nonce integer.\n"); return -1; } memcpy(p.nonce_data, &nonce, sizeof(nonce)); p.nonce_size = sizeof(nonce); } else p.nonce_size = 0; rv = flash_cmd(ec, EC_CMD_VBOOT_HASH, 0, &p, sizeof(p), &r, sizeof(r)); if (rv < 0) return rv; /* Start command doesn't wait for hashing to finish */ if (p.cmd == EC_VBOOT_HASH_START) return 0; /* Recalc command does wait around, so a result is ready now */ return ec_hash_print(&r); }
/********************************************************************* * @fn flash_sector_erase * * @brief erase one sector data - 4KB * * @param address: sector address to be earsed * * @return none: */ void flash_sector_erase(unsigned long address) { flash_WIP_poll(); flash_cmd(WRITE_ENABLE, 0); flash_cmd(SECTOR_ERASE, address); }
/* TODO: 2x16 unsupported */ int flash_erase (flash_info_t *info, int s_first, int s_last) { volatile unsigned char *addr = (uchar *)(info->start[0]); int flag, prot, sect, l_sect; ulong start, now, last; /* TODO: 2x16 unsupported */ if(info->portwidth==4) return 1; if((info->flash_id & FLASH_TYPEMASK) == FLASH_ROM) return 1; if((info->flash_id & FLASH_TYPEMASK) == FLASH_RAM) { for (sect = s_first; sect<=s_last; sect++) { int sector_size=info->size/info->sector_count; addr = (uchar *)(info->start[sect]); memset((void *)addr, 0, sector_size); } return 0; } if ((s_first < 0) || (s_first > s_last)) { if (info->flash_id == FLASH_UNKNOWN) { printf ("- missing\n"); } else { printf ("- no sectors to erase\n"); } return 1; } if ((info->flash_id&FLASH_VENDMASK) == FLASH_MAN_INTEL) { return flash_erase_intel(info, (unsigned short)s_first, (unsigned short)s_last); } #if 0 if ((info->flash_id == FLASH_UNKNOWN) || (info->flash_id > FLASH_AMD_COMP)) { printf ("Can't erase unknown flash type %08lx - aborted\n", info->flash_id); return 1; } #endif prot = 0; for (sect=s_first; sect<=s_last; ++sect) { if (info->protect[sect]) { prot++; } } if (prot) { printf ("- Warning: %d protected sectors will not be erased!\n", prot); } else { printf ("\n"); } l_sect = -1; /* Disable interrupts which might cause a timeout here */ flag = disable_interrupts(); flash_cmd(info->portwidth,addr,0x555,0xAA); flash_cmd(info->portwidth,addr,0x2AA,0x55); flash_cmd(info->portwidth,addr,0x555,0x80); flash_cmd(info->portwidth,addr,0x555,0xAA); flash_cmd(info->portwidth,addr,0x2AA,0x55); /* Start erase on unprotected sectors */ for (sect = s_first; sect<=s_last; sect++) { if (info->protect[sect] == 0) { /* not protected */ addr = (uchar *)(info->start[sect]); flash_cmd(info->portwidth,addr,0,0x30); l_sect = sect; } } /* re-enable interrupts if necessary */ if (flag) enable_interrupts(); /* wait at least 80us - let's wait 1 ms */ udelay (1000); /* * We wait for the last triggered sector */ if (l_sect < 0) goto DONE; start = get_timer (0); last = start; addr = (volatile unsigned char *)(info->start[l_sect]); /* broken for 2x16: TODO */ while ((addr[0] & 0x80) != 0x80) { if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) { printf ("Timeout\n"); return 1; } /* show that we're waiting */ if ((now - last) > 1000) { /* every second */ putc ('.'); last = now; } } DONE: /* reset to read mode */ addr = (volatile unsigned char *)info->start[0]; flash_cmd(info->portwidth,addr,0,0xf0); flash_cmd(info->portwidth,addr,0,0xf0); printf (" done\n"); return 0; }
static int cmd_ec_gpioget(int argc, const char **argv) { struct ec_params_gpio_get_v1 p_v1; struct ec_response_gpio_get_v1 r_v1; int i, rv, subcmd, num_gpios; if (!get_ec()) return -ENODEV; if (argc > 2) { printf("Usage: %s [<subcmd> <GPIO name>]\n", argv[0]); printf("'gpioget <GPIO_NAME>' - Get value by name\n"); printf("'gpioget count' - Get count of GPIOS\n"); printf("'gpioget all' - Get info for all GPIOs\n"); return -1; } /* Keeping it consistent with console command behavior */ if (argc == 1) subcmd = EC_GPIO_GET_INFO; else if (!strcmp(argv[1], "count")) subcmd = EC_GPIO_GET_COUNT; else if (!strcmp(argv[1], "all")) subcmd = EC_GPIO_GET_INFO; else subcmd = EC_GPIO_GET_BY_NAME; if (subcmd == EC_GPIO_GET_BY_NAME) { p_v1.subcmd = EC_GPIO_GET_BY_NAME; if (strlen(argv[1]) + 1 > sizeof(p_v1.get_value_by_name.name)) { fprintf(stderr, "GPIO name too long.\n"); return -1; } strcpy(p_v1.get_value_by_name.name, argv[1]); rv = flash_cmd(ec, EC_CMD_GPIO_GET, 1, &p_v1, sizeof(p_v1), &r_v1, sizeof(r_v1)); if (rv < 0) return rv; printf("GPIO %s = %d\n", p_v1.get_value_by_name.name, r_v1.get_value_by_name.val); return 0; } /* Need GPIO count for EC_GPIO_GET_COUNT or EC_GPIO_GET_INFO */ p_v1.subcmd = EC_GPIO_GET_COUNT; rv = flash_cmd(ec, EC_CMD_GPIO_GET, 1, &p_v1, sizeof(p_v1), &r_v1, sizeof(r_v1)); if (rv < 0) return rv; if (subcmd == EC_GPIO_GET_COUNT) { printf("GPIO COUNT = %d\n", r_v1.get_count.val); return 0; } /* subcmd EC_GPIO_GET_INFO */ num_gpios = r_v1.get_count.val; p_v1.subcmd = EC_GPIO_GET_INFO; for (i = 0; i < num_gpios; i++) { p_v1.get_info.index = i; rv = flash_cmd(ec, EC_CMD_GPIO_GET, 1, &p_v1, sizeof(p_v1), &r_v1, sizeof(r_v1)); if (rv < 0) return rv; printf("%2d %-32s 0x%04X\n", r_v1.get_info.val, r_v1.get_info.name, r_v1.get_info.flags); } return 0; }
/********************************************************************* * @fn flash_erase * * @brief erase entire flash * * @param none * * @return none: */ void flash_erase() { flash_WIP_poll(); flash_cmd(WRITE_ENABLE, 0); flash_cmd(CHIP_ERASE, 0); }
static ulong flash_get_size (int portwidth, vu_long *addr, flash_info_t *info) { short i; volatile unsigned char *caddr = (unsigned char *)addr; volatile unsigned short *saddr = (unsigned short *)addr; volatile unsigned long *laddr = (unsigned long *)addr; char old[2], save; ulong id, manu, base = (ulong)addr; info->portwidth=portwidth; save = *caddr; flash_cmd(portwidth,caddr,0,0xf0); flash_cmd(portwidth,caddr,0,0xf0); udelay(10); old[0] = caddr[0]; old[1] = caddr[1]; if(old[0]!=0xf0) { flash_cmd(portwidth,caddr,0,0xf0); flash_cmd(portwidth,caddr,0,0xf0); udelay(10); if(*caddr==0xf0) { /* this area is ROM */ *caddr=save; #ifndef FLASH_ID_OVERRIDE info->flash_id = FLASH_ROM + FLASH_MAN_UNKNOWN; info->sector_count = 8; info->size = 0x80000; #else info->flash_id = FLASH_MAN_AMD + FLASH_AM040; info->sector_count = 8; info->size = 0x80000; info->chipwidth=1; #endif flash_get_offsets(base, info); return info->size; } } else { *caddr=0; udelay(10); if(*caddr==0) { /* this area is RAM */ *caddr=save; info->flash_id = FLASH_RAM + FLASH_MAN_UNKNOWN; info->sector_count = 8; info->size = 0x80000; flash_get_offsets(base, info); return info->size; } flash_cmd(portwidth,caddr,0,0xf0); udelay(10); } /* Write auto select command: read Manufacturer ID */ flash_cmd(portwidth,caddr,0x555,0xAA); flash_cmd(portwidth,caddr,0x2AA,0x55); flash_cmd(portwidth,caddr,0x555,0x90); udelay(10); if ((caddr[0] == old[0]) && (caddr[1] == old[1])) { /* this area is ROM */ #ifndef FLASH_ID_OVERRIDE info->flash_id = FLASH_ROM + FLASH_MAN_UNKNOWN; info->sector_count = 8; info->size = 0x80000; #else info->flash_id = FLASH_MAN_AMD + FLASH_AM040; info->sector_count = 8; info->size = 0x80000; info->chipwidth=1; #endif flash_get_offsets(base, info); return info->size; #ifdef DEBUG } else { printf("%px%d: %02x:%02x -> %02x:%02x\n", caddr, portwidth, old[0], old[1], caddr[0], caddr[1]); #endif } switch(portwidth) { case 1: manu = caddr[0]; manu |= manu<<16; id = caddr[1]; break; case 2: manu = saddr[0]; manu |= manu<<16; id = saddr[1]; id |= id<<16; break; case 4: manu = laddr[0]; id = laddr[1]; break; default: id = manu = -1; break; } #ifdef DEBUG printf("\n%08lx:%08lx:%08lx\n", base, manu, id); printf("%08lx %08lx %08lx %08lx\n", laddr[0],laddr[1],laddr[2],laddr[3]); #endif switch (manu) { case AMD_MANUFACT: info->flash_id = FLASH_MAN_AMD; break; case FUJ_MANUFACT: info->flash_id = FLASH_MAN_FUJ; break; case INTEL_MANUFACT: info->flash_id = FLASH_MAN_INTEL; break; default: printf("Unknown Mfr [%08lx]:%08lx\n", manu, id); info->flash_id = FLASH_UNKNOWN; info->sector_count = 0; info->size = 0; return (0); /* no or unknown flash */ } switch (id) { case AMD_ID_LV400T: info->flash_id += FLASH_AM400T; info->sector_count = 11; info->size = 0x00100000; info->chipwidth=1; break; /* => 1 MB */ case AMD_ID_LV400B: info->flash_id += FLASH_AM400B; info->sector_count = 11; info->size = 0x00100000; info->chipwidth=1; break; /* => 1 MB */ case AMD_ID_LV800T: info->flash_id += FLASH_AM800T; info->sector_count = 19; info->size = 0x00200000; info->chipwidth=1; break; /* => 2 MB */ case AMD_ID_LV800B: info->flash_id += FLASH_AM800B; info->sector_count = 19; info->size = 0x00200000; info->chipwidth=1; break; /* => 2 MB */ case AMD_ID_LV160T: info->flash_id += FLASH_AM160T; info->sector_count = 35; info->size = 0x00400000; info->chipwidth=1; break; /* => 4 MB */ case AMD_ID_LV160B: info->flash_id += FLASH_AM160B; info->sector_count = 35; info->size = 0x00400000; info->chipwidth=1; break; /* => 4 MB */ #if 0 /* enable when device IDs are available */ case AMD_ID_LV320T: info->flash_id += FLASH_AM320T; info->sector_count = 67; info->size = 0x00800000; break; /* => 8 MB */ case AMD_ID_LV320B: info->flash_id += FLASH_AM320B; info->sector_count = 67; info->size = 0x00800000; break; /* => 8 MB */ #endif case AMD_ID_LV040B: info->flash_id += FLASH_AM040; info->sector_count = 8; info->size = 0x80000; info->chipwidth=1; break; case INTEL_ID_28F640J3A: info->flash_id += FLASH_28F640J3A; info->sector_count = 64; info->size = 128*1024 * 64; /* 128kbytes x 64 blocks */ info->chipwidth=2; if(portwidth==4) info->size*=2; /* 2x16 */ break; case INTEL_ID_28F128J3A: info->flash_id += FLASH_28F128J3A; info->sector_count = 128; info->size = 128*1024 * 128; /* 128kbytes x 128 blocks */ info->chipwidth=2; if(portwidth==4) info->size*=2; /* 2x16 */ break; default: printf("Unknown id %lx:[%lx]\n", manu, id); info->flash_id = FLASH_UNKNOWN; info->chipwidth=1; return (0); /* => no or unknown flash */ } flash_get_offsets(base, info); #if 0 /* set up sector start address table */ if (info->flash_id & FLASH_AM040) { /* this chip has uniformly spaced sectors */ for (i = 0; i < info->sector_count; i++) info->start[i] = base + (i * 0x00010000); } else if (info->flash_id & FLASH_BTYPE) { /* set sector offsets for bottom boot block type */ info->start[0] = base + 0x00000000; info->start[1] = base + 0x00008000; info->start[2] = base + 0x0000C000; info->start[3] = base + 0x00010000; for (i = 4; i < info->sector_count; i++) { info->start[i] = base + (i * 0x00020000) - 0x00060000; } } else { /* set sector offsets for top boot block type */ i = info->sector_count - 1; info->start[i--] = base + info->size - 0x00008000; info->start[i--] = base + info->size - 0x0000C000; info->start[i--] = base + info->size - 0x00010000; for (; i >= 0; i--) { info->start[i] = base + i * 0x00020000; } } #endif /* check for protected sectors */ for (i = 0; i < info->sector_count; i++) { /* read sector protection at sector address, (A7 .. A0)=0x02 */ /* D0 = 1 if protected */ caddr = (volatile unsigned char *)(info->start[i]); saddr = (volatile unsigned short *)(info->start[i]); laddr = (volatile unsigned long *)(info->start[i]); if(portwidth==1) info->protect[i] = caddr[2] & 1; else if(portwidth==2) info->protect[i] = saddr[2] & 1; else info->protect[i] = laddr[2] & 1; } /* * Prevent writes to uninitialized FLASH. */ if (info->flash_id != FLASH_UNKNOWN) { caddr = (volatile unsigned char *)info->start[0]; flash_cmd(portwidth,caddr,0,0xF0); /* reset bank */ } return (info->size); }
static int pi3usb9281_read(int reg, int *value) { int rv; struct ec_response_i2c_read r; struct ec_params_i2c_read p = { .port = 0, .read_size = 8, .addr = PI3USB9281_ADDR, .offset = reg }; rv = flash_cmd(ec, EC_CMD_I2C_READ, 0, &p, sizeof(p), &r, sizeof(r)); if (rv < 0) { *value = -1; return rv; } *value = r.data; return 0; } static int cmd_ec_pi3usb9281(int argc, const char **argv) { unsigned i; int value; int rv; int dev_type, chg_stat, vbus; char *apple_chg = "", *proprio_chg = ""; if (!get_ec()) return -ENODEV; pi3usb9281_read(PI3USB9281_REG_DEV_TYPE, &dev_type); pi3usb9281_read(PI3USB9281_REG_CHG_STATUS, &chg_stat); pi3usb9281_read(PI3USB9281_REG_VBUS, &vbus); switch((chg_stat>>2)&7) { case 4: apple_chg = "Apple 2.4A"; break; case 2: apple_chg = "Apple 2A"; break; case 1: apple_chg = "Apple 1A"; break; } switch(chg_stat&3) { case 3: proprio_chg = "type-2"; break; case 2: proprio_chg = "type-1"; break; case 1: proprio_chg = "rsvd"; break; } printf("USB: %s%s%s%s%s%s Charger: %s%s VBUS: %d\n", dev_type & (1<<6) ? "DCP" : " ", dev_type & (1<<5) ? "CDP" : " ", dev_type & (1<<4) ? "CarKit" : " ", dev_type & (1<<2) ? "SDP" : " ", dev_type & (1<<1) ? "OTG" : " ", dev_type & (1<<0) ? "MHL" : " ", apple_chg, proprio_chg, !!(vbus & 2)); printf("REG:"); for (i = 0; i < PI3USB9281_COUNT; ++i) printf(" %02x", pi3usb9281_regs[i]); printf("\n"); printf("VAL:"); for (i = 0; i < PI3USB9281_COUNT; ++i) { rv = pi3usb9281_read(pi3usb9281_regs[i], &value); if (rv) return rv; printf(" %02x", value); } printf("\n"); return 0; }
int main(int argc, char **argv) { int status; int nrx_fd; int host_rfd; int host_wfd; int use_stdin = 0; char * ser_dev = NULL; int port = 12345; char * filename = default_filename; void * handle = NULL; int host_flash = 0; int input_baudrate = 115200; speed_t baudrate = B115200; int opt; struct ifreq ifr; struct nanoioctl nr; while((opt = getopt(argc, argv, "d:s:p:f:b:i")) != -1) { switch(opt) { case 'b': input_baudrate = atoi(optarg); switch(input_baudrate) { case 9600: baudrate = B9600; break; case 19200: baudrate = B19200; break; case 38400: baudrate = B38400; break; case 57600: baudrate = B57600; break; case 115200: baudrate = B115200; break; default: usage(); } break; case 'd': debug = atoi(optarg); break; case 'f': filename = optarg; break; case 'i': use_stdin = 1; break; case 'p': port = atoi(optarg); break; case 's': ser_dev = optarg; break; default: break; } } if(optind == argc) usage(); strcpy(ifr.ifr_name, argv[optind]); ifr.ifr_data = (char *)&nr; memset(&nr,0,sizeof(nr)); nr.magic = NR_MAGIC; APP_INFO("Nanoradio network interface: %s\n", ifr.ifr_name); APP_INFO("Saving persistent MIB data of type HOST to: %s\n", filename); if(use_stdin) { APP_INFO("Using stdin/stdout as client interface\n"); host_wfd = host_rfd = open_terminal(); redirect_stdout("/tmp/hic_proxy.log"); } else if(ser_dev) { APP_INFO("Using %s (baudrate = %d) as serial client interface\n", ser_dev,input_baudrate); host_wfd = host_rfd = open_serial(ser_dev, baudrate); } else { APP_INFO("Using ethernet as client interface\n"); host_wfd = host_rfd = open_socket(port); } nrx_fd = socket(AF_INET, SOCK_DGRAM, 0); if(nrx_fd < 0) err(1, "socket"); for(;;) { status = poll_host(host_rfd, &ifr); if(status) { if((nr.data[TYPE_INDEX] == HIC_MESSAGE_TYPE_FLASH_PRG)) { APP_DEBUG("flash cmd recieved\n"); //examine flash cmd handle = flash_cmd(&ifr,handle,filename); if(handle) { //send local host flash cmd reply host_write(host_wfd, nr.data, nr.length); } else { //forward to target nrx_write(nrx_fd, &ifr); } } else { //forward to target nrx_write(nrx_fd, &ifr); } } status = poll_target(nrx_fd, &ifr); if(status) host_write(host_wfd, nr.data, nr.length); usleep(5000); } if(!use_stdin) { close(host_rfd); } close(nrx_fd); }
static int cmd_ec_usbpd(int argc, const char **argv) { const char *role_str[] = {"", "toggle", "toggle-off", "sink", "source"}; const char *mux_str[] = {"", "none", "usb", "dp", "dock", "auto"}; const char *swap_str[] = {"", "dr_swap", "pr_swap", "vconn_swap"}; struct ec_params_usb_pd_control p; struct ec_response_usb_pd_control_v1 r; int rv, i; unsigned j; int option_ok; char *e; if (!get_ec()) return -ENODEV; p.role = USB_PD_CTRL_ROLE_NO_CHANGE; p.mux = USB_PD_CTRL_MUX_NO_CHANGE; p.swap = USB_PD_CTRL_SWAP_NONE; if (argc < 2) { fprintf(stderr, "No port specified.\n"); return -1; } p.port = strtol(argv[1], &e, 0); if (e && *e) { fprintf(stderr, "Invalid param (port)\n"); return -1; } for (i = 2; i < argc; ++i) { option_ok = 0; if (!strcmp(argv[i], "auto")) { if (argc != 3) { fprintf(stderr, "\"auto\" may not be used " "with other options.\n"); return -1; } p.role = USB_PD_CTRL_ROLE_TOGGLE_ON; p.mux = USB_PD_CTRL_MUX_AUTO; continue; } for (j = 0; j < ARRAY_SIZE(role_str); ++j) { if (!strcmp(argv[i], role_str[j])) { if (p.role != USB_PD_CTRL_ROLE_NO_CHANGE) { fprintf(stderr, "Only one role allowed.\n"); return -1; } p.role = j; option_ok = 1; break; } } if (option_ok) continue; for (j = 0; j < ARRAY_SIZE(mux_str); ++j) { if (!strcmp(argv[i], mux_str[j])) { if (p.mux != USB_PD_CTRL_MUX_NO_CHANGE) { fprintf(stderr, "Only one mux type allowed.\n"); return -1; } p.mux = j; option_ok = 1; break; } } if (option_ok) continue; for (j = 0; j < ARRAY_SIZE(swap_str); ++j) { if (!strcmp(argv[i], swap_str[j])) { if (p.swap != USB_PD_CTRL_SWAP_NONE) { fprintf(stderr, "Only one swap type allowed.\n"); return -1; } p.swap = j; option_ok = 1; break; } } if (!option_ok) { fprintf(stderr, "Unknown option: %s\n", argv[i]); return -1; } } rv = flash_cmd(ec, EC_CMD_USB_PD_CONTROL, 1, &p, sizeof(p), &r, sizeof(r)); if (rv < 0 || argc != 2) return (rv < 0) ? rv : 0; printf("Port C%d is %s,%s, Role:%s %s%s Polarity:CC%d State:%s\n", p.port, (r.enabled & 1) ? "enabled" : "disabled", (r.enabled & 2) ? "connected" : "disconnected", r.role & PD_ROLE_SOURCE ? "SRC" : "SNK", r.role & (PD_ROLE_DFP << 1) ? "DFP" : "UFP", r.role & (1 << 2) ? " VCONN" : "", r.polarity + 1, r.state); return (rv < 0 ? rv : 0); }
static void flash_write_disable(void) { flash_spi_select(); flash_cmd(FLASH_WRDI); flash_spi_unselect(); }