#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //宏定义 #define SMPLRT_DIV 0x19 #define CONFIG 0x1A #define GYRO_CONFIG 0x1B #define ACCEL_CONFIG 0x1C #define ACCEL_XOUT_H 0x3B #define ACCEL_XOUT_L 0x3C #define ACCEL_YOUT_H 0x3D #define ACCEL_YOUT_L 0x3E #define ACCEL_ZOUT_H 0x3F #define ACCEL_ZOUT_L 0x40 #define TEMP_OUT_H 0x41 #define TEMP_OUT_L 0x42 #define GYRO_XOUT_H 0x43 #define GYRO_XOUT_L 0x44 #define GYRO_YOUT_H 0x45 #define GYRO_YOUT_L 0x46 #define GYRO_ZOUT_H 0x47 #define GYRO_ZOUT_L 0x48 #define PWR_MGMT_1 0x6B #define WHO_AM_I 0x75 #define SlaveAddress 0xD0 #define Address 0x68 //MPU6050地址 #define I2C_RETRIES 0x0701 #define I2C_TIMEOUT 0x0702 #define I2C_SLAVE 0x0703 //IIC从器件的地址设置 #define I2C_BUS_MODE 0x0780 static struct mpu6050_dev{ struct cdev c_dev; dev_t devno; struct class *class; struct device *device; struct i2c_client *client; }; static int i2c_write_mpu6050(struct i2c_client *mpu6050_client, u8 address, u8 data) { int error = 0; u8 write_data[2]; struct i2c_msg send_msg; //要发送的数据结构体 /*设置要发送的数据*/ write_data[0] = address; write_data[1] = data; /*发送 iic要写入的地址 reg*/ send_msg.addr = mpu6050_client->addr; //mpu6050在 iic 总线上的地址 send_msg.flags = 0; //标记为发送数据 send_msg.buf = write_data; //写入的首地址 send_msg.len = 2; //reg长度 /*执行发送*/ error = i2c_transfer(mpu6050_client->adapter, &send_msg, 1); if (error != 1) { pr_err("\n i2c_transfer error \n"); return -1; } return 0; } static int i2c_read_mpu6050(struct i2c_client *mpu6050_client, u8 address, void *data, u32 length) { return 0; } static int mpu6050_init(struct i2c_client *mpu6050_client) { int error = 0; /*配置mpu6050*/ error += i2c_write_mpu6050(mpu6050_client, PWR_MGMT_1, 0X00); error += i2c_write_mpu6050(mpu6050_client, SMPLRT_DIV, 0X07); error += i2c_write_mpu6050(mpu6050_client, CONFIG, 0X06); error += i2c_write_mpu6050(mpu6050_client, ACCEL_CONFIG, 0X01); if (error < 0) { /*初始化错误*/ pr_err("\n mpu6050_init error \n"); return -1; } return 0; } /*字符设备操作函数集,open函数实现*/ static int mpu6050_open(struct inode *inode, struct file *filp) { struct mpu6050_dev *mpu = NULL; mpu = container_of(inode->i_cdev, struct mpu6050_dev, c_dev); filp->private_data = mpu; return mpu6050_init(mpu); } /*字符设备操作函数集,.read函数实现*/ static ssize_t mpu6050_read(struct file *filp, char __user *buf, size_t cnt, loff_t *off) { return 0; } /*字符设备操作函数集,.release函数实现*/ static int mpu6050_release(struct inode *inode, struct file *filp) { return 0; } /*字符设备操作函数集*/ static struct file_operations mpu6050_chr_dev_fops = { .owner = THIS_MODULE, .open = mpu6050_open, .read = mpu6050_read, .release = mpu6050_release, }; static struct mpu6050_dev mpu6050dev; /*i2c总线设备函数集*/ static int mpu6050_probe(struct i2c_client *client, const struct i2c_device_id *id) { int ret = 0; ret = alloc_chrdev_region(&(mpu6050dev.devno),0,1,"mpu6050"); if(ret < 0){ pr_err("chrdev alloc region failed\n"); return ret; } pr_info("devno is %u(major:%u,minor:%u)\n",mpu6050dev.devno,MAJOR(mpu6050dev.devno), MINOR(mpu6050dev.devno)); cdev_init(&mpu6050dev.c_dev, &mpu6050_chr_dev_fops); mpu6050dev.c_dev.owner = THIS_MODULE; ret = cdev_add(&mpu6050dev.c_dev, mpu6050dev.devno, 1); if(ret < 0){ pr_err("chrdev add failed\n"); goto cdev_add_err; } ret = class_create(THIS_MODULE, "mpu_class"); if(IS_ERR(ret)) { pr_err("create class faild!/n"); goto class_create_err; } mpu6050dev.class = ret; ret = device_create(mpu6050dev.class,NULL,devno,NULL,"mpu6050"); if(IS_ERR(ret)) { pr_err("device_create failed\n"); goto device_create_err; } mpu6050dev.device = ret; mpu6050dev.client = client; return 0; device_create_err: class_destroy(mpu6050dev.class); class_create_err: cdev_del(&mpu6050dev.c_dev); cdev_add_err: unregister_chrdev_region(mpu6050dev.devno, 1); return ret; } static int mpu6050_remove(struct i2c_client *client) { device_destroy(mpu6050dev.class, mpu6050dev.device); class_destroy(mpu6050dev.class); cdev_del(&mpu6050dev.c_dev); unregister_chrdev_region(mpu6050dev.devno, 1); return 0; } /*定义ID 匹配表*/ static const struct i2c_device_id gtp_device_id[] = { {"fire,i2c_mpu6050", 0}, {}}; /*定义设备树匹配表*/ static const struct of_device_id mpu6050_of_match_table[] = { {.compatible = "fire,i2c_mpu6050"}, {/* sentinel */}}; /*定义i2c总线设备结构体*/ struct i2c_driver mpu6050_driver = { .probe = mpu6050_probe, .remove = mpu6050_remove, .id_table = gtp_device_id, .driver = { .name = "fire,i2c_mpu6050", .owner = THIS_MODULE, .of_match_table = mpu6050_of_match_table, }, }; /* * 驱动初始化函数 */ static int __init mpu6050_driver_init(void) { int ret; pr_info("mpu6050_driver_init\n"); ret = i2c_add_driver(&mpu6050_driver); return 0; } /* * 驱动注销函数 */ static void __exit mpu6050_driver_exit(void) { pr_info("mpu6050_driver_exit\n"); i2c_del_driver(&mpu6050_driver); } module_init(mpu6050_driver_init); module_exit(mpu6050_driver_exit); MODULE_LICENSE("GPL");