2021-07-24 19:06:33

by Christophe Branchereau

[permalink] [raw]
Subject: [PATCH v3 0/4] iio/adc: ingenic: add support for the JZ4760(B) Socs to the ingenic sadc driver

This is a set of patches to add support to the JZ4760(B) socs found in numerous gaming handhelds and some
mp3 players to the ingenic-sadc driver.

Changelog for this v3:
- Minor formatting change in ingenic-adc.c to remain within 80 lines
- Correctly set the ingenic,use-internal-divider property in the Documentation so it cannot be used on other
socs than the jz4760b, and modify the description as requested.

Thanks to Paul and Jonathan for their help

Christophe Branchereau (5):
iio/adc: ingenic: rename has_aux2 to has_aux_md
dt-bindings: iio/adc: add an INGENIC_ADC_AUX0 entry
iio/adc: ingenic: add JZ4760 support to the sadc driver
iio/adc: ingenic: add JZ4760B support to the sadc driver
dt-bindings: iio/adc: ingenic: add the JZ4760(B) socs to the sadc
Documentation

.../bindings/iio/adc/ingenic,adc.yaml | 19 ++++
drivers/iio/adc/ingenic-adc.c | 101 ++++++++++++++++--
include/dt-bindings/iio/adc/ingenic,adc.h | 1 +
3 files changed, 112 insertions(+), 9 deletions(-)

--
2.30.2


2021-07-24 19:06:37

by Christophe Branchereau

[permalink] [raw]
Subject: [PATCH v3 3/5] iio/adc: ingenic: add JZ4760 support to the sadc driver

The jz4760 sadc is very similar to the jz4770 one, but has a VREF of 2.5V
and 3 aux channels.

modify ingenic_adc_read_chan_info_raw() needs a change to account for it.

Signed-off-by: Christophe Branchereau <[email protected]>
---
drivers/iio/adc/ingenic-adc.c | 82 +++++++++++++++++++++++++++++++++--
1 file changed, 78 insertions(+), 4 deletions(-)

diff --git a/drivers/iio/adc/ingenic-adc.c b/drivers/iio/adc/ingenic-adc.c
index 40f2d8c2cf72..6b9af0530590 100644
--- a/drivers/iio/adc/ingenic-adc.c
+++ b/drivers/iio/adc/ingenic-adc.c
@@ -71,6 +71,7 @@
#define JZ4725B_ADC_BATTERY_HIGH_VREF_BITS 10
#define JZ4740_ADC_BATTERY_HIGH_VREF (7500 * 0.986)
#define JZ4740_ADC_BATTERY_HIGH_VREF_BITS 12
+#define JZ4760_ADC_BATTERY_VREF 2500
#define JZ4770_ADC_BATTERY_VREF 1200
#define JZ4770_ADC_BATTERY_VREF_BITS 12

@@ -295,6 +296,10 @@ static const int jz4740_adc_battery_scale_avail[] = {
JZ_ADC_BATTERY_LOW_VREF, JZ_ADC_BATTERY_LOW_VREF_BITS,
};

+static const int jz4760_adc_battery_scale_avail[] = {
+ JZ4760_ADC_BATTERY_VREF, JZ4770_ADC_BATTERY_VREF_BITS,
+};
+
static const int jz4770_adc_battery_raw_avail[] = {
0, 1, (1 << JZ4770_ADC_BATTERY_VREF_BITS) - 1,
};
@@ -400,6 +405,47 @@ static const struct iio_chan_spec jz4740_channels[] = {
},
};

