新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 3.4.2內核下I2C驅動之24CXX實例

        3.4.2內核下I2C驅動之24CXX實例

        作者: 時間:2016-11-21 來源:網絡 收藏
        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 = 0xxn", 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 %dn", __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 %dn", __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 addrn", file);
        printf("%s w addr valn", 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("cant open /dev/at24cxxn");
        return -1;
        }
        if (strcmp(argv[1], "r") == 0)
        {
        buf[0] = strtoul(argv[2], NULL, 0);
        read(fd, buf, 1);
        printf("data: %c, %d, 0x%2xn", 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 = 0xxn", 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



        評論


        技術專區

        關閉
        主站蜘蛛池模板: 忻城县| 兖州市| 中山市| 泽普县| 金川县| 监利县| 望谟县| 永城市| 长寿区| 青河县| 宁晋县| 寿光市| 全州县| 乐至县| 五华县| 安龙县| 昭平县| 韩城市| 临沧市| 尼木县| 湘阴县| 鹰潭市| 怀来县| 临潭县| 三亚市| 龙岩市| 石景山区| 新昌县| 宕昌县| 宜章县| 玉龙| 都江堰市| 庆安县| 临武县| 鄂托克前旗| 平凉市| 抚州市| 宁乡县| 名山县| 墨脱县| 晋中市|