* [PATCH v4 0/5] Add support for LTC6373
@ 2024-01-17 12:51 Dumitru Ceclan
2024-01-17 12:51 ` [PATCH v4 1/5] dt-bindings: iio: hmc425a: add conditional GPIO array size constraints Dumitru Ceclan
` (4 more replies)
0 siblings, 5 replies; 10+ messages in thread
From: Dumitru Ceclan @ 2024-01-17 12:51 UTC (permalink / raw)
Cc: Lars-Peter Clausen, Jonathan Cameron, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, linux-iio, devicetree,
linux-kernel, Ceclan Dumitru, Dumitru Ceclan
This patch series adds support for the LTC6373 Instrumentation Amplifier within
the existing HMC425A driver.
The LTC6373 is a silicon, 3-bit Fully-Differential digital instrumentation
amplifier that supports the following programmable gains (Vout/Vin):
G = 0.25, 0.5, 1, 2, 4, 8, 16 + Shutdown.
The programmable interface consists of 3 digitally controled inputs.
V3->V4
- Fix git commit message typo and remove newline between tags
V2->V3
- Use return instead of break in *_gain_dB_to_code()
- Add new line before return in *_code_to_gain_dB()
- Match parameter alignment for added _powerdown functions
- Add precursor patch for using pointers in the match table
- Add chip_info attributes: has_powerdown and powerdown_val
- Change probe logic to use has_powerdown for default powerdown state
- Added 'Fixes' tag to commit message of 'add conditional GPIO array...'
V1->V2
Driver:
- Fix chip info table indent
- Remove enable attribute
- Add ext_info powerdown attribute
- Enable by default powerdown attribute
- Set default gain after disabling powerdown to min value
Binding:
- Fix conditional checking of GPIO array size for LTC6373
- Add precursor commit for correctly checking gpio size depending upon compatible
Dumitru Ceclan (5):
dt-bindings: iio: hmc425a: add conditional GPIO array size constraints
dt-bindings: iio: hmc425a: add entry for LTC6373
iio: amplifiers: hmc425a: move conversion logic
iio: amplifiers: hmc425a: use pointers in match table
iio: amplifiers: hmc425a: add support for LTC6373 Instrumentation
Amplifier
.../bindings/iio/amplifiers/adi,hmc425a.yaml | 47 +++-
drivers/iio/amplifiers/hmc425a.c | 253 +++++++++++++-----
2 files changed, 236 insertions(+), 64 deletions(-)
--
2.42.0
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH v4 1/5] dt-bindings: iio: hmc425a: add conditional GPIO array size constraints
2024-01-17 12:51 [PATCH v4 0/5] Add support for LTC6373 Dumitru Ceclan
@ 2024-01-17 12:51 ` Dumitru Ceclan
2024-01-17 12:51 ` [PATCH v4 2/5] dt-bindings: iio: hmc425a: add entry for LTC6373 Dumitru Ceclan
` (3 subsequent siblings)
4 siblings, 0 replies; 10+ messages in thread
From: Dumitru Ceclan @ 2024-01-17 12:51 UTC (permalink / raw)
Cc: Lars-Peter Clausen, Jonathan Cameron, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, linux-iio, devicetree,
linux-kernel, Ceclan Dumitru, Dumitru Ceclan, Conor Dooley
ADRF5740 and HMC540S have a 4 bit parallel interface.
Update ctrl-gpios description and min/maxItems values depending on the
matched compatible to correctly reflect the hardware properties.
Fixes: 79f2ff6461e7 ("dt-bindings: iio: hmc425a: add entry for ADRF5740 Attenuator")
Fixes: 20f87a9a26be ("dt-bindings: iio: hmc425a: add entry for HMC540S")
Acked-by: Conor Dooley <conor.dooley@microchip.com>
Signed-off-by: Dumitru Ceclan <mitrutzceclan@gmail.com>
---
.../bindings/iio/amplifiers/adi,hmc425a.yaml | 33 +++++++++++++++++--
1 file changed, 30 insertions(+), 3 deletions(-)
diff --git a/Documentation/devicetree/bindings/iio/amplifiers/adi,hmc425a.yaml b/Documentation/devicetree/bindings/iio/amplifiers/adi,hmc425a.yaml
index 67de9d4e3a1d..a434cb8ddcc9 100644
--- a/Documentation/devicetree/bindings/iio/amplifiers/adi,hmc425a.yaml
+++ b/Documentation/devicetree/bindings/iio/amplifiers/adi,hmc425a.yaml
@@ -33,11 +33,38 @@ properties:
ctrl-gpios:
description:
- Must contain an array of 6 GPIO specifiers, referring to the GPIO pins
- connected to the control pins V1-V6.
- minItems: 6
+ Must contain an array of GPIO specifiers, referring to the GPIO pins
+ connected to the control pins.
+ ADRF5740 - 4 GPIO connected to D2-D5
+ HMC540S - 4 GPIO connected to V1-V4
+ HMC425A - 6 GPIO connected to V1-V6
+ minItems: 1
maxItems: 6
+allOf:
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: adi,hmc425a
+ then:
+ properties:
+ ctrl-gpios:
+ minItems: 6
+ maxItems: 6
+ - if:
+ properties:
+ compatible:
+ contains:
+ anyOf:
+ - const: adi,adrf5740
+ - const: adi,hmc540s
+ then:
+ properties:
+ ctrl-gpios:
+ minItems: 4
+ maxItems: 4
+
required:
- compatible
- ctrl-gpios
--
2.42.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v4 2/5] dt-bindings: iio: hmc425a: add entry for LTC6373
2024-01-17 12:51 [PATCH v4 0/5] Add support for LTC6373 Dumitru Ceclan
2024-01-17 12:51 ` [PATCH v4 1/5] dt-bindings: iio: hmc425a: add conditional GPIO array size constraints Dumitru Ceclan
@ 2024-01-17 12:51 ` Dumitru Ceclan
2024-01-17 12:51 ` [PATCH v4 3/5] iio: amplifiers: hmc425a: move conversion logic Dumitru Ceclan
` (2 subsequent siblings)
4 siblings, 0 replies; 10+ messages in thread
From: Dumitru Ceclan @ 2024-01-17 12:51 UTC (permalink / raw)
Cc: Lars-Peter Clausen, Jonathan Cameron, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, linux-iio, devicetree,
linux-kernel, Ceclan Dumitru, Dumitru Ceclan, Conor Dooley
The LTC6373 is a silicon, 3-bit Fully-Differential digital instrumentation
amplifier that supports the following programmable gains (Vout/Vin):
G = 0.25, 0.5, 1, 2, 4, 8, 16 + Shutdown.
Acked-by: Conor Dooley <conor.dooley@microchip.com>
Signed-off-by: Dumitru Ceclan <mitrutzceclan@gmail.com>
---
.../bindings/iio/amplifiers/adi,hmc425a.yaml | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/Documentation/devicetree/bindings/iio/amplifiers/adi,hmc425a.yaml b/Documentation/devicetree/bindings/iio/amplifiers/adi,hmc425a.yaml
index a434cb8ddcc9..3a470459b965 100644
--- a/Documentation/devicetree/bindings/iio/amplifiers/adi,hmc425a.yaml
+++ b/Documentation/devicetree/bindings/iio/amplifiers/adi,hmc425a.yaml
@@ -21,6 +21,8 @@ description: |
HMC540S 1 dB LSB Silicon MMIC 4-Bit Digital Positive Control Attenuator, 0.1 - 8 GHz
https://www.analog.com/media/en/technical-documentation/data-sheets/hmc540s.pdf
+ LTC6373 is a 3-Bit precision instrumentation amplifier with fully differential outputs
+ https://www.analog.com/media/en/technical-documentation/data-sheets/ltc6373.pdf
properties:
compatible:
@@ -28,6 +30,7 @@ properties:
- adi,adrf5740
- adi,hmc425a
- adi,hmc540s
+ - adi,ltc6373
vcc-supply: true
@@ -38,6 +41,7 @@ properties:
ADRF5740 - 4 GPIO connected to D2-D5
HMC540S - 4 GPIO connected to V1-V4
HMC425A - 6 GPIO connected to V1-V6
+ LTC6373 - 3 GPIO connected to A0-A2
minItems: 1
maxItems: 6
@@ -64,6 +68,16 @@ allOf:
ctrl-gpios:
minItems: 4
maxItems: 4
+ - if:
+ properties:
+ compatible:
+ contains:
+ const: adi,ltc6373
+ then:
+ properties:
+ ctrl-gpios:
+ minItems: 3
+ maxItems: 3
required:
- compatible
--
2.42.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v4 3/5] iio: amplifiers: hmc425a: move conversion logic
2024-01-17 12:51 [PATCH v4 0/5] Add support for LTC6373 Dumitru Ceclan
2024-01-17 12:51 ` [PATCH v4 1/5] dt-bindings: iio: hmc425a: add conditional GPIO array size constraints Dumitru Ceclan
2024-01-17 12:51 ` [PATCH v4 2/5] dt-bindings: iio: hmc425a: add entry for LTC6373 Dumitru Ceclan
@ 2024-01-17 12:51 ` Dumitru Ceclan
2024-01-21 17:07 ` Jonathan Cameron
2024-01-17 12:51 ` [PATCH v4 4/5] iio: amplifiers: hmc425a: use pointers in match table Dumitru Ceclan
2024-01-17 12:51 ` [PATCH v4 5/5] iio: amplifiers: hmc425a: add support for LTC6373 Instrumentation Amplifier Dumitru Ceclan
4 siblings, 1 reply; 10+ messages in thread
From: Dumitru Ceclan @ 2024-01-17 12:51 UTC (permalink / raw)
Cc: Lars-Peter Clausen, Jonathan Cameron, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, linux-iio, devicetree,
linux-kernel, Ceclan Dumitru, Dumitru Ceclan
Move gain-dB<->code conversion logic from read_raw and write_raw to
hmc425a_gain_dB_to_code() and hmc425a_code_to_gain_dB().
Signed-off-by: Dumitru Ceclan <mitrutzceclan@gmail.com>
---
drivers/iio/amplifiers/hmc425a.c | 102 ++++++++++++++++++-------------
1 file changed, 59 insertions(+), 43 deletions(-)
diff --git a/drivers/iio/amplifiers/hmc425a.c b/drivers/iio/amplifiers/hmc425a.c
index ed4d72922696..e1162a500daf 100644
--- a/drivers/iio/amplifiers/hmc425a.c
+++ b/drivers/iio/amplifiers/hmc425a.c
@@ -56,35 +56,72 @@ static int hmc425a_write(struct iio_dev *indio_dev, u32 value)
return 0;
}
+static int hmc425a_gain_dB_to_code(struct hmc425a_state *st, int val, int val2, int *code)
+{
+ struct hmc425a_chip_info *inf = st->chip_info;
+ int gain, temp;
+
+ if (val < 0)
+ gain = (val * 1000) - (val2 / 1000);
+ else
+ gain = (val * 1000) + (val2 / 1000);
+
+ if (gain > inf->gain_max || gain < inf->gain_min)
+ return -EINVAL;
+
+ switch (st->type) {
+ case ID_HMC425A:
+ *code = ~((abs(gain) / 500) & 0x3F);
+ return 0;
+ case ID_HMC540S:
+ *code = ~((abs(gain) / 1000) & 0xF);
+ return 0;
+ case ID_ADRF5740:
+ temp = (abs(gain) / 2000) & 0xF;
+ *code = temp & BIT(3) ? temp | BIT(2) : temp;
+ return 0;
+ default:
+ return -EINVAL;
+ }
+}
+
+static int hmc425a_code_to_gain_dB(struct hmc425a_state *st, int *val, int *val2)
+{
+ int code, gain;
+
+ code = st->gain;
+ switch (st->type) {
+ case ID_HMC425A:
+ gain = ~code * -500;
+ break;
+ case ID_HMC540S:
+ gain = ~code * -1000;
+ break;
+ case ID_ADRF5740:
+ code = code & BIT(3) ? code & ~BIT(2) : code;
+ gain = code * -2000;
+ break;
+ }
+
+ *val = gain / 1000;
+ *val2 = (gain % 1000) * 1000;
+
+ return 0;
+}
+
static int hmc425a_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan, int *val,
int *val2, long m)
{
struct hmc425a_state *st = iio_priv(indio_dev);
- int code, gain = 0;
int ret;
mutex_lock(&st->lock);
switch (m) {
case IIO_CHAN_INFO_HARDWAREGAIN:
- code = st->gain;
-
- switch (st->type) {
- case ID_HMC425A:
- gain = ~code * -500;
- break;
- case ID_HMC540S:
- gain = ~code * -1000;
+ ret = hmc425a_code_to_gain_dB(st, val, val2);
+ if (ret)
break;
- case ID_ADRF5740:
- code = code & BIT(3) ? code & ~BIT(2) : code;
- gain = code * -2000;
- break;
- }
-
- *val = gain / 1000;
- *val2 = (gain % 1000) * 1000;
-
ret = IIO_VAL_INT_PLUS_MICRO_DB;
break;
default:
@@ -100,36 +137,15 @@ static int hmc425a_write_raw(struct iio_dev *indio_dev,
int val2, long mask)
{
struct hmc425a_state *st = iio_priv(indio_dev);
- struct hmc425a_chip_info *inf = st->chip_info;
- int code = 0, gain;
- int ret;
-
- if (val < 0)
- gain = (val * 1000) - (val2 / 1000);
- else
- gain = (val * 1000) + (val2 / 1000);
-
- if (gain > inf->gain_max || gain < inf->gain_min)
- return -EINVAL;
-
- switch (st->type) {
- case ID_HMC425A:
- code = ~((abs(gain) / 500) & 0x3F);
- break;
- case ID_HMC540S:
- code = ~((abs(gain) / 1000) & 0xF);
- break;
- case ID_ADRF5740:
- code = (abs(gain) / 2000) & 0xF;
- code = code & BIT(3) ? code | BIT(2) : code;
- break;
- }
+ int code = 0, ret;
mutex_lock(&st->lock);
switch (mask) {
case IIO_CHAN_INFO_HARDWAREGAIN:
+ ret = hmc425a_gain_dB_to_code(st, val, val2, &code);
+ if (ret)
+ break;
st->gain = code;
-
ret = hmc425a_write(indio_dev, st->gain);
break;
default:
--
2.42.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v4 4/5] iio: amplifiers: hmc425a: use pointers in match table
2024-01-17 12:51 [PATCH v4 0/5] Add support for LTC6373 Dumitru Ceclan
` (2 preceding siblings ...)
2024-01-17 12:51 ` [PATCH v4 3/5] iio: amplifiers: hmc425a: move conversion logic Dumitru Ceclan
@ 2024-01-17 12:51 ` Dumitru Ceclan
2024-01-21 16:57 ` Jonathan Cameron
2024-01-17 12:51 ` [PATCH v4 5/5] iio: amplifiers: hmc425a: add support for LTC6373 Instrumentation Amplifier Dumitru Ceclan
4 siblings, 1 reply; 10+ messages in thread
From: Dumitru Ceclan @ 2024-01-17 12:51 UTC (permalink / raw)
Cc: Lars-Peter Clausen, Jonathan Cameron, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, linux-iio, devicetree,
linux-kernel, Ceclan Dumitru, Dumitru Ceclan
Change the match table to use pointers instead of device ids.
Alignment of the hmc425a_state was changed because of the const
specifier for hmc425a_chip_info.
Signed-off-by: Dumitru Ceclan <mitrutzceclan@gmail.com>
---
drivers/iio/amplifiers/hmc425a.c | 39 ++++++++++++++++++--------------
1 file changed, 22 insertions(+), 17 deletions(-)
diff --git a/drivers/iio/amplifiers/hmc425a.c b/drivers/iio/amplifiers/hmc425a.c
index e1162a500daf..b116b54e4206 100644
--- a/drivers/iio/amplifiers/hmc425a.c
+++ b/drivers/iio/amplifiers/hmc425a.c
@@ -37,11 +37,11 @@ struct hmc425a_chip_info {
};
struct hmc425a_state {
- struct mutex lock; /* protect sensor state */
- struct hmc425a_chip_info *chip_info;
- struct gpio_descs *gpios;
- enum hmc425a_type type;
- u32 gain;
+ struct mutex lock; /* protect sensor state */
+ const struct hmc425a_chip_info *chip_info;
+ struct gpio_descs *gpios;
+ enum hmc425a_type type;
+ u32 gain;
};
static int hmc425a_write(struct iio_dev *indio_dev, u32 value)
@@ -58,7 +58,7 @@ static int hmc425a_write(struct iio_dev *indio_dev, u32 value)
static int hmc425a_gain_dB_to_code(struct hmc425a_state *st, int val, int val2, int *code)
{
- struct hmc425a_chip_info *inf = st->chip_info;
+ const struct hmc425a_chip_info *inf = st->chip_info;
int gain, temp;
if (val < 0)
@@ -187,15 +187,6 @@ static const struct iio_chan_spec hmc425a_channels[] = {
HMC425A_CHAN(0),
};
-/* Match table for of_platform binding */
-static const struct of_device_id hmc425a_of_match[] = {
- { .compatible = "adi,hmc425a", .data = (void *)ID_HMC425A },
- { .compatible = "adi,hmc540s", .data = (void *)ID_HMC540S },
- { .compatible = "adi,adrf5740", .data = (void *)ID_ADRF5740 },
- {},
-};
-MODULE_DEVICE_TABLE(of, hmc425a_of_match);
-
static struct hmc425a_chip_info hmc425a_chip_info_tbl[] = {
[ID_HMC425A] = {
.name = "hmc425a",
@@ -226,6 +217,18 @@ static struct hmc425a_chip_info hmc425a_chip_info_tbl[] = {
},
};
+/* Match table for of_platform binding */
+static const struct of_device_id hmc425a_of_match[] = {
+ { .compatible = "adi,hmc425a",
+ .data = &hmc425a_chip_info_tbl[ID_HMC425A]},
+ { .compatible = "adi,hmc540s",
+ .data = &hmc425a_chip_info_tbl[ID_HMC540S]},
+ { .compatible = "adi,adrf5740",
+ .data = &hmc425a_chip_info_tbl[ID_ADRF5740]},
+ {},
+};
+MODULE_DEVICE_TABLE(of, hmc425a_of_match);
+
static int hmc425a_probe(struct platform_device *pdev)
{
struct iio_dev *indio_dev;
@@ -237,14 +240,16 @@ static int hmc425a_probe(struct platform_device *pdev)
return -ENOMEM;
st = iio_priv(indio_dev);
- st->type = (uintptr_t)device_get_match_data(&pdev->dev);
- st->chip_info = &hmc425a_chip_info_tbl[st->type];
+ st->chip_info = device_get_match_data(&pdev->dev);
indio_dev->num_channels = st->chip_info->num_channels;
indio_dev->channels = st->chip_info->channels;
indio_dev->name = st->chip_info->name;
st->gain = st->chip_info->default_gain;
+ /* Compute index of the acquired chip info in the array */
+ st->type = st->chip_info - hmc425a_chip_info_tbl;
+
st->gpios = devm_gpiod_get_array(&pdev->dev, "ctrl", GPIOD_OUT_LOW);
if (IS_ERR(st->gpios))
return dev_err_probe(&pdev->dev, PTR_ERR(st->gpios),
--
2.42.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH v4 5/5] iio: amplifiers: hmc425a: add support for LTC6373 Instrumentation Amplifier
2024-01-17 12:51 [PATCH v4 0/5] Add support for LTC6373 Dumitru Ceclan
` (3 preceding siblings ...)
2024-01-17 12:51 ` [PATCH v4 4/5] iio: amplifiers: hmc425a: use pointers in match table Dumitru Ceclan
@ 2024-01-17 12:51 ` Dumitru Ceclan
2024-01-21 17:14 ` Jonathan Cameron
2024-01-26 9:18 ` Petre Rodan
4 siblings, 2 replies; 10+ messages in thread
From: Dumitru Ceclan @ 2024-01-17 12:51 UTC (permalink / raw)
Cc: Lars-Peter Clausen, Jonathan Cameron, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, linux-iio, devicetree,
linux-kernel, Ceclan Dumitru, Dumitru Ceclan
This adds support for LTC6373 36 V Fully-Differential Programmable-Gain
Instrumentation Amplifier with 25 pA Input Bias Current.
The user can program the gain to one of seven available settings through
a 3-bit parallel interface (A2 to A0).
Signed-off-by: Dumitru Ceclan <mitrutzceclan@gmail.com>
---
drivers/iio/amplifiers/hmc425a.c | 118 +++++++++++++++++++++++++++++--
1 file changed, 114 insertions(+), 4 deletions(-)
diff --git a/drivers/iio/amplifiers/hmc425a.c b/drivers/iio/amplifiers/hmc425a.c
index b116b54e4206..e7f425677fd3 100644
--- a/drivers/iio/amplifiers/hmc425a.c
+++ b/drivers/iio/amplifiers/hmc425a.c
@@ -2,9 +2,10 @@
/*
* HMC425A and similar Gain Amplifiers
*
- * Copyright 2020 Analog Devices Inc.
+ * Copyright 2020, 2023 Analog Devices Inc.
*/
+#include <linux/bits.h>
#include <linux/bitops.h>
#include <linux/device.h>
#include <linux/err.h>
@@ -20,10 +21,24 @@
#include <linux/regulator/consumer.h>
#include <linux/sysfs.h>
+/*
+ * The LTC6373 amplifier supports configuring gain using GPIO's with the following
+ * values (OUTPUT_V / INPUT_V): 0(shutdown), 0.25, 0.5, 1, 2, 4, 8, 16
+ *
+ * Except for the shutdown value, all can be converted to dB using 20 * log10(x)
+ * From here, it is observed that all values are multiples of the '2' gain setting,
+ * with the correspondent of 6.020dB.
+ */
+#define LTC6373_CONVERSION_CONSTANT 6020
+#define LTC6373_MIN_GAIN_CODE 0x6
+#define LTC6373_CONVERSION_MASK GENMASK(2, 0)
+#define LTC6373_SHUTDOWN GENMASK(2, 0)
+
enum hmc425a_type {
ID_HMC425A,
ID_HMC540S,
- ID_ADRF5740
+ ID_ADRF5740,
+ ID_LTC6373,
};
struct hmc425a_chip_info {
@@ -34,6 +49,8 @@ struct hmc425a_chip_info {
int gain_min;
int gain_max;
int default_gain;
+ int powerdown_val;
+ bool has_powerdown;
};
struct hmc425a_state {
@@ -42,6 +59,7 @@ struct hmc425a_state {
struct gpio_descs *gpios;
enum hmc425a_type type;
u32 gain;
+ bool powerdown;
};
static int hmc425a_write(struct iio_dev *indio_dev, u32 value)
@@ -80,6 +98,17 @@ static int hmc425a_gain_dB_to_code(struct hmc425a_state *st, int val, int val2,
temp = (abs(gain) / 2000) & 0xF;
*code = temp & BIT(3) ? temp | BIT(2) : temp;
return 0;
+ case ID_LTC6373:
+ if (st->powerdown)
+ return -EPERM;
+
+ /* add half of the value for rounding */
+ temp = LTC6373_CONVERSION_CONSTANT / 2;
+ if (val < 0)
+ temp *= -1;
+ *code = ~((gain + temp) / LTC6373_CONVERSION_CONSTANT + 3)
+ & LTC6373_CONVERSION_MASK;
+ return 0;
default:
return -EINVAL;
}
@@ -101,6 +130,12 @@ static int hmc425a_code_to_gain_dB(struct hmc425a_state *st, int *val, int *val2
code = code & BIT(3) ? code & ~BIT(2) : code;
gain = code * -2000;
break;
+ case ID_LTC6373:
+ if (st->powerdown)
+ return -EPERM;
+ gain = ((~code & LTC6373_CONVERSION_MASK) - 3) *
+ LTC6373_CONVERSION_CONSTANT;
+ break;
}
*val = gain / 1000;
@@ -174,6 +209,48 @@ static const struct iio_info hmc425a_info = {
.write_raw_get_fmt = &hmc425a_write_raw_get_fmt,
};
+static ssize_t ltc6373_read_powerdown(struct iio_dev *indio_dev,
+ uintptr_t private,
+ const struct iio_chan_spec *chan,
+ char *buf)
+{
+ struct hmc425a_state *st = iio_priv(indio_dev);
+
+ return sysfs_emit(buf, "%d\n", st->powerdown);
+}
+
+static ssize_t ltc6373_write_powerdown(struct iio_dev *indio_dev,
+ uintptr_t private,
+ const struct iio_chan_spec *chan,
+ const char *buf,
+ size_t len)
+{
+ struct hmc425a_state *st = iio_priv(indio_dev);
+ bool powerdown;
+ int code, ret;
+
+ ret = kstrtobool(buf, &powerdown);
+ if (ret)
+ return ret;
+
+ mutex_lock(&st->lock);
+ st->powerdown = powerdown;
+ code = (powerdown) ? LTC6373_SHUTDOWN : st->gain;
+ ret = hmc425a_write(indio_dev, code);
+ mutex_unlock(&st->lock);
+ return len;
+}
+
+static const struct iio_chan_spec_ext_info ltc6373_ext_info[] = {
+ {
+ .name = "powerdown",
+ .read = ltc6373_read_powerdown,
+ .write = ltc6373_write_powerdown,
+ .shared = IIO_SEPARATE,
+ },
+ {},
+};
+
#define HMC425A_CHAN(_channel) \
{ \
.type = IIO_VOLTAGE, \
@@ -183,10 +260,24 @@ static const struct iio_info hmc425a_info = {
.info_mask_separate = BIT(IIO_CHAN_INFO_HARDWAREGAIN), \
}
+#define LTC6373_CHAN(_channel) \
+{ \
+ .type = IIO_VOLTAGE, \
+ .output = 1, \
+ .indexed = 1, \
+ .channel = _channel, \
+ .info_mask_separate = BIT(IIO_CHAN_INFO_HARDWAREGAIN), \
+ .ext_info = ltc6373_ext_info, \
+}
+
static const struct iio_chan_spec hmc425a_channels[] = {
HMC425A_CHAN(0),
};
+static const struct iio_chan_spec ltc6373_channels[] = {
+ LTC6373_CHAN(0),
+};
+
static struct hmc425a_chip_info hmc425a_chip_info_tbl[] = {
[ID_HMC425A] = {
.name = "hmc425a",
@@ -215,6 +306,18 @@ static struct hmc425a_chip_info hmc425a_chip_info_tbl[] = {
.gain_max = 0,
.default_gain = 0xF, /* set default gain -22.0db*/
},
+ [ID_LTC6373] = {
+ .name = "ltc6373",
+ .channels = ltc6373_channels,
+ .num_channels = ARRAY_SIZE(ltc6373_channels),
+ .num_gpios = 3,
+ .gain_min = -12041, /* gain setting x0.25*/
+ .gain_max = 24082, /* gain setting x16 */
+ .default_gain = LTC6373_MIN_GAIN_CODE,
+ .powerdown_val = LTC6373_SHUTDOWN,
+ .has_powerdown = true,
+ },
+
};
/* Match table for of_platform binding */
@@ -225,6 +328,8 @@ static const struct of_device_id hmc425a_of_match[] = {
.data = &hmc425a_chip_info_tbl[ID_HMC540S]},
{ .compatible = "adi,adrf5740",
.data = &hmc425a_chip_info_tbl[ID_ADRF5740]},
+ { .compatible = "adi,ltc6373",
+ .data = &hmc425a_chip_info_tbl[ID_LTC6373]},
{},
};
MODULE_DEVICE_TABLE(of, hmc425a_of_match);
@@ -270,8 +375,13 @@ static int hmc425a_probe(struct platform_device *pdev)
indio_dev->info = &hmc425a_info;
indio_dev->modes = INDIO_DIRECT_MODE;
- /* Set default gain */
- hmc425a_write(indio_dev, st->gain);
+ if (st->chip_info->has_powerdown) {
+ st->powerdown = true;
+ hmc425a_write(indio_dev, st->chip_info->powerdown_val);
+ } else {
+ /* Set default gain */
+ hmc425a_write(indio_dev, st->gain);
+ }
return devm_iio_device_register(&pdev->dev, indio_dev);
}
--
2.42.0
^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH v4 4/5] iio: amplifiers: hmc425a: use pointers in match table
2024-01-17 12:51 ` [PATCH v4 4/5] iio: amplifiers: hmc425a: use pointers in match table Dumitru Ceclan
@ 2024-01-21 16:57 ` Jonathan Cameron
0 siblings, 0 replies; 10+ messages in thread
From: Jonathan Cameron @ 2024-01-21 16:57 UTC (permalink / raw)
To: Dumitru Ceclan
Cc: Lars-Peter Clausen, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, linux-iio, devicetree, linux-kernel,
Ceclan Dumitru
On Wed, 17 Jan 2024 14:51:13 +0200
Dumitru Ceclan <mitrutzceclan@gmail.com> wrote:
> Change the match table to use pointers instead of device ids.
> Alignment of the hmc425a_state was changed because of the const
> specifier for hmc425a_chip_info.
>
> Signed-off-by: Dumitru Ceclan <mitrutzceclan@gmail.com>
Hi Dumitru
The remaining use of type in here and deriving from structure offsets is
not nice. Add a trivial callback for the stuff in write_raw() that needs
to be different and is currently in a switch statement.
Then get rid of the type enum completely if possible.
> ---
> drivers/iio/amplifiers/hmc425a.c | 39 ++++++++++++++++++--------------
> 1 file changed, 22 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/iio/amplifiers/hmc425a.c b/drivers/iio/amplifiers/hmc425a.c
> index e1162a500daf..b116b54e4206 100644
> --- a/drivers/iio/amplifiers/hmc425a.c
> +++ b/drivers/iio/amplifiers/hmc425a.c
> @@ -37,11 +37,11 @@ struct hmc425a_chip_info {
> };
>
> struct hmc425a_state {
> - struct mutex lock; /* protect sensor state */
> - struct hmc425a_chip_info *chip_info;
> - struct gpio_descs *gpios;
> - enum hmc425a_type type;
> - u32 gain;
> + struct mutex lock; /* protect sensor state */
> + const struct hmc425a_chip_info *chip_info;
> + struct gpio_descs *gpios;
> + enum hmc425a_type type;
> + u32 gain;
This illustrates why I'm not keen on manual alignment like this. Generates
churn that makes it hard to spot the actual changes. To avoid this happening
again I'd suggest a single space is fine for all lines and don't align them
at all!
> };
>
> static int hmc425a_write(struct iio_dev *indio_dev, u32 value)
> @@ -58,7 +58,7 @@ static int hmc425a_write(struct iio_dev *indio_dev, u32 value)
>
> static int hmc425a_gain_dB_to_code(struct hmc425a_state *st, int val, int val2, int *code)
> {
> - struct hmc425a_chip_info *inf = st->chip_info;
> + const struct hmc425a_chip_info *inf = st->chip_info;
> int gain, temp;
>
> if (val < 0)
> @@ -187,15 +187,6 @@ static const struct iio_chan_spec hmc425a_channels[] = {
> HMC425A_CHAN(0),
> };
>
> -/* Match table for of_platform binding */
> -static const struct of_device_id hmc425a_of_match[] = {
> - { .compatible = "adi,hmc425a", .data = (void *)ID_HMC425A },
> - { .compatible = "adi,hmc540s", .data = (void *)ID_HMC540S },
> - { .compatible = "adi,adrf5740", .data = (void *)ID_ADRF5740 },
> - {},
> -};
> -MODULE_DEVICE_TABLE(of, hmc425a_of_match);
> -
> static struct hmc425a_chip_info hmc425a_chip_info_tbl[] = {
> [ID_HMC425A] = {
> .name = "hmc425a",
> @@ -226,6 +217,18 @@ static struct hmc425a_chip_info hmc425a_chip_info_tbl[] = {
> },
> };
>
> +/* Match table for of_platform binding */
> +static const struct of_device_id hmc425a_of_match[] = {
> + { .compatible = "adi,hmc425a",
> + .data = &hmc425a_chip_info_tbl[ID_HMC425A]},
> + { .compatible = "adi,hmc540s",
> + .data = &hmc425a_chip_info_tbl[ID_HMC540S]},
> + { .compatible = "adi,adrf5740",
> + .data = &hmc425a_chip_info_tbl[ID_ADRF5740]},
> + {},
Nice to drop that trailing comma whilst here. No need for one on a 'terminator'
of such an array as by definition nothing should ever be added after it.
> +};
> +MODULE_DEVICE_TABLE(of, hmc425a_of_match);
> +
> static int hmc425a_probe(struct platform_device *pdev)
> {
> struct iio_dev *indio_dev;
> @@ -237,14 +240,16 @@ static int hmc425a_probe(struct platform_device *pdev)
> return -ENOMEM;
>
> st = iio_priv(indio_dev);
> - st->type = (uintptr_t)device_get_match_data(&pdev->dev);
>
> - st->chip_info = &hmc425a_chip_info_tbl[st->type];
> + st->chip_info = device_get_match_data(&pdev->dev);
> indio_dev->num_channels = st->chip_info->num_channels;
> indio_dev->channels = st->chip_info->channels;
> indio_dev->name = st->chip_info->name;
> st->gain = st->chip_info->default_gain;
>
> + /* Compute index of the acquired chip info in the array */
> + st->type = st->chip_info - hmc425a_chip_info_tbl;
Definitely not a good idea. If you need a type field, put it in the chip_info_tbl
but you should not need one anyway because type is rarely what matters
but rather data or behavior (via a callback) needed for a given device.
Here it looks like a callback is needed for the few lines in write_raw()
that are fiddly to express as data.
> +
> st->gpios = devm_gpiod_get_array(&pdev->dev, "ctrl", GPIOD_OUT_LOW);
> if (IS_ERR(st->gpios))
> return dev_err_probe(&pdev->dev, PTR_ERR(st->gpios),
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v4 3/5] iio: amplifiers: hmc425a: move conversion logic
2024-01-17 12:51 ` [PATCH v4 3/5] iio: amplifiers: hmc425a: move conversion logic Dumitru Ceclan
@ 2024-01-21 17:07 ` Jonathan Cameron
0 siblings, 0 replies; 10+ messages in thread
From: Jonathan Cameron @ 2024-01-21 17:07 UTC (permalink / raw)
To: Dumitru Ceclan
Cc: Lars-Peter Clausen, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, linux-iio, devicetree, linux-kernel,
Ceclan Dumitru
On Wed, 17 Jan 2024 14:51:12 +0200
Dumitru Ceclan <mitrutzceclan@gmail.com> wrote:
> Move gain-dB<->code conversion logic from read_raw and write_raw to
> hmc425a_gain_dB_to_code() and hmc425a_code_to_gain_dB().
>
> Signed-off-by: Dumitru Ceclan <mitrutzceclan@gmail.com>
Some comments inline
Jonathan
> ---
> drivers/iio/amplifiers/hmc425a.c | 102 ++++++++++++++++++-------------
> 1 file changed, 59 insertions(+), 43 deletions(-)
>
> diff --git a/drivers/iio/amplifiers/hmc425a.c b/drivers/iio/amplifiers/hmc425a.c
> index ed4d72922696..e1162a500daf 100644
> --- a/drivers/iio/amplifiers/hmc425a.c
> +++ b/drivers/iio/amplifiers/hmc425a.c
> @@ -56,35 +56,72 @@ static int hmc425a_write(struct iio_dev *indio_dev, u32 value)
> return 0;
> }
>
> +static int hmc425a_gain_dB_to_code(struct hmc425a_state *st, int val, int val2, int *code)
> +{
> + struct hmc425a_chip_info *inf = st->chip_info;
> + int gain, temp;
> +
> + if (val < 0)
> + gain = (val * 1000) - (val2 / 1000);
> + else
> + gain = (val * 1000) + (val2 / 1000);
> +
> + if (gain > inf->gain_max || gain < inf->gain_min)
> + return -EINVAL;
> +
> + switch (st->type) {
> + case ID_HMC425A:
> + *code = ~((abs(gain) / 500) & 0x3F);
In the next patch I point out that this should be data or callbacks in in
the st->chip_info structure, not encoded in code here based on st->type (which
I want you to get rid of!)
> + return 0;
> + case ID_HMC540S:
> + *code = ~((abs(gain) / 1000) & 0xF);
> + return 0;
> + case ID_ADRF5740:
> + temp = (abs(gain) / 2000) & 0xF;
> + *code = temp & BIT(3) ? temp | BIT(2) : temp;
Given you are moving the code, a comment here might be nice as it's unusual
(bits are 2DB, 4DB, 8DB and another 8DB)
> + return 0;
> + default:
> + return -EINVAL;
> + }
> +}
> +
> +static int hmc425a_code_to_gain_dB(struct hmc425a_state *st, int *val, int *val2)
> +{
> + int code, gain;
> +
> + code = st->gain;
> + switch (st->type) {
> + case ID_HMC425A:
> + gain = ~code * -500;
> + break;
> + case ID_HMC540S:
> + gain = ~code * -1000;
> + break;
> + case ID_ADRF5740:
> + code = code & BIT(3) ? code & ~BIT(2) : code;
> + gain = code * -2000;
> + break;
> + }
> +
> + *val = gain / 1000;
> + *val2 = (gain % 1000) * 1000;
> +
> + return 0;
> +}
> +
> static int hmc425a_read_raw(struct iio_dev *indio_dev,
> struct iio_chan_spec const *chan, int *val,
> int *val2, long m)
> {
> struct hmc425a_state *st = iio_priv(indio_dev);
> - int code, gain = 0;
> int ret;
>
> mutex_lock(&st->lock);
> switch (m) {
> case IIO_CHAN_INFO_HARDWAREGAIN:
> - code = st->gain;
> -
> - switch (st->type) {
> - case ID_HMC425A:
> - gain = ~code * -500;
> - break;
> - case ID_HMC540S:
> - gain = ~code * -1000;
> + ret = hmc425a_code_to_gain_dB(st, val, val2);
> + if (ret)
> break;
> - case ID_ADRF5740:
> - code = code & BIT(3) ? code & ~BIT(2) : code;
> - gain = code * -2000;
> - break;
> - }
> -
> - *val = gain / 1000;
> - *val2 = (gain % 1000) * 1000;
> -
> ret = IIO_VAL_INT_PLUS_MICRO_DB;
> break;
> default:
> @@ -100,36 +137,15 @@ static int hmc425a_write_raw(struct iio_dev *indio_dev,
> int val2, long mask)
> {
> struct hmc425a_state *st = iio_priv(indio_dev);
> - struct hmc425a_chip_info *inf = st->chip_info;
> - int code = 0, gain;
> - int ret;
> -
> - if (val < 0)
> - gain = (val * 1000) - (val2 / 1000);
> - else
> - gain = (val * 1000) + (val2 / 1000);
> -
> - if (gain > inf->gain_max || gain < inf->gain_min)
> - return -EINVAL;
> -
> - switch (st->type) {
> - case ID_HMC425A:
> - code = ~((abs(gain) / 500) & 0x3F);
> - break;
> - case ID_HMC540S:
> - code = ~((abs(gain) / 1000) & 0xF);
> - break;
> - case ID_ADRF5740:
> - code = (abs(gain) / 2000) & 0xF;
> - code = code & BIT(3) ? code | BIT(2) : code;
> - break;
> - }
> + int code = 0, ret;
>
> mutex_lock(&st->lock);
> switch (mask) {
> case IIO_CHAN_INFO_HARDWAREGAIN:
> + ret = hmc425a_gain_dB_to_code(st, val, val2, &code);
> + if (ret)
> + break;
> st->gain = code;
> -
> ret = hmc425a_write(indio_dev, st->gain);
> break;
> default:
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v4 5/5] iio: amplifiers: hmc425a: add support for LTC6373 Instrumentation Amplifier
2024-01-17 12:51 ` [PATCH v4 5/5] iio: amplifiers: hmc425a: add support for LTC6373 Instrumentation Amplifier Dumitru Ceclan
@ 2024-01-21 17:14 ` Jonathan Cameron
2024-01-26 9:18 ` Petre Rodan
1 sibling, 0 replies; 10+ messages in thread
From: Jonathan Cameron @ 2024-01-21 17:14 UTC (permalink / raw)
To: Dumitru Ceclan
Cc: Lars-Peter Clausen, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, linux-iio, devicetree, linux-kernel,
Ceclan Dumitru
On Wed, 17 Jan 2024 14:51:14 +0200
Dumitru Ceclan <mitrutzceclan@gmail.com> wrote:
> This adds support for LTC6373 36 V Fully-Differential Programmable-Gain
> Instrumentation Amplifier with 25 pA Input Bias Current.
> The user can program the gain to one of seven available settings through
> a 3-bit parallel interface (A2 to A0).
>
> Signed-off-by: Dumitru Ceclan <mitrutzceclan@gmail.com>
Hi Dumitru,
Some comments inline. I'd forgotten we have a rich set of DIV_xxx macros
in math.h, DIV_ROUND_CLOSEST is I think the same as what you have
coded up in here.
> ---
> drivers/iio/amplifiers/hmc425a.c | 118 +++++++++++++++++++++++++++++--
> 1 file changed, 114 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/iio/amplifiers/hmc425a.c b/drivers/iio/amplifiers/hmc425a.c
> index b116b54e4206..e7f425677fd3 100644
> --- a/drivers/iio/amplifiers/hmc425a.c
> +++ b/drivers/iio/amplifiers/hmc425a.c
> @@ -2,9 +2,10 @@
> /*
> * HMC425A and similar Gain Amplifiers
> *
> - * Copyright 2020 Analog Devices Inc.
> + * Copyright 2020, 2023 Analog Devices Inc.
> */
>
> +#include <linux/bits.h>
> #include <linux/bitops.h>
> #include <linux/device.h>
> #include <linux/err.h>
> @@ -20,10 +21,24 @@
> #include <linux/regulator/consumer.h>
> #include <linux/sysfs.h>
>
> +/*
> + * The LTC6373 amplifier supports configuring gain using GPIO's with the following
> + * values (OUTPUT_V / INPUT_V): 0(shutdown), 0.25, 0.5, 1, 2, 4, 8, 16
> + *
> + * Except for the shutdown value, all can be converted to dB using 20 * log10(x)
> + * From here, it is observed that all values are multiples of the '2' gain setting,
> + * with the correspondent of 6.020dB.
> + */
> +#define LTC6373_CONVERSION_CONSTANT 6020
> +#define LTC6373_MIN_GAIN_CODE 0x6
> +#define LTC6373_CONVERSION_MASK GENMASK(2, 0)
> +#define LTC6373_SHUTDOWN GENMASK(2, 0)
> +
> enum hmc425a_type {
> ID_HMC425A,
> ID_HMC540S,
> - ID_ADRF5740
> + ID_ADRF5740,
> + ID_LTC6373,
> };
>
> struct hmc425a_chip_info {
> @@ -34,6 +49,8 @@ struct hmc425a_chip_info {
> int gain_min;
> int gain_max;
> int default_gain;
> + int powerdown_val;
> + bool has_powerdown;
> };
>
> struct hmc425a_state {
> @@ -42,6 +59,7 @@ struct hmc425a_state {
> struct gpio_descs *gpios;
> enum hmc425a_type type;
> u32 gain;
> + bool powerdown;
> };
>
> static int hmc425a_write(struct iio_dev *indio_dev, u32 value)
> @@ -80,6 +98,17 @@ static int hmc425a_gain_dB_to_code(struct hmc425a_state *st, int val, int val2,
> temp = (abs(gain) / 2000) & 0xF;
> *code = temp & BIT(3) ? temp | BIT(2) : temp;
> return 0;
> + case ID_LTC6373:
> + if (st->powerdown)
> + return -EPERM;
> +
> + /* add half of the value for rounding */
> + temp = LTC6373_CONVERSION_CONSTANT / 2;
As mentioned in review of earlier patch, I'd like this to be in a callback not
based on st->type (which should be removed from the driver).
> + if (val < 0)
> + temp *= -1;
> + *code = ~((gain + temp) / LTC6373_CONVERSION_CONSTANT + 3)
I'd forgotten in previous reviews that we have DIV_ROUND_CLOSEST() that does
pretty similar maths to your handling here. Better to use that than
spin your own version.
> + & LTC6373_CONVERSION_MASK;
> + return 0;
> default:
> return -EINVAL;
> }
> @@ -101,6 +130,12 @@ static int hmc425a_code_to_gain_dB(struct hmc425a_state *st, int *val, int *val2
> code = code & BIT(3) ? code & ~BIT(2) : code;
> gain = code * -2000;
> break;
> + case ID_LTC6373:
> + if (st->powerdown)
> + return -EPERM;
> + gain = ((~code & LTC6373_CONVERSION_MASK) - 3) *
> + LTC6373_CONVERSION_CONSTANT;
> + break;
> }
>
> *val = gain / 1000;
> @@ -174,6 +209,48 @@ static const struct iio_info hmc425a_info = {
> .write_raw_get_fmt = &hmc425a_write_raw_get_fmt,
> };
>
> +
> +static const struct iio_chan_spec_ext_info ltc6373_ext_info[] = {
> + {
> + .name = "powerdown",
> + .read = ltc6373_read_powerdown,
> + .write = ltc6373_write_powerdown,
> + .shared = IIO_SEPARATE,
> + },
> + {},
No comma preferred after a terminator entry like this as nothing should
ever come after it. Any new additions must be before this last entry.
> +};
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH v4 5/5] iio: amplifiers: hmc425a: add support for LTC6373 Instrumentation Amplifier
2024-01-17 12:51 ` [PATCH v4 5/5] iio: amplifiers: hmc425a: add support for LTC6373 Instrumentation Amplifier Dumitru Ceclan
2024-01-21 17:14 ` Jonathan Cameron
@ 2024-01-26 9:18 ` Petre Rodan
1 sibling, 0 replies; 10+ messages in thread
From: Petre Rodan @ 2024-01-26 9:18 UTC (permalink / raw)
To: Dumitru Ceclan
Cc: Lars-Peter Clausen, Jonathan Cameron, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, linux-iio, devicetree,
linux-kernel, Ceclan Dumitru
[-- Attachment #1: Type: text/plain, Size: 318 bytes --]
hello Dumitru,
I know this is not part of your current patch, but you might also want to have
a look at ltc6373_write_powerdown():
hmc425a.c:239:2: warning: Value stored to 'ret' is never read [deadcode.DeadStores]
239 | ret = hmc425a_write(indio_dev, code);
cheers,
peter
--
petre rodan
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2024-01-26 9:25 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2024-01-17 12:51 [PATCH v4 0/5] Add support for LTC6373 Dumitru Ceclan
2024-01-17 12:51 ` [PATCH v4 1/5] dt-bindings: iio: hmc425a: add conditional GPIO array size constraints Dumitru Ceclan
2024-01-17 12:51 ` [PATCH v4 2/5] dt-bindings: iio: hmc425a: add entry for LTC6373 Dumitru Ceclan
2024-01-17 12:51 ` [PATCH v4 3/5] iio: amplifiers: hmc425a: move conversion logic Dumitru Ceclan
2024-01-21 17:07 ` Jonathan Cameron
2024-01-17 12:51 ` [PATCH v4 4/5] iio: amplifiers: hmc425a: use pointers in match table Dumitru Ceclan
2024-01-21 16:57 ` Jonathan Cameron
2024-01-17 12:51 ` [PATCH v4 5/5] iio: amplifiers: hmc425a: add support for LTC6373 Instrumentation Amplifier Dumitru Ceclan
2024-01-21 17:14 ` Jonathan Cameron
2024-01-26 9:18 ` Petre Rodan
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.