/* linux/arch/arm/mach-msm/devices.c * * Copyright (C) 2008 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 #include #include #include #include #include #include #include #include #include "smd_private.h" #include #include #include #include #include #include "devices.h" #include "clock.h" #include "proc_comm.h" #include #include #include #ifdef CONFIG_USB_FUNCTION #include #endif #ifdef CONFIG_PMIC8058 #include #endif static char *df_serialno = "000000000000"; static char *board_sn; int usb_phy_error; #define HSUSB_API_INIT_PHY_PROC 2 #define HSUSB_API_PROG 0x30000064 #define HSUSB_API_VERS MSM_RPC_VERS(1, 1) #define MFG_GPIO_TABLE_MAX_SIZE 0x400 static unsigned char mfg_gpio_table[MFG_GPIO_TABLE_MAX_SIZE]; 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)); return; } 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); msm_rpc_close(usb_ep); } static void *usb_base; #define MSM_USB_BASE ((unsigned)usb_base) static unsigned ulpi_read(void __iomem *usb_base, unsigned reg) { unsigned timeout = 100000; /* initiate read operation */ writel(ULPI_RUN | ULPI_READ | ULPI_ADDR(reg), USB_ULPI_VIEWPORT); /* wait for completion */ while ((readl(USB_ULPI_VIEWPORT) & ULPI_RUN) && (--timeout)) cpu_relax(); if (timeout == 0) { printk(KERN_ERR "ulpi_read: timeout %08x\n", readl(USB_ULPI_VIEWPORT)); return 0xffffffff; } return ULPI_DATA_READ(readl(USB_ULPI_VIEWPORT)); } static int ulpi_write(void __iomem *usb_base, unsigned val, unsigned reg) { unsigned timeout = 10000; /* initiate write operation */ writel(ULPI_RUN | ULPI_WRITE | ULPI_ADDR(reg) | ULPI_DATA(val), USB_ULPI_VIEWPORT); /* wait for completion */ while ((readl(USB_ULPI_VIEWPORT) & ULPI_RUN) && (--timeout)) cpu_relax(); if (timeout == 0) { printk(KERN_ERR "ulpi_write: timeout\n"); return -1; } return 0; } #define CLKRGM_APPS_RESET_USBH 37 #define CLKRGM_APPS_RESET_USB_PHY 34 static void msm_hsusb_apps_reset_link(int reset) { int ret; unsigned usb_id = CLKRGM_APPS_RESET_USBH; if (reset) ret = msm_proc_comm(PCOM_CLK_REGIME_SEC_RESET_ASSERT, &usb_id, NULL); else ret = msm_proc_comm(PCOM_CLK_REGIME_SEC_RESET_DEASSERT, &usb_id, NULL); if (ret) printk(KERN_INFO "%s: Cannot set reset to %d (%d)\n", __func__, reset, ret); } static void msm_hsusb_apps_reset_phy(void) { int ret; unsigned usb_phy_id = CLKRGM_APPS_RESET_USB_PHY; ret = msm_proc_comm(PCOM_CLK_REGIME_SEC_RESET_ASSERT, &usb_phy_id, NULL); if (ret) { printk(KERN_INFO "%s: Cannot assert (%d)\n", __func__, ret); return; } msleep(1); ret = msm_proc_comm(PCOM_CLK_REGIME_SEC_RESET_DEASSERT, &usb_phy_id, NULL); if (ret) { printk(KERN_INFO "%s: Cannot assert (%d)\n", __func__, ret); return; } } #define ULPI_VERIFY_MAX_LOOP_COUNT 3 static int msm_hsusb_phy_verify_access(void __iomem *usb_base) { int temp; for (temp = 0; temp < ULPI_VERIFY_MAX_LOOP_COUNT; temp++) { if (ulpi_read(usb_base, ULPI_DEBUG) != (unsigned)-1) break; msm_hsusb_apps_reset_phy(); } if (temp == ULPI_VERIFY_MAX_LOOP_COUNT) { pr_err("%s: ulpi read failed for %d times\n", __func__, ULPI_VERIFY_MAX_LOOP_COUNT); return -1; } return 0; } static unsigned msm_hsusb_ulpi_read_with_reset(void __iomem *usb_base, unsigned reg) { int temp; unsigned res; for (temp = 0; temp < ULPI_VERIFY_MAX_LOOP_COUNT; temp++) { res = ulpi_read(usb_base, reg); if (res != -1) return res; msm_hsusb_apps_reset_phy(); } pr_err("%s: ulpi read failed for %d times\n", __func__, ULPI_VERIFY_MAX_LOOP_COUNT); return -1; } static int msm_hsusb_ulpi_write_with_reset(void __iomem *usb_base, unsigned val, unsigned reg) { int temp; int res; for (temp = 0; temp < ULPI_VERIFY_MAX_LOOP_COUNT; temp++) { res = ulpi_write(usb_base, val, reg); if (!res) return 0; msm_hsusb_apps_reset_phy(); } pr_err("%s: ulpi write failed for %d times\n", __func__, ULPI_VERIFY_MAX_LOOP_COUNT); return -1; } static int msm_hsusb_phy_caliberate(void __iomem *usb_base) { int ret; unsigned res; ret = msm_hsusb_phy_verify_access(usb_base); if (ret) return -ETIMEDOUT; res = msm_hsusb_ulpi_read_with_reset(usb_base, ULPI_FUNC_CTRL_CLR); if (res == -1) return -ETIMEDOUT; res = msm_hsusb_ulpi_write_with_reset(usb_base, res | ULPI_SUSPENDM, ULPI_FUNC_CTRL_CLR); if (res) return -ETIMEDOUT; msm_hsusb_apps_reset_phy(); return msm_hsusb_phy_verify_access(usb_base); } #define USB_LINK_RESET_TIMEOUT (msecs_to_jiffies(10)) void msm_hsusb_8x50_phy_reset(void) { u32 temp; unsigned long timeout; printk(KERN_INFO "msm_hsusb_phy_reset\n"); usb_base = ioremap(MSM_HSUSB_PHYS, 4096); msm_hsusb_apps_reset_link(1); msm_hsusb_apps_reset_phy(); msm_hsusb_apps_reset_link(0); /* select ULPI phy */ temp = (readl(USB_PORTSC) & ~PORTSC_PTS); writel(temp | PORTSC_PTS_ULPI, USB_PORTSC); if (msm_hsusb_phy_caliberate(usb_base)) { usb_phy_error = 1; return; } /* soft reset phy */ writel(USBCMD_RESET, USB_USBCMD); timeout = jiffies + USB_LINK_RESET_TIMEOUT; while (readl(USB_USBCMD) & USBCMD_RESET) { if (time_after(jiffies, timeout)) { pr_err("usb link reset timeout\n"); break; } msleep(1); } usb_phy_error = 0; return; } /* adjust eye diagram, disable vbusvalid interrupts */ static int hsusb_phy_init_seq[] = { 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 #if defined(CONFIG_USB_FUNCTION_ADB) "adb", #endif #if defined(CONFIG_USB_FUNCTION_DIAG) "diag", #endif #if defined(CONFIG_USB_FUNCTION_MODEM) "serial", #endif #if defined(CONFIG_USB_FUNCTION_PROJECTOR) "projector", #endif #if defined(CONFIG_USB_FUNCTION_MTP_TUNNEL) "mtp_tunnel", #endif #if defined(CONFIG_USB_FUNCTION_ETHER) "ether", #endif #if defined(CONFIG_USB_FUNCTION_MODEM) "modem", "nmea", #endif }; static struct msm_hsusb_product usb_products[] = { { .product_id = 0x0ff9, .functions = 0x00000001, /* usb_mass_storage */ }, { .product_id = 0x0c02, .functions = 0x00000003, /* usb_mass_storage + adb */ }, { .product_id = 0x0c03, .functions = 0x00000101, /* modem + mass_storage */ }, { .product_id = 0x0c04, .functions = 0x00000103, /* modem + adb + mass_storage */ }, { .product_id = 0x0c05, .functions = 0x00000021, /* Projector + mass_storage */ }, { .product_id = 0x0c06, .functions = 0x00000023, /* Projector + adb + mass_storage */ }, { .product_id = 0x0c07, .functions = 0x0000000B, /* diag + adb + mass_storage */ }, { .product_id = 0x0c08, .functions = 0x00000009, /* diag + mass_storage */ }, { .product_id = 0x0c88, .functions = 0x0000010B, /* adb + mass_storage + diag + modem */ }, { .product_id = 0x0c89, .functions = 0x00000019, /* serial + diag + mass_storage */ }, { .product_id = 0x0c8a, .functions = 0x0000001B, /* serial + diag + adb + mass_storage */ }, { .product_id = 0x0c93, .functions = 0x00000080, /* mtp */ }, { .product_id = 0x0FFE, .functions = 0x00000004, /* internet sharing */ }, }; #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 static struct resource resources_hsusb[] = { { .start = MSM_HSUSB_PHYS, .end = MSM_HSUSB_PHYS + MSM_HSUSB_SIZE, .flags = IORESOURCE_MEM, }, { .start = INT_USB_HS, .end = INT_USB_HS, .flags = IORESOURCE_IRQ, }, #ifdef CONFIG_ARCH_MSM7X30 { .name = "vbus_on", .start = PM8058_IRQ_CHGVAL, .end = PM8058_IRQ_CHGVAL, .flags = IORESOURCE_IRQ, }, #endif }; struct platform_device msm_device_hsusb = { .name = "msm_hsusb", .id = -1, .num_resources = ARRAY_SIZE(resources_hsusb), .resource = resources_hsusb, .dev = { .coherent_dma_mask = 0xffffffff, .platform_data = &msm_hsusb_pdata, }, }; void __init msm_add_usb_devices(void (*phy_reset) (void), void (*phy_shutdown) (void)) { /* setup */ msm_hsusb_pdata.phy_reset = phy_reset; msm_hsusb_pdata.phy_shutdown = phy_shutdown; msm_device_hsusb.dev.platform_data = &msm_hsusb_pdata; platform_device_register(&msm_device_hsusb); #ifdef CONFIG_USB_FUNCTION platform_device_register(&usb_mass_storage_device); #endif } #ifdef CONFIG_USB_FUNCTION void __init msm_set_ums_device_id(int id) { usb_mass_storage_device.id = id; } void __init msm_add_usb_id_pin_function(void (*config_usb_id_gpios)(bool enable)) { /* setup */ msm_hsusb_pdata.config_usb_id_gpios = config_usb_id_gpios; } void __init msm_enable_car_kit_detect(bool enable) { msm_hsusb_pdata.enable_car_kit_detect = enable; } void __init msm_init_ums_lun(int lun_num) { if (lun_num > 0) mass_storage_pdata.nluns = lun_num; } void __init msm_register_usb_phy_init_seq(int *int_seq) { if (int_seq) msm_hsusb_pdata.phy_init_seq = int_seq; } void __init msm_register_uart_usb_switch(void (*usb_uart_switch) (int)) { if (usb_uart_switch) msm_hsusb_pdata.usb_uart_switch = usb_uart_switch; } void __init msm_add_usb_id_pin_gpio(int usb_id_pin_io) { msm_hsusb_pdata.usb_id_pin_gpio = usb_id_pin_io; } void __init msm_hsusb_set_product(struct msm_hsusb_product *product, int num_products) { msm_hsusb_pdata.products = product; msm_hsusb_pdata.num_products = num_products; } #endif static struct resource resources_uart1[] = { { .start = INT_UART1, .end = INT_UART1, .flags = IORESOURCE_IRQ, }, { .start = MSM_UART1_PHYS, .end = MSM_UART1_PHYS + MSM_UART1_SIZE - 1, .flags = IORESOURCE_MEM, }, }; static struct resource resources_uart2[] = { { .start = INT_UART2, .end = INT_UART2, .flags = IORESOURCE_IRQ, }, { .start = MSM_UART2_PHYS, .end = MSM_UART2_PHYS + MSM_UART2_SIZE - 1, .flags = IORESOURCE_MEM, }, }; static struct resource resources_uart3[] = { { .start = INT_UART3, .end = INT_UART3, .flags = IORESOURCE_IRQ, }, { .start = MSM_UART3_PHYS, .end = MSM_UART3_PHYS + MSM_UART3_SIZE - 1, .flags = IORESOURCE_MEM, }, }; struct platform_device msm_device_uart1 = { .name = "msm_serial", .id = 0, .num_resources = ARRAY_SIZE(resources_uart1), .resource = resources_uart1, }; struct platform_device msm_device_uart2 = { .name = "msm_serial", .id = 1, .num_resources = ARRAY_SIZE(resources_uart2), .resource = resources_uart2, }; struct platform_device msm_device_uart3 = { .name = "msm_serial", .id = 2, .num_resources = ARRAY_SIZE(resources_uart3), .resource = resources_uart3, }; static struct resource msm_uart1_dm_resources[] = { { .start = MSM_UART1DM_PHYS, .end = MSM_UART1DM_PHYS + PAGE_SIZE - 1, .flags = IORESOURCE_MEM, }, { .start = INT_UART1DM_IRQ, .end = INT_UART1DM_IRQ, .flags = IORESOURCE_IRQ, }, { .start = INT_UART1DM_RX, .end = INT_UART1DM_RX, .flags = IORESOURCE_IRQ, }, { .start = DMOV_HSUART1_TX_CHAN, .end = DMOV_HSUART1_RX_CHAN, .name = "uartdm_channels", .flags = IORESOURCE_DMA, }, { .start = DMOV_HSUART1_TX_CRCI, .end = DMOV_HSUART1_RX_CRCI, .name = "uartdm_crci", .flags = IORESOURCE_DMA, }, }; static u64 msm_uart_dm1_dma_mask = DMA_BIT_MASK(32); struct platform_device msm_device_uart_dm1 = { .name = "msm_serial_hs", .id = 0, .num_resources = ARRAY_SIZE(msm_uart1_dm_resources), .resource = msm_uart1_dm_resources, .dev = { .dma_mask = &msm_uart_dm1_dma_mask, .coherent_dma_mask = DMA_BIT_MASK(32), }, }; static struct resource msm_uart2_dm_resources[] = { { .start = MSM_UART2DM_PHYS, .end = MSM_UART2DM_PHYS + PAGE_SIZE - 1, .flags = IORESOURCE_MEM, }, { .start = INT_UART2DM_IRQ, .end = INT_UART2DM_IRQ, .flags = IORESOURCE_IRQ, }, { .start = INT_UART2DM_RX, .end = INT_UART2DM_RX, .flags = IORESOURCE_IRQ, }, { .start = DMOV_HSUART2_TX_CHAN, .end = DMOV_HSUART2_RX_CHAN, .name = "uartdm_channels", .flags = IORESOURCE_DMA, }, { .start = DMOV_HSUART2_TX_CRCI, .end = DMOV_HSUART2_RX_CRCI, .name = "uartdm_crci", .flags = IORESOURCE_DMA, }, }; static u64 msm_uart_dm2_dma_mask = DMA_BIT_MASK(32); struct platform_device msm_device_uart_dm2 = { .name = "msm_serial_hs", .id = 1, .num_resources = ARRAY_SIZE(msm_uart2_dm_resources), .resource = msm_uart2_dm_resources, .dev = { .dma_mask = &msm_uart_dm2_dma_mask, .coherent_dma_mask = DMA_BIT_MASK(32), }, }; #ifdef CONFIG_ARCH_MSM7X30 static struct resource resources_i2c_2[] = { { .start = MSM_I2C_2_PHYS, .end = MSM_I2C_2_PHYS + MSM_I2C_SIZE - 1, .flags = IORESOURCE_MEM, }, { .start = INT_PWB_I2C_2, .end = INT_PWB_I2C_2, .flags = IORESOURCE_IRQ, }, }; struct platform_device msm_device_i2c_2 = { .name = "msm_i2c", .id = 2, .num_resources = ARRAY_SIZE(resources_i2c_2), .resource = resources_i2c_2, }; #endif static struct resource resources_i2c[] = { { .start = MSM_I2C_PHYS, .end = MSM_I2C_PHYS + MSM_I2C_SIZE - 1, .flags = IORESOURCE_MEM, }, { .start = INT_PWB_I2C, .end = INT_PWB_I2C, .flags = IORESOURCE_IRQ, }, }; struct platform_device msm_device_i2c = { .name = "msm_i2c", .id = 0, .num_resources = ARRAY_SIZE(resources_i2c), .resource = resources_i2c, }; #ifdef CONFIG_ARCH_MSM7X30 static struct resource resources_qup[] = { { .name = "qup_phys_addr", .start = MSM_QUP_PHYS, .end = MSM_QUP_PHYS + MSM_QUP_SIZE - 1, .flags = IORESOURCE_MEM, }, { .name = "gsbi_qup_i2c_addr", .start = MSM_GSBI_QUP_I2C_PHYS, .end = MSM_GSBI_QUP_I2C_PHYS + 4 - 1, .flags = IORESOURCE_MEM, }, { .name = "qup_in_intr", .start = INT_PWB_QUP_IN, .end = INT_PWB_QUP_IN, .flags = IORESOURCE_IRQ, }, { .name = "qup_out_intr", .start = INT_PWB_QUP_OUT, .end = INT_PWB_QUP_OUT, .flags = IORESOURCE_IRQ, }, { .name = "qup_err_intr", .start = INT_PWB_QUP_ERR, .end = INT_PWB_QUP_ERR, .flags = IORESOURCE_IRQ, }, }; struct platform_device qup_device_i2c = { .name = "qup_i2c", .id = 4, .num_resources = ARRAY_SIZE(resources_qup), .resource = resources_qup, }; #endif #ifdef CONFIG_SPI_QSD_NEW static struct resource qsd_spi_resources[] = { { .name = "spi_irq_in", .start = INT_SPI_INPUT, .end = INT_SPI_INPUT, .flags = IORESOURCE_IRQ, }, { .name = "spi_irq_out", .start = INT_SPI_OUTPUT, .end = INT_SPI_OUTPUT, .flags = IORESOURCE_IRQ, }, { .name = "spi_irq_err", .start = INT_SPI_ERROR, .end = INT_SPI_ERROR, .flags = IORESOURCE_IRQ, }, { .name = "spi_base", .start = 0xA8000000, .end = 0xA8000000 + SZ_4K - 1, .flags = IORESOURCE_MEM, }, }; struct platform_device qsdnew_device_spi = { .name = "spi_qsd_new", .id = 0, .num_resources = ARRAY_SIZE(qsd_spi_resources), .resource = qsd_spi_resources, }; #endif #ifdef CONFIG_I2C_SSBI #define MSM_SSBI6_PHYS 0xAD900000 static struct resource msm_ssbi6_resources[] = { { .name = "ssbi_base", .start = MSM_SSBI6_PHYS, .end = MSM_SSBI6_PHYS + SZ_4K - 1, .flags = IORESOURCE_MEM, }, }; struct platform_device msm_device_ssbi6 = { .name = "i2c_ssbi", .id = 6, .num_resources = ARRAY_SIZE(msm_ssbi6_resources), .resource = msm_ssbi6_resources, }; #define MSM_SSBI7_PHYS 0xAC800000 static struct resource msm_ssbi7_resources[] = { { .name = "ssbi_base", .start = MSM_SSBI7_PHYS, .end = MSM_SSBI7_PHYS + SZ_4K - 1, .flags = IORESOURCE_MEM, }, }; struct platform_device msm_device_ssbi7 = { .name = "i2c_ssbi", .id = 7, .num_resources = ARRAY_SIZE(msm_ssbi7_resources), .resource = msm_ssbi7_resources, }; #endif /* CONFIG_I2C_SSBI */ #if defined(CONFIG_ARCH_MSM7X30) #define GPIO_I2C_CLK 70 #define GPIO_I2C_DAT 71 #elif defined(CONFIG_ARCH_QSD8X50) #define GPIO_I2C_CLK 95 #define GPIO_I2C_DAT 96 #else #define GPIO_I2C_CLK 60 #define GPIO_I2C_DAT 61 #endif void msm_i2c_gpio_init(void) { gpio_request(GPIO_I2C_CLK, "i2c_clk"); gpio_request(GPIO_I2C_DAT, "i2c_data"); } void msm_set_i2c_mux(bool gpio, int *gpio_clk, int *gpio_dat, int clk_str, int dat_str) { unsigned id; if (gpio) { id = PCOM_GPIO_CFG(GPIO_I2C_CLK, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA); msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX, &id, 0); id = PCOM_GPIO_CFG(GPIO_I2C_DAT, 0, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_2MA); msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX, &id, 0); *gpio_clk = GPIO_I2C_CLK; *gpio_dat = GPIO_I2C_DAT; } else { id = PCOM_GPIO_CFG(GPIO_I2C_CLK, 1, GPIO_INPUT, GPIO_NO_PULL, clk_str); msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX, &id, 0); id = PCOM_GPIO_CFG(GPIO_I2C_DAT , 1, GPIO_INPUT, GPIO_NO_PULL, dat_str); msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX, &id, 0); } } struct flash_platform_data msm_nand_data = { .parts = NULL, .nr_parts = 0, }; static struct resource resources_nand[] = { [0] = { .start = 7, .end = 7, .flags = IORESOURCE_DMA, }, }; struct platform_device msm_device_nand = { .name = "msm_nand", .id = -1, .num_resources = ARRAY_SIZE(resources_nand), .resource = resources_nand, .dev = { .platform_data = &msm_nand_data, }, }; struct platform_device msm_device_smd = { .name = "msm_smd", .id = -1, }; static struct resource resources_sdc1[] = { { .start = MSM_SDC1_PHYS, .end = MSM_SDC1_PHYS + MSM_SDC1_SIZE - 1, .flags = IORESOURCE_MEM, }, { .start = INT_SDC1_0, .end = INT_SDC1_0, .flags = IORESOURCE_IRQ, .name = "cmd_irq", }, { .start = INT_SDC1_1, .end = INT_SDC1_1, .flags = IORESOURCE_IRQ, .name = "pio_irq", }, { .flags = IORESOURCE_IRQ | IORESOURCE_DISABLED, .name = "status_irq" }, { .start = 8, .end = 8, .flags = IORESOURCE_DMA, }, }; static struct resource resources_sdc2[] = { { .start = MSM_SDC2_PHYS, .end = MSM_SDC2_PHYS + MSM_SDC2_SIZE - 1, .flags = IORESOURCE_MEM, }, { .start = INT_SDC2_0, .end = INT_SDC2_0, .flags = IORESOURCE_IRQ, .name = "cmd_irq", }, { .start = INT_SDC2_1, .end = INT_SDC2_1, .flags = IORESOURCE_IRQ, .name = "pio_irq", }, { .flags = IORESOURCE_IRQ | IORESOURCE_DISABLED, .name = "status_irq" }, { .start = 8, .end = 8, .flags = IORESOURCE_DMA, }, }; static struct resource resources_sdc3[] = { { .start = MSM_SDC3_PHYS, .end = MSM_SDC3_PHYS + MSM_SDC3_SIZE - 1, .flags = IORESOURCE_MEM, }, { .start = INT_SDC3_0, .end = INT_SDC3_0, .flags = IORESOURCE_IRQ, .name = "cmd_irq", }, { .start = INT_SDC3_1, .end = INT_SDC3_1, .flags = IORESOURCE_IRQ, .name = "pio_irq", }, { .flags = IORESOURCE_IRQ | IORESOURCE_DISABLED, .name = "status_irq" }, { .start = 8, .end = 8, .flags = IORESOURCE_DMA, }, }; static struct resource resources_sdc4[] = { { .start = MSM_SDC4_PHYS, .end = MSM_SDC4_PHYS + MSM_SDC4_SIZE - 1, .flags = IORESOURCE_MEM, }, { .start = INT_SDC4_0, .end = INT_SDC4_0, .flags = IORESOURCE_IRQ, .name = "cmd_irq", }, { .start = INT_SDC4_1, .end = INT_SDC4_1, .flags = IORESOURCE_IRQ, .name = "pio_irq", }, { .flags = IORESOURCE_IRQ | IORESOURCE_DISABLED, .name = "status_irq" }, { .start = 8, .end = 8, .flags = IORESOURCE_DMA, }, }; struct platform_device msm_device_sdc1 = { .name = "msm_sdcc", .id = 1, .num_resources = ARRAY_SIZE(resources_sdc1), .resource = resources_sdc1, .dev = { .coherent_dma_mask = 0xffffffff, }, }; struct platform_device msm_device_sdc2 = { .name = "msm_sdcc", .id = 2, .num_resources = ARRAY_SIZE(resources_sdc2), .resource = resources_sdc2, .dev = { .coherent_dma_mask = 0xffffffff, }, }; struct platform_device msm_device_sdc3 = { .name = "msm_sdcc", .id = 3, .num_resources = ARRAY_SIZE(resources_sdc3), .resource = resources_sdc3, .dev = { .coherent_dma_mask = 0xffffffff, }, }; struct platform_device msm_device_sdc4 = { .name = "msm_sdcc", .id = 4, .num_resources = ARRAY_SIZE(resources_sdc4), .resource = resources_sdc4, .dev = { .coherent_dma_mask = 0xffffffff, }, }; static struct platform_device *msm_sdcc_devices[] __initdata = { &msm_device_sdc1, &msm_device_sdc2, &msm_device_sdc3, &msm_device_sdc4, }; int __init msm_add_sdcc(unsigned int controller, struct mmc_platform_data *plat, unsigned int stat_irq, unsigned long stat_irq_flags) { struct platform_device *pdev; struct resource *res; if (controller < 1 || controller > 4) return -EINVAL; pdev = msm_sdcc_devices[controller-1]; pdev->dev.platform_data = plat; res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "status_irq"); if (!res) return -EINVAL; else if (stat_irq) { res->start = res->end = stat_irq; res->flags &= ~IORESOURCE_DISABLED; res->flags |= stat_irq_flags; } #ifdef CONFIG_MMC_SUPPORT_EXTERNEL_DRIVER if (plat->use_ext_sdiodrv) pdev->name = plat->ext_sdiodrv_name; #endif return platform_device_register(pdev); } #ifdef CONFIG_MSM_RMT_STORAGE_SERVER #define RAMFS_INFO_MAGICNUMBER 0x654D4D43 #define RAMFS_INFO_VERSION 0x00000001 #define RAMFS_MODEMSTORAGE_ID 0x4D454653 static void __init msm_register_device(struct platform_device *pdev, void *data) { int ret; pdev->dev.platform_data = data; ret = platform_device_register(pdev); if (ret) dev_err(&pdev->dev, "%s: platform_device_register() failed = %d\n", __func__, ret); } static struct resource rmt_storage_resources[] = { { .flags = IORESOURCE_MEM, }, }; static struct platform_device rmt_storage_device = { .name = "rmt_storage", .id = -1, .num_resources = ARRAY_SIZE(rmt_storage_resources), .resource = rmt_storage_resources, }; int __init rmt_storage_add_ramfs(void) { struct shared_ramfs_table *ramfs_table; struct shared_ramfs_entry *ramfs_entry; int index; ramfs_table = smem_alloc(SMEM_SEFS_INFO, sizeof(struct shared_ramfs_table)); if (!ramfs_table) { printk(KERN_WARNING "%s: No RAMFS table in SMEM\n", __func__); return -ENOENT; } if ((ramfs_table->magic_id != (u32) RAMFS_INFO_MAGICNUMBER) || (ramfs_table->version != (u32) RAMFS_INFO_VERSION)) { printk(KERN_WARNING "%s: Magic / Version mismatch:, " "magic_id=%#x, format_version=%#x\n", __func__, ramfs_table->magic_id, ramfs_table->version); return -ENOENT; } for (index = 0; index < ramfs_table->entries; index++) { ramfs_entry = &ramfs_table->ramfs_entry[index]; /* Find a match for the Modem Storage RAMFS area */ if (ramfs_entry->client_id == (u32) RAMFS_MODEMSTORAGE_ID) { printk(KERN_INFO "%s: RAMFS Info (from SMEM): " "Baseaddr = 0x%08x, Size = 0x%08x\n", __func__, ramfs_entry->base_addr, ramfs_entry->size); rmt_storage_resources[0].start = ramfs_entry->base_addr; rmt_storage_resources[0].end = ramfs_entry->base_addr + ramfs_entry->size - 1; msm_register_device(&rmt_storage_device, ramfs_entry); return 0; } } return -ENOENT; } #endif static struct resource resources_mddi0[] = { { .start = MSM_PMDH_PHYS, .end = MSM_PMDH_PHYS + MSM_PMDH_SIZE - 1, .flags = IORESOURCE_MEM, }, { .start = INT_MDDI_PRI, .end = INT_MDDI_PRI, .flags = IORESOURCE_IRQ, }, }; static struct resource resources_mddi1[] = { { .start = MSM_EMDH_PHYS, .end = MSM_EMDH_PHYS + MSM_EMDH_SIZE - 1, .flags = IORESOURCE_MEM, }, { .start = INT_MDDI_EXT, .end = INT_MDDI_EXT, .flags = IORESOURCE_IRQ, }, }; struct platform_device msm_device_mddi0 = { .name = "msm_mddi", .id = 0, .num_resources = ARRAY_SIZE(resources_mddi0), .resource = resources_mddi0, .dev = { .coherent_dma_mask = 0xffffffff, }, }; struct platform_device msm_device_mddi1 = { .name = "msm_mddi", .id = 1, .num_resources = ARRAY_SIZE(resources_mddi1), .resource = resources_mddi1, .dev = { .coherent_dma_mask = 0xffffffff, } }; static struct resource resources_mdp[] = { { .start = MSM_MDP_PHYS, .end = MSM_MDP_PHYS + MSM_MDP_SIZE - 1, .name = "mdp", .flags = IORESOURCE_MEM }, { .start = INT_MDP, .end = INT_MDP, .flags = IORESOURCE_IRQ, }, }; struct platform_device msm_device_mdp = { .name = "msm_mdp", .id = 0, .num_resources = ARRAY_SIZE(resources_mdp), .resource = resources_mdp, }; #if defined(CONFIG_ARCH_MSM7X30) static struct resource msm_vidc_720p_resources[] = { { .start = 0xA3B00000, .end = 0xA3B00000 + SZ_4K - 1, .flags = IORESOURCE_MEM, }, { .start = INT_MFC720, .end = INT_MFC720, .flags = IORESOURCE_IRQ, }, }; struct platform_device msm_device_vidc_720p = { .name = "msm_vidc_720p", .id = 0, .num_resources = ARRAY_SIZE(msm_vidc_720p_resources), .resource = msm_vidc_720p_resources, }; #endif static struct resource resources_tssc[] = { #if defined(CONFIG_ARCH_MSM7225) { .start = MSM_TSSC_PHYS, .end = MSM_TSSC_PHYS + MSM_TSSC_SIZE - 1, .name = "tssc", .flags = IORESOURCE_MEM, }, #endif { .start = INT_TCHSCRN1, .end = INT_TCHSCRN1, .name = "tssc1", .flags = IORESOURCE_IRQ | IRQF_TRIGGER_RISING, }, { .start = INT_TCHSCRN2, .end = INT_TCHSCRN2, .name = "tssc2", .flags = IORESOURCE_IRQ | IRQF_TRIGGER_RISING, }, }; struct platform_device msm_device_touchscreen = { .name = "msm_touchscreen", .id = 0, .num_resources = ARRAY_SIZE(resources_tssc), .resource = resources_tssc, }; #if defined(CONFIG_ARCH_QSD8X50) static struct resource resources_spi[] = { { .start = MSM_SPI_PHYS, .end = MSM_SPI_PHYS + MSM_SPI_SIZE - 1, .flags = IORESOURCE_MEM, }, { .start = INT_SPI_INPUT, .end = INT_SPI_INPUT, .name = "irq_in", .flags = IORESOURCE_IRQ, }, { .start = INT_SPI_OUTPUT, .end = INT_SPI_OUTPUT, .name = "irq_out", .flags = IORESOURCE_IRQ, }, { .start = INT_SPI_ERROR, .end = INT_SPI_ERROR, .name = "irq_err", .flags = IORESOURCE_IRQ, }, }; struct platform_device msm_device_spi = { .name = "msm_spi", .id = 0, .num_resources = ARRAY_SIZE(resources_spi), .resource = resources_spi, }; #endif #ifdef CONFIG_MSM_ROTATOR static struct resource resources_msm_rotator[] = { { .start = MSM_ROTATOR_PHYS, .end = MSM_ROTATOR_PHYS + MSM_ROTATOR_SIZE - 1, .flags = IORESOURCE_MEM, }, { .start = INT_ROTATOR, .end = INT_ROTATOR, .flags = IORESOURCE_IRQ, }, }; struct platform_device msm_rotator_device = { .name = "msm_rotator", .id = 0, .num_resources = ARRAY_SIZE(resources_msm_rotator), .resource = resources_msm_rotator, }; #endif #ifdef CONFIG_MSM_SSBI static struct resource resources_ssbi_pmic[] = { { .start = MSM_PMIC_SSBI_PHYS, .end = MSM_PMIC_SSBI_PHYS + MSM_PMIC_SSBI_SIZE - 1, .flags = IORESOURCE_MEM, }, }; struct platform_device msm_device_ssbi_pmic = { .name = "msm_ssbi", .id = -1, .resource = resources_ssbi_pmic, .num_resources = ARRAY_SIZE(resources_ssbi_pmic), }; #endif #define CLOCK(clk_name, clk_id, clk_dev, clk_flags, clk_arch) { \ .name = clk_name, \ .id = clk_id, \ .flags = (clk_flags) | ((clk_arch) & CLKFLAG_ARCH_ALL), \ .dev = clk_dev, \ } #define CLK_ALL(name, id, dev, flags) \ CLOCK(name, id, dev, flags, CLKFLAG_ARCH_ALL) #define CLK_7X00A(name, id, dev, flags) \ CLOCK(name, id, dev, flags, CLKFLAG_ARCH_MSM7X00A) #define CLK_8X50(name, id, dev, flags) \ CLOCK(name, id, dev, flags, CLKFLAG_ARCH_QSD8X50) #define OFF CLKFLAG_AUTO_OFF #define MINMAX (CLKFLAG_USE_MIN_TO_SET | CLKFLAG_USE_MAX_TO_SET) #define USE_MIN (CLKFLAG_USE_MIN_TO_SET | CLKFLAG_SHARED) struct clk msm_clocks[] = { #ifndef CONFIG_ARCH_MSM7X30 CLK_ALL("adm_clk", ADM_CLK, NULL, 0), CLK_ALL("adsp_clk", ADSP_CLK, NULL, 0), CLK_ALL("ebi1_clk", EBI1_CLK, NULL, USE_MIN), CLK_ALL("ebi2_clk", EBI2_CLK, NULL, 0), CLK_ALL("ecodec_clk", ECODEC_CLK, NULL, 0), CLK_ALL("mddi_clk", EMDH_CLK, &msm_device_mddi1.dev, OFF), CLK_ALL("gp_clk", GP_CLK, NULL, 0), CLK_ALL("grp_clk", GRP_CLK, NULL, OFF), CLK_ALL("i2c_clk", I2C_CLK, &msm_device_i2c.dev, 0), CLK_ALL("icodec_rx_clk", ICODEC_RX_CLK, NULL, 0), CLK_ALL("icodec_tx_clk", ICODEC_TX_CLK, NULL, 0), CLK_ALL("imem_clk", IMEM_CLK, NULL, OFF), CLK_ALL("mdc_clk", MDC_CLK, NULL, 0), CLK_ALL("mdp_clk", MDP_CLK, &msm_device_mdp.dev, 0), CLK_ALL("pbus_clk", PBUS_CLK, NULL, 0), CLK_ALL("pcm_clk", PCM_CLK, NULL, 0), #ifdef CONFIG_MACH_SUPERSONIC CLK_ALL("mddi_clk", PMDH_CLK, &msm_device_mddi0.dev, OFF), #else CLK_ALL("mddi_clk", PMDH_CLK, &msm_device_mddi0.dev, OFF | MINMAX), #endif CLK_ALL("sdac_clk", SDAC_CLK, NULL, OFF), CLK_ALL("sdc_clk", SDC1_CLK, &msm_device_sdc1.dev, OFF), CLK_ALL("sdc_pclk", SDC1_PCLK, &msm_device_sdc1.dev, OFF), CLK_ALL("sdc_clk", SDC2_CLK, &msm_device_sdc2.dev, OFF), CLK_ALL("sdc_pclk", SDC2_PCLK, &msm_device_sdc2.dev, OFF), CLK_ALL("sdc_clk", SDC3_CLK, &msm_device_sdc3.dev, OFF), CLK_ALL("sdc_pclk", SDC3_PCLK, &msm_device_sdc3.dev, OFF), CLK_ALL("sdc_clk", SDC4_CLK, &msm_device_sdc4.dev, OFF), CLK_ALL("sdc_pclk", SDC4_PCLK, &msm_device_sdc4.dev, OFF), CLK_ALL("tsif_clk", TSIF_CLK, NULL, 0), CLK_ALL("tsif_ref_clk", TSIF_REF_CLK, NULL, 0), CLK_ALL("tv_dac_clk", TV_DAC_CLK, NULL, 0), CLK_ALL("tv_enc_clk", TV_ENC_CLK, NULL, 0), CLK_ALL("uart_clk", UART1_CLK, &msm_device_uart1.dev, OFF), CLK_ALL("uart_clk", UART2_CLK, &msm_device_uart2.dev, OFF), CLK_ALL("uart_clk", UART3_CLK, &msm_device_uart3.dev, OFF), CLK_ALL("uartdm_clk", UART1DM_CLK, &msm_device_uart_dm1.dev, OFF), CLK_ALL("uartdm_clk", UART2DM_CLK, &msm_device_uart_dm2.dev, OFF), CLK_ALL("usb_hs_clk", USB_HS_CLK, &msm_device_hsusb.dev, OFF), CLK_ALL("usb_hs_pclk", USB_HS_PCLK, &msm_device_hsusb.dev, OFF), CLK_ALL("usb_otg_clk", USB_OTG_CLK, NULL, 0), CLK_ALL("vdc_clk", VDC_CLK, NULL, OFF | MINMAX), CLK_ALL("vfe_clk", VFE_CLK, NULL, OFF), CLK_ALL("vfe_mdc_clk", VFE_MDC_CLK, NULL, OFF), #ifdef CONFIG_ARCH_MSM7227 CLK_ALL("grp_pclk", GRP_PCLK, NULL, OFF), #endif CLK_ALL("spi_clk", SPI_CLK, NULL, 0), CLK_ALL("usb_phy_clk", USB_PHY_CLK, NULL, USE_MIN), CLK_8X50("lcdc_pclk_clk", LCDC_PCLK, &msm_device_mdp.dev, 0), CLK_8X50("lcdc_pad_pclk_clk", LCDC_PAD_PCLK, &msm_device_mdp.dev, 0), CLK_8X50("mdp_vsync_clk", MDP_VSYNC_CLK, &msm_device_mdp.dev, 0), CLOCK(NULL, 0, NULL, 0, 0), #else /* 7x30 clock tbl */ CLK_PCOM("adm_clk", ADM_CLK, NULL, 0), CLK_PCOM("adsp_clk", ADSP_CLK, NULL, 0), CLK_PCOM("cam_m_clk", CAM_M_CLK, NULL, 0), CLK_PCOM("camif_pad_pclk", CAMIF_PAD_P_CLK, NULL, OFF), CLK_PCOM("ebi1_clk", EBI1_CLK, NULL, USE_MIN), CLK_PCOM("ecodec_clk", ECODEC_CLK, NULL, 0), CLK_PCOM("emdh_clk", EMDH_CLK, NULL, OFF | MINMAX), CLK_PCOM("emdh_pclk", EMDH_P_CLK, NULL, OFF), CLK_PCOM("gp_clk", GP_CLK, NULL, 0), CLK_PCOM("grp_2d_clk", GRP_2D_CLK, NULL, 0), CLK_PCOM("grp_2d_pclk", GRP_2D_P_CLK, NULL, 0), CLK_PCOM("grp_clk", GRP_3D_CLK, NULL, 0), CLK_PCOM("grp_pclk", GRP_3D_P_CLK, NULL, 0), CLK_7X30S("grp_src_clk", GRP_3D_SRC_CLK, GRP_3D_CLK, NULL, 0), CLK_PCOM("hdmi_clk", HDMI_CLK, NULL, 0), CLK_PCOM("i2c_clk", I2C_CLK, &msm_device_i2c.dev, 0), CLK_PCOM("i2c_clk", I2C_2_CLK, &msm_device_i2c_2.dev, 0), CLK_PCOM("imem_clk", IMEM_CLK, NULL, OFF), CLK_PCOM("jpeg_clk", JPEG_CLK, NULL, OFF), CLK_PCOM("jpeg_pclk", JPEG_P_CLK, NULL, OFF), CLK_PCOM("lpa_codec_clk", LPA_CODEC_CLK, NULL, 0), CLK_PCOM("lpa_core_clk", LPA_CORE_CLK, NULL, 0), CLK_PCOM("lpa_pclk", LPA_P_CLK, NULL, 0), CLK_PCOM("mdc_clk", MDC_CLK, NULL, 0), CLK_PCOM("mddi_clk", PMDH_CLK, NULL, OFF | MINMAX), CLK_PCOM("mddi_pclk", PMDH_P_CLK, NULL, 0), CLK_PCOM("mdp_clk", MDP_CLK, NULL, OFF), CLK_PCOM("mdp_pclk", MDP_P_CLK, NULL, 0), /*Original is mdp_lcdc_pclk_clk and mdp_lcdc_pad_pclk_clk*/ CLK_PCOM("lcdc_pclk_clk", MDP_LCDC_PCLK_CLK, NULL, OFF), CLK_PCOM("lcdc_pad_pclk_clk", MDP_LCDC_PAD_PCLK_CLK, NULL, OFF), CLK_PCOM("mdp_vsync_clk", MDP_VSYNC_CLK, NULL, 0), CLK_PCOM("mfc_clk", MFC_CLK, NULL, 0), CLK_PCOM("mfc_div2_clk", MFC_DIV2_CLK, NULL, 0), CLK_PCOM("mfc_pclk", MFC_P_CLK, NULL, 0), CLK_PCOM("mi2s_codec_rx_m_clk", MI2S_CODEC_RX_M_CLK, NULL, 0), CLK_PCOM("mi2s_codec_rx_s_clk", MI2S_CODEC_RX_S_CLK, NULL, 0), CLK_PCOM("mi2s_codec_tx_m_clk", MI2S_CODEC_TX_M_CLK, NULL, 0), CLK_PCOM("mi2s_codec_tx_s_clk", MI2S_CODEC_TX_S_CLK, NULL, 0), CLK_PCOM("pbus_clk", PBUS_CLK, NULL, USE_MIN), CLK_PCOM("pcm_clk", PCM_CLK, NULL, 0), CLK_PCOM("qup_clk", QUP_I2C_CLK, &qup_device_i2c.dev, 0), CLK_PCOM("rotator_clk", AXI_ROTATOR_CLK, NULL, 0), CLK_PCOM("rotator_imem_clk", ROTATOR_IMEM_CLK, NULL, OFF), CLK_PCOM("rotator_pclk", ROTATOR_P_CLK, NULL, OFF), CLK_PCOM("sdac_clk", SDAC_CLK, NULL, OFF), CLK_PCOM("sdc_clk", SDC1_CLK, &msm_device_sdc1.dev, OFF), CLK_PCOM("sdc_pclk", SDC1_P_CLK, &msm_device_sdc1.dev, OFF), CLK_PCOM("sdc_clk", SDC2_CLK, &msm_device_sdc2.dev, OFF), CLK_PCOM("sdc_pclk", SDC2_P_CLK, &msm_device_sdc2.dev, OFF), CLK_PCOM("sdc_clk", SDC3_CLK, &msm_device_sdc3.dev, OFF), CLK_PCOM("sdc_pclk", SDC3_P_CLK, &msm_device_sdc3.dev, OFF), CLK_PCOM("sdc_clk", SDC4_CLK, &msm_device_sdc4.dev, OFF), CLK_PCOM("sdc_pclk", SDC4_P_CLK, &msm_device_sdc4.dev, OFF), CLK_PCOM("spi_clk", SPI_CLK, NULL, 0), CLK_PCOM("spi_pclk", SPI_P_CLK, NULL, OFF), CLK_7X30S("tv_src_clk", TV_CLK, TV_ENC_CLK, NULL, 0), CLK_PCOM("tv_dac_clk", TV_DAC_CLK, NULL, 0), CLK_PCOM("tv_enc_clk", TV_ENC_CLK, NULL, 0), CLK_PCOM("uart_clk", UART1_CLK, &msm_device_uart1.dev, OFF), CLK_PCOM("uart_clk", UART2_CLK, &msm_device_uart2.dev, 0), CLK_PCOM("uart_clk", UART3_CLK, &msm_device_uart3.dev, OFF), CLK_PCOM("uartdm_clk", UART1DM_CLK, &msm_device_uart_dm1.dev, OFF), CLK_PCOM("uartdm_clk", UART2DM_CLK, &msm_device_uart_dm2.dev, 0), CLK_PCOM("usb_hs_clk", USB_HS_CLK, NULL, OFF), CLK_PCOM("usb_hs_pclk", USB_HS_P_CLK, NULL, OFF), /* Now we can't close these usb clocks at the beginning change OFF to 0 temporarily */ CLK_PCOM("usb_hs_core_clk", USB_HS_CORE_CLK, NULL, 0), CLK_PCOM("usb_hs2_clk", USB_HS2_CLK, NULL, 0), CLK_PCOM("usb_hs2_pclk", USB_HS2_P_CLK, NULL, 0), CLK_PCOM("usb_hs2_core_clk", USB_HS2_CORE_CLK, NULL, 0), CLK_PCOM("usb_hs3_clk", USB_HS3_CLK, NULL, 0), CLK_PCOM("usb_hs3_pclk", USB_HS3_P_CLK, NULL, 0), CLK_PCOM("usb_hs3_core_clk", USB_HS3_CORE_CLK, NULL, 0), CLK_PCOM("vdc_clk", VDC_CLK, NULL, OFF | MINMAX), CLK_PCOM("vfe_camif_clk", VFE_CAMIF_CLK, NULL, OFF), CLK_PCOM("vfe_clk", VFE_CLK, NULL, 0), CLK_PCOM("vfe_mdc_clk", VFE_MDC_CLK, NULL, OFF), CLK_PCOM("vfe_pclk", VFE_P_CLK, NULL, OFF), CLK_PCOM("vpe_clk", VPE_CLK, NULL, 0), /* 7x30 v2 hardware only. */ CLK_PCOM("csi_clk", CSI0_CLK, NULL, 0), CLK_PCOM("csi_pclk", CSI0_P_CLK, NULL, 0), CLK_PCOM("csi_vfe_clk", CSI0_VFE_CLK, NULL, 0), CLOCK(NULL, 0, NULL, 0, 0), #endif }; 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; else if (!strcmp(s, "power_test")) mfg_mode = 4; else if (!strcmp(s, "offmode_charging")) mfg_mode = 5; return 1; } __setup("androidboot.mode=", board_mfg_mode_init); int board_mfg_mode(void) { return mfg_mode; } EXPORT_SYMBOL(board_mfg_mode); static int __init board_serialno_setup(char *serialno) { char *str; /* use default serial number when mode is factory2 */ if (board_mfg_mode() == 1 || !strlen(serialno)) str = df_serialno; else str = serialno; #ifdef CONFIG_USB_FUNCTION msm_hsusb_pdata.serial_number = str; #endif board_sn = str; return 1; } __setup("androidboot.serialno=", board_serialno_setup); char *board_serialno(void) { return board_sn; } #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_HERO_PANEL_TYPE 0x4d534D74 int panel_type; int __init tag_panel_parsing(const struct tag *tags) { panel_type = tags->u.revision.rev; printk(KERN_DEBUG "%s: panel type = %d\n", __func__, panel_type); return panel_type; } __tagtable(ATAG_HERO_PANEL_TYPE, tag_panel_parsing); #define ATAG_ENGINEERID 0x4d534D75 unsigned engineer_id; 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) { engineer_id = t->u.revision.rev; engineerid = t->u.revision.rev; } printk(KERN_DEBUG "parse_tag_engineerid: 0x%x\n", engineerid); return engineerid; } __tagtable(ATAG_ENGINEERID, parse_tag_engineerid); #define ATAG_MFG_GPIO_TABLE 0x59504551 int __init parse_tag_mfg_gpio_table(const struct tag *tags) { unsigned char *dptr = (unsigned char *)(&tags->u); __u32 size; size = min((__u32)(tags->hdr.size - 2) * sizeof(__u32), (__u32)MFG_GPIO_TABLE_MAX_SIZE); memcpy(mfg_gpio_table, dptr, size); return 0; } __tagtable(ATAG_MFG_GPIO_TABLE, parse_tag_mfg_gpio_table); char * board_get_mfg_sleep_gpio_table(void) { return mfg_gpio_table; } EXPORT_SYMBOL(board_get_mfg_sleep_gpio_table); static char *emmc_tag; static int __init board_set_emmc_tag(char *get_hboot_emmc) { if (strlen(get_hboot_emmc)) emmc_tag = get_hboot_emmc; else emmc_tag = NULL; return 1; } __setup("androidboot.emmc=", board_set_emmc_tag); int board_emmc_boot(void) { if (emmc_tag) { if (!strcmp(emmc_tag, "true")) return 1; } return 0; }