这里以调试mt8735 7.0 中的lvds屏Icn6202为例:
icn6202是一款LVDS 屏:它可以把CPU端传出来的数字信号(譬如mipi信号)转换成lvds信号,再转换成lcd能接收的数字信号,再通过lcd显示对应的图像;lvds信号跟mipi信号一样,虽都可以做到低功耗高数率传输,但lvds信号能远距离传送;
下面开始具体分析调试LCD:
1.从上面原理图可以知道icn6202是一个i2设备,再考虑到lcm的代码在lk kernel里面都有,andorid6.0之后,lk kernel对i2c的处理和gpio口操作函数不一样;
//lk代码名称跟路径
Icn6202_wsvga_lvds_dsi_vdo.c (drivers\vendor\mediatek\proprietary\bootable\bootloader\lk\dev\lcm\icn6202_wsvga_lvds_dsi_vdo)
lk:直接可以调用系统接口的i2通讯函数操作gpio口函数
//lk的i2c通讯函数
static struct mt_i2c_t icn6202_i2c;
#define LCM_I2C_ID I2C1
#define LCM_I2C_ADDR 0x58
#define LCM_I2C_MODE ST_MODE
#define LCM_I2C_SPEED 100
static int icn6202_reg_i2c_write(kal_uint8 addr, kal_uint8 value)
{
kal_int32 ret_code = I2C_OK;
kal_uint8 write_data[2];
kal_uint16 len;
write_data[0]= addr;
write_data[1] = value;
icn6202_i2c.id = LCM_I2C_ID;
icn6202_i2c.addr = (LCM_I2C_ADDR>>1);
icn6202_i2c.mode = LCM_I2C_MODE;
icn6202_i2c.speed = LCM_I2C_SPEED;
len = 2;
ret_code = i2c_write(&icn6202_i2c, write_data, len);
if (ret_code<0)
printf("[LCM][ERROR] %s: %d\n", __func__, ret_code);
return ret_code;
}
//lk的gpio操作函数
#define GPIO_LCD_ICN6202_EN (GPIO55 | 0x80000000)
static void lcm_set_power_pin(u32 pin, u32 out)
{
mt_set_gpio_mode(pin, GPIO_MODE_GPIO);
mt_set_gpio_dir(pin, GPIO_DIR_OUT);
mt_set_gpio_out(pin, out);
}
static void lcm_init(void)
{
printf("lcm_init start\n");
SET_RESET_PIN(0);
MDELAY(10);
SET_RESET_PIN(1);
MDELAY(20);
lcm_set_power_pin(GPIO_LCD_ICN6202_EN,1); //gpio调用
init_icn6202_registers();
printf("lcm_init end\n");
}
//kernel的代码名称跟路径
//Icn6202_wsvga_lvds_dsi_vdo.c (drivers\kernel-3.18\drivers\misc\mediatek\lcm\icn6202_wsvga_lvds_dsi_vdo)
//gpio的操作函数
跟lk不同,kernel的gpio函数要除了跟lk样要dct工具配置外,还要在设备树中配置,因此代码中必须要先申请,后才能调用
static unsigned int GPIO_LCD_PWR1_EN;
static unsigned int GPIO_LCD_PWR2_EN;
static unsigned int GPIO_LCD_ic6202_EN;
void lcm_get_gpio_infor(void)
{
static struct device_node *node;
node = of_find_compatible_node(NULL, NULL, "mediatek,lcm_mtk");
GPIO_LCD_PWR1_EN = of_get_named_gpio(node, "lcm_power1_gpio", 0);
GPIO_LCD_PWR2_EN = of_get_named_gpio(node, "lcm_power2_gpio", 0);
GPIO_LCD_ic6202_EN = of_get_named_gpio(node, "lcm_i2c_gpio", 0);
gpio_request(GPIO_LCD_PWR1_EN, "lcm_power1_gpio");
gpio_request(GPIO_LCD_PWR2_EN, "lcm_power2_gpio");
gpio_request(GPIO_LCD_ic6202_EN, "lcm_i2c_gpio");
}
//I2C的dct操作和out目录生成的文件如下
&i2c1 {
#address-cells = <1>;
#size-cells = <0>;
ext_disp@2c {
compatible = "mediatek,ext_disp";
reg = <0x2c>;
status = "okay";
};
};
//除了dct的i2c配置外,同时代码库里面也要对i2c进行操作
static int icn6202_i2c_write(u8 reg, u8 writedata)
{
u8 databuf[2] = {0};
int ret = 0;
databuf[0] = reg;
databuf[1] = writedata;
ret = i2c_master_send(icn6202_i2c_client, databuf, 2);
printk(" lcm --- icn6202_i2c_write ret=%d, databuf[0]=%d, databuf[1]=%d\n", ret, databuf[0], databuf[1]);
if(ret < 0)
{
printk(" lcm --- icn6202_i2c_write send data failed !\n");
return -1;
}
return ret;
}
#ifdef CONFIG_OF
static const struct of_device_id lcm_of_match[] = {
{ .compatible = "mediatek,ext_disp" },
{},
};
#endif
struct i2c_driver icn6202_i2c_driver = {
.id_table = icn6202_i2c_id,
.probe = icn6202_i2c_probe,
.remove = icn6202_i2c_remove,
.driver = {
.owner = THIS_MODULE,
.name = icn6202_DEVICE_NAME ,
#ifdef CONFIG_OF
.of_match_table = lcm_of_match,
#endif
},
};
//lcm调试对于驱动来讲:lk kernel一样就是填充一个结构体中的6个成员(其他成员按情况添加)
LCM_DRIVER icn6202_wsvga_lvds_dsi_vdo_lcm_drv =
{
.name = "icn6202_dsi_lvds",
.set_util_funcs = lcm_set_util_funcs,
.get_params = lcm_get_params,
.init = lcm_init,
.suspend = lcm_suspend,
.resume = lcm_resume,
};
mt6737 M0 c66项目 (同样适合mt8735_7.0)
lcd 移植
lk
R:\c66_6.0\vendor\mediatek\proprietary\bootable\bootloader\lk\dev\lcm\ek79030_tm686_dsi_vdo
R:\c66_6.0\vendor\mediatek\proprietary\bootable\bootloader\lk\project\joya6737m_65_m0.mk
R:\c66_6.0\vendor\mediatek\proprietary\bootable\bootloader\lk\dev\lcm\mt65xx_lcm_list.c
kernel
R:\c66_6.0\device\joya\joya6737m_65_m0\ProjectConfig.mk
R:\c66_6.0\kernel-3.18\drivers\misc\mediatek\lcm\mt65xx_lcm_list.c
R:\c66_6.0\kernel-3.18\drivers\misc\mediatek\lcm\mt65xx_lcm_list.h
R:\c66_6.0\kernel-3.18\arch\arm64\configs\joya6737m_65_m0_defconfig
R:\c66_6.0\kernel-3.18\arch\arm64\configs\joya6737m_65_m0_debug_defconfig
Line 1037: CONFIG_CUSTOM_KERNEL_LCM="ek79030_tm686_dsi_vdo"
Line 1160: CONFIG_MTK_LCM_PHYSICAL_ROTATION="90"
Line 1161: CONFIG_LCM_HEIGHT="1280"
Line 1162: CONFIG_LCM_WIDTH="480"
//add kernel driver
R:\c66_6.0\kernel-3.18\drivers\misc\mediatek\lcm\ek79030_tm686_dsi_vdo