summaryrefslogtreecommitdiffstats
path: root/drivers/staging/nokia_h4p/hci_h4p.h
blob: 99c4da61a56c5295b1dc7e92e8adad1a18d0a0f2 (plain)
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
32
33
34
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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
/*
 * This file is part of Nokia H4P bluetooth driver
 *
 * Copyright (C) 2005-2008 Nokia Corporation.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * version 2 as published by the Free Software Foundation.
 *
 * 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; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 *
 */

#ifndef __DRIVERS_BLUETOOTH_HCI_H4P_H
#define __DRIVERS_BLUETOOTH_HCI_H4P_H

#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/hci.h>

#define UART_SYSC_OMAP_RESET	0x03
#define UART_SYSS_RESETDONE	0x01
#define UART_OMAP_SCR_EMPTY_THR	0x08
#define UART_OMAP_SCR_WAKEUP	0x10
#define UART_OMAP_SSR_WAKEUP	0x02
#define UART_OMAP_SSR_TXFULL	0x01

#define UART_OMAP_SYSC_IDLEMODE		0x03
#define UART_OMAP_SYSC_IDLEMASK		(3 << UART_OMAP_SYSC_IDLEMODE)

#define UART_OMAP_SYSC_FORCE_IDLE	(0 << UART_OMAP_SYSC_IDLEMODE)
#define UART_OMAP_SYSC_NO_IDLE		(1 << UART_OMAP_SYSC_IDLEMODE)
#define UART_OMAP_SYSC_SMART_IDLE	(2 << UART_OMAP_SYSC_IDLEMODE)

#define H4P_TRANSFER_MODE		1
#define H4P_SCHED_TRANSFER_MODE		2
#define H4P_ACTIVE_MODE			3

struct hci_h4p_info {
	struct timer_list lazy_release;
	struct hci_dev *hdev;
	spinlock_t lock;

	void __iomem *uart_base;
	unsigned long uart_phys_base;
	int irq;
	struct device *dev;
	u8 chip_type;
	u8 bt_wakeup_gpio;
	u8 host_wakeup_gpio;
	u8 reset_gpio;
	u8 reset_gpio_shared;
	u8 bt_sysclk;
	u8 man_id;
	u8 ver_id;

	struct sk_buff_head fw_queue;
	struct sk_buff *alive_cmd_skb;
	struct completion init_completion;
	struct completion fw_completion;
	struct completion test_completion;
	int fw_error;
	int init_error;

	struct sk_buff_head txq;

	struct sk_buff *rx_skb;
	long rx_count;
	unsigned long rx_state;
	unsigned long garbage_bytes;

	u8 bd_addr[6];
	struct sk_buff_head *fw_q;

	int pm_enabled;
	int tx_enabled;
	int autorts;
	int rx_enabled;
	unsigned long pm_flags;

	int tx_clocks_en;
	int rx_clocks_en;
	spinlock_t clocks_lock;
	struct clk *uart_iclk;
	struct clk *uart_fclk;
	atomic_t clk_users;
	u16 dll;
	u16 dlh;
	u16 ier;
	u16 mdr1;
	u16 efr;
};

struct hci_h4p_radio_hdr {
	__u8 evt;
	__u8 dlen;
} __packed;

struct hci_h4p_neg_hdr {
	__u8 dlen;
} __packed;
#define H4P_NEG_HDR_SIZE 1

#define H4P_NEG_REQ	0x00
#define H4P_NEG_ACK	0x20
#define H4P_NEG_NAK	0x40

#define H4P_PROTO_PKT	0x44
#define H4P_PROTO_BYTE	0x4c

#define H4P_ID_CSR	0x02
#define H4P_ID_BCM2048	0x04
#define H4P_ID_TI1271	0x31

struct hci_h4p_neg_cmd {
	__u8	ack;
	__u16	baud;
	__u16	unused1;
	__u8	proto;
	__u16	sys_clk;
	__u16	unused2;
} __packed;

