主题 : 求救 用tiny210v2开发板的p4引脚拓展的buttons和leds不能用呀!!怎么办 复制链接 | 浏览器收藏 | 打印
级别: 新手上路
UID: 99179
精华: 0
发帖: 15
金钱: 75 两
威望: 15 点
综合积分: 30 分
注册时间: 2013-12-20
最后登录: 2014-01-16
楼主  发表于: 2013-12-26 10:46

 求救 用tiny210v2开发板的p4引脚拓展的buttons和leds不能用呀!!怎么办

我使用tiny210v2开发板p4(1,3,4,7,9,11,13,15)口的CAM_B_D0~CAM_B_D7(即gpj0(0)~gpj0(7))引脚拓展出的led驱动和buttons都无法使用,用软件测试时引脚没反应终端也没反应,但是在p4(2,4,6,8,10,12,14)(XINT20~34,XINT28~31即gph2(4.5.67)和gph2(4.5.6.7))可以正常使用。源码就是就是友善之臂的leds和buttons的驱动只是改了gpio口。是不是内核中有驱动已经占用了这些gpio口呀,有的话该怎么改?使这个led驱动能用?

led驱动:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/types.h>
#include <linux/moduleparam.h>
#include <linux/slab.h>
#include <linux/ioctl.h>
#include <linux/cdev.h>
#include <linux/delay.h>

#include <mach/gpio.h>
#include <mach/regs-gpio.h>
#include <plat/gpio-cfg.h>


#define DEVICE_NAME "my_leds"

