linux/arch/arm/mach-at91/board-gsia18s.c
<<
>>
Prefs
   1/*
   2 *  Copyright (C) 2010 Christian Glindkamp <christian.glindkamp@taskit.de>
   3 *                     taskit GmbH
   4 *                2010 Igor Plyatov <plyatov@gmail.com>
   5 *                     GeoSIG Ltd
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License as published by
   9 * the Free Software Foundation; either version 2 of the License, or
  10 * (at your option) any later version.
  11 *
  12 * This program is distributed in the hope that it will be useful,
  13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15 * GNU General Public License for more details.
  16 *
  17 * You should have received a copy of the GNU General Public License
  18 * along with this program; if not, write to the Free Software
  19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  20 */
  21
  22#include <linux/platform_device.h>
  23#include <linux/gpio.h>
  24#include <linux/w1-gpio.h>
  25#include <linux/i2c.h>
  26#include <linux/i2c/pcf857x.h>
  27#include <linux/gpio_keys.h>
  28#include <linux/input.h>
  29
  30#include <asm/mach-types.h>
  31#include <asm/mach/arch.h>
  32
  33#include <mach/board.h>
  34#include <mach/at91sam9_smc.h>
  35#include <mach/gsia18s.h>
  36#include <mach/stamp9g20.h>
  37
  38#include "sam9_smc.h"
  39#include "generic.h"
  40
  41static void __init gsia18s_map_io(void)
  42{
  43        stamp9g20_map_io();
  44
  45        /*
  46         * USART0 on ttyS1 (Rx, Tx, CTS, RTS, DTR, DSR, DCD, RI).
  47         * Used for Internal Analog Modem.
  48         */
  49        at91_register_uart(AT91SAM9260_ID_US0, 1,
  50                                ATMEL_UART_CTS | ATMEL_UART_RTS |
  51                                ATMEL_UART_DTR | ATMEL_UART_DSR |
  52                                ATMEL_UART_DCD | ATMEL_UART_RI);
  53        /*
  54         * USART1 on ttyS2 (Rx, Tx, CTS, RTS).
  55         * Used for GPS or WiFi or Data stream.
  56         */
  57        at91_register_uart(AT91SAM9260_ID_US1, 2,
  58                                ATMEL_UART_CTS | ATMEL_UART_RTS);
  59        /*
  60         * USART2 on ttyS3 (Rx, Tx, CTS, RTS).
  61         * Used for External Modem.
  62         */
  63        at91_register_uart(AT91SAM9260_ID_US2, 3,
  64                                ATMEL_UART_CTS | ATMEL_UART_RTS);
  65        /*
  66         * USART3 on ttyS4 (Rx, Tx, RTS).
  67         * Used for RS-485.
  68         */
  69        at91_register_uart(AT91SAM9260_ID_US3, 4, ATMEL_UART_RTS);
  70
  71        /*
  72         * USART4 on ttyS5 (Rx, Tx).
  73         * Used for TRX433 Radio Module.
  74         */
  75        at91_register_uart(AT91SAM9260_ID_US4, 5, 0);
  76}
  77
  78static void __init init_irq(void)
  79{
  80        at91sam9260_init_interrupts(NULL);
  81}
  82
  83/*
  84 * Two USB Host ports
  85 */
  86static struct at91_usbh_data __initdata usbh_data = {
  87        .ports          = 2,
  88};
  89
  90/*
  91 * USB Device port
  92 */
  93static struct at91_udc_data __initdata udc_data = {
  94        .vbus_pin       = AT91_PIN_PA22,
  95        .pullup_pin     = 0,            /* pull-up driven by UDC */
  96};
  97
  98/*
  99 * MACB Ethernet device
 100 */
 101static struct at91_eth_data __initdata macb_data = {
 102        .phy_irq_pin    = AT91_PIN_PA28,
 103        .is_rmii        = 1,
 104};
 105
 106/*
 107 * LEDs and GPOs
 108 */
 109static struct gpio_led gpio_leds[] = {
 110        {
 111                .name                   = "gpo:spi1reset",
 112                .gpio                   = AT91_PIN_PC1,
 113                .active_low             = 0,
 114                .default_trigger        = "none",
 115                .default_state          = LEDS_GPIO_DEFSTATE_OFF,
 116        },
 117        {
 118                .name                   = "gpo:trig_net_out",
 119                .gpio                   = AT91_PIN_PB20,
 120                .active_low             = 0,
 121                .default_trigger        = "none",
 122                .default_state          = LEDS_GPIO_DEFSTATE_OFF,
 123        },
 124        {
 125                .name                   = "gpo:trig_net_dir",
 126                .gpio                   = AT91_PIN_PB19,
 127                .active_low             = 0,
 128                .default_trigger        = "none",
 129                .default_state          = LEDS_GPIO_DEFSTATE_OFF,
 130        },
 131        {
 132                .name                   = "gpo:charge_dis",
 133                .gpio                   = AT91_PIN_PC2,
 134                .active_low             = 0,
 135                .default_trigger        = "none",
 136                .default_state          = LEDS_GPIO_DEFSTATE_OFF,
 137        },
 138        {
 139                .name                   = "led:event",
 140                .gpio                   = AT91_PIN_PB17,
 141                .active_low             = 1,
 142                .default_trigger        = "none",
 143                .default_state          = LEDS_GPIO_DEFSTATE_OFF,
 144        },
 145        {
 146                .name                   = "led:lan",
 147                .gpio                   = AT91_PIN_PB18,
 148                .active_low             = 1,
 149                .default_trigger        = "none",
 150                .default_state          = LEDS_GPIO_DEFSTATE_OFF,
 151        },
 152        {
 153                .name                   = "led:error",
 154                .gpio                   = AT91_PIN_PB16,
 155                .active_low             = 1,
 156                .default_trigger        = "none",
 157                .default_state          = LEDS_GPIO_DEFSTATE_ON,
 158        }
 159};
 160
 161static struct gpio_led_platform_data gpio_led_info = {
 162        .leds           = gpio_leds,
 163        .num_leds       = ARRAY_SIZE(gpio_leds),
 164};
 165
 166static struct platform_device leds = {
 167        .name   = "leds-gpio",
 168        .id     = 0,
 169        .dev    = {
 170                .platform_data  = &gpio_led_info,
 171        }
 172};
 173
 174static void __init gsia18s_leds_init(void)
 175{
 176        platform_device_register(&leds);
 177}
 178
 179/* PCF8574 0x20 GPIO - U1 on the GS_IA18-CB_V3 board */
 180static struct gpio_led pcf_gpio_leds1[] = {
 181        { /* bit 0 */
 182                .name                   = "gpo:hdc_power",
 183                .gpio                   = PCF_GPIO_HDC_POWER,
 184                .active_low             = 0,
 185                .default_trigger        = "none",
 186                .default_state          = LEDS_GPIO_DEFSTATE_OFF,
 187        },
 188        { /* bit 1 */
 189                .name                   = "gpo:wifi_setup",
 190                .gpio                   = PCF_GPIO_WIFI_SETUP,
 191                .active_low             = 1,
 192                .default_trigger        = "none",
 193                .default_state          = LEDS_GPIO_DEFSTATE_OFF,
 194        },
 195        { /* bit 2 */
 196                .name                   = "gpo:wifi_enable",
 197                .gpio                   = PCF_GPIO_WIFI_ENABLE,
 198                .active_low             = 1,
 199                .default_trigger        = "none",
 200                .default_state          = LEDS_GPIO_DEFSTATE_OFF,
 201        },
 202        { /* bit 3      */
 203                .name                   = "gpo:wifi_reset",
 204                .gpio                   = PCF_GPIO_WIFI_RESET,
 205                .active_low             = 1,
 206                .default_trigger        = "none",
 207                .default_state          = LEDS_GPIO_DEFSTATE_ON,
 208        },
 209        /* bit 4 used as GPI    */
 210        { /* bit 5 */
 211                .name                   = "gpo:gps_setup",
 212                .gpio                   = PCF_GPIO_GPS_SETUP,
 213                .active_low             = 1,
 214                .default_trigger        = "none",
 215                .default_state          = LEDS_GPIO_DEFSTATE_OFF,
 216        },
 217        { /* bit 6 */
 218                .name                   = "gpo:gps_standby",
 219                .gpio                   = PCF_GPIO_GPS_STANDBY,
 220                .active_low             = 0,
 221                .default_trigger        = "none",
 222                .default_state          = LEDS_GPIO_DEFSTATE_ON,
 223        },
 224        { /* bit 7 */
 225                .name                   = "gpo:gps_power",
 226                .gpio                   = PCF_GPIO_GPS_POWER,
 227                .active_low             = 0,
 228                .default_trigger        = "none",
 229                .default_state          = LEDS_GPIO_DEFSTATE_OFF,
 230        }
 231};
 232
 233static struct gpio_led_platform_data pcf_gpio_led_info1 = {
 234        .leds           = pcf_gpio_leds1,
 235        .num_leds       = ARRAY_SIZE(pcf_gpio_leds1),
 236};
 237
 238static struct platform_device pcf_leds1 = {
 239        .name   = "leds-gpio", /* GS_IA18-CB_board */
 240        .id     = 1,
 241        .dev    = {
 242                .platform_data  = &pcf_gpio_led_info1,
 243        }
 244};
 245
 246/* PCF8574 0x22 GPIO - U1 on the GS_2G_OPT1-A_V0 board (Alarm) */
 247static struct gpio_led pcf_gpio_leds2[] = {
 248        { /* bit 0 */
 249                .name                   = "gpo:alarm_1",
 250                .gpio                   = PCF_GPIO_ALARM1,
 251                .active_low             = 1,
 252                .default_trigger        = "none",
 253                .default_state          = LEDS_GPIO_DEFSTATE_OFF,
 254        },
 255        { /* bit 1 */
 256                .name                   = "gpo:alarm_2",
 257                .gpio                   = PCF_GPIO_ALARM2,
 258                .active_low             = 1,
 259                .default_trigger        = "none",
 260                .default_state          = LEDS_GPIO_DEFSTATE_OFF,
 261        },
 262        { /* bit 2 */
 263                .name                   = "gpo:alarm_3",
 264                .gpio                   = PCF_GPIO_ALARM3,
 265                .active_low             = 1,
 266                .default_trigger        = "none",
 267                .default_state          = LEDS_GPIO_DEFSTATE_OFF,
 268        },
 269        { /* bit 3 */
 270                .name                   = "gpo:alarm_4",
 271                .gpio                   = PCF_GPIO_ALARM4,
 272                .active_low             = 1,
 273                .default_trigger        = "none",
 274                .default_state          = LEDS_GPIO_DEFSTATE_OFF,
 275        },
 276        /* bits 4, 5, 6 not used */
 277        { /* bit 7 */
 278                .name                   = "gpo:alarm_v_relay_on",
 279                .gpio                   = PCF_GPIO_ALARM_V_RELAY_ON,
 280                .active_low             = 0,
 281                .default_trigger        = "none",
 282                .default_state          = LEDS_GPIO_DEFSTATE_OFF,
 283        },
 284};
 285
 286static struct gpio_led_platform_data pcf_gpio_led_info2 = {
 287        .leds           = pcf_gpio_leds2,
 288        .num_leds       = ARRAY_SIZE(pcf_gpio_leds2),
 289};
 290
 291static struct platform_device pcf_leds2 = {
 292        .name   = "leds-gpio",
 293        .id     = 2,
 294        .dev    = {
 295                .platform_data  = &pcf_gpio_led_info2,
 296        }
 297};
 298
 299/* PCF8574 0x24 GPIO U1 on the GS_2G-OPT23-A_V0 board (Modem) */
 300static struct gpio_led pcf_gpio_leds3[] = {
 301        { /* bit 0 */
 302                .name                   = "gpo:modem_power",
 303                .gpio                   = PCF_GPIO_MODEM_POWER,
 304                .active_low             = 1,
 305                .default_trigger        = "none",
 306                .default_state          = LEDS_GPIO_DEFSTATE_OFF,
 307        },
 308                /* bits 1 and 2 not used */
 309        { /* bit 3 */
 310                .name                   = "gpo:modem_reset",
 311                .gpio                   = PCF_GPIO_MODEM_RESET,
 312                .active_low             = 1,
 313                .default_trigger        = "none",
 314                .default_state          = LEDS_GPIO_DEFSTATE_ON,
 315        },
 316                /* bits 4, 5 and 6 not used */
 317        { /* bit 7 */
 318                .name                   = "gpo:trx_reset",
 319                .gpio                   = PCF_GPIO_TRX_RESET,
 320                .active_low             = 1,
 321                .default_trigger        = "none",
 322                .default_state          = LEDS_GPIO_DEFSTATE_ON,
 323        }
 324};
 325
 326static struct gpio_led_platform_data pcf_gpio_led_info3 = {
 327        .leds           = pcf_gpio_leds3,
 328        .num_leds       = ARRAY_SIZE(pcf_gpio_leds3),
 329};
 330
 331static struct platform_device pcf_leds3 = {
 332        .name   = "leds-gpio",
 333        .id     = 3,
 334        .dev    = {
 335                .platform_data  = &pcf_gpio_led_info3,
 336        }
 337};
 338
 339static void __init gsia18s_pcf_leds_init(void)
 340{
 341        platform_device_register(&pcf_leds1);
 342        platform_device_register(&pcf_leds2);
 343        platform_device_register(&pcf_leds3);
 344}
 345
 346/*
 347 * SPI busses.
 348 */
 349static struct spi_board_info gsia18s_spi_devices[] = {
 350        { /* User accessible spi0, cs0 used for communication with MSP RTC */
 351                .modalias       = "spidev",
 352                .bus_num        = 0,
 353                .chip_select    = 0,
 354                .max_speed_hz   = 580000,
 355                .mode           = SPI_MODE_1,
 356        },
 357        { /* User accessible spi1, cs0 used for communication with int. DSP */
 358                .modalias       = "spidev",
 359                .bus_num        = 1,
 360                .chip_select    = 0,
 361                .max_speed_hz   = 5600000,
 362                .mode           = SPI_MODE_0,
 363        },
 364        { /* User accessible spi1, cs1 used for communication with ext. DSP */
 365                .modalias       = "spidev",
 366                .bus_num        = 1,
 367                .chip_select    = 1,
 368                .max_speed_hz   = 5600000,
 369                .mode           = SPI_MODE_0,
 370        },
 371        { /* User accessible spi1, cs2 used for communication with ext. DSP */
 372                .modalias       = "spidev",
 373                .bus_num        = 1,
 374                .chip_select    = 2,
 375                .max_speed_hz   = 5600000,
 376                .mode           = SPI_MODE_0,
 377        },
 378        { /* User accessible spi1, cs3 used for communication with ext. DSP */
 379                .modalias       = "spidev",
 380                .bus_num        = 1,
 381                .chip_select    = 3,
 382                .max_speed_hz   = 5600000,
 383                .mode           = SPI_MODE_0,
 384        }
 385};
 386
 387/*
 388 * GPI Buttons
 389 */
 390static struct gpio_keys_button buttons[] = {
 391        {
 392                .gpio           = GPIO_TRIG_NET_IN,
 393                .code           = BTN_1,
 394                .desc           = "TRIG_NET_IN",
 395                .type           = EV_KEY,
 396                .active_low     = 0,
 397                .wakeup         = 1,
 398        },
 399        { /* SW80 on the GS_IA18_S-MN board*/
 400                .gpio           = GPIO_CARD_UNMOUNT_0,
 401                .code           = BTN_2,
 402                .desc           = "Card umount 0",
 403                .type           = EV_KEY,
 404                .active_low     = 1,
 405                .wakeup         = 1,
 406        },
 407        { /* SW79 on the GS_IA18_S-MN board*/
 408                .gpio           = GPIO_CARD_UNMOUNT_1,
 409                .code           = BTN_3,
 410                .desc           = "Card umount 1",
 411                .type           = EV_KEY,
 412                .active_low     = 1,
 413                .wakeup         = 1,
 414        },
 415        { /* SW280 on the GS_IA18-CB board*/
 416                .gpio           = GPIO_KEY_POWER,
 417                .code           = KEY_POWER,
 418                .desc           = "Power Off Button",
 419                .type           = EV_KEY,
 420                .active_low     = 0,
 421                .wakeup         = 1,
 422        }
 423};
 424
 425static struct gpio_keys_platform_data button_data = {
 426        .buttons        = buttons,
 427        .nbuttons       = ARRAY_SIZE(buttons),
 428};
 429
 430static struct platform_device button_device = {
 431        .name           = "gpio-keys",
 432        .id             = -1,
 433        .num_resources  = 0,
 434        .dev            = {
 435                .platform_data  = &button_data,
 436        }
 437};
 438
 439static void __init gsia18s_add_device_buttons(void)
 440{
 441        at91_set_gpio_input(GPIO_TRIG_NET_IN, 1);
 442        at91_set_deglitch(GPIO_TRIG_NET_IN, 1);
 443        at91_set_gpio_input(GPIO_CARD_UNMOUNT_0, 1);
 444        at91_set_deglitch(GPIO_CARD_UNMOUNT_0, 1);
 445        at91_set_gpio_input(GPIO_CARD_UNMOUNT_1, 1);
 446        at91_set_deglitch(GPIO_CARD_UNMOUNT_1, 1);
 447        at91_set_gpio_input(GPIO_KEY_POWER, 0);
 448        at91_set_deglitch(GPIO_KEY_POWER, 1);
 449
 450        platform_device_register(&button_device);
 451}
 452
 453/*
 454 * I2C
 455 */
 456static int pcf8574x_0x20_setup(struct i2c_client *client, int gpio,
 457                                unsigned int ngpio, void *context)
 458{
 459        int status;
 460
 461        status = gpio_request(gpio + PCF_GPIO_ETH_DETECT, "eth_det");
 462        if (status < 0) {
 463                pr_err("error: can't request GPIO%d\n",
 464                        gpio + PCF_GPIO_ETH_DETECT);
 465                return status;
 466        }
 467        status = gpio_direction_input(gpio + PCF_GPIO_ETH_DETECT);
 468        if (status < 0) {
 469                pr_err("error: can't setup GPIO%d as input\n",
 470                        gpio + PCF_GPIO_ETH_DETECT);
 471                return status;
 472        }
 473        status = gpio_export(gpio + PCF_GPIO_ETH_DETECT, false);
 474        if (status < 0) {
 475                pr_err("error: can't export GPIO%d\n",
 476                        gpio + PCF_GPIO_ETH_DETECT);
 477                return status;
 478        }
 479        status = gpio_sysfs_set_active_low(gpio + PCF_GPIO_ETH_DETECT, 1);
 480        if (status < 0) {
 481                pr_err("error: gpio_sysfs_set active_low(GPIO%d, 1)\n",
 482                        gpio + PCF_GPIO_ETH_DETECT);
 483                return status;
 484        }
 485
 486        return 0;
 487}
 488
 489static int pcf8574x_0x20_teardown(struct i2c_client *client, int gpio,
 490                                        unsigned ngpio, void *context)
 491{
 492        gpio_free(gpio + PCF_GPIO_ETH_DETECT);
 493        return 0;
 494}
 495
 496static struct pcf857x_platform_data pcf20_pdata = {
 497        .gpio_base      = GS_IA18_S_PCF_GPIO_BASE0,
 498        .n_latch        = (1 << 4),
 499        .setup          = pcf8574x_0x20_setup,
 500        .teardown       = pcf8574x_0x20_teardown,
 501};
 502
 503static struct pcf857x_platform_data pcf22_pdata = {
 504        .gpio_base      = GS_IA18_S_PCF_GPIO_BASE1,
 505};
 506
 507static struct pcf857x_platform_data pcf24_pdata = {
 508        .gpio_base      = GS_IA18_S_PCF_GPIO_BASE2,
 509};
 510
 511static struct i2c_board_info __initdata gsia18s_i2c_devices[] = {
 512        { /* U1 on the GS_IA18-CB_V3 board */
 513                I2C_BOARD_INFO("pcf8574", 0x20),
 514                .platform_data = &pcf20_pdata,
 515        },
 516        { /* U1 on the GS_2G_OPT1-A_V0 board (Alarm) */
 517                I2C_BOARD_INFO("pcf8574", 0x22),
 518                .platform_data = &pcf22_pdata,
 519        },
 520        { /* U1 on the GS_2G-OPT23-A_V0 board (Modem) */
 521                I2C_BOARD_INFO("pcf8574", 0x24),
 522                .platform_data = &pcf24_pdata,
 523        },
 524        { /* U161 on the GS_IA18_S-MN board */
 525                I2C_BOARD_INFO("24c1024", 0x50),
 526        },
 527        { /* U162 on the GS_IA18_S-MN board */
 528                I2C_BOARD_INFO("24c01", 0x53),
 529        },
 530};
 531
 532/*
 533 * Compact Flash
 534 */
 535static struct at91_cf_data __initdata gsia18s_cf1_data = {
 536        .irq_pin        = AT91_PIN_PA27,
 537        .det_pin        = AT91_PIN_PB30,
 538        .rst_pin        = AT91_PIN_PB31,
 539        .chipselect     = 5,
 540        .flags          = AT91_CF_TRUE_IDE,
 541};
 542
 543/* Power Off by RTC */
 544static void gsia18s_power_off(void)
 545{
 546        pr_notice("Power supply will be switched off automatically now or after 60 seconds without ArmDAS.\n");
 547        at91_set_gpio_output(AT91_PIN_PA25, 1);
 548        /* Spin to death... */
 549        while (1)
 550                ;
 551}
 552
 553static int __init gsia18s_power_off_init(void)
 554{
 555        pm_power_off = gsia18s_power_off;
 556        return 0;
 557}
 558
 559/* ---------------------------------------------------------------------------*/
 560
 561static void __init gsia18s_board_init(void)
 562{
 563        stamp9g20_board_init();
 564        at91_add_device_usbh(&usbh_data);
 565        at91_add_device_udc(&udc_data);
 566        at91_add_device_eth(&macb_data);
 567        gsia18s_leds_init();
 568        gsia18s_pcf_leds_init();
 569        gsia18s_add_device_buttons();
 570        at91_add_device_i2c(gsia18s_i2c_devices,
 571                                ARRAY_SIZE(gsia18s_i2c_devices));
 572        at91_add_device_cf(&gsia18s_cf1_data);
 573        at91_add_device_spi(gsia18s_spi_devices,
 574                                ARRAY_SIZE(gsia18s_spi_devices));
 575        gsia18s_power_off_init();
 576}
 577
 578MACHINE_START(GSIA18S, "GS_IA18_S")
 579        .boot_params    = AT91_SDRAM_BASE + 0x100,
 580        .timer          = &at91sam926x_timer,
 581        .map_io         = gsia18s_map_io,
 582        .init_irq       = init_irq,
 583        .init_machine   = gsia18s_board_init,
 584MACHINE_END
 585