diff options
author | vdumpa <vdumpa@nvidia.com> | 2010-04-22 13:00:05 -0700 |
---|---|---|
committer | Yu-Huan Hsu <yhsu@nvidia.com> | 2010-04-29 21:36:02 -0700 |
commit | 70cf653c28cea97ca63d1d7a6770348e64709e67 (patch) | |
tree | 22729dffe32106aaae805ffb35c4cf2057f4281d /arch | |
parent | 1743f5918df4a4be189ac5d408c76ed25a065760 (diff) |
tegra accelerometer:Adding ODM Bosch accelerometer driver.
Checking ODM Bosch accelerometer driver for BMA150 part.
This is not a complete driver. The interrupts from BMA150
are not reliably received. The polling mode works fine.
This driver need to be updated for changing config settings
through sysfs interface.
Change-Id: I1492c5661509ba23c3967ed3ea1908bfb4336948
Reviewed-on: http://git-master/r/1180
Reviewed-by: Gary King <gking@nvidia.com>
Reviewed-by: Hoang Pham <hopham@nvidia.com>
Tested-by: Hoang Pham <hopham@nvidia.com>
Diffstat (limited to 'arch')
3 files changed, 835 insertions, 1 deletions
diff --git a/arch/arm/mach-tegra/odm_kit/platform/accelerometer/Makefile b/arch/arm/mach-tegra/odm_kit/platform/accelerometer/Makefile index 4171fe9b24de..0ec8a6b4ea03 100644 --- a/arch/arm/mach-tegra/odm_kit/platform/accelerometer/Makefile +++ b/arch/arm/mach-tegra/odm_kit/platform/accelerometer/Makefile @@ -8,5 +8,5 @@ ccflags-y += -DNV_DEBUG=0 endif obj-$(CONFIG_TEGRA_ODM_CONCORDE) += nvodm_accelerometer_adi340.o -obj-$(CONFIG_TEGRA_ODM_HARMONY) += nvodm_accelerometer_stub.o +obj-$(CONFIG_TEGRA_ODM_HARMONY) += nvodm_accelerometer_bma150.o obj-$(CONFIG_TEGRA_ODM_WHISTLER) += nvodm_accelerometer_adi340.o diff --git a/arch/arm/mach-tegra/odm_kit/platform/accelerometer/nvodm_accelerometer_bma150.c b/arch/arm/mach-tegra/odm_kit/platform/accelerometer/nvodm_accelerometer_bma150.c new file mode 100644 index 000000000000..aedf87c837a9 --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/platform/accelerometer/nvodm_accelerometer_bma150.c @@ -0,0 +1,622 @@ +/* + * Copyright (c) 2010 NVIDIA Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of the NVIDIA Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* NVIDIA Tegra ODM Kit Sample Accelerometer Adaptation of the + * WinCE Accelerometer Driver + */ + +#include "nvodm_accelerometer_bma150.h" +#include "nvodm_services.h" +#include "nvodm_query_discovery.h" +#include "nvos.h" + +#define NVODMACCELEROMETER_ENABLE_PRINTF 0 + +#if NVODMACCELEROMETER_ENABLE_PRINTF + #define NVODMACCELEROMETER_PRINTF(x) \ + do { \ + NvOdmOsPrintf x; \ + } while (0) +#else + #define NVODMACCELEROMETER_PRINTF(x) +#endif + +#define NV_BMA150_MAX_FORCE_IN_REG 512 // It indicates force register length. +#define NV_DEBOUNCE_TIME_MS 0 + +#define ENABLE_XYZ_POLLING 0 + +//FIXME: protect this variable using spinlock. +static volatile int g_WaitCounter = 0; +static void BMA150_ResetInterrupt(NvOdmAccelHandle hDevice); + +static void +SetPowerRail( + NvOdmServicesPmuHandle hPMUDevice, + NvU32 Id, + NvBool IsEnable) +{ + NvOdmServicesPmuVddRailCapabilities vddrailcap; + NvU32 settletime; + + if (hPMUDevice && Id) + { + NvOdmServicesPmuGetCapabilities(hPMUDevice, Id, &vddrailcap); + if (IsEnable) + { + NvOdmServicesPmuSetVoltage(hPMUDevice, Id, + vddrailcap.requestMilliVolts, &settletime); + } + else + { + NvOdmServicesPmuSetVoltage(hPMUDevice, Id, + vddrailcap.MinMilliVolts, &settletime); + } + NvOdmOsWaitUS(settletime); + } +} + +static void GpioInterruptHandler(void *arg) +{ + NvU32 pinValue; + NvOdmAccelHandle hDevice = (NvOdmAccelHandle)arg; + + NvOdmGpioGetState(hDevice->hGpioINT, hDevice->hPinINT, &pinValue); + if (pinValue == 1) + { + NVODMACCELEROMETER_PRINTF(("\r\nBMA150 Interrupt")); + g_WaitCounter = 10; + BMA150_ResetInterrupt(hDevice); + } else + NVODMACCELEROMETER_PRINTF(("\r\nBMA150 non-Interrupt")); + + if (pinValue == 1) + { + NvOdmOsSemaphoreSignal(hDevice->SemaphoreForINT); + } + NvOdmGpioInterruptDone(hDevice->hGpioInterrupt); + return; +} + +static NvBool ConnectSemaphore(NvOdmAccelHandle hDevice) +{ + NvOdmGpioPinMode mode; + NvOdmInterruptHandler callback = + (NvOdmInterruptHandler)GpioInterruptHandler; + + hDevice->hGpioINT = (NvOdmServicesGpioHandle)NvOdmGpioOpen(); + if (!(hDevice->hGpioINT)) + { + NVODMACCELEROMETER_PRINTF(( + "NvOdm Accelerometer : NvOdmGpioOpen Error \n")); + return NV_FALSE; + } + + hDevice->hPinINT = NvOdmGpioAcquirePinHandle(hDevice->hGpioINT, + hDevice->GPIOPortINT, + hDevice->GPIOPinINT); + hDevice->SemaphoreForINT = NvOdmOsSemaphoreCreate(0); + + if (!(hDevice->SemaphoreForINT)) + { + NVODMACCELEROMETER_PRINTF(( + "NvOdm Accelerometer : 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)) + { + NVODMACCELEROMETER_PRINTF(( + "NvOdm Accelerometer : NvOdmGpioInterruptRegister Error \n")); + NvOdmGpioClose(hDevice->hGpioINT); + NvOdmOsSemaphoreDestroy(hDevice->SemaphoreForINT); + return NV_FALSE; + } + return NV_TRUE; +} + +static NvBool +WriteReg( + NvOdmAccelHandle hDevice, + NvU8 RegAddr, + NvU8* value, + NvU32 len) +{ + NvOdmI2cTransactionInfo TransactionInfo; + + if ( (NULL == hDevice) || (NULL == value) || + (len > I2C_ACCELRATOR_PACKET_SIZE-1 ) ) + { + NVODMACCELEROMETER_PRINTF(( + "NvOdmI2c Set Regs Failed, max size is %d bytes\n", + I2C_ACCELRATOR_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, 400, + I2C_ACCELRATOR_TRANSACTION_TIMEOUT) != NvOdmI2cStatus_Success) + return NV_FALSE; + + return NV_TRUE; +} + +static NvBool +ReadReg( + NvOdmAccelHandle hDevice, + NvU8 RegAddr, + NvU8* value, + NvU32 len) +{ + NvOdmI2cTransactionInfo TransactionInfo; + + if ( (NULL == hDevice) || (NULL == value) || + (len > I2C_ACCELRATOR_PACKET_SIZE-1 ) ) + { + NVODMACCELEROMETER_PRINTF(( + "NvOdmI2c Get Regs Failed, max size is %d bytes\n", + I2C_ACCELRATOR_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, 400, + I2C_ACCELRATOR_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, 400, + I2C_ACCELRATOR_TRANSACTION_TIMEOUT) != NvOdmI2cStatus_Success) + return NV_FALSE; + + NvOdmOsMemcpy(value, &s_ReadBuffer[0], len); + return NV_TRUE; +} + +static NvBool BMA150_Init(NvOdmAccelHandle hAccel) +{ + NvU8 TestVal; + + ReadReg(hAccel, CHIP_ID_REG, &TestVal, 1); + if (TestVal != BMA150_CHIP_ID) + { + NVODMACCELEROMETER_PRINTF(("Unknown BMA150 ID = 0x%x\n", TestVal)); + goto error; + } + NVODMACCELEROMETER_PRINTF(("BMA150 ID is 0x%x\n", TestVal)); + + // Init Hw + if (!ReadReg(hAccel, RANGE_BWIDTH_REG, &TestVal, 1)) + goto error; + TestVal &= 0xE0; + TestVal |= 0x04; //Set bandwidth to 375hz + if (!WriteReg(hAccel, RANGE_BWIDTH_REG, &TestVal, 1)) + goto error; + + if (!ReadReg(hAccel, SMB150_CONF2_REG, &TestVal, 1)) + goto error; + // Enable Advanced interrupt(6), latch int(4) + TestVal |= (0 << 3) | (1 << 6) | (1 << 4); + if (!WriteReg(hAccel, SMB150_CONF2_REG, &TestVal, 1)) + goto error; + // Init Hw end + // Set mode + if (!ReadReg(hAccel, SMB150_CTRL_REG, &TestVal, 1)) + goto error; + TestVal &= 0xFE; + if (!WriteReg(hAccel, SMB150_CTRL_REG, &TestVal, 1)) + goto error; + // Set mode end + + // Set motion thres + if (!ReadReg(hAccel, MOTION_THRS_REG, &TestVal, 1)) + goto error; + TestVal = 0x0A; + if (!WriteReg(hAccel, MOTION_THRS_REG, &TestVal, 1)) + goto error; + // Set motion thres end + + // Set any motion int + if (!ReadReg(hAccel, SMB150_CONF1_REG, &TestVal, 1)) + goto error; + TestVal &= 0xFC; + TestVal |= (1 << 6) | (1 << 1) | (1 << 0); + if (!WriteReg(hAccel, SMB150_CONF1_REG, &TestVal, 1)) + goto error; + // Set any motion int end + NVODMACCELEROMETER_PRINTF(("\n BMA150_Init passed")); + return NV_TRUE; +error: + NVODMACCELEROMETER_PRINTF(("\n BMA150_Init failed")); + return NV_FALSE; +} + +static NvBool +BMA150_ReadXYZ( + NvOdmAccelHandle hDevice, + NvS32* X, + NvS32* Y, + NvS32* Z) +{ + NvU8 Data[6]; + NvBool NewData = 0; + + if (!ReadReg(hDevice, X_AXIS_LSB_REG, &Data[0], 6)) + return NV_FALSE; + NewData = ( (Data[0] & 0x1) || (Data[2] & 0x1) || (Data[4] & 0x1) ) ? 1 : 0; + + *X = ((Data[1] << 2) | (Data[0] >> 6)); + *Y = ((Data[3] << 2) | (Data[2] >> 6)); + *Z = ((Data[5] << 2) | (Data[4] >> 6)); + + // Preserve sign bits. + *X = *X << ((sizeof(*X)*8) - 10); + *X = *X >> ((sizeof(*X)*8) - 10); + *Y = *Y << ((sizeof(*Y)*8) - 10); + *Y = *Y >> ((sizeof(*Y)*8) - 10); + *Z = *Z << ((sizeof(*Z)*8) - 10); + *Z = *Z >> ((sizeof(*Z)*8) - 10); + return NewData; +} + +static void BMA150_ResetInterrupt(NvOdmAccelHandle hDevice) +{ + NvU8 Data = (1 << 6); + + WriteReg(hDevice, SMB150_CTRL_REG, &Data, 1); +} + +NvBool NvOdmAccelOpen(NvOdmAccelHandle* hDevice) +{ + NvU32 i; + NvOdmAccelHandle hAccel; + NvOdmIoModule IoModule = NvOdmIoModule_I2c; + const NvOdmPeripheralConnectivity *pConnectivity; + NvBool FoundGpio = NV_FALSE, FoundI2cModule = NV_FALSE; + + hAccel = NvOdmOsAlloc(sizeof(NvOdmAccel)); + if (hAccel == NULL) + { + NVODMACCELEROMETER_PRINTF(("Error Allocating NvOdmAccel. \n")); + return NV_FALSE; + } + NvOdmOsMemset(hAccel, 0, sizeof(NvOdmAccel)); + hAccel->nBusType = NV_ACCELEROMETER_BUS_I2C; + + // Info of accelerometer with current setting. + hAccel->Caption.MaxForceInGs = 2000; + hAccel->Caption.MaxTapTimeDeltaInUs = 255; + hAccel->Caption.NumMotionThresholds = 1; + hAccel->Caption.SupportsFreefallInt = 0; + hAccel->Caption.MaxSampleRate = 100; + hAccel->Caption.MinSampleRate = 3; + hAccel->PowerState = NvOdmAccelPower_Fullrun; + hAccel->AxisXMapping = NvOdmAccelAxis_Y; + hAccel->AxisXDirection = -1; + hAccel->AxisYMapping = NvOdmAccelAxis_X; + hAccel->AxisYDirection = 1; + hAccel->AxisZMapping = NvOdmAccelAxis_Z; + hAccel->AxisZDirection = -1; + + hAccel->hPmu = NvOdmServicesPmuOpen(); + if (!hAccel->hPmu) + { + NVODMACCELEROMETER_PRINTF(("NvOdmServicesPmuOpen Error \n")); + goto error; + } + + pConnectivity = (NvOdmPeripheralConnectivity*)NvOdmPeripheralGetGuid( + NV_ODM_GUID('b','m','a','1','5','0','a','c')); + if (!pConnectivity) + { + NvOdmOsDebugPrintf(("NvOdmPeripheralGetGuid doesn't detect\ + BMA150 accelerometer device\n")); + goto error; + } + + if (pConnectivity->Class != NvOdmPeripheralClass_Other) + goto error; + + for( i = 0; i < pConnectivity->NumAddress; i++) + { + switch(pConnectivity->AddressList[i].Interface) + { + case NvOdmIoModule_I2c: + case NvOdmIoModule_I2c_Pmu: + hAccel->I2CChannelId = pConnectivity->AddressList[i].Instance; + hAccel->nDevAddr = (NvU8)pConnectivity->AddressList[i].Address; + FoundI2cModule = NV_TRUE; + IoModule = pConnectivity->AddressList[i].Interface; + break; + case NvOdmIoModule_Gpio: + hAccel->GPIOPortINT = pConnectivity->AddressList[i].Instance; + hAccel->GPIOPinINT = pConnectivity->AddressList[i].Address; + FoundGpio = NV_TRUE; + break; + case NvOdmIoModule_Vdd: + hAccel->VddId = pConnectivity->AddressList[i].Address; + // Power on accelerometer according to Vddid + SetPowerRail(hAccel->hPmu, hAccel->VddId, NV_TRUE); + break; + default: + break; + } + } + + if (!FoundGpio || !FoundI2cModule) + { + NVODMACCELEROMETER_PRINTF(("Accelerometer : didn't find any periperal\ + in discovery query for touch device Error \n")); + goto error; + } + + // Open I2C handle. + hAccel->hOdmI2C = NvOdmI2cOpen(IoModule, hAccel->I2CChannelId); + if (!hAccel->hOdmI2C) + goto error; + + hAccel->RegsRead = ReadReg; + hAccel->RegsWrite = WriteReg; + + if (!BMA150_Init(hAccel)) + goto error; + if (!ConnectSemaphore(hAccel)) + goto error; + + *hDevice = hAccel; + return NV_TRUE; + error: + NVODMACCELEROMETER_PRINTF(("Error during BMA150 NvOdmAccelOpen\n")); + // Release all of resources requested. + if (hAccel) + { + SetPowerRail(hAccel->hPmu, hAccel->VddId, NV_FALSE); + NvOdmServicesPmuClose(hAccel->hPmu); + hAccel->hPmu = NULL; + NvOdmI2cClose(hAccel->hOdmI2C); + hAccel->hOdmI2C = NULL; + NvOdmOsFree(hAccel); + *hDevice = NULL; + } + return NV_FALSE; +} + +void NvOdmAccelClose(NvOdmAccelHandle hDevice) +{ + if (hDevice) + { + if (hDevice->SemaphoreForINT && hDevice->hGpioINT && + hDevice->hPinINT && hDevice->hGpioInterrupt) + { + NvOdmGpioInterruptUnregister(hDevice->hGpioINT, + hDevice->hPinINT, hDevice->hGpioInterrupt); + NvOdmOsSemaphoreDestroy(hDevice->SemaphoreForINT); + NvOdmGpioReleasePinHandle(hDevice->hGpioINT, hDevice->hPinINT); + NvOdmGpioClose(hDevice->hGpioINT); + } + NvOdmI2cClose(hDevice->hOdmI2C); + + // Power off accelermeter + SetPowerRail(hDevice->hPmu, hDevice->VddId, NV_FALSE); + if (hDevice->hPmu) + { + //NvAccelerometerSetPowerOn(0); + NvOdmServicesPmuClose(hDevice->hPmu); + } + } +} + +NvBool +NvOdmAccelSetIntForceThreshold( + NvOdmAccelHandle hDevice, + NvOdmAccelIntType IntType, + NvU32 IntNum, + NvU32 Threshold) +{ + return NV_TRUE; +} + +NvBool +NvOdmAccelSetIntTimeThreshold( + NvOdmAccelHandle hDevice, + NvOdmAccelIntType IntType, + NvU32 IntNum, + NvU32 Threshold) +{ + return NV_TRUE; +} + +NvBool +NvOdmAccelSetIntEnable( + NvOdmAccelHandle hDevice, + NvOdmAccelIntType IntType, + NvOdmAccelAxisType IntAxis, + NvU32 IntNum, + NvBool Toggle) +{ + return NV_TRUE; +} + +void +NvOdmAccelWaitInt( + NvOdmAccelHandle hDevice, + NvOdmAccelIntType *IntType, + NvOdmAccelAxisType *IntMotionAxis, + NvOdmAccelAxisType *IntTapAxis) +{ + NV_ASSERT(hDevice); + NV_ASSERT(IntType); + NV_ASSERT(IntMotionAxis); + NV_ASSERT(IntTapAxis); + + if ((g_WaitCounter > 0) || ENABLE_XYZ_POLLING) + { + NvOdmOsSemaphoreWaitTimeout( hDevice->SemaphoreForINT, 300); + g_WaitCounter--; + } + else + NvOdmOsSemaphoreWait( hDevice->SemaphoreForINT); +} + +void NvOdmAccelSignal(NvOdmAccelHandle hDevice) +{ + NvOdmOsSemaphoreSignal(hDevice->SemaphoreForINT); +} + +NvBool +NvOdmAccelGetAcceleration( + NvOdmAccelHandle hDevice, + NvS32 *AccelX, + NvS32 *AccelY, + NvS32 *AccelZ) +{ + NvS32 data; + NvBool NewData = 0; + NvS32 TempAccelX = 0; + NvS32 TempAccelY = 0; + NvS32 TempAccelZ = 0; + + NV_ASSERT(NULL != hDevice); + NV_ASSERT(NULL != AccelX); + NV_ASSERT(NULL != AccelY); + NV_ASSERT(NULL != AccelZ); + NewData = BMA150_ReadXYZ(hDevice, &TempAccelX, &TempAccelY, &TempAccelZ); + + data = (((NvS32)(hDevice->Caption.MaxForceInGs))*TempAccelX+(NvS32)(NV_BMA150_MAX_FORCE_IN_REG/2))/ + (NvS32)NV_BMA150_MAX_FORCE_IN_REG; + switch(hDevice->AxisXMapping) + { + case NvOdmAccelAxis_X: + *AccelX = data*hDevice->AxisXDirection; + break; + case NvOdmAccelAxis_Y: + *AccelY = data*hDevice->AxisYDirection; + break; + case NvOdmAccelAxis_Z: + *AccelZ = data*hDevice->AxisZDirection; + break; + default: + return NV_FALSE; + } + + data = (((NvS32)(hDevice->Caption.MaxForceInGs))*TempAccelY+(NvS32)(NV_BMA150_MAX_FORCE_IN_REG/2))/ + (NvS32)NV_BMA150_MAX_FORCE_IN_REG; + switch(hDevice->AxisYMapping) + { + case NvOdmAccelAxis_X: + *AccelX = data*hDevice->AxisXDirection; + break; + case NvOdmAccelAxis_Y: + *AccelY = data*hDevice->AxisYDirection; + break; + case NvOdmAccelAxis_Z: + *AccelZ = data*hDevice->AxisZDirection; + break; + default: + return NV_FALSE; + } + + data = (((NvS32)(hDevice->Caption.MaxForceInGs))*TempAccelZ+(NvS32)(NV_BMA150_MAX_FORCE_IN_REG/2))/ + (NvS32)NV_BMA150_MAX_FORCE_IN_REG; + switch(hDevice->AxisZMapping) + { + case NvOdmAccelAxis_X: + *AccelX = data*hDevice->AxisXDirection; + break; + case NvOdmAccelAxis_Y: + *AccelY = data*hDevice->AxisYDirection; + break; + case NvOdmAccelAxis_Z: + *AccelZ = data*hDevice->AxisZDirection; + break; + default: + return NV_FALSE; + } + + NVODMACCELEROMETER_PRINTF(("\naccel output, x=%d,y=%d,z=%d, NewData=%d", + *AccelX, *AccelY, *AccelZ, NewData)); + return NewData; +} + +NvOdmAccelerometerCaps NvOdmAccelGetCaps(NvOdmAccelHandle hDevice) +{ + NV_ASSERT(NULL != hDevice); + return hDevice->Caption; +} + +NvBool NvOdmAccelSetSampleRate(NvOdmAccelHandle hDevice, NvU32 SampleRate) +{ + return NV_TRUE; +} + +NvBool NvOdmAccelGetSampleRate(NvOdmAccelHandle hDevice, NvU32 *pSampleRate) +{ + return NV_TRUE; +} + +NvBool +NvOdmAccelSetPowerState( + NvOdmAccelHandle hDevice, + NvOdmAccelPowerType PowerState) +{ + return NV_TRUE; +} + diff --git a/arch/arm/mach-tegra/odm_kit/platform/accelerometer/nvodm_accelerometer_bma150.h b/arch/arm/mach-tegra/odm_kit/platform/accelerometer/nvodm_accelerometer_bma150.h new file mode 100644 index 000000000000..1b8efb12ad0c --- /dev/null +++ b/arch/arm/mach-tegra/odm_kit/platform/accelerometer/nvodm_accelerometer_bma150.h @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2010 NVIDIA Corporation. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of the NVIDIA Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + */ + +/* NVIDIA Tegra ODM Kit Sample Accelerometer Adaptation of the + * WinCE Accelerometer Driver + */ + +#ifndef INCLUDED_NVODM_ACCELEROMETER_BMA150_H +#define INCLUDED_NVODM_ACCELEROMETER_BMA150_H + +#if defined(_cplusplus) +extern "C" +{ +#endif + +#include "nvodm_services.h" +#include "nvodm_accelerometer.h" + +/* BMA150 register address */ +#define CHIP_ID_REG 0x00 +#define VERSION_REG 0x01 +#define X_AXIS_LSB_REG 0x02 +#define X_AXIS_MSB_REG 0x03 +#define Y_AXIS_LSB_REG 0x04 +#define Y_AXIS_MSB_REG 0x05 +#define Z_AXIS_LSB_REG 0x06 +#define Z_AXIS_MSB_REG 0x07 +#define TEMP_RD_REG 0x08 +#define SMB150_STATUS_REG 0x09 +#define SMB150_CTRL_REG 0x0a +#define SMB150_CONF1_REG 0x0b +#define LG_THRESHOLD_REG 0x0c +#define LG_DURATION_REG 0x0d +#define HG_THRESHOLD_REG 0x0e +#define HG_DURATION_REG 0x0f +#define MOTION_THRS_REG 0x10 +#define HYSTERESIS_REG 0x11 +#define CUSTOMER1_REG 0x12 +#define CUSTOMER2_REG 0x13 +#define RANGE_BWIDTH_REG 0x14 +#define SMB150_CONF2_REG 0x15 + +#define OFFS_GAIN_X_REG 0x16 +#define OFFS_GAIN_Y_REG 0x17 +#define OFFS_GAIN_Z_REG 0x18 +#define OFFS_GAIN_T_REG 0x19 +#define OFFSET_X_REG 0x1a +#define OFFSET_Y_REG 0x1b +#define OFFSET_Z_REG 0x1c +#define OFFSET_T_REG 0x1d + +/* range and bandwidth */ +#define BMA_RANGE_2G 0 +#define BMA_RANGE_4G 1 +#define BMA_RANGE_8G 2 + +#define BMA_BW_25HZ 0 +#define BMA_BW_50HZ 1 +#define BMA_BW_100HZ 2 +#define BMA_BW_190HZ 3 +#define BMA_BW_375HZ 4 +#define BMA_BW_750HZ 5 +#define BMA_BW_1500HZ 6 + +/* mode settings */ +#define BMA_MODE_NORMAL 0 +#define BMA_MODE_SLEEP 1 + +#define BMA150_CHIP_ID 0x02 // RO - device identification +/* + * Defines the threshold source for the accelerometer. + */ +typedef enum +{ + /// Indicates the accelerometer generated interrupt by exceeding the x threshold. + NvOdmAccelerometerThresholdSource_X = 0, + + /// Indicates the accelerometer generated interrupt by exceeding the y threshold. + NvOdmAccelerometerThresholdSource_Y, + + /// Indicates the accelerometer generated interrupt by exceeding the z threshold. + NvOdmAccelerometerThresholdSource_Z, + + NvOdmAccelerometerThresholdSource_Force32 = 0x7FFFFFFF +} NvOdmAccelerometerThresholdSource; + +// Timeout for I2C transaction. +enum { I2C_ACCELRATOR_TRANSACTION_TIMEOUT = 1000 }; +// Maximum number of packetsize supported by the I2C controller. +enum { I2C_ACCELRATOR_PACKET_SIZE = 8}; +static NvU8 s_ReadBuffer[I2C_ACCELRATOR_PACKET_SIZE]; +static NvU8 s_WriteBuffer[I2C_ACCELRATOR_PACKET_SIZE]; + +#define INT_EVENT_TIMEOUT 100 +#define NV_ACCELEROMETER_BUS_I2C 0 +#define NV_ACCELEROMETER_BUS_SPI_3 1 +#define NV_ACCELEROMETER_BUS_SPI_4 2 + +/* + * Defines the way to read accelerometer registers. + */ +typedef NvBool +(*AccelerometerRegsRead)( + NvOdmAccelHandle hDevice, + NvU8 nRegOffset, + NvU8* nData, + NvU32 nLen); +/* + * Defines the way to write accelerometer registers. + */ +typedef NvBool +(*AccelerometerRegsWrite)( + NvOdmAccelHandle hDevice, + NvU8 nRegOffset, + NvU8* nData, + NvU32 nLen); +/* + * Holds register address and value pairs. + */ +typedef struct NvDevCtrlRegRec { + /// Holds the register offset. + NvU8 RegAddr; + /// Holds the value programmed into the upper address. + NvU8 RegValue; +} NvDevCtrlReg; +/* + * Max accelerometer registers number. + */ +#define ACCELEROMETER_CONTROL_REGS_MAX_LENGHT 100 +/* + * Max accelerometer callback functions number. + */ +#define ACCELEROMETER_CALLBACK_ARRAY_LENGTH 5 + +typedef struct NvOdmAccelRec +{ + // Specifies use I2C or SPI to configure accelerometer registers. + NvU8 nBusType; + // Specifies accelerometer device address, for example, I2C write address. + NvU8 nDevAddr; + // Specifies the initial value that make accelerometer work, + // ACCELEROMETER_CONTROL_REGS_MAX_LENGHT is always 100. + NvDevCtrlReg CtrlRegsList[ACCELEROMETER_CONTROL_REGS_MAX_LENGHT]; + // Specifies the initial CtrlRegsList length. + NvU8 nLength; + // Specifies accelerometer chip ID. + NvU8 nChipID; + // Specifies the way to get accelerometer register information. + AccelerometerRegsRead RegsRead; + // Specifies the way to set accelerometer register information. + AccelerometerRegsWrite RegsWrite; + // Specifies I2C handle from the system. + NvOdmServicesI2cHandle hOdmI2C; + // Interrupt pin to ap15. + NvOdmServicesGpioHandle hGpioINT; + NvOdmGpioPinHandle hPinINT; + NvU32 GPIOPortINT; + NvU32 GPIOPinINT; + NvOdmOsSemaphoreHandle SemaphoreForINT; + NvOdmServicesGpioIntrHandle hGpioInterrupt; + NvOdmAccelIntType Data; + NvOdmServicesPmuHandle hPmu; + NvU32 VddId; + NvU32 I2CChannelId; + NvOdmAccelerometerCaps Caption; + NvOdmAccelPowerType PowerState; + // In real case, when the board put in frontispiece, the value from z axis + // should be g, but due to physical connect on different board, the axis + // should be remapped to the correct one. + NvOdmAccelAxisType AxisXMapping; + // If the physical direct is the same with our expection, the value + // should be set to 1, or else the value should be -1. + NvS32 AxisXDirection; + NvOdmAccelAxisType AxisYMapping; + NvS32 AxisYDirection; + NvOdmAccelAxisType AxisZMapping; + NvS32 AxisZDirection; +} NvOdmAccel; + +#if defined(__cplusplus) +} +#endif +#endif |