31
31
32
32
#define VERSION "1.0"
33
33
34
+ #define ATH3K_DNLOAD 0x01
35
+ #define ATH3K_GETSTATE 0x05
36
+ #define ATH3K_SET_NORMAL_MODE 0x07
37
+ #define ATH3K_GETVERSION 0x09
38
+ #define USB_REG_SWITCH_VID_PID 0x0a
39
+
40
+ #define ATH3K_MODE_MASK 0x3F
41
+ #define ATH3K_NORMAL_MODE 0x0E
42
+
43
+ #define ATH3K_PATCH_UPDATE 0x80
44
+ #define ATH3K_SYSCFG_UPDATE 0x40
45
+
46
+ #define ATH3K_XTAL_FREQ_26M 0x00
47
+ #define ATH3K_XTAL_FREQ_40M 0x01
48
+ #define ATH3K_XTAL_FREQ_19P2 0x02
49
+ #define ATH3K_NAME_LEN 0xFF
50
+
51
+ struct ath3k_version {
52
+ unsigned int rom_version ;
53
+ unsigned int build_version ;
54
+ unsigned int ram_version ;
55
+ unsigned char ref_clock ;
56
+ unsigned char reserved [0x07 ];
57
+ };
34
58
35
59
static struct usb_device_id ath3k_table [] = {
36
60
/* Atheros AR3011 */
@@ -41,13 +65,29 @@ static struct usb_device_id ath3k_table[] = {
41
65
42
66
/* Atheros AR9285 Malbec with sflash firmware */
43
67
{ USB_DEVICE (0x03F0 , 0x311D ) },
68
+
69
+ /* Atheros AR3012 with sflash firmware*/
70
+ { USB_DEVICE (0x0CF3 , 0x3004 ) },
71
+
44
72
{ } /* Terminating entry */
45
73
};
46
74
47
75
MODULE_DEVICE_TABLE (usb , ath3k_table );
48
76
77
+ #define BTUSB_ATH3012 0x80
78
+ /* This table is to load patch and sysconfig files
79
+ * for AR3012 */
80
+ static struct usb_device_id ath3k_blist_tbl [] = {
81
+
82
+ /* Atheros AR3012 with sflash firmware*/
83
+ { USB_DEVICE (0x0cf3 , 0x3004 ), .driver_info = BTUSB_ATH3012 },
84
+
85
+ { } /* Terminating entry */
86
+ };
87
+
49
88
#define USB_REQ_DFU_DNLOAD 1
50
89
#define BULK_SIZE 4096
90
+ #define FW_HDR_SIZE 20
51
91
52
92
static int ath3k_load_firmware (struct usb_device * udev ,
53
93
const struct firmware * firmware )
@@ -103,6 +143,215 @@ static int ath3k_load_firmware(struct usb_device *udev,
103
143
return err ;
104
144
}
105
145
146
+ static int ath3k_get_state (struct usb_device * udev , unsigned char * state )
147
+ {
148
+ int pipe = 0 ;
149
+
150
+ pipe = usb_rcvctrlpipe (udev , 0 );
151
+ return usb_control_msg (udev , pipe , ATH3K_GETSTATE ,
152
+ USB_TYPE_VENDOR | USB_DIR_IN , 0 , 0 ,
153
+ state , 0x01 , USB_CTRL_SET_TIMEOUT );
154
+ }
155
+
156
+ static int ath3k_get_version (struct usb_device * udev ,
157
+ struct ath3k_version * version )
158
+ {
159
+ int pipe = 0 ;
160
+
161
+ pipe = usb_rcvctrlpipe (udev , 0 );
162
+ return usb_control_msg (udev , pipe , ATH3K_GETVERSION ,
163
+ USB_TYPE_VENDOR | USB_DIR_IN , 0 , 0 , version ,
164
+ sizeof (struct ath3k_version ),
165
+ USB_CTRL_SET_TIMEOUT );
166
+ }
167
+
168
+ static int ath3k_load_fwfile (struct usb_device * udev ,
169
+ const struct firmware * firmware )
170
+ {
171
+ u8 * send_buf ;
172
+ int err , pipe , len , size , count , sent = 0 ;
173
+ int ret ;
174
+
175
+ count = firmware -> size ;
176
+
177
+ send_buf = kmalloc (BULK_SIZE , GFP_ATOMIC );
178
+ if (!send_buf ) {
179
+ BT_ERR ("Can't allocate memory chunk for firmware" );
180
+ return - ENOMEM ;
181
+ }
182
+
183
+ size = min_t (uint , count , FW_HDR_SIZE );
184
+ memcpy (send_buf , firmware -> data , size );
185
+
186
+ pipe = usb_sndctrlpipe (udev , 0 );
187
+ ret = usb_control_msg (udev , pipe , ATH3K_DNLOAD ,
188
+ USB_TYPE_VENDOR , 0 , 0 , send_buf ,
189
+ size , USB_CTRL_SET_TIMEOUT );
190
+ if (ret < 0 ) {
191
+ BT_ERR ("Can't change to loading configuration err" );
192
+ kfree (send_buf );
193
+ return ret ;
194
+ }
195
+
196
+ sent += size ;
197
+ count -= size ;
198
+
199
+ while (count ) {
200
+ size = min_t (uint , count , BULK_SIZE );
201
+ pipe = usb_sndbulkpipe (udev , 0x02 );
202
+
203
+ memcpy (send_buf , firmware -> data + sent , size );
204
+
205
+ err = usb_bulk_msg (udev , pipe , send_buf , size ,
206
+ & len , 3000 );
207
+ if (err || (len != size )) {
208
+ BT_ERR ("Error in firmware loading err = %d,"
209
+ "len = %d, size = %d" , err , len , size );
210
+ kfree (send_buf );
211
+ return err ;
212
+ }
213
+ sent += size ;
214
+ count -= size ;
215
+ }
216
+
217
+ kfree (send_buf );
218
+ return 0 ;
219
+ }
220
+
221
+ static int ath3k_switch_pid (struct usb_device * udev )
222
+ {
223
+ int pipe = 0 ;
224
+
225
+ pipe = usb_sndctrlpipe (udev , 0 );
226
+ return usb_control_msg (udev , pipe , USB_REG_SWITCH_VID_PID ,
227
+ USB_TYPE_VENDOR , 0 , 0 ,
228
+ NULL , 0 , USB_CTRL_SET_TIMEOUT );
229
+ }
230
+
231
+ static int ath3k_set_normal_mode (struct usb_device * udev )
232
+ {
233
+ unsigned char fw_state ;
234
+ int pipe = 0 , ret ;
235
+
236
+ ret = ath3k_get_state (udev , & fw_state );
237
+ if (ret < 0 ) {
238
+ BT_ERR ("Can't get state to change to normal mode err" );
239
+ return ret ;
240
+ }
241
+
242
+ if ((fw_state & ATH3K_MODE_MASK ) == ATH3K_NORMAL_MODE ) {
243
+ BT_DBG ("firmware was already in normal mode" );
244
+ return 0 ;
245
+ }
246
+
247
+ pipe = usb_sndctrlpipe (udev , 0 );
248
+ return usb_control_msg (udev , pipe , ATH3K_SET_NORMAL_MODE ,
249
+ USB_TYPE_VENDOR , 0 , 0 ,
250
+ NULL , 0 , USB_CTRL_SET_TIMEOUT );
251
+ }
252
+
253
+ static int ath3k_load_patch (struct usb_device * udev )
254
+ {
255
+ unsigned char fw_state ;
256
+ char filename [ATH3K_NAME_LEN ] = {0 };
257
+ const struct firmware * firmware ;
258
+ struct ath3k_version fw_version , pt_version ;
259
+ int ret ;
260
+
261
+ ret = ath3k_get_state (udev , & fw_state );
262
+ if (ret < 0 ) {
263
+ BT_ERR ("Can't get state to change to load ram patch err" );
264
+ return ret ;
265
+ }
266
+
267
+ if (fw_state & ATH3K_PATCH_UPDATE ) {
268
+ BT_DBG ("Patch was already downloaded" );
269
+ return 0 ;
270
+ }
271
+
272
+ ret = ath3k_get_version (udev , & fw_version );
273
+ if (ret < 0 ) {
274
+ BT_ERR ("Can't get version to change to load ram patch err" );
275
+ return ret ;
276
+ }
277
+
278
+ snprintf (filename , ATH3K_NAME_LEN , "ar3k/AthrBT_0x%08x.dfu" ,
279
+ fw_version .rom_version );
280
+
281
+ ret = request_firmware (& firmware , filename , & udev -> dev );
282
+ if (ret < 0 ) {
283
+ BT_ERR ("Patch file not found %s" , filename );
284
+ return ret ;
285
+ }
286
+
287
+ pt_version .rom_version = * (int * )(firmware -> data + firmware -> size - 8 );
288
+ pt_version .build_version = * (int * )
289
+ (firmware -> data + firmware -> size - 4 );
290
+
291
+ if ((pt_version .rom_version != fw_version .rom_version ) ||
292
+ (pt_version .build_version <= fw_version .build_version )) {
293
+ BT_ERR ("Patch file version did not match with firmware" );
294
+ release_firmware (firmware );
295
+ return - EINVAL ;
296
+ }
297
+
298
+ ret = ath3k_load_fwfile (udev , firmware );
299
+ release_firmware (firmware );
300
+
301
+ return ret ;
302
+ }
303
+
304
+ static int ath3k_load_syscfg (struct usb_device * udev )
305
+ {
306
+ unsigned char fw_state ;
307
+ char filename [ATH3K_NAME_LEN ] = {0 };
308
+ const struct firmware * firmware ;
309
+ struct ath3k_version fw_version ;
310
+ int clk_value , ret ;
311
+
312
+ ret = ath3k_get_state (udev , & fw_state );
313
+ if (ret < 0 ) {
314
+ BT_ERR ("Can't get state to change to load configration err" );
315
+ return - EBUSY ;
316
+ }
317
+
318
+ ret = ath3k_get_version (udev , & fw_version );
319
+ if (ret < 0 ) {
320
+ BT_ERR ("Can't get version to change to load ram patch err" );
321
+ return ret ;
322
+ }
323
+
324
+ switch (fw_version .ref_clock ) {
325
+
326
+ case ATH3K_XTAL_FREQ_26M :
327
+ clk_value = 26 ;
328
+ break ;
329
+ case ATH3K_XTAL_FREQ_40M :
330
+ clk_value = 40 ;
331
+ break ;
332
+ case ATH3K_XTAL_FREQ_19P2 :
333
+ clk_value = 19 ;
334
+ break ;
335
+ default :
336
+ clk_value = 0 ;
337
+ break ;
338
+ }
339
+
340
+ snprintf (filename , ATH3K_NAME_LEN , "ar3k/ramps_0x%08x_%d%s" ,
341
+ fw_version .rom_version , clk_value , ".dfu" );
342
+
343
+ ret = request_firmware (& firmware , filename , & udev -> dev );
344
+ if (ret < 0 ) {
345
+ BT_ERR ("Configuration file not found %s" , filename );
346
+ return ret ;
347
+ }
348
+
349
+ ret = ath3k_load_fwfile (udev , firmware );
350
+ release_firmware (firmware );
351
+
352
+ return ret ;
353
+ }
354
+
106
355
static int ath3k_probe (struct usb_interface * intf ,
107
356
const struct usb_device_id * id )
108
357
{
@@ -115,7 +364,37 @@ static int ath3k_probe(struct usb_interface *intf,
115
364
if (intf -> cur_altsetting -> desc .bInterfaceNumber != 0 )
116
365
return - ENODEV ;
117
366
367
+ /* match device ID in ath3k blacklist table */
368
+ if (!id -> driver_info ) {
369
+ const struct usb_device_id * match ;
370
+ match = usb_match_id (intf , ath3k_blist_tbl );
371
+ if (match )
372
+ id = match ;
373
+ }
374
+
375
+ /* load patch and sysconfig files for AR3012 */
376
+ if (id -> driver_info & BTUSB_ATH3012 ) {
377
+ ret = ath3k_load_patch (udev );
378
+ if (ret < 0 ) {
379
+ BT_ERR ("Loading patch file failed" );
380
+ return ret ;
381
+ }
382
+ ret = ath3k_load_syscfg (udev );
383
+ if (ret < 0 ) {
384
+ BT_ERR ("Loading sysconfig file failed" );
385
+ return ret ;
386
+ }
387
+ ret = ath3k_set_normal_mode (udev );
388
+ if (ret < 0 ) {
389
+ BT_ERR ("Set normal mode failed" );
390
+ return ret ;
391
+ }
392
+ ath3k_switch_pid (udev );
393
+ return 0 ;
394
+ }
395
+
118
396
if (request_firmware (& firmware , "ath3k-1.fw" , & udev -> dev ) < 0 ) {
397
+ BT_ERR ("Error loading firmware" );
119
398
return - EIO ;
120
399
}
121
400
0 commit comments