diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:49:45 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:49:45 +0000 |
commit | 2c3c1048746a4622d8c89a29670120dc8fab93c4 (patch) | |
tree | 848558de17fb3008cdf4d861b01ac7781903ce39 /arch/arm/mach-pxa/icontrol.c | |
parent | Initial commit. (diff) | |
download | linux-2c3c1048746a4622d8c89a29670120dc8fab93c4.tar.xz linux-2c3c1048746a4622d8c89a29670120dc8fab93c4.zip |
Adding upstream version 6.1.76.upstream/6.1.76
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'arch/arm/mach-pxa/icontrol.c')
-rw-r--r-- | arch/arm/mach-pxa/icontrol.c | 218 |
1 files changed, 218 insertions, 0 deletions
diff --git a/arch/arm/mach-pxa/icontrol.c b/arch/arm/mach-pxa/icontrol.c new file mode 100644 index 000000000..624088257 --- /dev/null +++ b/arch/arm/mach-pxa/icontrol.c @@ -0,0 +1,218 @@ +// 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 = "spi3", + .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 = "spi4", + .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 |