3.4.2内核下I2C驱动之24CXX实例

发布者:和谐相伴最新更新时间:2016-03-31 来源: eefocus关键字:3.4.2内核  I2C驱动  24CXX实例 手机看文章 扫描二维码
随时随地手机看文章
at24cxx_dev.c部分:
 
#include "linux/kernel.h"
#include "linux/module.h"
#include "linux/platform_device.h"
#include "linux/i2c.h"
#include "linux/err.h"
#include "linux/regmap.h"
#include "linux/slab.h"
 
static struct i2c_board_info at24cxx_info = {    
    I2C_BOARD_INFO("at24c08", 0x50),
};
 
static struct i2c_client *at24cxx_client;
 
static int at24cxx_dev_init(void)
{
    struct i2c_adapter *i2c_adap;
 
    i2c_adap = i2c_get_adapter(0);
    at24cxx_client = i2c_new_device(i2c_adap, &at24cxx_info);
    i2c_put_adapter(i2c_adap);
    
    return 0;
}
 
static void at24cxx_dev_exit(void)
{
    i2c_unregister_device(at24cxx_client);
}
 
module_init(at24cxx_dev_init);
module_exit(at24cxx_dev_exit);
MODULE_LICENSE("GPL");
 
=================================================================
at24cxx_drv.c部分:
 
#include "linux/kernel.h"
#include "linux/module.h"
#include "linux/platform_device.h"
#include "linux/i2c.h"
#include "linux/err.h"
#include "linux/regmap.h"
#include "linux/slab.h"
#include "linux/fs.h"
#include "asm/uaccess.h"
 
static int major;
static struct class *class;
static struct i2c_client *at24cxx_client;
 
// 传入: buf[0] : addr
// 输出: buf[0] : data
//
static ssize_t at24cxx_read(struct file * file, char __user *buf, size_t count, loff_t *off)
{
    unsigned char addr, data;
    
    copy_from_user(&addr, buf, 1);
    data = i2c_smbus_read_byte_data(at24cxx_client, addr);
    copy_to_user(buf, &data, 1);
    return 1;
}
 
// buf[0] : addr
// buf[1] : data
//
static ssize_t at24cxx_write(struct file *file, const char __user *buf, size_t count, loff_t *off)
{
    unsigned char ker_buf[2];
    unsigned char addr, data;
 
    copy_from_user(ker_buf, buf, 2);
    addr = ker_buf[0];
    data = ker_buf[1];
 
    printk("addr = 0xx, data = 0xx\n", addr, data);
 
    if (!i2c_smbus_write_byte_data(at24cxx_client, addr, data))
        return 2;
    else
        return -EIO;    
}
 
static struct file_operations at24cxx_fops = {
    .owner = THIS_MODULE,
    .read  = at24cxx_read,
    .write = at24cxx_write,
};
 
static int __devinit at24cxx_probe(struct i2c_client *client,
                  const struct i2c_device_id *id)
{
    at24cxx_client = client;
        
    //printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
    major = register_chrdev(0, "at24cxx", &at24cxx_fops);
    class = class_create(THIS_MODULE, "at24cxx");
    device_create(class, NULL, MKDEV(major, 0), NULL, "at24cxx"); // /dev/at24cxx //
    
    return 0;
}
 
static int __devexit at24cxx_remove(struct i2c_client *client)
{
    //printk("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
    device_destroy(class, MKDEV(major, 0));
    class_destroy(class);
    unregister_chrdev(major, "at24cxx");
        
    return 0;
}
 
static const struct i2c_device_id at24cxx_id_table[] = {
    { "at24c08", 0 },
    {}
};
 
 
// 1. 分配/设置i2c_driver //
static struct i2c_driver at24cxx_driver = {
    .driver    = {
        .name    = "100ask",
        .owner   = THIS_MODULE,
    },
    .probe       = at24cxx_probe,
    .remove    = __devexit_p(at24cxx_remove),
    .id_table    = at24cxx_id_table,
};
 
static int at24cxx_drv_init(void)
{
    // 2. 注册i2c_driver //
    i2c_add_driver(&at24cxx_driver);
    
    return 0;
}
 
static void at24cxx_drv_exit(void)
{
    i2c_del_driver(&at24cxx_driver);
}
 
module_init(at24cxx_drv_init);
module_exit(at24cxx_drv_exit);
MODULE_LICENSE("GPL");
 
=================================================================
i2c_test.c测试程序:
 
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "sys/types.h"
#include "sys/stat.h"
#include "fcntl.h"
 
// i2c_test r addr
// i2c_test w addr val
 
void print_usage(char *file)
{
    printf("%s r addr\n", file);
    printf("%s w addr val\n", file);
}
 
