Merge remote-tracking branches 'spi/topic/bcm63xx', 'spi/topic/butterfly', 'spi/topic/cadence' and 'spi/topic/davinci' into spi-next
This commit is contained in:
Коммит
3c2789239a
|
@ -207,6 +207,9 @@ static void bcm63xx_spi_setup_transfer(struct spi_device *spi,
|
||||||
u8 clk_cfg, reg;
|
u8 clk_cfg, reg;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
/* Default to lowest clock configuration */
|
||||||
|
clk_cfg = SPI_CLK_0_391MHZ;
|
||||||
|
|
||||||
/* Find the closest clock configuration */
|
/* Find the closest clock configuration */
|
||||||
for (i = 0; i < SPI_CLK_MASK; i++) {
|
for (i = 0; i < SPI_CLK_MASK; i++) {
|
||||||
if (t->speed_hz >= bcm63xx_spi_freq_table[i][0]) {
|
if (t->speed_hz >= bcm63xx_spi_freq_table[i][0]) {
|
||||||
|
@ -215,10 +218,6 @@ static void bcm63xx_spi_setup_transfer(struct spi_device *spi,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* No matching configuration found, default to lowest */
|
|
||||||
if (i == SPI_CLK_MASK)
|
|
||||||
clk_cfg = SPI_CLK_0_391MHZ;
|
|
||||||
|
|
||||||
/* clear existing clock configuration bits of the register */
|
/* clear existing clock configuration bits of the register */
|
||||||
reg = bcm_spi_readb(bs, SPI_CLK_CFG);
|
reg = bcm_spi_readb(bs, SPI_CLK_CFG);
|
||||||
reg &= ~SPI_CLK_MASK;
|
reg &= ~SPI_CLK_MASK;
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
|
|
||||||
#include <linux/mtd/partitions.h>
|
#include <linux/mtd/partitions.h>
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This uses SPI to talk with an "AVR Butterfly", which is a $US20 card
|
* This uses SPI to talk with an "AVR Butterfly", which is a $US20 card
|
||||||
* with a battery powered AVR microcontroller and lots of goodies. You
|
* with a battery powered AVR microcontroller and lots of goodies. You
|
||||||
|
@ -37,7 +36,6 @@
|
||||||
* and use this custom parallel port cable.
|
* and use this custom parallel port cable.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/* DATA output bits (pins 2..9 == D0..D7) */
|
/* DATA output bits (pins 2..9 == D0..D7) */
|
||||||
#define butterfly_nreset (1 << 1) /* pin 3 */
|
#define butterfly_nreset (1 << 1) /* pin 3 */
|
||||||
|
|
||||||
|
@ -52,14 +50,11 @@
|
||||||
/* CONTROL output bits */
|
/* CONTROL output bits */
|
||||||
#define spi_cs_bit PARPORT_CONTROL_SELECT /* pin 17 */
|
#define spi_cs_bit PARPORT_CONTROL_SELECT /* pin 17 */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static inline struct butterfly *spidev_to_pp(struct spi_device *spi)
|
static inline struct butterfly *spidev_to_pp(struct spi_device *spi)
|
||||||
{
|
{
|
||||||
return spi->controller_data;
|
return spi->controller_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
struct butterfly {
|
struct butterfly {
|
||||||
/* REVISIT ... for now, this must be first */
|
/* REVISIT ... for now, this must be first */
|
||||||
struct spi_bitbang bitbang;
|
struct spi_bitbang bitbang;
|
||||||
|
@ -140,7 +135,6 @@ static void butterfly_chipselect(struct spi_device *spi, int value)
|
||||||
parport_frob_control(pp->port, spi_cs_bit, value ? spi_cs_bit : 0);
|
parport_frob_control(pp->port, spi_cs_bit, value ? spi_cs_bit : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* we only needed to implement one mode here, and choose SPI_MODE_0 */
|
/* we only needed to implement one mode here, and choose SPI_MODE_0 */
|
||||||
|
|
||||||
#define spidelay(X) do { } while (0)
|
#define spidelay(X) do { } while (0)
|
||||||
|
@ -149,9 +143,8 @@ static void butterfly_chipselect(struct spi_device *spi, int value)
|
||||||
#include "spi-bitbang-txrx.h"
|
#include "spi-bitbang-txrx.h"
|
||||||
|
|
||||||
static u32
|
static u32
|
||||||
butterfly_txrx_word_mode0(struct spi_device *spi,
|
butterfly_txrx_word_mode0(struct spi_device *spi, unsigned nsecs, u32 word,
|
||||||
unsigned nsecs,
|
u8 bits)
|
||||||
u32 word, u8 bits)
|
|
||||||
{
|
{
|
||||||
return bitbang_txrx_be_cpha0(spi, nsecs, 0, 0, word, bits);
|
return bitbang_txrx_be_cpha0(spi, nsecs, 0, 0, word, bits);
|
||||||
}
|
}
|
||||||
|
@ -186,7 +179,6 @@ static struct flash_platform_data flash = {
|
||||||
.nr_parts = ARRAY_SIZE(partitions),
|
.nr_parts = ARRAY_SIZE(partitions),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* REVISIT remove this ugly global and its "only one" limitation */
|
/* REVISIT remove this ugly global and its "only one" limitation */
|
||||||
static struct butterfly *butterfly;
|
static struct butterfly *butterfly;
|
||||||
|
|
||||||
|
@ -197,6 +189,7 @@ static void butterfly_attach(struct parport *p)
|
||||||
struct butterfly *pp;
|
struct butterfly *pp;
|
||||||
struct spi_master *master;
|
struct spi_master *master;
|
||||||
struct device *dev = p->physport->dev;
|
struct device *dev = p->physport->dev;
|
||||||
|
struct pardev_cb butterfly_cb;
|
||||||
|
|
||||||
if (butterfly || !dev)
|
if (butterfly || !dev)
|
||||||
return;
|
return;
|
||||||
|
@ -229,9 +222,9 @@ static void butterfly_attach(struct parport *p)
|
||||||
* parport hookup
|
* parport hookup
|
||||||
*/
|
*/
|
||||||
pp->port = p;
|
pp->port = p;
|
||||||
pd = parport_register_device(p, "spi_butterfly",
|
memset(&butterfly_cb, 0, sizeof(butterfly_cb));
|
||||||
NULL, NULL, NULL,
|
butterfly_cb.private = pp;
|
||||||
0 /* FLAGS */, pp);
|
pd = parport_register_dev_model(p, "spi_butterfly", &butterfly_cb, 0);
|
||||||
if (!pd) {
|
if (!pd) {
|
||||||
status = -ENOMEM;
|
status = -ENOMEM;
|
||||||
goto clean0;
|
goto clean0;
|
||||||
|
@ -262,7 +255,6 @@ static void butterfly_attach(struct parport *p)
|
||||||
parport_write_data(pp->port, pp->lastbyte);
|
parport_write_data(pp->port, pp->lastbyte);
|
||||||
msleep(100);
|
msleep(100);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Start SPI ... for now, hide that we're two physical busses.
|
* Start SPI ... for now, hide that we're two physical busses.
|
||||||
*/
|
*/
|
||||||
|
@ -283,7 +275,7 @@ static void butterfly_attach(struct parport *p)
|
||||||
pp->dataflash = spi_new_device(pp->bitbang.master, &pp->info[0]);
|
pp->dataflash = spi_new_device(pp->bitbang.master, &pp->info[0]);
|
||||||
if (pp->dataflash)
|
if (pp->dataflash)
|
||||||
pr_debug("%s: dataflash at %s\n", p->name,
|
pr_debug("%s: dataflash at %s\n", p->name,
|
||||||
dev_name(&pp->dataflash->dev));
|
dev_name(&pp->dataflash->dev));
|
||||||
|
|
||||||
pr_info("%s: AVR Butterfly\n", p->name);
|
pr_info("%s: AVR Butterfly\n", p->name);
|
||||||
butterfly = pp;
|
butterfly = pp;
|
||||||
|
@ -297,7 +289,7 @@ clean2:
|
||||||
clean1:
|
clean1:
|
||||||
parport_unregister_device(pd);
|
parport_unregister_device(pd);
|
||||||
clean0:
|
clean0:
|
||||||
(void) spi_master_put(pp->bitbang.master);
|
spi_master_put(pp->bitbang.master);
|
||||||
done:
|
done:
|
||||||
pr_debug("%s: butterfly probe, fail %d\n", p->name, status);
|
pr_debug("%s: butterfly probe, fail %d\n", p->name, status);
|
||||||
}
|
}
|
||||||
|
@ -325,16 +317,16 @@ static void butterfly_detach(struct parport *p)
|
||||||
parport_release(pp->pd);
|
parport_release(pp->pd);
|
||||||
parport_unregister_device(pp->pd);
|
parport_unregister_device(pp->pd);
|
||||||
|
|
||||||
(void) spi_master_put(pp->bitbang.master);
|
spi_master_put(pp->bitbang.master);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct parport_driver butterfly_driver = {
|
static struct parport_driver butterfly_driver = {
|
||||||
.name = "spi_butterfly",
|
.name = "spi_butterfly",
|
||||||
.attach = butterfly_attach,
|
.match_port = butterfly_attach,
|
||||||
.detach = butterfly_detach,
|
.detach = butterfly_detach,
|
||||||
|
.devmodel = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static int __init butterfly_init(void)
|
static int __init butterfly_init(void)
|
||||||
{
|
{
|
||||||
return parport_register_driver(&butterfly_driver);
|
return parport_register_driver(&butterfly_driver);
|
||||||
|
|
|
@ -617,8 +617,7 @@ static int cdns_spi_remove(struct platform_device *pdev)
|
||||||
*/
|
*/
|
||||||
static int __maybe_unused cdns_spi_suspend(struct device *dev)
|
static int __maybe_unused cdns_spi_suspend(struct device *dev)
|
||||||
{
|
{
|
||||||
struct platform_device *pdev = container_of(dev,
|
struct platform_device *pdev = to_platform_device(dev);
|
||||||
struct platform_device, dev);
|
|
||||||
struct spi_master *master = platform_get_drvdata(pdev);
|
struct spi_master *master = platform_get_drvdata(pdev);
|
||||||
struct cdns_spi *xspi = spi_master_get_devdata(master);
|
struct cdns_spi *xspi = spi_master_get_devdata(master);
|
||||||
|
|
||||||
|
@ -641,8 +640,7 @@ static int __maybe_unused cdns_spi_suspend(struct device *dev)
|
||||||
*/
|
*/
|
||||||
static int __maybe_unused cdns_spi_resume(struct device *dev)
|
static int __maybe_unused cdns_spi_resume(struct device *dev)
|
||||||
{
|
{
|
||||||
struct platform_device *pdev = container_of(dev,
|
struct platform_device *pdev = to_platform_device(dev);
|
||||||
struct platform_device, dev);
|
|
||||||
struct spi_master *master = platform_get_drvdata(pdev);
|
struct spi_master *master = platform_get_drvdata(pdev);
|
||||||
struct cdns_spi *xspi = spi_master_get_devdata(master);
|
struct cdns_spi *xspi = spi_master_get_devdata(master);
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
|
@ -477,33 +477,33 @@ static int davinci_spi_check_error(struct davinci_spi *dspi, int int_status)
|
||||||
struct device *sdev = dspi->bitbang.master->dev.parent;
|
struct device *sdev = dspi->bitbang.master->dev.parent;
|
||||||
|
|
||||||
if (int_status & SPIFLG_TIMEOUT_MASK) {
|
if (int_status & SPIFLG_TIMEOUT_MASK) {
|
||||||
dev_dbg(sdev, "SPI Time-out Error\n");
|
dev_err(sdev, "SPI Time-out Error\n");
|
||||||
return -ETIMEDOUT;
|
return -ETIMEDOUT;
|
||||||
}
|
}
|
||||||
if (int_status & SPIFLG_DESYNC_MASK) {
|
if (int_status & SPIFLG_DESYNC_MASK) {
|
||||||
dev_dbg(sdev, "SPI Desynchronization Error\n");
|
dev_err(sdev, "SPI Desynchronization Error\n");
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
if (int_status & SPIFLG_BITERR_MASK) {
|
if (int_status & SPIFLG_BITERR_MASK) {
|
||||||
dev_dbg(sdev, "SPI Bit error\n");
|
dev_err(sdev, "SPI Bit error\n");
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dspi->version == SPI_VERSION_2) {
|
if (dspi->version == SPI_VERSION_2) {
|
||||||
if (int_status & SPIFLG_DLEN_ERR_MASK) {
|
if (int_status & SPIFLG_DLEN_ERR_MASK) {
|
||||||
dev_dbg(sdev, "SPI Data Length Error\n");
|
dev_err(sdev, "SPI Data Length Error\n");
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
if (int_status & SPIFLG_PARERR_MASK) {
|
if (int_status & SPIFLG_PARERR_MASK) {
|
||||||
dev_dbg(sdev, "SPI Parity Error\n");
|
dev_err(sdev, "SPI Parity Error\n");
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
if (int_status & SPIFLG_OVRRUN_MASK) {
|
if (int_status & SPIFLG_OVRRUN_MASK) {
|
||||||
dev_dbg(sdev, "SPI Data Overrun error\n");
|
dev_err(sdev, "SPI Data Overrun error\n");
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
if (int_status & SPIFLG_BUF_INIT_ACTIVE_MASK) {
|
if (int_status & SPIFLG_BUF_INIT_ACTIVE_MASK) {
|
||||||
dev_dbg(sdev, "SPI Buffer Init Active\n");
|
dev_err(sdev, "SPI Buffer Init Active\n");
|
||||||
return -EBUSY;
|
return -EBUSY;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -703,7 +703,8 @@ static int davinci_spi_bufs(struct spi_device *spi, struct spi_transfer *t)
|
||||||
|
|
||||||
/* Wait for the transfer to complete */
|
/* Wait for the transfer to complete */
|
||||||
if (spicfg->io_type != SPI_IO_TYPE_POLL) {
|
if (spicfg->io_type != SPI_IO_TYPE_POLL) {
|
||||||
wait_for_completion_interruptible(&(dspi->done));
|
if (wait_for_completion_timeout(&dspi->done, HZ) == 0)
|
||||||
|
errors = SPIFLG_TIMEOUT_MASK;
|
||||||
} else {
|
} else {
|
||||||
while (dspi->rcount > 0 || dspi->wcount > 0) {
|
while (dspi->rcount > 0 || dspi->wcount > 0) {
|
||||||
errors = davinci_spi_process_events(dspi);
|
errors = davinci_spi_process_events(dspi);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче