Path: blob/master/arch/arm/mach-msm/board-trout-panel.c
10817 views
/* linux/arch/arm/mach-msm/board-trout-mddi.c1** Author: Brian Swetland <[email protected]>2*/34#include <linux/kernel.h>5#include <linux/init.h>6#include <linux/platform_device.h>7#include <linux/delay.h>8#include <linux/leds.h>9#include <linux/clk.h>10#include <linux/err.h>1112#include <asm/io.h>13#include <asm/gpio.h>14#include <asm/mach-types.h>1516#include <mach/msm_fb.h>17#include <mach/vreg.h>1819#include "board-trout.h"20#include "proc_comm.h"21#include "devices.h"2223#define TROUT_DEFAULT_BACKLIGHT_BRIGHTNESS 2552425#define MDDI_CLIENT_CORE_BASE 0x10800026#define LCD_CONTROL_BLOCK_BASE 0x11000027#define SPI_BLOCK_BASE 0x12000028#define I2C_BLOCK_BASE 0x13000029#define PWM_BLOCK_BASE 0x14000030#define GPIO_BLOCK_BASE 0x15000031#define SYSTEM_BLOCK1_BASE 0x16000032#define SYSTEM_BLOCK2_BASE 0x170000333435#define DPSUS (MDDI_CLIENT_CORE_BASE|0x24)36#define SYSCLKENA (MDDI_CLIENT_CORE_BASE|0x2C)37#define PWM0OFF (PWM_BLOCK_BASE|0x1C)3839#define V_VDDE2E_VDD2_GPIO 040#define MDDI_RST_N 824142#define MDDICAP0 (MDDI_CLIENT_CORE_BASE|0x00)43#define MDDICAP1 (MDDI_CLIENT_CORE_BASE|0x04)44#define MDDICAP2 (MDDI_CLIENT_CORE_BASE|0x08)45#define MDDICAP3 (MDDI_CLIENT_CORE_BASE|0x0C)46#define MDCAPCHG (MDDI_CLIENT_CORE_BASE|0x10)47#define MDCRCERC (MDDI_CLIENT_CORE_BASE|0x14)48#define TTBUSSEL (MDDI_CLIENT_CORE_BASE|0x18)49#define DPSET0 (MDDI_CLIENT_CORE_BASE|0x1C)50#define DPSET1 (MDDI_CLIENT_CORE_BASE|0x20)51#define DPSUS (MDDI_CLIENT_CORE_BASE|0x24)52#define DPRUN (MDDI_CLIENT_CORE_BASE|0x28)53#define SYSCKENA (MDDI_CLIENT_CORE_BASE|0x2C)54#define TESTMODE (MDDI_CLIENT_CORE_BASE|0x30)55#define FIFOMONI (MDDI_CLIENT_CORE_BASE|0x34)56#define INTMONI (MDDI_CLIENT_CORE_BASE|0x38)57#define MDIOBIST (MDDI_CLIENT_CORE_BASE|0x3C)58#define MDIOPSET (MDDI_CLIENT_CORE_BASE|0x40)59#define BITMAP0 (MDDI_CLIENT_CORE_BASE|0x44)60#define BITMAP1 (MDDI_CLIENT_CORE_BASE|0x48)61#define BITMAP2 (MDDI_CLIENT_CORE_BASE|0x4C)62#define BITMAP3 (MDDI_CLIENT_CORE_BASE|0x50)63#define BITMAP4 (MDDI_CLIENT_CORE_BASE|0x54)6465#define SRST (LCD_CONTROL_BLOCK_BASE|0x00)66#define PORT_ENB (LCD_CONTROL_BLOCK_BASE|0x04)67#define START (LCD_CONTROL_BLOCK_BASE|0x08)68#define PORT (LCD_CONTROL_BLOCK_BASE|0x0C)69#define CMN (LCD_CONTROL_BLOCK_BASE|0x10)70#define GAMMA (LCD_CONTROL_BLOCK_BASE|0x14)71#define INTFLG (LCD_CONTROL_BLOCK_BASE|0x18)72#define INTMSK (LCD_CONTROL_BLOCK_BASE|0x1C)73#define MPLFBUF (LCD_CONTROL_BLOCK_BASE|0x20)74#define HDE_LEFT (LCD_CONTROL_BLOCK_BASE|0x24)75#define VDE_TOP (LCD_CONTROL_BLOCK_BASE|0x28)76#define PXL (LCD_CONTROL_BLOCK_BASE|0x30)77#define HCYCLE (LCD_CONTROL_BLOCK_BASE|0x34)78#define HSW (LCD_CONTROL_BLOCK_BASE|0x38)79#define HDE_START (LCD_CONTROL_BLOCK_BASE|0x3C)80#define HDE_SIZE (LCD_CONTROL_BLOCK_BASE|0x40)81#define VCYCLE (LCD_CONTROL_BLOCK_BASE|0x44)82#define VSW (LCD_CONTROL_BLOCK_BASE|0x48)83#define VDE_START (LCD_CONTROL_BLOCK_BASE|0x4C)84#define VDE_SIZE (LCD_CONTROL_BLOCK_BASE|0x50)85#define WAKEUP (LCD_CONTROL_BLOCK_BASE|0x54)86#define WSYN_DLY (LCD_CONTROL_BLOCK_BASE|0x58)87#define REGENB (LCD_CONTROL_BLOCK_BASE|0x5C)88#define VSYNIF (LCD_CONTROL_BLOCK_BASE|0x60)89#define WRSTB (LCD_CONTROL_BLOCK_BASE|0x64)90#define RDSTB (LCD_CONTROL_BLOCK_BASE|0x68)91#define ASY_DATA (LCD_CONTROL_BLOCK_BASE|0x6C)92#define ASY_DATB (LCD_CONTROL_BLOCK_BASE|0x70)93#define ASY_DATC (LCD_CONTROL_BLOCK_BASE|0x74)94#define ASY_DATD (LCD_CONTROL_BLOCK_BASE|0x78)95#define ASY_DATE (LCD_CONTROL_BLOCK_BASE|0x7C)96#define ASY_DATF (LCD_CONTROL_BLOCK_BASE|0x80)97#define ASY_DATG (LCD_CONTROL_BLOCK_BASE|0x84)98#define ASY_DATH (LCD_CONTROL_BLOCK_BASE|0x88)99#define ASY_CMDSET (LCD_CONTROL_BLOCK_BASE|0x8C)100101#define SSICTL (SPI_BLOCK_BASE|0x00)102#define SSITIME (SPI_BLOCK_BASE|0x04)103#define SSITX (SPI_BLOCK_BASE|0x08)104#define SSIRX (SPI_BLOCK_BASE|0x0C)105#define SSIINTC (SPI_BLOCK_BASE|0x10)106#define SSIINTS (SPI_BLOCK_BASE|0x14)107#define SSIDBG1 (SPI_BLOCK_BASE|0x18)108#define SSIDBG2 (SPI_BLOCK_BASE|0x1C)109#define SSIID (SPI_BLOCK_BASE|0x20)110111#define WKREQ (SYSTEM_BLOCK1_BASE|0x00)112#define CLKENB (SYSTEM_BLOCK1_BASE|0x04)113#define DRAMPWR (SYSTEM_BLOCK1_BASE|0x08)114#define INTMASK (SYSTEM_BLOCK1_BASE|0x0C)115#define GPIOSEL (SYSTEM_BLOCK2_BASE|0x00)116117#define GPIODATA (GPIO_BLOCK_BASE|0x00)118#define GPIODIR (GPIO_BLOCK_BASE|0x04)119#define GPIOIS (GPIO_BLOCK_BASE|0x08)120#define GPIOIBE (GPIO_BLOCK_BASE|0x0C)121#define GPIOIEV (GPIO_BLOCK_BASE|0x10)122#define GPIOIE (GPIO_BLOCK_BASE|0x14)123#define GPIORIS (GPIO_BLOCK_BASE|0x18)124#define GPIOMIS (GPIO_BLOCK_BASE|0x1C)125#define GPIOIC (GPIO_BLOCK_BASE|0x20)126#define GPIOOMS (GPIO_BLOCK_BASE|0x24)127#define GPIOPC (GPIO_BLOCK_BASE|0x28)128#define GPIOID (GPIO_BLOCK_BASE|0x30)129130#define SPI_WRITE(reg, val) \131{ SSITX, 0x00010000 | (((reg) & 0xff) << 8) | ((val) & 0xff) }, \132{ 0, 5 },133134#define SPI_WRITE1(reg) \135{ SSITX, (reg) & 0xff }, \136{ 0, 5 },137138struct mddi_table {139uint32_t reg;140uint32_t value;141};142static struct mddi_table mddi_toshiba_init_table[] = {143{ DPSET0, 0x09e90046 },144{ DPSET1, 0x00000118 },145{ DPSUS, 0x00000000 },146{ DPRUN, 0x00000001 },147{ 1, 14 }, /* msleep 14 */148{ SYSCKENA, 0x00000001 },149{ CLKENB, 0x0000A1EF }, /* # SYS.CLKENB # Enable clocks for each module (without DCLK , i2cCLK) */150151{ GPIODATA, 0x02000200 }, /* # GPI .GPIODATA # GPIO2(RESET_LCD_N) set to 0 , GPIO3(eDRAM_Power) set to 0 */152{ GPIODIR, 0x000030D }, /* 24D # GPI .GPIODIR # Select direction of GPIO port (0,2,3,6,9 output) */153{ GPIOSEL, 0/*0x00000173*/}, /* # SYS.GPIOSEL # GPIO port multiplexing control */154{ GPIOPC, 0x03C300C0 }, /* # GPI .GPIOPC # GPIO2,3 PD cut */155{ WKREQ, 0x00000000 }, /* # SYS.WKREQ # Wake-up request event is VSYNC alignment */156157{ GPIOIBE, 0x000003FF },158{ GPIOIS, 0x00000000 },159{ GPIOIC, 0x000003FF },160{ GPIOIE, 0x00000000 },161162{ GPIODATA, 0x00040004 }, /* # GPI .GPIODATA # eDRAM VD supply */163{ 1, 1 }, /* msleep 1 */164{ GPIODATA, 0x02040004 }, /* # GPI .GPIODATA # eDRAM VD supply */165{ DRAMPWR, 0x00000001 }, /* eDRAM power */166};167168#define GPIOSEL_VWAKEINT (1U << 0)169#define INTMASK_VWAKEOUT (1U << 0)170171172static struct clk *gp_clk;173static int trout_new_backlight = 1;174static struct vreg *vreg_mddi_1v5;175static struct vreg *vreg_lcm_2v85;176177static void trout_process_mddi_table(struct msm_mddi_client_data *client_data,178struct mddi_table *table, size_t count)179{180int i;181for (i = 0; i < count; i++) {182uint32_t reg = table[i].reg;183uint32_t value = table[i].value;184185if (reg == 0)186udelay(value);187else if (reg == 1)188msleep(value);189else190client_data->remote_write(client_data, value, reg);191}192}193194static int trout_mddi_toshiba_client_init(195struct msm_mddi_bridge_platform_data *bridge_data,196struct msm_mddi_client_data *client_data)197{198int panel_id;199200client_data->auto_hibernate(client_data, 0);201trout_process_mddi_table(client_data, mddi_toshiba_init_table,202ARRAY_SIZE(mddi_toshiba_init_table));203client_data->auto_hibernate(client_data, 1);204panel_id = (client_data->remote_read(client_data, GPIODATA) >> 4) & 3;205if (panel_id > 1) {206printk(KERN_WARNING "unknown panel id at mddi_enable\n");207return -1;208}209return 0;210}211212static int trout_mddi_toshiba_client_uninit(213struct msm_mddi_bridge_platform_data *bridge_data,214struct msm_mddi_client_data *client_data)215{216return 0;217}218219static struct resource resources_msm_fb[] = {220{221.start = MSM_FB_BASE,222.end = MSM_FB_BASE + MSM_FB_SIZE,223.flags = IORESOURCE_MEM,224},225};226227struct msm_mddi_bridge_platform_data toshiba_client_data = {228.init = trout_mddi_toshiba_client_init,229.uninit = trout_mddi_toshiba_client_uninit,230.fb_data = {231.xres = 320,232.yres = 480,233.width = 45,234.height = 67,235.output_format = 0,236},237};238239static struct msm_mddi_platform_data mddi_pdata = {240.clk_rate = 122880000,241.fb_resource = resources_msm_fb,242.num_clients = 1,243.client_platform_data = {244{245.product_id = (0xd263 << 16 | 0),246.name = "mddi_c_d263_0000",247.id = 0,248.client_data = &toshiba_client_data,249.clk_rate = 0,250},251},252};253254int __init trout_init_panel(void)255{256int rc;257258if (!machine_is_trout())259return 0;260vreg_mddi_1v5 = vreg_get(0, "gp2");261if (IS_ERR(vreg_mddi_1v5))262return PTR_ERR(vreg_mddi_1v5);263vreg_lcm_2v85 = vreg_get(0, "gp4");264if (IS_ERR(vreg_lcm_2v85))265return PTR_ERR(vreg_lcm_2v85);266267trout_new_backlight = system_rev >= 5;268if (trout_new_backlight) {269uint32_t config = PCOM_GPIO_CFG(27, 0, GPIO_OUTPUT,270GPIO_NO_PULL, GPIO_8MA);271msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX, &config, 0);272} else {273uint32_t config = PCOM_GPIO_CFG(27, 1, GPIO_OUTPUT,274GPIO_NO_PULL, GPIO_8MA);275msm_proc_comm(PCOM_RPC_GPIO_TLMM_CONFIG_EX, &config, 0);276277gp_clk = clk_get(NULL, "gp_clk");278if (IS_ERR(gp_clk)) {279printk(KERN_ERR "trout_init_panel: could not get gp"280"clock\n");281gp_clk = NULL;282}283rc = clk_set_rate(gp_clk, 19200000);284if (rc)285printk(KERN_ERR "trout_init_panel: set clock rate "286"failed\n");287}288289rc = platform_device_register(&msm_device_mdp);290if (rc)291return rc;292msm_device_mddi0.dev.platform_data = &mddi_pdata;293return platform_device_register(&msm_device_mddi0);294}295296device_initcall(trout_init_panel);297298299