spi: spi-fsl-dspi: enabling Coldfire mcf5441x dspi

Signed-off-by: Angelo Dureghello <angelo@sysam.it>
Signed-off-by: Mark Brown <broonie@kernel.org>
This commit is contained in:
Angelo Dureghello 2017-10-28 00:23:01 +02:00 committed by Mark Brown
parent 2bd6bf03f4
commit ec7ed7708e
No known key found for this signature in database
GPG Key ID: 24D68B725D5487D0
3 changed files with 77 additions and 22 deletions

View File

@ -379,7 +379,7 @@ config SPI_FSL_DSPI
tristate "Freescale DSPI controller" tristate "Freescale DSPI controller"
select REGMAP_MMIO select REGMAP_MMIO
depends on HAS_DMA depends on HAS_DMA
depends on SOC_VF610 || SOC_LS1021A || ARCH_LAYERSCAPE || COMPILE_TEST depends on SOC_VF610 || SOC_LS1021A || ARCH_LAYERSCAPE || M5441x || COMPILE_TEST
help help
This enables support for the Freescale DSPI controller in master This enables support for the Freescale DSPI controller in master
mode. VF610 platform uses the controller. mode. VF610 platform uses the controller.

View File

@ -32,6 +32,7 @@
#include <linux/regmap.h> #include <linux/regmap.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/spi/spi.h> #include <linux/spi/spi.h>
#include <linux/spi/spi-fsl-dspi.h>
#include <linux/spi/spi_bitbang.h> #include <linux/spi/spi_bitbang.h>
#include <linux/time.h> #include <linux/time.h>
@ -151,6 +152,11 @@ static const struct fsl_dspi_devtype_data ls2085a_data = {
.max_clock_factor = 8, .max_clock_factor = 8,
}; };
static const struct fsl_dspi_devtype_data coldfire_data = {
.trans_mode = DSPI_EOQ_MODE,
.max_clock_factor = 8,
};
struct fsl_dspi_dma { struct fsl_dspi_dma {
/* Length of transfer in words of DSPI_FIFO_SIZE */ /* Length of transfer in words of DSPI_FIFO_SIZE */
u32 curr_xfer_len; u32 curr_xfer_len;
@ -741,6 +747,7 @@ static int dspi_setup(struct spi_device *spi)
{ {
struct chip_data *chip; struct chip_data *chip;
struct fsl_dspi *dspi = spi_master_get_devdata(spi->master); struct fsl_dspi *dspi = spi_master_get_devdata(spi->master);
struct fsl_dspi_platform_data *pdata;
u32 cs_sck_delay = 0, sck_cs_delay = 0; u32 cs_sck_delay = 0, sck_cs_delay = 0;
unsigned char br = 0, pbr = 0, pcssck = 0, cssck = 0; unsigned char br = 0, pbr = 0, pcssck = 0, cssck = 0;
unsigned char pasc = 0, asc = 0, fmsz = 0; unsigned char pasc = 0, asc = 0, fmsz = 0;
@ -761,11 +768,18 @@ static int dspi_setup(struct spi_device *spi)
return -ENOMEM; return -ENOMEM;
} }
pdata = dev_get_platdata(&dspi->pdev->dev);
if (!pdata) {
of_property_read_u32(spi->dev.of_node, "fsl,spi-cs-sck-delay", of_property_read_u32(spi->dev.of_node, "fsl,spi-cs-sck-delay",
&cs_sck_delay); &cs_sck_delay);
of_property_read_u32(spi->dev.of_node, "fsl,spi-sck-cs-delay", of_property_read_u32(spi->dev.of_node, "fsl,spi-sck-cs-delay",
&sck_cs_delay); &sck_cs_delay);
} else {
cs_sck_delay = pdata->cs_sck_delay;
sck_cs_delay = pdata->sck_cs_delay;
}
chip->mcr_val = SPI_MCR_MASTER | SPI_MCR_PCSIS | chip->mcr_val = SPI_MCR_MASTER | SPI_MCR_PCSIS |
SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF; SPI_MCR_CLR_TXF | SPI_MCR_CLR_RXF;
@ -949,6 +963,7 @@ static int dspi_probe(struct platform_device *pdev)
struct fsl_dspi *dspi; struct fsl_dspi *dspi;
struct resource *res; struct resource *res;
void __iomem *base; void __iomem *base;
struct fsl_dspi_platform_data *pdata;
int ret = 0, cs_num, bus_num; int ret = 0, cs_num, bus_num;
master = spi_alloc_master(&pdev->dev, sizeof(struct fsl_dspi)); master = spi_alloc_master(&pdev->dev, sizeof(struct fsl_dspi));
@ -969,6 +984,14 @@ static int dspi_probe(struct platform_device *pdev)
master->bits_per_word_mask = SPI_BPW_MASK(4) | SPI_BPW_MASK(8) | master->bits_per_word_mask = SPI_BPW_MASK(4) | SPI_BPW_MASK(8) |
SPI_BPW_MASK(16); SPI_BPW_MASK(16);
pdata = dev_get_platdata(&pdev->dev);
if (pdata) {
master->num_chipselect = pdata->cs_num;
master->bus_num = pdata->bus_num;
dspi->devtype_data = &coldfire_data;
} else {
ret = of_property_read_u32(np, "spi-num-chipselects", &cs_num); ret = of_property_read_u32(np, "spi-num-chipselects", &cs_num);
if (ret < 0) { if (ret < 0) {
dev_err(&pdev->dev, "can't get spi-num-chipselects\n"); dev_err(&pdev->dev, "can't get spi-num-chipselects\n");
@ -989,6 +1012,7 @@ static int dspi_probe(struct platform_device *pdev)
ret = -EFAULT; ret = -EFAULT;
goto out_master_put; goto out_master_put;
} }
}
res = platform_get_resource(pdev, IORESOURCE_MEM, 0); res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base = devm_ioremap_resource(&pdev->dev, res); base = devm_ioremap_resource(&pdev->dev, res);

View File

@ -0,0 +1,31 @@
/*
* Freescale DSPI controller driver
*
* Copyright (c) 2017 Angelo Dureghello <angelo@sysam.it>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* 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.
*/
#ifndef SPI_FSL_DSPI_HEADER_H
#define SPI_FSL_DSPI_HEADER_H
/**
* struct fsl_dspi_platform_data - platform data for the Freescale DSPI driver
* @bus_num: board specific identifier for this DSPI driver.
* @cs_num: number of chip selects supported by this DSPI driver.
*/
struct fsl_dspi_platform_data {
u32 cs_num;
u32 bus_num;
u32 sck_cs_delay;
u32 cs_sck_delay;
};
#endif /* SPI_FSL_DSPI_HEADER_H */