int wbsio_check_for_spi(void) { if (0 == (wbsio_spibase = wbsio_get_spibase(WBSIO_PORT1))) if (0 == (wbsio_spibase = wbsio_get_spibase(WBSIO_PORT2))) return 1; msg_pspew("\nwbsio_spibase = 0x%x\n", wbsio_spibase); register_spi_programmer(&spi_programmer_wbsio); msg_pdbg("%s: Winbond saved on 4 register bits so max chip size is " "1024 kB!\n", __func__); max_rom_decode.spi = 1024 * 1024; return 0; }
int it85xx_spi_init(struct superio s) { int ret; if (!(buses_supported & CHIP_BUSTYPE_FWH)) { msg_pdbg("%s():%d buses not support FWH\n", __func__, __LINE__); return 1; } ret = it85xx_spi_common_init(s); msg_pdbg("FWH: %s():%d ret=%d\n", __func__, __LINE__, ret); if (!ret) { msg_pdbg("%s():%d buses_supported=0x%x\n", __func__, __LINE__, buses_supported); if (buses_supported & CHIP_BUSTYPE_FWH) msg_pdbg("Overriding chipset SPI with IT85 FWH|SPI.\n"); /* Really leave FWH enabled? */ /* Set this as spi controller. */ register_spi_programmer(&spi_programmer_it85xx); } return ret; }
int linux_spi_init(void) { char *p, *endp, *dev; uint32_t speed = 0; /* FIXME: make the following configurable by CLI options. */ /* SPI mode 0 (beware this also includes: MSB first, CS active low and others */ const uint8_t mode = SPI_MODE_0; const uint8_t bits = 8; dev = extract_programmer_param("dev"); if (!dev || !strlen(dev)) { msg_perr("No SPI device given. Use flashrom -p " "linux_spi:dev=/dev/spidevX.Y\n"); return 1; } p = extract_programmer_param("speed"); if (p && strlen(p)) { speed = (uint32_t)strtoul(p, &endp, 10) * 1024; if (p == endp) { msg_perr("%s: invalid clock: %s kHz\n", __func__, p); return 1; } } msg_pdbg("Using device %s\n", dev); if ((fd = open(dev, O_RDWR)) == -1) { msg_perr("%s: failed to open %s: %s\n", __func__, dev, strerror(errno)); return 1; } if (register_shutdown(linux_spi_shutdown, NULL)) return 1; /* We rely on the shutdown function for cleanup from here on. */ if (speed > 0) { if (ioctl(fd, SPI_IOC_WR_MAX_SPEED_HZ, &speed) == -1) { msg_perr("%s: failed to set speed to %d Hz: %s\n", __func__, speed, strerror(errno)); return 1; } msg_pdbg("Using %d kHz clock\n", speed); } if (ioctl(fd, SPI_IOC_WR_MODE, &mode) == -1) { msg_perr("%s: failed to set SPI mode to 0x%02x: %s\n", __func__, mode, strerror(errno)); return 1; } if (ioctl(fd, SPI_IOC_WR_BITS_PER_WORD, &bits) == -1) { msg_perr("%s: failed to set the number of bits per SPI word to %u: %s\n", __func__, bits == 0 ? 8 : bits, strerror(errno)); return 1; } register_spi_programmer(&spi_programmer_linux); return 0; }
static uint16_t it87spi_probe(uint16_t port) { uint8_t tmp = 0; char *portpos = NULL; uint16_t flashport = 0; enter_conf_mode_ite(port); /* NOLDN, reg 0x24, mask out lowest bit (suspend) */ tmp = sio_read(port, 0x24) & 0xFE; /* If IT87SPI was not explicitly selected, we want to check * quickly if LPC->SPI translation is active. */ if ((programmer == PROGRAMMER_INTERNAL) && !(tmp & (0x0E))) { msg_pdbg("No IT87* serial flash segment enabled.\n"); exit_conf_mode_ite(port); /* Nothing to do. */ return 0; } msg_pdbg("Serial flash segment 0x%08x-0x%08x %sabled\n", 0xFFFE0000, 0xFFFFFFFF, (tmp & 1 << 1) ? "en" : "dis"); msg_pdbg("Serial flash segment 0x%08x-0x%08x %sabled\n", 0x000E0000, 0x000FFFFF, (tmp & 1 << 1) ? "en" : "dis"); msg_pdbg("Serial flash segment 0x%08x-0x%08x %sabled\n", 0xFFEE0000, 0xFFEFFFFF, (tmp & 1 << 2) ? "en" : "dis"); msg_pdbg("Serial flash segment 0x%08x-0x%08x %sabled\n", 0xFFF80000, 0xFFFEFFFF, (tmp & 1 << 3) ? "en" : "dis"); msg_pdbg("LPC write to serial flash %sabled\n", (tmp & 1 << 4) ? "en" : "dis"); /* The LPC->SPI force write enable below only makes sense for * non-programmer mode. */ /* If any serial flash segment is enabled, enable writing. */ if ((tmp & 0xe) && (!(tmp & 1 << 4))) { msg_pdbg("Enabling LPC write to serial flash\n"); tmp |= 1 << 4; sio_write(port, 0x24, tmp); } msg_pdbg("Serial flash pin %i\n", (tmp & 1 << 5) ? 87 : 29); /* LDN 0x7, reg 0x64/0x65 */ sio_write(port, 0x07, 0x7); flashport = sio_read(port, 0x64) << 8; flashport |= sio_read(port, 0x65); msg_pdbg("Serial flash port 0x%04x\n", flashport); /* Non-default port requested? */ portpos = extract_programmer_param("it87spiport"); if (portpos) { char *endptr = NULL; unsigned long forced_flashport; forced_flashport = strtoul(portpos, &endptr, 0); /* Port 0, port >0x1000, unaligned ports and garbage strings * are rejected. */ if (!forced_flashport || (forced_flashport >= 0x1000) || (forced_flashport & 0x7) || (*endptr != '\0')) { /* Using ports below 0x100 is a really bad idea, and * should only be done if no port between 0x100 and * 0xff8 works due to routing issues. */ msg_perr("Error: it87spiport specified, but no valid " "port specified.\nPort must be a multiple of " "0x8 and lie between 0x100 and 0xff8.\n"); free(portpos); return 1; } else { flashport = (uint16_t)forced_flashport; msg_pinfo("Forcing serial flash port 0x%04x\n", flashport); sio_write(port, 0x64, (flashport >> 8)); sio_write(port, 0x65, (flashport & 0xff)); } } free(portpos); exit_conf_mode_ite(port); it8716f_flashport = flashport; if (buses_supported & CHIP_BUSTYPE_SPI) msg_pdbg("Overriding chipset SPI with IT87 SPI.\n"); /* FIXME: Add the SPI bus or replace the other buses with it? */ register_spi_programmer(&spi_programmer_it87xx); return 0; }