From nobody Thu Dec 18 22:29:49 2025 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1FBB1EE49B5 for ; Wed, 23 Aug 2023 21:18:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237535AbjHWVRf (ORCPT ); Wed, 23 Aug 2023 17:17:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:35806 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237816AbjHWVRW (ORCPT ); Wed, 23 Aug 2023 17:17:22 -0400 Received: from mail-wr1-x42d.google.com (mail-wr1-x42d.google.com [IPv6:2a00:1450:4864:20::42d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5C8B810DE; Wed, 23 Aug 2023 14:17:15 -0700 (PDT) Received: by mail-wr1-x42d.google.com with SMTP id ffacd0b85a97d-31c5c06e8bbso2560456f8f.1; Wed, 23 Aug 2023 14:17:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1692825434; x=1693430234; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=HOH7L9DmeCgj73H8ba5S9J4X+JEaZ83zmM8kUJ6nD+0=; b=dGmzW4KdQj6+FLq3AMtNbaEE1VdQSP8uzpExAZ9tdF2mOvdbpnAmgJVzyMLjJdMMBD NoGdpqAGCd9eUZqp1z/Kek7822Zy6QIBxgC3Dt6fXJmu9CjQH3IgPsQHy2slIpE1vcpI FcQ74U+QLcDOLqq3FiVRDHvH97fAc2Sb/bbddbecmK+SQUIANG91JbrB0mp+cihhbPCm PJEKqPMZ5IulIXbRyJ/F+dQbeIe/O0B4q1ZeTlniJMKHaDr+2ZKbQMjZ6OkojsBW8uAy NshYuS57XkxjISDCaS/kALpokwQRwWb25DlGUJbHNmEnouKs1et06k6d+254g3ne2lUK sOQg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1692825434; x=1693430234; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=HOH7L9DmeCgj73H8ba5S9J4X+JEaZ83zmM8kUJ6nD+0=; b=g6KIEPRPNqmKBvhNfWNwyM5XwS9hroZSPtWpX4L3guawenT5KngwMCu/8jAnyki8SS H5qHspOqYrgzOQV6jzGlB87H9F9b5ZriWW3JKnkbzuN3QohmPwHg/pIca/j0dhwnESUN KZStEpjhG5gX+UpVxNVkdmMwzVbmzyPKDFRdMqRaFa6RpTt/BjE/OcNhRSmNNfI2i/ki bS0qdDlHHnxBbRtG+1+ydzy9zTyUiyVrBayO37TpicppsuVPofyGaj+imxSlEKmmlefL PS+Ck2ccNGoAk3iGFcJKXaL5tNi5DBPqOSWgjhZX7DNouhT0+YT5cXT2VjLTV/kWvt8N /jCg== X-Gm-Message-State: AOJu0Yz4LikP4ueEP9gPuFtC+ze8VIVCAmIs6phrRVHALr8hf7i6ssLl 9P5NovRYBzlz+mfpSmkE7sw= X-Google-Smtp-Source: AGHT+IHLmHSaYrfBf1FwivWUoTksFSC9M61mPtutK1a7OHEj3bcnm9++NIMAaiX4P67CSXhMILakIQ== X-Received: by 2002:adf:fa47:0:b0:319:6e74:1637 with SMTP id y7-20020adffa47000000b003196e741637mr9782874wrr.27.1692825433753; Wed, 23 Aug 2023 14:17:13 -0700 (PDT) Received: from localhost.localdomain ([2a01:e0a:bb2:6df0:64ae:3840:3a64:b26a]) by smtp.gmail.com with ESMTPSA id p11-20020adfe60b000000b003176c6e87b1sm20193399wrm.81.2023.08.23.14.17.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 23 Aug 2023 14:17:13 -0700 (PDT) From: Mehdi Djait To: jic23@kernel.org, mazziesaccount@gmail.com Cc: krzysztof.kozlowski+dt@linaro.org, andriy.shevchenko@linux.intel.com, robh+dt@kernel.org, lars@metafoo.de, linux-iio@vger.kernel.org, linux-kernel@vger.kernel.org, devicetree@vger.kernel.org, Mehdi Djait Subject: [PATCH v8 5/7] iio: accel: kionix-kx022a: Refactor driver and add chip_info structure Date: Wed, 23 Aug 2023 23:16:39 +0200 Message-Id: <8ff0761f3912491d1d31f2f096e24423ad04140b.1692824815.git.mehdi.djait.k@gmail.com> X-Mailer: git-send-email 2.30.2 In-Reply-To: References: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" Add the chip_info structure to the driver's private data to hold all the device specific infos. Refactor the kx022a driver implementation to make it more generic and extensible. Acked-by: Matti Vaittinen Signed-off-by: Mehdi Djait --- v8: - replaced min_t() by min() and kmalloc() by kmalloc_array() v7: - no changes v6: - placed chip_info after the regmap elemnt in kx022a_data struct to save memory as suggested by Andy - added a check for the availability of chip_info for the SPI case as=20 suggested by Andy v5: - moved the "kfree" call to match the reverse of what happens in=20 kx022a_fifo_enable() as suggested by Matti and Jonathan - used min_t, checked for availability of chip_info as suggested by Andy v4: - allocating and freeing the buffer moved to the kx022a_fifo{enable, disable} functions - used the spi_get_device_match_data helper function v3: - added the change of the buffer's allocation in the __kx022a_fifo_flush to this patch - added the chip_info to the struct kx022a_data drivers/iio/accel/kionix-kx022a-i2c.c | 18 +++- drivers/iio/accel/kionix-kx022a-spi.c | 13 ++- drivers/iio/accel/kionix-kx022a.c | 117 +++++++++++++++++--------- drivers/iio/accel/kionix-kx022a.h | 52 +++++++++++- 4 files changed, 148 insertions(+), 52 deletions(-) diff --git a/drivers/iio/accel/kionix-kx022a-i2c.c b/drivers/iio/accel/kion= ix-kx022a-i2c.c index b5a85ce3a891..006ffb51d3e6 100644 --- a/drivers/iio/accel/kionix-kx022a-i2c.c +++ b/drivers/iio/accel/kionix-kx022a-i2c.c @@ -15,6 +15,7 @@ static int kx022a_i2c_probe(struct i2c_client *i2c) { struct device *dev =3D &i2c->dev; + const struct kx022a_chip_info *chip_info; struct regmap *regmap; =20 if (!i2c->irq) { @@ -22,22 +23,31 @@ static int kx022a_i2c_probe(struct i2c_client *i2c) return -EINVAL; } =20 - regmap =3D devm_regmap_init_i2c(i2c, &kx022a_regmap); + chip_info =3D device_get_match_data(&i2c->dev); + if (!chip_info) { + const struct i2c_device_id *id =3D i2c_client_get_device_id(i2c); + + chip_info =3D (const struct kx022a_chip_info *)id->driver_data; + if (!chip_info) + return -EINVAL; + } + + regmap =3D devm_regmap_init_i2c(i2c, chip_info->regmap_config); if (IS_ERR(regmap)) return dev_err_probe(dev, PTR_ERR(regmap), "Failed to initialize Regmap\n"); =20 - return kx022a_probe_internal(dev); + return kx022a_probe_internal(dev, chip_info); } =20 static const struct i2c_device_id kx022a_i2c_id[] =3D { - { .name =3D "kx022a" }, + { .name =3D "kx022a", .driver_data =3D (kernel_ulong_t)&kx022a_chip_info = }, { } }; MODULE_DEVICE_TABLE(i2c, kx022a_i2c_id); =20 static const struct of_device_id kx022a_of_match[] =3D { - { .compatible =3D "kionix,kx022a", }, + { .compatible =3D "kionix,kx022a", .data =3D &kx022a_chip_info }, { } }; MODULE_DEVICE_TABLE(of, kx022a_of_match); diff --git a/drivers/iio/accel/kionix-kx022a-spi.c b/drivers/iio/accel/kion= ix-kx022a-spi.c index 9cd047f7b346..896b57866fc9 100644 --- a/drivers/iio/accel/kionix-kx022a-spi.c +++ b/drivers/iio/accel/kionix-kx022a-spi.c @@ -15,6 +15,7 @@ static int kx022a_spi_probe(struct spi_device *spi) { struct device *dev =3D &spi->dev; + const struct kx022a_chip_info *chip_info; struct regmap *regmap; =20 if (!spi->irq) { @@ -22,22 +23,26 @@ static int kx022a_spi_probe(struct spi_device *spi) return -EINVAL; } =20 - regmap =3D devm_regmap_init_spi(spi, &kx022a_regmap); + chip_info =3D spi_get_device_match_data(spi); + if (!chip_info) + return -EINVAL; + + regmap =3D devm_regmap_init_spi(spi, chip_info->regmap_config); if (IS_ERR(regmap)) return dev_err_probe(dev, PTR_ERR(regmap), "Failed to initialize Regmap\n"); =20 - return kx022a_probe_internal(dev); + return kx022a_probe_internal(dev, chip_info); } =20 static const struct spi_device_id kx022a_id[] =3D { - { "kx022a" }, + { .name =3D "kx022a", .driver_data =3D (kernel_ulong_t)&kx022a_chip_info = }, { } }; MODULE_DEVICE_TABLE(spi, kx022a_id); =20 static const struct of_device_id kx022a_of_match[] =3D { - { .compatible =3D "kionix,kx022a", }, + { .compatible =3D "kionix,kx022a", .data =3D &kx022a_chip_info }, { } }; MODULE_DEVICE_TABLE(of, kx022a_of_match); diff --git a/drivers/iio/accel/kionix-kx022a.c b/drivers/iio/accel/kionix-k= x022a.c index 494e81ba1da9..6bac618c63b4 100644 --- a/drivers/iio/accel/kionix-kx022a.c +++ b/drivers/iio/accel/kionix-kx022a.c @@ -48,7 +48,7 @@ enum { KX022A_STATE_FIFO, }; =20 -/* Regmap configs */ +/* kx022a Regmap configs */ static const struct regmap_range kx022a_volatile_ranges[] =3D { { .range_min =3D KX022A_REG_XHP_L, @@ -138,7 +138,7 @@ static const struct regmap_access_table kx022a_nir_regs= =3D { .n_yes_ranges =3D ARRAY_SIZE(kx022a_noinc_read_ranges), }; =20 -const struct regmap_config kx022a_regmap =3D { +static const struct regmap_config kx022a_regmap_config =3D { .reg_bits =3D 8, .val_bits =3D 8, .volatile_table =3D &kx022a_volatile_regs, @@ -149,10 +149,10 @@ const struct regmap_config kx022a_regmap =3D { .max_register =3D KX022A_MAX_REGISTER, .cache_type =3D REGCACHE_RBTREE, }; -EXPORT_SYMBOL_NS_GPL(kx022a_regmap, IIO_KX022A); =20 struct kx022a_data { struct regmap *regmap; + const struct kx022a_chip_info *chip_info; struct iio_trigger *trig; struct device *dev; struct iio_mount_matrix orientation; @@ -175,6 +175,8 @@ struct kx022a_data { struct mutex mutex; u8 watermark; =20 + __le16 *fifo_buffer; + /* 3 x 16bit accel data + timestamp */ __le16 buffer[8] __aligned(IIO_DMA_MINALIGN); struct { @@ -208,7 +210,7 @@ static const struct iio_chan_spec_ext_info kx022a_ext_i= nfo[] =3D { { } }; =20 -#define KX022A_ACCEL_CHAN(axis, index) \ +#define KX022A_ACCEL_CHAN(axis, reg, index) \ { \ .type =3D IIO_ACCEL, \ .modified =3D 1, \ @@ -220,7 +222,7 @@ static const struct iio_chan_spec_ext_info kx022a_ext_i= nfo[] =3D { BIT(IIO_CHAN_INFO_SCALE) | \ BIT(IIO_CHAN_INFO_SAMP_FREQ), \ .ext_info =3D kx022a_ext_info, \ - .address =3D KX022A_REG_##axis##OUT_L, \ + .address =3D reg, \ .scan_index =3D index, \ .scan_type =3D { \ .sign =3D 's', \ @@ -231,9 +233,9 @@ static const struct iio_chan_spec_ext_info kx022a_ext_i= nfo[] =3D { } =20 static const struct iio_chan_spec kx022a_channels[] =3D { - KX022A_ACCEL_CHAN(X, 0), - KX022A_ACCEL_CHAN(Y, 1), - KX022A_ACCEL_CHAN(Z, 2), + KX022A_ACCEL_CHAN(X, KX022A_REG_XOUT_L, 0), + KX022A_ACCEL_CHAN(Y, KX022A_REG_YOUT_L, 1), + KX022A_ACCEL_CHAN(Z, KX022A_REG_ZOUT_L, 2), IIO_CHAN_SOFT_TIMESTAMP(3), }; =20 @@ -332,10 +334,10 @@ static int kx022a_turn_on_off_unlocked(struct kx022a_= data *data, bool on) int ret; =20 if (on) - ret =3D regmap_set_bits(data->regmap, KX022A_REG_CNTL, + ret =3D regmap_set_bits(data->regmap, data->chip_info->cntl, KX022A_MASK_PC1); else - ret =3D regmap_clear_bits(data->regmap, KX022A_REG_CNTL, + ret =3D regmap_clear_bits(data->regmap, data->chip_info->cntl, KX022A_MASK_PC1); if (ret) dev_err(data->dev, "Turn %s fail %d\n", str_on_off(on), ret); @@ -402,7 +404,7 @@ static int kx022a_write_raw(struct iio_dev *idev, break; =20 ret =3D regmap_update_bits(data->regmap, - KX022A_REG_ODCNTL, + data->chip_info->odcntl, KX022A_MASK_ODR, n); data->odr_ns =3D kx022a_odrs[n]; kx022a_turn_on_unlock(data); @@ -423,7 +425,7 @@ static int kx022a_write_raw(struct iio_dev *idev, if (ret) break; =20 - ret =3D regmap_update_bits(data->regmap, KX022A_REG_CNTL, + ret =3D regmap_update_bits(data->regmap, data->chip_info->cntl, KX022A_MASK_GSEL, n << KX022A_GSEL_SHIFT); kx022a_turn_on_unlock(data); @@ -445,7 +447,7 @@ static int kx022a_fifo_set_wmi(struct kx022a_data *data) =20 threshold =3D data->watermark; =20 - return regmap_update_bits(data->regmap, KX022A_REG_BUF_CNTL1, + return regmap_update_bits(data->regmap, data->chip_info->buf_cntl1, KX022A_MASK_WM_TH, threshold); } =20 @@ -488,7 +490,7 @@ static int kx022a_read_raw(struct iio_dev *idev, return ret; =20 case IIO_CHAN_INFO_SAMP_FREQ: - ret =3D regmap_read(data->regmap, KX022A_REG_ODCNTL, ®val); + ret =3D regmap_read(data->regmap, data->chip_info->odcntl, ®val); if (ret) return ret; =20 @@ -503,7 +505,7 @@ static int kx022a_read_raw(struct iio_dev *idev, return IIO_VAL_INT_PLUS_MICRO; =20 case IIO_CHAN_INFO_SCALE: - ret =3D regmap_read(data->regmap, KX022A_REG_CNTL, ®val); + ret =3D regmap_read(data->regmap, data->chip_info->cntl, ®val); if (ret < 0) return ret; =20 @@ -530,8 +532,7 @@ static int kx022a_set_watermark(struct iio_dev *idev, u= nsigned int val) { struct kx022a_data *data =3D iio_priv(idev); =20 - if (val > KX022A_FIFO_LENGTH) - val =3D KX022A_FIFO_LENGTH; + val =3D min(data->chip_info->fifo_length, val); =20 mutex_lock(&data->mutex); data->watermark =3D val; @@ -592,7 +593,7 @@ static int kx022a_drop_fifo_contents(struct kx022a_data= *data) */ data->timestamp =3D 0; =20 - return regmap_write(data->regmap, KX022A_REG_BUF_CLEAR, 0x0); + return regmap_write(data->regmap, data->chip_info->buf_clear, 0x0); } =20 static int __kx022a_fifo_flush(struct iio_dev *idev, unsigned int samples, @@ -600,7 +601,6 @@ static int __kx022a_fifo_flush(struct iio_dev *idev, un= signed int samples, { struct kx022a_data *data =3D iio_priv(idev); struct device *dev =3D regmap_get_device(data->regmap); - __le16 buffer[KX022A_FIFO_LENGTH * 3]; uint64_t sample_period; int count, fifo_bytes; bool renable =3D false; @@ -679,13 +679,13 @@ static int __kx022a_fifo_flush(struct iio_dev *idev, = unsigned int samples, } =20 fifo_bytes =3D count * KX022A_FIFO_SAMPLES_SIZE_BYTES; - ret =3D regmap_noinc_read(data->regmap, KX022A_REG_BUF_READ, - &buffer[0], fifo_bytes); + ret =3D regmap_noinc_read(data->regmap, data->chip_info->buf_read, + data->fifo_buffer, fifo_bytes); if (ret) goto renable_out; =20 for (i =3D 0; i < count; i++) { - __le16 *sam =3D &buffer[i * 3]; + __le16 *sam =3D &data->fifo_buffer[i * 3]; __le16 *chs; int bit; =20 @@ -732,10 +732,10 @@ static const struct iio_info kx022a_info =3D { static int kx022a_set_drdy_irq(struct kx022a_data *data, bool en) { if (en) - return regmap_set_bits(data->regmap, KX022A_REG_CNTL, + return regmap_set_bits(data->regmap, data->chip_info->cntl, KX022A_MASK_DRDY); =20 - return regmap_clear_bits(data->regmap, KX022A_REG_CNTL, + return regmap_clear_bits(data->regmap, data->chip_info->cntl, KX022A_MASK_DRDY); } =20 @@ -770,7 +770,7 @@ static int kx022a_fifo_disable(struct kx022a_data *data) if (ret) goto unlock_out; =20 - ret =3D regmap_clear_bits(data->regmap, KX022A_REG_BUF_CNTL2, + ret =3D regmap_clear_bits(data->regmap, data->chip_info->buf_cntl2, KX022A_MASK_BUF_EN); if (ret) goto unlock_out; @@ -779,6 +779,8 @@ static int kx022a_fifo_disable(struct kx022a_data *data) =20 kx022a_drop_fifo_contents(data); =20 + kfree(data->fifo_buffer); + return kx022a_turn_on_unlock(data); =20 unlock_out: @@ -801,6 +803,12 @@ static int kx022a_fifo_enable(struct kx022a_data *data) { int ret; =20 + data->fifo_buffer =3D kmalloc_array(data->chip_info->fifo_length, + KX022A_FIFO_SAMPLES_SIZE_BYTES, + GFP_KERNEL); + if (!data->fifo_buffer) + return -ENOMEM; + ret =3D kx022a_turn_off_lock(data); if (ret) return ret; @@ -811,7 +819,7 @@ static int kx022a_fifo_enable(struct kx022a_data *data) goto unlock_out; =20 /* Enable buffer */ - ret =3D regmap_set_bits(data->regmap, KX022A_REG_BUF_CNTL2, + ret =3D regmap_set_bits(data->regmap, data->chip_info->buf_cntl2, KX022A_MASK_BUF_EN); if (ret) goto unlock_out; @@ -857,7 +865,7 @@ static irqreturn_t kx022a_trigger_handler(int irq, void= *p) struct kx022a_data *data =3D iio_priv(idev); int ret; =20 - ret =3D regmap_bulk_read(data->regmap, KX022A_REG_XOUT_L, data->buffer, + ret =3D regmap_bulk_read(data->regmap, data->chip_info->xout_l, data->buf= fer, KX022A_FIFO_SAMPLES_SIZE_BYTES); if (ret < 0) goto err_read; @@ -905,7 +913,7 @@ static irqreturn_t kx022a_irq_thread_handler(int irq, v= oid *private) if (data->state & KX022A_STATE_FIFO) { int ok; =20 - ok =3D __kx022a_fifo_flush(idev, KX022A_FIFO_LENGTH, true); + ok =3D __kx022a_fifo_flush(idev, data->chip_info->fifo_length, true); if (ok > 0) ret =3D IRQ_HANDLED; } @@ -958,7 +966,7 @@ static int kx022a_chip_init(struct kx022a_data *data) int ret, val; =20 /* Reset the senor */ - ret =3D regmap_write(data->regmap, KX022A_REG_CNTL2, KX022A_MASK_SRST); + ret =3D regmap_write(data->regmap, data->chip_info->cntl2, KX022A_MASK_SR= ST); if (ret) return ret; =20 @@ -968,7 +976,7 @@ static int kx022a_chip_init(struct kx022a_data *data) */ msleep(1); =20 - ret =3D regmap_read_poll_timeout(data->regmap, KX022A_REG_CNTL2, val, + ret =3D regmap_read_poll_timeout(data->regmap, data->chip_info->cntl2, va= l, !(val & KX022A_MASK_SRST), KX022A_SOFT_RESET_WAIT_TIME_US, KX022A_SOFT_RESET_TOTAL_WAIT_TIME_US); @@ -978,14 +986,14 @@ static int kx022a_chip_init(struct kx022a_data *data) return ret; } =20 - ret =3D regmap_reinit_cache(data->regmap, &kx022a_regmap); + ret =3D regmap_reinit_cache(data->regmap, data->chip_info->regmap_config); if (ret) { dev_err(data->dev, "Failed to reinit reg cache\n"); return ret; } =20 /* set data res 16bit */ - ret =3D regmap_set_bits(data->regmap, KX022A_REG_BUF_CNTL2, + ret =3D regmap_set_bits(data->regmap, data->chip_info->buf_cntl2, KX022A_MASK_BRES16); if (ret) { dev_err(data->dev, "Failed to set data resolution\n"); @@ -995,7 +1003,31 @@ static int kx022a_chip_init(struct kx022a_data *data) return kx022a_prepare_irq_pin(data); } =20 -int kx022a_probe_internal(struct device *dev) +const struct kx022a_chip_info kx022a_chip_info =3D { + .name =3D "kx022-accel", + .regmap_config =3D &kx022a_regmap_config, + .channels =3D kx022a_channels, + .num_channels =3D ARRAY_SIZE(kx022a_channels), + .fifo_length =3D KX022A_FIFO_LENGTH, + .who =3D KX022A_REG_WHO, + .id =3D KX022A_ID, + .cntl =3D KX022A_REG_CNTL, + .cntl2 =3D KX022A_REG_CNTL2, + .odcntl =3D KX022A_REG_ODCNTL, + .buf_cntl1 =3D KX022A_REG_BUF_CNTL1, + .buf_cntl2 =3D KX022A_REG_BUF_CNTL2, + .buf_clear =3D KX022A_REG_BUF_CLEAR, + .buf_status1 =3D KX022A_REG_BUF_STATUS_1, + .buf_read =3D KX022A_REG_BUF_READ, + .inc1 =3D KX022A_REG_INC1, + .inc4 =3D KX022A_REG_INC4, + .inc5 =3D KX022A_REG_INC5, + .inc6 =3D KX022A_REG_INC6, + .xout_l =3D KX022A_REG_XOUT_L, +}; +EXPORT_SYMBOL_NS_GPL(kx022a_chip_info, IIO_KX022A); + +int kx022a_probe_internal(struct device *dev, const struct kx022a_chip_inf= o *chip_info) { static const char * const regulator_names[] =3D {"io-vdd", "vdd"}; struct iio_trigger *indio_trig; @@ -1022,6 +1054,7 @@ int kx022a_probe_internal(struct device *dev) return -ENOMEM; =20 data =3D iio_priv(idev); + data->chip_info =3D chip_info; =20 /* * VDD is the analog and digital domain voltage supply and @@ -1032,24 +1065,24 @@ int kx022a_probe_internal(struct device *dev) if (ret && ret !=3D -ENODEV) return dev_err_probe(dev, ret, "failed to enable regulator\n"); =20 - ret =3D regmap_read(regmap, KX022A_REG_WHO, &chip_id); + ret =3D regmap_read(regmap, chip_info->who, &chip_id); if (ret) return dev_err_probe(dev, ret, "Failed to access sensor\n"); =20 - if (chip_id !=3D KX022A_ID) + if (chip_id !=3D chip_info->id) dev_warn(dev, "unknown device 0x%x\n", chip_id); =20 irq =3D fwnode_irq_get_byname(fwnode, "INT1"); if (irq > 0) { - data->inc_reg =3D KX022A_REG_INC1; - data->ien_reg =3D KX022A_REG_INC4; + data->inc_reg =3D chip_info->inc1; + data->ien_reg =3D chip_info->inc4; } else { irq =3D fwnode_irq_get_byname(fwnode, "INT2"); if (irq <=3D 0) return dev_err_probe(dev, irq, "No suitable IRQ\n"); =20 - data->inc_reg =3D KX022A_REG_INC5; - data->ien_reg =3D KX022A_REG_INC6; + data->inc_reg =3D chip_info->inc5; + data->ien_reg =3D chip_info->inc6; } =20 data->regmap =3D regmap; @@ -1058,9 +1091,9 @@ int kx022a_probe_internal(struct device *dev) data->odr_ns =3D KX022A_DEFAULT_PERIOD_NS; mutex_init(&data->mutex); =20 - idev->channels =3D kx022a_channels; - idev->num_channels =3D ARRAY_SIZE(kx022a_channels); - idev->name =3D "kx022-accel"; + idev->channels =3D chip_info->channels; + idev->num_channels =3D chip_info->num_channels; + idev->name =3D chip_info->name; idev->info =3D &kx022a_info; idev->modes =3D INDIO_DIRECT_MODE | INDIO_BUFFER_SOFTWARE; idev->available_scan_masks =3D kx022a_scan_masks; diff --git a/drivers/iio/accel/kionix-kx022a.h b/drivers/iio/accel/kionix-k= x022a.h index 12424649d438..0e5026019213 100644 --- a/drivers/iio/accel/kionix-kx022a.h +++ b/drivers/iio/accel/kionix-kx022a.h @@ -76,7 +76,55 @@ =20 struct device; =20 -int kx022a_probe_internal(struct device *dev); -extern const struct regmap_config kx022a_regmap; +/** + * struct kx022a_chip_info - Kionix accelerometer chip specific information + * + * @name: name of the device + * @regmap_config: pointer to register map configuration + * @channels: pointer to iio_chan_spec array + * @num_channels: number of iio_chan_spec channels + * @fifo_length: number of 16-bit samples in a full buffer + * @who: WHO_AM_I register + * @id: WHO_AM_I register value + * @cntl: control register 1 + * @cntl2: control register 2 + * @odcntl: output data control register + * @buf_cntl1: buffer control register 1 + * @buf_cntl2: buffer control register 2 + * @buf_clear: buffer clear register + * @buf_status1: buffer status register 1 + * @buf_read: buffer read register + * @inc1: interrupt control register 1 + * @inc4: interrupt control register 4 + * @inc5: interrupt control register 5 + * @inc6: interrupt control register 6 + * @xout_l: x-axis output least significant byte + */ +struct kx022a_chip_info { + const char *name; + const struct regmap_config *regmap_config; + const struct iio_chan_spec *channels; + unsigned int num_channels; + unsigned int fifo_length; + u8 who; + u8 id; + u8 cntl; + u8 cntl2; + u8 odcntl; + u8 buf_cntl1; + u8 buf_cntl2; + u8 buf_clear; + u8 buf_status1; + u8 buf_read; + u8 inc1; + u8 inc4; + u8 inc5; + u8 inc6; + u8 xout_l; +}; + +int kx022a_probe_internal(struct device *dev, const struct kx022a_chip_inf= o *chip_info); + +extern const struct kx022a_chip_info kx022a_chip_info; =20 #endif --=20 2.30.2