Merge remote-tracking branches 'spi/topic/davinci', 'spi/topic/doc', 'spi/topic/dw' and 'spi/topic/fsl' into spi-next
This commit is contained in:
commit
7020d76971
|
@ -1,5 +1,10 @@
|
|||
Davinci SPI controller device bindings
|
||||
|
||||
Links on DM:
|
||||
Keystone 2 - http://www.ti.com/lit/ug/sprugp2a/sprugp2a.pdf
|
||||
dm644x - http://www.ti.com/lit/ug/sprue32a/sprue32a.pdf
|
||||
OMAP-L138/da830 - http://www.ti.com/lit/ug/spruh77a/spruh77a.pdf
|
||||
|
||||
Required properties:
|
||||
- #address-cells: number of cells required to define a chip select
|
||||
address on the SPI bus. Should be set to 1.
|
||||
|
@ -24,6 +29,30 @@ Optional:
|
|||
cs-gpios = <0>, <0>, <0>, <&gpio1 30 0>, <&gpio1 31 0>;
|
||||
where first three are internal CS and last two are GPIO CS.
|
||||
|
||||
Optional properties for slave devices:
|
||||
SPI slave nodes can contain the following properties.
|
||||
Not all SPI Peripherals from Texas Instruments support this.
|
||||
Please check SPI peripheral documentation for a device before using these.
|
||||
|
||||
- ti,spi-wdelay : delay between transmission of words
|
||||
(SPIFMTn.WDELAY, SPIDAT1.WDEL) must be specified in number of SPI module
|
||||
clock periods.
|
||||
|
||||
delay = WDELAY * SPI_module_clock_period + 2 * SPI_module_clock_period
|
||||
|
||||
Below is timing diagram which shows functional meaning of
|
||||
"ti,spi-wdelay" parameter.
|
||||
|
||||
+-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+
|
||||
SPI_CLK | | | | | | | | | | | | | | | |
|
||||
+----------+ +-+ +-+ +-+ +-+ +---------------------------+ +-+ +-+ +-
|
||||
|
||||
SPI_SOMI/SIMO+-----------------+ +-----------
|
||||
+----------+ word1 +---------------------------+word2
|
||||
+-----------------+ +-----------
|
||||
WDELAY
|
||||
<-------------------------->
|
||||
|
||||
Example of a NOR flash slave device (n25q032) connected to DaVinci
|
||||
SPI controller device over the SPI bus.
|
||||
|
||||
|
@ -43,6 +72,7 @@ spi0:spi@20BF0000 {
|
|||
compatible = "st,m25p32";
|
||||
spi-max-frequency = <25000000>;
|
||||
reg = <0>;
|
||||
ti,spi-wdelay = <8>;
|
||||
|
||||
partition@0 {
|
||||
label = "u-boot-spl";
|
||||
|
|
|
@ -601,13 +601,13 @@ THANKS TO
|
|||
Contributors to Linux-SPI discussions include (in alphabetical order,
|
||||
by last name):
|
||||
|
||||
Mark Brown
|
||||
David Brownell
|
||||
Russell King
|
||||
Grant Likely
|
||||
Dmitry Pervushin
|
||||
Stephen Street
|
||||
Mark Underwood
|
||||
Andrew Victor
|
||||
Vitaly Wool
|
||||
Grant Likely
|
||||
Mark Brown
|
||||
Linus Walleij
|
||||
Vitaly Wool
|
||||
|
|
|
@ -602,7 +602,7 @@ config SPI_DW_PCI
|
|||
depends on SPI_DESIGNWARE && PCI
|
||||
|
||||
config SPI_DW_MID_DMA
|
||||
bool "DMA support for DW SPI controller on Intel Moorestown platform"
|
||||
bool "DMA support for DW SPI controller on Intel MID platform"
|
||||
depends on SPI_DW_PCI && INTEL_MID_DMAC
|
||||
|
||||
config SPI_DW_MMIO
|
||||
|
|
|
@ -65,6 +65,7 @@
|
|||
|
||||
/* SPIDAT1 (upper 16 bit defines) */
|
||||
#define SPIDAT1_CSHOLD_MASK BIT(12)
|
||||
#define SPIDAT1_WDEL BIT(10)
|
||||
|
||||
/* SPIGCR1 */
|
||||
#define SPIGCR1_CLKMOD_MASK BIT(1)
|
||||
|
@ -213,6 +214,7 @@ static void davinci_spi_chipselect(struct spi_device *spi, int value)
|
|||
{
|
||||
struct davinci_spi *dspi;
|
||||
struct davinci_spi_platform_data *pdata;
|
||||
struct davinci_spi_config *spicfg = spi->controller_data;
|
||||
u8 chip_sel = spi->chip_select;
|
||||
u16 spidat1 = CS_DEFAULT;
|
||||
bool gpio_chipsel = false;
|
||||
|
@ -227,6 +229,10 @@ static void davinci_spi_chipselect(struct spi_device *spi, int value)
|
|||
gpio = spi->cs_gpio;
|
||||
}
|
||||
|
||||
/* program delay transfers if tx_delay is non zero */
|
||||
if (spicfg->wdelay)
|
||||
spidat1 |= SPIDAT1_WDEL;
|
||||
|
||||
/*
|
||||
* Board specific chip select logic decides the polarity and cs
|
||||
* line for the controller
|
||||
|
@ -241,9 +247,9 @@ static void davinci_spi_chipselect(struct spi_device *spi, int value)
|
|||
spidat1 |= SPIDAT1_CSHOLD_MASK;
|
||||
spidat1 &= ~(0x1 << chip_sel);
|
||||
}
|
||||
|
||||
iowrite16(spidat1, dspi->base + SPIDAT1 + 2);
|
||||
}
|
||||
|
||||
iowrite16(spidat1, dspi->base + SPIDAT1 + 2);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -289,7 +295,7 @@ static int davinci_spi_setup_transfer(struct spi_device *spi,
|
|||
int prescale;
|
||||
|
||||
dspi = spi_master_get_devdata(spi->master);
|
||||
spicfg = (struct davinci_spi_config *)spi->controller_data;
|
||||
spicfg = spi->controller_data;
|
||||
if (!spicfg)
|
||||
spicfg = &davinci_spi_default_cfg;
|
||||
|
||||
|
@ -336,6 +342,14 @@ static int davinci_spi_setup_transfer(struct spi_device *spi,
|
|||
if (!(spi->mode & SPI_CPHA))
|
||||
spifmt |= SPIFMT_PHASE_MASK;
|
||||
|
||||
/*
|
||||
* Assume wdelay is used only on SPI peripherals that has this field
|
||||
* in SPIFMTn register and when it's configured from board file or DT.
|
||||
*/
|
||||
if (spicfg->wdelay)
|
||||
spifmt |= ((spicfg->wdelay << SPIFMT_WDELAY_SHIFT)
|
||||
& SPIFMT_WDELAY_MASK);
|
||||
|
||||
/*
|
||||
* Version 1 hardware supports two basic SPI modes:
|
||||
* - Standard SPI mode uses 4 pins, with chipselect
|
||||
|
@ -353,9 +367,6 @@ static int davinci_spi_setup_transfer(struct spi_device *spi,
|
|||
|
||||
u32 delay = 0;
|
||||
|
||||
spifmt |= ((spicfg->wdelay << SPIFMT_WDELAY_SHIFT)
|
||||
& SPIFMT_WDELAY_MASK);
|
||||
|
||||
if (spicfg->odd_parity)
|
||||
spifmt |= SPIFMT_ODD_PARITY_MASK;
|
||||
|
||||
|
@ -387,6 +398,26 @@ static int davinci_spi_setup_transfer(struct spi_device *spi,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int davinci_spi_of_setup(struct spi_device *spi)
|
||||
{
|
||||
struct davinci_spi_config *spicfg = spi->controller_data;
|
||||
struct device_node *np = spi->dev.of_node;
|
||||
u32 prop;
|
||||
|
||||
if (spicfg == NULL && np) {
|
||||
spicfg = kzalloc(sizeof(*spicfg), GFP_KERNEL);
|
||||
if (!spicfg)
|
||||
return -ENOMEM;
|
||||
*spicfg = davinci_spi_default_cfg;
|
||||
/* override with dt configured values */
|
||||
if (!of_property_read_u32(np, "ti,spi-wdelay", &prop))
|
||||
spicfg->wdelay = (u8)prop;
|
||||
spi->controller_data = spicfg;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* davinci_spi_setup - This functions will set default transfer method
|
||||
* @spi: spi device on which data transfer to be done
|
||||
|
@ -437,7 +468,16 @@ static int davinci_spi_setup(struct spi_device *spi)
|
|||
else
|
||||
clear_io_bits(dspi->base + SPIGCR1, SPIGCR1_LOOPBACK_MASK);
|
||||
|
||||
return retval;
|
||||
return davinci_spi_of_setup(spi);
|
||||
}
|
||||
|
||||
static void davinci_spi_cleanup(struct spi_device *spi)
|
||||
{
|
||||
struct davinci_spi_config *spicfg = spi->controller_data;
|
||||
|
||||
spi->controller_data = NULL;
|
||||
if (spi->dev.of_node)
|
||||
kfree(spicfg);
|
||||
}
|
||||
|
||||
static int davinci_spi_check_error(struct davinci_spi *dspi, int int_status)
|
||||
|
@ -951,6 +991,7 @@ static int davinci_spi_probe(struct platform_device *pdev)
|
|||
master->num_chipselect = pdata->num_chipselect;
|
||||
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(2, 16);
|
||||
master->setup = davinci_spi_setup;
|
||||
master->cleanup = davinci_spi_cleanup;
|
||||
|
||||
dspi->bitbang.chipselect = davinci_spi_chipselect;
|
||||
dspi->bitbang.setup_transfer = davinci_spi_setup_transfer;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* Special handling for DW core on Intel MID platform
|
||||
*
|
||||
* Copyright (c) 2009, Intel Corporation.
|
||||
* Copyright (c) 2009, 2014 Intel Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -11,10 +11,6 @@
|
|||
* 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, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <linux/dma-mapping.h>
|
||||
|
@ -39,22 +35,25 @@ static bool mid_spi_dma_chan_filter(struct dma_chan *chan, void *param)
|
|||
{
|
||||
struct dw_spi *dws = param;
|
||||
|
||||
return dws->dmac && (&dws->dmac->dev == chan->device->dev);
|
||||
return dws->dma_dev == chan->device->dev;
|
||||
}
|
||||
|
||||
static int mid_spi_dma_init(struct dw_spi *dws)
|
||||
{
|
||||
struct mid_dma *dw_dma = dws->dma_priv;
|
||||
struct pci_dev *dma_dev;
|
||||
struct intel_mid_dma_slave *rxs, *txs;
|
||||
dma_cap_mask_t mask;
|
||||
|
||||
/*
|
||||
* Get pci device for DMA controller, currently it could only
|
||||
* be the DMA controller of either Moorestown or Medfield
|
||||
* be the DMA controller of Medfield
|
||||
*/
|
||||
dws->dmac = pci_get_device(PCI_VENDOR_ID_INTEL, 0x0813, NULL);
|
||||
if (!dws->dmac)
|
||||
dws->dmac = pci_get_device(PCI_VENDOR_ID_INTEL, 0x0827, NULL);
|
||||
dma_dev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x0827, NULL);
|
||||
if (!dma_dev)
|
||||
return -ENODEV;
|
||||
|
||||
dws->dma_dev = &dma_dev->dev;
|
||||
|
||||
dma_cap_zero(mask);
|
||||
dma_cap_set(DMA_SLAVE, mask);
|
||||
|
@ -83,13 +82,18 @@ static int mid_spi_dma_init(struct dw_spi *dws)
|
|||
free_rxchan:
|
||||
dma_release_channel(dws->rxchan);
|
||||
err_exit:
|
||||
return -1;
|
||||
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
static void mid_spi_dma_exit(struct dw_spi *dws)
|
||||
{
|
||||
if (!dws->dma_inited)
|
||||
return;
|
||||
|
||||
dmaengine_terminate_all(dws->txchan);
|
||||
dma_release_channel(dws->txchan);
|
||||
|
||||
dmaengine_terminate_all(dws->rxchan);
|
||||
dma_release_channel(dws->rxchan);
|
||||
}
|
||||
|
||||
|
@ -109,8 +113,7 @@ static void dw_spi_dma_done(void *arg)
|
|||
|
||||
static int mid_spi_dma_transfer(struct dw_spi *dws, int cs_change)
|
||||
{
|
||||
struct dma_async_tx_descriptor *txdesc = NULL, *rxdesc = NULL;
|
||||
struct dma_chan *txchan, *rxchan;
|
||||
struct dma_async_tx_descriptor *txdesc, *rxdesc;
|
||||
struct dma_slave_config txconf, rxconf;
|
||||
u16 dma_ctrl = 0;
|
||||
|
||||
|
@ -120,37 +123,34 @@ static int mid_spi_dma_transfer(struct dw_spi *dws, int cs_change)
|
|||
dw_writew(dws, DW_SPI_DMARDLR, 0xf);
|
||||
dw_writew(dws, DW_SPI_DMATDLR, 0x10);
|
||||
if (dws->tx_dma)
|
||||
dma_ctrl |= 0x2;
|
||||
dma_ctrl |= SPI_DMA_TDMAE;
|
||||
if (dws->rx_dma)
|
||||
dma_ctrl |= 0x1;
|
||||
dma_ctrl |= SPI_DMA_RDMAE;
|
||||
dw_writew(dws, DW_SPI_DMACR, dma_ctrl);
|
||||
spi_enable_chip(dws, 1);
|
||||
}
|
||||
|
||||
dws->dma_chan_done = 0;
|
||||
txchan = dws->txchan;
|
||||
rxchan = dws->rxchan;
|
||||
|
||||
/* 2. Prepare the TX dma transfer */
|
||||
txconf.direction = DMA_MEM_TO_DEV;
|
||||
txconf.dst_addr = dws->dma_addr;
|
||||
txconf.dst_maxburst = LNW_DMA_MSIZE_16;
|
||||
txconf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
||||
txconf.dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
|
||||
txconf.dst_addr_width = dws->dma_width;
|
||||
txconf.device_fc = false;
|
||||
|
||||
txchan->device->device_control(txchan, DMA_SLAVE_CONFIG,
|
||||
(unsigned long) &txconf);
|
||||
dmaengine_slave_config(dws->txchan, &txconf);
|
||||
|
||||
memset(&dws->tx_sgl, 0, sizeof(dws->tx_sgl));
|
||||
dws->tx_sgl.dma_address = dws->tx_dma;
|
||||
dws->tx_sgl.length = dws->len;
|
||||
|
||||
txdesc = dmaengine_prep_slave_sg(txchan,
|
||||
txdesc = dmaengine_prep_slave_sg(dws->txchan,
|
||||
&dws->tx_sgl,
|
||||
1,
|
||||
DMA_MEM_TO_DEV,
|
||||
DMA_PREP_INTERRUPT);
|
||||
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
|
||||
txdesc->callback = dw_spi_dma_done;
|
||||
txdesc->callback_param = dws;
|
||||
|
||||
|
@ -159,27 +159,30 @@ static int mid_spi_dma_transfer(struct dw_spi *dws, int cs_change)
|
|||
rxconf.src_addr = dws->dma_addr;
|
||||
rxconf.src_maxburst = LNW_DMA_MSIZE_16;
|
||||
rxconf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
|
||||
rxconf.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
|
||||
rxconf.src_addr_width = dws->dma_width;
|
||||
rxconf.device_fc = false;
|
||||
|
||||
rxchan->device->device_control(rxchan, DMA_SLAVE_CONFIG,
|
||||
(unsigned long) &rxconf);
|
||||
dmaengine_slave_config(dws->rxchan, &rxconf);
|
||||
|
||||
memset(&dws->rx_sgl, 0, sizeof(dws->rx_sgl));
|
||||
dws->rx_sgl.dma_address = dws->rx_dma;
|
||||
dws->rx_sgl.length = dws->len;
|
||||
|
||||
rxdesc = dmaengine_prep_slave_sg(rxchan,
|
||||
rxdesc = dmaengine_prep_slave_sg(dws->rxchan,
|
||||
&dws->rx_sgl,
|
||||
1,
|
||||
DMA_DEV_TO_MEM,
|
||||
DMA_PREP_INTERRUPT);
|
||||
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
|
||||
rxdesc->callback = dw_spi_dma_done;
|
||||
rxdesc->callback_param = dws;
|
||||
|
||||
/* rx must be started before tx due to spi instinct */
|
||||
rxdesc->tx_submit(rxdesc);
|
||||
txdesc->tx_submit(txdesc);
|
||||
dmaengine_submit(rxdesc);
|
||||
dma_async_issue_pending(dws->rxchan);
|
||||
|
||||
dmaengine_submit(txdesc);
|
||||
dma_async_issue_pending(dws->txchan);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -190,7 +193,7 @@ static struct dw_spi_dma_ops mid_dma_ops = {
|
|||
};
|
||||
#endif
|
||||
|
||||
/* Some specific info for SPI0 controller on Moorestown */
|
||||
/* Some specific info for SPI0 controller on Intel MID */
|
||||
|
||||
/* HW info for MRST CLk Control Unit, one 32b reg */
|
||||
#define MRST_SPI_CLK_BASE 100000000 /* 100m */
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
* PCI interface driver for DW SPI Core
|
||||
*
|
||||
* Copyright (c) 2009, Intel Corporation.
|
||||
* Copyright (c) 2009, 2014 Intel Corporation.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
|
@ -11,10 +11,6 @@
|
|||
* 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, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <linux/interrupt.h>
|
||||
|
@ -32,17 +28,22 @@ struct dw_spi_pci {
|
|||
struct dw_spi dws;
|
||||
};
|
||||
|
||||
static int spi_pci_probe(struct pci_dev *pdev,
|
||||
const struct pci_device_id *ent)
|
||||
struct spi_pci_desc {
|
||||
int (*setup)(struct dw_spi *);
|
||||
};
|
||||
|
||||
static struct spi_pci_desc spi_pci_mid_desc = {
|
||||
.setup = dw_spi_mid_init,
|
||||
};
|
||||
|
||||
static int spi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
|
||||
{
|
||||
struct dw_spi_pci *dwpci;
|
||||
struct dw_spi *dws;
|
||||
struct spi_pci_desc *desc = (struct spi_pci_desc *)ent->driver_data;
|
||||
int pci_bar = 0;
|
||||
int ret;
|
||||
|
||||
dev_info(&pdev->dev, "found PCI SPI controller(ID: %04x:%04x)\n",
|
||||
pdev->vendor, pdev->device);
|
||||
|
||||
ret = pcim_enable_device(pdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
@ -58,7 +59,7 @@ static int spi_pci_probe(struct pci_dev *pdev,
|
|||
/* Get basic io resource and map it */
|
||||
dws->paddr = pci_resource_start(pdev, pci_bar);
|
||||
|
||||
ret = pcim_iomap_regions(pdev, 1, dev_name(&pdev->dev));
|
||||
ret = pcim_iomap_regions(pdev, 1 << pci_bar, pci_name(pdev));
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -69,11 +70,11 @@ static int spi_pci_probe(struct pci_dev *pdev,
|
|||
dws->irq = pdev->irq;
|
||||
|
||||
/*
|
||||
* Specific handling for Intel MID paltforms, like dma setup,
|
||||
* Specific handling for paltforms, like dma setup,
|
||||
* clock rate, FIFO depth.
|
||||
*/
|
||||
if (pdev->device == 0x0800) {
|
||||
ret = dw_spi_mid_init(dws);
|
||||
if (desc && desc->setup) {
|
||||
ret = desc->setup(dws);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
@ -85,6 +86,9 @@ static int spi_pci_probe(struct pci_dev *pdev,
|
|||
/* PCI hook and SPI hook use the same drv data */
|
||||
pci_set_drvdata(pdev, dwpci);
|
||||
|
||||
dev_info(&pdev->dev, "found PCI SPI controller(ID: %04x:%04x)\n",
|
||||
pdev->vendor, pdev->device);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -95,41 +99,29 @@ static void spi_pci_remove(struct pci_dev *pdev)
|
|||
dw_spi_remove_host(&dwpci->dws);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int spi_suspend(struct pci_dev *pdev, pm_message_t state)
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
static int spi_suspend(struct device *dev)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
struct dw_spi_pci *dwpci = pci_get_drvdata(pdev);
|
||||
int ret;
|
||||
|
||||
ret = dw_spi_suspend_host(&dwpci->dws);
|
||||
if (ret)
|
||||
return ret;
|
||||
pci_save_state(pdev);
|
||||
pci_disable_device(pdev);
|
||||
pci_set_power_state(pdev, pci_choose_state(pdev, state));
|
||||
return ret;
|
||||
return dw_spi_suspend_host(&dwpci->dws);
|
||||
}
|
||||
|
||||
static int spi_resume(struct pci_dev *pdev)
|
||||
static int spi_resume(struct device *dev)
|
||||
{
|
||||
struct pci_dev *pdev = to_pci_dev(dev);
|
||||
struct dw_spi_pci *dwpci = pci_get_drvdata(pdev);
|
||||
int ret;
|
||||
|
||||
pci_set_power_state(pdev, PCI_D0);
|
||||
pci_restore_state(pdev);
|
||||
ret = pci_enable_device(pdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
return dw_spi_resume_host(&dwpci->dws);
|
||||
}
|
||||
#else
|
||||
#define spi_suspend NULL
|
||||
#define spi_resume NULL
|
||||
#endif
|
||||
|
||||
static SIMPLE_DEV_PM_OPS(dw_spi_pm_ops, spi_suspend, spi_resume);
|
||||
|
||||
static const struct pci_device_id pci_ids[] = {
|
||||
/* Intel MID platform SPI controller 0 */
|
||||
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0800) },
|
||||
{ PCI_VDEVICE(INTEL, 0x0800), (kernel_ulong_t)&spi_pci_mid_desc},
|
||||
{},
|
||||
};
|
||||
|
||||
|
@ -138,8 +130,9 @@ static struct pci_driver dw_spi_driver = {
|
|||
.id_table = pci_ids,
|
||||
.probe = spi_pci_probe,
|
||||
.remove = spi_pci_remove,
|
||||
.suspend = spi_suspend,
|
||||
.resume = spi_resume,
|
||||
.driver = {
|
||||
.pm = &dw_spi_pm_ops,
|
||||
},
|
||||
};
|
||||
|
||||
module_pci_driver(dw_spi_driver);
|
||||
|
|
|
@ -11,10 +11,6 @@
|
|||
* 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, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include <linux/dma-mapping.h>
|
||||
|
@ -59,22 +55,20 @@ struct chip_data {
|
|||
|
||||
#ifdef CONFIG_DEBUG_FS
|
||||
#define SPI_REGS_BUFSIZE 1024
|
||||
static ssize_t spi_show_regs(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
static ssize_t dw_spi_show_regs(struct file *file, char __user *user_buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
struct dw_spi *dws;
|
||||
struct dw_spi *dws = file->private_data;
|
||||
char *buf;
|
||||
u32 len = 0;
|
||||
ssize_t ret;
|
||||
|
||||
dws = file->private_data;
|
||||
|
||||
buf = kzalloc(SPI_REGS_BUFSIZE, GFP_KERNEL);
|
||||
if (!buf)
|
||||
return 0;
|
||||
|
||||
len += snprintf(buf + len, SPI_REGS_BUFSIZE - len,
|
||||
"MRST SPI0 registers:\n");
|
||||
"%s registers:\n", dev_name(&dws->master->dev));
|
||||
len += snprintf(buf + len, SPI_REGS_BUFSIZE - len,
|
||||
"=================================\n");
|
||||
len += snprintf(buf + len, SPI_REGS_BUFSIZE - len,
|
||||
|
@ -110,41 +104,41 @@ static ssize_t spi_show_regs(struct file *file, char __user *user_buf,
|
|||
len += snprintf(buf + len, SPI_REGS_BUFSIZE - len,
|
||||
"=================================\n");
|
||||
|
||||
ret = simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
ret = simple_read_from_buffer(user_buf, count, ppos, buf, len);
|
||||
kfree(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct file_operations mrst_spi_regs_ops = {
|
||||
static const struct file_operations dw_spi_regs_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.open = simple_open,
|
||||
.read = spi_show_regs,
|
||||
.read = dw_spi_show_regs,
|
||||
.llseek = default_llseek,
|
||||
};
|
||||
|
||||
static int mrst_spi_debugfs_init(struct dw_spi *dws)
|
||||
static int dw_spi_debugfs_init(struct dw_spi *dws)
|
||||
{
|
||||
dws->debugfs = debugfs_create_dir("mrst_spi", NULL);
|
||||
dws->debugfs = debugfs_create_dir("dw_spi", NULL);
|
||||
if (!dws->debugfs)
|
||||
return -ENOMEM;
|
||||
|
||||
debugfs_create_file("registers", S_IFREG | S_IRUGO,
|
||||
dws->debugfs, (void *)dws, &mrst_spi_regs_ops);
|
||||
dws->debugfs, (void *)dws, &dw_spi_regs_ops);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mrst_spi_debugfs_remove(struct dw_spi *dws)
|
||||
static void dw_spi_debugfs_remove(struct dw_spi *dws)
|
||||
{
|
||||
debugfs_remove_recursive(dws->debugfs);
|
||||
}
|
||||
|
||||
#else
|
||||
static inline int mrst_spi_debugfs_init(struct dw_spi *dws)
|
||||
static inline int dw_spi_debugfs_init(struct dw_spi *dws)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void mrst_spi_debugfs_remove(struct dw_spi *dws)
|
||||
static inline void dw_spi_debugfs_remove(struct dw_spi *dws)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_DEBUG_FS */
|
||||
|
@ -396,7 +390,7 @@ static void pump_transfers(unsigned long data)
|
|||
goto early_exit;
|
||||
}
|
||||
|
||||
/* Delay if requested at end of transfer*/
|
||||
/* Delay if requested at end of transfer */
|
||||
if (message->state == RUNNING_STATE) {
|
||||
previous = list_entry(transfer->transfer_list.prev,
|
||||
struct spi_transfer,
|
||||
|
@ -525,7 +519,7 @@ static int dw_spi_transfer_one_message(struct spi_master *master,
|
|||
struct dw_spi *dws = spi_master_get_devdata(master);
|
||||
|
||||
dws->cur_msg = msg;
|
||||
/* Initial message state*/
|
||||
/* Initial message state */
|
||||
dws->cur_msg->state = START_STATE;
|
||||
dws->cur_transfer = list_entry(dws->cur_msg->transfers.next,
|
||||
struct spi_transfer,
|
||||
|
@ -596,6 +590,9 @@ static int dw_spi_setup(struct spi_device *spi)
|
|||
| (spi->mode << SPI_MODE_OFFSET)
|
||||
| (chip->tmode << SPI_TMOD_OFFSET);
|
||||
|
||||
if (spi->mode & SPI_LOOP)
|
||||
chip->cr0 |= 1 << SPI_SRL_OFFSET;
|
||||
|
||||
if (gpio_is_valid(spi->cs_gpio)) {
|
||||
ret = gpio_direction_output(spi->cs_gpio,
|
||||
!(spi->mode & SPI_CS_HIGH));
|
||||
|
@ -655,8 +652,7 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws)
|
|||
dws->prev_chip = NULL;
|
||||
dws->dma_inited = 0;
|
||||
dws->dma_addr = (dma_addr_t)(dws->paddr + 0x60);
|
||||
snprintf(dws->name, sizeof(dws->name), "dw_spi%d",
|
||||
dws->bus_num);
|
||||
snprintf(dws->name, sizeof(dws->name), "dw_spi%d", dws->bus_num);
|
||||
|
||||
ret = devm_request_irq(dev, dws->irq, dw_spi_irq, IRQF_SHARED,
|
||||
dws->name, dws);
|
||||
|
@ -665,7 +661,7 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws)
|
|||
goto err_free_master;
|
||||
}
|
||||
|
||||
master->mode_bits = SPI_CPOL | SPI_CPHA;
|
||||
master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LOOP;
|
||||
master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16);
|
||||
master->bus_num = dws->bus_num;
|
||||
master->num_chipselect = dws->num_cs;
|
||||
|
@ -694,7 +690,7 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws)
|
|||
goto err_dma_exit;
|
||||
}
|
||||
|
||||
mrst_spi_debugfs_init(dws);
|
||||
dw_spi_debugfs_init(dws);
|
||||
return 0;
|
||||
|
||||
err_dma_exit:
|
||||
|
@ -711,7 +707,7 @@ void dw_spi_remove_host(struct dw_spi *dws)
|
|||
{
|
||||
if (!dws)
|
||||
return;
|
||||
mrst_spi_debugfs_remove(dws);
|
||||
dw_spi_debugfs_remove(dws);
|
||||
|
||||
if (dws->dma_ops && dws->dma_ops->dma_exit)
|
||||
dws->dma_ops->dma_exit(dws);
|
||||
|
|
|
@ -74,6 +74,10 @@
|
|||
#define SPI_INT_RXFI (1 << 4)
|
||||
#define SPI_INT_MSTI (1 << 5)
|
||||
|
||||
/* Bit fields in DMACR */
|
||||
#define SPI_DMA_RDMAE (1 << 0)
|
||||
#define SPI_DMA_TDMAE (1 << 1)
|
||||
|
||||
/* TX RX interrupt level threshold, max can be 256 */
|
||||
#define SPI_INT_THRESHOLD 32
|
||||
|
||||
|
@ -140,7 +144,6 @@ struct dw_spi {
|
|||
dma_addr_t dma_addr; /* phy address of the Data register */
|
||||
struct dw_spi_dma_ops *dma_ops;
|
||||
void *dma_priv; /* platform relate info */
|
||||
struct pci_dev *dmac;
|
||||
|
||||
/* Bus interface info */
|
||||
void *priv;
|
||||
|
@ -217,11 +220,11 @@ static inline void spi_umask_intr(struct dw_spi *dws, u32 mask)
|
|||
* Each SPI slave device to work with dw_api controller should
|
||||
* has such a structure claiming its working mode (PIO/DMA etc),
|
||||
* which can be save in the "controller_data" member of the
|
||||
* struct spi_device
|
||||
* struct spi_device.
|
||||
*/
|
||||
struct dw_spi_chip {
|
||||
u8 poll_mode; /* 0 for contoller polling mode */
|
||||
u8 type; /* SPI/SSP/Micrwire */
|
||||
u8 poll_mode; /* 1 for controller polling mode */
|
||||
u8 type; /* SPI/SSP/MicroWire */
|
||||
u8 enable_dma;
|
||||
void (*cs_control)(u32 command);
|
||||
};
|
||||
|
|
|
@ -15,17 +15,17 @@
|
|||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
#include <linux/types.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/fsl_devices.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <asm/cpm.h>
|
||||
#include <asm/qe.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/fsl_devices.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include "spi-fsl-lib.h"
|
||||
#include "spi-fsl-cpm.h"
|
||||
#include "spi-fsl-lib.h"
|
||||
#include "spi-fsl-spi.h"
|
||||
|
||||
/* CPM1 and CPM2 are mutually exclusive. */
|
||||
|
|
|
@ -13,22 +13,22 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/spi/spi_bitbang.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/spi/spi_bitbang.h>
|
||||
|
||||
#define DRIVER_NAME "fsl-dspi"
|
||||
|
||||
|
|
|
@ -8,19 +8,19 @@
|
|||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/fsl_devices.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <sysdev/fsl_soc.h>
|
||||
|
||||
#include "spi-fsl-lib.h"
|
||||
|
|
|
@ -16,10 +16,10 @@
|
|||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/fsl_devices.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/fsl_devices.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/spi/spi.h>
|
||||
|
|
|
@ -19,25 +19,25 @@
|
|||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*/
|
||||
#include <linux/module.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/spi/spi_bitbang.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/fsl_devices.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/fsl_devices.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/spi/spi_bitbang.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include "spi-fsl-lib.h"
|
||||
#include "spi-fsl-cpm.h"
|
||||
|
|
Loading…
Reference in New Issue