android_kernel_google_msm/drivers/video/msm/mipi_lgit.c
jaekyung.oh 0e4c04388a mako: display: update lcd initial code.
Added OTP read protection code for prevent skew value read error.

Change-Id: Ic91031c41ccf6a43346eb0e20f82ad6144fccab2
Signed-off-by: Iliyan Malchev <malchev@google.com>
2013-03-04 12:45:16 -08:00

256 lines
5.9 KiB
C

/*
* Copyright (C) 2011-2012, LG Eletronics,Inc. All rights reserved.
* LGIT LCD device driver
*
* 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/gpio.h>
#include "msm_fb.h"
#include "mipi_dsi.h"
#include "mipi_lgit.h"
#include "mdp4.h"
static struct msm_panel_common_pdata *mipi_lgit_pdata;
static struct dsi_buf lgit_tx_buf;
static struct dsi_buf lgit_rx_buf;
static int skip_init;
#define DSV_ONBST 57
static int lgit_external_dsv_onoff(uint8_t on_off)
{
int ret =0;
static int init_done=0;
if (!init_done) {
ret = gpio_request(DSV_ONBST,"DSV_ONBST_en");
if (ret) {
pr_err("%s: failed to request DSV_ONBST gpio \n", __func__);
goto out;
}
ret = gpio_direction_output(DSV_ONBST, 1);
if (ret) {
pr_err("%s: failed to set DSV_ONBST direction\n", __func__);
goto err_gpio;
}
init_done = 1;
}
gpio_set_value(DSV_ONBST, on_off);
mdelay(20);
goto out;
err_gpio:
gpio_free(DSV_ONBST);
out:
return ret;
}
static int mipi_lgit_lcd_on(struct platform_device *pdev)
{
struct msm_fb_data_type *mfd;
int ret = 0;
pr_info("%s started\n", __func__);
mfd = platform_get_drvdata(pdev);
if (!mfd)
return -ENODEV;
if (mfd->key != MFD_KEY)
return -EINVAL;
MIPI_OUTP(MIPI_DSI_BASE + 0x38, 0x10000000);
ret = mipi_dsi_cmds_tx(&lgit_tx_buf,
mipi_lgit_pdata->power_on_set_1,
mipi_lgit_pdata->power_on_set_size_1);
MIPI_OUTP(MIPI_DSI_BASE + 0x38, 0x14000000);
if (ret < 0) {
pr_err("%s: failed to transmit power_on_set_1 cmds\n", __func__);
return ret;
}
if(!skip_init){
MIPI_OUTP(MIPI_DSI_BASE + 0x38, 0x10000000);
ret = mipi_dsi_cmds_tx(&lgit_tx_buf,
mipi_lgit_pdata->power_on_set_2,
mipi_lgit_pdata->power_on_set_size_2);
MIPI_OUTP(MIPI_DSI_BASE + 0x38, 0x14000000);
if (ret < 0) {
pr_err("%s: failed to transmit power_on_set_2 cmds\n", __func__);
return ret;
}
}
skip_init = false;
ret = lgit_external_dsv_onoff(1);
if (ret < 0) {
pr_err("%s: failed to turn on external dsv\n", __func__);
return ret;
}
MIPI_OUTP(MIPI_DSI_BASE + 0x38, 0x10000000);
ret = mipi_dsi_cmds_tx(&lgit_tx_buf,
mipi_lgit_pdata->power_on_set_3,
mipi_lgit_pdata->power_on_set_size_3);
MIPI_OUTP(MIPI_DSI_BASE + 0x38, 0x14000000);
if (ret < 0) {
pr_err("%s: failed to transmit power_on_set_3 cmds\n", __func__);
return ret;
}
pr_info("%s finished\n", __func__);
return 0;
}
static int mipi_lgit_lcd_off(struct platform_device *pdev)
{
struct msm_fb_data_type *mfd;
int ret = 0;
pr_info("%s started\n", __func__);
if (mipi_lgit_pdata->bl_pwm_disable)
mipi_lgit_pdata->bl_pwm_disable();
mfd = platform_get_drvdata(pdev);
if (!mfd)
return -ENODEV;
if (mfd->key != MFD_KEY)
return -EINVAL;
MIPI_OUTP(MIPI_DSI_BASE + 0x38, 0x10000000);
ret = mipi_dsi_cmds_tx(&lgit_tx_buf,
mipi_lgit_pdata->power_off_set_1,
mipi_lgit_pdata->power_off_set_size_1);
MIPI_OUTP(MIPI_DSI_BASE + 0x38, 0x14000000);
if (ret < 0) {
pr_err("%s: failed to transmit power_off_set_1 cmds\n", __func__);
return ret;
}
ret = lgit_external_dsv_onoff(0);
if (ret < 0) {
pr_err("%s: failed to turn off external dsv\n", __func__);
return ret;
}
MIPI_OUTP(MIPI_DSI_BASE + 0x38, 0x10000000);
ret = mipi_dsi_cmds_tx(&lgit_tx_buf,
mipi_lgit_pdata->power_off_set_2,
mipi_lgit_pdata->power_off_set_size_2);
MIPI_OUTP(MIPI_DSI_BASE + 0x38, 0x14000000);
if (ret < 0) {
pr_err("%s: failed to transmit power_off_set_2 cmds\n", __func__);
return ret;
}
pr_info("%s finished\n", __func__);
return 0;
}
static int mipi_lgit_backlight_on_status(void)
{
return (mipi_lgit_pdata->bl_on_status());
}
static void mipi_lgit_set_backlight_board(struct msm_fb_data_type *mfd)
{
int level;
level = (int)mfd->bl_level;
mipi_lgit_pdata->backlight_level(level, 0, 0);
}
static int mipi_lgit_lcd_probe(struct platform_device *pdev)
{
if (pdev->id == 0) {
mipi_lgit_pdata = pdev->dev.platform_data;
return 0;
}
pr_info("%s start\n", __func__);
skip_init = true;
msm_fb_add_device(pdev);
return 0;
}
static struct platform_driver this_driver = {
.probe = mipi_lgit_lcd_probe,
.driver = {
.name = "mipi_lgit",
},
};
static struct msm_fb_panel_data lgit_panel_data = {
.on = mipi_lgit_lcd_on,
.off = mipi_lgit_lcd_off,
.set_backlight = mipi_lgit_set_backlight_board,
.get_backlight_on_status = mipi_lgit_backlight_on_status,
};
static int ch_used[3];
int mipi_lgit_device_register(struct msm_panel_info *pinfo,
u32 channel, u32 panel)
{
struct platform_device *pdev = NULL;
int ret;
if ((channel >= 3) || ch_used[channel])
return -ENODEV;
ch_used[channel] = TRUE;
pdev = platform_device_alloc("mipi_lgit", (panel << 8)|channel);
if (!pdev)
return -ENOMEM;
lgit_panel_data.panel_info = *pinfo;
ret = platform_device_add_data(pdev, &lgit_panel_data,
sizeof(lgit_panel_data));
if (ret) {
pr_err("%s: platform_device_add_data failed!\n", __func__);
goto err_device_put;
}
ret = platform_device_add(pdev);
if (ret) {
pr_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 mipi_lgit_lcd_init(void)
{
mipi_dsi_buf_alloc(&lgit_tx_buf, DSI_BUF_SIZE);
mipi_dsi_buf_alloc(&lgit_rx_buf, DSI_BUF_SIZE);
return platform_driver_register(&this_driver);
}
module_init(mipi_lgit_lcd_init);