Restricting GPIOS to output-only or input-only through sysfs - linux

I am using Ubuntu 11.10. I have written a driver for a GPIO chip which did not have its own driver in the kernel.
I want to place a restriction on users from setting output-only pins to inputs, and vice-versa when using /sys/class/gpio. This is because many of the GPIO's on my board are input only or output only.
I could scan for restricted GPIO numbers from within the functions gpio_direction_in(), gpio_direction_out() and gpio_request() but I think that's a bit of a hack-around.
Is there any function especially for this purpose? I looked through the documentation for GPIOs but I couldn't see anything.
Andrew

Related

Preferred Linux driver architecture for a multi-function PMU device

I have a bespoke/complex Power Management Unit which exposes its functionality as an I2C slave with 16-bit registers and an interrupt (out) signal.
This PMU also has GPIO functionality.
(The interrupt tells the Linux kernel (I2C master) to read registers because a GPIO input has changed state).
Currently, I've structured the (working) driver(s) as:
./include/linux/mfd/mypmu.h
./drivers/gpio/gpio-mypmu.c
./drivers/mfd/mypmu-core.c
./drivers/mfd/mypmu-regmap.c
./drivers/mfd/mypmu-i2c.c
I have three MODULE_DESCRIPTION() macro invocations:
./drivers/gpio/gpio-mypmu.c:MODULE_DESCRIPTION("GPIO interface for MYPMU");
./drivers/mfd/mypmu-core.c:MODULE_DESCRIPTION("MYMU device");
./drivers/mfd/mypmu-i2c.c:MODULE_DESCRIPTION("MYPMU_I2C");
The reason that it's split into three separate modules is that I use different ways of registering each module, according to the kernel subsystem of which they are a part.
./drivers/gpio/gpio-mypmu.c:platform_driver_register(&mypmu_gpio_driver);
./drivers/mfd/mypmu-core.c:platform_set_drvdata(*pdev, mypmu);
./drivers/mfd/mypmu-i2c.c:i2c_add_driver(&mypmu_i2c_driver);
(This is largely cargo-cult programming, caused by aping other (single-function) drivers' code.)
Is using three modules in one device driver normal? Or is there a way to register one driver in multiple Linux subsystems, such as GPIO and I2C?
Can a driver appear in /sys/class/gpio without a module living in the drivers/gpio tree?
Is there a better way of structuring an MFD driver?

Gpio Linux conventions and names

How can we find the naming of available gpios in an arbitrary board that runs Linux and then to use the Linux commands echo "gpionumber" >/sys/class/gpio so then we can control this gpio?
Gpio and gpiocontrollers are numbered. Gpiocontrollers may have labels, but they may not be unique.
The linux kernel documentation on gpio sysfs driver can be found here and is a good read.
The linux kernel uses device tree file to know which gpiocontrollers are available to him. A gpiocontroller may have multiple gpios. Each board has it's own unique device tree compiled with the kernel or loaded at boot time.
Gpiocontrollers are identified by the register and register length they refer too, see here. You can specify the label of the gpiocontroller as described in device tree file format and you can query the gpiocontroller label using /sys/class/gpio/gpiochipN/label, they may be not unique and they don't let you identify the gpio. Also, they may change between device tree file versions.
There is no "naming", just numbering. You can query all gpios available on a particular board by just inspecting/adding the /sys/class/gpio/gpiochip*/ngpio Usually a board manufacturer/provider/seller/etc provides documentation with the kernel it ships with the board with explanation, which gpio has which number/address, like for Colibri VF61. For some popular boards it is just a matter of googling to find nice looking images with gpio numbers, like for RaspberryPi3 or

Linux: access i2c device within board_init function

(iMX6 SOC running Linux 3.0)
I need to run a few I2C transactions in my board_init function. I tried calling i2c_get_adapter, then i2c_transfer, those being available in kernel mode, but i2c_get_adapter returns NULL. It's already called imx6q_add_imx_i2c, which is a wrapper around platform_device_register_full, but that isn't enough.
I can manipulate GPIO in board_init by calling gpio_request to obtain access, and gpio_free at the end. Is there something analogous to those functions for i2c?
--- added details ---
I've got a LAN9500A USB 100Base-T Ethernet MAC connected to a LAN9303 3-port switch with a virtual PHY. The MAC has a GPIO reset line that has to be turned off before it will spring to life and enumerate on the USB. That's done in board_init because it's completely nonstandard, so we don't want to patch the stock driver to manipulate some GPIO that's not part of the device.
The problem I'm having is that even though the MAC is permanently attached to the VPHY, it's not noticing it's connected, and an "ip link show eth1" command shows NO-CARRIER. I found I can kickstart it by unmasking the VPHY's Device Ready interrupt via I2C, but I also have to mask it immediately, or I get infinite interrupts. That's not the right solution, but Microchip has been no help in showing me a better way. But we don't want to patch the MAC driver with code to fiddle with the PHY.
There is no PHY driver for this part, and the MII interface to the VPHY doesn't include any interrupt-related registers, so it must be done through I2C. Writing a PHY driver just to flip a bit on and off once seems a lot of trouble, especially for a newbie like me who's never written a driver before.
I can do it in Python in a startup script, but that, too, seems like a heavyweight solution to a lightweight problem.
That's a wrong approach. Board file supposed to register device drivers and pass important information to them, rather than act as a device driver itself. I'm not sure if what you're trying to do is even possible.
If you really need to extract something from your I2C device on a very early stage - do that in the bootloader and pass the data to kernel via cmdline (U-boot, by the way, has I2C support for a quite some time). Then later, kernel might do appropriate actions depending on what you have passed to it.

I want to utilize PCA9685 chip to drive servos on beaglebone black, I see there is a linux driver, but how to utilize in C/C++. Any examples?

So I have a Beaglebone black, and a servo/led controller http://www.adafruit.com/product/815. I'd like to control it from a C/C++ program running on the included Debian Linux.
I see there is a driver included in the kernel "pwm_pca9685", and it did create some items in the /sys directory, but nothing that seems to make any sense.
So I know that at least I need to tell the module what i2c address the chip has, so how would I do that, and then how to send various pwm commands to chip?
So I ended up forgoing the use of the driver, as I was unable to find any information on it. Instead I used various ioctl calls, such as is used in this code from Adafruit: https://github.com/adafruit/Adafruit-PWM-Servo-Driver-Library/blob/master/Adafruit_PWMServoDriver.cpp

Transfer data from linux to fpga and inversely?

I have booted a ubuntu on a ZedBoard. I want to transfer data between fpga and linux. For example, I want to write or read a register from linux. What is best way for doing it? I have not any idea.
Thanx.
First of all, you need to specifically say what you want to do, for example. if you want to access the IO signals on the FPGA, you need to first add the GPIO module to your system, synthesize and implement it.
Then you use the Linux GPIO Driver to access the port as it is explained in this page:
Linux GPIO Driver
The GPIO driver fits in the Linux GPIO framework which is not a char
mode driver. Yet it does provide access to the GPIO by user space
through the sysfs filesystem. This allows each GPIO signal to be read
and written in similar manner to a char mode device. The interface is
somewhat documented in the kernel tree at Documentation/gpio.txt. The
following text is aimed to augment, not replace the existing
documentation.
For other, more complex interfaces you need to create your own driver or use one of the drivers that are available and modify it to fit your needs.

Resources