嵌入式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");