summaryrefslogtreecommitdiff
path: root/chip
diff options
context:
space:
mode:
authorDino Li <dino.li@ite.com.tw>2015-06-16 15:57:07 +0800
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2015-06-23 01:53:46 +0000
commit19424a6c91b19488d04b75491599f4ae719d944d (patch)
tree8ce012cbcc71ba0eae600ea2fba53f6c670912c3 /chip
parentd5c318329abbec47e30fdade870db421c021b826 (diff)
downloadchrome-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.mk1
-rw-r--r--chip/it83xx/config_chip.h1
-rw-r--r--chip/it83xx/registers.h10
-rw-r--r--chip/it83xx/spi.c157
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);