Received: by 2002:ac0:bc90:0:0:0:0:0 with SMTP id a16csp4060151img; Tue, 26 Mar 2019 02:06:15 -0700 (PDT) X-Google-Smtp-Source: APXvYqwCXNWGR9bp8GyLbymOOmC91/1Lpcg/DnryfmUIdnBZIa0nAucd7pCWUxUYs9kJx5yWzVl7 X-Received: by 2002:a17:902:1002:: with SMTP id b2mr29098572pla.248.1553591175711; Tue, 26 Mar 2019 02:06:15 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1553591175; cv=none; d=google.com; s=arc-20160816; b=SmilBrAkYyzoGxXBF6Vw0RbvBcaDA9hZDIq5Rqoc03MG0fQksPYaRL8HXGF3UlRHxc utvtnxNj1Z8yxLF0v/lA59IJ5WQPIECS2/W/M41p1VYAKQ3PSuuAGJ/ZDs4tSwjpmOAA Zsyzvhu89XySnkpUDzp38Ef0RZYbj9xQUMCc1nTHK+e452Q10Q6ZnTWcLDheK2c1r2j2 xmxEW8pojfTuE5gA2EMO6QQpDf8Ps83p4W9cygQQIJ+nEXmFwqpSsZgnd6w8uqx2tss1 eW9FFg1sW7yxk9uwOhvUpd0GdvS7vsGvDKyeMkaB0u2zrzOSuN2GsTDPQs8j5efUm2PM i+ug== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=Kyc1zizkwKohgx4A7VcnL5Bai7KVRGtlYwLkDvfw2+w=; b=aqQ47Mv0SzBASz8AsfalkkEIykfpNmJNup4DVXbUYU+Wb/gCFO1L2Jqsm2C5T/wjVz nLA93a2TFRbWixessbkaRm7lMEnmxKLO4T1eg0zBDZto1YIcNk9F5T+IM/2QvosrGfad 5YDdoz9VJWSpG7ki79KhW4dVdlqAwgoxWWVy5WEqiNdbQJbcCAcH5SzCtxTnBFurwLq+ Fws7OzqKzhJlgYyGQkSqOmD2UKlQzmHAcmV3N3KjNm8rc/MhToqFUP9hYtPGCoRmtFSw f6E+U1DEGYHx0ndtgsj/aPwXTsqKoZQrt9kfHOyOPoW/2w9IcbW11asmPGXcmCFx7Psy V35A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@skydio.com header.s=google header.b=HiEFseJd; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=skydio.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id 59si17017979plb.405.2019.03.26.02.06.00; Tue, 26 Mar 2019 02:06:15 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@skydio.com header.s=google header.b=HiEFseJd; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=skydio.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730722AbfCZJFT (ORCPT + 99 others); Tue, 26 Mar 2019 05:05:19 -0400 Received: from mail-pl1-f193.google.com ([209.85.214.193]:37651 "EHLO mail-pl1-f193.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728991AbfCZJFS (ORCPT ); Tue, 26 Mar 2019 05:05:18 -0400 Received: by mail-pl1-f193.google.com with SMTP id q6so1326844pll.4 for ; Tue, 26 Mar 2019 02:05:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=skydio.com; s=google; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=Kyc1zizkwKohgx4A7VcnL5Bai7KVRGtlYwLkDvfw2+w=; b=HiEFseJdu6tZwOcQMo7As9lRqt4BF0bGV269rpNS5vduOyJa1GsJHBRS64W2wZ6Wmm Co2Da3QmJJncoQWmM2VKRRXWAjlHyPPc+gA5Jm+AN2I8B4Fwf7iC/9GKI7QRitP+4YXa 4nI1FiL4/eDgz4RG3D+QBhDZYLxv6b+cClHJq0HJmpZIDLy4/hMDou+wtmXlY0o8fQrI egT8/rDkHeQLBMWszO4HTnOxME8VIo1QoqJBdgiwjKbHXu2nRx1ORmTRKSHjCjcGL+U9 BF3VBanU19CUYx56afU7lMq3KUZq3fhSHVnrlGvKRd6ju1TkZvY+A6Jjc8xLtUTIRNIo ONSQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=Kyc1zizkwKohgx4A7VcnL5Bai7KVRGtlYwLkDvfw2+w=; b=hjsweA9L8mIA5PhQXDZ+YoD8QfDZDPuAE1p+4As9nn6b9+TS+2lRyKZrKqPfVDw5lm eedeCl5vHNC8heZnnjB4xP3QNSe6D5rxGBbmy2xwkYmMOTodeUIBdAUtwBbWjfKZZ6em hloVf4NaLztxfwHblY3NzHIL/hssTQ7AXChmj8EcPG+1gQxWXcBk0nUxdMKb+IpAnywv kjOg3bDnJvJGLsz6r1hVTi0r8OaAVEPH5HTP47xr2IjhvHTKvreLjT8oBub3VPV1u57I bFjTECP4aRf1qVxrdjDwJIizR0+MYjozp15/FXqZpBu3ZCxUfllN/GSK5oMWmli3rPRk wIQA== X-Gm-Message-State: APjAAAWJaAqo/rCuaTn08/+3r37NQXXGl19lbnCNfD7GS+xkzT36nJbt Kr7fPknfRDMbXe9OWXrVjOrf6A== X-Received: by 2002:a17:902:bb0c:: with SMTP id l12mr30412854pls.108.1553591117930; Tue, 26 Mar 2019 02:05:17 -0700 (PDT) Received: from stevemo-laptop.localdomain ([2601:646:c601:9a31:6c4c:9a9b:7596:e32f]) by smtp.gmail.com with ESMTPSA id v188sm9935467pgb.7.2019.03.26.02.05.15 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 26 Mar 2019 02:05:16 -0700 (PDT) From: stevemo@skydio.com To: gaireg@gaireg.de Cc: Steve Moskovchenko , Jonathan Cameron , Hartmut Knaack , Lars-Peter Clausen , Peter Meerwald-Stadler , Jean-Baptiste Maneyrol , Martin Kelly , Jonathan Marek , Brian Masney , Rob Herring , Douglas Fischer , linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH] iio: imu: mpu6050: Fix FIFO layout for ICM20602 Date: Tue, 26 Mar 2019 02:01:45 -0700 Message-Id: <20190326090238.23651-1-stevemo@skydio.com> X-Mailer: git-send-email 2.21.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Steve Moskovchenko The MPU6050 driver has recently gained support for the ICM20602 IMU, which is very similar to MPU6xxx. However, the ICM20602's Gyro data specifically includes temperature readings, which were not present on MPU6xxx parts. As a result, the driver will under-read the ICM20602's FIFO register, causing the same (partial) sample to be returned for all reads, until the FIFO overflows. Fix this by adding a table of scan elements speciically for the ICM20602, which takes the extra temperature data into consideration. While we're at it, fix the temperature offset and scaling on ICM20602, since it uses different scale/offset constants than the rest of the MPU6xxx devices. Signed-off-by: Steve Moskovchenko --- drivers/iio/imu/inv_mpu6050/inv_mpu_core.c | 46 ++++++++++++++++++++-- drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h | 20 +++++++++- drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c | 8 +++- 3 files changed, 67 insertions(+), 7 deletions(-) diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c index 650de0fefb7b..fedd3f2b0135 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c @@ -471,7 +471,10 @@ inv_mpu6050_read_raw(struct iio_dev *indio_dev, return IIO_VAL_INT_PLUS_MICRO; case IIO_TEMP: *val = 0; - *val2 = INV_MPU6050_TEMP_SCALE; + if (st->chip_type == INV_ICM20602) + *val2 = INV_ICM20602_TEMP_SCALE; + else + *val2 = INV_MPU6050_TEMP_SCALE; return IIO_VAL_INT_PLUS_MICRO; default: @@ -480,7 +483,10 @@ inv_mpu6050_read_raw(struct iio_dev *indio_dev, case IIO_CHAN_INFO_OFFSET: switch (chan->type) { case IIO_TEMP: - *val = INV_MPU6050_TEMP_OFFSET; + if (st->chip_type == INV_ICM20602) + *val = INV_ICM20602_TEMP_OFFSET; + else + *val = INV_MPU6050_TEMP_OFFSET; return IIO_VAL_INT; default: @@ -845,6 +851,32 @@ static const struct iio_chan_spec inv_mpu_channels[] = { INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_Z, INV_MPU6050_SCAN_ACCL_Z), }; +static const struct iio_chan_spec inv_icm20602_channels[] = { + IIO_CHAN_SOFT_TIMESTAMP(INV_ICM20602_SCAN_TIMESTAMP), + { + .type = IIO_TEMP, + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) + | BIT(IIO_CHAN_INFO_OFFSET) + | BIT(IIO_CHAN_INFO_SCALE), + .scan_index = INV_ICM20602_SCAN_GYRO_TEMP, + .scan_type = { + .sign = 's', + .realbits = 16, + .storagebits = 16, + .shift = 0, + .endianness = IIO_BE, + }, + }, + + INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_X, INV_ICM20602_SCAN_GYRO_X), + INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_Y, INV_ICM20602_SCAN_GYRO_Y), + INV_MPU6050_CHAN(IIO_ANGL_VEL, IIO_MOD_Z, INV_ICM20602_SCAN_GYRO_Z), + + INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_Y, INV_ICM20602_SCAN_ACCL_Y), + INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_X, INV_ICM20602_SCAN_ACCL_X), + INV_MPU6050_CHAN(IIO_ACCEL, IIO_MOD_Z, INV_ICM20602_SCAN_ACCL_Z), +}; + /* * The user can choose any frequency between INV_MPU6050_MIN_FIFO_RATE and * INV_MPU6050_MAX_FIFO_RATE, but only these frequencies are matched by the @@ -1100,8 +1132,14 @@ int inv_mpu_core_probe(struct regmap *regmap, int irq, const char *name, indio_dev->name = name; else indio_dev->name = dev_name(dev); - indio_dev->channels = inv_mpu_channels; - indio_dev->num_channels = ARRAY_SIZE(inv_mpu_channels); + + if (chip_type == INV_ICM20602) { + indio_dev->channels = inv_icm20602_channels; + indio_dev->num_channels = ARRAY_SIZE(inv_icm20602_channels); + } else { + indio_dev->channels = inv_mpu_channels; + indio_dev->num_channels = ARRAY_SIZE(inv_mpu_channels); + } indio_dev->info = &mpu_info; indio_dev->modes = INDIO_BUFFER_TRIGGERED; diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h index 325afd9f5f61..eb04391feaa8 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_iio.h @@ -208,6 +208,9 @@ struct inv_mpu6050_state { #define INV_MPU6050_BYTES_PER_3AXIS_SENSOR 6 #define INV_MPU6050_FIFO_COUNT_BYTE 2 +/* ICM20602 gyro data includes temperature */ +#define INV_ICM20602_BYTES_PER_GYRO_SENSOR 8 + /* mpu6500 registers */ #define INV_MPU6500_REG_ACCEL_CONFIG_2 0x1D #define INV_MPU6500_REG_ACCEL_OFFSET 0x77 @@ -229,6 +232,9 @@ struct inv_mpu6050_state { #define INV_MPU6050_GYRO_CONFIG_FSR_SHIFT 3 #define INV_MPU6050_ACCL_CONFIG_FSR_SHIFT 3 +#define INV_ICM20602_TEMP_OFFSET 8170 +#define INV_ICM20602_TEMP_SCALE 3060 + /* 6 + 6 round up and plus 8 */ #define INV_MPU6050_OUTPUT_DATA_SIZE 24 @@ -270,7 +276,7 @@ struct inv_mpu6050_state { #define INV_ICM20608_WHOAMI_VALUE 0xAF #define INV_ICM20602_WHOAMI_VALUE 0x12 -/* scan element definition */ +/* scan element definition for generic MPU6xxx devices */ enum inv_mpu6050_scan { INV_MPU6050_SCAN_ACCL_X, INV_MPU6050_SCAN_ACCL_Y, @@ -281,6 +287,18 @@ enum inv_mpu6050_scan { INV_MPU6050_SCAN_TIMESTAMP, }; +/* scan element definition for ICM20602, which includes gyro temp */ +enum inv_icm20602_scan { + INV_ICM20602_SCAN_ACCL_X, + INV_ICM20602_SCAN_ACCL_Y, + INV_ICM20602_SCAN_ACCL_Z, + INV_ICM20602_SCAN_GYRO_TEMP, + INV_ICM20602_SCAN_GYRO_X, + INV_ICM20602_SCAN_GYRO_Y, + INV_ICM20602_SCAN_GYRO_Z, + INV_ICM20602_SCAN_TIMESTAMP, +}; + enum inv_mpu6050_filter_e { INV_MPU6050_FILTER_256HZ_NOLPF2 = 0, INV_MPU6050_FILTER_188HZ, diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c index 548e042f7b5b..20828d6a13f9 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c @@ -204,8 +204,12 @@ irqreturn_t inv_mpu6050_read_fifo(int irq, void *p) if (st->chip_config.accl_fifo_enable) bytes_per_datum += INV_MPU6050_BYTES_PER_3AXIS_SENSOR; - if (st->chip_config.gyro_fifo_enable) - bytes_per_datum += INV_MPU6050_BYTES_PER_3AXIS_SENSOR; + if (st->chip_config.gyro_fifo_enable) { + if (st->chip_type == INV_ICM20602) + bytes_per_datum += INV_ICM20602_BYTES_PER_GYRO_SENSOR; + else + bytes_per_datum += INV_MPU6050_BYTES_PER_3AXIS_SENSOR; + } /* * read fifo_count register to know how many bytes are inside the FIFO -- 2.20.1