access GPIO from user space - linux-kernel

I am trying to access intel (cavecreek) gpio controller from user space. But I am getting: "NO such device " error when trying to echo to /sys/class/gpio/export :
echo 32 > /sys/class/gpio/export
bash: echo: write error: No such device
The error message seems to suggest that i need to have a device connected to the gpio. But documentation doesn't seem to mention that.
Nothing is being reserved as far as I can tell from dumping out /sys/kernel/debug/gpio.
I have a i2c mux connected to the gpio pins.
Below is more info on my kernel and configuration
the kernel is is 3.14
here's the relevant config setting:
CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
CONFIG_GPIOLIB=y
CONFIG_GPIO_DEVRES=y
CONFIG_GPIO_ACPI=y
CONFIG_DEBUG_GPIO=y
CONFIG_GPIO_SYSFS=y

in my case, the problem was with the kernel source 3.14.
my system uses intel rangely. in the source lpc_ich.c, .gpio_version field is missing for LPC_DH89XXCC.
i added that field, recompiled and kernel was able to enumerate gpiopin, although the display for the default gpio direction is not correct. direction always shows 'in' for all pins initially, but after using echo command to change the pin direction, the display will show up correctly.

Related

How can I dynamically remove or retrigger the probing an EEPROM via sysFS?

