forked from luck/tmp_suning_uos_patched
98da352953
This adds a driver for the U300 pinmux portions of the system controller "SYSCON". It also serves as an example of how to use the pinmux subsystem. This driver also houses the platform data for the only supported platform. This deletes the old U300 driver in arch/arm/mach-u300 and replace it with a driver using the new subsystem. The new driver is considerably fatter than the old one, but it also registers all 467 pins of the system and adds the power and EMIF pin groups and corresponding functions. The idea is to use this driver as a a reference for other implementation so it needs to be as complete and verbose as possible. Reviewed-by: Barry Song <21cnbao@gmail.com> [Fixup for changed function names and semantics in the v10 patch] Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
104 lines
2.9 KiB
C
104 lines
2.9 KiB
C
/*
|
|
* arch/arm/mach-u300/spi.c
|
|
*
|
|
* Copyright (C) 2009 ST-Ericsson AB
|
|
* License terms: GNU General Public License (GPL) version 2
|
|
*
|
|
* Author: Linus Walleij <linus.walleij@stericsson.com>
|
|
*/
|
|
#include <linux/device.h>
|
|
#include <linux/amba/bus.h>
|
|
#include <linux/spi/spi.h>
|
|
#include <linux/amba/pl022.h>
|
|
#include <linux/err.h>
|
|
#include <mach/coh901318.h>
|
|
#include <mach/dma_channels.h>
|
|
|
|
/*
|
|
* The following is for the actual devices on the SSP/SPI bus
|
|
*/
|
|
#ifdef CONFIG_MACH_U300_SPIDUMMY
|
|
static void select_dummy_chip(u32 chipselect)
|
|
{
|
|
pr_debug("CORE: %s called with CS=0x%x (%s)\n",
|
|
__func__,
|
|
chipselect,
|
|
chipselect ? "unselect chip" : "select chip");
|
|
/*
|
|
* Here you would write the chip select value to the GPIO pins if
|
|
* this was a real chip (but this is a loopback dummy).
|
|
*/
|
|
}
|
|
|
|
struct pl022_config_chip dummy_chip_info = {
|
|
/* available POLLING_TRANSFER, INTERRUPT_TRANSFER, DMA_TRANSFER */
|
|
.com_mode = DMA_TRANSFER,
|
|
.iface = SSP_INTERFACE_MOTOROLA_SPI,
|
|
/* We can only act as master but SSP_SLAVE is possible in theory */
|
|
.hierarchy = SSP_MASTER,
|
|
/* 0 = drive TX even as slave, 1 = do not drive TX as slave */
|
|
.slave_tx_disable = 0,
|
|
.rx_lev_trig = SSP_RX_4_OR_MORE_ELEM,
|
|
.tx_lev_trig = SSP_TX_4_OR_MORE_EMPTY_LOC,
|
|
.ctrl_len = SSP_BITS_12,
|
|
.wait_state = SSP_MWIRE_WAIT_ZERO,
|
|
.duplex = SSP_MICROWIRE_CHANNEL_FULL_DUPLEX,
|
|
/*
|
|
* This is where you insert a call to a function to enable CS
|
|
* (usually GPIO) for a certain chip.
|
|
*/
|
|
.cs_control = select_dummy_chip,
|
|
};
|
|
#endif
|
|
|
|
static struct spi_board_info u300_spi_devices[] = {
|
|
#ifdef CONFIG_MACH_U300_SPIDUMMY
|
|
{
|
|
/* A dummy chip used for loopback tests */
|
|
.modalias = "spi-dummy",
|
|
/* Really dummy, pass in additional chip config here */
|
|
.platform_data = NULL,
|
|
/* This defines how the controller shall handle the device */
|
|
.controller_data = &dummy_chip_info,
|
|
/* .irq - no external IRQ routed from this device */
|
|
.max_speed_hz = 1000000,
|
|
.bus_num = 0, /* Only one bus on this chip */
|
|
.chip_select = 0,
|
|
/* Means SPI_CS_HIGH, change if e.g low CS */
|
|
.mode = SPI_MODE_1 | SPI_LOOP,
|
|
},
|
|
#endif
|
|
};
|
|
|
|
static struct pl022_ssp_controller ssp_platform_data = {
|
|
/* If you have several SPI buses this varies, we have only bus 0 */
|
|
.bus_id = 0,
|
|
/*
|
|
* On the APP CPU GPIO 4, 5 and 6 are connected as generic
|
|
* chip selects for SPI. (Same on U330, U335 and U365.)
|
|
* TODO: make sure the GPIO driver can select these properly
|
|
* and do padmuxing accordingly too.
|
|
*/
|
|
.num_chipselect = 3,
|
|
#ifdef CONFIG_COH901318
|
|
.enable_dma = 1,
|
|
.dma_filter = coh901318_filter_id,
|
|
.dma_rx_param = (void *) U300_DMA_SPI_RX,
|
|
.dma_tx_param = (void *) U300_DMA_SPI_TX,
|
|
#else
|
|
.enable_dma = 0,
|
|
#endif
|
|
};
|
|
|
|
|
|
void __init u300_spi_init(struct amba_device *adev)
|
|
{
|
|
adev->dev.platform_data = &ssp_platform_data;
|
|
}
|
|
|
|
void __init u300_spi_register_board_devices(void)
|
|
{
|
|
/* Register any SPI devices */
|
|
spi_register_board_info(u300_spi_devices, ARRAY_SIZE(u300_spi_devices));
|
|
}
|