RK驱动小结

printk打印

P.S.关于调试信息,一般rk自己的相关驱动在.c前面会有个debug全局变量,讲这个初始值改为3以上即可以打开所有编译条件。
关于dev_dbg,可以参考http://blog.chinaunix.net/uid-20672559-id-3383042.html
用户态更改调试打印等级,通过读写/proc/sys/kernel/printk文件可读取和修改控制台的日志级别。查看这个文件的方法如下:
cat /proc/sys/kernel/printk
6 6 1 7
上面显示的4个数据分别对应:

#define KERN_SOH	"\001"		/* ASCII Start Of Header */
#define KERN_SOH_ASCII	'\001'

#define KERN_EMERG	KERN_SOH "0"	/* system is unusable */
#define KERN_ALERT	KERN_SOH "1"	/* action must be taken immediately */
#define KERN_CRIT	KERN_SOH "2"	/* critical conditions */
#define KERN_ERR	KERN_SOH "3"	/* error conditions */
#define KERN_WARNING	KERN_SOH "4"	/* warning conditions */
#define KERN_NOTICE	KERN_SOH "5"	/* normal but significant condition */
#define KERN_INFO	KERN_SOH "6"	/* informational */
#define KERN_DEBUG	KERN_SOH "7"	/* debug-level messages */
#define KERN_DEFAULT	KERN_SOH "d"	/* the default kernel loglevel */

  	console_loglevel  /* 当前控制台日志级别,所有printk打印级别必须小于(不包含等于)这个等级才能被输出,比如当前为6,则KERN_INFO级别不能被输出*/
	default_message_loglevel /* KERN_DEFAULT或者不指定等级如printk(“HelloWorld”)对应的等级 */
	minimum_console_loglevel  /* 支持的最小等级 */
	default_console_loglevel /* 默认为7,与console_loglevel的默认值一致 */

可用下面的命令设置当前日志级别:
echo “7 6 1 7” > /proc/sys/kernel/printk
kmesg打印增加打印缓冲大小
make menuconfig -> General Setup -> Kernel log buffer size

1.摄像头

随着视频设备功能复杂化(音视频合成,编解码等),v4l2的框架也越来越复杂,在linux3.0中用一个比较粗糙的图来表现他们之间的关系,大致为:
设备实例(v4l2_device)
|______子设备实例(v4l2_subdev)
|______视频设备节点(video_device)
|______文件访问控制(v4l2_fh)
|______视频缓冲的处理(videobuf/videobuf2)
详细框架可以参考http://blog.csdn.net/rubyboss/article/details/14053523

①rk3128_cif_sensor.dtsi中有“rockchip,sensor”的设备描述符,主要描述IIC地址、通道、cif时钟频率等等信息;
rk312x.dtsi中有"rockchip,cif"的设备描述符,主要描述rk312x的时钟名、中断号等;
②rk_camera.c中主要就是“rockchip,sensor”和"rockchip,cif"的驱动;
其中rk_dts_sensor_probe主要完成IIC地址、通道、时钟频率的获取,并且创建new_camera,填充信息后被链接到new_camera_head队列,这个结构体中有rk_sensor_ioctrl这个函数,可以完成摄像头的时钟设定、电源开关、复位功能,时钟在rk_sensor_pwrseq被调用的时候设定,rk_sensor_power在软件上规定只能是24M或者48M;
而rk_dts_cif_probe相对简单,主要完成中断等等其他硬件资源的获取;
③rk30_camera.c调用rk_camera_platform_data.sensor_register,会将new_camera_head队列中的所有camera都以"soc-camera-pdrv"作为platform设备名注册;soc_camera.c中的"soc-camera-pdrv"驱动主要任务就是为每一个new_camera节点创建一个icd设备并且加入到icd设备列表,icd中有video_device(v4l2标准设备);
④rk_camera中注册的两个driver获取到的信息最终都会保存在rk_device_camera_host_0这个platform_device,其名字为RK29_CAM_DRV_NAME(它在rk30_camera.c文件中被注册).
RK29_CAM_DRV_NAME对应的platform_driver有两个(只选其中一个):
rk30_camera_pingpong.c
rk30_camera_oneframe.c
以上两个driver在probe函数中调用soc_camera_host_register(soc_camera.c),作用为遍历icd设备列表,依次注册标准的v4l2_device(包含于soc_camera_host *ici),接下来,通过scan_add_host注册video_device (包含于soc_camera_device *icd,icd中有soc_camera_desc,这个结构体分为host_desc,代指的是总线adapter,subdev_desc代指的就是摄像头i2c或者spi控制器),并且添加v4l2标准fops操作函数。scan_add_host中还会以subdev_desc中的i2c地址信息,进行i2c_new_probed_device,创建i2c设备。
⑤ov5640.c这样的文件通过文件尾部的宏定义,最终会生成以SENSOR_NAME(如“ov5640_front_3”)为id_table的i2c_driver,当存在对应的subdev时,驱动执行,作用为向对应的subdev中注册subdev_ops;在ov5640.c中主要就是几组寄存器的配置,他们分别对应SEQUENCE_INIT、SEQUENCE_PREVIEW等各个显示模式,他们有各自有独立的分辨率跟帧率,这些寄存器组会被generic_sensor.h转化成二维数组群,存放在senser_seriers中;另外还有几组色彩配置寄存器值,用于相应ctrl_cmd。

