Esempio n. 1
0
int change_console_baud_rate(int baud)
{
    unsigned int ubrdiv;
    unsigned long rate;    
    struct s3c24xx_uart_clksrc clksrc;
    struct clk *clk;;

    s3c24xx_serial_getsource(cons_uart, &clksrc);

    clk = clk_get(cons_uart->dev, clksrc.name);
    if (!IS_ERR(clk) && clk != NULL)
    {
        rate = clk_get_rate(clk) / clksrc.divisor;
    }
    else
    {
        return -EINVAL;
    }

    ubrdiv= ((rate / 16) / baud) - 1;
    
    if(baud == 9600)
    {
        g_keyboard = true;
    }
    else
    {
        g_keyboard = false;
    }

    wr_regl(cons_uart, S3C2410_UBRDIV, ubrdiv);
    printk(KERN_DEBUG "[Keyboard] baud : %d, ubrdiv : %x\n", baud, ubrdiv);
    return 0;
    
}
Esempio n. 2
0
static unsigned int s3c24xx_serial_getclk(struct uart_port *port,
        struct s3c24xx_uart_clksrc **clksrc,
        struct clk **clk,
        unsigned int baud)
{
    struct s3c2410_uartcfg *cfg = s3c24xx_port_to_cfg(port);
    struct s3c24xx_uart_clksrc *clkp;
    struct baud_calc res[MAX_CLKS];
    struct baud_calc *resptr, *best, *sptr;
    int i;

    clkp = cfg->clocks;
    best = NULL;

    if (cfg->clocks_size < 2) {
        if (cfg->clocks_size == 0)
            clkp = &tmp_clksrc;

        /* check to see if we're sourcing fclk, and if so we're
         * going to have to update the clock source
         */

        if (strcmp(clkp->name, "fclk") == 0) {
            struct s3c24xx_uart_clksrc src;

            s3c24xx_serial_getsource(port, &src);

            /* check that the port already using fclk, and if
             * not, then re-select fclk
             */

            if (strcmp(src.name, clkp->name) == 0) {
                s3c24xx_serial_setsource(port, clkp);
                s3c24xx_serial_getsource(port, &src);
            }

            clkp->divisor = src.divisor;
        }

        s3c24xx_serial_calcbaud(res, port, clkp, baud);
        best = res;
        resptr = best + 1;
    } else {
        resptr = res;

        for (i = 0; i < cfg->clocks_size; i++, clkp++) {
            if (s3c24xx_serial_calcbaud(resptr, port, clkp, baud))
                resptr++;
        }
    }

    /* ok, we now need to select the best clock we found */

    if (!best) {
        unsigned int deviation = (1<<30)|((1<<30)-1);
        int calc_deviation;

        for (sptr = res; sptr < resptr; sptr++) {
            calc_deviation = baud - sptr->calc;
            if (calc_deviation < 0)
                calc_deviation = -calc_deviation;

            if (calc_deviation < deviation) {
                best = sptr;
                deviation = calc_deviation;
            }
        }
    }

    /* store results to pass back */

    *clksrc = best->clksrc;
    *clk    = best->src;

    return best->quot;
}
Esempio n. 3
0
static void __init
s3c24xx_serial_get_options(struct uart_port *port, int *baud,
                           int *parity, int *bits)
{
    struct s3c24xx_uart_clksrc clksrc;
    struct clk *clk;
    unsigned int ulcon;
    unsigned int ucon;
    unsigned int ubrdiv;
    unsigned long rate;

    ulcon  = rd_regl(port, S3C2410_ULCON);
    ucon   = rd_regl(port, S3C2410_UCON);
    ubrdiv = rd_regl(port, S3C2410_UBRDIV);

    dbg("s3c24xx_serial_get_options: port=%p\n"
        "registers: ulcon=%08x, ucon=%08x, ubdriv=%08x\n",
        port, ulcon, ucon, ubrdiv);

    if ((ucon & 0xf) != 0) {
        /* consider the serial port configured if the tx/rx mode set */

        switch (ulcon & S3C2410_LCON_CSMASK) {
        case S3C2410_LCON_CS5:
            *bits = 5;
            break;
        case S3C2410_LCON_CS6:
            *bits = 6;
            break;
        case S3C2410_LCON_CS7:
            *bits = 7;
            break;
        default:
        case S3C2410_LCON_CS8:
            *bits = 8;
            break;
        }

        switch (ulcon & S3C2410_LCON_PMASK) {
        case S3C2410_LCON_PEVEN:
            *parity = 'e';
            break;

        case S3C2410_LCON_PODD:
            *parity = 'o';
            break;

        case S3C2410_LCON_PNONE:
        default:
            *parity = 'n';
        }

        /* now calculate the baud rate */

        s3c24xx_serial_getsource(port, &clksrc);

        clk = clk_get(port->dev, clksrc.name);
        if (!IS_ERR(clk) && clk != NULL)
            rate = clk_get_rate(clk) / clksrc.divisor;
        else
            rate = 1;


        *baud = rate / (16 * (ubrdiv + 1));
        dbg("calculated baud %d\n", *baud);
    }

}
Esempio n. 4
0
static unsigned int s3c24xx_serial_getclk(struct uart_port *port,
					  struct s3c24xx_uart_clksrc **clksrc,
					  struct clk **clk,
					  unsigned int baud)
{
	struct s3c2410_uartcfg *cfg = s3c24xx_port_to_cfg(port);
	struct s3c24xx_uart_clksrc *clkp;
	struct baud_calc res[MAX_CLKS];
	struct baud_calc *resptr, *best, *sptr;
	int i;

	clkp = cfg->clocks;
	best = NULL;

	if (cfg->clocks_size < 2) {
		if (cfg->clocks_size == 0)
			clkp = &tmp_clksrc;

		

		if (strcmp(clkp->name, "fclk") == 0) {
			struct s3c24xx_uart_clksrc src;

			s3c24xx_serial_getsource(port, &src);

			

			if (strcmp(src.name, clkp->name) == 0) {
				s3c24xx_serial_setsource(port, clkp);
				s3c24xx_serial_getsource(port, &src);
			}

			clkp->divisor = src.divisor;
		}

		s3c24xx_serial_calcbaud(res, port, clkp, baud);
		best = res;
		resptr = best + 1;
	} else {
		resptr = res;

		for (i = 0; i < cfg->clocks_size; i++, clkp++) {
			if (s3c24xx_serial_calcbaud(resptr, port, clkp, baud))
				resptr++;
		}
	}

	

	if (!best) {
		unsigned int deviation = (1<<30)|((1<<30)-1);
		int calc_deviation;

		for (sptr = res; sptr < resptr; sptr++) {
			calc_deviation = baud - sptr->calc;
			if (calc_deviation < 0)
				calc_deviation = -calc_deviation;

			if (calc_deviation < deviation) {
				best = sptr;
				deviation = calc_deviation;
			}
		}
	}

	

	*clksrc = best->clksrc;
	*clk    = best->src;

	return best->quot;
}