Path: blob/master/arch/arm/mach-msm/board-qsd8x50.c
10817 views
/* Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.1*2* This program is free software; you can redistribute it and/or modify3* it under the terms of the GNU General Public License version 2 and4* only version 2 as published by the Free Software Foundation.5*6* This program is distributed in the hope that it will be useful,7* but WITHOUT ANY WARRANTY; without even the implied warranty of8* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the9* GNU General Public License for more details.10*11* You should have received a copy of the GNU General Public License12* along with this program; if not, write to the Free Software13* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA14* 02110-1301, USA.15*/1617#include <linux/kernel.h>18#include <linux/irq.h>19#include <linux/gpio.h>20#include <linux/platform_device.h>21#include <linux/delay.h>22#include <linux/usb/msm_hsusb.h>23#include <linux/err.h>24#include <linux/clkdev.h>2526#include <asm/mach-types.h>27#include <asm/mach/arch.h>28#include <asm/io.h>29#include <asm/setup.h>3031#include <mach/board.h>32#include <mach/irqs.h>33#include <mach/sirc.h>34#include <mach/gpio.h>35#include <mach/vreg.h>36#include <mach/mmc.h>3738#include "devices.h"3940extern struct sys_timer msm_timer;4142static const resource_size_t qsd8x50_surf_smc91x_base __initdata = 0x70000300;43static const unsigned qsd8x50_surf_smc91x_gpio __initdata = 156;4445/* Leave smc91x resources empty here, as we'll fill them in46* at run-time: they vary from board to board, and the true47* configuration won't be known until boot.48*/49static struct resource smc91x_resources[] = {50[0] = {51.flags = IORESOURCE_MEM,52},53[1] = {54.flags = IORESOURCE_IRQ,55},56};5758static struct platform_device smc91x_device = {59.name = "smc91x",60.id = 0,61.num_resources = ARRAY_SIZE(smc91x_resources),62.resource = smc91x_resources,63};6465static int __init msm_init_smc91x(void)66{67if (machine_is_qsd8x50_surf()) {68smc91x_resources[0].start = qsd8x50_surf_smc91x_base;69smc91x_resources[0].end = qsd8x50_surf_smc91x_base + 0xff;70smc91x_resources[1].start =71gpio_to_irq(qsd8x50_surf_smc91x_gpio);72smc91x_resources[1].end =73gpio_to_irq(qsd8x50_surf_smc91x_gpio);74platform_device_register(&smc91x_device);75}7677return 0;78}79module_init(msm_init_smc91x);8081static int hsusb_phy_init_seq[] = {820x08, 0x31, /* Increase HS Driver Amplitude */830x20, 0x32, /* Enable and set Pre-Emphasis Depth to 10% */84-185};8687static struct msm_otg_platform_data msm_otg_pdata = {88.phy_init_seq = hsusb_phy_init_seq,89.mode = USB_PERIPHERAL,90.otg_control = OTG_PHY_CONTROL,91};9293static struct platform_device *devices[] __initdata = {94&msm_device_uart3,95&msm_device_smd,96&msm_device_otg,97&msm_device_hsusb,98&msm_device_hsusb_host,99};100101static struct msm_mmc_gpio sdc1_gpio_cfg[] = {102{51, "sdc1_dat_3"},103{52, "sdc1_dat_2"},104{53, "sdc1_dat_1"},105{54, "sdc1_dat_0"},106{55, "sdc1_cmd"},107{56, "sdc1_clk"}108};109110static struct vreg *vreg_mmc;111static unsigned long vreg_sts;112113static uint32_t msm_sdcc_setup_power(struct device *dv, unsigned int vdd)114{115int rc = 0;116struct platform_device *pdev;117118pdev = container_of(dv, struct platform_device, dev);119120if (vdd == 0) {121if (!vreg_sts)122return 0;123124clear_bit(pdev->id, &vreg_sts);125126if (!vreg_sts) {127rc = vreg_disable(vreg_mmc);128if (rc)129pr_err("vreg_mmc disable failed for slot "130"%d: %d\n", pdev->id, rc);131}132return 0;133}134135if (!vreg_sts) {136rc = vreg_set_level(vreg_mmc, 2900);137if (rc)138pr_err("vreg_mmc set level failed for slot %d: %d\n",139pdev->id, rc);140rc = vreg_enable(vreg_mmc);141if (rc)142pr_err("vreg_mmc enable failed for slot %d: %d\n",143pdev->id, rc);144}145set_bit(pdev->id, &vreg_sts);146return 0;147}148149static struct msm_mmc_gpio_data sdc1_gpio = {150.gpio = sdc1_gpio_cfg,151.size = ARRAY_SIZE(sdc1_gpio_cfg),152};153154static struct msm_mmc_platform_data qsd8x50_sdc1_data = {155.ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29,156.translate_vdd = msm_sdcc_setup_power,157.gpio_data = &sdc1_gpio,158};159160static void __init qsd8x50_init_mmc(void)161{162vreg_mmc = vreg_get(NULL, "gp5");163164if (IS_ERR(vreg_mmc)) {165pr_err("vreg get for vreg_mmc failed (%ld)\n",166PTR_ERR(vreg_mmc));167return;168}169170msm_add_sdcc(1, &qsd8x50_sdc1_data, 0, 0);171}172173static void __init qsd8x50_map_io(void)174{175msm_map_qsd8x50_io();176msm_clock_init(msm_clocks_8x50, msm_num_clocks_8x50);177}178179static void __init qsd8x50_init_irq(void)180{181msm_init_irq();182msm_init_sirc();183}184185static void __init qsd8x50_init(void)186{187msm_device_otg.dev.platform_data = &msm_otg_pdata;188msm_device_hsusb.dev.parent = &msm_device_otg.dev;189msm_device_hsusb_host.dev.parent = &msm_device_otg.dev;190platform_add_devices(devices, ARRAY_SIZE(devices));191qsd8x50_init_mmc();192}193194MACHINE_START(QSD8X50_SURF, "QCT QSD8X50 SURF")195.boot_params = PLAT_PHYS_OFFSET + 0x100,196.map_io = qsd8x50_map_io,197.init_irq = qsd8x50_init_irq,198.init_machine = qsd8x50_init,199.timer = &msm_timer,200MACHINE_END201202MACHINE_START(QSD8X50A_ST1_5, "QCT QSD8X50A ST1.5")203.boot_params = PLAT_PHYS_OFFSET + 0x100,204.map_io = qsd8x50_map_io,205.init_irq = qsd8x50_init_irq,206.init_machine = qsd8x50_init,207.timer = &msm_timer,208MACHINE_END209210211