]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
Support M95040 SPI EEPROM
authorIvo Sieben <meltedpianoman@gmail.com>
Wed, 18 Apr 2012 06:29:34 +0000 (08:29 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Wed, 18 Apr 2012 21:57:57 +0000 (14:57 -0700)
Updated the generic SPI EEPROM driver AT25 for support of an additional address
bit in the instruction byte. Certain EEPROMS have a size that is larger than the
number of address bytes would allow (e.g. like M95040 from ST that has 512 Byte
size but uses only one address byte (A0 to A7) for addressing.) For the extra
address bit (A8, A16 or A24) bit 3 of the instruction byte is used. This
instruction bit is normally defined as don't care for other AT25 like chips.

Reviewed-by: Wolfram Sang <w.sang@pengutronix.de>
Signed-off-by: Ivo Sieben <meltedpianoman@gmail.com>
Acked-by: Chris Wright <chrisw@sous-sol.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/misc/eeprom/at25.c
include/linux/spi/eeprom.h

index 01ab3c9b4cf7cb8f1c1eaa1d436519be49fcc794..0842c2994ee24d2f2d6d285968bdad054ea52e13 100644 (file)
@@ -50,6 +50,7 @@ struct at25_data {
 #define        AT25_SR_BP1     0x08
 #define        AT25_SR_WPEN    0x80            /* writeprotect enable */
 
+#define        AT25_INSTR_BIT3 0x08            /* Additional address bit in instr */
 
 #define EE_MAXADDRLEN  3               /* 24 bit addresses, up to 2 MBytes */
 
@@ -75,6 +76,7 @@ at25_ee_read(
        ssize_t                 status;
        struct spi_transfer     t[2];
        struct spi_message      m;
+       u8                      instr;
 
        if (unlikely(offset >= at25->bin.size))
                return 0;
@@ -84,7 +86,12 @@ at25_ee_read(
                return count;
 
        cp = command;
-       *cp++ = AT25_READ;
+
+       instr = AT25_READ;
+       if (at25->chip.flags & EE_INSTR_BIT3_IS_ADDR)
+               if (offset >= (1U << (at25->addrlen * 8)))
+                       instr |= AT25_INSTR_BIT3;
+       *cp++ = instr;
 
        /* 8/16/24-bit address is written MSB first */
        switch (at25->addrlen) {
@@ -167,14 +174,14 @@ at25_ee_write(struct at25_data *at25, const char *buf, loff_t off,
        /* For write, rollover is within the page ... so we write at
         * most one page, then manually roll over to the next page.
         */
-       bounce[0] = AT25_WRITE;
        mutex_lock(&at25->lock);
        do {
                unsigned long   timeout, retries;
                unsigned        segment;
                unsigned        offset = (unsigned) off;
-               u8              *cp = bounce + 1;
+               u8              *cp = bounce;
                int             sr;
+               u8              instr;
 
                *cp = AT25_WREN;
                status = spi_write(at25->spi, cp, 1);
@@ -184,6 +191,12 @@ at25_ee_write(struct at25_data *at25, const char *buf, loff_t off,
                        break;
                }
 
+               instr = AT25_WRITE;
+               if (at25->chip.flags & EE_INSTR_BIT3_IS_ADDR)
+                       if (offset >= (1U << (at25->addrlen * 8)))
+                               instr |= AT25_INSTR_BIT3;
+               *cp++ = instr;
+
                /* 8/16/24-bit address is written MSB first */
                switch (at25->addrlen) {
                default:        /* case 3 */
index 306e7b1c69edf30243836e89d7141e47934e7a98..403e007aef6825e2bffc7df3f8c0b8f0fee9d937 100644 (file)
@@ -20,6 +20,16 @@ struct spi_eeprom {
 #define        EE_ADDR3        0x0004                  /* 24 bit addrs */
 #define        EE_READONLY     0x0008                  /* disallow writes */
 
+       /*
+        * Certain EEPROMS have a size that is larger than the number of address
+        * bytes would allow (e.g. like M95040 from ST that has 512 Byte size
+        * but uses only one address byte (A0 to A7) for addressing.) For
+        * the extra address bit (A8, A16 or A24) bit 3 of the instruction byte
+        * is used. This instruction bit is normally defined as don't care for
+        * other AT25 like chips.
+        */
+#define EE_INSTR_BIT3_IS_ADDR  0x0010
+
        /* for exporting this chip's data to other kernel code */
        void (*setup)(struct memory_accessor *mem, void *context);
        void *context;