Re: [Gumstix-users] non-standard baud rates

On Jan 31, 2005, at 9:21 PM, Craig Hughes wrote:
> :) stty is though, and it too has trouble changing some parameters --
> probably some limitation of the pxa serial port ioctl implementation.
> In particular, it seem to allow me to set certain "standard" serial
> port baud rates, but not funky ones like 30720 or 31779. I'll look at
> the kernel code in the morning to try and figure out why.
I've been trying today to figure this out, and I think I'm on the right
track. There doesn't seem to be a way to ask for funky baud rates
directly. You'd have to change 4-5 different files to add the new baud
rates to the list. However it would seem that I can set the port to
38400, set the UPF_SPD_CUST flag, and the driver will jam a custom
divisor into the port's Divisor Latch Registers for me.
in drivers/serial/pxa.c the funtion serial_pxa_set_termios():
/*
* Ask the core to calculate the divisor for us.
*/
baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
quot = uart_get_divisor(port, baud);
uart_get_divisor() is in serial_core.c
if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST)
quot = port->custom_divisor;
else
quot = (port->uartclk + (8 * baud)) / (16 * baud);
return quot;
There are examples of how to do it with setserial, but they fail:
# ./setserial -a /dev/ttyS3 divisor 29 spd_cust
set_serial():TIOCSSERIAL:Cannot set serial info: Invalid argument
/dev/ttyS3, Line 3, UART: undefined, Port: 0x0000, IRQ: 0
Baud_base: 921600, close_delay: 50, divisor: 29
closing_wait: 3000
Flags: spd_cust
setserial's ioctl appears to call into uart_ioctl(), and then
uart_set_info() in serial_core.c. I'm guessing that this:
/*
* Ask the low level driver to verify the settings.
*/
if (port->ops->verify_port)
retval = port->ops->verify_port(port, &new_serial);
might be where it's failing...
static int
serial_pxa_verify_port(struct uart_port *port, struct serial_struct
*ser)
{
/* we don't want the core code to modify any port params */
return -EINVAL;
}
Does anyone know their way around this code enough to guess where to
look more closely?