mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-08-24 09:50:04 +00:00
![Linus Walleij](/assets/img/avatar_default.png)
This converts the PXA2xx SPI driver to use GPIO descriptors exclusively to retrieve GPIO chip select lines. The device tree and ACPI paths of the driver already use descriptors, hence ->use_gpio_descriptors is already set and this codepath is well tested. Convert all the PXA boards providing chip select GPIOs as platform data and drop the old GPIO chipselect handling in favor of the core managing it exclusively. Cc: Marek Vasut <marek.vasut@gmail.com> Cc: Daniel Mack <daniel@zonque.org> Cc: Haojian Zhuang <haojian.zhuang@gmail.com> Cc: Robert Jarzmik <robert.jarzmik@free.fr> Cc: linux-arm-kernel@lists.infradead.org Acked-by: Jonathan Cameron <Jonathan.Cameron@huawei.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Link: https://lore.kernel.org/r/20220125005836.494807-1-linus.walleij@linaro.org Signed-off-by: Mark Brown <broonie@kernel.org>
218 lines
5.2 KiB
C
218 lines
5.2 KiB
C
// SPDX-License-Identifier: GPL-2.0-only
|
|
/*
|
|
* linux/arch/arm/mach-pxa/icontrol.c
|
|
*
|
|
* Support for the iControl and SafeTcam platforms from TMT Services
|
|
* using the Embedian MXM-8x10 Computer on Module
|
|
*
|
|
* Copyright (C) 2009 TMT Services & Supplies (Pty) Ltd.
|
|
*
|
|
* 2010-01-21 Hennie van der Merve <hvdmerwe@tmtservies.co.za>
|
|
*/
|
|
|
|
#include <linux/irq.h>
|
|
#include <linux/platform_device.h>
|
|
#include <linux/property.h>
|
|
#include <linux/gpio/machine.h>
|
|
|
|
#include <asm/mach-types.h>
|
|
#include <asm/mach/arch.h>
|
|
|
|
#include "pxa320.h"
|
|
#include "mxm8x10.h"
|
|
|
|
#include <linux/spi/spi.h>
|
|
#include <linux/spi/pxa2xx_spi.h>
|
|
#include <linux/regulator/machine.h>
|
|
|
|
#include "generic.h"
|
|
|
|
#define ICONTROL_MCP251x_nCS1 (15)
|
|
#define ICONTROL_MCP251x_nCS2 (16)
|
|
#define ICONTROL_MCP251x_nCS3 (17)
|
|
#define ICONTROL_MCP251x_nCS4 (24)
|
|
|
|
#define ICONTROL_MCP251x_nIRQ1 (74)
|
|
#define ICONTROL_MCP251x_nIRQ2 (75)
|
|
#define ICONTROL_MCP251x_nIRQ3 (76)
|
|
#define ICONTROL_MCP251x_nIRQ4 (77)
|
|
|
|
static struct pxa2xx_spi_chip mcp251x_chip_info1 = {
|
|
.tx_threshold = 8,
|
|
.rx_threshold = 128,
|
|
.dma_burst_size = 8,
|
|
.timeout = 235,
|
|
};
|
|
|
|
static struct pxa2xx_spi_chip mcp251x_chip_info2 = {
|
|
.tx_threshold = 8,
|
|
.rx_threshold = 128,
|
|
.dma_burst_size = 8,
|
|
.timeout = 235,
|
|
};
|
|
|
|
static struct pxa2xx_spi_chip mcp251x_chip_info3 = {
|
|
.tx_threshold = 8,
|
|
.rx_threshold = 128,
|
|
.dma_burst_size = 8,
|
|
.timeout = 235,
|
|
};
|
|
|
|
static struct pxa2xx_spi_chip mcp251x_chip_info4 = {
|
|
.tx_threshold = 8,
|
|
.rx_threshold = 128,
|
|
.dma_burst_size = 8,
|
|
.timeout = 235,
|
|
};
|
|
|
|
static const struct property_entry mcp251x_properties[] = {
|
|
PROPERTY_ENTRY_U32("clock-frequency", 16000000),
|
|
{}
|
|
};
|
|
|
|
static const struct software_node mcp251x_node = {
|
|
.properties = mcp251x_properties,
|
|
};
|
|
|
|
static struct spi_board_info mcp251x_board_info[] = {
|
|
{
|
|
.modalias = "mcp2515",
|
|
.max_speed_hz = 6500000,
|
|
.bus_num = 3,
|
|
.chip_select = 0,
|
|
.swnode = &mcp251x_node,
|
|
.controller_data = &mcp251x_chip_info1,
|
|
.irq = PXA_GPIO_TO_IRQ(ICONTROL_MCP251x_nIRQ1)
|
|
},
|
|
{
|
|
.modalias = "mcp2515",
|
|
.max_speed_hz = 6500000,
|
|
.bus_num = 3,
|
|
.chip_select = 1,
|
|
.swnode = &mcp251x_node,
|
|
.controller_data = &mcp251x_chip_info2,
|
|
.irq = PXA_GPIO_TO_IRQ(ICONTROL_MCP251x_nIRQ2)
|
|
},
|
|
{
|
|
.modalias = "mcp2515",
|
|
.max_speed_hz = 6500000,
|
|
.bus_num = 4,
|
|
.chip_select = 0,
|
|
.swnode = &mcp251x_node,
|
|
.controller_data = &mcp251x_chip_info3,
|
|
.irq = PXA_GPIO_TO_IRQ(ICONTROL_MCP251x_nIRQ3)
|
|
},
|
|
{
|
|
.modalias = "mcp2515",
|
|
.max_speed_hz = 6500000,
|
|
.bus_num = 4,
|
|
.chip_select = 1,
|
|
.swnode = &mcp251x_node,
|
|
.controller_data = &mcp251x_chip_info4,
|
|
.irq = PXA_GPIO_TO_IRQ(ICONTROL_MCP251x_nIRQ4)
|
|
}
|
|
};
|
|
|
|
static struct pxa2xx_spi_controller pxa_ssp3_spi_master_info = {
|
|
.num_chipselect = 2,
|
|
.enable_dma = 1
|
|
};
|
|
|
|
static struct pxa2xx_spi_controller pxa_ssp4_spi_master_info = {
|
|
.num_chipselect = 2,
|
|
.enable_dma = 1
|
|
};
|
|
|
|
struct platform_device pxa_spi_ssp3 = {
|
|
.name = "pxa2xx-spi",
|
|
.id = 3,
|
|
.dev = {
|
|
.platform_data = &pxa_ssp3_spi_master_info,
|
|
}
|
|
};
|
|
|
|
struct platform_device pxa_spi_ssp4 = {
|
|
.name = "pxa2xx-spi",
|
|
.id = 4,
|
|
.dev = {
|
|
.platform_data = &pxa_ssp4_spi_master_info,
|
|
}
|
|
};
|
|
|
|
static struct gpiod_lookup_table pxa_ssp3_gpio_table = {
|
|
.dev_id = "pxa2xx-spi.3",
|
|
.table = {
|
|
GPIO_LOOKUP_IDX("gpio-pxa", ICONTROL_MCP251x_nCS1, "cs", 0, GPIO_ACTIVE_LOW),
|
|
GPIO_LOOKUP_IDX("gpio-pxa", ICONTROL_MCP251x_nCS2, "cs", 1, GPIO_ACTIVE_LOW),
|
|
{ },
|
|
},
|
|
};
|
|
|
|
static struct gpiod_lookup_table pxa_ssp4_gpio_table = {
|
|
.dev_id = "pxa2xx-spi.4",
|
|
.table = {
|
|
GPIO_LOOKUP_IDX("gpio-pxa", ICONTROL_MCP251x_nCS3, "cs", 0, GPIO_ACTIVE_LOW),
|
|
GPIO_LOOKUP_IDX("gpio-pxa", ICONTROL_MCP251x_nCS4, "cs", 1, GPIO_ACTIVE_LOW),
|
|
{ },
|
|
},
|
|
};
|
|
|
|
static struct platform_device *icontrol_spi_devices[] __initdata = {
|
|
&pxa_spi_ssp3,
|
|
&pxa_spi_ssp4,
|
|
};
|
|
|
|
static mfp_cfg_t mfp_can_cfg[] __initdata = {
|
|
/* CAN CS lines */
|
|
GPIO15_GPIO,
|
|
GPIO16_GPIO,
|
|
GPIO17_GPIO,
|
|
GPIO24_GPIO,
|
|
|
|
/* SPI (SSP3) lines */
|
|
GPIO89_SSP3_SCLK,
|
|
GPIO91_SSP3_TXD,
|
|
GPIO92_SSP3_RXD,
|
|
|
|
/* SPI (SSP4) lines */
|
|
GPIO93_SSP4_SCLK,
|
|
GPIO95_SSP4_TXD,
|
|
GPIO96_SSP4_RXD,
|
|
|
|
/* CAN nIRQ lines */
|
|
GPIO74_GPIO | MFP_LPM_EDGE_RISE,
|
|
GPIO75_GPIO | MFP_LPM_EDGE_RISE,
|
|
GPIO76_GPIO | MFP_LPM_EDGE_RISE,
|
|
GPIO77_GPIO | MFP_LPM_EDGE_RISE
|
|
};
|
|
|
|
static void __init icontrol_can_init(void)
|
|
{
|
|
pxa3xx_mfp_config(ARRAY_AND_SIZE(mfp_can_cfg));
|
|
gpiod_add_lookup_table(&pxa_ssp3_gpio_table);
|
|
gpiod_add_lookup_table(&pxa_ssp4_gpio_table);
|
|
platform_add_devices(ARRAY_AND_SIZE(icontrol_spi_devices));
|
|
spi_register_board_info(ARRAY_AND_SIZE(mcp251x_board_info));
|
|
}
|
|
|
|
static void __init icontrol_init(void)
|
|
{
|
|
mxm_8x10_barebones_init();
|
|
mxm_8x10_usb_host_init();
|
|
mxm_8x10_mmc_init();
|
|
|
|
icontrol_can_init();
|
|
|
|
regulator_has_full_constraints();
|
|
}
|
|
|
|
MACHINE_START(ICONTROL, "iControl/SafeTcam boards using Embedian MXM-8x10 CoM")
|
|
.atag_offset = 0x100,
|
|
.map_io = pxa3xx_map_io,
|
|
.nr_irqs = PXA_NR_IRQS,
|
|
.init_irq = pxa3xx_init_irq,
|
|
.handle_irq = pxa3xx_handle_irq,
|
|
.init_time = pxa_timer_init,
|
|
.init_machine = icontrol_init,
|
|
.restart = pxa_restart,
|
|
MACHINE_END
|