struct hci_h4p_neg_evt {
	__u8	ack;
	__u16	baud;
	__u16	unused1;
	__u8	proto;
	__u16	sys_clk;
	__u16	unused2;
	__u8	man_id;
	__u8	ver_id;
} __packed;

#define H4P_ALIVE_REQ	0x55
#define H4P_ALIVE_RESP	0xcc

struct hci_h4p_alive_hdr {
	__u8	dlen;
} __packed;
#define H4P_ALIVE_HDR_SIZE 1

struct hci_h4p_alive_pkt {
	__u8	mid;
	__u8	unused;
} __packed;

#define MAX_BAUD_RATE		921600
#define BC4_MAX_BAUD_RATE	3692300
#define UART_CLOCK		48000000
#define BT_INIT_DIVIDER		320
#define BT_BAUDRATE_DIVIDER	384000000
#define BT_SYSCLK_DIV		1000
#define INIT_SPEED		120000

#define H4_TYPE_SIZE		1
#define H4_RADIO_HDR_SIZE	2

/* H4+ packet types */
#define H4_CMD_PKT		0x01
#define H4_ACL_PKT		0x02
#define H4_SCO_PKT		0x03
#define H4_EVT_PKT		0x04
#define H4_NEG_PKT		0x06
#define H4_ALIVE_PKT		0x07
#define H4_RADIO_PKT		0x08

/* TX states */
#define WAIT_FOR_PKT_TYPE	1
#define WAIT_FOR_HEADER		2
#define WAIT_FOR_DATA		3

struct hci_fw_event {
	struct hci_event_hdr hev;
	struct hci_ev_cmd_complete cmd;
	u8 status;
} __packed;

int hci_h4p_send_alive_packet(struct hci_h4p_info *info);

void hci_h4p_bcm_parse_fw_event(struct hci_h4p_info *info,
				struct sk_buff *skb);
int hci_h4p_bcm_send_fw(struct hci_h4p_info *info,
			struct sk_buff_head *fw_queue);

void hci_h4p_bc4_parse_fw_event(struct hci_h4p_info *info,
				struct sk_buff *skb);
int hci_h4p_bc4_send_fw(struct hci_h4p_info *info,
			struct sk_buff_head *fw_queue);

void hci_h4p_ti1273_parse_fw_event(struct hci_h4p_info *info,
				    struct sk_buff *skb);
int hci_h4p_ti1273_send_fw(struct hci_h4p_info *info,
			    struct sk_buff_head *fw_queue);

int hci_h4p_read_fw(struct hci_h4p_info *info, struct sk_buff_head *fw_queue);
int hci_h4p_send_fw(struct hci_h4p_info *info, struct sk_buff_head *fw_queue);
void hci_h4p_parse_fw_event(struct hci_h4p_info *info, struct sk_buff *skb);

void hci_h4p_outb(struct hci_h4p_info *info, unsigned int offset, u8 val);
u8 hci_h4p_inb(struct hci_h4p_info *info, unsigned int offset);
void hci_h4p_set_rts(struct hci_h4p_info *info, int active);
int hci_h4p_wait_for_cts(struct hci_h4p_info *info, int active, int timeout_ms);
void __hci_h4p_set_auto_ctsrts(struct hci_h4p_info *info, int on, u8 which);
void hci_h4p_set_auto_ctsrts(struct hci_h4p_info *info, int on, u8 which);
void hci_h4p_change_speed(struct hci_h4p_info *info, unsigned long speed);
int hci_h4p_reset_uart(struct hci_h4p_info *info);
void hci_h4p_init_uart(struct hci_h4p_info *info);
void hci_h4p_enable_tx(struct hci_h4p_info *info);
void hci_h4p_store_regs(struct hci_h4p_info *info);
void hci_h4p_restore_regs(struct hci_h4p_info *info);
void hci_h4p_smart_idle(struct hci_h4p_info *info, bool enable);

#endif /* __DRIVERS_BLUETOOTH_HCI_H4P_H */