赞
踩
手上的项目兼容了一款新mipi副屏,如果想了解,可以去看看
兼容副屏后,已经能正常点亮,休眠唤醒也正常了,还剩一个问题:显示为竖屏,要改为横屏。
我参考了同事的做法,就是先在dev下创建一个设备文件/dev/dsi-panel-id,上层open该设备文件后通过ioctl方式访问kernel层,将kernel层的储存屏id的变量传递给上层。最后在上层判断屏id区别是新旧屏,如果是新屏,就旋转。
drivers/gpu/drm/panel/panel-simple.c
- diff --git a/drivers/gpu/drm/panel/panel-simple.c b/drivers/gpu/drm/panel/panel-simple.c
- index db392b8..01dba51 100644
- --- a/drivers/gpu/drm/panel/panel-simple.c
- +++ b/drivers/gpu/drm/panel/panel-simple.c
-
- @@ -40,6 +40,9 @@
- #include <linux/of_graph.h>
- #include <video/videomode.h>
-
- +static char panel_id; //储存读取dts的panel id
- +
- +
- struct cmd_ctrl_hdr {
- u8 dtype; /* data type */
- u8 wait; /* ms */
- @@ -2351,6 +2354,106 @@ static const struct of_device_id dsi_of_match[] = {
- };
- MODULE_DEVICE_TABLE(of, dsi_of_match);
-
- +/*---------------------------liyj ---------------------------------------------------------------------------*/
- +
- +static struct class *dsi_panel_class = NULL;
- +static struct device *dsi_panel_device = NULL;
- +static struct miscdevice dsi_pane_id_device;
- +#define NO_PANEL_ID 0XFF
- +#define DSI_PANEL_ID_MAGIC 0xFA
- +#define DSI_PANEL_ID_GET _IOR(DSI_PANEL_ID_MAGIC, 0x01, char) //自定义一个ioctl命令,用于上层与kernel层的交互
- +
- //下面会有一个函数在sys文件系统下创建/sys/class/panel/dsi-panel节点,在控制台下使用cat id会回调id_show函数
- +static ssize_t id_show(struct device *dev,
- + struct device_attribute *attr, char *buf)
- +{
- + return sprintf(buf, "%d",panel_id);
- +}
- +
- +static DEVICE_ATTR_RO(id);
-
- //在sys文件系统下创建/sys/class/panel/dsi-panel节点
- +static int telpo_create_panel_sysfs_dir(void)
- +{
- + printk("---liyj--- FILE : %s enter func : %s LINE : %d\n",__FILE__,__func__,__LINE__);
- + dsi_panel_class = class_create(THIS_MODULE, "panel");
- + if (IS_ERR(dsi_panel_class))
- + return PTR_ERR(dsi_panel_class);
- +
- + dsi_panel_device = device_create(dsi_panel_class, NULL, MKDEV(0, 0), NULL, "dsi-panel");
- + if (IS_ERR(dsi_panel_device)) {
- + class_destroy(dsi_panel_class);
- + return PTR_ERR(dsi_panel_device);
- + }
- +
- + return device_create_file(dsi_panel_device, &dev_attr_id);
- +}
-
- +static int dsi_panel_id_dev_open(struct inode *inode, struct file *filp)
- +{
- + return 0;
- +}
- +
- +
- //上层与kernel层交互的通道
- +static long dsi_panel_id_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
- +{
- + switch (cmd) {
- + case DSI_PANEL_ID_GET:
- + printk("***liyj***copy_to_user start\n");
- + if(copy_to_user((void * __user)arg,&panel_id,sizeof(panel_id)))
- + {
- + printk("***liyj***copy_to_user failed\n");
- + }
- + break;
- + default:
- + printk("get dsi panel id err\n");
- + return -EINVAL;
- + }
- + return 0;
- +}
- +
- +static const struct file_operations dsi_panel_id_dev_fops =
- +{
- + .owner = THIS_MODULE,
- + .llseek = no_llseek,
- + .open = dsi_panel_id_dev_open,
- + .unlocked_ioctl = dsi_panel_id_dev_ioctl,
- + .compat_ioctl = dsi_panel_id_dev_ioctl,
- +};
-
- //在dev下创建一个设备节点,用于上层跟kernel层的交互
- +static int telpo_create_panel_misc_dev(void)
- +{
- + int ret;
- +
- + printk("---liyj--- FILE : %s enter func : %s LINE : %d\n",__FILE__,__func__,__LINE__);
- + dsi_pane_id_device.minor = MISC_DYNAMIC_MINOR;
- + dsi_pane_id_device.name = "dsi-panel-id";
- + dsi_pane_id_device.fops = &dsi_panel_id_dev_fops;
- +
- + ret = misc_register(&dsi_pane_id_device);
- + if (ret) {
- + pr_err("%s :dsi panel is misc register failed\n", __FILE__);
- + return -ENODEV;
- + }
- + return 0;
- +}
- +
- +
- +static char get_panel_id(struct device *dev)
- +{
- + char g_panel_id ;
- + int len;
- + int ret;
- + struct device_node *np = dev->of_node;
- + //g_panel_id = of_get_property(np,"id",&len);
- + of_property_read_u8(np,"id",&g_panel_id); //读取dts中panel节点的id
- + printk("---liyj--- g_panel_id = %x\n",g_panel_id);
- + return g_panel_id;
- +}
-
- +/*---------------------------liyj ---------------------------------------------------------------------------*/
- +
- static int panel_simple_dsi_probe(struct mipi_dsi_device *dsi)
- {
- struct panel_simple *panel;
- @@ -2360,6 +2463,7 @@ static int panel_simple_dsi_probe(struct mipi_dsi_device *dsi)
- int err;
- u32 val;
-
- +
- id = of_match_node(dsi_of_match, dsi->dev.of_node);
- if (!id)
- return -ENODEV;
- @@ -2390,6 +2494,14 @@ static int panel_simple_dsi_probe(struct mipi_dsi_device *dsi)
-
- if (!of_property_read_u32(dsi->dev.of_node, "dsi,lanes", &val))
- dsi->lanes = val;
- +//liyj add start
- + panel_id = get_panel_id(&dsi->dev);
- + if (panel_id != NO_PANEL_ID) {
- + telpo_create_panel_sysfs_dir();
- + telpo_create_panel_misc_dev();
- + }
- +
- +//liyj add end
-
- return mipi_dsi_attach(dsi);
- }

dts中新屏节点的配置
- &dsi {
- status = "okay";
- rockchip,lane-rate = <528>;
- enable-gpios = <&gpio2 5 GPIO_ACTIVE_HIGH>;
- panel@0 {
- compatible = "simple-panel-dsi";
- reg = <0>;
- ............
- ............
-
- num = <0>;
- id = [93]; //新屏的id
- id-reg = <0xda>; //要读取的id寄存器
-
- ............
- ............
- }
-
-
- ............
- }

system/core/drmservice/drmservice.c
- diff --git a/system/core/drmservice/drmservice.c b/system/core/drmservice/drmservice.c
- index 4640716..61cd86d 100755
- --- a/system/core/drmservice/drmservice.c
- +++ b/system/core/drmservice/drmservice.c
- @@ -1074,6 +1074,59 @@ void copy_dir(const char *old_path,const char *new_path)
- }
-
-
- +#define DSI_PANEL_ID_MAGIC 0xFA
- +#define DSI_PANEL_ID_GET _IOR(DSI_PANEL_ID_MAGIC, 0x01,char)
- +#define DSI_PANEL_ID_DEV_PATH "/dev/dsi-panel-id"
- +#define NO_PANEL_ID 0xff
- +#define PANEL_OLD 0 //old panel
- +#define PANEL_NEW 147 //new panel 新屏id,我的新屏id是0x93,十进制就是147
- +static void get_dsi_panel_id(void)
- +{
- + int fd = -1;
- + char id = NO_PANEL_ID;
- + int ret;
- + char model_value[PROPERTY_VALUE_MAX] = {0};
- + property_get("ro.internal.model", model_value, "");
- +
- + fd = open(DSI_PANEL_ID_DEV_PATH, O_RDONLY); //1、打开设备文件
- + if (fd > 0) {
- + SLOGE("---liyj--- fd > 0");
- + ret = ioctl(fd, DSI_PANEL_ID_GET, &id); //2、通过自定义的cmd跟kernel交互,获取panel id
- + if(ret <0)
- + {
- + SLOGE("---liyj--- ioctl failed\n");
- + }
- + SLOGE("---liyj--- id = %d\n",id);
- + close(fd);
- + }
- + if (id == NO_PANEL_ID)
- + return;
- +
- + if (!(strcmp(model_value, "TPS680C"))) {
- + ALOGE("set TPS680C panel");
- + switch (id) {
- + case PANEL_OLD:
- + ALOGE("set panel as PANEL_OLD");
- + property_set("persist.sys.rotation.efull-1", "true");
- + property_set("persist.sys.rotation.einit", "0");
- + break;
- + case PANEL_NEW: //新屏
- + ALOGE("set panel as PANEL_NEW");
- + property_set("persist.sys.rotation.efull-1", "false");
- + property_set("persist.sys.rotation.einit", "3"); //旋转270度
- + break;
- + default:
- + SLOGD("not support panel id, set PANEL_NEW as default");
- + property_set("persist.sys.rotation.efull-1", "false");
- + property_set("persist.sys.rotation.einit", "3");
- + break;
- + }
- + } else {
- + ALOGE("no model panel set");
- + }
- +}
- +
-
- /** * Program entry pointer */
- @@ -1091,6 +1144,8 @@ int main( int argc, char *argv[] )
- SLOGE("get prop_board_platform,prop_board_platform = %s , diff=%d",prop_board_platform,
- strcmp(prop_board_platform,"rk3399"));
-
- + get_dsi_panel_id(); //函数调用,获取panel id
- +
- //get hid data
- rknand_sys_storage_test_hid();
- SLOGE("Get HID data:%s", hid_buf_idb);

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。