diff options
Diffstat (limited to 'chip/lm4/spi.c')
-rw-r--r-- | chip/lm4/spi.c | 179 |
1 files changed, 0 insertions, 179 deletions
diff --git a/chip/lm4/spi.c b/chip/lm4/spi.c deleted file mode 100644 index 629e306af7..0000000000 --- a/chip/lm4/spi.c +++ /dev/null @@ -1,179 +0,0 @@ -/* Copyright 2013 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* SPI module for Chrome EC */ - -#include "console.h" -#include "gpio.h" -#include "hooks.h" -#include "registers.h" -#include "spi.h" -#include "task.h" -#include "timer.h" -#include "util.h" - -/* Console output macros */ -#define CPUTS(outstr) cputs(CC_SPI, outstr) -#define CPRINTS(format, args...) cprints(CC_SPI, format, ## args) - -int spi_enable(const struct spi_device_t *spi_device, int enable) -{ - if (enable) { - gpio_config_module(MODULE_SPI, 1); - /* - * Don't use the SSI0 frame output. - * CS# is a GPIO so we can keep it low during an entire - * transaction. - */ - gpio_set_flags(spi_device->gpio_cs, GPIO_OUTPUT); - gpio_set_level(spi_device->gpio_cs, 1); - - /* Enable SSI port */ - LM4_SSI_CR1(0) |= 0x02; - } else { - /* Disable SSI port */ - LM4_SSI_CR1(0) &= ~0x02; - - /* Make sure CS# is deselected */ - gpio_set_level(spi_device->gpio_cs, 1); - gpio_set_flags(spi_device->gpio_cs[i], GPIO_ODR_HIGH); - - gpio_config_module(MODULE_SPI, 0); - } - - return EC_SUCCESS; -} - - -int spi_transaction(const struct spi_device_t *spi_device, - const uint8_t *txdata, int txlen, - uint8_t *rxdata, int rxlen) -{ - int totallen = txlen + rxlen; - int txcount = 0, rxcount = 0; - static struct mutex spi_mutex; - volatile uint32_t unused __attribute__((unused)); - - mutex_lock(&spi_mutex); - /* Empty the receive FIFO */ - while (LM4_SSI_SR(0) & LM4_SSI_SR_RNE) - unused = LM4_SSI_DR(0); - - /* Start transaction. Need to do this explicitly because the LM4 - * SSI controller pulses its frame select every byte, and the EEPROM - * wants the chip select held low during the entire transaction. */ - gpio_set_level(spi_device->gpio_cs, 0); - - while (rxcount < totallen) { - /* Handle received bytes if any. We just checked rxcount < - * totallen, so we don't need to worry about overflowing the - * receive buffer. */ - if (LM4_SSI_SR(0) & LM4_SSI_SR_RNE) { - if (rxcount < txlen) { - /* Throw away bytes received while we were - transmitting */ - unused = LM4_SSI_DR(0); - } else - *(rxdata++) = LM4_SSI_DR(0); - rxcount++; - } - - /* Transmit another byte if needed */ - if ((LM4_SSI_SR(0) & LM4_SSI_SR_TNF) && txcount < totallen) { - if (txcount < txlen) - LM4_SSI_DR(0) = *(txdata++); - else { - /* Clock out unused byte so we can clock in the - * response byte */ - LM4_SSI_DR(0) = 0; - } - txcount++; - } - } - - /* End transaction */ - gpio_set_level(spi_device->gpio_cs, 1); - mutex_unlock(&spi_mutex); - - return EC_SUCCESS; -} - -/*****************************************************************************/ -/* Hooks */ - -static int spi_init(void) -{ - /* Enable the SPI module in run and sleep modes */ - clock_enable_peripheral(CGC_OFFSET_SSI, 0x1, - CGC_MODE_RUN | CGC_MODE_SLEEP); - - LM4_SSI_CR1(0) = 0; /* Disable SSI */ - LM4_SSI_CR0(0) = 0x0007; /* SCR=0, SPH=0, SPO=0, FRF=SPI, 8-bit */ - - /* Use PIOSC for clock. This limits us to 8MHz (PIOSC/2), but is - * simpler to configure and we don't need to worry about clock - * frequency changing when the PLL is disabled. If we really start - * using this, might be worth using the system clock and handling - * frequency change (like we do with PECI) so we can go faster. */ - LM4_SSI_CC(0) = 1; - /* SSICLK = PIOSC / (CPSDVSR * (1 + SCR) - * = 16 MHz / (2 * (1 + 0)) - * = 8 MHz */ - LM4_SSI_CPSR(0) = 2; - - /* Ensure the SPI port is disabled. This keeps us from interfering - * with the main chipset when we're not explicitly using the SPI - * bus. */ - spi_enable(SPI_FLASH_DEVICE, 0); - - return EC_SUCCESS; -} -DECLARE_HOOK(HOOK_INIT, spi_init, HOOK_PRIO_INIT_SPI); - -/*****************************************************************************/ -/* Console commands */ - -static int printrx(const char *desc, const uint8_t *txdata, int txlen, - int rxlen) -{ - uint8_t rxdata[32]; - int rv; - int i; - - rv = spi_transaction(SPI_FLASH_DEVICE, txdata, txlen, rxdata, rxlen); - if (rv) - return rv; - - ccprintf("%-12s:", desc); - for (i = 0; i < rxlen; i++) - ccprintf(" 0x%02x", rxdata[i]); - ccputs("\n"); - return EC_SUCCESS; -} - - -static int command_spirom(int argc, char **argv) -{ - uint8_t txmandev[] = {0x90, 0x00, 0x00, 0x00}; - uint8_t txjedec[] = {0x9f}; - uint8_t txunique[] = {0x4b, 0x00, 0x00, 0x00, 0x00}; - uint8_t txsr1[] = {0x05}; - uint8_t txsr2[] = {0x35}; - - spi_enable(SPI_FLASH_DEVICE, 1); - - printrx("Man/Dev ID", txmandev, sizeof(txmandev), 2); - printrx("JEDEC ID", txjedec, sizeof(txjedec), 3); - printrx("Unique ID", txunique, sizeof(txunique), 8); - printrx("Status reg 1", txsr1, sizeof(txsr1), 1); - printrx("Status reg 2", txsr2, sizeof(txsr2), 1); - - spi_enable(SPI_FLASH_DEVICE, 0); - - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(spirom, command_spirom, - NULL, - "Test reading SPI EEPROM"); |