#define MXC_CSPIINT 0x0c
#define MXC_RESET 0x1c
+#define MX3_CSPISTAT 0x14
+#define MX3_CSPISTAT_RR (1 << 3)
+
/* generic defines to abstract from the different register layouts */
#define MXC_INT_RR (1 << 0) /* Receive data ready interrupt */
#define MXC_INT_TE (1 << 1) /* Transmit FIFO empty interrupt */
if (cpu_is_mx31())
reg |= (config->bpw - 1) << MX31_CSPICTRL_BC_SHIFT;
- else if (cpu_is_mx35()) {
+ else if (cpu_is_mx25() || cpu_is_mx35()) {
reg |= (config->bpw - 1) << MX35_CSPICTRL_BL_SHIFT;
reg |= MX31_CSPICTRL_SSCTL;
}
if (config->cs < 0) {
if (cpu_is_mx31())
reg |= (config->cs + 32) << MX31_CSPICTRL_CS_SHIFT;
- else if (cpu_is_mx35())
+ else if (cpu_is_mx25() || cpu_is_mx35())
reg |= (config->cs + 32) << MX35_CSPICTRL_CS_SHIFT;
}
static void spi_imx_chipselect(struct spi_device *spi, int is_active)
{
struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master);
- unsigned int cs = 0;
int gpio = spi_imx->chipselect[spi->chip_select];
- struct spi_imx_config config;
-
- if (spi->mode & SPI_CS_HIGH)
- cs = 1;
+ int active = is_active != BITBANG_CS_INACTIVE;
+ int dev_is_lowactive = !(spi->mode & SPI_CS_HIGH);
- if (is_active == BITBANG_CS_INACTIVE) {
- if (gpio >= 0)
- gpio_set_value(gpio, !cs);
+ if (gpio < 0)
return;
- }
-
- config.bpw = spi->bits_per_word;
- config.speed_hz = spi->max_speed_hz;
- config.mode = spi->mode;
- config.cs = spi_imx->chipselect[spi->chip_select];
-
- spi_imx->config(spi_imx, &config);
-
- /* Initialize the functions for transfer */
- if (config.bpw <= 8) {
- spi_imx->rx = spi_imx_buf_rx_u8;
- spi_imx->tx = spi_imx_buf_tx_u8;
- } else if (config.bpw <= 16) {
- spi_imx->rx = spi_imx_buf_rx_u16;
- spi_imx->tx = spi_imx_buf_tx_u16;
- } else if (config.bpw <= 32) {
- spi_imx->rx = spi_imx_buf_rx_u32;
- spi_imx->tx = spi_imx_buf_tx_u32;
- } else
- BUG();
- if (gpio >= 0)
- gpio_set_value(gpio, cs);
-
- return;
+ gpio_set_value(gpio, dev_is_lowactive ^ active);
}
static void spi_imx_push(struct spi_imx_data *spi_imx)
config.bpw = t ? t->bits_per_word : spi->bits_per_word;
config.speed_hz = t ? t->speed_hz : spi->max_speed_hz;
config.mode = spi->mode;
+ config.cs = spi_imx->chipselect[spi->chip_select];
if (!config.speed_hz)
config.speed_hz = spi->max_speed_hz;
if (!config.speed_hz)
config.speed_hz = spi->max_speed_hz;
+ /* Initialize the functions for transfer */
+ if (config.bpw <= 8) {
+ spi_imx->rx = spi_imx_buf_rx_u8;
+ spi_imx->tx = spi_imx_buf_tx_u8;
+ } else if (config.bpw <= 16) {
+ spi_imx->rx = spi_imx_buf_rx_u16;
+ spi_imx->tx = spi_imx_buf_tx_u16;
+ } else if (config.bpw <= 32) {
+ spi_imx->rx = spi_imx_buf_rx_u32;
+ spi_imx->tx = spi_imx_buf_tx_u32;
+ } else
+ BUG();
+
spi_imx->config(spi_imx, &config);
return 0;
struct spi_imx_data *spi_imx = spi_master_get_devdata(spi->master);
int gpio = spi_imx->chipselect[spi->chip_select];
- if (!spi->bits_per_word)
- spi->bits_per_word = 8;
-
pr_debug("%s: mode %d, %u bpw, %d hz\n", __func__,
spi->mode, spi->bits_per_word, spi->max_speed_hz);
{
}
-static int __init spi_imx_probe(struct platform_device *pdev)
+static int __devinit spi_imx_probe(struct platform_device *pdev)
{
struct spi_imx_master *mxc_platform_info;
struct spi_master *master;
struct resource *res;
int i, ret;
- mxc_platform_info = (struct spi_imx_master *)pdev->dev.platform_data;
+ mxc_platform_info = dev_get_platdata(&pdev->dev);
if (!mxc_platform_info) {
dev_err(&pdev->dev, "can't get the platform data\n");
return -EINVAL;
continue;
ret = gpio_request(spi_imx->chipselect[i], DRIVER_NAME);
if (ret) {
- i--;
- while (i > 0)
+ while (i > 0) {
+ i--;
if (spi_imx->chipselect[i] >= 0)
- gpio_free(spi_imx->chipselect[i--]);
- dev_err(&pdev->dev, "can't get cs gpios");
+ gpio_free(spi_imx->chipselect[i]);
+ }
+ dev_err(&pdev->dev, "can't get cs gpios\n");
goto out_master_put;
}
}
spi_imx->bitbang.txrx_bufs = spi_imx_transfer;
spi_imx->bitbang.master->setup = spi_imx_setup;
spi_imx->bitbang.master->cleanup = spi_imx_cleanup;
+ spi_imx->bitbang.master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH;
init_completion(&spi_imx->xfer_done);
}
spi_imx->irq = platform_get_irq(pdev, 0);
- if (!spi_imx->irq) {
+ if (spi_imx->irq <= 0) {
ret = -EINVAL;
goto out_iounmap;
}
goto out_iounmap;
}
- if (cpu_is_mx31() || cpu_is_mx35()) {
+ if (cpu_is_mx25() || cpu_is_mx31() || cpu_is_mx35()) {
spi_imx->intctrl = mx31_intctrl;
spi_imx->config = mx31_config;
spi_imx->trigger = mx31_trigger;
clk_enable(spi_imx->clk);
spi_imx->spi_clk = clk_get_rate(spi_imx->clk);
- if (!cpu_is_mx31() || !cpu_is_mx35())
+ if (cpu_is_mx1() || cpu_is_mx21() || cpu_is_mx27())
writel(1, spi_imx->base + MXC_RESET);
+ /* drain receive buffer */
+ if (cpu_is_mx25() || cpu_is_mx31() || cpu_is_mx35())
+ while (readl(spi_imx->base + MX3_CSPISTAT) & MX3_CSPISTAT_RR)
+ readl(spi_imx->base + MXC_CSPIRXDATA);
+
spi_imx->intctrl(spi_imx, 0);
ret = spi_bitbang_start(&spi_imx->bitbang);
return ret;
}
-static int __exit spi_imx_remove(struct platform_device *pdev)
+static int __devexit spi_imx_remove(struct platform_device *pdev)
{
struct spi_master *master = platform_get_drvdata(pdev);
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
.owner = THIS_MODULE,
},
.probe = spi_imx_probe,
- .remove = __exit_p(spi_imx_remove),
+ .remove = __devexit_p(spi_imx_remove),
};
static int __init spi_imx_init(void)