/* --------------------------------------------------------------------- Here we defined two functions here for I2C r/w via GPIO void DRV_GPIOI2C_WriteFun(UINT8 Mx UINT8 DeviceID UINT8 AddrLen UINT32 Addr UINT8 *pData UINT32 DataLen UINT8 Speed UINT8 *Status); UINT8 DRV_GPIOI2C_ReadFun(UINT8 Mx, UINT8 DeviceID, UINT8 AddrLen, UINT32 Addr, UINT8 *pData, UINT32 DataLen, UINT8 Speed, UINT8 *Status); --------------------------------------------------------------------- */ #include #include #include #include "drv_i2c_gpioi2c.h" #include "drv_i2c_main.h" #include #include "gpio_pin_define.h" #include "drv_gpio.h" #include "pin_config.h" extern I2C_DEV I2cDev; #if CONFIG_CHIPID == 0x330 #define GPIO_I2C_CLK 21 #define GPIO_I2C_DATA 22 #else #define GPIO_I2C_CLK GPIO_I2C_SCL_PIN #define GPIO_I2C_DATA GPIO_I2C_SDA_PIN #endif #define GPIO_X_I2C_CLK 21 #define GPIO_X_I2C_DATA 20 #define LAG 8 /* 90=50k, 42 = 100k, 12 = 200k */ //#define CONFIG_ENABLE_2ND_GPIO_I2C UINT8 GpioI2CSatus; void i2cGPIOOpenDrainWrite(UINT8 index, UINT32 value); void MxI2cGPIORestart(void); void MxI2cGPIOStart(void); void MxI2cGPIOStop(void); void MxI2cGPIOWriteByte(UINT8 Value); UINT8 MxI2cGPIOReadByte(UINT8 bMoreByte); UINT32 mmioRead(UINT32 addr) { volatile UINT32 dw = *((UINT32*)addr); return dw; } UINT32 mmioReadMask(UINT32 addr, UINT32 mask) { return mmioRead( addr ) & mask; } void mmioWrite(UINT32 addr, UINT32 data) { *(UINT32*)addr = data; } void mmioWriteMask(UINT32 addr, UINT32 mask, UINT32 data) { UINT32 dw; dw = mmioReadMask( addr, ~mask ); mmioWrite( addr, ((data & mask) | dw) ); } void i2cGPIOOpenDrainWrite(UINT8 index, UINT32 value) { UINT8 bits; // set GPIO output value bits = index ; mmioWriteMask(0xbe0f0610,(0x1 << bits),(0x0 << bits)); // set GPIO input / output control register to "output mode" mmioWriteMask(0xbe0f0618,(0x1 << bits),(value << bits)); // set "function selection" mux to "GPIO (set '01') " bits = (index % 16) * 2; mmioWriteMask(0xbe0f0604,(0x3 << bits),(0x1 << bits)); } void MxI2cGPIOStart(void) { GpioI2CSatus = 0; i2cGPIO_writeGPIO(GPIO_I2C_CLK,1); i2cGPIO_writeGPIO(GPIO_I2C_DATA,1); udelay(LAG); i2cGPIO_writeGPIO(GPIO_I2C_DATA,0); udelay(LAG); i2cGPIO_writeGPIO(GPIO_I2C_CLK,0); udelay(LAG); } void MxI2cGPIOStop(void) { i2cGPIO_writeGPIO(GPIO_I2C_DATA,0); udelay(LAG); i2cGPIO_writeGPIO(GPIO_I2C_CLK,1); udelay(LAG); i2cGPIO_writeGPIO(GPIO_I2C_DATA,1); udelay(LAG); i2cGPIO_readGPIO(GPIO_I2C_CLK); i2cGPIO_readGPIO(GPIO_I2C_DATA); udelay(LAG); } void MxI2cGPIORestart(void) { if(GpioI2CSatus) return; i2cGPIO_writeGPIO(GPIO_I2C_DATA,1); udelay(LAG); i2cGPIO_writeGPIO(GPIO_I2C_CLK,1); udelay(LAG); i2cGPIO_writeGPIO(GPIO_I2C_DATA,0); udelay(LAG); i2cGPIO_writeGPIO(GPIO_I2C_CLK,0); udelay(LAG); } void MxI2cGPIOWriteByte(UINT8 Value) { UINT8 i; if(GpioI2CSatus) return; for(i=0;i<8;i++) { if(Value & 0x80) { i2cGPIO_writeGPIO(GPIO_I2C_DATA,1); } else { i2cGPIO_writeGPIO(GPIO_I2C_DATA,0); } udelay(LAG); i2cGPIO_writeGPIO(GPIO_I2C_CLK,1); udelay(LAG); i2cGPIO_writeGPIO(GPIO_I2C_CLK,0); udelay(LAG); Value <<= 1; } i2cGPIO_readGPIO(GPIO_I2C_DATA); udelay(LAG); i2cGPIO_writeGPIO(GPIO_I2C_CLK,1); udelay(LAG); if(i2cGPIO_readGPIO(GPIO_I2C_DATA)) { GpioI2CSatus = 1; } i2cGPIO_writeGPIO(GPIO_I2C_CLK,0); udelay(LAG); } UINT8 MxI2cGPIOReadByte(UINT8 bMoreByte) { UINT8 i,Value; if(GpioI2CSatus) return 0; i2cGPIO_readGPIO(GPIO_I2C_DATA); udelay(LAG); Value = 0; for(i=0;i<8;i++) { Value <<= 1; i2cGPIO_writeGPIO(GPIO_I2C_CLK,1); udelay(LAG); if(i2cGPIO_readGPIO(GPIO_I2C_DATA)) { Value |= 1; } i2cGPIO_writeGPIO(GPIO_I2C_CLK,0); udelay(LAG); } if(bMoreByte) { i2cGPIO_writeGPIO(GPIO_I2C_DATA,0); } else { i2cGPIO_writeGPIO(GPIO_I2C_DATA,1); } udelay(LAG); i2cGPIO_writeGPIO(GPIO_I2C_CLK,1); udelay(LAG); i2cGPIO_writeGPIO(GPIO_I2C_CLK,0); udelay(LAG); return Value; } void _GPIOI2C_0_WriteFun(UINT8 Mx, UINT8 DeviceID, UINT8 AddrLen, UINT32 Addr,UINT8 *pData, UINT32 DataLen,UINT8 Speed,UINT8 *Status) { UINT32 i; // printk(KERN_EMERG"Mx = %d",Mx); // printk(KERN_EMERG"DeviceID = 0x%x",DeviceID); // printk(KERN_EMERG"AddrLen = %d",AddrLen); // printk(KERN_EMERG"Addr = %d",Addr); // printk(KERN_EMERG"DataLen = %d",DataLen); // printk(KERN_EMERG"Speed = %d",Speed); DeviceID &= 0xFE; if(in_atomic()) { DbgFunPrint("ID=%02x,Invalid Write Process!!",DeviceID); *Status = I2C_STATUS_DATA_ERROR; return; } down(&I2cDev.GPIOI2cMutex); MxI2cGPIOStart(); MxI2cGPIOWriteByte(DeviceID); switch (AddrLen) { case ADDRESS_TYPE_BYTE: MxI2cGPIOWriteByte((UINT8) (Addr & 0xff)); MxI2cGPIORestart(); MxI2cGPIOWriteByte(DeviceID); break; case ADDRESS_TYPE_MULTIPLE: if( ((Addr&0x0f000000) >> 24) >= 1 ) { MxI2cGPIOWriteByte((UINT8) ((Addr>>0) & 0xff));} if( ((Addr&0x0f000000) >> 24) >= 2 ) { MxI2cGPIOWriteByte((UINT8) ((Addr>>8) & 0xff));} if( ((Addr&0x0f000000) >> 24) >= 3 ) { MxI2cGPIOWriteByte((UINT8) ((Addr>>16) & 0xff));} //if( ((Addr&0x0f000000) >> 24) >= 4 ) { MxI2cGPIOWriteByte((UINT8) ((Addr>>24) & 0xff));} MxI2cGPIORestart(); MxI2cGPIOWriteByte(DeviceID); break; case ADDRESS_TYPE_NONE: break; default: printk("writeI2CviaGPIO write error:AddrLen must be equal to or less than 4.\n"); GpioI2CSatus = I2C_STATUS_DATA_ERROR; break; } for(i=0;i> 24) >= 1 ) { MxI2cGPIOWriteByte((UINT8) (Addr & 0xff));} if( ((Addr&0x0f000000) >> 24) >= 2 ) { MxI2cGPIOWriteByte((UINT8) ((Addr>>8) & 0xff));} if( ((Addr&0x0f000000) >> 24) >= 3 ) { MxI2cGPIOWriteByte((UINT8) ((Addr>>16) & 0xff));} //if( ((Addr&0x0f000000) >> 24) >= 4 ) { MxI2cGPIOWriteByte((UINT8) ((Addr>>24) & 0xff));} break; case ADDRESS_TYPE_NONE: break; default: printk(KERN_EMERG"writeI2CviaGPIO read error:DataLen must be equal to or less than 4.\n"); GpioI2CSatus = I2C_STATUS_DATA_ERROR; break; } if (AddrLen != ADDRESS_TYPE_NONE) MxI2cGPIORestart(); MxI2cGPIOWriteByte(DeviceID|1); for(i=0;i> 24) >= 1 ) { MxI2cXGPIOWriteByte((UINT8) ((Addr>>0) & 0xff));} if( ((Addr&0x0f000000) >> 24) >= 2 ) { MxI2cXGPIOWriteByte((UINT8) ((Addr>>8) & 0xff));} if( ((Addr&0x0f000000) >> 24) >= 3 ) { MxI2cXGPIOWriteByte((UINT8) ((Addr>>16) & 0xff));} //if( ((Addr&0x0f000000) >> 24) >= 4 ) { MxI2cXGPIOWriteByte((UINT8) ((Addr>>24) & 0xff));} MxI2cXGPIORestart(); MxI2cXGPIOWriteByte(DeviceID); break; case ADDRESS_TYPE_NONE: break; default: printk("writeI2CviaGPIO write error:AddrLen must be equal to or less than 4.\n"); GpioI2CSatus = I2C_STATUS_DATA_ERROR; break; } for(i=0;i> 24) >= 1 ) { MxI2cXGPIOWriteByte((UINT8) (Addr & 0xff));} if( ((Addr&0x0f000000) >> 24) >= 2 ) { MxI2cXGPIOWriteByte((UINT8) ((Addr>>8) & 0xff));} if( ((Addr&0x0f000000) >> 24) >= 3 ) { MxI2cXGPIOWriteByte((UINT8) ((Addr>>16) & 0xff));} //if( ((Addr&0x0f000000) >> 24) >= 4 ) { MxI2cXGPIOWriteByte((UINT8) ((Addr>>24) & 0xff));} break; case ADDRESS_TYPE_NONE: break; default: printk(KERN_EMERG"writeI2CviaGPIO read error:DataLen must be equal to or less than 4.\n"); GpioI2CSatus = I2C_STATUS_DATA_ERROR; break; } if (AddrLen != ADDRESS_TYPE_NONE) MxI2cXGPIORestart(); MxI2cXGPIOWriteByte(DeviceID|1); for(i=0;i