mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-09-21 15:12:04 +00:00
x86: ich-spi: Convert driver to spi-mem ops
With the introduction of the new spi-mem model operations changed slightly. The new spi-mem operations make things a bit easier to handle for ich-spi flash interface. This patch converts the ich-spi driver by using spi-mem operations. Signed-off-by: Bernhard Messerklinger <bernhard.messerklinger@br-automation.com> Reviewed-by: Bin Meng <bmeng.cn@gmail.com> Tested on Intel CrownBay and MinnowMax Tested-by: Bin Meng <bmeng.cn@gmail.com> [bmeng: fix compiler warnings when building the driver for 64-bit] Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
This commit is contained in:
parent
fd95e10178
commit
0709ddb68f
2 changed files with 103 additions and 180 deletions
|
@ -14,6 +14,8 @@
|
||||||
#include <pci_ids.h>
|
#include <pci_ids.h>
|
||||||
#include <spi.h>
|
#include <spi.h>
|
||||||
#include <asm/io.h>
|
#include <asm/io.h>
|
||||||
|
#include <spi-mem.h>
|
||||||
|
#include <div64.h>
|
||||||
|
|
||||||
#include "ich.h"
|
#include "ich.h"
|
||||||
|
|
||||||
|
@ -171,18 +173,6 @@ static int ich_init_controller(struct udevice *dev,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void spi_use_out(struct spi_trans *trans, unsigned bytes)
|
|
||||||
{
|
|
||||||
trans->out += bytes;
|
|
||||||
trans->bytesout -= bytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void spi_use_in(struct spi_trans *trans, unsigned bytes)
|
|
||||||
{
|
|
||||||
trans->in += bytes;
|
|
||||||
trans->bytesin -= bytes;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void spi_lock_down(struct ich_spi_platdata *plat, void *sbase)
|
static void spi_lock_down(struct ich_spi_platdata *plat, void *sbase)
|
||||||
{
|
{
|
||||||
if (plat->ich_version == ICHV_7) {
|
if (plat->ich_version == ICHV_7) {
|
||||||
|
@ -213,47 +203,12 @@ static bool spi_lock_status(struct ich_spi_platdata *plat, void *sbase)
|
||||||
return lock != 0;
|
return lock != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void spi_setup_type(struct spi_trans *trans, int data_bytes)
|
|
||||||
{
|
|
||||||
trans->type = 0xFF;
|
|
||||||
|
|
||||||
/* Try to guess spi type from read/write sizes */
|
|
||||||
if (trans->bytesin == 0) {
|
|
||||||
if (trans->bytesout + data_bytes > 4)
|
|
||||||
/*
|
|
||||||
* If bytesin = 0 and bytesout > 4, we presume this is
|
|
||||||
* a write data operation, which is accompanied by an
|
|
||||||
* address.
|
|
||||||
*/
|
|
||||||
trans->type = SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS;
|
|
||||||
else
|
|
||||||
trans->type = SPI_OPCODE_TYPE_WRITE_NO_ADDRESS;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (trans->bytesout == 1) { /* and bytesin is > 0 */
|
|
||||||
trans->type = SPI_OPCODE_TYPE_READ_NO_ADDRESS;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (trans->bytesout == 4) /* and bytesin is > 0 */
|
|
||||||
trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS;
|
|
||||||
|
|
||||||
/* Fast read command is called with 5 bytes instead of 4 */
|
|
||||||
if (trans->out[0] == SPI_OPCODE_FAST_READ && trans->bytesout == 5) {
|
|
||||||
trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS;
|
|
||||||
--trans->bytesout;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int spi_setup_opcode(struct ich_spi_priv *ctlr, struct spi_trans *trans,
|
static int spi_setup_opcode(struct ich_spi_priv *ctlr, struct spi_trans *trans,
|
||||||
bool lock)
|
bool lock)
|
||||||
{
|
{
|
||||||
uint16_t optypes;
|
uint16_t optypes;
|
||||||
uint8_t opmenu[ctlr->menubytes];
|
uint8_t opmenu[ctlr->menubytes];
|
||||||
|
|
||||||
trans->opcode = trans->out[0];
|
|
||||||
spi_use_out(trans, 1);
|
|
||||||
if (!lock) {
|
if (!lock) {
|
||||||
/* The lock is off, so just use index 0. */
|
/* The lock is off, so just use index 0. */
|
||||||
ich_writeb(ctlr, trans->opcode, ctlr->opmenu);
|
ich_writeb(ctlr, trans->opcode, ctlr->opmenu);
|
||||||
|
@ -285,12 +240,7 @@ static int spi_setup_opcode(struct ich_spi_priv *ctlr, struct spi_trans *trans,
|
||||||
|
|
||||||
optypes = ich_readw(ctlr, ctlr->optype);
|
optypes = ich_readw(ctlr, ctlr->optype);
|
||||||
optype = (optypes >> (opcode_index * 2)) & 0x3;
|
optype = (optypes >> (opcode_index * 2)) & 0x3;
|
||||||
if (trans->type == SPI_OPCODE_TYPE_WRITE_NO_ADDRESS &&
|
|
||||||
optype == SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS &&
|
|
||||||
trans->bytesout >= 3) {
|
|
||||||
/* We guessed wrong earlier. Fix it up. */
|
|
||||||
trans->type = optype;
|
|
||||||
}
|
|
||||||
if (optype != trans->type) {
|
if (optype != trans->type) {
|
||||||
printf("ICH SPI: Transaction doesn't fit type %d\n",
|
printf("ICH SPI: Transaction doesn't fit type %d\n",
|
||||||
optype);
|
optype);
|
||||||
|
@ -300,26 +250,6 @@ static int spi_setup_opcode(struct ich_spi_priv *ctlr, struct spi_trans *trans,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int spi_setup_offset(struct spi_trans *trans)
|
|
||||||
{
|
|
||||||
/* Separate the SPI address and data */
|
|
||||||
switch (trans->type) {
|
|
||||||
case SPI_OPCODE_TYPE_READ_NO_ADDRESS:
|
|
||||||
case SPI_OPCODE_TYPE_WRITE_NO_ADDRESS:
|
|
||||||
return 0;
|
|
||||||
case SPI_OPCODE_TYPE_READ_WITH_ADDRESS:
|
|
||||||
case SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS:
|
|
||||||
trans->offset = ((uint32_t)trans->out[0] << 16) |
|
|
||||||
((uint32_t)trans->out[1] << 8) |
|
|
||||||
((uint32_t)trans->out[2] << 0);
|
|
||||||
spi_use_out(trans, 3);
|
|
||||||
return 1;
|
|
||||||
default:
|
|
||||||
printf("Unrecognized SPI transaction type %#x\n", trans->type);
|
|
||||||
return -EPROTO;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wait for up to 6s til status register bit(s) turn 1 (in case wait_til_set
|
* Wait for up to 6s til status register bit(s) turn 1 (in case wait_til_set
|
||||||
* below is true) or 0. In case the wait was for the bit(s) to set - write
|
* below is true) or 0. In case the wait was for the bit(s) to set - write
|
||||||
|
@ -350,7 +280,7 @@ static int ich_status_poll(struct ich_spi_priv *ctlr, u16 bitmask,
|
||||||
return -ETIMEDOUT;
|
return -ETIMEDOUT;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ich_spi_config_opcode(struct udevice *dev)
|
static void ich_spi_config_opcode(struct udevice *dev)
|
||||||
{
|
{
|
||||||
struct ich_spi_priv *ctlr = dev_get_priv(dev);
|
struct ich_spi_priv *ctlr = dev_get_priv(dev);
|
||||||
|
|
||||||
|
@ -365,90 +295,38 @@ void ich_spi_config_opcode(struct udevice *dev)
|
||||||
ich_writel(ctlr, SPI_OPMENU_UPPER, ctlr->opmenu + sizeof(u32));
|
ich_writel(ctlr, SPI_OPMENU_UPPER, ctlr->opmenu + sizeof(u32));
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ich_spi_xfer(struct udevice *dev, unsigned int bitlen,
|
static int ich_spi_exec_op(struct spi_slave *slave, const struct spi_mem_op *op)
|
||||||
const void *dout, void *din, unsigned long flags)
|
|
||||||
{
|
{
|
||||||
struct udevice *bus = dev_get_parent(dev);
|
struct udevice *bus = dev_get_parent(slave->dev);
|
||||||
struct ich_spi_platdata *plat = dev_get_platdata(bus);
|
struct ich_spi_platdata *plat = dev_get_platdata(bus);
|
||||||
struct ich_spi_priv *ctlr = dev_get_priv(bus);
|
struct ich_spi_priv *ctlr = dev_get_priv(bus);
|
||||||
uint16_t control;
|
uint16_t control;
|
||||||
int16_t opcode_index;
|
int16_t opcode_index;
|
||||||
int with_address;
|
int with_address;
|
||||||
int status;
|
int status;
|
||||||
int bytes = bitlen / 8;
|
|
||||||
struct spi_trans *trans = &ctlr->trans;
|
struct spi_trans *trans = &ctlr->trans;
|
||||||
unsigned type = flags & (SPI_XFER_BEGIN | SPI_XFER_END);
|
|
||||||
int using_cmd = 0;
|
|
||||||
bool lock = spi_lock_status(plat, ctlr->base);
|
bool lock = spi_lock_status(plat, ctlr->base);
|
||||||
int ret;
|
int ret = 0;
|
||||||
|
|
||||||
/* We don't support writing partial bytes */
|
trans->in = NULL;
|
||||||
if (bitlen % 8) {
|
trans->out = NULL;
|
||||||
debug("ICH SPI: Accessing partial bytes not supported\n");
|
trans->type = 0xFF;
|
||||||
return -EPROTONOSUPPORT;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* An empty end transaction can be ignored */
|
if (op->data.nbytes) {
|
||||||
if (type == SPI_XFER_END && !dout && !din)
|
if (op->data.dir == SPI_MEM_DATA_IN) {
|
||||||
return 0;
|
trans->in = op->data.buf.in;
|
||||||
|
trans->bytesin = op->data.nbytes;
|
||||||
if (type & SPI_XFER_BEGIN)
|
} else {
|
||||||
memset(trans, '\0', sizeof(*trans));
|
trans->out = op->data.buf.out;
|
||||||
|
trans->bytesout = op->data.nbytes;
|
||||||
/* Dp we need to come back later to finish it? */
|
|
||||||
if (dout && type == SPI_XFER_BEGIN) {
|
|
||||||
if (bytes > ICH_MAX_CMD_LEN) {
|
|
||||||
debug("ICH SPI: Command length limit exceeded\n");
|
|
||||||
return -ENOSPC;
|
|
||||||
}
|
}
|
||||||
memcpy(trans->cmd, dout, bytes);
|
}
|
||||||
trans->cmd_len = bytes;
|
|
||||||
debug_trace("ICH SPI: Saved %d bytes\n", bytes);
|
if (trans->opcode != op->cmd.opcode)
|
||||||
|
trans->opcode = op->cmd.opcode;
|
||||||
|
|
||||||
|
if (lock && trans->opcode == SPI_OPCODE_WRDIS)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We process a 'middle' spi_xfer() call, which has no
|
|
||||||
* SPI_XFER_BEGIN/END, as an independent transaction as if it had
|
|
||||||
* an end. We therefore repeat the command. This is because ICH
|
|
||||||
* seems to have no support for this, or because interest (in digging
|
|
||||||
* out the details and creating a special case in the code) is low.
|
|
||||||
*/
|
|
||||||
if (trans->cmd_len) {
|
|
||||||
trans->out = trans->cmd;
|
|
||||||
trans->bytesout = trans->cmd_len;
|
|
||||||
using_cmd = 1;
|
|
||||||
debug_trace("ICH SPI: Using %d bytes\n", trans->cmd_len);
|
|
||||||
} else {
|
|
||||||
trans->out = dout;
|
|
||||||
trans->bytesout = dout ? bytes : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
trans->in = din;
|
|
||||||
trans->bytesin = din ? bytes : 0;
|
|
||||||
|
|
||||||
/* There has to always at least be an opcode */
|
|
||||||
if (!trans->bytesout) {
|
|
||||||
debug("ICH SPI: No opcode for transfer\n");
|
|
||||||
return -EPROTO;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = ich_status_poll(ctlr, SPIS_SCIP, 0);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
if (plat->ich_version == ICHV_7)
|
|
||||||
ich_writew(ctlr, SPIS_CDS | SPIS_FCERR, ctlr->status);
|
|
||||||
else
|
|
||||||
ich_writeb(ctlr, SPIS_CDS | SPIS_FCERR, ctlr->status);
|
|
||||||
|
|
||||||
spi_setup_type(trans, using_cmd ? bytes : 0);
|
|
||||||
opcode_index = spi_setup_opcode(ctlr, trans, lock);
|
|
||||||
if (opcode_index < 0)
|
|
||||||
return -EINVAL;
|
|
||||||
with_address = spi_setup_offset(trans);
|
|
||||||
if (with_address < 0)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
if (trans->opcode == SPI_OPCODE_WREN) {
|
if (trans->opcode == SPI_OPCODE_WREN) {
|
||||||
/*
|
/*
|
||||||
|
@ -461,6 +339,40 @@ static int ich_spi_xfer(struct udevice *dev, unsigned int bitlen,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = ich_status_poll(ctlr, SPIS_SCIP, 0);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (plat->ich_version == ICHV_7)
|
||||||
|
ich_writew(ctlr, SPIS_CDS | SPIS_FCERR, ctlr->status);
|
||||||
|
else
|
||||||
|
ich_writeb(ctlr, SPIS_CDS | SPIS_FCERR, ctlr->status);
|
||||||
|
|
||||||
|
/* Try to guess spi transaction type */
|
||||||
|
if (op->data.dir == SPI_MEM_DATA_OUT) {
|
||||||
|
if (op->addr.nbytes)
|
||||||
|
trans->type = SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS;
|
||||||
|
else
|
||||||
|
trans->type = SPI_OPCODE_TYPE_WRITE_NO_ADDRESS;
|
||||||
|
} else {
|
||||||
|
if (op->addr.nbytes)
|
||||||
|
trans->type = SPI_OPCODE_TYPE_READ_WITH_ADDRESS;
|
||||||
|
else
|
||||||
|
trans->type = SPI_OPCODE_TYPE_READ_NO_ADDRESS;
|
||||||
|
}
|
||||||
|
/* Special erase case handling */
|
||||||
|
if (op->addr.nbytes && !op->data.buswidth)
|
||||||
|
trans->type = SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS;
|
||||||
|
|
||||||
|
opcode_index = spi_setup_opcode(ctlr, trans, lock);
|
||||||
|
if (opcode_index < 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (op->addr.nbytes) {
|
||||||
|
trans->offset = op->addr.val;
|
||||||
|
with_address = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (ctlr->speed && ctlr->max_speed >= 33000000) {
|
if (ctlr->speed && ctlr->max_speed >= 33000000) {
|
||||||
int byte;
|
int byte;
|
||||||
|
|
||||||
|
@ -472,13 +384,6 @@ static int ich_spi_xfer(struct udevice *dev, unsigned int bitlen,
|
||||||
ich_writeb(ctlr, byte, ctlr->speed);
|
ich_writeb(ctlr, byte, ctlr->speed);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See if we have used up the command data */
|
|
||||||
if (using_cmd && dout && bytes) {
|
|
||||||
trans->out = dout;
|
|
||||||
trans->bytesout = bytes;
|
|
||||||
debug_trace("ICH SPI: Moving to data, %d bytes\n", bytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Preset control fields */
|
/* Preset control fields */
|
||||||
control = SPIC_SCGO | ((opcode_index & 0x07) << 4);
|
control = SPIC_SCGO | ((opcode_index & 0x07) << 4);
|
||||||
|
|
||||||
|
@ -513,22 +418,6 @@ static int ich_spi_xfer(struct udevice *dev, unsigned int bitlen,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Check if this is a write command atempting to transfer more bytes
|
|
||||||
* than the controller can handle. Iterations for writes are not
|
|
||||||
* supported here because each SPI write command needs to be preceded
|
|
||||||
* and followed by other SPI commands, and this sequence is controlled
|
|
||||||
* by the SPI chip driver.
|
|
||||||
*/
|
|
||||||
if (trans->bytesout > ctlr->databytes) {
|
|
||||||
debug("ICH SPI: Too much to write. This should be prevented by the driver's max_write_size?\n");
|
|
||||||
return -EPROTO;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Read or write up to databytes bytes at a time until everything has
|
|
||||||
* been sent.
|
|
||||||
*/
|
|
||||||
while (trans->bytesout || trans->bytesin) {
|
while (trans->bytesout || trans->bytesin) {
|
||||||
uint32_t data_length;
|
uint32_t data_length;
|
||||||
|
|
||||||
|
@ -543,9 +432,7 @@ static int ich_spi_xfer(struct udevice *dev, unsigned int bitlen,
|
||||||
/* Program data into FDATA0 to N */
|
/* Program data into FDATA0 to N */
|
||||||
if (trans->bytesout) {
|
if (trans->bytesout) {
|
||||||
write_reg(ctlr, trans->out, ctlr->data, data_length);
|
write_reg(ctlr, trans->out, ctlr->data, data_length);
|
||||||
spi_use_out(trans, data_length);
|
trans->bytesout -= data_length;
|
||||||
if (with_address)
|
|
||||||
trans->offset += data_length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add proper control fields' values */
|
/* Add proper control fields' values */
|
||||||
|
@ -568,9 +455,7 @@ static int ich_spi_xfer(struct udevice *dev, unsigned int bitlen,
|
||||||
|
|
||||||
if (trans->bytesin) {
|
if (trans->bytesin) {
|
||||||
read_reg(ctlr, ctlr->data, trans->in, data_length);
|
read_reg(ctlr, ctlr->data, trans->in, data_length);
|
||||||
spi_use_in(trans, data_length);
|
trans->bytesin -= data_length;
|
||||||
if (with_address)
|
|
||||||
trans->offset += data_length;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -581,6 +466,40 @@ static int ich_spi_xfer(struct udevice *dev, unsigned int bitlen,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int ich_spi_adjust_size(struct spi_slave *slave, struct spi_mem_op *op)
|
||||||
|
{
|
||||||
|
unsigned int page_offset;
|
||||||
|
int addr = op->addr.val;
|
||||||
|
unsigned int byte_count = op->data.nbytes;
|
||||||
|
|
||||||
|
if (hweight32(ICH_BOUNDARY) == 1) {
|
||||||
|
page_offset = addr & (ICH_BOUNDARY - 1);
|
||||||
|
} else {
|
||||||
|
u64 aux = addr;
|
||||||
|
|
||||||
|
page_offset = do_div(aux, ICH_BOUNDARY);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (op->data.dir == SPI_MEM_DATA_IN && slave->max_read_size) {
|
||||||
|
op->data.nbytes = min(ICH_BOUNDARY - page_offset,
|
||||||
|
slave->max_read_size);
|
||||||
|
} else if (slave->max_write_size) {
|
||||||
|
op->data.nbytes = min(ICH_BOUNDARY - page_offset,
|
||||||
|
slave->max_write_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
op->data.nbytes = min(op->data.nbytes, byte_count);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ich_spi_xfer(struct udevice *dev, unsigned int bitlen,
|
||||||
|
const void *dout, void *din, unsigned long flags)
|
||||||
|
{
|
||||||
|
printf("ICH SPI: Only supports memory operations\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
static int ich_spi_probe(struct udevice *dev)
|
static int ich_spi_probe(struct udevice *dev)
|
||||||
{
|
{
|
||||||
struct ich_spi_platdata *plat = dev_get_platdata(dev);
|
struct ich_spi_platdata *plat = dev_get_platdata(dev);
|
||||||
|
@ -686,10 +605,17 @@ static int ich_spi_ofdata_to_platdata(struct udevice *dev)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct spi_controller_mem_ops ich_controller_mem_ops = {
|
||||||
|
.adjust_op_size = ich_spi_adjust_size,
|
||||||
|
.supports_op = NULL,
|
||||||
|
.exec_op = ich_spi_exec_op,
|
||||||
|
};
|
||||||
|
|
||||||
static const struct dm_spi_ops ich_spi_ops = {
|
static const struct dm_spi_ops ich_spi_ops = {
|
||||||
.xfer = ich_spi_xfer,
|
.xfer = ich_spi_xfer,
|
||||||
.set_speed = ich_spi_set_speed,
|
.set_speed = ich_spi_set_speed,
|
||||||
.set_mode = ich_spi_set_mode,
|
.set_mode = ich_spi_set_mode,
|
||||||
|
.mem_ops = &ich_controller_mem_ops,
|
||||||
/*
|
/*
|
||||||
* cs_info is not needed, since we require all chip selects to be
|
* cs_info is not needed, since we require all chip selects to be
|
||||||
* in the device tree explicitly
|
* in the device tree explicitly
|
||||||
|
|
|
@ -100,13 +100,8 @@ enum {
|
||||||
HSFC_FSMIE = 0x8000
|
HSFC_FSMIE = 0x8000
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
|
||||||
ICH_MAX_CMD_LEN = 5,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct spi_trans {
|
struct spi_trans {
|
||||||
uint8_t cmd[ICH_MAX_CMD_LEN];
|
uint8_t cmd;
|
||||||
int cmd_len;
|
|
||||||
const uint8_t *out;
|
const uint8_t *out;
|
||||||
uint32_t bytesout;
|
uint32_t bytesout;
|
||||||
uint8_t *in;
|
uint8_t *in;
|
||||||
|
@ -166,6 +161,8 @@ struct spi_trans {
|
||||||
#define SPI_OPMENU_LOWER ((SPI_OPMENU_3 << 24) | (SPI_OPMENU_2 << 16) | \
|
#define SPI_OPMENU_LOWER ((SPI_OPMENU_3 << 24) | (SPI_OPMENU_2 << 16) | \
|
||||||
(SPI_OPMENU_1 << 8) | (SPI_OPMENU_0 << 0))
|
(SPI_OPMENU_1 << 8) | (SPI_OPMENU_0 << 0))
|
||||||
|
|
||||||
|
#define ICH_BOUNDARY 0x1000
|
||||||
|
|
||||||
enum ich_version {
|
enum ich_version {
|
||||||
ICHV_7,
|
ICHV_7,
|
||||||
ICHV_9,
|
ICHV_9,
|
||||||
|
|
Loading…
Reference in a new issue