提交 8eb26942 编写于 作者: G Greg Kroah-Hartman

Staging: msm: delete the driver

It doesn't build anymore, no one is working on it, and, according to the
developers, there's a different one that is working and in the real part
of the kernel already.
Acked-by: NDavid Brown <davidb@codeaurora.org>
Signed-off-by: NGreg Kroah-Hartman <gregkh@suse.de>
上级 0435f933
...@@ -118,8 +118,6 @@ source "drivers/staging/cxt1e1/Kconfig" ...@@ -118,8 +118,6 @@ source "drivers/staging/cxt1e1/Kconfig"
source "drivers/staging/xgifb/Kconfig" source "drivers/staging/xgifb/Kconfig"
source "drivers/staging/msm/Kconfig"
source "drivers/staging/lirc/Kconfig" source "drivers/staging/lirc/Kconfig"
source "drivers/staging/easycap/Kconfig" source "drivers/staging/easycap/Kconfig"
......
...@@ -51,7 +51,6 @@ obj-$(CONFIG_VIDEO_DT3155) += dt3155v4l/ ...@@ -51,7 +51,6 @@ obj-$(CONFIG_VIDEO_DT3155) += dt3155v4l/
obj-$(CONFIG_CRYSTALHD) += crystalhd/ obj-$(CONFIG_CRYSTALHD) += crystalhd/
obj-$(CONFIG_CXT1E1) += cxt1e1/ obj-$(CONFIG_CXT1E1) += cxt1e1/
obj-$(CONFIG_FB_XGI) += xgifb/ obj-$(CONFIG_FB_XGI) += xgifb/
obj-$(CONFIG_MSM_STAGING) += msm/
obj-$(CONFIG_EASYCAP) += easycap/ obj-$(CONFIG_EASYCAP) += easycap/
obj-$(CONFIG_SOLO6X10) += solo6x10/ obj-$(CONFIG_SOLO6X10) += solo6x10/
obj-$(CONFIG_TIDSPBRIDGE) += tidspbridge/ obj-$(CONFIG_TIDSPBRIDGE) += tidspbridge/
......
config MSM_STAGING
tristate "MSM Frame Buffer Support"
depends on FB && ARCH_MSM && !FB_MSM
select FB_BACKLIGHT if FB_MSM_BACKLIGHT
select NEW_LEDS
select LEDS_CLASS
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
---help---
Support for MSM Framebuffer.
if MSM_STAGING
config FB_MSM_LCDC_HW
bool
default n
choice
prompt "MDP HW version"
default FB_MSM_MDP31
config FB_MSM_MDP31
select FB_MSM_LCDC_HW
bool "MDP HW ver3.1"
---help---
Support for MSM MDP HW revision 3.1
Say Y here if this is msm8x50 variant platform.
endchoice
config FB_MSM_LCDC
bool
default n
config FB_MSM_TVOUT
bool
default n
config FB_MSM_LCDC_PANEL
bool
select FB_MSM_LCDC
default n
config FB_MSM_LCDC_PRISM_WVGA
bool
select FB_MSM_LCDC_PANEL
default n
config FB_MSM_LCDC_ST15_WXGA
bool
select FB_MSM_LCDC_PANEL
default n
choice
prompt "LCD Panel"
default FB_MSM_LCDC_ST15_PANEL
config FB_MSM_LCDC_PRISM_WVGA_PANEL
depends on FB_MSM_LCDC_HW
bool "LCDC Prism WVGA Panel"
select FB_MSM_LCDC_PRISM_WVGA
---help---
Support for LCDC Prism WVGA (800x480) panel
config FB_MSM_LCDC_ST15_PANEL
depends on FB_MSM_LCDC_HW
bool "LCDC ST1.5 Panel"
select FB_MSM_LCDC_ST15_WXGA
---help---
Support for ST1.5 WXGA (1366x768) panel
config FB_MSM_PANEL_NONE
bool "NONE"
---help---
This will disable LCD panel
endchoice
choice
prompt "Secondary LCD Panel"
depends on FB_MSM_MDP31
default FB_MSM_SECONDARY_PANEL_NONE
config FB_MSM_SECONDARY_PANEL_NONE
bool "NONE"
---help---
No secondary panel
endchoice
config FB_MSM_TVOUT_NTSC
bool
select FB_MSM_TVOUT
default n
config FB_MSM_TVOUT_PAL
bool
select FB_MSM_TVOUT
default n
choice
depends on (FB_MSM_MDP22 || FB_MSM_MDP31)
prompt "TVOut Region"
default FB_MSM_TVOUT_NTSC_M
config FB_MSM_TVOUT_NTSC_M
bool "NTSC M"
select FB_MSM_TVOUT_NTSC
---help---
Support for NTSC M region (North American and Korea)
config FB_MSM_TVOUT_NONE
bool "NONE"
---help---
This will disable TV Out functionality.
endchoice
config PMEM_KERNEL_SIZE
int "PMEM for kernel components (in MB)"
default 2
depends on ARCH_QSD8X50
help
Configures the amount of PMEM for use by kernel components
(in MB; minimum 2MB)
endif
obj-y := msm_fb.o staging-devices.o memory.o
obj-$(CONFIG_FB_MSM_LOGO) += logo.o
obj-$(CONFIG_FB_BACKLIGHT) += msm_fb_bl.o
# MDP
obj-y += mdp.o
ifeq ($(CONFIG_FB_MSM_MDP40),y)
obj-y += mdp4_util.o
obj-$(CONFIG_DEBUG_FS) += mdp4_debugfs.o
else
obj-y += mdp_hw_init.o
obj-y += mdp_ppp.o
ifeq ($(CONFIG_FB_MSM_MDP31),y)
obj-y += mdp_ppp_v31.o
obj-$(CONFIG_MDP_PPP_ASYNC_OP) += mdp_ppp_dq.o
else
obj-y += mdp_ppp_v20.o
endif
endif
ifeq ($(CONFIG_FB_MSM_OVERLAY),y)
obj-y += mdp4_overlay.o
obj-y += mdp4_overlay_lcdc.o
obj-y += mdp4_overlay_mddi.o
else
obj-y += mdp_dma_lcdc.o
endif
obj-y += mdp_dma.o
obj-y += mdp_dma_s.o
obj-y += mdp_vsync.o
obj-y += mdp_cursor.o
obj-y += mdp_dma_tv.o
# EBI2
obj-$(CONFIG_FB_MSM_EBI2) += ebi2_lcd.o
# LCDC
obj-$(CONFIG_FB_MSM_LCDC) += lcdc.o
# MDDI
msm_mddi-y := mddi.o mddihost.o mddihosti.o
obj-$(CONFIG_FB_MSM_MDDI) += msm_mddi.o
# External MDDI
msm_mddi_ext-y := mddihost_e.o mddi_ext.o
obj-$(CONFIG_FB_MSM_EXTMDDI) += msm_mddi_ext.o
# TVEnc
obj-$(CONFIG_FB_MSM_TVOUT) += tvenc.o
# MSM FB Panel
obj-y += msm_fb_panel.o
obj-$(CONFIG_FB_MSM_EBI2_TMD_QVGA_EPSON_QCIF) += ebi2_tmd20.o
obj-$(CONFIG_FB_MSM_EBI2_TMD_QVGA_EPSON_QCIF) += ebi2_l2f.o
ifeq ($(CONFIG_FB_MSM_MDDI_AUTO_DETECT),y)
obj-y += mddi_prism.o
obj-y += mddi_toshiba.o
obj-y += mddi_toshiba_vga.o
obj-y += mddi_toshiba_wvga_pt.o
obj-y += mddi_sharp.o
else
obj-$(CONFIG_FB_MSM_MDDI_PRISM_WVGA) += mddi_prism.o
obj-$(CONFIG_FB_MSM_MDDI_TOSHIBA_COMMON) += mddi_toshiba.o
obj-$(CONFIG_FB_MSM_MDDI_TOSHIBA_COMMON_VGA) += mddi_toshiba_vga.o
obj-$(CONFIG_FB_MSM_MDDI_TOSHIBA_WVGA_PORTRAIT) += mddi_toshiba_wvga_pt.o
obj-$(CONFIG_FB_MSM_MDDI_SHARP_QVGA_128x128) += mddi_sharp.o
endif
obj-$(CONFIG_FB_MSM_LCDC_PANEL) += lcdc_panel.o
obj-$(CONFIG_FB_MSM_LCDC_PRISM_WVGA) += lcdc_prism.o
obj-$(CONFIG_FB_MSM_LCDC_EXTERNAL_WXGA) += lcdc_external.o
obj-$(CONFIG_FB_MSM_LCDC_GORDON_VGA) += lcdc_gordon.o
obj-$(CONFIG_FB_MSM_LCDC_TOSHIBA_WVGA_PT) += lcdc_toshiba_wvga_pt.o
obj-$(CONFIG_FB_MSM_LCDC_SHARP_WVGA_PT) += lcdc_sharp_wvga_pt.o
obj-$(CONFIG_FB_MSM_LCDC_ST15_WXGA) += lcdc_st15.o
obj-$(CONFIG_FB_MSM_HDMI_SII_EXTERNAL_720P) += hdmi_sii9022.o
obj-$(CONFIG_FB_MSM_TVOUT_NTSC) += tv_ntsc.o
obj-$(CONFIG_FB_MSM_TVOUT_PAL) += tv_pal.o
obj-$(CONFIG_FB_MSM_EXTMDDI_SVGA) += mddi_ext_lcd.o
clean:
rm *.o .*cmd
- Merge this code with the existing MSM framebuffer
- General style clean ups.
/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#include "msm_fb.h"
#include <linux/memory.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/time.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/proc_fs.h>
#include <linux/delay.h>
#include <mach/hardware.h>
#include <linux/io.h>
#include <asm/system.h>
#include <asm/mach-types.h>
/* The following are for MSM5100 on Gator
*/
#ifdef FEATURE_PM1000
#include "pm1000.h"
#endif /* FEATURE_PM1000 */
/* The following are for MSM6050 on Bambi
*/
#ifdef FEATURE_PMIC_LCDKBD_LED_DRIVER
#include "pm.h"
#endif /* FEATURE_PMIC_LCDKBD_LED_DRIVER */
#ifdef DISP_DEVICE_18BPP
#undef DISP_DEVICE_18BPP
#define DISP_DEVICE_16BPP
#endif
#define QCIF_WIDTH 176
#define QCIF_HEIGHT 220
static void *DISP_CMD_PORT;
static void *DISP_DATA_PORT;
#define DISP_CMD_DISON 0xaf
#define DISP_CMD_DISOFF 0xae
#define DISP_CMD_DISNOR 0xa6
#define DISP_CMD_DISINV 0xa7
#define DISP_CMD_DISCTL 0xca
#define DISP_CMD_GCP64 0xcb
#define DISP_CMD_GCP16 0xcc
#define DISP_CMD_GSSET 0xcd
#define DISP_GS_2 0x02
#define DISP_GS_16 0x01
#define DISP_GS_64 0x00
#define DISP_CMD_SLPIN 0x95
#define DISP_CMD_SLPOUT 0x94
#define DISP_CMD_SD_PSET 0x75
#define DISP_CMD_MD_PSET 0x76
#define DISP_CMD_SD_CSET 0x15
#define DISP_CMD_MD_CSET 0x16
#define DISP_CMD_DATCTL 0xbc
#define DISP_DATCTL_666 0x08
#define DISP_DATCTL_565 0x28
#define DISP_DATCTL_444 0x38
#define DISP_CMD_RAMWR 0x5c
#define DISP_CMD_RAMRD 0x5d
#define DISP_CMD_PTLIN 0xa8
#define DISP_CMD_PTLOUT 0xa9
#define DISP_CMD_ASCSET 0xaa
#define DISP_CMD_SCSTART 0xab
#define DISP_CMD_VOLCTL 0xc6
#define DISP_VOLCTL_TONE 0x80
#define DISP_CMD_NOp 0x25
#define DISP_CMD_OSSEL 0xd0
#define DISP_CMD_3500KSET 0xd1
#define DISP_CMD_3500KEND 0xd2
#define DISP_CMD_14MSET 0xd3
#define DISP_CMD_14MEND 0xd4
#define DISP_CMD_OUT(cmd) outpw(DISP_CMD_PORT, cmd);
#define DISP_DATA_OUT(data) outpw(DISP_DATA_PORT, data);
#define DISP_DATA_IN() inpw(DISP_DATA_PORT);
/* Epson device column number starts at 2
*/
#define DISP_SET_RECT(ulhc_row, lrhc_row, ulhc_col, lrhc_col) \
DISP_CMD_OUT(DISP_CMD_SD_PSET) \
DISP_DATA_OUT((ulhc_row) & 0xFF) \
DISP_DATA_OUT((ulhc_row) >> 8) \
DISP_DATA_OUT((lrhc_row) & 0xFF) \
DISP_DATA_OUT((lrhc_row) >> 8) \
DISP_CMD_OUT(DISP_CMD_SD_CSET) \
DISP_DATA_OUT(((ulhc_col)+2) & 0xFF) \
DISP_DATA_OUT(((ulhc_col)+2) >> 8) \
DISP_DATA_OUT(((lrhc_col)+2) & 0xFF) \
DISP_DATA_OUT(((lrhc_col)+2) >> 8)
#define DISP_MIN_CONTRAST 0
#define DISP_MAX_CONTRAST 127
#define DISP_DEFAULT_CONTRAST 80
#define DISP_MIN_BACKLIGHT 0
#define DISP_MAX_BACKLIGHT 15
#define DISP_DEFAULT_BACKLIGHT 2
#define WAIT_SEC(sec) mdelay((sec)/1000)
static word disp_area_start_row;
static word disp_area_end_row;
static byte disp_contrast = DISP_DEFAULT_CONTRAST;
static boolean disp_powered_up;
static boolean disp_initialized = FALSE;
/* For some reason the contrast set at init time is not good. Need to do
* it again
*/
static boolean display_on = FALSE;
static void epsonQcif_disp_init(struct platform_device *pdev);
static void epsonQcif_disp_set_contrast(word contrast);
static void epsonQcif_disp_set_display_area(word start_row, word end_row);
static int epsonQcif_disp_off(struct platform_device *pdev);
static int epsonQcif_disp_on(struct platform_device *pdev);
static void epsonQcif_disp_set_rect(int x, int y, int xres, int yres);
volatile word databack;
static void epsonQcif_disp_init(struct platform_device *pdev)
{
struct msm_fb_data_type *mfd;
int i;
if (disp_initialized)
return;
mfd = platform_get_drvdata(pdev);
DISP_CMD_PORT = mfd->cmd_port;
DISP_DATA_PORT = mfd->data_port;
/* Sleep in */
DISP_CMD_OUT(DISP_CMD_SLPIN);
/* Display off */
DISP_CMD_OUT(DISP_CMD_DISOFF);
/* Display normal */
DISP_CMD_OUT(DISP_CMD_DISNOR);
/* Set data mode */
DISP_CMD_OUT(DISP_CMD_DATCTL);
DISP_DATA_OUT(DISP_DATCTL_565);
/* Set display timing */
DISP_CMD_OUT(DISP_CMD_DISCTL);
DISP_DATA_OUT(0x1c); /* p1 */
DISP_DATA_OUT(0x02); /* p1 */
DISP_DATA_OUT(0x82); /* p2 */
DISP_DATA_OUT(0x00); /* p3 */
DISP_DATA_OUT(0x00); /* p4 */
DISP_DATA_OUT(0xe0); /* p5 */
DISP_DATA_OUT(0x00); /* p5 */
DISP_DATA_OUT(0xdc); /* p6 */
DISP_DATA_OUT(0x00); /* p6 */
DISP_DATA_OUT(0x02); /* p7 */
DISP_DATA_OUT(0x00); /* p8 */
/* Set 64 gray scale level */
DISP_CMD_OUT(DISP_CMD_GCP64);
DISP_DATA_OUT(0x08); /* p01 */
DISP_DATA_OUT(0x00);
DISP_DATA_OUT(0x2a); /* p02 */
DISP_DATA_OUT(0x00);
DISP_DATA_OUT(0x4e); /* p03 */
DISP_DATA_OUT(0x00);
DISP_DATA_OUT(0x6b); /* p04 */
DISP_DATA_OUT(0x00);
DISP_DATA_OUT(0x88); /* p05 */
DISP_DATA_OUT(0x00);
DISP_DATA_OUT(0xa3); /* p06 */
DISP_DATA_OUT(0x00);
DISP_DATA_OUT(0xba); /* p07 */
DISP_DATA_OUT(0x00);
DISP_DATA_OUT(0xd1); /* p08 */
DISP_DATA_OUT(0x00);
DISP_DATA_OUT(0xe5); /* p09 */
DISP_DATA_OUT(0x00);
DISP_DATA_OUT(0xf3); /* p10 */
DISP_DATA_OUT(0x00);
DISP_DATA_OUT(0x03); /* p11 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x13); /* p12 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x22); /* p13 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x2f); /* p14 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x3b); /* p15 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x46); /* p16 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x51); /* p17 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x5b); /* p18 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x64); /* p19 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x6c); /* p20 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x74); /* p21 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x7c); /* p22 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x83); /* p23 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x8a); /* p24 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x91); /* p25 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x98); /* p26 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x9f); /* p27 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xa6); /* p28 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xac); /* p29 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xb2); /* p30 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xb7); /* p31 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xbc); /* p32 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xc1); /* p33 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xc6); /* p34 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xcb); /* p35 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xd0); /* p36 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xd4); /* p37 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xd8); /* p38 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xdc); /* p39 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xe0); /* p40 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xe4); /* p41 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xe8); /* p42 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xec); /* p43 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xf0); /* p44 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xf4); /* p45 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xf8); /* p46 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xfb); /* p47 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xfe); /* p48 */
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0x01); /* p49 */
DISP_DATA_OUT(0x02);
DISP_DATA_OUT(0x03); /* p50 */
DISP_DATA_OUT(0x02);
DISP_DATA_OUT(0x05); /* p51 */
DISP_DATA_OUT(0x02);
DISP_DATA_OUT(0x07); /* p52 */
DISP_DATA_OUT(0x02);
DISP_DATA_OUT(0x09); /* p53 */
DISP_DATA_OUT(0x02);
DISP_DATA_OUT(0x0b); /* p54 */
DISP_DATA_OUT(0x02);
DISP_DATA_OUT(0x0d); /* p55 */
DISP_DATA_OUT(0x02);
DISP_DATA_OUT(0x0f); /* p56 */
DISP_DATA_OUT(0x02);
DISP_DATA_OUT(0x11); /* p57 */
DISP_DATA_OUT(0x02);
DISP_DATA_OUT(0x13); /* p58 */
DISP_DATA_OUT(0x02);
DISP_DATA_OUT(0x15); /* p59 */
DISP_DATA_OUT(0x02);
DISP_DATA_OUT(0x17); /* p60 */
DISP_DATA_OUT(0x02);
DISP_DATA_OUT(0x19); /* p61 */
DISP_DATA_OUT(0x02);
DISP_DATA_OUT(0x1b); /* p62 */
DISP_DATA_OUT(0x02);
DISP_DATA_OUT(0x1c); /* p63 */
DISP_DATA_OUT(0x02);
/* Set 16 gray scale level */
DISP_CMD_OUT(DISP_CMD_GCP16);
DISP_DATA_OUT(0x1a); /* p01 */
DISP_DATA_OUT(0x32); /* p02 */
DISP_DATA_OUT(0x42); /* p03 */
DISP_DATA_OUT(0x4c); /* p04 */
DISP_DATA_OUT(0x58); /* p05 */
DISP_DATA_OUT(0x5f); /* p06 */
DISP_DATA_OUT(0x66); /* p07 */
DISP_DATA_OUT(0x6b); /* p08 */
DISP_DATA_OUT(0x70); /* p09 */
DISP_DATA_OUT(0x74); /* p10 */
DISP_DATA_OUT(0x78); /* p11 */
DISP_DATA_OUT(0x7b); /* p12 */
DISP_DATA_OUT(0x7e); /* p13 */
DISP_DATA_OUT(0x80); /* p14 */
DISP_DATA_OUT(0x82); /* p15 */
/* Set DSP column */
DISP_CMD_OUT(DISP_CMD_MD_CSET);
DISP_DATA_OUT(0xff);
DISP_DATA_OUT(0x03);
DISP_DATA_OUT(0xff);
DISP_DATA_OUT(0x03);
/* Set DSP page */
DISP_CMD_OUT(DISP_CMD_MD_PSET);
DISP_DATA_OUT(0xff);
DISP_DATA_OUT(0x01);
DISP_DATA_OUT(0xff);
DISP_DATA_OUT(0x01);
/* Set ARM column */
DISP_CMD_OUT(DISP_CMD_SD_CSET);
DISP_DATA_OUT(0x02);
DISP_DATA_OUT(0x00);
DISP_DATA_OUT((QCIF_WIDTH + 1) & 0xFF);
DISP_DATA_OUT((QCIF_WIDTH + 1) >> 8);
/* Set ARM page */
DISP_CMD_OUT(DISP_CMD_SD_PSET);
DISP_DATA_OUT(0x00);
DISP_DATA_OUT(0x00);
DISP_DATA_OUT((QCIF_HEIGHT - 1) & 0xFF);
DISP_DATA_OUT((QCIF_HEIGHT - 1) >> 8);
/* Set 64 gray scales */
DISP_CMD_OUT(DISP_CMD_GSSET);
DISP_DATA_OUT(DISP_GS_64);
DISP_CMD_OUT(DISP_CMD_OSSEL);
DISP_DATA_OUT(0);
/* Sleep out */
DISP_CMD_OUT(DISP_CMD_SLPOUT);
WAIT_SEC(40000);
/* Initialize power IC */
DISP_CMD_OUT(DISP_CMD_VOLCTL);
DISP_DATA_OUT(DISP_VOLCTL_TONE);
WAIT_SEC(40000);
/* Set electronic volume, d'xx */
DISP_CMD_OUT(DISP_CMD_VOLCTL);
DISP_DATA_OUT(DISP_DEFAULT_CONTRAST); /* value from 0 to 127 */
/* Initialize display data */
DISP_SET_RECT(0, (QCIF_HEIGHT - 1), 0, (QCIF_WIDTH - 1));
DISP_CMD_OUT(DISP_CMD_RAMWR);
for (i = 0; i < QCIF_HEIGHT * QCIF_WIDTH; i++)
DISP_DATA_OUT(0xffff);
DISP_CMD_OUT(DISP_CMD_RAMRD);
databack = DISP_DATA_IN();
databack = DISP_DATA_IN();
databack = DISP_DATA_IN();
databack = DISP_DATA_IN();
WAIT_SEC(80000);
DISP_CMD_OUT(DISP_CMD_DISON);
disp_area_start_row = 0;
disp_area_end_row = QCIF_HEIGHT - 1;
disp_powered_up = TRUE;
disp_initialized = TRUE;
epsonQcif_disp_set_display_area(0, QCIF_HEIGHT - 1);
display_on = TRUE;
}
static void epsonQcif_disp_set_rect(int x, int y, int xres, int yres)
{
if (!disp_initialized)
return;
DISP_SET_RECT(y, y + yres - 1, x, x + xres - 1);
DISP_CMD_OUT(DISP_CMD_RAMWR);
}
static void epsonQcif_disp_set_display_area(word start_row, word end_row)
{
if (!disp_initialized)
return;
if ((start_row == disp_area_start_row)
&& (end_row == disp_area_end_row))
return;
disp_area_start_row = start_row;
disp_area_end_row = end_row;
/* Range checking
*/
if (end_row >= QCIF_HEIGHT)
end_row = QCIF_HEIGHT - 1;
if (start_row > end_row)
start_row = end_row;
/* When display is not the full screen, gray scale is set to
** 2; otherwise it is set to 64.
*/
if ((start_row == 0) && (end_row == (QCIF_HEIGHT - 1))) {
/* The whole screen */
DISP_CMD_OUT(DISP_CMD_PTLOUT);
WAIT_SEC(10000);
DISP_CMD_OUT(DISP_CMD_DISOFF);
WAIT_SEC(100000);
DISP_CMD_OUT(DISP_CMD_GSSET);
DISP_DATA_OUT(DISP_GS_64);
WAIT_SEC(100000);
DISP_CMD_OUT(DISP_CMD_DISON);
} else {
/* partial screen */
DISP_CMD_OUT(DISP_CMD_PTLIN);
DISP_DATA_OUT(start_row);
DISP_DATA_OUT(start_row >> 8);
DISP_DATA_OUT(end_row);
DISP_DATA_OUT(end_row >> 8);
DISP_CMD_OUT(DISP_CMD_GSSET);
DISP_DATA_OUT(DISP_GS_2);
}
}
static int epsonQcif_disp_off(struct platform_device *pdev)
{
if (!disp_initialized)
epsonQcif_disp_init(pdev);
if (display_on) {
DISP_CMD_OUT(DISP_CMD_DISOFF);
DISP_CMD_OUT(DISP_CMD_SLPIN);
display_on = FALSE;
}
return 0;
}
static int epsonQcif_disp_on(struct platform_device *pdev)
{
if (!disp_initialized)
epsonQcif_disp_init(pdev);
if (!display_on) {
DISP_CMD_OUT(DISP_CMD_SLPOUT);
WAIT_SEC(40000);
DISP_CMD_OUT(DISP_CMD_DISON);
epsonQcif_disp_set_contrast(disp_contrast);
display_on = TRUE;
}
return 0;
}
static void epsonQcif_disp_set_contrast(word contrast)
{
if (!disp_initialized)
return;
/* Initialize power IC, d'24 */
DISP_CMD_OUT(DISP_CMD_VOLCTL);
DISP_DATA_OUT(DISP_VOLCTL_TONE);
WAIT_SEC(40000);
/* Set electronic volume, d'xx */
DISP_CMD_OUT(DISP_CMD_VOLCTL);
if (contrast > 127)
contrast = 127;
DISP_DATA_OUT(contrast); /* value from 0 to 127 */
disp_contrast = (byte) contrast;
} /* End disp_set_contrast */
static void epsonQcif_disp_clear_screen_area(
word start_row, word end_row, word start_column, word end_column) {
int32 i;
/* Clear the display screen */
DISP_SET_RECT(start_row, end_row, start_column, end_column);
DISP_CMD_OUT(DISP_CMD_RAMWR);
i = (end_row - start_row + 1) * (end_column - start_column + 1);
for (; i > 0; i--)
DISP_DATA_OUT(0xffff);
}
static int __init epsonQcif_probe(struct platform_device *pdev)
{
msm_fb_add_device(pdev);
return 0;
}
static struct platform_driver this_driver = {
.probe = epsonQcif_probe,
.driver = {
.name = "ebi2_epson_qcif",
},
};
static struct msm_fb_panel_data epsonQcif_panel_data = {
.on = epsonQcif_disp_on,
.off = epsonQcif_disp_off,
.set_rect = epsonQcif_disp_set_rect,
};
static struct platform_device this_device = {
.name = "ebi2_epson_qcif",
.id = 0,
.dev = {
.platform_data = &epsonQcif_panel_data,
}
};
static int __init epsonQcif_init(void)
{
int ret;
struct msm_panel_info *pinfo;
ret = platform_driver_register(&this_driver);
if (!ret) {
pinfo = &epsonQcif_panel_data.panel_info;
pinfo->xres = QCIF_WIDTH;
pinfo->yres = QCIF_HEIGHT;
pinfo->type = EBI2_PANEL;
pinfo->pdest = DISPLAY_2;
pinfo->wait_cycle = 0x808000;
pinfo->bpp = 16;
pinfo->fb_num = 2;
pinfo->lcd.vsync_enable = FALSE;
ret = platform_device_register(&this_device);
if (ret)
platform_driver_unregister(&this_driver);
}
return ret;
}
module_init(epsonQcif_init);
/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/mm.h>
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/uaccess.h>
#include <linux/workqueue.h>
#include <linux/string.h>
#include <linux/proc_fs.h>
#include <linux/vmalloc.h>
#include <linux/debugfs.h>
#include "msm_fb.h"
static int ebi2_lcd_probe(struct platform_device *pdev);
static int ebi2_lcd_remove(struct platform_device *pdev);
static struct platform_driver ebi2_lcd_driver = {
.probe = ebi2_lcd_probe,
.remove = ebi2_lcd_remove,
.suspend = NULL,
.suspend_late = NULL,
.resume_early = NULL,
.resume = NULL,
.shutdown = NULL,
.driver = {
.name = "ebi2_lcd",
},
};
static void *ebi2_base;
static void *ebi2_lcd_cfg0;
static void *ebi2_lcd_cfg1;
static void __iomem *lcd01_base;
static void __iomem *lcd02_base;
static int ebi2_lcd_resource_initialized;
static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST];
static int pdev_list_cnt;
static int ebi2_lcd_probe(struct platform_device *pdev)
{
struct msm_fb_data_type *mfd;
struct platform_device *mdp_dev = NULL;
struct msm_fb_panel_data *pdata = NULL;
int rc, i;
if (pdev->id == 0) {
for (i = 0; i < pdev->num_resources; i++) {
if (!strncmp(pdev->resource[i].name, "base", 4)) {
ebi2_base = ioremap(pdev->resource[i].start,
pdev->resource[i].end -
pdev->resource[i].start + 1);
if (!ebi2_base) {
printk(KERN_ERR
"ebi2_base ioremap failed!\n");
return -ENOMEM;
}
ebi2_lcd_cfg0 = (void *)(ebi2_base + 0x20);
ebi2_lcd_cfg1 = (void *)(ebi2_base + 0x24);
} else if (!strncmp(pdev->resource[i].name,
"lcd01", 5)) {
lcd01_base = ioremap(pdev->resource[i].start,
pdev->resource[i].end -
pdev->resource[i].start + 1);
if (!lcd01_base) {
printk(KERN_ERR
"lcd01_base ioremap failed!\n");
return -ENOMEM;
}
} else if (!strncmp(pdev->resource[i].name,
"lcd02", 5)) {
lcd02_base = ioremap(pdev->resource[i].start,
pdev->resource[i].end -
pdev->resource[i].start + 1);
if (!lcd02_base) {
printk(KERN_ERR
"lcd02_base ioremap failed!\n");
return -ENOMEM;
}
}
}
ebi2_lcd_resource_initialized = 1;
return 0;
}
if (!ebi2_lcd_resource_initialized)
return -EPERM;
mfd = platform_get_drvdata(pdev);
if (!mfd)
return -ENODEV;
if (mfd->key != MFD_KEY)
return -EINVAL;
if (pdev_list_cnt >= MSM_FB_MAX_DEV_LIST)
return -ENOMEM;
if (ebi2_base == NULL)
return -ENOMEM;
mdp_dev = platform_device_alloc("mdp", pdev->id);
if (!mdp_dev)
return -ENOMEM;
/* link to the latest pdev */
mfd->pdev = mdp_dev;
mfd->dest = DISPLAY_LCD;
/* add panel data */
if (platform_device_add_data
(mdp_dev, pdev->dev.platform_data,
sizeof(struct msm_fb_panel_data))) {
printk(KERN_ERR "ebi2_lcd_probe: platform_device_add_data failed!\n");
platform_device_put(mdp_dev);
return -ENOMEM;
}
/* data chain */
pdata = mdp_dev->dev.platform_data;
pdata->on = panel_next_on;
pdata->off = panel_next_off;
pdata->next = pdev;
/* get/set panel specific fb info */
mfd->panel_info = pdata->panel_info;
if (mfd->panel_info.bpp == 24)
mfd->fb_imgType = MDP_RGB_888;
else
mfd->fb_imgType = MDP_RGB_565;
/* config msm ebi2 lcd register */
if (mfd->panel_info.pdest == DISPLAY_1) {
outp32(ebi2_base,
(inp32(ebi2_base) & (~(EBI2_PRIM_LCD_CLR))) |
EBI2_PRIM_LCD_SEL);
/*
* current design has one set of cfg0/1 register to control
* both EBI2 channels. so, we're using the PRIM channel to
* configure both.
*/
outp32(ebi2_lcd_cfg0, mfd->panel_info.wait_cycle);
if (mfd->panel_info.bpp == 18)
outp32(ebi2_lcd_cfg1, 0x01000000);
else
outp32(ebi2_lcd_cfg1, 0x0);
} else {
#ifdef DEBUG_EBI2_LCD
/*
* confliting with QCOM SURF FPGA CS.
* OEM should enable below for their CS mapping
*/
outp32(ebi2_base, (inp32(ebi2_base)&(~(EBI2_SECD_LCD_CLR)))
|EBI2_SECD_LCD_SEL);
#endif
}
/*
* map cs (chip select) address
*/
if (mfd->panel_info.pdest == DISPLAY_1) {
mfd->cmd_port = lcd01_base;
mfd->data_port =
(void *)((uint32) mfd->cmd_port + EBI2_PRIM_LCD_RS_PIN);
mfd->data_port_phys =
(void *)(LCD_PRIM_BASE_PHYS + EBI2_PRIM_LCD_RS_PIN);
} else {
mfd->cmd_port = lcd01_base;
mfd->data_port =
(void *)((uint32) mfd->cmd_port + EBI2_SECD_LCD_RS_PIN);
mfd->data_port_phys =
(void *)(LCD_SECD_BASE_PHYS + EBI2_SECD_LCD_RS_PIN);
}
/*
* set driver data
*/
platform_set_drvdata(mdp_dev, mfd);
/*
* register in mdp driver
*/
rc = platform_device_add(mdp_dev);
if (rc) {
goto ebi2_lcd_probe_err;
}
pdev_list[pdev_list_cnt++] = pdev;
return 0;
ebi2_lcd_probe_err:
platform_device_put(mdp_dev);
return rc;
}
static int ebi2_lcd_remove(struct platform_device *pdev)
{
struct msm_fb_data_type *mfd;
mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
if (!mfd)
return 0;
if (mfd->key != MFD_KEY)
return 0;
iounmap(mfd->cmd_port);
return 0;
}
static int ebi2_lcd_register_driver(void)
{
return platform_driver_register(&ebi2_lcd_driver);
}
static int __init ebi2_lcd_driver_init(void)
{
return ebi2_lcd_register_driver();
}
module_init(ebi2_lcd_driver_init);
此差异已折叠。
/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#include <linux/i2c.h>
#include <linux/delay.h>
#include "msm_fb.h"
#define DEVICE_NAME "sii9022"
#define SII9022_DEVICE_ID 0xB0
struct sii9022_i2c_addr_data{
u8 addr;
u8 data;
};
/* video mode data */
static u8 video_mode_data[] = {
0x00,
0xF9, 0x1C, 0x70, 0x17, 0x72, 0x06, 0xEE, 0x02,
};
static u8 avi_io_format[] = {
0x09,
0x00, 0x00,
};
/* power state */
static struct sii9022_i2c_addr_data regset0[] = {
{ 0x60, 0x04 },
{ 0x63, 0x00 },
{ 0x1E, 0x00 },
};
static u8 video_infoframe[] = {
0x0C,
0xF0, 0x00, 0x68, 0x00, 0x04, 0x00, 0x19, 0x00,
0xE9, 0x02, 0x04, 0x01, 0x04, 0x06,
};
/* configure audio */
static struct sii9022_i2c_addr_data regset1[] = {
{ 0x26, 0x90 },
{ 0x20, 0x90 },
{ 0x1F, 0x80 },
{ 0x26, 0x80 },
{ 0x24, 0x02 },
{ 0x25, 0x0B },
{ 0xBC, 0x02 },
{ 0xBD, 0x24 },
{ 0xBE, 0x02 },
};
/* enable audio */
static u8 misc_infoframe[] = {
0xBF,
0xC2, 0x84, 0x01, 0x0A, 0x6F, 0x02, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
/* set HDMI, active */
static struct sii9022_i2c_addr_data regset2[] = {
{ 0x1A, 0x01 },
{ 0x3D, 0x00 },
};
static int send_i2c_data(struct i2c_client *client,
struct sii9022_i2c_addr_data *regset,
int size)
{
int i;
int rc = 0;
for (i = 0; i < size; i++) {
rc = i2c_smbus_write_byte_data(
client,
regset[i].addr, regset[i].data);
if (rc)
break;
}
return rc;
}
static int hdmi_sii_enable(struct i2c_client *client)
{
int rc;
int retries = 10;
int count;
rc = i2c_smbus_write_byte_data(client, 0xC7, 0x00);
if (rc)
goto enable_exit;
do {
msleep(1);
rc = i2c_smbus_read_byte_data(client, 0x1B);
} while ((rc != SII9022_DEVICE_ID) && retries--);
if (rc != SII9022_DEVICE_ID)
return -ENODEV;
rc = i2c_smbus_write_byte_data(client, 0x1A, 0x11);
if (rc)
goto enable_exit;
count = ARRAY_SIZE(video_mode_data);
rc = i2c_master_send(client, video_mode_data, count);
if (rc != count) {
rc = -EIO;
goto enable_exit;
}
rc = i2c_smbus_write_byte_data(client, 0x08, 0x20);
if (rc)
goto enable_exit;
count = ARRAY_SIZE(avi_io_format);
rc = i2c_master_send(client, avi_io_format, count);
if (rc != count) {
rc = -EIO;
goto enable_exit;
}
rc = send_i2c_data(client, regset0, ARRAY_SIZE(regset0));
if (rc)
goto enable_exit;
count = ARRAY_SIZE(video_infoframe);
rc = i2c_master_send(client, video_infoframe, count);
if (rc != count) {
rc = -EIO;
goto enable_exit;
}
rc = send_i2c_data(client, regset1, ARRAY_SIZE(regset1));
if (rc)
goto enable_exit;
count = ARRAY_SIZE(misc_infoframe);
rc = i2c_master_send(client, misc_infoframe, count);
if (rc != count) {
rc = -EIO;
goto enable_exit;
}
rc = send_i2c_data(client, regset2, ARRAY_SIZE(regset2));
if (rc)
goto enable_exit;
return 0;
enable_exit:
printk(KERN_ERR "%s: exited rc=%d\n", __func__, rc);
return rc;
}
static const struct i2c_device_id hmdi_sii_id[] = {
{ DEVICE_NAME, 0 },
{ }
};
static int hdmi_sii_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int rc;
if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_BYTE | I2C_FUNC_I2C))
return -ENODEV;
rc = hdmi_sii_enable(client);
return rc;
}
static struct i2c_driver hdmi_sii_i2c_driver = {
.driver = {
.name = DEVICE_NAME,
.owner = THIS_MODULE,
},
.probe = hdmi_sii_probe,
.remove = __exit_p(hdmi_sii_remove),
.id_table = hmdi_sii_id,
};
static int __init hdmi_sii_init(void)
{
int ret;
struct msm_panel_info pinfo;
if (msm_fb_detect_client("hdmi_sii9022"))
return 0;
pinfo.xres = 1280;
pinfo.yres = 720;
pinfo.type = HDMI_PANEL;
pinfo.pdest = DISPLAY_1;
pinfo.wait_cycle = 0;
pinfo.bpp = 24;
pinfo.fb_num = 2;
pinfo.clk_rate = 74250000;
pinfo.lcdc.h_back_porch = 124;
pinfo.lcdc.h_front_porch = 110;
pinfo.lcdc.h_pulse_width = 136;
pinfo.lcdc.v_back_porch = 19;
pinfo.lcdc.v_front_porch = 5;
pinfo.lcdc.v_pulse_width = 6;
pinfo.lcdc.border_clr = 0;
pinfo.lcdc.underflow_clr = 0xff;
pinfo.lcdc.hsync_skew = 0;
ret = lcdc_device_register(&pinfo);
if (ret) {
printk(KERN_ERR "%s: failed to register device\n", __func__);
goto init_exit;
}
ret = i2c_add_driver(&hdmi_sii_i2c_driver);
if (ret)
printk(KERN_ERR "%s: failed to add i2c driver\n", __func__);
init_exit:
return ret;
}
static void __exit hdmi_sii_exit(void)
{
i2c_del_driver(&hdmi_sii_i2c_driver);
}
module_init(hdmi_sii_init);
module_exit(hdmi_sii_exit);
MODULE_LICENSE("GPL v2");
MODULE_VERSION("0.1");
MODULE_AUTHOR("Qualcomm Innovation Center, Inc.");
MODULE_DESCRIPTION("SiI9022 HDMI driver");
MODULE_ALIAS("platform:hdmi-sii9022");
/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/time.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/delay.h>
#include <mach/hardware.h>
#include <linux/io.h>
#include <asm/system.h>
#include <asm/mach-types.h>
#include <linux/semaphore.h>
#include <linux/uaccess.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
#include <linux/pm_qos_params.h>
#include "msm_fb.h"
static int lcdc_probe(struct platform_device *pdev);
static int lcdc_remove(struct platform_device *pdev);
static int lcdc_off(struct platform_device *pdev);
static int lcdc_on(struct platform_device *pdev);
static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST];
static int pdev_list_cnt;
static struct clk *mdp_lcdc_pclk_clk;
static struct clk *mdp_lcdc_pad_pclk_clk;
int mdp_lcdc_pclk_clk_rate;
int mdp_lcdc_pad_pclk_clk_rate;
static struct platform_driver lcdc_driver = {
.probe = lcdc_probe,
.remove = lcdc_remove,
.suspend = NULL,
.resume = NULL,
.shutdown = NULL,
.driver = {
.name = "lcdc",
},
};
static struct lcdc_platform_data *lcdc_pdata;
static int lcdc_off(struct platform_device *pdev)
{
int ret = 0;
ret = panel_next_off(pdev);
clk_disable(mdp_lcdc_pclk_clk);
clk_disable(mdp_lcdc_pad_pclk_clk);
if (lcdc_pdata && lcdc_pdata->lcdc_power_save)
lcdc_pdata->lcdc_power_save(0);
if (lcdc_pdata && lcdc_pdata->lcdc_gpio_config)
ret = lcdc_pdata->lcdc_gpio_config(0);
// pm_qos_update_requirement(PM_QOS_SYSTEM_BUS_FREQ , "lcdc",
// PM_QOS_DEFAULT_VALUE);
return ret;
}
static int lcdc_on(struct platform_device *pdev)
{
int ret = 0;
struct msm_fb_data_type *mfd;
unsigned long panel_pixclock_freq , pm_qos_freq;
mfd = platform_get_drvdata(pdev);
panel_pixclock_freq = mfd->fbi->var.pixclock;
if (panel_pixclock_freq > 58000000)
/* pm_qos_freq should be in Khz */
pm_qos_freq = panel_pixclock_freq / 1000 ;
else
pm_qos_freq = 58000;
// pm_qos_update_requirement(PM_QOS_SYSTEM_BUS_FREQ , "lcdc",
// pm_qos_freq);
mfd = platform_get_drvdata(pdev);
clk_enable(mdp_lcdc_pclk_clk);
clk_enable(mdp_lcdc_pad_pclk_clk);
if (lcdc_pdata && lcdc_pdata->lcdc_power_save)
lcdc_pdata->lcdc_power_save(1);
if (lcdc_pdata && lcdc_pdata->lcdc_gpio_config)
ret = lcdc_pdata->lcdc_gpio_config(1);
clk_set_rate(mdp_lcdc_pclk_clk, mfd->fbi->var.pixclock);
clk_set_rate(mdp_lcdc_pad_pclk_clk, mfd->fbi->var.pixclock);
mdp_lcdc_pclk_clk_rate = clk_get_rate(mdp_lcdc_pclk_clk);
mdp_lcdc_pad_pclk_clk_rate = clk_get_rate(mdp_lcdc_pad_pclk_clk);
ret = panel_next_on(pdev);
return ret;
}
static int lcdc_probe(struct platform_device *pdev)
{
struct msm_fb_data_type *mfd;
struct fb_info *fbi;
struct platform_device *mdp_dev = NULL;
struct msm_fb_panel_data *pdata = NULL;
int rc;
if (pdev->id == 0) {
lcdc_pdata = pdev->dev.platform_data;
return 0;
}
mfd = platform_get_drvdata(pdev);
if (!mfd)
return -ENODEV;
if (mfd->key != MFD_KEY)
return -EINVAL;
if (pdev_list_cnt >= MSM_FB_MAX_DEV_LIST)
return -ENOMEM;
mdp_dev = platform_device_alloc("mdp", pdev->id);
if (!mdp_dev)
return -ENOMEM;
/*
* link to the latest pdev
*/
mfd->pdev = mdp_dev;
mfd->dest = DISPLAY_LCDC;
/*
* alloc panel device data
*/
if (platform_device_add_data
(mdp_dev, pdev->dev.platform_data,
sizeof(struct msm_fb_panel_data))) {
printk(KERN_ERR "lcdc_probe: platform_device_add_data failed!\n");
platform_device_put(mdp_dev);
return -ENOMEM;
}
/*
* data chain
*/
pdata = (struct msm_fb_panel_data *)mdp_dev->dev.platform_data;
pdata->on = lcdc_on;
pdata->off = lcdc_off;
pdata->next = pdev;
/*
* get/set panel specific fb info
*/
mfd->panel_info = pdata->panel_info;
mfd->fb_imgType = MDP_RGB_565;
fbi = mfd->fbi;
fbi->var.pixclock = mfd->panel_info.clk_rate;
fbi->var.left_margin = mfd->panel_info.lcdc.h_back_porch;
fbi->var.right_margin = mfd->panel_info.lcdc.h_front_porch;
fbi->var.upper_margin = mfd->panel_info.lcdc.v_back_porch;
fbi->var.lower_margin = mfd->panel_info.lcdc.v_front_porch;
fbi->var.hsync_len = mfd->panel_info.lcdc.h_pulse_width;
fbi->var.vsync_len = mfd->panel_info.lcdc.v_pulse_width;
/*
* set driver data
*/
platform_set_drvdata(mdp_dev, mfd);
/*
* register in mdp driver
*/
rc = platform_device_add(mdp_dev);
if (rc)
goto lcdc_probe_err;
pdev_list[pdev_list_cnt++] = pdev;
return 0;
lcdc_probe_err:
platform_device_put(mdp_dev);
return rc;
}
static int lcdc_remove(struct platform_device *pdev)
{
// pm_qos_remove_requirement(PM_QOS_SYSTEM_BUS_FREQ , "lcdc");
return 0;
}
static int lcdc_register_driver(void)
{
return platform_driver_register(&lcdc_driver);
}
static int __init lcdc_driver_init(void)
{
mdp_lcdc_pclk_clk = clk_get(NULL, "mdp_lcdc_pclk_clk");
if (IS_ERR(mdp_lcdc_pclk_clk)) {
printk(KERN_ERR "error: can't get mdp_lcdc_pclk_clk!\n");
return PTR_ERR(mdp_lcdc_pclk_clk);
}
mdp_lcdc_pad_pclk_clk = clk_get(NULL, "mdp_lcdc_pad_pclk_clk");
if (IS_ERR(mdp_lcdc_pad_pclk_clk)) {
printk(KERN_ERR "error: can't get mdp_lcdc_pad_pclk_clk!\n");
return PTR_ERR(mdp_lcdc_pad_pclk_clk);
}
// pm_qos_add_requirement(PM_QOS_SYSTEM_BUS_FREQ , "lcdc",
// PM_QOS_DEFAULT_VALUE);
return lcdc_register_driver();
}
module_init(lcdc_driver_init);
/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#include "msm_fb.h"
static int __init lcdc_external_init(void)
{
int ret;
struct msm_panel_info pinfo;
if (msm_fb_detect_client("lcdc_external"))
return 0;
pinfo.xres = 1280;
pinfo.yres = 720;
pinfo.type = LCDC_PANEL;
pinfo.pdest = DISPLAY_1;
pinfo.wait_cycle = 0;
pinfo.bpp = 24;
pinfo.fb_num = 2;
pinfo.clk_rate = 74250000;
pinfo.lcdc.h_back_porch = 124;
pinfo.lcdc.h_front_porch = 110;
pinfo.lcdc.h_pulse_width = 136;
pinfo.lcdc.v_back_porch = 19;
pinfo.lcdc.v_front_porch = 5;
pinfo.lcdc.v_pulse_width = 6;
pinfo.lcdc.border_clr = 0; /* blk */
pinfo.lcdc.underflow_clr = 0xff; /* blue */
pinfo.lcdc.hsync_skew = 0;
ret = lcdc_device_register(&pinfo);
if (ret)
printk(KERN_ERR "%s: failed to register device!\n", __func__);
return ret;
}
module_init(lcdc_external_init);
/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#include <linux/delay.h>
#include <mach/gpio.h>
#include "msm_fb.h"
/* registers */
#define GORDON_REG_NOP 0x00
#define GORDON_REG_IMGCTL1 0x10
#define GORDON_REG_IMGCTL2 0x11
#define GORDON_REG_IMGSET1 0x12
#define GORDON_REG_IMGSET2 0x13
#define GORDON_REG_IVBP1 0x14
#define GORDON_REG_IHBP1 0x15
#define GORDON_REG_IVNUM1 0x16
#define GORDON_REG_IHNUM1 0x17
#define GORDON_REG_IVBP2 0x18
#define GORDON_REG_IHBP2 0x19
#define GORDON_REG_IVNUM2 0x1A
#define GORDON_REG_IHNUM2 0x1B
#define GORDON_REG_LCDIFCTL1 0x30
#define GORDON_REG_VALTRAN 0x31
#define GORDON_REG_AVCTL 0x33
#define GORDON_REG_LCDIFCTL2 0x34
#define GORDON_REG_LCDIFCTL3 0x35
#define GORDON_REG_LCDIFSET1 0x36
#define GORDON_REG_PCCTL 0x3C
#define GORDON_REG_TPARAM1 0x40
#define GORDON_REG_TLCDIF1 0x41
#define GORDON_REG_TSSPB_ST1 0x42
#define GORDON_REG_TSSPB_ED1 0x43
#define GORDON_REG_TSCK_ST1 0x44
#define GORDON_REG_TSCK_WD1 0x45
#define GORDON_REG_TGSPB_VST1 0x46
#define GORDON_REG_TGSPB_VED1 0x47
#define GORDON_REG_TGSPB_CH1 0x48
#define GORDON_REG_TGCK_ST1 0x49
#define GORDON_REG_TGCK_ED1 0x4A
#define GORDON_REG_TPCTL_ST1 0x4B
#define GORDON_REG_TPCTL_ED1 0x4C
#define GORDON_REG_TPCHG_ED1 0x4D
#define GORDON_REG_TCOM_CH1 0x4E
#define GORDON_REG_THBP1 0x4F
#define GORDON_REG_TPHCTL1 0x50
#define GORDON_REG_EVPH1 0x51
#define GORDON_REG_EVPL1 0x52
#define GORDON_REG_EVNH1 0x53
#define GORDON_REG_EVNL1 0x54
#define GORDON_REG_TBIAS1 0x55
#define GORDON_REG_TPARAM2 0x56
#define GORDON_REG_TLCDIF2 0x57
#define GORDON_REG_TSSPB_ST2 0x58
#define GORDON_REG_TSSPB_ED2 0x59
#define GORDON_REG_TSCK_ST2 0x5A
#define GORDON_REG_TSCK_WD2 0x5B
#define GORDON_REG_TGSPB_VST2 0x5C
#define GORDON_REG_TGSPB_VED2 0x5D
#define GORDON_REG_TGSPB_CH2 0x5E
#define GORDON_REG_TGCK_ST2 0x5F
#define GORDON_REG_TGCK_ED2 0x60
#define GORDON_REG_TPCTL_ST2 0x61
#define GORDON_REG_TPCTL_ED2 0x62
#define GORDON_REG_TPCHG_ED2 0x63
#define GORDON_REG_TCOM_CH2 0x64
#define GORDON_REG_THBP2 0x65
#define GORDON_REG_TPHCTL2 0x66
#define GORDON_REG_POWCTL 0x80
static int lcdc_gordon_panel_off(struct platform_device *pdev);
static int spi_cs;
static int spi_sclk;
static int spi_sdo;
static int spi_sdi;
static int spi_dac;
static unsigned char bit_shift[8] = { (1 << 7), /* MSB */
(1 << 6),
(1 << 5),
(1 << 4),
(1 << 3),
(1 << 2),
(1 << 1),
(1 << 0) /* LSB */
};
struct gordon_state_type{
boolean disp_initialized;
boolean display_on;
boolean disp_powered_up;
};
static struct gordon_state_type gordon_state = { 0 };
static struct msm_panel_common_pdata *lcdc_gordon_pdata;
static void serigo(uint16 reg, uint8 data)
{
unsigned int tx_val = ((0x00FF & reg) << 8) | data;
unsigned char i, val = 0;
/* Enable the Chip Select */
gpio_set_value(spi_cs, 1);
udelay(33);
/* Transmit it in two parts, Higher Byte first, then Lower Byte */
val = (unsigned char)((tx_val & 0xFF00) >> 8);
/* Clock should be Low before entering ! */
for (i = 0; i < 8; i++) {
/* #1: Drive the Data (High or Low) */
if (val & bit_shift[i])
gpio_set_value(spi_sdi, 1);
else
gpio_set_value(spi_sdi, 0);
/* #2: Drive the Clk High and then Low */
udelay(33);
gpio_set_value(spi_sclk, 1);
udelay(33);
gpio_set_value(spi_sclk, 0);
}
/* Idle state of SDO (MOSI) is Low */
gpio_set_value(spi_sdi, 0);
/* ..then Lower Byte */
val = (uint8) (tx_val & 0x00FF);
/* Before we enter here the Clock should be Low ! */
for (i = 0; i < 8; i++) {
/* #1: Drive the Data (High or Low) */
if (val & bit_shift[i])
gpio_set_value(spi_sdi, 1);
else
gpio_set_value(spi_sdi, 0);
/* #2: Drive the Clk High and then Low */
udelay(33);
gpio_set_value(spi_sclk, 1);
udelay(33);
gpio_set_value(spi_sclk, 0);
}
/* Idle state of SDO (MOSI) is Low */
gpio_set_value(spi_sdi, 0);
/* Now Disable the Chip Select */
udelay(33);
gpio_set_value(spi_cs, 0);
}
static void spi_init(void)
{
/* Setting the Default GPIO's */
spi_sclk = *(lcdc_gordon_pdata->gpio_num);
spi_cs = *(lcdc_gordon_pdata->gpio_num + 1);
spi_sdi = *(lcdc_gordon_pdata->gpio_num + 2);
spi_sdo = *(lcdc_gordon_pdata->gpio_num + 3);
/* Set the output so that we dont disturb the slave device */
gpio_set_value(spi_sclk, 0);
gpio_set_value(spi_sdi, 0);
/* Set the Chip Select De-asserted */
gpio_set_value(spi_cs, 0);
}
static void gordon_disp_powerup(void)
{
if (!gordon_state.disp_powered_up && !gordon_state.display_on) {
/* Reset the hardware first */
/* Include DAC power up implementation here */
gordon_state.disp_powered_up = TRUE;
}
}
static void gordon_init(void)
{
/* Image interface settings */
serigo(GORDON_REG_IMGCTL2, 0x00);
serigo(GORDON_REG_IMGSET1, 0x00);
/* Exchange the RGB signal for J510(Softbank mobile) */
serigo(GORDON_REG_IMGSET2, 0x12);
serigo(GORDON_REG_LCDIFSET1, 0x00);
/* Pre-charge settings */
serigo(GORDON_REG_PCCTL, 0x09);
serigo(GORDON_REG_LCDIFCTL2, 0x7B);
mdelay(1);
}
static void gordon_disp_on(void)
{
if (gordon_state.disp_powered_up && !gordon_state.display_on) {
gordon_init();
mdelay(20);
/* gordon_dispmode setting */
serigo(GORDON_REG_TPARAM1, 0x30);
serigo(GORDON_REG_TLCDIF1, 0x00);
serigo(GORDON_REG_TSSPB_ST1, 0x8B);
serigo(GORDON_REG_TSSPB_ED1, 0x93);
serigo(GORDON_REG_TSCK_ST1, 0x88);
serigo(GORDON_REG_TSCK_WD1, 0x00);
serigo(GORDON_REG_TGSPB_VST1, 0x01);
serigo(GORDON_REG_TGSPB_VED1, 0x02);
serigo(GORDON_REG_TGSPB_CH1, 0x5E);
serigo(GORDON_REG_TGCK_ST1, 0x80);
serigo(GORDON_REG_TGCK_ED1, 0x3C);
serigo(GORDON_REG_TPCTL_ST1, 0x50);
serigo(GORDON_REG_TPCTL_ED1, 0x74);
serigo(GORDON_REG_TPCHG_ED1, 0x78);
serigo(GORDON_REG_TCOM_CH1, 0x50);
serigo(GORDON_REG_THBP1, 0x84);
serigo(GORDON_REG_TPHCTL1, 0x00);
serigo(GORDON_REG_EVPH1, 0x70);
serigo(GORDON_REG_EVPL1, 0x64);
serigo(GORDON_REG_EVNH1, 0x56);
serigo(GORDON_REG_EVNL1, 0x48);
serigo(GORDON_REG_TBIAS1, 0x88);
/* QVGA settings */
serigo(GORDON_REG_TPARAM2, 0x28);
serigo(GORDON_REG_TLCDIF2, 0x14);
serigo(GORDON_REG_TSSPB_ST2, 0x49);
serigo(GORDON_REG_TSSPB_ED2, 0x4B);
serigo(GORDON_REG_TSCK_ST2, 0x4A);
serigo(GORDON_REG_TSCK_WD2, 0x02);
serigo(GORDON_REG_TGSPB_VST2, 0x02);
serigo(GORDON_REG_TGSPB_VED2, 0x03);
serigo(GORDON_REG_TGSPB_CH2, 0x2F);
serigo(GORDON_REG_TGCK_ST2, 0x40);
serigo(GORDON_REG_TGCK_ED2, 0x1E);
serigo(GORDON_REG_TPCTL_ST2, 0x2C);
serigo(GORDON_REG_TPCTL_ED2, 0x3A);
serigo(GORDON_REG_TPCHG_ED2, 0x3C);
serigo(GORDON_REG_TCOM_CH2, 0x28);
serigo(GORDON_REG_THBP2, 0x4D);
serigo(GORDON_REG_TPHCTL2, 0x1A);
/* VGA settings */
serigo(GORDON_REG_IVBP1, 0x02);
serigo(GORDON_REG_IHBP1, 0x90);
serigo(GORDON_REG_IVNUM1, 0xA0);
serigo(GORDON_REG_IHNUM1, 0x78);
/* QVGA settings */
serigo(GORDON_REG_IVBP2, 0x02);
serigo(GORDON_REG_IHBP2, 0x48);
serigo(GORDON_REG_IVNUM2, 0x50);
serigo(GORDON_REG_IHNUM2, 0x3C);
/* Gordon Charge pump settings and ON */
serigo(GORDON_REG_POWCTL, 0x03);
mdelay(15);
serigo(GORDON_REG_POWCTL, 0x07);
mdelay(15);
serigo(GORDON_REG_POWCTL, 0x0F);
mdelay(15);
serigo(GORDON_REG_AVCTL, 0x03);
mdelay(15);
serigo(GORDON_REG_POWCTL, 0x1F);
mdelay(15);
serigo(GORDON_REG_POWCTL, 0x5F);
mdelay(15);
serigo(GORDON_REG_POWCTL, 0x7F);
mdelay(15);
serigo(GORDON_REG_LCDIFCTL1, 0x02);
mdelay(15);
serigo(GORDON_REG_IMGCTL1, 0x00);
mdelay(15);
serigo(GORDON_REG_LCDIFCTL3, 0x00);
mdelay(15);
serigo(GORDON_REG_VALTRAN, 0x01);
mdelay(15);
serigo(GORDON_REG_LCDIFCTL1, 0x03);
mdelay(1);
gordon_state.display_on = TRUE;
}
}
static int lcdc_gordon_panel_on(struct platform_device *pdev)
{
if (!gordon_state.disp_initialized) {
/* Configure reset GPIO that drives DAC */
lcdc_gordon_pdata->panel_config_gpio(1);
spi_dac = *(lcdc_gordon_pdata->gpio_num + 4);
gpio_set_value(spi_dac, 0);
udelay(15);
gpio_set_value(spi_dac, 1);
spi_init(); /* LCD needs SPI */
gordon_disp_powerup();
gordon_disp_on();
gordon_state.disp_initialized = TRUE;
}
return 0;
}
static int lcdc_gordon_panel_off(struct platform_device *pdev)
{
if (gordon_state.disp_powered_up && gordon_state.display_on) {
serigo(GORDON_REG_LCDIFCTL2, 0x7B);
serigo(GORDON_REG_VALTRAN, 0x01);
serigo(GORDON_REG_LCDIFCTL1, 0x02);
serigo(GORDON_REG_LCDIFCTL3, 0x01);
mdelay(20);
serigo(GORDON_REG_VALTRAN, 0x01);
serigo(GORDON_REG_IMGCTL1, 0x01);
serigo(GORDON_REG_LCDIFCTL1, 0x00);
mdelay(20);
serigo(GORDON_REG_POWCTL, 0x1F);
mdelay(40);
serigo(GORDON_REG_POWCTL, 0x07);
mdelay(40);
serigo(GORDON_REG_POWCTL, 0x03);
mdelay(40);
serigo(GORDON_REG_POWCTL, 0x00);
mdelay(40);
lcdc_gordon_pdata->panel_config_gpio(0);
gordon_state.display_on = FALSE;
gordon_state.disp_initialized = FALSE;
}
return 0;
}
static void lcdc_gordon_set_backlight(struct msm_fb_data_type *mfd)
{
int bl_level = mfd->bl_level;
if (bl_level <= 1) {
/* keep back light OFF */
serigo(GORDON_REG_LCDIFCTL2, 0x0B);
udelay(15);
serigo(GORDON_REG_VALTRAN, 0x01);
} else {
/* keep back light ON */
serigo(GORDON_REG_LCDIFCTL2, 0x7B);
udelay(15);
serigo(GORDON_REG_VALTRAN, 0x01);
}
}
static int __init gordon_probe(struct platform_device *pdev)
{
if (pdev->id == 0) {
lcdc_gordon_pdata = pdev->dev.platform_data;
return 0;
}
msm_fb_add_device(pdev);
return 0;
}
static struct platform_driver this_driver = {
.probe = gordon_probe,
.driver = {
.name = "lcdc_gordon_vga",
},
};
static struct msm_fb_panel_data gordon_panel_data = {
.on = lcdc_gordon_panel_on,
.off = lcdc_gordon_panel_off,
.set_backlight = lcdc_gordon_set_backlight,
};
static struct platform_device this_device = {
.name = "lcdc_gordon_vga",
.id = 1,
.dev = {
.platform_data = &gordon_panel_data,
}
};
static int __init lcdc_gordon_panel_init(void)
{
int ret;
struct msm_panel_info *pinfo;
#ifdef CONFIG_FB_MSM_TRY_MDDI_CATCH_LCDC_PRISM
if (msm_fb_detect_client("lcdc_gordon_vga"))
return 0;
#endif
ret = platform_driver_register(&this_driver);
if (ret)
return ret;
pinfo = &gordon_panel_data.panel_info;
pinfo->xres = 480;
pinfo->yres = 640;
pinfo->type = LCDC_PANEL;
pinfo->pdest = DISPLAY_1;
pinfo->wait_cycle = 0;
pinfo->bpp = 24;
pinfo->fb_num = 2;
pinfo->clk_rate = 24500000;
pinfo->bl_max = 4;
pinfo->bl_min = 1;
pinfo->lcdc.h_back_porch = 84;
pinfo->lcdc.h_front_porch = 33;
pinfo->lcdc.h_pulse_width = 60;
pinfo->lcdc.v_back_porch = 0;
pinfo->lcdc.v_front_porch = 2;
pinfo->lcdc.v_pulse_width = 2;
pinfo->lcdc.border_clr = 0; /* blk */
pinfo->lcdc.underflow_clr = 0xff; /* blue */
pinfo->lcdc.hsync_skew = 0;
ret = platform_device_register(&this_device);
if (ret)
platform_driver_unregister(&this_driver);
return ret;
}
module_init(lcdc_gordon_panel_init);
/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#include "msm_fb.h"
static int lcdc_panel_on(struct platform_device *pdev)
{
return 0;
}
static int lcdc_panel_off(struct platform_device *pdev)
{
return 0;
}
static int __init lcdc_panel_probe(struct platform_device *pdev)
{
msm_fb_add_device(pdev);
return 0;
}
static struct platform_driver this_driver = {
.probe = lcdc_panel_probe,
.driver = {
.name = "lcdc_panel",
},
};
static struct msm_fb_panel_data lcdc_panel_data = {
.on = lcdc_panel_on,
.off = lcdc_panel_off,
};
static int lcdc_dev_id;
int lcdc_device_register(struct msm_panel_info *pinfo)
{
struct platform_device *pdev = NULL;
int ret;
pdev = platform_device_alloc("lcdc_panel", ++lcdc_dev_id);
if (!pdev)
return -ENOMEM;
lcdc_panel_data.panel_info = *pinfo;
ret = platform_device_add_data(pdev, &lcdc_panel_data,
sizeof(lcdc_panel_data));
if (ret) {
printk(KERN_ERR
"%s: platform_device_add_data failed!\n", __func__);
goto err_device_put;
}
ret = platform_device_add(pdev);
if (ret) {
printk(KERN_ERR
"%s: platform_device_register failed!\n", __func__);
goto err_device_put;
}
return 0;
err_device_put:
platform_device_put(pdev);
return ret;
}
static int __init lcdc_panel_init(void)
{
return platform_driver_register(&this_driver);
}
module_init(lcdc_panel_init);
/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#include "msm_fb.h"
#ifdef CONFIG_FB_MSM_TRY_MDDI_CATCH_LCDC_PRISM
#include "mddihosti.h"
#endif
static int __init lcdc_prism_init(void)
{
int ret;
struct msm_panel_info pinfo;
#ifdef CONFIG_FB_MSM_TRY_MDDI_CATCH_LCDC_PRISM
ret = msm_fb_detect_client("lcdc_prism_wvga");
if (ret == -ENODEV)
return 0;
if (ret && (mddi_get_client_id() != 0))
return 0;
#endif
pinfo.xres = 800;
pinfo.yres = 480;
pinfo.type = LCDC_PANEL;
pinfo.pdest = DISPLAY_1;
pinfo.wait_cycle = 0;
pinfo.bpp = 24;
pinfo.fb_num = 2;
pinfo.clk_rate = 38460000;
pinfo.lcdc.h_back_porch = 21;
pinfo.lcdc.h_front_porch = 81;
pinfo.lcdc.h_pulse_width = 60;
pinfo.lcdc.v_back_porch = 18;
pinfo.lcdc.v_front_porch = 27;
pinfo.lcdc.v_pulse_width = 2;
pinfo.lcdc.border_clr = 0; /* blk */
pinfo.lcdc.underflow_clr = 0xff; /* blue */
pinfo.lcdc.hsync_skew = 0;
ret = lcdc_device_register(&pinfo);
if (ret)
printk(KERN_ERR "%s: failed to register device!\n", __func__);
return ret;
}
module_init(lcdc_prism_init);
/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#include <linux/delay.h>
#ifdef CONFIG_ARCH_MSM7X30
#include <linux/mfd/pmic8058.h>
#endif
#include <mach/gpio.h>
#include "msm_fb.h"
static int lcdc_sharp_panel_off(struct platform_device *pdev);
static int spi_cs;
static int spi_sclk;
static int spi_mosi;
static int spi_miso;
static unsigned char bit_shift[8] = { (1 << 7), /* MSB */
(1 << 6),
(1 << 5),
(1 << 4),
(1 << 3),
(1 << 2),
(1 << 1),
(1 << 0) /* LSB */
};
struct sharp_state_type {
boolean disp_initialized;
boolean display_on;
boolean disp_powered_up;
};
struct sharp_spi_data {
u8 addr;
u8 data;
};
static struct sharp_spi_data init_sequence[] = {
{ 15, 0x01 },
{ 5, 0x01 },
{ 7, 0x10 },
{ 9, 0x1E },
{ 10, 0x04 },
{ 17, 0xFF },
{ 21, 0x8A },
{ 22, 0x00 },
{ 23, 0x82 },
{ 24, 0x24 },
{ 25, 0x22 },
{ 26, 0x6D },
{ 27, 0xEB },
{ 28, 0xB9 },
{ 29, 0x3A },
{ 49, 0x1A },
{ 50, 0x16 },
{ 51, 0x05 },
{ 55, 0x7F },
{ 56, 0x15 },
{ 57, 0x7B },
{ 60, 0x05 },
{ 61, 0x0C },
{ 62, 0x80 },
{ 63, 0x00 },
{ 92, 0x90 },
{ 97, 0x01 },
{ 98, 0xFF },
{ 113, 0x11 },
{ 114, 0x02 },
{ 115, 0x08 },
{ 123, 0xAB },
{ 124, 0x04 },
{ 6, 0x02 },
{ 133, 0x00 },
{ 134, 0xFE },
{ 135, 0x22 },
{ 136, 0x0B },
{ 137, 0xFF },
{ 138, 0x0F },
{ 139, 0x00 },
{ 140, 0xFE },
{ 141, 0x22 },
{ 142, 0x0B },
{ 143, 0xFF },
{ 144, 0x0F },
{ 145, 0x00 },
{ 146, 0xFE },
{ 147, 0x22 },
{ 148, 0x0B },
{ 149, 0xFF },
{ 150, 0x0F },
{ 202, 0x30 },
{ 30, 0x01 },
{ 4, 0x01 },
{ 31, 0x41 },
};
static struct sharp_state_type sharp_state = { 0 };
static struct msm_panel_common_pdata *lcdc_sharp_pdata;
static void sharp_spi_write_byte(u8 val)
{
int i;
/* Clock should be Low before entering */
for (i = 0; i < 8; i++) {
/* #1: Drive the Data (High or Low) */
if (val & bit_shift[i])
gpio_set_value(spi_mosi, 1);
else
gpio_set_value(spi_mosi, 0);
/* #2: Drive the Clk High and then Low */
gpio_set_value(spi_sclk, 1);
gpio_set_value(spi_sclk, 0);
}
}
static void serigo(u8 reg, u8 data)
{
/* Enable the Chip Select - low */
gpio_set_value(spi_cs, 0);
udelay(1);
/* Transmit register address first, then data */
sharp_spi_write_byte(reg);
/* Idle state of MOSI is Low */
gpio_set_value(spi_mosi, 0);
udelay(1);
sharp_spi_write_byte(data);
gpio_set_value(spi_mosi, 0);
gpio_set_value(spi_cs, 1);
}
static void sharp_spi_init(void)
{
spi_sclk = *(lcdc_sharp_pdata->gpio_num);
spi_cs = *(lcdc_sharp_pdata->gpio_num + 1);
spi_mosi = *(lcdc_sharp_pdata->gpio_num + 2);
spi_miso = *(lcdc_sharp_pdata->gpio_num + 3);
/* Set the output so that we don't disturb the slave device */
gpio_set_value(spi_sclk, 0);
gpio_set_value(spi_mosi, 0);
/* Set the Chip Select deasserted (active low) */
gpio_set_value(spi_cs, 1);
}
static void sharp_disp_powerup(void)
{
if (!sharp_state.disp_powered_up && !sharp_state.display_on)
sharp_state.disp_powered_up = TRUE;
}
static void sharp_disp_on(void)
{
int i;
if (sharp_state.disp_powered_up && !sharp_state.display_on) {
for (i = 0; i < ARRAY_SIZE(init_sequence); i++) {
serigo(init_sequence[i].addr,
init_sequence[i].data);
}
mdelay(10);
serigo(31, 0xC1);
mdelay(10);
serigo(31, 0xD9);
serigo(31, 0xDF);
sharp_state.display_on = TRUE;
}
}
static int lcdc_sharp_panel_on(struct platform_device *pdev)
{
if (!sharp_state.disp_initialized) {
lcdc_sharp_pdata->panel_config_gpio(1);
sharp_spi_init();
sharp_disp_powerup();
sharp_disp_on();
sharp_state.disp_initialized = TRUE;
}
return 0;
}
static int lcdc_sharp_panel_off(struct platform_device *pdev)
{
if (sharp_state.disp_powered_up && sharp_state.display_on) {
serigo(4, 0x00);
mdelay(40);
serigo(31, 0xC1);
mdelay(40);
serigo(31, 0x00);
mdelay(100);
sharp_state.display_on = FALSE;
sharp_state.disp_initialized = FALSE;
}
return 0;
}
static int __init sharp_probe(struct platform_device *pdev)
{
if (pdev->id == 0) {
lcdc_sharp_pdata = pdev->dev.platform_data;
return 0;
}
msm_fb_add_device(pdev);
return 0;
}
static struct platform_driver this_driver = {
.probe = sharp_probe,
.driver = {
.name = "lcdc_sharp_wvga",
},
};
static struct msm_fb_panel_data sharp_panel_data = {
.on = lcdc_sharp_panel_on,
.off = lcdc_sharp_panel_off,
};
static struct platform_device this_device = {
.name = "lcdc_sharp_wvga",
.id = 1,
.dev = {
.platform_data = &sharp_panel_data,
}
};
static int __init lcdc_sharp_panel_init(void)
{
int ret;
struct msm_panel_info *pinfo;
#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT
if (msm_fb_detect_client("lcdc_sharp_wvga_pt"))
return 0;
#endif
ret = platform_driver_register(&this_driver);
if (ret)
return ret;
pinfo = &sharp_panel_data.panel_info;
pinfo->xres = 480;
pinfo->yres = 800;
pinfo->type = LCDC_PANEL;
pinfo->pdest = DISPLAY_1;
pinfo->wait_cycle = 0;
pinfo->bpp = 18;
pinfo->fb_num = 2;
pinfo->clk_rate = 24500000;
pinfo->bl_max = 4;
pinfo->bl_min = 1;
pinfo->lcdc.h_back_porch = 20;
pinfo->lcdc.h_front_porch = 10;
pinfo->lcdc.h_pulse_width = 10;
pinfo->lcdc.v_back_porch = 2;
pinfo->lcdc.v_front_porch = 2;
pinfo->lcdc.v_pulse_width = 2;
pinfo->lcdc.border_clr = 0;
pinfo->lcdc.underflow_clr = 0xff;
pinfo->lcdc.hsync_skew = 0;
ret = platform_device_register(&this_device);
if (ret)
platform_driver_unregister(&this_driver);
return ret;
}
module_init(lcdc_sharp_panel_init);
/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#include <linux/i2c.h>
#include <linux/delay.h>
#include "msm_fb.h"
#define DEVICE_NAME "sii9022"
#define SII9022_DEVICE_ID 0xB0
struct sii9022_i2c_addr_data{
u8 addr;
u8 data;
};
/* video mode data */
static u8 video_mode_data[] = {
0x00,
0xF9, 0x1C, 0x70, 0x17, 0x72, 0x06, 0xEE, 0x02,
};
static u8 avi_io_format[] = {
0x09,
0x00, 0x00,
};
/* power state */
static struct sii9022_i2c_addr_data regset0[] = {
{ 0x60, 0x04 },
{ 0x63, 0x00 },
{ 0x1E, 0x00 },
};
static u8 video_infoframe[] = {
0x0C,
0xF0, 0x00, 0x68, 0x00, 0x04, 0x00, 0x19, 0x00,
0xE9, 0x02, 0x04, 0x01, 0x04, 0x06,
};
/* configure audio */
static struct sii9022_i2c_addr_data regset1[] = {
{ 0x26, 0x90 },
{ 0x20, 0x90 },
{ 0x1F, 0x80 },
{ 0x26, 0x80 },
{ 0x24, 0x02 },
{ 0x25, 0x0B },
{ 0xBC, 0x02 },
{ 0xBD, 0x24 },
{ 0xBE, 0x02 },
};
/* enable audio */
static u8 misc_infoframe[] = {
0xBF,
0xC2, 0x84, 0x01, 0x0A, 0x6F, 0x02, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
};
/* set HDMI, active */
static struct sii9022_i2c_addr_data regset2[] = {
{ 0x1A, 0x01 },
{ 0x3D, 0x00 },
};
static int send_i2c_data(struct i2c_client *client,
struct sii9022_i2c_addr_data *regset,
int size)
{
int i;
int rc = 0;
for (i = 0; i < size; i++) {
rc = i2c_smbus_write_byte_data(
client,
regset[i].addr, regset[i].data);
if (rc)
break;
}
return rc;
}
static int hdmi_sii_enable(struct i2c_client *client)
{
int rc;
int retries = 10;
int count;
rc = i2c_smbus_write_byte_data(client, 0xC7, 0x00);
if (rc)
goto enable_exit;
do {
msleep(1);
rc = i2c_smbus_read_byte_data(client, 0x1B);
} while ((rc != SII9022_DEVICE_ID) && retries--);
if (rc != SII9022_DEVICE_ID)
return -ENODEV;
rc = i2c_smbus_write_byte_data(client, 0x1A, 0x11);
if (rc)
goto enable_exit;
count = ARRAY_SIZE(video_mode_data);
rc = i2c_master_send(client, video_mode_data, count);
if (rc != count) {
rc = -EIO;
goto enable_exit;
}
rc = i2c_smbus_write_byte_data(client, 0x08, 0x20);
if (rc)
goto enable_exit;
count = ARRAY_SIZE(avi_io_format);
rc = i2c_master_send(client, avi_io_format, count);
if (rc != count) {
rc = -EIO;
goto enable_exit;
}
rc = send_i2c_data(client, regset0, ARRAY_SIZE(regset0));
if (rc)
goto enable_exit;
count = ARRAY_SIZE(video_infoframe);
rc = i2c_master_send(client, video_infoframe, count);
if (rc != count) {
rc = -EIO;
goto enable_exit;
}
rc = send_i2c_data(client, regset1, ARRAY_SIZE(regset1));
if (rc)
goto enable_exit;
count = ARRAY_SIZE(misc_infoframe);
rc = i2c_master_send(client, misc_infoframe, count);
if (rc != count) {
rc = -EIO;
goto enable_exit;
}
rc = send_i2c_data(client, regset2, ARRAY_SIZE(regset2));
if (rc)
goto enable_exit;
return 0;
enable_exit:
printk(KERN_ERR "%s: exited rc=%d\n", __func__, rc);
return rc;
}
static const struct i2c_device_id hmdi_sii_id[] = {
{ DEVICE_NAME, 0 },
{ }
};
static int hdmi_sii_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int rc;
if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_BYTE | I2C_FUNC_I2C))
return -ENODEV;
rc = hdmi_sii_enable(client);
return rc;
}
static struct i2c_driver hdmi_sii_i2c_driver = {
.driver = {
.name = DEVICE_NAME,
.owner = THIS_MODULE,
},
.probe = hdmi_sii_probe,
.remove = __exit_p(hdmi_sii_remove),
.id_table = hmdi_sii_id,
};
static int __init lcdc_st15_init(void)
{
int ret;
struct msm_panel_info pinfo;
if (msm_fb_detect_client("lcdc_st15"))
return 0;
pinfo.xres = 1366;
pinfo.yres = 768;
pinfo.type = LCDC_PANEL;
pinfo.pdest = DISPLAY_1;
pinfo.wait_cycle = 0;
pinfo.bpp = 24;
pinfo.fb_num = 2;
pinfo.clk_rate = 74250000;
pinfo.lcdc.h_back_porch = 120;
pinfo.lcdc.h_front_porch = 20;
pinfo.lcdc.h_pulse_width = 40;
pinfo.lcdc.v_back_porch = 25;
pinfo.lcdc.v_front_porch = 1;
pinfo.lcdc.v_pulse_width = 7;
pinfo.lcdc.border_clr = 0; /* blk */
pinfo.lcdc.underflow_clr = 0xff; /* blue */
pinfo.lcdc.hsync_skew = 0;
ret = lcdc_device_register(&pinfo);
if (ret) {
printk(KERN_ERR "%s: failed to register device!\n", __func__);
goto init_exit;
}
ret = i2c_add_driver(&hdmi_sii_i2c_driver);
if (ret)
printk(KERN_ERR "%s: failed to add i2c driver\n", __func__);
init_exit:
return ret;
}
module_init(lcdc_st15_init);
/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#include <linux/delay.h>
#include <linux/module.h>
#include <mach/gpio.h>
#include <mach/pmic.h>
#include "msm_fb.h"
#ifdef CONFIG_FB_MSM_TRY_MDDI_CATCH_LCDC_PRISM
#include "mddihosti.h"
#endif
static int spi_cs;
static int spi_sclk;
static int spi_mosi;
static int spi_miso;
struct toshiba_state_type{
boolean disp_initialized;
boolean display_on;
boolean disp_powered_up;
};
static struct toshiba_state_type toshiba_state = { 0 };
static struct msm_panel_common_pdata *lcdc_toshiba_pdata;
static void toshiba_spi_write_byte(char dc, uint8 data)
{
uint32 bit;
int bnum;
gpio_set_value(spi_sclk, 0); /* clk low */
/* dc: 0 for command, 1 for parameter */
gpio_set_value(spi_mosi, dc);
udelay(1); /* at least 20 ns */
gpio_set_value(spi_sclk, 1); /* clk high */
udelay(1); /* at least 20 ns */
bnum = 8; /* 8 data bits */
bit = 0x80;
while (bnum) {
gpio_set_value(spi_sclk, 0); /* clk low */
if (data & bit)
gpio_set_value(spi_mosi, 1);
else
gpio_set_value(spi_mosi, 0);
udelay(1);
gpio_set_value(spi_sclk, 1); /* clk high */
udelay(1);
bit >>= 1;
bnum--;
}
}
static void toshiba_spi_write(char cmd, uint32 data, int num)
{
char *bp;
gpio_set_value(spi_cs, 1); /* cs high */
/* command byte first */
toshiba_spi_write_byte(0, cmd);
/* followed by parameter bytes */
if (num) {
bp = (char *)&data;
bp += (num - 1);
while (num) {
toshiba_spi_write_byte(1, *bp);
num--;
bp--;
}
}
gpio_set_value(spi_cs, 0); /* cs low */
udelay(1);
}
void toshiba_spi_read_bytes(char cmd, uint32 *data, int num)
{
uint32 dbit, bits;
int bnum;
gpio_set_value(spi_cs, 1); /* cs high */
/* command byte first */
toshiba_spi_write_byte(0, cmd);
if (num > 1) {
/* extra dc bit */
gpio_set_value(spi_sclk, 0); /* clk low */
udelay(1);
dbit = gpio_get_value(spi_miso);/* dc bit */
udelay(1);
gpio_set_value(spi_sclk, 1); /* clk high */
}
/* followed by data bytes */
bnum = num * 8; /* number of bits */
bits = 0;
while (bnum) {
bits <<= 1;
gpio_set_value(spi_sclk, 0); /* clk low */
udelay(1);
dbit = gpio_get_value(spi_miso);
udelay(1);
gpio_set_value(spi_sclk, 1); /* clk high */
bits |= dbit;
bnum--;
}
*data = bits;
udelay(1);
gpio_set_value(spi_cs, 0); /* cs low */
udelay(1);
}
static void spi_pin_assign(void)
{
/* Setting the Default GPIO's */
spi_sclk = *(lcdc_toshiba_pdata->gpio_num);
spi_cs = *(lcdc_toshiba_pdata->gpio_num + 1);
spi_mosi = *(lcdc_toshiba_pdata->gpio_num + 2);
spi_miso = *(lcdc_toshiba_pdata->gpio_num + 3);
}
static void toshiba_disp_powerup(void)
{
if (!toshiba_state.disp_powered_up && !toshiba_state.display_on) {
/* Reset the hardware first */
/* Include DAC power up implementation here */
toshiba_state.disp_powered_up = TRUE;
}
}
static void toshiba_disp_on(void)
{
uint32 data;
gpio_set_value(spi_cs, 0); /* low */
gpio_set_value(spi_sclk, 1); /* high */
gpio_set_value(spi_mosi, 0);
gpio_set_value(spi_miso, 0);
if (toshiba_state.disp_powered_up && !toshiba_state.display_on) {
toshiba_spi_write(0, 0, 0);
mdelay(7);
toshiba_spi_write(0, 0, 0);
mdelay(7);
toshiba_spi_write(0, 0, 0);
mdelay(7);
toshiba_spi_write(0xba, 0x11, 1);
toshiba_spi_write(0x36, 0x00, 1);
mdelay(1);
toshiba_spi_write(0x3a, 0x60, 1);
toshiba_spi_write(0xb1, 0x5d, 1);
mdelay(1);
toshiba_spi_write(0xb2, 0x33, 1);
toshiba_spi_write(0xb3, 0x22, 1);
mdelay(1);
toshiba_spi_write(0xb4, 0x02, 1);
toshiba_spi_write(0xb5, 0x1e, 1); /* vcs -- adjust brightness */
mdelay(1);
toshiba_spi_write(0xb6, 0x27, 1);
toshiba_spi_write(0xb7, 0x03, 1);
mdelay(1);
toshiba_spi_write(0xb9, 0x24, 1);
toshiba_spi_write(0xbd, 0xa1, 1);
mdelay(1);
toshiba_spi_write(0xbb, 0x00, 1);
toshiba_spi_write(0xbf, 0x01, 1);
mdelay(1);
toshiba_spi_write(0xbe, 0x00, 1);
toshiba_spi_write(0xc0, 0x11, 1);
mdelay(1);
toshiba_spi_write(0xc1, 0x11, 1);
toshiba_spi_write(0xc2, 0x11, 1);
mdelay(1);
toshiba_spi_write(0xc3, 0x3232, 2);
mdelay(1);
toshiba_spi_write(0xc4, 0x3232, 2);
mdelay(1);
toshiba_spi_write(0xc5, 0x3232, 2);
mdelay(1);
toshiba_spi_write(0xc6, 0x3232, 2);
mdelay(1);
toshiba_spi_write(0xc7, 0x6445, 2);
mdelay(1);
toshiba_spi_write(0xc8, 0x44, 1);
toshiba_spi_write(0xc9, 0x52, 1);
mdelay(1);
toshiba_spi_write(0xca, 0x00, 1);
mdelay(1);
toshiba_spi_write(0xec, 0x02a4, 2); /* 0x02a4 */
mdelay(1);
toshiba_spi_write(0xcf, 0x01, 1);
mdelay(1);
toshiba_spi_write(0xd0, 0xc003, 2); /* c003 */
mdelay(1);
toshiba_spi_write(0xd1, 0x01, 1);
mdelay(1);
toshiba_spi_write(0xd2, 0x0028, 2);
mdelay(1);
toshiba_spi_write(0xd3, 0x0028, 2);
mdelay(1);
toshiba_spi_write(0xd4, 0x26a4, 2);
mdelay(1);
toshiba_spi_write(0xd5, 0x20, 1);
mdelay(1);
toshiba_spi_write(0xef, 0x3200, 2);
mdelay(32);
toshiba_spi_write(0xbc, 0x80, 1); /* wvga pass through */
toshiba_spi_write(0x3b, 0x00, 1);
mdelay(1);
toshiba_spi_write(0xb0, 0x16, 1);
mdelay(1);
toshiba_spi_write(0xb8, 0xfff5, 2);
mdelay(1);
toshiba_spi_write(0x11, 0, 0);
mdelay(5);
toshiba_spi_write(0x29, 0, 0);
mdelay(5);
toshiba_state.display_on = TRUE;
}
data = 0;
toshiba_spi_read_bytes(0x04, &data, 3);
printk(KERN_INFO "toshiba_disp_on: id=%x\n", data);
}
static int lcdc_toshiba_panel_on(struct platform_device *pdev)
{
if (!toshiba_state.disp_initialized) {
/* Configure reset GPIO that drives DAC */
if (lcdc_toshiba_pdata->panel_config_gpio)
lcdc_toshiba_pdata->panel_config_gpio(1);
toshiba_disp_powerup();
toshiba_disp_on();
toshiba_state.disp_initialized = TRUE;
}
return 0;
}
static int lcdc_toshiba_panel_off(struct platform_device *pdev)
{
if (toshiba_state.disp_powered_up && toshiba_state.display_on) {
/* Main panel power off (Deep standby in) */
toshiba_spi_write(0x28, 0, 0); /* display off */
mdelay(1);
toshiba_spi_write(0xb8, 0x8002, 2); /* output control */
mdelay(1);
toshiba_spi_write(0x10, 0x00, 1); /* sleep mode in */
mdelay(85); /* wait 85 msec */
toshiba_spi_write(0xb0, 0x00, 1); /* deep standby in */
mdelay(1);
if (lcdc_toshiba_pdata->panel_config_gpio)
lcdc_toshiba_pdata->panel_config_gpio(0);
toshiba_state.display_on = FALSE;
toshiba_state.disp_initialized = FALSE;
}
return 0;
}
static void lcdc_toshiba_set_backlight(struct msm_fb_data_type *mfd)
{
int bl_level;
int ret = -EPERM;
bl_level = mfd->bl_level;
ret = pmic_set_led_intensity(LED_LCD, bl_level);
if (ret)
printk(KERN_WARNING "%s: can't set lcd backlight!\n",
__func__);
}
static int __init toshiba_probe(struct platform_device *pdev)
{
if (pdev->id == 0) {
lcdc_toshiba_pdata = pdev->dev.platform_data;
spi_pin_assign();
return 0;
}
msm_fb_add_device(pdev);
return 0;
}
static struct platform_driver this_driver = {
.probe = toshiba_probe,
.driver = {
.name = "lcdc_toshiba_wvga",
},
};
static struct msm_fb_panel_data toshiba_panel_data = {
.on = lcdc_toshiba_panel_on,
.off = lcdc_toshiba_panel_off,
.set_backlight = lcdc_toshiba_set_backlight,
};
static struct platform_device this_device = {
.name = "lcdc_toshiba_wvga",
.id = 1,
.dev = {
.platform_data = &toshiba_panel_data,
}
};
static int __init lcdc_toshiba_panel_init(void)
{
int ret;
struct msm_panel_info *pinfo;
#ifdef CONFIG_FB_MSM_TRY_MDDI_CATCH_LCDC_PRISM
if (mddi_get_client_id() != 0)
return 0;
ret = msm_fb_detect_client("lcdc_toshiba_wvga_pt");
if (ret)
return 0;
#endif
ret = platform_driver_register(&this_driver);
if (ret)
return ret;
pinfo = &toshiba_panel_data.panel_info;
pinfo->xres = 480;
pinfo->yres = 800;
pinfo->type = LCDC_PANEL;
pinfo->pdest = DISPLAY_1;
pinfo->wait_cycle = 0;
pinfo->bpp = 18;
pinfo->fb_num = 2;
/* 30Mhz mdp_lcdc_pclk and mdp_lcdc_pad_pcl */
pinfo->clk_rate = 27648000;
pinfo->bl_max = 15;
pinfo->bl_min = 1;
pinfo->lcdc.h_back_porch = 184; /* hsw = 8 + hbp=184 */
pinfo->lcdc.h_front_porch = 4;
pinfo->lcdc.h_pulse_width = 8;
pinfo->lcdc.v_back_porch = 2; /* vsw=1 + vbp = 2 */
pinfo->lcdc.v_front_porch = 3;
pinfo->lcdc.v_pulse_width = 1;
pinfo->lcdc.border_clr = 0; /* blk */
pinfo->lcdc.underflow_clr = 0xff; /* blue */
pinfo->lcdc.hsync_skew = 0;
ret = platform_device_register(&this_device);
if (ret)
platform_driver_unregister(&this_driver);
return ret;
}
device_initcall(lcdc_toshiba_panel_init);
/* drivers/video/msm/logo.c
*
* Show Logo in RLE 565 format
*
* Copyright (C) 2008 Google Incorporated
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#include <linux/module.h>
#include <linux/types.h>
#include <linux/fb.h>
#include <linux/vt_kern.h>
#include <linux/unistd.h>
#include <linux/syscalls.h>
#include <linux/irq.h>
#include <asm/system.h>
#define fb_width(fb) ((fb)->var.xres)
#define fb_height(fb) ((fb)->var.yres)
#define fb_size(fb) ((fb)->var.xres * (fb)->var.yres * 2)
static void memset16(void *_ptr, unsigned short val, unsigned count)
{
unsigned short *ptr = _ptr;
count >>= 1;
while (count--)
*ptr++ = val;
}
/* 565RLE image format: [count(2 bytes), rle(2 bytes)] */
int load_565rle_image(char *filename)
{
struct fb_info *info;
int fd, err = 0;
unsigned count, max;
unsigned short *data, *bits, *ptr;
info = registered_fb[0];
if (!info) {
printk(KERN_WARNING "%s: Can not access framebuffer\n",
__func__);
return -ENODEV;
}
fd = sys_open(filename, O_RDONLY, 0);
if (fd < 0) {
printk(KERN_WARNING "%s: Can not open %s\n",
__func__, filename);
return -ENOENT;
}
count = (unsigned)sys_lseek(fd, (off_t)0, 2);
if (count == 0) {
sys_close(fd);
err = -EIO;
goto err_logo_close_file;
}
sys_lseek(fd, (off_t)0, 0);
data = kmalloc(count, GFP_KERNEL);
if (!data) {
printk(KERN_WARNING "%s: Can not alloc data\n", __func__);
err = -ENOMEM;
goto err_logo_close_file;
}
if ((unsigned)sys_read(fd, (char *)data, count) != count) {
err = -EIO;
goto err_logo_free_data;
}
max = fb_width(info) * fb_height(info);
ptr = data;
bits = (unsigned short *)(info->screen_base);
while (count > 3) {
unsigned n = ptr[0];
if (n > max)
break;
memset16(bits, ptr[1], n << 1);
bits += n;
max -= n;
ptr += 2;
count -= 4;
}
err_logo_free_data:
kfree(data);
err_logo_close_file:
sys_close(fd);
return err;
}
EXPORT_SYMBOL(load_565rle_image);
/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/time.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/spinlock.h>
#include <linux/delay.h>
#include <mach/hardware.h>
#include <asm/io.h>
#include <asm/system.h>
#include <asm/mach-types.h>
#include <linux/semaphore.h>
#include <linux/uaccess.h>
#include <linux/clk.h>
#include <linux/platform_device.h>
#include "msm_fb.h"
#include "mddihosti.h"
#include "mddihost.h"
#include <mach/gpio.h>
#include <mach/clk.h>
static int mddi_probe(struct platform_device *pdev);
static int mddi_remove(struct platform_device *pdev);
static int mddi_off(struct platform_device *pdev);
static int mddi_on(struct platform_device *pdev);
static int mddi_suspend(struct platform_device *pdev, pm_message_t state);
static int mddi_resume(struct platform_device *pdev);
#ifdef CONFIG_HAS_EARLYSUSPEND
static void mddi_early_suspend(struct early_suspend *h);
static void mddi_early_resume(struct early_suspend *h);
#endif
static struct platform_device *pdev_list[MSM_FB_MAX_DEV_LIST];
static int pdev_list_cnt;
static struct clk *mddi_clk;
static struct clk *mddi_pclk;
static struct mddi_platform_data *mddi_pdata;
static struct platform_driver mddi_driver = {
.probe = mddi_probe,
.remove = mddi_remove,
#ifndef CONFIG_HAS_EARLYSUSPEND
#ifdef CONFIG_PM
.suspend = mddi_suspend,
.resume = mddi_resume,
#endif
#endif
.suspend_late = NULL,
.resume_early = NULL,
.shutdown = NULL,
.driver = {
.name = "mddi",
},
};
extern int int_mddi_pri_flag;
static int mddi_off(struct platform_device *pdev)
{
int ret = 0;
ret = panel_next_off(pdev);
if (mddi_pdata && mddi_pdata->mddi_power_save)
mddi_pdata->mddi_power_save(0);
return ret;
}
static int mddi_on(struct platform_device *pdev)
{
int ret = 0;
u32 clk_rate;
struct msm_fb_data_type *mfd;
mfd = platform_get_drvdata(pdev);
if (mddi_pdata && mddi_pdata->mddi_power_save)
mddi_pdata->mddi_power_save(1);
clk_rate = mfd->fbi->var.pixclock;
clk_rate = min(clk_rate, mfd->panel_info.clk_max);
if (mddi_pdata &&
mddi_pdata->mddi_sel_clk &&
mddi_pdata->mddi_sel_clk(&clk_rate))
printk(KERN_ERR
"%s: can't select mddi io clk targate rate = %d\n",
__func__, clk_rate);
if (clk_set_min_rate(mddi_clk, clk_rate) < 0)
printk(KERN_ERR "%s: clk_set_min_rate failed\n",
__func__);
ret = panel_next_on(pdev);
return ret;
}
static int mddi_resource_initialized;
static int mddi_probe(struct platform_device *pdev)
{
struct msm_fb_data_type *mfd;
struct platform_device *mdp_dev = NULL;
struct msm_fb_panel_data *pdata = NULL;
int rc;
resource_size_t size ;
u32 clk_rate;
if ((pdev->id == 0) && (pdev->num_resources >= 0)) {
mddi_pdata = pdev->dev.platform_data;
size = resource_size(&pdev->resource[0]);
msm_pmdh_base = ioremap(pdev->resource[0].start, size);
MSM_FB_INFO("primary mddi base phy_addr = 0x%x virt = 0x%x\n",
pdev->resource[0].start, (int) msm_pmdh_base);
if (unlikely(!msm_pmdh_base))
return -ENOMEM;
if (mddi_pdata && mddi_pdata->mddi_power_save)
mddi_pdata->mddi_power_save(1);
mddi_resource_initialized = 1;
return 0;
}
if (!mddi_resource_initialized)
return -EPERM;
mfd = platform_get_drvdata(pdev);
if (!mfd)
return -ENODEV;
if (mfd->key != MFD_KEY)
return -EINVAL;
if (pdev_list_cnt >= MSM_FB_MAX_DEV_LIST)
return -ENOMEM;
mdp_dev = platform_device_alloc("mdp", pdev->id);
if (!mdp_dev)
return -ENOMEM;
/*
* link to the latest pdev
*/
mfd->pdev = mdp_dev;
mfd->dest = DISPLAY_LCD;
/*
* alloc panel device data
*/
if (platform_device_add_data
(mdp_dev, pdev->dev.platform_data,
sizeof(struct msm_fb_panel_data))) {
printk(KERN_ERR "mddi_probe: platform_device_add_data failed!\n");
platform_device_put(mdp_dev);
return -ENOMEM;
}
/*
* data chain
*/
pdata = mdp_dev->dev.platform_data;
pdata->on = mddi_on;
pdata->off = mddi_off;
pdata->next = pdev;
/*
* get/set panel specific fb info
*/
mfd->panel_info = pdata->panel_info;
mfd->fb_imgType = MDP_RGB_565;
clk_rate = mfd->panel_info.clk_max;
if (mddi_pdata &&
mddi_pdata->mddi_sel_clk &&
mddi_pdata->mddi_sel_clk(&clk_rate))
printk(KERN_ERR
"%s: can't select mddi io clk targate rate = %d\n",
__func__, clk_rate);
if (clk_set_max_rate(mddi_clk, clk_rate) < 0)
printk(KERN_ERR "%s: clk_set_max_rate failed\n", __func__);
mfd->panel_info.clk_rate = mfd->panel_info.clk_min;
/*
* set driver data
*/
platform_set_drvdata(mdp_dev, mfd);
/*
* register in mdp driver
*/
rc = platform_device_add(mdp_dev);
if (rc)
goto mddi_probe_err;
pdev_list[pdev_list_cnt++] = pdev;
#ifdef CONFIG_HAS_EARLYSUSPEND
mfd->mddi_early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB;
mfd->mddi_early_suspend.suspend = mddi_early_suspend;
mfd->mddi_early_suspend.resume = mddi_early_resume;
register_early_suspend(&mfd->mddi_early_suspend);
#endif
return 0;
mddi_probe_err:
platform_device_put(mdp_dev);
return rc;
}
static int mddi_pad_ctrl;
static int mddi_power_locked;
static int mddi_is_in_suspend;
void mddi_disable(int lock)
{
mddi_host_type host_idx = MDDI_HOST_PRIM;
if (mddi_power_locked)
return;
if (lock)
mddi_power_locked = 1;
if (mddi_host_timer.function)
del_timer_sync(&mddi_host_timer);
mddi_pad_ctrl = mddi_host_reg_in(PAD_CTL);
mddi_host_reg_out(PAD_CTL, 0x0);
if (clk_set_min_rate(mddi_clk, 0) < 0)
printk(KERN_ERR "%s: clk_set_min_rate failed\n", __func__);
clk_disable(mddi_clk);
if (mddi_pclk)
clk_disable(mddi_pclk);
disable_irq(INT_MDDI_PRI);
if (mddi_pdata && mddi_pdata->mddi_power_save)
mddi_pdata->mddi_power_save(0);
}
static int mddi_suspend(struct platform_device *pdev, pm_message_t state)
{
if (mddi_is_in_suspend)
return 0;
mddi_is_in_suspend = 1;
mddi_disable(0);
return 0;
}
static int mddi_resume(struct platform_device *pdev)
{
mddi_host_type host_idx = MDDI_HOST_PRIM;
if (!mddi_is_in_suspend)
return 0;
mddi_is_in_suspend = 0;
if (mddi_power_locked)
return 0;
enable_irq(INT_MDDI_PRI);
clk_enable(mddi_clk);
if (mddi_pclk)
clk_enable(mddi_pclk);
mddi_host_reg_out(PAD_CTL, mddi_pad_ctrl);
if (mddi_host_timer.function)
mddi_host_timer_service(0);
return 0;
}
#ifdef CONFIG_HAS_EARLYSUSPEND
static void mddi_early_suspend(struct early_suspend *h)
{
pm_message_t state;
struct msm_fb_data_type *mfd = container_of(h, struct msm_fb_data_type,
mddi_early_suspend);
state.event = PM_EVENT_SUSPEND;
mddi_suspend(mfd->pdev, state);
}
static void mddi_early_resume(struct early_suspend *h)
{
struct msm_fb_data_type *mfd = container_of(h, struct msm_fb_data_type,
mddi_early_suspend);
mddi_resume(mfd->pdev);
}
#endif
static int mddi_remove(struct platform_device *pdev)
{
if (mddi_host_timer.function)
del_timer_sync(&mddi_host_timer);
iounmap(msm_pmdh_base);
return 0;
}
static int mddi_register_driver(void)
{
return platform_driver_register(&mddi_driver);
}
static int __init mddi_driver_init(void)
{
int ret;
mddi_clk = clk_get(NULL, "mddi_clk");
if (IS_ERR(mddi_clk)) {
printk(KERN_ERR "can't find mddi_clk \n");
return PTR_ERR(mddi_clk);
}
clk_enable(mddi_clk);
mddi_pclk = clk_get(NULL, "mddi_pclk");
if (IS_ERR(mddi_pclk))
mddi_pclk = NULL;
else
clk_enable(mddi_pclk);
ret = mddi_register_driver();
if (ret) {
clk_disable(mddi_clk);
clk_put(mddi_clk);
if (mddi_pclk) {
clk_disable(mddi_pclk);
clk_put(mddi_pclk);
}
printk(KERN_ERR "mddi_register_driver() failed!\n");
return ret;
}
mddi_init();
return ret;
}
module_init(mddi_driver_init);
此差异已折叠。
/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#include "msm_fb.h"
#include "mddihost.h"
#include "mddihosti.h"
static int mddi_ext_lcd_on(struct platform_device *pdev);
static int mddi_ext_lcd_off(struct platform_device *pdev);
static int mddi_ext_lcd_on(struct platform_device *pdev)
{
return 0;
}
static int mddi_ext_lcd_off(struct platform_device *pdev)
{
return 0;
}
static int __init mddi_ext_lcd_probe(struct platform_device *pdev)
{
msm_fb_add_device(pdev);
return 0;
}
static struct platform_driver this_driver = {
.probe = mddi_ext_lcd_probe,
.driver = {
.name = "extmddi_svga",
},
};
static struct msm_fb_panel_data mddi_ext_lcd_panel_data = {
.panel_info.xres = 800,
.panel_info.yres = 600,
.panel_info.type = EXT_MDDI_PANEL,
.panel_info.pdest = DISPLAY_1,
.panel_info.wait_cycle = 0,
.panel_info.bpp = 18,
.panel_info.fb_num = 2,
.panel_info.clk_rate = 122880000,
.panel_info.clk_min = 120000000,
.panel_info.clk_max = 125000000,
.on = mddi_ext_lcd_on,
.off = mddi_ext_lcd_off,
};
static struct platform_device this_device = {
.name = "extmddi_svga",
.id = 0,
.dev = {
.platform_data = &mddi_ext_lcd_panel_data,
}
};
static int __init mddi_ext_lcd_init(void)
{
int ret;
struct msm_panel_info *pinfo;
ret = platform_driver_register(&this_driver);
if (!ret) {
pinfo = &mddi_ext_lcd_panel_data.panel_info;
pinfo->lcd.vsync_enable = FALSE;
pinfo->mddi.vdopkt = MDDI_DEFAULT_PRIM_PIX_ATTR;
ret = platform_device_register(&this_device);
if (ret)
platform_driver_unregister(&this_driver);
}
return ret;
}
module_init(mddi_ext_lcd_init);
/* Copyright (c) 2008-2009, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#include "msm_fb.h"
#include "mddihost.h"
#include "mddihosti.h"
static int prism_lcd_on(struct platform_device *pdev);
static int prism_lcd_off(struct platform_device *pdev);
static int prism_lcd_on(struct platform_device *pdev)
{
/* Set the MDP pixel data attributes for Primary Display */
mddi_host_write_pix_attr_reg(0x00C3);
return 0;
}
static int prism_lcd_off(struct platform_device *pdev)
{
return 0;
}
static int __init prism_probe(struct platform_device *pdev)
{
msm_fb_add_device(pdev);
return 0;
}
static struct platform_driver this_driver = {
.probe = prism_probe,
.driver = {
.name = "mddi_prism_wvga",
},
};
static struct msm_fb_panel_data prism_panel_data = {
.on = prism_lcd_on,
.off = prism_lcd_off,
};
static struct platform_device this_device = {
.name = "mddi_prism_wvga",
.id = 0,
.dev = {
.platform_data = &prism_panel_data,
}
};
static int __init prism_init(void)
{
int ret;
struct msm_panel_info *pinfo;
#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT
u32 id;
ret = msm_fb_detect_client("mddi_prism_wvga");
if (ret == -ENODEV)
return 0;
if (ret) {
id = mddi_get_client_id();
if (((id >> 16) != 0x4474) || ((id & 0xffff) == 0x8960))
return 0;
}
#endif
ret = platform_driver_register(&this_driver);
if (!ret) {
pinfo = &prism_panel_data.panel_info;
pinfo->xres = 800;
pinfo->yres = 480;
pinfo->type = MDDI_PANEL;
pinfo->pdest = DISPLAY_1;
pinfo->mddi.vdopkt = MDDI_DEFAULT_PRIM_PIX_ATTR;
pinfo->wait_cycle = 0;
pinfo->bpp = 18;
pinfo->fb_num = 2;
pinfo->clk_rate = 153600000;
pinfo->clk_min = 150000000;
pinfo->clk_max = 160000000;
pinfo->lcd.vsync_enable = TRUE;
pinfo->lcd.refx100 = 6050;
pinfo->lcd.v_back_porch = 23;
pinfo->lcd.v_front_porch = 20;
pinfo->lcd.v_pulse_width = 105;
pinfo->lcd.hw_vsync_mode = TRUE;
pinfo->lcd.vsync_notifier_period = 0;
ret = platform_device_register(&this_device);
if (ret)
platform_driver_unregister(&this_driver);
}
return ret;
}
module_init(prism_init);
此差异已折叠。
此差异已折叠。
/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef MDDI_TOSHIBA_H
#define MDDI_TOSHIBA_H
#define TOSHIBA_VGA_PRIM 1
#define TOSHIBA_VGA_SECD 2
#define LCD_TOSHIBA_2P4_VGA 0
#define LCD_TOSHIBA_2P4_WVGA 1
#define LCD_TOSHIBA_2P4_WVGA_PT 2
#define LCD_SHARP_2P4_VGA 3
#define GPIO_BLOCK_BASE 0x150000
#define SYSTEM_BLOCK2_BASE 0x170000
#define GPIODIR (GPIO_BLOCK_BASE|0x04)
#define GPIOSEL (SYSTEM_BLOCK2_BASE|0x00)
#define GPIOPC (GPIO_BLOCK_BASE|0x28)
#define GPIODATA (GPIO_BLOCK_BASE|0x00)
#define write_client_reg(__X, __Y, __Z) {\
mddi_queue_register_write(__X, __Y, TRUE, 0);\
}
#endif /* MDDI_TOSHIBA_H */
此差异已折叠。
/* Copyright (c) 2009, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
#include "msm_fb.h"
#include "mddihost.h"
#include "mddihosti.h"
#include "mddi_toshiba.h"
static int __init mddi_toshiba_wvga_pt_init(void)
{
int ret;
struct msm_panel_info pinfo;
#ifdef CONFIG_FB_MSM_MDDI_AUTO_DETECT
uint id;
ret = msm_fb_detect_client("mddi_toshiba_wvga_pt");
if (ret == -ENODEV)
return 0;
if (ret) {
id = mddi_get_client_id();
if (id != 0xd2638722)
return 0;
}
#endif
pinfo.xres = 480;
pinfo.yres = 800;
pinfo.type = MDDI_PANEL;
pinfo.pdest = DISPLAY_1;
pinfo.mddi.vdopkt = MDDI_DEFAULT_PRIM_PIX_ATTR;
pinfo.wait_cycle = 0;
pinfo.bpp = 18;
pinfo.lcd.vsync_enable = FALSE;
pinfo.bl_max = 15;
pinfo.bl_min = 1;
pinfo.clk_rate = 192000000;
pinfo.clk_min = 190000000;
pinfo.clk_max = 200000000;
pinfo.fb_num = 2;
ret = mddi_toshiba_device_register(&pinfo, TOSHIBA_VGA_PRIM,
LCD_TOSHIBA_2P4_WVGA_PT);
if (ret)
printk(KERN_ERR "%s: failed to register device!\n", __func__);
return ret;
}
module_init(mddi_toshiba_wvga_pt_init);
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册