2 * (C) Copyright 2010, ucRobotics Inc.
3 * Copyright (c) 2014, Sage Electronic Engineering, LLC
5 * Author: Chong Huang <chuang@ucrobotics.com>
6 * Licensed under the GPL-2 or later.
10 #include <spi_flash.h>
12 #include "spi_flash_internal.h"
14 /* EN25*-specific commands */
15 #define CMD_EN25_WREN 0x06 /* Write Enable */
16 #define CMD_EN25_WRDI 0x04 /* Write Disable */
17 #define CMD_EN25_RDSR 0x05 /* Read Status Register */
18 #define CMD_EN25_WRSR 0x01 /* Write Status Register */
19 #define CMD_EN25_READ 0x03 /* Read Data Bytes */
20 #define CMD_EN25_FAST_READ 0x0b /* Read Data Bytes at Higher Speed */
21 #define CMD_EN25_PP 0x02 /* Page Program */
22 #define CMD_EN25_SE 0x20 /* Sector Erase */
23 #define CMD_EN25_BE 0xd8 /* Block Erase */
24 #define CMD_EN25_DP 0xb9 /* Deep Power-down */
25 #define CMD_EN25_RES 0xab /* Release from DP, and Read Signature */
27 #define EON_ID_EN25Q128 0x3018
28 #define EON_ID_EN25Q64 0x3017
29 #define EON_ID_EN25S64 0x3817
31 struct eon_spi_flash_params
{
35 u16 sectors_per_block
;
40 /* spi_flash needs to be first so upper layers can free() it */
41 struct eon_spi_flash
{
42 struct spi_flash flash
;
43 const struct eon_spi_flash_params
*params
;
46 static inline struct eon_spi_flash
*to_eon_spi_flash(struct spi_flash
*flash
)
48 return container_of(flash
, struct eon_spi_flash
, flash
);
51 static const struct eon_spi_flash_params eon_spi_flash_table
[] = {
53 .id
= EON_ID_EN25Q128
,
55 .pages_per_sector
= 16,
56 .sectors_per_block
= 16,
63 .pages_per_sector
= 16,
64 .sectors_per_block
= 16,
71 .pages_per_sector
= 16,
72 .sectors_per_block
= 16,
78 static int eon_write(struct spi_flash
*flash
,
79 u32 offset
, size_t len
, const void *buf
)
81 struct eon_spi_flash
*eon
= to_eon_spi_flash(flash
);
82 unsigned long byte_addr
;
83 unsigned long page_size
;
89 page_size
= 1 << eon
->params
->page_size
;
90 byte_addr
= offset
% page_size
;
92 flash
->spi
->rw
= SPI_WRITE_FLAG
;
94 for (actual
= 0; actual
< len
; actual
+= chunk_len
) {
95 chunk_len
= min(len
- actual
, page_size
- byte_addr
);
96 chunk_len
= spi_crop_chunk(sizeof(cmd
), chunk_len
);
98 ret
= spi_flash_cmd(flash
->spi
, CMD_EN25_WREN
, NULL
, 0);
100 printk(BIOS_WARNING
, "SF: Enabling Write failed\n");
104 cmd
[0] = CMD_EN25_PP
;
105 cmd
[1] = (offset
>> 16) & 0xff;
106 cmd
[2] = (offset
>> 8) & 0xff;
107 cmd
[3] = offset
& 0xff;
109 #if CONFIG_DEBUG_SPI_FLASH
111 "PP: 0x%p => cmd = { 0x%02x 0x%02x%02x%02x } chunk_len = %zu\n",
112 buf
+ actual
, cmd
[0], cmd
[1], cmd
[2], cmd
[3], chunk_len
);
115 ret
= spi_flash_cmd_write(flash
->spi
, cmd
, sizeof(cmd
),
116 buf
+ actual
, chunk_len
);
118 printk(BIOS_WARNING
, "SF: EON Page Program failed\n");
122 ret
= spi_flash_cmd_wait_ready(flash
, SPI_FLASH_PROG_TIMEOUT
);
124 printk(BIOS_WARNING
, "SF: EON Page Program timeout\n");
132 #if CONFIG_DEBUG_SPI_FLASH
133 printk(BIOS_SPEW
, "SF: EON: Successfully programmed %zu bytes @ %#x\n",
134 len
, (unsigned int)(offset
- len
));
141 struct spi_flash
*spi_flash_probe_eon(struct spi_slave
*spi
, u8
*idcode
)
143 const struct eon_spi_flash_params
*params
;
144 struct eon_spi_flash
*eon
;
147 for (i
= 0; i
< ARRAY_SIZE(eon_spi_flash_table
); ++i
) {
148 params
= &eon_spi_flash_table
[i
];
149 if (params
->id
== ((idcode
[1] << 8) | idcode
[2]))
153 if (i
== ARRAY_SIZE(eon_spi_flash_table
)) {
154 printk(BIOS_WARNING
, "SF: Unsupported EON ID %#02x%02x\n",
155 idcode
[1], idcode
[2]);
159 eon
= malloc(sizeof(*eon
));
161 printk(BIOS_WARNING
, "SF: Failed to allocate memory\n");
165 eon
->params
= params
;
166 eon
->flash
.spi
= spi
;
167 eon
->flash
.name
= params
->name
;
169 eon
->flash
.write
= eon_write
;
170 eon
->flash
.erase
= spi_flash_cmd_erase
;
171 eon
->flash
.read
= spi_flash_cmd_read_fast
;
172 eon
->flash
.sector_size
= params
->page_size
* params
->pages_per_sector
;
173 eon
->flash
.size
= params
->page_size
* params
->pages_per_sector
174 * params
->nr_sectors
;
175 eon
->flash
.erase_cmd
= CMD_EN25_SE
;