From patchwork Tue Aug 3 11:56:14 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Enric Balletbo Serra X-Patchwork-Id: 116736 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.4/8.14.3) with ESMTP id o73BuTTu009958 for ; Tue, 3 Aug 2010 11:56:33 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756136Ab0HCL4c (ORCPT ); Tue, 3 Aug 2010 07:56:32 -0400 Received: from mail-ww0-f44.google.com ([74.125.82.44]:39296 "EHLO mail-ww0-f44.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756052Ab0HCL42 (ORCPT ); Tue, 3 Aug 2010 07:56:28 -0400 Received: by mail-ww0-f44.google.com with SMTP id 40so5028695wwj.1 for ; Tue, 03 Aug 2010 04:56:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:from:to:cc:subject:date :message-id:x-mailer:in-reply-to:references; bh=pyI6d1rU/7sGGimVR3H7ETj1VS0HZtQyGKbiiNT9Oko=; b=ZP+uPHFZ3INh0EnvnPY5JXjoHQGrTKfDwzRzzt5Bz4RxydS2w5CUyE2jUp9oeaygLp z9f7YfcGfdHatsfqRB7jeOHfyzxgTeDabfimTt75oucIn/mws0SJ6Xff3ZmB1YMgDola WAy4lWMJHXSXRK14+FhPKoxxThqzn7qONruIU= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=from:to:cc:subject:date:message-id:x-mailer:in-reply-to:references; b=VFOkA2kDNBBOBJImWg9Iy8kt4w7hIlkkuDyE3TTHEIlQ9vUtEHPT7PhEI4+LKzd3es jUesSXVbNIFwBR37KKfZU+e7DxsCryn6Otz06KA5RmHZmB2c+30M8eEDeI+35Y0+bDwp ncBveI7ioPQlOpqO+2YbDOYWdALhwFcdEcmZw= Received: by 10.227.128.82 with SMTP id j18mr6200374wbs.36.1280836586457; Tue, 03 Aug 2010 04:56:26 -0700 (PDT) Received: from localhost.localdomain ([81.35.234.198]) by mx.google.com with ESMTPS id e8sm3485720wej.46.2010.08.03.04.56.25 (version=TLSv1/SSLv3 cipher=RC4-MD5); Tue, 03 Aug 2010 04:56:26 -0700 (PDT) From: Enric Balletbo i Serra To: linux-omap@vger.kernel.org Cc: Enric Balletbo i Serra Subject: [PATCH 4/4] omap3: Add minimal OMAP3 IGEP module support. Date: Tue, 3 Aug 2010 13:56:14 +0200 Message-Id: <1280836574-32467-5-git-send-email-eballetbo@gmail.com> X-Mailer: git-send-email 1.7.0.4 In-Reply-To: <1280836574-32467-1-git-send-email-eballetbo@gmail.com> References: <1280836574-32467-1-git-send-email-eballetbo@gmail.com> Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Tue, 03 Aug 2010 11:56:33 +0000 (UTC) diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index b31b6f1..db8bd18 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig @@ -142,6 +142,11 @@ config MACH_IGEP0020 depends on ARCH_OMAP3 select OMAP_PACKAGE_CBB +config MACH_IGEP0030 + bool "IGEP OMAP3 module" + depends on ARCH_OMAP3 + select OMAP_PACKAGE_CBB + config MACH_SBC3530 bool "OMAP3 SBC STALKER board" depends on ARCH_OMAP3 diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile index ea52b03..fab0222 100644 --- a/arch/arm/mach-omap2/Makefile +++ b/arch/arm/mach-omap2/Makefile @@ -136,6 +136,8 @@ obj-$(CONFIG_MACH_CM_T35) += board-cm-t35.o \ hsmmc.o obj-$(CONFIG_MACH_IGEP0020) += board-igep0020.o \ hsmmc.o +obj-$(CONFIG_MACH_IGEP0030) += board-igep0030.o \ + hsmmc.o obj-$(CONFIG_MACH_OMAP3_TOUCHBOOK) += board-omap3touchbook.o \ hsmmc.o obj-$(CONFIG_MACH_OMAP_4430SDP) += board-4430sdp.o \ diff --git a/arch/arm/mach-omap2/board-igep0030.c b/arch/arm/mach-omap2/board-igep0030.c new file mode 100644 index 0000000..936bf98 --- /dev/null +++ b/arch/arm/mach-omap2/board-igep0030.c @@ -0,0 +1,436 @@ +/* + * Copyright (C) 2010 Integration Software and Electronic Engineering. + * + * Modified from mach-omap2/board-generic.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "mux.h" +#include "hsmmc.h" +#include "sdram-numonyx-m65kxxxxam.h" + +#define IGEP3_GPIO_LED0_GREEN 54 +#define IGEP3_GPIO_LED0_RED 53 +#define IGEP3_GPIO_LED1_RED 16 + +#define IGEP3_GPIO_WIFI_NPD 138 +#define IGEP3_GPIO_WIFI_NRESET 139 +#define IGEP3_GPIO_BT_NRESET 137 + +#define IGEP3_GPIO_USBH_NRESET 115 + + +#if defined(CONFIG_MTD_ONENAND_OMAP2) || \ + defined(CONFIG_MTD_ONENAND_OMAP2_MODULE) + +#define ONENAND_MAP 0x20000000 + +/* x2 Flash built-in COMBO POP MEMORY + * Since the device is equipped with two DataRAMs, and two-plane NAND + * Flash memory array, these two component enables simultaneous program + * of 4KiB. Plane1 has only even blocks such as block0, block2, block4 + * while Plane2 has only odd blocks such as block1, block3, block5. + * So MTD regards it as 4KiB page size and 256KiB block size 64*(2*2048) + */ + +static struct mtd_partition igep3_onenand_partitions[] = { + { + .name = "X-Loader", + .offset = 0, + .size = 2 * (64*(2*2048)) + }, + { + .name = "U-Boot", + .offset = MTDPART_OFS_APPEND, + .size = 6 * (64*(2*2048)), + }, + { + .name = "Environment", + .offset = MTDPART_OFS_APPEND, + .size = 2 * (64*(2*2048)), + }, + { + .name = "Kernel", + .offset = MTDPART_OFS_APPEND, + .size = 12 * (64*(2*2048)), + }, + { + .name = "File System", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + }, +}; + +static int igep3_onenand_setup(void __iomem *onenand_base, int freq) +{ + /* nothing is required to be setup for onenand as of now */ + return 0; +} + +static struct omap_onenand_platform_data igep3_onenand_data = { + .parts = igep3_onenand_partitions, + .nr_parts = ARRAY_SIZE(igep3_onenand_partitions), + .onenand_setup = igep3_onenand_setup, + .dma_channel = -1, /* disable DMA in OMAP OneNAND driver */ +}; + +static struct platform_device igep3_onenand_device = { + .name = "omap2-onenand", + .id = -1, + .dev = { + .platform_data = &igep3_onenand_data, + }, +}; + +void __init igep3_flash_init(void) +{ + u8 cs = 0; + u8 onenandcs = GPMC_CS_NUM + 1; + + while (cs < GPMC_CS_NUM) { + u32 ret = 0; + ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG1); + + /* Check if NAND/oneNAND is configured */ + if ((ret & 0xC00) == 0x800) + /* NAND found */ + pr_err("IGEP: Unsupported NAND found\n"); + else { + ret = gpmc_cs_read_reg(cs, GPMC_CS_CONFIG7); + if ((ret & 0x3F) == (ONENAND_MAP >> 24)) + /* ONENAND found */ + onenandcs = cs; + } + cs++; + } + if (onenandcs > GPMC_CS_NUM) { + pr_err("IGEP: Unable to find configuration in GPMC\n"); + return; + } + + if (onenandcs < GPMC_CS_NUM) { + igep3_onenand_data.cs = onenandcs; + if (platform_device_register(&igep3_onenand_device) < 0) + pr_err("IGEP: Unable to register OneNAND device\n"); + } +} + +#else +void __init igep3_flash_init(void) {} +#endif + +static struct omap_board_config_kernel igep3_config[] __initdata = { +}; + +static struct regulator_consumer_supply igep3_vmmc1_supply = { + .supply = "vmmc", +}; + +static struct regulator_consumer_supply igep3_vmmc2_supply = { + .supply = "vmmc", +}; + +/* VMMC1 for OMAP VDD_MMC1 (i/o) and MMC1 card */ +static struct regulator_init_data igep3_vmmc1 = { + .constraints = { + .min_uV = 1850000, + .max_uV = 3150000, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &igep3_vmmc1_supply, +}; + +/* VMMC2 for OMAP VDD_MMC2 (i/o) and MMC2 WIFI */ +static struct regulator_init_data igep3_vmmc2 = { + .constraints = { + .min_uV = 1850000, + .max_uV = 3150000, + .valid_modes_mask = REGULATOR_MODE_NORMAL + | REGULATOR_MODE_STANDBY, + .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE + | REGULATOR_CHANGE_MODE + | REGULATOR_CHANGE_STATUS, + }, + .num_consumer_supplies = 1, + .consumer_supplies = &igep3_vmmc2_supply, +}; + +static struct omap2_hsmmc_info mmc[] = { + [0] = { + .mmc = 1, + .wires = 4, + .gpio_cd = -EINVAL, + .gpio_wp = -EINVAL, + }, + [1] = { + .mmc = 2, + .wires = 4, + .gpio_cd = -EINVAL, + .gpio_wp = -EINVAL, + }, + {} /* Terminator */ +}; + +#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE) +#include + +static struct gpio_led igep3_gpio_leds[] = { + [0] = { + .name = "led0:red", + .gpio = IGEP3_GPIO_LED0_RED, + .default_trigger = "default-off", + .active_low = true, + }, + [1] = { + .name = "led0:green", + .gpio = IGEP3_GPIO_LED0_GREEN, + .default_trigger = "default-off", + .active_low = true, + }, + [2] = { + .name = "led1:red", + .gpio = IGEP3_GPIO_LED1_RED, + .default_trigger = "default-off", + .active_low = true, + }, + [3] = { + .name = "led1:green", + .default_trigger = "heartbeat", + .gpio = -EINVAL, /* gets replaced */ + .active_low = true, + }, +}; + +static struct gpio_led_platform_data igep3_led_pdata = { + .leds = igep3_gpio_leds, + .num_leds = ARRAY_SIZE(igep3_gpio_leds), +}; + +static struct platform_device igep3_led_device = { + .name = "leds-gpio", + .id = -1, + .dev = { + .platform_data = &igep3_led_pdata, + }, +}; + +static void __init igep3_init_led(void) +{ + platform_device_register(&igep3_led_device); +} + +#else +static inline void igep3_init_led(void) +{ + if ((gpio_request(IGEP3_GPIO_LED0_RED, "led0:red") == 0) && + (gpio_direction_output(IGEP3_GPIO_LED0_RED, 1) == 0)) { + gpio_export(IGEP3_GPIO_LED0_RED, 0); + gpio_set_value(IGEP3_GPIO_LED0_RED, 1); + } else + pr_warning("IGEP: Could not obtain gpio GPIO_LED0_RED\n"); + + if ((gpio_request(IGEP3_GPIO_LED0_GREEN, "led0:green") == 0) && + (gpio_direction_output(IGEP3_GPIO_LED0_GREEN, 1) == 0)) { + gpio_export(IGEP3_GPIO_LED0_GREEN, 0); + gpio_set_value(IGEP3_GPIO_LED0_GREEN, 1); + } else + pr_warning("IGEP: Could not obtain gpio GPIO_LED0_GREEN\n"); + + if ((gpio_request(IGEP3_GPIO_LED1_RED, "led1:red") == 0) && + (gpio_direction_output(IGEP3_GPIO_LED1_RED, 1) == 0)) { + gpio_export(IGEP3_GPIO_LED1_RED, 0); + gpio_set_value(IGEP3_GPIO_LED1_RED, 1); + } else + pr_warning("IGEP: Could not obtain gpio GPIO_LED1_RED\n"); +} +#endif + +static int igep3_twl_gpio_setup(struct device *dev, + unsigned gpio, unsigned ngpio) +{ + /* gpio + 0 is "mmc0_cd" (input/IRQ) */ + mmc[0].gpio_cd = gpio + 0; + omap2_hsmmc_init(mmc); + + /* link regulators to MMC adapters ... we "know" the + * regulators will be set up only *after* we return. + */ + igep3_vmmc1_supply.dev = mmc[0].dev; + igep3_vmmc2_supply.dev = mmc[1].dev; + + /* REVISIT: need ehci-omap hooks for external VBUS + * power switch and overcurrent detect + */ + gpio_request(gpio + 1, "GPIO_EHCI_NOC"); + gpio_direction_input(gpio + 1); + + /* TWL4030_GPIO_MAX + 0 == ledA, GPIO_USBH_CPEN (out, active low) */ + gpio_request(gpio + TWL4030_GPIO_MAX, "GPIO_USB_CPEN"); + gpio_direction_output(gpio + TWL4030_GPIO_MAX, 0); + + /* TWL4030_GPIO_MAX + 1 == ledB (out, active low LED) */ +#if !defined(CONFIG_LEDS_GPIO) && !defined(CONFIG_LEDS_GPIO_MODULE) + if ((gpio_request(gpio + TWL4030_GPIO_MAX + 1, "led1:green") == 0) && + (gpio_direction_output(gpio + TWL4030_GPIO_MAX + 1, 1) == 0)) { + gpio_export(gpio + TWL4030_GPIO_MAX + 1, 0); + gpio_set_value(gpio + TWL4030_GPIO_MAX + 1, 0); + } else + pr_warning("IGEP: Could not obtain gpio GPIO_LED1_GREEN\n"); +#else + igep3_gpio_leds[3].gpio = gpio + TWL4030_GPIO_MAX + 1; +#endif + + return 0; +}; + +static struct twl4030_gpio_platform_data igep3_gpio_data = { + .gpio_base = OMAP_MAX_GPIO_LINES, + .irq_base = TWL4030_GPIO_IRQ_BASE, + .irq_end = TWL4030_GPIO_IRQ_END, + .use_leds = true, + .setup = igep3_twl_gpio_setup, +}; + +static struct twl4030_usb_data igep3_usb_data = { + .usb_mode = T2_USB_MODE_ULPI, +}; + +static void __init igep3_init_irq(void) +{ + omap_board_config = igep3_config; + omap_board_config_size = ARRAY_SIZE(igep3_config); + omap2_init_common_hw(m65kxxxxam_sdrc_params, m65kxxxxam_sdrc_params); + omap_init_irq(); + omap_gpio_init(); +} + +static struct twl4030_platform_data igep3_twldata = { + .irq_base = TWL4030_IRQ_BASE, + .irq_end = TWL4030_IRQ_END, + + /* platform_data for children goes here */ + .usb = &igep3_usb_data, + .gpio = &igep3_gpio_data, + .vmmc1 = &igep3_vmmc1, + .vmmc2 = &igep3_vmmc2, +}; + +static struct i2c_board_info __initdata igep3_i2c_boardinfo[] = { + { + I2C_BOARD_INFO("twl4030", 0x48), + .flags = I2C_CLIENT_WAKE, + .irq = INT_34XX_SYS_NIRQ, + .platform_data = &igep3_twldata, + }, +}; + +static int __init igep3_i2c_init(void) +{ + omap_register_i2c_bus(1, 2600, igep3_i2c_boardinfo, + ARRAY_SIZE(igep3_i2c_boardinfo)); + + return 0; +} + +static struct omap_musb_board_data musb_board_data = { + .interface_type = MUSB_INTERFACE_ULPI, + .mode = MUSB_OTG, + .power = 100, +}; + +static void __init igep3_init_wifi_bt(void) +{ + /* Configure MUX values for W-LAN + Bluetooth GPIO's */ + omap_mux_init_gpio(IGEP3_GPIO_WIFI_NPD, OMAP_PIN_OUTPUT); + omap_mux_init_gpio(IGEP3_GPIO_WIFI_NRESET, OMAP_PIN_OUTPUT); + omap_mux_init_gpio(IGEP3_GPIO_BT_NRESET, OMAP_PIN_OUTPUT); + + /* Set GPIO's for W-LAN + Bluetooth combo module */ + if ((gpio_request(IGEP3_GPIO_WIFI_NPD, "GPIO_WIFI_NPD") == 0) && + (gpio_direction_output(IGEP3_GPIO_WIFI_NPD, 1) == 0)) { + gpio_export(IGEP3_GPIO_WIFI_NPD, 0); + } else + pr_warning("IGEP: Could not obtain gpio GPIO_WIFI_NPD\n"); + + if ((gpio_request(IGEP3_GPIO_WIFI_NRESET, "GPIO_WIFI_NRESET") == 0) && + (gpio_direction_output(IGEP3_GPIO_WIFI_NRESET, 1) == 0)) { + gpio_export(IGEP3_GPIO_WIFI_NRESET, 0); + gpio_set_value(IGEP3_GPIO_WIFI_NRESET, 0); + udelay(10); + gpio_set_value(IGEP3_GPIO_WIFI_NRESET, 1); + } else + pr_warning("IGEP: Could not obtain gpio GPIO_WIFI_NRESET\n"); + + if ((gpio_request(IGEP3_GPIO_BT_NRESET, "GPIO_BT_NRESET") == 0) && + (gpio_direction_output(IGEP3_GPIO_BT_NRESET, 1) == 0)) { + gpio_export(IGEP3_GPIO_BT_NRESET, 0); + } else + pr_warning("IGEP: Could not obtain gpio GPIO_BT_NRESET\n"); +} + +#ifdef CONFIG_OMAP_MUX +static struct omap_board_mux board_mux[] __initdata = { + { .reg_offset = OMAP_MUX_TERMINATOR }, +}; +#else +#define board_mux NULL +#endif + +static void __init igep3_init(void) +{ + omap3_mux_init(board_mux, OMAP_PACKAGE_CBB); + + omap_serial_init(); + usb_musb_init(&musb_board_data); + + igep3_i2c_init(); + igep3_flash_init(); + igep3_init_wifi_bt(); + igep3_init_led(); +} + +static void __init igep3_map_io(void) +{ + omap2_set_globals_343x(); + omap34xx_map_common_io(); +} + +MACHINE_START(IGEP0030, "IGEP OMAP3 module") + .phys_io = 0x48000000, + .io_pg_offst = ((0xfa000000) >> 18) & 0xfffc, + .boot_params = 0x80000100, + .map_io = igep3_map_io, + .init_irq = igep3_init_irq, + .init_machine = igep3_init, + .timer = &omap_timer, +MACHINE_END