新手上路
- 积分
- 37
- 金钱
- 37
- 注册时间
- 2020-6-13
- 在线时间
- 5 小时
|
7金钱
自己根据视频编写了蜂鸣器的驱动,先用depmod,后modprobe加载驱动,设备号自动申请失败,求大神帮忙看看哪里出问题了,源码如下
#define BEEPDEV_CNT 1
#define BEEPDEV_NAME "beep"
#define BEEP_ON 1
#define BEEP_OFF 0
struct mybeep_dev {
dev_t devid;
int major;
int minor;
struct cdev cdev;
struct class *class;
struct device *device;
struct device_node *nd;
int beep_gpio;
};
struct mybeep_dev mybeep;
static int mybeep_open(struct inode *inode, struct file *filp)
{
filp->private_data = &mybeep;
return 0;
}
static ssize_t mybeep_write(struct file *filp, const char __user *buf, size_t cnt, loff_t *offt)
{
int ret = 0;
struct mybeep_dev *dev = (struct mybeep_dev *)filp->private_data;
unsigned char databuff[1];
unsigned char beep_status;
ret = copy_from_user(databuff, buf, cnt);
if(ret < 0) {
printk("kernel write failed!\r\n");
return -EFAULT;
}
beep_status = databuff[0];
if(beep_status == BEEP_OFF) {
gpio_set_value(dev->beep_gpio, 0);
} else if (beep_status == BEEP_ON) {
gpio_set_value(dev->beep_gpio, 1);
}
return 0;
}
static int mybeep_release(struct inode *inode, struct file *filp)
{
return 0;
}
static const struct file_operations mybeep_filp = {
.owner = THIS_MODULE,
.open = mybeep_open,
.write = mybeep_write,
.release = mybeep_release,
};
static int __init mybeep_init(void)
{
int ret = 0;
/* init devid */
if (mybeep.major) {
mybeep.devid = MKDEV(mybeep.major, 0);
register_chrdev_region(mybeep.devid, BEEPDEV_CNT, BEEPDEV_NAME);
} else {
ret = alloc_chrdev_region(&mybeep.devid, 0, BEEPDEV_CNT, BEEPDEV_NAME);
if (ret < 0) {
goto fail_devid;
}
mybeep.major = MAJOR(mybeep.devid);
mybeep.minor = MINOR(mybeep.devid);
printk("beep major = %d minor = %d\n", mybeep.major, mybeep.minor);
}
/* init cdev */
mybeep.cdev.owner = THIS_MODULE;
cdev_init(&mybeep.cdev, &mybeep_filp);
ret = cdev_add(&mybeep.cdev, mybeep.devid, BEEPDEV_CNT);
if (ret < 0) {
goto fail_cdev;
}
/* create class */
mybeep.class = class_create(THIS_MODULE, BEEPDEV_NAME);
if (IS_ERR(mybeep.class)) {
goto fail_class;
}
/* create device */
mybeep.device = device_create(mybeep.class, NULL, mybeep.devid, NULL, BEEPDEV_NAME);
if (IS_ERR(mybeep.device)) {
goto fail_device;
}
mybeep.nd = of_find_node_by_path("/beep");
if (mybeep.nd == NULL) {
ret = -EINVAL;
goto fail_findnd;
}
mybeep.beep_gpio = of_get_named_gpio(mybeep.nd, "beep-gpio", 0);
if (mybeep.beep_gpio < 0) {
ret = -EINVAL;
goto fail_getgpio;
}
ret = gpio_request(mybeep.beep_gpio, "beepgpio");
if (ret < 0) {
goto fail_reqgpio;
}
ret = gpio_direction_output(mybeep.beep_gpio, 1);
if (ret < 0) {
goto fail_setdirevtion;
}
fail_devid:
printk("alloc devid failed\r\n");
unregister_chrdev_region(mybeep.devid, BEEPDEV_CNT);
return ret;
fail_cdev:
printk("add cdev failed\r\n");
unregister_chrdev_region(mybeep.devid, BEEPDEV_CNT);
return ret;
fail_class:
printk("create class failed\r\n");
cdev_del(&mybeep.cdev);
return PTR_ERR(mybeep.class);
fail_device:
printk("create device failed\r\n");
class_destroy(mybeep.class);
return PTR_ERR(mybeep.device);
fail_findnd:
printk("not find beep node\r\n");
device_destroy(mybeep.class, mybeep.devid);
return ret;
fail_getgpio:
printk("cant get beep gpio number\r\n");
return ret;
fail_reqgpio:
printk("cant request gpio\r\n");
gpio_free(mybeep.beep_gpio);
return ret;
fail_setdirevtion:
printk("set gpio direction failed\r\n");
return ret;
return 0;
}
static void __exit mybeep_exit(void)
{
unregister_chrdev_region(mybeep.devid, BEEPDEV_CNT);
cdev_del(&mybeep.cdev);
class_destroy(mybeep.class);
device_destroy(mybeep.class, mybeep.devid);
gpio_free(mybeep.beep_gpio);
}
module_init(mybeep_init);
module_exit(mybeep_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("chuixue");
|
|