2 * This file is part of hci_h4p bluetooth driver
4 * Copyright (C) 2005, 2006 Nokia Corporation.
6 * Contact: Ville Tervo <ville.tervo@nokia.com>
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * version 2 as published by the Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
24 #include <linux/serial_reg.h>
25 #include <linux/delay.h>
26 #include <linux/clk.h>
32 inline void hci_h4p_outb(struct hci_h4p_info *info, unsigned int offset, u8 val)
34 outb(val, info->uart_base + (offset << 2));
37 inline u8 hci_h4p_inb(struct hci_h4p_info *info, unsigned int offset)
39 return inb(info->uart_base + (offset << 2));
42 void hci_h4p_set_rts(struct hci_h4p_info *info, int active)
46 b = hci_h4p_inb(info, UART_MCR);
51 hci_h4p_outb(info, UART_MCR, b);
54 int hci_h4p_wait_for_cts(struct hci_h4p_info *info, int active,
58 unsigned long timeout;
61 timeout = jiffies + msecs_to_jiffies(timeout_ms);
65 state = hci_h4p_inb(info, UART_MSR) & UART_MSR_CTS;
73 if (time_after(jiffies, timeout))
78 void hci_h4p_set_auto_ctsrts(struct hci_h4p_info *info, int on, u8 which)
82 lcr = hci_h4p_inb(info, UART_LCR);
83 hci_h4p_outb(info, UART_LCR, 0xbf);
84 b = hci_h4p_inb(info, UART_EFR);
89 hci_h4p_outb(info, UART_EFR, b);
90 hci_h4p_outb(info, UART_LCR, lcr);
93 void hci_h4p_change_speed(struct hci_h4p_info *info, unsigned long speed)
98 NBT_DBG("Setting speed %lu\n", speed);
100 if (speed >= 460800) {
101 divisor = UART_CLOCK / 13 / speed;
104 divisor = UART_CLOCK / 16 / speed;
108 hci_h4p_outb(info, UART_OMAP_MDR1, 7); /* Make sure UART mode is disabled */
109 lcr = hci_h4p_inb(info, UART_LCR);
110 hci_h4p_outb(info, UART_LCR, UART_LCR_DLAB); /* Set DLAB */
111 hci_h4p_outb(info, UART_DLL, divisor & 0xff); /* Set speed */
112 hci_h4p_outb(info, UART_DLM, divisor >> 8);
113 hci_h4p_outb(info, UART_LCR, lcr);
114 hci_h4p_outb(info, UART_OMAP_MDR1, mdr1); /* Make sure UART mode is enabled */
117 int hci_h4p_reset_uart(struct hci_h4p_info *info)
122 hci_h4p_outb(info, UART_OMAP_SYSC, UART_SYSC_OMAP_RESET);
123 while (!(hci_h4p_inb(info, UART_OMAP_SYSS) & UART_SYSS_RESETDONE)) {
125 dev_err(info->dev, "hci_h4p: UART reset timeout\n");
134 int hci_h4p_init_uart(struct hci_h4p_info *info)
138 err = hci_h4p_reset_uart(info);
142 /* Enable and setup FIFO */
143 hci_h4p_outb(info, UART_LCR, UART_LCR_WLEN8);
144 hci_h4p_outb(info, UART_OMAP_MDR1, 0x00); /* Make sure UART mode is enabled */
145 hci_h4p_outb(info, UART_OMAP_SCR, 0x80);
146 hci_h4p_outb(info, UART_EFR, UART_EFR_ECB);
147 hci_h4p_outb(info, UART_MCR, UART_MCR_TCRTLR);
148 hci_h4p_outb(info, UART_TI752_TLR, 0x1f);
149 hci_h4p_outb(info, UART_TI752_TCR, 0xef);
150 hci_h4p_outb(info, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR |
151 UART_FCR_CLEAR_XMIT | UART_FCR_R_TRIG_00);
152 hci_h4p_outb(info, UART_IER, UART_IER_RDI);