Re: Reading ADC that comes from a multiplexer

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On 2021-09-22 04:18, Fabio Estevam wrote:
> Hi Peter,
> 
> I have a SN74LV4051 multiplexer that is controlled by 3 GPIOs and I
> described like this in DT:
> 
> adcmux: mux-controller {
>        compatible = "gpio-mux";
>        #mux-control-cells = <0>;
>        mux-gpios = <&gpio3 31 GPIO_ACTIVE_HIGH>,
>                            <&gpio3 30 GPIO_ACTIVE_HIGH>,
>                           <&gpio3 26 GPIO_ACTIVE_HIGH>;
> };
> 
> adc-mux {
>        compatible = "io-channel-mux";
>        io-channels = <&adc 4>;
>        io-channel-names = "parent";
>        mux-controls = <&adcmux>;
>        channels = "chan0", "chan1", "chan2", "chan3",
>                          "chan4", "chan5", "chan6", "chan7";
> };
> 
> /sys/class/mux/muxchip0/ is created:
> 
> # ls /sys/class/mux/muxchip0/
> device  of_node  power  subsystem  uevent
> 
> Sorry for the trivial question, but I haven't found any examples.
> 
> What is the userspace command if I want to expose "chan3" to be read
> by the ADC 4 channel?

Basically, the whole point is that you simply don't. The iio-mux exposes
the channels as 8 new ADCs, and whenever you read a value from one of
them, the iio-mux operates the gpios for you, giving you the impression
that you have 8 independet ADCs. They are of course not independent, but...

Anyway, I have almost the exact same setup in
arch/arm/boot/dts/at91-tse850-3.dts

	mux: mux-controller {
		compatible = "gpio-mux";
		#mux-control-cells = <0>;

		mux-gpios = <&pioA 0 GPIO_ACTIVE_HIGH>,
			    <&pioA 1 GPIO_ACTIVE_HIGH>,
			    <&pioA 2 GPIO_ACTIVE_HIGH>;
		idle-state = <0>;
	};

	envelope-detector-mux {
		compatible = "io-channel-mux";
		io-channels = <&env_det 0>;
		io-channel-names = "parent";

		mux-controls = <&mux>;

		channels = "", "",
			 "sync-1",
			 "in",
			 "out",
			 "sync-2",
			 "sys-reg",
			 "ana-reg";
	};

(but with the added complication that my ADC is not an ordinary ADC, but
instead a DAC and a comparator, such that the envelope of an AC signal can
be detected by a series of measurements, and I only use 6 channels)

That's exposed to user-space as:

$ ls "/sys/bus/iio/devices/iio:device3"
in_altvoltage2_compare_interval  in_altvoltage5_scale
in_altvoltage2_invert            in_altvoltage6_compare_interval
in_altvoltage2_raw               in_altvoltage6_invert
in_altvoltage2_scale             in_altvoltage6_raw
in_altvoltage3_compare_interval  in_altvoltage6_scale
in_altvoltage3_invert            in_altvoltage7_compare_interval
in_altvoltage3_raw               in_altvoltage7_invert
in_altvoltage3_scale             in_altvoltage7_raw
in_altvoltage4_compare_interval  in_altvoltage7_scale
in_altvoltage4_invert            name
in_altvoltage4_raw               of_node
in_altvoltage4_scale             power
in_altvoltage5_compare_interval  subsystem
in_altvoltage5_invert            uevent
in_altvoltage5_raw
$ cat "/sys/bus/iio/devices/iio:device3/name"
envelope-detector-mux



But the above gets tedious fast, and iio:device3 can of course be something
else etc etc, which is why libiio is the recommended interface.

	ctx = iio_create_local_context();
	dev = iio_context_find_device(ctx, "envelope-detector-mux");
	chn = iio_device_find_channel(dev, "altvoltage2", 0);
	iio_channel_attr_read_longlong(chn, "raw", &value);

Hope that helps!

Cheers,
Peter



[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Input]     [Linux Kernel]     [Linux SCSI]     [X.org]

  Powered by Linux