新路程------imx6动态修改lvds channel

xiaoxiao2021-02-28  69

  之前选择lvds channel都是在uboot的env里面写ldb=sin0这样,但是现在要动态去修改也就是在系统跑起来之后做这个事。于是先看这个channel是怎么选择的。

在ldb.c中看code

static int __init ldb_setup(char *options) { if (!strcmp(options, "spl0")) g_ldb_mode = LDB_SPL_DI0; else if (!strcmp(options, "spl1")) g_ldb_mode = LDB_SPL_DI1; else if (!strcmp(options, "dul0")) g_ldb_mode = LDB_DUL_DI0; else if (!strcmp(options, "dul1")) g_ldb_mode = LDB_DUL_DI1; else if (!strcmp(options, "sin0")) g_ldb_mode = LDB_SIN0; else if (!strcmp(options, "sin1")) g_ldb_mode = LDB_SIN1; else if (!strcmp(options, "sep0")) g_ldb_mode = LDB_SEP0; else if (!strcmp(options, "sep1")) g_ldb_mode = LDB_SEP1; return 1; } __setup("ldb=", ldb_setup);

这里获取了cmd line里的参数,然后这个参数怎么用呢

其实就是写了两个register

writel(reg, ldb->control_reg);

writel(reg, ldb->control_reg);

这两个register在cmd里的sin0的时候

是161,0

在sin1的时候是172,256.

那在哪里改呢,先看ldb和fbmem.c直接怎么通信

有个ldb_fb_event,这里接受fb_notify的消息

fbmem.c中会发消息,所以先在这里加代码

case FB_EVENT_CHANR_CHANNEL: printk("matt-FB_EVENT_CHANR_CHANNEL \n"); mo=*((int *)event->data); if(mo == 0)//channel sin0 {             ldb->mode=5; writel(161, ldb->control_reg); ldb->setting[0].ch_mask = 3;            ldb->setting[0].ch_val = 1; }else{ ldb->mode=6; writel(172, ldb->control_reg); ldb->setting[0].ch_mask = 12;            ldb->setting[0].ch_val = 12; } reg = readl(ldb->gpr3_reg); printk("matt-before reg=%d\n",reg); reg &= ~(LVDS0_MUX_CTL_MASK | LVDS1_MUX_CTL_MASK);    channel1 = ldb->mode - LDB_SIN0;    shift1 = LVDS0_MUX_CTL_OFFS + channel1 * LVDS_MUX_CTL_WIDTH;    reg |= ROUTE_IPU_DI(0, mo) << shift1;    printk("matt-channel=%d,reg=%d\n",channel1,reg); writel(reg, ldb->gpr3_reg); break;

然后到fbmem.c中的ioctl中去加代码

case FBIOSET_CHANNEL: printk("matt-FBIOSET_CHANNEL\n"); if (copy_from_user(&ret1, argp, sizeof(ret1))) return -EFAULT; event.data=&ret1; if (!lock_fb_info(info)) return -ENODEV; event.info = info; fb_notifier_call_chain(FB_EVENT_CHANR_CHANNEL, &event); unlock_fb_info(info); ret = copy_to_user(argp, &ret, sizeof(ret)) ? -EFAULT : 0;

然后在外面写应用c

#include <linux/fb.h> #include <stdio.h> #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h> #include <linux/ioctl.h> #include <unistd.h>   #include <stdio.h>   #include <stdlib.h>   #include <fcntl.h>   #include <linux/fb.h>   #include <sys/mman.h>   #include <math.h> #include <unistd.h>   #include <stdio.h>   #include <stdlib.h>   #include <fcntl.h>   #include <linux/fb.h>   #include <sys/mman.h>    #define FBIOSET_CHANNEL 0x4622  struct fb_var_screeninfo  vinfo; void main(int argc, char * argv[]) {         int fd = 0;     int channel;     int x =0;      channel=atoi(argv[1]);     printf("start ioctl \n");        //  printf("matt-argc=%d\n",argc);              fd = open("/dev/fb0",O_RDWR);     if (fd < 0)     {         printf("matt-Open Dev Mem0 Error!\n");     }    sleep(5);          printf("matt-channel=%d\n",channel);          //选择channel     /* if (ioctl(fd,FBIOSET_CHANNEL,&channel))        {             printf("Error writeing variable information/n");             exit(3);        } */       if (ioctl(fd,FBIOGET_VSCREENINFO,&vinfo))        {             printf("Error reading variable information/n");             exit(3);        }      close(fd);     done: exit(0);

转载请注明原文地址: https://www.6miu.com/read-70882.html

最新回复(0)