您的位置:首页 > 产品设计 > 产品经理

6/25/2011 9:30:09 PM

2011-06-25 22:55 316 查看
6/25/2011 9:30:09 PM

struct platform_device {
const char * name;
u32 id;
struct device dev;
u32 num_resources;
struct resource * resource;
};

平台设备包含了名字 ID 设备 资源等

驱动来探测设备

struct pxafb_mach_info

描述机器信息

也就是所谓的设备的平台数据

首先检测各寄存器的值,看这些值是否有效

struct pxafb_info {
struct fb_info fb;

封装了fb_info等

fbi = kmalloc(sizeof(struct pxafb_info) + sizeof(u32) * 16, GFP_KERNEL);

注意后面还预留了16个int

接着对结构体 pxafb_info 进行赋值

struct fb_ops 描述了fb的操作方法

static struct fb_ops pxafb_ops = {
.owner = THIS_MODULE,
.fb_check_var = pxafb_check_var,
.fb_set_par = pxafb_set_par,
.fb_setcolreg = pxafb_setcolreg,
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
.fb_blank = pxafb_blank,
.fb_mmap = pxafb_mmap,
#ifdef CONFIG_FB_PXA_MINILCD
.fb_ioctl = pxafb_minilcd_ioctl,
#elif defined(CONFIG_FB_PXA_LCD_TPO)
.fb_ioctl = pxafb_lcd_ioctl,
#endif
};

pxafb_check_var 检查可变参数

看看上层是怎么设置的?

ov2_info->fd = open("/dev/fb2", O_RDWR);

首先打开设备

接着设置了可变参数

struct fb_var_screeninfo var;

err = ioctl(fd, FBIOPUT_VSCREENINFO, &var);

struct fb_var_screeninfo {
__u32 xres; /* visible resolution */
__u32 yres;
__u32 xres_virtual; /* virtual resolution */
__u32 yres_virtual;
__u32 xoffset; /* offset from virtual to visible */
__u32 yoffset; /* resolution */

__u32 bits_per_pixel; /* guess what */
__u32 grayscale; /* != 0 Graylevels instead of colors */

struct fb_bitfield red; /* bitfield in fb mem if true color, */
struct fb_bitfield green; /* else only length is significant */
struct fb_bitfield blue;
struct fb_bitfield transp; /* transparency */

__u32 nonstd; /* != 0 Non standard pixel format */

__u32 activate; /* see FB_ACTIVATE_* */

__u32 height; /* height of picture in mm */
__u32 width; /* width of picture in mm */

__u32 accel_flags; /* (OBSOLETE) see fb_info.flags */

/* Timing: All values in pixclocks, except pixclock (of course) */
__u32 pixclock; /* pixel clock in ps (pico seconds) */
__u32 left_margin; /* time from sync to picture */
__u32 right_margin; /* time from picture to sync */
__u32 upper_margin; /* time from sync to picture */
__u32 lower_margin;
__u32 hsync_len; /* length of horizontal sync */
__u32 vsync_len; /* length of vertical sync */
__u32 sync; /* see FB_SYNC_* */
__u32 vmode; /* see FB_VMODE_* */
__u32 rotate; /* angle we rotate counter clockwise */
__u32 reserved[5]; /* Reserved for future compatibility */
};

if (var->xres < MIN_XRES)
var->xres = MIN_XRES;
if (var->yres < MIN_YRES)
var->yres = MIN_YRES;

也就是说最小打开的也是16*16的

if (var->xres > fbi->max_xres)
var->xres = fbi->max_xres;
if (var->yres > fbi->max_yres)
var->yres = fbi->max_yres;
var->xres_virtual =
max(var->xres_virtual, var->xres);
var->yres_virtual =
max(var->yres_virtual, var->yres);

也不能超过实际最大值

x y 的虚拟坐标也取最大值

接着设置RGB的位数

初试化等待队列

static void pxafb_task(struct work_struct *work)
{
struct pxafb_info *fbi =
container_of(work, struct pxafb_info, task);
u_int state = xchg(&fbi->task_state, -1);

set_ctrlr_state(fbi, state);
}

注意这个work_struct

pxafb_disable_controller disable掉控制器

typedef struct __wait_queue wait_queue_t;
typedef int (*wait_queue_func_t)(wait_queue_t *wait, unsigned mode, int sync, void *key);
int default_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key);

struct __wait_queue {
unsigned int flags;
#define WQ_FLAG_EXCLUSIVE 0x01
void *private;
wait_queue_func_t func;
struct list_head task_list;
};

声明了一个等待队列

down(&fcs_lcd_sem);
add_wait_queue(&fbi->ctrlr_wait, &wait);

将到fbi的等待队列中

#define LCSR __REG_2(0x44000038) /* LCD Controller Status Register */

LCD 的状态寄存器

/*
* 0x42000000 - 0x421fffff <--> 0xf8000000 - 0xf81fffff MMC2 & USIM2
* 0x43000000 - 0x430fffff <--> 0xf8200000 - 0xf82fffff Caddo
* 0x43100000 - 0x431fffff <--> 0xf8300000 - 0xf83fffff NAND
* 0x44000000 - 0x440fffff <--> 0xf8400000 - 0xf84fffff LCD
* 0x46000000 - 0x460fffff <--> 0xf8800000 - 0xf88fffff Mini LCD
* 0x48100000 - 0x481fffff <--> 0xf8d00000 - 0xf8dfffff Dynamic Mem Ctl
* 0x4a000000 - 0x4a0fffff <--> 0xf9000000 - 0xf90fffff Static Mem Ctl
* 0x4c000000 - 0x4c0fffff <--> 0xf9400000 - 0xf94fffff USB Host
*/

#define io_p2v_2(x) (((((x) - 0x42000000) & 0xff000000) >> 3) + 0xf8000000/
+ ((x) & 0x001fffff))
#define io_v2p_2(x) (((((x) & 0xffe00000) - 0xf8000000) << 3) + 0x42000000/
+ (x & 0x001fffff))

LCD的地址映射关系

系统给LCD 预留有1M的地址空间

schedule_timeout 调用超时

如果输入参数为 MAX_SCHEDULE_TIMEOUT

就表示是一个完整的调用,不需要中间进行截断

否则还需要使用一个定时器

建立了一个定时器 定时唤醒本进程的

setup_timer(&timer, process_timeout, (unsigned long)current);
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: