diff options
author | Dino Li <dino.li@ite.com.tw> | 2015-06-16 15:57:07 +0800 |
---|---|---|
committer | ChromeOS Commit Bot <chromeos-commit-bot@chromium.org> | 2015-06-23 01:53:46 +0000 |
commit | 19424a6c91b19488d04b75491599f4ae719d944d (patch) | |
tree | 8ce012cbcc71ba0eae600ea2fba53f6c670912c3 /chip | |
parent | d5c318329abbec47e30fdade870db421c021b826 (diff) | |
download | chrome-ec-19424a6c91b19488d04b75491599f4ae719d944d.tar.gz |
it8380dev: add sspi control module
Add sspi control module for emulation board.
Signed-off-by: Dino Li <dino.li@ite.com.tw>
BRANCH=none
BUG=none
TEST=EVB + Winbond W25Q80 SPI ROM
To define CONFIG_SPI_FLASH, CONFIG_SPI_FLASH_SIZE, and
CONFIG_SPI_FLASH_W25X40
console "spi_flashinfo" can get SPI information
> spi_flashinfo
Manufacturer ID: ef
Device ID: 40 14
Unique ID: c8 60 84 a1 1f 6a 7f 2f
Capacity: 1024 MB
Change-Id: I6c4d4d977536484d47a2207ed80dd0ea08a7c8fd
Reviewed-on: https://chromium-review.googlesource.com/267403
Reviewed-by: Alec Berg <alecaberg@chromium.org>
Commit-Queue: Dino Li <dino.li@ite.com.tw>
Tested-by: Dino Li <dino.li@ite.com.tw>
Diffstat (limited to 'chip')
-rw-r--r-- | chip/it83xx/build.mk | 1 | ||||
-rw-r--r-- | chip/it83xx/config_chip.h | 1 | ||||
-rw-r--r-- | chip/it83xx/registers.h | 10 | ||||
-rw-r--r-- | chip/it83xx/spi.c | 157 |
4 files changed, 168 insertions, 1 deletions
diff --git a/chip/it83xx/build.mk b/chip/it83xx/build.mk index af4ce15cfa..736c71038f 100644 --- a/chip/it83xx/build.mk +++ b/chip/it83xx/build.mk @@ -20,4 +20,5 @@ chip-$(CONFIG_PWM)+=pwm.o chip-$(CONFIG_ADC)+=adc.o chip-$(CONFIG_EC2I)+=ec2i.o chip-$(CONFIG_LPC)+=lpc.o +chip-$(CONFIG_SPI)+=spi.o chip-$(HAS_TASK_KEYSCAN)+=keyboard_raw.o diff --git a/chip/it83xx/config_chip.h b/chip/it83xx/config_chip.h index b6b8239e96..82907551ee 100644 --- a/chip/it83xx/config_chip.h +++ b/chip/it83xx/config_chip.h @@ -83,6 +83,7 @@ #define CONFIG_ADC #define CONFIG_EC2I #define CONFIG_LPC +#define CONFIG_SPI #define GPIO_PIN(port, index) GPIO_##port, (1 << index) #define GPIO_PIN_MASK(port, mask) GPIO_##port, (mask) diff --git a/chip/it83xx/registers.h b/chip/it83xx/registers.h index cf9b227711..dda81ef09f 100644 --- a/chip/it83xx/registers.h +++ b/chip/it83xx/registers.h @@ -800,6 +800,15 @@ REG8(IT83XX_PMC_BASE + (ch > LPC_PM2 ? 3 : 6) + (ch << 4)) #define IT83XX_SMFI_H2RAMECSA REG8(IT83XX_SMFI_BASE+0x7B) #define IT83XX_SMFI_H2RAMHSS REG8(IT83XX_SMFI_BASE+0x7C) +/* Serial Peripheral Interface (SSPI) */ +#define IT83XX_SSPI_BASE 0x00F02600 + +#define IT83XX_SSPI_SPIDATA REG8(IT83XX_SSPI_BASE+0x00) +#define IT83XX_SSPI_SPICTRL1 REG8(IT83XX_SSPI_BASE+0x01) +#define IT83XX_SSPI_SPICTRL2 REG8(IT83XX_SSPI_BASE+0x02) +#define IT83XX_SSPI_SPISTS REG8(IT83XX_SSPI_BASE+0x03) +#define IT83XX_SSPI_SPICTRL3 REG8(IT83XX_SSPI_BASE+0x04) + /* --- MISC (not implemented yet) --- */ #define IT83XX_PS2_BASE 0x00F01700 @@ -810,7 +819,6 @@ REG8(IT83XX_PMC_BASE + (ch > LPC_PM2 ? 3 : 6) + (ch << 4)) #define IT83XX_BRAM_BASE 0x00F02200 #define IT83XX_CIR_BASE 0x00F02300 #define IT83XX_DBGR_BASE 0x00F02500 -#define IT83XX_SSPI_BASE 0x00F02600 #define IT83XX_OW_BASE 0x00F02A00 #define IT83XX_PECI_BASE 0x00F02C00 #define IT83XX_I2C_BASE 0x00F02D00 diff --git a/chip/it83xx/spi.c b/chip/it83xx/spi.c new file mode 100644 index 0000000000..503e4a8d41 --- /dev/null +++ b/chip/it83xx/spi.c @@ -0,0 +1,157 @@ +/* Copyright 2015 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 "clock.h" +#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) + +enum sspi_clk_sel { + sspi_clk_24mhz = 0, + sspi_clk_12mhz, + sspi_clk_8mhz, + sspi_clk_6mhz, + sspi_clk_4p8mhz, + sspi_clk_4mhz, + sspi_clk_3p428mhz, + sspi_clk_3mhz, +}; + +static void sspi_frequency(enum sspi_clk_sel freq) +{ + /* SSPI clock frequency select 48MHz (clk_sspi) */ + IT83XX_ECPM_SCDCR2 &= ~0xF0; + + /* + * bit[6:5] + * Bit 6:Clock Polarity (CLPOL) + * 0: SSCK is low in the idle mode. + * 1: SSCK is high in the idle mode. + * Bit 5:Clock Phase (CLPHS) + * 0: Latch data on the first SSCK edge. + * 1: Latch data on the second SSCK edge. + * + * bit[4:2] + * 000b: 1/2 clk_sspi + * 001b: 1/4 clk_sspi + * 010b: 1/6 clk_sspi + * 011b: 1/8 clk_sspi + * 100b: 1/10 clk_sspi + * 101b: 1/12 clk_sspi + * 110b: 1/14 clk_sspi + * 111b: 1/16 clk_sspi + * + * SSCK frequency is [freq] MHz and mode 3. + * note, clk_sspi need equal to 48MHz above. + */ + IT83XX_SSPI_SPICTRL1 |= (0x60 | (freq << 2)); +} + +static void sspi_transmission_end(void) +{ + /* Write 1 to end the SPI transmission. */ + IT83XX_SSPI_SPISTS = 0x20; + + /* Short delay for "Transfer End Flag" */ + IT83XX_GCTRL_WNCKR = 0; + + /* Write 1 to clear this bit and terminate data transmission. */ + IT83XX_SSPI_SPISTS = 0x02; +} + +int spi_enable(int enable) +{ + if (enable) { + /* + * bit[5:4] + * 00b: SPI channel 0 and channel 1 are disabled. + * 10b: SSCK/SMOSI/SMISO/SSCE1# are enabled. + * 01b: SSCK/SMOSI/SMISO/SSCE0# are enabled. + * 11b: SSCK/SMOSI/SMISO/SSCE1#/SSCE0# are enabled. + */ +#ifdef CONFIG_SPI_USE_CS1 + IT83XX_GPIO_GRC1 |= 0x20; +#else + IT83XX_GPIO_GRC1 |= 0x10; +#endif + gpio_config_module(MODULE_SPI, 1); + } else { + IT83XX_GPIO_GRC1 &= ~0x30; + gpio_config_module(MODULE_SPI, 0); + } + + return EC_SUCCESS; +} + +int spi_transaction(const uint8_t *txdata, int txlen, + uint8_t *rxdata, int rxlen) +{ + int idx; + + /* bit[0]: Write cycle */ + IT83XX_SSPI_SPICTRL2 &= ~0x04; + for (idx = 0x00; idx < txlen; idx++) { + IT83XX_SSPI_SPIDATA = txdata[idx]; +#ifdef CONFIG_SPI_USE_CS1 + /* Write 1 to start the data transmission of CS1 */ + IT83XX_SSPI_SPISTS |= 0x08; +#else + /* Write 1 to start the data transmission of CS0 */ + IT83XX_SSPI_SPISTS |= 0x10; +#endif + } + + /* bit[1]: Read cycle */ + IT83XX_SSPI_SPICTRL2 |= 0x04; + for (idx = 0x00; idx < rxlen; idx++) { +#ifdef CONFIG_SPI_USE_CS1 + /* Write 1 to start the data transmission of CS1 */ + IT83XX_SSPI_SPISTS |= 0x08; +#else + /* Write 1 to start the data transmission of CS0 */ + IT83XX_SSPI_SPISTS |= 0x10; +#endif + rxdata[idx] = IT83XX_SSPI_SPIDATA; + } + + sspi_transmission_end(); + + return EC_SUCCESS; +} + +static void sspi_init(void) +{ + sspi_frequency(sspi_clk_8mhz); + + /* + * bit[5:3] Byte Width (BYTEWIDTH) + * 000b: 8-bit transmission + * 001b: 1-bit transmission + * 010b: 2-bit transmission + * 011b: 3-bit transmission + * 100b: 4-bit transmission + * 101b: 5-bit transmission + * 110b: 6-bit transmission + * 111b: 7-bit transmission + * + * bit[1] Blocking selection + */ + IT83XX_SSPI_SPICTRL2 |= 0x02; + + /* Disabling spi module */ + spi_enable(0); +} +DECLARE_HOOK(HOOK_INIT, sspi_init, HOOK_PRIO_DEFAULT); |