[ARM] tegra: stingray: Initial stingray board files
authorColin Cross <ccross@android.com>
Thu, 13 May 2010 20:51:58 +0000 (13:51 -0700)
committerColin Cross <ccross@android.com>
Wed, 6 Oct 2010 23:32:54 +0000 (16:32 -0700)
Change-Id: I644ea9bfe0d256fadfac6e129c9d64cae7982c0b
Signed-off-by: Colin Cross <ccross@android.com>
arch/arm/mach-tegra/Kconfig
arch/arm/mach-tegra/Makefile
arch/arm/mach-tegra/board-stingray-i2c.c [new file with mode: 0644]
arch/arm/mach-tegra/board-stingray-keypad.c [new file with mode: 0644]
arch/arm/mach-tegra/board-stingray-panel.c [new file with mode: 0644]
arch/arm/mach-tegra/board-stingray-pinmux.c [new file with mode: 0644]
arch/arm/mach-tegra/board-stingray-wifi.c [new file with mode: 0644]
arch/arm/mach-tegra/board-stingray.c [new file with mode: 0644]
arch/arm/mach-tegra/board-stingray.h [new file with mode: 0644]

index 2490112b5e6b360d837283f161757c539a90e3d1..c911cb30473a6b621579500b1af949a6d245b104 100644 (file)
@@ -36,6 +36,12 @@ config MACH_OLYMPUS
        help
         Support for Olympus development platform
 
+config MACH_STINGRAY
+       bool "Stingray board"
+       select TEGRA_DEBUG_UARTB
+       help
+        Support for Stingray development platform
+
 choice
         prompt "Low-level debug console UART"
         default TEGRA_DEBUG_UART_NONE
index 9d17111912c04223a2ca03b536866fd0e2756b3d..b3d839ffcdb38e64abd135fc61187cd3b00a6dd6 100644 (file)
@@ -50,3 +50,10 @@ obj-${CONFIG_MACH_OLYMPUS}              += board-olympus-panel.o
 obj-${CONFIG_MACH_OLYMPUS}              += board-olympus-i2c.o
 obj-${CONFIG_MACH_OLYMPUS}              += board-olympus-keypad.o
 obj-${CONFIG_MACH_OLYMPUS}              += board-olympus-wifi.o
