1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * linux/arch/arm/mach-pxa/icontrol.c 4 * 5 * Support for the iControl and SafeTcam platforms from TMT Services 6 * using the Embedian MXM-8x10 Computer on Module 7 * 8 * Copyright (C) 2009 TMT Services & Supplies (Pty) Ltd. 9 * 10 * 2010-01-21 Hennie van der Merve <hvdmerwe@tmtservies.co.za> 11 */ 12 13#include <linux/irq.h> 14#include <linux/platform_device.h> 15#include <linux/property.h> 16#include <linux/gpio.h> 17 18#include <asm/mach-types.h> 19#include <asm/mach/arch.h> 20 21#include "pxa320.h" 22#include "mxm8x10.h" 23 24#include <linux/spi/spi.h> 25#include <linux/spi/pxa2xx_spi.h> 26#include <linux/regulator/machine.h> 27 28#include "generic.h" 29 30#define ICONTROL_MCP251x_nCS1 (15) 31#define ICONTROL_MCP251x_nCS2 (16) 32#define ICONTROL_MCP251x_nCS3 (17) 33#define ICONTROL_MCP251x_nCS4 (24) 34 35#define ICONTROL_MCP251x_nIRQ1 (74) 36#define ICONTROL_MCP251x_nIRQ2 (75) 37#define ICONTROL_MCP251x_nIRQ3 (76) 38#define ICONTROL_MCP251x_nIRQ4 (77) 39 40static struct pxa2xx_spi_chip mcp251x_chip_info1 = { 41 .tx_threshold = 8, 42 .rx_threshold = 128, 43 .dma_burst_size = 8, 44 .timeout = 235, 45 .gpio_cs = ICONTROL_MCP251x_nCS1 46}; 47 48static struct pxa2xx_spi_chip mcp251x_chip_info2 = { 49 .tx_threshold = 8, 50 .rx_threshold = 128, 51 .dma_burst_size = 8, 52 .timeout = 235, 53 .gpio_cs = ICONTROL_MCP251x_nCS2 54}; 55 56static struct pxa2xx_spi_chip mcp251x_chip_info3 = { 57 .tx_threshold = 8, 58 .rx_threshold = 128, 59 .dma_burst_size = 8, 60 .timeout = 235, 61 .gpio_cs = ICONTROL_MCP251x_nCS3 62}; 63 64static struct pxa2xx_spi_chip mcp251x_chip_info4 = { 65 .tx_threshold = 8, 66 .rx_threshold = 128, 67 .dma_burst_size = 8, 68 .timeout = 235, 69 .gpio_cs = ICONTROL_MCP251x_nCS4 70}; 71 72static const struct property_entry mcp251x_properties[] = { 73 PROPERTY_ENTRY_U32("clock-frequency", 16000000), 74 {} 75}; 76 77static struct spi_board_info mcp251x_board_info[] = { 78 { 79 .modalias = "mcp2515", 80 .max_speed_hz = 6500000, 81 .bus_num = 3, 82 .chip_select = 0, 83 .properties = mcp251x_properties, 84 .controller_data = &mcp251x_chip_info1, 85 .irq = PXA_GPIO_TO_IRQ(ICONTROL_MCP251x_nIRQ1) 86 }, 87 { 88 .modalias = "mcp2515", 89 .max_speed_hz = 6500000, 90 .bus_num = 3, 91 .chip_select = 1, 92 .properties = mcp251x_properties, 93 .controller_data = &mcp251x_chip_info2, 94 .irq = PXA_GPIO_TO_IRQ(ICONTROL_MCP251x_nIRQ2) 95 }, 96 { 97 .modalias = "mcp2515", 98 .max_speed_hz = 6500000, 99 .bus_num = 4, 100 .chip_select = 0, 101 .properties = mcp251x_properties, 102 .controller_data = &mcp251x_chip_info3, 103 .irq = PXA_GPIO_TO_IRQ(ICONTROL_MCP251x_nIRQ3) 104 }, 105 { 106 .modalias = "mcp2515", 107 .max_speed_hz = 6500000, 108 .bus_num = 4, 109 .chip_select = 1, 110 .properties = mcp251x_properties, 111 .controller_data = &mcp251x_chip_info4, 112 .irq = PXA_GPIO_TO_IRQ(ICONTROL_MCP251x_nIRQ4) 113 } 114}; 115 116static struct pxa2xx_spi_controller pxa_ssp3_spi_master_info = { 117 .num_chipselect = 2, 118 .enable_dma = 1 119}; 120 121static struct pxa2xx_spi_controller pxa_ssp4_spi_master_info = { 122 .num_chipselect = 2, 123 .enable_dma = 1 124}; 125 126struct platform_device pxa_spi_ssp3 = { 127 .name = "pxa2xx-spi", 128 .id = 3, 129 .dev = { 130 .platform_data = &pxa_ssp3_spi_master_info, 131 } 132}; 133 134struct platform_device pxa_spi_ssp4 = { 135 .name = "pxa2xx-spi", 136 .id = 4, 137 .dev = { 138 .platform_data = &pxa_ssp4_spi_master_info, 139 } 140}; 141 142static struct platform_device *icontrol_spi_devices[] __initdata = { 143 &pxa_spi_ssp3, 144 &pxa_spi_ssp4, 145}; 146 147static mfp_cfg_t mfp_can_cfg[] __initdata = { 148 /* CAN CS lines */ 149 GPIO15_GPIO, 150 GPIO16_GPIO, 151 GPIO17_GPIO, 152 GPIO24_GPIO, 153 154 /* SPI (SSP3) lines */ 155 GPIO89_SSP3_SCLK, 156 GPIO91_SSP3_TXD, 157 GPIO92_SSP3_RXD, 158 159 /* SPI (SSP4) lines */ 160 GPIO93_SSP4_SCLK, 161 GPIO95_SSP4_TXD, 162 GPIO96_SSP4_RXD, 163 164 /* CAN nIRQ lines */ 165 GPIO74_GPIO | MFP_LPM_EDGE_RISE, 166 GPIO75_GPIO | MFP_LPM_EDGE_RISE, 167 GPIO76_GPIO | MFP_LPM_EDGE_RISE, 168 GPIO77_GPIO | MFP_LPM_EDGE_RISE 169}; 170 171static void __init icontrol_can_init(void) 172{ 173 pxa3xx_mfp_config(ARRAY_AND_SIZE(mfp_can_cfg)); 174 platform_add_devices(ARRAY_AND_SIZE(icontrol_spi_devices)); 175 spi_register_board_info(ARRAY_AND_SIZE(mcp251x_board_info)); 176} 177 178static void __init icontrol_init(void) 179{ 180 mxm_8x10_barebones_init(); 181 mxm_8x10_usb_host_init(); 182 mxm_8x10_mmc_init(); 183 184 icontrol_can_init(); 185 186 regulator_has_full_constraints(); 187} 188 189MACHINE_START(ICONTROL, "iControl/SafeTcam boards using Embedian MXM-8x10 CoM") 190 .atag_offset = 0x100, 191 .map_io = pxa3xx_map_io, 192 .nr_irqs = PXA_NR_IRQS, 193 .init_irq = pxa3xx_init_irq, 194 .handle_irq = pxa3xx_handle_irq, 195 .init_time = pxa_timer_init, 196 .init_machine = icontrol_init, 197 .restart = pxa_restart, 198MACHINE_END 199