blob: f884f229dfe435a60b5ecc675bb2faeb9538724f [file] [log] [blame]
/*
* Copyright (c) 2010-2012 Nest Labs, Inc.
*
* Author: Grant Erickson <grant@nestlabs.com>
*
* 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.
*
* Description:
* This file is the core Linux board support file for the Nest
* Diamond board. It was originally cloned from the Texas
* Instruments OMAP3 EVM board file.
*
* SDRAM Controller (SDRC):
* - Samsung K4X51163PI-FCG6 512 Mb x 16 (64 MiB) DDR SDRAM
* - Nanya NT6D 512Mb x 16 (64MiB) DDR SDRAM
*
* General Purpose Memory Controller (GPMC):
* - Micron MT29F2G16ABDHC-ET 256 MiB SLC NAND Flash (Development)
* - Micron MT29F2G16ABBEAH4 256 MiB SLC NAND Flash (Non-development)
* - Samsung K9F4G08U0C 512 MiB SLC NAND Flash (Development Only)
* - SMSC LAN9220 10/100 Mbit Ethernet MAC and PHY (Development Only)
*
* Multimedia Card (MMC) Interface:
* - Molex 500998-0900 Secure Digital (SD) Connector (Development Only)
* - Wireless LAN (WLAN) Module
*
* Display Subsystem (DSS):
* - Samsung LMS350DF03 HVGA (320 x 480) LCM (Development and Prototype)
* - Tianma TM025ZDZ01 (320 x 320) LCM (Production)
*
* Camera Image Signal Processor:
* - Unused
*
* Inter-Integrated Circuit (I2C) Controller:
* - Channel 1:
* * Texas Instruments TPS65921 Power Management Unit (PMU)
*
* - Channel 2:
* * Silicon Labs 1143 Proximity / Ambient Light Sensor (Development Only)
* * Avago ADBS A330 Optical Finger Navigation (OFN) Sensor (Non-development)
*
* - Channel 3:
* * Unused
*
* - Channel 4:
* * Texas Instruments TPS65921 Power Management Unit (PMU)
*
* UART Controller:
* - Channel 1:
* * Head Unit Serial Console
*
* - Channel 2:
* * ZigBee Wireless Module
*
* Multichannel Buffered Serial Port (McBSP):
* - Channel 1:
* * Unused
*
* - Channel 2:
* * Unused
*
* - Channel 3:
* * UART2
*
* - Channel 4:
* * Unavailable
*
* - Channel 5:
* * Unavailable
*
* Multichannel Serial Peripheral Interface (McSPI):
* - Channel 1:
* * Unused
*
* - Channel 2:
* * Samsung LMS350DF03 HVGA (320 x 480) LCM (Development and Prototype)
* * Tianma TM025ZDZ01 (320 x 320) LCM (Production)
*
* - Channel 3:
* * Unavailable
*
* Interrupt Controller:
* - SMSC LAN9220 10/100 Mbit Ethernet MAC and PHY (Development Only)
* - Si1143 Proximity / Ambient Light Sensor (Development Only)
*
* GPIO Controller:
* - Bank 1:
* - Bank 2:
* * 2.11 (43) Samsung LMS350DF03 LCD 1.8V to 3.3V Buffer #Enable (Development Only)
*
* - Bank 3:
* - Bank 4:
* * 4.5 (101) Samsung LMS350DF03 LCD 3.3V Supply Enable (Development Only)
* * 4.13 (109) Samsung LMS350DF03 LCD #Reset
*
* - Bank 5:
* - Bank 6:
*
* - Backplate Detect
* - Battery Disconnect
* - ZigBee Wireless Module
*/
#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/gpio.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/backlight.h>
#include <linux/pwm_backlight.h>
#include <linux/omapfb.h>
#include <linux/si1143.h>
#include <linux/spi/spi.h>
#include <linux/spi/ili9481.h>
#include <linux/spi/lms350df03.h>
#include <linux/spi/s6d05a1.h>
#include <linux/wl12xx.h>
#include <linux/i2c/twl.h>
#include <linux/usb/otg.h>
#include <linux/usb/dynamic.h>
#include <linux/usb/msc.h>
#include <linux/smsc911x.h>
#include <linux/rotary_encoder_lite.h>
#include <linux/rtc.h>
#include <linux/adbs-a330.h>
#include <linux/mmc/host.h>
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/nand.h>
#include <linux/regulator/consumer.h>
#include <linux/regulator/fixed.h>
#include <linux/regulator/machine.h>
#include <linux/input/pwm-beeper.h>
#include <linux/lm3530_bl.h>
#include <linux/lm3530_bl.h>
#include <linux/r61529a1.h>
#include <mach/board-diamond-gpio.h>
#include <mach/board-j49-gpio.h>
#include <mach/hardware.h>
#include <asm/system.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <plat/board.h>
#include <plat/onenand.h>
#include <plat/gpmc.h>
#include <plat/nand.h>
#include <plat/common.h>
#include <plat/usb.h>
#include <plat/mcspi.h>
#include <plat/clock.h>
#include <plat/omap-pm.h>
#include <plat/display.h>
#include <plat/pwm.h>
#include "mux.h"
#include "hsmmc.h"
#include "sdram-samsung-k4x51163pi-nanya-nt6d.h"
#include "pm.h"
#include "prm-regbits-34xx.h"
#include "board-diamond-battery.h"
#include "board-diamond-backplate.h"
#include "board-diamond-nlmodel.h"
#include "control.h"
#include "board-diamond-zigbee.h"
/* Preprocessor Definitions */
#define diamond_gpio_try_request(gpio, string, action) \
if (unlikely(gpio_request(gpio, string))) { \
printk(KERN_ERR \
"Failed to request GPIO %u " string "\n", gpio); \
action; \
} \
#define diamond_gpio_try_output(gpio, value, action) \
do { \
diamond_gpio_try_request(gpio, #gpio, action); \
if (gpio_direction_output(gpio, value) < 0) { \
printk(KERN_ERR \
"Could not set GPIO %u " #gpio \
" as an output with value %u\n", \
gpio, value); \
action; \
} \
} while (0)
#define diamond_gpio_try_input(gpio, action) \
do { \
diamond_gpio_try_request(gpio, #gpio, action); \
if (gpio_direction_input(gpio) < 0) { \
printk(KERN_ERR \
"Could not set GPIO %u " #gpio \
" as an input\n", gpio); \
action; \
} \
} while (0)
#define machine_warn(format, ...) pr_warning("Machine: " format, ## __VA_ARGS__)
#define machine_info(format, ...) pr_info("Machine: " format, ## __VA_ARGS__)
#define GPMC_CS0_BASE 0x60
#define GPMC_CS_SIZE 0x30
#define DIAMOND_ETHR_START 0x2c000000
#define DIAMOND_ETHR_SIZE 1024
#define DIAMOND_ETHR_ID_REV 0x50
#define DIAMOND_SMSC911X_CS 5
#define DIAMOND_BACKLIGHT_PWM_ID 0
#define DIAMOND_PIEZO_PWM_ID 1
#define DIAMOND_ADBS_A330_VDDA_SUPPLY "vdda"
#define DIAMOND_ADBS_A330_VDDA_UV 3000000
#define NEST_USB_VENDOR_STRING "Nest"
#define DIAMOND_USB_VENDOR_STRING NEST_USB_VENDOR_STRING
#define DIAMOND_USB_PRODUCT_STRING "Learning Thermostat"
#define DIAMOND_USB_SERIAL_STRING_SIZE ((sizeof(u64) * 2) + 1)
#define J49_USB_VENDOR_STRING NEST_USB_VENDOR_STRING
#define J49_USB_PRODUCT_STRING "Learning Thermostat"
#define J49_USB_SERIAL_STRING_SIZE ((sizeof(u64) * 2) + 1)
#define NEST_USB_VENDOR_ID 0x2464
#define DIAMOND_USB_VENDOR_ID 0x2464
#define DIAMOND_USB_PRODUCT_ID 0x0001
#define J49_USB_VENDOR_ID 0x2464
#define J49_USB_PRODUCT_ID 0x0002
/* NOTE: SCSI Inquiry (which is how USB Mass Storage Class (MSC)
* vendor and product strings are queried), are limited to 8 and 16
* ASCII characters, for vendor and product, respectively.
*/
#define DIAMOND_MSC_VENDOR_STRING "Nest"
#define DIAMOND_MSC_PRODUCT_STRING "Nest"
#define DIAMOND_MSC_RELEASE 1
/* Type Definitions */
enum {
DIAMOND_SPI_LCD,
J49_SPI_DEV
};
enum {
DIAMOND_DEVELOPMENT_DATA = 0,
DIAMOND_1_4_DATA = 1,
DIAMOND_1_5_DATA = 2,
DIAMOND_1_6_DATA = 3,
DIAMOND_1_7_DATA = 4,
DIAMOND_1_8_DATA = 5,
DIAMOND_1_9_DATA = 6,
DISPLAY_2_0_DATA = 7,
DISPLAY_2_1_DATA = 8,
DISPLAY_2_2_DATA = 9,
DISPLAY_2_3_DATA = 10,
DISPLAY_2_4_DATA = 11,
DISPLAY_2_11_DATA = 12
};
struct diamond_init_data {
const char *name;
void (*add_devices)(void);
void (*backplate_init)(const struct nlmodel *model);
void (*clk_init)(void);
void (*display_init)(void);
void (*flash_init)(void);
void (*i2c_init)(void);
void (*mmc_init)(void);
void (*mux_init)(void);
void (*net_init)(void);
void (*piezo_init)(void);
void (*power_init)(void);
void (*regulator_init)(void);
void (*serial_init)(void);
void (*spi_init)(void);
void (*usb_init)(void);
};
static struct omap_musb_board_data musb_board_data = {
.interface_type = MUSB_INTERFACE_ULPI,
.mode = MUSB_PERIPHERAL,
.power = 50,
};
/* Function Prototypes */
extern void twl4030_poweroff(void);
static int diamond_development_enable_lcd(struct omap_dss_device *dssdev);
static void diamond_development_disable_lcd(struct omap_dss_device *dssdev);
static int diamond_backlight_notify(struct device *dev, int brightness);
static void __init diamond_backplate_init(const struct nlmodel *model);
static void __init diamond_clk_init(void);
static void __init diamond_flash_init(void);
static void __init diamond_irq_init(void);
static void __init diamond_serial_init(void);
static void __init diamond_usb_init(void);
static void __init diamond_development_add_devices(void);
static void __init diamond_development_display_init(void);
static void __init diamond_development_i2c_init(void);
static void __init diamond_development_mmc_init(void);
static void __init diamond_development_mux_init(void);
static void __init diamond_development_net_init(void);
static void __init diamond_development_regulator_init(void);
static void __init diamond_development_spi_init(void);
static void __init diamond_1_4_add_devices(void);
static void __init diamond_1_4_display_init(void);
static void __init diamond_1_4_i2c_init(void);
static void __init diamond_1_4_mmc_init(void);
static void __init diamond_1_4_mux_init(void);
static void __init diamond_1_4_net_init(void);
static void __init diamond_1_4_piezo_init(void);
static void __init diamond_1_4_regulator_init(void);
static void __init diamond_1_4_spi_init(void);
static void __init diamond_1_4_power_init(void);
static void __init diamond_1_5_add_devices(void);
static void __init diamond_1_5_display_init(void);
static void __init diamond_1_5_i2c_init(void);
static void __init diamond_1_5_mmc_init(void);
static void __init diamond_1_5_mux_init(void);
static void __init diamond_1_5_net_init(void);
static void __init diamond_1_5_piezo_init(void);
static void __init diamond_1_5_regulator_init(void);
static void __init diamond_1_5_spi_init(void);
static void __init diamond_1_6_add_devices(void);
static void __init diamond_1_6_i2c_init(void);
static void __init diamond_1_6_mux_init(void);
static void __init diamond_1_6_power_init(void);
static void __init diamond_1_7_add_devices(void);
static void __init diamond_1_7_mux_init(void);
static void __init diamond_1_7_spi_init(void);
static void __init display_2_0_add_devices(void);
static void __init display_2_0_i2c_init(void);
static void __init display_2_0_mux_init(void);
static void __init display_2_0_spi_init(void);
static void __init display_2_0_net_init(void);
static void __init display_2_1_mux_init(void);
static void __init display_2_11_display_init(void);
static void __init display_2_11_regulator_init(void);
/* Global Variables */
static const char *diamond_family = "Diamond";
static const int diamond_product_default = 1;
static const int diamond_revision_default = 10;
static const char *j49_family = "Display";
static const int j49_product_default = 2;
static struct diamond_init_data diamond_development_data __initdata = {
.name = "Development",
.add_devices = diamond_development_add_devices,
.backplate_init = diamond_backplate_init,
.clk_init = diamond_clk_init,
.display_init = diamond_development_display_init,
.flash_init = diamond_flash_init,
.i2c_init = diamond_development_i2c_init,
.mmc_init = diamond_development_mmc_init,
.mux_init = diamond_development_mux_init,
.net_init = diamond_development_net_init,
.piezo_init = NULL,
.power_init = NULL,
.regulator_init = diamond_development_regulator_init,
.serial_init = diamond_serial_init,
.spi_init = diamond_development_spi_init,
.usb_init = diamond_usb_init
};
static struct diamond_init_data diamond_1_4_data __initdata = {
.name = "Prototype",
.add_devices = diamond_1_4_add_devices,
.backplate_init = diamond_backplate_init,
.clk_init = diamond_clk_init,
.display_init = diamond_1_4_display_init,
.flash_init = diamond_flash_init,
.i2c_init = diamond_1_4_i2c_init,
.mmc_init = diamond_1_4_mmc_init,
.mux_init = diamond_1_4_mux_init,
.net_init = diamond_1_4_net_init,
.piezo_init = diamond_1_4_piezo_init,
.power_init = diamond_1_4_power_init,
.regulator_init = diamond_1_4_regulator_init,
.serial_init = diamond_serial_init,
.spi_init = diamond_1_4_spi_init,
.usb_init = diamond_usb_init
};
static struct diamond_init_data diamond_1_5_data __initdata = {
.name = "Prototype",
.add_devices = diamond_1_5_add_devices,
.backplate_init = diamond_backplate_init,
.clk_init = diamond_clk_init,
.display_init = diamond_1_5_display_init,
.flash_init = diamond_flash_init,
.i2c_init = diamond_1_5_i2c_init,
.mmc_init = diamond_1_5_mmc_init,
.mux_init = diamond_1_5_mux_init,
.net_init = diamond_1_5_net_init,
.piezo_init = diamond_1_5_piezo_init,
.power_init = diamond_1_4_power_init,
.regulator_init = diamond_1_5_regulator_init,
.serial_init = diamond_serial_init,
.spi_init = diamond_1_5_spi_init,
.usb_init = diamond_usb_init
};
static struct diamond_init_data diamond_1_6_data __initdata = {
.name = "EVT",
.add_devices = diamond_1_6_add_devices,
.backplate_init = diamond_backplate_init,
.clk_init = diamond_clk_init,
.display_init = diamond_1_5_display_init,
.flash_init = diamond_flash_init,
.i2c_init = diamond_1_6_i2c_init,
.mmc_init = diamond_1_5_mmc_init,
.mux_init = diamond_1_6_mux_init,
.net_init = diamond_1_5_net_init,
.piezo_init = diamond_1_5_piezo_init,
.power_init = diamond_1_6_power_init,
.regulator_init = diamond_1_5_regulator_init,
.serial_init = diamond_serial_init,
.spi_init = diamond_1_5_spi_init,
.usb_init = diamond_usb_init
};
static struct diamond_init_data diamond_1_7_data __initdata = {
.name = "DVT",
.add_devices = diamond_1_7_add_devices,
.backplate_init = diamond_backplate_init,
.clk_init = diamond_clk_init,
.display_init = diamond_1_5_display_init,
.flash_init = diamond_flash_init,
.i2c_init = diamond_1_6_i2c_init,
.mmc_init = diamond_1_5_mmc_init,
.mux_init = diamond_1_7_mux_init,
.net_init = diamond_1_5_net_init,
.piezo_init = diamond_1_5_piezo_init,
.power_init = diamond_1_6_power_init,
.regulator_init = diamond_1_5_regulator_init,
.serial_init = diamond_serial_init,
.spi_init = diamond_1_7_spi_init,
.usb_init = diamond_usb_init
};
static struct diamond_init_data display_2_0_data __initdata = {
.name = "Prototype",
.add_devices = display_2_0_add_devices,
.backplate_init = diamond_backplate_init,
.clk_init = diamond_clk_init,
.display_init = diamond_1_5_display_init,
.flash_init = diamond_flash_init,
.i2c_init = display_2_0_i2c_init,
.mmc_init = diamond_1_5_mmc_init,
.mux_init = display_2_0_mux_init,
.net_init = display_2_0_net_init,
.piezo_init = diamond_1_5_piezo_init,
.power_init = diamond_1_6_power_init,
.regulator_init = diamond_1_5_regulator_init,
.serial_init = diamond_serial_init,
.spi_init = display_2_0_spi_init,
.usb_init = diamond_usb_init
};
static struct diamond_init_data display_2_1_data __initdata = {
.name = "EVT",
.add_devices = display_2_0_add_devices,
.backplate_init = diamond_backplate_init,
.clk_init = diamond_clk_init,
.display_init = diamond_1_5_display_init,
.flash_init = diamond_flash_init,
.i2c_init = display_2_0_i2c_init,
.mmc_init = diamond_1_5_mmc_init,
.mux_init = display_2_1_mux_init,
.net_init = display_2_0_net_init,
.piezo_init = diamond_1_5_piezo_init,
.power_init = diamond_1_6_power_init,
.regulator_init = diamond_1_5_regulator_init,
.serial_init = diamond_serial_init,
.spi_init = display_2_0_spi_init,
.usb_init = diamond_usb_init
};
static struct diamond_init_data display_2_2_data __initdata = {
.name = "DVT",
.add_devices = display_2_0_add_devices,
.backplate_init = diamond_backplate_init,
.clk_init = diamond_clk_init,
.display_init = diamond_1_5_display_init,
.flash_init = diamond_flash_init,
.i2c_init = display_2_0_i2c_init,
.mmc_init = diamond_1_5_mmc_init,
.mux_init = display_2_1_mux_init,
.net_init = display_2_0_net_init,
.piezo_init = diamond_1_5_piezo_init,
.power_init = diamond_1_6_power_init,
.regulator_init = diamond_1_5_regulator_init,
.serial_init = diamond_serial_init,
.spi_init = display_2_0_spi_init,
.usb_init = diamond_usb_init
};
static struct diamond_init_data display_2_3_data __initdata = {
.name = "Pre-PVT",
.add_devices = display_2_0_add_devices,
.backplate_init = diamond_backplate_init,
.clk_init = diamond_clk_init,
.display_init = diamond_1_5_display_init,
.flash_init = diamond_flash_init,
.i2c_init = display_2_0_i2c_init,
.mmc_init = diamond_1_5_mmc_init,
.mux_init = display_2_1_mux_init,
.net_init = display_2_0_net_init,
.piezo_init = diamond_1_5_piezo_init,
.power_init = diamond_1_6_power_init,
.regulator_init = diamond_1_5_regulator_init,
.serial_init = diamond_serial_init,
.spi_init = display_2_0_spi_init,
.usb_init = diamond_usb_init
};
static struct diamond_init_data display_2_4_data __initdata = {
.name = "PVT",
.add_devices = display_2_0_add_devices,
.backplate_init = diamond_backplate_init,
.clk_init = diamond_clk_init,
.display_init = diamond_1_5_display_init,
.flash_init = diamond_flash_init,
.i2c_init = display_2_0_i2c_init,
.mmc_init = diamond_1_5_mmc_init,
.mux_init = display_2_1_mux_init,
.net_init = display_2_0_net_init,
.piezo_init = diamond_1_5_piezo_init,
.power_init = diamond_1_6_power_init,
.regulator_init = diamond_1_5_regulator_init,
.serial_init = diamond_serial_init,
.spi_init = display_2_0_spi_init,
.usb_init = diamond_usb_init
};
static struct diamond_init_data display_2_11_data __initdata = {
.name = "D2D",
.add_devices = display_2_0_add_devices,
.backplate_init = diamond_backplate_init,
.clk_init = diamond_clk_init,
.display_init = display_2_11_display_init,
.flash_init = diamond_flash_init,
.i2c_init = display_2_0_i2c_init,
.mmc_init = diamond_1_5_mmc_init,
.mux_init = display_2_1_mux_init,
.net_init = display_2_0_net_init,
.piezo_init = diamond_1_5_piezo_init,
.power_init = diamond_1_6_power_init,
.regulator_init = display_2_11_regulator_init,
.serial_init = diamond_serial_init,
.spi_init = display_2_0_spi_init,
.usb_init = diamond_usb_init
};
static struct diamond_init_data *diamond_init_data[] __initdata = {
[DIAMOND_DEVELOPMENT_DATA] = &diamond_development_data,
[DIAMOND_1_4_DATA] = &diamond_1_4_data,
[DIAMOND_1_5_DATA] = &diamond_1_5_data,
[DIAMOND_1_6_DATA] = &diamond_1_6_data,
[DIAMOND_1_7_DATA] = &diamond_1_7_data,
[DIAMOND_1_8_DATA] = &diamond_1_7_data,
[DIAMOND_1_9_DATA] = &diamond_1_7_data,
[DISPLAY_2_0_DATA] = &display_2_0_data,
[DISPLAY_2_1_DATA] = &display_2_1_data,
[DISPLAY_2_2_DATA] = &display_2_2_data,
[DISPLAY_2_3_DATA] = &display_2_3_data,
[DISPLAY_2_4_DATA] = &display_2_4_data,
[DISPLAY_2_11_DATA] = &display_2_11_data
};
static bool lcd_enabled = false;
#if defined(CONFIG_HAVE_PWM)
/* OMAP-specific implementations of generic PWM devices required to
* support the OMAP PWM-driven backlight and piezo devices.
*/
static struct omap2_pwm_platform_config diamond_backlight_pwm_config = {
.timer_id = 10, // GPT10_PWM_EVT
.polarity = 1 // Active-high
};
static struct omap2_pwm_platform_config diamond_piezo_pwm_config = {
.timer_id = 11, // GPT11_PWM_EVT
.polarity = 1 // Active-high
};
static struct platform_device diamond_backlight_pwm_device = {
.name = "omap-pwm",
.id = DIAMOND_BACKLIGHT_PWM_ID,
.dev = {
.platform_data = &diamond_backlight_pwm_config,
},
};
static struct platform_device diamond_piezo_pwm_device = {
.name = "omap-pwm",
.id = DIAMOND_PIEZO_PWM_ID,
.dev = {
.platform_data = &diamond_piezo_pwm_config,
},
};
#endif /* defined(CONFIG_HAVE_PWM) */
static struct twl4030_ins __initdata sleep_on_seq[] = {
/* Turn OFF VAUX2 */
{MSG_SINGULAR(DEV_GRP_P1, RES_VAUX2, RES_STATE_OFF), 2},
/* Turn off HFCLKOUT */
{MSG_SINGULAR(DEV_GRP_P1, RES_HFCLKOUT, RES_STATE_OFF), 2},
/* Turn OFF VDD1 */
{MSG_SINGULAR(DEV_GRP_P1, RES_VDD1, RES_STATE_OFF), 2},
/* Turn OFF VDD2 */
{MSG_SINGULAR(DEV_GRP_P1, RES_VDD2, RES_STATE_OFF), 2},
/* Turn OFF VPLL1 */
{MSG_SINGULAR(DEV_GRP_P1, RES_VPLL1, RES_STATE_OFF), 2},
};
static struct twl4030_script __initdata sleep_on_script = {
.script = sleep_on_seq,
.size = ARRAY_SIZE(sleep_on_seq),
.flags = TWL4030_SLEEP_SCRIPT,
};
/*
* This script instructs twl4030 to first enable CLKEN, then wakeup the
* regulators and then all other resources.
*/
static struct twl4030_ins __initdata wakeup_seq[] = {
/* Turn on VAUX2 */
{MSG_SINGULAR(DEV_GRP_P1, RES_VAUX2, RES_STATE_ACTIVE), 2},
/* Turn on HFCLKOUT */
{MSG_SINGULAR(DEV_GRP_P1, RES_HFCLKOUT, RES_STATE_ACTIVE), 2},
/* Turn ON VDD1 */
{MSG_SINGULAR(DEV_GRP_P1, RES_VDD1, RES_STATE_ACTIVE), 2},
/* Turn ON VDD2 */
{MSG_SINGULAR(DEV_GRP_P1, RES_VDD2, RES_STATE_ACTIVE), 2},
/* Turn ON VPLL1 */
{MSG_SINGULAR(DEV_GRP_P1, RES_VPLL1, RES_STATE_ACTIVE), 2},
};
static struct twl4030_script __initdata wakeup_script = {
.script = wakeup_seq,
.size = ARRAY_SIZE(wakeup_seq),
.flags = TWL4030_WAKEUP12_SCRIPT | TWL4030_WAKEUP3_SCRIPT,
};
static struct twl4030_ins __initdata wrst_seq[] = {
{MSG_SINGULAR(DEV_GRP_ALL, RES_RESET, RES_STATE_OFF), 0x2},
{MSG_SINGULAR(DEV_GRP_ALL, RES_Main_Ref, RES_STATE_WRST), 0x2},
{MSG_BROADCAST(DEV_GRP_ALL, RES_GRP_ALL, 0, 0x2, RES_STATE_WRST), 0x2},
{MSG_SINGULAR(DEV_GRP_ALL, RES_VUSB_3V1, RES_STATE_WRST), 0x2},
{MSG_SINGULAR(DEV_GRP_P1, RES_VAUX2, RES_STATE_WRST), 0x2},
{MSG_SINGULAR(DEV_GRP_P1, RES_VPLL1, RES_STATE_WRST), 0x2},
{MSG_SINGULAR(DEV_GRP_P1, RES_VDD2, RES_STATE_WRST), 0x7},
{MSG_SINGULAR(DEV_GRP_P1, RES_VDD1, RES_STATE_WRST), 0x25},
{MSG_BROADCAST(DEV_GRP_NULL, RES_GRP_RC, 7, 0, RES_STATE_WRST), 0x2},
{MSG_SINGULAR(DEV_GRP_ALL, RES_RESET, RES_STATE_ACTIVE), 0x2},
};
static struct twl4030_script __initdata wrst_script = {
.script = wrst_seq,
.size = ARRAY_SIZE(wrst_seq),
.flags = TWL4030_WRST_SCRIPT,
};
static struct twl4030_script __initdata *twl4030_scripts[] = {
&wakeup_script,
&sleep_on_script,
&wrst_script
};
/*
* Setting the devgroup enables the regulator. VAUX2 is the only one
* that we're not using the default voltage, so we set its inital group
* to NULL. This way it won't turn on until after we set its voltage
* at registration.
*/
static struct twl4030_resconfig __initdata diamond_twl4030_rconfig[] = {
{ .resource = RES_VPLL1, .devgroup = DEV_GRP_P1, .type = 3,
.type2 = 1, .remap_sleep = RES_STATE_OFF },
{ .resource = RES_VINTANA1, .devgroup = DEV_GRP_ALL, .type = 1,
.type2 = 2, .remap_sleep = RES_STATE_SLEEP },
{ .resource = RES_VINTANA2, .devgroup = DEV_GRP_ALL, .type = 0,
.type2 = 2, .remap_sleep = RES_STATE_SLEEP },
{ .resource = RES_VINTDIG, .devgroup = DEV_GRP_ALL, .type = 1,
.type2 = 2, .remap_sleep = RES_STATE_SLEEP },
{ .resource = RES_VIO, .devgroup = DEV_GRP_ALL, .type = 2,
.type2 = 2, .remap_sleep = RES_STATE_SLEEP },
{ .resource = RES_VAUX2, .devgroup = DEV_GRP_NULL,
.type = 3, .type2 = 1, .remap_sleep = RES_STATE_OFF },
{ .resource = RES_VDD1, .devgroup = DEV_GRP_P1,
.type = 4, .type2 = 1, .remap_sleep = RES_STATE_OFF },
{ .resource = RES_VDD2, .devgroup = DEV_GRP_P1,
.type = 3, .type2 = 1, .remap_sleep = RES_STATE_OFF },
{ .resource = RES_REGEN, .devgroup = DEV_GRP_ALL, .type = 2,
.type2 = 1, .remap_sleep = RES_STATE_SLEEP },
{ .resource = RES_NRES_PWRON, .devgroup = DEV_GRP_ALL, .type = 0,
.type2 = 1, .remap_sleep = RES_STATE_SLEEP },
{ .resource = RES_CLKEN, .devgroup = DEV_GRP_ALL, .type = 3,
.type2 = 2, .remap_sleep = RES_STATE_SLEEP },
{ .resource = RES_SYSEN, .devgroup = DEV_GRP_ALL, .type = 6,
.type2 = 1, .remap_sleep = RES_STATE_SLEEP },
{ .resource = RES_HFCLKOUT, .devgroup = DEV_GRP_P3,
.type = 0, .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
{ 0, 0},
};
/*
* This is identical to that of diamond except for turning off VMMC1
*/
static struct twl4030_resconfig __initdata j49_twl4030_rconfig[] = {
{ .resource = RES_VPLL1, .devgroup = DEV_GRP_P1, .type = 3,
.type2 = 1, .remap_sleep = RES_STATE_OFF },
{ .resource = RES_VINTANA1, .devgroup = DEV_GRP_ALL, .type = 1,
.type2 = 2, .remap_sleep = RES_STATE_SLEEP },
{ .resource = RES_VINTANA2, .devgroup = DEV_GRP_ALL, .type = 0,
.type2 = 2, .remap_sleep = RES_STATE_SLEEP },
{ .resource = RES_VINTDIG, .devgroup = DEV_GRP_ALL, .type = 1,
.type2 = 2, .remap_sleep = RES_STATE_SLEEP },
{ .resource = RES_VIO, .devgroup = DEV_GRP_ALL, .type = 2,
.type2 = 2, .remap_sleep = RES_STATE_SLEEP },
{ .resource = RES_VAUX2, .devgroup = DEV_GRP_NULL,
.type = 3, .type2 = 1, .remap_sleep = RES_STATE_OFF },
{ .resource = RES_VDD1, .devgroup = DEV_GRP_P1,
.type = 4, .type2 = 1, .remap_sleep = RES_STATE_OFF },
{ .resource = RES_VDD2, .devgroup = DEV_GRP_P1,
.type = 3, .type2 = 1, .remap_sleep = RES_STATE_OFF },
{ .resource = RES_REGEN, .devgroup = DEV_GRP_ALL, .type = 2,
.type2 = 1, .remap_sleep = RES_STATE_SLEEP },
{ .resource = RES_NRES_PWRON, .devgroup = DEV_GRP_ALL, .type = 0,
.type2 = 1, .remap_sleep = RES_STATE_SLEEP },
{ .resource = RES_CLKEN, .devgroup = DEV_GRP_ALL, .type = 3,
.type2 = 2, .remap_sleep = RES_STATE_SLEEP },
{ .resource = RES_SYSEN, .devgroup = DEV_GRP_ALL, .type = 6,
.type2 = 1, .remap_sleep = RES_STATE_SLEEP },
{ .resource = RES_HFCLKOUT, .devgroup = DEV_GRP_P3,
.type = 0, .type2 = 2, .remap_sleep = RES_STATE_SLEEP },
{ .resource = RES_VMMC1, .devgroup = DEV_GRP_NULL,
.type = 2, .type2 = 1, .remap_sleep = RES_STATE_OFF },
{ 0, 0},
};
static struct twl4030_power_data __initdata diamond_tps65921_scripts_data = {
.scripts = twl4030_scripts,
.num = ARRAY_SIZE(twl4030_scripts),
.resource_config = diamond_twl4030_rconfig,
};
static struct twl4030_power_data __initdata j49_tps65921_scripts_data = {
.scripts = twl4030_scripts,
.num = ARRAY_SIZE(twl4030_scripts),
.resource_config = j49_twl4030_rconfig,
};
/*
* XXX - Diamond does not actually have or use any OneNAND. However,
* the way OMAP board support is written in this kernel, removing any
* data and code associated with OneNAND from our board results in a
* kernel panic. So, we leave this as-is for now until we can debug
* the root cause.
*/
static struct mtd_partition diamond_onenand_partitions[] = {
{
.name = "xloader-onenand",
.offset = 0,
.size = 4*(64*2048),
.mask_flags = MTD_WRITEABLE
},
{
.name = "uboot-onenand",
.offset = MTDPART_OFS_APPEND,
.size = 15*(64*2048),
.mask_flags = MTD_WRITEABLE
},
{
.name = "params-onenand",
.offset = MTDPART_OFS_APPEND,
.size = 1*(64*2048),
},
{
.name = "linux-onenand",
.offset = MTDPART_OFS_APPEND,
.size = 40*(64*2048),
},
{
.name = "jffs2-onenand",
.offset = MTDPART_OFS_APPEND,
.size = MTDPART_SIZ_FULL,
},
};
static struct omap_onenand_platform_data diamond_onenand_data = {
.parts = diamond_onenand_partitions,
.nr_parts = ARRAY_SIZE(diamond_onenand_partitions),
.dma_channel = -1, /* disable DMA in OMAP OneNAND driver */
};
/*
* Diamond NAND flash parition sizes.
*
* For "raw" partitions, any size evenly divisible by the NAND erase
* block size (generally 128 KiB) is acceptable.
*
* For JFFS2 file system partitions, there's quite a bit of metadata
* overhead with JFFS2, so any size smaller than 4 MiB is practically
* useless as overhead at that size is just about less than 50%.
*/
#define DIAMOND_IPL_RAW_NAND_SIZE ( 256 << 10) // 256 KiB
#define DIAMOND_SPL_RAW_NAND_SIZE (1536 << 10) // 1.5 MiB (x2)
#define DIAMOND_ENV_RAW_NAND_SIZE ( 384 << 10) // 384 KiB (x2)
#define DIAMOND_BOOT_RAW_NAND_SIZE ( 8 << 20) // 8 MiB (x2)
#define DIAMOND_ROOT_FS_NAND_SIZE ( 46 << 20) // 46 MiB (x2)
#define DIAMOND_SYSTEM_CONFIG_FS_NAND_SIZE ( 4 << 20) // 4 MiB
#define DIAMOND_USER_CONFIG_FS_NAND_SIZE ( 8 << 20) // 8 MiB
#define DIAMOND_DATA_FS_NAND_SIZE ( 20 << 20) // 20 MiB
#define DIAMOND_LOG_FS_NAND_SIZE ( 20 << 20) // 20 MiB
#define DIAMOND_SCRATCH_FS_NAND_SIZE ( 92 << 20) // 92 MiB
static struct mtd_partition diamond_nand_partitions[] = {
// First, one partition for the entire device.
{
.name = "nand0",
.offset = 0,
.size = MTDPART_SIZ_FULL
},
// Then, partitions by functional use overlaid on the whole device.
//
// Initial- and secondary-program loader-related partitions. These
// are generally expected to stay constant with increasing NAND
// density.
{
.name = "ipl",
.offset = 0,
.size = DIAMOND_IPL_RAW_NAND_SIZE,
},
{
.name = "spl0",
.offset = MTDPART_OFS_APPEND,
.size = DIAMOND_SPL_RAW_NAND_SIZE
},
{
.name = "spl1",
.offset = MTDPART_OFS_APPEND,
.size = DIAMOND_SPL_RAW_NAND_SIZE
},
{
.name = "env0",
.offset = MTDPART_OFS_APPEND,
.size = DIAMOND_ENV_RAW_NAND_SIZE
},
{
.name = "env1",
.offset = MTDPART_OFS_APPEND,
.size = DIAMOND_ENV_RAW_NAND_SIZE
},
// Kernel- and file system-related partitions. These are generally
// expected to grow with increasing NAND density.
{
.name = "boot0",
.offset = MTDPART_OFS_APPEND,
.size = DIAMOND_BOOT_RAW_NAND_SIZE
},
{
.name = "root0",
.offset = MTDPART_OFS_APPEND,
.size = DIAMOND_ROOT_FS_NAND_SIZE
},
{
.name = "boot1",
.offset = MTDPART_OFS_APPEND,
.size = DIAMOND_BOOT_RAW_NAND_SIZE
},
{
.name = "root1",
.offset = MTDPART_OFS_APPEND,
.size = DIAMOND_ROOT_FS_NAND_SIZE
},
{
.name = "system-config",
.offset = MTDPART_OFS_APPEND,
.size = DIAMOND_SYSTEM_CONFIG_FS_NAND_SIZE
},
{
.name = "user-config",
.offset = MTDPART_OFS_APPEND,
.size = DIAMOND_USER_CONFIG_FS_NAND_SIZE
},
{
.name = "data",
.offset = MTDPART_OFS_APPEND,
.size = DIAMOND_DATA_FS_NAND_SIZE
},
{
.name = "log",
.offset = MTDPART_OFS_APPEND,
.size = DIAMOND_LOG_FS_NAND_SIZE
},
{
.name = "scratch",
.offset = MTDPART_OFS_APPEND,
.size = DIAMOND_SCRATCH_FS_NAND_SIZE
}
};
static struct omap_nand_platform_data diamond_nand_data = {
.parts = diamond_nand_partitions,
.nr_parts = ARRAY_SIZE(diamond_nand_partitions),
.nand_setup = NULL,
.dma_channel = -1, /* disable DMA in OMAP NAND driver */
.dev_ready = NULL,
};
/*
* The TI OMAP frame buffer (OMAPFB) driver has a number of different
* ways of allocating frame buffer memory to its various frame buffer
* devices. Unfortunately, they are not fully unified with the generic
* Linux frame buffer driver.
*
* Regardless, one such method is specifiying the parameters on the
* kernel command line. For example, the following would instruct the
* generic linux frame buffer driver to allocate 4 MiB of memory and
* to then allocate all of it to the OMAP frame buffer zero (0),
* typically the LCD:
*
* vram=4M omapfb.vram=0:4M
*
* Another method is to programmatically use platform data. Because we
* do not need any dynamism in this area and because we elect to
* minimize futzing with kernel command line parameters, we take the
* platform data approach.
*
* Because the frame buffer is a virtual entity, all the parameters
* specified here are in terms of virtual sizes and depths and may not
* actually reflect the capabilities of the LCD itself.
*
* The parameters below basically define a double-buffered 320 x 320
* (or 480) frame at 4 bytes per pixel.
*/
#define DIAMOND_VFB_BPP 4
#define DIAMOND_VFB_COUNT 2
#define DIAMOND_VFB_ROUND (512 << 10)
static struct omapfb_platform_data diamond_320_320_omapfb_config = {
.mem_desc = {
.region_cnt = 1,
.region[0] = {
.paddr = 0,
.size = diamond_roundup(320 * 320 *
DIAMOND_VFB_BPP *
DIAMOND_VFB_COUNT,
DIAMOND_VFB_ROUND),
}
},
.lcd ={
.rotation = 0
}
};
static struct omapfb_platform_data diamond_320_480_omapfb_config = {
.mem_desc = {
.region_cnt = 1,
.region[0] = {
.paddr = 0,
.size = diamond_roundup(320 * 480 *
DIAMOND_VFB_BPP *
DIAMOND_VFB_COUNT,
DIAMOND_VFB_ROUND)
}
}
};
#if defined(CONFIG_PANEL_SAMSUNG_LMS350DF03)
static struct lms350df03_platform_data lms350df03_development_lcd_config = {
.reset = {
.gpio = DIAMOND_GPIO_LCD_RESETB,
.inverted = false
},
.regulator = {
.vcc = NULL,
},
};
static struct lms350df03_platform_data lms350df03_prototype_lcd_config = {
.reset = {
.gpio = DIAMOND_GPIO_LCD_RESETB,
.inverted = false
},
.regulator = {
.vcc = "lcd2v8",
},
};
#define LMS350DF03_LCD_MODALIAS "lms350df03"
#define LMS350DF03_LCD_SPI_MAX_SPEED 10000000
#endif /* defined(CONFIG_PANEL_SAMSUNG_LMS350DF03) */
#if defined(CONFIG_PANEL_GIANTPLUS_GPM1145A0)
static struct ili9481_platform_data ili9481_lcd_config = {
.reset = {
.gpio = DIAMOND_GPIO_LCD_RESETB,
.inverted = false
}
};
#define ILI9481_LCD_MODALIAS "ili9481"
#define ILI9481_LCD_SPI_MAX_SPEED 8000000
#endif /* defined(CONFIG_PANEL_GIANTPLUS_GPM1145A0) */
#if defined(CONFIG_PANEL_TIANMA_TM025ZDZ01)
static struct s6d05a1_platform_data s6d05a1_lcd_config = {
.reset = {
.gpio = DIAMOND_GPIO_LCD_RESETB,
.inverted = false
},
.lcd_id = {
.gpio = DIAMOND_GPIO_LCD_ID,
},
.regulator = {
.vcc = "lcd2v8",
},
// The Tianma display is mounted and oriented such that its
// natural position is upside down. So, set x- and y-mirroring to
// effect a 180 degree rotation.
.orientation = {
.x_mirror = true,
.y_mirror = true,
.x_y_exchange = false
}
};
#define TM025ZDZ01_LCD_MODALIAS "s6d05a1"
#define TM025ZDZ01_LCD_SPI_MAX_SPEED 10000000
#endif /* defined(CONFIG_PANEL_TIANMA_TM025ZDZ01) */
#define SPI_DEV_MODALIAS "spidev"
#define SPI_DEV_MAX_SPEED 1000000
static struct omap2_mcspi_device_config lcd_mcspi_config = {
.turbo_mode = false,
.single_channel = 0
};
static struct spi_board_info diamond_development_spi_board_info[] = {
[DIAMOND_SPI_LCD] = {
#if defined(CONFIG_PANEL_SAMSUNG_LMS350DF03)
.modalias = LMS350DF03_LCD_MODALIAS,
.bus_num = 2,
.chip_select = 0,
.max_speed_hz = LMS350DF03_LCD_SPI_MAX_SPEED,
.controller_data = &lcd_mcspi_config,
.platform_data = &lms350df03_development_lcd_config
#endif
}
};
static struct spi_board_info diamond_1_4_spi_board_info[] = {
[DIAMOND_SPI_LCD] = {
#if defined(CONFIG_PANEL_SAMSUNG_LMS350DF03)
.modalias = LMS350DF03_LCD_MODALIAS,
.bus_num = 2,
.chip_select = 0,
.max_speed_hz = LMS350DF03_LCD_SPI_MAX_SPEED,
.controller_data = &lcd_mcspi_config,
.platform_data = &lms350df03_prototype_lcd_config
#endif
}
};
/*
* Starting with EVT revisions, displays transition for form-factor
* Tianma TM025ZDZ01 displays.
*/
static struct spi_board_info diamond_1_5_spi_board_info[] = {
[DIAMOND_SPI_LCD] = {
.modalias = TM025ZDZ01_LCD_MODALIAS,
.bus_num = 2,
.chip_select = 0,
.max_speed_hz = TM025ZDZ01_LCD_SPI_MAX_SPEED,
.controller_data = &lcd_mcspi_config,
.platform_data = &s6d05a1_lcd_config
}
};
/*
* Starting with DVT revisions, displays move to McSPI1 from McSPI2
* to accomodate bi-directional SPI communication.
*/
static struct spi_board_info diamond_1_7_spi_board_info[] = {
[DIAMOND_SPI_LCD] = {
.modalias = TM025ZDZ01_LCD_MODALIAS,
.bus_num = 1,
.chip_select = 0,
.max_speed_hz = TM025ZDZ01_LCD_SPI_MAX_SPEED,
.controller_data = &lcd_mcspi_config,
.platform_data = &s6d05a1_lcd_config
}
};
/*
* Starting with DVT revisions, displays move to McSPI1 from McSPI2
* to accomodate bi-directional SPI communication.
*/
static struct spi_board_info display_2_0_spi_board_info[] = {
[DIAMOND_SPI_LCD] = {
.modalias = TM025ZDZ01_LCD_MODALIAS,
.bus_num = 1,
.chip_select = 0,
.max_speed_hz = TM025ZDZ01_LCD_SPI_MAX_SPEED,
.controller_data = &lcd_mcspi_config,
.platform_data = &s6d05a1_lcd_config
},
[J49_SPI_DEV] = {
.modalias = SPI_DEV_MODALIAS,
.bus_num = 2,
.chip_select = 0,
.max_speed_hz = SPI_DEV_MAX_SPEED,
}
};
static struct omap_dss_device diamond_development_lcd_device = {
.name = "Samsung LMS350DF03",
.driver_name = "samsung_lms350df03",
.phy.dpi.data_lines = 24,
.type = OMAP_DISPLAY_TYPE_DPI,
.platform_enable = diamond_development_enable_lcd,
.platform_disable = diamond_development_disable_lcd,
};
static struct omap_dss_device diamond_1_4_lcd_device = {
.name = "Samsung LMS350DF03",
.driver_name = "samsung_lms350df03",
.phy.dpi.data_lines = 24,
.type = OMAP_DISPLAY_TYPE_DPI,
.platform_enable = NULL,
.platform_disable = NULL,
};
static struct omap_dss_device diamond_1_5_lcd_device = {
.name = "Tianma TM025ZDZ01",
.driver_name = "tianma_tm025zdz01",
.phy.dpi.data_lines = 24,
.type = OMAP_DISPLAY_TYPE_DPI,
.platform_enable = NULL,
.platform_disable = NULL,
};
/*
tast = 0
taht = 10
tcs = 20
trcs = 170
tcsf= 20
twc = 50
twrh = 20
twrl = 20
trc = 450
trdh = 250
trdl = 170
twds = 15
twdh = 15
tracc = 150
trod = 10
*/
static struct omap_dss_device display_2_11_lcd_device = {
.name = "Renesas R61529a1",
.driver_name = "renesas_r61529a1",
.phy.rfbi.data_lines = 16,
.phy.rfbi.channel = OMAP_DSS_CHANNEL_LCD,
.ctrl.pixel_size = 24,
.ctrl.rfbi_timings = {
.cs_on_time = 0,
.cs_off_time = (250+170)*1000,
.we_on_time = 20*1000,
.we_off_time = (40)*1000,
.re_on_time = 250*1000,
.re_off_time = (250+170)*1000,
.we_cycle_time = (52)*1000,
.re_cycle_time = (250+170)*1000,
.cs_pulse_width = (250+170+50)*1000,
.access_time = (250+170)*1000,
},
.type = OMAP_DISPLAY_TYPE_DBI,
.panel.timings = {
.x_res = 320,
.y_res = 320,
.pixel_clock = 7180,
.hsw = 2,
.hfp = 8,
.hbp = 8,
.vsw = 2,
.vfp = 8,
.vbp = 8,
},
.platform_enable = NULL,
.platform_disable = NULL,
};
static struct r61529a1_platform_data r61529a1_config = {
.reset = {
.gpio = DIAMOND_GPIO_LCD_RESETB,
.inverted = false
},
.regulator = {
.vcc = "lcd2v8",
},
};
/*
* Both the devices array and the device data will get fixed up in the
* model-specific display initialization function.
*/
static struct omap_dss_device *diamond_dss_devices[] = {
NULL,
};
static struct omap_dss_board_info diamond_dss_data = {
.num_devices = ARRAY_SIZE(diamond_dss_devices),
.devices = diamond_dss_devices,
.default_device = NULL,
};
static struct platform_device diamond_dss_device = {
.name = "omapdss",
.id = -1,
.dev = {
.platform_data = &diamond_dss_data
},
};
#if defined(CONFIG_WILINK) || defined(CONFIG_WILINK_MODULE)
static struct platform_device diamond_wl1271_device = {
.name = "tiwlan_pm_driver",
.id = -1,
.dev = {
.platform_data = NULL,
},
};
static struct platform_device diamond_wl127x_device = {
.id = 1,
.dev = {
.bus = &platform_bus_type,
},
};
#endif /* defined(CONFIG_WILINK) || defined(CONFIG_WILINK_MODULE) */
#if defined(CONFIG_WL12XX) || defined(CONFIG_WL12XX_MODULE)
static struct wl12xx_platform_data diamond_wl12xx_data __initdata = {
.irq = -1,
.use_eeprom = false,
.pwr_in_suspend = true,
};
#endif /* defined(CONFIG_WL12XX) || defined(CONFIG_WL12XX_MODULE) */
/*
* Generic PWM backlight platform data and device data
*
* The TPS61042 constant current LED drivers which ultimately drives
* the backlight can handle, per its datasheet "TPS61042: Constant
* Current LED Driver", a PWM input in the frequency range 100 Hz to
* 50 KHz (period 10 ms to 20 us).
*
* Per "Control (CTRL)", Page 10 of the datasheet, to enable the
* device, the TPS61042 CTRL signal must be high for 50 us (50000
* ns). The PWM signal can then be applied with a pulse width (tp)
* greater or smaller than tON. To force the device into shutdown
* mode, the CTRL signal must be low for at least 32 ms (32000000 ns).
*
* However, also per "Control (CTRL)", Page 10 of the datasheet, to
* enable the device when the pulse width <= 2.5 us, run with a pulse
* > 2.5 us for 512 PWM cycles. Experimentally, this method does not
* work and, in fact, requires a pulse of 8.1 us, which causes a
* bright flash with white pixels.
*/
#define TPS61042_DISABLE_NS_MIN 32000000
#define TPS61042_ENABLE_NS_MIN 100000
#define TPS61042_PULSE_NS_MIN 400
#define PWM_BL_PERIOD_NS_100_HZ 10000000
#define PWM_BL_PERIOD_NS_50_KHZ 20000
#define TPS61042_PWM_PERIOD_NS_MIN PWM_BL_PERIOD_NS_50_KHZ
#define TPS61042_PWM_PERIOD_NS_MAX PWM_BL_PERIOD_NS_100_HZ
/* Starting at pulse width smaller than this value requires a soft
* start. Datasheet says 2500ns, feedback from TI is to double that
*/
#define TPS61042_START_PULSE_NS_MIN 5000
/* Measured minimum soft start time is 210ms, feedback from TI is
* to add 50%. This value should be independent of soft start
* frequency, but based on my testing that is false.
*/
#define TPS61042_START_MS_MIN 315
/* Soft start algorithm from TI is to use 100Hz, 0.5% duty cycle. If
* increase from 100Hz, must also increase the duty cycle.
*/
#define TPS61042_START_PWM_PERIOD_NS PWM_BL_PERIOD_NS_100_HZ
#define TPS61042_START_PULSE_NS ((TPS61042_START_PWM_PERIOD_NS/1000)*5)
/* The following backight PWM periods are a sampling of periods that
* have been experimentally tried. Those in or just in the super-audio
* frequency range (>= 20 KHz) avoid audible "whine" but also meet the
* TPS61042 pulse width minimum at the number of brightness steps
* chosen (100).
*/
#define PWM_BL_PERIOD_NS_1_0_KHZ 1000000
#define PWM_BL_PERIOD_NS_2_0_KHZ 500000
#define PWM_BL_PERIOD_NS_3_2_KHZ 312500
#define PWM_BL_PERIOD_NS_4_0_KHZ 250000
#define PWM_BL_PERIOD_NS_7_4_KHZ 135000
#define PWM_BL_PERIOD_NS_7_7_KHZ 130000
#define PWM_BL_PERIOD_NS_8_3_KHZ 120000
#define PWM_BL_PERIOD_NS_10_0_KHZ 100000
#define PWM_BL_PERIOD_NS_20_0_KHZ 50000
#define PWM_BL_PERIOD_NS_20_5_KHZ 48780
#define PWM_BL_PERIOD_NS_21_0_KHZ 47619
#define PWM_BL_PERIOD_NS_22_0_KHZ 45455
#define PWM_BL_PERIOD_NS_22_2_KHZ 45000
#define PWM_BL_PERIOD_NS_24_0_KHZ 41667
#define PWM_BL_PERIOD_NS_25_0_KHZ 40000
static struct platform_pwm_backlight_data diamond_tps61042_backlight_data = {
// Generic PWM timer ID to request
.pwm_id = DIAMOND_BACKLIGHT_PWM_ID,
// The maximum and default brightness values, without units. These
// effectively provide the number of possible backlight brightness
// steps.
.max_brightness = 100,
.dft_brightness = 50,
// The PWM period, in nanoseconds.
.pwm_period_ns = PWM_BL_PERIOD_NS_2_0_KHZ,
// The TPS61042 LED driver-specific parameters. Based on our
// frequency and steps, we have a pulse of 450 ns at 1% which
// means we have to specify not only the enable minimum but also
// an initial start pulse train.
.driver = {
.enable_ns = TPS61042_ENABLE_NS_MIN,
.pulse_min_ns = TPS61042_PULSE_NS_MIN,
.start_pulse_min_ns = TPS61042_START_PULSE_NS_MIN,
.start_pulse_ns = TPS61042_START_PULSE_NS,
.start_ms = TPS61042_START_MS_MIN,
.start_period_ns = TPS61042_START_PWM_PERIOD_NS
},
// At this point, we don't have an eye response ramp.
.ramp = NULL,
// Board-specific callback when the backlight changes.
.notify = diamond_backlight_notify,
};
static struct platform_device diamond_tps61042_backlight_device = {
.name = "pwm-backlight",
.dev = {
.platform_data = &diamond_tps61042_backlight_data,
},
};
static struct lm3530_platform_data j49_lm3530_backlight_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 = LM3530_RAMP_LAW_EXP,
.brt_ramp_fall = LM3530_RAMP_TIME_2s,
.brt_ramp_rise = LM3530_RAMP_TIME_2s,
.als1_resistor_sel = LM3530_ALS_IMPD_13_53kOhm,
.als2_resistor_sel = LM3530_ALS_IMPD_Z,
.als_vmin = 730, /* mV */
.als_vmax = 1020, /* mV */
.max_brightness = 0x78,
.dft_brightness = 0x6c,
.enable_gpio = J49_GPIO_LCD_BL_HWEN,
.wait_for_framebuffer = "omapfb"
};
static struct platform_device j49_lm3530_backlight_device = {
.name = "lm3530-backlight",
.dev = {
},
};
static struct i2c_board_info __initdata j49_backlight_i2c_info[] = {
{
I2C_BOARD_INFO("lm3530-backlight", 0x36),
.platform_data = &j49_lm3530_backlight_data,
},
};
#if defined(CONFIG_INPUT_GPIO_ROTARY_ENCODER_LITE)
static struct rotary_encoder_lite_platform_data rotary_enc = {
.gpio_a = DIAMOND_GPIO_ROTARY_VALID,
.gpio_b = DIAMOND_GPIO_ROTARY_DIR,
.gpio_clear = DIAMOND_GPIO_ROTARY_CLEAR,
.steps = 360,
.rollover = 1
};
static struct platform_device diamond_rotary_device = {
.name = "rotary-encoder-lite",
.dev = {
.platform_data = &rotary_enc,
},
};
#endif /* defined(CONFIG_INPUT_GPIO_ROTARY_ENCODER_LITE) */
static int diamond_prototype_piezo_init(struct device *dev)
{
const unsigned int enabled = 0;
diamond_gpio_try_output(DIAMOND_GPIO_PIEZO_NENABLE,
!enabled,
goto fail);
return 0;
fail:
return -EBUSY;
}
static void diamond_prototype_piezo_exit(struct device *dev)
{
gpio_free(DIAMOND_GPIO_PIEZO_NENABLE);
}
static void diamond_prototype_piezo_notify(struct device *dev, int hz)
{
const unsigned int enabled = 0;
gpio_set_value(DIAMOND_GPIO_PIEZO_NENABLE, hz ? enabled : !enabled);
}
static struct platform_pwm_beeper_data diamond_pwm_beeper_data = {
.pwm_id = DIAMOND_PIEZO_PWM_ID,
.init = NULL,
.exit = NULL,
.notify = NULL,
};
static struct platform_device diamond_piezo_device = {
.name = "pwm-beeper",
.id = -1,
.dev = {
.platform_data = &diamond_pwm_beeper_data,
},
};
static struct platform_device diamond_backplate_device = {
.name = "diamond-backplate",
.id = -1,
};
static struct platform_device diamond_battery_device = {
.name = "diamond-battery",
.id = -1,
};
static struct diamond_zigbee_platform_data diamond_zigbee_data = {
.reset_gpio = DIAMOND_GPIO_ZIGBEE_RESET_L,
.pwr_enable_gpio = DIAMOND_GPIO_ZIGBEE_PWR_ENABLE,
.interrupt_gpio = 0
};
static struct platform_device diamond_zigbee_device = {
.name = "diamond-zigbee",
.id = -1,
.dev = {
.platform_data = &diamond_zigbee_data,
},
};
static struct diamond_zigbee_platform_data j49_zigbee_data = {
.reset_gpio = DIAMOND_GPIO_ZIGBEE_RESET_L,
.pwr_enable_gpio = 0,
.interrupt_gpio = J49_GPIO_ZIGBEE_INTERRUPT_L,
};
static struct platform_device j49_zigbee_device = {
.name = "diamond-zigbee",
.id = -1,
.dev = {
.platform_data = &j49_zigbee_data,
},
};
#if defined(CONFIG_SENSORS_TWL4030_MADC)
static struct platform_device diamond_madc_hwmon_device = {
.name = "twl4030_madc_hwmon"
};
#endif
#define ONENAND_MAP 0x20000000 /* OneNand flash */
//Function taken from board_nand_init in board-flash.h
void __init diamond_nand_init(void)
{
diamond_nand_data.cs = 0;
diamond_nand_data.parts = diamond_nand_partitions;
diamond_nand_data.nr_parts = ARRAY_SIZE(diamond_nand_partitions);
diamond_nand_data.devsize = NAND_BUSWIDTH_16;
diamond_nand_data.gpmc_irq = OMAP_GPMC_IRQ_BASE;
diamond_nand_data.ecc_opt = OMAP_ECC_BCH4_CODE_HW;
if (gpmc_nand_init(&diamond_nand_data) < 0)
printk(KERN_ERR "Unable to register NAND device\n");
}
static void __init diamond_onenand_init(void)
{
gpmc_onenand_init(&diamond_onenand_data);
}
static void __init diamond_flash_init(void)
{
diamond_nand_init();
diamond_onenand_init();
}
#if (defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE))
static struct resource diamond_smsc911x_resources[] = {
[0] = {
.start = DIAMOND_ETHR_START,
.end = (DIAMOND_ETHR_START + DIAMOND_ETHR_SIZE - 1),
.flags = IORESOURCE_MEM,
},
[1] = {
.start = OMAP_GPIO_IRQ(DIAMOND_GPIO_ENET_IRQ),
.end = OMAP_GPIO_IRQ(DIAMOND_GPIO_ENET_IRQ),
.flags = (IORESOURCE_IRQ | IRQF_TRIGGER_LOW),
},
};
static struct smsc911x_platform_config smsc911x_config = {
.phy_interface = PHY_INTERFACE_MODE_MII,
.irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW,
.irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN,
.flags = (SMSC911X_USE_32BIT | SMSC911X_SAVE_MAC_ADDRESS),
};
static struct platform_device diamond_smsc911x_device = {
.name = "smsc911x",
.id = -1,
.num_resources = ARRAY_SIZE(diamond_smsc911x_resources),
.resource = &diamond_smsc911x_resources[0],
.dev = {
.platform_data = &smsc911x_config,
},
};
static inline void __init diamond_smsc911x_init(void)
{
diamond_gpio_try_input(DIAMOND_GPIO_ENET_IRQ, goto done);
platform_device_register(&diamond_smsc911x_device);
done:
return;
}
#endif /* (defined(CONFIG_SMSC911X) || defined(CONFIG_SMSC911X_MODULE)) */
static void __init diamond_wlan_init(void)
{
#if defined(CONFIG_WILINK) || defined(CONFIG_WILINK_MODULE)
/* Create proxy platform device and alias for MMC2 clock,
* required for WiLink driver.
*/
dev_set_name(&diamond_wl127x_device.dev, "mmci-omap-hs.%d", 1);
clk_add_alias("ick", "tiwlan_pm_driver", "ick", &diamond_wl127x_device.dev);
clk_add_alias("fck", "tiwlan_pm_driver", "fck", &diamond_wl127x_device.dev);
#endif
}
static void __init diamond_display_gpio_init(void)
{
// Attempt to request GPIO outputs for the platform-specific
// aspects of the LCD control interface, including the 3.3V LCM
// Vdd enable (active high) and 1.8V to 3.3V buffer enable (active
// low).
diamond_gpio_try_output(DIAMOND_GPIO_LCD_NENABLE_BUFFER,
1,
goto done);
diamond_gpio_try_output(DIAMOND_GPIO_LCD_ENABLE_VDD,
0,
goto err_1);
// If we are here, we successfully requested all LCM GPIOs.
goto done;
// One of the GPIO requests failed, bail out and release any
// requested GPIOs.
err_1:
gpio_free(DIAMOND_GPIO_LCD_NENABLE_BUFFER);
done:
return;
}
static int diamond_development_enable_lcd(struct omap_dss_device *dssdev)
{
int status = 0;
if (lcd_enabled) {
return (status);
}
// First, enable (active high) the 3.3V supply and wait a few
// milliseconds.
gpio_set_value(DIAMOND_GPIO_LCD_ENABLE_VDD, 1);
mdelay(30);
// Second, enable (active low) the 1.8V to 3.3V signal buffer and
// wait a few milliseconds.
gpio_set_value(DIAMOND_GPIO_LCD_NENABLE_BUFFER, 0);
mdelay(30);
lcd_enabled = true;
return (status);
}
static void diamond_development_disable_lcd(struct omap_dss_device *dssdev)
{
if (!lcd_enabled) {
goto done;
}
// Second, disable (active low) the 1.8V to 3.3V signal buffer.
gpio_set_value(DIAMOND_GPIO_LCD_NENABLE_BUFFER, 1);
// Finally, disable (active high) the 3.3V supply.
gpio_set_value(DIAMOND_GPIO_LCD_ENABLE_VDD, 0);
lcd_enabled = false;
done:
return;
}
static void diamond_1_6_power_off(void)
{
diamond_battery_disconnect(true);
}
static void diamond_1_6_halt_system(void)
{
// reset the backplate
diamond_backplate_reset();
// power off
twl4030_poweroff();
}
/**
* diamond_backlight_notify - backlight change notification callback
* @brightness: the brightness value the backlight PWM will be changed to.
*
* This routine is called whenever a backlight value change
* occurs. Nominally, this routine simply returns the changed
* backlight value, unmodified.
*
* However, in the future, this routine could be used to linearize the
* backlight response in a platform-specific way or to quantize the
* allowed backlight levels.
*
* Returns the backlight PWM value to change to.
*/
static int diamond_backlight_notify(struct device *dev, int brightness)
{
return brightness;
}
static struct regulator_consumer_supply diamond_development_vaux2_supplies[] = {
REGULATOR_SUPPLY("hsusb1", NULL),
};
/*
* This will get fixed up in the model-specific regulator initialization
* function.
*/
static struct regulator_consumer_supply diamond_prototype_vaux2_supplies[] = {
REGULATOR_SUPPLY("hsusb1", NULL),
REGULATOR_SUPPLY("lcd2v8", NULL),
};
static struct regulator_init_data diamond_vaux2 = {
.constraints = {
.min_uV = 2800000,
.max_uV = 2800000,
.apply_uV = true,
.boot_on = true,
.initial_mode = REGULATOR_MODE_NORMAL,
.valid_modes_mask = REGULATOR_MODE_NORMAL
| REGULATOR_MODE_STANDBY,
.valid_ops_mask = REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS,
},
.num_consumer_supplies = 0,
.consumer_supplies = NULL,
};
/*
* We only define one MMC channel even though two are supported and used.
* The TI WiLink driver currently in use has it's own SDIO driver which
* plays outside the normal Linux driver space. Consequently, we cannot
* normally define the second MMC channel and have the WiLink driver bind
* to it.
*/
static struct omap2_hsmmc_info diamond_development_tps65921_mmc[] = {
#if defined(CONFIG_MMC_BLOCK)
{
.mmc = 1,
.caps = MMC_CAP_4_BIT_DATA,
.gpio_cd = -EINVAL,
.gpio_wp = 63,
.cover_only = true,
.ocr_mask = 0,
},
#endif /* defined(CONFIG_MMC_BLOCK) */
#if !defined(CONFIG_WILINK) && !defined(CONFIG_WILINK_MODULE)
{
.name = "wl1271",
.mmc = 2,
.caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD
| MMC_PM_KEEP_POWER,
.gpio_cd = -EINVAL,
.gpio_wp = -EINVAL,
.cover_only = false,
.ext_clock = false,
.nonremovable = true,
.power_saving = false,
.transceiver = false,
.ocr_mask = 0,
},
#endif /* !defined(CONFIG_WILINK) && !defined(CONFIG_WILINK_MODULE) */
{} /* Terminator */
};
static struct omap2_hsmmc_info diamond_prototype_tps65921_mmc[] = {
#if !defined(CONFIG_WILINK) && !defined(CONFIG_WILINK_MODULE)
{
.name = "wl1271",
.mmc = 2,
.caps = MMC_CAP_4_BIT_DATA | MMC_CAP_POWER_OFF_CARD
| MMC_PM_KEEP_POWER,
.gpio_cd = -EINVAL,
.gpio_wp = -EINVAL,
.cover_only = false,
.ext_clock = false,
.nonremovable = true,
.power_saving = false,
.transceiver = false,
.ocr_mask = 0,
},
#endif /* !defined(CONFIG_WILINK) && !defined(CONFIG_WILINK_MODULE) */
{} /* Terminator */
};
static struct twl4030_gpio_platform_data diamond_tps65921_gpio_data = {
.gpio_base = OMAP_MAX_GPIO_LINES,
.irq_base = TWL4030_GPIO_IRQ_BASE,
.irq_end = TWL4030_GPIO_IRQ_END,
};
static struct twl4030_usb_data diamond_tps65921_usb_data = {
.usb_mode = T2_USB_MODE_ULPI,
};
#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
static struct ohci_hcd_omap_platform_data diamond_ohci_pdata __initdata = {
.port_mode[0] = OMAP_OHCI_PORT_MODE_UNUSED,
.port_mode[1] = OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM,
.port_mode[2] = OMAP_OHCI_PORT_MODE_UNUSED,
};
#endif // defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
#if defined(CONFIG_USB_DYNAMIC)
static const char *diamond_dynamic_usb_functions[] = {
#if defined(CONFIG_USB_DYNAMIC_MASS_STORAGE)
"usb_mass_storage",
#endif
#if defined(CONFIG_USB_DYNAMIC_ACM)
"acm",
#endif
};
static char diamond_serial_number[DIAMOND_USB_SERIAL_STRING_SIZE] = "";
static const struct dynamic_usb_product diamond_dynamic_usb_products[] = {
{
.product_id = DIAMOND_USB_PRODUCT_ID,
.num_functions = ARRAY_SIZE(diamond_dynamic_usb_functions),
.functions = diamond_dynamic_usb_functions,
},
};
static struct dynamic_usb_platform_data diamond_dynamic_usb_data = {
.vendor_id = DIAMOND_USB_VENDOR_ID,
.product_id = DIAMOND_USB_PRODUCT_ID,
.manufacturer_name = DIAMOND_USB_VENDOR_STRING,
.product_name = DIAMOND_USB_PRODUCT_STRING,
.serial_number = diamond_serial_number,
.num_products = ARRAY_SIZE(diamond_dynamic_usb_products),
.products = diamond_dynamic_usb_products,
.num_functions = ARRAY_SIZE(diamond_dynamic_usb_functions),
.functions = diamond_dynamic_usb_functions,
};
static struct platform_device diamond_dynamic_usb_device = {
.name = "dynamic_usb",
.id = -1,
.dev = {
.platform_data = &diamond_dynamic_usb_data,
},
};
static const struct dynamic_usb_product j49_dynamic_usb_products[] = {
{
.product_id = J49_USB_PRODUCT_ID,
.num_functions = ARRAY_SIZE(diamond_dynamic_usb_functions),
.functions = diamond_dynamic_usb_functions,
},
};
static struct dynamic_usb_platform_data j49_dynamic_usb_data = {
.vendor_id = J49_USB_VENDOR_ID,
.product_id = J49_USB_PRODUCT_ID,
.manufacturer_name = J49_USB_VENDOR_STRING,
.product_name = J49_USB_PRODUCT_STRING,
.serial_number = diamond_serial_number,
.num_products = ARRAY_SIZE(j49_dynamic_usb_products),
.products = j49_dynamic_usb_products,
.num_functions = ARRAY_SIZE(diamond_dynamic_usb_functions),
.functions = diamond_dynamic_usb_functions,
};
static struct platform_device j49_dynamic_usb_device = {
.name = "dynamic_usb",
.id = -1,
.dev = {
.platform_data = &j49_dynamic_usb_data,
},
};
#endif /* defined(CONFIG_USB_DYNAMIC) */
#if defined(CONFIG_USB_DYNAMIC_MASS_STORAGE)
static struct usb_msc_platform_data diamond_dynamic_usb_msc_data = {
.vendor = DIAMOND_MSC_VENDOR_STRING,
.product = DIAMOND_MSC_PRODUCT_STRING,
.release = DIAMOND_MSC_RELEASE,
.nluns = 1,
};
static struct platform_device diamond_dynamic_usb_msc_device = {
.name = "usb_mass_storage",
.id = -1,
.dev = {
.platform_data = &diamond_dynamic_usb_msc_data,
},
};
#endif /* defined(CONFIG_USB_DYNAMIC_MASS_STORAGE) */
#if defined(CONFIG_OMAP2_DSS)
/*
* Power supplies for digital video interfaces, including the OMAP
* Display Subsystem (DSS) and its Display Serial Interface (DSI)
* block.
*
* On the prototype instantiation of the Diamond board, the TPS65921
* VAUX rail at 2.8V is used to power the Tianma TM025ZDZ01 VCC input.
* This supply is defined elsewhere in this file.
*
* Without these, there will be no functioning LCD display. These
* supplies are largely internal between the TPS65921 and the AM3703;
* whereas, the LCD panel itself it supplied externally to both.
*/
/* VMMC1 */
struct regulator_consumer_supply twl4030_vmmc1_supply = {
.supply = "vmmc",
};
static struct regulator_consumer_supply diamond_vpll2_supplies[] = {
REGULATOR_SUPPLY("vdvi", NULL),
{
.supply = "vdds_dsi",
.dev = &diamond_dss_device.dev,
},
};
static struct regulator_init_data diamond_tps65921_vpll2 = {
.constraints = {
.name = "VDVI",
.min_uV = 1800000,
.max_uV = 1800000,
.apply_uV = true,
.valid_modes_mask = REGULATOR_MODE_NORMAL
| REGULATOR_MODE_STANDBY,
.valid_ops_mask = REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS,
},
.num_consumer_supplies = ARRAY_SIZE(diamond_vpll2_supplies),
.consumer_supplies = diamond_vpll2_supplies,
};
#endif /* defined(CONFIG_OMAP2_DSS) */
static struct regulator_consumer_supply diamond_development_vmmc1_supplies[] = {
#if defined(CONFIG_MMC_OMAP_HS)
REGULATOR_SUPPLY("vmmc", "mmci-omap-hs.0"),
#endif /* defined(CONFIG_MMC_OMAP_HS) */
};
static struct regulator_consumer_supply diamond_prototype_vmmc1_supplies[] = {
#if defined(CONFIG_MMC_OMAP_HS)
REGULATOR_SUPPLY("vmmc", "mmci-omap-hs.0"),
#endif /* defined(CONFIG_MMC_OMAP_HS) */
#if defined(CONFIG_INPUT_ADBS_A330)
REGULATOR_SUPPLY(DIAMOND_ADBS_A330_VDDA_SUPPLY, "2-0057"),
#endif /* defined(CONFIG_INPUT_ADBS_A330) */
};
#if !defined(CONFIG_WILINK) && !defined(CONFIG_WILINK_MODULE)
static struct regulator_consumer_supply diamond_vmmc2_supplies[] = {
REGULATOR_SUPPLY("vmmc", "mmci-omap-hs.1")
};
static struct regulator_init_data diamond_vmmc2_data = {
.constraints = {
.valid_modes_mask = REGULATOR_MODE_NORMAL,
.valid_ops_mask = REGULATOR_CHANGE_STATUS,
.always_on = false,
},
.num_consumer_supplies = ARRAY_SIZE(diamond_vmmc2_supplies),
.consumer_supplies = diamond_vmmc2_supplies,
};
static struct fixed_voltage_config diamond_vmmc2_pdata = {
.supply_name = "vmmc2",
.microvolts = 1800000,
.gpio = DIAMOND_GPIO_WIFI_ENABLE,
.startup_delay = 70000, /* 70 ms */
.enable_high = true,
.enabled_at_boot = false,
.init_data = &diamond_vmmc2_data,
};
static struct platform_device diamond_vmmc2_device = {
.name = "reg-fixed-voltage",
.id = -1,
.dev = {
.platform_data = &diamond_vmmc2_pdata,
},
};
#endif /* !defined(CONFIG_WILINK) && !defined(CONFIG_WILINK_MODULE) */
#if defined(CONFIG_TWL4030_MADC)
static struct twl4030_madc_platform_data __initdata diamond_tps65921_madc_data = {
.irq_line = 1
};
#endif
/* VMMC1 for MMC1 pins CMD, CLK, DAT0..DAT3 (20 mA, plus card == max 220 mA) */
struct regulator_init_data vmmc1_data = {
.constraints = {
.min_uV = 1850000,
.max_uV = 3150000,
.valid_modes_mask = REGULATOR_MODE_NORMAL
| REGULATOR_MODE_STANDBY,
.valid_ops_mask = REGULATOR_CHANGE_VOLTAGE
| REGULATOR_CHANGE_MODE
| REGULATOR_CHANGE_STATUS,
},
.num_consumer_supplies = 1,
.consumer_supplies = &twl4030_vmmc1_supply
};
static struct twl4030_platform_data __initdata diamond_tps65921_data = {
.irq_base = TWL4030_IRQ_BASE,
.irq_end = TWL4030_IRQ_END,
// platform_data for children goes here
.power = &diamond_tps65921_scripts_data,
.usb = &diamond_tps65921_usb_data,
.gpio = &diamond_tps65921_gpio_data,
.vmmc1 = &vmmc1_data,
#if defined(CONFIG_TWL4030_MADC)
.madc = &diamond_tps65921_madc_data,
#endif
#if defined(CONFIG_OMAP2_DSS)
.vpll2 = &diamond_tps65921_vpll2,
#endif
.vaux2 = &diamond_vaux2
};
/*
* This is identical to diamond except for using j49 scripts data and
* setting the vmmc1 data to NULL (VMMC1 is off for j49).
*/
static struct twl4030_platform_data __initdata j49_tps65921_data = {
.irq_base = TWL4030_IRQ_BASE,
.irq_end = TWL4030_IRQ_END,
/* platform_data for children goes here */
.power = &j49_tps65921_scripts_data,
.usb = &diamond_tps65921_usb_data,
.gpio = &diamond_tps65921_gpio_data,
#if defined(CONFIG_TWL4030_MADC)
.madc = &diamond_tps65921_madc_data,
#endif
#if defined(CONFIG_OMAP2_DSS)
.vpll2 = &diamond_tps65921_vpll2,
#endif
.vaux2 = &diamond_vaux2
};
static struct i2c_board_info __initdata diamond_tps65921_i2c_info[] = {
{
I2C_BOARD_INFO("twl4030", 0x48),
.flags = I2C_CLIENT_WAKE,
.irq = INT_34XX_SYS_NIRQ,
.platform_data = &diamond_tps65921_data,
},
};
static struct i2c_board_info __initdata j49_tps65921_i2c_info[] = {
{
I2C_BOARD_INFO("twl4030", 0x48),
.flags = I2C_CLIENT_WAKE,
.irq = INT_34XX_SYS_NIRQ,
.platform_data = &j49_tps65921_data,
},
};
#if defined(CONFIG_SENSORS_SI1143)
static struct si1143_platform_data diamond_si1143_data = {
.proximity_tx_led1 = 1,
.proximity_tx_led2 = 0,
.proximity_tx_led3 = 0,
};
#endif /* defined(CONFIG_SENSORS_SI1143) */
#if defined(CONFIG_INPUT_ADBS_A330)
static struct adbs_a330_platform_data diamond_adbs_a330_data = {
.vdda_supply = DIAMOND_ADBS_A330_VDDA_SUPPLY,
.vdda_uv = DIAMOND_ADBS_A330_VDDA_UV,
.motion_gpio = DIAMOND_GPIO_OFN_MOTION_L
/*
* We'll fix up both the shutdown and reset GPIO assignments based
* on the model.
*
* We'll also fix up both direction and mode at runtime based on
* the detected model.
*
* Generally, DIRECTION_NEG for form factor enclosures,
* DIRECTION_POS otherwise and DELTA_X for form factor enclosures,
* DELTA_Y otherwise.
*/
};
/*
* No regulator control necessary for j49, OFN is powered from VIO
*/
static struct adbs_a330_platform_data j49_adbs_a330_data = {
.motion_gpio = DIAMOND_GPIO_OFN_MOTION_L
/*
* We'll fix up both the shutdown and reset GPIO assignments based
* on the model.
*
* We'll also fix up both direction and mode at runtime based on
* the detected model.
*
* Generally, DIRECTION_NEG for form factor enclosures,
* DIRECTION_POS otherwise and DELTA_X for form factor enclosures,
* DELTA_Y otherwise.
*/
};
#endif /* defined(CONFIG_INPUT_ADBS_A330) */
static struct i2c_board_info __initdata diamond_development_i2c_2_info[] = {
#if defined(CONFIG_SENSORS_SI1143)
{
I2C_BOARD_INFO("si1143", 0x5A),
.flags = I2C_CLIENT_WAKE,
.irq = DIAMOND_GPIO_PROX_ALS_IRQ,
.platform_data = &diamond_si1143_data,
},
#endif /* defined(CONFIG_SENSORS_SI1143) */
};
static struct i2c_board_info __initdata diamond_prototype_i2c_2_info[] = {
#if defined(CONFIG_INPUT_ADBS_A330)
{
I2C_BOARD_INFO("avago-adbs-a330", 0x57),
.platform_data = &diamond_adbs_a330_data,
}
#endif /* defined(CONFIG_INPUT_ADBS_A330) */
};
static struct i2c_board_info __initdata j49_i2c_2_info[] = {
#if defined(CONFIG_INPUT_ADBS_A330)
{
I2C_BOARD_INFO("avago-adbs-a330", 0x57),
.platform_data = &j49_adbs_a330_data,
}
#endif /* defined(CONFIG_INPUT_ADBS_A330) */
};
#if defined(CONFIG_GENERIC_CMOS_UPDATE) && defined(CONFIG_RTC_LIB)
/**
* update_persistent_clock - set the hardware clock time to system time
* @now: the current system wall clock time.
*
* This routine attempts to access the primary hardware real-time
* clock and, if successful, sets it to the current system wall clock
* time.
*
* This generation (2.6.32) of ARM kernel has an alternative function
* do_set_rtc in linux/arch/arm/kernel/time.c that does something
* similar; however, in a more awkward and non-standard way. So much
* so, that in 2.6.36 kernels, it's gone away entirely.
*
* This more or less matches what is in linux/arch/sparc/kernel/time_64.c
*
* Returns 0 if the real-time clock was successfully set to the system
* wall clock time; otherwise, < 0 on error.
*/
int update_persistent_clock(struct timespec now)
{
const char * name = "rtc0";
struct rtc_device *rtc;
int err = -ENODEV;
rtc = rtc_class_open(name);
if (rtc) {
err = rtc_set_mmss(rtc, now.tv_sec);
rtc_class_close(rtc);
}
return err;
}
#endif /* defined(CONFIG_GENERIC_CMOS_UPDATE) && defined(CONFIG_RTC_LIB) */
static struct omap_board_config_kernel diamond_config[] __initdata = {
};
static void __init diamond_irq_init(void)
{
omap_board_config = diamond_config;
omap_board_config_size = ARRAY_SIZE(diamond_config);
omap2_init_common_infrastructure();
omap2_init_common_devices(k4x51163pi_nt6d_sdrc_params, NULL);
omap_init_irq();
gpmc_init();
}
static struct platform_device *diamond_common_devices[] __initdata = {
&diamond_dss_device,
&diamond_piezo_pwm_device,
#if defined(CONFIG_WILINK) || defined(CONFIG_WILINK_MODULE)
&diamond_wl1271_device,
#endif
&diamond_piezo_device,
&diamond_backplate_device,
#if defined(CONFIG_USB_DYNAMIC_MASS_STORAGE)
&diamond_dynamic_usb_msc_device,
#endif
#if !defined(CONFIG_WILINK) && !defined(CONFIG_WILINK_MODULE)
&diamond_vmmc2_device,
#endif /* !defined(CONFIG_WILINK) && !defined(CONFIG_WILINK_MODULE) */
};
static struct platform_device *diamond_development_devices[] __initdata = {
#if defined(CONFIG_USB_DYNAMIC)
&diamond_dynamic_usb_device,
#endif
#if defined(CONFIG_INPUT_GPIO_ROTARY_ENCODER_LITE)
&diamond_rotary_device,
#endif
&diamond_tps61042_backlight_device,
&diamond_backlight_pwm_device,
&diamond_zigbee_device,
};
static struct platform_device *diamond_prototype_devices[] __initdata = {
#if defined(CONFIG_USB_DYNAMIC)
&diamond_dynamic_usb_device,
#endif
#if defined(CONFIG_SENSORS_TWL4030_MADC)
&diamond_madc_hwmon_device,
#endif
&diamond_tps61042_backlight_device,
&diamond_backlight_pwm_device,
&diamond_zigbee_device,
};
static struct platform_device *diamond_1_6_devices[] __initdata = {
#if defined(CONFIG_USB_DYNAMIC)
&diamond_dynamic_usb_device,
#endif
#if defined(CONFIG_SENSORS_TWL4030_MADC)
&diamond_madc_hwmon_device,
#endif
&diamond_battery_device,
&diamond_tps61042_backlight_device,
&diamond_backlight_pwm_device,
&diamond_zigbee_device,
};
static struct platform_device *display_2_0_devices[] __initdata = {
#if defined(CONFIG_USB_DYNAMIC)
&j49_dynamic_usb_device,
#endif
#if defined(CONFIG_SENSORS_TWL4030_MADC)
&diamond_madc_hwmon_device,
#endif
&diamond_battery_device,
&j49_lm3530_backlight_device,
&j49_zigbee_device,
};
#ifdef CONFIG_OMAP_MUX
/*
* These are listed in schematic order, starting from the first CPU
* block symbol to the second, upper left corner to lower right
* corner.
*
* Do NOT be tempted to refactor these into a set of common mux
* settings and board-specific mux settings as omap3_mux_init does not
* tolerate being called twice and will overwrite previous settings
* with package defaults before applying the second set of
* board-specific settings.
*/
#include "board-diamond-development-mux.c"
#include "board-diamond-prototype-mux.c"
#include "board-diamond-evt-mux.c"
#include "board-diamond-dvt-mux.c"
#include "board-j49-prototype-mux.c"
#include "board-j49-evt-mux.c"
#else
#define diamond_development_mux NULL
#define diamond_prototype_mux NULL
#define diamond_evt_mux NULL
#define diamond_dvt_mux NULL
#define j49_prototype_mux NULL
#define j49_evt_mux NULL
#endif
#if defined(CONFIG_USB_DYNAMIC)
/**
* diamond_serial_number_init - initialize the board serial number used for USB
*
* This routine attempts to decode the board serial number, passed
* from the boot loader via ATAGs, and format it into a
* NULL-terminated C string used by the USB dynamic multi-function
* composite gadget interface.
*
* Successful implementation of this relies on the fact that
* manufacturing is restricting the serial number format to 15 decimal
* digits which we represent as a zero-padded, right-aligned
* hexadecimal number. Were that not the case, the serial number would
* have to be passed as a string on the kernel command line or we'd
* have to have a u-boot environment driver in the kernel.
*/
static void __init diamond_serial_number_init(void)
{
snprintf(diamond_serial_number,
DIAMOND_USB_SERIAL_STRING_SIZE,
"%.07X%.08X",
system_serial_high,
system_serial_low);
}
#else
static inline void diamond_serial_number_init(void) { return; }
#endif /* defined(CONFIG_USB_DYNAMIC) */
static void __init diamond_usb_init(void)
{
diamond_serial_number_init();
// USB 2.0 High-speed device support initialization
usb_musb_init(&musb_board_data);
#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
// USB 2.0 Full-speed host support initialization
diamond_gpio_try_output(DIAMOND_GPIO_INTUSB_SUSPEND, 0, return);
usb_ohci_init(&diamond_ohci_pdata);
#else
diamond_gpio_try_output(DIAMOND_GPIO_INTUSB_SUSPEND, 1, return);
#endif
}
static void __init diamond_backplate_init(const struct nlmodel *model)
{
diamond_backplate_device.dev.platform_data = (void *)((!strcmp(model->family, diamond_family) && \
(model->revision <= 3)) ? 0 : 1);
}
static void __init diamond_clk_init(void)
{
struct clk *sys_clkout1 = NULL;
/* In this architecture, we use the AM3703 as a 19.2 MHz clock
* master and the TPS65921 as a clock slave, fed via the AM3703's
* sys_clkout1 pin.
*
* We need to request the 'sys_clkout1' clock source to at least
* give it a reference count of one (1); otherwise, if the power
* management code has been configured, it'll get unceremoniously
* turned off with a message:
*
* Disabling unused clock "sys_clkout1"
*
* and general system functionality fails thereafter.
*/
sys_clkout1 = clk_get(NULL, "sys_clkout1");
BUG_ON(IS_ERR(sys_clkout1));
clk_enable(sys_clkout1);
}
static void __init diamond_development_mux_init(void)
{
const int flags = OMAP_PACKAGE_CUS;
omap3_mux_init(diamond_development_mux, flags);
}
static void __init diamond_1_4_mux_init(void)
{
const int flags = OMAP_PACKAGE_CUS;
omap3_mux_init(diamond_prototype_mux, flags);
}
static void __init diamond_1_5_mux_init(void)
{
const int flags = OMAP_PACKAGE_CUS;
omap3_mux_init(diamond_prototype_mux, flags);
}
static void __init diamond_1_6_mux_init(void)
{
const int flags = OMAP_PACKAGE_CUS;
omap3_mux_init(diamond_evt_mux, flags);
}
static void __init diamond_1_7_mux_init(void)
{
const int flags = OMAP_PACKAGE_CUS;
omap3_mux_init(diamond_dvt_mux, flags);
}
static void __init display_2_0_mux_init(void)
{
const int flags = OMAP_PACKAGE_CUS;
omap3_mux_init(j49_prototype_mux, flags);
}
static void __init display_2_1_mux_init(void)
{
const int flags = OMAP_PACKAGE_CUS;
omap3_mux_init(j49_evt_mux, flags);
}
static void __init diamond_development_i2c_init(void)
{
omap_register_i2c_bus(1, 2600, diamond_tps65921_i2c_info,
ARRAY_SIZE(diamond_tps65921_i2c_info));
omap_register_i2c_bus(2, 400, diamond_development_i2c_2_info,
ARRAY_SIZE(diamond_development_i2c_2_info));
}
static void __init diamond_1_4_i2c_init(void)
{
#if defined(CONFIG_INPUT_ADBS_A330)
/* Fix-up the shutdown and reset GPIOs as appropriate. */
diamond_adbs_a330_data.shutdown_gpio = DIAMOND_PROTOTYPE_GPIO_OFN_SHUTDOWN;
diamond_adbs_a330_data.reset_gpio = DIAMOND_PROTOTYPE_GPIO_OFN_RESET_L;
/* Fix-up the direction and mode as apppropriate. */
diamond_adbs_a330_data.direction = ADBS_A330_DIRECTION_POS;
diamond_adbs_a330_data.mode = ADBS_A330_DELTA_Y;
#endif /* defined(CONFIG_INPUT_ADBS_A330) */
omap_register_i2c_bus(1, 2600, diamond_tps65921_i2c_info,
ARRAY_SIZE(diamond_tps65921_i2c_info));
omap_register_i2c_bus(2, 400, diamond_prototype_i2c_2_info,
ARRAY_SIZE(diamond_prototype_i2c_2_info));
}
static void __init diamond_1_5_i2c_init(void)
{
/* Fix-up the shutdown and reset GPIOs as appropriate. */
#if defined(CONFIG_INPUT_ADBS_A330)
diamond_adbs_a330_data.shutdown_gpio = DIAMOND_PROTOTYPE_GPIO_OFN_SHUTDOWN;
diamond_adbs_a330_data.reset_gpio = DIAMOND_PROTOTYPE_GPIO_OFN_RESET_L;
/* Fix-up the direction and mode as apppropriate.*/
diamond_adbs_a330_data.direction = ADBS_A330_DIRECTION_NEG;
diamond_adbs_a330_data.mode = ADBS_A330_DELTA_X;
#endif /* defined(CONFIG_INPUT_ADBS_A330) */
omap_register_i2c_bus(1, 2600, diamond_tps65921_i2c_info,
ARRAY_SIZE(diamond_tps65921_i2c_info));
omap_register_i2c_bus(2, 400, diamond_prototype_i2c_2_info,
ARRAY_SIZE(diamond_prototype_i2c_2_info));
}
static void __init diamond_1_6_i2c_init(void)
{
/* Fix-up the shutdown and reset GPIOs as appropriate.*/
#if defined(CONFIG_INPUT_ADBS_A330)
diamond_adbs_a330_data.shutdown_gpio = DIAMOND_EVT_GPIO_OFN_SHUTDOWN;
diamond_adbs_a330_data.reset_gpio = DIAMOND_EVT_GPIO_OFN_RESET_L;
/* Fix-up the direction and mode as apppropriate.*/
diamond_adbs_a330_data.direction = ADBS_A330_DIRECTION_NEG;
diamond_adbs_a330_data.mode = ADBS_A330_DELTA_X;
#endif /* defined(CONFIG_INPUT_ADBS_A330) */
omap_register_i2c_bus(1, 400, diamond_tps65921_i2c_info,
ARRAY_SIZE(diamond_tps65921_i2c_info));
omap_register_i2c_bus(2, 400, diamond_prototype_i2c_2_info,
ARRAY_SIZE(diamond_prototype_i2c_2_info));
}
static void __init display_2_0_i2c_init(void)
{
#if defined(CONFIG_INPUT_ADBS_A330)
/* Fix-up the shutdown and reset GPIOs as appropriate. */
j49_adbs_a330_data.shutdown_gpio = DIAMOND_EVT_GPIO_OFN_SHUTDOWN;
j49_adbs_a330_data.reset_gpio = DIAMOND_EVT_GPIO_OFN_RESET_L;
/* Fix-up the direction and mode as apppropriate. */
j49_adbs_a330_data.direction = ADBS_A330_DIRECTION_POS;
j49_adbs_a330_data.mode = ADBS_A330_DELTA_Y;
#endif
omap_register_i2c_bus(1, 400, j49_tps65921_i2c_info,
ARRAY_SIZE(j49_tps65921_i2c_info));
omap_register_i2c_bus(2, 400, j49_i2c_2_info,
ARRAY_SIZE(j49_i2c_2_info));
omap_register_i2c_bus(3, 400, j49_backlight_i2c_info,
ARRAY_SIZE(j49_backlight_i2c_info));
}
static void __init diamond_1_4_piezo_init(void)
{
diamond_pwm_beeper_data.init = diamond_prototype_piezo_init;
diamond_pwm_beeper_data.exit = diamond_prototype_piezo_exit;
diamond_pwm_beeper_data.notify = diamond_prototype_piezo_notify;
}
static void __init diamond_1_5_piezo_init(void)
{
diamond_1_4_piezo_init();
}
static void __init diamond_development_add_devices(void)
{
platform_add_devices(diamond_common_devices,
ARRAY_SIZE(diamond_common_devices));
platform_add_devices(diamond_development_devices,
ARRAY_SIZE(diamond_development_devices));
}
static void __init diamond_1_4_add_devices(void)
{
platform_add_devices(diamond_common_devices,
ARRAY_SIZE(diamond_common_devices));
platform_add_devices(diamond_prototype_devices,
ARRAY_SIZE(diamond_prototype_devices));
}
static void __init diamond_1_5_add_devices(void)
{
diamond_1_4_add_devices();
}
static void __init diamond_1_6_add_devices(void)
{
platform_add_devices(diamond_common_devices,
ARRAY_SIZE(diamond_common_devices));
platform_add_devices(diamond_1_6_devices,
ARRAY_SIZE(diamond_1_6_devices));
}
/**
* diamond_1_7_add_devices - Add platform devices for model identifier "Diamond-1.7"
*
* Diamond-1.7 has an identical set of devices to Diamond-1.6, so
* simply add those.
*/
static void __init diamond_1_7_add_devices(void)
{
platform_add_devices(diamond_common_devices,
ARRAY_SIZE(diamond_common_devices));
platform_add_devices(diamond_1_6_devices,
ARRAY_SIZE(diamond_1_6_devices));
}
static void __init display_2_0_add_devices(void)
{
platform_add_devices(diamond_common_devices,
ARRAY_SIZE(diamond_common_devices));
platform_add_devices(display_2_0_devices,
ARRAY_SIZE(display_2_0_devices));
}
static void __init diamond_development_spi_init(void)
{
spi_register_board_info(diamond_development_spi_board_info,
ARRAY_SIZE(diamond_development_spi_board_info));
}
static void __init diamond_1_4_spi_init(void)
{
spi_register_board_info(diamond_1_4_spi_board_info,
ARRAY_SIZE(diamond_1_4_spi_board_info));
}
static void __init diamond_1_5_spi_init(void)
{
spi_register_board_info(diamond_1_5_spi_board_info,
ARRAY_SIZE(diamond_1_5_spi_board_info));
}
static void __init diamond_1_7_spi_init(void)
{
spi_register_board_info(diamond_1_7_spi_board_info,
ARRAY_SIZE(diamond_1_7_spi_board_info));
}
static void __init display_2_0_spi_init(void)
{
spi_register_board_info(display_2_0_spi_board_info,
ARRAY_SIZE(display_2_0_spi_board_info));
}
static void __init diamond_serial_init(void)
{
omap_serial_init();
}
static void __init diamond_development_mmc_init(void)
{
omap2_hsmmc_init(diamond_development_tps65921_mmc);
}
static void __init diamond_1_4_mmc_init(void)
{
omap2_hsmmc_init(diamond_prototype_tps65921_mmc);
}
static void __init diamond_1_5_mmc_init(void)
{
diamond_1_4_mmc_init();
}
static void __init diamond_development_display_init(void)
{
omapfb_set_platform_data(&diamond_320_480_omapfb_config);
diamond_display_gpio_init();
diamond_dss_devices[0] = &diamond_development_lcd_device;
diamond_dss_data.default_device = &diamond_development_lcd_device;
}
static void __init diamond_1_4_display_init(void)
{
omapfb_set_platform_data(&diamond_320_480_omapfb_config);
diamond_dss_devices[0] = &diamond_1_4_lcd_device;
diamond_dss_data.default_device = &diamond_1_4_lcd_device;
}
static void __init diamond_1_5_display_init(void)
{
omapfb_set_platform_data(&diamond_320_320_omapfb_config);
diamond_dss_devices[0] = &diamond_1_5_lcd_device;
diamond_dss_data.default_device = &diamond_1_5_lcd_device;
}
static void __init display_2_11_display_init(void)
{
int value;
diamond_gpio_try_input(DIAMOND_GPIO_LCD_ID, goto done);
value = gpio_get_value(DIAMOND_GPIO_LCD_ID);
gpio_free(DIAMOND_GPIO_LCD_ID);
if (value == LCD_ID_SAMSUNG)
{
omapfb_set_platform_data(&diamond_320_320_omapfb_config);
diamond_dss_devices[0] = &diamond_1_5_lcd_device;
diamond_dss_data.default_device = &diamond_1_5_lcd_device;
}
else
{
//renesas display driver
display_2_11_lcd_device.data = &r61529a1_config;
diamond_320_320_omapfb_config.lcd.rotation = 2;
omapfb_set_platform_data(&diamond_320_320_omapfb_config);
diamond_dss_devices[0] = &display_2_11_lcd_device;
diamond_dss_data.default_device = &display_2_11_lcd_device;
}
done:
return;
}
static void __init diamond_development_regulator_init(void)
{
// First, fix-up the number of and pointer to the consumer
// supplies for the VMMC1 PMU regulator rail; the static
// configuration in twl4030-pmic.c is incorrect for this board.
vmmc1_data.num_consumer_supplies = ARRAY_SIZE(diamond_development_vmmc1_supplies);
vmmc1_data.consumer_supplies = diamond_development_vmmc1_supplies;
// Fix up the LCD VPLL2 supply device.
diamond_vpll2_supplies[0].dev = &diamond_development_lcd_device.dev;
// Fix up the VAUX2 supplies as appropriate for this model
diamond_vaux2.num_consumer_supplies = ARRAY_SIZE(diamond_development_vaux2_supplies);
diamond_vaux2.consumer_supplies = diamond_development_vaux2_supplies;
#if !defined(CONFIG_WILINK) && !defined(CONFIG_WILINK_MODULE)
// Fix up the VMMC2 supply device.
diamond_vmmc2_supplies[0].dev = diamond_development_tps65921_mmc[1].dev;
#endif /* !defined(CONFIG_WILINK) && !defined(CONFIG_WILINK_MODULE) */
}
static void __init diamond_prototype_regulator_init(struct device *lcd_dev)
{
// First, fix-up the number of and pointer to the consumer
// supplies for the VMMC1 PMU regulator rail; the static
// configuration in twl4030-pmic.c is incorrect for this board.
vmmc1_data.num_consumer_supplies = ARRAY_SIZE(diamond_prototype_vmmc1_supplies);
vmmc1_data.consumer_supplies = diamond_prototype_vmmc1_supplies;
// Fix up the LCD VPLL2 supply device.
diamond_vpll2_supplies[0].dev = lcd_dev;
// Fix up the LCD VAUX2 supply device.
diamond_prototype_vaux2_supplies[1].dev = lcd_dev;
// Fix up the VAUX2 supplies as appropriate for this model
diamond_vaux2.num_consumer_supplies = ARRAY_SIZE(diamond_prototype_vaux2_supplies);
diamond_vaux2.consumer_supplies = diamond_prototype_vaux2_supplies;
#if !defined(CONFIG_WILINK) && !defined(CONFIG_WILINK_MODULE)
// Fix up the VMMC2 supply device.
diamond_vmmc2_supplies[0].dev = diamond_prototype_tps65921_mmc[0].dev;
#endif /* !defined(CONFIG_WILINK) && !defined(CONFIG_WILINK_MODULE) */
}
static void __init diamond_1_4_regulator_init(void)
{
diamond_prototype_regulator_init(&diamond_1_4_lcd_device.dev);
}
static void __init diamond_1_5_regulator_init(void)
{
diamond_prototype_regulator_init(&diamond_1_5_lcd_device.dev);
}
static void __init display_2_11_regulator_init(void)
{
diamond_prototype_regulator_init(&display_2_11_lcd_device.dev);
}
static void __init diamond_1_4_power_init(void)
{
pm_halt_system = twl4030_poweroff;
}
static void __init diamond_1_6_power_init(void)
{
pm_power_off = diamond_1_6_power_off;
pm_halt_system = diamond_1_6_halt_system;
}
#if defined(CONFIG_WL12XX) || defined(CONFIG_WL12XX_MODULE)
static void __init diamond_wl12xx_init(struct wl12xx_platform_data *data, unsigned int gpio, int clock)
{
int err, irq;
const char *name = "WL127x IRQ";
err = gpio_request(gpio, name);
if (err < 0) {
pr_err("Could not request GPIO %u for %s: %d\n", gpio, name, err);
return;
}
irq = OMAP_GPIO_IRQ(gpio);
if (irq < 0) {
pr_err("Could not assign GPIO %u for %s: %d\n", gpio, name, irq);
return;
}
data->irq = irq;
data->board_ref_clock = clock;
wl12xx_set_platform_data(data);
}
#endif /* defined(CONFIG_WL12XX) || defined(CONFIG_WL12XX_MODULE) */
static void __init diamond_development_net_init(void)
{
diamond_smsc911x_init();
diamond_wlan_init();
#if defined(CONFIG_WL12XX) || defined(CONFIG_WL12XX_MODULE)
diamond_wl12xx_init(&diamond_wl12xx_data, DIAMOND_GPIO_WIFI_IRQ, WL12XX_REFCLOCK_26);
#endif /* defined(CONFIG_WL12XX) || defined(CONFIG_WL12XX_MODULE) */
}
static void __init diamond_1_4_net_init(void)
{
diamond_wlan_init();
#if defined(CONFIG_WL12XX) || defined(CONFIG_WL12XX_MODULE)
diamond_wl12xx_init(&diamond_wl12xx_data, DIAMOND_GPIO_WIFI_IRQ, WL12XX_REFCLOCK_26);
#endif /* defined(CONFIG_WL12XX) || defined(CONFIG_WL12XX_MODULE) */
}
static void __init diamond_1_5_net_init(void)
{
diamond_1_4_net_init();
}
static void __init display_2_0_net_init(void)
{
#if defined(CONFIG_WL12XX) || defined(CONFIG_WL12XX_MODULE)
diamond_wl12xx_init(&diamond_wl12xx_data, DIAMOND_GPIO_WIFI_IRQ, WL12XX_REFCLOCK_26_XTAL);
#endif /* defined(CONFIG_WL12XX) || defined(CONFIG_WL12XX_MODULE) */
}
static void __init diamond_model_init(struct nlmodel *model,
const struct diamond_init_data *didp)
{
if (didp == NULL)
return;
if (didp->regulator_init) {
didp->regulator_init();
}
if (didp->power_init) {
didp->power_init();
}
if (didp->backplate_init) {
didp->backplate_init(model);
}
if (didp->display_init) {
didp->display_init();
}
if (didp->mux_init) {
didp->mux_init();
}
if (didp->i2c_init) {
didp->i2c_init();
}
if (didp->piezo_init) {
didp->piezo_init();
}
if (didp->add_devices) {
didp->add_devices();
}
if (didp->spi_init) {
didp->spi_init();
}
if (didp->serial_init) {
didp->serial_init();
}
if (didp->mmc_init) {
didp->mmc_init();
}
if (didp->usb_init) {
didp->usb_init();
}
if (didp->flash_init) {
didp->flash_init();
}
if (didp->net_init) {
didp->net_init();
}
if (didp->clk_init) {
didp->clk_init();
}
}
const struct diamond_init_data * __init __diamond_init_data(const char *family, int product, int revision)
{
const struct diamond_init_data *data = NULL;
if (family != NULL) {
if ((strcmp(family, diamond_family) != 0) && strcmp(family, j49_family) != 0) {
machine_warn("Unsupported model family '%s'\n", family);
} else {
if (product == diamond_product_default) {
if (revision >= 0 && revision <= 3) {
data = diamond_init_data[DIAMOND_DEVELOPMENT_DATA];
} else if (revision == 4) {
data = diamond_init_data[DIAMOND_1_4_DATA];
} else if (revision == 5) {
data = diamond_init_data[DIAMOND_1_5_DATA];
} else if (revision == 6) {
data = diamond_init_data[DIAMOND_1_6_DATA];
} else if (revision == 7) {
data = diamond_init_data[DIAMOND_1_7_DATA];
} else if (revision == 8) {
data = diamond_init_data[DIAMOND_1_8_DATA];
} else if (revision >= 9) {
data = diamond_init_data[DIAMOND_1_9_DATA];
} else if (revision != NL_MODEL_UNKNOWN) {
machine_warn("Unsupported model revision '%d'\n", revision);
} else {
machine_warn("Unknown model revision.\n");
}
} else if (product == j49_product_default) {
if (revision == 0) {
data = diamond_init_data[DISPLAY_2_0_DATA];
} else if (revision == 1) {
data = diamond_init_data[DISPLAY_2_1_DATA];
} else if (revision == 2) {
data = diamond_init_data[DISPLAY_2_2_DATA];
} else if (revision == 3) {
data = diamond_init_data[DISPLAY_2_3_DATA];
} else if ((revision >= 4) && (revision < 11)) {
data = diamond_init_data[DISPLAY_2_4_DATA];
} else if (revision >= 11) {
data = diamond_init_data[DISPLAY_2_11_DATA];
} else if (revision != NL_MODEL_UNKNOWN) {
machine_warn("Unsupported model revision '%d'\n", revision);
} else {
machine_warn("Unknown model revision.\n");
}
} else if (product != NL_MODEL_UNKNOWN) {
machine_warn("Unsupported model product '%d'\n", product);
} else {
machine_warn("Unknown model product.\n");
}
}
}
return data;
}
/**
* diamond_init - machine-specific initialization
*
* This is the machine-specific initialization function called from
* the .init_machine method of the machine defintion structure.
*
* This attempts to determine the machine model we are running on,
* first from the 'nlmodel=<family>-<product>.<revision>' kernel
* command line argument passed in by the boot loader, second the
* BCD-encoded <product:8><revision:8> also passed in from the boot
* loader and encoded in system_rev and, finally, by simply guessing.
*
*/
static void __init diamond_init(void)
{
int status;
struct nlmodel model;
const char *identifier = NULL;
const struct diamond_init_data *didp = NULL;
const char *family = NULL;
int product = NL_MODEL_UNKNOWN, revision = NL_MODEL_UNKNOWN;
bool initialized;
status = nlmodel_init(&model);
initialized = (status == 0);
if (status != 0) {
machine_warn("Could not initialize model.\n");
} else {
identifier = nlmodel_identifier();
if (identifier == NULL) {
machine_warn("Could not determine the model identifier.\n");
} else {
status = nlmodel_parse(identifier, &model);
if (status != 0) {
machine_warn("Unrecognized model identifer '%s'\n", identifier);
} else {
family = model.family;
product = model.product;
revision = model.revision;
didp = __diamond_init_data(family, product, revision);
}
}
}
/* Assume a Diamond family and fall back and try to BCD-decode
* (8-bits each, integer and fractional components) the product
* and revision from the system revision global as it's possible
* that the boot loader can still pass that via tags but the
* 'nlmodel=...' was missed.
*/
if (didp == NULL) {
machine_warn("Trying fallback model information.\n");
if (family == NULL) {
family = diamond_family;
}
product = (system_rev >> 8) & 0xFF;
revision = (system_rev >> 0) & 0xFF;
/* Treat a BCD-encoded value of 0x0000 the same as unknown (0xFFFF). */
if (!product && !revision) {
product = NL_MODEL_UNKNOWN;
revision = NL_MODEL_UNKNOWN;
}
if (model.product != NL_MODEL_UNKNOWN) {
product = model.product;
}
if (model.revision != NL_MODEL_UNKNOWN) {
revision = model.revision;
}
didp = __diamond_init_data(family, product, revision);
}
/* The fallback did not work, guess. */
if (didp == NULL) {
machine_warn("Guessing model information.\n");
family = diamond_family;
product = diamond_product_default;
revision = diamond_revision_default;
didp = __diamond_init_data(family, product, revision);
BUG_ON(didp == NULL);
}
/* Log what model we decoded, fell back to or guessed. */
if ((family != NULL) && (revision != NL_MODEL_UNKNOWN)) {
if ((didp != NULL) && (didp->name != NULL)) {
machine_info("Nest %s %s, Revision %d\n",
family,
didp->name,
revision);
} else {
machine_info("Nest %s, Revision %d\n",
family,
revision);
}
}
/* Perform the model-specific initialization. */
diamond_model_init(&model, didp);
if (initialized) {
nlmodel_destroy(&model);
}
}
/* This board file will support the following board machine identifiers. */
MACHINE_START(OMAP3EVM, "Nest Diamond")
.boot_params = 0x80000100,
.map_io = omap3_map_io,
.reserve = omap_reserve,
.init_irq = diamond_irq_init,
.init_machine = diamond_init,
.timer = &omap_timer,
MACHINE_END
/* MACH_DIAMOND - http://www.arm.linux.org.uk/developer/machines/list.php?id=3745 */
MACHINE_START(DIAMOND, "Nest Diamond")
.boot_params = 0x80000100,
.map_io = omap3_map_io,
.reserve = omap_reserve,
.init_irq = diamond_irq_init,
.init_machine = diamond_init,
.timer = &omap_timer,
MACHINE_END
/* MACH_J49 - http://www.arm.linux.org.uk/developer/machines/list.php?id=4082 */
MACHINE_START(J49, "Nest J49")
.boot_params = 0x80000100,
.map_io = omap3_map_io,
.reserve = omap_reserve,
.init_irq = diamond_irq_init,
.init_machine = diamond_init,
.timer = &omap_timer,
MACHINE_END