mirror of
https://github.com/FEX-Emu/linux.git
synced 2024-12-19 07:27:50 +00:00
m68knommu: Coldfire QSPI platform support
Since Grant has added the coldfire-qspi driver to next-spi, here is the platform support for the parts that have qspi hardware. This sets up gpio to do the spi chip select using the default chip select pins; it should be trivial for boards that require different or additional spi chip selects to use other gpios as needed. Signed-off-by: Steven King <sfking@fdwdc.com> Signed-off-by: Greg Ungerer <gerg@uclinux.org>
This commit is contained in:
parent
e40152ee1e
commit
91d6041721
arch
m68k/include/asm
m68knommu/platform
@ -113,6 +113,7 @@
|
||||
|
||||
#define MCF_GPIO_PAR_UART (0xA4036)
|
||||
#define MCF_GPIO_PAR_FECI2C (0xA4033)
|
||||
#define MCF_GPIO_PAR_QSPI (0xA4034)
|
||||
#define MCF_GPIO_PAR_FEC (0xA4038)
|
||||
|
||||
#define MCF_GPIO_PAR_UART_PAR_URXD0 (0x0001)
|
||||
|
@ -127,5 +127,10 @@
|
||||
#define MCFGPIO_IRQ_MAX 8
|
||||
#define MCFGPIO_IRQ_VECBASE MCFINT_VECBASE
|
||||
|
||||
/*
|
||||
* Pin Assignment
|
||||
*/
|
||||
#define MCFGPIO_PAR_QSPI (MCF_IPSBAR + 0x10004A)
|
||||
#define MCFGPIO_PAR_TIMER (MCF_IPSBAR + 0x10004C)
|
||||
/****************************************************************************/
|
||||
#endif /* m523xsim_h */
|
||||
|
@ -69,10 +69,12 @@
|
||||
#define MCFSIM_DMA1ICR MCFSIM_ICR7 /* DMA 1 ICR */
|
||||
#define MCFSIM_DMA2ICR MCFSIM_ICR8 /* DMA 2 ICR */
|
||||
#define MCFSIM_DMA3ICR MCFSIM_ICR9 /* DMA 3 ICR */
|
||||
#define MCFSIM_QSPIICR MCFSIM_ICR10 /* QSPI ICR */
|
||||
|
||||
/*
|
||||
* Define system peripheral IRQ usage.
|
||||
*/
|
||||
#define MCF_IRQ_QSPI 28 /* QSPI, Level 4 */
|
||||
#define MCF_IRQ_TIMER 30 /* Timer0, Level 6 */
|
||||
#define MCF_IRQ_PROFILER 31 /* Timer1, Level 7 */
|
||||
|
||||
|
@ -31,6 +31,7 @@
|
||||
#define MCFINT_UART0 13 /* Interrupt number for UART0 */
|
||||
#define MCFINT_UART1 14 /* Interrupt number for UART1 */
|
||||
#define MCFINT_UART2 15 /* Interrupt number for UART2 */
|
||||
#define MCFINT_QSPI 18 /* Interrupt number for QSPI */
|
||||
#define MCFINT_PIT1 36 /* Interrupt number for PIT1 */
|
||||
|
||||
/*
|
||||
@ -120,6 +121,9 @@
|
||||
#define MCFGPIO_PIN_MAX 100
|
||||
#define MCFGPIO_IRQ_MAX 8
|
||||
#define MCFGPIO_IRQ_VECBASE MCFINT_VECBASE
|
||||
|
||||
#define MCFGPIO_PAR_QSPI (MCF_IPSBAR + 0x10004A)
|
||||
#define MCFGPIO_PAR_TIMER (MCF_IPSBAR + 0x10004C)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_M5275
|
||||
@ -212,6 +216,8 @@
|
||||
#define MCFGPIO_PIN_MAX 148
|
||||
#define MCFGPIO_IRQ_MAX 8
|
||||
#define MCFGPIO_IRQ_VECBASE MCFINT_VECBASE
|
||||
|
||||
#define MCFGPIO_PAR_QSPI (MCF_IPSBAR + 0x10007E)
|
||||
#endif
|
||||
|
||||
/*
|
||||
@ -223,6 +229,7 @@
|
||||
#define MCFEPORT_EPPDR (MCF_IPSBAR + 0x130005)
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* GPIO pins setups to enable the UARTs.
|
||||
*/
|
||||
|
@ -29,6 +29,7 @@
|
||||
|
||||
#define MCFINT_VECBASE 64 /* Vector base number */
|
||||
#define MCFINT_UART0 13 /* Interrupt number for UART0 */
|
||||
#define MCFINT_QSPI 18 /* Interrupt number for QSPI */
|
||||
#define MCFINT_PIT1 55 /* Interrupt number for PIT1 */
|
||||
|
||||
/*
|
||||
@ -249,70 +250,4 @@
|
||||
#define MCF5282_I2C_I2SR_RXAK (0x01) // received acknowledge
|
||||
|
||||
|
||||
|
||||
/*********************************************************************
|
||||
*
|
||||
* Queued Serial Peripheral Interface (QSPI) Module
|
||||
*
|
||||
*********************************************************************/
|
||||
/* Derek - 21 Feb 2005 */
|
||||
/* change to the format used in I2C */
|
||||
/* Read/Write access macros for general use */
|
||||
#define MCF5282_QSPI_QMR MCF_IPSBAR + 0x0340
|
||||
#define MCF5282_QSPI_QDLYR MCF_IPSBAR + 0x0344
|
||||
#define MCF5282_QSPI_QWR MCF_IPSBAR + 0x0348
|
||||
#define MCF5282_QSPI_QIR MCF_IPSBAR + 0x034C
|
||||
#define MCF5282_QSPI_QAR MCF_IPSBAR + 0x0350
|
||||
#define MCF5282_QSPI_QDR MCF_IPSBAR + 0x0354
|
||||
#define MCF5282_QSPI_QCR MCF_IPSBAR + 0x0354
|
||||
|
||||
/* Bit level definitions and macros */
|
||||
#define MCF5282_QSPI_QMR_MSTR (0x8000)
|
||||
#define MCF5282_QSPI_QMR_DOHIE (0x4000)
|
||||
#define MCF5282_QSPI_QMR_BITS_16 (0x0000)
|
||||
#define MCF5282_QSPI_QMR_BITS_8 (0x2000)
|
||||
#define MCF5282_QSPI_QMR_BITS_9 (0x2400)
|
||||
#define MCF5282_QSPI_QMR_BITS_10 (0x2800)
|
||||
#define MCF5282_QSPI_QMR_BITS_11 (0x2C00)
|
||||
#define MCF5282_QSPI_QMR_BITS_12 (0x3000)
|
||||
#define MCF5282_QSPI_QMR_BITS_13 (0x3400)
|
||||
#define MCF5282_QSPI_QMR_BITS_14 (0x3800)
|
||||
#define MCF5282_QSPI_QMR_BITS_15 (0x3C00)
|
||||
#define MCF5282_QSPI_QMR_CPOL (0x0200)
|
||||
#define MCF5282_QSPI_QMR_CPHA (0x0100)
|
||||
#define MCF5282_QSPI_QMR_BAUD(x) (((x)&0x00FF))
|
||||
|
||||
#define MCF5282_QSPI_QDLYR_SPE (0x80)
|
||||
#define MCF5282_QSPI_QDLYR_QCD(x) (((x)&0x007F)<<8)
|
||||
#define MCF5282_QSPI_QDLYR_DTL(x) (((x)&0x00FF))
|
||||
|
||||
#define MCF5282_QSPI_QWR_HALT (0x8000)
|
||||
#define MCF5282_QSPI_QWR_WREN (0x4000)
|
||||
#define MCF5282_QSPI_QWR_WRTO (0x2000)
|
||||
#define MCF5282_QSPI_QWR_CSIV (0x1000)
|
||||
#define MCF5282_QSPI_QWR_ENDQP(x) (((x)&0x000F)<<8)
|
||||
#define MCF5282_QSPI_QWR_CPTQP(x) (((x)&0x000F)<<4)
|
||||
#define MCF5282_QSPI_QWR_NEWQP(x) (((x)&0x000F))
|
||||
|
||||
#define MCF5282_QSPI_QIR_WCEFB (0x8000)
|
||||
#define MCF5282_QSPI_QIR_ABRTB (0x4000)
|
||||
#define MCF5282_QSPI_QIR_ABRTL (0x1000)
|
||||
#define MCF5282_QSPI_QIR_WCEFE (0x0800)
|
||||
#define MCF5282_QSPI_QIR_ABRTE (0x0400)
|
||||
#define MCF5282_QSPI_QIR_SPIFE (0x0100)
|
||||
#define MCF5282_QSPI_QIR_WCEF (0x0008)
|
||||
#define MCF5282_QSPI_QIR_ABRT (0x0004)
|
||||
#define MCF5282_QSPI_QIR_SPIF (0x0001)
|
||||
|
||||
#define MCF5282_QSPI_QAR_ADDR(x) (((x)&0x003F))
|
||||
|
||||
#define MCF5282_QSPI_QDR_COMMAND(x) (((x)&0xFF00))
|
||||
#define MCF5282_QSPI_QCR_DATA(x) (((x)&0x00FF)<<8)
|
||||
#define MCF5282_QSPI_QCR_CONT (0x8000)
|
||||
#define MCF5282_QSPI_QCR_BITSE (0x4000)
|
||||
#define MCF5282_QSPI_QCR_DT (0x2000)
|
||||
#define MCF5282_QSPI_QCR_DSCK (0x1000)
|
||||
#define MCF5282_QSPI_QCR_CS (((x)&0x000F)<<8)
|
||||
|
||||
/****************************************************************************/
|
||||
#endif /* m528xsim_h */
|
||||
|
@ -17,6 +17,7 @@
|
||||
#define MCFINT_UART0 26 /* Interrupt number for UART0 */
|
||||
#define MCFINT_UART1 27 /* Interrupt number for UART1 */
|
||||
#define MCFINT_UART2 28 /* Interrupt number for UART2 */
|
||||
#define MCFINT_QSPI 31 /* Interrupt number for QSPI */
|
||||
|
||||
#define MCF_WTM_WCR MCF_REG16(0xFC098000)
|
||||
|
||||
|
64
arch/m68k/include/asm/mcfqspi.h
Normal file
64
arch/m68k/include/asm/mcfqspi.h
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Definitions for Freescale Coldfire QSPI module
|
||||
*
|
||||
* Copyright 2010 Steven King <sfking@fdwdc.com>
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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 Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef mcfqspi_h
|
||||
#define mcfqspi_h
|
||||
|
||||
#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
|
||||
#define MCFQSPI_IOBASE (MCF_IPSBAR + 0x340)
|
||||
#elif defined(CONFIG_M5249)
|
||||
#define MCFQSPI_IOBASE (MCF_MBAR + 0x300)
|
||||
#elif defined(CONFIG_M520x) || defined(CONFIG_M532x)
|
||||
#define MCFQSPI_IOBASE 0xFC058000
|
||||
#endif
|
||||
#define MCFQSPI_IOSIZE 0x40
|
||||
|
||||
/**
|
||||
* struct mcfqspi_cs_control - chip select control for the coldfire qspi driver
|
||||
* @setup: setup the control; allocate gpio's, etc. May be NULL.
|
||||
* @teardown: finish with the control; free gpio's, etc. May be NULL.
|
||||
* @select: output the signals to select the device. Can not be NULL.
|
||||
* @deselect: output the signals to deselect the device. Can not be NULL.
|
||||
*
|
||||
* The QSPI module has 4 hardware chip selects. We don't use them. Instead
|
||||
* platforms are required to supply a mcfqspi_cs_control as a part of the
|
||||
* platform data for each QSPI master controller. Only the select and
|
||||
* deselect functions are required.
|
||||
*/
|
||||
struct mcfqspi_cs_control {
|
||||
int (*setup)(struct mcfqspi_cs_control *);
|
||||
void (*teardown)(struct mcfqspi_cs_control *);
|
||||
void (*select)(struct mcfqspi_cs_control *, u8, bool);
|
||||
void (*deselect)(struct mcfqspi_cs_control *, u8, bool);
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mcfqspi_platform_data - platform data for the coldfire qspi driver
|
||||
* @bus_num: board specific identifier for this qspi driver.
|
||||
* @num_chipselects: number of chip selects supported by this qspi driver.
|
||||
* @cs_control: platform dependent chip select control.
|
||||
*/
|
||||
struct mcfqspi_platform_data {
|
||||
s16 bus_num;
|
||||
u16 num_chipselect;
|
||||
struct mcfqspi_cs_control *cs_control;
|
||||
};
|
||||
|
||||
#endif /* mcfqspi_h */
|
@ -15,10 +15,13 @@
|
||||
#include <linux/param.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfsim.h>
|
||||
#include <asm/mcfuart.h>
|
||||
#include <asm/mcfqspi.h>
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
@ -74,9 +77,152 @@ static struct platform_device m520x_fec = {
|
||||
.resource = m520x_fec_resources,
|
||||
};
|
||||
|
||||
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
|
||||
static struct resource m520x_qspi_resources[] = {
|
||||
{
|
||||
.start = MCFQSPI_IOBASE,
|
||||
.end = MCFQSPI_IOBASE + MCFQSPI_IOSIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = MCFINT_VECBASE + MCFINT_QSPI,
|
||||
.end = MCFINT_VECBASE + MCFINT_QSPI,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
#define MCFQSPI_CS0 62
|
||||
#define MCFQSPI_CS1 63
|
||||
#define MCFQSPI_CS2 44
|
||||
|
||||
static int m520x_cs_setup(struct mcfqspi_cs_control *cs_control)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0");
|
||||
if (status) {
|
||||
pr_debug("gpio_request for MCFQSPI_CS0 failed\n");
|
||||
goto fail0;
|
||||
}
|
||||
status = gpio_direction_output(MCFQSPI_CS0, 1);
|
||||
if (status) {
|
||||
pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n");
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1");
|
||||
if (status) {
|
||||
pr_debug("gpio_request for MCFQSPI_CS1 failed\n");
|
||||
goto fail1;
|
||||
}
|
||||
status = gpio_direction_output(MCFQSPI_CS1, 1);
|
||||
if (status) {
|
||||
pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n");
|
||||
goto fail2;
|
||||
}
|
||||
|
||||
status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2");
|
||||
if (status) {
|
||||
pr_debug("gpio_request for MCFQSPI_CS2 failed\n");
|
||||
goto fail2;
|
||||
}
|
||||
status = gpio_direction_output(MCFQSPI_CS2, 1);
|
||||
if (status) {
|
||||
pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n");
|
||||
goto fail3;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail3:
|
||||
gpio_free(MCFQSPI_CS2);
|
||||
fail2:
|
||||
gpio_free(MCFQSPI_CS1);
|
||||
fail1:
|
||||
gpio_free(MCFQSPI_CS0);
|
||||
fail0:
|
||||
return status;
|
||||
}
|
||||
|
||||
static void m520x_cs_teardown(struct mcfqspi_cs_control *cs_control)
|
||||
{
|
||||
gpio_free(MCFQSPI_CS2);
|
||||
gpio_free(MCFQSPI_CS1);
|
||||
gpio_free(MCFQSPI_CS0);
|
||||
}
|
||||
|
||||
static void m520x_cs_select(struct mcfqspi_cs_control *cs_control,
|
||||
u8 chip_select, bool cs_high)
|
||||
{
|
||||
switch (chip_select) {
|
||||
case 0:
|
||||
gpio_set_value(MCFQSPI_CS0, cs_high);
|
||||
break;
|
||||
case 1:
|
||||
gpio_set_value(MCFQSPI_CS1, cs_high);
|
||||
break;
|
||||
case 2:
|
||||
gpio_set_value(MCFQSPI_CS2, cs_high);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void m520x_cs_deselect(struct mcfqspi_cs_control *cs_control,
|
||||
u8 chip_select, bool cs_high)
|
||||
{
|
||||
switch (chip_select) {
|
||||
case 0:
|
||||
gpio_set_value(MCFQSPI_CS0, !cs_high);
|
||||
break;
|
||||
case 1:
|
||||
gpio_set_value(MCFQSPI_CS1, !cs_high);
|
||||
break;
|
||||
case 2:
|
||||
gpio_set_value(MCFQSPI_CS2, !cs_high);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static struct mcfqspi_cs_control m520x_cs_control = {
|
||||
.setup = m520x_cs_setup,
|
||||
.teardown = m520x_cs_teardown,
|
||||
.select = m520x_cs_select,
|
||||
.deselect = m520x_cs_deselect,
|
||||
};
|
||||
|
||||
static struct mcfqspi_platform_data m520x_qspi_data = {
|
||||
.bus_num = 0,
|
||||
.num_chipselect = 3,
|
||||
.cs_control = &m520x_cs_control,
|
||||
};
|
||||
|
||||
static struct platform_device m520x_qspi = {
|
||||
.name = "mcfqspi",
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(m520x_qspi_resources),
|
||||
.resource = m520x_qspi_resources,
|
||||
.dev.platform_data = &m520x_qspi_data,
|
||||
};
|
||||
|
||||
static void __init m520x_qspi_init(void)
|
||||
{
|
||||
u16 par;
|
||||
/* setup Port QS for QSPI with gpio CS control */
|
||||
writeb(0x3f, MCF_IPSBAR + MCF_GPIO_PAR_QSPI);
|
||||
/* make U1CTS and U2RTS gpio for cs_control */
|
||||
par = readw(MCF_IPSBAR + MCF_GPIO_PAR_UART);
|
||||
par &= 0x00ff;
|
||||
writew(par, MCF_IPSBAR + MCF_GPIO_PAR_UART);
|
||||
}
|
||||
#endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */
|
||||
|
||||
|
||||
static struct platform_device *m520x_devices[] __initdata = {
|
||||
&m520x_uart,
|
||||
&m520x_fec,
|
||||
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
|
||||
&m520x_qspi,
|
||||
#endif
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
@ -147,6 +293,9 @@ void __init config_BSP(char *commandp, int size)
|
||||
mach_reset = m520x_cpu_reset;
|
||||
m520x_uarts_init();
|
||||
m520x_fec_init();
|
||||
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
|
||||
m520x_qspi_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
@ -16,10 +16,13 @@
|
||||
#include <linux/param.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfsim.h>
|
||||
#include <asm/mcfuart.h>
|
||||
#include <asm/mcfqspi.h>
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
@ -75,9 +78,173 @@ static struct platform_device m523x_fec = {
|
||||
.resource = m523x_fec_resources,
|
||||
};
|
||||
|
||||
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
|
||||
static struct resource m523x_qspi_resources[] = {
|
||||
{
|
||||
.start = MCFQSPI_IOBASE,
|
||||
.end = MCFQSPI_IOBASE + MCFQSPI_IOSIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = MCFINT_VECBASE + MCFINT_QSPI,
|
||||
.end = MCFINT_VECBASE + MCFINT_QSPI,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
#define MCFQSPI_CS0 91
|
||||
#define MCFQSPI_CS1 92
|
||||
#define MCFQSPI_CS2 103
|
||||
#define MCFQSPI_CS3 99
|
||||
|
||||
static int m523x_cs_setup(struct mcfqspi_cs_control *cs_control)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0");
|
||||
if (status) {
|
||||
pr_debug("gpio_request for MCFQSPI_CS0 failed\n");
|
||||
goto fail0;
|
||||
}
|
||||
status = gpio_direction_output(MCFQSPI_CS0, 1);
|
||||
if (status) {
|
||||
pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n");
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1");
|
||||
if (status) {
|
||||
pr_debug("gpio_request for MCFQSPI_CS1 failed\n");
|
||||
goto fail1;
|
||||
}
|
||||
status = gpio_direction_output(MCFQSPI_CS1, 1);
|
||||
if (status) {
|
||||
pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n");
|
||||
goto fail2;
|
||||
}
|
||||
|
||||
status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2");
|
||||
if (status) {
|
||||
pr_debug("gpio_request for MCFQSPI_CS2 failed\n");
|
||||
goto fail2;
|
||||
}
|
||||
status = gpio_direction_output(MCFQSPI_CS2, 1);
|
||||
if (status) {
|
||||
pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n");
|
||||
goto fail3;
|
||||
}
|
||||
|
||||
status = gpio_request(MCFQSPI_CS3, "MCFQSPI_CS3");
|
||||
if (status) {
|
||||
pr_debug("gpio_request for MCFQSPI_CS3 failed\n");
|
||||
goto fail3;
|
||||
}
|
||||
status = gpio_direction_output(MCFQSPI_CS3, 1);
|
||||
if (status) {
|
||||
pr_debug("gpio_direction_output for MCFQSPI_CS3 failed\n");
|
||||
goto fail4;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail4:
|
||||
gpio_free(MCFQSPI_CS3);
|
||||
fail3:
|
||||
gpio_free(MCFQSPI_CS2);
|
||||
fail2:
|
||||
gpio_free(MCFQSPI_CS1);
|
||||
fail1:
|
||||
gpio_free(MCFQSPI_CS0);
|
||||
fail0:
|
||||
return status;
|
||||
}
|
||||
|
||||
static void m523x_cs_teardown(struct mcfqspi_cs_control *cs_control)
|
||||
{
|
||||
gpio_free(MCFQSPI_CS3);
|
||||
gpio_free(MCFQSPI_CS2);
|
||||
gpio_free(MCFQSPI_CS1);
|
||||
gpio_free(MCFQSPI_CS0);
|
||||
}
|
||||
|
||||
static void m523x_cs_select(struct mcfqspi_cs_control *cs_control,
|
||||
u8 chip_select, bool cs_high)
|
||||
{
|
||||
switch (chip_select) {
|
||||
case 0:
|
||||
gpio_set_value(MCFQSPI_CS0, cs_high);
|
||||
break;
|
||||
case 1:
|
||||
gpio_set_value(MCFQSPI_CS1, cs_high);
|
||||
break;
|
||||
case 2:
|
||||
gpio_set_value(MCFQSPI_CS2, cs_high);
|
||||
break;
|
||||
case 3:
|
||||
gpio_set_value(MCFQSPI_CS3, cs_high);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void m523x_cs_deselect(struct mcfqspi_cs_control *cs_control,
|
||||
u8 chip_select, bool cs_high)
|
||||
{
|
||||
switch (chip_select) {
|
||||
case 0:
|
||||
gpio_set_value(MCFQSPI_CS0, !cs_high);
|
||||
break;
|
||||
case 1:
|
||||
gpio_set_value(MCFQSPI_CS1, !cs_high);
|
||||
break;
|
||||
case 2:
|
||||
gpio_set_value(MCFQSPI_CS2, !cs_high);
|
||||
break;
|
||||
case 3:
|
||||
gpio_set_value(MCFQSPI_CS3, !cs_high);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static struct mcfqspi_cs_control m523x_cs_control = {
|
||||
.setup = m523x_cs_setup,
|
||||
.teardown = m523x_cs_teardown,
|
||||
.select = m523x_cs_select,
|
||||
.deselect = m523x_cs_deselect,
|
||||
};
|
||||
|
||||
static struct mcfqspi_platform_data m523x_qspi_data = {
|
||||
.bus_num = 0,
|
||||
.num_chipselect = 4,
|
||||
.cs_control = &m523x_cs_control,
|
||||
};
|
||||
|
||||
static struct platform_device m523x_qspi = {
|
||||
.name = "mcfqspi",
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(m523x_qspi_resources),
|
||||
.resource = m523x_qspi_resources,
|
||||
.dev.platform_data = &m523x_qspi_data,
|
||||
};
|
||||
|
||||
static void __init m523x_qspi_init(void)
|
||||
{
|
||||
u16 par;
|
||||
|
||||
/* setup QSPS pins for QSPI with gpio CS control */
|
||||
writeb(0x1f, MCFGPIO_PAR_QSPI);
|
||||
/* and CS2 & CS3 as gpio */
|
||||
par = readw(MCFGPIO_PAR_TIMER);
|
||||
par &= 0x3f3f;
|
||||
writew(par, MCFGPIO_PAR_TIMER);
|
||||
}
|
||||
#endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */
|
||||
|
||||
static struct platform_device *m523x_devices[] __initdata = {
|
||||
&m523x_uart,
|
||||
&m523x_fec,
|
||||
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
|
||||
&m523x_qspi,
|
||||
#endif
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
@ -114,6 +281,9 @@ void __init config_BSP(char *commandp, int size)
|
||||
static int __init init_BSP(void)
|
||||
{
|
||||
m523x_fec_init();
|
||||
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
|
||||
m523x_qspi_init();
|
||||
#endif
|
||||
platform_add_devices(m523x_devices, ARRAY_SIZE(m523x_devices));
|
||||
return 0;
|
||||
}
|
||||
|
@ -12,10 +12,13 @@
|
||||
#include <linux/param.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfsim.h>
|
||||
#include <asm/mcfuart.h>
|
||||
#include <asm/mcfqspi.h>
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
@ -37,8 +40,169 @@ static struct platform_device m5249_uart = {
|
||||
.dev.platform_data = m5249_uart_platform,
|
||||
};
|
||||
|
||||
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
|
||||
static struct resource m5249_qspi_resources[] = {
|
||||
{
|
||||
.start = MCFQSPI_IOBASE,
|
||||
.end = MCFQSPI_IOBASE + MCFQSPI_IOSIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = MCF_IRQ_QSPI,
|
||||
.end = MCF_IRQ_QSPI,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
#define MCFQSPI_CS0 29
|
||||
#define MCFQSPI_CS1 24
|
||||
#define MCFQSPI_CS2 21
|
||||
#define MCFQSPI_CS3 22
|
||||
|
||||
static int m5249_cs_setup(struct mcfqspi_cs_control *cs_control)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0");
|
||||
if (status) {
|
||||
pr_debug("gpio_request for MCFQSPI_CS0 failed\n");
|
||||
goto fail0;
|
||||
}
|
||||
status = gpio_direction_output(MCFQSPI_CS0, 1);
|
||||
if (status) {
|
||||
pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n");
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1");
|
||||
if (status) {
|
||||
pr_debug("gpio_request for MCFQSPI_CS1 failed\n");
|
||||
goto fail1;
|
||||
}
|
||||
status = gpio_direction_output(MCFQSPI_CS1, 1);
|
||||
if (status) {
|
||||
pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n");
|
||||
goto fail2;
|
||||
}
|
||||
|
||||
status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2");
|
||||
if (status) {
|
||||
pr_debug("gpio_request for MCFQSPI_CS2 failed\n");
|
||||
goto fail2;
|
||||
}
|
||||
status = gpio_direction_output(MCFQSPI_CS2, 1);
|
||||
if (status) {
|
||||
pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n");
|
||||
goto fail3;
|
||||
}
|
||||
|
||||
status = gpio_request(MCFQSPI_CS3, "MCFQSPI_CS3");
|
||||
if (status) {
|
||||
pr_debug("gpio_request for MCFQSPI_CS3 failed\n");
|
||||
goto fail3;
|
||||
}
|
||||
status = gpio_direction_output(MCFQSPI_CS3, 1);
|
||||
if (status) {
|
||||
pr_debug("gpio_direction_output for MCFQSPI_CS3 failed\n");
|
||||
goto fail4;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail4:
|
||||
gpio_free(MCFQSPI_CS3);
|
||||
fail3:
|
||||
gpio_free(MCFQSPI_CS2);
|
||||
fail2:
|
||||
gpio_free(MCFQSPI_CS1);
|
||||
fail1:
|
||||
gpio_free(MCFQSPI_CS0);
|
||||
fail0:
|
||||
return status;
|
||||
}
|
||||
|
||||
static void m5249_cs_teardown(struct mcfqspi_cs_control *cs_control)
|
||||
{
|
||||
gpio_free(MCFQSPI_CS3);
|
||||
gpio_free(MCFQSPI_CS2);
|
||||
gpio_free(MCFQSPI_CS1);
|
||||
gpio_free(MCFQSPI_CS0);
|
||||
}
|
||||
|
||||
static void m5249_cs_select(struct mcfqspi_cs_control *cs_control,
|
||||
u8 chip_select, bool cs_high)
|
||||
{
|
||||
switch (chip_select) {
|
||||
case 0:
|
||||
gpio_set_value(MCFQSPI_CS0, cs_high);
|
||||
break;
|
||||
case 1:
|
||||
gpio_set_value(MCFQSPI_CS1, cs_high);
|
||||
break;
|
||||
case 2:
|
||||
gpio_set_value(MCFQSPI_CS2, cs_high);
|
||||
break;
|
||||
case 3:
|
||||
gpio_set_value(MCFQSPI_CS3, cs_high);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void m5249_cs_deselect(struct mcfqspi_cs_control *cs_control,
|
||||
u8 chip_select, bool cs_high)
|
||||
{
|
||||
switch (chip_select) {
|
||||
case 0:
|
||||
gpio_set_value(MCFQSPI_CS0, !cs_high);
|
||||
break;
|
||||
case 1:
|
||||
gpio_set_value(MCFQSPI_CS1, !cs_high);
|
||||
break;
|
||||
case 2:
|
||||
gpio_set_value(MCFQSPI_CS2, !cs_high);
|
||||
break;
|
||||
case 3:
|
||||
gpio_set_value(MCFQSPI_CS3, !cs_high);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static struct mcfqspi_cs_control m5249_cs_control = {
|
||||
.setup = m5249_cs_setup,
|
||||
.teardown = m5249_cs_teardown,
|
||||
.select = m5249_cs_select,
|
||||
.deselect = m5249_cs_deselect,
|
||||
};
|
||||
|
||||
static struct mcfqspi_platform_data m5249_qspi_data = {
|
||||
.bus_num = 0,
|
||||
.num_chipselect = 4,
|
||||
.cs_control = &m5249_cs_control,
|
||||
};
|
||||
|
||||
static struct platform_device m5249_qspi = {
|
||||
.name = "mcfqspi",
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(m5249_qspi_resources),
|
||||
.resource = m5249_qspi_resources,
|
||||
.dev.platform_data = &m5249_qspi_data,
|
||||
};
|
||||
|
||||
static void __init m5249_qspi_init(void)
|
||||
{
|
||||
/* QSPI irq setup */
|
||||
writeb(MCFSIM_ICR_AUTOVEC | MCFSIM_ICR_LEVEL4 | MCFSIM_ICR_PRI0,
|
||||
MCF_MBAR + MCFSIM_QSPIICR);
|
||||
mcf_mapirq2imr(MCF_IRQ_QSPI, MCFINTC_QSPI);
|
||||
}
|
||||
#endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */
|
||||
|
||||
|
||||
static struct platform_device *m5249_devices[] __initdata = {
|
||||
&m5249_uart,
|
||||
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
|
||||
&m5249_qspi,
|
||||
#endif
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
@ -100,6 +264,9 @@ void __init config_BSP(char *commandp, int size)
|
||||
mach_reset = m5249_cpu_reset;
|
||||
m5249_timers_init();
|
||||
m5249_uarts_init();
|
||||
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
|
||||
m5249_qspi_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
@ -16,10 +16,13 @@
|
||||
#include <linux/param.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfsim.h>
|
||||
#include <asm/mcfuart.h>
|
||||
#include <asm/mcfqspi.h>
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
@ -106,12 +109,188 @@ static struct platform_device m527x_fec[] = {
|
||||
},
|
||||
};
|
||||
|
||||
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
|
||||
static struct resource m527x_qspi_resources[] = {
|
||||
{
|
||||
.start = MCFQSPI_IOBASE,
|
||||
.end = MCFQSPI_IOBASE + MCFQSPI_IOSIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = MCFINT_VECBASE + MCFINT_QSPI,
|
||||
.end = MCFINT_VECBASE + MCFINT_QSPI,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
#if defined(CONFIG_M5271)
|
||||
#define MCFQSPI_CS0 91
|
||||
#define MCFQSPI_CS1 92
|
||||
#define MCFQSPI_CS2 99
|
||||
#define MCFQSPI_CS3 103
|
||||
#elif defined(CONFIG_M5275)
|
||||
#define MCFQSPI_CS0 59
|
||||
#define MCFQSPI_CS1 60
|
||||
#define MCFQSPI_CS2 61
|
||||
#define MCFQSPI_CS3 62
|
||||
#endif
|
||||
|
||||
static int m527x_cs_setup(struct mcfqspi_cs_control *cs_control)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0");
|
||||
if (status) {
|
||||
pr_debug("gpio_request for MCFQSPI_CS0 failed\n");
|
||||
goto fail0;
|
||||
}
|
||||
status = gpio_direction_output(MCFQSPI_CS0, 1);
|
||||
if (status) {
|
||||
pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n");
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1");
|
||||
if (status) {
|
||||
pr_debug("gpio_request for MCFQSPI_CS1 failed\n");
|
||||
goto fail1;
|
||||
}
|
||||
status = gpio_direction_output(MCFQSPI_CS1, 1);
|
||||
if (status) {
|
||||
pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n");
|
||||
goto fail2;
|
||||
}
|
||||
|
||||
status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2");
|
||||
if (status) {
|
||||
pr_debug("gpio_request for MCFQSPI_CS2 failed\n");
|
||||
goto fail2;
|
||||
}
|
||||
status = gpio_direction_output(MCFQSPI_CS2, 1);
|
||||
if (status) {
|
||||
pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n");
|
||||
goto fail3;
|
||||
}
|
||||
|
||||
status = gpio_request(MCFQSPI_CS3, "MCFQSPI_CS3");
|
||||
if (status) {
|
||||
pr_debug("gpio_request for MCFQSPI_CS3 failed\n");
|
||||
goto fail3;
|
||||
}
|
||||
status = gpio_direction_output(MCFQSPI_CS3, 1);
|
||||
if (status) {
|
||||
pr_debug("gpio_direction_output for MCFQSPI_CS3 failed\n");
|
||||
goto fail4;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail4:
|
||||
gpio_free(MCFQSPI_CS3);
|
||||
fail3:
|
||||
gpio_free(MCFQSPI_CS2);
|
||||
fail2:
|
||||
gpio_free(MCFQSPI_CS1);
|
||||
fail1:
|
||||
gpio_free(MCFQSPI_CS0);
|
||||
fail0:
|
||||
return status;
|
||||
}
|
||||
|
||||
static void m527x_cs_teardown(struct mcfqspi_cs_control *cs_control)
|
||||
{
|
||||
gpio_free(MCFQSPI_CS3);
|
||||
gpio_free(MCFQSPI_CS2);
|
||||
gpio_free(MCFQSPI_CS1);
|
||||
gpio_free(MCFQSPI_CS0);
|
||||
}
|
||||
|
||||
static void m527x_cs_select(struct mcfqspi_cs_control *cs_control,
|
||||
u8 chip_select, bool cs_high)
|
||||
{
|
||||
switch (chip_select) {
|
||||
case 0:
|
||||
gpio_set_value(MCFQSPI_CS0, cs_high);
|
||||
break;
|
||||
case 1:
|
||||
gpio_set_value(MCFQSPI_CS1, cs_high);
|
||||
break;
|
||||
case 2:
|
||||
gpio_set_value(MCFQSPI_CS2, cs_high);
|
||||
break;
|
||||
case 3:
|
||||
gpio_set_value(MCFQSPI_CS3, cs_high);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void m527x_cs_deselect(struct mcfqspi_cs_control *cs_control,
|
||||
u8 chip_select, bool cs_high)
|
||||
{
|
||||
switch (chip_select) {
|
||||
case 0:
|
||||
gpio_set_value(MCFQSPI_CS0, !cs_high);
|
||||
break;
|
||||
case 1:
|
||||
gpio_set_value(MCFQSPI_CS1, !cs_high);
|
||||
break;
|
||||
case 2:
|
||||
gpio_set_value(MCFQSPI_CS2, !cs_high);
|
||||
break;
|
||||
case 3:
|
||||
gpio_set_value(MCFQSPI_CS3, !cs_high);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static struct mcfqspi_cs_control m527x_cs_control = {
|
||||
.setup = m527x_cs_setup,
|
||||
.teardown = m527x_cs_teardown,
|
||||
.select = m527x_cs_select,
|
||||
.deselect = m527x_cs_deselect,
|
||||
};
|
||||
|
||||
static struct mcfqspi_platform_data m527x_qspi_data = {
|
||||
.bus_num = 0,
|
||||
.num_chipselect = 4,
|
||||
.cs_control = &m527x_cs_control,
|
||||
};
|
||||
|
||||
static struct platform_device m527x_qspi = {
|
||||
.name = "mcfqspi",
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(m527x_qspi_resources),
|
||||
.resource = m527x_qspi_resources,
|
||||
.dev.platform_data = &m527x_qspi_data,
|
||||
};
|
||||
|
||||
static void __init m527x_qspi_init(void)
|
||||
{
|
||||
#if defined(CONFIG_M5271)
|
||||
u16 par;
|
||||
|
||||
/* setup QSPS pins for QSPI with gpio CS control */
|
||||
writeb(0x1f, MCFGPIO_PAR_QSPI);
|
||||
/* and CS2 & CS3 as gpio */
|
||||
par = readw(MCFGPIO_PAR_TIMER);
|
||||
par &= 0x3f3f;
|
||||
writew(par, MCFGPIO_PAR_TIMER);
|
||||
#elif defined(CONFIG_M5275)
|
||||
/* setup QSPS pins for QSPI with gpio CS control */
|
||||
writew(0x003e, MCFGPIO_PAR_QSPI);
|
||||
#endif
|
||||
}
|
||||
#endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */
|
||||
|
||||
static struct platform_device *m527x_devices[] __initdata = {
|
||||
&m527x_uart,
|
||||
&m527x_fec[0],
|
||||
#ifdef CONFIG_FEC2
|
||||
&m527x_fec[1],
|
||||
#endif
|
||||
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
|
||||
&m527x_qspi,
|
||||
#endif
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
@ -187,6 +366,9 @@ void __init config_BSP(char *commandp, int size)
|
||||
mach_reset = m527x_cpu_reset;
|
||||
m527x_uarts_init();
|
||||
m527x_fec_init();
|
||||
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
|
||||
m527x_qspi_init();
|
||||
#endif
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
@ -17,10 +17,13 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfsim.h>
|
||||
#include <asm/mcfuart.h>
|
||||
#include <asm/mcfqspi.h>
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
@ -76,10 +79,141 @@ static struct platform_device m528x_fec = {
|
||||
.resource = m528x_fec_resources,
|
||||
};
|
||||
|
||||
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
|
||||
static struct resource m528x_qspi_resources[] = {
|
||||
{
|
||||
.start = MCFQSPI_IOBASE,
|
||||
.end = MCFQSPI_IOBASE + MCFQSPI_IOSIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = MCFINT_VECBASE + MCFINT_QSPI,
|
||||
.end = MCFINT_VECBASE + MCFINT_QSPI,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
#define MCFQSPI_CS0 147
|
||||
#define MCFQSPI_CS1 148
|
||||
#define MCFQSPI_CS2 149
|
||||
#define MCFQSPI_CS3 150
|
||||
|
||||
static int m528x_cs_setup(struct mcfqspi_cs_control *cs_control)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0");
|
||||
if (status) {
|
||||
pr_debug("gpio_request for MCFQSPI_CS0 failed\n");
|
||||
goto fail0;
|
||||
}
|
||||
status = gpio_direction_output(MCFQSPI_CS0, 1);
|
||||
if (status) {
|
||||
pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n");
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1");
|
||||
if (status) {
|
||||
pr_debug("gpio_request for MCFQSPI_CS1 failed\n");
|
||||
goto fail1;
|
||||
}
|
||||
status = gpio_direction_output(MCFQSPI_CS1, 1);
|
||||
if (status) {
|
||||
pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n");
|
||||
goto fail2;
|
||||
}
|
||||
|
||||
status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2");
|
||||
if (status) {
|
||||
pr_debug("gpio_request for MCFQSPI_CS2 failed\n");
|
||||
goto fail2;
|
||||
}
|
||||
status = gpio_direction_output(MCFQSPI_CS2, 1);
|
||||
if (status) {
|
||||
pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n");
|
||||
goto fail3;
|
||||
}
|
||||
|
||||
status = gpio_request(MCFQSPI_CS3, "MCFQSPI_CS3");
|
||||
if (status) {
|
||||
pr_debug("gpio_request for MCFQSPI_CS3 failed\n");
|
||||
goto fail3;
|
||||
}
|
||||
status = gpio_direction_output(MCFQSPI_CS3, 1);
|
||||
if (status) {
|
||||
pr_debug("gpio_direction_output for MCFQSPI_CS3 failed\n");
|
||||
goto fail4;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail4:
|
||||
gpio_free(MCFQSPI_CS3);
|
||||
fail3:
|
||||
gpio_free(MCFQSPI_CS2);
|
||||
fail2:
|
||||
gpio_free(MCFQSPI_CS1);
|
||||
fail1:
|
||||
gpio_free(MCFQSPI_CS0);
|
||||
fail0:
|
||||
return status;
|
||||
}
|
||||
|
||||
static void m528x_cs_teardown(struct mcfqspi_cs_control *cs_control)
|
||||
{
|
||||
gpio_free(MCFQSPI_CS3);
|
||||
gpio_free(MCFQSPI_CS2);
|
||||
gpio_free(MCFQSPI_CS1);
|
||||
gpio_free(MCFQSPI_CS0);
|
||||
}
|
||||
|
||||
static void m528x_cs_select(struct mcfqspi_cs_control *cs_control,
|
||||
u8 chip_select, bool cs_high)
|
||||
{
|
||||
gpio_set_value(MCFQSPI_CS0 + chip_select, cs_high);
|
||||
}
|
||||
|
||||
static void m528x_cs_deselect(struct mcfqspi_cs_control *cs_control,
|
||||
u8 chip_select, bool cs_high)
|
||||
{
|
||||
gpio_set_value(MCFQSPI_CS0 + chip_select, !cs_high);
|
||||
}
|
||||
|
||||
static struct mcfqspi_cs_control m528x_cs_control = {
|
||||
.setup = m528x_cs_setup,
|
||||
.teardown = m528x_cs_teardown,
|
||||
.select = m528x_cs_select,
|
||||
.deselect = m528x_cs_deselect,
|
||||
};
|
||||
|
||||
static struct mcfqspi_platform_data m528x_qspi_data = {
|
||||
.bus_num = 0,
|
||||
.num_chipselect = 4,
|
||||
.cs_control = &m528x_cs_control,
|
||||
};
|
||||
|
||||
static struct platform_device m528x_qspi = {
|
||||
.name = "mcfqspi",
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(m528x_qspi_resources),
|
||||
.resource = m528x_qspi_resources,
|
||||
.dev.platform_data = &m528x_qspi_data,
|
||||
};
|
||||
|
||||
static void __init m528x_qspi_init(void)
|
||||
{
|
||||
/* setup Port QS for QSPI with gpio CS control */
|
||||
__raw_writeb(0x07, MCFGPIO_PQSPAR);
|
||||
}
|
||||
#endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */
|
||||
|
||||
static struct platform_device *m528x_devices[] __initdata = {
|
||||
&m528x_uart,
|
||||
&m528x_fec,
|
||||
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
|
||||
&m528x_qspi,
|
||||
#endif
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
@ -174,6 +308,9 @@ static int __init init_BSP(void)
|
||||
mach_reset = m528x_cpu_reset;
|
||||
m528x_uarts_init();
|
||||
m528x_fec_init();
|
||||
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
|
||||
m528x_qspi_init();
|
||||
#endif
|
||||
platform_add_devices(m528x_devices, ARRAY_SIZE(m528x_devices));
|
||||
return 0;
|
||||
}
|
||||
|
@ -21,12 +21,15 @@
|
||||
#include <linux/param.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/spi/spi.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/coldfire.h>
|
||||
#include <asm/mcfsim.h>
|
||||
#include <asm/mcfuart.h>
|
||||
#include <asm/mcfdma.h>
|
||||
#include <asm/mcfwdebug.h>
|
||||
#include <asm/mcfqspi.h>
|
||||
|
||||
/***************************************************************************/
|
||||
|
||||
@ -82,9 +85,127 @@ static struct platform_device m532x_fec = {
|
||||
.resource = m532x_fec_resources,
|
||||
};
|
||||
|
||||
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
|
||||
static struct resource m532x_qspi_resources[] = {
|
||||
{
|
||||
.start = MCFQSPI_IOBASE,
|
||||
.end = MCFQSPI_IOBASE + MCFQSPI_IOSIZE - 1,
|
||||
.flags = IORESOURCE_MEM,
|
||||
},
|
||||
{
|
||||
.start = MCFINT_VECBASE + MCFINT_QSPI,
|
||||
.end = MCFINT_VECBASE + MCFINT_QSPI,
|
||||
.flags = IORESOURCE_IRQ,
|
||||
},
|
||||
};
|
||||
|
||||
#define MCFQSPI_CS0 84
|
||||
#define MCFQSPI_CS1 85
|
||||
#define MCFQSPI_CS2 86
|
||||
|
||||
static int m532x_cs_setup(struct mcfqspi_cs_control *cs_control)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = gpio_request(MCFQSPI_CS0, "MCFQSPI_CS0");
|
||||
if (status) {
|
||||
pr_debug("gpio_request for MCFQSPI_CS0 failed\n");
|
||||
goto fail0;
|
||||
}
|
||||
status = gpio_direction_output(MCFQSPI_CS0, 1);
|
||||
if (status) {
|
||||
pr_debug("gpio_direction_output for MCFQSPI_CS0 failed\n");
|
||||
goto fail1;
|
||||
}
|
||||
|
||||
status = gpio_request(MCFQSPI_CS1, "MCFQSPI_CS1");
|
||||
if (status) {
|
||||
pr_debug("gpio_request for MCFQSPI_CS1 failed\n");
|
||||
goto fail1;
|
||||
}
|
||||
status = gpio_direction_output(MCFQSPI_CS1, 1);
|
||||
if (status) {
|
||||
pr_debug("gpio_direction_output for MCFQSPI_CS1 failed\n");
|
||||
goto fail2;
|
||||
}
|
||||
|
||||
status = gpio_request(MCFQSPI_CS2, "MCFQSPI_CS2");
|
||||
if (status) {
|
||||
pr_debug("gpio_request for MCFQSPI_CS2 failed\n");
|
||||
goto fail2;
|
||||
}
|
||||
status = gpio_direction_output(MCFQSPI_CS2, 1);
|
||||
if (status) {
|
||||
pr_debug("gpio_direction_output for MCFQSPI_CS2 failed\n");
|
||||
goto fail3;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail3:
|
||||
gpio_free(MCFQSPI_CS2);
|
||||
fail2:
|
||||
gpio_free(MCFQSPI_CS1);
|
||||
fail1:
|
||||
gpio_free(MCFQSPI_CS0);
|
||||
fail0:
|
||||
return status;
|
||||
}
|
||||
|
||||
static void m532x_cs_teardown(struct mcfqspi_cs_control *cs_control)
|
||||
{
|
||||
gpio_free(MCFQSPI_CS2);
|
||||
gpio_free(MCFQSPI_CS1);
|
||||
gpio_free(MCFQSPI_CS0);
|
||||
}
|
||||
|
||||
static void m532x_cs_select(struct mcfqspi_cs_control *cs_control,
|
||||
u8 chip_select, bool cs_high)
|
||||
{
|
||||
gpio_set_value(MCFQSPI_CS0 + chip_select, cs_high);
|
||||
}
|
||||
|
||||
static void m532x_cs_deselect(struct mcfqspi_cs_control *cs_control,
|
||||
u8 chip_select, bool cs_high)
|
||||
{
|
||||
gpio_set_value(MCFQSPI_CS0 + chip_select, !cs_high);
|
||||
}
|
||||
|
||||
static struct mcfqspi_cs_control m532x_cs_control = {
|
||||
.setup = m532x_cs_setup,
|
||||
.teardown = m532x_cs_teardown,
|
||||
.select = m532x_cs_select,
|
||||
.deselect = m532x_cs_deselect,
|
||||
};
|
||||
|
||||
static struct mcfqspi_platform_data m532x_qspi_data = {
|
||||
.bus_num = 0,
|
||||
.num_chipselect = 3,
|
||||
.cs_control = &m532x_cs_control,
|
||||
};
|
||||
|
||||
static struct platform_device m532x_qspi = {
|
||||
.name = "mcfqspi",
|
||||
.id = 0,
|
||||
.num_resources = ARRAY_SIZE(m532x_qspi_resources),
|
||||
.resource = m532x_qspi_resources,
|
||||
.dev.platform_data = &m532x_qspi_data,
|
||||
};
|
||||
|
||||
static void __init m532x_qspi_init(void)
|
||||
{
|
||||
/* setup QSPS pins for QSPI with gpio CS control */
|
||||
writew(0x01f0, MCF_GPIO_PAR_QSPI);
|
||||
}
|
||||
#endif /* defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE) */
|
||||
|
||||
|
||||
static struct platform_device *m532x_devices[] __initdata = {
|
||||
&m532x_uart,
|
||||
&m532x_fec,
|
||||
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
|
||||
&m532x_qspi,
|
||||
#endif
|
||||
};
|
||||
|
||||
/***************************************************************************/
|
||||
@ -158,6 +279,9 @@ static int __init init_BSP(void)
|
||||
{
|
||||
m532x_uarts_init();
|
||||
m532x_fec_init();
|
||||
#if defined(CONFIG_SPI_COLDFIRE_QSPI) || defined(CONFIG_SPI_COLDFIRE_QSPI_MODULE)
|
||||
m532x_qspi_init();
|
||||
#endif
|
||||
platform_add_devices(m532x_devices, ARRAY_SIZE(m532x_devices));
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user