Pm8916 mpp analog configuration

hi,

i had configured mpp3 as analog output, mpp4 as analog input in apq8016-sbc-pmic-pins.dtsi

i am not able to set the mpp3 value as high, please suggest?
how to read the status values/measure the analog values from mpp4?

gpiochip2: GPIOs 504-507, parent: platform/200f000.spmi:pm8916@0:mpps@a000, 200f000.spmi:pm8916@0:mpps@a000:
mpp1 : out analog vin-2 0 high
mpp2 : out digital vin-0 0 low
mpp3 : out analog vin-0 0 low
mpp4 : in analog vin-0 0 low


pinctrl-names = “default”;
pinctrl-0 = <&pm8916_mpp_analog_out &pm8916_mpp_analog_in>;

pm8916_mpp_analog_in: pm8916_mpp4 {
pinconf {
pins = “mpp4”;
function = “analog”;
qcom,amux-route = <PMIC_MPP_AMUX_ROUTE_CH5>;
};
};

pm8916_mpp_analog_out: pm8916_mpp_analog {
pinconf {
pins = “mpp3”;
function = “analog”;
qcom,analog-level = <PMIC_MPP_AOUT_LVL_1V25>;
output-high;
};
};

regards,
vinaysimha

What ‘high’ means in analog context?

Could you attach all changes, which node selects this pinconfs?

the changes done in dts are already shown as by default settings in pinctrl-0
&pm8916_mpps {

    pinctrl-names = "default";
    pinctrl-0 = <&pm8916_mpp_analog_out &pm8916_mpp_analog_in>;

    pm8916_mpp_analog_in: pm8916_mpp4 {
            pinconf {
                    pins = "mpp4"; //sink
                    function = "analog";
                    qcom,amux-route = <PMIC_MPP_AMUX_ROUTE_CH5>;
            };
    };

    pm8916_mpp_analog_out: pm8916_mpp_analog {
            pinconf {
                    pins = "mpp3";
                    function = "analog";
                    qcom,analog-level = <PMIC_MPP_AOUT_LVL_1V25>;
                    output-high;
            };
    };

};

from the cat /sys/kernel/debug/gpio
mpp3 : out analog vin-0 0 low

it shows lows, it means the 1.25V is not yet enabled? once it becomes high it should give 1.25V.

if we make mpp as analog input , how to measure how much voltage is coming to mpp analog input in kernel/sysfs?

please suggest

any inputs on the mpp analog output input issue.

The point being made is that “HIGH” and “LOW” are digital concepts, not analog. If you apply a voltage to it using a pull-up (or down), that voltage will have an impact on the analog reading that will vary as you alter the pull-up resistance or the driving current of the analog circuit.

Given that you are asking about setting it high, I’m going to guess that the analog circuit that you want to measure voltage from is a variable resistance to GROUND. Is that correct?

If you want to measure resistance to ground, you need to first determine the range of possible resistance, and you use that range to calculate the amount of resistance with which to pull the circuit up. This is because the analog input measures voltage, and you need to convert the resistance into a voltage that is scaled evenly across the range of acceptable voltage inputs.

So here is the math;
A voltage divider is made up of 2 resistances. We will call them R1 and R2.
R1 will be your pull-up resistor. It connects from your INPUT PIN to high level voltage (1.25).
R2 will be the resistance-to-ground that you are trying to measure. It will connect from your INPUT PIN to GROUND.

The voltage on the INPUT PIN will be 1.25 * (R2 / (R1 + R2))

Now imagine this; say that your R2 is a variable resistor, and its halfway setting is 100k ohms. You’re going to want your voltage for that point to be about 0.625 volts. Right?

0.625 = 1.25 * (100,000 / (x + 100,000))
Solve for x – that will be the size of the pull-up resistor that you want to use for this circuit.
(Hint: x = 100,000)

Now how about if your halfway point is only 1000 ohms? Well same formula, except this time the pull-up resistor (x) is only going to be 1000 ohms.

What happens if we try to measure 1000 ohms resistance with a pull-up resistor of 100,000?
V = 1.25 * (1000 / (100000+1000))
V = 0.012

And if we try to measure 100,000 ohms with a pull-up resistor of 1000?
V = 1.25 * (100000 / (1000+100000))
V = 1.238

So you see what happens when we use a pull-up resistor of the wrong scale? You end up with your readings being bunched up closely to one of the extremes, which means that don’t have enough sensitivity to make a reasonable measurement of them.

So if you want to set an analog pin as a pull-up, then what size of internal pull-up resistor would you use for it? So you see the problem with an analog input pin having any form of pull-up. You would have to add this resistor externally.

Now if you’re coming from the microcontroller world, you will probably know that they very often do allow you to activate an internal pull-up resistor when set for analog input. I generally don’t recommend using them in that way. The only exception, I would say, is if you are using the pull-up resistor for a “holding” situation (what I mean by that, is if you may or may not have something hooked up to the pin, and need to just make sure that you don’t get ghost readings from it), and you KNOW that the resistance you would have to measure is an order of magnitude lower than the internal. For example, Atmel/microchip MCU’s can have internal resistors anywhere from about 20k to 150k ohm depending on the specific chip. If you’re going to be measuring resistances in the 0-1000 ohm range, then you’re ok to activate the internal resistor, since it’s value will have only a minor impact on the reading that you can compensate for. But if you get into a conflicting range, then again, you need to switch to an external resistor. For instance, 1M.

Given that you are asking about setting it high, I’m going to guess that the analog circuit that you want to measure voltage from is a variable resistance to GROUND. Is that correct?
Yes

we want to configure one of the mpp as analog input, to measure the current consumption of the board at runtime.

for testing purpose we want to configure one of the mpp as input and other as output, configure the voltage level dynamically by sysfs and read back the voltage level from another mpp analog i/o from 625mV to 1.25V

is there a way in kernel 4.14.15 to control the analog voltage output and read the input analog voltage at runtime in sysfs?

below is the mpp as analog i/o configurations

arch/arm64/boot/dts/qcom/apq8016-sbc-pmic-pins.dtsi
&pm8916_mpps {

    pinctrl-names = "default";
    pinctrl-0 = <&pm8916_mpp_analog_out &pm8916_mpp_analog_in>;

    pm8916_mpp_analog_in: pm8916_mpp4 {
            pinconf {
                    pins = "mpp4";
                    function = "analog";
                    qcom,amux-route = <PMIC_MPP_AMUX_ROUTE_CH5>;
            };
    };
    pm8916_mpp_analog_out: pm8916_mpp_analog {
            pinconf {
                    pins = "mpp3";
                    function = "analog";
                    qcom,analog-level = <PMIC_MPP_AOUT_LVL_1V25>;
                    bias-pull-up;
            };
    };

arch/arm64/boot/dts/qcom/pm8916.dtsi
pm8916_vadc: vadc@3100 {
compatible = “qcom,spmi-vadc”;

 mpp4_in {
                            reg = <VADC_P_MUX4_1_1>;
                            qcom,decimation = <512>;
                            qcom,ratiometric; //0.625V and 1.25V reference
                            qcom,hw-settle-time = <200>;
                            qcom,avg-samples = <1>;
                            qcom,pre-scaling = <1 1>;
                    };

Once you have the DT tweaks correct then the devices should show up in /sys/bus/iio/devices

BTW there was a similar topic and I think the advice there matches what you have already setup up but you might like to take a look (especially #3 about recompiling the kernel):