diff options
| author | Eric Tashakkor <w36098@motorola.com> | 2014-06-04 15:44:44 -0500 |
|---|---|---|
| committer | ERIC TASHAKKOR <w36098@motorola.com> | 2014-06-10 13:03:53 +0000 |
| commit | e70ac8c9bc07da7767878973a1783b17ec1ea30f (patch) | |
| tree | 7e40cfbf24ea402834dfa3b40ab4672c7af7d972 | |
| parent | bba287631b6c01d978d373c53520b750b9c3135e (diff) | |
| download | olio-linux-3.10-e70ac8c9bc07da7767878973a1783b17ec1ea30f.tar.xz olio-linux-3.10-e70ac8c9bc07da7767878973a1783b17ec1ea30f.zip | |
IKXCLOCK-2012 Add Orientation to Fusion Driver
Added orientation using Euler values from M4.
Change-Id: I3dafb73851d30cef5aa98b84a9bda58839bab7c2
Signed-off-by: Eric Tashakkor <w36098@motorola.com>
| -rw-r--r-- | drivers/misc/m4sensorhub_fusion.c | 74 | ||||
| -rw-r--r-- | include/linux/iio/m4sensorhub/m4sensorhub_fusion.h | 3 |
2 files changed, 66 insertions, 11 deletions
diff --git a/drivers/misc/m4sensorhub_fusion.c b/drivers/misc/m4sensorhub_fusion.c index 512a1be2299..9a6649c2a88 100644 --- a/drivers/misc/m4sensorhub_fusion.c +++ b/drivers/misc/m4sensorhub_fusion.c @@ -44,7 +44,7 @@ struct m4fus_driver_data { struct m4sensorhub_data *m4; struct mutex mutex; /* controls driver entry points */ - struct m4sensorhub_fusion_iio_data iiodat; + struct m4sensorhub_fusion_iio_data iiodat[M4FUS_NUM_FUSION_BUFFERS]; int16_t samplerate; uint16_t status; }; @@ -59,14 +59,14 @@ static void m4fus_isr(enum m4sensorhub_irqs int_event, void *handle) mutex_lock(&(dd->mutex)); size = m4sensorhub_reg_getsize(dd->m4, M4SH_REG_FUSION_ROTATIONVECTOR); - if (size > (sizeof(int32_t) * ARRAY_SIZE(dd->iiodat.values))) { + if (size > (sizeof(int32_t) * ARRAY_SIZE(dd->iiodat[0].values))) { m4fus_err("%s: M4 register is too large.\n", __func__); err = -EOVERFLOW; goto m4fus_isr_fail; } err = m4sensorhub_reg_read(dd->m4, M4SH_REG_FUSION_ROTATIONVECTOR, - (char *)&(dd->iiodat.values[0])); + (char *)&(dd->iiodat[0].values[0])); if (err < 0) { m4fus_err("%s: Failed to read rotation data.\n", __func__); goto m4fus_isr_fail; @@ -77,9 +77,57 @@ static void m4fus_isr(enum m4sensorhub_irqs int_event, void *handle) goto m4fus_isr_fail; } - dd->iiodat.type = FUSION_TYPE_ROTATION; - dd->iiodat.timestamp = iio_get_time_ns(); - iio_push_to_buffers(iio, (unsigned char *)&(dd->iiodat)); + dd->iiodat[0].type = FUSION_TYPE_ROTATION; + dd->iiodat[0].timestamp = iio_get_time_ns(); + + size = m4sensorhub_reg_getsize(dd->m4, M4SH_REG_FUSION_EULERPITCH); + err = m4sensorhub_reg_read(dd->m4, M4SH_REG_FUSION_EULERPITCH, + (char *)&(dd->iiodat[1].values[0])); + if (err < 0) { + m4fus_err("%s: Failed to read euler_pitch data.\n", __func__); + goto m4fus_isr_fail; + } else if (err != size) { + m4fus_err("%s: Read %d bytes instead of %d for %s.\n", + __func__, err, size, "euler_pitch"); + err = -EBADE; + goto m4fus_isr_fail; + } + + size = m4sensorhub_reg_getsize(dd->m4, M4SH_REG_FUSION_EULERROLL); + err = m4sensorhub_reg_read(dd->m4, M4SH_REG_FUSION_EULERROLL, + (char *)&(dd->iiodat[1].values[1])); + if (err < 0) { + m4fus_err("%s: Failed to read euler_roll data.\n", __func__); + goto m4fus_isr_fail; + } else if (err != size) { + m4fus_err("%s: Read %d bytes instead of %d for %s.\n", + __func__, err, size, "euler_roll"); + err = -EBADE; + goto m4fus_isr_fail; + } + + size = m4sensorhub_reg_getsize(dd->m4, M4SH_REG_FUSION_HEADING); + err = m4sensorhub_reg_read(dd->m4, M4SH_REG_FUSION_HEADING, + (char *)&(dd->iiodat[1].values[2])); + if (err < 0) { + m4fus_err("%s: Failed to read heading data.\n", __func__); + goto m4fus_isr_fail; + } else if (err != size) { + m4fus_err("%s: Read %d bytes instead of %d for %s.\n", + __func__, err, size, "heading"); + err = -EBADE; + goto m4fus_isr_fail; + } + + dd->iiodat[1].type = FUSION_TYPE_ORIENTATION; + dd->iiodat[1].timestamp = iio_get_time_ns(); + + /* + * For some reason, IIO knows we are sending an array, + * so all FUSION_TYPE_* indicies will be sent + * in this one call (see the M4 passive driver). + */ + iio_push_to_buffers(iio, (unsigned char *)&(dd->iiodat[0])); m4fus_isr_fail: if (err < 0) @@ -209,11 +257,15 @@ static ssize_t m4fus_iiodata_show(struct device *dev, ssize_t size = 0; mutex_lock(&(dd->mutex)); - size = snprintf(buf, PAGE_SIZE, "%s%d\n%s%d\n%s%d\n%s%d\n", - "rotation[0]: ", dd->iiodat.values[0], - "rotation[1]: ", dd->iiodat.values[1], - "rotation[2]: ", dd->iiodat.values[2], - "rotation[3]: ", dd->iiodat.values[3]); + size = snprintf(buf, PAGE_SIZE, + "%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%d\n%s%hd\n", + "rotation[0]: ", dd->iiodat[0].values[0], + "rotation[1]: ", dd->iiodat[0].values[1], + "rotation[2]: ", dd->iiodat[0].values[2], + "rotation[3]: ", dd->iiodat[0].values[3], + "euler_pitch: ", dd->iiodat[1].values[0], + "euler_roll: ", dd->iiodat[1].values[1], + "heading: ", dd->iiodat[1].values[2]); mutex_unlock(&(dd->mutex)); return size; } diff --git a/include/linux/iio/m4sensorhub/m4sensorhub_fusion.h b/include/linux/iio/m4sensorhub/m4sensorhub_fusion.h index fc116e6e6b0..57680018826 100644 --- a/include/linux/iio/m4sensorhub/m4sensorhub_fusion.h +++ b/include/linux/iio/m4sensorhub/m4sensorhub_fusion.h @@ -25,6 +25,7 @@ enum m4sensorhub_fusion_iio_type { FUSION_TYPE_ROTATION = 0, + FUSION_TYPE_ORIENTATION = 1, }; struct m4sensorhub_fusion_iio_data { @@ -37,4 +38,6 @@ struct m4sensorhub_fusion_iio_data { #define M4FUS_DATA_STRUCT_SIZE_BITS \ (sizeof(struct m4sensorhub_fusion_iio_data) * 8) +#define M4FUS_NUM_FUSION_BUFFERS 2 + #endif /* _M4SENSORHUB_FUSION_IIO_H */ |