summaryrefslogtreecommitdiff
path: root/drivers/misc/mpu3050/compass/ak8975.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/misc/mpu3050/compass/ak8975.c')
-rw-r--r--drivers/misc/mpu3050/compass/ak8975.c95
1 files changed, 66 insertions, 29 deletions
diff --git a/drivers/misc/mpu3050/compass/ak8975.c b/drivers/misc/mpu3050/compass/ak8975.c
index 18606e240f1c..991de77dbd01 100644
--- a/drivers/misc/mpu3050/compass/ak8975.c
+++ b/drivers/misc/mpu3050/compass/ak8975.c
@@ -25,12 +25,14 @@
* @{
* @file AK8975.c
* @brief Magnetometer setup and handling methods for AKM 8975 compass.
-**/
+ */
/* ------------------ */
/* - Include Files. - */
/* ------------------ */
+#include <string.h>
+
#ifdef __KERNEL__
#include <linux/module.h>
#endif
@@ -84,44 +86,78 @@ int ak8975_read(void *mlsl_handle,
struct ext_slave_descr *slave,
struct ext_slave_platform_data *pdata, unsigned char *data)
{
- unsigned char stat;
- unsigned char stat2;
+ unsigned char regs[8];
+ unsigned char *stat = &regs[0];
+ unsigned char *stat2 = &regs[7];
int result = ML_SUCCESS;
+ int status = ML_SUCCESS;
result =
- MLSLSerialRead(mlsl_handle, pdata->address, AK8975_REG_ST1, 1,
- &stat);
+ MLSLSerialRead(mlsl_handle, pdata->address, AK8975_REG_ST1,
+ 8, regs);
ERROR_CHECK(result);
- if (stat & 0x01) {
- result =
- MLSLSerialRead(mlsl_handle, pdata->address,
- AK8975_REG_HXL, 6,
- (unsigned char *) data);
- ERROR_CHECK(result);
- result =
- MLSLSerialRead(mlsl_handle, pdata->address,
- AK8975_REG_ST2, 1, &stat2);
- ERROR_CHECK(result);
- if (stat2 & 0x04) /* data error */
- return ML_ERROR_COMPASS_DATA_NOT_READY;
- if (stat2 & 0x08)
- return ML_ERROR_COMPASS_DATA_OVERFLOW;
+ /*
+ * ST : data ready -
+ * Measurement has been completed and data is ready to be read.
+ */
+ if (*stat & 0x01) {
+ memcpy(data, &regs[1], 6);
+ status = ML_SUCCESS;
+ }
+
+ /*
+ * ST2 : data error -
+ * occurs when data read is started outside of a readable period;
+ * data read would not be correct.
+ * Valid in continuous measurement mode only.
+ * In single measurement mode this error should not occour but we
+ * stil account for it and return an error, since the data would be
+ * corrupted.
+ * DERR bit is self-clearing when ST2 register is read.
+ */
+ if (*stat2 & 0x04)
+ status = ML_ERROR_COMPASS_DATA_ERROR;
+ /*
+ * ST2 : overflow -
+ * the sum of the absolute values of all axis |X|+|Y|+|Z| < 2400uT.
+ * This is likely to happen in presence of an external magnetic
+ * disturbance; it indicates, the sensor data is incorrect and should
+ * be ignored.
+ * An error is returned.
+ * HOFL bit clears when a new measurement starts.
+ */
+ if (*stat2 & 0x08)
+ status = ML_ERROR_COMPASS_DATA_OVERFLOW;
+ /*
+ * ST : overrun -
+ * the previous sample was not fetched and lost.
+ * Valid in continuous measurement mode only.
+ * In single measurement mode this error should not occour and we
+ * don't consider this condition an error.
+ * DOR bit is self-clearing when ST2 or any meas. data register is
+ * read.
+ */
+ if (*stat & 0x02) {
+ /* status = ML_ERROR_COMPASS_DATA_UNDERFLOW; */
+ status = ML_SUCCESS;
+ }
+
+ /*
+ * trigger next measurement if:
+ * - stat is non zero;
+ * - if stat is zero and stat2 is non zero.
+ * Won't trigger if data is not ready and there was no error.
+ */
+ if (*stat != 0x00 || *stat2 != 0x00) {
result =
MLSLSerialWriteSingle(mlsl_handle, pdata->address,
AK8975_REG_CNTL,
AK8975_CNTL_MODE_SINGLE_MEASUREMENT);
ERROR_CHECK(result);
- return ML_SUCCESS;
- } else if (stat & 0x02) {
- result =
- MLSLSerialRead(mlsl_handle, pdata->address,
- AK8975_REG_ST2, 1, &stat2);
- ERROR_CHECK(result);
- return ML_ERROR_COMPASS_DATA_OVERFLOW;
- } else {
- return ML_ERROR_COMPASS_DATA_NOT_READY;
}
+
+ return status;
}
struct ext_slave_descr ak8975_descr = {
@@ -131,6 +167,7 @@ struct ext_slave_descr ak8975_descr = {
/*.resume = */ ak8975_resume,
/*.read = */ ak8975_read,
/*.config = */ NULL,
+ /*.get_config = */ NULL,
/*.name = */ "ak8975",
/*.type = */ EXT_SLAVE_TYPE_COMPASS,
/*.id = */ COMPASS_ID_AKM,
@@ -148,4 +185,4 @@ EXPORT_SYMBOL(ak8975_get_slave_descr);
/**
* @}
-**/
+ */