Audio driver base address, DMA and IRQ - linux

In the old days you would look at finding the base addr, DMA and IRQ to communicate with a device. I'm kinda looking for the equiviant.
I'm looking to communicate directly with an audio device, not through a driver, in Linux. Time isn't an issue, but I am struggling to find the information that I need and I know there is a possibility of needing a lot of code, that's fine.
I was wondering if anyone could point me in the right direction to achieving this.
Thankyou very much.

As far as I was aware you couldn't use IRQs or DMA if you're in a user-mode process from linux and this guide (heading 3) seems to confirm that, however after checking I managed to find this Linux driver (udmabuf) that lets you access DMA buffers through the user space; maybe this is what you are looking for?
Otherwise I would mabye try and write a similar, but more customized version of (udmabuf), specific to your purpose.
I'm not sure entirely what you are planning on using it for, but the first thing I would look for is building a driver for what you wanted to do (here's how to get started for ALSA just as an example). At least to communicate at this level, unless you wanted to do some of your own OS development? (I think this would be the way in the end if you really couldn't use drivers for whatever purpose)

I feel bad by answering this myself, WoodyDev, thankyou for pointing me in the right direction.
You are right, a driver is the best way to go.
The best solution is to read the PCI Address Space, the first 64 bytes contain all the data needed.
https://www.safaribooksonline.com/library/view/linux-device-drivers/0596000081/ch15.html

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.

Using libMPSSE with FT4232H in Linux

I don't have much experience with the FT4232H.
It is quad a port device.
I want to configure some of the ports as SPI, other as UART and GPIO
I have started experimenting with the SPI .
In the official documentation it says that if ftd2xx and libMPSSE are used
one have to remove the standard kernel modules ftdi_sio and usbserial so I did it.
My question:
In Linux can I have all 4 port configured arbitrary as SPI/UART/I2C/GPIO
as each port uses possibly different driver in the PC?
As far as I know the driver is loaded based on the PID/VID.
It is unique for the FT4232H which has 4 ports, so how this can be done?
Any thought about this is welcome.
I also want to share my current (one day) experience with the libMPSSE.
Unfortunately kind of negative.
I have downloaded the source code for the latest libMPSSE-rev0.6 from the official FTDI web site.
I was surprised to see that no provisioning for compilation under Linux.
There is no Makefile for the libMPSSE. I have made a simple one which is not a big deal but then I found out it does not compile out of the box. I got "undefined type byte" at one location.
After building the library I have done a simple test application which behaved strange.
I was sending 8 bytes on the SPI but with the oscilloscope I was observing 7 8bit clock packets then 100us pause and finally the last 8 bit packet. The MOSI also was incorrect in the last packet.(I was sending all 0 but got two bits high at the end)
Luckily I found https://www.mathworks.com/matlabcentral/answers/518039-ftdi-libmpsse-0-6-spi_readwrite-weird-behaviour-loadlibrary-calllib .
Fixing that made my transfer looks OK.
It looks to me FTDI have not done even a basic check of libMPSSE
I can not understand how FTDI so popular chips can have that low quality software library.
Probably ftd2xx is OK and issues are only in the higher layer libMPSSE?
Anyone using libMPSSE? Should I expect more issues?
Any thoughts about FTDI solution stability is welcome.
Thanks
Dimitar
First of all:
In my understanding, large part of your "question" is not really a question but a "discussion starting point" which is not the scope of the "stack-..." ecosystem.
To the driver question part:
To the best of my knowledge, the driver is loaded once per device and not per port. However, the ftd2xx is able to address each port individually and set them to different modes (basically it simple gives the specific orders to the MPSSE engine which does not really care about the real meaning of the given sequences). Only thing you lose is the convinent VCP accessability.
The different libMPSSE modes have their limitations and quirks. A website search will yield more than enough as a starting point for more narrowed down follow-up questions. If you are only interested in one mode, an IC dedicated to only this mode might be an alternative to the relatively "generic" FTx232x serie.

Writing end to end linux device driver

I am looking forward to learn writing a typical linux device driver. Can anyone guide me how can i learn all the aspects of a typical linux device driver ? The examples i see on internet are way too simple, they just send a "hello world" msg from user space to kernel driver module, and echo back "hello". I want to touch almost all areas in a simple way, one would face in writing a real world driver. Would i need to have a real hardware to go forward to meet my requirement ? Cannot system's memory simulate the hardware peripheral and let me treat it as a hardware and control it vie kernel driver covering good set of operations ? Any examples/guidance for this ?
Take a look at the following example of network driver. It uses QEMU for development and testing.
http://www.codeproject.com/Articles/1087177/Linux-Ethernet-Driver-using-Qemu
Sample drivers usually don't control real hardware. The QEMU answer mentioned here is a good exception I guess.
It depends what type of driver you want to focus on. Most classes of drivers distributed with the kernel have some simpler drivers you can learn from. Nbd for example is great for block subsystem and loop devices:
https://github.com/torvalds/linux/blob/c05c2ec96bb8b7310da1055c7b9d786a3ec6dc0c/drivers/block/nbd.c
Look at the smallest file sizes in a drivers/xyz directory and go up until the code is too complex.

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.

how to access sound card in linux using nasm

hello i want to know how i can access sound card from nasm assembly program using int 0x80.
and also what values should i put in the registers when to access the sound card.
is there any manual or something that has details about the arguments that we have to pass to the kernel to access the sound card or other hardware devices, please if anyone know please tell me.
i had done alot of searching and well there alot of c libraries and ALSA and OSS and stuff like that, but what i would like is that if any one know of some resources about learning from the basics up about assembly program interfacing with the hardware.
and if any one could give me a small code listing as to how the access is done i would be very thankful.
As you've observed, the interface between user-space and kernel space in Linux is INT 0x80.
In Unix, as a matter of philosophy, (almost) everything is a file, thus sound cards are treated as "Character Files." The kernel syscalls are as per the POSIX specification - so "open","close","ioctl","read","write".
Access to the soundcard is done through the driver interface, as a file under "/dev/". Some sample documentation is at OSS documentation, but I'm not sure if its current.
To observe this communication, you can use 'strace' to see what system calls are being used by any existing application.
You will likely see a sequence like:
open("/dev/dsp", ... )
ioctl()
write()
...
write()
close()
Usually you'd get to "open" through the C library, but since you want to skip that, you can find the syscalls a few ways - one way would be
objdump -d /usr/lib/libc.a
For example, you can find that open is syscall 0x5 by looking for <__libc_open>:
You'll notice that eax is 5, and the rest of the parameters are in ebx, ecx and edx.
(The usage and parameters are also listed on Linux Syscalls )
This is what sound card drivers do. They have to be custom written for each sound card, in order to implement a common API which can be used by the O/S or applications. The same goes for other hardware devices. Hardware manufacturers tend to be less than open about how to access their stuff at this level (for one thing).
Not that I'm a Linux expert, but this is a fairly fundamental issue with all O/S's.
From user mode, this won't work - you won't have direct access to the sound hardware.
If you create a kernel-mode driver, you'd be able to directly poke the sound card hardware, but at this point I think most vendors have different implementations and don't follow a consistent standard. Newer sound cards might still be Adlib & SoundBlaster 16 compatible - this was the hardware standard WAY back when games were targetting DOS and directly used the hardware, but I wouldn't be surprised if this is no longer valid. A quick search should yield ways to directly access the interface for these legacy cards. Alternatively, you could run DOS inside of a virtual machine and access the hardware - most virtual machines emulate this level of sound card.
Depending what you're trying to do, you're probably better off using an existing library to handle the interface to the sound card, unless you aim to write a sound card driver, which I doubt, and that would be best done in C on linux.
Portaudio is one (free) one that's relatively easy to use. one example lib using portaudio with a C interface (I'm the author of wwviaudio).
FMOD seems to be big with the game programming guys, though it's not free.
sdl mixer is another one that's big with the linux game developers.
JACK is big in the linux pro-audio world. (think ardour -- the linux answer to Protools.)
There's no sense in trying to talk to the audio hardware directly from user space.

Resources