I am wondering what the proper way is to remove EEPROMs dynamically. An alternate approach that will also work is telling the device to re-do the probe. I tried just echoing it to delete_device, but that gives an error that it can't find it in the device list. I am running 4.14.149 kernel (built with Yocto Pyro). The EEPROM in question is an Atmel 24CS02 (at24 compatible).
This is kind of an odd use case; this is in a simulator with two i.MX6 based SOMs that is used for Continuous Integration, and there is no physical EEPROM, so the initial probe at boot time will fail. This is why there is no eeprom file in the directory. The EEPROM is simulated by an FPGA (that isn't loaded and configured until after the initial boot). Once that is complete, I need to either re-probe (so that it will see an EEPROM there and populate the sysFS) or delete and re-add the device (which will re-trigger the probe).
Here is the output from when I try to remove it:
root#PLX-23-UUT:~# cd /sys/bus/i2c/devices/
root#PLX-23-UUT:/sys/bus/i2c/devices# ls
2-0041 2-0050 2-0052 2-0056 2-0057 2-006f i2c-1 i2c-2
root#PLX-23-UUT:/sys/bus/i2c/devices# ls 2-0052
modalias name of_node subsystem uevent
root#PLX-23-UUT:/sys/bus/i2c/devices# echo 0x52 > i2c-2/delete_device
[ 72.717009] i2c i2c-2: delete_device: Can't find device in list
-sh: echo: write error: No such file or directory
You can unbind and bind the driver:
# echo 2-0052 > /sys/bus/i2c/drivers/at24/unbind
# echo 2-0052 > /sys/bus/i2c/drivers/at24/bind
at24 2-0052: supply vcc not found, using dummy regulator
at24 2-0052: 32768 byte 24c256 EEPROM, writable, 1 bytes/write
https://github.com/torvalds/linux/blob/master/drivers/i2c/i2c-core-base.c
/*
* And of course let the users delete the devices they instantiated, if
* they got it wrong. This interface can only be used to delete devices
* instantiated by i2c_sysfs_new_device above. This guarantees that we
* don't delete devices to which some kernel code still has references.
*
* Parameter checking may look overzealous, but we really don't want
* the user to delete the wrong device.
*/
In other words, if you didn't instantiate the device, you don't get to remove it.

ACPI sleep state S3(suspend to ram) is supported on ARM64?

I am using ARMv8/ARM64 Architecture and booting Linaro v4.9 lsk . I want to use ACPI sleep state S3 like below:
echo mem > /sys/power/state
I got an error :
Invalid argument
The only strings present in /sys/power/state are "freeze" and "mem"
I am also using ARM trusted Firmware and after so much efforts to get any clue to make it work .I found out that it is supported with psci 1.0 which is already there in my Firmware..
Can anybody let me know what i am missing?
I have tried to change device tree also to take psci-1.0...if there is really a device tree entry needed..please let me know the exact entries for making Suspend to Ram work.
Thanks in Advance

Unable to change gpio value

Currently I'm trying to check the booting time of an Tixi board using systemd on a 2.6.39 linux kernel. To do so I created a service file that calls a bash script which sets and uses a gpio. The problem is that my systems is not allowing me to change the value of the gpio. I can sucessfully export it, change its direction, but NOT the value. I have connected an oscilloscope to check if the value had changed in the hardware but not updated in the file as suggested in some forums, but it was the same: the value just doesn't change!
I should also point out that the same script is working if I use system V, with exactly the same coonfiguration for the kernel, busybox and filesystem.
It is very ironic because I'm already the root of the systems, nevertheless even changing the permissions of the file, would not allow me to change its value. There is also no feedback from the kernel saying that the operation was not possible, but rather it looks as if it was possible but when I check the value, it was the same as before.
I also tried to run that in the Raspbian with a 3.12 (which I changed to systemd) and it was in fact possible to do it, just in the normal way from userspace.
I would appreciate if you have any idea oh what might be the problem since I already run out of ideas.
Thanks
PS: This is the code that should work on the bash line:
echo 0 > /sys/class/gpio/gpio104/value
more /sys/class/gpio/gpio104/value
// I get 1 not 0 as I requested
Nevertheless the same lines of code in the same board work if I use systemV but not if I use systemd
Probably cause by the lack of udev in your new setup which change the permission for those gpio in /sys/class. You might want to just put back udev to see if it fixes your problem.
I don't know your image setting, but each gpio pins needs to be exported prior to usage. Are you doing it or it's done automatically? If you have omap mux kernel switch, you do something like :
echo 0x104 > /sys/kernel/debug/omap_mux/cam_d5 (set mode 4 as stipulate in TI Sitara TRM)
echo 104 > /sys/class/gpio/export (export the pin)
echo out > /sys/class/gpio/gpio104/direction (set the pin as output)
Also do a dmesg | grep gpio and see if there's any initializing problem with the gpio mux.
Actually I've faced an issue similar to your's , ie was not able to change the value of set of gpio pin manually
Finally the result obtained was even though the name of that pin is gpio it can only be used for input only (DM3730 gpiO_114 and gpio_115).
So please refer to the datasheet and confirm it can be used for I/O operations..

GPIO pins will not toggle (high/low) on beagleboard xm

I am trying to use the expansion header to control a couple motors and auxiliary task mechanism. For this I am using the appropriate pins as GPIO and merely attempting to send high or low signals as needed by the robot. (For instance, I might need the robot to move forward and so I'd send high signals on both sets of pins, whereas if I needed the robot to turn I'd send a high signal to one pin and a low to the other.)
However, the problem is that the pins will only stay high! I've followed the conventions for sysfs just via the terminal, and, although I'm able to set the "values", "active_lows", etc. to 0 or 1, I can't actually get the pins to send 0V. After checking the beagle.h file I used for u-boot it looks like the multiplexer mode is configured correctly. This is also reflected when I get the info from sys/class/gpio/gpio%/% and sys/kernel/debug/gpio. Furthermore I don't get any errors or indication from anywhere that there is something wrong...it just doesn't work!
What should I do? For the first time in my life I have seemingly exhausted the internet...
details:
Beagleboard xm rev c1
ubuntu 12.04
kernel 3.6.8-x4
Im pretty new to the beagle board and I have recently been trying to configure the GPIO pins on my classic beagleboard c4, which i believe should be fairly similar.
Half of my GPIO pins seemed to work fine and the other half seemed to remain high or low no matter what i did. Even though they were configured the same way as the working pins in /sys/class/gpio/
have you tried to use other gpio pins?
I ended up following http://labs.isee.biz/index.php/Mux_instructions
to configure the mux to 4 and now i can control the pins that were not working.
I basically used the command:
sudo echo 0x004 > /sys/kernel/debug/omap_mux/(mux 0 name)
where (mux 0 name) was the name of the subsystem for the mux 0 setting for the gpio pin you wish to configure
ie. for gpio 183 on beagleboard c4
sudo echo 0x004 > /sys/kernel/debug/omap_mux/i2c2_sda
Though I had to change permissions to modify these files
As I said I am pretty new to the beagleboard and ubuntu but this worked for me so I thought I would share it with you, I hope it is of some help.
Regards;
Paul;
It seems that the beagleboard expansion pins are numbered in alternating fashion, as clearly and professionally depicted here.
Thanks to everyone for your help. I now know way more than I should about GPIO on OMAP systems (and so do you). Good luck on finals/life!**
tl;dr I'm an idiot!

Handling Hardware interrupts in Linux

I am working on a embedded linux platform running Linux 2.6 . I would love to know how to do the following.
1) I have a hardware interrupt source irq7 which shows up in /proc/interrupts
cat /proc/interrupts | grep IRQ7
M547X_8X 71: 1916076 PCI IRQ7
2) For PCI IRQ7, each time i press a button, 3rd value value changes
M547X_8X 71: 2177862 PCI IRQ7
Doesn't this mean my switch press is recognized?
Now i want to trigger a user program from sleep when i press this button. How do i write
this user space program using interrupts or signal?
Should i write a driver program for this?
Can you suggest resources that i should look into?
You should take a look on gpio key on linux. After exporting the interrupt to /dev/input/eventXXX, you can use evtest tool for check from user space.

Resources