Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

mtd: mchp23k256: Add support for mchp23lcv1024

The mchp23lcv1024 is similar to the mchp23k256, the differences (from a
software point of view) are the capacity of the chip and the size of the
addresses used.

There is no way to detect the specific chip so we must be told via a
Device Tree or default to mchp23k256 when device tree is not used.

Signed-off-by: Chris Packham <chris.packham@alliedtelesis.co.nz>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Acked-by: Rob Herring <robh@kernel.org>
Signed-off-by: Brian Norris <computersforpeace@gmail.com>

authored by

Chris Packham and committed by
Brian Norris
4379075a 2f071ff1

+57 -11
+1 -1
Documentation/devicetree/bindings/mtd/microchip,mchp23k256.txt
··· 3 3 Required properties: 4 4 - #address-cells, #size-cells : Must be present if the device has sub-nodes 5 5 representing partitions. 6 - - compatible : Must be "microchip,mchp23k256" 6 + - compatible : Must be one of "microchip,mchp23k256" or "microchip,mchp23lcv1024" 7 7 - reg : Chip-Select number 8 8 - spi-max-frequency : Maximum frequency of the SPI bus the chip can operate at 9 9
+56 -10
drivers/mtd/devices/mchp23k256.c
··· 21 21 #include <linux/spi/spi.h> 22 22 #include <linux/of_device.h> 23 23 24 + #define MAX_CMD_SIZE 4 25 + 26 + struct mchp23_caps { 27 + u8 addr_width; 28 + unsigned int size; 29 + }; 30 + 24 31 struct mchp23k256_flash { 25 32 struct spi_device *spi; 26 33 struct mutex lock; 27 34 struct mtd_info mtd; 35 + const struct mchp23_caps *caps; 28 36 }; 29 37 30 38 #define MCHP23K256_CMD_WRITE_STATUS 0x01 ··· 42 34 43 35 #define to_mchp23k256_flash(x) container_of(x, struct mchp23k256_flash, mtd) 44 36 37 + static void mchp23k256_addr2cmd(struct mchp23k256_flash *flash, 38 + unsigned int addr, u8 *cmd) 39 + { 40 + int i; 41 + 42 + /* 43 + * Address is sent in big endian (MSB first) and we skip 44 + * the first entry of the cmd array which contains the cmd 45 + * opcode. 46 + */ 47 + for (i = flash->caps->addr_width; i > 0; i--, addr >>= 8) 48 + cmd[i] = addr; 49 + } 50 + 51 + static int mchp23k256_cmdsz(struct mchp23k256_flash *flash) 52 + { 53 + return 1 + flash->caps->addr_width; 54 + } 55 + 45 56 static int mchp23k256_write(struct mtd_info *mtd, loff_t to, size_t len, 46 57 size_t *retlen, const unsigned char *buf) 47 58 { 48 59 struct mchp23k256_flash *flash = to_mchp23k256_flash(mtd); 49 60 struct spi_transfer transfer[2] = {}; 50 61 struct spi_message message; 51 - unsigned char command[3]; 62 + unsigned char command[MAX_CMD_SIZE]; 52 63 53 64 spi_message_init(&message); 54 65 55 66 command[0] = MCHP23K256_CMD_WRITE; 56 - command[1] = to >> 8; 57 - command[2] = to; 67 + mchp23k256_addr2cmd(flash, to, command); 58 68 59 69 transfer[0].tx_buf = command; 60 - transfer[0].len = sizeof(command); 70 + transfer[0].len = mchp23k256_cmdsz(flash); 61 71 spi_message_add_tail(&transfer[0], &message); 62 72 63 73 transfer[1].tx_buf = buf; ··· 99 73 struct mchp23k256_flash *flash = to_mchp23k256_flash(mtd); 100 74 struct spi_transfer transfer[2] = {}; 101 75 struct spi_message message; 102 - unsigned char command[3]; 76 + unsigned char command[MAX_CMD_SIZE]; 103 77 104 78 spi_message_init(&message); 105 79 106 80 memset(&transfer, 0, sizeof(transfer)); 107 81 command[0] = MCHP23K256_CMD_READ; 108 - command[1] = from >> 8; 109 - command[2] = from; 82 + mchp23k256_addr2cmd(flash, from, command); 110 83 111 84 transfer[0].tx_buf = command; 112 - transfer[0].len = sizeof(command); 85 + transfer[0].len = mchp23k256_cmdsz(flash); 113 86 spi_message_add_tail(&transfer[0], &message); 114 87 115 88 transfer[1].rx_buf = buf; ··· 148 123 return spi_sync(spi, &message); 149 124 } 150 125 126 + static const struct mchp23_caps mchp23k256_caps = { 127 + .size = SZ_32K, 128 + .addr_width = 2, 129 + }; 130 + 131 + static const struct mchp23_caps mchp23lcv1024_caps = { 132 + .size = SZ_128K, 133 + .addr_width = 3, 134 + }; 135 + 151 136 static int mchp23k256_probe(struct spi_device *spi) 152 137 { 153 138 struct mchp23k256_flash *flash; ··· 178 143 179 144 data = dev_get_platdata(&spi->dev); 180 145 146 + flash->caps = of_device_get_match_data(&spi->dev); 147 + if (!flash->caps) 148 + flash->caps = &mchp23k256_caps; 149 + 181 150 mtd_set_of_node(&flash->mtd, spi->dev.of_node); 182 151 flash->mtd.dev.parent = &spi->dev; 183 152 flash->mtd.type = MTD_RAM; 184 153 flash->mtd.flags = MTD_CAP_RAM; 185 154 flash->mtd.writesize = 1; 186 - flash->mtd.size = SZ_32K; 155 + flash->mtd.size = flash->caps->size; 187 156 flash->mtd._read = mchp23k256_read; 188 157 flash->mtd._write = mchp23k256_write; 189 158 ··· 207 168 } 208 169 209 170 static const struct of_device_id mchp23k256_of_table[] = { 210 - { .compatible = "microchip,mchp23k256" }, 171 + { 172 + .compatible = "microchip,mchp23k256", 173 + .data = &mchp23k256_caps, 174 + }, 175 + { 176 + .compatible = "microchip,mchp23lcv1024", 177 + .data = &mchp23lcv1024_caps, 178 + }, 211 179 {} 212 180 }; 213 181 MODULE_DEVICE_TABLE(of, mchp23k256_of_table);