diff options
Diffstat (limited to 'arch/arm/mach-omap2/board-omap3h1.c')
| -rw-r--r-- | arch/arm/mach-omap2/board-omap3h1.c | 495 |
1 files changed, 495 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/board-omap3h1.c b/arch/arm/mach-omap2/board-omap3h1.c new file mode 100644 index 00000000000..145efe4da76 --- /dev/null +++ b/arch/arm/mach-omap2/board-omap3h1.c @@ -0,0 +1,495 @@ +/* + * Copyright (C) 2014 Olio Devices, Inc. + * Authors: Evan Wilson <evan@oliodevices.com> + * Mattis Fjallstrom <mattis@oliodevices.com> + * + * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ + * + * Modified from the original mach-omap/omap2/board-generic.c did by Paul + * to support the OMAP2+ device tree boards with an unique board file. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/platform_device.h> +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/clk.h> +#include <linux/io.h> +#include <linux/opp.h> +#include <linux/cpu.h> +#include <linux/mpu.h> +#include <linux/spi/spi.h> +#include <linux/mtd/mtd.h> +#include <linux/mtd/partitions.h> +#include <linux/mtd/nand.h> + +#include <linux/usb/musb.h> +#include <linux/usb/phy.h> +#include <linux/usb/nop-usb-xceiv.h> + +#include <linux/i2c/atmel_mxt_ts.h> +#include <linux/gpio.h> + +#include <linux/regulator/machine.h> +#include <linux/regulator/fixed.h> +#include <linux/mfd/tps65910.h> + +#include <linux/wakelock.h> /* used in interrupt, waking up. */ +#include <linux/debugfs.h> + +#include <linux/led-lm3530.h> + +#include <asm/mach-types.h> +#include <asm/mach/arch.h> +#include <asm/mach/map.h> +#include <asm/mach/flash.h> + +#include <video/omapdss.h> +#include <video/omap-panel-data.h> +#include <linux/platform_data/mtd-nand-omap2.h> +#include <linux/platform_data/serial-omap.h> +#include <linux/interrupt.h> + +#include <linux/of_irq.h> +#include <linux/of_platform.h> + + +#include "common.h" +#include "omap_device.h" +#include "gpmc.h" +#include "soc.h" +#include "mux.h" +#include "pm.h" +#include "board-flash.h" +#include "common-board-devices.h" +#include "board-omap3h1.h" +#include "prm2xxx_3xxx.h" +#include "prm-regbits-34xx.h" + +#include "sdram-micron-mt29c8g96m-48.h" + +#define NAND_CS 0 + +#define MPUIRQ_GPIO 31 +#define ATMEL_MXT_GPIO 105 +#define TPS_SYS_NIRQ 0 +#define USB_IRQ 124 +#define USB_CS 17 + +#define DEFAULT_RXDMA_POLLRATE 1 /* RX DMA polling rate (us) */ +#define DEFAULT_RXDMA_BUFSIZE 4096 /* RX DMA buffer size */ +#define DEFAULT_RXDMA_TIMEOUT (3 * HZ)/* RX DMA timeout (jiffies) */ + +#if defined(CONFIG_MACH_OMAP3_H1_DVT1) || defined(CONFIG_MACH_OMAP3_H1_DVT2) || defined (CONFIG_MACH_OMAP3_H1_PV) +#define LCD_RESET_GPIO 94 +#else +#define LCD_RESET_GPIO 122 +#endif + +static struct of_device_id omap_dt_match_table[] __initdata = { + { .compatible = "olio,omap3-h1", }, + { .compatible = "simple-bus", }, + { .compatible = "ti,omap-infra", }, + { } +}; + +static struct mtd_partition omap3h1_nand_partitions[] = { + /* All the partition sizes are listed in terms of NAND block size */ + { + .name = "X-Loader", + .offset = 0, + .size = 4 * NAND_BLOCK_SIZE, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + { + .name = "U-Boot", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */ + .size = 15 * NAND_BLOCK_SIZE, + .mask_flags = MTD_WRITEABLE, /* force read-only */ + }, + { + .name = "U-Boot Env", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x260000 */ + .size = 1 * NAND_BLOCK_SIZE, + }, + { + .name = "kernel", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x280000 */ + .size = 40 * NAND_BLOCK_SIZE, + }, + { + .name = "initramfs", + .offset = MTDPART_OFS_APPEND, /* Offset = 0xC80000 */ + .size = 80 * NAND_BLOCK_SIZE, + }, + { + .name = "ramdisk", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x1180000 */ + .size = 40 * NAND_BLOCK_SIZE, + }, + { + .name = "system", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x1680000 */ + .size = 2000 * NAND_BLOCK_SIZE, + }, + { + .name = "userdata", + .offset = MTDPART_OFS_APPEND, /* Offset = 0x11180000 */ + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct omap_dss_device omap3h1_lcd_device = { + .type = OMAP_DISPLAY_TYPE_DPI, + .name = "olio_h1_panel", + .driver_name = "ili9342_panel", + .phy.dpi.data_lines = 18, + .reset_gpio = LCD_RESET_GPIO, +}; + +static struct omap_dss_device *omap3h1_dss_devices[] = { + &omap3h1_lcd_device, +}; + +static struct omap_dss_board_info omap3h1_dss_data = { + .num_devices = 1, + .devices = omap3h1_dss_devices, + .default_device = &omap3h1_lcd_device, +}; + +static struct spi_board_info omap3h1_spi_board_info[] __initdata = { + { + .modalias = "ili9342-spi", + .bus_num = 1, + .chip_select = 1, + .max_speed_hz = 375000, + .platform_data = &omap3h1_lcd_device, + .mode = SPI_MODE_0, + } +}; + +static int __init omap3h1_spi_init(void) { + spi_register_board_info(omap3h1_spi_board_info, + ARRAY_SIZE(omap3h1_spi_board_info)); + return 0; +} + + +/* + * int_config is interrupt config, INT_ENABLE register. To enable _all_ + * interrupts, set to 0x59. I think. --mfj + * + * Level shifter seems to set power rail between two options - 1 means VDD. + * (0 means VLogic, which I'm not sure what it is). + */ + +#ifndef CONFIG_MACH_OMAP3_H1_PV2 +static struct mpu_platform_data mpu_data = { + .int_config = 0x00, + .level_shifter = 1, + .orientation = { 0, -1, 0, + -1, 0, 0, + 0, 0, 1 }, +}; +#endif + +static struct lm3530_platform_data omap3h1_backlight_platform_data = { + .mode = LM3530_BL_MODE_MANUAL, + //.als_input_mode = LM3530_INPUT_ALS1, + .max_current = LM3530_FS_CURR_29mA, + //.pwm_pol_hi = true, + //.als_avrg_time = LM3530_ALS_AVRG_TIME_512ms, + .brt_ramp_law = 0, + .brt_ramp_fall = LM3530_RAMP_TIME_1s, /* LM3530_RAMP_TIME_1s, */ + .brt_ramp_rise = LM3530_RAMP_TIME_1s, /* LM3530_RAMP_TIME_1s, */ + //.als1_resistor_sel = LM3530_ALS_IMPD_13_53kOhm, + //.als2_resistor_sel = LM3530_ALS_IMPD_Z, + //.als_vmin = 730, /* mV */ + //.als_vmax = 10a20, /* mV */ + .brt_val = 0x64, /* initial brightness */ +}; + + + +static struct mxt_platform_data mxt_data = { + .irqflags = IRQF_TRIGGER_FALLING, +}; + + +static struct platform_device bcm20702_bluetooth_device = { + .name = "bcm20702_bluetooth", + .id = -1, +}; + +static struct platform_device omap3h1_dmic_codec = { + .name = "dmic-codec", + .id = -1, +}; + +/* --------------------------------------------------------------------------- */ +/* USB settings + */ + + + +static struct omap_musb_board_data musb_board_data = { + .interface_type = MUSB_INTERFACE_ULPI, + .mode = MUSB_OTG, + .power = 100, +}; + +static struct nop_usb_xceiv_platform_data nop_plat_data = { + .type = USB_PHY_TYPE_USB2, + .clk_rate = 60000000, /* 60 MHz */ + .needs_vcc = 1, + .needs_reset = 0, +}; + +static struct platform_device nop_phy_device = { + .name = "nop_usb_xceiv", + .id = -1, + .dev = { + .platform_data = &nop_plat_data, + }, +}; + + +/* static struct usbhs_omap_platform_data usbhs_bdata __initdata = { */ +/* .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY, */ +/* }; */ + + + + +/* ====================================================================== */ + + +static struct i2c_board_info __initdata omap3h1_i2c1_board_info[] = { + { + }, +#if defined (CONFIG_MACH_OMAP3_H1_DVT2) || defined (CONFIG_MACH_OMAP3_H1_PV) +}; +static struct i2c_board_info __initdata omap3h1_i2c2_board_info[] = { +#endif + { +#ifdef CONFIG_MACH_OMAP3_H1_PV2 + I2C_BOARD_INFO("lsm6ds3", 0x6a), +#else + I2C_BOARD_INFO("mpu6515", 0x68), + .platform_data = &mpu_data, +#endif + }, + { + /* Backlight */ + I2C_BOARD_INFO("lm3530-led", 0x38), + .platform_data = &omap3h1_backlight_platform_data, + }, + { + I2C_BOARD_INFO("mXT224", 0x4a), + .platform_data = &mxt_data, + }, + { + I2C_BOARD_INFO("cm3391", 0x10), + }, +#ifdef CONFIG_MACH_OMAP3_H1_EVT1 +}; +static struct i2c_board_info __initdata omap3h1_i2c3_board_info[] = { +#endif + { + I2C_BOARD_INFO("bq274xx", 0x55), + }, +}; + + +/*************************************************************************** + * omap_uart data + */ + +/* Some notes: + .dma_enabled = false, + .dma_rx_buf_size = DEFAULT_RXDMA_BUFSIZE, + .dma_rx_poll_rate = DEFAULT_RXDMA_POLLRATE, + .dma_rx_timeout = DEFAULT_RXDMA_TIMEOUT, + .autosuspend_timeout = DEFAULT_AUTOSUSPEND_DELAY, ( -1 or X ms. ) + + .wakelock_timeout - for minnow, this is 150 (BT) or 50 (M4 debug). + Can be left out. + + .DTR_* -> can be left out. I can't find anyone using it. + + int DTR_gpio; + int DTR_inverted; + int DTR_present; + bool wakeup_capable; + + bool open_close_pm; - Minnow uses this for c55 only + unsigned int rx_trig; Minnow, BT & debug only +*/ + +static struct omap_uart_port_info omap_uart_ports[] = { + { + .dma_enabled = false, /* To specify DMA Mode */ + .dma_rx_buf_size = DEFAULT_RXDMA_BUFSIZE, + .dma_rx_timeout = DEFAULT_RXDMA_TIMEOUT, + .dma_rx_poll_rate = DEFAULT_RXDMA_POLLRATE, + .autosuspend_timeout = 1000, + .wakelock_timeout = 150, + .wake_peer = bcm_bt_lpm_exit_lpm_locked, + .wakeup_capable = true, + .rx_trig = 0x3, + }, + { + .dma_enabled = false, /* To specify DMA Mode */ + .dma_rx_buf_size = DEFAULT_RXDMA_BUFSIZE, + .dma_rx_timeout = DEFAULT_RXDMA_TIMEOUT, + .dma_rx_poll_rate = DEFAULT_RXDMA_POLLRATE, + .autosuspend_timeout = 0, + .wakeup_capable = false, + }, + { + .dma_enabled = false, /* To specify DMA Mode */ + .dma_rx_buf_size = DEFAULT_RXDMA_BUFSIZE, + .dma_rx_timeout = DEFAULT_RXDMA_TIMEOUT, + .dma_rx_poll_rate = DEFAULT_RXDMA_POLLRATE, + .autosuspend_timeout = -1, + .wakeup_capable = true, + }, + { + .dma_enabled = false, /* To specify DMA Mode */ + .dma_rx_buf_size = DEFAULT_RXDMA_BUFSIZE, + .dma_rx_timeout = DEFAULT_RXDMA_TIMEOUT, + .dma_rx_poll_rate = DEFAULT_RXDMA_POLLRATE, + .autosuspend_timeout = 0, + .wakeup_capable = false, + }, +}; + + +/*************************************************************************** + * omap3_h1_i2c_init - init the i2c buses + * + */ + +static int __init omap3_h1_i2c_init(void) +{ + int acc_irq; + + /* In Linux 3.10 we need to request an IRQ through + * gpio_to_irq. This means it can't be set at compile time, and + * must be done at runtime. In other words, here. + */ + + gpio_request_one(ATMEL_MXT_GPIO, GPIOF_IN, "atmel_mxt_ts CHG"); + gpio_request_one(MPUIRQ_GPIO, GPIOF_IN, "Accl IRQ pin"); + + acc_irq = gpio_to_irq(MPUIRQ_GPIO); + +#if defined (CONFIG_MACH_OMAP3_H1_DVT2) || defined (CONFIG_MACH_OMAP3_H1_PV) + omap3h1_i2c2_board_info[2].irq = gpio_to_irq(ATMEL_MXT_GPIO); + omap3h1_i2c2_board_info[0].irq = acc_irq; +#else + omap3h1_i2c1_board_info[3].irq = gpio_to_irq(ATMEL_MXT_GPIO); + omap3h1_i2c1_board_info[1].irq = acc_irq; +#endif + + gpio_request_one(USB_CS, GPIOF_OUT_INIT_HIGH, "USB on"); + + /* Register buses */ + + // omap_register_i2c_bus(1, 400, omap3h1_i2c1_board_info, ARRAY_SIZE(omap3h1_i2c1_board_info)); +#if defined (CONFIG_MACH_OMAP3_H1_DVT2) || defined (CONFIG_MACH_OMAP3_H1_PV) + omap_register_i2c_bus(2, 400, omap3h1_i2c2_board_info, ARRAY_SIZE(omap3h1_i2c2_board_info)); +#else + omap_register_i2c_bus(2, 400, NULL, 0); +#endif +#ifdef CONFIG_MACH_OMAP3_H1_EVT1 + omap_register_i2c_bus(3, 400, omap3h1_i2c3_board_info, ARRAY_SIZE(omap3h1_i2c3_board_info)); +#else + omap_register_i2c_bus(3, 400, NULL, 0); +#endif + return 0; +} + + +static struct platform_device *omap3h1_devices[] __initdata = { + &bcm20702_bluetooth_device, + &nop_phy_device, + &omap3h1_dmic_codec, +}; + +static void __init omap3_h1_init(void) +{ + /* Read what we can from the device tree */ + + of_platform_populate(NULL, omap_dt_match_table, NULL, NULL); + +#ifdef CONFIG_MACH_OMAP3_H1_PV + /* The PV units need reversed polarity for the sysclkreq pin. */ + + omap2_prm_rmw_mod_reg_bits(OMAP3430_CLKREQ_POL_MASK, + 0, OMAP3430_GR_MOD, + OMAP3_PRM_POLCTRL_OFFSET); +#endif + + board_nand_init(omap3h1_nand_partitions, + ARRAY_SIZE(omap3h1_nand_partitions), NAND_CS, + NAND_BUSWIDTH_16, NULL); + + omap_sdrc_init(mt29c8g96_sdrc_params, mt29c8g96_sdrc_params); + + omap3_h1_i2c_init(); + + platform_add_devices(omap3h1_devices, ARRAY_SIZE(omap3h1_devices)); + + omap3h1_spi_init(); + + omap_serial_board_init(omap_uart_ports); + + omap_display_init(&omap3h1_dss_data); + + usb_bind_phy("musb-hdrc.0.auto", 0, "nop_usb_xceiv"); /* "tusb-usb-h1" */ + + usb_musb_init(&musb_board_data); +} + +static const char *omap3_h1_boards_compat[] __initdata = { + "olio,omap3-h1", + NULL, +}; + +DT_MACHINE_START(OMAP3_H1, "Olio OMAP3 H1 (Flattened Device Tree)") + .atag_offset = 0x100, + .reserve = omap_reserve, + .map_io = omap3_map_io, + .init_early = omap3630_init_early, + /* .init_irq = omap3_init_irq, */ + .init_irq = omap_intc_of_init, + .handle_irq = omap3_intc_handle_irq, + .init_machine = omap3_h1_init, + .init_late = omap3630_init_late, + .init_time = omap3_sync32k_timer_init, + /* .init_time = omap3_secure_sync32k_timer_init, */ + .dt_compat = omap3_h1_boards_compat, + .restart = omap3xxx_restart, +MACHINE_END + +#if 0 /* removing ... for now */ +MACHINE_START(OMAP3_H1, "Olio OMAP3 H1 Board") + .atag_offset = 0x100, + .reserve = omap_reserve, + .map_io = omap3_map_io, + .init_early = omap3630_init_early, + .init_irq = omap3_init_irq, + .handle_irq = omap3_intc_handle_irq, + .init_machine = omap3_h1_init, + .init_late = omap3630_init_late, + .init_time = omap3_sync32k_timer_init, + /* .init_time = omap3_secure_sync32k_timer_init, */ + /* .dt_compat = omap3_h1_boards_compat, */ + .restart = omap3xxx_restart, +MACHINE_END +#endif |