+
+obj-${CONFIG_MACH_STINGRAY}             += board-stingray.o
+obj-${CONFIG_MACH_STINGRAY}             += board-stingray-pinmux.o
+obj-${CONFIG_MACH_STINGRAY}             += board-stingray-panel.o
+obj-${CONFIG_MACH_STINGRAY}             += board-stingray-i2c.o
+obj-${CONFIG_MACH_STINGRAY}             += board-stingray-keypad.o
+obj-${CONFIG_MACH_STINGRAY}             += board-stingray-wifi.o
diff --git a/arch/arm/mach-tegra/board-stingray-i2c.c b/arch/arm/mach-tegra/board-stingray-i2c.c
new file mode 100644 (file)
index 0000000..53e527a
--- /dev/null
@@ -0,0 +1,222 @@
+/*
+ * arch/arm/mach-tegra/board-stingray-i2c.c
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/resource.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/i2c.h>
+#include <asm/mach-types.h>
+#include <mach/irqs.h>
+#include <mach/iomap.h>
+#include <mach/pinmux.h>
+#include <linux/qtouch_obp_ts.h>
+#include <linux/interrupt.h>
+#include <linux/input.h>
+#include "gpio-names.h"
+
+#define STINGRAY_TOUCH_IRQ_GPIO TEGRA_GPIO_PF5
+#define STINGRAY_COMPASS_IRQ_GPIO TEGRA_GPIO_PE2
+
+static int sholes_touch_reset(void)
+{
+       return 0;
+}
+
+static struct vkey sholes_touch_vkeys[] = {
+       {
+               .code           = KEY_BACK,
+       },
+       {
+               .code           = KEY_MENU,
+       },
+       {
+               .code           = KEY_HOME,
+       },
+       {
+               .code           = KEY_SEARCH,
+       },
+};
+
+static struct qtm_touch_keyarray_cfg sholes_key_array_data[] = {
+       {
+               .ctrl = 0,
+               .x_origin = 0,
+               .y_origin = 0,
+               .x_size = 0,
+               .y_size = 0,
+               .aks_cfg = 0,
+               .burst_len = 0,
+               .tch_det_thr = 0,
+               .tch_det_int = 0,
+               .rsvd1 = 0,
+               .rsvd2 = 0,
+       },
+       {
+               .ctrl = 0,
+               .x_origin = 0,
+               .y_origin = 0,
+               .x_size = 0,
+               .y_size = 0,
+               .aks_cfg = 0,
+               .burst_len = 0,
+               .tch_det_thr = 0,
+               .tch_det_int = 0,
+               .rsvd1 = 0,
+               .rsvd2 = 0,
+       },
+};
+
+static struct qtouch_ts_platform_data sholes_ts_platform_data = {
+       .irqflags       = IRQF_TRIGGER_LOW,
+       .flags          = (QTOUCH_SWAP_XY |
+                          QTOUCH_FLIP_X |
+                          QTOUCH_USE_MULTITOUCH |
+                          QTOUCH_CFG_BACKUPNV |
+                          QTOUCH_EEPROM_CHECKSUM),
+       .abs_min_x      = 0,
+       .abs_max_x      = 1024,
+       .abs_min_y      = 0,
+       .abs_max_y      = 1024,
+       .abs_min_p      = 0,
+       .abs_max_p      = 255,
+       .abs_min_w      = 0,
+       .abs_max_w      = 15,
+       .x_delta        = 400,
+       .y_delta        = 250,
+       .nv_checksum    = 0xfaf5,
+       .fuzz_x         = 0,
+       .fuzz_y         = 0,
+       .fuzz_p         = 2,
+       .fuzz_w         = 2,
+       .hw_reset       = sholes_touch_reset,
+       .power_cfg      = {
+               .idle_acq_int   = 0xff,
+               .active_acq_int = 0xff,
+               .active_idle_to = 0x01,
+       },
+       .acquire_cfg    = {
+               .charge_time    = 12,
+               .atouch_drift   = 5,
+               .touch_drift    = 20,
+               .drift_susp     = 20,
+               .touch_autocal  = 0x96,
+               .sync           = 0,
+       },
+       .multi_touch_cfg        = {
+               .ctrl           = 0x0b,
+               .x_origin       = 0,
+               .y_origin       = 0,
+               .x_size         = 19,
+               .y_size         = 11,
+               .aks_cfg        = 0,
+               .burst_len      = 0x40,
+               .tch_det_thr    = 0x12,
+               .tch_det_int    = 0x2,
+               .mov_hyst_init  = 0xe,
+               .mov_hyst_next  = 0xe,
+               .mov_filter     = 0x9,
+               .num_touch      = 2,
+               .merge_hyst     = 0,
+               .merge_thresh   = 3,
+               .amp_hyst = 2,
+                .x_res = 0x0000,
+                .y_res = 0x0000,
+                .x_low_clip = 0x00,
+                .x_high_clip = 0x00,
+                .y_low_clip = 0x00,
+                .y_high_clip = 0x00,
+       },
+    .linear_tbl_cfg = {
+                 .ctrl = 0x01,
+                 .x_offset = 0x0000,
+                 .x_segment = {
+                         0x48, 0x3f, 0x3c, 0x3E,
+                         0x3f, 0x3e, 0x3e, 0x3e,
+                         0x3f, 0x42, 0x41, 0x3f,
+                         0x41, 0x40, 0x41, 0x46
+                 },
+                 .y_offset = 0x0000,
+                 .y_segment = {
+                         0x44, 0x38, 0x37, 0x3e,
+                         0x3e, 0x41, 0x41, 0x3f,
+                         0x42, 0x41, 0x42, 0x42,
+                         0x41, 0x3f, 0x41, 0x45
+                 },
+         },
+       .grip_suppression_cfg = {
+               .ctrl           = 0x00,
+               .xlogrip        = 0x00,
+               .xhigrip        = 0x00,
+               .ylogrip        = 0x00,
+               .yhigrip        = 0x00,
+               .maxtchs        = 0x00,
+               .reserve0   = 0x00,
+               .szthr1 = 0x00,
+               .szthr2 = 0x00,
+               .shpthr1        = 0x00,
+               .shpthr2        = 0x00,
+       },
+       .noise1_suppression_cfg = {
+               .ctrl = 0x01,
+               .reserved = 0x01,
+               .atchthr = 0x64,
+               .duty_cycle = 0x08,
+       },
+       .key_array      = {
+               .cfg            = sholes_key_array_data,
+               .num_keys   = ARRAY_SIZE(sholes_key_array_data),
+       },
+       .vkeys                  = {
+               .keys           = sholes_touch_vkeys,
+               .count          = ARRAY_SIZE(sholes_touch_vkeys),
+               .start          = 961,
+       },
+};
+
+static struct i2c_board_info __initdata sholes_i2c_bus1_board_info[] = {
+       {
+               I2C_BOARD_INFO(QTOUCH_TS_NAME, 0x4a),
+               .platform_data = &sholes_ts_platform_data,
+               .irq = TEGRA_GPIO_TO_IRQ(STINGRAY_TOUCH_IRQ_GPIO),
+       },
+};
+
+static struct i2c_board_info __initdata stingray_i2c_bus4_board_info[] = {
+        {
+                I2C_BOARD_INFO("akm8973", 0x0C),
+                .irq = TEGRA_GPIO_TO_IRQ(STINGRAY_COMPASS_IRQ_GPIO),
+        },
+};
+
+static int __init stingray_init_i2c(void)
+{
+       if (!machine_is_stingray())
+               return 0;
+
+       tegra_gpio_enable(STINGRAY_TOUCH_IRQ_GPIO);
+       gpio_request(STINGRAY_TOUCH_IRQ_GPIO, "touch_irq");
+       gpio_direction_input(STINGRAY_TOUCH_IRQ_GPIO);
+
+       i2c_register_board_info(0, sholes_i2c_bus1_board_info, 1);
+
+       i2c_register_board_info(3, stingray_i2c_bus4_board_info, 1);
+
+       return 0;
+}
+
+device_initcall(stingray_init_i2c);
+
diff --git a/arch/arm/mach-tegra/board-stingray-keypad.c b/arch/arm/mach-tegra/board-stingray-keypad.c
new file mode 100644 (file)
index 0000000..45df99c
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * arch/arm/mach-tegra/board-stingray-keypad.c
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/gpio_event.h>
+#include <linux/keyreset.h>
+#include <linux/gpio.h>
+#include "gpio-names.h"
+
+static unsigned int tegra_row_gpios[] = {
+       TEGRA_GPIO_PR0,
+       TEGRA_GPIO_PR1,
+       TEGRA_GPIO_PR2
+};
+static unsigned int tegra_col_gpios[] = {
+       TEGRA_GPIO_PQ0,
+       TEGRA_GPIO_PQ1,
+       TEGRA_GPIO_PQ2
+};
+
+#define KEYMAP_INDEX(col, row) ((col)*ARRAY_SIZE(tegra_row_gpios) + (row))
+
+static const unsigned short tegra_p3_keymap[ARRAY_SIZE(tegra_col_gpios) *
+                                            ARRAY_SIZE(tegra_row_gpios)] = {
+       [KEYMAP_INDEX(0, 0)] = KEY_VOLUMEUP,
+       [KEYMAP_INDEX(1, 0)] = KEY_CAMERA_FOCUS,
+       [KEYMAP_INDEX(2, 0)] = KEY_MENU,
+       [KEYMAP_INDEX(0, 1)] = KEY_VOLUMEDOWN,
+       [KEYMAP_INDEX(1, 1)] = KEY_CAMERA,
+       [KEYMAP_INDEX(2, 1)] = KEY_HOME,
+       [KEYMAP_INDEX(0, 2)] = KEY_AUX,
+       [KEYMAP_INDEX(1, 2)] = KEY_SEARCH,
+       [KEYMAP_INDEX(2, 2)] = KEY_BACK,
+};
+
+static struct gpio_event_matrix_info tegra_keypad_matrix_info = {
+       .info.func = gpio_event_matrix_func,
+       .keymap = tegra_p3_keymap,
+       .output_gpios = tegra_col_gpios,
+       .input_gpios = tegra_row_gpios,
+       .noutputs = ARRAY_SIZE(tegra_col_gpios),
+       .ninputs = ARRAY_SIZE(tegra_row_gpios),
+       .settle_time.tv.nsec = 40 * NSEC_PER_USEC,
+       .poll_time.tv.nsec = 20 * NSEC_PER_MSEC,
+       .flags = GPIOKPF_LEVEL_TRIGGERED_IRQ | GPIOKPF_REMOVE_PHANTOM_KEYS |
+                GPIOKPF_PRINT_UNMAPPED_KEYS /*| GPIOKPF_PRINT_MAPPED_KEYS*/
+};
+
+static struct gpio_event_direct_entry tegra_keypad_switch_map[] = {
+};
+
+static struct gpio_event_input_info tegra_keypad_switch_info = {
+       .info.func = gpio_event_input_func,
+       .flags = 0,
+       .type = EV_SW,
+       .keymap = tegra_keypad_switch_map,
+       .keymap_size = ARRAY_SIZE(tegra_keypad_switch_map)
+};
+
+static struct gpio_event_info *tegra_keypad_info[] = {
+       &tegra_keypad_matrix_info.info,
+       &tegra_keypad_switch_info.info,
+};
+
+static struct gpio_event_platform_data tegra_keypad_data = {
+       .name = "tegra-keypad",
+       .info = tegra_keypad_info,
+       .info_count = ARRAY_SIZE(tegra_keypad_info)
+};
+
+static struct platform_device tegra_keypad_device = {
+       .name = GPIO_EVENT_DEV_NAME,
+       .id = 0,
+       .dev            = {
+               .platform_data  = &tegra_keypad_data,
+       },
+};
+
+static int tegra_reset_keys_up[] = {
+       BTN_MOUSE,              /* XXX */
+        0
+};
+
+static struct keyreset_platform_data tegra_reset_keys_pdata = {
+       .keys_up = tegra_reset_keys_up,
+       .keys_down = {
+               KEY_LEFTSHIFT,
+               KEY_LEFTALT,
+               KEY_BACKSPACE,
+               0
+       },
+};
+
+struct platform_device tegra_reset_keys_device = {
+         .name = KEYRESET_NAME,
+         .dev.platform_data = &tegra_reset_keys_pdata,
+};
+
+static int __init tegra_init_keypad(void)
+{
+       tegra_gpio_enable(TEGRA_GPIO_PR0);
+       tegra_gpio_enable(TEGRA_GPIO_PR1);
+       tegra_gpio_enable(TEGRA_GPIO_PR2);
+       tegra_gpio_enable(TEGRA_GPIO_PQ0);
+       tegra_gpio_enable(TEGRA_GPIO_PQ1);
+       tegra_gpio_enable(TEGRA_GPIO_PQ2);
+       platform_device_register(&tegra_reset_keys_device);
+       return platform_device_register(&tegra_keypad_device);
+}
+
+device_initcall(tegra_init_keypad);
diff --git a/arch/arm/mach-tegra/board-stingray-panel.c b/arch/arm/mach-tegra/board-stingray-panel.c
new file mode 100644 (file)
index 0000000..778ca56
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * arch/arm/mach-tegra/board-stingray-panel.c
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/resource.h>
+#include <linux/platform_device.h>
+#include <asm/mach-types.h>
+#include <mach/irqs.h>
+#include <mach/iomap.h>
+#include <mach/tegra_fb.h>
+
+/* Framebuffer */
+static struct resource fb_resource[] = {
+       [0] = {
+               .start  = INT_DISPLAY_GENERAL,
+               .end    = INT_DISPLAY_GENERAL,
+               .flags  = IORESOURCE_IRQ,
+       },
+       [1] = {
+               .start  = TEGRA_DISPLAY_BASE,
+               .end    = TEGRA_DISPLAY_BASE + TEGRA_DISPLAY_SIZE-1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [2] = {
+               .start  = 0x1c03a000,
+               .end    = 0x1c03a000 + 0x500000 - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+};
+
+static struct tegra_fb_lcd_data tegra_fb_lcd_platform_data = {
+       .lcd_xres       = 480,
+       .lcd_yres       = 854,
+       .fb_xres        = 480,
+       .fb_yres        = 854,
+       .bits_per_pixel = 16,
+};
+
+static struct platform_device tegra_fb_device = {
+       .name           = "tegrafb",
+       .id             = 0,
+       .resource       = fb_resource,
+       .num_resources  = ARRAY_SIZE(fb_resource),
+       .dev = {
+               .platform_data = &tegra_fb_lcd_platform_data,
+       },
+};
+
+static int __init stingray_init_panel(void) {
+       int ret;
+
+       if (!machine_is_stingray())
+               return 0;
+
+       ret = platform_device_register(&tegra_fb_device);
+       if (ret != 0)
+               return ret;
+
+       return 0;
+}
+
+device_initcall(stingray_init_panel);
+
diff --git a/arch/arm/mach-tegra/board-stingray-pinmux.c b/arch/arm/mach-tegra/board-stingray-pinmux.c
new file mode 100644 (file)
index 0000000..f73d350
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+ * arch/arm/mach-tegra/board-stingray-pinmux.c
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <mach/pinmux.h>
+
+#include "board-stingray.h"
+
+static struct tegra_pingroup_config stingray_pinmux[] = {
+       {TEGRA_PINGROUP_ATA,   TEGRA_MUX_GMI,           TEGRA_PUPD_PULL_UP,   TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_ATB,   TEGRA_MUX_SDIO4,         TEGRA_PUPD_PULL_UP,   TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_ATC,   TEGRA_MUX_GMI,           TEGRA_PUPD_PULL_UP,   TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_ATD,   TEGRA_MUX_GMI,           TEGRA_PUPD_PULL_UP,   TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_ATE,   TEGRA_MUX_GMI,           TEGRA_PUPD_PULL_UP,   TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_CDEV1, TEGRA_MUX_OSC,           TEGRA_PUPD_NORMAL,    TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_CDEV2, TEGRA_MUX_OSC,           TEGRA_PUPD_NORMAL,    TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_CRTP,  TEGRA_MUX_CRT,           TEGRA_PUPD_NORMAL,    TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_CSUS,  TEGRA_MUX_VI_SENSOR_CLK, TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_DAP1,  TEGRA_MUX_DAP1,          TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_DAP2,  TEGRA_MUX_DAP2,          TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_DAP3,  TEGRA_MUX_DAP3,          TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_DAP4,  TEGRA_MUX_DAP4,          TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_DDC,   TEGRA_MUX_I2C2,          TEGRA_PUPD_PULL_UP,   TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_DTA,   TEGRA_MUX_SDIO2,         TEGRA_TRI_NORMAL,     TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_DTB,   TEGRA_MUX_RSVD1,         TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_DTC,   TEGRA_MUX_RSVD1,         TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_DTD,   TEGRA_MUX_SDIO2,         TEGRA_TRI_NORMAL,     TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_DTE,   TEGRA_MUX_RSVD1,         TEGRA_PUPD_NORMAL,    TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_DTF,   TEGRA_MUX_I2C3,          TEGRA_PUPD_PULL_UP,   TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_GMA,   TEGRA_MUX_SDIO4,         TEGRA_PUPD_NORMAL,    TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_GMB,   TEGRA_MUX_GMI,           TEGRA_PUPD_NORMAL,    TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_GMC,   TEGRA_MUX_UARTD,         TEGRA_PUPD_NORMAL,    TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_GMD,   TEGRA_MUX_GMI,           TEGRA_PUPD_NORMAL,    TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_GME,   TEGRA_MUX_SDIO4,         TEGRA_PUPD_NORMAL,    TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_GPU,   TEGRA_MUX_GMI,           TEGRA_PUPD_NORMAL,    TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_GPU7,  TEGRA_MUX_RTCK,          TEGRA_PUPD_NORMAL,    TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_GPV,   TEGRA_MUX_PCIE,          TEGRA_PUPD_NORMAL,    TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_HDINT, TEGRA_MUX_HDMI,          TEGRA_PUPD_PULL_UP,   TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_I2CP,  TEGRA_MUX_I2C,           TEGRA_PUPD_NORMAL,    TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_IRRX,  TEGRA_MUX_UARTA,         TEGRA_PUPD_NORMAL,    TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_IRTX,  TEGRA_MUX_UARTA,         TEGRA_PUPD_NORMAL,    TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_KBCA,  TEGRA_MUX_KBC,           TEGRA_PUPD_PULL_UP,   TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_KBCB,  TEGRA_MUX_KBC,           TEGRA_PUPD_PULL_UP,   TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_KBCC,  TEGRA_MUX_KBC,           TEGRA_PUPD_PULL_UP,   TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_KBCD,  TEGRA_MUX_KBC,           TEGRA_PUPD_PULL_UP,   TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_KBCE,  TEGRA_MUX_KBC,           TEGRA_PUPD_PULL_UP,   TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_KBCF,  TEGRA_MUX_KBC,           TEGRA_PUPD_PULL_UP,   TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_LCSN,  TEGRA_MUX_DISPLAYA,      TEGRA_PUPD_PULL_UP,   TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_LD0,   TEGRA_MUX_DISPLAYA,      TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_LD1,   TEGRA_MUX_DISPLAYA,      TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_LD10,  TEGRA_MUX_DISPLAYA,      TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_LD11,  TEGRA_MUX_DISPLAYA,      TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_LD12,  TEGRA_MUX_DISPLAYA,      TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_LD13,  TEGRA_MUX_DISPLAYA,      TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_LD14,  TEGRA_MUX_DISPLAYA,      TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_LD15,  TEGRA_MUX_DISPLAYA,      TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_LD16,  TEGRA_MUX_DISPLAYA,      TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_LD17,  TEGRA_MUX_DISPLAYA,      TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_LD2,   TEGRA_MUX_DISPLAYA,      TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_LD3,   TEGRA_MUX_DISPLAYA,      TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_LD4,   TEGRA_MUX_DISPLAYA,      TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_LD5,   TEGRA_MUX_DISPLAYA,      TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_LD6,   TEGRA_MUX_DISPLAYA,      TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_LD7,   TEGRA_MUX_DISPLAYA,      TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_LD8,   TEGRA_MUX_DISPLAYA,      TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_LD9,   TEGRA_MUX_DISPLAYA,      TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_LDC,   TEGRA_MUX_DISPLAYA,      TEGRA_PUPD_PULL_UP,   TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_LDI,   TEGRA_MUX_DISPLAYA,      TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_LHP0,  TEGRA_MUX_DISPLAYA,      TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_LHP1,  TEGRA_MUX_DISPLAYA,      TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_LHP2,  TEGRA_MUX_DISPLAYA,      TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_LHS,   TEGRA_MUX_DISPLAYA,      TEGRA_PUPD_PULL_UP,   TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_LM0,   TEGRA_MUX_SPI3,          TEGRA_PUPD_PULL_UP,   TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_LM1,   TEGRA_MUX_DISPLAYA,      TEGRA_PUPD_PULL_UP,   TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_LPP,   TEGRA_MUX_DISPLAYA,      TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_LPW0,  TEGRA_MUX_SPI3,          TEGRA_PUPD_PULL_UP,   TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_LPW1,  TEGRA_MUX_DISPLAYA,      TEGRA_PUPD_PULL_UP,   TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_LPW2,  TEGRA_MUX_SPI3,          TEGRA_PUPD_PULL_UP,   TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_LSC0,  TEGRA_MUX_DISPLAYA,      TEGRA_PUPD_PULL_UP,   TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_LSC1,  TEGRA_MUX_SPI3,          TEGRA_PUPD_PULL_UP,   TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_LSCK,  TEGRA_MUX_DISPLAYA,      TEGRA_PUPD_PULL_UP,   TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_LSDA,  TEGRA_MUX_DISPLAYA,      TEGRA_PUPD_PULL_UP,   TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_LSDI,  TEGRA_MUX_DISPLAYA,      TEGRA_PUPD_PULL_UP,   TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_LSPI,  TEGRA_MUX_DISPLAYA,      TEGRA_PUPD_PULL_UP,   TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_LVP0,  TEGRA_MUX_DISPLAYA,      TEGRA_PUPD_PULL_UP,   TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_LVP1,  TEGRA_MUX_DISPLAYA,      TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_LVS,   TEGRA_MUX_DISPLAYA,      TEGRA_PUPD_PULL_UP,   TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_OWC,   TEGRA_MUX_OWR,           TEGRA_PUPD_PULL_UP,   TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_PMC,   TEGRA_MUX_PWR_ON,        TEGRA_PUPD_NORMAL,    TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_PTA,   TEGRA_MUX_RSVD4,         TEGRA_PUPD_NORMAL,    TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_RM,    TEGRA_MUX_I2C,           TEGRA_PUPD_NORMAL,    TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_SDB,   TEGRA_MUX_SDIO3,         TEGRA_PUPD_NORMAL,    TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_SDC,   TEGRA_MUX_SDIO3,         TEGRA_TRI_NORMAL,     TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_SDD,   TEGRA_MUX_SDIO3,         TEGRA_TRI_NORMAL,     TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_SDIO1, TEGRA_MUX_SDIO1,         TEGRA_PUPD_PULL_UP,   TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_SLXA,  TEGRA_MUX_PCIE,          TEGRA_PUPD_NORMAL,    TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_SLXC,  TEGRA_MUX_SPI4,          TEGRA_PUPD_NORMAL,    TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_SLXD,  TEGRA_MUX_SPI4,          TEGRA_PUPD_NORMAL,    TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_SLXK,  TEGRA_MUX_PCIE,          TEGRA_PUPD_NORMAL,    TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_SPDI,  TEGRA_MUX_RSVD2,         TEGRA_PUPD_NORMAL,    TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_SPDO,  TEGRA_MUX_RSVD2,         TEGRA_PUPD_NORMAL,    TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_SPIA,  TEGRA_MUX_SPI2,          TEGRA_PUPD_NORMAL,    TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_SPIB,  TEGRA_MUX_SPI2,          TEGRA_PUPD_NORMAL,    TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_SPIC,  TEGRA_MUX_SPI2,          TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_SPID,  TEGRA_MUX_SPI1,          TEGRA_PUPD_NORMAL,    TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_SPIE,  TEGRA_MUX_SPI1,          TEGRA_PUPD_NORMAL,    TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_SPIF,  TEGRA_MUX_SPI1,          TEGRA_PUPD_NORMAL,    TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_SPIG,  TEGRA_MUX_SPI2,          TEGRA_PUPD_PULL_DOWN, TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_SPIH,  TEGRA_MUX_SPI2,          TEGRA_PUPD_NORMAL,    TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_UAA,   TEGRA_MUX_MIPI_HS,       TEGRA_PUPD_PULL_UP,   TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_UAB,   TEGRA_MUX_MIPI_HS,       TEGRA_PUPD_PULL_UP,   TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_UAC,   TEGRA_MUX_OWR,           TEGRA_PUPD_NORMAL,    TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_UAD,   TEGRA_MUX_IRDA,          TEGRA_PUPD_PULL_UP,   TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_UCA,   TEGRA_MUX_UARTC,         TEGRA_PUPD_PULL_UP,   TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_UCB,   TEGRA_MUX_UARTC,         TEGRA_PUPD_PULL_UP,   TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_UDA,   TEGRA_MUX_RSVD2,         TEGRA_PUPD_NORMAL,    TEGRA_TRI_TRISTATE},
+       {TEGRA_PINGROUP_CK32,  TEGRA_MUX_NONE,          TEGRA_PUPD_NORMAL,    TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_DDRC,  TEGRA_MUX_NONE,          TEGRA_PUPD_NORMAL,    TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_PMCA,  TEGRA_MUX_NONE,          TEGRA_PUPD_NORMAL,    TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_PMCB,  TEGRA_MUX_NONE,          TEGRA_PUPD_NORMAL,    TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_PMCC,  TEGRA_MUX_NONE,          TEGRA_PUPD_NORMAL,    TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_PMCD,  TEGRA_MUX_NONE,          TEGRA_PUPD_NORMAL,    TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_PMCE,  TEGRA_MUX_NONE,          TEGRA_PUPD_NORMAL,    TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_XM2C,  TEGRA_MUX_NONE,          TEGRA_PUPD_NORMAL,    TEGRA_TRI_NORMAL},
+       {TEGRA_PINGROUP_XM2D,  TEGRA_MUX_NONE,          TEGRA_PUPD_NORMAL,    TEGRA_TRI_NORMAL},
+};
+
+void stingray_pinmux_init(void)
+{
+       tegra_pinmux_config_table(stingray_pinmux, ARRAY_SIZE(stingray_pinmux));
+}
diff --git a/arch/arm/mach-tegra/board-stingray-wifi.c b/arch/arm/mach-tegra/board-stingray-wifi.c
new file mode 100644 (file)
index 0000000..47b0c94
--- /dev/null
@@ -0,0 +1,212 @@
+/* linux/arch/arm/mach-msm/board-stingray-wifi.c
+*/
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <asm/mach-types.h>
+#include <asm/gpio.h>
+#include <asm/io.h>
+#include <linux/skbuff.h>
+#include <linux/wlan_plat.h>
+#include <mach/sdhci.h>
+
+#include "gpio-names.h"
+
+#define STINGRAY_WLAN_IRQ      TEGRA_GPIO_PU5
+#define STINGRAY_WLAN_PWR      TEGRA_GPIO_PU3
+#define STINGRAY_WLAN_RST      TEGRA_GPIO_PU2
+
+#define PREALLOC_WLAN_NUMBER_OF_SECTIONS       4
+#define PREALLOC_WLAN_NUMBER_OF_BUFFERS                160
+#define PREALLOC_WLAN_SECTION_HEADER           24
+
+#define WLAN_SECTION_SIZE_0    (PREALLOC_WLAN_NUMBER_OF_BUFFERS * 128)
+#define WLAN_SECTION_SIZE_1    (PREALLOC_WLAN_NUMBER_OF_BUFFERS * 128)
+#define WLAN_SECTION_SIZE_2    (PREALLOC_WLAN_NUMBER_OF_BUFFERS * 512)
+#define WLAN_SECTION_SIZE_3    (PREALLOC_WLAN_NUMBER_OF_BUFFERS * 1024)
+
+#define WLAN_SKB_BUF_NUM       16
+
+static struct sk_buff *wlan_static_skb[WLAN_SKB_BUF_NUM];
+
+typedef struct wifi_mem_prealloc_struct {
+       void *mem_ptr;
+       unsigned long size;
+} wifi_mem_prealloc_t;
+
+static wifi_mem_prealloc_t wifi_mem_array[PREALLOC_WLAN_NUMBER_OF_SECTIONS] = {
+       { NULL, (WLAN_SECTION_SIZE_0 + PREALLOC_WLAN_SECTION_HEADER) },
+       { NULL, (WLAN_SECTION_SIZE_1 + PREALLOC_WLAN_SECTION_HEADER) },
+       { NULL, (WLAN_SECTION_SIZE_2 + PREALLOC_WLAN_SECTION_HEADER) },
+       { NULL, (WLAN_SECTION_SIZE_3 + PREALLOC_WLAN_SECTION_HEADER) }
+};
+
+static void *stingray_wifi_mem_prealloc(int section, unsigned long size)
+{
+       if (section == PREALLOC_WLAN_NUMBER_OF_SECTIONS)
+               return wlan_static_skb;
+       if ((section < 0) || (section > PREALLOC_WLAN_NUMBER_OF_SECTIONS))
+               return NULL;
+       if (wifi_mem_array[section].size < size)
+               return NULL;
+       return wifi_mem_array[section].mem_ptr;
+}
+
+int __init stingray_init_wifi_mem(void)
+{
+       int i;
+
+       for(i=0;( i < WLAN_SKB_BUF_NUM );i++) {
+               if (i < (WLAN_SKB_BUF_NUM/2))
+                       wlan_static_skb[i] = dev_alloc_skb(4096);
+               else
+                       wlan_static_skb[i] = dev_alloc_skb(8192);
+       }
+       for(i=0;( i < PREALLOC_WLAN_NUMBER_OF_SECTIONS );i++) {
+               wifi_mem_array[i].mem_ptr = kmalloc(wifi_mem_array[i].size,
+                                                       GFP_KERNEL);
+               if (wifi_mem_array[i].mem_ptr == NULL)
+                       return -ENOMEM;
+       }
+       return 0;
+}
+
+static struct resource stingray_wifi_resources[] = {
+       [0] = {
+               .name           = "bcm4329_wlan_irq",
+               .start          = TEGRA_GPIO_TO_IRQ(STINGRAY_WLAN_IRQ),
+               .end            = TEGRA_GPIO_TO_IRQ(STINGRAY_WLAN_IRQ),
+               .flags          = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWEDGE,
+       },
+};
+
+/* BCM4329 returns wrong sdio_vsn(1) when we read cccr,
+ * we use predefined value (sdio_vsn=2) here to initial sdio driver well
+  */
+static struct embedded_sdio_data stingray_wifi_emb_data = {
+       .cccr   = {
+               .sdio_vsn       = 2,
+               .multi_block    = 1,
+               .low_speed      = 0,
+               .wide_bus       = 0,
+               .high_power     = 1,
+               .high_speed     = 1,
+       },
+};
+
+static int stingray_wifi_cd = 0; /* WIFI virtual 'card detect' status */
+static void (*wifi_status_cb)(int card_present, void *dev_id);
+static void *wifi_status_cb_devid;
+
+static int stingray_wifi_status_register(
+               void (*callback)(int card_present, void *dev_id),
+               void *dev_id)
+{
+       if (wifi_status_cb)
+               return -EAGAIN;
+       wifi_status_cb = callback;
+       wifi_status_cb_devid = dev_id;
+       return 0;
+}
+
+static unsigned int stingray_wifi_status(struct device *dev)
+{
+       return stingray_wifi_cd;
+}
+
+struct tegra_sdhci_platform_data stingray_wifi_data = {
+       .clk_id = NULL,
+       .force_hs = 0,
+       .mmc_data = {
+               .ocr_mask               = MMC_VDD_165_195,
+               .status                 = stingray_wifi_status,
+               .register_status_notify = stingray_wifi_status_register,
+               .embedded_sdio          = &stingray_wifi_emb_data,
+       }
+};
+
+int stingray_wifi_set_carddetect(int val)
+{
+       pr_debug("%s: %d\n", __func__, val);
+       stingray_wifi_cd = val;
+       if (wifi_status_cb) {
+               wifi_status_cb(val, wifi_status_cb_devid);
+       } else
+               pr_warning("%s: Nobody to notify\n", __func__);
+       return 0;
+}
+
+static int stingray_wifi_power_state;
+
+int stingray_wifi_power(int on)
+{
+       pr_debug("%s: %d\n", __func__, on);
+
+       mdelay(100);
+       gpio_set_value(STINGRAY_WLAN_PWR, on);
+       mdelay(100);
+       gpio_set_value(STINGRAY_WLAN_RST, on);
+       mdelay(200);
+
+       stingray_wifi_power_state = on;
+       return 0;
+}
+
+static int stingray_wifi_reset_state;
+
+int stingray_wifi_reset(int on)
+{
+       pr_debug("%s: do nothing\n", __func__);
+       stingray_wifi_reset_state = on;
+       return 0;
+}
+
+static struct wifi_platform_data stingray_wifi_control = {
+       .set_power      = stingray_wifi_power,
+       .set_reset      = stingray_wifi_reset,
+       .set_carddetect = stingray_wifi_set_carddetect,
+       .mem_prealloc   = stingray_wifi_mem_prealloc,
+};
+
+static struct platform_device stingray_wifi_device = {
+        .name           = "bcm4329_wlan",
+        .id             = 1,
+        .num_resources  = ARRAY_SIZE(stingray_wifi_resources),
+        .resource       = stingray_wifi_resources,
+        .dev            = {
+                .platform_data = &stingray_wifi_control,
+        },
+};
+
+static void __init stingray_wlan_gpio(void)
+{
+       tegra_gpio_enable(STINGRAY_WLAN_PWR);
+       gpio_request(STINGRAY_WLAN_PWR, "wlan_pwr");
+       gpio_direction_output(STINGRAY_WLAN_PWR, 0);
+
+       tegra_gpio_enable(STINGRAY_WLAN_RST);
+       gpio_request(STINGRAY_WLAN_RST, "wlan_rst");
+       gpio_direction_output(STINGRAY_WLAN_RST, 0);
+
+       tegra_gpio_enable(STINGRAY_WLAN_IRQ);
+       gpio_request(STINGRAY_WLAN_IRQ, "wlan_irq");
+       gpio_direction_input(STINGRAY_WLAN_IRQ);
+}
+
+static int __init stingray_wlan_init(void)
+{
+       int ret;
+
+       if (!machine_is_stingray())
+               return 0;
+
+       pr_debug("%s: start\n", __func__);
+       stingray_wlan_gpio();
+       stingray_init_wifi_mem();
+       ret = platform_device_register(&stingray_wifi_device);
+       return ret;
+}
+
+late_initcall(stingray_wlan_init);
diff --git a/arch/arm/mach-tegra/board-stingray.c b/arch/arm/mach-tegra/board-stingray.c
new file mode 100644 (file)
index 0000000..3c169ed
--- /dev/null
@@ -0,0 +1,289 @@
+/*
+ * arch/arm/mach-tegra/board-stingray.c
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/serial_8250.h>
+#include <linux/clk.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/dma-mapping.h>
+#include <linux/fsl_devices.h>
+#include <linux/pda_power.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+#include <asm/setup.h>
+
+#include <mach/io.h>
+#include <mach/iomap.h>
+#include <mach/irqs.h>
+#include <mach/iomap.h>
+#include <mach/sdhci.h>
+#include <mach/gpio.h>
+
+#include <linux/usb/android_composite.h>
+
+#include "board.h"
+#include "board-stingray.h"
+#include "clock.h"
+#include "gpio-names.h"
+#include "devices.h"
+
+/* NVidia bootloader tags */
+#define ATAG_NVIDIA            0x41000801
+
+#define ATAG_NVIDIA_RM                 0x1
+#define ATAG_NVIDIA_DISPLAY            0x2
+#define ATAG_NVIDIA_FRAMEBUFFER                0x3
+#define ATAG_NVIDIA_CHIPSHMOO          0x4
+#define ATAG_NVIDIA_CHIPSHMOOPHYS      0x5
+#define ATAG_NVIDIA_PRESERVED_MEM_0    0x10000
+#define ATAG_NVIDIA_PRESERVED_MEM_N    2
+#define ATAG_NVIDIA_FORCE_32           0x7fffffff
+
+struct tag_tegra {
+       __u32 bootarg_key;
+       __u32 bootarg_len;
+       char bootarg[1];
+};
+
+static int __init parse_tag_nvidia(const struct tag *tag)
+{
+
+       return 0;
+}
+__tagtable(ATAG_NVIDIA, parse_tag_nvidia);
+
+static struct plat_serial8250_port debug_uart_platform_data[] = {
+       {
+               .membase        = IO_ADDRESS(TEGRA_UARTB_BASE),
+               .mapbase        = TEGRA_UARTB_BASE,
+               .irq            = INT_UARTB,
+               .flags          = UPF_BOOT_AUTOCONF,
+               .iotype         = UPIO_MEM,
+               .regshift       = 2,
+               .uartclk        = 0, /* filled in by tegra_stingray_init */
+       }, {
+               .flags          = 0
+       }
+};
+
+static struct platform_device debug_uart = {
+       .name = "serial8250",
+       .id = PLAT8250_DEV_PLATFORM,
+       .dev = {
+               .platform_data = debug_uart_platform_data,
+       },
+};
+
+static struct plat_serial8250_port hsuart_platform_data[] = {
+       {
+               .mapbase        = TEGRA_UARTD_BASE,
+               .membase        = IO_ADDRESS(TEGRA_UARTD_BASE),
+               .irq            = INT_UARTD,
+       }, {
+               .flags          = 0
+       }
+};
+
+static struct platform_device hsuart = {
+       .name = "tegra_uart",
+       .id = 3,
+       .dev = {
+               .platform_data = hsuart_platform_data,
+               .coherent_dma_mask = 0xffffffff,
+       },
+};
+
+/* OTG gadget device */
+static u64 tegra_otg_dmamask = DMA_BIT_MASK(32);
+
+
+static struct resource tegra_otg_resources[] = {
+       [0] = {
+               .start  = TEGRA_USB_BASE,
+               .end    = TEGRA_USB_BASE + TEGRA_USB_SIZE - 1,
+               .flags  = IORESOURCE_MEM,
+       },
+       [1] = {
+               .start  = INT_USB,
+               .end    = INT_USB,
+               .flags  = IORESOURCE_IRQ,
+       },
+};
+
+static struct fsl_usb2_platform_data tegra_otg_pdata = {
+       .operating_mode = FSL_USB2_DR_DEVICE,
+       .phy_mode       = FSL_USB2_PHY_UTMI,
+};
+
+struct platform_device tegra_otg = {
+       .name = "fsl-tegra-udc",
+       .id   = -1,
+       .dev  = {
+               .dma_mask               = &tegra_otg_dmamask,
+               .coherent_dma_mask      = 0xffffffff,
+               .platform_data = &tegra_otg_pdata,
+       },
+       .resource = tegra_otg_resources,
+       .num_resources = ARRAY_SIZE(tegra_otg_resources),
+};
+
+static char *usb_functions[] = { "usb_mass_storage" };
+static char *usb_functions_adb[] = { "usb_mass_storage", "adb" };
+
+static struct android_usb_product usb_products[] = {
+       {
+               .product_id     = 0xDEAD,
+               .num_functions  = ARRAY_SIZE(usb_functions),
+               .functions      = usb_functions,
+       },
+       {
+               .product_id     = 0xBEEF,
+               .num_functions  = ARRAY_SIZE(usb_functions_adb),
+               .functions      = usb_functions_adb,
+       },
+};
+
+/* standard android USB platform data */
+static struct android_usb_platform_data andusb_plat = {
+       .vendor_id                      = 0x18d1,
+       .product_id                     = 0x0002,
+       .manufacturer_name      = "Google",
+       .product_name           = "Stingray!",
+       .serial_number          = "0000",
+       .num_products = ARRAY_SIZE(usb_products),
+       .products = usb_products,
+       .num_functions = ARRAY_SIZE(usb_functions_adb),
+       .functions = usb_functions_adb,
+};
+
+
+static struct platform_device androidusb_device = {
+       .name   = "android_usb",
+       .id     = -1,
+       .dev    = {
+               .platform_data  = &andusb_plat,
+       },
+};
+
+/* PDA power */
+static struct pda_power_pdata pda_power_pdata = {
+};
+
+static struct platform_device pda_power_device = {
+       .name   = "pda_power",
+       .id     = -1,
+       .dev    = {
+               .platform_data  = &pda_power_pdata,
+       },
+};
+
+static struct platform_device *stingray_devices[] __initdata = {
+       &debug_uart,
+       &tegra_otg,
+       &androidusb_device,
+       &pda_power_device,
+       &hsuart,
+};
+
+extern struct tegra_sdhci_platform_data stingray_wifi_data; /* sdhci1 */
+
+static struct tegra_sdhci_platform_data stingray_sdhci_platform_data3 = {
+       .clk_id = NULL,
+       .force_hs = 0,
+};
+
+static struct tegra_sdhci_platform_data stingray_sdhci_platform_data4 = {
+       .clk_id = NULL,
+       .force_hs = 0,
+       .cd_gpio = TEGRA_GPIO_PH2,
+       .wp_gpio = TEGRA_GPIO_PH3,
+       .power_gpio = TEGRA_GPIO_PI6,
+};
+
+static __initdata struct tegra_clk_init_table stingray_clk_init_table[] = {
+       /* name         parent          rate            enabled */
+       { "uartb",      "clk_m",        26000000,       true},
+       { NULL,         NULL,           0,              0},
+};
+
+
+static void stingray_sdhci_init(void)
+{
+       /* TODO: setup GPIOs for cd, wd, and power */
+       tegra_sdhci_device1.dev.platform_data = &stingray_wifi_data;
+       tegra_sdhci_device3.dev.platform_data = &stingray_sdhci_platform_data3;
+       tegra_sdhci_device4.dev.platform_data = &stingray_sdhci_platform_data4;
+
+       platform_device_register(&tegra_sdhci_device1);
+       platform_device_register(&tegra_sdhci_device3);
+       platform_device_register(&tegra_sdhci_device4);
+}
+
+
+static void __init tegra_stingray_fixup(struct machine_desc *desc, struct tag *tags,
+                                char **cmdline, struct meminfo *mi)
+{
+       mi->nr_banks = 2;
+       mi->bank[0].start = PHYS_OFFSET;
+       mi->bank[0].node = PHYS_TO_NID(PHYS_OFFSET);
+       mi->bank[0].size = 448 * SZ_1M;
+       mi->bank[1].start = SZ_512M;
+       mi->bank[1].node = PHYS_TO_NID(SZ_512M);
+       mi->bank[1].size = SZ_512M;
+}
+
+static void __init tegra_stingray_init(void)
+{
+       struct clk *clk;
+
+       tegra_common_init();
+
+       /* Stingray has a USB switch that disconnects the usb port from the AP20
+          unless a factory cable is used, the factory jumper is set, or the
+          usb_data_en gpio is set.
+        */
+       tegra_gpio_enable(TEGRA_GPIO_PV6);
+       gpio_request(TEGRA_GPIO_PV6, "usb_data_en");
+       gpio_direction_output(TEGRA_GPIO_PV6, 1);
+
+       stingray_pinmux_init();
+
+       stingray_sdhci_init();
+
+       tegra_clk_init_from_table(stingray_clk_init_table);
+
+       clk = tegra_get_clock_by_name("uartb");
+       debug_uart_platform_data[0].uartclk = clk_get_rate(clk);
+
+       platform_add_devices(stingray_devices, ARRAY_SIZE(stingray_devices));
+}
+
+MACHINE_START(STINGRAY, "stingray")
+       .boot_params  = 0x00000100,
+       .phys_io        = IO_APB_PHYS,
+       .io_pg_offst    = ((IO_APB_VIRT) >> 18) & 0xfffc,
+       .fixup          = tegra_stingray_fixup,
+       .init_irq       = tegra_init_irq,
+       .init_machine   = tegra_stingray_init,
+       .map_io         = tegra_map_common_io,
+       .timer          = &tegra_timer,
+MACHINE_END
diff --git a/arch/arm/mach-tegra/board-stingray.h b/arch/arm/mach-tegra/board-stingray.h
new file mode 100644 (file)
index 0000000..257b086
--- /dev/null
@@ -0,0 +1,22 @@
+/*
+ * arch/arm/mach-tegra/board-stingray.h
+ *
+ * Copyright (C) 2010 Google, Inc.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * 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.
+ *
+ */
+
+#ifndef _MACH_TEGRA_BOARD_STINGRAY_H
+#define _MACH_TEGRA_BOARD_STINGRAY_H
+
+void stingray_pinmux_init(void);
+
+#endif