summaryrefslogtreecommitdiff
path: root/arch/arm/mach-msm/devices_htc.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-msm/devices_htc.c')
-rw-r--r--arch/arm/mach-msm/devices_htc.c450
1 files changed, 450 insertions, 0 deletions
diff --git a/arch/arm/mach-msm/devices_htc.c b/arch/arm/mach-msm/devices_htc.c
new file mode 100644
index 000000000000..fad7dfb1bcc4
--- /dev/null
+++ b/arch/arm/mach-msm/devices_htc.c
@@ -0,0 +1,450 @@
+/* linux/arch/arm/mach-msm/devices.c
+ *
+ * Copyright (C) 2008 Google, Inc.
+ * Copyright (C) 2007-2009 HTC Corporation.
+ * Author: Thomas Tsai <thomas_tsai@htc.com>
+ *
+ * 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/platform_device.h>
+
+#include <linux/dma-mapping.h>
+#include <mach/msm_iomap.h>
+#include <mach/dma.h>
+#include "gpio_chip.h"
+#include "devices.h"
+#include <mach/board.h>
+#include <mach/board_htc.h>
+#include <mach/msm_hsusb.h>
+#include <linux/usb/mass_storage_function.h>
+#include <linux/usb/android.h>
+
+#include <asm/mach/flash.h>
+#include <asm/setup.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+#include <linux/delay.h>
+#include <linux/android_pmem.h>
+#include <mach/msm_rpcrouter.h>
+#include <mach/msm_iomap.h>
+#include <asm/mach/mmc.h>
+
+static char *df_serialno = "000000000000";
+
+#if 0
+struct platform_device *devices[] __initdata = {
+ &msm_device_nand,
+ &msm_device_smd,
+ &msm_device_i2c,
+};
+
+void __init msm_add_devices(void)
+{
+ platform_add_devices(devices, ARRAY_SIZE(devices));
+}
+#endif
+
+#define HSUSB_API_INIT_PHY_PROC 2
+#define HSUSB_API_PROG 0x30000064
+#define HSUSB_API_VERS 0x10001
+static void internal_phy_reset(void)
+{
+ struct msm_rpc_endpoint *usb_ep;
+ int rc;
+ struct hsusb_phy_start_req {
+ struct rpc_request_hdr hdr;
+ } req;
+
+ printk(KERN_INFO "msm_hsusb_phy_reset\n");
+
+ usb_ep = msm_rpc_connect(HSUSB_API_PROG, HSUSB_API_VERS, 0);
+ if (IS_ERR(usb_ep)) {
+ printk(KERN_ERR "%s: init rpc failed! error: %ld\n",
+ __func__, PTR_ERR(usb_ep));
+ goto close;
+ }
+ rc = msm_rpc_call(usb_ep, HSUSB_API_INIT_PHY_PROC,
+ &req, sizeof(req), 5 * HZ);
+ if (rc < 0)
+ printk(KERN_ERR "%s: rpc call failed! (%d)\n", __func__, rc);
+
+close:
+ msm_rpc_close(usb_ep);
+}
+
+/* adjust eye diagram, disable vbusvalid interrupts */
+static int hsusb_phy_init_seq[] = { 0x40, 0x31, 0x1D, 0x0D, 0x1D, 0x10, -1 };
+
+#ifdef CONFIG_USB_FUNCTION
+static char *usb_functions[] = {
+#if defined(CONFIG_USB_FUNCTION_MASS_STORAGE) || defined(CONFIG_USB_FUNCTION_UMS)
+ "usb_mass_storage",
+#endif
+#ifdef CONFIG_USB_FUNCTION_ADB
+ "adb",
+#endif
+};
+
+static struct msm_hsusb_product usb_products[] = {
+ {
+ .product_id = 0x0c01,
+ .functions = 0x00000041, /* usb_mass_storage */
+ },
+ {
+ .product_id = 0x0c02,
+ .functions = 0x00000043, /* usb_mass_storage + adb */
+ },
+};
+#endif
+
+struct msm_hsusb_platform_data msm_hsusb_pdata = {
+ .phy_reset = internal_phy_reset,
+ .phy_init_seq = hsusb_phy_init_seq,
+#ifdef CONFIG_USB_FUNCTION
+ .vendor_id = 0x0bb4,
+ .product_id = 0x0c02,
+ .version = 0x0100,
+ .product_name = "Android Phone",
+ .manufacturer_name = "HTC",
+
+ .functions = usb_functions,
+ .num_functions = ARRAY_SIZE(usb_functions),
+ .products = usb_products,
+ .num_products = ARRAY_SIZE(usb_products),
+#endif
+};
+
+#ifdef CONFIG_USB_FUNCTION
+static struct usb_mass_storage_platform_data mass_storage_pdata = {
+ .nluns = 1,
+ .buf_size = 16384,
+ .vendor = "HTC ",
+ .product = "Android Phone ",
+ .release = 0x0100,
+};
+
+static struct platform_device usb_mass_storage_device = {
+ .name = "usb_mass_storage",
+ .id = -1,
+ .dev = {
+ .platform_data = &mass_storage_pdata,
+ },
+};
+#endif
+
+#ifdef CONFIG_USB_ANDROID
+static struct android_usb_platform_data android_usb_pdata = {
+ .vendor_id = 0x0bb4,
+ .product_id = 0x0c01,
+ .adb_product_id = 0x0c02,
+ .version = 0x0100,
+ .product_name = "Android Phone",
+ .manufacturer_name = "HTC",
+ .nluns = 1,
+};
+
+static struct platform_device android_usb_device = {
+ .name = "android_usb",
+ .id = -1,
+ .dev = {
+ .platform_data = &android_usb_pdata,
+ },
+};
+#endif
+
+void __init msm_add_usb_devices(void (*phy_reset) (void))
+{
+ /* setup */
+ if (phy_reset)
+ msm_hsusb_pdata.phy_reset = phy_reset;
+ msm_device_hsusb.dev.platform_data = &msm_hsusb_pdata;
+ platform_device_register(&msm_device_hsusb);
+#ifdef CONFIG_USB_FUNCTION_MASS_STORAGE
+ platform_device_register(&usb_mass_storage_device);
+#endif
+#ifdef CONFIG_USB_ANDROID
+ platform_device_register(&android_usb_device);
+#endif
+}
+
+static struct android_pmem_platform_data pmem_pdata = {
+ .name = "pmem",
+ .no_allocator = 1,
+ .cached = 1,
+};
+
+static struct android_pmem_platform_data pmem_adsp_pdata = {
+ .name = "pmem_adsp",
+ .no_allocator = 0,
+ .cached = 0,
+};
+
+static struct android_pmem_platform_data pmem_camera_pdata = {
+ .name = "pmem_camera",
+ .no_allocator = 0,
+ .cached = 0,
+};
+
+static struct android_pmem_platform_data pmem_gpu0_pdata = {
+ .name = "pmem_gpu0",
+ .no_allocator = 1,
+ .cached = 0,
+ .buffered = 1,
+};
+
+static struct android_pmem_platform_data pmem_gpu1_pdata = {
+ .name = "pmem_gpu1",
+ .no_allocator = 1,
+ .cached = 0,
+ .buffered = 1,
+};
+
+static struct platform_device pmem_device = {
+ .name = "android_pmem",
+ .id = 0,
+ .dev = { .platform_data = &pmem_pdata },
+};
+
+static struct platform_device pmem_adsp_device = {
+ .name = "android_pmem",
+ .id = 1,
+ .dev = { .platform_data = &pmem_adsp_pdata },
+};
+
+static struct platform_device pmem_gpu0_device = {
+ .name = "android_pmem",
+ .id = 2,
+ .dev = { .platform_data = &pmem_gpu0_pdata },
+};
+
+static struct platform_device pmem_gpu1_device = {
+ .name = "android_pmem",
+ .id = 3,
+ .dev = { .platform_data = &pmem_gpu1_pdata },
+};
+
+static struct platform_device pmem_camera_device = {
+ .name = "android_pmem",
+ .id = 4,
+ .dev = { .platform_data = &pmem_camera_pdata },
+};
+
+static struct resource ram_console_resource[] = {
+ {
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device ram_console_device = {
+ .name = "ram_console",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(ram_console_resource),
+ .resource = ram_console_resource,
+};
+
+void __init msm_add_mem_devices(struct msm_pmem_setting *setting)
+{
+ if (setting->pmem_size) {
+ pmem_pdata.start = setting->pmem_start;
+ pmem_pdata.size = setting->pmem_size;
+ platform_device_register(&pmem_device);
+ }
+
+ if (setting->pmem_adsp_size) {
+ pmem_adsp_pdata.start = setting->pmem_adsp_start;
+ pmem_adsp_pdata.size = setting->pmem_adsp_size;
+ platform_device_register(&pmem_adsp_device);
+ }
+
+ if (setting->pmem_gpu0_size) {
+ pmem_gpu0_pdata.start = setting->pmem_gpu0_start;
+ pmem_gpu0_pdata.size = setting->pmem_gpu0_size;
+ platform_device_register(&pmem_gpu0_device);
+ }
+
+ if (setting->pmem_gpu1_size) {
+ pmem_gpu1_pdata.start = setting->pmem_gpu1_start;
+ pmem_gpu1_pdata.size = setting->pmem_gpu1_size;
+ platform_device_register(&pmem_gpu1_device);
+ }
+
+ if (setting->pmem_camera_size) {
+ pmem_camera_pdata.start = setting->pmem_camera_start;
+ pmem_camera_pdata.size = setting->pmem_camera_size;
+ platform_device_register(&pmem_camera_device);
+ }
+
+ if (setting->ram_console_size) {
+ ram_console_resource[0].start = setting->ram_console_start;
+ ram_console_resource[0].end = setting->ram_console_start
+ + setting->ram_console_size - 1;
+ platform_device_register(&ram_console_device);
+ }
+}
+
+#define PM_LIBPROG 0x30000061
+#if (CONFIG_MSM_AMSS_VERSION == 6220) || (CONFIG_MSM_AMSS_VERSION == 6225)
+#define PM_LIBVERS 0xfb837d0b
+#else
+#define PM_LIBVERS 0x10001
+#endif
+
+#if 0
+static struct platform_device *msm_serial_devices[] __initdata = {
+ &msm_device_uart1,
+ &msm_device_uart2,
+ &msm_device_uart3,
+ #ifdef CONFIG_SERIAL_MSM_HS
+ &msm_device_uart_dm1,
+ &msm_device_uart_dm2,
+ #endif
+};
+
+int __init msm_add_serial_devices(unsigned num)
+{
+ if (num > MSM_SERIAL_NUM)
+ return -EINVAL;
+
+ return platform_device_register(msm_serial_devices[num]);
+}
+#endif
+
+#define ATAG_SMI 0x4d534D71
+/* setup calls mach->fixup, then parse_tags, parse_cmdline
+ * We need to setup meminfo in mach->fixup, so this function
+ * will need to traverse each tag to find smi tag.
+ */
+int __init parse_tag_smi(const struct tag *tags)
+{
+ int smi_sz = 0, find = 0;
+ struct tag *t = (struct tag *)tags;
+
+ for (; t->hdr.size; t = tag_next(t)) {
+ if (t->hdr.tag == ATAG_SMI) {
+ printk(KERN_DEBUG "find the smi tag\n");
+ find = 1;
+ break;
+ }
+ }
+ if (!find)
+ return -1;
+
+ printk(KERN_DEBUG "parse_tag_smi: smi size = %d\n", t->u.mem.size);
+ smi_sz = t->u.mem.size;
+ return smi_sz;
+}
+__tagtable(ATAG_SMI, parse_tag_smi);
+
+
+#define ATAG_HWID 0x4d534D72
+int __init parse_tag_hwid(const struct tag *tags)
+{
+ int hwid = 0, find = 0;
+ struct tag *t = (struct tag *)tags;
+
+ for (; t->hdr.size; t = tag_next(t)) {
+ if (t->hdr.tag == ATAG_HWID) {
+ printk(KERN_DEBUG "find the hwid tag\n");
+ find = 1;
+ break;
+ }
+ }
+
+ if (find)
+ hwid = t->u.revision.rev;
+ printk(KERN_DEBUG "parse_tag_hwid: hwid = 0x%x\n", hwid);
+ return hwid;
+}
+__tagtable(ATAG_HWID, parse_tag_hwid);
+
+#define ATAG_SKUID 0x4d534D73
+int __init parse_tag_skuid(const struct tag *tags)
+{
+ int skuid = 0, find = 0;
+ struct tag *t = (struct tag *)tags;
+
+ for (; t->hdr.size; t = tag_next(t)) {
+ if (t->hdr.tag == ATAG_SKUID) {
+ printk(KERN_DEBUG "find the skuid tag\n");
+ find = 1;
+ break;
+ }
+ }
+
+ if (find)
+ skuid = t->u.revision.rev;
+ printk(KERN_DEBUG "parse_tag_skuid: hwid = 0x%x\n", skuid);
+ return skuid;
+}
+__tagtable(ATAG_SKUID, parse_tag_skuid);
+
+#define ATAG_ENGINEERID 0x4d534D75
+int __init parse_tag_engineerid(const struct tag *tags)
+{
+ int engineerid = 0, find = 0;
+ struct tag *t = (struct tag *)tags;
+
+ for (; t->hdr.size; t = tag_next(t)) {
+ if (t->hdr.tag == ATAG_ENGINEERID) {
+ printk(KERN_DEBUG "find the engineer tag\n");
+ find = 1;
+ break;
+ }
+ }
+
+ if (find)
+ engineerid = t->u.revision.rev;
+ printk(KERN_DEBUG "parse_tag_engineerid: hwid = 0x%x\n", engineerid);
+ return engineerid;
+}
+__tagtable(ATAG_ENGINEERID, parse_tag_engineerid);
+
+static int mfg_mode;
+int __init board_mfg_mode_init(char *s)
+{
+ if (!strcmp(s, "normal"))
+ mfg_mode = 0;
+ else if (!strcmp(s, "factory2"))
+ mfg_mode = 1;
+ else if (!strcmp(s, "recovery"))
+ mfg_mode = 2;
+ else if (!strcmp(s, "charge"))
+ mfg_mode = 3;
+
+ return 1;
+}
+__setup("androidboot.mode=", board_mfg_mode_init);
+
+
+int board_mfg_mode(void)
+{
+ return mfg_mode;
+}
+
+static int __init board_serialno_setup(char *serialno)
+{
+ char *str;
+
+ if (board_mfg_mode() || !strlen(serialno))
+ str = df_serialno;
+ else
+ str = serialno;
+#ifdef CONFIG_USB_FUNCTION
+ msm_hsusb_pdata.serial_number = str;
+#endif
+#ifdef CONFIG_USB_ANDROID
+ android_usb_pdata.serial_number = str;
+#endif
+ return 1;
+}
+
+__setup("androidboot.serialno=", board_serialno_setup);