aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2012-04-15 12:40:49 +0200
committerHarald Welte <laforge@gnumonks.org>2012-04-15 12:40:49 +0200
commitd63da4f70e76c4707d96f4e7f902ce63bb6f1f21 (patch)
tree39c1ec6a25867ee0d60caae9d1cbc823eb34b783
parent6942f3cf662237048ef6ca4007ea345ebe88179e (diff)
add minimalistic CC32 SPI driver
-rw-r--r--src/cc32/cc32_spi.c79
-rw-r--r--src/cc32/cc32_spi.h9
2 files changed, 88 insertions, 0 deletions
diff --git a/src/cc32/cc32_spi.c b/src/cc32/cc32_spi.c
new file mode 100644
index 0000000..09ea845
--- /dev/null
+++ b/src/cc32/cc32_spi.c
@@ -0,0 +1,79 @@
+/*
+ * ChipCity CC32RS512 SPI controller driver
+ *
+ * Copyright (C) 2012 Harald Welte <laforge@gnumonks.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 or
+ * (at your option) version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <errno.h>
+
+#include "cc32_spi.h"
+
+#define CC32_SPI_BASE 0x0f9800
+
+enum cc32_flcon_reg {
+ SPICON2 = 0x08,
+ SPIDAT = 0x0C,
+ SPISTS = 0x10,
+ SPIMSK = 0x14,
+ SPIDMALEN = 0x20,
+ SPIDMACON = 0x28,
+ SPIDMASTS = 0x2C,
+ SPIDMAMSK = 0x30,
+ SPITBUF = 0x40,
+ SPIRBUF = 0x44,
+ SPIDMARPT = 0x48,
+};
+
+#define SPI_REG(x) (uint32_t *)((uint8_t *)CC32_SPI_BASE + x)
+
+#define SPICON2_RUNEN (1 << 7)
+
+#define SPISTS_BOVER (1 << 0)
+#define SPISTS_MODF (1 << 1)
+
+#define SPIMSK_MBOVER (1 << 0)
+
+#define SPIDMACON_FULL_DUPLEX (0 << 1)
+#define SPIDMACON_TX_ONLY (1 << 1)
+#define SPIDMACON_RX_ONLY (2 << 1)
+#define SPIDMACON_START (1 << 0)
+
+#define SPIDMASTS_OVER (1 << 0)
+#define SPIDMASTS_BOVER (1 << 1)
+
+#define SPIDMAMSK_MOVER (1 << 0)
+#define SPIDMAMSK_MBOVER (1 << 1)
+
+int cc32_spi_init(uint8_t cpol, uint8_t cpha, uint8_t divide_2n)
+{
+ uint32_t val;
+
+ if (divide_2n < 2 || divide_2n > 256)
+ return -EINVAL;
+
+ val = ((cpol & 1) << 0) | ((cpha & 1) << 1) | ((divide_2n-1) << 2) | SPICON2_RUNEN;
+
+ *SPI_REG(SPICON2) = val;
+
+ return 0;
+}
+
+int cc32_spi_xcv_byte(uint8_t tx)
+{
+ *SPI_REG(SPIDAT) = tx;
+ while (!(*SPI_REG(SPISTS) & SPISTS_BOVER)) { }
+ return *SPI_REG(SPIDAT);
+}
diff --git a/src/cc32/cc32_spi.h b/src/cc32/cc32_spi.h
new file mode 100644
index 0000000..873ffc1
--- /dev/null
+++ b/src/cc32/cc32_spi.h
@@ -0,0 +1,9 @@
+#ifndef _CC32_SPI_H
+#define _CC32_SPI_H
+
+#include <stdint.h>
+
+int cc32_spi_init(uint8_t cpol, uint8_t cpha, uint8_t divide_2n);
+int cc32_spi_xcv_byte(uint8_t tx);
+
+#endif