+static const struct iio_chan_spec jz4760_channels[] = {
+ {
+ .extend_name = "aux",
+ .type = IIO_VOLTAGE,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_SCALE),
+ .indexed = 1,
+ .channel = INGENIC_ADC_AUX0,
+ .scan_index = -1,
+ },
+ {
+ .extend_name = "aux1",
+ .type = IIO_VOLTAGE,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_SCALE),
+ .indexed = 1,
+ .channel = INGENIC_ADC_AUX,
+ .scan_index = -1,
+ },
+ {
+ .extend_name = "aux2",
+ .type = IIO_VOLTAGE,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_SCALE),
+ .indexed = 1,
+ .channel = INGENIC_ADC_AUX2,
+ .scan_index = -1,
+ },
+ {
+ .extend_name = "battery",
+ .type = IIO_VOLTAGE,
+ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_SCALE),
+ .info_mask_separate_available = BIT(IIO_CHAN_INFO_RAW) |
+ BIT(IIO_CHAN_INFO_SCALE),
+ .indexed = 1,
+ .channel = INGENIC_ADC_BATTERY,
+ .scan_index = -1,
+ },
+};
+
static const struct iio_chan_spec jz4770_channels[] = {
{
.type = IIO_VOLTAGE,
@@ -526,6 +572,20 @@ static const struct ingenic_adc_soc_data jz4740_adc_soc_data = {
.init_clk_div = NULL, /* no ADCLK register on JZ4740 */
};

+static const struct ingenic_adc_soc_data jz4760_adc_soc_data = {
+ .battery_high_vref = JZ4760_ADC_BATTERY_VREF,
+ .battery_high_vref_bits = JZ4770_ADC_BATTERY_VREF_BITS,
+ .battery_raw_avail = jz4770_adc_battery_raw_avail,
+ .battery_raw_avail_size = ARRAY_SIZE(jz4770_adc_battery_raw_avail),
+ .battery_scale_avail = jz4760_adc_battery_scale_avail,
+ .battery_scale_avail_size = ARRAY_SIZE(jz4760_adc_battery_scale_avail),
+ .battery_vref_mode = false,
+ .has_aux_md = true,
+ .channels = jz4760_channels,
+ .num_channels = ARRAY_SIZE(jz4760_channels),
+ .init_clk_div = jz4770_adc_init_clk_div,
+};
+
static const struct ingenic_adc_soc_data jz4770_adc_soc_data = {
.battery_high_vref = JZ4770_ADC_BATTERY_VREF,
.battery_high_vref_bits = JZ4770_ADC_BATTERY_VREF_BITS,
@@ -569,7 +629,7 @@ static int ingenic_adc_read_chan_info_raw(struct iio_dev *iio_dev,
struct iio_chan_spec const *chan,
int *val)
{
- int bit, ret, engine = (chan->channel == INGENIC_ADC_BATTERY);
+ int cmd, ret, engine = (chan->channel == INGENIC_ADC_BATTERY);
struct ingenic_adc *adc = iio_priv(iio_dev);

ret = clk_enable(adc->clk);
@@ -579,11 +639,22 @@ static int ingenic_adc_read_chan_info_raw(struct iio_dev *iio_dev,
return ret;
}

- /* We cannot sample AUX/AUX2 in parallel. */
+ /* We cannot sample the aux channels in parallel. */
mutex_lock(&adc->aux_lock);
if (adc->soc_data->has_aux_md && engine == 0) {
- bit = BIT(chan->channel == INGENIC_ADC_AUX2);
- ingenic_adc_set_config(adc, JZ_ADC_REG_CFG_AUX_MD, bit);
+ switch (chan->channel) {
+ case INGENIC_ADC_AUX0:
+ cmd = 0;
+ break;
+ case INGENIC_ADC_AUX:
+ cmd = 1;
+ break;
+ case INGENIC_ADC_AUX2:
+ cmd = 2;
+ break;
+ }
+
+ ingenic_adc_set_config(adc, JZ_ADC_REG_CFG_AUX_MD, cmd);
}

ret = ingenic_adc_capture(adc, engine);
@@ -591,6 +662,7 @@ static int ingenic_adc_read_chan_info_raw(struct iio_dev *iio_dev,
goto out;

switch (chan->channel) {
+ case INGENIC_ADC_AUX0:
case INGENIC_ADC_AUX:
case INGENIC_ADC_AUX2:
*val = readw(adc->base + JZ_ADC_REG_ADSDAT);
@@ -621,6 +693,7 @@ static int ingenic_adc_read_raw(struct iio_dev *iio_dev,
return ingenic_adc_read_chan_info_raw(iio_dev, chan, val);
case IIO_CHAN_INFO_SCALE:
switch (chan->channel) {
+ case INGENIC_ADC_AUX0:
case INGENIC_ADC_AUX:
case INGENIC_ADC_AUX2:
*val = JZ_ADC_AUX_VREF;
@@ -832,6 +905,7 @@ static int ingenic_adc_probe(struct platform_device *pdev)
static const struct of_device_id ingenic_adc_of_match[] = {
{ .compatible = "ingenic,jz4725b-adc", .data = &jz4725b_adc_soc_data, },
{ .compatible = "ingenic,jz4740-adc", .data = &jz4740_adc_soc_data, },
+ { .compatible = "ingenic,jz4760-adc", .data = &jz4760_adc_soc_data, },
{ .compatible = "ingenic,jz4770-adc", .data = &jz4770_adc_soc_data, },
{ },
};
--
2.30.2

2021-07-24 19:07:07

by Christophe Branchereau

[permalink] [raw]
Subject: [PATCH v3 4/5] iio/adc: ingenic: add JZ4760B support to the sadc driver

The JZ4760B variant differs slightly from the JZ4760: it has a bit called VBAT_SEL in the CFG register.

In order to correctly sample the battery voltage on existing handhelds using this SOC, the bit must be cleared.

We leave the possibility to set the bit, by using the "ingenic,use-internal-divider" in the devicetree.

Signed-off-by: Christophe Branchereau <[email protected]>
---
drivers/iio/adc/ingenic-adc.c | 9 +++++++++
1 file changed, 9 insertions(+)

diff --git a/drivers/iio/adc/ingenic-adc.c b/drivers/iio/adc/ingenic-adc.c
index 6b9af0530590..eaa8ab36183c 100644
--- a/drivers/iio/adc/ingenic-adc.c
+++ b/drivers/iio/adc/ingenic-adc.c
@@ -37,6 +37,7 @@
#define JZ_ADC_REG_CFG_SAMPLE_NUM(n) ((n) << 10)
#define JZ_ADC_REG_CFG_PULL_UP(n) ((n) << 16)
#define JZ_ADC_REG_CFG_CMD_SEL BIT(22)
+#define JZ_ADC_REG_CFG_VBAT_SEL BIT(30)
#define JZ_ADC_REG_CFG_TOUCH_OPS_MASK (BIT(31) | GENMASK(23, 10))
#define JZ_ADC_REG_ADCLK_CLKDIV_LSB 0
#define JZ4725B_ADC_REG_ADCLK_CLKDIV10US_LSB 16
@@ -879,6 +880,14 @@ static int ingenic_adc_probe(struct platform_device *pdev)
/* Put hardware in a known passive state. */
writeb(0x00, adc->base + JZ_ADC_REG_ENABLE);
writeb(0xff, adc->base + JZ_ADC_REG_CTRL);
+
+ /* JZ4760B specific */
+ if (device_property_present(dev, "ingenic,use-internal-divider"))
+ ingenic_adc_set_config(adc, JZ_ADC_REG_CFG_VBAT_SEL,
+ JZ_ADC_REG_CFG_VBAT_SEL);
+ else
+ ingenic_adc_set_config(adc, JZ_ADC_REG_CFG_VBAT_SEL, 0);
+
usleep_range(2000, 3000); /* Must wait at least 2ms. */
clk_disable(adc->clk);

--
2.30.2

2021-07-24 19:07:10

by Christophe Branchereau

[permalink] [raw]
Subject: [PATCH v3 1/5] iio/adc: ingenic: rename has_aux2 to has_aux_md

The jz4760(b) socs have 3 aux channels.

The purpose of has_aux2 is to set the MD bits used to select
the AUX channel to be sampled, not to describe the hardware.

Rename it to a more appropriate name.

Signed-off-by: Christophe Branchereau <[email protected]>
---
drivers/iio/adc/ingenic-adc.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/iio/adc/ingenic-adc.c b/drivers/iio/adc/ingenic-adc.c
index 34c03a264f74..40f2d8c2cf72 100644
--- a/drivers/iio/adc/ingenic-adc.c
+++ b/drivers/iio/adc/ingenic-adc.c
@@ -92,7 +92,7 @@ struct ingenic_adc_soc_data {
const int *battery_scale_avail;
size_t battery_scale_avail_size;
unsigned int battery_vref_mode: 1;
- unsigned int has_aux2: 1;
+ unsigned int has_aux_md: 1;
const struct iio_chan_spec *channels;
unsigned int num_channels;
int (*init_clk_div)(struct device *dev, struct ingenic_adc *adc);
@@ -506,7 +506,7 @@ static const struct ingenic_adc_soc_data jz4725b_adc_soc_data = {
.battery_scale_avail = jz4725b_adc_battery_scale_avail,
.battery_scale_avail_size = ARRAY_SIZE(jz4725b_adc_battery_scale_avail),
.battery_vref_mode = true,
- .has_aux2 = false,
+ .has_aux_md = false,
.channels = jz4740_channels,
.num_channels = ARRAY_SIZE(jz4740_channels),
.init_clk_div = jz4725b_adc_init_clk_div,
@@ -520,7 +520,7 @@ static const struct ingenic_adc_soc_data jz4740_adc_soc_data = {
.battery_scale_avail = jz4740_adc_battery_scale_avail,
.battery_scale_avail_size = ARRAY_SIZE(jz4740_adc_battery_scale_avail),
.battery_vref_mode = true,
- .has_aux2 = false,
+ .has_aux_md = false,
.channels = jz4740_channels,
.num_channels = ARRAY_SIZE(jz4740_channels),
.init_clk_div = NULL, /* no ADCLK register on JZ4740 */
@@ -534,7 +534,7 @@ static const struct ingenic_adc_soc_data jz4770_adc_soc_data = {
.battery_scale_avail = jz4770_adc_battery_scale_avail,
.battery_scale_avail_size = ARRAY_SIZE(jz4770_adc_battery_scale_avail),
.battery_vref_mode = false,
- .has_aux2 = true,
+ .has_aux_md = true,
.channels = jz4770_channels,
.num_channels = ARRAY_SIZE(jz4770_channels),
.init_clk_div = jz4770_adc_init_clk_div,
@@ -581,7 +581,7 @@ static int ingenic_adc_read_chan_info_raw(struct iio_dev *iio_dev,

/* We cannot sample AUX/AUX2 in parallel. */
mutex_lock(&adc->aux_lock);
- if (adc->soc_data->has_aux2 && engine == 0) {
+ if (adc->soc_data->has_aux_md && engine == 0) {
bit = BIT(chan->channel == INGENIC_ADC_AUX2);
ingenic_adc_set_config(adc, JZ_ADC_REG_CFG_AUX_MD, bit);
}
--
2.30.2

2021-07-24 19:07:12

by Christophe Branchereau

[permalink] [raw]
Subject: [PATCH v3 5/5] dt-bindings: iio/adc: ingenic: add the JZ4760(B) socs to the sadc Documentation

Add both the jz4760 and jz4760b, plus a property to use the internal
divider on the b variant and document it.

Signed-off-by: Christophe Branchereau <[email protected]>
---
.../bindings/iio/adc/ingenic,adc.yaml | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)

diff --git a/Documentation/devicetree/bindings/iio/adc/ingenic,adc.yaml b/Documentation/devicetree/bindings/iio/adc/ingenic,adc.yaml
index 433a3fb55a2e..3eb7aa8822c3 100644
--- a/Documentation/devicetree/bindings/iio/adc/ingenic,adc.yaml
+++ b/Documentation/devicetree/bindings/iio/adc/ingenic,adc.yaml
@@ -23,6 +23,8 @@ properties:
enum:
- ingenic,jz4725b-adc
- ingenic,jz4740-adc
+ - ingenic,jz4760-adc
+ - ingenic,jz4760b-adc
- ingenic,jz4770-adc

'#io-channel-cells':
@@ -43,6 +45,23 @@ properties:
interrupts:
maxItems: 1

+ ingenic,use-internal-divider:
+ description:
+ If present, battery voltage is read from the VBAT_IR pin, which has an
+ internal 1/4 divider. If absent, it is read through the VBAT_ER pin,
+ which does not have such a divider.
+ type: boolean
+
+if:
+ not:
+ properties:
+ compatible:
+ contains:
+ const: ingenic,jz4760b-adc
+then:
+ properties:
+ ingenic,use-internal-divider: false
+
required:
- compatible
- '#io-channel-cells'
--
2.30.2

2021-07-25 09:16:45

by Paul Cercueil

[permalink] [raw]
Subject: Re: [PATCH v3 1/5] iio/adc: ingenic: rename has_aux2 to has_aux_md

Hi Christophe,

Le sam., juil. 24 2021 at 21:04:45 +0200, Christophe Branchereau
<[email protected]> a ?crit :
> The jz4760(b) socs have 3 aux channels.
>
> The purpose of has_aux2 is to set the MD bits used to select
> the AUX channel to be sampled, not to describe the hardware.
>
> Rename it to a more appropriate name.
>
> Signed-off-by: Christophe Branchereau <[email protected]>

Reviewed-by: Paul Cercueil <[email protected]>

Cheers,
-Paul

> ---
> drivers/iio/adc/ingenic-adc.c | 10 +++++-----
> 1 file changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/iio/adc/ingenic-adc.c
> b/drivers/iio/adc/ingenic-adc.c
> index 34c03a264f74..40f2d8c2cf72 100644
> --- a/drivers/iio/adc/ingenic-adc.c
> +++ b/drivers/iio/adc/ingenic-adc.c
> @@ -92,7 +92,7 @@ struct ingenic_adc_soc_data {
> const int *battery_scale_avail;
> size_t battery_scale_avail_size;
> unsigned int battery_vref_mode: 1;
> - unsigned int has_aux2: 1;
> + unsigned int has_aux_md: 1;
> const struct iio_chan_spec *channels;
> unsigned int num_channels;
> int (*init_clk_div)(struct device *dev, struct ingenic_adc *adc);
> @@ -506,7 +506,7 @@ static const struct ingenic_adc_soc_data
> jz4725b_adc_soc_data = {
> .battery_scale_avail = jz4725b_adc_battery_scale_avail,
> .battery_scale_avail_size =
> ARRAY_SIZE(jz4725b_adc_battery_scale_avail),
> .battery_vref_mode = true,
> - .has_aux2 = false,
> + .has_aux_md = false,
> .channels = jz4740_channels,
> .num_channels = ARRAY_SIZE(jz4740_channels),
> .init_clk_div = jz4725b_adc_init_clk_div,
> @@ -520,7 +520,7 @@ static const struct ingenic_adc_soc_data
> jz4740_adc_soc_data = {
> .battery_scale_avail = jz4740_adc_battery_scale_avail,
> .battery_scale_avail_size =
> ARRAY_SIZE(jz4740_adc_battery_scale_avail),
> .battery_vref_mode = true,
> - .has_aux2 = false,
> + .has_aux_md = false,
> .channels = jz4740_channels,
> .num_channels = ARRAY_SIZE(jz4740_channels),
> .init_clk_div = NULL, /* no ADCLK register on JZ4740 */
> @@ -534,7 +534,7 @@ static const struct ingenic_adc_soc_data
> jz4770_adc_soc_data = {
> .battery_scale_avail = jz4770_adc_battery_scale_avail,
> .battery_scale_avail_size =
> ARRAY_SIZE(jz4770_adc_battery_scale_avail),
> .battery_vref_mode = false,
> - .has_aux2 = true,
> + .has_aux_md = true,
> .channels = jz4770_channels,
> .num_channels = ARRAY_SIZE(jz4770_channels),
> .init_clk_div = jz4770_adc_init_clk_div,
> @@ -581,7 +581,7 @@ static int ingenic_adc_read_chan_info_raw(struct
> iio_dev *iio_dev,
>
> /* We cannot sample AUX/AUX2 in parallel. */
> mutex_lock(&adc->aux_lock);
> - if (adc->soc_data->has_aux2 && engine == 0) {
> + if (adc->soc_data->has_aux_md && engine == 0) {
> bit = BIT(chan->channel == INGENIC_ADC_AUX2);
> ingenic_adc_set_config(adc, JZ_ADC_REG_CFG_AUX_MD, bit);
> }
> --
> 2.30.2
>


2021-07-25 09:17:22

by Paul Cercueil

[permalink] [raw]
Subject: Re: [PATCH v3 3/5] iio/adc: ingenic: add JZ4760 support to the sadc driver



Le sam., juil. 24 2021 at 21:04:47 +0200, Christophe Branchereau
<[email protected]> a ?crit :
> The jz4760 sadc is very similar to the jz4770 one, but has a VREF of
> 2.5V
> and 3 aux channels.
>
> modify ingenic_adc_read_chan_info_raw() needs a change to account for
> it.
>
> Signed-off-by: Christophe Branchereau <[email protected]>

Reviewed-by: Paul Cercueil <[email protected]>

Cheers,
-Paul

> ---
> drivers/iio/adc/ingenic-adc.c | 82
> +++++++++++++++++++++++++++++++++--
> 1 file changed, 78 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/iio/adc/ingenic-adc.c
> b/drivers/iio/adc/ingenic-adc.c
> index 40f2d8c2cf72..6b9af0530590 100644
> --- a/drivers/iio/adc/ingenic-adc.c
> +++ b/drivers/iio/adc/ingenic-adc.c
> @@ -71,6 +71,7 @@
> #define JZ4725B_ADC_BATTERY_HIGH_VREF_BITS 10
> #define JZ4740_ADC_BATTERY_HIGH_VREF (7500 * 0.986)
> #define JZ4740_ADC_BATTERY_HIGH_VREF_BITS 12
> +#define JZ4760_ADC_BATTERY_VREF 2500
> #define JZ4770_ADC_BATTERY_VREF 1200
> #define JZ4770_ADC_BATTERY_VREF_BITS 12
>
> @@ -295,6 +296,10 @@ static const int
> jz4740_adc_battery_scale_avail[] = {
> JZ_ADC_BATTERY_LOW_VREF, JZ_ADC_BATTERY_LOW_VREF_BITS,
> };
>
> +static const int jz4760_adc_battery_scale_avail[] = {
> + JZ4760_ADC_BATTERY_VREF, JZ4770_ADC_BATTERY_VREF_BITS,
> +};
> +
> static const int jz4770_adc_battery_raw_avail[] = {
> 0, 1, (1 << JZ4770_ADC_BATTERY_VREF_BITS) - 1,
> };
> @@ -400,6 +405,47 @@ static const struct iio_chan_spec
> jz4740_channels[] = {
> },
> };
>
> +static const struct iio_chan_spec jz4760_channels[] = {
> + {
> + .extend_name = "aux",
> + .type = IIO_VOLTAGE,
> + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
> + BIT(IIO_CHAN_INFO_SCALE),
> + .indexed = 1,
> + .channel = INGENIC_ADC_AUX0,
> + .scan_index = -1,
> + },
> + {
> + .extend_name = "aux1",
> + .type = IIO_VOLTAGE,
> + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
> + BIT(IIO_CHAN_INFO_SCALE),
> + .indexed = 1,
> + .channel = INGENIC_ADC_AUX,
> + .scan_index = -1,
> + },
> + {
> + .extend_name = "aux2",
> + .type = IIO_VOLTAGE,
> + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
> + BIT(IIO_CHAN_INFO_SCALE),
> + .indexed = 1,
> + .channel = INGENIC_ADC_AUX2,
> + .scan_index = -1,
> + },
> + {
> + .extend_name = "battery",
> + .type = IIO_VOLTAGE,
> + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |
> + BIT(IIO_CHAN_INFO_SCALE),
> + .info_mask_separate_available = BIT(IIO_CHAN_INFO_RAW) |
> + BIT(IIO_CHAN_INFO_SCALE),
> + .indexed = 1,
> + .channel = INGENIC_ADC_BATTERY,
> + .scan_index = -1,
> + },
> +};
> +
> static const struct iio_chan_spec jz4770_channels[] = {
> {
> .type = IIO_VOLTAGE,
> @@ -526,6 +572,20 @@ static const struct ingenic_adc_soc_data
> jz4740_adc_soc_data = {
> .init_clk_div = NULL, /* no ADCLK register on JZ4740 */
> };
>
> +static const struct ingenic_adc_soc_data jz4760_adc_soc_data = {
> + .battery_high_vref = JZ4760_ADC_BATTERY_VREF,
> + .battery_high_vref_bits = JZ4770_ADC_BATTERY_VREF_BITS,
> + .battery_raw_avail = jz4770_adc_battery_raw_avail,
> + .battery_raw_avail_size = ARRAY_SIZE(jz4770_adc_battery_raw_avail),
> + .battery_scale_avail = jz4760_adc_battery_scale_avail,
> + .battery_scale_avail_size =
> ARRAY_SIZE(jz4760_adc_battery_scale_avail),
> + .battery_vref_mode = false,
> + .has_aux_md = true,
> + .channels = jz4760_channels,
> + .num_channels = ARRAY_SIZE(jz4760_channels),
> + .init_clk_div = jz4770_adc_init_clk_div,
> +};
> +
> static const struct ingenic_adc_soc_data jz4770_adc_soc_data = {
> .battery_high_vref = JZ4770_ADC_BATTERY_VREF,
> .battery_high_vref_bits = JZ4770_ADC_BATTERY_VREF_BITS,
> @@ -569,7 +629,7 @@ static int ingenic_adc_read_chan_info_raw(struct
> iio_dev *iio_dev,
> struct iio_chan_spec const *chan,
> int *val)
> {
> - int bit, ret, engine = (chan->channel == INGENIC_ADC_BATTERY);
> + int cmd, ret, engine = (chan->channel == INGENIC_ADC_BATTERY);
> struct ingenic_adc *adc = iio_priv(iio_dev);
>
> ret = clk_enable(adc->clk);
> @@ -579,11 +639,22 @@ static int
> ingenic_adc_read_chan_info_raw(struct iio_dev *iio_dev,
> return ret;
> }
>
> - /* We cannot sample AUX/AUX2 in parallel. */
> + /* We cannot sample the aux channels in parallel. */
> mutex_lock(&adc->aux_lock);
> if (adc->soc_data->has_aux_md && engine == 0) {
> - bit = BIT(chan->channel == INGENIC_ADC_AUX2);
> - ingenic_adc_set_config(adc, JZ_ADC_REG_CFG_AUX_MD, bit);
> + switch (chan->channel) {
> + case INGENIC_ADC_AUX0:
> + cmd = 0;
> + break;
> + case INGENIC_ADC_AUX:
> + cmd = 1;
> + break;
> + case INGENIC_ADC_AUX2:
> + cmd = 2;
> + break;
> + }
> +
> + ingenic_adc_set_config(adc, JZ_ADC_REG_CFG_AUX_MD, cmd);
> }
>
> ret = ingenic_adc_capture(adc, engine);
> @@ -591,6 +662,7 @@ static int ingenic_adc_read_chan_info_raw(struct
> iio_dev *iio_dev,
> goto out;
>
> switch (chan->channel) {
> + case INGENIC_ADC_AUX0:
> case INGENIC_ADC_AUX:
> case INGENIC_ADC_AUX2:
> *val = readw(adc->base + JZ_ADC_REG_ADSDAT);
> @@ -621,6 +693,7 @@ static int ingenic_adc_read_raw(struct iio_dev
> *iio_dev,
> return ingenic_adc_read_chan_info_raw(iio_dev, chan, val);
> case IIO_CHAN_INFO_SCALE:
> switch (chan->channel) {
> + case INGENIC_ADC_AUX0:
> case INGENIC_ADC_AUX:
> case INGENIC_ADC_AUX2:
> *val = JZ_ADC_AUX_VREF;
> @@ -832,6 +905,7 @@ static int ingenic_adc_probe(struct
> platform_device *pdev)
> static const struct of_device_id ingenic_adc_of_match[] = {
> { .compatible = "ingenic,jz4725b-adc", .data =
> &jz4725b_adc_soc_data, },
> { .compatible = "ingenic,jz4740-adc", .data = &jz4740_adc_soc_data,
> },
> + { .compatible = "ingenic,jz4760-adc", .data = &jz4760_adc_soc_data,
> },
> { .compatible = "ingenic,jz4770-adc", .data = &jz4770_adc_soc_data,
> },
> { },
> };
> --
> 2.30.2
>


2021-07-25 09:24:06

by Paul Cercueil

[permalink] [raw]
Subject: Re: [PATCH v3 4/5] iio/adc: ingenic: add JZ4760B support to the sadc driver

Hi Christophe,

Where did the
+ { .compatible = "ingenic,jz4760b-adc", .data = &jz4760_adc_soc_data },

go?

Cheers,
-Paul


Le sam., juil. 24 2021 at 21:04:48 +0200, Christophe Branchereau
<[email protected]> a ?crit :
> The JZ4760B variant differs slightly from the JZ4760: it has a bit
> called VBAT_SEL in the CFG register.
>
> In order to correctly sample the battery voltage on existing
> handhelds using this SOC, the bit must be cleared.
>
> We leave the possibility to set the bit, by using the
> "ingenic,use-internal-divider" in the devicetree.
>
> Signed-off-by: Christophe Branchereau <[email protected]>
> ---
> drivers/iio/adc/ingenic-adc.c | 9 +++++++++
> 1 file changed, 9 insertions(+)
>
> diff --git a/drivers/iio/adc/ingenic-adc.c
> b/drivers/iio/adc/ingenic-adc.c
> index 6b9af0530590..eaa8ab36183c 100644
> --- a/drivers/iio/adc/ingenic-adc.c
> +++ b/drivers/iio/adc/ingenic-adc.c
> @@ -37,6 +37,7 @@
> #define JZ_ADC_REG_CFG_SAMPLE_NUM(n) ((n) << 10)
> #define JZ_ADC_REG_CFG_PULL_UP(n) ((n) << 16)
> #define JZ_ADC_REG_CFG_CMD_SEL BIT(22)
> +#define JZ_ADC_REG_CFG_VBAT_SEL BIT(30)
> #define JZ_ADC_REG_CFG_TOUCH_OPS_MASK (BIT(31) | GENMASK(23, 10))
> #define JZ_ADC_REG_ADCLK_CLKDIV_LSB 0
> #define JZ4725B_ADC_REG_ADCLK_CLKDIV10US_LSB 16
> @@ -879,6 +880,14 @@ static int ingenic_adc_probe(struct
> platform_device *pdev)
> /* Put hardware in a known passive state. */
> writeb(0x00, adc->base + JZ_ADC_REG_ENABLE);
> writeb(0xff, adc->base + JZ_ADC_REG_CTRL);
> +
> + /* JZ4760B specific */
> + if (device_property_present(dev, "ingenic,use-internal-divider"))
> + ingenic_adc_set_config(adc, JZ_ADC_REG_CFG_VBAT_SEL,
> + JZ_ADC_REG_CFG_VBAT_SEL);
> + else
> + ingenic_adc_set_config(adc, JZ_ADC_REG_CFG_VBAT_SEL, 0);
> +
> usleep_range(2000, 3000); /* Must wait at least 2ms. */
> clk_disable(adc->clk);
>
> --
> 2.30.2
>


2021-07-25 09:25:33

by Paul Cercueil

[permalink] [raw]
Subject: Re: [PATCH v3 5/5] dt-bindings: iio/adc: ingenic: add the JZ4760(B) socs to the sadc Documentation

Hi Christophe,

Le sam., juil. 24 2021 at 21:04:49 +0200, Christophe Branchereau
<[email protected]> a ?crit :
> Add both the jz4760 and jz4760b, plus a property to use the internal
> divider on the b variant and document it.
>
> Signed-off-by: Christophe Branchereau <[email protected]>

Looks good.

Reviewed-by: Paul Cercueil <[email protected]>

> ---
> .../bindings/iio/adc/ingenic,adc.yaml | 19
> +++++++++++++++++++
> 1 file changed, 19 insertions(+)
>
> diff --git
> a/Documentation/devicetree/bindings/iio/adc/ingenic,adc.yaml
> b/Documentation/devicetree/bindings/iio/adc/ingenic,adc.yaml
> index 433a3fb55a2e..3eb7aa8822c3 100644
> --- a/Documentation/devicetree/bindings/iio/adc/ingenic,adc.yaml
> +++ b/Documentation/devicetree/bindings/iio/adc/ingenic,adc.yaml
> @@ -23,6 +23,8 @@ properties:
> enum:
> - ingenic,jz4725b-adc
> - ingenic,jz4740-adc
> + - ingenic,jz4760-adc
> + - ingenic,jz4760b-adc
> - ingenic,jz4770-adc
>
> '#io-channel-cells':
> @@ -43,6 +45,23 @@ properties:
> interrupts:
> maxItems: 1
>
> + ingenic,use-internal-divider:
> + description:
> + If present, battery voltage is read from the VBAT_IR pin,
> which has an
> + internal 1/4 divider. If absent, it is read through the
> VBAT_ER pin,
> + which does not have such a divider.
> + type: boolean
> +
> +if:
> + not:
> + properties:
> + compatible:
> + contains:
> + const: ingenic,jz4760b-adc
> +then:
> + properties:
> + ingenic,use-internal-divider: false
> +
> required:
> - compatible
> - '#io-channel-cells'
> --
> 2.30.2
>


2021-07-25 15:21:44

by Jonathan Cameron

[permalink] [raw]
Subject: Re: [PATCH v3 0/4] iio/adc: ingenic: add support for the JZ4760(B) Socs to the ingenic sadc driver

On Sat, 24 Jul 2021 21:04:44 +0200
Christophe Branchereau <[email protected]> wrote:

> This is a set of patches to add support to the JZ4760(B) socs found in numerous gaming handhelds and some
> mp3 players to the ingenic-sadc driver.
>
> Changelog for this v3:
> - Minor formatting change in ingenic-adc.c to remain within 80 lines
> - Correctly set the ingenic,use-internal-divider property in the Documentation so it cannot be used on other
> socs than the jz4760b, and modify the description as requested.
>
> Thanks to Paul and Jonathan for their help

You are welcome.

Other than Paul's question on the missing entry in patch 4, these look good to me.
We should leave a bit of time for others to review but otherwise once that's
resolved I'll pick them up.

Thanks,

Jonathan

>
> Christophe Branchereau (5):
> iio/adc: ingenic: rename has_aux2 to has_aux_md
> dt-bindings: iio/adc: add an INGENIC_ADC_AUX0 entry
> iio/adc: ingenic: add JZ4760 support to the sadc driver
> iio/adc: ingenic: add JZ4760B support to the sadc driver
> dt-bindings: iio/adc: ingenic: add the JZ4760(B) socs to the sadc
> Documentation
>
> .../bindings/iio/adc/ingenic,adc.yaml | 19 ++++
> drivers/iio/adc/ingenic-adc.c | 101 ++++++++++++++++--
> include/dt-bindings/iio/adc/ingenic,adc.h | 1 +
> 3 files changed, 112 insertions(+), 9 deletions(-)
>