From patchwork Thu Apr 29 12:28:03 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Nyekjaer X-Patchwork-Id: 429355 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_CR_TRAILER, INCLUDES_PATCH, MAILING_LIST_MULTI, SPF_HELO_NONE, SPF_PASS, URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 16743C43470 for ; Thu, 29 Apr 2021 12:28:23 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 00482613E1 for ; Thu, 29 Apr 2021 12:28:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236118AbhD2M3H (ORCPT ); Thu, 29 Apr 2021 08:29:07 -0400 Received: from first.geanix.com ([116.203.34.67]:50672 "EHLO first.geanix.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232657AbhD2M3F (ORCPT ); Thu, 29 Apr 2021 08:29:05 -0400 Received: from zen.. (unknown [185.17.218.86]) by first.geanix.com (Postfix) with ESMTPSA id BBB7A466693; Thu, 29 Apr 2021 12:28:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=geanix.com; s=first; t=1619699296; bh=9RFIp34R8dOCPLYSj4YJHVUXoQjw99Td2vb3UssDJec=; h=From:To:Cc:Subject:Date:In-Reply-To:References; b=EmKa7lKoZ77N+iWfoN0d6HWrCoi85XEJmBn6LeVY7kp1vPMJTy4n7liS6UpuFpB3G 5UNFOgHOkadlBZPFlWUA5hZtyp+pu4V1gahtyo7DsY0jXBZw+VhbGY2reATLKY8Obc 8DJeAgsqaaKmK6DjFr94kFNInpyYdGBmIW5Vdo9zLjAyI5rzHhfkWT+1fR8bsJOV2P hC582v5SJbp8jR1Hng4EIA/j5IhxiC0LdcMCym1qWqKO2RDJPkhmuQ5X2UNXreiCiK uVrp87dTnMD10LQBVO25mPOfQxEeFssL3+7jO1acuJz9SzYb11qo7/PB8w7FUxPrYq 7GjMenh1upJ+g== From: Sean Nyekjaer To: jic23@kernel.org, linux-iio@vger.kernel.org, andy.shevchenko@gmail.com, lars@metafoo.de, Nuno.Sa@analog.com, robh+dt@kernel.org, devicetree@vger.kernel.org Cc: Sean Nyekjaer Subject: [PATCH v4 3/6] iio: accel: fxls8962af: add set/get of samplerate Date: Thu, 29 Apr 2021 14:28:03 +0200 Message-Id: <20210429122806.3814330-3-sean@geanix.com> X-Mailer: git-send-email 2.31.0 In-Reply-To: <20210429122806.3814330-1-sean@geanix.com> References: <20210429122806.3814330-1-sean@geanix.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org This adds support for setting de accelerometers output data rate. Primarily used for hardware buffered reads. Signed-off-by: Sean Nyekjaer --- drivers/iio/accel/fxls8962af-core.c | 77 +++++++++++++++++++++++++++-- 1 file changed, 74 insertions(+), 3 deletions(-) diff --git a/drivers/iio/accel/fxls8962af-core.c b/drivers/iio/accel/fxls8962af-core.c index 6ae47eac4490..9de30e8539b1 100644 --- a/drivers/iio/accel/fxls8962af-core.c +++ b/drivers/iio/accel/fxls8962af-core.c @@ -50,6 +50,9 @@ #define FXLS8962AF_SENS_CONFIG2 0x16 #define FXLS8962AF_SENS_CONFIG3 0x17 +#define FXLS8962AF_SC3_WAKE_ODR_MASK GENMASK(7, 4) +#define FXLS8962AF_SC3_WAKE_ODR_PREP(x) FIELD_PREP(FXLS8962AF_SC3_WAKE_ODR_MASK, (x)) +#define FXLS8962AF_SC3_WAKE_ODR_GET(x) FIELD_GET(FXLS8962AF_SC3_WAKE_ODR_MASK, (x)) #define FXLS8962AF_SENS_CONFIG4 0x18 #define FXLS8962AF_SENS_CONFIG5 0x19 @@ -96,6 +99,7 @@ #define FXLS8962AF_AUTO_SUSPEND_DELAY_MS 2000 #define FXLS8962AF_SCALE_TABLE_LEN 4 +#define FXLS8962AF_SAMP_FREQ_TABLE_LEN 13 static const int fxls8962af_scale_table[FXLS8962AF_SCALE_TABLE_LEN][2] = { {0, IIO_G_TO_M_S_2(980000)}, @@ -104,6 +108,12 @@ static const int fxls8962af_scale_table[FXLS8962AF_SCALE_TABLE_LEN][2] = { {0, IIO_G_TO_M_S_2(7810000)}, }; +static const int fxls8962af_samp_freq_table[FXLS8962AF_SAMP_FREQ_TABLE_LEN][2] = { + {3200, 0}, {1600, 0}, {800, 0}, {400, 0}, {200, 0}, {100, 0}, + {50, 0}, {25, 0}, {12, 500000}, {6, 250000}, {3, 125000}, + {1, 563000}, {0, 781000}, +}; + struct fxls8962af_chip_info { const char *name; const struct iio_chan_spec *channels; @@ -228,6 +238,11 @@ static int fxls8962af_read_avail(struct iio_dev *indio_dev, *vals = (int *)fxls8962af_scale_table; *length = ARRAY_SIZE(fxls8962af_scale_table) * 2; return IIO_AVAIL_LIST; + case IIO_CHAN_INFO_SAMP_FREQ: + *type = IIO_VAL_INT_PLUS_MICRO; + *vals = (int *)fxls8962af_samp_freq_table; + *length = ARRAY_SIZE(fxls8962af_samp_freq_table) * 2; + return IIO_AVAIL_LIST; default: return -EINVAL; } @@ -237,7 +252,14 @@ static int fxls8962af_write_raw_get_fmt(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, long mask) { - return IIO_VAL_INT_PLUS_NANO; + 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; + default: + return IIO_VAL_INT_PLUS_NANO; + } } static int fxls8962af_update_config(struct fxls8962af_data *data, u8 reg, @@ -300,6 +322,42 @@ static unsigned int fxls8962af_read_full_scale(struct fxls8962af_data *data, return IIO_VAL_INT_PLUS_NANO; } +static int fxls8962af_set_samp_freq(struct fxls8962af_data *data, u32 val, u32 val2) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(fxls8962af_samp_freq_table); i++) + if (val == fxls8962af_samp_freq_table[i][0] && + val2 == fxls8962af_samp_freq_table[i][1]) + break; + + if (i == ARRAY_SIZE(fxls8962af_samp_freq_table)) + return -EINVAL; + + return fxls8962af_update_config(data, FXLS8962AF_SENS_CONFIG3, + FXLS8962AF_SC3_WAKE_ODR_MASK, + FXLS8962AF_SC3_WAKE_ODR_PREP(i)); +} + +static unsigned int fxls8962af_read_samp_freq(struct fxls8962af_data *data, + int *val, int *val2) +{ + int ret; + unsigned int reg; + u8 range_idx; + + ret = regmap_read(data->regmap, FXLS8962AF_SENS_CONFIG3, ®); + if (ret < 0) + return ret; + + range_idx = FXLS8962AF_SC3_WAKE_ODR_GET(reg); + + *val = fxls8962af_samp_freq_table[range_idx][0]; + *val2 = fxls8962af_samp_freq_table[range_idx][1]; + + return IIO_VAL_INT_PLUS_MICRO; +} + static int fxls8962af_read_raw(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, int *val, int *val2, long mask) @@ -324,6 +382,8 @@ static int fxls8962af_read_raw(struct iio_dev *indio_dev, case IIO_CHAN_INFO_SCALE: *val = 0; return fxls8962af_read_full_scale(data, val2); + case IIO_CHAN_INFO_SAMP_FREQ: + return fxls8962af_read_samp_freq(data, val, val2); default: return -EINVAL; } @@ -347,6 +407,15 @@ static int fxls8962af_write_raw(struct iio_dev *indio_dev, ret = fxls8962af_set_full_scale(data, val2); + iio_device_release_direct_mode(indio_dev); + return ret; + case IIO_CHAN_INFO_SAMP_FREQ: + ret = iio_device_claim_direct_mode(indio_dev); + if (ret) + return ret; + + ret = fxls8962af_set_samp_freq(data, val, val2); + iio_device_release_direct_mode(indio_dev); return ret; default: @@ -360,8 +429,10 @@ static int fxls8962af_write_raw(struct iio_dev *indio_dev, .modified = 1, \ .channel2 = IIO_MOD_##axis, \ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), \ - .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_type = BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ + .info_mask_shared_by_type_available = BIT(IIO_CHAN_INFO_SCALE) | \ + BIT(IIO_CHAN_INFO_SAMP_FREQ), \ .scan_index = idx, \ .scan_type = { \ .sign = 's', \