NvBool NvOdmEcompassOpen(NvOdmEcompassHandle* hDevice) { NvU32 i; NvOdmEcompassHandle hEcompass; NvOdmIoModule IoModule = NvOdmIoModule_I2c; const NvOdmPeripheralConnectivity *pConnectivity; NvBool FoundGpio = NV_FALSE, FoundI2cModule = NV_FALSE; hEcompass = NvOdmOsAlloc(sizeof(NvOdmEcompass)); if (hEcompass == NULL) { NVODMECOMPASS_PRINTF(("AKM8975 compass driver: Open fail\n")); return NV_FALSE; } NvOdmOsMemset(hEcompass,0,sizeof(NvOdmEcompass)); hEcompass->nBusType = NV_ECOMPASS_BUS_I2C; // Info of ecompass with current setting pConnectivity = (NvOdmPeripheralConnectivity*)NvOdmPeripheralGetGuid( ECOMPASS_GUID); if (!pConnectivity) { NvOdmOsDebugPrintf(("NvOdmPeripheralGetGuid doesn't detect\ AKM8975/B device\n")); goto error; }
static NvBool WriteReg( NvOdmEcompassHandle hDevice, NvU8 RegAddr, NvU8* value, NvU32 len) { NvOdmI2cTransactionInfo TransactionInfo; if ( (NULL == hDevice) || (NULL == value) || (len > I2C_ECOMPASS_PACKET_SIZE-1 ) ) { NVODMECOMPASS_PRINTF(("NvOdmI2c Set Regs Failed, max size is %d bytes\n", I2C_ECOMPASS_PACKET_SIZE-1)); return NV_FALSE; } s_WriteBuffer[0] = RegAddr; NvOdmOsMemcpy(&s_WriteBuffer[1], value, len); TransactionInfo.Address = hDevice->nDevAddr; TransactionInfo.Buf = s_WriteBuffer; TransactionInfo.Flags = NVODM_I2C_IS_WRITE; TransactionInfo.NumBytes = len+1; // Write the accelerator RegAddr (from where data is to be read). if (NvOdmI2cTransaction(hDevice->hOdmI2C, &TransactionInfo, 1, NVODMECOMPASS_I2C_SPEED_KHZ, I2C_ECOMPASS_TRANSACTION_TIMEOUT) != NvOdmI2cStatus_Success) return NV_FALSE; return NV_TRUE; }
static NvBool ConnectSemaphore(NvOdmEcompassHandle hDevice) { NvOdmGpioPinMode mode; NvOdmInterruptHandler callback = (NvOdmInterruptHandler)GpioInterruptHandler; hDevice->hGpioINT = (NvOdmServicesGpioHandle)NvOdmGpioOpen(); if (!(hDevice->hGpioINT)) { NVODMECOMPASS_PRINTF(("AKM8975 compass driver: NvOdmGpioOpenError \n")); return NV_FALSE; } hDevice->hPinINT = NvOdmGpioAcquirePinHandle(hDevice->hGpioINT, hDevice->GPIOPortINT, hDevice->GPIOPinINT); hDevice->SemaphoreForINT = NvOdmOsSemaphoreCreate(0); if (!(hDevice->SemaphoreForINT)) { NVODMECOMPASS_PRINTF(( "AKM8975 compass driver: NvOdmOsSemaphoreCreate Error \n")); NvOdmGpioClose(hDevice->hGpioINT); return NV_FALSE; } mode = NvOdmGpioPinMode_InputInterruptHigh; if (NvOdmGpioInterruptRegister(hDevice->hGpioINT, &hDevice->hGpioInterrupt, hDevice->hPinINT, mode, callback, hDevice, NV_DEBOUNCE_TIME_MS) == NV_FALSE) { return NV_FALSE; } if (!(hDevice->hGpioInterrupt)) { NVODMECOMPASS_PRINTF(("AKM8975 compass driver: NvOdm Ecompass NvOdmGpioInterruptRegister Error \n")); NvOdmGpioClose(hDevice->hGpioINT); NvOdmOsSemaphoreDestroy(hDevice->SemaphoreForINT); return NV_FALSE; } return NV_TRUE; }
static NvBool AKM8975_Init(NvOdmEcompassHandle hEcompass){ NvU8 TestVal; /* Check Connection */ if(!ReadReg(hEcompass,AK8975_REG_WIA,&TestVal, 1)) goto error; if (TestVal!=0x48) { NVODMECOMPASS_PRINTF(("AKM8975 compass driver : Unknown ID 0x%x \n",TestVal)); goto error; } NVODMECOMPASS_PRINTF(("AKM8975 compass driver: ID is 0x%x \n",TestVal)); NVODMECOMPASS_PRINTF(("AKM8975 compass driver: Init Passed \n")); return NV_TRUE; error: NVODMECOMPASS_PRINTF(("AKM8975 compass driver: Init Failed \n")); return NV_FALSE; }
static NvBool akm8975_ReadXYZ( NvOdmEcompassHandle hDevice, NvS16* X, NvS16* Y, NvS16* Z) { NvU8 Data[13]; NvBool NewData = 0; NvU8 i=0; if (!ReadReg(hDevice, AK8975_REG_WIA, &Data[0], 1)) return NV_FALSE; if (!ReadReg(hDevice, AK8975_REG_INFO, &Data[1], 1)) return NV_FALSE; if (!ReadReg(hDevice, AK8975_REG_ST1, &Data[2], 1)) return NV_FALSE; if (!ReadReg(hDevice, AK8975_REG_ST2, &Data[9], 1)) return NV_FALSE; for (i=0;i<6;i++) { if (!ReadReg(hDevice, AK8975_REG_HXL+i, &Data[3+i], 1)) return NV_FALSE; } NewData = ((Data[0] == 0x48)&& !(Data[9] & 0x04) && (Data[2] & 0x01)) ? 1:0; NVODMECOMPASS_PRINTF((" X: [%x] [%x] Y: [%x] [%x] Z: [%x] [%x]", Data[4],Data[3], Data[6], Data[5], Data[8], Data[7])); *X = 0xFFFF; *Y = 0xFFFF; *Z = 0xFFFF; return NewData; }
static void GpioInterruptHandler(void *arg) { NvU32 pinValue; NvU8 ret; NvU8 buffer[SENSOR_DATA_SIZE]; NvU8 i; NvOdmEcompassHandle hDevice = (NvOdmEcompassHandle)arg; NvOdmGpioGetState(hDevice->hGpioINT, hDevice->hPinINT, &pinValue); if (pinValue == 1) { ret=ReadReg(hDevice, AK8975_REG_ST1, buffer, SENSOR_DATA_SIZE); if (ret<0) { NVODMECOMPASS_PRINTF(("AKM8975 compass driver: I2C failed\n")); return; } /* Check ST bit */ if ((buffer[0] & 0x01) != 0x01) { NVODMECOMPASS_PRINTF(("AKM8975 akm8975_work_func: ST is not set\n")); return; } /* Check ST2 bit */ if (((buffer[7]&0x04)==0x04)||((buffer[7]&0x08)==0x08)) { NVODMECOMPASS_PRINTF(("AKM8975 akm8975_work_func: Data is Fail\n")); return; } NvOdmOsMemcpy(ecompass_buffer,buffer,SENSOR_DATA_SIZE); #if 0 NVODMECOMPASS_PRINTF(("\n")); NVODMECOMPASS_PRINTF((" GPIO handle :\n")); for (i=0; i<SENSOR_DATA_SIZE; i++) { NVODMECOMPASS_PRINTF((" Reg %d : [%02x]\n",i,ecompass_buffer[i])); } #endif NvOdmOsSemaphoreSignal(hDevice->SemaphoreForINT); } NvOdmGpioInterruptDone(hDevice->hGpioInterrupt); return; }
static NvBool ReadReg( NvOdmEcompassHandle hDevice, NvU8 RegAddr, NvU8* value, NvU32 len) { #if 0 NvOdmI2cTransactionInfo TransactionInfo; if ( (NULL == hDevice) || (NULL == value) || (len > I2C_ECOMPASS_PACKET_SIZE-1 ) ) { NVODMECOMPASS_PRINTF(("NvOdmI2c Get Regs Failed, max size is %d bytes\n", I2C_ECOMPASS_PACKET_SIZE-1)); return NV_FALSE; } s_WriteBuffer[0] = RegAddr; TransactionInfo.Address = hDevice->nDevAddr; TransactionInfo.Buf = s_WriteBuffer; TransactionInfo.Flags = NVODM_I2C_IS_WRITE; TransactionInfo.NumBytes = 1; // Write the accelerometor RegAddr (from where data is to be read). if (NvOdmI2cTransaction(hDevice->hOdmI2C, &TransactionInfo, 1, NVODMECOMPASS_I2C_SPEED_KHZ, I2C_ECOMPASS_TRANSACTION_TIMEOUT) != NvOdmI2cStatus_Success) return NV_FALSE; s_ReadBuffer[0] = 0; TransactionInfo.Address = (hDevice->nDevAddr| 0x1); TransactionInfo.Buf = s_ReadBuffer; TransactionInfo.Flags = 0; TransactionInfo.NumBytes = len; //Read the data from the eeprom at the specified RegAddr if (NvOdmI2cTransaction(hDevice->hOdmI2C, &TransactionInfo, 1, NVODMECOMPASS_I2C_SPEED_KHZ, I2C_ECOMPASS_TRANSACTION_TIMEOUT) != NvOdmI2cStatus_Success) return NV_FALSE; NvOdmOsMemcpy(value, &s_ReadBuffer[0], len); return NV_TRUE; #else NvU32 i; NvOdmI2cStatus status = NvOdmI2cStatus_Success; NvOdmI2cTransactionInfo TransactionInfo[2]; if ( (NULL == hDevice) || (NULL == value) || (len > I2C_ECOMPASS_PACKET_SIZE-1 ) ) { NVODMECOMPASS_PRINTF(("NvOdmI2c Get Regs Failed, max size is %d bytes\n", I2C_ECOMPASS_PACKET_SIZE-1)); return NV_FALSE; } for (i=0; i<NVODMECOMPASS_I2C_RETRY_CNT; i++) { NvU32 TransactionCount = 0; s_WriteBuffer[0] = RegAddr; TransactionInfo[TransactionCount].Address = hDevice->nDevAddr; TransactionInfo[TransactionCount].Buf = &s_WriteBuffer[0]; TransactionInfo[TransactionCount].Flags = NVODM_I2C_IS_WRITE | NVODM_I2C_USE_REPEATED_START; TransactionInfo[TransactionCount++].NumBytes = 1; s_ReadBuffer[0] = 0; TransactionInfo[TransactionCount].Address = (hDevice->nDevAddr | 0x1); TransactionInfo[TransactionCount].Buf = &s_ReadBuffer[0]; TransactionInfo[TransactionCount].Flags = 0; TransactionInfo[TransactionCount++].NumBytes = len; status = NvOdmI2cTransaction(hDevice->hOdmI2C, &TransactionInfo[0], TransactionCount, NVODMECOMPASS_I2C_SPEED_KHZ, NV_WAIT_INFINITE); if (status == NvOdmI2cStatus_Success) { NvOdmOsMemcpy(value, &s_ReadBuffer[0], len); return NV_TRUE; } } // Transaction Error switch (status) { case NvOdmI2cStatus_Timeout: NVODMECOMPASS_PRINTF(("NvOdmEcompassI2cRead Failed: Timeout\n")); break; case NvOdmI2cStatus_SlaveNotFound: default: NVODMECOMPASS_PRINTF(("NvOdmEcompassI2cRead Failed: SlaveNotFound\n")); break; } return NV_FALSE; #endif }