static int led_gpios[] = {
    S5PV210_GPJ0(0),
    S5PV210_GPJ0(1),
    S5PV210_GPJ0(2),
    S5PV210_GPJ0(3),
    S5PV210_GPJ0(4),
    S5PV210_GPJ0(5),#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/poll.h>
#include <linux/irq.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <linux/interrupt.h>
#include <asm/uaccess.h>
#include <mach/hardware.h>
#include <linux/platform_device.h>
#include <linux/cdev.h>
#include <linux/miscdevice.h>

#include <mach/map.h>
#include <mach/gpio.h>
#include <mach/regs-clock.h>
#include <mach/regs-gpio.h>

#define DEVICE_NAME        "my_buttons"

struct button_desc {
    int gpio;
    int number;
    char *name;    
    struct timer_list timer;
};

static struct button_desc buttons[] = {
    { S5PV210_GPJ0(0), 0, "KEY0" },
    { S5PV210_GPJ0(1), 1, "KEY1" },
    { S5PV210_GPJ0(2), 2, "KEY2" },
    { S5PV210_GPJ0(3), 3, "KEY3" },
    { S5PV210_GPJ0(4), 4, "KEY4" },
    { S5PV210_GPJ0(5), 5, "KEY5" },
    { S5PV210_GPJ0(6), 6, "KEY6" },
    { S5PV210_GPJ0(6), 7, "KEY7" },
};

static volatile char key_values[] = {
    '0', '0', '0', '0', '0', '0', '0', '0'
};

static DECLARE_WAIT_QUEUE_HEAD(button_waitq);

static volatile int ev_press = 0;

static void mini210_buttons_timer(unsigned long _data)
{
    struct button_desc *bdata = (struct button_desc *)_data;
    int down;
    int number;
    unsigned tmp;

    tmp = gpio_get_value(bdata->gpio);

    /* active low */
    down = !tmp;
    printk("KEY %d: %08x\n", bdata->number, down);

    number = bdata->number;
    if (down != (key_values[number] & 1)) {
        key_values[number] = '0' + down;

        ev_press = 1;
        wake_up_interruptible(&button_waitq);
    }
}

static irqreturn_t button_interrupt(int irq, void *dev_id)
{
    struct button_desc *bdata = (struct button_desc *)dev_id;

    mod_timer(&bdata->timer, jiffies + msecs_to_jiffies(40));

    return IRQ_HANDLED;
}

static int mini210_buttons_open(struct inode *inode, struct file *file)
{
    int irq;
    int i;
    int err = 0;

    for (i = 0; i < ARRAY_SIZE(buttons); i++) {
        if (!buttons.gpio)
            continue;

        setup_timer(&buttons.timer, mini210_buttons_timer,
                (unsigned long)&buttons);

        irq = gpio_to_irq(buttons.gpio);
        err = request_irq(irq, button_interrupt, IRQ_TYPE_EDGE_BOTH,
                buttons.name, (void *)&buttons);
        if (err)
            break;
    }

    if (err) {
        i--;
        for (; i >= 0; i--) {
            if (!buttons.gpio)
                continue;

            irq = gpio_to_irq(buttons.gpio);
            disable_irq(irq);
            free_irq(irq, (void *)&buttons);

            del_timer_sync(&buttons.timer);
        }

        return -EBUSY;
    }

    ev_press = 1;
    return 0;
}

static int mini210_buttons_close(struct inode *inode, struct file *file)
{
    int irq, i;

    for (i = 0; i < ARRAY_SIZE(buttons); i++) {
        if (!buttons.gpio)
            continue;

        irq = gpio_to_irq(buttons.gpio);
        free_irq(irq, (void *)&buttons);

        del_timer_sync(&buttons.timer);
    }

    return 0;
}

static int mini210_buttons_read(struct file *filp, char __user *buff,
        size_t count, loff_t *offp)
{
    unsigned long err;

    if (!ev_press) {
        if (filp->f_flags & O_NONBLOCK)
            return -EAGAIN;
        else
            wait_event_interruptible(button_waitq, ev_press);
    }

    ev_press = 0;

    err = copy_to_user((void *)buff, (const void *)(&key_values),
            min(sizeof(key_values), count));

    return err ? -EFAULT : min(sizeof(key_values), count);
}

static unsigned int mini210_buttons_poll( struct file *file,
        struct poll_table_struct *wait)
{
    unsigned int mask = 0;

    poll_wait(file, &button_waitq, wait);
    if (ev_press)
        mask |= POLLIN | POLLRDNORM;

    return mask;
}

static struct file_operations dev_fops = {
    .owner        = THIS_MODULE,
    .open        = mini210_buttons_open,
    .release    = mini210_buttons_close,
    .read        = mini210_buttons_read,
    .poll        = mini210_buttons_poll,
};

static struct miscdevice misc = {
    .minor        = MISC_DYNAMIC_MINOR,
    .name        = DEVICE_NAME,
    .fops        = &dev_fops,
};

static int __init button_dev_init(void)
{
    int ret;

    ret = misc_register(&misc);

    printk(DEVICE_NAME"\tinitialized\n");

    return ret;
}

static void __exit button_dev_exit(void)
{
    misc_deregister(&misc);
}

module_init(button_dev_init);
module_exit(button_dev_exit);

MODULE_LICENSE("GPL");

    S5PV210_GPJ0(6),
    S5PV210_GPJ0(7),
};

#define LED_NUM        ARRAY_SIZE(led_gpios)


static long mini210_leds_ioctl(struct file *filp, unsigned int cmd,
        unsigned long arg)
{
    switch(cmd) {
        case 0:
        case 1:
            if (arg > LED_NUM) {
                return -EINVAL;
            }

            gpio_set_value(led_gpios[arg], !cmd);
            //printk(DEVICE_NAME": %d %d\n", arg, cmd);
            break;

        default:
            return -EINVAL;
    }

    return 0;
}

static struct file_operations mini210_led_dev_fops = {
    .owner            = THIS_MODULE,
    .unlocked_ioctl    = mini210_leds_ioctl,
};

static struct miscdevice mini210_led_dev = {
    .minor            = MISC_DYNAMIC_MINOR,
    .name            = DEVICE_NAME,
    .fops            = &mini210_led_dev_fops,
};

static int __init mini210_led_dev_init(void) {
    int ret;
    int i;

    for (i = 0; i < LED_NUM; i++) {
        ret = gpio_request(led_gpios, "my_LED");
        if (ret) {
            printk("%s: request GPIO %d for LED failed, ret = %d\n", DEVICE_NAME,
                    led_gpios, ret);
            return ret;
        }

        s3c_gpio_cfgpin(led_gpios, S3C_GPIO_OUTPUT);
        gpio_set_value(led_gpios, 1);
    }

    ret = misc_register(&mini210_led_dev);

    printk(DEVICE_NAME"\tinitialized\n");

    return ret;
}

