From patchwork Thu May 7 14:42:11 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jean-Baptiste Maneyrol X-Patchwork-Id: 11533983 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 21D83139F for ; Thu, 7 May 2020 14:43:24 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E6ADD2083B for ; Thu, 7 May 2020 14:43:23 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=invensense.com header.i=@invensense.com header.b="WZSpN8vS"; dkim=pass (1024-bit key) header.d=invensense.onmicrosoft.com header.i=@invensense.onmicrosoft.com header.b="EZjefep+" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726476AbgEGOnW (ORCPT ); Thu, 7 May 2020 10:43:22 -0400 Received: from mx0b-00328301.pphosted.com ([148.163.141.47]:22320 "EHLO mx0b-00328301.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726470AbgEGOnV (ORCPT ); Thu, 7 May 2020 10:43:21 -0400 Received: from pps.filterd (m0156136.ppops.net [127.0.0.1]) by mx0b-00328301.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 047EbhbW006057; Thu, 7 May 2020 07:43:09 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=invensense.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : content-type : content-transfer-encoding : mime-version; s=pfpt1; bh=UgS9409OZ7jcsrOpUf1U/Wt1Y50MnDXXPDLeOEz14qE=; b=WZSpN8vSamnu76c6jvcyil5daJQibX+MeQkv3z8kV3am0tZ3Lf91P9VA8ObwaBiMEQv8 t/A0YcTK/oSHWI+rDdFZamZe/KIC92NErqs//8QylC4wgb2gsvwXDLzaLZKZp2jzeS+N gWFLi1+7JYW+5qcjUTrngKwx5b8s0vl85j27YqtLiDPjMbAR2/F94i/GtbZhIkHMZ8ao +ZJZYwLwL/CHHr0PxqWzqLFhF6C0/nS1KfaBJB7ksiLPOL/RJrraWxs4Id9Rr/st8Sz6 1UzaJ2dScSRBh3tmhfVZtW9d/zML3XKkz1yGKdVarWzljY0rRaVTzLeYTeom+t9GNuOW Pw== Received: from nam11-dm6-obe.outbound.protection.outlook.com (mail-dm6nam11lp2174.outbound.protection.outlook.com [104.47.57.174]) by mx0b-00328301.pphosted.com with ESMTP id 30s4tnatwj-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 07 May 2020 07:43:09 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=A5GOEEv8EHPBF/oGbRFPkgs7MjVBtwSiR+azfOfRTvp6nbLfBswym3MVgKohvBxwmOLhbwM8etBMmFVBU0vRL6tuQkgUvi4BpxTIgsUEks4aMKlcP2e7h3JjMQCq1gGTutCw+QURTk6NgG9o0ZAg+upSkCsnnU8OY9vUM7lFognKe379BnyFSCSpQYLiR6d7nNcbgmdWjnezwtp/3MGpm7HwZeh6DRUnoKZW0a7DpER+SXfmXSeM6mXq6E+ARg2fDMDMvxp6WQSF4cQklxRdwHznkj+QspQYKAap4y0CfoLYBuPWRf8vtlkiw9NUzXDgrHHOCD271zfhrWlUQS9o3g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=UgS9409OZ7jcsrOpUf1U/Wt1Y50MnDXXPDLeOEz14qE=; b=bYh+1EGIEH61SJPoma/OK+Uy21hU3FZSjVSePPavGay/4mCz5ziq0Azq5eo+Cjvp1qmKU+KkKKDhDXUsg0EQufyodeQZcKtjSkWoMCxMuPpaW77DpgM4JTbj7CMnY+zc6GX8Y3SLFaMhWa/px4JQK5ouM8J1qlSvjBwx+LxbkkICNIQ0i24Oej9f7yrgyYgpJn7jFjrA1vihK4WsCOOxFthnSkt8xEfuZm8M2zRIoRfAp+ooeoMGpX8xe0RaIUS6MCyl5VycnWfSfV/G5sNW0CZ/Zc/YxI8dSf9crtPlscIZags1t1L/20P32bGFYSNYIgK9Zi6rhtkta7oQFT8nvw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=invensense.com; dmarc=pass action=none header.from=invensense.com; dkim=pass header.d=invensense.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=invensense.onmicrosoft.com; s=selector2-invensense-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=UgS9409OZ7jcsrOpUf1U/Wt1Y50MnDXXPDLeOEz14qE=; b=EZjefep+9ltCeQr4LMON9ItqkhCUxZvTu9qd5UwvViRqFDPROsjUroTORCR7kNSjcBjmw6CKd5Nq8+c/be592PvzG6pUKeT1UFqelj6ZJGXvKJQQD7vOLjYDsvpg0N3kTbUG7D9DMljbxVXZbigkKB/JWoTZCi/WbkzCKpNkW6w= Authentication-Results: kernel.org; dkim=none (message not signed) header.d=none;kernel.org; dmarc=none action=none header.from=invensense.com; Received: from MN2PR12MB4422.namprd12.prod.outlook.com (2603:10b6:208:265::9) by MN2PR12MB4269.namprd12.prod.outlook.com (2603:10b6:208:1d4::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2979.28; Thu, 7 May 2020 14:43:07 +0000 Received: from MN2PR12MB4422.namprd12.prod.outlook.com ([fe80::7471:da8b:8ca1:6af0]) by MN2PR12MB4422.namprd12.prod.outlook.com ([fe80::7471:da8b:8ca1:6af0%4]) with mapi id 15.20.2979.028; Thu, 7 May 2020 14:43:07 +0000 From: Jean-Baptiste Maneyrol To: jic23@kernel.org, robh+dt@kernel.org, robh@kernel.org, mchehab+huawei@kernel.org, davem@davemloft.net, gregkh@linuxfoundation.org Cc: linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Jean-Baptiste Maneyrol Subject: [PATCH 01/12] iio: imu: inv_icm42600: add core of new inv_icm42600 driver Date: Thu, 7 May 2020 16:42:11 +0200 Message-Id: <20200507144222.20989-2-jmaneyrol@invensense.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200507144222.20989-1-jmaneyrol@invensense.com> References: <20200507144222.20989-1-jmaneyrol@invensense.com> X-ClientProxiedBy: LNXP265CA0048.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:5c::36) To MN2PR12MB4422.namprd12.prod.outlook.com (2603:10b6:208:265::9) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from frgnb-buildozer.invcorp.invensense.com (77.157.193.39) by LNXP265CA0048.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:5c::36) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2979.26 via Frontend Transport; Thu, 7 May 2020 14:43:05 +0000 X-Mailer: git-send-email 2.17.1 X-Originating-IP: [77.157.193.39] X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 6c9c07fa-7c95-46b3-e710-08d7f294f4b1 X-MS-TrafficTypeDiagnostic: MN2PR12MB4269: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:48; X-Forefront-PRVS: 03965EFC76 X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: mjOwBsOnNhwIv1/j44yYpcqKCgHFs7Cbsox1VNJVPUuqpaw6XwdWTvX63nV4E0i10kSLHtbTQkJm4P+QxRpP1dEqzGbezDZELU4mGQfFLXz7XSJ+Yhf1yPtDv9HHqqWPPO1+14N0Wb/jAgUQfw6B46BN6BZARxl4FLnREwX50Pgfd1YS2sRdz36Dsn5QVPR0OUrldTy0u48t4dueXV2OtHGwNzlqZUb6wKK/bSY05zB45VBBC6DvlAh6oXaw0yTiz/o9ozDszBJgjc7Btqs/HwItxSINc9D8Nh8XgAWyXAk0TnTyj8/dPbBn4o+zVkwBUkWdsXZJt8YTnOCj0lktP1Ql7Ef9eUVu8GI1qlKwxciwmeQv3r9/W0EbqL4F0tpAO6nTfkZvUZgjqIV+3P2HPEP89JBGZvUWlv8UnLAskb/VaLGYj4BQGgTPRf/Zf2JwQrnBZcjmToVLoFttL74+HwKU48MEP1xuE8MPBERMMJz7z9VWya5fnFbgDGYsMLlFpNnrylgQm3K+SmUt1q34dA== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:MN2PR12MB4422.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFTY:;SFS:(346002)(396003)(136003)(366004)(39850400004)(376002)(33430700001)(186003)(6486002)(478600001)(16526019)(5660300002)(4326008)(33440700001)(30864003)(66556008)(8676002)(1076003)(36756003)(316002)(66946007)(66476007)(6666004)(52116002)(8936002)(86362001)(2616005)(83280400001)(956004)(83320400001)(83290400001)(83310400001)(26005)(2906002)(7696005)(83300400001)(107886003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData: ujYys01TYH18auPkkP6wsgT0ptgw99vTBsnHwnYEKYMKFAv70X7A8A/U0zc/xxy7dbi/9keiMxpuLmyUn8kNg/y+iLp0N6N7qI9PPk0AD1Dagf23QSxJ8YN/yLzAPi6ejRievtB9z3CmIvWwGI9OoVm18ooXO/YXZHc/MyaEhNJyTw3bTybpMOjk6N2cYq6ed5dhQyN7K9I3MZTUbEtKOSmxgBQjfWEnkhF9EL8kdgcmbn4dXt6FQBxiG6gISYWSexO21PjPbnoqTfAf5ys1tTIiO7d6yW5svkjwSUtAQRPKR2n9pGRwQ0MiVWb4GmC9IERMmg+Or4egjCLZN7VwwrCKCawkuu3AivThNK7oG8VEw6zcmY9PMGLIxNFh/PR/JfuAuYoUgOSWRLvKfE7VbhMVHy3vZ1GBClmf39pnDY991fIEKW49RPNn9U45JqsdU/dpSsMeLJNJHZr6+3SZelroxRxp1Qe0t9YrpuiGJ0uoflhAZXt6teYdyMaOkEzz0ey4Mn22WksI8ay2rlz1YPauk1r0Vmdq6B67LFZ+w4XWdoInv6blfEW69IxE+l9Ia2prCLF2qUEuIblS0aEHh39vIlx8H9+IU4JI8OuiDFbeuQZ7+KnZJyYkYdodLGw+ngFXnb1RrsXKjrw4EAV/rJSYXHNs+Z9vAZIeMbRaFsMVe4jidc6HP9f8nxbIqs7xHn8pZ3DAEY0pWic1Y3FxT1iSjSSHO/G0r1RgieQjb7k2H1BQ5TvxXB5i5+rnUOk2s1zPoUcXGlkv+lGHdgIF9vIbf1ylWRS7xahLmVMD8+I= X-OriginatorOrg: invensense.com X-MS-Exchange-CrossTenant-Network-Message-Id: 6c9c07fa-7c95-46b3-e710-08d7f294f4b1 X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 May 2020 14:43:07.5583 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 462b3b3b-e42b-47ea-801a-f1581aac892d X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 00xaBwL4GtppzIAcCT64jsxp2Y48gvpgEOSoYF7MDtmQOnmD3M0JRI92EEr1nccI2b8aQbvsp7eEz/6+3FdTqa9PIeGkhAQ2UvSiUYkT1+g= X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR12MB4269 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.216,18.0.676 definitions=2020-05-07_09:2020-05-07,2020-05-07 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 adultscore=0 priorityscore=1501 spamscore=0 mlxlogscore=999 impostorscore=0 suspectscore=0 phishscore=0 malwarescore=0 lowpriorityscore=0 bulkscore=0 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2005070118 Sender: linux-iio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org Core component of a new driver for InvenSense ICM-426xx devices. It includes registers definition, main probe/setup, and device utility functions. ICM-426xx devices are latest generation of 6-axis IMU, gyroscope+accelerometer and temperature sensor. This device includes a 2K FIFO, supports I2C/I3C/SPI, and provides intelligent motion features like pedometer, tilt detection, and tap detection. Signed-off-by: Jean-Baptiste Maneyrol --- drivers/iio/imu/inv_icm42600/inv_icm42600.h | 372 +++++++++++ .../iio/imu/inv_icm42600/inv_icm42600_core.c | 618 ++++++++++++++++++ 2 files changed, 990 insertions(+) create mode 100644 drivers/iio/imu/inv_icm42600/inv_icm42600.h create mode 100644 drivers/iio/imu/inv_icm42600/inv_icm42600_core.c diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600.h b/drivers/iio/imu/inv_icm42600/inv_icm42600.h new file mode 100644 index 000000000000..8da4c8249aed --- /dev/null +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600.h @@ -0,0 +1,372 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2020 Invensense, Inc. + */ + +#ifndef INV_ICM42600_H_ +#define INV_ICM42600_H_ + +#include +#include +#include +#include +#include +#include +#include + +enum inv_icm42600_chip { + INV_CHIP_ICM42600, + INV_CHIP_ICM42602, + INV_CHIP_ICM42605, + INV_CHIP_ICM42622, + INV_CHIP_NB, +}; + +/* serial bus slew rates */ +enum inv_icm42600_slew_rate { + INV_ICM42600_SLEW_RATE_20_60NS, + INV_ICM42600_SLEW_RATE_12_36NS, + INV_ICM42600_SLEW_RATE_6_18NS, + INV_ICM42600_SLEW_RATE_4_12NS, + INV_ICM42600_SLEW_RATE_2_6NS, + INV_ICM42600_SLEW_RATE_INF_2NS, +}; + +enum inv_icm42600_sensor_mode { + INV_ICM42600_SENSOR_MODE_OFF, + INV_ICM42600_SENSOR_MODE_STANDBY, + INV_ICM42600_SENSOR_MODE_LOW_POWER, + INV_ICM42600_SENSOR_MODE_LOW_NOISE, + INV_ICM42600_SENSOR_MODE_NB, +}; + +/* gyroscope fullscale values */ +enum inv_icm42600_gyro_fs { + INV_ICM42600_GYRO_FS_2000DPS, + INV_ICM42600_GYRO_FS_1000DPS, + INV_ICM42600_GYRO_FS_500DPS, + INV_ICM42600_GYRO_FS_250DPS, + INV_ICM42600_GYRO_FS_125DPS, + INV_ICM42600_GYRO_FS_62_5DPS, + INV_ICM42600_GYRO_FS_31_25DPS, + INV_ICM42600_GYRO_FS_15_625DPS, + INV_ICM42600_GYRO_FS_NB, +}; + +/* accelerometer fullscale values */ +enum inv_icm42600_accel_fs { + INV_ICM42600_ACCEL_FS_16G, + INV_ICM42600_ACCEL_FS_8G, + INV_ICM42600_ACCEL_FS_4G, + INV_ICM42600_ACCEL_FS_2G, + INV_ICM42600_ACCEL_FS_NB, +}; + +/* ODR suffixed by LN or LP are Low-Noise or Low-Power mode only */ +enum inv_icm42600_odr { + INV_ICM42600_ODR_8KHZ_LN = 3, + INV_ICM42600_ODR_4KHZ_LN, + INV_ICM42600_ODR_2KHZ_LN, + INV_ICM42600_ODR_1KHZ_LN, + INV_ICM42600_ODR_200HZ, + INV_ICM42600_ODR_100HZ, + INV_ICM42600_ODR_50HZ, + INV_ICM42600_ODR_25HZ, + INV_ICM42600_ODR_12_5HZ, + INV_ICM42600_ODR_6_25HZ_LP, + INV_ICM42600_ODR_3_125HZ_LP, + INV_ICM42600_ODR_1_5625HZ_LP, + INV_ICM42600_ODR_500HZ, + INV_ICM42600_ODR_NB, +}; + +enum inv_icm42600_filter { + /* Low-Noise mode sensor data filter (3rd order filter by default) */ + INV_ICM42600_FILTER_BW_ODR_DIV_2, + + /* Low-Power mode sensor data filter (averaging) */ + INV_ICM42600_FILTER_AVG_1X = 1, + INV_ICM42600_FILTER_AVG_16X = 6, +}; + +struct inv_icm42600_sensor_conf { + int mode; + int fs; + int odr; + int filter; +}; +#define INV_ICM42600_SENSOR_CONF_INIT {-1, -1, -1, -1} + +struct inv_icm42600_conf { + struct inv_icm42600_sensor_conf gyro; + struct inv_icm42600_sensor_conf accel; + bool temp_en; +}; + +struct inv_icm42600_suspended { + enum inv_icm42600_sensor_mode gyro; + enum inv_icm42600_sensor_mode accel; + bool temp; +}; + +/* + * struct inv_icm42600_state - driver state variables + * @lock: chip access lock. + * @chip: chip identifier. + * @name: chip name. + * @map: regmap pointer. + * @vdd_supply: VDD voltage regulator for the chip. + * @vddio_supply: I/O voltage regulator for the chip. + * @orientation: sensor chip orientation relative to main hardware. + * @conf: chip sensors configurations. + * @suspended: suspended sensors configuration. + */ +struct inv_icm42600_state { + struct mutex lock; + enum inv_icm42600_chip chip; + const char *name; + struct regmap *map; + struct regulator *vdd_supply; + struct regulator *vddio_supply; + struct iio_mount_matrix orientation; + struct inv_icm42600_conf conf; + struct inv_icm42600_suspended suspended; +}; + +/* Virtual register addresses: @bank on MSB (4 upper bits), @address on LSB */ + +/* Bank selection register, available in all banks */ +#define INV_ICM42600_REG_BANK_SEL 0x76 +#define INV_ICM42600_BANK_SEL_MASK GENMASK(2, 0) + +/* User bank 0 (MSB 0x00) */ +#define INV_ICM42600_REG_DEVICE_CONFIG 0x0011 +#define INV_ICM42600_DEVICE_CONFIG_SOFT_RESET BIT(0) + +#define INV_ICM42600_REG_DRIVE_CONFIG 0x0013 +#define INV_ICM42600_DRIVE_CONFIG_I2C_MASK GENMASK(5, 3) +#define INV_ICM42600_DRIVE_CONFIG_I2C(_rate) \ + FIELD_PREP(INV_ICM42600_DRIVE_CONFIG_I2C_MASK, (_rate)) +#define INV_ICM42600_DRIVE_CONFIG_SPI_MASK GENMASK(2, 0) +#define INV_ICM42600_DRIVE_CONFIG_SPI(_rate) \ + FIELD_PREP(INV_ICM42600_DRIVE_CONFIG_SPI_MASK, (_rate)) + +#define INV_ICM42600_REG_INT_CONFIG 0x0014 +#define INV_ICM42600_INT_CONFIG_INT2_LATCHED BIT(5) +#define INV_ICM42600_INT_CONFIG_INT2_PUSH_PULL BIT(4) +#define INV_ICM42600_INT_CONFIG_INT2_ACTIVE_HIGH BIT(3) +#define INV_ICM42600_INT_CONFIG_INT2_ACTIVE_LOW 0x00 +#define INV_ICM42600_INT_CONFIG_INT1_LATCHED BIT(2) +#define INV_ICM42600_INT_CONFIG_INT1_PUSH_PULL BIT(1) +#define INV_ICM42600_INT_CONFIG_INT1_ACTIVE_HIGH BIT(0) +#define INV_ICM42600_INT_CONFIG_INT1_ACTIVE_LOW 0x00 + +#define INV_ICM42600_REG_FIFO_CONFIG 0x0016 +#define INV_ICM42600_FIFO_CONFIG_MASK GENMASK(7, 6) +#define INV_ICM42600_FIFO_CONFIG_BYPASS \ + FIELD_PREP(INV_ICM42600_FIFO_CONFIG_MASK, 0) +#define INV_ICM42600_FIFO_CONFIG_STREAM \ + FIELD_PREP(INV_ICM42600_FIFO_CONFIG_MASK, 1) +#define INV_ICM42600_FIFO_CONFIG_STOP_ON_FULL \ + FIELD_PREP(INV_ICM42600_FIFO_CONFIG_MASK, 2) + +/* all sensor data are 16 bits (2 registers wide) in big-endian */ +#define INV_ICM42600_REG_TEMP_DATA 0x001D +#define INV_ICM42600_REG_ACCEL_DATA_X 0x001F +#define INV_ICM42600_REG_ACCEL_DATA_Y 0x0021 +#define INV_ICM42600_REG_ACCEL_DATA_Z 0x0023 +#define INV_ICM42600_REG_GYRO_DATA_X 0x0025 +#define INV_ICM42600_REG_GYRO_DATA_Y 0x0027 +#define INV_ICM42600_REG_GYRO_DATA_Z 0x0029 +#define INV_ICM42600_DATA_INVALID -32768 + +#define INV_ICM42600_REG_INT_STATUS 0x002D +#define INV_ICM42600_INT_STATUS_UI_FSYNC BIT(6) +#define INV_ICM42600_INT_STATUS_PLL_RDY BIT(5) +#define INV_ICM42600_INT_STATUS_RESET_DONE BIT(4) +#define INV_ICM42600_INT_STATUS_DATA_RDY BIT(3) +#define INV_ICM42600_INT_STATUS_FIFO_THS BIT(2) +#define INV_ICM42600_INT_STATUS_FIFO_FULL BIT(1) +#define INV_ICM42600_INT_STATUS_AGC_RDY BIT(0) + +/* + * FIFO access registers + * FIFO count is 16 bits (2 registers) big-endian + * FIFO data is a continuous read register to read FIFO content + */ +#define INV_ICM42600_REG_FIFO_COUNT 0x002E +#define INV_ICM42600_REG_FIFO_DATA 0x0030 + +#define INV_ICM42600_REG_SIGNAL_PATH_RESET 0x004B +#define INV_ICM42600_SIGNAL_PATH_RESET_DMP_INIT_EN BIT(6) +#define INV_ICM42600_SIGNAL_PATH_RESET_DMP_MEM_RESET BIT(5) +#define INV_ICM42600_SIGNAL_PATH_RESET_RESET BIT(3) +#define INV_ICM42600_SIGNAL_PATH_RESET_TMST_STROBE BIT(2) +#define INV_ICM42600_SIGNAL_PATH_RESET_FIFO_FLUSH BIT(1) + +/* default configuration: all data big-endian and fifo count in bytes */ +#define INV_ICM42600_REG_INTF_CONFIG0 0x004C +#define INV_ICM42600_INTF_CONFIG0_FIFO_HOLD_LAST_DATA BIT(7) +#define INV_ICM42600_INTF_CONFIG0_FIFO_COUNT_REC BIT(6) +#define INV_ICM42600_INTF_CONFIG0_FIFO_COUNT_ENDIAN BIT(5) +#define INV_ICM42600_INTF_CONFIG0_SENSOR_DATA_ENDIAN BIT(4) +#define INV_ICM42600_INTF_CONFIG0_UI_SIFS_CFG_MASK GENMASK(1, 0) +#define INV_ICM42600_INTF_CONFIG0_UI_SIFS_CFG_SPI_DIS \ + FIELD_PREP(INV_ICM42600_INTF_CONFIG0_UI_SIFS_CFG_MASK, 2) +#define INV_ICM42600_INTF_CONFIG0_UI_SIFS_CFG_I2C_DIS \ + FIELD_PREP(INV_ICM42600_INTF_CONFIG0_UI_SIFS_CFG_MASK, 3) + +#define INV_ICM42600_REG_INTF_CONFIG1 0x004D +#define INV_ICM42600_INTF_CONFIG1_ACCEL_LP_CLK_RC BIT(3) + +#define INV_ICM42600_REG_PWR_MGMT0 0x004E +#define INV_ICM42600_PWR_MGMT0_TEMP_DIS BIT(5) +#define INV_ICM42600_PWR_MGMT0_IDLE BIT(4) +#define INV_ICM42600_PWR_MGMT0_GYRO(_mode) \ + FIELD_PREP(GENMASK(3, 2), (_mode)) +#define INV_ICM42600_PWR_MGMT0_ACCEL(_mode) \ + FIELD_PREP(GENMASK(1, 0), (_mode)) + +#define INV_ICM42600_REG_GYRO_CONFIG0 0x004F +#define INV_ICM42600_GYRO_CONFIG0_FS(_fs) \ + FIELD_PREP(GENMASK(7, 5), (_fs)) +#define INV_ICM42600_GYRO_CONFIG0_ODR(_odr) \ + FIELD_PREP(GENMASK(3, 0), (_odr)) + +#define INV_ICM42600_REG_ACCEL_CONFIG0 0x0050 +#define INV_ICM42600_ACCEL_CONFIG0_FS(_fs) \ + FIELD_PREP(GENMASK(7, 5), (_fs)) +#define INV_ICM42600_ACCEL_CONFIG0_ODR(_odr) \ + FIELD_PREP(GENMASK(3, 0), (_odr)) + +#define INV_ICM42600_REG_GYRO_ACCEL_CONFIG0 0x0052 +#define INV_ICM42600_GYRO_ACCEL_CONFIG0_ACCEL_FILT(_f) \ + FIELD_PREP(GENMASK(7, 4), (_f)) +#define INV_ICM42600_GYRO_ACCEL_CONFIG0_GYRO_FILT(_f) \ + FIELD_PREP(GENMASK(3, 0), (_f)) + +#define INV_ICM42600_REG_TMST_CONFIG 0x0054 +#define INV_ICM42600_TMST_CONFIG_MASK GENMASK(4, 0) +#define INV_ICM42600_TMST_CONFIG_TMST_TO_REGS_EN BIT(4) +#define INV_ICM42600_TMST_CONFIG_TMST_RES_16US BIT(3) +#define INV_ICM42600_TMST_CONFIG_TMST_DELTA_EN BIT(2) +#define INV_ICM42600_TMST_CONFIG_TMST_FSYNC_EN BIT(1) +#define INV_ICM42600_TMST_CONFIG_TMST_EN BIT(0) + +#define INV_ICM42600_REG_FIFO_CONFIG1 0x005F +#define INV_ICM42600_FIFO_CONFIG1_RESUME_PARTIAL_RD BIT(6) +#define INV_ICM42600_FIFO_CONFIG1_WM_GT_TH BIT(5) +#define INV_ICM42600_FIFO_CONFIG1_TMST_FSYNC_EN BIT(3) +#define INV_ICM42600_FIFO_CONFIG1_TEMP_EN BIT(2) +#define INV_ICM42600_FIFO_CONFIG1_GYRO_EN BIT(1) +#define INV_ICM42600_FIFO_CONFIG1_ACCEL_EN BIT(0) + +/* FIFO watermark is 16 bits (2 registers wide) in little-endian */ +#define INV_ICM42600_REG_FIFO_WATERMARK 0x0060 +#define INV_ICM42600_FIFO_WATERMARK_VAL(_wm) \ + cpu_to_le16((_wm) & GENMASK(11, 0)) +/* FIFO is 2048 bytes, let 12 samples for reading latency */ +#define INV_ICM42600_FIFO_WATERMARK_MAX (2048 - 12 * 16) + +#define INV_ICM42600_REG_INT_CONFIG1 0x0064 +#define INV_ICM42600_INT_CONFIG1_TPULSE_DURATION BIT(6) +#define INV_ICM42600_INT_CONFIG1_TDEASSERT_DISABLE BIT(5) +#define INV_ICM42600_INT_CONFIG1_ASYNC_RESET BIT(4) + +#define INV_ICM42600_REG_INT_SOURCE0 0x0065 +#define INV_ICM42600_INT_SOURCE0_UI_FSYNC_INT1_EN BIT(6) +#define INV_ICM42600_INT_SOURCE0_PLL_RDY_INT1_EN BIT(5) +#define INV_ICM42600_INT_SOURCE0_RESET_DONE_INT1_EN BIT(4) +#define INV_ICM42600_INT_SOURCE0_UI_DRDY_INT1_EN BIT(3) +#define INV_ICM42600_INT_SOURCE0_FIFO_THS_INT1_EN BIT(2) +#define INV_ICM42600_INT_SOURCE0_FIFO_FULL_INT1_EN BIT(1) +#define INV_ICM42600_INT_SOURCE0_UI_AGC_RDY_INT1_EN BIT(0) + +#define INV_ICM42600_REG_WHOAMI 0x0075 +#define INV_ICM42600_WHOAMI_ICM42600 0x40 +#define INV_ICM42600_WHOAMI_ICM42602 0x41 +#define INV_ICM42600_WHOAMI_ICM42605 0x42 +#define INV_ICM42600_WHOAMI_ICM42622 0x46 + +/* User bank 1 (MSB 0x10) */ +#define INV_ICM42600_REG_SENSOR_CONFIG0 0x1003 +#define INV_ICM42600_SENSOR_CONFIG0_ZG_DISABLE BIT(5) +#define INV_ICM42600_SENSOR_CONFIG0_YG_DISABLE BIT(4) +#define INV_ICM42600_SENSOR_CONFIG0_XG_DISABLE BIT(3) +#define INV_ICM42600_SENSOR_CONFIG0_ZA_DISABLE BIT(2) +#define INV_ICM42600_SENSOR_CONFIG0_YA_DISABLE BIT(1) +#define INV_ICM42600_SENSOR_CONFIG0_XA_DISABLE BIT(0) + +/* Timestamp value is 20 bits (3 registers) in little-endian */ +#define INV_ICM42600_REG_TMSTVAL 0x1062 +#define INV_ICM42600_TMSTVAL_MASK GENMASK(19, 0) + +#define INV_ICM42600_REG_INTF_CONFIG4 0x107A +#define INV_ICM42600_INTF_CONFIG4_I3C_BUS_ONLY BIT(6) +#define INV_ICM42600_INTF_CONFIG4_SPI_AP_4WIRE BIT(1) + +#define INV_ICM42600_REG_INTF_CONFIG6 0x107C +#define INV_ICM42600_INTF_CONFIG6_MASK GENMASK(4, 0) +#define INV_ICM42600_INTF_CONFIG6_I3C_EN BIT(4) +#define INV_ICM42600_INTF_CONFIG6_I3C_IBI_BYTE_EN BIT(3) +#define INV_ICM42600_INTF_CONFIG6_I3C_IBI_EN BIT(2) +#define INV_ICM42600_INTF_CONFIG6_I3C_DDR_EN BIT(1) +#define INV_ICM42600_INTF_CONFIG6_I3C_SDR_EN BIT(0) + +/* User bank 4 (MSB 0x40) */ +#define INV_ICM42600_REG_INT_SOURCE8 0x404F +#define INV_ICM42600_INT_SOURCE8_FSYNC_IBI_EN BIT(5) +#define INV_ICM42600_INT_SOURCE8_PLL_RDY_IBI_EN BIT(4) +#define INV_ICM42600_INT_SOURCE8_UI_DRDY_IBI_EN BIT(3) +#define INV_ICM42600_INT_SOURCE8_FIFO_THS_IBI_EN BIT(2) +#define INV_ICM42600_INT_SOURCE8_FIFO_FULL_IBI_EN BIT(1) +#define INV_ICM42600_INT_SOURCE8_AGC_RDY_IBI_EN BIT(0) + +#define INV_ICM42600_REG_OFFSET_USER0 0x4077 +#define INV_ICM42600_REG_OFFSET_USER1 0x4078 +#define INV_ICM42600_REG_OFFSET_USER2 0x4079 +#define INV_ICM42600_REG_OFFSET_USER3 0x407A +#define INV_ICM42600_REG_OFFSET_USER4 0x407B +#define INV_ICM42600_REG_OFFSET_USER5 0x407C +#define INV_ICM42600_REG_OFFSET_USER6 0x407D +#define INV_ICM42600_REG_OFFSET_USER7 0x407E +#define INV_ICM42600_REG_OFFSET_USER8 0x407F + +/* Sleep times required by the driver */ +#define INV_ICM42600_POWER_UP_TIME_MS 100 +#define INV_ICM42600_RESET_TIME_MS 1 +#define INV_ICM42600_ACCEL_STARTUP_TIME_MS 20 +#define INV_ICM42600_GYRO_STARTUP_TIME_MS 60 +#define INV_ICM42600_GYRO_STOP_TIME_MS 150 +#define INV_ICM42600_TEMP_STARTUP_TIME_MS 14 +#define INV_ICM42600_SUSPEND_DELAY_MS 2000 + +typedef int (*inv_icm42600_bus_setup)(struct inv_icm42600_state *); + +extern const struct regmap_config inv_icm42600_regmap_config; +extern const struct dev_pm_ops inv_icm42600_pm_ops; + +const struct iio_mount_matrix * +inv_icm42600_get_mount_matrix(const struct iio_dev *indio_dev, + const struct iio_chan_spec *chan); + +uint32_t inv_icm42600_odr_to_period(enum inv_icm42600_odr odr); + +int inv_icm42600_set_accel_conf(struct inv_icm42600_state *st, + struct inv_icm42600_sensor_conf *conf, + unsigned int *sleep); + +int inv_icm42600_set_gyro_conf(struct inv_icm42600_state *st, + struct inv_icm42600_sensor_conf *conf, + unsigned int *sleep); + +int inv_icm42600_set_temp_conf(struct inv_icm42600_state *st, bool enable, + unsigned int *sleep); + +int inv_icm42600_debugfs_reg(struct iio_dev *indio_dev, unsigned int reg, + unsigned int writeval, unsigned int *readval); + +int inv_icm42600_core_probe(struct regmap *regmap, int chip, + inv_icm42600_bus_setup bus_setup); + +#endif diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c new file mode 100644 index 000000000000..35bdf4f9d31e --- /dev/null +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c @@ -0,0 +1,618 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2020 Invensense, Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "inv_icm42600.h" + +static const struct regmap_range_cfg inv_icm42600_regmap_ranges[] = { + { + .name = "user banks", + .range_min = 0x0000, + .range_max = 0x4FFF, + .selector_reg = INV_ICM42600_REG_BANK_SEL, + .selector_mask = INV_ICM42600_BANK_SEL_MASK, + .selector_shift = 0, + .window_start = 0, + .window_len = 0x1000, + }, +}; + +const struct regmap_config inv_icm42600_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = 0x4FFF, + .ranges = inv_icm42600_regmap_ranges, + .num_ranges = ARRAY_SIZE(inv_icm42600_regmap_ranges), +}; +EXPORT_SYMBOL_GPL(inv_icm42600_regmap_config); + +struct inv_icm42600_hw { + uint8_t whoami; + const char *name; + const struct inv_icm42600_conf *conf; +}; + +/* chip initial default configuration */ +static const struct inv_icm42600_conf inv_icm42600_default_conf = { + .gyro = { + .mode = INV_ICM42600_SENSOR_MODE_OFF, + .fs = INV_ICM42600_GYRO_FS_2000DPS, + .odr = INV_ICM42600_ODR_50HZ, + .filter = INV_ICM42600_FILTER_BW_ODR_DIV_2, + }, + .accel = { + .mode = INV_ICM42600_SENSOR_MODE_OFF, + .fs = INV_ICM42600_ACCEL_FS_16G, + .odr = INV_ICM42600_ODR_50HZ, + .filter = INV_ICM42600_FILTER_BW_ODR_DIV_2, + }, + .temp_en = false, +}; + +static const struct inv_icm42600_hw inv_icm42600_hw[] = { + [INV_CHIP_ICM42600] = { + .whoami = INV_ICM42600_WHOAMI_ICM42600, + .name = "icm42600", + .conf = &inv_icm42600_default_conf, + }, + [INV_CHIP_ICM42602] = { + .whoami = INV_ICM42600_WHOAMI_ICM42602, + .name = "icm42602", + .conf = &inv_icm42600_default_conf, + }, + [INV_CHIP_ICM42605] = { + .whoami = INV_ICM42600_WHOAMI_ICM42605, + .name = "icm42605", + .conf = &inv_icm42600_default_conf, + }, + [INV_CHIP_ICM42622] = { + .whoami = INV_ICM42600_WHOAMI_ICM42622, + .name = "icm42622", + .conf = &inv_icm42600_default_conf, + }, +}; + +const struct iio_mount_matrix * +inv_icm42600_get_mount_matrix(const struct iio_dev *indio_dev, + const struct iio_chan_spec *chan) +{ + const struct inv_icm42600_state *st = + iio_device_get_drvdata((struct iio_dev *)indio_dev); + + return &st->orientation; +} + +uint32_t inv_icm42600_odr_to_period(enum inv_icm42600_odr odr) +{ + static uint32_t odr_periods[INV_ICM42600_ODR_NB] = { + /* reserved values */ + 0, 0, 0, + /* 8kHz */ + 125000, + /* 4kHz */ + 250000, + /* 2kHz */ + 500000, + /* 1kHz */ + 1000000, + /* 200Hz */ + 5000000, + /* 100Hz */ + 10000000, + /* 50Hz */ + 20000000, + /* 25Hz */ + 40000000, + /* 12.5Hz */ + 80000000, + /* 6.25Hz */ + 160000000, + /* 3.125Hz */ + 320000000, + /* 1.5625Hz */ + 640000000, + /* 500Hz */ + 2000000, + }; + + return odr_periods[odr]; +} + +static int inv_icm42600_set_pwr_mgmt0(struct inv_icm42600_state *st, + enum inv_icm42600_sensor_mode gyro, + enum inv_icm42600_sensor_mode accel, + bool temp, unsigned int *sleep) +{ + enum inv_icm42600_sensor_mode oldgyro = st->conf.gyro.mode; + enum inv_icm42600_sensor_mode oldaccel = st->conf.accel.mode; + bool oldtemp = st->conf.temp_en; + unsigned int sleepval; + unsigned int val; + int ret; + + /* if nothing changed, exit */ + if (gyro == oldgyro && accel == oldaccel && temp == oldtemp) + return 0; + + val = INV_ICM42600_PWR_MGMT0_GYRO(gyro) | + INV_ICM42600_PWR_MGMT0_ACCEL(accel); + if (!temp) + val |= INV_ICM42600_PWR_MGMT0_TEMP_DIS; + dev_dbg(regmap_get_device(st->map), "pwr_mgmt0: %#02x\n", val); + ret = regmap_write(st->map, INV_ICM42600_REG_PWR_MGMT0, val); + if (ret) + return ret; + + st->conf.gyro.mode = gyro; + st->conf.accel.mode = accel; + st->conf.temp_en = temp; + + /* compute required wait time for sensors to stabilize */ + sleepval = 0; + /* temperature stabilization time */ + if (temp && !oldtemp) { + if (sleepval < INV_ICM42600_TEMP_STARTUP_TIME_MS) + sleepval = INV_ICM42600_TEMP_STARTUP_TIME_MS; + } + /* accel startup time */ + if (accel != oldaccel && oldaccel == INV_ICM42600_SENSOR_MODE_OFF) { + /* block any register write for at least 200 µs */ + usleep_range(200, 300); + if (sleepval < INV_ICM42600_ACCEL_STARTUP_TIME_MS) + sleepval = INV_ICM42600_ACCEL_STARTUP_TIME_MS; + } + if (gyro != oldgyro) { + /* gyro startup time */ + if (oldgyro == INV_ICM42600_SENSOR_MODE_OFF) { + /* block any register write for at least 200 µs */ + usleep_range(200, 300); + if (sleepval < INV_ICM42600_GYRO_STARTUP_TIME_MS) + sleepval = INV_ICM42600_GYRO_STARTUP_TIME_MS; + /* gyro stop time */ + } else if (gyro == INV_ICM42600_SENSOR_MODE_OFF) { + if (sleepval < INV_ICM42600_GYRO_STOP_TIME_MS) + sleepval = INV_ICM42600_GYRO_STOP_TIME_MS; + } + } + + /* deferred sleep value if sleep pointer is provided or direct sleep */ + if (sleep) + *sleep = sleepval; + else if (sleepval) + msleep(sleepval); + + return 0; +} + +int inv_icm42600_set_accel_conf(struct inv_icm42600_state *st, + struct inv_icm42600_sensor_conf *conf, + unsigned int *sleep) +{ + struct inv_icm42600_sensor_conf *oldconf = &st->conf.accel; + unsigned int val; + int ret; + + /* Sanitize missing values with current values */ + if (conf->mode < 0) + conf->mode = oldconf->mode; + if (conf->fs < 0) + conf->fs = oldconf->fs; + if (conf->odr < 0) + conf->odr = oldconf->odr; + if (conf->filter < 0) + conf->filter = oldconf->filter; + + /* set ACCEL_CONFIG0 register (accel fullscale & odr) */ + if (conf->fs != oldconf->fs || conf->odr != oldconf->odr) { + val = INV_ICM42600_ACCEL_CONFIG0_FS(conf->fs) | + INV_ICM42600_ACCEL_CONFIG0_ODR(conf->odr); + dev_dbg(regmap_get_device(st->map), "accel_config0: %#02x\n", val); + ret = regmap_write(st->map, INV_ICM42600_REG_ACCEL_CONFIG0, val); + if (ret) + return ret; + oldconf->fs = conf->fs; + oldconf->odr = conf->odr; + } + + /* set GYRO_ACCEL_CONFIG0 register (accel filter) */ + if (conf->filter != oldconf->filter) { + val = INV_ICM42600_GYRO_ACCEL_CONFIG0_ACCEL_FILT(conf->filter) | + INV_ICM42600_GYRO_ACCEL_CONFIG0_GYRO_FILT(st->conf.gyro.filter); + dev_dbg(regmap_get_device(st->map), "gyro_accel_config0: %#02x\n", val); + ret = regmap_write(st->map, INV_ICM42600_REG_GYRO_ACCEL_CONFIG0, val); + if (ret) + return ret; + oldconf->filter = conf->filter; + } + + /* set PWR_MGMT0 register (accel sensor mode) */ + return inv_icm42600_set_pwr_mgmt0(st, st->conf.gyro.mode, conf->mode, + st->conf.temp_en, sleep); +} + +int inv_icm42600_set_gyro_conf(struct inv_icm42600_state *st, + struct inv_icm42600_sensor_conf *conf, + unsigned int *sleep) +{ + struct inv_icm42600_sensor_conf *oldconf = &st->conf.gyro; + unsigned int val; + int ret; + + /* sanitize missing values with current values */ + if (conf->mode < 0) + conf->mode = oldconf->mode; + if (conf->fs < 0) + conf->fs = oldconf->fs; + if (conf->odr < 0) + conf->odr = oldconf->odr; + if (conf->filter < 0) + conf->filter = oldconf->filter; + + /* set GYRO_CONFIG0 register (gyro fullscale & odr) */ + if (conf->fs != oldconf->fs || conf->odr != oldconf->odr) { + val = INV_ICM42600_GYRO_CONFIG0_FS(conf->fs) | + INV_ICM42600_GYRO_CONFIG0_ODR(conf->odr); + dev_dbg(regmap_get_device(st->map), "gyro_config0: %#02x\n", val); + ret = regmap_write(st->map, INV_ICM42600_REG_GYRO_CONFIG0, val); + if (ret) + return ret; + oldconf->fs = conf->fs; + oldconf->odr = conf->odr; + } + + /* set GYRO_ACCEL_CONFIG0 register (gyro filter) */ + if (conf->filter != oldconf->filter) { + val = INV_ICM42600_GYRO_ACCEL_CONFIG0_ACCEL_FILT(st->conf.accel.filter) | + INV_ICM42600_GYRO_ACCEL_CONFIG0_GYRO_FILT(conf->filter); + dev_dbg(regmap_get_device(st->map), "gyro_accel_config0: %#02x\n", val); + ret = regmap_write(st->map, INV_ICM42600_REG_GYRO_ACCEL_CONFIG0, val); + if (ret) + return ret; + oldconf->filter = conf->filter; + } + + /* set PWR_MGMT0 register (gyro sensor mode) */ + return inv_icm42600_set_pwr_mgmt0(st, conf->mode, st->conf.accel.mode, + st->conf.temp_en, sleep); + + return 0; +} + +int inv_icm42600_set_temp_conf(struct inv_icm42600_state *st, bool enable, + unsigned int *sleep) +{ + return inv_icm42600_set_pwr_mgmt0(st, st->conf.gyro.mode, + st->conf.accel.mode, enable, + sleep); +} + +int inv_icm42600_debugfs_reg(struct iio_dev *indio_dev, unsigned int reg, + unsigned int writeval, unsigned int *readval) +{ + struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); + int ret; + + mutex_lock(&st->lock); + + if (readval) + ret = regmap_read(st->map, reg, readval); + else + ret = regmap_write(st->map, reg, writeval); + + mutex_unlock(&st->lock); + + return ret; +} + +static int inv_icm42600_set_conf(struct inv_icm42600_state *st, + const struct inv_icm42600_conf *conf) +{ + unsigned int val; + int ret; + + /* set PWR_MGMT0 register (gyro & accel sensor mode, temp enabled) */ + val = INV_ICM42600_PWR_MGMT0_GYRO(conf->gyro.mode) | + INV_ICM42600_PWR_MGMT0_ACCEL(conf->accel.mode); + if (!conf->temp_en) + val |= INV_ICM42600_PWR_MGMT0_TEMP_DIS; + ret = regmap_write(st->map, INV_ICM42600_REG_PWR_MGMT0, val); + if (ret) + return ret; + + /* set GYRO_CONFIG0 register (gyro fullscale & odr) */ + val = INV_ICM42600_GYRO_CONFIG0_FS(conf->gyro.fs) | + INV_ICM42600_GYRO_CONFIG0_ODR(conf->gyro.odr); + ret = regmap_write(st->map, INV_ICM42600_REG_GYRO_CONFIG0, val); + if (ret) + return ret; + + /* set ACCEL_CONFIG0 register (accel fullscale & odr) */ + val = INV_ICM42600_ACCEL_CONFIG0_FS(conf->accel.fs) | + INV_ICM42600_ACCEL_CONFIG0_ODR(conf->accel.odr); + ret = regmap_write(st->map, INV_ICM42600_REG_ACCEL_CONFIG0, val); + if (ret) + return ret; + + /* set GYRO_ACCEL_CONFIG0 register (gyro & accel filters) */ + val = INV_ICM42600_GYRO_ACCEL_CONFIG0_ACCEL_FILT(conf->accel.filter) | + INV_ICM42600_GYRO_ACCEL_CONFIG0_GYRO_FILT(conf->gyro.filter); + ret = regmap_write(st->map, INV_ICM42600_REG_GYRO_ACCEL_CONFIG0, val); + if (ret) + return ret; + + /* update internal conf */ + st->conf = *conf; + + return 0; +} + +/** + * inv_icm42600_setup() - check and setup chip. + */ +static int inv_icm42600_setup(struct inv_icm42600_state *st, + inv_icm42600_bus_setup bus_setup) +{ + const struct inv_icm42600_hw *hw = &inv_icm42600_hw[st->chip]; + const struct device *dev = regmap_get_device(st->map); + unsigned int mask, val; + int ret; + + /* check chip self-identification value */ + ret = regmap_read(st->map, INV_ICM42600_REG_WHOAMI, &val); + if (ret) + return ret; + if (val != hw->whoami) { + dev_err(dev, "invalid whoami %#02x expected %#02x (%s)\n", + val, hw->whoami, hw->name); + return -ENODEV; + } + dev_info(dev, "found %s (%#02x)\n", hw->name, hw->whoami); + st->name = hw->name; + + /* reset to make sure previous state are not there */ + ret = regmap_write(st->map, INV_ICM42600_REG_DEVICE_CONFIG, + INV_ICM42600_DEVICE_CONFIG_SOFT_RESET); + if (ret) + return ret; + msleep(INV_ICM42600_RESET_TIME_MS); + ret = regmap_read(st->map, INV_ICM42600_REG_INT_STATUS, &val); + if (ret) + return ret; + if (!(val & INV_ICM42600_INT_STATUS_RESET_DONE)) { + dev_err(dev, "reset error, reset done bit not set\n"); + return -ENODEV; + } + + /* set chip bus configuration */ + ret = bus_setup(st); + if (ret) + return ret; + + /* sensor data in big-endian (default) */ + mask = INV_ICM42600_INTF_CONFIG0_SENSOR_DATA_ENDIAN; + val = INV_ICM42600_INTF_CONFIG0_SENSOR_DATA_ENDIAN; + ret = regmap_update_bits(st->map, INV_ICM42600_REG_INTF_CONFIG0, + mask, val); + if (ret) + return ret; + + return inv_icm42600_set_conf(st, hw->conf); +} + +static int inv_icm42600_enable_regulator_vddio(struct inv_icm42600_state *st) +{ + int ret; + + ret = regulator_enable(st->vddio_supply); + if (ret) + return ret; + + /* wait a little for supply ramp */ + usleep_range(3000, 4000); + + return 0; +} + +static void inv_icm42600_disable_regulators(void *_data) +{ + struct inv_icm42600_state *st = _data; + const struct device *dev = regmap_get_device(st->map); + int ret; + + ret = regulator_disable(st->vddio_supply); + if (ret) + dev_err(dev, "failed to disable vddio error %d\n", ret); + + ret = regulator_disable(st->vdd_supply); + if (ret) + dev_err(dev, "failed to disable vdd error %d\n", ret); +} + +static void inv_icm42600_disable_pm(void *_data) +{ + struct device *dev = _data; + + pm_runtime_put_sync(dev); + pm_runtime_disable(dev); +} + +int inv_icm42600_core_probe(struct regmap *regmap, int chip, + inv_icm42600_bus_setup bus_setup) +{ + struct device *dev = regmap_get_device(regmap); + struct inv_icm42600_state *st; + int ret; + + BUILD_BUG_ON(ARRAY_SIZE(inv_icm42600_hw) != INV_CHIP_NB); + if (chip < 0 || chip >= INV_CHIP_NB) { + dev_err(dev, "invalid chip = %d\n", chip); + return -ENODEV; + } + + st = devm_kzalloc(dev, sizeof(*st), GFP_KERNEL); + if (!st) + return -ENOMEM; + dev_set_drvdata(dev, st); + mutex_init(&st->lock); + st->chip = chip; + st->map = regmap; + + ret = iio_read_mount_matrix(dev, "mount-matrix", &st->orientation); + if (ret) { + dev_err(dev, "failed to retrieve mounting matrix %d\n", ret); + return ret; + } + + st->vdd_supply = devm_regulator_get(dev, "vdd"); + if (IS_ERR(st->vdd_supply)) + return PTR_ERR(st->vdd_supply); + + st->vddio_supply = devm_regulator_get(dev, "vddio"); + if (IS_ERR(st->vddio_supply)) + return PTR_ERR(st->vddio_supply); + + ret = regulator_enable(st->vdd_supply); + if (ret) + return ret; + msleep(INV_ICM42600_POWER_UP_TIME_MS); + + ret = inv_icm42600_enable_regulator_vddio(st); + if (ret) { + regulator_disable(st->vdd_supply); + return ret; + } + + ret = devm_add_action_or_reset(dev, inv_icm42600_disable_regulators, + st); + if (ret) + return ret; + + /* setup chip registers */ + ret = inv_icm42600_setup(st, bus_setup); + if (ret) + return ret; + + /* setup runtime power management */ + ret = pm_runtime_set_active(dev); + if (ret) + return ret; + pm_runtime_get_noresume(dev); + pm_runtime_enable(dev); + pm_runtime_set_autosuspend_delay(dev, INV_ICM42600_SUSPEND_DELAY_MS); + pm_runtime_use_autosuspend(dev); + pm_runtime_put(dev); + + return devm_add_action_or_reset(dev, inv_icm42600_disable_pm, dev); +} +EXPORT_SYMBOL_GPL(inv_icm42600_core_probe); + +static int __maybe_unused inv_icm42600_suspend(struct device *dev) +{ + struct inv_icm42600_state *st = dev_get_drvdata(dev); + int ret; + + mutex_lock(&st->lock); + + st->suspended.gyro = st->conf.gyro.mode; + st->suspended.accel = st->conf.accel.mode; + st->suspended.temp = st->conf.temp_en; + if (pm_runtime_suspended(dev)) { + ret = 0; + goto out_unlock; + } + + ret = inv_icm42600_set_pwr_mgmt0(st, INV_ICM42600_SENSOR_MODE_OFF, + INV_ICM42600_SENSOR_MODE_OFF, false, + NULL); + if (ret) + goto out_unlock; + + regulator_disable(st->vddio_supply); + +out_unlock: + mutex_unlock(&st->lock); + return ret; +} + +static int __maybe_unused inv_icm42600_resume(struct device *dev) +{ + struct inv_icm42600_state *st = dev_get_drvdata(dev); + int ret; + + mutex_lock(&st->lock); + + ret = inv_icm42600_enable_regulator_vddio(st); + if (ret) + goto out_unlock; + + pm_runtime_disable(dev); + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + + /* restore sensors state */ + ret = inv_icm42600_set_pwr_mgmt0(st, st->suspended.gyro, + st->suspended.accel, + st->suspended.temp, NULL); + if (ret) + goto out_unlock; + +out_unlock: + mutex_unlock(&st->lock); + return ret; +} + +static int __maybe_unused inv_icm42600_runtime_suspend(struct device *dev) +{ + struct inv_icm42600_state *st = dev_get_drvdata(dev); + int ret; + + mutex_lock(&st->lock); + + /* disable all sensors */ + ret = inv_icm42600_set_pwr_mgmt0(st, INV_ICM42600_SENSOR_MODE_OFF, + INV_ICM42600_SENSOR_MODE_OFF, false, + NULL); + if (ret) + goto error_unlock; + + regulator_disable(st->vddio_supply); + +error_unlock: + mutex_unlock(&st->lock); + return ret; +} + +static int __maybe_unused inv_icm42600_runtime_resume(struct device *dev) +{ + struct inv_icm42600_state *st = dev_get_drvdata(dev); + int ret; + + mutex_lock(&st->lock); + + ret = inv_icm42600_enable_regulator_vddio(st); + + mutex_unlock(&st->lock); + return ret; +} + +const struct dev_pm_ops inv_icm42600_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(inv_icm42600_suspend, inv_icm42600_resume) + SET_RUNTIME_PM_OPS(inv_icm42600_runtime_suspend, + inv_icm42600_runtime_resume, NULL) +}; +EXPORT_SYMBOL_GPL(inv_icm42600_pm_ops); + +MODULE_AUTHOR("InvenSense, Inc."); +MODULE_DESCRIPTION("InvenSense ICM-426xx device driver"); +MODULE_LICENSE("GPL"); From patchwork Thu May 7 14:42:12 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Baptiste Maneyrol X-Patchwork-Id: 11533977 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 12F07159A for ; Thu, 7 May 2020 14:43:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E4F4F20838 for ; Thu, 7 May 2020 14:43:17 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=invensense.com header.i=@invensense.com header.b="fcTjI6zL"; dkim=pass (1024-bit key) header.d=invensense.onmicrosoft.com header.i=@invensense.onmicrosoft.com header.b="Uf0KAzsn" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726518AbgEGOnR (ORCPT ); Thu, 7 May 2020 10:43:17 -0400 Received: from mx0b-00328301.pphosted.com ([148.163.141.47]:22222 "EHLO mx0b-00328301.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725953AbgEGOnQ (ORCPT ); Thu, 7 May 2020 10:43:16 -0400 Received: from pps.filterd (m0156136.ppops.net [127.0.0.1]) by mx0b-00328301.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 047EbhbX006057; Thu, 7 May 2020 07:43:10 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=invensense.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : content-type : mime-version; s=pfpt1; bh=er34X0ctctBVY/TXGsxPvBZIbWfDqgkiAj78pIAj8Cs=; b=fcTjI6zLLK2EgfR4yEfQu1h6o8POIGrIQfZkewN2+wydxdKHHZB7ksdIjJBhKiYNeoiI zJWrpjsjvVA10BgImQFA9pUjW3SYEJqg+rjSTfUSkqKfIisGbguBBgr3Rt1yYfjDmB32 r7wLHroVNyqcODsYexfvfCzcQp9Yo4iQ6dK3peSKkWbaD7ST5WuTbmp0liDisZZArpPB M8vFTrJXEDIqXLbSpsWmPrI6qjkWO8bGwUnGO8qv5oiSi7vIgK7nDCbSWB8hIEn29xM9 bMHWlTrS9ZQzEuSiJo4BLKtLbVuTVEdTmn6CKchHgRqnQsyWSm2l7b3uqE4yKnx1XCRJ qw== Received: from nam11-dm6-obe.outbound.protection.outlook.com (mail-dm6nam11lp2174.outbound.protection.outlook.com [104.47.57.174]) by mx0b-00328301.pphosted.com with ESMTP id 30s4tnatwj-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 07 May 2020 07:43:10 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=oG0gzy5zyCeQC4WcozcqeVALsDheHasIpnySvnU4fdBIvZj2UnUa2bw5FZDU5zDfKmRNx0OL0EiW6NJHE9btdwjCi2vLTTjSkOvWmX1BXFlNG8d9q1VimsiEg/HGm0PtxJ/7LpQAds5qwYQamwwF3D7sZOhjMyqqzpz7VUO9fF1nBPIxMLU/GqKKpDoVIEaOPszpQb5aME08kcFDxFSaCfs+Pbg1em+wJfro6l0YOVW6HVgyZECF9jm828zEmW8oN/AhF4dX83J0Jiw9IUA61DF7uEUsErlMGDc98Rj95IsB9Q4HUFai0Qm5Y4VquSccyWCHDPS/7I41Xb+f75cMFQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=er34X0ctctBVY/TXGsxPvBZIbWfDqgkiAj78pIAj8Cs=; b=lUXF/tVbfVMBY/8DChFiVcVhCxsJWUjWG7ZQn3GZZVGm2AkHKVTZvybRpIkQs5f3+l/Fo84CpcxJMoJ/wcKUu8nLbTwmM1mG5w47vDwVSjOwrNcvM6SZ4m9orlV/JnZ3MGOOBlDPD7XbT7mrkDapiX/0DD4V+SpPSsYZclGrKe6/QFiR/uyLiXVzLfJOVA8VXpe8ERM3p6z5waGm9iQZdhsUIkS2F0NRqYFkJlhwJ6z8KLjYQQQDFo9OCHpy4Z1tQIixHjDMPPDD9eNWaFFBlHzGVCt2xbQgsyvoNVV7X5iapPf0Zx9lFEg9lalac8rdthKxKBjrqZgUj64X0Dx/og== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=invensense.com; dmarc=pass action=none header.from=invensense.com; dkim=pass header.d=invensense.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=invensense.onmicrosoft.com; s=selector2-invensense-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=er34X0ctctBVY/TXGsxPvBZIbWfDqgkiAj78pIAj8Cs=; b=Uf0KAzsnJ5/G7+gXsh4QK9+J6qCGyxfoisQ+z/EZXkf6G8oOdWpG8yXwpNyMfCi/UjI5YVXhjNvA8kxcPJsPEGMXEMGVG9WTiFxns4AJIKRLo9R4Bx/s4uBczST7FQEiqA5Ui49SXGG5ebYjhweIoCV1rIFje6GMbLyYfEOV/e0= Authentication-Results: kernel.org; dkim=none (message not signed) header.d=none;kernel.org; dmarc=none action=none header.from=invensense.com; Received: from MN2PR12MB4422.namprd12.prod.outlook.com (2603:10b6:208:265::9) by MN2PR12MB4269.namprd12.prod.outlook.com (2603:10b6:208:1d4::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2979.28; Thu, 7 May 2020 14:43:09 +0000 Received: from MN2PR12MB4422.namprd12.prod.outlook.com ([fe80::7471:da8b:8ca1:6af0]) by MN2PR12MB4422.namprd12.prod.outlook.com ([fe80::7471:da8b:8ca1:6af0%4]) with mapi id 15.20.2979.028; Thu, 7 May 2020 14:43:09 +0000 From: Jean-Baptiste Maneyrol To: jic23@kernel.org, robh+dt@kernel.org, robh@kernel.org, mchehab+huawei@kernel.org, davem@davemloft.net, gregkh@linuxfoundation.org Cc: linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Jean-Baptiste Maneyrol Subject: [PATCH 02/12] iio: imu: inv_icm42600: add I2C driver for inv_icm42600 driver Date: Thu, 7 May 2020 16:42:12 +0200 Message-Id: <20200507144222.20989-3-jmaneyrol@invensense.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200507144222.20989-1-jmaneyrol@invensense.com> References: <20200507144222.20989-1-jmaneyrol@invensense.com> X-ClientProxiedBy: LNXP265CA0048.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:5c::36) To MN2PR12MB4422.namprd12.prod.outlook.com (2603:10b6:208:265::9) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from frgnb-buildozer.invcorp.invensense.com (77.157.193.39) by LNXP265CA0048.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:5c::36) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2979.26 via Frontend Transport; Thu, 7 May 2020 14:43:07 +0000 X-Mailer: git-send-email 2.17.1 X-Originating-IP: [77.157.193.39] X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: b4d962cc-56d4-407f-1a30-08d7f294f5ea X-MS-TrafficTypeDiagnostic: MN2PR12MB4269: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:843; X-Forefront-PRVS: 03965EFC76 X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: kn8YuyNJD2Y9r0ku8F6frjmqsLfza+SQfsytq3a9E/YmlViqcjXygSGCU3+OyV2JLoXtmy+i4zgdsPl3Uqs0ED+DDDwD0u/zwgauT4ViqDxa9yx5GqbVJ1dAQ2FTczXG5GkxHuvDSjspDnO9mCMDpP6cFEZUZkamTTLfdATjMuHOdK7ZneVH22TZ4by7K7mVLBc2UIEEvUSAyjRRCg3u9WbbCqsFoHh+Za8ChiHf0z7jBq9p33vChI7oUgyQBhL/OY56FxaJb853lSie5JW307rV+S2tncikJNsvkSSUtj/tppQCVyO7f531c2rYOHiX09lCjVg2MqecwSQ2FZdOfUHnbLn2oZFALQD0sHC5abg411C0HVzzNMJSzhT7O27BzlaSBhhjvfH5AfScVZ7UDNmj545BJCW0+ZySW7hkpG61J2S66288PZeOitu+P+bAMSFWAp/I4UKtKNrNTSfgk+TZrWWItNrMROa23cGokBN8zK5NoWqgLS7lxzE81woAh0SOQQ7Z7lBOdIiQMlUaog== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:MN2PR12MB4422.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFTY:;SFS:(346002)(396003)(136003)(366004)(39850400004)(376002)(33430700001)(186003)(6486002)(478600001)(16526019)(5660300002)(4326008)(33440700001)(66556008)(8676002)(1076003)(36756003)(316002)(66946007)(66476007)(6666004)(52116002)(8936002)(86362001)(2616005)(83280400001)(956004)(83320400001)(83290400001)(83310400001)(26005)(2906002)(7696005)(83300400001)(107886003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData: Ia8nNKRS+K89yLUegzsxo0McCAI2QnxKxuEnoKl3lKMATVsoyrAdbBuG1GaBGfoTJ7BaeMoaPaVAWV3G8h6eHi1C/qrtXTEpPOq3PNrOJ/8qvCFXWBsjxSdMHQ11RFFY/hJUEYt1tAzwv9AFiPu6m0cKoC5eI8QJgVSfxa1qKAzYo6/MpzbDiPr8fLF10NoB+2ws6ucxhaWAbYx88vL4BOxvrq8PHKZ0bnXOHpSi64S0us3oCZdBEKerKLBErXKmbIeymD3+aaJQ8oFSBIAasDC7QUuL0yvK3t+CVddblQzvidy64a6+DxybqPf0cXDNiTEw1IGKlz/+UiYrCv/ENkHrp9R6h9wzv5mQsutloPdFePtXtW9OZgFNA9SzDPTFA4CBl/p/AiybIQ7naaryWCvnPmy+P3SpsMePDnRcu2CLzdqZqEMO2UQBTshulWLO8M6023Wy544MXCtSkV2Jm7GGSMlj+6fbHCJnwEpVAu8tiNUTHLh6M606E2+3qKFQYO2qnXgpOjFNtueSwLePtqH3hEOtYqkzFcgVegbTCRPh3QHvHZH0g8dixI5mx3WnyeZaJ9bzANRI97hHHuDqL8vIjh98AE6CMGaCVU3A2RBGhgTN7fgHK3HZ4Ba6e6S9Mz0TMfs0IbifJvcaxNI2sFP6VA1mK+aj05uYSPUGVCcbnh+R77635L1yYJUhWiUp1EJwqesOwQHFaM3+hDkj7srZTnjQ4P2d5GXeGYa4gAz8YJEKwpq/q+jV5OdU5NUmogxuqCMcwD6zs4RH5ojndKcdwaPIJTXJFE0Ttb/28rQ= X-OriginatorOrg: invensense.com X-MS-Exchange-CrossTenant-Network-Message-Id: b4d962cc-56d4-407f-1a30-08d7f294f5ea X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 May 2020 14:43:09.3137 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 462b3b3b-e42b-47ea-801a-f1581aac892d X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: IhfZf7tBM762Ndi4cEZwmLGFfeT/jTOvJn2r0+G+KVAHR/xec7Vkn+hghHxmsUJzjtrXrNfGwY4XRJdSlQBRGVTUTsgFNXx+ZN1l7t669Jw= X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR12MB4269 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.216,18.0.676 definitions=2020-05-07_09:2020-05-07,2020-05-07 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 adultscore=0 priorityscore=1501 spamscore=0 mlxlogscore=999 impostorscore=0 suspectscore=0 phishscore=0 malwarescore=0 lowpriorityscore=0 bulkscore=0 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2005070118 Sender: linux-iio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org Add I2C driver for InvenSense ICM-426xxx devices. Configure bus signal slew rates as indicated in the datasheet. Signed-off-by: Jean-Baptiste Maneyrol --- .../iio/imu/inv_icm42600/inv_icm42600_i2c.c | 117 ++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 drivers/iio/imu/inv_icm42600/inv_icm42600_i2c.c diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_i2c.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_i2c.c new file mode 100644 index 000000000000..b61f993beacf --- /dev/null +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_i2c.c @@ -0,0 +1,117 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2020 InvenSense, Inc. + */ + +#include +#include +#include +#include +#include + +#include "inv_icm42600.h" + +static int inv_icm42600_i2c_bus_setup(struct inv_icm42600_state *st) +{ + unsigned int mask, val; + int ret; + + /* setup interface registers */ + mask = INV_ICM42600_INTF_CONFIG6_MASK; + val = INV_ICM42600_INTF_CONFIG6_I3C_EN; + ret = regmap_update_bits(st->map, INV_ICM42600_REG_INTF_CONFIG6, + mask, val); + if (ret) + return ret; + + mask = INV_ICM42600_INTF_CONFIG4_I3C_BUS_ONLY; + val = 0; + ret = regmap_update_bits(st->map, INV_ICM42600_REG_INTF_CONFIG4, + mask, val); + if (ret) + return ret; + + /* set slew rates for I2C and SPI */ + mask = INV_ICM42600_DRIVE_CONFIG_I2C_MASK | + INV_ICM42600_DRIVE_CONFIG_SPI_MASK; + val = INV_ICM42600_DRIVE_CONFIG_I2C(INV_ICM42600_SLEW_RATE_12_36NS) | + INV_ICM42600_DRIVE_CONFIG_SPI(INV_ICM42600_SLEW_RATE_12_36NS); + ret = regmap_update_bits(st->map, INV_ICM42600_REG_DRIVE_CONFIG, + mask, val); + if (ret) + return ret; + + /* disable SPI bus */ + mask = INV_ICM42600_INTF_CONFIG0_UI_SIFS_CFG_MASK; + val = INV_ICM42600_INTF_CONFIG0_UI_SIFS_CFG_SPI_DIS; + return regmap_update_bits(st->map, INV_ICM42600_REG_INTF_CONFIG0, + mask, val); +} + +static int inv_icm42600_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + const void *match; + enum inv_icm42600_chip chip; + struct regmap *regmap; + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK)) + return -ENOTSUPP; + + match = device_get_match_data(&client->dev); + if (match) + chip = (enum inv_icm42600_chip)match; + else if (id) + chip = (enum inv_icm42600_chip)id->driver_data; + else + return -EINVAL; + + regmap = devm_regmap_init_i2c(client, &inv_icm42600_regmap_config); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + return inv_icm42600_core_probe(regmap, chip, + inv_icm42600_i2c_bus_setup); +} + +static const struct of_device_id inv_icm42600_of_matches[] = { + { + .compatible = "invensense,icm42600", + .data = (void *)INV_CHIP_ICM42600, + }, { + .compatible = "invensense,icm42602", + .data = (void *)INV_CHIP_ICM42602, + }, { + .compatible = "invensense,icm42605", + .data = (void *)INV_CHIP_ICM42605, + }, { + .compatible = "invensense,icm42622", + .data = (void *)INV_CHIP_ICM42622, + }, + {} +}; +MODULE_DEVICE_TABLE(of, inv_icm42600_of_matches); + +static const struct i2c_device_id inv_icm42600_ids[] = { + {"icm42600", INV_CHIP_ICM42600}, + {"icm42602", INV_CHIP_ICM42602}, + {"icm42605", INV_CHIP_ICM42605}, + {"icm42622", INV_CHIP_ICM42622}, + {} +}; +MODULE_DEVICE_TABLE(i2c, inv_icm42600_ids); + +static struct i2c_driver inv_icm42600_driver = { + .probe = inv_icm42600_probe, + .id_table = inv_icm42600_ids, + .driver = { + .of_match_table = inv_icm42600_of_matches, + .name = "inv-icm42600-i2c", + .pm = &inv_icm42600_pm_ops, + }, +}; +module_i2c_driver(inv_icm42600_driver); + +MODULE_AUTHOR("InvenSense, Inc."); +MODULE_DESCRIPTION("InvenSense ICM-426xx I2C driver"); +MODULE_LICENSE("GPL"); From patchwork Thu May 7 14:42:13 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Baptiste Maneyrol X-Patchwork-Id: 11533981 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8DD85139F for ; Thu, 7 May 2020 14:43:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 74CEC20936 for ; Thu, 7 May 2020 14:43:21 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=invensense.com header.i=@invensense.com header.b="QNBRP1/H"; dkim=pass (1024-bit key) header.d=invensense.onmicrosoft.com header.i=@invensense.onmicrosoft.com header.b="i2ri2etE" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726744AbgEGOnU (ORCPT ); Thu, 7 May 2020 10:43:20 -0400 Received: from mx0b-00328301.pphosted.com ([148.163.141.47]:26054 "EHLO mx0b-00328301.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726476AbgEGOnR (ORCPT ); Thu, 7 May 2020 10:43:17 -0400 Received: from pps.filterd (m0156136.ppops.net [127.0.0.1]) by mx0b-00328301.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 047EbhbY006057; Thu, 7 May 2020 07:43:13 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=invensense.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : content-type : mime-version; s=pfpt1; bh=guxiu81OBChS1YnA49t3W141td/mF6MlvFvEZ+dC/EU=; b=QNBRP1/HJ6qEBorQHeP2Cd3M9d0kUS3RVBUSb9rKFQPIlbwM3gP/eNehUXn42+vpDJgz 57x5lHfgDqLWiLrd5ux2GgngejUxnmhJLKwEcZFP24QlPAgrVVRgTKSeizqUP9gaBWGj 9mVAVNVSEaGBxzar48MawjvUjnA9a5ru4i67VnybqKrViBqSRZYaUjBbD8yPFF4XkODz BDP9th2LRJPC8+UhqfmzE5vLHMhd57V27WoVPpk2bxect9h2m9Mc5We4mE5vWwn8d9bO JfYKZPyoxZxrVNWNuQDMqrpwRx0SqLVNFln1xNr2MWYzxCVoYvP32RHfPX6DBjr1h7dL 7Q== Received: from nam11-dm6-obe.outbound.protection.outlook.com (mail-dm6nam11lp2171.outbound.protection.outlook.com [104.47.57.171]) by mx0b-00328301.pphosted.com with ESMTP id 30s4tnatwk-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 07 May 2020 07:43:13 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=l60h+dv1xQ9W1WrwLeC3+lJDfe5IujimzJie4A7e7pQKYwFGZU5jD1ZfEoElQhBV9HHQWKAlRbZGtNSejTSKQjaZUW6+eo83jq/yNfzyXBF5c04T3/r9YQ/b8hfH9bZ5vVgvuGTHlEnnYYNuHktXXKogYVZ0I7tyxIvyvA8pC+qruF6KNqn2atbQtrCTmw6ayGDD36FqABkuq6h56t7cLAHzmuvb7qD4UqvXGoniQv5m/T1FPwFrJ2LOxZaX4o0q4sFwCyKGBHJknY9hjDin7l/eYv6MgsN2dmNBHpZF0SAcK7ejS3BVFg7ECtXRKa4SVByAR1L5ym3TZ+fsmKiMjw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=guxiu81OBChS1YnA49t3W141td/mF6MlvFvEZ+dC/EU=; b=dt+Cs6TAwSVtRI9kGxPdKDzQ9fvnCRQrEKTq7mBOr+I1ulV6iK+fGtOGy8SQCixmwx0Zkya9mqy0GKsXBzJV9k7APhN+UehoTX/AyggB5RTk8cZBQzNF5rrJT54O4GWrevDOo/s5YHZZ3QwiIYrnbw3E0pA7IL99u0WP2QwJvXSlWzxELb7SgJkhU1agE45Re9Rdk9irkfnI0R4I7XubG32wiPLrL2qakPPmrGOR3mYET2gD8qBp3dRLhvmuOINwCYNuWXvqy6RJ4yzbL24UMrVyYmPrGfKHrAS69V08LUptmMDeZyE6VKzF6AfKja0XPTi0CjBLzp1/Oyx0yOgYfw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=invensense.com; dmarc=pass action=none header.from=invensense.com; dkim=pass header.d=invensense.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=invensense.onmicrosoft.com; s=selector2-invensense-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=guxiu81OBChS1YnA49t3W141td/mF6MlvFvEZ+dC/EU=; b=i2ri2etEVgPEF235g1Bxw+wd/07yuSxnd8RiT8ZkbbzgKP0BC1hCPrSclennCTwR2bt6Vq4Kqkrb3xwIx8Ssdd23KCACMrZs5SdjE+N3ntOgo6s0NLiBK37L2NFQo+L1iFr7HxzSCdDfPOQHFEhl8G2Q0SwOoVR//Fur+GjeJwc= Authentication-Results: kernel.org; dkim=none (message not signed) header.d=none;kernel.org; dmarc=none action=none header.from=invensense.com; Received: from MN2PR12MB4422.namprd12.prod.outlook.com (2603:10b6:208:265::9) by MN2PR12MB4269.namprd12.prod.outlook.com (2603:10b6:208:1d4::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2979.28; Thu, 7 May 2020 14:43:11 +0000 Received: from MN2PR12MB4422.namprd12.prod.outlook.com ([fe80::7471:da8b:8ca1:6af0]) by MN2PR12MB4422.namprd12.prod.outlook.com ([fe80::7471:da8b:8ca1:6af0%4]) with mapi id 15.20.2979.028; Thu, 7 May 2020 14:43:11 +0000 From: Jean-Baptiste Maneyrol To: jic23@kernel.org, robh+dt@kernel.org, robh@kernel.org, mchehab+huawei@kernel.org, davem@davemloft.net, gregkh@linuxfoundation.org Cc: linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Jean-Baptiste Maneyrol Subject: [PATCH 03/12] iio: imu: inv_icm42600: add SPI driver for inv_icm42600 driver Date: Thu, 7 May 2020 16:42:13 +0200 Message-Id: <20200507144222.20989-4-jmaneyrol@invensense.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200507144222.20989-1-jmaneyrol@invensense.com> References: <20200507144222.20989-1-jmaneyrol@invensense.com> X-ClientProxiedBy: LNXP265CA0048.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:5c::36) To MN2PR12MB4422.namprd12.prod.outlook.com (2603:10b6:208:265::9) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from frgnb-buildozer.invcorp.invensense.com (77.157.193.39) by LNXP265CA0048.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:5c::36) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2979.26 via Frontend Transport; Thu, 7 May 2020 14:43:09 +0000 X-Mailer: git-send-email 2.17.1 X-Originating-IP: [77.157.193.39] X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 91f2104d-787e-4710-baa9-08d7f294f70c X-MS-TrafficTypeDiagnostic: MN2PR12MB4269: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:843; X-Forefront-PRVS: 03965EFC76 X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: PPgkhNY4WewqVg9sFZUOVlKj/1ylBm22ojrhWAbIXy/NH5+Yzse8zCExFSFj/3m9xp6IeJGp8b7Unc+hFC2SWY4/PW1G1CbSQdVAnYeHsBO855tqyTmwZR5JwR0zSw1yQu/VN++WQeFqJp+66fqy6Ur/lv+Rjj42OBYWZk3BvF+MUixOQpnnuSZstFt58mfvnAbTzrDZze3/QROh1FpZO9qz5ouhs0lRcUkdpfaKe2n90HYbcOQyKL+oDFvdjEOPQoLUei7JmpbtO6qJ76gV23pCYXh9JllyAcunaEkabbi2XhX8xHC8n+wuGsCbWbPwK1r+er6Tg/tLz0pFIEB31ytB5Yjfe2AzecAvSEkvW73m+lh4Ija0Wj9C9swduVa5m2Vz5/gLinj147FKuirKf4QSCT6iYDWVH8Yw+QrWzFl8kQoM8+/03deOWDA6ASN4xzL8N0QVKzHOZs1TkU93BYB56fKKCkZeJ11USX7dEZB6jE2GP6ltXAM+kD5PbbksaeB8Fk3/QJsyqRpHxws+TA== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:MN2PR12MB4422.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFTY:;SFS:(346002)(396003)(136003)(366004)(39850400004)(376002)(33430700001)(186003)(6486002)(478600001)(16526019)(5660300002)(4326008)(33440700001)(66556008)(8676002)(1076003)(36756003)(316002)(66946007)(66476007)(6666004)(52116002)(8936002)(86362001)(2616005)(83280400001)(956004)(83320400001)(83290400001)(83310400001)(26005)(2906002)(7696005)(83300400001)(107886003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData: Dh23YC+MTF6Tmku1vAlsRo+0ppr+QYSRd2xbEKfyY5zySPkxjVKmZ+yy5oqEEom7V9pYg/VxDW8fJrbuLV3UZcWHiTxiCZ1ipAhIufl0SevlGVumJEtnZxthMGiIJxt1ArTjyNpQepFvBB+tYU8M/I03XarKICPyraulZqRX9lB7T7ogkN1iWiF6tFDuf73kZ8YtpLqURC17ZUE7GX5pAsJFIVbOvAP7t5OWtIc09FjXQwVfowUSLU/clppAp4h/hs8Qa57Y3SyUJ59na7z1j254RY3wBYaYcXnXtRJzYqlidggDwIOvk4t9BTMUFD2ykO2b6l46e2FNF7DVb1rx4BJJe6K7+z1kVd54P8+Xwun14UXyfeHy5243/zyYMYD/Q5WxkoVHl09xsuK1YrXABMYOIPBBaiRVd2UZFomDQUnFbxLFqTCM3mV7iJC0zEefXOL/xCGACpMWqObOwEByKORnC4RxnOWd3rmbJlwdfUn4/aOYpAJjfaR4mBOifrkzDju+hCiEXWgJQIhvlZIL0QCkbstywKDA2K8/EpXJo9aXsu/7myM3pa3eH4VoQiegxnwNF5alZqa8u0QmyZwA+wYu0briDmy1jw3FYM0gBjV/JoXDyidaGroHF4vrDxKq0NoIqJcizUef2JqLb7L1kaceirYN6uOK/yk3qTv2U9v6mPs1bEXUn1C7moggqZdUq8saY7nDDYATlkaamVYD8QIGV7T2Uu5w9FfpAl9kmLywuwWJuecMHCf3HsDIoH23zERZFtlgxiUGvmPahzf9nnrxFISIeDKVpC6K/AaZ+74= X-OriginatorOrg: invensense.com X-MS-Exchange-CrossTenant-Network-Message-Id: 91f2104d-787e-4710-baa9-08d7f294f70c X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 May 2020 14:43:11.2084 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 462b3b3b-e42b-47ea-801a-f1581aac892d X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: gFXFbrhGQxHNHQLhPG707z1e5u9yDIcoCytyVueRE3pInTWnYwU3yJTSlq+3OyZKma+RsCd6EB+nOMb1xB5T/qNNLjdEOc1jNxJdWeA+Udw= X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR12MB4269 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.216,18.0.676 definitions=2020-05-07_09:2020-05-07,2020-05-07 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 adultscore=0 priorityscore=1501 spamscore=0 mlxlogscore=999 impostorscore=0 suspectscore=0 phishscore=0 malwarescore=0 lowpriorityscore=0 bulkscore=0 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2005070118 Sender: linux-iio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org Add SPI driver for InvenSense ICM-426xxx devices. Configure bus signal slew rates as indicated in the datasheet. Signed-off-by: Jean-Baptiste Maneyrol --- .../iio/imu/inv_icm42600/inv_icm42600_spi.c | 117 ++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c new file mode 100644 index 000000000000..835ced68a3a3 --- /dev/null +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c @@ -0,0 +1,117 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2020 InvenSense, Inc. + */ + +#include +#include +#include +#include +#include + +#include "inv_icm42600.h" + +static int inv_icm42600_spi_bus_setup(struct inv_icm42600_state *st) +{ + unsigned int mask, val; + int ret; + + /* setup interface registers */ + mask = INV_ICM42600_INTF_CONFIG6_MASK; + val = INV_ICM42600_INTF_CONFIG6_I3C_EN | + INV_ICM42600_INTF_CONFIG6_I3C_SDR_EN | + INV_ICM42600_INTF_CONFIG6_I3C_DDR_EN; + ret = regmap_update_bits(st->map, INV_ICM42600_REG_INTF_CONFIG6, + mask, val); + if (ret) + return ret; + + mask = INV_ICM42600_INTF_CONFIG4_I3C_BUS_ONLY; + val = 0; + ret = regmap_update_bits(st->map, INV_ICM42600_REG_INTF_CONFIG4, + mask, val); + if (ret) + return ret; + + /* set slew rates for I2C and SPI */ + mask = INV_ICM42600_DRIVE_CONFIG_I2C_MASK | + INV_ICM42600_DRIVE_CONFIG_SPI_MASK; + val = INV_ICM42600_DRIVE_CONFIG_I2C(INV_ICM42600_SLEW_RATE_20_60NS) | + INV_ICM42600_DRIVE_CONFIG_SPI(INV_ICM42600_SLEW_RATE_INF_2NS); + ret = regmap_update_bits(st->map, INV_ICM42600_REG_DRIVE_CONFIG, + mask, val); + if (ret) + return ret; + + /* disable i2c bus */ + mask = INV_ICM42600_INTF_CONFIG0_UI_SIFS_CFG_MASK; + val = INV_ICM42600_INTF_CONFIG0_UI_SIFS_CFG_I2C_DIS; + return regmap_update_bits(st->map, INV_ICM42600_REG_INTF_CONFIG0, + mask, val); +} + +static int inv_icm42600_probe(struct spi_device *spi) +{ + const void *match; + const struct spi_device_id *spi_id; + enum inv_icm42600_chip chip; + struct regmap *regmap; + + match = device_get_match_data(&spi->dev); + spi_id = spi_get_device_id(spi); + if (match) + chip = (enum inv_icm42600_chip)match; + else if (spi_id) + chip = (enum inv_icm42600_chip)spi_id->driver_data; + else + return -EINVAL; + + regmap = devm_regmap_init_spi(spi, &inv_icm42600_regmap_config); + if (IS_ERR(regmap)) + return PTR_ERR(regmap); + + return inv_icm42600_core_probe(regmap, chip, + inv_icm42600_spi_bus_setup); +} + +static const struct of_device_id inv_icm42600_of_matches[] = { + { + .compatible = "invensense,icm42600", + .data = (void *)INV_CHIP_ICM42600, + }, { + .compatible = "invensense,icm42602", + .data = (void *)INV_CHIP_ICM42602, + }, { + .compatible = "invensense,icm42605", + .data = (void *)INV_CHIP_ICM42605, + }, { + .compatible = "invensense,icm42622", + .data = (void *)INV_CHIP_ICM42622, + }, + {} +}; +MODULE_DEVICE_TABLE(of, inv_icm42600_of_matches); + +static const struct spi_device_id inv_icm42600_ids[] = { + {"icm42600", INV_CHIP_ICM42600}, + {"icm42602", INV_CHIP_ICM42602}, + {"icm42605", INV_CHIP_ICM42605}, + {"icm42622", INV_CHIP_ICM42622}, + {} +}; +MODULE_DEVICE_TABLE(spi, inv_icm42600_ids); + +static struct spi_driver inv_icm42600_driver = { + .probe = inv_icm42600_probe, + .id_table = inv_icm42600_ids, + .driver = { + .of_match_table = inv_icm42600_of_matches, + .name = "inv-icm42600-spi", + .pm = &inv_icm42600_pm_ops, + }, +}; +module_spi_driver(inv_icm42600_driver); + +MODULE_AUTHOR("InvenSense, Inc."); +MODULE_DESCRIPTION("InvenSense ICM-426xx SPI driver"); +MODULE_LICENSE("GPL"); From patchwork Thu May 7 14:42:14 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Baptiste Maneyrol X-Patchwork-Id: 11533979 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6E859159A for ; Thu, 7 May 2020 14:43:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 457CB2184D for ; Thu, 7 May 2020 14:43:21 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=invensense.com header.i=@invensense.com header.b="mhUze55S"; dkim=pass (1024-bit key) header.d=invensense.onmicrosoft.com header.i=@invensense.onmicrosoft.com header.b="LRkYwmlY" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726771AbgEGOnU (ORCPT ); Thu, 7 May 2020 10:43:20 -0400 Received: from mx0a-00328301.pphosted.com ([148.163.145.46]:23002 "EHLO mx0a-00328301.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726598AbgEGOnT (ORCPT ); Thu, 7 May 2020 10:43:19 -0400 Received: from pps.filterd (m0156134.ppops.net [127.0.0.1]) by mx0a-00328301.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 047Eegd6005564; Thu, 7 May 2020 07:43:15 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=invensense.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : content-type : mime-version; s=pfpt1; bh=1bOjF4OnTz74NnMsiumNubxHvSGSjvKYI03VWRA74XU=; b=mhUze55Sk5y25snO+6W00wnwxh946shaykrqFAzLrSoRm89sw2E5gHpV3dnTyQToNhuv k0wZhckKoi9tgYkQoSf1RDRyxqlXpeseA9qrcADbjYHHWneR/+NviGc/SexEjbCkj7o+ gBYXimdl7WvYXshsDZ3Ks4u7FSw5QopofBWJptk8KP9eL8GrnRNrMjNJ7SNRZYGqxIri XxepbSyhJrYfZHoVhUJ963lkPev2D5nMhEy/niSDYMOLk1CBjFBXZjXsLExdRzYPEuk3 XzLn00r6jvUzp9Ka+A1shDvBYa2HNVL2B8flHUOOy95+ykNUYNrRaaejr5fJoi4mHkTy 9g== Received: from nam11-dm6-obe.outbound.protection.outlook.com (mail-dm6nam11lp2169.outbound.protection.outlook.com [104.47.57.169]) by mx0a-00328301.pphosted.com with ESMTP id 30sfwdjs8q-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 07 May 2020 07:43:15 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=d/J4roHpgG08xUz++aZUToAEOKlLElCFh83P/KUHrrhfapw6KGoJks5mX7qu+0vT+WdJjmeLIkNYSe8KTBTJBTXrI49yCzno6qlmBhNRbQQ92HXoEH5a96Gi1RCNnbCGCq5tFwhvCbvQLLioOk1Sfqj0mCrcS6xO5ga9NSXJFNgq/fzgU4jIwugyoC1nJlduJloOCBs+Cl4KXhD15pITX0w7h8qKBpnoKKojZTp+zGmctDKrzdrvDc5dy/di5M1TJP8HhlUbiXVVnpd3p+zVaHqSystx4qRQTNx6RDNm8nRAKs98xBpad9VRK6OLHbj7serRMNfQw0luuoK6EISjdA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=1bOjF4OnTz74NnMsiumNubxHvSGSjvKYI03VWRA74XU=; b=ej2CrkeRbFGbFTw1YrRYJ2aG9/fG1RAWW/9DQTBypzYrAdZmo74pZl7KAtWa6bqqjnVwGKjbl2C9iE+X/OG7MLEKWZvV4+OVb7ZsD7LAZdDyIh01OCHhzvxZe/kyz/KBmJYlFcnSwjNRL5QlVpTJQbTT/QDfIH7kRa4zZUA5q/lf5uSXlZ1ST/dsJ8KBDi4VVaiwos6Zrn9FWLKYvoSMohI7HWnPHoiujuVlqcTwVlGY59awnAl4S3D4FHUlsb8MUq6krNJCHRjB6idMZzDEiLvDv6T2nJQz7w1JcnFWVps7tMAWPv8NWWQAPIotXcDCtIWrechUf6IpZc9u02z/XQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=invensense.com; dmarc=pass action=none header.from=invensense.com; dkim=pass header.d=invensense.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=invensense.onmicrosoft.com; s=selector2-invensense-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=1bOjF4OnTz74NnMsiumNubxHvSGSjvKYI03VWRA74XU=; b=LRkYwmlYAdO8VE4wL85bubraBTHMP20qFoOP94R7Zg7oyM0Q8puvoqO0tVlNEteTli2KyKSdi9iBld256T5NGto22LoahFLMP7sBXm0LgthvhEuingXI4ck/JFX4BBaIRDnXUYcr0OJfExIbjP5O4bIFrFoOe20QFkNYDUe97OI= Authentication-Results: kernel.org; dkim=none (message not signed) header.d=none;kernel.org; dmarc=none action=none header.from=invensense.com; Received: from MN2PR12MB4422.namprd12.prod.outlook.com (2603:10b6:208:265::9) by MN2PR12MB4269.namprd12.prod.outlook.com (2603:10b6:208:1d4::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2979.28; Thu, 7 May 2020 14:43:14 +0000 Received: from MN2PR12MB4422.namprd12.prod.outlook.com ([fe80::7471:da8b:8ca1:6af0]) by MN2PR12MB4422.namprd12.prod.outlook.com ([fe80::7471:da8b:8ca1:6af0%4]) with mapi id 15.20.2979.028; Thu, 7 May 2020 14:43:14 +0000 From: Jean-Baptiste Maneyrol To: jic23@kernel.org, robh+dt@kernel.org, robh@kernel.org, mchehab+huawei@kernel.org, davem@davemloft.net, gregkh@linuxfoundation.org Cc: linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Jean-Baptiste Maneyrol Subject: [PATCH 04/12] iio: imu: inv_icm42600: add gyroscope IIO device Date: Thu, 7 May 2020 16:42:14 +0200 Message-Id: <20200507144222.20989-5-jmaneyrol@invensense.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200507144222.20989-1-jmaneyrol@invensense.com> References: <20200507144222.20989-1-jmaneyrol@invensense.com> X-ClientProxiedBy: LNXP265CA0048.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:5c::36) To MN2PR12MB4422.namprd12.prod.outlook.com (2603:10b6:208:265::9) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from frgnb-buildozer.invcorp.invensense.com (77.157.193.39) by LNXP265CA0048.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:5c::36) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2979.26 via Frontend Transport; Thu, 7 May 2020 14:43:11 +0000 X-Mailer: git-send-email 2.17.1 X-Originating-IP: [77.157.193.39] X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 27e96971-22d8-4f7e-149e-08d7f294f82d X-MS-TrafficTypeDiagnostic: MN2PR12MB4269: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:565; X-Forefront-PRVS: 03965EFC76 X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: PjQIsCVxWzvnzUHr3hBJOD1kUKlwyoGxB/yOYrmtKrHWXcWfW2klR2XkHWpUjS40ZsqqbDduq98RKfMDk3dRfAVUI5tjCcA3UbkRjLBMkprdGn/OPWv4iKUR6Y6vE1IIfDB4jaYGDVIuyqOLXGkzvQAe3HcHWROlCw+R+vgWeojBvD35qb8oIoY1yLzTGRPjgW1W68Ktgw3fqgJsyxx50LhuT4cyHazXfbHUbT+uYDn9FWBfptOmHc36g0+koUpZZgHqvCpdni7iItg463vpOzpF1y3GcNU78Qx4FVqEEsufQhCHXW32Di5Uil9yBH9ZH5aSDkkqIxS6wuRJYLshumIpAgX5SH5GG9RvCFd3VTsom1jo40zhrucoYzIX70FCIy1AIq7jHCq4UyTQL1653SSpiKNIitGaVomdHWSUbXyw8Z0jqolc+IpKHgnHQ2fWCkwgzBxMpySB3ubu3YufvlEUcGEMKCFi7KxFwY4wnkNs8WtquqV5jQHv0Tw8AU4tncO+XaMPjKDCFfj1D0z0zQ== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:MN2PR12MB4422.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFTY:;SFS:(346002)(396003)(136003)(366004)(39850400004)(376002)(33430700001)(186003)(6486002)(478600001)(16526019)(5660300002)(4326008)(33440700001)(30864003)(66556008)(8676002)(1076003)(36756003)(316002)(66946007)(66476007)(52116002)(8936002)(86362001)(2616005)(83280400001)(956004)(83320400001)(83290400001)(83310400001)(26005)(2906002)(7696005)(83300400001)(107886003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData: J7bDtdj253sIw1hHVbsBVV4g4vR0uz5YJ8py4kk5vMq0suLqBgd+GjqMvJu7bKarXkD5bpgKvofj54QEaiDJNRugSDtGktoxdztK/krO6wWo8lZ29DnbJFd37iKw5AdQaFLOovuVo3Iu8yW6NS1S5mygPJR+ph2YOUw0EahVaBbp9j18Nj8QJbYzRESEz3bkazgkNRxpyLW6z5/qvXMqJuC0dm6WomxqIieQH4JaPF6YWr9fJB0RvEnD+5w36kaAzn26mRatbh0wtShCjQ49PgszEn0nbyWh2iinV2quy30RZvLjC6woUOYZePwkfIMI7PNIQwqgtChNZC/h+xxClHUHBGmc/vgXLZjpVbnC12mOQQHAe/fIyzF5e3bsyt4W/NFXTQ8uWkHMvy1O6UHMZowgRbTE6Uk8REdcFNhsFAU1fxYKPcLLqvTpg60RUjvymdnSk1ubWjpxCrnIhUy3mhJD0pTOHpHFS6WyYQF6+6s/0kFbIqHKonq2BmroWC6LR2Cya6cPCLUNzQlPRHIEpUcPA5Cac1hMzF48n4/3szg7PBeTT+N33a9H2lXmDgcAfXyW7YA6TV3UQBrQ6lo5KHqL5I6InGiG++9W+0Py4pT3cQP8l0f8Ou+9MYx5fGUvRAUudFpamT4+Ca0e0qtqaw5WzSyEWEYRi/YrGRplTAWAqeUmIQsrD8/6rHMxTipbsszB98kjqgTR19cOb0yTuEUYKJiLTP92LmP1UpOfnPMZ1D/kuL5LetU137j7ab6thX/dU8NF6c6xdukfDLjQqJv99h8NLe8JcHgzwZa0yzM= X-OriginatorOrg: invensense.com X-MS-Exchange-CrossTenant-Network-Message-Id: 27e96971-22d8-4f7e-149e-08d7f294f82d X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 May 2020 14:43:14.1584 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 462b3b3b-e42b-47ea-801a-f1581aac892d X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: j7YM6Seu+Pvj5xixFihT7BfWw1499Jn55+LXvE5qnUZrXFTFHpzB4eyuiFIZjraOQhhiYt1xx6oB4MwasyILfmv4KgovD35stE+gYZ0NqmM= X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR12MB4269 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.216,18.0.676 definitions=2020-05-07_09:2020-05-07,2020-05-07 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 adultscore=0 spamscore=0 impostorscore=0 suspectscore=0 mlxscore=0 phishscore=0 bulkscore=0 malwarescore=0 mlxlogscore=999 clxscore=1015 priorityscore=1501 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2005070118 Sender: linux-iio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org Add IIO device for gyroscope sensor with data polling interface. Attributes: raw, scale, sampling_frequency, calibbias. Gyroscope in low noise mode. Signed-off-by: Jean-Baptiste Maneyrol --- drivers/iio/imu/inv_icm42600/inv_icm42600.h | 4 + .../iio/imu/inv_icm42600/inv_icm42600_core.c | 5 + .../iio/imu/inv_icm42600/inv_icm42600_gyro.c | 549 ++++++++++++++++++ 3 files changed, 558 insertions(+) create mode 100644 drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600.h b/drivers/iio/imu/inv_icm42600/inv_icm42600.h index 8da4c8249aed..ca41a9d6404a 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600.h +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600.h @@ -120,6 +120,7 @@ struct inv_icm42600_suspended { * @orientation: sensor chip orientation relative to main hardware. * @conf: chip sensors configurations. * @suspended: suspended sensors configuration. + * @indio_gyro: gyroscope IIO device. */ struct inv_icm42600_state { struct mutex lock; @@ -131,6 +132,7 @@ struct inv_icm42600_state { struct iio_mount_matrix orientation; struct inv_icm42600_conf conf; struct inv_icm42600_suspended suspended; + struct iio_dev *indio_gyro; }; /* Virtual register addresses: @bank on MSB (4 upper bits), @address on LSB */ @@ -369,4 +371,6 @@ int inv_icm42600_debugfs_reg(struct iio_dev *indio_dev, unsigned int reg, int inv_icm42600_core_probe(struct regmap *regmap, int chip, inv_icm42600_bus_setup bus_setup); +int inv_icm42600_gyro_init(struct inv_icm42600_state *st); + #endif diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c index 35bdf4f9d31e..151257652ce6 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c @@ -503,6 +503,11 @@ int inv_icm42600_core_probe(struct regmap *regmap, int chip, if (ret) return ret; + /* create and init gyroscope iio device */ + ret = inv_icm42600_gyro_init(st); + if (ret) + return ret; + /* setup runtime power management */ ret = pm_runtime_set_active(dev); if (ret) diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c new file mode 100644 index 000000000000..74aa2b5fa611 --- /dev/null +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c @@ -0,0 +1,549 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2020 Invensense, Inc. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "inv_icm42600.h" + +#define INV_ICM42600_GYRO_CHAN(_modifier, _index, _ext_info) \ + { \ + .type = IIO_ANGL_VEL, \ + .modified = 1, \ + .channel2 = _modifier, \ + .info_mask_separate = \ + BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_CALIBBIAS), \ + .info_mask_shared_by_type = \ + BIT(IIO_CHAN_INFO_SCALE), \ + .info_mask_shared_by_type_available = \ + BIT(IIO_CHAN_INFO_SCALE), \ + .info_mask_shared_by_all = \ + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .info_mask_shared_by_all_available = \ + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .scan_index = _index, \ + .scan_type = { \ + .sign = 's', \ + .realbits = 16, \ + .storagebits = 16, \ + .shift = 0, \ + .endianness = IIO_BE, \ + }, \ + .ext_info = _ext_info, \ + } + +enum inv_icm42600_gyro_scan { + INV_ICM42600_GYRO_SCAN_X, + INV_ICM42600_GYRO_SCAN_Y, + INV_ICM42600_GYRO_SCAN_Z, +}; + +static const struct iio_chan_spec_ext_info inv_icm42600_gyro_ext_infos[] = { + IIO_MOUNT_MATRIX(IIO_SHARED_BY_ALL, inv_icm42600_get_mount_matrix), + {}, +}; + +static const struct iio_chan_spec inv_icm42600_gyro_channels[] = { + INV_ICM42600_GYRO_CHAN(IIO_MOD_X, INV_ICM42600_GYRO_SCAN_X, + inv_icm42600_gyro_ext_infos), + INV_ICM42600_GYRO_CHAN(IIO_MOD_Y, INV_ICM42600_GYRO_SCAN_Y, + inv_icm42600_gyro_ext_infos), + INV_ICM42600_GYRO_CHAN(IIO_MOD_Z, INV_ICM42600_GYRO_SCAN_Z, + inv_icm42600_gyro_ext_infos), +}; + +static int inv_icm42600_gyro_read_sensor(struct inv_icm42600_state *st, + struct iio_chan_spec const *chan, + int16_t *val) +{ + struct device *dev = regmap_get_device(st->map); + struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT; + unsigned int reg; + __be16 data; + int ret; + + if (chan->type != IIO_ANGL_VEL) + return -EINVAL; + + switch (chan->channel2) { + case IIO_MOD_X: + reg = INV_ICM42600_REG_GYRO_DATA_X; + break; + case IIO_MOD_Y: + reg = INV_ICM42600_REG_GYRO_DATA_Y; + break; + case IIO_MOD_Z: + reg = INV_ICM42600_REG_GYRO_DATA_Z; + break; + default: + return -EINVAL; + } + + pm_runtime_get_sync(dev); + mutex_lock(&st->lock); + + /* enable gyro sensor */ + conf.mode = INV_ICM42600_SENSOR_MODE_LOW_NOISE; + ret = inv_icm42600_set_gyro_conf(st, &conf, NULL); + if (ret) + goto exit; + + /* read gyro register data */ + ret = regmap_bulk_read(st->map, reg, &data, sizeof(data)); + if (ret) + goto exit; + + *val = (int16_t)be16_to_cpu(data); + if (*val == INV_ICM42600_DATA_INVALID) + ret = -EINVAL; +exit: + mutex_unlock(&st->lock); + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + return ret; +} + +/* IIO format int + nano */ +static const int inv_icm42600_gyro_scale[] = { + /* +/- 2000dps => 0.001065264 rad/s */ + [2 * INV_ICM42600_GYRO_FS_2000DPS] = 0, + [2 * INV_ICM42600_GYRO_FS_2000DPS + 1] = 1065264, + /* +/- 1000dps => 0.000532632 rad/s */ + [2 * INV_ICM42600_GYRO_FS_1000DPS] = 0, + [2 * INV_ICM42600_GYRO_FS_1000DPS + 1] = 532632, + /* +/- 500dps => 0.000266316 rad/s */ + [2 * INV_ICM42600_GYRO_FS_500DPS] = 0, + [2 * INV_ICM42600_GYRO_FS_500DPS + 1] = 266316, + /* +/- 250dps => 0.000133158 rad/s */ + [2 * INV_ICM42600_GYRO_FS_250DPS] = 0, + [2 * INV_ICM42600_GYRO_FS_250DPS + 1] = 133158, + /* +/- 125dps => 0.000066579 rad/s */ + [2 * INV_ICM42600_GYRO_FS_125DPS] = 0, + [2 * INV_ICM42600_GYRO_FS_125DPS + 1] = 66579, + /* +/- 62.5dps => 0.000033290 rad/s */ + [2 * INV_ICM42600_GYRO_FS_62_5DPS] = 0, + [2 * INV_ICM42600_GYRO_FS_62_5DPS + 1] = 33290, + /* +/- 31.25dps => 0.000016645 rad/s */ + [2 * INV_ICM42600_GYRO_FS_31_25DPS] = 0, + [2 * INV_ICM42600_GYRO_FS_31_25DPS + 1] = 16645, + /* +/- 15.625dps => 0.000008322 rad/s */ + [2 * INV_ICM42600_GYRO_FS_15_625DPS] = 0, + [2 * INV_ICM42600_GYRO_FS_15_625DPS + 1] = 8322, +}; + +static int inv_icm42600_gyro_read_scale(struct inv_icm42600_state *st, + int *val, int *val2) +{ + unsigned int idx; + + mutex_lock(&st->lock); + idx = st->conf.gyro.fs; + mutex_unlock(&st->lock); + + *val = inv_icm42600_gyro_scale[2 * idx]; + *val2 = inv_icm42600_gyro_scale[2 * idx + 1]; + return IIO_VAL_INT_PLUS_NANO; +} + +static int inv_icm42600_gyro_write_scale(struct inv_icm42600_state *st, + int val, int val2) +{ + struct device *dev = regmap_get_device(st->map); + unsigned int idx; + struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT; + int ret; + + for (idx = 0; idx < ARRAY_SIZE(inv_icm42600_gyro_scale); idx += 2) { + if (val == inv_icm42600_gyro_scale[idx] && + val2 == inv_icm42600_gyro_scale[idx + 1]) + break; + } + if (idx >= ARRAY_SIZE(inv_icm42600_gyro_scale)) + return -EINVAL; + + /* update gyro fs */ + pm_runtime_get_sync(dev); + + mutex_lock(&st->lock); + conf.fs = idx / 2; + ret = inv_icm42600_set_gyro_conf(st, &conf, NULL); + mutex_unlock(&st->lock); + + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + + return ret; +} + +/* IIO format int + micro */ +static const int inv_icm42600_gyro_odr[] = { + /* 12.5Hz */ + 12, 500000, + /* 25Hz */ + 25, 0, + /* 50Hz */ + 50, 0, + /* 100Hz */ + 100, 0, + /* 200Hz */ + 200, 0, + /* 1kHz */ + 1000, 0, + /* 2kHz */ + 2000, 0, + /* 4kHz */ + 4000, 0, +}; + +static const int inv_icm42600_gyro_odr_conv[] = { + INV_ICM42600_ODR_12_5HZ, + INV_ICM42600_ODR_25HZ, + INV_ICM42600_ODR_50HZ, + INV_ICM42600_ODR_100HZ, + INV_ICM42600_ODR_200HZ, + INV_ICM42600_ODR_1KHZ_LN, + INV_ICM42600_ODR_2KHZ_LN, + INV_ICM42600_ODR_4KHZ_LN, +}; + +static int inv_icm42600_gyro_read_odr(struct inv_icm42600_state *st, + int *val, int *val2) +{ + unsigned int odr; + unsigned int i; + + mutex_lock(&st->lock); + odr = st->conf.gyro.odr; + mutex_unlock(&st->lock); + + for (i = 0; i < ARRAY_SIZE(inv_icm42600_gyro_odr_conv); ++i) { + if (inv_icm42600_gyro_odr_conv[i] == odr) + break; + } + if (i >= ARRAY_SIZE(inv_icm42600_gyro_odr_conv)) + return -EINVAL; + + *val = inv_icm42600_gyro_odr[2 * i]; + *val2 = inv_icm42600_gyro_odr[2 * i + 1]; + + return IIO_VAL_INT_PLUS_MICRO; +} + +static int inv_icm42600_gyro_write_odr(struct inv_icm42600_state *st, + int val, int val2) +{ + struct device *dev = regmap_get_device(st->map); + unsigned int idx; + struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT; + int ret; + + for (idx = 0; idx < ARRAY_SIZE(inv_icm42600_gyro_odr); idx += 2) { + if (val == inv_icm42600_gyro_odr[idx] && + val2 == inv_icm42600_gyro_odr[idx + 1]) + break; + } + if (idx >= ARRAY_SIZE(inv_icm42600_gyro_odr)) + return -EINVAL; + + /* update gyro odr */ + pm_runtime_get_sync(dev); + + mutex_lock(&st->lock); + conf.odr = inv_icm42600_gyro_odr_conv[idx / 2]; + ret = inv_icm42600_set_gyro_conf(st, &conf, NULL); + mutex_unlock(&st->lock); + + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + + return ret; +} + +static int inv_icm42600_gyro_read_offset(struct inv_icm42600_state *st, + struct iio_chan_spec const *chan, + int16_t *val) +{ + struct device *dev = regmap_get_device(st->map); + unsigned int reg; + uint8_t data[2]; + int ret; + + if (chan->type != IIO_ANGL_VEL) + return -EINVAL; + + switch (chan->channel2) { + case IIO_MOD_X: + reg = INV_ICM42600_REG_OFFSET_USER0; + break; + case IIO_MOD_Y: + reg = INV_ICM42600_REG_OFFSET_USER1; + break; + case IIO_MOD_Z: + reg = INV_ICM42600_REG_OFFSET_USER3; + break; + default: + return -EINVAL; + } + + pm_runtime_get_sync(dev); + + /* read gyro offset data */ + mutex_lock(&st->lock); + ret = regmap_bulk_read(st->map, reg, &data, sizeof(data)); + mutex_unlock(&st->lock); + if (ret) + goto exit; + + switch (chan->channel2) { + case IIO_MOD_X: + *val = (int16_t)(((data[1] & 0x0F) << 8) | data[0]); + break; + case IIO_MOD_Y: + *val = (int16_t)(((data[0] & 0xF0) << 4) | data[1]); + break; + case IIO_MOD_Z: + *val = (int16_t)(((data[1] & 0x0F) << 8) | data[0]); + break; + default: + ret = -EINVAL; + break; + } + +exit: + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + return ret; +} + +static int inv_icm42600_gyro_write_offset(struct inv_icm42600_state *st, + struct iio_chan_spec const *chan, + int val) +{ + struct device *dev = regmap_get_device(st->map); + unsigned int reg, regval; + uint8_t data[2]; + int ret; + + if (chan->type != IIO_ANGL_VEL) + return -EINVAL; + + switch (chan->channel2) { + case IIO_MOD_X: + reg = INV_ICM42600_REG_OFFSET_USER0; + break; + case IIO_MOD_Y: + reg = INV_ICM42600_REG_OFFSET_USER1; + break; + case IIO_MOD_Z: + reg = INV_ICM42600_REG_OFFSET_USER3; + break; + default: + return -EINVAL; + } + + /* value is limited to 12 bits signed */ + if (val < -2048 || val > 2047) + return -EINVAL; + + pm_runtime_get_sync(dev); + mutex_lock(&st->lock); + + switch (chan->channel2) { + case IIO_MOD_X: + /* OFFSET_USER1 register is shared */ + ret = regmap_read(st->map, INV_ICM42600_REG_OFFSET_USER1, + ®val); + if (ret) + goto out_unlock; + data[0] = val & 0xFF; + data[1] = (regval & 0xF0) | ((val & 0xF00) >> 8); + break; + case IIO_MOD_Y: + /* OFFSET_USER1 register is shared */ + ret = regmap_read(st->map, INV_ICM42600_REG_OFFSET_USER1, + ®val); + if (ret) + goto out_unlock; + data[0] = ((val & 0xF00) >> 4) | (regval & 0x0F); + data[1] = val & 0xFF; + break; + case IIO_MOD_Z: + /* OFFSET_USER4 register is shared */ + ret = regmap_read(st->map, INV_ICM42600_REG_OFFSET_USER4, + ®val); + if (ret) + goto out_unlock; + data[0] = val & 0xFF; + data[1] = (regval & 0xF0) | ((val & 0xF00) >> 8); + break; + default: + ret = -EINVAL; + goto out_unlock; + } + + ret = regmap_bulk_write(st->map, reg, data, sizeof(data)); + +out_unlock: + mutex_unlock(&st->lock); + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + return ret; +} + +static int inv_icm42600_gyro_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); + int16_t data; + int ret; + + if (chan->type != IIO_ANGL_VEL) + return -EINVAL; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; + ret = inv_icm42600_gyro_read_sensor(st, chan, &data); + iio_device_release_direct_mode(indio_dev); + if (ret) + return ret; + *val = data; + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + return inv_icm42600_gyro_read_scale(st, val, val2); + case IIO_CHAN_INFO_SAMP_FREQ: + return inv_icm42600_gyro_read_odr(st, val, val2); + case IIO_CHAN_INFO_CALIBBIAS: + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; + ret = inv_icm42600_gyro_read_offset(st, chan, &data); + iio_device_release_direct_mode(indio_dev); + if (ret) + return ret; + *val = data; + return IIO_VAL_INT; + default: + return -EINVAL; + } +} + +static int inv_icm42600_gyro_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + const int **vals, + int *type, int *length, long mask) +{ + if (chan->type != IIO_ANGL_VEL) + return -EINVAL; + + switch (mask) { + case IIO_CHAN_INFO_SCALE: + *vals = inv_icm42600_gyro_scale; + *type = IIO_VAL_INT_PLUS_NANO; + *length = ARRAY_SIZE(inv_icm42600_gyro_scale); + return IIO_AVAIL_LIST; + case IIO_CHAN_INFO_SAMP_FREQ: + *vals = inv_icm42600_gyro_odr; + *type = IIO_VAL_INT_PLUS_MICRO; + *length = ARRAY_SIZE(inv_icm42600_gyro_odr); + return IIO_AVAIL_LIST; + default: + return -EINVAL; + } +} + +static int inv_icm42600_gyro_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); + int ret; + + if (chan->type != IIO_ANGL_VEL) + return -EINVAL; + + switch (mask) { + case IIO_CHAN_INFO_SCALE: + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; + ret = inv_icm42600_gyro_write_scale(st, val, val2); + iio_device_release_direct_mode(indio_dev); + return ret; + case IIO_CHAN_INFO_SAMP_FREQ: + return inv_icm42600_gyro_write_odr(st, val, val2); + case IIO_CHAN_INFO_CALIBBIAS: + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; + ret = inv_icm42600_gyro_write_offset(st, chan, val); + iio_device_release_direct_mode(indio_dev); + return ret; + default: + return -EINVAL; + } +} + +static int inv_icm42600_gyro_write_raw_get_fmt(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + long mask) +{ + if (chan->type != IIO_ANGL_VEL) + return -EINVAL; + + switch (mask) { + case IIO_CHAN_INFO_SCALE: + return IIO_VAL_INT_PLUS_NANO; + case IIO_CHAN_INFO_SAMP_FREQ: + return IIO_VAL_INT_PLUS_MICRO; + case IIO_CHAN_INFO_CALIBBIAS: + return IIO_VAL_INT; + default: + return -EINVAL; + } +} + +static const struct iio_info inv_icm42600_gyro_info = { + .read_raw = inv_icm42600_gyro_read_raw, + .read_avail = inv_icm42600_gyro_read_avail, + .write_raw = inv_icm42600_gyro_write_raw, + .write_raw_get_fmt = inv_icm42600_gyro_write_raw_get_fmt, + .debugfs_reg_access = inv_icm42600_debugfs_reg, +}; + +int inv_icm42600_gyro_init(struct inv_icm42600_state *st) +{ + struct device *dev = regmap_get_device(st->map); + const char *name; + struct iio_dev *indio_dev; + + name = devm_kasprintf(dev, GFP_KERNEL, "%s-gyro", st->name); + if (!name) + return -ENOMEM; + + indio_dev = devm_iio_device_alloc(dev, 0); + if (!indio_dev) + return -ENOMEM; + + iio_device_set_drvdata(indio_dev, st); + indio_dev->dev.parent = dev; + indio_dev->name = name; + indio_dev->info = &inv_icm42600_gyro_info; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = inv_icm42600_gyro_channels; + indio_dev->num_channels = ARRAY_SIZE(inv_icm42600_gyro_channels); + + st->indio_gyro = indio_dev; + return devm_iio_device_register(dev, st->indio_gyro); +} From patchwork Thu May 7 14:42:15 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Baptiste Maneyrol X-Patchwork-Id: 11533995 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D719C159A for ; Thu, 7 May 2020 14:43:55 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B427D20870 for ; Thu, 7 May 2020 14:43:55 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=invensense.com header.i=@invensense.com header.b="XxGx7sf7"; dkim=pass (1024-bit key) header.d=invensense.onmicrosoft.com header.i=@invensense.onmicrosoft.com header.b="Zg1bvf1c" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728105AbgEGOnx (ORCPT ); Thu, 7 May 2020 10:43:53 -0400 Received: from mx0b-00328301.pphosted.com ([148.163.141.47]:34630 "EHLO mx0b-00328301.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726807AbgEGOn0 (ORCPT ); Thu, 7 May 2020 10:43:26 -0400 Received: from pps.filterd (m0156136.ppops.net [127.0.0.1]) by mx0b-00328301.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 047EeBq9009573; Thu, 7 May 2020 07:43:18 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=invensense.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : content-type : mime-version; s=pfpt1; bh=jKvwThIXd9hxjE3UeowRVGB++10GIiQYd9la+T+pXPs=; b=XxGx7sf7oAukNB4PgaAWgEKX4S7a1wkChInpUSTSQTvgtfM1gDdBBdt9j8BKHkHKL8rZ /AHZl9uQzXvXbDSrPA55N2jUpjhUeBSv3M9Cgy7MhV1mJT4IHglF9zG7Vc5HBEbunFVw j3BwfrYjN4Zk9AJuOEjiDCVkLYRwNmmSIByd1Nq6ms/7t6/ohH9Wpp6x2pfTuB0DUAII wv8komZ3XbFoPy+RJ/FhM3SpBpBl7ceEnJUIoiVjQlg/hRZY9OoBEEzjGQgIBJTztDbH MrhmeHVAi5r/0B+Gj9AWqzTOwE4rCJIeX1LyZh2zxwKIIr8dLsbvwhi1f+ObEY5cHJoJ wg== Received: from nam11-dm6-obe.outbound.protection.outlook.com (mail-dm6nam11lp2172.outbound.protection.outlook.com [104.47.57.172]) by mx0b-00328301.pphosted.com with ESMTP id 30s4tnatwq-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 07 May 2020 07:43:18 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=KLEqywLsIAGdcvHf3FB6KXgb+1GCOMBgUoVBG3xJC7kNV8OdN3Eu5BSr3ot7hs/6V5e2zvt8/LbcIzIPTST631MO2I7DPn4TMG7TBgEkfPnWXI9hT0GOsyYGlmn8XuPbK18VgA8we50iuZS7k0OAkB+LAYT2VmLiB9GSvNRTMqV7chmWHNKFhSNfGmf5dLh/MQDUWid7MY6PiCX4xnJM/NRLUpDLnyX6Bev/QRNqQEKKYJUwoNbPCMaf//CvDguWYS6TBgN/P8xzNNkm5BAMVtnOhFv2PpJEbri94CbT8ej0Wlej3NYPbBflgWZfquB6+src5uUzUzmqZoyngA8TNA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=jKvwThIXd9hxjE3UeowRVGB++10GIiQYd9la+T+pXPs=; b=TDgWMevRXZajH2d2QPeiBl6k6nbKLfQVC0SymwedqAinMv8HQDAEeToYagKbnIlwwKSoHFjW7Enrty+GgTD1wwvI4VcQNtD6eZt1z3JaN7V0GIVWNvNRTcnyqSKgWJHwhH+QCalYWBwPNcZ1MR2RsfOBwKSf8Y8K0ZfOFZKAV9pitMFM+Wj8MmV+0bu6vUQWL1ZNwfQ/WDt9Aag1JGjWDHBfEurYTmyxL/dOkUPEdIlgoeeTDIZO3MUpcUvF6Saaba1owgH489Iuuuq2D+SMt3gfhXSKNUhuy8Zhj3a7oILoPL/6NGQU08LKuTStpo/256UMHFSsXOQHYFn0tnGkcg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=invensense.com; dmarc=pass action=none header.from=invensense.com; dkim=pass header.d=invensense.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=invensense.onmicrosoft.com; s=selector2-invensense-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=jKvwThIXd9hxjE3UeowRVGB++10GIiQYd9la+T+pXPs=; b=Zg1bvf1c9+8fItG3I1P1c83fcznuaecNc7I4k+bUods5oRNVS2wNeBcuiTvQZCi708yhmwoKH9E7rUEpxg9vJ3qXyyeAzcQA1xYieTA0jSWaxryCqTjmLVHMzQHhe2Z5sbto3AJf+DOYZQ0D5lsQfucwpsFagWXa3CEs32vZIsE= Authentication-Results: kernel.org; dkim=none (message not signed) header.d=none;kernel.org; dmarc=none action=none header.from=invensense.com; Received: from MN2PR12MB4422.namprd12.prod.outlook.com (2603:10b6:208:265::9) by MN2PR12MB4269.namprd12.prod.outlook.com (2603:10b6:208:1d4::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2979.28; Thu, 7 May 2020 14:43:16 +0000 Received: from MN2PR12MB4422.namprd12.prod.outlook.com ([fe80::7471:da8b:8ca1:6af0]) by MN2PR12MB4422.namprd12.prod.outlook.com ([fe80::7471:da8b:8ca1:6af0%4]) with mapi id 15.20.2979.028; Thu, 7 May 2020 14:43:16 +0000 From: Jean-Baptiste Maneyrol To: jic23@kernel.org, robh+dt@kernel.org, robh@kernel.org, mchehab+huawei@kernel.org, davem@davemloft.net, gregkh@linuxfoundation.org Cc: linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Jean-Baptiste Maneyrol Subject: [PATCH 05/12] iio: imu: inv_icm42600: add accelerometer IIO device Date: Thu, 7 May 2020 16:42:15 +0200 Message-Id: <20200507144222.20989-6-jmaneyrol@invensense.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200507144222.20989-1-jmaneyrol@invensense.com> References: <20200507144222.20989-1-jmaneyrol@invensense.com> X-ClientProxiedBy: LNXP265CA0048.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:5c::36) To MN2PR12MB4422.namprd12.prod.outlook.com (2603:10b6:208:265::9) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from frgnb-buildozer.invcorp.invensense.com (77.157.193.39) by LNXP265CA0048.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:5c::36) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2979.26 via Frontend Transport; Thu, 7 May 2020 14:43:14 +0000 X-Mailer: git-send-email 2.17.1 X-Originating-IP: [77.157.193.39] X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 630e27e3-3b12-4e59-8ed1-08d7f294fa1d X-MS-TrafficTypeDiagnostic: MN2PR12MB4269: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:5236; X-Forefront-PRVS: 03965EFC76 X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: L9/EOLK7xPnzdF4LjQsAhQUOHYehN8RYs8fHeIpQy2dYWKfkaNmEHSfc7czUO5nVZpAqzkKDHmeJBQ1DyunH6kNhx1y9TP18sUkCUut6wYQhvgQVhus4HkihZLN+fP02mdaaDulldaJYAJrOSBxHqdkKhZGVH+0lcTS81JWOXAgBkPqvwYV52jvHwRiTYKDd9fOTZTKBwZV3dMcImBfKhoqtYnKmxXTPgTRV0dYyYMSfeb78X2CK+etlQDpmYv7OqdQthaDZSME7h7kjjZpw1Cs0gSfYMo0qaTUXxf4dXBL7Q0DE4wNde4QMXoxRadxzy59t9y1TgtMOeQtvvl3X5rzv/d8rhQGvqBabftgmyt78TX3OxPCubF45Y3z7XPFOyeAH/ckdTC1AMBliVqFDRZ+UuGtxOEKD/s1Ls3UG9rE4c4f4cKJEyvACmQOs3JgD8h4zcE4yGqkCFqM18cMY0WUSscqIERKSVnbHQ8SU5K46Bjo37l8awdrJ4ehv5UiqG/51hf7oB8EcJ0S20q6z2g== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:MN2PR12MB4422.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFTY:;SFS:(346002)(396003)(136003)(366004)(39850400004)(376002)(33430700001)(186003)(6486002)(478600001)(16526019)(5660300002)(4326008)(33440700001)(30864003)(66556008)(8676002)(1076003)(36756003)(316002)(66946007)(66476007)(52116002)(8936002)(86362001)(2616005)(83280400001)(956004)(83320400001)(83290400001)(83310400001)(26005)(2906002)(7696005)(83300400001)(107886003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData: qZZs2vBJ5cPPgSm5IVJmMY+9vwk1NB7SZCEZxiUQbgGxA8pDuDJGdllmSGrLiIfvzV4FjJQeBW6E2Skz/LAGu6gbBR9bKEc3p2el+2gNWwOVnzm1SB3SiLeXuv/zGiTb16XSHn5miE4BWhTN+LoFe+N63Js8glUIcA+13DF2ZsiOurRoLuOwTggKQ1o36jUPjTDmVKMfbj155txHm7KuNU8qQ+rqOBnw8xtEsD+f6AJrP9N3Gn12EZbpiZmC3nizxEgDuRd7MKUHWRiaxgje8qJbZdj1i1NR8H43D4fa8IfKOudR2c2KyX5oC+o4KO0XT8dlWwAzo4dlZWTIfcQeC/r+ZEyZ24699gfpiIBLwUy0W4zMrSpJYQXfUBPshQZU5hza9XNt6YKGzLOXYyLypALyozbpbo6gU4//bT9ymKqMsA4KpqDWw4JK32y3pwumNzd96ki+vIAWa7uQL4SZuE0qqXvx2GR24A2FAKvgGI71WcN171Y825GFRDwFxVHZ3aqIi2DEHQ1JB4YdeRlLZETGBgFaybGB/XOALGJoU3YmAScQmYFSq9D6v60PtwumNVJ9NX9I8uX/hpbooFz8r5fZp0N+n4zssMQy662zbmirpawXWHNFx1bvSwp7FWKFy8QjIhfQecvLrMBqqSobdp4z8YLJGxR7uupEzsf2KjnzTOfSKTHTsDX+NEkx19xbzq5zA+WIXsIV9RWrFPH0+lqICix6jFDDiIe/n0oJBsXzEJ/PjKBVFz7EK17ifq9ILtj9E5PejnJK2I3KkV4cr9oz4knoZ6j2tw4uazlGSMI= X-OriginatorOrg: invensense.com X-MS-Exchange-CrossTenant-Network-Message-Id: 630e27e3-3b12-4e59-8ed1-08d7f294fa1d X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 May 2020 14:43:16.4484 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 462b3b3b-e42b-47ea-801a-f1581aac892d X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: ByZKg8hNHeeBZK7wtnBTvr3w7HQmvOOLLakIMvv+PS0IMWANUidfwc3BaSKMaUuHU0LnTng7weTJ7NBflGfwpgU8IVhmfrLnX5qzqSw6gmQ= X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR12MB4269 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.216,18.0.676 definitions=2020-05-07_09:2020-05-07,2020-05-07 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 adultscore=0 priorityscore=1501 spamscore=0 mlxlogscore=999 impostorscore=0 suspectscore=0 phishscore=0 malwarescore=0 lowpriorityscore=0 bulkscore=0 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2005070118 Sender: linux-iio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org Add IIO device for accelerometer sensor with data polling interface. Attributes: raw, scale, sampling_frequency, calibbias. Accelerometer in low noise mode. Signed-off-by: Jean-Baptiste Maneyrol --- drivers/iio/imu/inv_icm42600/inv_icm42600.h | 4 + .../iio/imu/inv_icm42600/inv_icm42600_accel.c | 537 ++++++++++++++++++ .../iio/imu/inv_icm42600/inv_icm42600_core.c | 5 + 3 files changed, 546 insertions(+) create mode 100644 drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600.h b/drivers/iio/imu/inv_icm42600/inv_icm42600.h index ca41a9d6404a..bc963b3d1800 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600.h +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600.h @@ -121,6 +121,7 @@ struct inv_icm42600_suspended { * @conf: chip sensors configurations. * @suspended: suspended sensors configuration. * @indio_gyro: gyroscope IIO device. + * @indio_accel: accelerometer IIO device. */ struct inv_icm42600_state { struct mutex lock; @@ -133,6 +134,7 @@ struct inv_icm42600_state { struct inv_icm42600_conf conf; struct inv_icm42600_suspended suspended; struct iio_dev *indio_gyro; + struct iio_dev *indio_accel; }; /* Virtual register addresses: @bank on MSB (4 upper bits), @address on LSB */ @@ -373,4 +375,6 @@ int inv_icm42600_core_probe(struct regmap *regmap, int chip, int inv_icm42600_gyro_init(struct inv_icm42600_state *st); +int inv_icm42600_accel_init(struct inv_icm42600_state *st); + #endif diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c new file mode 100644 index 000000000000..397e3d0fd42b --- /dev/null +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c @@ -0,0 +1,537 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2020 Invensense, Inc. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "inv_icm42600.h" + +#define INV_ICM42600_ACCEL_CHAN(_modifier, _index, _ext_info) \ + { \ + .type = IIO_ACCEL, \ + .modified = 1, \ + .channel2 = _modifier, \ + .info_mask_separate = \ + BIT(IIO_CHAN_INFO_RAW) | \ + BIT(IIO_CHAN_INFO_CALIBBIAS), \ + .info_mask_shared_by_type = \ + BIT(IIO_CHAN_INFO_SCALE), \ + .info_mask_shared_by_type_available = \ + BIT(IIO_CHAN_INFO_SCALE), \ + .info_mask_shared_by_all = \ + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .info_mask_shared_by_all_available = \ + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .scan_index = _index, \ + .scan_type = { \ + .sign = 's', \ + .realbits = 16, \ + .storagebits = 16, \ + .shift = 0, \ + .endianness = IIO_BE, \ + }, \ + .ext_info = _ext_info, \ + } + +enum inv_icm42600_accel_scan { + INV_ICM42600_ACCEL_SCAN_X, + INV_ICM42600_ACCEL_SCAN_Y, + INV_ICM42600_ACCEL_SCAN_Z, +}; + +static const struct iio_chan_spec_ext_info inv_icm42600_accel_ext_infos[] = { + IIO_MOUNT_MATRIX(IIO_SHARED_BY_ALL, inv_icm42600_get_mount_matrix), + {}, +}; + +static const struct iio_chan_spec inv_icm42600_accel_channels[] = { + INV_ICM42600_ACCEL_CHAN(IIO_MOD_X, INV_ICM42600_ACCEL_SCAN_X, + inv_icm42600_accel_ext_infos), + INV_ICM42600_ACCEL_CHAN(IIO_MOD_Y, INV_ICM42600_ACCEL_SCAN_Y, + inv_icm42600_accel_ext_infos), + INV_ICM42600_ACCEL_CHAN(IIO_MOD_Z, INV_ICM42600_ACCEL_SCAN_Z, + inv_icm42600_accel_ext_infos), +}; + +static int inv_icm42600_accel_read_sensor(struct inv_icm42600_state *st, + struct iio_chan_spec const *chan, + int16_t *val) +{ + struct device *dev = regmap_get_device(st->map); + struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT; + unsigned int reg; + __be16 data; + int ret; + + if (chan->type != IIO_ACCEL) + return -EINVAL; + + switch (chan->channel2) { + case IIO_MOD_X: + reg = INV_ICM42600_REG_ACCEL_DATA_X; + break; + case IIO_MOD_Y: + reg = INV_ICM42600_REG_ACCEL_DATA_Y; + break; + case IIO_MOD_Z: + reg = INV_ICM42600_REG_ACCEL_DATA_Z; + break; + default: + return -EINVAL; + } + + pm_runtime_get_sync(dev); + mutex_lock(&st->lock); + + /* enable accel sensor */ + conf.mode = INV_ICM42600_SENSOR_MODE_LOW_NOISE; + ret = inv_icm42600_set_accel_conf(st, &conf, NULL); + if (ret) + goto exit; + + /* read accel register data */ + ret = regmap_bulk_read(st->map, reg, &data, sizeof(data)); + if (ret) + goto exit; + + *val = (int16_t)be16_to_cpu(data); + if (*val == INV_ICM42600_DATA_INVALID) + ret = -EINVAL; +exit: + mutex_unlock(&st->lock); + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + return ret; +} + +/* IIO format int + nano */ +static const int inv_icm42600_accel_scale[] = { + /* +/- 16G => 0.004788403 m/s-2 */ + [2 * INV_ICM42600_ACCEL_FS_16G] = 0, + [2 * INV_ICM42600_ACCEL_FS_16G + 1] = 4788403, + /* +/- 8G => 0.002394202 m/s-2 */ + [2 * INV_ICM42600_ACCEL_FS_8G] = 0, + [2 * INV_ICM42600_ACCEL_FS_8G + 1] = 2394202, + /* +/- 4G => 0.001197101 m/s-2 */ + [2 * INV_ICM42600_ACCEL_FS_4G] = 0, + [2 * INV_ICM42600_ACCEL_FS_4G + 1] = 1197101, + /* +/- 2G => 0.000598550 m/s-2 */ + [2 * INV_ICM42600_ACCEL_FS_2G] = 0, + [2 * INV_ICM42600_ACCEL_FS_2G + 1] = 598550, +}; + +static int inv_icm42600_accel_read_scale(struct inv_icm42600_state *st, + int *val, int *val2) +{ + unsigned int idx; + + mutex_lock(&st->lock); + idx = st->conf.accel.fs; + mutex_unlock(&st->lock); + + *val = inv_icm42600_accel_scale[2 * idx]; + *val2 = inv_icm42600_accel_scale[2 * idx + 1]; + return IIO_VAL_INT_PLUS_NANO; +} + +static int inv_icm42600_accel_write_scale(struct inv_icm42600_state *st, + int val, int val2) +{ + struct device *dev = regmap_get_device(st->map); + unsigned int idx; + struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT; + int ret; + + for (idx = 0; idx < ARRAY_SIZE(inv_icm42600_accel_scale); idx += 2) { + if (val == inv_icm42600_accel_scale[idx] && + val2 == inv_icm42600_accel_scale[idx + 1]) + break; + } + if (idx >= ARRAY_SIZE(inv_icm42600_accel_scale)) + return -EINVAL; + + /* update accel fs */ + pm_runtime_get_sync(dev); + + mutex_lock(&st->lock); + conf.fs = idx / 2; + ret = inv_icm42600_set_accel_conf(st, &conf, NULL); + mutex_unlock(&st->lock); + + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + + return ret; +} + +/* IIO format int + micro */ +static const int inv_icm42600_accel_odr[] = { + /* 12.5Hz */ + 12, 500000, + /* 25Hz */ + 25, 0, + /* 50Hz */ + 50, 0, + /* 100Hz */ + 100, 0, + /* 200Hz */ + 200, 0, + /* 1kHz */ + 1000, 0, + /* 2kHz */ + 2000, 0, + /* 4kHz */ + 4000, 0, +}; + +static const int inv_icm42600_accel_odr_conv[] = { + INV_ICM42600_ODR_12_5HZ, + INV_ICM42600_ODR_25HZ, + INV_ICM42600_ODR_50HZ, + INV_ICM42600_ODR_100HZ, + INV_ICM42600_ODR_200HZ, + INV_ICM42600_ODR_1KHZ_LN, + INV_ICM42600_ODR_2KHZ_LN, + INV_ICM42600_ODR_4KHZ_LN, +}; + +static int inv_icm42600_accel_read_odr(struct inv_icm42600_state *st, + int *val, int *val2) +{ + unsigned int odr; + unsigned int i; + + mutex_lock(&st->lock); + odr = st->conf.accel.odr; + mutex_unlock(&st->lock); + + for (i = 0; i < ARRAY_SIZE(inv_icm42600_accel_odr_conv); ++i) { + if (inv_icm42600_accel_odr_conv[i] == odr) + break; + } + if (i >= ARRAY_SIZE(inv_icm42600_accel_odr_conv)) + return -EINVAL; + + *val = inv_icm42600_accel_odr[2 * i]; + *val2 = inv_icm42600_accel_odr[2 * i + 1]; + + return IIO_VAL_INT_PLUS_MICRO; +} + +static int inv_icm42600_accel_write_odr(struct inv_icm42600_state *st, + int val, int val2) +{ + struct device *dev = regmap_get_device(st->map); + unsigned int idx; + struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT; + int ret; + + for (idx = 0; idx < ARRAY_SIZE(inv_icm42600_accel_odr); idx += 2) { + if (val == inv_icm42600_accel_odr[idx] && + val2 == inv_icm42600_accel_odr[idx + 1]) + break; + } + if (idx >= ARRAY_SIZE(inv_icm42600_accel_odr)) + return -EINVAL; + + /* update accel odr */ + pm_runtime_get_sync(dev); + + mutex_lock(&st->lock); + conf.odr = inv_icm42600_accel_odr_conv[idx / 2]; + ret = inv_icm42600_set_accel_conf(st, &conf, NULL); + mutex_unlock(&st->lock); + + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + + return ret; +} + +static int inv_icm42600_accel_read_offset(struct inv_icm42600_state *st, + struct iio_chan_spec const *chan, + int16_t *val) +{ + struct device *dev = regmap_get_device(st->map); + unsigned int reg; + uint8_t data[2]; + int ret; + + if (chan->type != IIO_ACCEL) + return -EINVAL; + + switch (chan->channel2) { + case IIO_MOD_X: + reg = INV_ICM42600_REG_OFFSET_USER4; + break; + case IIO_MOD_Y: + reg = INV_ICM42600_REG_OFFSET_USER6; + break; + case IIO_MOD_Z: + reg = INV_ICM42600_REG_OFFSET_USER7; + break; + default: + return -EINVAL; + } + + pm_runtime_get_sync(dev); + + /* read accel offset data */ + mutex_lock(&st->lock); + ret = regmap_bulk_read(st->map, reg, &data, sizeof(data)); + mutex_unlock(&st->lock); + if (ret) + goto exit; + + switch (chan->channel2) { + case IIO_MOD_X: + *val = (int16_t)(((data[0] & 0xF0) << 4) | data[1]); + break; + case IIO_MOD_Y: + *val = (int16_t)(((data[1] & 0x0F) << 8) | data[0]); + break; + case IIO_MOD_Z: + *val = (int16_t)(((data[0] & 0xF0) << 4) | data[1]); + break; + default: + ret = -EINVAL; + break; + } + +exit: + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + return ret; +} + +static int inv_icm42600_accel_write_offset(struct inv_icm42600_state *st, + struct iio_chan_spec const *chan, + int val) +{ + struct device *dev = regmap_get_device(st->map); + unsigned int reg, regval; + uint8_t data[2]; + int ret; + + if (chan->type != IIO_ACCEL) + return -EINVAL; + + switch (chan->channel2) { + case IIO_MOD_X: + reg = INV_ICM42600_REG_OFFSET_USER4; + break; + case IIO_MOD_Y: + reg = INV_ICM42600_REG_OFFSET_USER6; + break; + case IIO_MOD_Z: + reg = INV_ICM42600_REG_OFFSET_USER7; + break; + default: + return -EINVAL; + } + + /* value is limited to 12 bits signed */ + if (val < -2048 || val > 2047) + return -EINVAL; + + pm_runtime_get_sync(dev); + mutex_lock(&st->lock); + + switch (chan->channel2) { + case IIO_MOD_X: + /* OFFSET_USER4 register is shared */ + ret = regmap_read(st->map, INV_ICM42600_REG_OFFSET_USER4, + ®val); + if (ret) + goto out_unlock; + data[0] = ((val & 0xF00) >> 4) | (regval & 0x0F); + data[1] = val & 0xFF; + break; + case IIO_MOD_Y: + /* OFFSET_USER7 register is shared */ + ret = regmap_read(st->map, INV_ICM42600_REG_OFFSET_USER7, + ®val); + if (ret) + goto out_unlock; + data[0] = val & 0xFF; + data[1] = ((val & 0xF00) >> 8) | (regval & 0xF0); + break; + case IIO_MOD_Z: + /* OFFSET_USER7 register is shared */ + ret = regmap_read(st->map, INV_ICM42600_REG_OFFSET_USER7, + ®val); + if (ret) + goto out_unlock; + data[0] = ((val & 0xF00) >> 4) | (regval & 0x0F); + data[1] = val & 0xFF; + break; + default: + ret = -EINVAL; + goto out_unlock; + } + + ret = regmap_bulk_write(st->map, reg, data, sizeof(data)); + +out_unlock: + mutex_unlock(&st->lock); + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + return ret; +} + +static int inv_icm42600_accel_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); + int16_t data; + int ret; + + if (chan->type != IIO_ACCEL) + return -EINVAL; + + switch (mask) { + case IIO_CHAN_INFO_RAW: + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; + ret = inv_icm42600_accel_read_sensor(st, chan, &data); + iio_device_release_direct_mode(indio_dev); + if (ret) + return ret; + *val = data; + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + return inv_icm42600_accel_read_scale(st, val, val2); + case IIO_CHAN_INFO_SAMP_FREQ: + return inv_icm42600_accel_read_odr(st, val, val2); + case IIO_CHAN_INFO_CALIBBIAS: + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; + ret = inv_icm42600_accel_read_offset(st, chan, &data); + iio_device_release_direct_mode(indio_dev); + if (ret) + return ret; + *val = data; + return IIO_VAL_INT; + default: + return -EINVAL; + } +} + +static int inv_icm42600_accel_read_avail(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + const int **vals, + int *type, int *length, long mask) +{ + if (chan->type != IIO_ACCEL) + return -EINVAL; + + switch (mask) { + case IIO_CHAN_INFO_SCALE: + *vals = inv_icm42600_accel_scale; + *type = IIO_VAL_INT_PLUS_NANO; + *length = ARRAY_SIZE(inv_icm42600_accel_scale); + return IIO_AVAIL_LIST; + case IIO_CHAN_INFO_SAMP_FREQ: + *vals = inv_icm42600_accel_odr; + *type = IIO_VAL_INT_PLUS_MICRO; + *length = ARRAY_SIZE(inv_icm42600_accel_odr); + return IIO_AVAIL_LIST; + default: + return -EINVAL; + } +} + +static int inv_icm42600_accel_write_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int val, int val2, long mask) +{ + struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); + int ret; + + if (chan->type != IIO_ACCEL) + return -EINVAL; + + switch (mask) { + case IIO_CHAN_INFO_SCALE: + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; + ret = inv_icm42600_accel_write_scale(st, val, val2); + iio_device_release_direct_mode(indio_dev); + return ret; + case IIO_CHAN_INFO_SAMP_FREQ: + return inv_icm42600_accel_write_odr(st, val, val2); + case IIO_CHAN_INFO_CALIBBIAS: + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; + ret = inv_icm42600_accel_write_offset(st, chan, val); + iio_device_release_direct_mode(indio_dev); + return ret; + default: + return -EINVAL; + } +} + +static int inv_icm42600_accel_write_raw_get_fmt(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + long mask) +{ + if (chan->type != IIO_ACCEL) + return -EINVAL; + + switch (mask) { + case IIO_CHAN_INFO_SCALE: + return IIO_VAL_INT_PLUS_NANO; + case IIO_CHAN_INFO_SAMP_FREQ: + return IIO_VAL_INT_PLUS_MICRO; + case IIO_CHAN_INFO_CALIBBIAS: + return IIO_VAL_INT; + default: + return -EINVAL; + } +} + +static const struct iio_info inv_icm42600_accel_info = { + .read_raw = inv_icm42600_accel_read_raw, + .read_avail = inv_icm42600_accel_read_avail, + .write_raw = inv_icm42600_accel_write_raw, + .write_raw_get_fmt = inv_icm42600_accel_write_raw_get_fmt, + .debugfs_reg_access = inv_icm42600_debugfs_reg, +}; + +int inv_icm42600_accel_init(struct inv_icm42600_state *st) +{ + struct device *dev = regmap_get_device(st->map); + const char *name; + struct iio_dev *indio_dev; + + name = devm_kasprintf(dev, GFP_KERNEL, "%s-accel", st->name); + if (!name) + return -ENOMEM; + + indio_dev = devm_iio_device_alloc(dev, 0); + if (!indio_dev) + return -ENOMEM; + + iio_device_set_drvdata(indio_dev, st); + indio_dev->dev.parent = dev; + indio_dev->name = name; + indio_dev->info = &inv_icm42600_accel_info; + indio_dev->modes = INDIO_DIRECT_MODE; + indio_dev->channels = inv_icm42600_accel_channels; + indio_dev->num_channels = ARRAY_SIZE(inv_icm42600_accel_channels); + + st->indio_accel = indio_dev; + return devm_iio_device_register(dev, st->indio_accel); +} diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c index 151257652ce6..4e33f263d3ea 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c @@ -508,6 +508,11 @@ int inv_icm42600_core_probe(struct regmap *regmap, int chip, if (ret) return ret; + /* create and init accelerometer iio device */ + ret = inv_icm42600_accel_init(st); + if (ret) + return ret; + /* setup runtime power management */ ret = pm_runtime_set_active(dev); if (ret) From patchwork Thu May 7 14:42:16 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jean-Baptiste Maneyrol X-Patchwork-Id: 11533985 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 011B6139F for ; Thu, 7 May 2020 14:43:29 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D1819208D6 for ; Thu, 7 May 2020 14:43:28 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=invensense.com header.i=@invensense.com header.b="FHX889XK"; dkim=pass (1024-bit key) header.d=invensense.onmicrosoft.com header.i=@invensense.onmicrosoft.com header.b="KTLmrV/w" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727778AbgEGOn0 (ORCPT ); Thu, 7 May 2020 10:43:26 -0400 Received: from mx0b-00328301.pphosted.com ([148.163.141.47]:36142 "EHLO mx0b-00328301.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727032AbgEGOnY (ORCPT ); Thu, 7 May 2020 10:43:24 -0400 Received: from pps.filterd (m0156136.ppops.net [127.0.0.1]) by mx0b-00328301.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 047Eb4lb005942; Thu, 7 May 2020 07:43:19 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=invensense.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : content-type : content-transfer-encoding : mime-version; s=pfpt1; bh=vx8zKfnK39Y2G7jVI/7YNtma6l/Y6g3qWBZ7ad+TqMs=; b=FHX889XKGAn4W99unMe1koCC7N9kJ9nueeUCgxEZpe7o5xUscOixzLPxu4EylLpDiiDn YGprj4979MzabqLbIjcGqMljFLY+D1UrZkQsllwOg/Tkppr6yX8vm6cyegggwMSv1uaT eJ0gZc+7s++dKyKRFkkL2H045mQ7DZv7Oaq+yG4VBvO8RSGqJJJYY6tdzizgciRojC3P ZH5PEIgvGFcpgsWWixE+nE82xC7/cA5VX+SCBkxGAQlsAlRexZ2OZfFQUXVHTNWoUIN7 i+P1mAkAaP/grkwGHSC8/xUNq1EA2KjnQoghe8uEJetHhiaQPsaErN9OzHtwk469A6ZK aQ== Received: from nam12-bn8-obe.outbound.protection.outlook.com (mail-bn8nam12lp2173.outbound.protection.outlook.com [104.47.55.173]) by mx0b-00328301.pphosted.com with ESMTP id 30s4tnatwr-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 07 May 2020 07:43:19 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=TpyROuIoTrJbQLwAGkbY8p0KNFkLA1hGsnyMWYr135Z56YeNOWbHQnSmzPyAV217HwTweFGRrIiqTid8jDogWJUV2DjQXuRCDVmakBtzBOw1kgndDVDY21B3HbXqly5iGaAjz0fbXEkycIQMkpYrCVZiup9ndi+HwczP/49RN++eAjAAAPuJpaAIne1WaJYBTG6CQfec6+R5S+tB9AHuOil1hSw3/Lk36JSRTXF18tUlyHL9tejn4S1x4FthyW+JinF9RqsfJg2wN1pyRVxD9OdqGDI2wG8T6loChmkyQu7aye2jlsh1CKlhoOAXE5GmvOEDt9/D1nbPccadNZ3p5A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=vx8zKfnK39Y2G7jVI/7YNtma6l/Y6g3qWBZ7ad+TqMs=; b=hP2wsvLd31OthoCdJAg/3cTPc4JKbndwMkpCKIuVJt3xAeR2B6Ia+fDlsUY28P5o2vVxN85SXs1FHQz7RMDBpJcfC94cUrEXWSo3M+5UWw8iT8aPWT/BSMVvVnsVJUziSZTmef7E/ECWr6rp7l/v02ZvbazQmsDTfM9hSanFDJbn2y8ufWNTrPCT0lMdG4amleBmfvqFehK7FymaFml2SAUFHSpGuk3u6ut8zMQn9rK2e7BL03/lSDMUoPLLOnB/EthnymUHzoeexuyixxKNGRZsnethHd8Sw6JaDDMvjJVCxcvpSo0u1hgyIAGe1MDjSG+GjNey2ybg2r6M6tpzkw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=invensense.com; dmarc=pass action=none header.from=invensense.com; dkim=pass header.d=invensense.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=invensense.onmicrosoft.com; s=selector2-invensense-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=vx8zKfnK39Y2G7jVI/7YNtma6l/Y6g3qWBZ7ad+TqMs=; b=KTLmrV/wFQxiGXKoSTQViPw1evhYBVOFyDonX7NF6YkCOO6IOjNVccA0BrOCSTPuo5e4ydj83FNQc/2Q1RUxZiGlnLSha7YSZ64m2u2u1LkuqfV3M7HD9rWpvQ6O1+hjaZGUL3hUHnNgFJBhehuDMVqPstGBzAb80O21As6QLfw= Authentication-Results: kernel.org; dkim=none (message not signed) header.d=none;kernel.org; dmarc=none action=none header.from=invensense.com; Received: from MN2PR12MB4422.namprd12.prod.outlook.com (2603:10b6:208:265::9) by MN2PR12MB4269.namprd12.prod.outlook.com (2603:10b6:208:1d4::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2979.28; Thu, 7 May 2020 14:43:18 +0000 Received: from MN2PR12MB4422.namprd12.prod.outlook.com ([fe80::7471:da8b:8ca1:6af0]) by MN2PR12MB4422.namprd12.prod.outlook.com ([fe80::7471:da8b:8ca1:6af0%4]) with mapi id 15.20.2979.028; Thu, 7 May 2020 14:43:18 +0000 From: Jean-Baptiste Maneyrol To: jic23@kernel.org, robh+dt@kernel.org, robh@kernel.org, mchehab+huawei@kernel.org, davem@davemloft.net, gregkh@linuxfoundation.org Cc: linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Jean-Baptiste Maneyrol Subject: [PATCH 06/12] iio: imu: inv_icm42600: add temperature sensor support Date: Thu, 7 May 2020 16:42:16 +0200 Message-Id: <20200507144222.20989-7-jmaneyrol@invensense.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200507144222.20989-1-jmaneyrol@invensense.com> References: <20200507144222.20989-1-jmaneyrol@invensense.com> X-ClientProxiedBy: LNXP265CA0048.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:5c::36) To MN2PR12MB4422.namprd12.prod.outlook.com (2603:10b6:208:265::9) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from frgnb-buildozer.invcorp.invensense.com (77.157.193.39) by LNXP265CA0048.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:5c::36) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2979.26 via Frontend Transport; Thu, 7 May 2020 14:43:16 +0000 X-Mailer: git-send-email 2.17.1 X-Originating-IP: [77.157.193.39] X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: f879c516-b3b5-46a8-65e1-08d7f294fb35 X-MS-TrafficTypeDiagnostic: MN2PR12MB4269: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:8882; X-Forefront-PRVS: 03965EFC76 X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: c6giz5YXjBMB64YoaTGFcu668cm/l/HOzDVGXnEct+u7NR4Ip9vhkJF10W4C9p2ImCjo7NoaPAQub3ipOwQXkz67wDUtI7ZuY+YoBASiT4wPq3X2QOM5hlC/5UK7sTJ7uem7ewdINAKQsTmgczf4HCj50OkCLQdr1c7Sv3VASQPmhKkUPcJZLLNf0x0Ex4nH9Y7PvdEP4uf/+OeAlkLTBK92Q+TM+JW/Zyj72+d3ngcougJU9+YggYJWGUTfxJNf+5x+AZqB1sXIcGX3nze+ccoIdInzSkFLqNB7HLKuZX1zRDHqEtAVLgSVCnZUTyGC23TQ/NB8r8DcRrdiZnPS1DifAZCv9eabegiY2KXzfkBDqtyzFyXv1b3hIWjsZvU3GmyhVZGJgWZCTDp1C0BiSEwwY7On5SYXqCwBsF1jKuzwMUnu0LVGycMZA65Crto9ssmUCVJLA7NlhhWic58WybWJP5HHI8n/H+H9coB5hdFyYDAiKOGDVsi/jrLO/GoJNjogdeO1wq7G9+XW5gj+1g== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:MN2PR12MB4422.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFTY:;SFS:(346002)(396003)(136003)(366004)(39850400004)(376002)(33430700001)(186003)(6486002)(478600001)(16526019)(5660300002)(4326008)(33440700001)(66556008)(8676002)(1076003)(36756003)(316002)(66946007)(66476007)(52116002)(8936002)(86362001)(2616005)(83280400001)(956004)(83320400001)(83290400001)(83310400001)(26005)(2906002)(7696005)(83300400001)(107886003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData: +RNptZ1QAUG6MsNLzuspjbmysinzHmqbFANYgxak4KDPCSwRVsKuLM1L1eBihByY4Hr7p1DxVDBrfy4aCHqeNrlxHmWVC4DnmDa0YO5uJbYpp2J8WOF21TifOpJjZLRTj0hhRwA3Wrdky6d+OVpvn2QEZZrbjgJ6xHATA99/MOMajgi2ajKNcNIRiJvWKOAcT2JjnQqHcJwdteV3CWTzgvMsgf72xekmEtqkWYnWYp2JDJPFm46ZXbZ2aY9yW0fYRKgaj9lU+AZQIBTgpOVetAOwQt+DvVGkznZEWW3UeYnp58VrA50v2H+eK/SOzqNxyPLUvYMmQZf5u4qz0uOEchWk/lw2n9vfZ56NkusgFslXIlFZR0BZUnxhRVge0yMV0QM1QGBCbdEWSZr2/ecveGuaisXob3C3i8ZuF2dyQVcFLbsyRWsIEOzy4GNSpM/k35PF+0KaVLQjAQPhif7dr8O4Jmt938t23Qconxt6SDZHCkPl8kcByA4jA71SUD0JCbRIE+VtQDiImyTliNmr8ybwIb0OBcMsy/ecMZd2OKNZzpz4huInWm2WcL/7Naxtjp7fAZQof+YA8slgx8G8V0OhpvTKytp89EFP43oFFZU6FXdB5+sSVibumdH9DJ+wqQ9gQYomrQGYwmDrp6ux1NPc3jXYtZwor6uVN0WQqeF5unoIBi/+l2dqy9nmiG9WLfnUsCtsiqgqZGZ30axqWSztM8ScqY9gecCUsIMl7bVlJ6MziRPPXILahohh2qEToGbiTRhebXluwFgtu6Lq2aTcM9XXQouVb3RS5jej3MY= X-OriginatorOrg: invensense.com X-MS-Exchange-CrossTenant-Network-Message-Id: f879c516-b3b5-46a8-65e1-08d7f294fb35 X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 May 2020 14:43:18.2146 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 462b3b3b-e42b-47ea-801a-f1581aac892d X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: FQg9oGEU9Vt2358yxZdsQac2eDHFSbZWCv8Y0b/KgFpv2BjAUJErHaccZtZLy3BdJoOOuZPzY7dgi/P+6QeImEC2HBfCnsjo7a+31p7452E= X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR12MB4269 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.216,18.0.676 definitions=2020-05-07_09:2020-05-07,2020-05-07 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 adultscore=0 priorityscore=1501 spamscore=0 mlxlogscore=999 impostorscore=0 suspectscore=0 phishscore=0 malwarescore=0 lowpriorityscore=0 bulkscore=0 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2005070118 Sender: linux-iio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org Add temperature channel in gyroscope and accelerometer devices. Temperature is available in full 16 bits resolution as a processed channel. Scale and offset attributes are also provided for the low 8 bits resolution raw temperature found in the FIFO. Signed-off-by: Jean-Baptiste Maneyrol --- .../iio/imu/inv_icm42600/inv_icm42600_accel.c | 12 ++- .../iio/imu/inv_icm42600/inv_icm42600_gyro.c | 12 ++- .../iio/imu/inv_icm42600/inv_icm42600_temp.c | 86 +++++++++++++++++++ .../iio/imu/inv_icm42600/inv_icm42600_temp.h | 32 +++++++ 4 files changed, 140 insertions(+), 2 deletions(-) create mode 100644 drivers/iio/imu/inv_icm42600/inv_icm42600_temp.c create mode 100644 drivers/iio/imu/inv_icm42600/inv_icm42600_temp.h diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c index 397e3d0fd42b..74dac5f283d4 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c @@ -12,6 +12,7 @@ #include #include "inv_icm42600.h" +#include "inv_icm42600_temp.h" #define INV_ICM42600_ACCEL_CHAN(_modifier, _index, _ext_info) \ { \ @@ -44,6 +45,7 @@ enum inv_icm42600_accel_scan { INV_ICM42600_ACCEL_SCAN_X, INV_ICM42600_ACCEL_SCAN_Y, INV_ICM42600_ACCEL_SCAN_Z, + INV_ICM42600_ACCEL_SCAN_TEMP, }; static const struct iio_chan_spec_ext_info inv_icm42600_accel_ext_infos[] = { @@ -58,6 +60,7 @@ static const struct iio_chan_spec inv_icm42600_accel_channels[] = { inv_icm42600_accel_ext_infos), INV_ICM42600_ACCEL_CHAN(IIO_MOD_Z, INV_ICM42600_ACCEL_SCAN_Z, inv_icm42600_accel_ext_infos), + INV_ICM42600_TEMP_CHAN(INV_ICM42600_ACCEL_SCAN_TEMP), }; static int inv_icm42600_accel_read_sensor(struct inv_icm42600_state *st, @@ -394,8 +397,15 @@ static int inv_icm42600_accel_read_raw(struct iio_dev *indio_dev, int16_t data; int ret; - if (chan->type != IIO_ACCEL) + switch (chan->type) { + case IIO_ACCEL: + break; + case IIO_TEMP: + return inv_icm42600_temp_read_raw(indio_dev, chan, val, val2, + mask); + default: return -EINVAL; + } switch (mask) { case IIO_CHAN_INFO_RAW: diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c index 74aa2b5fa611..c0164ab2830e 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c @@ -12,6 +12,7 @@ #include #include "inv_icm42600.h" +#include "inv_icm42600_temp.h" #define INV_ICM42600_GYRO_CHAN(_modifier, _index, _ext_info) \ { \ @@ -44,6 +45,7 @@ enum inv_icm42600_gyro_scan { INV_ICM42600_GYRO_SCAN_X, INV_ICM42600_GYRO_SCAN_Y, INV_ICM42600_GYRO_SCAN_Z, + INV_ICM42600_GYRO_SCAN_TEMP, }; static const struct iio_chan_spec_ext_info inv_icm42600_gyro_ext_infos[] = { @@ -58,6 +60,7 @@ static const struct iio_chan_spec inv_icm42600_gyro_channels[] = { inv_icm42600_gyro_ext_infos), INV_ICM42600_GYRO_CHAN(IIO_MOD_Z, INV_ICM42600_GYRO_SCAN_Z, inv_icm42600_gyro_ext_infos), + INV_ICM42600_TEMP_CHAN(INV_ICM42600_GYRO_SCAN_TEMP), }; static int inv_icm42600_gyro_read_sensor(struct inv_icm42600_state *st, @@ -406,8 +409,15 @@ static int inv_icm42600_gyro_read_raw(struct iio_dev *indio_dev, int16_t data; int ret; - if (chan->type != IIO_ANGL_VEL) + switch (chan->type) { + case IIO_ANGL_VEL: + break; + case IIO_TEMP: + return inv_icm42600_temp_read_raw(indio_dev, chan, val, val2, + mask); + default: return -EINVAL; + } switch (mask) { case IIO_CHAN_INFO_RAW: diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_temp.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_temp.c new file mode 100644 index 000000000000..e5407b17c407 --- /dev/null +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_temp.c @@ -0,0 +1,86 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2020 Invensense, Inc. + */ + +#include +#include +#include +#include +#include +#include + +#include "inv_icm42600.h" +#include "inv_icm42600_temp.h" + +static int inv_icm42600_temp_read(struct inv_icm42600_state *st, int32_t *temp) +{ + struct device *dev = regmap_get_device(st->map); + __be16 raw; + int16_t val; + int64_t data; + int ret; + + pm_runtime_get_sync(dev); + mutex_lock(&st->lock); + + ret = inv_icm42600_set_temp_conf(st, true, NULL); + if (ret) + goto exit; + + ret = regmap_bulk_read(st->map, INV_ICM42600_REG_TEMP_DATA, + &raw, sizeof(raw)); + if (ret) + goto exit; + + val = (int16_t)be16_to_cpu(raw); + if (val == INV_ICM42600_DATA_INVALID) { + ret = -EINVAL; + goto exit; + } + /* + * T°C = (val / 132.48) + 25 = ((val * 100) / 13248) + 25 + * Tm°C = (val * 100 * 1000) / 13248 + 25000 + */ + data = (int64_t)(val) * 100LL * 1000LL; + *temp = div_s64(data, 13248) + 25000; +exit: + mutex_unlock(&st->lock); + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + return ret; +} + +int inv_icm42600_temp_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); + int32_t temp; + int ret; + + if (chan->type != IIO_TEMP) + return -EINVAL; + + switch (mask) { + case IIO_CHAN_INFO_PROCESSED: + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; + ret = inv_icm42600_temp_read(st, &temp); + iio_device_release_direct_mode(indio_dev); + if (ret) + return ret; + *val = temp; + return IIO_VAL_INT; + case IIO_CHAN_INFO_SCALE: + *val = 483; + *val2 = 91787; + return IIO_VAL_INT_PLUS_MICRO; + case IIO_CHAN_INFO_OFFSET: + *val = 25000; + return IIO_VAL_INT; + default: + return -EINVAL; + } +} diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_temp.h b/drivers/iio/imu/inv_icm42600/inv_icm42600_temp.h new file mode 100644 index 000000000000..7c0854d38e1e --- /dev/null +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_temp.h @@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2020 Invensense, Inc. + */ + +#ifndef INV_ICM42600_TEMP_H_ +#define INV_ICM42600_TEMP_H_ + +#include +#include + +#define INV_ICM42600_TEMP_CHAN(_index) \ + { \ + .type = IIO_TEMP, \ + .info_mask_separate = \ + BIT(IIO_CHAN_INFO_PROCESSED) | \ + BIT(IIO_CHAN_INFO_OFFSET) | \ + BIT(IIO_CHAN_INFO_SCALE), \ + .scan_index = _index, \ + .scan_type = { \ + .sign = 's', \ + .realbits = 8, \ + .storagebits = 8, \ + .shift = 0, \ + }, \ + } + +int inv_icm42600_temp_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask); + +#endif From patchwork Thu May 7 14:42:17 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Baptiste Maneyrol X-Patchwork-Id: 11533999 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 32808139F for ; Thu, 7 May 2020 14:44:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 1503020575 for ; Thu, 7 May 2020 14:44:03 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=invensense.com header.i=@invensense.com header.b="eienbKpv"; dkim=pass (1024-bit key) header.d=invensense.onmicrosoft.com header.i=@invensense.onmicrosoft.com header.b="FTar6318" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726515AbgEGOn0 (ORCPT ); Thu, 7 May 2020 10:43:26 -0400 Received: from mx0b-00328301.pphosted.com ([148.163.141.47]:38022 "EHLO mx0b-00328301.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727094AbgEGOnZ (ORCPT ); Thu, 7 May 2020 10:43:25 -0400 Received: from pps.filterd (m0156136.ppops.net [127.0.0.1]) by mx0b-00328301.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 047Ebhba006057; Thu, 7 May 2020 07:43:21 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=invensense.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : content-type : mime-version; s=pfpt1; bh=QBf2HMHj1/eKnonntrdhRRALP8UmjKyNHNknL468b6U=; b=eienbKpvciTEuqJXQkvpq+b9N7yM9ZY9yEJ0Caoc8WOyxl805njRCEh3+TWy2pSsNbja C97WyWksoiCA/o04UwJwQ70loql0GN4YQ+7OGtw9idBYp2Xr8zRMdJ/U5LI6+Qb9nAay HxcghQl8c2+MTy2gnVEFhD8q7FMgImKxaDFToNek7eAKaZKlU+F8ZbrIUgK6TTmAdsMu SXLPESET+y6LcnowUm7aTNgTp70bU14Hcw2CmCP4ePTDCofAm+/XUUkwmM8XCFnCe5dK QkUcNPOeIN+2si0WvylptrzQ0Z8iaIXiINd8yu7UTBfZOPj1ePFoeh248rf94FG8bzED 5g== Received: from nam12-bn8-obe.outbound.protection.outlook.com (mail-bn8nam12lp2168.outbound.protection.outlook.com [104.47.55.168]) by mx0b-00328301.pphosted.com with ESMTP id 30s4tnatws-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 07 May 2020 07:43:21 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=fQ9CtZQXwW4BOKLLp9nglkqQrYIXH870kXUMwu/VkClvS51+uqnlq/5JVmrNjUvVGDAw2yx2IarXAx5wBH3KZPATP/J4HeRZYmuXFaIEntuMP2vaHY4gBobpNdfZuaqKJker06Xmz4EppcYaFn1WsbiKUwkuigFbzuS4ar07r2351rKooZ+a58oCV8iY5F/NQIRGkX8NT16tR1FntmmFyn0neqA19W7nzi+5nGQRRS/0MeEo1b45djMOlEvOtUG6y9cOjPTiEV2DuJll+s2jHNoJNky69FDY81JFRdUuQk6v8Hv93UwUWUVP4wBLQ//ST/8SSareroGhYGm2ujF7MQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=QBf2HMHj1/eKnonntrdhRRALP8UmjKyNHNknL468b6U=; b=bBqO35iy4CJzQb+XkrTkk7oPJ0dhin41CmgIKOiGdVYyhWZ+gtPiL1Swq3nHlXDGEAst/2yTNyCw28IewI1J8oZfeLab4nI0Z0G4279ozyjMQZE6Bi733pN8hFu/SqbNNMTib88fP4u7/ETtXxt0mIeELI6GHTB6fr/U2EsfZh0EnNBbxRRwYE++eR6evWsnUYko4w5uSXqe8l7m9AwHp68M8rZIaVjKYZRNAwC6ASP6EgaW6kHfzQR7HEXq7L8b7fNPdfHeS7XSwlcMK0SGK93ajOMDR+w4TCyGfrIt4eEp6MlgJd9iLeDl5qsewcdcKdR7cmUwffxQlHA1kN2KAQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=invensense.com; dmarc=pass action=none header.from=invensense.com; dkim=pass header.d=invensense.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=invensense.onmicrosoft.com; s=selector2-invensense-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=QBf2HMHj1/eKnonntrdhRRALP8UmjKyNHNknL468b6U=; b=FTar6318Ohq3P8Du+/VZyEuvgwepz0y+wK7C+K7etttZqkQs/SosGFN2Tu7JKo7XEhuThkyD3mYkm4/wY9Z9TnAoKVdcaa3TtsvrOo7CilQIGreT1xCn9S9EAMlacMusv4YQcI78zIlpeFUh7IDSfuTAeCgI4gJAgIexzyPW9ug= Authentication-Results: kernel.org; dkim=none (message not signed) header.d=none;kernel.org; dmarc=none action=none header.from=invensense.com; Received: from MN2PR12MB4422.namprd12.prod.outlook.com (2603:10b6:208:265::9) by MN2PR12MB4269.namprd12.prod.outlook.com (2603:10b6:208:1d4::7) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2979.28; Thu, 7 May 2020 14:43:20 +0000 Received: from MN2PR12MB4422.namprd12.prod.outlook.com ([fe80::7471:da8b:8ca1:6af0]) by MN2PR12MB4422.namprd12.prod.outlook.com ([fe80::7471:da8b:8ca1:6af0%4]) with mapi id 15.20.2979.028; Thu, 7 May 2020 14:43:20 +0000 From: Jean-Baptiste Maneyrol To: jic23@kernel.org, robh+dt@kernel.org, robh@kernel.org, mchehab+huawei@kernel.org, davem@davemloft.net, gregkh@linuxfoundation.org Cc: linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Jean-Baptiste Maneyrol Subject: [PATCH 07/12] iio: imu: add Kconfig and Makefile for inv_icm42600 driver Date: Thu, 7 May 2020 16:42:17 +0200 Message-Id: <20200507144222.20989-8-jmaneyrol@invensense.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200507144222.20989-1-jmaneyrol@invensense.com> References: <20200507144222.20989-1-jmaneyrol@invensense.com> X-ClientProxiedBy: LNXP265CA0048.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:5c::36) To MN2PR12MB4422.namprd12.prod.outlook.com (2603:10b6:208:265::9) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from frgnb-buildozer.invcorp.invensense.com (77.157.193.39) by LNXP265CA0048.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:5c::36) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2979.26 via Frontend Transport; Thu, 7 May 2020 14:43:18 +0000 X-Mailer: git-send-email 2.17.1 X-Originating-IP: [77.157.193.39] X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 5d0f0bf9-761e-423b-f51e-08d7f294fc3e X-MS-TrafficTypeDiagnostic: MN2PR12MB4269: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:2803; X-Forefront-PRVS: 03965EFC76 X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: bD23nHtkOTtrqzo5NFeCs8OH0ls7FpBwFZacj2kDRu0gR2Jwbf9vH3UR/5KWfLpKp7aTsiiaPx6uyRYQx9z300b8cOHS55uWLFvdcCap6fReC4VtyNdPyYB/gHgcvADd590T697ppaEOPL5apTW4nYoHyodfjwRFao+gcJMY9fbDHsTUK0AB/LluTXEU0EqSa18FUqd5nrhI7RYD+wIHxyahxilEhLuda0q4vZ1T71ANWLd3pl4iRks8g9sdoyqJa9Fv+FrziN1/cCwgK+3WXkt/rHTSybt4GD2VznO+b+BasU+9EQVEC8pjv637Elio36vblCDxTCw4Xd5HJCYPjyuACmDBIOkhGOzt9bqdI8bz5k7EqR6aFwKMOuA4F9t2LtbHvRc57kGf5CmWKjcVp/ePDKNa/11gyNCt9gHnodjWgsMzOB/BBphNJAEbkWXsuDrIS5T657/diX39QawWZ9/fyAVcjZUFB9Vgc85G1knlIPelm8bz24g9EUDD5hnexSnE8zibzj3SNRcerT5DyA== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:MN2PR12MB4422.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFTY:;SFS:(346002)(396003)(136003)(366004)(39850400004)(376002)(33430700001)(186003)(6486002)(478600001)(16526019)(5660300002)(4326008)(33440700001)(66556008)(8676002)(1076003)(36756003)(316002)(66946007)(66476007)(52116002)(8936002)(86362001)(2616005)(83280400001)(956004)(83320400001)(83290400001)(83310400001)(26005)(2906002)(7696005)(83300400001)(107886003);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData: D0vn3kE7+/KDPKtvHmRzT1hhA/SBJMT10LfFiIJBWggBJUlsCz8XJBBJRrVmDkZvt5fSNC9ZQl9FfaxGi8sJnCK+UO65Bo0TBTBEoLcSFoQmw2LNdhVs0VAlF9gKkpeMO9F8ZHetlf7R2agF6R5/kWImfzbedqeIhvw8GUSrm5Ik+JcGF5GeYdWu0QFPrlNOdqj4BzsCF2KT9NrfzAGVri2UXgWSjSw4FhrB1jOWW9e9Vh5AdBT/HXgDeXUt79tt337zrSylEVbzyXAt4zN52y/uMfjiWBCKIXvF9hjRNs3gvBqHQQZ/+s+p+bHWyDFyij+BVH9UsaWvfpXAlTpNa9RVgbZLawC3FN+493dJhdtfpRQpwrfu/j40AluwlyGCBm3Y8MUp336WpK+GuVTxj8AssYQsxJwgT2ext/tLDUFHY/CxHXfz1y1GoFIIF355sG70ZbyFV/o9kdccf+mkT0vQZsEDNz4KMDT+0UoCj0BUEPDVfzzSH2qFB8v090q6r6tYrljL4BDuG1oYMqT23GTNHDFBWkOWfDyNvtzBmdB3eGlbsF/IKemUuHrM2MSK5lOvB6WwkeqlrPWZro8vKeh1sNpyCKWDvXRjYTe8wu9bvFvuWQK3fZcRpVf81MP8yvDC6k6LuFQoqi6VfcZPc+dI3ZJr3dEHTllwlWB9AAihmw9kySfSL3DR6P6meB5Y5jWRMP2NAowhJg760MqiQNX3I2ORVZJpIra4BiYsjmrA5pzc8eBJgtkpep/6/LEdCSyut3S2o+L4mljYp+aYfjRhofHxNnHZfrnqsG+KNJI= X-OriginatorOrg: invensense.com X-MS-Exchange-CrossTenant-Network-Message-Id: 5d0f0bf9-761e-423b-f51e-08d7f294fc3e X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 May 2020 14:43:19.9650 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 462b3b3b-e42b-47ea-801a-f1581aac892d X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: wqtKoO6NLvBwFQlYMorKkce8Sm7hncJNuIRVmT10RFvuZAMknG7GFGpX4vDNvli5VebnrAslOfTNKOx43bBr36yYS9J9Q8YdHj8k8OH52uY= X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR12MB4269 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.216,18.0.676 definitions=2020-05-07_09:2020-05-07,2020-05-07 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 adultscore=0 priorityscore=1501 spamscore=0 mlxlogscore=964 impostorscore=0 suspectscore=0 phishscore=0 malwarescore=0 lowpriorityscore=0 bulkscore=0 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2005070118 Sender: linux-iio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org Add 3 modules: inv-icm42600, inv-icm42600-i2c, inv-icm42600-spi. Signed-off-by: Jean-Baptiste Maneyrol --- drivers/iio/imu/Kconfig | 1 + drivers/iio/imu/Makefile | 1 + drivers/iio/imu/inv_icm42600/Kconfig | 28 +++++++++++++++++++++++++++ drivers/iio/imu/inv_icm42600/Makefile | 13 +++++++++++++ 4 files changed, 43 insertions(+) create mode 100644 drivers/iio/imu/inv_icm42600/Kconfig create mode 100644 drivers/iio/imu/inv_icm42600/Makefile diff --git a/drivers/iio/imu/Kconfig b/drivers/iio/imu/Kconfig index fc4123d518bc..f02883b08480 100644 --- a/drivers/iio/imu/Kconfig +++ b/drivers/iio/imu/Kconfig @@ -91,6 +91,7 @@ config KMX61 To compile this driver as module, choose M here: the module will be called kmx61. +source "drivers/iio/imu/inv_icm42600/Kconfig" source "drivers/iio/imu/inv_mpu6050/Kconfig" source "drivers/iio/imu/st_lsm6dsx/Kconfig" diff --git a/drivers/iio/imu/Makefile b/drivers/iio/imu/Makefile index 88b2c4555230..13e9ff442b11 100644 --- a/drivers/iio/imu/Makefile +++ b/drivers/iio/imu/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_FXOS8700) += fxos8700_core.o obj-$(CONFIG_FXOS8700_I2C) += fxos8700_i2c.o obj-$(CONFIG_FXOS8700_SPI) += fxos8700_spi.o +obj-y += inv_icm42600/ obj-y += inv_mpu6050/ obj-$(CONFIG_KMX61) += kmx61.o diff --git a/drivers/iio/imu/inv_icm42600/Kconfig b/drivers/iio/imu/inv_icm42600/Kconfig new file mode 100644 index 000000000000..22390a72f0a3 --- /dev/null +++ b/drivers/iio/imu/inv_icm42600/Kconfig @@ -0,0 +1,28 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +config INV_ICM42600 + tristate + +config INV_ICM42600_I2C + tristate "InvenSense ICM-426xx I2C driver" + depends on I2C + select INV_ICM42600 + select REGMAP_I2C + help + This driver supports the InvenSense ICM-426xx motion tracking + devices over I2C. + + This driver can be built as a module. The module will be called + inv-icm42600-i2c. + +config INV_ICM42600_SPI + tristate "InvenSense ICM-426xx SPI driver" + depends on SPI_MASTER + select INV_ICM42600 + select REGMAP_SPI + help + This driver supports the InvenSense ICM-426xx motion tracking + devices over SPI. + + This driver can be built as a module. The module will be called + inv-icm42600-spi. diff --git a/drivers/iio/imu/inv_icm42600/Makefile b/drivers/iio/imu/inv_icm42600/Makefile new file mode 100644 index 000000000000..48965824f00c --- /dev/null +++ b/drivers/iio/imu/inv_icm42600/Makefile @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: GPL-2.0-or-later + +obj-$(CONFIG_INV_ICM42600) += inv-icm42600.o +inv-icm42600-y += inv_icm42600_core.o +inv-icm42600-y += inv_icm42600_gyro.o +inv-icm42600-y += inv_icm42600_accel.o +inv-icm42600-y += inv_icm42600_temp.o + +obj-$(CONFIG_INV_ICM42600_I2C) += inv-icm42600-i2c.o +inv-icm42600-i2c-y += inv_icm42600_i2c.o + +obj-$(CONFIG_INV_ICM42600_SPI) += inv-icm42600-spi.o +inv-icm42600-spi-y += inv_icm42600_spi.o From patchwork Thu May 7 14:42:18 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Baptiste Maneyrol X-Patchwork-Id: 11533997 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C97E0159A for ; Thu, 7 May 2020 14:44:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A01BC20870 for ; Thu, 7 May 2020 14:44:02 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=invensense.com header.i=@invensense.com header.b="L8BCBt/H"; dkim=pass (1024-bit key) header.d=invensense.onmicrosoft.com header.i=@invensense.onmicrosoft.com header.b="LOqqPwc8" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727121AbgEGOnx (ORCPT ); Thu, 7 May 2020 10:43:53 -0400 Received: from mx0b-00328301.pphosted.com ([148.163.141.47]:42036 "EHLO mx0b-00328301.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727772AbgEGOn2 (ORCPT ); Thu, 7 May 2020 10:43:28 -0400 Received: from pps.filterd (m0156136.ppops.net [127.0.0.1]) by mx0b-00328301.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 047EeBqA009573; Thu, 7 May 2020 07:43:24 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=invensense.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : content-type : mime-version; s=pfpt1; bh=ih1YAq1tAzzkOsqsEijrLmTMFDUFg046Zw65ZJPQDcA=; b=L8BCBt/HD5Yi1d2OQEWJVhDSXJvSbYAFpXcDzL2J/PUcuLsEgCXujBRdgAZ43UOd6sDS nwrM1CxLHjfZ0FzSovZqpjwduloZdk/x8Ohep4l+X5Xn3O5J8CG0Ip45qjnDmZlHrP8B FI2sv2pGsEiaQqL9N9WRpkGtYCep5iUVUj6xzIcV8+EvhaJLBH/w29YgeJsRfuEvvWGC KBHFXnU+NBHJ0y8TqNIVZ1FnaBztLTD/6c9oapLXGKos0e1xrLSkjlumKmWQ1gpSROMR h3TWQ2xILJc8ZEcQ6T9gm+C+LaT6FaPbZsr+epwui9ntQEu+cexwyv4jL5bUqIdJIy/X NA== Received: from nam11-dm6-obe.outbound.protection.outlook.com (mail-dm6nam11lp2172.outbound.protection.outlook.com [104.47.57.172]) by mx0b-00328301.pphosted.com with ESMTP id 30s4tnatwt-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 07 May 2020 07:43:24 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=TFg60S44u7LiMyLEFD33o1GrLIgfoWh3s9WuhOv/YFKWAVK/F/77J2a08+yrgP3wQFqu4kQlvW1s+hW0felAboLu071zWaZ5kcsR5mK95pGh/6vHuOwp8mBRDvkVCOoo4xPbUg9ytjvJ2jJQX8VdFSSZte6YobNMJNJYiB3egcuQELpAd8VV/UCbnq7BUDVdOZ5D+Dhc59boIL6iK5WlqkThR+/x4+Yt79l8kDzrwxOtICkyuTL4iQKm1cjSdOBPp3D0adjDIZU0KZR6gcZy8ywIgC3xEK3DuY1+2ANPCQCEDvQ3KsU9tAOtRb6cgtgspVhSlvX5gugV3vA/0B1Iyg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=ih1YAq1tAzzkOsqsEijrLmTMFDUFg046Zw65ZJPQDcA=; b=XPPHI7mTboz6FwTY7rhkE17iclkakNa7sLARLaJRTiuhIDHn6xSBiUruCi9MxvUHSawEOpGRxSz2I6U3eWkEwK48cnF3Dcbfhw9SSqzEDHGmIrrV8DPefNtSPx8AjDqL4+sVSUGjvxCnGuZTMMoKqd1eWdNufxR68d/dYJL6cHBixfBFPwKjeA1ulSpw445Xv9yKNdgt/glXhDWoh5QvcyFW3UPpKPYYhzme3WGIsmyOvLcJfn1fXsvrF5/OQhI6NeKBOfKubQ2dvA2XoGbKVEbszxzxGSgvH2HOQNrFRyfI9TpYF/vPaQ2wWR2Cu7s/T4wTiwncsvRrudzVqbfOeg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=invensense.com; dmarc=pass action=none header.from=invensense.com; dkim=pass header.d=invensense.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=invensense.onmicrosoft.com; s=selector2-invensense-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=ih1YAq1tAzzkOsqsEijrLmTMFDUFg046Zw65ZJPQDcA=; b=LOqqPwc8yPOwmt/v1ogCKh6TgfYot3MZ26UO/eXw0AV7trKKomP/Fqpgy8noo+zS+11kaD2a9lz0soys3kgURiFcWrSLEtBFAbvWxSGzlUSrhXQDi4PeNJqbUpPFmHYlohH5hqLKAaKnfPDU/GF4F28hi3vypDx2thSxLCBGRs4= Authentication-Results: kernel.org; dkim=none (message not signed) header.d=none;kernel.org; dmarc=none action=none header.from=invensense.com; Received: from MN2PR12MB4422.namprd12.prod.outlook.com (2603:10b6:208:265::9) by MN2PR12MB4501.namprd12.prod.outlook.com (2603:10b6:208:269::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2979.27; Thu, 7 May 2020 14:43:21 +0000 Received: from MN2PR12MB4422.namprd12.prod.outlook.com ([fe80::7471:da8b:8ca1:6af0]) by MN2PR12MB4422.namprd12.prod.outlook.com ([fe80::7471:da8b:8ca1:6af0%4]) with mapi id 15.20.2979.028; Thu, 7 May 2020 14:43:21 +0000 From: Jean-Baptiste Maneyrol To: jic23@kernel.org, robh+dt@kernel.org, robh@kernel.org, mchehab+huawei@kernel.org, davem@davemloft.net, gregkh@linuxfoundation.org Cc: linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Jean-Baptiste Maneyrol Subject: [PATCH 08/12] iio: imu: inv_icm42600: add device interrupt trigger Date: Thu, 7 May 2020 16:42:18 +0200 Message-Id: <20200507144222.20989-9-jmaneyrol@invensense.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200507144222.20989-1-jmaneyrol@invensense.com> References: <20200507144222.20989-1-jmaneyrol@invensense.com> X-ClientProxiedBy: LNXP265CA0048.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:5c::36) To MN2PR12MB4422.namprd12.prod.outlook.com (2603:10b6:208:265::9) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from frgnb-buildozer.invcorp.invensense.com (77.157.193.39) by LNXP265CA0048.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:5c::36) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2979.26 via Frontend Transport; Thu, 7 May 2020 14:43:20 +0000 X-Mailer: git-send-email 2.17.1 X-Originating-IP: [77.157.193.39] X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: f005aa3b-a0ca-4e9d-46c4-08d7f294fd49 X-MS-TrafficTypeDiagnostic: MN2PR12MB4501: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:1002; X-Forefront-PRVS: 03965EFC76 X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: HyIiqtPdqg5VLOw2UAm9MoEkgH7uH9FfNpvxzKW62wnuwCR77XgeIi9/+zMN4Y/05QHKQlGCrrAJfo3ehwGJtfTvvlM1Ashx46rNUKwfZ+WdLT3o4kPkzyLTSVegGi89gK9l3wFQyXOTzgtl3i2LJo1FSE/JhBUuhT9LRB0PdJSejLYjgAMNioT6R1fwj0Z4wtizhHnepSPFkRfjpsMJL59XxUnSWyAjq3EtbtWHcLXqXlLPWBogN/b3Frv3+vxIwpqHKJKtLeWxjpqDOYCVGdqY9tyv2j/RrEu/Jv31LqiTEADMd3Ep1fCHkSDDmFW9zfoDZ03AN52ByAbzoKG5mN5hzTmXcHxPXjtFlg8HA7e+4ZRNBVX4c7N+srV6506IVeWrQydG4MNaRgsktbRZmh52kTW4WLmATIg2bgOC0czPOJZAdJukrQHtcPcdc8P6uFsJFOuAujjjjew5YqysLA84DH3JVhfGXcTBidYBlCiMPDSXeoDYaGepQCN3TiW7eSvTWCRi7+qq1dx8HDt2gg== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:MN2PR12MB4422.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFTY:;SFS:(346002)(376002)(136003)(396003)(39850400004)(366004)(33430700001)(30864003)(107886003)(4326008)(8676002)(6486002)(2906002)(316002)(5660300002)(8936002)(1076003)(26005)(7696005)(33440700001)(66946007)(956004)(66476007)(52116002)(2616005)(86362001)(186003)(83320400001)(83280400001)(83310400001)(83290400001)(16526019)(478600001)(36756003)(66556008)(83300400001);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData: pQ2MFB/iJMRP0dyD9fA9JvFXk6r/oO2gC+c7pIMypu6yrWRzvCQY4x3daL5znfrEiS6J284i9DzJmf96dFZ3Txj/VFc1+3XCJp1adLs2eI4sTvSewXqNfpyNssEFxfhyAjw44L61gsyyjdKjhr0fYMi//rhGFKywcEsuGQfaxprys+gb+9sFP94pRpgiOjFmG/b0Ry2lj06i5F2GvWqPg5PsIn8vLHMF8RNcbPPcbCm9FjCjCvgV8nxOmWfhDgfsTugnHRhLYYrlo4DG2RVXYxAPWmRqX6VGRcEq+AqjyxhZ244YBY+XVO7aiLmJynEscNr3xhQ9W+ND8O0nAR+k0fQsZD5ad/FQI25XjeJGgXMYcbAQXBJNitgETBjhqUSaBx9I7omVTl4EfeAdJYVGNjGMQ+MbUAEIm7eLXBvVMECMfwRck8GbpLYGVq8iIbq8U0R//K9mDCvU6Ef120V5o5DPBaS/97D8OHubf10Ykp7mcdyL+ciMbtlWrifdZtTA/SlWHLsan+tCen514vZlJPxlLkCDQAh77jM7U1dP3enS6mzdym++RJBoh1jAvfA7vmjgaWmi/bXHgEHaAV8tD+OjNNaJ5LuEPDIWfslZsR7+yaL+Z7vf73FX477lT5euYCOWKnqrOMZ6GZwRqju+w4jUT28dTQ/G9MH2c3oUrbbGcipuO8fJRaGbGWqAToztyuxYQPrRbw6PemT1zGiMtsu3MuotzaQKabrvftHeBE+ibZgA2mygYjvJVrGrHSYRCqhen0hIbMqhJ3RKgnLMUtf3T5Kr3oZ7xyHfo4WhtSU= X-OriginatorOrg: invensense.com X-MS-Exchange-CrossTenant-Network-Message-Id: f005aa3b-a0ca-4e9d-46c4-08d7f294fd49 X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 May 2020 14:43:21.8945 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 462b3b3b-e42b-47ea-801a-f1581aac892d X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: ta1NYNfFrDoQAUUrOVOhssculqqBJctyfefdTkmXZcmcWoMQjY1Q/qQlSB9LDOGeVjqjEixYQvkp7fyYZsWG2/+YebKSUEwE92VANtp2W5o= X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR12MB4501 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.216,18.0.676 definitions=2020-05-07_09:2020-05-07,2020-05-07 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 adultscore=0 priorityscore=1501 spamscore=0 mlxlogscore=999 impostorscore=0 suspectscore=0 phishscore=0 malwarescore=0 lowpriorityscore=0 bulkscore=0 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2005070118 Sender: linux-iio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org Add INT1 interrupt support and use it as an iio trigger. Support interrupt edge and level, active high or low. Push-pull configuration only. Trigger enables FIFO and will be useful with buffer support. Signed-off-by: Jean-Baptiste Maneyrol --- drivers/iio/imu/inv_icm42600/Kconfig | 1 + drivers/iio/imu/inv_icm42600/Makefile | 1 + drivers/iio/imu/inv_icm42600/inv_icm42600.h | 8 +- .../iio/imu/inv_icm42600/inv_icm42600_core.c | 19 +- .../iio/imu/inv_icm42600/inv_icm42600_i2c.c | 2 +- .../iio/imu/inv_icm42600/inv_icm42600_spi.c | 2 +- .../imu/inv_icm42600/inv_icm42600_trigger.c | 177 ++++++++++++++++++ 7 files changed, 206 insertions(+), 4 deletions(-) create mode 100644 drivers/iio/imu/inv_icm42600/inv_icm42600_trigger.c diff --git a/drivers/iio/imu/inv_icm42600/Kconfig b/drivers/iio/imu/inv_icm42600/Kconfig index 22390a72f0a3..7b3eaeb2aa4a 100644 --- a/drivers/iio/imu/inv_icm42600/Kconfig +++ b/drivers/iio/imu/inv_icm42600/Kconfig @@ -2,6 +2,7 @@ config INV_ICM42600 tristate + select IIO_TRIGGER config INV_ICM42600_I2C tristate "InvenSense ICM-426xx I2C driver" diff --git a/drivers/iio/imu/inv_icm42600/Makefile b/drivers/iio/imu/inv_icm42600/Makefile index 48965824f00c..e1f2aacbe888 100644 --- a/drivers/iio/imu/inv_icm42600/Makefile +++ b/drivers/iio/imu/inv_icm42600/Makefile @@ -5,6 +5,7 @@ inv-icm42600-y += inv_icm42600_core.o inv-icm42600-y += inv_icm42600_gyro.o inv-icm42600-y += inv_icm42600_accel.o inv-icm42600-y += inv_icm42600_temp.o +inv-icm42600-y += inv_icm42600_trigger.o obj-$(CONFIG_INV_ICM42600_I2C) += inv-icm42600-i2c.o inv-icm42600-i2c-y += inv_icm42600_i2c.o diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600.h b/drivers/iio/imu/inv_icm42600/inv_icm42600.h index bc963b3d1800..175c1f67faee 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600.h +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600.h @@ -13,6 +13,7 @@ #include #include #include +#include enum inv_icm42600_chip { INV_CHIP_ICM42600, @@ -122,6 +123,7 @@ struct inv_icm42600_suspended { * @suspended: suspended sensors configuration. * @indio_gyro: gyroscope IIO device. * @indio_accel: accelerometer IIO device. + * @trigger: device internal interrupt trigger */ struct inv_icm42600_state { struct mutex lock; @@ -135,6 +137,7 @@ struct inv_icm42600_state { struct inv_icm42600_suspended suspended; struct iio_dev *indio_gyro; struct iio_dev *indio_accel; + struct iio_trigger *trigger; }; /* Virtual register addresses: @bank on MSB (4 upper bits), @address on LSB */ @@ -370,11 +373,14 @@ int inv_icm42600_set_temp_conf(struct inv_icm42600_state *st, bool enable, int inv_icm42600_debugfs_reg(struct iio_dev *indio_dev, unsigned int reg, unsigned int writeval, unsigned int *readval); -int inv_icm42600_core_probe(struct regmap *regmap, int chip, +int inv_icm42600_core_probe(struct regmap *regmap, int chip, int irq, inv_icm42600_bus_setup bus_setup); int inv_icm42600_gyro_init(struct inv_icm42600_state *st); int inv_icm42600_accel_init(struct inv_icm42600_state *st); +int inv_icm42600_trigger_init(struct inv_icm42600_state *st, int irq, + int irq_type); + #endif diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c index 4e33f263d3ea..1102c54396e3 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c @@ -447,11 +447,13 @@ static void inv_icm42600_disable_pm(void *_data) pm_runtime_disable(dev); } -int inv_icm42600_core_probe(struct regmap *regmap, int chip, +int inv_icm42600_core_probe(struct regmap *regmap, int chip, int irq, inv_icm42600_bus_setup bus_setup) { struct device *dev = regmap_get_device(regmap); struct inv_icm42600_state *st; + struct irq_data *irq_desc; + int irq_type; int ret; BUILD_BUG_ON(ARRAY_SIZE(inv_icm42600_hw) != INV_CHIP_NB); @@ -460,6 +462,16 @@ int inv_icm42600_core_probe(struct regmap *regmap, int chip, return -ENODEV; } + /* get irq data, set trigger falling by default */ + irq_desc = irq_get_irq_data(irq); + if (!irq_desc) { + dev_err(dev, "could not find IRQ %d\n", irq); + return -EINVAL; + } + irq_type = irqd_get_trigger_type(irq_desc); + if (!irq_type) + irq_type = IRQF_TRIGGER_FALLING; + st = devm_kzalloc(dev, sizeof(*st), GFP_KERNEL); if (!st) return -ENOMEM; @@ -503,6 +515,11 @@ int inv_icm42600_core_probe(struct regmap *regmap, int chip, if (ret) return ret; + /* setup interrupt trigger */ + ret = inv_icm42600_trigger_init(st, irq, irq_type); + if (ret) + return ret; + /* create and init gyroscope iio device */ ret = inv_icm42600_gyro_init(st); if (ret) diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_i2c.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_i2c.c index b61f993beacf..b1478ece43f6 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_i2c.c +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_i2c.c @@ -70,7 +70,7 @@ static int inv_icm42600_probe(struct i2c_client *client, if (IS_ERR(regmap)) return PTR_ERR(regmap); - return inv_icm42600_core_probe(regmap, chip, + return inv_icm42600_core_probe(regmap, chip, client->irq, inv_icm42600_i2c_bus_setup); } diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c index 835ced68a3a3..ec784f9e3c2c 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_spi.c @@ -70,7 +70,7 @@ static int inv_icm42600_probe(struct spi_device *spi) if (IS_ERR(regmap)) return PTR_ERR(regmap); - return inv_icm42600_core_probe(regmap, chip, + return inv_icm42600_core_probe(regmap, chip, spi->irq, inv_icm42600_spi_bus_setup); } diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_trigger.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_trigger.c new file mode 100644 index 000000000000..7a5e76305f0b --- /dev/null +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_trigger.c @@ -0,0 +1,177 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2020 Invensense, Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "inv_icm42600.h" + +static irqreturn_t inv_icm42600_trigger_timestamp(int irq, void *_data) +{ + struct inv_icm42600_state *st = _data; + + if (st->indio_gyro) + iio_pollfunc_store_time(irq, st->indio_gyro->pollfunc); + if (st->indio_accel) + iio_pollfunc_store_time(irq, st->indio_accel->pollfunc); + + return IRQ_WAKE_THREAD; +} + +static irqreturn_t inv_icm42600_trigger_int_handler(int irq, void *_data) +{ + struct inv_icm42600_state *st = _data; + struct device *dev = regmap_get_device(st->map); + unsigned int status; + int ret; + + mutex_lock(&st->lock); + + ret = regmap_read(st->map, INV_ICM42600_REG_INT_STATUS, &status); + if (ret) + goto out_unlock; + dev_dbg(dev, "int_status = %#02x\n", status); + + /* FIFO full */ + if (status & INV_ICM42600_INT_STATUS_FIFO_FULL) + dev_warn(dev, "FIFO full data lost!\n"); + + /* FIFO threshold reached */ + if (status & INV_ICM42600_INT_STATUS_FIFO_THS) + iio_trigger_poll_chained(st->trigger); + +out_unlock: + mutex_unlock(&st->lock); + return IRQ_HANDLED; +} + +static int inv_icm42600_trigger_set_state(struct iio_trigger *trig, bool state) +{ + struct inv_icm42600_state *st = iio_trigger_get_drvdata(trig); + unsigned int val; + uint16_t dummy; + int ret; + + mutex_lock(&st->lock); + + /* + * IIO buffers preenable and postdisable are managing power on/off. + * update_scan_mode is setting data FIFO enabled. + */ + if (state) { + /* set FIFO threshold interrupt */ + val = INV_ICM42600_INT_SOURCE0_FIFO_THS_INT1_EN; + ret = regmap_update_bits(st->map, INV_ICM42600_REG_INT_SOURCE0, + val, val); + if (ret) + goto out_unlock; + /* flush FIFO data */ + ret = regmap_write(st->map, INV_ICM42600_REG_SIGNAL_PATH_RESET, + INV_ICM42600_SIGNAL_PATH_RESET_FIFO_FLUSH); + if (ret) + goto out_unlock; + /* set FIFO in streaming mode */ + ret = regmap_write(st->map, INV_ICM42600_REG_FIFO_CONFIG, + INV_ICM42600_FIFO_CONFIG_STREAM); + if (ret) + goto out_unlock; + /* workaround: dummy read of FIFO count */ + ret = regmap_bulk_read(st->map, INV_ICM42600_REG_FIFO_COUNT, + &dummy, sizeof(dummy)); + } else { + /* set FIFO in bypass mode */ + ret = regmap_write(st->map, INV_ICM42600_REG_FIFO_CONFIG, + INV_ICM42600_FIFO_CONFIG_BYPASS); + if (ret) + goto out_unlock; + /* flush FIFO data */ + ret = regmap_write(st->map, INV_ICM42600_REG_SIGNAL_PATH_RESET, + INV_ICM42600_SIGNAL_PATH_RESET_FIFO_FLUSH); + if (ret) + goto out_unlock; + /* disable FIFO threshold interrupt */ + val = INV_ICM42600_INT_SOURCE0_FIFO_THS_INT1_EN; + ret = regmap_update_bits(st->map, INV_ICM42600_REG_INT_SOURCE0, + val, 0); + } + +out_unlock: + mutex_unlock(&st->lock); + return ret; +} + +static int inv_icm42600_trigger_validate(struct iio_trigger *trig, + struct iio_dev *indio_dev) +{ + struct inv_icm42600_state *st = iio_trigger_get_drvdata(trig); + + if (iio_device_get_drvdata(indio_dev) != st) + return -ENODEV; + + return 0; +} + +static const struct iio_trigger_ops inv_icm42600_trigger_ops = { + .set_trigger_state = &inv_icm42600_trigger_set_state, + .validate_device = &inv_icm42600_trigger_validate, +}; + +int inv_icm42600_trigger_init(struct inv_icm42600_state *st, int irq, + int irq_type) +{ + struct device *dev = regmap_get_device(st->map); + unsigned int val; + int ret; + + st->trigger = devm_iio_trigger_alloc(dev, "%s-dev", st->name); + if (!st->trigger) + return -ENOMEM; + + st->trigger->dev.parent = dev; + st->trigger->ops = &inv_icm42600_trigger_ops; + iio_trigger_set_drvdata(st->trigger, st); + + /* configure INT1 with correct mode */ + /* falling or both-edge */ + if (irq_type & IRQF_TRIGGER_FALLING) { + val = INV_ICM42600_INT_CONFIG_INT1_ACTIVE_LOW; + } else if (irq_type == IRQF_TRIGGER_RISING) { + val = INV_ICM42600_INT_CONFIG_INT1_ACTIVE_HIGH; + } else if (irq_type == IRQF_TRIGGER_LOW) { + val = INV_ICM42600_INT_CONFIG_INT1_ACTIVE_LOW | + INV_ICM42600_INT_CONFIG_INT1_LATCHED; + } else if (irq_type == IRQF_TRIGGER_HIGH) { + val = INV_ICM42600_INT_CONFIG_INT1_ACTIVE_LOW | + INV_ICM42600_INT_CONFIG_INT1_LATCHED; + } else { + dev_err(dev, "invalid interrupt type %#x\n", irq_type); + return -EINVAL; + } + val |= INV_ICM42600_INT_CONFIG_INT1_PUSH_PULL; + ret = regmap_write(st->map, INV_ICM42600_REG_INT_CONFIG, val); + if (ret) + return ret; + + /* Deassert async reset for proper INT pin operation (cf datasheet) */ + ret = regmap_update_bits(st->map, INV_ICM42600_REG_INT_CONFIG1, + INV_ICM42600_INT_CONFIG1_ASYNC_RESET, 0); + if (ret) + return ret; + + ret = devm_request_threaded_irq(dev, irq, + inv_icm42600_trigger_timestamp, + inv_icm42600_trigger_int_handler, + irq_type, "inv_icm42600", st); + if (ret) + return ret; + + return devm_iio_trigger_register(dev, st->trigger); +} From patchwork Thu May 7 14:42:19 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Baptiste Maneyrol X-Patchwork-Id: 11533993 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 6C620139F for ; Thu, 7 May 2020 14:43:53 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3D46D20575 for ; Thu, 7 May 2020 14:43:53 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=invensense.com header.i=@invensense.com header.b="F8fnmZoi"; dkim=pass (1024-bit key) header.d=invensense.onmicrosoft.com header.i=@invensense.onmicrosoft.com header.b="bxABE7Pt" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728051AbgEGOns (ORCPT ); Thu, 7 May 2020 10:43:48 -0400 Received: from mx0a-00328301.pphosted.com ([148.163.145.46]:36510 "EHLO mx0a-00328301.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727787AbgEGOna (ORCPT ); Thu, 7 May 2020 10:43:30 -0400 Received: from pps.filterd (m0156134.ppops.net [127.0.0.1]) by mx0a-00328301.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 047Eegd7005564; Thu, 7 May 2020 07:43:25 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=invensense.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : content-type : mime-version; s=pfpt1; bh=E4/9MNCKw3gAe5FzYl5LeaML9JToSDiY4KYE8GjysP8=; b=F8fnmZoij68TX2owuC2+6Y1T1vC2CdbAMQCSnix+/gzeCcUUSVD38A0dZDs5Vb00ofGm 6OYYxYgvsG4vG2b3PLAmfBGMteCp/KiQRb+Tg5KukhjjnUhJCOt1kuRr1KKSS2raLcza Yr631Qwhm/HytZc2ppMIXUM40pBgtFBTikSdVuE/DgvmjPXk7dxV0XLHErmpbbYc1GMA mWU2bbwJDm49IS6fLe73HsVKwCrp9CddGJ45i9zK2k9pKt+Gn7mQSZrzj06+xtZQDUBx IrCF5s/pGep9yOxPqV3aNs9S3JnrKlhTj2rjsOYFSucDIpeIRpS8UZx2SABjDSYdCYaa hA== Received: from nam11-dm6-obe.outbound.protection.outlook.com (mail-dm6nam11lp2170.outbound.protection.outlook.com [104.47.57.170]) by mx0a-00328301.pphosted.com with ESMTP id 30sfwdjs8x-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 07 May 2020 07:43:25 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=YIw7LKylCEh+x0/l3VaNqTU8YZmJaZYdSURV0fZKOjXXO/jSKY+i1YB1DyLRLdB+RWUPNVFR+SSB7Eiffpqn97BuZ/1XHoAnXvlIAO5klnHfzEah6MJpXRPllPMG6eOhCvZ9YyFAlwQUxxc7K4yIB1zpFd73bdXLp1E6jREie0kyDTudO3msItKaNcJIxu4GrBcD+Zem8RN0LEX6S93uJPerK4TbNdpnLuFbANy/Uza2uoR7LkvR+Mm2ryp05+Dcn5gYoazyXXhHLwDaHW4wPSqIdnDrIH0mAlkHseTFlvoP+7/bdmUaR/Vf2Fx6kFqUYFixO5rJWwiRKxvcwW6IRg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=E4/9MNCKw3gAe5FzYl5LeaML9JToSDiY4KYE8GjysP8=; b=X/rNCsVst5bNwm3Y5GFjoiE+uFItmFwnpAeoFgAe0Z78dFQpVXwtBTcEddkjoaYRsMhcWHImx1XRC6UBNmyQC4D8/KuwzL5d2kBbk/kySSpt7+K9GZtfMoq2Ln2lNxON21Boz+NAR2mGg4E1Li5DGEmaJ52VIlhrWtF21AFjbC62+F6Bg6o2LlHOtioHFZqnR/lawll2hGuweZKQjQR/laU/i0l9oLhrZBWrVuJsCFGiDsYsYRx1VrdpRT9/EbohvUJosbSpf2/v9eeLbGzDUM0cA19W+HpJ3YoVbGuCSeVTV4KrQKcqghybXDC6GrtK53PToTD0PExApby8071FYg== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=invensense.com; dmarc=pass action=none header.from=invensense.com; dkim=pass header.d=invensense.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=invensense.onmicrosoft.com; s=selector2-invensense-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=E4/9MNCKw3gAe5FzYl5LeaML9JToSDiY4KYE8GjysP8=; b=bxABE7PtrMiaRVX1IJf0OMoXwVSj0SDiJh5wd5j7ctebwesbQKFIPKFTRB8iAaJAsNAvX8dMA3ecmpSUDeQzmQVtOWX3I5/eqOfpEBj0Ldu86xq+LTbTmSqjx9ZwaPzFaHDyDIZvPr/wdPOoQ4mH0mXj05DmLc5GyHAOJp/qoAA= Authentication-Results: kernel.org; dkim=none (message not signed) header.d=none;kernel.org; dmarc=none action=none header.from=invensense.com; Received: from MN2PR12MB4422.namprd12.prod.outlook.com (2603:10b6:208:265::9) by MN2PR12MB4501.namprd12.prod.outlook.com (2603:10b6:208:269::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2979.27; Thu, 7 May 2020 14:43:23 +0000 Received: from MN2PR12MB4422.namprd12.prod.outlook.com ([fe80::7471:da8b:8ca1:6af0]) by MN2PR12MB4422.namprd12.prod.outlook.com ([fe80::7471:da8b:8ca1:6af0%4]) with mapi id 15.20.2979.028; Thu, 7 May 2020 14:43:23 +0000 From: Jean-Baptiste Maneyrol To: jic23@kernel.org, robh+dt@kernel.org, robh@kernel.org, mchehab+huawei@kernel.org, davem@davemloft.net, gregkh@linuxfoundation.org Cc: linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Jean-Baptiste Maneyrol Subject: [PATCH 09/12] iio: imu: inv_icm42600: add buffer support in iio devices Date: Thu, 7 May 2020 16:42:19 +0200 Message-Id: <20200507144222.20989-10-jmaneyrol@invensense.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200507144222.20989-1-jmaneyrol@invensense.com> References: <20200507144222.20989-1-jmaneyrol@invensense.com> X-ClientProxiedBy: LNXP265CA0048.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:5c::36) To MN2PR12MB4422.namprd12.prod.outlook.com (2603:10b6:208:265::9) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from frgnb-buildozer.invcorp.invensense.com (77.157.193.39) by LNXP265CA0048.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:5c::36) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2979.26 via Frontend Transport; Thu, 7 May 2020 14:43:22 +0000 X-Mailer: git-send-email 2.17.1 X-Originating-IP: [77.157.193.39] X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 9ef73221-038d-431a-c6af-08d7f294fe69 X-MS-TrafficTypeDiagnostic: MN2PR12MB4501: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:86; X-Forefront-PRVS: 03965EFC76 X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: +bLM10Mdg9qA9y0ByvTTBxE+gB6vLRsygmWae2J36iqJXsdDmGqSHivk5rjXAhO4RPVjGJ2PANvcfohZ11IHZHG6OB/pCgMwGBLJUvl4mcFSNU0J8vPaaiWnV8kNnYFWNSTIk2qvy8HDhme6GxTFCGuM+wV961C6m6DB1t9n/qUrJhh6NQtX81c7w4bfAhMSApIpula80h6qrhyRTi5YROP9zmrbigzfqjdgrjAVymBXDDSlRjtS9l8L8dZwI2g2KjcvAatT6lOUOsXI0WIIq2Ejec4VAjqegqYxaCgZtQSkmwltvmmPc+wwBqzF52ioYOHXXg2IEwsyHfx8WWPkxED2D8NBerqsWAEwEUhFBbq1ZpwU00m2iwSd0y6l3GoSWKVcp+S0zgyHZxbcws7jgjCJD//vtCVEGWMG/Vk0dHI5yHCfMarQAc7DAVzn7Gaj7qUlcjs5K5HtHk14nhvwyZGQMKRBaHBn3u8pZPnrdKh/ib+593bG2QuYTnUtudhft2h1meduenkDkfzJfvKUTA== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:MN2PR12MB4422.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFTY:;SFS:(346002)(376002)(136003)(396003)(39850400004)(366004)(33430700001)(30864003)(107886003)(4326008)(8676002)(6486002)(2906002)(316002)(5660300002)(8936002)(1076003)(26005)(7696005)(33440700001)(66946007)(956004)(66476007)(52116002)(2616005)(86362001)(186003)(83320400001)(83280400001)(83310400001)(83290400001)(16526019)(478600001)(6666004)(36756003)(66556008)(83300400001);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData: 3aAiZNoC8vcV3btvAFZ5yGcafNBgPnWZ3IqggzYErDUQSxn0grnouBK4nUtBTfcRM9FLPh+jr28zBirSeRMCaziR70PBH00k/1XvcUaeIWn8ws2Ox7qKqLaUR+uHz3JZX2gwYRR5KS65UyjiC+VZ8stMbiRk+Op9fOnMo5cGhrCS7sMyXDzHKalhajAxfpnE6hFxkDvNSqNtZ3d0U13UNSl/GPTQsebru+0CHrM5FFVadwBi7fUswTHOI4honDDP0meJXob58pFO5TMs1Ig5y+I1lAA6L8uu/+6PMNHF3cM42GK/49o/qyG4TyQ6KqXNcATEiWB5rtCXvG/F4+PkFRLO4yzckMe2/+DeHe40ZbeCiTwRR9CCcZm0aU/z8K0ekz84Poca9yGYcgpnD2fkR9ttS2Dachnap6Uw4FiZGtCRcoiCgSCCIdDpdpmjyqg3Z2Ue+R7G/NxQYiy2eOkE8/zcLKjVV8XF2t/2APeEzaYUDgmvwTcf7q2hYBedME1VEOdVN+ljtCtWyYDgMffjSAn7wKWdjL64AWrhOlQ/HQ0ccwA5t8a0Nf4DkX2/boXNGn+FXFiWjO56MTsD7IGTfC583qwtRAnZUQgWCN7tlPhRF1z3ErgM6P50UMzXe+vJQc0b1qptwd04qRsq6IpbmhRDjH9bZUtVf119ERTDAwJ2+kOeOqWHseRSJGbUtZzCgK5rpSAIH32abJMThUgEElB7JZCnhbt8Tp5FnoGMe3Wz8Xz7ByBZWjzAxMccAidhO1Pwo+vnfrZ8ghzNpIeNsgqmV7vS8P297644pzwIn4Q= X-OriginatorOrg: invensense.com X-MS-Exchange-CrossTenant-Network-Message-Id: 9ef73221-038d-431a-c6af-08d7f294fe69 X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 May 2020 14:43:23.5990 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 462b3b3b-e42b-47ea-801a-f1581aac892d X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: S7McbcaDRQjGx5iqtkJj65mKF2mDhgUfi5FsbhEM0oPk7r7gTpaAxyzn5xcCkIQBqXwkCds25XU0JwZMa1v1TzMbNbUXnBiaY4VE3E6sW+0= X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR12MB4501 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.216,18.0.676 definitions=2020-05-07_09:2020-05-07,2020-05-07 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 adultscore=0 spamscore=0 impostorscore=0 suspectscore=0 mlxscore=0 phishscore=0 bulkscore=0 malwarescore=0 mlxlogscore=999 clxscore=1015 priorityscore=1501 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2005070118 Sender: linux-iio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org Use triggered buffer by parsing FIFO data read in device trigger. Support hwfifo watermark by multiplexing gyro and accel settings. Support hwfifo flush. Simply use interrupt timestamp first. Signed-off-by: Jean-Baptiste Maneyrol --- drivers/iio/imu/inv_icm42600/Kconfig | 3 +- drivers/iio/imu/inv_icm42600/Makefile | 1 + drivers/iio/imu/inv_icm42600/inv_icm42600.h | 8 + .../iio/imu/inv_icm42600/inv_icm42600_accel.c | 183 +++++++++ .../imu/inv_icm42600/inv_icm42600_buffer.c | 353 ++++++++++++++++++ .../imu/inv_icm42600/inv_icm42600_buffer.h | 162 ++++++++ .../iio/imu/inv_icm42600/inv_icm42600_core.c | 23 ++ .../iio/imu/inv_icm42600/inv_icm42600_gyro.c | 183 +++++++++ .../imu/inv_icm42600/inv_icm42600_trigger.c | 15 +- 9 files changed, 928 insertions(+), 3 deletions(-) create mode 100644 drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c create mode 100644 drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.h diff --git a/drivers/iio/imu/inv_icm42600/Kconfig b/drivers/iio/imu/inv_icm42600/Kconfig index 7b3eaeb2aa4a..8c0969319c49 100644 --- a/drivers/iio/imu/inv_icm42600/Kconfig +++ b/drivers/iio/imu/inv_icm42600/Kconfig @@ -2,7 +2,8 @@ config INV_ICM42600 tristate - select IIO_TRIGGER + select IIO_BUFFER + select IIO_TRIGGERED_BUFFER config INV_ICM42600_I2C tristate "InvenSense ICM-426xx I2C driver" diff --git a/drivers/iio/imu/inv_icm42600/Makefile b/drivers/iio/imu/inv_icm42600/Makefile index e1f2aacbe888..d6732118010c 100644 --- a/drivers/iio/imu/inv_icm42600/Makefile +++ b/drivers/iio/imu/inv_icm42600/Makefile @@ -6,6 +6,7 @@ inv-icm42600-y += inv_icm42600_gyro.o inv-icm42600-y += inv_icm42600_accel.o inv-icm42600-y += inv_icm42600_temp.o inv-icm42600-y += inv_icm42600_trigger.o +inv-icm42600-y += inv_icm42600_buffer.o obj-$(CONFIG_INV_ICM42600_I2C) += inv-icm42600-i2c.o inv-icm42600-i2c-y += inv_icm42600_i2c.o diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600.h b/drivers/iio/imu/inv_icm42600/inv_icm42600.h index 175c1f67faee..947ca4dd245b 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600.h +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600.h @@ -15,6 +15,8 @@ #include #include +#include "inv_icm42600_buffer.h" + enum inv_icm42600_chip { INV_CHIP_ICM42600, INV_CHIP_ICM42602, @@ -124,6 +126,7 @@ struct inv_icm42600_suspended { * @indio_gyro: gyroscope IIO device. * @indio_accel: accelerometer IIO device. * @trigger: device internal interrupt trigger + * @fifo: FIFO management structure. */ struct inv_icm42600_state { struct mutex lock; @@ -138,6 +141,7 @@ struct inv_icm42600_state { struct iio_dev *indio_gyro; struct iio_dev *indio_accel; struct iio_trigger *trigger; + struct inv_icm42600_fifo fifo; }; /* Virtual register addresses: @bank on MSB (4 upper bits), @address on LSB */ @@ -378,8 +382,12 @@ int inv_icm42600_core_probe(struct regmap *regmap, int chip, int irq, int inv_icm42600_gyro_init(struct inv_icm42600_state *st); +int inv_icm42600_gyro_parse_fifo(struct iio_dev *indio_dev, int64_t ts); + int inv_icm42600_accel_init(struct inv_icm42600_state *st); +int inv_icm42600_accel_parse_fifo(struct iio_dev *indio_dev, int64_t ts); + int inv_icm42600_trigger_init(struct inv_icm42600_state *st, int irq, int irq_type); diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c index 74dac5f283d4..4206be54d057 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c @@ -10,9 +10,13 @@ #include #include #include +#include +#include +#include #include "inv_icm42600.h" #include "inv_icm42600_temp.h" +#include "inv_icm42600_buffer.h" #define INV_ICM42600_ACCEL_CHAN(_modifier, _index, _ext_info) \ { \ @@ -46,6 +50,7 @@ enum inv_icm42600_accel_scan { INV_ICM42600_ACCEL_SCAN_Y, INV_ICM42600_ACCEL_SCAN_Z, INV_ICM42600_ACCEL_SCAN_TEMP, + INV_ICM42600_ACCEL_SCAN_TIMESTAMP, }; static const struct iio_chan_spec_ext_info inv_icm42600_accel_ext_infos[] = { @@ -61,8 +66,100 @@ static const struct iio_chan_spec inv_icm42600_accel_channels[] = { INV_ICM42600_ACCEL_CHAN(IIO_MOD_Z, INV_ICM42600_ACCEL_SCAN_Z, inv_icm42600_accel_ext_infos), INV_ICM42600_TEMP_CHAN(INV_ICM42600_ACCEL_SCAN_TEMP), + IIO_CHAN_SOFT_TIMESTAMP(INV_ICM42600_ACCEL_SCAN_TIMESTAMP), }; +/* IIO buffer data */ +struct inv_icm42600_accel_buffer { + struct inv_icm42600_fifo_sensor_data accel; + int8_t temp; + int64_t timestamp; +}; + +#define INV_ICM42600_SCAN_MASK_ACCEL_3AXIS \ + (BIT(INV_ICM42600_ACCEL_SCAN_X) | \ + BIT(INV_ICM42600_ACCEL_SCAN_Y) | \ + BIT(INV_ICM42600_ACCEL_SCAN_Z)) + +#define INV_ICM42600_SCAN_MASK_TEMP BIT(INV_ICM42600_ACCEL_SCAN_TEMP) + +static const unsigned long inv_icm42600_accel_scan_masks[] = { + /* 3-axis accel + temperature */ + INV_ICM42600_SCAN_MASK_ACCEL_3AXIS | INV_ICM42600_SCAN_MASK_TEMP, + 0, +}; + +static irqreturn_t inv_icm42600_accel_handler(int irq, void *_data) +{ + struct iio_poll_func *pf = _data; + struct iio_dev *indio_dev = pf->indio_dev; + struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); + const size_t fifo_nb = st->fifo.nb.total; + int ret; + + /* exit if no sample */ + if (fifo_nb == 0) + goto out; + + ret = inv_icm42600_accel_parse_fifo(indio_dev, pf->timestamp); + if (ret) + dev_err(regmap_get_device(st->map), "accel fifo error %d\n", + ret); + +out: + iio_trigger_notify_done(indio_dev->trig); + return IRQ_HANDLED; +} + +/* enable accelerometer sensor and FIFO write */ +static int inv_icm42600_accel_update_scan_mode(struct iio_dev *indio_dev, + const unsigned long *scan_mask) +{ + struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); + struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT; + unsigned int fifo_en = 0; + unsigned int sleep_temp = 0; + unsigned int sleep_accel = 0; + unsigned int sleep; + int ret; + + mutex_lock(&st->lock); + + if (*scan_mask & INV_ICM42600_SCAN_MASK_TEMP) { + /* enable temp sensor */ + ret = inv_icm42600_set_temp_conf(st, true, &sleep_temp); + if (ret) + goto out_unlock; + fifo_en |= INV_ICM42600_SENSOR_TEMP; + } + + if (*scan_mask & INV_ICM42600_SCAN_MASK_ACCEL_3AXIS) { + /* enable accel sensor */ + conf.mode = INV_ICM42600_SENSOR_MODE_LOW_NOISE; + ret = inv_icm42600_set_accel_conf(st, &conf, &sleep_accel); + if (ret) + goto out_unlock; + fifo_en |= INV_ICM42600_SENSOR_ACCEL; + } + + /* update data FIFO write and FIFO watermark */ + ret = inv_icm42600_buffer_set_fifo_en(st, fifo_en | st->fifo.en); + if (ret) + goto out_unlock; + ret = inv_icm42600_buffer_update_watermark(st); + +out_unlock: + mutex_unlock(&st->lock); + /* sleep maximum required time */ + if (sleep_accel > sleep_temp) + sleep = sleep_accel; + else + sleep = sleep_temp; + if (sleep) + msleep(sleep); + return ret; +} + static int inv_icm42600_accel_read_sensor(struct inv_icm42600_state *st, struct iio_chan_spec const *chan, int16_t *val) @@ -250,6 +347,8 @@ static int inv_icm42600_accel_write_odr(struct inv_icm42600_state *st, mutex_lock(&st->lock); conf.odr = inv_icm42600_accel_odr_conv[idx / 2]; ret = inv_icm42600_set_accel_conf(st, &conf, NULL); + inv_icm42600_buffer_update_fifo_period(st); + inv_icm42600_buffer_update_watermark(st); mutex_unlock(&st->lock); pm_runtime_mark_last_busy(dev); @@ -512,12 +611,51 @@ static int inv_icm42600_accel_write_raw_get_fmt(struct iio_dev *indio_dev, } } +static int inv_icm42600_accel_hwfifo_set_watermark(struct iio_dev *indio_dev, + unsigned int val) +{ + struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); + int ret; + + mutex_lock(&st->lock); + + st->fifo.watermark.accel = val; + ret = inv_icm42600_buffer_update_watermark(st); + + mutex_unlock(&st->lock); + + return ret; +} + +static int inv_icm42600_accel_hwfifo_flush(struct iio_dev *indio_dev, + unsigned int count) +{ + struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); + int ret; + + if (count == 0) + return 0; + + mutex_lock(&st->lock); + + ret = inv_icm42600_buffer_hwfifo_flush(st, count); + if (!ret) + ret = st->fifo.nb.accel; + + mutex_unlock(&st->lock); + + return ret; +} + static const struct iio_info inv_icm42600_accel_info = { .read_raw = inv_icm42600_accel_read_raw, .read_avail = inv_icm42600_accel_read_avail, .write_raw = inv_icm42600_accel_write_raw, .write_raw_get_fmt = inv_icm42600_accel_write_raw_get_fmt, .debugfs_reg_access = inv_icm42600_debugfs_reg, + .update_scan_mode = inv_icm42600_accel_update_scan_mode, + .hwfifo_set_watermark = inv_icm42600_accel_hwfifo_set_watermark, + .hwfifo_flush_to_buffer = inv_icm42600_accel_hwfifo_flush, }; int inv_icm42600_accel_init(struct inv_icm42600_state *st) @@ -525,6 +663,7 @@ int inv_icm42600_accel_init(struct inv_icm42600_state *st) struct device *dev = regmap_get_device(st->map); const char *name; struct iio_dev *indio_dev; + int ret; name = devm_kasprintf(dev, GFP_KERNEL, "%s-accel", st->name); if (!name) @@ -541,7 +680,51 @@ int inv_icm42600_accel_init(struct inv_icm42600_state *st) indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->channels = inv_icm42600_accel_channels; indio_dev->num_channels = ARRAY_SIZE(inv_icm42600_accel_channels); + indio_dev->available_scan_masks = inv_icm42600_accel_scan_masks; + + ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL, + inv_icm42600_accel_handler, + &inv_icm42600_buffer_ops); + if (ret) + return ret; + + indio_dev->trig = iio_trigger_get(st->trigger); st->indio_accel = indio_dev; return devm_iio_device_register(dev, st->indio_accel); } + +int inv_icm42600_accel_parse_fifo(struct iio_dev *indio_dev, int64_t ts) +{ + struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); + const size_t accel_nb = st->fifo.nb.accel; + ssize_t i, size; + const void *accel, *gyro, *temp, *timestamp; + unsigned int odr; + struct inv_icm42600_accel_buffer buffer; + + /* exit if no accel sample */ + if (accel_nb == 0) + return 0; + + /* parse all fifo packets */ + for (i = 0; i < st->fifo.count; i += size) { + size = inv_icm42600_fifo_decode_packet(&st->fifo.data[i], + &accel, &gyro, &temp, ×tamp, &odr); + dev_dbg(regmap_get_device(st->map), "accel packet size = %zd\n", + size); + /* quit if error or FIFO is empty */ + if (size <= 0) + return size; + /* skip packet if no accel data or data is invalid */ + if (accel == NULL || !inv_icm42600_fifo_is_data_valid(accel)) { + dev_dbg(regmap_get_device(st->map), "skip accel data\n"); + continue; + } + memcpy(&buffer.accel, accel, sizeof(buffer.accel)); + memcpy(&buffer.temp, temp, sizeof(buffer.temp)); + iio_push_to_buffers_with_timestamp(indio_dev, &buffer, ts); + } + + return 0; +} diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c new file mode 100644 index 000000000000..b428abdc92ee --- /dev/null +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c @@ -0,0 +1,353 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2020 Invensense, Inc. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "inv_icm42600.h" +#include "inv_icm42600_buffer.h" + +void inv_icm42600_buffer_update_fifo_period(struct inv_icm42600_state *st) +{ + uint32_t period_gyro, period_accel, period; + + if (st->fifo.en & INV_ICM42600_SENSOR_GYRO) + period_gyro = inv_icm42600_odr_to_period(st->conf.gyro.odr); + else + period_gyro = U32_MAX; + + if (st->fifo.en & INV_ICM42600_SENSOR_ACCEL) + period_accel = inv_icm42600_odr_to_period(st->conf.accel.odr); + else + period_accel = U32_MAX; + + if (period_gyro <= period_accel) + period = period_gyro; + else + period = period_accel; + + st->fifo.period = period; +} + +int inv_icm42600_buffer_set_fifo_en(struct inv_icm42600_state *st, + unsigned int fifo_en) +{ + unsigned int mask, val; + int ret; + + /* update only FIFO EN bits */ + mask = INV_ICM42600_FIFO_CONFIG1_TMST_FSYNC_EN | + INV_ICM42600_FIFO_CONFIG1_TEMP_EN | + INV_ICM42600_FIFO_CONFIG1_GYRO_EN | + INV_ICM42600_FIFO_CONFIG1_ACCEL_EN; + + val = 0; + if (fifo_en & INV_ICM42600_SENSOR_GYRO) + val |= INV_ICM42600_FIFO_CONFIG1_GYRO_EN; + if (fifo_en & INV_ICM42600_SENSOR_ACCEL) + val |= INV_ICM42600_FIFO_CONFIG1_ACCEL_EN; + if (fifo_en & INV_ICM42600_SENSOR_TEMP) + val |= INV_ICM42600_FIFO_CONFIG1_TEMP_EN; + + ret = regmap_update_bits(st->map, INV_ICM42600_REG_FIFO_CONFIG1, + mask, val); + if (ret) + return ret; + + st->fifo.en = fifo_en; + inv_icm42600_buffer_update_fifo_period(st); + + return 0; +} + +static size_t inv_icm42600_get_packet_size(unsigned int fifo_en) +{ + size_t packet_size; + + if ((fifo_en & INV_ICM42600_SENSOR_GYRO) && + (fifo_en & INV_ICM42600_SENSOR_ACCEL)) + packet_size = INV_ICM42600_FIFO_2SENSORS_PACKET_SIZE; + else + packet_size = INV_ICM42600_FIFO_1SENSOR_PACKET_SIZE; + + return packet_size; +} + +static unsigned int inv_icm42600_wm_truncate(unsigned int watermark, + size_t packet_size) +{ + size_t wm_size; + unsigned int wm; + + wm_size = watermark * packet_size; + if (wm_size > INV_ICM42600_FIFO_WATERMARK_MAX) + wm_size = INV_ICM42600_FIFO_WATERMARK_MAX; + + wm = wm_size / packet_size; + + return wm; +} + +int inv_icm42600_buffer_update_watermark(struct inv_icm42600_state *st) +{ + size_t packet_size, wm_size; + unsigned int wm_gyro, wm_accel, watermark; + uint32_t period_gyro, period_accel, period; + int64_t latency_gyro, latency_accel, latency; + unsigned int mask, val; + bool restore; + __le16 raw_wm; + int ret; + + packet_size = inv_icm42600_get_packet_size(st->fifo.en); + + /* get minimal latency, depending on sensor watermark and odr */ + wm_gyro = inv_icm42600_wm_truncate(st->fifo.watermark.gyro, + packet_size); + wm_accel = inv_icm42600_wm_truncate(st->fifo.watermark.accel, + packet_size); + period_gyro = inv_icm42600_odr_to_period(st->conf.gyro.odr); + period_accel = inv_icm42600_odr_to_period(st->conf.accel.odr); + latency_gyro = (int64_t)period_gyro * (int64_t)wm_gyro; + latency_accel = (int64_t)period_accel * (int64_t)wm_accel; + if (latency_gyro == 0) { + latency = latency_accel; + watermark = wm_accel; + } else if (latency_accel == 0) { + latency = latency_gyro; + watermark = wm_gyro; + } else { + /* compute the smallest latency that is a multiple of both */ + if (latency_gyro <= latency_accel) { + latency = latency_gyro; + latency -= latency_accel % latency_gyro; + } else { + latency = latency_accel; + latency -= latency_gyro % latency_accel; + } + /* use the shortest period */ + if (period_gyro <= period_accel) + period = period_gyro; + else + period = period_accel; + /* all this works because periods are multiple of each others */ + watermark = div_s64(latency, period); + if (watermark < 1) + watermark = 1; + } + wm_size = watermark * packet_size; + dev_dbg(regmap_get_device(st->map), "watermark: %u (%zu)\n", + watermark, wm_size); + + /* changing FIFO watermark requires to turn off watermark interrupt */ + mask = INV_ICM42600_INT_SOURCE0_FIFO_THS_INT1_EN; + val = 0; + ret = regmap_update_bits_check(st->map, INV_ICM42600_REG_INT_SOURCE0, + mask, val, &restore); + if (ret) + return ret; + + raw_wm = INV_ICM42600_FIFO_WATERMARK_VAL(wm_size); + ret = regmap_bulk_write(st->map, INV_ICM42600_REG_FIFO_WATERMARK, + &raw_wm, sizeof(raw_wm)); + if (ret) + return ret; + + /* restore watermark interrupt */ + if (restore) { + mask = INV_ICM42600_INT_SOURCE0_FIFO_THS_INT1_EN; + val = INV_ICM42600_INT_SOURCE0_FIFO_THS_INT1_EN; + ret = regmap_update_bits(st->map, INV_ICM42600_REG_INT_SOURCE0, + mask, val); + if (ret) + return ret; + } + + return 0; +} + +static int inv_icm42600_buffer_preenable(struct iio_dev *indio_dev) +{ + struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); + struct device *dev = regmap_get_device(st->map); + + pm_runtime_get_sync(dev); + + return 0; +} + +static int inv_icm42600_buffer_postdisable(struct iio_dev *indio_dev) +{ + struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); + struct device *dev = regmap_get_device(st->map); + unsigned int sensor; + unsigned int *watermark; + struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT; + unsigned int sleep = 0; + int ret; + + if (indio_dev == st->indio_gyro) { + sensor = INV_ICM42600_SENSOR_GYRO; + watermark = &st->fifo.watermark.gyro; + } else if (indio_dev == st->indio_accel) { + sensor = INV_ICM42600_SENSOR_ACCEL; + watermark = &st->fifo.watermark.accel; + } else { + return -EINVAL; + } + + mutex_lock(&st->lock); + + ret = inv_icm42600_buffer_set_fifo_en(st, st->fifo.en & ~sensor); + if (ret) + goto out_unlock; + + *watermark = 0; + ret = inv_icm42600_buffer_update_watermark(st); + if (ret) + goto out_unlock; + + conf.mode = INV_ICM42600_SENSOR_MODE_OFF; + if (sensor == INV_ICM42600_SENSOR_GYRO) + ret = inv_icm42600_set_gyro_conf(st, &conf, &sleep); + else + ret = inv_icm42600_set_accel_conf(st, &conf, &sleep); + +out_unlock: + mutex_unlock(&st->lock); + if (sleep) + msleep(sleep); + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + + return ret; +} + +const struct iio_buffer_setup_ops inv_icm42600_buffer_ops = { + .preenable = inv_icm42600_buffer_preenable, + .postenable = iio_triggered_buffer_postenable, + .predisable = iio_triggered_buffer_predisable, + .postdisable = inv_icm42600_buffer_postdisable, +}; + +int inv_icm42600_buffer_fifo_read(struct inv_icm42600_state *st, + unsigned int max) +{ + struct device *dev = regmap_get_device(st->map); + __be16 raw_fifo_count; + size_t max_count; + ssize_t i, size; + const void *accel, *gyro, *temp, *timestamp; + unsigned int odr; + int ret; + + /* reset all samples counters */ + st->fifo.count = 0; + st->fifo.nb.gyro = 0; + st->fifo.nb.accel = 0; + st->fifo.nb.total = 0; + + /* compute maximum FIFO read size */ + if (max == 0) + max_count = sizeof(st->fifo.data); + else + max_count = max * inv_icm42600_get_packet_size(st->fifo.en); + + /* read FIFO count value */ + ret = regmap_bulk_read(st->map, INV_ICM42600_REG_FIFO_COUNT, + &raw_fifo_count, sizeof(raw_fifo_count)); + if (ret) + return ret; + st->fifo.count = be16_to_cpu(raw_fifo_count); + dev_dbg(dev, "FIFO count = %zu\n", st->fifo.count); + + /* check and sanitize FIFO count value */ + if (st->fifo.count == 0) + return 0; + if (st->fifo.count > max_count) + st->fifo.count = max_count; + + /* read all FIFO data in internal buffer */ + ret = regmap_noinc_read(st->map, INV_ICM42600_REG_FIFO_DATA, + st->fifo.data, st->fifo.count); + if (ret) + return ret; + + /* compute number of samples for each sensor */ + for (i = 0; i < st->fifo.count; i += size) { + size = inv_icm42600_fifo_decode_packet(&st->fifo.data[i], + &accel, &gyro, &temp, ×tamp, &odr); + if (size <= 0) + break; + if (gyro != NULL && inv_icm42600_fifo_is_data_valid(gyro)) + st->fifo.nb.gyro++; + if (accel != NULL && inv_icm42600_fifo_is_data_valid(accel)) + st->fifo.nb.accel++; + st->fifo.nb.total++; + } + + return 0; +} + +int inv_icm42600_buffer_hwfifo_flush(struct inv_icm42600_state *st, + unsigned int count) +{ + int64_t ts_gyro, ts_accel; + int ret; + + dev_dbg(regmap_get_device(st->map), "FIFO flush %u\n", count); + + ts_gyro = iio_get_time_ns(st->indio_gyro); + ts_accel = iio_get_time_ns(st->indio_accel); + ret = inv_icm42600_buffer_fifo_read(st, count); + if (ret) + return ret; + + if (st->fifo.nb.total == 0) + return 0; + + ret = inv_icm42600_gyro_parse_fifo(st->indio_gyro, ts_gyro); + if (ret) + return ret; + + return inv_icm42600_accel_parse_fifo(st->indio_accel, ts_accel); +} + +int inv_icm42600_buffer_init(struct inv_icm42600_state *st) +{ + unsigned int mask, val; + int ret; + + /* + * Default FIFO configuration (bits 7 to 5) + * - use invalid value + * - FIFO count in bytes + * - FIFO count in big endian + */ + mask = GENMASK(7, 5); + val = INV_ICM42600_INTF_CONFIG0_FIFO_COUNT_ENDIAN; + ret = regmap_update_bits(st->map, INV_ICM42600_REG_INTF_CONFIG0, + mask, val); + if (ret) + return ret; + + /* + * Enable FIFO partial read and continuous watermark interrupt. + * Disable all FIFO EN bits. + */ + mask = GENMASK(6, 5) | GENMASK(3, 0); + val = INV_ICM42600_FIFO_CONFIG1_RESUME_PARTIAL_RD | + INV_ICM42600_FIFO_CONFIG1_WM_GT_TH; + return regmap_update_bits(st->map, INV_ICM42600_REG_FIFO_CONFIG1, + mask, val); +} diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.h b/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.h new file mode 100644 index 000000000000..74b91c0e664b --- /dev/null +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.h @@ -0,0 +1,162 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2020 Invensense, Inc. + */ + +#ifndef INV_ICM42600_BUFFER_H_ +#define INV_ICM42600_BUFFER_H_ + +#include +#include + +struct inv_icm42600_state; + +#define INV_ICM42600_SENSOR_GYRO BIT(0) +#define INV_ICM42600_SENSOR_ACCEL BIT(1) +#define INV_ICM42600_SENSOR_TEMP BIT(2) + +struct inv_icm42600_fifo { + unsigned int en; + uint32_t period; + struct { + unsigned int gyro; + unsigned int accel; + } watermark; + size_t count; + struct { + size_t gyro; + size_t accel; + size_t total; + } nb; + uint8_t data[2080]; +}; + +/* FIFO header: 1 byte */ +#define INV_ICM42600_FIFO_HEADER_MSG BIT(7) +#define INV_ICM42600_FIFO_HEADER_ACCEL BIT(6) +#define INV_ICM42600_FIFO_HEADER_GYRO BIT(5) +#define INV_ICM42600_FIFO_HEADER_TMST_FSYNC GENMASK(3, 2) +#define INV_ICM42600_FIFO_HEADER_ODR_ACCEL BIT(1) +#define INV_ICM42600_FIFO_HEADER_ODR_GYRO BIT(0) + +/* FIFO data packet */ +struct inv_icm42600_fifo_sensor_data { + __be16 x; + __be16 y; + __be16 z; +} __packed; +#define INV_ICM42600_FIFO_DATA_INVALID -32768 + +struct inv_icm42600_fifo_1sensor_packet { + uint8_t header; + struct inv_icm42600_fifo_sensor_data data; + int8_t temp; +} __packed; +#define INV_ICM42600_FIFO_1SENSOR_PACKET_SIZE 8 + +struct inv_icm42600_fifo_2sensors_packet { + uint8_t header; + struct inv_icm42600_fifo_sensor_data accel; + struct inv_icm42600_fifo_sensor_data gyro; + int8_t temp; + __be16 timestamp; +} __packed; +#define INV_ICM42600_FIFO_2SENSORS_PACKET_SIZE 16 + +static inline int16_t inv_icm42600_fifo_get_sensor_data(__be16 d) +{ + return be16_to_cpu(d); +} + +static inline bool +inv_icm42600_fifo_is_data_valid(const struct inv_icm42600_fifo_sensor_data *s) +{ + int16_t x, y, z; + + x = inv_icm42600_fifo_get_sensor_data(s->x); + y = inv_icm42600_fifo_get_sensor_data(s->y); + z = inv_icm42600_fifo_get_sensor_data(s->z); + + if (x == INV_ICM42600_FIFO_DATA_INVALID && + y == INV_ICM42600_FIFO_DATA_INVALID && + z == INV_ICM42600_FIFO_DATA_INVALID) + return false; + + return true; +} + +static inline ssize_t inv_icm42600_fifo_decode_packet(const void *packet, + const void **accel, const void **gyro, const void **temp, + const void **timestamp, unsigned int *odr) +{ + const struct inv_icm42600_fifo_1sensor_packet *pack1 = packet; + const struct inv_icm42600_fifo_2sensors_packet *pack2 = packet; + uint8_t header = *((const uint8_t *)packet); + + /* FIFO empty */ + if (header & INV_ICM42600_FIFO_HEADER_MSG) { + *accel = NULL; + *gyro = NULL; + *temp = NULL; + *timestamp = NULL; + *odr = 0; + return 0; + } + + /* handle odr flags */ + *odr = 0; + if (header & INV_ICM42600_FIFO_HEADER_ODR_GYRO) + *odr |= INV_ICM42600_SENSOR_GYRO; + if (header & INV_ICM42600_FIFO_HEADER_ODR_ACCEL) + *odr |= INV_ICM42600_SENSOR_ACCEL; + + /* accel + gyro */ + if ((header & INV_ICM42600_FIFO_HEADER_ACCEL) && + (header & INV_ICM42600_FIFO_HEADER_GYRO)) { + *accel = &pack2->accel; + *gyro = &pack2->gyro; + *temp = &pack2->temp; + *timestamp = &pack2->timestamp; + return INV_ICM42600_FIFO_2SENSORS_PACKET_SIZE; + } + + /* accel only */ + if (header & INV_ICM42600_FIFO_HEADER_ACCEL) { + *accel = &pack1->data; + *gyro = NULL; + *temp = &pack1->temp; + *timestamp = NULL; + return INV_ICM42600_FIFO_1SENSOR_PACKET_SIZE; + } + + /* gyro only */ + if (header & INV_ICM42600_FIFO_HEADER_GYRO) { + *accel = NULL; + *gyro = &pack1->data; + *temp = &pack1->temp; + *timestamp = NULL; + return INV_ICM42600_FIFO_1SENSOR_PACKET_SIZE; + } + + /* invalid packet if here */ + return -EINVAL; +} + +extern const struct iio_buffer_setup_ops inv_icm42600_buffer_ops; + +int inv_icm42600_buffer_init(struct inv_icm42600_state *st); + +void inv_icm42600_buffer_update_fifo_period(struct inv_icm42600_state *st); + +int inv_icm42600_buffer_set_fifo_en(struct inv_icm42600_state *st, + unsigned int fifo_en); + +int inv_icm42600_buffer_update_watermark(struct inv_icm42600_state *st); + +int inv_icm42600_buffer_fifo_read(struct inv_icm42600_state *st, + unsigned int max); + +int inv_icm42600_buffer_hwfifo_flush(struct inv_icm42600_state *st, + unsigned int count); + +#endif diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c index 1102c54396e3..689089065ff9 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c @@ -14,6 +14,7 @@ #include #include "inv_icm42600.h" +#include "inv_icm42600_buffer.h" static const struct regmap_range_cfg inv_icm42600_regmap_ranges[] = { { @@ -515,6 +516,11 @@ int inv_icm42600_core_probe(struct regmap *regmap, int chip, int irq, if (ret) return ret; + /* setup FIFO buffer */ + ret = inv_icm42600_buffer_init(st); + if (ret) + return ret; + /* setup interrupt trigger */ ret = inv_icm42600_trigger_init(st, irq, irq_type); if (ret) @@ -559,6 +565,16 @@ static int __maybe_unused inv_icm42600_suspend(struct device *dev) goto out_unlock; } + /* disable FIFO data streaming */ + if (iio_buffer_enabled(st->indio_gyro) || + iio_buffer_enabled(st->indio_accel)) { + /* set FIFO in bypass mode */ + ret = regmap_write(st->map, INV_ICM42600_REG_FIFO_CONFIG, + INV_ICM42600_FIFO_CONFIG_BYPASS); + if (ret) + goto out_unlock; + } + ret = inv_icm42600_set_pwr_mgmt0(st, INV_ICM42600_SENSOR_MODE_OFF, INV_ICM42600_SENSOR_MODE_OFF, false, NULL); @@ -594,6 +610,13 @@ static int __maybe_unused inv_icm42600_resume(struct device *dev) if (ret) goto out_unlock; + /* restore FIFO data streaming */ + if (iio_buffer_enabled(st->indio_gyro) || + iio_buffer_enabled(st->indio_accel)) { + ret = regmap_write(st->map, INV_ICM42600_REG_FIFO_CONFIG, + INV_ICM42600_FIFO_CONFIG_STREAM); + } + out_unlock: mutex_unlock(&st->lock); return ret; diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c index c0164ab2830e..dafb104abc77 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c @@ -10,9 +10,13 @@ #include #include #include +#include +#include +#include #include "inv_icm42600.h" #include "inv_icm42600_temp.h" +#include "inv_icm42600_buffer.h" #define INV_ICM42600_GYRO_CHAN(_modifier, _index, _ext_info) \ { \ @@ -46,6 +50,7 @@ enum inv_icm42600_gyro_scan { INV_ICM42600_GYRO_SCAN_Y, INV_ICM42600_GYRO_SCAN_Z, INV_ICM42600_GYRO_SCAN_TEMP, + INV_ICM42600_GYRO_SCAN_TIMESTAMP, }; static const struct iio_chan_spec_ext_info inv_icm42600_gyro_ext_infos[] = { @@ -61,8 +66,100 @@ static const struct iio_chan_spec inv_icm42600_gyro_channels[] = { INV_ICM42600_GYRO_CHAN(IIO_MOD_Z, INV_ICM42600_GYRO_SCAN_Z, inv_icm42600_gyro_ext_infos), INV_ICM42600_TEMP_CHAN(INV_ICM42600_GYRO_SCAN_TEMP), + IIO_CHAN_SOFT_TIMESTAMP(INV_ICM42600_GYRO_SCAN_TIMESTAMP), }; +/* IIO buffer data */ +struct inv_icm42600_gyro_buffer { + struct inv_icm42600_fifo_sensor_data gyro; + int8_t temp; + int64_t timestamp; +}; + +#define INV_ICM42600_SCAN_MASK_GYRO_3AXIS \ + (BIT(INV_ICM42600_GYRO_SCAN_X) | \ + BIT(INV_ICM42600_GYRO_SCAN_Y) | \ + BIT(INV_ICM42600_GYRO_SCAN_Z)) + +#define INV_ICM42600_SCAN_MASK_TEMP BIT(INV_ICM42600_GYRO_SCAN_TEMP) + +static const unsigned long inv_icm42600_gyro_scan_masks[] = { + /* 3-axis gyro + temperature */ + INV_ICM42600_SCAN_MASK_GYRO_3AXIS | INV_ICM42600_SCAN_MASK_TEMP, + 0, +}; + +static irqreturn_t inv_icm42600_gyro_handler(int irq, void *_data) +{ + struct iio_poll_func *pf = _data; + struct iio_dev *indio_dev = pf->indio_dev; + struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); + const size_t fifo_nb = st->fifo.nb.total; + int ret; + + /* exit if no sample */ + if (fifo_nb == 0) + goto out; + + ret = inv_icm42600_gyro_parse_fifo(indio_dev, pf->timestamp); + if (ret) + dev_err(regmap_get_device(st->map), "gyro fifo error %d\n", + ret); + +out: + iio_trigger_notify_done(indio_dev->trig); + return IRQ_HANDLED; +} + +/* enable gyroscope sensor and FIFO write */ +static int inv_icm42600_gyro_update_scan_mode(struct iio_dev *indio_dev, + const unsigned long *scan_mask) +{ + struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); + struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT; + unsigned int fifo_en = 0; + unsigned int sleep_gyro = 0; + unsigned int sleep_temp = 0; + unsigned int sleep; + int ret; + + mutex_lock(&st->lock); + + if (*scan_mask & INV_ICM42600_SCAN_MASK_TEMP) { + /* enable temp sensor */ + ret = inv_icm42600_set_temp_conf(st, true, &sleep_temp); + if (ret) + goto out_unlock; + fifo_en |= INV_ICM42600_SENSOR_TEMP; + } + + if (*scan_mask & INV_ICM42600_SCAN_MASK_GYRO_3AXIS) { + /* enable gyro sensor */ + conf.mode = INV_ICM42600_SENSOR_MODE_LOW_NOISE; + ret = inv_icm42600_set_gyro_conf(st, &conf, &sleep_gyro); + if (ret) + goto out_unlock; + fifo_en |= INV_ICM42600_SENSOR_GYRO; + } + + /* update data FIFO write and FIFO watermark */ + ret = inv_icm42600_buffer_set_fifo_en(st, fifo_en | st->fifo.en); + if (ret) + goto out_unlock; + ret = inv_icm42600_buffer_update_watermark(st); + +out_unlock: + mutex_unlock(&st->lock); + /* sleep maximum required time */ + if (sleep_gyro > sleep_temp) + sleep = sleep_gyro; + else + sleep = sleep_temp; + if (sleep) + msleep(sleep); + return ret; +} + static int inv_icm42600_gyro_read_sensor(struct inv_icm42600_state *st, struct iio_chan_spec const *chan, int16_t *val) @@ -262,6 +359,8 @@ static int inv_icm42600_gyro_write_odr(struct inv_icm42600_state *st, mutex_lock(&st->lock); conf.odr = inv_icm42600_gyro_odr_conv[idx / 2]; ret = inv_icm42600_set_gyro_conf(st, &conf, NULL); + inv_icm42600_buffer_update_fifo_period(st); + inv_icm42600_buffer_update_watermark(st); mutex_unlock(&st->lock); pm_runtime_mark_last_busy(dev); @@ -524,12 +623,51 @@ static int inv_icm42600_gyro_write_raw_get_fmt(struct iio_dev *indio_dev, } } +static int inv_icm42600_gyro_hwfifo_set_watermark(struct iio_dev *indio_dev, + unsigned int val) +{ + struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); + int ret; + + mutex_lock(&st->lock); + + st->fifo.watermark.gyro = val; + ret = inv_icm42600_buffer_update_watermark(st); + + mutex_unlock(&st->lock); + + return ret; +} + +static int inv_icm42600_gyro_hwfifo_flush(struct iio_dev *indio_dev, + unsigned int count) +{ + struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); + int ret; + + if (count == 0) + return 0; + + mutex_lock(&st->lock); + + ret = inv_icm42600_buffer_hwfifo_flush(st, count); + if (!ret) + ret = st->fifo.nb.gyro; + + mutex_unlock(&st->lock); + + return ret; +} + static const struct iio_info inv_icm42600_gyro_info = { .read_raw = inv_icm42600_gyro_read_raw, .read_avail = inv_icm42600_gyro_read_avail, .write_raw = inv_icm42600_gyro_write_raw, .write_raw_get_fmt = inv_icm42600_gyro_write_raw_get_fmt, .debugfs_reg_access = inv_icm42600_debugfs_reg, + .update_scan_mode = inv_icm42600_gyro_update_scan_mode, + .hwfifo_set_watermark = inv_icm42600_gyro_hwfifo_set_watermark, + .hwfifo_flush_to_buffer = inv_icm42600_gyro_hwfifo_flush, }; int inv_icm42600_gyro_init(struct inv_icm42600_state *st) @@ -537,6 +675,7 @@ int inv_icm42600_gyro_init(struct inv_icm42600_state *st) struct device *dev = regmap_get_device(st->map); const char *name; struct iio_dev *indio_dev; + int ret; name = devm_kasprintf(dev, GFP_KERNEL, "%s-gyro", st->name); if (!name) @@ -553,7 +692,51 @@ int inv_icm42600_gyro_init(struct inv_icm42600_state *st) indio_dev->modes = INDIO_DIRECT_MODE; indio_dev->channels = inv_icm42600_gyro_channels; indio_dev->num_channels = ARRAY_SIZE(inv_icm42600_gyro_channels); + indio_dev->available_scan_masks = inv_icm42600_gyro_scan_masks; + + ret = devm_iio_triggered_buffer_setup(dev, indio_dev, NULL, + inv_icm42600_gyro_handler, + &inv_icm42600_buffer_ops); + if (ret) + return ret; + + indio_dev->trig = iio_trigger_get(st->trigger); st->indio_gyro = indio_dev; return devm_iio_device_register(dev, st->indio_gyro); } + +int inv_icm42600_gyro_parse_fifo(struct iio_dev *indio_dev, int64_t ts) +{ + struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); + const size_t gyro_nb = st->fifo.nb.gyro; + ssize_t i, size; + const void *accel, *gyro, *temp, *timestamp; + unsigned int odr; + struct inv_icm42600_gyro_buffer buffer; + + /* exit if no gyro sample */ + if (gyro_nb == 0) + return 0; + + /* parse all fifo packets */ + for (i = 0; i < st->fifo.count; i += size) { + size = inv_icm42600_fifo_decode_packet(&st->fifo.data[i], + &accel, &gyro, &temp, ×tamp, &odr); + dev_dbg(regmap_get_device(st->map), "gyro packet size = %zd\n", + size); + /* quit if error or FIFO is empty */ + if (size <= 0) + return size; + /* skip packet if no gyro data or data is invalid */ + if (gyro == NULL || !inv_icm42600_fifo_is_data_valid(gyro)) { + dev_dbg(regmap_get_device(st->map), "skip gyro data\n"); + continue; + } + memcpy(&buffer.gyro, gyro, sizeof(buffer.gyro)); + memcpy(&buffer.temp, temp, sizeof(buffer.temp)); + iio_push_to_buffers_with_timestamp(indio_dev, &buffer, ts); + } + + return 0; +} diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_trigger.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_trigger.c index 7a5e76305f0b..5667e0204722 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_trigger.c +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_trigger.c @@ -13,6 +13,7 @@ #include #include "inv_icm42600.h" +#include "inv_icm42600_buffer.h" static irqreturn_t inv_icm42600_trigger_timestamp(int irq, void *_data) { @@ -45,8 +46,18 @@ static irqreturn_t inv_icm42600_trigger_int_handler(int irq, void *_data) dev_warn(dev, "FIFO full data lost!\n"); /* FIFO threshold reached */ - if (status & INV_ICM42600_INT_STATUS_FIFO_THS) - iio_trigger_poll_chained(st->trigger); + if (status & INV_ICM42600_INT_STATUS_FIFO_THS) { + ret = inv_icm42600_buffer_fifo_read(st, 0); + if (ret) + dev_err(dev, "FIFO read error %d\n", ret); + } else { + st->fifo.count = 0; + st->fifo.nb.gyro = 0; + st->fifo.nb.accel = 0; + st->fifo.nb.total = 0; + } + + iio_trigger_poll_chained(st->trigger); out_unlock: mutex_unlock(&st->lock); From patchwork Thu May 7 14:42:20 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Baptiste Maneyrol X-Patchwork-Id: 11533989 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 862E0139F for ; Thu, 7 May 2020 14:43:46 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 57C6B208D6 for ; Thu, 7 May 2020 14:43:46 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=invensense.com header.i=@invensense.com header.b="gfDcJnwF"; dkim=pass (1024-bit key) header.d=invensense.onmicrosoft.com header.i=@invensense.onmicrosoft.com header.b="Zd5Epjjt" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727956AbgEGOnh (ORCPT ); Thu, 7 May 2020 10:43:37 -0400 Received: from mx0a-00328301.pphosted.com ([148.163.145.46]:38060 "EHLO mx0a-00328301.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727797AbgEGOnc (ORCPT ); Thu, 7 May 2020 10:43:32 -0400 Received: from pps.filterd (m0156134.ppops.net [127.0.0.1]) by mx0a-00328301.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 047EfNHW007275; Thu, 7 May 2020 07:43:26 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=invensense.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : content-type : mime-version; s=pfpt1; bh=IOHOvLupLHGO/eT7yFbBKakOdBLzPKmB/GYgdC4b4Zw=; b=gfDcJnwF2AgYp8TJbyQcZ22oRRcsQ2sjcl6mhcmSFkeFtv7QSMZqnf6HKaIL92vplbSB FnwI3wEmAo9qHw8gcNC40uOQu0ShUB53xiH0g53qxjQEgNWyhZ5ykSINC7rNMw/R1jyE /PUnvUMNg9sMwRjFyGJxwUfV8b8jTdpldvR7ZyZLFN85i4P9G8SDQZE2y+JJmrQsd5E1 4/WkUMBkqyUrVT4Qc/wqd0DyczrA9vQ7J2bBYwWfPyayPOMzTfvtdlDteDfOelRfNEiq JxA4f3c4UwtxJrpJfyKxmt2iFVEU/jzVJpFfatgZcnVkfzPxkeNY8Q7rzcoy42wxMnk+ EQ== Received: from nam11-dm6-obe.outbound.protection.outlook.com (mail-dm6nam11lp2175.outbound.protection.outlook.com [104.47.57.175]) by mx0a-00328301.pphosted.com with ESMTP id 30sfwdjs8y-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 07 May 2020 07:43:26 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=lKwMNi4MXWdL2XIkcn8P1ya9auByPbIVPKEjmnYAaTjc4gUaB2PRCmzeuWkOIlHFKkrEZHlFdTurYvc4klYPk7u41sxGY24c0t0BINWVlZqNBJLfQ9ocN6nEPOh9F8POpz3FnqdtDWMt/aZk0FUNwGQbGrAJCpN9iLZfFCHI+85Wbz2HoFD5bDcfJE4vZZouKuEl6M+Vq7b8ewCeCr1luB009Twdvic1r2IRxZqfC85qN+HcmZeyQBZDYwmhApVhFBGv4D7waVj0RgXeA42+yz45pA8mfNbHV+UNju3SIzWxZZ+ziqVV/QjxSv2OOcCng4OpyFjzBpploeR3YbmDvg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=IOHOvLupLHGO/eT7yFbBKakOdBLzPKmB/GYgdC4b4Zw=; b=SSRxeSfcAWdJHy2yhCMkFm1YyR7JXKh8HKhX2hod0/ZH5P7WvlnW9lvHkXFKmmfpbjYE3MDZZsCUvo4li9MJSc6zWFdeH2BdQnTr6JDs9f1xVQNxXfEivldlBToGkOwfjLav+NiJP0RsL+eDqJwSwCdb0UcPBhVqnoG8SlnSn25Zziytw8fYgZGQ5yb0ZMSlZUo7b+cuvxmaY4zusH5oXydHEJUCRYs90GVOMZesUbzLokuEUWL2H3JrGJuhZzOCGmDnfOcXrsqQ4jl9abZxE5u8HVefcpHVQenjQi2orIg43TnkzpMmemQDv97QLTFTfQ05SYaxyTrSNIwDad3Rqw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=invensense.com; dmarc=pass action=none header.from=invensense.com; dkim=pass header.d=invensense.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=invensense.onmicrosoft.com; s=selector2-invensense-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=IOHOvLupLHGO/eT7yFbBKakOdBLzPKmB/GYgdC4b4Zw=; b=Zd5EpjjtJULQTw5qtGrY+nArbuu2WZcDlwlkJ48VY+E0uKfqQArl+5mEYQR02or6v0wEi3F+OzFAXporzHrCRicZorIH3ym/mNod0ASig6BeUOoM0Ybe5RQpit+zft/XGeEw8d0Gi4UDI32eKU+Z4zdNz7+Bt7N0SG2E3aUQye4= Authentication-Results: kernel.org; dkim=none (message not signed) header.d=none;kernel.org; dmarc=none action=none header.from=invensense.com; Received: from MN2PR12MB4422.namprd12.prod.outlook.com (2603:10b6:208:265::9) by MN2PR12MB4501.namprd12.prod.outlook.com (2603:10b6:208:269::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2979.27; Thu, 7 May 2020 14:43:25 +0000 Received: from MN2PR12MB4422.namprd12.prod.outlook.com ([fe80::7471:da8b:8ca1:6af0]) by MN2PR12MB4422.namprd12.prod.outlook.com ([fe80::7471:da8b:8ca1:6af0%4]) with mapi id 15.20.2979.028; Thu, 7 May 2020 14:43:25 +0000 From: Jean-Baptiste Maneyrol To: jic23@kernel.org, robh+dt@kernel.org, robh@kernel.org, mchehab+huawei@kernel.org, davem@davemloft.net, gregkh@linuxfoundation.org Cc: linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Jean-Baptiste Maneyrol Subject: [PATCH 10/12] iio: imu: inv_icm42600: add accurate timestamping Date: Thu, 7 May 2020 16:42:20 +0200 Message-Id: <20200507144222.20989-11-jmaneyrol@invensense.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200507144222.20989-1-jmaneyrol@invensense.com> References: <20200507144222.20989-1-jmaneyrol@invensense.com> X-ClientProxiedBy: LNXP265CA0048.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:5c::36) To MN2PR12MB4422.namprd12.prod.outlook.com (2603:10b6:208:265::9) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from frgnb-buildozer.invcorp.invensense.com (77.157.193.39) by LNXP265CA0048.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:5c::36) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2979.26 via Frontend Transport; Thu, 7 May 2020 14:43:23 +0000 X-Mailer: git-send-email 2.17.1 X-Originating-IP: [77.157.193.39] X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: f4c10859-9b64-46f8-765b-08d7f294ff75 X-MS-TrafficTypeDiagnostic: MN2PR12MB4501: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:199; X-Forefront-PRVS: 03965EFC76 X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: TgGJ/m+ekSLx8Eaw+S/FemnCiBehtKG7iJQxQI7cq+eKmLZvHo6NY8spRi/Xmdbn+VB9UwBLxxmxFbSQq4bvyH4uZ116yz1F7C+hN8v3Mzte8z7gsxebDPuReN7CvwjwocA20xM5edWAa/N0JxoFvEu4sQrxg6qfTuSDbyTnbrF2K2dOM8z94VoZRORW/D4q0DLnqvEJeMpovQXebY+r1T6wAOSu4VI4oucMrlm9WYoax43rI1ga/9NM52KQ+1DwImUIGBdb8E0SdYbhYGhyi0TWylX5aeAW4m7JNlsx5k0ACOLDZdOAAa3NNS2OO3jHTIEIPxpr7oAJiyhZy7K9qYzbqgcokaUpFRfgFPm/mEutI2Fc96TJI2dkFiMmTzU0MdJfDaPAc5ATEI88vBegECtsZzvI9VKDcCgfhPi9y8X9Aypp48/qdvFqoWnl+uqbzhvK3JuAp0r+2gOSihyXTAs/kRPc6X5HJIBoFiwTi60bOXd9lgk4mIKKE6T1OEHiJogdHmaIWb7Li86WKE5hwA== X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:MN2PR12MB4422.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFTY:;SFS:(346002)(376002)(136003)(396003)(39850400004)(366004)(33430700001)(30864003)(107886003)(4326008)(8676002)(6486002)(2906002)(316002)(5660300002)(8936002)(1076003)(26005)(7696005)(33440700001)(66946007)(956004)(66476007)(52116002)(2616005)(86362001)(186003)(83320400001)(83280400001)(83310400001)(83290400001)(16526019)(478600001)(36756003)(66556008)(83300400001);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData: BDaUFnv4JeGQm+HPXzGb5MCysx++BUs9ewy30nlmYLyySMhIgP+jXe/zKz8tWgJ15fCp7pSyh6sCD1CDzLERnjUFtJB+xNAYqfhsnjPKxZKAn1uK0blklwicCL+wMPUXRJboRwQivENISrI3znbw2/p48fOU2fnyXgsZqyKMbc/3u0Kb8BH3m4lHRAhSaINEoFuzozs3OYskHMB87jjCdUi1Np0svuXZo0f2LFvsm4+3bOrdd6IWVs8oorYcJlKjvoNNya3zFjRQC0xOKG1wmvtzZhYbT9ac61+upIPTHCeYCvQM1OgeEK1A3uCNQhKd+sP4XDvoHEBfzsZWnp4/i/tAncDz/CohvH8uJUqt97uB4yeaqXsFoR/AlPgx/6qhBiQFWJfACkqdxwA0YpuYc20OEU2BcnRYEtw8VbI4BSnCWIyvuIxTC4Dh2eqUTgtmxmabCVsP4WeHZz7wk32+veftxVe1bKSmzMbWDW4sxK7/eZ4deOWYaB4xgeee8tKkzrectZiDhqvYAJwAcRVy2jArv8Q4Jd4TVxpTl1Q7BnzzkmzPJl7Txcs7vh72K+t69xtZqUmNzMO2XhluPiVQDaYU96T+1Q5px+r8NfaxN8gP4IkvJxgLEasroFvqWtl4X/K7f8s7l7kSr86sYPSfZvQ59bNGM2ofILzdldEhlOEeG+kdFqcqpeso1KZ3x9CSnzr4lu00qPv4K7Tka63Wbzzs0Ds6J4gfB0uwrnG1KKL/asQ/0XVng93pwWdJ+Tk3GVHf4zTOm5h7owKRIJNHFFP+D5/MiSA+sz/VCGU6FGM= X-OriginatorOrg: invensense.com X-MS-Exchange-CrossTenant-Network-Message-Id: f4c10859-9b64-46f8-765b-08d7f294ff75 X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 May 2020 14:43:25.4051 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 462b3b3b-e42b-47ea-801a-f1581aac892d X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: QkVD0QM6Nlcr/2FV2GzWwdaO8OfsAZ28fj2XzlSgzbYBJTPjoq0Pyv0YJRjM/zr9AP6sa4KsE6YHOuwZ9S5upLs2L8Ud30XzYl2j3hicjTM= X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR12MB4501 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.216,18.0.676 definitions=2020-05-07_09:2020-05-07,2020-05-07 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 adultscore=0 spamscore=0 impostorscore=0 suspectscore=0 mlxscore=0 phishscore=0 bulkscore=0 malwarescore=0 mlxlogscore=999 clxscore=1015 priorityscore=1501 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2005070118 Sender: linux-iio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org Add a timestamp channel with processed value that returns full precision 20 bits timestamp. Add a timestamping mechanism for buffer that provides accurate event timestamps when using watermark. This mechanism estimates device internal clock by comparing FIFO interrupts delta time and corresponding device elapsed time computed by parsing FIFO data. Signed-off-by: Jean-Baptiste Maneyrol --- drivers/iio/imu/inv_icm42600/Makefile | 1 + drivers/iio/imu/inv_icm42600/inv_icm42600.h | 10 +- .../iio/imu/inv_icm42600/inv_icm42600_accel.c | 32 ++- .../imu/inv_icm42600/inv_icm42600_buffer.c | 28 +- .../iio/imu/inv_icm42600/inv_icm42600_core.c | 6 + .../iio/imu/inv_icm42600/inv_icm42600_gyro.c | 32 ++- .../imu/inv_icm42600/inv_icm42600_timestamp.c | 246 ++++++++++++++++++ .../imu/inv_icm42600/inv_icm42600_timestamp.h | 82 ++++++ 8 files changed, 421 insertions(+), 16 deletions(-) create mode 100644 drivers/iio/imu/inv_icm42600/inv_icm42600_timestamp.c create mode 100644 drivers/iio/imu/inv_icm42600/inv_icm42600_timestamp.h diff --git a/drivers/iio/imu/inv_icm42600/Makefile b/drivers/iio/imu/inv_icm42600/Makefile index d6732118010c..1197b545a682 100644 --- a/drivers/iio/imu/inv_icm42600/Makefile +++ b/drivers/iio/imu/inv_icm42600/Makefile @@ -7,6 +7,7 @@ inv-icm42600-y += inv_icm42600_accel.o inv-icm42600-y += inv_icm42600_temp.o inv-icm42600-y += inv_icm42600_trigger.o inv-icm42600-y += inv_icm42600_buffer.o +inv-icm42600-y += inv_icm42600_timestamp.o obj-$(CONFIG_INV_ICM42600_I2C) += inv-icm42600-i2c.o inv-icm42600-i2c-y += inv_icm42600_i2c.o diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600.h b/drivers/iio/imu/inv_icm42600/inv_icm42600.h index 947ca4dd245b..e15eddafe009 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600.h +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600.h @@ -16,6 +16,7 @@ #include #include "inv_icm42600_buffer.h" +#include "inv_icm42600_timestamp.h" enum inv_icm42600_chip { INV_CHIP_ICM42600, @@ -127,6 +128,7 @@ struct inv_icm42600_suspended { * @indio_accel: accelerometer IIO device. * @trigger: device internal interrupt trigger * @fifo: FIFO management structure. + * @timestamp: timestamp management structure. */ struct inv_icm42600_state { struct mutex lock; @@ -142,6 +144,10 @@ struct inv_icm42600_state { struct iio_dev *indio_accel; struct iio_trigger *trigger; struct inv_icm42600_fifo fifo; + struct { + struct inv_icm42600_timestamp gyro; + struct inv_icm42600_timestamp accel; + } timestamp; }; /* Virtual register addresses: @bank on MSB (4 upper bits), @address on LSB */ @@ -382,11 +388,11 @@ int inv_icm42600_core_probe(struct regmap *regmap, int chip, int irq, int inv_icm42600_gyro_init(struct inv_icm42600_state *st); -int inv_icm42600_gyro_parse_fifo(struct iio_dev *indio_dev, int64_t ts); +int inv_icm42600_gyro_parse_fifo(struct iio_dev *indio_dev); int inv_icm42600_accel_init(struct inv_icm42600_state *st); -int inv_icm42600_accel_parse_fifo(struct iio_dev *indio_dev, int64_t ts); +int inv_icm42600_accel_parse_fifo(struct iio_dev *indio_dev); int inv_icm42600_trigger_init(struct inv_icm42600_state *st, int irq, int irq_type); diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c index 4206be54d057..ac140c824c03 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c @@ -17,6 +17,7 @@ #include "inv_icm42600.h" #include "inv_icm42600_temp.h" #include "inv_icm42600_buffer.h" +#include "inv_icm42600_timestamp.h" #define INV_ICM42600_ACCEL_CHAN(_modifier, _index, _ext_info) \ { \ @@ -66,7 +67,7 @@ static const struct iio_chan_spec inv_icm42600_accel_channels[] = { INV_ICM42600_ACCEL_CHAN(IIO_MOD_Z, INV_ICM42600_ACCEL_SCAN_Z, inv_icm42600_accel_ext_infos), INV_ICM42600_TEMP_CHAN(INV_ICM42600_ACCEL_SCAN_TEMP), - IIO_CHAN_SOFT_TIMESTAMP(INV_ICM42600_ACCEL_SCAN_TIMESTAMP), + INV_ICM42600_TIMESTAMP_CHAN(INV_ICM42600_ACCEL_SCAN_TIMESTAMP), }; /* IIO buffer data */ @@ -94,14 +95,20 @@ static irqreturn_t inv_icm42600_accel_handler(int irq, void *_data) struct iio_poll_func *pf = _data; struct iio_dev *indio_dev = pf->indio_dev; struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); + struct inv_icm42600_timestamp *ts = &st->timestamp.accel; const size_t fifo_nb = st->fifo.nb.total; + const size_t accel_nb = st->fifo.nb.accel; + const uint32_t fifo_period = st->fifo.period; int ret; /* exit if no sample */ if (fifo_nb == 0) goto out; - ret = inv_icm42600_accel_parse_fifo(indio_dev, pf->timestamp); + inv_icm42600_timestamp_interrupt(ts, fifo_period, fifo_nb, accel_nb, + pf->timestamp); + + ret = inv_icm42600_accel_parse_fifo(indio_dev); if (ret) dev_err(regmap_get_device(st->map), "accel fifo error %d\n", ret); @@ -143,6 +150,7 @@ static int inv_icm42600_accel_update_scan_mode(struct iio_dev *indio_dev, } /* update data FIFO write and FIFO watermark */ + inv_icm42600_timestamp_apply_odr(&st->timestamp.accel, 0, 0, 0); ret = inv_icm42600_buffer_set_fifo_en(st, fifo_en | st->fifo.en); if (ret) goto out_unlock; @@ -347,6 +355,7 @@ static int inv_icm42600_accel_write_odr(struct inv_icm42600_state *st, mutex_lock(&st->lock); conf.odr = inv_icm42600_accel_odr_conv[idx / 2]; ret = inv_icm42600_set_accel_conf(st, &conf, NULL); + inv_icm42600_timestamp_update_odr(&st->timestamp.accel, conf.odr); inv_icm42600_buffer_update_fifo_period(st); inv_icm42600_buffer_update_watermark(st); mutex_unlock(&st->lock); @@ -502,6 +511,9 @@ static int inv_icm42600_accel_read_raw(struct iio_dev *indio_dev, case IIO_TEMP: return inv_icm42600_temp_read_raw(indio_dev, chan, val, val2, mask); + case IIO_TIMESTAMP: + return inv_icm42600_timestamp_read_raw(indio_dev, chan, val, + val2, mask); default: return -EINVAL; } @@ -694,13 +706,18 @@ int inv_icm42600_accel_init(struct inv_icm42600_state *st) return devm_iio_device_register(dev, st->indio_accel); } -int inv_icm42600_accel_parse_fifo(struct iio_dev *indio_dev, int64_t ts) +int inv_icm42600_accel_parse_fifo(struct iio_dev *indio_dev) { struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); + struct inv_icm42600_timestamp *ts = &st->timestamp.accel; + const size_t fifo_nb = st->fifo.nb.total; const size_t accel_nb = st->fifo.nb.accel; + const uint32_t fifo_period = st->fifo.period; ssize_t i, size; + unsigned int no; const void *accel, *gyro, *temp, *timestamp; unsigned int odr; + int64_t ts_val; struct inv_icm42600_accel_buffer buffer; /* exit if no accel sample */ @@ -708,7 +725,7 @@ int inv_icm42600_accel_parse_fifo(struct iio_dev *indio_dev, int64_t ts) return 0; /* parse all fifo packets */ - for (i = 0; i < st->fifo.count; i += size) { + for (i = 0, no = 0; i < st->fifo.count; i += size, ++no) { size = inv_icm42600_fifo_decode_packet(&st->fifo.data[i], &accel, &gyro, &temp, ×tamp, &odr); dev_dbg(regmap_get_device(st->map), "accel packet size = %zd\n", @@ -721,9 +738,14 @@ int inv_icm42600_accel_parse_fifo(struct iio_dev *indio_dev, int64_t ts) dev_dbg(regmap_get_device(st->map), "skip accel data\n"); continue; } + /* update odr */ + if (odr & INV_ICM42600_SENSOR_ACCEL) + inv_icm42600_timestamp_apply_odr(ts, fifo_period, + fifo_nb, no); memcpy(&buffer.accel, accel, sizeof(buffer.accel)); memcpy(&buffer.temp, temp, sizeof(buffer.temp)); - iio_push_to_buffers_with_timestamp(indio_dev, &buffer, ts); + ts_val = inv_icm42600_timestamp_get(ts); + iio_push_to_buffers_with_timestamp(indio_dev, &buffer, ts_val); } return 0; diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c index b428abdc92ee..bea4c9810da7 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c @@ -15,6 +15,7 @@ #include #include "inv_icm42600.h" +#include "inv_icm42600_timestamp.h" #include "inv_icm42600_buffer.h" void inv_icm42600_buffer_update_fifo_period(struct inv_icm42600_state *st) @@ -194,14 +195,17 @@ static int inv_icm42600_buffer_postdisable(struct iio_dev *indio_dev) unsigned int *watermark; struct inv_icm42600_sensor_conf conf = INV_ICM42600_SENSOR_CONF_INIT; unsigned int sleep = 0; + struct inv_icm42600_timestamp *ts; int ret; if (indio_dev == st->indio_gyro) { sensor = INV_ICM42600_SENSOR_GYRO; watermark = &st->fifo.watermark.gyro; + ts = &st->timestamp.gyro; } else if (indio_dev == st->indio_accel) { sensor = INV_ICM42600_SENSOR_ACCEL; watermark = &st->fifo.watermark.accel; + ts = &st->timestamp.accel; } else { return -EINVAL; } @@ -223,6 +227,8 @@ static int inv_icm42600_buffer_postdisable(struct iio_dev *indio_dev) else ret = inv_icm42600_set_accel_conf(st, &conf, &sleep); + inv_icm42600_timestamp_reset(ts); + out_unlock: mutex_unlock(&st->lock); if (sleep) @@ -316,11 +322,25 @@ int inv_icm42600_buffer_hwfifo_flush(struct inv_icm42600_state *st, if (st->fifo.nb.total == 0) return 0; - ret = inv_icm42600_gyro_parse_fifo(st->indio_gyro, ts_gyro); - if (ret) - return ret; + if (st->fifo.nb.gyro > 0) { + inv_icm42600_timestamp_interrupt(&st->timestamp.gyro, + st->fifo.period, st->fifo.nb.total, + st->fifo.nb.gyro, ts_gyro); + ret = inv_icm42600_gyro_parse_fifo(st->indio_gyro); + if (ret) + return ret; + } - return inv_icm42600_accel_parse_fifo(st->indio_accel, ts_accel); + if (st->fifo.nb.accel > 0) { + inv_icm42600_timestamp_interrupt(&st->timestamp.accel, + st->fifo.period, st->fifo.nb.total, + st->fifo.nb.accel, ts_accel); + ret = inv_icm42600_accel_parse_fifo(st->indio_accel); + if (ret) + return ret; + } + + return ret; } int inv_icm42600_buffer_init(struct inv_icm42600_state *st) diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c index 689089065ff9..563c4348de01 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_core.c @@ -15,6 +15,7 @@ #include "inv_icm42600.h" #include "inv_icm42600_buffer.h" +#include "inv_icm42600_timestamp.h" static const struct regmap_range_cfg inv_icm42600_regmap_ranges[] = { { @@ -516,6 +517,11 @@ int inv_icm42600_core_probe(struct regmap *regmap, int chip, int irq, if (ret) return ret; + /* initialize timestamping */ + ret = inv_icm42600_timestamp_init(st); + if (ret) + return ret; + /* setup FIFO buffer */ ret = inv_icm42600_buffer_init(st); if (ret) diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c index dafb104abc77..1245588170bd 100644 --- a/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c @@ -17,6 +17,7 @@ #include "inv_icm42600.h" #include "inv_icm42600_temp.h" #include "inv_icm42600_buffer.h" +#include "inv_icm42600_timestamp.h" #define INV_ICM42600_GYRO_CHAN(_modifier, _index, _ext_info) \ { \ @@ -66,7 +67,7 @@ static const struct iio_chan_spec inv_icm42600_gyro_channels[] = { INV_ICM42600_GYRO_CHAN(IIO_MOD_Z, INV_ICM42600_GYRO_SCAN_Z, inv_icm42600_gyro_ext_infos), INV_ICM42600_TEMP_CHAN(INV_ICM42600_GYRO_SCAN_TEMP), - IIO_CHAN_SOFT_TIMESTAMP(INV_ICM42600_GYRO_SCAN_TIMESTAMP), + INV_ICM42600_TIMESTAMP_CHAN(INV_ICM42600_GYRO_SCAN_TIMESTAMP), }; /* IIO buffer data */ @@ -94,14 +95,20 @@ static irqreturn_t inv_icm42600_gyro_handler(int irq, void *_data) struct iio_poll_func *pf = _data; struct iio_dev *indio_dev = pf->indio_dev; struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); + struct inv_icm42600_timestamp *ts = &st->timestamp.gyro; const size_t fifo_nb = st->fifo.nb.total; + const size_t gyro_nb = st->fifo.nb.gyro; + const uint32_t fifo_period = st->fifo.period; int ret; /* exit if no sample */ if (fifo_nb == 0) goto out; - ret = inv_icm42600_gyro_parse_fifo(indio_dev, pf->timestamp); + inv_icm42600_timestamp_interrupt(ts, fifo_period, fifo_nb, gyro_nb, + pf->timestamp); + + ret = inv_icm42600_gyro_parse_fifo(indio_dev); if (ret) dev_err(regmap_get_device(st->map), "gyro fifo error %d\n", ret); @@ -143,6 +150,7 @@ static int inv_icm42600_gyro_update_scan_mode(struct iio_dev *indio_dev, } /* update data FIFO write and FIFO watermark */ + inv_icm42600_timestamp_apply_odr(&st->timestamp.gyro, 0, 0, 0); ret = inv_icm42600_buffer_set_fifo_en(st, fifo_en | st->fifo.en); if (ret) goto out_unlock; @@ -359,6 +367,7 @@ static int inv_icm42600_gyro_write_odr(struct inv_icm42600_state *st, mutex_lock(&st->lock); conf.odr = inv_icm42600_gyro_odr_conv[idx / 2]; ret = inv_icm42600_set_gyro_conf(st, &conf, NULL); + inv_icm42600_timestamp_update_odr(&st->timestamp.gyro, conf.odr); inv_icm42600_buffer_update_fifo_period(st); inv_icm42600_buffer_update_watermark(st); mutex_unlock(&st->lock); @@ -514,6 +523,9 @@ static int inv_icm42600_gyro_read_raw(struct iio_dev *indio_dev, case IIO_TEMP: return inv_icm42600_temp_read_raw(indio_dev, chan, val, val2, mask); + case IIO_TIMESTAMP: + return inv_icm42600_timestamp_read_raw(indio_dev, chan, val, + val2, mask); default: return -EINVAL; } @@ -706,13 +718,18 @@ int inv_icm42600_gyro_init(struct inv_icm42600_state *st) return devm_iio_device_register(dev, st->indio_gyro); } -int inv_icm42600_gyro_parse_fifo(struct iio_dev *indio_dev, int64_t ts) +int inv_icm42600_gyro_parse_fifo(struct iio_dev *indio_dev) { struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); + struct inv_icm42600_timestamp *ts = &st->timestamp.gyro; + const size_t fifo_nb = st->fifo.nb.total; const size_t gyro_nb = st->fifo.nb.gyro; + const uint32_t fifo_period = st->fifo.period; ssize_t i, size; + unsigned int no; const void *accel, *gyro, *temp, *timestamp; unsigned int odr; + int64_t ts_val; struct inv_icm42600_gyro_buffer buffer; /* exit if no gyro sample */ @@ -720,7 +737,7 @@ int inv_icm42600_gyro_parse_fifo(struct iio_dev *indio_dev, int64_t ts) return 0; /* parse all fifo packets */ - for (i = 0; i < st->fifo.count; i += size) { + for (i = 0, no = 0; i < st->fifo.count; i += size, ++no) { size = inv_icm42600_fifo_decode_packet(&st->fifo.data[i], &accel, &gyro, &temp, ×tamp, &odr); dev_dbg(regmap_get_device(st->map), "gyro packet size = %zd\n", @@ -733,9 +750,14 @@ int inv_icm42600_gyro_parse_fifo(struct iio_dev *indio_dev, int64_t ts) dev_dbg(regmap_get_device(st->map), "skip gyro data\n"); continue; } + /* update odr */ + if (odr & INV_ICM42600_SENSOR_GYRO) + inv_icm42600_timestamp_apply_odr(ts, fifo_period, + fifo_nb, no); memcpy(&buffer.gyro, gyro, sizeof(buffer.gyro)); memcpy(&buffer.temp, temp, sizeof(buffer.temp)); - iio_push_to_buffers_with_timestamp(indio_dev, &buffer, ts); + ts_val = inv_icm42600_timestamp_get(ts); + iio_push_to_buffers_with_timestamp(indio_dev, &buffer, ts_val); } return 0; diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_timestamp.c b/drivers/iio/imu/inv_icm42600/inv_icm42600_timestamp.c new file mode 100644 index 000000000000..79cf777e2e84 --- /dev/null +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_timestamp.c @@ -0,0 +1,246 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2020 Invensense, Inc. + */ + +#include +#include +#include +#include +#include +#include + +#include "inv_icm42600.h" +#include "inv_icm42600_timestamp.h" + +/* internal chip period is 32kHz, 31250ns */ +#define INV_ICM42600_TIMESTAMP_PERIOD 31250 +/* allow a jitter of +/- 2% */ +#define INV_ICM42600_TIMESTAMP_JITTER 2 +/* compute min and max periods accepted */ +#define INV_ICM42600_TIMESTAMP_MIN_PERIOD(_p) \ + (((_p) * (100 - INV_ICM42600_TIMESTAMP_JITTER)) / 100) +#define INV_ICM42600_TIMESTAMP_MAX_PERIOD(_p) \ + (((_p) * (100 + INV_ICM42600_TIMESTAMP_JITTER)) / 100) + +static void inv_update_acc(struct inv_icm42600_timestamp_acc *acc, uint32_t val) +{ + uint64_t sum = 0; + size_t i; + + acc->values[acc->idx++] = val; + if (acc->idx >= ARRAY_SIZE(acc->values)) + acc->idx = 0; + + for (i = 0; i < ARRAY_SIZE(acc->values); ++i) { + if (acc->values[i] == 0) + break; + sum += acc->values[i]; + } + + acc->val = div_u64(sum, i); +} + +static int inv_icm42600_timestamp_read(struct inv_icm42600_state *st, + uint32_t *ts) +{ + struct device *dev = regmap_get_device(st->map); + __le32 raw; + int ret; + + pm_runtime_get_sync(dev); + mutex_lock(&st->lock); + + ret = regmap_write(st->map, INV_ICM42600_REG_SIGNAL_PATH_RESET, + INV_ICM42600_SIGNAL_PATH_RESET_TMST_STROBE); + if (ret) + goto exit; + + /* Read timestamp value 3 registers little-endian */ + raw = 0; + ret = regmap_bulk_read(st->map, INV_ICM42600_REG_TMSTVAL, &raw, 3); + if (ret) + goto exit; + + *ts = (uint32_t)le32_to_cpu(raw); +exit: + mutex_unlock(&st->lock); + pm_runtime_mark_last_busy(dev); + pm_runtime_put_autosuspend(dev); + return ret; +} + +int inv_icm42600_timestamp_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask) +{ + struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); + uint32_t ts; + int ret; + + if (chan->type != IIO_TIMESTAMP) + return -EINVAL; + + switch (mask) { + case IIO_CHAN_INFO_PROCESSED: + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; + ret = inv_icm42600_timestamp_read(st, &ts); + iio_device_release_direct_mode(indio_dev); + if (ret) + return ret; + *val = ts * 1000; + return IIO_VAL_INT; + default: + return -EINVAL; + } +} + +static void inv_icm42600_init_ts(struct inv_icm42600_timestamp *ts, + struct device *dev, uint32_t period) +{ + /* initial odr for sensor is 1kHz */ + const uint32_t default_period = 1000000; + + ts->dev = dev; + ts->mult = default_period / INV_ICM42600_TIMESTAMP_PERIOD; + ts->new_mult = period / INV_ICM42600_TIMESTAMP_PERIOD; + ts->period = default_period; + + /* use theoretical value for chip period */ + inv_update_acc(&ts->chip_period, INV_ICM42600_TIMESTAMP_PERIOD); +} + +int inv_icm42600_timestamp_init(struct inv_icm42600_state *st) +{ + unsigned int val; + + inv_icm42600_init_ts(&st->timestamp.gyro, regmap_get_device(st->map), + inv_icm42600_odr_to_period(st->conf.gyro.odr)); + inv_icm42600_init_ts(&st->timestamp.accel, regmap_get_device(st->map), + inv_icm42600_odr_to_period(st->conf.accel.odr)); + + /* enable timestamp register */ + val = INV_ICM42600_TMST_CONFIG_TMST_TO_REGS_EN | + INV_ICM42600_TMST_CONFIG_TMST_EN; + return regmap_update_bits(st->map, INV_ICM42600_REG_TMST_CONFIG, + INV_ICM42600_TMST_CONFIG_MASK, val); +} + +void inv_icm42600_timestamp_update_odr(struct inv_icm42600_timestamp *ts, + int odr) +{ + uint32_t period; + + period = inv_icm42600_odr_to_period(odr); + ts->new_mult = period / INV_ICM42600_TIMESTAMP_PERIOD; + dev_dbg(ts->dev, "ts new mult: %u\n", ts->new_mult); +} + +static bool inv_validate_period(uint32_t period, uint32_t mult) +{ + const uint32_t chip_period = INV_ICM42600_TIMESTAMP_PERIOD; + uint32_t period_min, period_max; + + /* check that time interval between interrupts is acceptable */ + period_min = INV_ICM42600_TIMESTAMP_MIN_PERIOD(chip_period) * mult; + period_max = INV_ICM42600_TIMESTAMP_MAX_PERIOD(chip_period) * mult; + if (period > period_min && period < period_max) + return true; + else + return false; +} + +static bool inv_compute_chip_period(struct inv_icm42600_timestamp *ts, + uint32_t mult, uint32_t period) +{ + uint32_t new_chip_period; + + if (!inv_validate_period(period, mult)) + return false; + + /* update chip internal period estimation */ + new_chip_period = period / mult; + inv_update_acc(&ts->chip_period, new_chip_period); + + dev_dbg(ts->dev, "ts chip period: %u - val %u\n", new_chip_period, + ts->chip_period.val); + + return true; +} + +void inv_icm42600_timestamp_interrupt(struct inv_icm42600_timestamp *ts, + uint32_t fifo_period, size_t fifo_nb, + size_t sensor_nb, int64_t timestamp) +{ + struct inv_icm42600_timestamp_interval *it; + int64_t delta, interval; + const uint32_t fifo_mult = fifo_period / INV_ICM42600_TIMESTAMP_PERIOD; + uint32_t period = ts->period; + int32_t m; + bool valid = false; + + if (fifo_nb == 0) + return; + + /* update interrupt timestamp and compute chip and sensor periods */ + it = &ts->it; + it->lo = it->up; + it->up = timestamp; + delta = it->up - it->lo; + dev_dbg(ts->dev, "ts it: %lld - %lld - %lld\n", it->lo, it->up, delta); + if (it->lo != 0) { + period = div_s64(delta, fifo_nb); + valid = inv_compute_chip_period(ts, fifo_mult, period); + if (valid) + ts->period = ts->mult * ts->chip_period.val; + } + + /* no previous data, compute theoritical value from interrupt */ + if (ts->timestamp == 0) { + interval = (int64_t)ts->period * (int64_t)sensor_nb; + ts->timestamp = it->up - interval; + dev_dbg(ts->dev, "ts start: %lld\n", ts->timestamp); + return; + } + + /* if interrupt interval is valid, sync with interrupt timestamp */ + if (valid) { + /* compute real fifo_period */ + fifo_period = fifo_mult * ts->chip_period.val; + delta = it->lo - ts->timestamp; + while (delta >= (fifo_period * 3 / 2)) + delta -= fifo_period; + /* compute maximal adjustment value */ + m = INV_ICM42600_TIMESTAMP_MAX_PERIOD(ts->period) - ts->period; + if (delta > m) + delta = m; + else if (delta < -m) + delta = -m; + dev_dbg(ts->dev, "ts adj: %lld\n", delta); + ts->timestamp += delta; + } +} + +void inv_icm42600_timestamp_apply_odr(struct inv_icm42600_timestamp *ts, + uint32_t fifo_period, size_t fifo_nb, + unsigned int fifo_no) +{ + int64_t interval; + uint32_t fifo_mult; + + ts->mult = ts->new_mult; + ts->period = ts->mult * ts->chip_period.val; + dev_dbg(ts->dev, "ts mult: %u\n", ts->mult); + + if (ts->timestamp != 0) { + /* compute real fifo period */ + fifo_mult = fifo_period / INV_ICM42600_TIMESTAMP_PERIOD; + fifo_period = fifo_mult * ts->chip_period.val; + /* compute timestamp from current interrupt after ODR change */ + interval = (int64_t)(fifo_nb - fifo_no) * (int64_t)fifo_period; + ts->timestamp = ts->it.up - interval; + dev_dbg(ts->dev, "ts new: %lld\n", ts->timestamp); + } +} diff --git a/drivers/iio/imu/inv_icm42600/inv_icm42600_timestamp.h b/drivers/iio/imu/inv_icm42600/inv_icm42600_timestamp.h new file mode 100644 index 000000000000..c865e1a9a7c8 --- /dev/null +++ b/drivers/iio/imu/inv_icm42600/inv_icm42600_timestamp.h @@ -0,0 +1,82 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2020 Invensense, Inc. + */ + +#ifndef INV_ICM42600_TIMESTAMP_H_ +#define INV_ICM42600_TIMESTAMP_H_ + +#include +#include + +struct inv_icm42600_state; + +struct inv_icm42600_timestamp_interval { + int64_t lo; + int64_t up; +}; + +struct inv_icm42600_timestamp_acc { + uint32_t val; + size_t idx; + uint32_t values[32]; +}; + +struct inv_icm42600_timestamp { + struct device *dev; + struct inv_icm42600_timestamp_interval it; + int64_t timestamp; + uint32_t mult; + uint32_t new_mult; + uint32_t period; + struct inv_icm42600_timestamp_acc chip_period; +}; + +#define INV_ICM42600_TIMESTAMP_CHAN(_index) \ + { \ + .type = IIO_TIMESTAMP, \ + .info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED), \ + .scan_index = _index, \ + .scan_type = { \ + .sign = 's', \ + .realbits = 64, \ + .storagebits = 64, \ + }, \ + } + +int inv_icm42600_timestamp_read_raw(struct iio_dev *indio_dev, + struct iio_chan_spec const *chan, + int *val, int *val2, long mask); + +int inv_icm42600_timestamp_init(struct inv_icm42600_state *st); + +void inv_icm42600_timestamp_update_odr(struct inv_icm42600_timestamp *ts, + int odr); + +void inv_icm42600_timestamp_interrupt(struct inv_icm42600_timestamp *ts, + uint32_t fifo_period, size_t fifo_nb, + size_t sensor_nb, int64_t timestamp); + +static inline int64_t +inv_icm42600_timestamp_get(struct inv_icm42600_timestamp *ts) +{ + ts->timestamp += ts->period; + dev_dbg(ts->dev, "ts: %lld\n", ts->timestamp); + + return ts->timestamp; +} + +void inv_icm42600_timestamp_apply_odr(struct inv_icm42600_timestamp *ts, + uint32_t fifo_period, size_t fifo_nb, + unsigned int fifo_no); + +static inline void +inv_icm42600_timestamp_reset(struct inv_icm42600_timestamp *ts) +{ + const struct inv_icm42600_timestamp_interval interval_init = {0LL, 0LL}; + + ts->it = interval_init; + ts->timestamp = 0; +} + +#endif From patchwork Thu May 7 14:42:21 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Baptiste Maneyrol X-Patchwork-Id: 11533987 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id AAA94139F for ; Thu, 7 May 2020 14:43:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8C98F21473 for ; Thu, 7 May 2020 14:43:37 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=invensense.com header.i=@invensense.com header.b="RBCAlL4u"; dkim=pass (1024-bit key) header.d=invensense.onmicrosoft.com header.i=@invensense.onmicrosoft.com header.b="hbvivFj6" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727932AbgEGOng (ORCPT ); Thu, 7 May 2020 10:43:36 -0400 Received: from mx0b-00328301.pphosted.com ([148.163.141.47]:48780 "EHLO mx0b-00328301.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727841AbgEGOne (ORCPT ); Thu, 7 May 2020 10:43:34 -0400 Received: from pps.filterd (m0156136.ppops.net [127.0.0.1]) by mx0b-00328301.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 047Ebhbe006057; Thu, 7 May 2020 07:43:29 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=invensense.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : content-type : mime-version; s=pfpt1; bh=czBRGgwfM0sgMjtVxSdWQYBBKCe6Zr5q/E9kFStNDUM=; b=RBCAlL4umqFSTniGAWD9drkyz27W/ElM60aVfusL4uchw97Zs6iCp7+EH3PHKdqFeJYf 8MAFTZNDSmgMeWI1T7KrzMfXuqHMSRKTuPiI80fT4qAZeCsLKZke0KAKMXvld2IgXQKZ gjlg7lFdI2xD5IMgSLCQMcVhfO31WeCcIYd+CwTieg05Qq/9e86cKlbMAUudf6kR0q7o YlFkORd90Cu+ojrmHEVeucUf2wwQZ8pIWvSGf0kCEk4SdKJyVnGYjCNqUwDAaMGyawUZ WnasOJ4ZNJj2yRlJ3KTSaR9vTjmOEZN3vpyTAbs0StSb6MolQC6u0R4JX9jJdr9E8Y0/ LA== Received: from nam12-mw2-obe.outbound.protection.outlook.com (mail-mw2nam12lp2040.outbound.protection.outlook.com [104.47.66.40]) by mx0b-00328301.pphosted.com with ESMTP id 30s4tnatww-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 07 May 2020 07:43:29 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=hku0/KLc1ArRGQLLbzP6jmaI/Gg6zOD5kZa5BWTrONSuAY0CkcSysqAkoq813MgVneteeN+lLgGK0+M/N3dvAhbgyCp5JsvUTCvHbKL2/9IKGelBsr7gEQltH1VlIm5UyIQQgcfSCihbpgxXeC3je40VEFSJrBlwt87S5O2swV0DeeTv1s6TQltPecfYTG3rXi1vjWyhPw6JgXfkdJz8DZ7GmzbAI5Lexbjgvg+H8ebS9Yv3gLSa9SJC5FTZTGDX1g8cnlKZGHCM7epUbn38YGGkMaaYQ52JBA50DC7anZpIItpSn1EETOeOcSDv8Jwd7VvQdOyn6R/sx1yCxvyxsQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=czBRGgwfM0sgMjtVxSdWQYBBKCe6Zr5q/E9kFStNDUM=; b=UlrmMPgMV+BxNzgae4wjThhH7KS7XYVnssNEokSkglmGp6laQVz3Il/9RT+UiYTrgY9r9sSNWnpjd23yMf5ukQrpDPtzsP6MJ515ToxrmsdW9D9unQLgEhNh4e1fZMSEHbmfsi5bi63k3V7opF8uhswTfFhnuKyul1m0RDPEpMksNrbYzo/Kxx5EftHC7Y74B+UhczhEwfjtO+c2G1IzIqC8DESh48iGxq9FJLFqdR/8UrDwvWmKcubS5/CbNa5qDfvljCfKhmUVTW1Kgmc4pfyk97Y1Z5SREq8fJTV5+B6IYWGTLYhUzttHgZgGVlG0bCT0shtNWXEQRDOMIVszGA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=invensense.com; dmarc=pass action=none header.from=invensense.com; dkim=pass header.d=invensense.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=invensense.onmicrosoft.com; s=selector2-invensense-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=czBRGgwfM0sgMjtVxSdWQYBBKCe6Zr5q/E9kFStNDUM=; b=hbvivFj6n++zDHmlOi72ooTQhth3w3JHk3CsM1CaZSLLnzKKMR6jhuGv6H4RDtCdFyGnEiYvF7NfC8X5E7wQR+C75SIMRrnrYo6of+GRcDwllzKukkmcqvrtN8EnqO+Y9jiyBdamcoC9j0nUkzmWOllmGloivxocQZv+uPSn78U= Authentication-Results: kernel.org; dkim=none (message not signed) header.d=none;kernel.org; dmarc=none action=none header.from=invensense.com; Received: from MN2PR12MB4422.namprd12.prod.outlook.com (2603:10b6:208:265::9) by MN2PR12MB4501.namprd12.prod.outlook.com (2603:10b6:208:269::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2979.27; Thu, 7 May 2020 14:43:27 +0000 Received: from MN2PR12MB4422.namprd12.prod.outlook.com ([fe80::7471:da8b:8ca1:6af0]) by MN2PR12MB4422.namprd12.prod.outlook.com ([fe80::7471:da8b:8ca1:6af0%4]) with mapi id 15.20.2979.028; Thu, 7 May 2020 14:43:27 +0000 From: Jean-Baptiste Maneyrol To: jic23@kernel.org, robh+dt@kernel.org, robh@kernel.org, mchehab+huawei@kernel.org, davem@davemloft.net, gregkh@linuxfoundation.org Cc: linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Jean-Baptiste Maneyrol Subject: [PATCH 11/12] dt-bindings: iio: imu: Add inv_icm42600 documentation Date: Thu, 7 May 2020 16:42:21 +0200 Message-Id: <20200507144222.20989-12-jmaneyrol@invensense.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200507144222.20989-1-jmaneyrol@invensense.com> References: <20200507144222.20989-1-jmaneyrol@invensense.com> X-ClientProxiedBy: LNXP265CA0048.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:5c::36) To MN2PR12MB4422.namprd12.prod.outlook.com (2603:10b6:208:265::9) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from frgnb-buildozer.invcorp.invensense.com (77.157.193.39) by LNXP265CA0048.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:5c::36) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2979.26 via Frontend Transport; Thu, 7 May 2020 14:43:25 +0000 X-Mailer: git-send-email 2.17.1 X-Originating-IP: [77.157.193.39] X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: e6b9fc75-b14d-4da3-3a2f-08d7f2950093 X-MS-TrafficTypeDiagnostic: MN2PR12MB4501: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:5236; X-Forefront-PRVS: 03965EFC76 X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: RBf0vNz1wLxhW11xA4rFESmBYVLvmwawr95KfCLRprr0Xi+901K8hOUofQoq3ZCI5n/F2F0xzFulOxo2oNP0OIz0Fsdst7P9P8b39RRl5HyLPM4p+o7wPQ8EY9M9p1Kk6LyDMmg5QTzzfm+A5rI98e7SBXGTa8xyGWBZiUKZUBC99eXZpqME4NC/vuoafPtjiNbM2MohLt6iYn39pIT2E083E0gelKyP6U0YQ2/79Lg5NCFpp3jx1rWMu6a3BFg3t9LFXyjV5b4sW2orF7RF31OzWhRymZPmARhjFC4OxglYgI/dAQU3QcFBTrUMhLOCn//fnNDfVtdlnILcTlLs5qxUT9ohwV8h4E612xwGJql534DVBnCiweS7UbYh2XcB2f87tHruI//NYOxr8mLiz6V99ExfVwhFVX0G6MkkEsokTInIcv0oQguZSM9C68e5cjlekO5hhJvHRojTNKtdG/O1PgRNW2MJ6FrC7aqzIhtdW90bjT8Tvl2XBZvoWaVYYX7OGDXBRYdJLYUThPZGJ6210QKpSh8CI2syy9vouLGj+zdNS5SDcWZOKcukDLqNw3tKAK+b9YAJOGV/HIUsc2gq1czZ3zf9u8ML6d6C4edPvLI6xV8ex4R03pkym4T0Msir2NARTt+rawORrfDGT3f3a8mP78AoDqJcsg7H/3w= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:MN2PR12MB4422.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFTY:;SFS:(346002)(376002)(136003)(396003)(39850400004)(366004)(33430700001)(966005)(107886003)(4326008)(8676002)(6486002)(2906002)(316002)(5660300002)(8936002)(1076003)(26005)(7696005)(33440700001)(66946007)(956004)(66476007)(52116002)(2616005)(86362001)(186003)(83320400001)(83280400001)(83310400001)(83290400001)(16526019)(478600001)(6666004)(36756003)(66556008)(83300400001)(15398625002)(43620500001);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData: RVAeKi5ESVfuU6LCNEJFx29kuf+H7n9XGoU/oDhK+ZhpUVoA7MbU42tNVW59ProeulOps18DfsAy8YmfZZJQ3LDayOTquV7RT/T+P3v+ChAbcJKBI/DemjuNri5aYs2r1QUdNmNZoj/TUm/CDNxNacvFjIdU4joKa16w9DQ/tzmZ007QPzBjTS++y30B8pzaIsjxwccBQZ5V5uprtnKDCmMralQ0CPnIOPbfFlYfap4h+rO88rdTv5wOM5BTz/FAn+Y1FHMVJUtU2xCnxCnZbhn3SXtLF+W9jcPtfzD4c8xbFObxP/6V8xyvQRpSPdrZMXhqx7g5JMJ/6pg7YnlJ5sCULlg/+86Q4t6QTfUvmIurfUM9lOrf4c+er8ohC6OwyvgoBp1kKWm3hUYHBB348UYdUPkjCUnmmqu+h/7hU1ZYG+N0cKOvEOBemo+3Q7ETpecOTDeLLDJr1exsQAorFL/GVTptZ13B481E78bEZmCu8ftdJ/3jtgGNfv5p0eWrrL8yJQQ2nJtWXu3Oj12aXKsAFovrxqsp1uFyh7QxXpEaPI6D0u2/X2F5hgUQf0c2unCeDpsQAUepM4QeMoSVxf1R1dqMKoHZhaq90JxOpTivr/O9mfpjs7UEyvG0gpFs4h3fh4N1gBwaOOX4RKS7AD9FTI9lrSf8nMXnayMiakWTFhbUoOhqriBd8AOMwRFkAAH7nNj2SMwifAnsfOYWtxMlomo/JlkqvIjKjbIX28ddGMta/RKoyycbYVUZvmGTyMkFqN8f0fi4qYdf78ZvLfUFYRa3jKxP8DFhUm5K3hE= X-OriginatorOrg: invensense.com X-MS-Exchange-CrossTenant-Network-Message-Id: e6b9fc75-b14d-4da3-3a2f-08d7f2950093 X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 May 2020 14:43:27.1544 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 462b3b3b-e42b-47ea-801a-f1581aac892d X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: cMqCCkKadvayxF6OKORErY90Yj2GOyP8QhzdzBgAC+omU77/sOHgZ7VluXRpzAAhyNBJ+89ueHc+SKgI4Ufn+CEYMZ9II5iN9vb/7WKjfK8= X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR12MB4501 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.216,18.0.676 definitions=2020-05-07_09:2020-05-07,2020-05-07 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 adultscore=0 priorityscore=1501 spamscore=0 mlxlogscore=999 impostorscore=0 suspectscore=0 phishscore=0 malwarescore=0 lowpriorityscore=0 bulkscore=0 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2005070118 Sender: linux-iio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org Document the ICM-426xxx devices devicetree bindings. Signed-off-by: Jean-Baptiste Maneyrol --- .../bindings/iio/imu/invensense,icm42600.yaml | 90 +++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml diff --git a/Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml b/Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml new file mode 100644 index 000000000000..a7175f6543fa --- /dev/null +++ b/Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml @@ -0,0 +1,90 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/iio/imu/invensense,icm42600.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: InvenSense ICM-426xx Inertial Measurement Unit + +maintainers: + - Jean-Baptiste Maneyrol + +description: | + 6-axis MotionTracking device that combines a 3-axis gyroscope and a 3-axis accelerometer. + + It has a configurable host interface that supports I3C, I2C and SPI serial communication, features a 2kB FIFO and + 2 programmable interrupts with ultra-low-power wake-on-motion support to minimize system power consumption. + + Other industry-leading features include InvenSense on-chip APEX Motion Processing engine for gesture recognition, + activity classification, and pedometer, along with programmable digital filters, and an embedded temperature sensor. + + https://invensense.tdk.com/wp-content/uploads/2020/03/DS-000292-ICM-42605-v1.4.pdf + +properties: + compatible: + enum: + - invensense,icm42600 + - invensense,icm42602 + - invensense,icm42605 + - invensense,icm42622 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + spi-cpha: true + + spi-cpol: true + + spi-max-frequency: + maxItems: 1 + + vdd-supply: + description: Regulator that provides power to the sensor + + vddio-supply: + description: Regulator that provides power to the bus + +required: + - compatible + - reg + - interrupts + +examples: + - | + #include + #include + i2c0 { + #address-cells = <1>; + #size-cells = <0>; + + icm42605@68 { + compatible = "invensense,icm42605"; + reg = <0x68>; + interrupt-parent = <&gpio2>; + interrupts = <7 IRQ_TYPE_EDGE_FALLING>; + vdd-supply = <&vdd>; + vddio-supply = <&vddio>; + }; + }; + - | + #include + #include + spi0 { + #address-cells = <1>; + #size-cells = <0>; + + icm42602@0 { + compatible = "invensense,icm42602"; + reg = <0>; + spi-max-frequency = <24000000>; + spi-cpha; + spi-cpol; + interrupt-parent = <&gpio1>; + interrupts = <2 IRQ_TYPE_EDGE_FALLING>; + vdd-supply = <&vdd>; + vddio-supply = <&vddio>; + }; + }; From patchwork Thu May 7 14:42:22 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Baptiste Maneyrol X-Patchwork-Id: 11533991 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 58DF2159A for ; Thu, 7 May 2020 14:43:47 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3BF78208D6 for ; Thu, 7 May 2020 14:43:47 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=invensense.com header.i=@invensense.com header.b="iQC7hIwZ"; dkim=pass (1024-bit key) header.d=invensense.onmicrosoft.com header.i=@invensense.onmicrosoft.com header.b="Ayp+xS08" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727935AbgEGOng (ORCPT ); Thu, 7 May 2020 10:43:36 -0400 Received: from mx0b-00328301.pphosted.com ([148.163.141.47]:49462 "EHLO mx0b-00328301.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727857AbgEGOne (ORCPT ); Thu, 7 May 2020 10:43:34 -0400 Received: from pps.filterd (m0156136.ppops.net [127.0.0.1]) by mx0b-00328301.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 047Ebhbf006057; Thu, 7 May 2020 07:43:30 -0700 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=invensense.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : content-type : mime-version; s=pfpt1; bh=fEwmw9ER5fwbE7/630gcavOolHhI9ezXUsNWuYkyYSg=; b=iQC7hIwZ6pydHDAR0Pgm7WyUi+02kCJrJ2OKRZKWomBi+l777W8F0UzeZn3NqHnRi6yQ wSBoJHuJ4z6xKkTgMY4qK5GN5GOShYf/KCiuWi1lHFInuuRRtti1gz7jgQqlTNeZpTLq 7i9yIqhboLwVm/bho/e38fRWANpEfJX73JwP/SZo8xQR8t4JdPM16QFyrqx5s8oU8SZx dad+q+QS3JvBPFTBxOGOJXvRh2eH6eb2+/CsFtX2dlTpY+NrZpowHEeQxsf0LNQURQdg 2rQm6IOjDrCPLGWvC4K1VpEi1HGfEHekFQuUR4tTvMCBi2YQUszPCn5jQZt1oWYnhKbp 2A== Received: from nam12-mw2-obe.outbound.protection.outlook.com (mail-mw2nam12lp2040.outbound.protection.outlook.com [104.47.66.40]) by mx0b-00328301.pphosted.com with ESMTP id 30s4tnatww-2 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Thu, 07 May 2020 07:43:29 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=nchpGGhKnoY6rsQnliL7SilrzTPnqnNijhl5ZZUYNWRD2P3xY80vK2SsheusNFqb4V/l4CIAHgfT9FVqLh6jcUcTFIdslmApCUH6vNqlur5iGcfVFQr9tyc4zjqKsLaMMK2CJ2DiHFZdYFChOMGsJZLGrj2jmGRYgG4h5sJ/dZfvKGSidGMkR0BNKOzkg2MDwyG8HZPyq9yIBXZh/38YeL/vQdrejpSLEB3OCgI2NA7oo/QJTOtjEh8SW16Fey7qiFCmV/NcuC8Qw/smDGfR0afdDOFCqBgYwl+WyUAPYALnhuAEObeeMD9xEkgn7ci8xcZ9vrDZWgFPyNLxYnbL5A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=fEwmw9ER5fwbE7/630gcavOolHhI9ezXUsNWuYkyYSg=; b=MkdAhZwBfZ59wd4N4CMuEML6hT/iodIRYLNTjmM9qe1xdISo/Ixs2DoR5rM6FxDTG5UebKezf3RBU/DFc2YWLsCpmnV/QzBZobqZHx+8I7Wawwy9OkvTnZcLFFUpQBYPQEs99s/PoUjll12d6UUKE1YPjJIE6F63t2Vefpkn8sYZpANC2Hs2zPUTzOZ3ZFBAsRXndDVXvEFkuWPL2p+PofO5TUu/hdFL80hV+llsW4FHrSYeHVM0JDw/N02BEt16U03g930bUAyrEDlXmzIPyeLM8Evrr3lo2FEEAGwPvbaW/UVxmgJbnu5rf0LuiLfRRbCy7YHN6mu3ZcVpD+LRMw== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=invensense.com; dmarc=pass action=none header.from=invensense.com; dkim=pass header.d=invensense.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=invensense.onmicrosoft.com; s=selector2-invensense-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=fEwmw9ER5fwbE7/630gcavOolHhI9ezXUsNWuYkyYSg=; b=Ayp+xS08CizKyQLVV7390d0yKAI5qQPnDCQp2wVlSoXTsK6bYfT7EvI73NJ4K3+1eykfu9GMVPE2Xm4fwFF5kQauf+WdmjvkugQStWP6/qbaJ/sbjE2ziNUp+1GTkofor7iQYXtXpMcDuWqh3xdqrmi/IohVW1V2XZKiscNttdM= Authentication-Results: kernel.org; dkim=none (message not signed) header.d=none;kernel.org; dmarc=none action=none header.from=invensense.com; Received: from MN2PR12MB4422.namprd12.prod.outlook.com (2603:10b6:208:265::9) by MN2PR12MB4501.namprd12.prod.outlook.com (2603:10b6:208:269::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2979.27; Thu, 7 May 2020 14:43:29 +0000 Received: from MN2PR12MB4422.namprd12.prod.outlook.com ([fe80::7471:da8b:8ca1:6af0]) by MN2PR12MB4422.namprd12.prod.outlook.com ([fe80::7471:da8b:8ca1:6af0%4]) with mapi id 15.20.2979.028; Thu, 7 May 2020 14:43:29 +0000 From: Jean-Baptiste Maneyrol To: jic23@kernel.org, robh+dt@kernel.org, robh@kernel.org, mchehab+huawei@kernel.org, davem@davemloft.net, gregkh@linuxfoundation.org Cc: linux-iio@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Jean-Baptiste Maneyrol Subject: [PATCH 12/12] MAINTAINERS: add entry for inv_icm42600 6-axis imu sensor Date: Thu, 7 May 2020 16:42:22 +0200 Message-Id: <20200507144222.20989-13-jmaneyrol@invensense.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200507144222.20989-1-jmaneyrol@invensense.com> References: <20200507144222.20989-1-jmaneyrol@invensense.com> X-ClientProxiedBy: LNXP265CA0048.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:5c::36) To MN2PR12MB4422.namprd12.prod.outlook.com (2603:10b6:208:265::9) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from frgnb-buildozer.invcorp.invensense.com (77.157.193.39) by LNXP265CA0048.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:5c::36) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.2979.26 via Frontend Transport; Thu, 7 May 2020 14:43:27 +0000 X-Mailer: git-send-email 2.17.1 X-Originating-IP: [77.157.193.39] X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: cf2f4123-155e-41bd-d99e-08d7f295019d X-MS-TrafficTypeDiagnostic: MN2PR12MB4501: X-MS-Exchange-Transport-Forked: True X-Microsoft-Antispam-PRVS: X-MS-Oob-TLC-OOBClassifiers: OLM:1079; X-Forefront-PRVS: 03965EFC76 X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 2tIfo+rg3TeQfbiJBhZNPtIM4yhSo7GvAJ9c/pPjLd26Hq+qyltQ/5A5DRP7ooVJ6R31dhD9Ugav2gZW9TQhz3l78u4X3TFgZCa+bb+XsnHPYtTyse+v0rvtJ5Su1Hd08p3zWpXgiJxfxw7EXPyaGRo6S6JJd03njyxFXu/qdAAaNf/4jCS558Jlgsp9ww2rclxVUxwVhl8Kn2k+KRQ6Otn5J4fSTbmDueDexUdAGbXXfc+oPtehSBU92pO5YrGO30KeufELtZTp9BjkwKQZ5I2s6rSR1Fc6IlM6d7uapwJfHc0TsxHY5UPjHSVWEjZPXmHgNPSPMxYT4s/v2TkEVRZ5DuOKCl1XGboipQw6xgCDshW4nlO4sFqYkrsYdzbooJkFaGL0oHzBLjuOk6eql4NUTNgKboKlRnW7+TpjCO9tigiuQqjvLU3z2hx/ZfzxLwPLlIkOAXyJcNiXATibQ3dQUIYVwPfL6jKeDXkqE3fqhS10Wf2YHa9ceV9G0zs9GadAIXTbAaKf8sL6T3Nwk0MQDwEEz85b+X6cUuqMzxl/AuuJExxemaK7FgaqyaXLSgSnBCmLt/cQjQ1PugPyIDnjAC8aJqNSu6Oj3oG1Ln0= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:MN2PR12MB4422.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFTY:;SFS:(346002)(376002)(136003)(396003)(39850400004)(366004)(33430700001)(966005)(107886003)(4326008)(8676002)(6486002)(2906002)(316002)(5660300002)(8936002)(1076003)(26005)(7696005)(33440700001)(66946007)(956004)(66476007)(52116002)(2616005)(86362001)(186003)(83320400001)(83280400001)(83310400001)(83290400001)(16526019)(478600001)(6666004)(36756003)(4744005)(66556008)(83300400001);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData: 8Finn44NzEpmZo1n6xEKRDAnLHo4LdBDVBHqwQ4QYiMD8uYcibSGOjFqqsVUrKAtQ21nl3ateOCcWDp2ewMbra6PCEYbJZ7nFq+4LpRvimO7wKjkHRSNyR98aLl/+C3QvZ5kyDLkKcyrGj+8jY8oDJdQrKuYWSOUiLGNCpZdJKHhAQfnfFxjxkDNiOvDNvpL5aQE2STOsBl3UJoTPGf3Y7GLWr87d3qEn6HDlcdV7U5Zp/pqf7fX2IPjEZeEBfMpmziaqdk0rSSXTtkq1vQxQ3vNr7NPf1z04IQGumsnlWO7Bn5DuBmRJL/ZCunidZVkKGMy5hH+CrIEyGuuJ7r7eqo0VcD8jVF1QuaT3ATPVTUbKL9ascjoeV+v+MWomk7q+84hQ2Y+4IL5rjgwJ6GpN0krjXniBYOXx+2mMlgvY1x66VWKQTVjrV2kys+hGt0EetdYmO1lXMXWKog3oeL+NF/s5M2S47S912ansZDyaC7KRa/5EAtkhuJrorRyxZ3uZKDy7OVlOdBE1EzLoCNyOEAatFR5eQ07BTQAYN4FiZjieqZjmjqe4xqyJnOvco4s791QcSzy9DgLrwiyQXP3j3zCu4sYahSY9UhnK6XrNIIpKuZIqlddRizDlyY2uGmFfOLscW/1ZgXvmEFFB170/7nHl1qTj09iIdyyz8b+AdUTWn3Ek/vugB27gLoE7lKgHfKRJDlx4Y5V4EshNBLlIgJVjahSuYDcqkqSvm+A1kZeDOF9Bh7WDVzCgxCj8DjoRsoLy+Fs3GkrD8WwDdpA3k8yxKVvG0UDcHJh/6E/v1U= X-OriginatorOrg: invensense.com X-MS-Exchange-CrossTenant-Network-Message-Id: cf2f4123-155e-41bd-d99e-08d7f295019d X-MS-Exchange-CrossTenant-OriginalArrivalTime: 07 May 2020 14:43:29.0252 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 462b3b3b-e42b-47ea-801a-f1581aac892d X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 0gaTtrGRGO45yKmhpRN5PtKCblu0wodWVe3cP/paUxOEUvHdSjs5vTL8u+32Gp2czQxweyYagcy6w4OF1l/Z0D0sL8RLkew+4zsMtnHjEkE= X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR12MB4501 X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.216,18.0.676 definitions=2020-05-07_09:2020-05-07,2020-05-07 signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 clxscore=1015 adultscore=0 priorityscore=1501 spamscore=0 mlxlogscore=999 impostorscore=0 suspectscore=0 phishscore=0 malwarescore=0 lowpriorityscore=0 bulkscore=0 mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2005070118 Sender: linux-iio-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-iio@vger.kernel.org Add MAINTAINERS entry for InvenSense ICM-426xx IMU device. Signed-off-by: Jean-Baptiste Maneyrol --- MAINTAINERS | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 10eb348c801c..1714390e2721 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -8864,6 +8864,14 @@ F: include/dt-bindings/interconnect/ F: include/linux/interconnect-provider.h F: include/linux/interconnect.h +INVENSENSE ICM-426xx IMU DRIVER +M: Jean-Baptiste Maneyrol +L: linux-iio@vger.kernel.org +S: Maintained +W https://invensense.tdk.com/ +F: Documentation/devicetree/bindings/iio/imu/invensense,icm42600.yaml +F: drivers/iio/imu/inv_icm42600/ + INVENSENSE MPU-3050 GYROSCOPE DRIVER M: Linus Walleij L: linux-iio@vger.kernel.org