mirror of
https://github.com/genesi/linux-legacy.git
synced 2026-09-23 07:05:27 +00:00
862 lines
24 KiB
C
862 lines
24 KiB
C
/*
|
|
* Copyright 2009 Pegatron, Inc. All Rights Reserved.
|
|
*/
|
|
|
|
/*
|
|
* The code contained herein is licensed under the GNU General Public
|
|
* License. You may obtain a copy of the GNU General Public License
|
|
* Version 2 or later at the following locations:
|
|
*
|
|
* http://www.opensource.org/licenses/gpl-license.html
|
|
* http://www.gnu.org/copyleft/gpl.html
|
|
*/
|
|
|
|
/*!
|
|
* @defgroup Framebuffer Framebuffer Driver for Efikasb Platform.
|
|
*/
|
|
|
|
/*!
|
|
* @file mxcfb_mtl017.c
|
|
*
|
|
* @brief MXC Frame buffer driver for Efikasb Platform
|
|
*
|
|
* @ingroup Framebuffer
|
|
*/
|
|
|
|
/*!
|
|
* Include files
|
|
*/
|
|
#define DEBUG
|
|
#include <linux/module.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/console.h>
|
|
#include <linux/delay.h>
|
|
#include <linux/errno.h>
|
|
#include <linux/fb.h>
|
|
#include <linux/init.h>
|
|
#include <linux/string.h>
|
|
#include <linux/platform_device.h>
|
|
#include <linux/regulator/consumer.h>
|
|
#include <linux/i2c.h>
|
|
#include <linux/mxcfb.h>
|
|
#include <linux/ipu.h>
|
|
#include <linux/spinlock.h>
|
|
#include <mach/hardware.h>
|
|
|
|
#define EDID_LENGTH 128
|
|
#define DEBUG_MTL017 1
|
|
|
|
typedef struct mtl017_dev_data_tag {
|
|
struct i2c_client *client;
|
|
u8 edid[EDID_LENGTH];
|
|
struct fb_videomode *mode;
|
|
u8 *regs;
|
|
int suspending;
|
|
int disp_on;
|
|
|
|
struct semaphore sem;
|
|
|
|
void (*reset)(void);
|
|
void (*lcd_power) (int);
|
|
void (*lvds_power) (int);
|
|
void (*lvds_enable) (int);
|
|
} mtl017_dev_data;
|
|
|
|
//vv static struct mtl017_dev_data *mtl017 = NULL;
|
|
static mtl017_dev_data * mtl017 = NULL; //vv
|
|
static void mtl017_conf(u8 *reg_tbl);
|
|
static void disp_power_on(void);
|
|
static void disp_power_off(void);
|
|
|
|
static void disp_on_work_handler(struct work_struct *work);
|
|
static void disp_off_work_handler(struct work_struct *work);
|
|
|
|
static void disp_on_work_handler(struct work_struct *work)
|
|
{
|
|
disp_power_on();
|
|
}
|
|
|
|
static void disp_off_work_handler(struct work_struct *work)
|
|
{
|
|
disp_power_off();
|
|
}
|
|
|
|
static DECLARE_WORK(disp_off_work, disp_off_work_handler);
|
|
static DECLARE_WORK(disp_on_work, disp_on_work_handler);
|
|
|
|
#ifdef DEBUG_MTL017
|
|
static void dump_edid(unsigned char *id)
|
|
{
|
|
int i;
|
|
|
|
printk("EDID Dump:\n");
|
|
for (i = 0; i < EDID_LENGTH; i+=32) {
|
|
int j;
|
|
|
|
for ( j = 0; j < 32; j++) {
|
|
printk("%02x", id[i+j]);
|
|
}
|
|
printk("\n");
|
|
}
|
|
}
|
|
|
|
static void dump_screeninfo(struct fb_var_screeninfo *einfo)
|
|
{
|
|
printk("resolution: r(%d, %d), v(%d, %d) o(%d, %d)\n",
|
|
einfo->xres,
|
|
einfo->yres,
|
|
einfo->xres_virtual,
|
|
einfo->yres_virtual,
|
|
einfo->xoffset,
|
|
einfo->yoffset);
|
|
printk("bpp=%d, hw(%d, %d), pclk=%d\n",
|
|
einfo->bits_per_pixel,
|
|
einfo->height,
|
|
einfo->width,
|
|
einfo->pixclock);
|
|
|
|
printk("margin(%d, %d, %d, %d)\n",
|
|
einfo->left_margin,
|
|
einfo->right_margin,
|
|
einfo->upper_margin,
|
|
einfo->lower_margin);
|
|
|
|
printk("hv(%d, %d), sync=%x, vmode=%x\n",
|
|
einfo->hsync_len,
|
|
einfo->vsync_len,
|
|
einfo->sync,
|
|
einfo->vmode);
|
|
|
|
}
|
|
#else
|
|
static void dump_edid(unsigned char *edid) {}
|
|
static void dump_screeninfo(struct fb_var_screeninfo *einfo) {}
|
|
#endif
|
|
|
|
static u8 mtl017_auo_tbl[] = {
|
|
/* ron: 66M to 66M */
|
|
/* 0x00,0x20,0xAF,0x59,0x2B,0xDE,0x51,0x00, */
|
|
/* 0x00,0x04,0x17,0x00,0x58,0x02,0x00,0x00, */
|
|
/* 0x00,0x21,0x01,0x08,0x00,0x1E,0x01,0x05, */
|
|
/* 0x00,0x01,0x7C,0x04,0x32,0x00,0x00,0x04, */
|
|
/* 0x00,0x00,0x20,0xA8,0x02,0x12,0x00,0x58, */
|
|
/* 0x02,0x00,0x00,0x02,0x00,0x00,0x02,0x00, */
|
|
/* 0x00,0x02,0x10,0x01,0x68,0x03,0xC2,0x01, */
|
|
/* 0x4A,0x03,0x46,0x00,0xF1,0x01,0x5C,0x04, */
|
|
/* 0x08,0x00,0x10,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x3A, */
|
|
/* 0x18,0x4B,0x29,0x5C,0xDE,0xF6,0xE0,0x1C, */
|
|
/* 0x03,0xFC,0xE3,0x1F,0xF3,0x75,0x26,0x45, */
|
|
/* 0x4A,0x91,0x8A,0xFF,0x3F,0x83,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x20,0x4E,0x48, */
|
|
/* 0x00,0x00,0x06,0x01,0x02,0x00,0x10,0x04, */
|
|
/* 0x02,0x1F,0x00,0x00,0x00,0x0A,0x00,0x00, */
|
|
/* 0x32,0x00,0x00,0x04,0x12,0x00,0x00,0x03, */
|
|
/* 0x02,0x7C,0x04,0x98,0x02,0x11,0x78,0x18, */
|
|
/* 0x30,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, */
|
|
/* 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, */
|
|
/* 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, */
|
|
|
|
/* ron: 44MHz to 54MHz */
|
|
/* 0x00,0x20,0xAF,0x59,0x2B,0xDE,0x51,0x00, */
|
|
/* 0x00,0x04,0x17,0x00,0x58,0x02,0x00,0x00, */
|
|
/* 0x00,0x3B,0x01,0x08,0x00,0x1E,0x01,0x05, */
|
|
/* 0x00,0x01,0x82,0x05,0x32,0x00,0x00,0x04, */
|
|
/* 0x00,0x00,0x20,0xA8,0x02,0x12,0x00,0x58, */
|
|
/* 0x02,0x00,0x00,0x02,0x00,0x00,0x02,0x00, */
|
|
/* 0x00,0x02,0x10,0x01,0x68,0x03,0xC2,0x01, */
|
|
/* 0x4A,0x03,0x46,0x00,0xF1,0x01,0x5C,0x04, */
|
|
/* 0x08,0x00,0x10,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x3A, */
|
|
/* 0x18,0x4B,0x29,0x5C,0xDE,0xF6,0xE0,0x1C, */
|
|
/* 0x03,0xFC,0xE3,0x1F,0xF3,0x75,0x26,0x45, */
|
|
/* 0x4A,0x91,0x8A,0xFF,0x3F,0x83,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x20,0x4E,0x48, */
|
|
/* 0x00,0x04,0x2A,0x01,0x02,0x00,0x10,0x04, */
|
|
/* 0x02,0x1F,0x00,0x00,0x00,0x0A,0x00,0x00, */
|
|
/* 0x32,0x00,0x00,0x04,0x12,0x00,0x58,0x02, */
|
|
/* 0x02,0x7C,0x04,0x7E,0x02,0x11,0x78,0x18, */
|
|
/* 0x30,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, */
|
|
/* 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, */
|
|
/* 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, */
|
|
|
|
|
|
/* ron: 44MHz to 48MHz */
|
|
/* 0x00,0x20,0xAF,0x59,0x2B,0xDE,0x51,0x00, */
|
|
/* 0x00,0x04,0x16,0x00,0x59,0x02,0x00,0x00, */
|
|
/* 0x00,0x21,0x00,0x09,0x00,0x1E,0x01,0x05, */
|
|
/* 0x00,0x01,0xEA,0x04,0x32,0x00,0x00,0x04, */
|
|
/* 0x00,0x00,0x20,0xA8,0x02,0x12,0x00,0x58, */
|
|
/* 0x02,0x00,0x00,0x02,0x00,0x00,0x02,0x00, */
|
|
/* 0x00,0x02,0x10,0x01,0x68,0x03,0xC2,0x01, */
|
|
/* 0x4A,0x03,0x46,0x00,0xF1,0x01,0x5C,0x04, */
|
|
/* 0x08,0x00,0x10,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x3A, */
|
|
/* 0x18,0x4B,0x29,0x5C,0xDE,0xF6,0xE0,0x1C, */
|
|
/* 0x03,0xFC,0xE3,0x1F,0xF3,0x75,0x26,0x45, */
|
|
/* 0x4A,0x91,0x8A,0xFF,0x3F,0x83,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x20,0x4E,0x48, */
|
|
/* 0x00,0x02,0x16,0x01,0x02,0x00,0x10,0x04, */
|
|
/* 0x02,0x1F,0x00,0x00,0x00,0x0A,0x00,0x00, */
|
|
/* 0x32,0x00,0x00,0x04,0x12,0x00,0x00,0x03, */
|
|
/* 0x02,0x7C,0x04,0x7E,0x02,0x11,0x78,0x18, */
|
|
/* 0x30,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, */
|
|
/* 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, */
|
|
/* 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, */
|
|
|
|
/* ron: 44M to 53.8M */
|
|
/* 0x00,0x20,0xAF,0x59,0x2B,0xDE,0x51,0x00, */
|
|
/* 0x00,0x04,0x17,0x00,0x58,0x02,0x00,0x00, */
|
|
/* 0x00,0x3B,0x01,0x08,0x00,0x1E,0x01,0x05, */
|
|
/* 0x00,0x01,0x7E,0x05,0x32,0x00,0x00,0x04, */
|
|
/* 0x00,0x00,0x20,0xA8,0x02,0x12,0x00,0x58, */
|
|
/* 0x02,0x00,0x00,0x02,0x00,0x00,0x02,0x00, */
|
|
/* 0x00,0x02,0x10,0x01,0x68,0x03,0xC2,0x01, */
|
|
/* 0x4A,0x03,0x46,0x00,0xF1,0x01,0x5C,0x04, */
|
|
/* 0x08,0x00,0x10,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x3A, */
|
|
/* 0x18,0x4B,0x29,0x5C,0xDE,0xF6,0xE0,0x1C, */
|
|
/* 0x03,0xFC,0xE3,0x1F,0xF3,0x75,0x26,0x45, */
|
|
/* 0x4A,0x91,0x8A,0xFF,0x3F,0x83,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x20,0x4E,0x48, */
|
|
/* 0x00,0x06,0x3B,0x01,0x02,0x00,0x10,0x04, */
|
|
/* 0x02,0x1F,0x00,0x00,0x00,0x0A,0x00,0x00, */
|
|
/* 0x32,0x00,0x00,0x04,0x12,0x00,0x58,0x02, */
|
|
/* 0x02,0x7C,0x04,0x98,0x02,0x11,0x78,0x18, */
|
|
/* 0x30,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, */
|
|
/* 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, */
|
|
/* 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, */
|
|
|
|
/* ron: 44M to 53.9M */
|
|
0x00,0x20,0xAF,0x59,0x2B,0xDE,0x51,0x00,
|
|
0x00,0x04,0x17,0x00,0x58,0x02,0x00,0x00,
|
|
0x00,0x3B,0x01,0x08,0x00,0x1E,0x01,0x05,
|
|
0x00,0x01,0x72,0x05,0x32,0x00,0x00,0x04,
|
|
0x00,0x00,0x20,0xA8,0x02,0x12,0x00,0x58,
|
|
0x02,0x00,0x00,0x02,0x00,0x00,0x02,0x00,
|
|
0x00,0x02,0x10,0x01,0x68,0x03,0xC2,0x01,
|
|
0x4A,0x03,0x46,0x00,0xF1,0x01,0x5C,0x04,
|
|
0x08,0x00,0x10,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x3A,
|
|
0x18,0x4B,0x29,0x5C,0xDE,0xF6,0xE0,0x1C,
|
|
0x03,0xFC,0xE3,0x1F,0xF3,0x75,0x26,0x45,
|
|
0x4A,0x91,0x8A,0xFF,0x3F,0x83,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x20,0x4E,0x48,
|
|
0x00,0x01,0x10,0x01,0x00,0x00,0x10,0x04,
|
|
0x02,0x1F,0x00,0x00,0x00,0x0A,0x00,0x00,
|
|
0x32,0x00,0x00,0x04,0x12,0x00,0x58,0x02,
|
|
0x02,0x7C,0x04,0x98,0x02,0x11,0x78,0x18,
|
|
0x30,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
|
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
|
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
|
};
|
|
|
|
static u8 mtl017_cpt_tbl[] = {
|
|
/* 0x00,0x20,0xAF,0x59,0x2B,0xDE,0x51,0x00, */
|
|
/* 0x00,0x04,0x17,0x00,0x58,0x02,0x00,0x00, */
|
|
/* 0x00,0x21,0x01,0x08,0x00,0x1E,0x01,0x05, */
|
|
/* 0x00,0x01,0x7C,0x04,0x32,0x00,0x00,0x04, */
|
|
/* 0x00,0x00,0x20,0xA8,0x02,0x12,0x00,0x58, */
|
|
/* 0x02,0x00,0x00,0x02,0x00,0x00,0x02,0x00, */
|
|
/* 0x00,0x02,0x10,0x01,0x68,0x03,0xC2,0x01, */
|
|
/* 0x4A,0x03,0x46,0x00,0xF1,0x01,0x5C,0x04, */
|
|
/* 0x08,0x00,0x10,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x3A, */
|
|
/* 0x18,0x4B,0x29,0x5C,0xDE,0xF6,0xE0,0x1C, */
|
|
/* 0x03,0xFC,0xE3,0x1F,0xF3,0x75,0x26,0x45, */
|
|
/* 0x4A,0x91,0x8A,0xFF,0x3F,0x83,0x00,0x00, */
|
|
/* 0x00,0x00,0x00,0x00,0x00,0x20,0x4E,0x48, */
|
|
/* 0x00,0x00,0x06,0x01,0x02,0x00,0x10,0x04, */
|
|
/* 0x02,0x1F,0x00,0x00,0x00,0x0A,0x00,0x00, */
|
|
/* 0x32,0x00,0x00,0x04,0x12,0x00,0x00,0x03, */
|
|
/* 0x02,0x7C,0x04,0x98,0x02,0x11,0x78,0x18, */
|
|
/* 0x30,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, */
|
|
/* 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, */
|
|
/* 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, */
|
|
|
|
/* ron: 44M to 53.9M */
|
|
0x00,0x20,0xAF,0x59,0x2B,0xDE,0x51,0x00,
|
|
0x00,0x04,0x17,0x00,0x58,0x02,0x00,0x00,
|
|
0x00,0x3B,0x01,0x08,0x00,0x1E,0x01,0x05,
|
|
0x00,0x01,0x72,0x05,0x32,0x00,0x00,0x04,
|
|
0x00,0x00,0x20,0xA8,0x02,0x12,0x00,0x58,
|
|
0x02,0x00,0x00,0x02,0x00,0x00,0x02,0x00,
|
|
0x00,0x02,0x10,0x01,0x68,0x03,0xC2,0x01,
|
|
0x4A,0x03,0x46,0x00,0xF1,0x01,0x5C,0x04,
|
|
0x08,0x00,0x10,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x3A,
|
|
0x18,0x4B,0x29,0x5C,0xDE,0xF6,0xE0,0x1C,
|
|
0x03,0xFC,0xE3,0x1F,0xF3,0x75,0x26,0x45,
|
|
0x4A,0x91,0x8A,0xFF,0x3F,0x83,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x20,0x4E,0x48,
|
|
0x00,0x01,0x10,0x01,0x00,0x00,0x10,0x04,
|
|
0x02,0x1F,0x00,0x00,0x00,0x0A,0x00,0x00,
|
|
0x32,0x00,0x00,0x04,0x12,0x00,0x58,0x02,
|
|
0x02,0x7C,0x04,0x98,0x02,0x11,0x78,0x18,
|
|
0x30,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
|
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
|
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
|
};
|
|
|
|
static u8 mtl017_auo_hires_tbl[] = {
|
|
0x00,0x20,0xAF,0x59,0x2B,0xDE,0x3D,0x00,
|
|
0x00,0x05,0x0C,0x00,0xD0,0x02,0x00,0x00,
|
|
0x00,0x05,0x00,0x02,0x00,0x02,0x00,0x0A,
|
|
0x00,0x01,0x70,0x05,0x3D,0x00,0x00,0x05,
|
|
0x00,0x00,0x20,0xF0,0x02,0x0C,0x00,0xD0,
|
|
0x02,0x00,0x00,0x02,0x00,0x00,0x02,0x00,
|
|
0x00,0x02,0x10,0x01,0x68,0x03,0xC2,0x01,
|
|
0x4A,0x03,0x46,0x00,0xF1,0x01,0x5C,0x04,
|
|
0x08,0x00,0x10,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x3A,
|
|
0x18,0x4B,0x29,0x5C,0xDE,0xF6,0xE0,0x1C,
|
|
0x03,0xFC,0xE3,0x1F,0xF3,0x75,0x26,0x45,
|
|
0x4A,0x91,0x8A,0xFF,0x3F,0x83,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x20,0x4E,0x48,
|
|
0x00,0x00,0x06,0x01,0x02,0x00,0x12,0x04,
|
|
0x02,0x1F,0x00,0x00,0x00,0x0A,0x00,0x00,
|
|
0x3D,0x00,0x00,0x05,0x0C,0x00,0xD0,0x02,
|
|
0x02,0x70,0x05,0xE0,0x02,0x11,0x78,0x18,
|
|
0x30,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
|
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
|
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
|
};
|
|
|
|
static u8 mtl017_cmo_tbl[] = {
|
|
/* ron: 44M to 53.9M */
|
|
0x00,0x20,0xAF,0x59,0x2B,0xDE,0x51,0x00,
|
|
0x00,0x04,0x17,0x00,0x58,0x02,0x00,0x00,
|
|
0x00,0x3B,0x01,0x08,0x00,0x1E,0x01,0x05,
|
|
0x00,0x01,0x72,0x05,0x32,0x00,0x00,0x04,
|
|
0x00,0x00,0x20,0xA8,0x02,0x12,0x00,0x58,
|
|
0x02,0x00,0x00,0x02,0x00,0x00,0x02,0x00,
|
|
0x00,0x02,0x10,0x01,0x68,0x03,0xC2,0x01,
|
|
0x4A,0x03,0x46,0x00,0xF1,0x01,0x5C,0x04,
|
|
0x08,0x00,0x10,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x3A,
|
|
0x18,0x4B,0x29,0x5C,0xDE,0xF6,0xE0,0x1C,
|
|
0x03,0xFC,0xE3,0x1F,0xF3,0x75,0x26,0x45,
|
|
0x4A,0x91,0x8A,0xFF,0x3F,0x83,0x00,0x00,
|
|
0x00,0x00,0x00,0x00,0x00,0x20,0x4E,0x48,
|
|
0x00,0x01,0x10,0x01,0x00,0x00,0x10,0x04,
|
|
0x02,0x1F,0x00,0x00,0x00,0x0A,0x00,0x00,
|
|
0x32,0x00,0x00,0x04,0x12,0x00,0x58,0x02,
|
|
0x02,0x7C,0x04,0x98,0x02,0x11,0x78,0x18,
|
|
0x30,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
|
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
|
0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
|
|
};
|
|
|
|
#define REGMAP_LENGTH ( sizeof(mtl017_auo_tbl) / sizeof(u8) )
|
|
#define BLOCK_TX_SIZE 32
|
|
|
|
static int mtl017_read_edid(struct i2c_adapter *adp, unsigned char *edid)
|
|
{
|
|
u8 buf0[2] = {0, 0};
|
|
int dat = 0;
|
|
u16 addr = 0x50;
|
|
struct i2c_msg msg[2] = {
|
|
{
|
|
.addr = addr,
|
|
.flags = 0,
|
|
.len = 1,
|
|
.buf = buf0,
|
|
}, {
|
|
.addr = addr,
|
|
.flags = I2C_M_RD,
|
|
.len = EDID_LENGTH,
|
|
.buf = edid,
|
|
},
|
|
};
|
|
|
|
if (adp == NULL)
|
|
return -EINVAL;
|
|
|
|
buf0[0] = 0x00;
|
|
memset(edid, 0, EDID_LENGTH);
|
|
dat = i2c_transfer(adp, msg, 2);
|
|
if (dat <= 0)
|
|
return -ENODEV;
|
|
|
|
if (edid[1] == 0x00)
|
|
return -ENOENT;
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* ron: for AUO B101AW02 1024x600 LCD Panel */
|
|
static struct fb_videomode auo_mode = {
|
|
.name = "AUO B101AW02 1024x600",
|
|
.refresh = 60,
|
|
.xres = 1024,
|
|
.yres = 600,
|
|
/* .pixclock = 16666, */ /* ron: 66MHz display clock*/
|
|
.pixclock = 22800, /* ron: 44MHz display clock*/
|
|
.left_margin = 80,
|
|
.right_margin = 40,
|
|
.upper_margin = 21,
|
|
.lower_margin = 21,
|
|
.hsync_len = 4,
|
|
.vsync_len = 4,
|
|
.sync = FB_SYNC_OE_LOW_ACT,
|
|
.vmode = FB_VMODE_NONINTERLACED,
|
|
};
|
|
|
|
/* ron: for AUO B101EW01 1280x720 LCD Panel */
|
|
static struct fb_videomode auo_hires_mode = {
|
|
.name = "AUO B101EW01 1280x720",
|
|
.refresh = 60,
|
|
.xres = 1280,
|
|
.yres = 720,
|
|
.pixclock = 16260,
|
|
.left_margin = 32,
|
|
.right_margin = 48,
|
|
.upper_margin = 7,
|
|
.lower_margin = 3,
|
|
.hsync_len = 32,
|
|
.vsync_len = 6,
|
|
.sync = FB_SYNC_OE_LOW_ACT,
|
|
.vmode = FB_VMODE_NONINTERLACED,
|
|
};
|
|
|
|
/* ron: for CPT CLAA101NB03A 1024x600 LCD Panel */
|
|
static struct fb_videomode cpt_mode = {
|
|
.name = "CPT CLAA101 1024x600",
|
|
.refresh = 60,
|
|
.xres = 1024,
|
|
.yres = 600,
|
|
.pixclock = 22800, /* ron: 44M display clock */
|
|
.left_margin = 80,
|
|
.right_margin = 40,
|
|
.upper_margin = 20,
|
|
.lower_margin = 21,
|
|
.hsync_len = 4,
|
|
.vsync_len = 4,
|
|
.sync = FB_SYNC_OE_LOW_ACT,
|
|
.vmode = FB_VMODE_NONINTERLACED,
|
|
};
|
|
|
|
static struct fb_videomode cmo_mode = {
|
|
.name = "CMO N101L6-L0D 1024x600",
|
|
.refresh = 60,
|
|
.xres = 1024,
|
|
.yres = 600,
|
|
.pixclock = 22800, /* ron: 44MHz display clock*/
|
|
.left_margin = 80,
|
|
.right_margin = 40,
|
|
.upper_margin = 20,
|
|
.lower_margin = 21,
|
|
.hsync_len = 4,
|
|
.vsync_len = 4,
|
|
.sync = FB_SYNC_OE_LOW_ACT,
|
|
.vmode = FB_VMODE_NONINTERLACED,
|
|
};
|
|
|
|
struct lcd_panel_info {
|
|
char manufacture[16];
|
|
char product_name[16];
|
|
struct fb_videomode *mode;
|
|
u8 *regs;
|
|
};
|
|
|
|
static struct lcd_panel_info pinfo[] = {
|
|
{
|
|
.manufacture = "AUO",
|
|
.product_name = "B101AW02 V0",
|
|
.mode = &auo_mode,
|
|
.regs = mtl017_auo_tbl,
|
|
},
|
|
{
|
|
.manufacture = "CPT",
|
|
.product_name = "CLAA101NB03A",
|
|
.mode = &cpt_mode,
|
|
.regs = mtl017_cpt_tbl,
|
|
},
|
|
{
|
|
.manufacture = "AUO",
|
|
.product_name = "B101EW01",
|
|
.mode = &auo_hires_mode,
|
|
.regs = mtl017_auo_hires_tbl,
|
|
},
|
|
{
|
|
.manufacture = "CMO",
|
|
.product_name = "N101L6-L0D",
|
|
.mode = &cmo_mode,
|
|
.regs = mtl017_cmo_tbl,
|
|
}
|
|
};
|
|
|
|
//vv static void mtl017_find_videomode(struct mtl017_dev_data *mtl017)
|
|
static void mtl017_find_videomode(mtl017_dev_data *mtl017)
|
|
{
|
|
int i;
|
|
struct i2c_adapter *adp;
|
|
struct fb_var_screeninfo var;
|
|
int err;
|
|
|
|
adp = i2c_get_adapter(1);
|
|
err = mtl017_read_edid(adp, mtl017->edid);
|
|
|
|
dump_edid(mtl017->edid);
|
|
/* ron: use edid to parse screeninfo,
|
|
but these parameters have some problem */
|
|
memset(&var, 0, sizeof(var));
|
|
fb_parse_edid(mtl017->edid, &var);
|
|
dump_screeninfo(&var);
|
|
|
|
for (i = 0; i < ARRAY_SIZE(pinfo); i ++) {
|
|
if(/* (memcmp(mtl017->edid + 0x5f, pinfo[i].manufacture, strlen(pinfo[i].manufacture)) == 0) && */
|
|
(memcmp(mtl017->edid + 0x71, pinfo[i].product_name, strlen(pinfo[i].product_name)) == 0)) {
|
|
printk("mtl017: Probe LCD Panel: %s %s\n",
|
|
pinfo[i].manufacture,
|
|
pinfo[i].product_name);
|
|
mtl017->mode = pinfo[i].mode;
|
|
mtl017->regs = pinfo[i].regs;
|
|
|
|
return;
|
|
}
|
|
}
|
|
|
|
mtl017->regs = NULL;
|
|
mtl017->mode = NULL;
|
|
}
|
|
|
|
static void lcd_init_fb(struct fb_info *info)
|
|
{
|
|
struct fb_var_screeninfo var;
|
|
|
|
memset(&var, 0, sizeof(var));
|
|
|
|
fb_videomode_to_var(&var, mtl017->mode);
|
|
var.activate = FB_ACTIVATE_ALL;
|
|
|
|
acquire_console_sem();
|
|
info->flags |= FBINFO_MISC_USEREVENT;
|
|
fb_set_var(info, &var);
|
|
fb_blank(info, FB_BLANK_UNBLANK);
|
|
info->flags &= ~FBINFO_MISC_USEREVENT;
|
|
release_console_sem();
|
|
|
|
|
|
}
|
|
|
|
static int lcd_fb_event(struct notifier_block *nb, unsigned long val, void *v)
|
|
{
|
|
struct fb_event *event = v;
|
|
|
|
if (strcmp(event->info->fix.id, "DISP3 BG - DI1")) {
|
|
return 0;
|
|
}
|
|
|
|
switch (val) {
|
|
case FB_EVENT_FB_REGISTERED:
|
|
lcd_init_fb(event->info);
|
|
break;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static struct notifier_block fb_nb = {
|
|
.notifier_call = lcd_fb_event,
|
|
};
|
|
|
|
/*!
|
|
* This function is called whenever the SPI slave device is detected.
|
|
*
|
|
* @param spi the SPI slave device
|
|
*
|
|
* @return Returns 0 on SUCCESS and error on FAILURE.
|
|
*/
|
|
|
|
static int __devinit mtl017_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
|
{
|
|
struct mxc_lcd_platform_data *plat = client->dev.platform_data;
|
|
int retval;
|
|
int i;
|
|
|
|
//vv mtl017 = kzalloc(sizeof(*mtl017), GFP_KERNEL);
|
|
mtl017 = (mtl017_dev_data*)kzalloc(sizeof(*mtl017), GFP_KERNEL);
|
|
|
|
if(!mtl017) {
|
|
dev_err(&client->dev, "failed to allocate mtl017 device\n");
|
|
retval = -ENOMEM;
|
|
return retval;
|
|
}
|
|
|
|
mtl017->suspending = 0;
|
|
mtl017->client = client;
|
|
if(plat) {
|
|
mtl017->reset = plat->reset;
|
|
mtl017->lcd_power = plat->lcd_power;
|
|
mtl017->lvds_power = plat->lvds_power;
|
|
mtl017->lvds_enable = plat->lvds_enable;
|
|
}
|
|
|
|
/* mtl017->lock = SPIN_LOCK_UNLOCKED; */
|
|
sema_init(&mtl017->sem, 1);
|
|
|
|
mtl017_find_videomode(mtl017);
|
|
if(mtl017->mode == NULL)
|
|
mtl017->mode = &auo_mode;
|
|
if(mtl017->regs == NULL)
|
|
mtl017->regs = mtl017_auo_tbl;
|
|
|
|
for (i = 0; i < num_registered_fb; i++) {
|
|
if (strcmp(registered_fb[i]->fix.id, "DISP3 BG - DI1") == 0) {
|
|
lcd_init_fb(registered_fb[i]);
|
|
fb_show_logo(registered_fb[i], 0);
|
|
}
|
|
}
|
|
|
|
fb_register_client(&fb_nb);
|
|
|
|
/* disp_power_on(); */
|
|
schedule_work(&disp_on_work);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
static int __devexit mtl017_remove(struct i2c_client *client)
|
|
{
|
|
fb_unregister_client(&fb_nb);
|
|
disp_power_off();
|
|
|
|
kfree(mtl017);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int mtl017_suspend(struct i2c_client *client, pm_message_t message)
|
|
{
|
|
mtl017->suspending = 1;
|
|
disp_power_off();
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int mtl017_resume(struct i2c_client *client)
|
|
{
|
|
/* ron: because we turn off regulator, */
|
|
/* so re-initialize MTL017 controller after suspending */
|
|
mtl017->suspending = 0;
|
|
disp_power_on();
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void mtl017_conf(u8 *reg_tbl)
|
|
{
|
|
int i;
|
|
int ret;
|
|
int retry = 5;
|
|
|
|
dev_dbg(&mtl017->client->dev, "Initializing MTL017 LVDS Controller\n");
|
|
|
|
// Writing configuration table.
|
|
for (i = 0; i < REGMAP_LENGTH; i+=BLOCK_TX_SIZE) {
|
|
retry:
|
|
msleep(1);
|
|
ret = i2c_smbus_write_i2c_block_data(mtl017->client, i, BLOCK_TX_SIZE, &(reg_tbl[i]));
|
|
if (ret < 0) {
|
|
printk(KERN_WARNING "MTL017 LVDS Controller Initialize Fail!\n");
|
|
if(retry -- > 0)
|
|
goto retry;
|
|
return;
|
|
}
|
|
}
|
|
|
|
}
|
|
static void disp_power_on(void)
|
|
{
|
|
if(mtl017->disp_on || mtl017->suspending)
|
|
return;
|
|
|
|
if (down_interruptible(&mtl017->sem))
|
|
return;
|
|
|
|
if(mtl017->lcd_power) {
|
|
mtl017->lcd_power(1);
|
|
msleep(10);
|
|
}
|
|
|
|
if(mtl017->lvds_enable) {
|
|
mtl017->lvds_enable(1);
|
|
msleep(5);
|
|
}
|
|
|
|
if(mtl017->lvds_power) {
|
|
mtl017->lvds_power(1);
|
|
msleep(5);
|
|
}
|
|
|
|
mtl017_conf(mtl017->regs);
|
|
msleep(200);
|
|
|
|
mtl017->disp_on = 1;
|
|
|
|
up(&mtl017->sem);
|
|
}
|
|
|
|
static void disp_power_off(void)
|
|
{
|
|
if(mtl017->disp_on == 0)
|
|
return;
|
|
|
|
if (down_interruptible(&mtl017->sem))
|
|
return;
|
|
|
|
msleep(200);
|
|
|
|
if(mtl017->lvds_enable) {
|
|
mtl017->lvds_enable(0);
|
|
}
|
|
|
|
if(mtl017->lvds_power) {
|
|
mtl017->lvds_power(0);
|
|
msleep(5);
|
|
}
|
|
|
|
if(mtl017->lcd_power) {
|
|
mtl017->lcd_power(0);
|
|
}
|
|
|
|
mtl017->disp_on = 0;
|
|
|
|
up(&mtl017->sem);
|
|
}
|
|
|
|
static const struct i2c_device_id mtl017_id[] = {
|
|
{ "mtl017", 0 },
|
|
{},
|
|
};
|
|
MODULE_DEVICE_TABLE(i2c, mtl017_id);
|
|
|
|
static struct i2c_driver mtl017_driver = {
|
|
.driver = {
|
|
.name = "mtl017",
|
|
},
|
|
.probe = mtl017_probe,
|
|
.remove = mtl017_remove,
|
|
.suspend = mtl017_suspend,
|
|
.resume = mtl017_resume,
|
|
.id_table = mtl017_id,
|
|
};
|
|
|
|
static int __init mtl017_init(void)
|
|
{
|
|
return i2c_add_driver(&mtl017_driver);
|
|
}
|
|
|
|
static void __exit mtl017_exit(void)
|
|
{
|
|
i2c_del_driver(&mtl017_driver);
|
|
}
|
|
|
|
module_init(mtl017_init);
|
|
module_exit(mtl017_exit);
|
|
|
|
MODULE_AUTHOR("Ron Lee <ron1_lee@pegatroncorp.com> Pegatron Corp.");
|
|
MODULE_DESCRIPTION("MTL017 LVDS Controller driver");
|
|
MODULE_LICENSE("GPL");
|
|
|