staging/bluetooth: Add hci_h4p driver
[cascardo/linux.git] / drivers / staging / nokia_h4p / nokia_fw.c
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 }