Add sharp_probe into jedec_probe
Simon Evans
spse at secret.org.uk
Wed Jun 5 08:46:35 EDT 2002
Hi,
I just wanted to see if anyone had any objections to me committing the below
patch to CVS. Basically I have some sharp chips that almost work with the
normal jedec_probe routine however they do not like the Autoselect Command.
The patch below adds a second probing function `sharp_probe' to jedec_probe.c
that handles this difference. Is it ok to put this into the same file?
I thought it would be preferable to putting it into a second file since so
much of the jedec code is reused.
Comments?
cheers
si
Index: jedec_probe.c
===================================================================
RCS file: /home/cvs/mtd/drivers/mtd/chips/jedec_probe.c,v
retrieving revision 1.15
diff -u -r1.15 jedec_probe.c
--- jedec_probe.c 17 May 2002 08:48:57 -0000 1.15
+++ jedec_probe.c 5 Jun 2002 12:21:54 -0000
@@ -870,37 +880,13 @@
return 1; /* ok */
}
-static int jedec_probe_chip(struct map_info *map, __u32 base,
- struct flchip *chips, struct cfi_private *cfi)
+
+static int do_jedec_probe_chip(struct map_info *map, __u32 base, struct flchip *chips, struct cfi_private *cfi)
+
{
int i;
int retried = 0;
- if (!cfi->numchips) {
- switch (cfi->device_type) {
- case CFI_DEVICETYPE_X8:
- cfi->addr_unlock1 = 0x555;
- cfi->addr_unlock2 = 0x2aa;
- break;
- case CFI_DEVICETYPE_X16:
- cfi->addr_unlock1 = 0xaaa;
- if (map->buswidth == cfi->interleave) {
- /* X16 chip(s) in X8 mode */
- cfi->addr_unlock2 = 0x555;
- } else {
- cfi->addr_unlock2 = 0x554;
- }
- break;
- case CFI_DEVICETYPE_X32:
- cfi->addr_unlock1 = 0x1555;
- cfi->addr_unlock2 = 0xaaa;
- break;
- default:
- printk(KERN_NOTICE "Eep. Unknown jedec_probe device type %d\n", cfi->device_type);
- return 0;
- }
- }
-
retry:
/* Make certain we aren't probing past the end of map */
if (base >= map->size) {
@@ -928,9 +914,14 @@
/* Reset */
jedec_reset(base, map, cfi);
- /* Autoselect Mode */
- cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
- cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
+ /* Autoselect Mode - Some sharp chips dont like these two commands.
+ * sharp_probe sets addr->unlock1 = 0, jedec_probe sets addr->unlock1
+ * to a !0 address
+ */
+ if(cfi->addr_unlock1) {
+ cfi_send_gen_cmd(0xaa, cfi->addr_unlock1, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
+ cfi_send_gen_cmd(0x55, cfi->addr_unlock2, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
+ }
cfi_send_gen_cmd(0x90, cfi->addr_unlock1, base, map, cfi, CFI_DEVICETYPE_X8, NULL);
if (!cfi->numchips) {
@@ -1025,11 +1016,84 @@
return 1;
}
+
+static int jedec_probe_chip(struct map_info *map, __u32 base,
+ struct flchip *chips, struct cfi_private *cfi)
+{
+ if (!cfi->numchips) {
+ switch (cfi->device_type) {
+ case CFI_DEVICETYPE_X8:
+ cfi->addr_unlock1 = 0x555;
+ cfi->addr_unlock2 = 0x2aa;
+ break;
+ case CFI_DEVICETYPE_X16:
+ cfi->addr_unlock1 = 0xaaa;
+ if (map->buswidth == cfi->interleave) {
+ /* X16 chip(s) in X8 mode */
+ cfi->addr_unlock2 = 0x555;
+ } else {
+ cfi->addr_unlock2 = 0x554;
+ }
+ break;
+ case CFI_DEVICETYPE_X32:
+ cfi->addr_unlock1 = 0x1555;
+ cfi->addr_unlock2 = 0xaaa;
+ break;
+ default:
+ printk(KERN_NOTICE "Eep. Unknown jedec_probe device type %d\n", cfi->device_type);
+ return 0;
+ }
+ }
+ return do_jedec_probe_chip(map, base, chips, cfi);
+}
+
+
+static int sharp_probe_chip(struct map_info *map, __u32 base,
+ struct flchip *chips, struct cfi_private *cfi)
+{
+
+
+ if (!cfi->numchips) {
+ switch (cfi->device_type) {
+ case CFI_DEVICETYPE_X8:
+ cfi->addr_unlock1 = 0x0;
+ cfi->addr_unlock2 = 0x1;
+ break;
+ case CFI_DEVICETYPE_X16:
+ cfi->addr_unlock1 = 0x0;
+ if (map->buswidth == cfi->interleave) {
+ /* X16 chip(s) in X8 mode */
+ cfi->addr_unlock2 = 0x1;
+ } else {
+ cfi->addr_unlock2 = 0x2;
+ }
+ break;
+ case CFI_DEVICETYPE_X32:
+ cfi->addr_unlock1 = 0x0;
+ cfi->addr_unlock2 = 0x4;
+ break;
+ default:
+ printk(KERN_NOTICE "Eep. Unknown sharp_probe device type %d\n", cfi->device_type);
+ return 0;
+ }
+ }
+ return do_jedec_probe_chip(map, base, chips, cfi);
+}
+
+
+
static struct chip_probe jedec_chip_probe = {
name: "JEDEC",
probe_chip: jedec_probe_chip
};
+
+static struct chip_probe sharp_chip_probe = {
+ name: "SHARP",
+ probe_chip: sharp_probe_chip
+};
+
+
struct mtd_info *jedec_probe(struct map_info *map)
{
/*
@@ -1039,21 +1103,40 @@
return mtd_do_chip_probe(map, &jedec_chip_probe);
}
+struct mtd_info *sharp_probe(struct map_info *map)
+{
+ /*
+ * This is for chips that work with the jedec_probe except
+ * they dont like the autoselect command.
+ */
+ return mtd_do_chip_probe(map, &sharp_chip_probe);
+}
+
static struct mtd_chip_driver jedec_chipdrv = {
probe: jedec_probe,
name: "jedec_probe",
module: THIS_MODULE
};
+
+static struct mtd_chip_driver sharp_chipdrv = {
+ probe: sharp_probe,
+ name: "sharp_probe",
+ module: THIS_MODULE
+};
+
+
int __init jedec_probe_init(void)
{
register_mtd_chip_driver(&jedec_chipdrv);
+ register_mtd_chip_driver(&sharp_chipdrv);
return 0;
}
static void __exit jedec_probe_exit(void)
{
unregister_mtd_chip_driver(&jedec_chipdrv);
+ unregister_mtd_chip_driver(&sharp_chipdrv);
}
module_init(jedec_probe_init);
More information about the linux-mtd
mailing list