123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- /* Copyright (c) 2012, The Linux Foundation. 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.
- */
- #include <mach/gpio.h>
- #include "msm_fb.h"
- static struct lvds_panel_platform_data *frc_pdata;
- static struct platform_device *frc_fbpdev;
- static int gpio_update; /* 268 */
- static int gpio_reset; /* 269 */
- static int gpio_pwr; /* 270 */
- static int lvds_frc_panel_on(struct platform_device *pdev)
- {
- int ret;
- ret = gpio_request(gpio_pwr, "frc_pwr");
- if (ret) {
- pr_err("%s: gpio_pwr=%d, gpio_request failed\n",
- __func__, gpio_pwr);
- goto panel_on_exit;
- }
- ret = gpio_request(gpio_update, "frc_update");
- if (ret) {
- pr_err("%s: gpio_update=%d, gpio_request failed\n",
- __func__, gpio_update);
- goto panel_on_exit1;
- }
- ret = gpio_request(gpio_reset, "frc_reset");
- if (ret) {
- pr_err("%s: gpio_reset=%d, gpio_request failed\n",
- __func__, gpio_reset);
- goto panel_on_exit2;
- }
- gpio_direction_output(gpio_reset, 1);
- gpio_direction_output(gpio_pwr, 0);
- gpio_direction_output(gpio_update, 0);
- usleep(1000);
- gpio_direction_output(gpio_reset, 0);
- usleep(1000);
- gpio_direction_output(gpio_pwr, 1);
- usleep(1000);
- gpio_direction_output(gpio_update, 1);
- usleep(1000);
- gpio_direction_output(gpio_reset, 1);
- usleep(1000);
- gpio_free(gpio_reset);
- panel_on_exit2:
- gpio_free(gpio_update);
- panel_on_exit1:
- gpio_free(gpio_pwr);
- panel_on_exit:
- return ret;
- }
- static int lvds_frc_panel_off(struct platform_device *pdev)
- {
- int ret;
- ret = gpio_request(gpio_pwr, "frc_pwr");
- if (ret) {
- pr_err("%s: gpio_pwr=%d, gpio_request failed\n",
- __func__, gpio_pwr);
- goto panel_off_exit;
- }
- ret = gpio_request(gpio_update, "frc_update");
- if (ret) {
- pr_err("%s: gpio_update=%d, gpio_request failed\n",
- __func__, gpio_update);
- goto panel_off_exit1;
- }
- ret = gpio_request(gpio_reset, "frc_reset");
- if (ret) {
- pr_err("%s: gpio_reset=%d, gpio_request failed\n",
- __func__, gpio_reset);
- goto panel_off_exit2;
- }
- gpio_direction_output(gpio_reset, 0);
- usleep(1000);
- gpio_direction_output(gpio_update, 0);
- usleep(1000);
- gpio_direction_output(gpio_pwr, 0);
- usleep(1000);
- gpio_free(gpio_reset);
- panel_off_exit2:
- gpio_free(gpio_update);
- panel_off_exit1:
- gpio_free(gpio_pwr);
- panel_off_exit:
- return ret;
- }
- static int __devinit lvds_frc_probe(struct platform_device *pdev)
- {
- int rc = 0;
- if (pdev->id == 0) {
- frc_pdata = pdev->dev.platform_data;
- if (frc_pdata != NULL) {
- gpio_update = frc_pdata->gpio[0];
- gpio_reset = frc_pdata->gpio[1];
- gpio_pwr = frc_pdata->gpio[2];
- pr_info("%s: power=%d update=%d reset=%d\n",
- __func__, gpio_pwr, gpio_update, gpio_reset);
- }
- return 0;
- }
- frc_fbpdev = msm_fb_add_device(pdev);
- if (!frc_fbpdev) {
- dev_err(&pdev->dev, "failed to add msm_fb device\n");
- rc = -ENODEV;
- goto probe_exit;
- }
- probe_exit:
- return rc;
- }
- static struct platform_driver this_driver = {
- .probe = lvds_frc_probe,
- .driver = {
- .name = "lvds_frc_fhd",
- },
- };
- static struct msm_fb_panel_data lvds_frc_panel_data = {
- .on = lvds_frc_panel_on,
- .off = lvds_frc_panel_off,
- };
- static struct platform_device this_device = {
- .name = "lvds_frc_fhd",
- .id = 1,
- .dev = {
- .platform_data = &lvds_frc_panel_data,
- }
- };
- static int __init lvds_frc_fhd_init(void)
- {
- int ret;
- struct msm_panel_info *pinfo;
- if (msm_fb_detect_client("lvds_frc_fhd"))
- return 0;
- ret = platform_driver_register(&this_driver);
- if (ret)
- return ret;
- pinfo = &lvds_frc_panel_data.panel_info;
- pinfo->xres = 1920;
- pinfo->yres = 1080;
- MSM_FB_SINGLE_MODE_PANEL(pinfo);
- pinfo->type = LVDS_PANEL;
- pinfo->pdest = DISPLAY_1;
- pinfo->wait_cycle = 0;
- pinfo->bpp = 24;
- pinfo->fb_num = 2;
- pinfo->clk_rate = 74250000;
- pinfo->bl_max = 255;
- pinfo->bl_min = 1;
- /*
- * use hdmi 1080p60 setting, for dual channel mode,
- * horizontal length is half.
- */
- pinfo->lcdc.h_back_porch = 148/2;
- pinfo->lcdc.h_front_porch = 88/2;
- pinfo->lcdc.h_pulse_width = 44/2;
- pinfo->lcdc.v_back_porch = 36;
- pinfo->lcdc.v_front_porch = 4;
- pinfo->lcdc.v_pulse_width = 5;
- pinfo->lcdc.underflow_clr = 0xff;
- pinfo->lcdc.hsync_skew = 0;
- pinfo->lvds.channel_mode = LVDS_DUAL_CHANNEL_MODE;
- pinfo->lcdc.is_sync_active_high = TRUE;
- /* Set border color, padding only for reducing active display region */
- pinfo->lcdc.border_clr = 0x0;
- pinfo->lcdc.xres_pad = 0;
- pinfo->lcdc.yres_pad = 0;
- ret = platform_device_register(&this_device);
- if (ret)
- platform_driver_unregister(&this_driver);
- return ret;
- }
- module_init(lvds_frc_fhd_init);
|