static void __exit mini210_led_dev_exit(void) {
    int i;

    for (i = 0; i < LED_NUM; i++) {
        gpio_free(led_gpios);
    }

    misc_deregister(&mini210_led_dev);
}

module_init(mini210_led_dev_init);
module_exit(mini210_led_dev_exit);

MODULE_LICENSE("GPL");


buttons驱动:

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/poll.h>
#include <linux/irq.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <linux/interrupt.h>
#include <asm/uaccess.h>
#include <mach/hardware.h>
#include <linux/platform_device.h>
#include <linux/cdev.h>
#include <linux/miscdevice.h>

#include <mach/map.h>
#include <mach/gpio.h>
#include <mach/regs-clock.h>
#include <mach/regs-gpio.h>

#define DEVICE_NAME        "my_buttons"

struct button_desc {
    int gpio;
    int number;
    char *name;    
    struct timer_list timer;
};

static struct button_desc buttons[] = {
    { S5PV210_GPJ0(0), 0, "KEY0" },
    { S5PV210_GPJ0(1), 1, "KEY1" },
    { S5PV210_GPJ0(2), 2, "KEY2" },
    { S5PV210_GPJ0(3), 3, "KEY3" },
    { S5PV210_GPJ0(4), 4, "KEY4" },
    { S5PV210_GPJ0(5), 5, "KEY5" },
    { S5PV210_GPJ0(6), 6, "KEY6" },
    { S5PV210_GPJ0(6), 7, "KEY7" },
};

static volatile char key_values[] = {
    '0', '0', '0', '0', '0', '0', '0', '0'
};

static DECLARE_WAIT_QUEUE_HEAD(button_waitq);

static volatile int ev_press = 0;

static void mini210_buttons_timer(unsigned long _data)
{
    struct button_desc *bdata = (struct button_desc *)_data;
    int down;
    int number;
    unsigned tmp;

    tmp = gpio_get_value(bdata->gpio);

    /* active low */
    down = !tmp;
    printk("KEY %d: %08x\n", bdata->number, down);

    number = bdata->number;
    if (down != (key_values[number] & 1)) {
        key_values[number] = '0' + down;

        ev_press = 1;
        wake_up_interruptible(&button_waitq);
    }
}

static irqreturn_t button_interrupt(int irq, void *dev_id)
{
    struct button_desc *bdata = (struct button_desc *)dev_id;

    mod_timer(&bdata->timer, jiffies + msecs_to_jiffies(40));

    return IRQ_HANDLED;
}

static int mini210_buttons_open(struct inode *inode, struct file *file)
{
    int irq;
    int i;
    int err = 0;

    for (i = 0; i < ARRAY_SIZE(buttons); i++) {
        if (!buttons.gpio)
            continue;

        setup_timer(&buttons.timer, mini210_buttons_timer,
                (unsigned long)&buttons);

        irq = gpio_to_irq(buttons.gpio);
        err = request_irq(irq, button_interrupt, IRQ_TYPE_EDGE_BOTH,
                buttons.name, (void *)&buttons);
        if (err)
            break;
    }

    if (err) {
        i--;
        for (; i >= 0; i--) {
            if (!buttons.gpio)
                continue;

            irq = gpio_to_irq(buttons.gpio);
            disable_irq(irq);
            free_irq(irq, (void *)&buttons);

            del_timer_sync(&buttons.timer);
        }

        return -EBUSY;
    }

    ev_press = 1;
    return 0;
}

static int mini210_buttons_close(struct inode *inode, struct file *file)
{
    int irq, i;

    for (i = 0; i < ARRAY_SIZE(buttons); i++) {
        if (!buttons.gpio)
            continue;

        irq = gpio_to_irq(buttons.gpio);
        free_irq(irq, (void *)&buttons);

        del_timer_sync(&buttons.timer);
    }

    return 0;
}

