首先修改设备树
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/ide.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/gpio.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/of_gpio.h>
#include <linux/semaphore.h>
#include <linux/timer.h>
#include <linux/spi/spi.h>
#include <asm/mach/map.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <linux/delay.h>
#define ICM20608_CNT 1
#define ICM20608_NAME "icm20608"
//设备结构体
struct icm20608_dev {
dev_t devid; /* 设备号 */
struct cdev cdev; /* cdev */
struct class *class; /* 类 */
struct device *device; /* 设备 */
struct device_node *nd; /* 设备节点 */
int major; /* 主设备号 */
int minor; //次设备号
void *private_data; /* 私有数据 */
};
static struct icm20608_dev icm20608dev;
static int icm20608_release(struct inode *inode, struct file *filp)
{
return 0;
}
static int icm20608_open(struct inode *inode, struct file *filp)
{
filp->private_data = &icm20608dev; /* 设置私有数据 */
return 0;
}
static ssize_t icm20608_read(struct file *filp, char __user *buf, size_t cnt, loff_t *off)
{
return 0;
}
/* icm20608操作函数 */
static const struct file_operations icm20608_ops = {
.owner = THIS_MODULE,
.open = icm20608_open,
.read = icm20608_read,
.release = icm20608_release,
};
static int icm20608_probe(struct spi_device *spi)
{
int ret = 0;
/* 1、构建设备号 */
if (icm20608dev.major) {
icm20608dev.devid = MKDEV(icm20608dev.major, 0);
register_chrdev_region(icm20608dev.devid, ICM20608_CNT, ICM20608_NAME);
} else {
alloc_chrdev_region(&icm20608dev.devid, 0, ICM20608_CNT, ICM20608_NAME);
icm20608dev.major = MAJOR(icm20608dev.devid);
icm20608dev.minor = MINOR(icm20608dev.devid);
}
printk("major:%d,minor=%d\r\n",icm20608dev.major,icm20608dev.minor);
/* 2、注册设备 */
cdev_init(&icm20608dev.cdev, &icm20608_ops);
cdev_add(&icm20608dev.cdev, icm20608dev.devid, ICM20608_CNT);
/* 3、创建类 */
icm20608dev.class = class_create(THIS_MODULE, ICM20608_NAME);
if (IS_ERR(icm20608dev.class)) {
return PTR_ERR(icm20608dev.class);
}
/* 4、创建设备 */
icm20608dev.device = device_create(icm20608dev.class, NULL, icm20608dev.devid, NULL, ICM20608_NAME);
if (IS_ERR(icm20608dev.device)) {
return PTR_ERR(icm20608dev.device);
}
icm20608dev.private_data = spi; /* 设置私有数据 */
return ret;
}
static int icm20608_remove(struct spi_devide *spi)
{
int ret = 0;
return ret;
}
//传统匹配
struct spi_device_id icm206080_id[] = {
{"alientek,icm20608",0},
{}
};
//设备树匹配
static const struct of_device_id icm20608_of_match[] = {
{.compatible = "alientek,icm20608"},
{}
};
//spi_driver
struct spi_driver icm20608_driver = {
.probe = icm20608_probe,
.remove = icm20608_probe,
.driver = {
.name = "icm20608", //无设备树时用名字和设备匹配
.owner = THIS_MODULE,
.of_match_table = icm20608_of_match, //有设备树时,用设备树匹配表
},
.id_table = icm206080_id,
};
//驱动入口函数
static int __init icm20608_init(void)
{
int ret;
return spi_register_driver(&icm20608_driver);
return ret;
}
//驱动出口函数
static void __exit icm20608_exit(void)
{
spi_unregister_driver(&icm20608_driver);
}
module_init(icm20608_init);
module_exit(icm20608_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("DENG");