bfin_serial_5xx.h 4.4 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
/*
 * file:        include/asm-blackfin/mach-bf561/bfin_serial_5xx.h
 * based on:
 * author:
 *
 * created:
 * description:
 *	blackfin serial driver head file
 * rev:
 *
 * modified:
 *
 *
 * bugs:         enter bugs at http://blackfin.uclinux.org/
 *
 * this program is free software; you can redistribute it and/or modify
 * it under the terms of the gnu general public license as published by
 * the free software foundation; either version 2, or (at your option)
 * any later version.
 *
 * this program is distributed in the hope that it will be useful,
 * but without any warranty; without even the implied warranty of
 * merchantability or fitness for a particular purpose.  see the
 * gnu general public license for more details.
 *
 * you should have received a copy of the gnu general public license
 * along with this program; see the file copying.
 * if not, write to the free software foundation,
 * 59 temple place - suite 330, boston, ma 02111-1307, usa.
 */

B
Bryan Wu 已提交
32 33
#include <linux/serial.h>
#include <asm/dma.h>
34
#include <asm/portmux.h>
B
Bryan Wu 已提交
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63

#define UART_GET_CHAR(uart)     bfin_read16(((uart)->port.membase + OFFSET_RBR))
#define UART_GET_DLL(uart)	bfin_read16(((uart)->port.membase + OFFSET_DLL))
#define UART_GET_IER(uart)      bfin_read16(((uart)->port.membase + OFFSET_IER))
#define UART_GET_DLH(uart)	bfin_read16(((uart)->port.membase + OFFSET_DLH))
#define UART_GET_IIR(uart)      bfin_read16(((uart)->port.membase + OFFSET_IIR))
#define UART_GET_LCR(uart)      bfin_read16(((uart)->port.membase + OFFSET_LCR))
#define UART_GET_GCTL(uart)     bfin_read16(((uart)->port.membase + OFFSET_GCTL))

#define UART_PUT_CHAR(uart,v)   bfin_write16(((uart)->port.membase + OFFSET_THR),v)
#define UART_PUT_DLL(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_DLL),v)
#define UART_PUT_IER(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_IER),v)
#define UART_PUT_DLH(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_DLH),v)
#define UART_PUT_LCR(uart,v)    bfin_write16(((uart)->port.membase + OFFSET_LCR),v)
#define UART_PUT_GCTL(uart,v)   bfin_write16(((uart)->port.membase + OFFSET_GCTL),v)

#ifdef CONFIG_BFIN_UART0_CTSRTS
# define CONFIG_SERIAL_BFIN_CTSRTS
# ifndef CONFIG_UART0_CTS_PIN
#  define CONFIG_UART0_CTS_PIN -1
# endif
# ifndef CONFIG_UART0_RTS_PIN
#  define CONFIG_UART0_RTS_PIN -1
# endif
#endif

struct bfin_serial_port {
        struct uart_port        port;
        unsigned int            old_status;
64
	unsigned int lsr;
B
Bryan Wu 已提交
65 66 67 68 69 70 71 72 73 74
#ifdef CONFIG_SERIAL_BFIN_DMA
	int			tx_done;
	int			tx_count;
	struct circ_buf		rx_dma_buf;
	struct timer_list       rx_dma_timer;
	int			rx_dma_nrows;
	unsigned int		tx_dma_channel;
	unsigned int		rx_dma_channel;
	struct work_struct	tx_dma_workqueue;
#else
75 76 77
# if ANOMALY_05000230
	unsigned int anomaly_threshold;
# endif
B
Bryan Wu 已提交
78 79
#endif
#ifdef CONFIG_SERIAL_BFIN_CTSRTS
80
	struct work_struct 	cts_workqueue;
B
Bryan Wu 已提交
81 82 83 84 85
	int			cts_pin;
	int			rts_pin;
#endif
};

86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
/* The hardware clears the LSR bits upon read, so we need to cache
 * some of the more fun bits in software so they don't get lost
 * when checking the LSR in other code paths (TX).
 */
static inline unsigned int UART_GET_LSR(struct bfin_serial_port *uart)
{
	unsigned int lsr = bfin_read16(uart->port.membase + OFFSET_LSR);
	uart->lsr |= (lsr & (BI|FE|PE|OE));
	return lsr | uart->lsr;
}

static inline void UART_CLEAR_LSR(struct bfin_serial_port *uart)
{
	uart->lsr = 0;
	bfin_write16(uart->port.membase + OFFSET_LSR, -1);
}

103
struct bfin_serial_port bfin_serial_ports[BFIN_UART_NR_PORTS];
B
Bryan Wu 已提交
104 105 106 107 108 109 110 111 112 113 114 115 116 117
struct bfin_serial_res {
	unsigned long	uart_base_addr;
	int		uart_irq;
#ifdef CONFIG_SERIAL_BFIN_DMA
	unsigned int	uart_tx_dma_channel;
	unsigned int	uart_rx_dma_channel;
#endif
#ifdef CONFIG_SERIAL_BFIN_CTSRTS
	int		uart_cts_pin;
	int		uart_rts_pin;
#endif
};

struct bfin_serial_res bfin_serial_resource[] = {
118
	{
B
Bryan Wu 已提交
119 120 121 122 123 124 125 126 127 128
	0xFFC00400,
	IRQ_UART_RX,
#ifdef CONFIG_SERIAL_BFIN_DMA
	CH_UART_TX,
	CH_UART_RX,
#endif
#ifdef CONFIG_BFIN_UART0_CTSRTS
	CONFIG_UART0_CTS_PIN,
	CONFIG_UART0_RTS_PIN,
#endif
129
	}
B
Bryan Wu 已提交
130 131
};

132
#define DRIVER_NAME "bfin-uart"
B
Bryan Wu 已提交
133

134
int nr_ports = BFIN_UART_NR_PORTS;
B
Bryan Wu 已提交
135 136 137
static void bfin_serial_hw_init(struct bfin_serial_port *uart)
{

138 139 140 141 142
#ifdef CONFIG_SERIAL_BFIN_UART0
	peripheral_request(P_UART0_TX, DRIVER_NAME);
	peripheral_request(P_UART0_RX, DRIVER_NAME);
#endif

B
Bryan Wu 已提交
143 144
#ifdef CONFIG_SERIAL_BFIN_CTSRTS
	if (uart->cts_pin >= 0) {
145
		gpio_request(uart->cts_pin, DRIVER_NAME);
B
Bryan Wu 已提交
146 147 148
		gpio_direction_input(uart->cts_pin);
	}
	if (uart->rts_pin >= 0) {
149
		gpio_request(uart->rts_pin, DRIVER_NAME);
150
		gpio_direction_input(uart->rts_pin, 0);
B
Bryan Wu 已提交
151 152 153
	}
#endif
}