android_kernel_cmhtcleo/arch/arm/mach-msm/devices.c
2010-08-27 11:19:57 +02:00

1635 lines
38 KiB
C

/* 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 <linux/kernel.h>
#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <mach/irqs.h>
#include <mach/msm_iomap.h>
#include <mach/dma.h>
#include <mach/board.h>
#include "smd_private.h"
#include <asm/mach/flash.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
#include <asm/mach/mmc.h>
#include <asm/setup.h>
#include "devices.h"
#include "clock.h"
#include "proc_comm.h"
#include <mach/msm_hsusb.h>
#include <mach/msm_rpcrouter.h>
#include <mach/msm_hsusb_hw.h>
#ifdef CONFIG_USB_FUNCTION
#include <linux/usb/mass_storage_function.h>
#endif
#ifdef CONFIG_PMIC8058
#include <linux/mfd/pmic8058.h>
#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;
}