Linux I2C总线控制器驱动(S3C2440)(4)

s3c2440_i2c_regs->iicadd  = 0x10;    // S3C24xx slave address = [7:1]
    s3c2440_i2c_regs->iicstat = 0x10;    // I2C串行输出使能(Rx/Tx)
}

static int i2c_bus_s3c2440_init(void)
{
    /* 2. 硬件相关的设置 */
    s3c2440_i2c_regs = ioremap(0x54000000, sizeof(struct s3c2440_i2c_regs));//映射功能寄存器
   
    s3c2440_i2c_init(); //初始化i2c控制器

request_irq(IRQ_IIC, s3c2440_i2c_xfer_irq, 0, "s3c2440-i2c", NULL); //申请中断源,加载中断处理函数-s3c2440_i2c_xfer_irq

init_waitqueue_head(&s3c2440_i2c_xfer_data.wait); //初始化一个等待队列头
   
    /* 3. 注册i2c_adapter */
    i2c_add_adapter(&s3c2440_i2c_adapter);
   
    return 0;
}

static void i2c_bus_s3c2440_exit(void)
{
    i2c_del_adapter(&s3c2440_i2c_adapter);   
    free_irq(IRQ_IIC, NULL);
    iounmap(s3c2440_i2c_regs);
}

module_init(i2c_bus_s3c2440_init);
module_exit(i2c_bus_s3c2440_exit);
MODULE_LICENSE("GPL");

附一份测试程序:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "i2c-dev.h"


/* i2c_usr_test </dev/i2c-0> <dev_addr> r addr
 * i2c_usr_test </dev/i2c-0> <dev_addr> w addr val
 */

void print_usage(char *file)
{
    printf("%s </dev/i2c-0> <dev_addr> r addr\n", file);
    printf("%s </dev/i2c-0> <dev_addr> w addr val\n", file);
}

int main(int argc, char **argv)
{
    int fd;
    unsigned char addr, data;
    int dev_addr;
   
    if ((argc != 5) && (argc != 6))
    {
        print_usage(argv[0]);
        return -1;
    }

fd = open(argv[1], O_RDWR);
    if (fd < 0)
    {
        printf("can't open %s\n", argv[1]);
        return -1;
    }

dev_addr = strtoul(argv[2], NULL, 0);
    if (ioctl(fd, I2C_SLAVE, dev_addr) < 0)
    {   
        /* ERROR HANDLING; you can check errno to see what went wrong */   
        printf("set addr error!\n");
        return -1;
    }

if (strcmp(argv[3], "r") == 0)
    {
        addr = strtoul(argv[4], NULL, 0);
       
        data = i2c_smbus_read_word_data(fd, addr);
           
        printf("data: %c, %d, 0x%2x\n", data, data, data);
    }
    else if ((strcmp(argv[3], "w") == 0) && (argc == 6))
    {
        addr = strtoul(argv[4], NULL, 0);
        data = strtoul(argv[5], NULL, 0);
        i2c_smbus_write_byte_data(fd, addr, data);       
    }
    else
    {
        print_usage(argv[0]);
        return -1;
    }
   
    return 0;
}

Make File:

KERN_DIR = /work/system/linux-3.4.2

all:
    make -C $(KERN_DIR) M=`pwd` modules

clean:
    make -C $(KERN_DIR) M=`pwd` modules clean
    rm -rf modules.order

obj-m    += i2c_bus_s3c2440.o

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/50d322c3f56eb4d1846acdcb8741af1b.html