Source code of keyboard driver of linux - linux

I have been working on making my own keyboard driver for linux. So I came accross these two links: usbkbd.c and atkbd.c.
Now I am
confused which of these is the actual code driving my keyboard at the present. As I see it atkbd.c is quite gory and there is a conversion
of scancodes to keycodes. So it should be the code, though I am not sure.
If atkbd.c is the code, then what is the other code for?

This is easy to check. Let's take usbkbd.c.
The corresponding Kconfig (http://lxr.free-electrons.com/source/drivers/hid/usbhid/Kconfig#L50) says:
Say Y here only if you are absolutely sure that you don't want to use
the generic HID driver for your USB keyboard and prefer to use the
keyboard in its limited Boot Protocol mode instead.
This is almost certainly not what you want. This is mostly useful for
embedded applications or simple keyboards.
So it looks unlikely to be the keyboard driver we are looking for. Also check current kernel config for USB_KBD. The config can be found under /boot directory or by running zcat /proc/config.gz. If USB_KBD is not there, you're not using it. If usbkbd.c is built as module, then will be worth checking if it is actually loaded. Makefile (http://lxr.free-electrons.com/source/drivers/hid/usbhid/Makefile#L10) gives the target as usbkbd. We can check if it is loaded by grepping for it in output of lsmod.
In contrast, Kconfig (http://lxr.free-electrons.com/source/drivers/input/keyboard/Kconfig#L69) for atkbd.c seem much more likely:
Say Y here if you want to use a standard AT or PS/2 keyboard. Usually
you'll need this, unless you have a different type keyboard (USB, ADB
or other). This also works for AT and PS/2 keyboards connected over a
PS/2 to serial converter. If unsure, say Y.
Also check kernel config for KEYBOARD_ATKBD. If it is Y, you know it is being used. If it's M, check output of lsmod for atkbd.

Related

How to read the i2c adapter class (e.g. I2C_CLASS_DDC) from userspace (linux i2c-dev)?

Outside of Laptops, changing e.g. brightness of monitors requires DDC/CI. This is best done in userspace, I believe. Loading i2c-dev (kernel module) gives access to i2c-buses under /dev/i2c-<number>. Unfortunately not just monitors supporting DDC/CI have i2c-buses and it is far from ideal to read/write on unrelated buses, while trying to find which connects to what.
It seems that i2c bus adapter drivers already categorize their buses: e.g. I2C_CLASS_DDC for exactly what I’m looking for.
Is there any way to see the adapter class of a i2c-dev device?
(Or equally good: any way to match the device I want to talk to for DDC/CI from X11 workspaces or similar?)
You can try to look at ddccontrol:
ddccontrol -p
This utility scan I2Cs and somehow detects which are connected to monitors.
You can examine it's source code and find solution.
P.S.
This may be not an answer, but, sorry, I have not enough "reputation" to write a comment.

Manipulation of the backlight in a embedded linux device is unstable

I want to control the backlight value of a LCD monitor in a embedded linux device. Doing researches throughout the internet I found a couple of references saying that the file called backlight inside the backlight's driver folder in sys/classes holds the key: it's just a matter of changing the value inside (such as using the echo command in Terminal) that one would get this results. References saying that includes this link, this and this one. In my specific case, the file is located inside /sys/devices/platform/pwm-backlight/backlight/pwm-backlight and there all the relevant, mentioned files are located: actual_brightness, brightness, max_brightness.
Using the echo command, I did managed to control de backlight, but the problem is that this command is unstable. Sometimes I change the value inside the file and the backlight reacts accordingly; other times nothing happens. I couldn't find any particularity that would justify why sometimes it works and others don't, and that's why I'm here. What could be happening that makes this works sometimes and others not? Is there something lacking in programming or would it be a driver or even hardware problem? And what should I do to correct this instability?
It's worth mentioning that I did compile the Linux kernel in accordance to what seems needed (see this link). Given the instructions in this page, the driver being used is called "Generic PWM based Backlight Driver". I'm using a Texas Instruments OMAP L138 processor.
By the way, it's worth mentioning that a "counter" solution that doesn't involve changing that file is accepted (such as for example what is shown in this link).

Command-line configurating a TTY device

My task at the moment is to port a driver for some 16550-compatible chip from QNX to Linux. The chip provides several UARTs, each one seen as a standard 16550 serial port, albeit with some extensions.
Now, in QNX, the whole device driver is packed into a standalone executable, that acts both as a driver and as an initial configurator for the provided UARTs (baud rates, loopback modes etc.) That is just natural in QNX because there device drivers run in user space and are little more than standard executables.
On Linux, OTOH, the driver is now implemented as a kernel module, loadable at will. More, that module is provided by the producer, so I would not want to modify or patch it too much.
For me, the remaining task is to provide some mechanism for setting up those UARTs' parameters. They are seen as /dev/ttyPREFIXX devices. I intend to do that through a standard C-programmed executable calling standard termios (ie tcsetattr() or ioctls) on the serial ports of interest.
Which leads me to the question: is my approach right? And, if yes, then how to achieve a persistent configuration? As I perceive the fact (from this example: http://www.easysw.com/~mike/serial/serial.html), the termios functions act on OPEN devices. In short: they open a device, they set up the parameters, they read or write, then close the port. After closing the port, is the configuration (baud rate etc.) lost? I hope it is not, because it is stored, already, into the hardware.
Can somebodey confirm to me that the configuration is persistent? And, if not, how to achieve that persistence, for the future applications that would open again that port and will expect it with some pre-established parameters? If not, should I modify the module kernel to accept some parameters and, then, do the configuration at the load time?
The approach that I intend for now is to write that C executable that opens the ports, sets up their configuration, then close the ports. I hope the latter applications will see the ports with the desired configuration.
Thank you.
You might want to have a look at stty and setserial. The venerable Serial-HOWTO (wow, when was the last time I actually recommended a HOWTO to anyone?) is probably also a good starting point.
Well, I found the answer here: http://www.gnu.org/software/libc/manual/html_node/Mode-Functions.html#Mode-Functions
Quote: "Although tcgetattr and tcsetattr specify the terminal device with a file descriptor, the attributes are those of the terminal device itself and not of the file descriptor. This means that the effects of changing terminal attributes are persistent; if another process opens the terminal file later on, it will see the changed attributes even though it doesn't have anything to do with the open file descriptor you originally specified in changing the attributes."
This clears the issue.

How can I get edge events via GPIO on Linux without a busy-loop?

I'm working an a system with embedded Linux (Kernel 2.6.31).
It is a AT91SAM9G20 chip inside, and some of the Pins are forwarded to the outside.
Now I want to use them as GPIO Inputs.
I read the gpio.txt documentation about using the GPIOs via filesystem, and that works very well 'til here. I connected some switches to the gpio-pins and I can see the result in /sys/class/gpio/gpioX/value. But now I'd like to react on a change without busy-waiting in a loop. (i.e echo "Switch1 was pressed").
I guess I need interrupts here, but I couldn't find out how to use them without writing my own kernel driver. I'm relatively new to Linux and C (I normally program in Java), so I'd like to handle the Interrupts via sysfs too. But my problem is, that there is no "edge"-file in my GPIO directory (I guess because this is only since Kernel version 2.6.33+). Is that right? Instead of "edge" I've got a uevent file in there, which is not described in gpio.txt.
In the gpio.txt documentation there was a Standard Kernel Driver mentioned: "gpio_keys". Is it possible to use this for my problem?
I guess it would be better to work with this driver than allowing a userspace program to manipulate kernel tasks.
I found a lot of codesnippets for writing my own driver, but I wasn't even able to find out which of the 600 gpio.h files to include, and how to refer to the library (cross compiler couldn't find the gpio.h file).
Sorry for newbie questions, I hope you could give me some advices.
Thanks in advance
See this for an example on how to do that. Basically, the thing you're missing is the usage of the select or poll system calls.

Hardware recognition in user space Linux

I want to be able to inspect my Linux machine hardware in C.
How do I get the information that appear in dmesg in C ?
For example, for keyboard the message is input: AT Translated Set 2 keyboard as /devices/platform/i8042/serio0/input/input0
I want to get in my program the label, AT Translated Set 2, and the path, /devices/platform/i8042/serio0/input/input0.
Any idea how to do so ?
amit
You can also look at the contents of files in /proc.
/proc/version, /proc/ioports, /proc/iomem, /proc/meminfo, and others have a lot of information in them.
The files under /proc/bus have additional information about the system's hardware devices.
I'd also recommend looking at the source code for usbutils and pciutils for example code to get the output from the lsusb and lspci commands respectively.
It uses the klogctl call.
Best thing is to read the source code yourself, it can be downloaded here: util-linux
You would want to use libhal, and connect to the hal daemon. If HAL isn't there, look for a mounted sysfs partition. Check out /sys/devices, or work backwards through /sys/bus.
If neither HAL nor sysfs is available, reconsider your approach or restrict your scope.

Resources