From mboxrd@z Thu Jan 1 00:00:00 1970 From: Gregor Boirie Subject: [RFC PATCH v1 3/3] iio:imu:mpu6050: enhance mounting matrix support Date: Fri, 8 Apr 2016 16:12:05 +0200 Message-ID: <594bc2f45d1894c9c3308509062b991e4a5fcc7e.1460113510.git.gregor.boirie@parrot.com> References: Mime-Version: 1.0 Content-Type: text/plain Return-path: In-Reply-To: Sender: linux-iio-owner-u79uwXL29TY76Z2rM5mHXA@public.gmane.org To: linux-iio-u79uwXL29TY76Z2rM5mHXA@public.gmane.org Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, Rob Herring , Jonathan Cameron , Hartmut Knaack , Lars-Peter Clausen , Peter Meerwald-Stadler , Matt Ranostay , Daniel Baluta , Vladimir Barinov , Martin Fuzzey , Cristina Opriceana , Varka Bhadram , Adriana Reus , Lucas De Marchi , Julia Lawall , Gregor Boirie List-Id: devicetree@vger.kernel.org Add a new rotation matrix sysfs attribute compliant with IIO core mounting matrix API. Matrix is retrieved from "in_anglvel_mount_matrix" and "in_accel_mount_matrix" sysfs attributes. It is declared into mpu6050 DTS entry as a "mount-matrix" property. Old interface is kept for backward userspace compatibility and may be retrieved from legacy platform_data mechanism only. Signed-off-by: Gregor Boirie --- .../devicetree/bindings/iio/imu/inv_mpu6050.txt | 13 +++++ drivers/iio/imu/inv_mpu6050/inv_mpu_core.c | 56 ++++++++++++++++++++-- drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h | 4 +- include/linux/platform_data/invensense_mpu6050.h | 5 +- 4 files changed, 72 insertions(+), 6 deletions(-) diff --git a/Documentation/devicetree/bindings/iio/imu/inv_mpu6050.txt b/Documentation/devicetree/bindings/iio/imu/inv_mpu6050.txt index e4d8f1c..a9fc11e 100644 --- a/Documentation/devicetree/bindings/iio/imu/inv_mpu6050.txt +++ b/Documentation/devicetree/bindings/iio/imu/inv_mpu6050.txt @@ -8,10 +8,23 @@ Required properties: - interrupt-parent : should be the phandle for the interrupt controller - interrupts : interrupt mapping for GPIO IRQ +Optional properties: + - mount-matrix: an optional 3x3 mounting rotation matrix + + Example: mpu6050@68 { compatible = "invensense,mpu6050"; reg = <0x68>; interrupt-parent = <&gpio1>; interrupts = <18 1>; + mount-matrix = "-0.984807753012208", /* x0 */ + "0", /* y0 */ + "-0.173648177666930", /* z0 */ + "0", /* x1 */ + "-1", /* y1 */ + "0", /* z1 */ + "-0.173648177666930", /* x2 */ + "0", /* y2 */ + "0.984807753012208"; /* z2 */ }; diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c index d192953..deb93bc 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c @@ -599,7 +599,11 @@ inv_fifo_rate_show(struct device *dev, struct device_attribute *attr, /** * inv_attr_show() - calling this function will show current - * parameters. + * parameters. + * + * Deprecated in favor of IIO mounting matrix API. + * + * See inv_show_mount_matrix() */ static ssize_t inv_attr_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -625,6 +629,30 @@ static ssize_t inv_attr_show(struct device *dev, struct device_attribute *attr, } /** + * inv_show_mount_matrix() - calling this function will show current sensor's + * orientation. + */ +static ssize_t inv_show_mount_matrix(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct inv_mpu6050_state *st = iio_priv(dev_to_iio_dev(dev)); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + switch (this_attr->address) { + /* + * In MPU6050, the two matrix are the same because gyro and accel + * are integrated in one chip + */ + case ATTR_GYRO_MATRIX: + case ATTR_ACCL_MATRIX: + return iio_show_mount_matrix(&st->orientation, buf); + default: + return -EINVAL; + } +} + +/** * inv_mpu6050_validate_trigger() - validate_trigger callback for invensense * MPU6050 device. * @indio_dev: The IIO device @@ -692,14 +720,23 @@ static IIO_CONST_ATTR(in_accel_scale_available, "0.000598 0.001196 0.002392 0.004785"); static IIO_DEV_ATTR_SAMP_FREQ(S_IRUGO | S_IWUSR, inv_fifo_rate_show, inv_mpu6050_fifo_rate_store); + +/* Deprecated: kept for userspace backward compatibility. */ static IIO_DEVICE_ATTR(in_gyro_matrix, S_IRUGO, inv_attr_show, NULL, ATTR_GYRO_MATRIX); static IIO_DEVICE_ATTR(in_accel_matrix, S_IRUGO, inv_attr_show, NULL, ATTR_ACCL_MATRIX); +/* Replacement for old matrix attribute interface. */ +static IIO_DEV_ATTR_MOUNT_MATRIX(in_anglvel_mount_matrix, inv_show_mount_matrix, + ATTR_GYRO_MATRIX); +static IIO_DEV_ATTR_MOUNT_MATRIX(in_accel_mount_matrix, inv_show_mount_matrix, + ATTR_ACCL_MATRIX); static struct attribute *inv_attributes[] = { - &iio_dev_attr_in_gyro_matrix.dev_attr.attr, - &iio_dev_attr_in_accel_matrix.dev_attr.attr, + &iio_dev_attr_in_gyro_matrix.dev_attr.attr, /* deprecated */ + &iio_dev_attr_in_accel_matrix.dev_attr.attr,/* deprecated */ + &iio_dev_attr_in_anglvel_mount_matrix.dev_attr.attr, + &iio_dev_attr_in_accel_mount_matrix.dev_attr.attr, &iio_dev_attr_sampling_frequency.dev_attr.attr, &iio_const_attr_sampling_frequency_available.dev_attr.attr, &iio_const_attr_in_accel_scale_available.dev_attr.attr, @@ -779,9 +816,20 @@ int inv_mpu_core_probe(struct regmap *regmap, int irq, const char *name, st->powerup_count = 0; st->irq = irq; st->map = regmap; + pdata = dev_get_platdata(dev); - if (pdata) + if (!pdata) { + result = of_iio_read_mount_matrix(dev, "mount-matrix", + &st->orientation); + if (result) { + dev_err(dev, "Failed to retrieve mounting matrix %d\n", + result); + return result; + } + } else { st->plat_data = *pdata; + } + /* power is turned on inside check chip type*/ result = inv_check_and_setup_chip(st); if (result) diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h index e302a49..52d60cd 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h @@ -114,7 +114,8 @@ struct inv_mpu6050_hw { * @hw: Other hardware-specific information. * @chip_type: chip type. * @time_stamp_lock: spin lock to time stamp. - * @plat_data: platform data. + * @plat_data: platform data (deprecated in favor of @orientation). + * @orientation: sensor chip orientation relative to main hardware. * @timestamps: kfifo queue to store time stamp. * @map regmap pointer. * @irq interrupt number. @@ -131,6 +132,7 @@ struct inv_mpu6050_state { struct i2c_client *mux_client; unsigned int powerup_count; struct inv_mpu6050_platform_data plat_data; + struct iio_mount_matrix orientation; DECLARE_KFIFO(timestamps, long long, TIMESTAMP_FIFO_SIZE); struct regmap *map; int irq; diff --git a/include/linux/platform_data/invensense_mpu6050.h b/include/linux/platform_data/invensense_mpu6050.h index ad3aa7b..554b598 100644 --- a/include/linux/platform_data/invensense_mpu6050.h +++ b/include/linux/platform_data/invensense_mpu6050.h @@ -16,13 +16,16 @@ /** * struct inv_mpu6050_platform_data - Platform data for the mpu driver - * @orientation: Orientation matrix of the chip + * @orientation: Orientation matrix of the chip (deprecated in favor of + * mounting matrix retrieved from device-tree) * * Contains platform specific information on how to configure the MPU6050 to * work on this platform. The orientation matricies are 3x3 rotation matricies * that are applied to the data to rotate from the mounting orientation to the * platform orientation. The values must be one of 0, 1, or -1 and each row and * column should have exactly 1 non-zero value. + * + * Deprecated in favor of mounting matrix retrieved from device-tree. */ struct inv_mpu6050_platform_data { __s8 orientation[9]; -- 2.1.4 From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: From: Gregor Boirie To: CC: , Rob Herring , Jonathan Cameron , Hartmut Knaack , Lars-Peter Clausen , Peter Meerwald-Stadler , Matt Ranostay , Daniel Baluta , Vladimir Barinov , Martin Fuzzey , Cristina Opriceana , Varka Bhadram , Adriana Reus , Lucas De Marchi , Julia Lawall , Gregor Boirie Subject: [RFC PATCH v1 3/3] iio:imu:mpu6050: enhance mounting matrix support Date: Fri, 8 Apr 2016 16:12:05 +0200 Message-ID: <594bc2f45d1894c9c3308509062b991e4a5fcc7e.1460113510.git.gregor.boirie@parrot.com> In-Reply-To: References: MIME-Version: 1.0 Content-Type: text/plain List-ID: Add a new rotation matrix sysfs attribute compliant with IIO core mounting matrix API. Matrix is retrieved from "in_anglvel_mount_matrix" and "in_accel_mount_matrix" sysfs attributes. It is declared into mpu6050 DTS entry as a "mount-matrix" property. Old interface is kept for backward userspace compatibility and may be retrieved from legacy platform_data mechanism only. Signed-off-by: Gregor Boirie --- .../devicetree/bindings/iio/imu/inv_mpu6050.txt | 13 +++++ drivers/iio/imu/inv_mpu6050/inv_mpu_core.c | 56 ++++++++++++++++++++-- drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h | 4 +- include/linux/platform_data/invensense_mpu6050.h | 5 +- 4 files changed, 72 insertions(+), 6 deletions(-) diff --git a/Documentation/devicetree/bindings/iio/imu/inv_mpu6050.txt b/Documentation/devicetree/bindings/iio/imu/inv_mpu6050.txt index e4d8f1c..a9fc11e 100644 --- a/Documentation/devicetree/bindings/iio/imu/inv_mpu6050.txt +++ b/Documentation/devicetree/bindings/iio/imu/inv_mpu6050.txt @@ -8,10 +8,23 @@ Required properties: - interrupt-parent : should be the phandle for the interrupt controller - interrupts : interrupt mapping for GPIO IRQ +Optional properties: + - mount-matrix: an optional 3x3 mounting rotation matrix + + Example: mpu6050@68 { compatible = "invensense,mpu6050"; reg = <0x68>; interrupt-parent = <&gpio1>; interrupts = <18 1>; + mount-matrix = "-0.984807753012208", /* x0 */ + "0", /* y0 */ + "-0.173648177666930", /* z0 */ + "0", /* x1 */ + "-1", /* y1 */ + "0", /* z1 */ + "-0.173648177666930", /* x2 */ + "0", /* y2 */ + "0.984807753012208"; /* z2 */ }; diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c index d192953..deb93bc 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c @@ -599,7 +599,11 @@ inv_fifo_rate_show(struct device *dev, struct device_attribute *attr, /** * inv_attr_show() - calling this function will show current - * parameters. + * parameters. + * + * Deprecated in favor of IIO mounting matrix API. + * + * See inv_show_mount_matrix() */ static ssize_t inv_attr_show(struct device *dev, struct device_attribute *attr, char *buf) @@ -625,6 +629,30 @@ static ssize_t inv_attr_show(struct device *dev, struct device_attribute *attr, } /** + * inv_show_mount_matrix() - calling this function will show current sensor's + * orientation. + */ +static ssize_t inv_show_mount_matrix(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct inv_mpu6050_state *st = iio_priv(dev_to_iio_dev(dev)); + struct iio_dev_attr *this_attr = to_iio_dev_attr(attr); + + switch (this_attr->address) { + /* + * In MPU6050, the two matrix are the same because gyro and accel + * are integrated in one chip + */ + case ATTR_GYRO_MATRIX: + case ATTR_ACCL_MATRIX: + return iio_show_mount_matrix(&st->orientation, buf); + default: + return -EINVAL; + } +} + +/** * inv_mpu6050_validate_trigger() - validate_trigger callback for invensense * MPU6050 device. * @indio_dev: The IIO device @@ -692,14 +720,23 @@ static IIO_CONST_ATTR(in_accel_scale_available, "0.000598 0.001196 0.002392 0.004785"); static IIO_DEV_ATTR_SAMP_FREQ(S_IRUGO | S_IWUSR, inv_fifo_rate_show, inv_mpu6050_fifo_rate_store); + +/* Deprecated: kept for userspace backward compatibility. */ static IIO_DEVICE_ATTR(in_gyro_matrix, S_IRUGO, inv_attr_show, NULL, ATTR_GYRO_MATRIX); static IIO_DEVICE_ATTR(in_accel_matrix, S_IRUGO, inv_attr_show, NULL, ATTR_ACCL_MATRIX); +/* Replacement for old matrix attribute interface. */ +static IIO_DEV_ATTR_MOUNT_MATRIX(in_anglvel_mount_matrix, inv_show_mount_matrix, + ATTR_GYRO_MATRIX); +static IIO_DEV_ATTR_MOUNT_MATRIX(in_accel_mount_matrix, inv_show_mount_matrix, + ATTR_ACCL_MATRIX); static struct attribute *inv_attributes[] = { - &iio_dev_attr_in_gyro_matrix.dev_attr.attr, - &iio_dev_attr_in_accel_matrix.dev_attr.attr, + &iio_dev_attr_in_gyro_matrix.dev_attr.attr, /* deprecated */ + &iio_dev_attr_in_accel_matrix.dev_attr.attr,/* deprecated */ + &iio_dev_attr_in_anglvel_mount_matrix.dev_attr.attr, + &iio_dev_attr_in_accel_mount_matrix.dev_attr.attr, &iio_dev_attr_sampling_frequency.dev_attr.attr, &iio_const_attr_sampling_frequency_available.dev_attr.attr, &iio_const_attr_in_accel_scale_available.dev_attr.attr, @@ -779,9 +816,20 @@ int inv_mpu_core_probe(struct regmap *regmap, int irq, const char *name, st->powerup_count = 0; st->irq = irq; st->map = regmap; + pdata = dev_get_platdata(dev); - if (pdata) + if (!pdata) { + result = of_iio_read_mount_matrix(dev, "mount-matrix", + &st->orientation); + if (result) { + dev_err(dev, "Failed to retrieve mounting matrix %d\n", + result); + return result; + } + } else { st->plat_data = *pdata; + } + /* power is turned on inside check chip type*/ result = inv_check_and_setup_chip(st); if (result) diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h index e302a49..52d60cd 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h @@ -114,7 +114,8 @@ struct inv_mpu6050_hw { * @hw: Other hardware-specific information. * @chip_type: chip type. * @time_stamp_lock: spin lock to time stamp. - * @plat_data: platform data. + * @plat_data: platform data (deprecated in favor of @orientation). + * @orientation: sensor chip orientation relative to main hardware. * @timestamps: kfifo queue to store time stamp. * @map regmap pointer. * @irq interrupt number. @@ -131,6 +132,7 @@ struct inv_mpu6050_state { struct i2c_client *mux_client; unsigned int powerup_count; struct inv_mpu6050_platform_data plat_data; + struct iio_mount_matrix orientation; DECLARE_KFIFO(timestamps, long long, TIMESTAMP_FIFO_SIZE); struct regmap *map; int irq; diff --git a/include/linux/platform_data/invensense_mpu6050.h b/include/linux/platform_data/invensense_mpu6050.h index ad3aa7b..554b598 100644 --- a/include/linux/platform_data/invensense_mpu6050.h +++ b/include/linux/platform_data/invensense_mpu6050.h @@ -16,13 +16,16 @@ /** * struct inv_mpu6050_platform_data - Platform data for the mpu driver - * @orientation: Orientation matrix of the chip + * @orientation: Orientation matrix of the chip (deprecated in favor of + * mounting matrix retrieved from device-tree) * * Contains platform specific information on how to configure the MPU6050 to * work on this platform. The orientation matricies are 3x3 rotation matricies * that are applied to the data to rotate from the mounting orientation to the * platform orientation. The values must be one of 0, 1, or -1 and each row and * column should have exactly 1 non-zero value. + * + * Deprecated in favor of mounting matrix retrieved from device-tree. */ struct inv_mpu6050_platform_data { __s8 orientation[9]; -- 2.1.4