blob: a64f25fa5b336a0aaf833a1c162ecaf55a45aa94 [file] [log] [blame]
Rong Changaaa1acf2012-06-21 19:21:18 +08001/*
2 * This file is part of the flashrom project.
3 *
4 * Copyright (C) 2012 Google Inc.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * Neither the name of Google or the names of contributors or
18 * licensors may be used to endorse or promote products derived from this
19 * software without specific prior written permission.
20 *
21 * This software is provided "AS IS," without a warranty of any kind.
22 * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
23 * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
24 * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
25 * GOOGLE INC AND ITS LICENSORS SHALL NOT BE LIABLE
26 * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
27 * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
28 * GOOGLE OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
29 * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
30 * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
31 * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
32 * EVEN IF GOOGLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
33 */
34
35#if defined(__i386__) || defined(__x86_64__)
36#include <inttypes.h>
37#include <string.h>
38#include <unistd.h>
Shawn Nematbakhshb903dfd2012-07-24 15:27:00 -070039#include <sys/time.h>
Rong Changaaa1acf2012-06-21 19:21:18 +080040
41#include "chipdrivers.h"
42#include "flash.h"
43#include "programmer.h"
44#include "spi.h"
45
Shawn Nematbakhsh36046f52012-07-26 09:42:36 -070046/* Supported ENE ECs, ENE_LAST should always be LAST member */
47enum ene_chip_id {
48 ENE_KB932 = 0,
49 ENE_KB94X,
50 ENE_LAST
51};
52
Rong Changd8889e52012-07-27 21:42:25 +080053/* EC state */
54enum ene_ec_state {
55 EC_STATE_NORMAL,
56 EC_STATE_IDLE,
57 EC_STATE_RESET,
58 EC_STATE_UNKNOWN
59};
60
Shawn Nematbakhsh36046f52012-07-26 09:42:36 -070061/* chip-specific parameters */
62typedef struct {
63 enum ene_chip_id chip_id;
64 uint8_t hwver;
65 uint8_t ediid;
Rong Changd8889e52012-07-27 21:42:25 +080066 uint32_t port_bios;
Shawn Nematbakhsh36046f52012-07-26 09:42:36 -070067 uint32_t port_ec_command;
68 uint32_t port_ec_data;
69 uint8_t ec_reset_cmd;
70 uint8_t ec_reset_data;
71 uint8_t ec_restart_cmd;
72 uint8_t ec_restart_data;
Rong Changd8889e52012-07-27 21:42:25 +080073 uint8_t ec_pause_cmd;
74 uint8_t ec_pause_data;
Shawn Nematbakhsh36046f52012-07-26 09:42:36 -070075 uint16_t ec_status_buf;
76 uint8_t ec_is_stopping;
77 uint8_t ec_is_running;
Rong Changd8889e52012-07-27 21:42:25 +080078 uint8_t ec_is_pausing;
Shawn Nematbakhsh36046f52012-07-26 09:42:36 -070079 uint32_t port_io_base;
80} ene_chip;
81
82/* table of supported chips + parameters */
83static ene_chip ene_chips[] = {
84 { ENE_KB932, /* chip_id */
85 0xa2, 0x02, /* hwver + ediid */
Rong Changd8889e52012-07-27 21:42:25 +080086 0x66, /* port_bios */
Shawn Nematbakhsh36046f52012-07-26 09:42:36 -070087 0x6c, 0x68, /* port_ec_{command,data} */
88 0x59, 0xf2, /* ec_reset_{cmd,data} */
89 0x59, 0xf9, /* ec_restart_{cmd,data} */
Rong Changd8889e52012-07-27 21:42:25 +080090 0x59, 0xf1, /* ec_pause_{cmd,data} */
Shawn Nematbakhsh36046f52012-07-26 09:42:36 -070091 0xf554, /* ec_status_buf */
92 0xa5, 0x00, /* ec_is_{stopping,running} masks */
Rong Changd8889e52012-07-27 21:42:25 +080093 0x33, /* ec_is_pausing mask */
Shawn Nematbakhsh36046f52012-07-26 09:42:36 -070094 0xfd60 }, /* port_io_base */
95
Rong Changd8889e52012-07-27 21:42:25 +080096 { ENE_KB94X, /* chip_id */
Shawn Nematbakhsh36046f52012-07-26 09:42:36 -070097 0xa3, 0x05, /* hwver + ediid */
Rong Changd8889e52012-07-27 21:42:25 +080098 0x66, /* port_bios */
Shawn Nematbakhsh36046f52012-07-26 09:42:36 -070099 0x66, 0x68, /* port_ec_{command,data} */
100 0x7d, 0x10, /* ec_reset_{cmd,data} */
101 0x7f, 0x10, /* ec_restart_{cmd,data} */
agnescheng433ff582012-09-26 12:33:35 +0800102 0x7e, 0x10, /* ec_pause_{cmd,data} */
Shawn Nematbakhsh36046f52012-07-26 09:42:36 -0700103 0xf710, /* ec_status_buf */
104 0x02, 0x00, /* ec_is_{stopping,running} masks */
agnescheng433ff582012-09-26 12:33:35 +0800105 0x01, /* ec_is_pausing mask */
Shawn Nematbakhsh36046f52012-07-26 09:42:36 -0700106 0x0380 }, /* port_io_base */
107};
108
109/* pointer to table entry of identified chip */
110static ene_chip *found_chip;
Rong Changd8889e52012-07-27 21:42:25 +0800111/* current ec state */
112static enum ene_ec_state ec_state = EC_STATE_NORMAL;
Shawn Nematbakhsh36046f52012-07-26 09:42:36 -0700113
Rong Changaaa1acf2012-06-21 19:21:18 +0800114#define REG_EC_HWVER 0xff00
115#define REG_EC_FWVER 0xff01
116#define REG_EC_EDIID 0xff24
117#define REG_8051_CTRL 0xff14
Rong Changd8889e52012-07-27 21:42:25 +0800118#define REG_EC_EXTCMD 0xff10
Rong Changaaa1acf2012-06-21 19:21:18 +0800119
Rong Changaaa1acf2012-06-21 19:21:18 +0800120#define CPU_RESET 1
121
122/* Hwardware registers */
123#define REG_SPI_DATA 0xfeab
124#define REG_SPI_COMMAND 0xfeac
125#define REG_SPI_CONFIG 0xfead
126#define CFG_CSn_FORCE_LOW (1 << 4)
127#define CFG_COMMAND_WRITE_ENABLE (1 << 3)
128#define CFG_STATUS (1 << 1)
129#define CFG_ENABLE_BUSY_STATUS_CHECK (1 << 0)
130
131/* Timeout */
132#define EC_COMMAND_TIMEOUT 4
133#define EC_RESTART_TIMEOUT 10
134#define ENE_SPI_DELAY_CYCLE 4
agnescheng433ff582012-09-26 12:33:35 +0800135#define EC_PAUSE_TIMEOUT 12
Shawn Nematbakhsh9c0cd8d2013-05-15 17:07:13 -0700136#define EC_RESET_TRIES 3
agnescheng433ff582012-09-26 12:33:35 +0800137
138#define ENE_KB94X_PAUSE_WAKEUP_PORT 0x64
Rong Changaaa1acf2012-06-21 19:21:18 +0800139
David Hendricks835b3102015-11-05 20:33:00 -0800140#define MASK_INPUT_BUFFER_FULL 2
141#define MASK_OUTPUT_BUFFER_FULL 1
Rong Changaaa1acf2012-06-21 19:21:18 +0800142
Rong Changaaa1acf2012-06-21 19:21:18 +0800143const int port_ene_bank = 1;
144const int port_ene_offset = 2;
145const int port_ene_data = 3;
146
agnescheng433ff582012-09-26 12:33:35 +0800147static struct timeval pause_begin, pause_now;
148
Rong Changaaa1acf2012-06-21 19:21:18 +0800149static void ec_command(uint8_t cmd, uint8_t data)
150{
151 struct timeval begin, now;
152
153 /* Spin wait for EC input buffer empty */
154 gettimeofday(&begin, NULL);
David Hendricks835b3102015-11-05 20:33:00 -0800155 while (INB(found_chip->port_ec_command) & MASK_INPUT_BUFFER_FULL) {
Rong Changaaa1acf2012-06-21 19:21:18 +0800156 gettimeofday(&now, NULL);
157 if ((now.tv_sec - begin.tv_sec) >= EC_COMMAND_TIMEOUT) {
158 msg_pdbg("%s: buf not empty\n", __func__);
159 return;
160 }
161 }
agnescheng433ff582012-09-26 12:33:35 +0800162
Rong Changaaa1acf2012-06-21 19:21:18 +0800163 /* Write command */
Shawn Nematbakhsh36046f52012-07-26 09:42:36 -0700164 OUTB(cmd, found_chip->port_ec_command);
Rong Changaaa1acf2012-06-21 19:21:18 +0800165
Shawn Nematbakhsh36046f52012-07-26 09:42:36 -0700166 if (found_chip->chip_id == ENE_KB932) {
167 /* Spin wait for EC input buffer empty */
168 gettimeofday(&begin, NULL);
169 while (INB(found_chip->port_ec_command) &
David Hendricks835b3102015-11-05 20:33:00 -0800170 MASK_INPUT_BUFFER_FULL) {
Shawn Nematbakhsh36046f52012-07-26 09:42:36 -0700171 gettimeofday(&now, NULL);
172 if ((now.tv_sec - begin.tv_sec) >=
173 EC_COMMAND_TIMEOUT) {
174 msg_pdbg("%s: buf not empty\n", __func__);
175 return;
176 }
Rong Changaaa1acf2012-06-21 19:21:18 +0800177 }
Shawn Nematbakhsh36046f52012-07-26 09:42:36 -0700178 /* Write data */
179 OUTB(data, found_chip->port_ec_data);
Rong Changaaa1acf2012-06-21 19:21:18 +0800180 }
Rong Changaaa1acf2012-06-21 19:21:18 +0800181}
182
183static uint8_t ene_read(uint16_t addr)
184{
Shawn Nematbakhsh36046f52012-07-26 09:42:36 -0700185 uint8_t bank;
186 uint8_t offset;
187 uint8_t data;
188 uint32_t port_io_base;
Rong Changaaa1acf2012-06-21 19:21:18 +0800189
190 bank = addr >> 8;
191 offset = addr & 0xff;
Shawn Nematbakhsh36046f52012-07-26 09:42:36 -0700192 port_io_base = found_chip->port_io_base;
Rong Changaaa1acf2012-06-21 19:21:18 +0800193
194 OUTB(bank, port_io_base + port_ene_bank);
195 OUTB(offset, port_io_base + port_ene_offset);
196 data = INB(port_io_base + port_ene_data);
197
198 return data;
199}
200
201static void ene_write(uint16_t addr, uint8_t data)
202{
Shawn Nematbakhsh36046f52012-07-26 09:42:36 -0700203 uint8_t bank;
204 uint8_t offset;
205 uint32_t port_io_base;
Rong Changaaa1acf2012-06-21 19:21:18 +0800206
207 bank = addr >> 8;
208 offset = addr & 0xff;
Shawn Nematbakhsh36046f52012-07-26 09:42:36 -0700209 port_io_base = found_chip->port_io_base;
Rong Changaaa1acf2012-06-21 19:21:18 +0800210
211 OUTB(bank, port_io_base + port_ene_bank);
212 OUTB(offset, port_io_base + port_ene_offset);
213
214 OUTB(data, port_io_base + port_ene_data);
215}
216
217/**
218 * wait_cycles, wait for n LPC bus clock cycles
219 *
220 * @param n: number of LPC cycles to wait
221 * @return void
222 */
223void wait_cycles(int n)
224{
225 while (n--)
Shawn Nematbakhsh36046f52012-07-26 09:42:36 -0700226 INB(found_chip->port_io_base + port_ene_bank);
Rong Changaaa1acf2012-06-21 19:21:18 +0800227}
228
Rong Changd8889e52012-07-27 21:42:25 +0800229static int is_spicmd_write(uint8_t cmd)
230{
231 switch (cmd) {
Rong Chang7797e4c2012-08-19 00:40:49 +0800232 case JEDEC_WREN:
233 /* Chip Write Enable */
234 case JEDEC_EWSR:
235 /* Write Status Enable */
Rong Changd8889e52012-07-27 21:42:25 +0800236 case JEDEC_CE_60:
237 /* Chip Erase 0x60 */
238 case JEDEC_CE_C7:
239 /* Chip Erase 0xc7 */
240 case JEDEC_BE_52:
241 /* Block Erase 0x52 */
242 case JEDEC_BE_D8:
243 /* Block Erase 0xd8 */
244 case JEDEC_BE_D7:
245 /* Block Erase 0xd7 */
246 case JEDEC_SE:
247 /* Sector Erase */
248 case JEDEC_BYTE_PROGRAM:
249 /* Write memory byte */
250 case JEDEC_AAI_WORD_PROGRAM:
251 /* Write AAI word */
252 return 1;
253 }
254 return 0;
255}
256
Rong Changaaa1acf2012-06-21 19:21:18 +0800257static void ene_spi_start(void)
258{
259 int cfg;
260
261 cfg = ene_read(REG_SPI_CONFIG);
262 cfg |= CFG_CSn_FORCE_LOW;
263 cfg |= CFG_COMMAND_WRITE_ENABLE;
264 ene_write(REG_SPI_CONFIG, cfg);
265
266 wait_cycles(ENE_SPI_DELAY_CYCLE);
267}
268
269static void ene_spi_end(void)
270{
271 int cfg;
272
273 cfg = ene_read(REG_SPI_CONFIG);
274 cfg &= ~CFG_CSn_FORCE_LOW;
275 cfg |= CFG_COMMAND_WRITE_ENABLE;
276 ene_write(REG_SPI_CONFIG, cfg);
277
278 wait_cycles(ENE_SPI_DELAY_CYCLE);
279}
280
281static int ene_spi_wait(void)
282{
283 struct timeval begin, now;
284
285 gettimeofday(&begin, NULL);
286 while(ene_read(REG_SPI_CONFIG) & CFG_STATUS) {
287 gettimeofday(&now, NULL);
288 if ((now.tv_sec - begin.tv_sec) >= EC_COMMAND_TIMEOUT) {
289 msg_pdbg("%s: spi busy\n", __func__);
290 return 1;
291 }
292 }
293 return 0;
294}
295
Rong Changd8889e52012-07-27 21:42:25 +0800296static int ene_pause_ec(void)
297{
298 struct timeval begin, now;
299
300 if (!found_chip->ec_pause_cmd)
301 return -1;
302
303 /* EC prepare pause */
304 ec_command(found_chip->ec_pause_cmd, found_chip->ec_pause_data);
305
306 gettimeofday(&begin, NULL);
307 /* Spin wait for EC ready */
308 while (ene_read(found_chip->ec_status_buf) !=
309 found_chip->ec_is_pausing) {
310 gettimeofday(&now, NULL);
311 if ((now.tv_sec - begin.tv_sec) >=
312 EC_COMMAND_TIMEOUT) {
313 msg_pdbg("%s: unable to pause ec\n", __func__);
314 return -1;
315 }
316 }
317
agnescheng433ff582012-09-26 12:33:35 +0800318
319 gettimeofday(&pause_begin, NULL);
Rong Changd8889e52012-07-27 21:42:25 +0800320 ec_state = EC_STATE_IDLE;
321 return 0;
322}
323
324static int ene_resume_ec(void)
325{
326 struct timeval begin, now;
327
agnescheng433ff582012-09-26 12:33:35 +0800328
329 if (found_chip->chip_id == ENE_KB94X)
330 OUTB(0xff, ENE_KB94X_PAUSE_WAKEUP_PORT);
331 else
332 /* Trigger 8051 interrupt to resume */
333 ene_write(REG_EC_EXTCMD, 0xff);
Rong Changd8889e52012-07-27 21:42:25 +0800334
335 gettimeofday(&begin, NULL);
336 while (ene_read(found_chip->ec_status_buf) !=
337 found_chip->ec_is_running) {
338 gettimeofday(&now, NULL);
339 if ((now.tv_sec - begin.tv_sec) >=
340 EC_COMMAND_TIMEOUT) {
341 msg_pdbg("%s: unable to resume ec\n", __func__);
342 return -1;
343 }
344 }
345
346 ec_state = EC_STATE_NORMAL;
347 return 0;
348}
349
agnescheng433ff582012-09-26 12:33:35 +0800350static int ene_pause_timeout_check(void)
351{
352 gettimeofday(&pause_now, NULL);
353 if ((pause_now.tv_sec - pause_begin.tv_sec) >=
354 EC_PAUSE_TIMEOUT) {
355 if(ene_resume_ec() == 0)
356 ene_pause_ec();
357
358 }
359 return 0;
360}
361
Rong Changd8889e52012-07-27 21:42:25 +0800362static int ene_reset_ec(void)
363{
364 uint8_t reg;
365
366 struct timeval begin, now;
367 gettimeofday(&begin, NULL);
368
369 /* EC prepare reset */
370 ec_command(found_chip->ec_reset_cmd, found_chip->ec_reset_data);
371
372 /* Spin wait for EC ready */
373 while (ene_read(found_chip->ec_status_buf) !=
374 found_chip->ec_is_stopping) {
375 gettimeofday(&now, NULL);
376 if ((now.tv_sec - begin.tv_sec) >=
377 EC_COMMAND_TIMEOUT) {
378 msg_pdbg("%s: unable to reset ec\n", __func__);
379 return -1;
380 }
381 }
382
383 /* Wait 1 second */
384 sleep(1);
385
386 /* Reset 8051 */
387 reg = ene_read(REG_8051_CTRL);
388 reg |= CPU_RESET;
389 ene_write(REG_8051_CTRL, reg);
390
391 ec_state = EC_STATE_RESET;
392 return 0;
393}
394
agnescheng433ff582012-09-26 12:33:35 +0800395static int ene_enter_flash_mode(void)
396{
397 if (ene_pause_ec())
398 return ene_reset_ec();
399 return 0;
400}
401
Souvik Ghoshd75cd672016-06-17 14:21:39 -0700402static int ene_spi_send_command(const struct flashctx *flash,
403 unsigned int writecnt,
Rong Changaaa1acf2012-06-21 19:21:18 +0800404 unsigned int readcnt,
405 const unsigned char *writearr,
406 unsigned char *readarr)
407{
Rong Changaaa1acf2012-06-21 19:21:18 +0800408 int i;
Shawn Nematbakhsh9c0cd8d2013-05-15 17:07:13 -0700409 int tries = EC_RESET_TRIES;
Rong Changaaa1acf2012-06-21 19:21:18 +0800410
Rong Changd8889e52012-07-27 21:42:25 +0800411 if (ec_state == EC_STATE_IDLE && is_spicmd_write(writearr[0])) {
Shawn Nematbakhsh9c0cd8d2013-05-15 17:07:13 -0700412 do {
413 /* Enter reset mode if we need to write/erase */
414 if (ene_resume_ec())
415 continue;
416
417 if (!ene_reset_ec())
418 break;
419 } while (--tries > 0);
420
421 if (!tries) {
422 msg_perr("%s: EC failed reset, skipping write\n",
423 __func__);
424 ec_state = EC_STATE_IDLE;
425 return 1;
426 }
Rong Changd8889e52012-07-27 21:42:25 +0800427 }
agnescheng433ff582012-09-26 12:33:35 +0800428 else if(found_chip->chip_id == ENE_KB94X && ec_state == EC_STATE_IDLE)
429 ene_pause_timeout_check();
Rong Changd8889e52012-07-27 21:42:25 +0800430
Rong Changaaa1acf2012-06-21 19:21:18 +0800431 ene_spi_start();
432
433 for (i = 0; i < writecnt; i++) {
434 ene_write(REG_SPI_COMMAND, writearr[i]);
435 if (ene_spi_wait()) {
436 msg_pdbg("%s: write count %d\n", __func__, i);
437 return 1;
438 }
439 }
440
441 for (i = 0; i < readcnt; i++) {
442 /* Push data by clock the serial bus */
443 ene_write(REG_SPI_COMMAND, 0);
444 if (ene_spi_wait()) {
445 msg_pdbg("%s: read count %d\n", __func__, i);
446 return 1;
447 }
448 readarr[i] = ene_read(REG_SPI_DATA);
449 if (ene_spi_wait()) {
450 msg_pdbg("%s: read count %d\n", __func__, i);
451 return 1;
452 }
453 }
454
455 ene_spi_end();
456 return 0;
457}
458
David Hendricks93784b42016-08-09 17:00:38 -0700459static int ene_leave_flash_mode(void *data)
Rong Changaaa1acf2012-06-21 19:21:18 +0800460{
Rong Changd8889e52012-07-27 21:42:25 +0800461 int rv = 0;
Shawn Nematbakhshb903dfd2012-07-24 15:27:00 -0700462 uint8_t reg;
Rong Changaaa1acf2012-06-21 19:21:18 +0800463 struct timeval begin, now;
464
Rong Changd8889e52012-07-27 21:42:25 +0800465 if (ec_state == EC_STATE_RESET) {
466 reg = ene_read(REG_8051_CTRL);
467 reg &= ~CPU_RESET;
468 ene_write(REG_8051_CTRL, reg);
Rong Changaaa1acf2012-06-21 19:21:18 +0800469
Rong Changd8889e52012-07-27 21:42:25 +0800470 gettimeofday(&begin, NULL);
471 /* EC restart */
472 while (ene_read(found_chip->ec_status_buf) !=
473 found_chip->ec_is_running) {
474 gettimeofday(&now, NULL);
475 if ((now.tv_sec - begin.tv_sec) >=
476 EC_RESTART_TIMEOUT) {
477 msg_pdbg("%s: ec restart busy\n", __func__);
478 rv = 1;
479 goto exit;
480 }
Rong Changaaa1acf2012-06-21 19:21:18 +0800481 }
Rong Changd8889e52012-07-27 21:42:25 +0800482 msg_pdbg("%s: send ec restart\n", __func__);
483 ec_command(found_chip->ec_restart_cmd,
484 found_chip->ec_restart_data);
485
486 ec_state = EC_STATE_NORMAL;
487 rv = 0;
488 goto exit;
Rong Changaaa1acf2012-06-21 19:21:18 +0800489 }
490
Rong Changd8889e52012-07-27 21:42:25 +0800491 rv = ene_resume_ec();
Rong Changea1ec812012-07-21 11:41:32 +0800492
Rong Changd8889e52012-07-27 21:42:25 +0800493exit:
494 /*
495 * Trigger ec interrupt after pause/reset by sending 0x80
496 * to bios command port.
497 */
498 OUTB(0x80, found_chip->port_bios);
499 return rv;
Rong Changaaa1acf2012-06-21 19:21:18 +0800500}
501
502static const struct spi_programmer spi_programmer_ene = {
503 .type = SPI_CONTROLLER_ENE,
504 .max_data_read = 256,
505 .max_data_write = 256,
506 .command = ene_spi_send_command,
507 .multicommand = default_spi_send_multicommand,
508 .read = default_spi_read,
509 .write_256 = default_spi_write_256,
510};
511
Souvik Ghosh63b92f92016-06-29 18:45:52 -0700512int ene_probe_spi_flash(struct flashctx *flash, const char *name)
Rong Changaaa1acf2012-06-21 19:21:18 +0800513{
Shawn Nematbakhsh36046f52012-07-26 09:42:36 -0700514 uint8_t hwver, ediid, i;
Rong Changaaa1acf2012-06-21 19:21:18 +0800515
David Hendricksba0827a2013-05-03 20:25:40 -0700516 if (alias && alias->type != ALIAS_EC)
517 return 1;
518
Rong Changaaa1acf2012-06-21 19:21:18 +0800519 msg_pdbg("%s\n", __func__);
Rong Changaaa1acf2012-06-21 19:21:18 +0800520
Shawn Nematbakhsh36046f52012-07-26 09:42:36 -0700521 for (i = 0; i < ENE_LAST; ++i) {
522 found_chip = &ene_chips[i];
523
524 hwver = ene_read(REG_EC_HWVER);
525 ediid = ene_read(REG_EC_EDIID);
526
527 if(hwver == ene_chips[i].hwver &&
528 ediid == ene_chips[i].ediid) {
529 break;
530 }
531 }
532
533 if (i == ENE_LAST) {
534 msg_pdbg("ENE EC not found (probe failed)\n");
David Hendricks5e79c9f2013-11-04 22:05:08 -0800535 return 1;
Rong Changaaa1acf2012-06-21 19:21:18 +0800536 }
537
538 /* TODO: probe the EC stop protocol
539 *
540 * Compal - ec_command(0x41, 0xa1) returns 43 4f 4d 50 41 4c 9c
541 */
542
543
544 if (register_shutdown(ene_leave_flash_mode, NULL))
545 return 1;
546
547 ene_enter_flash_mode();
548
Souvik Ghosh63b92f92016-06-29 18:45:52 -0700549 flash->pgm->buses_supported |= BUS_LPC;
Rong Changaaa1acf2012-06-21 19:21:18 +0800550 register_spi_programmer(&spi_programmer_ene);
551 msg_pdbg("%s: successfully initialized ene\n", __func__);
552 return 0;
553}
554
555#endif /* __i386__ || __x86_64__ */
556