iio: accel: Add support for Kionix/ROHM KX132 accelerometer
Subsystems (3)
cover iio: accel: Add support for Kionix/ROHM KX132 accelerometer
KX132 accelerometer is a sensor which:
- supports G-ranges of (+/-) 2, 4, 8, and 16G
- can be connected to I2C or SPI
- has internal HW FIFO buffer
- supports various ODRs (output data rates)
The KX132 accelerometer is very similair to the KX022A.
One key difference is number of bits to report the number of data bytes that have been stored in the sample buffer: 8 bits for KX022A vs 10 bits for KX132.
A complete list of differences is listed in [1]
[1] https://kionixfs.azureedge.net/en/document/AN112-Transitioning-to-KX132-1211-Accelerometer.pdf1
Mehdi Djait (3):
dt-bindings: iio: Add KX132 accelerometer
iio: accel: kionix-kx022a: Add chip_info structure
iio: accel: Add support for Kionix/ROHM KX132 accelerometer
.../bindings/iio/accel/kionix,kx022a.yaml | 13 +- drivers/iio/accel/kionix-kx022a-i2c.c | 21 +- drivers/iio/accel/kionix-kx022a-spi.c | 24 +- drivers/iio/accel/kionix-kx022a.c | 413 +++++++++++------- drivers/iio/accel/kionix-kx022a.h | 181 +++++++- 5 files changed, 464 insertions(+), 188 deletions(-)
Signature · 1 line
2.30.2
PATCH 1/3 dt-bindings: iio: Add KX132 accelerometer
Extend the kionix,kx022a.yaml file to support the
kx132 device
--- .../bindings/iio/accel/kionix,kx022a.yaml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
Documentation/devicetree/bindings/iio/accel/kionix,kx022a.yaml +8 -5
@@ -4,19 +4,22 @@ $id: http://devicetree.org/schemas/iio/accel/kionix,kx022a.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: ROHM/Kionix KX022A Accelerometer +title: ROHM/Kionix KX022A and KX132 Accelerometers maintainers: - Matti Vaittinen <[email protected]> description: | - KX022A is a 3-axis accelerometer supporting +/- 2G, 4G, 8G and 16G ranges, - output data-rates from 0.78Hz to 1600Hz and a hardware-fifo buffering. - KX022A can be accessed either via I2C or SPI. + KX022A and KX132 are 3-axis accelerometers supporting +/- 2G, 4G, 8G and + 16G ranges, output data-rates from 0.78Hz to 1600Hz and a hardware-fifo + buffering. + KX022A and KX132 can be accessed either via I2C or SPI. properties: compatible: - const: kionix,kx022a + enum: + - kionix,kx022a + - kionix,kx132 reg: maxItems: 1
Signature · 1 line
2.30.2
Jonathan Cameron
maintainerRe: [PATCH 1/3] dt-bindings: iio: Add KX132 accelerometer
Quoted 4 lines · On Fri, 17 Mar 2023 00:48:35 +0100 Mehdi Djait <[email protected]> wrote:
Extend the kionix,kx022a.yaml file to support the
kx132 deviceSigned-off-by Mehdi Djait <[email protected]>
Pins and power supplies etc all look the same to me so indeed seems that you have covered all that is needed. One small comment inline and I think Matti's point about more specific compatibles probably needs to be taken into account if there are known variants.
Kionix has done this for a long time. I remember that fun with the kxsd9 lots of years back - that had lots of subtle variants.
Quoted 14 lines
--- .../bindings/iio/accel/kionix,kx022a.yaml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)Documentation/devicetree/bindings/iio/accel/kionix,kx022a.yaml +1
-1@@ -4,19 +4,22 @@ $id: http://devicetree.org/schemas/iio/accel/kionix,kx022a.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: ROHM/Kionix KX022A Accelerometer +title: ROHM/Kionix KX022A and KX132 Accelerometers
Documentation/devicetree/bindings/iio/accel/kionix,kx022a.yaml line 14
Quoted 10 lines
Documentation/devicetree/bindings/iio/accel/kionix,kx022a.yaml +2
-3maintainers: - Matti Vaittinen <[email protected]> description: | - KX022A is a 3-axis accelerometer supporting +/- 2G, 4G, 8G and 16G ranges, - output data-rates from 0.78Hz to 1600Hz and a hardware-fifo buffering. - KX022A can be accessed either via I2C or SPI. + KX022A and KX132 are 3-axis accelerometers supporting +/- 2G, 4G, 8G and + 16G ranges, output data-rates from 0.78Hz to 1600Hz and a hardware-fifo
This may be one of those 'there are many versions' of the chip issues, but the random datasheet I got via digikey (kionix website was slow and I'm impatient) has max as 25600Hz for the KX132-1211.
No particular reason the sampling rates need to be in this description so if they are different I'd just remove the mention or just say "variable output data-rates"
Quoted 12 lines
Documentation/devicetree/bindings/iio/accel/kionix,kx022a.yaml +5
-1+ buffering. + KX022A and KX132 can be accessed either via I2C or SPI. properties: compatible: - const: kionix,kx022a + enum: + - kionix,kx022a + - kionix,kx132 reg: maxItems: 1
Re: [PATCH 1/3] dt-bindings: iio: Add KX132 accelerometer
Hello Jonathan,
Quoted 45 lines · Jonathan Cameron
Quoted 4 lines · On Fri, 17 Mar 2023 00:48:35 +0100 Mehdi Djait <[email protected]> wrote:
Extend the kionix,kx022a.yaml file to support the
kx132 deviceSigned-off-by Mehdi Djait <[email protected]>Pins and power supplies etc all look the same to me so indeed seems that you have covered all that is needed. One small comment inline and I think Matti's point about more specific compatibles probably needs to be taken into account if there are known variants.
Kionix has done this for a long time. I remember that fun with the kxsd9 lots of years back - that had lots of subtle variants.
Quoted 14 lines
--- .../bindings/iio/accel/kionix,kx022a.yaml | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)Documentation/devicetree/bindings/iio/accel/kionix,kx022a.yaml +1
-1@@ -4,19 +4,22 @@ $id: http://devicetree.org/schemas/iio/accel/kionix,kx022a.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: ROHM/Kionix KX022A Accelerometer +title: ROHM/Kionix KX022A and KX132 AccelerometersDocumentation/devicetree/bindings/iio/accel/kionix,kx022a.yaml line 14
Quoted 10 lines
Documentation/devicetree/bindings/iio/accel/kionix,kx022a.yaml +2
-3maintainers: - Matti Vaittinen <[email protected]> description: | - KX022A is a 3-axis accelerometer supporting +/- 2G, 4G, 8G and 16G ranges, - output data-rates from 0.78Hz to 1600Hz and a hardware-fifo buffering. - KX022A can be accessed either via I2C or SPI. + KX022A and KX132 are 3-axis accelerometers supporting +/- 2G, 4G, 8G and + 16G ranges, output data-rates from 0.78Hz to 1600Hz and a hardware-fifoThis may be one of those 'there are many versions' of the chip issues, but the random datasheet I got via digikey (kionix website was slow and I'm impatient) has max as 25600Hz for the KX132-1211.
Quoted 3 lines
No particular reason the sampling rates need to be in this description so if they are different I'd just remove the mention or just say "variable output data-rates"
Yes indeed, the max frequency is different and the max frequency supported in the driver is 200Hz anyway.
Removing the values of samling rates is best here. I will change it in v2.
--
Kind Regards
Mehdi Djait
PATCH 2/3 iio: accel: kionix-kx022a: Add chip_info structure
In reply to Mehdi DjaitRefactor the kx022a driver implementation to make it more generic and extensible.
Add the chip_info structure will to the driver's private data to hold all the device specific infos.
Move the enum, struct and constants definitions to the header file.
--- drivers/iio/accel/kionix-kx022a-i2c.c | 19 +- drivers/iio/accel/kionix-kx022a-spi.c | 22 +- drivers/iio/accel/kionix-kx022a.c | 289 ++++++++++++-------------- drivers/iio/accel/kionix-kx022a.h | 128 ++++++++++-- 4 files changed, 274 insertions(+), 184 deletions(-)
drivers/iio/accel/kionix-kx022a-i2c.c +16 -3
@@ -15,23 +15,35 @@static int kx022a_i2c_probe (struct i2c_client *i2c) {struct device *dev = &i2c->dev; +struct kx022a_chip_info *chip_info;struct regmap *regmap; +const struct i2c_device_id *id =i2c_client_get_device_id (i2c);if (!i2c->irq) {dev_err (dev,"No IRQ configured\n" );return -EINVAL ; } - regmap =devm_regmap_init_i2c (i2c, &kx022a_regmap); + chip_info =device_get_match_data (&i2c->dev); +if (!chip_info) + chip_info = (const struct kx022a_chip_info *) id->driver_data; + + regmap =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" ); -return kx022a_probe_internal (dev); +return kx022a_probe_internal (dev, chip_info); } +static const struct i2c_device_id kx022a_i2c_id[] = { + { .name ="kx022a" , .driver_data = (kernel_ulong_t)&kx_chip_info[KX022A ] }, + { } +}; +MODULE_DEVICE_TABLE (i2c, kx022a_i2c_id); +static const struct of_device_id kx022a_of_match[] = { - { .compatible ="kionix,kx022a" , }, + { .compatible ="kionix,kx022a" , .data = &kx_chip_info[KX022A ] }, { } };MODULE_DEVICE_TABLE (of, kx022a_of_match);
@@ -42,6 +54,7 @@ static struct i2c_driver kx022a_i2c_driver = { .of_match_table = kx022a_of_match, }, .probe_new = kx022a_i2c_probe, + .id_table = kx022a_i2c_id, };module_i2c_driver (kx022a_i2c_driver);
drivers/iio/accel/kionix-kx022a-spi.c +14 -8
@@ -15,40 +15,46 @@static int kx022a_spi_probe (struct spi_device *spi) {struct device *dev = &spi->dev; +struct kx022a_chip_info *chip_info;struct regmap *regmap; +const struct spi_device_id *id =spi_get_device_id (spi);if (!spi->irq) {dev_err (dev,"No IRQ configured\n" );return -EINVAL ; } - regmap =devm_regmap_init_spi (spi, &kx022a_regmap); + chip_info =device_get_match_data (&spi->dev); +if (!chip_info) + chip_info = (const struct kx022a_chip_info *) id->driver_data; + + regmap =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" ); -return kx022a_probe_internal (dev); +return kx022a_probe_internal (dev, chip_info); } -static const struct spi_device_id kx022a_id[] = { - {"kx022a" }, +static const struct spi_device_id kx022a_spi_id[] = { + { .name ="kx022a" , .driver_data = (kernel_ulong_t)&kx_chip_info[KX022A ] }, { } }; -MODULE_DEVICE_TABLE (spi, kx022a_id); +MODULE_DEVICE_TABLE (spi, kx022a_spi_id);static const struct of_device_id kx022a_of_match[] = { - { .compatible ="kionix,kx022a" , }, + { .compatible ="kionix,kx022a" , .data = &kx_chip_info[KX022A ] }, { } };MODULE_DEVICE_TABLE (of, kx022a_of_match);static struct spi_driver kx022a_spi_driver = { .driver = { - .name ="kx022a-spi" , + .name ="kx022a-spi" , .of_match_table = kx022a_of_match, }, .probe = kx022a_spi_probe, - .id_table = kx022a_id, + .id_table = kx022a_spi_id, };module_spi_driver (kx022a_spi_driver);
drivers/iio/accel/kionix-kx022a.c +135 -154
560 lines not on this page · raw message
drivers/iio/accel/kionix-kx022a.h +109 -19
171 lines not on this page · raw message
Signature · 1 line
2.30.2
kernel test robot
build botRe: [PATCH 2/3] iio: accel: kionix-kx022a: Add chip_info structure
Thank you for the patch! Perhaps something to improve:
Hi Mehdi,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on jic23-iio/togreg]
[also build test WARNING on next-20230316]
[cannot apply to linus/master v6.3-rc2]
[If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Mehdi-Djait/dt-bindings-iio-Add-KX132-accelerometer/20230317-075056 base: https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git togreg patch link: https://lore.kernel.org/r/3ddca10a4c03c3a64afb831cc9dd1e01fe89d305.1679009443.git.mehdi.djait.k%40gmail.com patch subject: [PATCH 2/3] iio: accel: kionix-kx022a: Add chip_info structure config: m68k-allyesconfig (https://download.01.org/0day-ci/archive/20230317/[email protected]/config) compiler: m68k-linux-gcc (GCC) 12.1.0
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/40c75341c42d0e5bea5d73961202978a4be41cd2
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Mehdi-Djait/dt-bindings-iio-Add-KX132-accelerometer/20230317-075056 git checkout 40c75341c42d0e5bea5d73961202978a4be41cd2
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=m68k olddefconfig COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross W=1 O=build_dir ARCH=m68k SHELL=/bin/bash drivers/iio/
If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <[email protected]>
| Link: https://lore.kernel.org/oe-kbuild-all/[email protected]/
All warnings (new ones prefixed by >>):
drivers/iio/accel/kionix-kx022a.c: In function '__kx022a_fifo_flush':
>> drivers/iio/accel/kionix-kx022a.c:598:9: warning: ISO C90 forbids variable length array 'buffer' [-Wvla]
598 | __le16 buffer[data->chip_info->fifo_length * 3];
| ^~~~~~
--
drivers/iio/accel/kionix-kx022a-i2c.c: In function 'kx022a_i2c_probe':
>> drivers/iio/accel/kionix-kx022a-i2c.c:27:19: warning: assignment discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
27 | chip_info = device_get_match_data(&i2c->dev);
| ^
drivers/iio/accel/kionix-kx022a-i2c.c:29:27: warning: assignment discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
29 | chip_info = (const struct kx022a_chip_info *) id->driver_data;
| ^
--
drivers/iio/accel/kionix-kx022a-spi.c: In function 'kx022a_spi_probe':
>> drivers/iio/accel/kionix-kx022a-spi.c:27:19: warning: assignment discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
27 | chip_info = device_get_match_data(&spi->dev);
| ^
drivers/iio/accel/kionix-kx022a-spi.c:29:27: warning: assignment discards 'const' qualifier from pointer target type [-Wdiscarded-qualifiers]
29 | chip_info = (const struct kx022a_chip_info *) id->driver_data;
| ^vim +/buffer +598 drivers/iio/accel/kionix-kx022a.c
593
594 static int __kx022a_fifo_flush(struct iio_dev *idev, unsigned int samples,
595 bool irq)
596 {
597 struct kx022a_data *data = iio_priv(idev);
> 598 __le16 buffer[data->chip_info->fifo_length * 3];
599 uint64_t sample_period;
600 int count, fifo_bytes;
601 bool renable = false;
602 int64_t tstamp;
603 int ret, i;
604
605 fifo_bytes = kx022a_get_fifo_bytes(data);
606 count = fifo_bytes / KX_FIFO_SAMPLES_SIZE_BYTES;
607 if (!count)
608 return 0;
609
610 /*
611 * If we are being called from IRQ handler we know the stored timestamp
612 * is fairly accurate for the last stored sample. Otherwise, if we are
613 * called as a result of a read operation from userspace and hence
614 * before the watermark interrupt was triggered, take a timestamp
615 * now. We can fall anywhere in between two samples so the error in this
616 * case is at most one sample period.
617 */
618 if (!irq) {
619 /*
620 * We need to have the IRQ disabled or we risk of messing-up
621 * the timestamps. If we are ran from IRQ, then the
622 * IRQF_ONESHOT has us covered - but if we are ran by the
623 * user-space read we need to disable the IRQ to be on a safe
624 * side. We do this usng synchronous disable so that if the
625 * IRQ thread is being ran on other CPU we wait for it to be
626 * finished.
627 */
628 disable_irq(data->irq);
629 renable = true;
630
631 data->old_timestamp = data->timestamp;
632 data->timestamp = iio_get_time_ns(idev);
633 }
634
635 /*
636 * Approximate timestamps for each of the sample based on the sampling
637 * frequency, timestamp for last sample and number of samples.
638 *
639 * We'd better not use the current bandwidth settings to compute the
640 * sample period. The real sample rate varies with the device and
641 * small variation adds when we store a large number of samples.
642 *
643 * To avoid this issue we compute the actual sample period ourselves
644 * based on the timestamp delta between the last two flush operations.
645 */
646 if (data->old_timestamp) {
647 sample_period = data->timestamp - data->old_timestamp;
648 do_div(sample_period, count);
649 } else {
650 sample_period = data->odr_ns;
651 }
652 tstamp = data->timestamp - (count - 1) * sample_period;
653
654 if (samples && count > samples) {
655 /*
656 * Here we leave some old samples to the buffer. We need to
657 * adjust the timestamp to match the first sample in the buffer
658 * or we will miscalculate the sample_period at next round.
659 */
660 data->timestamp -= (count - samples) * sample_period;
661 count = samples;
662 }
663
664 fifo_bytes = count * KX_FIFO_SAMPLES_SIZE_BYTES;
665 ret = regmap_noinc_read(data->regmap, data->chip_info->buf_read,
666 &buffer[0], fifo_bytes);
667 if (ret)
668 goto renable_out;
669
670 for (i = 0; i < count; i++) {
671 __le16 *sam = &buffer[i * 3];
672 __le16 *chs;
673 int bit;
674
675 chs = &data->scan.channels[0];
676 for_each_set_bit(bit, idev->active_scan_mask, AXIS_MAX)
677 chs[bit] = sam[bit];
678
679 iio_push_to_buffers_with_timestamp(idev, &data->scan, tstamp);
680
681 tstamp += sample_period;
682 }
683
684 ret = count;
685
686 renable_out:
687 if (renable)
688 enable_irq(data->irq);
689
690 return ret;
691 }
692
Signature · 2 lines
0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests
kernel test robot
build botRe: [PATCH 2/3] iio: accel: kionix-kx022a: Add chip_info structure
In reply to Mehdi DjaitThank you for the patch! Yet something to improve:
Hi Mehdi,
Thank you for the patch! Yet something to improve:
[auto build test ERROR on jic23-iio/togreg]
[also build test ERROR on next-20230317]
[cannot apply to linus/master v6.3-rc2]
[If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Mehdi-Djait/dt-bindings-iio-Add-KX132-accelerometer/20230317-075056 base: https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git togreg patch link: https://lore.kernel.org/r/3ddca10a4c03c3a64afb831cc9dd1e01fe89d305.1679009443.git.mehdi.djait.k%40gmail.com patch subject: [PATCH 2/3] iio: accel: kionix-kx022a: Add chip_info structure config: i386-randconfig-a011-20230313 (https://download.01.org/0day-ci/archive/20230317/[email protected]/config) compiler: clang version 14.0.6 (https://github.com/llvm/llvm-project f28c006a5895fc0e329fe15fead81e37457cb1d1)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross
# https://github.com/intel-lab-lkp/linux/commit/40c75341c42d0e5bea5d73961202978a4be41cd2
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Mehdi-Djait/dt-bindings-iio-Add-KX132-accelerometer/20230317-075056 git checkout 40c75341c42d0e5bea5d73961202978a4be41cd2
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=i386 olddefconfig COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross W=1 O=build_dir ARCH=i386 SHELL=/bin/bash drivers/iio/accel/
If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <[email protected]>
| Link: https://lore.kernel.org/oe-kbuild-all/[email protected]/
All error/warnings (new ones prefixed by >>):
>> drivers/iio/accel/kionix-kx022a-i2c.c:27:12: error: assigning to 'struct kx022a_chip_info *' from 'const void *' discards qualifiers [-Werror,-Wincompatible-pointer-types-discards-qualifiers]
chip_info = device_get_match_data(&i2c->dev);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/iio/accel/kionix-kx022a-i2c.c:29:13: error: assigning to 'struct kx022a_chip_info *' from 'const struct kx022a_chip_info *' discards qualifiers [-Werror,-Wincompatible-pointer-types-discards-qualifiers]
chip_info = (const struct kx022a_chip_info *) id->driver_data;
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 errors generated.
--
>> drivers/iio/accel/kionix-kx022a.c:598:16: warning: variable length array used [-Wvla]
__le16 buffer[data->chip_info->fifo_length * 3];
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1 warning generated.
--
>> drivers/iio/accel/kionix-kx022a-spi.c:27:12: error: assigning to 'struct kx022a_chip_info *' from 'const void *' discards qualifiers [-Werror,-Wincompatible-pointer-types-discards-qualifiers]
chip_info = device_get_match_data(&spi->dev);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>> drivers/iio/accel/kionix-kx022a-spi.c:29:13: error: assigning to 'struct kx022a_chip_info *' from 'const struct kx022a_chip_info *' discards qualifiers [-Werror,-Wincompatible-pointer-types-discards-qualifiers]
chip_info = (const struct kx022a_chip_info *) id->driver_data;
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~2 errors generated.
vim +27 drivers/iio/accel/kionix-kx022a-i2c.c
14
15 static int kx022a_i2c_probe(struct i2c_client *i2c)
16 {
17 struct device *dev = &i2c->dev;
18 struct kx022a_chip_info *chip_info;
19 struct regmap *regmap;
20 const struct i2c_device_id *id = i2c_client_get_device_id(i2c);
21
22 if (!i2c->irq) {
23 dev_err(dev, "No IRQ configured\n");
24 return -EINVAL;
25 }
26
> 27 chip_info = device_get_match_data(&i2c->dev);
28 if (!chip_info)
> 29 chip_info = (const struct kx022a_chip_info *) id->driver_data;
30
31 regmap = devm_regmap_init_i2c(i2c, chip_info->regmap_config);
32 if (IS_ERR(regmap))
33 return dev_err_probe(dev, PTR_ERR(regmap),
34 "Failed to initialize Regmap\n");
35
36 return kx022a_probe_internal(dev, chip_info);
37 }
38 Signature · 2 lines
0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests
Re: [PATCH 2/3] iio: accel: kionix-kx022a: Add chip_info structure
In reply to Mehdi DjaitQuoted 6 lines · Mehdi Djait
Refactor the kx022a driver implementation to make it more generic and extensible.
Add thechip_infostructure will to the driver's private data to hold all the device specific infos.
Move the enum, struct and constants definitions to the header file.
Please, compile and test before sending.
...
drivers/iio/accel/kionix-kx022a-spi.c line 55
Quoted 5 lines
drivers/iio/accel/kionix-kx022a-spi.c +1
-1.driver = { - .name = "kx022a-spi", + .name = "kx022a-spi", .of_match_table = kx022a_of_match, },
What was changed here?
...
drivers/iio/accel/kionix-kx022a-spi.c line 57
Quoted 2 lines
drivers/iio/accel/kionix-kx022a-spi.c +1
-1- .id_table = kx022a_id, + .id_table = kx022a_spi_id,
Why do we need this change?
...
drivers/iio/accel/kionix-kx022a.c int kx022a_probe_internal(struct device *dev) · line 1097
Quoted 3 lines
drivers/iio/accel/kionix-kx022a.c +1
-1- name =devm_kasprintf (data->dev,GFP_KERNEL ,"%s-kx022a" , + name =devm_kasprintf (data->dev,GFP_KERNEL ,"%s-accel" ,dev_name (data->dev));
Shouldn't you use the name from chip info?
...
drivers/iio/accel/kionix-kx022a.h line 38
Quoted 3 lines
drivers/iio/accel/kionix-kx022a.h +3
-0+#define KX_MASK_BRES16 BIT(6) + +
One blank line is enough.
Quoted 2 lines
#define
KX022A_REG_WHO0x0f
#defineKX022A_ID0xc8
Signature · 2 lines
With Best Regards, Andy Shevchenko
Re: [PATCH 2/3] iio: accel: kionix-kx022a: Add chip_info structure
Hi Andy,
Quoted 9 lines · Andy Shevchenko
Quoted 6 lines · Mehdi Djait
Refactor the kx022a driver implementation to make it more generic and extensible.
Add thechip_infostructure will to the driver's private data to hold all the device specific infos.
Move the enum, struct and constants definitions to the header file.Please, compile and test before sending.
My bad, I ignored the warnings... I will fix it.
Quoted 10 lines
...
drivers/iio/accel/kionix-kx022a-spi.c line 55
Quoted 5 lines
drivers/iio/accel/kionix-kx022a-spi.c +1
-1.driver = { - .name = "kx022a-spi", + .name = "kx022a-spi", .of_match_table = kx022a_of_match, },What was changed here?
Nothing. I will fix it
Quoted 8 lines
...
drivers/iio/accel/kionix-kx022a-spi.c line 57
Quoted 2 lines
drivers/iio/accel/kionix-kx022a-spi.c +1
-1- .id_table = kx022a_id, + .id_table = kx022a_spi_id,Why do we need this change?
For consistency:
i2c: .id_table = kx022a_i2c_id,
spi: .id_table = kx022a_spi_id,
Quoted 7 lines
...
drivers/iio/accel/kionix-kx022a.c int kx022a_probe_internal(struct device *dev) · line 1097
Quoted 3 lines
drivers/iio/accel/kionix-kx022a.c +1
-1- name =devm_kasprintf (data->dev,GFP_KERNEL ,"%s-kx022a" , + name =devm_kasprintf (data->dev,GFP_KERNEL ,"%s-accel" ,dev_name (data->dev));Shouldn't you use the name from chip info?
I can use the name from chip info. dev_name(data->dev) is the original implementation
Quoted 8 lines
...
drivers/iio/accel/kionix-kx022a.h line 38
Quoted 3 lines
drivers/iio/accel/kionix-kx022a.h +3
-0+#define KX_MASK_BRES16 BIT(6) + +One blank line is enough.
I will change it in v2
--
Kind Regards
Mehdi Djait
Jonathan Cameron
maintainerRe: [PATCH 2/3] iio: accel: kionix-kx022a: Add chip_info structure
In reply to Mehdi DjaitQuoted 6 lines · On Fri, 17 Mar 2023 00:48:36 +0100 Mehdi Djait <[email protected]> wrote:
Refactor the kx022a driver implementation to make it more generic and extensible.
Add thechip_infostructure will to the driver's private data to hold all the device specific infos.
Move the enum, struct and constants definitions to the header file.
You also introduce an i2c_device_id table
Without that I think module autoloading will be broken anyway so that's definitely a good thing to add.
A few comments inline. Mostly around reducing the name changes. Wild cards (or simply shorted 'generic' prefixes like KX_) almost always bite back in the long run. Hence we generally just try to name things after the first device that they were relevant to.
Thanks,
Jonathan
Quoted 20 lines
Signed-off-by Mehdi Djait <[email protected]>--- drivers/iio/accel/kionix-kx022a-i2c.c | 19 +- drivers/iio/accel/kionix-kx022a-spi.c | 22 +- drivers/iio/accel/kionix-kx022a.c | 289 ++++++++++++-------------- drivers/iio/accel/kionix-kx022a.h | 128 ++++++++++-- 4 files changed, 274 insertions(+), 184 deletions(-)drivers/iio/accel/kionix-kx022a-i2c.c +2
-0@@ -15,23 +15,35 @@static int kx022a_i2c_probe (struct i2c_client *i2c) {struct device *dev = &i2c->dev; +struct kx022a_chip_info *chip_info;struct regmap *regmap; +const struct i2c_device_id *id =i2c_client_get_device_id (i2c);
drivers/iio/accel/kionix-kx022a-i2c.c line 29
Quoted 10 lines
drivers/iio/accel/kionix-kx022a-i2c.c +3
-1if (!i2c->irq) {dev_err (dev,"No IRQ configured\n" );return -EINVAL ; } - regmap =devm_regmap_init_i2c (i2c, &kx022a_regmap); + chip_info =device_get_match_data (&i2c->dev); +if (!chip_info) + chip_info = (const struct kx022a_chip_info *) id->driver_data;
Get id only if the device_get_match_data() fails.
if (!chip_info) {
const struct i2c_device_id *id = i2c_client_get_device_id(i2c);
chip_info = (const struct kx...)
} drivers/iio/accel/kionix-kx022a-i2c.c line 40
Quoted 12 lines
drivers/iio/accel/kionix-kx022a-i2c.c +5
-1+ + regmap =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" ); -return kx022a_probe_internal (dev); +return kx022a_probe_internal (dev, chip_info); } +static const struct i2c_device_id kx022a_i2c_id[] = { + { .name ="kx022a" , .driver_data = (kernel_ulong_t)&kx_chip_info[KX022A ] },
If there are a small set and we aren't ever going to index the chip_info structure we might be better off not bothering with the enum and instead using a separate instance of the structure for each chip.
.driver_data = (kernel_ulong_t)&kx022a_chip_info,
etc.
Quoted 28 lines
drivers/iio/accel/kionix-kx022a-i2c.c +6
-1+ { } +}; +MODULE_DEVICE_TABLE (i2c, kx022a_i2c_id); +static const struct of_device_id kx022a_of_match[] = { - { .compatible ="kionix,kx022a" , }, + { .compatible ="kionix,kx022a" , .data = &kx_chip_info[KX022A ] }, { } };MODULE_DEVICE_TABLE (of, kx022a_of_match);@@ -42,6 +54,7 @@ static struct i2c_driver kx022a_i2c_driver = { .of_match_table = kx022a_of_match, }, .probe_new = kx022a_i2c_probe, + .id_table = kx022a_i2c_id, };module_i2c_driver (kx022a_i2c_driver);drivers/iio/accel/kionix-kx022a-spi.c +1
-0@@ -15,40 +15,46 @@static int kx022a_spi_probe (struct spi_device *spi) {struct device *dev = &spi->dev; +struct kx022a_chip_info *chip_info;struct regmap *regmap;
drivers/iio/accel/kionix-kx022a-spi.c line 28
Quoted 10 lines
drivers/iio/accel/kionix-kx022a-spi.c +3
-1+const struct spi_device_id *id =spi_get_device_id (spi);if (!spi->irq) {dev_err (dev,"No IRQ configured\n" );return -EINVAL ; } - regmap =devm_regmap_init_spi (spi, &kx022a_regmap); + chip_info =device_get_match_data (&spi->dev); +if (!chip_info)
As above. Get the id only if we are going to use it.
Quoted 44 lines
drivers/iio/accel/kionix-kx022a-spi.c +10
-7+ chip_info = (const struct kx022a_chip_info *) id->driver_data; + + regmap =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" ); -return kx022a_probe_internal (dev); +return kx022a_probe_internal (dev, chip_info); } -static const struct spi_device_id kx022a_id[] = { - {"kx022a" }, +static const struct spi_device_id kx022a_spi_id[] = { + { .name ="kx022a" , .driver_data = (kernel_ulong_t)&kx_chip_info[KX022A ] }, { } }; -MODULE_DEVICE_TABLE (spi, kx022a_id); +MODULE_DEVICE_TABLE (spi, kx022a_spi_id);static const struct of_device_id kx022a_of_match[] = { - { .compatible ="kionix,kx022a" , }, + { .compatible ="kionix,kx022a" , .data = &kx_chip_info[KX022A ] }, { } };MODULE_DEVICE_TABLE (of, kx022a_of_match);static struct spi_driver kx022a_spi_driver = { .driver = { - .name ="kx022a-spi" , + .name ="kx022a-spi" , .of_match_table = kx022a_of_match, }, .probe = kx022a_spi_probe, - .id_table = kx022a_id, + .id_table = kx022a_spi_id, };module_spi_driver (kx022a_spi_driver);drivers/iio/accel/kionix-kx022a.c +0
-0@@ -26,29 +26,7 @@
..
drivers/iio/accel/kionix-kx022a.c static const struct iio_chan_spec_ext_info kx022a_ext_info[] = { · line 161
Quoted 11 lines
drivers/iio/accel/kionix-kx022a.c +2
-2-#define KX022A_ACCEL_CHAN (axis, index) \ +#define KX022A_ACCEL_CHAN (axis, index, device) \ { \ .type = IIO_ACCEL, \ .modified = 1, \@@ -220,7 +158,7 @@ static const struct iio_chan_spec_ext_info kx022a_ext_info[] = { BIT(IIO_CHAN_INFO_SCALE) | \ BIT(IIO_CHAN_INFO_SAMP_FREQ), \ .ext_info = kx022a_ext_info, \ - .address = KX022A_REG_##axis##OUT_L, \ + .address = device##_REG_##axis##OUT_L, \
I'm not particularly keen on this because it is hard to search for. It wasn't great before, but it's getting worse.
Perhaps just put the fully defined address in as a parameter to the macro.
Quoted 47 lines
drivers/iio/accel/kionix-kx022a.c +30
-3.scan_index = index, \ .scan_type = { \ .sign = 's', \@@ -231,9 +169,9 @@ static const struct iio_chan_spec_ext_info kx022a_ext_info[] = { }static const struct iio_chan_spec kx022a_channels[] = { -KX022A_ACCEL_CHAN (X ,0 ), -KX022A_ACCEL_CHAN (Y ,1 ), -KX022A_ACCEL_CHAN (Z ,2 ), +KX022A_ACCEL_CHAN (X ,0 ,KX022A ), +KX022A_ACCEL_CHAN (Y ,1 ,KX022A ), +KX022A_ACCEL_CHAN (Z ,2 ,KX022A ),IIO_CHAN_SOFT_TIMESTAMP (3 ), };@@ -286,6 +224,34 @@ static const int kx022a_scale_table[][2] = { { 4788, 403320 }, }; +const struct kx022a_chip_info kx_chip_info[] = { + [KX022A ] = { + .name ="kx022a" , + .type =KX022A , + .regmap_config = &kx022a_regmap_config, + .channels = kx022a_channels, + .num_channels =ARRAY_SIZE (kx022a_channels), + .fifo_length =KX022A_FIFO_LENGTH , + .who =KX022A_REG_WHO , + .id =KX022A_ID , + .cntl =KX022A_REG_CNTL , + .cntl2 =KX022A_REG_CNTL2 , + .odcntl =KX022A_REG_ODCNTL , + .buf_cntl1 =KX022A_REG_BUF_CNTL1 , + .buf_cntl2 =KX022A_REG_BUF_CNTL2 , + .buf_clear =KX022A_REG_BUF_CLEAR , + .buf_status1 =KX022A_REG_BUF_STATUS_1 , + .buf_smp_lvl_mask =KX022A_MASK_BUF_SMP_LVL , + .buf_read =KX022A_REG_BUF_READ , + .inc1 =KX022A_REG_INC1 , + .inc4 =KX022A_REG_INC4 , + .inc5 =KX022A_REG_INC5 , + .inc6 =KX022A_REG_INC6 , + .xout_l =KX022A_REG_XOUT_L , + }, +}; +EXPORT_SYMBOL_NS_GPL (kx_chip_info,IIO_KX022A );
...
Quoted 2 lines
+static int
kx022a_get_fifo_bytes(struct kx022a_data *data)
Factoring this out looks like an unrelated change. Fine to do it but should be a separate patch.
If you need a device type specific version of this add a function pointer to your chip_info structure. Given you don't add one for the next patch I think this is just refactoring and so fine to do, but needs to be in a separate patch from this one with a description that says why you are doing it.
Quoted 72 lines
drivers/iio/accel/kionix-kx022a.c +34
-17+{ +struct device *dev =regmap_get_device (data->regmap); +__le16 buf_status; +int ret, fifo_bytes; + + ret =regmap_bulk_read (data->regmap, data->chip_info->buf_status1, &buf_status,sizeof (buf_status)); +if (ret) { +dev_err (dev,"Error reading buffer status\n" ); +return ret; + } + + buf_status &= data->chip_info->buf_smp_lvl_mask; + fifo_bytes =le16_to_cpu (buf_status); + +/* +* The KX022A has FIFO which can store 43 samples of HiRes data from 2 +* channels. This equals to 43 (samples) * 3 (channels) * 2 (bytes/sample) to +* 258 bytes of sample data. The quirk to know is that the amount of bytes in +* the FIFO is advertised via 8 bit register (max value 255). The thing to note +* is that full 258 bytes of data is indicated using the max value 255. +*/ +if (data->chip_info->type ==KX022A && fifo_bytes ==KX022A_FIFO_FULL_VALUE ) + fifo_bytes =KX022A_FIFO_MAX_BYTES ; + +if (fifo_bytes %KX_FIFO_SAMPLES_SIZE_BYTES ) +dev_warn (data->dev,"Bad FIFO alignment. Data may be corrupt\n" ); + +return fifo_bytes; +} +static int kx022a_drop_fifo_contents (struct kx022a_data *data) {/* @@ -593,35 +588,22 @@ static int kx022a_drop_fifo_contents(struct kx022a_data *data)*/ data->timestamp =0 ; -return regmap_write (data->regmap,KX022A_REG_BUF_CLEAR ,0x0 ); +return regmap_write (data->regmap, data->chip_info->buf_clear,0x0 ); }static int __kx022a_fifo_flush (struct iio_dev *idev,unsigned int samples,bool irq) {struct kx022a_data *data =iio_priv (idev); -struct device *dev =regmap_get_device (data->regmap); -__le16 buffer[KX022A_FIFO_LENGTH *3 ]; +__le16 buffer[data->chip_info->fifo_length *3 ];uint64_t sample_period;int count, fifo_bytes;bool renable = false;int64_t tstamp;int ret, i; - ret =regmap_read (data->regmap,KX022A_REG_BUF_STATUS_1 , &fifo_bytes); -if (ret) { -dev_err (dev,"Error reading buffer status\n" ); -return ret; - } - -/* Let's not overflow if we for some reason get bogus value from i2c */ -if (fifo_bytes ==KX022A_FIFO_FULL_VALUE ) - fifo_bytes =KX022A_FIFO_MAX_BYTES ; - -if (fifo_bytes %KX022A_FIFO_SAMPLES_SIZE_BYTES ) -dev_warn (data->dev,"Bad FIFO alignment. Data may be corrupt\n" ); - - count = fifo_bytes /KX022A_FIFO_SAMPLES_SIZE_BYTES ; + fifo_bytes =kx022a_get_fifo_bytes (data); + count = fifo_bytes /KX_FIFO_SAMPLES_SIZE_BYTES ;if (!count)return 0 ;
...
drivers/iio/accel/kionix-kx022a.c static int kx022a_chip_init(struct kx022a_data *data) · line 955
Quoted 13 lines
drivers/iio/accel/kionix-kx022a.c +4
-4@@ -969,25 +949,25 @@ static int kx022a_chip_init(struct kx022a_data *data)*/ msleep (1 ); - ret =regmap_read_poll_timeout (data->regmap,KX022A_REG_CNTL2 , val, - !(val &KX022A_MASK_SRST ), -KX022A_SOFT_RESET_WAIT_TIME_US , -KX022A_SOFT_RESET_TOTAL_WAIT_TIME_US ); + ret =regmap_read_poll_timeout (data->regmap, data->chip_info->cntl2, val, + !(val &KX_MASK_SRST ), +KX_SOFT_RESET_WAIT_TIME_US , +KX_SOFT_RESET_TOTAL_WAIT_TIME_US );
Where ever there are lots of accesses to data->chip_info I'd add a local chip_info variable to improve readabilty a bit. Might be worth doing the same with regmap (in a different patch)
Quoted 40 lines
drivers/iio/accel/kionix-kx022a.c +6
-5if (ret) {dev_err (data->dev,"Sensor reset %s\n" , - val &KX022A_MASK_SRST ?"timeout" :"fail#" ); + val &KX_MASK_SRST ?"timeout" :"fail#" );return ret; } - ret =regmap_reinit_cache (data->regmap, &kx022a_regmap); + ret =regmap_reinit_cache (data->regmap, data->chip_info->regmap_config);if (ret) {dev_err (data->dev,"Failed to reinit reg cache\n" );return ret; }/* set data res 16bit */ - ret =regmap_set_bits (data->regmap,KX022A_REG_BUF_CNTL2 , -KX022A_MASK_BRES16 ); + ret =regmap_set_bits (data->regmap, data->chip_info->buf_cntl2, +KX_MASK_BRES16 );if (ret) {dev_err (data->dev,"Failed to set data resolution\n" );return ret;@@ -996,7 +976,7 @@ static int kx022a_chip_init(struct kx022a_data *data)return kx022a_prepare_irq_pin (data); } -int kx022a_probe_internal (struct device *dev) +int kx022a_probe_internal (struct device *dev,const struct kx022a_chip_info *chip_info) {static const char *const regulator_names[] = {"io-vdd" ,"vdd" };struct iio_trigger *indio_trig;@@ -1023,6 +1003,7 @@ int kx022a_probe_internal(struct device *dev)return -ENOMEM ; data =iio_priv (idev); + data->chip_info = chip_info;/* * VDD is the analog and digital domain voltage supply and
drivers/iio/accel/kionix-kx022a.c int kx022a_probe_internal(struct device *dev) · line 1017
Quoted 5 lines
drivers/iio/accel/kionix-kx022a.c +1
-1@@ -1033,37 +1014,37 @@ int kx022a_probe_internal(struct device *dev)if (ret && ret != -ENODEV )return dev_err_probe (dev, ret,"failed to enable regulator\n" ); - ret =regmap_read (regmap,KX022A_REG_WHO , &chip_id); + ret =regmap_read (regmap, data->chip_info->who, &chip_id);
I think you have chip_info available as a local variable. Use that in this function to shorten lines with no loss of readability.
drivers/iio/accel/kionix-kx022a.c int kx022a_probe_internal(struct device *dev) · line 1021
Quoted 5 lines
drivers/iio/accel/kionix-kx022a.c +1
-1if (ret)return dev_err_probe (dev, ret,"Failed to access sensor\n" ); -if (chip_id !=KX022A_ID ) { +if (chip_id != data->chip_info->id) {
Recently we've tried to avoid introduce error returns on a failure to match and instead just warn and go ahead with assumption that we have a correct dt-binding telling us that some new device with a different ID is backwards compatible with the old one. Obviously not part of this patch though but something to think about later (if you don't do it later in this series).
Quoted 3 lines
drivers/iio/accel/kionix-kx022a.c +0
-0dev_err (dev,"unsupported device 0x%x\n" , chip_id);return -EINVAL ; }
...
drivers/iio/accel/kionix-kx022a.c int kx022a_probe_internal(struct device *dev) · line 1066
Quoted 11 lines
drivers/iio/accel/kionix-kx022a.c +1
-4data->regmap = regmap; data->dev = dev; data->irq = irq; - data->odr_ns =KX022A_DEFAULT_PERIOD_NS ; + data->odr_ns =KX_DEFAULT_PERIOD_NS ;mutex_init (&data->mutex); - idev->channels = kx022a_channels; - idev->num_channels =ARRAY_SIZE (kx022a_channels); - idev->name ="kx022-accel" ;
Ah. Missed this naming in original driver review. We only normally postfix with accel in devices that have multiple sensors with separate drivers. Don't think that is true of the kx022a.
It's ABI so we are stuck with it, but avoid repeating that issue for new devices.
drivers/iio/accel/kionix-kx022a.c int kx022a_probe_internal(struct device *dev) · line 1097
Quoted 13 lines
drivers/iio/accel/kionix-kx022a.c +4
-1+ idev->channels = data->chip_info->channels; + idev->num_channels = data->chip_info->num_channels; + idev->name = data->chip_info->name; idev->info = &kx022a_info; idev->modes =INDIO_DIRECT_MODE |INDIO_BUFFER_SOFTWARE ; idev->available_scan_masks = kx022a_scan_masks;@@ -1112,7 +1093,7 @@ int kx022a_probe_internal(struct device *dev)* No need to check for NULL. request_threaded_irq() defaults to * dev_name() should the alloc fail. */ - name =devm_kasprintf (data->dev,GFP_KERNEL ,"%s-kx022a" , + name =devm_kasprintf (data->dev,GFP_KERNEL ,"%s-accel" ,dev_name (data->dev));
Why name change here? It's not particularly important but if we can avoid it that would be a nice to have.
Quoted 7 lines
drivers/iio/accel/kionix-kx022a.c +0
-0ret = devm_request_threaded_irq(data->dev, irq, kx022a_irq_handler,drivers/iio/accel/kionix-kx022a.h +0
-0
drivers/iio/accel/kionix-kx022a.h line 17
Quoted 7 lines
drivers/iio/accel/kionix-kx022a.h +4
-0@@ -11,24 +11,48 @@#include <linux/bits.h> #include <linux/regmap.h> +#include <linux/iio/iio.h> + +/* Common for all supported devices */ +#define KX_FIFO_SAMPLES_SIZE_BYTES 6
Even if they are used across multiple parts, don't rename them to be generic. It almost always causes churn / name clashes etc.
It is absolutely fine to have driver specific naming that is based on the first supported part rather than trying to make it cover them all.
Quoted 76 lines
drivers/iio/accel/kionix-kx022a.h +29
-16+#define KX_SOFT_RESET_WAIT_TIME_US (5 * USEC_PER_MSEC) +#define KX_SOFT_RESET_TOTAL_WAIT_TIME_US (500 * USEC_PER_MSEC) +#define KX_DEFAULT_PERIOD_NS (20 * NSEC_PER_MSEC) +#define KX_MASK_GSEL GENMASK(4, 3) +#define KX_MASK_ODR GENMASK(3, 0) +#define KX_MASK_WM_TH GENMASK(6, 0) +#define KX_GSEL_SHIFT 3 +#define KX_MASK_IEN BIT(5) +#define KX_MASK_DRDY BIT(5) +#define KX_MASK_PC1 BIT(7) +#define KX_MASK_IPOL BIT(4) +#define KX_IPOL_LOW 0 +#define KX_MASK_ITYP BIT(3) +#define KX_ITYP_LEVEL 0 +#define KX_MASK_INS2_DRDY BIT(4) +#define KX_MASK_WMI BIT(5) +#define KX_MASK_BUF_EN BIT(7) +#define KX_MASK_SRST BIT(7) +#define KX_MASK_BRES16 BIT(6) + +#define KX022A_REG_WHO 0x0f#define KX022A_ID 0xc8 +#define KX022A_FIFO_LENGTH 43 +#define KX022A_FIFO_FULL_VALUE 255 +#define KX022A_FIFO_MAX_BYTES \ + (KX022A_FIFO_LENGTH * KX_FIFO_SAMPLES_SIZE_BYTES) +#define KX022A_REG_CNTL2 0x19 -#define KX022A_MASK_SRST BIT(7)#define KX022A_REG_CNTL 0x18 -#define KX022A_MASK_PC1 BIT(7)#define KX022A_MASK_RES BIT(6) -#define KX022A_MASK_DRDY BIT(5) -#define KX022A_MASK_GSEL GENMASK(4, 3) -#define KX022A_GSEL_SHIFT 3#define KX022A_GSEL_2 0x0#define KX022A_GSEL_4 BIT(3)#define KX022A_GSEL_8 BIT(4)#define KX022A_GSEL_16 GENMASK(4, 3)#define KX022A_REG_INS2 0x13 -#define KX022A_MASK_INS2_DRDY BIT(4)#define KX122_MASK_INS2_WMI BIT(5)#define KX022A_REG_XHP_L 0x0@@ -45,38 +69,104 @@#define KX022A_REG_MAN_WAKE 0x2c#define KX022A_REG_BUF_CNTL1 0x3a -#define KX022A_MASK_WM_TH GENMASK(6, 0)#define KX022A_REG_BUF_CNTL2 0x3b -#define KX022A_MASK_BUF_EN BIT(7) -#define KX022A_MASK_BRES16 BIT(6)#define KX022A_REG_BUF_STATUS_1 0x3c#define KX022A_REG_BUF_STATUS_2 0x3d +#define KX022A_MASK_BUF_SMP_LVL GENMASK(6, 0)#define KX022A_REG_BUF_CLEAR 0x3e#define KX022A_REG_BUF_READ 0x3f -#define KX022A_MASK_ODR GENMASK(3, 0)#define KX022A_ODR_SHIFT 3#define KX022A_FIFO_MAX_WMI_TH 41#define KX022A_REG_INC1 0x1c#define KX022A_REG_INC5 0x20#define KX022A_REG_INC6 0x21 -#define KX022A_MASK_IEN BIT(5) -#define KX022A_MASK_IPOL BIT(4)#define KX022A_IPOL_LOW 0 -#define KX022A_IPOL_HIGH KX022A_MASK_IPOL1 -#define KX022A_MASK_ITYP BIT(3) -#define KX022A_ITYP_PULSE KX022A_MASK_ITYP -#define KX022A_ITYP_LEVEL 0 +#define KX022A_IPOL_HIGH KX_MASK_IPOL +#define KX022A_ITYP_PULSE KX_MASK_ITYP
drivers/iio/accel/kionix-kx022a.h line 95
Quoted 10 lines
drivers/iio/accel/kionix-kx022a.h +3
-1#define KX022A_REG_INC4 0x1f -#define KX022A_MASK_WMI BIT(5)#define KX022A_REG_SELF_TEST 0x60#define KX022A_MAX_REGISTER 0x60 +enum kx022a_device_type { +KX022A , +};
As below. I'd avoid using the enum unless needed.
That can make sense where a driver supports lots of devices but I don't think it does here.
Quoted 15 lines
drivers/iio/accel/kionix-kx022a.h +13
-0+ +enum { +KX_STATE_SAMPLE , +KX_STATE_FIFO , +}; + +enum { +AXIS_X , +AXIS_Y , +AXIS_Z , +AXIS_MAX +}; +struct device ;
drivers/iio/accel/kionix-kx022a.h line 118
Quoted 10 lines
drivers/iio/accel/kionix-kx022a.h +8
-2-int kx022a_probe_internal (struct device *dev); -extern const struct regmap_config kx022a_regmap; +struct kx022a_chip_info { +const char *name; +enum kx022a_device_type type; +const struct regmap_config *regmap_config; +const struct iio_chan_spec *channels; +unsigned int num_channels; +unsigned int fifo_length; +u8 who;
Some of these are no immediately obvious so either rename the field so it is more obvious what it is, or add comments.
Quoted 8 lines
drivers/iio/accel/kionix-kx022a.h +8
-0+u8 id; +u8 cntl; +u8 cntl2; +u8 odcntl; +u8 buf_cntl1; +u8 buf_cntl2; +u8 buf_clear; +u8 buf_status1;
drivers/iio/accel/kionix-kx022a.h line 136
Quoted 10 lines
drivers/iio/accel/kionix-kx022a.h +10
-0+u16 buf_smp_lvl_mask; +u8 buf_read; +u8 inc1; +u8 inc4; +u8 inc5; +u8 inc6; +u8 xout_l; +}; + +struct kx022a_data {
Why move this to the header? Unless there is a strong reason I'd prefer this to stay down in the .c file.
Quoted 24 lines
drivers/iio/accel/kionix-kx022a.h +24
-0+const struct kx022a_chip_info *chip_info; +struct regmap *regmap; +struct iio_trigger *trig; +struct device *dev; +struct iio_mount_matrix orientation; +int64_t timestamp, old_timestamp; + +int irq; +int inc_reg; +int ien_reg; + +unsigned int state; +unsigned int odr_ns; + +bool trigger_enabled; +/* +* Prevent toggling the sensor stby/active state (PC1 bit) in the +* middle of a configuration, or when the fifo is enabled. Also, +* protect the data stored/retrieved from this structure from +* concurrent accesses. +*/ +struct mutex mutex; +u8 watermark; +
drivers/iio/accel/kionix-kx022a.h line 170
Quoted 10 lines
drivers/iio/accel/kionix-kx022a.h +10
-0+/* 3 x 16bit accel data + timestamp */ +__le16 buffer[8 ]__aligned(IIO_DMA_MINALIGN) ; +struct { +__le16 channels[3 ]; +s64 ts__aligned(8) ; + } scan; +}; + +int kx022a_probe_internal (struct device *dev,const struct kx022a_chip_info *chip_info); +extern const struct kx022a_chip_info kx_chip_info[];
As mentioned in the bus specific driver, given there is a small set and we need the enum just to index this, I'd just have one per supported device.
extern const struct kx022a_chip_info kx022a_chip_info; extern const struct kx022a_chip_info kx321_chip_info;
etc
Quoted 2 lines
drivers/iio/accel/kionix-kx022a.h +0
-0#endif
Matti Vaittinen
maintainerRe: [PATCH 2/3] iio: accel: kionix-kx022a: Add chip_info structure
Hi Mehdi and Jonathan,
Just my take on couple of comments from Jonathan :) I still have my own review to do though...
Quoted 10 lines · Jonathan Cameron
Quoted 6 lines · On Fri, 17 Mar 2023 00:48:36 +0100 Mehdi Djait <[email protected]> wrote:
Refactor the kx022a driver implementation to make it more generic and extensible.
Add thechip_infostructure will to the driver's private data to hold all the device specific infos.
Move the enum, struct and constants definitions to the header file.
Quoted 4 lines
You also introduce an
i2c_device_idtableWithout that I think module autoloading will be broken anyway so that's definitely a good thing to add.
I am pretty sure the autoloading worked for OF-systems. But yes, adding the i2c_device_id is probably a good idea. Thanks.
Quoted 4 lines
A few comments inline. Mostly around reducing the name changes. Wild cards (or simply shorted 'generic' prefixes like
KX_) almost always bite back in the long run. Hence we generally just try to name things after the first device that they were relevant to.
I must say I disagree on this with you Jonathan. I know wildcards tend to get confusing - but I still like the idea of showing which of the definitions are IC specific and which ones are generic or at least used by more than one variant - especially as long as we only have two supported ICs. I definitely like the macro naming added by Mehdi. This approach has been very helpful for me for example in the BD718x7 (BD71837/BD71847/BD71850) PMIC driver. My take on this is:
1) I like the generic KX_define.
2) I would not try adding wildcards like KX_X22 - to denote support for 122 and 022 - while not supporting 132 - in my experience - that won't scale.
3) I definitely like the idea of using exact model number prefix for 'stuff' which is intended to work only on one exact model.
Regarding the 3) - I am not so strict on how the register/mask defines are handled - I _like_ the 1) 2) 3) approach above - but mask/register defines tend to get set (correctly) once and not required to be looked up after this. But. When the 'stuff' is functions - this gets very useful as one is very often required to see which functions are executed on which IC variant. Same goes to structs.
So, if we manage to convince Jonathan about the naming, then I like what yoo had here! I would hovever do it in two steps. I would at first do renaming patch where the generic defines were renamed - without any functional changes - and only then add the kx132 stuff in a subsequent patch. That would simplify seeing which changes are just renaming and which are functional ones.
But here, I must go with the wind - if subsystem maintainer says the code should not have naming like this - then I have no say over it... :/
Quoted 7 lines
drivers/iio/accel/kionix-kx022a-i2c.c line 40
Quoted 3 lines
drivers/iio/accel/kionix-kx022a-i2c.c +2
-0+static const struct i2c_device_id kx022a_i2c_id[] = { + { .name ="kx022a" , .driver_data = (kernel_ulong_t)&kx_chip_info[KX022A ] },If there are a small set and we aren't ever going to index the
chip_infostructure we might be better off not bothering with the enum and instead using a separate instance of the structure for each chip.
I kind of like also the table added by Mehdi. I admit I was at first just thinking that we should have a pointer to the struct here without any tables - but... After I took a peek in the kionix-kx022a.c - I kind of liked the table and not exporting the struct names. So, I don't have a strong opinion on this.
I think it's worth noting that this driver could (maybe easily enough) be extended to support also a few other kionix accelerometers. Maybe, if we don't scare Mehdi away, we will see a few other variants supported as well ;)
Quoted 7 lines
Quoted 7 lines
data->regmap = regmap; data->dev = dev; data->irq = irq;drivers/iio/accel/kionix-kx022a.c +1
-1- data->odr_ns =KX022A_DEFAULT_PERIOD_NS ; + data->odr_ns =KX_DEFAULT_PERIOD_NS ;mutex_init (&data->mutex);
Quoted 7 lines
drivers/iio/accel/kionix-kx022a.c int kx022a_probe_internal(struct device *dev) · line 1066
Quoted 3 lines
drivers/iio/accel/kionix-kx022a.c +0
-3- idev->channels = kx022a_channels; - idev->num_channels =ARRAY_SIZE (kx022a_channels); - idev->name ="kx022-accel" ;Ah. Missed this naming in original driver review. We only normally postfix with accel in devices that have multiple sensors with separate drivers. Don't think that is true of the kx022a.
Ouch. I am not 100% sure but may be you didn't miss it. It may be I just missed fixing this because your comment here sounds somewhat familiar to me! (Or then you commented on suffix in driver-name).
Quoted 11 lines
It's ABI so we are stuck with it, but avoid repeating that issue for new devices. >
drivers/iio/accel/kionix-kx022a.h line 95
Quoted 4 lines
drivers/iio/accel/kionix-kx022a.h +3
-0+enum kx022a_device_type { +KX022A , +};As below. I'd avoid using the enum unless needed.
That can make sense where a driver supports lots of devices but I don't think it does here.
Well, I know it is usually not too clever to be prepared for the future stuff too well. But - I don't think the enum and table are adding much of complexity? I am saying this as I think this driver could be extended to support also kx022 (without the A), kx023, kx122. I've also seen some references to model kx022A-120B (but I have no idea what's the story there or if that IC is publicly available). Maybe Mehdi would like to extend this driver further after the KX132 is done ;)
Quoted 4 lines
Quoted 4 lines
drivers/iio/accel/kionix-kx022a.h +2
-2-int kx022a_probe_internal (struct device *dev); -extern const struct regmap_config kx022a_regmap; +struct kx022a_chip_info { +const char *name;
Quoted 8 lines
drivers/iio/accel/kionix-kx022a.h line 118
Quoted 6 lines
drivers/iio/accel/kionix-kx022a.h +6
-0+enum kx022a_device_type type; +const struct regmap_config *regmap_config; +const struct iio_chan_spec *channels; +unsigned int num_channels; +unsigned int fifo_length; +u8 who;Some of these are no immediately obvious so either rename the field so it is more obvious what it is, or add comments.
I would vote for adding a comment :) I like the who. Both the band and this member here :) Data-sheet has register named as "who_am_i" - so I don't think this name is too obfuscating - and what matters to me - it is short yet meaningful.
Quoted 13 lines
Quoted 13 lines
drivers/iio/accel/kionix-kx022a.h +13
-0+u8 id; +u8 cntl; +u8 cntl2; +u8 odcntl; +u8 buf_cntl1; +u8 buf_cntl2; +u8 buf_clear; +u8 buf_status1; +u16 buf_smp_lvl_mask; +u8 buf_read; +u8 inc1; +u8 inc4; +u8 inc5;
Quoted 8 lines
drivers/iio/accel/kionix-kx022a.h line 136
Quoted 5 lines
drivers/iio/accel/kionix-kx022a.h +5
-0+u8 inc6; +u8 xout_l; +}; + +struct kx022a_data {Why move this to the header? Unless there is a strong reason I'd prefer this to stay down in the .c file.
So would I. It's definitely nice to be able to see the struct in the same file where the code referencing it is.
Yours,
-- Matti
Signature · 5 lines
Matti Vaittinen Linux kernel developer at ROHM Semiconductors Oulu Finland ~~ When things go utterly wrong vim users can always type :help! ~~
Re: [PATCH 2/3] iio: accel: kionix-kx022a: Add chip_info structure
Quoted 16 lines · On Mon, 20 Mar 2023 09:17:54 +0200 Matti Vaittinen <[email protected]>…
Hi Mehdi and Jonathan,
Just my take on couple of comments from Jonathan :) I still have my own review to do though...
Quoted 10 lines · Jonathan Cameron
Quoted 6 lines · On Fri, 17 Mar 2023 00:48:36 +0100 Mehdi Djait <[email protected]> wrote:
Refactor the kx022a driver implementation to make it more generic and extensible.
Add thechip_infostructure will to the driver's private data to hold all the device specific infos.
Move the enum, struct and constants definitions to the header file.
Quoted 7 lines
Quoted 4 lines
You also introduce an
i2c_device_idtableWithout that I think module autoloading will be broken anyway so that's definitely a good thing to add.
I am pretty sure the autoloading worked for OF-systems. But yes, adding the
i2c_device_idis probably a good idea. Thanks.
Ah. Maybe that issue only occurred for SPI - I'd assumed it was more general.
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/?id=5fa6863ba692
Quoted 14 lines
Quoted 5 lines
A few comments inline. Mostly around reducing the name changes. Wild cards (or simply shorted 'generic' prefixes like
KX_) almost always bite back in the long run. Hence we generally just try to name things after the first device that they were relevant to.I must say I disagree on this with you Jonathan. I know wildcards tend to get confusing - but I still like the idea of showing which of the definitions are IC specific and which ones are generic or at least used by more than one variant - especially as long as we only have two supported ICs. I definitely like the macro naming added by Mehdi. This approach has been very helpful for me for example in the BD718x7 (BD71837/BD71847/BD71850) PMIC driver. My take on this is:
Quoted 1 line
1) I like the generic
KX_define.
We already have other kionix drivers that don't use these defines. This is less of an issue if they are very local - so pushed down to the C file, but I still don't like the implication that they extend to a broad range of devices.
Quoted 3 lines
2) I would not try adding wildcards like
KX_X22- to denote support for 122 and 022 - while not supporting 132 - in my experience - that won't scale.
I think this already runs into this problem or at least sets the driver up to hit it very soon. The reality is that these definitions are shared by the 2 parts supported so far. 3rd part comes along and I'd be willing to place a bet that at least one of these definitions doesn't apply. So we end up with a mess converting it back to a specific name.
I've gone down this path many times before and it very rarely works out.
Quoted 2 lines
3) I definitely like the idea of using exact model number prefix for 'stuff' which is intended to work only on one exact .
When you have 2 devices it is easy to separate the 'generic' from the 'specific'. That breaks when you have 3. If we are sure there won't be a 3rd device supported by this driver then fair enough...
Quoted 7 lines
Regarding the 3) - I am not so strict on how the register/mask defines are handled - I _like_ the 1) 2) 3) approach above - but mask/register defines tend to get set (correctly) once and not required to be looked up after this. But. When the 'stuff' is functions - this gets very useful as one is very often required to see which functions are executed on which IC variant. Same goes to structs.
Given they tend to be accessed via a function pointer, even functions are only set up the once. For these I'm fine with a nasty listing type approach with multiple part names in the function defintion. That doesn't scale great either as lots of parts get added but it at least calls out which function covers which parts.
Quoted 10 lines
So, if we manage to convince Jonathan about the naming, then I like what yoo had here! I would hovever do it in two steps. I would at first do renaming patch where the generic defines were renamed - without any functional changes - and only then add the kx132 stuff in a subsequent patch. That would simplify seeing which changes are just renaming and which are functional ones.
But here, I must go with the wind - if subsystem maintainer says the code should not have naming like this - then I have no say over it... :/
If we have truely universal defines - sometimes this happens for WHO AM I registers for example as they are the same over all devices from a manufacturer (more or less anyway) then the broad forms are fine. Otherwise it just tends to end up as a mess if lots of parts added.
Quoted 15 lines
Quoted 8 lines
drivers/iio/accel/kionix-kx022a-i2c.c line 40
Quoted 4 lines
drivers/iio/accel/kionix-kx022a-i2c.c +2
-0+static const struct i2c_device_id kx022a_i2c_id[] = { + { .name ="kx022a" , .driver_data = (kernel_ulong_t)&kx_chip_info[KX022A ] },If there are a small set and we aren't ever going to index the
chip_infostructure we might be better off not bothering with the enum and instead using a separate instance of the structure for each chip.I kind of like also the table added by Mehdi. I admit I was at first just thinking that we should have a pointer to the struct here without any tables - but... After I took a peek in the
kionix-kx022a.c- I kind of liked the table and not exporting the struct names. So, I don't have a strong opinion on this.
Quoted 4 lines
I think it's worth noting that this driver could (maybe easily enough) be extended to support also a few other kionix accelerometers. Maybe, if we don't scare Mehdi away, we will see a few other variants supported as well ;)
This one wasn't a particularly important bit of feedback. I'm fine with the table, though seems slightly less readable to my eyes.
Quoted 16 lines
Quoted 8 lines
Quoted 8 lines
data->regmap = regmap; data->dev = dev; data->irq = irq;drivers/iio/accel/kionix-kx022a.c +1
-1- data->odr_ns =KX022A_DEFAULT_PERIOD_NS ; + data->odr_ns =KX_DEFAULT_PERIOD_NS ;mutex_init (&data->mutex);Quoted 7 lines
drivers/iio/accel/kionix-kx022a.c int kx022a_probe_internal(struct device *dev) · line 1066
Quoted 3 lines
drivers/iio/accel/kionix-kx022a.c +0
-3- idev->channels = kx022a_channels; - idev->num_channels =ARRAY_SIZE (kx022a_channels); - idev->name ="kx022-accel" ;Ah. Missed this naming in original driver review. We only normally postfix with accel in devices that have multiple sensors with separate drivers. Don't think that is true of the kx022a.
Quoted 3 lines
Ouch. I am not 100% sure but may be you didn't miss it. It may be I just missed fixing this because your comment here sounds somewhat familiar to me! (Or then you commented on suffix in driver-name).
Meh. This stuff happens and at the end of the day it's a magic string that userspace can match against. No userspace knows all of them anyway so most likely it's just provided in a 'selection' box for a user or encoded in a custom script / config file. So not hugely important for it to have the simplest possible form.
Quoted 13 lines
Quoted 5 lines
It's ABI so we are stuck with it, but avoid repeating that issue for new devices. >
Quoted 1 line
Quoted 7 lines
drivers/iio/accel/kionix-kx022a.h line 95
Quoted 3 lines
drivers/iio/accel/kionix-kx022a.h +3
-0+enum kx022a_device_type { +KX022A , +};As below. I'd avoid using the enum unless needed.
That can make sense where a driver supports lots of devices but I don't think it does here.
Quoted 7 lines
Well, I know it is usually not too clever to be prepared for the future stuff too well. But - I don't think the enum and table are adding much of complexity? I am saying this as I think this driver could be extended to support also kx022 (without the A), kx023, kx122. I've also seen some references to model kx022A-120B (but I have no idea what's the story there or if that IC is publicly available). Maybe Mehdi would like to extend this driver further after the KX132 is done ;)
Not adding a lot, but you are going to end up with adding one line to an enum in the header for each new device, vs one extern line. So I'm not sure it saves anything either.
Quoted 41 lines
Quoted 13 lines
drivers/iio/accel/kionix-kx022a.h line 118
Quoted 11 lines
drivers/iio/accel/kionix-kx022a.h +8
-2-int kx022a_probe_internal (struct device *dev); -extern const struct regmap_config kx022a_regmap; +struct kx022a_chip_info { +const char *name; +enum kx022a_device_type type; +const struct regmap_config *regmap_config; +const struct iio_chan_spec *channels; +unsigned int num_channels; +unsigned int fifo_length; +u8 who;Some of these are no immediately obvious so either rename the field so it is more obvious what it is, or add comments.
I would vote for adding a comment :) I like the who. Both the band and this member here :) Data-sheet has register named as "
who_am_i" - so I don't think this name is too obfuscating - and what matters to me - it is short yet meaningful.Quoted 13 lines
Quoted 13 lines
drivers/iio/accel/kionix-kx022a.h +13
-0+u8 id; +u8 cntl; +u8 cntl2; +u8 odcntl; +u8 buf_cntl1; +u8 buf_cntl2; +u8 buf_clear; +u8 buf_status1; +u16 buf_smp_lvl_mask; +u8 buf_read; +u8 inc1; +u8 inc4; +u8 inc5;Quoted 8 lines
drivers/iio/accel/kionix-kx022a.h line 136
Quoted 5 lines
drivers/iio/accel/kionix-kx022a.h +5
-0+u8 inc6; +u8 xout_l; +}; + +struct kx022a_data {Why move this to the header? Unless there is a strong reason I'd prefer this to stay down in the .c file.
Quoted 6 lines
So would I. It's definitely nice to be able to see the struct in the same file where the code referencing it is.
Yours,
-- Matti
Thanks,
Jonathan
Quoted 1 line
Re: [PATCH 2/3] iio: accel: kionix-kx022a: Add chip_info structure
Hello everyone,
Quoted 93 lines · Jonathan Cameron
Quoted 16 lines · On Mon, 20 Mar 2023 09:17:54 +0200 Matti Vaittinen <[email protected]>…
Hi Mehdi and Jonathan,
Just my take on couple of comments from Jonathan :) I still have my own review to do though...
Quoted 10 lines · Jonathan Cameron
Quoted 6 lines · On Fri, 17 Mar 2023 00:48:36 +0100 Mehdi Djait <[email protected]> wrote:
Refactor the kx022a driver implementation to make it more generic and extensible.
Add thechip_infostructure will to the driver's private data to hold all the device specific infos.
Move the enum, struct and constants definitions to the header file.Quoted 7 lines
Quoted 4 lines
You also introduce an
i2c_device_idtableWithout that I think module autoloading will be broken anyway so that's definitely a good thing to add.
I am pretty sure the autoloading worked for OF-systems. But yes, adding the
i2c_device_idis probably a good idea. Thanks.Ah. Maybe that issue only occurred for SPI - I'd assumed it was more general.
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/?id=5fa6863ba692
Quoted 14 lines
Quoted 5 lines
A few comments inline. Mostly around reducing the name changes. Wild cards (or simply shorted 'generic' prefixes like
KX_) almost always bite back in the long run. Hence we generally just try to name things after the first device that they were relevant to.I must say I disagree on this with you Jonathan. I know wildcards tend to get confusing - but I still like the idea of showing which of the definitions are IC specific and which ones are generic or at least used by more than one variant - especially as long as we only have two supported ICs. I definitely like the macro naming added by Mehdi. This approach has been very helpful for me for example in the BD718x7 (BD71837/BD71847/BD71850) PMIC driver. My take on this is:
Quoted 1 line
1) I like the generic
KX_define.We already have other kionix drivers that don't use these defines. This is less of an issue if they are very local - so pushed down to the C file, but I still don't like the implication that they extend to a broad range of devices.
Quoted 3 lines
2) I would not try adding wildcards like
KX_X22- to denote support for 122 and 022 - while not supporting 132 - in my experience - that won't scale.I think this already runs into this problem or at least sets the driver up to hit it very soon. The reality is that these definitions are shared by the 2 parts supported so far. 3rd part comes along and I'd be willing to place a bet that at least one of these definitions doesn't apply. So we end up with a mess converting it back to a specific name.
I've gone down this path many times before and it very rarely works out.
Quoted 2 lines
3) I definitely like the idea of using exact model number prefix for 'stuff' which is intended to work only on one exact .
When you have 2 devices it is easy to separate the 'generic' from the 'specific'. That breaks when you have 3. If we are sure there won't be a 3rd device supported by this driver then fair enough...
Quoted 7 lines
Regarding the 3) - I am not so strict on how the register/mask defines are handled - I _like_ the 1) 2) 3) approach above - but mask/register defines tend to get set (correctly) once and not required to be looked up after this. But. When the 'stuff' is functions - this gets very useful as one is very often required to see which functions are executed on which IC variant. Same goes to structs.
Given they tend to be accessed via a function pointer, even functions are only set up the once. For these I'm fine with a nasty listing type approach with multiple part names in the function defintion. That doesn't scale great either as lots of parts get added but it at least calls out which function covers which parts.
Quoted 8 lines
So, if we manage to convince Jonathan about the naming, then I like what yoo had here! I would hovever do it in two steps. I would at first do renaming patch where the generic defines were renamed - without any functional changes - and only then add the kx132 stuff in a subsequent patch. That would simplify seeing which changes are just renaming and which are functional ones.
Quoted 7 lines
Quoted 2 lines
But here, I must go with the wind - if subsystem maintainer says the code should not have naming like this - then I have no say over it... :/
If we have truely universal defines - sometimes this happens for WHO AM I registers for example as they are the same over all devices from a manufacturer (more or less anyway) then the broad forms are fine. Otherwise it just tends to end up as a mess if lots of parts added.
I will remove the generic defines.
I also really liked the idea of seperating the IC specific stuff from the generic ones. Better play it safe here, I can also see it becoming a mess in the long run.
Quoted 15 lines
Quoted 15 lines
Quoted 8 lines
drivers/iio/accel/kionix-kx022a-i2c.c line 40
Quoted 4 lines
drivers/iio/accel/kionix-kx022a-i2c.c +2
-0+static const struct i2c_device_id kx022a_i2c_id[] = { + { .name ="kx022a" , .driver_data = (kernel_ulong_t)&kx_chip_info[KX022A ] },If there are a small set and we aren't ever going to index the
chip_infostructure we might be better off not bothering with the enum and instead using a separate instance of the structure for each chip.I kind of like also the table added by Mehdi. I admit I was at first just thinking that we should have a pointer to the struct here without any tables - but... After I took a peek in the
kionix-kx022a.c- I kind of liked the table and not exporting the struct names. So, I don't have a strong opinion on this.
Quoted 7 lines
Quoted 4 lines
I think it's worth noting that this driver could (maybe easily enough) be extended to support also a few other kionix accelerometers. Maybe, if we don't scare Mehdi away, we will see a few other variants supported as well ;)
This one wasn't a particularly important bit of feedback. I'm fine with the table, though seems slightly less readable to my eyes.
My reasoning behind it: when supporting multiple devices, having a single array of chip_info and one single EXPORT_SYMBOL is more concise and readable.
Quoted 21 lines
Quoted 17 lines
Quoted 9 lines
Quoted 9 lines
data->regmap = regmap; data->dev = dev; data->irq = irq;drivers/iio/accel/kionix-kx022a.c +1
-1- data->odr_ns =KX022A_DEFAULT_PERIOD_NS ; + data->odr_ns =KX_DEFAULT_PERIOD_NS ;mutex_init (&data->mutex);Quoted 7 lines
drivers/iio/accel/kionix-kx022a.c int kx022a_probe_internal(struct device *dev) · line 1066
Quoted 3 lines
drivers/iio/accel/kionix-kx022a.c +0
-3- idev->channels = kx022a_channels; - idev->num_channels =ARRAY_SIZE (kx022a_channels); - idev->name ="kx022-accel" ;Ah. Missed this naming in original driver review. We only normally postfix with accel in devices that have multiple sensors with separate drivers. Don't think that is true of the kx022a.
Quoted 3 lines
Ouch. I am not 100% sure but may be you didn't miss it. It may be I just missed fixing this because your comment here sounds somewhat familiar to me! (Or then you commented on suffix in driver-name).
Quoted 9 lines
Meh. This stuff happens and at the end of the day it's a magic string that userspace can match against. No userspace knows all of them anyway so most likely it's just provided in a 'selection' box for a user or encoded in a custom script / config file. So not hugely important for it to have the simplest possible form.
Quoted 3 lines
Quoted 3 lines
It's ABI so we are stuck with it, but avoid repeating that issue for new devices. >
I will change the name in the chip_info of kx022a back to "kx022-accel"
I am already using "kx132" as name for the newly supported device
Quoted 10 lines
Quoted 10 lines
Quoted 9 lines
drivers/iio/accel/kionix-kx022a.h line 95
Quoted 5 lines
drivers/iio/accel/kionix-kx022a.h +3
-0+enum kx022a_device_type { +KX022A , +};As below. I'd avoid using the enum unless needed.
That can make sense where a driver supports lots of devices but I don't think it does here.
Quoted 7 lines
Quoted 7 lines
Well, I know it is usually not too clever to be prepared for the future stuff too well. But - I don't think the enum and table are adding much of complexity? I am saying this as I think this driver could be extended to support also kx022 (without the A), kx023, kx122. I've also seen some references to model kx022A-120B (but I have no idea what's the story there or if that IC is publicly available). Maybe Mehdi would like to extend this driver further after the KX132 is done ;)
Yes, my goal is to support more devices and I want to make as easy as possible to extend this driver :)
Quoted 5 lines
Not adding a lot, but you are going to end up with adding one line to an enum in the header for each new device, vs one extern line. So I'm not sure it saves anything either.
Using a separate instance of the chip_info structure for each chip means also an extra symbol export
Quoted 41 lines
Quoted 41 lines
Quoted 13 lines
drivers/iio/accel/kionix-kx022a.h line 118
Quoted 11 lines
drivers/iio/accel/kionix-kx022a.h +8
-2-int kx022a_probe_internal (struct device *dev); -extern const struct regmap_config kx022a_regmap; +struct kx022a_chip_info { +const char *name; +enum kx022a_device_type type; +const struct regmap_config *regmap_config; +const struct iio_chan_spec *channels; +unsigned int num_channels; +unsigned int fifo_length; +u8 who;Some of these are no immediately obvious so either rename the field so it is more obvious what it is, or add comments.
I would vote for adding a comment :) I like the who. Both the band and this member here :) Data-sheet has register named as "
who_am_i" - so I don't think this name is too obfuscating - and what matters to me - it is short yet meaningful.Quoted 21 lines
Quoted 8 lines
drivers/iio/accel/kionix-kx022a.h +8
-0+u8 id; +u8 cntl; +u8 cntl2; +u8 odcntl; +u8 buf_cntl1; +u8 buf_cntl2; +u8 buf_clear; +u8 buf_status1;drivers/iio/accel/kionix-kx022a.h line 136
Quoted 10 lines
drivers/iio/accel/kionix-kx022a.h +10
-0+u16 buf_smp_lvl_mask; +u8 buf_read; +u8 inc1; +u8 inc4; +u8 inc5; +u8 inc6; +u8 xout_l; +}; + +struct kx022a_data {Why move this to the header? Unless there is a strong reason I'd prefer this to stay down in the .c file.
Quoted 2 lines
Quoted 2 lines
So would I. It's definitely nice to be able to see the struct in the same file where the code referencing it is.
no strong reason, I will move it back to the .c file
--
Kind Regards
Mehdi Djait
Matti Vaittinen
maintainerRe: [PATCH 2/3] iio: accel: kionix-kx022a: Add chip_info structure
In reply to Mehdi DjaitQuoted 31 lines · Mehdi Djait
Refactor the kx022a driver implementation to make it more generic and extensible.
Add thechip_infostructure will to the driver's private data to hold all the device specific infos.
Move the enum, struct and constants definitions to the header file.Signed-off-by Mehdi Djait <[email protected]>--- drivers/iio/accel/kionix-kx022a-i2c.c | 19 +- drivers/iio/accel/kionix-kx022a-spi.c | 22 +- drivers/iio/accel/kionix-kx022a.c | 289 ++++++++++++-------------- drivers/iio/accel/kionix-kx022a.h | 128 ++++++++++-- 4 files changed, 274 insertions(+), 184 deletions(-)drivers/iio/accel/kionix-kx022a-i2c.c +2
-0@@ -15,23 +15,35 @@static int kx022a_i2c_probe (struct i2c_client *i2c) {struct device *dev = &i2c->dev; +struct kx022a_chip_info *chip_info;struct regmap *regmap; +const struct i2c_device_id *id =i2c_client_get_device_id (i2c);if (!i2c->irq) {dev_err (dev,"No IRQ configured\n" );return -EINVAL ; }
drivers/iio/accel/kionix-kx022a-i2c.c line 34
Quoted 10 lines
drivers/iio/accel/kionix-kx022a-i2c.c +5
-1- regmap =devm_regmap_init_i2c (i2c, &kx022a_regmap); + chip_info =device_get_match_data (&i2c->dev); +if (!chip_info) + chip_info = (const struct kx022a_chip_info *) id->driver_data; + + regmap =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" );
Hm. I would like to pull the regmap_config out of the chip_info struct. As far as I see, the regmap_config is only needed in these bus specific files. On the other hand, the chip-info is only needed in the kionix-kx022a.c file, right?
So, maybe you could here just get the regmap_config based on the chip-id (enum value you added - the data pointer in match tables could be just the enum value indicating the IC type). Then, you could pass this enum value to kx022a_probe_internal() - and the chip-info struct could be selected in the kionix-kx022a.c based on it. That way you would not need the struct chip-info here or regmap_config in kionix-kx022a.c. Same in the *-spi.c
Something like:
enum {
KIONIX_IC_KX022A,
KIONIX_IC_KX132_xxx, /* xxx denotes accurate model suffix */
};static const struct of_device_id kx022a_of_match[] = {
{ .compatible = "kionix,kx022a", .data = KIONIX_IC_KX022A },
...chip_id = device_get_match_data(&i2c->dev);
regmap_cfg = kx022a_kx_regmap_cfg[chip_id];
regmap = devm_regmap_init_i2c(i2c, regmap_cfg);
...
return kx022a_probe_internal(dev, chip_id);
Do you think that would work?
OTOH, to really benefit from this we should probably pull out the regmap-configs from the kionix-kx022a.c. I am not really sure where we should put it then though. Hence, if there is no good ideas how to split the config and chip-info so they are only available/used where needed - then I am also Ok with the current approach.
Quoted 22 lines
drivers/iio/accel/kionix-kx022a-i2c.c +0
-22- -struct kx022a_data { -struct regmap *regmap; -struct iio_trigger *trig; -struct device *dev; -struct iio_mount_matrix orientation; -int64_t timestamp, old_timestamp; - -int irq; -int inc_reg; -int ien_reg; - -unsigned int state; -unsigned int odr_ns; - -bool trigger_enabled; -/* -* Prevent toggling the sensor stby/active state (PC1 bit) in the -* middle of a configuration, or when the fifo is enabled. Also, -* protect the data stored/retrieved from this structure from -* concurrent accesses. -*/
drivers/iio/accel/kionix-kx022a-i2c.c
Quoted 10 lines
drivers/iio/accel/kionix-kx022a-i2c.c +0
-10-struct mutex mutex; -u8 watermark; - -/* 3 x 16bit accel data + timestamp */ -__le16 buffer[8 ]__aligned(IIO_DMA_MINALIGN) ; -struct { -__le16 channels[3 ]; -s64 ts__aligned(8) ; - } scan; -};
As mentioned by Jonathan - It'd be better to keep this struct in C-file.
drivers/iio/accel/kionix-kx022a-i2c.c
Quoted 6 lines
drivers/iio/accel/kionix-kx022a-i2c.c +5
-0+const struct kx022a_chip_info kx_chip_info[] = { + [KX022A ] = { + .name ="kx022a" , + .type =KX022A , + .regmap_config = &kx022a_regmap_config,
As mentioned above, the regmap config is not really needed after the regmap is initialized. Id prefer this not being part of the chip info.
Quoted 30 lines
drivers/iio/accel/kionix-kx022a-i2c.c +23
-0+ .channels = kx022a_channels, + .num_channels = ARRAY_SIZE(kx022a_channels), + .fifo_length = KX022A_FIFO_LENGTH, + .who = KX022A_REG_WHO, + .id = KX022A_ID, + .cntl = KX022A_REG_CNTL, + .cntl2 = KX022A_REG_CNTL2, + .odcntl = KX022A_REG_ODCNTL, + .buf_cntl1 = KX022A_REG_BUF_CNTL1, + .buf_cntl2 = KX022A_REG_BUF_CNTL2, + .buf_clear = KX022A_REG_BUF_CLEAR, + .buf_status1 = KX022A_REG_BUF_STATUS_1, + .buf_smp_lvl_mask = KX022A_MASK_BUF_SMP_LVL, + .buf_read = KX022A_REG_BUF_READ, + .inc1 = KX022A_REG_INC1, + .inc4 = KX022A_REG_INC4, + .inc5 = KX022A_REG_INC5, + .inc6 = KX022A_REG_INC6, + .xout_l = KX022A_REG_XOUT_L, + }, +}; +EXPORT_SYMBOL_NS_GPL (kx_chip_info,IIO_KX022A ); + static int kx022a_read_avail(struct iio_dev *indio_dev, struct iio_chan_spec const *chan, const int **vals, int *type, int *length,@@ -309,19 +275,17 @@ static int kx022a_read_avail(struct iio_dev *indio_dev, } }
drivers/iio/accel/kionix-kx022a-i2c.c static int kx022a_read_avail(struct iio_dev *indio_dev, · line 283
Quoted 10 lines
drivers/iio/accel/kionix-kx022a-i2c.c +2
-4-#define KX022A_DEFAULT_PERIOD_NS (20 * NSEC_PER_MSEC) -static void kx022a_reg2freq (unsigned int val,int *val1,int *val2) { - *val1 = kx022a_accel_samp_freq_table[val &KX022A_MASK_ODR ][0 ]; - *val2 = kx022a_accel_samp_freq_table[val &KX022A_MASK_ODR ][1 ]; + *val1 = kx022a_accel_samp_freq_table[val &KX_MASK_ODR ][0 ]; + *val2 = kx022a_accel_samp_freq_table[val &KX_MASK_ODR ][1 ]; }
As mentioned elsewhere, doing the renaming separately from the functional changes will ease the reviewing.
Quoted 21 lines
drivers/iio/accel/kionix-kx022a-i2c.c +20
-0+static int kx022a_get_fifo_bytes (struct kx022a_data *data) +{ +struct device *dev =regmap_get_device (data->regmap); +__le16 buf_status; +int ret, fifo_bytes; + + ret =regmap_bulk_read (data->regmap, data->chip_info->buf_status1, &buf_status,sizeof (buf_status)); +if (ret) { +dev_err (dev,"Error reading buffer status\n" ); +return ret; + } + + buf_status &= data->chip_info->buf_smp_lvl_mask; + fifo_bytes =le16_to_cpu (buf_status); + +/* +* The KX022A has FIFO which can store 43 samples of HiRes data from 2 +* channels. This equals to 43 (samples) * 3 (channels) * 2 (bytes/sample) to +* 258 bytes of sample data. The quirk to know is that the amount of bytes in +* the FIFO is advertised via 8 bit register (max value 255). The thing to note
drivers/iio/accel/kionix-kx022a-i2c.c static int kx022a_read_avail(struct iio_dev *indio_dev,
Quoted 10 lines
drivers/iio/accel/kionix-kx022a-i2c.c +10
-0+* is that full 258 bytes of data is indicated using the max value 255. +*/ +if (data->chip_info->type ==KX022A && fifo_bytes ==KX022A_FIFO_FULL_VALUE ) + fifo_bytes =KX022A_FIFO_MAX_BYTES ; + +if (fifo_bytes %KX_FIFO_SAMPLES_SIZE_BYTES ) +dev_warn (data->dev,"Bad FIFO alignment. Data may be corrupt\n" ); + +return fifo_bytes; +}
I like adding this function. Here I agree with Jonathan - having a device specific functions would clarify this a bit. The KX022A "quirk" is a bit confusing. You could then get rid of the buf_smp_lvl_mask.
Quoted 9 lines
drivers/iio/accel/kionix-kx022a-i2c.c +1
-1+static int kx022a_drop_fifo_contents (struct kx022a_data *data) {/* @@ -593,35 +588,22 @@ static int kx022a_drop_fifo_contents(struct kx022a_data *data)*/ data->timestamp =0 ; -return regmap_write (data->regmap,KX022A_REG_BUF_CLEAR ,0x0 );
drivers/iio/accel/kionix-kx022a-i2c.c static int kx022a_drop_fifo_contents(struct kx022a_data *data) · line 598
Quoted 10 lines
drivers/iio/accel/kionix-kx022a-i2c.c +2
-2+return regmap_write (data->regmap, data->chip_info->buf_clear,0x0 ); }static int __kx022a_fifo_flush (struct iio_dev *idev,unsigned int samples,bool irq) {struct kx022a_data *data =iio_priv (idev); -struct device *dev =regmap_get_device (data->regmap); -__le16 buffer[KX022A_FIFO_LENGTH *3 ]; +__le16 buffer[data->chip_info->fifo_length *3 ];
I don't like this. Having the length of an array decided at run-time is not something I appreciate. Maybe you could just always reserve the memory so that the largest FIFO gets supported. I am just wondering how large arrays we can safely allocate from the stack?
Quoted 6 lines
drivers/iio/accel/kionix-kx022a-i2c.c +0
-2@@ -812,14 +792,14 @@ static int kx022a_fifo_enable(struct kx022a_data *data) goto unlock_out;/* Enable buffer */ - ret =regmap_set_bits (data->regmap,KX022A_REG_BUF_CNTL2 , -KX022A_MASK_BUF_EN );
drivers/iio/accel/kionix-kx022a-i2c.c static int kx022a_fifo_enable(struct kx022a_data *data) · line 802
Quoted 10 lines
drivers/iio/accel/kionix-kx022a-i2c.c +4
-2+ ret =regmap_set_bits (data->regmap, data->chip_info->buf_cntl2, +KX_MASK_BUF_EN );if (ret) goto unlock_out; - data->state |=KX022A_STATE_FIFO ; + data->state |=KX_STATE_FIFO ; ret =regmap_set_bits (data->regmap, data->ien_reg, -KX022A_MASK_WMI ); +KX_MASK_WMI );
I think this fits to one line now. (even on my screen)
drivers/iio/accel/kionix-kx022a-i2c.c static int kx022a_fifo_enable(struct kx022a_data *data)
Quoted 6 lines
drivers/iio/accel/kionix-kx022a-i2c.c +1
-1if (ret) goto unlock_out; -int kx022a_probe_internal (struct device *dev) +int kx022a_probe_internal (struct device *dev,const struct kx022a_chip_info *chip_info)
As mentioned elsewhere, this might also work if the chip-type enum was passed here as parameter. That way the bus specific part would not need to know about the struct chip_info...
drivers/iio/accel/kionix-kx022a-i2c.c int kx022a_probe_internal(struct device *dev) · line 1006
Quoted 8 lines
{ static const char * const regulator_names[] = {"io-vdd", "vdd"}; struct iio_trigger *indio_trig;drivers/iio/accel/kionix-kx022a-i2c.c +1
-0@@ -1023,6 +1003,7 @@ int kx022a_probe_internal(struct device *dev)return -ENOMEM ; data =iio_priv (idev); + data->chip_info = chip_info;
...Here you could then pick the correct chip_info based on the chip-type enum. In that case I'd like to get the regmap_config(s) in own file. Not sure how that would look like though.
All in all, I like how this looks like. Nice job!
Yours,
-- Matti
Signature · 5 lines
Matti Vaittinen Linux kernel developer at ROHM Semiconductors Oulu Finland ~~ When things go utterly wrong vim users can always type :help! ~~
Re: [PATCH 2/3] iio: accel: kionix-kx022a: Add chip_info structure
Quoted 7 lines · Matti Vaittinen
Quoted 6 lines · Mehdi Djait
Refactor the kx022a driver implementation to make it more generic and extensible.
Add thechip_infostructure will to the driver's private data to hold all the device specific infos.
Move the enum, struct and constants definitions to the header file.
...
Quoted 7 lines
Something like:
enum { KIONIX_IC_KX022A, KIONIX_IC_KX132_xxx, /* xxx denotes accurate model suffix */ };
Quoted 5 lines
static const struct of_device_id kx022a_of_match[] = { { .compatible = "kionix,kx022a", .data = KIONIX_IC_KX022A }, ...
chip_id=device_get_match_data(&i2c->dev);
No, please avoid putting plain integers as pointers of driver_data.
The problem you introduced with your suggestion is impossibility to distinguish 0 and NULL, beyond other not good things (like missing castings which are ugly).
Signature · 2 lines
With Best Regards, Andy Shevchenko
Re: [PATCH 2/3] iio: accel: kionix-kx022a: Add chip_info structure
In reply to Matti VaittinenQuoted 33 lines · On Mon, 20 Mar 2023 11:35:06 +0200 Matti Vaittinen <[email protected]>…
Quoted 32 lines · Mehdi Djait
Refactor the kx022a driver implementation to make it more generic and extensible.
Add thechip_infostructure will to the driver's private data to hold all the device specific infos.
Move the enum, struct and constants definitions to the header file.Signed-off-by Mehdi Djait <[email protected]>--- drivers/iio/accel/kionix-kx022a-i2c.c | 19 +- drivers/iio/accel/kionix-kx022a-spi.c | 22 +- drivers/iio/accel/kionix-kx022a.c | 289 ++++++++++++-------------- drivers/iio/accel/kionix-kx022a.h | 128 ++++++++++-- 4 files changed, 274 insertions(+), 184 deletions(-)drivers/iio/accel/kionix-kx022a-i2c.c +2
-0@@ -15,23 +15,35 @@static int kx022a_i2c_probe (struct i2c_client *i2c) {struct device *dev = &i2c->dev; +struct kx022a_chip_info *chip_info;struct regmap *regmap; +const struct i2c_device_id *id =i2c_client_get_device_id (i2c);if (!i2c->irq) {dev_err (dev,"No IRQ configured\n" );return -EINVAL ; }
Quoted 15 lines
drivers/iio/accel/kionix-kx022a-i2c.c line 34
Quoted 9 lines
drivers/iio/accel/kionix-kx022a-i2c.c +5
-1- regmap =devm_regmap_init_i2c (i2c, &kx022a_regmap); + chip_info =device_get_match_data (&i2c->dev); +if (!chip_info) + chip_info = (const struct kx022a_chip_info *) id->driver_data; + + regmap =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" );Hm. I would like to pull the
regmap_configout of thechip_infostruct. As far as I see, theregmap_configis only needed in these bus specific files. On the other hand, the chip-info is only needed in thekionix-kx022a.cfile, right?
I disagree. We've moved quite a few drivers away from the enum route because the indirection doesn't add anything useful and leads to nasty casting to enums. In particular, we have to avoid using enum value of 0 if we want to check if there is a match. For a pointer that's an easy check against NULL.
The regmap is product specific so makes sense as part of the chip_info structure.
Quoted 15 lines
So, maybe you could here just get the
regmap_configbased on the chip-id (enum value you added - the data pointer in match tables could be just the enum value indicating the IC type). Then, you could pass this enum value tokx022a_probe_internal()- and the chip-info struct could be selected in thekionix-kx022a.cbased on it. That way you would not need the struct chip-info here orregmap_configinkionix-kx022a.c. Same in the *-spi.cSomething like:
enum { KIONIX_IC_KX022A, KIONIX_IC_KX132_xxx, /* xxx denotes accurate model suffix */ };
Quoted 5 lines
static const struct of_device_id kx022a_of_match[] = { { .compatible = "kionix,kx022a", .data = KIONIX_IC_KX022A }, ...
chip_id=device_get_match_data(&i2c->dev);
This fails for probes using the i2c_device_id table entries. So you need to check for invalid entry. Unfortunately that is a NULL return which you can't detect if your enum has a value of 0.
Quoted 7 lines
regmap_cfg= kx022a_kx_regmap_cfg[chip_id];
regmap =devm_regmap_init_i2c(i2c, regmap_cfg);
...
returnkx022a_probe_internal(dev, chip_id);Do you think that would work?
It would work with the enum starting at 1, and it's a pattern that used to be common. Less so now because with multiple firmware types we want to be able to check trivially if we have a match.
Quoted 6 lines
OTOH, to really benefit from this we should probably pull out the regmap-configs from the
kionix-kx022a.c. I am not really sure where we should put it then though. Hence, if there is no good ideas how to split the config and chip-info so they are only available/used where needed - then I am also Ok with the current approach.
Definitely stick to current approach. If I had the time I'd rip out all the code useing enums in match tables. It's bitten us a few times with nasty to track down bugs that only affect more obscure ways of binding the driver.
...
Quoted 28 lines
Quoted 28 lines
drivers/iio/accel/kionix-kx022a-i2c.c +26
-0+static int kx022a_get_fifo_bytes (struct kx022a_data *data) +{ +struct device *dev =regmap_get_device (data->regmap); +__le16 buf_status; +int ret, fifo_bytes; + + ret =regmap_bulk_read (data->regmap, data->chip_info->buf_status1, &buf_status,sizeof (buf_status)); +if (ret) { +dev_err (dev,"Error reading buffer status\n" ); +return ret; + } + + buf_status &= data->chip_info->buf_smp_lvl_mask; + fifo_bytes =le16_to_cpu (buf_status); + +/* +* The KX022A has FIFO which can store 43 samples of HiRes data from 2 +* channels. This equals to 43 (samples) * 3 (channels) * 2 (bytes/sample) to +* 258 bytes of sample data. The quirk to know is that the amount of bytes in +* the FIFO is advertised via 8 bit register (max value 255). The thing to note +* is that full 258 bytes of data is indicated using the max value 255. +*/ +if (data->chip_info->type ==KX022A && fifo_bytes ==KX022A_FIFO_FULL_VALUE ) + fifo_bytes =KX022A_FIFO_MAX_BYTES ; + +if (fifo_bytes %KX_FIFO_SAMPLES_SIZE_BYTES )
Quoted 8 lines
drivers/iio/accel/kionix-kx022a-i2c.c
Quoted 4 lines
drivers/iio/accel/kionix-kx022a-i2c.c +4
-0+dev_warn (data->dev,"Bad FIFO alignment. Data may be corrupt\n" ); + +return fifo_bytes; +}I like adding this function. Here I agree with Jonathan - having a device specific functions would clarify this a bit. The KX022A "quirk" is a bit confusing. You could then get rid of the
buf_smp_lvl_mask.
I'd missed the type quirk. Good point, definitely have a callback. Get rid of that 'type' element of the chip_info.
That is a bad design pattern as it doesn't scale to lots of devices as you end up with big switch statements.
Quoted 13 lines
Quoted 13 lines
drivers/iio/accel/kionix-kx022a-i2c.c +2
-1+static int kx022a_drop_fifo_contents (struct kx022a_data *data) {/* @@ -593,35 +588,22 @@ static int kx022a_drop_fifo_contents(struct kx022a_data *data)*/ data->timestamp =0 ; -return regmap_write (data->regmap,KX022A_REG_BUF_CLEAR ,0x0 ); +return regmap_write (data->regmap, data->chip_info->buf_clear,0x0 ); }
Quoted 12 lines
drivers/iio/accel/kionix-kx022a-i2c.c static int kx022a_drop_fifo_contents(struct kx022a_data *data) · line 598
Quoted 7 lines
drivers/iio/accel/kionix-kx022a-i2c.c +1
-2static int __kx022a_fifo_flush (struct iio_dev *idev,unsigned int samples,bool irq) {struct kx022a_data *data =iio_priv (idev); -struct device *dev =regmap_get_device (data->regmap); -__le16 buffer[KX022A_FIFO_LENGTH *3 ]; +__le16 buffer[data->chip_info->fifo_length *3 ];I don't like this. Having the length of an array decided at run-time is not something I appreciate. Maybe you could just always reserve the memory so that the largest FIFO gets supported. I am just wondering how large arrays we can safely allocate from the stack?
I'd missed this as well. Definitely don't have a variable length array. Allocate it as a buffer accessed via a pointer in kx022a_data
Quoted 7 lines
Quoted 6 lines
drivers/iio/accel/kionix-kx022a-i2c.c +0
-0if (ret) goto unlock_out;
Quoted 6 lines
drivers/iio/accel/kionix-kx022a-i2c.c static int kx022a_drop_fifo_contents(struct kx022a_data *data) · line 602
Quoted 2 lines
drivers/iio/accel/kionix-kx022a-i2c.c +1
-1-int kx022a_probe_internal (struct device *dev) +int kx022a_probe_internal (struct device *dev,const struct kx022a_chip_info *chip_info)As mentioned elsewhere, this might also work if the chip-type enum was passed here as parameter. That way the bus specific part would not need to know about the struct
chip_info...
It only knows there is a pointer. Doesn't need to know more than that.
+ argument against as above.
Jonathan
Matti Vaittinen
maintainerRe: [PATCH 2/3] iio: accel: kionix-kx022a: Add chip_info structure
Quoted 11 lines · Jonathan Cameron
Quoted 7 lines · On Mon, 20 Mar 2023 11:35:06 +0200 Matti Vaittinen <[email protected]>…
On 3/17/23 01:48, Mehdi Djait wrote:
OTOH, to really benefit from this we should probably pull out the regmap-configs from the
kionix-kx022a.c. I am not really sure where we should put it then though. Hence, if there is no good ideas how to split the config and chip-info so they are only available/used where needed - then I am also Ok with the current approach.
Quoted 5 lines
Definitely stick to current approach. If I had the time I'd rip out all the code useing enums in match tables. It's bitten us a few times with nasty to track down bugs that only affect more obscure ways of binding the driver.
Seems like Jonathan has a strong opinion on this. Please follow his and Andy's guidance on this one and forget my comment.
Yours,
-- Matti
Signature · 5 lines
Matti Vaittinen Linux kernel developer at ROHM Semiconductors Oulu Finland ~~ When things go utterly wrong vim users can always type :help! ~~
Re: [PATCH 2/3] iio: accel: kionix-kx022a: Add chip_info structure
In reply to Matti VaittinenHello Matti,
Quoted 26 lines
Quoted 26 lines
drivers/iio/accel/kionix-kx022a.c +26
-0+static int kx022a_get_fifo_bytes (struct kx022a_data *data) +{ +struct device *dev =regmap_get_device (data->regmap); +__le16 buf_status; +int ret, fifo_bytes; + + ret =regmap_bulk_read (data->regmap, data->chip_info->buf_status1, &buf_status,sizeof (buf_status)); +if (ret) { +dev_err (dev,"Error reading buffer status\n" ); +return ret; + } + + buf_status &= data->chip_info->buf_smp_lvl_mask; + fifo_bytes =le16_to_cpu (buf_status); + +/* +* The KX022A has FIFO which can store 43 samples of HiRes data from 2 +* channels. This equals to 43 (samples) * 3 (channels) * 2 (bytes/sample) to +* 258 bytes of sample data. The quirk to know is that the amount of bytes in +* the FIFO is advertised via 8 bit register (max value 255). The thing to note +* is that full 258 bytes of data is indicated using the max value 255. +*/ +if (data->chip_info->type ==KX022A && fifo_bytes ==KX022A_FIFO_FULL_VALUE ) + fifo_bytes =KX022A_FIFO_MAX_BYTES ; + +if (fifo_bytes %KX_FIFO_SAMPLES_SIZE_BYTES )
Quoted 8 lines
drivers/iio/accel/kionix-kx022a.c static const struct iio_dev_attr *kx022a_fifo_attributes[] = { · line 576
Quoted 4 lines
drivers/iio/accel/kionix-kx022a.c +4
-0+dev_warn (data->dev,"Bad FIFO alignment. Data may be corrupt\n" ); + +return fifo_bytes; +}I like adding this function. Here I agree with Jonathan - having a device specific functions would clarify this a bit. The KX022A "quirk" is a bit confusing. You could then get rid of the
buf_smp_lvl_mask.
my bad here, I should have made a separate patch and explained more ... buf_smp_lvl_mask is essential because kionix products use different number of bits to report "the number of data bytes that have been stored in the sample buffer" using the registers BUF_STATUS_1 and BUF_STATUS_2
kx022a: 8bits
kx132: 10bits
kx12x: 11bits
kx126: 12bits
I think this function is quite generic and can be used for different kionix devices:
- It reads BUF_STATUS_1 and BUF_STATUS_2 and then uses a chip specific mask
- It takes care of the quirk of kx022a which is just a simple if statement
Quoted 15 lines
Quoted 15 lines
drivers/iio/accel/kionix-kx022a.c +2
-1+static int kx022a_drop_fifo_contents (struct kx022a_data *data) {/* @@ -593,35 +588,22 @@ static int kx022a_drop_fifo_contents(struct kx022a_data *data)*/ data->timestamp =0 ; -return regmap_write (data->regmap,KX022A_REG_BUF_CLEAR ,0x0 ); +return regmap_write (data->regmap, data->chip_info->buf_clear,0x0 ); }static int __kx022a_fifo_flush (struct iio_dev *idev,unsigned int samples,bool irq) {struct kx022a_data *data =iio_priv (idev);
Quoted 8 lines
drivers/iio/accel/kionix-kx022a.c static int kx022a_drop_fifo_contents(struct kx022a_data *data) · line 598
Quoted 3 lines
drivers/iio/accel/kionix-kx022a.c +1
-2-struct device *dev =regmap_get_device (data->regmap); -__le16 buffer[KX022A_FIFO_LENGTH *3 ]; +__le16 buffer[data->chip_info->fifo_length *3 ];I don't like this. Having the length of an array decided at run-time is not something I appreciate. Maybe you could just always reserve the memory so that the largest FIFO gets supported. I am just wondering how large arrays we can safely allocate from the stack?
I was stupid enough to ignore the warnings...
I will take care of it in the v2
Quoted 41 lines
Quoted 6 lines
drivers/iio/accel/kionix-kx022a.c +0
-1@@ -812,14 +792,14 @@ static int kx022a_fifo_enable(struct kx022a_data *data) goto unlock_out;/* Enable buffer */ - ret = regmap_set_bits(data->regmap, KX022A_REG_BUF_CNTL2,drivers/iio/accel/kionix-kx022a.c static int kx022a_fifo_enable(struct kx022a_data *data) · line 800
Quoted 10 lines
drivers/iio/accel/kionix-kx022a.c +4
-3- KX022A_MASK_BUF_EN); + ret =regmap_set_bits (data->regmap, data->chip_info->buf_cntl2, +KX_MASK_BUF_EN );if (ret) goto unlock_out; - data->state |=KX022A_STATE_FIFO ; + data->state |=KX_STATE_FIFO ; ret =regmap_set_bits (data->regmap, data->ien_reg, -KX022A_MASK_WMI ); +KX_MASK_WMI );I think this fits to one line now. (even on my screen)
drivers/iio/accel/kionix-kx022a.c static int kx022a_chip_init(struct kx022a_data *data) · line 979
Quoted 5 lines
drivers/iio/accel/kionix-kx022a.c +1
-1if (ret) goto unlock_out; -int kx022a_probe_internal (struct device *dev) +int kx022a_probe_internal (struct device *dev,const struct kx022a_chip_info *chip_info)As mentioned elsewhere, this might also work if the chip-type enum was passed here as parameter. That way the bus specific part would not need to know about the struct
chip_info...drivers/iio/accel/kionix-kx022a.c int kx022a_probe_internal(struct device *dev) · line 1005
Quoted 7 lines
(quoted diff) +0
-0{static const char * const regulator_names[] = {"io-vdd", "vdd"}; struct iio_trigger *indio_trig;drivers/iio/accel/kionix-kx022a.c +1
-0@@ -1023,6 +1003,7 @@ int kx022a_probe_internal(struct device *dev)return -ENOMEM ; data =iio_priv (idev); + data->chip_info = chip_info;...Here you could then pick the correct
chip_infobased on the chip-type enum. In that case I'd like to get theregmap_config(s)in own file. Not sure how that would look like though.
Quoted 1 line
All in all, I like how this looks like. Nice job!
Thank you for the feedback :)
--
Kind Regards
Mehdi Djait
Matti Vaittinen
maintainerRe: [PATCH 2/3] iio: accel: kionix-kx022a: Add chip_info structure
Quoted 37 lines · Mehdi Djait
Hello Matti,
Quoted 26 lines
Quoted 26 lines
drivers/iio/accel/kionix-kx022a.c +26
-0+static int kx022a_get_fifo_bytes (struct kx022a_data *data) +{ +struct device *dev =regmap_get_device (data->regmap); +__le16 buf_status; +int ret, fifo_bytes; + + ret =regmap_bulk_read (data->regmap, data->chip_info->buf_status1, &buf_status,sizeof (buf_status)); +if (ret) { +dev_err (dev,"Error reading buffer status\n" ); +return ret; + } + + buf_status &= data->chip_info->buf_smp_lvl_mask; + fifo_bytes =le16_to_cpu (buf_status); + +/* +* The KX022A has FIFO which can store 43 samples of HiRes data from 2 +* channels. This equals to 43 (samples) * 3 (channels) * 2 (bytes/sample) to +* 258 bytes of sample data. The quirk to know is that the amount of bytes in +* the FIFO is advertised via 8 bit register (max value 255). The thing to note +* is that full 258 bytes of data is indicated using the max value 255. +*/ +if (data->chip_info->type ==KX022A && fifo_bytes ==KX022A_FIFO_FULL_VALUE ) + fifo_bytes =KX022A_FIFO_MAX_BYTES ; + +if (fifo_bytes %KX_FIFO_SAMPLES_SIZE_BYTES )Quoted 8 lines
drivers/iio/accel/kionix-kx022a.c static const struct iio_dev_attr *kx022a_fifo_attributes[] = { · line 576
Quoted 4 lines
drivers/iio/accel/kionix-kx022a.c +4
-0+dev_warn (data->dev,"Bad FIFO alignment. Data may be corrupt\n" ); + +return fifo_bytes; +}I like adding this function. Here I agree with Jonathan - having a device specific functions would clarify this a bit. The KX022A "quirk" is a bit confusing. You could then get rid of the
buf_smp_lvl_mask.
Quoted 4 lines
my bad here, I should have made a separate patch and explained more ...
buf_smp_lvl_maskis essential because kionix products use different number of bits to report "the number of data bytes that have been stored in the sample buffer" using the registersBUF_STATUS_1andBUF_STATUS_2
Yes, they have different size of FIFO, and the KX022A does also have the nasty "FIFO FULL" quirk. Due to this quirk and other differences I was suggesting you created own functions for kx022a and kx132. Eg something along the lines:
static int kx022a_get_fifo_bytes(struct kx022a_data *data) {
...
}
static int kx132_get_fifo_bytes(struct kx022a_data *data) {
...
}
struct chip_info {
...
int (*fifo_bytes)(struct kx022a_data *);
};and do the:fifo_bytes = kx022a_get_fifo_bytes;
orfifo_bytes = kx132_get_fifo_bytes;
in probe. That will also remove the need to check the IC variant for each FIFO read.
If you did that you could remove the buf_smp_lvl_mask and maybe also the buf_statusX members from the chip_info struct (at least for now). You could also do regular read for KX022A and drop the endianess conversion for it. Bulk read is only needed for ICs with more than 8bits of FIFO status. Furthermore, the IC-type check could then go away and the above mentioned KX022A-specific handling would not be obfuscating the kx132 code.
Quoted 6 lines
kx022a: 8bits
kx132: 10bits
kx12x: 11bits
kx126: 12bits
Quoted 6 lines
I think this function is quite generic and can be used for different kionix devices:
- It reads
BUF_STATUS_1andBUF_STATUS_2and then uses a chip specific mask
- It takes care of the quirk of kx022a which is just a simple if statement
Yes. Your function definitely works. And I do like the fact that you did own function for the "amount of data in fifo"-check. Still, the code would be little simpler and perform a tiny bit better if you did two functions instead of one.
Yours,
-- Matti
Signature · 5 lines
Matti Vaittinen Linux kernel developer at ROHM Semiconductors Oulu Finland ~~ When things go utterly wrong vim users can always type :help! ~~
kernel test robot
build botRe: [PATCH 2/3] iio: accel: kionix-kx022a: Add chip_info structure
In reply to Mehdi DjaitThank you for the patch! Perhaps something to improve:
Hi Mehdi,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on jic23-iio/togreg]
[also build test WARNING on next-20230320]
[cannot apply to linus/master v6.3-rc3]
[If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]
url: https://github.com/intel-lab-lkp/linux/commits/Mehdi-Djait/dt-bindings-iio-Add-KX132-accelerometer/20230317-075056 base: https://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio.git togreg patch link: https://lore.kernel.org/r/3ddca10a4c03c3a64afb831cc9dd1e01fe89d305.1679009443.git.mehdi.djait.k%40gmail.com patch subject: [PATCH 2/3] iio: accel: kionix-kx022a: Add chip_info structure config: loongarch-randconfig-s032-20230319 (https://download.01.org/0day-ci/archive/20230321/[email protected]/config) compiler: loongarch64-linux-gcc (GCC) 12.1.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# apt-get install sparse
# sparse version: v0.6.4-39-gce1a6720-dirty
# https://github.com/intel-lab-lkp/linux/commit/40c75341c42d0e5bea5d73961202978a4be41cd2
git remote add linux-review https://github.com/intel-lab-lkp/linux
git fetch --no-tags linux-review Mehdi-Djait/dt-bindings-iio-Add-KX132-accelerometer/20230317-075056
git checkout 40c75341c42d0e5bea5d73961202978a4be41cd2
# save the config file
mkdir build_dir && cp config build_dir/.config
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=loongarch olddefconfig COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-12.1.0 make.cross C=1 CF='-fdiagnostic-prefix -D__CHECK_ENDIAN__' O=build_dir ARCH=loongarch SHELL=/bin/bash drivers/iio/accel/
If you fix the issue, kindly add following tag where applicable
| Reported-by: kernel test robot <[email protected]>
| Link: https://lore.kernel.org/oe-kbuild-all/[email protected]/
sparse warnings: (new ones prefixed by >>)
>> drivers/iio/accel/kionix-kx022a-spi.c:27:19: sparse: sparse: incorrect type in assignment (different modifiers) @@ expected struct kx022a_chip_info *chip_info @@ got void const * @@ drivers/iio/accel/kionix-kx022a-spi.c:27:19: sparse: expected struct kx022a_chip_info *chip_info drivers/iio/accel/kionix-kx022a-spi.c:27:19: sparse: got void const * >> drivers/iio/accel/kionix-kx022a-spi.c:29:27: sparse: sparse: incorrect type in assignment (different modifiers) @@ expected struct kx022a_chip_info *chip_info @@ got struct kx022a_chip_info const * @@
drivers/iio/accel/kionix-kx022a-spi.c:29:27: sparse: expected struct kx022a_chip_info *chip_info
drivers/iio/accel/kionix-kx022a-spi.c:29:27: sparse: got struct kx022a_chip_info const *
vim +27 drivers/iio/accel/kionix-kx022a-spi.c
14
15 static int kx022a_spi_probe(struct spi_device *spi)
16 {
17 struct device *dev = &spi->dev;
18 struct kx022a_chip_info *chip_info;
19 struct regmap *regmap;
20 const struct spi_device_id *id = spi_get_device_id(spi);
21
22 if (!spi->irq) {
23 dev_err(dev, "No IRQ configured\n");
24 return -EINVAL;
25 }
26
> 27 chip_info = device_get_match_data(&spi->dev);
28 if (!chip_info)
> 29 chip_info = (const struct kx022a_chip_info *) id->driver_data;
30
31 regmap = devm_regmap_init_spi(spi, chip_info->regmap_config);
32 if (IS_ERR(regmap))
33 return dev_err_probe(dev, PTR_ERR(regmap),
34 "Failed to initialize Regmap\n");
35
36 return kx022a_probe_internal(dev, chip_info);
37 }
38 Signature · 2 lines
0-DAY CI Kernel Test Service https://github.com/intel/lkp-tests
PATCH 3/3 iio: accel: Add support for Kionix/ROHM KX132 accelerometer
In reply to Mehdi DjaitAdd support for the basic accelerometer features such as getting the acceleration data via IIO. (raw reads, triggered buffer [data-ready] or using the WMI IRQ).
Datasheet: https://kionixfs.azureedge.net/en/document/KX132-1211-Technical-Reference-Manual-Rev-5.0.pdf
--- drivers/iio/accel/kionix-kx022a-i2c.c | 2 + drivers/iio/accel/kionix-kx022a-spi.c | 2 + drivers/iio/accel/kionix-kx022a.c | 126 ++++++++++++++++++++++++++ drivers/iio/accel/kionix-kx022a.h | 53 +++++++++++ 4 files changed, 183 insertions(+)
drivers/iio/accel/kionix-kx022a-i2c.c +2 -0
@@ -38,12 +38,14 @@ static int kx022a_i2c_probe(struct i2c_client *i2c)static const struct i2c_device_id kx022a_i2c_id[] = { { .name ="kx022a" , .driver_data = (kernel_ulong_t)&kx_chip_info[KX022A ] }, + { .name ="kx132" , .driver_data = (kernel_ulong_t)&kx_chip_info[KX132 ] }, { } };MODULE_DEVICE_TABLE (i2c, kx022a_i2c_id);static const struct of_device_id kx022a_of_match[] = { { .compatible ="kionix,kx022a" , .data = &kx_chip_info[KX022A ] }, + { .compatible ="kionix,kx132" , .data = &kx_chip_info[KX132 ] }, { } };MODULE_DEVICE_TABLE (of, kx022a_of_match);
drivers/iio/accel/kionix-kx022a-spi.c +2 -0
@@ -38,12 +38,14 @@ static int kx022a_spi_probe(struct spi_device *spi)static const struct spi_device_id kx022a_spi_id[] = { { .name ="kx022a" , .driver_data = (kernel_ulong_t)&kx_chip_info[KX022A ] }, + { .name ="kx132" , .driver_data = (kernel_ulong_t)&kx_chip_info[KX132 ] }, { } };MODULE_DEVICE_TABLE (spi, kx022a_spi_id);static const struct of_device_id kx022a_of_match[] = { { .compatible ="kionix,kx022a" , .data = &kx_chip_info[KX022A ] }, + { .compatible ="kionix,kx132" , .data = &kx_chip_info[KX132 ] }, { } };MODULE_DEVICE_TABLE (of, kx022a_of_match);
drivers/iio/accel/kionix-kx022a.c +126 -0
144 lines not on this page · raw message
drivers/iio/accel/kionix-kx022a.h +53 -0
61 lines not on this page · raw message
Signature · 1 line
2.30.2
Jonathan Cameron
maintainerQuoted 6 lines · On Fri, 17 Mar 2023 00:48:37 +0100 Mehdi Djait <[email protected]> wrote:
Add support for the basic accelerometer features such as getting the acceleration data via IIO. (raw reads, triggered buffer [data-ready] or using the WMI IRQ).
Datasheet: https://kionixfs.azureedge.net/en/document/KX132-1211-Technical-Reference-Manual-Rev-5.0.pdf
Signed-off-by Mehdi Djait <[email protected]>
Nothing much specific to this patch, most changes will be as a result of bringing this inline with the changes suggested for patch 2.
thanks,
Jonathan
Quoted 201 lines
--- drivers/iio/accel/kionix-kx022a-i2c.c | 2 + drivers/iio/accel/kionix-kx022a-spi.c | 2 + drivers/iio/accel/kionix-kx022a.c | 126 ++++++++++++++++++++++++++ drivers/iio/accel/kionix-kx022a.h | 53 +++++++++++ 4 files changed, 183 insertions(+)drivers/iio/accel/kionix-kx022a-i2c.c +2
-0@@ -38,12 +38,14 @@ static int kx022a_i2c_probe(struct i2c_client *i2c)static const struct i2c_device_id kx022a_i2c_id[] = { { .name ="kx022a" , .driver_data = (kernel_ulong_t)&kx_chip_info[KX022A ] }, + { .name ="kx132" , .driver_data = (kernel_ulong_t)&kx_chip_info[KX132 ] }, { } };MODULE_DEVICE_TABLE (i2c, kx022a_i2c_id);static const struct of_device_id kx022a_of_match[] = { { .compatible ="kionix,kx022a" , .data = &kx_chip_info[KX022A ] }, + { .compatible ="kionix,kx132" , .data = &kx_chip_info[KX132 ] }, { } };MODULE_DEVICE_TABLE (of, kx022a_of_match);drivers/iio/accel/kionix-kx022a-spi.c +2
-0@@ -38,12 +38,14 @@ static int kx022a_spi_probe(struct spi_device *spi)static const struct spi_device_id kx022a_spi_id[] = { { .name ="kx022a" , .driver_data = (kernel_ulong_t)&kx_chip_info[KX022A ] }, + { .name ="kx132" , .driver_data = (kernel_ulong_t)&kx_chip_info[KX132 ] }, { } };MODULE_DEVICE_TABLE (spi, kx022a_spi_id);static const struct of_device_id kx022a_of_match[] = { { .compatible ="kionix,kx022a" , .data = &kx_chip_info[KX022A ] }, + { .compatible ="kionix,kx132" , .data = &kx_chip_info[KX132 ] }, { } };MODULE_DEVICE_TABLE (of, kx022a_of_match);drivers/iio/accel/kionix-kx022a.c +126
-0@@ -128,6 +128,101 @@ static const struct regmap_config kx022a_regmap_config = { .cache_type = REGCACHE_RBTREE, }; +/* Regmap configs kx132 */ +static const struct regmap_range kx132_volatile_ranges[] = { + { + .range_min =KX132_REG_XADP_L , + .range_max =KX132_REG_COTR , + }, { + .range_min =KX132_REG_TSCP , + .range_max =KX132_REG_INT_REL , + }, { +/* The reset bit will be cleared by sensor */ + .range_min =KX132_REG_CNTL2 , + .range_max =KX132_REG_CNTL2 , + }, { + .range_min =KX132_REG_BUF_STATUS_1 , + .range_max =KX132_REG_BUF_READ , + }, +}; + +static const struct regmap_access_table kx132_volatile_regs = { + .yes_ranges = &kx132_volatile_ranges[0 ], + .n_yes_ranges =ARRAY_SIZE (kx132_volatile_ranges), +}; + +static const struct regmap_range kx132_precious_ranges[] = { + { + .range_min =KX132_REG_INT_REL , + .range_max =KX132_REG_INT_REL , + }, +}; + +static const struct regmap_access_table kx132_precious_regs = { + .yes_ranges = &kx132_precious_ranges[0 ], + .n_yes_ranges =ARRAY_SIZE (kx132_precious_ranges), +}; + +static const struct regmap_range kx132_read_only_ranges[] = { + { + .range_min =KX132_REG_XADP_L , + .range_max =KX132_REG_INT_REL , + }, { + .range_min =KX132_REG_BUF_STATUS_1 , + .range_max =KX132_REG_BUF_STATUS_2 , + }, { + .range_min =KX132_REG_BUF_READ , + .range_max =KX132_REG_BUF_READ , + }, +}; + +static const struct regmap_access_table kx132_ro_regs = { + .no_ranges = &kx132_read_only_ranges[0 ], + .n_no_ranges =ARRAY_SIZE (kx132_read_only_ranges), +}; + +static const struct regmap_range kx132_write_only_ranges[] = { + { + .range_min =KX132_REG_MAN_WAKE , + .range_max =KX132_REG_MAN_WAKE , + }, { + .range_min =KX132_REG_SELF_TEST , + .range_max =KX132_REG_SELF_TEST , + }, { + .range_min =KX132_REG_BUF_CLEAR , + .range_max =KX132_REG_BUF_CLEAR , + }, +}; + +static const struct regmap_access_table kx132_wo_regs = { + .no_ranges = &kx132_write_only_ranges[0 ], + .n_no_ranges =ARRAY_SIZE (kx132_write_only_ranges), +}; + +static const struct regmap_range kx132_noinc_read_ranges[] = { + { + .range_min =KX132_REG_BUF_READ , + .range_max =KX132_REG_BUF_READ , + }, +}; + +static const struct regmap_access_table kx132_nir_regs = { + .yes_ranges = &kx132_noinc_read_ranges[0 ], + .n_yes_ranges =ARRAY_SIZE (kx132_noinc_read_ranges), +}; + +static const struct regmap_config kx132_regmap_config = { + .reg_bits =8 , + .val_bits =8 , + .volatile_table = &kx132_volatile_regs, + .rd_table = &kx132_wo_regs, + .wr_table = &kx132_ro_regs, + .rd_noinc_table = &kx132_nir_regs, + .precious_table = &kx132_precious_regs, + .max_register =KX132_MAX_REGISTER , + .cache_type =REGCACHE_RBTREE , +}; +static const struct iio_mount_matrix *kx022a_get_mount_matrix (const struct iio_dev *idev,const struct iio_chan_spec *chan)@@ -175,6 +270,13 @@ static const struct iio_chan_spec kx022a_channels[] = { IIO_CHAN_SOFT_TIMESTAMP(3), }; +static const struct iio_chan_spec kx132_channels[] = { +KX022A_ACCEL_CHAN (X ,0 ,KX132 ), +KX022A_ACCEL_CHAN (Y ,1 ,KX132 ), +KX022A_ACCEL_CHAN (Z ,2 ,KX132 ), +IIO_CHAN_SOFT_TIMESTAMP (3 ), +}; +/* * The sensor HW can support ODR up to 1600 Hz, which is beyond what most of the * Linux CPUs can handle without dropping samples. Also, the low power mode is @@ -249,6 +351,30 @@ const struct kx022a_chip_info kx_chip_info[] = { .inc6 = KX022A_REG_INC6, .xout_l = KX022A_REG_XOUT_L, }, + [KX132] = { + .name = "kx132", + .type = KX132, + .regmap_config = &kx132_regmap_config, + .channels = kx132_channels, + .num_channels = ARRAY_SIZE(kx132_channels), + .fifo_length = KX132_FIFO_LENGTH, + .who = KX132_REG_WHO, + .id = KX132_ID, + .cntl = KX132_REG_CNTL, + .cntl2 = KX132_REG_CNTL2, + .odcntl = KX132_REG_ODCNTL, + .buf_cntl1 = KX132_REG_BUF_CNTL1, + .buf_cntl2 = KX132_REG_BUF_CNTL2, + .buf_clear = KX132_REG_BUF_CLEAR, + .buf_status1 = KX132_REG_BUF_STATUS_1, + .buf_smp_lvl_mask = KX132_MASK_BUF_SMP_LVL, + .buf_read = KX132_REG_BUF_READ, + .inc1 = KX132_REG_INC1, + .inc4 = KX132_REG_INC4, + .inc5 = KX132_REG_INC5, + .inc6 = KX132_REG_INC6, + .xout_l = KX132_REG_XOUT_L, + }, };EXPORT_SYMBOL_NS_GPL (kx_chip_info,IIO_KX022A );drivers/iio/accel/kionix-kx022a.h +0
-0
drivers/iio/accel/kionix-kx022a.h line 93
Quoted 4 lines
drivers/iio/accel/kionix-kx022a.h +1
-0@@ -90,8 +90,61 @@#define KX022A_REG_SELF_TEST 0x60#define KX022A_MAX_REGISTER 0x60 +
Push these down into the c file.
Quoted 44 lines
drivers/iio/accel/kionix-kx022a.h +44
-0+#define KX132_REG_WHO 0x13 +#define KX132_ID 0x3d + +#define KX132_FIFO_LENGTH 86 + +#define KX132_REG_CNTL2 0x1c +#define KX132_REG_CNTL 0x1b +#define KX132_MASK_RES BIT(6) +#define KX132_GSEL_2 0x0 +#define KX132_GSEL_4 BIT(3) +#define KX132_GSEL_8 BIT(4) +#define KX132_GSEL_16 GENMASK(4, 3) + +#define KX132_REG_INS2 0x17 +#define KX132_MASK_INS2_WMI BIT(5) + +#define KX132_REG_XADP_L 0x02 +#define KX132_REG_XOUT_L 0x08 +#define KX132_REG_YOUT_L 0x0a +#define KX132_REG_ZOUT_L 0x0c +#define KX132_REG_COTR 0x12 +#define KX132_REG_TSCP 0x14 +#define KX132_REG_INT_REL 0x1a + +#define KX132_REG_ODCNTL 0x21 + +#define KX132_REG_BTS_WUF_TH 0x4a +#define KX132_REG_MAN_WAKE 0x4d + +#define KX132_REG_BUF_CNTL1 0x5e +#define KX132_REG_BUF_CNTL2 0x5f +#define KX132_REG_BUF_STATUS_1 0x60 +#define KX132_REG_BUF_STATUS_2 0x61 +#define KX132_MASK_BUF_SMP_LVL GENMASK(9, 0) +#define KX132_REG_BUF_CLEAR 0x62 +#define KX132_REG_BUF_READ 0x63 +#define KX132_ODR_SHIFT 3 +#define KX132_FIFO_MAX_WMI_TH 86 + +#define KX132_REG_INC1 0x22 +#define KX132_REG_INC5 0x26 +#define KX132_REG_INC6 0x27 +#define KX132_IPOL_LOW 0 +#define KX132_IPOL_HIGH KX_MASK_IPOL
drivers/iio/accel/kionix-kx022a.h line 147
Quoted 10 lines
drivers/iio/accel/kionix-kx022a.h +8
-0+#define KX132_ITYP_PULSE KX_MASK_ITYP + +#define KX132_REG_INC4 0x25 + +#define KX132_REG_SELF_TEST 0x5d +#define KX132_MAX_REGISTER 0x76 +enum kx022a_device_type {KX022A , +KX132 ,
As mentioned in previous review, I think this would be neater done by just exporting the chip_info structures directly rather than putting them in an array.
Quoted 3 lines
drivers/iio/accel/kionix-kx022a.h +0
-0};enum {
Hello Jonathan,
Quoted 25 lines · Jonathan Cameron
Quoted 6 lines · On Fri, 17 Mar 2023 00:48:37 +0100 Mehdi Djait <[email protected]> wrote:
Add support for the basic accelerometer features such as getting the acceleration data via IIO. (raw reads, triggered buffer [data-ready] or using the WMI IRQ).
Datasheet: https://kionixfs.azureedge.net/en/document/KX132-1211-Technical-Reference-Manual-Rev-5.0.pdf
Signed-off-by Mehdi Djait <[email protected]>Nothing much specific to this patch, most changes will be as a result of bringing this inline with the changes suggested for patch 2.
thanks,
Jonathan
Quoted 9 lines
drivers/iio/accel/kionix-kx022a.h +0
-0@@ -90,8 +90,61 @@#define KX022A_REG_SELF_TEST 0x60#define KX022A_MAX_REGISTER 0x60
Quoted 3 lines
drivers/iio/accel/kionix-kx022a.h line 93
Quoted 1 line
drivers/iio/accel/kionix-kx022a.h +1
-0+Push these down into the c file.
Do you mean all REG and MASK defines ?
Even kx022a defines them in the h file, or am I misunderstanding your comment ?
Quoted 50 lines
Quoted 50 lines
drivers/iio/accel/kionix-kx022a.h +49
-0+#define KX132_REG_WHO 0x13 +#define KX132_ID 0x3d + +#define KX132_FIFO_LENGTH 86 + +#define KX132_REG_CNTL2 0x1c +#define KX132_REG_CNTL 0x1b +#define KX132_MASK_RES BIT(6) +#define KX132_GSEL_2 0x0 +#define KX132_GSEL_4 BIT(3) +#define KX132_GSEL_8 BIT(4) +#define KX132_GSEL_16 GENMASK(4, 3) + +#define KX132_REG_INS2 0x17 +#define KX132_MASK_INS2_WMI BIT(5) + +#define KX132_REG_XADP_L 0x02 +#define KX132_REG_XOUT_L 0x08 +#define KX132_REG_YOUT_L 0x0a +#define KX132_REG_ZOUT_L 0x0c +#define KX132_REG_COTR 0x12 +#define KX132_REG_TSCP 0x14 +#define KX132_REG_INT_REL 0x1a + +#define KX132_REG_ODCNTL 0x21 + +#define KX132_REG_BTS_WUF_TH 0x4a +#define KX132_REG_MAN_WAKE 0x4d + +#define KX132_REG_BUF_CNTL1 0x5e +#define KX132_REG_BUF_CNTL2 0x5f +#define KX132_REG_BUF_STATUS_1 0x60 +#define KX132_REG_BUF_STATUS_2 0x61 +#define KX132_MASK_BUF_SMP_LVL GENMASK(9, 0) +#define KX132_REG_BUF_CLEAR 0x62 +#define KX132_REG_BUF_READ 0x63 +#define KX132_ODR_SHIFT 3 +#define KX132_FIFO_MAX_WMI_TH 86 + +#define KX132_REG_INC1 0x22 +#define KX132_REG_INC5 0x26 +#define KX132_REG_INC6 0x27 +#define KX132_IPOL_LOW 0 +#define KX132_IPOL_HIGH KX_MASK_IPOL +#define KX132_ITYP_PULSE KX_MASK_ITYP + +#define KX132_REG_INC4 0x25 + +#define KX132_REG_SELF_TEST 0x5d
Quoted 8 lines
drivers/iio/accel/kionix-kx022a.h line 147
Quoted 5 lines
drivers/iio/accel/kionix-kx022a.h +3
-0+#define KX132_MAX_REGISTER 0x76 +enum kx022a_device_type {KX022A , +KX132 ,As mentioned in previous review, I think this would be neater done by just exporting the
chip_infostructures directly rather than putting them in an array.
I gave the reason in a response to the previous review.
--
Kind Regards
Mehdi Djait
Jonathan Cameron
maintainerQuoted 28 lines · On Tue, 21 Mar 2023 17:34:15 +0100 Mehdi Djait <[email protected]> wrote:
Hello Jonathan,
Quoted 25 lines · Jonathan Cameron
Quoted 6 lines · On Fri, 17 Mar 2023 00:48:37 +0100 Mehdi Djait <[email protected]> wrote:
Add support for the basic accelerometer features such as getting the acceleration data via IIO. (raw reads, triggered buffer [data-ready] or using the WMI IRQ).
Datasheet: https://kionixfs.azureedge.net/en/document/KX132-1211-Technical-Reference-Manual-Rev-5.0.pdf
Signed-off-by Mehdi Djait <[email protected]>Nothing much specific to this patch, most changes will be as a result of bringing this inline with the changes suggested for patch 2.
thanks,
Jonathan
Quoted 9 lines
drivers/iio/accel/kionix-kx022a.h +0
-0@@ -90,8 +90,61 @@#define KX022A_REG_SELF_TEST 0x60#define KX022A_MAX_REGISTER 0x60
Quoted 7 lines
Quoted 3 lines
drivers/iio/accel/kionix-kx022a.h line 93
Quoted 1 line
drivers/iio/accel/kionix-kx022a.h +1
-0+Push these down into the c file.
Do you mean all REG and MASK defines ?
Even kx022a defines them in the h file, or am I misunderstanding your comment ?
Hmm. Generally we only put reg defines in a header if they
are accessed from multiple c files. Otherwise it's both noise and more code that has to be parsed when compiling (even if it's all unused / ignored).
I'm fine with this patch set just continuing with local style given they are already there, but if you fancy moving the existing ones down to the C file as a precursor patch, then even better!
Quoted 60 lines
Quoted 51 lines
Quoted 51 lines
drivers/iio/accel/kionix-kx022a.h +49
-0+#define KX132_REG_WHO 0x13 +#define KX132_ID 0x3d + +#define KX132_FIFO_LENGTH 86 + +#define KX132_REG_CNTL2 0x1c +#define KX132_REG_CNTL 0x1b +#define KX132_MASK_RES BIT(6) +#define KX132_GSEL_2 0x0 +#define KX132_GSEL_4 BIT(3) +#define KX132_GSEL_8 BIT(4) +#define KX132_GSEL_16 GENMASK(4, 3) + +#define KX132_REG_INS2 0x17 +#define KX132_MASK_INS2_WMI BIT(5) + +#define KX132_REG_XADP_L 0x02 +#define KX132_REG_XOUT_L 0x08 +#define KX132_REG_YOUT_L 0x0a +#define KX132_REG_ZOUT_L 0x0c +#define KX132_REG_COTR 0x12 +#define KX132_REG_TSCP 0x14 +#define KX132_REG_INT_REL 0x1a + +#define KX132_REG_ODCNTL 0x21 + +#define KX132_REG_BTS_WUF_TH 0x4a +#define KX132_REG_MAN_WAKE 0x4d + +#define KX132_REG_BUF_CNTL1 0x5e +#define KX132_REG_BUF_CNTL2 0x5f +#define KX132_REG_BUF_STATUS_1 0x60 +#define KX132_REG_BUF_STATUS_2 0x61 +#define KX132_MASK_BUF_SMP_LVL GENMASK(9, 0) +#define KX132_REG_BUF_CLEAR 0x62 +#define KX132_REG_BUF_READ 0x63 +#define KX132_ODR_SHIFT 3 +#define KX132_FIFO_MAX_WMI_TH 86 + +#define KX132_REG_INC1 0x22 +#define KX132_REG_INC5 0x26 +#define KX132_REG_INC6 0x27 +#define KX132_IPOL_LOW 0 +#define KX132_IPOL_HIGH KX_MASK_IPOL +#define KX132_ITYP_PULSE KX_MASK_ITYP + +#define KX132_REG_INC4 0x25 + +#define KX132_REG_SELF_TEST 0x5dQuoted 8 lines
drivers/iio/accel/kionix-kx022a.h line 147
Quoted 5 lines
drivers/iio/accel/kionix-kx022a.h +3
-0+#define KX132_MAX_REGISTER 0x76 +enum kx022a_device_type {KX022A , +KX132 ,As mentioned in previous review, I think this would be neater done by just exporting the
chip_infostructures directly rather than putting them in an array.
Quoted 1 line
I gave the reason in a response to the previous review.
If you strongly prefer the enum indexing array that's fine, but definitely don't use the enum for the data in the tables - that should be the pointer to the particular element of the array.
Quoted 4 lines
--
Kind Regards
Mehdi Djait
Matti Vaittinen
maintainerQuoted 4 lines · Mehdi Djait
Add support for the basic accelerometer features such as getting the acceleration data via IIO. (raw reads, triggered buffer [data-ready] or using the WMI IRQ).
Hi Mehdi,
I have nothing to say to this patch yet. Let's see how it looks like after the comments from Jonathan/Andy have been discussed/reworked :)
Yours,
-- Matti
Signature · 5 lines
Matti Vaittinen Linux kernel developer at ROHM Semiconductors Oulu Finland ~~ When things go utterly wrong vim users can always type :help! ~~
Quoted 6 lines · Mehdi Djait
KX132 accelerometer is a sensor which:
- supports G-ranges of (+/-) 2, 4, 8, and 16G
- can be connected to I2C or SPI
- has internal HW FIFO buffer
- supports various ODRs (output data rates)
Quoted 6 lines
The KX132 accelerometer is very similair to the KX022A.
One key difference is number of bits to report the number of data bytes that have been stored in the sample buffer: 8 bits for KX022A vs 10 bits for KX132.A complete list of differences is listed in [1]
[1] https://kionixfs.azureedge.net/en/document/AN112-Transitioning-to-KX132-1211-Accelerometer.pdf1
Is it really the first version of this contribution?
Signature · 2 lines
With Best Regards, Andy Shevchenko
Hi Andy,
Quoted 7 lines · Andy Shevchenko
Quoted 6 lines · Mehdi Djait
KX132 accelerometer is a sensor which:
- supports G-ranges of (+/-) 2, 4, 8, and 16G
- can be connected to I2C or SPI
- has internal HW FIFO buffer
- supports various ODRs (output data rates)
Quoted 9 lines
Quoted 6 lines
The KX132 accelerometer is very similair to the KX022A.
One key difference is number of bits to report the number of data bytes that have been stored in the sample buffer: 8 bits for KX022A vs 10 bits for KX132.A complete list of differences is listed in [1]
[1] https://kionixfs.azureedge.net/en/document/AN112-Transitioning-to-KX132-1211-Accelerometer.pdf1Is it really the first version of this contribution?
Yes this is my first series for the KX132 Support.
--
Kind Regards
Mehdi Djait
Matti Vaittinen
maintainerHi Mehdi,
Things have been piling up for me during last two weeks... I will do proper review during next week.
Quoted 9 lines · Mehdi Djait
KX132 accelerometer is a sensor which:
- supports G-ranges of (+/-) 2, 4, 8, and 16G
- can be connected to I2C or SPI
- has internal HW FIFO buffer
- supports various ODRs (output data rates)The KX132 accelerometer is very similair to the KX022A.
One key difference is number of bits to report the number of data bytes that have been stored in the sample buffer: 8 bits for KX022A vs 10 bits for KX132.
The KX022A has 16bits of data in HiRes mode. This is the default for kx022a driver.
Quoted 4 lines
A complete list of differences is listed in [1]
[1] https://kionixfs.azureedge.net/en/document/AN112-Transitioning-to-KX132-1211-Accelerometer.pdf1
This document is somewhat misleading. It does not contain KX022A but the older KX022. Kionix has the somewhat confusing habit of having very similar names for models with - occasionally significant - differences. (My own opinion).
I the "Technical referene manual" is more interesting document than the data-sheet:
https://kionixfs.azureedge.net/en/document/KX132-1211-Technical-Reference-Manual-Rev-5.0.pdf
I have heard that there have been a few very different versions of KX132 as well. Not sure if they have "leaked" out to public though. In any case, for the kx132 it might be safest to use the full model name - especially in the DT compatibles.
Finally, AFAIK the key "thing" in KX132 is the "ADP" (Advanced Data Path) feature which allows filtering the data "in sensor". Unfortunately, I am not really familiar with this feature. Do you think this is something that might get configured only once at start-up depending on the purpose of the board? If yes, this might be something that will end-up having properties in device-tree. If yes, then it might be a good idea to have own binding doc for KX132. Currently it seems Ok to have them in the same binding doc though.
Anyways, I'll have proper look at this series during the next week - Thanks for the contribution! Much appreciated!
Yours,
-- Matti
Quoted 12 lines
Mehdi Djait (3):
dt-bindings: iio: Add KX132 accelerometer
iio: accel: kionix-kx022a: Addchip_infostructure
iio: accel: Add support for Kionix/ROHM KX132 accelerometer.../bindings/iio/accel/kionix,kx022a.yaml | 13 +- drivers/iio/accel/kionix-kx022a-i2c.c | 21 +- drivers/iio/accel/kionix-kx022a-spi.c | 24 +- drivers/iio/accel/kionix-kx022a.c | 413 +++++++++++------- drivers/iio/accel/kionix-kx022a.h | 181 +++++++- 5 files changed, 464 insertions(+), 188 deletions(-)
Signature · 5 lines
Matti Vaittinen Linux kernel developer at ROHM Semiconductors Oulu Finland ~~ When things go utterly wrong vim users can always type :help! ~~
Hi Matti,
Quoted 12 lines · Matti Vaittinen
Hi Mehdi,
Things have been piling up for me during last two weeks... I will do proper review during next week.
Quoted 6 lines · Mehdi Djait
KX132 accelerometer is a sensor which:
- supports G-ranges of (+/-) 2, 4, 8, and 16G
- can be connected to I2C or SPI
- has internal HW FIFO buffer
- supports various ODRs (output data rates)
Quoted 6 lines
Quoted 3 lines
The KX132 accelerometer is very similair to the KX022A.
One key difference is number of bits to report the number of data bytes that have been stored in the sample buffer: 8 bits for KX022A vs 10 bits for KX132.The KX022A has 16bits of data in HiRes mode. This is the default for kx022a driver.
I am talking here about "Buffer Sample Level number of bits": kx022a uses 8 bits: just BUF_STATUS_1 to report the status of the buffer. kx132 uses BUF_STATUS_1 and the Bit0, Bit1 of BUF_STATUS_2.
That's the reason for adding the kx022a_get_fifo_bytes function.
Quoted 10 lines
Quoted 5 lines
A complete list of differences is listed in [1]
[1] https://kionixfs.azureedge.net/en/document/AN112-Transitioning-to-KX132-1211-Accelerometer.pdf1
This document is somewhat misleading. It does not contain KX022A but the older KX022. Kionix has the somewhat confusing habit of having very similar names for models with - occasionally significant - differences. (My own opinion).
Yes, I am aware that it does not contain KX022A, but from my understanding of your code, the document can be used to highlight the difference I mentioned
Quoted 11 lines
I the "Technical referene manual" is more interesting document than the data-sheet:
https://kionixfs.azureedge.net/en/document/KX132-1211-Technical-Reference-Manual-Rev-5.0.pdf
I have heard that there have been a few very different versions of KX132 as well. Not sure if they have "leaked" out to public though. In any case, for the kx132 it might be safest to use the full model name - especially in the DT compatibles.
I will change it to kx132-1211
Quoted 9 lines
Finally, AFAIK the key "thing" in KX132 is the "ADP" (Advanced Data Path) feature which allows filtering the data "in sensor". Unfortunately, I am not really familiar with this feature. Do you think this is something that might get configured only once at start-up depending on the purpose of the board? If yes, this might be something that will end-up having properties in device-tree. If yes, then it might be a good idea to have own binding doc for KX132. Currently it seems Ok to have them in the same binding doc though.
Correct me if I am wrong: the Devicetree is a description of the hardware and the transitioning document states:
"From a hardware perspective, all these sensors
have an identical pad/pin layouts and identical pin functionality"
I was thinking about adding an advanced_data_path boolean to the chip_info struct and providing different driver callbacks depending on the value.
Something like in the bmc150-accel-core: iio_info for bmc150_accel_info and iio_info for bmc150_accel_info_fifo
--
Kind Regards
Mehdi Djait
Matti Vaittinen
maintainerQuoted 15 lines · Mehdi Djait
Hi Matti,
Quoted 12 lines · Matti Vaittinen
Hi Mehdi,
Things have been piling up for me during last two weeks... I will do proper review during next week.
Quoted 6 lines · Mehdi Djait
KX132 accelerometer is a sensor which:
- supports G-ranges of (+/-) 2, 4, 8, and 16G
- can be connected to I2C or SPI
- has internal HW FIFO buffer
- supports various ODRs (output data rates)
Quoted 8 lines
Quoted 6 lines
Quoted 3 lines
The KX132 accelerometer is very similair to the KX022A.
One key difference is number of bits to report the number of data bytes that have been stored in the sample buffer: 8 bits for KX022A vs 10 bits for KX132.The KX022A has 16bits of data in HiRes mode. This is the default for kx022a driver.
I am talking here about "Buffer Sample Level number of bits":
Ah. My bad. I misunderstood. Mentioning the number of bits made me to instantly think of the format of measured data not the size of the FIFO and how many bits are needed to represent the full FIFO.
kx022a uses
Quoted 11 lines
8 bits: just
BUF_STATUS_1to report the status of the buffer. kx132 usesBUF_STATUS_1and the Bit0, Bit1 ofBUF_STATUS_2.That's the reason for adding the
kx022a_get_fifo_bytesfunction.Quoted 6 lines
Quoted 5 lines
A complete list of differences is listed in [1]
[1] https://kionixfs.azureedge.net/en/document/AN112-Transitioning-to-KX132-1211-Accelerometer.pdf1
Quoted 8 lines
Quoted 4 lines
This document is somewhat misleading. It does not contain KX022A but the older KX022. Kionix has the somewhat confusing habit of having very similar names for models with - occasionally significant - differences. (My own opinion).
Yes, I am aware that it does not contain KX022A, but from my understanding of your code, the document can be used to highlight the difference I mentioned
I don't remember all the differences between the KX022 and KX022A - but I believe at least the supported G-ranges were different. I think there probably were also some other things.
Quoted 10 lines
Quoted 9 lines
Finally, AFAIK the key "thing" in KX132 is the "ADP" (Advanced Data Path) feature which allows filtering the data "in sensor". Unfortunately, I am not really familiar with this feature. Do you think this is something that might get configured only once at start-up depending on the purpose of the board? If yes, this might be something that will end-up having properties in device-tree. If yes, then it might be a good idea to have own binding doc for KX132. Currently it seems Ok to have them in the same binding doc though.
Quoted 2 lines
Correct me if I am wrong: the Devicetree is a description of the hardware
Yes.
Quoted 4 lines
and the transitioning document states:
"From a hardware perspective, all these sensors
have an identical pad/pin layouts and identical pin functionality"
Sometimes (fixed) hardware _configuration_ can be visible in device-tree. Eg, device-tree can be used to tell: "On this board this configurable piece of hardware shall look like this". My understanding of ADP is very limited, but I thought it may be used to adjust the hardware by for example adding some filters.
As I said, I however don't know if the ADP will be used with 'static configurations' which could be seen as hardware properties. Hence I asked if you had insight to this.
Quoted 2 lines
I was thinking about adding an
advanced_data_pathboolean to thechip_infostruct and providing different driver callbacks depending on the value.
I can't really comment on this much as I lack of knowledge. I have understood the ADP can be configured to do very different type of filtering(?) I wonder how the boolean flag suits these needs but I guess we can go into those details when ADP support is being implemented. Right now I am happy if you say you have analyzed the ADP to the point you don't expect many kx132 specific dt-bindings to be needed. And. even if this analysis was wrong, we can later separate the kx132 bindings to own doc if that is needed. So, I am happy with the bindings being in same file now.
Quoted 2 lines
Something like in the bmc150-accel-core:
iio_infoforbmc150_accel_infoandiio_infoforbmc150_accel_info_fifo
I will see those later, thanks.
Yours
-- Matti
Signature · 5 lines
Matti Vaittinen Linux kernel developer at ROHM Semiconductors Oulu Finland ~~ When things go utterly wrong vim users can always type :help! ~~