mtd: st_spi_fsm: Add support for JEDEC ID extraction
authorLee Jones <lee.jones@linaro.org>
Thu, 20 Mar 2014 09:20:38 +0000 (09:20 +0000)
committerBrian Norris <computersforpeace@gmail.com>
Thu, 20 Mar 2014 11:17:15 +0000 (04:17 -0700)
Once we start supporting devices it will be handy go detect them
dynamically. This will be done using the chip's unique JEDEC ID. This
patch allows us to extract a device's JEDEC ID using the a predefined
FSM register write sequence.

Acked-by Angus Clark <angus.clark@st.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
drivers/mtd/devices/st_spi_fsm.c

index 73e0f2731bcbaf87d9808b3fa22824de4ce8966d..9fc0b1911fe1d4cc874c891b30b7733b2747dcc1 100644 (file)
@@ -219,6 +219,22 @@ struct stfsm_seq {
        uint32_t seq_cfg;
 } __packed __aligned(4);
 
+static struct stfsm_seq stfsm_seq_read_jedec = {
+       .data_size = TRANSFER_SIZE(8),
+       .seq_opc[0] = (SEQ_OPC_PADS_1 |
+                      SEQ_OPC_CYCLES(8) |
+                      SEQ_OPC_OPCODE(FLASH_CMD_RDID)),
+       .seq = {
+               STFSM_INST_CMD1,
+               STFSM_INST_DATA_READ,
+               STFSM_INST_STOP,
+       },
+       .seq_cfg = (SEQ_CFG_PADS_1 |
+                   SEQ_CFG_READNOTWRITE |
+                   SEQ_CFG_CSDEASSERT |
+                   SEQ_CFG_STARTSEQ),
+};
+
 static inline int stfsm_is_idle(struct stfsm *fsm)
 {
        return readl(fsm->base + SPI_FAST_SEQ_STA) & 0x10;
@@ -307,6 +323,42 @@ static void stfsm_read_fifo(struct stfsm *fsm, uint32_t *buf,
        }
 }
 
+static void stfsm_read_jedec(struct stfsm *fsm, uint8_t *const jedec)
+{
+       const struct stfsm_seq *seq = &stfsm_seq_read_jedec;
+       uint32_t tmp[2];
+
+       stfsm_load_seq(fsm, seq);
+
+       stfsm_read_fifo(fsm, tmp, 8);
+
+       memcpy(jedec, tmp, 5);
+
+       stfsm_wait_seq(fsm);
+}
+
+static struct flash_info *stfsm_jedec_probe(struct stfsm *fsm)
+{
+       u16                     ext_jedec;
+       u32                     jedec;
+       u8                      id[5];
+
+       stfsm_read_jedec(fsm, id);
+
+       jedec     = id[0] << 16 | id[1] << 8 | id[2];
+       /*
+        * JEDEC also defines an optional "extended device information"
+        * string for after vendor-specific data, after the three bytes
+        * we use here. Supporting some chips might require using it.
+        */
+       ext_jedec = id[3] << 8  | id[4];
+
+       dev_dbg(fsm->dev, "JEDEC =  0x%08x [%02x %02x %02x %02x %02x]\n",
+               jedec, id[0], id[1], id[2], id[3], id[4]);
+
+       return NULL;
+}
+
 static int stfsm_set_mode(struct stfsm *fsm, uint32_t mode)
 {
        int ret, timeout = 10;
@@ -436,6 +488,9 @@ static int stfsm_probe(struct platform_device *pdev)
                return ret;
        }
 
+       /* Detect SPI FLASH device */
+       stfsm_jedec_probe(fsm);
+
        fsm->mtd.dev.parent     = &pdev->dev;
        fsm->mtd.type           = MTD_NORFLASH;
        fsm->mtd.writesize      = 4;