Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * linux/arch/arm/mach-pxa/icontrol.c
0004  *
0005  * Support for the iControl and SafeTcam platforms from TMT Services
0006  * using the Embedian MXM-8x10 Computer on Module
0007  *
0008  * Copyright (C) 2009 TMT Services & Supplies (Pty) Ltd.
0009  *
0010  * 2010-01-21 Hennie van der Merve <hvdmerwe@tmtservies.co.za>
0011  */
0012 
0013 #include <linux/irq.h>
0014 #include <linux/platform_device.h>
0015 #include <linux/property.h>
0016 #include <linux/gpio/machine.h>
0017 
0018 #include <asm/mach-types.h>
0019 #include <asm/mach/arch.h>
0020 
0021 #include "pxa320.h"
0022 #include "mxm8x10.h"
0023 
0024 #include <linux/spi/spi.h>
0025 #include <linux/spi/pxa2xx_spi.h>
0026 #include <linux/regulator/machine.h>
0027 
0028 #include "generic.h"
0029 
0030 #define ICONTROL_MCP251x_nCS1   (15)
0031 #define ICONTROL_MCP251x_nCS2   (16)
0032 #define ICONTROL_MCP251x_nCS3   (17)
0033 #define ICONTROL_MCP251x_nCS4   (24)
0034 
0035 #define ICONTROL_MCP251x_nIRQ1  (74)
0036 #define ICONTROL_MCP251x_nIRQ2  (75)
0037 #define ICONTROL_MCP251x_nIRQ3  (76)
0038 #define ICONTROL_MCP251x_nIRQ4  (77)
0039 
0040 static struct pxa2xx_spi_chip mcp251x_chip_info1 = {
0041     .tx_threshold   = 8,
0042     .rx_threshold   = 128,
0043     .dma_burst_size = 8,
0044     .timeout        = 235,
0045 };
0046 
0047 static struct pxa2xx_spi_chip mcp251x_chip_info2 = {
0048     .tx_threshold   = 8,
0049     .rx_threshold   = 128,
0050     .dma_burst_size = 8,
0051     .timeout        = 235,
0052 };
0053 
0054 static struct pxa2xx_spi_chip mcp251x_chip_info3 = {
0055     .tx_threshold   = 8,
0056     .rx_threshold   = 128,
0057     .dma_burst_size = 8,
0058     .timeout        = 235,
0059 };
0060 
0061 static struct pxa2xx_spi_chip mcp251x_chip_info4 = {
0062     .tx_threshold   = 8,
0063     .rx_threshold   = 128,
0064     .dma_burst_size = 8,
0065     .timeout        = 235,
0066 };
0067 
0068 static const struct property_entry mcp251x_properties[] = {
0069     PROPERTY_ENTRY_U32("clock-frequency", 16000000),
0070     {}
0071 };
0072 
0073 static const struct software_node mcp251x_node = {
0074     .properties = mcp251x_properties,
0075 };
0076 
0077 static struct spi_board_info mcp251x_board_info[] = {
0078     {
0079         .modalias        = "mcp2515",
0080         .max_speed_hz    = 6500000,
0081         .bus_num         = 3,
0082         .chip_select     = 0,
0083         .swnode      = &mcp251x_node,
0084         .controller_data = &mcp251x_chip_info1,
0085         .irq             = PXA_GPIO_TO_IRQ(ICONTROL_MCP251x_nIRQ1)
0086     },
0087     {
0088         .modalias        = "mcp2515",
0089         .max_speed_hz    = 6500000,
0090         .bus_num         = 3,
0091         .chip_select     = 1,
0092         .swnode      = &mcp251x_node,
0093         .controller_data = &mcp251x_chip_info2,
0094         .irq             = PXA_GPIO_TO_IRQ(ICONTROL_MCP251x_nIRQ2)
0095     },
0096     {
0097         .modalias        = "mcp2515",
0098         .max_speed_hz    = 6500000,
0099         .bus_num         = 4,
0100         .chip_select     = 0,
0101         .swnode      = &mcp251x_node,
0102         .controller_data = &mcp251x_chip_info3,
0103         .irq             = PXA_GPIO_TO_IRQ(ICONTROL_MCP251x_nIRQ3)
0104     },
0105     {
0106         .modalias        = "mcp2515",
0107         .max_speed_hz    = 6500000,
0108         .bus_num         = 4,
0109         .chip_select     = 1,
0110         .swnode      = &mcp251x_node,
0111         .controller_data = &mcp251x_chip_info4,
0112         .irq             = PXA_GPIO_TO_IRQ(ICONTROL_MCP251x_nIRQ4)
0113     }
0114 };
0115 
0116 static struct pxa2xx_spi_controller pxa_ssp3_spi_master_info = {
0117     .num_chipselect = 2,
0118     .enable_dma     = 1
0119 };
0120 
0121 static struct pxa2xx_spi_controller pxa_ssp4_spi_master_info = {
0122     .num_chipselect = 2,
0123     .enable_dma     = 1
0124 };
0125 
0126 struct platform_device pxa_spi_ssp3 = {
0127     .name          = "pxa2xx-spi",
0128     .id            = 3,
0129     .dev           = {
0130         .platform_data = &pxa_ssp3_spi_master_info,
0131     }
0132 };
0133 
0134 struct platform_device pxa_spi_ssp4 = {
0135     .name          = "pxa2xx-spi",
0136     .id            = 4,
0137     .dev           = {
0138         .platform_data = &pxa_ssp4_spi_master_info,
0139     }
0140 };
0141 
0142 static struct gpiod_lookup_table pxa_ssp3_gpio_table = {
0143     .dev_id = "spi3",
0144     .table = {
0145         GPIO_LOOKUP_IDX("gpio-pxa", ICONTROL_MCP251x_nCS1, "cs", 0, GPIO_ACTIVE_LOW),
0146         GPIO_LOOKUP_IDX("gpio-pxa", ICONTROL_MCP251x_nCS2, "cs", 1, GPIO_ACTIVE_LOW),
0147         { },
0148     },
0149 };
0150 
0151 static struct gpiod_lookup_table pxa_ssp4_gpio_table = {
0152     .dev_id = "spi4",
0153     .table = {
0154         GPIO_LOOKUP_IDX("gpio-pxa", ICONTROL_MCP251x_nCS3, "cs", 0, GPIO_ACTIVE_LOW),
0155         GPIO_LOOKUP_IDX("gpio-pxa", ICONTROL_MCP251x_nCS4, "cs", 1, GPIO_ACTIVE_LOW),
0156         { },
0157     },
0158 };
0159 
0160 static struct platform_device *icontrol_spi_devices[] __initdata = {
0161     &pxa_spi_ssp3,
0162     &pxa_spi_ssp4,
0163 };
0164 
0165 static mfp_cfg_t mfp_can_cfg[] __initdata = {
0166     /* CAN CS lines */
0167     GPIO15_GPIO,
0168     GPIO16_GPIO,
0169     GPIO17_GPIO,
0170     GPIO24_GPIO,
0171 
0172     /* SPI (SSP3) lines */
0173     GPIO89_SSP3_SCLK,
0174     GPIO91_SSP3_TXD,
0175     GPIO92_SSP3_RXD,
0176 
0177     /* SPI (SSP4) lines */
0178     GPIO93_SSP4_SCLK,
0179     GPIO95_SSP4_TXD,
0180     GPIO96_SSP4_RXD,
0181 
0182     /* CAN nIRQ lines */
0183     GPIO74_GPIO | MFP_LPM_EDGE_RISE,
0184     GPIO75_GPIO | MFP_LPM_EDGE_RISE,
0185     GPIO76_GPIO | MFP_LPM_EDGE_RISE,
0186     GPIO77_GPIO | MFP_LPM_EDGE_RISE
0187 };
0188 
0189 static void __init icontrol_can_init(void)
0190 {
0191     pxa3xx_mfp_config(ARRAY_AND_SIZE(mfp_can_cfg));
0192     gpiod_add_lookup_table(&pxa_ssp3_gpio_table);
0193     gpiod_add_lookup_table(&pxa_ssp4_gpio_table);
0194     platform_add_devices(ARRAY_AND_SIZE(icontrol_spi_devices));
0195     spi_register_board_info(ARRAY_AND_SIZE(mcp251x_board_info));
0196 }
0197 
0198 static void __init icontrol_init(void)
0199 {
0200     mxm_8x10_barebones_init();
0201     mxm_8x10_usb_host_init();
0202     mxm_8x10_mmc_init();
0203 
0204     icontrol_can_init();
0205 
0206     regulator_has_full_constraints();
0207 }
0208 
0209 MACHINE_START(ICONTROL, "iControl/SafeTcam boards using Embedian MXM-8x10 CoM")
0210     .atag_offset    = 0x100,
0211     .map_io     = pxa3xx_map_io,
0212     .nr_irqs    = PXA_NR_IRQS,
0213     .init_irq   = pxa3xx_init_irq,
0214     .handle_irq = pxa3xx_handle_irq,
0215     .init_time  = pxa_timer_init,
0216     .init_machine   = icontrol_init,
0217     .restart    = pxa_restart,
0218 MACHINE_END