Fix Sharp LHF00L04

- Add eraseblock definitions
- Use correct eraseblock sizes (the datasheet is a bit ambiguous)
- Use correct probe function
- Fill in probe timing

There is a lot more stuff left to clean up, but at least probe and erase
should work now.

Corresponding to flashrom svn r837.

Signed-off-by: Carl-Daniel Hailfinger <c-d.hailfinger.devel.2006@gmx.net>
Acked-by: Sean Nelson <audiohacked@gmail.com>
diff --git a/chipdrivers.h b/chipdrivers.h
index 4456204..af22abf 100644
--- a/chipdrivers.h
+++ b/chipdrivers.h
@@ -53,6 +53,7 @@
 int spi_aai_write(struct flashchip *flash, uint8_t *buf);
 
 /* 82802ab.c */
+uint8_t wait_82802ab(chipaddr bios);
 int probe_82802ab(struct flashchip *flash);
 int erase_82802ab(struct flashchip *flash);
 int write_82802ab(struct flashchip *flash, uint8_t *buf);
@@ -117,7 +118,7 @@
 
 /* sharplhf00l04.c */
 int probe_lhf00l04(struct flashchip *flash);
-int erase_lhf00l04(struct flashchip *flash);
+int erase_lhf00l04_block(struct flashchip *flash, unsigned int blockaddr, unsigned int blocklen);
 int write_lhf00l04(struct flashchip *flash, uint8_t *buf);
 void protect_lhf00l04(chipaddr bios);
 
diff --git a/flashchips.c b/flashchips.c
index 50a1226..e6c4b86 100644
--- a/flashchips.c
+++ b/flashchips.c
@@ -2522,9 +2522,24 @@
 		.total_size	= 1024,
 		.page_size	= 64 * 1024,
 		.tested		= TEST_UNTESTED,
-		.probe		= probe_lhf00l04,
-		.probe_timing	= TIMING_IGNORED, /* routine don't use probe_timing (sharplhf00l04.c) */
-		.erase		= erase_lhf00l04,
+		.probe		= probe_49lfxxxc,
+		.probe_timing	= TIMING_ZERO,
+		.erase		= NULL,
+		.block_erasers	=
+		{
+			{
+				.eraseblocks = {
+					{64 * 1024, 15},
+					{8 * 1024, 8}
+				 },
+				.block_erase = erase_lhf00l04_block,
+			}, {
+				.eraseblocks = {
+					{1024 * 1024, 1}
+				},
+				.block_erase = NULL, /* 30 D0, only in PP mode */
+			},
+		},
 		.write		= write_lhf00l04,
 		.read		= read_memmapped,
 	},
diff --git a/sharplhf00l04.c b/sharplhf00l04.c
index 1234ae4..9669e20 100644
--- a/sharplhf00l04.c
+++ b/sharplhf00l04.c
@@ -33,80 +33,20 @@
 	printf("%s", status & 0x2 ? "WP|TBL#|WP#,ABORT:" : "UNLOCK:");
 }
 
