Chinaunix首页 | 论坛 | 博客
  • 博客访问: 635467
  • 博文数量: 121
  • 博客积分: 8469
  • 博客等级: 中将
  • 技术积分: 1065
  • 用 户 组: 普通用户
  • 注册时间: 2008-07-03 10:32
文章分类

全部博文(121)

文章存档

2013年(1)

2012年(15)

2010年(2)

2009年(8)

2008年(95)

我的朋友

分类: LINUX

2008-09-01 10:44:12

linux-2.6.9

PXA27x I2C总线驱动driver/i2c/busses/i2c_adap_pxa.c
首先设置GPIO属性:
#ifdef CONFIG_PXA27x    /* set i2c command & data GPIO */
        pxa_gpio_mode(GPIO117_I2CSCL_MD);
        pxa_gpio_mode(GPIO118_I2CSDA_MD);
#endif

初始化等待队列
init_waitqueue_head(&i2c_wait);

申请中断
request_irq(IRQ_I2C, &i2c_pxa_handler, SA_INTERRUPT, "I2C_PXA", 0)
申请成功后使能中断
enable_irq(irq);
i2c_pxa_handler中断处理函数负责唤醒等待队列i2c_wait。
static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id, struct pt_regs *regs)
{
    int status, wakeup = 0;
    status = (ISR);

    if (status & ISR_BED){
        (ISR) |= ISR_BED;
        bus_error=ISR_BED;
        wakeup = 1;
    }
    if (status & ISR_ITE){
        (ISR) |= ISR_ITE;
        tx_finished=ISR_ITE;
        wakeup = 1;
    }
    if (status & ISR_IRF){
        (ISR) |= ISR_IRF;
        rx_finished=ISR_IRF;
        wakeup = 1;
    }
    if (wakeup) {
        i2c_pending = 1;
        wake_up_interruptible(&i2c_wait);
    }
    return IRQ_HANDLED;
}


两个重要结构
struct i2c_algorithm i2c_pxa_algorithm  = {
    .name             =    "PXA I2C Algorithm",
    .id             =     I2C_ALGO_PXA,
    .master_xfer      =     i2c_pxa_xfer,
   .functionality     =     i2c_pxa_functionality,    
};

static struct i2c_adapter i2c_pxa_ops = {
    .owner        = THIS_MODULE,
    .id            = I2C_ALGO_PXA,
    .name        = "PXA i2c adapter",
    .algo_data    = &i2c_pxa_data,
    .retries    = 2,
};



其中i2c_adapter的成员algo_data,类型是void *,在PXA的驱动里它指向了结构
struct i2c_algo_pxa_data
{
        void (*write_byte) (u8 value);
        u8   (*read_byte) (void);
        void (*start) (void);
        void (*repeat_start) (void);
        void (*stop) (void);
        void (*abort) (void);
        int  (*wait_bus_not_busy) (void);
        int  (*wait_for_interrupt) (int wait_type);
        void (*transfer) (int lastbyte, int receive, int midbyte);
        void (*reset) (void);

    int udelay;
    int timeout;
};


该结构提供了读写控制等的接口。
比如:
static struct i2c_algo_pxa_data i2c_pxa_data = {
    write_byte:        i2c_pxa_write_byte,
    read_byte:        i2c_pxa_read_byte,

    start:            i2c_pxa_start,
    repeat_start:    i2c_pxa_repeat_start,
    stop:            i2c_pxa_stop,
    abort:            i2c_pxa_abort,

    wait_bus_not_busy:    i2c_pxa_wait_bus_not_busy,
    wait_for_interrupt:    i2c_pxa_wait_for_int,
    transfer:        i2c_pxa_transfer,
    reset:            i2c_pxa_reset,

    udelay:            10,
    timeout:        DEF_TIMEOUT,
};


其中的i2c_pxa_write_byte定义如下:
/* place a byte in the transmit register */
static void i2c_pxa_write_byte(u8 value)
{
    IDBR = value;
}


初始化adapter的algorithm:
i2c_adap->algo = &i2c_pxa_algorithm;

注册adapter:
i2c_pxa_add_bus(&i2c_pxa_ops);
该函数调用了i2c_add_adapter(i2c_adap);来注册总线驱动。



阅读(3192) | 评论(1) | 转发(0) |
给主人留下些什么吧!~~

chinaunix网友2009-04-27 10:41:17

版主,请教下,我现在用的也是LINUX2.6.9 CPU 用PXA270 怎么在linux中加载SPI(DMA) 2.6.9 DRIVER中没有SPI 文件夹。要自己建个字符型设备么?能给模板么?我的邮箱是nnnn_777@163.com