'Cannot read/write I2C register in Linux device driver (Orange Pi)

I'm using I2C register to config for device driver but:

  • I cannot read/write I2C register after request_mem_region() -> ioremap(). I see that just happens with I2C, UART, SPI... but I still can use with GPIO and TIMER.
  • I tried to change config in menuconfig before building distro but it's efficient (enable Embedded system, enable map Ram...). Of course, I too tried readl(), writel(), iowrite32(), ioread32()...
  • But code works fine when I edit I2C register that is available when configuring the distro and can see it on /dev/iomem.

I think there is a problem with ram access. But how to fix it? Thanks!

After code for test:

u8 twi_mem_flag = 0;

int PIOA_Init(void)
{
    if (!request_mem_region(TWI_BASE, 0x400, "TWI_MEM")) {
        printk(KERN_INFO "TWI_MEM is existed\n");
        twi_mem_flag = 1;
    }
    PA_CFG0_REG  = (uint32_t *) ioremap(PA_CFG0, 4);
    PA_PUL0_REG  = (uint32_t *) ioremap(PA_PUL0, 4);
    PA_DATA_REG  = (uint32_t *) ioremap(PA_DAT, 4);
    PA_DRV0_REG  = (uint32_t *) ioremap(PA_DRV0, 4);
    PA_EINT_CFG0_REG   = (uint32_t *) ioremap(PA_EINT_CFG0, 4);
    PA_EINT_CTL_REG    = (uint32_t *) ioremap(PA_EINT_CTL, 4);
    PA_EINT_STATUS_REG = (uint32_t *) ioremap(PA_EINT_STATUS, 4);
    PA_EINT_DEB_REG    = (uint32_t *) ioremap(PA_EINT_DEB, 4);
    
    TWI_ADDR_REG   = (uint32_t *) ioremap(TWI_ADDR, 4);
    TWI_XADDR_REG    = (uint32_t *) ioremap(TWI_XADDR, 4);
    TWI_DATA_REG = (uint32_t *) ioremap(TWI_DATA, 4);
    TWI_CNTR_REG    = (uint32_t *) ioremap(TWI_CNTR, 4);
    
    *PA_CFG0_REG &= ~(0X77 << 24);
    *PA_CFG0_REG |=  (0X01 << 24);

    *PA_PUL0_REG &= ~(0X0f << 12);
    *PA_PUL0_REG |=  (0X05 << 12);

    *PA_EINT_CFG0_REG   = (0x03 << 28);
    *PA_EINT_CTL_REG    = (0x01 << 7);
    *PA_EINT_STATUS_REG     = (0x01 << 7);
    *PA_EINT_DEB_REG    = (0x11);
    
    *TWI_ADDR_REG |= 0x07;
    *TWI_DATA_REG |= 0x77;
    *TWI_CNTR_REG |= 0x05;
    printk( KERN_INFO "GPIO: %x - %x - %x - %x\n", *PA_CFG0_REG, *PA_PUL0_REG, *PA_DATA_REG, *PA_DRV0_REG);
    printk( KERN_INFO "TWI: %x - %x - %x - %x\n", *TWI_ADDR_REG, *TWI_XADDR_REG, *TWI_DATA_REG, *TWI_CNTR_REG);

    return 0;
}

void PIOA_destroy(void)
{
    iounmap(PA_DRV0_REG);
    iounmap(PA_DATA_REG);
    iounmap(PA_CFG0_REG);
    iounmap(PA_PUL0_REG);
    
    iounmap(PA_EINT_CFG0_REG);
    iounmap(PA_EINT_CTL_REG);
    iounmap(PA_EINT_STATUS_REG);
    iounmap(PA_EINT_DEB_REG);
        
    iounmap(TWI_ADDR_REG);
    iounmap(TWI_XADDR_REG);
    iounmap(TWI_DATA_REG);
    iounmap(TWI_CNTR_REG);
    
    if (!twi_mem_flag)
        release_mem_region(TWI_BASE, 0x400);
}
[  228.246399] GPIO: 1227777 - 5400 - 0 - 55555555 
[  228.246420] TWI: 0 - 0 - 0 - 0 
[  228.246428] The blink led device is installed !!


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source