blob: 8d0819aa9d4ba2ca753983a33b789e70c3035c9a [file] [log] [blame]
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +03001/*
2 * This file is part of the flashrom project.
3 *
4 * Copyright (C) 2015 Paul Kocialkowski <contact@paulk.fr>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include <string.h>
18#include "flash.h"
Nico Hubera94ce1c2026-02-19 19:24:44 +010019#include "programmer.h"
Nico Huber6bd4f102026-02-22 23:28:13 +010020#include "chipdrivers/edi.h"
Nico Huberd5185632024-01-05 18:44:41 +010021#include "spi_command.h"
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +030022#include "ene.h"
23#include "edi.h"
24
25static unsigned int edi_read_buffer_length = EDI_READ_BUFFER_LENGTH_DEFAULT;
26
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +030027static void edi_write_cmd(unsigned char *cmd, unsigned short address, unsigned char data)
28{
29 cmd[0] = EDI_WRITE; /* EDI write command. */
30 cmd[1] = 0x00; /* Address is only 2 bytes. */
31 cmd[2] = (address >> 8) & 0xff; /* Address higher byte. */
32 cmd[3] = (address >> 0) & 0xff; /* Address lower byte. */
33 cmd[4] = data; /* Write data. */
34}
35
36static void edi_read_cmd(unsigned char *cmd, unsigned short address)
37{
38 cmd[0] = EDI_READ; /* EDI read command. */
39 cmd[1] = 0x00; /* Address is only 2 bytes. */
40 cmd[2] = (address >> 8) & 0xff; /* Address higher byte. */
41 cmd[3] = (address >> 0) & 0xff; /* Address lower byte. */
42}
43
Nico Hubera94ce1c2026-02-19 19:24:44 +010044static int edi_write(const struct spi_master *spi, unsigned short address, unsigned char data)
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +030045{
46 unsigned char cmd[5];
47 int rc;
48
49 edi_write_cmd(cmd, address, data);
50
Nico Hubera94ce1c2026-02-19 19:24:44 +010051 rc = spi->command(spi, sizeof(cmd), 0, cmd, NULL);
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +030052 if (rc)
53 return -1;
54
55 return 0;
56}
57
Nico Hubera94ce1c2026-02-19 19:24:44 +010058static int edi_read_byte(const struct spi_master *spi, unsigned short address, unsigned char *data)
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +030059{
60 unsigned char cmd[4];
61 unsigned char buffer[edi_read_buffer_length];
62 unsigned int index;
63 unsigned int i;
64 int rc;
65
66 edi_read_cmd(cmd, address);
67
Nico Hubera94ce1c2026-02-19 19:24:44 +010068 rc = spi->command(spi, sizeof(cmd), sizeof(buffer), cmd, buffer);
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +030069 if (rc)
70 return -1;
71
72 index = 0;
73
74 for (i = 0; i < sizeof(buffer); i++) {
75 index = i;
76
77 if (buffer[i] == EDI_NOT_READY)
78 continue;
79
80 if (buffer[i] == EDI_READY) {
81 if (i == (sizeof(buffer) - 1)) {
82 /*
83 * Buffer size was too small for receiving the value.
84 * This is as good as getting only EDI_NOT_READY.
85 */
86
87 buffer[i] = EDI_NOT_READY;
88 break;
89 }
90
91 *data = buffer[i + 1];
92 return 0;
93 }
94 }
95
96 if (buffer[index] == EDI_NOT_READY)
97 return -EDI_NOT_READY;
98
99 return -1;
100}
101
Nico Hubera94ce1c2026-02-19 19:24:44 +0100102static int edi_read(const struct spi_master *spi, unsigned short address, unsigned char *data)
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300103{
104 int rc;
105
106 do {
Nico Hubera94ce1c2026-02-19 19:24:44 +0100107 rc = edi_read_byte(spi, address, data);
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300108 if (rc == -EDI_NOT_READY) {
109 /*
110 * Buffer size is increased, one step at a time,
111 * to hold more data if we only catch EDI_NOT_READY.
112 * Once CS is deasserted, no more data will be sent by the EC,
113 * so we cannot keep reading afterwards and have to start a new
114 * transaction with a longer buffer, to be safe.
115 */
116
117 if (edi_read_buffer_length < EDI_READ_BUFFER_LENGTH_MAX) {
118 msg_pwarn("%s: Retrying read with greater buffer length!\n", __func__);
119 edi_read_buffer_length++;
120 } else {
121 msg_perr("%s: Maximum buffer length reached and data still not ready!\n", __func__);
122 return -1;
123 }
124 } else if (rc < 0) {
125 return -1;
126 }
127 } while (rc == -EDI_NOT_READY);
128
129 return 0;
130}
131
Nico Hubera94ce1c2026-02-19 19:24:44 +0100132static int edi_disable(const struct spi_master *spi)
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300133{
134 unsigned char cmd = EDI_DISABLE;
135 int rc;
136
Nico Hubera94ce1c2026-02-19 19:24:44 +0100137 rc = spi->command(spi, sizeof(cmd), 0, &cmd, NULL);
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300138 if (rc)
139 return -1;
140
141 return 0;
142}
143
Nico Huberf3113ac2026-02-21 12:50:19 +0100144static struct found_id *edi_chip_probe(const struct spi_master *spi)
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300145{
146 unsigned char hwversion;
147 unsigned char ediid;
148 int rc;
149
Nico Hubera94ce1c2026-02-19 19:24:44 +0100150 rc = edi_read(spi, ENE_EC_HWVERSION, &hwversion);
Mike Banon3a826042018-01-15 01:09:16 +0300151 if (rc < 0) {
152 msg_cdbg("%s: reading hwversion failed\n", __func__);
Nico Huberf3113ac2026-02-21 12:50:19 +0100153 return NULL;
Mike Banon3a826042018-01-15 01:09:16 +0300154 }
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300155
Nico Hubera94ce1c2026-02-19 19:24:44 +0100156 rc = edi_read(spi, ENE_EC_EDIID, &ediid);
Mike Banon3a826042018-01-15 01:09:16 +0300157 if (rc < 0) {
158 msg_cdbg("%s: reading ediid failed\n", __func__);
Nico Huberf3113ac2026-02-21 12:50:19 +0100159 return NULL;
Mike Banon3a826042018-01-15 01:09:16 +0300160 }
161
Nico Huberf3113ac2026-02-21 12:50:19 +0100162 struct found_id *const found = calloc(1, sizeof(*found));
163 if (!found) {
164 msg_cerr("Out of memory!\n");
165 return NULL;
166 }
167
168 struct id_info *const id = &found->info.id;
169
170 id->hwversion = hwversion;
171 id->model = ediid;
172 id->type = ID_EDI;
173
Mike Banon3a826042018-01-15 01:09:16 +0300174 msg_cdbg("%s: hwversion 0x%02x, ediid 0x%02x\n", __func__, hwversion, ediid);
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300175
Nico Huberf3113ac2026-02-21 12:50:19 +0100176 return found;
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300177}
178
Nico Hubera94ce1c2026-02-19 19:24:44 +0100179static int edi_spi_enable(const struct spi_master *spi)
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300180{
181 unsigned char buffer;
182 int rc;
183
Nico Hubera94ce1c2026-02-19 19:24:44 +0100184 rc = edi_read(spi, ENE_XBI_EFCFG, &buffer);
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300185 if (rc < 0)
186 return -1;
187
188 buffer |= ENE_XBI_EFCFG_CMD_WE;
189
Nico Hubera94ce1c2026-02-19 19:24:44 +0100190 rc = edi_write(spi, ENE_XBI_EFCFG, buffer);
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300191 if (rc < 0)
192 return -1;
193
194 return 0;
195}
196
Nico Hubera94ce1c2026-02-19 19:24:44 +0100197static int edi_spi_disable(const struct spi_master *spi)
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300198{
199 unsigned char buffer;
200 int rc;
201
Nico Hubera94ce1c2026-02-19 19:24:44 +0100202 rc = edi_read(spi, ENE_XBI_EFCFG, &buffer);
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300203 if (rc < 0)
204 return -1;
205
206 buffer &= ~ENE_XBI_EFCFG_CMD_WE;
207
Nico Hubera94ce1c2026-02-19 19:24:44 +0100208 rc = edi_write(spi, ENE_XBI_EFCFG, buffer);
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300209 if (rc < 0)
210 return -1;
211
212 return 0;
213}
214
Nico Hubera94ce1c2026-02-19 19:24:44 +0100215static int edi_spi_busy(const struct spi_master *spi)
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300216{
217 unsigned char buffer;
218 int rc;
219
Nico Hubera94ce1c2026-02-19 19:24:44 +0100220 rc = edi_read(spi, ENE_XBI_EFCFG, &buffer);
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300221 if (rc < 0)
222 return -1;
223
224 return !!(buffer & ENE_XBI_EFCFG_BUSY);
225}
226
Nico Hubera94ce1c2026-02-19 19:24:44 +0100227static int edi_spi_address(const struct spi_master *spi, unsigned int start, unsigned int address)
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300228{
229 int rc;
230
231 if ((address == start) || (((address - 1) & 0xff) != (address & 0xff))) {
Nico Hubera94ce1c2026-02-19 19:24:44 +0100232 rc = edi_write(spi, ENE_XBI_EFA0, ((address & 0xff) >> 0));
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300233 if (rc < 0)
234 return -1;
235 }
236
237 if ((address == start) || (((address - 1) & 0xff00) != (address & 0xff00))) {
Nico Hubera94ce1c2026-02-19 19:24:44 +0100238 rc = edi_write(spi, ENE_XBI_EFA1, ((address & 0xff00) >> 8));
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300239 if (rc < 0)
240 return -1;
241 }
242
243 if ((address == start) || (((address - 1) & 0xff0000) != (address & 0xff0000))) {
Nico Hubera94ce1c2026-02-19 19:24:44 +0100244 rc = edi_write(spi, ENE_XBI_EFA2, ((address & 0xff0000) >> 16));
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300245 if (rc < 0)
246 return -1;
247 }
248
249 return 0;
250}
251
Nico Hubera94ce1c2026-02-19 19:24:44 +0100252static int edi_8051_reset(const struct spi_master *spi)
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300253{
254 unsigned char buffer;
255 int rc;
256
Nico Hubera94ce1c2026-02-19 19:24:44 +0100257 rc = edi_read(spi, ENE_EC_PXCFG, &buffer);
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300258 if (rc < 0)
259 return -1;
260
261 buffer |= ENE_EC_PXCFG_8051_RESET;
262
Nico Hubera94ce1c2026-02-19 19:24:44 +0100263 rc = edi_write(spi, ENE_EC_PXCFG, buffer);
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300264 if (rc < 0)
265 return -1;
266
267 return 0;
268}
269
Nico Hubera94ce1c2026-02-19 19:24:44 +0100270static int edi_8051_execute(const struct spi_master *spi)
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300271{
272 unsigned char buffer;
273 int rc;
274
Nico Hubera94ce1c2026-02-19 19:24:44 +0100275 rc = edi_read(spi, ENE_EC_PXCFG, &buffer);
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300276 if (rc < 0)
277 return -1;
278
279 buffer &= ~ENE_EC_PXCFG_8051_RESET;
280
Nico Hubera94ce1c2026-02-19 19:24:44 +0100281 rc = edi_write(spi, ENE_EC_PXCFG, buffer);
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300282 if (rc < 0)
283 return -1;
284
285 return 0;
286}
287
288int edi_chip_block_erase(struct flashctx *flash, unsigned int page, unsigned int size)
289{
Nico Hubera94ce1c2026-02-19 19:24:44 +0100290 const struct spi_master *const spi = flash->mst.spi;
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300291 unsigned int timeout = 64;
292 int rc;
293
294 if (size != flash->chip->page_size) {
295 msg_perr("%s: Block erase size is not page size!\n", __func__);
296 return -1;
297 }
298
Nico Hubera94ce1c2026-02-19 19:24:44 +0100299 rc = edi_spi_enable(spi);
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300300 if (rc < 0) {
301 msg_perr("%s: Unable to enable SPI!\n", __func__);
302 return -1;
303 }
304
Nico Hubera94ce1c2026-02-19 19:24:44 +0100305 rc = edi_spi_address(spi, page, page);
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300306 if (rc < 0)
307 return -1;
308
Nico Hubera94ce1c2026-02-19 19:24:44 +0100309 rc = edi_write(spi, ENE_XBI_EFCMD, ENE_XBI_EFCMD_ERASE);
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300310 if (rc < 0)
311 return -1;
312
Nico Hubera94ce1c2026-02-19 19:24:44 +0100313 while (edi_spi_busy(spi) == 1 && timeout) {
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300314 programmer_delay(10);
315 timeout--;
316 }
317
318 if (!timeout) {
319 msg_perr("%s: Timed out waiting for SPI not busy!\n", __func__);
320 return -1;
321 }
322
Nico Hubera94ce1c2026-02-19 19:24:44 +0100323 rc = edi_spi_disable(spi);
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300324 if (rc < 0) {
325 msg_perr("%s: Unable to disable SPI!\n", __func__);
326 return -1;
327 }
328
329 return 0;
330}
331
332int edi_chip_write(struct flashctx *flash, const uint8_t *buf, unsigned int start, unsigned int len)
333{
Nico Hubera94ce1c2026-02-19 19:24:44 +0100334 const struct spi_master *const spi = flash->mst.spi;
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300335 unsigned int address = start;
336 unsigned int pages;
337 unsigned int timeout;
338 unsigned int i, j;
339 int rc;
340
341 if ((start % flash->chip->page_size) != 0) {
342 msg_perr("%s: Start address is not page-aligned!\n", __func__);
343 return -1;
344 }
345
346 if ((len % flash->chip->page_size) != 0) {
347 msg_perr("%s: Length is not page-aligned!\n", __func__);
348 return -1;
349 }
350
351 pages = len / flash->chip->page_size;
352
Nico Hubera94ce1c2026-02-19 19:24:44 +0100353 rc = edi_spi_enable(spi);
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300354 if (rc < 0) {
355 msg_perr("%s: Unable to enable SPI!\n", __func__);
356 return -1;
357 }
358
359 for (i = 0; i < pages; i++) {
360 timeout = 64;
361
362 /* Clear page buffer. */
Nico Hubera94ce1c2026-02-19 19:24:44 +0100363 rc = edi_write(spi, ENE_XBI_EFCMD, ENE_XBI_EFCMD_HVPL_CLEAR);
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300364 if (rc < 0)
365 return -1;
366
367 for (j = 0; j < flash->chip->page_size; j++) {
Nico Hubera94ce1c2026-02-19 19:24:44 +0100368 rc = edi_spi_address(spi, start, address);
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300369 if (rc < 0)
370 return -1;
371
Nico Hubera94ce1c2026-02-19 19:24:44 +0100372 rc = edi_write(spi, ENE_XBI_EFDAT, *buf);
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300373 if (rc < 0)
374 return -1;
375
Nico Hubera94ce1c2026-02-19 19:24:44 +0100376 rc = edi_write(spi, ENE_XBI_EFCMD, ENE_XBI_EFCMD_HVPL_LATCH);
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300377 if (rc < 0)
378 return -1;
379
380 buf++;
381 address++;
382 }
383
384 /* Program page buffer to flash. */
Nico Hubera94ce1c2026-02-19 19:24:44 +0100385 rc = edi_write(spi, ENE_XBI_EFCMD, ENE_XBI_EFCMD_PROGRAM);
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300386 if (rc < 0)
387 return -1;
388
Nico Hubera94ce1c2026-02-19 19:24:44 +0100389 while (edi_spi_busy(spi) == 1 && timeout) {
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300390 programmer_delay(10);
391 timeout--;
392 }
393
394 if (!timeout) {
395 msg_perr("%s: Timed out waiting for SPI not busy!\n", __func__);
396 return -1;
397 }
Richard Hughes842d6782021-01-15 09:48:12 +0000398
399 flashprog_progress_add(flash, flash->chip->page_size);
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300400 }
401
Nico Hubera94ce1c2026-02-19 19:24:44 +0100402 rc = edi_spi_disable(spi);
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300403 if (rc < 0) {
404 msg_perr("%s: Unable to disable SPI!\n", __func__);
405 return -1;
406 }
407
408 return 0;
409}
410
411int edi_chip_read(struct flashctx *flash, uint8_t *buf, unsigned int start, unsigned int len)
412{
Nico Hubera94ce1c2026-02-19 19:24:44 +0100413 const struct spi_master *const spi = flash->mst.spi;
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300414 unsigned int address = start;
415 unsigned int i;
416 unsigned int timeout;
417 int rc;
418
Nico Hubera94ce1c2026-02-19 19:24:44 +0100419 rc = edi_spi_enable(spi);
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300420 if (rc < 0) {
421 msg_perr("%s: Unable to enable SPI!\n", __func__);
422 return -1;
423 }
424
425 /*
426 * EDI brings such a drastic overhead that there is about no need to
427 * have any delay in between calls. The EDI protocol will handle wait
428 * I/O times on its own anyway.
429 */
430
431 for (i = 0; i < len; i++) {
432 timeout = 64;
433
Nico Hubera94ce1c2026-02-19 19:24:44 +0100434 rc = edi_spi_address(spi, start, address);
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300435 if (rc < 0)
436 return -1;
437
Nico Hubera94ce1c2026-02-19 19:24:44 +0100438 rc = edi_write(spi, ENE_XBI_EFCMD, ENE_XBI_EFCMD_READ);
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300439 if (rc < 0)
440 return -1;
441
442 do {
Nico Hubera94ce1c2026-02-19 19:24:44 +0100443 rc = edi_read(spi, ENE_XBI_EFDAT, buf);
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300444 if (rc == 0)
445 break;
446
447 /* Just in case. */
Nico Hubera94ce1c2026-02-19 19:24:44 +0100448 while (edi_spi_busy(spi) == 1 && timeout) {
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300449 programmer_delay(10);
450 timeout--;
451 }
452
453 if (!timeout) {
454 msg_perr("%s: Timed out waiting for SPI not busy!\n", __func__);
455 return -1;
456 }
457 } while (1);
458
459 buf++;
460 address++;
Richard Hughes842d6782021-01-15 09:48:12 +0000461 flashprog_progress_add(flash, 1);
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300462 }
463
Nico Hubera94ce1c2026-02-19 19:24:44 +0100464 rc = edi_spi_disable(spi);
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300465 if (rc < 0) {
466 msg_perr("%s: Unable to disable SPI!\n", __func__);
467 return -1;
468 }
469
470 return 0;
471}
472
Nico Huber4af02fe2026-02-21 12:29:26 +0100473static void edi_finish(struct flashctx *flash)
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300474{
Nico Huber4af02fe2026-02-21 12:29:26 +0100475 const struct spi_master *const spi = flash->mst.spi;
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300476
Nico Huber4af02fe2026-02-21 12:29:26 +0100477 if (edi_8051_execute(spi) < 0)
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300478 msg_perr("%s: Unable to execute 8051!\n", __func__);
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300479
Nico Huber4af02fe2026-02-21 12:29:26 +0100480 if (edi_disable(spi) < 0)
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300481 msg_perr("%s: Unable to disable EDI!\n", __func__);
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300482}
483
Nico Huberf3113ac2026-02-21 12:50:19 +0100484struct found_id *probe_edi(const struct bus_probe *probe, const struct master_common *mst)
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300485{
Nico Huberf3113ac2026-02-21 12:50:19 +0100486 const struct spi_master *const spi = (const struct spi_master *)mst;
Paul Kocialkowskia590f482018-01-15 01:08:39 +0300487 unsigned char hwversion;
488
489 /*
490 * ENE chips enable EDI by detecting a clock frequency between 1 MHz and
491 * 8 MHz. In many cases, the chip won't be able to both detect the clock
492 * signal and serve the associated request at the same time.
493 *
494 * Thus, a dummy read has to be added to ensure that EDI is enabled and
495 * operational starting from the next request. This dummy read below
496 * draws the chip's attention and as result the chip enables its EDI.
497 */
Nico Hubera94ce1c2026-02-19 19:24:44 +0100498 edi_read(spi, ENE_EC_HWVERSION, &hwversion);
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300499
Nico Huberf3113ac2026-02-21 12:50:19 +0100500 return edi_chip_probe(spi);
Nico Huber4af02fe2026-02-21 12:29:26 +0100501}
502
503int edi_prepare(struct flashctx *flash, enum preparation_steps step)
504{
505 int rc;
506
507 if (step < PREPARE_FULL)
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300508 return 0;
509
Nico Huber4af02fe2026-02-21 12:29:26 +0100510 rc = edi_8051_reset(flash->mst.spi);
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300511 if (rc < 0) {
512 msg_perr("%s: Unable to reset 8051!\n", __func__);
Nico Huber4af02fe2026-02-21 12:29:26 +0100513 return rc;
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300514 }
515
Nico Huber4af02fe2026-02-21 12:29:26 +0100516 flash->chip->finish_access = edi_finish;
517 return 0;
Paul Kocialkowski80ae14e2018-01-15 01:07:46 +0300518}