diff options
-rw-r--r-- | drivers/staging/Kconfig | 2 | ||||
-rw-r--r-- | drivers/staging/Makefile | 1 | ||||
-rw-r--r-- | drivers/staging/nokia_h4p/Kconfig | 9 | ||||
-rw-r--r-- | drivers/staging/nokia_h4p/Makefile | 6 | ||||
-rw-r--r-- | drivers/staging/nokia_h4p/TODO | 140 | ||||
-rw-r--r-- | drivers/staging/nokia_h4p/hci_h4p.h | 228 | ||||
-rw-r--r-- | drivers/staging/nokia_h4p/nokia_core.c | 1205 | ||||
-rw-r--r-- | drivers/staging/nokia_h4p/nokia_fw-bcm.c | 147 | ||||
-rw-r--r-- | drivers/staging/nokia_h4p/nokia_fw-csr.c | 150 | ||||
-rw-r--r-- | drivers/staging/nokia_h4p/nokia_fw-ti1273.c | 110 | ||||
-rw-r--r-- | drivers/staging/nokia_h4p/nokia_fw.c | 195 | ||||
-rw-r--r-- | drivers/staging/nokia_h4p/nokia_uart.c | 199 | ||||
-rw-r--r-- | include/linux/platform_data/bt-nokia-h4p.h | 38 |
13 files changed, 2430 insertions, 0 deletions
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig index 93a7ecf936ac..babb1cf67ce7 100644 --- a/drivers/staging/Kconfig +++ b/drivers/staging/Kconfig | |||
@@ -148,4 +148,6 @@ source "drivers/staging/dgap/Kconfig" | |||
148 | 148 | ||
149 | source "drivers/staging/gs_fpgaboot/Kconfig" | 149 | source "drivers/staging/gs_fpgaboot/Kconfig" |
150 | 150 | ||
151 | source "drivers/staging/nokia_h4p/Kconfig" | ||
152 | |||
151 | endif # STAGING | 153 | endif # STAGING |
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile index 399f9fe07014..2c4949a9bd9b 100644 --- a/drivers/staging/Makefile +++ b/drivers/staging/Makefile | |||
@@ -66,3 +66,4 @@ obj-$(CONFIG_DGNC) += dgnc/ | |||
66 | obj-$(CONFIG_DGAP) += dgap/ | 66 | obj-$(CONFIG_DGAP) += dgap/ |
67 | obj-$(CONFIG_MTD_SPINAND_MT29F) += mt29f_spinand/ | 67 | obj-$(CONFIG_MTD_SPINAND_MT29F) += mt29f_spinand/ |
68 | obj-$(CONFIG_GS_FPGABOOT) += gs_fpgaboot/ | 68 | obj-$(CONFIG_GS_FPGABOOT) += gs_fpgaboot/ |
69 | obj-$(CONFIG_BT_NOKIA_H4P) += nokia_h4p/ | ||
diff --git a/drivers/staging/nokia_h4p/Kconfig b/drivers/staging/nokia_h4p/Kconfig new file mode 100644 index 000000000000..4336c0ad065b --- /dev/null +++ b/drivers/staging/nokia_h4p/Kconfig | |||
@@ -0,0 +1,9 @@ | |||
1 | config BT_NOKIA_H4P | ||
2 | tristate "HCI driver with H4 Nokia extensions" | ||
3 | depends on BT && ARCH_OMAP | ||
4 | help | ||
5 | Bluetooth HCI driver with H4 extensions. This driver provides | ||
6 | support for H4+ Bluetooth chip with vendor-specific H4 extensions. | ||
7 | |||
8 | Say Y here to compile support for h4 extended devices into the kernel | ||
9 | or say M to compile it as module (btnokia_h4p). | ||
diff --git a/drivers/staging/nokia_h4p/Makefile b/drivers/staging/nokia_h4p/Makefile new file mode 100644 index 000000000000..9625db4a9af3 --- /dev/null +++ b/drivers/staging/nokia_h4p/Makefile | |||
@@ -0,0 +1,6 @@ | |||
1 | |||
2 | obj-$(CONFIG_BT_NOKIA_H4P) += btnokia_h4p.o | ||
3 | btnokia_h4p-objs := nokia_core.o nokia_fw.o nokia_uart.o nokia_fw-csr.o \ | ||
4 | nokia_fw-bcm.o nokia_fw-ti1273.o | ||
5 | |||
6 | ccflags-y += -D__CHECK_ENDIAN__ | ||
diff --git a/drivers/staging/nokia_h4p/TODO b/drivers/staging/nokia_h4p/TODO new file mode 100644 index 000000000000..d997afe14173 --- /dev/null +++ b/drivers/staging/nokia_h4p/TODO | |||
@@ -0,0 +1,140 @@ | |||
1 | Few attempts to submission have been made, last review comments were received in | ||
2 | |||
3 | Date: Wed, 15 Jan 2014 19:01:51 -0800 | ||
4 | From: Marcel Holtmann <marcel@holtmann.org> | ||
5 | Subject: Re: [PATCH v6] Bluetooth: Add hci_h4p driver | ||
6 | |||
7 | Some code refactoring is still needed. | ||
8 | |||
9 | TODO: | ||
10 | |||
11 | > +++ b/drivers/bluetooth/hci_h4p.h | ||
12 | |||
13 | can we please get the naming straight. File names do not start with | ||
14 | hci_ anymore. We moved away from it since that term is too generic. | ||
15 | |||
16 | > +#define FW_NAME_TI1271_LE "ti1273_le.bin" | ||
17 | > +#define FW_NAME_TI1271 "ti1273.bin" | ||
18 | > +#define FW_NAME_BCM2048 "bcmfw.bin" | ||
19 | > +#define FW_NAME_CSR "bc4fw.bin" | ||
20 | |||
21 | We do these have to be global in a header file. This should be | ||
22 | confined to the specific firmware part. | ||
23 | |||
24 | > +struct hci_h4p_info { | ||
25 | |||
26 | Can we please get rid of the hci_ prefix for everything. Copying from | ||
27 | drivers that are over 10 years old is not a good idea. Please look at | ||
28 | recent ones. | ||
29 | |||
30 | > + struct timer_list lazy_release; | ||
31 | |||
32 | Timer? Not delayed work? | ||
33 | |||
34 | > +void hci_h4p_outb(struct hci_h4p_info *info, unsigned int offset, u8 val); | ||
35 | > +u8 hci_h4p_inb(struct hci_h4p_info *info, unsigned int offset); | ||
36 | > +void hci_h4p_set_rts(struct hci_h4p_info *info, int active); | ||
37 | > +int hci_h4p_wait_for_cts(struct hci_h4p_info *info, int active, int timeout_ms); | ||
38 | > +void __hci_h4p_set_auto_ctsrts(struct hci_h4p_info *info, int on, u8 which); | ||
39 | > +void hci_h4p_set_auto_ctsrts(struct hci_h4p_info *info, int on, u8 which); | ||
40 | > +void hci_h4p_change_speed(struct hci_h4p_info *info, unsigned long speed); | ||
41 | > +int hci_h4p_reset_uart(struct hci_h4p_info *info); | ||
42 | > +void hci_h4p_init_uart(struct hci_h4p_info *info); | ||
43 | > +void hci_h4p_enable_tx(struct hci_h4p_info *info); | ||
44 | > +void hci_h4p_store_regs(struct hci_h4p_info *info); | ||
45 | > +void hci_h4p_restore_regs(struct hci_h4p_info *info); | ||
46 | > +void hci_h4p_smart_idle(struct hci_h4p_info *info, bool enable); | ||
47 | |||
48 | These are a lot of public functions. Are they all really needed or can | ||
49 | the code be done smart. | ||
50 | |||
51 | > +static ssize_t hci_h4p_store_bdaddr(struct device *dev, | ||
52 | > + struct device_attribute *attr, | ||
53 | > + const char *buf, size_t count) | ||
54 | > +{ | ||
55 | > + struct hci_h4p_info *info = dev_get_drvdata(dev); | ||
56 | |||
57 | Since none of these devices can function without having a valid | ||
58 | address, the way this should work is that we should not register the | ||
59 | HCI device when probing the platform device. | ||
60 | |||
61 | The HCI device should be registered once a valid address has been | ||
62 | written into the sysfs file. I do not want to play the tricks with | ||
63 | bringing up the device without a valid address. | ||
64 | |||
65 | > + hdev->close = hci_h4p_hci_close; | ||
66 | > + hdev->flush = hci_h4p_hci_flush; | ||
67 | > + hdev->send = hci_h4p_hci_send_frame; | ||
68 | |||
69 | It needs to use hdev->setup to load the firmware. I assume the | ||
70 | firmware only needs to be loaded once. That is exactly what | ||
71 | hdev->setup does. It gets executed once. | ||
72 | |||
73 | > + set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks); | ||
74 | |||
75 | Is this quirk really needed? Normally only Bluetooth 1.1 and early | ||
76 | devices qualify for it. | ||
77 | |||
78 | > +static int hci_h4p_bcm_set_bdaddr(struct hci_h4p_info *info, struct sk_buff *skb) | ||
79 | > +{ | ||
80 | > + int i; | ||
81 | > + static const u8 nokia_oui[3] = {0x00, 0x1f, 0xdf}; | ||
82 | > + int not_valid; | ||
83 | |||
84 | Has this actually been confirmed that we can just randomly set an | ||
85 | address out of the Nokia range. I do not think so. This is a pretty | ||
86 | bad idea. | ||
87 | |||
88 | I have no interest in merging a driver with such a hack. | ||
89 | |||
90 | > + not_valid = 1; | ||
91 | > + for (i = 0; i < 6; i++) { | ||
92 | > + if (info->bd_addr[i] != 0x00) { | ||
93 | > + not_valid = 0; | ||
94 | > + break; | ||
95 | > + } | ||
96 | > + } | ||
97 | |||
98 | Anybody every heard of memcmp or bacmp and BDADDR_ANY? | ||
99 | |||
100 | > + if (not_valid) { | ||
101 | > + dev_info(info->dev, "Valid bluetooth address not found," | ||
102 | > + " setting some random\n"); | ||
103 | > + /* When address is not valid, use some random */ | ||
104 | > + memcpy(info->bd_addr, nokia_oui, 3); | ||
105 | > + get_random_bytes(info->bd_addr + 3, 3); | ||
106 | > + } | ||
107 | |||
108 | |||
109 | And why does every single chip firmware does this differently. Seriously, this is a mess. | ||
110 | |||
111 | > +void hci_h4p_parse_fw_event(struct hci_h4p_info *info, struct sk_buff *skb) | ||
112 | > +{ | ||
113 | > + switch (info->man_id) { | ||
114 | > + case H4P_ID_CSR: | ||
115 | > + hci_h4p_bc4_parse_fw_event(info, skb); | ||
116 | > + break; | ||
117 | ... | ||
118 | > +} | ||
119 | |||
120 | We have proper HCI sync command handling in recent kernels. I really | ||
121 | do not know why this is hand coded these days. Check how the Intel | ||
122 | firmware loading inside btusb.c does it. | ||
123 | |||
124 | > +inline u8 hci_h4p_inb(struct hci_h4p_info *info, unsigned int offset) | ||
125 | > +{ | ||
126 | > + return __raw_readb(info->uart_base + (offset << 2)); | ||
127 | > +} | ||
128 | |||
129 | Inline in a *.c file for a non-static function. Makes no sense to me. | ||
130 | |||
131 | > +/** | ||
132 | > + * struct hci_h4p_platform data - hci_h4p Platform data structure | ||
133 | > + */ | ||
134 | > +struct hci_h4p_platform_data { | ||
135 | |||
136 | please have a proper name here. For example | ||
137 | btnokia_h4p_platform_data. | ||
138 | |||
139 | Please send patches to Greg Kroah-Hartman <greg@kroah.com> and Cc: | ||
140 | Pavel Machek <pavel@ucw.cz> | ||
diff --git a/drivers/staging/nokia_h4p/hci_h4p.h b/drivers/staging/nokia_h4p/hci_h4p.h new file mode 100644 index 000000000000..fd7a6407f20c --- /dev/null +++ b/drivers/staging/nokia_h4p/hci_h4p.h | |||
@@ -0,0 +1,228 @@ | |||
1 | /* | ||
2 | * This file is part of Nokia H4P bluetooth driver | ||
3 | * | ||
4 | * Copyright (C) 2005-2008 Nokia Corporation. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * version 2 as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, but | ||
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
18 | * 02110-1301 USA | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #ifndef __DRIVERS_BLUETOOTH_HCI_H4P_H | ||
23 | #define __DRIVERS_BLUETOOTH_HCI_H4P_H | ||
24 | |||
25 | #include <net/bluetooth/bluetooth.h> | ||
26 | #include <net/bluetooth/hci_core.h> | ||
27 | #include <net/bluetooth/hci.h> | ||
28 | |||
29 | #define FW_NAME_TI1271_PRELE "ti1273_prele.bin" | ||
30 | #define FW_NAME_TI1271_LE "ti1273_le.bin" | ||
31 | #define FW_NAME_TI1271 "ti1273.bin" | ||
32 | #define FW_NAME_BCM2048 "bcmfw.bin" | ||
33 | #define FW_NAME_CSR "bc4fw.bin" | ||
34 | |||
35 | #define UART_SYSC_OMAP_RESET 0x03 | ||
36 | #define UART_SYSS_RESETDONE 0x01 | ||
37 | #define UART_OMAP_SCR_EMPTY_THR 0x08 | ||
38 | #define UART_OMAP_SCR_WAKEUP 0x10 | ||
39 | #define UART_OMAP_SSR_WAKEUP 0x02 | ||
40 | #define UART_OMAP_SSR_TXFULL 0x01 | ||
41 | |||
42 | #define UART_OMAP_SYSC_IDLEMODE 0x03 | ||
43 | #define UART_OMAP_SYSC_IDLEMASK (3 << UART_OMAP_SYSC_IDLEMODE) | ||
44 | |||
45 | #define UART_OMAP_SYSC_FORCE_IDLE (0 << UART_OMAP_SYSC_IDLEMODE) | ||
46 | #define UART_OMAP_SYSC_NO_IDLE (1 << UART_OMAP_SYSC_IDLEMODE) | ||
47 | #define UART_OMAP_SYSC_SMART_IDLE (2 << UART_OMAP_SYSC_IDLEMODE) | ||
48 | |||
49 | #define H4P_TRANSFER_MODE 1 | ||
50 | #define H4P_SCHED_TRANSFER_MODE 2 | ||
51 | #define H4P_ACTIVE_MODE 3 | ||
52 | |||
53 | struct hci_h4p_info { | ||
54 | struct timer_list lazy_release; | ||
55 | struct hci_dev *hdev; | ||
56 | spinlock_t lock; | ||
57 | |||
58 | void __iomem *uart_base; | ||
59 | unsigned long uart_phys_base; | ||
60 | int irq; | ||
61 | struct device *dev; | ||
62 | u8 chip_type; | ||
63 | u8 bt_wakeup_gpio; | ||
64 | u8 host_wakeup_gpio; | ||
65 | u8 reset_gpio; | ||
66 | u8 reset_gpio_shared; | ||
67 | u8 bt_sysclk; | ||
68 | u8 man_id; | ||
69 | u8 ver_id; | ||
70 | |||
71 | struct sk_buff_head fw_queue; | ||
72 | struct sk_buff *alive_cmd_skb; | ||
73 | struct completion init_completion; | ||
74 | struct completion fw_completion; | ||
75 | struct completion test_completion; | ||
76 | int fw_error; | ||
77 | int init_error; | ||
78 | |||
79 | struct sk_buff_head txq; | ||
80 | |||
81 | struct sk_buff *rx_skb; | ||
82 | long rx_count; | ||
83 | unsigned long rx_state; | ||
84 | unsigned long garbage_bytes; | ||
85 | |||
86 | u8 bd_addr[6]; | ||
87 | struct sk_buff_head *fw_q; | ||
88 | |||
89 | int pm_enabled; | ||
90 | int tx_enabled; | ||
91 | int autorts; | ||
92 | int rx_enabled; | ||
93 | unsigned long pm_flags; | ||
94 | |||
95 | int tx_clocks_en; | ||
96 | int rx_clocks_en; | ||
97 | spinlock_t clocks_lock; | ||
98 | struct clk *uart_iclk; | ||
99 | struct clk *uart_fclk; | ||
100 | atomic_t clk_users; | ||
101 | u16 dll; | ||
102 | u16 dlh; | ||
103 | u16 ier; | ||
104 | u16 mdr1; | ||
105 | u16 efr; | ||
106 | }; | ||
107 | |||
108 | struct hci_h4p_radio_hdr { | ||
109 | __u8 evt; | ||
110 | __u8 dlen; | ||
111 | } __attribute__ ((packed)); | ||
112 | |||
113 | struct hci_h4p_neg_hdr { | ||
114 | __u8 dlen; | ||
115 | } __attribute__ ((packed)); | ||
116 | #define H4P_NEG_HDR_SIZE 1 | ||
117 | |||
118 | #define H4P_NEG_REQ 0x00 | ||
119 | #define H4P_NEG_ACK 0x20 | ||
120 | #define H4P_NEG_NAK 0x40 | ||
121 | |||
122 | #define H4P_PROTO_PKT 0x44 | ||
123 | #define H4P_PROTO_BYTE 0x4c | ||
124 | |||
125 | #define H4P_ID_CSR 0x02 | ||
126 | #define H4P_ID_BCM2048 0x04 | ||
127 | #define H4P_ID_TI1271 0x31 | ||
128 | |||
129 | struct hci_h4p_neg_cmd { | ||
130 | __u8 ack; | ||
131 | __u16 baud; | ||
132 | __u16 unused1; | ||
133 | __u8 proto; | ||
134 | __u16 sys_clk; | ||
135 | __u16 unused2; | ||
136 | } __attribute__ ((packed)); | ||
137 | |||
138 | struct hci_h4p_neg_evt { | ||
139 | __u8 ack; | ||
140 | __u16 baud; | ||
141 | __u16 unused1; | ||
142 | __u8 proto; | ||
143 | __u16 sys_clk; | ||
144 | __u16 unused2; | ||
145 | __u8 man_id; | ||
146 | __u8 ver_id; | ||
147 | } __attribute__ ((packed)); | ||
148 | |||
149 | #define H4P_ALIVE_REQ 0x55 | ||
150 | #define H4P_ALIVE_RESP 0xcc | ||
151 | |||
152 | struct hci_h4p_alive_hdr { | ||
153 | __u8 dlen; | ||
154 | } __attribute__ ((packed)); | ||
155 | #define H4P_ALIVE_HDR_SIZE 1 | ||
156 | |||
157 | struct hci_h4p_alive_pkt { | ||
158 | __u8 mid; | ||
159 | __u8 unused; | ||
160 | } __attribute__ ((packed)); | ||
161 | |||
162 | #define MAX_BAUD_RATE 921600 | ||
163 | #define BC4_MAX_BAUD_RATE 3692300 | ||
164 | #define UART_CLOCK 48000000 | ||
165 | #define BT_INIT_DIVIDER 320 | ||
166 | #define BT_BAUDRATE_DIVIDER 384000000 | ||
167 | #define BT_SYSCLK_DIV 1000 | ||
168 | #define INIT_SPEED 120000 | ||
169 | |||
170 | #define H4_TYPE_SIZE 1 | ||
171 | #define H4_RADIO_HDR_SIZE 2 | ||
172 | |||
173 | /* H4+ packet types */ | ||
174 | #define H4_CMD_PKT 0x01 | ||
175 | #define H4_ACL_PKT 0x02 | ||
176 | #define H4_SCO_PKT 0x03 | ||
177 | #define H4_EVT_PKT 0x04 | ||
178 | #define H4_NEG_PKT 0x06 | ||
179 | #define H4_ALIVE_PKT 0x07 | ||
180 | #define H4_RADIO_PKT 0x08 | ||
181 | |||
182 | /* TX states */ | ||
183 | #define WAIT_FOR_PKT_TYPE 1 | ||
184 | #define WAIT_FOR_HEADER 2 | ||
185 | #define WAIT_FOR_DATA 3 | ||
186 | |||
187 | struct hci_fw_event { | ||
188 | struct hci_event_hdr hev; | ||
189 | struct hci_ev_cmd_complete cmd; | ||
190 | u8 status; | ||
191 | } __attribute__ ((packed)); | ||
192 | |||
193 | int hci_h4p_send_alive_packet(struct hci_h4p_info *info); | ||
194 | |||
195 | void hci_h4p_bcm_parse_fw_event(struct hci_h4p_info *info, | ||
196 | struct sk_buff *skb); | ||
197 | int hci_h4p_bcm_send_fw(struct hci_h4p_info *info, | ||
198 | struct sk_buff_head *fw_queue); | ||
199 | |||
200 | void hci_h4p_bc4_parse_fw_event(struct hci_h4p_info *info, | ||
201 | struct sk_buff *skb); | ||
202 | int hci_h4p_bc4_send_fw(struct hci_h4p_info *info, | ||
203 | struct sk_buff_head *fw_queue); | ||
204 | |||
205 | void hci_h4p_ti1273_parse_fw_event(struct hci_h4p_info *info, | ||
206 | struct sk_buff *skb); | ||
207 | int hci_h4p_ti1273_send_fw(struct hci_h4p_info *info, | ||
208 | struct sk_buff_head *fw_queue); | ||
209 | |||
210 | int hci_h4p_read_fw(struct hci_h4p_info *info, struct sk_buff_head *fw_queue); | ||
211 | int hci_h4p_send_fw(struct hci_h4p_info *info, struct sk_buff_head *fw_queue); | ||
212 | void hci_h4p_parse_fw_event(struct hci_h4p_info *info, struct sk_buff *skb); | ||
213 | |||
214 | void hci_h4p_outb(struct hci_h4p_info *info, unsigned int offset, u8 val); | ||
215 | u8 hci_h4p_inb(struct hci_h4p_info *info, unsigned int offset); | ||
216 | void hci_h4p_set_rts(struct hci_h4p_info *info, int active); | ||
217 | int hci_h4p_wait_for_cts(struct hci_h4p_info *info, int active, int timeout_ms); | ||
218 | void __hci_h4p_set_auto_ctsrts(struct hci_h4p_info *info, int on, u8 which); | ||
219 | void hci_h4p_set_auto_ctsrts(struct hci_h4p_info *info, int on, u8 which); | ||
220 | void hci_h4p_change_speed(struct hci_h4p_info *info, unsigned long speed); | ||
221 | int hci_h4p_reset_uart(struct hci_h4p_info *info); | ||
222 | void hci_h4p_init_uart(struct hci_h4p_info *info); | ||
223 | void hci_h4p_enable_tx(struct hci_h4p_info *info); | ||
224 | void hci_h4p_store_regs(struct hci_h4p_info *info); | ||
225 | void hci_h4p_restore_regs(struct hci_h4p_info *info); | ||
226 | void hci_h4p_smart_idle(struct hci_h4p_info *info, bool enable); | ||
227 | |||
228 | #endif /* __DRIVERS_BLUETOOTH_HCI_H4P_H */ | ||
diff --git a/drivers/staging/nokia_h4p/nokia_core.c b/drivers/staging/nokia_h4p/nokia_core.c new file mode 100644 index 000000000000..5da84b06eff3 --- /dev/null +++ b/drivers/staging/nokia_h4p/nokia_core.c | |||
@@ -0,0 +1,1205 @@ | |||
1 | /* | ||
2 | * This file is part of Nokia H4P bluetooth driver | ||
3 | * | ||
4 | * Copyright (C) 2005-2008 Nokia Corporation. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * version 2 as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, but | ||
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
18 | * 02110-1301 USA | ||
19 | * | ||
20 | * Thanks to all the Nokia people that helped with this driver, | ||
21 | * including Ville Tervo and Roger Quadros. | ||
22 | * | ||
23 | * Power saving functionality was removed from this driver to make | ||
24 | * merging easier. | ||
25 | */ | ||
26 | |||
27 | #include <linux/module.h> | ||
28 | #include <linux/kernel.h> | ||
29 | #include <linux/init.h> | ||
30 | #include <linux/errno.h> | ||
31 | #include <linux/delay.h> | ||
32 | #include <linux/spinlock.h> | ||
33 | #include <linux/serial_reg.h> | ||
34 | #include <linux/skbuff.h> | ||
35 | #include <linux/device.h> | ||
36 | #include <linux/platform_device.h> | ||
37 | #include <linux/clk.h> | ||
38 | #include <linux/interrupt.h> | ||
39 | #include <linux/gpio.h> | ||
40 | #include <linux/timer.h> | ||
41 | #include <linux/kthread.h> | ||
42 | #include <linux/io.h> | ||
43 | #include <linux/completion.h> | ||
44 | #include <linux/sizes.h> | ||
45 | |||
46 | #include <net/bluetooth/bluetooth.h> | ||
47 | #include <net/bluetooth/hci_core.h> | ||
48 | #include <net/bluetooth/hci.h> | ||
49 | |||
50 | #include <linux/platform_data/bt-nokia-h4p.h> | ||
51 | |||
52 | #include "hci_h4p.h" | ||
53 | |||
54 | /* This should be used in function that cannot release clocks */ | ||
55 | static void hci_h4p_set_clk(struct hci_h4p_info *info, int *clock, int enable) | ||
56 | { | ||
57 | unsigned long flags; | ||
58 | |||
59 | spin_lock_irqsave(&info->clocks_lock, flags); | ||
60 | if (enable && !*clock) { | ||
61 | BT_DBG("Enabling %p", clock); | ||
62 | clk_prepare_enable(info->uart_fclk); | ||
63 | clk_prepare_enable(info->uart_iclk); | ||
64 | if (atomic_read(&info->clk_users) == 0) | ||
65 | hci_h4p_restore_regs(info); | ||
66 | atomic_inc(&info->clk_users); | ||
67 | } | ||
68 | |||
69 | if (!enable && *clock) { | ||
70 | BT_DBG("Disabling %p", clock); | ||
71 | if (atomic_dec_and_test(&info->clk_users)) | ||
72 | hci_h4p_store_regs(info); | ||
73 | clk_disable_unprepare(info->uart_fclk); | ||
74 | clk_disable_unprepare(info->uart_iclk); | ||
75 | } | ||
76 | |||
77 | *clock = enable; | ||
78 | spin_unlock_irqrestore(&info->clocks_lock, flags); | ||
79 | } | ||
80 | |||
81 | static void hci_h4p_lazy_clock_release(unsigned long data) | ||
82 | { | ||
83 | struct hci_h4p_info *info = (struct hci_h4p_info *)data; | ||
84 | unsigned long flags; | ||
85 | |||
86 | spin_lock_irqsave(&info->lock, flags); | ||
87 | if (!info->tx_enabled) | ||
88 | hci_h4p_set_clk(info, &info->tx_clocks_en, 0); | ||
89 | spin_unlock_irqrestore(&info->lock, flags); | ||
90 | } | ||
91 | |||
92 | /* Power management functions */ | ||
93 | void hci_h4p_smart_idle(struct hci_h4p_info *info, bool enable) | ||
94 | { | ||
95 | u8 v; | ||
96 | |||
97 | v = hci_h4p_inb(info, UART_OMAP_SYSC); | ||
98 | v &= ~(UART_OMAP_SYSC_IDLEMASK); | ||
99 | |||
100 | if (enable) | ||
101 | v |= UART_OMAP_SYSC_SMART_IDLE; | ||
102 | else | ||
103 | v |= UART_OMAP_SYSC_NO_IDLE; | ||
104 | |||
105 | hci_h4p_outb(info, UART_OMAP_SYSC, v); | ||
106 | } | ||
107 | |||
108 | static inline void h4p_schedule_pm(struct hci_h4p_info *info) | ||
109 | { | ||
110 | } | ||
111 | |||
112 | static void hci_h4p_disable_tx(struct hci_h4p_info *info) | ||
113 | { | ||
114 | if (!info->pm_enabled) | ||
115 | return; | ||
116 | |||
117 | /* Re-enable smart-idle */ | ||
118 | hci_h4p_smart_idle(info, 1); | ||
119 | |||
120 | gpio_set_value(info->bt_wakeup_gpio, 0); | ||
121 | mod_timer(&info->lazy_release, jiffies + msecs_to_jiffies(100)); | ||
122 | info->tx_enabled = 0; | ||
123 | } | ||
124 | |||
125 | void hci_h4p_enable_tx(struct hci_h4p_info *info) | ||
126 | { | ||
127 | unsigned long flags; | ||
128 | |||
129 | if (!info->pm_enabled) | ||
130 | return; | ||
131 | |||
132 | h4p_schedule_pm(info); | ||
133 | |||
134 | spin_lock_irqsave(&info->lock, flags); | ||
135 | del_timer(&info->lazy_release); | ||
136 | hci_h4p_set_clk(info, &info->tx_clocks_en, 1); | ||
137 | info->tx_enabled = 1; | ||
138 | gpio_set_value(info->bt_wakeup_gpio, 1); | ||
139 | hci_h4p_outb(info, UART_IER, hci_h4p_inb(info, UART_IER) | | ||
140 | UART_IER_THRI); | ||
141 | /* | ||
142 | * Disable smart-idle as UART TX interrupts | ||
143 | * are not wake-up capable | ||
144 | */ | ||
145 | hci_h4p_smart_idle(info, 0); | ||
146 | |||
147 | spin_unlock_irqrestore(&info->lock, flags); | ||
148 | } | ||
149 | |||
150 | static void hci_h4p_disable_rx(struct hci_h4p_info *info) | ||
151 | { | ||
152 | if (!info->pm_enabled) | ||
153 | return; | ||
154 | |||
155 | info->rx_enabled = 0; | ||
156 | |||
157 | if (hci_h4p_inb(info, UART_LSR) & UART_LSR_DR) | ||
158 | return; | ||
159 | |||
160 | if (!(hci_h4p_inb(info, UART_LSR) & UART_LSR_TEMT)) | ||
161 | return; | ||
162 | |||
163 | __hci_h4p_set_auto_ctsrts(info, 0, UART_EFR_RTS); | ||
164 | info->autorts = 0; | ||
165 | hci_h4p_set_clk(info, &info->rx_clocks_en, 0); | ||
166 | } | ||
167 | |||
168 | static void hci_h4p_enable_rx(struct hci_h4p_info *info) | ||
169 | { | ||
170 | if (!info->pm_enabled) | ||
171 | return; | ||
172 | |||
173 | h4p_schedule_pm(info); | ||
174 | |||
175 | hci_h4p_set_clk(info, &info->rx_clocks_en, 1); | ||
176 | info->rx_enabled = 1; | ||
177 | |||
178 | if (!(hci_h4p_inb(info, UART_LSR) & UART_LSR_TEMT)) | ||
179 | return; | ||
180 | |||
181 | __hci_h4p_set_auto_ctsrts(info, 1, UART_EFR_RTS); | ||
182 | info->autorts = 1; | ||
183 | } | ||
184 | |||
185 | /* Negotiation functions */ | ||
186 | int hci_h4p_send_alive_packet(struct hci_h4p_info *info) | ||
187 | { | ||
188 | struct hci_h4p_alive_hdr *hdr; | ||
189 | struct hci_h4p_alive_pkt *pkt; | ||
190 | struct sk_buff *skb; | ||
191 | unsigned long flags; | ||
192 | int len; | ||
193 | |||
194 | BT_DBG("Sending alive packet"); | ||
195 | |||
196 | len = H4_TYPE_SIZE + sizeof(*hdr) + sizeof(*pkt); | ||
197 | skb = bt_skb_alloc(len, GFP_KERNEL); | ||
198 | if (!skb) | ||
199 | return -ENOMEM; | ||
200 | |||
201 | memset(skb->data, 0x00, len); | ||
202 | *skb_put(skb, 1) = H4_ALIVE_PKT; | ||
203 | hdr = (struct hci_h4p_alive_hdr *)skb_put(skb, sizeof(*hdr)); | ||
204 | hdr->dlen = sizeof(*pkt); | ||
205 | pkt = (struct hci_h4p_alive_pkt *)skb_put(skb, sizeof(*pkt)); | ||
206 | pkt->mid = H4P_ALIVE_REQ; | ||
207 | |||
208 | skb_queue_tail(&info->txq, skb); | ||
209 | spin_lock_irqsave(&info->lock, flags); | ||
210 | hci_h4p_outb(info, UART_IER, hci_h4p_inb(info, UART_IER) | | ||
211 | UART_IER_THRI); | ||
212 | spin_unlock_irqrestore(&info->lock, flags); | ||
213 | |||
214 | BT_DBG("Alive packet sent"); | ||
215 | |||
216 | return 0; | ||
217 | } | ||
218 | |||
219 | static void hci_h4p_alive_packet(struct hci_h4p_info *info, | ||
220 | struct sk_buff *skb) | ||
221 | { | ||
222 | struct hci_h4p_alive_hdr *hdr; | ||
223 | struct hci_h4p_alive_pkt *pkt; | ||
224 | |||
225 | BT_DBG("Received alive packet"); | ||
226 | hdr = (struct hci_h4p_alive_hdr *)skb->data; | ||
227 | if (hdr->dlen != sizeof(*pkt)) { | ||
228 | dev_err(info->dev, "Corrupted alive message\n"); | ||
229 | info->init_error = -EIO; | ||
230 | goto finish_alive; | ||
231 | } | ||
232 | |||
233 | pkt = (struct hci_h4p_alive_pkt *)skb_pull(skb, sizeof(*hdr)); | ||
234 | if (pkt->mid != H4P_ALIVE_RESP) { | ||
235 | dev_err(info->dev, "Could not negotiate hci_h4p settings\n"); | ||
236 | info->init_error = -EINVAL; | ||
237 | } | ||
238 | |||
239 | finish_alive: | ||
240 | complete(&info->init_completion); | ||
241 | kfree_skb(skb); | ||
242 | } | ||
243 | |||
244 | static int hci_h4p_send_negotiation(struct hci_h4p_info *info) | ||
245 | { | ||
246 | struct hci_h4p_neg_cmd *neg_cmd; | ||
247 | struct hci_h4p_neg_hdr *neg_hdr; | ||
248 | struct sk_buff *skb; | ||
249 | unsigned long flags; | ||
250 | int err, len; | ||
251 | u16 sysclk; | ||
252 | |||
253 | BT_DBG("Sending negotiation.."); | ||
254 | |||
255 | switch (info->bt_sysclk) { | ||
256 | case 1: | ||
257 | sysclk = 12000; | ||
258 | break; | ||
259 | case 2: | ||
260 | sysclk = 38400; | ||
261 | break; | ||
262 | default: | ||
263 | return -EINVAL; | ||
264 | } | ||
265 | |||
266 | len = sizeof(*neg_cmd) + sizeof(*neg_hdr) + H4_TYPE_SIZE; | ||
267 | skb = bt_skb_alloc(len, GFP_KERNEL); | ||
268 | if (!skb) | ||
269 | return -ENOMEM; | ||
270 | |||
271 | memset(skb->data, 0x00, len); | ||
272 | *skb_put(skb, 1) = H4_NEG_PKT; | ||
273 | neg_hdr = (struct hci_h4p_neg_hdr *)skb_put(skb, sizeof(*neg_hdr)); | ||
274 | neg_cmd = (struct hci_h4p_neg_cmd *)skb_put(skb, sizeof(*neg_cmd)); | ||
275 | |||
276 | neg_hdr->dlen = sizeof(*neg_cmd); | ||
277 | neg_cmd->ack = H4P_NEG_REQ; | ||
278 | neg_cmd->baud = cpu_to_le16(BT_BAUDRATE_DIVIDER/MAX_BAUD_RATE); | ||
279 | neg_cmd->proto = H4P_PROTO_BYTE; | ||
280 | neg_cmd->sys_clk = cpu_to_le16(sysclk); | ||
281 | |||
282 | hci_h4p_change_speed(info, INIT_SPEED); | ||
283 | |||
284 | hci_h4p_set_rts(info, 1); | ||
285 | info->init_error = 0; | ||
286 | init_completion(&info->init_completion); | ||
287 | skb_queue_tail(&info->txq, skb); | ||
288 | spin_lock_irqsave(&info->lock, flags); | ||
289 | hci_h4p_outb(info, UART_IER, hci_h4p_inb(info, UART_IER) | | ||
290 | UART_IER_THRI); | ||
291 | spin_unlock_irqrestore(&info->lock, flags); | ||
292 | |||
293 | if (!wait_for_completion_interruptible_timeout(&info->init_completion, | ||
294 | msecs_to_jiffies(1000))) | ||
295 | return -ETIMEDOUT; | ||
296 | |||
297 | if (info->init_error < 0) | ||
298 | return info->init_error; | ||
299 | |||
300 | /* Change to operational settings */ | ||
301 | hci_h4p_set_auto_ctsrts(info, 0, UART_EFR_RTS); | ||
302 | hci_h4p_set_rts(info, 0); | ||
303 | hci_h4p_change_speed(info, MAX_BAUD_RATE); | ||
304 | |||
305 | err = hci_h4p_wait_for_cts(info, 1, 100); | ||
306 | if (err < 0) | ||
307 | return err; | ||
308 | |||
309 | hci_h4p_set_auto_ctsrts(info, 1, UART_EFR_RTS); | ||
310 | init_completion(&info->init_completion); | ||
311 | err = hci_h4p_send_alive_packet(info); | ||
312 | |||
313 | if (err < 0) | ||
314 | return err; | ||
315 | |||
316 | if (!wait_for_completion_interruptible_timeout(&info->init_completion, | ||
317 | msecs_to_jiffies(1000))) | ||
318 | return -ETIMEDOUT; | ||
319 | |||
320 | if (info->init_error < 0) | ||
321 | return info->init_error; | ||
322 | |||
323 | BT_DBG("Negotiation successful"); | ||
324 | return 0; | ||
325 | } | ||
326 | |||
327 | static void hci_h4p_negotiation_packet(struct hci_h4p_info *info, | ||
328 | struct sk_buff *skb) | ||
329 | { | ||
330 | struct hci_h4p_neg_hdr *hdr; | ||
331 | struct hci_h4p_neg_evt *evt; | ||
332 | |||
333 | hdr = (struct hci_h4p_neg_hdr *)skb->data; | ||
334 | if (hdr->dlen != sizeof(*evt)) { | ||
335 | info->init_error = -EIO; | ||
336 | goto finish_neg; | ||
337 | } | ||
338 | |||
339 | evt = (struct hci_h4p_neg_evt *)skb_pull(skb, sizeof(*hdr)); | ||
340 | |||
341 | if (evt->ack != H4P_NEG_ACK) { | ||
342 | dev_err(info->dev, "Could not negotiate hci_h4p settings\n"); | ||
343 | info->init_error = -EINVAL; | ||
344 | } | ||
345 | |||
346 | info->man_id = evt->man_id; | ||
347 | info->ver_id = evt->ver_id; | ||
348 | |||
349 | finish_neg: | ||
350 | |||
351 | complete(&info->init_completion); | ||
352 | kfree_skb(skb); | ||
353 | } | ||
354 | |||
355 | /* H4 packet handling functions */ | ||
356 | static int hci_h4p_get_hdr_len(struct hci_h4p_info *info, u8 pkt_type) | ||
357 | { | ||
358 | long retval; | ||
359 | |||
360 | switch (pkt_type) { | ||
361 | case H4_EVT_PKT: | ||
362 | retval = HCI_EVENT_HDR_SIZE; | ||
363 | break; | ||
364 | case H4_ACL_PKT: | ||
365 | retval = HCI_ACL_HDR_SIZE; | ||
366 | break; | ||
367 | case H4_SCO_PKT: | ||
368 | retval = HCI_SCO_HDR_SIZE; | ||
369 | break; | ||
370 | case H4_NEG_PKT: | ||
371 | retval = H4P_NEG_HDR_SIZE; | ||
372 | break; | ||
373 | case H4_ALIVE_PKT: | ||
374 | retval = H4P_ALIVE_HDR_SIZE; | ||
375 | break; | ||
376 | case H4_RADIO_PKT: | ||
377 | retval = H4_RADIO_HDR_SIZE; | ||
378 | break; | ||
379 | default: | ||
380 | dev_err(info->dev, "Unknown H4 packet type 0x%.2x\n", pkt_type); | ||
381 | retval = -1; | ||
382 | break; | ||
383 | } | ||
384 | |||
385 | return retval; | ||
386 | } | ||
387 | |||
388 | static unsigned int hci_h4p_get_data_len(struct hci_h4p_info *info, | ||
389 | struct sk_buff *skb) | ||
390 | { | ||
391 | long retval = -1; | ||
392 | struct hci_acl_hdr *acl_hdr; | ||
393 | struct hci_sco_hdr *sco_hdr; | ||
394 | struct hci_event_hdr *evt_hdr; | ||
395 | struct hci_h4p_neg_hdr *neg_hdr; | ||
396 | struct hci_h4p_alive_hdr *alive_hdr; | ||
397 | struct hci_h4p_radio_hdr *radio_hdr; | ||
398 | |||
399 | switch (bt_cb(skb)->pkt_type) { | ||
400 | case H4_EVT_PKT: | ||
401 | evt_hdr = (struct hci_event_hdr *)skb->data; | ||
402 | retval = evt_hdr->plen; | ||
403 | break; | ||
404 | case H4_ACL_PKT: | ||
405 | acl_hdr = (struct hci_acl_hdr *)skb->data; | ||
406 | retval = le16_to_cpu(acl_hdr->dlen); | ||
407 | break; | ||
408 | case H4_SCO_PKT: | ||
409 | sco_hdr = (struct hci_sco_hdr *)skb->data; | ||
410 | retval = sco_hdr->dlen; | ||
411 | break; | ||
412 | case H4_RADIO_PKT: | ||
413 | radio_hdr = (struct hci_h4p_radio_hdr *)skb->data; | ||
414 | retval = radio_hdr->dlen; | ||
415 | break; | ||
416 | case H4_NEG_PKT: | ||
417 | neg_hdr = (struct hci_h4p_neg_hdr *)skb->data; | ||
418 | retval = neg_hdr->dlen; | ||
419 | break; | ||
420 | case H4_ALIVE_PKT: | ||
421 | alive_hdr = (struct hci_h4p_alive_hdr *)skb->data; | ||
422 | retval = alive_hdr->dlen; | ||
423 | break; | ||
424 | } | ||
425 | |||
426 | return retval; | ||
427 | } | ||
428 | |||
429 | static inline void hci_h4p_recv_frame(struct hci_h4p_info *info, | ||
430 | struct sk_buff *skb) | ||
431 | { | ||
432 | if (unlikely(!test_bit(HCI_RUNNING, &info->hdev->flags))) { | ||
433 | switch (bt_cb(skb)->pkt_type) { | ||
434 | case H4_NEG_PKT: | ||
435 | hci_h4p_negotiation_packet(info, skb); | ||
436 | info->rx_state = WAIT_FOR_PKT_TYPE; | ||
437 | return; | ||
438 | case H4_ALIVE_PKT: | ||
439 | hci_h4p_alive_packet(info, skb); | ||
440 | info->rx_state = WAIT_FOR_PKT_TYPE; | ||
441 | return; | ||
442 | } | ||
443 | |||
444 | if (!test_bit(HCI_UP, &info->hdev->flags)) { | ||
445 | BT_DBG("fw_event"); | ||
446 | hci_h4p_parse_fw_event(info, skb); | ||
447 | return; | ||
448 | } | ||
449 | } | ||
450 | |||
451 | hci_recv_frame(info->hdev, skb); | ||
452 | BT_DBG("Frame sent to upper layer"); | ||
453 | } | ||
454 | |||
455 | static inline void hci_h4p_handle_byte(struct hci_h4p_info *info, u8 byte) | ||
456 | { | ||
457 | switch (info->rx_state) { | ||
458 | case WAIT_FOR_PKT_TYPE: | ||
459 | bt_cb(info->rx_skb)->pkt_type = byte; | ||
460 | info->rx_count = hci_h4p_get_hdr_len(info, byte); | ||
461 | if (info->rx_count < 0) { | ||
462 | info->hdev->stat.err_rx++; | ||
463 | kfree_skb(info->rx_skb); | ||
464 | info->rx_skb = NULL; | ||
465 | } else { | ||
466 | info->rx_state = WAIT_FOR_HEADER; | ||
467 | } | ||
468 | break; | ||
469 | case WAIT_FOR_HEADER: | ||
470 | info->rx_count--; | ||
471 | *skb_put(info->rx_skb, 1) = byte; | ||
472 | if (info->rx_count != 0) | ||
473 | break; | ||
474 | info->rx_count = hci_h4p_get_data_len(info, info->rx_skb); | ||
475 | if (info->rx_count > skb_tailroom(info->rx_skb)) { | ||
476 | dev_err(info->dev, "frame too long\n"); | ||
477 | info->garbage_bytes = info->rx_count | ||
478 | - skb_tailroom(info->rx_skb); | ||
479 | kfree_skb(info->rx_skb); | ||
480 | info->rx_skb = NULL; | ||
481 | break; | ||
482 | } | ||
483 | info->rx_state = WAIT_FOR_DATA; | ||
484 | break; | ||
485 | case WAIT_FOR_DATA: | ||
486 | info->rx_count--; | ||
487 | *skb_put(info->rx_skb, 1) = byte; | ||
488 | break; | ||
489 | default: | ||
490 | WARN_ON(1); | ||
491 | break; | ||
492 | } | ||
493 | |||
494 | if (info->rx_count == 0) { | ||
495 | /* H4+ devices should always send word aligned packets */ | ||
496 | if (!(info->rx_skb->len % 2)) | ||
497 | info->garbage_bytes++; | ||
498 | hci_h4p_recv_frame(info, info->rx_skb); | ||
499 | info->rx_skb = NULL; | ||
500 | } | ||
501 | } | ||
502 | |||
503 | static void hci_h4p_rx_tasklet(unsigned long data) | ||
504 | { | ||
505 | u8 byte; | ||
506 | struct hci_h4p_info *info = (struct hci_h4p_info *)data; | ||
507 | |||
508 | BT_DBG("tasklet woke up"); | ||
509 | BT_DBG("rx_tasklet woke up"); | ||
510 | |||
511 | while (hci_h4p_inb(info, UART_LSR) & UART_LSR_DR) { | ||
512 | byte = hci_h4p_inb(info, UART_RX); | ||
513 | if (info->garbage_bytes) { | ||
514 | info->garbage_bytes--; | ||
515 | continue; | ||
516 | } | ||
517 | if (info->rx_skb == NULL) { | ||
518 | info->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, | ||
519 | GFP_ATOMIC | GFP_DMA); | ||
520 | if (!info->rx_skb) { | ||
521 | dev_err(info->dev, | ||
522 | "No memory for new packet\n"); | ||
523 | goto finish_rx; | ||
524 | } | ||
525 | info->rx_state = WAIT_FOR_PKT_TYPE; | ||
526 | info->rx_skb->dev = (void *)info->hdev; | ||
527 | } | ||
528 | info->hdev->stat.byte_rx++; | ||
529 | hci_h4p_handle_byte(info, byte); | ||
530 | } | ||
531 | |||
532 | if (!info->rx_enabled) { | ||
533 | if (hci_h4p_inb(info, UART_LSR) & UART_LSR_TEMT && | ||
534 | info->autorts) { | ||
535 | __hci_h4p_set_auto_ctsrts(info, 0 , UART_EFR_RTS); | ||
536 | info->autorts = 0; | ||
537 | } | ||
538 | /* Flush posted write to avoid spurious interrupts */ | ||
539 | hci_h4p_inb(info, UART_OMAP_SCR); | ||
540 | hci_h4p_set_clk(info, &info->rx_clocks_en, 0); | ||
541 | } | ||
542 | |||
543 | finish_rx: | ||
544 | BT_DBG("rx_ended"); | ||
545 | } | ||
546 | |||
547 | static void hci_h4p_tx_tasklet(unsigned long data) | ||
548 | { | ||
549 | unsigned int sent = 0; | ||
550 | struct sk_buff *skb; | ||
551 | struct hci_h4p_info *info = (struct hci_h4p_info *)data; | ||
552 | |||
553 | BT_DBG("tasklet woke up"); | ||
554 | BT_DBG("tx_tasklet woke up"); | ||
555 | |||
556 | if (info->autorts != info->rx_enabled) { | ||
557 | if (hci_h4p_inb(info, UART_LSR) & UART_LSR_TEMT) { | ||
558 | if (info->autorts && !info->rx_enabled) { | ||
559 | __hci_h4p_set_auto_ctsrts(info, 0, | ||
560 | UART_EFR_RTS); | ||
561 | info->autorts = 0; | ||
562 | } | ||
563 | if (!info->autorts && info->rx_enabled) { | ||
564 | __hci_h4p_set_auto_ctsrts(info, 1, | ||
565 | UART_EFR_RTS); | ||
566 | info->autorts = 1; | ||
567 | } | ||
568 | } else { | ||
569 | hci_h4p_outb(info, UART_OMAP_SCR, | ||
570 | hci_h4p_inb(info, UART_OMAP_SCR) | | ||
571 | UART_OMAP_SCR_EMPTY_THR); | ||
572 | goto finish_tx; | ||
573 | } | ||
574 | } | ||
575 | |||
576 | skb = skb_dequeue(&info->txq); | ||
577 | if (!skb) { | ||
578 | /* No data in buffer */ | ||
579 | BT_DBG("skb ready"); | ||
580 | if (hci_h4p_inb(info, UART_LSR) & UART_LSR_TEMT) { | ||
581 | hci_h4p_outb(info, UART_IER, | ||
582 | hci_h4p_inb(info, UART_IER) & | ||
583 | ~UART_IER_THRI); | ||
584 | hci_h4p_inb(info, UART_OMAP_SCR); | ||
585 | hci_h4p_disable_tx(info); | ||
586 | return; | ||
587 | } | ||
588 | hci_h4p_outb(info, UART_OMAP_SCR, | ||
589 | hci_h4p_inb(info, UART_OMAP_SCR) | | ||
590 | UART_OMAP_SCR_EMPTY_THR); | ||
591 | goto finish_tx; | ||
592 | } | ||
593 | |||
594 | /* Copy data to tx fifo */ | ||
595 | while (!(hci_h4p_inb(info, UART_OMAP_SSR) & UART_OMAP_SSR_TXFULL) && | ||
596 | (sent < skb->len)) { | ||
597 | hci_h4p_outb(info, UART_TX, skb->data[sent]); | ||
598 | sent++; | ||
599 | } | ||
600 | |||
601 | info->hdev->stat.byte_tx += sent; | ||
602 | if (skb->len == sent) { | ||
603 | kfree_skb(skb); | ||
604 | } else { | ||
605 | skb_pull(skb, sent); | ||
606 | skb_queue_head(&info->txq, skb); | ||
607 | } | ||
608 | |||
609 | hci_h4p_outb(info, UART_OMAP_SCR, hci_h4p_inb(info, UART_OMAP_SCR) & | ||
610 | ~UART_OMAP_SCR_EMPTY_THR); | ||
611 | hci_h4p_outb(info, UART_IER, hci_h4p_inb(info, UART_IER) | | ||
612 | UART_IER_THRI); | ||
613 | |||
614 | finish_tx: | ||
615 | /* Flush posted write to avoid spurious interrupts */ | ||
616 | hci_h4p_inb(info, UART_OMAP_SCR); | ||
617 | |||
618 | } | ||
619 | |||
620 | static irqreturn_t hci_h4p_interrupt(int irq, void *data) | ||
621 | { | ||
622 | struct hci_h4p_info *info = (struct hci_h4p_info *)data; | ||
623 | u8 iir, msr; | ||
624 | int ret; | ||
625 | |||
626 | ret = IRQ_NONE; | ||
627 | |||
628 | iir = hci_h4p_inb(info, UART_IIR); | ||
629 | if (iir & UART_IIR_NO_INT) | ||
630 | return IRQ_HANDLED; | ||
631 | |||
632 | BT_DBG("In interrupt handler iir 0x%.2x", iir); | ||
633 | |||
634 | iir &= UART_IIR_ID; | ||
635 | |||
636 | if (iir == UART_IIR_MSI) { | ||
637 | msr = hci_h4p_inb(info, UART_MSR); | ||
638 | ret = IRQ_HANDLED; | ||
639 | } | ||
640 | if (iir == UART_IIR_RLSI) { | ||
641 | hci_h4p_inb(info, UART_RX); | ||
642 | hci_h4p_inb(info, UART_LSR); | ||
643 | ret = IRQ_HANDLED; | ||
644 | } | ||
645 | |||
646 | if (iir == UART_IIR_RDI) { | ||
647 | hci_h4p_rx_tasklet((unsigned long)data); | ||
648 | ret = IRQ_HANDLED; | ||
649 | } | ||
650 | |||
651 | if (iir == UART_IIR_THRI) { | ||
652 | hci_h4p_tx_tasklet((unsigned long)data); | ||
653 | ret = IRQ_HANDLED; | ||
654 | } | ||
655 | |||
656 | return ret; | ||
657 | } | ||
658 | |||
659 | static irqreturn_t hci_h4p_wakeup_interrupt(int irq, void *dev_inst) | ||
660 | { | ||
661 | struct hci_h4p_info *info = dev_inst; | ||
662 | int should_wakeup; | ||
663 | struct hci_dev *hdev; | ||
664 | |||
665 | if (!info->hdev) | ||
666 | return IRQ_HANDLED; | ||
667 | |||
668 | should_wakeup = gpio_get_value(info->host_wakeup_gpio); | ||
669 | hdev = info->hdev; | ||
670 | |||
671 | if (!test_bit(HCI_RUNNING, &hdev->flags)) { | ||
672 | if (should_wakeup == 1) | ||
673 | complete_all(&info->test_completion); | ||
674 | |||
675 | return IRQ_HANDLED; | ||
676 | } | ||
677 | |||
678 | BT_DBG("gpio interrupt %d", should_wakeup); | ||
679 | |||
680 | /* Check if wee have missed some interrupts */ | ||
681 | if (info->rx_enabled == should_wakeup) | ||
682 | return IRQ_HANDLED; | ||
683 | |||
684 | if (should_wakeup) | ||
685 | hci_h4p_enable_rx(info); | ||
686 | else | ||
687 | hci_h4p_disable_rx(info); | ||
688 | |||
689 | return IRQ_HANDLED; | ||
690 | } | ||
691 | |||
692 | static inline void hci_h4p_set_pm_limits(struct hci_h4p_info *info, bool set) | ||
693 | { | ||
694 | struct hci_h4p_platform_data *bt_plat_data = info->dev->platform_data; | ||
695 | const char *sset = set ? "set" : "clear"; | ||
696 | |||
697 | if (unlikely(!bt_plat_data || !bt_plat_data->set_pm_limits)) | ||
698 | return; | ||
699 | |||
700 | if (set != !!test_bit(H4P_ACTIVE_MODE, &info->pm_flags)) { | ||
701 | bt_plat_data->set_pm_limits(info->dev, set); | ||
702 | if (set) | ||
703 | set_bit(H4P_ACTIVE_MODE, &info->pm_flags); | ||
704 | else | ||
705 | clear_bit(H4P_ACTIVE_MODE, &info->pm_flags); | ||
706 | BT_DBG("Change pm constraints to: %s", sset); | ||
707 | return; | ||
708 | } | ||
709 | |||
710 | BT_DBG("pm constraints remains: %s", sset); | ||
711 | } | ||
712 | |||
713 | static int hci_h4p_reset(struct hci_h4p_info *info) | ||
714 | { | ||
715 | int err; | ||
716 | |||
717 | err = hci_h4p_reset_uart(info); | ||
718 | if (err < 0) { | ||
719 | dev_err(info->dev, "Uart reset failed\n"); | ||
720 | return err; | ||
721 | } | ||
722 | hci_h4p_init_uart(info); | ||
723 | hci_h4p_set_rts(info, 0); | ||
724 | |||
725 | gpio_set_value(info->reset_gpio, 0); | ||
726 | gpio_set_value(info->bt_wakeup_gpio, 1); | ||
727 | msleep(10); | ||
728 | |||
729 | if (gpio_get_value(info->host_wakeup_gpio) == 1) { | ||
730 | dev_err(info->dev, "host_wakeup_gpio not low\n"); | ||
731 | return -EPROTO; | ||
732 | } | ||
733 | |||
734 | init_completion(&info->test_completion); | ||
735 | gpio_set_value(info->reset_gpio, 1); | ||
736 | |||
737 | if (!wait_for_completion_interruptible_timeout(&info->test_completion, | ||
738 | msecs_to_jiffies(100))) { | ||
739 | dev_err(info->dev, "wakeup test timed out\n"); | ||
740 | complete_all(&info->test_completion); | ||
741 | return -EPROTO; | ||
742 | } | ||
743 | |||
744 | err = hci_h4p_wait_for_cts(info, 1, 100); | ||
745 | if (err < 0) { | ||
746 | dev_err(info->dev, "No cts from bt chip\n"); | ||
747 | return err; | ||
748 | } | ||
749 | |||
750 | hci_h4p_set_rts(info, 1); | ||
751 | |||
752 | return 0; | ||
753 | } | ||
754 | |||
755 | /* hci callback functions */ | ||
756 | static int hci_h4p_hci_flush(struct hci_dev *hdev) | ||
757 | { | ||
758 | struct hci_h4p_info *info = hci_get_drvdata(hdev); | ||
759 | skb_queue_purge(&info->txq); | ||
760 | |||
761 | return 0; | ||
762 | } | ||
763 | |||
764 | static int hci_h4p_bt_wakeup_test(struct hci_h4p_info *info) | ||
765 | { | ||
766 | /* | ||
767 | * Test Sequence: | ||
768 | * Host de-asserts the BT_WAKE_UP line. | ||
769 | * Host polls the UART_CTS line, waiting for it to be de-asserted. | ||
770 | * Host asserts the BT_WAKE_UP line. | ||
771 | * Host polls the UART_CTS line, waiting for it to be asserted. | ||
772 | * Host de-asserts the BT_WAKE_UP line (allow the Bluetooth device to | ||
773 | * sleep). | ||
774 | * Host polls the UART_CTS line, waiting for it to be de-asserted. | ||
775 | */ | ||
776 | int err; | ||
777 | int ret = -ECOMM; | ||
778 | |||
779 | if (!info) | ||
780 | return -EINVAL; | ||
781 | |||
782 | /* Disable wakeup interrupts */ | ||
783 | disable_irq(gpio_to_irq(info->host_wakeup_gpio)); | ||
784 | |||
785 | gpio_set_value(info->bt_wakeup_gpio, 0); | ||
786 | err = hci_h4p_wait_for_cts(info, 0, 100); | ||
787 | if (err) { | ||
788 | dev_warn(info->dev, "bt_wakeup_test: fail: " | ||
789 | "CTS low timed out: %d\n", err); | ||
790 | goto out; | ||
791 | } | ||
792 | |||
793 | gpio_set_value(info->bt_wakeup_gpio, 1); | ||
794 | err = hci_h4p_wait_for_cts(info, 1, 100); | ||
795 | if (err) { | ||
796 | dev_warn(info->dev, "bt_wakeup_test: fail: " | ||
797 | "CTS high timed out: %d\n", err); | ||
798 | goto out; | ||
799 | } | ||
800 | |||
801 | gpio_set_value(info->bt_wakeup_gpio, 0); | ||
802 | err = hci_h4p_wait_for_cts(info, 0, 100); | ||
803 | if (err) { | ||
804 | dev_warn(info->dev, "bt_wakeup_test: fail: " | ||
805 | "CTS re-low timed out: %d\n", err); | ||
806 | goto out; | ||
807 | } | ||
808 | |||
809 | ret = 0; | ||
810 | |||
811 | out: | ||
812 | |||
813 | /* Re-enable wakeup interrupts */ | ||
814 | enable_irq(gpio_to_irq(info->host_wakeup_gpio)); | ||
815 | |||
816 | return ret; | ||
817 | } | ||
818 | |||
819 | static int hci_h4p_hci_open(struct hci_dev *hdev) | ||
820 | { | ||
821 | struct hci_h4p_info *info; | ||
822 | int err, retries = 0; | ||
823 | struct sk_buff_head fw_queue; | ||
824 | unsigned long flags; | ||
825 | |||
826 | info = hci_get_drvdata(hdev); | ||
827 | |||
828 | if (test_bit(HCI_RUNNING, &hdev->flags)) | ||
829 | return 0; | ||
830 | |||
831 | /* TI1271 has HW bug and boot up might fail. Retry up to three times */ | ||
832 | again: | ||
833 | |||
834 | info->rx_enabled = 1; | ||
835 | info->rx_state = WAIT_FOR_PKT_TYPE; | ||
836 | info->rx_count = 0; | ||
837 | info->garbage_bytes = 0; | ||
838 | info->rx_skb = NULL; | ||
839 | info->pm_enabled = 0; | ||
840 | init_completion(&info->fw_completion); | ||
841 | hci_h4p_set_clk(info, &info->tx_clocks_en, 1); | ||
842 | hci_h4p_set_clk(info, &info->rx_clocks_en, 1); | ||
843 | skb_queue_head_init(&fw_queue); | ||
844 | |||
845 | err = hci_h4p_reset(info); | ||
846 | if (err < 0) | ||
847 | goto err_clean; | ||
848 | |||
849 | hci_h4p_set_auto_ctsrts(info, 1, UART_EFR_CTS | UART_EFR_RTS); | ||
850 | info->autorts = 1; | ||
851 | |||
852 | err = hci_h4p_send_negotiation(info); | ||
853 | |||
854 | err = hci_h4p_read_fw(info, &fw_queue); | ||
855 | if (err < 0) { | ||
856 | dev_err(info->dev, "Cannot read firmware\n"); | ||
857 | goto err_clean; | ||
858 | } | ||
859 | |||
860 | err = hci_h4p_send_fw(info, &fw_queue); | ||
861 | if (err < 0) { | ||
862 | dev_err(info->dev, "Sending firmware failed.\n"); | ||
863 | goto err_clean; | ||
864 | } | ||
865 | |||
866 | info->pm_enabled = 1; | ||
867 | |||
868 | err = hci_h4p_bt_wakeup_test(info); | ||
869 | if (err < 0) { | ||
870 | dev_err(info->dev, "BT wakeup test failed.\n"); | ||
871 | goto err_clean; | ||
872 | } | ||
873 | |||
874 | spin_lock_irqsave(&info->lock, flags); | ||
875 | info->rx_enabled = gpio_get_value(info->host_wakeup_gpio); | ||
876 | hci_h4p_set_clk(info, &info->rx_clocks_en, info->rx_enabled); | ||
877 | spin_unlock_irqrestore(&info->lock, flags); | ||
878 | |||
879 | hci_h4p_set_clk(info, &info->tx_clocks_en, 0); | ||
880 | |||
881 | kfree_skb(info->alive_cmd_skb); | ||
882 | info->alive_cmd_skb = NULL; | ||
883 | set_bit(HCI_RUNNING, &hdev->flags); | ||
884 | |||
885 | BT_DBG("hci up and running"); | ||
886 | return 0; | ||
887 | |||
888 | err_clean: | ||
889 | hci_h4p_hci_flush(hdev); | ||
890 | hci_h4p_reset_uart(info); | ||
891 | del_timer_sync(&info->lazy_release); | ||
892 | hci_h4p_set_clk(info, &info->tx_clocks_en, 0); | ||
893 | hci_h4p_set_clk(info, &info->rx_clocks_en, 0); | ||
894 | gpio_set_value(info->reset_gpio, 0); | ||
895 | gpio_set_value(info->bt_wakeup_gpio, 0); | ||
896 | skb_queue_purge(&fw_queue); | ||
897 | kfree_skb(info->alive_cmd_skb); | ||
898 | info->alive_cmd_skb = NULL; | ||
899 | kfree_skb(info->rx_skb); | ||
900 | info->rx_skb = NULL; | ||
901 | |||
902 | if (retries++ < 3) { | ||
903 | dev_err(info->dev, "FW loading try %d fail. Retry.\n", retries); | ||
904 | goto again; | ||
905 | } | ||
906 | |||
907 | return err; | ||
908 | } | ||
909 | |||
910 | static int hci_h4p_hci_close(struct hci_dev *hdev) | ||
911 | { | ||
912 | struct hci_h4p_info *info = hci_get_drvdata(hdev); | ||
913 | |||
914 | if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)) | ||
915 | return 0; | ||
916 | |||
917 | hci_h4p_hci_flush(hdev); | ||
918 | hci_h4p_set_clk(info, &info->tx_clocks_en, 1); | ||
919 | hci_h4p_set_clk(info, &info->rx_clocks_en, 1); | ||
920 | hci_h4p_reset_uart(info); | ||
921 | del_timer_sync(&info->lazy_release); | ||
922 | hci_h4p_set_clk(info, &info->tx_clocks_en, 0); | ||
923 | hci_h4p_set_clk(info, &info->rx_clocks_en, 0); | ||
924 | gpio_set_value(info->reset_gpio, 0); | ||
925 | gpio_set_value(info->bt_wakeup_gpio, 0); | ||
926 | kfree_skb(info->rx_skb); | ||
927 | |||
928 | return 0; | ||
929 | } | ||
930 | |||
931 | static int hci_h4p_hci_send_frame(struct hci_dev *hdev, struct sk_buff *skb) | ||
932 | { | ||
933 | struct hci_h4p_info *info; | ||
934 | int err = 0; | ||
935 | |||
936 | BT_DBG("dev %p, skb %p", hdev, skb); | ||
937 | |||
938 | info = hci_get_drvdata(hdev); | ||
939 | |||
940 | if (!test_bit(HCI_RUNNING, &hdev->flags)) { | ||
941 | dev_warn(info->dev, "Frame for non-running device\n"); | ||
942 | return -EIO; | ||
943 | } | ||
944 | |||
945 | switch (bt_cb(skb)->pkt_type) { | ||
946 | case HCI_COMMAND_PKT: | ||
947 | hdev->stat.cmd_tx++; | ||
948 | break; | ||
949 | case HCI_ACLDATA_PKT: | ||
950 | hdev->stat.acl_tx++; | ||
951 | break; | ||
952 | case HCI_SCODATA_PKT: | ||
953 | hdev->stat.sco_tx++; | ||
954 | break; | ||
955 | } | ||
956 | |||
957 | /* Push frame type to skb */ | ||
958 | *skb_push(skb, 1) = (bt_cb(skb)->pkt_type); | ||
959 | /* We should allways send word aligned data to h4+ devices */ | ||
960 | if (skb->len % 2) { | ||
961 | err = skb_pad(skb, 1); | ||
962 | if (!err) | ||
963 | *skb_put(skb, 1) = 0x00; | ||
964 | } | ||
965 | if (err) | ||
966 | return err; | ||
967 | |||
968 | skb_queue_tail(&info->txq, skb); | ||
969 | hci_h4p_enable_tx(info); | ||
970 | |||
971 | return 0; | ||
972 | } | ||
973 | |||
974 | static ssize_t hci_h4p_store_bdaddr(struct device *dev, | ||
975 | struct device_attribute *attr, | ||
976 | const char *buf, size_t count) | ||
977 | { | ||
978 | struct hci_h4p_info *info = dev_get_drvdata(dev); | ||
979 | unsigned int bdaddr[6]; | ||
980 | int ret, i; | ||
981 | |||
982 | ret = sscanf(buf, "%2x:%2x:%2x:%2x:%2x:%2x\n", | ||
983 | &bdaddr[0], &bdaddr[1], &bdaddr[2], | ||
984 | &bdaddr[3], &bdaddr[4], &bdaddr[5]); | ||
985 | |||
986 | if (ret != 6) | ||
987 | return -EINVAL; | ||
988 | |||
989 | for (i = 0; i < 6; i++) { | ||
990 | if (bdaddr[i] > 0xff) | ||
991 | return -EINVAL; | ||
992 | info->bd_addr[i] = bdaddr[i] & 0xff; | ||
993 | } | ||
994 | |||
995 | return count; | ||
996 | } | ||
997 | |||
998 | static ssize_t hci_h4p_show_bdaddr(struct device *dev, | ||
999 | struct device_attribute *attr, char *buf) | ||
1000 | { | ||
1001 | struct hci_h4p_info *info = dev_get_drvdata(dev); | ||
1002 | |||
1003 | return sprintf(buf, "%pMR\n", info->bd_addr); | ||
1004 | } | ||
1005 | |||
1006 | static DEVICE_ATTR(bdaddr, S_IRUGO | S_IWUSR, hci_h4p_show_bdaddr, | ||
1007 | hci_h4p_store_bdaddr); | ||
1008 | |||
1009 | static int hci_h4p_sysfs_create_files(struct device *dev) | ||
1010 | { | ||
1011 | return device_create_file(dev, &dev_attr_bdaddr); | ||
1012 | } | ||
1013 | |||
1014 | static void hci_h4p_sysfs_remove_files(struct device *dev) | ||
1015 | { | ||
1016 | device_remove_file(dev, &dev_attr_bdaddr); | ||
1017 | } | ||
1018 | |||
1019 | static int hci_h4p_register_hdev(struct hci_h4p_info *info) | ||
1020 | { | ||
1021 | struct hci_dev *hdev; | ||
1022 | |||
1023 | /* Initialize and register HCI device */ | ||
1024 | |||
1025 | hdev = hci_alloc_dev(); | ||
1026 | if (!hdev) { | ||
1027 | dev_err(info->dev, "Can't allocate memory for device\n"); | ||
1028 | return -ENOMEM; | ||
1029 | } | ||
1030 | info->hdev = hdev; | ||
1031 | |||
1032 | hdev->bus = HCI_UART; | ||
1033 | hci_set_drvdata(hdev, info); | ||
1034 | |||
1035 | hdev->open = hci_h4p_hci_open; | ||
1036 | hdev->close = hci_h4p_hci_close; | ||
1037 | hdev->flush = hci_h4p_hci_flush; | ||
1038 | hdev->send = hci_h4p_hci_send_frame; | ||
1039 | set_bit(HCI_QUIRK_RESET_ON_CLOSE, &hdev->quirks); | ||
1040 | |||
1041 | SET_HCIDEV_DEV(hdev, info->dev); | ||
1042 | |||
1043 | if (hci_h4p_sysfs_create_files(info->dev) < 0) { | ||
1044 | dev_err(info->dev, "failed to create sysfs files\n"); | ||
1045 | goto free; | ||
1046 | } | ||
1047 | |||
1048 | if (hci_register_dev(hdev) >= 0) | ||
1049 | return 0; | ||
1050 | |||
1051 | dev_err(info->dev, "hci_register failed %s.\n", hdev->name); | ||
1052 | hci_h4p_sysfs_remove_files(info->dev); | ||
1053 | free: | ||
1054 | hci_free_dev(info->hdev); | ||
1055 | return -ENODEV; | ||
1056 | } | ||
1057 | |||
1058 | static int hci_h4p_probe(struct platform_device *pdev) | ||
1059 | { | ||
1060 | struct hci_h4p_platform_data *bt_plat_data; | ||
1061 | struct hci_h4p_info *info; | ||
1062 | int err; | ||
1063 | |||
1064 | dev_info(&pdev->dev, "Registering HCI H4P device\n"); | ||
1065 | info = devm_kzalloc(&pdev->dev, sizeof(struct hci_h4p_info), GFP_KERNEL); | ||
1066 | if (!info) | ||
1067 | return -ENOMEM; | ||
1068 | |||
1069 | info->dev = &pdev->dev; | ||
1070 | info->tx_enabled = 1; | ||
1071 | info->rx_enabled = 1; | ||
1072 | spin_lock_init(&info->lock); | ||
1073 | spin_lock_init(&info->clocks_lock); | ||
1074 | skb_queue_head_init(&info->txq); | ||
1075 | |||
1076 | if (pdev->dev.platform_data == NULL) { | ||
1077 | dev_err(&pdev->dev, "Could not get Bluetooth config data\n"); | ||
1078 | return -ENODATA; | ||
1079 | } | ||
1080 | |||
1081 | bt_plat_data = pdev->dev.platform_data; | ||
1082 | info->chip_type = bt_plat_data->chip_type; | ||
1083 | info->bt_wakeup_gpio = bt_plat_data->bt_wakeup_gpio; | ||
1084 | info->host_wakeup_gpio = bt_plat_data->host_wakeup_gpio; | ||
1085 | info->reset_gpio = bt_plat_data->reset_gpio; | ||
1086 | info->reset_gpio_shared = bt_plat_data->reset_gpio_shared; | ||
1087 | info->bt_sysclk = bt_plat_data->bt_sysclk; | ||
1088 | |||
1089 | BT_DBG("RESET gpio: %d", info->reset_gpio); | ||
1090 | BT_DBG("BTWU gpio: %d", info->bt_wakeup_gpio); | ||
1091 | BT_DBG("HOSTWU gpio: %d", info->host_wakeup_gpio); | ||
1092 | BT_DBG("sysclk: %d", info->bt_sysclk); | ||
1093 | |||
1094 | init_completion(&info->test_completion); | ||
1095 | complete_all(&info->test_completion); | ||
1096 | |||
1097 | if (!info->reset_gpio_shared) { | ||
1098 | err = devm_gpio_request_one(&pdev->dev, info->reset_gpio, | ||
1099 | GPIOF_OUT_INIT_LOW, "bt_reset"); | ||
1100 | if (err < 0) { | ||
1101 | dev_err(&pdev->dev, "Cannot get GPIO line %d\n", | ||
1102 | info->reset_gpio); | ||
1103 | return err; | ||
1104 | } | ||
1105 | } | ||
1106 | |||
1107 | err = devm_gpio_request_one(&pdev->dev, info->bt_wakeup_gpio, | ||
1108 | GPIOF_OUT_INIT_LOW, "bt_wakeup"); | ||
1109 | |||
1110 | if (err < 0) { | ||
1111 | dev_err(info->dev, "Cannot get GPIO line 0x%d", | ||
1112 | info->bt_wakeup_gpio); | ||
1113 | return err; | ||
1114 | } | ||
1115 | |||
1116 | err = devm_gpio_request_one(&pdev->dev, info->host_wakeup_gpio, | ||
1117 | GPIOF_DIR_IN, "host_wakeup"); | ||
1118 | if (err < 0) { | ||
1119 | dev_err(info->dev, "Cannot get GPIO line %d", | ||
1120 | info->host_wakeup_gpio); | ||
1121 | return err; | ||
1122 | } | ||
1123 | |||
1124 | info->irq = bt_plat_data->uart_irq; | ||
1125 | info->uart_base = devm_ioremap(&pdev->dev, bt_plat_data->uart_base, SZ_2K); | ||
1126 | info->uart_iclk = devm_clk_get(&pdev->dev, bt_plat_data->uart_iclk); | ||
1127 | info->uart_fclk = devm_clk_get(&pdev->dev, bt_plat_data->uart_fclk); | ||
1128 | |||
1129 | err = devm_request_irq(&pdev->dev, info->irq, hci_h4p_interrupt, IRQF_DISABLED, | ||
1130 | "hci_h4p", info); | ||
1131 | if (err < 0) { | ||
1132 | dev_err(info->dev, "hci_h4p: unable to get IRQ %d\n", info->irq); | ||
1133 | return err; | ||
1134 | } | ||
1135 | |||
1136 | err = devm_request_irq(&pdev->dev, gpio_to_irq(info->host_wakeup_gpio), | ||
1137 | hci_h4p_wakeup_interrupt, IRQF_TRIGGER_FALLING | | ||
1138 | IRQF_TRIGGER_RISING | IRQF_DISABLED, | ||
1139 | "hci_h4p_wkup", info); | ||
1140 | if (err < 0) { | ||
1141 | dev_err(info->dev, "hci_h4p: unable to get wakeup IRQ %d\n", | ||
1142 | gpio_to_irq(info->host_wakeup_gpio)); | ||
1143 | return err; | ||
1144 | } | ||
1145 | |||
1146 | err = irq_set_irq_wake(gpio_to_irq(info->host_wakeup_gpio), 1); | ||
1147 | if (err < 0) { | ||
1148 | dev_err(info->dev, "hci_h4p: unable to set wakeup for IRQ %d\n", | ||
1149 | gpio_to_irq(info->host_wakeup_gpio)); | ||
1150 | return err; | ||
1151 | } | ||
1152 | |||
1153 | init_timer_deferrable(&info->lazy_release); | ||
1154 | info->lazy_release.function = hci_h4p_lazy_clock_release; | ||
1155 | info->lazy_release.data = (unsigned long)info; | ||
1156 | hci_h4p_set_clk(info, &info->tx_clocks_en, 1); | ||
1157 | err = hci_h4p_reset_uart(info); | ||
1158 | if (err < 0) | ||
1159 | return err; | ||
1160 | gpio_set_value(info->reset_gpio, 0); | ||
1161 | hci_h4p_set_clk(info, &info->tx_clocks_en, 0); | ||
1162 | |||
1163 | platform_set_drvdata(pdev, info); | ||
1164 | |||
1165 | if (hci_h4p_register_hdev(info) < 0) { | ||
1166 | dev_err(info->dev, "failed to register hci_h4p hci device\n"); | ||
1167 | return -EINVAL; | ||
1168 | } | ||
1169 | |||
1170 | return 0; | ||
1171 | } | ||
1172 | |||
1173 | static int hci_h4p_remove(struct platform_device *pdev) | ||
1174 | { | ||
1175 | struct hci_h4p_info *info; | ||
1176 | |||
1177 | info = platform_get_drvdata(pdev); | ||
1178 | |||
1179 | hci_h4p_sysfs_remove_files(info->dev); | ||
1180 | hci_h4p_hci_close(info->hdev); | ||
1181 | hci_unregister_dev(info->hdev); | ||
1182 | hci_free_dev(info->hdev); | ||
1183 | |||
1184 | return 0; | ||
1185 | } | ||
1186 | |||
1187 | static struct platform_driver hci_h4p_driver = { | ||
1188 | .probe = hci_h4p_probe, | ||
1189 | .remove = hci_h4p_remove, | ||
1190 | .driver = { | ||
1191 | .name = "hci_h4p", | ||
1192 | }, | ||
1193 | }; | ||
1194 | |||
1195 | module_platform_driver(hci_h4p_driver); | ||
1196 | |||
1197 | MODULE_ALIAS("platform:hci_h4p"); | ||
1198 | MODULE_DESCRIPTION("Bluetooth h4 driver with nokia extensions"); | ||
1199 | MODULE_LICENSE("GPL"); | ||
1200 | MODULE_AUTHOR("Ville Tervo"); | ||
1201 | MODULE_FIRMWARE(FW_NAME_TI1271_PRELE); | ||
1202 | MODULE_FIRMWARE(FW_NAME_TI1271_LE); | ||
1203 | MODULE_FIRMWARE(FW_NAME_TI1271); | ||
1204 | MODULE_FIRMWARE(FW_NAME_BCM2048); | ||
1205 | MODULE_FIRMWARE(FW_NAME_CSR); | ||
diff --git a/drivers/staging/nokia_h4p/nokia_fw-bcm.c b/drivers/staging/nokia_h4p/nokia_fw-bcm.c new file mode 100644 index 000000000000..e8912bfc0a91 --- /dev/null +++ b/drivers/staging/nokia_h4p/nokia_fw-bcm.c | |||
@@ -0,0 +1,147 @@ | |||
1 | /* | ||
2 | * This file is part of Nokia H4P bluetooth driver | ||
3 | * | ||
4 | * Copyright (C) 2005-2008 Nokia Corporation. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * version 2 as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, but | ||
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
18 | * 02110-1301 USA | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #include <linux/skbuff.h> | ||
23 | #include <linux/delay.h> | ||
24 | #include <linux/serial_reg.h> | ||
25 | |||
26 | #include "hci_h4p.h" | ||
27 | |||
28 | static int hci_h4p_bcm_set_bdaddr(struct hci_h4p_info *info, struct sk_buff *skb) | ||
29 | { | ||
30 | int i; | ||
31 | static const u8 nokia_oui[3] = {0x00, 0x1f, 0xdf}; | ||
32 | int not_valid; | ||
33 | |||
34 | not_valid = 1; | ||
35 | for (i = 0; i < 6; i++) { | ||
36 | if (info->bd_addr[i] != 0x00) { | ||
37 | not_valid = 0; | ||
38 | break; | ||
39 | } | ||
40 | } | ||
41 | |||
42 | if (not_valid) { | ||
43 | dev_info(info->dev, "Valid bluetooth address not found, setting some random\n"); | ||
44 | /* When address is not valid, use some random but Nokia MAC */ | ||
45 | memcpy(info->bd_addr, nokia_oui, 3); | ||
46 | get_random_bytes(info->bd_addr + 3, 3); | ||
47 | } | ||
48 | |||
49 | for (i = 0; i < 6; i++) | ||
50 | skb->data[9 - i] = info->bd_addr[i]; | ||
51 | |||
52 | return 0; | ||
53 | } | ||
54 | |||
55 | void hci_h4p_bcm_parse_fw_event(struct hci_h4p_info *info, struct sk_buff *skb) | ||
56 | { | ||
57 | struct sk_buff *fw_skb; | ||
58 | int err; | ||
59 | unsigned long flags; | ||
60 | |||
61 | if (skb->data[5] != 0x00) { | ||
62 | dev_err(info->dev, "Firmware sending command failed 0x%.2x\n", | ||
63 | skb->data[5]); | ||
64 | info->fw_error = -EPROTO; | ||
65 | } | ||
66 | |||
67 | kfree_skb(skb); | ||
68 | |||
69 | fw_skb = skb_dequeue(info->fw_q); | ||
70 | if (fw_skb == NULL || info->fw_error) { | ||
71 | complete(&info->fw_completion); | ||
72 | return; | ||
73 | } | ||
74 | |||
75 | if (fw_skb->data[1] == 0x01 && fw_skb->data[2] == 0xfc && fw_skb->len >= 10) { | ||
76 | BT_DBG("Setting bluetooth address"); | ||
77 | err = hci_h4p_bcm_set_bdaddr(info, fw_skb); | ||
78 | if (err < 0) { | ||
79 | kfree_skb(fw_skb); | ||
80 | info->fw_error = err; | ||
81 | complete(&info->fw_completion); | ||
82 | return; | ||
83 | } | ||
84 | } | ||
85 | |||
86 | skb_queue_tail(&info->txq, fw_skb); | ||
87 | spin_lock_irqsave(&info->lock, flags); | ||
88 | hci_h4p_outb(info, UART_IER, hci_h4p_inb(info, UART_IER) | | ||
89 | UART_IER_THRI); | ||
90 | spin_unlock_irqrestore(&info->lock, flags); | ||
91 | } | ||
92 | |||
93 | |||
94 | int hci_h4p_bcm_send_fw(struct hci_h4p_info *info, | ||
95 | struct sk_buff_head *fw_queue) | ||
96 | { | ||
97 | struct sk_buff *skb; | ||
98 | unsigned long flags, time; | ||
99 | |||
100 | info->fw_error = 0; | ||
101 | |||
102 | BT_DBG("Sending firmware"); | ||
103 | |||
104 | time = jiffies; | ||
105 | |||
106 | info->fw_q = fw_queue; | ||
107 | skb = skb_dequeue(fw_queue); | ||
108 | if (!skb) | ||
109 | return -ENODATA; | ||
110 | |||
111 | BT_DBG("Sending commands"); | ||
112 | |||
113 | /* | ||
114 | * Disable smart-idle as UART TX interrupts | ||
115 | * are not wake-up capable | ||
116 | */ | ||
117 | hci_h4p_smart_idle(info, 0); | ||
118 | |||
119 | /* Check if this is bd_address packet */ | ||
120 | init_completion(&info->fw_completion); | ||
121 | skb_queue_tail(&info->txq, skb); | ||
122 | spin_lock_irqsave(&info->lock, flags); | ||
123 | hci_h4p_outb(info, UART_IER, hci_h4p_inb(info, UART_IER) | | ||
124 | UART_IER_THRI); | ||
125 | spin_unlock_irqrestore(&info->lock, flags); | ||
126 | |||
127 | if (!wait_for_completion_timeout(&info->fw_completion, | ||
128 | msecs_to_jiffies(2000))) { | ||
129 | dev_err(info->dev, "No reply to fw command\n"); | ||
130 | return -ETIMEDOUT; | ||
131 | } | ||
132 | |||
133 | if (info->fw_error) { | ||
134 | dev_err(info->dev, "FW error\n"); | ||
135 | return -EPROTO; | ||
136 | } | ||
137 | |||
138 | BT_DBG("Firmware sent in %d msecs", | ||
139 | jiffies_to_msecs(jiffies-time)); | ||
140 | |||
141 | hci_h4p_set_auto_ctsrts(info, 0, UART_EFR_RTS); | ||
142 | hci_h4p_set_rts(info, 0); | ||
143 | hci_h4p_change_speed(info, BC4_MAX_BAUD_RATE); | ||
144 | hci_h4p_set_auto_ctsrts(info, 1, UART_EFR_RTS); | ||
145 | |||
146 | return 0; | ||
147 | } | ||
diff --git a/drivers/staging/nokia_h4p/nokia_fw-csr.c b/drivers/staging/nokia_h4p/nokia_fw-csr.c new file mode 100644 index 000000000000..e39c4a31a879 --- /dev/null +++ b/drivers/staging/nokia_h4p/nokia_fw-csr.c | |||
@@ -0,0 +1,150 @@ | |||
1 | /* | ||
2 | * This file is part of Nokia H4P bluetooth driver | ||
3 | * | ||
4 | * Copyright (C) 2005-2008 Nokia Corporation. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * version 2 as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, but | ||
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
18 | * 02110-1301 USA | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #include <linux/skbuff.h> | ||
23 | #include <linux/delay.h> | ||
24 | #include <linux/serial_reg.h> | ||
25 | |||
26 | #include "hci_h4p.h" | ||
27 | |||
28 | void hci_h4p_bc4_parse_fw_event(struct hci_h4p_info *info, struct sk_buff *skb) | ||
29 | { | ||
30 | /* Check if this is fw packet */ | ||
31 | if (skb->data[0] != 0xff) { | ||
32 | hci_recv_frame(info->hdev, skb); | ||
33 | return; | ||
34 | } | ||
35 | |||
36 | if (skb->data[11] || skb->data[12]) { | ||
37 | dev_err(info->dev, "Firmware sending command failed\n"); | ||
38 | info->fw_error = -EPROTO; | ||
39 | } | ||
40 | |||
41 | kfree_skb(skb); | ||
42 | complete(&info->fw_completion); | ||
43 | } | ||
44 | |||
45 | int hci_h4p_bc4_send_fw(struct hci_h4p_info *info, | ||
46 | struct sk_buff_head *fw_queue) | ||
47 | { | ||
48 | static const u8 nokia_oui[3] = {0x00, 0x19, 0x4F}; | ||
49 | struct sk_buff *skb; | ||
50 | unsigned int offset; | ||
51 | int retries, count, i, not_valid; | ||
52 | unsigned long flags; | ||
53 | |||
54 | info->fw_error = 0; | ||
55 | |||
56 | BT_DBG("Sending firmware"); | ||
57 | skb = skb_dequeue(fw_queue); | ||
58 | |||
59 | if (!skb) | ||
60 | return -ENOMSG; | ||
61 | |||
62 | /* Check if this is bd_address packet */ | ||
63 | if (skb->data[15] == 0x01 && skb->data[16] == 0x00) { | ||
64 | offset = 21; | ||
65 | skb->data[offset + 1] = 0x00; | ||
66 | skb->data[offset + 5] = 0x00; | ||
67 | |||
68 | not_valid = 1; | ||
69 | for (i = 0; i < 6; i++) { | ||
70 | if (info->bd_addr[i] != 0x00) { | ||
71 | not_valid = 0; | ||
72 | break; | ||
73 | } | ||
74 | } | ||
75 | |||
76 | if (not_valid) { | ||
77 | dev_info(info->dev, "Valid bluetooth address not found," | ||
78 | " setting some random\n"); | ||
79 | /* When address is not valid, use some random */ | ||
80 | memcpy(info->bd_addr, nokia_oui, 3); | ||
81 | get_random_bytes(info->bd_addr + 3, 3); | ||
82 | } | ||
83 | |||
84 | skb->data[offset + 7] = info->bd_addr[0]; | ||
85 | skb->data[offset + 6] = info->bd_addr[1]; | ||
86 | skb->data[offset + 4] = info->bd_addr[2]; | ||
87 | skb->data[offset + 0] = info->bd_addr[3]; | ||
88 | skb->data[offset + 3] = info->bd_addr[4]; | ||
89 | skb->data[offset + 2] = info->bd_addr[5]; | ||
90 | } | ||
91 | |||
92 | for (count = 1; ; count++) { | ||
93 | BT_DBG("Sending firmware command %d", count); | ||
94 | init_completion(&info->fw_completion); | ||
95 | skb_queue_tail(&info->txq, skb); | ||
96 | spin_lock_irqsave(&info->lock, flags); | ||
97 | hci_h4p_outb(info, UART_IER, hci_h4p_inb(info, UART_IER) | | ||
98 | UART_IER_THRI); | ||
99 | spin_unlock_irqrestore(&info->lock, flags); | ||
100 | |||
101 | skb = skb_dequeue(fw_queue); | ||
102 | if (!skb) | ||
103 | break; | ||
104 | |||
105 | if (!wait_for_completion_timeout(&info->fw_completion, | ||
106 | msecs_to_jiffies(1000))) { | ||
107 | dev_err(info->dev, "No reply to fw command\n"); | ||
108 | return -ETIMEDOUT; | ||
109 | } | ||
110 | |||
111 | if (info->fw_error) { | ||
112 | dev_err(info->dev, "FW error\n"); | ||
113 | return -EPROTO; | ||
114 | } | ||
115 | }; | ||
116 | |||
117 | /* Wait for chip warm reset */ | ||
118 | retries = 100; | ||
119 | while ((!skb_queue_empty(&info->txq) || | ||
120 | !(hci_h4p_inb(info, UART_LSR) & UART_LSR_TEMT)) && | ||
121 | retries--) { | ||
122 | msleep(10); | ||
123 | } | ||
124 | if (!retries) { | ||
125 | dev_err(info->dev, "Transmitter not empty\n"); | ||
126 | return -ETIMEDOUT; | ||
127 | } | ||
128 | |||
129 | hci_h4p_change_speed(info, BC4_MAX_BAUD_RATE); | ||
130 | |||
131 | if (hci_h4p_wait_for_cts(info, 1, 100)) { | ||
132 | dev_err(info->dev, "cts didn't deassert after final speed\n"); | ||
133 | return -ETIMEDOUT; | ||
134 | } | ||
135 | |||
136 | retries = 100; | ||
137 | do { | ||
138 | init_completion(&info->init_completion); | ||
139 | hci_h4p_send_alive_packet(info); | ||
140 | retries--; | ||
141 | } while (!wait_for_completion_timeout(&info->init_completion, 100) && | ||
142 | retries > 0); | ||
143 | |||
144 | if (!retries) { | ||
145 | dev_err(info->dev, "No alive reply after speed change\n"); | ||
146 | return -ETIMEDOUT; | ||
147 | } | ||
148 | |||
149 | return 0; | ||
150 | } | ||
diff --git a/drivers/staging/nokia_h4p/nokia_fw-ti1273.c b/drivers/staging/nokia_h4p/nokia_fw-ti1273.c new file mode 100644 index 000000000000..f5500f71c839 --- /dev/null +++ b/drivers/staging/nokia_h4p/nokia_fw-ti1273.c | |||
@@ -0,0 +1,110 @@ | |||
1 | /* | ||
2 | * This file is part of Nokia H4P bluetooth driver | ||
3 | * | ||
4 | * Copyright (C) 2009 Nokia Corporation. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * version 2 as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, but | ||
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
18 | * 02110-1301 USA | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #include <linux/skbuff.h> | ||
23 | #include <linux/delay.h> | ||
24 | #include <linux/serial_reg.h> | ||
25 | |||
26 | #include "hci_h4p.h" | ||
27 | |||
28 | static struct sk_buff_head *fw_q; | ||
29 | |||
30 | void hci_h4p_ti1273_parse_fw_event(struct hci_h4p_info *info, | ||
31 | struct sk_buff *skb) | ||
32 | { | ||
33 | struct sk_buff *fw_skb; | ||
34 | unsigned long flags; | ||
35 | |||
36 | if (skb->data[5] != 0x00) { | ||
37 | dev_err(info->dev, "Firmware sending command failed 0x%.2x\n", | ||
38 | skb->data[5]); | ||
39 | info->fw_error = -EPROTO; | ||
40 | } | ||
41 | |||
42 | kfree_skb(skb); | ||
43 | |||
44 | fw_skb = skb_dequeue(fw_q); | ||
45 | if (fw_skb == NULL || info->fw_error) { | ||
46 | complete(&info->fw_completion); | ||
47 | return; | ||
48 | } | ||
49 | |||
50 | skb_queue_tail(&info->txq, fw_skb); | ||
51 | spin_lock_irqsave(&info->lock, flags); | ||
52 | hci_h4p_outb(info, UART_IER, hci_h4p_inb(info, UART_IER) | | ||
53 | UART_IER_THRI); | ||
54 | spin_unlock_irqrestore(&info->lock, flags); | ||
55 | } | ||
56 | |||
57 | |||
58 | int hci_h4p_ti1273_send_fw(struct hci_h4p_info *info, | ||
59 | struct sk_buff_head *fw_queue) | ||
60 | { | ||
61 | struct sk_buff *skb; | ||
62 | unsigned long flags, time; | ||
63 | |||
64 | info->fw_error = 0; | ||
65 | |||
66 | BT_DBG("Sending firmware"); | ||
67 | |||
68 | time = jiffies; | ||
69 | |||
70 | fw_q = fw_queue; | ||
71 | skb = skb_dequeue(fw_queue); | ||
72 | if (!skb) | ||
73 | return -ENODATA; | ||
74 | |||
75 | BT_DBG("Sending commands"); | ||
76 | /* Check if this is bd_address packet */ | ||
77 | init_completion(&info->fw_completion); | ||
78 | hci_h4p_smart_idle(info, 0); | ||
79 | skb_queue_tail(&info->txq, skb); | ||
80 | spin_lock_irqsave(&info->lock, flags); | ||
81 | hci_h4p_outb(info, UART_IER, hci_h4p_inb(info, UART_IER) | | ||
82 | UART_IER_THRI); | ||
83 | spin_unlock_irqrestore(&info->lock, flags); | ||
84 | |||
85 | if (!wait_for_completion_timeout(&info->fw_completion, | ||
86 | msecs_to_jiffies(2000))) { | ||
87 | dev_err(info->dev, "No reply to fw command\n"); | ||
88 | return -ETIMEDOUT; | ||
89 | } | ||
90 | |||
91 | if (info->fw_error) { | ||
92 | dev_err(info->dev, "FW error\n"); | ||
93 | return -EPROTO; | ||
94 | } | ||
95 | |||
96 | BT_DBG("Firmware sent in %d msecs", | ||
97 | jiffies_to_msecs(jiffies-time)); | ||
98 | |||
99 | hci_h4p_set_auto_ctsrts(info, 0, UART_EFR_RTS); | ||
100 | hci_h4p_set_rts(info, 0); | ||
101 | hci_h4p_change_speed(info, BC4_MAX_BAUD_RATE); | ||
102 | if (hci_h4p_wait_for_cts(info, 1, 100)) { | ||
103 | dev_err(info->dev, | ||
104 | "cts didn't go down after final speed change\n"); | ||
105 | return -ETIMEDOUT; | ||
106 | } | ||
107 | hci_h4p_set_auto_ctsrts(info, 1, UART_EFR_RTS); | ||
108 | |||
109 | return 0; | ||
110 | } | ||
diff --git a/drivers/staging/nokia_h4p/nokia_fw.c b/drivers/staging/nokia_h4p/nokia_fw.c new file mode 100644 index 000000000000..cfea61cd59e9 --- /dev/null +++ b/drivers/staging/nokia_h4p/nokia_fw.c | |||
@@ -0,0 +1,195 @@ | |||
1 | /* | ||
2 | * This file is part of hci_h4p bluetooth driver | ||
3 | * | ||
4 | * Copyright (C) 2005, 2006 Nokia Corporation. | ||
5 | * | ||
6 | * Contact: Ville Tervo <ville.tervo@nokia.com> | ||
7 | * | ||
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. | ||
11 | * | ||
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. | ||
16 | * | ||
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 | ||
20 | * 02110-1301 USA | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | #include <linux/skbuff.h> | ||
25 | #include <linux/firmware.h> | ||
26 | #include <linux/clk.h> | ||
27 | |||
28 | #include <net/bluetooth/bluetooth.h> | ||
29 | |||
30 | #include "hci_h4p.h" | ||
31 | |||
32 | static int fw_pos; | ||
33 | |||
34 | /* Firmware handling */ | ||
35 | static int hci_h4p_open_firmware(struct hci_h4p_info *info, | ||
36 | const struct firmware **fw_entry) | ||
37 | { | ||
38 | int err; | ||
39 | |||
40 | fw_pos = 0; | ||
41 | BT_DBG("Opening firmware man_id 0x%.2x ver_id 0x%.2x", | ||
42 | info->man_id, info->ver_id); | ||
43 | switch (info->man_id) { | ||
44 | case H4P_ID_TI1271: | ||
45 | switch (info->ver_id) { | ||
46 | case 0xe1: | ||
47 | err = request_firmware(fw_entry, FW_NAME_TI1271_PRELE, | ||
48 | info->dev); | ||
49 | break; | ||
50 | case 0xd1: | ||
51 | case 0xf1: | ||
52 | err = request_firmware(fw_entry, FW_NAME_TI1271_LE, | ||
53 | info->dev); | ||
54 | break; | ||
55 | default: | ||
56 | err = request_firmware(fw_entry, FW_NAME_TI1271, | ||
57 | info->dev); | ||
58 | } | ||
59 | break; | ||
60 | case H4P_ID_CSR: | ||
61 | err = request_firmware(fw_entry, FW_NAME_CSR, info->dev); | ||
62 | break; | ||
63 | case H4P_ID_BCM2048: | ||
64 | err = request_firmware(fw_entry, FW_NAME_BCM2048, info->dev); | ||
65 | break; | ||
66 | default: | ||
67 | dev_err(info->dev, "Invalid chip type\n"); | ||
68 | *fw_entry = NULL; | ||
69 | err = -EINVAL; | ||
70 | } | ||
71 | |||
72 | return err; | ||
73 | } | ||
74 | |||
75 | static void hci_h4p_close_firmware(const struct firmware *fw_entry) | ||
76 | { | ||
77 | release_firmware(fw_entry); | ||
78 | } | ||
79 | |||
80 | /* Read fw. Return length of the command. If no more commands in | ||
81 | * fw 0 is returned. In error case return value is negative. | ||
82 | */ | ||
83 | static int hci_h4p_read_fw_cmd(struct hci_h4p_info *info, struct sk_buff **skb, | ||
84 | const struct firmware *fw_entry, gfp_t how) | ||
85 | { | ||
86 | unsigned int cmd_len; | ||
87 | |||
88 | if (fw_pos >= fw_entry->size) | ||
89 | return 0; | ||
90 | |||
91 | if (fw_pos + 2 > fw_entry->size) { | ||
92 | dev_err(info->dev, "Corrupted firmware image 1\n"); | ||
93 | return -EMSGSIZE; | ||
94 | } | ||
95 | |||
96 | cmd_len = fw_entry->data[fw_pos++]; | ||
97 | cmd_len += fw_entry->data[fw_pos++] << 8; | ||
98 | if (cmd_len == 0) | ||
99 | return 0; | ||
100 | |||
101 | if (fw_pos + cmd_len > fw_entry->size) { | ||
102 | dev_err(info->dev, "Corrupted firmware image 2\n"); | ||
103 | return -EMSGSIZE; | ||
104 | } | ||
105 | |||
106 | *skb = bt_skb_alloc(cmd_len, how); | ||
107 | if (!*skb) { | ||
108 | dev_err(info->dev, "Cannot reserve memory for buffer\n"); | ||
109 | return -ENOMEM; | ||
110 | } | ||
111 | memcpy(skb_put(*skb, cmd_len), &fw_entry->data[fw_pos], cmd_len); | ||
112 | |||
113 | fw_pos += cmd_len; | ||
114 | |||
115 | return (*skb)->len; | ||
116 | } | ||
117 | |||
118 | int hci_h4p_read_fw(struct hci_h4p_info *info, struct sk_buff_head *fw_queue) | ||
119 | { | ||
120 | const struct firmware *fw_entry = NULL; | ||
121 | struct sk_buff *skb = NULL; | ||
122 | int err; | ||
123 | |||
124 | err = hci_h4p_open_firmware(info, &fw_entry); | ||
125 | if (err < 0 || !fw_entry) | ||
126 | goto err_clean; | ||
127 | |||
128 | while ((err = hci_h4p_read_fw_cmd(info, &skb, fw_entry, GFP_KERNEL))) { | ||
129 | if (err < 0 || !skb) | ||
130 | goto err_clean; | ||
131 | |||
132 | skb_queue_tail(fw_queue, skb); | ||
133 | } | ||
134 | |||
135 | /* Chip detection code does neg and alive stuff | ||
136 | * discard two first skbs */ | ||
137 | skb = skb_dequeue(fw_queue); | ||
138 | if (!skb) { | ||
139 | err = -EMSGSIZE; | ||
140 | goto err_clean; | ||
141 | } | ||
142 | kfree_skb(skb); | ||
143 | skb = skb_dequeue(fw_queue); | ||
144 | if (!skb) { | ||
145 | err = -EMSGSIZE; | ||
146 | goto err_clean; | ||
147 | } | ||
148 | kfree_skb(skb); | ||
149 | |||
150 | err_clean: | ||
151 | hci_h4p_close_firmware(fw_entry); | ||
152 | return err; | ||
153 | } | ||
154 | |||
155 | int hci_h4p_send_fw(struct hci_h4p_info *info, struct sk_buff_head *fw_queue) | ||
156 | { | ||
157 | int err; | ||
158 | |||
159 | switch (info->man_id) { | ||
160 | case H4P_ID_CSR: | ||
161 | err = hci_h4p_bc4_send_fw(info, fw_queue); | ||
162 | break; | ||
163 | case H4P_ID_TI1271: | ||
164 | err = hci_h4p_ti1273_send_fw(info, fw_queue); | ||
165 | break; | ||
166 | case H4P_ID_BCM2048: | ||
167 | err = hci_h4p_bcm_send_fw(info, fw_queue); | ||
168 | break; | ||
169 | default: | ||
170 | dev_err(info->dev, "Don't know how to send firmware\n"); | ||
171 | err = -EINVAL; | ||
172 | } | ||
173 | |||
174 | return err; | ||
175 | } | ||
176 | |||
177 | void hci_h4p_parse_fw_event(struct hci_h4p_info *info, struct sk_buff *skb) | ||
178 | { | ||
179 | switch (info->man_id) { | ||
180 | case H4P_ID_CSR: | ||
181 | hci_h4p_bc4_parse_fw_event(info, skb); | ||
182 | break; | ||
183 | case H4P_ID_TI1271: | ||
184 | hci_h4p_ti1273_parse_fw_event(info, skb); | ||
185 | break; | ||
186 | case H4P_ID_BCM2048: | ||
187 | hci_h4p_bcm_parse_fw_event(info, skb); | ||
188 | break; | ||
189 | default: | ||
190 | dev_err(info->dev, "Don't know how to parse fw event\n"); | ||
191 | info->fw_error = -EINVAL; | ||
192 | } | ||
193 | |||
194 | return; | ||
195 | } | ||
diff --git a/drivers/staging/nokia_h4p/nokia_uart.c b/drivers/staging/nokia_h4p/nokia_uart.c new file mode 100644 index 000000000000..0fb57de4b750 --- /dev/null +++ b/drivers/staging/nokia_h4p/nokia_uart.c | |||
@@ -0,0 +1,199 @@ | |||
1 | /* | ||
2 | * This file is part of Nokia H4P bluetooth driver | ||
3 | * | ||
4 | * Copyright (C) 2005, 2006 Nokia Corporation. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * version 2 as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, but | ||
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
18 | * 02110-1301 USA | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | #include <linux/serial_reg.h> | ||
23 | #include <linux/delay.h> | ||
24 | #include <linux/clk.h> | ||
25 | |||
26 | #include <linux/io.h> | ||
27 | |||
28 | #include "hci_h4p.h" | ||
29 | |||
30 | inline void hci_h4p_outb(struct hci_h4p_info *info, unsigned int offset, u8 val) | ||
31 | { | ||
32 | __raw_writeb(val, info->uart_base + (offset << 2)); | ||
33 | } | ||
34 | |||
35 | inline u8 hci_h4p_inb(struct hci_h4p_info *info, unsigned int offset) | ||
36 | { | ||
37 | return __raw_readb(info->uart_base + (offset << 2)); | ||
38 | } | ||
39 | |||
40 | void hci_h4p_set_rts(struct hci_h4p_info *info, int active) | ||
41 | { | ||
42 | u8 b; | ||
43 | |||
44 | b = hci_h4p_inb(info, UART_MCR); | ||
45 | if (active) | ||
46 | b |= UART_MCR_RTS; | ||
47 | else | ||
48 | b &= ~UART_MCR_RTS; | ||
49 | hci_h4p_outb(info, UART_MCR, b); | ||
50 | } | ||
51 | |||
52 | int hci_h4p_wait_for_cts(struct hci_h4p_info *info, int active, | ||
53 | int timeout_ms) | ||
54 | { | ||
55 | unsigned long timeout; | ||
56 | int state; | ||
57 | |||
58 | timeout = jiffies + msecs_to_jiffies(timeout_ms); | ||
59 | for (;;) { | ||
60 | state = hci_h4p_inb(info, UART_MSR) & UART_MSR_CTS; | ||
61 | if (active) { | ||
62 | if (state) | ||
63 | return 0; | ||
64 | } else { | ||
65 | if (!state) | ||
66 | return 0; | ||
67 | } | ||
68 | if (time_after(jiffies, timeout)) | ||
69 | return -ETIMEDOUT; | ||
70 | msleep(1); | ||
71 | } | ||
72 | } | ||
73 | |||
74 | void __hci_h4p_set_auto_ctsrts(struct hci_h4p_info *info, int on, u8 which) | ||
75 | { | ||
76 | u8 lcr, b; | ||
77 | |||
78 | lcr = hci_h4p_inb(info, UART_LCR); | ||
79 | hci_h4p_outb(info, UART_LCR, 0xbf); | ||
80 | b = hci_h4p_inb(info, UART_EFR); | ||
81 | if (on) | ||
82 | b |= which; | ||
83 | else | ||
84 | b &= ~which; | ||
85 | hci_h4p_outb(info, UART_EFR, b); | ||
86 | hci_h4p_outb(info, UART_LCR, lcr); | ||
87 | } | ||
88 | |||
89 | void hci_h4p_set_auto_ctsrts(struct hci_h4p_info *info, int on, u8 which) | ||
90 | { | ||
91 | unsigned long flags; | ||
92 | |||
93 | spin_lock_irqsave(&info->lock, flags); | ||
94 | __hci_h4p_set_auto_ctsrts(info, on, which); | ||
95 | spin_unlock_irqrestore(&info->lock, flags); | ||
96 | } | ||
97 | |||
98 | void hci_h4p_change_speed(struct hci_h4p_info *info, unsigned long speed) | ||
99 | { | ||
100 | unsigned int divisor; | ||
101 | u8 lcr, mdr1; | ||
102 | |||
103 | BT_DBG("Setting speed %lu", speed); | ||
104 | |||
105 | if (speed >= 460800) { | ||
106 | divisor = UART_CLOCK / 13 / speed; | ||
107 | mdr1 = 3; | ||
108 | } else { | ||
109 | divisor = UART_CLOCK / 16 / speed; | ||
110 | mdr1 = 0; | ||
111 | } | ||
112 | |||
113 | /* Make sure UART mode is disabled */ | ||
114 | hci_h4p_outb(info, UART_OMAP_MDR1, 7); | ||
115 | |||
116 | lcr = hci_h4p_inb(info, UART_LCR); | ||
117 | hci_h4p_outb(info, UART_LCR, UART_LCR_DLAB); /* Set DLAB */ | ||
118 | hci_h4p_outb(info, UART_DLL, divisor & 0xff); /* Set speed */ | ||
119 | hci_h4p_outb(info, UART_DLM, divisor >> 8); | ||
120 | hci_h4p_outb(info, UART_LCR, lcr); | ||
121 | |||
122 | /* Make sure UART mode is enabled */ | ||
123 | hci_h4p_outb(info, UART_OMAP_MDR1, mdr1); | ||
124 | } | ||
125 | |||
126 | int hci_h4p_reset_uart(struct hci_h4p_info *info) | ||
127 | { | ||
128 | int count = 0; | ||
129 | |||
130 | /* Reset the UART */ | ||
131 | hci_h4p_outb(info, UART_OMAP_SYSC, UART_SYSC_OMAP_RESET); | ||
132 | while (!(hci_h4p_inb(info, UART_OMAP_SYSS) & UART_SYSS_RESETDONE)) { | ||
133 | if (count++ > 100) { | ||
134 | dev_err(info->dev, "hci_h4p: UART reset timeout\n"); | ||
135 | return -ENODEV; | ||
136 | } | ||
137 | udelay(1); | ||
138 | } | ||
139 | |||
140 | return 0; | ||
141 | } | ||
142 | |||
143 | void hci_h4p_store_regs(struct hci_h4p_info *info) | ||
144 | { | ||
145 | u16 lcr = 0; | ||
146 | |||
147 | lcr = hci_h4p_inb(info, UART_LCR); | ||
148 | hci_h4p_outb(info, UART_LCR, 0xBF); | ||
149 | info->dll = hci_h4p_inb(info, UART_DLL); | ||
150 | info->dlh = hci_h4p_inb(info, UART_DLM); | ||
151 | info->efr = hci_h4p_inb(info, UART_EFR); | ||
152 | hci_h4p_outb(info, UART_LCR, lcr); | ||
153 | info->mdr1 = hci_h4p_inb(info, UART_OMAP_MDR1); | ||
154 | info->ier = hci_h4p_inb(info, UART_IER); | ||
155 | } | ||
156 | |||
157 | void hci_h4p_restore_regs(struct hci_h4p_info *info) | ||
158 | { | ||
159 | u16 lcr = 0; | ||
160 | |||
161 | hci_h4p_init_uart(info); | ||
162 | |||
163 | hci_h4p_outb(info, UART_OMAP_MDR1, 7); | ||
164 | lcr = hci_h4p_inb(info, UART_LCR); | ||
165 | hci_h4p_outb(info, UART_LCR, 0xBF); | ||
166 | hci_h4p_outb(info, UART_DLL, info->dll); /* Set speed */ | ||
167 | hci_h4p_outb(info, UART_DLM, info->dlh); | ||
168 | hci_h4p_outb(info, UART_EFR, info->efr); | ||
169 | hci_h4p_outb(info, UART_LCR, lcr); | ||
170 | hci_h4p_outb(info, UART_OMAP_MDR1, info->mdr1); | ||
171 | hci_h4p_outb(info, UART_IER, info->ier); | ||
172 | } | ||
173 | |||
174 | void hci_h4p_init_uart(struct hci_h4p_info *info) | ||
175 | { | ||
176 | u8 mcr, efr; | ||
177 | |||
178 | /* Enable and setup FIFO */ | ||
179 | hci_h4p_outb(info, UART_OMAP_MDR1, 0x00); | ||
180 | |||
181 | hci_h4p_outb(info, UART_LCR, 0xbf); | ||
182 | efr = hci_h4p_inb(info, UART_EFR); | ||
183 | hci_h4p_outb(info, UART_EFR, UART_EFR_ECB); | ||
184 | hci_h4p_outb(info, UART_LCR, UART_LCR_DLAB); | ||
185 | mcr = hci_h4p_inb(info, UART_MCR); | ||
186 | hci_h4p_outb(info, UART_MCR, UART_MCR_TCRTLR); | ||
187 | hci_h4p_outb(info, UART_FCR, UART_FCR_ENABLE_FIFO | | ||
188 | UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT | | ||
189 | (3 << 6) | (0 << 4)); | ||
190 | hci_h4p_outb(info, UART_LCR, 0xbf); | ||
191 | hci_h4p_outb(info, UART_TI752_TLR, 0xed); | ||
192 | hci_h4p_outb(info, UART_TI752_TCR, 0xef); | ||
193 | hci_h4p_outb(info, UART_EFR, efr); | ||
194 | hci_h4p_outb(info, UART_LCR, UART_LCR_DLAB); | ||
195 | hci_h4p_outb(info, UART_MCR, 0x00); | ||
196 | hci_h4p_outb(info, UART_LCR, UART_LCR_WLEN8); | ||
197 | hci_h4p_outb(info, UART_IER, UART_IER_RDI); | ||
198 | hci_h4p_outb(info, UART_OMAP_SYSC, (1 << 0) | (1 << 2) | (2 << 3)); | ||
199 | } | ||
diff --git a/include/linux/platform_data/bt-nokia-h4p.h b/include/linux/platform_data/bt-nokia-h4p.h new file mode 100644 index 000000000000..30d169dfadf3 --- /dev/null +++ b/include/linux/platform_data/bt-nokia-h4p.h | |||
@@ -0,0 +1,38 @@ | |||
1 | /* | ||
2 | * This file is part of Nokia H4P bluetooth driver | ||
3 | * | ||
4 | * Copyright (C) 2010 Nokia Corporation. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * version 2 as published by the Free Software Foundation. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, but | ||
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | * General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
18 | * 02110-1301 USA | ||
19 | * | ||
20 | */ | ||
21 | |||
22 | |||
23 | /** | ||
24 | * struct hci_h4p_platform data - hci_h4p Platform data structure | ||
25 | */ | ||
26 | struct hci_h4p_platform_data { | ||
27 | int chip_type; | ||
28 | int bt_sysclk; | ||
29 | unsigned int bt_wakeup_gpio; | ||
30 | unsigned int host_wakeup_gpio; | ||
31 | unsigned int reset_gpio; | ||
32 | int reset_gpio_shared; | ||
33 | unsigned int uart_irq; | ||
34 | phys_addr_t uart_base; | ||
35 | const char *uart_iclk; | ||
36 | const char *uart_fclk; | ||
37 | void (*set_pm_limits)(struct device *dev, bool set); | ||
38 | }; | ||