]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
eeprom: at25: add support for Infineon Cypress QSN FRAMs
authorPatrick Wicki <patrick.wicki@siemens.com>
Tue, 20 Jan 2026 13:06:02 +0000 (14:06 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 27 Jan 2026 14:55:45 +0000 (15:55 +0100)
Add support for Infineon Cypress CY15****QSN FRAM chips.
Unlike the QN variants these chips have an 8 byte JEDEC ID.

The layout of the serial number matches that of already supported chips
like the CY15B204QN, so make the read-out unconditional.

Tested with the CY15B204QSN. According to Infineon datasheets, all QSN
variants appear to share a consistent pattern so the size should be
correctly detected based on the density bits in the ID:

CY15B201QSN: 0x00 00 00 00 06 82 54 40, density_id:  8: 1Mb
CY15B102QSN: 0x00 00 00 00 06 82 51 48, density_id:  9: 2Mb
CY15B204QSN: 0x00 00 00 00 06 82 54 50, density_id: 10: 4Mb
CY15V108QSN: 0x00 00 00 00 06 82 52 58, density_id: 11: 8Mb

Signed-off-by: Patrick Wicki <patrick.wicki@siemens.com>
Reviewed-by: Alexander Sverdlin <alexander.sverdlin@siemens.com>
Tested-by: Alexander Sverdlin <alexander.sverdlin@siemens.com>
Link: https://patch.msgid.link/20260120130603.1066559-1-patrick@subset.ch
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/misc/eeprom/at25.c

index 883dfd0ed6583f49c8933d9863b512bcd1798420..5b00921d07d2e1987633550e90faceb25fee236d 100644 (file)
@@ -398,30 +398,40 @@ static int at25_fram_to_chip(struct device *dev, struct spi_eeprom *chip)
                                id[i] = id[j];
                                id[j] = tmp;
                        }
-               if (id[6] != 0xc2) {
-                       dev_err(dev, "Error: no Cypress FRAM with device ID (manufacturer ID bank 7: %02x)\n", id[6]);
-                       return -ENODEV;
-               }
 
-               switch (id[7]) {
-               case 0x21 ... 0x26:
-                       chip->byte_len = BIT(id[7] - 0x21 + 4) * 1024;
-                       break;
-               case 0x2a ... 0x30:
-                       /* CY15B102QN ... CY15B116QN */
-                       chip->byte_len = BIT(((id[7] >> 1) & 0xf) + 13);
-                       break;
-               default:
-                       dev_err(dev, "Error: unsupported size (id %02x)\n", id[7]);
+               if (id[6] == 0xc2) {
+                       switch (id[7]) {
+                       case 0x21 ... 0x26:
+                               chip->byte_len = BIT(id[7] - 0x21 + 4) * 1024;
+                               break;
+                       case 0x2a ... 0x30:
+                               /* CY15B102QN ... CY15B116QN */
+                               chip->byte_len = BIT(((id[7] >> 1) & 0xf) + 13);
+                               break;
+                       default:
+                               dev_err(dev, "Error: unsupported size (id %02x)\n", id[7]);
+                               return -ENODEV;
+                       }
+               } else if (id[2] == 0x82 && id[3] == 0x06) {
+                       switch (id[1]) {
+                       case 0x51 ... 0x54:
+                               /* CY15B102QSN ... CY15B204QSN */
+                               chip->byte_len = BIT(((id[0] >> 3) & 0x1F) + 9);
+                               break;
+                       default:
+                               dev_err(dev, "Error: unsupported product id %02x\n", id[1]);
+                               return -ENODEV;
+                       }
+               } else {
+                       dev_err(dev, "Error: unrecognized JEDEC ID format: %*ph\n",
+                               FM25_ID_LEN, id);
                        return -ENODEV;
                }
 
-               if (id[8]) {
-                       fm25_aux_read(at25, sernum, FM25_RDSN, FM25_SN_LEN);
-                       /* Swap byte order */
-                       for (i = 0; i < FM25_SN_LEN; i++)
-                               at25->sernum[i] = sernum[FM25_SN_LEN - 1 - i];
-               }
+               fm25_aux_read(at25, sernum, FM25_RDSN, FM25_SN_LEN);
+               /* Swap byte order */
+               for (i = 0; i < FM25_SN_LEN; i++)
+                       at25->sernum[i] = sernum[FM25_SN_LEN - 1 - i];
        }
 
        if (chip->byte_len > 64 * 1024)