Using UART in kernel driver code on AT91SAM9260
Hi,
I have a speech codec chip which uses SPI for high-speed PCM data and UART for control/compressed speech packet transfer.
While I could write a userland device driver that just uses the ttySn serial device, I would prefer to do that in kernel space since this is where device drivers belong.
This way a device could be created where compressed speech packets can be read and written.
Possible device setup functions could be done with IOCTLs.
Now what is the best way to implement this ?
There is the linux/drivers/char/atmel_serial.c driver which I could modify, so that it also includes the driver code for the speech codec. However, obviously that would be a really bad idea since it would duplicate code and completely bypass the linux serial port abstraction layer.
It would be better to somehow write a speech codec driver that depends on the UART driver.
Thus on the speech codec serial port no ttySn device should be created by the UART driver, but instead the speech codec driver should create the device (e.g. /dev/speechcodec0).
Since the speech codec driver should only do speech codec specific tasks, it should use the UART driver to send and receive data over the serial port.
I suppose this it is a common problem that higher level kernel driver code would like to use lower level driver code.
For example there is the GPIO driver which enables high level kernel code to use GPIO pins.
It's the same for other communication interfaces like I2C or SPI. However, these drivers usually do not create a device, but they rather export kernel symbols which can then be used by higher level kernel code. Unfortunately, it doesn't seem like the relevant serial port function symbols are exported ?
On mach-at91 it seems like the UART can be registered by calling the relevant setup function in linux/arch/arm/mach-at91/at91sam9260_devices.c which is at91_register_uart().
However, once I register an uart port, also a ttySn device is created (which I do not want).
By looking at linux/documentation/serial/driver it seems like bypassing linux/drivers/serial/serial_core.c seems to be the right way since the low level linux/drivers/serial/atmel_serial.c already provides the necessary UART ops in struct uart_ops.
However, these uart_ops are not exported, so I don't know how to access them.
Is this the right way to go ?
How could I use the low level driver but bypass serial_core ?
It would be great if you could provide some links to documentation and example code.
cheers,
Stefan
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
"Stefan" == Stefan Schoenleitner <[email protected]> writes:
Hi,
Stefan> There is the linux/drivers/char/atmel_serial.c driver which I Stefan> could modify, so that it also includes the driver code for Stefan> the speech codec. However, obviously that would be a really Stefan> bad idea since it would duplicate code and completely bypass Stefan> the linux serial port abstraction layer.
Stefan> It would be better to somehow write a speech codec driver Stefan> that depends on the UART driver. Thus on the speech codec Stefan> serial port no ttySn device should be created by the UART Stefan> driver, but instead the speech codec driver should create the Stefan> device (e.g. /dev/speechcodec0). Since the speech codec Stefan> driver should only do speech codec specific tasks, it should Stefan> use the UART driver to send and receive data over the serial Stefan> port.
The input layer has serio infrastructure for this (E.G. for serial mice/touchscreens). Now, a speech codec doesn't have much to do with input devices, but it atleast clearly seperates the lowlevel uart communication from the speech codec handling.
Have a look in drivers/input/{serio,touchscreen}.
Signature · 1 line
Bye, Peter Korsgaard
Hi,
Quoted 6 lines · Peter Korsgaard
The input layer has serio infrastructure for this (E.G. for serial mice/touchscreens). Now, a speech codec doesn't have much to do with input devices, but it atleast clearly seperates the lowlevel uart communication from the speech codec handling.
Have a look in
drivers/input/{serio,touchscreen}.
thanks for the tip !
I'm looking to find some more serio documentation now.
If it won't work out, I guess I still have the possibility to write a line discipline.
However, using serio seems to be more comfortable (also from a useeland perspective).
cheers,
stefan
Quoted 2 lines · Stefan Schoenleitner
It would be great if you could provide some links to documentation and example code.
I just found out that there are other kernel drivers using the serial port as well (e.g. the SLIP or PPP drivers).
It seems that what I want to do (which is accessing the serial port from kernel space) is called a "line discipline".
I found an article "Writing a Kernel Line Discipline" with code snippets on http://www.linux-mag.com/id/1891
(You can find a login to this page here: http://www.bugmenot.com)
Is this the right way to go ?