diff options
author | Hans de Goede <hdegoede@redhat.com> | 2012-09-19 21:04:00 +0000 |
---|---|---|
committer | Hans de Goede <hdegoede@redhat.com> | 2012-09-19 21:04:00 +0000 |
commit | 3fb22f2cf2d8216d29e79ef3367ea33ca346cfd3 (patch) | |
tree | cbaa9f30201340dae2f588b290efb7f3f14a8a84 | |
parent | 10f0aadd724ff62072293845d67d90c9e8e3bf96 (diff) | |
download | libgphoto2-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.c | 57 | ||||
-rw-r--r-- | camlibs/ax203/ax203.h | 1 |
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; }; |