2 years ago

#29248

test-img

Sir Jo Black

Issues creating a Linux device driver to manage NanoPI TWI (I2C) registers

I'm trying to develop a Linux device driver to manage the GPIO registers of a NanoPI Neo card (Allwinner H3).

I'm using a simple approach to understand the GPIO registers behaviour by means the use of only two driver functions: open and ioctl.

My driver implementation, at now, is able to manage a lot of registers such as RTC and CPU-PORT and to read write some other registers.

But I'm having issues in using/managing TWI registers (I2C).

The blocking me issue is that whathever register I read or read after writing any value to the register itself always returns 0x00000000 and nothing seems to happen at pin HW level (PA11/PA12 see below)

I read on the CPU datasheet (see: paragraph 8.1 of the document) the registers value and base address to manage TWI0, base address should be 0x01C2AC00.

I can't find any AllWinner H3 GPIO programmer's reference and I'm not sure if specific operations are required to activate the TWI register functionality. The only operations I have done are to set registers PA11 and PA12 to be the I/O of TWI0_SCK and TWI0_SDA.

Questions:

  • Do you have any news of an "AllWinner H3 GPIO Programmer's Reference"?

  • Do you know which GPIO register I have to set / modify to get TWI enabled or at least give me "signs of life"?


A very strong simplification, aimed at using only TWI0 registers, of the mapping and ioctl functions of the driver I wrote might be the following code, but my code is much more sophisticated and I know it works with many other registers.

#define TWI_IOBASE(n)           (0x01C2AC00 + 0x400*((n)&3))
#define TWI_PAGESIZE            0x400

#define IO_ADDRESS_MSK          0x0000FFFFUL
#define IO_CMD_MSK              0xF0000000UL
#define IO_CMD_READ             0x10000000UL
#define IO_CMD_WRITE            0x20000000UL

static unsigned char * vmaddr;

inline static int drv_init_twi_vm(void)
{
    vmaddr=ioremap(TWI_IOBASE(0), TWI_PAGESIZE);
}

static long drv_ioctl_twi_rw(struct file *file, unsigned int cmd, unsigned long * arg)
{
    long retval = 1;

    unsigned c;

    uint32_t r;

    void *x;

    r=cmd & IO_ADDRESS_MSK;

    x=vmaddr+r;

    c=cmd & IO_CMD_MSK;

    switch(c)
    {
    case IO_CMD_READ:
        if ( copy_to_user((void *)arg, x, 4) ) {
            retval = -EFAULT;
        }
        break;

    case IO_CMD_WRITE:
        *(unsigned long *)x=*arg;
        break;

    default:
        retval=-EFAULT;
        break;
    }

    return retval;
}

c

linux-device-driver

nanopi

0 Answers

Your Answer

Accepted video resources