@@ -161,6 +161,12 @@ config MACH_OMAP_GENERIC
custom OMAP boards. Say Y here if you have a custom
board.
+config MACH_HTCOXYGEN
+ bool "HTC Oxygen"
+ depends on ARCH_OMAP850
+ help
+ HTC Oxygen smartphone support (AKA HTC S310, ...)
+
comment "OMAP CPU Speed"
depends on ARCH_OMAP1
@@ -39,6 +39,7 @@ obj-$(CONFIG_MACH_NOKIA770) += board-nokia770.o
obj-$(CONFIG_MACH_AMS_DELTA) += board-ams-delta.o
obj-$(CONFIG_MACH_SX1) += board-sx1.o board-sx1-mmc.o
obj-$(CONFIG_MACH_HERALD) += board-htcherald.o
+obj-$(CONFIG_MACH_HTCOXYGEN) += board-htcoxygen.o
ifeq ($(CONFIG_ARCH_OMAP15XX),y)
# Innovator-1510 FPGA
b/arch/arm/mach-omap1/board-htcoxygen.c
new file mode 100644
@@ -0,0 +1,282 @@
+/*
+ * HTC Oxygen board configuration
+ * Copyright (C) 2010 Marek Belisko <marek.belisko@gmail.com>
+ *
+ * Based on board-herald.c file from wing-linux project:
+ * Copyright (C) 2009 Cory Maccarrone <darkstar6262@gmail.com>
+ * Copyright (C) 2009 Wing Linux
+ *
+ * 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., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+#include <linux/bootmem.h>
+#include <linux/io.h>
+#include <linux/gpio.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <plat/omap7xx.h>
+#include <plat/common.h>
+#include <plat/board.h>
+#include <plat/keypad.h>
+#include <plat/usb.h>
+
+#include <mach/irqs.h>
+
+#include <linux/delay.h>
+
+/* LCD register definition */
+#define OMAP_LCDC_CONTROL (0xfffec000 + 0x00)
+#define OMAP_LCDC_STATUS (0xfffec000 + 0x10)
+#define OMAP_DMA_LCD_CCR (0xfffee300 + 0xc2)
+#define OMAP_DMA_LCD_CTRL (0xfffee300 + 0xc4)
+#define OMAP_LCDC_CTRL_LCD_EN (1 << 0)
+#define OMAP_LCDC_STAT_DONE (1 << 0)
+
+static struct omap_lcd_config htcoxygen_lcd_config __initdata = {
+ .ctrl_name = "internal",
+};
+
+static struct omap_board_config_kernel htcoxygen_config[] __initdata = {
+ { OMAP_TAG_LCD, &htcoxygen_lcd_config },
+};
+
+/* Keyboard definition */
+
+static int htc_oxygen_keymap[] = {
+ KEY(1,3,KEY_ENTER),
+ KEY(3,3,KEY_MENU),
+ KEY(2,3,KEY_BACKSPACE),
+ KEY(4,3,KEY_BACKSPACE),
+ KEY(3,5,KEY_LEFTALT),
+ KEY(4,5,KEY_RIGHTALT),
+ KEY(1,0,KEY_KP1),
+ KEY(2,0,KEY_KP2),
+ KEY(3,0,KEY_KP3),
+ KEY(4,0,KEY_KP4),
+ KEY(1,1,KEY_KP5),
+ KEY(2,1,KEY_KP6),
+ KEY(3,1,KEY_KP7),
+ KEY(4,1,KEY_KP8),
+ KEY(1,2,KEY_KP9),
+ KEY(3,2,KEY_KPASTERISK),
+ KEY(2,2,KEY_KP0),
+ KEY(4,2,KEY_KPSLASH),
+ KEY(0,1,KEY_VOLUMEUP),
+ KEY(0,3,KEY_VOLUMEDOWN),
+ KEY(0,2,KEY_CAMERA),
+ 0
+};
+
+struct omap_kp_platform_data htcoxygen_kp_data = {
+ .rows = 7,
+ .cols = 7,
+ .delay = 20,
+ .rep = 1,
+ .keymap = htc_oxygen_keymap,
+};
+
+static struct resource kp_resources[] = {
+ [0] = {
+ .start = INT_7XX_MPUIO_KEYPAD,
+ .end = INT_7XX_MPUIO_KEYPAD,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device kp_device = {
+ .name = "omap-keypad",
+ .id = -1,
+ .dev = {
+ .platform_data = &htcoxygen_kp_data,
+ },
+ .num_resources = ARRAY_SIZE(kp_resources),
+ .resource = kp_resources,
+};
+
+/* USB Device */
+static struct omap_usb_config htcoxygen_usb_config __initdata = {
+ .otg = 0,
+ .register_host = 0,
+ .register_dev = 1,
+ .hmc_mode = 4,
+ .pins[0] = 2,
+};
+
+/* LCD Device resources */
+static struct platform_device lcd_device = {
+ .name = "lcd_htcoxygen",
+ .id = -1,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &kp_device,
+ &lcd_device,
+};
+
+/*
+ * Init functions from here on
+ */
+
+static void __init htcoxygen_lcd_init(void)
+{
+ u32 reg;
+ unsigned int tries = 200;
+
+ /* disable controller if active */
+ reg = omap_readl(OMAP_LCDC_CONTROL);
+ if (reg & OMAP_LCDC_CTRL_LCD_EN) {
+ reg &= ~OMAP_LCDC_CTRL_LCD_EN;
+ omap_writel(reg, OMAP_LCDC_CONTROL);
+
+ /* wait for end of frame */
+ while (!(omap_readl(OMAP_LCDC_STATUS) & OMAP_LCDC_STAT_DONE)) {
+ tries--;
+ if (!tries)
+ break;
+ }
+ if (!tries)
+ printk(KERN_WARNING "Timeout waiting for end of frame "
+ "-- LCD may not be available\n");
+
+ /* turn off DMA */
+ reg = omap_readw(OMAP_DMA_LCD_CCR);
+ reg &= ~(1 << 7);
+ omap_writew(reg, OMAP_DMA_LCD_CCR);
+
+ reg = omap_readw(OMAP_DMA_LCD_CTRL);
+ reg &= ~(1 << 8);
+ omap_writew(reg, OMAP_DMA_LCD_CTRL);
+ }
+}
+
+static void __init htcoxygen_map_io(void)
+{
+ omap1_map_common_io();
+
+ /*
+ * The LCD panel must be disabled and DMA turned off here, as doing
+ * it later causes the LCD never to reinitialize.
+ */
+ htcoxygen_lcd_init();
+
+ printk(KERN_INFO "htcoxygen_map_io done.\n");
+}
+
+static void __init htcoxygen_disable_watchdog(void)
+{
+ /* Disable watchdog if running */
+ if (omap_readl(OMAP_WDT_TIMER_MODE) & 0x8000) {
+ /*
+ * disable a potentially running watchdog timer before
+ * it kills us.
+ */
+ printk(KERN_WARNING "OMAP850 Watchdog seems to be activated,
disabling it for now.\n");
+ omap_writel(0xF5, OMAP_WDT_TIMER_MODE);
+ omap_writel(0xA0, OMAP_WDT_TIMER_MODE);
+ }
+}
+
+#define HTCOXYGEN_GPIO_USB_EN1 33
+#define HTCOXYGEN_GPIO_USB_EN2 73
+#define HTCOXYGEN_GPIO_USB_DM 35
+#define HTCOXYGEN_GPIO_USB_DP 36
+
+static void __init htcoxygen_usb_enable(void)
+{
+ unsigned int tries = 20;
+ unsigned int value = 0;
+
+ /* Request the GPIOs we need to control here */
+ if (gpio_request(HTCOXYGEN_GPIO_USB_EN1, "oxygen_usb") < 0)
+ goto err1;
+
+ if (gpio_request(HTCOXYGEN_GPIO_USB_EN2, "oxygen_usb") < 0)
+ goto err2;
+
+ if (gpio_request(HTCOXYGEN_GPIO_USB_DM, "oxygen_usb") < 0)
+ goto err3;
+
+ if (gpio_request(HTCOXYGEN_GPIO_USB_DP, "oxygen_usb") < 0)
+ goto err4;
+
+ /* force USB_EN GPIO to 0 */
+ do {
+ /* output low */
+ gpio_direction_output(HTCOXYGEN_GPIO_USB_EN1, 0);
+ } while ((value = gpio_get_value(HTCOXYGEN_GPIO_USB_EN1)) == 1 &&
+ --tries);
+
+ if (value == 1)
+ printk(KERN_WARNING "Unable to reset USB, trying to continue\n");
+
+ gpio_direction_output(HTCOXYGEN_GPIO_USB_EN2, 0); /* output low */
+ gpio_direction_input(HTCOXYGEN_GPIO_USB_DM); /* input */
+ gpio_direction_input(HTCOXYGEN_GPIO_USB_DP); /* input */
+
+ goto done;
+
+err4:
+ gpio_free(HTCOXYGEN_GPIO_USB_DM);
+err3:
+ gpio_free(HTCOXYGEN_GPIO_USB_EN2);
+err2:
+ gpio_free(HTCOXYGEN_GPIO_USB_EN1);
+err1:
+ printk(KERN_ERR "Unabled to request GPIO for USB\n");
+done:
+ printk(KERN_INFO "USB setup complete.\n");
+}
+
+static void __init htcoxygen_init(void)
+{
+ printk(KERN_INFO "HTC Oxygen init.\n");
+
+ omap_gpio_init();
+
+ omap_board_config = htcoxygen_config;
+ omap_board_config_size = ARRAY_SIZE(htcoxygen_config);
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+
+ htcoxygen_disable_watchdog();
+
+ htcoxygen_usb_enable();
+ omap_usb_init(&htcoxygen_usb_config);
+}
+
+static void __init htcoxygen_init_irq(void)
+{
+ printk(KERN_INFO "htcoxygen_init_irq.\n");
+ omap1_init_common_hw();
+ omap_init_irq();
+}
+
+MACHINE_START(HTCOXYGEN, "HTC Oxygen")
+ /* Maintainer: Marek Belisko <marek.belisko@gmail.com> */
+ .phys_io = 0xfff00000,
+ .io_pg_offst = ((0xfef00000) >> 18) & 0xfffc,
+ .boot_params = 0x10000100,
+ .map_io = htcoxygen_map_io,
+ .init_irq = htcoxygen_init_irq,
+ .init_machine = htcoxygen_init,
+ .timer = &omap_timer,
+MACHINE_END
@@ -36,6 +36,7 @@ objs-y$(CONFIG_MACH_OMAP3_BEAGLE) += lcd_omap3beagle.o
objs-y$(CONFIG_FB_OMAP_LCD_MIPID) += lcd_mipid.o
objs-y$(CONFIG_MACH_OVERO) += lcd_overo.o
objs-y$(CONFIG_MACH_HERALD) += lcd_htcherald.o
+objs-y$(CONFIG_MACH_HTCOXYGEN) += lcd_htcoxygen.o
omapfb-objs := $(objs-yy)
b/drivers/video/omap/lcd_htcoxygen.c
new file mode 100644
@@ -0,0 +1,129 @@
+/*
+ * File: drivers/video/omap/lcd-oxygen.c
+ *
+ * LCD panel support for the HTC Oxygen.
+ *
+ * Copyright (C) 2010 Marek Belisko <marek.belisko@gmail.com>
+ *
+ * Based on the lcd_htcwizard.c file from the linwizard project:
+ * Copyright (C) linwizard.sourceforge.net
+ * Author: Angelo Arrifano <miknix@gmail.com>
+ * Based on lcd_h4 by Imre Deak <imre.deak@nokia.com>
+ *
+ * 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/module.h>
+#include <linux/platform_device.h>
+
+#include "omapfb.h"
+
+static int htcoxygen_panel_init(struct lcd_panel *panel,
+ struct omapfb_device *fbdev)
+{
+ return 0;
+}
+
+static void htcoxygen_panel_cleanup(struct lcd_panel *panel)
+{
+}
+
+static int htcoxygen_panel_enable(struct lcd_panel *panel)
+{
+ return 0;
+}
+
+static void htcoxygen_panel_disable(struct lcd_panel *panel)
+{
+}
+
+static unsigned long htcoxygen_panel_get_caps(struct lcd_panel *panel)
+{
+ return 0;
+}
+
+struct lcd_panel htcoxygen_panel = {
+ .name = "lcd_oxygen",
+ .config = OMAP_LCDC_PANEL_TFT |
+ OMAP_LCDC_INV_VSYNC |
+ OMAP_LCDC_INV_HSYNC |
+ OMAP_LCDC_HSVS_OPPOSITE,
+ .bpp = 16,
+ .data_lines = 16,
+ .x_res = 176,
+ .y_res = 220,
+ .pixel_clock = 3362,
+ .hsw = 10,
+ .hfp = 45,
+ .hbp = 9,
+ .vsw = 3,
+ .vfp = 3,
+ .vbp = 3,
+ .pcd = 0,
+
+ .init = htcoxygen_panel_init,
+ .cleanup = htcoxygen_panel_cleanup,
+ .enable = htcoxygen_panel_enable,
+ .disable = htcoxygen_panel_disable,
+ .get_caps = htcoxygen_panel_get_caps,
+};
+
+
+static int htcoxygen_panel_probe(struct platform_device *pdev)
+{
+ omapfb_register_panel(&htcoxygen_panel);
+ return 0;
+}
+
+static int htcoxygen_panel_remove(struct platform_device *pdev)
+{
+ return 0;
+}
+
+static int htcoxygen_panel_suspend(struct platform_device *pdev,
+ pm_message_t mesg)
+{
+ return 0;
+}
+
+static int htcoxygen_panel_resume(struct platform_device *pdev)
+{
+ return 0;
+}
+
+struct platform_driver htcoxygen_panel_driver = {
+ .probe = htcoxygen_panel_probe,
+ .remove = htcoxygen_panel_remove,
+ .suspend = htcoxygen_panel_suspend,
+ .resume = htcoxygen_panel_resume,
+ .driver = {
+ .name = "lcd_htcoxygen",
+ .owner = THIS_MODULE,
+ },
+};
+
+static int __init htcoxygen_panel_drv_init(void)
+{
+ return platform_driver_register(&htcoxygen_panel_driver);
+}
+
+static void __exit htcoxygen_panel_drv_cleanup(void)
+{
+ platform_driver_unregister(&htcoxygen_panel_driver);
+}
+
+module_init(htcoxygen_panel_drv_init);
+module_exit(htcoxygen_panel_drv_cleanup);
+