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

来源:互联网 发布:2年java开发工程师简历 编辑:程序博客网 时间:2024/06/04 19:35

  之前选择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);

原创粉丝点击