diff options
author | Harald Welte <laforge@gnumonks.org> | 2012-04-15 12:40:49 +0200 |
---|---|---|
committer | Harald Welte <laforge@gnumonks.org> | 2012-04-15 12:40:49 +0200 |
commit | d63da4f70e76c4707d96f4e7f902ce63bb6f1f21 (patch) | |
tree | 39c1ec6a25867ee0d60caae9d1cbc823eb34b783 | |
parent | 6942f3cf662237048ef6ca4007ea345ebe88179e (diff) |
add minimalistic CC32 SPI driver
-rw-r--r-- | src/cc32/cc32_spi.c | 79 | ||||
-rw-r--r-- | src/cc32/cc32_spi.h | 9 |
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 |