summaryrefslogtreecommitdiffstats
path: root/sensors/akm8975.c
diff options
context:
space:
mode:
authorWolfgang Wiedmeyer <wolfgit@wiedmeyer.de>2017-01-13 12:55:00 +0100
committerWolfgang Wiedmeyer <wolfgit@wiedmeyer.de>2017-01-13 12:55:00 +0100
commit3487b6cccff1251bd043bf6c9d83541a84654398 (patch)
tree1edaed9213e30ad2e22e60c069025f81a2f328ff /sensors/akm8975.c
parent719298e8ec1a32ef72c7c3b34a29f6da5636e2e5 (diff)
downloaddevice_samsung_i9100-3487b6cccff1251bd043bf6c9d83541a84654398.zip
device_samsung_i9100-3487b6cccff1251bd043bf6c9d83541a84654398.tar.gz
device_samsung_i9100-3487b6cccff1251bd043bf6c9d83541a84654398.tar.bz2
Squashed sensor updates from i9300
The following commits were ported to the i9100 sensors: commit 0f8e8cc Author: Christian Balster <christian.balster@gmail.com> Date: Wed May 20 13:19:48 2015 +0200 i9300: libsensors: add real accuracy reporting for magnetometer Change-Id: I3dd56f4d7fb0de8feca2422c165fe0c3cd92761a commit 2104318 Author: Christian Balster <christian.balster@gmail.com> Date: Wed May 20 17:14:11 2015 +0200 i9300: libsensors: fix typo in accelerometer data Change-Id: Iee501b65c23bed22bfe769496bafc852f939a8ac commit b69dd87 Author: Christian Balster <christian.balster@gmail.com> Date: Wed May 20 17:16:29 2015 +0200 i9300: libsensors: report at least bogus accuracy for gyro Change-Id: I81ff71c8ae6bf25c1aabac4a6d8d6fcf64bd2e0b commit d786475 Author: Christian Balster <christian.balster@gmail.com> Date: Thu May 21 17:46:00 2015 +0200 i9300: libsensors: fix magnetometer offset parameters not being saved also fix a typo Change-Id: I69246a96c53d7ec02ca90d73bc85dec4cbc73343 commit f7d2dfd Author: Christian Balster <christian.balster@gmail.com> Date: Tue Jun 2 15:08:02 2015 +0200 i9300: libsensors: remove unused orientation sensor The Orientation Sensor is deprecated and no longer required. Additionally this implementation is never even used, since Android automatically replaces it by it's own implementation if the sensor HAL doesn't also provide a Rotation Vector sensor. Furthermore the current implementation only uses the accelerometer and magnetometer for the sensor fusion and doesn't make use of the Gyroscope. So should we at some point decide to implement our own complete sensor fusion this would have to be rewritten anyway. Change-Id: I45d8a9afd2089b49131e6cc69cdf2f3dfee46c92 commit fc862f3 Author: Dheeraj CVR <cvr.dheeraj@gmail.com> Date: Thu Jun 11 16:44:25 2015 +0400 libsensors: switch to portable typedefs to match callbacks Using a strict basetype only coding style is not a good idea especially when we are dealing with callbacks which use portable typedef like int64_t. This kind of coding style would most likely end up in overflows at various places especially when dealing with timestamps and sensor delays which are caused when typecasting datatypes of different size. Switch to portable typedefs and get rid of "long". Change-Id: I75b9cace7602345dba9095f046292e6d4db07df4 commit a484daf Author: Christian Balster <christian.balster@gmail.com> Date: Mon Jun 15 17:46:29 2015 +0200 i9300: libsensors: fix possible overflow while setting delay Even though we changed the signature of the set_delay() methods, we can still get an overflow while actually writing the values to sysfs. Let's adapt sysfs_value_read() and sysfs_value_write() too. Change-Id: If8eda7204831f0edabec890d4e3127be520fa3bf commit 594d5b8 Author: Dheeraj CVR <cvr.dheeraj@gmail.com> Date: Thu Jun 11 17:57:26 2015 +0400 libsensors: update sensor flags Change-Id: Ia57026f4e8f5dd270da7619bc25289fc414bce30 There is one commit that has fixes for the light sensor, but I didn't look into it: ea6c7d9 libsensors: fix light sensor This one likely needs to be ported, too. Signed-off-by: Wolfgang Wiedmeyer <wolfgit@wiedmeyer.de>
Diffstat (limited to 'sensors/akm8975.c')
-rw-r--r--sensors/akm8975.c78
1 files changed, 47 insertions, 31 deletions
diff --git a/sensors/akm8975.c b/sensors/akm8975.c
index 52a905b..b3c2b94 100644
--- a/sensors/akm8975.c
+++ b/sensors/akm8975.c
@@ -39,12 +39,10 @@
#define AKFS_PAT PAT2
struct akm8975_data {
- struct smdk4210_sensors_handlers *orientation_sensor;
-
AK8975PRMS akfs_params;
sensors_vec_t magnetic;
- long int delay;
+ int64_t delay;
int device_fd;
int uinput_fd;
@@ -56,7 +54,8 @@ struct akm8975_data {
int akfs_get_magnetic_field(struct akm8975_data *akm8975_data, short *magnetic_data)
{
AK8975PRMS *params;
- int rc;
+ int rc, aocret;
+ float radius;
if (akm8975_data == NULL || magnetic_data == NULL)
return -EINVAL;
@@ -80,7 +79,7 @@ int akfs_get_magnetic_field(struct akm8975_data *akm8975_data, short *magnetic_d
// AOC for magnetometer
// Offset estimation is done in this function
- AKFS_AOC(&params->m_aocv, params->mfv_hdata, &params->mfv_ho);
+ aocret = AKFS_AOC(&params->m_aocv, params->mfv_hdata, &params->mfv_ho);
// Subtract offset
// Then, a magnetic vector, the unit is uT, is stored in mfv_hvbuf.
@@ -99,9 +98,25 @@ int akfs_get_magnetic_field(struct akm8975_data *akm8975_data, short *magnetic_d
return -1;
}
+ // Check the size of magnetic vector
+ radius = sqrtf(
+ (params->mfv_hvec.u.x * params->mfv_hvec.u.x) +
+ (params->mfv_hvec.u.y * params->mfv_hvec.u.y) +
+ (params->mfv_hvec.u.z * params->mfv_hvec.u.z));
+
+ // Sanity check result and set accuracy
+ if ((radius > MAGNETIC_FIELD_EARTH_MAX + 10) || (radius < MAGNETIC_FIELD_EARTH_MIN - 10)) {
+ params->mi_hstatus = SENSOR_STATUS_UNRELIABLE;
+ } else if(params->mi_hstatus == SENSOR_STATUS_UNRELIABLE) {
+ params->mi_hstatus = SENSOR_STATUS_ACCURACY_MEDIUM;
+ } else if (aocret == AKFS_SUCCESS) {
+ params->mi_hstatus = SENSOR_STATUS_ACCURACY_HIGH;
+ }
+
akm8975_data->magnetic.x = params->mfv_hvec.u.x;
akm8975_data->magnetic.y = params->mfv_hvec.u.y;
akm8975_data->magnetic.z = params->mfv_hvec.u.z;
+ akm8975_data->magnetic.status = params->mi_hstatus;
return 0;
}
@@ -151,7 +166,7 @@ void *akm8975_thread(void *thread_data)
char i2c_data[SENSOR_DATA_SIZE] = { 0 };
short magnetic_data[3];
short mode;
- long int before, after;
+ int64_t before, after;
int diff;
int device_fd;
int uinput_fd;
@@ -223,6 +238,8 @@ void *akm8975_thread(void *thread_data)
write(uinput_fd, &event, sizeof(event));
input_event_set(&event, EV_REL, REL_Z, (int) (data->magnetic.z * 1000));
write(uinput_fd, &event, sizeof(event));
+ input_event_set(&event, EV_REL, REL_MISC, (int) data->magnetic.status);
+ write(uinput_fd, &event, sizeof(event));
input_event_set(&event, EV_SYN, 0, 0);
write(uinput_fd, &event, sizeof(event));
@@ -259,14 +276,6 @@ int akm8975_init(struct smdk4210_sensors_handlers *handlers,
data = (struct akm8975_data *) calloc(1, sizeof(struct akm8975_data));
- for (i = 0; i < device->handlers_count; i++) {
- if (device->handlers[i] == NULL)
- continue;
-
- if (device->handlers[i]->handle == SENSOR_TYPE_ORIENTATION)
- data->orientation_sensor = device->handlers[i];
- }
-
device_fd = open("/dev/akm8975", O_RDONLY);
if (device_fd < 0) {
ALOGE("%s: Unable to open device", __func__);
@@ -308,7 +317,7 @@ int akm8975_init(struct smdk4210_sensors_handlers *handlers,
i2c_data[1] = AK8975_REG_WIA;
rc = ioctl(device_fd, ECS_IOCTL_READ, &i2c_data);
if (rc < 0) {
- ALOGE("%s: Unable to read akm8975 FUSE data", __func__);
+ ALOGE("%s: Unable to read akm8975 WIA data", __func__);
goto error;
}
@@ -434,8 +443,15 @@ int akm8975_activate(struct smdk4210_sensors_handlers *handlers)
// Read settings from a file
rc = AKFS_LoadParameters(akfs_params, AKFS_CONFIG_PATH);
- if (rc != AKM_SUCCESS)
- ALOGE("%s: Unable to read AKFS parameters", __func__);
+ if (rc != AKM_SUCCESS) {
+ ALOGE("%s: Unable to read AKFS HO parameters", __func__);
+ akfs_params->mfv_ho.u.x = 0.0f;
+ akfs_params->mfv_ho.u.y = 0.0f;
+ akfs_params->mfv_ho.u.z = 0.0f;
+ } else {
+ ALOGD("AKM8975 HO (Offset Adjustment) parameters read are: (%f, %f, %f)",
+ akfs_params->mfv_ho.u.x, akfs_params->mfv_ho.u.y, akfs_params->mfv_ho.u.z);
+ }
// Initialize buffer
AKFS_InitBuffer(AKFS_HDATA_SIZE, akfs_params->mfv_hdata);
@@ -446,7 +462,7 @@ int akm8975_activate(struct smdk4210_sensors_handlers *handlers)
// Initialize for AOC
AKFS_InitAOC(&akfs_params->m_aocv);
// Initialize magnetic status
- akfs_params->mi_hstatus = 0;
+ akfs_params->mi_hstatus = SENSOR_STATUS_UNRELIABLE;
handlers->activated = 1;
pthread_mutex_unlock(&data->mutex);
@@ -478,18 +494,20 @@ int akm8975_deactivate(struct smdk4210_sensors_handlers *handlers)
empty = 1;
- for (i = 0; i < 3; i++) {
- if (akfs_params->mfv_ho.v[i] != 0) {
- empty = 0;
- break;
- }
+ if ((akfs_params->mfv_ho.u.x != 0.0f) || (akfs_params->mfv_ho.u.y != 0.0f) ||
+ (akfs_params->mfv_ho.u.z != 0.0f)) {
+ empty = 0;
}
if (!empty) {
// Write settings to a file
rc = AKFS_SaveParameters(akfs_params, AKFS_CONFIG_PATH);
- if (rc != AKM_SUCCESS)
- ALOGE("%s: Unable to write AKFS parameters", __func__);
+ if (rc != AKM_SUCCESS) {
+ ALOGE("%s: Unable to write AKFS HO parameters", __func__);
+ } else {
+ ALOGD("AKM8975 HO (Offset Adjustment) parameters written are: (%f, %f, %f)",
+ akfs_params->mfv_ho.u.x, akfs_params->mfv_ho.u.y, akfs_params->mfv_ho.u.z);
+ }
}
mode = AK8975_MODE_POWER_DOWN;
@@ -502,7 +520,7 @@ int akm8975_deactivate(struct smdk4210_sensors_handlers *handlers)
return 0;
}
-int akm8975_set_delay(struct smdk4210_sensors_handlers *handlers, long int delay)
+int akm8975_set_delay(struct smdk4210_sensors_handlers *handlers, int64_t delay)
{
struct akm8975_data *data;
@@ -547,8 +565,6 @@ int akm8975_get_data(struct smdk4210_sensors_handlers *handlers,
event->sensor = handlers->handle;
event->type = handlers->handle;
- event->magnetic.status = SENSOR_STATUS_ACCURACY_MEDIUM;
-
do {
rc = read(input_fd, &input_event, sizeof(input_event));
if (rc < (int) sizeof(input_event))
@@ -565,6 +581,9 @@ int akm8975_get_data(struct smdk4210_sensors_handlers *handlers,
case REL_Z:
event->magnetic.z = akm8975_convert(input_event.value);
break;
+ case REL_MISC:
+ event->magnetic.status = input_event.value;
+ break;
default:
continue;
}
@@ -574,9 +593,6 @@ int akm8975_get_data(struct smdk4210_sensors_handlers *handlers,
}
} while (input_event.type != EV_SYN);
- if (data->orientation_sensor != NULL)
- orientation_fill(data->orientation_sensor, NULL, &event->magnetic);
-
return 0;
}