linux驱动学习笔记Camif

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

触摸屏驱动学习:

\drivers\media\video\s3c2440camif.c

\drivers\media\video\s3c2440_ov9650.c

\drivers\media\video\sccb.c

硬件连接

I2C总线连接

I2CSCL ——GPE14

I2CSDA——GPE15

Sccb.h

#define SIO_C S3C2410_GPE14

#define SIO_D S3C2410_GPE15

#define State(x) s3c2410_gpio_getpin(x)

#define High(x) do{s3c2410_gpio_setpin(x,1); smp_mb();}while(0)

#define Low(x) do{s3c2410_gpio_setpin(x,0); smp_mb();}while(0)

#define WAIT_STABLE() do{udelay(10);}while(0)

#define WAIT_CYCLE() do{udelay(90);}while(0)

#define CFG_READ(x) do{s3c2410_gpio_cfgpin(x,S3C2410_GPIO_INPUT);smp_mb();}while(0) #define CFG_WRITE(x) d o{s3c2410_gpio_cfgpin(x,S3C2410_GPIO_OUTPUT);smp_mb();}while(0) void sccb_write(u8 IdAddr, u8 SubAddr, u8 data);

u8 sccb_read(u8 IdAddr, u8 SubAddr);

CFG_WRITE(x)把GPIO设置为输出

CFG_READ(x)把GPIO设置为输入

High(x) 把GPIO设置为高电平

Low(x) 把GPIO设置为低电平

把SCL和Data都拉高,即为默认初始化状态电平

int sccb_init(void)

{

CFG_WRITE(SIO_C);

CFG_WRITE(SIO_D);

High(SIO_C);

High(SIO_D);

WAIT_STABLE();

return 0;

}

由上面的图可以看出,CLK高电平时,DATA拉低,即为START

static void __inline__ sccb_start(void)

{

CFG_WRITE(SIO_D);

Low(SIO_D);

WAIT_STABLE();

}

使用到一个信号量

static DECLARE_MUTEX(bus_lock);

void sccb_write(u8 IdAddr, u8 SubAddr, u8 data)

{

down(&bus_lock);

sccb_start();

sccb_write_byte(IdAddr);

sccb_write_byte(SubAddr);

sccb_write_byte(data);

sccb_stop();

up (&bus_lock);

}

首先把信号量数值降低,表示自己使用,如果此时信号量不大于0,表示bus正在使用,驱动会在此等待,知道信号量大于0,然后,将其减1,此时bus对外界不可用。最后再把信号量加1,表示bus

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

摄像头接口初始化:

/*

* camif_init()

*/

static int __init camif_init(void)

{

配置CAMIF的GPIO接口功能

/* set gpio-j to camera mode. */

s3c2410_gpio_cfgpin(S3C2440_GPJ0, S3C2440_GPJ0_CAMDATA0);

s3c2410_gpio_cfgpin(S3C2440_GPJ1, S3C2440_GPJ1_CAMDATA1);

s3c2410_gpio_cfgpin(S3C2440_GPJ2, S3C2440_GPJ2_CAMDATA2);

s3c2410_gpio_cfgpin(S3C2440_GPJ3, S3C2440_GPJ3_CAMDATA3);

s3c2410_gpio_cfgpin(S3C2440_GPJ4, S3C2440_GPJ4_CAMDATA4);

s3c2410_gpio_cfgpin(S3C2440_GPJ5, S3C2440_GPJ5_CAMDATA5);

s3c2410_gpio_cfgpin(S3C2440_GPJ6, S3C2440_GPJ6_CAMDATA6);

s3c2410_gpio_cfgpin(S3C2440_GPJ7, S3C2440_GPJ7_CAMDATA7);

s3c2410_gpio_cfgpin(S3C2440_GPJ8, S3C2440_GPJ8_CAMPCLK);

s3c2410_gpio_cfgpin(S3C2440_GPJ9, S3C2440_GPJ9_CAMVSYNC);

s3c2410_gpio_cfgpin(S3C2440_GPJ10, S3C2440_GPJ10_CAMHREF);

s3c2410_gpio_cfgpin(S3C2440_GPJ11, S3C2440_GPJ11_CAMCLKOUT);

s3c2410_gpio_cfgpin(S3C2440_GPJ12, S3C2440_GPJ12_CAMRESET);

申请CAMIF的寄存器区域,由于OS的系统统一管理,所以,需要确定,该寄存器区域没有被别的进程获取,所以要申请。

/* init camera's virtual memory. */

if (!request_mem_region((unsigned long)S3C2440_PA_CAMIF, S3C2440_SZ_CAMIF, CARD_NAME))

{

ret = -EBUSY;

goto error1;

}

申请到了寄存器区域,相当于物理地址可用,然后,再将该物理地址映射到虚拟地址。

/* remap the virtual memory. */

camif_base_addr = (unsigned long)ioremap_nocache((unsigned long)S3C2440_PA_CAMIF, S3C2440_SZ_CAMIF);

if (camif_base_addr == (unsigned long)NULL)

{

ret = -EBUSY;

goto error2;

}

相关文档
最新文档