]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/bluetooth/hci_h4p/fw.c
792b6b70fc9e4a62c747df90f255e14f0631fe85
[linux-2.6-omap-h63xx.git] / drivers / bluetooth / hci_h4p / 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         NBT_DBG_FW("Opening %d firmware\n", info->chip_type);
42         switch (info->chip_type) {
43         case BT_CHIP_TI:
44                 err = request_firmware(fw_entry, "brf6150fw.bin", info->dev);
45                 break;
46         case BT_CHIP_CSR:
47                 err = request_firmware(fw_entry, "bc4fw.bin", info->dev);
48                 break;
49         default:
50                 dev_err(info->dev, "Invalid chip type\n");
51                 *fw_entry = NULL;
52                 err = -EINVAL;
53         }
54
55         return err;
56 }
57
58 static void hci_h4p_close_firmware(const struct firmware *fw_entry)
59 {
60         release_firmware(fw_entry);
61 }
62
63 /* Read fw. Return length of the command. If no more commands in
64  * fw 0 is returned. In error case return value is negative.
65  */
66 static int hci_h4p_read_fw_cmd(struct hci_h4p_info *info, struct sk_buff **skb,
67                                const struct firmware *fw_entry, int how)
68 {
69         unsigned int cmd_len;
70
71         if (fw_pos >= fw_entry->size) {
72                 return 0;
73         }
74
75         cmd_len = fw_entry->data[fw_pos++];
76         if (!cmd_len)
77                 return 0;
78
79         if (fw_pos + cmd_len > fw_entry->size) {
80                 dev_err(info->dev, "Corrupted firmware image\n");
81                 return -EMSGSIZE;
82         }
83
84         *skb = bt_skb_alloc(cmd_len, how);
85         if (!*skb) {
86                 dev_err(info->dev, "Cannot reserve memory for buffer\n");
87                 return -ENOMEM;
88         }
89         memcpy(skb_put(*skb, cmd_len), &fw_entry->data[fw_pos], cmd_len);
90
91         fw_pos += cmd_len;
92
93         return (*skb)->len;
94 }
95
96 int hci_h4p_read_fw(struct hci_h4p_info *info, struct sk_buff_head *fw_queue)
97 {
98         const struct firmware *fw_entry = NULL;
99         struct sk_buff *skb = NULL;
100         int err;
101
102         err = hci_h4p_open_firmware(info, &fw_entry);
103         if (err < 0 || !fw_entry)
104                 goto err_clean;
105
106         while ((err = hci_h4p_read_fw_cmd(info, &skb, fw_entry, GFP_KERNEL))) {
107                 if (err < 0 || !skb)
108                         goto err_clean;
109
110                 skb_queue_tail(fw_queue, skb);
111         }
112
113 err_clean:
114         hci_h4p_close_firmware(fw_entry);
115         return err;
116 }
117
118 int hci_h4p_send_fw(struct hci_h4p_info *info, struct sk_buff_head *fw_queue)
119 {
120         int err;
121
122         switch(info->chip_type) {
123         case BT_CHIP_CSR:
124                 err = hci_h4p_bc4_send_fw(info, fw_queue);
125                 break;
126         case BT_CHIP_TI:
127                 err = hci_h4p_brf6150_send_fw(info, fw_queue);
128                 break;
129         default:
130                 dev_err(info->dev, "Don't know how to send firmware\n");
131                 err = -EINVAL;
132         }
133
134         return err;
135 }
136
137 void hci_h4p_parse_fw_event(struct hci_h4p_info *info, struct sk_buff *skb)
138 {
139         switch (info->chip_type) {
140         case BT_CHIP_CSR:
141                 hci_h4p_bc4_parse_fw_event(info, skb);
142                 break;
143         case BT_CHIP_TI:
144                 hci_h4p_brf6150_parse_fw_event(info, skb);
145                 break;
146         default:
147                 dev_err(info->dev, "Don't know how to parse fw event\n");
148                 info->fw_error = -EINVAL;
149         }
150
151         return;
152 }