| /* |
| * (C) Copyright 2012, Amlogic Inc. |
| * Licensed under the GPL-2 or later. |
| */ |
| |
| #include <common.h> |
| #include <malloc.h> |
| #include <spi_flash.h> |
| #include "spi_flash_amlogic.h" |
| |
| struct pmdevice_spi_flash_params { |
| uint32_t id; |
| uint32_t sector_size; |
| uint32_t block_size; |
| uint32_t chip_size; |
| const char *name; |
| }; |
| |
| /* spi_flash needs to be first so upper layers can free() it */ |
| struct pmdevice_spi_flash { |
| struct spi_flash flash; |
| const struct pmdevice_spi_flash_params *params; |
| }; |
| |
| static inline struct pmdevice_spi_flash *to_pmdevice_spi_flash(struct spi_flash *flash) |
| { |
| return container_of(flash, struct pmdevice_spi_flash, flash); |
| } |
| |
| #define PM_ID_PM25LQ032C 0x9d46 |
| |
| static const struct pmdevice_spi_flash_params pmdevice_spi_flash_table[] = { |
| { .id = PM_ID_PM25LQ032C, |
| .sector_size = 4*1024, |
| .block_size = 16*4*1024 , |
| .chip_size = 4*1024*1024, |
| .name = "PM25LQ032C", |
| }, |
| }; |
| |
| static int pmdevice_write(struct spi_flash *flash, u32 offset, size_t len, const void *buf) |
| { |
| int nReturn = 0; |
| |
| spi_claim_bus(flash->spi); |
| |
| nReturn = spi_flash_write_amlogic(flash, offset, len,buf); |
| |
| spi_release_bus(flash->spi); |
| |
| return nReturn; |
| } |
| |
| static int pmdevice_read_fast(struct spi_flash *flash, u32 offset, size_t len, void *buf) |
| { |
| int nReturn =0; |
| |
| spi_claim_bus(flash->spi); |
| |
| nReturn = spi_flash_read_amlogic(flash, offset, len,buf); |
| |
| spi_release_bus(flash->spi); |
| |
| return nReturn; |
| } |
| static int pmdevice_erase(struct spi_flash *flash, u32 offset, size_t len) |
| { |
| struct pmdevice_spi_flash *stm = to_pmdevice_spi_flash(flash); |
| u32 sector_size; |
| int nReturn; |
| |
| sector_size = stm->params->sector_size; |
| |
| spi_claim_bus(flash->spi); |
| |
| nReturn = spi_flash_erase_amlogic(flash, offset, len, sector_size); |
| |
| spi_release_bus(flash->spi); |
| |
| return nReturn; |
| } |
| |
| struct spi_flash *spi_flash_probe_pmdevice(struct spi_slave *spi, u8 *idcode) |
| { |
| const struct pmdevice_spi_flash_params *params; |
| struct pmdevice_spi_flash *pmdevice; |
| unsigned int i; |
| |
| printf("spi_flash_probe_pmdevice %02x %02x %02x\n", idcode[0], idcode[1], idcode[2]); |
| for (i = 0; i < ARRAY_SIZE(pmdevice_spi_flash_table); ++i) { |
| params = &pmdevice_spi_flash_table[i]; |
| if (((idcode[1] << 8) | idcode[2]) == params->id) |
| break; |
| } |
| |
| if (i == ARRAY_SIZE(pmdevice_spi_flash_table)) { |
| debug("SF: Unsupported pmdevice ID %02x\n", idcode[1]); |
| return NULL; |
| } |
| |
| pmdevice = malloc(sizeof(*pmdevice)); |
| if (!pmdevice) { |
| debug("SF: Failed to allocate memory\n"); |
| return NULL; |
| } |
| |
| pmdevice->params = params; |
| pmdevice->flash.spi = spi; |
| pmdevice->flash.name = params->name; |
| |
| pmdevice->flash.write = pmdevice_write; |
| pmdevice->flash.erase = pmdevice_erase; |
| pmdevice->flash.read = pmdevice_read_fast; |
| |
| pmdevice->flash.size = params->chip_size; |
| |
| debug("SF: Detected %s with page size %u, total %u bytes\n", |
| params->name, params->page_size, pmdevice->flash.size); |
| |
| return &pmdevice->flash; |
| } |
| |