static int mini210_buttons_read(struct file *filp, char __user *buff,
        size_t count, loff_t *offp)
{
    unsigned long err;

    if (!ev_press) {
        if (filp->f_flags & O_NONBLOCK)
            return -EAGAIN;
        else
            wait_event_interruptible(button_waitq, ev_press);
    }

    ev_press = 0;

    err = copy_to_user((void *)buff, (const void *)(&key_values),
            min(sizeof(key_values), count));

    return err ? -EFAULT : min(sizeof(key_values), count);
}

static unsigned int mini210_buttons_poll( struct file *file,
        struct poll_table_struct *wait)
{
    unsigned int mask = 0;

    poll_wait(file, &button_waitq, wait);
    if (ev_press)
        mask |= POLLIN | POLLRDNORM;

    return mask;
}

static struct file_operations dev_fops = {
    .owner        = THIS_MODULE,
    .open        = mini210_buttons_open,
    .release    = mini210_buttons_close,
    .read        = mini210_buttons_read,
    .poll        = mini210_buttons_poll,
};

static struct miscdevice misc = {
    .minor        = MISC_DYNAMIC_MINOR,
    .name        = DEVICE_NAME,
    .fops        = &dev_fops,
};

static int __init button_dev_init(void)
{
    int ret;

    ret = misc_register(&misc);

    printk(DEVICE_NAME"\tinitialized\n");

    return ret;
}

static void __exit button_dev_exit(void)
{
    misc_deregister(&misc);
}

module_init(button_dev_init);
module_exit(button_dev_exit);

MODULE_LICENSE("GPL");


级别: 新手上路
UID: 99179
精华: 0
发帖: 15
金钱: 75 两
威望: 15 点
综合积分: 30 分
注册时间: 2013-12-20
最后登录: 2014-01-16
1楼  发表于: 2013-12-26 11:00

 回 楼主(william.sun) 的帖子

代码复制时没复制好代码如下
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/sched.h>
#include <linux/poll.h>
#include <linux/irq.h>
#include <asm/irq.h>
#include <asm/io.h>
#include <linux/interrupt.h>
#include <asm/uaccess.h>
#include <mach/hardware.h>
#include <linux/platform_device.h>
#include <linux/cdev.h>
#include <linux/miscdevice.h>

#include <mach/map.h>
#include <mach/gpio.h>
#include <mach/regs-clock.h>
#include <mach/regs-gpio.h>

#define DEVICE_NAME        "my_buttons"

struct button_desc {
    int gpio;
    int number;
    char *name;    
    struct timer_list timer;
};

static struct button_desc buttons[] = {
    { S5PV210_GPJ0(0), 0, "KEY0" },
    { S5PV210_GPJ0(1), 1, "KEY1" },
    { S5PV210_GPJ0(2), 2, "KEY2" },
    { S5PV210_GPJ0(3), 3, "KEY3" },
    { S5PV210_GPJ0(4), 4, "KEY4" },
    { S5PV210_GPJ0(5), 5, "KEY5" },
    { S5PV210_GPJ0(6), 6, "KEY6" },
    { S5PV210_GPJ0(7), 7, "KEY7" },
};

static volatile char key_values[] = {
    '0', '0', '0', '0', '0', '0', '0', '0'
};

static DECLARE_WAIT_QUEUE_HEAD(button_waitq);

static volatile int ev_press = 0;

static void mini210_buttons_timer(unsigned long _data)
{
    struct button_desc *bdata = (struct button_desc *)_data;
    int down;
    int number;
    unsigned tmp;

    tmp = gpio_get_value(bdata->gpio);

    /* active low */
    down = !tmp;
    printk("KEY %d: %08x\n", bdata->number, down);

    number = bdata->number;
    if (down != (key_values[number] & 1)) {
        key_values[number] = '0' + down;

        ev_press = 1;
        wake_up_interruptible(&button_waitq);
    }
}

static irqreturn_t button_interrupt(int irq, void *dev_id)
{
    struct button_desc *bdata = (struct button_desc *)dev_id;

    mod_timer(&bdata->timer, jiffies + msecs_to_jiffies(40));

    return IRQ_HANDLED;
}

