summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans de Goede <hdegoede@redhat.com>2012-09-19 21:04:00 +0000
committerHans de Goede <hdegoede@redhat.com>2012-09-19 21:04:00 +0000
commit3fb22f2cf2d8216d29e79ef3367ea33ca346cfd3 (patch)
treecbaa9f30201340dae2f588b290efb7f3f14a8a84
parent10f0aadd724ff62072293845d67d90c9e8e3bf96 (diff)
downloadlibgphoto2-3fb22f2cf2d8216d29e79ef3367ea33ca346cfd3.tar.gz
ax203: Add support for SST25VF0?? spi eeproms
git-svn-id: https://svn.code.sf.net/p/gphoto/code/branches/libgphoto2-2_4/libgphoto2@14113 67ed7778-7388-44ab-90cf-0a291f65f57c
-rw-r--r--camlibs/ax203/ax203.c57
-rw-r--r--camlibs/ax203/ax203.h1
2 files changed, 46 insertions, 12 deletions
diff --git a/camlibs/ax203/ax203.c b/camlibs/ax203/ax203.c
index 0eb5de425..09731b134 100644
--- a/camlibs/ax203/ax203.c
+++ b/camlibs/ax203/ax203.c
@@ -43,6 +43,7 @@ static const struct eeprom_info {
uint32_t id;
int mem_size;
int has_4k_sectors;
+ int pp_64k;
} ax203_eeprom_info[] = {
{ "AMIC A25L040", 0x37133037, 524288, 1 },
{ "AMIC A25L080", 0x37143037, 1048576, 1 },
@@ -85,9 +86,8 @@ static const struct eeprom_info {
{ "Spansion S25FL008A", 0x00130201, 1048576, 0 },
{ "Spansion S25FL016A", 0x00140201, 2097152, 0 },
- /* The SST25VF080 and SST25VF016 (id:0xbf8e25bf & 0xbf4125bf) PP
- instruction can only program a single byte at a time. Thus they
- are not supported */
+ { "SST25VF080", 0xbf8e25bf, 1048576, 0, 1 },
+ { "SST25VF016", 0xbf4125bf, 2097152, 0, 1 },
{ "ST M25P08", 0x7f142020, 1048576, 0 },
{ "ST M25P16", 0x7f152020, 2097152, 0 },
@@ -1603,11 +1603,23 @@ ax203_commit_block_64k(Camera *camera, int bss)
return GP_OK;
}
+/* The ax3003 and the ax206 with AAI capable eeproms can program 64k at once,
+ this is probably done by special handling inside the firmware. */
static int
-ax203_commit_block_ax3003(Camera *camera, int bss)
+ax203_commit_block_64k_at_once(Camera *camera, int bss)
{
int block_sector_size = SPI_EEPROM_BLOCK_SIZE / SPI_EEPROM_SECTOR_SIZE;
int i, address = bss * SPI_EEPROM_SECTOR_SIZE;
+ int checksum = 0;
+ char extra_arg = 0;
+
+ /* The ax206 (and we assume the same applies for ax203, untested!):
+ 1) Needs the last byte of the scsi cmd to be 2 to enable 64k pp
+ 2) Has an extra checksum function, which we might as well use. */
+ if (camera->pl->frame_version != AX3003_FIRMWARE_3_5_x) {
+ extra_arg = 2;
+ checksum = 1;
+ }
/* Make sure we have read the entire block before erasing it !! */
for (i = 0; i < block_sector_size; i++)
@@ -1623,14 +1635,31 @@ ax203_commit_block_ax3003(Camera *camera, int bss)
/* Erase the block */
CHECK (ax203_erase64k_sector (camera, bss))
- /* And program the block in one large 64k page write, the ax3003
- probably emulates this in firmware, to avoid usb bus overhead. */
+ /* program the block in one large 64k page write */
CHECK (ax203_eeprom_write_enable (camera))
CHECK (ax203_eeprom_program_page (camera, address,
camera->pl->mem + address,
- SPI_EEPROM_BLOCK_SIZE, 0))
+ SPI_EEPROM_BLOCK_SIZE, extra_arg))
CHECK (ax203_eeprom_wait_ready (camera))
+ /* and ask the device to verify the write with a checksum */
+ if (checksum) {
+ checksum = 0;
+ for (i = address; i < (address + SPI_EEPROM_BLOCK_SIZE); i++)
+ checksum += ((uint8_t *)camera->pl->mem)[i];
+ checksum &= 0xffff;
+
+ i = ax203_get_checksum(camera, address, SPI_EEPROM_BLOCK_SIZE);
+ if (i < 0)
+ return i;
+ if (i != checksum) {
+ gp_log (GP_LOG_ERROR, "ax203",
+ "checksum mismatch after programming "
+ "expected %04x, got %04x\n", checksum, i);
+ return GP_ERROR_IO;
+ }
+ }
+
for (i = 0; i < block_sector_size; i++)
camera->pl->sector_dirty[bss + i] = 0;
@@ -1659,8 +1688,8 @@ ax203_commit(Camera *camera)
if (!dirty_sectors)
continue;
- if (camera->pl->frame_version == AX3003_FIRMWARE_3_5_x)
- CHECK (ax203_commit_block_ax3003 (camera, i))
+ if (camera->pl->pp_64k)
+ CHECK (ax203_commit_block_64k_at_once (camera, i))
/* There are 16 4k sectors per 64k block, when we need to
program 12 or more sectors, programming the entire block
becomes faster */
@@ -1729,9 +1758,13 @@ ax203_open_device(Camera *camera)
camera->pl->mem_size = ax203_eeprom_info[i].mem_size;
camera->pl->has_4k_sectors = ax203_eeprom_info[i].has_4k_sectors;
- GP_DEBUG ("%s EEPROM found, capacity: %d, has 4k sectors: %d",
- ax203_eeprom_info[i].name, camera->pl->mem_size,
- camera->pl->has_4k_sectors);
+ camera->pl->pp_64k = ax203_eeprom_info[i].pp_64k;
+ if (camera->pl->frame_version == AX3003_FIRMWARE_3_5_x)
+ camera->pl->pp_64k = 1;
+ GP_DEBUG (
+ "%s EEPROM found, capacity: %d, has 4k sectors: %d, pp_64k %d",
+ ax203_eeprom_info[i].name, camera->pl->mem_size,
+ camera->pl->has_4k_sectors, camera->pl->pp_64k);
return ax203_init (camera);
}
diff --git a/camlibs/ax203/ax203.h b/camlibs/ax203/ax203.h
index 1108f05b6..7ca009e0e 100644
--- a/camlibs/ax203/ax203.h
+++ b/camlibs/ax203/ax203.h
@@ -103,6 +103,7 @@ struct _CameraPrivateLibrary {
int mem_size;
int has_4k_sectors;
int block_protection_removed;
+ int pp_64k;
/* Driver configuration settings */
int syncdatetime;
};