16C950 UART 9-bit and custom baud rates support for Linux
Last friday I found myself patching the Linux kernel sources to be able to add custom baud rates support for 16C950 UART cards. I needed to communicate, via a serial port, with one of the devices built by the hardware guys at work. Unfortunately, a non-standard baud rate and 9-bits were needed.
The Sealevel Ultra COMM+422 PCI card we are using is already provided with a patch that adds 9-bit support. However, I was not able to found how to change the baud rate to a non-standard one.
Following the 9-bit patch approach, I added extra requests to ioctl in order to modify the 16C950 registers needed to achieve custom baud rates. Here is the list of added extra ioctl requests (also the 9-bit ones) with the necessary parameters and updated/accessed 16C950 registers:
|TIOC9BITGET||out: integer||NMR||Get current 9-bit status|
|TIOC9BITSET||NMR||Enable 9-bit support|
|TIOC9BITCLR||NMR||Disable 9-bit support|
|TIOCPRESCALERGET||out: integer||EFR, MCR||Get prescaler status|
|TIOCPRESCALERSET||EFR, MCR||Enable prescaler|
|TIOCPRESCALERCLR||EFR, MCR||Disable prescaler|
|TIOCDIVLATCHGET||out: integer||LCR, DLL/DLM||Get divisor latch register|
|TIOCDIVLATCHSET||in: integer||LCR, DLL/DLM||Set divisor latch register|
|TIOCSAMPLINGCLKGET||out: integer||TCR||Get sampling clock|
|TIOCSAMPLINGCLKSET||in: integer||TCR||Set sampling clock|
|TIOCPRESCALERCLKGET||out: integer||CPR||Get prescaler clock|
|TIOCPRESCALERCLKSET||in: integer||CPR||Set prescaler clock|
I’m not sure if this is the best way to do it, but it works. So, if you need 9-bit and custom baud rates support, apply one the following patches to the kernel (I have aslo updated the Sealevel patch for older and newer kernels than the one provided):
|9-bit and baud rate||2.6.24||2.6.26||2.6.31||2.6.32|
I am not responsible for any damage that these patches can cause to your hardware. No warranty is provided, so use them at your own risk.