static int mini210_buttons_open(struct inode *inode, struct file *file)
{
    int irq;
    int i;
    int err = 0;

    for (i = 0; i < ARRAY_SIZE(buttons); i++) {
        if (!buttons.gpio)
            continue;

        setup_timer(&buttons.timer, mini210_buttons_timer,
                (unsigned long)&buttons);

        irq = gpio_to_irq(buttons.gpio);
        err = request_irq(irq, button_interrupt, IRQ_TYPE_EDGE_BOTH,
                buttons.name, (void *)&buttons);
        if (err)
            break;
    }

    if (err) {
        i--;
        for (; i >= 0; i--) {
            if (!buttons.gpio)
                continue;

            irq = gpio_to_irq(buttons.gpio);
            disable_irq(irq);
            free_irq(irq, (void *)&buttons);

            del_timer_sync(&buttons.timer);
            printk("get gpio failed");
        }

        return -EBUSY;
    }

    ev_press = 1;
    return 0;
}

static int mini210_buttons_close(struct inode *inode, struct file *file)
{
    int irq, i;

    for (i = 0; i < ARRAY_SIZE(buttons); i++) {
        if (!buttons.gpio)
            continue;

        irq = gpio_to_irq(buttons.gpio);
        free_irq(irq, (void *)&buttons);

        del_timer_sync(&buttons.timer);
    }

    return 0;
}

static int mini210_buttons_read(struct file *filp, char __user *buff,
        size_t count, loff_t *offp)
{
    unsigned long err;

    if (!ev_press) {
        if (filp->f_flags & O_NONBLOCK)
            return -EAGAIN;
        else
            wait_event_interruptible(button_waitq, ev_press);
    }

    ev_press = 0;

    err = copy_to_user((void *)buff, (const void *)(&key_values),
            min(sizeof(key_values), count));

    return err ? -EFAULT : min(sizeof(key_values), count);
}

static unsigned int mini210_buttons_poll( struct file *file,
        struct poll_table_struct *wait)
{
    unsigned int mask = 0;

    poll_wait(file, &button_waitq, wait);
    if (ev_press)
        mask |= POLLIN | POLLRDNORM;

    return mask;
}

static struct file_operations dev_fops = {
    .owner        = THIS_MODULE,
    .open        = mini210_buttons_open,
    .release    = mini210_buttons_close,
    .read        = mini210_buttons_read,
    .poll        = mini210_buttons_poll,
};

static struct miscdevice misc = {
    .minor        = MISC_DYNAMIC_MINOR,
    .name        = DEVICE_NAME,
    .fops        = &dev_fops,
};

static int __init button_dev_init(void)
{
    int ret;

    ret = misc_register(&misc);

    printk(DEVICE_NAME"\tinitialized\n");

    return ret;
}

static void __exit button_dev_exit(void)
{
    misc_deregister(&misc);
}

module_init(button_dev_init);
module_exit(button_dev_exit);

MODULE_LICENSE("GPL");
自由,自强,共享,共创。
级别: 论坛版主
UID: 12573
精华: 27
发帖: 8838
金钱: 46490 两
威望: 9298 点
综合积分: 18216 分
注册时间: 2010-01-09
最后登录: 2019-07-16
2楼  发表于: 2013-12-26 11:11
可以多多使用grep搜索命令,来搜索内核源代码
新手如何向我们反馈有效的信息,以便解决问题,见此贴:
http://www.arm9home.net/read.php?tid-14431.html

[注]: 此处签名链接仅为指引方向,而非解答问题本身.
级别: 新手上路
UID: 99179
精华: 0
发帖: 15
金钱: 75 两
威望: 15 点
综合积分: 30 分
注册时间: 2013-12-20
最后登录: 2014-01-16
3楼  发表于: 2013-12-26 11:30


我搜了 [root@FriendlyARM /home]# grep -r "S5PV210_GPJ0(0)"  十几分钟了没反应,估计是搜错了,不知道谁占用了他怎么搜呀,

没用过grep
级别: 新手上路
UID: 99179
精华: 0
发帖: 15
金钱: 75 两
威望: 15 点
综合积分: 30 分
注册时间: 2013-12-20
最后登录: 2014-01-16
4楼  发表于: 2013-12-26 11:57

 回 2楼(mindee) 的帖子

大神回来呀!