| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507 | /* *  Copyright (C) 2010 Christian Glindkamp <christian.glindkamp@taskit.de> *                     taskit GmbH *                2010 Igor Plyatov <plyatov@gmail.com> *                     GeoSIG Ltd * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include <linux/platform_device.h>#include <linux/gpio.h>#include <linux/w1-gpio.h>#include <linux/i2c.h>#include <linux/i2c/pcf857x.h>#include <linux/gpio_keys.h>#include <linux/input.h>#include <asm/mach-types.h>#include <asm/mach/arch.h>#include <mach/at91sam9_smc.h>#include "at91_aic.h"#include "board.h"#include "sam9_smc.h"#include "generic.h"#include "gsia18s.h"#include "stamp9g20.h"static void __init gsia18s_init_early(void){	stamp9g20_init_early();}/* * Two USB Host ports */static struct at91_usbh_data __initdata usbh_data = {	.ports		= 2,	.vbus_pin	= {-EINVAL, -EINVAL},	.overcurrent_pin= {-EINVAL, -EINVAL},};/* * USB Device port */static struct at91_udc_data __initdata udc_data = {	.vbus_pin	= AT91_PIN_PA22,	.pullup_pin	= -EINVAL,		/* pull-up driven by UDC */};/* * MACB Ethernet device */static struct macb_platform_data __initdata macb_data = {	.phy_irq_pin	= AT91_PIN_PA28,	.is_rmii	= 1,};/* * LEDs and GPOs */static struct gpio_led gpio_leds[] = {	{		.name			= "gpo:spi1reset",		.gpio			= AT91_PIN_PC1,		.active_low		= 0,		.default_trigger	= "none",		.default_state		= LEDS_GPIO_DEFSTATE_OFF,	},	{		.name			= "gpo:trig_net_out",		.gpio			= AT91_PIN_PB20,		.active_low		= 0,		.default_trigger	= "none",		.default_state		= LEDS_GPIO_DEFSTATE_OFF,	},	{		.name			= "gpo:trig_net_dir",		.gpio			= AT91_PIN_PB19,		.active_low		= 0,		.default_trigger	= "none",		.default_state		= LEDS_GPIO_DEFSTATE_OFF,	},	{		.name			= "gpo:charge_dis",		.gpio			= AT91_PIN_PC2,		.active_low		= 0,		.default_trigger	= "none",		.default_state		= LEDS_GPIO_DEFSTATE_OFF,	},	{		.name			= "led:event",		.gpio			= AT91_PIN_PB17,		.active_low		= 1,		.default_trigger	= "none",		.default_state		= LEDS_GPIO_DEFSTATE_OFF,	},	{		.name			= "led:lan",		.gpio			= AT91_PIN_PB18,		.active_low		= 1,		.default_trigger	= "none",		.default_state		= LEDS_GPIO_DEFSTATE_OFF,	},	{		.name			= "led:error",		.gpio			= AT91_PIN_PB16,		.active_low		= 1,		.default_trigger	= "none",		.default_state		= LEDS_GPIO_DEFSTATE_ON,	}};static struct gpio_led_platform_data gpio_led_info = {	.leds		= gpio_leds,	.num_leds	= ARRAY_SIZE(gpio_leds),};static struct platform_device leds = {	.name	= "leds-gpio",	.id	= 0,	.dev	= {		.platform_data	= &gpio_led_info,	}};static void __init gsia18s_leds_init(void){	platform_device_register(&leds);}/* PCF8574 0x20 GPIO - U1 on the GS_IA18-CB_V3 board */static struct gpio_led pcf_gpio_leds1[] = {	{ /* bit 0 */		.name			= "gpo:hdc_power",		.gpio			= PCF_GPIO_HDC_POWER,		.active_low		= 0,		.default_trigger	= "none",		.default_state		= LEDS_GPIO_DEFSTATE_OFF,	},	{ /* bit 1 */		.name			= "gpo:wifi_setup",		.gpio			= PCF_GPIO_WIFI_SETUP,		.active_low		= 1,		.default_trigger	= "none",		.default_state		= LEDS_GPIO_DEFSTATE_OFF,	},	{ /* bit 2 */		.name			= "gpo:wifi_enable",		.gpio			= PCF_GPIO_WIFI_ENABLE,		.active_low		= 1,		.default_trigger	= "none",		.default_state		= LEDS_GPIO_DEFSTATE_OFF,	},	{ /* bit 3	*/		.name			= "gpo:wifi_reset",		.gpio			= PCF_GPIO_WIFI_RESET,		.active_low		= 1,		.default_trigger	= "none",		.default_state		= LEDS_GPIO_DEFSTATE_ON,	},	/* bit 4 used as GPI	*/	{ /* bit 5 */		.name			= "gpo:gps_setup",		.gpio			= PCF_GPIO_GPS_SETUP,		.active_low		= 1,		.default_trigger	= "none",		.default_state		= LEDS_GPIO_DEFSTATE_OFF,	},	{ /* bit 6 */		.name			= "gpo:gps_standby",		.gpio			= PCF_GPIO_GPS_STANDBY,		.active_low		= 0,		.default_trigger	= "none",		.default_state		= LEDS_GPIO_DEFSTATE_ON,	},	{ /* bit 7 */		.name			= "gpo:gps_power",		.gpio			= PCF_GPIO_GPS_POWER,		.active_low		= 0,		.default_trigger	= "none",		.default_state		= LEDS_GPIO_DEFSTATE_OFF,	}};static struct gpio_led_platform_data pcf_gpio_led_info1 = {	.leds		= pcf_gpio_leds1,	.num_leds	= ARRAY_SIZE(pcf_gpio_leds1),};static struct platform_device pcf_leds1 = {	.name	= "leds-gpio", /* GS_IA18-CB_board */	.id	= 1,	.dev	= {		.platform_data	= &pcf_gpio_led_info1,	}};/* PCF8574 0x22 GPIO - U1 on the GS_2G_OPT1-A_V0 board (Alarm) */static struct gpio_led pcf_gpio_leds2[] = {	{ /* bit 0 */		.name			= "gpo:alarm_1",		.gpio			= PCF_GPIO_ALARM1,		.active_low		= 1,		.default_trigger	= "none",		.default_state		= LEDS_GPIO_DEFSTATE_OFF,	},	{ /* bit 1 */		.name			= "gpo:alarm_2",		.gpio			= PCF_GPIO_ALARM2,		.active_low		= 1,		.default_trigger	= "none",		.default_state		= LEDS_GPIO_DEFSTATE_OFF,	},	{ /* bit 2 */		.name			= "gpo:alarm_3",		.gpio			= PCF_GPIO_ALARM3,		.active_low		= 1,		.default_trigger	= "none",		.default_state		= LEDS_GPIO_DEFSTATE_OFF,	},	{ /* bit 3 */		.name			= "gpo:alarm_4",		.gpio			= PCF_GPIO_ALARM4,		.active_low		= 1,		.default_trigger	= "none",		.default_state		= LEDS_GPIO_DEFSTATE_OFF,	},	/* bits 4, 5, 6 not used */	{ /* bit 7 */		.name			= "gpo:alarm_v_relay_on",		.gpio			= PCF_GPIO_ALARM_V_RELAY_ON,		.active_low		= 0,		.default_trigger	= "none",		.default_state		= LEDS_GPIO_DEFSTATE_OFF,	},};static struct gpio_led_platform_data pcf_gpio_led_info2 = {	.leds		= pcf_gpio_leds2,	.num_leds	= ARRAY_SIZE(pcf_gpio_leds2),};static struct platform_device pcf_leds2 = {	.name	= "leds-gpio",	.id	= 2,	.dev	= {		.platform_data	= &pcf_gpio_led_info2,	}};/* PCF8574 0x24 GPIO U1 on the GS_2G-OPT23-A_V0 board (Modem) */static struct gpio_led pcf_gpio_leds3[] = {	{ /* bit 0 */		.name			= "gpo:modem_power",		.gpio			= PCF_GPIO_MODEM_POWER,		.active_low		= 1,		.default_trigger	= "none",		.default_state		= LEDS_GPIO_DEFSTATE_OFF,	},		/* bits 1 and 2 not used */	{ /* bit 3 */		.name			= "gpo:modem_reset",		.gpio			= PCF_GPIO_MODEM_RESET,		.active_low		= 1,		.default_trigger	= "none",		.default_state		= LEDS_GPIO_DEFSTATE_ON,	},		/* bits 4, 5 and 6 not used */	{ /* bit 7 */		.name			= "gpo:trx_reset",		.gpio			= PCF_GPIO_TRX_RESET,		.active_low		= 1,		.default_trigger	= "none",		.default_state		= LEDS_GPIO_DEFSTATE_ON,	}};static struct gpio_led_platform_data pcf_gpio_led_info3 = {	.leds		= pcf_gpio_leds3,	.num_leds	= ARRAY_SIZE(pcf_gpio_leds3),};static struct platform_device pcf_leds3 = {	.name	= "leds-gpio",	.id	= 3,	.dev	= {		.platform_data	= &pcf_gpio_led_info3,	}};static void __init gsia18s_pcf_leds_init(void){	platform_device_register(&pcf_leds1);	platform_device_register(&pcf_leds2);	platform_device_register(&pcf_leds3);}/* * SPI busses. */static struct spi_board_info gsia18s_spi_devices[] = {	{ /* User accessible spi0, cs0 used for communication with MSP RTC */		.modalias	= "spidev",		.bus_num	= 0,		.chip_select	= 0,		.max_speed_hz	= 580000,		.mode		= SPI_MODE_1,	},	{ /* User accessible spi1, cs0 used for communication with int. DSP */		.modalias	= "spidev",		.bus_num	= 1,		.chip_select	= 0,		.max_speed_hz	= 5600000,		.mode		= SPI_MODE_0,	},	{ /* User accessible spi1, cs1 used for communication with ext. DSP */		.modalias	= "spidev",		.bus_num	= 1,		.chip_select	= 1,		.max_speed_hz	= 5600000,		.mode		= SPI_MODE_0,	},	{ /* User accessible spi1, cs2 used for communication with ext. DSP */		.modalias	= "spidev",		.bus_num	= 1,		.chip_select	= 2,		.max_speed_hz	= 5600000,		.mode		= SPI_MODE_0,	},	{ /* User accessible spi1, cs3 used for communication with ext. DSP */		.modalias	= "spidev",		.bus_num	= 1,		.chip_select	= 3,		.max_speed_hz	= 5600000,		.mode		= SPI_MODE_0,	}};/* * GPI Buttons */static struct gpio_keys_button buttons[] = {	{		.gpio		= GPIO_TRIG_NET_IN,		.code		= BTN_1,		.desc		= "TRIG_NET_IN",		.type		= EV_KEY,		.active_low	= 0,		.wakeup		= 1,	},	{ /* SW80 on the GS_IA18_S-MN board*/		.gpio		= GPIO_CARD_UNMOUNT_0,		.code		= BTN_2,		.desc		= "Card umount 0",		.type		= EV_KEY,		.active_low	= 1,		.wakeup		= 1,	},	{ /* SW79 on the GS_IA18_S-MN board*/		.gpio		= GPIO_CARD_UNMOUNT_1,		.code		= BTN_3,		.desc		= "Card umount 1",		.type		= EV_KEY,		.active_low	= 1,		.wakeup		= 1,	},	{ /* SW280 on the GS_IA18-CB board*/		.gpio		= GPIO_KEY_POWER,		.code		= KEY_POWER,		.desc		= "Power Off Button",		.type		= EV_KEY,		.active_low	= 0,		.wakeup		= 1,	}};static struct gpio_keys_platform_data button_data = {	.buttons	= buttons,	.nbuttons	= ARRAY_SIZE(buttons),};static struct platform_device button_device = {	.name		= "gpio-keys",	.id		= -1,	.num_resources	= 0,	.dev		= {		.platform_data	= &button_data,	}};static void __init gsia18s_add_device_buttons(void){	at91_set_gpio_input(GPIO_TRIG_NET_IN, 1);	at91_set_deglitch(GPIO_TRIG_NET_IN, 1);	at91_set_gpio_input(GPIO_CARD_UNMOUNT_0, 1);	at91_set_deglitch(GPIO_CARD_UNMOUNT_0, 1);	at91_set_gpio_input(GPIO_CARD_UNMOUNT_1, 1);	at91_set_deglitch(GPIO_CARD_UNMOUNT_1, 1);	at91_set_gpio_input(GPIO_KEY_POWER, 0);	at91_set_deglitch(GPIO_KEY_POWER, 1);	platform_device_register(&button_device);}/* * I2C */static int pcf8574x_0x20_setup(struct i2c_client *client, int gpio,				unsigned int ngpio, void *context){	int status;	status = gpio_request(gpio + PCF_GPIO_ETH_DETECT, "eth_det");	if (status < 0) {		pr_err("error: can't request GPIO%d\n",			gpio + PCF_GPIO_ETH_DETECT);		return status;	}	status = gpio_direction_input(gpio + PCF_GPIO_ETH_DETECT);	if (status < 0) {		pr_err("error: can't setup GPIO%d as input\n",			gpio + PCF_GPIO_ETH_DETECT);		return status;	}	status = gpio_export(gpio + PCF_GPIO_ETH_DETECT, false);	if (status < 0) {		pr_err("error: can't export GPIO%d\n",			gpio + PCF_GPIO_ETH_DETECT);		return status;	}	status = gpio_sysfs_set_active_low(gpio + PCF_GPIO_ETH_DETECT, 1);	if (status < 0) {		pr_err("error: gpio_sysfs_set active_low(GPIO%d, 1)\n",			gpio + PCF_GPIO_ETH_DETECT);		return status;	}	return 0;}static int pcf8574x_0x20_teardown(struct i2c_client *client, int gpio,					unsigned ngpio, void *context){	gpio_free(gpio + PCF_GPIO_ETH_DETECT);	return 0;}static struct pcf857x_platform_data pcf20_pdata = {	.gpio_base	= GS_IA18_S_PCF_GPIO_BASE0,	.n_latch	= (1 << 4),	.setup		= pcf8574x_0x20_setup,	.teardown	= pcf8574x_0x20_teardown,};static struct pcf857x_platform_data pcf22_pdata = {	.gpio_base	= GS_IA18_S_PCF_GPIO_BASE1,};static struct pcf857x_platform_data pcf24_pdata = {	.gpio_base	= GS_IA18_S_PCF_GPIO_BASE2,};static struct i2c_board_info __initdata gsia18s_i2c_devices[] = {	{ /* U1 on the GS_IA18-CB_V3 board */		I2C_BOARD_INFO("pcf8574", 0x20),		.platform_data = &pcf20_pdata,	},	{ /* U1 on the GS_2G_OPT1-A_V0 board (Alarm) */		I2C_BOARD_INFO("pcf8574", 0x22),		.platform_data = &pcf22_pdata,	},	{ /* U1 on the GS_2G-OPT23-A_V0 board (Modem) */		I2C_BOARD_INFO("pcf8574", 0x24),		.platform_data = &pcf24_pdata,	},	{ /* U161 on the GS_IA18_S-MN board */		I2C_BOARD_INFO("24c1024", 0x50),	},	{ /* U162 on the GS_IA18_S-MN board */		I2C_BOARD_INFO("24c01", 0x53),	},};/* * Compact Flash */static struct at91_cf_data __initdata gsia18s_cf1_data = {	.irq_pin	= AT91_PIN_PA27,	.det_pin	= AT91_PIN_PB30,	.vcc_pin	= -EINVAL,	.rst_pin	= AT91_PIN_PB31,	.chipselect	= 5,	.flags		= AT91_CF_TRUE_IDE,
 |