-int probe_lhf00l04(struct flashchip *flash)
+/* FIXME: The datasheet is unclear whether we should use toggle_ready_jedec
+ * or wait_82802ab.
+ */
+
+int erase_lhf00l04_block(struct flashchip *flash, unsigned int blockaddr, unsigned int blocklen)
 {
-	chipaddr bios = flash->virtual_memory;
-	uint8_t id1, id2;
-
-#if 0
-	/* Enter ID mode */
-	chip_writeb(0xAA, bios + 0x5555);
-	chip_writeb(0x55, bios + 0x2AAA);
-	chip_writeb(0x90, bios + 0x5555);
-#endif
-
-	chip_writeb(0xff, bios);
-	programmer_delay(10);
-	chip_writeb(0x90, bios);
-	programmer_delay(10);
-
-	id1 = chip_readb(bios);
-	id2 = chip_readb(bios + 0x01);
-
-	/* Leave ID mode */
-	chip_writeb(0xAA, bios + 0x5555);
-	chip_writeb(0x55, bios + 0x2AAA);
-	chip_writeb(0xF0, bios + 0x5555);
-
-	programmer_delay(10);
-
-	printf_debug("%s: id1 0x%02x, id2 0x%02x\n", __func__, id1, id2);
-
-	if (id1 != flash->manufacture_id || id2 != flash->model_id)
-		return 0;
-
-	map_flash_registers(flash);
-
-	return 1;
-}
-
-uint8_t wait_lhf00l04(chipaddr bios)
-{
-	uint8_t status;
-
-	chip_writeb(0x70, bios);
-	if ((chip_readb(bios) & 0x80) == 0) {	// it's busy
-		while ((chip_readb(bios) & 0x80) == 0) ;
-	}
-
-	status = chip_readb(bios);
-
-	// put another command to get out of status register mode.
-
-	chip_writeb(0x90, bios);
-	programmer_delay(10);
-
-	chip_readb(bios);		// vendor ID
-	chip_readb(bios + 0x01);	// device ID
-
-	// this is needed to jam it out of "read id" mode
-	chip_writeb(0xAA, bios + 0x5555);
-	chip_writeb(0x55, bios + 0x2AAA);
-	chip_writeb(0xF0, bios + 0x5555);
-
-	return status;
-}
-
-int erase_lhf00l04_block(struct flashchip *flash, int offset)
-{
-	chipaddr bios = flash->virtual_memory + offset;
-	chipaddr wrprotect = flash->virtual_registers + offset + 2;
+	chipaddr bios = flash->virtual_memory + blockaddr;
+	chipaddr wrprotect = flash->virtual_registers + blockaddr + 2;
 	uint8_t status;
 
 	// clear status register
 	chip_writeb(0x50, bios);
 	printf("Erase at 0x%lx\n", bios);
-	status = wait_lhf00l04(flash->virtual_memory);
+	status = wait_82802ab(flash->virtual_memory);
 	print_lhf00l04_status(status);
 	// clear write protect
 	printf("write protect is at 0x%lx\n", (wrprotect));
@@ -119,34 +59,17 @@
 	chip_writeb(0xd0, bios);
 	programmer_delay(10);
 	// now let's see what the register is
-	status = wait_lhf00l04(flash->virtual_memory);
+	status = wait_82802ab(flash->virtual_memory);
 	print_lhf00l04_status(status);
-	printf("DONE BLOCK 0x%x\n", offset);
+	printf("DONE BLOCK 0x%x\n", blockaddr);
 
-	if (check_erased_range(flash, offset, flash->page_size)) {
+	if (check_erased_range(flash, blockaddr, blocklen)) {
 		fprintf(stderr, "ERASE FAILED!\n");
 		return -1;
 	}
 	return 0;
 }
 
-int erase_lhf00l04(struct flashchip *flash)
-{
-	int i;
-	unsigned int total_size = flash->total_size * 1024;
-
-	printf("total_size is %d; flash->page_size is %d\n",
-	       total_size, flash->page_size);
-	for (i = 0; i < total_size; i += flash->page_size)
-		if (erase_lhf00l04_block(flash, i)) {
-			fprintf(stderr, "ERASE FAILED!\n");
-			return -1;
-		}
-	printf("DONE ERASE\n");
-
-	return 0;
-}
-
 void write_page_lhf00l04(chipaddr bios, uint8_t *src,
 			 chipaddr dst, int page_size)
 {
@@ -156,7 +79,7 @@
 		/* transfer data from source to destination */
 		chip_writeb(0x40, dst);
 		chip_writeb(*src++, dst++);
-		wait_lhf00l04(bios);
+		wait_82802ab(bios);
 	}
 }
 
@@ -167,7 +90,7 @@
 	int page_size = flash->page_size;
 	chipaddr bios = flash->virtual_memory;
 
-	if (erase_lhf00l04(flash)) {
+	if (erase_flash(flash)) {
 		fprintf(stderr, "ERASE FAILED!\n");
 		return -1;
 	}