嵌入式LINUX驱动学习之15 i2c代码举例(三轴加速度传感器MMA8653)方式二

嵌入式LINUX驱动学习之15 i2c代码举例(三轴加速度传感器MMA8653)方式二


本实例是通过i2c_new_device函数添加I2C设备,相比于板级添加,减少了去源码中查看启动函数的麻烦

一、代码举例

#include <linux/init.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/fs.h>
#include <linux/miscdevice.h>
#include <linux/uaccess.h>
#include <linux/slab.h>
void mma8653_state(void);
void mma8653_action(void);
static long my_ioctl(struct file * file ,unsigned int ucmd,unsigned long ubuf);
struct i2c_client *g_cli = NULL;
struct i2c_adapter *i2c_adp_obj = NULL;
struct mma8653_state_struct *mma8653_state_obj = NULL;
struct i2c_board_info i2c_dev_obj[] = {
    
    
    {
    
    
        I2C_BOARD_INFO("my_mma8653_drv",0x1D)
    }
};
struct mma8653_state_struct {
    
    
    int x;
    int y;
    int z;
};
struct file_operations f_ops={
    
    
    .owner = THIS_MODULE,
    .unlocked_ioctl = my_ioctl
};
struct miscdevice misc_ops = {
    
    
    .minor = MISC_DYNAMIC_MINOR,
    .fops  = &f_ops,
    .name = "mma8653_ioctl"
};

static int mma8653_test_init(void){
    
    
    i2c_adp_obj = i2c_get_adapter(2);
    g_cli = i2c_new_device(i2c_adp_obj,i2c_dev_obj);
    misc_register(&misc_ops);
    printk("%s\n",__func__);
    return 0;
}
static void mma8653_test_exit(void){
    
    
    misc_deregister(&misc_ops);
    i2c_unregister_device(g_cli);
    printk("%s\n",__func__);
}

static long my_ioctl(struct file * file,unsigned int ucmd,unsigned long ubuf){
    
    
    int copy_ret = 0;
    if(!g_cli){
    
    
        printk("设备打开失败!\n");
        return -EIO;
    }
    mma8653_state_obj = (struct mma8653_state_struct *) \
                        kmalloc(sizeof(mma8653_state_obj),GFP_KERNEL);
    mma8653_action();
    mma8653_state();
    copy_ret = copy_to_user((struct mma8653_state_struct *)ubuf,\
                  mma8653_state_obj,sizeof(struct mma8653_state_struct));
    kfree(mma8653_state_obj);
    return 0;
}

void mma8653_state(void){
    
    
    int mma8653_x,mma8653_y,mma8653_z;
    mma8653_x = (i2c_smbus_read_byte_data(g_cli, 0x01) << 2 ) |\
                (i2c_smbus_read_byte_data(g_cli,0x2) >> 6 );
    mma8653_y = (i2c_smbus_read_byte_data(g_cli, 0x03) << 2 ) |\
                (i2c_smbus_read_byte_data(g_cli,0x4) >> 6 );
    mma8653_z = (i2c_smbus_read_byte_data(g_cli, 0x05) << 2 ) |\
                (i2c_smbus_read_byte_data(g_cli,0x6) >> 6 );
    if(mma8653_x & (0x1 << 9))
        mma8653_x = ((mma8653_x & 0x3ff) & ~(0x1 << 9)) - (0x1 << 9);
    if(mma8653_y & (0x1 << 9))
        mma8653_y = ((mma8653_y & 0x3ff) & ~(0x1 << 9)) - (0x1 << 9);
    if(mma8653_z & (0x1 << 9))
        mma8653_z = ((mma8653_z & 0x3ff) & ~(0x1 << 9)) - (0x1 << 9);
    mma8653_state_obj -> x = mma8653_x;
    mma8653_state_obj -> y = mma8653_y;
    mma8653_state_obj -> z = mma8653_z;
}
void mma8653_action(void){
    
    
    int data;
    data= i2c_smbus_read_byte_data(g_cli, 0x2a);
    data|= 1;
    i2c_smbus_write_byte_data(g_cli,0x2a,data);
}

module_init(mma8653_test_init);
module_exit(mma8653_test_exit);
MODULE_LICENSE("GPL");

二、用户空间程序(参考方式一)

猜你喜欢

转载自blog.csdn.net/weixin_47273317/article/details/108462681