1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Driver for Microchip 48L640 64 Kb SPI Serial EERAM 4 * 5 * Copyright Heiko Schocher <hs@denx.de> 6 * 7 * datasheet: http://ww1.microchip.com/downloads/en/DeviceDoc/20006055B.pdf 8 * 9 * we set continuous mode but reading/writing more bytes than 10 * pagesize seems to bring chip into state where readden values 11 * are wrong ... no idea why. 12 * 13 */ 14 #include <linux/delay.h> 15 #include <linux/device.h> 16 #include <linux/jiffies.h> 17 #include <linux/module.h> 18 #include <linux/mtd/mtd.h> 19 #include <linux/mtd/partitions.h> 20 #include <linux/mutex.h> 21 #include <linux/sched.h> 22 #include <linux/sizes.h> 23 #include <linux/spi/flash.h> 24 #include <linux/spi/spi.h> 25 #include <linux/of.h> 26 #include <linux/string_choices.h> 27 28 struct mchp48_caps { 29 unsigned int size; 30 unsigned int page_size; 31 bool auto_disable_wel; 32 }; 33 34 struct mchp48l640_flash { 35 struct spi_device *spi; 36 struct mutex lock; 37 struct mtd_info mtd; 38 const struct mchp48_caps *caps; 39 }; 40 41 #define MCHP48L640_CMD_WREN 0x06 42 #define MCHP48L640_CMD_WRDI 0x04 43 #define MCHP48L640_CMD_WRITE 0x02 44 #define MCHP48L640_CMD_READ 0x03 45 #define MCHP48L640_CMD_WRSR 0x01 46 #define MCHP48L640_CMD_RDSR 0x05 47 48 #define MCHP48L640_STATUS_RDY 0x01 49 #define MCHP48L640_STATUS_WEL 0x02 50 #define MCHP48L640_STATUS_BP0 0x04 51 #define MCHP48L640_STATUS_BP1 0x08 52 #define MCHP48L640_STATUS_SWM 0x10 53 #define MCHP48L640_STATUS_PRO 0x20 54 #define MCHP48L640_STATUS_ASE 0x40 55 56 #define MCHP48L640_TIMEOUT 100 57 58 #define MAX_CMD_SIZE 0x10 59 60 #define to_mchp48l640_flash(x) container_of(x, struct mchp48l640_flash, mtd) 61 62 static int mchp48l640_mkcmd(struct mchp48l640_flash *flash, u8 cmd, loff_t addr, char *buf) 63 { 64 buf[0] = cmd; 65 buf[1] = addr >> 8; 66 buf[2] = addr; 67 68 return 3; 69 } 70 71 static int mchp48l640_read_status(struct mchp48l640_flash *flash, int *status) 72 { 73 unsigned char cmd[2]; 74 int ret; 75 76 cmd[0] = MCHP48L640_CMD_RDSR; 77 cmd[1] = 0x00; 78 mutex_lock(&flash->lock); 79 ret = spi_write_then_read(flash->spi, &cmd[0], 1, &cmd[1], 1); 80 mutex_unlock(&flash->lock); 81 if (!ret) 82 *status = cmd[1]; 83 dev_dbg(&flash->spi->dev, "read status ret: %d status: %x", ret, *status); 84 85 return ret; 86 } 87 88 static int mchp48l640_waitforbit(struct mchp48l640_flash *flash, int bit, bool set) 89 { 90 int ret, status; 91 unsigned long deadline; 92 93 deadline = jiffies + msecs_to_jiffies(MCHP48L640_TIMEOUT); 94 do { 95 ret = mchp48l640_read_status(flash, &status); 96 dev_dbg(&flash->spi->dev, "read status ret: %d bit: %x %sset status: %x", 97 ret, bit, (set ? "" : "not"), status); 98 if (ret) 99 return ret; 100 101 if (set) { 102 if ((status & bit) == bit) 103 return 0; 104 } else { 105 if ((status & bit) == 0) 106 return 0; 107 } 108 109 usleep_range(1000, 2000); 110 } while (!time_after_eq(jiffies, deadline)); 111 112 dev_err(&flash->spi->dev, "Timeout waiting for bit %x %s set in status register.", 113 bit, (set ? "" : "not")); 114 return -ETIMEDOUT; 115 } 116 117 static int mchp48l640_write_prepare(struct mchp48l640_flash *flash, bool enable) 118 { 119 unsigned char cmd[2]; 120 int ret; 121 122 if (enable) 123 cmd[0] = MCHP48L640_CMD_WREN; 124 else 125 cmd[0] = MCHP48L640_CMD_WRDI; 126 127 mutex_lock(&flash->lock); 128 ret = spi_write(flash->spi, cmd, 1); 129 mutex_unlock(&flash->lock); 130 131 if (ret) 132 dev_err(&flash->spi->dev, "write %s failed ret: %d", 133 str_enable_disable(enable), ret); 134 135 dev_dbg(&flash->spi->dev, "write %s success ret: %d", 136 str_enable_disable(enable), ret); 137 if (enable) 138 return mchp48l640_waitforbit(flash, MCHP48L640_STATUS_WEL, true); 139 140 return ret; 141 } 142 143 static int mchp48l640_set_mode(struct mchp48l640_flash *flash) 144 { 145 unsigned char cmd[2]; 146 int ret; 147 148 ret = mchp48l640_write_prepare(flash, true); 149 if (ret) 150 return ret; 151 152 cmd[0] = MCHP48L640_CMD_WRSR; 153 cmd[1] = MCHP48L640_STATUS_PRO; 154 155 mutex_lock(&flash->lock); 156 ret = spi_write(flash->spi, cmd, 2); 157 mutex_unlock(&flash->lock); 158 if (ret) 159 dev_err(&flash->spi->dev, "Could not set continuous mode ret: %d", ret); 160 161 return mchp48l640_waitforbit(flash, MCHP48L640_STATUS_PRO, true); 162 } 163 164 static int mchp48l640_wait_rdy(struct mchp48l640_flash *flash) 165 { 166 return mchp48l640_waitforbit(flash, MCHP48L640_STATUS_RDY, false); 167 }; 168 169 static int mchp48l640_write_page(struct mtd_info *mtd, loff_t to, size_t len, 170 size_t *retlen, const unsigned char *buf) 171 { 172 struct mchp48l640_flash *flash = to_mchp48l640_flash(mtd); 173 unsigned char *cmd; 174 int ret; 175 int cmdlen; 176 177 cmd = kmalloc((3 + len), GFP_KERNEL | GFP_DMA); 178 if (!cmd) 179 return -ENOMEM; 180 181 ret = mchp48l640_wait_rdy(flash); 182 if (ret) 183 goto fail; 184 185 ret = mchp48l640_write_prepare(flash, true); 186 if (ret) 187 goto fail; 188 189 mutex_lock(&flash->lock); 190 cmdlen = mchp48l640_mkcmd(flash, MCHP48L640_CMD_WRITE, to, cmd); 191 memcpy(&cmd[cmdlen], buf, len); 192 ret = spi_write(flash->spi, cmd, cmdlen + len); 193 mutex_unlock(&flash->lock); 194 if (!ret) 195 *retlen += len; 196 else 197 goto fail; 198 199 if (flash->caps->auto_disable_wel) { 200 ret = mchp48l640_waitforbit(flash, MCHP48L640_STATUS_WEL, false); 201 if (ret) 202 goto fail; 203 } else { 204 ret = mchp48l640_write_prepare(flash, false); 205 if (ret) 206 goto fail; 207 } 208 209 kfree(cmd); 210 return 0; 211 fail: 212 kfree(cmd); 213 dev_err(&flash->spi->dev, "write fail with: %d", ret); 214 return ret; 215 }; 216 217 static int mchp48l640_write(struct mtd_info *mtd, loff_t to, size_t len, 218 size_t *retlen, const unsigned char *buf) 219 { 220 struct mchp48l640_flash *flash = to_mchp48l640_flash(mtd); 221 int ret; 222 size_t wlen = 0; 223 loff_t woff = to; 224 size_t ws; 225 size_t page_sz = flash->caps->page_size; 226 227 /* 228 * we set PRO bit (page rollover), but writing length > page size 229 * does result in total chaos, so write in 32 byte chunks. 230 */ 231 while (wlen < len) { 232 ws = min((len - wlen), page_sz); 233 ret = mchp48l640_write_page(mtd, woff, ws, retlen, &buf[wlen]); 234 if (ret) 235 return ret; 236 wlen += ws; 237 woff += ws; 238 } 239 240 return 0; 241 } 242 243 static int mchp48l640_read_page(struct mtd_info *mtd, loff_t from, size_t len, 244 size_t *retlen, unsigned char *buf) 245 { 246 struct mchp48l640_flash *flash = to_mchp48l640_flash(mtd); 247 unsigned char *cmd; 248 int ret; 249 int cmdlen; 250 251 cmd = kmalloc((3 + len), GFP_KERNEL | GFP_DMA); 252 if (!cmd) 253 return -ENOMEM; 254 255 ret = mchp48l640_wait_rdy(flash); 256 if (ret) 257 goto fail; 258 259 mutex_lock(&flash->lock); 260 cmdlen = mchp48l640_mkcmd(flash, MCHP48L640_CMD_READ, from, cmd); 261 ret = spi_write_then_read(flash->spi, cmd, cmdlen, buf, len); 262 mutex_unlock(&flash->lock); 263 if (!ret) 264 *retlen += len; 265 266 kfree(cmd); 267 return ret; 268 269 fail: 270 kfree(cmd); 271 dev_err(&flash->spi->dev, "read fail with: %d", ret); 272 return ret; 273 } 274 275 static int mchp48l640_read(struct mtd_info *mtd, loff_t from, size_t len, 276 size_t *retlen, unsigned char *buf) 277 { 278 struct mchp48l640_flash *flash = to_mchp48l640_flash(mtd); 279 int ret; 280 size_t wlen = 0; 281 loff_t woff = from; 282 size_t ws; 283 size_t page_sz = flash->caps->page_size; 284 285 /* 286 * we set PRO bit (page rollover), but if read length > page size 287 * does result in total chaos in result ... 288 */ 289 while (wlen < len) { 290 ws = min((len - wlen), page_sz); 291 ret = mchp48l640_read_page(mtd, woff, ws, retlen, &buf[wlen]); 292 if (ret) 293 return ret; 294 wlen += ws; 295 woff += ws; 296 } 297 298 return 0; 299 }; 300 301 static const struct mchp48_caps mchp48l640_caps = { 302 .size = SZ_8K, 303 .page_size = 32, 304 .auto_disable_wel = true, 305 }; 306 307 static const struct mchp48_caps mb85rs128ty_caps = { 308 .size = SZ_16K, 309 .page_size = 256, 310 .auto_disable_wel = false, 311 }; 312 313 static int mchp48l640_probe(struct spi_device *spi) 314 { 315 struct mchp48l640_flash *flash; 316 struct flash_platform_data *data; 317 int err; 318 int status; 319 320 flash = devm_kzalloc(&spi->dev, sizeof(*flash), GFP_KERNEL); 321 if (!flash) 322 return -ENOMEM; 323 324 flash->spi = spi; 325 mutex_init(&flash->lock); 326 spi_set_drvdata(spi, flash); 327 328 err = mchp48l640_read_status(flash, &status); 329 if (err) 330 return err; 331 332 err = mchp48l640_set_mode(flash); 333 if (err) 334 return err; 335 336 data = dev_get_platdata(&spi->dev); 337 338 flash->caps = of_device_get_match_data(&spi->dev); 339 if (!flash->caps) 340 flash->caps = &mchp48l640_caps; 341 342 mtd_set_of_node(&flash->mtd, spi->dev.of_node); 343 flash->mtd.dev.parent = &spi->dev; 344 flash->mtd.type = MTD_RAM; 345 flash->mtd.flags = MTD_CAP_RAM; 346 flash->mtd.writesize = flash->caps->page_size; 347 flash->mtd.size = flash->caps->size; 348 flash->mtd._read = mchp48l640_read; 349 flash->mtd._write = mchp48l640_write; 350 351 err = mtd_device_register(&flash->mtd, data ? data->parts : NULL, 352 data ? data->nr_parts : 0); 353 if (err) 354 return err; 355 356 return 0; 357 } 358 359 static void mchp48l640_remove(struct spi_device *spi) 360 { 361 struct mchp48l640_flash *flash = spi_get_drvdata(spi); 362 363 WARN_ON(mtd_device_unregister(&flash->mtd)); 364 } 365 366 static const struct of_device_id mchp48l640_of_table[] = { 367 { 368 .compatible = "microchip,48l640", 369 .data = &mchp48l640_caps, 370 }, 371 { 372 .compatible = "fujitsu,mb85rs128ty", 373 .data = &mb85rs128ty_caps, 374 }, 375 {} 376 }; 377 MODULE_DEVICE_TABLE(of, mchp48l640_of_table); 378 379 static const struct spi_device_id mchp48l640_spi_ids[] = { 380 { 381 .name = "48l640", 382 .driver_data = (kernel_ulong_t)&mchp48l640_caps, 383 }, 384 { 385 .name = "mb85rs128ty", 386 .driver_data = (kernel_ulong_t)&mb85rs128ty_caps, 387 }, 388 {} 389 }; 390 MODULE_DEVICE_TABLE(spi, mchp48l640_spi_ids); 391 392 static struct spi_driver mchp48l640_driver = { 393 .driver = { 394 .name = "mchp48l640", 395 .of_match_table = mchp48l640_of_table, 396 }, 397 .probe = mchp48l640_probe, 398 .remove = mchp48l640_remove, 399 .id_table = mchp48l640_spi_ids, 400 }; 401 402 module_spi_driver(mchp48l640_driver); 403 404 MODULE_DESCRIPTION("MTD SPI driver for Microchip 48l640 EERAM chips"); 405 MODULE_AUTHOR("Heiko Schocher <hs@denx.de>"); 406 MODULE_LICENSE("GPL v2"); 407 MODULE_ALIAS("spi:mchp48l640"); 408