summaryrefslogtreecommitdiff
path: root/resources
diff options
context:
space:
mode:
authorFrancis Rowe <info@gluglug.org.uk>2014-07-11 08:53:00 +0000
committerMichał Masłowski <mtjm@mtjm.eu>2014-08-22 19:01:19 +0200
commitcee90ae0fce6d6aee8d78969b60c952c8890abd6 (patch)
tree6cbca259e213f5ffbc3927121e662c0377938cce /resources
Libreboot release 6 beta 1.
Diffstat (limited to 'resources')
-rw-r--r--resources/cbfstool/patch/COPYING2
-rw-r--r--resources/cbfstool/patch/rmodule.c628
-rw-r--r--resources/flashrom/patch/COPYING2
-rw-r--r--resources/flashrom/patch/flashchips.c13500
-rw-r--r--resources/flashrom/patch/flashchips.c_lenovobios_macronix13574
-rw-r--r--resources/flashrom/patch/flashchips.c_lenovobios_sst13574
-rw-r--r--resources/grub/background/COPYING3
-rw-r--r--resources/grub/background/background1024x768.pngbin0 -> 393850 bytes
-rw-r--r--resources/grub/config/COPYING33
-rw-r--r--resources/grub/config/grub_memdisk.cfg29
-rw-r--r--resources/grub/config/macbook21/grub.cfg57
-rw-r--r--resources/grub/config/macbook21/grub_dvorak.cfg57
-rw-r--r--resources/grub/config/macbook21/grub_ukdvorak.cfg57
-rw-r--r--resources/grub/config/macbook21/grub_ukqwerty.cfg57
-rw-r--r--resources/grub/config/t60/grub.cfg61
-rw-r--r--resources/grub/config/t60/grub_dvorak.cfg61
-rw-r--r--resources/grub/config/t60/grub_serial.cfg71
-rw-r--r--resources/grub/config/t60/grub_serial_dvorak.cfg71
-rw-r--r--resources/grub/config/t60/grub_serial_ukdvorak.cfg71
-rw-r--r--resources/grub/config/t60/grub_serial_ukqwerty.cfg71
-rw-r--r--resources/grub/config/t60/grub_ukdvorak.cfg61
-rw-r--r--resources/grub/config/t60/grub_ukqwerty.cfg61
-rw-r--r--resources/grub/config/x60/grub.cfg57
-rw-r--r--resources/grub/config/x60/grub_dvorak.cfg57
-rw-r--r--resources/grub/config/x60/grub_serial.cfg71
-rw-r--r--resources/grub/config/x60/grub_serial_dvorak.cfg71
-rw-r--r--resources/grub/config/x60/grub_serial_ukdvorak.cfg71
-rw-r--r--resources/grub/config/x60/grub_serial_ukqwerty.cfg71
-rw-r--r--resources/grub/config/x60/grub_ukdvorak.cfg57
-rw-r--r--resources/grub/config/x60/grub_ukqwerty.cfg57
-rw-r--r--resources/grub/config/x60t/grub.cfg57
-rw-r--r--resources/grub/config/x60t/grub_dvorak.cfg57
-rw-r--r--resources/grub/config/x60t/grub_serial.cfg71
-rw-r--r--resources/grub/config/x60t/grub_serial_dvorak.cfg71
-rw-r--r--resources/grub/config/x60t/grub_serial_ukdvorak.cfg71
-rw-r--r--resources/grub/config/x60t/grub_serial_ukqwerty.cfg71
-rw-r--r--resources/grub/config/x60t/grub_ukdvorak.cfg57
-rw-r--r--resources/grub/config/x60t/grub_ukqwerty.cfg57
-rw-r--r--resources/grub/font/COPYING3
-rw-r--r--resources/grub/font/dejavusansmono.pf2bin0 -> 100513 bytes
-rw-r--r--resources/grub/keymap/COPYING13
-rw-r--r--resources/grub/keymap/dvorak.gkbbin0 -> 2572 bytes
-rw-r--r--resources/grub/keymap/ukdvorak130
-rw-r--r--resources/grub/keymap/ukdvorak.gkbbin0 -> 2572 bytes
-rw-r--r--resources/grub/keymap/ukqwerty130
-rw-r--r--resources/grub/keymap/ukqwerty.gkbbin0 -> 2572 bytes
-rw-r--r--resources/grub/keymap/usdvorak130
-rw-r--r--resources/grub/keymap/usqwerty130
-rw-r--r--resources/grub/keymap/usqwerty.gkbbin0 -> 2572 bytes
-rw-r--r--resources/grub/patch/COPYING2
-rw-r--r--resources/grub/patch/gitdiff13
-rw-r--r--resources/libreboot/config/COPYING7
-rw-r--r--resources/libreboot/config/macbook21config436
-rw-r--r--resources/libreboot/config/t60config449
-rw-r--r--resources/libreboot/config/x60config452
-rw-r--r--resources/libreboot/config/x60tconfig452
-rw-r--r--resources/libreboot/patch/COPYING6
-rw-r--r--resources/libreboot/patch/gitdiff580
-rw-r--r--resources/memtest86/patch/COPYING6
-rw-r--r--resources/memtest86/patch/diff40
60 files changed, 46104 insertions, 0 deletions
diff --git a/resources/cbfstool/patch/COPYING b/resources/cbfstool/patch/COPYING
new file mode 100644
index 0000000..c4c97fc
--- /dev/null
+++ b/resources/cbfstool/patch/COPYING
@@ -0,0 +1,2 @@
+rmodule.c is from and part of the coreboot project.
+Check coreboot's copyright information to see what conditions apply.
diff --git a/resources/cbfstool/patch/rmodule.c b/resources/cbfstool/patch/rmodule.c
new file mode 100644
index 0000000..989da86
--- /dev/null
+++ b/resources/cbfstool/patch/rmodule.c
@@ -0,0 +1,628 @@
+/*
+ ;* Copyright (C) 2014 Google, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA, 02110-1301 USA
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "elfparsing.h"
+#include "rmodule.h"
+#include "rmodule-defs.h"
+
+struct rmod_context;
+
+struct arch_ops {
+ int arch;
+ /* Determine if relocation is a valid type for the architecture. */
+ int (*valid_type)(struct rmod_context *ctx, Elf64_Rela *rel);
+ /* Determine if relocation should be emitted. */
+ int (*should_emit)(struct rmod_context *ctx, Elf64_Rela *rel);
+};
+
+struct rmod_context {
+ /* Ops to process relocations. */
+ struct arch_ops *ops;
+
+ /* endian conversion ops */
+ struct xdr *xdr;
+
+ /* Parsed ELF sturcture. */
+ struct parsed_elf pelf;
+ /* Program segment. */
+ Elf64_Phdr *phdr;
+
+ /* Collection of relocation addresses fixup in the module. */
+ Elf64_Xword nrelocs;
+ Elf64_Addr *emitted_relocs;
+
+ /* The following fields are addresses within the linked program. */
+ Elf64_Addr link_addr;
+ Elf64_Addr entry;
+ Elf64_Addr parameters_begin;
+ Elf64_Addr parameters_end;
+ Elf64_Addr bss_begin;
+ Elf64_Addr bss_end;
+ Elf64_Xword size;
+};
+
+/*
+ * Architecture specific support operations.
+ */
+static int valid_reloc_386(struct rmod_context *ctx, Elf64_Rela *rel)
+{
+ int type;
+
+ type = ELF64_R_TYPE(rel->r_info);
+
+ /* Only these 2 relocations are expected to be found. */
+ return (type == R_386_32 || type == R_386_PC32);
+}
+
+static int should_emit_386(struct rmod_context *ctx, Elf64_Rela *rel)
+{
+ int type;
+
+ type = ELF64_R_TYPE(rel->r_info);
+
+ /* R_386_32 relocations are absolute. Must emit these. */
+ return (type == R_386_32);
+}
+
+static struct arch_ops reloc_ops[] = {
+ {
+ .arch = EM_386,
+ .valid_type = valid_reloc_386,
+ .should_emit = should_emit_386,
+ },
+};
+
+/*
+ * Relocation processing loops.
+ */
+
+static int for_each_reloc(struct rmod_context *ctx, int do_emit)
+{
+ Elf64_Half i;
+ struct parsed_elf *pelf = &ctx->pelf;
+
+ for (i = 0; i < pelf->ehdr.e_shnum; i++) {
+ Elf64_Shdr *shdr;
+ Elf64_Rela *relocs;
+ Elf64_Xword nrelocs;
+ Elf64_Xword j;
+
+ relocs = pelf->relocs[i];
+
+ /* No relocations in this section. */
+ if (relocs == NULL)
+ continue;
+
+ shdr = &pelf->shdr[i];
+ nrelocs = shdr->sh_size / shdr->sh_entsize;
+
+ for (j = 0; j < nrelocs; j++) {
+ Elf64_Rela *r = &relocs[j];
+
+ if (!ctx->ops->valid_type(ctx, r)) {
+ ERROR("Invalid reloc type: %u\n",
+ (unsigned int)ELF64_R_TYPE(r->r_info));
+ return -1;
+ }
+
+ if (ctx->ops->should_emit(ctx, r)) {
+ int n = ctx->nrelocs;
+ if (do_emit)
+ ctx->emitted_relocs[n] = r->r_offset;
+ ctx->nrelocs++;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int find_program_segment(struct rmod_context *ctx)
+{
+ int i;
+ int nsegments;
+ struct parsed_elf *pelf;
+ Elf64_Phdr *phdr;
+
+ pelf = &ctx->pelf;
+
+ /* There should only be a single loadable segment. */
+ nsegments = 0;
+ for (i = 0; i < pelf->ehdr.e_phnum; i++) {
+ if (pelf->phdr[i].p_type != PT_LOAD)
+ continue;
+ phdr = &pelf->phdr[i];
+ nsegments++;
+ }
+
+ if (nsegments != 1) {
+ ERROR("Unexepcted number of loadable segments: %d.\n",
+ nsegments);
+ return -1;
+ }
+
+ INFO("Segment at 0x%0llx, file size 0x%0llx, mem size 0x%0llx.\n",
+ (long long)phdr->p_vaddr, (long long)phdr->p_filesz,
+ (long long)phdr->p_memsz);
+
+ ctx->phdr = phdr;
+
+ return 0;
+}
+
+static int
+filter_relocation_sections(struct rmod_context *ctx)
+{
+ int i;
+ const char *shstrtab;
+ struct parsed_elf *pelf;
+ const Elf64_Phdr *phdr;
+
+ pelf = &ctx->pelf;
+ phdr = ctx->phdr;
+ shstrtab = buffer_get(pelf->strtabs[pelf->ehdr.e_shstrndx]);
+
+ /*
+ * Find all relocation sections that contain relocation entries
+ * for sections that fall within the bounds of the segment. For
+ * easier processing the pointer to the relocation array for the
+ * sections that don't fall within the loadable program are NULL'd
+ * out.
+ */
+ for (i = 0; i < pelf->ehdr.e_shnum; i++) {
+ Elf64_Shdr *shdr;
+ Elf64_Word sh_info;
+ const char *section_name;
+
+ shdr = &pelf->shdr[i];
+
+ /* Ignore non-relocation sections. */
+ if (shdr->sh_type != SHT_RELA && shdr->sh_type != SHT_REL)
+ continue;
+
+ /* Obtain section which relocations apply. */
+ sh_info = shdr->sh_info;
+ shdr = &pelf->shdr[sh_info];
+
+ section_name = &shstrtab[shdr->sh_name];
+ DEBUG("Relocation section found for '%s' section.\n",
+ section_name);
+
+ /* Do not process relocations for debug sections. */
+ if (strstr(section_name, ".debug") != NULL) {
+ pelf->relocs[i] = NULL;
+ continue;
+ }
+
+ /*
+ * If relocations apply to a non program section ignore the
+ * relocations for future processing.
+ */
+ if (shdr->sh_type != SHT_PROGBITS) {
+ pelf->relocs[i] = NULL;
+ continue;
+ }
+
+ if (shdr->sh_addr < phdr->p_vaddr ||
+ ((shdr->sh_addr + shdr->sh_size) >
+ (phdr->p_vaddr + phdr->p_memsz))) {
+ ERROR("Relocations being applied to section %d not "
+ "within segment region.\n", sh_info);
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+static int vaddr_cmp(const void *a, const void *b)
+{
+ const Elf64_Addr *pa = a;
+ const Elf64_Addr *pb = b;
+
+ if (*pa < *pb)
+ return -1;
+ if (*pa > *pb)
+ return 1;
+ return 0;
+}
+
+static int collect_relocations(struct rmod_context *ctx)
+{
+ int nrelocs;
+
+ /*
+ * The relocs array in the pelf should only contain relocations that
+ * apply to the program. Count the number relocations. Then collect
+ * them into the allocated buffer.
+ */
+ if (for_each_reloc(ctx, 0))
+ return -1;
+
+ nrelocs = ctx->nrelocs;
+ INFO("%d relocations to be emitted.\n", nrelocs);
+ if (!nrelocs) {
+ ERROR("No valid relocations in file.\n");
+ return -1;
+ }
+
+ /* Reset the counter for indexing into the array. */
+ ctx->nrelocs = 0;
+ ctx->emitted_relocs = calloc(nrelocs, sizeof(Elf64_Addr));
+ /* Write out the relocations into the emitted_relocs array. */
+ if (for_each_reloc(ctx, 1))
+ return -1;
+
+ if (ctx->nrelocs != nrelocs) {
+ ERROR("Mismatch counted and emitted relocations: %zu vs %zu.\n",
+ (size_t)nrelocs, (size_t)ctx->nrelocs);
+ return -1;
+ }
+
+ /* Sort the relocations by their address. */
+ qsort(ctx->emitted_relocs, nrelocs, sizeof(Elf64_Addr), vaddr_cmp);
+
+ return 0;
+}
+
+static int
+populate_sym(struct rmod_context *ctx, const char *sym_name, Elf64_Addr *addr,
+ int nsyms, const char *strtab)
+{
+ int i;
+ Elf64_Sym *syms;
+
+ syms = ctx->pelf.syms;
+
+ for (i = 0; i < nsyms; i++) {
+ if (syms[i].st_name == 0)
+ continue;
+ if (strcmp(sym_name, &strtab[syms[i].st_name]))
+ continue;
+ DEBUG("%s -> 0x%llx\n", sym_name, (long long)syms[i].st_value);
+ *addr = syms[i].st_value;
+ return 0;
+ }
+ ERROR("symbol '%s' not found.\n", sym_name);
+ return -1;
+}
+
+static int populate_program_info(struct rmod_context *ctx)
+{
+ int i;
+ const char *strtab;
+ struct parsed_elf *pelf;
+ Elf64_Ehdr *ehdr;
+ int nsyms;
+
+ pelf = &ctx->pelf;
+ ehdr = &pelf->ehdr;
+
+ /* Obtain the string table. */
+ strtab = NULL;
+ for (i = 0; i < ehdr->e_shnum; i++) {
+ if (ctx->pelf.strtabs[i] == NULL)
+ continue;
+ /* Don't use the section headers' string table. */
+ if (i == ehdr->e_shstrndx)
+ continue;
+ strtab = buffer_get(ctx->pelf.strtabs[i]);
+ break;
+ }
+
+ if (strtab == NULL) {
+ ERROR("No string table found.\n");
+ return -1;
+ }
+
+ /* Determine number of symbols. */
+ nsyms = 0;
+ for (i = 0; i < ehdr->e_shnum; i++) {
+ if (pelf->shdr[i].sh_type != SHT_SYMTAB)
+ continue;
+
+ nsyms = pelf->shdr[i].sh_size / pelf->shdr[i].sh_entsize;
+ break;
+ }
+
+ if (populate_sym(ctx, "_module_params_begin", &ctx->parameters_begin,
+ nsyms, strtab))
+ return -1;
+
+ if (populate_sym(ctx, "_module_params_end", &ctx->parameters_end,
+ nsyms, strtab))
+ return -1;
+
+ if (populate_sym(ctx, "_bss", &ctx->bss_begin, nsyms, strtab))
+ return -1;
+
+ if (populate_sym(ctx, "_ebss", &ctx->bss_end, nsyms, strtab))
+ return -1;
+
+ if (populate_sym(ctx, "__rmodule_entry", &ctx->entry, nsyms, strtab))
+ return -1;
+
+ /* Link address is the virtual address of the program segment. */
+ ctx->link_addr = ctx->phdr->p_vaddr;
+
+ /* The program size is the memsz of the program segment. */
+ ctx->size = ctx->phdr->p_memsz;
+
+ return 0;
+}
+
+static int
+add_section(struct elf_writer *ew, struct buffer *data, const char *name,
+ Elf64_Addr addr, Elf64_Word size)
+{
+ Elf64_Shdr shdr;
+ int ret;
+
+ memset(&shdr, 0, sizeof(shdr));
+ if (data != NULL) {
+ shdr.sh_type = SHT_PROGBITS;
+ shdr.sh_flags = SHF_ALLOC | SHF_WRITE | SHF_EXECINSTR;
+ } else {
+ shdr.sh_type = SHT_NOBITS;
+ shdr.sh_flags = SHF_ALLOC;
+ }
+ shdr.sh_addr = addr;
+ shdr.sh_offset = addr;
+ shdr.sh_size = size;
+
+ ret = elf_writer_add_section(ew, &shdr, data, name);
+
+ if (ret)
+ ERROR("Could not add '%s' section.\n", name);
+
+ return ret;
+}
+
+static int
+write_elf(const struct rmod_context *ctx, const struct buffer *in,
+ struct buffer *out)
+{
+ int i;
+ int ret;
+ int bit64;
+ size_t loc;
+ size_t rmod_data_size;
+ struct elf_writer *ew;
+ struct buffer rmod_data;
+ struct buffer rmod_header;
+ struct buffer program;
+ struct buffer relocs;
+ Elf64_Xword total_size;
+ Elf64_Addr addr;
+ Elf64_Ehdr ehdr;
+
+ bit64 = ctx->pelf.ehdr.e_ident[EI_CLASS] == ELFCLASS64;
+
+ /*
+ * 3 sections will be added to the ELF file.
+ * +------------------+
+ * | rmodule header |
+ * +------------------+
+ * | program |
+ * +------------------+
+ * | relocations |
+ * +------------------+
+ */
+
+ /* Create buffer for header and relocations. */
+ rmod_data_size = sizeof(struct rmodule_header);
+ if (bit64)
+ rmod_data_size += ctx->nrelocs * sizeof(Elf64_Addr);
+ else
+ rmod_data_size += ctx->nrelocs * sizeof(Elf32_Addr);
+
+ if (buffer_create(&rmod_data, rmod_data_size, "rmod"))
+ return -1;
+
+ buffer_splice(&rmod_header, &rmod_data,
+ 0, sizeof(struct rmodule_header));
+ buffer_clone(&relocs, &rmod_data);
+ buffer_seek(&relocs, sizeof(struct rmodule_header));
+
+ /* Reset current location. */
+ buffer_set_size(&rmod_header, 0);
+ buffer_set_size(&relocs, 0);
+
+ /* Program contents. */
+ buffer_splice(&program, in, ctx->phdr->p_offset, ctx->phdr->p_filesz);
+
+ /* Create ELF writer with modified entry point. */
+ memcpy(&ehdr, &ctx->pelf.ehdr, sizeof(ehdr));
+ ehdr.e_entry = ctx->entry;
+ ew = elf_writer_init(&ehdr);
+
+ if (ew == NULL) {
+ ERROR("Failed to create ELF writer.\n");
+ buffer_delete(&rmod_data);
+ return -1;
+ }
+
+ /* Write out rmodule_header. */
+ ctx->xdr->put16(&rmod_header, RMODULE_MAGIC);
+ ctx->xdr->put8(&rmod_header, RMODULE_VERSION_1);
+ ctx->xdr->put8(&rmod_header, 0);
+ /* payload_begin_offset */
+ loc = sizeof(struct rmodule_header);
+ ctx->xdr->put32(&rmod_header, loc);
+ /* payload_end_offset */
+ loc += ctx->phdr->p_filesz;
+ ctx->xdr->put32(&rmod_header, loc);
+ /* relocations_begin_offset */
+ ctx->xdr->put32(&rmod_header, loc);
+ /* relocations_end_offset */
+ if (bit64)
+ loc += ctx->nrelocs * sizeof(Elf64_Addr);
+ else
+ loc += ctx->nrelocs * sizeof(Elf32_Addr);
+ ctx->xdr->put32(&rmod_header, loc);
+ /* module_link_start_address */
+ ctx->xdr->put32(&rmod_header, ctx->link_addr);
+ /* module_program_size */
+ ctx->xdr->put32(&rmod_header, ctx->size);
+ /* module_entry_point */
+ ctx->xdr->put32(&rmod_header, ctx->entry);
+ /* parameters_begin */
+ ctx->xdr->put32(&rmod_header, ctx->parameters_begin);
+ /* parameters_end */
+ ctx->xdr->put32(&rmod_header, ctx->parameters_end);
+ /* bss_begin */
+ ctx->xdr->put32(&rmod_header, ctx->bss_begin);
+ /* bss_end */
+ ctx->xdr->put32(&rmod_header, ctx->bss_end);
+ /* padding[4] */
+ ctx->xdr->put32(&rmod_header, 0);
+ ctx->xdr->put32(&rmod_header, 0);
+ ctx->xdr->put32(&rmod_header, 0);
+ ctx->xdr->put32(&rmod_header, 0);
+
+ /* Write the relocations. */
+ for (i = 0; i < ctx->nrelocs; i++) {
+ if (bit64)
+ ctx->xdr->put64(&relocs, ctx->emitted_relocs[i]);
+ else
+ ctx->xdr->put32(&relocs, ctx->emitted_relocs[i]);
+ }
+
+ total_size = 0;
+ addr = 0;
+
+ /*
+ * There are 2 cases to deal with. The program has a large NOBITS
+ * section and the relocations can fit entirely within occupied memory
+ * region for the program. The other is that the relocations increase
+ * the memory footprint of the program if it was loaded directly into
+ * the region it would run. The rmdoule header is a fixed cost that
+ * is considered a part of the program.
+ */
+ total_size += buffer_size(&rmod_header);
+ total_size += ctx->phdr->p_memsz;
+ if (buffer_size(&relocs) + ctx->phdr->p_filesz > total_size) {
+ total_size -= ctx->phdr->p_memsz;
+ total_size += buffer_size(&relocs);
+ total_size += ctx->phdr->p_filesz;
+ }
+
+ ret = add_section(ew, &rmod_header, ".header", addr,
+ buffer_size(&rmod_header));
+ if (ret < 0)
+ goto out;
+ addr += buffer_size(&rmod_header);
+
+ ret = add_section(ew, &program, ".program", addr, ctx->phdr->p_filesz);
+ if (ret < 0)
+ goto out;
+ addr += ctx->phdr->p_filesz;
+
+ ret = add_section(ew, &relocs, ".relocs", addr, buffer_size(&relocs));
+ if (ret < 0)
+ goto out;
+ addr += buffer_size(&relocs);
+
+ if (total_size != addr) {
+ ret = add_section(ew, NULL, ".empty", addr, total_size - addr);
+ if (ret < 0)
+ goto out;
+ }
+
+ /*
+ * Ensure last section has a memory usage that meets the required
+ * total size of the program in memory.
+ */
+
+ ret = elf_writer_serialize(ew, out);
+ if (ret < 0)
+ ERROR("Failed to serialize ELF to buffer.\n");
+
+out:
+ buffer_delete(&rmod_data);
+ elf_writer_destroy(ew);
+
+ return ret;
+}
+
+int rmodule_create(const struct buffer *elfin, struct buffer *elfout)
+{
+ struct rmod_context ctx;
+ struct parsed_elf *pelf;
+ int i;
+ int ret;
+
+ ret = -1;
+ memset(&ctx, 0, sizeof(ctx));
+ pelf = &ctx.pelf;
+
+ if (parse_elf(elfin, pelf, ELF_PARSE_ALL)) {
+ ERROR("Couldn't parse ELF!\n");
+ return -1;
+ }
+
+ /* Only allow executables to be turned into rmodules. */
+ if (pelf->ehdr.e_type != ET_EXEC) {
+ ERROR("ELF is not an executable: %u.\n", pelf->ehdr.e_type);
+ goto out;
+ }
+
+ /* Determine if architecture is supported. */
+ for (i = 0; i < ARRAY_SIZE(reloc_ops); i++) {
+ if (reloc_ops[i].arch == pelf->ehdr.e_machine) {
+ ctx.ops = &reloc_ops[i];
+ break;
+ }
+ }
+
+ if (ctx.ops == NULL) {
+ ERROR("ELF is unsupported arch: %u.\n", pelf->ehdr.e_machine);
+ goto out;
+ }
+
+ /* Set the endian ops. */
+ if (ctx.pelf.ehdr.e_ident[EI_DATA] == ELFDATA2MSB)
+ ctx.xdr = &xdr_be;
+ else
+ ctx.xdr = &xdr_le;
+
+ if (find_program_segment(&ctx))
+ goto out;
+
+ if (filter_relocation_sections(&ctx))
+ goto out;
+
+ if (collect_relocations(&ctx))
+ goto out;
+
+ if (populate_program_info(&ctx))
+ goto out;
+
+ if (write_elf(&ctx, elfin, elfout))
+ goto out;
+
+ ret = 0;
+
+out:
+ free(ctx.emitted_relocs);
+ parsed_elf_destroy(pelf);
+ return ret;
+}
diff --git a/resources/flashrom/patch/COPYING b/resources/flashrom/patch/COPYING
new file mode 100644
index 0000000..e9b0d02
--- /dev/null
+++ b/resources/flashrom/patch/COPYING
@@ -0,0 +1,2 @@
+These files are from and part of the flashrom (http://flashrom.org/) project.
+Check the flashrom project's copyright information to see what conditions these files fall under.
diff --git a/resources/flashrom/patch/flashchips.c b/resources/flashrom/patch/flashchips.c
new file mode 100644
index 0000000..bb24bdb
--- /dev/null
+++ b/resources/flashrom/patch/flashchips.c
@@ -0,0 +1,13500 @@
+/*
+ * This file is part of the flashrom project.
+ *
+ * Copyright (C) 2000 Silicon Integrated System Corporation
+ * Copyright (C) 2004 Tyan Corp
+ * Copyright (C) 2005-2008 coresystems GmbH <stepan@openbios.org>
+ * Copyright (C) 2006-2009 Carl-Daniel Hailfinger
+ * Copyright (C) 2009 Sean Nelson <audiohacked@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "flash.h"
+#include "flashchips.h"
+#include "chipdrivers.h"
+
+/**
+ * List of supported flash chips.
+ *
+ * Please keep the list sorted by vendor name and chip family, so that the output of 'flashrom -L' is roughly
+ * alphabetically sorted. Within families keep them in order of density.
+ */
+const struct flashchip flashchips[] = {
+
+ /*
+ * .vendor = Vendor name
+ * .name = Chip name
+ * .bustype = Supported flash bus types (Parallel, LPC...)
+ * .manufacture_id = Manufacturer chip ID
+ * .model_id = Model chip ID
+ * .total_size = Total size in (binary) kbytes
+ * .page_size = Page or eraseblock(?) size in bytes
+ * .tested = Test status
+ * .probe = Probe function
+ * .probe_timing = Probe function delay
+ * .block_erasers[] = Array of erase layouts and erase functions
+ * {
+ * .eraseblocks[] = Array of { blocksize, blockcount }
+ * .block_erase = Block erase function
+ * }
+ * .printlock = Chip lock status function
+ * .unlock = Chip unlock function
+ * .write = Chip write function
+ * .read = Chip read function
+ * .voltage = Voltage range in millivolt
+ */
+
+ {
+ .vendor = "AMD",
+ .name = "Am29F010A/B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29F010B, /* Same as Am29F010A */
+ .total_size = 128,
+ .page_size = 16 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PRE,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {16 * 1024, 8} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "AMD",
+ .name = "Am29F002(N)BB",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29F002BB,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_SHORT_RESET | FEATURE_ADDR_2AA,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {32 * 1024, 1},
+ {64 * 1024, 3},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4750, 5250}, /* 4.75-5.25V for type -55, others 4.5-5.5V */
+ },
+
+ {
+ .vendor = "AMD",
+ .name = "Am29F002(N)BT",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29F002BT,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_EITHER_RESET | FEATURE_ADDR_2AA,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 3},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4750, 5250}, /* 4.75-5.25V for type -55, others 4.5-5.5V */
+ },
+
+ {
+ .vendor = "AMD",
+ .name = "Am29F016D",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29F016D,
+ .total_size = 2 * 1024,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {2048 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "AMD",
+ .name = "Am29F040B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29F040B,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "AMD",
+ .name = "Am29F080B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29F080B,
+ .total_size = 1024,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "AMD",
+ .name = "Am29LV001BB",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29LV001BB,
+ .total_size = 128,
+ .page_size = 64 * 1024, /* unused */
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ {16 * 1024, 7},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* 3.0-3.6V for type -45R, others 2.7-3.6V */
+ },
+
+ {
+ .vendor = "AMD",
+ .name = "Am29LV001BT",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29LV001BT,
+ .total_size = 128,
+ .page_size = 64 * 1024, /* unused */
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 7},
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* 3.0-3.6V for type -45R, others 2.7-3.6V */
+ },
+
+ {
+ .vendor = "AMD",
+ .name = "Am29LV002BB",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29LV002BB,
+ .total_size = 256,
+ .page_size = 64 * 1024, /* unused */
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {32 * 1024, 1},
+ {64 * 1024, 3},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* 3.0-3.6V for type -55, others 2.7-3.6V */
+ },
+
+ {
+ .vendor = "AMD",
+ .name = "Am29LV002BT",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29LV002BT,
+ .total_size = 256,
+ .page_size = 64 * 1024, /* unused */
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 3},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* 3.0-3.6V for type -55, others 2.7-3.6V */
+ },
+
+ {
+ .vendor = "AMD",
+ .name = "Am29LV004BB",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29LV004BB,
+ .total_size = 512,
+ .page_size = 64 * 1024, /* unused */
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {32 * 1024, 1},
+ {64 * 1024, 7},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMD",
+ .name = "Am29LV004BT",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29LV004BT,
+ .total_size = 512,
+ .page_size = 64 * 1024, /* unused */
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 7},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMD",
+ .name = "Am29LV008BB",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29LV008BB,
+ .total_size = 1024,
+ .page_size = 64 * 1024, /* unused */
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {32 * 1024, 1},
+ {64 * 1024, 15},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600} /* 3.0-3.6V for type -70R, others 2.7-3.6V */
+ },
+
+ {
+ .vendor = "AMD",
+ .name = "Am29LV008BT",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29LV008BT,
+ .total_size = 1024,
+ .page_size = 64 * 1024, /* unused */
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 15},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600} /* 3.0-3.6V for type -70R, others 2.7-3.6V */
+ },
+
+ {
+ .vendor = "AMD",
+ .name = "Am29LV040B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29LV040B,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_OK_PRE,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* 3.0-3.6V for type -60R, others 2.7-3.6V*/
+ },
+
+ {
+ .vendor = "AMD",
+ .name = "Am29LV081B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29LV080B,
+ .total_size = 1024,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET, /* datasheet specifies address as don't care */
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* 3.0-3.6V for type -70R, others 2.7-3.6V */
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L05PT",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID,
+ .model_id = AMIC_A25L05PT,
+ .total_size = 64,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid4,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {32 * 1024, 1},
+ {16 * 1024, 1},
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp1_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L05PU",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID,
+ .model_id = AMIC_A25L05PU,
+ .total_size = 64,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid4,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ {16 * 1024, 1},
+ {32 * 1024, 1},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp1_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L10PT",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID,
+ .model_id = AMIC_A25L10PT,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid4,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 1},
+ {32 * 1024, 1},
+ {16 * 1024, 1},
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp1_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L10PU",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID,
+ .model_id = AMIC_A25L10PU,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid4,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ {16 * 1024, 1},
+ {32 * 1024, 1},
+ {64 * 1024, 1},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp1_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L20PT",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID,
+ .model_id = AMIC_A25L20PT,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid4,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 3},
+ {32 * 1024, 1},
+ {16 * 1024, 1},
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp1_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L20PU",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID,
+ .model_id = AMIC_A25L20PU,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid4,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ {16 * 1024, 1},
+ {32 * 1024, 1},
+ {64 * 1024, 3},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp1_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ /* The A25L40P{T,U} chips are distinguished by their
+ * erase block layouts, but without any distinction in RDID.
+ * This inexplicable quirk was verified by Rudolf Marek
+ * and discussed on the flashrom mailing list on 2010-07-12.
+ */
+ {
+ .vendor = "AMIC",
+ .name = "A25L40PT",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID,
+ .model_id = AMIC_A25L40PT,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PR,
+ .probe = probe_spi_rdid4,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 7},
+ {32 * 1024, 1},
+ {16 * 1024, 1},
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L40PU",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID,
+ .model_id = AMIC_A25L40PU,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PR,
+ .probe = probe_spi_rdid4,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ {16 * 1024, 1},
+ {32 * 1024, 1},
+ {64 * 1024, 7},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L80P",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID,
+ .model_id = AMIC_A25L80P,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PRE,
+ .probe = probe_spi_rdid4,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ {16 * 1024, 1},
+ {32 * 1024, 1},
+ {64 * 1024, 15},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L16PT",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID,
+ .model_id = AMIC_A25L16PT,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid4,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 31},
+ {32 * 1024, 1},
+ {16 * 1024, 1},
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2048 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2048 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L16PU",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID,
+ .model_id = AMIC_A25L16PU,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PR,
+ .probe = probe_spi_rdid4,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ {16 * 1024, 1},
+ {32 * 1024, 1},
+ {64 * 1024, 31},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2048 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2048 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L512",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID_NOPREFIX,
+ .model_id = AMIC_A25L512,
+ .total_size = 64,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { { 4 * 1024, 16 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { { 64 * 1024, 1 } },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 64 * 1024, 1 } },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L010",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID_NOPREFIX,
+ .model_id = AMIC_A25L010,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { { 4 * 1024, 32 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { { 64 * 1024, 2 } },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 128 * 1024, 1 } },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L020",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID_NOPREFIX,
+ .model_id = AMIC_A25L020,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { { 4 * 1024, 64 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { { 64 * 1024, 4 } },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 256 * 1024, 1 } },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L040",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID_NOPREFIX,
+ .model_id = AMIC_A25L040,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { { 4 * 1024, 128 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { { 64 * 1024, 8 } },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 512 * 1024, 1 } },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L080",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID_NOPREFIX,
+ .model_id = AMIC_A25L080,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { { 4 * 1024, 256 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { { 64 * 1024, 16 } },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 1024 * 1024, 1 } },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L016",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID_NOPREFIX,
+ .model_id = AMIC_A25L016,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { { 4 * 1024, 512 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { { 64 * 1024, 32 } },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 2048 * 1024, 1 } },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L032",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID_NOPREFIX,
+ .model_id = AMIC_A25L032,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 64B total; read 0x4B, 0x48; write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { { 4 * 1024, 1024 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { { 64 * 1024, 64 } },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { { 64 * 1024, 64 } },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 4096 * 1024, 1 } },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { { 4096 * 1024, 1 } },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_amic_a25l032, /* bit5: T/B, bit6: prot size */
+ .unlock = spi_disable_blockprotect_bp2_srwd, /* TODO: 2nd status reg (read with 0x35) */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25LQ16",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID_NOPREFIX,
+ .model_id = AMIC_A25LQ16,
+ .total_size = 2048,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 64B total; read 0x4B, 0x48; write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { { 4 * 1024, 512 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { { 64 * 1024, 32 } },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { { 64 * 1024, 32 } },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 2048 * 1024, 1 } },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { { 2048 * 1024, 1 } },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_amic_a25l032, /* bit5: T/B, bit6: prot size */
+ .unlock = spi_disable_blockprotect_bp2_srwd, /* TODO: 2nd status reg (read with 0x35) */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25LQ032/A25LQ32A",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID_NOPREFIX,
+ .model_id = AMIC_A25LQ032,
+ .total_size = 4096,
+ .page_size = 256,
+ /* A25LQ32A supports SFDP */
+ /* OTP: 64B total; read 0x4B, 0x48; write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { { 4 * 1024, 1024 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { { 64 * 1024, 64 } },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { { 64 * 1024, 64 } },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 4096 * 1024, 1 } },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { { 4096 * 1024, 1 } },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_amic_a25l032, /* bit5: T/B, bit6: prot size */
+ .unlock = spi_disable_blockprotect_bp2_srwd, /* TODO: 2nd status reg (read with 0x35) */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25LQ64",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID_NOPREFIX,
+ .model_id = AMIC_A25LQ032,
+ .total_size = 8192,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 512B total; enter 0xB1, exit 0xC1 */
+ /* QPI enable 0x35, disable 0xF5 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { { 4 * 1024, 2048 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { { 32 * 1024, 256 } },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { { 64 * 1024, 128 } },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 8192 * 1024, 1 } },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { { 8192 * 1024, 1 } },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6 is quad enhance (sic!) */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A29002B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMIC_ID_NOPREFIX,
+ .model_id = AMIC_A29002B,
+ .total_size = 256,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {32 * 1024, 1},
+ {64 * 1024, 3},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A29002T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMIC_ID_NOPREFIX,
+ .model_id = AMIC_A29002T,
+ .total_size = 256,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 3},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A29040B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMIC_ID_NOPREFIX,
+ .model_id = AMIC_A29040B,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A49LF040A",
+ .bustype = BUS_LPC,
+ .manufacture_id = AMIC_ID_NOPREFIX,
+ .model_id = AMIC_A49LF040A,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* routine is wrapper to probe_jedec (pm49fl00x.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .unlock = unlock_49fl00x,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25DF021",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25DF021,
+ .total_size = 256,
+ .page_size = 256,
+ /* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 8} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25df,
+ .unlock = spi_disable_blockprotect_at2x_global_unprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600}, /* 2.3-3.6V & 2.7-3.6V models available */
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25DF041A",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25DF041A,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 16} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25df,
+ .unlock = spi_disable_blockprotect_at2x_global_unprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600}, /* 2.3-3.6V & 2.7-3.6V models available */
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25DF081",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25DF081,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 32} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25df,
+ .unlock = spi_disable_blockprotect_at2x_global_unprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {1600, 2000}, /* Datasheet says range is 1.65-1.95 V */
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25DF081A",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25DF081A,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 32} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25df_sec,
+ .unlock = spi_disable_blockprotect_at2x_global_unprotect_sec,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25DF161",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25DF161,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PROBE,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 64} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25df_sec,
+ .unlock = spi_disable_blockprotect_at2x_global_unprotect_sec,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25DF321",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25DF321,
+ .total_size = 4096,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 128} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25df,
+ .unlock = spi_disable_blockprotect_at2x_global_unprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25DF321A",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25DF321A,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 128} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25df_sec,
+ .unlock = spi_disable_blockprotect_at2x_global_unprotect_sec,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25DF641(A)",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25DF641,
+ .total_size = 8192,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 2048} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 256} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25df_sec,
+ .unlock = spi_disable_blockprotect_at2x_global_unprotect_sec,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25DL081",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25DF081,
+ .total_size = 1024,
+ .page_size = 256,
+ /* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 32} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25df_sec,
+ .unlock = spi_disable_blockprotect_at2x_global_unprotect_sec,
+ .write = spi_chip_write_256, /* Dual I/O (0xA2) supported */
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O (0x3B) supported */
+ .voltage = {1650, 1950},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25DL161",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25DL161,
+ .total_size = 2048,
+ .page_size = 256,
+ /* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 64} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25df_sec,
+ .unlock = spi_disable_blockprotect_at2x_global_unprotect_sec,
+ .write = spi_chip_write_256, /* Dual I/O (0xA2) supported */
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O (0x3B) supported */
+ .voltage = {1650, 1950},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25DQ161",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25DQ161,
+ .total_size = 2048,
+ .page_size = 256,
+ /* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 64} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25df_sec,
+ .unlock = spi_disable_blockprotect_at2x_global_unprotect_sec,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25F512",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25F512,
+ .total_size = 64,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_at25f,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {32 * 1024, 2} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_62,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25f,
+ .unlock = spi_disable_blockprotect_at25f,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25F512A",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25F512A,
+ .total_size = 64,
+ .page_size = 128,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_at25f,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {32 * 1024, 2} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_62,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25f512a,
+ /* FIXME: It is not correct to use this one, because the BP1 bit is N/A. */
+ .unlock = spi_disable_blockprotect_at25f512a,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25F512B",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25F512B,
+ .total_size = 64,
+ .page_size = 256,
+ /* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 16} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 2} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {32 * 1024, 2} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_62,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25f512b,
+ .unlock = spi_disable_blockprotect_at25f512b,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ /* The A suffix indicates 33MHz instead of 20MHz clock rate.
+ * All other properties seem to be the same.*/
+ .name = "AT25F1024(A)",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25F1024,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_at25f,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_62,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25f,
+ .unlock = spi_disable_blockprotect_at25f,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25F2048",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25F2048,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_at25f,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_62,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25f,
+ .unlock = spi_disable_blockprotect_at25f,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25F4096",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25F4096,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_at25f,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_62,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25f4096,
+ /* "Bits 5-6 are 0s when device is not in an internal write cycle." Better leave them alone: */
+ .unlock = spi_disable_blockprotect_bp2_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25FS010",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25FS010,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25fs010,
+ .unlock = spi_disable_blockprotect_at25fs010,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25FS040",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25FS040,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25fs040,
+ .unlock = spi_disable_blockprotect_at25fs040,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT26DF041",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT26DF041,
+ .total_size = 512,
+ .page_size = 256,
+ /* does not support EWSR nor WREN and has no writable status register bits whatsoever */
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {256, 2048} },
+ .block_erase = spi_block_erase_81,
+ }, {
+ .eraseblocks = { {2 * 1024, 256} },
+ .block_erase = spi_block_erase_50,
+ }, {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain,
+ /* Supports also an incompatible page write (of exactly 256 B) and an auto-erasing write. */
+ .write = spi_chip_write_1,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600}, /* 3.0-3.6V for higher speed, 2.7-3.6V normal */
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT26DF081A",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT26DF081A,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 32} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at26df081a,
+ .unlock = spi_disable_blockprotect_at2x_global_unprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT26DF161",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT26DF161,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PR,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 64} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25df,
+ .unlock = spi_disable_blockprotect_at2x_global_unprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT26DF161A",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT26DF161A,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 64} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at26df081a,
+ .unlock = spi_disable_blockprotect_at2x_global_unprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ /*The AT26DF321 has the same ID as the AT25DF321. */
+ /*{
+ .vendor = "Atmel",
+ .name = "AT26DF321",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT26DF321,
+ .total_size = 4096,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .printlock = spi_prettyprint_status_register_at26df081a,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ },*/
+
+ {
+ .vendor = "Atmel",
+ .name = "AT26F004",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT26F004,
+ .total_size = 512,
+ .page_size = 256,
+ .tested = {.probe = NT, .read = NT, .erase = NT, .write = BAD },
+ .feature_bits = FEATURE_WRSR_WREN,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 16} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .write = NULL /* Incompatible Page write */,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT29C512",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT29C512,
+ .total_size = 64,
+ .page_size = 128,
+ .feature_bits = FEATURE_LONG_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10000, /* 10mS, Enter=Exec */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT29C010A",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT29C010A,
+ .total_size = 128,
+ .page_size = 128,
+ .feature_bits = FEATURE_LONG_RESET,
+ .tested = TEST_OK_PRE,
+ .probe = probe_jedec,
+ .probe_timing = 10000, /* 10mS, Enter=Exec */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec, /* FIXME */
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT29C020",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT29C020,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_LONG_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10000, /* 10ms */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT29C040A",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT29C040A,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_LONG_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = 10000, /* 10 ms */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT45CS1282",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT45CS1282,
+ .total_size = 16896 /* No power of two sizes */,
+ .page_size = 1056 /* No power of two sizes */,
+ /* does not support EWSR nor WREN and has no writable status register bits whatsoever */
+ /* OTP: 128B total, 64B pre-programmed; read 0x77 (4 dummy bytes); write 0x9A (via buffer) */
+ .feature_bits = FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {8 * 1056, 1}, /* sector 0a: opcode 50h */
+ {248 * 1056, 1}, /* sector 0b: opcode 7Ch */
+ {256 * 1056, 63}, /* sectors 1 - 63: opcode 7Ch */
+ },
+ .block_erase = spi_erase_at45cs_sector,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain,
+ .gran = write_gran_1056bytes,
+ .write = spi_write_at45db,
+ .read = spi_read_at45db,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT45DB011D",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT45DB011D,
+ .total_size = 128 /* or 132, determined from status register */,
+ .page_size = 256 /* or 264, determined from status register */,
+ /* does not support EWSR nor WREN and has no writable status register bits whatsoever */
+ /* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+ .feature_bits = FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_at45db,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {256, 512} },
+ .block_erase = spi_erase_at45db_page,
+ }, {
+ .eraseblocks = { {8 * 256, 512/8} },
+ .block_erase = spi_erase_at45db_block,
+ }, {
+ .eraseblocks = {
+ {8 * 256, 1},
+ {120 * 256, 1},
+ {128 * 256, 3},
+ },
+ .block_erase = spi_erase_at45db_sector
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_erase_at45db_chip,
+ }
+ },
+ .unlock = spi_disable_blockprotect_at45db, /* Impossible if locked down or #WP is low */
+ .printlock = spi_prettyprint_status_register_at45db,
+ /* granularity will be set by the probing function. */
+ .write = spi_write_at45db,
+ .read = spi_read_at45db, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT45DB021D",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT45DB021D,
+ .total_size = 256 /* or 264, determined from status register */,
+ .page_size = 256 /* or 264, determined from status register */,
+ /* does not support EWSR nor WREN and has no writable status register bits whatsoever */
+ /* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+ .feature_bits = FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_at45db,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {256, 1024} },
+ .block_erase = spi_erase_at45db_page,
+ }, {
+ .eraseblocks = { {8 * 256, 1024/8} },
+ .block_erase = spi_erase_at45db_block,
+ }, {
+ .eraseblocks = {
+ {8 * 256, 1},
+ {120 * 256, 1},
+ {128 * 256, 7},
+ },
+ .block_erase = spi_erase_at45db_sector
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_erase_at45db_chip,
+ }
+ },
+ .unlock = spi_disable_blockprotect_at45db, /* Impossible if locked down or #WP is low */
+ .printlock = spi_prettyprint_status_register_at45db,
+ /* granularity will be set by the probing function. */
+ .write = spi_write_at45db,
+ .read = spi_read_at45db, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT45DB041D",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT45DB041D,
+ .total_size = 512 /* or 528, determined from status register */,
+ .page_size = 256 /* or 264, determined from status register */,
+ /* does not support EWSR nor WREN and has no writable status register bits whatsoever */
+ /* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+ .feature_bits = FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_at45db,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {256, 2048} },
+ .block_erase = spi_erase_at45db_page,
+ }, {
+ .eraseblocks = { {8 * 256, 2048/8} },
+ .block_erase = spi_erase_at45db_block,
+ }, {
+ .eraseblocks = {
+ {8 * 256, 1},
+ {248 * 256, 1},
+ {256 * 256, 7},
+ },
+ .block_erase = spi_erase_at45db_sector
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_erase_at45db_chip,
+ }
+ },
+ .unlock = spi_disable_blockprotect_at45db, /* Impossible if locked down or #WP is low */
+ .printlock = spi_prettyprint_status_register_at45db,
+ /* granularity will be set by the probing function. */
+ .write = spi_write_at45db,
+ .read = spi_read_at45db, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600}, /* 2.5-3.6V & 2.7-3.6V models available */
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT45DB081D",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT45DB081D,
+ .total_size = 1024 /* or 1056, determined from status register */,
+ .page_size = 256 /* or 264, determined from status register */,
+ /* does not support EWSR nor WREN and has no writable status register bits whatsoever */
+ /* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+ .feature_bits = FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_at45db,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {256, 4096} },
+ .block_erase = spi_erase_at45db_page,
+ }, {
+ .eraseblocks = { {8 * 256, 4096/8} },
+ .block_erase = spi_erase_at45db_block,
+ }, {
+ .eraseblocks = {
+ {8 * 256, 1},
+ {248 * 256, 1},
+ {256 * 256, 15},
+ },
+ .block_erase = spi_erase_at45db_sector
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_erase_at45db_chip,
+ }
+ },
+ .unlock = spi_disable_blockprotect_at45db, /* Impossible if locked down or #WP is low */
+ .printlock = spi_prettyprint_status_register_at45db,
+ /* granularity will be set by the probing function. */
+ .write = spi_write_at45db,
+ .read = spi_read_at45db, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600}, /* 2.5-3.6V & 2.7-3.6V models available */
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT45DB161D",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT45DB161D,
+ .total_size = 2048 /* or 2112, determined from status register */,
+ .page_size = 512 /* or 528, determined from status register */,
+ /* does not support EWSR nor WREN and has no writable status register bits whatsoever */
+ /* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+ .feature_bits = FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_at45db,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {512, 4096} },
+ .block_erase = spi_erase_at45db_page,
+ }, {
+ .eraseblocks = { {8 * 512, 4096/8} },
+ .block_erase = spi_erase_at45db_block,
+ }, {
+ .eraseblocks = {
+ {8 * 512, 1},
+ {248 * 512, 1},
+ {256 * 512, 15},
+ },
+ .block_erase = spi_erase_at45db_sector
+ }, {
+ .eraseblocks = { {2048 * 1024, 1} },
+ .block_erase = spi_erase_at45db_chip,
+ }
+ },
+ .unlock = spi_disable_blockprotect_at45db, /* Impossible if locked down or #WP is low */
+ .printlock = spi_prettyprint_status_register_at45db,
+ /* granularity will be set by the probing function. */
+ .write = spi_write_at45db,
+ .read = spi_read_at45db, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600}, /* 2.5-3.6V & 2.7-3.6V models available */
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT45DB321C",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT45DB321C,
+ .total_size = 4224 /* No power of two sizes */,
+ .page_size = 528 /* No power of two sizes */,
+ /* does not support EWSR nor WREN and has no writable status register bits whatsoever */
+ /* OTP: 128B total, 64B pre-programmed; read 0x77 (4 dummy bytes); write 0x9A (via buffer) */
+ .feature_bits = FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {528, 8192} },
+ .block_erase = spi_erase_at45db_page,
+ }, {
+ .eraseblocks = { {8 * 528, 8192/8} },
+ .block_erase = spi_erase_at45db_block,
+ }, /* Although the datasheets describes sectors (which can be write protected)
+ * there seems to be no erase functions for them.
+ {
+ .eraseblocks = {
+ {8 * 528, 1},
+ {120 * 528, 1},
+ {128 * 528, 63},
+ },
+ .block_erase = spi_erase_at45db_sector
+ }, */ {
+ .eraseblocks = { {4224 * 1024, 1} },
+ .block_erase = spi_erase_at45db_chip,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at45db, /* Bit 0 is undefined, no lockdown */
+ .gran = write_gran_528bytes,
+ .write = spi_write_at45db,
+ .read = spi_read_at45db_e8, /* 3 address and 4 dummy bytes */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT45DB321D",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT45DB321D,
+ .total_size = 4096 /* or 4224, determined from status register */,
+ .page_size = 512 /* or 528, determined from status register */,
+ /* does not support EWSR nor WREN and has no writable status register bits whatsoever */
+ /* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+ .feature_bits = FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_at45db,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {512, 8192} },
+ .block_erase = spi_erase_at45db_page,
+ }, {
+ .eraseblocks = { {8 * 512, 8192/8} },
+ .block_erase = spi_erase_at45db_block,
+ }, {
+ .eraseblocks = {
+ {8 * 512, 1},
+ {120 * 512, 1},
+ {128 * 512, 63},
+ },
+ .block_erase = spi_erase_at45db_sector
+ }, {
+ .eraseblocks = { {4096 * 1024, 1} },
+ .block_erase = spi_erase_at45db_chip,
+ }
+ },
+ .unlock = spi_disable_blockprotect_at45db, /* Impossible if locked down or #WP is low */
+ .printlock = spi_prettyprint_status_register_at45db,
+ /* granularity will be set by the probing function. */
+ .write = spi_write_at45db,
+ .read = spi_read_at45db, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600}, /* 2.5-3.6V & 2.7-3.6V models available */
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT45DB321E",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT45DB321C,
+ .total_size = 4096 /* or 4224, determined from status register */,
+ .page_size = 512 /* or 528, determined from status register */,
+ /* does not support EWSR nor WREN and has no writable status register bits whatsoever */
+ /* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+ .feature_bits = FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_at45db,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {512, 8192} },
+ .block_erase = spi_erase_at45db_page,
+ }, {
+ .eraseblocks = { {8 * 512, 8192/8} },
+ .block_erase = spi_erase_at45db_block,
+ }, {
+ .eraseblocks = {
+ {8 * 512, 1},
+ {120 * 512, 1},
+ {128 * 512, 63},
+ },
+ .block_erase = spi_erase_at45db_sector
+ }, {
+ .eraseblocks = { {4096 * 1024, 1} },
+ .block_erase = spi_erase_at45db_chip,
+ }
+ },
+ .unlock = spi_disable_blockprotect_at45db, /* Impossible if locked down or #WP is low */
+ .printlock = spi_prettyprint_status_register_at45db, /* has a 2nd status register */
+ /* granularity will be set by the probing function. */
+ .write = spi_write_at45db,
+ .read = spi_read_at45db, /* Fast read (0x0B) supported */
+ .voltage = {2500, 3600}, /* 2.3-3.6V & 2.5-3.6V models available */
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT45DB642D",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT45DB642D,
+ .total_size = 8192 /* or 8448, determined from status register */,
+ .page_size = 1024 /* or 1056, determined from status register */,
+ /* does not support EWSR nor WREN and has no writable status register bits whatsoever */
+ /* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+ .feature_bits = FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_at45db,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {1024, 8192} },
+ .block_erase = spi_erase_at45db_page,
+ }, {
+ .eraseblocks = { {8 * 1024, 8192/8} },
+ .block_erase = spi_erase_at45db_block,
+ }, {
+ .eraseblocks = {
+ {8 * 1024, 1},
+ {248 * 1024, 1},
+ {256 * 1024, 31},
+ },
+ .block_erase = spi_erase_at45db_sector
+ }, {
+ .eraseblocks = { {8192 * 1024, 1} },
+ .block_erase = spi_erase_at45db_chip,
+ }
+ },
+ .unlock = spi_disable_blockprotect_at45db, /* Impossible if locked down or #WP is low */
+ .printlock = spi_prettyprint_status_register_at45db,
+ /* granularity will be set by the probing function. */
+ .write = spi_write_at45db,
+ .read = spi_read_at45db, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT49BV512",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT49BV512,
+ .total_size = 64,
+ .page_size = 64,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT49F002(N)",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT49F002N,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {96 * 1024, 1},
+ {128 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT49F002(N)T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT49F002NT,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PR,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {128 * 1024, 1},
+ {96 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT49(H)F010",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT49F010,
+ .total_size = 128,
+ .page_size = 0, /* unused */
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .printlock = printlock_at49f,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT49F020",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT49F020,
+ .total_size = 256,
+ .page_size = 0, /* unused */
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PRE,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ /* Chip features an optional permanent write protection
+ * of the first 8 kB. The erase function is the same as
+ * above, but 00000H to 01FFFH will not be erased.
+ * FIXME: add another eraser when partial erasers are
+ * supported.
+ */
+ },
+ .printlock = printlock_at49f,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT49F040",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT49F040,
+ .total_size = 512,
+ .page_size = 0, /* unused */
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ /* Chip features an optional permanent write protection
+ * of the first 16 kB. The erase function is the same as
+ * above, but 00000H to 03FFFH will not be erased.
+ * FIXME: add another eraser when partial erasers are
+ * supported.
+ */
+ },
+ .printlock = printlock_at49f,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT49F080",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT49F080,
+ .total_size = 1024,
+ .page_size = 0, /* unused */
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ /* Chip features an optional permanent write protection
+ * of the first 16 kB. The erase function is the same as
+ * above, but 00000H to 03FFFH will not be erased.
+ * FIXME: add another eraser when partial erasers are
+ * supported.
+ */
+ },
+ .printlock = printlock_at49f,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ /* 'top' version of AT49F080. equal in all aspects but the boot block address */
+ .vendor = "Atmel",
+ .name = "AT49F080T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT49F080T,
+ .total_size = 1024,
+ .page_size = 0, /* unused */
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ /* Chip features an optional permanent write protection
+ * of the first 16 kB. The erase function is the same as
+ * above, but FC000H to FFFFFH will not be erased.
+ * FIXME: add another eraser when partial erasers are
+ * supported.
+ */
+ },
+ .printlock = printlock_at49f,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT49LH002",
+ .bustype = BUS_LPC | BUS_FWH, /* A/A Mux */
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT49LH002,
+ .total_size = 256,
+ .page_size = 0, /* unused */
+ .feature_bits = FEATURE_REGISTERMAP, /* TODO: LPC OK too? */
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab, /* TODO: 0xff cmd not documented? */
+ .probe_timing = TIMING_FIXME,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 3},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_block_82802ab,
+ }, {
+ .eraseblocks = {
+ {64 * 1024, 4},
+ },
+ .block_erase = NULL, /* TODO: Implement. */
+ },
+ },
+ .printlock = NULL, /* TODO */
+ .unlock = NULL, /* unlock_82802ab() not correct(?) */
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Catalyst",
+ .name = "CAT28F512",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = CATALYST_ID,
+ .model_id = CATALYST_CAT28F512,
+ .total_size = 64,
+ .page_size = 0, /* unused */
+ .feature_bits = 0,
+ .tested = TEST_OK_PR,
+ .probe = probe_jedec, /* FIXME! */
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = NULL, /* TODO */
+ },
+ },
+ .write = NULL, /* TODO */
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Bright",
+ .name = "BM29F040",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = BRIGHT_ID,
+ .model_id = BRIGHT_BM29F040,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PR,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "ESMT",
+ .name = "F49B002UA",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ESMT_ID,
+ .model_id = ESMT_F49B002UA,
+ .total_size = 256,
+ .page_size = 4096,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {128 * 1024, 1},
+ {96 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "ESMT",
+ .name = "F25L008A",
+ .bustype = BUS_SPI,
+ .manufacture_id = ESMT_ID,
+ .model_id = ESMT_F25L008A,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EITHER,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_1,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "ESMT",
+ .name = "F25L32PA",
+ .bustype = BUS_SPI,
+ .manufacture_id = ESMT_ID,
+ .model_id = ESMT_F25L32PA,
+ .total_size = 4096,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EITHER | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_bpl,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B05",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B05,
+ .total_size = 64,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ {16 * 1024, 1},
+ {32 * 1024, 1},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B05T",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B05,
+ .total_size = 64,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {32 * 1024, 1},
+ {16 * 1024, 1},
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B10",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B10,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ {16 * 1024, 1},
+ {32 * 1024, 3},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B10T",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B10,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {32 * 1024, 3},
+ {16 * 1024, 1},
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B20",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B20,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ {16 * 1024, 1},
+ {32 * 1024, 1},
+ {64 * 1024, 3}
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B20T",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B20,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 3},
+ {32 * 1024, 1},
+ {16 * 1024, 1},
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B40",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B40,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ {16 * 1024, 1},
+ {32 * 1024, 1},
+ {64 * 1024, 7}
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B40T",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B40,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 7},
+ {32 * 1024, 1},
+ {16 * 1024, 1},
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B80",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B80,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ {16 * 1024, 1},
+ {32 * 1024, 1},
+ {64 * 1024, 15}
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B80T",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B80,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 15},
+ {32 * 1024, 1},
+ {16 * 1024, 1},
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B16",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B16,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ {16 * 1024, 1},
+ {32 * 1024, 1},
+ {64 * 1024, 31},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B16T",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B16,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 31},
+ {32 * 1024, 1},
+ {16 * 1024, 1},
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B32",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B32,
+ .total_size = 4096,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ {16 * 1024, 1},
+ {32 * 1024, 1},
+ {64 * 1024, 63},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B32T",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B32,
+ .total_size = 4096,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 63},
+ {32 * 1024, 1},
+ {16 * 1024, 1},
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B64",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B64,
+ .total_size = 8192,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ {16 * 1024, 1},
+ {32 * 1024, 1},
+ {64 * 1024, 127},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B64T",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B64,
+ .total_size = 8192,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 127},
+ {32 * 1024, 1},
+ {16 * 1024, 1},
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25F05",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25F05,
+ .total_size = 64,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 16} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 2} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {32 * 1024, 2} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25F10",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25F10,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25F20",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25F20,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25F40",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25F40,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PROBE,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25F80",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25F80,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25F16",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25F16,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25F32",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25F32,
+ .total_size = 4096,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25F64",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25F64,
+ .total_size = 8192,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 2048} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25Q40",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25Q40,
+ .total_size = 512,
+ .page_size = 256,
+ /* OTP: 256B total; enter 0x3A */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25Q80(A)",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25Q80,
+ .total_size = 1024,
+ .page_size = 256,
+ /* OTP: 256B total; enter 0x3A */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ /* Note: EN25D16 is an evil twin which shares the model ID
+ but has different write protection capabilities */
+ .vendor = "Eon",
+ .name = "EN25Q16",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25Q16,
+ .total_size = 2048,
+ .page_size = 256,
+ /* OTP: D16 512B/Q16 128B total; enter 0x3A */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ /* not supported by Q16 version */
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25Q32(A/B)",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25Q32,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 512B total; enter 0x3A */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25Q64",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25Q64,
+ .total_size = 8192,
+ .page_size = 256,
+ /* OTP: 512B total; enter 0x3A */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 2048} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25Q128",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25Q128,
+ .total_size = 16384,
+ .page_size = 256,
+ /* OTP: 512B total; enter 0x3A */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 4096} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 256} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {16 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {16 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25QH16",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25QH16,
+ .total_size = 2048,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 512B total; enter 0x3A */
+ /* QPI enable 0x38, disable 0xFF */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .tested = TEST_OK_PR,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 2048, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 2048, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6 is quad enable */
+ .unlock = spi_disable_blockprotect_bp3_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25QH32",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25QH32,
+ .total_size = 4096,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 512B total; enter 0x3A */
+ /* QPI enable 0x38, disable 0xFF */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 4096, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 4096, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6 is quad enable */
+ .unlock = spi_disable_blockprotect_bp3_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25QH64",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25QH64,
+ .total_size = 8192,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 512B total; enter 0x3A */
+ /* QPI enable 0x38, disable 0xFF */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .tested = TEST_OK_PR,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 2048} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 8192 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { { 8192 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6 is quad enable */
+ .unlock = spi_disable_blockprotect_bp3_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25QH128",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25QH128,
+ .total_size = 16384,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 512B total; enter 0x3A */
+ /* QPI enable 0x38, disable 0xFF */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 4096} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 256} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 16384 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { { 16384 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6 is quad enable */
+ .unlock = spi_disable_blockprotect_bp3_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25S10",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25S10,
+ .total_size = 128,
+ .page_size = 256,
+ /* OTP: 256B total; enter 0x3A */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {1650, 1950},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25S20",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25S20,
+ .total_size = 256,
+ .page_size = 256,
+ /* OTP: 256B total; enter 0x3A */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {1650, 1950},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25S40",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25S40,
+ .total_size = 512,
+ .page_size = 256,
+ /* OTP: 256B total; enter 0x3A */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {1650, 1950},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25S80",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25S80,
+ .total_size = 1024,
+ .page_size = 256,
+ /* OTP: 256B total; enter 0x3A */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {1650, 1950},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25S16",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25S16,
+ .total_size = 2048,
+ .page_size = 256,
+ /* OTP: 512B total; enter 0x3A */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {32 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2048 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2048 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_en25s_wp,
+ .unlock = spi_disable_blockprotect_bp3_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {1650, 1950},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25S32",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25S32,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 512B total; enter 0x3A */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 128} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4096 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4096 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_en25s_wp,
+ .unlock = spi_disable_blockprotect_bp3_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {1650, 1950},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25S64",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25S64,
+ .total_size = 8192,
+ .page_size = 256,
+ /* OTP: 512B total; enter 0x3A */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 2048} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8192 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {8192 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_en25s_wp,
+ .unlock = spi_disable_blockprotect_bp3_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {1650, 1950},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN29F010",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = EON_ID,
+ .model_id = EON_EN29F010,
+ .total_size = 128,
+ .page_size = 128,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PRE,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {16 * 1024, 8} },
+ .block_erase = erase_sector_jedec,
+ },
+ {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN29F002(A)(N)B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = EON_ID,
+ .model_id = EON_EN29F002B,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_ADDR_AAA | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PR,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {32 * 1024, 1},
+ {64 * 1024, 3},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN29F002(A)(N)T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = EON_ID,
+ .model_id = EON_EN29F002T,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_ADDR_AAA | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 3},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN29LV640B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = EON_ID,
+ .model_id = EON_EN29LV640B,
+ .total_size = 8192,
+ .page_size = 8192,
+ .feature_bits = 0,
+ .tested = TEST_OK_PREW,
+ .probe = probe_en29lv640b,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {8 * 1024, 8},
+ {64 * 1024, 127},
+ },
+ .block_erase = erase_block_shifted_jedec,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = erase_chip_block_shifted_jedec,
+ },
+ },
+ .write = write_en29lv640b,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Fujitsu",
+ .name = "MBM29F004BC",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = FUJITSU_ID,
+ .model_id = FUJITSU_MBM29F004BC,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {32 * 1024, 1},
+ {64 * 1024, 7},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = NULL,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Fujitsu",
+ .name = "MBM29F004TC",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = FUJITSU_ID,
+ .model_id = FUJITSU_MBM29F004TC,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 7},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = NULL,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ /* FIXME: this has WORD/BYTE sequences; 2AA for word, 555 for byte */
+ .vendor = "Fujitsu",
+ .name = "MBM29F400BC",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = FUJITSU_ID,
+ .model_id = FUJITSU_MBM29F400BC,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_SHIFTED | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_m29f400bt,
+ .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (m29f400bt.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {32 * 1024, 1},
+ {64 * 1024, 7},
+ },
+ .block_erase = erase_block_shifted_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_shifted_jedec,
+ },
+ },
+ .write = write_m29f400bt,
+ .read = read_memmapped,
+ .voltage = {4750, 5250}, /* 4.75-5.25V for type -55, others 4.5-5.5V */
+ },
+
+ {
+ .vendor = "Fujitsu",
+ .name = "MBM29F400TC",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = FUJITSU_ID,
+ .model_id = FUJITSU_MBM29F400TC,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_SHIFTED | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_m29f400bt,
+ .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (m29f400bt.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 7},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_block_shifted_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_shifted_jedec,
+ },
+ },
+ .write = write_m29f400bt,
+ .read = read_memmapped,
+ .voltage = {4750, 5250}, /* 4.75-5.25V for type -55, others 4.5-5.5V */
+ },
+
+ {
+ .vendor = "Fujitsu",
+ .name = "MBM29LV160BE",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = FUJITSU_ID,
+ .model_id = FUJITSU_MBM29LV160BE,
+ .total_size = 2 * 1024,
+ .page_size = 0,
+ .feature_bits = FEATURE_ADDR_SHIFTED | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_m29f400bt,
+ .probe_timing = TIMING_IGNORED,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {32 * 1024, 1},
+ {64 * 1024, 31},
+ },
+ .block_erase = erase_block_shifted_jedec,
+ }, {
+ .eraseblocks = { {2048 * 1024, 1} },
+ .block_erase = erase_chip_block_shifted_jedec,
+ },
+ },
+ .write = write_m29f400bt, /* Supports a fast mode too */
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* 3.0-3.6V for type -70, others 2.7-3.6V */
+ },
+
+ {
+ .vendor = "Fujitsu",
+ .name = "MBM29LV160TE",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = FUJITSU_ID,
+ .model_id = FUJITSU_MBM29LV160TE,
+ .total_size = 2 * 1024,
+ .page_size = 0,
+ .feature_bits = FEATURE_ADDR_SHIFTED | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_m29f400bt,
+ .probe_timing = TIMING_IGNORED,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 31},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_block_shifted_jedec,
+ }, {
+ .eraseblocks = { {2048 * 1024, 1} },
+ .block_erase = erase_chip_block_shifted_jedec,
+ },
+ },
+ .write = write_m29f400bt, /* Supports a fast mode too */
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* 3.0-3.6V for type -70, others 2.7-3.6V */
+ },
+
+ {
+ .vendor = "GigaDevice",
+ .name = "GD25LQ32",
+ .bustype = BUS_SPI,
+ .manufacture_id = GIGADEVICE_ID,
+ .model_id = GIGADEVICE_GD25LQ32,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 128} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp4_srwd,
+ .unlock = spi_disable_blockprotect_bp4_srwd, /* TODO: 2nd status reg (read with 0x35) */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {1700, 1950},
+ },
+
+ {
+ .vendor = "GigaDevice",
+ .name = "GD25Q512",
+ .bustype = BUS_SPI,
+ .manufacture_id = GIGADEVICE_ID,
+ .model_id = GIGADEVICE_GD25Q512,
+ .total_size = 64,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 16} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 2} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp4_srwd,
+ .unlock = spi_disable_blockprotect_bp4_srwd, /* TODO: 2nd status reg (read with 0x35) */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "GigaDevice",
+ .name = "GD25Q10",
+ .bustype = BUS_SPI,
+ .manufacture_id = GIGADEVICE_ID,
+ .model_id = GIGADEVICE_GD25Q10,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 2} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp4_srwd,
+ .unlock = spi_disable_blockprotect_bp4_srwd, /* TODO: 2nd status reg (read with 0x35) */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "GigaDevice",
+ .name = "GD25Q20(B)",
+ .bustype = BUS_SPI,
+ .manufacture_id = GIGADEVICE_ID,
+ .model_id = GIGADEVICE_GD25Q20,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 8} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp4_srwd,
+ .unlock = spi_disable_blockprotect_bp4_srwd, /* TODO: 2nd status reg (read with 0x35) */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "GigaDevice",
+ .name = "GD25Q40(B)",
+ .bustype = BUS_SPI,
+ .manufacture_id = GIGADEVICE_ID,
+ .model_id = GIGADEVICE_GD25Q40,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 16} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp4_srwd,
+ .unlock = spi_disable_blockprotect_bp4_srwd, /* TODO: 2nd status reg (read with 0x35) */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "GigaDevice",
+ .name = "GD25Q80(B)",
+ .bustype = BUS_SPI,
+ .manufacture_id = GIGADEVICE_ID,
+ .model_id = GIGADEVICE_GD25Q80,
+ .total_size = 1024,
+ .page_size = 256,
+ /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44 (B version only) */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 32} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp4_srwd,
+ .unlock = spi_disable_blockprotect_bp4_srwd, /* TODO: 2nd status reg (read with 0x35) */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "GigaDevice",
+ .name = "GD25Q16(B)",
+ .bustype = BUS_SPI,
+ .manufacture_id = GIGADEVICE_ID,
+ .model_id = GIGADEVICE_GD25Q16,
+ .total_size = 2048,
+ .page_size = 256,
+ /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44 (B version only) */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 64} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp4_srwd,
+ .unlock = spi_disable_blockprotect_bp4_srwd, /* TODO: 2nd status reg (read with 0x35) */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "GigaDevice",
+ .name = "GD25Q32(B)",
+ .bustype = BUS_SPI,
+ .manufacture_id = GIGADEVICE_ID,
+ .model_id = GIGADEVICE_GD25Q32,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 128} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp4_srwd,
+ .unlock = spi_disable_blockprotect_bp4_srwd, /* TODO: 2nd status reg (read with 0x35) */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "GigaDevice",
+ .name = "GD25Q64(B)",
+ .bustype = BUS_SPI,
+ .manufacture_id = GIGADEVICE_ID,
+ .model_id = GIGADEVICE_GD25Q64,
+ .total_size = 8192,
+ .page_size = 256,
+ /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 2048} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 256} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp4_srwd,
+ .unlock = spi_disable_blockprotect_bp4_srwd, /* TODO: 2nd status reg (read with 0x35) */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "GigaDevice",
+ .name = "GD25Q128B",
+ .bustype = BUS_SPI,
+ .manufacture_id = GIGADEVICE_ID,
+ .model_id = GIGADEVICE_GD25Q128,
+ .total_size = 16384,
+ .page_size = 256,
+ /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 4096} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 512} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 256} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {16 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {16 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp4_srwd,
+ .unlock = spi_disable_blockprotect_bp4_srwd, /* TODO: 2nd status reg (read with 0x35) */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "GigaDevice",
+ .name = "GD25T80",
+ .bustype = BUS_SPI,
+ .manufacture_id = GIGADEVICE_ID,
+ .model_id = GIGADEVICE_GD25T80,
+ .total_size = 1024,
+ .page_size = 256,
+ /* OTP: 256B total; enter 0x3A */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Hyundai",
+ .name = "HY29F002T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = HYUNDAI_ID,
+ .model_id = HYUNDAI_HY29F002T,
+ .total_size = 256,
+ .page_size = 256 * 1024,
+ .feature_bits = FEATURE_EITHER_RESET, /* Some revisions may need FEATURE_ADDR_2AA */
+ .tested = TEST_OK_PRE,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 3},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4750, 5250}, /* 4.75-5.25V for type -45, others 4.5-5.5V */
+ },
+
+ {
+ .vendor = "Hyundai",
+ .name = "HY29F002B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = HYUNDAI_ID,
+ .model_id = HYUNDAI_HY29F002B,
+ .total_size = 256,
+ .page_size = 256 * 1024,
+ .feature_bits = FEATURE_EITHER_RESET, /* Some revisions may need FEATURE_ADDR_2AA */
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {32 * 1024, 1},
+ {64 * 1024, 3},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4750, 5250}, /* 4.75-5.25V for type -45, others 4.5-5.5V */
+ },
+
+ {
+ .vendor = "Hyundai",
+ .name = "HY29F040A",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = HYUNDAI_ID,
+ .model_id = HYUNDAI_HY29F040A,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "25F160S33B8",
+ .bustype = BUS_SPI,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_25F160S33B8,
+ .total_size = 2048,
+ .page_size = 256,
+ /* OTP: 506B total (2x 8B, 30x 16B, 1x 10B); read 0x4B; write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ /* This chip supports erasing of the 8 so-called "parameter blocks" with
+ * opcode 0x40. Trying to access an address outside these 8 8kB blocks does
+ * have no effect on the memory contents, but sets a flag in the SR.
+ .eraseblocks = {
+ {8 * 1024, 8},
+ {64 * 1024, 31} // inaccessible
+ },
+ .block_erase = spi_block_erase_40,
+ }, { */
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_ep_srwd,
+ .unlock = spi_disable_blockprotect_bp2_ep_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* also fast read 0x0B */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "25F160S33T8",
+ .bustype = BUS_SPI,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_25F160S33T8,
+ .total_size = 2048,
+ .page_size = 256,
+ /* OTP: 506B total (2x 8B, 30x 16B, 1x 10B); read 0x4B; write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ /* This chip supports erasing of the 8 so-called "parameter blocks" with
+ * opcode 0x40. Trying to access an address outside these 8 8kB blocks does
+ * have no effect on the memory contents, but sets a flag in the SR.
+ .eraseblocks = {
+ {64 * 1024, 31}, // inaccessible
+ {8 * 1024, 8}
+ },
+ .block_erase = spi_block_erase_40,
+ }, { */
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_ep_srwd,
+ .unlock = spi_disable_blockprotect_bp2_ep_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* also fast read 0x0B */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "25F320S33B8",
+ .bustype = BUS_SPI,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_25F320S33B8,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 506B total (2x 8B, 30x 16B, 1x 10B); read 0x4B; write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ /* This chip supports erasing of the 8 so-called "parameter blocks" with
+ * opcode 0x40. Trying to access an address outside these 8 8kB blocks does
+ * have no effect on the memory contents, but sets a flag in the SR.
+ .eraseblocks = {
+ {8 * 1024, 8},
+ {64 * 1024, 63} // inaccessible
+ },
+ .block_erase = spi_block_erase_40,
+ }, { */
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_ep_srwd,
+ .unlock = spi_disable_blockprotect_bp2_ep_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* also fast read 0x0B */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "25F320S33T8",
+ .bustype = BUS_SPI,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_25F320S33T8,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 506B total (2x 8B, 30x 16B, 1x 10B); read 0x4B; write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ /* This chip supports erasing of the 8 so-called "parameter blocks" with
+ * opcode 0x40. Trying to access an address outside these 8 8kB blocks does
+ * have no effect on the memory contents, but sets a flag in the SR.
+ .eraseblocks = {
+ {64 * 1024, 63}, // inaccessible
+ {8 * 1024, 8}
+ },
+ .block_erase = spi_block_erase_40,
+ }, { */
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_ep_srwd,
+ .unlock = spi_disable_blockprotect_bp2_ep_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* also fast read 0x0B */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "25F640S33B8",
+ .bustype = BUS_SPI,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_25F640S33B8,
+ .total_size = 8192,
+ .page_size = 256,
+ /* OTP: 506B total (2x 8B, 30x 16B, 1x 10B); read 0x4B; write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ /* This chip supports erasing of the 8 so-called "parameter blocks" with
+ * opcode 0x40. Trying to access an address outside these 8 8kB blocks does
+ * have no effect on the memory contents, but sets a flag in the SR.
+ .eraseblocks = {
+ {8 * 1024, 8},
+ {64 * 1024, 127} // inaccessible
+ },
+ .block_erase = spi_block_erase_40,
+ }, { */
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_ep_srwd,
+ .unlock = spi_disable_blockprotect_bp2_ep_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* also fast read 0x0B */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "25F640S33T8",
+ .bustype = BUS_SPI,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_25F640S33T8,
+ .total_size = 8192,
+ .page_size = 256,
+ /* OTP: 506B total (2x 8B, 30x 16B, 1x 10B); read 0x4B; write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ /* This chip supports erasing of the 8 so-called "parameter blocks" with
+ * opcode 0x40. Trying to access an address outside these 8 8kB blocks does
+ * have no effect on the memory contents, but sets a flag in the SR.
+ .eraseblocks = {
+ {64 * 1024, 127}, // inaccessible
+ {8 * 1024, 8}
+ },
+ .block_erase = spi_block_erase_40,
+ }, { */
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_ep_srwd,
+ .unlock = spi_disable_blockprotect_bp2_ep_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* also fast read 0x0B */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "28F001BN/BX-B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_28F001B,
+ .total_size = 128,
+ .page_size = 128 * 1024, /* 8k + 2x4k + 112k */
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ {112 * 1024, 1},
+ },
+ .block_erase = erase_block_82802ab,
+ },
+ },
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "28F001BN/BX-T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_28F001T,
+ .total_size = 128,
+ .page_size = 128 * 1024, /* 112k + 2x4k + 8k */
+ .tested = TEST_OK_PR,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {112 * 1024, 1},
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ },
+ .block_erase = erase_block_82802ab,
+ },
+ },
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "28F002BC/BL/BV/BX-T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_28F002T,
+ .total_size = 256,
+ .page_size = 256 * 1024,
+ .tested = TEST_OK_PRE,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {128 * 1024, 1},
+ {96 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_block_82802ab,
+ },
+ },
+ .write = write_82802ab,
+ .read = read_memmapped,
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "28F008S3/S5/SC",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_28F004S3,
+ .total_size = 512,
+ .page_size = 256,
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_block_82802ab,
+ },
+ },
+ .unlock = unlock_28f004s5,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "28F004B5/BE/BV/BX-B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_28F004B,
+ .total_size = 512,
+ .page_size = 128 * 1024, /* maximal block size */
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {96 * 1024, 1},
+ {128 * 1024, 3},
+ },
+ .block_erase = erase_block_82802ab,
+ },
+ },
+ .write = write_82802ab,
+ .read = read_memmapped,
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "28F004B5/BE/BV/BX-T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_28F004T,
+ .total_size = 512,
+ .page_size = 128 * 1024, /* maximal block size */
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {128 * 1024, 3},
+ {96 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_block_82802ab,
+ },
+ },
+ .write = write_82802ab,
+ .read = read_memmapped,
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "28F400BV/BX/CE/CV-B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_28F400B,
+ .total_size = 512,
+ .page_size = 128 * 1024, /* maximal block size */
+ .feature_bits = FEATURE_ADDR_SHIFTED,
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {96 * 1024, 1},
+ {128 * 1024, 3},
+ },
+ .block_erase = erase_block_82802ab,
+ },
+ },
+ .write = write_82802ab,
+ .read = read_memmapped,
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "28F400BV/BX/CE/CV-T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_28F400T,
+ .total_size = 512,
+ .page_size = 128 * 1024, /* maximal block size */
+ .feature_bits = FEATURE_ADDR_SHIFTED,
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {128 * 1024, 3},
+ {96 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_block_82802ab,
+ },
+ },
+ .write = write_82802ab,
+ .read = read_memmapped,
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "82802AB",
+ .bustype = BUS_FWH,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_82802AB,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_IGNORED, /* routine does not use probe_timing (82802ab.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_block_82802ab,
+ },
+ },
+ .unlock = unlock_82802ab,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "82802AC",
+ .bustype = BUS_FWH,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_82802AC,
+ .total_size = 1024,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_OK_PR,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_IGNORED, /* routine does not use probe_timing (82802ab.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = erase_block_82802ab,
+ },
+ },
+ .unlock = unlock_82802ab,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX23L3254",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX23L3254,
+ .total_size = 4096,
+ .page_size = 256,
+ .tested = {.probe = OK, .read = OK, .erase = NA, .write = NA},
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .write = NULL, /* MX23L3254 is a mask ROM, so it is read-only */
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L512(E)/MX25V512(C)",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L512,
+ .total_size = 64,
+ .page_size = 256,
+ /* MX25L512E supports SFDP */
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 16} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_bp1_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported, MX25L512E supports dual I/O */
+ .voltage = {2700, 3600}, /* 2.35-3.6V for MX25V512(C) */
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L1005(C)/MX25L1006E",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L1005,
+ .total_size = 128,
+ .page_size = 256,
+ /* MX25L1006E supports SFDP */
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 2} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_bp1_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported, MX25L1006E supports dual I/O */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L2005(C)",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L2005,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_bp1_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L4005(A/C)",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L4005,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L8005/MX25V8005",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L8005,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600}, /* 2.35-3.6V for MX25V8005 */
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L1605D/MX25L1608D/MX25L1673E",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L1605,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6: Continously Program (CP) mode */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L1635D",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L1635D,
+ .total_size = 2048,
+ .page_size = 256,
+ /* OTP: 64B total; enter 0xB1, exit 0xC1 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6 is quad enable */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L1635E",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L1635E,
+ .total_size = 2048,
+ .page_size = 256,
+ /* OTP: 64B total; enter 0xB1, exit 0xC1 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6 is quad enable */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L3205(A)",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L3205,
+ .total_size = 4096,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd, /* bit6: error flag */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L3205D/MX25L3208D",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L3205,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 64B total; enter 0xB1, exit 0xC1 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6: CP mode */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and dual I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L3206E",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L3205,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 64B total; enter 0xB1, exit 0xC1 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and dual I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L3273E",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L3205,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 64B total; enter 0xB1, exit 0xC1 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 128} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and dual I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L3235D",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L3235D,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 256B total; enter 0xB1, exit 0xC1 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6 is quad enable */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L6405(D)",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L6405,
+ .total_size = 8192,
+ .page_size = 256,
+ /* MX25L6405D has 64B of OTP; enter 0xB1, exit 0xC1 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6 has different meanings */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L6406E/MX25L6436E",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L6405,
+ .total_size = 8192,
+ .page_size = 256,
+ /* OTP: 06E 64B/36E 512B total; enter 0xB1, exit 0xC1 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 2048} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6 for 36E is quad enable */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L6445E/MX25L6473E",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L6405,
+ .total_size = 8192,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 512B total; enter 0xB1, exit 0xC1 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 2048} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 256} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6 is quad enable */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L12805(D)",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L12805,
+ .total_size = 16384,
+ .page_size = 256,
+ /* MX25L12805D has 64B of OTP; enter 0xB1, exit 0xC1 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 4096} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 256} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {16 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {16 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* MX25L12805D: Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25U1635E",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25U1635E,
+ .total_size = 2048,
+ .page_size = 256,
+ /* OTP: 512B total; enter 0xB1, exit 0xC1 */
+ /* QPI enable 0x35, disable 0xF5 (0xFF et al. work too) */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 64} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ /* TODO: security register */
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6 is quad enable */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {1650, 2000},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25U3235E/F",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25U3235E,
+ .total_size = 4096,
+ .page_size = 256,
+ /* F model supports SFDP */
+ /* OTP: 512B total; enter 0xB1, exit 0xC1 */
+ /* QPI enable 0x35, disable 0xF5 (0xFF et al. work too) */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 128} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ /* TODO: security register */
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6 is quad enable */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {1650, 2000},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25U6435E/F",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25U6435E,
+ .total_size = 8192,
+ .page_size = 256,
+ /* F model supports SFDP */
+ /* OTP: 512B total; enter 0xB1, exit 0xC1 */
+ /* QPI enable 0x35, disable 0xF5 (0xFF et al. work too) */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 2048} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 256} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ /* TODO: security register */
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6 is quad enable */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {1650, 2000},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX29F001B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX29F001B,
+ .total_size = 128,
+ .page_size = 32 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ {8 * 1024, 2},
+ {32 * 1024, 1},
+ {64 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX29F001T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX29F001T,
+ .total_size = 128,
+ .page_size = 32 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 1},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX29F002(N)B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX29F002B,
+ .total_size = 256,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {32 * 1024, 1},
+ {64 * 1024, 3},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX29F002(N)T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX29F002T,
+ .total_size = 256,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 3},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX29F040",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX29F040,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX29LV040",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX29LV040,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8}, },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25P05-A",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25P05A,
+ .total_size = 64,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {32 * 1024, 2} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ /* The ST M25P05 is a bit of a problem. It has the same ID as the
+ * ST M25P05-A in RES mode, but supports only 128 byte writes instead
+ * of 256 byte writes. We rely heavily on the fact that probe_spi_res1
+ * only is successful if RDID does not work.
+ */
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25P05",
+ .bustype = BUS_SPI,
+ .manufacture_id = 0, /* Not used. */
+ .model_id = ST_M25P05_RES,
+ .total_size = 64,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_res1,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {32 * 1024, 2} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_1, /* 128 */
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25P10-A",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25P10A,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PRE,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ /* The ST M25P10 has the same problem as the M25P05. */
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25P10",
+ .bustype = BUS_SPI,
+ .manufacture_id = 0, /* Not used. */
+ .model_id = ST_M25P10_RES,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_res1,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_1, /* 128 */
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST", /* Numonyx */
+ .name = "M25P20",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25P20,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp1_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25P20-old",
+ .bustype = BUS_SPI,
+ .manufacture_id = 0, /* Not used. */
+ .model_id = ST_M25P20_RES,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_res1,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp1_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST", /* Numonyx */
+ .name = "M25P40",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25P40,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25P40-old",
+ .bustype = BUS_SPI,
+ .manufacture_id = 0, /* Not used. */
+ .model_id = ST_M25P40_RES,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_res1,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25P80",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25P80,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25P16",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25P16,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25P32",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25P32,
+ .total_size = 4096,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25P64",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25P64,
+ .total_size = 8192,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25P128",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25P128,
+ .total_size = 16384,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {256 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {16 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25PE10",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25PE10,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 2} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25PE20",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25PE20,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25PE40",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25PE40,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25PE80",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25PE80,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25PE16",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25PE16,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25PX80",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25PX80,
+ .total_size = 1024,
+ .page_size = 256,
+ /* OTP: 64B total; read 0x4B, write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { { 4 * 1024, 256 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd, /* bit5: T/B */
+ .unlock = spi_disable_blockprotect_bp2_srwd, /* TODO: per 64kB sector lock registers */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25PX16",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25PX16,
+ .total_size = 2048,
+ .page_size = 256,
+ /* OTP: 64B total; read 0x4B; write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { { 4 * 1024, 512 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd, /* bit5: T/B */
+ .unlock = spi_disable_blockprotect_bp2_srwd, /* TODO: per 64kB sector lock registers */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2300, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25PX32",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25PX32,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 64B total; read 0x4B; write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PRE,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { { 4 * 1024, 1024 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd, /* bit5: T/B */
+ .unlock = spi_disable_blockprotect_bp2_srwd, /* TODO: per 64kB sector lock registers */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25PX64",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25PX64,
+ .total_size = 8192,
+ .page_size = 256,
+ /* OTP: 64B total; read 0x4B; write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { { 4 * 1024, 2048 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd, /* bit5: T/B */
+ .unlock = spi_disable_blockprotect_bp2_srwd, /* TODO: per 64kB sector lock registers */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M45PE10",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M45PE10,
+ .total_size = 128,
+ .page_size = 256,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {256, 512} },
+ .block_erase = spi_block_erase_db,
+ }, {
+ .eraseblocks = { {64 * 1024, 2} },
+ .block_erase = spi_block_erase_d8,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_default_welwip,
+ .unlock = NULL, /* #WP pin write-protects lower 64kB. */
+ .write = spi_chip_write_256, /* Page write (similar to PP but allows 0->1 changes) */
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M45PE20",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M45PE20,
+ .total_size = 256,
+ .page_size = 256,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {256, 1024} },
+ .block_erase = spi_block_erase_db,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_default_welwip,
+ .unlock = NULL, /* #WP pin write-protects lower 64kB. */
+ .write = spi_chip_write_256, /* Page write (similar to PP but allows 0->1 changes) */
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M45PE40",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M45PE40,
+ .total_size = 512,
+ .page_size = 256,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {256, 2048} },
+ .block_erase = spi_block_erase_db,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_default_welwip,
+ .unlock = NULL, /* #WP pin write-protects lower 64kB. */
+ .write = spi_chip_write_256, /* Page write (similar to PP but allows 0->1 changes) */
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M45PE80",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M45PE80,
+ .total_size = 1024,
+ .page_size = 256,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {256, 4096} },
+ .block_erase = spi_block_erase_db,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_default_welwip,
+ .unlock = NULL, /* #WP pin write-protects lower 64kB. */
+ .write = spi_chip_write_256, /* Page write (similar to PP but allows 0->1 changes) */
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M45PE16",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M45PE16,
+ .total_size = 2048,
+ .page_size = 256,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {256, 8192} },
+ .block_erase = spi_block_erase_db,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_default_welwip,
+ .unlock = NULL, /* #WP pin write-protects lower 64kB. */
+ .write = spi_chip_write_256, /* Page write (similar to PP but allows 0->1 changes) */
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "N25Q016",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_N25Q016__1E,
+ .total_size = 2048,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 64B total; read 0x4B, write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 64} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_n25q, /* TODO: config, lock, flag regs */
+ .unlock = spi_disable_blockprotect_n25q, /* TODO: per 64kB sector lock registers */
+ .write = spi_chip_write_256, /* Multi I/O supported */
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {1700, 2000},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "N25Q032..1E",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_N25Q032__1E,
+ .total_size = 4096,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 64B total; read 0x4B, write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_n25q, /* TODO: config, lock, flag regs */
+ .unlock = spi_disable_blockprotect_n25q, /* TODO: per 64kB sector lock registers */
+ .write = spi_chip_write_256, /* Multi I/O supported */
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {1700, 2000},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "N25Q032..3E",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_N25Q032__3E,
+ .total_size = 4096,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 64B total; read 0x4B, write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_n25q, /* TODO: config, lock, flag regs */
+ .unlock = spi_disable_blockprotect_n25q, /* TODO: per 64kB sector lock registers */
+ .write = spi_chip_write_256, /* Multi I/O supported */
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "N25Q064..1E", /* ..1E = 1.8V, uniform 64KB/4KB blocks/sectors */
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_N25Q064__1E,
+ .total_size = 8192,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 64B total; read 0x4B, write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 2048 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_n25q, /* TODO: config, lock, flag regs */
+ .unlock = spi_disable_blockprotect_n25q, /* TODO: per 64kB sector lock registers */
+ .write = spi_chip_write_256, /* Multi I/O supported */
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {1700, 2000},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "N25Q064..3E", /* ..3E = 3V, uniform 64KB/4KB blocks/sectors */
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_N25Q064__3E,
+ .total_size = 8192,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 64B total; read 0x4B, write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 2048 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_n25q, /* TODO: config, lock, flag regs */
+ .unlock = spi_disable_blockprotect_n25q, /* TODO: per 64kB sector lock registers */
+ .write = spi_chip_write_256, /* Multi I/O supported */
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "N25Q128..1E", /* ..1E = 1.8V, uniform 64KB/4KB blocks/sectors */
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_N25Q128__1E,
+ .total_size = 16384,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 64B total; read 0x4B, write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 4096 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 256} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {16384 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_n25q, /* TODO: config, lock, flag regs */
+ .unlock = spi_disable_blockprotect_n25q, /* TODO: per 64kB sector lock registers */
+ .write = spi_chip_write_256, /* Multi I/O supported */
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {1700, 2000},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "N25Q128..3E", /* ..3E = 3V, uniform 64KB/4KB blocks/sectors */
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_N25Q128__3E,
+ .total_size = 16384,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 64B total; read 0x4B, write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 4096 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 256} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {16384 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_n25q, /* TODO: config, lock, flag regs */
+ .unlock = spi_disable_blockprotect_n25q, /* TODO: per 64kB sector lock registers */
+ .write = spi_chip_write_256, /* Multi I/O supported */
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "MoselVitelic",
+ .name = "V29C51000B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SYNCMOS_MVC_ID,
+ .model_id = MVC_V29C51000B,
+ .total_size = 64,
+ .page_size = 512,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {512, 128} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "MoselVitelic",
+ .name = "V29C51000T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SYNCMOS_MVC_ID,
+ .model_id = MVC_V29C51000T,
+ .total_size = 64,
+ .page_size = 512,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {512, 128} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "MoselVitelic",
+ .name = "V29C51400B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SYNCMOS_MVC_ID,
+ .model_id = MVC_V29C51400B,
+ .total_size = 512,
+ .page_size = 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {1024, 512} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "MoselVitelic",
+ .name = "V29C51400T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SYNCMOS_MVC_ID,
+ .model_id = MVC_V29C51400T,
+ .total_size = 512,
+ .page_size = 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {1024, 512} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "MoselVitelic",
+ .name = "V29LC51000",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SYNCMOS_MVC_ID,
+ .model_id = MVC_V29LC51000,
+ .total_size = 64,
+ .page_size = 512,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {512, 128} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "MoselVitelic",
+ .name = "V29LC51001",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SYNCMOS_MVC_ID,
+ .model_id = MVC_V29LC51001,
+ .total_size = 128,
+ .page_size = 512,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {512, 256} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "MoselVitelic",
+ .name = "V29LC51002",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SYNCMOS_MVC_ID,
+ .model_id = MVC_V29LC51002,
+ .total_size = 256,
+ .page_size = 512,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {512, 512} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Nantronics",
+ .name = "N25S10",
+ .bustype = BUS_SPI,
+ .manufacture_id = NANTRONICS_ID_NOPREFIX,
+ .model_id = NANTRONICS_N25S10,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 2} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd,
+ .unlock = spi_disable_blockprotect_bp3_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O read (0x3B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Nantronics",
+ .name = "N25S20",
+ .bustype = BUS_SPI,
+ .manufacture_id = NANTRONICS_ID_NOPREFIX,
+ .model_id = NANTRONICS_N25S20,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {32 * 1024, 8} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd,
+ .unlock = spi_disable_blockprotect_bp3_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O read (0x3B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Nantronics",
+ .name = "N25S40",
+ .bustype = BUS_SPI,
+ .manufacture_id = NANTRONICS_ID_NOPREFIX,
+ .model_id = NANTRONICS_N25S40,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {32 * 1024, 16} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd,
+ .unlock = spi_disable_blockprotect_bp3_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O read (0x3B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Nantronics",
+ .name = "N25S80",
+ .bustype = BUS_SPI,
+ .manufacture_id = NANTRONICS_ID_NOPREFIX,
+ .model_id = NANTRONICS_N25S80,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 32} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd,
+ .unlock = spi_disable_blockprotect_bp3_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O read (0x3B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Nantronics",
+ .name = "N25S16",
+ .bustype = BUS_SPI,
+ .manufacture_id = NANTRONICS_ID_NOPREFIX,
+ .model_id = NANTRONICS_N25S16,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2048 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2048 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd,
+ .unlock = spi_disable_blockprotect_bp3_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O read (0x3B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm25LD256C",
+ .bustype = BUS_SPI,
+ .manufacture_id = PMC_ID,
+ .model_id = PMC_PM25LD256C,
+ .total_size = 32,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 8} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {4 * 1024, 8} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {32 * 1024, 1} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {32 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {32 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O supported */
+ .voltage = {2700, 3600},
+ },
+ {
+ .vendor = "PMC",
+ .name = "Pm25LD512(C)",
+ .bustype = BUS_SPI,
+ .manufacture_id = PMC_ID,
+ .model_id = PMC_PM25LD512,
+ .total_size = 64,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 16} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {4 * 1024, 16} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {32 * 1024, 2} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect, /* FIXME: C version supports "Safe Guard" */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O supported */
+ .voltage = {2300, 3600},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm25LD010(C)",
+ .bustype = BUS_SPI,
+ .manufacture_id = PMC_ID,
+ .model_id = PMC_PM25LD010,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect, /* FIXME: C version supports "Safe Guard" */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O supported */
+ .voltage = {2700, 3600}, /* 2.3-3.6V for Pm25LD010 */
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm25LD020(C)",
+ .bustype = BUS_SPI,
+ .manufacture_id = PMC_ID,
+ .model_id = PMC_PM25LD020,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect, /* FIXME: C version supports "Safe Guard" */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O supported */
+ .voltage = {2700, 3600}, /* 2.3-3.6V for Pm25LD020 */
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm25LD040(C)",
+ .bustype = BUS_SPI,
+ .manufacture_id = PMC_ID,
+ .model_id = PMC_PM25LV040,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O supported */
+ .voltage = {2700, 3600}, /* 2.3-3.6V for Pm25LD040 */
+ },
+
+{
+ .vendor = "PMC",
+ .name = "Pm25LV512(A)",
+ .bustype = BUS_SPI,
+ .manufacture_id = PMC_ID_NOPREFIX,
+ .model_id = PMC_PM25LV512,
+ .total_size = 64,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_res2, /* The continuation code is transferred as the 3rd byte m( */
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 16} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {32 * 1024, 2} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp1_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm25LV010",
+ .bustype = BUS_SPI,
+ .manufacture_id = PMC_ID_NOPREFIX,
+ .model_id = PMC_PM25LV010,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_res2, /* The continuation code is transferred as the 3rd byte m( */
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp1_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm25LV010A",
+ .bustype = BUS_SPI,
+ .manufacture_id = PMC_ID,
+ .model_id = PMC_PM25LV010,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp1_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm25LV020",
+ .bustype = BUS_SPI,
+ .manufacture_id = PMC_ID,
+ .model_id = PMC_PM25LV020,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm25LV040",
+ .bustype = BUS_SPI,
+ .manufacture_id = PMC_ID,
+ .model_id = PMC_PM25LV040,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm25LV080B",
+ .bustype = BUS_SPI,
+ .manufacture_id = PMC_ID,
+ .model_id = PMC_PM25LV080B,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm25LV016B",
+ .bustype = BUS_SPI,
+ .manufacture_id = PMC_ID,
+ .model_id = PMC_PM25LV016B,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm29F002T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = PMC_ID_NOPREFIX,
+ .model_id = PMC_PM29F002T,
+ .total_size = 256,
+ .page_size = 8 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_FIXME,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {128 * 1024, 1},
+ {96 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm29F002B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = PMC_ID_NOPREFIX,
+ .model_id = PMC_PM29F002B,
+ .total_size = 256,
+ .page_size = 8 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_FIXME,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {96 * 1024, 1},
+ {128 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm39LV010",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = PMC_ID_NOPREFIX,
+ .model_id = PMC_PM39F010, /* Pm39LV010 and Pm39F010 have identical IDs but different voltage */
+ .total_size = 128,
+ .page_size = 4096,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 2} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm39LV020",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = PMC_ID_NOPREFIX,
+ .model_id = PMC_PM39LV020,
+ .total_size = 256,
+ .page_size = 4096,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm39LV040",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = PMC_ID_NOPREFIX,
+ .model_id = PMC_PM39LV040,
+ .total_size = 512,
+ .page_size = 4096,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PR,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm39LV512",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = PMC_ID_NOPREFIX,
+ .model_id = PMC_PM39LV512,
+ .total_size = 64,
+ .page_size = 4096,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 16} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm49FL002",
+ .bustype = BUS_LPC | BUS_FWH, /* A/A Mux */
+ .manufacture_id = PMC_ID_NOPREFIX,
+ .model_id = PMC_PM49FL002,
+ .total_size = 256,
+ .page_size = 16 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* routine is wrapper to probe_jedec (pm49fl00x.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {16 * 1024, 16} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .unlock = unlock_49fl00x,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm49FL004",
+ .bustype = BUS_LPC | BUS_FWH, /* A/A Mux */
+ .manufacture_id = PMC_ID_NOPREFIX,
+ .model_id = PMC_PM49FL004,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* routine is wrapper to probe_jedec (pm49fl00x.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .unlock = unlock_49fl00x,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Sanyo",
+ .name = "LE25FW106",
+ .bustype = BUS_SPI,
+ .manufacture_id = SANYO_ID,
+ .model_id = SANYO_LE25FW106,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_res2,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {2 * 1024, 64} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp1_srwd, /* FIXME: Add ERSER error flag. */
+ .unlock = spi_disable_blockprotect_bp1_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Sanyo",
+ .name = "LE25FW406A",
+ .bustype = BUS_SPI,
+ .manufacture_id = SANYO_ID,
+ .model_id = SANYO_LE25FW406A,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_res2,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Sanyo",
+ .name = "LE25FU406B",
+ .bustype = BUS_SPI,
+ .manufacture_id = SANYO_ID,
+ .model_id = SANYO_LE25FU406B,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_res2,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect, /* #WP pin write-protects SRWP bit. */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2300, 3600},
+ },
+
+ {
+ .vendor = "Sanyo",
+ .name = "LE25FW203A",
+ .bustype = BUS_SPI,
+ .manufacture_id = SANYO_ID,
+ .model_id = SANYO_LE25FW203A,
+ .total_size = 256,
+ .page_size = 256,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {256, 1024} },
+ .block_erase = spi_block_erase_db,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_default_welwip,
+ .unlock = NULL, /* #WP pin write-protects lower 64kB. */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Sanyo",
+ .name = "LE25FW403A",
+ .bustype = BUS_SPI,
+ .manufacture_id = SANYO_ID,
+ .model_id = SANYO_LE25FW403A,
+ .total_size = 512,
+ .page_size = 256,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {256, 2 * 1024} },
+ .block_erase = spi_block_erase_db,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_default_welwip,
+ .unlock = NULL, /* #WP pin write-protects lower 64kB. */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Sanyo",
+ .name = "LE25FW418A",
+ .bustype = BUS_SPI,
+ .manufacture_id = SANYO_ID,
+ .model_id = SANYO_LE25FW418A,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_res2,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect, /* #WP pin write-protects SRWP bit. */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* some quad-read supported ("HD_READ mode") */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Sanyo",
+ .name = "LE25FW806",
+ .bustype = BUS_SPI,
+ .manufacture_id = SANYO_ID,
+ .model_id = SANYO_LE25FW806,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_res2,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect, /* #WP pin write-protects SRWP bit. */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Sanyo",
+ .name = "LE25FW808",
+ .bustype = BUS_SPI,
+ .manufacture_id = SANYO_ID,
+ .model_id = SANYO_LE25FW808,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_res2,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {8 * 1024, 128} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect, /* #WP pin write-protects SRWP bit. */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* some quad-read supported ("HD_READ mode") */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Sharp",
+ .name = "LH28F008BJT-BTLZ1",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SHARP_ID,
+ .model_id = SHARP_LH28F008BJ__PB,
+ .total_size = 1024,
+ .page_size = 64 * 1024,
+ .tested = TEST_OK_PREW,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {8 * 1024, 8},
+ {64 * 1024, 15}
+ },
+ .block_erase = erase_block_82802ab,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = erase_sector_49lfxxxc,
+ }
+ },
+ .unlock = unlock_lh28f008bjt,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Sharp",
+ .name = "LHF00L04",
+ .bustype = BUS_FWH, /* A/A Mux */
+ .manufacture_id = SHARP_ID,
+ .model_id = SHARP_LHF00L04,
+ .total_size = 1024,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_EITHER_RESET | FEATURE_REGISTERMAP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 15},
+ {8 * 1024, 8}
+ },
+ .block_erase = erase_block_82802ab,
+ }, {
+ .eraseblocks = {
+ {1024 * 1024, 1}
+ },
+ .block_erase = NULL, /* 30 D0, only in A/A mux mode */
+ },
+ },
+ .unlock = unlock_82802ab,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Spansion",
+ .name = "S25FL004A",
+ .bustype = BUS_SPI,
+ .manufacture_id = SPANSION_ID,
+ .model_id = SPANSION_S25FL004A,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Spansion",
+ .name = "S25FL008A",
+ .bustype = BUS_SPI,
+ .manufacture_id = SPANSION_ID,
+ .model_id = SPANSION_S25FL008A,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PRE,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Spansion",
+ .name = "S25FL016A",
+ .bustype = BUS_SPI,
+ .manufacture_id = SPANSION_ID,
+ .model_id = SPANSION_S25FL016A,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PR,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Spansion",
+ .name = "S25FL032A/P",
+ .bustype = BUS_SPI,
+ .manufacture_id = SPANSION_ID,
+ .model_id = SPANSION_S25FL032A,
+ .total_size = 4096,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Spansion",
+ .name = "S25FL064A/P",
+ .bustype = BUS_SPI,
+ .manufacture_id = SPANSION_ID,
+ .model_id = SPANSION_S25FL064A,
+ .total_size = 8192,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Spansion",
+ .name = "S25FL204K",
+ .bustype = BUS_SPI,
+ .manufacture_id = SPANSION_ID,
+ .model_id = SPANSION_S25FL204,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { { 512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd,
+ .unlock = spi_disable_blockprotect_bp3_srwd, /* #WP pin write-protects SRWP bit. */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O (0x3B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Spansion",
+ .name = "S25FL208K",
+ .bustype = BUS_SPI,
+ .manufacture_id = SPANSION_ID,
+ .model_id = SPANSION_S25FL208,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { { 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd,
+ .unlock = spi_disable_blockprotect_bp3_srwd, /* #WP pin write-protects SRWP bit. */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O (0x3B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Spansion",
+ .name = "S25FL116K/S25FL216K",
+ .bustype = BUS_SPI,
+ .manufacture_id = SPANSION_ID,
+ .model_id = SPANSION_S25FL216,
+ .total_size = 2048,
+ .page_size = 256,
+ /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44 (S25FL116K only) */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 2048 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { { 2048 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd,
+ .unlock = spi_disable_blockprotect_bp3_srwd, /* #WP pin write-protects SRWP bit. */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O (0x3B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Spansion",
+ .name = "S25FL132K",
+ .bustype = BUS_SPI,
+ .manufacture_id = SPANSION_ID,
+ .model_id = SPANSION_S25FL132K,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 768B total, 256B reserved; read 0x48; write 0x42, erase 0x44 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 4096 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { { 4096 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd, /* TODO: improve */
+ .unlock = spi_disable_blockprotect_bp2_srwd, /* #WP pin write-protects SRWP bit. */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Spansion",
+ .name = "S25FL164K",
+ .bustype = BUS_SPI,
+ .manufacture_id = SPANSION_ID,
+ .model_id = SPANSION_S25FL164K,
+ .total_size = 8192,
+ .page_size = 256,
+ /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 2048} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 8192 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { { 8192 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd, /* TODO: improve */
+ .unlock = spi_disable_blockprotect_bp2_srwd, /* #WP pin write-protects SRWP bit. */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Spansion",
+ .name = "S25FL128S......0", /* uniform 256kB sectors */
+ .bustype = BUS_SPI,
+ .manufacture_id = SPANSION_ID,
+ .model_id = SPANSION_S25FL128,
+ .total_size = 16384,
+ .page_size = 256,
+ /* supports 4B addressing */
+ /* OTP: 1024B total, 32B reserved; read 0x4B; write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 4096} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {256 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 16384 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { { 16384 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_ep_srwd, /* TODO: SR2 and many others */
+ .unlock = spi_disable_blockprotect_bp2_srwd, /* TODO: various other locks */
+ .write = spi_chip_write_256, /* Multi I/O supported */
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25LF020A",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25VF020_REMS,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EWSR,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rems,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 8} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* FIXME: No BP2 & 3 */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_1, /* AAI supported, but opcode is 0xAF */
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25LF040A",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25VF040_REMS,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EWSR,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_res2,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 16} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_1, /* AAI supported, but opcode is 0xAF */
+ .read = spi_chip_read,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25LF080(A)",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25VF080_REMS,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EITHER,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_res2,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 32} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_1, /* AAI supported, but opcode is 0xAF */
+ .read = spi_chip_read,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25VF512A",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25VF512A_REMS,
+ .total_size = 64,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EWSR,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rems,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 16} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 2} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {32 * 1024, 2} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* FIXME: No BP2 & 3 */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_1, /* AAI supported, but opcode is 0xAF */
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25VF010",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25VF010_REMS,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EWSR,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rems,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* FIXME: No BP2 & 3 */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_1, /* AAI supported, but opcode is 0xAF */
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25VF020",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25VF020_REMS,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EWSR,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rems,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 8} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* FIXME: No BP2 & 3 */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_1, /* AAI supported, but opcode is 0xAF */
+ .read = spi_chip_read, /* only */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25VF020B",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25VF020B,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EWSR,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 8} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* FIXME: No BP2 & 3 and 2nd SR */
+ .unlock = spi_disable_blockprotect, /* FIXME: 2nd SR */
+ .write = spi_aai_write, /* AAI supported (0xAD) */
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25VF040",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25VF040_REMS,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EWSR,
+ .tested = TEST_OK_PR,
+ .probe = probe_spi_rems,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 16} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_1, /* AAI supported, but opcode is 0xAF */
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25VF040B",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25VF040B,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EWSR,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 16} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25vf040b,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_aai_write, /* AAI supported (0xAD) */
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25VF040B.REMS",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25VF040B_REMS,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EWSR,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rems,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 16} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25vf040b,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_aai_write,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25VF080B",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25VF080B,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EWSR,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 32} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_aai_write,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25VF016B",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25VF016B,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EITHER,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 64} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25vf016,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_aai_write,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25VF032B",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25VF032B,
+ .total_size = 4096,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EWSR,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 128} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_aai_write,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25VF064C",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25VF064C,
+ .total_size = 8192,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EWSR,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 2048} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 256} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25WF512",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25WF512,
+ .total_size = 64,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EITHER,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 16} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 2} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {1024 * 64, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 64, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* FIXME: does not have a BP3 */
+ .unlock = spi_disable_blockprotect_bp2_srwd,
+ .write = spi_aai_write,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {1650, 1950},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25WF010",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25WF010,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EITHER,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {1024 * 128, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 128, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* FIXME: does not have a BP3 */
+ .unlock = spi_disable_blockprotect_bp2_srwd,
+ .write = spi_aai_write,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {1650, 1950},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25WF020",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25WF020,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EITHER,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 8} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 256, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 256, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* FIXME: does not have a BP3 */
+ .unlock = spi_disable_blockprotect_bp2_srwd,
+ .write = spi_aai_write,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {1650, 1950},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25WF040",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25WF040,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EITHER,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 16} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 512, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 512, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* FIXME: does not have a BP3 */
+ .unlock = spi_disable_blockprotect_bp2_srwd,
+ .write = spi_aai_write,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {1650, 1950},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25WF080",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25WF080,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EITHER,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 32} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* *does* have a BP3 but it is useless */
+ .unlock = spi_disable_blockprotect_bp3_srwd,
+ .write = spi_aai_write,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {1650, 1950},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST28SF040A",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST28SF040,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = 0,
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (sst28sf040.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {128, 4096} },
+ .block_erase = erase_sector_28sf040,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_28sf040,
+ }
+ },
+ .unlock = unprotect_28sf040,
+ .write = write_28sf040,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST29EE010",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST29EE010,
+ .total_size = 128,
+ .page_size = 128,
+ .feature_bits = FEATURE_LONG_RESET,
+ .tested = TEST_OK_PR,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST29LE010",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST29LE010,
+ .total_size = 128,
+ .page_size = 128,
+ .feature_bits = FEATURE_LONG_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST29EE020A",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST29EE020A,
+ .total_size = 256,
+ .page_size = 128,
+ .feature_bits = FEATURE_LONG_RESET,
+ .tested = TEST_OK_PRE,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST29LE020",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST29LE020,
+ .total_size = 256,
+ .page_size = 128,
+ .feature_bits = FEATURE_LONG_RESET,
+ .tested = TEST_OK_PRE,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST39SF512",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST39SF512,
+ .total_size = 64,
+ .page_size = 4096,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 16} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST39SF010A",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST39SF010,
+ .total_size = 128,
+ .page_size = 4096,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST39SF020A",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST39SF020,
+ .total_size = 256,
+ .page_size = 4096,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST39SF040",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST39SF040,
+ .total_size = 512,
+ .page_size = 4096,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST39VF512",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST39VF512,
+ .total_size = 64,
+ .page_size = 4096,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 16} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST39VF010",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST39VF010,
+ .total_size = 128,
+ .page_size = 4096,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST39VF020",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST39VF020,
+ .total_size = 256,
+ .page_size = 4096,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST39VF040",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST39VF040,
+ .total_size = 512,
+ .page_size = 4096,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST39VF080",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST39VF080,
+ .total_size = 1024,
+ .page_size = 4096,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST49LF002A/B",
+ .bustype = BUS_FWH, /* A/A Mux */
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST49LF002A,
+ .total_size = 256,
+ .page_size = 16 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {16 * 1024, 16} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = NULL, /* AA 55 80 AA 55 10, only in A/A mux mode */
+ }
+ },
+ .printlock = printlock_sst_fwhub,
+ .unlock = unlock_sst_fwhub,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST49LF003A/B",
+ .bustype = BUS_FWH, /* A/A Mux */
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST49LF003A,
+ .total_size = 384,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 96} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 6} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {384 * 1024, 1} },
+ .block_erase = NULL, /* AA 55 80 AA 55 10, only in A/A mux mode */
+ }
+ },
+ .printlock = printlock_sst_fwhub,
+ .unlock = unlock_sst_fwhub,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ /* Contrary to the data sheet, TBL# on the SST49LF004B affects the top 128kB (instead of 64kB)
+ * and is only honored for 64k block erase, but not 4k sector erase.
+ */
+ .vendor = "SST",
+ .name = "SST49LF004A/B",
+ .bustype = BUS_FWH, /* A/A Mux */
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST49LF004A,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = NULL, /* AA 55 80 AA 55 10, only in A/A mux mode */
+ },
+ },
+ .printlock = printlock_sst_fwhub,
+ .unlock = unlock_sst_fwhub,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST49LF004C",
+ .bustype = BUS_FWH,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST49LF004C,
+ .total_size = 512,
+ .page_size = 4 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (sst49lfxxxc.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = erase_sector_49lfxxxc,
+ }, {
+ .eraseblocks = {
+ {64 * 1024, 7},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_block_82802ab,
+ }
+ },
+ .unlock = unlock_49lfxxxc,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST49LF008A",
+ .bustype = BUS_FWH, /* A/A Mux */
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST49LF008A,
+ .total_size = 1024,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = NULL, /* AA 55 80 AA 55 10, only in A/A mux mode */
+ }
+ },
+ .printlock = printlock_sst_fwhub,
+ .unlock = unlock_sst_fwhub,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST49LF008C",
+ .bustype = BUS_FWH,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST49LF008C,
+ .total_size = 1024,
+ .page_size = 4 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (sst49lfxxxc.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = erase_sector_49lfxxxc,
+ }, {
+ .eraseblocks = {
+ {64 * 1024, 15},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_block_82802ab,
+ }
+ },
+ .unlock = unlock_49lfxxxc,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST49LF016C",
+ .bustype = BUS_FWH,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST49LF016C,
+ .total_size = 2048,
+ .page_size = 4 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (sst49lfxxxc.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = erase_sector_49lfxxxc,
+ }, {
+ .eraseblocks = {
+ {64 * 1024, 31},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_block_82802ab,
+ }
+ },
+ .unlock = unlock_49lfxxxc,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST49LF020",
+ .bustype = BUS_LPC,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST49LF020,
+ .total_size = 256,
+ .page_size = 16 * 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {16 * 1024, 16} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = NULL,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST49LF020A",
+ .bustype = BUS_LPC,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST49LF020A,
+ .total_size = 256,
+ .page_size = 4 * 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PRE,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {16 * 1024, 16} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = NULL,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST49LF040",
+ .bustype = BUS_LPC,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST49LF040,
+ .total_size = 512,
+ .page_size = 4096,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = NULL,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST49LF040B",
+ .bustype = BUS_LPC, /* A/A Mux */
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST49LF040B,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_EITHER_RESET | FEATURE_REGISTERMAP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = NULL,
+ }
+ },
+ .unlock = unlock_82802ab,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST49LF080A",
+ .bustype = BUS_LPC, /* A/A Mux */
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST49LF080A,
+ .total_size = 1024,
+ .page_size = 4096,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_FIXME,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = NULL,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST49LF160C",
+ .bustype = BUS_LPC,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST49LF160C,
+ .total_size = 2048,
+ .page_size = 4 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_OK_PRE,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (sst49lfxxxc.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = erase_sector_49lfxxxc,
+ }, {
+ .eraseblocks = {
+ {64 * 1024, 31},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_block_82802ab,
+ }
+ },
+ .unlock = unlock_49lfxxxc,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M29F002B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M29F002B,
+ .total_size = 256,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_AAA | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {32 * 1024, 1},
+ {64 * 1024, 3},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4750, 5250}, /* 4.75-5.25V for type -X, others 4.5-5.5V */
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M29F002T/NT",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M29F002T,
+ .total_size = 256,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_AAA | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 3},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4750, 5250}, /* 4.75-5.25V for type -X, others 4.5-5.5V */
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M29F040B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M29F040B,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* datasheet specifies no timing */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8}, },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ /* FIXME: this has WORD/BYTE sequences; 2AA for word, 555 for byte */
+ .vendor = "ST",
+ .name = "M29F400BB",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M29F400BB,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_SHIFTED | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_m29f400bt,
+ .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (m29f400bt.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {32 * 1024, 1},
+ {64 * 1024, 7},
+ },
+ .block_erase = erase_block_shifted_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_shifted_jedec,
+ }
+ },
+ .write = write_m29f400bt,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+ {
+ /* FIXME: this has WORD/BYTE sequences; 2AA for word, 555 for byte */
+ .vendor = "ST",
+ .name = "M29F400BT",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M29F400BT,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_SHIFTED | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_m29f400bt,
+ .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (m29f400bt.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 7},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_block_shifted_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_shifted_jedec,
+ }
+ },
+ .write = write_m29f400bt,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M29W010B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M29W010B,
+ .total_size = 128,
+ .page_size = 16 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {16 * 1024, 8}, },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M29W040B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M29W040B,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8}, },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M29W512B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M29W512B,
+ .total_size = 64,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M50FLW040A",
+ .bustype = BUS_FWH | BUS_LPC, /* A/A Mux */
+ .manufacture_id = ST_ID,
+ .model_id = ST_M50FLW040A,
+ .total_size = 512,
+ .page_size = 0,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_FIXME,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 16}, /* sector */
+ {64 * 1024, 5}, /* block */
+ {4 * 1024, 16}, /* sector */
+ {4 * 1024, 16}, /* sector */
+ },
+ .block_erase = erase_sector_stm50,
+ }, {
+ .eraseblocks = { {64 * 1024, 8}, },
+ .block_erase = erase_block_82802ab,
+ }
+ },
+ .write = write_82802ab,
+ .unlock = unlock_stm50_uniform,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* Also has 12V fast program & erase */
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M50FLW040B",
+ .bustype = BUS_FWH | BUS_LPC, /* A/A Mux */
+ .manufacture_id = ST_ID,
+ .model_id = ST_M50FLW040B,
+ .total_size = 512,
+ .page_size = 0,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_FIXME,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 16}, /* sector */
+ {4 * 1024, 16}, /* sector */
+ {64 * 1024, 5}, /* block */
+ {4 * 1024, 16}, /* sector */
+ },
+ .block_erase = erase_sector_stm50,
+ }, {
+ .eraseblocks = { {64 * 1024, 8}, },
+ .block_erase = erase_block_82802ab,
+ }
+ },
+ .write = write_82802ab,
+ .unlock = unlock_stm50_uniform,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* Also has 12V fast program & erase */
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M50FLW080A",
+ .bustype = BUS_FWH | BUS_LPC, /* A/A Mux */
+ .manufacture_id = ST_ID,
+ .model_id = ST_M50FLW080A,
+ .total_size = 1024,
+ .page_size = 0,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_OK_PRE,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_FIXME,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 16}, /* sector */
+ {64 * 1024, 13}, /* block */
+ {4 * 1024, 16}, /* sector */
+ {4 * 1024, 16}, /* sector */
+ },
+ .block_erase = erase_sector_stm50,
+ }, {
+ .eraseblocks = { {64 * 1024, 16}, },
+ .block_erase = erase_block_82802ab,
+ }
+ },
+ .unlock = unlock_stm50_nonuniform,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* Also has 12V fast program & erase */
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M50FLW080B",
+ .bustype = BUS_FWH | BUS_LPC, /* A/A Mux */
+ .manufacture_id = ST_ID,
+ .model_id = ST_M50FLW080B,
+ .total_size = 1024,
+ .page_size = 0,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_FIXME,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 16}, /* sector */
+ {4 * 1024, 16}, /* sector */
+ {64 * 1024, 13}, /* block */
+ {4 * 1024, 16}, /* sector */
+ },
+ .block_erase = erase_sector_stm50,
+ }, {
+ .eraseblocks = { {64 * 1024, 16}, },
+ .block_erase = erase_block_82802ab,
+ }
+ },
+ .unlock = unlock_stm50_nonuniform,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* Also has 12V fast program & erase */
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M50FW002",
+ .bustype = BUS_FWH, /* A/A Mux */
+ .manufacture_id = ST_ID,
+ .model_id = ST_M50FW002,
+ .total_size = 256,
+ .page_size = 0,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (sst49lfxxxc.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 3},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_block_82802ab,
+ }
+ },
+ .unlock = unlock_stm50_nonuniform,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* Also has 12V fast program & erase */
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M50FW016",
+ .bustype = BUS_FWH, /* A/A Mux */
+ .manufacture_id = ST_ID,
+ .model_id = ST_M50FW016,
+ .total_size = 2048,
+ .page_size = 0,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (82802ab.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 32}, },
+ .block_erase = erase_block_82802ab,
+ }
+ },
+ .unlock = unlock_stm50_uniform,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* Also has 12V fast program & erase */
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M50FW040",
+ .bustype = BUS_FWH, /* A/A Mux */
+ .manufacture_id = ST_ID,
+ .model_id = ST_M50FW040,
+ .total_size = 512,
+ .page_size = 0,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_OK_PR,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (82802ab.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8}, },
+ .block_erase = erase_block_82802ab,
+ }
+ },
+ .unlock = unlock_stm50_uniform,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* Also has 12V fast program & erase */
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M50FW080",
+ .bustype = BUS_FWH, /* A/A Mux */
+ .manufacture_id = ST_ID,
+ .model_id = ST_M50FW080,
+ .total_size = 1024,
+ .page_size = 0,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (82802ab.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 16}, },
+ .block_erase = erase_block_82802ab,
+ }
+ },
+ .unlock = unlock_stm50_uniform,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* Also has 12V fast program & erase */
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M50LPW080",
+ .bustype = BUS_LPC, /* A/A Mux */
+ .manufacture_id = ST_ID,
+ .model_id = ST_M50LPW080,
+ .total_size = 1024,
+ .page_size = 0,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 16}, },
+ .block_erase = erase_block_82802ab,
+ }
+ },
+ .unlock = unlock_stm50_uniform,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* Also has 12V fast program & erase */
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M50LPW116",
+ .bustype = BUS_LPC, /* A/A Mux */
+ .manufacture_id = ST_ID,
+ .model_id = ST_M50LPW116,
+ .total_size = 2048,
+ .page_size = 0,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 16},
+ {64 * 1024, 30},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_block_82802ab,
+ }
+ },
+ .unlock = unlock_stm50_nonuniform,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* Also has 12V fast program & erase */
+ },
+
+ {
+ .vendor = "SyncMOS/MoselVitelic",
+ .name = "{F,S,V}29C51001B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SYNCMOS_MVC_ID,
+ .model_id = SM_MVC_29C51001B,
+ .total_size = 128,
+ .page_size = 512,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {512, 256} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "SyncMOS/MoselVitelic",
+ .name = "{F,S,V}29C51001T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SYNCMOS_MVC_ID,
+ .model_id = SM_MVC_29C51001T,
+ .total_size = 128,
+ .page_size = 512,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {512, 256} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "SyncMOS/MoselVitelic",
+ .name = "{F,S,V}29C51002B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SYNCMOS_MVC_ID,
+ .model_id = SM_MVC_29C51002B,
+ .total_size = 256,
+ .page_size = 512,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {512, 512} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ },
+
+ {
+ .vendor = "SyncMOS/MoselVitelic",
+ .name = "{F,S,V}29C51002T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SYNCMOS_MVC_ID,
+ .model_id = SM_MVC_29C51002T,
+ .total_size = 256,
+ .page_size = 512,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {512, 512} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ },
+
+ {
+ .vendor = "SyncMOS/MoselVitelic",
+ .name = "{F,S,V}29C51004B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SYNCMOS_MVC_ID,
+ .model_id = SM_MVC_29C51004B,
+ .total_size = 512,
+ .page_size = 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {1024, 512} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "SyncMOS/MoselVitelic",
+ .name = "{F,S,V}29C51004T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SYNCMOS_MVC_ID,
+ .model_id = SM_MVC_29C51004T,
+ .total_size = 512,
+ .page_size = 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {1024, 512} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "SyncMOS/MoselVitelic",
+ .name = "{S,V}29C31004B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SYNCMOS_MVC_ID,
+ .model_id = SM_MVC_29C31004B,
+ .total_size = 512,
+ .page_size = 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {1024, 512} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SyncMOS/MoselVitelic",
+ .name = "{S,V}29C31004T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SYNCMOS_MVC_ID,
+ .model_id = SM_MVC_29C31004T,
+ .total_size = 512,
+ .page_size = 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {1024, 512} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "TI",
+ .name = "TMS29F002RB",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = TI_OLD_ID,
+ .model_id = TI_TMS29F002RB,
+ .total_size = 256,
+ .page_size = 16384, /* Non-uniform sectors */
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {32 * 1024, 1},
+ {64 * 1024, 3},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "TI",
+ .name = "TMS29F002RT",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = TI_OLD_ID,
+ .model_id = TI_TMS29F002RT,
+ .total_size = 256,
+ .page_size = 16384, /* Non-uniform sectors */
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 3},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25Q80.V",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25Q80_V,
+ .total_size = 1024,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44, read ID 0x4B */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 32} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25Q16.V",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25Q16_V,
+ .total_size = 2048,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44, read ID 0x4B */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 64} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25Q32.V",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25Q32_V,
+ .total_size = 4096,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44, read ID 0x4B */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 128} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25Q64.V",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25Q64_V,
+ .total_size = 8192,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44, read ID 0x4B */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 2048} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 256} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25Q128.V",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25Q128_V,
+ .total_size = 16384,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44, read ID 0x4B */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 4096} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 512} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 256} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {16 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {16 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25Q20.W",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25Q20_W,
+ .total_size = 256,
+ .page_size = 256,
+ /* OTP: 256B total; read 0x48; write 0x42, erase 0x44, read ID 0x4B */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 8} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {1700, 1950}, /* Fast read (0x0B) and multi I/O supported */
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25Q40.W",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25Q40_W,
+ .total_size = 512,
+ .page_size = 256,
+ /* OTP: 256B total; read 0x48; write 0x42, erase 0x44, read ID 0x4B */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 16} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {1700, 1950}, /* Fast read (0x0B) and multi I/O supported */
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25Q80.W",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25Q80_W,
+ .total_size = 1024,
+ .page_size = 256,
+ /* OTP: 256B total; read 0x48; write 0x42, erase 0x44, read ID 0x4B */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 32} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {1700, 1950}, /* Fast read (0x0B) and multi I/O supported */
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25Q16.W",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25Q16_W,
+ .total_size = 2048,
+ .page_size = 256,
+ /* OTP: 256B total; read 0x48; write 0x42, erase 0x44, read ID 0x4B */
+ /* QPI enable 0x38, disable 0xFF */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 64} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {1700, 1950}, /* Fast read (0x0B) and multi I/O supported */
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25Q32.W",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25Q32_W,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 256B total; read 0x48; write 0x42, erase 0x44, read ID 0x4B */
+ /* QPI enable 0x38, disable 0xFF */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 128} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {1700, 1950}, /* Fast read (0x0B) and multi I/O supported */
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25Q64.W",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25Q64_W,
+ .total_size = 8192,
+ .page_size = 256,
+ /* OTP: 256B total; read 0x48; write 0x42, erase 0x44, read ID 0x4B */
+ /* QPI enable 0x38, disable 0xFF */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 2048} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 256} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {1700, 1950}, /* Fast read (0x0B) and multi I/O supported */
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25X10",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25X10,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 2} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25X20",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25X20,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25X40",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25X40,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25X80",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25X80,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25X16",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25X16,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 64} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25X32",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25X32,
+ .total_size = 4096,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 128} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25X64",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25X64,
+ .total_size = 8192,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PROBE,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 2048} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 256} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W29C010(M)/W29C011A/W29EE011/W29EE012-old",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W29C010,
+ .total_size = 128,
+ .page_size = 128,
+ .feature_bits = FEATURE_LONG_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_w29ee011,
+ .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (w29ee011.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec,
+ .read = read_memmapped,
+ },
+
+ {/* W29EE011, W29EE012, W29C010M, W29C011A do not support probe_jedec according to the datasheet, but it works for newer(?) steppings. */
+ .vendor = "Winbond",
+ .name = "W29C010(M)/W29C011A/W29EE011/W29EE012",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W29C010,
+ .total_size = 128,
+ .page_size = 128,
+ .feature_bits = FEATURE_LONG_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10, /* used datasheet for the W29C011A */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec,
+ .read = read_memmapped,
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W29C020(C)/W29C022",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W29C020,
+ .total_size = 256,
+ .page_size = 128,
+ .feature_bits = FEATURE_LONG_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W29C040/P",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W29C040,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_LONG_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W39F010",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W39F010,
+ .total_size = 128,
+ .page_size = 4 * 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .printlock = printlock_w39f010,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W39L010",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W39L010,
+ .total_size = 128,
+ .page_size = 4 * 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .printlock = printlock_w39l010,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W39L020",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W39L020,
+ .total_size = 256,
+ .page_size = 4 * 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .printlock = printlock_w39l020,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W39L040",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W39L040,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PR,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .printlock = printlock_w39l040,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W39V040A",
+ .bustype = BUS_LPC,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W39V040A,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .printlock = printlock_w39v040a,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W39V040B",
+ .bustype = BUS_LPC,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W39V040B,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .printlock = printlock_w39v040b,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W39V040C",
+ .bustype = BUS_LPC,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W39V040C,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .printlock = printlock_w39v040c,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W39V040FA",
+ .bustype = BUS_FWH,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W39V040FA,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .printlock = printlock_w39v040fa,
+ .unlock = unlock_sst_fwhub,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W39V040FB",
+ .bustype = BUS_FWH,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W39V040B,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .printlock = printlock_w39v040fb,
+ .unlock = unlock_w39v040fb,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* Also has 12V fast program */
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W39V040FC",
+ .bustype = BUS_FWH,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W39V040C,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .printlock = printlock_w39v040fc,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* Also has 12V fast program */
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W39V080A",
+ .bustype = BUS_LPC,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W39V080A,
+ .total_size = 1024,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .printlock = printlock_w39v080a,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W49F002U/N",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W49F002U,
+ .total_size = 256,
+ .page_size = 128,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {128 * 1024, 1},
+ {96 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W49F020",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W49F020,
+ .total_size = 256,
+ .page_size = 128,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PROBE,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W49V002A",
+ .bustype = BUS_LPC,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W49V002A,
+ .total_size = 256,
+ .page_size = 128,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 3},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W49V002FA",
+ .bustype = BUS_FWH,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W49V002FA,
+ .total_size = 256,
+ .page_size = 128,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 3},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W39V080FA",
+ .bustype = BUS_FWH,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W39V080FA,
+ .total_size = 1024,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 16}, },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .printlock = printlock_w39v080fa,
+ .unlock = unlock_w39v080fa,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* Also has 12V fast program */
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W39V080FA (dual mode)",
+ .bustype = BUS_FWH,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W39V080FA_DM,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8}, },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .printlock = printlock_w39v080fa_dual,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* Also has 12V fast program */
+ },
+
+ {
+ .vendor = "Unknown",
+ .name = "SFDP-capable chip",
+ .bustype = BUS_SPI,
+ .manufacture_id = GENERIC_MANUF_ID,
+ .model_id = SFDP_DEVICE_ID,
+ /* We present our own "report this" text hence we do not
+ * want the default "This flash part has status UNTESTED..."
+ * text to be printed. */
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_sfdp,
+ .unlock = spi_disable_blockprotect, /* is this safe? */
+ .read = spi_chip_read,
+ /* FIXME: some vendor extensions define this */
+ .voltage = {0},
+ /* Everything below will be set by the probing function. */
+ .write = NULL,
+ .total_size = 0,
+ .page_size = 0,
+ .feature_bits = 0,
+ .block_erasers = {},
+ },
+
+ {
+ .vendor = "Programmer",
+ .name = "Opaque flash chip",
+ .bustype = BUS_PROG,
+ .manufacture_id = PROGMANUF_ID,
+ .model_id = PROGDEV_ID,
+ .total_size = 0,
+ .page_size = 256,
+ /* probe is assumed to work, rest will be filled in by probe */
+ .tested = TEST_OK_PROBE,
+ .probe = probe_opaque,
+ /* eraseblock sizes will be set by the probing function */
+ .block_erasers =
+ {
+ {
+ .block_erase = erase_opaque,
+ }
+ },
+ .write = write_opaque,
+ .read = read_opaque,
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "unknown AMIC SPI chip",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID,
+ .model_id = GENERIC_DEVICE_ID,
+ .total_size = 0,
+ .page_size = 256,
+ .tested = TEST_BAD_PREW,
+ .probe = probe_spi_rdid4,
+ .probe_timing = TIMING_ZERO,
+ .write = NULL,
+ .read = NULL,
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "unknown Atmel SPI chip",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = GENERIC_DEVICE_ID,
+ .total_size = 0,
+ .page_size = 256,
+ .tested = TEST_BAD_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .write = NULL,
+ .read = NULL,
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "unknown Eon SPI chip",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = GENERIC_DEVICE_ID,
+ .total_size = 0,
+ .page_size = 256,
+ .tested = TEST_BAD_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .write = NULL,
+ .read = NULL,
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "unknown Macronix SPI chip",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = GENERIC_DEVICE_ID,
+ .total_size = 0,
+ .page_size = 256,
+ .tested = TEST_BAD_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .write = NULL,
+ .read = NULL,
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "unknown PMC SPI chip",
+ .bustype = BUS_SPI,
+ .manufacture_id = PMC_ID,
+ .model_id = GENERIC_DEVICE_ID,
+ .total_size = 0,
+ .page_size = 256,
+ .tested = TEST_BAD_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .write = NULL,
+ .read = NULL,
+ },
+
+ {
+ .vendor = "SST",
+ .name = "unknown SST SPI chip",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = GENERIC_DEVICE_ID,
+ .total_size = 0,
+ .page_size = 256,
+ .tested = TEST_BAD_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .write = NULL,
+ .read = NULL,
+ },
+
+ {
+ .vendor = "ST",
+ .name = "unknown ST SPI chip",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = GENERIC_DEVICE_ID,
+ .total_size = 0,
+ .page_size = 256,
+ .tested = TEST_BAD_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .write = NULL,
+ .read = NULL,
+ },
+
+ {
+ .vendor = "Sanyo",
+ .name = "unknown Sanyo SPI chip",
+ .bustype = BUS_SPI,
+ .manufacture_id = SANYO_ID,
+ .model_id = GENERIC_DEVICE_ID,
+ .total_size = 0,
+ .page_size = 256,
+ .tested = TEST_BAD_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .write = NULL,
+ .read = NULL,
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "unknown Winbond (ex Nexcom) SPI chip",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = GENERIC_DEVICE_ID,
+ .total_size = 0,
+ .page_size = 256,
+ .tested = TEST_BAD_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .write = NULL,
+ .read = NULL,
+ },
+
+ {
+ .vendor = "Generic",
+ .name = "unknown SPI chip (RDID)",
+ .bustype = BUS_SPI,
+ .manufacture_id = GENERIC_MANUF_ID,
+ .model_id = GENERIC_DEVICE_ID,
+ .total_size = 0,
+ .page_size = 256,
+ .tested = TEST_BAD_PREW,
+ .probe = probe_spi_rdid,
+ .write = NULL,
+ },
+
+ {
+ .vendor = "Generic",
+ .name = "unknown SPI chip (REMS)",
+ .bustype = BUS_SPI,
+ .manufacture_id = GENERIC_MANUF_ID,
+ .model_id = GENERIC_DEVICE_ID,
+ .total_size = 0,
+ .page_size = 256,
+ .tested = TEST_BAD_PREW,
+ .probe = probe_spi_rems,
+ .write = NULL,
+ },
+
+ {0}
+};
+
+const unsigned int flashchips_size = ARRAY_SIZE(flashchips);
diff --git a/resources/flashrom/patch/flashchips.c_lenovobios_macronix b/resources/flashrom/patch/flashchips.c_lenovobios_macronix
new file mode 100644
index 0000000..9a7ec32
--- /dev/null
+++ b/resources/flashrom/patch/flashchips.c_lenovobios_macronix
@@ -0,0 +1,13574 @@
+/*
+ * This file is part of the flashrom project.
+ *
+ * Copyright (C) 2000 Silicon Integrated System Corporation
+ * Copyright (C) 2004 Tyan Corp
+ * Copyright (C) 2005-2008 coresystems GmbH <stepan@openbios.org>
+ * Copyright (C) 2006-2009 Carl-Daniel Hailfinger
+ * Copyright (C) 2009 Sean Nelson <audiohacked@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "flash.h"
+#include "flashchips.h"
+#include "chipdrivers.h"
+
+/**
+ * List of supported flash chips.
+ *
+ * Please keep the list sorted by vendor name and chip family, so that the output of 'flashrom -L' is roughly
+ * alphabetically sorted. Within families keep them in order of density.
+ */
+const struct flashchip flashchips[] = {
+
+ /*
+ * .vendor = Vendor name
+ * .name = Chip name
+ * .bustype = Supported flash bus types (Parallel, LPC...)
+ * .manufacture_id = Manufacturer chip ID
+ * .model_id = Model chip ID
+ * .total_size = Total size in (binary) kbytes
+ * .page_size = Page or eraseblock(?) size in bytes
+ * .tested = Test status
+ * .probe = Probe function
+ * .probe_timing = Probe function delay
+ * .block_erasers[] = Array of erase layouts and erase functions
+ * {
+ * .eraseblocks[] = Array of { blocksize, blockcount }
+ * .block_erase = Block erase function
+ * }
+ * .printlock = Chip lock status function
+ * .unlock = Chip unlock function
+ * .write = Chip write function
+ * .read = Chip read function
+ * .voltage = Voltage range in millivolt
+ */
+
+ {
+ .vendor = "AMD",
+ .name = "Am29F010A/B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29F010B, /* Same as Am29F010A */
+ .total_size = 128,
+ .page_size = 16 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PRE,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {16 * 1024, 8} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "AMD",
+ .name = "Am29F002(N)BB",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29F002BB,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_SHORT_RESET | FEATURE_ADDR_2AA,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {32 * 1024, 1},
+ {64 * 1024, 3},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4750, 5250}, /* 4.75-5.25V for type -55, others 4.5-5.5V */
+ },
+
+ {
+ .vendor = "AMD",
+ .name = "Am29F002(N)BT",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29F002BT,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_EITHER_RESET | FEATURE_ADDR_2AA,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 3},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4750, 5250}, /* 4.75-5.25V for type -55, others 4.5-5.5V */
+ },
+
+ {
+ .vendor = "AMD",
+ .name = "Am29F016D",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29F016D,
+ .total_size = 2 * 1024,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {2048 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "AMD",
+ .name = "Am29F040B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29F040B,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "AMD",
+ .name = "Am29F080B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29F080B,
+ .total_size = 1024,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "AMD",
+ .name = "Am29LV001BB",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29LV001BB,
+ .total_size = 128,
+ .page_size = 64 * 1024, /* unused */
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ {16 * 1024, 7},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* 3.0-3.6V for type -45R, others 2.7-3.6V */
+ },
+
+ {
+ .vendor = "AMD",
+ .name = "Am29LV001BT",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29LV001BT,
+ .total_size = 128,
+ .page_size = 64 * 1024, /* unused */
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 7},
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* 3.0-3.6V for type -45R, others 2.7-3.6V */
+ },
+
+ {
+ .vendor = "AMD",
+ .name = "Am29LV002BB",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29LV002BB,
+ .total_size = 256,
+ .page_size = 64 * 1024, /* unused */
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {32 * 1024, 1},
+ {64 * 1024, 3},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* 3.0-3.6V for type -55, others 2.7-3.6V */
+ },
+
+ {
+ .vendor = "AMD",
+ .name = "Am29LV002BT",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29LV002BT,
+ .total_size = 256,
+ .page_size = 64 * 1024, /* unused */
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 3},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* 3.0-3.6V for type -55, others 2.7-3.6V */
+ },
+
+ {
+ .vendor = "AMD",
+ .name = "Am29LV004BB",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29LV004BB,
+ .total_size = 512,
+ .page_size = 64 * 1024, /* unused */
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {32 * 1024, 1},
+ {64 * 1024, 7},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMD",
+ .name = "Am29LV004BT",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29LV004BT,
+ .total_size = 512,
+ .page_size = 64 * 1024, /* unused */
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 7},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMD",
+ .name = "Am29LV008BB",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29LV008BB,
+ .total_size = 1024,
+ .page_size = 64 * 1024, /* unused */
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {32 * 1024, 1},
+ {64 * 1024, 15},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600} /* 3.0-3.6V for type -70R, others 2.7-3.6V */
+ },
+
+ {
+ .vendor = "AMD",
+ .name = "Am29LV008BT",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29LV008BT,
+ .total_size = 1024,
+ .page_size = 64 * 1024, /* unused */
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 15},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600} /* 3.0-3.6V for type -70R, others 2.7-3.6V */
+ },
+
+ {
+ .vendor = "AMD",
+ .name = "Am29LV040B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29LV040B,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_OK_PRE,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* 3.0-3.6V for type -60R, others 2.7-3.6V*/
+ },
+
+ {
+ .vendor = "AMD",
+ .name = "Am29LV081B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29LV080B,
+ .total_size = 1024,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET, /* datasheet specifies address as don't care */
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* 3.0-3.6V for type -70R, others 2.7-3.6V */
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L05PT",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID,
+ .model_id = AMIC_A25L05PT,
+ .total_size = 64,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid4,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {32 * 1024, 1},
+ {16 * 1024, 1},
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp1_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L05PU",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID,
+ .model_id = AMIC_A25L05PU,
+ .total_size = 64,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid4,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ {16 * 1024, 1},
+ {32 * 1024, 1},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp1_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L10PT",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID,
+ .model_id = AMIC_A25L10PT,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid4,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 1},
+ {32 * 1024, 1},
+ {16 * 1024, 1},
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp1_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L10PU",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID,
+ .model_id = AMIC_A25L10PU,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid4,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ {16 * 1024, 1},
+ {32 * 1024, 1},
+ {64 * 1024, 1},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp1_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L20PT",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID,
+ .model_id = AMIC_A25L20PT,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid4,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 3},
+ {32 * 1024, 1},
+ {16 * 1024, 1},
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp1_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L20PU",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID,
+ .model_id = AMIC_A25L20PU,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid4,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ {16 * 1024, 1},
+ {32 * 1024, 1},
+ {64 * 1024, 3},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp1_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ /* The A25L40P{T,U} chips are distinguished by their
+ * erase block layouts, but without any distinction in RDID.
+ * This inexplicable quirk was verified by Rudolf Marek
+ * and discussed on the flashrom mailing list on 2010-07-12.
+ */
+ {
+ .vendor = "AMIC",
+ .name = "A25L40PT",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID,
+ .model_id = AMIC_A25L40PT,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PR,
+ .probe = probe_spi_rdid4,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 7},
+ {32 * 1024, 1},
+ {16 * 1024, 1},
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L40PU",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID,
+ .model_id = AMIC_A25L40PU,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PR,
+ .probe = probe_spi_rdid4,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ {16 * 1024, 1},
+ {32 * 1024, 1},
+ {64 * 1024, 7},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L80P",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID,
+ .model_id = AMIC_A25L80P,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PRE,
+ .probe = probe_spi_rdid4,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ {16 * 1024, 1},
+ {32 * 1024, 1},
+ {64 * 1024, 15},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L16PT",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID,
+ .model_id = AMIC_A25L16PT,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid4,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 31},
+ {32 * 1024, 1},
+ {16 * 1024, 1},
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2048 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2048 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L16PU",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID,
+ .model_id = AMIC_A25L16PU,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PR,
+ .probe = probe_spi_rdid4,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ {16 * 1024, 1},
+ {32 * 1024, 1},
+ {64 * 1024, 31},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2048 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2048 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L512",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID_NOPREFIX,
+ .model_id = AMIC_A25L512,
+ .total_size = 64,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { { 4 * 1024, 16 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { { 64 * 1024, 1 } },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 64 * 1024, 1 } },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L010",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID_NOPREFIX,
+ .model_id = AMIC_A25L010,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { { 4 * 1024, 32 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { { 64 * 1024, 2 } },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 128 * 1024, 1 } },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L020",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID_NOPREFIX,
+ .model_id = AMIC_A25L020,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { { 4 * 1024, 64 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { { 64 * 1024, 4 } },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 256 * 1024, 1 } },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L040",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID_NOPREFIX,
+ .model_id = AMIC_A25L040,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { { 4 * 1024, 128 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { { 64 * 1024, 8 } },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 512 * 1024, 1 } },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L080",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID_NOPREFIX,
+ .model_id = AMIC_A25L080,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { { 4 * 1024, 256 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { { 64 * 1024, 16 } },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 1024 * 1024, 1 } },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L016",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID_NOPREFIX,
+ .model_id = AMIC_A25L016,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { { 4 * 1024, 512 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { { 64 * 1024, 32 } },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 2048 * 1024, 1 } },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L032",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID_NOPREFIX,
+ .model_id = AMIC_A25L032,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 64B total; read 0x4B, 0x48; write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { { 4 * 1024, 1024 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { { 64 * 1024, 64 } },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { { 64 * 1024, 64 } },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 4096 * 1024, 1 } },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { { 4096 * 1024, 1 } },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_amic_a25l032, /* bit5: T/B, bit6: prot size */
+ .unlock = spi_disable_blockprotect_bp2_srwd, /* TODO: 2nd status reg (read with 0x35) */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25LQ16",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID_NOPREFIX,
+ .model_id = AMIC_A25LQ16,
+ .total_size = 2048,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 64B total; read 0x4B, 0x48; write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { { 4 * 1024, 512 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { { 64 * 1024, 32 } },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { { 64 * 1024, 32 } },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 2048 * 1024, 1 } },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { { 2048 * 1024, 1 } },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_amic_a25l032, /* bit5: T/B, bit6: prot size */
+ .unlock = spi_disable_blockprotect_bp2_srwd, /* TODO: 2nd status reg (read with 0x35) */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25LQ032/A25LQ32A",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID_NOPREFIX,
+ .model_id = AMIC_A25LQ032,
+ .total_size = 4096,
+ .page_size = 256,
+ /* A25LQ32A supports SFDP */
+ /* OTP: 64B total; read 0x4B, 0x48; write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { { 4 * 1024, 1024 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { { 64 * 1024, 64 } },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { { 64 * 1024, 64 } },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 4096 * 1024, 1 } },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { { 4096 * 1024, 1 } },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_amic_a25l032, /* bit5: T/B, bit6: prot size */
+ .unlock = spi_disable_blockprotect_bp2_srwd, /* TODO: 2nd status reg (read with 0x35) */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25LQ64",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID_NOPREFIX,
+ .model_id = AMIC_A25LQ032,
+ .total_size = 8192,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 512B total; enter 0xB1, exit 0xC1 */
+ /* QPI enable 0x35, disable 0xF5 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { { 4 * 1024, 2048 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { { 32 * 1024, 256 } },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { { 64 * 1024, 128 } },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 8192 * 1024, 1 } },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { { 8192 * 1024, 1 } },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6 is quad enhance (sic!) */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A29002B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMIC_ID_NOPREFIX,
+ .model_id = AMIC_A29002B,
+ .total_size = 256,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {32 * 1024, 1},
+ {64 * 1024, 3},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A29002T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMIC_ID_NOPREFIX,
+ .model_id = AMIC_A29002T,
+ .total_size = 256,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 3},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A29040B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMIC_ID_NOPREFIX,
+ .model_id = AMIC_A29040B,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A49LF040A",
+ .bustype = BUS_LPC,
+ .manufacture_id = AMIC_ID_NOPREFIX,
+ .model_id = AMIC_A49LF040A,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* routine is wrapper to probe_jedec (pm49fl00x.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .unlock = unlock_49fl00x,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25DF021",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25DF021,
+ .total_size = 256,
+ .page_size = 256,
+ /* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 8} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25df,
+ .unlock = spi_disable_blockprotect_at2x_global_unprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600}, /* 2.3-3.6V & 2.7-3.6V models available */
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25DF041A",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25DF041A,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 16} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25df,
+ .unlock = spi_disable_blockprotect_at2x_global_unprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600}, /* 2.3-3.6V & 2.7-3.6V models available */
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25DF081",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25DF081,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 32} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25df,
+ .unlock = spi_disable_blockprotect_at2x_global_unprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {1600, 2000}, /* Datasheet says range is 1.65-1.95 V */
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25DF081A",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25DF081A,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 32} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25df_sec,
+ .unlock = spi_disable_blockprotect_at2x_global_unprotect_sec,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25DF161",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25DF161,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PROBE,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 64} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25df_sec,
+ .unlock = spi_disable_blockprotect_at2x_global_unprotect_sec,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25DF321",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25DF321,
+ .total_size = 4096,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 128} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25df,
+ .unlock = spi_disable_blockprotect_at2x_global_unprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25DF321A",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25DF321A,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 128} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25df_sec,
+ .unlock = spi_disable_blockprotect_at2x_global_unprotect_sec,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25DF641(A)",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25DF641,
+ .total_size = 8192,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 2048} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 256} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25df_sec,
+ .unlock = spi_disable_blockprotect_at2x_global_unprotect_sec,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25DL081",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25DF081,
+ .total_size = 1024,
+ .page_size = 256,
+ /* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 32} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25df_sec,
+ .unlock = spi_disable_blockprotect_at2x_global_unprotect_sec,
+ .write = spi_chip_write_256, /* Dual I/O (0xA2) supported */
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O (0x3B) supported */
+ .voltage = {1650, 1950},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25DL161",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25DL161,
+ .total_size = 2048,
+ .page_size = 256,
+ /* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 64} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25df_sec,
+ .unlock = spi_disable_blockprotect_at2x_global_unprotect_sec,
+ .write = spi_chip_write_256, /* Dual I/O (0xA2) supported */
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O (0x3B) supported */
+ .voltage = {1650, 1950},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25DQ161",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25DQ161,
+ .total_size = 2048,
+ .page_size = 256,
+ /* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 64} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25df_sec,
+ .unlock = spi_disable_blockprotect_at2x_global_unprotect_sec,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25F512",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25F512,
+ .total_size = 64,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_at25f,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {32 * 1024, 2} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_62,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25f,
+ .unlock = spi_disable_blockprotect_at25f,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25F512A",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25F512A,
+ .total_size = 64,
+ .page_size = 128,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_at25f,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {32 * 1024, 2} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_62,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25f512a,
+ /* FIXME: It is not correct to use this one, because the BP1 bit is N/A. */
+ .unlock = spi_disable_blockprotect_at25f512a,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25F512B",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25F512B,
+ .total_size = 64,
+ .page_size = 256,
+ /* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 16} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 2} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {32 * 1024, 2} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_62,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25f512b,
+ .unlock = spi_disable_blockprotect_at25f512b,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ /* The A suffix indicates 33MHz instead of 20MHz clock rate.
+ * All other properties seem to be the same.*/
+ .name = "AT25F1024(A)",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25F1024,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_at25f,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_62,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25f,
+ .unlock = spi_disable_blockprotect_at25f,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25F2048",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25F2048,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_at25f,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_62,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25f,
+ .unlock = spi_disable_blockprotect_at25f,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25F4096",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25F4096,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_at25f,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_62,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25f4096,
+ /* "Bits 5-6 are 0s when device is not in an internal write cycle." Better leave them alone: */
+ .unlock = spi_disable_blockprotect_bp2_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25FS010",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25FS010,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25fs010,
+ .unlock = spi_disable_blockprotect_at25fs010,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25FS040",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25FS040,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25fs040,
+ .unlock = spi_disable_blockprotect_at25fs040,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT26DF041",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT26DF041,
+ .total_size = 512,
+ .page_size = 256,
+ /* does not support EWSR nor WREN and has no writable status register bits whatsoever */
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {256, 2048} },
+ .block_erase = spi_block_erase_81,
+ }, {
+ .eraseblocks = { {2 * 1024, 256} },
+ .block_erase = spi_block_erase_50,
+ }, {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain,
+ /* Supports also an incompatible page write (of exactly 256 B) and an auto-erasing write. */
+ .write = spi_chip_write_1,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600}, /* 3.0-3.6V for higher speed, 2.7-3.6V normal */
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT26DF081A",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT26DF081A,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 32} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at26df081a,
+ .unlock = spi_disable_blockprotect_at2x_global_unprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT26DF161",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT26DF161,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PR,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 64} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25df,
+ .unlock = spi_disable_blockprotect_at2x_global_unprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT26DF161A",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT26DF161A,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 64} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at26df081a,
+ .unlock = spi_disable_blockprotect_at2x_global_unprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ /*The AT26DF321 has the same ID as the AT25DF321. */
+ /*{
+ .vendor = "Atmel",
+ .name = "AT26DF321",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT26DF321,
+ .total_size = 4096,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .printlock = spi_prettyprint_status_register_at26df081a,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ },*/
+
+ {
+ .vendor = "Atmel",
+ .name = "AT26F004",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT26F004,
+ .total_size = 512,
+ .page_size = 256,
+ .tested = {.probe = NT, .read = NT, .erase = NT, .write = BAD },
+ .feature_bits = FEATURE_WRSR_WREN,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 16} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .write = NULL /* Incompatible Page write */,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT29C512",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT29C512,
+ .total_size = 64,
+ .page_size = 128,
+ .feature_bits = FEATURE_LONG_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10000, /* 10mS, Enter=Exec */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT29C010A",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT29C010A,
+ .total_size = 128,
+ .page_size = 128,
+ .feature_bits = FEATURE_LONG_RESET,
+ .tested = TEST_OK_PRE,
+ .probe = probe_jedec,
+ .probe_timing = 10000, /* 10mS, Enter=Exec */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec, /* FIXME */
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT29C020",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT29C020,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_LONG_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10000, /* 10ms */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT29C040A",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT29C040A,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_LONG_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = 10000, /* 10 ms */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT45CS1282",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT45CS1282,
+ .total_size = 16896 /* No power of two sizes */,
+ .page_size = 1056 /* No power of two sizes */,
+ /* does not support EWSR nor WREN and has no writable status register bits whatsoever */
+ /* OTP: 128B total, 64B pre-programmed; read 0x77 (4 dummy bytes); write 0x9A (via buffer) */
+ .feature_bits = FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {8 * 1056, 1}, /* sector 0a: opcode 50h */
+ {248 * 1056, 1}, /* sector 0b: opcode 7Ch */
+ {256 * 1056, 63}, /* sectors 1 - 63: opcode 7Ch */
+ },
+ .block_erase = spi_erase_at45cs_sector,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain,
+ .gran = write_gran_1056bytes,
+ .write = spi_write_at45db,
+ .read = spi_read_at45db,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT45DB011D",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT45DB011D,
+ .total_size = 128 /* or 132, determined from status register */,
+ .page_size = 256 /* or 264, determined from status register */,
+ /* does not support EWSR nor WREN and has no writable status register bits whatsoever */
+ /* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+ .feature_bits = FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_at45db,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {256, 512} },
+ .block_erase = spi_erase_at45db_page,
+ }, {
+ .eraseblocks = { {8 * 256, 512/8} },
+ .block_erase = spi_erase_at45db_block,
+ }, {
+ .eraseblocks = {
+ {8 * 256, 1},
+ {120 * 256, 1},
+ {128 * 256, 3},
+ },
+ .block_erase = spi_erase_at45db_sector
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_erase_at45db_chip,
+ }
+ },
+ .unlock = spi_disable_blockprotect_at45db, /* Impossible if locked down or #WP is low */
+ .printlock = spi_prettyprint_status_register_at45db,
+ /* granularity will be set by the probing function. */
+ .write = spi_write_at45db,
+ .read = spi_read_at45db, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT45DB021D",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT45DB021D,
+ .total_size = 256 /* or 264, determined from status register */,
+ .page_size = 256 /* or 264, determined from status register */,
+ /* does not support EWSR nor WREN and has no writable status register bits whatsoever */
+ /* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+ .feature_bits = FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_at45db,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {256, 1024} },
+ .block_erase = spi_erase_at45db_page,
+ }, {
+ .eraseblocks = { {8 * 256, 1024/8} },
+ .block_erase = spi_erase_at45db_block,
+ }, {
+ .eraseblocks = {
+ {8 * 256, 1},
+ {120 * 256, 1},
+ {128 * 256, 7},
+ },
+ .block_erase = spi_erase_at45db_sector
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_erase_at45db_chip,
+ }
+ },
+ .unlock = spi_disable_blockprotect_at45db, /* Impossible if locked down or #WP is low */
+ .printlock = spi_prettyprint_status_register_at45db,
+ /* granularity will be set by the probing function. */
+ .write = spi_write_at45db,
+ .read = spi_read_at45db, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT45DB041D",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT45DB041D,
+ .total_size = 512 /* or 528, determined from status register */,
+ .page_size = 256 /* or 264, determined from status register */,
+ /* does not support EWSR nor WREN and has no writable status register bits whatsoever */
+ /* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+ .feature_bits = FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_at45db,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {256, 2048} },
+ .block_erase = spi_erase_at45db_page,
+ }, {
+ .eraseblocks = { {8 * 256, 2048/8} },
+ .block_erase = spi_erase_at45db_block,
+ }, {
+ .eraseblocks = {
+ {8 * 256, 1},
+ {248 * 256, 1},
+ {256 * 256, 7},
+ },
+ .block_erase = spi_erase_at45db_sector
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_erase_at45db_chip,
+ }
+ },
+ .unlock = spi_disable_blockprotect_at45db, /* Impossible if locked down or #WP is low */
+ .printlock = spi_prettyprint_status_register_at45db,
+ /* granularity will be set by the probing function. */
+ .write = spi_write_at45db,
+ .read = spi_read_at45db, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600}, /* 2.5-3.6V & 2.7-3.6V models available */
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT45DB081D",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT45DB081D,
+ .total_size = 1024 /* or 1056, determined from status register */,
+ .page_size = 256 /* or 264, determined from status register */,
+ /* does not support EWSR nor WREN and has no writable status register bits whatsoever */
+ /* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+ .feature_bits = FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_at45db,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {256, 4096} },
+ .block_erase = spi_erase_at45db_page,
+ }, {
+ .eraseblocks = { {8 * 256, 4096/8} },
+ .block_erase = spi_erase_at45db_block,
+ }, {
+ .eraseblocks = {
+ {8 * 256, 1},
+ {248 * 256, 1},
+ {256 * 256, 15},
+ },
+ .block_erase = spi_erase_at45db_sector
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_erase_at45db_chip,
+ }
+ },
+ .unlock = spi_disable_blockprotect_at45db, /* Impossible if locked down or #WP is low */
+ .printlock = spi_prettyprint_status_register_at45db,
+ /* granularity will be set by the probing function. */
+ .write = spi_write_at45db,
+ .read = spi_read_at45db, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600}, /* 2.5-3.6V & 2.7-3.6V models available */
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT45DB161D",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT45DB161D,
+ .total_size = 2048 /* or 2112, determined from status register */,
+ .page_size = 512 /* or 528, determined from status register */,
+ /* does not support EWSR nor WREN and has no writable status register bits whatsoever */
+ /* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+ .feature_bits = FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_at45db,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {512, 4096} },
+ .block_erase = spi_erase_at45db_page,
+ }, {
+ .eraseblocks = { {8 * 512, 4096/8} },
+ .block_erase = spi_erase_at45db_block,
+ }, {
+ .eraseblocks = {
+ {8 * 512, 1},
+ {248 * 512, 1},
+ {256 * 512, 15},
+ },
+ .block_erase = spi_erase_at45db_sector
+ }, {
+ .eraseblocks = { {2048 * 1024, 1} },
+ .block_erase = spi_erase_at45db_chip,
+ }
+ },
+ .unlock = spi_disable_blockprotect_at45db, /* Impossible if locked down or #WP is low */
+ .printlock = spi_prettyprint_status_register_at45db,
+ /* granularity will be set by the probing function. */
+ .write = spi_write_at45db,
+ .read = spi_read_at45db, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600}, /* 2.5-3.6V & 2.7-3.6V models available */
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT45DB321C",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT45DB321C,
+ .total_size = 4224 /* No power of two sizes */,
+ .page_size = 528 /* No power of two sizes */,
+ /* does not support EWSR nor WREN and has no writable status register bits whatsoever */
+ /* OTP: 128B total, 64B pre-programmed; read 0x77 (4 dummy bytes); write 0x9A (via buffer) */
+ .feature_bits = FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {528, 8192} },
+ .block_erase = spi_erase_at45db_page,
+ }, {
+ .eraseblocks = { {8 * 528, 8192/8} },
+ .block_erase = spi_erase_at45db_block,
+ }, /* Although the datasheets describes sectors (which can be write protected)
+ * there seems to be no erase functions for them.
+ {
+ .eraseblocks = {
+ {8 * 528, 1},
+ {120 * 528, 1},
+ {128 * 528, 63},
+ },
+ .block_erase = spi_erase_at45db_sector
+ }, */ {
+ .eraseblocks = { {4224 * 1024, 1} },
+ .block_erase = spi_erase_at45db_chip,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at45db, /* Bit 0 is undefined, no lockdown */
+ .gran = write_gran_528bytes,
+ .write = spi_write_at45db,
+ .read = spi_read_at45db_e8, /* 3 address and 4 dummy bytes */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT45DB321D",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT45DB321D,
+ .total_size = 4096 /* or 4224, determined from status register */,
+ .page_size = 512 /* or 528, determined from status register */,
+ /* does not support EWSR nor WREN and has no writable status register bits whatsoever */
+ /* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+ .feature_bits = FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_at45db,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {512, 8192} },
+ .block_erase = spi_erase_at45db_page,
+ }, {
+ .eraseblocks = { {8 * 512, 8192/8} },
+ .block_erase = spi_erase_at45db_block,
+ }, {
+ .eraseblocks = {
+ {8 * 512, 1},
+ {120 * 512, 1},
+ {128 * 512, 63},
+ },
+ .block_erase = spi_erase_at45db_sector
+ }, {
+ .eraseblocks = { {4096 * 1024, 1} },
+ .block_erase = spi_erase_at45db_chip,
+ }
+ },
+ .unlock = spi_disable_blockprotect_at45db, /* Impossible if locked down or #WP is low */
+ .printlock = spi_prettyprint_status_register_at45db,
+ /* granularity will be set by the probing function. */
+ .write = spi_write_at45db,
+ .read = spi_read_at45db, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600}, /* 2.5-3.6V & 2.7-3.6V models available */
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT45DB321E",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT45DB321C,
+ .total_size = 4096 /* or 4224, determined from status register */,
+ .page_size = 512 /* or 528, determined from status register */,
+ /* does not support EWSR nor WREN and has no writable status register bits whatsoever */
+ /* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+ .feature_bits = FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_at45db,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {512, 8192} },
+ .block_erase = spi_erase_at45db_page,
+ }, {
+ .eraseblocks = { {8 * 512, 8192/8} },
+ .block_erase = spi_erase_at45db_block,
+ }, {
+ .eraseblocks = {
+ {8 * 512, 1},
+ {120 * 512, 1},
+ {128 * 512, 63},
+ },
+ .block_erase = spi_erase_at45db_sector
+ }, {
+ .eraseblocks = { {4096 * 1024, 1} },
+ .block_erase = spi_erase_at45db_chip,
+ }
+ },
+ .unlock = spi_disable_blockprotect_at45db, /* Impossible if locked down or #WP is low */
+ .printlock = spi_prettyprint_status_register_at45db, /* has a 2nd status register */
+ /* granularity will be set by the probing function. */
+ .write = spi_write_at45db,
+ .read = spi_read_at45db, /* Fast read (0x0B) supported */
+ .voltage = {2500, 3600}, /* 2.3-3.6V & 2.5-3.6V models available */
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT45DB642D",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT45DB642D,
+ .total_size = 8192 /* or 8448, determined from status register */,
+ .page_size = 1024 /* or 1056, determined from status register */,
+ /* does not support EWSR nor WREN and has no writable status register bits whatsoever */
+ /* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+ .feature_bits = FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_at45db,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {1024, 8192} },
+ .block_erase = spi_erase_at45db_page,
+ }, {
+ .eraseblocks = { {8 * 1024, 8192/8} },
+ .block_erase = spi_erase_at45db_block,
+ }, {
+ .eraseblocks = {
+ {8 * 1024, 1},
+ {248 * 1024, 1},
+ {256 * 1024, 31},
+ },
+ .block_erase = spi_erase_at45db_sector
+ }, {
+ .eraseblocks = { {8192 * 1024, 1} },
+ .block_erase = spi_erase_at45db_chip,
+ }
+ },
+ .unlock = spi_disable_blockprotect_at45db, /* Impossible if locked down or #WP is low */
+ .printlock = spi_prettyprint_status_register_at45db,
+ /* granularity will be set by the probing function. */
+ .write = spi_write_at45db,
+ .read = spi_read_at45db, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT49BV512",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT49BV512,
+ .total_size = 64,
+ .page_size = 64,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT49F002(N)",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT49F002N,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {96 * 1024, 1},
+ {128 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT49F002(N)T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT49F002NT,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PR,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {128 * 1024, 1},
+ {96 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT49(H)F010",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT49F010,
+ .total_size = 128,
+ .page_size = 0, /* unused */
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .printlock = printlock_at49f,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT49F020",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT49F020,
+ .total_size = 256,
+ .page_size = 0, /* unused */
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PRE,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ /* Chip features an optional permanent write protection
+ * of the first 8 kB. The erase function is the same as
+ * above, but 00000H to 01FFFH will not be erased.
+ * FIXME: add another eraser when partial erasers are
+ * supported.
+ */
+ },
+ .printlock = printlock_at49f,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT49F040",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT49F040,
+ .total_size = 512,
+ .page_size = 0, /* unused */
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ /* Chip features an optional permanent write protection
+ * of the first 16 kB. The erase function is the same as
+ * above, but 00000H to 03FFFH will not be erased.
+ * FIXME: add another eraser when partial erasers are
+ * supported.
+ */
+ },
+ .printlock = printlock_at49f,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT49F080",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT49F080,
+ .total_size = 1024,
+ .page_size = 0, /* unused */
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ /* Chip features an optional permanent write protection
+ * of the first 16 kB. The erase function is the same as
+ * above, but 00000H to 03FFFH will not be erased.
+ * FIXME: add another eraser when partial erasers are
+ * supported.
+ */
+ },
+ .printlock = printlock_at49f,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ /* 'top' version of AT49F080. equal in all aspects but the boot block address */
+ .vendor = "Atmel",
+ .name = "AT49F080T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT49F080T,
+ .total_size = 1024,
+ .page_size = 0, /* unused */
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ /* Chip features an optional permanent write protection
+ * of the first 16 kB. The erase function is the same as
+ * above, but FC000H to FFFFFH will not be erased.
+ * FIXME: add another eraser when partial erasers are
+ * supported.
+ */
+ },
+ .printlock = printlock_at49f,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT49LH002",
+ .bustype = BUS_LPC | BUS_FWH, /* A/A Mux */
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT49LH002,
+ .total_size = 256,
+ .page_size = 0, /* unused */
+ .feature_bits = FEATURE_REGISTERMAP, /* TODO: LPC OK too? */
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab, /* TODO: 0xff cmd not documented? */
+ .probe_timing = TIMING_FIXME,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 3},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_block_82802ab,
+ }, {
+ .eraseblocks = {
+ {64 * 1024, 4},
+ },
+ .block_erase = NULL, /* TODO: Implement. */
+ },
+ },
+ .printlock = NULL, /* TODO */
+ .unlock = NULL, /* unlock_82802ab() not correct(?) */
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Catalyst",
+ .name = "CAT28F512",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = CATALYST_ID,
+ .model_id = CATALYST_CAT28F512,
+ .total_size = 64,
+ .page_size = 0, /* unused */
+ .feature_bits = 0,
+ .tested = TEST_OK_PR,
+ .probe = probe_jedec, /* FIXME! */
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = NULL, /* TODO */
+ },
+ },
+ .write = NULL, /* TODO */
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Bright",
+ .name = "BM29F040",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = BRIGHT_ID,
+ .model_id = BRIGHT_BM29F040,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PR,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "ESMT",
+ .name = "F49B002UA",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ESMT_ID,
+ .model_id = ESMT_F49B002UA,
+ .total_size = 256,
+ .page_size = 4096,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {128 * 1024, 1},
+ {96 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "ESMT",
+ .name = "F25L008A",
+ .bustype = BUS_SPI,
+ .manufacture_id = ESMT_ID,
+ .model_id = ESMT_F25L008A,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EITHER,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_1,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "ESMT",
+ .name = "F25L32PA",
+ .bustype = BUS_SPI,
+ .manufacture_id = ESMT_ID,
+ .model_id = ESMT_F25L32PA,
+ .total_size = 4096,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EITHER | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_bpl,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B05",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B05,
+ .total_size = 64,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ {16 * 1024, 1},
+ {32 * 1024, 1},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B05T",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B05,
+ .total_size = 64,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {32 * 1024, 1},
+ {16 * 1024, 1},
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B10",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B10,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ {16 * 1024, 1},
+ {32 * 1024, 3},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B10T",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B10,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {32 * 1024, 3},
+ {16 * 1024, 1},
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B20",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B20,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ {16 * 1024, 1},
+ {32 * 1024, 1},
+ {64 * 1024, 3}
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B20T",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B20,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 3},
+ {32 * 1024, 1},
+ {16 * 1024, 1},
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B40",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B40,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ {16 * 1024, 1},
+ {32 * 1024, 1},
+ {64 * 1024, 7}
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B40T",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B40,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 7},
+ {32 * 1024, 1},
+ {16 * 1024, 1},
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B80",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B80,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ {16 * 1024, 1},
+ {32 * 1024, 1},
+ {64 * 1024, 15}
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B80T",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B80,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 15},
+ {32 * 1024, 1},
+ {16 * 1024, 1},
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B16",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B16,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ {16 * 1024, 1},
+ {32 * 1024, 1},
+ {64 * 1024, 31},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B16T",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B16,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 31},
+ {32 * 1024, 1},
+ {16 * 1024, 1},
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B32",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B32,
+ .total_size = 4096,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ {16 * 1024, 1},
+ {32 * 1024, 1},
+ {64 * 1024, 63},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B32T",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B32,
+ .total_size = 4096,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 63},
+ {32 * 1024, 1},
+ {16 * 1024, 1},
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B64",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B64,
+ .total_size = 8192,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ {16 * 1024, 1},
+ {32 * 1024, 1},
+ {64 * 1024, 127},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B64T",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B64,
+ .total_size = 8192,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 127},
+ {32 * 1024, 1},
+ {16 * 1024, 1},
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25F05",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25F05,
+ .total_size = 64,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 16} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 2} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {32 * 1024, 2} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25F10",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25F10,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25F20",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25F20,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25F40",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25F40,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PROBE,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25F80",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25F80,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25F16",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25F16,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25F32",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25F32,
+ .total_size = 4096,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25F64",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25F64,
+ .total_size = 8192,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 2048} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25Q40",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25Q40,
+ .total_size = 512,
+ .page_size = 256,
+ /* OTP: 256B total; enter 0x3A */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25Q80(A)",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25Q80,
+ .total_size = 1024,
+ .page_size = 256,
+ /* OTP: 256B total; enter 0x3A */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ /* Note: EN25D16 is an evil twin which shares the model ID
+ but has different write protection capabilities */
+ .vendor = "Eon",
+ .name = "EN25Q16",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25Q16,
+ .total_size = 2048,
+ .page_size = 256,
+ /* OTP: D16 512B/Q16 128B total; enter 0x3A */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ /* not supported by Q16 version */
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25Q32(A/B)",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25Q32,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 512B total; enter 0x3A */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25Q64",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25Q64,
+ .total_size = 8192,
+ .page_size = 256,
+ /* OTP: 512B total; enter 0x3A */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 2048} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25Q128",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25Q128,
+ .total_size = 16384,
+ .page_size = 256,
+ /* OTP: 512B total; enter 0x3A */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 4096} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 256} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {16 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {16 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25QH16",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25QH16,
+ .total_size = 2048,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 512B total; enter 0x3A */
+ /* QPI enable 0x38, disable 0xFF */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .tested = TEST_OK_PR,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 2048, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 2048, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6 is quad enable */
+ .unlock = spi_disable_blockprotect_bp3_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25QH32",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25QH32,
+ .total_size = 4096,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 512B total; enter 0x3A */
+ /* QPI enable 0x38, disable 0xFF */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 4096, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 4096, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6 is quad enable */
+ .unlock = spi_disable_blockprotect_bp3_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25QH64",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25QH64,
+ .total_size = 8192,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 512B total; enter 0x3A */
+ /* QPI enable 0x38, disable 0xFF */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .tested = TEST_OK_PR,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 2048} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 8192 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { { 8192 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6 is quad enable */
+ .unlock = spi_disable_blockprotect_bp3_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25QH128",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25QH128,
+ .total_size = 16384,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 512B total; enter 0x3A */
+ /* QPI enable 0x38, disable 0xFF */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 4096} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 256} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 16384 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { { 16384 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6 is quad enable */
+ .unlock = spi_disable_blockprotect_bp3_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25S10",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25S10,
+ .total_size = 128,
+ .page_size = 256,
+ /* OTP: 256B total; enter 0x3A */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {1650, 1950},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25S20",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25S20,
+ .total_size = 256,
+ .page_size = 256,
+ /* OTP: 256B total; enter 0x3A */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {1650, 1950},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25S40",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25S40,
+ .total_size = 512,
+ .page_size = 256,
+ /* OTP: 256B total; enter 0x3A */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {1650, 1950},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25S80",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25S80,
+ .total_size = 1024,
+ .page_size = 256,
+ /* OTP: 256B total; enter 0x3A */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {1650, 1950},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25S16",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25S16,
+ .total_size = 2048,
+ .page_size = 256,
+ /* OTP: 512B total; enter 0x3A */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {32 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2048 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2048 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_en25s_wp,
+ .unlock = spi_disable_blockprotect_bp3_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {1650, 1950},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25S32",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25S32,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 512B total; enter 0x3A */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 128} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4096 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4096 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_en25s_wp,
+ .unlock = spi_disable_blockprotect_bp3_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {1650, 1950},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25S64",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25S64,
+ .total_size = 8192,
+ .page_size = 256,
+ /* OTP: 512B total; enter 0x3A */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 2048} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8192 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {8192 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_en25s_wp,
+ .unlock = spi_disable_blockprotect_bp3_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {1650, 1950},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN29F010",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = EON_ID,
+ .model_id = EON_EN29F010,
+ .total_size = 128,
+ .page_size = 128,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PRE,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {16 * 1024, 8} },
+ .block_erase = erase_sector_jedec,
+ },
+ {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN29F002(A)(N)B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = EON_ID,
+ .model_id = EON_EN29F002B,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_ADDR_AAA | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PR,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {32 * 1024, 1},
+ {64 * 1024, 3},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN29F002(A)(N)T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = EON_ID,
+ .model_id = EON_EN29F002T,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_ADDR_AAA | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 3},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN29LV640B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = EON_ID,
+ .model_id = EON_EN29LV640B,
+ .total_size = 8192,
+ .page_size = 8192,
+ .feature_bits = 0,
+ .tested = TEST_OK_PREW,
+ .probe = probe_en29lv640b,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {8 * 1024, 8},
+ {64 * 1024, 127},
+ },
+ .block_erase = erase_block_shifted_jedec,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = erase_chip_block_shifted_jedec,
+ },
+ },
+ .write = write_en29lv640b,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Fujitsu",
+ .name = "MBM29F004BC",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = FUJITSU_ID,
+ .model_id = FUJITSU_MBM29F004BC,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {32 * 1024, 1},
+ {64 * 1024, 7},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = NULL,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Fujitsu",
+ .name = "MBM29F004TC",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = FUJITSU_ID,
+ .model_id = FUJITSU_MBM29F004TC,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 7},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = NULL,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ /* FIXME: this has WORD/BYTE sequences; 2AA for word, 555 for byte */
+ .vendor = "Fujitsu",
+ .name = "MBM29F400BC",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = FUJITSU_ID,
+ .model_id = FUJITSU_MBM29F400BC,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_SHIFTED | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_m29f400bt,
+ .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (m29f400bt.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {32 * 1024, 1},
+ {64 * 1024, 7},
+ },
+ .block_erase = erase_block_shifted_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_shifted_jedec,
+ },
+ },
+ .write = write_m29f400bt,
+ .read = read_memmapped,
+ .voltage = {4750, 5250}, /* 4.75-5.25V for type -55, others 4.5-5.5V */
+ },
+
+ {
+ .vendor = "Fujitsu",
+ .name = "MBM29F400TC",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = FUJITSU_ID,
+ .model_id = FUJITSU_MBM29F400TC,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_SHIFTED | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_m29f400bt,
+ .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (m29f400bt.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 7},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_block_shifted_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_shifted_jedec,
+ },
+ },
+ .write = write_m29f400bt,
+ .read = read_memmapped,
+ .voltage = {4750, 5250}, /* 4.75-5.25V for type -55, others 4.5-5.5V */
+ },
+
+ {
+ .vendor = "Fujitsu",
+ .name = "MBM29LV160BE",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = FUJITSU_ID,
+ .model_id = FUJITSU_MBM29LV160BE,
+ .total_size = 2 * 1024,
+ .page_size = 0,
+ .feature_bits = FEATURE_ADDR_SHIFTED | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_m29f400bt,
+ .probe_timing = TIMING_IGNORED,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {32 * 1024, 1},
+ {64 * 1024, 31},
+ },
+ .block_erase = erase_block_shifted_jedec,
+ }, {
+ .eraseblocks = { {2048 * 1024, 1} },
+ .block_erase = erase_chip_block_shifted_jedec,
+ },
+ },
+ .write = write_m29f400bt, /* Supports a fast mode too */
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* 3.0-3.6V for type -70, others 2.7-3.6V */
+ },
+
+ {
+ .vendor = "Fujitsu",
+ .name = "MBM29LV160TE",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = FUJITSU_ID,
+ .model_id = FUJITSU_MBM29LV160TE,
+ .total_size = 2 * 1024,
+ .page_size = 0,
+ .feature_bits = FEATURE_ADDR_SHIFTED | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_m29f400bt,
+ .probe_timing = TIMING_IGNORED,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 31},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_block_shifted_jedec,
+ }, {
+ .eraseblocks = { {2048 * 1024, 1} },
+ .block_erase = erase_chip_block_shifted_jedec,
+ },
+ },
+ .write = write_m29f400bt, /* Supports a fast mode too */
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* 3.0-3.6V for type -70, others 2.7-3.6V */
+ },
+
+ {
+ .vendor = "GigaDevice",
+ .name = "GD25LQ32",
+ .bustype = BUS_SPI,
+ .manufacture_id = GIGADEVICE_ID,
+ .model_id = GIGADEVICE_GD25LQ32,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 128} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp4_srwd,
+ .unlock = spi_disable_blockprotect_bp4_srwd, /* TODO: 2nd status reg (read with 0x35) */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {1700, 1950},
+ },
+
+ {
+ .vendor = "GigaDevice",
+ .name = "GD25Q512",
+ .bustype = BUS_SPI,
+ .manufacture_id = GIGADEVICE_ID,
+ .model_id = GIGADEVICE_GD25Q512,
+ .total_size = 64,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 16} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 2} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp4_srwd,
+ .unlock = spi_disable_blockprotect_bp4_srwd, /* TODO: 2nd status reg (read with 0x35) */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "GigaDevice",
+ .name = "GD25Q10",
+ .bustype = BUS_SPI,
+ .manufacture_id = GIGADEVICE_ID,
+ .model_id = GIGADEVICE_GD25Q10,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 2} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp4_srwd,
+ .unlock = spi_disable_blockprotect_bp4_srwd, /* TODO: 2nd status reg (read with 0x35) */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "GigaDevice",
+ .name = "GD25Q20(B)",
+ .bustype = BUS_SPI,
+ .manufacture_id = GIGADEVICE_ID,
+ .model_id = GIGADEVICE_GD25Q20,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 8} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp4_srwd,
+ .unlock = spi_disable_blockprotect_bp4_srwd, /* TODO: 2nd status reg (read with 0x35) */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "GigaDevice",
+ .name = "GD25Q40(B)",
+ .bustype = BUS_SPI,
+ .manufacture_id = GIGADEVICE_ID,
+ .model_id = GIGADEVICE_GD25Q40,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 16} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp4_srwd,
+ .unlock = spi_disable_blockprotect_bp4_srwd, /* TODO: 2nd status reg (read with 0x35) */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "GigaDevice",
+ .name = "GD25Q80(B)",
+ .bustype = BUS_SPI,
+ .manufacture_id = GIGADEVICE_ID,
+ .model_id = GIGADEVICE_GD25Q80,
+ .total_size = 1024,
+ .page_size = 256,
+ /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44 (B version only) */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 32} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp4_srwd,
+ .unlock = spi_disable_blockprotect_bp4_srwd, /* TODO: 2nd status reg (read with 0x35) */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "GigaDevice",
+ .name = "GD25Q16(B)",
+ .bustype = BUS_SPI,
+ .manufacture_id = GIGADEVICE_ID,
+ .model_id = GIGADEVICE_GD25Q16,
+ .total_size = 2048,
+ .page_size = 256,
+ /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44 (B version only) */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 64} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp4_srwd,
+ .unlock = spi_disable_blockprotect_bp4_srwd, /* TODO: 2nd status reg (read with 0x35) */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "GigaDevice",
+ .name = "GD25Q32(B)",
+ .bustype = BUS_SPI,
+ .manufacture_id = GIGADEVICE_ID,
+ .model_id = GIGADEVICE_GD25Q32,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 128} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp4_srwd,
+ .unlock = spi_disable_blockprotect_bp4_srwd, /* TODO: 2nd status reg (read with 0x35) */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "GigaDevice",
+ .name = "GD25Q64(B)",
+ .bustype = BUS_SPI,
+ .manufacture_id = GIGADEVICE_ID,
+ .model_id = GIGADEVICE_GD25Q64,
+ .total_size = 8192,
+ .page_size = 256,
+ /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 2048} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 256} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp4_srwd,
+ .unlock = spi_disable_blockprotect_bp4_srwd, /* TODO: 2nd status reg (read with 0x35) */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "GigaDevice",
+ .name = "GD25Q128B",
+ .bustype = BUS_SPI,
+ .manufacture_id = GIGADEVICE_ID,
+ .model_id = GIGADEVICE_GD25Q128,
+ .total_size = 16384,
+ .page_size = 256,
+ /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 4096} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 512} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 256} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {16 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {16 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp4_srwd,
+ .unlock = spi_disable_blockprotect_bp4_srwd, /* TODO: 2nd status reg (read with 0x35) */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "GigaDevice",
+ .name = "GD25T80",
+ .bustype = BUS_SPI,
+ .manufacture_id = GIGADEVICE_ID,
+ .model_id = GIGADEVICE_GD25T80,
+ .total_size = 1024,
+ .page_size = 256,
+ /* OTP: 256B total; enter 0x3A */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Hyundai",
+ .name = "HY29F002T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = HYUNDAI_ID,
+ .model_id = HYUNDAI_HY29F002T,
+ .total_size = 256,
+ .page_size = 256 * 1024,
+ .feature_bits = FEATURE_EITHER_RESET, /* Some revisions may need FEATURE_ADDR_2AA */
+ .tested = TEST_OK_PRE,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 3},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4750, 5250}, /* 4.75-5.25V for type -45, others 4.5-5.5V */
+ },
+
+ {
+ .vendor = "Hyundai",
+ .name = "HY29F002B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = HYUNDAI_ID,
+ .model_id = HYUNDAI_HY29F002B,
+ .total_size = 256,
+ .page_size = 256 * 1024,
+ .feature_bits = FEATURE_EITHER_RESET, /* Some revisions may need FEATURE_ADDR_2AA */
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {32 * 1024, 1},
+ {64 * 1024, 3},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4750, 5250}, /* 4.75-5.25V for type -45, others 4.5-5.5V */
+ },
+
+ {
+ .vendor = "Hyundai",
+ .name = "HY29F040A",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = HYUNDAI_ID,
+ .model_id = HYUNDAI_HY29F040A,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "25F160S33B8",
+ .bustype = BUS_SPI,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_25F160S33B8,
+ .total_size = 2048,
+ .page_size = 256,
+ /* OTP: 506B total (2x 8B, 30x 16B, 1x 10B); read 0x4B; write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ /* This chip supports erasing of the 8 so-called "parameter blocks" with
+ * opcode 0x40. Trying to access an address outside these 8 8kB blocks does
+ * have no effect on the memory contents, but sets a flag in the SR.
+ .eraseblocks = {
+ {8 * 1024, 8},
+ {64 * 1024, 31} // inaccessible
+ },
+ .block_erase = spi_block_erase_40,
+ }, { */
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_ep_srwd,
+ .unlock = spi_disable_blockprotect_bp2_ep_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* also fast read 0x0B */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "25F160S33T8",
+ .bustype = BUS_SPI,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_25F160S33T8,
+ .total_size = 2048,
+ .page_size = 256,
+ /* OTP: 506B total (2x 8B, 30x 16B, 1x 10B); read 0x4B; write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ /* This chip supports erasing of the 8 so-called "parameter blocks" with
+ * opcode 0x40. Trying to access an address outside these 8 8kB blocks does
+ * have no effect on the memory contents, but sets a flag in the SR.
+ .eraseblocks = {
+ {64 * 1024, 31}, // inaccessible
+ {8 * 1024, 8}
+ },
+ .block_erase = spi_block_erase_40,
+ }, { */
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_ep_srwd,
+ .unlock = spi_disable_blockprotect_bp2_ep_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* also fast read 0x0B */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "25F320S33B8",
+ .bustype = BUS_SPI,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_25F320S33B8,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 506B total (2x 8B, 30x 16B, 1x 10B); read 0x4B; write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ /* This chip supports erasing of the 8 so-called "parameter blocks" with
+ * opcode 0x40. Trying to access an address outside these 8 8kB blocks does
+ * have no effect on the memory contents, but sets a flag in the SR.
+ .eraseblocks = {
+ {8 * 1024, 8},
+ {64 * 1024, 63} // inaccessible
+ },
+ .block_erase = spi_block_erase_40,
+ }, { */
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_ep_srwd,
+ .unlock = spi_disable_blockprotect_bp2_ep_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* also fast read 0x0B */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "25F320S33T8",
+ .bustype = BUS_SPI,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_25F320S33T8,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 506B total (2x 8B, 30x 16B, 1x 10B); read 0x4B; write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ /* This chip supports erasing of the 8 so-called "parameter blocks" with
+ * opcode 0x40. Trying to access an address outside these 8 8kB blocks does
+ * have no effect on the memory contents, but sets a flag in the SR.
+ .eraseblocks = {
+ {64 * 1024, 63}, // inaccessible
+ {8 * 1024, 8}
+ },
+ .block_erase = spi_block_erase_40,
+ }, { */
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_ep_srwd,
+ .unlock = spi_disable_blockprotect_bp2_ep_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* also fast read 0x0B */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "25F640S33B8",
+ .bustype = BUS_SPI,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_25F640S33B8,
+ .total_size = 8192,
+ .page_size = 256,
+ /* OTP: 506B total (2x 8B, 30x 16B, 1x 10B); read 0x4B; write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ /* This chip supports erasing of the 8 so-called "parameter blocks" with
+ * opcode 0x40. Trying to access an address outside these 8 8kB blocks does
+ * have no effect on the memory contents, but sets a flag in the SR.
+ .eraseblocks = {
+ {8 * 1024, 8},
+ {64 * 1024, 127} // inaccessible
+ },
+ .block_erase = spi_block_erase_40,
+ }, { */
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_ep_srwd,
+ .unlock = spi_disable_blockprotect_bp2_ep_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* also fast read 0x0B */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "25F640S33T8",
+ .bustype = BUS_SPI,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_25F640S33T8,
+ .total_size = 8192,
+ .page_size = 256,
+ /* OTP: 506B total (2x 8B, 30x 16B, 1x 10B); read 0x4B; write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ /* This chip supports erasing of the 8 so-called "parameter blocks" with
+ * opcode 0x40. Trying to access an address outside these 8 8kB blocks does
+ * have no effect on the memory contents, but sets a flag in the SR.
+ .eraseblocks = {
+ {64 * 1024, 127}, // inaccessible
+ {8 * 1024, 8}
+ },
+ .block_erase = spi_block_erase_40,
+ }, { */
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_ep_srwd,
+ .unlock = spi_disable_blockprotect_bp2_ep_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* also fast read 0x0B */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "28F001BN/BX-B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_28F001B,
+ .total_size = 128,
+ .page_size = 128 * 1024, /* 8k + 2x4k + 112k */
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ {112 * 1024, 1},
+ },
+ .block_erase = erase_block_82802ab,
+ },
+ },
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "28F001BN/BX-T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_28F001T,
+ .total_size = 128,
+ .page_size = 128 * 1024, /* 112k + 2x4k + 8k */
+ .tested = TEST_OK_PR,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {112 * 1024, 1},
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ },
+ .block_erase = erase_block_82802ab,
+ },
+ },
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "28F002BC/BL/BV/BX-T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_28F002T,
+ .total_size = 256,
+ .page_size = 256 * 1024,
+ .tested = TEST_OK_PRE,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {128 * 1024, 1},
+ {96 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_block_82802ab,
+ },
+ },
+ .write = write_82802ab,
+ .read = read_memmapped,
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "28F008S3/S5/SC",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_28F004S3,
+ .total_size = 512,
+ .page_size = 256,
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_block_82802ab,
+ },
+ },
+ .unlock = unlock_28f004s5,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "28F004B5/BE/BV/BX-B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_28F004B,
+ .total_size = 512,
+ .page_size = 128 * 1024, /* maximal block size */
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {96 * 1024, 1},
+ {128 * 1024, 3},
+ },
+ .block_erase = erase_block_82802ab,
+ },
+ },
+ .write = write_82802ab,
+ .read = read_memmapped,
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "28F004B5/BE/BV/BX-T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_28F004T,
+ .total_size = 512,
+ .page_size = 128 * 1024, /* maximal block size */
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {128 * 1024, 3},
+ {96 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_block_82802ab,
+ },
+ },
+ .write = write_82802ab,
+ .read = read_memmapped,
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "28F400BV/BX/CE/CV-B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_28F400B,
+ .total_size = 512,
+ .page_size = 128 * 1024, /* maximal block size */
+ .feature_bits = FEATURE_ADDR_SHIFTED,
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {96 * 1024, 1},
+ {128 * 1024, 3},
+ },
+ .block_erase = erase_block_82802ab,
+ },
+ },
+ .write = write_82802ab,
+ .read = read_memmapped,
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "28F400BV/BX/CE/CV-T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_28F400T,
+ .total_size = 512,
+ .page_size = 128 * 1024, /* maximal block size */
+ .feature_bits = FEATURE_ADDR_SHIFTED,
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {128 * 1024, 3},
+ {96 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_block_82802ab,
+ },
+ },
+ .write = write_82802ab,
+ .read = read_memmapped,
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "82802AB",
+ .bustype = BUS_FWH,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_82802AB,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_IGNORED, /* routine does not use probe_timing (82802ab.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_block_82802ab,
+ },
+ },
+ .unlock = unlock_82802ab,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "82802AC",
+ .bustype = BUS_FWH,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_82802AC,
+ .total_size = 1024,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_OK_PR,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_IGNORED, /* routine does not use probe_timing (82802ab.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = erase_block_82802ab,
+ },
+ },
+ .unlock = unlock_82802ab,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX23L3254",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX23L3254,
+ .total_size = 4096,
+ .page_size = 256,
+ .tested = {.probe = OK, .read = OK, .erase = NA, .write = NA},
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .write = NULL, /* MX23L3254 is a mask ROM, so it is read-only */
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L512(E)/MX25V512(C)",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L512,
+ .total_size = 64,
+ .page_size = 256,
+ /* MX25L512E supports SFDP */
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 16} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_bp1_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported, MX25L512E supports dual I/O */
+ .voltage = {2700, 3600}, /* 2.35-3.6V for MX25V512(C) */
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L1005(C)/MX25L1006E",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L1005,
+ .total_size = 128,
+ .page_size = 256,
+ /* MX25L1006E supports SFDP */
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 2} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_bp1_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported, MX25L1006E supports dual I/O */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L2005(C)",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L2005,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_bp1_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L4005(A/C)",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L4005,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L8005/MX25V8005",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L8005,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600}, /* 2.35-3.6V for MX25V8005 */
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L1605",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L1605,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd, /* bit6: error flag */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L1605A/MX25L1606E",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L1605,
+ .total_size = 2048,
+ .page_size = 256,
+ /* OTP: 64B total; enter 0xB1, exit 0xC1 (MX25L1606E only) */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* MX25L1605A bp2 only */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L1605D/MX25L1608D/MX25L1673E",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = 0x14,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_res1,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6: Continously Program (CP) mode */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_1,
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L1635D",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L1635D,
+ .total_size = 2048,
+ .page_size = 256,
+ /* OTP: 64B total; enter 0xB1, exit 0xC1 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6 is quad enable */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L1635E",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L1635E,
+ .total_size = 2048,
+ .page_size = 256,
+ /* OTP: 64B total; enter 0xB1, exit 0xC1 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6 is quad enable */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L3205(A)",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L3205,
+ .total_size = 4096,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd, /* bit6: error flag */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L3205D/MX25L3208D",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L3205,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 64B total; enter 0xB1, exit 0xC1 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6: CP mode */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and dual I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L3206E",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L3205,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 64B total; enter 0xB1, exit 0xC1 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and dual I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L3273E",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L3205,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 64B total; enter 0xB1, exit 0xC1 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 128} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and dual I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L3235D",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L3235D,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 256B total; enter 0xB1, exit 0xC1 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6 is quad enable */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L6405(D)",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L6405,
+ .total_size = 8192,
+ .page_size = 256,
+ /* MX25L6405D has 64B of OTP; enter 0xB1, exit 0xC1 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6 has different meanings */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L6406E/MX25L6436E",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L6405,
+ .total_size = 8192,
+ .page_size = 256,
+ /* OTP: 06E 64B/36E 512B total; enter 0xB1, exit 0xC1 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 2048} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6 for 36E is quad enable */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L6445E/MX25L6473E",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L6405,
+ .total_size = 8192,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 512B total; enter 0xB1, exit 0xC1 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 2048} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 256} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6 is quad enable */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L12805(D)",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L12805,
+ .total_size = 16384,
+ .page_size = 256,
+ /* MX25L12805D has 64B of OTP; enter 0xB1, exit 0xC1 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 4096} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 256} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {16 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {16 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* MX25L12805D: Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25U1635E",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25U1635E,
+ .total_size = 2048,
+ .page_size = 256,
+ /* OTP: 512B total; enter 0xB1, exit 0xC1 */
+ /* QPI enable 0x35, disable 0xF5 (0xFF et al. work too) */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 64} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ /* TODO: security register */
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6 is quad enable */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {1650, 2000},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25U3235E/F",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25U3235E,
+ .total_size = 4096,
+ .page_size = 256,
+ /* F model supports SFDP */
+ /* OTP: 512B total; enter 0xB1, exit 0xC1 */
+ /* QPI enable 0x35, disable 0xF5 (0xFF et al. work too) */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 128} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ /* TODO: security register */
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6 is quad enable */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {1650, 2000},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25U6435E/F",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25U6435E,
+ .total_size = 8192,
+ .page_size = 256,
+ /* F model supports SFDP */
+ /* OTP: 512B total; enter 0xB1, exit 0xC1 */
+ /* QPI enable 0x35, disable 0xF5 (0xFF et al. work too) */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 2048} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 256} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ /* TODO: security register */
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6 is quad enable */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {1650, 2000},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX29F001B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX29F001B,
+ .total_size = 128,
+ .page_size = 32 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ {8 * 1024, 2},
+ {32 * 1024, 1},
+ {64 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX29F001T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX29F001T,
+ .total_size = 128,
+ .page_size = 32 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 1},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX29F002(N)B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX29F002B,
+ .total_size = 256,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {32 * 1024, 1},
+ {64 * 1024, 3},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX29F002(N)T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX29F002T,
+ .total_size = 256,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 3},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX29F040",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX29F040,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX29LV040",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX29LV040,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8}, },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25P05-A",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25P05A,
+ .total_size = 64,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {32 * 1024, 2} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ /* The ST M25P05 is a bit of a problem. It has the same ID as the
+ * ST M25P05-A in RES mode, but supports only 128 byte writes instead
+ * of 256 byte writes. We rely heavily on the fact that probe_spi_res1
+ * only is successful if RDID does not work.
+ */
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25P05",
+ .bustype = BUS_SPI,
+ .manufacture_id = 0, /* Not used. */
+ .model_id = ST_M25P05_RES,
+ .total_size = 64,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_res1,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {32 * 1024, 2} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_1, /* 128 */
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25P10-A",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25P10A,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PRE,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ /* The ST M25P10 has the same problem as the M25P05. */
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25P10",
+ .bustype = BUS_SPI,
+ .manufacture_id = 0, /* Not used. */
+ .model_id = ST_M25P10_RES,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_res1,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_1, /* 128 */
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST", /* Numonyx */
+ .name = "M25P20",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25P20,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp1_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25P20-old",
+ .bustype = BUS_SPI,
+ .manufacture_id = 0, /* Not used. */
+ .model_id = ST_M25P20_RES,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_res1,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp1_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST", /* Numonyx */
+ .name = "M25P40",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25P40,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25P40-old",
+ .bustype = BUS_SPI,
+ .manufacture_id = 0, /* Not used. */
+ .model_id = ST_M25P40_RES,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_res1,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25P80",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25P80,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25P16",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25P16,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25P32",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25P32,
+ .total_size = 4096,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25P64",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25P64,
+ .total_size = 8192,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25P128",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25P128,
+ .total_size = 16384,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {256 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {16 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25PE10",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25PE10,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 2} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25PE20",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25PE20,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25PE40",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25PE40,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25PE80",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25PE80,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25PE16",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25PE16,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25PX80",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25PX80,
+ .total_size = 1024,
+ .page_size = 256,
+ /* OTP: 64B total; read 0x4B, write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { { 4 * 1024, 256 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd, /* bit5: T/B */
+ .unlock = spi_disable_blockprotect_bp2_srwd, /* TODO: per 64kB sector lock registers */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25PX16",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25PX16,
+ .total_size = 2048,
+ .page_size = 256,
+ /* OTP: 64B total; read 0x4B; write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { { 4 * 1024, 512 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd, /* bit5: T/B */
+ .unlock = spi_disable_blockprotect_bp2_srwd, /* TODO: per 64kB sector lock registers */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2300, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25PX32",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25PX32,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 64B total; read 0x4B; write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PRE,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { { 4 * 1024, 1024 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd, /* bit5: T/B */
+ .unlock = spi_disable_blockprotect_bp2_srwd, /* TODO: per 64kB sector lock registers */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25PX64",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25PX64,
+ .total_size = 8192,
+ .page_size = 256,
+ /* OTP: 64B total; read 0x4B; write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { { 4 * 1024, 2048 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd, /* bit5: T/B */
+ .unlock = spi_disable_blockprotect_bp2_srwd, /* TODO: per 64kB sector lock registers */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M45PE10",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M45PE10,
+ .total_size = 128,
+ .page_size = 256,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {256, 512} },
+ .block_erase = spi_block_erase_db,
+ }, {
+ .eraseblocks = { {64 * 1024, 2} },
+ .block_erase = spi_block_erase_d8,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_default_welwip,
+ .unlock = NULL, /* #WP pin write-protects lower 64kB. */
+ .write = spi_chip_write_256, /* Page write (similar to PP but allows 0->1 changes) */
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M45PE20",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M45PE20,
+ .total_size = 256,
+ .page_size = 256,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {256, 1024} },
+ .block_erase = spi_block_erase_db,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_default_welwip,
+ .unlock = NULL, /* #WP pin write-protects lower 64kB. */
+ .write = spi_chip_write_256, /* Page write (similar to PP but allows 0->1 changes) */
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M45PE40",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M45PE40,
+ .total_size = 512,
+ .page_size = 256,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {256, 2048} },
+ .block_erase = spi_block_erase_db,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_default_welwip,
+ .unlock = NULL, /* #WP pin write-protects lower 64kB. */
+ .write = spi_chip_write_256, /* Page write (similar to PP but allows 0->1 changes) */
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M45PE80",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M45PE80,
+ .total_size = 1024,
+ .page_size = 256,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {256, 4096} },
+ .block_erase = spi_block_erase_db,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_default_welwip,
+ .unlock = NULL, /* #WP pin write-protects lower 64kB. */
+ .write = spi_chip_write_256, /* Page write (similar to PP but allows 0->1 changes) */
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M45PE16",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M45PE16,
+ .total_size = 2048,
+ .page_size = 256,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {256, 8192} },
+ .block_erase = spi_block_erase_db,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_default_welwip,
+ .unlock = NULL, /* #WP pin write-protects lower 64kB. */
+ .write = spi_chip_write_256, /* Page write (similar to PP but allows 0->1 changes) */
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "N25Q016",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_N25Q016__1E,
+ .total_size = 2048,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 64B total; read 0x4B, write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 64} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_n25q, /* TODO: config, lock, flag regs */
+ .unlock = spi_disable_blockprotect_n25q, /* TODO: per 64kB sector lock registers */
+ .write = spi_chip_write_256, /* Multi I/O supported */
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {1700, 2000},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "N25Q032..1E",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_N25Q032__1E,
+ .total_size = 4096,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 64B total; read 0x4B, write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_n25q, /* TODO: config, lock, flag regs */
+ .unlock = spi_disable_blockprotect_n25q, /* TODO: per 64kB sector lock registers */
+ .write = spi_chip_write_256, /* Multi I/O supported */
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {1700, 2000},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "N25Q032..3E",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_N25Q032__3E,
+ .total_size = 4096,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 64B total; read 0x4B, write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_n25q, /* TODO: config, lock, flag regs */
+ .unlock = spi_disable_blockprotect_n25q, /* TODO: per 64kB sector lock registers */
+ .write = spi_chip_write_256, /* Multi I/O supported */
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "N25Q064..1E", /* ..1E = 1.8V, uniform 64KB/4KB blocks/sectors */
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_N25Q064__1E,
+ .total_size = 8192,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 64B total; read 0x4B, write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 2048 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_n25q, /* TODO: config, lock, flag regs */
+ .unlock = spi_disable_blockprotect_n25q, /* TODO: per 64kB sector lock registers */
+ .write = spi_chip_write_256, /* Multi I/O supported */
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {1700, 2000},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "N25Q064..3E", /* ..3E = 3V, uniform 64KB/4KB blocks/sectors */
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_N25Q064__3E,
+ .total_size = 8192,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 64B total; read 0x4B, write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 2048 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_n25q, /* TODO: config, lock, flag regs */
+ .unlock = spi_disable_blockprotect_n25q, /* TODO: per 64kB sector lock registers */
+ .write = spi_chip_write_256, /* Multi I/O supported */
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "N25Q128..1E", /* ..1E = 1.8V, uniform 64KB/4KB blocks/sectors */
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_N25Q128__1E,
+ .total_size = 16384,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 64B total; read 0x4B, write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 4096 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 256} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {16384 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_n25q, /* TODO: config, lock, flag regs */
+ .unlock = spi_disable_blockprotect_n25q, /* TODO: per 64kB sector lock registers */
+ .write = spi_chip_write_256, /* Multi I/O supported */
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {1700, 2000},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "N25Q128..3E", /* ..3E = 3V, uniform 64KB/4KB blocks/sectors */
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_N25Q128__3E,
+ .total_size = 16384,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 64B total; read 0x4B, write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 4096 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 256} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {16384 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_n25q, /* TODO: config, lock, flag regs */
+ .unlock = spi_disable_blockprotect_n25q, /* TODO: per 64kB sector lock registers */
+ .write = spi_chip_write_256, /* Multi I/O supported */
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "MoselVitelic",
+ .name = "V29C51000B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SYNCMOS_MVC_ID,
+ .model_id = MVC_V29C51000B,
+ .total_size = 64,
+ .page_size = 512,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {512, 128} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "MoselVitelic",
+ .name = "V29C51000T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SYNCMOS_MVC_ID,
+ .model_id = MVC_V29C51000T,
+ .total_size = 64,
+ .page_size = 512,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {512, 128} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "MoselVitelic",
+ .name = "V29C51400B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SYNCMOS_MVC_ID,
+ .model_id = MVC_V29C51400B,
+ .total_size = 512,
+ .page_size = 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {1024, 512} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "MoselVitelic",
+ .name = "V29C51400T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SYNCMOS_MVC_ID,
+ .model_id = MVC_V29C51400T,
+ .total_size = 512,
+ .page_size = 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {1024, 512} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "MoselVitelic",
+ .name = "V29LC51000",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SYNCMOS_MVC_ID,
+ .model_id = MVC_V29LC51000,
+ .total_size = 64,
+ .page_size = 512,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {512, 128} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "MoselVitelic",
+ .name = "V29LC51001",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SYNCMOS_MVC_ID,
+ .model_id = MVC_V29LC51001,
+ .total_size = 128,
+ .page_size = 512,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {512, 256} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "MoselVitelic",
+ .name = "V29LC51002",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SYNCMOS_MVC_ID,
+ .model_id = MVC_V29LC51002,
+ .total_size = 256,
+ .page_size = 512,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {512, 512} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Nantronics",
+ .name = "N25S10",
+ .bustype = BUS_SPI,
+ .manufacture_id = NANTRONICS_ID_NOPREFIX,
+ .model_id = NANTRONICS_N25S10,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 2} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd,
+ .unlock = spi_disable_blockprotect_bp3_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O read (0x3B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Nantronics",
+ .name = "N25S20",
+ .bustype = BUS_SPI,
+ .manufacture_id = NANTRONICS_ID_NOPREFIX,
+ .model_id = NANTRONICS_N25S20,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {32 * 1024, 8} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd,
+ .unlock = spi_disable_blockprotect_bp3_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O read (0x3B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Nantronics",
+ .name = "N25S40",
+ .bustype = BUS_SPI,
+ .manufacture_id = NANTRONICS_ID_NOPREFIX,
+ .model_id = NANTRONICS_N25S40,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {32 * 1024, 16} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd,
+ .unlock = spi_disable_blockprotect_bp3_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O read (0x3B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Nantronics",
+ .name = "N25S80",
+ .bustype = BUS_SPI,
+ .manufacture_id = NANTRONICS_ID_NOPREFIX,
+ .model_id = NANTRONICS_N25S80,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 32} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd,
+ .unlock = spi_disable_blockprotect_bp3_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O read (0x3B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Nantronics",
+ .name = "N25S16",
+ .bustype = BUS_SPI,
+ .manufacture_id = NANTRONICS_ID_NOPREFIX,
+ .model_id = NANTRONICS_N25S16,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2048 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2048 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd,
+ .unlock = spi_disable_blockprotect_bp3_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O read (0x3B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm25LD256C",
+ .bustype = BUS_SPI,
+ .manufacture_id = PMC_ID,
+ .model_id = PMC_PM25LD256C,
+ .total_size = 32,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 8} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {4 * 1024, 8} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {32 * 1024, 1} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {32 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {32 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O supported */
+ .voltage = {2700, 3600},
+ },
+ {
+ .vendor = "PMC",
+ .name = "Pm25LD512(C)",
+ .bustype = BUS_SPI,
+ .manufacture_id = PMC_ID,
+ .model_id = PMC_PM25LD512,
+ .total_size = 64,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 16} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {4 * 1024, 16} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {32 * 1024, 2} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect, /* FIXME: C version supports "Safe Guard" */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O supported */
+ .voltage = {2300, 3600},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm25LD010(C)",
+ .bustype = BUS_SPI,
+ .manufacture_id = PMC_ID,
+ .model_id = PMC_PM25LD010,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect, /* FIXME: C version supports "Safe Guard" */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O supported */
+ .voltage = {2700, 3600}, /* 2.3-3.6V for Pm25LD010 */
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm25LD020(C)",
+ .bustype = BUS_SPI,
+ .manufacture_id = PMC_ID,
+ .model_id = PMC_PM25LD020,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect, /* FIXME: C version supports "Safe Guard" */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O supported */
+ .voltage = {2700, 3600}, /* 2.3-3.6V for Pm25LD020 */
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm25LD040(C)",
+ .bustype = BUS_SPI,
+ .manufacture_id = PMC_ID,
+ .model_id = PMC_PM25LV040,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O supported */
+ .voltage = {2700, 3600}, /* 2.3-3.6V for Pm25LD040 */
+ },
+
+{
+ .vendor = "PMC",
+ .name = "Pm25LV512(A)",
+ .bustype = BUS_SPI,
+ .manufacture_id = PMC_ID_NOPREFIX,
+ .model_id = PMC_PM25LV512,
+ .total_size = 64,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_res2, /* The continuation code is transferred as the 3rd byte m( */
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 16} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {32 * 1024, 2} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp1_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm25LV010",
+ .bustype = BUS_SPI,
+ .manufacture_id = PMC_ID_NOPREFIX,
+ .model_id = PMC_PM25LV010,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_res2, /* The continuation code is transferred as the 3rd byte m( */
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp1_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm25LV010A",
+ .bustype = BUS_SPI,
+ .manufacture_id = PMC_ID,
+ .model_id = PMC_PM25LV010,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp1_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm25LV020",
+ .bustype = BUS_SPI,
+ .manufacture_id = PMC_ID,
+ .model_id = PMC_PM25LV020,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm25LV040",
+ .bustype = BUS_SPI,
+ .manufacture_id = PMC_ID,
+ .model_id = PMC_PM25LV040,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm25LV080B",
+ .bustype = BUS_SPI,
+ .manufacture_id = PMC_ID,
+ .model_id = PMC_PM25LV080B,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm25LV016B",
+ .bustype = BUS_SPI,
+ .manufacture_id = PMC_ID,
+ .model_id = PMC_PM25LV016B,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm29F002T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = PMC_ID_NOPREFIX,
+ .model_id = PMC_PM29F002T,
+ .total_size = 256,
+ .page_size = 8 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_FIXME,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {128 * 1024, 1},
+ {96 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm29F002B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = PMC_ID_NOPREFIX,
+ .model_id = PMC_PM29F002B,
+ .total_size = 256,
+ .page_size = 8 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_FIXME,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {96 * 1024, 1},
+ {128 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm39LV010",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = PMC_ID_NOPREFIX,
+ .model_id = PMC_PM39F010, /* Pm39LV010 and Pm39F010 have identical IDs but different voltage */
+ .total_size = 128,
+ .page_size = 4096,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 2} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm39LV020",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = PMC_ID_NOPREFIX,
+ .model_id = PMC_PM39LV020,
+ .total_size = 256,
+ .page_size = 4096,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm39LV040",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = PMC_ID_NOPREFIX,
+ .model_id = PMC_PM39LV040,
+ .total_size = 512,
+ .page_size = 4096,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PR,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm39LV512",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = PMC_ID_NOPREFIX,
+ .model_id = PMC_PM39LV512,
+ .total_size = 64,
+ .page_size = 4096,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 16} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm49FL002",
+ .bustype = BUS_LPC | BUS_FWH, /* A/A Mux */
+ .manufacture_id = PMC_ID_NOPREFIX,
+ .model_id = PMC_PM49FL002,
+ .total_size = 256,
+ .page_size = 16 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* routine is wrapper to probe_jedec (pm49fl00x.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {16 * 1024, 16} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .unlock = unlock_49fl00x,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm49FL004",
+ .bustype = BUS_LPC | BUS_FWH, /* A/A Mux */
+ .manufacture_id = PMC_ID_NOPREFIX,
+ .model_id = PMC_PM49FL004,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* routine is wrapper to probe_jedec (pm49fl00x.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .unlock = unlock_49fl00x,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Sanyo",
+ .name = "LE25FW106",
+ .bustype = BUS_SPI,
+ .manufacture_id = SANYO_ID,
+ .model_id = SANYO_LE25FW106,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_res2,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {2 * 1024, 64} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp1_srwd, /* FIXME: Add ERSER error flag. */
+ .unlock = spi_disable_blockprotect_bp1_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Sanyo",
+ .name = "LE25FW406A",
+ .bustype = BUS_SPI,
+ .manufacture_id = SANYO_ID,
+ .model_id = SANYO_LE25FW406A,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_res2,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Sanyo",
+ .name = "LE25FU406B",
+ .bustype = BUS_SPI,
+ .manufacture_id = SANYO_ID,
+ .model_id = SANYO_LE25FU406B,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_res2,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect, /* #WP pin write-protects SRWP bit. */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2300, 3600},
+ },
+
+ {
+ .vendor = "Sanyo",
+ .name = "LE25FW203A",
+ .bustype = BUS_SPI,
+ .manufacture_id = SANYO_ID,
+ .model_id = SANYO_LE25FW203A,
+ .total_size = 256,
+ .page_size = 256,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {256, 1024} },
+ .block_erase = spi_block_erase_db,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_default_welwip,
+ .unlock = NULL, /* #WP pin write-protects lower 64kB. */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Sanyo",
+ .name = "LE25FW403A",
+ .bustype = BUS_SPI,
+ .manufacture_id = SANYO_ID,
+ .model_id = SANYO_LE25FW403A,
+ .total_size = 512,
+ .page_size = 256,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {256, 2 * 1024} },
+ .block_erase = spi_block_erase_db,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_default_welwip,
+ .unlock = NULL, /* #WP pin write-protects lower 64kB. */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Sanyo",
+ .name = "LE25FW418A",
+ .bustype = BUS_SPI,
+ .manufacture_id = SANYO_ID,
+ .model_id = SANYO_LE25FW418A,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_res2,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect, /* #WP pin write-protects SRWP bit. */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* some quad-read supported ("HD_READ mode") */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Sanyo",
+ .name = "LE25FW806",
+ .bustype = BUS_SPI,
+ .manufacture_id = SANYO_ID,
+ .model_id = SANYO_LE25FW806,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_res2,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect, /* #WP pin write-protects SRWP bit. */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Sanyo",
+ .name = "LE25FW808",
+ .bustype = BUS_SPI,
+ .manufacture_id = SANYO_ID,
+ .model_id = SANYO_LE25FW808,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_res2,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {8 * 1024, 128} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect, /* #WP pin write-protects SRWP bit. */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* some quad-read supported ("HD_READ mode") */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Sharp",
+ .name = "LH28F008BJT-BTLZ1",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SHARP_ID,
+ .model_id = SHARP_LH28F008BJ__PB,
+ .total_size = 1024,
+ .page_size = 64 * 1024,
+ .tested = TEST_OK_PREW,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {8 * 1024, 8},
+ {64 * 1024, 15}
+ },
+ .block_erase = erase_block_82802ab,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = erase_sector_49lfxxxc,
+ }
+ },
+ .unlock = unlock_lh28f008bjt,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Sharp",
+ .name = "LHF00L04",
+ .bustype = BUS_FWH, /* A/A Mux */
+ .manufacture_id = SHARP_ID,
+ .model_id = SHARP_LHF00L04,
+ .total_size = 1024,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_EITHER_RESET | FEATURE_REGISTERMAP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 15},
+ {8 * 1024, 8}
+ },
+ .block_erase = erase_block_82802ab,
+ }, {
+ .eraseblocks = {
+ {1024 * 1024, 1}
+ },
+ .block_erase = NULL, /* 30 D0, only in A/A mux mode */
+ },
+ },
+ .unlock = unlock_82802ab,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Spansion",
+ .name = "S25FL004A",
+ .bustype = BUS_SPI,
+ .manufacture_id = SPANSION_ID,
+ .model_id = SPANSION_S25FL004A,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Spansion",
+ .name = "S25FL008A",
+ .bustype = BUS_SPI,
+ .manufacture_id = SPANSION_ID,
+ .model_id = SPANSION_S25FL008A,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PRE,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Spansion",
+ .name = "S25FL016A",
+ .bustype = BUS_SPI,
+ .manufacture_id = SPANSION_ID,
+ .model_id = SPANSION_S25FL016A,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PR,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Spansion",
+ .name = "S25FL032A/P",
+ .bustype = BUS_SPI,
+ .manufacture_id = SPANSION_ID,
+ .model_id = SPANSION_S25FL032A,
+ .total_size = 4096,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Spansion",
+ .name = "S25FL064A/P",
+ .bustype = BUS_SPI,
+ .manufacture_id = SPANSION_ID,
+ .model_id = SPANSION_S25FL064A,
+ .total_size = 8192,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Spansion",
+ .name = "S25FL204K",
+ .bustype = BUS_SPI,
+ .manufacture_id = SPANSION_ID,
+ .model_id = SPANSION_S25FL204,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { { 512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd,
+ .unlock = spi_disable_blockprotect_bp3_srwd, /* #WP pin write-protects SRWP bit. */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O (0x3B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Spansion",
+ .name = "S25FL208K",
+ .bustype = BUS_SPI,
+ .manufacture_id = SPANSION_ID,
+ .model_id = SPANSION_S25FL208,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { { 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd,
+ .unlock = spi_disable_blockprotect_bp3_srwd, /* #WP pin write-protects SRWP bit. */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O (0x3B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Spansion",
+ .name = "S25FL116K/S25FL216K",
+ .bustype = BUS_SPI,
+ .manufacture_id = SPANSION_ID,
+ .model_id = SPANSION_S25FL216,
+ .total_size = 2048,
+ .page_size = 256,
+ /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44 (S25FL116K only) */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 2048 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { { 2048 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd,
+ .unlock = spi_disable_blockprotect_bp3_srwd, /* #WP pin write-protects SRWP bit. */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O (0x3B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Spansion",
+ .name = "S25FL132K",
+ .bustype = BUS_SPI,
+ .manufacture_id = SPANSION_ID,
+ .model_id = SPANSION_S25FL132K,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 768B total, 256B reserved; read 0x48; write 0x42, erase 0x44 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 4096 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { { 4096 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd, /* TODO: improve */
+ .unlock = spi_disable_blockprotect_bp2_srwd, /* #WP pin write-protects SRWP bit. */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Spansion",
+ .name = "S25FL164K",
+ .bustype = BUS_SPI,
+ .manufacture_id = SPANSION_ID,
+ .model_id = SPANSION_S25FL164K,
+ .total_size = 8192,
+ .page_size = 256,
+ /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 2048} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 8192 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { { 8192 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd, /* TODO: improve */
+ .unlock = spi_disable_blockprotect_bp2_srwd, /* #WP pin write-protects SRWP bit. */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Spansion",
+ .name = "S25FL128S......0", /* uniform 256kB sectors */
+ .bustype = BUS_SPI,
+ .manufacture_id = SPANSION_ID,
+ .model_id = SPANSION_S25FL128,
+ .total_size = 16384,
+ .page_size = 256,
+ /* supports 4B addressing */
+ /* OTP: 1024B total, 32B reserved; read 0x4B; write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 4096} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {256 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 16384 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { { 16384 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_ep_srwd, /* TODO: SR2 and many others */
+ .unlock = spi_disable_blockprotect_bp2_srwd, /* TODO: various other locks */
+ .write = spi_chip_write_256, /* Multi I/O supported */
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25LF020A",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25VF020_REMS,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EWSR,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rems,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 8} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* FIXME: No BP2 & 3 */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_1, /* AAI supported, but opcode is 0xAF */
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25LF040A",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25VF040_REMS,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EWSR,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_res2,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 16} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_1, /* AAI supported, but opcode is 0xAF */
+ .read = spi_chip_read,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25LF080(A)",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25VF080_REMS,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EITHER,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_res2,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 32} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_1, /* AAI supported, but opcode is 0xAF */
+ .read = spi_chip_read,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25VF512A",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25VF512A_REMS,
+ .total_size = 64,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EWSR,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rems,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 16} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 2} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {32 * 1024, 2} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* FIXME: No BP2 & 3 */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_1, /* AAI supported, but opcode is 0xAF */
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25VF010",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25VF010_REMS,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EWSR,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rems,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* FIXME: No BP2 & 3 */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_1, /* AAI supported, but opcode is 0xAF */
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25VF020",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25VF020_REMS,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EWSR,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rems,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 8} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* FIXME: No BP2 & 3 */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_1, /* AAI supported, but opcode is 0xAF */
+ .read = spi_chip_read, /* only */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25VF020B",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25VF020B,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EWSR,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 8} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* FIXME: No BP2 & 3 and 2nd SR */
+ .unlock = spi_disable_blockprotect, /* FIXME: 2nd SR */
+ .write = spi_aai_write, /* AAI supported (0xAD) */
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25VF040",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25VF040_REMS,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EWSR,
+ .tested = TEST_OK_PR,
+ .probe = probe_spi_rems,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 16} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_1, /* AAI supported, but opcode is 0xAF */
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25VF040B",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25VF040B,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EWSR,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 16} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25vf040b,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_aai_write, /* AAI supported (0xAD) */
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25VF040B.REMS",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25VF040B_REMS,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EWSR,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rems,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 16} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25vf040b,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_aai_write,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25VF080B",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25VF080B,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EWSR,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 32} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_aai_write,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25VF016B",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25VF016B,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EITHER,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 64} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25vf016,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_aai_write,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25VF032B",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25VF032B,
+ .total_size = 4096,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EWSR,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 128} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_aai_write,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25VF064C",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25VF064C,
+ .total_size = 8192,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EWSR,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 2048} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 256} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25WF512",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25WF512,
+ .total_size = 64,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EITHER,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 16} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 2} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {1024 * 64, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 64, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* FIXME: does not have a BP3 */
+ .unlock = spi_disable_blockprotect_bp2_srwd,
+ .write = spi_aai_write,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {1650, 1950},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25WF010",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25WF010,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EITHER,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {1024 * 128, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 128, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* FIXME: does not have a BP3 */
+ .unlock = spi_disable_blockprotect_bp2_srwd,
+ .write = spi_aai_write,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {1650, 1950},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25WF020",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25WF020,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EITHER,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 8} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 256, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 256, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* FIXME: does not have a BP3 */
+ .unlock = spi_disable_blockprotect_bp2_srwd,
+ .write = spi_aai_write,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {1650, 1950},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25WF040",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25WF040,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EITHER,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 16} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 512, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 512, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* FIXME: does not have a BP3 */
+ .unlock = spi_disable_blockprotect_bp2_srwd,
+ .write = spi_aai_write,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {1650, 1950},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25WF080",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25WF080,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EITHER,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 32} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* *does* have a BP3 but it is useless */
+ .unlock = spi_disable_blockprotect_bp3_srwd,
+ .write = spi_aai_write,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {1650, 1950},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST28SF040A",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST28SF040,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = 0,
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (sst28sf040.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {128, 4096} },
+ .block_erase = erase_sector_28sf040,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_28sf040,
+ }
+ },
+ .unlock = unprotect_28sf040,
+ .write = write_28sf040,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST29EE010",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST29EE010,
+ .total_size = 128,
+ .page_size = 128,
+ .feature_bits = FEATURE_LONG_RESET,
+ .tested = TEST_OK_PR,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST29LE010",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST29LE010,
+ .total_size = 128,
+ .page_size = 128,
+ .feature_bits = FEATURE_LONG_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST29EE020A",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST29EE020A,
+ .total_size = 256,
+ .page_size = 128,
+ .feature_bits = FEATURE_LONG_RESET,
+ .tested = TEST_OK_PRE,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST29LE020",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST29LE020,
+ .total_size = 256,
+ .page_size = 128,
+ .feature_bits = FEATURE_LONG_RESET,
+ .tested = TEST_OK_PRE,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST39SF512",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST39SF512,
+ .total_size = 64,
+ .page_size = 4096,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 16} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST39SF010A",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST39SF010,
+ .total_size = 128,
+ .page_size = 4096,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST39SF020A",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST39SF020,
+ .total_size = 256,
+ .page_size = 4096,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST39SF040",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST39SF040,
+ .total_size = 512,
+ .page_size = 4096,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST39VF512",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST39VF512,
+ .total_size = 64,
+ .page_size = 4096,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 16} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST39VF010",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST39VF010,
+ .total_size = 128,
+ .page_size = 4096,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST39VF020",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST39VF020,
+ .total_size = 256,
+ .page_size = 4096,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST39VF040",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST39VF040,
+ .total_size = 512,
+ .page_size = 4096,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST39VF080",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST39VF080,
+ .total_size = 1024,
+ .page_size = 4096,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST49LF002A/B",
+ .bustype = BUS_FWH, /* A/A Mux */
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST49LF002A,
+ .total_size = 256,
+ .page_size = 16 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {16 * 1024, 16} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = NULL, /* AA 55 80 AA 55 10, only in A/A mux mode */
+ }
+ },
+ .printlock = printlock_sst_fwhub,
+ .unlock = unlock_sst_fwhub,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST49LF003A/B",
+ .bustype = BUS_FWH, /* A/A Mux */
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST49LF003A,
+ .total_size = 384,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 96} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 6} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {384 * 1024, 1} },
+ .block_erase = NULL, /* AA 55 80 AA 55 10, only in A/A mux mode */
+ }
+ },
+ .printlock = printlock_sst_fwhub,
+ .unlock = unlock_sst_fwhub,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ /* Contrary to the data sheet, TBL# on the SST49LF004B affects the top 128kB (instead of 64kB)
+ * and is only honored for 64k block erase, but not 4k sector erase.
+ */
+ .vendor = "SST",
+ .name = "SST49LF004A/B",
+ .bustype = BUS_FWH, /* A/A Mux */
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST49LF004A,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = NULL, /* AA 55 80 AA 55 10, only in A/A mux mode */
+ },
+ },
+ .printlock = printlock_sst_fwhub,
+ .unlock = unlock_sst_fwhub,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST49LF004C",
+ .bustype = BUS_FWH,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST49LF004C,
+ .total_size = 512,
+ .page_size = 4 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (sst49lfxxxc.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = erase_sector_49lfxxxc,
+ }, {
+ .eraseblocks = {
+ {64 * 1024, 7},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_block_82802ab,
+ }
+ },
+ .unlock = unlock_49lfxxxc,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST49LF008A",
+ .bustype = BUS_FWH, /* A/A Mux */
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST49LF008A,
+ .total_size = 1024,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = NULL, /* AA 55 80 AA 55 10, only in A/A mux mode */
+ }
+ },
+ .printlock = printlock_sst_fwhub,
+ .unlock = unlock_sst_fwhub,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST49LF008C",
+ .bustype = BUS_FWH,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST49LF008C,
+ .total_size = 1024,
+ .page_size = 4 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (sst49lfxxxc.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = erase_sector_49lfxxxc,
+ }, {
+ .eraseblocks = {
+ {64 * 1024, 15},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_block_82802ab,
+ }
+ },
+ .unlock = unlock_49lfxxxc,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST49LF016C",
+ .bustype = BUS_FWH,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST49LF016C,
+ .total_size = 2048,
+ .page_size = 4 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (sst49lfxxxc.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = erase_sector_49lfxxxc,
+ }, {
+ .eraseblocks = {
+ {64 * 1024, 31},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_block_82802ab,
+ }
+ },
+ .unlock = unlock_49lfxxxc,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST49LF020",
+ .bustype = BUS_LPC,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST49LF020,
+ .total_size = 256,
+ .page_size = 16 * 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {16 * 1024, 16} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = NULL,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST49LF020A",
+ .bustype = BUS_LPC,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST49LF020A,
+ .total_size = 256,
+ .page_size = 4 * 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PRE,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {16 * 1024, 16} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = NULL,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST49LF040",
+ .bustype = BUS_LPC,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST49LF040,
+ .total_size = 512,
+ .page_size = 4096,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = NULL,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST49LF040B",
+ .bustype = BUS_LPC, /* A/A Mux */
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST49LF040B,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_EITHER_RESET | FEATURE_REGISTERMAP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = NULL,
+ }
+ },
+ .unlock = unlock_82802ab,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST49LF080A",
+ .bustype = BUS_LPC, /* A/A Mux */
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST49LF080A,
+ .total_size = 1024,
+ .page_size = 4096,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_FIXME,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = NULL,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST49LF160C",
+ .bustype = BUS_LPC,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST49LF160C,
+ .total_size = 2048,
+ .page_size = 4 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_OK_PRE,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (sst49lfxxxc.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = erase_sector_49lfxxxc,
+ }, {
+ .eraseblocks = {
+ {64 * 1024, 31},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_block_82802ab,
+ }
+ },
+ .unlock = unlock_49lfxxxc,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M29F002B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M29F002B,
+ .total_size = 256,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_AAA | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {32 * 1024, 1},
+ {64 * 1024, 3},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4750, 5250}, /* 4.75-5.25V for type -X, others 4.5-5.5V */
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M29F002T/NT",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M29F002T,
+ .total_size = 256,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_AAA | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 3},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4750, 5250}, /* 4.75-5.25V for type -X, others 4.5-5.5V */
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M29F040B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M29F040B,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* datasheet specifies no timing */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8}, },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ /* FIXME: this has WORD/BYTE sequences; 2AA for word, 555 for byte */
+ .vendor = "ST",
+ .name = "M29F400BB",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M29F400BB,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_SHIFTED | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_m29f400bt,
+ .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (m29f400bt.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {32 * 1024, 1},
+ {64 * 1024, 7},
+ },
+ .block_erase = erase_block_shifted_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_shifted_jedec,
+ }
+ },
+ .write = write_m29f400bt,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+ {
+ /* FIXME: this has WORD/BYTE sequences; 2AA for word, 555 for byte */
+ .vendor = "ST",
+ .name = "M29F400BT",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M29F400BT,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_SHIFTED | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_m29f400bt,
+ .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (m29f400bt.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 7},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_block_shifted_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_shifted_jedec,
+ }
+ },
+ .write = write_m29f400bt,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M29W010B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M29W010B,
+ .total_size = 128,
+ .page_size = 16 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {16 * 1024, 8}, },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M29W040B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M29W040B,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8}, },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M29W512B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M29W512B,
+ .total_size = 64,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M50FLW040A",
+ .bustype = BUS_FWH | BUS_LPC, /* A/A Mux */
+ .manufacture_id = ST_ID,
+ .model_id = ST_M50FLW040A,
+ .total_size = 512,
+ .page_size = 0,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_FIXME,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 16}, /* sector */
+ {64 * 1024, 5}, /* block */
+ {4 * 1024, 16}, /* sector */
+ {4 * 1024, 16}, /* sector */
+ },
+ .block_erase = erase_sector_stm50,
+ }, {
+ .eraseblocks = { {64 * 1024, 8}, },
+ .block_erase = erase_block_82802ab,
+ }
+ },
+ .write = write_82802ab,
+ .unlock = unlock_stm50_uniform,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* Also has 12V fast program & erase */
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M50FLW040B",
+ .bustype = BUS_FWH | BUS_LPC, /* A/A Mux */
+ .manufacture_id = ST_ID,
+ .model_id = ST_M50FLW040B,
+ .total_size = 512,
+ .page_size = 0,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_FIXME,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 16}, /* sector */
+ {4 * 1024, 16}, /* sector */
+ {64 * 1024, 5}, /* block */
+ {4 * 1024, 16}, /* sector */
+ },
+ .block_erase = erase_sector_stm50,
+ }, {
+ .eraseblocks = { {64 * 1024, 8}, },
+ .block_erase = erase_block_82802ab,
+ }
+ },
+ .write = write_82802ab,
+ .unlock = unlock_stm50_uniform,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* Also has 12V fast program & erase */
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M50FLW080A",
+ .bustype = BUS_FWH | BUS_LPC, /* A/A Mux */
+ .manufacture_id = ST_ID,
+ .model_id = ST_M50FLW080A,
+ .total_size = 1024,
+ .page_size = 0,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_OK_PRE,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_FIXME,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 16}, /* sector */
+ {64 * 1024, 13}, /* block */
+ {4 * 1024, 16}, /* sector */
+ {4 * 1024, 16}, /* sector */
+ },
+ .block_erase = erase_sector_stm50,
+ }, {
+ .eraseblocks = { {64 * 1024, 16}, },
+ .block_erase = erase_block_82802ab,
+ }
+ },
+ .unlock = unlock_stm50_nonuniform,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* Also has 12V fast program & erase */
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M50FLW080B",
+ .bustype = BUS_FWH | BUS_LPC, /* A/A Mux */
+ .manufacture_id = ST_ID,
+ .model_id = ST_M50FLW080B,
+ .total_size = 1024,
+ .page_size = 0,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_FIXME,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 16}, /* sector */
+ {4 * 1024, 16}, /* sector */
+ {64 * 1024, 13}, /* block */
+ {4 * 1024, 16}, /* sector */
+ },
+ .block_erase = erase_sector_stm50,
+ }, {
+ .eraseblocks = { {64 * 1024, 16}, },
+ .block_erase = erase_block_82802ab,
+ }
+ },
+ .unlock = unlock_stm50_nonuniform,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* Also has 12V fast program & erase */
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M50FW002",
+ .bustype = BUS_FWH, /* A/A Mux */
+ .manufacture_id = ST_ID,
+ .model_id = ST_M50FW002,
+ .total_size = 256,
+ .page_size = 0,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (sst49lfxxxc.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 3},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_block_82802ab,
+ }
+ },
+ .unlock = unlock_stm50_nonuniform,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* Also has 12V fast program & erase */
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M50FW016",
+ .bustype = BUS_FWH, /* A/A Mux */
+ .manufacture_id = ST_ID,
+ .model_id = ST_M50FW016,
+ .total_size = 2048,
+ .page_size = 0,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (82802ab.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 32}, },
+ .block_erase = erase_block_82802ab,
+ }
+ },
+ .unlock = unlock_stm50_uniform,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* Also has 12V fast program & erase */
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M50FW040",
+ .bustype = BUS_FWH, /* A/A Mux */
+ .manufacture_id = ST_ID,
+ .model_id = ST_M50FW040,
+ .total_size = 512,
+ .page_size = 0,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_OK_PR,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (82802ab.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8}, },
+ .block_erase = erase_block_82802ab,
+ }
+ },
+ .unlock = unlock_stm50_uniform,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* Also has 12V fast program & erase */
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M50FW080",
+ .bustype = BUS_FWH, /* A/A Mux */
+ .manufacture_id = ST_ID,
+ .model_id = ST_M50FW080,
+ .total_size = 1024,
+ .page_size = 0,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (82802ab.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 16}, },
+ .block_erase = erase_block_82802ab,
+ }
+ },
+ .unlock = unlock_stm50_uniform,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* Also has 12V fast program & erase */
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M50LPW080",
+ .bustype = BUS_LPC, /* A/A Mux */
+ .manufacture_id = ST_ID,
+ .model_id = ST_M50LPW080,
+ .total_size = 1024,
+ .page_size = 0,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 16}, },
+ .block_erase = erase_block_82802ab,
+ }
+ },
+ .unlock = unlock_stm50_uniform,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* Also has 12V fast program & erase */
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M50LPW116",
+ .bustype = BUS_LPC, /* A/A Mux */
+ .manufacture_id = ST_ID,
+ .model_id = ST_M50LPW116,
+ .total_size = 2048,
+ .page_size = 0,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 16},
+ {64 * 1024, 30},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_block_82802ab,
+ }
+ },
+ .unlock = unlock_stm50_nonuniform,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* Also has 12V fast program & erase */
+ },
+
+ {
+ .vendor = "SyncMOS/MoselVitelic",
+ .name = "{F,S,V}29C51001B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SYNCMOS_MVC_ID,
+ .model_id = SM_MVC_29C51001B,
+ .total_size = 128,
+ .page_size = 512,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {512, 256} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "SyncMOS/MoselVitelic",
+ .name = "{F,S,V}29C51001T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SYNCMOS_MVC_ID,
+ .model_id = SM_MVC_29C51001T,
+ .total_size = 128,
+ .page_size = 512,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {512, 256} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "SyncMOS/MoselVitelic",
+ .name = "{F,S,V}29C51002B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SYNCMOS_MVC_ID,
+ .model_id = SM_MVC_29C51002B,
+ .total_size = 256,
+ .page_size = 512,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {512, 512} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ },
+
+ {
+ .vendor = "SyncMOS/MoselVitelic",
+ .name = "{F,S,V}29C51002T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SYNCMOS_MVC_ID,
+ .model_id = SM_MVC_29C51002T,
+ .total_size = 256,
+ .page_size = 512,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {512, 512} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ },
+
+ {
+ .vendor = "SyncMOS/MoselVitelic",
+ .name = "{F,S,V}29C51004B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SYNCMOS_MVC_ID,
+ .model_id = SM_MVC_29C51004B,
+ .total_size = 512,
+ .page_size = 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {1024, 512} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "SyncMOS/MoselVitelic",
+ .name = "{F,S,V}29C51004T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SYNCMOS_MVC_ID,
+ .model_id = SM_MVC_29C51004T,
+ .total_size = 512,
+ .page_size = 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {1024, 512} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "SyncMOS/MoselVitelic",
+ .name = "{S,V}29C31004B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SYNCMOS_MVC_ID,
+ .model_id = SM_MVC_29C31004B,
+ .total_size = 512,
+ .page_size = 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {1024, 512} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SyncMOS/MoselVitelic",
+ .name = "{S,V}29C31004T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SYNCMOS_MVC_ID,
+ .model_id = SM_MVC_29C31004T,
+ .total_size = 512,
+ .page_size = 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {1024, 512} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "TI",
+ .name = "TMS29F002RB",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = TI_OLD_ID,
+ .model_id = TI_TMS29F002RB,
+ .total_size = 256,
+ .page_size = 16384, /* Non-uniform sectors */
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {32 * 1024, 1},
+ {64 * 1024, 3},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "TI",
+ .name = "TMS29F002RT",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = TI_OLD_ID,
+ .model_id = TI_TMS29F002RT,
+ .total_size = 256,
+ .page_size = 16384, /* Non-uniform sectors */
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 3},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25Q80.V",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25Q80_V,
+ .total_size = 1024,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44, read ID 0x4B */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 32} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25Q16.V",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25Q16_V,
+ .total_size = 2048,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44, read ID 0x4B */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 64} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25Q32.V",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25Q32_V,
+ .total_size = 4096,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44, read ID 0x4B */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 128} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25Q64.V",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25Q64_V,
+ .total_size = 8192,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44, read ID 0x4B */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 2048} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 256} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25Q128.V",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25Q128_V,
+ .total_size = 16384,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44, read ID 0x4B */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 4096} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 512} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 256} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {16 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {16 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25Q20.W",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25Q20_W,
+ .total_size = 256,
+ .page_size = 256,
+ /* OTP: 256B total; read 0x48; write 0x42, erase 0x44, read ID 0x4B */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 8} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {1700, 1950}, /* Fast read (0x0B) and multi I/O supported */
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25Q40.W",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25Q40_W,
+ .total_size = 512,
+ .page_size = 256,
+ /* OTP: 256B total; read 0x48; write 0x42, erase 0x44, read ID 0x4B */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 16} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {1700, 1950}, /* Fast read (0x0B) and multi I/O supported */
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25Q80.W",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25Q80_W,
+ .total_size = 1024,
+ .page_size = 256,
+ /* OTP: 256B total; read 0x48; write 0x42, erase 0x44, read ID 0x4B */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 32} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {1700, 1950}, /* Fast read (0x0B) and multi I/O supported */
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25Q16.W",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25Q16_W,
+ .total_size = 2048,
+ .page_size = 256,
+ /* OTP: 256B total; read 0x48; write 0x42, erase 0x44, read ID 0x4B */
+ /* QPI enable 0x38, disable 0xFF */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 64} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {1700, 1950}, /* Fast read (0x0B) and multi I/O supported */
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25Q32.W",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25Q32_W,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 256B total; read 0x48; write 0x42, erase 0x44, read ID 0x4B */
+ /* QPI enable 0x38, disable 0xFF */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 128} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {1700, 1950}, /* Fast read (0x0B) and multi I/O supported */
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25Q64.W",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25Q64_W,
+ .total_size = 8192,
+ .page_size = 256,
+ /* OTP: 256B total; read 0x48; write 0x42, erase 0x44, read ID 0x4B */
+ /* QPI enable 0x38, disable 0xFF */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 2048} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 256} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {1700, 1950}, /* Fast read (0x0B) and multi I/O supported */
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25X10",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25X10,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 2} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25X20",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25X20,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25X40",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25X40,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25X80",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25X80,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25X16",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25X16,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 64} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25X32",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25X32,
+ .total_size = 4096,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 128} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25X64",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25X64,
+ .total_size = 8192,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PROBE,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 2048} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 256} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W29C010(M)/W29C011A/W29EE011/W29EE012-old",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W29C010,
+ .total_size = 128,
+ .page_size = 128,
+ .feature_bits = FEATURE_LONG_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_w29ee011,
+ .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (w29ee011.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec,
+ .read = read_memmapped,
+ },
+
+ {/* W29EE011, W29EE012, W29C010M, W29C011A do not support probe_jedec according to the datasheet, but it works for newer(?) steppings. */
+ .vendor = "Winbond",
+ .name = "W29C010(M)/W29C011A/W29EE011/W29EE012",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W29C010,
+ .total_size = 128,
+ .page_size = 128,
+ .feature_bits = FEATURE_LONG_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10, /* used datasheet for the W29C011A */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec,
+ .read = read_memmapped,
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W29C020(C)/W29C022",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W29C020,
+ .total_size = 256,
+ .page_size = 128,
+ .feature_bits = FEATURE_LONG_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W29C040/P",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W29C040,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_LONG_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W39F010",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W39F010,
+ .total_size = 128,
+ .page_size = 4 * 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .printlock = printlock_w39f010,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W39L010",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W39L010,
+ .total_size = 128,
+ .page_size = 4 * 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .printlock = printlock_w39l010,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W39L020",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W39L020,
+ .total_size = 256,
+ .page_size = 4 * 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .printlock = printlock_w39l020,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W39L040",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W39L040,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PR,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .printlock = printlock_w39l040,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W39V040A",
+ .bustype = BUS_LPC,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W39V040A,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .printlock = printlock_w39v040a,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W39V040B",
+ .bustype = BUS_LPC,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W39V040B,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .printlock = printlock_w39v040b,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W39V040C",
+ .bustype = BUS_LPC,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W39V040C,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .printlock = printlock_w39v040c,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W39V040FA",
+ .bustype = BUS_FWH,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W39V040FA,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .printlock = printlock_w39v040fa,
+ .unlock = unlock_sst_fwhub,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W39V040FB",
+ .bustype = BUS_FWH,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W39V040B,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .printlock = printlock_w39v040fb,
+ .unlock = unlock_w39v040fb,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* Also has 12V fast program */
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W39V040FC",
+ .bustype = BUS_FWH,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W39V040C,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .printlock = printlock_w39v040fc,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* Also has 12V fast program */
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W39V080A",
+ .bustype = BUS_LPC,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W39V080A,
+ .total_size = 1024,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .printlock = printlock_w39v080a,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W49F002U/N",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W49F002U,
+ .total_size = 256,
+ .page_size = 128,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {128 * 1024, 1},
+ {96 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W49F020",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W49F020,
+ .total_size = 256,
+ .page_size = 128,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PROBE,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W49V002A",
+ .bustype = BUS_LPC,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W49V002A,
+ .total_size = 256,
+ .page_size = 128,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 3},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W49V002FA",
+ .bustype = BUS_FWH,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W49V002FA,
+ .total_size = 256,
+ .page_size = 128,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 3},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W39V080FA",
+ .bustype = BUS_FWH,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W39V080FA,
+ .total_size = 1024,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 16}, },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .printlock = printlock_w39v080fa,
+ .unlock = unlock_w39v080fa,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* Also has 12V fast program */
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W39V080FA (dual mode)",
+ .bustype = BUS_FWH,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W39V080FA_DM,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8}, },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .printlock = printlock_w39v080fa_dual,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* Also has 12V fast program */
+ },
+
+ {
+ .vendor = "Unknown",
+ .name = "SFDP-capable chip",
+ .bustype = BUS_SPI,
+ .manufacture_id = GENERIC_MANUF_ID,
+ .model_id = SFDP_DEVICE_ID,
+ /* We present our own "report this" text hence we do not
+ * want the default "This flash part has status UNTESTED..."
+ * text to be printed. */
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_sfdp,
+ .unlock = spi_disable_blockprotect, /* is this safe? */
+ .read = spi_chip_read,
+ /* FIXME: some vendor extensions define this */
+ .voltage = {0},
+ /* Everything below will be set by the probing function. */
+ .write = NULL,
+ .total_size = 0,
+ .page_size = 0,
+ .feature_bits = 0,
+ .block_erasers = {},
+ },
+
+ {
+ .vendor = "Programmer",
+ .name = "Opaque flash chip",
+ .bustype = BUS_PROG,
+ .manufacture_id = PROGMANUF_ID,
+ .model_id = PROGDEV_ID,
+ .total_size = 0,
+ .page_size = 256,
+ /* probe is assumed to work, rest will be filled in by probe */
+ .tested = TEST_OK_PROBE,
+ .probe = probe_opaque,
+ /* eraseblock sizes will be set by the probing function */
+ .block_erasers =
+ {
+ {
+ .block_erase = erase_opaque,
+ }
+ },
+ .write = write_opaque,
+ .read = read_opaque,
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "unknown AMIC SPI chip",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID,
+ .model_id = GENERIC_DEVICE_ID,
+ .total_size = 0,
+ .page_size = 256,
+ .tested = TEST_BAD_PREW,
+ .probe = probe_spi_rdid4,
+ .probe_timing = TIMING_ZERO,
+ .write = NULL,
+ .read = NULL,
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "unknown Atmel SPI chip",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = GENERIC_DEVICE_ID,
+ .total_size = 0,
+ .page_size = 256,
+ .tested = TEST_BAD_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .write = NULL,
+ .read = NULL,
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "unknown Eon SPI chip",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = GENERIC_DEVICE_ID,
+ .total_size = 0,
+ .page_size = 256,
+ .tested = TEST_BAD_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .write = NULL,
+ .read = NULL,
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "unknown Macronix SPI chip",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = GENERIC_DEVICE_ID,
+ .total_size = 0,
+ .page_size = 256,
+ .tested = TEST_BAD_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .write = NULL,
+ .read = NULL,
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "unknown PMC SPI chip",
+ .bustype = BUS_SPI,
+ .manufacture_id = PMC_ID,
+ .model_id = GENERIC_DEVICE_ID,
+ .total_size = 0,
+ .page_size = 256,
+ .tested = TEST_BAD_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .write = NULL,
+ .read = NULL,
+ },
+
+ {
+ .vendor = "SST",
+ .name = "unknown SST SPI chip",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = GENERIC_DEVICE_ID,
+ .total_size = 0,
+ .page_size = 256,
+ .tested = TEST_BAD_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .write = NULL,
+ .read = NULL,
+ },
+
+ {
+ .vendor = "ST",
+ .name = "unknown ST SPI chip",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = GENERIC_DEVICE_ID,
+ .total_size = 0,
+ .page_size = 256,
+ .tested = TEST_BAD_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .write = NULL,
+ .read = NULL,
+ },
+
+ {
+ .vendor = "Sanyo",
+ .name = "unknown Sanyo SPI chip",
+ .bustype = BUS_SPI,
+ .manufacture_id = SANYO_ID,
+ .model_id = GENERIC_DEVICE_ID,
+ .total_size = 0,
+ .page_size = 256,
+ .tested = TEST_BAD_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .write = NULL,
+ .read = NULL,
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "unknown Winbond (ex Nexcom) SPI chip",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = GENERIC_DEVICE_ID,
+ .total_size = 0,
+ .page_size = 256,
+ .tested = TEST_BAD_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .write = NULL,
+ .read = NULL,
+ },
+
+ {
+ .vendor = "Generic",
+ .name = "unknown SPI chip (RDID)",
+ .bustype = BUS_SPI,
+ .manufacture_id = GENERIC_MANUF_ID,
+ .model_id = GENERIC_DEVICE_ID,
+ .total_size = 0,
+ .page_size = 256,
+ .tested = TEST_BAD_PREW,
+ .probe = probe_spi_rdid,
+ .write = NULL,
+ },
+
+ {
+ .vendor = "Generic",
+ .name = "unknown SPI chip (REMS)",
+ .bustype = BUS_SPI,
+ .manufacture_id = GENERIC_MANUF_ID,
+ .model_id = GENERIC_DEVICE_ID,
+ .total_size = 0,
+ .page_size = 256,
+ .tested = TEST_BAD_PREW,
+ .probe = probe_spi_rems,
+ .write = NULL,
+ },
+
+ {0}
+};
+
+const unsigned int flashchips_size = ARRAY_SIZE(flashchips);
diff --git a/resources/flashrom/patch/flashchips.c_lenovobios_sst b/resources/flashrom/patch/flashchips.c_lenovobios_sst
new file mode 100644
index 0000000..cdb65f1
--- /dev/null
+++ b/resources/flashrom/patch/flashchips.c_lenovobios_sst
@@ -0,0 +1,13574 @@
+/*
+ * This file is part of the flashrom project.
+ *
+ * Copyright (C) 2000 Silicon Integrated System Corporation
+ * Copyright (C) 2004 Tyan Corp
+ * Copyright (C) 2005-2008 coresystems GmbH <stepan@openbios.org>
+ * Copyright (C) 2006-2009 Carl-Daniel Hailfinger
+ * Copyright (C) 2009 Sean Nelson <audiohacked@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "flash.h"
+#include "flashchips.h"
+#include "chipdrivers.h"
+
+/**
+ * List of supported flash chips.
+ *
+ * Please keep the list sorted by vendor name and chip family, so that the output of 'flashrom -L' is roughly
+ * alphabetically sorted. Within families keep them in order of density.
+ */
+const struct flashchip flashchips[] = {
+
+ /*
+ * .vendor = Vendor name
+ * .name = Chip name
+ * .bustype = Supported flash bus types (Parallel, LPC...)
+ * .manufacture_id = Manufacturer chip ID
+ * .model_id = Model chip ID
+ * .total_size = Total size in (binary) kbytes
+ * .page_size = Page or eraseblock(?) size in bytes
+ * .tested = Test status
+ * .probe = Probe function
+ * .probe_timing = Probe function delay
+ * .block_erasers[] = Array of erase layouts and erase functions
+ * {
+ * .eraseblocks[] = Array of { blocksize, blockcount }
+ * .block_erase = Block erase function
+ * }
+ * .printlock = Chip lock status function
+ * .unlock = Chip unlock function
+ * .write = Chip write function
+ * .read = Chip read function
+ * .voltage = Voltage range in millivolt
+ */
+
+ {
+ .vendor = "AMD",
+ .name = "Am29F010A/B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29F010B, /* Same as Am29F010A */
+ .total_size = 128,
+ .page_size = 16 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PRE,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {16 * 1024, 8} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "AMD",
+ .name = "Am29F002(N)BB",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29F002BB,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_SHORT_RESET | FEATURE_ADDR_2AA,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {32 * 1024, 1},
+ {64 * 1024, 3},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4750, 5250}, /* 4.75-5.25V for type -55, others 4.5-5.5V */
+ },
+
+ {
+ .vendor = "AMD",
+ .name = "Am29F002(N)BT",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29F002BT,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_EITHER_RESET | FEATURE_ADDR_2AA,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 3},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4750, 5250}, /* 4.75-5.25V for type -55, others 4.5-5.5V */
+ },
+
+ {
+ .vendor = "AMD",
+ .name = "Am29F016D",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29F016D,
+ .total_size = 2 * 1024,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {2048 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "AMD",
+ .name = "Am29F040B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29F040B,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "AMD",
+ .name = "Am29F080B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29F080B,
+ .total_size = 1024,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "AMD",
+ .name = "Am29LV001BB",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29LV001BB,
+ .total_size = 128,
+ .page_size = 64 * 1024, /* unused */
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ {16 * 1024, 7},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* 3.0-3.6V for type -45R, others 2.7-3.6V */
+ },
+
+ {
+ .vendor = "AMD",
+ .name = "Am29LV001BT",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29LV001BT,
+ .total_size = 128,
+ .page_size = 64 * 1024, /* unused */
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 7},
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* 3.0-3.6V for type -45R, others 2.7-3.6V */
+ },
+
+ {
+ .vendor = "AMD",
+ .name = "Am29LV002BB",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29LV002BB,
+ .total_size = 256,
+ .page_size = 64 * 1024, /* unused */
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {32 * 1024, 1},
+ {64 * 1024, 3},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* 3.0-3.6V for type -55, others 2.7-3.6V */
+ },
+
+ {
+ .vendor = "AMD",
+ .name = "Am29LV002BT",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29LV002BT,
+ .total_size = 256,
+ .page_size = 64 * 1024, /* unused */
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 3},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* 3.0-3.6V for type -55, others 2.7-3.6V */
+ },
+
+ {
+ .vendor = "AMD",
+ .name = "Am29LV004BB",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29LV004BB,
+ .total_size = 512,
+ .page_size = 64 * 1024, /* unused */
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {32 * 1024, 1},
+ {64 * 1024, 7},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMD",
+ .name = "Am29LV004BT",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29LV004BT,
+ .total_size = 512,
+ .page_size = 64 * 1024, /* unused */
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 7},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMD",
+ .name = "Am29LV008BB",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29LV008BB,
+ .total_size = 1024,
+ .page_size = 64 * 1024, /* unused */
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {32 * 1024, 1},
+ {64 * 1024, 15},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600} /* 3.0-3.6V for type -70R, others 2.7-3.6V */
+ },
+
+ {
+ .vendor = "AMD",
+ .name = "Am29LV008BT",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29LV008BT,
+ .total_size = 1024,
+ .page_size = 64 * 1024, /* unused */
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 15},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600} /* 3.0-3.6V for type -70R, others 2.7-3.6V */
+ },
+
+ {
+ .vendor = "AMD",
+ .name = "Am29LV040B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29LV040B,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_OK_PRE,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* 3.0-3.6V for type -60R, others 2.7-3.6V*/
+ },
+
+ {
+ .vendor = "AMD",
+ .name = "Am29LV081B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMD_ID,
+ .model_id = AMD_AM29LV080B,
+ .total_size = 1024,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET, /* datasheet specifies address as don't care */
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* 3.0-3.6V for type -70R, others 2.7-3.6V */
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L05PT",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID,
+ .model_id = AMIC_A25L05PT,
+ .total_size = 64,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid4,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {32 * 1024, 1},
+ {16 * 1024, 1},
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp1_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L05PU",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID,
+ .model_id = AMIC_A25L05PU,
+ .total_size = 64,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid4,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ {16 * 1024, 1},
+ {32 * 1024, 1},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp1_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L10PT",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID,
+ .model_id = AMIC_A25L10PT,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid4,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 1},
+ {32 * 1024, 1},
+ {16 * 1024, 1},
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp1_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L10PU",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID,
+ .model_id = AMIC_A25L10PU,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid4,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ {16 * 1024, 1},
+ {32 * 1024, 1},
+ {64 * 1024, 1},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp1_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L20PT",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID,
+ .model_id = AMIC_A25L20PT,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid4,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 3},
+ {32 * 1024, 1},
+ {16 * 1024, 1},
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp1_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L20PU",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID,
+ .model_id = AMIC_A25L20PU,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid4,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ {16 * 1024, 1},
+ {32 * 1024, 1},
+ {64 * 1024, 3},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp1_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ /* The A25L40P{T,U} chips are distinguished by their
+ * erase block layouts, but without any distinction in RDID.
+ * This inexplicable quirk was verified by Rudolf Marek
+ * and discussed on the flashrom mailing list on 2010-07-12.
+ */
+ {
+ .vendor = "AMIC",
+ .name = "A25L40PT",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID,
+ .model_id = AMIC_A25L40PT,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PR,
+ .probe = probe_spi_rdid4,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 7},
+ {32 * 1024, 1},
+ {16 * 1024, 1},
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L40PU",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID,
+ .model_id = AMIC_A25L40PU,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PR,
+ .probe = probe_spi_rdid4,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ {16 * 1024, 1},
+ {32 * 1024, 1},
+ {64 * 1024, 7},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L80P",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID,
+ .model_id = AMIC_A25L80P,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PRE,
+ .probe = probe_spi_rdid4,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ {16 * 1024, 1},
+ {32 * 1024, 1},
+ {64 * 1024, 15},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L16PT",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID,
+ .model_id = AMIC_A25L16PT,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid4,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 31},
+ {32 * 1024, 1},
+ {16 * 1024, 1},
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2048 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2048 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L16PU",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID,
+ .model_id = AMIC_A25L16PU,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PR,
+ .probe = probe_spi_rdid4,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ {16 * 1024, 1},
+ {32 * 1024, 1},
+ {64 * 1024, 31},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2048 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2048 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L512",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID_NOPREFIX,
+ .model_id = AMIC_A25L512,
+ .total_size = 64,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { { 4 * 1024, 16 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { { 64 * 1024, 1 } },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 64 * 1024, 1 } },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L010",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID_NOPREFIX,
+ .model_id = AMIC_A25L010,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { { 4 * 1024, 32 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { { 64 * 1024, 2 } },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 128 * 1024, 1 } },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L020",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID_NOPREFIX,
+ .model_id = AMIC_A25L020,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { { 4 * 1024, 64 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { { 64 * 1024, 4 } },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 256 * 1024, 1 } },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L040",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID_NOPREFIX,
+ .model_id = AMIC_A25L040,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { { 4 * 1024, 128 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { { 64 * 1024, 8 } },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 512 * 1024, 1 } },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L080",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID_NOPREFIX,
+ .model_id = AMIC_A25L080,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { { 4 * 1024, 256 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { { 64 * 1024, 16 } },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 1024 * 1024, 1 } },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L016",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID_NOPREFIX,
+ .model_id = AMIC_A25L016,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { { 4 * 1024, 512 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { { 64 * 1024, 32 } },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 2048 * 1024, 1 } },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25L032",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID_NOPREFIX,
+ .model_id = AMIC_A25L032,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 64B total; read 0x4B, 0x48; write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { { 4 * 1024, 1024 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { { 64 * 1024, 64 } },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { { 64 * 1024, 64 } },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 4096 * 1024, 1 } },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { { 4096 * 1024, 1 } },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_amic_a25l032, /* bit5: T/B, bit6: prot size */
+ .unlock = spi_disable_blockprotect_bp2_srwd, /* TODO: 2nd status reg (read with 0x35) */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25LQ16",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID_NOPREFIX,
+ .model_id = AMIC_A25LQ16,
+ .total_size = 2048,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 64B total; read 0x4B, 0x48; write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { { 4 * 1024, 512 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { { 64 * 1024, 32 } },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { { 64 * 1024, 32 } },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 2048 * 1024, 1 } },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { { 2048 * 1024, 1 } },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_amic_a25l032, /* bit5: T/B, bit6: prot size */
+ .unlock = spi_disable_blockprotect_bp2_srwd, /* TODO: 2nd status reg (read with 0x35) */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25LQ032/A25LQ32A",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID_NOPREFIX,
+ .model_id = AMIC_A25LQ032,
+ .total_size = 4096,
+ .page_size = 256,
+ /* A25LQ32A supports SFDP */
+ /* OTP: 64B total; read 0x4B, 0x48; write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { { 4 * 1024, 1024 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { { 64 * 1024, 64 } },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { { 64 * 1024, 64 } },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 4096 * 1024, 1 } },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { { 4096 * 1024, 1 } },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_amic_a25l032, /* bit5: T/B, bit6: prot size */
+ .unlock = spi_disable_blockprotect_bp2_srwd, /* TODO: 2nd status reg (read with 0x35) */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A25LQ64",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID_NOPREFIX,
+ .model_id = AMIC_A25LQ032,
+ .total_size = 8192,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 512B total; enter 0xB1, exit 0xC1 */
+ /* QPI enable 0x35, disable 0xF5 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { { 4 * 1024, 2048 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { { 32 * 1024, 256 } },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { { 64 * 1024, 128 } },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 8192 * 1024, 1 } },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { { 8192 * 1024, 1 } },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6 is quad enhance (sic!) */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A29002B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMIC_ID_NOPREFIX,
+ .model_id = AMIC_A29002B,
+ .total_size = 256,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {32 * 1024, 1},
+ {64 * 1024, 3},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A29002T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMIC_ID_NOPREFIX,
+ .model_id = AMIC_A29002T,
+ .total_size = 256,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 3},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A29040B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = AMIC_ID_NOPREFIX,
+ .model_id = AMIC_A29040B,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "A49LF040A",
+ .bustype = BUS_LPC,
+ .manufacture_id = AMIC_ID_NOPREFIX,
+ .model_id = AMIC_A49LF040A,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* routine is wrapper to probe_jedec (pm49fl00x.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .unlock = unlock_49fl00x,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25DF021",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25DF021,
+ .total_size = 256,
+ .page_size = 256,
+ /* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 8} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25df,
+ .unlock = spi_disable_blockprotect_at2x_global_unprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600}, /* 2.3-3.6V & 2.7-3.6V models available */
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25DF041A",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25DF041A,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 16} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25df,
+ .unlock = spi_disable_blockprotect_at2x_global_unprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600}, /* 2.3-3.6V & 2.7-3.6V models available */
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25DF081",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25DF081,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 32} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25df,
+ .unlock = spi_disable_blockprotect_at2x_global_unprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {1600, 2000}, /* Datasheet says range is 1.65-1.95 V */
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25DF081A",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25DF081A,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 32} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25df_sec,
+ .unlock = spi_disable_blockprotect_at2x_global_unprotect_sec,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25DF161",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25DF161,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PROBE,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 64} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25df_sec,
+ .unlock = spi_disable_blockprotect_at2x_global_unprotect_sec,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25DF321",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25DF321,
+ .total_size = 4096,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 128} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25df,
+ .unlock = spi_disable_blockprotect_at2x_global_unprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25DF321A",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25DF321A,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 128} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25df_sec,
+ .unlock = spi_disable_blockprotect_at2x_global_unprotect_sec,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25DF641(A)",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25DF641,
+ .total_size = 8192,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 2048} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 256} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25df_sec,
+ .unlock = spi_disable_blockprotect_at2x_global_unprotect_sec,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25DL081",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25DF081,
+ .total_size = 1024,
+ .page_size = 256,
+ /* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 32} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25df_sec,
+ .unlock = spi_disable_blockprotect_at2x_global_unprotect_sec,
+ .write = spi_chip_write_256, /* Dual I/O (0xA2) supported */
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O (0x3B) supported */
+ .voltage = {1650, 1950},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25DL161",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25DL161,
+ .total_size = 2048,
+ .page_size = 256,
+ /* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 64} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25df_sec,
+ .unlock = spi_disable_blockprotect_at2x_global_unprotect_sec,
+ .write = spi_chip_write_256, /* Dual I/O (0xA2) supported */
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O (0x3B) supported */
+ .voltage = {1650, 1950},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25DQ161",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25DQ161,
+ .total_size = 2048,
+ .page_size = 256,
+ /* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 64} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25df_sec,
+ .unlock = spi_disable_blockprotect_at2x_global_unprotect_sec,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25F512",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25F512,
+ .total_size = 64,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_at25f,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {32 * 1024, 2} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_62,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25f,
+ .unlock = spi_disable_blockprotect_at25f,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25F512A",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25F512A,
+ .total_size = 64,
+ .page_size = 128,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_at25f,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {32 * 1024, 2} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_62,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25f512a,
+ /* FIXME: It is not correct to use this one, because the BP1 bit is N/A. */
+ .unlock = spi_disable_blockprotect_at25f512a,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25F512B",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25F512B,
+ .total_size = 64,
+ .page_size = 256,
+ /* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 16} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 2} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {32 * 1024, 2} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_62,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25f512b,
+ .unlock = spi_disable_blockprotect_at25f512b,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ /* The A suffix indicates 33MHz instead of 20MHz clock rate.
+ * All other properties seem to be the same.*/
+ .name = "AT25F1024(A)",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25F1024,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_at25f,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_62,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25f,
+ .unlock = spi_disable_blockprotect_at25f,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25F2048",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25F2048,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_at25f,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_62,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25f,
+ .unlock = spi_disable_blockprotect_at25f,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25F4096",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25F4096,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_at25f,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_62,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25f4096,
+ /* "Bits 5-6 are 0s when device is not in an internal write cycle." Better leave them alone: */
+ .unlock = spi_disable_blockprotect_bp2_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25FS010",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25FS010,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25fs010,
+ .unlock = spi_disable_blockprotect_at25fs010,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT25FS040",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT25FS040,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25fs040,
+ .unlock = spi_disable_blockprotect_at25fs040,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT26DF041",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT26DF041,
+ .total_size = 512,
+ .page_size = 256,
+ /* does not support EWSR nor WREN and has no writable status register bits whatsoever */
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {256, 2048} },
+ .block_erase = spi_block_erase_81,
+ }, {
+ .eraseblocks = { {2 * 1024, 256} },
+ .block_erase = spi_block_erase_50,
+ }, {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain,
+ /* Supports also an incompatible page write (of exactly 256 B) and an auto-erasing write. */
+ .write = spi_chip_write_1,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600}, /* 3.0-3.6V for higher speed, 2.7-3.6V normal */
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT26DF081A",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT26DF081A,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 32} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at26df081a,
+ .unlock = spi_disable_blockprotect_at2x_global_unprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT26DF161",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT26DF161,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PR,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 64} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at25df,
+ .unlock = spi_disable_blockprotect_at2x_global_unprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT26DF161A",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT26DF161A,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 64} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at26df081a,
+ .unlock = spi_disable_blockprotect_at2x_global_unprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ /*The AT26DF321 has the same ID as the AT25DF321. */
+ /*{
+ .vendor = "Atmel",
+ .name = "AT26DF321",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT26DF321,
+ .total_size = 4096,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .printlock = spi_prettyprint_status_register_at26df081a,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ },*/
+
+ {
+ .vendor = "Atmel",
+ .name = "AT26F004",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT26F004,
+ .total_size = 512,
+ .page_size = 256,
+ .tested = {.probe = NT, .read = NT, .erase = NT, .write = BAD },
+ .feature_bits = FEATURE_WRSR_WREN,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 16} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .write = NULL /* Incompatible Page write */,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT29C512",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT29C512,
+ .total_size = 64,
+ .page_size = 128,
+ .feature_bits = FEATURE_LONG_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10000, /* 10mS, Enter=Exec */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT29C010A",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT29C010A,
+ .total_size = 128,
+ .page_size = 128,
+ .feature_bits = FEATURE_LONG_RESET,
+ .tested = TEST_OK_PRE,
+ .probe = probe_jedec,
+ .probe_timing = 10000, /* 10mS, Enter=Exec */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec, /* FIXME */
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT29C020",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT29C020,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_LONG_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10000, /* 10ms */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT29C040A",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT29C040A,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_LONG_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = 10000, /* 10 ms */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT45CS1282",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT45CS1282,
+ .total_size = 16896 /* No power of two sizes */,
+ .page_size = 1056 /* No power of two sizes */,
+ /* does not support EWSR nor WREN and has no writable status register bits whatsoever */
+ /* OTP: 128B total, 64B pre-programmed; read 0x77 (4 dummy bytes); write 0x9A (via buffer) */
+ .feature_bits = FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {8 * 1056, 1}, /* sector 0a: opcode 50h */
+ {248 * 1056, 1}, /* sector 0b: opcode 7Ch */
+ {256 * 1056, 63}, /* sectors 1 - 63: opcode 7Ch */
+ },
+ .block_erase = spi_erase_at45cs_sector,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain,
+ .gran = write_gran_1056bytes,
+ .write = spi_write_at45db,
+ .read = spi_read_at45db,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT45DB011D",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT45DB011D,
+ .total_size = 128 /* or 132, determined from status register */,
+ .page_size = 256 /* or 264, determined from status register */,
+ /* does not support EWSR nor WREN and has no writable status register bits whatsoever */
+ /* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+ .feature_bits = FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_at45db,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {256, 512} },
+ .block_erase = spi_erase_at45db_page,
+ }, {
+ .eraseblocks = { {8 * 256, 512/8} },
+ .block_erase = spi_erase_at45db_block,
+ }, {
+ .eraseblocks = {
+ {8 * 256, 1},
+ {120 * 256, 1},
+ {128 * 256, 3},
+ },
+ .block_erase = spi_erase_at45db_sector
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_erase_at45db_chip,
+ }
+ },
+ .unlock = spi_disable_blockprotect_at45db, /* Impossible if locked down or #WP is low */
+ .printlock = spi_prettyprint_status_register_at45db,
+ /* granularity will be set by the probing function. */
+ .write = spi_write_at45db,
+ .read = spi_read_at45db, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT45DB021D",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT45DB021D,
+ .total_size = 256 /* or 264, determined from status register */,
+ .page_size = 256 /* or 264, determined from status register */,
+ /* does not support EWSR nor WREN and has no writable status register bits whatsoever */
+ /* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+ .feature_bits = FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_at45db,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {256, 1024} },
+ .block_erase = spi_erase_at45db_page,
+ }, {
+ .eraseblocks = { {8 * 256, 1024/8} },
+ .block_erase = spi_erase_at45db_block,
+ }, {
+ .eraseblocks = {
+ {8 * 256, 1},
+ {120 * 256, 1},
+ {128 * 256, 7},
+ },
+ .block_erase = spi_erase_at45db_sector
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_erase_at45db_chip,
+ }
+ },
+ .unlock = spi_disable_blockprotect_at45db, /* Impossible if locked down or #WP is low */
+ .printlock = spi_prettyprint_status_register_at45db,
+ /* granularity will be set by the probing function. */
+ .write = spi_write_at45db,
+ .read = spi_read_at45db, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT45DB041D",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT45DB041D,
+ .total_size = 512 /* or 528, determined from status register */,
+ .page_size = 256 /* or 264, determined from status register */,
+ /* does not support EWSR nor WREN and has no writable status register bits whatsoever */
+ /* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+ .feature_bits = FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_at45db,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {256, 2048} },
+ .block_erase = spi_erase_at45db_page,
+ }, {
+ .eraseblocks = { {8 * 256, 2048/8} },
+ .block_erase = spi_erase_at45db_block,
+ }, {
+ .eraseblocks = {
+ {8 * 256, 1},
+ {248 * 256, 1},
+ {256 * 256, 7},
+ },
+ .block_erase = spi_erase_at45db_sector
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_erase_at45db_chip,
+ }
+ },
+ .unlock = spi_disable_blockprotect_at45db, /* Impossible if locked down or #WP is low */
+ .printlock = spi_prettyprint_status_register_at45db,
+ /* granularity will be set by the probing function. */
+ .write = spi_write_at45db,
+ .read = spi_read_at45db, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600}, /* 2.5-3.6V & 2.7-3.6V models available */
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT45DB081D",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT45DB081D,
+ .total_size = 1024 /* or 1056, determined from status register */,
+ .page_size = 256 /* or 264, determined from status register */,
+ /* does not support EWSR nor WREN and has no writable status register bits whatsoever */
+ /* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+ .feature_bits = FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_at45db,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {256, 4096} },
+ .block_erase = spi_erase_at45db_page,
+ }, {
+ .eraseblocks = { {8 * 256, 4096/8} },
+ .block_erase = spi_erase_at45db_block,
+ }, {
+ .eraseblocks = {
+ {8 * 256, 1},
+ {248 * 256, 1},
+ {256 * 256, 15},
+ },
+ .block_erase = spi_erase_at45db_sector
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_erase_at45db_chip,
+ }
+ },
+ .unlock = spi_disable_blockprotect_at45db, /* Impossible if locked down or #WP is low */
+ .printlock = spi_prettyprint_status_register_at45db,
+ /* granularity will be set by the probing function. */
+ .write = spi_write_at45db,
+ .read = spi_read_at45db, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600}, /* 2.5-3.6V & 2.7-3.6V models available */
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT45DB161D",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT45DB161D,
+ .total_size = 2048 /* or 2112, determined from status register */,
+ .page_size = 512 /* or 528, determined from status register */,
+ /* does not support EWSR nor WREN and has no writable status register bits whatsoever */
+ /* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+ .feature_bits = FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_at45db,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {512, 4096} },
+ .block_erase = spi_erase_at45db_page,
+ }, {
+ .eraseblocks = { {8 * 512, 4096/8} },
+ .block_erase = spi_erase_at45db_block,
+ }, {
+ .eraseblocks = {
+ {8 * 512, 1},
+ {248 * 512, 1},
+ {256 * 512, 15},
+ },
+ .block_erase = spi_erase_at45db_sector
+ }, {
+ .eraseblocks = { {2048 * 1024, 1} },
+ .block_erase = spi_erase_at45db_chip,
+ }
+ },
+ .unlock = spi_disable_blockprotect_at45db, /* Impossible if locked down or #WP is low */
+ .printlock = spi_prettyprint_status_register_at45db,
+ /* granularity will be set by the probing function. */
+ .write = spi_write_at45db,
+ .read = spi_read_at45db, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600}, /* 2.5-3.6V & 2.7-3.6V models available */
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT45DB321C",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT45DB321C,
+ .total_size = 4224 /* No power of two sizes */,
+ .page_size = 528 /* No power of two sizes */,
+ /* does not support EWSR nor WREN and has no writable status register bits whatsoever */
+ /* OTP: 128B total, 64B pre-programmed; read 0x77 (4 dummy bytes); write 0x9A (via buffer) */
+ .feature_bits = FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {528, 8192} },
+ .block_erase = spi_erase_at45db_page,
+ }, {
+ .eraseblocks = { {8 * 528, 8192/8} },
+ .block_erase = spi_erase_at45db_block,
+ }, /* Although the datasheets describes sectors (which can be write protected)
+ * there seems to be no erase functions for them.
+ {
+ .eraseblocks = {
+ {8 * 528, 1},
+ {120 * 528, 1},
+ {128 * 528, 63},
+ },
+ .block_erase = spi_erase_at45db_sector
+ }, */ {
+ .eraseblocks = { {4224 * 1024, 1} },
+ .block_erase = spi_erase_at45db_chip,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_at45db, /* Bit 0 is undefined, no lockdown */
+ .gran = write_gran_528bytes,
+ .write = spi_write_at45db,
+ .read = spi_read_at45db_e8, /* 3 address and 4 dummy bytes */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT45DB321D",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT45DB321D,
+ .total_size = 4096 /* or 4224, determined from status register */,
+ .page_size = 512 /* or 528, determined from status register */,
+ /* does not support EWSR nor WREN and has no writable status register bits whatsoever */
+ /* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+ .feature_bits = FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_at45db,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {512, 8192} },
+ .block_erase = spi_erase_at45db_page,
+ }, {
+ .eraseblocks = { {8 * 512, 8192/8} },
+ .block_erase = spi_erase_at45db_block,
+ }, {
+ .eraseblocks = {
+ {8 * 512, 1},
+ {120 * 512, 1},
+ {128 * 512, 63},
+ },
+ .block_erase = spi_erase_at45db_sector
+ }, {
+ .eraseblocks = { {4096 * 1024, 1} },
+ .block_erase = spi_erase_at45db_chip,
+ }
+ },
+ .unlock = spi_disable_blockprotect_at45db, /* Impossible if locked down or #WP is low */
+ .printlock = spi_prettyprint_status_register_at45db,
+ /* granularity will be set by the probing function. */
+ .write = spi_write_at45db,
+ .read = spi_read_at45db, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600}, /* 2.5-3.6V & 2.7-3.6V models available */
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT45DB321E",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT45DB321C,
+ .total_size = 4096 /* or 4224, determined from status register */,
+ .page_size = 512 /* or 528, determined from status register */,
+ /* does not support EWSR nor WREN and has no writable status register bits whatsoever */
+ /* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+ .feature_bits = FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_at45db,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {512, 8192} },
+ .block_erase = spi_erase_at45db_page,
+ }, {
+ .eraseblocks = { {8 * 512, 8192/8} },
+ .block_erase = spi_erase_at45db_block,
+ }, {
+ .eraseblocks = {
+ {8 * 512, 1},
+ {120 * 512, 1},
+ {128 * 512, 63},
+ },
+ .block_erase = spi_erase_at45db_sector
+ }, {
+ .eraseblocks = { {4096 * 1024, 1} },
+ .block_erase = spi_erase_at45db_chip,
+ }
+ },
+ .unlock = spi_disable_blockprotect_at45db, /* Impossible if locked down or #WP is low */
+ .printlock = spi_prettyprint_status_register_at45db, /* has a 2nd status register */
+ /* granularity will be set by the probing function. */
+ .write = spi_write_at45db,
+ .read = spi_read_at45db, /* Fast read (0x0B) supported */
+ .voltage = {2500, 3600}, /* 2.3-3.6V & 2.5-3.6V models available */
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT45DB642D",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT45DB642D,
+ .total_size = 8192 /* or 8448, determined from status register */,
+ .page_size = 1024 /* or 1056, determined from status register */,
+ /* does not support EWSR nor WREN and has no writable status register bits whatsoever */
+ /* OTP: 128B total, 64B pre-programmed; read 0x77; write 0x9B */
+ .feature_bits = FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_at45db,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {1024, 8192} },
+ .block_erase = spi_erase_at45db_page,
+ }, {
+ .eraseblocks = { {8 * 1024, 8192/8} },
+ .block_erase = spi_erase_at45db_block,
+ }, {
+ .eraseblocks = {
+ {8 * 1024, 1},
+ {248 * 1024, 1},
+ {256 * 1024, 31},
+ },
+ .block_erase = spi_erase_at45db_sector
+ }, {
+ .eraseblocks = { {8192 * 1024, 1} },
+ .block_erase = spi_erase_at45db_chip,
+ }
+ },
+ .unlock = spi_disable_blockprotect_at45db, /* Impossible if locked down or #WP is low */
+ .printlock = spi_prettyprint_status_register_at45db,
+ /* granularity will be set by the probing function. */
+ .write = spi_write_at45db,
+ .read = spi_read_at45db, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT49BV512",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT49BV512,
+ .total_size = 64,
+ .page_size = 64,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT49F002(N)",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT49F002N,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {96 * 1024, 1},
+ {128 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT49F002(N)T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT49F002NT,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PR,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {128 * 1024, 1},
+ {96 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT49(H)F010",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT49F010,
+ .total_size = 128,
+ .page_size = 0, /* unused */
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .printlock = printlock_at49f,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT49F020",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT49F020,
+ .total_size = 256,
+ .page_size = 0, /* unused */
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PRE,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ /* Chip features an optional permanent write protection
+ * of the first 8 kB. The erase function is the same as
+ * above, but 00000H to 01FFFH will not be erased.
+ * FIXME: add another eraser when partial erasers are
+ * supported.
+ */
+ },
+ .printlock = printlock_at49f,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT49F040",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT49F040,
+ .total_size = 512,
+ .page_size = 0, /* unused */
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ /* Chip features an optional permanent write protection
+ * of the first 16 kB. The erase function is the same as
+ * above, but 00000H to 03FFFH will not be erased.
+ * FIXME: add another eraser when partial erasers are
+ * supported.
+ */
+ },
+ .printlock = printlock_at49f,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT49F080",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT49F080,
+ .total_size = 1024,
+ .page_size = 0, /* unused */
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ /* Chip features an optional permanent write protection
+ * of the first 16 kB. The erase function is the same as
+ * above, but 00000H to 03FFFH will not be erased.
+ * FIXME: add another eraser when partial erasers are
+ * supported.
+ */
+ },
+ .printlock = printlock_at49f,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ /* 'top' version of AT49F080. equal in all aspects but the boot block address */
+ .vendor = "Atmel",
+ .name = "AT49F080T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT49F080T,
+ .total_size = 1024,
+ .page_size = 0, /* unused */
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ /* Chip features an optional permanent write protection
+ * of the first 16 kB. The erase function is the same as
+ * above, but FC000H to FFFFFH will not be erased.
+ * FIXME: add another eraser when partial erasers are
+ * supported.
+ */
+ },
+ .printlock = printlock_at49f,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "AT49LH002",
+ .bustype = BUS_LPC | BUS_FWH, /* A/A Mux */
+ .manufacture_id = ATMEL_ID,
+ .model_id = ATMEL_AT49LH002,
+ .total_size = 256,
+ .page_size = 0, /* unused */
+ .feature_bits = FEATURE_REGISTERMAP, /* TODO: LPC OK too? */
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab, /* TODO: 0xff cmd not documented? */
+ .probe_timing = TIMING_FIXME,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 3},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_block_82802ab,
+ }, {
+ .eraseblocks = {
+ {64 * 1024, 4},
+ },
+ .block_erase = NULL, /* TODO: Implement. */
+ },
+ },
+ .printlock = NULL, /* TODO */
+ .unlock = NULL, /* unlock_82802ab() not correct(?) */
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Catalyst",
+ .name = "CAT28F512",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = CATALYST_ID,
+ .model_id = CATALYST_CAT28F512,
+ .total_size = 64,
+ .page_size = 0, /* unused */
+ .feature_bits = 0,
+ .tested = TEST_OK_PR,
+ .probe = probe_jedec, /* FIXME! */
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = NULL, /* TODO */
+ },
+ },
+ .write = NULL, /* TODO */
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Bright",
+ .name = "BM29F040",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = BRIGHT_ID,
+ .model_id = BRIGHT_BM29F040,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PR,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "ESMT",
+ .name = "F49B002UA",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ESMT_ID,
+ .model_id = ESMT_F49B002UA,
+ .total_size = 256,
+ .page_size = 4096,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {128 * 1024, 1},
+ {96 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "ESMT",
+ .name = "F25L008A",
+ .bustype = BUS_SPI,
+ .manufacture_id = ESMT_ID,
+ .model_id = ESMT_F25L008A,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EITHER,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_1,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "ESMT",
+ .name = "F25L32PA",
+ .bustype = BUS_SPI,
+ .manufacture_id = ESMT_ID,
+ .model_id = ESMT_F25L32PA,
+ .total_size = 4096,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EITHER | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_bpl,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B05",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B05,
+ .total_size = 64,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ {16 * 1024, 1},
+ {32 * 1024, 1},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B05T",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B05,
+ .total_size = 64,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {32 * 1024, 1},
+ {16 * 1024, 1},
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B10",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B10,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ {16 * 1024, 1},
+ {32 * 1024, 3},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B10T",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B10,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {32 * 1024, 3},
+ {16 * 1024, 1},
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B20",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B20,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ {16 * 1024, 1},
+ {32 * 1024, 1},
+ {64 * 1024, 3}
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B20T",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B20,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 3},
+ {32 * 1024, 1},
+ {16 * 1024, 1},
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B40",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B40,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ {16 * 1024, 1},
+ {32 * 1024, 1},
+ {64 * 1024, 7}
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B40T",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B40,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 7},
+ {32 * 1024, 1},
+ {16 * 1024, 1},
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B80",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B80,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ {16 * 1024, 1},
+ {32 * 1024, 1},
+ {64 * 1024, 15}
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B80T",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B80,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 15},
+ {32 * 1024, 1},
+ {16 * 1024, 1},
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B16",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B16,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ {16 * 1024, 1},
+ {32 * 1024, 1},
+ {64 * 1024, 31},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B16T",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B16,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 31},
+ {32 * 1024, 1},
+ {16 * 1024, 1},
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B32",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B32,
+ .total_size = 4096,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ {16 * 1024, 1},
+ {32 * 1024, 1},
+ {64 * 1024, 63},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B32T",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B32,
+ .total_size = 4096,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 63},
+ {32 * 1024, 1},
+ {16 * 1024, 1},
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B64",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B64,
+ .total_size = 8192,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ {16 * 1024, 1},
+ {32 * 1024, 1},
+ {64 * 1024, 127},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25B64T",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25B64,
+ .total_size = 8192,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 127},
+ {32 * 1024, 1},
+ {16 * 1024, 1},
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25F05",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25F05,
+ .total_size = 64,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 16} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 2} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {32 * 1024, 2} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25F10",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25F10,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25F20",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25F20,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25F40",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25F40,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PROBE,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25F80",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25F80,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25F16",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25F16,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25F32",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25F32,
+ .total_size = 4096,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25F64",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25F64,
+ .total_size = 8192,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 2048} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25Q40",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25Q40,
+ .total_size = 512,
+ .page_size = 256,
+ /* OTP: 256B total; enter 0x3A */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25Q80(A)",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25Q80,
+ .total_size = 1024,
+ .page_size = 256,
+ /* OTP: 256B total; enter 0x3A */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ /* Note: EN25D16 is an evil twin which shares the model ID
+ but has different write protection capabilities */
+ .vendor = "Eon",
+ .name = "EN25Q16",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25Q16,
+ .total_size = 2048,
+ .page_size = 256,
+ /* OTP: D16 512B/Q16 128B total; enter 0x3A */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ /* not supported by Q16 version */
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25Q32(A/B)",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25Q32,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 512B total; enter 0x3A */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25Q64",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25Q64,
+ .total_size = 8192,
+ .page_size = 256,
+ /* OTP: 512B total; enter 0x3A */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 2048} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25Q128",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25Q128,
+ .total_size = 16384,
+ .page_size = 256,
+ /* OTP: 512B total; enter 0x3A */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 4096} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 256} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {16 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {16 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25QH16",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25QH16,
+ .total_size = 2048,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 512B total; enter 0x3A */
+ /* QPI enable 0x38, disable 0xFF */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .tested = TEST_OK_PR,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 2048, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 2048, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6 is quad enable */
+ .unlock = spi_disable_blockprotect_bp3_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25QH32",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25QH32,
+ .total_size = 4096,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 512B total; enter 0x3A */
+ /* QPI enable 0x38, disable 0xFF */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 4096, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 4096, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6 is quad enable */
+ .unlock = spi_disable_blockprotect_bp3_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25QH64",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25QH64,
+ .total_size = 8192,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 512B total; enter 0x3A */
+ /* QPI enable 0x38, disable 0xFF */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .tested = TEST_OK_PR,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 2048} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 8192 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { { 8192 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6 is quad enable */
+ .unlock = spi_disable_blockprotect_bp3_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25QH128",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25QH128,
+ .total_size = 16384,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 512B total; enter 0x3A */
+ /* QPI enable 0x38, disable 0xFF */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 4096} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 256} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 16384 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { { 16384 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6 is quad enable */
+ .unlock = spi_disable_blockprotect_bp3_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25S10",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25S10,
+ .total_size = 128,
+ .page_size = 256,
+ /* OTP: 256B total; enter 0x3A */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {1650, 1950},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25S20",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25S20,
+ .total_size = 256,
+ .page_size = 256,
+ /* OTP: 256B total; enter 0x3A */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {1650, 1950},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25S40",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25S40,
+ .total_size = 512,
+ .page_size = 256,
+ /* OTP: 256B total; enter 0x3A */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {1650, 1950},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25S80",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25S80,
+ .total_size = 1024,
+ .page_size = 256,
+ /* OTP: 256B total; enter 0x3A */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {1650, 1950},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25S16",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25S16,
+ .total_size = 2048,
+ .page_size = 256,
+ /* OTP: 512B total; enter 0x3A */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {32 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2048 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2048 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_en25s_wp,
+ .unlock = spi_disable_blockprotect_bp3_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {1650, 1950},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25S32",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25S32,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 512B total; enter 0x3A */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 128} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4096 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4096 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_en25s_wp,
+ .unlock = spi_disable_blockprotect_bp3_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {1650, 1950},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN25S64",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = EON_EN25S64,
+ .total_size = 8192,
+ .page_size = 256,
+ /* OTP: 512B total; enter 0x3A */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 2048} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8192 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {8192 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_en25s_wp,
+ .unlock = spi_disable_blockprotect_bp3_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {1650, 1950},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN29F010",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = EON_ID,
+ .model_id = EON_EN29F010,
+ .total_size = 128,
+ .page_size = 128,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PRE,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {16 * 1024, 8} },
+ .block_erase = erase_sector_jedec,
+ },
+ {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN29F002(A)(N)B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = EON_ID,
+ .model_id = EON_EN29F002B,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_ADDR_AAA | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PR,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {32 * 1024, 1},
+ {64 * 1024, 3},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN29F002(A)(N)T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = EON_ID,
+ .model_id = EON_EN29F002T,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_ADDR_AAA | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 3},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "EN29LV640B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = EON_ID,
+ .model_id = EON_EN29LV640B,
+ .total_size = 8192,
+ .page_size = 8192,
+ .feature_bits = 0,
+ .tested = TEST_OK_PREW,
+ .probe = probe_en29lv640b,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {8 * 1024, 8},
+ {64 * 1024, 127},
+ },
+ .block_erase = erase_block_shifted_jedec,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = erase_chip_block_shifted_jedec,
+ },
+ },
+ .write = write_en29lv640b,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Fujitsu",
+ .name = "MBM29F004BC",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = FUJITSU_ID,
+ .model_id = FUJITSU_MBM29F004BC,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {32 * 1024, 1},
+ {64 * 1024, 7},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = NULL,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Fujitsu",
+ .name = "MBM29F004TC",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = FUJITSU_ID,
+ .model_id = FUJITSU_MBM29F004TC,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 7},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = NULL,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ /* FIXME: this has WORD/BYTE sequences; 2AA for word, 555 for byte */
+ .vendor = "Fujitsu",
+ .name = "MBM29F400BC",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = FUJITSU_ID,
+ .model_id = FUJITSU_MBM29F400BC,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_SHIFTED | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_m29f400bt,
+ .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (m29f400bt.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {32 * 1024, 1},
+ {64 * 1024, 7},
+ },
+ .block_erase = erase_block_shifted_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_shifted_jedec,
+ },
+ },
+ .write = write_m29f400bt,
+ .read = read_memmapped,
+ .voltage = {4750, 5250}, /* 4.75-5.25V for type -55, others 4.5-5.5V */
+ },
+
+ {
+ .vendor = "Fujitsu",
+ .name = "MBM29F400TC",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = FUJITSU_ID,
+ .model_id = FUJITSU_MBM29F400TC,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_SHIFTED | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_m29f400bt,
+ .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (m29f400bt.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 7},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_block_shifted_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_shifted_jedec,
+ },
+ },
+ .write = write_m29f400bt,
+ .read = read_memmapped,
+ .voltage = {4750, 5250}, /* 4.75-5.25V for type -55, others 4.5-5.5V */
+ },
+
+ {
+ .vendor = "Fujitsu",
+ .name = "MBM29LV160BE",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = FUJITSU_ID,
+ .model_id = FUJITSU_MBM29LV160BE,
+ .total_size = 2 * 1024,
+ .page_size = 0,
+ .feature_bits = FEATURE_ADDR_SHIFTED | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_m29f400bt,
+ .probe_timing = TIMING_IGNORED,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {32 * 1024, 1},
+ {64 * 1024, 31},
+ },
+ .block_erase = erase_block_shifted_jedec,
+ }, {
+ .eraseblocks = { {2048 * 1024, 1} },
+ .block_erase = erase_chip_block_shifted_jedec,
+ },
+ },
+ .write = write_m29f400bt, /* Supports a fast mode too */
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* 3.0-3.6V for type -70, others 2.7-3.6V */
+ },
+
+ {
+ .vendor = "Fujitsu",
+ .name = "MBM29LV160TE",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = FUJITSU_ID,
+ .model_id = FUJITSU_MBM29LV160TE,
+ .total_size = 2 * 1024,
+ .page_size = 0,
+ .feature_bits = FEATURE_ADDR_SHIFTED | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_m29f400bt,
+ .probe_timing = TIMING_IGNORED,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 31},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_block_shifted_jedec,
+ }, {
+ .eraseblocks = { {2048 * 1024, 1} },
+ .block_erase = erase_chip_block_shifted_jedec,
+ },
+ },
+ .write = write_m29f400bt, /* Supports a fast mode too */
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* 3.0-3.6V for type -70, others 2.7-3.6V */
+ },
+
+ {
+ .vendor = "GigaDevice",
+ .name = "GD25LQ32",
+ .bustype = BUS_SPI,
+ .manufacture_id = GIGADEVICE_ID,
+ .model_id = GIGADEVICE_GD25LQ32,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 128} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp4_srwd,
+ .unlock = spi_disable_blockprotect_bp4_srwd, /* TODO: 2nd status reg (read with 0x35) */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {1700, 1950},
+ },
+
+ {
+ .vendor = "GigaDevice",
+ .name = "GD25Q512",
+ .bustype = BUS_SPI,
+ .manufacture_id = GIGADEVICE_ID,
+ .model_id = GIGADEVICE_GD25Q512,
+ .total_size = 64,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 16} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 2} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp4_srwd,
+ .unlock = spi_disable_blockprotect_bp4_srwd, /* TODO: 2nd status reg (read with 0x35) */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "GigaDevice",
+ .name = "GD25Q10",
+ .bustype = BUS_SPI,
+ .manufacture_id = GIGADEVICE_ID,
+ .model_id = GIGADEVICE_GD25Q10,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 2} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp4_srwd,
+ .unlock = spi_disable_blockprotect_bp4_srwd, /* TODO: 2nd status reg (read with 0x35) */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "GigaDevice",
+ .name = "GD25Q20(B)",
+ .bustype = BUS_SPI,
+ .manufacture_id = GIGADEVICE_ID,
+ .model_id = GIGADEVICE_GD25Q20,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 8} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp4_srwd,
+ .unlock = spi_disable_blockprotect_bp4_srwd, /* TODO: 2nd status reg (read with 0x35) */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "GigaDevice",
+ .name = "GD25Q40(B)",
+ .bustype = BUS_SPI,
+ .manufacture_id = GIGADEVICE_ID,
+ .model_id = GIGADEVICE_GD25Q40,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 16} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp4_srwd,
+ .unlock = spi_disable_blockprotect_bp4_srwd, /* TODO: 2nd status reg (read with 0x35) */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "GigaDevice",
+ .name = "GD25Q80(B)",
+ .bustype = BUS_SPI,
+ .manufacture_id = GIGADEVICE_ID,
+ .model_id = GIGADEVICE_GD25Q80,
+ .total_size = 1024,
+ .page_size = 256,
+ /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44 (B version only) */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 32} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp4_srwd,
+ .unlock = spi_disable_blockprotect_bp4_srwd, /* TODO: 2nd status reg (read with 0x35) */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "GigaDevice",
+ .name = "GD25Q16(B)",
+ .bustype = BUS_SPI,
+ .manufacture_id = GIGADEVICE_ID,
+ .model_id = GIGADEVICE_GD25Q16,
+ .total_size = 2048,
+ .page_size = 256,
+ /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44 (B version only) */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 64} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp4_srwd,
+ .unlock = spi_disable_blockprotect_bp4_srwd, /* TODO: 2nd status reg (read with 0x35) */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "GigaDevice",
+ .name = "GD25Q32(B)",
+ .bustype = BUS_SPI,
+ .manufacture_id = GIGADEVICE_ID,
+ .model_id = GIGADEVICE_GD25Q32,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 128} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp4_srwd,
+ .unlock = spi_disable_blockprotect_bp4_srwd, /* TODO: 2nd status reg (read with 0x35) */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "GigaDevice",
+ .name = "GD25Q64(B)",
+ .bustype = BUS_SPI,
+ .manufacture_id = GIGADEVICE_ID,
+ .model_id = GIGADEVICE_GD25Q64,
+ .total_size = 8192,
+ .page_size = 256,
+ /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 2048} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 256} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp4_srwd,
+ .unlock = spi_disable_blockprotect_bp4_srwd, /* TODO: 2nd status reg (read with 0x35) */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "GigaDevice",
+ .name = "GD25Q128B",
+ .bustype = BUS_SPI,
+ .manufacture_id = GIGADEVICE_ID,
+ .model_id = GIGADEVICE_GD25Q128,
+ .total_size = 16384,
+ .page_size = 256,
+ /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 4096} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 512} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 256} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {16 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {16 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp4_srwd,
+ .unlock = spi_disable_blockprotect_bp4_srwd, /* TODO: 2nd status reg (read with 0x35) */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "GigaDevice",
+ .name = "GD25T80",
+ .bustype = BUS_SPI,
+ .manufacture_id = GIGADEVICE_ID,
+ .model_id = GIGADEVICE_GD25T80,
+ .total_size = 1024,
+ .page_size = 256,
+ /* OTP: 256B total; enter 0x3A */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Hyundai",
+ .name = "HY29F002T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = HYUNDAI_ID,
+ .model_id = HYUNDAI_HY29F002T,
+ .total_size = 256,
+ .page_size = 256 * 1024,
+ .feature_bits = FEATURE_EITHER_RESET, /* Some revisions may need FEATURE_ADDR_2AA */
+ .tested = TEST_OK_PRE,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 3},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4750, 5250}, /* 4.75-5.25V for type -45, others 4.5-5.5V */
+ },
+
+ {
+ .vendor = "Hyundai",
+ .name = "HY29F002B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = HYUNDAI_ID,
+ .model_id = HYUNDAI_HY29F002B,
+ .total_size = 256,
+ .page_size = 256 * 1024,
+ .feature_bits = FEATURE_EITHER_RESET, /* Some revisions may need FEATURE_ADDR_2AA */
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {32 * 1024, 1},
+ {64 * 1024, 3},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4750, 5250}, /* 4.75-5.25V for type -45, others 4.5-5.5V */
+ },
+
+ {
+ .vendor = "Hyundai",
+ .name = "HY29F040A",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = HYUNDAI_ID,
+ .model_id = HYUNDAI_HY29F040A,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "25F160S33B8",
+ .bustype = BUS_SPI,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_25F160S33B8,
+ .total_size = 2048,
+ .page_size = 256,
+ /* OTP: 506B total (2x 8B, 30x 16B, 1x 10B); read 0x4B; write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ /* This chip supports erasing of the 8 so-called "parameter blocks" with
+ * opcode 0x40. Trying to access an address outside these 8 8kB blocks does
+ * have no effect on the memory contents, but sets a flag in the SR.
+ .eraseblocks = {
+ {8 * 1024, 8},
+ {64 * 1024, 31} // inaccessible
+ },
+ .block_erase = spi_block_erase_40,
+ }, { */
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_ep_srwd,
+ .unlock = spi_disable_blockprotect_bp2_ep_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* also fast read 0x0B */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "25F160S33T8",
+ .bustype = BUS_SPI,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_25F160S33T8,
+ .total_size = 2048,
+ .page_size = 256,
+ /* OTP: 506B total (2x 8B, 30x 16B, 1x 10B); read 0x4B; write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ /* This chip supports erasing of the 8 so-called "parameter blocks" with
+ * opcode 0x40. Trying to access an address outside these 8 8kB blocks does
+ * have no effect on the memory contents, but sets a flag in the SR.
+ .eraseblocks = {
+ {64 * 1024, 31}, // inaccessible
+ {8 * 1024, 8}
+ },
+ .block_erase = spi_block_erase_40,
+ }, { */
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_ep_srwd,
+ .unlock = spi_disable_blockprotect_bp2_ep_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* also fast read 0x0B */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "25F320S33B8",
+ .bustype = BUS_SPI,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_25F320S33B8,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 506B total (2x 8B, 30x 16B, 1x 10B); read 0x4B; write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ /* This chip supports erasing of the 8 so-called "parameter blocks" with
+ * opcode 0x40. Trying to access an address outside these 8 8kB blocks does
+ * have no effect on the memory contents, but sets a flag in the SR.
+ .eraseblocks = {
+ {8 * 1024, 8},
+ {64 * 1024, 63} // inaccessible
+ },
+ .block_erase = spi_block_erase_40,
+ }, { */
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_ep_srwd,
+ .unlock = spi_disable_blockprotect_bp2_ep_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* also fast read 0x0B */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "25F320S33T8",
+ .bustype = BUS_SPI,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_25F320S33T8,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 506B total (2x 8B, 30x 16B, 1x 10B); read 0x4B; write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ /* This chip supports erasing of the 8 so-called "parameter blocks" with
+ * opcode 0x40. Trying to access an address outside these 8 8kB blocks does
+ * have no effect on the memory contents, but sets a flag in the SR.
+ .eraseblocks = {
+ {64 * 1024, 63}, // inaccessible
+ {8 * 1024, 8}
+ },
+ .block_erase = spi_block_erase_40,
+ }, { */
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_ep_srwd,
+ .unlock = spi_disable_blockprotect_bp2_ep_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* also fast read 0x0B */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "25F640S33B8",
+ .bustype = BUS_SPI,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_25F640S33B8,
+ .total_size = 8192,
+ .page_size = 256,
+ /* OTP: 506B total (2x 8B, 30x 16B, 1x 10B); read 0x4B; write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ /* This chip supports erasing of the 8 so-called "parameter blocks" with
+ * opcode 0x40. Trying to access an address outside these 8 8kB blocks does
+ * have no effect on the memory contents, but sets a flag in the SR.
+ .eraseblocks = {
+ {8 * 1024, 8},
+ {64 * 1024, 127} // inaccessible
+ },
+ .block_erase = spi_block_erase_40,
+ }, { */
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_ep_srwd,
+ .unlock = spi_disable_blockprotect_bp2_ep_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* also fast read 0x0B */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "25F640S33T8",
+ .bustype = BUS_SPI,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_25F640S33T8,
+ .total_size = 8192,
+ .page_size = 256,
+ /* OTP: 506B total (2x 8B, 30x 16B, 1x 10B); read 0x4B; write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ /* This chip supports erasing of the 8 so-called "parameter blocks" with
+ * opcode 0x40. Trying to access an address outside these 8 8kB blocks does
+ * have no effect on the memory contents, but sets a flag in the SR.
+ .eraseblocks = {
+ {64 * 1024, 127}, // inaccessible
+ {8 * 1024, 8}
+ },
+ .block_erase = spi_block_erase_40,
+ }, { */
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_ep_srwd,
+ .unlock = spi_disable_blockprotect_bp2_ep_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* also fast read 0x0B */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "28F001BN/BX-B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_28F001B,
+ .total_size = 128,
+ .page_size = 128 * 1024, /* 8k + 2x4k + 112k */
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ {112 * 1024, 1},
+ },
+ .block_erase = erase_block_82802ab,
+ },
+ },
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "28F001BN/BX-T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_28F001T,
+ .total_size = 128,
+ .page_size = 128 * 1024, /* 112k + 2x4k + 8k */
+ .tested = TEST_OK_PR,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {112 * 1024, 1},
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ },
+ .block_erase = erase_block_82802ab,
+ },
+ },
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "28F002BC/BL/BV/BX-T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_28F002T,
+ .total_size = 256,
+ .page_size = 256 * 1024,
+ .tested = TEST_OK_PRE,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {128 * 1024, 1},
+ {96 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_block_82802ab,
+ },
+ },
+ .write = write_82802ab,
+ .read = read_memmapped,
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "28F008S3/S5/SC",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_28F004S3,
+ .total_size = 512,
+ .page_size = 256,
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_block_82802ab,
+ },
+ },
+ .unlock = unlock_28f004s5,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "28F004B5/BE/BV/BX-B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_28F004B,
+ .total_size = 512,
+ .page_size = 128 * 1024, /* maximal block size */
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {96 * 1024, 1},
+ {128 * 1024, 3},
+ },
+ .block_erase = erase_block_82802ab,
+ },
+ },
+ .write = write_82802ab,
+ .read = read_memmapped,
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "28F004B5/BE/BV/BX-T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_28F004T,
+ .total_size = 512,
+ .page_size = 128 * 1024, /* maximal block size */
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {128 * 1024, 3},
+ {96 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_block_82802ab,
+ },
+ },
+ .write = write_82802ab,
+ .read = read_memmapped,
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "28F400BV/BX/CE/CV-B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_28F400B,
+ .total_size = 512,
+ .page_size = 128 * 1024, /* maximal block size */
+ .feature_bits = FEATURE_ADDR_SHIFTED,
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {96 * 1024, 1},
+ {128 * 1024, 3},
+ },
+ .block_erase = erase_block_82802ab,
+ },
+ },
+ .write = write_82802ab,
+ .read = read_memmapped,
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "28F400BV/BX/CE/CV-T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_28F400T,
+ .total_size = 512,
+ .page_size = 128 * 1024, /* maximal block size */
+ .feature_bits = FEATURE_ADDR_SHIFTED,
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {128 * 1024, 3},
+ {96 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_block_82802ab,
+ },
+ },
+ .write = write_82802ab,
+ .read = read_memmapped,
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "82802AB",
+ .bustype = BUS_FWH,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_82802AB,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_IGNORED, /* routine does not use probe_timing (82802ab.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_block_82802ab,
+ },
+ },
+ .unlock = unlock_82802ab,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Intel",
+ .name = "82802AC",
+ .bustype = BUS_FWH,
+ .manufacture_id = INTEL_ID,
+ .model_id = INTEL_82802AC,
+ .total_size = 1024,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_OK_PR,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_IGNORED, /* routine does not use probe_timing (82802ab.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = erase_block_82802ab,
+ },
+ },
+ .unlock = unlock_82802ab,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX23L3254",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX23L3254,
+ .total_size = 4096,
+ .page_size = 256,
+ .tested = {.probe = OK, .read = OK, .erase = NA, .write = NA},
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .write = NULL, /* MX23L3254 is a mask ROM, so it is read-only */
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L512(E)/MX25V512(C)",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L512,
+ .total_size = 64,
+ .page_size = 256,
+ /* MX25L512E supports SFDP */
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 16} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_bp1_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported, MX25L512E supports dual I/O */
+ .voltage = {2700, 3600}, /* 2.35-3.6V for MX25V512(C) */
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L1005(C)/MX25L1006E",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L1005,
+ .total_size = 128,
+ .page_size = 256,
+ /* MX25L1006E supports SFDP */
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 2} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_bp1_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported, MX25L1006E supports dual I/O */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L2005(C)",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L2005,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_bp1_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L4005(A/C)",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L4005,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L8005/MX25V8005",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L8005,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600}, /* 2.35-3.6V for MX25V8005 */
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L1605",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L1605,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd, /* bit6: error flag */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L1605A/MX25L1606E",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L1605,
+ .total_size = 2048,
+ .page_size = 256,
+ /* OTP: 64B total; enter 0xB1, exit 0xC1 (MX25L1606E only) */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* MX25L1605A bp2 only */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L1605D/MX25L1608D/MX25L1673E",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L1605,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6: Continously Program (CP) mode */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L1635D",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L1635D,
+ .total_size = 2048,
+ .page_size = 256,
+ /* OTP: 64B total; enter 0xB1, exit 0xC1 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6 is quad enable */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L1635E",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L1635E,
+ .total_size = 2048,
+ .page_size = 256,
+ /* OTP: 64B total; enter 0xB1, exit 0xC1 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6 is quad enable */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L3205(A)",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L3205,
+ .total_size = 4096,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd, /* bit6: error flag */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L3205D/MX25L3208D",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L3205,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 64B total; enter 0xB1, exit 0xC1 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6: CP mode */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and dual I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L3206E",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L3205,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 64B total; enter 0xB1, exit 0xC1 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and dual I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L3273E",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L3205,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 64B total; enter 0xB1, exit 0xC1 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 128} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and dual I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L3235D",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L3235D,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 256B total; enter 0xB1, exit 0xC1 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6 is quad enable */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L6405(D)",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L6405,
+ .total_size = 8192,
+ .page_size = 256,
+ /* MX25L6405D has 64B of OTP; enter 0xB1, exit 0xC1 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6 has different meanings */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L6406E/MX25L6436E",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L6405,
+ .total_size = 8192,
+ .page_size = 256,
+ /* OTP: 06E 64B/36E 512B total; enter 0xB1, exit 0xC1 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 2048} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6 for 36E is quad enable */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L6445E/MX25L6473E",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L6405,
+ .total_size = 8192,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 512B total; enter 0xB1, exit 0xC1 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 2048} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 256} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6 is quad enable */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25L12805(D)",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25L12805,
+ .total_size = 16384,
+ .page_size = 256,
+ /* MX25L12805D has 64B of OTP; enter 0xB1, exit 0xC1 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 4096} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 256} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {16 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {16 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* MX25L12805D: Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25U1635E",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25U1635E,
+ .total_size = 2048,
+ .page_size = 256,
+ /* OTP: 512B total; enter 0xB1, exit 0xC1 */
+ /* QPI enable 0x35, disable 0xF5 (0xFF et al. work too) */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 64} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ /* TODO: security register */
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6 is quad enable */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {1650, 2000},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25U3235E/F",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25U3235E,
+ .total_size = 4096,
+ .page_size = 256,
+ /* F model supports SFDP */
+ /* OTP: 512B total; enter 0xB1, exit 0xC1 */
+ /* QPI enable 0x35, disable 0xF5 (0xFF et al. work too) */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 128} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ /* TODO: security register */
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6 is quad enable */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {1650, 2000},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX25U6435E/F",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX25U6435E,
+ .total_size = 8192,
+ .page_size = 256,
+ /* F model supports SFDP */
+ /* OTP: 512B total; enter 0xB1, exit 0xC1 */
+ /* QPI enable 0x35, disable 0xF5 (0xFF et al. work too) */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 2048} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 256} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ /* TODO: security register */
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* bit6 is quad enable */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {1650, 2000},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX29F001B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX29F001B,
+ .total_size = 128,
+ .page_size = 32 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {8 * 1024, 1},
+ {4 * 1024, 2},
+ {8 * 1024, 2},
+ {32 * 1024, 1},
+ {64 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX29F001T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX29F001T,
+ .total_size = 128,
+ .page_size = 32 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 1},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {4 * 1024, 2},
+ {8 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX29F002(N)B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX29F002B,
+ .total_size = 256,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {32 * 1024, 1},
+ {64 * 1024, 3},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX29F002(N)T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX29F002T,
+ .total_size = 256,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 3},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX29F040",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX29F040,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "MX29LV040",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = MACRONIX_MX29LV040,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_SHORT_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8}, },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25P05-A",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25P05A,
+ .total_size = 64,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {32 * 1024, 2} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ /* The ST M25P05 is a bit of a problem. It has the same ID as the
+ * ST M25P05-A in RES mode, but supports only 128 byte writes instead
+ * of 256 byte writes. We rely heavily on the fact that probe_spi_res1
+ * only is successful if RDID does not work.
+ */
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25P05",
+ .bustype = BUS_SPI,
+ .manufacture_id = 0, /* Not used. */
+ .model_id = ST_M25P05_RES,
+ .total_size = 64,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_res1,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {32 * 1024, 2} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_1, /* 128 */
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25P10-A",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25P10A,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PRE,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ /* The ST M25P10 has the same problem as the M25P05. */
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25P10",
+ .bustype = BUS_SPI,
+ .manufacture_id = 0, /* Not used. */
+ .model_id = ST_M25P10_RES,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_res1,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_1, /* 128 */
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST", /* Numonyx */
+ .name = "M25P20",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25P20,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp1_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25P20-old",
+ .bustype = BUS_SPI,
+ .manufacture_id = 0, /* Not used. */
+ .model_id = ST_M25P20_RES,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_res1,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp1_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST", /* Numonyx */
+ .name = "M25P40",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25P40,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25P40-old",
+ .bustype = BUS_SPI,
+ .manufacture_id = 0, /* Not used. */
+ .model_id = ST_M25P40_RES,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_res1,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25P80",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25P80,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25P16",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25P16,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25P32",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25P32,
+ .total_size = 4096,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25P64",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25P64,
+ .total_size = 8192,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25P128",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25P128,
+ .total_size = 16384,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {256 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {16 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25PE10",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25PE10,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 2} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25PE20",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25PE20,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25PE40",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25PE40,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25PE80",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25PE80,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25PE16",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25PE16,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25PX80",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25PX80,
+ .total_size = 1024,
+ .page_size = 256,
+ /* OTP: 64B total; read 0x4B, write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { { 4 * 1024, 256 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd, /* bit5: T/B */
+ .unlock = spi_disable_blockprotect_bp2_srwd, /* TODO: per 64kB sector lock registers */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25PX16",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25PX16,
+ .total_size = 2048,
+ .page_size = 256,
+ /* OTP: 64B total; read 0x4B; write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { { 4 * 1024, 512 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd, /* bit5: T/B */
+ .unlock = spi_disable_blockprotect_bp2_srwd, /* TODO: per 64kB sector lock registers */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2300, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25PX32",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25PX32,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 64B total; read 0x4B; write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PRE,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { { 4 * 1024, 1024 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd, /* bit5: T/B */
+ .unlock = spi_disable_blockprotect_bp2_srwd, /* TODO: per 64kB sector lock registers */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M25PX64",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M25PX64,
+ .total_size = 8192,
+ .page_size = 256,
+ /* OTP: 64B total; read 0x4B; write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { { 4 * 1024, 2048 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd, /* bit5: T/B */
+ .unlock = spi_disable_blockprotect_bp2_srwd, /* TODO: per 64kB sector lock registers */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M45PE10",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M45PE10,
+ .total_size = 128,
+ .page_size = 256,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {256, 512} },
+ .block_erase = spi_block_erase_db,
+ }, {
+ .eraseblocks = { {64 * 1024, 2} },
+ .block_erase = spi_block_erase_d8,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_default_welwip,
+ .unlock = NULL, /* #WP pin write-protects lower 64kB. */
+ .write = spi_chip_write_256, /* Page write (similar to PP but allows 0->1 changes) */
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M45PE20",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M45PE20,
+ .total_size = 256,
+ .page_size = 256,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {256, 1024} },
+ .block_erase = spi_block_erase_db,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_default_welwip,
+ .unlock = NULL, /* #WP pin write-protects lower 64kB. */
+ .write = spi_chip_write_256, /* Page write (similar to PP but allows 0->1 changes) */
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M45PE40",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M45PE40,
+ .total_size = 512,
+ .page_size = 256,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {256, 2048} },
+ .block_erase = spi_block_erase_db,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_default_welwip,
+ .unlock = NULL, /* #WP pin write-protects lower 64kB. */
+ .write = spi_chip_write_256, /* Page write (similar to PP but allows 0->1 changes) */
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M45PE80",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M45PE80,
+ .total_size = 1024,
+ .page_size = 256,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {256, 4096} },
+ .block_erase = spi_block_erase_db,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_default_welwip,
+ .unlock = NULL, /* #WP pin write-protects lower 64kB. */
+ .write = spi_chip_write_256, /* Page write (similar to PP but allows 0->1 changes) */
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "M45PE16",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M45PE16,
+ .total_size = 2048,
+ .page_size = 256,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {256, 8192} },
+ .block_erase = spi_block_erase_db,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_default_welwip,
+ .unlock = NULL, /* #WP pin write-protects lower 64kB. */
+ .write = spi_chip_write_256, /* Page write (similar to PP but allows 0->1 changes) */
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "N25Q016",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_N25Q016__1E,
+ .total_size = 2048,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 64B total; read 0x4B, write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 64} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_n25q, /* TODO: config, lock, flag regs */
+ .unlock = spi_disable_blockprotect_n25q, /* TODO: per 64kB sector lock registers */
+ .write = spi_chip_write_256, /* Multi I/O supported */
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {1700, 2000},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "N25Q032..1E",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_N25Q032__1E,
+ .total_size = 4096,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 64B total; read 0x4B, write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_n25q, /* TODO: config, lock, flag regs */
+ .unlock = spi_disable_blockprotect_n25q, /* TODO: per 64kB sector lock registers */
+ .write = spi_chip_write_256, /* Multi I/O supported */
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {1700, 2000},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "N25Q032..3E",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_N25Q032__3E,
+ .total_size = 4096,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 64B total; read 0x4B, write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_n25q, /* TODO: config, lock, flag regs */
+ .unlock = spi_disable_blockprotect_n25q, /* TODO: per 64kB sector lock registers */
+ .write = spi_chip_write_256, /* Multi I/O supported */
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "N25Q064..1E", /* ..1E = 1.8V, uniform 64KB/4KB blocks/sectors */
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_N25Q064__1E,
+ .total_size = 8192,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 64B total; read 0x4B, write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 2048 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_n25q, /* TODO: config, lock, flag regs */
+ .unlock = spi_disable_blockprotect_n25q, /* TODO: per 64kB sector lock registers */
+ .write = spi_chip_write_256, /* Multi I/O supported */
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {1700, 2000},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "N25Q064..3E", /* ..3E = 3V, uniform 64KB/4KB blocks/sectors */
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_N25Q064__3E,
+ .total_size = 8192,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 64B total; read 0x4B, write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 2048 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_n25q, /* TODO: config, lock, flag regs */
+ .unlock = spi_disable_blockprotect_n25q, /* TODO: per 64kB sector lock registers */
+ .write = spi_chip_write_256, /* Multi I/O supported */
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "N25Q128..1E", /* ..1E = 1.8V, uniform 64KB/4KB blocks/sectors */
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_N25Q128__1E,
+ .total_size = 16384,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 64B total; read 0x4B, write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 4096 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 256} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {16384 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_n25q, /* TODO: config, lock, flag regs */
+ .unlock = spi_disable_blockprotect_n25q, /* TODO: per 64kB sector lock registers */
+ .write = spi_chip_write_256, /* Multi I/O supported */
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {1700, 2000},
+ },
+
+ {
+ .vendor = "Micron/Numonyx/ST",
+ .name = "N25Q128..3E", /* ..3E = 3V, uniform 64KB/4KB blocks/sectors */
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = ST_N25Q128__3E,
+ .total_size = 16384,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 64B total; read 0x4B, write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 4096 } },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 256} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {16384 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_n25q, /* TODO: config, lock, flag regs */
+ .unlock = spi_disable_blockprotect_n25q, /* TODO: per 64kB sector lock registers */
+ .write = spi_chip_write_256, /* Multi I/O supported */
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "MoselVitelic",
+ .name = "V29C51000B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SYNCMOS_MVC_ID,
+ .model_id = MVC_V29C51000B,
+ .total_size = 64,
+ .page_size = 512,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {512, 128} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "MoselVitelic",
+ .name = "V29C51000T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SYNCMOS_MVC_ID,
+ .model_id = MVC_V29C51000T,
+ .total_size = 64,
+ .page_size = 512,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {512, 128} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "MoselVitelic",
+ .name = "V29C51400B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SYNCMOS_MVC_ID,
+ .model_id = MVC_V29C51400B,
+ .total_size = 512,
+ .page_size = 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {1024, 512} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "MoselVitelic",
+ .name = "V29C51400T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SYNCMOS_MVC_ID,
+ .model_id = MVC_V29C51400T,
+ .total_size = 512,
+ .page_size = 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {1024, 512} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "MoselVitelic",
+ .name = "V29LC51000",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SYNCMOS_MVC_ID,
+ .model_id = MVC_V29LC51000,
+ .total_size = 64,
+ .page_size = 512,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {512, 128} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "MoselVitelic",
+ .name = "V29LC51001",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SYNCMOS_MVC_ID,
+ .model_id = MVC_V29LC51001,
+ .total_size = 128,
+ .page_size = 512,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {512, 256} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "MoselVitelic",
+ .name = "V29LC51002",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SYNCMOS_MVC_ID,
+ .model_id = MVC_V29LC51002,
+ .total_size = 256,
+ .page_size = 512,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {512, 512} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Nantronics",
+ .name = "N25S10",
+ .bustype = BUS_SPI,
+ .manufacture_id = NANTRONICS_ID_NOPREFIX,
+ .model_id = NANTRONICS_N25S10,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 2} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd,
+ .unlock = spi_disable_blockprotect_bp3_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O read (0x3B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Nantronics",
+ .name = "N25S20",
+ .bustype = BUS_SPI,
+ .manufacture_id = NANTRONICS_ID_NOPREFIX,
+ .model_id = NANTRONICS_N25S20,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {32 * 1024, 8} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd,
+ .unlock = spi_disable_blockprotect_bp3_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O read (0x3B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Nantronics",
+ .name = "N25S40",
+ .bustype = BUS_SPI,
+ .manufacture_id = NANTRONICS_ID_NOPREFIX,
+ .model_id = NANTRONICS_N25S40,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {32 * 1024, 16} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd,
+ .unlock = spi_disable_blockprotect_bp3_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O read (0x3B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Nantronics",
+ .name = "N25S80",
+ .bustype = BUS_SPI,
+ .manufacture_id = NANTRONICS_ID_NOPREFIX,
+ .model_id = NANTRONICS_N25S80,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 32} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd,
+ .unlock = spi_disable_blockprotect_bp3_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O read (0x3B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Nantronics",
+ .name = "N25S16",
+ .bustype = BUS_SPI,
+ .manufacture_id = NANTRONICS_ID_NOPREFIX,
+ .model_id = NANTRONICS_N25S16,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2048 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2048 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd,
+ .unlock = spi_disable_blockprotect_bp3_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O read (0x3B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm25LD256C",
+ .bustype = BUS_SPI,
+ .manufacture_id = PMC_ID,
+ .model_id = PMC_PM25LD256C,
+ .total_size = 32,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 8} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {4 * 1024, 8} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {32 * 1024, 1} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {32 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {32 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O supported */
+ .voltage = {2700, 3600},
+ },
+ {
+ .vendor = "PMC",
+ .name = "Pm25LD512(C)",
+ .bustype = BUS_SPI,
+ .manufacture_id = PMC_ID,
+ .model_id = PMC_PM25LD512,
+ .total_size = 64,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 16} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {4 * 1024, 16} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {32 * 1024, 2} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect, /* FIXME: C version supports "Safe Guard" */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O supported */
+ .voltage = {2300, 3600},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm25LD010(C)",
+ .bustype = BUS_SPI,
+ .manufacture_id = PMC_ID,
+ .model_id = PMC_PM25LD010,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect, /* FIXME: C version supports "Safe Guard" */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O supported */
+ .voltage = {2700, 3600}, /* 2.3-3.6V for Pm25LD010 */
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm25LD020(C)",
+ .bustype = BUS_SPI,
+ .manufacture_id = PMC_ID,
+ .model_id = PMC_PM25LD020,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect, /* FIXME: C version supports "Safe Guard" */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O supported */
+ .voltage = {2700, 3600}, /* 2.3-3.6V for Pm25LD020 */
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm25LD040(C)",
+ .bustype = BUS_SPI,
+ .manufacture_id = PMC_ID,
+ .model_id = PMC_PM25LV040,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O supported */
+ .voltage = {2700, 3600}, /* 2.3-3.6V for Pm25LD040 */
+ },
+
+{
+ .vendor = "PMC",
+ .name = "Pm25LV512(A)",
+ .bustype = BUS_SPI,
+ .manufacture_id = PMC_ID_NOPREFIX,
+ .model_id = PMC_PM25LV512,
+ .total_size = 64,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_res2, /* The continuation code is transferred as the 3rd byte m( */
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 16} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {32 * 1024, 2} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp1_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm25LV010",
+ .bustype = BUS_SPI,
+ .manufacture_id = PMC_ID_NOPREFIX,
+ .model_id = PMC_PM25LV010,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_res2, /* The continuation code is transferred as the 3rd byte m( */
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp1_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm25LV010A",
+ .bustype = BUS_SPI,
+ .manufacture_id = PMC_ID,
+ .model_id = PMC_PM25LV010,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp1_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm25LV020",
+ .bustype = BUS_SPI,
+ .manufacture_id = PMC_ID,
+ .model_id = PMC_PM25LV020,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm25LV040",
+ .bustype = BUS_SPI,
+ .manufacture_id = PMC_ID,
+ .model_id = PMC_PM25LV040,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm25LV080B",
+ .bustype = BUS_SPI,
+ .manufacture_id = PMC_ID,
+ .model_id = PMC_PM25LV080B,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm25LV016B",
+ .bustype = BUS_SPI,
+ .manufacture_id = PMC_ID,
+ .model_id = PMC_PM25LV016B,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm29F002T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = PMC_ID_NOPREFIX,
+ .model_id = PMC_PM29F002T,
+ .total_size = 256,
+ .page_size = 8 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_FIXME,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {128 * 1024, 1},
+ {96 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm29F002B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = PMC_ID_NOPREFIX,
+ .model_id = PMC_PM29F002B,
+ .total_size = 256,
+ .page_size = 8 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_FIXME,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {96 * 1024, 1},
+ {128 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm39LV010",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = PMC_ID_NOPREFIX,
+ .model_id = PMC_PM39F010, /* Pm39LV010 and Pm39F010 have identical IDs but different voltage */
+ .total_size = 128,
+ .page_size = 4096,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 2} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm39LV020",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = PMC_ID_NOPREFIX,
+ .model_id = PMC_PM39LV020,
+ .total_size = 256,
+ .page_size = 4096,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm39LV040",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = PMC_ID_NOPREFIX,
+ .model_id = PMC_PM39LV040,
+ .total_size = 512,
+ .page_size = 4096,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PR,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm39LV512",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = PMC_ID_NOPREFIX,
+ .model_id = PMC_PM39LV512,
+ .total_size = 64,
+ .page_size = 4096,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 16} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm49FL002",
+ .bustype = BUS_LPC | BUS_FWH, /* A/A Mux */
+ .manufacture_id = PMC_ID_NOPREFIX,
+ .model_id = PMC_PM49FL002,
+ .total_size = 256,
+ .page_size = 16 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* routine is wrapper to probe_jedec (pm49fl00x.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {16 * 1024, 16} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .unlock = unlock_49fl00x,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "Pm49FL004",
+ .bustype = BUS_LPC | BUS_FWH, /* A/A Mux */
+ .manufacture_id = PMC_ID_NOPREFIX,
+ .model_id = PMC_PM49FL004,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* routine is wrapper to probe_jedec (pm49fl00x.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .unlock = unlock_49fl00x,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Sanyo",
+ .name = "LE25FW106",
+ .bustype = BUS_SPI,
+ .manufacture_id = SANYO_ID,
+ .model_id = SANYO_LE25FW106,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_res2,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {2 * 1024, 64} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp1_srwd, /* FIXME: Add ERSER error flag. */
+ .unlock = spi_disable_blockprotect_bp1_srwd,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Sanyo",
+ .name = "LE25FW406A",
+ .bustype = BUS_SPI,
+ .manufacture_id = SANYO_ID,
+ .model_id = SANYO_LE25FW406A,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_res2,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Sanyo",
+ .name = "LE25FU406B",
+ .bustype = BUS_SPI,
+ .manufacture_id = SANYO_ID,
+ .model_id = SANYO_LE25FU406B,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_res2,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect, /* #WP pin write-protects SRWP bit. */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2300, 3600},
+ },
+
+ {
+ .vendor = "Sanyo",
+ .name = "LE25FW203A",
+ .bustype = BUS_SPI,
+ .manufacture_id = SANYO_ID,
+ .model_id = SANYO_LE25FW203A,
+ .total_size = 256,
+ .page_size = 256,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {256, 1024} },
+ .block_erase = spi_block_erase_db,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_default_welwip,
+ .unlock = NULL, /* #WP pin write-protects lower 64kB. */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Sanyo",
+ .name = "LE25FW403A",
+ .bustype = BUS_SPI,
+ .manufacture_id = SANYO_ID,
+ .model_id = SANYO_LE25FW403A,
+ .total_size = 512,
+ .page_size = 256,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {256, 2 * 1024} },
+ .block_erase = spi_block_erase_db,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_default_welwip,
+ .unlock = NULL, /* #WP pin write-protects lower 64kB. */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Sanyo",
+ .name = "LE25FW418A",
+ .bustype = BUS_SPI,
+ .manufacture_id = SANYO_ID,
+ .model_id = SANYO_LE25FW418A,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_res2,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect, /* #WP pin write-protects SRWP bit. */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* some quad-read supported ("HD_READ mode") */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Sanyo",
+ .name = "LE25FW806",
+ .bustype = BUS_SPI,
+ .manufacture_id = SANYO_ID,
+ .model_id = SANYO_LE25FW806,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_res2,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect, /* #WP pin write-protects SRWP bit. */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Sanyo",
+ .name = "LE25FW808",
+ .bustype = BUS_SPI,
+ .manufacture_id = SANYO_ID,
+ .model_id = SANYO_LE25FW808,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_res2,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {8 * 1024, 128} },
+ .block_erase = spi_block_erase_d7,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd,
+ .unlock = spi_disable_blockprotect, /* #WP pin write-protects SRWP bit. */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* some quad-read supported ("HD_READ mode") */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Sharp",
+ .name = "LH28F008BJT-BTLZ1",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SHARP_ID,
+ .model_id = SHARP_LH28F008BJ__PB,
+ .total_size = 1024,
+ .page_size = 64 * 1024,
+ .tested = TEST_OK_PREW,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {8 * 1024, 8},
+ {64 * 1024, 15}
+ },
+ .block_erase = erase_block_82802ab,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = erase_sector_49lfxxxc,
+ }
+ },
+ .unlock = unlock_lh28f008bjt,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Sharp",
+ .name = "LHF00L04",
+ .bustype = BUS_FWH, /* A/A Mux */
+ .manufacture_id = SHARP_ID,
+ .model_id = SHARP_LHF00L04,
+ .total_size = 1024,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_EITHER_RESET | FEATURE_REGISTERMAP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 15},
+ {8 * 1024, 8}
+ },
+ .block_erase = erase_block_82802ab,
+ }, {
+ .eraseblocks = {
+ {1024 * 1024, 1}
+ },
+ .block_erase = NULL, /* 30 D0, only in A/A mux mode */
+ },
+ },
+ .unlock = unlock_82802ab,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Spansion",
+ .name = "S25FL004A",
+ .bustype = BUS_SPI,
+ .manufacture_id = SPANSION_ID,
+ .model_id = SPANSION_S25FL004A,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Spansion",
+ .name = "S25FL008A",
+ .bustype = BUS_SPI,
+ .manufacture_id = SPANSION_ID,
+ .model_id = SPANSION_S25FL008A,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PRE,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Spansion",
+ .name = "S25FL016A",
+ .bustype = BUS_SPI,
+ .manufacture_id = SPANSION_ID,
+ .model_id = SPANSION_S25FL016A,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PR,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Spansion",
+ .name = "S25FL032A/P",
+ .bustype = BUS_SPI,
+ .manufacture_id = SPANSION_ID,
+ .model_id = SPANSION_S25FL032A,
+ .total_size = 4096,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Spansion",
+ .name = "S25FL064A/P",
+ .bustype = BUS_SPI,
+ .manufacture_id = SPANSION_ID,
+ .model_id = SPANSION_S25FL064A,
+ .total_size = 8192,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Spansion",
+ .name = "S25FL204K",
+ .bustype = BUS_SPI,
+ .manufacture_id = SPANSION_ID,
+ .model_id = SPANSION_S25FL204,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { { 512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd,
+ .unlock = spi_disable_blockprotect_bp3_srwd, /* #WP pin write-protects SRWP bit. */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O (0x3B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Spansion",
+ .name = "S25FL208K",
+ .bustype = BUS_SPI,
+ .manufacture_id = SPANSION_ID,
+ .model_id = SPANSION_S25FL208,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { { 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd,
+ .unlock = spi_disable_blockprotect_bp3_srwd, /* #WP pin write-protects SRWP bit. */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O (0x3B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Spansion",
+ .name = "S25FL116K/S25FL216K",
+ .bustype = BUS_SPI,
+ .manufacture_id = SPANSION_ID,
+ .model_id = SPANSION_S25FL216,
+ .total_size = 2048,
+ .page_size = 256,
+ /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44 (S25FL116K only) */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 2048 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { { 2048 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp3_srwd,
+ .unlock = spi_disable_blockprotect_bp3_srwd, /* #WP pin write-protects SRWP bit. */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B), dual I/O (0x3B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Spansion",
+ .name = "S25FL132K",
+ .bustype = BUS_SPI,
+ .manufacture_id = SPANSION_ID,
+ .model_id = SPANSION_S25FL132K,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 768B total, 256B reserved; read 0x48; write 0x42, erase 0x44 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 4096 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { { 4096 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd, /* TODO: improve */
+ .unlock = spi_disable_blockprotect_bp2_srwd, /* #WP pin write-protects SRWP bit. */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Spansion",
+ .name = "S25FL164K",
+ .bustype = BUS_SPI,
+ .manufacture_id = SPANSION_ID,
+ .model_id = SPANSION_S25FL164K,
+ .total_size = 8192,
+ .page_size = 256,
+ /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 2048} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 8192 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { { 8192 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_srwd, /* TODO: improve */
+ .unlock = spi_disable_blockprotect_bp2_srwd, /* #WP pin write-protects SRWP bit. */
+ .write = spi_chip_write_256,
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Spansion",
+ .name = "S25FL128S......0", /* uniform 256kB sectors */
+ .bustype = BUS_SPI,
+ .manufacture_id = SPANSION_ID,
+ .model_id = SPANSION_S25FL128,
+ .total_size = 16384,
+ .page_size = 256,
+ /* supports 4B addressing */
+ /* OTP: 1024B total, 32B reserved; read 0x4B; write 0x42 */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers = {
+ {
+ .eraseblocks = { {4 * 1024, 4096} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {256 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { { 16384 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { { 16384 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_bp2_ep_srwd, /* TODO: SR2 and many others */
+ .unlock = spi_disable_blockprotect_bp2_srwd, /* TODO: various other locks */
+ .write = spi_chip_write_256, /* Multi I/O supported */
+ .read = spi_chip_read, /* Fast read (0x0B) and multi I/O supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25LF020A",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25VF020_REMS,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EWSR,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rems,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 8} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* FIXME: No BP2 & 3 */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_1, /* AAI supported, but opcode is 0xAF */
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25LF040A",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25VF040_REMS,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EWSR,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_res2,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 16} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_1, /* AAI supported, but opcode is 0xAF */
+ .read = spi_chip_read,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25LF080(A)",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25VF080_REMS,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EITHER,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_res2,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 32} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_1, /* AAI supported, but opcode is 0xAF */
+ .read = spi_chip_read,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25VF512A",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25VF512A_REMS,
+ .total_size = 64,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EWSR,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rems,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 16} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 2} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {32 * 1024, 2} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* FIXME: No BP2 & 3 */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_1, /* AAI supported, but opcode is 0xAF */
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25VF010",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25VF010_REMS,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EWSR,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rems,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* FIXME: No BP2 & 3 */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_1, /* AAI supported, but opcode is 0xAF */
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25VF020",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25VF020_REMS,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EWSR,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rems,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 8} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* FIXME: No BP2 & 3 */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_1, /* AAI supported, but opcode is 0xAF */
+ .read = spi_chip_read, /* only */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25VF020B",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25VF020B,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EWSR,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 8} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* FIXME: No BP2 & 3 and 2nd SR */
+ .unlock = spi_disable_blockprotect, /* FIXME: 2nd SR */
+ .write = spi_aai_write, /* AAI supported (0xAD) */
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25VF040",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25VF040_REMS,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EWSR,
+ .tested = TEST_OK_PR,
+ .probe = probe_spi_rems,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 16} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_1, /* AAI supported, but opcode is 0xAF */
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25VF040B",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25VF040B,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EWSR,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 16} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25vf040b,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_aai_write, /* AAI supported (0xAD) */
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25VF040B.REMS",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25VF040B_REMS,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EWSR,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rems,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 16} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25vf040b,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_aai_write,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25VF080B",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25VF080B,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EWSR,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 32} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_aai_write,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25VF016B",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = 0x41,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EITHER,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_res2,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 64} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25vf016,
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_1,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25VF032B",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25VF032B,
+ .total_size = 4096,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EWSR,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 128} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_aai_write,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25VF064C",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25VF064C,
+ .total_size = 8192,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EWSR,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 2048} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 256} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* TODO: check */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25WF512",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25WF512,
+ .total_size = 64,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EITHER,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 16} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 2} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {1024 * 64, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 64, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* FIXME: does not have a BP3 */
+ .unlock = spi_disable_blockprotect_bp2_srwd,
+ .write = spi_aai_write,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {1650, 1950},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25WF010",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25WF010,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EITHER,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 4} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {1024 * 128, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 128, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* FIXME: does not have a BP3 */
+ .unlock = spi_disable_blockprotect_bp2_srwd,
+ .write = spi_aai_write,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {1650, 1950},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25WF020",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25WF020,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EITHER,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 8} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 256, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 256, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* FIXME: does not have a BP3 */
+ .unlock = spi_disable_blockprotect_bp2_srwd,
+ .write = spi_aai_write,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {1650, 1950},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25WF040",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25WF040,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EITHER,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 16} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 512, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 512, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* FIXME: does not have a BP3 */
+ .unlock = spi_disable_blockprotect_bp2_srwd,
+ .write = spi_aai_write,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {1650, 1950},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST25WF080",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST25WF080,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_EITHER,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 32} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ },
+ },
+ .printlock = spi_prettyprint_status_register_sst25, /* *does* have a BP3 but it is useless */
+ .unlock = spi_disable_blockprotect_bp3_srwd,
+ .write = spi_aai_write,
+ .read = spi_chip_read, /* Fast read (0x0B) supported */
+ .voltage = {1650, 1950},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST28SF040A",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST28SF040,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = 0,
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (sst28sf040.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {128, 4096} },
+ .block_erase = erase_sector_28sf040,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_28sf040,
+ }
+ },
+ .unlock = unprotect_28sf040,
+ .write = write_28sf040,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST29EE010",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST29EE010,
+ .total_size = 128,
+ .page_size = 128,
+ .feature_bits = FEATURE_LONG_RESET,
+ .tested = TEST_OK_PR,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST29LE010",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST29LE010,
+ .total_size = 128,
+ .page_size = 128,
+ .feature_bits = FEATURE_LONG_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST29EE020A",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST29EE020A,
+ .total_size = 256,
+ .page_size = 128,
+ .feature_bits = FEATURE_LONG_RESET,
+ .tested = TEST_OK_PRE,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST29LE020",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST29LE020,
+ .total_size = 256,
+ .page_size = 128,
+ .feature_bits = FEATURE_LONG_RESET,
+ .tested = TEST_OK_PRE,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST39SF512",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST39SF512,
+ .total_size = 64,
+ .page_size = 4096,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 16} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST39SF010A",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST39SF010,
+ .total_size = 128,
+ .page_size = 4096,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST39SF020A",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST39SF020,
+ .total_size = 256,
+ .page_size = 4096,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST39SF040",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST39SF040,
+ .total_size = 512,
+ .page_size = 4096,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST39VF512",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST39VF512,
+ .total_size = 64,
+ .page_size = 4096,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 16} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST39VF010",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST39VF010,
+ .total_size = 128,
+ .page_size = 4096,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST39VF020",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST39VF020,
+ .total_size = 256,
+ .page_size = 4096,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST39VF040",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST39VF040,
+ .total_size = 512,
+ .page_size = 4096,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST39VF080",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST39VF080,
+ .total_size = 1024,
+ .page_size = 4096,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST49LF002A/B",
+ .bustype = BUS_FWH, /* A/A Mux */
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST49LF002A,
+ .total_size = 256,
+ .page_size = 16 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {16 * 1024, 16} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = NULL, /* AA 55 80 AA 55 10, only in A/A mux mode */
+ }
+ },
+ .printlock = printlock_sst_fwhub,
+ .unlock = unlock_sst_fwhub,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST49LF003A/B",
+ .bustype = BUS_FWH, /* A/A Mux */
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST49LF003A,
+ .total_size = 384,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 96} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 6} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {384 * 1024, 1} },
+ .block_erase = NULL, /* AA 55 80 AA 55 10, only in A/A mux mode */
+ }
+ },
+ .printlock = printlock_sst_fwhub,
+ .unlock = unlock_sst_fwhub,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ /* Contrary to the data sheet, TBL# on the SST49LF004B affects the top 128kB (instead of 64kB)
+ * and is only honored for 64k block erase, but not 4k sector erase.
+ */
+ .vendor = "SST",
+ .name = "SST49LF004A/B",
+ .bustype = BUS_FWH, /* A/A Mux */
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST49LF004A,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = NULL, /* AA 55 80 AA 55 10, only in A/A mux mode */
+ },
+ },
+ .printlock = printlock_sst_fwhub,
+ .unlock = unlock_sst_fwhub,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST49LF004C",
+ .bustype = BUS_FWH,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST49LF004C,
+ .total_size = 512,
+ .page_size = 4 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (sst49lfxxxc.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = erase_sector_49lfxxxc,
+ }, {
+ .eraseblocks = {
+ {64 * 1024, 7},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_block_82802ab,
+ }
+ },
+ .unlock = unlock_49lfxxxc,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST49LF008A",
+ .bustype = BUS_FWH, /* A/A Mux */
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST49LF008A,
+ .total_size = 1024,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = NULL, /* AA 55 80 AA 55 10, only in A/A mux mode */
+ }
+ },
+ .printlock = printlock_sst_fwhub,
+ .unlock = unlock_sst_fwhub,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST49LF008C",
+ .bustype = BUS_FWH,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST49LF008C,
+ .total_size = 1024,
+ .page_size = 4 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (sst49lfxxxc.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = erase_sector_49lfxxxc,
+ }, {
+ .eraseblocks = {
+ {64 * 1024, 15},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_block_82802ab,
+ }
+ },
+ .unlock = unlock_49lfxxxc,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST49LF016C",
+ .bustype = BUS_FWH,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST49LF016C,
+ .total_size = 2048,
+ .page_size = 4 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (sst49lfxxxc.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = erase_sector_49lfxxxc,
+ }, {
+ .eraseblocks = {
+ {64 * 1024, 31},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_block_82802ab,
+ }
+ },
+ .unlock = unlock_49lfxxxc,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST49LF020",
+ .bustype = BUS_LPC,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST49LF020,
+ .total_size = 256,
+ .page_size = 16 * 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {16 * 1024, 16} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = NULL,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST49LF020A",
+ .bustype = BUS_LPC,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST49LF020A,
+ .total_size = 256,
+ .page_size = 4 * 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PRE,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {16 * 1024, 16} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = NULL,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST49LF040",
+ .bustype = BUS_LPC,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST49LF040,
+ .total_size = 512,
+ .page_size = 4096,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150 ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = NULL,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST49LF040B",
+ .bustype = BUS_LPC, /* A/A Mux */
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST49LF040B,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_EITHER_RESET | FEATURE_REGISTERMAP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 1, /* 150ns */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = NULL,
+ }
+ },
+ .unlock = unlock_82802ab,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST49LF080A",
+ .bustype = BUS_LPC, /* A/A Mux */
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST49LF080A,
+ .total_size = 1024,
+ .page_size = 4096,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_FIXME,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = NULL,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SST",
+ .name = "SST49LF160C",
+ .bustype = BUS_LPC,
+ .manufacture_id = SST_ID,
+ .model_id = SST_SST49LF160C,
+ .total_size = 2048,
+ .page_size = 4 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_OK_PRE,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (sst49lfxxxc.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = erase_sector_49lfxxxc,
+ }, {
+ .eraseblocks = {
+ {64 * 1024, 31},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_block_82802ab,
+ }
+ },
+ .unlock = unlock_49lfxxxc,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M29F002B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M29F002B,
+ .total_size = 256,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_AAA | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {32 * 1024, 1},
+ {64 * 1024, 3},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4750, 5250}, /* 4.75-5.25V for type -X, others 4.5-5.5V */
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M29F002T/NT",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M29F002T,
+ .total_size = 256,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_AAA | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 3},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4750, 5250}, /* 4.75-5.25V for type -X, others 4.5-5.5V */
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M29F040B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M29F040B,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* datasheet specifies no timing */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8}, },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ /* FIXME: this has WORD/BYTE sequences; 2AA for word, 555 for byte */
+ .vendor = "ST",
+ .name = "M29F400BB",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M29F400BB,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_SHIFTED | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_m29f400bt,
+ .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (m29f400bt.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {32 * 1024, 1},
+ {64 * 1024, 7},
+ },
+ .block_erase = erase_block_shifted_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_shifted_jedec,
+ }
+ },
+ .write = write_m29f400bt,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+ {
+ /* FIXME: this has WORD/BYTE sequences; 2AA for word, 555 for byte */
+ .vendor = "ST",
+ .name = "M29F400BT",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M29F400BT,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_SHIFTED | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_m29f400bt,
+ .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (m29f400bt.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 7},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_block_shifted_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_shifted_jedec,
+ }
+ },
+ .write = write_m29f400bt,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M29W010B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M29W010B,
+ .total_size = 128,
+ .page_size = 16 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {16 * 1024, 8}, },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M29W040B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M29W040B,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8}, },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M29W512B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = ST_ID,
+ .model_id = ST_M29W512B,
+ .total_size = 64,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M50FLW040A",
+ .bustype = BUS_FWH | BUS_LPC, /* A/A Mux */
+ .manufacture_id = ST_ID,
+ .model_id = ST_M50FLW040A,
+ .total_size = 512,
+ .page_size = 0,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_FIXME,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 16}, /* sector */
+ {64 * 1024, 5}, /* block */
+ {4 * 1024, 16}, /* sector */
+ {4 * 1024, 16}, /* sector */
+ },
+ .block_erase = erase_sector_stm50,
+ }, {
+ .eraseblocks = { {64 * 1024, 8}, },
+ .block_erase = erase_block_82802ab,
+ }
+ },
+ .write = write_82802ab,
+ .unlock = unlock_stm50_uniform,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* Also has 12V fast program & erase */
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M50FLW040B",
+ .bustype = BUS_FWH | BUS_LPC, /* A/A Mux */
+ .manufacture_id = ST_ID,
+ .model_id = ST_M50FLW040B,
+ .total_size = 512,
+ .page_size = 0,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_FIXME,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 16}, /* sector */
+ {4 * 1024, 16}, /* sector */
+ {64 * 1024, 5}, /* block */
+ {4 * 1024, 16}, /* sector */
+ },
+ .block_erase = erase_sector_stm50,
+ }, {
+ .eraseblocks = { {64 * 1024, 8}, },
+ .block_erase = erase_block_82802ab,
+ }
+ },
+ .write = write_82802ab,
+ .unlock = unlock_stm50_uniform,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* Also has 12V fast program & erase */
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M50FLW080A",
+ .bustype = BUS_FWH | BUS_LPC, /* A/A Mux */
+ .manufacture_id = ST_ID,
+ .model_id = ST_M50FLW080A,
+ .total_size = 1024,
+ .page_size = 0,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_OK_PRE,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_FIXME,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 16}, /* sector */
+ {64 * 1024, 13}, /* block */
+ {4 * 1024, 16}, /* sector */
+ {4 * 1024, 16}, /* sector */
+ },
+ .block_erase = erase_sector_stm50,
+ }, {
+ .eraseblocks = { {64 * 1024, 16}, },
+ .block_erase = erase_block_82802ab,
+ }
+ },
+ .unlock = unlock_stm50_nonuniform,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* Also has 12V fast program & erase */
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M50FLW080B",
+ .bustype = BUS_FWH | BUS_LPC, /* A/A Mux */
+ .manufacture_id = ST_ID,
+ .model_id = ST_M50FLW080B,
+ .total_size = 1024,
+ .page_size = 0,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_FIXME,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 16}, /* sector */
+ {4 * 1024, 16}, /* sector */
+ {64 * 1024, 13}, /* block */
+ {4 * 1024, 16}, /* sector */
+ },
+ .block_erase = erase_sector_stm50,
+ }, {
+ .eraseblocks = { {64 * 1024, 16}, },
+ .block_erase = erase_block_82802ab,
+ }
+ },
+ .unlock = unlock_stm50_nonuniform,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* Also has 12V fast program & erase */
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M50FW002",
+ .bustype = BUS_FWH, /* A/A Mux */
+ .manufacture_id = ST_ID,
+ .model_id = ST_M50FW002,
+ .total_size = 256,
+ .page_size = 0,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (sst49lfxxxc.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 3},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_block_82802ab,
+ }
+ },
+ .unlock = unlock_stm50_nonuniform,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* Also has 12V fast program & erase */
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M50FW016",
+ .bustype = BUS_FWH, /* A/A Mux */
+ .manufacture_id = ST_ID,
+ .model_id = ST_M50FW016,
+ .total_size = 2048,
+ .page_size = 0,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (82802ab.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 32}, },
+ .block_erase = erase_block_82802ab,
+ }
+ },
+ .unlock = unlock_stm50_uniform,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* Also has 12V fast program & erase */
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M50FW040",
+ .bustype = BUS_FWH, /* A/A Mux */
+ .manufacture_id = ST_ID,
+ .model_id = ST_M50FW040,
+ .total_size = 512,
+ .page_size = 0,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_OK_PR,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (82802ab.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8}, },
+ .block_erase = erase_block_82802ab,
+ }
+ },
+ .unlock = unlock_stm50_uniform,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* Also has 12V fast program & erase */
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M50FW080",
+ .bustype = BUS_FWH, /* A/A Mux */
+ .manufacture_id = ST_ID,
+ .model_id = ST_M50FW080,
+ .total_size = 1024,
+ .page_size = 0,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (82802ab.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 16}, },
+ .block_erase = erase_block_82802ab,
+ }
+ },
+ .unlock = unlock_stm50_uniform,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* Also has 12V fast program & erase */
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M50LPW080",
+ .bustype = BUS_LPC, /* A/A Mux */
+ .manufacture_id = ST_ID,
+ .model_id = ST_M50LPW080,
+ .total_size = 1024,
+ .page_size = 0,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 16}, },
+ .block_erase = erase_block_82802ab,
+ }
+ },
+ .unlock = unlock_stm50_uniform,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* Also has 12V fast program & erase */
+ },
+
+ {
+ .vendor = "ST",
+ .name = "M50LPW116",
+ .bustype = BUS_LPC, /* A/A Mux */
+ .manufacture_id = ST_ID,
+ .model_id = ST_M50LPW116,
+ .total_size = 2048,
+ .page_size = 0,
+ .feature_bits = FEATURE_REGISTERMAP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_82802ab,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {4 * 1024, 16},
+ {64 * 1024, 30},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_block_82802ab,
+ }
+ },
+ .unlock = unlock_stm50_nonuniform,
+ .write = write_82802ab,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* Also has 12V fast program & erase */
+ },
+
+ {
+ .vendor = "SyncMOS/MoselVitelic",
+ .name = "{F,S,V}29C51001B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SYNCMOS_MVC_ID,
+ .model_id = SM_MVC_29C51001B,
+ .total_size = 128,
+ .page_size = 512,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {512, 256} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "SyncMOS/MoselVitelic",
+ .name = "{F,S,V}29C51001T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SYNCMOS_MVC_ID,
+ .model_id = SM_MVC_29C51001T,
+ .total_size = 128,
+ .page_size = 512,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {512, 256} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "SyncMOS/MoselVitelic",
+ .name = "{F,S,V}29C51002B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SYNCMOS_MVC_ID,
+ .model_id = SM_MVC_29C51002B,
+ .total_size = 256,
+ .page_size = 512,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {512, 512} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ },
+
+ {
+ .vendor = "SyncMOS/MoselVitelic",
+ .name = "{F,S,V}29C51002T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SYNCMOS_MVC_ID,
+ .model_id = SM_MVC_29C51002T,
+ .total_size = 256,
+ .page_size = 512,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {512, 512} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ },
+
+ {
+ .vendor = "SyncMOS/MoselVitelic",
+ .name = "{F,S,V}29C51004B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SYNCMOS_MVC_ID,
+ .model_id = SM_MVC_29C51004B,
+ .total_size = 512,
+ .page_size = 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {1024, 512} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "SyncMOS/MoselVitelic",
+ .name = "{F,S,V}29C51004T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SYNCMOS_MVC_ID,
+ .model_id = SM_MVC_29C51004T,
+ .total_size = 512,
+ .page_size = 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {1024, 512} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "SyncMOS/MoselVitelic",
+ .name = "{S,V}29C31004B",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SYNCMOS_MVC_ID,
+ .model_id = SM_MVC_29C31004B,
+ .total_size = 512,
+ .page_size = 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {1024, 512} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "SyncMOS/MoselVitelic",
+ .name = "{S,V}29C31004T",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = SYNCMOS_MVC_ID,
+ .model_id = SM_MVC_29C31004T,
+ .total_size = 512,
+ .page_size = 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {1024, 512} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "TI",
+ .name = "TMS29F002RB",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = TI_OLD_ID,
+ .model_id = TI_TMS29F002RB,
+ .total_size = 256,
+ .page_size = 16384, /* Non-uniform sectors */
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {16 * 1024, 1},
+ {8 * 1024, 2},
+ {32 * 1024, 1},
+ {64 * 1024, 3},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "TI",
+ .name = "TMS29F002RT",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = TI_OLD_ID,
+ .model_id = TI_TMS29F002RT,
+ .total_size = 256,
+ .page_size = 16384, /* Non-uniform sectors */
+ .feature_bits = FEATURE_ADDR_2AA | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = TIMING_ZERO, /* Datasheet has no timing info specified */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 3},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ },
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25Q80.V",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25Q80_V,
+ .total_size = 1024,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44, read ID 0x4B */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 32} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25Q16.V",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25Q16_V,
+ .total_size = 2048,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44, read ID 0x4B */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 64} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25Q32.V",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25Q32_V,
+ .total_size = 4096,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44, read ID 0x4B */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 128} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25Q64.V",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25Q64_V,
+ .total_size = 8192,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44, read ID 0x4B */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 2048} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 256} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25Q128.V",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25Q128_V,
+ .total_size = 16384,
+ .page_size = 256,
+ /* supports SFDP */
+ /* OTP: 1024B total, 256B reserved; read 0x48; write 0x42, erase 0x44, read ID 0x4B */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 4096} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 512} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 256} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {16 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {16 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25Q20.W",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25Q20_W,
+ .total_size = 256,
+ .page_size = 256,
+ /* OTP: 256B total; read 0x48; write 0x42, erase 0x44, read ID 0x4B */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 8} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {1700, 1950}, /* Fast read (0x0B) and multi I/O supported */
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25Q40.W",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25Q40_W,
+ .total_size = 512,
+ .page_size = 256,
+ /* OTP: 256B total; read 0x48; write 0x42, erase 0x44, read ID 0x4B */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 16} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {1700, 1950}, /* Fast read (0x0B) and multi I/O supported */
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25Q80.W",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25Q80_W,
+ .total_size = 1024,
+ .page_size = 256,
+ /* OTP: 256B total; read 0x48; write 0x42, erase 0x44, read ID 0x4B */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 32} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {1 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {1700, 1950}, /* Fast read (0x0B) and multi I/O supported */
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25Q16.W",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25Q16_W,
+ .total_size = 2048,
+ .page_size = 256,
+ /* OTP: 256B total; read 0x48; write 0x42, erase 0x44, read ID 0x4B */
+ /* QPI enable 0x38, disable 0xFF */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .tested = TEST_UNTESTED,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 64} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {1700, 1950}, /* Fast read (0x0B) and multi I/O supported */
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25Q32.W",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25Q32_W,
+ .total_size = 4096,
+ .page_size = 256,
+ /* OTP: 256B total; read 0x48; write 0x42, erase 0x44, read ID 0x4B */
+ /* QPI enable 0x38, disable 0xFF */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 128} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {1700, 1950}, /* Fast read (0x0B) and multi I/O supported */
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25Q64.W",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25Q64_W,
+ .total_size = 8192,
+ .page_size = 256,
+ /* OTP: 256B total; read 0x48; write 0x42, erase 0x44, read ID 0x4B */
+ /* QPI enable 0x38, disable 0xFF */
+ .feature_bits = FEATURE_WRSR_WREN | FEATURE_OTP | FEATURE_QPI,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 2048} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 256} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {1700, 1950}, /* Fast read (0x0B) and multi I/O supported */
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25X10",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25X10,
+ .total_size = 128,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 2} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25X20",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25X20,
+ .total_size = 256,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25X40",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25X40,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25X80",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25X80,
+ .total_size = 1024,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 256} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25X16",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25X16,
+ .total_size = 2048,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 512} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 64} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 32} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {2 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25X32",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25X32,
+ .total_size = 4096,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 1024} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 128} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 64} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {4 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W25X64",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = WINBOND_NEX_W25X64,
+ .total_size = 8192,
+ .page_size = 256,
+ .feature_bits = FEATURE_WRSR_WREN,
+ .tested = TEST_OK_PROBE,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 2048} },
+ .block_erase = spi_block_erase_20,
+ }, {
+ .eraseblocks = { {32 * 1024, 256} },
+ .block_erase = spi_block_erase_52,
+ }, {
+ .eraseblocks = { {64 * 1024, 128} },
+ .block_erase = spi_block_erase_d8,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_60,
+ }, {
+ .eraseblocks = { {8 * 1024 * 1024, 1} },
+ .block_erase = spi_block_erase_c7,
+ }
+ },
+ .printlock = spi_prettyprint_status_register_plain, /* TODO: improve */
+ .unlock = spi_disable_blockprotect,
+ .write = spi_chip_write_256,
+ .read = spi_chip_read,
+ .voltage = {2700, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W29C010(M)/W29C011A/W29EE011/W29EE012-old",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W29C010,
+ .total_size = 128,
+ .page_size = 128,
+ .feature_bits = FEATURE_LONG_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_w29ee011,
+ .probe_timing = TIMING_IGNORED, /* routine doesn't use probe_timing (w29ee011.c) */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec,
+ .read = read_memmapped,
+ },
+
+ {/* W29EE011, W29EE012, W29C010M, W29C011A do not support probe_jedec according to the datasheet, but it works for newer(?) steppings. */
+ .vendor = "Winbond",
+ .name = "W29C010(M)/W29C011A/W29EE011/W29EE012",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W29C010,
+ .total_size = 128,
+ .page_size = 128,
+ .feature_bits = FEATURE_LONG_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10, /* used datasheet for the W29C011A */
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec,
+ .read = read_memmapped,
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W29C020(C)/W29C022",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W29C020,
+ .total_size = 256,
+ .page_size = 128,
+ .feature_bits = FEATURE_LONG_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W29C040/P",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W29C040,
+ .total_size = 512,
+ .page_size = 256,
+ .feature_bits = FEATURE_LONG_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W39F010",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W39F010,
+ .total_size = 128,
+ .page_size = 4 * 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .printlock = printlock_w39f010,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W39L010",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W39L010,
+ .total_size = 128,
+ .page_size = 4 * 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 32} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {128 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .printlock = printlock_w39l010,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W39L020",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W39L020,
+ .total_size = 256,
+ .page_size = 4 * 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 64} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 4} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .printlock = printlock_w39l020,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W39L040",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W39L040,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PR,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .printlock = printlock_w39l040,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W39V040A",
+ .bustype = BUS_LPC,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W39V040A,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .printlock = printlock_w39v040a,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W39V040B",
+ .bustype = BUS_LPC,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W39V040B,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .printlock = printlock_w39v040b,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W39V040C",
+ .bustype = BUS_LPC,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W39V040C,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .printlock = printlock_w39v040c,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W39V040FA",
+ .bustype = BUS_FWH,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W39V040FA,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {4 * 1024, 128} },
+ .block_erase = erase_block_jedec,
+ }, {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .printlock = printlock_w39v040fa,
+ .unlock = unlock_sst_fwhub,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W39V040FB",
+ .bustype = BUS_FWH,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W39V040B,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .printlock = printlock_w39v040fb,
+ .unlock = unlock_w39v040fb,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* Also has 12V fast program */
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W39V040FC",
+ .bustype = BUS_FWH,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W39V040C,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .printlock = printlock_w39v040fc,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* Also has 12V fast program */
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W39V080A",
+ .bustype = BUS_LPC,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W39V080A,
+ .total_size = 1024,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 16} },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .printlock = printlock_w39v080a,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W49F002U/N",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W49F002U,
+ .total_size = 256,
+ .page_size = 128,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {128 * 1024, 1},
+ {96 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W49F020",
+ .bustype = BUS_PARALLEL,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W49F020,
+ .total_size = 256,
+ .page_size = 128,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PROBE,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {4500, 5500},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W49V002A",
+ .bustype = BUS_LPC,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W49V002A,
+ .total_size = 256,
+ .page_size = 128,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 3},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W49V002FA",
+ .bustype = BUS_FWH,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W49V002FA,
+ .total_size = 256,
+ .page_size = 128,
+ .feature_bits = FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = {
+ {64 * 1024, 3},
+ {32 * 1024, 1},
+ {8 * 1024, 2},
+ {16 * 1024, 1},
+ },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {256 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600},
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W39V080FA",
+ .bustype = BUS_FWH,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W39V080FA,
+ .total_size = 1024,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
+ .tested = TEST_OK_PREW,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 16}, },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {1024 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .printlock = printlock_w39v080fa,
+ .unlock = unlock_w39v080fa,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* Also has 12V fast program */
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "W39V080FA (dual mode)",
+ .bustype = BUS_FWH,
+ .manufacture_id = WINBOND_ID,
+ .model_id = WINBOND_W39V080FA_DM,
+ .total_size = 512,
+ .page_size = 64 * 1024,
+ .feature_bits = FEATURE_REGISTERMAP | FEATURE_EITHER_RESET,
+ .tested = TEST_UNTESTED,
+ .probe = probe_jedec,
+ .probe_timing = 10,
+ .block_erasers =
+ {
+ {
+ .eraseblocks = { {64 * 1024, 8}, },
+ .block_erase = erase_sector_jedec,
+ }, {
+ .eraseblocks = { {512 * 1024, 1} },
+ .block_erase = erase_chip_block_jedec,
+ }
+ },
+ .printlock = printlock_w39v080fa_dual,
+ .write = write_jedec_1,
+ .read = read_memmapped,
+ .voltage = {3000, 3600}, /* Also has 12V fast program */
+ },
+
+ {
+ .vendor = "Unknown",
+ .name = "SFDP-capable chip",
+ .bustype = BUS_SPI,
+ .manufacture_id = GENERIC_MANUF_ID,
+ .model_id = SFDP_DEVICE_ID,
+ /* We present our own "report this" text hence we do not
+ * want the default "This flash part has status UNTESTED..."
+ * text to be printed. */
+ .tested = TEST_OK_PREW,
+ .probe = probe_spi_sfdp,
+ .unlock = spi_disable_blockprotect, /* is this safe? */
+ .read = spi_chip_read,
+ /* FIXME: some vendor extensions define this */
+ .voltage = {0},
+ /* Everything below will be set by the probing function. */
+ .write = NULL,
+ .total_size = 0,
+ .page_size = 0,
+ .feature_bits = 0,
+ .block_erasers = {},
+ },
+
+ {
+ .vendor = "Programmer",
+ .name = "Opaque flash chip",
+ .bustype = BUS_PROG,
+ .manufacture_id = PROGMANUF_ID,
+ .model_id = PROGDEV_ID,
+ .total_size = 0,
+ .page_size = 256,
+ /* probe is assumed to work, rest will be filled in by probe */
+ .tested = TEST_OK_PROBE,
+ .probe = probe_opaque,
+ /* eraseblock sizes will be set by the probing function */
+ .block_erasers =
+ {
+ {
+ .block_erase = erase_opaque,
+ }
+ },
+ .write = write_opaque,
+ .read = read_opaque,
+ },
+
+ {
+ .vendor = "AMIC",
+ .name = "unknown AMIC SPI chip",
+ .bustype = BUS_SPI,
+ .manufacture_id = AMIC_ID,
+ .model_id = GENERIC_DEVICE_ID,
+ .total_size = 0,
+ .page_size = 256,
+ .tested = TEST_BAD_PREW,
+ .probe = probe_spi_rdid4,
+ .probe_timing = TIMING_ZERO,
+ .write = NULL,
+ .read = NULL,
+ },
+
+ {
+ .vendor = "Atmel",
+ .name = "unknown Atmel SPI chip",
+ .bustype = BUS_SPI,
+ .manufacture_id = ATMEL_ID,
+ .model_id = GENERIC_DEVICE_ID,
+ .total_size = 0,
+ .page_size = 256,
+ .tested = TEST_BAD_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .write = NULL,
+ .read = NULL,
+ },
+
+ {
+ .vendor = "Eon",
+ .name = "unknown Eon SPI chip",
+ .bustype = BUS_SPI,
+ .manufacture_id = EON_ID_NOPREFIX,
+ .model_id = GENERIC_DEVICE_ID,
+ .total_size = 0,
+ .page_size = 256,
+ .tested = TEST_BAD_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .write = NULL,
+ .read = NULL,
+ },
+
+ {
+ .vendor = "Macronix",
+ .name = "unknown Macronix SPI chip",
+ .bustype = BUS_SPI,
+ .manufacture_id = MACRONIX_ID,
+ .model_id = GENERIC_DEVICE_ID,
+ .total_size = 0,
+ .page_size = 256,
+ .tested = TEST_BAD_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .write = NULL,
+ .read = NULL,
+ },
+
+ {
+ .vendor = "PMC",
+ .name = "unknown PMC SPI chip",
+ .bustype = BUS_SPI,
+ .manufacture_id = PMC_ID,
+ .model_id = GENERIC_DEVICE_ID,
+ .total_size = 0,
+ .page_size = 256,
+ .tested = TEST_BAD_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .write = NULL,
+ .read = NULL,
+ },
+
+ {
+ .vendor = "SST",
+ .name = "unknown SST SPI chip",
+ .bustype = BUS_SPI,
+ .manufacture_id = SST_ID,
+ .model_id = GENERIC_DEVICE_ID,
+ .total_size = 0,
+ .page_size = 256,
+ .tested = TEST_BAD_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .write = NULL,
+ .read = NULL,
+ },
+
+ {
+ .vendor = "ST",
+ .name = "unknown ST SPI chip",
+ .bustype = BUS_SPI,
+ .manufacture_id = ST_ID,
+ .model_id = GENERIC_DEVICE_ID,
+ .total_size = 0,
+ .page_size = 256,
+ .tested = TEST_BAD_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .write = NULL,
+ .read = NULL,
+ },
+
+ {
+ .vendor = "Sanyo",
+ .name = "unknown Sanyo SPI chip",
+ .bustype = BUS_SPI,
+ .manufacture_id = SANYO_ID,
+ .model_id = GENERIC_DEVICE_ID,
+ .total_size = 0,
+ .page_size = 256,
+ .tested = TEST_BAD_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .write = NULL,
+ .read = NULL,
+ },
+
+ {
+ .vendor = "Winbond",
+ .name = "unknown Winbond (ex Nexcom) SPI chip",
+ .bustype = BUS_SPI,
+ .manufacture_id = WINBOND_NEX_ID,
+ .model_id = GENERIC_DEVICE_ID,
+ .total_size = 0,
+ .page_size = 256,
+ .tested = TEST_BAD_PREW,
+ .probe = probe_spi_rdid,
+ .probe_timing = TIMING_ZERO,
+ .write = NULL,
+ .read = NULL,
+ },
+
+ {
+ .vendor = "Generic",
+ .name = "unknown SPI chip (RDID)",
+ .bustype = BUS_SPI,
+ .manufacture_id = GENERIC_MANUF_ID,
+ .model_id = GENERIC_DEVICE_ID,
+ .total_size = 0,
+ .page_size = 256,
+ .tested = TEST_BAD_PREW,
+ .probe = probe_spi_rdid,
+ .write = NULL,
+ },
+
+ {
+ .vendor = "Generic",
+ .name = "unknown SPI chip (REMS)",
+ .bustype = BUS_SPI,
+ .manufacture_id = GENERIC_MANUF_ID,
+ .model_id = GENERIC_DEVICE_ID,
+ .total_size = 0,
+ .page_size = 256,
+ .tested = TEST_BAD_PREW,
+ .probe = probe_spi_rems,
+ .write = NULL,
+ },
+
+ {0}
+};
+
+const unsigned int flashchips_size = ARRAY_SIZE(flashchips);
diff --git a/resources/grub/background/COPYING b/resources/grub/background/COPYING
new file mode 100644
index 0000000..176839e
--- /dev/null
+++ b/resources/grub/background/COPYING
@@ -0,0 +1,3 @@
+background1024x768.png is based on https://www.gnu.org/graphics/meditate.xcf.gz
+which can be found at https://www.gnu.org/graphics/meditate.html
+Check that webpage for licensing information to see what conditions the image falls under.
diff --git a/resources/grub/background/background1024x768.png b/resources/grub/background/background1024x768.png
new file mode 100644
index 0000000..ae13024
--- /dev/null
+++ b/resources/grub/background/background1024x768.png
Binary files differ
diff --git a/resources/grub/config/COPYING b/resources/grub/config/COPYING
new file mode 100644
index 0000000..624c22d
--- /dev/null
+++ b/resources/grub/config/COPYING
@@ -0,0 +1,33 @@
+The following files inside this directory:
+
+ * grub_memdisk.cfg
+ * macbook21/grub.cfg
+ * macbook21/grub_dvorak.cfg
+ * macbook21/grub_ukdvorak.cfg
+ * macbook21/grub_ukqwerty.cfg
+ * t60/grub.cfg
+ * t60/grub_dvorak.cfg
+ * t60/grub_ukdvorak.cfg
+ * t60/grub_ukqwerty.cfg
+ * t60/grub_serial.cfg
+ * t60/grub_serial_dvorak.cfg
+ * t60/grub_serial_ukdvorak.cfg
+ * t60/grub_serial_ukqwerty.cfg
+ * x60/grub.cfg
+ * x60/grub_dvorak.cfg
+ * x60/grub_ukdvorak.cfg
+ * x60/grub_ukqwerty.cfg
+ * x60/grub_serial.cfg
+ * x60/grub_serial_dvorak.cfg
+ * x60/grub_serial_ukdvorak.cfg
+ * x60/grub_serial_ukqwerty.cfg
+ * x60t/grub.cfg
+ * x60t/grub_dvorak.cfg
+ * x60t/grub_ukdvorak.cfg
+ * x60t/grub_ukqwerty.cfg
+ * x60t/grub_serial.cfg
+ * x60t/grub_serial_dvorak.cfg
+ * x60t/grub_serial_ukdvorak.cfg
+ * x60t/grub_serial_ukqwerty.cfg
+
+Look inside each file for copyright information
diff --git a/resources/grub/config/grub_memdisk.cfg b/resources/grub/config/grub_memdisk.cfg
new file mode 100644
index 0000000..fbac687
--- /dev/null
+++ b/resources/grub/config/grub_memdisk.cfg
@@ -0,0 +1,29 @@
+#
+# configuration file for GRUB memdisk which sits inside the grub.elf payload included inside the ROM image
+#
+# Copyright (C) 2014 Francis Rowe
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# Serial and keyboard configuration, very important.
+serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1
+terminal_input --append serial
+terminal_output --append serial
+terminal_input --append at_keyboard #add keyboard support.
+
+set prefix=(memdisk)/boot/grub
+
+set root='cbfsdisk'
+source (cbfsdisk)/grub.cfg
diff --git a/resources/grub/config/macbook21/grub.cfg b/resources/grub/config/macbook21/grub.cfg
new file mode 100644
index 0000000..8fc4100
--- /dev/null
+++ b/resources/grub/config/macbook21/grub.cfg
@@ -0,0 +1,57 @@
+#
+# GRUB configuration file which sits inside the root CBFS (coreboot filesystem)
+#
+# Copyright (C) 2014 Francis Rowe
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+set default="0"
+set timeout=1
+set pager=1
+
+keymap usqwerty
+background_image (cbfsdisk)/background.png
+loadfont (cbfsdisk)/dejavusansmono.pf2
+
+menuentry 'Load Operating System' {
+ linux (ahci0,1)/vmlinuz root=/dev/sda1
+ initrd (ahci0,1)/initrd.img
+}
+menuentry 'Parse ISOLINUX menu (USB)' {
+ set root='usb0'
+ syslinux_configfile -i (usb0)/isolinux/isolinux.cfg
+}
+menuentry 'Search for GRUB configuration on internal storage' {
+ insmod regexp
+ insmod ahci
+ insmod part_msdos
+ for x in (ahci0,*) ; do
+ if [ -f "$x/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /grub/grub.cfg
+ unset superusers
+ }
+ fi
+ if [ -f "$x/boot/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /boot/grub/grub.cfg
+ unset superusers
+ }
+ fi
+ done
+}
+
diff --git a/resources/grub/config/macbook21/grub_dvorak.cfg b/resources/grub/config/macbook21/grub_dvorak.cfg
new file mode 100644
index 0000000..52d12e5
--- /dev/null
+++ b/resources/grub/config/macbook21/grub_dvorak.cfg
@@ -0,0 +1,57 @@
+#
+# GRUB configuration file which sits inside the root CBFS (coreboot filesystem)
+#
+# Copyright (C) 2014 Francis Rowe
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+set default="0"
+set timeout=1
+set pager=1
+
+keymap dvorak
+background_image (cbfsdisk)/background.png
+loadfont (cbfsdisk)/dejavusansmono.pf2
+
+menuentry 'Load Operating System' {
+ linux (ahci0,1)/vmlinuz root=/dev/sda1
+ initrd (ahci0,1)/initrd.img
+}
+menuentry 'Parse ISOLINUX menu (USB)' {
+ set root='usb0'
+ syslinux_configfile -i (usb0)/isolinux/isolinux.cfg
+}
+menuentry 'Search for GRUB configuration on internal storage' {
+ insmod regexp
+ insmod ahci
+ insmod part_msdos
+ for x in (ahci0,*) ; do
+ if [ -f "$x/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /grub/grub.cfg
+ unset superusers
+ }
+ fi
+ if [ -f "$x/boot/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /boot/grub/grub.cfg
+ unset superusers
+ }
+ fi
+ done
+}
+
diff --git a/resources/grub/config/macbook21/grub_ukdvorak.cfg b/resources/grub/config/macbook21/grub_ukdvorak.cfg
new file mode 100644
index 0000000..b2075d8
--- /dev/null
+++ b/resources/grub/config/macbook21/grub_ukdvorak.cfg
@@ -0,0 +1,57 @@
+#
+# GRUB configuration file which sits inside the root CBFS (coreboot filesystem)
+#
+# Copyright (C) 2014 Francis Rowe
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+set default="0"
+set timeout=1
+set pager=1
+
+keymap ukdvorak
+background_image (cbfsdisk)/background.png
+loadfont (cbfsdisk)/dejavusansmono.pf2
+
+menuentry 'Load Operating System' {
+ linux (ahci0,1)/vmlinuz root=/dev/sda1
+ initrd (ahci0,1)/initrd.img
+}
+menuentry 'Parse ISOLINUX menu (USB)' {
+ set root='usb0'
+ syslinux_configfile -i (usb0)/isolinux/isolinux.cfg
+}
+menuentry 'Search for GRUB configuration on internal storage' {
+ insmod regexp
+ insmod ahci
+ insmod part_msdos
+ for x in (ahci0,*) ; do
+ if [ -f "$x/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /grub/grub.cfg
+ unset superusers
+ }
+ fi
+ if [ -f "$x/boot/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /boot/grub/grub.cfg
+ unset superusers
+ }
+ fi
+ done
+}
+
diff --git a/resources/grub/config/macbook21/grub_ukqwerty.cfg b/resources/grub/config/macbook21/grub_ukqwerty.cfg
new file mode 100644
index 0000000..b853242
--- /dev/null
+++ b/resources/grub/config/macbook21/grub_ukqwerty.cfg
@@ -0,0 +1,57 @@
+#
+# GRUB configuration file which sits inside the root CBFS (coreboot filesystem)
+#
+# Copyright (C) 2014 Francis Rowe
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+set default="0"
+set timeout=1
+set pager=1
+
+keymap ukqwerty
+background_image (cbfsdisk)/background.png
+loadfont (cbfsdisk)/dejavusansmono.pf2
+
+menuentry 'Load Operating System' {
+ linux (ahci0,1)/vmlinuz root=/dev/sda1
+ initrd (ahci0,1)/initrd.img
+}
+menuentry 'Parse ISOLINUX menu (USB)' {
+ set root='usb0'
+ syslinux_configfile -i (usb0)/isolinux/isolinux.cfg
+}
+menuentry 'Search for GRUB configuration on internal storage' {
+ insmod regexp
+ insmod ahci
+ insmod part_msdos
+ for x in (ahci0,*) ; do
+ if [ -f "$x/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /grub/grub.cfg
+ unset superusers
+ }
+ fi
+ if [ -f "$x/boot/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /boot/grub/grub.cfg
+ unset superusers
+ }
+ fi
+ done
+}
+
diff --git a/resources/grub/config/t60/grub.cfg b/resources/grub/config/t60/grub.cfg
new file mode 100644
index 0000000..2c34f8f
--- /dev/null
+++ b/resources/grub/config/t60/grub.cfg
@@ -0,0 +1,61 @@
+#
+# GRUB configuration file which sits inside the root CBFS (coreboot filesystem)
+#
+# Copyright (C) 2014 Francis Rowe
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+set default="0"
+set timeout=1
+set pager=1
+
+keymap usqwerty
+background_image (cbfsdisk)/background.png
+loadfont (cbfsdisk)/dejavusansmono.pf2
+
+menuentry 'Load Operating System' {
+ linux (ahci0,1)/vmlinuz root=/dev/sda1
+ initrd (ahci0,1)/initrd.img
+}
+menuentry 'Parse ISOLINUX menu (USB)' {
+ set root='usb0'
+ syslinux_configfile -i (usb0)/isolinux/isolinux.cfg
+}
+menuentry 'Parse ISOLINUX menu (CD)' {
+ set root='ata0'
+ syslinux_configfile -i (ata0)/isolinux/isolinux.cfg
+}
+menuentry 'Search for GRUB configuration on internal storage' {
+ insmod regexp
+ insmod ahci
+ insmod part_msdos
+ for x in (ahci0,*) ; do
+ if [ -f "$x/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /grub/grub.cfg
+ unset superusers
+ }
+ fi
+ if [ -f "$x/boot/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /boot/grub/grub.cfg
+ unset superusers
+ }
+ fi
+ done
+}
+
diff --git a/resources/grub/config/t60/grub_dvorak.cfg b/resources/grub/config/t60/grub_dvorak.cfg
new file mode 100644
index 0000000..eeb4a97
--- /dev/null
+++ b/resources/grub/config/t60/grub_dvorak.cfg
@@ -0,0 +1,61 @@
+#
+# GRUB configuration file which sits inside the root CBFS (coreboot filesystem)
+#
+# Copyright (C) 2014 Francis Rowe
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+set default="0"
+set timeout=1
+set pager=1
+
+keymap dvorak
+background_image (cbfsdisk)/background.png
+loadfont (cbfsdisk)/dejavusansmono.pf2
+
+menuentry 'Load Operating System' {
+ linux (ahci0,1)/vmlinuz root=/dev/sda1
+ initrd (ahci0,1)/initrd.img
+}
+menuentry 'Parse ISOLINUX menu (USB)' {
+ set root='usb0'
+ syslinux_configfile -i (usb0)/isolinux/isolinux.cfg
+}
+menuentry 'Parse ISOLINUX menu (CD)' {
+ set root='ata0'
+ syslinux_configfile -i (ata0)/isolinux/isolinux.cfg
+}
+menuentry 'Search for GRUB configuration on internal storage' {
+ insmod regexp
+ insmod ahci
+ insmod part_msdos
+ for x in (ahci0,*) ; do
+ if [ -f "$x/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /grub/grub.cfg
+ unset superusers
+ }
+ fi
+ if [ -f "$x/boot/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /boot/grub/grub.cfg
+ unset superusers
+ }
+ fi
+ done
+}
+
diff --git a/resources/grub/config/t60/grub_serial.cfg b/resources/grub/config/t60/grub_serial.cfg
new file mode 100644
index 0000000..bd33753
--- /dev/null
+++ b/resources/grub/config/t60/grub_serial.cfg
@@ -0,0 +1,71 @@
+#
+# GRUB configuration file which sits inside the root CBFS (coreboot filesystem)
+#
+# Copyright (C) 2014 Francis Rowe
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# Serial and keyboard configuration, very important.
+serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1
+terminal_input --append serial
+terminal_output --append serial
+terminal_input --append at_keyboard #add keyboard support.
+
+set default="0"
+set timeout=1
+set pager=1
+
+keymap usqwerty
+background_image (cbfsdisk)/background.png
+loadfont (cbfsdisk)/dejavusansmono.pf2
+
+menuentry 'Load Operating System' {
+ linux (ahci0,1)/vmlinuz root=/dev/sda1
+ initrd (ahci0,1)/initrd.img
+}
+menuentry 'Parse ISOLINUX menu (USB)' {
+ set root='usb0'
+ syslinux_configfile -i (usb0)/isolinux/isolinux.cfg
+}
+menuentry 'Parse ISOLINUX menu (CD)' {
+ set root='ata0'
+ syslinux_configfile -i (ata0)/isolinux/isolinux.cfg
+}
+menuentry 'Load MemTest86+ (serial port, baud 115200)' {
+ set root='cbfsdisk'
+ chainloader /memtest
+}
+menuentry 'Search for GRUB configuration on internal storage' {
+ insmod regexp
+ insmod ahci
+ insmod part_msdos
+ for x in (ahci0,*) ; do
+ if [ -f "$x/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /grub/grub.cfg
+ unset superusers
+ }
+ fi
+ if [ -f "$x/boot/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /boot/grub/grub.cfg
+ unset superusers
+ }
+ fi
+ done
+}
+
diff --git a/resources/grub/config/t60/grub_serial_dvorak.cfg b/resources/grub/config/t60/grub_serial_dvorak.cfg
new file mode 100644
index 0000000..6d49318
--- /dev/null
+++ b/resources/grub/config/t60/grub_serial_dvorak.cfg
@@ -0,0 +1,71 @@
+#
+# GRUB configuration file which sits inside the root CBFS (coreboot filesystem)
+#
+# Copyright (C) 2014 Francis Rowe
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# Serial and keyboard configuration, very important.
+serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1
+terminal_input --append serial
+terminal_output --append serial
+terminal_input --append at_keyboard #add keyboard support.
+
+set default="0"
+set timeout=1
+set pager=1
+
+keymap dvorak
+background_image (cbfsdisk)/background.png
+loadfont (cbfsdisk)/dejavusansmono.pf2
+
+menuentry 'Load Operating System' {
+ linux (ahci0,1)/vmlinuz root=/dev/sda1
+ initrd (ahci0,1)/initrd.img
+}
+menuentry 'Parse ISOLINUX menu (USB)' {
+ set root='usb0'
+ syslinux_configfile -i (usb0)/isolinux/isolinux.cfg
+}
+menuentry 'Parse ISOLINUX menu (CD)' {
+ set root='ata0'
+ syslinux_configfile -i (ata0)/isolinux/isolinux.cfg
+}
+menuentry 'Load MemTest86+ (serial port, baud 115200)' {
+ set root='cbfsdisk'
+ chainloader /memtest
+}
+menuentry 'Search for GRUB configuration on internal storage' {
+ insmod regexp
+ insmod ahci
+ insmod part_msdos
+ for x in (ahci0,*) ; do
+ if [ -f "$x/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /grub/grub.cfg
+ unset superusers
+ }
+ fi
+ if [ -f "$x/boot/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /boot/grub/grub.cfg
+ unset superusers
+ }
+ fi
+ done
+}
+
diff --git a/resources/grub/config/t60/grub_serial_ukdvorak.cfg b/resources/grub/config/t60/grub_serial_ukdvorak.cfg
new file mode 100644
index 0000000..e52fec5
--- /dev/null
+++ b/resources/grub/config/t60/grub_serial_ukdvorak.cfg
@@ -0,0 +1,71 @@
+#
+# GRUB configuration file which sits inside the root CBFS (coreboot filesystem)
+#
+# Copyright (C) 2014 Francis Rowe
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# Serial and keyboard configuration, very important.
+serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1
+terminal_input --append serial
+terminal_output --append serial
+terminal_input --append at_keyboard #add keyboard support.
+
+set default="0"
+set timeout=1
+set pager=1
+
+keymap ukdvorak
+background_image (cbfsdisk)/background.png
+loadfont (cbfsdisk)/dejavusansmono.pf2
+
+menuentry 'Load Operating System' {
+ linux (ahci0,1)/vmlinuz root=/dev/sda1
+ initrd (ahci0,1)/initrd.img
+}
+menuentry 'Parse ISOLINUX menu (USB)' {
+ set root='usb0'
+ syslinux_configfile -i (usb0)/isolinux/isolinux.cfg
+}
+menuentry 'Parse ISOLINUX menu (CD)' {
+ set root='ata0'
+ syslinux_configfile -i (ata0)/isolinux/isolinux.cfg
+}
+menuentry 'Load MemTest86+ (serial port, baud 115200)' {
+ set root='cbfsdisk'
+ chainloader /memtest
+}
+menuentry 'Search for GRUB configuration on internal storage' {
+ insmod regexp
+ insmod ahci
+ insmod part_msdos
+ for x in (ahci0,*) ; do
+ if [ -f "$x/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /grub/grub.cfg
+ unset superusers
+ }
+ fi
+ if [ -f "$x/boot/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /boot/grub/grub.cfg
+ unset superusers
+ }
+ fi
+ done
+}
+
diff --git a/resources/grub/config/t60/grub_serial_ukqwerty.cfg b/resources/grub/config/t60/grub_serial_ukqwerty.cfg
new file mode 100644
index 0000000..63aeafe
--- /dev/null
+++ b/resources/grub/config/t60/grub_serial_ukqwerty.cfg
@@ -0,0 +1,71 @@
+#
+# GRUB configuration file which sits inside the root CBFS (coreboot filesystem)
+#
+# Copyright (C) 2014 Francis Rowe
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# Serial and keyboard configuration, very important.
+serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1
+terminal_input --append serial
+terminal_output --append serial
+terminal_input --append at_keyboard #add keyboard support.
+
+set default="0"
+set timeout=1
+set pager=1
+
+keymap ukqwerty
+background_image (cbfsdisk)/background.png
+loadfont (cbfsdisk)/dejavusansmono.pf2
+
+menuentry 'Load Operating System' {
+ linux (ahci0,1)/vmlinuz root=/dev/sda1
+ initrd (ahci0,1)/initrd.img
+}
+menuentry 'Parse ISOLINUX menu (USB)' {
+ set root='usb0'
+ syslinux_configfile -i (usb0)/isolinux/isolinux.cfg
+}
+menuentry 'Parse ISOLINUX menu (CD)' {
+ set root='ata0'
+ syslinux_configfile -i (ata0)/isolinux/isolinux.cfg
+}
+menuentry 'Load MemTest86+ (serial port, baud 115200)' {
+ set root='cbfsdisk'
+ chainloader /memtest
+}
+menuentry 'Search for GRUB configuration on internal storage' {
+ insmod regexp
+ insmod ahci
+ insmod part_msdos
+ for x in (ahci0,*) ; do
+ if [ -f "$x/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /grub/grub.cfg
+ unset superusers
+ }
+ fi
+ if [ -f "$x/boot/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /boot/grub/grub.cfg
+ unset superusers
+ }
+ fi
+ done
+}
+
diff --git a/resources/grub/config/t60/grub_ukdvorak.cfg b/resources/grub/config/t60/grub_ukdvorak.cfg
new file mode 100644
index 0000000..b7c572d
--- /dev/null
+++ b/resources/grub/config/t60/grub_ukdvorak.cfg
@@ -0,0 +1,61 @@
+#
+# GRUB configuration file which sits inside the root CBFS (coreboot filesystem)
+#
+# Copyright (C) 2014 Francis Rowe
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+set default="0"
+set timeout=1
+set pager=1
+
+keymap ukdvorak
+background_image (cbfsdisk)/background.png
+loadfont (cbfsdisk)/dejavusansmono.pf2
+
+menuentry 'Load Operating System' {
+ linux (ahci0,1)/vmlinuz root=/dev/sda1
+ initrd (ahci0,1)/initrd.img
+}
+menuentry 'Parse ISOLINUX menu (USB)' {
+ set root='usb0'
+ syslinux_configfile -i (usb0)/isolinux/isolinux.cfg
+}
+menuentry 'Parse ISOLINUX menu (CD)' {
+ set root='ata0'
+ syslinux_configfile -i (ata0)/isolinux/isolinux.cfg
+}
+menuentry 'Search for GRUB configuration on internal storage' {
+ insmod regexp
+ insmod ahci
+ insmod part_msdos
+ for x in (ahci0,*) ; do
+ if [ -f "$x/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /grub/grub.cfg
+ unset superusers
+ }
+ fi
+ if [ -f "$x/boot/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /boot/grub/grub.cfg
+ unset superusers
+ }
+ fi
+ done
+}
+
diff --git a/resources/grub/config/t60/grub_ukqwerty.cfg b/resources/grub/config/t60/grub_ukqwerty.cfg
new file mode 100644
index 0000000..e754843
--- /dev/null
+++ b/resources/grub/config/t60/grub_ukqwerty.cfg
@@ -0,0 +1,61 @@
+#
+# GRUB configuration file which sits inside the root CBFS (coreboot filesystem)
+#
+# Copyright (C) 2014 Francis Rowe
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+set default="0"
+set timeout=1
+set pager=1
+
+keymap ukqwerty
+background_image (cbfsdisk)/background.png
+loadfont (cbfsdisk)/dejavusansmono.pf2
+
+menuentry 'Load Operating System' {
+ linux (ahci0,1)/vmlinuz root=/dev/sda1
+ initrd (ahci0,1)/initrd.img
+}
+menuentry 'Parse ISOLINUX menu (USB)' {
+ set root='usb0'
+ syslinux_configfile -i (usb0)/isolinux/isolinux.cfg
+}
+menuentry 'Parse ISOLINUX menu (CD)' {
+ set root='ata0'
+ syslinux_configfile -i (ata0)/isolinux/isolinux.cfg
+}
+menuentry 'Search for GRUB configuration on internal storage' {
+ insmod regexp
+ insmod ahci
+ insmod part_msdos
+ for x in (ahci0,*) ; do
+ if [ -f "$x/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /grub/grub.cfg
+ unset superusers
+ }
+ fi
+ if [ -f "$x/boot/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /boot/grub/grub.cfg
+ unset superusers
+ }
+ fi
+ done
+}
+
diff --git a/resources/grub/config/x60/grub.cfg b/resources/grub/config/x60/grub.cfg
new file mode 100644
index 0000000..8fc4100
--- /dev/null
+++ b/resources/grub/config/x60/grub.cfg
@@ -0,0 +1,57 @@
+#
+# GRUB configuration file which sits inside the root CBFS (coreboot filesystem)
+#
+# Copyright (C) 2014 Francis Rowe
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+set default="0"
+set timeout=1
+set pager=1
+
+keymap usqwerty
+background_image (cbfsdisk)/background.png
+loadfont (cbfsdisk)/dejavusansmono.pf2
+
+menuentry 'Load Operating System' {
+ linux (ahci0,1)/vmlinuz root=/dev/sda1
+ initrd (ahci0,1)/initrd.img
+}
+menuentry 'Parse ISOLINUX menu (USB)' {
+ set root='usb0'
+ syslinux_configfile -i (usb0)/isolinux/isolinux.cfg
+}
+menuentry 'Search for GRUB configuration on internal storage' {
+ insmod regexp
+ insmod ahci
+ insmod part_msdos
+ for x in (ahci0,*) ; do
+ if [ -f "$x/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /grub/grub.cfg
+ unset superusers
+ }
+ fi
+ if [ -f "$x/boot/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /boot/grub/grub.cfg
+ unset superusers
+ }
+ fi
+ done
+}
+
diff --git a/resources/grub/config/x60/grub_dvorak.cfg b/resources/grub/config/x60/grub_dvorak.cfg
new file mode 100644
index 0000000..52d12e5
--- /dev/null
+++ b/resources/grub/config/x60/grub_dvorak.cfg
@@ -0,0 +1,57 @@
+#
+# GRUB configuration file which sits inside the root CBFS (coreboot filesystem)
+#
+# Copyright (C) 2014 Francis Rowe
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+set default="0"
+set timeout=1
+set pager=1
+
+keymap dvorak
+background_image (cbfsdisk)/background.png
+loadfont (cbfsdisk)/dejavusansmono.pf2
+
+menuentry 'Load Operating System' {
+ linux (ahci0,1)/vmlinuz root=/dev/sda1
+ initrd (ahci0,1)/initrd.img
+}
+menuentry 'Parse ISOLINUX menu (USB)' {
+ set root='usb0'
+ syslinux_configfile -i (usb0)/isolinux/isolinux.cfg
+}
+menuentry 'Search for GRUB configuration on internal storage' {
+ insmod regexp
+ insmod ahci
+ insmod part_msdos
+ for x in (ahci0,*) ; do
+ if [ -f "$x/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /grub/grub.cfg
+ unset superusers
+ }
+ fi
+ if [ -f "$x/boot/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /boot/grub/grub.cfg
+ unset superusers
+ }
+ fi
+ done
+}
+
diff --git a/resources/grub/config/x60/grub_serial.cfg b/resources/grub/config/x60/grub_serial.cfg
new file mode 100644
index 0000000..bd33753
--- /dev/null
+++ b/resources/grub/config/x60/grub_serial.cfg
@@ -0,0 +1,71 @@
+#
+# GRUB configuration file which sits inside the root CBFS (coreboot filesystem)
+#
+# Copyright (C) 2014 Francis Rowe
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# Serial and keyboard configuration, very important.
+serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1
+terminal_input --append serial
+terminal_output --append serial
+terminal_input --append at_keyboard #add keyboard support.
+
+set default="0"
+set timeout=1
+set pager=1
+
+keymap usqwerty
+background_image (cbfsdisk)/background.png
+loadfont (cbfsdisk)/dejavusansmono.pf2
+
+menuentry 'Load Operating System' {
+ linux (ahci0,1)/vmlinuz root=/dev/sda1
+ initrd (ahci0,1)/initrd.img
+}
+menuentry 'Parse ISOLINUX menu (USB)' {
+ set root='usb0'
+ syslinux_configfile -i (usb0)/isolinux/isolinux.cfg
+}
+menuentry 'Parse ISOLINUX menu (CD)' {
+ set root='ata0'
+ syslinux_configfile -i (ata0)/isolinux/isolinux.cfg
+}
+menuentry 'Load MemTest86+ (serial port, baud 115200)' {
+ set root='cbfsdisk'
+ chainloader /memtest
+}
+menuentry 'Search for GRUB configuration on internal storage' {
+ insmod regexp
+ insmod ahci
+ insmod part_msdos
+ for x in (ahci0,*) ; do
+ if [ -f "$x/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /grub/grub.cfg
+ unset superusers
+ }
+ fi
+ if [ -f "$x/boot/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /boot/grub/grub.cfg
+ unset superusers
+ }
+ fi
+ done
+}
+
diff --git a/resources/grub/config/x60/grub_serial_dvorak.cfg b/resources/grub/config/x60/grub_serial_dvorak.cfg
new file mode 100644
index 0000000..6d49318
--- /dev/null
+++ b/resources/grub/config/x60/grub_serial_dvorak.cfg
@@ -0,0 +1,71 @@
+#
+# GRUB configuration file which sits inside the root CBFS (coreboot filesystem)
+#
+# Copyright (C) 2014 Francis Rowe
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# Serial and keyboard configuration, very important.
+serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1
+terminal_input --append serial
+terminal_output --append serial
+terminal_input --append at_keyboard #add keyboard support.
+
+set default="0"
+set timeout=1
+set pager=1
+
+keymap dvorak
+background_image (cbfsdisk)/background.png
+loadfont (cbfsdisk)/dejavusansmono.pf2
+
+menuentry 'Load Operating System' {
+ linux (ahci0,1)/vmlinuz root=/dev/sda1
+ initrd (ahci0,1)/initrd.img
+}
+menuentry 'Parse ISOLINUX menu (USB)' {
+ set root='usb0'
+ syslinux_configfile -i (usb0)/isolinux/isolinux.cfg
+}
+menuentry 'Parse ISOLINUX menu (CD)' {
+ set root='ata0'
+ syslinux_configfile -i (ata0)/isolinux/isolinux.cfg
+}
+menuentry 'Load MemTest86+ (serial port, baud 115200)' {
+ set root='cbfsdisk'
+ chainloader /memtest
+}
+menuentry 'Search for GRUB configuration on internal storage' {
+ insmod regexp
+ insmod ahci
+ insmod part_msdos
+ for x in (ahci0,*) ; do
+ if [ -f "$x/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /grub/grub.cfg
+ unset superusers
+ }
+ fi
+ if [ -f "$x/boot/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /boot/grub/grub.cfg
+ unset superusers
+ }
+ fi
+ done
+}
+
diff --git a/resources/grub/config/x60/grub_serial_ukdvorak.cfg b/resources/grub/config/x60/grub_serial_ukdvorak.cfg
new file mode 100644
index 0000000..e52fec5
--- /dev/null
+++ b/resources/grub/config/x60/grub_serial_ukdvorak.cfg
@@ -0,0 +1,71 @@
+#
+# GRUB configuration file which sits inside the root CBFS (coreboot filesystem)
+#
+# Copyright (C) 2014 Francis Rowe
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# Serial and keyboard configuration, very important.
+serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1
+terminal_input --append serial
+terminal_output --append serial
+terminal_input --append at_keyboard #add keyboard support.
+
+set default="0"
+set timeout=1
+set pager=1
+
+keymap ukdvorak
+background_image (cbfsdisk)/background.png
+loadfont (cbfsdisk)/dejavusansmono.pf2
+
+menuentry 'Load Operating System' {
+ linux (ahci0,1)/vmlinuz root=/dev/sda1
+ initrd (ahci0,1)/initrd.img
+}
+menuentry 'Parse ISOLINUX menu (USB)' {
+ set root='usb0'
+ syslinux_configfile -i (usb0)/isolinux/isolinux.cfg
+}
+menuentry 'Parse ISOLINUX menu (CD)' {
+ set root='ata0'
+ syslinux_configfile -i (ata0)/isolinux/isolinux.cfg
+}
+menuentry 'Load MemTest86+ (serial port, baud 115200)' {
+ set root='cbfsdisk'
+ chainloader /memtest
+}
+menuentry 'Search for GRUB configuration on internal storage' {
+ insmod regexp
+ insmod ahci
+ insmod part_msdos
+ for x in (ahci0,*) ; do
+ if [ -f "$x/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /grub/grub.cfg
+ unset superusers
+ }
+ fi
+ if [ -f "$x/boot/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /boot/grub/grub.cfg
+ unset superusers
+ }
+ fi
+ done
+}
+
diff --git a/resources/grub/config/x60/grub_serial_ukqwerty.cfg b/resources/grub/config/x60/grub_serial_ukqwerty.cfg
new file mode 100644
index 0000000..63aeafe
--- /dev/null
+++ b/resources/grub/config/x60/grub_serial_ukqwerty.cfg
@@ -0,0 +1,71 @@
+#
+# GRUB configuration file which sits inside the root CBFS (coreboot filesystem)
+#
+# Copyright (C) 2014 Francis Rowe
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# Serial and keyboard configuration, very important.
+serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1
+terminal_input --append serial
+terminal_output --append serial
+terminal_input --append at_keyboard #add keyboard support.
+
+set default="0"
+set timeout=1
+set pager=1
+
+keymap ukqwerty
+background_image (cbfsdisk)/background.png
+loadfont (cbfsdisk)/dejavusansmono.pf2
+
+menuentry 'Load Operating System' {
+ linux (ahci0,1)/vmlinuz root=/dev/sda1
+ initrd (ahci0,1)/initrd.img
+}
+menuentry 'Parse ISOLINUX menu (USB)' {
+ set root='usb0'
+ syslinux_configfile -i (usb0)/isolinux/isolinux.cfg
+}
+menuentry 'Parse ISOLINUX menu (CD)' {
+ set root='ata0'
+ syslinux_configfile -i (ata0)/isolinux/isolinux.cfg
+}
+menuentry 'Load MemTest86+ (serial port, baud 115200)' {
+ set root='cbfsdisk'
+ chainloader /memtest
+}
+menuentry 'Search for GRUB configuration on internal storage' {
+ insmod regexp
+ insmod ahci
+ insmod part_msdos
+ for x in (ahci0,*) ; do
+ if [ -f "$x/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /grub/grub.cfg
+ unset superusers
+ }
+ fi
+ if [ -f "$x/boot/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /boot/grub/grub.cfg
+ unset superusers
+ }
+ fi
+ done
+}
+
diff --git a/resources/grub/config/x60/grub_ukdvorak.cfg b/resources/grub/config/x60/grub_ukdvorak.cfg
new file mode 100644
index 0000000..b2075d8
--- /dev/null
+++ b/resources/grub/config/x60/grub_ukdvorak.cfg
@@ -0,0 +1,57 @@
+#
+# GRUB configuration file which sits inside the root CBFS (coreboot filesystem)
+#
+# Copyright (C) 2014 Francis Rowe
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+set default="0"
+set timeout=1
+set pager=1
+
+keymap ukdvorak
+background_image (cbfsdisk)/background.png
+loadfont (cbfsdisk)/dejavusansmono.pf2
+
+menuentry 'Load Operating System' {
+ linux (ahci0,1)/vmlinuz root=/dev/sda1
+ initrd (ahci0,1)/initrd.img
+}
+menuentry 'Parse ISOLINUX menu (USB)' {
+ set root='usb0'
+ syslinux_configfile -i (usb0)/isolinux/isolinux.cfg
+}
+menuentry 'Search for GRUB configuration on internal storage' {
+ insmod regexp
+ insmod ahci
+ insmod part_msdos
+ for x in (ahci0,*) ; do
+ if [ -f "$x/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /grub/grub.cfg
+ unset superusers
+ }
+ fi
+ if [ -f "$x/boot/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /boot/grub/grub.cfg
+ unset superusers
+ }
+ fi
+ done
+}
+
diff --git a/resources/grub/config/x60/grub_ukqwerty.cfg b/resources/grub/config/x60/grub_ukqwerty.cfg
new file mode 100644
index 0000000..b853242
--- /dev/null
+++ b/resources/grub/config/x60/grub_ukqwerty.cfg
@@ -0,0 +1,57 @@
+#
+# GRUB configuration file which sits inside the root CBFS (coreboot filesystem)
+#
+# Copyright (C) 2014 Francis Rowe
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+set default="0"
+set timeout=1
+set pager=1
+
+keymap ukqwerty
+background_image (cbfsdisk)/background.png
+loadfont (cbfsdisk)/dejavusansmono.pf2
+
+menuentry 'Load Operating System' {
+ linux (ahci0,1)/vmlinuz root=/dev/sda1
+ initrd (ahci0,1)/initrd.img
+}
+menuentry 'Parse ISOLINUX menu (USB)' {
+ set root='usb0'
+ syslinux_configfile -i (usb0)/isolinux/isolinux.cfg
+}
+menuentry 'Search for GRUB configuration on internal storage' {
+ insmod regexp
+ insmod ahci
+ insmod part_msdos
+ for x in (ahci0,*) ; do
+ if [ -f "$x/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /grub/grub.cfg
+ unset superusers
+ }
+ fi
+ if [ -f "$x/boot/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /boot/grub/grub.cfg
+ unset superusers
+ }
+ fi
+ done
+}
+
diff --git a/resources/grub/config/x60t/grub.cfg b/resources/grub/config/x60t/grub.cfg
new file mode 100644
index 0000000..8fc4100
--- /dev/null
+++ b/resources/grub/config/x60t/grub.cfg
@@ -0,0 +1,57 @@
+#
+# GRUB configuration file which sits inside the root CBFS (coreboot filesystem)
+#
+# Copyright (C) 2014 Francis Rowe
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+set default="0"
+set timeout=1
+set pager=1
+
+keymap usqwerty
+background_image (cbfsdisk)/background.png
+loadfont (cbfsdisk)/dejavusansmono.pf2
+
+menuentry 'Load Operating System' {
+ linux (ahci0,1)/vmlinuz root=/dev/sda1
+ initrd (ahci0,1)/initrd.img
+}
+menuentry 'Parse ISOLINUX menu (USB)' {
+ set root='usb0'
+ syslinux_configfile -i (usb0)/isolinux/isolinux.cfg
+}
+menuentry 'Search for GRUB configuration on internal storage' {
+ insmod regexp
+ insmod ahci
+ insmod part_msdos
+ for x in (ahci0,*) ; do
+ if [ -f "$x/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /grub/grub.cfg
+ unset superusers
+ }
+ fi
+ if [ -f "$x/boot/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /boot/grub/grub.cfg
+ unset superusers
+ }
+ fi
+ done
+}
+
diff --git a/resources/grub/config/x60t/grub_dvorak.cfg b/resources/grub/config/x60t/grub_dvorak.cfg
new file mode 100644
index 0000000..52d12e5
--- /dev/null
+++ b/resources/grub/config/x60t/grub_dvorak.cfg
@@ -0,0 +1,57 @@
+#
+# GRUB configuration file which sits inside the root CBFS (coreboot filesystem)
+#
+# Copyright (C) 2014 Francis Rowe
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+set default="0"
+set timeout=1
+set pager=1
+
+keymap dvorak
+background_image (cbfsdisk)/background.png
+loadfont (cbfsdisk)/dejavusansmono.pf2
+
+menuentry 'Load Operating System' {
+ linux (ahci0,1)/vmlinuz root=/dev/sda1
+ initrd (ahci0,1)/initrd.img
+}
+menuentry 'Parse ISOLINUX menu (USB)' {
+ set root='usb0'
+ syslinux_configfile -i (usb0)/isolinux/isolinux.cfg
+}
+menuentry 'Search for GRUB configuration on internal storage' {
+ insmod regexp
+ insmod ahci
+ insmod part_msdos
+ for x in (ahci0,*) ; do
+ if [ -f "$x/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /grub/grub.cfg
+ unset superusers
+ }
+ fi
+ if [ -f "$x/boot/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /boot/grub/grub.cfg
+ unset superusers
+ }
+ fi
+ done
+}
+
diff --git a/resources/grub/config/x60t/grub_serial.cfg b/resources/grub/config/x60t/grub_serial.cfg
new file mode 100644
index 0000000..bd33753
--- /dev/null
+++ b/resources/grub/config/x60t/grub_serial.cfg
@@ -0,0 +1,71 @@
+#
+# GRUB configuration file which sits inside the root CBFS (coreboot filesystem)
+#
+# Copyright (C) 2014 Francis Rowe
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# Serial and keyboard configuration, very important.
+serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1
+terminal_input --append serial
+terminal_output --append serial
+terminal_input --append at_keyboard #add keyboard support.
+
+set default="0"
+set timeout=1
+set pager=1
+
+keymap usqwerty
+background_image (cbfsdisk)/background.png
+loadfont (cbfsdisk)/dejavusansmono.pf2
+
+menuentry 'Load Operating System' {
+ linux (ahci0,1)/vmlinuz root=/dev/sda1
+ initrd (ahci0,1)/initrd.img
+}
+menuentry 'Parse ISOLINUX menu (USB)' {
+ set root='usb0'
+ syslinux_configfile -i (usb0)/isolinux/isolinux.cfg
+}
+menuentry 'Parse ISOLINUX menu (CD)' {
+ set root='ata0'
+ syslinux_configfile -i (ata0)/isolinux/isolinux.cfg
+}
+menuentry 'Load MemTest86+ (serial port, baud 115200)' {
+ set root='cbfsdisk'
+ chainloader /memtest
+}
+menuentry 'Search for GRUB configuration on internal storage' {
+ insmod regexp
+ insmod ahci
+ insmod part_msdos
+ for x in (ahci0,*) ; do
+ if [ -f "$x/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /grub/grub.cfg
+ unset superusers
+ }
+ fi
+ if [ -f "$x/boot/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /boot/grub/grub.cfg
+ unset superusers
+ }
+ fi
+ done
+}
+
diff --git a/resources/grub/config/x60t/grub_serial_dvorak.cfg b/resources/grub/config/x60t/grub_serial_dvorak.cfg
new file mode 100644
index 0000000..6d49318
--- /dev/null
+++ b/resources/grub/config/x60t/grub_serial_dvorak.cfg
@@ -0,0 +1,71 @@
+#
+# GRUB configuration file which sits inside the root CBFS (coreboot filesystem)
+#
+# Copyright (C) 2014 Francis Rowe
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# Serial and keyboard configuration, very important.
+serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1
+terminal_input --append serial
+terminal_output --append serial
+terminal_input --append at_keyboard #add keyboard support.
+
+set default="0"
+set timeout=1
+set pager=1
+
+keymap dvorak
+background_image (cbfsdisk)/background.png
+loadfont (cbfsdisk)/dejavusansmono.pf2
+
+menuentry 'Load Operating System' {
+ linux (ahci0,1)/vmlinuz root=/dev/sda1
+ initrd (ahci0,1)/initrd.img
+}
+menuentry 'Parse ISOLINUX menu (USB)' {
+ set root='usb0'
+ syslinux_configfile -i (usb0)/isolinux/isolinux.cfg
+}
+menuentry 'Parse ISOLINUX menu (CD)' {
+ set root='ata0'
+ syslinux_configfile -i (ata0)/isolinux/isolinux.cfg
+}
+menuentry 'Load MemTest86+ (serial port, baud 115200)' {
+ set root='cbfsdisk'
+ chainloader /memtest
+}
+menuentry 'Search for GRUB configuration on internal storage' {
+ insmod regexp
+ insmod ahci
+ insmod part_msdos
+ for x in (ahci0,*) ; do
+ if [ -f "$x/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /grub/grub.cfg
+ unset superusers
+ }
+ fi
+ if [ -f "$x/boot/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /boot/grub/grub.cfg
+ unset superusers
+ }
+ fi
+ done
+}
+
diff --git a/resources/grub/config/x60t/grub_serial_ukdvorak.cfg b/resources/grub/config/x60t/grub_serial_ukdvorak.cfg
new file mode 100644
index 0000000..e52fec5
--- /dev/null
+++ b/resources/grub/config/x60t/grub_serial_ukdvorak.cfg
@@ -0,0 +1,71 @@
+#
+# GRUB configuration file which sits inside the root CBFS (coreboot filesystem)
+#
+# Copyright (C) 2014 Francis Rowe
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# Serial and keyboard configuration, very important.
+serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1
+terminal_input --append serial
+terminal_output --append serial
+terminal_input --append at_keyboard #add keyboard support.
+
+set default="0"
+set timeout=1
+set pager=1
+
+keymap ukdvorak
+background_image (cbfsdisk)/background.png
+loadfont (cbfsdisk)/dejavusansmono.pf2
+
+menuentry 'Load Operating System' {
+ linux (ahci0,1)/vmlinuz root=/dev/sda1
+ initrd (ahci0,1)/initrd.img
+}
+menuentry 'Parse ISOLINUX menu (USB)' {
+ set root='usb0'
+ syslinux_configfile -i (usb0)/isolinux/isolinux.cfg
+}
+menuentry 'Parse ISOLINUX menu (CD)' {
+ set root='ata0'
+ syslinux_configfile -i (ata0)/isolinux/isolinux.cfg
+}
+menuentry 'Load MemTest86+ (serial port, baud 115200)' {
+ set root='cbfsdisk'
+ chainloader /memtest
+}
+menuentry 'Search for GRUB configuration on internal storage' {
+ insmod regexp
+ insmod ahci
+ insmod part_msdos
+ for x in (ahci0,*) ; do
+ if [ -f "$x/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /grub/grub.cfg
+ unset superusers
+ }
+ fi
+ if [ -f "$x/boot/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /boot/grub/grub.cfg
+ unset superusers
+ }
+ fi
+ done
+}
+
diff --git a/resources/grub/config/x60t/grub_serial_ukqwerty.cfg b/resources/grub/config/x60t/grub_serial_ukqwerty.cfg
new file mode 100644
index 0000000..63aeafe
--- /dev/null
+++ b/resources/grub/config/x60t/grub_serial_ukqwerty.cfg
@@ -0,0 +1,71 @@
+#
+# GRUB configuration file which sits inside the root CBFS (coreboot filesystem)
+#
+# Copyright (C) 2014 Francis Rowe
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# Serial and keyboard configuration, very important.
+serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1
+terminal_input --append serial
+terminal_output --append serial
+terminal_input --append at_keyboard #add keyboard support.
+
+set default="0"
+set timeout=1
+set pager=1
+
+keymap ukqwerty
+background_image (cbfsdisk)/background.png
+loadfont (cbfsdisk)/dejavusansmono.pf2
+
+menuentry 'Load Operating System' {
+ linux (ahci0,1)/vmlinuz root=/dev/sda1
+ initrd (ahci0,1)/initrd.img
+}
+menuentry 'Parse ISOLINUX menu (USB)' {
+ set root='usb0'
+ syslinux_configfile -i (usb0)/isolinux/isolinux.cfg
+}
+menuentry 'Parse ISOLINUX menu (CD)' {
+ set root='ata0'
+ syslinux_configfile -i (ata0)/isolinux/isolinux.cfg
+}
+menuentry 'Load MemTest86+ (serial port, baud 115200)' {
+ set root='cbfsdisk'
+ chainloader /memtest
+}
+menuentry 'Search for GRUB configuration on internal storage' {
+ insmod regexp
+ insmod ahci
+ insmod part_msdos
+ for x in (ahci0,*) ; do
+ if [ -f "$x/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /grub/grub.cfg
+ unset superusers
+ }
+ fi
+ if [ -f "$x/boot/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /boot/grub/grub.cfg
+ unset superusers
+ }
+ fi
+ done
+}
+
diff --git a/resources/grub/config/x60t/grub_ukdvorak.cfg b/resources/grub/config/x60t/grub_ukdvorak.cfg
new file mode 100644
index 0000000..b2075d8
--- /dev/null
+++ b/resources/grub/config/x60t/grub_ukdvorak.cfg
@@ -0,0 +1,57 @@
+#
+# GRUB configuration file which sits inside the root CBFS (coreboot filesystem)
+#
+# Copyright (C) 2014 Francis Rowe
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+set default="0"
+set timeout=1
+set pager=1
+
+keymap ukdvorak
+background_image (cbfsdisk)/background.png
+loadfont (cbfsdisk)/dejavusansmono.pf2
+
+menuentry 'Load Operating System' {
+ linux (ahci0,1)/vmlinuz root=/dev/sda1
+ initrd (ahci0,1)/initrd.img
+}
+menuentry 'Parse ISOLINUX menu (USB)' {
+ set root='usb0'
+ syslinux_configfile -i (usb0)/isolinux/isolinux.cfg
+}
+menuentry 'Search for GRUB configuration on internal storage' {
+ insmod regexp
+ insmod ahci
+ insmod part_msdos
+ for x in (ahci0,*) ; do
+ if [ -f "$x/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /grub/grub.cfg
+ unset superusers
+ }
+ fi
+ if [ -f "$x/boot/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /boot/grub/grub.cfg
+ unset superusers
+ }
+ fi
+ done
+}
+
diff --git a/resources/grub/config/x60t/grub_ukqwerty.cfg b/resources/grub/config/x60t/grub_ukqwerty.cfg
new file mode 100644
index 0000000..b853242
--- /dev/null
+++ b/resources/grub/config/x60t/grub_ukqwerty.cfg
@@ -0,0 +1,57 @@
+#
+# GRUB configuration file which sits inside the root CBFS (coreboot filesystem)
+#
+# Copyright (C) 2014 Francis Rowe
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+set default="0"
+set timeout=1
+set pager=1
+
+keymap ukqwerty
+background_image (cbfsdisk)/background.png
+loadfont (cbfsdisk)/dejavusansmono.pf2
+
+menuentry 'Load Operating System' {
+ linux (ahci0,1)/vmlinuz root=/dev/sda1
+ initrd (ahci0,1)/initrd.img
+}
+menuentry 'Parse ISOLINUX menu (USB)' {
+ set root='usb0'
+ syslinux_configfile -i (usb0)/isolinux/isolinux.cfg
+}
+menuentry 'Search for GRUB configuration on internal storage' {
+ insmod regexp
+ insmod ahci
+ insmod part_msdos
+ for x in (ahci0,*) ; do
+ if [ -f "$x/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /grub/grub.cfg
+ unset superusers
+ }
+ fi
+ if [ -f "$x/boot/grub/grub.cfg" ] ; then
+ submenu "Load Config from $x" $x {
+ root=$2
+ source /boot/grub/grub.cfg
+ unset superusers
+ }
+ fi
+ done
+}
+
diff --git a/resources/grub/font/COPYING b/resources/grub/font/COPYING
new file mode 100644
index 0000000..db00082
--- /dev/null
+++ b/resources/grub/font/COPYING
@@ -0,0 +1,3 @@
+dejavusansmono.pf2 is generated from "DeJavu Sans Mono" font.
+Check ../../../dejavu-fonts-ttf-2.34 for the copyright information of that project.
+(it's in libreboot_src if you downloaded the libreboot_bin archive. See ../../../docs/RELEASE.html to find where to get it)
diff --git a/resources/grub/font/dejavusansmono.pf2 b/resources/grub/font/dejavusansmono.pf2
new file mode 100644
index 0000000..9ba557e
--- /dev/null
+++ b/resources/grub/font/dejavusansmono.pf2
Binary files differ
diff --git a/resources/grub/keymap/COPYING b/resources/grub/keymap/COPYING
new file mode 100644
index 0000000..1a47bfa
--- /dev/null
+++ b/resources/grub/keymap/COPYING
@@ -0,0 +1,13 @@
+Look at ../../../docs/index.html under the "GRUB2 payload" section to see
+how the following files were generated:
+
+ * dvorak.gkb
+ * ukdvorak
+ * ukdvorak.gkb
+ * ukqwerty
+ * ukqwerty.gkb
+ * usdvorak
+ * usqwerty
+ * usqwerty.gkb
+
+The files listed above are made available in the public domain (the information in them is public knowledge. copyright is pointless). Use them as you wish.
diff --git a/resources/grub/keymap/dvorak.gkb b/resources/grub/keymap/dvorak.gkb
new file mode 100644
index 0000000..41301ef
--- /dev/null
+++ b/resources/grub/keymap/dvorak.gkb
Binary files differ
diff --git a/resources/grub/keymap/ukdvorak b/resources/grub/keymap/ukdvorak
new file mode 100644
index 0000000..d41b873
--- /dev/null
+++ b/resources/grub/keymap/ukdvorak
@@ -0,0 +1,130 @@
+keymaps 0-127
+keycode 1 = Escape Escape Escape Escape Escape Escape Escape Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Escape Escape Escape Escape Escape Escape Escape Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Escape Escape Escape Escape Escape Escape Escape Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Escape Escape Escape Escape Escape Escape Escape Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Escape Escape Escape Escape Escape Escape Escape Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Escape Escape Escape Escape Escape Escape Escape Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Escape Escape Escape Escape Escape Escape Escape Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Escape Escape Escape Escape Escape Escape Escape Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape
+keycode 2 = U+0031 U+0021 U+0031 U+0031 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_one Meta_exclam Meta_one Meta_one VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0031 U+0021 U+0031 U+0031 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_one Meta_exclam Meta_one Meta_one VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0031 U+0021 U+0031 U+0031 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_one Meta_exclam Meta_one Meta_one VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0031 U+0021 U+0031 U+0031 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_one Meta_exclam Meta_one Meta_one VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0031 U+0021 U+0031 U+0031 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_one Meta_exclam Meta_one Meta_one VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0031 U+0021 U+0031 U+0031 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_one Meta_exclam Meta_one Meta_one VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0031 U+0021 U+0031 U+0031 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_one Meta_exclam Meta_one Meta_one VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0031 U+0021 U+0031 U+0031 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_one Meta_exclam Meta_one Meta_one VoidSymbol VoidSymbol VoidSymbol VoidSymbol
+keycode 3 = U+0032 U+0022 U+0032 U+0032 nul nul nul nul Meta_two Meta_at Meta_two Meta_two Meta_nul Meta_nul Meta_nul Meta_nul U+0032 U+0040 U+0032 U+0032 nul nul nul nul Meta_two Meta_at Meta_two Meta_two Meta_nul Meta_nul Meta_nul Meta_nul U+0032 U+0022 U+0032 U+0032 nul nul nul nul Meta_two Meta_at Meta_two Meta_two Meta_nul Meta_nul Meta_nul Meta_nul U+0032 U+0022 U+0032 U+0032 nul nul nul nul Meta_two Meta_at Meta_two Meta_two Meta_nul Meta_nul Meta_nul Meta_nul U+0032 U+0022 U+0032 U+0032 nul nul nul nul Meta_two Meta_at Meta_two Meta_two Meta_nul Meta_nul Meta_nul Meta_nul U+0032 U+0022 U+0032 U+0032 nul nul nul nul Meta_two Meta_at Meta_two Meta_two Meta_nul Meta_nul Meta_nul Meta_nul U+0032 U+0022 U+0032 U+0032 nul nul nul nul Meta_two Meta_at Meta_two Meta_two Meta_nul Meta_nul Meta_nul Meta_nul U+0032 U+0022 U+0032 U+0032 nul nul nul nul Meta_two Meta_at Meta_two Meta_two Meta_nul Meta_nul Meta_nul Meta_nul
+keycode 4 = U+0033 U+009c U+0033 U+0033 Escape Escape Escape Escape Meta_three Meta_numbersign Meta_three Meta_three Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+0033 U+009c U+0033 U+0033 Escape Escape Escape Escape Meta_three Meta_numbersign Meta_three Meta_three Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+0033 U+009c U+0033 U+0033 Escape Escape Escape Escape Meta_three Meta_numbersign Meta_three Meta_three Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+0033 U+009c U+0033 U+0033 Escape Escape Escape Escape Meta_three Meta_numbersign Meta_three Meta_three Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+0033 U+009c U+0033 U+0033 Escape Escape Escape Escape Meta_three Meta_numbersign Meta_three Meta_three Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+0033 U+009c U+0033 U+0033 Escape Escape Escape Escape Meta_three Meta_numbersign Meta_three Meta_three Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+0033 U+009c U+0033 U+0033 Escape Escape Escape Escape Meta_three Meta_numbersign Meta_three Meta_three Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+0033 U+009c U+0033 U+0033 Escape Escape Escape Escape Meta_three Meta_numbersign Meta_three Meta_three Meta_Escape Meta_Escape Meta_Escape Meta_Escape
+keycode 5 = U+0034 U+0024 U+0034 U+0034 Control_backslash Control_backslash Control_backslash Control_backslash Meta_four Meta_dollar Meta_four Meta_four Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+0034 U+0024 U+0034 U+0034 Control_backslash Control_backslash Control_backslash Control_backslash Meta_four Meta_dollar Meta_four Meta_four Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+0034 U+0024 U+0034 U+0034 Control_backslash Control_backslash Control_backslash Control_backslash Meta_four Meta_dollar Meta_four Meta_four Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+0034 U+0024 U+0034 U+0034 Control_backslash Control_backslash Control_backslash Control_backslash Meta_four Meta_dollar Meta_four Meta_four Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+0034 U+0024 U+0034 U+0034 Control_backslash Control_backslash Control_backslash Control_backslash Meta_four Meta_dollar Meta_four Meta_four Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+0034 U+0024 U+0034 U+0034 Control_backslash Control_backslash Control_backslash Control_backslash Meta_four Meta_dollar Meta_four Meta_four Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+0034 U+0024 U+0034 U+0034 Control_backslash Control_backslash Control_backslash Control_backslash Meta_four Meta_dollar Meta_four Meta_four Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+0034 U+0024 U+0034 U+0034 Control_backslash Control_backslash Control_backslash Control_backslash Meta_four Meta_dollar Meta_four Meta_four Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash
+keycode 6 = U+0035 U+0025 U+0035 U+0035 Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_five Meta_percent Meta_five Meta_five Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright U+0035 U+0025 U+0035 U+0035 Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_five Meta_percent Meta_five Meta_five Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright U+0035 U+0025 U+0035 U+0035 Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_five Meta_percent Meta_five Meta_five Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright U+0035 U+0025 U+0035 U+0035 Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_five Meta_percent Meta_five Meta_five Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright U+0035 U+0025 U+0035 U+0035 Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_five Meta_percent Meta_five Meta_five Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright U+0035 U+0025 U+0035 U+0035 Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_five Meta_percent Meta_five Meta_five Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright U+0035 U+0025 U+0035 U+0035 Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_five Meta_percent Meta_five Meta_five Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright U+0035 U+0025 U+0035 U+0035 Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_five Meta_percent Meta_five Meta_five Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright
+keycode 7 = U+0036 U+005e dead_circumflex dead_circumflex Control_asciicircum Control_asciicircum dead_circumflex dead_circumflex Meta_six Meta_asciicircum dead_circumflex dead_circumflex Meta_Control_asciicircum Meta_Control_asciicircum dead_circumflex dead_circumflex U+0036 U+005e dead_circumflex dead_circumflex Control_asciicircum Control_asciicircum dead_circumflex dead_circumflex Meta_six Meta_asciicircum dead_circumflex dead_circumflex Meta_Control_asciicircum Meta_Control_asciicircum dead_circumflex dead_circumflex U+0036 U+005e dead_circumflex dead_circumflex Control_asciicircum Control_asciicircum dead_circumflex dead_circumflex Meta_six Meta_asciicircum dead_circumflex dead_circumflex Meta_Control_asciicircum Meta_Control_asciicircum dead_circumflex dead_circumflex U+0036 U+005e dead_circumflex dead_circumflex Control_asciicircum Control_asciicircum dead_circumflex dead_circumflex Meta_six Meta_asciicircum dead_circumflex dead_circumflex Meta_Control_asciicircum Meta_Control_asciicircum dead_circumflex dead_circumflex U+0036 U+005e dead_circumflex dead_circumflex Control_asciicircum Control_asciicircum dead_circumflex dead_circumflex Meta_six Meta_asciicircum dead_circumflex dead_circumflex Meta_Control_asciicircum Meta_Control_asciicircum dead_circumflex dead_circumflex U+0036 U+005e dead_circumflex dead_circumflex Control_asciicircum Control_asciicircum dead_circumflex dead_circumflex Meta_six Meta_asciicircum dead_circumflex dead_circumflex Meta_Control_asciicircum Meta_Control_asciicircum dead_circumflex dead_circumflex U+0036 U+005e dead_circumflex dead_circumflex Control_asciicircum Control_asciicircum dead_circumflex dead_circumflex Meta_six Meta_asciicircum dead_circumflex dead_circumflex Meta_Control_asciicircum Meta_Control_asciicircum dead_circumflex dead_circumflex U+0036 U+005e dead_circumflex dead_circumflex Control_asciicircum Control_asciicircum dead_circumflex dead_circumflex Meta_six Meta_asciicircum dead_circumflex dead_circumflex Meta_Control_asciicircum Meta_Control_asciicircum dead_circumflex dead_circumflex
+keycode 8 = U+0037 U+0026 U+0037 U+0037 Control_underscore Control_underscore Control_underscore Control_underscore Meta_seven Meta_ampersand Meta_seven Meta_seven Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+0037 U+0026 U+0037 U+0037 Control_underscore Control_underscore Control_underscore Control_underscore Meta_seven Meta_ampersand Meta_seven Meta_seven Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+0037 U+0026 U+0037 U+0037 Control_underscore Control_underscore Control_underscore Control_underscore Meta_seven Meta_ampersand Meta_seven Meta_seven Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+0037 U+0026 U+0037 U+0037 Control_underscore Control_underscore Control_underscore Control_underscore Meta_seven Meta_ampersand Meta_seven Meta_seven Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+0037 U+0026 U+0037 U+0037 Control_underscore Control_underscore Control_underscore Control_underscore Meta_seven Meta_ampersand Meta_seven Meta_seven Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+0037 U+0026 U+0037 U+0037 Control_underscore Control_underscore Control_underscore Control_underscore Meta_seven Meta_ampersand Meta_seven Meta_seven Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+0037 U+0026 U+0037 U+0037 Control_underscore Control_underscore Control_underscore Control_underscore Meta_seven Meta_ampersand Meta_seven Meta_seven Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+0037 U+0026 U+0037 U+0037 Control_underscore Control_underscore Control_underscore Control_underscore Meta_seven Meta_ampersand Meta_seven Meta_seven Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore
+keycode 9 = U+0038 U+002a U+0038 U+0038 Delete Delete Delete Delete Meta_eight Meta_asterisk Meta_eight Meta_eight Meta_Delete Meta_Delete Meta_Delete Meta_Delete U+0038 U+002a U+0038 U+0038 Delete Delete Delete Delete Meta_eight Meta_asterisk Meta_eight Meta_eight Meta_Delete Meta_Delete Meta_Delete Meta_Delete U+0038 U+002a U+0038 U+0038 Delete Delete Delete Delete Meta_eight Meta_asterisk Meta_eight Meta_eight Meta_Delete Meta_Delete Meta_Delete Meta_Delete U+0038 U+002a U+0038 U+0038 Delete Delete Delete Delete Meta_eight Meta_asterisk Meta_eight Meta_eight Meta_Delete Meta_Delete Meta_Delete Meta_Delete U+0038 U+002a U+0038 U+0038 Delete Delete Delete Delete Meta_eight Meta_asterisk Meta_eight Meta_eight Meta_Delete Meta_Delete Meta_Delete Meta_Delete U+0038 U+002a U+0038 U+0038 Delete Delete Delete Delete Meta_eight Meta_asterisk Meta_eight Meta_eight Meta_Delete Meta_Delete Meta_Delete Meta_Delete U+0038 U+002a U+0038 U+0038 Delete Delete Delete Delete Meta_eight Meta_asterisk Meta_eight Meta_eight Meta_Delete Meta_Delete Meta_Delete Meta_Delete U+0038 U+002a U+0038 U+0038 Delete Delete Delete Delete Meta_eight Meta_asterisk Meta_eight Meta_eight Meta_Delete Meta_Delete Meta_Delete Meta_Delete
+keycode 10 = U+0039 U+0028 dead_grave dead_grave dead_grave dead_grave dead_grave dead_grave Meta_nine Meta_parenleft dead_grave dead_grave dead_grave dead_grave dead_grave dead_grave U+0039 U+0028 dead_grave dead_grave dead_grave dead_grave dead_grave dead_grave Meta_nine Meta_parenleft dead_grave dead_grave dead_grave dead_grave dead_grave dead_grave U+0039 U+0028 dead_grave dead_grave dead_grave dead_grave dead_grave dead_grave Meta_nine Meta_parenleft dead_grave dead_grave dead_grave dead_grave dead_grave dead_grave U+0039 U+0028 dead_grave dead_grave dead_grave dead_grave dead_grave dead_grave Meta_nine Meta_parenleft dead_grave dead_grave dead_grave dead_grave dead_grave dead_grave U+0039 U+0028 dead_grave dead_grave dead_grave dead_grave dead_grave dead_grave Meta_nine Meta_parenleft dead_grave dead_grave dead_grave dead_grave dead_grave dead_grave U+0039 U+0028 dead_grave dead_grave dead_grave dead_grave dead_grave dead_grave Meta_nine Meta_parenleft dead_grave dead_grave dead_grave dead_grave dead_grave dead_grave U+0039 U+0028 dead_grave dead_grave dead_grave dead_grave dead_grave dead_grave Meta_nine Meta_parenleft dead_grave dead_grave dead_grave dead_grave dead_grave dead_grave U+0039 U+0028 dead_grave dead_grave dead_grave dead_grave dead_grave dead_grave Meta_nine Meta_parenleft dead_grave dead_grave dead_grave dead_grave dead_grave dead_grave
+keycode 11 = U+0030 U+0029 U+0030 U+0030 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_zero Meta_parenright Meta_zero Meta_zero VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0030 U+0029 U+0030 U+0030 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_zero Meta_parenright Meta_zero Meta_zero VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0030 U+0029 U+0030 U+0030 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_zero Meta_parenright Meta_zero Meta_zero VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0030 U+0029 U+0030 U+0030 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_zero Meta_parenright Meta_zero Meta_zero VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0030 U+0029 U+0030 U+0030 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_zero Meta_parenright Meta_zero Meta_zero VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0030 U+0029 U+0030 U+0030 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_zero Meta_parenright Meta_zero Meta_zero VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0030 U+0029 U+0030 U+0030 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_zero Meta_parenright Meta_zero Meta_zero VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0030 U+0029 U+0030 U+0030 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_zero Meta_parenright Meta_zero Meta_zero VoidSymbol VoidSymbol VoidSymbol VoidSymbol
+keycode 12 = U+005b U+007b U+005b U+005b Escape Escape Escape Escape Meta_bracketleft Meta_braceleft Meta_bracketleft Meta_bracketleft Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+005b U+007b U+005b U+005b Escape Escape Escape Escape Meta_bracketleft Meta_braceleft Meta_bracketleft Meta_bracketleft Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+005b U+007b U+005b U+005b Escape Escape Escape Escape Meta_bracketleft Meta_braceleft Meta_bracketleft Meta_bracketleft Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+005b U+007b U+005b U+005b Escape Escape Escape Escape Meta_bracketleft Meta_braceleft Meta_bracketleft Meta_bracketleft Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+005b U+007b U+005b U+005b Escape Escape Escape Escape Meta_bracketleft Meta_braceleft Meta_bracketleft Meta_bracketleft Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+005b U+007b U+005b U+005b Escape Escape Escape Escape Meta_bracketleft Meta_braceleft Meta_bracketleft Meta_bracketleft Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+005b U+007b U+005b U+005b Escape Escape Escape Escape Meta_bracketleft Meta_braceleft Meta_bracketleft Meta_bracketleft Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+005b U+007b U+005b U+005b Escape Escape Escape Escape Meta_bracketleft Meta_braceleft Meta_bracketleft Meta_bracketleft Meta_Escape Meta_Escape Meta_Escape Meta_Escape
+keycode 13 = U+005d U+007d dead_tilde dead_tilde Control_bracketright Control_bracketright dead_tilde dead_tilde Meta_bracketright Meta_braceright dead_tilde dead_tilde Meta_Control_bracketright Meta_Control_bracketright dead_tilde dead_tilde U+005d U+007d dead_tilde dead_tilde Control_bracketright Control_bracketright dead_tilde dead_tilde Meta_bracketright Meta_braceright dead_tilde dead_tilde Meta_Control_bracketright Meta_Control_bracketright dead_tilde dead_tilde U+005d U+007d dead_tilde dead_tilde Control_bracketright Control_bracketright dead_tilde dead_tilde Meta_bracketright Meta_braceright dead_tilde dead_tilde Meta_Control_bracketright Meta_Control_bracketright dead_tilde dead_tilde U+005d U+007d dead_tilde dead_tilde Control_bracketright Control_bracketright dead_tilde dead_tilde Meta_bracketright Meta_braceright dead_tilde dead_tilde Meta_Control_bracketright Meta_Control_bracketright dead_tilde dead_tilde U+005d U+007d dead_tilde dead_tilde Control_bracketright Control_bracketright dead_tilde dead_tilde Meta_bracketright Meta_braceright dead_tilde dead_tilde Meta_Control_bracketright Meta_Control_bracketright dead_tilde dead_tilde U+005d U+007d dead_tilde dead_tilde Control_bracketright Control_bracketright dead_tilde dead_tilde Meta_bracketright Meta_braceright dead_tilde dead_tilde Meta_Control_bracketright Meta_Control_bracketright dead_tilde dead_tilde U+005d U+007d dead_tilde dead_tilde Control_bracketright Control_bracketright dead_tilde dead_tilde Meta_bracketright Meta_braceright dead_tilde dead_tilde Meta_Control_bracketright Meta_Control_bracketright dead_tilde dead_tilde U+005d U+007d dead_tilde dead_tilde Control_bracketright Control_bracketright dead_tilde dead_tilde Meta_bracketright Meta_braceright dead_tilde dead_tilde Meta_Control_bracketright Meta_Control_bracketright dead_tilde dead_tilde
+keycode 14 = Delete Delete Delete Delete BackSpace BackSpace BackSpace BackSpace Meta_Delete Meta_Delete Meta_Delete Meta_Delete Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace Delete Delete Delete Delete BackSpace BackSpace BackSpace BackSpace Meta_Delete Meta_Delete Meta_Delete Meta_Delete Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace Delete Delete Delete Delete BackSpace BackSpace BackSpace BackSpace Meta_Delete Meta_Delete Meta_Delete Meta_Delete Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace Delete Delete Delete Delete BackSpace BackSpace BackSpace BackSpace Meta_Delete Meta_Delete Meta_Delete Meta_Delete Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace Delete Delete Delete Delete BackSpace BackSpace BackSpace BackSpace Meta_Delete Meta_Delete Meta_Delete Meta_Delete Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace Delete Delete Delete Delete BackSpace BackSpace BackSpace BackSpace Meta_Delete Meta_Delete Meta_Delete Meta_Delete Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace Delete Delete Delete Delete BackSpace BackSpace BackSpace BackSpace Meta_Delete Meta_Delete Meta_Delete Meta_Delete Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace Delete Delete Delete Delete BackSpace BackSpace BackSpace BackSpace Meta_Delete Meta_Delete Meta_Delete Meta_Delete Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace
+keycode 15 = Tab Tab Tab Tab Tab Tab Tab Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Tab Tab Tab Tab Tab Tab Tab Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Tab Tab Tab Tab Tab Tab Tab Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Tab Tab Tab Tab Tab Tab Tab Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Tab Tab Tab Tab Tab Tab Tab Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Tab Tab Tab Tab Tab Tab Tab Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Tab Tab Tab Tab Tab Tab Tab Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Tab Tab Tab Tab Tab Tab Tab Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab
+keycode 16 = U+0027 U+0040 dead_acute dead_diaeresis Control_g Control_g dead_acute dead_diaeresis Meta_apostrophe Meta_quotedbl dead_acute dead_diaeresis Meta_Control_g Meta_Control_g dead_acute dead_diaeresis U+0027 U+0040 dead_acute dead_diaeresis Control_g Control_g dead_acute dead_diaeresis Meta_apostrophe Meta_quotedbl dead_acute dead_diaeresis Meta_Control_g Meta_Control_g dead_acute dead_diaeresis U+0027 U+0040 dead_acute dead_diaeresis Control_g Control_g dead_acute dead_diaeresis Meta_apostrophe Meta_quotedbl dead_acute dead_diaeresis Meta_Control_g Meta_Control_g dead_acute dead_diaeresis U+0027 U+0040 dead_acute dead_diaeresis Control_g Control_g dead_acute dead_diaeresis Meta_apostrophe Meta_quotedbl dead_acute dead_diaeresis Meta_Control_g Meta_Control_g dead_acute dead_diaeresis U+0027 U+0040 dead_acute dead_diaeresis Control_g Control_g dead_acute dead_diaeresis Meta_apostrophe Meta_quotedbl dead_acute dead_diaeresis Meta_Control_g Meta_Control_g dead_acute dead_diaeresis U+0027 U+0040 dead_acute dead_diaeresis Control_g Control_g dead_acute dead_diaeresis Meta_apostrophe Meta_quotedbl dead_acute dead_diaeresis Meta_Control_g Meta_Control_g dead_acute dead_diaeresis U+0027 U+0040 dead_acute dead_diaeresis Control_g Control_g dead_acute dead_diaeresis Meta_apostrophe Meta_quotedbl dead_acute dead_diaeresis Meta_Control_g Meta_Control_g dead_acute dead_diaeresis U+0027 U+0040 dead_acute dead_diaeresis Control_g Control_g dead_acute dead_diaeresis Meta_apostrophe Meta_quotedbl dead_acute dead_diaeresis Meta_Control_g Meta_Control_g dead_acute dead_diaeresis
+keycode 17 = U+002c U+003c dead_cedilla dead_caron dead_cedilla dead_caron dead_cedilla dead_caron Meta_comma Meta_less dead_cedilla dead_caron dead_cedilla dead_caron dead_cedilla dead_caron U+002c U+003c dead_cedilla dead_caron dead_cedilla dead_caron dead_cedilla dead_caron Meta_comma Meta_less dead_cedilla dead_caron dead_cedilla dead_caron dead_cedilla dead_caron U+002c U+003c dead_cedilla dead_caron dead_cedilla dead_caron dead_cedilla dead_caron Meta_comma Meta_less dead_cedilla dead_caron dead_cedilla dead_caron dead_cedilla dead_caron U+002c U+003c dead_cedilla dead_caron dead_cedilla dead_caron dead_cedilla dead_caron Meta_comma Meta_less dead_cedilla dead_caron dead_cedilla dead_caron dead_cedilla dead_caron U+002c U+003c dead_cedilla dead_caron dead_cedilla dead_caron dead_cedilla dead_caron Meta_comma Meta_less dead_cedilla dead_caron dead_cedilla dead_caron dead_cedilla dead_caron U+002c U+003c dead_cedilla dead_caron dead_cedilla dead_caron dead_cedilla dead_caron Meta_comma Meta_less dead_cedilla dead_caron dead_cedilla dead_caron dead_cedilla dead_caron U+002c U+003c dead_cedilla dead_caron dead_cedilla dead_caron dead_cedilla dead_caron Meta_comma Meta_less dead_cedilla dead_caron dead_cedilla dead_caron dead_cedilla dead_caron U+002c U+003c dead_cedilla dead_caron dead_cedilla dead_caron dead_cedilla dead_caron Meta_comma Meta_less dead_cedilla dead_caron dead_cedilla dead_caron dead_cedilla dead_caron
+keycode 18 = U+002e U+003e U+002e U+00b7 Compose Compose Compose Compose Meta_period Meta_greater Meta_period Meta_period Compose Compose Compose Compose U+002e U+003e U+002e U+00b7 Compose Compose Compose Compose Meta_period Meta_greater Meta_period Meta_period Compose Compose Compose Compose U+002e U+003e U+002e U+00b7 Compose Compose Compose Compose Meta_period Meta_greater Meta_period Meta_period Compose Compose Compose Compose U+002e U+003e U+002e U+00b7 Compose Compose Compose Compose Meta_period Meta_greater Meta_period Meta_period Compose Compose Compose Compose U+002e U+003e U+002e U+00b7 Compose Compose Compose Compose Meta_period Meta_greater Meta_period Meta_period Compose Compose Compose Compose U+002e U+003e U+002e U+00b7 Compose Compose Compose Compose Meta_period Meta_greater Meta_period Meta_period Compose Compose Compose Compose U+002e U+003e U+002e U+00b7 Compose Compose Compose Compose Meta_period Meta_greater Meta_period Meta_period Compose Compose Compose Compose U+002e U+003e U+002e U+00b7 Compose Compose Compose Compose Meta_period Meta_greater Meta_period Meta_period Compose Compose Compose Compose
+keycode 19 = +U+0070 +U+0050 +U+0070 +U+0070 Control_p Control_p Control_p Control_p Meta_p Meta_P Meta_p Meta_p Meta_Control_p Meta_Control_p Meta_Control_p Meta_Control_p +U+0070 +U+0050 +U+0070 +U+0070 Control_p Control_p Control_p Control_p Meta_p Meta_P Meta_p Meta_p Meta_Control_p Meta_Control_p Meta_Control_p Meta_Control_p +U+0070 +U+0050 +U+0070 +U+0070 Control_p Control_p Control_p Control_p Meta_p Meta_P Meta_p Meta_p Meta_Control_p Meta_Control_p Meta_Control_p Meta_Control_p +U+0070 +U+0050 +U+0070 +U+0070 Control_p Control_p Control_p Control_p Meta_p Meta_P Meta_p Meta_p Meta_Control_p Meta_Control_p Meta_Control_p Meta_Control_p +U+0050 +U+0070 +U+0050 +U+0050 Control_p Control_p Control_p Control_p Meta_p Meta_P Meta_p Meta_p Meta_Control_p Meta_Control_p Meta_Control_p Meta_Control_p +U+0050 +U+0070 +U+0050 +U+0050 Control_p Control_p Control_p Control_p Meta_p Meta_P Meta_p Meta_p Meta_Control_p Meta_Control_p Meta_Control_p Meta_Control_p +U+0050 +U+0070 +U+0050 +U+0050 Control_p Control_p Control_p Control_p Meta_p Meta_P Meta_p Meta_p Meta_Control_p Meta_Control_p Meta_Control_p Meta_Control_p +U+0050 +U+0070 +U+0050 +U+0050 Control_p Control_p Control_p Control_p Meta_p Meta_P Meta_p Meta_p Meta_Control_p Meta_Control_p Meta_Control_p Meta_Control_p
+keycode 20 = +U+0079 +U+0059 +U+0079 +U+0079 Control_y Control_y Control_y Control_y Meta_y Meta_Y Meta_y Meta_y Meta_Control_y Meta_Control_y Meta_Control_y Meta_Control_y +U+0079 +U+0059 +U+0079 +U+0079 Control_y Control_y Control_y Control_y Meta_y Meta_Y Meta_y Meta_y Meta_Control_y Meta_Control_y Meta_Control_y Meta_Control_y +U+0079 +U+0059 +U+0079 +U+0079 Control_y Control_y Control_y Control_y Meta_y Meta_Y Meta_y Meta_y Meta_Control_y Meta_Control_y Meta_Control_y Meta_Control_y +U+0079 +U+0059 +U+0079 +U+0079 Control_y Control_y Control_y Control_y Meta_y Meta_Y Meta_y Meta_y Meta_Control_y Meta_Control_y Meta_Control_y Meta_Control_y +U+0059 +U+0079 +U+0059 +U+0059 Control_y Control_y Control_y Control_y Meta_y Meta_Y Meta_y Meta_y Meta_Control_y Meta_Control_y Meta_Control_y Meta_Control_y +U+0059 +U+0079 +U+0059 +U+0059 Control_y Control_y Control_y Control_y Meta_y Meta_Y Meta_y Meta_y Meta_Control_y Meta_Control_y Meta_Control_y Meta_Control_y +U+0059 +U+0079 +U+0059 +U+0059 Control_y Control_y Control_y Control_y Meta_y Meta_Y Meta_y Meta_y Meta_Control_y Meta_Control_y Meta_Control_y Meta_Control_y +U+0059 +U+0079 +U+0059 +U+0059 Control_y Control_y Control_y Control_y Meta_y Meta_Y Meta_y Meta_y Meta_Control_y Meta_Control_y Meta_Control_y Meta_Control_y
+keycode 21 = +U+0066 +U+0046 +U+0066 +U+0066 Control_f Control_f Control_f Control_f Meta_f Meta_F Meta_f Meta_f Meta_Control_f Meta_Control_f Meta_Control_f Meta_Control_f +U+0066 +U+0046 +U+0066 +U+0066 Control_f Control_f Control_f Control_f Meta_f Meta_F Meta_f Meta_f Meta_Control_f Meta_Control_f Meta_Control_f Meta_Control_f +U+0066 +U+0046 +U+0066 +U+0066 Control_f Control_f Control_f Control_f Meta_f Meta_F Meta_f Meta_f Meta_Control_f Meta_Control_f Meta_Control_f Meta_Control_f +U+0066 +U+0046 +U+0066 +U+0066 Control_f Control_f Control_f Control_f Meta_f Meta_F Meta_f Meta_f Meta_Control_f Meta_Control_f Meta_Control_f Meta_Control_f +U+0046 +U+0066 +U+0046 +U+0046 Control_f Control_f Control_f Control_f Meta_f Meta_F Meta_f Meta_f Meta_Control_f Meta_Control_f Meta_Control_f Meta_Control_f +U+0046 +U+0066 +U+0046 +U+0046 Control_f Control_f Control_f Control_f Meta_f Meta_F Meta_f Meta_f Meta_Control_f Meta_Control_f Meta_Control_f Meta_Control_f +U+0046 +U+0066 +U+0046 +U+0046 Control_f Control_f Control_f Control_f Meta_f Meta_F Meta_f Meta_f Meta_Control_f Meta_Control_f Meta_Control_f Meta_Control_f +U+0046 +U+0066 +U+0046 +U+0046 Control_f Control_f Control_f Control_f Meta_f Meta_F Meta_f Meta_f Meta_Control_f Meta_Control_f Meta_Control_f Meta_Control_f
+keycode 22 = +U+0067 +U+0047 +U+0067 +U+0067 Control_g Control_g Control_g Control_g Meta_g Meta_G Meta_g Meta_g Meta_Control_g Meta_Control_g Meta_Control_g Meta_Control_g +U+0067 +U+0047 +U+0067 +U+0067 Control_g Control_g Control_g Control_g Meta_g Meta_G Meta_g Meta_g Meta_Control_g Meta_Control_g Meta_Control_g Meta_Control_g +U+0067 +U+0047 +U+0067 +U+0067 Control_g Control_g Control_g Control_g Meta_g Meta_G Meta_g Meta_g Meta_Control_g Meta_Control_g Meta_Control_g Meta_Control_g +U+0067 +U+0047 +U+0067 +U+0067 Control_g Control_g Control_g Control_g Meta_g Meta_G Meta_g Meta_g Meta_Control_g Meta_Control_g Meta_Control_g Meta_Control_g +U+0047 +U+0067 +U+0047 +U+0047 Control_g Control_g Control_g Control_g Meta_g Meta_G Meta_g Meta_g Meta_Control_g Meta_Control_g Meta_Control_g Meta_Control_g +U+0047 +U+0067 +U+0047 +U+0047 Control_g Control_g Control_g Control_g Meta_g Meta_G Meta_g Meta_g Meta_Control_g Meta_Control_g Meta_Control_g Meta_Control_g +U+0047 +U+0067 +U+0047 +U+0047 Control_g Control_g Control_g Control_g Meta_g Meta_G Meta_g Meta_g Meta_Control_g Meta_Control_g Meta_Control_g Meta_Control_g +U+0047 +U+0067 +U+0047 +U+0047 Control_g Control_g Control_g Control_g Meta_g Meta_G Meta_g Meta_g Meta_Control_g Meta_Control_g Meta_Control_g Meta_Control_g
+keycode 23 = +U+0063 +U+0043 +U+0063 +U+0063 Control_c Control_c Control_c Control_c Meta_c Meta_C Meta_c Meta_c Meta_Control_c Meta_Control_c Meta_Control_c Meta_Control_c +U+0063 +U+0043 +U+0063 +U+0063 Control_c Control_c Control_c Control_c Meta_c Meta_C Meta_c Meta_c Meta_Control_c Meta_Control_c Meta_Control_c Meta_Control_c +U+0063 +U+0043 +U+0063 +U+0063 Control_c Control_c Control_c Control_c Meta_c Meta_C Meta_c Meta_c Meta_Control_c Meta_Control_c Meta_Control_c Meta_Control_c +U+0063 +U+0043 +U+0063 +U+0063 Control_c Control_c Control_c Control_c Meta_c Meta_C Meta_c Meta_c Meta_Control_c Meta_Control_c Meta_Control_c Meta_Control_c +U+0043 +U+0063 +U+0043 +U+0043 Control_c Control_c Control_c Control_c Meta_c Meta_C Meta_c Meta_c Meta_Control_c Meta_Control_c Meta_Control_c Meta_Control_c +U+0043 +U+0063 +U+0043 +U+0043 Control_c Control_c Control_c Control_c Meta_c Meta_C Meta_c Meta_c Meta_Control_c Meta_Control_c Meta_Control_c Meta_Control_c +U+0043 +U+0063 +U+0043 +U+0043 Control_c Control_c Control_c Control_c Meta_c Meta_C Meta_c Meta_c Meta_Control_c Meta_Control_c Meta_Control_c Meta_Control_c +U+0043 +U+0063 +U+0043 +U+0043 Control_c Control_c Control_c Control_c Meta_c Meta_C Meta_c Meta_c Meta_Control_c Meta_Control_c Meta_Control_c Meta_Control_c
+keycode 24 = +U+0072 +U+0052 +U+0072 +U+0072 Control_r Control_r Control_r Control_r Meta_r Meta_R Meta_r Meta_r Meta_Control_r Meta_Control_r Meta_Control_r Meta_Control_r +U+0072 +U+0052 +U+0072 +U+0072 Control_r Control_r Control_r Control_r Meta_r Meta_R Meta_r Meta_r Meta_Control_r Meta_Control_r Meta_Control_r Meta_Control_r +U+0072 +U+0052 +U+0072 +U+0072 Control_r Control_r Control_r Control_r Meta_r Meta_R Meta_r Meta_r Meta_Control_r Meta_Control_r Meta_Control_r Meta_Control_r +U+0072 +U+0052 +U+0072 +U+0072 Control_r Control_r Control_r Control_r Meta_r Meta_R Meta_r Meta_r Meta_Control_r Meta_Control_r Meta_Control_r Meta_Control_r +U+0052 +U+0072 +U+0052 +U+0052 Control_r Control_r Control_r Control_r Meta_r Meta_R Meta_r Meta_r Meta_Control_r Meta_Control_r Meta_Control_r Meta_Control_r +U+0052 +U+0072 +U+0052 +U+0052 Control_r Control_r Control_r Control_r Meta_r Meta_R Meta_r Meta_r Meta_Control_r Meta_Control_r Meta_Control_r Meta_Control_r +U+0052 +U+0072 +U+0052 +U+0052 Control_r Control_r Control_r Control_r Meta_r Meta_R Meta_r Meta_r Meta_Control_r Meta_Control_r Meta_Control_r Meta_Control_r +U+0052 +U+0072 +U+0052 +U+0052 Control_r Control_r Control_r Control_r Meta_r Meta_R Meta_r Meta_r Meta_Control_r Meta_Control_r Meta_Control_r Meta_Control_r
+keycode 25 = +U+006c +U+004c +U+006c +U+006c Control_l Control_l Control_l Control_l Meta_l Meta_L Meta_l Meta_l Meta_Control_l Meta_Control_l Meta_Control_l Meta_Control_l +U+006c +U+004c +U+006c +U+006c Control_l Control_l Control_l Control_l Meta_l Meta_L Meta_l Meta_l Meta_Control_l Meta_Control_l Meta_Control_l Meta_Control_l +U+006c +U+004c +U+006c +U+006c Control_l Control_l Control_l Control_l Meta_l Meta_L Meta_l Meta_l Meta_Control_l Meta_Control_l Meta_Control_l Meta_Control_l +U+006c +U+004c +U+006c +U+006c Control_l Control_l Control_l Control_l Meta_l Meta_L Meta_l Meta_l Meta_Control_l Meta_Control_l Meta_Control_l Meta_Control_l +U+004c +U+006c +U+004c +U+004c Control_l Control_l Control_l Control_l Meta_l Meta_L Meta_l Meta_l Meta_Control_l Meta_Control_l Meta_Control_l Meta_Control_l +U+004c +U+006c +U+004c +U+004c Control_l Control_l Control_l Control_l Meta_l Meta_L Meta_l Meta_l Meta_Control_l Meta_Control_l Meta_Control_l Meta_Control_l +U+004c +U+006c +U+004c +U+004c Control_l Control_l Control_l Control_l Meta_l Meta_L Meta_l Meta_l Meta_Control_l Meta_Control_l Meta_Control_l Meta_Control_l +U+004c +U+006c +U+004c +U+004c Control_l Control_l Control_l Control_l Meta_l Meta_L Meta_l Meta_l Meta_Control_l Meta_Control_l Meta_Control_l Meta_Control_l
+keycode 26 = U+002f U+003f U+002f U+002f Delete Delete Delete Delete Meta_slash Meta_question Meta_slash Meta_slash Meta_Delete Meta_Delete Meta_Delete Meta_Delete U+002f U+003f U+002f U+002f Delete Delete Delete Delete Meta_slash Meta_question Meta_slash Meta_slash Meta_Delete Meta_Delete Meta_Delete Meta_Delete U+002f U+003f U+002f U+002f Delete Delete Delete Delete Meta_slash Meta_question Meta_slash Meta_slash Meta_Delete Meta_Delete Meta_Delete Meta_Delete U+002f U+003f U+002f U+002f Delete Delete Delete Delete Meta_slash Meta_question Meta_slash Meta_slash Meta_Delete Meta_Delete Meta_Delete Meta_Delete U+002f U+003f U+002f U+002f Delete Delete Delete Delete Meta_slash Meta_question Meta_slash Meta_slash Meta_Delete Meta_Delete Meta_Delete Meta_Delete U+002f U+003f U+002f U+002f Delete Delete Delete Delete Meta_slash Meta_question Meta_slash Meta_slash Meta_Delete Meta_Delete Meta_Delete Meta_Delete U+002f U+003f U+002f U+002f Delete Delete Delete Delete Meta_slash Meta_question Meta_slash Meta_slash Meta_Delete Meta_Delete Meta_Delete Meta_Delete U+002f U+003f U+002f U+002f Delete Delete Delete Delete Meta_slash Meta_question Meta_slash Meta_slash Meta_Delete Meta_Delete Meta_Delete Meta_Delete
+keycode 27 = U+003d U+002b U+003d U+003d VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_equal Meta_plus Meta_equal Meta_equal VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+003d U+002b U+003d U+003d VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_equal Meta_plus Meta_equal Meta_equal VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+003d U+002b U+003d U+003d VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_equal Meta_plus Meta_equal Meta_equal VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+003d U+002b U+003d U+003d VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_equal Meta_plus Meta_equal Meta_equal VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+003d U+002b U+003d U+003d VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_equal Meta_plus Meta_equal Meta_equal VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+003d U+002b U+003d U+003d VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_equal Meta_plus Meta_equal Meta_equal VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+003d U+002b U+003d U+003d VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_equal Meta_plus Meta_equal Meta_equal VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+003d U+002b U+003d U+003d VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_equal Meta_plus Meta_equal Meta_equal VoidSymbol VoidSymbol VoidSymbol VoidSymbol
+keycode 28 = Return Return Return Return Control_m Control_m Control_m Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Return Return Return Return Control_m Control_m Control_m Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Return Return Return Return Control_m Control_m Control_m Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Return Return Return Return Control_m Control_m Control_m Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Return Return Return Return Control_m Control_m Control_m Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Return Return Return Return Control_m Control_m Control_m Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Return Return Return Return Control_m Control_m Control_m Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Return Return Return Return Control_m Control_m Control_m Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m
+keycode 29 = Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control
+keycode 30 = +U+0061 +U+0041 +U+0061 +U+0061 Control_a Control_a Control_a Control_a Meta_a Meta_A Meta_a Meta_a Meta_Control_a Meta_Control_a Meta_Control_a Meta_Control_a +U+0061 +U+0041 +U+0061 +U+0061 Control_a Control_a Control_a Control_a Meta_a Meta_A Meta_a Meta_a Meta_Control_a Meta_Control_a Meta_Control_a Meta_Control_a +U+0061 +U+0041 +U+0061 +U+0061 Control_a Control_a Control_a Control_a Meta_a Meta_A Meta_a Meta_a Meta_Control_a Meta_Control_a Meta_Control_a Meta_Control_a +U+0061 +U+0041 +U+0061 +U+0061 Control_a Control_a Control_a Control_a Meta_a Meta_A Meta_a Meta_a Meta_Control_a Meta_Control_a Meta_Control_a Meta_Control_a +U+0041 +U+0061 +U+0041 +U+0041 Control_a Control_a Control_a Control_a Meta_a Meta_A Meta_a Meta_a Meta_Control_a Meta_Control_a Meta_Control_a Meta_Control_a +U+0041 +U+0061 +U+0041 +U+0041 Control_a Control_a Control_a Control_a Meta_a Meta_A Meta_a Meta_a Meta_Control_a Meta_Control_a Meta_Control_a Meta_Control_a +U+0041 +U+0061 +U+0041 +U+0041 Control_a Control_a Control_a Control_a Meta_a Meta_A Meta_a Meta_a Meta_Control_a Meta_Control_a Meta_Control_a Meta_Control_a +U+0041 +U+0061 +U+0041 +U+0041 Control_a Control_a Control_a Control_a Meta_a Meta_A Meta_a Meta_a Meta_Control_a Meta_Control_a Meta_Control_a Meta_Control_a
+keycode 31 = +U+006f +U+004f +U+006f +U+006f Control_o Control_o Control_o Control_o Meta_o Meta_O Meta_o Meta_o Meta_Control_o Meta_Control_o Meta_Control_o Meta_Control_o +U+006f +U+004f +U+006f +U+006f Control_o Control_o Control_o Control_o Meta_o Meta_O Meta_o Meta_o Meta_Control_o Meta_Control_o Meta_Control_o Meta_Control_o +U+006f +U+004f +U+006f +U+006f Control_o Control_o Control_o Control_o Meta_o Meta_O Meta_o Meta_o Meta_Control_o Meta_Control_o Meta_Control_o Meta_Control_o +U+006f +U+004f +U+006f +U+006f Control_o Control_o Control_o Control_o Meta_o Meta_O Meta_o Meta_o Meta_Control_o Meta_Control_o Meta_Control_o Meta_Control_o +U+004f +U+006f +U+004f +U+004f Control_o Control_o Control_o Control_o Meta_o Meta_O Meta_o Meta_o Meta_Control_o Meta_Control_o Meta_Control_o Meta_Control_o +U+004f +U+006f +U+004f +U+004f Control_o Control_o Control_o Control_o Meta_o Meta_O Meta_o Meta_o Meta_Control_o Meta_Control_o Meta_Control_o Meta_Control_o +U+004f +U+006f +U+004f +U+004f Control_o Control_o Control_o Control_o Meta_o Meta_O Meta_o Meta_o Meta_Control_o Meta_Control_o Meta_Control_o Meta_Control_o +U+004f +U+006f +U+004f +U+004f Control_o Control_o Control_o Control_o Meta_o Meta_O Meta_o Meta_o Meta_Control_o Meta_Control_o Meta_Control_o Meta_Control_o
+keycode 32 = +U+0065 +U+0045 +U+0065 +U+0065 Control_e Control_e Control_e Control_e Meta_e Meta_E Meta_e Meta_e Meta_Control_e Meta_Control_e Meta_Control_e Meta_Control_e +U+0065 +U+0045 +U+0065 +U+0065 Control_e Control_e Control_e Control_e Meta_e Meta_E Meta_e Meta_e Meta_Control_e Meta_Control_e Meta_Control_e Meta_Control_e +U+0065 +U+0045 +U+0065 +U+0065 Control_e Control_e Control_e Control_e Meta_e Meta_E Meta_e Meta_e Meta_Control_e Meta_Control_e Meta_Control_e Meta_Control_e +U+0065 +U+0045 +U+0065 +U+0065 Control_e Control_e Control_e Control_e Meta_e Meta_E Meta_e Meta_e Meta_Control_e Meta_Control_e Meta_Control_e Meta_Control_e +U+0045 +U+0065 +U+0045 +U+0045 Control_e Control_e Control_e Control_e Meta_e Meta_E Meta_e Meta_e Meta_Control_e Meta_Control_e Meta_Control_e Meta_Control_e +U+0045 +U+0065 +U+0045 +U+0045 Control_e Control_e Control_e Control_e Meta_e Meta_E Meta_e Meta_e Meta_Control_e Meta_Control_e Meta_Control_e Meta_Control_e +U+0045 +U+0065 +U+0045 +U+0045 Control_e Control_e Control_e Control_e Meta_e Meta_E Meta_e Meta_e Meta_Control_e Meta_Control_e Meta_Control_e Meta_Control_e +U+0045 +U+0065 +U+0045 +U+0045 Control_e Control_e Control_e Control_e Meta_e Meta_E Meta_e Meta_e Meta_Control_e Meta_Control_e Meta_Control_e Meta_Control_e
+keycode 33 = +U+0075 +U+0055 +U+0075 +U+0075 Control_u Control_u Control_u Control_u Meta_u Meta_U Meta_u Meta_u Meta_Control_u Meta_Control_u Meta_Control_u Meta_Control_u +U+0075 +U+0055 +U+0075 +U+0075 Control_u Control_u Control_u Control_u Meta_u Meta_U Meta_u Meta_u Meta_Control_u Meta_Control_u Meta_Control_u Meta_Control_u +U+0075 +U+0055 +U+0075 +U+0075 Control_u Control_u Control_u Control_u Meta_u Meta_U Meta_u Meta_u Meta_Control_u Meta_Control_u Meta_Control_u Meta_Control_u +U+0075 +U+0055 +U+0075 +U+0075 Control_u Control_u Control_u Control_u Meta_u Meta_U Meta_u Meta_u Meta_Control_u Meta_Control_u Meta_Control_u Meta_Control_u +U+0055 +U+0075 +U+0055 +U+0055 Control_u Control_u Control_u Control_u Meta_u Meta_U Meta_u Meta_u Meta_Control_u Meta_Control_u Meta_Control_u Meta_Control_u +U+0055 +U+0075 +U+0055 +U+0055 Control_u Control_u Control_u Control_u Meta_u Meta_U Meta_u Meta_u Meta_Control_u Meta_Control_u Meta_Control_u Meta_Control_u +U+0055 +U+0075 +U+0055 +U+0055 Control_u Control_u Control_u Control_u Meta_u Meta_U Meta_u Meta_u Meta_Control_u Meta_Control_u Meta_Control_u Meta_Control_u +U+0055 +U+0075 +U+0055 +U+0055 Control_u Control_u Control_u Control_u Meta_u Meta_U Meta_u Meta_u Meta_Control_u Meta_Control_u Meta_Control_u Meta_Control_u
+keycode 34 = +U+0069 +U+0049 +U+0069 +U+0069 Tab Tab Tab Tab Meta_i Meta_I Meta_i Meta_i Meta_Tab Meta_Tab Meta_Tab Meta_Tab +U+0069 +U+0049 +U+0069 +U+0069 Tab Tab Tab Tab Meta_i Meta_I Meta_i Meta_i Meta_Tab Meta_Tab Meta_Tab Meta_Tab +U+0069 +U+0049 +U+0069 +U+0069 Tab Tab Tab Tab Meta_i Meta_I Meta_i Meta_i Meta_Tab Meta_Tab Meta_Tab Meta_Tab +U+0069 +U+0049 +U+0069 +U+0069 Tab Tab Tab Tab Meta_i Meta_I Meta_i Meta_i Meta_Tab Meta_Tab Meta_Tab Meta_Tab +U+0049 +U+0069 +U+0049 +U+0049 Tab Tab Tab Tab Meta_i Meta_I Meta_i Meta_i Meta_Tab Meta_Tab Meta_Tab Meta_Tab +U+0049 +U+0069 +U+0049 +U+0049 Tab Tab Tab Tab Meta_i Meta_I Meta_i Meta_i Meta_Tab Meta_Tab Meta_Tab Meta_Tab +U+0049 +U+0069 +U+0049 +U+0049 Tab Tab Tab Tab Meta_i Meta_I Meta_i Meta_i Meta_Tab Meta_Tab Meta_Tab Meta_Tab +U+0049 +U+0069 +U+0049 +U+0049 Tab Tab Tab Tab Meta_i Meta_I Meta_i Meta_i Meta_Tab Meta_Tab Meta_Tab Meta_Tab
+keycode 35 = +U+0064 +U+0044 +U+0064 +U+0064 Control_d Control_d Control_d Control_d Meta_d Meta_D Meta_d Meta_d Meta_Control_d Meta_Control_d Meta_Control_d Meta_Control_d +U+0064 +U+0044 +U+0064 +U+0064 Control_d Control_d Control_d Control_d Meta_d Meta_D Meta_d Meta_d Meta_Control_d Meta_Control_d Meta_Control_d Meta_Control_d +U+0064 +U+0044 +U+0064 +U+0064 Control_d Control_d Control_d Control_d Meta_d Meta_D Meta_d Meta_d Meta_Control_d Meta_Control_d Meta_Control_d Meta_Control_d +U+0064 +U+0044 +U+0064 +U+0064 Control_d Control_d Control_d Control_d Meta_d Meta_D Meta_d Meta_d Meta_Control_d Meta_Control_d Meta_Control_d Meta_Control_d +U+0044 +U+0064 +U+0044 +U+0044 Control_d Control_d Control_d Control_d Meta_d Meta_D Meta_d Meta_d Meta_Control_d Meta_Control_d Meta_Control_d Meta_Control_d +U+0044 +U+0064 +U+0044 +U+0044 Control_d Control_d Control_d Control_d Meta_d Meta_D Meta_d Meta_d Meta_Control_d Meta_Control_d Meta_Control_d Meta_Control_d +U+0044 +U+0064 +U+0044 +U+0044 Control_d Control_d Control_d Control_d Meta_d Meta_D Meta_d Meta_d Meta_Control_d Meta_Control_d Meta_Control_d Meta_Control_d +U+0044 +U+0064 +U+0044 +U+0044 Control_d Control_d Control_d Control_d Meta_d Meta_D Meta_d Meta_d Meta_Control_d Meta_Control_d Meta_Control_d Meta_Control_d
+keycode 36 = +U+0068 +U+0048 +U+0068 +U+0068 BackSpace BackSpace BackSpace BackSpace Meta_h Meta_H Meta_h Meta_h Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace +U+0068 +U+0048 +U+0068 +U+0068 BackSpace BackSpace BackSpace BackSpace Meta_h Meta_H Meta_h Meta_h Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace +U+0068 +U+0048 +U+0068 +U+0068 BackSpace BackSpace BackSpace BackSpace Meta_h Meta_H Meta_h Meta_h Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace +U+0068 +U+0048 +U+0068 +U+0068 BackSpace BackSpace BackSpace BackSpace Meta_h Meta_H Meta_h Meta_h Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace +U+0048 +U+0068 +U+0048 +U+0048 BackSpace BackSpace BackSpace BackSpace Meta_h Meta_H Meta_h Meta_h Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace +U+0048 +U+0068 +U+0048 +U+0048 BackSpace BackSpace BackSpace BackSpace Meta_h Meta_H Meta_h Meta_h Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace +U+0048 +U+0068 +U+0048 +U+0048 BackSpace BackSpace BackSpace BackSpace Meta_h Meta_H Meta_h Meta_h Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace +U+0048 +U+0068 +U+0048 +U+0048 BackSpace BackSpace BackSpace BackSpace Meta_h Meta_H Meta_h Meta_h Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace
+keycode 37 = +U+0074 +U+0054 +U+0074 +U+0074 Control_t Control_t Control_t Control_t Meta_t Meta_T Meta_t Meta_t Meta_Control_t Meta_Control_t Meta_Control_t Meta_Control_t +U+0074 +U+0054 +U+0074 +U+0074 Control_t Control_t Control_t Control_t Meta_t Meta_T Meta_t Meta_t Meta_Control_t Meta_Control_t Meta_Control_t Meta_Control_t +U+0074 +U+0054 +U+0074 +U+0074 Control_t Control_t Control_t Control_t Meta_t Meta_T Meta_t Meta_t Meta_Control_t Meta_Control_t Meta_Control_t Meta_Control_t +U+0074 +U+0054 +U+0074 +U+0074 Control_t Control_t Control_t Control_t Meta_t Meta_T Meta_t Meta_t Meta_Control_t Meta_Control_t Meta_Control_t Meta_Control_t +U+0054 +U+0074 +U+0054 +U+0054 Control_t Control_t Control_t Control_t Meta_t Meta_T Meta_t Meta_t Meta_Control_t Meta_Control_t Meta_Control_t Meta_Control_t +U+0054 +U+0074 +U+0054 +U+0054 Control_t Control_t Control_t Control_t Meta_t Meta_T Meta_t Meta_t Meta_Control_t Meta_Control_t Meta_Control_t Meta_Control_t +U+0054 +U+0074 +U+0054 +U+0054 Control_t Control_t Control_t Control_t Meta_t Meta_T Meta_t Meta_t Meta_Control_t Meta_Control_t Meta_Control_t Meta_Control_t +U+0054 +U+0074 +U+0054 +U+0054 Control_t Control_t Control_t Control_t Meta_t Meta_T Meta_t Meta_t Meta_Control_t Meta_Control_t Meta_Control_t Meta_Control_t
+keycode 38 = +U+006e +U+004e +U+006e +U+006e Control_n Control_n Control_n Control_n Meta_n Meta_N Meta_n Meta_n Meta_Control_n Meta_Control_n Meta_Control_n Meta_Control_n +U+006e +U+004e +U+006e +U+006e Control_n Control_n Control_n Control_n Meta_n Meta_N Meta_n Meta_n Meta_Control_n Meta_Control_n Meta_Control_n Meta_Control_n +U+006e +U+004e +U+006e +U+006e Control_n Control_n Control_n Control_n Meta_n Meta_N Meta_n Meta_n Meta_Control_n Meta_Control_n Meta_Control_n Meta_Control_n +U+006e +U+004e +U+006e +U+006e Control_n Control_n Control_n Control_n Meta_n Meta_N Meta_n Meta_n Meta_Control_n Meta_Control_n Meta_Control_n Meta_Control_n +U+004e +U+006e +U+004e +U+004e Control_n Control_n Control_n Control_n Meta_n Meta_N Meta_n Meta_n Meta_Control_n Meta_Control_n Meta_Control_n Meta_Control_n +U+004e +U+006e +U+004e +U+004e Control_n Control_n Control_n Control_n Meta_n Meta_N Meta_n Meta_n Meta_Control_n Meta_Control_n Meta_Control_n Meta_Control_n +U+004e +U+006e +U+004e +U+004e Control_n Control_n Control_n Control_n Meta_n Meta_N Meta_n Meta_n Meta_Control_n Meta_Control_n Meta_Control_n Meta_Control_n +U+004e +U+006e +U+004e +U+004e Control_n Control_n Control_n Control_n Meta_n Meta_N Meta_n Meta_n Meta_Control_n Meta_Control_n Meta_Control_n Meta_Control_n
+keycode 39 = +U+0073 +U+0053 +U+0073 +U+0073 Control_s Control_s Control_s Control_s Meta_s Meta_S Meta_s Meta_s Meta_Control_s Meta_Control_s Meta_Control_s Meta_Control_s +U+0073 +U+0053 +U+0073 +U+0073 Control_s Control_s Control_s Control_s Meta_s Meta_S Meta_s Meta_s Meta_Control_s Meta_Control_s Meta_Control_s Meta_Control_s +U+0073 +U+0053 +U+0073 +U+0073 Control_s Control_s Control_s Control_s Meta_s Meta_S Meta_s Meta_s Meta_Control_s Meta_Control_s Meta_Control_s Meta_Control_s +U+0073 +U+0053 +U+0073 +U+0073 Control_s Control_s Control_s Control_s Meta_s Meta_S Meta_s Meta_s Meta_Control_s Meta_Control_s Meta_Control_s Meta_Control_s +U+0053 +U+0073 +U+0053 +U+0053 Control_s Control_s Control_s Control_s Meta_s Meta_S Meta_s Meta_s Meta_Control_s Meta_Control_s Meta_Control_s Meta_Control_s +U+0053 +U+0073 +U+0053 +U+0053 Control_s Control_s Control_s Control_s Meta_s Meta_S Meta_s Meta_s Meta_Control_s Meta_Control_s Meta_Control_s Meta_Control_s +U+0053 +U+0073 +U+0053 +U+0053 Control_s Control_s Control_s Control_s Meta_s Meta_S Meta_s Meta_s Meta_Control_s Meta_Control_s Meta_Control_s Meta_Control_s +U+0053 +U+0073 +U+0053 +U+0053 Control_s Control_s Control_s Control_s Meta_s Meta_S Meta_s Meta_s Meta_Control_s Meta_Control_s Meta_Control_s Meta_Control_s
+keycode 40 = U+002d U+005f U+002d U+002d Control_underscore Control_underscore Control_underscore Control_underscore Meta_minus Meta_underscore Meta_minus Meta_minus Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+002d U+005f U+002d U+002d Control_underscore Control_underscore Control_underscore Control_underscore Meta_minus Meta_underscore Meta_minus Meta_minus Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+002d U+005f U+002d U+002d Control_underscore Control_underscore Control_underscore Control_underscore Meta_minus Meta_underscore Meta_minus Meta_minus Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+002d U+005f U+002d U+002d Control_underscore Control_underscore Control_underscore Control_underscore Meta_minus Meta_underscore Meta_minus Meta_minus Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+002d U+005f U+002d U+002d Control_underscore Control_underscore Control_underscore Control_underscore Meta_minus Meta_underscore Meta_minus Meta_minus Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+002d U+005f U+002d U+002d Control_underscore Control_underscore Control_underscore Control_underscore Meta_minus Meta_underscore Meta_minus Meta_minus Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+002d U+005f U+002d U+002d Control_underscore Control_underscore Control_underscore Control_underscore Meta_minus Meta_underscore Meta_minus Meta_minus Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+002d U+005f U+002d U+002d Control_underscore Control_underscore Control_underscore Control_underscore Meta_minus Meta_underscore Meta_minus Meta_minus Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore
+keycode 41 = U+0060 U+00ac dead_grave dead_tilde nul nul dead_grave dead_tilde Meta_grave Meta_asciitilde dead_grave dead_tilde Meta_nul Meta_nul dead_grave dead_tilde U+0060 U+00ac dead_grave dead_tilde nul nul dead_grave dead_tilde Meta_grave Meta_asciitilde dead_grave dead_tilde Meta_nul Meta_nul dead_grave dead_tilde U+0060 U+00ac dead_grave dead_tilde nul nul dead_grave dead_tilde Meta_grave Meta_asciitilde dead_grave dead_tilde Meta_nul Meta_nul dead_grave dead_tilde U+0060 U+00ac dead_grave dead_tilde nul nul dead_grave dead_tilde Meta_grave Meta_asciitilde dead_grave dead_tilde Meta_nul Meta_nul dead_grave dead_tilde U+0060 U+00ac dead_grave dead_tilde nul nul dead_grave dead_tilde Meta_grave Meta_asciitilde dead_grave dead_tilde Meta_nul Meta_nul dead_grave dead_tilde U+0060 U+00ac dead_grave dead_tilde nul nul dead_grave dead_tilde Meta_grave Meta_asciitilde dead_grave dead_tilde Meta_nul Meta_nul dead_grave dead_tilde U+0060 U+00ac dead_grave dead_tilde nul nul dead_grave dead_tilde Meta_grave Meta_asciitilde dead_grave dead_tilde Meta_nul Meta_nul dead_grave dead_tilde U+0060 U+00ac dead_grave dead_tilde nul nul dead_grave dead_tilde Meta_grave Meta_asciitilde dead_grave dead_tilde Meta_nul Meta_nul dead_grave dead_tilde
+keycode 42 = Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift
+keycode 43 = U+0023 U+007e U+005c U+005c Control_backslash Control_backslash Control_backslash Control_backslash Meta_backslash Meta_bar Meta_backslash Meta_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+0023 U+007e U+005c U+005c Control_backslash Control_backslash Control_backslash Control_backslash Meta_backslash Meta_bar Meta_backslash Meta_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+0023 U+007e U+005c U+005c Control_backslash Control_backslash Control_backslash Control_backslash Meta_backslash Meta_bar Meta_backslash Meta_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+0023 U+007e U+005c U+005c Control_backslash Control_backslash Control_backslash Control_backslash Meta_backslash Meta_bar Meta_backslash Meta_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+0023 U+007e U+005c U+005c Control_backslash Control_backslash Control_backslash Control_backslash Meta_backslash Meta_bar Meta_backslash Meta_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+0023 U+007e U+005c U+005c Control_backslash Control_backslash Control_backslash Control_backslash Meta_backslash Meta_bar Meta_backslash Meta_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+0023 U+007e U+005c U+005c Control_backslash Control_backslash Control_backslash Control_backslash Meta_backslash Meta_bar Meta_backslash Meta_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+0023 U+007e U+005c U+005c Control_backslash Control_backslash Control_backslash Control_backslash Meta_backslash Meta_bar Meta_backslash Meta_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash
+keycode 44 = U+003b U+003a dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute Meta_semicolon Meta_colon dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute U+003b U+003a dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute Meta_semicolon Meta_colon dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute U+003b U+003a dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute Meta_semicolon Meta_colon dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute U+003b U+003a dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute Meta_semicolon Meta_colon dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute U+003b U+003a dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute Meta_semicolon Meta_colon dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute U+003b U+003a dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute Meta_semicolon Meta_colon dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute U+003b U+003a dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute Meta_semicolon Meta_colon dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute U+003b U+003a dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute Meta_semicolon Meta_colon dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute
+keycode 45 = +U+0071 +U+0051 +U+0071 +U+0071 Control_q Control_q Control_q Control_q Meta_q Meta_Q Meta_q Meta_q Meta_Control_q Meta_Control_q Meta_Control_q Meta_Control_q +U+0071 +U+0051 +U+0071 +U+0071 Control_q Control_q Control_q Control_q Meta_q Meta_Q Meta_q Meta_q Meta_Control_q Meta_Control_q Meta_Control_q Meta_Control_q +U+0071 +U+0051 +U+0071 +U+0071 Control_q Control_q Control_q Control_q Meta_q Meta_Q Meta_q Meta_q Meta_Control_q Meta_Control_q Meta_Control_q Meta_Control_q +U+0071 +U+0051 +U+0071 +U+0071 Control_q Control_q Control_q Control_q Meta_q Meta_Q Meta_q Meta_q Meta_Control_q Meta_Control_q Meta_Control_q Meta_Control_q +U+0051 +U+0071 +U+0051 +U+0051 Control_q Control_q Control_q Control_q Meta_q Meta_Q Meta_q Meta_q Meta_Control_q Meta_Control_q Meta_Control_q Meta_Control_q +U+0051 +U+0071 +U+0051 +U+0051 Control_q Control_q Control_q Control_q Meta_q Meta_Q Meta_q Meta_q Meta_Control_q Meta_Control_q Meta_Control_q Meta_Control_q +U+0051 +U+0071 +U+0051 +U+0051 Control_q Control_q Control_q Control_q Meta_q Meta_Q Meta_q Meta_q Meta_Control_q Meta_Control_q Meta_Control_q Meta_Control_q +U+0051 +U+0071 +U+0051 +U+0051 Control_q Control_q Control_q Control_q Meta_q Meta_Q Meta_q Meta_q Meta_Control_q Meta_Control_q Meta_Control_q Meta_Control_q
+keycode 46 = +U+006a +U+004a +U+006a +U+006a Linefeed Linefeed Linefeed Linefeed Meta_j Meta_J Meta_j Meta_j Meta_Linefeed Meta_Linefeed Meta_Linefeed Meta_Linefeed +U+006a +U+004a +U+006a +U+006a Linefeed Linefeed Linefeed Linefeed Meta_j Meta_J Meta_j Meta_j Meta_Linefeed Meta_Linefeed Meta_Linefeed Meta_Linefeed +U+006a +U+004a +U+006a +U+006a Linefeed Linefeed Linefeed Linefeed Meta_j Meta_J Meta_j Meta_j Meta_Linefeed Meta_Linefeed Meta_Linefeed Meta_Linefeed +U+006a +U+004a +U+006a +U+006a Linefeed Linefeed Linefeed Linefeed Meta_j Meta_J Meta_j Meta_j Meta_Linefeed Meta_Linefeed Meta_Linefeed Meta_Linefeed +U+004a +U+006a +U+004a +U+004a Linefeed Linefeed Linefeed Linefeed Meta_j Meta_J Meta_j Meta_j Meta_Linefeed Meta_Linefeed Meta_Linefeed Meta_Linefeed +U+004a +U+006a +U+004a +U+004a Linefeed Linefeed Linefeed Linefeed Meta_j Meta_J Meta_j Meta_j Meta_Linefeed Meta_Linefeed Meta_Linefeed Meta_Linefeed +U+004a +U+006a +U+004a +U+004a Linefeed Linefeed Linefeed Linefeed Meta_j Meta_J Meta_j Meta_j Meta_Linefeed Meta_Linefeed Meta_Linefeed Meta_Linefeed +U+004a +U+006a +U+004a +U+004a Linefeed Linefeed Linefeed Linefeed Meta_j Meta_J Meta_j Meta_j Meta_Linefeed Meta_Linefeed Meta_Linefeed Meta_Linefeed
+keycode 47 = +U+006b +U+004b +U+006b +U+006b Control_k Control_k Control_k Control_k Meta_k Meta_K Meta_k Meta_k Meta_Control_k Meta_Control_k Meta_Control_k Meta_Control_k +U+006b +U+004b +U+006b +U+006b Control_k Control_k Control_k Control_k Meta_k Meta_K Meta_k Meta_k Meta_Control_k Meta_Control_k Meta_Control_k Meta_Control_k +U+006b +U+004b +U+006b +U+006b Control_k Control_k Control_k Control_k Meta_k Meta_K Meta_k Meta_k Meta_Control_k Meta_Control_k Meta_Control_k Meta_Control_k +U+006b +U+004b +U+006b +U+006b Control_k Control_k Control_k Control_k Meta_k Meta_K Meta_k Meta_k Meta_Control_k Meta_Control_k Meta_Control_k Meta_Control_k +U+004b +U+006b +U+004b +U+004b Control_k Control_k Control_k Control_k Meta_k Meta_K Meta_k Meta_k Meta_Control_k Meta_Control_k Meta_Control_k Meta_Control_k +U+004b +U+006b +U+004b +U+004b Control_k Control_k Control_k Control_k Meta_k Meta_K Meta_k Meta_k Meta_Control_k Meta_Control_k Meta_Control_k Meta_Control_k +U+004b +U+006b +U+004b +U+004b Control_k Control_k Control_k Control_k Meta_k Meta_K Meta_k Meta_k Meta_Control_k Meta_Control_k Meta_Control_k Meta_Control_k +U+004b +U+006b +U+004b +U+004b Control_k Control_k Control_k Control_k Meta_k Meta_K Meta_k Meta_k Meta_Control_k Meta_Control_k Meta_Control_k Meta_Control_k
+keycode 48 = +U+0078 +U+0058 +U+0078 +U+0078 Control_x Control_x Control_x Control_x Meta_x Meta_X Meta_x Meta_x Meta_Control_x Meta_Control_x Meta_Control_x Meta_Control_x +U+0078 +U+0058 +U+0078 +U+0078 Control_x Control_x Control_x Control_x Meta_x Meta_X Meta_x Meta_x Meta_Control_x Meta_Control_x Meta_Control_x Meta_Control_x +U+0078 +U+0058 +U+0078 +U+0078 Control_x Control_x Control_x Control_x Meta_x Meta_X Meta_x Meta_x Meta_Control_x Meta_Control_x Meta_Control_x Meta_Control_x +U+0078 +U+0058 +U+0078 +U+0078 Control_x Control_x Control_x Control_x Meta_x Meta_X Meta_x Meta_x Meta_Control_x Meta_Control_x Meta_Control_x Meta_Control_x +U+0058 +U+0078 +U+0058 +U+0058 Control_x Control_x Control_x Control_x Meta_x Meta_X Meta_x Meta_x Meta_Control_x Meta_Control_x Meta_Control_x Meta_Control_x +U+0058 +U+0078 +U+0058 +U+0058 Control_x Control_x Control_x Control_x Meta_x Meta_X Meta_x Meta_x Meta_Control_x Meta_Control_x Meta_Control_x Meta_Control_x +U+0058 +U+0078 +U+0058 +U+0058 Control_x Control_x Control_x Control_x Meta_x Meta_X Meta_x Meta_x Meta_Control_x Meta_Control_x Meta_Control_x Meta_Control_x +U+0058 +U+0078 +U+0058 +U+0058 Control_x Control_x Control_x Control_x Meta_x Meta_X Meta_x Meta_x Meta_Control_x Meta_Control_x Meta_Control_x Meta_Control_x
+keycode 49 = +U+0062 +U+0042 +U+0062 +U+0062 Control_b Control_b Control_b Control_b Meta_b Meta_B Meta_b Meta_b Meta_Control_b Meta_Control_b Meta_Control_b Meta_Control_b +U+0062 +U+0042 +U+0062 +U+0062 Control_b Control_b Control_b Control_b Meta_b Meta_B Meta_b Meta_b Meta_Control_b Meta_Control_b Meta_Control_b Meta_Control_b +U+0062 +U+0042 +U+0062 +U+0062 Control_b Control_b Control_b Control_b Meta_b Meta_B Meta_b Meta_b Meta_Control_b Meta_Control_b Meta_Control_b Meta_Control_b +U+0062 +U+0042 +U+0062 +U+0062 Control_b Control_b Control_b Control_b Meta_b Meta_B Meta_b Meta_b Meta_Control_b Meta_Control_b Meta_Control_b Meta_Control_b +U+0042 +U+0062 +U+0042 +U+0042 Control_b Control_b Control_b Control_b Meta_b Meta_B Meta_b Meta_b Meta_Control_b Meta_Control_b Meta_Control_b Meta_Control_b +U+0042 +U+0062 +U+0042 +U+0042 Control_b Control_b Control_b Control_b Meta_b Meta_B Meta_b Meta_b Meta_Control_b Meta_Control_b Meta_Control_b Meta_Control_b +U+0042 +U+0062 +U+0042 +U+0042 Control_b Control_b Control_b Control_b Meta_b Meta_B Meta_b Meta_b Meta_Control_b Meta_Control_b Meta_Control_b Meta_Control_b +U+0042 +U+0062 +U+0042 +U+0042 Control_b Control_b Control_b Control_b Meta_b Meta_B Meta_b Meta_b Meta_Control_b Meta_Control_b Meta_Control_b Meta_Control_b
+keycode 50 = +U+006d +U+004d +U+006d +U+006d Control_m Control_m Control_m Control_m Meta_m Meta_M Meta_m Meta_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m +U+006d +U+004d +U+006d +U+006d Control_m Control_m Control_m Control_m Meta_m Meta_M Meta_m Meta_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m +U+006d +U+004d +U+006d +U+006d Control_m Control_m Control_m Control_m Meta_m Meta_M Meta_m Meta_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m +U+006d +U+004d +U+006d +U+006d Control_m Control_m Control_m Control_m Meta_m Meta_M Meta_m Meta_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m +U+004d +U+006d +U+004d +U+004d Control_m Control_m Control_m Control_m Meta_m Meta_M Meta_m Meta_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m +U+004d +U+006d +U+004d +U+004d Control_m Control_m Control_m Control_m Meta_m Meta_M Meta_m Meta_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m +U+004d +U+006d +U+004d +U+004d Control_m Control_m Control_m Control_m Meta_m Meta_M Meta_m Meta_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m +U+004d +U+006d +U+004d +U+004d Control_m Control_m Control_m Control_m Meta_m Meta_M Meta_m Meta_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m
+keycode 51 = +U+0077 +U+0057 +U+0077 +U+0077 Control_w Control_w Control_w Control_w Meta_w Meta_W Meta_w Meta_w Meta_Control_w Meta_Control_w Meta_Control_w Meta_Control_w +U+0077 +U+0057 +U+0077 +U+0077 Control_w Control_w Control_w Control_w Meta_w Meta_W Meta_w Meta_w Meta_Control_w Meta_Control_w Meta_Control_w Meta_Control_w +U+0077 +U+0057 +U+0077 +U+0077 Control_w Control_w Control_w Control_w Meta_w Meta_W Meta_w Meta_w Meta_Control_w Meta_Control_w Meta_Control_w Meta_Control_w +U+0077 +U+0057 +U+0077 +U+0077 Control_w Control_w Control_w Control_w Meta_w Meta_W Meta_w Meta_w Meta_Control_w Meta_Control_w Meta_Control_w Meta_Control_w +U+0057 +U+0077 +U+0057 +U+0057 Control_w Control_w Control_w Control_w Meta_w Meta_W Meta_w Meta_w Meta_Control_w Meta_Control_w Meta_Control_w Meta_Control_w +U+0057 +U+0077 +U+0057 +U+0057 Control_w Control_w Control_w Control_w Meta_w Meta_W Meta_w Meta_w Meta_Control_w Meta_Control_w Meta_Control_w Meta_Control_w +U+0057 +U+0077 +U+0057 +U+0057 Control_w Control_w Control_w Control_w Meta_w Meta_W Meta_w Meta_w Meta_Control_w Meta_Control_w Meta_Control_w Meta_Control_w +U+0057 +U+0077 +U+0057 +U+0057 Control_w Control_w Control_w Control_w Meta_w Meta_W Meta_w Meta_w Meta_Control_w Meta_Control_w Meta_Control_w Meta_Control_w
+keycode 52 = +U+0076 +U+0056 +U+0076 +U+0076 Control_v Control_v Control_v Control_v Meta_v Meta_V Meta_v Meta_v Meta_Control_v Meta_Control_v Meta_Control_v Meta_Control_v +U+0076 +U+0056 +U+0076 +U+0076 Control_v Control_v Control_v Control_v Meta_v Meta_V Meta_v Meta_v Meta_Control_v Meta_Control_v Meta_Control_v Meta_Control_v +U+0076 +U+0056 +U+0076 +U+0076 Control_v Control_v Control_v Control_v Meta_v Meta_V Meta_v Meta_v Meta_Control_v Meta_Control_v Meta_Control_v Meta_Control_v +U+0076 +U+0056 +U+0076 +U+0076 Control_v Control_v Control_v Control_v Meta_v Meta_V Meta_v Meta_v Meta_Control_v Meta_Control_v Meta_Control_v Meta_Control_v +U+0056 +U+0076 +U+0056 +U+0056 Control_v Control_v Control_v Control_v Meta_v Meta_V Meta_v Meta_v Meta_Control_v Meta_Control_v Meta_Control_v Meta_Control_v +U+0056 +U+0076 +U+0056 +U+0056 Control_v Control_v Control_v Control_v Meta_v Meta_V Meta_v Meta_v Meta_Control_v Meta_Control_v Meta_Control_v Meta_Control_v +U+0056 +U+0076 +U+0056 +U+0056 Control_v Control_v Control_v Control_v Meta_v Meta_V Meta_v Meta_v Meta_Control_v Meta_Control_v Meta_Control_v Meta_Control_v +U+0056 +U+0076 +U+0056 +U+0056 Control_v Control_v Control_v Control_v Meta_v Meta_V Meta_v Meta_v Meta_Control_v Meta_Control_v Meta_Control_v Meta_Control_v
+keycode 53 = +U+007a +U+005a +U+007a +U+007a Control_z Control_z Control_z Control_z Meta_z Meta_Z Meta_z Meta_z Meta_Control_z Meta_Control_z Meta_Control_z Meta_Control_z +U+007a +U+005a +U+007a +U+007a Control_z Control_z Control_z Control_z Meta_z Meta_Z Meta_z Meta_z Meta_Control_z Meta_Control_z Meta_Control_z Meta_Control_z +U+007a +U+005a +U+007a +U+007a Control_z Control_z Control_z Control_z Meta_z Meta_Z Meta_z Meta_z Meta_Control_z Meta_Control_z Meta_Control_z Meta_Control_z +U+007a +U+005a +U+007a +U+007a Control_z Control_z Control_z Control_z Meta_z Meta_Z Meta_z Meta_z Meta_Control_z Meta_Control_z Meta_Control_z Meta_Control_z +U+005a +U+007a +U+005a +U+005a Control_z Control_z Control_z Control_z Meta_z Meta_Z Meta_z Meta_z Meta_Control_z Meta_Control_z Meta_Control_z Meta_Control_z +U+005a +U+007a +U+005a +U+005a Control_z Control_z Control_z Control_z Meta_z Meta_Z Meta_z Meta_z Meta_Control_z Meta_Control_z Meta_Control_z Meta_Control_z +U+005a +U+007a +U+005a +U+005a Control_z Control_z Control_z Control_z Meta_z Meta_Z Meta_z Meta_z Meta_Control_z Meta_Control_z Meta_Control_z Meta_Control_z +U+005a +U+007a +U+005a +U+005a Control_z Control_z Control_z Control_z Meta_z Meta_Z Meta_z Meta_z Meta_Control_z Meta_Control_z Meta_Control_z Meta_Control_z
+keycode 54 = Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift
+keycode 55 = KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply
+keycode 56 = Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt
+keycode 57 = U+0020 U+0020 U+0020 U+0020 nul nul nul nul Meta_space Meta_space Meta_space Meta_space Meta_nul Meta_nul Meta_nul Meta_nul U+0020 U+0020 U+0020 U+0020 nul nul nul nul Meta_space Meta_space Meta_space Meta_space Meta_nul Meta_nul Meta_nul Meta_nul U+0020 U+0020 U+0020 U+0020 nul nul nul nul Meta_space Meta_space Meta_space Meta_space Meta_nul Meta_nul Meta_nul Meta_nul U+0020 U+0020 U+0020 U+0020 nul nul nul nul Meta_space Meta_space Meta_space Meta_space Meta_nul Meta_nul Meta_nul Meta_nul U+0020 U+0020 U+0020 U+0020 nul nul nul nul Meta_space Meta_space Meta_space Meta_space Meta_nul Meta_nul Meta_nul Meta_nul U+0020 U+0020 U+0020 U+0020 nul nul nul nul Meta_space Meta_space Meta_space Meta_space Meta_nul Meta_nul Meta_nul Meta_nul U+0020 U+0020 U+0020 U+0020 nul nul nul nul Meta_space Meta_space Meta_space Meta_space Meta_nul Meta_nul Meta_nul Meta_nul U+0020 U+0020 U+0020 U+0020 nul nul nul nul Meta_space Meta_space Meta_space Meta_space Meta_nul Meta_nul Meta_nul Meta_nul
+keycode 58 = CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock
+keycode 59 = F1 F13 Console_13 Console_25 F25 F37 Console_13 Console_25 Console_1 Console_13 F1 F1 Console_1 Console_13 F1 F1 F1 F13 Console_13 Console_25 F25 F37 Console_13 Console_25 Console_1 Console_13 F1 F1 Console_1 Console_13 F1 F1 F1 F13 Console_13 Console_25 F25 F37 Console_13 Console_25 Console_1 Console_13 F1 F1 Console_1 Console_13 F1 F1 F1 F13 Console_13 Console_25 F25 F37 Console_13 Console_25 Console_1 Console_13 F1 F1 Console_1 Console_13 F1 F1 F1 F13 Console_13 Console_25 F25 F37 Console_13 Console_25 Console_1 Console_13 F1 F1 Console_1 Console_13 F1 F1 F1 F13 Console_13 Console_25 F25 F37 Console_13 Console_25 Console_1 Console_13 F1 F1 Console_1 Console_13 F1 F1 F1 F13 Console_13 Console_25 F25 F37 Console_13 Console_25 Console_1 Console_13 F1 F1 Console_1 Console_13 F1 F1 F1 F13 Console_13 Console_25 F25 F37 Console_13 Console_25 Console_1 Console_13 F1 F1 Console_1 Console_13 F1 F1
+keycode 60 = F2 F14 Console_14 Console_26 F26 F38 Console_14 Console_26 Console_2 Console_14 F2 F2 Console_2 Console_14 F2 F2 F2 F14 Console_14 Console_26 F26 F38 Console_14 Console_26 Console_2 Console_14 F2 F2 Console_2 Console_14 F2 F2 F2 F14 Console_14 Console_26 F26 F38 Console_14 Console_26 Console_2 Console_14 F2 F2 Console_2 Console_14 F2 F2 F2 F14 Console_14 Console_26 F26 F38 Console_14 Console_26 Console_2 Console_14 F2 F2 Console_2 Console_14 F2 F2 F2 F14 Console_14 Console_26 F26 F38 Console_14 Console_26 Console_2 Console_14 F2 F2 Console_2 Console_14 F2 F2 F2 F14 Console_14 Console_26 F26 F38 Console_14 Console_26 Console_2 Console_14 F2 F2 Console_2 Console_14 F2 F2 F2 F14 Console_14 Console_26 F26 F38 Console_14 Console_26 Console_2 Console_14 F2 F2 Console_2 Console_14 F2 F2 F2 F14 Console_14 Console_26 F26 F38 Console_14 Console_26 Console_2 Console_14 F2 F2 Console_2 Console_14 F2 F2
+keycode 61 = F3 F15 Console_15 Console_27 F27 F39 Console_15 Console_27 Console_3 Console_15 F3 F3 Console_3 Console_15 F3 F3 F3 F15 Console_15 Console_27 F27 F39 Console_15 Console_27 Console_3 Console_15 F3 F3 Console_3 Console_15 F3 F3 F3 F15 Console_15 Console_27 F27 F39 Console_15 Console_27 Console_3 Console_15 F3 F3 Console_3 Console_15 F3 F3 F3 F15 Console_15 Console_27 F27 F39 Console_15 Console_27 Console_3 Console_15 F3 F3 Console_3 Console_15 F3 F3 F3 F15 Console_15 Console_27 F27 F39 Console_15 Console_27 Console_3 Console_15 F3 F3 Console_3 Console_15 F3 F3 F3 F15 Console_15 Console_27 F27 F39 Console_15 Console_27 Console_3 Console_15 F3 F3 Console_3 Console_15 F3 F3 F3 F15 Console_15 Console_27 F27 F39 Console_15 Console_27 Console_3 Console_15 F3 F3 Console_3 Console_15 F3 F3 F3 F15 Console_15 Console_27 F27 F39 Console_15 Console_27 Console_3 Console_15 F3 F3 Console_3 Console_15 F3 F3
+keycode 62 = F4 F16 Console_16 Console_28 F28 F40 Console_16 Console_28 Console_4 Console_16 F4 F4 Console_4 Console_16 F4 F4 F4 F16 Console_16 Console_28 F28 F40 Console_16 Console_28 Console_4 Console_16 F4 F4 Console_4 Console_16 F4 F4 F4 F16 Console_16 Console_28 F28 F40 Console_16 Console_28 Console_4 Console_16 F4 F4 Console_4 Console_16 F4 F4 F4 F16 Console_16 Console_28 F28 F40 Console_16 Console_28 Console_4 Console_16 F4 F4 Console_4 Console_16 F4 F4 F4 F16 Console_16 Console_28 F28 F40 Console_16 Console_28 Console_4 Console_16 F4 F4 Console_4 Console_16 F4 F4 F4 F16 Console_16 Console_28 F28 F40 Console_16 Console_28 Console_4 Console_16 F4 F4 Console_4 Console_16 F4 F4 F4 F16 Console_16 Console_28 F28 F40 Console_16 Console_28 Console_4 Console_16 F4 F4 Console_4 Console_16 F4 F4 F4 F16 Console_16 Console_28 F28 F40 Console_16 Console_28 Console_4 Console_16 F4 F4 Console_4 Console_16 F4 F4
+keycode 63 = F5 F17 Console_17 Console_29 F29 F41 Console_17 Console_29 Console_5 Console_17 F5 F5 Console_5 Console_17 F5 F5 F5 F17 Console_17 Console_29 F29 F41 Console_17 Console_29 Console_5 Console_17 F5 F5 Console_5 Console_17 F5 F5 F5 F17 Console_17 Console_29 F29 F41 Console_17 Console_29 Console_5 Console_17 F5 F5 Console_5 Console_17 F5 F5 F5 F17 Console_17 Console_29 F29 F41 Console_17 Console_29 Console_5 Console_17 F5 F5 Console_5 Console_17 F5 F5 F5 F17 Console_17 Console_29 F29 F41 Console_17 Console_29 Console_5 Console_17 F5 F5 Console_5 Console_17 F5 F5 F5 F17 Console_17 Console_29 F29 F41 Console_17 Console_29 Console_5 Console_17 F5 F5 Console_5 Console_17 F5 F5 F5 F17 Console_17 Console_29 F29 F41 Console_17 Console_29 Console_5 Console_17 F5 F5 Console_5 Console_17 F5 F5 F5 F17 Console_17 Console_29 F29 F41 Console_17 Console_29 Console_5 Console_17 F5 F5 Console_5 Console_17 F5 F5
+keycode 64 = F6 F18 Console_18 Console_30 F30 F42 Console_18 Console_30 Console_6 Console_18 F6 F6 Console_6 Console_18 F6 F6 F6 F18 Console_18 Console_30 F30 F42 Console_18 Console_30 Console_6 Console_18 F6 F6 Console_6 Console_18 F6 F6 F6 F18 Console_18 Console_30 F30 F42 Console_18 Console_30 Console_6 Console_18 F6 F6 Console_6 Console_18 F6 F6 F6 F18 Console_18 Console_30 F30 F42 Console_18 Console_30 Console_6 Console_18 F6 F6 Console_6 Console_18 F6 F6 F6 F18 Console_18 Console_30 F30 F42 Console_18 Console_30 Console_6 Console_18 F6 F6 Console_6 Console_18 F6 F6 F6 F18 Console_18 Console_30 F30 F42 Console_18 Console_30 Console_6 Console_18 F6 F6 Console_6 Console_18 F6 F6 F6 F18 Console_18 Console_30 F30 F42 Console_18 Console_30 Console_6 Console_18 F6 F6 Console_6 Console_18 F6 F6 F6 F18 Console_18 Console_30 F30 F42 Console_18 Console_30 Console_6 Console_18 F6 F6 Console_6 Console_18 F6 F6
+keycode 65 = F7 F19 Console_19 Console_31 F31 F43 Console_19 Console_31 Console_7 Console_19 F7 F7 Console_7 Console_19 F7 F7 F7 F19 Console_19 Console_31 F31 F43 Console_19 Console_31 Console_7 Console_19 F7 F7 Console_7 Console_19 F7 F7 F7 F19 Console_19 Console_31 F31 F43 Console_19 Console_31 Console_7 Console_19 F7 F7 Console_7 Console_19 F7 F7 F7 F19 Console_19 Console_31 F31 F43 Console_19 Console_31 Console_7 Console_19 F7 F7 Console_7 Console_19 F7 F7 F7 F19 Console_19 Console_31 F31 F43 Console_19 Console_31 Console_7 Console_19 F7 F7 Console_7 Console_19 F7 F7 F7 F19 Console_19 Console_31 F31 F43 Console_19 Console_31 Console_7 Console_19 F7 F7 Console_7 Console_19 F7 F7 F7 F19 Console_19 Console_31 F31 F43 Console_19 Console_31 Console_7 Console_19 F7 F7 Console_7 Console_19 F7 F7 F7 F19 Console_19 Console_31 F31 F43 Console_19 Console_31 Console_7 Console_19 F7 F7 Console_7 Console_19 F7 F7
+keycode 66 = F8 F20 Console_20 Console_32 F32 F44 Console_20 Console_32 Console_8 Console_20 F8 F8 Console_8 Console_20 F8 F8 F8 F20 Console_20 Console_32 F32 F44 Console_20 Console_32 Console_8 Console_20 F8 F8 Console_8 Console_20 F8 F8 F8 F20 Console_20 Console_32 F32 F44 Console_20 Console_32 Console_8 Console_20 F8 F8 Console_8 Console_20 F8 F8 F8 F20 Console_20 Console_32 F32 F44 Console_20 Console_32 Console_8 Console_20 F8 F8 Console_8 Console_20 F8 F8 F8 F20 Console_20 Console_32 F32 F44 Console_20 Console_32 Console_8 Console_20 F8 F8 Console_8 Console_20 F8 F8 F8 F20 Console_20 Console_32 F32 F44 Console_20 Console_32 Console_8 Console_20 F8 F8 Console_8 Console_20 F8 F8 F8 F20 Console_20 Console_32 F32 F44 Console_20 Console_32 Console_8 Console_20 F8 F8 Console_8 Console_20 F8 F8 F8 F20 Console_20 Console_32 F32 F44 Console_20 Console_32 Console_8 Console_20 F8 F8 Console_8 Console_20 F8 F8
+keycode 67 = F9 F21 Console_21 Console_33 F33 F45 Console_21 Console_33 Console_9 Console_21 F9 F9 Console_9 Console_21 F9 F9 F9 F21 Console_21 Console_33 F33 F45 Console_21 Console_33 Console_9 Console_21 F9 F9 Console_9 Console_21 F9 F9 F9 F21 Console_21 Console_33 F33 F45 Console_21 Console_33 Console_9 Console_21 F9 F9 Console_9 Console_21 F9 F9 F9 F21 Console_21 Console_33 F33 F45 Console_21 Console_33 Console_9 Console_21 F9 F9 Console_9 Console_21 F9 F9 F9 F21 Console_21 Console_33 F33 F45 Console_21 Console_33 Console_9 Console_21 F9 F9 Console_9 Console_21 F9 F9 F9 F21 Console_21 Console_33 F33 F45 Console_21 Console_33 Console_9 Console_21 F9 F9 Console_9 Console_21 F9 F9 F9 F21 Console_21 Console_33 F33 F45 Console_21 Console_33 Console_9 Console_21 F9 F9 Console_9 Console_21 F9 F9 F9 F21 Console_21 Console_33 F33 F45 Console_21 Console_33 Console_9 Console_21 F9 F9 Console_9 Console_21 F9 F9
+keycode 68 = F10 F22 Console_22 Console_34 F34 F46 Console_22 Console_34 Console_10 Console_22 F10 F10 Console_10 Console_22 F10 F10 F10 F22 Console_22 Console_34 F34 F46 Console_22 Console_34 Console_10 Console_22 F10 F10 Console_10 Console_22 F10 F10 F10 F22 Console_22 Console_34 F34 F46 Console_22 Console_34 Console_10 Console_22 F10 F10 Console_10 Console_22 F10 F10 F10 F22 Console_22 Console_34 F34 F46 Console_22 Console_34 Console_10 Console_22 F10 F10 Console_10 Console_22 F10 F10 F10 F22 Console_22 Console_34 F34 F46 Console_22 Console_34 Console_10 Console_22 F10 F10 Console_10 Console_22 F10 F10 F10 F22 Console_22 Console_34 F34 F46 Console_22 Console_34 Console_10 Console_22 F10 F10 Console_10 Console_22 F10 F10 F10 F22 Console_22 Console_34 F34 F46 Console_22 Console_34 Console_10 Console_22 F10 F10 Console_10 Console_22 F10 F10 F10 F22 Console_22 Console_34 F34 F46 Console_22 Console_34 Console_10 Console_22 F10 F10 Console_10 Console_22 F10 F10
+keycode 69 = Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock
+keycode 70 = Scroll_Lock Show_Memory Show_Registers Scroll_Lock Show_State Scroll_Lock Scroll_Lock Scroll_Lock Show_Registers Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Show_Memory Show_Registers Scroll_Lock Show_State Scroll_Lock Scroll_Lock Scroll_Lock Show_Registers Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Show_Memory Show_Registers Scroll_Lock Show_State Scroll_Lock Scroll_Lock Scroll_Lock Show_Registers Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Show_Memory Show_Registers Scroll_Lock Show_State Scroll_Lock Scroll_Lock Scroll_Lock Show_Registers Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Show_Memory Show_Registers Scroll_Lock Show_State Scroll_Lock Scroll_Lock Scroll_Lock Show_Registers Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Show_Memory Show_Registers Scroll_Lock Show_State Scroll_Lock Scroll_Lock Scroll_Lock Show_Registers Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Show_Memory Show_Registers Scroll_Lock Show_State Scroll_Lock Scroll_Lock Scroll_Lock Show_Registers Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Show_Memory Show_Registers Scroll_Lock Show_State Scroll_Lock Scroll_Lock Scroll_Lock Show_Registers Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock
+keycode 71 = KP_7 KP_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 Ascii_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 Ascii_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 Ascii_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 Ascii_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 Ascii_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 Ascii_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 Ascii_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 Ascii_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7
+keycode 72 = KP_8 KP_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 Ascii_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 Ascii_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 Ascii_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 Ascii_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 Ascii_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 Ascii_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 Ascii_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 Ascii_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8
+keycode 73 = KP_9 KP_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 Ascii_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 Ascii_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 Ascii_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 Ascii_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 Ascii_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 Ascii_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 Ascii_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 Ascii_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9
+keycode 74 = KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract
+keycode 75 = KP_4 KP_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 Ascii_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 Ascii_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 Ascii_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 Ascii_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 Ascii_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 Ascii_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 Ascii_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 Ascii_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4
+keycode 76 = KP_5 KP_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 Ascii_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 Ascii_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 Ascii_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 Ascii_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 Ascii_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 Ascii_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 Ascii_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 Ascii_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5
+keycode 77 = KP_6 KP_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 Ascii_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 Ascii_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 Ascii_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 Ascii_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 Ascii_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 Ascii_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 Ascii_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 Ascii_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6
+keycode 78 = KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add
+keycode 79 = KP_1 KP_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 Ascii_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 Ascii_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 Ascii_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 Ascii_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 Ascii_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 Ascii_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 Ascii_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 Ascii_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1
+keycode 80 = KP_2 KP_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 Ascii_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 Ascii_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 Ascii_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 Ascii_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 Ascii_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 Ascii_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 Ascii_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 Ascii_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2
+keycode 81 = KP_3 KP_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 Ascii_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 Ascii_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 Ascii_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 Ascii_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 Ascii_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 Ascii_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 Ascii_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 Ascii_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3
+keycode 82 = KP_0 KP_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 Ascii_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 Ascii_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 Ascii_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 Ascii_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 Ascii_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 Ascii_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 Ascii_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 Ascii_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0
+keycode 83 = KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period Boot KP_Period
+keycode 86 = U+005c U+007c U+007c U+00a6 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_less Meta_greater Meta_bar Meta_bar VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+005c U+007c U+007c U+00a6 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_less Meta_greater Meta_bar Meta_bar VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+005c U+007c U+007c U+00a6 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_less Meta_greater Meta_bar Meta_bar VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+005c U+007c U+007c U+00a6 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_less Meta_greater Meta_bar Meta_bar VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+005c U+007c U+007c U+00a6 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_less Meta_greater Meta_bar Meta_bar VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+005c U+007c U+007c U+00a6 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_less Meta_greater Meta_bar Meta_bar VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+005c U+007c U+007c U+00a6 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_less Meta_greater Meta_bar Meta_bar VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+005c U+007c U+007c U+00a6 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_less Meta_greater Meta_bar Meta_bar VoidSymbol VoidSymbol VoidSymbol VoidSymbol
+keycode 87 = F11 F23 Console_23 Console_35 F35 F47 Console_23 Console_35 Console_11 Console_23 F11 F11 Console_11 Console_23 F11 F11 F11 F23 Console_23 Console_35 F35 F47 Console_23 Console_35 Console_11 Console_23 F11 F11 Console_11 Console_23 F11 F11 F11 F23 Console_23 Console_35 F35 F47 Console_23 Console_35 Console_11 Console_23 F11 F11 Console_11 Console_23 F11 F11 F11 F23 Console_23 Console_35 F35 F47 Console_23 Console_35 Console_11 Console_23 F11 F11 Console_11 Console_23 F11 F11 F11 F23 Console_23 Console_35 F35 F47 Console_23 Console_35 Console_11 Console_23 F11 F11 Console_11 Console_23 F11 F11 F11 F23 Console_23 Console_35 F35 F47 Console_23 Console_35 Console_11 Console_23 F11 F11 Console_11 Console_23 F11 F11 F11 F23 Console_23 Console_35 F35 F47 Console_23 Console_35 Console_11 Console_23 F11 F11 Console_11 Console_23 F11 F11 F11 F23 Console_23 Console_35 F35 F47 Console_23 Console_35 Console_11 Console_23 F11 F11 Console_11 Console_23 F11 F11
+keycode 88 = F12 F24 Console_24 Console_36 F36 F48 Console_24 Console_36 Console_12 Console_24 F12 F12 Console_12 Console_24 F12 F12 F12 F24 Console_24 Console_36 F36 F48 Console_24 Console_36 Console_12 Console_24 F12 F12 Console_12 Console_24 F12 F12 F12 F24 Console_24 Console_36 F36 F48 Console_24 Console_36 Console_12 Console_24 F12 F12 Console_12 Console_24 F12 F12 F12 F24 Console_24 Console_36 F36 F48 Console_24 Console_36 Console_12 Console_24 F12 F12 Console_12 Console_24 F12 F12 F12 F24 Console_24 Console_36 F36 F48 Console_24 Console_36 Console_12 Console_24 F12 F12 Console_12 Console_24 F12 F12 F12 F24 Console_24 Console_36 F36 F48 Console_24 Console_36 Console_12 Console_24 F12 F12 Console_12 Console_24 F12 F12 F12 F24 Console_24 Console_36 F36 F48 Console_24 Console_36 Console_12 Console_24 F12 F12 Console_12 Console_24 F12 F12 F12 F24 Console_24 Console_36 F36 F48 Console_24 Console_36 Console_12 Console_24 F12 F12 Console_12 Console_24 F12 F12
+keycode 102 = Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home
+keycode 103 = Up Up Up Up Up Up Up Up KeyboardSignal Up Up Up Up Up Up Up Up Up Up Up Up Up Up Up KeyboardSignal Up Up Up Up Up Up Up Up Up Up Up Up Up Up Up KeyboardSignal Up Up Up Up Up Up Up Up Up Up Up Up Up Up Up KeyboardSignal Up Up Up Up Up Up Up Up Up Up Up Up Up Up Up KeyboardSignal Up Up Up Up Up Up Up Up Up Up Up Up Up Up Up KeyboardSignal Up Up Up Up Up Up Up Up Up Up Up Up Up Up Up KeyboardSignal Up Up Up Up Up Up Up Up Up Up Up Up Up Up Up KeyboardSignal Up Up Up Up Up Up Up
+keycode 104 = Prior Scroll_Backward Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Scroll_Backward Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Scroll_Backward Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Scroll_Backward Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Scroll_Backward Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Scroll_Backward Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Scroll_Backward Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Scroll_Backward Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior
+keycode 105 = Left Left Left Left Left Left Left Left Decr_Console Left Left Left Left Left Left Left Left Left Left Left Left Left Left Left Decr_Console Left Left Left Left Left Left Left Left Left Left Left Left Left Left Left Decr_Console Left Left Left Left Left Left Left Left Left Left Left Left Left Left Left Decr_Console Left Left Left Left Left Left Left Left Left Left Left Left Left Left Left Decr_Console Left Left Left Left Left Left Left Left Left Left Left Left Left Left Left Decr_Console Left Left Left Left Left Left Left Left Left Left Left Left Left Left Left Decr_Console Left Left Left Left Left Left Left Left Left Left Left Left Left Left Left Decr_Console Left Left Left Left Left Left Left
+keycode 106 = Right Right Right Right Right Right Right Right Incr_Console Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Incr_Console Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Incr_Console Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Incr_Console Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Incr_Console Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Incr_Console Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Incr_Console Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Incr_Console Right Right Right Right Right Right Right
+keycode 107 = End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End
+keycode 108 = Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down
+keycode 109 = Next Scroll_Forward Next Next Next Next Next Next Next Next Next Next Next Next Next Next Next Scroll_Forward Next Next Next Next Next Next Next Next Next Next Next Next Next Next Next Scroll_Forward Next Next Next Next Next Next Next Next Next Next Next Next Next Next Next Scroll_Forward Next Next Next Next Next Next Next Next Next Next Next Next Next Next Next Scroll_Forward Next Next Next Next Next Next Next Next Next Next Next Next Next Next Next Scroll_Forward Next Next Next Next Next Next Next Next Next Next Next Next Next Next Next Scroll_Forward Next Next Next Next Next Next Next Next Next Next Next Next Next Next Next Scroll_Forward Next Next Next Next Next Next Next Next Next Next Next Next Next Next
+keycode 110 = Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert
+keycode 111 = Remove Remove Remove Remove Remove Remove Boot Remove Remove Remove Remove Remove Boot Remove Boot Remove Remove Remove Remove Remove Remove Remove Boot Remove Remove Remove Remove Remove Boot Remove Boot Remove Remove Remove Remove Remove Remove Remove Boot Remove Remove Remove Remove Remove Boot Remove Boot Remove Remove Remove Remove Remove Remove Remove Boot Remove Remove Remove Remove Remove Boot Remove Boot Remove Remove Remove Remove Remove Remove Remove Boot Remove Remove Remove Remove Remove Boot Remove Boot Remove Remove Remove Remove Remove Remove Remove Boot Remove Remove Remove Remove Remove Boot Remove Boot Remove Remove Remove Remove Remove Remove Remove Boot Remove Remove Remove Remove Remove Boot Remove Boot Remove Remove Remove Remove Remove Remove Remove Boot Remove Remove Remove Remove Remove Boot Remove Boot Remove
+keycode 96 = KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter
+keycode 97 = Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control
+keycode 119 = Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause
+keycode 99 = VoidSymbol VoidSymbol Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash VoidSymbol VoidSymbol Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash VoidSymbol VoidSymbol Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash VoidSymbol VoidSymbol Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash VoidSymbol VoidSymbol Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash VoidSymbol VoidSymbol Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash VoidSymbol VoidSymbol Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash VoidSymbol VoidSymbol Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash
+keycode 98 = KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide
+keycode 100 = Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt
+keycode 125 = Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt
+keycode 126 = Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt
+keycode 121 = KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period
+strings as usual
+# The content of this file will be appended to the keyboard layout.
+# For example if you uncomment the following lines Alt+j can be used
+# to go to the next console and Alt+k can be used to go to the
+# previous console:
+
+# alt keycode 36 = Incr_Console
+# shiftl alt keycode 36 = Incr_Console
+# shiftr alt keycode 36 = Incr_Console
+# shiftr shiftl alt keycode 36 = Incr_Console
+# ctrll alt keycode 36 = Incr_Console
+# ctrll shiftl alt keycode 36 = Incr_Console
+# ctrll shiftr alt keycode 36 = Incr_Console
+# ctrll shiftr shiftl alt keycode 36 = Incr_Console
+
+# alt keycode 37 = Decr_Console
+# shiftl alt keycode 37 = Decr_Console
+# shiftr alt keycode 37 = Decr_Console
+# shiftr shiftl alt keycode 37 = Decr_Console
+# ctrll alt keycode 37 = Decr_Console
+# ctrll shiftl alt keycode 37 = Decr_Console
+# ctrll shiftr alt keycode 37 = Decr_Console
+# ctrll shiftr shiftl alt keycode 37 = Decr_Console
+
diff --git a/resources/grub/keymap/ukdvorak.gkb b/resources/grub/keymap/ukdvorak.gkb
new file mode 100644
index 0000000..c793cae
--- /dev/null
+++ b/resources/grub/keymap/ukdvorak.gkb
Binary files differ
diff --git a/resources/grub/keymap/ukqwerty b/resources/grub/keymap/ukqwerty
new file mode 100644
index 0000000..94e5a45
--- /dev/null
+++ b/resources/grub/keymap/ukqwerty
@@ -0,0 +1,130 @@
+keymaps 0-127
+keycode 1 = Escape Escape Escape Escape Escape Escape Escape Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Escape Escape Escape Escape Escape Escape Escape Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Escape Escape Escape Escape Escape Escape Escape Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Escape Escape Escape Escape Escape Escape Escape Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Escape Escape Escape Escape Escape Escape Escape Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Escape Escape Escape Escape Escape Escape Escape Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Escape Escape Escape Escape Escape Escape Escape Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Escape Escape Escape Escape Escape Escape Escape Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape
+keycode 2 = U+0031 U+0021 U+00b9 U+00a1 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_one Meta_exclam Meta_one Meta_exclam VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0031 U+0021 U+00b9 U+00a1 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_one Meta_exclam Meta_one Meta_exclam VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0031 U+0021 U+00b9 U+00a1 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_one Meta_exclam Meta_one Meta_exclam VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0031 U+0021 U+00b9 U+00a1 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_one Meta_exclam Meta_one Meta_exclam VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0031 U+0021 U+00b9 U+00a1 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_one Meta_exclam Meta_one Meta_exclam VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0031 U+0021 U+00b9 U+00a1 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_one Meta_exclam Meta_one Meta_exclam VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0031 U+0021 U+00b9 U+00a1 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_one Meta_exclam Meta_one Meta_exclam VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0031 U+0021 U+00b9 U+00a1 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_one Meta_exclam Meta_one Meta_exclam VoidSymbol VoidSymbol VoidSymbol VoidSymbol
+keycode 3 = U+0032 U+0022 U+00b2 U+215b nul nul nul nul Meta_two Meta_quotedbl Meta_two Meta_quotedbl Meta_nul Meta_nul Meta_nul Meta_nul U+0032 U+0022 U+00b2 U+215b nul nul nul nul Meta_two Meta_quotedbl Meta_two Meta_quotedbl Meta_nul Meta_nul Meta_nul Meta_nul U+0032 U+0022 U+00b2 U+215b nul nul nul nul Meta_two Meta_quotedbl Meta_two Meta_quotedbl Meta_nul Meta_nul Meta_nul Meta_nul U+0032 U+0022 U+00b2 U+215b nul nul nul nul Meta_two Meta_quotedbl Meta_two Meta_quotedbl Meta_nul Meta_nul Meta_nul Meta_nul U+0032 U+0022 U+00b2 U+215b nul nul nul nul Meta_two Meta_quotedbl Meta_two Meta_quotedbl Meta_nul Meta_nul Meta_nul Meta_nul U+0032 U+0022 U+00b2 U+215b nul nul nul nul Meta_two Meta_quotedbl Meta_two Meta_quotedbl Meta_nul Meta_nul Meta_nul Meta_nul U+0032 U+0022 U+00b2 U+215b nul nul nul nul Meta_two Meta_quotedbl Meta_two Meta_quotedbl Meta_nul Meta_nul Meta_nul Meta_nul U+0032 U+0022 U+00b2 U+215b nul nul nul nul Meta_two Meta_quotedbl Meta_two Meta_quotedbl Meta_nul Meta_nul Meta_nul Meta_nul
+keycode 4 = U+0033 U+00a3 U+00b3 U+00a3 Escape Escape Escape Escape Meta_three Meta_three Meta_three Meta_three Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+0033 U+00a3 U+00b3 U+00a3 Escape Escape Escape Escape Meta_three Meta_three Meta_three Meta_three Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+0033 U+00a3 U+00b3 U+00a3 Escape Escape Escape Escape Meta_three Meta_three Meta_three Meta_three Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+0033 U+00a3 U+00b3 U+00a3 Escape Escape Escape Escape Meta_three Meta_three Meta_three Meta_three Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+0033 U+00a3 U+00b3 U+00a3 Escape Escape Escape Escape Meta_three Meta_three Meta_three Meta_three Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+0033 U+00a3 U+00b3 U+00a3 Escape Escape Escape Escape Meta_three Meta_three Meta_three Meta_three Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+0033 U+00a3 U+00b3 U+00a3 Escape Escape Escape Escape Meta_three Meta_three Meta_three Meta_three Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+0033 U+00a3 U+00b3 U+00a3 Escape Escape Escape Escape Meta_three Meta_three Meta_three Meta_three Meta_Escape Meta_Escape Meta_Escape Meta_Escape
+keycode 5 = U+0034 U+0024 U+20ac U+00bc Control_backslash Control_backslash Control_backslash Control_backslash Meta_four Meta_dollar Meta_four Meta_dollar Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+0034 U+0024 U+20ac U+00bc Control_backslash Control_backslash Control_backslash Control_backslash Meta_four Meta_dollar Meta_four Meta_dollar Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+0034 U+0024 U+20ac U+00bc Control_backslash Control_backslash Control_backslash Control_backslash Meta_four Meta_dollar Meta_four Meta_dollar Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+0034 U+0024 U+20ac U+00bc Control_backslash Control_backslash Control_backslash Control_backslash Meta_four Meta_dollar Meta_four Meta_dollar Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+0034 U+0024 U+20ac U+00bc Control_backslash Control_backslash Control_backslash Control_backslash Meta_four Meta_dollar Meta_four Meta_dollar Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+0034 U+0024 U+20ac U+00bc Control_backslash Control_backslash Control_backslash Control_backslash Meta_four Meta_dollar Meta_four Meta_dollar Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+0034 U+0024 U+20ac U+00bc Control_backslash Control_backslash Control_backslash Control_backslash Meta_four Meta_dollar Meta_four Meta_dollar Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+0034 U+0024 U+20ac U+00bc Control_backslash Control_backslash Control_backslash Control_backslash Meta_four Meta_dollar Meta_four Meta_dollar Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash
+keycode 6 = U+0035 U+0025 U+00bd U+215c Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_five Meta_percent Meta_five Meta_percent Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright U+0035 U+0025 U+00bd U+215c Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_five Meta_percent Meta_five Meta_percent Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright U+0035 U+0025 U+00bd U+215c Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_five Meta_percent Meta_five Meta_percent Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright U+0035 U+0025 U+00bd U+215c Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_five Meta_percent Meta_five Meta_percent Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright U+0035 U+0025 U+00bd U+215c Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_five Meta_percent Meta_five Meta_percent Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright U+0035 U+0025 U+00bd U+215c Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_five Meta_percent Meta_five Meta_percent Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright U+0035 U+0025 U+00bd U+215c Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_five Meta_percent Meta_five Meta_percent Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright U+0035 U+0025 U+00bd U+215c Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_five Meta_percent Meta_five Meta_percent Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright
+keycode 7 = U+0036 U+005e U+00be U+215d Control_asciicircum Control_asciicircum Control_asciicircum Control_asciicircum Meta_six Meta_asciicircum Meta_six Meta_asciicircum Meta_Control_asciicircum Meta_Control_asciicircum Meta_Control_asciicircum Meta_Control_asciicircum U+0036 U+005e U+00be U+215d Control_asciicircum Control_asciicircum Control_asciicircum Control_asciicircum Meta_six Meta_asciicircum Meta_six Meta_asciicircum Meta_Control_asciicircum Meta_Control_asciicircum Meta_Control_asciicircum Meta_Control_asciicircum U+0036 U+005e U+00be U+215d Control_asciicircum Control_asciicircum Control_asciicircum Control_asciicircum Meta_six Meta_asciicircum Meta_six Meta_asciicircum Meta_Control_asciicircum Meta_Control_asciicircum Meta_Control_asciicircum Meta_Control_asciicircum U+0036 U+005e U+00be U+215d Control_asciicircum Control_asciicircum Control_asciicircum Control_asciicircum Meta_six Meta_asciicircum Meta_six Meta_asciicircum Meta_Control_asciicircum Meta_Control_asciicircum Meta_Control_asciicircum Meta_Control_asciicircum U+0036 U+005e U+00be U+215d Control_asciicircum Control_asciicircum Control_asciicircum Control_asciicircum Meta_six Meta_asciicircum Meta_six Meta_asciicircum Meta_Control_asciicircum Meta_Control_asciicircum Meta_Control_asciicircum Meta_Control_asciicircum U+0036 U+005e U+00be U+215d Control_asciicircum Control_asciicircum Control_asciicircum Control_asciicircum Meta_six Meta_asciicircum Meta_six Meta_asciicircum Meta_Control_asciicircum Meta_Control_asciicircum Meta_Control_asciicircum Meta_Control_asciicircum U+0036 U+005e U+00be U+215d Control_asciicircum Control_asciicircum Control_asciicircum Control_asciicircum Meta_six Meta_asciicircum Meta_six Meta_asciicircum Meta_Control_asciicircum Meta_Control_asciicircum Meta_Control_asciicircum Meta_Control_asciicircum U+0036 U+005e U+00be U+215d Control_asciicircum Control_asciicircum Control_asciicircum Control_asciicircum Meta_six Meta_asciicircum Meta_six Meta_asciicircum Meta_Control_asciicircum Meta_Control_asciicircum Meta_Control_asciicircum Meta_Control_asciicircum
+keycode 8 = U+0037 U+0026 U+007b U+215e Control_underscore Control_underscore Control_underscore Control_underscore Meta_seven Meta_ampersand Meta_braceleft Meta_braceleft Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+0037 U+0026 U+007b U+215e Control_underscore Control_underscore Control_underscore Control_underscore Meta_seven Meta_ampersand Meta_braceleft Meta_braceleft Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+0037 U+0026 U+007b U+215e Control_underscore Control_underscore Control_underscore Control_underscore Meta_seven Meta_ampersand Meta_braceleft Meta_braceleft Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+0037 U+0026 U+007b U+215e Control_underscore Control_underscore Control_underscore Control_underscore Meta_seven Meta_ampersand Meta_braceleft Meta_braceleft Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+0037 U+0026 U+007b U+215e Control_underscore Control_underscore Control_underscore Control_underscore Meta_seven Meta_ampersand Meta_braceleft Meta_braceleft Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+0037 U+0026 U+007b U+215e Control_underscore Control_underscore Control_underscore Control_underscore Meta_seven Meta_ampersand Meta_braceleft Meta_braceleft Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+0037 U+0026 U+007b U+215e Control_underscore Control_underscore Control_underscore Control_underscore Meta_seven Meta_ampersand Meta_braceleft Meta_braceleft Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+0037 U+0026 U+007b U+215e Control_underscore Control_underscore Control_underscore Control_underscore Meta_seven Meta_ampersand Meta_braceleft Meta_braceleft Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore
+keycode 9 = U+0038 U+002a U+005b U+2122 Delete Delete Escape Escape Meta_eight Meta_asterisk Meta_bracketleft Meta_bracketleft Meta_Delete Meta_Delete Meta_Escape Meta_Escape U+0038 U+002a U+005b U+2122 Delete Delete Escape Escape Meta_eight Meta_asterisk Meta_bracketleft Meta_bracketleft Meta_Delete Meta_Delete Meta_Escape Meta_Escape U+0038 U+002a U+005b U+2122 Delete Delete Escape Escape Meta_eight Meta_asterisk Meta_bracketleft Meta_bracketleft Meta_Delete Meta_Delete Meta_Escape Meta_Escape U+0038 U+002a U+005b U+2122 Delete Delete Escape Escape Meta_eight Meta_asterisk Meta_bracketleft Meta_bracketleft Meta_Delete Meta_Delete Meta_Escape Meta_Escape U+0038 U+002a U+005b U+2122 Delete Delete Escape Escape Meta_eight Meta_asterisk Meta_bracketleft Meta_bracketleft Meta_Delete Meta_Delete Meta_Escape Meta_Escape U+0038 U+002a U+005b U+2122 Delete Delete Escape Escape Meta_eight Meta_asterisk Meta_bracketleft Meta_bracketleft Meta_Delete Meta_Delete Meta_Escape Meta_Escape U+0038 U+002a U+005b U+2122 Delete Delete Escape Escape Meta_eight Meta_asterisk Meta_bracketleft Meta_bracketleft Meta_Delete Meta_Delete Meta_Escape Meta_Escape U+0038 U+002a U+005b U+2122 Delete Delete Escape Escape Meta_eight Meta_asterisk Meta_bracketleft Meta_bracketleft Meta_Delete Meta_Delete Meta_Escape Meta_Escape
+keycode 10 = U+0039 U+0028 U+005d U+00b1 Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_nine Meta_parenleft Meta_bracketright Meta_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright U+0039 U+0028 U+005d U+00b1 Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_nine Meta_parenleft Meta_bracketright Meta_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright U+0039 U+0028 U+005d U+00b1 Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_nine Meta_parenleft Meta_bracketright Meta_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright U+0039 U+0028 U+005d U+00b1 Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_nine Meta_parenleft Meta_bracketright Meta_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright U+0039 U+0028 U+005d U+00b1 Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_nine Meta_parenleft Meta_bracketright Meta_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright U+0039 U+0028 U+005d U+00b1 Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_nine Meta_parenleft Meta_bracketright Meta_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright U+0039 U+0028 U+005d U+00b1 Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_nine Meta_parenleft Meta_bracketright Meta_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright U+0039 U+0028 U+005d U+00b1 Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_nine Meta_parenleft Meta_bracketright Meta_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright
+keycode 11 = U+0030 U+0029 U+007d U+00b0 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_zero Meta_parenright Meta_braceright Meta_braceright VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0030 U+0029 U+007d U+00b0 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_zero Meta_parenright Meta_braceright Meta_braceright VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0030 U+0029 U+007d U+00b0 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_zero Meta_parenright Meta_braceright Meta_braceright VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0030 U+0029 U+007d U+00b0 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_zero Meta_parenright Meta_braceright Meta_braceright VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0030 U+0029 U+007d U+00b0 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_zero Meta_parenright Meta_braceright Meta_braceright VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0030 U+0029 U+007d U+00b0 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_zero Meta_parenright Meta_braceright Meta_braceright VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0030 U+0029 U+007d U+00b0 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_zero Meta_parenright Meta_braceright Meta_braceright VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0030 U+0029 U+007d U+00b0 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_zero Meta_parenright Meta_braceright Meta_braceright VoidSymbol VoidSymbol VoidSymbol VoidSymbol
+keycode 12 = U+002d U+005f U+005c U+00bf Control_underscore Control_underscore Control_backslash Control_backslash Meta_minus Meta_underscore Meta_backslash Meta_backslash Meta_Control_underscore Meta_Control_underscore Meta_Control_backslash Meta_Control_backslash U+002d U+005f U+005c U+00bf Control_underscore Control_underscore Control_backslash Control_backslash Meta_minus Meta_underscore Meta_backslash Meta_backslash Meta_Control_underscore Meta_Control_underscore Meta_Control_backslash Meta_Control_backslash U+002d U+005f U+005c U+00bf Control_underscore Control_underscore Control_backslash Control_backslash Meta_minus Meta_underscore Meta_backslash Meta_backslash Meta_Control_underscore Meta_Control_underscore Meta_Control_backslash Meta_Control_backslash U+002d U+005f U+005c U+00bf Control_underscore Control_underscore Control_backslash Control_backslash Meta_minus Meta_underscore Meta_backslash Meta_backslash Meta_Control_underscore Meta_Control_underscore Meta_Control_backslash Meta_Control_backslash U+002d U+005f U+005c U+00bf Control_underscore Control_underscore Control_backslash Control_backslash Meta_minus Meta_underscore Meta_backslash Meta_backslash Meta_Control_underscore Meta_Control_underscore Meta_Control_backslash Meta_Control_backslash U+002d U+005f U+005c U+00bf Control_underscore Control_underscore Control_backslash Control_backslash Meta_minus Meta_underscore Meta_backslash Meta_backslash Meta_Control_underscore Meta_Control_underscore Meta_Control_backslash Meta_Control_backslash U+002d U+005f U+005c U+00bf Control_underscore Control_underscore Control_backslash Control_backslash Meta_minus Meta_underscore Meta_backslash Meta_backslash Meta_Control_underscore Meta_Control_underscore Meta_Control_backslash Meta_Control_backslash U+002d U+005f U+005c U+00bf Control_underscore Control_underscore Control_backslash Control_backslash Meta_minus Meta_underscore Meta_backslash Meta_backslash Meta_Control_underscore Meta_Control_underscore Meta_Control_backslash Meta_Control_backslash
+keycode 13 = U+003d U+002b dead_cedilla dead_ogonek dead_cedilla dead_ogonek dead_cedilla dead_ogonek Meta_equal Meta_plus dead_cedilla dead_ogonek dead_cedilla dead_ogonek dead_cedilla dead_ogonek U+003d U+002b dead_cedilla dead_ogonek dead_cedilla dead_ogonek dead_cedilla dead_ogonek Meta_equal Meta_plus dead_cedilla dead_ogonek dead_cedilla dead_ogonek dead_cedilla dead_ogonek U+003d U+002b dead_cedilla dead_ogonek dead_cedilla dead_ogonek dead_cedilla dead_ogonek Meta_equal Meta_plus dead_cedilla dead_ogonek dead_cedilla dead_ogonek dead_cedilla dead_ogonek U+003d U+002b dead_cedilla dead_ogonek dead_cedilla dead_ogonek dead_cedilla dead_ogonek Meta_equal Meta_plus dead_cedilla dead_ogonek dead_cedilla dead_ogonek dead_cedilla dead_ogonek U+003d U+002b dead_cedilla dead_ogonek dead_cedilla dead_ogonek dead_cedilla dead_ogonek Meta_equal Meta_plus dead_cedilla dead_ogonek dead_cedilla dead_ogonek dead_cedilla dead_ogonek U+003d U+002b dead_cedilla dead_ogonek dead_cedilla dead_ogonek dead_cedilla dead_ogonek Meta_equal Meta_plus dead_cedilla dead_ogonek dead_cedilla dead_ogonek dead_cedilla dead_ogonek U+003d U+002b dead_cedilla dead_ogonek dead_cedilla dead_ogonek dead_cedilla dead_ogonek Meta_equal Meta_plus dead_cedilla dead_ogonek dead_cedilla dead_ogonek dead_cedilla dead_ogonek U+003d U+002b dead_cedilla dead_ogonek dead_cedilla dead_ogonek dead_cedilla dead_ogonek Meta_equal Meta_plus dead_cedilla dead_ogonek dead_cedilla dead_ogonek dead_cedilla dead_ogonek
+keycode 14 = Delete Delete Delete Delete BackSpace BackSpace BackSpace BackSpace Meta_Delete Meta_Delete Meta_Delete Meta_Delete Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace Delete Delete Delete Delete BackSpace BackSpace BackSpace BackSpace Meta_Delete Meta_Delete Meta_Delete Meta_Delete Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace Delete Delete Delete Delete BackSpace BackSpace BackSpace BackSpace Meta_Delete Meta_Delete Meta_Delete Meta_Delete Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace Delete Delete Delete Delete BackSpace BackSpace BackSpace BackSpace Meta_Delete Meta_Delete Meta_Delete Meta_Delete Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace Delete Delete Delete Delete BackSpace BackSpace BackSpace BackSpace Meta_Delete Meta_Delete Meta_Delete Meta_Delete Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace Delete Delete Delete Delete BackSpace BackSpace BackSpace BackSpace Meta_Delete Meta_Delete Meta_Delete Meta_Delete Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace Delete Delete Delete Delete BackSpace BackSpace BackSpace BackSpace Meta_Delete Meta_Delete Meta_Delete Meta_Delete Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace Delete Delete Delete Delete BackSpace BackSpace BackSpace BackSpace Meta_Delete Meta_Delete Meta_Delete Meta_Delete Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace
+keycode 15 = Tab Tab Tab Tab Tab Tab Tab Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Tab Tab Tab Tab Tab Tab Tab Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Tab Tab Tab Tab Tab Tab Tab Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Tab Tab Tab Tab Tab Tab Tab Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Tab Tab Tab Tab Tab Tab Tab Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Tab Tab Tab Tab Tab Tab Tab Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Tab Tab Tab Tab Tab Tab Tab Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Tab Tab Tab Tab Tab Tab Tab Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab
+keycode 16 = +U+0071 +U+0051 U+0040 +U+03a9 Control_q Control_q nul nul Meta_q Meta_Q Meta_at Meta_at Meta_Control_q Meta_Control_q Meta_nul Meta_nul +U+0071 +U+0051 U+0040 +U+03a9 Control_q Control_q nul nul Meta_q Meta_Q Meta_at Meta_at Meta_Control_q Meta_Control_q Meta_nul Meta_nul +U+0071 +U+0051 U+0040 +U+03a9 Control_q Control_q nul nul Meta_q Meta_Q Meta_at Meta_at Meta_Control_q Meta_Control_q Meta_nul Meta_nul +U+0071 +U+0051 U+0040 +U+03a9 Control_q Control_q nul nul Meta_q Meta_Q Meta_at Meta_at Meta_Control_q Meta_Control_q Meta_nul Meta_nul +U+0051 +U+0071 U+0040 +U+03c9 Control_q Control_q nul nul Meta_q Meta_Q Meta_at Meta_at Meta_Control_q Meta_Control_q Meta_nul Meta_nul +U+0051 +U+0071 U+0040 +U+03c9 Control_q Control_q nul nul Meta_q Meta_Q Meta_at Meta_at Meta_Control_q Meta_Control_q Meta_nul Meta_nul +U+0051 +U+0071 U+0040 +U+03c9 Control_q Control_q nul nul Meta_q Meta_Q Meta_at Meta_at Meta_Control_q Meta_Control_q Meta_nul Meta_nul +U+0051 +U+0071 U+0040 +U+03c9 Control_q Control_q nul nul Meta_q Meta_Q Meta_at Meta_at Meta_Control_q Meta_Control_q Meta_nul Meta_nul
+keycode 17 = +U+0077 +U+0057 +U+0142 +U+0141 Control_w Control_w Control_w Control_w Meta_w Meta_W Meta_w Meta_W Meta_Control_w Meta_Control_w Meta_Control_w Meta_Control_w +U+0077 +U+0057 +U+0142 +U+0141 Control_w Control_w Control_w Control_w Meta_w Meta_W Meta_w Meta_W Meta_Control_w Meta_Control_w Meta_Control_w Meta_Control_w +U+0077 +U+0057 +U+0142 +U+0141 Control_w Control_w Control_w Control_w Meta_w Meta_W Meta_w Meta_W Meta_Control_w Meta_Control_w Meta_Control_w Meta_Control_w +U+0077 +U+0057 +U+0142 +U+0141 Control_w Control_w Control_w Control_w Meta_w Meta_W Meta_w Meta_W Meta_Control_w Meta_Control_w Meta_Control_w Meta_Control_w +U+0057 +U+0077 +U+0141 +U+0142 Control_w Control_w Control_w Control_w Meta_w Meta_W Meta_w Meta_W Meta_Control_w Meta_Control_w Meta_Control_w Meta_Control_w +U+0057 +U+0077 +U+0141 +U+0142 Control_w Control_w Control_w Control_w Meta_w Meta_W Meta_w Meta_W Meta_Control_w Meta_Control_w Meta_Control_w Meta_Control_w +U+0057 +U+0077 +U+0141 +U+0142 Control_w Control_w Control_w Control_w Meta_w Meta_W Meta_w Meta_W Meta_Control_w Meta_Control_w Meta_Control_w Meta_Control_w +U+0057 +U+0077 +U+0141 +U+0142 Control_w Control_w Control_w Control_w Meta_w Meta_W Meta_w Meta_W Meta_Control_w Meta_Control_w Meta_Control_w Meta_Control_w
+keycode 18 = +U+0065 +U+0045 +U+0065 +U+0045 Control_e Control_e Control_e Control_e Meta_e Meta_E Meta_e Meta_E Meta_Control_e Meta_Control_e Meta_Control_e Meta_Control_e +U+0065 +U+0045 +U+0065 +U+0045 Control_e Control_e Control_e Control_e Meta_e Meta_E Meta_e Meta_E Meta_Control_e Meta_Control_e Meta_Control_e Meta_Control_e +U+0065 +U+0045 +U+0065 +U+0045 Control_e Control_e Control_e Control_e Meta_e Meta_E Meta_e Meta_E Meta_Control_e Meta_Control_e Meta_Control_e Meta_Control_e +U+0065 +U+0045 +U+0065 +U+0045 Control_e Control_e Control_e Control_e Meta_e Meta_E Meta_e Meta_E Meta_Control_e Meta_Control_e Meta_Control_e Meta_Control_e +U+0045 +U+0065 +U+0045 +U+0065 Control_e Control_e Control_e Control_e Meta_e Meta_E Meta_e Meta_E Meta_Control_e Meta_Control_e Meta_Control_e Meta_Control_e +U+0045 +U+0065 +U+0045 +U+0065 Control_e Control_e Control_e Control_e Meta_e Meta_E Meta_e Meta_E Meta_Control_e Meta_Control_e Meta_Control_e Meta_Control_e +U+0045 +U+0065 +U+0045 +U+0065 Control_e Control_e Control_e Control_e Meta_e Meta_E Meta_e Meta_E Meta_Control_e Meta_Control_e Meta_Control_e Meta_Control_e +U+0045 +U+0065 +U+0045 +U+0065 Control_e Control_e Control_e Control_e Meta_e Meta_E Meta_e Meta_E Meta_Control_e Meta_Control_e Meta_Control_e Meta_Control_e
+keycode 19 = +U+0072 +U+0052 U+00b6 U+00ae Control_r Control_r Control_r Control_r Meta_r Meta_R Meta_r Meta_R Meta_Control_r Meta_Control_r Meta_Control_r Meta_Control_r +U+0072 +U+0052 U+00b6 U+00ae Control_r Control_r Control_r Control_r Meta_r Meta_R Meta_r Meta_R Meta_Control_r Meta_Control_r Meta_Control_r Meta_Control_r +U+0072 +U+0052 U+00b6 U+00ae Control_r Control_r Control_r Control_r Meta_r Meta_R Meta_r Meta_R Meta_Control_r Meta_Control_r Meta_Control_r Meta_Control_r +U+0072 +U+0052 U+00b6 U+00ae Control_r Control_r Control_r Control_r Meta_r Meta_R Meta_r Meta_R Meta_Control_r Meta_Control_r Meta_Control_r Meta_Control_r +U+0052 +U+0072 U+00b6 U+00ae Control_r Control_r Control_r Control_r Meta_r Meta_R Meta_r Meta_R Meta_Control_r Meta_Control_r Meta_Control_r Meta_Control_r +U+0052 +U+0072 U+00b6 U+00ae Control_r Control_r Control_r Control_r Meta_r Meta_R Meta_r Meta_R Meta_Control_r Meta_Control_r Meta_Control_r Meta_Control_r +U+0052 +U+0072 U+00b6 U+00ae Control_r Control_r Control_r Control_r Meta_r Meta_R Meta_r Meta_R Meta_Control_r Meta_Control_r Meta_Control_r Meta_Control_r +U+0052 +U+0072 U+00b6 U+00ae Control_r Control_r Control_r Control_r Meta_r Meta_R Meta_r Meta_R Meta_Control_r Meta_Control_r Meta_Control_r Meta_Control_r
+keycode 20 = +U+0074 +U+0054 +U+0167 +U+0166 Control_t Control_t Control_t Control_t Meta_t Meta_T Meta_t Meta_T Meta_Control_t Meta_Control_t Meta_Control_t Meta_Control_t +U+0074 +U+0054 +U+0167 +U+0166 Control_t Control_t Control_t Control_t Meta_t Meta_T Meta_t Meta_T Meta_Control_t Meta_Control_t Meta_Control_t Meta_Control_t +U+0074 +U+0054 +U+0167 +U+0166 Control_t Control_t Control_t Control_t Meta_t Meta_T Meta_t Meta_T Meta_Control_t Meta_Control_t Meta_Control_t Meta_Control_t +U+0074 +U+0054 +U+0167 +U+0166 Control_t Control_t Control_t Control_t Meta_t Meta_T Meta_t Meta_T Meta_Control_t Meta_Control_t Meta_Control_t Meta_Control_t +U+0054 +U+0074 +U+0166 +U+0167 Control_t Control_t Control_t Control_t Meta_t Meta_T Meta_t Meta_T Meta_Control_t Meta_Control_t Meta_Control_t Meta_Control_t +U+0054 +U+0074 +U+0166 +U+0167 Control_t Control_t Control_t Control_t Meta_t Meta_T Meta_t Meta_T Meta_Control_t Meta_Control_t Meta_Control_t Meta_Control_t +U+0054 +U+0074 +U+0166 +U+0167 Control_t Control_t Control_t Control_t Meta_t Meta_T Meta_t Meta_T Meta_Control_t Meta_Control_t Meta_Control_t Meta_Control_t +U+0054 +U+0074 +U+0166 +U+0167 Control_t Control_t Control_t Control_t Meta_t Meta_T Meta_t Meta_T Meta_Control_t Meta_Control_t Meta_Control_t Meta_Control_t
+keycode 21 = +U+0079 +U+0059 U+2190 U+00a5 Control_y Control_y Control_y Control_y Meta_y Meta_Y Meta_y Meta_Y Meta_Control_y Meta_Control_y Meta_Control_y Meta_Control_y +U+0079 +U+0059 U+2190 U+00a5 Control_y Control_y Control_y Control_y Meta_y Meta_Y Meta_y Meta_Y Meta_Control_y Meta_Control_y Meta_Control_y Meta_Control_y +U+0079 +U+0059 U+2190 U+00a5 Control_y Control_y Control_y Control_y Meta_y Meta_Y Meta_y Meta_Y Meta_Control_y Meta_Control_y Meta_Control_y Meta_Control_y +U+0079 +U+0059 U+2190 U+00a5 Control_y Control_y Control_y Control_y Meta_y Meta_Y Meta_y Meta_Y Meta_Control_y Meta_Control_y Meta_Control_y Meta_Control_y +U+0059 +U+0079 U+2190 U+00a5 Control_y Control_y Control_y Control_y Meta_y Meta_Y Meta_y Meta_Y Meta_Control_y Meta_Control_y Meta_Control_y Meta_Control_y +U+0059 +U+0079 U+2190 U+00a5 Control_y Control_y Control_y Control_y Meta_y Meta_Y Meta_y Meta_Y Meta_Control_y Meta_Control_y Meta_Control_y Meta_Control_y +U+0059 +U+0079 U+2190 U+00a5 Control_y Control_y Control_y Control_y Meta_y Meta_Y Meta_y Meta_Y Meta_Control_y Meta_Control_y Meta_Control_y Meta_Control_y +U+0059 +U+0079 U+2190 U+00a5 Control_y Control_y Control_y Control_y Meta_y Meta_Y Meta_y Meta_Y Meta_Control_y Meta_Control_y Meta_Control_y Meta_Control_y
+keycode 22 = +U+0075 +U+0055 U+2193 U+2191 Control_u Control_u Control_u Control_u Meta_u Meta_U Meta_u Meta_U Meta_Control_u Meta_Control_u Meta_Control_u Meta_Control_u +U+0075 +U+0055 U+2193 U+2191 Control_u Control_u Control_u Control_u Meta_u Meta_U Meta_u Meta_U Meta_Control_u Meta_Control_u Meta_Control_u Meta_Control_u +U+0075 +U+0055 U+2193 U+2191 Control_u Control_u Control_u Control_u Meta_u Meta_U Meta_u Meta_U Meta_Control_u Meta_Control_u Meta_Control_u Meta_Control_u +U+0075 +U+0055 U+2193 U+2191 Control_u Control_u Control_u Control_u Meta_u Meta_U Meta_u Meta_U Meta_Control_u Meta_Control_u Meta_Control_u Meta_Control_u +U+0055 +U+0075 U+2193 U+2191 Control_u Control_u Control_u Control_u Meta_u Meta_U Meta_u Meta_U Meta_Control_u Meta_Control_u Meta_Control_u Meta_Control_u +U+0055 +U+0075 U+2193 U+2191 Control_u Control_u Control_u Control_u Meta_u Meta_U Meta_u Meta_U Meta_Control_u Meta_Control_u Meta_Control_u Meta_Control_u +U+0055 +U+0075 U+2193 U+2191 Control_u Control_u Control_u Control_u Meta_u Meta_U Meta_u Meta_U Meta_Control_u Meta_Control_u Meta_Control_u Meta_Control_u +U+0055 +U+0075 U+2193 U+2191 Control_u Control_u Control_u Control_u Meta_u Meta_U Meta_u Meta_U Meta_Control_u Meta_Control_u Meta_Control_u Meta_Control_u
+keycode 23 = +U+0069 +U+0049 U+2192 +U+0131 Tab Tab Tab Tab Meta_i Meta_I Meta_i Meta_I Meta_Tab Meta_Tab Meta_Tab Meta_Tab +U+0069 +U+0049 U+2192 +U+0131 Tab Tab Tab Tab Meta_i Meta_I Meta_i Meta_I Meta_Tab Meta_Tab Meta_Tab Meta_Tab +U+0069 +U+0049 U+2192 +U+0131 Tab Tab Tab Tab Meta_i Meta_I Meta_i Meta_I Meta_Tab Meta_Tab Meta_Tab Meta_Tab +U+0069 +U+0049 U+2192 +U+0131 Tab Tab Tab Tab Meta_i Meta_I Meta_i Meta_I Meta_Tab Meta_Tab Meta_Tab Meta_Tab +U+0049 +U+0069 U+2192 +U+0049 Tab Tab Tab Tab Meta_i Meta_I Meta_i Meta_I Meta_Tab Meta_Tab Meta_Tab Meta_Tab +U+0049 +U+0069 U+2192 +U+0049 Tab Tab Tab Tab Meta_i Meta_I Meta_i Meta_I Meta_Tab Meta_Tab Meta_Tab Meta_Tab +U+0049 +U+0069 U+2192 +U+0049 Tab Tab Tab Tab Meta_i Meta_I Meta_i Meta_I Meta_Tab Meta_Tab Meta_Tab Meta_Tab +U+0049 +U+0069 U+2192 +U+0049 Tab Tab Tab Tab Meta_i Meta_I Meta_i Meta_I Meta_Tab Meta_Tab Meta_Tab Meta_Tab
+keycode 24 = +U+006f +U+004f +U+00f8 +U+00d8 Control_o Control_o Control_o Control_o Meta_o Meta_O Meta_o Meta_O Meta_Control_o Meta_Control_o Meta_Control_o Meta_Control_o +U+006f +U+004f +U+00f8 +U+00d8 Control_o Control_o Control_o Control_o Meta_o Meta_O Meta_o Meta_O Meta_Control_o Meta_Control_o Meta_Control_o Meta_Control_o +U+006f +U+004f +U+00f8 +U+00d8 Control_o Control_o Control_o Control_o Meta_o Meta_O Meta_o Meta_O Meta_Control_o Meta_Control_o Meta_Control_o Meta_Control_o +U+006f +U+004f +U+00f8 +U+00d8 Control_o Control_o Control_o Control_o Meta_o Meta_O Meta_o Meta_O Meta_Control_o Meta_Control_o Meta_Control_o Meta_Control_o +U+004f +U+006f +U+00d8 +U+00f8 Control_o Control_o Control_o Control_o Meta_o Meta_O Meta_o Meta_O Meta_Control_o Meta_Control_o Meta_Control_o Meta_Control_o +U+004f +U+006f +U+00d8 +U+00f8 Control_o Control_o Control_o Control_o Meta_o Meta_O Meta_o Meta_O Meta_Control_o Meta_Control_o Meta_Control_o Meta_Control_o +U+004f +U+006f +U+00d8 +U+00f8 Control_o Control_o Control_o Control_o Meta_o Meta_O Meta_o Meta_O Meta_Control_o Meta_Control_o Meta_Control_o Meta_Control_o +U+004f +U+006f +U+00d8 +U+00f8 Control_o Control_o Control_o Control_o Meta_o Meta_O Meta_o Meta_O Meta_Control_o Meta_Control_o Meta_Control_o Meta_Control_o
+keycode 25 = +U+0070 +U+0050 +U+00fe +U+00de Control_p Control_p Control_p Control_p Meta_p Meta_P Meta_p Meta_P Meta_Control_p Meta_Control_p Meta_Control_p Meta_Control_p +U+0070 +U+0050 +U+00fe +U+00de Control_p Control_p Control_p Control_p Meta_p Meta_P Meta_p Meta_P Meta_Control_p Meta_Control_p Meta_Control_p Meta_Control_p +U+0070 +U+0050 +U+00fe +U+00de Control_p Control_p Control_p Control_p Meta_p Meta_P Meta_p Meta_P Meta_Control_p Meta_Control_p Meta_Control_p Meta_Control_p +U+0070 +U+0050 +U+00fe +U+00de Control_p Control_p Control_p Control_p Meta_p Meta_P Meta_p Meta_P Meta_Control_p Meta_Control_p Meta_Control_p Meta_Control_p +U+0050 +U+0070 +U+00de +U+00fe Control_p Control_p Control_p Control_p Meta_p Meta_P Meta_p Meta_P Meta_Control_p Meta_Control_p Meta_Control_p Meta_Control_p +U+0050 +U+0070 +U+00de +U+00fe Control_p Control_p Control_p Control_p Meta_p Meta_P Meta_p Meta_P Meta_Control_p Meta_Control_p Meta_Control_p Meta_Control_p +U+0050 +U+0070 +U+00de +U+00fe Control_p Control_p Control_p Control_p Meta_p Meta_P Meta_p Meta_P Meta_Control_p Meta_Control_p Meta_Control_p Meta_Control_p +U+0050 +U+0070 +U+00de +U+00fe Control_p Control_p Control_p Control_p Meta_p Meta_P Meta_p Meta_P Meta_Control_p Meta_Control_p Meta_Control_p Meta_Control_p
+keycode 26 = U+005b U+007b dead_diaeresis U+002a Escape Escape dead_diaeresis dead_diaeresis Meta_bracketleft Meta_braceleft dead_diaeresis Meta_asterisk Meta_Escape Meta_Escape dead_diaeresis dead_diaeresis U+005b U+007b dead_diaeresis U+002a Escape Escape dead_diaeresis dead_diaeresis Meta_bracketleft Meta_braceleft dead_diaeresis Meta_asterisk Meta_Escape Meta_Escape dead_diaeresis dead_diaeresis U+005b U+007b dead_diaeresis U+002a Escape Escape dead_diaeresis dead_diaeresis Meta_bracketleft Meta_braceleft dead_diaeresis Meta_asterisk Meta_Escape Meta_Escape dead_diaeresis dead_diaeresis U+005b U+007b dead_diaeresis U+002a Escape Escape dead_diaeresis dead_diaeresis Meta_bracketleft Meta_braceleft dead_diaeresis Meta_asterisk Meta_Escape Meta_Escape dead_diaeresis dead_diaeresis U+005b U+007b dead_diaeresis U+002a Escape Escape dead_diaeresis dead_diaeresis Meta_bracketleft Meta_braceleft dead_diaeresis Meta_asterisk Meta_Escape Meta_Escape dead_diaeresis dead_diaeresis U+005b U+007b dead_diaeresis U+002a Escape Escape dead_diaeresis dead_diaeresis Meta_bracketleft Meta_braceleft dead_diaeresis Meta_asterisk Meta_Escape Meta_Escape dead_diaeresis dead_diaeresis U+005b U+007b dead_diaeresis U+002a Escape Escape dead_diaeresis dead_diaeresis Meta_bracketleft Meta_braceleft dead_diaeresis Meta_asterisk Meta_Escape Meta_Escape dead_diaeresis dead_diaeresis U+005b U+007b dead_diaeresis U+002a Escape Escape dead_diaeresis dead_diaeresis Meta_bracketleft Meta_braceleft dead_diaeresis Meta_asterisk Meta_Escape Meta_Escape dead_diaeresis dead_diaeresis
+keycode 27 = U+005d U+007d dead_tilde U+005f Control_bracketright Control_bracketright dead_tilde Control_underscore Meta_bracketright Meta_braceright dead_tilde Meta_underscore Meta_Control_bracketright Meta_Control_bracketright dead_tilde Meta_Control_underscore U+005d U+007d dead_tilde U+005f Control_bracketright Control_bracketright dead_tilde Control_underscore Meta_bracketright Meta_braceright dead_tilde Meta_underscore Meta_Control_bracketright Meta_Control_bracketright dead_tilde Meta_Control_underscore U+005d U+007d dead_tilde U+005f Control_bracketright Control_bracketright dead_tilde Control_underscore Meta_bracketright Meta_braceright dead_tilde Meta_underscore Meta_Control_bracketright Meta_Control_bracketright dead_tilde Meta_Control_underscore U+005d U+007d dead_tilde U+005f Control_bracketright Control_bracketright dead_tilde Control_underscore Meta_bracketright Meta_braceright dead_tilde Meta_underscore Meta_Control_bracketright Meta_Control_bracketright dead_tilde Meta_Control_underscore U+005d U+007d dead_tilde U+005f Control_bracketright Control_bracketright dead_tilde Control_underscore Meta_bracketright Meta_braceright dead_tilde Meta_underscore Meta_Control_bracketright Meta_Control_bracketright dead_tilde Meta_Control_underscore U+005d U+007d dead_tilde U+005f Control_bracketright Control_bracketright dead_tilde Control_underscore Meta_bracketright Meta_braceright dead_tilde Meta_underscore Meta_Control_bracketright Meta_Control_bracketright dead_tilde Meta_Control_underscore U+005d U+007d dead_tilde U+005f Control_bracketright Control_bracketright dead_tilde Control_underscore Meta_bracketright Meta_braceright dead_tilde Meta_underscore Meta_Control_bracketright Meta_Control_bracketright dead_tilde Meta_Control_underscore U+005d U+007d dead_tilde U+005f Control_bracketright Control_bracketright dead_tilde Control_underscore Meta_bracketright Meta_braceright dead_tilde Meta_underscore Meta_Control_bracketright Meta_Control_bracketright dead_tilde Meta_Control_underscore
+keycode 28 = Return Return Return Return Control_m Control_m Control_m Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Return Return Return Return Control_m Control_m Control_m Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Return Return Return Return Control_m Control_m Control_m Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Return Return Return Return Control_m Control_m Control_m Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Return Return Return Return Control_m Control_m Control_m Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Return Return Return Return Control_m Control_m Control_m Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Return Return Return Return Control_m Control_m Control_m Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Return Return Return Return Control_m Control_m Control_m Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m
+keycode 29 = Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control
+keycode 30 = +U+0061 +U+0041 +U+00e6 +U+00c6 Control_a Control_a Control_a Control_a Meta_a Meta_A Meta_a Meta_A Meta_Control_a Meta_Control_a Meta_Control_a Meta_Control_a +U+0061 +U+0041 +U+00e6 +U+00c6 Control_a Control_a Control_a Control_a Meta_a Meta_A Meta_a Meta_A Meta_Control_a Meta_Control_a Meta_Control_a Meta_Control_a +U+0061 +U+0041 +U+00e6 +U+00c6 Control_a Control_a Control_a Control_a Meta_a Meta_A Meta_a Meta_A Meta_Control_a Meta_Control_a Meta_Control_a Meta_Control_a +U+0061 +U+0041 +U+00e6 +U+00c6 Control_a Control_a Control_a Control_a Meta_a Meta_A Meta_a Meta_A Meta_Control_a Meta_Control_a Meta_Control_a Meta_Control_a +U+0041 +U+0061 +U+00c6 +U+00e6 Control_a Control_a Control_a Control_a Meta_a Meta_A Meta_a Meta_A Meta_Control_a Meta_Control_a Meta_Control_a Meta_Control_a +U+0041 +U+0061 +U+00c6 +U+00e6 Control_a Control_a Control_a Control_a Meta_a Meta_A Meta_a Meta_A Meta_Control_a Meta_Control_a Meta_Control_a Meta_Control_a +U+0041 +U+0061 +U+00c6 +U+00e6 Control_a Control_a Control_a Control_a Meta_a Meta_A Meta_a Meta_A Meta_Control_a Meta_Control_a Meta_Control_a Meta_Control_a +U+0041 +U+0061 +U+00c6 +U+00e6 Control_a Control_a Control_a Control_a Meta_a Meta_A Meta_a Meta_A Meta_Control_a Meta_Control_a Meta_Control_a Meta_Control_a
+keycode 31 = +U+0073 +U+0053 +U+00df U+00a7 Control_s Control_s Control_s Control_s Meta_s Meta_S Meta_s Meta_S Meta_Control_s Meta_Control_s Meta_Control_s Meta_Control_s +U+0073 +U+0053 +U+00df U+00a7 Control_s Control_s Control_s Control_s Meta_s Meta_S Meta_s Meta_S Meta_Control_s Meta_Control_s Meta_Control_s Meta_Control_s +U+0073 +U+0053 +U+00df U+00a7 Control_s Control_s Control_s Control_s Meta_s Meta_S Meta_s Meta_S Meta_Control_s Meta_Control_s Meta_Control_s Meta_Control_s +U+0073 +U+0053 +U+00df U+00a7 Control_s Control_s Control_s Control_s Meta_s Meta_S Meta_s Meta_S Meta_Control_s Meta_Control_s Meta_Control_s Meta_Control_s +U+0053 +U+0073 +U+0053 U+00a7 Control_s Control_s Control_s Control_s Meta_s Meta_S Meta_s Meta_S Meta_Control_s Meta_Control_s Meta_Control_s Meta_Control_s +U+0053 +U+0073 +U+0053 U+00a7 Control_s Control_s Control_s Control_s Meta_s Meta_S Meta_s Meta_S Meta_Control_s Meta_Control_s Meta_Control_s Meta_Control_s +U+0053 +U+0073 +U+0053 U+00a7 Control_s Control_s Control_s Control_s Meta_s Meta_S Meta_s Meta_S Meta_Control_s Meta_Control_s Meta_Control_s Meta_Control_s +U+0053 +U+0073 +U+0053 U+00a7 Control_s Control_s Control_s Control_s Meta_s Meta_S Meta_s Meta_S Meta_Control_s Meta_Control_s Meta_Control_s Meta_Control_s
+keycode 32 = +U+0064 +U+0044 +U+00f0 +U+00d0 Control_d Control_d Control_d Control_d Meta_d Meta_D Meta_d Meta_D Meta_Control_d Meta_Control_d Meta_Control_d Meta_Control_d +U+0064 +U+0044 +U+00f0 +U+00d0 Control_d Control_d Control_d Control_d Meta_d Meta_D Meta_d Meta_D Meta_Control_d Meta_Control_d Meta_Control_d Meta_Control_d +U+0064 +U+0044 +U+00f0 +U+00d0 Control_d Control_d Control_d Control_d Meta_d Meta_D Meta_d Meta_D Meta_Control_d Meta_Control_d Meta_Control_d Meta_Control_d +U+0064 +U+0044 +U+00f0 +U+00d0 Control_d Control_d Control_d Control_d Meta_d Meta_D Meta_d Meta_D Meta_Control_d Meta_Control_d Meta_Control_d Meta_Control_d +U+0044 +U+0064 +U+00d0 +U+00f0 Control_d Control_d Control_d Control_d Meta_d Meta_D Meta_d Meta_D Meta_Control_d Meta_Control_d Meta_Control_d Meta_Control_d +U+0044 +U+0064 +U+00d0 +U+00f0 Control_d Control_d Control_d Control_d Meta_d Meta_D Meta_d Meta_D Meta_Control_d Meta_Control_d Meta_Control_d Meta_Control_d +U+0044 +U+0064 +U+00d0 +U+00f0 Control_d Control_d Control_d Control_d Meta_d Meta_D Meta_d Meta_D Meta_Control_d Meta_Control_d Meta_Control_d Meta_Control_d +U+0044 +U+0064 +U+00d0 +U+00f0 Control_d Control_d Control_d Control_d Meta_d Meta_D Meta_d Meta_D Meta_Control_d Meta_Control_d Meta_Control_d Meta_Control_d
+keycode 33 = +U+0066 +U+0046 +U+0111 +U+00aa Control_f Control_f Control_f Control_f Meta_f Meta_F Meta_f Meta_F Meta_Control_f Meta_Control_f Meta_Control_f Meta_Control_f +U+0066 +U+0046 +U+0111 +U+00aa Control_f Control_f Control_f Control_f Meta_f Meta_F Meta_f Meta_F Meta_Control_f Meta_Control_f Meta_Control_f Meta_Control_f +U+0066 +U+0046 +U+0111 +U+00aa Control_f Control_f Control_f Control_f Meta_f Meta_F Meta_f Meta_F Meta_Control_f Meta_Control_f Meta_Control_f Meta_Control_f +U+0066 +U+0046 +U+0111 +U+00aa Control_f Control_f Control_f Control_f Meta_f Meta_F Meta_f Meta_F Meta_Control_f Meta_Control_f Meta_Control_f Meta_Control_f +U+0046 +U+0066 +U+0110 +U+00aa Control_f Control_f Control_f Control_f Meta_f Meta_F Meta_f Meta_F Meta_Control_f Meta_Control_f Meta_Control_f Meta_Control_f +U+0046 +U+0066 +U+0110 +U+00aa Control_f Control_f Control_f Control_f Meta_f Meta_F Meta_f Meta_F Meta_Control_f Meta_Control_f Meta_Control_f Meta_Control_f +U+0046 +U+0066 +U+0110 +U+00aa Control_f Control_f Control_f Control_f Meta_f Meta_F Meta_f Meta_F Meta_Control_f Meta_Control_f Meta_Control_f Meta_Control_f +U+0046 +U+0066 +U+0110 +U+00aa Control_f Control_f Control_f Control_f Meta_f Meta_F Meta_f Meta_F Meta_Control_f Meta_Control_f Meta_Control_f Meta_Control_f
+keycode 34 = +U+0067 +U+0047 +U+014b +U+014a Control_g Control_g Control_g Control_g Meta_g Meta_G Meta_g Meta_G Meta_Control_g Meta_Control_g Meta_Control_g Meta_Control_g +U+0067 +U+0047 +U+014b +U+014a Control_g Control_g Control_g Control_g Meta_g Meta_G Meta_g Meta_G Meta_Control_g Meta_Control_g Meta_Control_g Meta_Control_g +U+0067 +U+0047 +U+014b +U+014a Control_g Control_g Control_g Control_g Meta_g Meta_G Meta_g Meta_G Meta_Control_g Meta_Control_g Meta_Control_g Meta_Control_g +U+0067 +U+0047 +U+014b +U+014a Control_g Control_g Control_g Control_g Meta_g Meta_G Meta_g Meta_G Meta_Control_g Meta_Control_g Meta_Control_g Meta_Control_g +U+0047 +U+0067 +U+014a +U+014b Control_g Control_g Control_g Control_g Meta_g Meta_G Meta_g Meta_G Meta_Control_g Meta_Control_g Meta_Control_g Meta_Control_g +U+0047 +U+0067 +U+014a +U+014b Control_g Control_g Control_g Control_g Meta_g Meta_G Meta_g Meta_G Meta_Control_g Meta_Control_g Meta_Control_g Meta_Control_g +U+0047 +U+0067 +U+014a +U+014b Control_g Control_g Control_g Control_g Meta_g Meta_G Meta_g Meta_G Meta_Control_g Meta_Control_g Meta_Control_g Meta_Control_g +U+0047 +U+0067 +U+014a +U+014b Control_g Control_g Control_g Control_g Meta_g Meta_G Meta_g Meta_G Meta_Control_g Meta_Control_g Meta_Control_g Meta_Control_g
+keycode 35 = +U+0068 +U+0048 +U+0127 +U+0126 BackSpace BackSpace BackSpace BackSpace Meta_h Meta_H Meta_h Meta_H Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace +U+0068 +U+0048 +U+0127 +U+0126 BackSpace BackSpace BackSpace BackSpace Meta_h Meta_H Meta_h Meta_H Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace +U+0068 +U+0048 +U+0127 +U+0126 BackSpace BackSpace BackSpace BackSpace Meta_h Meta_H Meta_h Meta_H Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace +U+0068 +U+0048 +U+0127 +U+0126 BackSpace BackSpace BackSpace BackSpace Meta_h Meta_H Meta_h Meta_H Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace +U+0048 +U+0068 +U+0126 +U+0127 BackSpace BackSpace BackSpace BackSpace Meta_h Meta_H Meta_h Meta_H Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace +U+0048 +U+0068 +U+0126 +U+0127 BackSpace BackSpace BackSpace BackSpace Meta_h Meta_H Meta_h Meta_H Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace +U+0048 +U+0068 +U+0126 +U+0127 BackSpace BackSpace BackSpace BackSpace Meta_h Meta_H Meta_h Meta_H Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace +U+0048 +U+0068 +U+0126 +U+0127 BackSpace BackSpace BackSpace BackSpace Meta_h Meta_H Meta_h Meta_H Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace
+keycode 36 = +U+006a +U+004a U+0309 U+031b Linefeed Linefeed Linefeed Linefeed Meta_j Meta_J Meta_j Meta_J Meta_Linefeed Meta_Linefeed Meta_Linefeed Meta_Linefeed +U+006a +U+004a U+0309 U+031b Linefeed Linefeed Linefeed Linefeed Meta_j Meta_J Meta_j Meta_J Meta_Linefeed Meta_Linefeed Meta_Linefeed Meta_Linefeed +U+006a +U+004a U+0309 U+031b Linefeed Linefeed Linefeed Linefeed Meta_j Meta_J Meta_j Meta_J Meta_Linefeed Meta_Linefeed Meta_Linefeed Meta_Linefeed +U+006a +U+004a U+0309 U+031b Linefeed Linefeed Linefeed Linefeed Meta_j Meta_J Meta_j Meta_J Meta_Linefeed Meta_Linefeed Meta_Linefeed Meta_Linefeed +U+004a +U+006a U+0309 U+031b Linefeed Linefeed Linefeed Linefeed Meta_j Meta_J Meta_j Meta_J Meta_Linefeed Meta_Linefeed Meta_Linefeed Meta_Linefeed +U+004a +U+006a U+0309 U+031b Linefeed Linefeed Linefeed Linefeed Meta_j Meta_J Meta_j Meta_J Meta_Linefeed Meta_Linefeed Meta_Linefeed Meta_Linefeed +U+004a +U+006a U+0309 U+031b Linefeed Linefeed Linefeed Linefeed Meta_j Meta_J Meta_j Meta_J Meta_Linefeed Meta_Linefeed Meta_Linefeed Meta_Linefeed +U+004a +U+006a U+0309 U+031b Linefeed Linefeed Linefeed Linefeed Meta_j Meta_J Meta_j Meta_J Meta_Linefeed Meta_Linefeed Meta_Linefeed Meta_Linefeed
+keycode 37 = +U+006b +U+004b +U+0138 U+0026 Control_k Control_k Control_k Control_k Meta_k Meta_K Meta_k Meta_ampersand Meta_Control_k Meta_Control_k Meta_Control_k Meta_Control_k +U+006b +U+004b +U+0138 U+0026 Control_k Control_k Control_k Control_k Meta_k Meta_K Meta_k Meta_ampersand Meta_Control_k Meta_Control_k Meta_Control_k Meta_Control_k +U+006b +U+004b +U+0138 U+0026 Control_k Control_k Control_k Control_k Meta_k Meta_K Meta_k Meta_ampersand Meta_Control_k Meta_Control_k Meta_Control_k Meta_Control_k +U+006b +U+004b +U+0138 U+0026 Control_k Control_k Control_k Control_k Meta_k Meta_K Meta_k Meta_ampersand Meta_Control_k Meta_Control_k Meta_Control_k Meta_Control_k +U+004b +U+006b +U+0138 U+0026 Control_k Control_k Control_k Control_k Meta_k Meta_K Meta_k Meta_ampersand Meta_Control_k Meta_Control_k Meta_Control_k Meta_Control_k +U+004b +U+006b +U+0138 U+0026 Control_k Control_k Control_k Control_k Meta_k Meta_K Meta_k Meta_ampersand Meta_Control_k Meta_Control_k Meta_Control_k Meta_Control_k +U+004b +U+006b +U+0138 U+0026 Control_k Control_k Control_k Control_k Meta_k Meta_K Meta_k Meta_ampersand Meta_Control_k Meta_Control_k Meta_Control_k Meta_Control_k +U+004b +U+006b +U+0138 U+0026 Control_k Control_k Control_k Control_k Meta_k Meta_K Meta_k Meta_ampersand Meta_Control_k Meta_Control_k Meta_Control_k Meta_Control_k
+keycode 38 = +U+006c +U+004c +U+0142 +U+0141 Control_l Control_l Control_l Control_l Meta_l Meta_L Meta_l Meta_L Meta_Control_l Meta_Control_l Meta_Control_l Meta_Control_l +U+006c +U+004c +U+0142 +U+0141 Control_l Control_l Control_l Control_l Meta_l Meta_L Meta_l Meta_L Meta_Control_l Meta_Control_l Meta_Control_l Meta_Control_l +U+006c +U+004c +U+0142 +U+0141 Control_l Control_l Control_l Control_l Meta_l Meta_L Meta_l Meta_L Meta_Control_l Meta_Control_l Meta_Control_l Meta_Control_l +U+006c +U+004c +U+0142 +U+0141 Control_l Control_l Control_l Control_l Meta_l Meta_L Meta_l Meta_L Meta_Control_l Meta_Control_l Meta_Control_l Meta_Control_l +U+004c +U+006c +U+0141 +U+0142 Control_l Control_l Control_l Control_l Meta_l Meta_L Meta_l Meta_L Meta_Control_l Meta_Control_l Meta_Control_l Meta_Control_l +U+004c +U+006c +U+0141 +U+0142 Control_l Control_l Control_l Control_l Meta_l Meta_L Meta_l Meta_L Meta_Control_l Meta_Control_l Meta_Control_l Meta_Control_l +U+004c +U+006c +U+0141 +U+0142 Control_l Control_l Control_l Control_l Meta_l Meta_L Meta_l Meta_L Meta_Control_l Meta_Control_l Meta_Control_l Meta_Control_l +U+004c +U+006c +U+0141 +U+0142 Control_l Control_l Control_l Control_l Meta_l Meta_L Meta_l Meta_L Meta_Control_l Meta_Control_l Meta_Control_l Meta_Control_l
+keycode 39 = U+003b U+003a dead_acute dead_doubleacute dead_acute dead_doubleacute dead_acute dead_doubleacute Meta_semicolon Meta_colon dead_acute dead_doubleacute dead_acute dead_doubleacute dead_acute dead_doubleacute U+003b U+003a dead_acute dead_doubleacute dead_acute dead_doubleacute dead_acute dead_doubleacute Meta_semicolon Meta_colon dead_acute dead_doubleacute dead_acute dead_doubleacute dead_acute dead_doubleacute U+003b U+003a dead_acute dead_doubleacute dead_acute dead_doubleacute dead_acute dead_doubleacute Meta_semicolon Meta_colon dead_acute dead_doubleacute dead_acute dead_doubleacute dead_acute dead_doubleacute U+003b U+003a dead_acute dead_doubleacute dead_acute dead_doubleacute dead_acute dead_doubleacute Meta_semicolon Meta_colon dead_acute dead_doubleacute dead_acute dead_doubleacute dead_acute dead_doubleacute U+003b U+003a dead_acute dead_doubleacute dead_acute dead_doubleacute dead_acute dead_doubleacute Meta_semicolon Meta_colon dead_acute dead_doubleacute dead_acute dead_doubleacute dead_acute dead_doubleacute U+003b U+003a dead_acute dead_doubleacute dead_acute dead_doubleacute dead_acute dead_doubleacute Meta_semicolon Meta_colon dead_acute dead_doubleacute dead_acute dead_doubleacute dead_acute dead_doubleacute U+003b U+003a dead_acute dead_doubleacute dead_acute dead_doubleacute dead_acute dead_doubleacute Meta_semicolon Meta_colon dead_acute dead_doubleacute dead_acute dead_doubleacute dead_acute dead_doubleacute U+003b U+003a dead_acute dead_doubleacute dead_acute dead_doubleacute dead_acute dead_doubleacute Meta_semicolon Meta_colon dead_acute dead_doubleacute dead_acute dead_doubleacute dead_acute dead_doubleacute
+keycode 40 = U+0027 U+0040 dead_circumflex dead_caron Control_g nul dead_circumflex dead_caron Meta_apostrophe Meta_at dead_circumflex dead_caron Meta_Control_g Meta_nul dead_circumflex dead_caron U+0027 U+0040 dead_circumflex dead_caron Control_g nul dead_circumflex dead_caron Meta_apostrophe Meta_at dead_circumflex dead_caron Meta_Control_g Meta_nul dead_circumflex dead_caron U+0027 U+0040 dead_circumflex dead_caron Control_g nul dead_circumflex dead_caron Meta_apostrophe Meta_at dead_circumflex dead_caron Meta_Control_g Meta_nul dead_circumflex dead_caron U+0027 U+0040 dead_circumflex dead_caron Control_g nul dead_circumflex dead_caron Meta_apostrophe Meta_at dead_circumflex dead_caron Meta_Control_g Meta_nul dead_circumflex dead_caron U+0027 U+0040 dead_circumflex dead_caron Control_g nul dead_circumflex dead_caron Meta_apostrophe Meta_at dead_circumflex dead_caron Meta_Control_g Meta_nul dead_circumflex dead_caron U+0027 U+0040 dead_circumflex dead_caron Control_g nul dead_circumflex dead_caron Meta_apostrophe Meta_at dead_circumflex dead_caron Meta_Control_g Meta_nul dead_circumflex dead_caron U+0027 U+0040 dead_circumflex dead_caron Control_g nul dead_circumflex dead_caron Meta_apostrophe Meta_at dead_circumflex dead_caron Meta_Control_g Meta_nul dead_circumflex dead_caron U+0027 U+0040 dead_circumflex dead_caron Control_g nul dead_circumflex dead_caron Meta_apostrophe Meta_at dead_circumflex dead_caron Meta_Control_g Meta_nul dead_circumflex dead_caron
+keycode 41 = U+0060 U+00ac U+007c U+007c nul nul nul nul Meta_grave Meta_grave Meta_bar Meta_bar Meta_nul Meta_nul Meta_nul Meta_nul U+0060 U+00ac U+007c U+007c nul nul nul nul Meta_grave Meta_grave Meta_bar Meta_bar Meta_nul Meta_nul Meta_nul Meta_nul U+0060 U+00ac U+007c U+007c nul nul nul nul Meta_grave Meta_grave Meta_bar Meta_bar Meta_nul Meta_nul Meta_nul Meta_nul U+0060 U+00ac U+007c U+007c nul nul nul nul Meta_grave Meta_grave Meta_bar Meta_bar Meta_nul Meta_nul Meta_nul Meta_nul U+0060 U+00ac U+007c U+007c nul nul nul nul Meta_grave Meta_grave Meta_bar Meta_bar Meta_nul Meta_nul Meta_nul Meta_nul U+0060 U+00ac U+007c U+007c nul nul nul nul Meta_grave Meta_grave Meta_bar Meta_bar Meta_nul Meta_nul Meta_nul Meta_nul U+0060 U+00ac U+007c U+007c nul nul nul nul Meta_grave Meta_grave Meta_bar Meta_bar Meta_nul Meta_nul Meta_nul Meta_nul U+0060 U+00ac U+007c U+007c nul nul nul nul Meta_grave Meta_grave Meta_bar Meta_bar Meta_nul Meta_nul Meta_nul Meta_nul
+keycode 42 = Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift
+keycode 43 = U+0023 U+007e dead_grave dead_breve dead_grave dead_breve dead_grave dead_breve Meta_numbersign Meta_asciitilde dead_grave dead_breve dead_grave dead_breve dead_grave dead_breve U+0023 U+007e dead_grave dead_breve dead_grave dead_breve dead_grave dead_breve Meta_numbersign Meta_asciitilde dead_grave dead_breve dead_grave dead_breve dead_grave dead_breve U+0023 U+007e dead_grave dead_breve dead_grave dead_breve dead_grave dead_breve Meta_numbersign Meta_asciitilde dead_grave dead_breve dead_grave dead_breve dead_grave dead_breve U+0023 U+007e dead_grave dead_breve dead_grave dead_breve dead_grave dead_breve Meta_numbersign Meta_asciitilde dead_grave dead_breve dead_grave dead_breve dead_grave dead_breve U+0023 U+007e dead_grave dead_breve dead_grave dead_breve dead_grave dead_breve Meta_numbersign Meta_asciitilde dead_grave dead_breve dead_grave dead_breve dead_grave dead_breve U+0023 U+007e dead_grave dead_breve dead_grave dead_breve dead_grave dead_breve Meta_numbersign Meta_asciitilde dead_grave dead_breve dead_grave dead_breve dead_grave dead_breve U+0023 U+007e dead_grave dead_breve dead_grave dead_breve dead_grave dead_breve Meta_numbersign Meta_asciitilde dead_grave dead_breve dead_grave dead_breve dead_grave dead_breve U+0023 U+007e dead_grave dead_breve dead_grave dead_breve dead_grave dead_breve Meta_numbersign Meta_asciitilde dead_grave dead_breve dead_grave dead_breve dead_grave dead_breve
+keycode 44 = +U+007a +U+005a U+00ab U+003c Control_z Control_z Control_z Control_z Meta_z Meta_Z Meta_z Meta_less Meta_Control_z Meta_Control_z Meta_Control_z Meta_Control_z +U+007a +U+005a U+00ab U+003c Control_z Control_z Control_z Control_z Meta_z Meta_Z Meta_z Meta_less Meta_Control_z Meta_Control_z Meta_Control_z Meta_Control_z +U+007a +U+005a U+00ab U+003c Control_z Control_z Control_z Control_z Meta_z Meta_Z Meta_z Meta_less Meta_Control_z Meta_Control_z Meta_Control_z Meta_Control_z +U+007a +U+005a U+00ab U+003c Control_z Control_z Control_z Control_z Meta_z Meta_Z Meta_z Meta_less Meta_Control_z Meta_Control_z Meta_Control_z Meta_Control_z +U+005a +U+007a U+00ab U+003c Control_z Control_z Control_z Control_z Meta_z Meta_Z Meta_z Meta_less Meta_Control_z Meta_Control_z Meta_Control_z Meta_Control_z +U+005a +U+007a U+00ab U+003c Control_z Control_z Control_z Control_z Meta_z Meta_Z Meta_z Meta_less Meta_Control_z Meta_Control_z Meta_Control_z Meta_Control_z +U+005a +U+007a U+00ab U+003c Control_z Control_z Control_z Control_z Meta_z Meta_Z Meta_z Meta_less Meta_Control_z Meta_Control_z Meta_Control_z Meta_Control_z +U+005a +U+007a U+00ab U+003c Control_z Control_z Control_z Control_z Meta_z Meta_Z Meta_z Meta_less Meta_Control_z Meta_Control_z Meta_Control_z Meta_Control_z
+keycode 45 = +U+0078 +U+0058 U+00bb U+003e Control_x Control_x Control_x Control_x Meta_x Meta_X Meta_x Meta_greater Meta_Control_x Meta_Control_x Meta_Control_x Meta_Control_x +U+0078 +U+0058 U+00bb U+003e Control_x Control_x Control_x Control_x Meta_x Meta_X Meta_x Meta_greater Meta_Control_x Meta_Control_x Meta_Control_x Meta_Control_x +U+0078 +U+0058 U+00bb U+003e Control_x Control_x Control_x Control_x Meta_x Meta_X Meta_x Meta_greater Meta_Control_x Meta_Control_x Meta_Control_x Meta_Control_x +U+0078 +U+0058 U+00bb U+003e Control_x Control_x Control_x Control_x Meta_x Meta_X Meta_x Meta_greater Meta_Control_x Meta_Control_x Meta_Control_x Meta_Control_x +U+0058 +U+0078 U+00bb U+003e Control_x Control_x Control_x Control_x Meta_x Meta_X Meta_x Meta_greater Meta_Control_x Meta_Control_x Meta_Control_x Meta_Control_x +U+0058 +U+0078 U+00bb U+003e Control_x Control_x Control_x Control_x Meta_x Meta_X Meta_x Meta_greater Meta_Control_x Meta_Control_x Meta_Control_x Meta_Control_x +U+0058 +U+0078 U+00bb U+003e Control_x Control_x Control_x Control_x Meta_x Meta_X Meta_x Meta_greater Meta_Control_x Meta_Control_x Meta_Control_x Meta_Control_x +U+0058 +U+0078 U+00bb U+003e Control_x Control_x Control_x Control_x Meta_x Meta_X Meta_x Meta_greater Meta_Control_x Meta_Control_x Meta_Control_x Meta_Control_x
+keycode 46 = +U+0063 +U+0043 U+00a2 U+00a9 Control_c Control_c Control_c Control_c Meta_c Meta_C Meta_c Meta_C Meta_Control_c Meta_Control_c Meta_Control_c Meta_Control_c +U+0063 +U+0043 U+00a2 U+00a9 Control_c Control_c Control_c Control_c Meta_c Meta_C Meta_c Meta_C Meta_Control_c Meta_Control_c Meta_Control_c Meta_Control_c +U+0063 +U+0043 U+00a2 U+00a9 Control_c Control_c Control_c Control_c Meta_c Meta_C Meta_c Meta_C Meta_Control_c Meta_Control_c Meta_Control_c Meta_Control_c +U+0063 +U+0043 U+00a2 U+00a9 Control_c Control_c Control_c Control_c Meta_c Meta_C Meta_c Meta_C Meta_Control_c Meta_Control_c Meta_Control_c Meta_Control_c +U+0043 +U+0063 U+00a2 U+00a9 Control_c Control_c Control_c Control_c Meta_c Meta_C Meta_c Meta_C Meta_Control_c Meta_Control_c Meta_Control_c Meta_Control_c +U+0043 +U+0063 U+00a2 U+00a9 Control_c Control_c Control_c Control_c Meta_c Meta_C Meta_c Meta_C Meta_Control_c Meta_Control_c Meta_Control_c Meta_Control_c +U+0043 +U+0063 U+00a2 U+00a9 Control_c Control_c Control_c Control_c Meta_c Meta_C Meta_c Meta_C Meta_Control_c Meta_Control_c Meta_Control_c Meta_Control_c +U+0043 +U+0063 U+00a2 U+00a9 Control_c Control_c Control_c Control_c Meta_c Meta_C Meta_c Meta_C Meta_Control_c Meta_Control_c Meta_Control_c Meta_Control_c
+keycode 47 = +U+0076 +U+0056 U+201c U+2018 Control_v Control_v Control_v Control_v Meta_v Meta_V Meta_v Meta_V Meta_Control_v Meta_Control_v Meta_Control_v Meta_Control_v +U+0076 +U+0056 U+201c U+2018 Control_v Control_v Control_v Control_v Meta_v Meta_V Meta_v Meta_V Meta_Control_v Meta_Control_v Meta_Control_v Meta_Control_v +U+0076 +U+0056 U+201c U+2018 Control_v Control_v Control_v Control_v Meta_v Meta_V Meta_v Meta_V Meta_Control_v Meta_Control_v Meta_Control_v Meta_Control_v +U+0076 +U+0056 U+201c U+2018 Control_v Control_v Control_v Control_v Meta_v Meta_V Meta_v Meta_V Meta_Control_v Meta_Control_v Meta_Control_v Meta_Control_v +U+0056 +U+0076 U+201c U+2018 Control_v Control_v Control_v Control_v Meta_v Meta_V Meta_v Meta_V Meta_Control_v Meta_Control_v Meta_Control_v Meta_Control_v +U+0056 +U+0076 U+201c U+2018 Control_v Control_v Control_v Control_v Meta_v Meta_V Meta_v Meta_V Meta_Control_v Meta_Control_v Meta_Control_v Meta_Control_v +U+0056 +U+0076 U+201c U+2018 Control_v Control_v Control_v Control_v Meta_v Meta_V Meta_v Meta_V Meta_Control_v Meta_Control_v Meta_Control_v Meta_Control_v +U+0056 +U+0076 U+201c U+2018 Control_v Control_v Control_v Control_v Meta_v Meta_V Meta_v Meta_V Meta_Control_v Meta_Control_v Meta_Control_v Meta_Control_v
+keycode 48 = +U+0062 +U+0042 U+201d U+2019 Control_b Control_b Control_b Control_b Meta_b Meta_B Meta_b Meta_B Meta_Control_b Meta_Control_b Meta_Control_b Meta_Control_b +U+0062 +U+0042 U+201d U+2019 Control_b Control_b Control_b Control_b Meta_b Meta_B Meta_b Meta_B Meta_Control_b Meta_Control_b Meta_Control_b Meta_Control_b +U+0062 +U+0042 U+201d U+2019 Control_b Control_b Control_b Control_b Meta_b Meta_B Meta_b Meta_B Meta_Control_b Meta_Control_b Meta_Control_b Meta_Control_b +U+0062 +U+0042 U+201d U+2019 Control_b Control_b Control_b Control_b Meta_b Meta_B Meta_b Meta_B Meta_Control_b Meta_Control_b Meta_Control_b Meta_Control_b +U+0042 +U+0062 U+201d U+2019 Control_b Control_b Control_b Control_b Meta_b Meta_B Meta_b Meta_B Meta_Control_b Meta_Control_b Meta_Control_b Meta_Control_b +U+0042 +U+0062 U+201d U+2019 Control_b Control_b Control_b Control_b Meta_b Meta_B Meta_b Meta_B Meta_Control_b Meta_Control_b Meta_Control_b Meta_Control_b +U+0042 +U+0062 U+201d U+2019 Control_b Control_b Control_b Control_b Meta_b Meta_B Meta_b Meta_B Meta_Control_b Meta_Control_b Meta_Control_b Meta_Control_b +U+0042 +U+0062 U+201d U+2019 Control_b Control_b Control_b Control_b Meta_b Meta_B Meta_b Meta_B Meta_Control_b Meta_Control_b Meta_Control_b Meta_Control_b
+keycode 49 = +U+006e +U+004e +U+006e +U+004e Control_n Control_n Control_n Control_n Meta_n Meta_N Meta_n Meta_N Meta_Control_n Meta_Control_n Meta_Control_n Meta_Control_n +U+006e +U+004e +U+006e +U+004e Control_n Control_n Control_n Control_n Meta_n Meta_N Meta_n Meta_N Meta_Control_n Meta_Control_n Meta_Control_n Meta_Control_n +U+006e +U+004e +U+006e +U+004e Control_n Control_n Control_n Control_n Meta_n Meta_N Meta_n Meta_N Meta_Control_n Meta_Control_n Meta_Control_n Meta_Control_n +U+006e +U+004e +U+006e +U+004e Control_n Control_n Control_n Control_n Meta_n Meta_N Meta_n Meta_N Meta_Control_n Meta_Control_n Meta_Control_n Meta_Control_n +U+004e +U+006e +U+004e +U+006e Control_n Control_n Control_n Control_n Meta_n Meta_N Meta_n Meta_N Meta_Control_n Meta_Control_n Meta_Control_n Meta_Control_n +U+004e +U+006e +U+004e +U+006e Control_n Control_n Control_n Control_n Meta_n Meta_N Meta_n Meta_N Meta_Control_n Meta_Control_n Meta_Control_n Meta_Control_n +U+004e +U+006e +U+004e +U+006e Control_n Control_n Control_n Control_n Meta_n Meta_N Meta_n Meta_N Meta_Control_n Meta_Control_n Meta_Control_n Meta_Control_n +U+004e +U+006e +U+004e +U+006e Control_n Control_n Control_n Control_n Meta_n Meta_N Meta_n Meta_N Meta_Control_n Meta_Control_n Meta_Control_n Meta_Control_n
+keycode 50 = +U+006d +U+004d +U+00b5 +U+00ba Control_m Control_m Control_m Control_m Meta_m Meta_M Meta_m Meta_M Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m +U+006d +U+004d +U+00b5 +U+00ba Control_m Control_m Control_m Control_m Meta_m Meta_M Meta_m Meta_M Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m +U+006d +U+004d +U+00b5 +U+00ba Control_m Control_m Control_m Control_m Meta_m Meta_M Meta_m Meta_M Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m +U+006d +U+004d +U+00b5 +U+00ba Control_m Control_m Control_m Control_m Meta_m Meta_M Meta_m Meta_M Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m +U+004d +U+006d +U+039c +U+00ba Control_m Control_m Control_m Control_m Meta_m Meta_M Meta_m Meta_M Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m +U+004d +U+006d +U+039c +U+00ba Control_m Control_m Control_m Control_m Meta_m Meta_M Meta_m Meta_M Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m +U+004d +U+006d +U+039c +U+00ba Control_m Control_m Control_m Control_m Meta_m Meta_M Meta_m Meta_M Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m +U+004d +U+006d +U+039c +U+00ba Control_m Control_m Control_m Control_m Meta_m Meta_M Meta_m Meta_M Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m
+keycode 51 = U+002c U+003c U+2500 U+00d7 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_comma Meta_less Meta_comma Meta_less VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+002c U+003c U+2500 U+00d7 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_comma Meta_less Meta_comma Meta_less VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+002c U+003c U+2500 U+00d7 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_comma Meta_less Meta_comma Meta_less VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+002c U+003c U+2500 U+00d7 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_comma Meta_less Meta_comma Meta_less VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+002c U+003c U+2500 U+00d7 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_comma Meta_less Meta_comma Meta_less VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+002c U+003c U+2500 U+00d7 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_comma Meta_less Meta_comma Meta_less VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+002c U+003c U+2500 U+00d7 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_comma Meta_less Meta_comma Meta_less VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+002c U+003c U+2500 U+00d7 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_comma Meta_less Meta_comma Meta_less VoidSymbol VoidSymbol VoidSymbol VoidSymbol
+keycode 52 = U+002e U+003e U+00b7 U+00f7 Compose Compose Compose Compose Meta_period Meta_greater Meta_period Meta_greater Compose Compose Compose Compose U+002e U+003e U+00b7 U+00f7 Compose Compose Compose Compose Meta_period Meta_greater Meta_period Meta_greater Compose Compose Compose Compose U+002e U+003e U+00b7 U+00f7 Compose Compose Compose Compose Meta_period Meta_greater Meta_period Meta_greater Compose Compose Compose Compose U+002e U+003e U+00b7 U+00f7 Compose Compose Compose Compose Meta_period Meta_greater Meta_period Meta_greater Compose Compose Compose Compose U+002e U+003e U+00b7 U+00f7 Compose Compose Compose Compose Meta_period Meta_greater Meta_period Meta_greater Compose Compose Compose Compose U+002e U+003e U+00b7 U+00f7 Compose Compose Compose Compose Meta_period Meta_greater Meta_period Meta_greater Compose Compose Compose Compose U+002e U+003e U+00b7 U+00f7 Compose Compose Compose Compose Meta_period Meta_greater Meta_period Meta_greater Compose Compose Compose Compose U+002e U+003e U+00b7 U+00f7 Compose Compose Compose Compose Meta_period Meta_greater Meta_period Meta_greater Compose Compose Compose Compose
+keycode 53 = U+002f U+003f U+0323 U+002e Delete Delete Compose Compose Meta_slash Meta_question Meta_slash Meta_period Meta_Delete Meta_Delete Compose Compose U+002f U+003f U+0323 U+002e Delete Delete Compose Compose Meta_slash Meta_question Meta_slash Meta_period Meta_Delete Meta_Delete Compose Compose U+002f U+003f U+0323 U+002e Delete Delete Compose Compose Meta_slash Meta_question Meta_slash Meta_period Meta_Delete Meta_Delete Compose Compose U+002f U+003f U+0323 U+002e Delete Delete Compose Compose Meta_slash Meta_question Meta_slash Meta_period Meta_Delete Meta_Delete Compose Compose U+002f U+003f U+0323 U+002e Delete Delete Compose Compose Meta_slash Meta_question Meta_slash Meta_period Meta_Delete Meta_Delete Compose Compose U+002f U+003f U+0323 U+002e Delete Delete Compose Compose Meta_slash Meta_question Meta_slash Meta_period Meta_Delete Meta_Delete Compose Compose U+002f U+003f U+0323 U+002e Delete Delete Compose Compose Meta_slash Meta_question Meta_slash Meta_period Meta_Delete Meta_Delete Compose Compose U+002f U+003f U+0323 U+002e Delete Delete Compose Compose Meta_slash Meta_question Meta_slash Meta_period Meta_Delete Meta_Delete Compose Compose
+keycode 54 = Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift
+keycode 55 = KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply
+keycode 56 = Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt
+keycode 57 = U+0020 U+0020 U+0020 U+0020 nul nul nul nul Meta_space Meta_space Meta_space Meta_space Meta_nul Meta_nul Meta_nul Meta_nul U+0020 U+0020 U+0020 U+0020 nul nul nul nul Meta_space Meta_space Meta_space Meta_space Meta_nul Meta_nul Meta_nul Meta_nul U+0020 U+0020 U+0020 U+0020 nul nul nul nul Meta_space Meta_space Meta_space Meta_space Meta_nul Meta_nul Meta_nul Meta_nul U+0020 U+0020 U+0020 U+0020 nul nul nul nul Meta_space Meta_space Meta_space Meta_space Meta_nul Meta_nul Meta_nul Meta_nul U+0020 U+0020 U+0020 U+0020 nul nul nul nul Meta_space Meta_space Meta_space Meta_space Meta_nul Meta_nul Meta_nul Meta_nul U+0020 U+0020 U+0020 U+0020 nul nul nul nul Meta_space Meta_space Meta_space Meta_space Meta_nul Meta_nul Meta_nul Meta_nul U+0020 U+0020 U+0020 U+0020 nul nul nul nul Meta_space Meta_space Meta_space Meta_space Meta_nul Meta_nul Meta_nul Meta_nul U+0020 U+0020 U+0020 U+0020 nul nul nul nul Meta_space Meta_space Meta_space Meta_space Meta_nul Meta_nul Meta_nul Meta_nul
+keycode 58 = CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock
+keycode 59 = F1 F13 Console_13 Console_25 F25 F37 Console_13 Console_25 Console_1 Console_13 F1 F1 Console_1 Console_13 F1 F1 F1 F13 Console_13 Console_25 F25 F37 Console_13 Console_25 Console_1 Console_13 F1 F1 Console_1 Console_13 F1 F1 F1 F13 Console_13 Console_25 F25 F37 Console_13 Console_25 Console_1 Console_13 F1 F1 Console_1 Console_13 F1 F1 F1 F13 Console_13 Console_25 F25 F37 Console_13 Console_25 Console_1 Console_13 F1 F1 Console_1 Console_13 F1 F1 F1 F13 Console_13 Console_25 F25 F37 Console_13 Console_25 Console_1 Console_13 F1 F1 Console_1 Console_13 F1 F1 F1 F13 Console_13 Console_25 F25 F37 Console_13 Console_25 Console_1 Console_13 F1 F1 Console_1 Console_13 F1 F1 F1 F13 Console_13 Console_25 F25 F37 Console_13 Console_25 Console_1 Console_13 F1 F1 Console_1 Console_13 F1 F1 F1 F13 Console_13 Console_25 F25 F37 Console_13 Console_25 Console_1 Console_13 F1 F1 Console_1 Console_13 F1 F1
+keycode 60 = F2 F14 Console_14 Console_26 F26 F38 Console_14 Console_26 Console_2 Console_14 F2 F2 Console_2 Console_14 F2 F2 F2 F14 Console_14 Console_26 F26 F38 Console_14 Console_26 Console_2 Console_14 F2 F2 Console_2 Console_14 F2 F2 F2 F14 Console_14 Console_26 F26 F38 Console_14 Console_26 Console_2 Console_14 F2 F2 Console_2 Console_14 F2 F2 F2 F14 Console_14 Console_26 F26 F38 Console_14 Console_26 Console_2 Console_14 F2 F2 Console_2 Console_14 F2 F2 F2 F14 Console_14 Console_26 F26 F38 Console_14 Console_26 Console_2 Console_14 F2 F2 Console_2 Console_14 F2 F2 F2 F14 Console_14 Console_26 F26 F38 Console_14 Console_26 Console_2 Console_14 F2 F2 Console_2 Console_14 F2 F2 F2 F14 Console_14 Console_26 F26 F38 Console_14 Console_26 Console_2 Console_14 F2 F2 Console_2 Console_14 F2 F2 F2 F14 Console_14 Console_26 F26 F38 Console_14 Console_26 Console_2 Console_14 F2 F2 Console_2 Console_14 F2 F2
+keycode 61 = F3 F15 Console_15 Console_27 F27 F39 Console_15 Console_27 Console_3 Console_15 F3 F3 Console_3 Console_15 F3 F3 F3 F15 Console_15 Console_27 F27 F39 Console_15 Console_27 Console_3 Console_15 F3 F3 Console_3 Console_15 F3 F3 F3 F15 Console_15 Console_27 F27 F39 Console_15 Console_27 Console_3 Console_15 F3 F3 Console_3 Console_15 F3 F3 F3 F15 Console_15 Console_27 F27 F39 Console_15 Console_27 Console_3 Console_15 F3 F3 Console_3 Console_15 F3 F3 F3 F15 Console_15 Console_27 F27 F39 Console_15 Console_27 Console_3 Console_15 F3 F3 Console_3 Console_15 F3 F3 F3 F15 Console_15 Console_27 F27 F39 Console_15 Console_27 Console_3 Console_15 F3 F3 Console_3 Console_15 F3 F3 F3 F15 Console_15 Console_27 F27 F39 Console_15 Console_27 Console_3 Console_15 F3 F3 Console_3 Console_15 F3 F3 F3 F15 Console_15 Console_27 F27 F39 Console_15 Console_27 Console_3 Console_15 F3 F3 Console_3 Console_15 F3 F3
+keycode 62 = F4 F16 Console_16 Console_28 F28 F40 Console_16 Console_28 Console_4 Console_16 F4 F4 Console_4 Console_16 F4 F4 F4 F16 Console_16 Console_28 F28 F40 Console_16 Console_28 Console_4 Console_16 F4 F4 Console_4 Console_16 F4 F4 F4 F16 Console_16 Console_28 F28 F40 Console_16 Console_28 Console_4 Console_16 F4 F4 Console_4 Console_16 F4 F4 F4 F16 Console_16 Console_28 F28 F40 Console_16 Console_28 Console_4 Console_16 F4 F4 Console_4 Console_16 F4 F4 F4 F16 Console_16 Console_28 F28 F40 Console_16 Console_28 Console_4 Console_16 F4 F4 Console_4 Console_16 F4 F4 F4 F16 Console_16 Console_28 F28 F40 Console_16 Console_28 Console_4 Console_16 F4 F4 Console_4 Console_16 F4 F4 F4 F16 Console_16 Console_28 F28 F40 Console_16 Console_28 Console_4 Console_16 F4 F4 Console_4 Console_16 F4 F4 F4 F16 Console_16 Console_28 F28 F40 Console_16 Console_28 Console_4 Console_16 F4 F4 Console_4 Console_16 F4 F4
+keycode 63 = F5 F17 Console_17 Console_29 F29 F41 Console_17 Console_29 Console_5 Console_17 F5 F5 Console_5 Console_17 F5 F5 F5 F17 Console_17 Console_29 F29 F41 Console_17 Console_29 Console_5 Console_17 F5 F5 Console_5 Console_17 F5 F5 F5 F17 Console_17 Console_29 F29 F41 Console_17 Console_29 Console_5 Console_17 F5 F5 Console_5 Console_17 F5 F5 F5 F17 Console_17 Console_29 F29 F41 Console_17 Console_29 Console_5 Console_17 F5 F5 Console_5 Console_17 F5 F5 F5 F17 Console_17 Console_29 F29 F41 Console_17 Console_29 Console_5 Console_17 F5 F5 Console_5 Console_17 F5 F5 F5 F17 Console_17 Console_29 F29 F41 Console_17 Console_29 Console_5 Console_17 F5 F5 Console_5 Console_17 F5 F5 F5 F17 Console_17 Console_29 F29 F41 Console_17 Console_29 Console_5 Console_17 F5 F5 Console_5 Console_17 F5 F5 F5 F17 Console_17 Console_29 F29 F41 Console_17 Console_29 Console_5 Console_17 F5 F5 Console_5 Console_17 F5 F5
+keycode 64 = F6 F18 Console_18 Console_30 F30 F42 Console_18 Console_30 Console_6 Console_18 F6 F6 Console_6 Console_18 F6 F6 F6 F18 Console_18 Console_30 F30 F42 Console_18 Console_30 Console_6 Console_18 F6 F6 Console_6 Console_18 F6 F6 F6 F18 Console_18 Console_30 F30 F42 Console_18 Console_30 Console_6 Console_18 F6 F6 Console_6 Console_18 F6 F6 F6 F18 Console_18 Console_30 F30 F42 Console_18 Console_30 Console_6 Console_18 F6 F6 Console_6 Console_18 F6 F6 F6 F18 Console_18 Console_30 F30 F42 Console_18 Console_30 Console_6 Console_18 F6 F6 Console_6 Console_18 F6 F6 F6 F18 Console_18 Console_30 F30 F42 Console_18 Console_30 Console_6 Console_18 F6 F6 Console_6 Console_18 F6 F6 F6 F18 Console_18 Console_30 F30 F42 Console_18 Console_30 Console_6 Console_18 F6 F6 Console_6 Console_18 F6 F6 F6 F18 Console_18 Console_30 F30 F42 Console_18 Console_30 Console_6 Console_18 F6 F6 Console_6 Console_18 F6 F6
+keycode 65 = F7 F19 Console_19 Console_31 F31 F43 Console_19 Console_31 Console_7 Console_19 F7 F7 Console_7 Console_19 F7 F7 F7 F19 Console_19 Console_31 F31 F43 Console_19 Console_31 Console_7 Console_19 F7 F7 Console_7 Console_19 F7 F7 F7 F19 Console_19 Console_31 F31 F43 Console_19 Console_31 Console_7 Console_19 F7 F7 Console_7 Console_19 F7 F7 F7 F19 Console_19 Console_31 F31 F43 Console_19 Console_31 Console_7 Console_19 F7 F7 Console_7 Console_19 F7 F7 F7 F19 Console_19 Console_31 F31 F43 Console_19 Console_31 Console_7 Console_19 F7 F7 Console_7 Console_19 F7 F7 F7 F19 Console_19 Console_31 F31 F43 Console_19 Console_31 Console_7 Console_19 F7 F7 Console_7 Console_19 F7 F7 F7 F19 Console_19 Console_31 F31 F43 Console_19 Console_31 Console_7 Console_19 F7 F7 Console_7 Console_19 F7 F7 F7 F19 Console_19 Console_31 F31 F43 Console_19 Console_31 Console_7 Console_19 F7 F7 Console_7 Console_19 F7 F7
+keycode 66 = F8 F20 Console_20 Console_32 F32 F44 Console_20 Console_32 Console_8 Console_20 F8 F8 Console_8 Console_20 F8 F8 F8 F20 Console_20 Console_32 F32 F44 Console_20 Console_32 Console_8 Console_20 F8 F8 Console_8 Console_20 F8 F8 F8 F20 Console_20 Console_32 F32 F44 Console_20 Console_32 Console_8 Console_20 F8 F8 Console_8 Console_20 F8 F8 F8 F20 Console_20 Console_32 F32 F44 Console_20 Console_32 Console_8 Console_20 F8 F8 Console_8 Console_20 F8 F8 F8 F20 Console_20 Console_32 F32 F44 Console_20 Console_32 Console_8 Console_20 F8 F8 Console_8 Console_20 F8 F8 F8 F20 Console_20 Console_32 F32 F44 Console_20 Console_32 Console_8 Console_20 F8 F8 Console_8 Console_20 F8 F8 F8 F20 Console_20 Console_32 F32 F44 Console_20 Console_32 Console_8 Console_20 F8 F8 Console_8 Console_20 F8 F8 F8 F20 Console_20 Console_32 F32 F44 Console_20 Console_32 Console_8 Console_20 F8 F8 Console_8 Console_20 F8 F8
+keycode 67 = F9 F21 Console_21 Console_33 F33 F45 Console_21 Console_33 Console_9 Console_21 F9 F9 Console_9 Console_21 F9 F9 F9 F21 Console_21 Console_33 F33 F45 Console_21 Console_33 Console_9 Console_21 F9 F9 Console_9 Console_21 F9 F9 F9 F21 Console_21 Console_33 F33 F45 Console_21 Console_33 Console_9 Console_21 F9 F9 Console_9 Console_21 F9 F9 F9 F21 Console_21 Console_33 F33 F45 Console_21 Console_33 Console_9 Console_21 F9 F9 Console_9 Console_21 F9 F9 F9 F21 Console_21 Console_33 F33 F45 Console_21 Console_33 Console_9 Console_21 F9 F9 Console_9 Console_21 F9 F9 F9 F21 Console_21 Console_33 F33 F45 Console_21 Console_33 Console_9 Console_21 F9 F9 Console_9 Console_21 F9 F9 F9 F21 Console_21 Console_33 F33 F45 Console_21 Console_33 Console_9 Console_21 F9 F9 Console_9 Console_21 F9 F9 F9 F21 Console_21 Console_33 F33 F45 Console_21 Console_33 Console_9 Console_21 F9 F9 Console_9 Console_21 F9 F9
+keycode 68 = F10 F22 Console_22 Console_34 F34 F46 Console_22 Console_34 Console_10 Console_22 F10 F10 Console_10 Console_22 F10 F10 F10 F22 Console_22 Console_34 F34 F46 Console_22 Console_34 Console_10 Console_22 F10 F10 Console_10 Console_22 F10 F10 F10 F22 Console_22 Console_34 F34 F46 Console_22 Console_34 Console_10 Console_22 F10 F10 Console_10 Console_22 F10 F10 F10 F22 Console_22 Console_34 F34 F46 Console_22 Console_34 Console_10 Console_22 F10 F10 Console_10 Console_22 F10 F10 F10 F22 Console_22 Console_34 F34 F46 Console_22 Console_34 Console_10 Console_22 F10 F10 Console_10 Console_22 F10 F10 F10 F22 Console_22 Console_34 F34 F46 Console_22 Console_34 Console_10 Console_22 F10 F10 Console_10 Console_22 F10 F10 F10 F22 Console_22 Console_34 F34 F46 Console_22 Console_34 Console_10 Console_22 F10 F10 Console_10 Console_22 F10 F10 F10 F22 Console_22 Console_34 F34 F46 Console_22 Console_34 Console_10 Console_22 F10 F10 Console_10 Console_22 F10 F10
+keycode 69 = Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock
+keycode 70 = Scroll_Lock Show_Memory Show_Registers Scroll_Lock Show_State Scroll_Lock Scroll_Lock Scroll_Lock Show_Registers Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Show_Memory Show_Registers Scroll_Lock Show_State Scroll_Lock Scroll_Lock Scroll_Lock Show_Registers Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Show_Memory Show_Registers Scroll_Lock Show_State Scroll_Lock Scroll_Lock Scroll_Lock Show_Registers Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Show_Memory Show_Registers Scroll_Lock Show_State Scroll_Lock Scroll_Lock Scroll_Lock Show_Registers Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Show_Memory Show_Registers Scroll_Lock Show_State Scroll_Lock Scroll_Lock Scroll_Lock Show_Registers Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Show_Memory Show_Registers Scroll_Lock Show_State Scroll_Lock Scroll_Lock Scroll_Lock Show_Registers Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Show_Memory Show_Registers Scroll_Lock Show_State Scroll_Lock Scroll_Lock Scroll_Lock Show_Registers Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Show_Memory Show_Registers Scroll_Lock Show_State Scroll_Lock Scroll_Lock Scroll_Lock Show_Registers Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock
+keycode 71 = KP_7 KP_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 Ascii_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 Ascii_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 Ascii_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 Ascii_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 Ascii_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 Ascii_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 Ascii_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 Ascii_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7
+keycode 72 = KP_8 KP_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 Ascii_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 Ascii_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 Ascii_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 Ascii_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 Ascii_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 Ascii_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 Ascii_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 Ascii_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8
+keycode 73 = KP_9 KP_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 Ascii_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 Ascii_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 Ascii_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 Ascii_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 Ascii_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 Ascii_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 Ascii_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 Ascii_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9
+keycode 74 = KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract
+keycode 75 = KP_4 KP_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 Ascii_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 Ascii_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 Ascii_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 Ascii_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 Ascii_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 Ascii_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 Ascii_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 Ascii_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4
+keycode 76 = KP_5 KP_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 Ascii_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 Ascii_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 Ascii_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 Ascii_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 Ascii_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 Ascii_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 Ascii_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 Ascii_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5
+keycode 77 = KP_6 KP_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 Ascii_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 Ascii_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 Ascii_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 Ascii_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 Ascii_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 Ascii_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 Ascii_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 Ascii_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6
+keycode 78 = KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add
+keycode 79 = KP_1 KP_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 Ascii_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 Ascii_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 Ascii_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 Ascii_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 Ascii_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 Ascii_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 Ascii_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 Ascii_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1
+keycode 80 = KP_2 KP_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 Ascii_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 Ascii_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 Ascii_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 Ascii_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 Ascii_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 Ascii_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 Ascii_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 Ascii_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2
+keycode 81 = KP_3 KP_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 Ascii_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 Ascii_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 Ascii_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 Ascii_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 Ascii_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 Ascii_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 Ascii_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 Ascii_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3
+keycode 82 = KP_0 KP_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 Ascii_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 Ascii_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 Ascii_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 Ascii_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 Ascii_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 Ascii_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 Ascii_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 Ascii_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0
+keycode 83 = KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period Boot KP_Period
+keycode 86 = U+005c U+007c U+007c U+00a6 Control_backslash Control_backslash Control_backslash Control_backslash Meta_backslash Meta_bar Meta_bar Meta_bar Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+005c U+007c U+007c U+00a6 Control_backslash Control_backslash Control_backslash Control_backslash Meta_backslash Meta_bar Meta_bar Meta_bar Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+005c U+007c U+007c U+00a6 Control_backslash Control_backslash Control_backslash Control_backslash Meta_backslash Meta_bar Meta_bar Meta_bar Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+005c U+007c U+007c U+00a6 Control_backslash Control_backslash Control_backslash Control_backslash Meta_backslash Meta_bar Meta_bar Meta_bar Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+005c U+007c U+007c U+00a6 Control_backslash Control_backslash Control_backslash Control_backslash Meta_backslash Meta_bar Meta_bar Meta_bar Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+005c U+007c U+007c U+00a6 Control_backslash Control_backslash Control_backslash Control_backslash Meta_backslash Meta_bar Meta_bar Meta_bar Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+005c U+007c U+007c U+00a6 Control_backslash Control_backslash Control_backslash Control_backslash Meta_backslash Meta_bar Meta_bar Meta_bar Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+005c U+007c U+007c U+00a6 Control_backslash Control_backslash Control_backslash Control_backslash Meta_backslash Meta_bar Meta_bar Meta_bar Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash
+keycode 87 = F11 F23 Console_23 Console_35 F35 F47 Console_23 Console_35 Console_11 Console_23 F11 F11 Console_11 Console_23 F11 F11 F11 F23 Console_23 Console_35 F35 F47 Console_23 Console_35 Console_11 Console_23 F11 F11 Console_11 Console_23 F11 F11 F11 F23 Console_23 Console_35 F35 F47 Console_23 Console_35 Console_11 Console_23 F11 F11 Console_11 Console_23 F11 F11 F11 F23 Console_23 Console_35 F35 F47 Console_23 Console_35 Console_11 Console_23 F11 F11 Console_11 Console_23 F11 F11 F11 F23 Console_23 Console_35 F35 F47 Console_23 Console_35 Console_11 Console_23 F11 F11 Console_11 Console_23 F11 F11 F11 F23 Console_23 Console_35 F35 F47 Console_23 Console_35 Console_11 Console_23 F11 F11 Console_11 Console_23 F11 F11 F11 F23 Console_23 Console_35 F35 F47 Console_23 Console_35 Console_11 Console_23 F11 F11 Console_11 Console_23 F11 F11 F11 F23 Console_23 Console_35 F35 F47 Console_23 Console_35 Console_11 Console_23 F11 F11 Console_11 Console_23 F11 F11
+keycode 88 = F12 F24 Console_24 Console_36 F36 F48 Console_24 Console_36 Console_12 Console_24 F12 F12 Console_12 Console_24 F12 F12 F12 F24 Console_24 Console_36 F36 F48 Console_24 Console_36 Console_12 Console_24 F12 F12 Console_12 Console_24 F12 F12 F12 F24 Console_24 Console_36 F36 F48 Console_24 Console_36 Console_12 Console_24 F12 F12 Console_12 Console_24 F12 F12 F12 F24 Console_24 Console_36 F36 F48 Console_24 Console_36 Console_12 Console_24 F12 F12 Console_12 Console_24 F12 F12 F12 F24 Console_24 Console_36 F36 F48 Console_24 Console_36 Console_12 Console_24 F12 F12 Console_12 Console_24 F12 F12 F12 F24 Console_24 Console_36 F36 F48 Console_24 Console_36 Console_12 Console_24 F12 F12 Console_12 Console_24 F12 F12 F12 F24 Console_24 Console_36 F36 F48 Console_24 Console_36 Console_12 Console_24 F12 F12 Console_12 Console_24 F12 F12 F12 F24 Console_24 Console_36 F36 F48 Console_24 Console_36 Console_12 Console_24 F12 F12 Console_12 Console_24 F12 F12
+keycode 102 = Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home
+keycode 103 = Up Up Up Up Up Up Up Up KeyboardSignal Up Up Up Up Up Up Up Up Up Up Up Up Up Up Up KeyboardSignal Up Up Up Up Up Up Up Up Up Up Up Up Up Up Up KeyboardSignal Up Up Up Up Up Up Up Up Up Up Up Up Up Up Up KeyboardSignal Up Up Up Up Up Up Up Up Up Up Up Up Up Up Up KeyboardSignal Up Up Up Up Up Up Up Up Up Up Up Up Up Up Up KeyboardSignal Up Up Up Up Up Up Up Up Up Up Up Up Up Up Up KeyboardSignal Up Up Up Up Up Up Up Up Up Up Up Up Up Up Up KeyboardSignal Up Up Up Up Up Up Up
+keycode 104 = Prior Scroll_Backward Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Scroll_Backward Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Scroll_Backward Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Scroll_Backward Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Scroll_Backward Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Scroll_Backward Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Scroll_Backward Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Scroll_Backward Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior
+keycode 105 = Left Left Left Left Left Left Left Left Decr_Console Left Left Left Left Left Left Left Left Left Left Left Left Left Left Left Decr_Console Left Left Left Left Left Left Left Left Left Left Left Left Left Left Left Decr_Console Left Left Left Left Left Left Left Left Left Left Left Left Left Left Left Decr_Console Left Left Left Left Left Left Left Left Left Left Left Left Left Left Left Decr_Console Left Left Left Left Left Left Left Left Left Left Left Left Left Left Left Decr_Console Left Left Left Left Left Left Left Left Left Left Left Left Left Left Left Decr_Console Left Left Left Left Left Left Left Left Left Left Left Left Left Left Left Decr_Console Left Left Left Left Left Left Left
+keycode 106 = Right Right Right Right Right Right Right Right Incr_Console Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Incr_Console Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Incr_Console Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Incr_Console Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Incr_Console Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Incr_Console Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Incr_Console Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Incr_Console Right Right Right Right Right Right Right
+keycode 107 = End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End
+keycode 108 = Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down
+keycode 109 = Next Scroll_Forward Next Next Next Next Next Next Next Next Next Next Next Next Next Next Next Scroll_Forward Next Next Next Next Next Next Next Next Next Next Next Next Next Next Next Scroll_Forward Next Next Next Next Next Next Next Next Next Next Next Next Next Next Next Scroll_Forward Next Next Next Next Next Next Next Next Next Next Next Next Next Next Next Scroll_Forward Next Next Next Next Next Next Next Next Next Next Next Next Next Next Next Scroll_Forward Next Next Next Next Next Next Next Next Next Next Next Next Next Next Next Scroll_Forward Next Next Next Next Next Next Next Next Next Next Next Next Next Next Next Scroll_Forward Next Next Next Next Next Next Next Next Next Next Next Next Next Next
+keycode 110 = Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert
+keycode 111 = Remove Remove Remove Remove Remove Remove Boot Remove Remove Remove Remove Remove Boot Remove Boot Remove Remove Remove Remove Remove Remove Remove Boot Remove Remove Remove Remove Remove Boot Remove Boot Remove Remove Remove Remove Remove Remove Remove Boot Remove Remove Remove Remove Remove Boot Remove Boot Remove Remove Remove Remove Remove Remove Remove Boot Remove Remove Remove Remove Remove Boot Remove Boot Remove Remove Remove Remove Remove Remove Remove Boot Remove Remove Remove Remove Remove Boot Remove Boot Remove Remove Remove Remove Remove Remove Remove Boot Remove Remove Remove Remove Remove Boot Remove Boot Remove Remove Remove Remove Remove Remove Remove Boot Remove Remove Remove Remove Remove Boot Remove Boot Remove Remove Remove Remove Remove Remove Remove Boot Remove Remove Remove Remove Remove Boot Remove Boot Remove
+keycode 96 = KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter
+keycode 97 = Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control
+keycode 119 = Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause
+keycode 99 = VoidSymbol VoidSymbol Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash VoidSymbol VoidSymbol Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash VoidSymbol VoidSymbol Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash VoidSymbol VoidSymbol Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash VoidSymbol VoidSymbol Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash VoidSymbol VoidSymbol Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash VoidSymbol VoidSymbol Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash VoidSymbol VoidSymbol Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash
+keycode 98 = KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide
+keycode 100 = AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose AltGr Compose
+keycode 125 = Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt
+keycode 126 = Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt
+keycode 121 = KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period
+strings as usual
+# The content of this file will be appended to the keyboard layout.
+# For example if you uncomment the following lines Alt+j can be used
+# to go to the next console and Alt+k can be used to go to the
+# previous console:
+
+# alt keycode 36 = Incr_Console
+# shiftl alt keycode 36 = Incr_Console
+# shiftr alt keycode 36 = Incr_Console
+# shiftr shiftl alt keycode 36 = Incr_Console
+# ctrll alt keycode 36 = Incr_Console
+# ctrll shiftl alt keycode 36 = Incr_Console
+# ctrll shiftr alt keycode 36 = Incr_Console
+# ctrll shiftr shiftl alt keycode 36 = Incr_Console
+
+# alt keycode 37 = Decr_Console
+# shiftl alt keycode 37 = Decr_Console
+# shiftr alt keycode 37 = Decr_Console
+# shiftr shiftl alt keycode 37 = Decr_Console
+# ctrll alt keycode 37 = Decr_Console
+# ctrll shiftl alt keycode 37 = Decr_Console
+# ctrll shiftr alt keycode 37 = Decr_Console
+# ctrll shiftr shiftl alt keycode 37 = Decr_Console
+
diff --git a/resources/grub/keymap/ukqwerty.gkb b/resources/grub/keymap/ukqwerty.gkb
new file mode 100644
index 0000000..8e5ff29
--- /dev/null
+++ b/resources/grub/keymap/ukqwerty.gkb
Binary files differ
diff --git a/resources/grub/keymap/usdvorak b/resources/grub/keymap/usdvorak
new file mode 100644
index 0000000..b99b6a0
--- /dev/null
+++ b/resources/grub/keymap/usdvorak
@@ -0,0 +1,130 @@
+keymaps 0-127
+keycode 1 = Escape Escape Escape Escape Escape Escape Escape Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Escape Escape Escape Escape Escape Escape Escape Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Escape Escape Escape Escape Escape Escape Escape Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Escape Escape Escape Escape Escape Escape Escape Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Escape Escape Escape Escape Escape Escape Escape Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Escape Escape Escape Escape Escape Escape Escape Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Escape Escape Escape Escape Escape Escape Escape Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Escape Escape Escape Escape Escape Escape Escape Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape
+keycode 2 = U+0031 U+0021 U+0031 U+0031 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_one Meta_exclam Meta_one Meta_one VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0031 U+0021 U+0031 U+0031 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_one Meta_exclam Meta_one Meta_one VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0031 U+0021 U+0031 U+0031 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_one Meta_exclam Meta_one Meta_one VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0031 U+0021 U+0031 U+0031 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_one Meta_exclam Meta_one Meta_one VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0031 U+0021 U+0031 U+0031 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_one Meta_exclam Meta_one Meta_one VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0031 U+0021 U+0031 U+0031 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_one Meta_exclam Meta_one Meta_one VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0031 U+0021 U+0031 U+0031 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_one Meta_exclam Meta_one Meta_one VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0031 U+0021 U+0031 U+0031 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_one Meta_exclam Meta_one Meta_one VoidSymbol VoidSymbol VoidSymbol VoidSymbol
+keycode 3 = U+0032 U+0040 U+0032 U+0032 nul nul nul nul Meta_two Meta_at Meta_two Meta_two Meta_nul Meta_nul Meta_nul Meta_nul U+0032 U+0040 U+0032 U+0032 nul nul nul nul Meta_two Meta_at Meta_two Meta_two Meta_nul Meta_nul Meta_nul Meta_nul U+0032 U+0040 U+0032 U+0032 nul nul nul nul Meta_two Meta_at Meta_two Meta_two Meta_nul Meta_nul Meta_nul Meta_nul U+0032 U+0040 U+0032 U+0032 nul nul nul nul Meta_two Meta_at Meta_two Meta_two Meta_nul Meta_nul Meta_nul Meta_nul U+0032 U+0040 U+0032 U+0032 nul nul nul nul Meta_two Meta_at Meta_two Meta_two Meta_nul Meta_nul Meta_nul Meta_nul U+0032 U+0040 U+0032 U+0032 nul nul nul nul Meta_two Meta_at Meta_two Meta_two Meta_nul Meta_nul Meta_nul Meta_nul U+0032 U+0040 U+0032 U+0032 nul nul nul nul Meta_two Meta_at Meta_two Meta_two Meta_nul Meta_nul Meta_nul Meta_nul U+0032 U+0040 U+0032 U+0032 nul nul nul nul Meta_two Meta_at Meta_two Meta_two Meta_nul Meta_nul Meta_nul Meta_nul
+keycode 4 = U+0033 U+0023 U+0033 U+0033 Escape Escape Escape Escape Meta_three Meta_numbersign Meta_three Meta_three Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+0033 U+0023 U+0033 U+0033 Escape Escape Escape Escape Meta_three Meta_numbersign Meta_three Meta_three Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+0033 U+0023 U+0033 U+0033 Escape Escape Escape Escape Meta_three Meta_numbersign Meta_three Meta_three Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+0033 U+0023 U+0033 U+0033 Escape Escape Escape Escape Meta_three Meta_numbersign Meta_three Meta_three Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+0033 U+0023 U+0033 U+0033 Escape Escape Escape Escape Meta_three Meta_numbersign Meta_three Meta_three Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+0033 U+0023 U+0033 U+0033 Escape Escape Escape Escape Meta_three Meta_numbersign Meta_three Meta_three Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+0033 U+0023 U+0033 U+0033 Escape Escape Escape Escape Meta_three Meta_numbersign Meta_three Meta_three Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+0033 U+0023 U+0033 U+0033 Escape Escape Escape Escape Meta_three Meta_numbersign Meta_three Meta_three Meta_Escape Meta_Escape Meta_Escape Meta_Escape
+keycode 5 = U+0034 U+0024 U+0034 U+0034 Control_backslash Control_backslash Control_backslash Control_backslash Meta_four Meta_dollar Meta_four Meta_four Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+0034 U+0024 U+0034 U+0034 Control_backslash Control_backslash Control_backslash Control_backslash Meta_four Meta_dollar Meta_four Meta_four Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+0034 U+0024 U+0034 U+0034 Control_backslash Control_backslash Control_backslash Control_backslash Meta_four Meta_dollar Meta_four Meta_four Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+0034 U+0024 U+0034 U+0034 Control_backslash Control_backslash Control_backslash Control_backslash Meta_four Meta_dollar Meta_four Meta_four Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+0034 U+0024 U+0034 U+0034 Control_backslash Control_backslash Control_backslash Control_backslash Meta_four Meta_dollar Meta_four Meta_four Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+0034 U+0024 U+0034 U+0034 Control_backslash Control_backslash Control_backslash Control_backslash Meta_four Meta_dollar Meta_four Meta_four Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+0034 U+0024 U+0034 U+0034 Control_backslash Control_backslash Control_backslash Control_backslash Meta_four Meta_dollar Meta_four Meta_four Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+0034 U+0024 U+0034 U+0034 Control_backslash Control_backslash Control_backslash Control_backslash Meta_four Meta_dollar Meta_four Meta_four Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash
+keycode 6 = U+0035 U+0025 U+0035 U+0035 Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_five Meta_percent Meta_five Meta_five Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright U+0035 U+0025 U+0035 U+0035 Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_five Meta_percent Meta_five Meta_five Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright U+0035 U+0025 U+0035 U+0035 Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_five Meta_percent Meta_five Meta_five Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright U+0035 U+0025 U+0035 U+0035 Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_five Meta_percent Meta_five Meta_five Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright U+0035 U+0025 U+0035 U+0035 Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_five Meta_percent Meta_five Meta_five Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright U+0035 U+0025 U+0035 U+0035 Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_five Meta_percent Meta_five Meta_five Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright U+0035 U+0025 U+0035 U+0035 Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_five Meta_percent Meta_five Meta_five Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright U+0035 U+0025 U+0035 U+0035 Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_five Meta_percent Meta_five Meta_five Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright
+keycode 7 = U+0036 U+005e dead_circumflex dead_circumflex Control_asciicircum Control_asciicircum dead_circumflex dead_circumflex Meta_six Meta_asciicircum dead_circumflex dead_circumflex Meta_Control_asciicircum Meta_Control_asciicircum dead_circumflex dead_circumflex U+0036 U+005e dead_circumflex dead_circumflex Control_asciicircum Control_asciicircum dead_circumflex dead_circumflex Meta_six Meta_asciicircum dead_circumflex dead_circumflex Meta_Control_asciicircum Meta_Control_asciicircum dead_circumflex dead_circumflex U+0036 U+005e dead_circumflex dead_circumflex Control_asciicircum Control_asciicircum dead_circumflex dead_circumflex Meta_six Meta_asciicircum dead_circumflex dead_circumflex Meta_Control_asciicircum Meta_Control_asciicircum dead_circumflex dead_circumflex U+0036 U+005e dead_circumflex dead_circumflex Control_asciicircum Control_asciicircum dead_circumflex dead_circumflex Meta_six Meta_asciicircum dead_circumflex dead_circumflex Meta_Control_asciicircum Meta_Control_asciicircum dead_circumflex dead_circumflex U+0036 U+005e dead_circumflex dead_circumflex Control_asciicircum Control_asciicircum dead_circumflex dead_circumflex Meta_six Meta_asciicircum dead_circumflex dead_circumflex Meta_Control_asciicircum Meta_Control_asciicircum dead_circumflex dead_circumflex U+0036 U+005e dead_circumflex dead_circumflex Control_asciicircum Control_asciicircum dead_circumflex dead_circumflex Meta_six Meta_asciicircum dead_circumflex dead_circumflex Meta_Control_asciicircum Meta_Control_asciicircum dead_circumflex dead_circumflex U+0036 U+005e dead_circumflex dead_circumflex Control_asciicircum Control_asciicircum dead_circumflex dead_circumflex Meta_six Meta_asciicircum dead_circumflex dead_circumflex Meta_Control_asciicircum Meta_Control_asciicircum dead_circumflex dead_circumflex U+0036 U+005e dead_circumflex dead_circumflex Control_asciicircum Control_asciicircum dead_circumflex dead_circumflex Meta_six Meta_asciicircum dead_circumflex dead_circumflex Meta_Control_asciicircum Meta_Control_asciicircum dead_circumflex dead_circumflex
+keycode 8 = U+0037 U+0026 U+0037 U+0037 Control_underscore Control_underscore Control_underscore Control_underscore Meta_seven Meta_ampersand Meta_seven Meta_seven Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+0037 U+0026 U+0037 U+0037 Control_underscore Control_underscore Control_underscore Control_underscore Meta_seven Meta_ampersand Meta_seven Meta_seven Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+0037 U+0026 U+0037 U+0037 Control_underscore Control_underscore Control_underscore Control_underscore Meta_seven Meta_ampersand Meta_seven Meta_seven Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+0037 U+0026 U+0037 U+0037 Control_underscore Control_underscore Control_underscore Control_underscore Meta_seven Meta_ampersand Meta_seven Meta_seven Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+0037 U+0026 U+0037 U+0037 Control_underscore Control_underscore Control_underscore Control_underscore Meta_seven Meta_ampersand Meta_seven Meta_seven Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+0037 U+0026 U+0037 U+0037 Control_underscore Control_underscore Control_underscore Control_underscore Meta_seven Meta_ampersand Meta_seven Meta_seven Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+0037 U+0026 U+0037 U+0037 Control_underscore Control_underscore Control_underscore Control_underscore Meta_seven Meta_ampersand Meta_seven Meta_seven Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+0037 U+0026 U+0037 U+0037 Control_underscore Control_underscore Control_underscore Control_underscore Meta_seven Meta_ampersand Meta_seven Meta_seven Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore
+keycode 9 = U+0038 U+002a U+0038 U+0038 Delete Delete Delete Delete Meta_eight Meta_asterisk Meta_eight Meta_eight Meta_Delete Meta_Delete Meta_Delete Meta_Delete U+0038 U+002a U+0038 U+0038 Delete Delete Delete Delete Meta_eight Meta_asterisk Meta_eight Meta_eight Meta_Delete Meta_Delete Meta_Delete Meta_Delete U+0038 U+002a U+0038 U+0038 Delete Delete Delete Delete Meta_eight Meta_asterisk Meta_eight Meta_eight Meta_Delete Meta_Delete Meta_Delete Meta_Delete U+0038 U+002a U+0038 U+0038 Delete Delete Delete Delete Meta_eight Meta_asterisk Meta_eight Meta_eight Meta_Delete Meta_Delete Meta_Delete Meta_Delete U+0038 U+002a U+0038 U+0038 Delete Delete Delete Delete Meta_eight Meta_asterisk Meta_eight Meta_eight Meta_Delete Meta_Delete Meta_Delete Meta_Delete U+0038 U+002a U+0038 U+0038 Delete Delete Delete Delete Meta_eight Meta_asterisk Meta_eight Meta_eight Meta_Delete Meta_Delete Meta_Delete Meta_Delete U+0038 U+002a U+0038 U+0038 Delete Delete Delete Delete Meta_eight Meta_asterisk Meta_eight Meta_eight Meta_Delete Meta_Delete Meta_Delete Meta_Delete U+0038 U+002a U+0038 U+0038 Delete Delete Delete Delete Meta_eight Meta_asterisk Meta_eight Meta_eight Meta_Delete Meta_Delete Meta_Delete Meta_Delete
+keycode 10 = U+0039 U+0028 dead_grave dead_grave dead_grave dead_grave dead_grave dead_grave Meta_nine Meta_parenleft dead_grave dead_grave dead_grave dead_grave dead_grave dead_grave U+0039 U+0028 dead_grave dead_grave dead_grave dead_grave dead_grave dead_grave Meta_nine Meta_parenleft dead_grave dead_grave dead_grave dead_grave dead_grave dead_grave U+0039 U+0028 dead_grave dead_grave dead_grave dead_grave dead_grave dead_grave Meta_nine Meta_parenleft dead_grave dead_grave dead_grave dead_grave dead_grave dead_grave U+0039 U+0028 dead_grave dead_grave dead_grave dead_grave dead_grave dead_grave Meta_nine Meta_parenleft dead_grave dead_grave dead_grave dead_grave dead_grave dead_grave U+0039 U+0028 dead_grave dead_grave dead_grave dead_grave dead_grave dead_grave Meta_nine Meta_parenleft dead_grave dead_grave dead_grave dead_grave dead_grave dead_grave U+0039 U+0028 dead_grave dead_grave dead_grave dead_grave dead_grave dead_grave Meta_nine Meta_parenleft dead_grave dead_grave dead_grave dead_grave dead_grave dead_grave U+0039 U+0028 dead_grave dead_grave dead_grave dead_grave dead_grave dead_grave Meta_nine Meta_parenleft dead_grave dead_grave dead_grave dead_grave dead_grave dead_grave U+0039 U+0028 dead_grave dead_grave dead_grave dead_grave dead_grave dead_grave Meta_nine Meta_parenleft dead_grave dead_grave dead_grave dead_grave dead_grave dead_grave
+keycode 11 = U+0030 U+0029 U+0030 U+0030 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_zero Meta_parenright Meta_zero Meta_zero VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0030 U+0029 U+0030 U+0030 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_zero Meta_parenright Meta_zero Meta_zero VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0030 U+0029 U+0030 U+0030 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_zero Meta_parenright Meta_zero Meta_zero VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0030 U+0029 U+0030 U+0030 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_zero Meta_parenright Meta_zero Meta_zero VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0030 U+0029 U+0030 U+0030 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_zero Meta_parenright Meta_zero Meta_zero VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0030 U+0029 U+0030 U+0030 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_zero Meta_parenright Meta_zero Meta_zero VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0030 U+0029 U+0030 U+0030 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_zero Meta_parenright Meta_zero Meta_zero VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0030 U+0029 U+0030 U+0030 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_zero Meta_parenright Meta_zero Meta_zero VoidSymbol VoidSymbol VoidSymbol VoidSymbol
+keycode 12 = U+005b U+007b U+005b U+005b Escape Escape Escape Escape Meta_bracketleft Meta_braceleft Meta_bracketleft Meta_bracketleft Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+005b U+007b U+005b U+005b Escape Escape Escape Escape Meta_bracketleft Meta_braceleft Meta_bracketleft Meta_bracketleft Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+005b U+007b U+005b U+005b Escape Escape Escape Escape Meta_bracketleft Meta_braceleft Meta_bracketleft Meta_bracketleft Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+005b U+007b U+005b U+005b Escape Escape Escape Escape Meta_bracketleft Meta_braceleft Meta_bracketleft Meta_bracketleft Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+005b U+007b U+005b U+005b Escape Escape Escape Escape Meta_bracketleft Meta_braceleft Meta_bracketleft Meta_bracketleft Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+005b U+007b U+005b U+005b Escape Escape Escape Escape Meta_bracketleft Meta_braceleft Meta_bracketleft Meta_bracketleft Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+005b U+007b U+005b U+005b Escape Escape Escape Escape Meta_bracketleft Meta_braceleft Meta_bracketleft Meta_bracketleft Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+005b U+007b U+005b U+005b Escape Escape Escape Escape Meta_bracketleft Meta_braceleft Meta_bracketleft Meta_bracketleft Meta_Escape Meta_Escape Meta_Escape Meta_Escape
+keycode 13 = U+005d U+007d dead_tilde dead_tilde Control_bracketright Control_bracketright dead_tilde dead_tilde Meta_bracketright Meta_braceright dead_tilde dead_tilde Meta_Control_bracketright Meta_Control_bracketright dead_tilde dead_tilde U+005d U+007d dead_tilde dead_tilde Control_bracketright Control_bracketright dead_tilde dead_tilde Meta_bracketright Meta_braceright dead_tilde dead_tilde Meta_Control_bracketright Meta_Control_bracketright dead_tilde dead_tilde U+005d U+007d dead_tilde dead_tilde Control_bracketright Control_bracketright dead_tilde dead_tilde Meta_bracketright Meta_braceright dead_tilde dead_tilde Meta_Control_bracketright Meta_Control_bracketright dead_tilde dead_tilde U+005d U+007d dead_tilde dead_tilde Control_bracketright Control_bracketright dead_tilde dead_tilde Meta_bracketright Meta_braceright dead_tilde dead_tilde Meta_Control_bracketright Meta_Control_bracketright dead_tilde dead_tilde U+005d U+007d dead_tilde dead_tilde Control_bracketright Control_bracketright dead_tilde dead_tilde Meta_bracketright Meta_braceright dead_tilde dead_tilde Meta_Control_bracketright Meta_Control_bracketright dead_tilde dead_tilde U+005d U+007d dead_tilde dead_tilde Control_bracketright Control_bracketright dead_tilde dead_tilde Meta_bracketright Meta_braceright dead_tilde dead_tilde Meta_Control_bracketright Meta_Control_bracketright dead_tilde dead_tilde U+005d U+007d dead_tilde dead_tilde Control_bracketright Control_bracketright dead_tilde dead_tilde Meta_bracketright Meta_braceright dead_tilde dead_tilde Meta_Control_bracketright Meta_Control_bracketright dead_tilde dead_tilde U+005d U+007d dead_tilde dead_tilde Control_bracketright Control_bracketright dead_tilde dead_tilde Meta_bracketright Meta_braceright dead_tilde dead_tilde Meta_Control_bracketright Meta_Control_bracketright dead_tilde dead_tilde
+keycode 14 = Delete Delete Delete Delete BackSpace BackSpace BackSpace BackSpace Meta_Delete Meta_Delete Meta_Delete Meta_Delete Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace Delete Delete Delete Delete BackSpace BackSpace BackSpace BackSpace Meta_Delete Meta_Delete Meta_Delete Meta_Delete Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace Delete Delete Delete Delete BackSpace BackSpace BackSpace BackSpace Meta_Delete Meta_Delete Meta_Delete Meta_Delete Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace Delete Delete Delete Delete BackSpace BackSpace BackSpace BackSpace Meta_Delete Meta_Delete Meta_Delete Meta_Delete Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace Delete Delete Delete Delete BackSpace BackSpace BackSpace BackSpace Meta_Delete Meta_Delete Meta_Delete Meta_Delete Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace Delete Delete Delete Delete BackSpace BackSpace BackSpace BackSpace Meta_Delete Meta_Delete Meta_Delete Meta_Delete Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace Delete Delete Delete Delete BackSpace BackSpace BackSpace BackSpace Meta_Delete Meta_Delete Meta_Delete Meta_Delete Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace Delete Delete Delete Delete BackSpace BackSpace BackSpace BackSpace Meta_Delete Meta_Delete Meta_Delete Meta_Delete Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace
+keycode 15 = Tab Tab Tab Tab Tab Tab Tab Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Tab Tab Tab Tab Tab Tab Tab Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Tab Tab Tab Tab Tab Tab Tab Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Tab Tab Tab Tab Tab Tab Tab Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Tab Tab Tab Tab Tab Tab Tab Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Tab Tab Tab Tab Tab Tab Tab Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Tab Tab Tab Tab Tab Tab Tab Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Tab Tab Tab Tab Tab Tab Tab Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab
+keycode 16 = U+0027 U+0022 dead_acute dead_diaeresis Control_g Control_g dead_acute dead_diaeresis Meta_apostrophe Meta_quotedbl dead_acute dead_diaeresis Meta_Control_g Meta_Control_g dead_acute dead_diaeresis U+0027 U+0022 dead_acute dead_diaeresis Control_g Control_g dead_acute dead_diaeresis Meta_apostrophe Meta_quotedbl dead_acute dead_diaeresis Meta_Control_g Meta_Control_g dead_acute dead_diaeresis U+0027 U+0022 dead_acute dead_diaeresis Control_g Control_g dead_acute dead_diaeresis Meta_apostrophe Meta_quotedbl dead_acute dead_diaeresis Meta_Control_g Meta_Control_g dead_acute dead_diaeresis U+0027 U+0022 dead_acute dead_diaeresis Control_g Control_g dead_acute dead_diaeresis Meta_apostrophe Meta_quotedbl dead_acute dead_diaeresis Meta_Control_g Meta_Control_g dead_acute dead_diaeresis U+0027 U+0022 dead_acute dead_diaeresis Control_g Control_g dead_acute dead_diaeresis Meta_apostrophe Meta_quotedbl dead_acute dead_diaeresis Meta_Control_g Meta_Control_g dead_acute dead_diaeresis U+0027 U+0022 dead_acute dead_diaeresis Control_g Control_g dead_acute dead_diaeresis Meta_apostrophe Meta_quotedbl dead_acute dead_diaeresis Meta_Control_g Meta_Control_g dead_acute dead_diaeresis U+0027 U+0022 dead_acute dead_diaeresis Control_g Control_g dead_acute dead_diaeresis Meta_apostrophe Meta_quotedbl dead_acute dead_diaeresis Meta_Control_g Meta_Control_g dead_acute dead_diaeresis U+0027 U+0022 dead_acute dead_diaeresis Control_g Control_g dead_acute dead_diaeresis Meta_apostrophe Meta_quotedbl dead_acute dead_diaeresis Meta_Control_g Meta_Control_g dead_acute dead_diaeresis
+keycode 17 = U+002c U+003c dead_cedilla dead_caron dead_cedilla dead_caron dead_cedilla dead_caron Meta_comma Meta_less dead_cedilla dead_caron dead_cedilla dead_caron dead_cedilla dead_caron U+002c U+003c dead_cedilla dead_caron dead_cedilla dead_caron dead_cedilla dead_caron Meta_comma Meta_less dead_cedilla dead_caron dead_cedilla dead_caron dead_cedilla dead_caron U+002c U+003c dead_cedilla dead_caron dead_cedilla dead_caron dead_cedilla dead_caron Meta_comma Meta_less dead_cedilla dead_caron dead_cedilla dead_caron dead_cedilla dead_caron U+002c U+003c dead_cedilla dead_caron dead_cedilla dead_caron dead_cedilla dead_caron Meta_comma Meta_less dead_cedilla dead_caron dead_cedilla dead_caron dead_cedilla dead_caron U+002c U+003c dead_cedilla dead_caron dead_cedilla dead_caron dead_cedilla dead_caron Meta_comma Meta_less dead_cedilla dead_caron dead_cedilla dead_caron dead_cedilla dead_caron U+002c U+003c dead_cedilla dead_caron dead_cedilla dead_caron dead_cedilla dead_caron Meta_comma Meta_less dead_cedilla dead_caron dead_cedilla dead_caron dead_cedilla dead_caron U+002c U+003c dead_cedilla dead_caron dead_cedilla dead_caron dead_cedilla dead_caron Meta_comma Meta_less dead_cedilla dead_caron dead_cedilla dead_caron dead_cedilla dead_caron U+002c U+003c dead_cedilla dead_caron dead_cedilla dead_caron dead_cedilla dead_caron Meta_comma Meta_less dead_cedilla dead_caron dead_cedilla dead_caron dead_cedilla dead_caron
+keycode 18 = U+002e U+003e U+002e U+00b7 Compose Compose Compose Compose Meta_period Meta_greater Meta_period Meta_period Compose Compose Compose Compose U+002e U+003e U+002e U+00b7 Compose Compose Compose Compose Meta_period Meta_greater Meta_period Meta_period Compose Compose Compose Compose U+002e U+003e U+002e U+00b7 Compose Compose Compose Compose Meta_period Meta_greater Meta_period Meta_period Compose Compose Compose Compose U+002e U+003e U+002e U+00b7 Compose Compose Compose Compose Meta_period Meta_greater Meta_period Meta_period Compose Compose Compose Compose U+002e U+003e U+002e U+00b7 Compose Compose Compose Compose Meta_period Meta_greater Meta_period Meta_period Compose Compose Compose Compose U+002e U+003e U+002e U+00b7 Compose Compose Compose Compose Meta_period Meta_greater Meta_period Meta_period Compose Compose Compose Compose U+002e U+003e U+002e U+00b7 Compose Compose Compose Compose Meta_period Meta_greater Meta_period Meta_period Compose Compose Compose Compose U+002e U+003e U+002e U+00b7 Compose Compose Compose Compose Meta_period Meta_greater Meta_period Meta_period Compose Compose Compose Compose
+keycode 19 = +U+0070 +U+0050 +U+0070 +U+0070 Control_p Control_p Control_p Control_p Meta_p Meta_P Meta_p Meta_p Meta_Control_p Meta_Control_p Meta_Control_p Meta_Control_p +U+0070 +U+0050 +U+0070 +U+0070 Control_p Control_p Control_p Control_p Meta_p Meta_P Meta_p Meta_p Meta_Control_p Meta_Control_p Meta_Control_p Meta_Control_p +U+0070 +U+0050 +U+0070 +U+0070 Control_p Control_p Control_p Control_p Meta_p Meta_P Meta_p Meta_p Meta_Control_p Meta_Control_p Meta_Control_p Meta_Control_p +U+0070 +U+0050 +U+0070 +U+0070 Control_p Control_p Control_p Control_p Meta_p Meta_P Meta_p Meta_p Meta_Control_p Meta_Control_p Meta_Control_p Meta_Control_p +U+0050 +U+0070 +U+0050 +U+0050 Control_p Control_p Control_p Control_p Meta_p Meta_P Meta_p Meta_p Meta_Control_p Meta_Control_p Meta_Control_p Meta_Control_p +U+0050 +U+0070 +U+0050 +U+0050 Control_p Control_p Control_p Control_p Meta_p Meta_P Meta_p Meta_p Meta_Control_p Meta_Control_p Meta_Control_p Meta_Control_p +U+0050 +U+0070 +U+0050 +U+0050 Control_p Control_p Control_p Control_p Meta_p Meta_P Meta_p Meta_p Meta_Control_p Meta_Control_p Meta_Control_p Meta_Control_p +U+0050 +U+0070 +U+0050 +U+0050 Control_p Control_p Control_p Control_p Meta_p Meta_P Meta_p Meta_p Meta_Control_p Meta_Control_p Meta_Control_p Meta_Control_p
+keycode 20 = +U+0079 +U+0059 +U+0079 +U+0079 Control_y Control_y Control_y Control_y Meta_y Meta_Y Meta_y Meta_y Meta_Control_y Meta_Control_y Meta_Control_y Meta_Control_y +U+0079 +U+0059 +U+0079 +U+0079 Control_y Control_y Control_y Control_y Meta_y Meta_Y Meta_y Meta_y Meta_Control_y Meta_Control_y Meta_Control_y Meta_Control_y +U+0079 +U+0059 +U+0079 +U+0079 Control_y Control_y Control_y Control_y Meta_y Meta_Y Meta_y Meta_y Meta_Control_y Meta_Control_y Meta_Control_y Meta_Control_y +U+0079 +U+0059 +U+0079 +U+0079 Control_y Control_y Control_y Control_y Meta_y Meta_Y Meta_y Meta_y Meta_Control_y Meta_Control_y Meta_Control_y Meta_Control_y +U+0059 +U+0079 +U+0059 +U+0059 Control_y Control_y Control_y Control_y Meta_y Meta_Y Meta_y Meta_y Meta_Control_y Meta_Control_y Meta_Control_y Meta_Control_y +U+0059 +U+0079 +U+0059 +U+0059 Control_y Control_y Control_y Control_y Meta_y Meta_Y Meta_y Meta_y Meta_Control_y Meta_Control_y Meta_Control_y Meta_Control_y +U+0059 +U+0079 +U+0059 +U+0059 Control_y Control_y Control_y Control_y Meta_y Meta_Y Meta_y Meta_y Meta_Control_y Meta_Control_y Meta_Control_y Meta_Control_y +U+0059 +U+0079 +U+0059 +U+0059 Control_y Control_y Control_y Control_y Meta_y Meta_Y Meta_y Meta_y Meta_Control_y Meta_Control_y Meta_Control_y Meta_Control_y
+keycode 21 = +U+0066 +U+0046 +U+0066 +U+0066 Control_f Control_f Control_f Control_f Meta_f Meta_F Meta_f Meta_f Meta_Control_f Meta_Control_f Meta_Control_f Meta_Control_f +U+0066 +U+0046 +U+0066 +U+0066 Control_f Control_f Control_f Control_f Meta_f Meta_F Meta_f Meta_f Meta_Control_f Meta_Control_f Meta_Control_f Meta_Control_f +U+0066 +U+0046 +U+0066 +U+0066 Control_f Control_f Control_f Control_f Meta_f Meta_F Meta_f Meta_f Meta_Control_f Meta_Control_f Meta_Control_f Meta_Control_f +U+0066 +U+0046 +U+0066 +U+0066 Control_f Control_f Control_f Control_f Meta_f Meta_F Meta_f Meta_f Meta_Control_f Meta_Control_f Meta_Control_f Meta_Control_f +U+0046 +U+0066 +U+0046 +U+0046 Control_f Control_f Control_f Control_f Meta_f Meta_F Meta_f Meta_f Meta_Control_f Meta_Control_f Meta_Control_f Meta_Control_f +U+0046 +U+0066 +U+0046 +U+0046 Control_f Control_f Control_f Control_f Meta_f Meta_F Meta_f Meta_f Meta_Control_f Meta_Control_f Meta_Control_f Meta_Control_f +U+0046 +U+0066 +U+0046 +U+0046 Control_f Control_f Control_f Control_f Meta_f Meta_F Meta_f Meta_f Meta_Control_f Meta_Control_f Meta_Control_f Meta_Control_f +U+0046 +U+0066 +U+0046 +U+0046 Control_f Control_f Control_f Control_f Meta_f Meta_F Meta_f Meta_f Meta_Control_f Meta_Control_f Meta_Control_f Meta_Control_f
+keycode 22 = +U+0067 +U+0047 +U+0067 +U+0067 Control_g Control_g Control_g Control_g Meta_g Meta_G Meta_g Meta_g Meta_Control_g Meta_Control_g Meta_Control_g Meta_Control_g +U+0067 +U+0047 +U+0067 +U+0067 Control_g Control_g Control_g Control_g Meta_g Meta_G Meta_g Meta_g Meta_Control_g Meta_Control_g Meta_Control_g Meta_Control_g +U+0067 +U+0047 +U+0067 +U+0067 Control_g Control_g Control_g Control_g Meta_g Meta_G Meta_g Meta_g Meta_Control_g Meta_Control_g Meta_Control_g Meta_Control_g +U+0067 +U+0047 +U+0067 +U+0067 Control_g Control_g Control_g Control_g Meta_g Meta_G Meta_g Meta_g Meta_Control_g Meta_Control_g Meta_Control_g Meta_Control_g +U+0047 +U+0067 +U+0047 +U+0047 Control_g Control_g Control_g Control_g Meta_g Meta_G Meta_g Meta_g Meta_Control_g Meta_Control_g Meta_Control_g Meta_Control_g +U+0047 +U+0067 +U+0047 +U+0047 Control_g Control_g Control_g Control_g Meta_g Meta_G Meta_g Meta_g Meta_Control_g Meta_Control_g Meta_Control_g Meta_Control_g +U+0047 +U+0067 +U+0047 +U+0047 Control_g Control_g Control_g Control_g Meta_g Meta_G Meta_g Meta_g Meta_Control_g Meta_Control_g Meta_Control_g Meta_Control_g +U+0047 +U+0067 +U+0047 +U+0047 Control_g Control_g Control_g Control_g Meta_g Meta_G Meta_g Meta_g Meta_Control_g Meta_Control_g Meta_Control_g Meta_Control_g
+keycode 23 = +U+0063 +U+0043 +U+0063 +U+0063 Control_c Control_c Control_c Control_c Meta_c Meta_C Meta_c Meta_c Meta_Control_c Meta_Control_c Meta_Control_c Meta_Control_c +U+0063 +U+0043 +U+0063 +U+0063 Control_c Control_c Control_c Control_c Meta_c Meta_C Meta_c Meta_c Meta_Control_c Meta_Control_c Meta_Control_c Meta_Control_c +U+0063 +U+0043 +U+0063 +U+0063 Control_c Control_c Control_c Control_c Meta_c Meta_C Meta_c Meta_c Meta_Control_c Meta_Control_c Meta_Control_c Meta_Control_c +U+0063 +U+0043 +U+0063 +U+0063 Control_c Control_c Control_c Control_c Meta_c Meta_C Meta_c Meta_c Meta_Control_c Meta_Control_c Meta_Control_c Meta_Control_c +U+0043 +U+0063 +U+0043 +U+0043 Control_c Control_c Control_c Control_c Meta_c Meta_C Meta_c Meta_c Meta_Control_c Meta_Control_c Meta_Control_c Meta_Control_c +U+0043 +U+0063 +U+0043 +U+0043 Control_c Control_c Control_c Control_c Meta_c Meta_C Meta_c Meta_c Meta_Control_c Meta_Control_c Meta_Control_c Meta_Control_c +U+0043 +U+0063 +U+0043 +U+0043 Control_c Control_c Control_c Control_c Meta_c Meta_C Meta_c Meta_c Meta_Control_c Meta_Control_c Meta_Control_c Meta_Control_c +U+0043 +U+0063 +U+0043 +U+0043 Control_c Control_c Control_c Control_c Meta_c Meta_C Meta_c Meta_c Meta_Control_c Meta_Control_c Meta_Control_c Meta_Control_c
+keycode 24 = +U+0072 +U+0052 +U+0072 +U+0072 Control_r Control_r Control_r Control_r Meta_r Meta_R Meta_r Meta_r Meta_Control_r Meta_Control_r Meta_Control_r Meta_Control_r +U+0072 +U+0052 +U+0072 +U+0072 Control_r Control_r Control_r Control_r Meta_r Meta_R Meta_r Meta_r Meta_Control_r Meta_Control_r Meta_Control_r Meta_Control_r +U+0072 +U+0052 +U+0072 +U+0072 Control_r Control_r Control_r Control_r Meta_r Meta_R Meta_r Meta_r Meta_Control_r Meta_Control_r Meta_Control_r Meta_Control_r +U+0072 +U+0052 +U+0072 +U+0072 Control_r Control_r Control_r Control_r Meta_r Meta_R Meta_r Meta_r Meta_Control_r Meta_Control_r Meta_Control_r Meta_Control_r +U+0052 +U+0072 +U+0052 +U+0052 Control_r Control_r Control_r Control_r Meta_r Meta_R Meta_r Meta_r Meta_Control_r Meta_Control_r Meta_Control_r Meta_Control_r +U+0052 +U+0072 +U+0052 +U+0052 Control_r Control_r Control_r Control_r Meta_r Meta_R Meta_r Meta_r Meta_Control_r Meta_Control_r Meta_Control_r Meta_Control_r +U+0052 +U+0072 +U+0052 +U+0052 Control_r Control_r Control_r Control_r Meta_r Meta_R Meta_r Meta_r Meta_Control_r Meta_Control_r Meta_Control_r Meta_Control_r +U+0052 +U+0072 +U+0052 +U+0052 Control_r Control_r Control_r Control_r Meta_r Meta_R Meta_r Meta_r Meta_Control_r Meta_Control_r Meta_Control_r Meta_Control_r
+keycode 25 = +U+006c +U+004c +U+006c +U+006c Control_l Control_l Control_l Control_l Meta_l Meta_L Meta_l Meta_l Meta_Control_l Meta_Control_l Meta_Control_l Meta_Control_l +U+006c +U+004c +U+006c +U+006c Control_l Control_l Control_l Control_l Meta_l Meta_L Meta_l Meta_l Meta_Control_l Meta_Control_l Meta_Control_l Meta_Control_l +U+006c +U+004c +U+006c +U+006c Control_l Control_l Control_l Control_l Meta_l Meta_L Meta_l Meta_l Meta_Control_l Meta_Control_l Meta_Control_l Meta_Control_l +U+006c +U+004c +U+006c +U+006c Control_l Control_l Control_l Control_l Meta_l Meta_L Meta_l Meta_l Meta_Control_l Meta_Control_l Meta_Control_l Meta_Control_l +U+004c +U+006c +U+004c +U+004c Control_l Control_l Control_l Control_l Meta_l Meta_L Meta_l Meta_l Meta_Control_l Meta_Control_l Meta_Control_l Meta_Control_l +U+004c +U+006c +U+004c +U+004c Control_l Control_l Control_l Control_l Meta_l Meta_L Meta_l Meta_l Meta_Control_l Meta_Control_l Meta_Control_l Meta_Control_l +U+004c +U+006c +U+004c +U+004c Control_l Control_l Control_l Control_l Meta_l Meta_L Meta_l Meta_l Meta_Control_l Meta_Control_l Meta_Control_l Meta_Control_l +U+004c +U+006c +U+004c +U+004c Control_l Control_l Control_l Control_l Meta_l Meta_L Meta_l Meta_l Meta_Control_l Meta_Control_l Meta_Control_l Meta_Control_l
+keycode 26 = U+002f U+003f U+002f U+002f Delete Delete Delete Delete Meta_slash Meta_question Meta_slash Meta_slash Meta_Delete Meta_Delete Meta_Delete Meta_Delete U+002f U+003f U+002f U+002f Delete Delete Delete Delete Meta_slash Meta_question Meta_slash Meta_slash Meta_Delete Meta_Delete Meta_Delete Meta_Delete U+002f U+003f U+002f U+002f Delete Delete Delete Delete Meta_slash Meta_question Meta_slash Meta_slash Meta_Delete Meta_Delete Meta_Delete Meta_Delete U+002f U+003f U+002f U+002f Delete Delete Delete Delete Meta_slash Meta_question Meta_slash Meta_slash Meta_Delete Meta_Delete Meta_Delete Meta_Delete U+002f U+003f U+002f U+002f Delete Delete Delete Delete Meta_slash Meta_question Meta_slash Meta_slash Meta_Delete Meta_Delete Meta_Delete Meta_Delete U+002f U+003f U+002f U+002f Delete Delete Delete Delete Meta_slash Meta_question Meta_slash Meta_slash Meta_Delete Meta_Delete Meta_Delete Meta_Delete U+002f U+003f U+002f U+002f Delete Delete Delete Delete Meta_slash Meta_question Meta_slash Meta_slash Meta_Delete Meta_Delete Meta_Delete Meta_Delete U+002f U+003f U+002f U+002f Delete Delete Delete Delete Meta_slash Meta_question Meta_slash Meta_slash Meta_Delete Meta_Delete Meta_Delete Meta_Delete
+keycode 27 = U+003d U+002b U+003d U+003d VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_equal Meta_plus Meta_equal Meta_equal VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+003d U+002b U+003d U+003d VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_equal Meta_plus Meta_equal Meta_equal VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+003d U+002b U+003d U+003d VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_equal Meta_plus Meta_equal Meta_equal VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+003d U+002b U+003d U+003d VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_equal Meta_plus Meta_equal Meta_equal VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+003d U+002b U+003d U+003d VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_equal Meta_plus Meta_equal Meta_equal VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+003d U+002b U+003d U+003d VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_equal Meta_plus Meta_equal Meta_equal VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+003d U+002b U+003d U+003d VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_equal Meta_plus Meta_equal Meta_equal VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+003d U+002b U+003d U+003d VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_equal Meta_plus Meta_equal Meta_equal VoidSymbol VoidSymbol VoidSymbol VoidSymbol
+keycode 28 = Return Return Return Return Control_m Control_m Control_m Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Return Return Return Return Control_m Control_m Control_m Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Return Return Return Return Control_m Control_m Control_m Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Return Return Return Return Control_m Control_m Control_m Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Return Return Return Return Control_m Control_m Control_m Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Return Return Return Return Control_m Control_m Control_m Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Return Return Return Return Control_m Control_m Control_m Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Return Return Return Return Control_m Control_m Control_m Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m
+keycode 29 = Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control
+keycode 30 = +U+0061 +U+0041 +U+0061 +U+0061 Control_a Control_a Control_a Control_a Meta_a Meta_A Meta_a Meta_a Meta_Control_a Meta_Control_a Meta_Control_a Meta_Control_a +U+0061 +U+0041 +U+0061 +U+0061 Control_a Control_a Control_a Control_a Meta_a Meta_A Meta_a Meta_a Meta_Control_a Meta_Control_a Meta_Control_a Meta_Control_a +U+0061 +U+0041 +U+0061 +U+0061 Control_a Control_a Control_a Control_a Meta_a Meta_A Meta_a Meta_a Meta_Control_a Meta_Control_a Meta_Control_a Meta_Control_a +U+0061 +U+0041 +U+0061 +U+0061 Control_a Control_a Control_a Control_a Meta_a Meta_A Meta_a Meta_a Meta_Control_a Meta_Control_a Meta_Control_a Meta_Control_a +U+0041 +U+0061 +U+0041 +U+0041 Control_a Control_a Control_a Control_a Meta_a Meta_A Meta_a Meta_a Meta_Control_a Meta_Control_a Meta_Control_a Meta_Control_a +U+0041 +U+0061 +U+0041 +U+0041 Control_a Control_a Control_a Control_a Meta_a Meta_A Meta_a Meta_a Meta_Control_a Meta_Control_a Meta_Control_a Meta_Control_a +U+0041 +U+0061 +U+0041 +U+0041 Control_a Control_a Control_a Control_a Meta_a Meta_A Meta_a Meta_a Meta_Control_a Meta_Control_a Meta_Control_a Meta_Control_a +U+0041 +U+0061 +U+0041 +U+0041 Control_a Control_a Control_a Control_a Meta_a Meta_A Meta_a Meta_a Meta_Control_a Meta_Control_a Meta_Control_a Meta_Control_a
+keycode 31 = +U+006f +U+004f +U+006f +U+006f Control_o Control_o Control_o Control_o Meta_o Meta_O Meta_o Meta_o Meta_Control_o Meta_Control_o Meta_Control_o Meta_Control_o +U+006f +U+004f +U+006f +U+006f Control_o Control_o Control_o Control_o Meta_o Meta_O Meta_o Meta_o Meta_Control_o Meta_Control_o Meta_Control_o Meta_Control_o +U+006f +U+004f +U+006f +U+006f Control_o Control_o Control_o Control_o Meta_o Meta_O Meta_o Meta_o Meta_Control_o Meta_Control_o Meta_Control_o Meta_Control_o +U+006f +U+004f +U+006f +U+006f Control_o Control_o Control_o Control_o Meta_o Meta_O Meta_o Meta_o Meta_Control_o Meta_Control_o Meta_Control_o Meta_Control_o +U+004f +U+006f +U+004f +U+004f Control_o Control_o Control_o Control_o Meta_o Meta_O Meta_o Meta_o Meta_Control_o Meta_Control_o Meta_Control_o Meta_Control_o +U+004f +U+006f +U+004f +U+004f Control_o Control_o Control_o Control_o Meta_o Meta_O Meta_o Meta_o Meta_Control_o Meta_Control_o Meta_Control_o Meta_Control_o +U+004f +U+006f +U+004f +U+004f Control_o Control_o Control_o Control_o Meta_o Meta_O Meta_o Meta_o Meta_Control_o Meta_Control_o Meta_Control_o Meta_Control_o +U+004f +U+006f +U+004f +U+004f Control_o Control_o Control_o Control_o Meta_o Meta_O Meta_o Meta_o Meta_Control_o Meta_Control_o Meta_Control_o Meta_Control_o
+keycode 32 = +U+0065 +U+0045 +U+0065 +U+0065 Control_e Control_e Control_e Control_e Meta_e Meta_E Meta_e Meta_e Meta_Control_e Meta_Control_e Meta_Control_e Meta_Control_e +U+0065 +U+0045 +U+0065 +U+0065 Control_e Control_e Control_e Control_e Meta_e Meta_E Meta_e Meta_e Meta_Control_e Meta_Control_e Meta_Control_e Meta_Control_e +U+0065 +U+0045 +U+0065 +U+0065 Control_e Control_e Control_e Control_e Meta_e Meta_E Meta_e Meta_e Meta_Control_e Meta_Control_e Meta_Control_e Meta_Control_e +U+0065 +U+0045 +U+0065 +U+0065 Control_e Control_e Control_e Control_e Meta_e Meta_E Meta_e Meta_e Meta_Control_e Meta_Control_e Meta_Control_e Meta_Control_e +U+0045 +U+0065 +U+0045 +U+0045 Control_e Control_e Control_e Control_e Meta_e Meta_E Meta_e Meta_e Meta_Control_e Meta_Control_e Meta_Control_e Meta_Control_e +U+0045 +U+0065 +U+0045 +U+0045 Control_e Control_e Control_e Control_e Meta_e Meta_E Meta_e Meta_e Meta_Control_e Meta_Control_e Meta_Control_e Meta_Control_e +U+0045 +U+0065 +U+0045 +U+0045 Control_e Control_e Control_e Control_e Meta_e Meta_E Meta_e Meta_e Meta_Control_e Meta_Control_e Meta_Control_e Meta_Control_e +U+0045 +U+0065 +U+0045 +U+0045 Control_e Control_e Control_e Control_e Meta_e Meta_E Meta_e Meta_e Meta_Control_e Meta_Control_e Meta_Control_e Meta_Control_e
+keycode 33 = +U+0075 +U+0055 +U+0075 +U+0075 Control_u Control_u Control_u Control_u Meta_u Meta_U Meta_u Meta_u Meta_Control_u Meta_Control_u Meta_Control_u Meta_Control_u +U+0075 +U+0055 +U+0075 +U+0075 Control_u Control_u Control_u Control_u Meta_u Meta_U Meta_u Meta_u Meta_Control_u Meta_Control_u Meta_Control_u Meta_Control_u +U+0075 +U+0055 +U+0075 +U+0075 Control_u Control_u Control_u Control_u Meta_u Meta_U Meta_u Meta_u Meta_Control_u Meta_Control_u Meta_Control_u Meta_Control_u +U+0075 +U+0055 +U+0075 +U+0075 Control_u Control_u Control_u Control_u Meta_u Meta_U Meta_u Meta_u Meta_Control_u Meta_Control_u Meta_Control_u Meta_Control_u +U+0055 +U+0075 +U+0055 +U+0055 Control_u Control_u Control_u Control_u Meta_u Meta_U Meta_u Meta_u Meta_Control_u Meta_Control_u Meta_Control_u Meta_Control_u +U+0055 +U+0075 +U+0055 +U+0055 Control_u Control_u Control_u Control_u Meta_u Meta_U Meta_u Meta_u Meta_Control_u Meta_Control_u Meta_Control_u Meta_Control_u +U+0055 +U+0075 +U+0055 +U+0055 Control_u Control_u Control_u Control_u Meta_u Meta_U Meta_u Meta_u Meta_Control_u Meta_Control_u Meta_Control_u Meta_Control_u +U+0055 +U+0075 +U+0055 +U+0055 Control_u Control_u Control_u Control_u Meta_u Meta_U Meta_u Meta_u Meta_Control_u Meta_Control_u Meta_Control_u Meta_Control_u
+keycode 34 = +U+0069 +U+0049 +U+0069 +U+0069 Tab Tab Tab Tab Meta_i Meta_I Meta_i Meta_i Meta_Tab Meta_Tab Meta_Tab Meta_Tab +U+0069 +U+0049 +U+0069 +U+0069 Tab Tab Tab Tab Meta_i Meta_I Meta_i Meta_i Meta_Tab Meta_Tab Meta_Tab Meta_Tab +U+0069 +U+0049 +U+0069 +U+0069 Tab Tab Tab Tab Meta_i Meta_I Meta_i Meta_i Meta_Tab Meta_Tab Meta_Tab Meta_Tab +U+0069 +U+0049 +U+0069 +U+0069 Tab Tab Tab Tab Meta_i Meta_I Meta_i Meta_i Meta_Tab Meta_Tab Meta_Tab Meta_Tab +U+0049 +U+0069 +U+0049 +U+0049 Tab Tab Tab Tab Meta_i Meta_I Meta_i Meta_i Meta_Tab Meta_Tab Meta_Tab Meta_Tab +U+0049 +U+0069 +U+0049 +U+0049 Tab Tab Tab Tab Meta_i Meta_I Meta_i Meta_i Meta_Tab Meta_Tab Meta_Tab Meta_Tab +U+0049 +U+0069 +U+0049 +U+0049 Tab Tab Tab Tab Meta_i Meta_I Meta_i Meta_i Meta_Tab Meta_Tab Meta_Tab Meta_Tab +U+0049 +U+0069 +U+0049 +U+0049 Tab Tab Tab Tab Meta_i Meta_I Meta_i Meta_i Meta_Tab Meta_Tab Meta_Tab Meta_Tab
+keycode 35 = +U+0064 +U+0044 +U+0064 +U+0064 Control_d Control_d Control_d Control_d Meta_d Meta_D Meta_d Meta_d Meta_Control_d Meta_Control_d Meta_Control_d Meta_Control_d +U+0064 +U+0044 +U+0064 +U+0064 Control_d Control_d Control_d Control_d Meta_d Meta_D Meta_d Meta_d Meta_Control_d Meta_Control_d Meta_Control_d Meta_Control_d +U+0064 +U+0044 +U+0064 +U+0064 Control_d Control_d Control_d Control_d Meta_d Meta_D Meta_d Meta_d Meta_Control_d Meta_Control_d Meta_Control_d Meta_Control_d +U+0064 +U+0044 +U+0064 +U+0064 Control_d Control_d Control_d Control_d Meta_d Meta_D Meta_d Meta_d Meta_Control_d Meta_Control_d Meta_Control_d Meta_Control_d +U+0044 +U+0064 +U+0044 +U+0044 Control_d Control_d Control_d Control_d Meta_d Meta_D Meta_d Meta_d Meta_Control_d Meta_Control_d Meta_Control_d Meta_Control_d +U+0044 +U+0064 +U+0044 +U+0044 Control_d Control_d Control_d Control_d Meta_d Meta_D Meta_d Meta_d Meta_Control_d Meta_Control_d Meta_Control_d Meta_Control_d +U+0044 +U+0064 +U+0044 +U+0044 Control_d Control_d Control_d Control_d Meta_d Meta_D Meta_d Meta_d Meta_Control_d Meta_Control_d Meta_Control_d Meta_Control_d +U+0044 +U+0064 +U+0044 +U+0044 Control_d Control_d Control_d Control_d Meta_d Meta_D Meta_d Meta_d Meta_Control_d Meta_Control_d Meta_Control_d Meta_Control_d
+keycode 36 = +U+0068 +U+0048 +U+0068 +U+0068 BackSpace BackSpace BackSpace BackSpace Meta_h Meta_H Meta_h Meta_h Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace +U+0068 +U+0048 +U+0068 +U+0068 BackSpace BackSpace BackSpace BackSpace Meta_h Meta_H Meta_h Meta_h Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace +U+0068 +U+0048 +U+0068 +U+0068 BackSpace BackSpace BackSpace BackSpace Meta_h Meta_H Meta_h Meta_h Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace +U+0068 +U+0048 +U+0068 +U+0068 BackSpace BackSpace BackSpace BackSpace Meta_h Meta_H Meta_h Meta_h Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace +U+0048 +U+0068 +U+0048 +U+0048 BackSpace BackSpace BackSpace BackSpace Meta_h Meta_H Meta_h Meta_h Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace +U+0048 +U+0068 +U+0048 +U+0048 BackSpace BackSpace BackSpace BackSpace Meta_h Meta_H Meta_h Meta_h Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace +U+0048 +U+0068 +U+0048 +U+0048 BackSpace BackSpace BackSpace BackSpace Meta_h Meta_H Meta_h Meta_h Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace +U+0048 +U+0068 +U+0048 +U+0048 BackSpace BackSpace BackSpace BackSpace Meta_h Meta_H Meta_h Meta_h Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace
+keycode 37 = +U+0074 +U+0054 +U+0074 +U+0074 Control_t Control_t Control_t Control_t Meta_t Meta_T Meta_t Meta_t Meta_Control_t Meta_Control_t Meta_Control_t Meta_Control_t +U+0074 +U+0054 +U+0074 +U+0074 Control_t Control_t Control_t Control_t Meta_t Meta_T Meta_t Meta_t Meta_Control_t Meta_Control_t Meta_Control_t Meta_Control_t +U+0074 +U+0054 +U+0074 +U+0074 Control_t Control_t Control_t Control_t Meta_t Meta_T Meta_t Meta_t Meta_Control_t Meta_Control_t Meta_Control_t Meta_Control_t +U+0074 +U+0054 +U+0074 +U+0074 Control_t Control_t Control_t Control_t Meta_t Meta_T Meta_t Meta_t Meta_Control_t Meta_Control_t Meta_Control_t Meta_Control_t +U+0054 +U+0074 +U+0054 +U+0054 Control_t Control_t Control_t Control_t Meta_t Meta_T Meta_t Meta_t Meta_Control_t Meta_Control_t Meta_Control_t Meta_Control_t +U+0054 +U+0074 +U+0054 +U+0054 Control_t Control_t Control_t Control_t Meta_t Meta_T Meta_t Meta_t Meta_Control_t Meta_Control_t Meta_Control_t Meta_Control_t +U+0054 +U+0074 +U+0054 +U+0054 Control_t Control_t Control_t Control_t Meta_t Meta_T Meta_t Meta_t Meta_Control_t Meta_Control_t Meta_Control_t Meta_Control_t +U+0054 +U+0074 +U+0054 +U+0054 Control_t Control_t Control_t Control_t Meta_t Meta_T Meta_t Meta_t Meta_Control_t Meta_Control_t Meta_Control_t Meta_Control_t
+keycode 38 = +U+006e +U+004e +U+006e +U+006e Control_n Control_n Control_n Control_n Meta_n Meta_N Meta_n Meta_n Meta_Control_n Meta_Control_n Meta_Control_n Meta_Control_n +U+006e +U+004e +U+006e +U+006e Control_n Control_n Control_n Control_n Meta_n Meta_N Meta_n Meta_n Meta_Control_n Meta_Control_n Meta_Control_n Meta_Control_n +U+006e +U+004e +U+006e +U+006e Control_n Control_n Control_n Control_n Meta_n Meta_N Meta_n Meta_n Meta_Control_n Meta_Control_n Meta_Control_n Meta_Control_n +U+006e +U+004e +U+006e +U+006e Control_n Control_n Control_n Control_n Meta_n Meta_N Meta_n Meta_n Meta_Control_n Meta_Control_n Meta_Control_n Meta_Control_n +U+004e +U+006e +U+004e +U+004e Control_n Control_n Control_n Control_n Meta_n Meta_N Meta_n Meta_n Meta_Control_n Meta_Control_n Meta_Control_n Meta_Control_n +U+004e +U+006e +U+004e +U+004e Control_n Control_n Control_n Control_n Meta_n Meta_N Meta_n Meta_n Meta_Control_n Meta_Control_n Meta_Control_n Meta_Control_n +U+004e +U+006e +U+004e +U+004e Control_n Control_n Control_n Control_n Meta_n Meta_N Meta_n Meta_n Meta_Control_n Meta_Control_n Meta_Control_n Meta_Control_n +U+004e +U+006e +U+004e +U+004e Control_n Control_n Control_n Control_n Meta_n Meta_N Meta_n Meta_n Meta_Control_n Meta_Control_n Meta_Control_n Meta_Control_n
+keycode 39 = +U+0073 +U+0053 +U+0073 +U+0073 Control_s Control_s Control_s Control_s Meta_s Meta_S Meta_s Meta_s Meta_Control_s Meta_Control_s Meta_Control_s Meta_Control_s +U+0073 +U+0053 +U+0073 +U+0073 Control_s Control_s Control_s Control_s Meta_s Meta_S Meta_s Meta_s Meta_Control_s Meta_Control_s Meta_Control_s Meta_Control_s +U+0073 +U+0053 +U+0073 +U+0073 Control_s Control_s Control_s Control_s Meta_s Meta_S Meta_s Meta_s Meta_Control_s Meta_Control_s Meta_Control_s Meta_Control_s +U+0073 +U+0053 +U+0073 +U+0073 Control_s Control_s Control_s Control_s Meta_s Meta_S Meta_s Meta_s Meta_Control_s Meta_Control_s Meta_Control_s Meta_Control_s +U+0053 +U+0073 +U+0053 +U+0053 Control_s Control_s Control_s Control_s Meta_s Meta_S Meta_s Meta_s Meta_Control_s Meta_Control_s Meta_Control_s Meta_Control_s +U+0053 +U+0073 +U+0053 +U+0053 Control_s Control_s Control_s Control_s Meta_s Meta_S Meta_s Meta_s Meta_Control_s Meta_Control_s Meta_Control_s Meta_Control_s +U+0053 +U+0073 +U+0053 +U+0053 Control_s Control_s Control_s Control_s Meta_s Meta_S Meta_s Meta_s Meta_Control_s Meta_Control_s Meta_Control_s Meta_Control_s +U+0053 +U+0073 +U+0053 +U+0053 Control_s Control_s Control_s Control_s Meta_s Meta_S Meta_s Meta_s Meta_Control_s Meta_Control_s Meta_Control_s Meta_Control_s
+keycode 40 = U+002d U+005f U+002d U+002d Control_underscore Control_underscore Control_underscore Control_underscore Meta_minus Meta_underscore Meta_minus Meta_minus Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+002d U+005f U+002d U+002d Control_underscore Control_underscore Control_underscore Control_underscore Meta_minus Meta_underscore Meta_minus Meta_minus Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+002d U+005f U+002d U+002d Control_underscore Control_underscore Control_underscore Control_underscore Meta_minus Meta_underscore Meta_minus Meta_minus Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+002d U+005f U+002d U+002d Control_underscore Control_underscore Control_underscore Control_underscore Meta_minus Meta_underscore Meta_minus Meta_minus Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+002d U+005f U+002d U+002d Control_underscore Control_underscore Control_underscore Control_underscore Meta_minus Meta_underscore Meta_minus Meta_minus Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+002d U+005f U+002d U+002d Control_underscore Control_underscore Control_underscore Control_underscore Meta_minus Meta_underscore Meta_minus Meta_minus Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+002d U+005f U+002d U+002d Control_underscore Control_underscore Control_underscore Control_underscore Meta_minus Meta_underscore Meta_minus Meta_minus Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+002d U+005f U+002d U+002d Control_underscore Control_underscore Control_underscore Control_underscore Meta_minus Meta_underscore Meta_minus Meta_minus Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore
+keycode 41 = U+0060 U+007e dead_grave dead_tilde nul nul dead_grave dead_tilde Meta_grave Meta_asciitilde dead_grave dead_tilde Meta_nul Meta_nul dead_grave dead_tilde U+0060 U+007e dead_grave dead_tilde nul nul dead_grave dead_tilde Meta_grave Meta_asciitilde dead_grave dead_tilde Meta_nul Meta_nul dead_grave dead_tilde U+0060 U+007e dead_grave dead_tilde nul nul dead_grave dead_tilde Meta_grave Meta_asciitilde dead_grave dead_tilde Meta_nul Meta_nul dead_grave dead_tilde U+0060 U+007e dead_grave dead_tilde nul nul dead_grave dead_tilde Meta_grave Meta_asciitilde dead_grave dead_tilde Meta_nul Meta_nul dead_grave dead_tilde U+0060 U+007e dead_grave dead_tilde nul nul dead_grave dead_tilde Meta_grave Meta_asciitilde dead_grave dead_tilde Meta_nul Meta_nul dead_grave dead_tilde U+0060 U+007e dead_grave dead_tilde nul nul dead_grave dead_tilde Meta_grave Meta_asciitilde dead_grave dead_tilde Meta_nul Meta_nul dead_grave dead_tilde U+0060 U+007e dead_grave dead_tilde nul nul dead_grave dead_tilde Meta_grave Meta_asciitilde dead_grave dead_tilde Meta_nul Meta_nul dead_grave dead_tilde U+0060 U+007e dead_grave dead_tilde nul nul dead_grave dead_tilde Meta_grave Meta_asciitilde dead_grave dead_tilde Meta_nul Meta_nul dead_grave dead_tilde
+keycode 42 = Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift
+keycode 43 = U+005c U+007c U+005c U+005c Control_backslash Control_backslash Control_backslash Control_backslash Meta_backslash Meta_bar Meta_backslash Meta_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+005c U+007c U+005c U+005c Control_backslash Control_backslash Control_backslash Control_backslash Meta_backslash Meta_bar Meta_backslash Meta_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+005c U+007c U+005c U+005c Control_backslash Control_backslash Control_backslash Control_backslash Meta_backslash Meta_bar Meta_backslash Meta_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+005c U+007c U+005c U+005c Control_backslash Control_backslash Control_backslash Control_backslash Meta_backslash Meta_bar Meta_backslash Meta_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+005c U+007c U+005c U+005c Control_backslash Control_backslash Control_backslash Control_backslash Meta_backslash Meta_bar Meta_backslash Meta_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+005c U+007c U+005c U+005c Control_backslash Control_backslash Control_backslash Control_backslash Meta_backslash Meta_bar Meta_backslash Meta_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+005c U+007c U+005c U+005c Control_backslash Control_backslash Control_backslash Control_backslash Meta_backslash Meta_bar Meta_backslash Meta_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+005c U+007c U+005c U+005c Control_backslash Control_backslash Control_backslash Control_backslash Meta_backslash Meta_bar Meta_backslash Meta_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash
+keycode 44 = U+003b U+003a dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute Meta_semicolon Meta_colon dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute U+003b U+003a dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute Meta_semicolon Meta_colon dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute U+003b U+003a dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute Meta_semicolon Meta_colon dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute U+003b U+003a dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute Meta_semicolon Meta_colon dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute U+003b U+003a dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute Meta_semicolon Meta_colon dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute U+003b U+003a dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute Meta_semicolon Meta_colon dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute U+003b U+003a dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute Meta_semicolon Meta_colon dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute U+003b U+003a dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute Meta_semicolon Meta_colon dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute dead_ogonek dead_doubleacute
+keycode 45 = +U+0071 +U+0051 +U+0071 +U+0071 Control_q Control_q Control_q Control_q Meta_q Meta_Q Meta_q Meta_q Meta_Control_q Meta_Control_q Meta_Control_q Meta_Control_q +U+0071 +U+0051 +U+0071 +U+0071 Control_q Control_q Control_q Control_q Meta_q Meta_Q Meta_q Meta_q Meta_Control_q Meta_Control_q Meta_Control_q Meta_Control_q +U+0071 +U+0051 +U+0071 +U+0071 Control_q Control_q Control_q Control_q Meta_q Meta_Q Meta_q Meta_q Meta_Control_q Meta_Control_q Meta_Control_q Meta_Control_q +U+0071 +U+0051 +U+0071 +U+0071 Control_q Control_q Control_q Control_q Meta_q Meta_Q Meta_q Meta_q Meta_Control_q Meta_Control_q Meta_Control_q Meta_Control_q +U+0051 +U+0071 +U+0051 +U+0051 Control_q Control_q Control_q Control_q Meta_q Meta_Q Meta_q Meta_q Meta_Control_q Meta_Control_q Meta_Control_q Meta_Control_q +U+0051 +U+0071 +U+0051 +U+0051 Control_q Control_q Control_q Control_q Meta_q Meta_Q Meta_q Meta_q Meta_Control_q Meta_Control_q Meta_Control_q Meta_Control_q +U+0051 +U+0071 +U+0051 +U+0051 Control_q Control_q Control_q Control_q Meta_q Meta_Q Meta_q Meta_q Meta_Control_q Meta_Control_q Meta_Control_q Meta_Control_q +U+0051 +U+0071 +U+0051 +U+0051 Control_q Control_q Control_q Control_q Meta_q Meta_Q Meta_q Meta_q Meta_Control_q Meta_Control_q Meta_Control_q Meta_Control_q
+keycode 46 = +U+006a +U+004a +U+006a +U+006a Linefeed Linefeed Linefeed Linefeed Meta_j Meta_J Meta_j Meta_j Meta_Linefeed Meta_Linefeed Meta_Linefeed Meta_Linefeed +U+006a +U+004a +U+006a +U+006a Linefeed Linefeed Linefeed Linefeed Meta_j Meta_J Meta_j Meta_j Meta_Linefeed Meta_Linefeed Meta_Linefeed Meta_Linefeed +U+006a +U+004a +U+006a +U+006a Linefeed Linefeed Linefeed Linefeed Meta_j Meta_J Meta_j Meta_j Meta_Linefeed Meta_Linefeed Meta_Linefeed Meta_Linefeed +U+006a +U+004a +U+006a +U+006a Linefeed Linefeed Linefeed Linefeed Meta_j Meta_J Meta_j Meta_j Meta_Linefeed Meta_Linefeed Meta_Linefeed Meta_Linefeed +U+004a +U+006a +U+004a +U+004a Linefeed Linefeed Linefeed Linefeed Meta_j Meta_J Meta_j Meta_j Meta_Linefeed Meta_Linefeed Meta_Linefeed Meta_Linefeed +U+004a +U+006a +U+004a +U+004a Linefeed Linefeed Linefeed Linefeed Meta_j Meta_J Meta_j Meta_j Meta_Linefeed Meta_Linefeed Meta_Linefeed Meta_Linefeed +U+004a +U+006a +U+004a +U+004a Linefeed Linefeed Linefeed Linefeed Meta_j Meta_J Meta_j Meta_j Meta_Linefeed Meta_Linefeed Meta_Linefeed Meta_Linefeed +U+004a +U+006a +U+004a +U+004a Linefeed Linefeed Linefeed Linefeed Meta_j Meta_J Meta_j Meta_j Meta_Linefeed Meta_Linefeed Meta_Linefeed Meta_Linefeed
+keycode 47 = +U+006b +U+004b +U+006b +U+006b Control_k Control_k Control_k Control_k Meta_k Meta_K Meta_k Meta_k Meta_Control_k Meta_Control_k Meta_Control_k Meta_Control_k +U+006b +U+004b +U+006b +U+006b Control_k Control_k Control_k Control_k Meta_k Meta_K Meta_k Meta_k Meta_Control_k Meta_Control_k Meta_Control_k Meta_Control_k +U+006b +U+004b +U+006b +U+006b Control_k Control_k Control_k Control_k Meta_k Meta_K Meta_k Meta_k Meta_Control_k Meta_Control_k Meta_Control_k Meta_Control_k +U+006b +U+004b +U+006b +U+006b Control_k Control_k Control_k Control_k Meta_k Meta_K Meta_k Meta_k Meta_Control_k Meta_Control_k Meta_Control_k Meta_Control_k +U+004b +U+006b +U+004b +U+004b Control_k Control_k Control_k Control_k Meta_k Meta_K Meta_k Meta_k Meta_Control_k Meta_Control_k Meta_Control_k Meta_Control_k +U+004b +U+006b +U+004b +U+004b Control_k Control_k Control_k Control_k Meta_k Meta_K Meta_k Meta_k Meta_Control_k Meta_Control_k Meta_Control_k Meta_Control_k +U+004b +U+006b +U+004b +U+004b Control_k Control_k Control_k Control_k Meta_k Meta_K Meta_k Meta_k Meta_Control_k Meta_Control_k Meta_Control_k Meta_Control_k +U+004b +U+006b +U+004b +U+004b Control_k Control_k Control_k Control_k Meta_k Meta_K Meta_k Meta_k Meta_Control_k Meta_Control_k Meta_Control_k Meta_Control_k
+keycode 48 = +U+0078 +U+0058 +U+0078 +U+0078 Control_x Control_x Control_x Control_x Meta_x Meta_X Meta_x Meta_x Meta_Control_x Meta_Control_x Meta_Control_x Meta_Control_x +U+0078 +U+0058 +U+0078 +U+0078 Control_x Control_x Control_x Control_x Meta_x Meta_X Meta_x Meta_x Meta_Control_x Meta_Control_x Meta_Control_x Meta_Control_x +U+0078 +U+0058 +U+0078 +U+0078 Control_x Control_x Control_x Control_x Meta_x Meta_X Meta_x Meta_x Meta_Control_x Meta_Control_x Meta_Control_x Meta_Control_x +U+0078 +U+0058 +U+0078 +U+0078 Control_x Control_x Control_x Control_x Meta_x Meta_X Meta_x Meta_x Meta_Control_x Meta_Control_x Meta_Control_x Meta_Control_x +U+0058 +U+0078 +U+0058 +U+0058 Control_x Control_x Control_x Control_x Meta_x Meta_X Meta_x Meta_x Meta_Control_x Meta_Control_x Meta_Control_x Meta_Control_x +U+0058 +U+0078 +U+0058 +U+0058 Control_x Control_x Control_x Control_x Meta_x Meta_X Meta_x Meta_x Meta_Control_x Meta_Control_x Meta_Control_x Meta_Control_x +U+0058 +U+0078 +U+0058 +U+0058 Control_x Control_x Control_x Control_x Meta_x Meta_X Meta_x Meta_x Meta_Control_x Meta_Control_x Meta_Control_x Meta_Control_x +U+0058 +U+0078 +U+0058 +U+0058 Control_x Control_x Control_x Control_x Meta_x Meta_X Meta_x Meta_x Meta_Control_x Meta_Control_x Meta_Control_x Meta_Control_x
+keycode 49 = +U+0062 +U+0042 +U+0062 +U+0062 Control_b Control_b Control_b Control_b Meta_b Meta_B Meta_b Meta_b Meta_Control_b Meta_Control_b Meta_Control_b Meta_Control_b +U+0062 +U+0042 +U+0062 +U+0062 Control_b Control_b Control_b Control_b Meta_b Meta_B Meta_b Meta_b Meta_Control_b Meta_Control_b Meta_Control_b Meta_Control_b +U+0062 +U+0042 +U+0062 +U+0062 Control_b Control_b Control_b Control_b Meta_b Meta_B Meta_b Meta_b Meta_Control_b Meta_Control_b Meta_Control_b Meta_Control_b +U+0062 +U+0042 +U+0062 +U+0062 Control_b Control_b Control_b Control_b Meta_b Meta_B Meta_b Meta_b Meta_Control_b Meta_Control_b Meta_Control_b Meta_Control_b +U+0042 +U+0062 +U+0042 +U+0042 Control_b Control_b Control_b Control_b Meta_b Meta_B Meta_b Meta_b Meta_Control_b Meta_Control_b Meta_Control_b Meta_Control_b +U+0042 +U+0062 +U+0042 +U+0042 Control_b Control_b Control_b Control_b Meta_b Meta_B Meta_b Meta_b Meta_Control_b Meta_Control_b Meta_Control_b Meta_Control_b +U+0042 +U+0062 +U+0042 +U+0042 Control_b Control_b Control_b Control_b Meta_b Meta_B Meta_b Meta_b Meta_Control_b Meta_Control_b Meta_Control_b Meta_Control_b +U+0042 +U+0062 +U+0042 +U+0042 Control_b Control_b Control_b Control_b Meta_b Meta_B Meta_b Meta_b Meta_Control_b Meta_Control_b Meta_Control_b Meta_Control_b
+keycode 50 = +U+006d +U+004d +U+006d +U+006d Control_m Control_m Control_m Control_m Meta_m Meta_M Meta_m Meta_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m +U+006d +U+004d +U+006d +U+006d Control_m Control_m Control_m Control_m Meta_m Meta_M Meta_m Meta_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m +U+006d +U+004d +U+006d +U+006d Control_m Control_m Control_m Control_m Meta_m Meta_M Meta_m Meta_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m +U+006d +U+004d +U+006d +U+006d Control_m Control_m Control_m Control_m Meta_m Meta_M Meta_m Meta_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m +U+004d +U+006d +U+004d +U+004d Control_m Control_m Control_m Control_m Meta_m Meta_M Meta_m Meta_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m +U+004d +U+006d +U+004d +U+004d Control_m Control_m Control_m Control_m Meta_m Meta_M Meta_m Meta_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m +U+004d +U+006d +U+004d +U+004d Control_m Control_m Control_m Control_m Meta_m Meta_M Meta_m Meta_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m +U+004d +U+006d +U+004d +U+004d Control_m Control_m Control_m Control_m Meta_m Meta_M Meta_m Meta_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m
+keycode 51 = +U+0077 +U+0057 +U+0077 +U+0077 Control_w Control_w Control_w Control_w Meta_w Meta_W Meta_w Meta_w Meta_Control_w Meta_Control_w Meta_Control_w Meta_Control_w +U+0077 +U+0057 +U+0077 +U+0077 Control_w Control_w Control_w Control_w Meta_w Meta_W Meta_w Meta_w Meta_Control_w Meta_Control_w Meta_Control_w Meta_Control_w +U+0077 +U+0057 +U+0077 +U+0077 Control_w Control_w Control_w Control_w Meta_w Meta_W Meta_w Meta_w Meta_Control_w Meta_Control_w Meta_Control_w Meta_Control_w +U+0077 +U+0057 +U+0077 +U+0077 Control_w Control_w Control_w Control_w Meta_w Meta_W Meta_w Meta_w Meta_Control_w Meta_Control_w Meta_Control_w Meta_Control_w +U+0057 +U+0077 +U+0057 +U+0057 Control_w Control_w Control_w Control_w Meta_w Meta_W Meta_w Meta_w Meta_Control_w Meta_Control_w Meta_Control_w Meta_Control_w +U+0057 +U+0077 +U+0057 +U+0057 Control_w Control_w Control_w Control_w Meta_w Meta_W Meta_w Meta_w Meta_Control_w Meta_Control_w Meta_Control_w Meta_Control_w +U+0057 +U+0077 +U+0057 +U+0057 Control_w Control_w Control_w Control_w Meta_w Meta_W Meta_w Meta_w Meta_Control_w Meta_Control_w Meta_Control_w Meta_Control_w +U+0057 +U+0077 +U+0057 +U+0057 Control_w Control_w Control_w Control_w Meta_w Meta_W Meta_w Meta_w Meta_Control_w Meta_Control_w Meta_Control_w Meta_Control_w
+keycode 52 = +U+0076 +U+0056 +U+0076 +U+0076 Control_v Control_v Control_v Control_v Meta_v Meta_V Meta_v Meta_v Meta_Control_v Meta_Control_v Meta_Control_v Meta_Control_v +U+0076 +U+0056 +U+0076 +U+0076 Control_v Control_v Control_v Control_v Meta_v Meta_V Meta_v Meta_v Meta_Control_v Meta_Control_v Meta_Control_v Meta_Control_v +U+0076 +U+0056 +U+0076 +U+0076 Control_v Control_v Control_v Control_v Meta_v Meta_V Meta_v Meta_v Meta_Control_v Meta_Control_v Meta_Control_v Meta_Control_v +U+0076 +U+0056 +U+0076 +U+0076 Control_v Control_v Control_v Control_v Meta_v Meta_V Meta_v Meta_v Meta_Control_v Meta_Control_v Meta_Control_v Meta_Control_v +U+0056 +U+0076 +U+0056 +U+0056 Control_v Control_v Control_v Control_v Meta_v Meta_V Meta_v Meta_v Meta_Control_v Meta_Control_v Meta_Control_v Meta_Control_v +U+0056 +U+0076 +U+0056 +U+0056 Control_v Control_v Control_v Control_v Meta_v Meta_V Meta_v Meta_v Meta_Control_v Meta_Control_v Meta_Control_v Meta_Control_v +U+0056 +U+0076 +U+0056 +U+0056 Control_v Control_v Control_v Control_v Meta_v Meta_V Meta_v Meta_v Meta_Control_v Meta_Control_v Meta_Control_v Meta_Control_v +U+0056 +U+0076 +U+0056 +U+0056 Control_v Control_v Control_v Control_v Meta_v Meta_V Meta_v Meta_v Meta_Control_v Meta_Control_v Meta_Control_v Meta_Control_v
+keycode 53 = +U+007a +U+005a +U+007a +U+007a Control_z Control_z Control_z Control_z Meta_z Meta_Z Meta_z Meta_z Meta_Control_z Meta_Control_z Meta_Control_z Meta_Control_z +U+007a +U+005a +U+007a +U+007a Control_z Control_z Control_z Control_z Meta_z Meta_Z Meta_z Meta_z Meta_Control_z Meta_Control_z Meta_Control_z Meta_Control_z +U+007a +U+005a +U+007a +U+007a Control_z Control_z Control_z Control_z Meta_z Meta_Z Meta_z Meta_z Meta_Control_z Meta_Control_z Meta_Control_z Meta_Control_z +U+007a +U+005a +U+007a +U+007a Control_z Control_z Control_z Control_z Meta_z Meta_Z Meta_z Meta_z Meta_Control_z Meta_Control_z Meta_Control_z Meta_Control_z +U+005a +U+007a +U+005a +U+005a Control_z Control_z Control_z Control_z Meta_z Meta_Z Meta_z Meta_z Meta_Control_z Meta_Control_z Meta_Control_z Meta_Control_z +U+005a +U+007a +U+005a +U+005a Control_z Control_z Control_z Control_z Meta_z Meta_Z Meta_z Meta_z Meta_Control_z Meta_Control_z Meta_Control_z Meta_Control_z +U+005a +U+007a +U+005a +U+005a Control_z Control_z Control_z Control_z Meta_z Meta_Z Meta_z Meta_z Meta_Control_z Meta_Control_z Meta_Control_z Meta_Control_z +U+005a +U+007a +U+005a +U+005a Control_z Control_z Control_z Control_z Meta_z Meta_Z Meta_z Meta_z Meta_Control_z Meta_Control_z Meta_Control_z Meta_Control_z
+keycode 54 = Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift
+keycode 55 = KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply
+keycode 56 = Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt
+keycode 57 = U+0020 U+0020 U+0020 U+0020 nul nul nul nul Meta_space Meta_space Meta_space Meta_space Meta_nul Meta_nul Meta_nul Meta_nul U+0020 U+0020 U+0020 U+0020 nul nul nul nul Meta_space Meta_space Meta_space Meta_space Meta_nul Meta_nul Meta_nul Meta_nul U+0020 U+0020 U+0020 U+0020 nul nul nul nul Meta_space Meta_space Meta_space Meta_space Meta_nul Meta_nul Meta_nul Meta_nul U+0020 U+0020 U+0020 U+0020 nul nul nul nul Meta_space Meta_space Meta_space Meta_space Meta_nul Meta_nul Meta_nul Meta_nul U+0020 U+0020 U+0020 U+0020 nul nul nul nul Meta_space Meta_space Meta_space Meta_space Meta_nul Meta_nul Meta_nul Meta_nul U+0020 U+0020 U+0020 U+0020 nul nul nul nul Meta_space Meta_space Meta_space Meta_space Meta_nul Meta_nul Meta_nul Meta_nul U+0020 U+0020 U+0020 U+0020 nul nul nul nul Meta_space Meta_space Meta_space Meta_space Meta_nul Meta_nul Meta_nul Meta_nul U+0020 U+0020 U+0020 U+0020 nul nul nul nul Meta_space Meta_space Meta_space Meta_space Meta_nul Meta_nul Meta_nul Meta_nul
+keycode 58 = CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock
+keycode 59 = F1 F13 Console_13 Console_25 F25 F37 Console_13 Console_25 Console_1 Console_13 F1 F1 Console_1 Console_13 F1 F1 F1 F13 Console_13 Console_25 F25 F37 Console_13 Console_25 Console_1 Console_13 F1 F1 Console_1 Console_13 F1 F1 F1 F13 Console_13 Console_25 F25 F37 Console_13 Console_25 Console_1 Console_13 F1 F1 Console_1 Console_13 F1 F1 F1 F13 Console_13 Console_25 F25 F37 Console_13 Console_25 Console_1 Console_13 F1 F1 Console_1 Console_13 F1 F1 F1 F13 Console_13 Console_25 F25 F37 Console_13 Console_25 Console_1 Console_13 F1 F1 Console_1 Console_13 F1 F1 F1 F13 Console_13 Console_25 F25 F37 Console_13 Console_25 Console_1 Console_13 F1 F1 Console_1 Console_13 F1 F1 F1 F13 Console_13 Console_25 F25 F37 Console_13 Console_25 Console_1 Console_13 F1 F1 Console_1 Console_13 F1 F1 F1 F13 Console_13 Console_25 F25 F37 Console_13 Console_25 Console_1 Console_13 F1 F1 Console_1 Console_13 F1 F1
+keycode 60 = F2 F14 Console_14 Console_26 F26 F38 Console_14 Console_26 Console_2 Console_14 F2 F2 Console_2 Console_14 F2 F2 F2 F14 Console_14 Console_26 F26 F38 Console_14 Console_26 Console_2 Console_14 F2 F2 Console_2 Console_14 F2 F2 F2 F14 Console_14 Console_26 F26 F38 Console_14 Console_26 Console_2 Console_14 F2 F2 Console_2 Console_14 F2 F2 F2 F14 Console_14 Console_26 F26 F38 Console_14 Console_26 Console_2 Console_14 F2 F2 Console_2 Console_14 F2 F2 F2 F14 Console_14 Console_26 F26 F38 Console_14 Console_26 Console_2 Console_14 F2 F2 Console_2 Console_14 F2 F2 F2 F14 Console_14 Console_26 F26 F38 Console_14 Console_26 Console_2 Console_14 F2 F2 Console_2 Console_14 F2 F2 F2 F14 Console_14 Console_26 F26 F38 Console_14 Console_26 Console_2 Console_14 F2 F2 Console_2 Console_14 F2 F2 F2 F14 Console_14 Console_26 F26 F38 Console_14 Console_26 Console_2 Console_14 F2 F2 Console_2 Console_14 F2 F2
+keycode 61 = F3 F15 Console_15 Console_27 F27 F39 Console_15 Console_27 Console_3 Console_15 F3 F3 Console_3 Console_15 F3 F3 F3 F15 Console_15 Console_27 F27 F39 Console_15 Console_27 Console_3 Console_15 F3 F3 Console_3 Console_15 F3 F3 F3 F15 Console_15 Console_27 F27 F39 Console_15 Console_27 Console_3 Console_15 F3 F3 Console_3 Console_15 F3 F3 F3 F15 Console_15 Console_27 F27 F39 Console_15 Console_27 Console_3 Console_15 F3 F3 Console_3 Console_15 F3 F3 F3 F15 Console_15 Console_27 F27 F39 Console_15 Console_27 Console_3 Console_15 F3 F3 Console_3 Console_15 F3 F3 F3 F15 Console_15 Console_27 F27 F39 Console_15 Console_27 Console_3 Console_15 F3 F3 Console_3 Console_15 F3 F3 F3 F15 Console_15 Console_27 F27 F39 Console_15 Console_27 Console_3 Console_15 F3 F3 Console_3 Console_15 F3 F3 F3 F15 Console_15 Console_27 F27 F39 Console_15 Console_27 Console_3 Console_15 F3 F3 Console_3 Console_15 F3 F3
+keycode 62 = F4 F16 Console_16 Console_28 F28 F40 Console_16 Console_28 Console_4 Console_16 F4 F4 Console_4 Console_16 F4 F4 F4 F16 Console_16 Console_28 F28 F40 Console_16 Console_28 Console_4 Console_16 F4 F4 Console_4 Console_16 F4 F4 F4 F16 Console_16 Console_28 F28 F40 Console_16 Console_28 Console_4 Console_16 F4 F4 Console_4 Console_16 F4 F4 F4 F16 Console_16 Console_28 F28 F40 Console_16 Console_28 Console_4 Console_16 F4 F4 Console_4 Console_16 F4 F4 F4 F16 Console_16 Console_28 F28 F40 Console_16 Console_28 Console_4 Console_16 F4 F4 Console_4 Console_16 F4 F4 F4 F16 Console_16 Console_28 F28 F40 Console_16 Console_28 Console_4 Console_16 F4 F4 Console_4 Console_16 F4 F4 F4 F16 Console_16 Console_28 F28 F40 Console_16 Console_28 Console_4 Console_16 F4 F4 Console_4 Console_16 F4 F4 F4 F16 Console_16 Console_28 F28 F40 Console_16 Console_28 Console_4 Console_16 F4 F4 Console_4 Console_16 F4 F4
+keycode 63 = F5 F17 Console_17 Console_29 F29 F41 Console_17 Console_29 Console_5 Console_17 F5 F5 Console_5 Console_17 F5 F5 F5 F17 Console_17 Console_29 F29 F41 Console_17 Console_29 Console_5 Console_17 F5 F5 Console_5 Console_17 F5 F5 F5 F17 Console_17 Console_29 F29 F41 Console_17 Console_29 Console_5 Console_17 F5 F5 Console_5 Console_17 F5 F5 F5 F17 Console_17 Console_29 F29 F41 Console_17 Console_29 Console_5 Console_17 F5 F5 Console_5 Console_17 F5 F5 F5 F17 Console_17 Console_29 F29 F41 Console_17 Console_29 Console_5 Console_17 F5 F5 Console_5 Console_17 F5 F5 F5 F17 Console_17 Console_29 F29 F41 Console_17 Console_29 Console_5 Console_17 F5 F5 Console_5 Console_17 F5 F5 F5 F17 Console_17 Console_29 F29 F41 Console_17 Console_29 Console_5 Console_17 F5 F5 Console_5 Console_17 F5 F5 F5 F17 Console_17 Console_29 F29 F41 Console_17 Console_29 Console_5 Console_17 F5 F5 Console_5 Console_17 F5 F5
+keycode 64 = F6 F18 Console_18 Console_30 F30 F42 Console_18 Console_30 Console_6 Console_18 F6 F6 Console_6 Console_18 F6 F6 F6 F18 Console_18 Console_30 F30 F42 Console_18 Console_30 Console_6 Console_18 F6 F6 Console_6 Console_18 F6 F6 F6 F18 Console_18 Console_30 F30 F42 Console_18 Console_30 Console_6 Console_18 F6 F6 Console_6 Console_18 F6 F6 F6 F18 Console_18 Console_30 F30 F42 Console_18 Console_30 Console_6 Console_18 F6 F6 Console_6 Console_18 F6 F6 F6 F18 Console_18 Console_30 F30 F42 Console_18 Console_30 Console_6 Console_18 F6 F6 Console_6 Console_18 F6 F6 F6 F18 Console_18 Console_30 F30 F42 Console_18 Console_30 Console_6 Console_18 F6 F6 Console_6 Console_18 F6 F6 F6 F18 Console_18 Console_30 F30 F42 Console_18 Console_30 Console_6 Console_18 F6 F6 Console_6 Console_18 F6 F6 F6 F18 Console_18 Console_30 F30 F42 Console_18 Console_30 Console_6 Console_18 F6 F6 Console_6 Console_18 F6 F6
+keycode 65 = F7 F19 Console_19 Console_31 F31 F43 Console_19 Console_31 Console_7 Console_19 F7 F7 Console_7 Console_19 F7 F7 F7 F19 Console_19 Console_31 F31 F43 Console_19 Console_31 Console_7 Console_19 F7 F7 Console_7 Console_19 F7 F7 F7 F19 Console_19 Console_31 F31 F43 Console_19 Console_31 Console_7 Console_19 F7 F7 Console_7 Console_19 F7 F7 F7 F19 Console_19 Console_31 F31 F43 Console_19 Console_31 Console_7 Console_19 F7 F7 Console_7 Console_19 F7 F7 F7 F19 Console_19 Console_31 F31 F43 Console_19 Console_31 Console_7 Console_19 F7 F7 Console_7 Console_19 F7 F7 F7 F19 Console_19 Console_31 F31 F43 Console_19 Console_31 Console_7 Console_19 F7 F7 Console_7 Console_19 F7 F7 F7 F19 Console_19 Console_31 F31 F43 Console_19 Console_31 Console_7 Console_19 F7 F7 Console_7 Console_19 F7 F7 F7 F19 Console_19 Console_31 F31 F43 Console_19 Console_31 Console_7 Console_19 F7 F7 Console_7 Console_19 F7 F7
+keycode 66 = F8 F20 Console_20 Console_32 F32 F44 Console_20 Console_32 Console_8 Console_20 F8 F8 Console_8 Console_20 F8 F8 F8 F20 Console_20 Console_32 F32 F44 Console_20 Console_32 Console_8 Console_20 F8 F8 Console_8 Console_20 F8 F8 F8 F20 Console_20 Console_32 F32 F44 Console_20 Console_32 Console_8 Console_20 F8 F8 Console_8 Console_20 F8 F8 F8 F20 Console_20 Console_32 F32 F44 Console_20 Console_32 Console_8 Console_20 F8 F8 Console_8 Console_20 F8 F8 F8 F20 Console_20 Console_32 F32 F44 Console_20 Console_32 Console_8 Console_20 F8 F8 Console_8 Console_20 F8 F8 F8 F20 Console_20 Console_32 F32 F44 Console_20 Console_32 Console_8 Console_20 F8 F8 Console_8 Console_20 F8 F8 F8 F20 Console_20 Console_32 F32 F44 Console_20 Console_32 Console_8 Console_20 F8 F8 Console_8 Console_20 F8 F8 F8 F20 Console_20 Console_32 F32 F44 Console_20 Console_32 Console_8 Console_20 F8 F8 Console_8 Console_20 F8 F8
+keycode 67 = F9 F21 Console_21 Console_33 F33 F45 Console_21 Console_33 Console_9 Console_21 F9 F9 Console_9 Console_21 F9 F9 F9 F21 Console_21 Console_33 F33 F45 Console_21 Console_33 Console_9 Console_21 F9 F9 Console_9 Console_21 F9 F9 F9 F21 Console_21 Console_33 F33 F45 Console_21 Console_33 Console_9 Console_21 F9 F9 Console_9 Console_21 F9 F9 F9 F21 Console_21 Console_33 F33 F45 Console_21 Console_33 Console_9 Console_21 F9 F9 Console_9 Console_21 F9 F9 F9 F21 Console_21 Console_33 F33 F45 Console_21 Console_33 Console_9 Console_21 F9 F9 Console_9 Console_21 F9 F9 F9 F21 Console_21 Console_33 F33 F45 Console_21 Console_33 Console_9 Console_21 F9 F9 Console_9 Console_21 F9 F9 F9 F21 Console_21 Console_33 F33 F45 Console_21 Console_33 Console_9 Console_21 F9 F9 Console_9 Console_21 F9 F9 F9 F21 Console_21 Console_33 F33 F45 Console_21 Console_33 Console_9 Console_21 F9 F9 Console_9 Console_21 F9 F9
+keycode 68 = F10 F22 Console_22 Console_34 F34 F46 Console_22 Console_34 Console_10 Console_22 F10 F10 Console_10 Console_22 F10 F10 F10 F22 Console_22 Console_34 F34 F46 Console_22 Console_34 Console_10 Console_22 F10 F10 Console_10 Console_22 F10 F10 F10 F22 Console_22 Console_34 F34 F46 Console_22 Console_34 Console_10 Console_22 F10 F10 Console_10 Console_22 F10 F10 F10 F22 Console_22 Console_34 F34 F46 Console_22 Console_34 Console_10 Console_22 F10 F10 Console_10 Console_22 F10 F10 F10 F22 Console_22 Console_34 F34 F46 Console_22 Console_34 Console_10 Console_22 F10 F10 Console_10 Console_22 F10 F10 F10 F22 Console_22 Console_34 F34 F46 Console_22 Console_34 Console_10 Console_22 F10 F10 Console_10 Console_22 F10 F10 F10 F22 Console_22 Console_34 F34 F46 Console_22 Console_34 Console_10 Console_22 F10 F10 Console_10 Console_22 F10 F10 F10 F22 Console_22 Console_34 F34 F46 Console_22 Console_34 Console_10 Console_22 F10 F10 Console_10 Console_22 F10 F10
+keycode 69 = Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock
+keycode 70 = Scroll_Lock Show_Memory Show_Registers Scroll_Lock Show_State Scroll_Lock Scroll_Lock Scroll_Lock Show_Registers Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Show_Memory Show_Registers Scroll_Lock Show_State Scroll_Lock Scroll_Lock Scroll_Lock Show_Registers Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Show_Memory Show_Registers Scroll_Lock Show_State Scroll_Lock Scroll_Lock Scroll_Lock Show_Registers Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Show_Memory Show_Registers Scroll_Lock Show_State Scroll_Lock Scroll_Lock Scroll_Lock Show_Registers Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Show_Memory Show_Registers Scroll_Lock Show_State Scroll_Lock Scroll_Lock Scroll_Lock Show_Registers Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Show_Memory Show_Registers Scroll_Lock Show_State Scroll_Lock Scroll_Lock Scroll_Lock Show_Registers Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Show_Memory Show_Registers Scroll_Lock Show_State Scroll_Lock Scroll_Lock Scroll_Lock Show_Registers Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Show_Memory Show_Registers Scroll_Lock Show_State Scroll_Lock Scroll_Lock Scroll_Lock Show_Registers Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock
+keycode 71 = KP_7 KP_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 Ascii_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 Ascii_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 Ascii_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 Ascii_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 Ascii_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 Ascii_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 Ascii_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 Ascii_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7
+keycode 72 = KP_8 KP_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 Ascii_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 Ascii_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 Ascii_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 Ascii_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 Ascii_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 Ascii_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 Ascii_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 Ascii_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8
+keycode 73 = KP_9 KP_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 Ascii_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 Ascii_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 Ascii_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 Ascii_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 Ascii_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 Ascii_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 Ascii_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 Ascii_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9
+keycode 74 = KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract
+keycode 75 = KP_4 KP_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 Ascii_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 Ascii_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 Ascii_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 Ascii_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 Ascii_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 Ascii_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 Ascii_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 Ascii_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4
+keycode 76 = KP_5 KP_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 Ascii_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 Ascii_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 Ascii_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 Ascii_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 Ascii_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 Ascii_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 Ascii_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 Ascii_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5
+keycode 77 = KP_6 KP_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 Ascii_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 Ascii_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 Ascii_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 Ascii_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 Ascii_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 Ascii_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 Ascii_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 Ascii_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6
+keycode 78 = KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add
+keycode 79 = KP_1 KP_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 Ascii_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 Ascii_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 Ascii_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 Ascii_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 Ascii_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 Ascii_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 Ascii_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 Ascii_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1
+keycode 80 = KP_2 KP_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 Ascii_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 Ascii_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 Ascii_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 Ascii_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 Ascii_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 Ascii_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 Ascii_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 Ascii_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2
+keycode 81 = KP_3 KP_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 Ascii_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 Ascii_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 Ascii_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 Ascii_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 Ascii_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 Ascii_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 Ascii_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 Ascii_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3
+keycode 82 = KP_0 KP_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 Ascii_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 Ascii_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 Ascii_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 Ascii_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 Ascii_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 Ascii_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 Ascii_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 Ascii_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0
+keycode 83 = KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period Boot KP_Period
+keycode 86 = U+003c U+003e U+007c U+00a6 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_less Meta_greater Meta_bar Meta_bar VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+003c U+003e U+007c U+00a6 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_less Meta_greater Meta_bar Meta_bar VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+003c U+003e U+007c U+00a6 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_less Meta_greater Meta_bar Meta_bar VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+003c U+003e U+007c U+00a6 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_less Meta_greater Meta_bar Meta_bar VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+003c U+003e U+007c U+00a6 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_less Meta_greater Meta_bar Meta_bar VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+003c U+003e U+007c U+00a6 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_less Meta_greater Meta_bar Meta_bar VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+003c U+003e U+007c U+00a6 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_less Meta_greater Meta_bar Meta_bar VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+003c U+003e U+007c U+00a6 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_less Meta_greater Meta_bar Meta_bar VoidSymbol VoidSymbol VoidSymbol VoidSymbol
+keycode 87 = F11 F23 Console_23 Console_35 F35 F47 Console_23 Console_35 Console_11 Console_23 F11 F11 Console_11 Console_23 F11 F11 F11 F23 Console_23 Console_35 F35 F47 Console_23 Console_35 Console_11 Console_23 F11 F11 Console_11 Console_23 F11 F11 F11 F23 Console_23 Console_35 F35 F47 Console_23 Console_35 Console_11 Console_23 F11 F11 Console_11 Console_23 F11 F11 F11 F23 Console_23 Console_35 F35 F47 Console_23 Console_35 Console_11 Console_23 F11 F11 Console_11 Console_23 F11 F11 F11 F23 Console_23 Console_35 F35 F47 Console_23 Console_35 Console_11 Console_23 F11 F11 Console_11 Console_23 F11 F11 F11 F23 Console_23 Console_35 F35 F47 Console_23 Console_35 Console_11 Console_23 F11 F11 Console_11 Console_23 F11 F11 F11 F23 Console_23 Console_35 F35 F47 Console_23 Console_35 Console_11 Console_23 F11 F11 Console_11 Console_23 F11 F11 F11 F23 Console_23 Console_35 F35 F47 Console_23 Console_35 Console_11 Console_23 F11 F11 Console_11 Console_23 F11 F11
+keycode 88 = F12 F24 Console_24 Console_36 F36 F48 Console_24 Console_36 Console_12 Console_24 F12 F12 Console_12 Console_24 F12 F12 F12 F24 Console_24 Console_36 F36 F48 Console_24 Console_36 Console_12 Console_24 F12 F12 Console_12 Console_24 F12 F12 F12 F24 Console_24 Console_36 F36 F48 Console_24 Console_36 Console_12 Console_24 F12 F12 Console_12 Console_24 F12 F12 F12 F24 Console_24 Console_36 F36 F48 Console_24 Console_36 Console_12 Console_24 F12 F12 Console_12 Console_24 F12 F12 F12 F24 Console_24 Console_36 F36 F48 Console_24 Console_36 Console_12 Console_24 F12 F12 Console_12 Console_24 F12 F12 F12 F24 Console_24 Console_36 F36 F48 Console_24 Console_36 Console_12 Console_24 F12 F12 Console_12 Console_24 F12 F12 F12 F24 Console_24 Console_36 F36 F48 Console_24 Console_36 Console_12 Console_24 F12 F12 Console_12 Console_24 F12 F12 F12 F24 Console_24 Console_36 F36 F48 Console_24 Console_36 Console_12 Console_24 F12 F12 Console_12 Console_24 F12 F12
+keycode 102 = Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home
+keycode 103 = Up Up Up Up Up Up Up Up KeyboardSignal Up Up Up Up Up Up Up Up Up Up Up Up Up Up Up KeyboardSignal Up Up Up Up Up Up Up Up Up Up Up Up Up Up Up KeyboardSignal Up Up Up Up Up Up Up Up Up Up Up Up Up Up Up KeyboardSignal Up Up Up Up Up Up Up Up Up Up Up Up Up Up Up KeyboardSignal Up Up Up Up Up Up Up Up Up Up Up Up Up Up Up KeyboardSignal Up Up Up Up Up Up Up Up Up Up Up Up Up Up Up KeyboardSignal Up Up Up Up Up Up Up Up Up Up Up Up Up Up Up KeyboardSignal Up Up Up Up Up Up Up
+keycode 104 = Prior Scroll_Backward Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Scroll_Backward Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Scroll_Backward Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Scroll_Backward Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Scroll_Backward Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Scroll_Backward Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Scroll_Backward Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Scroll_Backward Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior
+keycode 105 = Left Left Left Left Left Left Left Left Decr_Console Left Left Left Left Left Left Left Left Left Left Left Left Left Left Left Decr_Console Left Left Left Left Left Left Left Left Left Left Left Left Left Left Left Decr_Console Left Left Left Left Left Left Left Left Left Left Left Left Left Left Left Decr_Console Left Left Left Left Left Left Left Left Left Left Left Left Left Left Left Decr_Console Left Left Left Left Left Left Left Left Left Left Left Left Left Left Left Decr_Console Left Left Left Left Left Left Left Left Left Left Left Left Left Left Left Decr_Console Left Left Left Left Left Left Left Left Left Left Left Left Left Left Left Decr_Console Left Left Left Left Left Left Left
+keycode 106 = Right Right Right Right Right Right Right Right Incr_Console Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Incr_Console Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Incr_Console Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Incr_Console Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Incr_Console Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Incr_Console Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Incr_Console Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Incr_Console Right Right Right Right Right Right Right
+keycode 107 = End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End
+keycode 108 = Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down
+keycode 109 = Next Scroll_Forward Next Next Next Next Next Next Next Next Next Next Next Next Next Next Next Scroll_Forward Next Next Next Next Next Next Next Next Next Next Next Next Next Next Next Scroll_Forward Next Next Next Next Next Next Next Next Next Next Next Next Next Next Next Scroll_Forward Next Next Next Next Next Next Next Next Next Next Next Next Next Next Next Scroll_Forward Next Next Next Next Next Next Next Next Next Next Next Next Next Next Next Scroll_Forward Next Next Next Next Next Next Next Next Next Next Next Next Next Next Next Scroll_Forward Next Next Next Next Next Next Next Next Next Next Next Next Next Next Next Scroll_Forward Next Next Next Next Next Next Next Next Next Next Next Next Next Next
+keycode 110 = Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert
+keycode 111 = Remove Remove Remove Remove Remove Remove Boot Remove Remove Remove Remove Remove Boot Remove Boot Remove Remove Remove Remove Remove Remove Remove Boot Remove Remove Remove Remove Remove Boot Remove Boot Remove Remove Remove Remove Remove Remove Remove Boot Remove Remove Remove Remove Remove Boot Remove Boot Remove Remove Remove Remove Remove Remove Remove Boot Remove Remove Remove Remove Remove Boot Remove Boot Remove Remove Remove Remove Remove Remove Remove Boot Remove Remove Remove Remove Remove Boot Remove Boot Remove Remove Remove Remove Remove Remove Remove Boot Remove Remove Remove Remove Remove Boot Remove Boot Remove Remove Remove Remove Remove Remove Remove Boot Remove Remove Remove Remove Remove Boot Remove Boot Remove Remove Remove Remove Remove Remove Remove Boot Remove Remove Remove Remove Remove Boot Remove Boot Remove
+keycode 96 = KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter
+keycode 97 = Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control
+keycode 119 = Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause
+keycode 99 = VoidSymbol VoidSymbol Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash VoidSymbol VoidSymbol Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash VoidSymbol VoidSymbol Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash VoidSymbol VoidSymbol Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash VoidSymbol VoidSymbol Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash VoidSymbol VoidSymbol Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash VoidSymbol VoidSymbol Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash VoidSymbol VoidSymbol Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash
+keycode 98 = KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide
+keycode 100 = Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt
+keycode 125 = Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt
+keycode 126 = Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt
+keycode 121 = KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period
+strings as usual
+# The content of this file will be appended to the keyboard layout.
+# For example if you uncomment the following lines Alt+j can be used
+# to go to the next console and Alt+k can be used to go to the
+# previous console:
+
+# alt keycode 36 = Incr_Console
+# shiftl alt keycode 36 = Incr_Console
+# shiftr alt keycode 36 = Incr_Console
+# shiftr shiftl alt keycode 36 = Incr_Console
+# ctrll alt keycode 36 = Incr_Console
+# ctrll shiftl alt keycode 36 = Incr_Console
+# ctrll shiftr alt keycode 36 = Incr_Console
+# ctrll shiftr shiftl alt keycode 36 = Incr_Console
+
+# alt keycode 37 = Decr_Console
+# shiftl alt keycode 37 = Decr_Console
+# shiftr alt keycode 37 = Decr_Console
+# shiftr shiftl alt keycode 37 = Decr_Console
+# ctrll alt keycode 37 = Decr_Console
+# ctrll shiftl alt keycode 37 = Decr_Console
+# ctrll shiftr alt keycode 37 = Decr_Console
+# ctrll shiftr shiftl alt keycode 37 = Decr_Console
+
diff --git a/resources/grub/keymap/usqwerty b/resources/grub/keymap/usqwerty
new file mode 100644
index 0000000..5110323
--- /dev/null
+++ b/resources/grub/keymap/usqwerty
@@ -0,0 +1,130 @@
+keymaps 0-127
+keycode 1 = Escape Escape Escape Escape Escape Escape Escape Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Escape Escape Escape Escape Escape Escape Escape Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Escape Escape Escape Escape Escape Escape Escape Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Escape Escape Escape Escape Escape Escape Escape Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Escape Escape Escape Escape Escape Escape Escape Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Escape Escape Escape Escape Escape Escape Escape Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Escape Escape Escape Escape Escape Escape Escape Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Escape Escape Escape Escape Escape Escape Escape Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape Meta_Escape
+keycode 2 = U+0031 U+0021 U+0031 U+0031 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_one Meta_exclam Meta_one Meta_one VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0031 U+0021 U+0031 U+0031 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_one Meta_exclam Meta_one Meta_one VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0031 U+0021 U+0031 U+0031 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_one Meta_exclam Meta_one Meta_one VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0031 U+0021 U+0031 U+0031 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_one Meta_exclam Meta_one Meta_one VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0031 U+0021 U+0031 U+0031 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_one Meta_exclam Meta_one Meta_one VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0031 U+0021 U+0031 U+0031 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_one Meta_exclam Meta_one Meta_one VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0031 U+0021 U+0031 U+0031 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_one Meta_exclam Meta_one Meta_one VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0031 U+0021 U+0031 U+0031 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_one Meta_exclam Meta_one Meta_one VoidSymbol VoidSymbol VoidSymbol VoidSymbol
+keycode 3 = U+0032 U+0040 U+0032 U+0032 nul nul nul nul Meta_two Meta_at Meta_two Meta_two Meta_nul Meta_nul Meta_nul Meta_nul U+0032 U+0040 U+0032 U+0032 nul nul nul nul Meta_two Meta_at Meta_two Meta_two Meta_nul Meta_nul Meta_nul Meta_nul U+0032 U+0040 U+0032 U+0032 nul nul nul nul Meta_two Meta_at Meta_two Meta_two Meta_nul Meta_nul Meta_nul Meta_nul U+0032 U+0040 U+0032 U+0032 nul nul nul nul Meta_two Meta_at Meta_two Meta_two Meta_nul Meta_nul Meta_nul Meta_nul U+0032 U+0040 U+0032 U+0032 nul nul nul nul Meta_two Meta_at Meta_two Meta_two Meta_nul Meta_nul Meta_nul Meta_nul U+0032 U+0040 U+0032 U+0032 nul nul nul nul Meta_two Meta_at Meta_two Meta_two Meta_nul Meta_nul Meta_nul Meta_nul U+0032 U+0040 U+0032 U+0032 nul nul nul nul Meta_two Meta_at Meta_two Meta_two Meta_nul Meta_nul Meta_nul Meta_nul U+0032 U+0040 U+0032 U+0032 nul nul nul nul Meta_two Meta_at Meta_two Meta_two Meta_nul Meta_nul Meta_nul Meta_nul
+keycode 4 = U+0033 U+0023 U+0033 U+0033 Escape Escape Escape Escape Meta_three Meta_numbersign Meta_three Meta_three Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+0033 U+0023 U+0033 U+0033 Escape Escape Escape Escape Meta_three Meta_numbersign Meta_three Meta_three Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+0033 U+0023 U+0033 U+0033 Escape Escape Escape Escape Meta_three Meta_numbersign Meta_three Meta_three Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+0033 U+0023 U+0033 U+0033 Escape Escape Escape Escape Meta_three Meta_numbersign Meta_three Meta_three Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+0033 U+0023 U+0033 U+0033 Escape Escape Escape Escape Meta_three Meta_numbersign Meta_three Meta_three Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+0033 U+0023 U+0033 U+0033 Escape Escape Escape Escape Meta_three Meta_numbersign Meta_three Meta_three Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+0033 U+0023 U+0033 U+0033 Escape Escape Escape Escape Meta_three Meta_numbersign Meta_three Meta_three Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+0033 U+0023 U+0033 U+0033 Escape Escape Escape Escape Meta_three Meta_numbersign Meta_three Meta_three Meta_Escape Meta_Escape Meta_Escape Meta_Escape
+keycode 5 = U+0034 U+0024 U+0034 U+0034 Control_backslash Control_backslash Control_backslash Control_backslash Meta_four Meta_dollar Meta_four Meta_four Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+0034 U+0024 U+0034 U+0034 Control_backslash Control_backslash Control_backslash Control_backslash Meta_four Meta_dollar Meta_four Meta_four Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+0034 U+0024 U+0034 U+0034 Control_backslash Control_backslash Control_backslash Control_backslash Meta_four Meta_dollar Meta_four Meta_four Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+0034 U+0024 U+0034 U+0034 Control_backslash Control_backslash Control_backslash Control_backslash Meta_four Meta_dollar Meta_four Meta_four Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+0034 U+0024 U+0034 U+0034 Control_backslash Control_backslash Control_backslash Control_backslash Meta_four Meta_dollar Meta_four Meta_four Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+0034 U+0024 U+0034 U+0034 Control_backslash Control_backslash Control_backslash Control_backslash Meta_four Meta_dollar Meta_four Meta_four Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+0034 U+0024 U+0034 U+0034 Control_backslash Control_backslash Control_backslash Control_backslash Meta_four Meta_dollar Meta_four Meta_four Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+0034 U+0024 U+0034 U+0034 Control_backslash Control_backslash Control_backslash Control_backslash Meta_four Meta_dollar Meta_four Meta_four Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash
+keycode 6 = U+0035 U+0025 U+0035 U+0035 Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_five Meta_percent Meta_five Meta_five Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright U+0035 U+0025 U+0035 U+0035 Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_five Meta_percent Meta_five Meta_five Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright U+0035 U+0025 U+0035 U+0035 Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_five Meta_percent Meta_five Meta_five Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright U+0035 U+0025 U+0035 U+0035 Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_five Meta_percent Meta_five Meta_five Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright U+0035 U+0025 U+0035 U+0035 Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_five Meta_percent Meta_five Meta_five Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright U+0035 U+0025 U+0035 U+0035 Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_five Meta_percent Meta_five Meta_five Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright U+0035 U+0025 U+0035 U+0035 Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_five Meta_percent Meta_five Meta_five Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright U+0035 U+0025 U+0035 U+0035 Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_five Meta_percent Meta_five Meta_five Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright
+keycode 7 = U+0036 U+005e U+0036 U+0036 Control_asciicircum Control_asciicircum Control_asciicircum Control_asciicircum Meta_six Meta_asciicircum Meta_six Meta_six Meta_Control_asciicircum Meta_Control_asciicircum Meta_Control_asciicircum Meta_Control_asciicircum U+0036 U+005e U+0036 U+0036 Control_asciicircum Control_asciicircum Control_asciicircum Control_asciicircum Meta_six Meta_asciicircum Meta_six Meta_six Meta_Control_asciicircum Meta_Control_asciicircum Meta_Control_asciicircum Meta_Control_asciicircum U+0036 U+005e U+0036 U+0036 Control_asciicircum Control_asciicircum Control_asciicircum Control_asciicircum Meta_six Meta_asciicircum Meta_six Meta_six Meta_Control_asciicircum Meta_Control_asciicircum Meta_Control_asciicircum Meta_Control_asciicircum U+0036 U+005e U+0036 U+0036 Control_asciicircum Control_asciicircum Control_asciicircum Control_asciicircum Meta_six Meta_asciicircum Meta_six Meta_six Meta_Control_asciicircum Meta_Control_asciicircum Meta_Control_asciicircum Meta_Control_asciicircum U+0036 U+005e U+0036 U+0036 Control_asciicircum Control_asciicircum Control_asciicircum Control_asciicircum Meta_six Meta_asciicircum Meta_six Meta_six Meta_Control_asciicircum Meta_Control_asciicircum Meta_Control_asciicircum Meta_Control_asciicircum U+0036 U+005e U+0036 U+0036 Control_asciicircum Control_asciicircum Control_asciicircum Control_asciicircum Meta_six Meta_asciicircum Meta_six Meta_six Meta_Control_asciicircum Meta_Control_asciicircum Meta_Control_asciicircum Meta_Control_asciicircum U+0036 U+005e U+0036 U+0036 Control_asciicircum Control_asciicircum Control_asciicircum Control_asciicircum Meta_six Meta_asciicircum Meta_six Meta_six Meta_Control_asciicircum Meta_Control_asciicircum Meta_Control_asciicircum Meta_Control_asciicircum U+0036 U+005e U+0036 U+0036 Control_asciicircum Control_asciicircum Control_asciicircum Control_asciicircum Meta_six Meta_asciicircum Meta_six Meta_six Meta_Control_asciicircum Meta_Control_asciicircum Meta_Control_asciicircum Meta_Control_asciicircum
+keycode 8 = U+0037 U+0026 U+0037 U+0037 Control_underscore Control_underscore Control_underscore Control_underscore Meta_seven Meta_ampersand Meta_seven Meta_seven Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+0037 U+0026 U+0037 U+0037 Control_underscore Control_underscore Control_underscore Control_underscore Meta_seven Meta_ampersand Meta_seven Meta_seven Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+0037 U+0026 U+0037 U+0037 Control_underscore Control_underscore Control_underscore Control_underscore Meta_seven Meta_ampersand Meta_seven Meta_seven Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+0037 U+0026 U+0037 U+0037 Control_underscore Control_underscore Control_underscore Control_underscore Meta_seven Meta_ampersand Meta_seven Meta_seven Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+0037 U+0026 U+0037 U+0037 Control_underscore Control_underscore Control_underscore Control_underscore Meta_seven Meta_ampersand Meta_seven Meta_seven Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+0037 U+0026 U+0037 U+0037 Control_underscore Control_underscore Control_underscore Control_underscore Meta_seven Meta_ampersand Meta_seven Meta_seven Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+0037 U+0026 U+0037 U+0037 Control_underscore Control_underscore Control_underscore Control_underscore Meta_seven Meta_ampersand Meta_seven Meta_seven Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+0037 U+0026 U+0037 U+0037 Control_underscore Control_underscore Control_underscore Control_underscore Meta_seven Meta_ampersand Meta_seven Meta_seven Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore
+keycode 9 = U+0038 U+002a U+0038 U+0038 Delete Delete Delete Delete Meta_eight Meta_asterisk Meta_eight Meta_eight Meta_Delete Meta_Delete Meta_Delete Meta_Delete U+0038 U+002a U+0038 U+0038 Delete Delete Delete Delete Meta_eight Meta_asterisk Meta_eight Meta_eight Meta_Delete Meta_Delete Meta_Delete Meta_Delete U+0038 U+002a U+0038 U+0038 Delete Delete Delete Delete Meta_eight Meta_asterisk Meta_eight Meta_eight Meta_Delete Meta_Delete Meta_Delete Meta_Delete U+0038 U+002a U+0038 U+0038 Delete Delete Delete Delete Meta_eight Meta_asterisk Meta_eight Meta_eight Meta_Delete Meta_Delete Meta_Delete Meta_Delete U+0038 U+002a U+0038 U+0038 Delete Delete Delete Delete Meta_eight Meta_asterisk Meta_eight Meta_eight Meta_Delete Meta_Delete Meta_Delete Meta_Delete U+0038 U+002a U+0038 U+0038 Delete Delete Delete Delete Meta_eight Meta_asterisk Meta_eight Meta_eight Meta_Delete Meta_Delete Meta_Delete Meta_Delete U+0038 U+002a U+0038 U+0038 Delete Delete Delete Delete Meta_eight Meta_asterisk Meta_eight Meta_eight Meta_Delete Meta_Delete Meta_Delete Meta_Delete U+0038 U+002a U+0038 U+0038 Delete Delete Delete Delete Meta_eight Meta_asterisk Meta_eight Meta_eight Meta_Delete Meta_Delete Meta_Delete Meta_Delete
+keycode 10 = U+0039 U+0028 U+0039 U+0039 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_nine Meta_parenleft Meta_nine Meta_nine VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0039 U+0028 U+0039 U+0039 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_nine Meta_parenleft Meta_nine Meta_nine VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0039 U+0028 U+0039 U+0039 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_nine Meta_parenleft Meta_nine Meta_nine VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0039 U+0028 U+0039 U+0039 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_nine Meta_parenleft Meta_nine Meta_nine VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0039 U+0028 U+0039 U+0039 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_nine Meta_parenleft Meta_nine Meta_nine VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0039 U+0028 U+0039 U+0039 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_nine Meta_parenleft Meta_nine Meta_nine VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0039 U+0028 U+0039 U+0039 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_nine Meta_parenleft Meta_nine Meta_nine VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0039 U+0028 U+0039 U+0039 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_nine Meta_parenleft Meta_nine Meta_nine VoidSymbol VoidSymbol VoidSymbol VoidSymbol
+keycode 11 = U+0030 U+0029 U+0030 U+0030 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_zero Meta_parenright Meta_zero Meta_zero VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0030 U+0029 U+0030 U+0030 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_zero Meta_parenright Meta_zero Meta_zero VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0030 U+0029 U+0030 U+0030 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_zero Meta_parenright Meta_zero Meta_zero VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0030 U+0029 U+0030 U+0030 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_zero Meta_parenright Meta_zero Meta_zero VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0030 U+0029 U+0030 U+0030 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_zero Meta_parenright Meta_zero Meta_zero VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0030 U+0029 U+0030 U+0030 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_zero Meta_parenright Meta_zero Meta_zero VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0030 U+0029 U+0030 U+0030 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_zero Meta_parenright Meta_zero Meta_zero VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+0030 U+0029 U+0030 U+0030 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_zero Meta_parenright Meta_zero Meta_zero VoidSymbol VoidSymbol VoidSymbol VoidSymbol
+keycode 12 = U+002d U+005f U+002d U+002d Control_underscore Control_underscore Control_underscore Control_underscore Meta_minus Meta_underscore Meta_minus Meta_minus Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+002d U+005f U+002d U+002d Control_underscore Control_underscore Control_underscore Control_underscore Meta_minus Meta_underscore Meta_minus Meta_minus Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+002d U+005f U+002d U+002d Control_underscore Control_underscore Control_underscore Control_underscore Meta_minus Meta_underscore Meta_minus Meta_minus Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+002d U+005f U+002d U+002d Control_underscore Control_underscore Control_underscore Control_underscore Meta_minus Meta_underscore Meta_minus Meta_minus Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+002d U+005f U+002d U+002d Control_underscore Control_underscore Control_underscore Control_underscore Meta_minus Meta_underscore Meta_minus Meta_minus Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+002d U+005f U+002d U+002d Control_underscore Control_underscore Control_underscore Control_underscore Meta_minus Meta_underscore Meta_minus Meta_minus Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+002d U+005f U+002d U+002d Control_underscore Control_underscore Control_underscore Control_underscore Meta_minus Meta_underscore Meta_minus Meta_minus Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore U+002d U+005f U+002d U+002d Control_underscore Control_underscore Control_underscore Control_underscore Meta_minus Meta_underscore Meta_minus Meta_minus Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore Meta_Control_underscore
+keycode 13 = U+003d U+002b U+003d U+003d VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_equal Meta_plus Meta_equal Meta_equal VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+003d U+002b U+003d U+003d VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_equal Meta_plus Meta_equal Meta_equal VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+003d U+002b U+003d U+003d VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_equal Meta_plus Meta_equal Meta_equal VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+003d U+002b U+003d U+003d VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_equal Meta_plus Meta_equal Meta_equal VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+003d U+002b U+003d U+003d VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_equal Meta_plus Meta_equal Meta_equal VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+003d U+002b U+003d U+003d VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_equal Meta_plus Meta_equal Meta_equal VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+003d U+002b U+003d U+003d VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_equal Meta_plus Meta_equal Meta_equal VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+003d U+002b U+003d U+003d VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_equal Meta_plus Meta_equal Meta_equal VoidSymbol VoidSymbol VoidSymbol VoidSymbol
+keycode 14 = Delete Delete Delete Delete BackSpace BackSpace BackSpace BackSpace Meta_Delete Meta_Delete Meta_Delete Meta_Delete Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace Delete Delete Delete Delete BackSpace BackSpace BackSpace BackSpace Meta_Delete Meta_Delete Meta_Delete Meta_Delete Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace Delete Delete Delete Delete BackSpace BackSpace BackSpace BackSpace Meta_Delete Meta_Delete Meta_Delete Meta_Delete Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace Delete Delete Delete Delete BackSpace BackSpace BackSpace BackSpace Meta_Delete Meta_Delete Meta_Delete Meta_Delete Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace Delete Delete Delete Delete BackSpace BackSpace BackSpace BackSpace Meta_Delete Meta_Delete Meta_Delete Meta_Delete Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace Delete Delete Delete Delete BackSpace BackSpace BackSpace BackSpace Meta_Delete Meta_Delete Meta_Delete Meta_Delete Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace Delete Delete Delete Delete BackSpace BackSpace BackSpace BackSpace Meta_Delete Meta_Delete Meta_Delete Meta_Delete Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace Delete Delete Delete Delete BackSpace BackSpace BackSpace BackSpace Meta_Delete Meta_Delete Meta_Delete Meta_Delete Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace
+keycode 15 = Tab Tab Tab Tab Tab Tab Tab Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Tab Tab Tab Tab Tab Tab Tab Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Tab Tab Tab Tab Tab Tab Tab Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Tab Tab Tab Tab Tab Tab Tab Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Tab Tab Tab Tab Tab Tab Tab Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Tab Tab Tab Tab Tab Tab Tab Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Tab Tab Tab Tab Tab Tab Tab Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Tab Tab Tab Tab Tab Tab Tab Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab Meta_Tab
+keycode 16 = +U+0071 +U+0051 +U+0071 +U+0071 Control_q Control_q Control_q Control_q Meta_q Meta_Q Meta_q Meta_q Meta_Control_q Meta_Control_q Meta_Control_q Meta_Control_q +U+0071 +U+0051 +U+0071 +U+0071 Control_q Control_q Control_q Control_q Meta_q Meta_Q Meta_q Meta_q Meta_Control_q Meta_Control_q Meta_Control_q Meta_Control_q +U+0071 +U+0051 +U+0071 +U+0071 Control_q Control_q Control_q Control_q Meta_q Meta_Q Meta_q Meta_q Meta_Control_q Meta_Control_q Meta_Control_q Meta_Control_q +U+0071 +U+0051 +U+0071 +U+0071 Control_q Control_q Control_q Control_q Meta_q Meta_Q Meta_q Meta_q Meta_Control_q Meta_Control_q Meta_Control_q Meta_Control_q +U+0051 +U+0071 +U+0051 +U+0051 Control_q Control_q Control_q Control_q Meta_q Meta_Q Meta_q Meta_q Meta_Control_q Meta_Control_q Meta_Control_q Meta_Control_q +U+0051 +U+0071 +U+0051 +U+0051 Control_q Control_q Control_q Control_q Meta_q Meta_Q Meta_q Meta_q Meta_Control_q Meta_Control_q Meta_Control_q Meta_Control_q +U+0051 +U+0071 +U+0051 +U+0051 Control_q Control_q Control_q Control_q Meta_q Meta_Q Meta_q Meta_q Meta_Control_q Meta_Control_q Meta_Control_q Meta_Control_q +U+0051 +U+0071 +U+0051 +U+0051 Control_q Control_q Control_q Control_q Meta_q Meta_Q Meta_q Meta_q Meta_Control_q Meta_Control_q Meta_Control_q Meta_Control_q
+keycode 17 = +U+0077 +U+0057 +U+0077 +U+0077 Control_w Control_w Control_w Control_w Meta_w Meta_W Meta_w Meta_w Meta_Control_w Meta_Control_w Meta_Control_w Meta_Control_w +U+0077 +U+0057 +U+0077 +U+0077 Control_w Control_w Control_w Control_w Meta_w Meta_W Meta_w Meta_w Meta_Control_w Meta_Control_w Meta_Control_w Meta_Control_w +U+0077 +U+0057 +U+0077 +U+0077 Control_w Control_w Control_w Control_w Meta_w Meta_W Meta_w Meta_w Meta_Control_w Meta_Control_w Meta_Control_w Meta_Control_w +U+0077 +U+0057 +U+0077 +U+0077 Control_w Control_w Control_w Control_w Meta_w Meta_W Meta_w Meta_w Meta_Control_w Meta_Control_w Meta_Control_w Meta_Control_w +U+0057 +U+0077 +U+0057 +U+0057 Control_w Control_w Control_w Control_w Meta_w Meta_W Meta_w Meta_w Meta_Control_w Meta_Control_w Meta_Control_w Meta_Control_w +U+0057 +U+0077 +U+0057 +U+0057 Control_w Control_w Control_w Control_w Meta_w Meta_W Meta_w Meta_w Meta_Control_w Meta_Control_w Meta_Control_w Meta_Control_w +U+0057 +U+0077 +U+0057 +U+0057 Control_w Control_w Control_w Control_w Meta_w Meta_W Meta_w Meta_w Meta_Control_w Meta_Control_w Meta_Control_w Meta_Control_w +U+0057 +U+0077 +U+0057 +U+0057 Control_w Control_w Control_w Control_w Meta_w Meta_W Meta_w Meta_w Meta_Control_w Meta_Control_w Meta_Control_w Meta_Control_w
+keycode 18 = +U+0065 +U+0045 +U+0065 +U+0065 Control_e Control_e Control_e Control_e Meta_e Meta_E Meta_e Meta_e Meta_Control_e Meta_Control_e Meta_Control_e Meta_Control_e +U+0065 +U+0045 +U+0065 +U+0065 Control_e Control_e Control_e Control_e Meta_e Meta_E Meta_e Meta_e Meta_Control_e Meta_Control_e Meta_Control_e Meta_Control_e +U+0065 +U+0045 +U+0065 +U+0065 Control_e Control_e Control_e Control_e Meta_e Meta_E Meta_e Meta_e Meta_Control_e Meta_Control_e Meta_Control_e Meta_Control_e +U+0065 +U+0045 +U+0065 +U+0065 Control_e Control_e Control_e Control_e Meta_e Meta_E Meta_e Meta_e Meta_Control_e Meta_Control_e Meta_Control_e Meta_Control_e +U+0045 +U+0065 +U+0045 +U+0045 Control_e Control_e Control_e Control_e Meta_e Meta_E Meta_e Meta_e Meta_Control_e Meta_Control_e Meta_Control_e Meta_Control_e +U+0045 +U+0065 +U+0045 +U+0045 Control_e Control_e Control_e Control_e Meta_e Meta_E Meta_e Meta_e Meta_Control_e Meta_Control_e Meta_Control_e Meta_Control_e +U+0045 +U+0065 +U+0045 +U+0045 Control_e Control_e Control_e Control_e Meta_e Meta_E Meta_e Meta_e Meta_Control_e Meta_Control_e Meta_Control_e Meta_Control_e +U+0045 +U+0065 +U+0045 +U+0045 Control_e Control_e Control_e Control_e Meta_e Meta_E Meta_e Meta_e Meta_Control_e Meta_Control_e Meta_Control_e Meta_Control_e
+keycode 19 = +U+0072 +U+0052 +U+0072 +U+0072 Control_r Control_r Control_r Control_r Meta_r Meta_R Meta_r Meta_r Meta_Control_r Meta_Control_r Meta_Control_r Meta_Control_r +U+0072 +U+0052 +U+0072 +U+0072 Control_r Control_r Control_r Control_r Meta_r Meta_R Meta_r Meta_r Meta_Control_r Meta_Control_r Meta_Control_r Meta_Control_r +U+0072 +U+0052 +U+0072 +U+0072 Control_r Control_r Control_r Control_r Meta_r Meta_R Meta_r Meta_r Meta_Control_r Meta_Control_r Meta_Control_r Meta_Control_r +U+0072 +U+0052 +U+0072 +U+0072 Control_r Control_r Control_r Control_r Meta_r Meta_R Meta_r Meta_r Meta_Control_r Meta_Control_r Meta_Control_r Meta_Control_r +U+0052 +U+0072 +U+0052 +U+0052 Control_r Control_r Control_r Control_r Meta_r Meta_R Meta_r Meta_r Meta_Control_r Meta_Control_r Meta_Control_r Meta_Control_r +U+0052 +U+0072 +U+0052 +U+0052 Control_r Control_r Control_r Control_r Meta_r Meta_R Meta_r Meta_r Meta_Control_r Meta_Control_r Meta_Control_r Meta_Control_r +U+0052 +U+0072 +U+0052 +U+0052 Control_r Control_r Control_r Control_r Meta_r Meta_R Meta_r Meta_r Meta_Control_r Meta_Control_r Meta_Control_r Meta_Control_r +U+0052 +U+0072 +U+0052 +U+0052 Control_r Control_r Control_r Control_r Meta_r Meta_R Meta_r Meta_r Meta_Control_r Meta_Control_r Meta_Control_r Meta_Control_r
+keycode 20 = +U+0074 +U+0054 +U+0074 +U+0074 Control_t Control_t Control_t Control_t Meta_t Meta_T Meta_t Meta_t Meta_Control_t Meta_Control_t Meta_Control_t Meta_Control_t +U+0074 +U+0054 +U+0074 +U+0074 Control_t Control_t Control_t Control_t Meta_t Meta_T Meta_t Meta_t Meta_Control_t Meta_Control_t Meta_Control_t Meta_Control_t +U+0074 +U+0054 +U+0074 +U+0074 Control_t Control_t Control_t Control_t Meta_t Meta_T Meta_t Meta_t Meta_Control_t Meta_Control_t Meta_Control_t Meta_Control_t +U+0074 +U+0054 +U+0074 +U+0074 Control_t Control_t Control_t Control_t Meta_t Meta_T Meta_t Meta_t Meta_Control_t Meta_Control_t Meta_Control_t Meta_Control_t +U+0054 +U+0074 +U+0054 +U+0054 Control_t Control_t Control_t Control_t Meta_t Meta_T Meta_t Meta_t Meta_Control_t Meta_Control_t Meta_Control_t Meta_Control_t +U+0054 +U+0074 +U+0054 +U+0054 Control_t Control_t Control_t Control_t Meta_t Meta_T Meta_t Meta_t Meta_Control_t Meta_Control_t Meta_Control_t Meta_Control_t +U+0054 +U+0074 +U+0054 +U+0054 Control_t Control_t Control_t Control_t Meta_t Meta_T Meta_t Meta_t Meta_Control_t Meta_Control_t Meta_Control_t Meta_Control_t +U+0054 +U+0074 +U+0054 +U+0054 Control_t Control_t Control_t Control_t Meta_t Meta_T Meta_t Meta_t Meta_Control_t Meta_Control_t Meta_Control_t Meta_Control_t
+keycode 21 = +U+0079 +U+0059 +U+0079 +U+0079 Control_y Control_y Control_y Control_y Meta_y Meta_Y Meta_y Meta_y Meta_Control_y Meta_Control_y Meta_Control_y Meta_Control_y +U+0079 +U+0059 +U+0079 +U+0079 Control_y Control_y Control_y Control_y Meta_y Meta_Y Meta_y Meta_y Meta_Control_y Meta_Control_y Meta_Control_y Meta_Control_y +U+0079 +U+0059 +U+0079 +U+0079 Control_y Control_y Control_y Control_y Meta_y Meta_Y Meta_y Meta_y Meta_Control_y Meta_Control_y Meta_Control_y Meta_Control_y +U+0079 +U+0059 +U+0079 +U+0079 Control_y Control_y Control_y Control_y Meta_y Meta_Y Meta_y Meta_y Meta_Control_y Meta_Control_y Meta_Control_y Meta_Control_y +U+0059 +U+0079 +U+0059 +U+0059 Control_y Control_y Control_y Control_y Meta_y Meta_Y Meta_y Meta_y Meta_Control_y Meta_Control_y Meta_Control_y Meta_Control_y +U+0059 +U+0079 +U+0059 +U+0059 Control_y Control_y Control_y Control_y Meta_y Meta_Y Meta_y Meta_y Meta_Control_y Meta_Control_y Meta_Control_y Meta_Control_y +U+0059 +U+0079 +U+0059 +U+0059 Control_y Control_y Control_y Control_y Meta_y Meta_Y Meta_y Meta_y Meta_Control_y Meta_Control_y Meta_Control_y Meta_Control_y +U+0059 +U+0079 +U+0059 +U+0059 Control_y Control_y Control_y Control_y Meta_y Meta_Y Meta_y Meta_y Meta_Control_y Meta_Control_y Meta_Control_y Meta_Control_y
+keycode 22 = +U+0075 +U+0055 +U+0075 +U+0075 Control_u Control_u Control_u Control_u Meta_u Meta_U Meta_u Meta_u Meta_Control_u Meta_Control_u Meta_Control_u Meta_Control_u +U+0075 +U+0055 +U+0075 +U+0075 Control_u Control_u Control_u Control_u Meta_u Meta_U Meta_u Meta_u Meta_Control_u Meta_Control_u Meta_Control_u Meta_Control_u +U+0075 +U+0055 +U+0075 +U+0075 Control_u Control_u Control_u Control_u Meta_u Meta_U Meta_u Meta_u Meta_Control_u Meta_Control_u Meta_Control_u Meta_Control_u +U+0075 +U+0055 +U+0075 +U+0075 Control_u Control_u Control_u Control_u Meta_u Meta_U Meta_u Meta_u Meta_Control_u Meta_Control_u Meta_Control_u Meta_Control_u +U+0055 +U+0075 +U+0055 +U+0055 Control_u Control_u Control_u Control_u Meta_u Meta_U Meta_u Meta_u Meta_Control_u Meta_Control_u Meta_Control_u Meta_Control_u +U+0055 +U+0075 +U+0055 +U+0055 Control_u Control_u Control_u Control_u Meta_u Meta_U Meta_u Meta_u Meta_Control_u Meta_Control_u Meta_Control_u Meta_Control_u +U+0055 +U+0075 +U+0055 +U+0055 Control_u Control_u Control_u Control_u Meta_u Meta_U Meta_u Meta_u Meta_Control_u Meta_Control_u Meta_Control_u Meta_Control_u +U+0055 +U+0075 +U+0055 +U+0055 Control_u Control_u Control_u Control_u Meta_u Meta_U Meta_u Meta_u Meta_Control_u Meta_Control_u Meta_Control_u Meta_Control_u
+keycode 23 = +U+0069 +U+0049 +U+0069 +U+0069 Tab Tab Tab Tab Meta_i Meta_I Meta_i Meta_i Meta_Tab Meta_Tab Meta_Tab Meta_Tab +U+0069 +U+0049 +U+0069 +U+0069 Tab Tab Tab Tab Meta_i Meta_I Meta_i Meta_i Meta_Tab Meta_Tab Meta_Tab Meta_Tab +U+0069 +U+0049 +U+0069 +U+0069 Tab Tab Tab Tab Meta_i Meta_I Meta_i Meta_i Meta_Tab Meta_Tab Meta_Tab Meta_Tab +U+0069 +U+0049 +U+0069 +U+0069 Tab Tab Tab Tab Meta_i Meta_I Meta_i Meta_i Meta_Tab Meta_Tab Meta_Tab Meta_Tab +U+0049 +U+0069 +U+0049 +U+0049 Tab Tab Tab Tab Meta_i Meta_I Meta_i Meta_i Meta_Tab Meta_Tab Meta_Tab Meta_Tab +U+0049 +U+0069 +U+0049 +U+0049 Tab Tab Tab Tab Meta_i Meta_I Meta_i Meta_i Meta_Tab Meta_Tab Meta_Tab Meta_Tab +U+0049 +U+0069 +U+0049 +U+0049 Tab Tab Tab Tab Meta_i Meta_I Meta_i Meta_i Meta_Tab Meta_Tab Meta_Tab Meta_Tab +U+0049 +U+0069 +U+0049 +U+0049 Tab Tab Tab Tab Meta_i Meta_I Meta_i Meta_i Meta_Tab Meta_Tab Meta_Tab Meta_Tab
+keycode 24 = +U+006f +U+004f +U+006f +U+006f Control_o Control_o Control_o Control_o Meta_o Meta_O Meta_o Meta_o Meta_Control_o Meta_Control_o Meta_Control_o Meta_Control_o +U+006f +U+004f +U+006f +U+006f Control_o Control_o Control_o Control_o Meta_o Meta_O Meta_o Meta_o Meta_Control_o Meta_Control_o Meta_Control_o Meta_Control_o +U+006f +U+004f +U+006f +U+006f Control_o Control_o Control_o Control_o Meta_o Meta_O Meta_o Meta_o Meta_Control_o Meta_Control_o Meta_Control_o Meta_Control_o +U+006f +U+004f +U+006f +U+006f Control_o Control_o Control_o Control_o Meta_o Meta_O Meta_o Meta_o Meta_Control_o Meta_Control_o Meta_Control_o Meta_Control_o +U+004f +U+006f +U+004f +U+004f Control_o Control_o Control_o Control_o Meta_o Meta_O Meta_o Meta_o Meta_Control_o Meta_Control_o Meta_Control_o Meta_Control_o +U+004f +U+006f +U+004f +U+004f Control_o Control_o Control_o Control_o Meta_o Meta_O Meta_o Meta_o Meta_Control_o Meta_Control_o Meta_Control_o Meta_Control_o +U+004f +U+006f +U+004f +U+004f Control_o Control_o Control_o Control_o Meta_o Meta_O Meta_o Meta_o Meta_Control_o Meta_Control_o Meta_Control_o Meta_Control_o +U+004f +U+006f +U+004f +U+004f Control_o Control_o Control_o Control_o Meta_o Meta_O Meta_o Meta_o Meta_Control_o Meta_Control_o Meta_Control_o Meta_Control_o
+keycode 25 = +U+0070 +U+0050 +U+0070 +U+0070 Control_p Control_p Control_p Control_p Meta_p Meta_P Meta_p Meta_p Meta_Control_p Meta_Control_p Meta_Control_p Meta_Control_p +U+0070 +U+0050 +U+0070 +U+0070 Control_p Control_p Control_p Control_p Meta_p Meta_P Meta_p Meta_p Meta_Control_p Meta_Control_p Meta_Control_p Meta_Control_p +U+0070 +U+0050 +U+0070 +U+0070 Control_p Control_p Control_p Control_p Meta_p Meta_P Meta_p Meta_p Meta_Control_p Meta_Control_p Meta_Control_p Meta_Control_p +U+0070 +U+0050 +U+0070 +U+0070 Control_p Control_p Control_p Control_p Meta_p Meta_P Meta_p Meta_p Meta_Control_p Meta_Control_p Meta_Control_p Meta_Control_p +U+0050 +U+0070 +U+0050 +U+0050 Control_p Control_p Control_p Control_p Meta_p Meta_P Meta_p Meta_p Meta_Control_p Meta_Control_p Meta_Control_p Meta_Control_p +U+0050 +U+0070 +U+0050 +U+0050 Control_p Control_p Control_p Control_p Meta_p Meta_P Meta_p Meta_p Meta_Control_p Meta_Control_p Meta_Control_p Meta_Control_p +U+0050 +U+0070 +U+0050 +U+0050 Control_p Control_p Control_p Control_p Meta_p Meta_P Meta_p Meta_p Meta_Control_p Meta_Control_p Meta_Control_p Meta_Control_p +U+0050 +U+0070 +U+0050 +U+0050 Control_p Control_p Control_p Control_p Meta_p Meta_P Meta_p Meta_p Meta_Control_p Meta_Control_p Meta_Control_p Meta_Control_p
+keycode 26 = U+005b U+007b U+005b U+005b Escape Escape Escape Escape Meta_bracketleft Meta_braceleft Meta_bracketleft Meta_bracketleft Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+005b U+007b U+005b U+005b Escape Escape Escape Escape Meta_bracketleft Meta_braceleft Meta_bracketleft Meta_bracketleft Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+005b U+007b U+005b U+005b Escape Escape Escape Escape Meta_bracketleft Meta_braceleft Meta_bracketleft Meta_bracketleft Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+005b U+007b U+005b U+005b Escape Escape Escape Escape Meta_bracketleft Meta_braceleft Meta_bracketleft Meta_bracketleft Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+005b U+007b U+005b U+005b Escape Escape Escape Escape Meta_bracketleft Meta_braceleft Meta_bracketleft Meta_bracketleft Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+005b U+007b U+005b U+005b Escape Escape Escape Escape Meta_bracketleft Meta_braceleft Meta_bracketleft Meta_bracketleft Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+005b U+007b U+005b U+005b Escape Escape Escape Escape Meta_bracketleft Meta_braceleft Meta_bracketleft Meta_bracketleft Meta_Escape Meta_Escape Meta_Escape Meta_Escape U+005b U+007b U+005b U+005b Escape Escape Escape Escape Meta_bracketleft Meta_braceleft Meta_bracketleft Meta_bracketleft Meta_Escape Meta_Escape Meta_Escape Meta_Escape
+keycode 27 = U+005d U+007d U+005d U+005d Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_bracketright Meta_braceright Meta_bracketright Meta_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright U+005d U+007d U+005d U+005d Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_bracketright Meta_braceright Meta_bracketright Meta_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright U+005d U+007d U+005d U+005d Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_bracketright Meta_braceright Meta_bracketright Meta_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright U+005d U+007d U+005d U+005d Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_bracketright Meta_braceright Meta_bracketright Meta_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright U+005d U+007d U+005d U+005d Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_bracketright Meta_braceright Meta_bracketright Meta_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright U+005d U+007d U+005d U+005d Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_bracketright Meta_braceright Meta_bracketright Meta_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright U+005d U+007d U+005d U+005d Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_bracketright Meta_braceright Meta_bracketright Meta_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright U+005d U+007d U+005d U+005d Control_bracketright Control_bracketright Control_bracketright Control_bracketright Meta_bracketright Meta_braceright Meta_bracketright Meta_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright Meta_Control_bracketright
+keycode 28 = Return Return Return Return Control_m Control_m Control_m Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Return Return Return Return Control_m Control_m Control_m Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Return Return Return Return Control_m Control_m Control_m Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Return Return Return Return Control_m Control_m Control_m Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Return Return Return Return Control_m Control_m Control_m Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Return Return Return Return Control_m Control_m Control_m Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Return Return Return Return Control_m Control_m Control_m Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Return Return Return Return Control_m Control_m Control_m Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m
+keycode 29 = Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control
+keycode 30 = +U+0061 +U+0041 +U+0061 +U+0061 Control_a Control_a Control_a Control_a Meta_a Meta_A Meta_a Meta_a Meta_Control_a Meta_Control_a Meta_Control_a Meta_Control_a +U+0061 +U+0041 +U+0061 +U+0061 Control_a Control_a Control_a Control_a Meta_a Meta_A Meta_a Meta_a Meta_Control_a Meta_Control_a Meta_Control_a Meta_Control_a +U+0061 +U+0041 +U+0061 +U+0061 Control_a Control_a Control_a Control_a Meta_a Meta_A Meta_a Meta_a Meta_Control_a Meta_Control_a Meta_Control_a Meta_Control_a +U+0061 +U+0041 +U+0061 +U+0061 Control_a Control_a Control_a Control_a Meta_a Meta_A Meta_a Meta_a Meta_Control_a Meta_Control_a Meta_Control_a Meta_Control_a +U+0041 +U+0061 +U+0041 +U+0041 Control_a Control_a Control_a Control_a Meta_a Meta_A Meta_a Meta_a Meta_Control_a Meta_Control_a Meta_Control_a Meta_Control_a +U+0041 +U+0061 +U+0041 +U+0041 Control_a Control_a Control_a Control_a Meta_a Meta_A Meta_a Meta_a Meta_Control_a Meta_Control_a Meta_Control_a Meta_Control_a +U+0041 +U+0061 +U+0041 +U+0041 Control_a Control_a Control_a Control_a Meta_a Meta_A Meta_a Meta_a Meta_Control_a Meta_Control_a Meta_Control_a Meta_Control_a +U+0041 +U+0061 +U+0041 +U+0041 Control_a Control_a Control_a Control_a Meta_a Meta_A Meta_a Meta_a Meta_Control_a Meta_Control_a Meta_Control_a Meta_Control_a
+keycode 31 = +U+0073 +U+0053 +U+0073 +U+0073 Control_s Control_s Control_s Control_s Meta_s Meta_S Meta_s Meta_s Meta_Control_s Meta_Control_s Meta_Control_s Meta_Control_s +U+0073 +U+0053 +U+0073 +U+0073 Control_s Control_s Control_s Control_s Meta_s Meta_S Meta_s Meta_s Meta_Control_s Meta_Control_s Meta_Control_s Meta_Control_s +U+0073 +U+0053 +U+0073 +U+0073 Control_s Control_s Control_s Control_s Meta_s Meta_S Meta_s Meta_s Meta_Control_s Meta_Control_s Meta_Control_s Meta_Control_s +U+0073 +U+0053 +U+0073 +U+0073 Control_s Control_s Control_s Control_s Meta_s Meta_S Meta_s Meta_s Meta_Control_s Meta_Control_s Meta_Control_s Meta_Control_s +U+0053 +U+0073 +U+0053 +U+0053 Control_s Control_s Control_s Control_s Meta_s Meta_S Meta_s Meta_s Meta_Control_s Meta_Control_s Meta_Control_s Meta_Control_s +U+0053 +U+0073 +U+0053 +U+0053 Control_s Control_s Control_s Control_s Meta_s Meta_S Meta_s Meta_s Meta_Control_s Meta_Control_s Meta_Control_s Meta_Control_s +U+0053 +U+0073 +U+0053 +U+0053 Control_s Control_s Control_s Control_s Meta_s Meta_S Meta_s Meta_s Meta_Control_s Meta_Control_s Meta_Control_s Meta_Control_s +U+0053 +U+0073 +U+0053 +U+0053 Control_s Control_s Control_s Control_s Meta_s Meta_S Meta_s Meta_s Meta_Control_s Meta_Control_s Meta_Control_s Meta_Control_s
+keycode 32 = +U+0064 +U+0044 +U+0064 +U+0064 Control_d Control_d Control_d Control_d Meta_d Meta_D Meta_d Meta_d Meta_Control_d Meta_Control_d Meta_Control_d Meta_Control_d +U+0064 +U+0044 +U+0064 +U+0064 Control_d Control_d Control_d Control_d Meta_d Meta_D Meta_d Meta_d Meta_Control_d Meta_Control_d Meta_Control_d Meta_Control_d +U+0064 +U+0044 +U+0064 +U+0064 Control_d Control_d Control_d Control_d Meta_d Meta_D Meta_d Meta_d Meta_Control_d Meta_Control_d Meta_Control_d Meta_Control_d +U+0064 +U+0044 +U+0064 +U+0064 Control_d Control_d Control_d Control_d Meta_d Meta_D Meta_d Meta_d Meta_Control_d Meta_Control_d Meta_Control_d Meta_Control_d +U+0044 +U+0064 +U+0044 +U+0044 Control_d Control_d Control_d Control_d Meta_d Meta_D Meta_d Meta_d Meta_Control_d Meta_Control_d Meta_Control_d Meta_Control_d +U+0044 +U+0064 +U+0044 +U+0044 Control_d Control_d Control_d Control_d Meta_d Meta_D Meta_d Meta_d Meta_Control_d Meta_Control_d Meta_Control_d Meta_Control_d +U+0044 +U+0064 +U+0044 +U+0044 Control_d Control_d Control_d Control_d Meta_d Meta_D Meta_d Meta_d Meta_Control_d Meta_Control_d Meta_Control_d Meta_Control_d +U+0044 +U+0064 +U+0044 +U+0044 Control_d Control_d Control_d Control_d Meta_d Meta_D Meta_d Meta_d Meta_Control_d Meta_Control_d Meta_Control_d Meta_Control_d
+keycode 33 = +U+0066 +U+0046 +U+0066 +U+0066 Control_f Control_f Control_f Control_f Meta_f Meta_F Meta_f Meta_f Meta_Control_f Meta_Control_f Meta_Control_f Meta_Control_f +U+0066 +U+0046 +U+0066 +U+0066 Control_f Control_f Control_f Control_f Meta_f Meta_F Meta_f Meta_f Meta_Control_f Meta_Control_f Meta_Control_f Meta_Control_f +U+0066 +U+0046 +U+0066 +U+0066 Control_f Control_f Control_f Control_f Meta_f Meta_F Meta_f Meta_f Meta_Control_f Meta_Control_f Meta_Control_f Meta_Control_f +U+0066 +U+0046 +U+0066 +U+0066 Control_f Control_f Control_f Control_f Meta_f Meta_F Meta_f Meta_f Meta_Control_f Meta_Control_f Meta_Control_f Meta_Control_f +U+0046 +U+0066 +U+0046 +U+0046 Control_f Control_f Control_f Control_f Meta_f Meta_F Meta_f Meta_f Meta_Control_f Meta_Control_f Meta_Control_f Meta_Control_f +U+0046 +U+0066 +U+0046 +U+0046 Control_f Control_f Control_f Control_f Meta_f Meta_F Meta_f Meta_f Meta_Control_f Meta_Control_f Meta_Control_f Meta_Control_f +U+0046 +U+0066 +U+0046 +U+0046 Control_f Control_f Control_f Control_f Meta_f Meta_F Meta_f Meta_f Meta_Control_f Meta_Control_f Meta_Control_f Meta_Control_f +U+0046 +U+0066 +U+0046 +U+0046 Control_f Control_f Control_f Control_f Meta_f Meta_F Meta_f Meta_f Meta_Control_f Meta_Control_f Meta_Control_f Meta_Control_f
+keycode 34 = +U+0067 +U+0047 +U+0067 +U+0067 Control_g Control_g Control_g Control_g Meta_g Meta_G Meta_g Meta_g Meta_Control_g Meta_Control_g Meta_Control_g Meta_Control_g +U+0067 +U+0047 +U+0067 +U+0067 Control_g Control_g Control_g Control_g Meta_g Meta_G Meta_g Meta_g Meta_Control_g Meta_Control_g Meta_Control_g Meta_Control_g +U+0067 +U+0047 +U+0067 +U+0067 Control_g Control_g Control_g Control_g Meta_g Meta_G Meta_g Meta_g Meta_Control_g Meta_Control_g Meta_Control_g Meta_Control_g +U+0067 +U+0047 +U+0067 +U+0067 Control_g Control_g Control_g Control_g Meta_g Meta_G Meta_g Meta_g Meta_Control_g Meta_Control_g Meta_Control_g Meta_Control_g +U+0047 +U+0067 +U+0047 +U+0047 Control_g Control_g Control_g Control_g Meta_g Meta_G Meta_g Meta_g Meta_Control_g Meta_Control_g Meta_Control_g Meta_Control_g +U+0047 +U+0067 +U+0047 +U+0047 Control_g Control_g Control_g Control_g Meta_g Meta_G Meta_g Meta_g Meta_Control_g Meta_Control_g Meta_Control_g Meta_Control_g +U+0047 +U+0067 +U+0047 +U+0047 Control_g Control_g Control_g Control_g Meta_g Meta_G Meta_g Meta_g Meta_Control_g Meta_Control_g Meta_Control_g Meta_Control_g +U+0047 +U+0067 +U+0047 +U+0047 Control_g Control_g Control_g Control_g Meta_g Meta_G Meta_g Meta_g Meta_Control_g Meta_Control_g Meta_Control_g Meta_Control_g
+keycode 35 = +U+0068 +U+0048 +U+0068 +U+0068 BackSpace BackSpace BackSpace BackSpace Meta_h Meta_H Meta_h Meta_h Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace +U+0068 +U+0048 +U+0068 +U+0068 BackSpace BackSpace BackSpace BackSpace Meta_h Meta_H Meta_h Meta_h Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace +U+0068 +U+0048 +U+0068 +U+0068 BackSpace BackSpace BackSpace BackSpace Meta_h Meta_H Meta_h Meta_h Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace +U+0068 +U+0048 +U+0068 +U+0068 BackSpace BackSpace BackSpace BackSpace Meta_h Meta_H Meta_h Meta_h Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace +U+0048 +U+0068 +U+0048 +U+0048 BackSpace BackSpace BackSpace BackSpace Meta_h Meta_H Meta_h Meta_h Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace +U+0048 +U+0068 +U+0048 +U+0048 BackSpace BackSpace BackSpace BackSpace Meta_h Meta_H Meta_h Meta_h Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace +U+0048 +U+0068 +U+0048 +U+0048 BackSpace BackSpace BackSpace BackSpace Meta_h Meta_H Meta_h Meta_h Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace +U+0048 +U+0068 +U+0048 +U+0048 BackSpace BackSpace BackSpace BackSpace Meta_h Meta_H Meta_h Meta_h Meta_BackSpace Meta_BackSpace Meta_BackSpace Meta_BackSpace
+keycode 36 = +U+006a +U+004a +U+006a +U+006a Linefeed Linefeed Linefeed Linefeed Meta_j Meta_J Meta_j Meta_j Meta_Linefeed Meta_Linefeed Meta_Linefeed Meta_Linefeed +U+006a +U+004a +U+006a +U+006a Linefeed Linefeed Linefeed Linefeed Meta_j Meta_J Meta_j Meta_j Meta_Linefeed Meta_Linefeed Meta_Linefeed Meta_Linefeed +U+006a +U+004a +U+006a +U+006a Linefeed Linefeed Linefeed Linefeed Meta_j Meta_J Meta_j Meta_j Meta_Linefeed Meta_Linefeed Meta_Linefeed Meta_Linefeed +U+006a +U+004a +U+006a +U+006a Linefeed Linefeed Linefeed Linefeed Meta_j Meta_J Meta_j Meta_j Meta_Linefeed Meta_Linefeed Meta_Linefeed Meta_Linefeed +U+004a +U+006a +U+004a +U+004a Linefeed Linefeed Linefeed Linefeed Meta_j Meta_J Meta_j Meta_j Meta_Linefeed Meta_Linefeed Meta_Linefeed Meta_Linefeed +U+004a +U+006a +U+004a +U+004a Linefeed Linefeed Linefeed Linefeed Meta_j Meta_J Meta_j Meta_j Meta_Linefeed Meta_Linefeed Meta_Linefeed Meta_Linefeed +U+004a +U+006a +U+004a +U+004a Linefeed Linefeed Linefeed Linefeed Meta_j Meta_J Meta_j Meta_j Meta_Linefeed Meta_Linefeed Meta_Linefeed Meta_Linefeed +U+004a +U+006a +U+004a +U+004a Linefeed Linefeed Linefeed Linefeed Meta_j Meta_J Meta_j Meta_j Meta_Linefeed Meta_Linefeed Meta_Linefeed Meta_Linefeed
+keycode 37 = +U+006b +U+004b +U+006b +U+006b Control_k Control_k Control_k Control_k Meta_k Meta_K Meta_k Meta_k Meta_Control_k Meta_Control_k Meta_Control_k Meta_Control_k +U+006b +U+004b +U+006b +U+006b Control_k Control_k Control_k Control_k Meta_k Meta_K Meta_k Meta_k Meta_Control_k Meta_Control_k Meta_Control_k Meta_Control_k +U+006b +U+004b +U+006b +U+006b Control_k Control_k Control_k Control_k Meta_k Meta_K Meta_k Meta_k Meta_Control_k Meta_Control_k Meta_Control_k Meta_Control_k +U+006b +U+004b +U+006b +U+006b Control_k Control_k Control_k Control_k Meta_k Meta_K Meta_k Meta_k Meta_Control_k Meta_Control_k Meta_Control_k Meta_Control_k +U+004b +U+006b +U+004b +U+004b Control_k Control_k Control_k Control_k Meta_k Meta_K Meta_k Meta_k Meta_Control_k Meta_Control_k Meta_Control_k Meta_Control_k +U+004b +U+006b +U+004b +U+004b Control_k Control_k Control_k Control_k Meta_k Meta_K Meta_k Meta_k Meta_Control_k Meta_Control_k Meta_Control_k Meta_Control_k +U+004b +U+006b +U+004b +U+004b Control_k Control_k Control_k Control_k Meta_k Meta_K Meta_k Meta_k Meta_Control_k Meta_Control_k Meta_Control_k Meta_Control_k +U+004b +U+006b +U+004b +U+004b Control_k Control_k Control_k Control_k Meta_k Meta_K Meta_k Meta_k Meta_Control_k Meta_Control_k Meta_Control_k Meta_Control_k
+keycode 38 = +U+006c +U+004c +U+006c +U+006c Control_l Control_l Control_l Control_l Meta_l Meta_L Meta_l Meta_l Meta_Control_l Meta_Control_l Meta_Control_l Meta_Control_l +U+006c +U+004c +U+006c +U+006c Control_l Control_l Control_l Control_l Meta_l Meta_L Meta_l Meta_l Meta_Control_l Meta_Control_l Meta_Control_l Meta_Control_l +U+006c +U+004c +U+006c +U+006c Control_l Control_l Control_l Control_l Meta_l Meta_L Meta_l Meta_l Meta_Control_l Meta_Control_l Meta_Control_l Meta_Control_l +U+006c +U+004c +U+006c +U+006c Control_l Control_l Control_l Control_l Meta_l Meta_L Meta_l Meta_l Meta_Control_l Meta_Control_l Meta_Control_l Meta_Control_l +U+004c +U+006c +U+004c +U+004c Control_l Control_l Control_l Control_l Meta_l Meta_L Meta_l Meta_l Meta_Control_l Meta_Control_l Meta_Control_l Meta_Control_l +U+004c +U+006c +U+004c +U+004c Control_l Control_l Control_l Control_l Meta_l Meta_L Meta_l Meta_l Meta_Control_l Meta_Control_l Meta_Control_l Meta_Control_l +U+004c +U+006c +U+004c +U+004c Control_l Control_l Control_l Control_l Meta_l Meta_L Meta_l Meta_l Meta_Control_l Meta_Control_l Meta_Control_l Meta_Control_l +U+004c +U+006c +U+004c +U+004c Control_l Control_l Control_l Control_l Meta_l Meta_L Meta_l Meta_l Meta_Control_l Meta_Control_l Meta_Control_l Meta_Control_l
+keycode 39 = U+003b U+003a U+003b U+003b VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_semicolon Meta_colon Meta_semicolon Meta_semicolon VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+003b U+003a U+003b U+003b VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_semicolon Meta_colon Meta_semicolon Meta_semicolon VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+003b U+003a U+003b U+003b VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_semicolon Meta_colon Meta_semicolon Meta_semicolon VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+003b U+003a U+003b U+003b VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_semicolon Meta_colon Meta_semicolon Meta_semicolon VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+003b U+003a U+003b U+003b VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_semicolon Meta_colon Meta_semicolon Meta_semicolon VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+003b U+003a U+003b U+003b VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_semicolon Meta_colon Meta_semicolon Meta_semicolon VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+003b U+003a U+003b U+003b VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_semicolon Meta_colon Meta_semicolon Meta_semicolon VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+003b U+003a U+003b U+003b VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_semicolon Meta_colon Meta_semicolon Meta_semicolon VoidSymbol VoidSymbol VoidSymbol VoidSymbol
+keycode 40 = U+0027 U+0022 U+0027 U+0027 Control_g Control_g Control_g Control_g Meta_apostrophe Meta_quotedbl Meta_apostrophe Meta_apostrophe Meta_Control_g Meta_Control_g Meta_Control_g Meta_Control_g U+0027 U+0022 U+0027 U+0027 Control_g Control_g Control_g Control_g Meta_apostrophe Meta_quotedbl Meta_apostrophe Meta_apostrophe Meta_Control_g Meta_Control_g Meta_Control_g Meta_Control_g U+0027 U+0022 U+0027 U+0027 Control_g Control_g Control_g Control_g Meta_apostrophe Meta_quotedbl Meta_apostrophe Meta_apostrophe Meta_Control_g Meta_Control_g Meta_Control_g Meta_Control_g U+0027 U+0022 U+0027 U+0027 Control_g Control_g Control_g Control_g Meta_apostrophe Meta_quotedbl Meta_apostrophe Meta_apostrophe Meta_Control_g Meta_Control_g Meta_Control_g Meta_Control_g U+0027 U+0022 U+0027 U+0027 Control_g Control_g Control_g Control_g Meta_apostrophe Meta_quotedbl Meta_apostrophe Meta_apostrophe Meta_Control_g Meta_Control_g Meta_Control_g Meta_Control_g U+0027 U+0022 U+0027 U+0027 Control_g Control_g Control_g Control_g Meta_apostrophe Meta_quotedbl Meta_apostrophe Meta_apostrophe Meta_Control_g Meta_Control_g Meta_Control_g Meta_Control_g U+0027 U+0022 U+0027 U+0027 Control_g Control_g Control_g Control_g Meta_apostrophe Meta_quotedbl Meta_apostrophe Meta_apostrophe Meta_Control_g Meta_Control_g Meta_Control_g Meta_Control_g U+0027 U+0022 U+0027 U+0027 Control_g Control_g Control_g Control_g Meta_apostrophe Meta_quotedbl Meta_apostrophe Meta_apostrophe Meta_Control_g Meta_Control_g Meta_Control_g Meta_Control_g
+keycode 41 = U+0060 U+007e U+0060 U+0060 nul nul nul nul Meta_grave Meta_asciitilde Meta_grave Meta_grave Meta_nul Meta_nul Meta_nul Meta_nul U+0060 U+007e U+0060 U+0060 nul nul nul nul Meta_grave Meta_asciitilde Meta_grave Meta_grave Meta_nul Meta_nul Meta_nul Meta_nul U+0060 U+007e U+0060 U+0060 nul nul nul nul Meta_grave Meta_asciitilde Meta_grave Meta_grave Meta_nul Meta_nul Meta_nul Meta_nul U+0060 U+007e U+0060 U+0060 nul nul nul nul Meta_grave Meta_asciitilde Meta_grave Meta_grave Meta_nul Meta_nul Meta_nul Meta_nul U+0060 U+007e U+0060 U+0060 nul nul nul nul Meta_grave Meta_asciitilde Meta_grave Meta_grave Meta_nul Meta_nul Meta_nul Meta_nul U+0060 U+007e U+0060 U+0060 nul nul nul nul Meta_grave Meta_asciitilde Meta_grave Meta_grave Meta_nul Meta_nul Meta_nul Meta_nul U+0060 U+007e U+0060 U+0060 nul nul nul nul Meta_grave Meta_asciitilde Meta_grave Meta_grave Meta_nul Meta_nul Meta_nul Meta_nul U+0060 U+007e U+0060 U+0060 nul nul nul nul Meta_grave Meta_asciitilde Meta_grave Meta_grave Meta_nul Meta_nul Meta_nul Meta_nul
+keycode 42 = Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift
+keycode 43 = U+005c U+007c U+005c U+005c Control_backslash Control_backslash Control_backslash Control_backslash Meta_backslash Meta_bar Meta_backslash Meta_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+005c U+007c U+005c U+005c Control_backslash Control_backslash Control_backslash Control_backslash Meta_backslash Meta_bar Meta_backslash Meta_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+005c U+007c U+005c U+005c Control_backslash Control_backslash Control_backslash Control_backslash Meta_backslash Meta_bar Meta_backslash Meta_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+005c U+007c U+005c U+005c Control_backslash Control_backslash Control_backslash Control_backslash Meta_backslash Meta_bar Meta_backslash Meta_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+005c U+007c U+005c U+005c Control_backslash Control_backslash Control_backslash Control_backslash Meta_backslash Meta_bar Meta_backslash Meta_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+005c U+007c U+005c U+005c Control_backslash Control_backslash Control_backslash Control_backslash Meta_backslash Meta_bar Meta_backslash Meta_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+005c U+007c U+005c U+005c Control_backslash Control_backslash Control_backslash Control_backslash Meta_backslash Meta_bar Meta_backslash Meta_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash U+005c U+007c U+005c U+005c Control_backslash Control_backslash Control_backslash Control_backslash Meta_backslash Meta_bar Meta_backslash Meta_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash Meta_Control_backslash
+keycode 44 = +U+007a +U+005a +U+007a +U+007a Control_z Control_z Control_z Control_z Meta_z Meta_Z Meta_z Meta_z Meta_Control_z Meta_Control_z Meta_Control_z Meta_Control_z +U+007a +U+005a +U+007a +U+007a Control_z Control_z Control_z Control_z Meta_z Meta_Z Meta_z Meta_z Meta_Control_z Meta_Control_z Meta_Control_z Meta_Control_z +U+007a +U+005a +U+007a +U+007a Control_z Control_z Control_z Control_z Meta_z Meta_Z Meta_z Meta_z Meta_Control_z Meta_Control_z Meta_Control_z Meta_Control_z +U+007a +U+005a +U+007a +U+007a Control_z Control_z Control_z Control_z Meta_z Meta_Z Meta_z Meta_z Meta_Control_z Meta_Control_z Meta_Control_z Meta_Control_z +U+005a +U+007a +U+005a +U+005a Control_z Control_z Control_z Control_z Meta_z Meta_Z Meta_z Meta_z Meta_Control_z Meta_Control_z Meta_Control_z Meta_Control_z +U+005a +U+007a +U+005a +U+005a Control_z Control_z Control_z Control_z Meta_z Meta_Z Meta_z Meta_z Meta_Control_z Meta_Control_z Meta_Control_z Meta_Control_z +U+005a +U+007a +U+005a +U+005a Control_z Control_z Control_z Control_z Meta_z Meta_Z Meta_z Meta_z Meta_Control_z Meta_Control_z Meta_Control_z Meta_Control_z +U+005a +U+007a +U+005a +U+005a Control_z Control_z Control_z Control_z Meta_z Meta_Z Meta_z Meta_z Meta_Control_z Meta_Control_z Meta_Control_z Meta_Control_z
+keycode 45 = +U+0078 +U+0058 +U+0078 +U+0078 Control_x Control_x Control_x Control_x Meta_x Meta_X Meta_x Meta_x Meta_Control_x Meta_Control_x Meta_Control_x Meta_Control_x +U+0078 +U+0058 +U+0078 +U+0078 Control_x Control_x Control_x Control_x Meta_x Meta_X Meta_x Meta_x Meta_Control_x Meta_Control_x Meta_Control_x Meta_Control_x +U+0078 +U+0058 +U+0078 +U+0078 Control_x Control_x Control_x Control_x Meta_x Meta_X Meta_x Meta_x Meta_Control_x Meta_Control_x Meta_Control_x Meta_Control_x +U+0078 +U+0058 +U+0078 +U+0078 Control_x Control_x Control_x Control_x Meta_x Meta_X Meta_x Meta_x Meta_Control_x Meta_Control_x Meta_Control_x Meta_Control_x +U+0058 +U+0078 +U+0058 +U+0058 Control_x Control_x Control_x Control_x Meta_x Meta_X Meta_x Meta_x Meta_Control_x Meta_Control_x Meta_Control_x Meta_Control_x +U+0058 +U+0078 +U+0058 +U+0058 Control_x Control_x Control_x Control_x Meta_x Meta_X Meta_x Meta_x Meta_Control_x Meta_Control_x Meta_Control_x Meta_Control_x +U+0058 +U+0078 +U+0058 +U+0058 Control_x Control_x Control_x Control_x Meta_x Meta_X Meta_x Meta_x Meta_Control_x Meta_Control_x Meta_Control_x Meta_Control_x +U+0058 +U+0078 +U+0058 +U+0058 Control_x Control_x Control_x Control_x Meta_x Meta_X Meta_x Meta_x Meta_Control_x Meta_Control_x Meta_Control_x Meta_Control_x
+keycode 46 = +U+0063 +U+0043 +U+0063 +U+0063 Control_c Control_c Control_c Control_c Meta_c Meta_C Meta_c Meta_c Meta_Control_c Meta_Control_c Meta_Control_c Meta_Control_c +U+0063 +U+0043 +U+0063 +U+0063 Control_c Control_c Control_c Control_c Meta_c Meta_C Meta_c Meta_c Meta_Control_c Meta_Control_c Meta_Control_c Meta_Control_c +U+0063 +U+0043 +U+0063 +U+0063 Control_c Control_c Control_c Control_c Meta_c Meta_C Meta_c Meta_c Meta_Control_c Meta_Control_c Meta_Control_c Meta_Control_c +U+0063 +U+0043 +U+0063 +U+0063 Control_c Control_c Control_c Control_c Meta_c Meta_C Meta_c Meta_c Meta_Control_c Meta_Control_c Meta_Control_c Meta_Control_c +U+0043 +U+0063 +U+0043 +U+0043 Control_c Control_c Control_c Control_c Meta_c Meta_C Meta_c Meta_c Meta_Control_c Meta_Control_c Meta_Control_c Meta_Control_c +U+0043 +U+0063 +U+0043 +U+0043 Control_c Control_c Control_c Control_c Meta_c Meta_C Meta_c Meta_c Meta_Control_c Meta_Control_c Meta_Control_c Meta_Control_c +U+0043 +U+0063 +U+0043 +U+0043 Control_c Control_c Control_c Control_c Meta_c Meta_C Meta_c Meta_c Meta_Control_c Meta_Control_c Meta_Control_c Meta_Control_c +U+0043 +U+0063 +U+0043 +U+0043 Control_c Control_c Control_c Control_c Meta_c Meta_C Meta_c Meta_c Meta_Control_c Meta_Control_c Meta_Control_c Meta_Control_c
+keycode 47 = +U+0076 +U+0056 +U+0076 +U+0076 Control_v Control_v Control_v Control_v Meta_v Meta_V Meta_v Meta_v Meta_Control_v Meta_Control_v Meta_Control_v Meta_Control_v +U+0076 +U+0056 +U+0076 +U+0076 Control_v Control_v Control_v Control_v Meta_v Meta_V Meta_v Meta_v Meta_Control_v Meta_Control_v Meta_Control_v Meta_Control_v +U+0076 +U+0056 +U+0076 +U+0076 Control_v Control_v Control_v Control_v Meta_v Meta_V Meta_v Meta_v Meta_Control_v Meta_Control_v Meta_Control_v Meta_Control_v +U+0076 +U+0056 +U+0076 +U+0076 Control_v Control_v Control_v Control_v Meta_v Meta_V Meta_v Meta_v Meta_Control_v Meta_Control_v Meta_Control_v Meta_Control_v +U+0056 +U+0076 +U+0056 +U+0056 Control_v Control_v Control_v Control_v Meta_v Meta_V Meta_v Meta_v Meta_Control_v Meta_Control_v Meta_Control_v Meta_Control_v +U+0056 +U+0076 +U+0056 +U+0056 Control_v Control_v Control_v Control_v Meta_v Meta_V Meta_v Meta_v Meta_Control_v Meta_Control_v Meta_Control_v Meta_Control_v +U+0056 +U+0076 +U+0056 +U+0056 Control_v Control_v Control_v Control_v Meta_v Meta_V Meta_v Meta_v Meta_Control_v Meta_Control_v Meta_Control_v Meta_Control_v +U+0056 +U+0076 +U+0056 +U+0056 Control_v Control_v Control_v Control_v Meta_v Meta_V Meta_v Meta_v Meta_Control_v Meta_Control_v Meta_Control_v Meta_Control_v
+keycode 48 = +U+0062 +U+0042 +U+0062 +U+0062 Control_b Control_b Control_b Control_b Meta_b Meta_B Meta_b Meta_b Meta_Control_b Meta_Control_b Meta_Control_b Meta_Control_b +U+0062 +U+0042 +U+0062 +U+0062 Control_b Control_b Control_b Control_b Meta_b Meta_B Meta_b Meta_b Meta_Control_b Meta_Control_b Meta_Control_b Meta_Control_b +U+0062 +U+0042 +U+0062 +U+0062 Control_b Control_b Control_b Control_b Meta_b Meta_B Meta_b Meta_b Meta_Control_b Meta_Control_b Meta_Control_b Meta_Control_b +U+0062 +U+0042 +U+0062 +U+0062 Control_b Control_b Control_b Control_b Meta_b Meta_B Meta_b Meta_b Meta_Control_b Meta_Control_b Meta_Control_b Meta_Control_b +U+0042 +U+0062 +U+0042 +U+0042 Control_b Control_b Control_b Control_b Meta_b Meta_B Meta_b Meta_b Meta_Control_b Meta_Control_b Meta_Control_b Meta_Control_b +U+0042 +U+0062 +U+0042 +U+0042 Control_b Control_b Control_b Control_b Meta_b Meta_B Meta_b Meta_b Meta_Control_b Meta_Control_b Meta_Control_b Meta_Control_b +U+0042 +U+0062 +U+0042 +U+0042 Control_b Control_b Control_b Control_b Meta_b Meta_B Meta_b Meta_b Meta_Control_b Meta_Control_b Meta_Control_b Meta_Control_b +U+0042 +U+0062 +U+0042 +U+0042 Control_b Control_b Control_b Control_b Meta_b Meta_B Meta_b Meta_b Meta_Control_b Meta_Control_b Meta_Control_b Meta_Control_b
+keycode 49 = +U+006e +U+004e +U+006e +U+006e Control_n Control_n Control_n Control_n Meta_n Meta_N Meta_n Meta_n Meta_Control_n Meta_Control_n Meta_Control_n Meta_Control_n +U+006e +U+004e +U+006e +U+006e Control_n Control_n Control_n Control_n Meta_n Meta_N Meta_n Meta_n Meta_Control_n Meta_Control_n Meta_Control_n Meta_Control_n +U+006e +U+004e +U+006e +U+006e Control_n Control_n Control_n Control_n Meta_n Meta_N Meta_n Meta_n Meta_Control_n Meta_Control_n Meta_Control_n Meta_Control_n +U+006e +U+004e +U+006e +U+006e Control_n Control_n Control_n Control_n Meta_n Meta_N Meta_n Meta_n Meta_Control_n Meta_Control_n Meta_Control_n Meta_Control_n +U+004e +U+006e +U+004e +U+004e Control_n Control_n Control_n Control_n Meta_n Meta_N Meta_n Meta_n Meta_Control_n Meta_Control_n Meta_Control_n Meta_Control_n +U+004e +U+006e +U+004e +U+004e Control_n Control_n Control_n Control_n Meta_n Meta_N Meta_n Meta_n Meta_Control_n Meta_Control_n Meta_Control_n Meta_Control_n +U+004e +U+006e +U+004e +U+004e Control_n Control_n Control_n Control_n Meta_n Meta_N Meta_n Meta_n Meta_Control_n Meta_Control_n Meta_Control_n Meta_Control_n +U+004e +U+006e +U+004e +U+004e Control_n Control_n Control_n Control_n Meta_n Meta_N Meta_n Meta_n Meta_Control_n Meta_Control_n Meta_Control_n Meta_Control_n
+keycode 50 = +U+006d +U+004d +U+006d +U+006d Control_m Control_m Control_m Control_m Meta_m Meta_M Meta_m Meta_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m +U+006d +U+004d +U+006d +U+006d Control_m Control_m Control_m Control_m Meta_m Meta_M Meta_m Meta_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m +U+006d +U+004d +U+006d +U+006d Control_m Control_m Control_m Control_m Meta_m Meta_M Meta_m Meta_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m +U+006d +U+004d +U+006d +U+006d Control_m Control_m Control_m Control_m Meta_m Meta_M Meta_m Meta_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m +U+004d +U+006d +U+004d +U+004d Control_m Control_m Control_m Control_m Meta_m Meta_M Meta_m Meta_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m +U+004d +U+006d +U+004d +U+004d Control_m Control_m Control_m Control_m Meta_m Meta_M Meta_m Meta_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m +U+004d +U+006d +U+004d +U+004d Control_m Control_m Control_m Control_m Meta_m Meta_M Meta_m Meta_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m +U+004d +U+006d +U+004d +U+004d Control_m Control_m Control_m Control_m Meta_m Meta_M Meta_m Meta_m Meta_Control_m Meta_Control_m Meta_Control_m Meta_Control_m
+keycode 51 = U+002c U+003c U+002c U+002c VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_comma Meta_less Meta_comma Meta_comma VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+002c U+003c U+002c U+002c VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_comma Meta_less Meta_comma Meta_comma VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+002c U+003c U+002c U+002c VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_comma Meta_less Meta_comma Meta_comma VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+002c U+003c U+002c U+002c VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_comma Meta_less Meta_comma Meta_comma VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+002c U+003c U+002c U+002c VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_comma Meta_less Meta_comma Meta_comma VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+002c U+003c U+002c U+002c VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_comma Meta_less Meta_comma Meta_comma VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+002c U+003c U+002c U+002c VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_comma Meta_less Meta_comma Meta_comma VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+002c U+003c U+002c U+002c VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_comma Meta_less Meta_comma Meta_comma VoidSymbol VoidSymbol VoidSymbol VoidSymbol
+keycode 52 = U+002e U+003e U+002e U+002e Compose Compose Compose Compose Meta_period Meta_greater Meta_period Meta_period Compose Compose Compose Compose U+002e U+003e U+002e U+002e Compose Compose Compose Compose Meta_period Meta_greater Meta_period Meta_period Compose Compose Compose Compose U+002e U+003e U+002e U+002e Compose Compose Compose Compose Meta_period Meta_greater Meta_period Meta_period Compose Compose Compose Compose U+002e U+003e U+002e U+002e Compose Compose Compose Compose Meta_period Meta_greater Meta_period Meta_period Compose Compose Compose Compose U+002e U+003e U+002e U+002e Compose Compose Compose Compose Meta_period Meta_greater Meta_period Meta_period Compose Compose Compose Compose U+002e U+003e U+002e U+002e Compose Compose Compose Compose Meta_period Meta_greater Meta_period Meta_period Compose Compose Compose Compose U+002e U+003e U+002e U+002e Compose Compose Compose Compose Meta_period Meta_greater Meta_period Meta_period Compose Compose Compose Compose U+002e U+003e U+002e U+002e Compose Compose Compose Compose Meta_period Meta_greater Meta_period Meta_period Compose Compose Compose Compose
+keycode 53 = U+002f U+003f U+002f U+002f Delete Delete Delete Delete Meta_slash Meta_question Meta_slash Meta_slash Meta_Delete Meta_Delete Meta_Delete Meta_Delete U+002f U+003f U+002f U+002f Delete Delete Delete Delete Meta_slash Meta_question Meta_slash Meta_slash Meta_Delete Meta_Delete Meta_Delete Meta_Delete U+002f U+003f U+002f U+002f Delete Delete Delete Delete Meta_slash Meta_question Meta_slash Meta_slash Meta_Delete Meta_Delete Meta_Delete Meta_Delete U+002f U+003f U+002f U+002f Delete Delete Delete Delete Meta_slash Meta_question Meta_slash Meta_slash Meta_Delete Meta_Delete Meta_Delete Meta_Delete U+002f U+003f U+002f U+002f Delete Delete Delete Delete Meta_slash Meta_question Meta_slash Meta_slash Meta_Delete Meta_Delete Meta_Delete Meta_Delete U+002f U+003f U+002f U+002f Delete Delete Delete Delete Meta_slash Meta_question Meta_slash Meta_slash Meta_Delete Meta_Delete Meta_Delete Meta_Delete U+002f U+003f U+002f U+002f Delete Delete Delete Delete Meta_slash Meta_question Meta_slash Meta_slash Meta_Delete Meta_Delete Meta_Delete Meta_Delete U+002f U+003f U+002f U+002f Delete Delete Delete Delete Meta_slash Meta_question Meta_slash Meta_slash Meta_Delete Meta_Delete Meta_Delete Meta_Delete
+keycode 54 = Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift Shift
+keycode 55 = KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply Hex_C KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply KP_Multiply
+keycode 56 = Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt
+keycode 57 = U+0020 U+0020 U+0020 U+0020 nul nul nul nul Meta_space Meta_space Meta_space Meta_space Meta_nul Meta_nul Meta_nul Meta_nul U+0020 U+0020 U+0020 U+0020 nul nul nul nul Meta_space Meta_space Meta_space Meta_space Meta_nul Meta_nul Meta_nul Meta_nul U+0020 U+0020 U+0020 U+0020 nul nul nul nul Meta_space Meta_space Meta_space Meta_space Meta_nul Meta_nul Meta_nul Meta_nul U+0020 U+0020 U+0020 U+0020 nul nul nul nul Meta_space Meta_space Meta_space Meta_space Meta_nul Meta_nul Meta_nul Meta_nul U+0020 U+0020 U+0020 U+0020 nul nul nul nul Meta_space Meta_space Meta_space Meta_space Meta_nul Meta_nul Meta_nul Meta_nul U+0020 U+0020 U+0020 U+0020 nul nul nul nul Meta_space Meta_space Meta_space Meta_space Meta_nul Meta_nul Meta_nul Meta_nul U+0020 U+0020 U+0020 U+0020 nul nul nul nul Meta_space Meta_space Meta_space Meta_space Meta_nul Meta_nul Meta_nul Meta_nul U+0020 U+0020 U+0020 U+0020 nul nul nul nul Meta_space Meta_space Meta_space Meta_space Meta_nul Meta_nul Meta_nul Meta_nul
+keycode 58 = CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock CtrlL_Lock
+keycode 59 = F1 F13 Console_13 Console_25 F25 F37 Console_13 Console_25 Console_1 Console_13 F1 F1 Console_1 Console_13 F1 F1 F1 F13 Console_13 Console_25 F25 F37 Console_13 Console_25 Console_1 Console_13 F1 F1 Console_1 Console_13 F1 F1 F1 F13 Console_13 Console_25 F25 F37 Console_13 Console_25 Console_1 Console_13 F1 F1 Console_1 Console_13 F1 F1 F1 F13 Console_13 Console_25 F25 F37 Console_13 Console_25 Console_1 Console_13 F1 F1 Console_1 Console_13 F1 F1 F1 F13 Console_13 Console_25 F25 F37 Console_13 Console_25 Console_1 Console_13 F1 F1 Console_1 Console_13 F1 F1 F1 F13 Console_13 Console_25 F25 F37 Console_13 Console_25 Console_1 Console_13 F1 F1 Console_1 Console_13 F1 F1 F1 F13 Console_13 Console_25 F25 F37 Console_13 Console_25 Console_1 Console_13 F1 F1 Console_1 Console_13 F1 F1 F1 F13 Console_13 Console_25 F25 F37 Console_13 Console_25 Console_1 Console_13 F1 F1 Console_1 Console_13 F1 F1
+keycode 60 = F2 F14 Console_14 Console_26 F26 F38 Console_14 Console_26 Console_2 Console_14 F2 F2 Console_2 Console_14 F2 F2 F2 F14 Console_14 Console_26 F26 F38 Console_14 Console_26 Console_2 Console_14 F2 F2 Console_2 Console_14 F2 F2 F2 F14 Console_14 Console_26 F26 F38 Console_14 Console_26 Console_2 Console_14 F2 F2 Console_2 Console_14 F2 F2 F2 F14 Console_14 Console_26 F26 F38 Console_14 Console_26 Console_2 Console_14 F2 F2 Console_2 Console_14 F2 F2 F2 F14 Console_14 Console_26 F26 F38 Console_14 Console_26 Console_2 Console_14 F2 F2 Console_2 Console_14 F2 F2 F2 F14 Console_14 Console_26 F26 F38 Console_14 Console_26 Console_2 Console_14 F2 F2 Console_2 Console_14 F2 F2 F2 F14 Console_14 Console_26 F26 F38 Console_14 Console_26 Console_2 Console_14 F2 F2 Console_2 Console_14 F2 F2 F2 F14 Console_14 Console_26 F26 F38 Console_14 Console_26 Console_2 Console_14 F2 F2 Console_2 Console_14 F2 F2
+keycode 61 = F3 F15 Console_15 Console_27 F27 F39 Console_15 Console_27 Console_3 Console_15 F3 F3 Console_3 Console_15 F3 F3 F3 F15 Console_15 Console_27 F27 F39 Console_15 Console_27 Console_3 Console_15 F3 F3 Console_3 Console_15 F3 F3 F3 F15 Console_15 Console_27 F27 F39 Console_15 Console_27 Console_3 Console_15 F3 F3 Console_3 Console_15 F3 F3 F3 F15 Console_15 Console_27 F27 F39 Console_15 Console_27 Console_3 Console_15 F3 F3 Console_3 Console_15 F3 F3 F3 F15 Console_15 Console_27 F27 F39 Console_15 Console_27 Console_3 Console_15 F3 F3 Console_3 Console_15 F3 F3 F3 F15 Console_15 Console_27 F27 F39 Console_15 Console_27 Console_3 Console_15 F3 F3 Console_3 Console_15 F3 F3 F3 F15 Console_15 Console_27 F27 F39 Console_15 Console_27 Console_3 Console_15 F3 F3 Console_3 Console_15 F3 F3 F3 F15 Console_15 Console_27 F27 F39 Console_15 Console_27 Console_3 Console_15 F3 F3 Console_3 Console_15 F3 F3
+keycode 62 = F4 F16 Console_16 Console_28 F28 F40 Console_16 Console_28 Console_4 Console_16 F4 F4 Console_4 Console_16 F4 F4 F4 F16 Console_16 Console_28 F28 F40 Console_16 Console_28 Console_4 Console_16 F4 F4 Console_4 Console_16 F4 F4 F4 F16 Console_16 Console_28 F28 F40 Console_16 Console_28 Console_4 Console_16 F4 F4 Console_4 Console_16 F4 F4 F4 F16 Console_16 Console_28 F28 F40 Console_16 Console_28 Console_4 Console_16 F4 F4 Console_4 Console_16 F4 F4 F4 F16 Console_16 Console_28 F28 F40 Console_16 Console_28 Console_4 Console_16 F4 F4 Console_4 Console_16 F4 F4 F4 F16 Console_16 Console_28 F28 F40 Console_16 Console_28 Console_4 Console_16 F4 F4 Console_4 Console_16 F4 F4 F4 F16 Console_16 Console_28 F28 F40 Console_16 Console_28 Console_4 Console_16 F4 F4 Console_4 Console_16 F4 F4 F4 F16 Console_16 Console_28 F28 F40 Console_16 Console_28 Console_4 Console_16 F4 F4 Console_4 Console_16 F4 F4
+keycode 63 = F5 F17 Console_17 Console_29 F29 F41 Console_17 Console_29 Console_5 Console_17 F5 F5 Console_5 Console_17 F5 F5 F5 F17 Console_17 Console_29 F29 F41 Console_17 Console_29 Console_5 Console_17 F5 F5 Console_5 Console_17 F5 F5 F5 F17 Console_17 Console_29 F29 F41 Console_17 Console_29 Console_5 Console_17 F5 F5 Console_5 Console_17 F5 F5 F5 F17 Console_17 Console_29 F29 F41 Console_17 Console_29 Console_5 Console_17 F5 F5 Console_5 Console_17 F5 F5 F5 F17 Console_17 Console_29 F29 F41 Console_17 Console_29 Console_5 Console_17 F5 F5 Console_5 Console_17 F5 F5 F5 F17 Console_17 Console_29 F29 F41 Console_17 Console_29 Console_5 Console_17 F5 F5 Console_5 Console_17 F5 F5 F5 F17 Console_17 Console_29 F29 F41 Console_17 Console_29 Console_5 Console_17 F5 F5 Console_5 Console_17 F5 F5 F5 F17 Console_17 Console_29 F29 F41 Console_17 Console_29 Console_5 Console_17 F5 F5 Console_5 Console_17 F5 F5
+keycode 64 = F6 F18 Console_18 Console_30 F30 F42 Console_18 Console_30 Console_6 Console_18 F6 F6 Console_6 Console_18 F6 F6 F6 F18 Console_18 Console_30 F30 F42 Console_18 Console_30 Console_6 Console_18 F6 F6 Console_6 Console_18 F6 F6 F6 F18 Console_18 Console_30 F30 F42 Console_18 Console_30 Console_6 Console_18 F6 F6 Console_6 Console_18 F6 F6 F6 F18 Console_18 Console_30 F30 F42 Console_18 Console_30 Console_6 Console_18 F6 F6 Console_6 Console_18 F6 F6 F6 F18 Console_18 Console_30 F30 F42 Console_18 Console_30 Console_6 Console_18 F6 F6 Console_6 Console_18 F6 F6 F6 F18 Console_18 Console_30 F30 F42 Console_18 Console_30 Console_6 Console_18 F6 F6 Console_6 Console_18 F6 F6 F6 F18 Console_18 Console_30 F30 F42 Console_18 Console_30 Console_6 Console_18 F6 F6 Console_6 Console_18 F6 F6 F6 F18 Console_18 Console_30 F30 F42 Console_18 Console_30 Console_6 Console_18 F6 F6 Console_6 Console_18 F6 F6
+keycode 65 = F7 F19 Console_19 Console_31 F31 F43 Console_19 Console_31 Console_7 Console_19 F7 F7 Console_7 Console_19 F7 F7 F7 F19 Console_19 Console_31 F31 F43 Console_19 Console_31 Console_7 Console_19 F7 F7 Console_7 Console_19 F7 F7 F7 F19 Console_19 Console_31 F31 F43 Console_19 Console_31 Console_7 Console_19 F7 F7 Console_7 Console_19 F7 F7 F7 F19 Console_19 Console_31 F31 F43 Console_19 Console_31 Console_7 Console_19 F7 F7 Console_7 Console_19 F7 F7 F7 F19 Console_19 Console_31 F31 F43 Console_19 Console_31 Console_7 Console_19 F7 F7 Console_7 Console_19 F7 F7 F7 F19 Console_19 Console_31 F31 F43 Console_19 Console_31 Console_7 Console_19 F7 F7 Console_7 Console_19 F7 F7 F7 F19 Console_19 Console_31 F31 F43 Console_19 Console_31 Console_7 Console_19 F7 F7 Console_7 Console_19 F7 F7 F7 F19 Console_19 Console_31 F31 F43 Console_19 Console_31 Console_7 Console_19 F7 F7 Console_7 Console_19 F7 F7
+keycode 66 = F8 F20 Console_20 Console_32 F32 F44 Console_20 Console_32 Console_8 Console_20 F8 F8 Console_8 Console_20 F8 F8 F8 F20 Console_20 Console_32 F32 F44 Console_20 Console_32 Console_8 Console_20 F8 F8 Console_8 Console_20 F8 F8 F8 F20 Console_20 Console_32 F32 F44 Console_20 Console_32 Console_8 Console_20 F8 F8 Console_8 Console_20 F8 F8 F8 F20 Console_20 Console_32 F32 F44 Console_20 Console_32 Console_8 Console_20 F8 F8 Console_8 Console_20 F8 F8 F8 F20 Console_20 Console_32 F32 F44 Console_20 Console_32 Console_8 Console_20 F8 F8 Console_8 Console_20 F8 F8 F8 F20 Console_20 Console_32 F32 F44 Console_20 Console_32 Console_8 Console_20 F8 F8 Console_8 Console_20 F8 F8 F8 F20 Console_20 Console_32 F32 F44 Console_20 Console_32 Console_8 Console_20 F8 F8 Console_8 Console_20 F8 F8 F8 F20 Console_20 Console_32 F32 F44 Console_20 Console_32 Console_8 Console_20 F8 F8 Console_8 Console_20 F8 F8
+keycode 67 = F9 F21 Console_21 Console_33 F33 F45 Console_21 Console_33 Console_9 Console_21 F9 F9 Console_9 Console_21 F9 F9 F9 F21 Console_21 Console_33 F33 F45 Console_21 Console_33 Console_9 Console_21 F9 F9 Console_9 Console_21 F9 F9 F9 F21 Console_21 Console_33 F33 F45 Console_21 Console_33 Console_9 Console_21 F9 F9 Console_9 Console_21 F9 F9 F9 F21 Console_21 Console_33 F33 F45 Console_21 Console_33 Console_9 Console_21 F9 F9 Console_9 Console_21 F9 F9 F9 F21 Console_21 Console_33 F33 F45 Console_21 Console_33 Console_9 Console_21 F9 F9 Console_9 Console_21 F9 F9 F9 F21 Console_21 Console_33 F33 F45 Console_21 Console_33 Console_9 Console_21 F9 F9 Console_9 Console_21 F9 F9 F9 F21 Console_21 Console_33 F33 F45 Console_21 Console_33 Console_9 Console_21 F9 F9 Console_9 Console_21 F9 F9 F9 F21 Console_21 Console_33 F33 F45 Console_21 Console_33 Console_9 Console_21 F9 F9 Console_9 Console_21 F9 F9
+keycode 68 = F10 F22 Console_22 Console_34 F34 F46 Console_22 Console_34 Console_10 Console_22 F10 F10 Console_10 Console_22 F10 F10 F10 F22 Console_22 Console_34 F34 F46 Console_22 Console_34 Console_10 Console_22 F10 F10 Console_10 Console_22 F10 F10 F10 F22 Console_22 Console_34 F34 F46 Console_22 Console_34 Console_10 Console_22 F10 F10 Console_10 Console_22 F10 F10 F10 F22 Console_22 Console_34 F34 F46 Console_22 Console_34 Console_10 Console_22 F10 F10 Console_10 Console_22 F10 F10 F10 F22 Console_22 Console_34 F34 F46 Console_22 Console_34 Console_10 Console_22 F10 F10 Console_10 Console_22 F10 F10 F10 F22 Console_22 Console_34 F34 F46 Console_22 Console_34 Console_10 Console_22 F10 F10 Console_10 Console_22 F10 F10 F10 F22 Console_22 Console_34 F34 F46 Console_22 Console_34 Console_10 Console_22 F10 F10 Console_10 Console_22 F10 F10 F10 F22 Console_22 Console_34 F34 F46 Console_22 Console_34 Console_10 Console_22 F10 F10 Console_10 Console_22 F10 F10
+keycode 69 = Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Hex_A Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock Num_Lock
+keycode 70 = Scroll_Lock Show_Memory Show_Registers Scroll_Lock Show_State Scroll_Lock Scroll_Lock Scroll_Lock Show_Registers Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Show_Memory Show_Registers Scroll_Lock Show_State Scroll_Lock Scroll_Lock Scroll_Lock Show_Registers Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Show_Memory Show_Registers Scroll_Lock Show_State Scroll_Lock Scroll_Lock Scroll_Lock Show_Registers Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Show_Memory Show_Registers Scroll_Lock Show_State Scroll_Lock Scroll_Lock Scroll_Lock Show_Registers Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Show_Memory Show_Registers Scroll_Lock Show_State Scroll_Lock Scroll_Lock Scroll_Lock Show_Registers Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Show_Memory Show_Registers Scroll_Lock Show_State Scroll_Lock Scroll_Lock Scroll_Lock Show_Registers Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Show_Memory Show_Registers Scroll_Lock Show_State Scroll_Lock Scroll_Lock Scroll_Lock Show_Registers Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Show_Memory Show_Registers Scroll_Lock Show_State Scroll_Lock Scroll_Lock Scroll_Lock Show_Registers Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock Scroll_Lock
+keycode 71 = KP_7 KP_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 Ascii_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 Ascii_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 Ascii_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 Ascii_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 Ascii_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 Ascii_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 Ascii_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 Ascii_7 Hex_7 KP_7 KP_7 KP_7 KP_7 KP_7 KP_7
+keycode 72 = KP_8 KP_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 Ascii_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 Ascii_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 Ascii_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 Ascii_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 Ascii_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 Ascii_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 Ascii_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 Ascii_8 Hex_8 KP_8 KP_8 KP_8 KP_8 KP_8 KP_8
+keycode 73 = KP_9 KP_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 Ascii_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 Ascii_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 Ascii_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 Ascii_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 Ascii_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 Ascii_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 Ascii_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 Ascii_9 Hex_9 KP_9 KP_9 KP_9 KP_9 KP_9 KP_9
+keycode 74 = KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract Hex_D KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract KP_Subtract
+keycode 75 = KP_4 KP_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 Ascii_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 Ascii_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 Ascii_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 Ascii_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 Ascii_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 Ascii_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 Ascii_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 Ascii_4 Hex_4 KP_4 KP_4 KP_4 KP_4 KP_4 KP_4
+keycode 76 = KP_5 KP_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 Ascii_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 Ascii_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 Ascii_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 Ascii_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 Ascii_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 Ascii_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 Ascii_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 Ascii_5 Hex_5 KP_5 KP_5 KP_5 KP_5 KP_5 KP_5
+keycode 77 = KP_6 KP_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 Ascii_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 Ascii_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 Ascii_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 Ascii_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 Ascii_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 Ascii_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 Ascii_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 Ascii_6 Hex_6 KP_6 KP_6 KP_6 KP_6 KP_6 KP_6
+keycode 78 = KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add Hex_E KP_Add KP_Add KP_Add KP_Add KP_Add KP_Add
+keycode 79 = KP_1 KP_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 Ascii_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 Ascii_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 Ascii_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 Ascii_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 Ascii_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 Ascii_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 Ascii_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 Ascii_1 Hex_1 KP_1 KP_1 KP_1 KP_1 KP_1 KP_1
+keycode 80 = KP_2 KP_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 Ascii_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 Ascii_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 Ascii_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 Ascii_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 Ascii_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 Ascii_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 Ascii_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 Ascii_2 Hex_2 KP_2 KP_2 KP_2 KP_2 KP_2 KP_2
+keycode 81 = KP_3 KP_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 Ascii_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 Ascii_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 Ascii_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 Ascii_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 Ascii_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 Ascii_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 Ascii_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 Ascii_3 Hex_3 KP_3 KP_3 KP_3 KP_3 KP_3 KP_3
+keycode 82 = KP_0 KP_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 Ascii_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 Ascii_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 Ascii_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 Ascii_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 Ascii_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 Ascii_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 Ascii_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 Ascii_0 Hex_0 KP_0 KP_0 KP_0 KP_0 KP_0 KP_0
+keycode 83 = KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period KP_Period KP_Period KP_Period KP_Period Boot KP_Period Boot KP_Period
+keycode 86 = U+003c U+003e U+007c U+00a6 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_less Meta_greater Meta_bar Meta_bar VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+003c U+003e U+007c U+00a6 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_less Meta_greater Meta_bar Meta_bar VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+003c U+003e U+007c U+00a6 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_less Meta_greater Meta_bar Meta_bar VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+003c U+003e U+007c U+00a6 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_less Meta_greater Meta_bar Meta_bar VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+003c U+003e U+007c U+00a6 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_less Meta_greater Meta_bar Meta_bar VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+003c U+003e U+007c U+00a6 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_less Meta_greater Meta_bar Meta_bar VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+003c U+003e U+007c U+00a6 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_less Meta_greater Meta_bar Meta_bar VoidSymbol VoidSymbol VoidSymbol VoidSymbol U+003c U+003e U+007c U+00a6 VoidSymbol VoidSymbol VoidSymbol VoidSymbol Meta_less Meta_greater Meta_bar Meta_bar VoidSymbol VoidSymbol VoidSymbol VoidSymbol
+keycode 87 = F11 F23 Console_23 Console_35 F35 F47 Console_23 Console_35 Console_11 Console_23 F11 F11 Console_11 Console_23 F11 F11 F11 F23 Console_23 Console_35 F35 F47 Console_23 Console_35 Console_11 Console_23 F11 F11 Console_11 Console_23 F11 F11 F11 F23 Console_23 Console_35 F35 F47 Console_23 Console_35 Console_11 Console_23 F11 F11 Console_11 Console_23 F11 F11 F11 F23 Console_23 Console_35 F35 F47 Console_23 Console_35 Console_11 Console_23 F11 F11 Console_11 Console_23 F11 F11 F11 F23 Console_23 Console_35 F35 F47 Console_23 Console_35 Console_11 Console_23 F11 F11 Console_11 Console_23 F11 F11 F11 F23 Console_23 Console_35 F35 F47 Console_23 Console_35 Console_11 Console_23 F11 F11 Console_11 Console_23 F11 F11 F11 F23 Console_23 Console_35 F35 F47 Console_23 Console_35 Console_11 Console_23 F11 F11 Console_11 Console_23 F11 F11 F11 F23 Console_23 Console_35 F35 F47 Console_23 Console_35 Console_11 Console_23 F11 F11 Console_11 Console_23 F11 F11
+keycode 88 = F12 F24 Console_24 Console_36 F36 F48 Console_24 Console_36 Console_12 Console_24 F12 F12 Console_12 Console_24 F12 F12 F12 F24 Console_24 Console_36 F36 F48 Console_24 Console_36 Console_12 Console_24 F12 F12 Console_12 Console_24 F12 F12 F12 F24 Console_24 Console_36 F36 F48 Console_24 Console_36 Console_12 Console_24 F12 F12 Console_12 Console_24 F12 F12 F12 F24 Console_24 Console_36 F36 F48 Console_24 Console_36 Console_12 Console_24 F12 F12 Console_12 Console_24 F12 F12 F12 F24 Console_24 Console_36 F36 F48 Console_24 Console_36 Console_12 Console_24 F12 F12 Console_12 Console_24 F12 F12 F12 F24 Console_24 Console_36 F36 F48 Console_24 Console_36 Console_12 Console_24 F12 F12 Console_12 Console_24 F12 F12 F12 F24 Console_24 Console_36 F36 F48 Console_24 Console_36 Console_12 Console_24 F12 F12 Console_12 Console_24 F12 F12 F12 F24 Console_24 Console_36 F36 F48 Console_24 Console_36 Console_12 Console_24 F12 F12 Console_12 Console_24 F12 F12
+keycode 102 = Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home Home
+keycode 103 = Up Up Up Up Up Up Up Up KeyboardSignal Up Up Up Up Up Up Up Up Up Up Up Up Up Up Up KeyboardSignal Up Up Up Up Up Up Up Up Up Up Up Up Up Up Up KeyboardSignal Up Up Up Up Up Up Up Up Up Up Up Up Up Up Up KeyboardSignal Up Up Up Up Up Up Up Up Up Up Up Up Up Up Up KeyboardSignal Up Up Up Up Up Up Up Up Up Up Up Up Up Up Up KeyboardSignal Up Up Up Up Up Up Up Up Up Up Up Up Up Up Up KeyboardSignal Up Up Up Up Up Up Up Up Up Up Up Up Up Up Up KeyboardSignal Up Up Up Up Up Up Up
+keycode 104 = Prior Scroll_Backward Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Scroll_Backward Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Scroll_Backward Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Scroll_Backward Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Scroll_Backward Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Scroll_Backward Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Scroll_Backward Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Scroll_Backward Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior Prior
+keycode 105 = Left Left Left Left Left Left Left Left Decr_Console Left Left Left Left Left Left Left Left Left Left Left Left Left Left Left Decr_Console Left Left Left Left Left Left Left Left Left Left Left Left Left Left Left Decr_Console Left Left Left Left Left Left Left Left Left Left Left Left Left Left Left Decr_Console Left Left Left Left Left Left Left Left Left Left Left Left Left Left Left Decr_Console Left Left Left Left Left Left Left Left Left Left Left Left Left Left Left Decr_Console Left Left Left Left Left Left Left Left Left Left Left Left Left Left Left Decr_Console Left Left Left Left Left Left Left Left Left Left Left Left Left Left Left Decr_Console Left Left Left Left Left Left Left
+keycode 106 = Right Right Right Right Right Right Right Right Incr_Console Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Incr_Console Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Incr_Console Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Incr_Console Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Incr_Console Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Incr_Console Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Incr_Console Right Right Right Right Right Right Right Right Right Right Right Right Right Right Right Incr_Console Right Right Right Right Right Right Right
+keycode 107 = End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End End
+keycode 108 = Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down Down
+keycode 109 = Next Scroll_Forward Next Next Next Next Next Next Next Next Next Next Next Next Next Next Next Scroll_Forward Next Next Next Next Next Next Next Next Next Next Next Next Next Next Next Scroll_Forward Next Next Next Next Next Next Next Next Next Next Next Next Next Next Next Scroll_Forward Next Next Next Next Next Next Next Next Next Next Next Next Next Next Next Scroll_Forward Next Next Next Next Next Next Next Next Next Next Next Next Next Next Next Scroll_Forward Next Next Next Next Next Next Next Next Next Next Next Next Next Next Next Scroll_Forward Next Next Next Next Next Next Next Next Next Next Next Next Next Next Next Scroll_Forward Next Next Next Next Next Next Next Next Next Next Next Next Next Next
+keycode 110 = Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert Insert
+keycode 111 = Remove Remove Remove Remove Remove Remove Boot Remove Remove Remove Remove Remove Boot Remove Boot Remove Remove Remove Remove Remove Remove Remove Boot Remove Remove Remove Remove Remove Boot Remove Boot Remove Remove Remove Remove Remove Remove Remove Boot Remove Remove Remove Remove Remove Boot Remove Boot Remove Remove Remove Remove Remove Remove Remove Boot Remove Remove Remove Remove Remove Boot Remove Boot Remove Remove Remove Remove Remove Remove Remove Boot Remove Remove Remove Remove Remove Boot Remove Boot Remove Remove Remove Remove Remove Remove Remove Boot Remove Remove Remove Remove Remove Boot Remove Boot Remove Remove Remove Remove Remove Remove Remove Boot Remove Remove Remove Remove Remove Boot Remove Boot Remove Remove Remove Remove Remove Remove Remove Boot Remove Remove Remove Remove Remove Boot Remove Boot Remove
+keycode 96 = KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter Hex_F KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter KP_Enter
+keycode 97 = Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control Control
+keycode 119 = Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause Pause
+keycode 99 = VoidSymbol VoidSymbol Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash VoidSymbol VoidSymbol Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash VoidSymbol VoidSymbol Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash VoidSymbol VoidSymbol Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash VoidSymbol VoidSymbol Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash VoidSymbol VoidSymbol Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash VoidSymbol VoidSymbol Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash VoidSymbol VoidSymbol Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash Control_backslash
+keycode 98 = KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide Hex_B KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide KP_Divide
+keycode 100 = Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt
+keycode 125 = Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt
+keycode 126 = Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt Alt
+keycode 121 = KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period KP_Period
+strings as usual
+# The content of this file will be appended to the keyboard layout.
+# For example if you uncomment the following lines Alt+j can be used
+# to go to the next console and Alt+k can be used to go to the
+# previous console:
+
+# alt keycode 36 = Incr_Console
+# shiftl alt keycode 36 = Incr_Console
+# shiftr alt keycode 36 = Incr_Console
+# shiftr shiftl alt keycode 36 = Incr_Console
+# ctrll alt keycode 36 = Incr_Console
+# ctrll shiftl alt keycode 36 = Incr_Console
+# ctrll shiftr alt keycode 36 = Incr_Console
+# ctrll shiftr shiftl alt keycode 36 = Incr_Console
+
+# alt keycode 37 = Decr_Console
+# shiftl alt keycode 37 = Decr_Console
+# shiftr alt keycode 37 = Decr_Console
+# shiftr shiftl alt keycode 37 = Decr_Console
+# ctrll alt keycode 37 = Decr_Console
+# ctrll shiftl alt keycode 37 = Decr_Console
+# ctrll shiftr alt keycode 37 = Decr_Console
+# ctrll shiftr shiftl alt keycode 37 = Decr_Console
+
diff --git a/resources/grub/keymap/usqwerty.gkb b/resources/grub/keymap/usqwerty.gkb
new file mode 100644
index 0000000..5fb78d3
--- /dev/null
+++ b/resources/grub/keymap/usqwerty.gkb
Binary files differ
diff --git a/resources/grub/patch/COPYING b/resources/grub/patch/COPYING
new file mode 100644
index 0000000..0a7d397
--- /dev/null
+++ b/resources/grub/patch/COPYING
@@ -0,0 +1,2 @@
+The "gifdiff" file is a patch for the GRUB project.
+Look at that project's copyright information to see what conditions apply.
diff --git a/resources/grub/patch/gitdiff b/resources/grub/patch/gitdiff
new file mode 100644
index 0000000..cb5681d
--- /dev/null
+++ b/resources/grub/patch/gitdiff
@@ -0,0 +1,13 @@
+diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c
+index 3a926fc..6d48c6a 100644
+--- a/grub-core/normal/main.c
++++ b/grub-core/normal/main.c
+@@ -208,7 +208,7 @@ grub_normal_init_page (struct grub_term_output *term,
+
+ grub_term_cls (term);
+
+- msg_formatted = grub_xasprintf (_("GNU GRUB version %s"), PACKAGE_VERSION);
++ msg_formatted = grub_xasprintf("FREE AS IN FREEDOM");
+ if (!msg_formatted)
+ return;
+
diff --git a/resources/libreboot/config/COPYING b/resources/libreboot/config/COPYING
new file mode 100644
index 0000000..6813883
--- /dev/null
+++ b/resources/libreboot/config/COPYING
@@ -0,0 +1,7 @@
+These files:
+ * macbook21config
+ * t60config
+ * x60config
+ * x60tconfig
+
+Are released to the public domain.
diff --git a/resources/libreboot/config/macbook21config b/resources/libreboot/config/macbook21config
new file mode 100644
index 0000000..63af035
--- /dev/null
+++ b/resources/libreboot/config/macbook21config
@@ -0,0 +1,436 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# coreboot configuration
+#
+
+#
+# General setup
+#
+CONFIG_EXPERT=y
+CONFIG_LOCALVERSION=" MB21.88Z.00A5.B07.0706270922"
+CONFIG_CBFS_PREFIX="fallback"
+CONFIG_COMPILER_GCC=y
+# CONFIG_COMPILER_LLVM_CLANG is not set
+# CONFIG_ANY_TOOLCHAIN is not set
+# CONFIG_CCACHE is not set
+# CONFIG_SCONFIG_GENPARSER is not set
+CONFIG_USE_OPTION_TABLE=y
+CONFIG_COMPRESS_RAMSTAGE=y
+CONFIG_INCLUDE_CONFIG_FILE=y
+CONFIG_EARLY_CBMEM_INIT=y
+# CONFIG_BROKEN_CAR_MIGRATE is not set
+# CONFIG_DYNAMIC_CBMEM is not set
+# CONFIG_COLLECT_TIMESTAMPS is not set
+# CONFIG_USE_BLOBS is not set
+# CONFIG_COVERAGE is not set
+
+#
+# Mainboard
+#
+# CONFIG_VENDOR_AAEON is not set
+# CONFIG_VENDOR_ABIT is not set
+# CONFIG_VENDOR_ADLINK is not set
+# CONFIG_VENDOR_ADVANSUS is not set
+# CONFIG_VENDOR_ADVANTECH is not set
+# CONFIG_VENDOR_AMD is not set
+# CONFIG_VENDOR_AOPEN is not set
+CONFIG_VENDOR_APPLE=y
+# CONFIG_VENDOR_ARIMA is not set
+# CONFIG_VENDOR_ARTECGROUP is not set
+# CONFIG_VENDOR_ASI is not set
+# CONFIG_VENDOR_ASROCK is not set
+# CONFIG_VENDOR_ASUS is not set
+# CONFIG_VENDOR_A_TREND is not set
+# CONFIG_VENDOR_AVALUE is not set
+# CONFIG_VENDOR_AXUS is not set
+# CONFIG_VENDOR_AZZA is not set
+# CONFIG_VENDOR_BACHMANN is not set
+# CONFIG_VENDOR_BCOM is not set
+# CONFIG_VENDOR_BIFFEROS is not set
+# CONFIG_VENDOR_BIOSTAR is not set
+# CONFIG_VENDOR_BROADCOM is not set
+# CONFIG_VENDOR_COMPAQ is not set
+# CONFIG_VENDOR_CUBIETECH is not set
+# CONFIG_VENDOR_DIGITALLOGIC is not set
+# CONFIG_VENDOR_DMP is not set
+# CONFIG_VENDOR_EAGLELION is not set
+# CONFIG_VENDOR_ECS is not set
+# CONFIG_VENDOR_EMULATION is not set
+# CONFIG_VENDOR_GETAC is not set
+# CONFIG_VENDOR_GIGABYTE is not set
+# CONFIG_VENDOR_GIZMOSPHERE is not set
+# CONFIG_VENDOR_GOOGLE is not set
+# CONFIG_VENDOR_HP is not set
+# CONFIG_VENDOR_IBASE is not set
+# CONFIG_VENDOR_IBM is not set
+# CONFIG_VENDOR_IEI is not set
+# CONFIG_VENDOR_INTEL is not set
+# CONFIG_VENDOR_IWAVE is not set
+# CONFIG_VENDOR_IWILL is not set
+# CONFIG_VENDOR_JETWAY is not set
+# CONFIG_VENDOR_KONTRON is not set
+# CONFIG_VENDOR_LANNER is not set
+# CONFIG_VENDOR_LENOVO is not set
+# CONFIG_VENDOR_LINUTOP is not set
+# CONFIG_VENDOR_LIPPERT is not set
+# CONFIG_VENDOR_MITAC is not set
+# CONFIG_VENDOR_MSI is not set
+# CONFIG_VENDOR_NEC is not set
+# CONFIG_VENDOR_NEWISYS is not set
+# CONFIG_VENDOR_NOKIA is not set
+# CONFIG_VENDOR_NVIDIA is not set
+# CONFIG_VENDOR_PACKARDBELL is not set
+# CONFIG_VENDOR_PCENGINES is not set
+# CONFIG_VENDOR_RCA is not set
+# CONFIG_VENDOR_RODA is not set
+# CONFIG_VENDOR_SAMSUNG is not set
+# CONFIG_VENDOR_SIEMENS is not set
+# CONFIG_VENDOR_SOYO is not set
+# CONFIG_VENDOR_SUNW is not set
+# CONFIG_VENDOR_SUPERMICRO is not set
+# CONFIG_VENDOR_TECHNEXION is not set
+# CONFIG_VENDOR_TECHNOLOGIC is not set
+# CONFIG_VENDOR_TELEVIDEO is not set
+# CONFIG_VENDOR_TI is not set
+# CONFIG_VENDOR_THOMSON is not set
+# CONFIG_VENDOR_TRAVERSE is not set
+# CONFIG_VENDOR_TYAN is not set
+# CONFIG_VENDOR_VIA is not set
+# CONFIG_VENDOR_WINENT is not set
+# CONFIG_VENDOR_WYSE is not set
+CONFIG_BOARD_SPECIFIC_OPTIONS=y
+CONFIG_MAINBOARD_DIR="apple/macbook21"
+CONFIG_MAINBOARD_PART_NUMBER="MacBook2,1"
+CONFIG_IRQ_SLOT_COUNT=18
+CONFIG_MAINBOARD_VENDOR="Apple"
+CONFIG_MAX_CPUS=2
+CONFIG_RAMTOP=0x200000
+CONFIG_HEAP_SIZE=0x4000
+CONFIG_RAMBASE=0x100000
+CONFIG_VGA_BIOS_ID="8086,27a2"
+CONFIG_DRIVERS_PS2_KEYBOARD=y
+# CONFIG_ONBOARD_VGA_IS_PRIMARY is not set
+# CONFIG_VGA_BIOS is not set
+# CONFIG_UDELAY_IO is not set
+CONFIG_DCACHE_RAM_BASE=0xffdf8000
+CONFIG_DCACHE_RAM_SIZE=0x8000
+CONFIG_ACPI_SSDTX_NUM=0
+CONFIG_BOARD_APPLE_MACBOOK21=y
+CONFIG_MMCONF_BASE_ADDRESS=0xf0000000
+CONFIG_MAINBOARD_SMBIOS_MANUFACTURER="Apple Inc."
+CONFIG_SEABIOS_PS2_TIMEOUT=3000
+# CONFIG_PCI_64BIT_PREF_MEM is not set
+CONFIG_UART_FOR_CONSOLE=0
+CONFIG_ID_SECTION_OFFSET=0x80
+# CONFIG_BOARD_EMULATION_QEMU_X86_I440FX is not set
+# CONFIG_BOARD_EMULATION_QEMU_X86_Q35 is not set
+# CONFIG_BOARD_EMULATION_QEMU_ARMV7 is not set
+CONFIG_STACK_SIZE=0x1000
+CONFIG_CACHE_ROM_SIZE_OVERRIDE=0
+CONFIG_CBFS_SIZE=0x200000
+CONFIG_MAINBOARD_VERSION="1.0"
+CONFIG_CPU_ADDR_BITS=32
+CONFIG_DEFAULT_CONSOLE_LOGLEVEL=8
+# CONFIG_USBDEBUG is not set
+CONFIG_MAXIMUM_SUPPORTED_FREQUENCY=0
+CONFIG_BOARD_ROMSIZE_KB_2048=y
+# CONFIG_COREBOOT_ROMSIZE_KB_64 is not set
+# CONFIG_COREBOOT_ROMSIZE_KB_128 is not set
+# CONFIG_COREBOOT_ROMSIZE_KB_256 is not set
+# CONFIG_COREBOOT_ROMSIZE_KB_512 is not set
+# CONFIG_COREBOOT_ROMSIZE_KB_1024 is not set
+CONFIG_COREBOOT_ROMSIZE_KB_2048=y
+# CONFIG_COREBOOT_ROMSIZE_KB_4096 is not set
+# CONFIG_COREBOOT_ROMSIZE_KB_8192 is not set
+# CONFIG_COREBOOT_ROMSIZE_KB_12288 is not set
+# CONFIG_COREBOOT_ROMSIZE_KB_16384 is not set
+CONFIG_COREBOOT_ROMSIZE_KB=2048
+CONFIG_ROM_SIZE=0x200000
+CONFIG_MAINBOARD_SERIAL_NUMBER="W8724XXXXXX"
+CONFIG_MAINBOARD_SMBIOS_PRODUCT_NAME="MacBook2,1"
+CONFIG_ARCH_X86=y
+# CONFIG_ARCH_ARMV7 is not set
+CONFIG_ARCH_BOOTBLOCK_X86_32=y
+CONFIG_ARCH_ROMSTAGE_X86_32=y
+CONFIG_ARCH_RAMSTAGE_X86_32=y
+CONFIG_AP_IN_SIPI_WAIT=y
+# CONFIG_SIPI_VECTOR_IN_ROM is not set
+CONFIG_NUM_IPI_STARTS=2
+# CONFIG_ROMCC is not set
+CONFIG_PC80_SYSTEM=y
+CONFIG_BOOTBLOCK_NORTHBRIDGE_INIT="northbridge/intel/i945/bootblock.c"
+CONFIG_HAVE_CMOS_DEFAULT=y
+CONFIG_CMOS_DEFAULT_FILE="src/mainboard/$(MAINBOARDDIR)/cmos.default"
+CONFIG_BOOTBLOCK_SOUTHBRIDGE_INIT="southbridge/intel/i82801gx/bootblock.c"
+CONFIG_IOAPIC_INTERRUPTS_ON_FSB=y
+# CONFIG_IOAPIC_INTERRUPTS_ON_APIC_SERIAL_BUS is not set
+CONFIG_HPET_ADDRESS=0xfed00000
+# CONFIG_ARCH_BOOTBLOCK_ARMV7 is not set
+# CONFIG_ARCH_ROMSTAGE_ARMV7 is not set
+# CONFIG_ARCH_RAMSTAGE_ARMV7 is not set
+# CONFIG_MAINBOARD_HAS_CHROMEOS is not set
+CONFIG_BOOTBLOCK_SIMPLE=y
+# CONFIG_BOOTBLOCK_NORMAL is not set
+CONFIG_BOOTBLOCK_SOURCE="bootblock_simple.c"
+# CONFIG_UPDATE_IMAGE is not set
+
+#
+# Chipset
+#
+
+#
+# CPU
+#
+# CONFIG_CPU_ALLWINNER_A10 is not set
+# CONFIG_CPU_ARMLTD_CORTEX_A9 is not set
+# CONFIG_CPU_SAMSUNG_EXYNOS5250 is not set
+# CONFIG_CPU_SAMSUNG_EXYNOS5420 is not set
+# CONFIG_CPU_TI_AM335X is not set
+CONFIG_SOCKET_SPECIFIC_OPTIONS=y
+CONFIG_XIP_ROM_SIZE=0x10000
+# CONFIG_CPU_AMD_AGESA is not set
+CONFIG_HIGH_SCRATCH_MEMORY_SIZE=0x0
+CONFIG_CPU_INTEL_MODEL_6EX=y
+CONFIG_CPU_INTEL_MODEL_6FX=y
+CONFIG_SMM_TSEG_SIZE=0
+CONFIG_CPU_INTEL_SOCKET_MFCPGA478=y
+CONFIG_SSE2=y
+# CONFIG_CPU_INTEL_FIRMWARE_INTERFACE_TABLE is not set
+# CONFIG_CPU_INTEL_TURBO_NOT_PACKAGE_SCOPED is not set
+# CONFIG_PARALLEL_CPU_INIT is not set
+CONFIG_UDELAY_LAPIC=y
+CONFIG_LAPIC_MONOTONIC_TIMER=y
+# CONFIG_UDELAY_TSC is not set
+# CONFIG_UDELAY_TIMER2 is not set
+# CONFIG_TSC_CALIBRATE_WITH_IO is not set
+# CONFIG_TSC_SYNC_LFENCE is not set
+CONFIG_TSC_SYNC_MFENCE=y
+CONFIG_LOGICAL_CPUS=y
+# CONFIG_SMM_TSEG is not set
+# CONFIG_SMM_MODULES is not set
+# CONFIG_X86_AMD_FIXED_MTRRS is not set
+# CONFIG_PLATFORM_USES_FSP is not set
+# CONFIG_PARALLEL_MP is not set
+# CONFIG_BACKUP_DEFAULT_SMM_REGION is not set
+# CONFIG_MIRROR_PAYLOAD_TO_RAM_BEFORE_LOADING is not set
+CONFIG_CACHE_AS_RAM=y
+CONFIG_SMP=y
+CONFIG_AP_SIPI_VECTOR=0xfffff000
+CONFIG_MMX=y
+CONFIG_SSE=y
+CONFIG_SUPPORT_CPU_UCODE_IN_CBFS=y
+# CONFIG_CPU_MICROCODE_CBFS_GENERATE is not set
+# CONFIG_CPU_MICROCODE_CBFS_EXTERNAL is not set
+CONFIG_CPU_MICROCODE_CBFS_NONE=y
+
+#
+# Northbridge
+#
+CONFIG_VIDEO_MB=0
+# CONFIG_NORTHBRIDGE_AMD_AGESA is not set
+# CONFIG_AMD_NB_CIMX is not set
+# CONFIG_NORTHBRIDGE_AMD_CIMX_RD890 is not set
+CONFIG_NORTHBRIDGE_SPECIFIC_OPTIONS=y
+CONFIG_NORTHBRIDGE_INTEL_I945=y
+# CONFIG_NORTHBRIDGE_INTEL_SUBTYPE_I945GC is not set
+CONFIG_NORTHBRIDGE_INTEL_SUBTYPE_I945GM=y
+CONFIG_CHANNEL_XOR_RANDOMIZATION=y
+# CONFIG_OVERRIDE_CLOCK_DISABLE is not set
+# CONFIG_CHECK_SLFRCS_ON_RESUME is not set
+CONFIG_HPET_MIN_TICKS=0x80
+CONFIG_MAX_PIRQ_LINKS=4
+
+#
+# Southbridge
+#
+CONFIG_EHCI_BAR=0xfef00000
+# CONFIG_AMD_SB_CIMX is not set
+# CONFIG_SOUTHBRIDGE_AMD_CIMX_SB800 is not set
+# CONFIG_SOUTHBRIDGE_AMD_CIMX_SB900 is not set
+CONFIG_SOUTHBRIDGE_INTEL_COMMON=y
+CONFIG_SOUTHBRIDGE_INTEL_I82801GX=y
+
+#
+# Super I/O
+#
+
+#
+# Embedded Controllers
+#
+
+#
+# SoC
+#
+
+#
+# Devices
+#
+CONFIG_MAINBOARD_HAS_NATIVE_VGA_INIT=y
+# CONFIG_MAINBOARD_HAS_NATIVE_VGA_INIT_TEXTMODECFG is not set
+CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT=y
+# CONFIG_VGA_ROM_RUN is not set
+# CONFIG_ON_DEVICE_ROM_RUN is not set
+# CONFIG_PCI_OPTION_ROM_RUN_REALMODE is not set
+# CONFIG_PCI_OPTION_ROM_RUN_YABEL is not set
+# CONFIG_MULTIPLE_VGA_ADAPTERS is not set
+CONFIG_PCI=y
+# CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT is not set
+CONFIG_PCIX_PLUGIN_SUPPORT=y
+CONFIG_PCIEXP_PLUGIN_SUPPORT=y
+CONFIG_AGP_PLUGIN_SUPPORT=y
+CONFIG_CARDBUS_PLUGIN_SUPPORT=y
+# CONFIG_AZALIA_PLUGIN_SUPPORT is not set
+# CONFIG_PCIEXP_COMMON_CLOCK is not set
+# CONFIG_PCIEXP_ASPM is not set
+CONFIG_PCI_BUS_SEGN_BITS=0
+# CONFIG_EARLY_PCI_BRIDGE is not set
+
+#
+# VGA BIOS
+#
+
+#
+# Display
+#
+
+#
+# PXE ROM
+#
+# CONFIG_PXE_ROM is not set
+CONFIG_SUBSYSTEM_VENDOR_ID=0x0000
+CONFIG_SUBSYSTEM_DEVICE_ID=0x0000
+
+#
+# Generic Drivers
+#
+# CONFIG_DRIVERS_I2C_RTD2132 is not set
+# CONFIG_INTEL_DP is not set
+# CONFIG_INTEL_DDI is not set
+CONFIG_INTEL_EDID=y
+# CONFIG_IPMI_KCS is not set
+# CONFIG_DRIVERS_LENOVO_WACOM is not set
+# CONFIG_DRIVER_MAXIM_MAX77686 is not set
+# CONFIG_DRIVER_PARADE_PS8625 is not set
+# CONFIG_TPM is not set
+# CONFIG_DRIVERS_SIL_3114 is not set
+# CONFIG_SPI_FLASH is not set
+# CONFIG_DRIVER_TI_TPS65090 is not set
+CONFIG_DRIVERS_UART=y
+CONFIG_DRIVERS_UART_8250IO=y
+# CONFIG_NO_UART_ON_SUPERIO is not set
+# CONFIG_DRIVERS_UART_8250MEM is not set
+# CONFIG_HAVE_UART_SPECIAL is not set
+# CONFIG_DRIVERS_UART_OXPCIE is not set
+# CONFIG_DRIVERS_UART_PL011 is not set
+CONFIG_HAVE_USBDEBUG=y
+# CONFIG_HAVE_USBDEBUG_OPTIONS is not set
+# CONFIG_DRIVER_XPOWERS_AXP209 is not set
+CONFIG_MMCONF_SUPPORT_DEFAULT=y
+CONFIG_MMCONF_SUPPORT=y
+# CONFIG_BOOTMODE_STRAPS is not set
+
+#
+# Console
+#
+CONFIG_SQUELCH_EARLY_SMP=y
+CONFIG_CONSOLE_SERIAL=y
+
+#
+# I/O mapped, 8250-compatible
+#
+CONFIG_TTYS0_BASE=0x3f8
+CONFIG_CONSOLE_SERIAL_115200=y
+# CONFIG_CONSOLE_SERIAL_57600 is not set
+# CONFIG_CONSOLE_SERIAL_38400 is not set
+# CONFIG_CONSOLE_SERIAL_19200 is not set
+# CONFIG_CONSOLE_SERIAL_9600 is not set
+CONFIG_TTYS0_BAUD=115200
+CONFIG_TTYS0_LCS=3
+# CONFIG_SPKMODEM is not set
+# CONFIG_CONSOLE_NE2K is not set
+CONFIG_CONSOLE_CBMEM=y
+CONFIG_CONSOLE_CBMEM_BUFFER_SIZE=0x10000
+CONFIG_CONSOLE_CAR_BUFFER_SIZE=0xc00
+CONFIG_DEFAULT_CONSOLE_LOGLEVEL_8=y
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_7 is not set
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_6 is not set
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_5 is not set
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_4 is not set
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_3 is not set
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_2 is not set
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_1 is not set
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_0 is not set
+# CONFIG_NO_POST is not set
+# CONFIG_CMOS_POST is not set
+# CONFIG_POST_IO is not set
+CONFIG_POST_DEVICE=y
+CONFIG_POST_DEVICE_NONE=y
+# CONFIG_POST_DEVICE_LPC is not set
+# CONFIG_POST_DEVICE_PCI_PCIE is not set
+CONFIG_HAVE_ACPI_RESUME=y
+# CONFIG_HAVE_ACPI_SLIC is not set
+CONFIG_HAVE_HARD_RESET=y
+CONFIG_HAVE_MONOTONIC_TIMER=y
+# CONFIG_TIMER_QUEUE is not set
+CONFIG_HAVE_OPTION_TABLE=y
+# CONFIG_PIRQ_ROUTE is not set
+CONFIG_HAVE_SMI_HANDLER=y
+# CONFIG_PCI_IO_CFG_EXT is not set
+CONFIG_IOAPIC=y
+CONFIG_USE_WATCHDOG_ON_BOOT=y
+# CONFIG_VGA is not set
+# CONFIG_GFXUMA is not set
+# CONFIG_RELOCATABLE_MODULES is not set
+# CONFIG_HAVE_REFCODE_BLOB is not set
+CONFIG_HAVE_ACPI_TABLES=y
+CONFIG_HAVE_MP_TABLE=y
+CONFIG_HAVE_PIRQ_TABLE=y
+
+#
+# System tables
+#
+CONFIG_GENERATE_ACPI_TABLES=y
+CONFIG_GENERATE_MP_TABLE=y
+CONFIG_GENERATE_PIRQ_TABLE=y
+CONFIG_GENERATE_SMBIOS_TABLES=y
+
+#
+# Payload
+#
+# CONFIG_PAYLOAD_NONE is not set
+CONFIG_PAYLOAD_ELF=y
+# CONFIG_PAYLOAD_LINUX is not set
+# CONFIG_PAYLOAD_SEABIOS is not set
+# CONFIG_PAYLOAD_FILO is not set
+# CONFIG_PAYLOAD_GRUB2 is not set
+# CONFIG_PAYLOAD_TIANOCORE is not set
+# CONFIG_SEABIOS_STABLE is not set
+# CONFIG_SEABIOS_MASTER is not set
+# CONFIG_SEABIOS_THREAD_OPTIONROMS is not set
+CONFIG_PAYLOAD_FILE="grub.elf"
+CONFIG_COMPRESSED_PAYLOAD_LZMA=y
+
+#
+# Debugging
+#
+# CONFIG_GDB_STUB is not set
+# CONFIG_DEBUG_CBFS is not set
+CONFIG_HAVE_DEBUG_RAM_SETUP=y
+# CONFIG_DEBUG_RAM_SETUP is not set
+# CONFIG_HAVE_DEBUG_CAR is not set
+# CONFIG_DEBUG_PIRQ is not set
+# CONFIG_HAVE_DEBUG_SMBUS is not set
+# CONFIG_DEBUG_SMI is not set
+# CONFIG_DEBUG_SMM_RELOCATION is not set
+# CONFIG_DEBUG_MALLOC is not set
+# CONFIG_DEBUG_ACPI is not set
+# CONFIG_TRACE is not set
+# CONFIG_ENABLE_APIC_EXT_ID is not set
+CONFIG_WARNINGS_ARE_ERRORS=y
+# CONFIG_POWER_BUTTON_DEFAULT_ENABLE is not set
+# CONFIG_POWER_BUTTON_DEFAULT_DISABLE is not set
+# CONFIG_POWER_BUTTON_FORCE_ENABLE is not set
+# CONFIG_POWER_BUTTON_FORCE_DISABLE is not set
+# CONFIG_POWER_BUTTON_IS_OPTIONAL is not set
+CONFIG_REG_SCRIPT=y
+CONFIG_MAX_REBOOT_CNT=3
diff --git a/resources/libreboot/config/t60config b/resources/libreboot/config/t60config
new file mode 100644
index 0000000..d5754ff
--- /dev/null
+++ b/resources/libreboot/config/t60config
@@ -0,0 +1,449 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# coreboot configuration
+#
+
+#
+# General setup
+#
+CONFIG_EXPERT=y
+CONFIG_LOCALVERSION="79ETE7WW (2.27 )"
+CONFIG_CBFS_PREFIX="fallback"
+CONFIG_COMPILER_GCC=y
+# CONFIG_COMPILER_LLVM_CLANG is not set
+# CONFIG_ANY_TOOLCHAIN is not set
+# CONFIG_CCACHE is not set
+# CONFIG_SCONFIG_GENPARSER is not set
+# CONFIG_USE_OPTION_TABLE is not set
+CONFIG_COMPRESS_RAMSTAGE=y
+CONFIG_INCLUDE_CONFIG_FILE=y
+CONFIG_EARLY_CBMEM_INIT=y
+# CONFIG_BROKEN_CAR_MIGRATE is not set
+# CONFIG_DYNAMIC_CBMEM is not set
+# CONFIG_COLLECT_TIMESTAMPS is not set
+# CONFIG_USE_BLOBS is not set
+# CONFIG_COVERAGE is not set
+
+#
+# Mainboard
+#
+# CONFIG_VENDOR_AAEON is not set
+# CONFIG_VENDOR_ABIT is not set
+# CONFIG_VENDOR_ADLINK is not set
+# CONFIG_VENDOR_ADVANSUS is not set
+# CONFIG_VENDOR_ADVANTECH is not set
+# CONFIG_VENDOR_AMD is not set
+# CONFIG_VENDOR_AOPEN is not set
+# CONFIG_VENDOR_APPLE is not set
+# CONFIG_VENDOR_ARIMA is not set
+# CONFIG_VENDOR_ARTECGROUP is not set
+# CONFIG_VENDOR_ASI is not set
+# CONFIG_VENDOR_ASROCK is not set
+# CONFIG_VENDOR_ASUS is not set
+# CONFIG_VENDOR_A_TREND is not set
+# CONFIG_VENDOR_AVALUE is not set
+# CONFIG_VENDOR_AXUS is not set
+# CONFIG_VENDOR_AZZA is not set
+# CONFIG_VENDOR_BACHMANN is not set
+# CONFIG_VENDOR_BCOM is not set
+# CONFIG_VENDOR_BIFFEROS is not set
+# CONFIG_VENDOR_BIOSTAR is not set
+# CONFIG_VENDOR_BROADCOM is not set
+# CONFIG_VENDOR_COMPAQ is not set
+# CONFIG_VENDOR_CUBIETECH is not set
+# CONFIG_VENDOR_DIGITALLOGIC is not set
+# CONFIG_VENDOR_DMP is not set
+# CONFIG_VENDOR_EAGLELION is not set
+# CONFIG_VENDOR_ECS is not set
+# CONFIG_VENDOR_EMULATION is not set
+# CONFIG_VENDOR_GETAC is not set
+# CONFIG_VENDOR_GIGABYTE is not set
+# CONFIG_VENDOR_GIZMOSPHERE is not set
+# CONFIG_VENDOR_GOOGLE is not set
+# CONFIG_VENDOR_HP is not set
+# CONFIG_VENDOR_IBASE is not set
+# CONFIG_VENDOR_IBM is not set
+# CONFIG_VENDOR_IEI is not set
+# CONFIG_VENDOR_INTEL is not set
+# CONFIG_VENDOR_IWAVE is not set
+# CONFIG_VENDOR_IWILL is not set
+# CONFIG_VENDOR_JETWAY is not set
+# CONFIG_VENDOR_KONTRON is not set
+# CONFIG_VENDOR_LANNER is not set
+CONFIG_VENDOR_LENOVO=y
+# CONFIG_VENDOR_LINUTOP is not set
+# CONFIG_VENDOR_LIPPERT is not set
+# CONFIG_VENDOR_MITAC is not set
+# CONFIG_VENDOR_MSI is not set
+# CONFIG_VENDOR_NEC is not set
+# CONFIG_VENDOR_NEWISYS is not set
+# CONFIG_VENDOR_NOKIA is not set
+# CONFIG_VENDOR_NVIDIA is not set
+# CONFIG_VENDOR_PACKARDBELL is not set
+# CONFIG_VENDOR_PCENGINES is not set
+# CONFIG_VENDOR_RCA is not set
+# CONFIG_VENDOR_RODA is not set
+# CONFIG_VENDOR_SAMSUNG is not set
+# CONFIG_VENDOR_SIEMENS is not set
+# CONFIG_VENDOR_SOYO is not set
+# CONFIG_VENDOR_SUNW is not set
+# CONFIG_VENDOR_SUPERMICRO is not set
+# CONFIG_VENDOR_TECHNEXION is not set
+# CONFIG_VENDOR_TECHNOLOGIC is not set
+# CONFIG_VENDOR_TELEVIDEO is not set
+# CONFIG_VENDOR_TI is not set
+# CONFIG_VENDOR_THOMSON is not set
+# CONFIG_VENDOR_TRAVERSE is not set
+# CONFIG_VENDOR_TYAN is not set
+# CONFIG_VENDOR_VIA is not set
+# CONFIG_VENDOR_WINENT is not set
+# CONFIG_VENDOR_WYSE is not set
+CONFIG_BOARD_SPECIFIC_OPTIONS=y
+CONFIG_MAINBOARD_DIR="lenovo/t60"
+CONFIG_MAINBOARD_PART_NUMBER="ThinkPad T60 / T60p"
+CONFIG_IRQ_SLOT_COUNT=18
+CONFIG_MAINBOARD_VENDOR="Lenovo"
+CONFIG_MAX_CPUS=2
+CONFIG_RAMTOP=0x200000
+CONFIG_HEAP_SIZE=0x4000
+CONFIG_RAMBASE=0x100000
+CONFIG_VGA_BIOS_ID="8086,27a2"
+CONFIG_DRIVERS_PS2_KEYBOARD=y
+# CONFIG_ONBOARD_VGA_IS_PRIMARY is not set
+# CONFIG_VGA_BIOS is not set
+# CONFIG_UDELAY_IO is not set
+CONFIG_DCACHE_RAM_BASE=0xffdf8000
+CONFIG_DCACHE_RAM_SIZE=0x8000
+CONFIG_ACPI_SSDTX_NUM=0
+CONFIG_MMCONF_BASE_ADDRESS=0xf0000000
+CONFIG_MAINBOARD_SMBIOS_MANUFACTURER="LENOVO"
+CONFIG_SEABIOS_PS2_TIMEOUT=3000
+# CONFIG_PCI_64BIT_PREF_MEM is not set
+CONFIG_UART_FOR_CONSOLE=0
+CONFIG_ID_SECTION_OFFSET=0x80
+# CONFIG_BOARD_EMULATION_QEMU_X86_I440FX is not set
+# CONFIG_BOARD_EMULATION_QEMU_X86_Q35 is not set
+# CONFIG_BOARD_EMULATION_QEMU_ARMV7 is not set
+CONFIG_STACK_SIZE=0x1000
+CONFIG_CACHE_ROM_SIZE_OVERRIDE=0
+CONFIG_CBFS_SIZE=0x200000
+# CONFIG_BOARD_LENOVO_X60 is not set
+# CONFIG_BOARD_LENOVO_X201 is not set
+# CONFIG_BOARD_LENOVO_X230 is not set
+# CONFIG_BOARD_LENOVO_T520 is not set
+# CONFIG_BOARD_LENOVO_T530 is not set
+CONFIG_BOARD_LENOVO_T60=y
+CONFIG_MAINBOARD_VERSION="ThinkPad T60"
+CONFIG_CPU_ADDR_BITS=32
+CONFIG_DEFAULT_CONSOLE_LOGLEVEL=8
+# CONFIG_USBDEBUG is not set
+CONFIG_MAXIMUM_SUPPORTED_FREQUENCY=0
+CONFIG_BOARD_ROMSIZE_KB_2048=y
+# CONFIG_COREBOOT_ROMSIZE_KB_64 is not set
+# CONFIG_COREBOOT_ROMSIZE_KB_128 is not set
+# CONFIG_COREBOOT_ROMSIZE_KB_256 is not set
+# CONFIG_COREBOOT_ROMSIZE_KB_512 is not set
+# CONFIG_COREBOOT_ROMSIZE_KB_1024 is not set
+CONFIG_COREBOOT_ROMSIZE_KB_2048=y
+# CONFIG_COREBOOT_ROMSIZE_KB_4096 is not set
+# CONFIG_COREBOOT_ROMSIZE_KB_8192 is not set
+# CONFIG_COREBOOT_ROMSIZE_KB_12288 is not set
+# CONFIG_COREBOOT_ROMSIZE_KB_16384 is not set
+CONFIG_COREBOOT_ROMSIZE_KB=2048
+CONFIG_ROM_SIZE=0x200000
+CONFIG_MAINBOARD_SERIAL_NUMBER="L3DKE06"
+CONFIG_MAINBOARD_SMBIOS_PRODUCT_NAME="1951FEG"
+CONFIG_ARCH_X86=y
+# CONFIG_ARCH_ARMV7 is not set
+CONFIG_ARCH_BOOTBLOCK_X86_32=y
+CONFIG_ARCH_ROMSTAGE_X86_32=y
+CONFIG_ARCH_RAMSTAGE_X86_32=y
+CONFIG_AP_IN_SIPI_WAIT=y
+# CONFIG_SIPI_VECTOR_IN_ROM is not set
+CONFIG_NUM_IPI_STARTS=2
+# CONFIG_ROMCC is not set
+CONFIG_PC80_SYSTEM=y
+CONFIG_BOOTBLOCK_NORTHBRIDGE_INIT="northbridge/intel/i945/bootblock.c"
+CONFIG_HAVE_CMOS_DEFAULT=y
+CONFIG_CMOS_DEFAULT_FILE="src/mainboard/$(MAINBOARDDIR)/cmos.default"
+CONFIG_BOOTBLOCK_SOUTHBRIDGE_INIT="southbridge/intel/i82801gx/bootblock.c"
+CONFIG_IOAPIC_INTERRUPTS_ON_FSB=y
+# CONFIG_IOAPIC_INTERRUPTS_ON_APIC_SERIAL_BUS is not set
+CONFIG_HPET_ADDRESS=0xfed00000
+# CONFIG_ARCH_BOOTBLOCK_ARMV7 is not set
+# CONFIG_ARCH_ROMSTAGE_ARMV7 is not set
+# CONFIG_ARCH_RAMSTAGE_ARMV7 is not set
+# CONFIG_MAINBOARD_HAS_CHROMEOS is not set
+CONFIG_BOOTBLOCK_SIMPLE=y
+# CONFIG_BOOTBLOCK_NORMAL is not set
+CONFIG_BOOTBLOCK_SOURCE="bootblock_simple.c"
+# CONFIG_UPDATE_IMAGE is not set
+
+#
+# Chipset
+#
+
+#
+# CPU
+#
+# CONFIG_CPU_ALLWINNER_A10 is not set
+# CONFIG_CPU_ARMLTD_CORTEX_A9 is not set
+# CONFIG_CPU_SAMSUNG_EXYNOS5250 is not set
+# CONFIG_CPU_SAMSUNG_EXYNOS5420 is not set
+# CONFIG_CPU_TI_AM335X is not set
+CONFIG_SOCKET_SPECIFIC_OPTIONS=y
+CONFIG_XIP_ROM_SIZE=0x10000
+# CONFIG_CPU_AMD_AGESA is not set
+CONFIG_HIGH_SCRATCH_MEMORY_SIZE=0x0
+CONFIG_CPU_INTEL_MODEL_6EX=y
+CONFIG_CPU_INTEL_MODEL_6FX=y
+CONFIG_SMM_TSEG_SIZE=0
+CONFIG_CPU_INTEL_SOCKET_MFCPGA478=y
+CONFIG_SSE2=y
+# CONFIG_CPU_INTEL_FIRMWARE_INTERFACE_TABLE is not set
+# CONFIG_CPU_INTEL_TURBO_NOT_PACKAGE_SCOPED is not set
+# CONFIG_PARALLEL_CPU_INIT is not set
+CONFIG_UDELAY_LAPIC=y
+CONFIG_LAPIC_MONOTONIC_TIMER=y
+# CONFIG_UDELAY_TSC is not set
+# CONFIG_UDELAY_TIMER2 is not set
+# CONFIG_TSC_CALIBRATE_WITH_IO is not set
+# CONFIG_TSC_SYNC_LFENCE is not set
+CONFIG_TSC_SYNC_MFENCE=y
+CONFIG_LOGICAL_CPUS=y
+# CONFIG_SMM_TSEG is not set
+# CONFIG_SMM_MODULES is not set
+# CONFIG_X86_AMD_FIXED_MTRRS is not set
+# CONFIG_PLATFORM_USES_FSP is not set
+# CONFIG_PARALLEL_MP is not set
+# CONFIG_BACKUP_DEFAULT_SMM_REGION is not set
+# CONFIG_MIRROR_PAYLOAD_TO_RAM_BEFORE_LOADING is not set
+CONFIG_CACHE_AS_RAM=y
+CONFIG_SMP=y
+CONFIG_AP_SIPI_VECTOR=0xfffff000
+CONFIG_MMX=y
+CONFIG_SSE=y
+CONFIG_SUPPORT_CPU_UCODE_IN_CBFS=y
+# CONFIG_CPU_MICROCODE_CBFS_GENERATE is not set
+# CONFIG_CPU_MICROCODE_CBFS_EXTERNAL is not set
+CONFIG_CPU_MICROCODE_CBFS_NONE=y
+
+#
+# Northbridge
+#
+CONFIG_VIDEO_MB=0
+# CONFIG_NORTHBRIDGE_AMD_AGESA is not set
+# CONFIG_AMD_NB_CIMX is not set
+# CONFIG_NORTHBRIDGE_AMD_CIMX_RD890 is not set
+CONFIG_NORTHBRIDGE_SPECIFIC_OPTIONS=y
+CONFIG_NORTHBRIDGE_INTEL_I945=y
+# CONFIG_NORTHBRIDGE_INTEL_SUBTYPE_I945GC is not set
+CONFIG_NORTHBRIDGE_INTEL_SUBTYPE_I945GM=y
+CONFIG_CHANNEL_XOR_RANDOMIZATION=y
+# CONFIG_OVERRIDE_CLOCK_DISABLE is not set
+# CONFIG_CHECK_SLFRCS_ON_RESUME is not set
+CONFIG_HPET_MIN_TICKS=0x80
+CONFIG_MAX_PIRQ_LINKS=4
+
+#
+# Southbridge
+#
+CONFIG_EHCI_BAR=0xfef00000
+# CONFIG_AMD_SB_CIMX is not set
+# CONFIG_SOUTHBRIDGE_AMD_CIMX_SB800 is not set
+# CONFIG_SOUTHBRIDGE_AMD_CIMX_SB900 is not set
+CONFIG_SOUTHBRIDGE_INTEL_COMMON=y
+CONFIG_SOUTHBRIDGE_INTEL_I82801GX=y
+CONFIG_SOUTHBRIDGE_TI_PCI1X2X=y
+
+#
+# Super I/O
+#
+CONFIG_SUPERIO_NSC_PC87382=y
+CONFIG_SUPERIO_NSC_PC87384=y
+
+#
+# Embedded Controllers
+#
+CONFIG_EC_ACPI=y
+CONFIG_EC_LENOVO_H8=y
+CONFIG_H8_DOCK_EARLY_INIT=y
+CONFIG_EC_LENOVO_PMH7=y
+
+#
+# SoC
+#
+
+#
+# Devices
+#
+CONFIG_MAINBOARD_HAS_NATIVE_VGA_INIT=y
+# CONFIG_MAINBOARD_HAS_NATIVE_VGA_INIT_TEXTMODECFG is not set
+CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT=y
+# CONFIG_VGA_ROM_RUN is not set
+# CONFIG_ON_DEVICE_ROM_RUN is not set
+# CONFIG_PCI_OPTION_ROM_RUN_REALMODE is not set
+# CONFIG_PCI_OPTION_ROM_RUN_YABEL is not set
+# CONFIG_MULTIPLE_VGA_ADAPTERS is not set
+CONFIG_PCI=y
+# CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT is not set
+CONFIG_PCIX_PLUGIN_SUPPORT=y
+CONFIG_PCIEXP_PLUGIN_SUPPORT=y
+CONFIG_AGP_PLUGIN_SUPPORT=y
+CONFIG_CARDBUS_PLUGIN_SUPPORT=y
+# CONFIG_AZALIA_PLUGIN_SUPPORT is not set
+# CONFIG_PCIEXP_COMMON_CLOCK is not set
+# CONFIG_PCIEXP_ASPM is not set
+CONFIG_PCI_BUS_SEGN_BITS=0
+# CONFIG_EARLY_PCI_BRIDGE is not set
+
+#
+# VGA BIOS
+#
+
+#
+# Display
+#
+
+#
+# PXE ROM
+#
+# CONFIG_PXE_ROM is not set
+CONFIG_SUBSYSTEM_VENDOR_ID=0x0000
+CONFIG_SUBSYSTEM_DEVICE_ID=0x0000
+
+#
+# Generic Drivers
+#
+# CONFIG_DRIVERS_I2C_RTD2132 is not set
+CONFIG_DRIVERS_ICS_954309=y
+# CONFIG_INTEL_DP is not set
+# CONFIG_INTEL_DDI is not set
+CONFIG_INTEL_EDID=y
+# CONFIG_IPMI_KCS is not set
+# CONFIG_DRIVERS_LENOVO_WACOM is not set
+# CONFIG_DRIVER_MAXIM_MAX77686 is not set
+# CONFIG_DRIVER_PARADE_PS8625 is not set
+# CONFIG_TPM is not set
+# CONFIG_DRIVERS_SIL_3114 is not set
+# CONFIG_SPI_FLASH is not set
+# CONFIG_DRIVER_TI_TPS65090 is not set
+CONFIG_DRIVERS_UART=y
+CONFIG_DRIVERS_UART_8250IO=y
+# CONFIG_NO_UART_ON_SUPERIO is not set
+# CONFIG_DRIVERS_UART_8250MEM is not set
+# CONFIG_HAVE_UART_SPECIAL is not set
+# CONFIG_DRIVERS_UART_OXPCIE is not set
+# CONFIG_DRIVERS_UART_PL011 is not set
+CONFIG_HAVE_USBDEBUG=y
+# CONFIG_HAVE_USBDEBUG_OPTIONS is not set
+# CONFIG_DRIVER_XPOWERS_AXP209 is not set
+CONFIG_MMCONF_SUPPORT_DEFAULT=y
+CONFIG_MMCONF_SUPPORT=y
+# CONFIG_BOOTMODE_STRAPS is not set
+
+#
+# Console
+#
+CONFIG_SQUELCH_EARLY_SMP=y
+CONFIG_CONSOLE_SERIAL=y
+
+#
+# I/O mapped, 8250-compatible
+#
+CONFIG_TTYS0_BASE=0x3f8
+CONFIG_CONSOLE_SERIAL_115200=y
+# CONFIG_CONSOLE_SERIAL_57600 is not set
+# CONFIG_CONSOLE_SERIAL_38400 is not set
+# CONFIG_CONSOLE_SERIAL_19200 is not set
+# CONFIG_CONSOLE_SERIAL_9600 is not set
+CONFIG_TTYS0_BAUD=115200
+CONFIG_TTYS0_LCS=3
+# CONFIG_SPKMODEM is not set
+# CONFIG_CONSOLE_NE2K is not set
+CONFIG_CONSOLE_CBMEM=y
+CONFIG_CONSOLE_CBMEM_BUFFER_SIZE=0x10000
+CONFIG_CONSOLE_CAR_BUFFER_SIZE=0xc00
+CONFIG_DEFAULT_CONSOLE_LOGLEVEL_8=y
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_7 is not set
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_6 is not set
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_5 is not set
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_4 is not set
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_3 is not set
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_2 is not set
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_1 is not set
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_0 is not set
+# CONFIG_NO_POST is not set
+# CONFIG_CMOS_POST is not set
+# CONFIG_POST_IO is not set
+CONFIG_POST_DEVICE=y
+CONFIG_POST_DEVICE_NONE=y
+# CONFIG_POST_DEVICE_LPC is not set
+# CONFIG_POST_DEVICE_PCI_PCIE is not set
+CONFIG_HAVE_ACPI_RESUME=y
+# CONFIG_HAVE_ACPI_SLIC is not set
+CONFIG_HAVE_HARD_RESET=y
+CONFIG_HAVE_MONOTONIC_TIMER=y
+# CONFIG_TIMER_QUEUE is not set
+CONFIG_HAVE_OPTION_TABLE=y
+# CONFIG_PIRQ_ROUTE is not set
+CONFIG_HAVE_SMI_HANDLER=y
+# CONFIG_PCI_IO_CFG_EXT is not set
+CONFIG_IOAPIC=y
+CONFIG_USE_WATCHDOG_ON_BOOT=y
+# CONFIG_VGA is not set
+# CONFIG_GFXUMA is not set
+# CONFIG_RELOCATABLE_MODULES is not set
+# CONFIG_HAVE_REFCODE_BLOB is not set
+CONFIG_HAVE_ACPI_TABLES=y
+CONFIG_HAVE_MP_TABLE=y
+CONFIG_HAVE_PIRQ_TABLE=y
+
+#
+# System tables
+#
+CONFIG_GENERATE_ACPI_TABLES=y
+CONFIG_GENERATE_MP_TABLE=y
+CONFIG_GENERATE_PIRQ_TABLE=y
+CONFIG_GENERATE_SMBIOS_TABLES=y
+
+#
+# Payload
+#
+# CONFIG_PAYLOAD_NONE is not set
+CONFIG_PAYLOAD_ELF=y
+# CONFIG_PAYLOAD_LINUX is not set
+# CONFIG_PAYLOAD_SEABIOS is not set
+# CONFIG_PAYLOAD_FILO is not set
+# CONFIG_PAYLOAD_GRUB2 is not set
+# CONFIG_PAYLOAD_TIANOCORE is not set
+# CONFIG_SEABIOS_STABLE is not set
+# CONFIG_SEABIOS_MASTER is not set
+# CONFIG_SEABIOS_THREAD_OPTIONROMS is not set
+CONFIG_PAYLOAD_FILE="grub.elf"
+CONFIG_COMPRESSED_PAYLOAD_LZMA=y
+
+#
+# Debugging
+#
+# CONFIG_GDB_STUB is not set
+# CONFIG_DEBUG_CBFS is not set
+CONFIG_HAVE_DEBUG_RAM_SETUP=y
+# CONFIG_DEBUG_RAM_SETUP is not set
+# CONFIG_HAVE_DEBUG_CAR is not set
+# CONFIG_DEBUG_PIRQ is not set
+# CONFIG_HAVE_DEBUG_SMBUS is not set
+# CONFIG_DEBUG_SMI is not set
+# CONFIG_DEBUG_SMM_RELOCATION is not set
+# CONFIG_DEBUG_MALLOC is not set
+# CONFIG_DEBUG_ACPI is not set
+# CONFIG_TRACE is not set
+# CONFIG_ENABLE_APIC_EXT_ID is not set
+CONFIG_WARNINGS_ARE_ERRORS=y
+# CONFIG_POWER_BUTTON_DEFAULT_ENABLE is not set
+# CONFIG_POWER_BUTTON_DEFAULT_DISABLE is not set
+# CONFIG_POWER_BUTTON_FORCE_ENABLE is not set
+# CONFIG_POWER_BUTTON_FORCE_DISABLE is not set
+# CONFIG_POWER_BUTTON_IS_OPTIONAL is not set
+CONFIG_REG_SCRIPT=y
+CONFIG_MAX_REBOOT_CNT=3
diff --git a/resources/libreboot/config/x60config b/resources/libreboot/config/x60config
new file mode 100644
index 0000000..fe56ceb
--- /dev/null
+++ b/resources/libreboot/config/x60config
@@ -0,0 +1,452 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# coreboot configuration
+#
+
+#
+# General setup
+#
+CONFIG_EXPERT=y
+CONFIG_LOCALVERSION="7BETC7WW (2.08 )"
+CONFIG_CBFS_PREFIX="fallback"
+CONFIG_COMPILER_GCC=y
+# CONFIG_COMPILER_LLVM_CLANG is not set
+# CONFIG_ANY_TOOLCHAIN is not set
+# CONFIG_CCACHE is not set
+# CONFIG_SCONFIG_GENPARSER is not set
+CONFIG_USE_OPTION_TABLE=y
+CONFIG_COMPRESS_RAMSTAGE=y
+CONFIG_INCLUDE_CONFIG_FILE=y
+CONFIG_EARLY_CBMEM_INIT=y
+# CONFIG_BROKEN_CAR_MIGRATE is not set
+# CONFIG_DYNAMIC_CBMEM is not set
+# CONFIG_COLLECT_TIMESTAMPS is not set
+# CONFIG_USE_BLOBS is not set
+# CONFIG_COVERAGE is not set
+
+#
+# Mainboard
+#
+# CONFIG_VENDOR_AAEON is not set
+# CONFIG_VENDOR_ABIT is not set
+# CONFIG_VENDOR_ADLINK is not set
+# CONFIG_VENDOR_ADVANSUS is not set
+# CONFIG_VENDOR_ADVANTECH is not set
+# CONFIG_VENDOR_AMD is not set
+# CONFIG_VENDOR_AOPEN is not set
+# CONFIG_VENDOR_APPLE is not set
+# CONFIG_VENDOR_ARIMA is not set
+# CONFIG_VENDOR_ARTECGROUP is not set
+# CONFIG_VENDOR_ASI is not set
+# CONFIG_VENDOR_ASROCK is not set
+# CONFIG_VENDOR_ASUS is not set
+# CONFIG_VENDOR_A_TREND is not set
+# CONFIG_VENDOR_AVALUE is not set
+# CONFIG_VENDOR_AXUS is not set
+# CONFIG_VENDOR_AZZA is not set
+# CONFIG_VENDOR_BACHMANN is not set
+# CONFIG_VENDOR_BCOM is not set
+# CONFIG_VENDOR_BIFFEROS is not set
+# CONFIG_VENDOR_BIOSTAR is not set
+# CONFIG_VENDOR_BROADCOM is not set
+# CONFIG_VENDOR_COMPAQ is not set
+# CONFIG_VENDOR_CUBIETECH is not set
+# CONFIG_VENDOR_DIGITALLOGIC is not set
+# CONFIG_VENDOR_DMP is not set
+# CONFIG_VENDOR_EAGLELION is not set
+# CONFIG_VENDOR_ECS is not set
+# CONFIG_VENDOR_EMULATION is not set
+# CONFIG_VENDOR_GETAC is not set
+# CONFIG_VENDOR_GIGABYTE is not set
+# CONFIG_VENDOR_GIZMOSPHERE is not set
+# CONFIG_VENDOR_GOOGLE is not set
+# CONFIG_VENDOR_HP is not set
+# CONFIG_VENDOR_IBASE is not set
+# CONFIG_VENDOR_IBM is not set
+# CONFIG_VENDOR_IEI is not set
+# CONFIG_VENDOR_INTEL is not set
+# CONFIG_VENDOR_IWAVE is not set
+# CONFIG_VENDOR_IWILL is not set
+# CONFIG_VENDOR_JETWAY is not set
+# CONFIG_VENDOR_KONTRON is not set
+# CONFIG_VENDOR_LANNER is not set
+CONFIG_VENDOR_LENOVO=y
+# CONFIG_VENDOR_LINUTOP is not set
+# CONFIG_VENDOR_LIPPERT is not set
+# CONFIG_VENDOR_MITAC is not set
+# CONFIG_VENDOR_MSI is not set
+# CONFIG_VENDOR_NEC is not set
+# CONFIG_VENDOR_NEWISYS is not set
+# CONFIG_VENDOR_NOKIA is not set
+# CONFIG_VENDOR_NVIDIA is not set
+# CONFIG_VENDOR_PACKARDBELL is not set
+# CONFIG_VENDOR_PCENGINES is not set
+# CONFIG_VENDOR_RCA is not set
+# CONFIG_VENDOR_RODA is not set
+# CONFIG_VENDOR_SAMSUNG is not set
+# CONFIG_VENDOR_SIEMENS is not set
+# CONFIG_VENDOR_SOYO is not set
+# CONFIG_VENDOR_SUNW is not set
+# CONFIG_VENDOR_SUPERMICRO is not set
+# CONFIG_VENDOR_TECHNEXION is not set
+# CONFIG_VENDOR_TECHNOLOGIC is not set
+# CONFIG_VENDOR_TELEVIDEO is not set
+# CONFIG_VENDOR_TI is not set
+# CONFIG_VENDOR_THOMSON is not set
+# CONFIG_VENDOR_TRAVERSE is not set
+# CONFIG_VENDOR_TYAN is not set
+# CONFIG_VENDOR_VIA is not set
+# CONFIG_VENDOR_WINENT is not set
+# CONFIG_VENDOR_WYSE is not set
+CONFIG_BOARD_SPECIFIC_OPTIONS=y
+CONFIG_MAINBOARD_DIR="lenovo/x60"
+CONFIG_MAINBOARD_PART_NUMBER="ThinkPad X60 / X60s / X60t"
+CONFIG_IRQ_SLOT_COUNT=18
+CONFIG_MAINBOARD_VENDOR="Lenovo"
+CONFIG_MAX_CPUS=2
+CONFIG_RAMTOP=0x200000
+CONFIG_HEAP_SIZE=0x4000
+CONFIG_RAMBASE=0x100000
+CONFIG_VGA_BIOS_ID="8086,27a2"
+CONFIG_DRIVERS_PS2_KEYBOARD=y
+# CONFIG_ONBOARD_VGA_IS_PRIMARY is not set
+# CONFIG_VGA_BIOS is not set
+# CONFIG_UDELAY_IO is not set
+CONFIG_DCACHE_RAM_BASE=0xffdf8000
+CONFIG_DCACHE_RAM_SIZE=0x8000
+CONFIG_ACPI_SSDTX_NUM=0
+CONFIG_MMCONF_BASE_ADDRESS=0xf0000000
+CONFIG_MAINBOARD_SMBIOS_MANUFACTURER="LENOVO"
+CONFIG_SEABIOS_PS2_TIMEOUT=3000
+# CONFIG_PCI_64BIT_PREF_MEM is not set
+CONFIG_UART_FOR_CONSOLE=0
+CONFIG_ID_SECTION_OFFSET=0x80
+# CONFIG_BOARD_EMULATION_QEMU_X86_I440FX is not set
+# CONFIG_BOARD_EMULATION_QEMU_X86_Q35 is not set
+# CONFIG_BOARD_EMULATION_QEMU_ARMV7 is not set
+CONFIG_STACK_SIZE=0x1000
+CONFIG_CACHE_ROM_SIZE_OVERRIDE=0
+CONFIG_CBFS_SIZE=0x200000
+CONFIG_BOARD_LENOVO_X60=y
+# CONFIG_BOARD_LENOVO_X201 is not set
+# CONFIG_BOARD_LENOVO_X230 is not set
+# CONFIG_BOARD_LENOVO_T520 is not set
+# CONFIG_BOARD_LENOVO_T530 is not set
+# CONFIG_BOARD_LENOVO_T60 is not set
+CONFIG_MAINBOARD_VERSION="ThinkPad X60s"
+CONFIG_CPU_ADDR_BITS=32
+CONFIG_DEFAULT_CONSOLE_LOGLEVEL=8
+# CONFIG_USBDEBUG is not set
+CONFIG_MAXIMUM_SUPPORTED_FREQUENCY=0
+CONFIG_BOARD_ROMSIZE_KB_2048=y
+# CONFIG_COREBOOT_ROMSIZE_KB_64 is not set
+# CONFIG_COREBOOT_ROMSIZE_KB_128 is not set
+# CONFIG_COREBOOT_ROMSIZE_KB_256 is not set
+# CONFIG_COREBOOT_ROMSIZE_KB_512 is not set
+# CONFIG_COREBOOT_ROMSIZE_KB_1024 is not set
+CONFIG_COREBOOT_ROMSIZE_KB_2048=y
+# CONFIG_COREBOOT_ROMSIZE_KB_4096 is not set
+# CONFIG_COREBOOT_ROMSIZE_KB_8192 is not set
+# CONFIG_COREBOOT_ROMSIZE_KB_12288 is not set
+# CONFIG_COREBOOT_ROMSIZE_KB_16384 is not set
+CONFIG_COREBOOT_ROMSIZE_KB=2048
+CONFIG_ROM_SIZE=0x200000
+CONFIG_MAINBOARD_SERIAL_NUMBER="L3BH242"
+CONFIG_MAINBOARD_SMBIOS_PRODUCT_NAME="1702L8G"
+CONFIG_ARCH_X86=y
+# CONFIG_ARCH_ARMV7 is not set
+CONFIG_ARCH_BOOTBLOCK_X86_32=y
+CONFIG_ARCH_ROMSTAGE_X86_32=y
+CONFIG_ARCH_RAMSTAGE_X86_32=y
+CONFIG_AP_IN_SIPI_WAIT=y
+# CONFIG_SIPI_VECTOR_IN_ROM is not set
+CONFIG_NUM_IPI_STARTS=2
+# CONFIG_ROMCC is not set
+CONFIG_PC80_SYSTEM=y
+CONFIG_BOOTBLOCK_NORTHBRIDGE_INIT="northbridge/intel/i945/bootblock.c"
+CONFIG_HAVE_CMOS_DEFAULT=y
+CONFIG_CMOS_DEFAULT_FILE="src/mainboard/$(MAINBOARDDIR)/cmos.default"
+CONFIG_BOOTBLOCK_SOUTHBRIDGE_INIT="southbridge/intel/i82801gx/bootblock.c"
+CONFIG_IOAPIC_INTERRUPTS_ON_FSB=y
+# CONFIG_IOAPIC_INTERRUPTS_ON_APIC_SERIAL_BUS is not set
+CONFIG_HPET_ADDRESS=0xfed00000
+# CONFIG_ARCH_BOOTBLOCK_ARMV7 is not set
+# CONFIG_ARCH_ROMSTAGE_ARMV7 is not set
+# CONFIG_ARCH_RAMSTAGE_ARMV7 is not set
+# CONFIG_MAINBOARD_HAS_CHROMEOS is not set
+CONFIG_BOOTBLOCK_SIMPLE=y
+# CONFIG_BOOTBLOCK_NORMAL is not set
+CONFIG_BOOTBLOCK_SOURCE="bootblock_simple.c"
+# CONFIG_UPDATE_IMAGE is not set
+
+#
+# Chipset
+#
+
+#
+# CPU
+#
+# CONFIG_CPU_ALLWINNER_A10 is not set
+# CONFIG_CPU_ARMLTD_CORTEX_A9 is not set
+# CONFIG_CPU_SAMSUNG_EXYNOS5250 is not set
+# CONFIG_CPU_SAMSUNG_EXYNOS5420 is not set
+# CONFIG_CPU_TI_AM335X is not set
+CONFIG_SOCKET_SPECIFIC_OPTIONS=y
+CONFIG_XIP_ROM_SIZE=0x10000
+# CONFIG_CPU_AMD_AGESA is not set
+CONFIG_HIGH_SCRATCH_MEMORY_SIZE=0x0
+CONFIG_CPU_INTEL_MODEL_6EX=y
+CONFIG_CPU_INTEL_MODEL_6FX=y
+CONFIG_SMM_TSEG_SIZE=0
+CONFIG_CPU_INTEL_SOCKET_MFCPGA478=y
+CONFIG_SSE2=y
+# CONFIG_CPU_INTEL_FIRMWARE_INTERFACE_TABLE is not set
+# CONFIG_CPU_INTEL_TURBO_NOT_PACKAGE_SCOPED is not set
+# CONFIG_PARALLEL_CPU_INIT is not set
+CONFIG_UDELAY_LAPIC=y
+CONFIG_LAPIC_MONOTONIC_TIMER=y
+# CONFIG_UDELAY_TSC is not set
+# CONFIG_UDELAY_TIMER2 is not set
+# CONFIG_TSC_CALIBRATE_WITH_IO is not set
+# CONFIG_TSC_SYNC_LFENCE is not set
+CONFIG_TSC_SYNC_MFENCE=y
+CONFIG_LOGICAL_CPUS=y
+# CONFIG_SMM_TSEG is not set
+# CONFIG_SMM_MODULES is not set
+# CONFIG_X86_AMD_FIXED_MTRRS is not set
+# CONFIG_PLATFORM_USES_FSP is not set
+# CONFIG_PARALLEL_MP is not set
+# CONFIG_BACKUP_DEFAULT_SMM_REGION is not set
+# CONFIG_MIRROR_PAYLOAD_TO_RAM_BEFORE_LOADING is not set
+CONFIG_CACHE_AS_RAM=y
+CONFIG_SMP=y
+CONFIG_AP_SIPI_VECTOR=0xfffff000
+CONFIG_MMX=y
+CONFIG_SSE=y
+CONFIG_SUPPORT_CPU_UCODE_IN_CBFS=y
+# CONFIG_CPU_MICROCODE_CBFS_GENERATE is not set
+# CONFIG_CPU_MICROCODE_CBFS_EXTERNAL is not set
+CONFIG_CPU_MICROCODE_CBFS_NONE=y
+
+#
+# Northbridge
+#
+CONFIG_VIDEO_MB=0
+# CONFIG_NORTHBRIDGE_AMD_AGESA is not set
+# CONFIG_AMD_NB_CIMX is not set
+# CONFIG_NORTHBRIDGE_AMD_CIMX_RD890 is not set
+CONFIG_NORTHBRIDGE_SPECIFIC_OPTIONS=y
+CONFIG_NORTHBRIDGE_INTEL_I945=y
+# CONFIG_NORTHBRIDGE_INTEL_SUBTYPE_I945GC is not set
+CONFIG_NORTHBRIDGE_INTEL_SUBTYPE_I945GM=y
+CONFIG_CHANNEL_XOR_RANDOMIZATION=y
+# CONFIG_OVERRIDE_CLOCK_DISABLE is not set
+# CONFIG_CHECK_SLFRCS_ON_RESUME is not set
+CONFIG_HPET_MIN_TICKS=0x80
+CONFIG_MAX_PIRQ_LINKS=4
+
+#
+# Southbridge
+#
+CONFIG_EHCI_BAR=0xfef00000
+# CONFIG_AMD_SB_CIMX is not set
+# CONFIG_SOUTHBRIDGE_AMD_CIMX_SB800 is not set
+# CONFIG_SOUTHBRIDGE_AMD_CIMX_SB900 is not set
+CONFIG_SOUTHBRIDGE_INTEL_COMMON=y
+CONFIG_SOUTHBRIDGE_INTEL_I82801GX=y
+CONFIG_SOUTHBRIDGE_RICOH_RL5C476=y
+
+#
+# Super I/O
+#
+CONFIG_SUPERIO_NSC_PC87382=y
+CONFIG_SUPERIO_NSC_PC87392=y
+
+#
+# Embedded Controllers
+#
+CONFIG_EC_ACPI=y
+CONFIG_EC_LENOVO_H8=y
+CONFIG_H8_DOCK_EARLY_INIT=y
+CONFIG_EC_LENOVO_PMH7=y
+
+#
+# SoC
+#
+
+#
+# Devices
+#
+CONFIG_MAINBOARD_HAS_NATIVE_VGA_INIT=y
+# CONFIG_MAINBOARD_HAS_NATIVE_VGA_INIT_TEXTMODECFG is not set
+CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT=y
+# CONFIG_VGA_ROM_RUN is not set
+# CONFIG_ON_DEVICE_ROM_RUN is not set
+# CONFIG_PCI_OPTION_ROM_RUN_REALMODE is not set
+# CONFIG_PCI_OPTION_ROM_RUN_YABEL is not set
+# CONFIG_MULTIPLE_VGA_ADAPTERS is not set
+CONFIG_PCI=y
+# CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT is not set
+CONFIG_PCIX_PLUGIN_SUPPORT=y
+CONFIG_PCIEXP_PLUGIN_SUPPORT=y
+CONFIG_AGP_PLUGIN_SUPPORT=y
+CONFIG_CARDBUS_PLUGIN_SUPPORT=y
+# CONFIG_AZALIA_PLUGIN_SUPPORT is not set
+# CONFIG_PCIEXP_COMMON_CLOCK is not set
+# CONFIG_PCIEXP_ASPM is not set
+CONFIG_PCI_BUS_SEGN_BITS=0
+# CONFIG_EARLY_PCI_BRIDGE is not set
+
+#
+# VGA BIOS
+#
+
+#
+# Display
+#
+
+#
+# PXE ROM
+#
+# CONFIG_PXE_ROM is not set
+CONFIG_SUBSYSTEM_VENDOR_ID=0x0000
+CONFIG_SUBSYSTEM_DEVICE_ID=0x0000
+
+#
+# Generic Drivers
+#
+# CONFIG_DRIVERS_I2C_RTD2132 is not set
+CONFIG_DRIVERS_ICS_954309=y
+# CONFIG_INTEL_DP is not set
+# CONFIG_INTEL_DDI is not set
+CONFIG_INTEL_EDID=y
+# CONFIG_IPMI_KCS is not set
+CONFIG_DRIVERS_LENOVO_WACOM=y
+CONFIG_DIGITIZER_AUTODETECT=y
+# CONFIG_DIGITIZER_PRESENT is not set
+# CONFIG_DIGITIZER_ABSENT is not set
+# CONFIG_DRIVER_MAXIM_MAX77686 is not set
+# CONFIG_DRIVER_PARADE_PS8625 is not set
+# CONFIG_TPM is not set
+# CONFIG_DRIVERS_SIL_3114 is not set
+# CONFIG_SPI_FLASH is not set
+# CONFIG_DRIVER_TI_TPS65090 is not set
+CONFIG_DRIVERS_UART=y
+CONFIG_DRIVERS_UART_8250IO=y
+# CONFIG_NO_UART_ON_SUPERIO is not set
+# CONFIG_DRIVERS_UART_8250MEM is not set
+# CONFIG_HAVE_UART_SPECIAL is not set
+# CONFIG_DRIVERS_UART_OXPCIE is not set
+# CONFIG_DRIVERS_UART_PL011 is not set
+CONFIG_HAVE_USBDEBUG=y
+# CONFIG_HAVE_USBDEBUG_OPTIONS is not set
+# CONFIG_DRIVER_XPOWERS_AXP209 is not set
+CONFIG_MMCONF_SUPPORT_DEFAULT=y
+CONFIG_MMCONF_SUPPORT=y
+# CONFIG_BOOTMODE_STRAPS is not set
+
+#
+# Console
+#
+CONFIG_SQUELCH_EARLY_SMP=y
+CONFIG_CONSOLE_SERIAL=y
+
+#
+# I/O mapped, 8250-compatible
+#
+CONFIG_TTYS0_BASE=0x3f8
+CONFIG_CONSOLE_SERIAL_115200=y
+# CONFIG_CONSOLE_SERIAL_57600 is not set
+# CONFIG_CONSOLE_SERIAL_38400 is not set
+# CONFIG_CONSOLE_SERIAL_19200 is not set
+# CONFIG_CONSOLE_SERIAL_9600 is not set
+CONFIG_TTYS0_BAUD=115200
+CONFIG_TTYS0_LCS=3
+# CONFIG_SPKMODEM is not set
+# CONFIG_CONSOLE_NE2K is not set
+CONFIG_CONSOLE_CBMEM=y
+CONFIG_CONSOLE_CBMEM_BUFFER_SIZE=0x10000
+CONFIG_CONSOLE_CAR_BUFFER_SIZE=0xc00
+CONFIG_DEFAULT_CONSOLE_LOGLEVEL_8=y
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_7 is not set
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_6 is not set
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_5 is not set
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_4 is not set
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_3 is not set
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_2 is not set
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_1 is not set
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_0 is not set
+# CONFIG_NO_POST is not set
+# CONFIG_CMOS_POST is not set
+# CONFIG_POST_IO is not set
+CONFIG_POST_DEVICE=y
+CONFIG_POST_DEVICE_NONE=y
+# CONFIG_POST_DEVICE_LPC is not set
+# CONFIG_POST_DEVICE_PCI_PCIE is not set
+CONFIG_HAVE_ACPI_RESUME=y
+# CONFIG_HAVE_ACPI_SLIC is not set
+CONFIG_HAVE_HARD_RESET=y
+CONFIG_HAVE_MONOTONIC_TIMER=y
+# CONFIG_TIMER_QUEUE is not set
+CONFIG_HAVE_OPTION_TABLE=y
+# CONFIG_PIRQ_ROUTE is not set
+CONFIG_HAVE_SMI_HANDLER=y
+# CONFIG_PCI_IO_CFG_EXT is not set
+CONFIG_IOAPIC=y
+CONFIG_USE_WATCHDOG_ON_BOOT=y
+# CONFIG_VGA is not set
+# CONFIG_GFXUMA is not set
+# CONFIG_RELOCATABLE_MODULES is not set
+# CONFIG_HAVE_REFCODE_BLOB is not set
+CONFIG_HAVE_ACPI_TABLES=y
+CONFIG_HAVE_MP_TABLE=y
+CONFIG_HAVE_PIRQ_TABLE=y
+
+#
+# System tables
+#
+CONFIG_GENERATE_ACPI_TABLES=y
+CONFIG_GENERATE_MP_TABLE=y
+CONFIG_GENERATE_PIRQ_TABLE=y
+CONFIG_GENERATE_SMBIOS_TABLES=y
+
+#
+# Payload
+#
+# CONFIG_PAYLOAD_NONE is not set
+CONFIG_PAYLOAD_ELF=y
+# CONFIG_PAYLOAD_LINUX is not set
+# CONFIG_PAYLOAD_SEABIOS is not set
+# CONFIG_PAYLOAD_FILO is not set
+# CONFIG_PAYLOAD_GRUB2 is not set
+# CONFIG_PAYLOAD_TIANOCORE is not set
+# CONFIG_SEABIOS_STABLE is not set
+# CONFIG_SEABIOS_MASTER is not set
+# CONFIG_SEABIOS_THREAD_OPTIONROMS is not set
+CONFIG_PAYLOAD_FILE="grub.elf"
+CONFIG_COMPRESSED_PAYLOAD_LZMA=y
+
+#
+# Debugging
+#
+# CONFIG_GDB_STUB is not set
+# CONFIG_DEBUG_CBFS is not set
+CONFIG_HAVE_DEBUG_RAM_SETUP=y
+# CONFIG_DEBUG_RAM_SETUP is not set
+# CONFIG_HAVE_DEBUG_CAR is not set
+# CONFIG_DEBUG_PIRQ is not set
+# CONFIG_HAVE_DEBUG_SMBUS is not set
+# CONFIG_DEBUG_SMI is not set
+# CONFIG_DEBUG_SMM_RELOCATION is not set
+# CONFIG_DEBUG_MALLOC is not set
+# CONFIG_DEBUG_ACPI is not set
+# CONFIG_TRACE is not set
+# CONFIG_ENABLE_APIC_EXT_ID is not set
+CONFIG_WARNINGS_ARE_ERRORS=y
+# CONFIG_POWER_BUTTON_DEFAULT_ENABLE is not set
+# CONFIG_POWER_BUTTON_DEFAULT_DISABLE is not set
+# CONFIG_POWER_BUTTON_FORCE_ENABLE is not set
+# CONFIG_POWER_BUTTON_FORCE_DISABLE is not set
+# CONFIG_POWER_BUTTON_IS_OPTIONAL is not set
+CONFIG_REG_SCRIPT=y
+CONFIG_MAX_REBOOT_CNT=3
diff --git a/resources/libreboot/config/x60tconfig b/resources/libreboot/config/x60tconfig
new file mode 100644
index 0000000..f698057
--- /dev/null
+++ b/resources/libreboot/config/x60tconfig
@@ -0,0 +1,452 @@
+#
+# Automatically generated file; DO NOT EDIT.
+# coreboot configuration
+#
+
+#
+# General setup
+#
+CONFIG_EXPERT=y
+CONFIG_LOCALVERSION="7JET23WW (1.08 )"
+CONFIG_CBFS_PREFIX="fallback"
+CONFIG_COMPILER_GCC=y
+# CONFIG_COMPILER_LLVM_CLANG is not set
+# CONFIG_ANY_TOOLCHAIN is not set
+# CONFIG_CCACHE is not set
+# CONFIG_SCONFIG_GENPARSER is not set
+CONFIG_USE_OPTION_TABLE=y
+CONFIG_COMPRESS_RAMSTAGE=y
+CONFIG_INCLUDE_CONFIG_FILE=y
+CONFIG_EARLY_CBMEM_INIT=y
+# CONFIG_BROKEN_CAR_MIGRATE is not set
+# CONFIG_DYNAMIC_CBMEM is not set
+# CONFIG_COLLECT_TIMESTAMPS is not set
+# CONFIG_USE_BLOBS is not set
+# CONFIG_COVERAGE is not set
+
+#
+# Mainboard
+#
+# CONFIG_VENDOR_AAEON is not set
+# CONFIG_VENDOR_ABIT is not set
+# CONFIG_VENDOR_ADLINK is not set
+# CONFIG_VENDOR_ADVANSUS is not set
+# CONFIG_VENDOR_ADVANTECH is not set
+# CONFIG_VENDOR_AMD is not set
+# CONFIG_VENDOR_AOPEN is not set
+# CONFIG_VENDOR_APPLE is not set
+# CONFIG_VENDOR_ARIMA is not set
+# CONFIG_VENDOR_ARTECGROUP is not set
+# CONFIG_VENDOR_ASI is not set
+# CONFIG_VENDOR_ASROCK is not set
+# CONFIG_VENDOR_ASUS is not set
+# CONFIG_VENDOR_A_TREND is not set
+# CONFIG_VENDOR_AVALUE is not set
+# CONFIG_VENDOR_AXUS is not set
+# CONFIG_VENDOR_AZZA is not set
+# CONFIG_VENDOR_BACHMANN is not set
+# CONFIG_VENDOR_BCOM is not set
+# CONFIG_VENDOR_BIFFEROS is not set
+# CONFIG_VENDOR_BIOSTAR is not set
+# CONFIG_VENDOR_BROADCOM is not set
+# CONFIG_VENDOR_COMPAQ is not set
+# CONFIG_VENDOR_CUBIETECH is not set
+# CONFIG_VENDOR_DIGITALLOGIC is not set
+# CONFIG_VENDOR_DMP is not set
+# CONFIG_VENDOR_EAGLELION is not set
+# CONFIG_VENDOR_ECS is not set
+# CONFIG_VENDOR_EMULATION is not set
+# CONFIG_VENDOR_GETAC is not set
+# CONFIG_VENDOR_GIGABYTE is not set
+# CONFIG_VENDOR_GIZMOSPHERE is not set
+# CONFIG_VENDOR_GOOGLE is not set
+# CONFIG_VENDOR_HP is not set
+# CONFIG_VENDOR_IBASE is not set
+# CONFIG_VENDOR_IBM is not set
+# CONFIG_VENDOR_IEI is not set
+# CONFIG_VENDOR_INTEL is not set
+# CONFIG_VENDOR_IWAVE is not set
+# CONFIG_VENDOR_IWILL is not set
+# CONFIG_VENDOR_JETWAY is not set
+# CONFIG_VENDOR_KONTRON is not set
+# CONFIG_VENDOR_LANNER is not set
+CONFIG_VENDOR_LENOVO=y
+# CONFIG_VENDOR_LINUTOP is not set
+# CONFIG_VENDOR_LIPPERT is not set
+# CONFIG_VENDOR_MITAC is not set
+# CONFIG_VENDOR_MSI is not set
+# CONFIG_VENDOR_NEC is not set
+# CONFIG_VENDOR_NEWISYS is not set
+# CONFIG_VENDOR_NOKIA is not set
+# CONFIG_VENDOR_NVIDIA is not set
+# CONFIG_VENDOR_PACKARDBELL is not set
+# CONFIG_VENDOR_PCENGINES is not set
+# CONFIG_VENDOR_RCA is not set
+# CONFIG_VENDOR_RODA is not set
+# CONFIG_VENDOR_SAMSUNG is not set
+# CONFIG_VENDOR_SIEMENS is not set
+# CONFIG_VENDOR_SOYO is not set
+# CONFIG_VENDOR_SUNW is not set
+# CONFIG_VENDOR_SUPERMICRO is not set
+# CONFIG_VENDOR_TECHNEXION is not set
+# CONFIG_VENDOR_TECHNOLOGIC is not set
+# CONFIG_VENDOR_TELEVIDEO is not set
+# CONFIG_VENDOR_TI is not set
+# CONFIG_VENDOR_THOMSON is not set
+# CONFIG_VENDOR_TRAVERSE is not set
+# CONFIG_VENDOR_TYAN is not set
+# CONFIG_VENDOR_VIA is not set
+# CONFIG_VENDOR_WINENT is not set
+# CONFIG_VENDOR_WYSE is not set
+CONFIG_BOARD_SPECIFIC_OPTIONS=y
+CONFIG_MAINBOARD_DIR="lenovo/x60"
+CONFIG_MAINBOARD_PART_NUMBER="ThinkPad X60 / X60s / X60t"
+CONFIG_IRQ_SLOT_COUNT=18
+CONFIG_MAINBOARD_VENDOR="Lenovo"
+CONFIG_MAX_CPUS=2
+CONFIG_RAMTOP=0x200000
+CONFIG_HEAP_SIZE=0x4000
+CONFIG_RAMBASE=0x100000
+CONFIG_VGA_BIOS_ID="8086,27a2"
+CONFIG_DRIVERS_PS2_KEYBOARD=y
+# CONFIG_ONBOARD_VGA_IS_PRIMARY is not set
+# CONFIG_VGA_BIOS is not set
+# CONFIG_UDELAY_IO is not set
+CONFIG_DCACHE_RAM_BASE=0xffdf8000
+CONFIG_DCACHE_RAM_SIZE=0x8000
+CONFIG_ACPI_SSDTX_NUM=0
+CONFIG_MMCONF_BASE_ADDRESS=0xf0000000
+CONFIG_MAINBOARD_SMBIOS_MANUFACTURER="LENOVO"
+CONFIG_SEABIOS_PS2_TIMEOUT=3000
+# CONFIG_PCI_64BIT_PREF_MEM is not set
+CONFIG_UART_FOR_CONSOLE=0
+CONFIG_ID_SECTION_OFFSET=0x80
+# CONFIG_BOARD_EMULATION_QEMU_X86_I440FX is not set
+# CONFIG_BOARD_EMULATION_QEMU_X86_Q35 is not set
+# CONFIG_BOARD_EMULATION_QEMU_ARMV7 is not set
+CONFIG_STACK_SIZE=0x1000
+CONFIG_CACHE_ROM_SIZE_OVERRIDE=0
+CONFIG_CBFS_SIZE=0x200000
+CONFIG_BOARD_LENOVO_X60=y
+# CONFIG_BOARD_LENOVO_X201 is not set
+# CONFIG_BOARD_LENOVO_X230 is not set
+# CONFIG_BOARD_LENOVO_T520 is not set
+# CONFIG_BOARD_LENOVO_T530 is not set
+# CONFIG_BOARD_LENOVO_T60 is not set
+CONFIG_MAINBOARD_VERSION="ThinkPad X60 Tablet"
+CONFIG_CPU_ADDR_BITS=32
+CONFIG_DEFAULT_CONSOLE_LOGLEVEL=8
+# CONFIG_USBDEBUG is not set
+CONFIG_MAXIMUM_SUPPORTED_FREQUENCY=0
+CONFIG_BOARD_ROMSIZE_KB_2048=y
+# CONFIG_COREBOOT_ROMSIZE_KB_64 is not set
+# CONFIG_COREBOOT_ROMSIZE_KB_128 is not set
+# CONFIG_COREBOOT_ROMSIZE_KB_256 is not set
+# CONFIG_COREBOOT_ROMSIZE_KB_512 is not set
+# CONFIG_COREBOOT_ROMSIZE_KB_1024 is not set
+CONFIG_COREBOOT_ROMSIZE_KB_2048=y
+# CONFIG_COREBOOT_ROMSIZE_KB_4096 is not set
+# CONFIG_COREBOOT_ROMSIZE_KB_8192 is not set
+# CONFIG_COREBOOT_ROMSIZE_KB_12288 is not set
+# CONFIG_COREBOOT_ROMSIZE_KB_16384 is not set
+CONFIG_COREBOOT_ROMSIZE_KB=2048
+CONFIG_ROM_SIZE=0x200000
+CONFIG_MAINBOARD_SERIAL_NUMBER="L3B8281"
+CONFIG_MAINBOARD_SMBIOS_PRODUCT_NAME="6364WJ1"
+CONFIG_ARCH_X86=y
+# CONFIG_ARCH_ARMV7 is not set
+CONFIG_ARCH_BOOTBLOCK_X86_32=y
+CONFIG_ARCH_ROMSTAGE_X86_32=y
+CONFIG_ARCH_RAMSTAGE_X86_32=y
+CONFIG_AP_IN_SIPI_WAIT=y
+# CONFIG_SIPI_VECTOR_IN_ROM is not set
+CONFIG_NUM_IPI_STARTS=2
+# CONFIG_ROMCC is not set
+CONFIG_PC80_SYSTEM=y
+CONFIG_BOOTBLOCK_NORTHBRIDGE_INIT="northbridge/intel/i945/bootblock.c"
+CONFIG_HAVE_CMOS_DEFAULT=y
+CONFIG_CMOS_DEFAULT_FILE="src/mainboard/$(MAINBOARDDIR)/cmos.default"
+CONFIG_BOOTBLOCK_SOUTHBRIDGE_INIT="southbridge/intel/i82801gx/bootblock.c"
+CONFIG_IOAPIC_INTERRUPTS_ON_FSB=y
+# CONFIG_IOAPIC_INTERRUPTS_ON_APIC_SERIAL_BUS is not set
+CONFIG_HPET_ADDRESS=0xfed00000
+# CONFIG_ARCH_BOOTBLOCK_ARMV7 is not set
+# CONFIG_ARCH_ROMSTAGE_ARMV7 is not set
+# CONFIG_ARCH_RAMSTAGE_ARMV7 is not set
+# CONFIG_MAINBOARD_HAS_CHROMEOS is not set
+CONFIG_BOOTBLOCK_SIMPLE=y
+# CONFIG_BOOTBLOCK_NORMAL is not set
+CONFIG_BOOTBLOCK_SOURCE="bootblock_simple.c"
+# CONFIG_UPDATE_IMAGE is not set
+
+#
+# Chipset
+#
+
+#
+# CPU
+#
+# CONFIG_CPU_ALLWINNER_A10 is not set
+# CONFIG_CPU_ARMLTD_CORTEX_A9 is not set
+# CONFIG_CPU_SAMSUNG_EXYNOS5250 is not set
+# CONFIG_CPU_SAMSUNG_EXYNOS5420 is not set
+# CONFIG_CPU_TI_AM335X is not set
+CONFIG_SOCKET_SPECIFIC_OPTIONS=y
+CONFIG_XIP_ROM_SIZE=0x10000
+# CONFIG_CPU_AMD_AGESA is not set
+CONFIG_HIGH_SCRATCH_MEMORY_SIZE=0x0
+CONFIG_CPU_INTEL_MODEL_6EX=y
+CONFIG_CPU_INTEL_MODEL_6FX=y
+CONFIG_SMM_TSEG_SIZE=0
+CONFIG_CPU_INTEL_SOCKET_MFCPGA478=y
+CONFIG_SSE2=y
+# CONFIG_CPU_INTEL_FIRMWARE_INTERFACE_TABLE is not set
+# CONFIG_CPU_INTEL_TURBO_NOT_PACKAGE_SCOPED is not set
+# CONFIG_PARALLEL_CPU_INIT is not set
+CONFIG_UDELAY_LAPIC=y
+CONFIG_LAPIC_MONOTONIC_TIMER=y
+# CONFIG_UDELAY_TSC is not set
+# CONFIG_UDELAY_TIMER2 is not set
+# CONFIG_TSC_CALIBRATE_WITH_IO is not set
+# CONFIG_TSC_SYNC_LFENCE is not set
+CONFIG_TSC_SYNC_MFENCE=y
+CONFIG_LOGICAL_CPUS=y
+# CONFIG_SMM_TSEG is not set
+# CONFIG_SMM_MODULES is not set
+# CONFIG_X86_AMD_FIXED_MTRRS is not set
+# CONFIG_PLATFORM_USES_FSP is not set
+# CONFIG_PARALLEL_MP is not set
+# CONFIG_BACKUP_DEFAULT_SMM_REGION is not set
+# CONFIG_MIRROR_PAYLOAD_TO_RAM_BEFORE_LOADING is not set
+CONFIG_CACHE_AS_RAM=y
+CONFIG_SMP=y
+CONFIG_AP_SIPI_VECTOR=0xfffff000
+CONFIG_MMX=y
+CONFIG_SSE=y
+CONFIG_SUPPORT_CPU_UCODE_IN_CBFS=y
+# CONFIG_CPU_MICROCODE_CBFS_GENERATE is not set
+# CONFIG_CPU_MICROCODE_CBFS_EXTERNAL is not set
+CONFIG_CPU_MICROCODE_CBFS_NONE=y
+
+#
+# Northbridge
+#
+CONFIG_VIDEO_MB=0
+# CONFIG_NORTHBRIDGE_AMD_AGESA is not set
+# CONFIG_AMD_NB_CIMX is not set
+# CONFIG_NORTHBRIDGE_AMD_CIMX_RD890 is not set
+CONFIG_NORTHBRIDGE_SPECIFIC_OPTIONS=y
+CONFIG_NORTHBRIDGE_INTEL_I945=y
+# CONFIG_NORTHBRIDGE_INTEL_SUBTYPE_I945GC is not set
+CONFIG_NORTHBRIDGE_INTEL_SUBTYPE_I945GM=y
+CONFIG_CHANNEL_XOR_RANDOMIZATION=y
+# CONFIG_OVERRIDE_CLOCK_DISABLE is not set
+# CONFIG_CHECK_SLFRCS_ON_RESUME is not set
+CONFIG_HPET_MIN_TICKS=0x80
+CONFIG_MAX_PIRQ_LINKS=4
+
+#
+# Southbridge
+#
+CONFIG_EHCI_BAR=0xfef00000
+# CONFIG_AMD_SB_CIMX is not set
+# CONFIG_SOUTHBRIDGE_AMD_CIMX_SB800 is not set
+# CONFIG_SOUTHBRIDGE_AMD_CIMX_SB900 is not set
+CONFIG_SOUTHBRIDGE_INTEL_COMMON=y
+CONFIG_SOUTHBRIDGE_INTEL_I82801GX=y
+CONFIG_SOUTHBRIDGE_RICOH_RL5C476=y
+
+#
+# Super I/O
+#
+CONFIG_SUPERIO_NSC_PC87382=y
+CONFIG_SUPERIO_NSC_PC87392=y
+
+#
+# Embedded Controllers
+#
+CONFIG_EC_ACPI=y
+CONFIG_EC_LENOVO_H8=y
+CONFIG_H8_DOCK_EARLY_INIT=y
+CONFIG_EC_LENOVO_PMH7=y
+
+#
+# SoC
+#
+
+#
+# Devices
+#
+CONFIG_MAINBOARD_HAS_NATIVE_VGA_INIT=y
+# CONFIG_MAINBOARD_HAS_NATIVE_VGA_INIT_TEXTMODECFG is not set
+CONFIG_MAINBOARD_DO_NATIVE_VGA_INIT=y
+# CONFIG_VGA_ROM_RUN is not set
+# CONFIG_ON_DEVICE_ROM_RUN is not set
+# CONFIG_PCI_OPTION_ROM_RUN_REALMODE is not set
+# CONFIG_PCI_OPTION_ROM_RUN_YABEL is not set
+# CONFIG_MULTIPLE_VGA_ADAPTERS is not set
+CONFIG_PCI=y
+# CONFIG_HYPERTRANSPORT_PLUGIN_SUPPORT is not set
+CONFIG_PCIX_PLUGIN_SUPPORT=y
+CONFIG_PCIEXP_PLUGIN_SUPPORT=y
+CONFIG_AGP_PLUGIN_SUPPORT=y
+CONFIG_CARDBUS_PLUGIN_SUPPORT=y
+# CONFIG_AZALIA_PLUGIN_SUPPORT is not set
+# CONFIG_PCIEXP_COMMON_CLOCK is not set
+# CONFIG_PCIEXP_ASPM is not set
+CONFIG_PCI_BUS_SEGN_BITS=0
+# CONFIG_EARLY_PCI_BRIDGE is not set
+
+#
+# VGA BIOS
+#
+
+#
+# Display
+#
+
+#
+# PXE ROM
+#
+# CONFIG_PXE_ROM is not set
+CONFIG_SUBSYSTEM_VENDOR_ID=0x0000
+CONFIG_SUBSYSTEM_DEVICE_ID=0x0000
+
+#
+# Generic Drivers
+#
+# CONFIG_DRIVERS_I2C_RTD2132 is not set
+CONFIG_DRIVERS_ICS_954309=y
+# CONFIG_INTEL_DP is not set
+# CONFIG_INTEL_DDI is not set
+CONFIG_INTEL_EDID=y
+# CONFIG_IPMI_KCS is not set
+CONFIG_DRIVERS_LENOVO_WACOM=y
+# CONFIG_DIGITIZER_AUTODETECT is not set
+CONFIG_DIGITIZER_PRESENT=y
+# CONFIG_DIGITIZER_ABSENT is not set
+# CONFIG_DRIVER_MAXIM_MAX77686 is not set
+# CONFIG_DRIVER_PARADE_PS8625 is not set
+# CONFIG_TPM is not set
+# CONFIG_DRIVERS_SIL_3114 is not set
+# CONFIG_SPI_FLASH is not set
+# CONFIG_DRIVER_TI_TPS65090 is not set
+CONFIG_DRIVERS_UART=y
+CONFIG_DRIVERS_UART_8250IO=y
+# CONFIG_NO_UART_ON_SUPERIO is not set
+# CONFIG_DRIVERS_UART_8250MEM is not set
+# CONFIG_HAVE_UART_SPECIAL is not set
+# CONFIG_DRIVERS_UART_OXPCIE is not set
+# CONFIG_DRIVERS_UART_PL011 is not set
+CONFIG_HAVE_USBDEBUG=y
+# CONFIG_HAVE_USBDEBUG_OPTIONS is not set
+# CONFIG_DRIVER_XPOWERS_AXP209 is not set
+CONFIG_MMCONF_SUPPORT_DEFAULT=y
+CONFIG_MMCONF_SUPPORT=y
+# CONFIG_BOOTMODE_STRAPS is not set
+
+#
+# Console
+#
+CONFIG_SQUELCH_EARLY_SMP=y
+CONFIG_CONSOLE_SERIAL=y
+
+#
+# I/O mapped, 8250-compatible
+#
+CONFIG_TTYS0_BASE=0x3f8
+CONFIG_CONSOLE_SERIAL_115200=y
+# CONFIG_CONSOLE_SERIAL_57600 is not set
+# CONFIG_CONSOLE_SERIAL_38400 is not set
+# CONFIG_CONSOLE_SERIAL_19200 is not set
+# CONFIG_CONSOLE_SERIAL_9600 is not set
+CONFIG_TTYS0_BAUD=115200
+CONFIG_TTYS0_LCS=3
+# CONFIG_SPKMODEM is not set
+# CONFIG_CONSOLE_NE2K is not set
+CONFIG_CONSOLE_CBMEM=y
+CONFIG_CONSOLE_CBMEM_BUFFER_SIZE=0x10000
+CONFIG_CONSOLE_CAR_BUFFER_SIZE=0xc00
+CONFIG_DEFAULT_CONSOLE_LOGLEVEL_8=y
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_7 is not set
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_6 is not set
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_5 is not set
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_4 is not set
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_3 is not set
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_2 is not set
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_1 is not set
+# CONFIG_DEFAULT_CONSOLE_LOGLEVEL_0 is not set
+# CONFIG_NO_POST is not set
+# CONFIG_CMOS_POST is not set
+# CONFIG_POST_IO is not set
+CONFIG_POST_DEVICE=y
+CONFIG_POST_DEVICE_NONE=y
+# CONFIG_POST_DEVICE_LPC is not set
+# CONFIG_POST_DEVICE_PCI_PCIE is not set
+CONFIG_HAVE_ACPI_RESUME=y
+# CONFIG_HAVE_ACPI_SLIC is not set
+CONFIG_HAVE_HARD_RESET=y
+CONFIG_HAVE_MONOTONIC_TIMER=y
+# CONFIG_TIMER_QUEUE is not set
+CONFIG_HAVE_OPTION_TABLE=y
+# CONFIG_PIRQ_ROUTE is not set
+CONFIG_HAVE_SMI_HANDLER=y
+# CONFIG_PCI_IO_CFG_EXT is not set
+CONFIG_IOAPIC=y
+CONFIG_USE_WATCHDOG_ON_BOOT=y
+# CONFIG_VGA is not set
+# CONFIG_GFXUMA is not set
+# CONFIG_RELOCATABLE_MODULES is not set
+# CONFIG_HAVE_REFCODE_BLOB is not set
+CONFIG_HAVE_ACPI_TABLES=y
+CONFIG_HAVE_MP_TABLE=y
+CONFIG_HAVE_PIRQ_TABLE=y
+
+#
+# System tables
+#
+CONFIG_GENERATE_ACPI_TABLES=y
+CONFIG_GENERATE_MP_TABLE=y
+CONFIG_GENERATE_PIRQ_TABLE=y
+CONFIG_GENERATE_SMBIOS_TABLES=y
+
+#
+# Payload
+#
+# CONFIG_PAYLOAD_NONE is not set
+CONFIG_PAYLOAD_ELF=y
+# CONFIG_PAYLOAD_LINUX is not set
+# CONFIG_PAYLOAD_SEABIOS is not set
+# CONFIG_PAYLOAD_FILO is not set
+# CONFIG_PAYLOAD_GRUB2 is not set
+# CONFIG_PAYLOAD_TIANOCORE is not set
+# CONFIG_SEABIOS_STABLE is not set
+# CONFIG_SEABIOS_MASTER is not set
+# CONFIG_SEABIOS_THREAD_OPTIONROMS is not set
+CONFIG_PAYLOAD_FILE="grub.elf"
+CONFIG_COMPRESSED_PAYLOAD_LZMA=y
+
+#
+# Debugging
+#
+# CONFIG_GDB_STUB is not set
+# CONFIG_DEBUG_CBFS is not set
+CONFIG_HAVE_DEBUG_RAM_SETUP=y
+# CONFIG_DEBUG_RAM_SETUP is not set
+# CONFIG_HAVE_DEBUG_CAR is not set
+# CONFIG_DEBUG_PIRQ is not set
+# CONFIG_HAVE_DEBUG_SMBUS is not set
+# CONFIG_DEBUG_SMI is not set
+# CONFIG_DEBUG_SMM_RELOCATION is not set
+# CONFIG_DEBUG_MALLOC is not set
+# CONFIG_DEBUG_ACPI is not set
+# CONFIG_TRACE is not set
+# CONFIG_ENABLE_APIC_EXT_ID is not set
+CONFIG_WARNINGS_ARE_ERRORS=y
+# CONFIG_POWER_BUTTON_DEFAULT_ENABLE is not set
+# CONFIG_POWER_BUTTON_DEFAULT_DISABLE is not set
+# CONFIG_POWER_BUTTON_FORCE_ENABLE is not set
+# CONFIG_POWER_BUTTON_FORCE_DISABLE is not set
+# CONFIG_POWER_BUTTON_IS_OPTIONAL is not set
+CONFIG_REG_SCRIPT=y
+CONFIG_MAX_REBOOT_CNT=3
diff --git a/resources/libreboot/patch/COPYING b/resources/libreboot/patch/COPYING
new file mode 100644
index 0000000..06f4f25
--- /dev/null
+++ b/resources/libreboot/patch/COPYING
@@ -0,0 +1,6 @@
+The "gitdiff" file is a patch for the coreboot project. Look at coreboot's copyright information
+therefore to see what conditions the patch falls under.
+
+Also, look at "getcb" script in a text editor in libreboot_src.tar.gz for this version of libreboot (go to ../../../docs/RELEASE.html
+to find out how to get libreboot_src.tar.gz for this version of libreboot) for attribution (acknowledgement) of
+the links to the original patches, since the gitdiff contains changes originally written by other people.
diff --git a/resources/libreboot/patch/gitdiff b/resources/libreboot/patch/gitdiff
new file mode 100644
index 0000000..9aec941
--- /dev/null
+++ b/resources/libreboot/patch/gitdiff
@@ -0,0 +1,580 @@
+diff --git a/src/drivers/Kconfig b/src/drivers/Kconfig
+index 874ec75..42d1583 100644
+--- a/src/drivers/Kconfig
++++ b/src/drivers/Kconfig
+@@ -26,6 +26,7 @@ source src/drivers/i2c/Kconfig
+ source src/drivers/ics/Kconfig
+ source src/drivers/intel/Kconfig
+ source src/drivers/ipmi/Kconfig
++source src/drivers/lenovo/Kconfig
+ source src/drivers/maxim/Kconfig
+ source src/drivers/parade/Kconfig
+ if PC80_SYSTEM
+diff --git a/src/drivers/Makefile.inc b/src/drivers/Makefile.inc
+index 66fe7b8..cb26643 100644
+--- a/src/drivers/Makefile.inc
++++ b/src/drivers/Makefile.inc
+@@ -23,6 +23,7 @@ subdirs-y += emulation
+ subdirs-y += generic
+ subdirs-y += i2c
+ subdirs-y += intel
++subdirs-y += lenovo
+ subdirs-y += maxim
+ subdirs-y += net
+ subdirs-y += parade
+diff --git a/src/drivers/lenovo/Kconfig b/src/drivers/lenovo/Kconfig
+index e69de29..30bacb9 100644
+--- a/src/drivers/lenovo/Kconfig
++++ b/src/drivers/lenovo/Kconfig
+@@ -0,0 +1,29 @@
++config DRIVERS_LENOVO_WACOM
++ bool
++ default n
++
++if DRIVERS_LENOVO_WACOM
++
++choice
++ prompt "Digitizer"
++ default DIGITIZER_AUTODETECT
++
++config DIGITIZER_AUTODETECT
++ bool "Autodetect"
++ help
++ The presence of digitizer is inferred from model number stored in
++ AT24RF chip.
++
++config DIGITIZER_PRESENT
++ bool "Present"
++ help
++ The digitizer is assumed to be present.
++
++config DIGITIZER_ABSENT
++ bool "Absent"
++ help
++ The digitizer is assumed to be absent.
++
++endchoice
++
++endif
+diff --git a/src/drivers/lenovo/Makefile.inc b/src/drivers/lenovo/Makefile.inc
+index e69de29..c50db5b 100644
+--- a/src/drivers/lenovo/Makefile.inc
++++ b/src/drivers/lenovo/Makefile.inc
+@@ -0,0 +1 @@
++ramstage-$(CONFIG_DRIVERS_LENOVO_WACOM) += wacom.c
+diff --git a/src/drivers/lenovo/lenovo.h b/src/drivers/lenovo/lenovo.h
+index e69de29..06b52e5 100644
+--- a/src/drivers/lenovo/lenovo.h
++++ b/src/drivers/lenovo/lenovo.h
+@@ -0,0 +1,4 @@
++int drivers_lenovo_is_wacom_present(void);
++void drivers_lenovo_serial_ports_ssdt_generate(const char *scope,
++ int have_dock_serial,
++ int have_infrared);
+diff --git a/src/drivers/lenovo/wacom.c b/src/drivers/lenovo/wacom.c
+index e69de29..ccccefd 100644
+--- a/src/drivers/lenovo/wacom.c
++++ b/src/drivers/lenovo/wacom.c
+@@ -0,0 +1,218 @@
++/*
++ * This file is part of the coreboot project.
++ *
++ * Copyright (C) 2014 Vladimir Serbinenko
++ *
++ * This program is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU General Public License as
++ * published by the Free Software Foundation; version 2, or (at your
++ * option) any later version, of the License.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
++ * MA 02110-1301 USA
++ */
++
++#include <types.h>
++#include <console/console.h>
++#include <arch/acpi.h>
++#include <arch/acpigen.h>
++#include <device/device.h>
++#include <device/pnp.h>
++#include <string.h>
++#include "lenovo.h"
++#include "drivers/i2c/at24rf08c/lenovo.h"
++
++static const char tablet_numbers[][5] = {
++ /* X60t. */
++ "6363", "6364", "6365", "6366",
++ "6367", "6368", "7762", "7763",
++ "7764", "7767", "7768", "7769",
++ /* X201t. */
++ "0053", "0831", "2985", "3093",
++ "3113", "3144", "3239", "4184",
++ "7448", "7449", "7450", "7453",
++ "2263", "2266",
++};
++
++int
++drivers_lenovo_is_wacom_present(void)
++{
++ const char *pn;
++ int i;
++ static int result = -1;
++ device_t superio;
++ u8 sioid;
++
++ if (result != -1)
++ return result;
++
++ if (IS_ENABLED(CONFIG_DIGITIZER_PRESENT)) {
++ printk (BIOS_INFO, "Digitizer state forced as present\n");
++ return (result = 1);
++ }
++
++ if (IS_ENABLED(CONFIG_DIGITIZER_ABSENT)) {
++ printk (BIOS_INFO, "Digitizer state forced as absent\n");
++ return (result = 0);
++ }
++
++ superio = dev_find_slot_pnp (0x164e, 3);
++ if (!superio) {
++ printk (BIOS_INFO, "No Super I/O, skipping wacom\n");
++ return (result = 0);
++ }
++
++ /* Probe ID. */
++ sioid = pnp_read_config(superio, 0x20);
++ if (sioid == 0xff) {
++ printk (BIOS_INFO, "Super I/O probe failed, skipping wacom\n");
++ return (result = 0);
++ }
++
++ pn = lenovo_mainboard_partnumber();
++ if (!pn)
++ return (result = 0);
++ printk (BIOS_DEBUG, "Lenovo P/N is %s\n", pn);
++ for (i = 0; i < ARRAY_SIZE (tablet_numbers); i++)
++ if (memcmp (tablet_numbers[i], pn, 4) == 0) {
++ printk (BIOS_DEBUG, "Lenovo P/N %s is a tablet\n", pn);
++ return (result = 1);
++ }
++ printk (BIOS_DEBUG, "Lenovo P/N %s is not a tablet\n", pn);
++ return (result = 0);
++}
++
++void
++drivers_lenovo_serial_ports_ssdt_generate(const char *scope,
++ int have_dock_serial,
++ int have_infrared)
++{
++ int scopelen, devicelen, reslen, methodlen;
++
++ scopelen = acpigen_write_scope(scope);
++
++ if (drivers_lenovo_is_wacom_present()) {
++ /* Device op. */
++ scopelen += acpigen_emit_byte(0x5b);
++ scopelen += acpigen_emit_byte(0x82);
++ devicelen = acpigen_write_len_f();
++ devicelen += acpigen_emit_namestring("DTR");
++
++ devicelen += acpigen_write_name("_HID");
++ devicelen += acpigen_emit_eisaid("WACF004");
++
++ devicelen += acpigen_write_name("_CRS");
++
++ reslen = acpigen_write_resourcetemplate_header();
++ reslen += acpigen_write_io16(0x200, 0x200, 1, 8, 1);
++ reslen += acpigen_write_irq((1 << 5));
++
++ devicelen += reslen;
++ devicelen += acpigen_write_resourcetemplate_footer(reslen);
++
++ /* method op */
++ devicelen += acpigen_emit_byte(0x14);
++ methodlen = acpigen_write_len_f();
++ methodlen += acpigen_emit_namestring("_STA");
++ /* no fnarg */
++ methodlen += acpigen_emit_byte(0x00);
++ /* return */
++ methodlen += acpigen_emit_byte(0xa4);
++ methodlen += acpigen_write_byte(0xf);
++
++ acpigen_patch_len(methodlen);
++ devicelen += methodlen;
++
++ acpigen_patch_len(devicelen - 1);
++ scopelen += devicelen;
++ }
++
++ if (have_infrared) {
++ /* Device op. */
++ scopelen += acpigen_emit_byte(0x5b);
++ scopelen += acpigen_emit_byte(0x82);
++ devicelen = acpigen_write_len_f();
++ devicelen += acpigen_emit_namestring("FIR");
++
++ devicelen += acpigen_write_name("_HID");
++ devicelen += acpigen_emit_eisaid("IBM0071");
++ devicelen += acpigen_write_name("_CID");
++ devicelen += acpigen_emit_eisaid("PNP0511");
++ devicelen += acpigen_write_name("_UID");
++
++ /* One */
++ devicelen += acpigen_write_byte(0x1);
++ devicelen += acpigen_write_name("_CRS");
++
++ reslen = acpigen_write_resourcetemplate_header();
++ reslen += acpigen_write_io16(0x2f8, 0x2f8, 1, 8, 1);
++ reslen += acpigen_write_irq(0x08);
++
++ devicelen += reslen;
++ devicelen += acpigen_write_resourcetemplate_footer(reslen);
++
++ /* method op */
++ devicelen += acpigen_emit_byte(0x14);
++ methodlen = acpigen_write_len_f();
++ methodlen += acpigen_emit_namestring("_STA");
++ /* no fnarg */
++ methodlen += acpigen_emit_byte(0x00);
++ /* return */
++ methodlen += acpigen_emit_byte(0xa4);
++ methodlen += acpigen_write_byte(0xf);
++ acpigen_patch_len(methodlen);
++
++ devicelen += methodlen;
++
++ acpigen_patch_len(devicelen - 1);
++ scopelen += devicelen;
++ }
++
++ if (have_dock_serial) {
++ /* Device op. */
++ scopelen += acpigen_emit_byte(0x5b);
++ scopelen += acpigen_emit_byte(0x82);
++ devicelen = acpigen_write_len_f();
++ devicelen += acpigen_emit_namestring("COMA");
++
++ devicelen += acpigen_write_name("_HID");
++ devicelen += acpigen_emit_eisaid("PNP0501");
++ devicelen += acpigen_write_name("_UID");
++ /* Byte */
++ devicelen += acpigen_write_byte(0x2);
++
++ devicelen += acpigen_write_name("_CRS");
++
++ reslen = acpigen_write_resourcetemplate_header();
++ reslen += acpigen_write_io16(0x3f8, 0x3f8, 1, 8, 1);
++ reslen += acpigen_write_irq(1 << 4);
++
++ devicelen += reslen;
++ devicelen += acpigen_write_resourcetemplate_footer(reslen);
++
++ /* method op */
++ devicelen += acpigen_emit_byte(0x14);
++ methodlen = acpigen_write_len_f();
++ methodlen += acpigen_emit_namestring("_STA");
++ /* no fnarg */
++ methodlen += acpigen_emit_byte(0x00);
++ /* return */
++ methodlen += acpigen_emit_byte(0xa4);
++ methodlen += acpigen_write_byte(0xf);
++ acpigen_patch_len(methodlen);
++
++ devicelen += methodlen;
++
++ acpigen_patch_len(devicelen - 1);
++ scopelen += devicelen;
++ }
++
++ acpigen_patch_len(scopelen - 1);
++}
+diff --git a/src/mainboard/lenovo/Kconfig b/src/mainboard/lenovo/Kconfig
+index c1dec85..583efc8 100644
+--- a/src/mainboard/lenovo/Kconfig
++++ b/src/mainboard/lenovo/Kconfig
+@@ -4,7 +4,7 @@ choice
+ prompt "Mainboard model"
+
+ config BOARD_LENOVO_X60
+- bool "ThinkPad X60 / X60s"
++ bool "ThinkPad X60 / X60s / X60t"
+ help
+ The following X60 series ThinkPad machines have been verified to
+ work correctly:
+@@ -13,7 +13,7 @@ config BOARD_LENOVO_X60
+ ThinkPad X60 (Model 1709)
+
+ config BOARD_LENOVO_X201
+- bool "ThinkPad X201"
++ bool "ThinkPad X201 / X201s / X201t"
+ help
+ Lenovo X201 laptop. Consult wiki for details.
+
+diff --git a/src/mainboard/lenovo/t60/acpi/superio.asl b/src/mainboard/lenovo/t60/acpi/superio.asl
+index e69de29..41137ce 100644
+--- a/src/mainboard/lenovo/t60/acpi/superio.asl
++++ b/src/mainboard/lenovo/t60/acpi/superio.asl
+@@ -0,0 +1,16 @@
++ Device (FIR) // Infrared
++ {
++ Name(_HID, EISAID("IBM0071"))
++ Name(_CID, EISAID("PNP0511"))
++
++ Name(_CRS, ResourceTemplate()
++ {
++ IO (Decode16, 0x2f8, 0x2f8, 0x01, 0x08)
++ IRQNoFlags () {3}
++ })
++
++ Method (_STA, 0)
++ {
++ Return (0xf)
++ }
++ }
+diff --git a/src/mainboard/lenovo/t60/devicetree.cb b/src/mainboard/lenovo/t60/devicetree.cb
+index 54b7da3..f13cb3a 100644
+--- a/src/mainboard/lenovo/t60/devicetree.cb
++++ b/src/mainboard/lenovo/t60/devicetree.cb
+@@ -25,7 +25,7 @@ chip northbridge/intel/i945
+ register "gpu_hotplug" = "0x00000220"
+ register "gpu_lvds_use_spread_spectrum_clock" = "1"
+ register "gpu_lvds_is_dual_channel" = "1"
+- register "gpu_backlight" = "0x1280128"
++ register "gpu_backlight" = "0x58BF58BE"
+
+ device cpu_cluster 0 on
+ chip cpu/intel/socket_mFCPGA478
+@@ -153,6 +153,10 @@ chip northbridge/intel/i945
+ chip superio/nsc/pc87382
+ device pnp 164e.2 on # IR
+ io 0x60 = 0x2f8
++ irq 0x29 = 0xb0
++ irq 0x70 = 0x3
++ drq 0x74 = 0x1
++ irq 0xf0 = 0x82
+ end
+
+ device pnp 164e.3 off # Serial Port
+diff --git a/src/mainboard/lenovo/t60/romstage.c b/src/mainboard/lenovo/t60/romstage.c
+index dae917c..237e967 100644
+--- a/src/mainboard/lenovo/t60/romstage.c
++++ b/src/mainboard/lenovo/t60/romstage.c
+@@ -79,7 +79,7 @@ static void ich7_enable_lpc(void)
+ // decode range
+ pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x80, 0x0210);
+ // decode range
+- pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x82, 0x1f0d);
++ pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x82, 0x1f0f);
+
+ /* range 0x1600 - 0x167f */
+ pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x84, 0x1601);
+diff --git a/src/mainboard/lenovo/x201/Kconfig b/src/mainboard/lenovo/x201/Kconfig
+index 50df47b..61038c4 100644
+--- a/src/mainboard/lenovo/x201/Kconfig
++++ b/src/mainboard/lenovo/x201/Kconfig
+@@ -17,6 +17,8 @@ config BOARD_SPECIFIC_OPTIONS # dummy
+ select EARLY_CBMEM_INIT
+ select MAINBOARD_HAS_NATIVE_VGA_INIT
+ select MAINBOARD_HAS_NATIVE_VGA_INIT_TEXTMODECFG
++ select SUPERIO_NSC_PC87382
++ select DRIVERS_LENOVO_WACOM
+
+ config MAINBOARD_DIR
+ string
+@@ -28,7 +30,7 @@ config MAINBOARD_PART_NUMBER
+
+ config MAINBOARD_VERSION
+ string
+- default "ThinkPad X201"
++ default "ThinkPad X201 / X201s / X201t"
+
+ config MAINBOARD_VENDOR
+ string
+diff --git a/src/mainboard/lenovo/x201/acpi_tables.c b/src/mainboard/lenovo/x201/acpi_tables.c
+index 165de0d..710e369 100644
+--- a/src/mainboard/lenovo/x201/acpi_tables.c
++++ b/src/mainboard/lenovo/x201/acpi_tables.c
+@@ -31,6 +31,7 @@
+ #include <device/pci.h>
+ #include <device/pci_ids.h>
+ #include "southbridge/intel/ibexpeak/nvs.h"
++#include "drivers/lenovo/lenovo.h"
+
+ extern const unsigned char AmlCode[];
+ #if CONFIG_HAVE_ACPI_SLIC
+@@ -93,6 +94,7 @@ unsigned long acpi_fill_ssdt_generator(unsigned long current,
+ const char *oem_table_id)
+ {
+ generate_cpu_entries();
++ drivers_lenovo_serial_ports_ssdt_generate("\\_SB.PCI0.LPCB", 0, 0);
+ return (unsigned long)(acpigen_get_current());
+ }
+
+diff --git a/src/mainboard/lenovo/x201/devicetree.cb b/src/mainboard/lenovo/x201/devicetree.cb
+index 9053f89..1db5bf0 100644
+--- a/src/mainboard/lenovo/x201/devicetree.cb
++++ b/src/mainboard/lenovo/x201/devicetree.cb
+@@ -143,6 +143,20 @@ chip northbridge/intel/nehalem
+ end
+ device pci 1f.0 on # PCI-LPC bridge
+ subsystemid 0x17aa 0x2166
++ chip superio/nsc/pc87382
++ device pnp 164e.3 on # Digitizer
++ io 0x60 = 0x200
++ irq 0x29 = 0xb0
++ irq 0x70 = 0x5
++ irq 0xf0 = 0x82
++ end
++ # IR, not connected
++ device pnp 164e.2 off end
++ # GPIO, not connected
++ device pnp 164e.7 off end
++ # DLPC, not connected
++ device pnp 164e.19 off end
++ end
+ end
+ device pci 1f.2 on # IDE/SATA
+ subsystemid 0x17aa 0x2168
+diff --git a/src/mainboard/lenovo/x201/romstage.c b/src/mainboard/lenovo/x201/romstage.c
+index 1237a5c..f74b441 100644
+--- a/src/mainboard/lenovo/x201/romstage.c
++++ b/src/mainboard/lenovo/x201/romstage.c
+@@ -53,7 +53,7 @@ static void pch_enable_lpc(void)
+ /* Enable EC, PS/2 Keyboard/Mouse */
+ pci_write_config16(PCH_LPC_DEV, LPC_EN,
+ CNF2_LPC_EN | CNF1_LPC_EN | MC_LPC_EN | KBC_LPC_EN |
+- COMA_LPC_EN);
++ COMA_LPC_EN | GAMEL_LPC_EN);
+
+ pci_write_config32(PCH_LPC_DEV, LPC_GEN1_DEC, 0x7c1601);
+ pci_write_config32(PCH_LPC_DEV, LPC_GEN2_DEC, 0xc15e1);
+diff --git a/src/mainboard/lenovo/x60/Kconfig b/src/mainboard/lenovo/x60/Kconfig
+index b0d7a06..3c708cd 100644
+--- a/src/mainboard/lenovo/x60/Kconfig
++++ b/src/mainboard/lenovo/x60/Kconfig
+@@ -24,6 +24,7 @@ config BOARD_SPECIFIC_OPTIONS # dummy
+ select MAINBOARD_HAS_NATIVE_VGA_INIT
+ select EARLY_CBMEM_INIT
+ select H8_DOCK_EARLY_INIT
++ select DRIVERS_LENOVO_WACOM
+ select INTEL_EDID
+
+ config MAINBOARD_DIR
+@@ -40,7 +41,7 @@ config DCACHE_RAM_SIZE
+
+ config MAINBOARD_PART_NUMBER
+ string
+- default "ThinkPad X60 / X60s"
++ default "ThinkPad X60 / X60s / X60t"
+
+ config MMCONF_BASE_ADDRESS
+ hex
+diff --git a/src/mainboard/lenovo/x60/acpi_tables.c b/src/mainboard/lenovo/x60/acpi_tables.c
+index f6ed4ae..c8fce7f 100644
+--- a/src/mainboard/lenovo/x60/acpi_tables.c
++++ b/src/mainboard/lenovo/x60/acpi_tables.c
+@@ -29,6 +29,7 @@
+ #include <device/device.h>
+ #include <device/pci.h>
+ #include <device/pci_ids.h>
++#include "drivers/lenovo/lenovo.h"
+
+ extern const unsigned char AmlCode[];
+ #if CONFIG_HAVE_ACPI_SLIC
+@@ -86,6 +87,7 @@ unsigned long acpi_fill_madt(unsigned long current)
+ unsigned long acpi_fill_ssdt_generator(unsigned long current, const char *oem_table_id)
+ {
+ generate_cpu_entries();
++ drivers_lenovo_serial_ports_ssdt_generate("\\_SB.PCI0.LPCB", 1, 1);
+ return (unsigned long) (acpigen_get_current());
+ }
+
+diff --git a/src/mainboard/lenovo/x60/devicetree.cb b/src/mainboard/lenovo/x60/devicetree.cb
+index dc1c5da..6f9d5d9 100644
+--- a/src/mainboard/lenovo/x60/devicetree.cb
++++ b/src/mainboard/lenovo/x60/devicetree.cb
+@@ -25,7 +25,7 @@ chip northbridge/intel/i945
+ register "gpu_hotplug" = "0x00000220"
+ register "gpu_lvds_use_spread_spectrum_clock" = "1"
+ register "gpu_lvds_is_dual_channel" = "0"
+- register "gpu_backlight" = "0x1280128"
++ register "gpu_backlight" = "0x879F879E"
+
+ device cpu_cluster 0 on
+ chip cpu/intel/socket_mFCPGA478
+@@ -130,10 +130,17 @@ chip northbridge/intel/i945
+ chip superio/nsc/pc87382
+ device pnp 164e.2 on # IR
+ io 0x60 = 0x2f8
++ irq 0x29 = 0xb0
++ irq 0x70 = 0x3
++ drq 0x74 = 0x1
++ irq 0xf0 = 0x82
+ end
+
+- device pnp 164e.3 off # Serial Port
+- io 0x60 = 0x3f8
++ device pnp 164e.3 on # Digitizer
++ io 0x60 = 0x200
++ irq 0x29 = 0xb0
++ irq 0x70 = 0x5
++ irq 0xf0 = 0x82
+ end
+
+ device pnp 164e.7 on # GPIO
+diff --git a/src/mainboard/lenovo/x60/romstage.c b/src/mainboard/lenovo/x60/romstage.c
+index 1198fb2..8eca464 100644
+--- a/src/mainboard/lenovo/x60/romstage.c
++++ b/src/mainboard/lenovo/x60/romstage.c
+@@ -86,7 +86,7 @@ static void ich7_enable_lpc(void)
+ // decode range
+ pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x80, 0x0210);
+ // decode range
+- pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x82, 0x1f0d);
++ pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x82, 0x1f0f);
+
+ /* range 0x1600 - 0x167f */
+ pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x84, 0x1601);
+diff --git a/src/northbridge/intel/i945/gma.c b/src/northbridge/intel/i945/gma.c
+index 4dd2ccf..5dbaff3 100644
+--- a/src/northbridge/intel/i945/gma.c
++++ b/src/northbridge/intel/i945/gma.c
+@@ -33,6 +33,8 @@
+
+ #define GDRST 0xc0
+
++#define BSM 0x5c
++
+ #define LVDS_CLOCK_A_POWERUP_ALL (3 << 8)
+ #define LVDS_CLOCK_B_POWERUP_ALL (3 << 4)
+ #define LVDS_CLOCK_BOTH_POWERUP_ALL (3 << 2)
+@@ -51,11 +53,19 @@
+ static int gtt_setup(unsigned int mmiobase)
+ {
+ unsigned long PGETBL_save;
+-
+- PGETBL_save = read32(mmiobase + PGETBL_CTL) & ~PGETBL_ENABLED;
++ unsigned long tom; // top of memory
++
++ /*
++ * The Video BIOS places the GTT right below top of memory.
++ * It is not documented in the Intel 945 datasheet, but the Intel
++ * developers said that it is normally placed there.
++ *
++ * TODO: Add option to make the GTT size runtime
++ * configurable
++ */
++ tom = pci_read_config8(dev_find_slot(0, PCI_DEVFN(0, 0)), TOLUD) << 24;
++ PGETBL_save = tom - 256 * KiB;
+ PGETBL_save |= PGETBL_ENABLED;
+-
+- PGETBL_save |= pci_read_config32(dev_find_slot(0, PCI_DEVFN(2,0)), 0x5c) & 0xfffff000;
+ PGETBL_save |= 2; /* set GTT to 256kb */
+
+ write32(mmiobase + GFX_FLSH_CNTL, 0);
diff --git a/resources/memtest86/patch/COPYING b/resources/memtest86/patch/COPYING
new file mode 100644
index 0000000..b3d325f
--- /dev/null
+++ b/resources/memtest86/patch/COPYING
@@ -0,0 +1,6 @@
+the "gitdiff" file is a patch for MemTest86+ so check that project's copyright information
+to see what conditions apply.
+
+Look in ../../../docs/RELEASE.html for information about where to get libreboot_src.tar.gz
+or libreboot_meta.tar.gz, both of which contain information about the version of MemTest86+
+used and where it came from.
diff --git a/resources/memtest86/patch/diff b/resources/memtest86/patch/diff
new file mode 100644
index 0000000..0abd8d0
--- /dev/null
+++ b/resources/memtest86/patch/diff
@@ -0,0 +1,40 @@
+diff -rupN memtest86+-5.01_/config.h memtest86+-5.01/config.h
+--- memtest86+-5.01_/config.h 2014-06-25 22:57:47.893476783 +0100
++++ memtest86+-5.01/config.h 2014-06-25 22:59:01.269840630 +0100
+@@ -17,7 +17,7 @@
+ #define CONSERVATIVE_SMP 1
+
+ /* BEEP_MODE - Beep on error. Default off, Change to 1 to enable */
+-#define BEEP_MODE 0
++#define BEEP_MODE 1
+
+ /* BEEP_END_NO_ERROR - Beep at end of each pass without error. Default off, Change to 1 to enable */
+ #define BEEP_END_NO_ERROR 0
+@@ -29,13 +29,13 @@
+ /* SERIAL_CONSOLE_DEFAULT - The default state of the serial console. */
+ /* This is normally off since it slows down testing. Change to a 1 */
+ /* to enable. */
+-#define SERIAL_CONSOLE_DEFAULT 0
++#define SERIAL_CONSOLE_DEFAULT 1
+
+ /* SERIAL_TTY - The default serial port to use. 0=ttyS0, 1=ttyS1 */
+ #define SERIAL_TTY 0
+
+ /* SERIAL_BAUD_RATE - Baud rate for the serial console */
+-#define SERIAL_BAUD_RATE 9600
++#define SERIAL_BAUD_RATE 115200
+
+ /* SCRN_DEBUG - extra check for SCREEN_BUFFER
+ */
+diff -rupN memtest86+-5.01_/Makefile memtest86+-5.01/Makefile
+--- memtest86+-5.01_/Makefile 2014-06-25 22:57:47.893476783 +0100
++++ memtest86+-5.01/Makefile 2014-06-25 22:59:19.237929751 +0100
+@@ -21,7 +21,7 @@ OBJS= head.o reloc.o main.o test.o init.
+
+
+ all: clean memtest.bin memtest
+- scp memtest.bin root@192.168.0.12:/srv/tftp/mt86plus
++# scp memtest.bin root@192.168.0.12:/srv/tftp/mt86plus
+
+ # Link it statically once so I know I don't have undefined
+ # symbols and then link it dynamically so I have full