Hellow I'm enthusiast newbie in linux kernel modules development. I started writing basic kernel modules that control Pi's gpio. But i came in to sticky situation i need to set pull up/down of pins and i can't find any function for that (I've been searching /include/linux directory whole day). For now I'm controlling gpios with functions from < linux/gpio.h> but there is nothing for setting internal resistors ... Any one knows any functions that i can use is in kernel space. I'm 100% sure there is one since there is /sys/ interface for controlling the gpios and setting up/downs? I've also searched github for source code of the interface that exports gpios in sys but still nothing (For sure that they are exported with gpio_export() but can't find where calls are made).
-
are you sure that kernel module is necessary? IMHO you should use userspace interfaces when it is possible.– edo1Commented Mar 29, 2016 at 19:12
-
1I need interrupts, timers and other none user-space interfaces + I really want to learn how to make kernel modules, char and block devices ... :(– Иво СтратевCommented Mar 29, 2016 at 19:18
-
There are only a few things you can do with the GPIO in the kernel with the declared interfaces. There is lots of userland code to do what you want, e.g. look at my minimal GPIO access. It would need minor changes to the base addressing to reflect the kernel address space.– joanCommented Mar 29, 2016 at 19:20
-
Like I said i want to learn kernel moduling but I need to build some first and gpio controll is first thing I can think of since my limited time I have for my own coding ...– Иво СтратевCommented Mar 29, 2016 at 19:34
-
You need to do exactly the same as is done in userland (apart from changing the addressing to reflect kernel and userland differences). There is NO other way of setting pull-ups and pull-downs.– joanCommented Mar 29, 2016 at 20:21
1 Answer
Since the pull-up/pull-downs and device functions are pin-controller specific, there aren't general interfaces for them. What we do instead is define pin groups in the device tree, which have the device-specific controls attached to them, and you can then set a pin group. In the existing device trees, we only ever attach a default pin group to a device (and, while any device could have pin groups associated with it, we only do it from within the gpio device node at the moment). So, bcm2836-rpi-2-b.dts says:
&gpio {
pinctrl-0 = <&gpioout &alt0 &i2s_alt0 &alt3>;
/* I2S interface */
i2s_alt0: i2s_alt0 {
brcm,pins = <18 19 20 21>;
brcm,function = <BCM2835_FSEL_ALT0>;
};
};
which says "Before probing this device, set up the pin groups gpioout
, alt0
, i2s_alt0
, and alt3
". You can see i2s_alt0
defined in the example there. If i2s_alt0
needed to set a pullup, you'd add something like: brcm,pull = <2>;
(set everything to pull-up) or brcm,pull = <0 0 2 0>
(set everything to not pull, except pin 20 to pull-up) to the i2s_alt0
node.
See Documentation/devicetree/bindings/pinctrl/brcm,bcm2835-gpio.txt
for more documentation on pin control from the DT, and pinctrl-bindings.txt
for more how groups work, and Documentation/pinctrl.txt
for switching pin groups at runtime, not just probe time.