spi: Use bus probing for REMS, RES and AT25F
Change-Id: Ic5d2a5283c5fb5e52c58c0b5937922371f56249f
Signed-off-by: Nico Huber <nico.h@gmx.de>
Reviewed-on: https://review.sourcearcade.org/c/flashprog/+/417
diff --git a/spi25.c b/spi25.c
index b22c8a8..d1ce38e 100644
--- a/spi25.c
+++ b/spi25.c
@@ -46,25 +46,25 @@
return 0;
}
-static int spi_rems(struct flashctx *flash, unsigned char *readarr)
+static int spi_rems(const struct spi_master *spi, unsigned char *readarr)
{
static const unsigned char cmd[JEDEC_REMS_OUTSIZE] = { JEDEC_REMS, };
int ret;
- ret = spi_send_command(flash, sizeof(cmd), JEDEC_REMS_INSIZE, cmd, readarr);
+ ret = spi->command(spi, sizeof(cmd), JEDEC_REMS_INSIZE, cmd, readarr);
if (ret)
return ret;
msg_cspew("REMS returned 0x%02x 0x%02x. ", readarr[0], readarr[1]);
return 0;
}
-static int spi_res(struct flashctx *flash, unsigned char *readarr, int bytes)
+static int spi_res(const struct spi_master *spi, unsigned char *readarr, int bytes)
{
static const unsigned char cmd[JEDEC_RES_OUTSIZE] = { JEDEC_RES, };
int ret;
int i;
- ret = spi_send_command(flash, sizeof(cmd), bytes, cmd, readarr);
+ ret = spi->command(spi, sizeof(cmd), bytes, cmd, readarr);
if (ret)
return ret;
msg_cspew("RES returned");
@@ -147,136 +147,114 @@
return found;
}
-int probe_spi_rems(struct flashctx *flash)
+struct found_id *probe_spi_rems(const struct bus_probe *probe, const struct master_common *mst)
{
- const struct flashchip *chip = flash->chip;
+ const struct spi_master *const spi = (const struct spi_master *)mst;
unsigned char readarr[JEDEC_REMS_INSIZE];
- uint32_t id1, id2;
- if (spi_rems(flash, readarr)) {
- return 0;
+ if (spi_rems(spi, readarr) || flashprog_no_data(readarr, sizeof(readarr))) {
+ return NULL;
}
- id1 = readarr[0];
- id2 = readarr[1];
+ struct found_id *const found = calloc(1, sizeof(*found));
+ if (!found) {
+ msg_cerr("Out of memory!\n");
+ return NULL;
+ }
- msg_cdbg("%s: id1 0x%x, id2 0x%x\n", __func__, id1, id2);
+ struct id_info *const id = &found->info.id;
- if (id1 == chip->id.manufacture && id2 == chip->id.model)
- return 1;
+ id->manufacture = readarr[0];
+ id->model = readarr[1];
+ id->type = ID_SPI_REMS;
- /* Test if this is a pure vendor match. */
- if (id1 == chip->id.manufacture && GENERIC_DEVICE_ID == chip->id.model)
- return 1;
+ msg_cdbg("%s: id1 0x%02x, id2 0x%02x\n", __func__, id->id1, id->id2);
- /* Test if there is any vendor ID. */
- if (GENERIC_MANUF_ID == chip->id.manufacture && id1 != 0xff && id1 != 0x00)
- return 1;
-
- return 0;
+ return found;
}
-int probe_spi_res1(struct flashctx *flash)
+struct found_id *probe_spi_res(const struct bus_probe *probe, const struct master_common *mst)
{
- static const unsigned char allff[] = {0xff, 0xff, 0xff};
- static const unsigned char all00[] = {0x00, 0x00, 0x00};
+ const struct spi_master *const spi = (const struct spi_master *)mst;
+ const unsigned int res_len = probe->type == ID_SPI_RES3 ? 3 :
+ (probe->type == ID_SPI_RES2 ? 2 : 1);
unsigned char readarr[3];
- uint32_t id2;
- /* We only want one-byte RES if RDID and REMS are unusable. */
+ if (res_len == 1) {
+ /* We only want one-byte RES if RDID and REMS are unusable. */
- /* Check if RDID is usable and does not return 0xff 0xff 0xff or
- * 0x00 0x00 0x00. In that case, RES is pointless.
- */
- if (!spi_rdid(flash->mst.spi, readarr, 3) && memcmp(readarr, allff, 3) &&
- memcmp(readarr, all00, 3)) {
- msg_cdbg("Ignoring RES in favour of RDID.\n");
- return 0;
- }
- /* Check if REMS is usable and does not return 0xff 0xff or
- * 0x00 0x00. In that case, RES is pointless.
- */
- if (!spi_rems(flash, readarr) &&
- memcmp(readarr, allff, JEDEC_REMS_INSIZE) &&
- memcmp(readarr, all00, JEDEC_REMS_INSIZE)) {
- msg_cdbg("Ignoring RES in favour of REMS.\n");
- return 0;
+ if (!spi_rdid(spi, readarr, 3) && !flashprog_no_data(readarr, 3)) {
+ msg_cdbg("Ignoring RES in favour of RDID.\n");
+ return NULL;
+ }
+
+ if (!spi_rems(spi, readarr) && !flashprog_no_data(readarr, JEDEC_REMS_INSIZE)) {
+ msg_cdbg("Ignoring RES in favour of REMS.\n");
+ return NULL;
+ }
}
- if (spi_res(flash, readarr, 1)) {
- return 0;
+ if (spi_res(spi, readarr, res_len) || flashprog_no_data(readarr, res_len)) {
+ return NULL;
}
- id2 = readarr[0];
-
- msg_cdbg("%s: id 0x%x\n", __func__, id2);
-
- if (id2 != flash->chip->id.model)
- return 0;
-
- return 1;
-}
-
-int probe_spi_res2(struct flashctx *flash)
-{
- unsigned char readarr[2];
- uint32_t id1, id2;
-
- if (spi_res(flash, readarr, 2)) {
- return 0;
+ struct found_id *const found = calloc(1, sizeof(*found));
+ if (!found) {
+ msg_cerr("Out of memory!\n");
+ return NULL;
}
- id1 = readarr[0];
- id2 = readarr[1];
+ struct id_info *const id = &found->info.id;
- msg_cdbg("%s: id1 0x%x, id2 0x%x\n", __func__, id1, id2);
-
- if (id1 != flash->chip->id.manufacture || id2 != flash->chip->id.model)
- return 0;
-
- return 1;
-}
-
-int probe_spi_res3(struct flashctx *flash)
-{
- unsigned char readarr[3];
- uint32_t id1, id2;
-
- if (spi_res(flash, readarr, 3)) {
- return 0;
+ switch (res_len) {
+ case 1:
+ id->manufacture = 0;
+ id->model = readarr[0];
+ msg_cdbg("%s: id 0x%02x\n", __func__, id->model);
+ break;
+ case 2:
+ id->manufacture = readarr[0];
+ id->model = readarr[1];
+ msg_cdbg("%s: id1 0x%02x, id2 0x%02x\n", __func__, id->id1, id->id2);
+ break;
+ case 3:
+ id->manufacture = (readarr[0] << 8) | readarr[1];
+ id->model = readarr[2];
+ msg_cdbg("%s: id1 0x%04x, id2 0x%02x\n", __func__, id->id1, id->id2);
+ break;
}
+ id->type = probe->type;
- id1 = (readarr[0] << 8) | readarr[1];
- id2 = readarr[2];
-
- msg_cdbg("%s: id1 0x%x, id2 0x%x\n", __func__, id1, id2);
-
- if (id1 != flash->chip->id.manufacture || id2 != flash->chip->id.model)
- return 0;
-
- return 1;
+ return found;
}
/* Only used for some Atmel chips. */
-int probe_spi_at25f(struct flashctx *flash)
+struct found_id *probe_spi_at25f(const struct bus_probe *probe, const struct master_common *mst)
{
static const unsigned char cmd[AT25F_RDID_OUTSIZE] = { AT25F_RDID };
+ const struct spi_master *const spi = (const struct spi_master *)mst;
unsigned char readarr[AT25F_RDID_INSIZE];
- uint32_t id1;
- uint32_t id2;
- if (spi_send_command(flash, sizeof(cmd), sizeof(readarr), cmd, readarr))
- return 0;
+ if (spi->command(spi, sizeof(cmd), sizeof(readarr), cmd, readarr))
+ return NULL;
+ if (flashprog_no_data(readarr, sizeof(readarr)))
+ return NULL;
- id1 = readarr[0];
- id2 = readarr[1];
+ struct found_id *const found = calloc(1, sizeof(*found));
+ if (!found) {
+ msg_cerr("Out of memory!\n");
+ return NULL;
+ }
- msg_cdbg("%s: id1 0x%02x, id2 0x%02x\n", __func__, id1, id2);
+ struct id_info *const id = &found->info.id;
- if (id1 == flash->chip->id.manufacture && id2 == flash->chip->id.model)
- return 1;
+ id->manufacture = readarr[0];
+ id->model = readarr[1];
+ id->type = ID_SPI_AT25F;
- return 0;
+ msg_cdbg("%s: id1 0x%02x, id2 0x%02x\n", __func__, id->id1, id->id2);
+
+ return found;
}
static int spi_poll_wip(struct flashctx *const flash, const unsigned int poll_delay)