mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-01 02:32:49 -04:00
spi: s3c64xx: add support for google,gs101-spi
Merge series from Tudor Ambarus <tudor.ambarus@linaro.org>: The Google GCS101 uses a variant of the Samsung SPI controller IP.
This commit is contained in:
@@ -17,6 +17,7 @@ properties:
|
||||
compatible:
|
||||
oneOf:
|
||||
- enum:
|
||||
- google,gs101-spi
|
||||
- samsung,s3c2443-spi # for S3C2443, S3C2416 and S3C2450
|
||||
- samsung,s3c6410-spi
|
||||
- samsung,s5pv210-spi # for S5PV210 and S5PC110
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
#include <linux/platform_data/spi-s3c64xx.h>
|
||||
|
||||
#define MAX_SPI_PORTS 12
|
||||
#define MAX_SPI_PORTS 16
|
||||
#define S3C64XX_SPI_QUIRK_CS_AUTO (1 << 1)
|
||||
#define AUTOSUSPEND_TIMEOUT 2000
|
||||
|
||||
@@ -142,6 +142,7 @@ struct s3c64xx_spi_dma_data {
|
||||
* prescaler unit.
|
||||
* @clk_ioclk: True if clock is present on this device
|
||||
* @has_loopback: True if loopback mode can be supported
|
||||
* @use_32bit_io: True if the SoC allows only 32-bit register accesses.
|
||||
*
|
||||
* The Samsung s3c64xx SPI controller are used on various Samsung SoC's but
|
||||
* differ in some aspects such as the size of the fifo and spi bus clock
|
||||
@@ -158,6 +159,7 @@ struct s3c64xx_spi_port_config {
|
||||
bool clk_from_cmu;
|
||||
bool clk_ioclk;
|
||||
bool has_loopback;
|
||||
bool use_32bit_io;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -414,6 +416,56 @@ static bool s3c64xx_spi_can_dma(struct spi_controller *host,
|
||||
|
||||
}
|
||||
|
||||
static void s3c64xx_iowrite8_32_rep(volatile void __iomem *addr,
|
||||
const void *buffer, unsigned int count)
|
||||
{
|
||||
if (count) {
|
||||
const u8 *buf = buffer;
|
||||
|
||||
do {
|
||||
__raw_writel(*buf++, addr);
|
||||
} while (--count);
|
||||
}
|
||||
}
|
||||
|
||||
static void s3c64xx_iowrite16_32_rep(volatile void __iomem *addr,
|
||||
const void *buffer, unsigned int count)
|
||||
{
|
||||
if (count) {
|
||||
const u16 *buf = buffer;
|
||||
|
||||
do {
|
||||
__raw_writel(*buf++, addr);
|
||||
} while (--count);
|
||||
}
|
||||
}
|
||||
|
||||
static void s3c64xx_iowrite_rep(const struct s3c64xx_spi_driver_data *sdd,
|
||||
struct spi_transfer *xfer)
|
||||
{
|
||||
void __iomem *addr = sdd->regs + S3C64XX_SPI_TX_DATA;
|
||||
const void *buf = xfer->tx_buf;
|
||||
unsigned int len = xfer->len;
|
||||
|
||||
switch (sdd->cur_bpw) {
|
||||
case 32:
|
||||
iowrite32_rep(addr, buf, len / 4);
|
||||
break;
|
||||
case 16:
|
||||
if (sdd->port_conf->use_32bit_io)
|
||||
s3c64xx_iowrite16_32_rep(addr, buf, len / 2);
|
||||
else
|
||||
iowrite16_rep(addr, buf, len / 2);
|
||||
break;
|
||||
default:
|
||||
if (sdd->port_conf->use_32bit_io)
|
||||
s3c64xx_iowrite8_32_rep(addr, buf, len);
|
||||
else
|
||||
iowrite8_rep(addr, buf, len);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int s3c64xx_enable_datapath(struct s3c64xx_spi_driver_data *sdd,
|
||||
struct spi_transfer *xfer, int dma_mode)
|
||||
{
|
||||
@@ -447,20 +499,7 @@ static int s3c64xx_enable_datapath(struct s3c64xx_spi_driver_data *sdd,
|
||||
modecfg |= S3C64XX_SPI_MODE_TXDMA_ON;
|
||||
ret = prepare_dma(&sdd->tx_dma, &xfer->tx_sg);
|
||||
} else {
|
||||
switch (sdd->cur_bpw) {
|
||||
case 32:
|
||||
iowrite32_rep(regs + S3C64XX_SPI_TX_DATA,
|
||||
xfer->tx_buf, xfer->len / 4);
|
||||
break;
|
||||
case 16:
|
||||
iowrite16_rep(regs + S3C64XX_SPI_TX_DATA,
|
||||
xfer->tx_buf, xfer->len / 2);
|
||||
break;
|
||||
default:
|
||||
iowrite8_rep(regs + S3C64XX_SPI_TX_DATA,
|
||||
xfer->tx_buf, xfer->len);
|
||||
break;
|
||||
}
|
||||
s3c64xx_iowrite_rep(sdd, xfer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1495,6 +1534,19 @@ static const struct s3c64xx_spi_port_config fsd_spi_port_config = {
|
||||
.quirks = S3C64XX_SPI_QUIRK_CS_AUTO,
|
||||
};
|
||||
|
||||
static const struct s3c64xx_spi_port_config gs101_spi_port_config = {
|
||||
.fifo_lvl_mask = { 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f,
|
||||
0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f, 0x7f},
|
||||
.rx_lvl_offset = 15,
|
||||
.tx_st_done = 25,
|
||||
.clk_div = 4,
|
||||
.high_speed = true,
|
||||
.clk_from_cmu = true,
|
||||
.has_loopback = true,
|
||||
.use_32bit_io = true,
|
||||
.quirks = S3C64XX_SPI_QUIRK_CS_AUTO,
|
||||
};
|
||||
|
||||
static const struct platform_device_id s3c64xx_spi_driver_ids[] = {
|
||||
{
|
||||
.name = "s3c2443-spi",
|
||||
@@ -1507,6 +1559,9 @@ static const struct platform_device_id s3c64xx_spi_driver_ids[] = {
|
||||
};
|
||||
|
||||
static const struct of_device_id s3c64xx_spi_dt_match[] = {
|
||||
{ .compatible = "google,gs101-spi",
|
||||
.data = &gs101_spi_port_config,
|
||||
},
|
||||
{ .compatible = "samsung,s3c2443-spi",
|
||||
.data = (void *)&s3c2443_spi_port_config,
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user