综上,可以认为rk_camera.c和rk30_camera.c为设备侧文件,而rk30_camera_pingpong.c/rk30_camera_oneframe.c、soc_camera.c和ov5640.c为驱动侧文件。其中可以在soc_camera.c中找到最直观的v4l2操作函数,这些函数大部分都是对rk30_camera_pingpong.c/rk30_camera_oneframe.c中的rk_soc_camera_host_ops进行封装,而rk_soc_camera_host_ops中的关于调光、白平衡等控制操作,实际上是通过subdev_fops的i2c传输完成。
另外,分析驱动,发现rk只做了yuv输入,并没有做jpeg的支持,如果需要添加,可能涉及的文件:
1.添加ov5640.c的寄存器组;
2.对于rk30_camera_oneframe.c,rk_camera_setup_format需要先添加对应格式的cif寄存器设置;
3.在rk_camera_get_formats中添加对应的上报数据格式。

摄像头借口

一般使用CIF或者RGB作为接口的摄像头模块上面都会集成ISP
一般使用MIPI作为接口的摄像头都需要主控芯片内置ISP或者外置ISP,对于rk3288的Android系统,ISP的支持都存放在camera的Hal层:
hardware/rockchip/camera/SiliconImage/isi/drv/

关于usb摄像头的镜像问题,尝试过在rockchip的hal上面修改,无效,最终在framework中修改:
/frameworks/av/services/camera/libcameraservice/api1/CameraClient.cpp 中的getOrientation返回,强行设置为HAL_TRANSFORM_FLIP_H

2.DTS分析

3.GPIO

4.FB

显示屏驱动分成四大块:
①Linux标准的屏幕驱动fb;
②lcdc,液晶控制接口,包括一些电源控制等的硬件操作;
③screen结构是一个屏幕的抽象,里面包含了屏幕的display_timing;
④收发器:常见的收发器包括edp、mipi:
edp的时钟一般为1.62G或者2.7G;
mipi的时钟(dsi_host_clk)可以是90M~1.5G,且这个频率必须根据屏幕数据量计算得出:100+H_totalV_totalfps38/lanes,其中100是rk3288由于时钟误差原因而需要添加的修正,H_total是 水平有效像素+水平前沿+水平后延+水平同步时钟长度,V_total同理,fps是屏幕的刷新频率,可以根据screen中的像素时钟计算得出,lanes是实际mipi借口的数据线宽,3代表一个像素大小是3Bytes。

5.PMU

以RK818作为例子,首先rk818作为一个IIC设备,在rk3128-sdk.dts中的i2c0总线上有作为子节点的设备描述符,其

6.DDR

8.时钟

你可能感兴趣的:(Linux驱动)