Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752781AbcD2TDz (ORCPT ); Fri, 29 Apr 2016 15:03:55 -0400 Received: from mga14.intel.com ([192.55.52.115]:61525 "EHLO mga14.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752634AbcD2TD1 (ORCPT ); Fri, 29 Apr 2016 15:03:27 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.24,552,1455004800"; d="scan'208";a="943055942" From: Crestez Dan Leonard To: Jonathan Cameron , linux-iio@vger.kernel.org Cc: linux-kernel@vger.kernel.org, Hartmut Knaack , Lars-Peter Clausen , Peter Meerwald-Stadler , Daniel Baluta , Crestez Dan Leonard , Ge Gao Subject: [PATCH 6/7] iio: inv_mpu6050: Check channel configuration on preenable Date: Fri, 29 Apr 2016 22:02:35 +0300 Message-Id: X-Mailer: git-send-email 2.5.5 In-Reply-To: References: In-Reply-To: References: Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3380 Lines: 91 Right now it is possible to only enable some of the x/y/z channels, for example you can enable accel_z without x or y. If you actually do that what you get is actually only the x channel. In theory the device supports selecting gyro x/y/z channels individually. It would also be possible to selectively enable x/y/z accel by unpacking the data read from the hardware into a format the iio core accepts. It is easier to simply refuse incorrect configuration. Signed-off-by: Crestez Dan Leonard --- drivers/iio/imu/inv_mpu6050/inv_mpu_core.c | 2 +- drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h | 4 ++++ drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c | 31 ++++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c index 064fc07..712e901 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c @@ -1130,7 +1130,7 @@ int inv_mpu_core_probe(struct regmap *regmap, int irq, const char *name, result = iio_triggered_buffer_setup(indio_dev, inv_mpu6050_irq_handler, inv_mpu6050_read_fifo, - NULL); + &inv_mpu_buffer_ops); if (result) { dev_err(dev, "configure buffer fail %d\n", result); return result; diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h index 9d15633..9d406df 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h @@ -284,6 +284,9 @@ enum inv_mpu6050_scan { INV_MPU6050_SCAN_TIMESTAMP, }; +#define INV_MPU6050_SCAN_MASK_ACCEL 0x07 +#define INV_MPU6050_SCAN_MASK_GYRO 0x38 + enum inv_mpu6050_filter_e { INV_MPU6050_FILTER_256HZ_NOLPF2 = 0, INV_MPU6050_FILTER_188HZ, @@ -340,3 +343,4 @@ int inv_mpu_core_remove(struct device *dev); int inv_mpu6050_set_power_itg(struct inv_mpu6050_state *st, bool power_on); extern const struct dev_pm_ops inv_mpu_pmops; extern const struct regmap_config inv_mpu_regmap_config; +extern const struct iio_buffer_setup_ops inv_mpu_buffer_ops; diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c index 56ee1e2..e8bda7f 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c @@ -222,3 +222,34 @@ flush_fifo: return IRQ_HANDLED; } + +/* Validate channels are set in a correct configuration */ +static int inv_mpu_buffer_preenable(struct iio_dev *indio_dev) +{ + struct inv_mpu6050_state *st = iio_priv(indio_dev); + unsigned long mask = *indio_dev->active_scan_mask; + + if ((mask & INV_MPU6050_SCAN_MASK_GYRO) && + (mask & INV_MPU6050_SCAN_MASK_GYRO) != INV_MPU6050_SCAN_MASK_GYRO) + { + dev_warn(regmap_get_device(st->map), + "Gyro channels can only be enabled together\n"); + return -EINVAL; + } + + if ((mask & INV_MPU6050_SCAN_MASK_ACCEL) && + (mask & INV_MPU6050_SCAN_MASK_ACCEL) != INV_MPU6050_SCAN_MASK_ACCEL) + { + dev_warn(regmap_get_device(st->map), + "Accel channels can only be enabled together\n"); + return -EINVAL; + } + + return 0; +} + +const struct iio_buffer_setup_ops inv_mpu_buffer_ops = { + .preenable = inv_mpu_buffer_preenable, + .postenable = iio_triggered_buffer_postenable, + .predisable = iio_triggered_buffer_predisable, +}; -- 2.5.5