int main(int argc, char **argv)
{
    int fd;
    unsigned char buf[2];
    
    if ((argc != 3) && (argc != 4))
    {
        print_usage(argv[0]);
        return -1;
    }
 
    fd = open("/dev/at24cxx", O_RDWR);
    if (fd " 0)
    {
        printf("can't open /dev/at24cxx\n");
        return -1;
    }
 
    if (strcmp(argv[1], "r") == 0)
    {
        buf[0] = strtoul(argv[2], NULL, 0);
        read(fd, buf, 1);
        printf("data: %c, %d, 0x%2x\n", buf[0], buf[0], buf[0]);
    }
    else if ((strcmp(argv[1], "w") == 0) && (argc == 4))
    {
        buf[0] = strtoul(argv[2], NULL, 0);
        buf[1] = strtoul(argv[3], NULL, 0);
        if (write(fd, buf, 2) != 2)
            printf("write err, addr = 0xx, data = 0xx\n", buf[0], buf[1]);
    }
    else
    {
        print_usage(argv[0]);
        return -1;
    }
    
    return 0;
}
 
================================================================
Makefile:
 
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        += at24cxx_dev.o
obj-m        += at24cxx_drv.o
#obj-m += i2c_bus_s3c2440.o

关键字:3.4.2内核  I2C驱动  24CXX实例 引用地址:3.4.2内核下I2C驱动之24CXX实例

上一篇:ARM问答
下一篇:Linux2.6.22内核移植

推荐阅读最新更新时间:2024-03-16 14:48

基于S3c2440的I2C驱动与测试程序追踪交叉分析
VMware虚拟机+Fedora10, 硬件平台TQ2440, 内核2.6.30.4 对应的驱动程序豁然开朗, 然后自己添加了一些dev_dbg后, 对于不理解的地方也有了一定的参考提示, 记录下来与大家分享。 测试程序如下: /*i2c_test.c * hongtao_liu */ #include #include #include #include #include #include #include #include #define I2C_RETRIES 0x0701 #define I2C_ TI MEOUT 0x0702 #define I2C_RDWR 0x0707 /*********定义struct i
[单片机]
基于WinCE的I2C驱动程序设计
引言     随着以计算机技术、通信技术和软件技术为核心的信息技术的迅速发展,嵌入式系统在各行业得到了广泛的应用,极大地推动了行业的渗透性应用。     嵌入式系统是“以应用为中心、以计算机技术为基础、软硬件可裁剪、适应应用系统对功能、可靠性、成本、体积、功耗严格要求的专用计算机系统”,由嵌入式硬件和嵌入式软件两部分组成。嵌入式软件包括嵌入式操作系统和嵌入式应用软件。Microsoft的桌面操作系统已经为人们熟悉和使用,嵌入式的操作系统Windows CE.net也日益风行。Windows CE.net是Microsoft推出的功能强大的紧凑、高效、可伸缩的32位嵌入式操作系统,主要面对各种各样的嵌入式系统和产品。该系统
[嵌入式]
基于I2C接口的LED驱动器设计与实现
   LED 无疑是当前最热的一个应用,无论是手持设备、游戏机、 霓虹灯 、广告牌等等,眩目的色彩及高质的光亮,总能第一时间吸引人的眼球。在当前众多的LED控制器面前,如何选择一款功能丰富且性价比又高的产品来迎合自己的设计,无疑是摆在每个设计师面前的问题。   最简单的 LED驱动 ,我们可以用普通的I/O来实现。但I/O控制只能实现LED的 ON 与OFF,无法用来进行混光、闪烁等功能,而且每个LED都需要占用一个单独的I/O资源,无疑性价比很低。我们也可以用专用的大电流LED控制器来设计,但昂贵的成本首先会成为问题,而且设计复杂,程度也会跟着各种干扰的出现相应地提高。基于这些,恩智浦( NXP )推出一系列使用I2C 接口 的L
[家用电子]
基于<font color='red'>I2C</font>接口的LED<font color='red'>驱动</font>器设计与实现
I2C总线在Linux系统中的驱动设计
  1 引言       Linux操作系统因具有源代码公开、便于裁减、有广泛的处理器支持等优点,成为当前嵌入式系统的热门选择。基于I2C总线的键盘扩展设备主要用于满足嵌入式设备中对多按键的需求,驱动程序在系统启动时对硬件进行初始化。在系统启动后实现硬件和应用程序之间的数据交互。针对 S3C2410 微处理器和键盘扫描管理器件,深入讨论如何在嵌入式操作系统ARM Linux中实现 ZLG7290 的驱动。 2 I2C总线    I2C总线是器件间串行传输总线,以其规范和带I2C接口的外围器件获得广泛应用。 S3C2410 处理器内置有I2C总线接口。I2C总线是由数据线SDA和时钟SCL构成的串行总线,可发送和
[嵌入式]
基于I2C的OSD显示驱动设计与实现
随着汽车工业的发展,车载导航设备得到了越来越多的应用。现在主流的车载导航设备都集成有DVD功能,对视频处理提出较高要求。选择高性能平台和高性能视频处理器对车载导航设备有十分重要的意义。同时,对于音量的可视性控制和DVD控制来说,OSD技术具有很大的优越性,它可以在不影响DVD画面的基础上叠加在屏幕上,降低了主处理器的工作量。PXA270处理器具有领先的高性能和低功耗功能,宏芯T128D具有强大的视频处理功能,同时集成了两层OSD处理引擎,两者通过I2C总线连接可以大大提高车载导航设备的多媒体处理功能,本文陈述了在两者基础上通过I2C总线连接实现OSD显示驱动的方法。 1 基本原理 1.1 OSD显示原理 OSD(On Scr
[电源管理]
基于<font color='red'>I2C</font>的OSD显示<font color='red'>驱动</font>设计与实现
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved