Problem with GPIO portB access on the p1021rdb

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Problem with GPIO portB access on the p1021rdb

2,187 Views
alfonsokame
Contributor III

Hi,

i m struggling to set the pins of the GPIO PORTB high using a GPIO driver.

For Example PB4, PB6, PB7.

is there any documentation on how to configure the pins in the device tree and how to use it in the kernel?

The problem is here that these seems to be qe pins and there is apparently no gpio controller in the p1021rdb.

I already activated qe and qe_gpio in the kernel.

I tried to configure the gpios in the device tree, but the call of the function gpio_direction_output(36, 1)  in my simple driver probe fails.

1.- Is there any Documentation about how to configure and use P1021 (qe) GPIOs?

2.- Which gpio number corresponds to PB 4?

4- How to get the relevant GPIO pins successfully requested using the device tree?

It looks like the sysfs gpio for the p1021 does'nt work

Im struggling for days to get it work, please help. Thanks

When I use code Codewarrior and the USB Tap. I can toggle those pins successfully using the CPDIR and CPDAT register.

Thanks very much for your reply!


Nachricht geändert durch alfonso kame

Labels (1)
0 Kudos
5 Replies

834 Views
alfonsokame
Contributor III

I tried out this code but the pins still dont work on the p1021.

What am I missing here?

Thanks

#include <linux/fs.h>

#include <linux/cdev.h>

#include <linux/kernel.h>

#include <linux/sched.h>

#include <linux/spinlock.h>

#include <linux/slab.h>

#include <linux/mm.h>

static struct MyGPIO* MyGPIO;

static const char* MODULENAME  = "P1021_GPIO";

static const u32 ccsr_gut_base = 0xffee0000;

static const u32 ccsr_gut_length = 0x1000;

/*

* @gpio:

* @value: 0..2

*     0: disabled

*     1: out

*     2: in

*     3: in and out

*/

int MyGPIO_SetDirection(unsigned int gpio, u8 value)

{

    u8 status = -1;

    u32 tmp, offset;

    spin_lock(&MyGPIO->gpio_lock);

    offset = 0x128;

    switch(value){

        case 0:

        break;

        case 1:  //out 01

            tmp = in_be32(MyGPIO->gpio_base + offset);

            tmp &= ~(1<<(31 - (gpio * 2))); //

            tmp |= (1<<(30 - (gpio * 2))); //

            out_be32(MyGPIO->gpio_base + offset, tmp);

            tmp = in_be32(MyGPIO->gpio_base + offset);

            if(tmp & (1<<(30 - (gpio * 2))))

                status = 1;

            else {

                printk(KERN_ERR "%s gpio nr %d direction write error\n", __func__, gpio);

                status = -2;

            }

        break;

        case 2: //in 10

            tmp = in_be32(MyGPIO->gpio_base + offset);

            tmp |= (1<<(31 - (gpio * 2))); //

            tmp &= ~(1<<(30 - (gpio * 2))); //

            out_be32(MyGPIO->gpio_base + offset, tmp);

            tmp = in_be32(MyGPIO->gpio_base + offset);

            if(tmp & (1<<(31 - (gpio * 2))))

                status = 1;

            else {

                printk(KERN_ERR "%s gpio nr %d direction write error\n", __func__, gpio);

                status = -2;

            }

        break;

        case 3: //in and out 11

            tmp = in_be32(MyGPIO->gpio_base + offset);

            tmp |= (1<<(31 - (gpio * 2))); //

            tmp |= (1<<(30 - (gpio * 2))); //

            out_be32(MyGPIO->gpio_base + offset, tmp);

            tmp = in_be32(MyGPIO->gpio_base + offset);

            if((tmp & (1<<(31 - (gpio * 2)))) && (tmp & (1<<(30 - (gpio * 2)))))

                status = 1;

            else {

                printk(KERN_ERR "%s gpio nr %d direction write error\n", __func__, gpio);

                status = -2;

            }

        break;

        default:

        break;

    }

    spin_unlock(&MyGPIO->gpio_lock);

    return status;

}

/*

*/

int MyGPIO_write(const unsigned int _gpio, bool value)

{

    u8 status;

    u32 tmp, offset;

    u32 gpio;

    spin_lock(&MyGPIO->gpio_lock);

    gpio = _gpio;

    offset = 0x124;

    tmp = in_be32(MyGPIO->gpio_base + offset);

 

    if(value){

        tmp |= (1<<(31 - gpio)); //

        out_be32((MyGPIO->gpio_base + offset), tmp);

        tmp = in_be32(MyGPIO->gpio_base + offset);

        if((tmp & (1<<(31 - gpio))) == (1<<(31-gpio)))

            status = 1;

        else {

            printk(KERN_ERR "%s gpio nr %d write error\n", __func__, gpio);

            status = -2;

        }

    } else {

        tmp &= ~(1<<(31 - gpio)); //

        out_be32(MyGPIO->gpio_base + offset, tmp);

        tmp = in_be32(MyGPIO->gpio_base + offset);

        if((tmp & (1<<(31 - gpio))) == 0)

            status = 1;

        else {

            printk(KERN_ERR "%s gpio nr %d write error\n", __func__, gpio);

            status = -2;

        }

    }

    spin_unlock(&MyGPIO->gpio_lock);

    return status;

}

static int __init gpio_init(void)

{

......

    spin_lock_init(&MyGPIO->gpio_lock);

    /* map GUT bus memory into CPU space for use */

    MyGPIO->gpio_base = ioremap(ccsr_gut_base, ccsr_gut_length);

    if(!MyGPIO->gpio_base){

        printk(KERN_INFO "can't ioremap region\r\n");

        return -1;

    }

    printk(KERN_INFO "gpio_base: 0x%08X\r\n", (u32)(MyGPIO->gpio_base));

    /*  Init Gpio directions */

    MyGPIO_SetDirection(0, 2); //PB0 out

    MyGPIO_SetDirection(1, 2); //PB1 out

    MyGPIO_SetDirection(6, 2); //PB6

    MyGPIO_SetDirection(4, 2); //PB4

 

    /***** Write 1 to PB4 fail !!!!!!!!!!!!!!!!  *****************/

    MyGPIO_write(4, 1)

    return 0;

}

static void __exit gpio_exit(void)

{

    printk(KERN_INFO "gpio module exit called\n");

    /* iounmap */

    iounmap(MyGPIO->gpio_base);

    return;  

}

module_init( gpio_init);

module_exit( gpio_exit );

//Meta information

MODULE_AUTHOR("Alfonsox");

MODULE_LICENSE("GPL");

MODULE_DESCRIPTION("Freescale P1021 GPIO Init Module!");


Thanks in advance for your Reply!!

0 Kudos

834 Views
marius_grigoras
NXP Employee
NXP Employee

Hi,

Did you try to take a look in the processor reference manual for GPIO signals? I attached the manual.

Regards,

Marius

0 Kudos

834 Views
alfonsokame
Contributor III

Hi Marius,

I m using the reference manual you ve sended to me. Especially because I ve choosen to write a small driver thats the GUT-Registers address space into the kernel spaceso that i can configure the CPDIR and CPDAT registers.

Ist there any documentation about how to use the qe_lib/gpio.c ? And to configure the device tree?

thanks!

0 Kudos

834 Views
marius_grigoras
NXP Employee
NXP Employee

Hi,

I just discussed with some linux guys and you can use Kernel API only, there is no integration with gpio.c, no /sys/class/gpio methods available.

Also, I found this link [1], maybe you can use these information to update the device tree according.

Hope this helps,

Marius

[1] http://www.armadeus.com/wiki/index.php?title=GPIOlib

0 Kudos

834 Views
francescoluccon
Contributor I

Hi Marius,

I've involved in the same issue but I'm working with p1021mds board instead, with kernel linux 3-8.13.

Could you give me any examples for using API linux functions for managing gpio pinout?

Thank you for the attention in advance.

Francesco

0 Kudos