blob: ac56c00a364478c3a16f4a637bda7dce43fe23eb [file] [log] [blame] [edit]
/* Board support file for Samsung Tuna Board.
*
* Copyright (C) 2011 Google, Inc.
* Copyright (C) 2010 Texas Instruments
*
* Based on mach-omap2/board-omap4panda.c
*
* 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/init.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/ion.h>
#include <linux/leds.h>
#include <linux/gpio.h>
#include <linux/memblock.h>
#include <linux/omap_ion.h>
#include <linux/usb/otg.h>
#include <linux/i2c/twl.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/fixed.h>
#include <linux/wl12xx.h>
#include <linux/reboot.h>
#include <linux/memblock.h>
#include <linux/sysfs.h>
#include <linux/uaccess.h>
#include <linux/proc_fs.h>
#include <linux/spi/spi.h>
#include <linux/spi/flash.h>
#include <linux/platform_data/lte_modem_bootloader.h>
#include <linux/platform_data/ram_console.h>
#include <plat/mcspi.h>
#include <linux/i2c-gpio.h>
#include <mach/hardware.h>
#include <mach/omap4-common.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <plat/board-tuna-bluetooth.h>
#include <plat/omap-serial.h>
#include <plat/board.h>
#include <plat/common.h>
#include <plat/cpu.h>
#include <plat/usb.h>
#include <plat/mmc.h>
#include <plat/remoteproc.h>
#include <plat/omap-serial.h>
#include <mach/omap_fiq_debugger.h>
#include <mach/id.h>
#include "timer-gp.h"
#include "omap4-sar-layout.h"
#include "hsmmc.h"
#include "control.h"
#include "mux.h"
#include "board-tuna.h"
#include "resetreason.h"
#include <mach/dmm.h>
#define TUNA_RAMCONSOLE_START (PLAT_PHYS_OFFSET + SZ_512M)
#define TUNA_RAMCONSOLE_SIZE SZ_2M
struct class *sec_class;
EXPORT_SYMBOL(sec_class);
/* For LTE(CMC221) */
#define OMAP_GPIO_LTE_ACTIVE 47
#define OMAP_GPIO_CMC2AP_INT1 61
#define GPIO_AUD_PWRON 127
#define GPIO_AUD_PWRON_TORO_V1 20
/* GPS GPIO Setting */
#define GPIO_AP_AGPS_TSYNC 18
#define GPIO_GPS_nRST 136
#define GPIO_GPS_PWR_EN 137
#define GPIO_GPS_UART_SEL 164
#define GPIO_MHL_SCL_18V 99
#define GPIO_MHL_SDA_18V 98
#define REBOOT_FLAG_RECOVERY 0x52564352
#define REBOOT_FLAG_FASTBOOT 0x54534146
#define REBOOT_FLAG_NORMAL 0x4D524F4E
#define REBOOT_FLAG_POWER_OFF 0x46464F50
#define UART_NUM_FOR_GPS 0
static int tuna_hw_rev;
static struct gpio tuna_hw_rev_gpios[] = {
{76, GPIOF_IN, "hw_rev0"},
{75, GPIOF_IN, "hw_rev1"},
{74, GPIOF_IN, "hw_rev2"},
{73, GPIOF_IN, "hw_rev3"},
{170, GPIOF_IN, "hw_rev4"},
};
static const char const *omap4_tuna_hw_name_maguro[] = {
[0x00] = "Toro Lunchbox #1",
[0x01] = "Maguro 1st Sample",
[0x02] = "Maguro 2nd Sample",
[0x03] = "Maguro 4th Sample",
[0x05] = "Maguro 5th Sample",
[0x07] = "Maguro 6th Sample",
[0x08] = "Maguro 7th Sample",
[0x09] = "Maguro 8th Sample",
};
static const char const *omap4_tuna_hw_name_toro[] = {
[0x00] = "Toro Lunchbox #2",
[0x01] = "Toro 1st Sample",
[0x02] = "Toro 2nd Sample",
[0x03] = "Toro 4th Sample",
[0x05] = "Toro 5th Sample",
[0x06] = "Toro 8th Sample",
[0x08] = "Toro 8th Sample",
[0x09] = "Toro 8-1th Sample",
};
int omap4_tuna_get_revision(void)
{
return tuna_hw_rev & TUNA_REV_MASK;
}
int omap4_tuna_get_type(void)
{
return tuna_hw_rev & TUNA_TYPE_MASK;
}
static const char *omap4_tuna_hw_rev_name(void) {
const char *ret;
const char **names;
int num;
int rev;
if (omap4_tuna_get_type() == TUNA_TYPE_MAGURO) {
names = omap4_tuna_hw_name_maguro;
num = ARRAY_SIZE(omap4_tuna_hw_name_maguro);
ret = "Maguro unknown";
} else {
names = omap4_tuna_hw_name_toro;
num = ARRAY_SIZE(omap4_tuna_hw_name_toro);
ret = "Toro unknown";
}
rev = omap4_tuna_get_revision();
if (rev >= num || !names[rev])
return ret;
return names[rev];
}
/*
* Store a handy board information string which we can use elsewhere like
* like in panic situation
*/
static char omap4_tuna_bd_info_string[255];
static void omap4_tuna_init_hw_rev(void)
{
int ret;
int i;
u32 r;
/* Disable weak driver pulldown on usbb2_hsic_strobe */
r = omap4_ctrl_pad_readl(OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_USBB_HSIC);
r &= ~OMAP4_USBB2_HSIC_STROBE_WD_MASK;
omap4_ctrl_pad_writel(r, OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_USBB_HSIC);
ret = gpio_request_array(tuna_hw_rev_gpios,
ARRAY_SIZE(tuna_hw_rev_gpios));
BUG_ON(ret);
for (i = 0; i < ARRAY_SIZE(tuna_hw_rev_gpios); i++)
tuna_hw_rev |= gpio_get_value(tuna_hw_rev_gpios[i].gpio) << i;
snprintf(omap4_tuna_bd_info_string,
ARRAY_SIZE(omap4_tuna_bd_info_string),
"Tuna HW revision: %02x (%s), cpu %s ES%d.%d ",
tuna_hw_rev,
omap4_tuna_hw_rev_name(),
cpu_is_omap443x() ? "OMAP4430" : "OMAP4460",
(GET_OMAP_REVISION() >> 4) & 0xf,
GET_OMAP_REVISION() & 0xf);
pr_info("%s\n", omap4_tuna_bd_info_string);
mach_panic_string = omap4_tuna_bd_info_string;
}
/* wl127x BT, FM, GPS connectivity chip */
static int wl1271_gpios[] = {46, -1, -1};
static struct platform_device wl1271_device = {
.name = "kim",
.id = -1,
.dev = {
.platform_data = &wl1271_gpios,
},
};
static struct resource ramconsole_resources[] = {
{
.flags = IORESOURCE_MEM,
.start = TUNA_RAMCONSOLE_START,
.end = TUNA_RAMCONSOLE_START + TUNA_RAMCONSOLE_SIZE - 1,
},
};
static struct ram_console_platform_data ramconsole_pdata;
static struct platform_device ramconsole_device = {
.name = "ram_console",
.id = -1,
.num_resources = ARRAY_SIZE(ramconsole_resources),
.resource = ramconsole_resources,
.dev = {
.platform_data = &ramconsole_pdata,
},
};
static struct platform_device bcm4330_bluetooth_device = {
.name = "bcm4330_bluetooth",
.id = -1,
};
static void __init tuna_bt_init(void)
{
/* BT_EN - GPIO 104 */
omap_mux_init_signal("gpmc_ncs6.gpio_103", OMAP_PIN_OUTPUT);
/*BT_nRST - GPIO 42 */
omap_mux_init_signal("gpmc_a18.gpio_42", OMAP_PIN_OUTPUT);
/* BT_WAKE - GPIO 27 */
omap_mux_init_signal("dpm_emu16.gpio_27", OMAP_PIN_OUTPUT);
/* BT_HOST_WAKE - GPIO 177 */
omap_mux_init_signal("kpd_row5.gpio_177", OMAP_WAKEUP_EN |
OMAP_PIN_INPUT_PULLDOWN);
platform_device_register(&bcm4330_bluetooth_device);
}
static struct twl4030_madc_platform_data twl6030_madc = {
.irq_line = -1,
};
static struct platform_device twl6030_madc_device = {
.name = "twl6030_madc",
.id = -1,
.dev = {
.platform_data = &twl6030_madc,
},
};
static struct i2c_gpio_platform_data tuna_gpio_i2c5_pdata = {
.sda_pin = GPIO_MHL_SDA_18V,
.scl_pin = GPIO_MHL_SCL_18V,
.udelay = 3,
.timeout = 0,
};
static struct platform_device tuna_gpio_i2c5_device = {
.name = "i2c-gpio",
.id = 5,
.dev = {
.platform_data = &tuna_gpio_i2c5_pdata,
}
};
#define PHYS_ADDR_SMC_SIZE (SZ_1M * 3)
#define PHYS_ADDR_DUCATI_SIZE (SZ_1M * 105)
#define OMAP_TUNA_ION_HEAP_SECURE_INPUT_SIZE (SZ_1M * 90)
#define OMAP_TUNA_ION_HEAP_TILER_SIZE (SZ_1M * 81)
#define OMAP_TUNA_ION_HEAP_NONSECURE_TILER_SIZE (SZ_1M * 15)
#define PHYS_ADDR_SMC_MEM (0x80000000 + SZ_1G - PHYS_ADDR_SMC_SIZE)
#define PHYS_ADDR_DUCATI_MEM (PHYS_ADDR_SMC_MEM - \
PHYS_ADDR_DUCATI_SIZE - \
OMAP_TUNA_ION_HEAP_SECURE_INPUT_SIZE)
static struct ion_platform_data tuna_ion_data = {
.nr = 3,
.heaps = {
{
.type = ION_HEAP_TYPE_CARVEOUT,
.id = OMAP_ION_HEAP_SECURE_INPUT,
.name = "secure_input",
.base = PHYS_ADDR_SMC_MEM -
OMAP_TUNA_ION_HEAP_SECURE_INPUT_SIZE,
.size = OMAP_TUNA_ION_HEAP_SECURE_INPUT_SIZE,
},
{ .type = OMAP_ION_HEAP_TYPE_TILER,
.id = OMAP_ION_HEAP_TILER,
.name = "tiler",
.base = PHYS_ADDR_DUCATI_MEM -
OMAP_TUNA_ION_HEAP_TILER_SIZE,
.size = OMAP_TUNA_ION_HEAP_TILER_SIZE,
},
{ .type = OMAP_ION_HEAP_TYPE_TILER,
.id = OMAP_ION_HEAP_NONSECURE_TILER,
.name = "nonsecure_tiler",
.base = PHYS_ADDR_DUCATI_MEM -
OMAP_TUNA_ION_HEAP_TILER_SIZE -
OMAP_TUNA_ION_HEAP_NONSECURE_TILER_SIZE,
.size = OMAP_TUNA_ION_HEAP_NONSECURE_TILER_SIZE,
},
},
};
static struct platform_device tuna_ion_device = {
.name = "ion-omap4",
.id = -1,
.dev = {
.platform_data = &tuna_ion_data,
},
};
static struct platform_device tuna_spdif_dit_device = {
.name = "spdif-dit",
.id = 0,
};
static struct platform_device *tuna_devices[] __initdata = {
&ramconsole_device,
&wl1271_device,
&twl6030_madc_device,
&tuna_ion_device,
&tuna_gpio_i2c5_device,
&tuna_spdif_dit_device,
};
/*
* The UART1 is for GPS, and CSR GPS chip should control uart1 rts level
* for gps firmware download.
*/
static int uart1_rts_ctrl_write(struct file *file, const char __user *buffer,
size_t count, loff_t *offs)
{
char buf[10] = {0,};
if (omap4_tuna_get_revision() < TUNA_REV_SAMPLE_4)
return -ENXIO;
if (count > sizeof(buf) - 1)
return -EINVAL;
if (copy_from_user(buf, buffer, count))
return -EFAULT;
if (!strncmp(buf, "1", 1)) {
omap_rts_mux_write(OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE7,
UART_NUM_FOR_GPS);
} else if (!strncmp(buf, "0", 1)) {
omap_rts_mux_write(OMAP_PIN_OUTPUT | OMAP_MUX_MODE1,
UART_NUM_FOR_GPS);
}
return count;
}
static const struct file_operations uart1_rts_ctrl_proc_fops = {
.write = uart1_rts_ctrl_write,
};
static int __init tuna_gps_rts_ctrl_init(void)
{
struct proc_dir_entry *p_entry;
p_entry = proc_create("mcspi1_cs3_ctrl", 0666, NULL,
&uart1_rts_ctrl_proc_fops);
if (!p_entry)
return -ENOMEM;
return 0;
}
static void tuna_gsd4t_gps_gpio(void)
{
/* AP_AGPS_TSYNC - GPIO 18 */
omap_mux_init_signal("dpm_emu7.gpio_18", OMAP_PIN_OUTPUT);
/* GPS_nRST - GPIO 136 */
omap_mux_init_signal("mcspi1_simo.gpio_136", OMAP_PIN_OUTPUT);
/* GPS_PWR_EN - GPIO 137 */
omap_mux_init_signal("mcspi1_cs0.gpio_137", OMAP_PIN_OUTPUT);
/* GPS_UART_SEL - GPIO 164 */
omap_mux_init_signal("usbb2_ulpitll_dat3.gpio_164", OMAP_PIN_OUTPUT);
}
static void tuna_gsd4t_gps_init(void)
{
struct device *gps_dev;
gps_dev = device_create(sec_class, NULL, 0, NULL, "gps");
if (IS_ERR(gps_dev)) {
pr_err("Failed to create device(gps)!\n");
goto err;
}
tuna_gsd4t_gps_gpio();
gpio_request(GPIO_AP_AGPS_TSYNC, "AP_AGPS_TSYNC");
gpio_direction_output(GPIO_AP_AGPS_TSYNC, 0);
gpio_request(GPIO_GPS_nRST, "GPS_nRST");
gpio_direction_output(GPIO_GPS_nRST, 1);
gpio_request(GPIO_GPS_PWR_EN, "GPS_PWR_EN");
gpio_direction_output(GPIO_GPS_PWR_EN, 0);
gpio_request(GPIO_GPS_UART_SEL , "GPS_UART_SEL");
gpio_direction_output(GPIO_GPS_UART_SEL , 0);
gpio_export(GPIO_GPS_nRST, 1);
gpio_export(GPIO_GPS_PWR_EN, 1);
gpio_export_link(gps_dev, "GPS_nRST", GPIO_GPS_nRST);
gpio_export_link(gps_dev, "GPS_PWR_EN", GPIO_GPS_PWR_EN);
tuna_gps_rts_ctrl_init();
err:
return;
}
static int __init sec_common_init(void)
{
sec_class = class_create(THIS_MODULE, "sec");
if (IS_ERR(sec_class))
pr_err("Failed to create class(sec)!\n");
return 0;
}
static void __init tuna_init_early(void)
{
omap2_init_common_infrastructure();
omap2_init_common_devices(NULL, NULL);
}
static struct omap_musb_board_data musb_board_data = {
.interface_type = MUSB_INTERFACE_UTMI,
#ifdef CONFIG_USB_MUSB_OTG
.mode = MUSB_OTG,
#else
.mode = MUSB_PERIPHERAL,
#endif
.power = 500,
};
static struct omap2_hsmmc_info mmc[] = {
{
.mmc = 1,
.nonremovable = true,
.caps = MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
.ocr_mask = MMC_VDD_165_195,
.gpio_wp = -EINVAL,
.gpio_cd = -EINVAL,
},
{
.name = "omap_wlan",
.mmc = 5,
.caps = MMC_CAP_4_BIT_DATA,
.gpio_wp = -EINVAL,
.gpio_cd = -EINVAL,
.ocr_mask = MMC_VDD_165_195 | MMC_VDD_20_21,
.nonremovable = false,
.mmc_data = &tuna_wifi_data,
},
{} /* Terminator */
};
static struct regulator_consumer_supply tuna_vmmc_supply[] = {
{
.supply = "vmmc",
.dev_name = "omap_hsmmc.0",
},
{
.supply = "vmmc",
.dev_name = "omap_hsmmc.1",
},
};
static struct regulator_init_data tuna_vaux1 = {
.constraints = {
.min_uV = 3000000,
.max_uV = 3000000,
.apply_uV = true,
.valid_modes_mask = REGULATOR_MODE_NORMAL
| REGULATOR_MODE_STANDBY,
.valid_ops_mask = REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS,
.always_on = true,
},
};
static struct regulator_init_data tuna_vaux2 = {
.constraints = {
.min_uV = 1200000,
.max_uV = 2800000,
.apply_uV = true,
.valid_modes_mask = REGULATOR_MODE_NORMAL
| REGULATOR_MODE_STANDBY,
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
| REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS,
.state_mem = {
.disabled = true,
},
.initial_state = PM_SUSPEND_MEM,
},
};
static struct regulator_consumer_supply tuna_vaux3_supplies[] = {
{
.supply = "vlcd",
},
};
static struct regulator_init_data tuna_vaux3 = {
.constraints = {
.min_uV = 3100000,
.max_uV = 3100000,
.apply_uV = true,
.valid_modes_mask = REGULATOR_MODE_NORMAL
| REGULATOR_MODE_STANDBY,
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
| REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS,
},
.num_consumer_supplies = ARRAY_SIZE(tuna_vaux3_supplies),
.consumer_supplies = tuna_vaux3_supplies,
};
static struct regulator_init_data tuna_vmmc = {
.constraints = {
.min_uV = 1800000,
.max_uV = 1800000,
.apply_uV = true,
.valid_modes_mask = REGULATOR_MODE_NORMAL
| REGULATOR_MODE_STANDBY,
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
| REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS,
},
.num_consumer_supplies = 2,
.consumer_supplies = tuna_vmmc_supply,
};
static struct regulator_init_data tuna_vpp = {
.constraints = {
.min_uV = 1800000,
.max_uV = 2500000,
.apply_uV = true,
.valid_modes_mask = REGULATOR_MODE_NORMAL
| REGULATOR_MODE_STANDBY,
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
| REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS,
.state_mem = {
.disabled = true,
},
.initial_state = PM_SUSPEND_MEM,
},
};
static struct regulator_consumer_supply tuna_vusim_supplies[] = {
{
.supply = "vlcd-iovcc",
},
};
static struct regulator_init_data tuna_vusim = {
.constraints = {
.min_uV = 2200000,
.max_uV = 2200000,
.valid_modes_mask = REGULATOR_MODE_NORMAL
| REGULATOR_MODE_STANDBY,
.valid_ops_mask = REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS,
},
.num_consumer_supplies = ARRAY_SIZE(tuna_vusim_supplies),
.consumer_supplies = tuna_vusim_supplies,
};
static struct regulator_init_data tuna_vana = {
.constraints = {
.min_uV = 2100000,
.max_uV = 2100000,
.valid_modes_mask = REGULATOR_MODE_NORMAL
| REGULATOR_MODE_STANDBY,
.valid_ops_mask = REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS,
.always_on = true,
},
};
static struct regulator_consumer_supply tuna_vcxio_supply[] = {
REGULATOR_SUPPLY("vdds_dsi", "omapdss_dss"),
REGULATOR_SUPPLY("vdds_dsi", "omapdss_dsi1"),
};
static struct regulator_init_data tuna_vcxio = {
.constraints = {
.min_uV = 1800000,
.max_uV = 1800000,
.valid_modes_mask = REGULATOR_MODE_NORMAL
| REGULATOR_MODE_STANDBY,
.valid_ops_mask = REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS,
},
.num_consumer_supplies = ARRAY_SIZE(tuna_vcxio_supply),
.consumer_supplies = tuna_vcxio_supply,
};
static struct regulator_consumer_supply tuna_vdac_supply[] = {
{
.supply = "hdmi_vref",
},
};
static struct regulator_init_data tuna_vdac = {
.constraints = {
.min_uV = 1800000,
.max_uV = 1800000,
.valid_modes_mask = REGULATOR_MODE_NORMAL
| REGULATOR_MODE_STANDBY,
.valid_ops_mask = REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS,
},
.num_consumer_supplies = ARRAY_SIZE(tuna_vdac_supply),
.consumer_supplies = tuna_vdac_supply,
};
static struct regulator_consumer_supply tuna_vusb_supply[] = {
REGULATOR_SUPPLY("vusb", "tuna_otg"),
};
static struct regulator_init_data tuna_vusb = {
.constraints = {
.min_uV = 3300000,
.max_uV = 3300000,
.valid_modes_mask = REGULATOR_MODE_NORMAL
| REGULATOR_MODE_STANDBY,
.valid_ops_mask = REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS,
.state_mem = {
.disabled = true,
},
.initial_state = PM_SUSPEND_MEM,
},
.num_consumer_supplies = ARRAY_SIZE(tuna_vusb_supply),
.consumer_supplies = tuna_vusb_supply,
};
/* clk32kg is a twl6030 32khz clock modeled as a regulator, used by GPS */
static struct regulator_init_data tuna_clk32kg = {
.constraints = {
.valid_ops_mask = REGULATOR_CHANGE_STATUS,
.always_on = true,
},
};
static struct regulator_consumer_supply tuna_clk32kaudio_supply[] = {
{
.supply = "clk32kaudio",
},
{
.supply = "twl6040_clk32k",
}
};
static struct regulator_init_data tuna_clk32kaudio = {
.constraints = {
.valid_ops_mask = REGULATOR_CHANGE_STATUS,
.boot_on = true,
},
.num_consumer_supplies = ARRAY_SIZE(tuna_clk32kaudio_supply),
.consumer_supplies = tuna_clk32kaudio_supply,
};
static struct regulator_init_data tuna_vdd3 = {
.constraints = {
.valid_ops_mask = REGULATOR_CHANGE_STATUS,
.state_mem = {
.disabled = true,
},
.initial_state = PM_SUSPEND_MEM,
},
};
/*
* VMEM is unused. Register it to regulator framework and let it
* be in disabled state.
*/
static struct regulator_init_data tuna_vmem = {
.constraints = {
.valid_ops_mask = REGULATOR_CHANGE_STATUS,
.state_mem = {
.disabled = true,
},
.initial_state = PM_SUSPEND_MEM,
},
};
static struct regulator_init_data tuna_v2v1 = {
.constraints = {
.min_uV = 2100000,
.max_uV = 2100000,
.valid_modes_mask = REGULATOR_MODE_NORMAL
| REGULATOR_MODE_STANDBY,
.valid_ops_mask = REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS,
.always_on = true,
},
};
static struct twl4030_codec_audio_data twl6040_audio = {
/* single-step ramp for headset and handsfree */
.hs_left_step = 0x0f,
.hs_right_step = 0x0f,
.hf_left_step = 0x1d,
.hf_right_step = 0x1d,
.ep_step = 0x0f,
};
static struct regulator *twl6040_clk32kreg;
static int tuna_twl6040_get_ext_clk32k(void)
{
int ret = 0;
twl6040_clk32kreg = regulator_get(NULL, "twl6040_clk32k");
if (IS_ERR(twl6040_clk32kreg)) {
ret = PTR_ERR(twl6040_clk32kreg);
pr_err("failed to get CLK32K %d\n", ret);
}
return ret;
}
static void tuna_twl6040_put_ext_clk32k(void)
{
regulator_put(twl6040_clk32kreg);
}
static int tuna_twl6040_set_ext_clk32k(bool on)
{
int ret;
if (IS_ERR_OR_NULL(twl6040_clk32kreg))
return -EINVAL;
if (on)
ret = regulator_enable(twl6040_clk32kreg);
else
ret = regulator_disable(twl6040_clk32kreg);
if (ret)
pr_err("failed to enable TWL6040 CLK32K %d\n", ret);
return ret;
}
static struct twl4030_codec_data twl6040_codec = {
.audio = &twl6040_audio,
.naudint_irq = OMAP44XX_IRQ_SYS_2N,
.irq_base = TWL6040_CODEC_IRQ_BASE,
.get_ext_clk32k = tuna_twl6040_get_ext_clk32k,
.put_ext_clk32k = tuna_twl6040_put_ext_clk32k,
.set_ext_clk32k = tuna_twl6040_set_ext_clk32k,
};
static struct twl4030_platform_data tuna_twldata = {
.irq_base = TWL6030_IRQ_BASE,
.irq_end = TWL6030_IRQ_END,
/* Regulators */
.vmmc = &tuna_vmmc,
.vpp = &tuna_vpp,
.vusim = &tuna_vusim,
.vana = &tuna_vana,
.vcxio = &tuna_vcxio,
.vdac = &tuna_vdac,
.vusb = &tuna_vusb,
.vaux1 = &tuna_vaux1,
.vaux2 = &tuna_vaux2,
.vaux3 = &tuna_vaux3,
.clk32kg = &tuna_clk32kg,
.clk32kaudio = &tuna_clk32kaudio,
/* children */
.codec = &twl6040_codec,
.madc = &twl6030_madc,
/* SMPS */
.vdd3 = &tuna_vdd3,
.vmem = &tuna_vmem,
.v2v1 = &tuna_v2v1,
};
static void tuna_audio_init(void)
{
unsigned int aud_pwron;
/* twl6040 naudint */
omap_mux_init_signal("sys_nirq2.sys_nirq2", \
OMAP_PIN_INPUT_PULLUP);
/* aud_pwron */
if (omap4_tuna_get_type() == TUNA_TYPE_TORO &&
omap4_tuna_get_revision() >= 1)
aud_pwron = GPIO_AUD_PWRON_TORO_V1;
else
aud_pwron = GPIO_AUD_PWRON;
omap_mux_init_gpio(aud_pwron, OMAP_PIN_OUTPUT);
twl6040_codec.audpwron_gpio = aud_pwron;
omap_mux_init_signal("gpmc_a24.gpio_48", OMAP_PIN_OUTPUT | OMAP_MUX_MODE3);
omap_mux_init_signal("kpd_col3.gpio_171", OMAP_PIN_OUTPUT | OMAP_MUX_MODE3);
}
static struct i2c_board_info __initdata tuna_i2c1_boardinfo[] = {
{
I2C_BOARD_INFO("twl6030", 0x48),
.flags = I2C_CLIENT_WAKE,
.irq = OMAP44XX_IRQ_SYS_1N,
.platform_data = &tuna_twldata,
},
};
static struct i2c_board_info __initdata tuna_i2c2_boardinfo[] = {
{
I2C_BOARD_INFO("ducati", 0x20),
.irq = OMAP44XX_IRQ_I2C2,
.ext_master = true,
},
};
static struct i2c_board_info __initdata tuna_i2c4_boardinfo[] = {
{
I2C_BOARD_INFO("an30259a", 0x30),
},
};
static int __init tuna_i2c_init(void)
{
u32 r;
omap_mux_init_signal("sys_nirq1", OMAP_PIN_INPUT_PULLUP |
OMAP_WAKEUP_EN);
omap_mux_init_signal("i2c1_scl.i2c1_scl", OMAP_PIN_INPUT_PULLUP);
omap_mux_init_signal("i2c1_sda.i2c1_sda", OMAP_PIN_INPUT_PULLUP);
/*
* This will allow unused regulator to be shutdown. This flag
* should be set in the board file. Before regulators are registered.
*/
regulator_has_full_constraints();
/*
* Phoenix Audio IC needs I2C1 to
* start with 400 KHz or less
*/
omap_register_i2c_bus(1, 400, tuna_i2c1_boardinfo,
ARRAY_SIZE(tuna_i2c1_boardinfo));
omap_register_i2c_bus(2, 400, tuna_i2c2_boardinfo,
ARRAY_SIZE(tuna_i2c2_boardinfo));
omap_register_i2c_bus(3, 400, NULL, 0);
/* Disable internal pullup on i2c.4 line:
* as external 2.2K is already present
*/
r = omap4_ctrl_pad_readl(OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_I2C_0);
r |= (1 << OMAP4_I2C4_SDA_PULLUPRESX_SHIFT);
omap4_ctrl_pad_writel(r, OMAP4_CTRL_MODULE_PAD_CORE_CONTROL_I2C_0);
omap_register_i2c_bus(4, 400, NULL, 0);
/*
* Drive MSECURE high for TWL6030 write access.
*/
omap_mux_init_signal("fref_clk0_out.gpio_wk6", OMAP_PIN_OUTPUT);
gpio_request(6, "msecure");
gpio_direction_output(6, 1);
return 0;
}
#ifdef CONFIG_OMAP_MUX
static struct omap_board_mux board_mux[] __initdata = {
/* camera gpios */
OMAP4_MUX(MCSPI1_SOMI,
OMAP_MUX_MODE3 | OMAP_PIN_INPUT_PULLDOWN), /* gpio_135 */
OMAP4_MUX(KPD_COL0,
OMAP_MUX_MODE3 | OMAP_PIN_INPUT_PULLDOWN), /* gpio_173 */
OMAP4_MUX(GPMC_A19,
OMAP_MUX_MODE3 | OMAP_PIN_INPUT_PULLDOWN), /* gpio_43 */
/* hwrev */
OMAP4_MUX(CSI21_DY4, OMAP_MUX_MODE3 | OMAP_PIN_INPUT),
OMAP4_MUX(CSI21_DX4, OMAP_MUX_MODE3 | OMAP_PIN_INPUT),
OMAP4_MUX(CSI21_DY3, OMAP_MUX_MODE3 | OMAP_PIN_INPUT),
OMAP4_MUX(CSI21_DX3, OMAP_MUX_MODE3 | OMAP_PIN_INPUT),
OMAP4_MUX(USBB2_HSIC_STROBE, OMAP_MUX_MODE3 | OMAP_PIN_INPUT),
/* fRom */
OMAP4_MUX(USBB2_ULPITLL_DAT4,
OMAP_MUX_MODE4 | OMAP_PIN_INPUT), /* mcpsi3_somi */
OMAP4_MUX(USBB2_ULPITLL_DAT5,
OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLDOWN), /* mcpsi3_cs0 */
OMAP4_MUX(USBB2_ULPITLL_DAT6,
OMAP_MUX_MODE4 | OMAP_PIN_INPUT), /* mcpsi3_simo */
OMAP4_MUX(USBB2_ULPITLL_DAT7,
OMAP_MUX_MODE4 | OMAP_PIN_INPUT), /* mcpsi3_clk */
{ .reg_offset = OMAP_MUX_TERMINATOR },
};
static struct omap_board_mux board_wkup_mux[] __initdata = {
/* power button */
OMAP4_MUX(SIM_CD, OMAP_MUX_MODE3 | OMAP_PIN_INPUT),
{ .reg_offset = OMAP_MUX_TERMINATOR },
};
#else
#define board_mux NULL
#define board_wkup_mux NULL
#endif
/* sample4+ adds gps rts/cts lines */
static struct omap_device_pad tuna_uart1_pads_sample4[] __initdata = {
{
.name = "mcspi1_cs3.uart1_rts",
.enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE1,
},
{
.name = "mcspi1_cs2.uart1_cts",
.enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE1,
},
{
.name = "uart3_cts_rctx.uart1_tx",
.enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE1,
},
{
.name = "mcspi1_cs1.uart1_rx",
.flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
.enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE1,
.idle = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE1,
},
};
static struct omap_device_pad tuna_uart1_pads[] __initdata = {
{
.name = "uart3_cts_rctx.uart1_tx",
.enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE1,
},
{
.name = "mcspi1_cs1.uart1_rx",
.flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
.enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE1,
.idle = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE1,
},
};
static struct omap_device_pad tuna_uart2_pads[] __initdata = {
{
.name = "uart2_cts.uart2_cts",
.enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
},
{
.name = "uart2_rts.uart2_rts",
.enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
},
{
.name = "uart2_tx.uart2_tx",
.enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
},
{
.name = "uart2_rx.uart2_rx",
.enable = OMAP_PIN_INPUT_PULLUP | OMAP_MUX_MODE0,
},
};
static struct omap_device_pad tuna_uart3_pads[] __initdata = {
{
.name = "uart3_tx_irtx.uart3_tx_irtx",
.enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
},
{
.name = "uart3_rx_irrx.uart3_rx_irrx",
.flags = OMAP_DEVICE_PAD_REMUX | OMAP_DEVICE_PAD_WAKEUP,
.enable = OMAP_PIN_INPUT | OMAP_MUX_MODE0,
.idle = OMAP_PIN_INPUT | OMAP_MUX_MODE0,
},
};
static struct omap_device_pad tuna_uart4_pads[] __initdata = {
{
.name = "uart4_tx.uart4_tx",
.enable = OMAP_PIN_OUTPUT | OMAP_MUX_MODE0,
},
{
.name = "uart4_rx.uart4_rx",
.enable = OMAP_PIN_INPUT | OMAP_MUX_MODE0,
},
};
static struct omap_uart_port_info tuna_uart2_info __initdata = {
.use_dma = 0,
.dma_rx_buf_size = DEFAULT_RXDMA_BUFSIZE,
.dma_rx_poll_rate = DEFAULT_RXDMA_POLLRATE,
.dma_rx_timeout = DEFAULT_RXDMA_TIMEOUT,
.auto_sus_timeout = 0,
.wake_peer = bcm_bt_lpm_exit_lpm_locked,
.rts_mux_driver_control = 1,
};
static inline void __init board_serial_init(void)
{
struct omap_device_pad *uart1_pads;
int uart1_pads_sz;
if (omap4_tuna_get_revision() >= TUNA_REV_SAMPLE_4) {
uart1_pads = tuna_uart1_pads_sample4;
uart1_pads_sz = ARRAY_SIZE(tuna_uart1_pads_sample4);
} else {
uart1_pads = tuna_uart1_pads;
uart1_pads_sz = ARRAY_SIZE(tuna_uart1_pads);
}
omap_serial_init_port_pads(0, uart1_pads, uart1_pads_sz, NULL);
omap_serial_init_port_pads(1, tuna_uart2_pads,
ARRAY_SIZE(tuna_uart2_pads), &tuna_uart2_info);
omap_serial_init_port_pads(3, tuna_uart4_pads,
ARRAY_SIZE(tuna_uart4_pads), NULL);
}
/* fiq_debugger initializes really early but OMAP resource mgmt
* is not yet ready @ arch_init, so init the serial debugger later */
static int __init board_serial_debug_init(void)
{
return omap_serial_debug_init(2, false, true,
tuna_uart3_pads, ARRAY_SIZE(tuna_uart3_pads));
}
device_initcall(board_serial_debug_init);
/* SPI flash memory in camera module */
#define F_ROM_SPI_BUS_NUM 3
#define F_ROM_SPI_CS 0
#define F_ROM_SPI_SPEED_HZ 24000000
static const struct flash_platform_data w25q80_pdata = {
.name = "w25q80",
.type = "w25q80",
};
static struct omap2_mcspi_device_config f_rom_mcspi_config = {
.turbo_mode = 0,
.single_channel = 1, /* 0: slave, 1: master */
.swap_datalines = 1,
};
static struct spi_board_info tuna_f_rom[] __initdata = {
{
.modalias = "m25p80",
.controller_data = &f_rom_mcspi_config,
.platform_data = &w25q80_pdata,
.bus_num = F_ROM_SPI_BUS_NUM,
.chip_select = F_ROM_SPI_CS,
.max_speed_hz = F_ROM_SPI_SPEED_HZ,
.mode = SPI_MODE_0,
},
};
static void tuna_from_init(void)
{
int err;
if (tuna_hw_rev >= 0x07)
f_rom_mcspi_config.swap_datalines = 0;
err = spi_register_board_info(tuna_f_rom, ARRAY_SIZE(tuna_f_rom));
if (err)
pr_err("failed to register SPI F-ROM\n");
}
/*SPI for LTE modem bootloader*/
#define LTE_MODEM_SPI_BUS_NUM 4
#define LTE_MODEM_SPI_CS 0
#define LTE_MODEM_SPI_MAX_HZ 1500000
struct lte_modem_bootloader_platform_data lte_modem_bootloader_pdata = {
.name = "lte_modem_int",
.gpio_lte2ap_status = OMAP_GPIO_CMC2AP_INT1,
};
static struct omap2_mcspi_device_config lte_mcspi_config = {
.turbo_mode = 0,
.single_channel = 1, /* 0: slave, 1: master */
};
static struct spi_board_info tuna_lte_modem[] __initdata = {
{
.modalias = "lte_modem_spi",
.controller_data = &lte_mcspi_config,
.platform_data = &lte_modem_bootloader_pdata,
.max_speed_hz = LTE_MODEM_SPI_MAX_HZ,
.bus_num = LTE_MODEM_SPI_BUS_NUM,
.chip_select = LTE_MODEM_SPI_CS,
.mode = SPI_MODE_0,
},
};
static int tuna_notifier_call(struct notifier_block *this,
unsigned long code, void *_cmd)
{
void __iomem *sar_base;
unsigned int flag = REBOOT_FLAG_NORMAL;
sar_base = omap4_get_sar_ram_base();
if (!sar_base)
return notifier_from_errno(-ENOMEM);
if (code == SYS_RESTART) {
if (_cmd) {
if (!strcmp(_cmd, "recovery"))
flag = REBOOT_FLAG_RECOVERY;
else if (!strcmp(_cmd, "bootloader"))
flag = REBOOT_FLAG_FASTBOOT;
}
} else if (code == SYS_POWER_OFF) {
flag = REBOOT_FLAG_POWER_OFF;
}
/* The Samsung LOKE bootloader will look for the boot flag at a fixed
* offset from the end of the 1st SAR bank.
*/
writel(flag, sar_base + SAR_BANK2_OFFSET - 0xC);
return NOTIFY_DONE;
}
static struct notifier_block tuna_reboot_notifier = {
.notifier_call = tuna_notifier_call,
};
static ssize_t tuna_soc_family_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "OMAP%04x\n", GET_OMAP_TYPE);
}
static ssize_t tuna_soc_revision_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "ES%d.%d\n", (GET_OMAP_REVISION() >> 4) & 0xf,
GET_OMAP_REVISION() & 0xf);
}
static ssize_t tuna_soc_die_id_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
struct omap_die_id oid;
omap_get_die_id(&oid);
return sprintf(buf, "%08X-%08X-%08X-%08X\n", oid.id_3, oid.id_2,
oid.id_1, oid.id_0);
}
static ssize_t tuna_soc_prod_id_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
struct omap_die_id oid;
omap_get_production_id(&oid);
return sprintf(buf, "%08X-%08X\n", oid.id_1, oid.id_0);
}
static ssize_t tuna_soc_msv_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%08X\n", omap_ctrl_readl(0x013c));
}
static const char *omap_types[] = {
[OMAP2_DEVICE_TYPE_TEST] = "TST",
[OMAP2_DEVICE_TYPE_EMU] = "EMU",
[OMAP2_DEVICE_TYPE_SEC] = "HS",
[OMAP2_DEVICE_TYPE_GP] = "GP",
[OMAP2_DEVICE_TYPE_BAD] = "BAD",
};
static ssize_t tuna_soc_type_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%s\n", omap_types[omap_type()]);
}
#define TUNA_ATTR_RO(_type, _name, _show) \
struct kobj_attribute tuna_##_type##_prop_attr_##_name = \
__ATTR(_name, S_IRUGO, _show, NULL)
static TUNA_ATTR_RO(soc, family, tuna_soc_family_show);
static TUNA_ATTR_RO(soc, revision, tuna_soc_revision_show);
static TUNA_ATTR_RO(soc, type, tuna_soc_type_show);
static TUNA_ATTR_RO(soc, die_id, tuna_soc_die_id_show);
static TUNA_ATTR_RO(soc, production_id, tuna_soc_prod_id_show);
static TUNA_ATTR_RO(soc, msv, tuna_soc_msv_show);
static struct attribute *tuna_soc_prop_attrs[] = {
&tuna_soc_prop_attr_family.attr,
&tuna_soc_prop_attr_revision.attr,
&tuna_soc_prop_attr_type.attr,
&tuna_soc_prop_attr_die_id.attr,
&tuna_soc_prop_attr_production_id.attr,
&tuna_soc_prop_attr_msv.attr,
NULL,
};
static struct attribute_group tuna_soc_prop_attr_group = {
.attrs = tuna_soc_prop_attrs,
};
static ssize_t tuna_board_revision_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%s (0x%02x)\n", omap4_tuna_hw_rev_name(),
tuna_hw_rev);
}
static TUNA_ATTR_RO(board, revision, tuna_board_revision_show);
static struct attribute *tuna_board_prop_attrs[] = {
&tuna_board_prop_attr_revision.attr,
NULL,
};
static struct attribute_group tuna_board_prop_attr_group = {
.attrs = tuna_board_prop_attrs,
};
static void __init omap4_tuna_create_board_props(void)
{
struct kobject *board_props_kobj;
struct kobject *soc_kobj;
int ret = 0;
board_props_kobj = kobject_create_and_add("board_properties", NULL);
if (!board_props_kobj)
goto err_board_obj;
soc_kobj = kobject_create_and_add("soc", board_props_kobj);
if (!soc_kobj)
goto err_soc_obj;
ret = sysfs_create_group(board_props_kobj, &tuna_board_prop_attr_group);
if (ret)
goto err_board_sysfs_create;
ret = sysfs_create_group(soc_kobj, &tuna_soc_prop_attr_group);
if (ret)
goto err_soc_sysfs_create;
return;
err_soc_sysfs_create:
sysfs_remove_group(board_props_kobj, &tuna_board_prop_attr_group);
err_board_sysfs_create:
kobject_put(soc_kobj);
err_soc_obj:
kobject_put(board_props_kobj);
err_board_obj:
if (!board_props_kobj || !soc_kobj || ret)
pr_err("failed to create board_properties\n");
}
#define HSMMC2_MUX (OMAP_MUX_MODE1 | OMAP_PIN_INPUT_PULLUP)
#define HSMMC1_MUX OMAP_PIN_INPUT_PULLUP
static void __init omap4_tuna_led_init(void)
{
i2c_register_board_info(4, tuna_i2c4_boardinfo,
ARRAY_SIZE(tuna_i2c4_boardinfo));
}
/* always reboot into charger mode on "power-off". Let the bootloader
* figure out if we should truly power-off or not.
*/
static void tuna_power_off(void)
{
printk(KERN_EMERG "Rebooting into bootloader for power-off.\n");
arm_pm_restart('c', NULL);
}
static void __init tuna_init(void)
{
int package = OMAP_PACKAGE_CBS;
if (omap_rev() == OMAP4430_REV_ES1_0)
package = OMAP_PACKAGE_CBL;
omap4_mux_init(board_mux, board_wkup_mux, package);
omap4_tuna_init_hw_rev();
omap4_tuna_emif_init();
pm_power_off = tuna_power_off;
register_reboot_notifier(&tuna_reboot_notifier);
/* hsmmc d0-d7 */
omap_mux_init_signal("sdmmc1_dat0.sdmmc1_dat0", HSMMC1_MUX);
omap_mux_init_signal("sdmmc1_dat1.sdmmc1_dat1", HSMMC1_MUX);
omap_mux_init_signal("sdmmc1_dat2.sdmmc1_dat2", HSMMC1_MUX);
omap_mux_init_signal("sdmmc1_dat3.sdmmc1_dat3", HSMMC1_MUX);
omap_mux_init_signal("sdmmc1_dat4.sdmmc1_dat4", HSMMC1_MUX);
omap_mux_init_signal("sdmmc1_dat5.sdmmc1_dat5", HSMMC1_MUX);
omap_mux_init_signal("sdmmc1_dat6.sdmmc1_dat6", HSMMC1_MUX);
omap_mux_init_signal("sdmmc1_dat7.sdmmc1_dat7", HSMMC1_MUX);
/* hsmmc cmd */
omap_mux_init_signal("sdmmc1_cmd.sdmmc1_cmd", HSMMC1_MUX);
/* hsmmc clk */
omap_mux_init_signal("sdmmc1_clk.sdmmc1_clk", HSMMC1_MUX);
gpio_request(158, "emmc_en");
gpio_direction_output(158, 1);
omap_mux_init_gpio(158, OMAP_PIN_INPUT_PULLUP);
omap_mux_init_gpio(GPIO_MHL_SDA_18V, OMAP_PIN_INPUT_PULLUP);
omap_mux_init_gpio(GPIO_MHL_SCL_18V, OMAP_PIN_INPUT_PULLUP);
sec_common_init();
if (TUNA_TYPE_TORO == omap4_tuna_get_type()) {
omap_mux_init_signal("gpmc_wait0",
OMAP_MUX_MODE3 | OMAP_PIN_INPUT_PULLDOWN);
gpio_request(OMAP_GPIO_CMC2AP_INT1, "gpio_61");
gpio_direction_input(OMAP_GPIO_CMC2AP_INT1);
omap_mux_init_signal("mcspi4_clk", OMAP_MUX_MODE0);
omap_mux_init_signal("mcspi4_simo", OMAP_MUX_MODE0);
omap_mux_init_signal("mcspi4_somi", OMAP_MUX_MODE0);
omap_mux_init_signal("mcspi4_cs0", OMAP_MUX_MODE0);
}
tuna_wlan_init();
tuna_audio_init();
tuna_i2c_init();
tuna_gsd4t_gps_init();
ramconsole_pdata.bootinfo = omap4_get_resetreason();
platform_add_devices(tuna_devices, ARRAY_SIZE(tuna_devices));
board_serial_init();
tuna_bt_init();
omap2_hsmmc_init(mmc);
usb_musb_init(&musb_board_data);
omap4_tuna_create_board_props();
if (TUNA_TYPE_TORO == omap4_tuna_get_type()) {
spi_register_board_info(tuna_lte_modem,
ARRAY_SIZE(tuna_lte_modem));
}
tuna_from_init();
omap_dmm_init();
omap4_tuna_display_init();
omap4_tuna_input_init();
omap4_tuna_nfc_init();
omap4_tuna_power_init();
omap4_tuna_jack_init();
omap4_tuna_sensors_init();
omap4_tuna_led_init();
omap4_tuna_connector_init();
omap4_tuna_pogo_init();
#ifdef CONFIG_OMAP_HSI_DEVICE
if (TUNA_TYPE_MAGURO == omap4_tuna_get_type())
omap_hsi_init();
#endif
#ifdef CONFIG_USB_EHCI_HCD_OMAP
if (TUNA_TYPE_TORO == omap4_tuna_get_type()) {
#ifdef CONFIG_SEC_MODEM
modem_toro_init();
#endif
omap4_ehci_init();
}
#endif
}
static void __init tuna_map_io(void)
{
omap2_set_globals_443x();
omap44xx_map_common_io();
}
static void __init tuna_reserve(void)
{
int i;
int ret;
/* do the static reservations first */
memblock_remove(TUNA_RAMCONSOLE_START, TUNA_RAMCONSOLE_SIZE);
memblock_remove(PHYS_ADDR_SMC_MEM, PHYS_ADDR_SMC_SIZE);
memblock_remove(PHYS_ADDR_DUCATI_MEM, PHYS_ADDR_DUCATI_SIZE);
for (i = 0; i < tuna_ion_data.nr; i++)
if (tuna_ion_data.heaps[i].type == ION_HEAP_TYPE_CARVEOUT ||
tuna_ion_data.heaps[i].type == OMAP_ION_HEAP_TYPE_TILER) {
ret = memblock_remove(tuna_ion_data.heaps[i].base,
tuna_ion_data.heaps[i].size);
if (ret)
pr_err("memblock remove of %x@%lx failed\n",
tuna_ion_data.heaps[i].size,
tuna_ion_data.heaps[i].base);
}
/* ipu needs to recognize secure input buffer area as well */
omap_ipu_set_static_mempool(PHYS_ADDR_DUCATI_MEM, PHYS_ADDR_DUCATI_SIZE +
OMAP_TUNA_ION_HEAP_SECURE_INPUT_SIZE);
omap_reserve();
}
#define PHOENIX_LAST_TURNOFF_STS 0x22
static int __init tuna_print_last_turnon_sts(void)
{
u8 turnon_sts;
int err;
err = twl_i2c_read_u8(TWL6030_MODULE_ID0, &turnon_sts,
PHOENIX_LAST_TURNOFF_STS);
if (!err) {
pr_info("PHOENIX_LAST_TURNOFF_STS: 0x%02x\n", turnon_sts);
twl_i2c_write_u8(TWL6030_MODULE_ID0, turnon_sts,
PHOENIX_LAST_TURNOFF_STS);
}
return 0;
}
device_initcall(tuna_print_last_turnon_sts);
MACHINE_START(TUNA, "Tuna")
/* Maintainer: Google, Inc */
.boot_params = 0x80000100,
.reserve = tuna_reserve,
.map_io = tuna_map_io,
.init_early = tuna_init_early,
.init_irq = gic_init_irq,
.init_machine = tuna_init,
.timer = &omap_timer,
MACHINE_END