CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
orangepi-xunlong

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place. Commercial Alternative to JupyterHub.

GitHub Repository: orangepi-xunlong/orangepi-build
Path: blob/next/external/cache/sources/hcitools/hciattach_sprd_2.c
Views: 3959
1
#include <stdio.h>
2
#include <stdlib.h>
3
#include <unistd.h>
4
#include <errno.h>
5
#include <fcntl.h>
6
#include <string.h>
7
#include <signal.h>
8
#include <time.h>
9
#include <stdint.h>
10
#include <sys/termios.h>
11
#include <sys/ioctl.h>
12
#include <limits.h>
13
#include "hciattach.h"
14
15
/******************************************************************************
16
** Constants & Macros
17
******************************************************************************/
18
#define LOG_STR "SPRD Bluetooth"
19
#define DBG_ON 1
20
21
#define SPRD_DBG(fmt, arg...) \
22
do { \
23
if (DBG_ON) \
24
fprintf(stderr, "%s: " fmt "\n" , LOG_STR, ##arg); \
25
} while(0)
26
27
#define SPRD_ERR(fmt, arg...) \
28
do { \
29
fprintf(stderr, "%s ERROR: " fmt "\n", LOG_STR, ##arg);\
30
perror(LOG_STR" ERROR reason"); \
31
} while(0)
32
33
#define SPRD_DUMP(buffer, len) \
34
fprintf(stderr, "%s: ", LOG_STR); \
35
do { \
36
int i = 0; \
37
for (i = 0; i < len; i++) { \
38
if (i && !(i % 16)) { \
39
fprintf(stderr, "\n"); \
40
fprintf(stderr, "%s: ", LOG_STR); \
41
} \
42
fprintf(stderr, "%02x ", buffer[i]); \
43
} \
44
fprintf(stderr, "\n"); \
45
} while (0)
46
47
#define CONF_ITEM_TABLE(ITEM, ACTION, BUF, LEN) \
48
{ #ITEM, ACTION, &(BUF.ITEM), LEN, (sizeof(BUF.ITEM) / LEN) }
49
50
#define UINT8_TO_STREAM(p, u8) \
51
{ *(p)++ = (uint8_t)(u8); }
52
53
#define STREAM_TO_UINT8(u8, p) \
54
{ \
55
(u8) = (uint8_t)(*(p)); \
56
(p) += 1; \
57
}
58
59
#define UINT16_TO_STREAM(p, u16) \
60
{ \
61
*(p)++ = (uint8_t)(u16); \
62
*(p)++ = (uint8_t)((u16) >> 8); \
63
}
64
65
#define STREAM_TO_UINT16(u16, p) \
66
{ \
67
(u16) = ((uint16_t)(*(p)) + (((uint16_t)(*((p) + 1))) << 8)); \
68
(p) += 2; \
69
}
70
71
#define UINT32_TO_STREAM(p, u32) \
72
{ \
73
*(p)++ = (uint8_t)(u32); \
74
*(p)++ = (uint8_t)((u32) >> 8); \
75
*(p)++ = (uint8_t)((u32) >> 16); \
76
*(p)++ = (uint8_t)((u32) >> 24); \
77
}
78
79
#define CONF_COMMENT '#'
80
#define CONF_DELIMITERS " =\n\r\t"
81
#define CONF_VALUES_DELIMITERS "=\n\r\t#"
82
#define CONF_VALUES_PARTITION " ,=\n\r\t#"
83
#define CONF_MAX_LINE_LEN 255
84
85
#define HCI_PSKEY 0xFCA0
86
#define HCI_VSC_ENABLE_COMMMAND 0xFCA1
87
#define HCI_RF_PARA 0xFCA2
88
89
#define RESPONSE_LENGTH 100
90
#define HCI_CMD_MAX_LEN 258
91
#define HCI_EVT_CMD_CMPL_OPCODE 3
92
#define HCI_PACKET_TYPE_COMMAND 1
93
#define HCI_CMD_PREAMBLE_SIZE 3
94
95
#define FW_NODE_BYTE 6
96
#define FW_DATE_D_BYTE 8
97
#define FW_DATE_M_BYTE 9
98
#define FW_DATE_Y_BYTE 10
99
100
#define BT_CONFIG_PATH "/lib/firmware"
101
#define BT_HC_HDR_SIZE (sizeof(HC_BT_HDR))
102
#define BT_VND_OP_RESULT_SUCCESS 0
103
#define BT_VND_OP_RESULT_FAIL 1
104
#define MSG_STACK_TO_HC_HCI_CMD 0x2000
105
#define START_STOP_CMD_SIZE 3
106
#define DUAL_MODE 0
107
#define DISABLE_BT 0
108
#define ENABLE_BT 1
109
110
typedef void (*hci_cback)(void *);
111
typedef int (conf_action_t)(char *p_conf_name, char *p_conf_value, void *buf, int len, int size);
112
113
typedef struct {
114
uint16_t event;
115
uint16_t len;
116
uint16_t offset;
117
uint16_t layer_specific;
118
uint8_t data[];
119
} HC_BT_HDR;
120
121
typedef struct {
122
uint32_t device_class;
123
uint8_t feature_set[16];
124
uint8_t device_addr[6];
125
uint16_t comp_id;
126
uint8_t g_sys_uart0_communication_supported;
127
uint8_t cp2_log_mode;
128
uint8_t LogLevel;
129
uint8_t g_central_or_perpheral;
130
uint16_t Log_BitMask;
131
uint8_t super_ssp_enable;
132
uint8_t common_rfu_b3;
133
uint32_t common_rfu_w[2];
134
uint32_t le_rfu_w[2];
135
uint32_t lmp_rfu_w[2];
136
uint32_t lc_rfu_w[2];
137
uint16_t g_wbs_nv_117;
138
uint16_t g_wbs_nv_118;
139
uint16_t g_nbv_nv_117;
140
uint16_t g_nbv_nv_118;
141
uint8_t g_sys_sco_transmit_mode;
142
uint8_t audio_rfu_b1;
143
uint8_t audio_rfu_b2;
144
uint8_t audio_rfu_b3;
145
uint32_t audio_rfu_w[2];
146
uint8_t g_sys_sleep_in_standby_supported;
147
uint8_t g_sys_sleep_master_supported;
148
uint8_t g_sys_sleep_slave_supported;
149
uint8_t power_rfu_b1;
150
uint32_t power_rfu_w[2];
151
uint32_t win_ext;
152
uint8_t edr_tx_edr_delay;
153
uint8_t edr_rx_edr_delay;
154
uint8_t tx_delay;
155
uint8_t rx_delay;
156
uint32_t bb_rfu_w[2];
157
uint8_t agc_mode;
158
uint8_t diff_or_eq;
159
uint8_t ramp_mode;
160
uint8_t modem_rfu_b1;
161
uint32_t modem_rfu_w[2];
162
uint32_t BQB_BitMask_1;
163
uint32_t BQB_BitMask_2;
164
uint16_t bt_coex_threshold[8];
165
uint32_t other_rfu_w[6];
166
} pskey_config_t;
167
168
typedef struct {
169
uint16_t g_GainValue_A[6];
170
uint16_t g_ClassicPowerValue_A[10];
171
uint16_t g_LEPowerValue_A[16];
172
uint16_t g_BRChannelpwrvalue_A[8];
173
uint16_t g_EDRChannelpwrvalue_A[8];
174
uint16_t g_LEChannelpwrvalue_A[8];
175
uint16_t g_GainValue_B[6];
176
uint16_t g_ClassicPowerValue_B[10];
177
uint16_t g_LEPowerValue_B[16];
178
uint16_t g_BRChannelpwrvalue_B[8];
179
uint16_t g_EDRChannelpwrvalue_B[8];
180
uint16_t g_LEChannelpwrvalue_B[8];
181
uint16_t LE_fix_powerword;
182
uint8_t Classic_pc_by_channel;
183
uint8_t LE_pc_by_channel;
184
uint8_t RF_switch_mode;
185
uint8_t Data_Capture_Mode;
186
uint8_t Analog_IQ_Debug_Mode;
187
uint8_t RF_common_rfu_b3;
188
uint32_t RF_common_rfu_w[5];
189
} rf_config_t;
190
191
typedef struct {
192
const char *conf_entry;
193
conf_action_t *p_action;
194
void *buf;
195
int len;
196
int size;
197
} conf_entry_t;
198
199
static uint8_t local_bdaddr[6]={0x10, 0x11, 0x12, 0x13, 0x14, 0x15};
200
static pskey_config_t marlin3_pskey;
201
static rf_config_t marlin3_rf_config;
202
static int s_bt_fd = -1;
203
204
static const conf_entry_t marlin3_pksey_table[] = {
205
CONF_ITEM_TABLE(device_class, 0, marlin3_pskey, 1),
206
CONF_ITEM_TABLE(feature_set, 0, marlin3_pskey, 16),
207
CONF_ITEM_TABLE(device_addr, 0, marlin3_pskey, 6),
208
CONF_ITEM_TABLE(comp_id, 0, marlin3_pskey, 1),
209
CONF_ITEM_TABLE(g_sys_uart0_communication_supported, 0, marlin3_pskey, 1),
210
CONF_ITEM_TABLE(cp2_log_mode, 0, marlin3_pskey, 1),
211
CONF_ITEM_TABLE(LogLevel, 0, marlin3_pskey, 1),
212
CONF_ITEM_TABLE(g_central_or_perpheral, 0, marlin3_pskey, 1),
213
CONF_ITEM_TABLE(Log_BitMask, 0, marlin3_pskey, 1),
214
CONF_ITEM_TABLE(super_ssp_enable, 0, marlin3_pskey, 1),
215
CONF_ITEM_TABLE(common_rfu_b3, 0, marlin3_pskey, 1),
216
CONF_ITEM_TABLE(common_rfu_w, 0, marlin3_pskey, 2),
217
CONF_ITEM_TABLE(le_rfu_w, 0, marlin3_pskey, 2),
218
CONF_ITEM_TABLE(lmp_rfu_w, 0, marlin3_pskey, 2),
219
CONF_ITEM_TABLE(lc_rfu_w, 0, marlin3_pskey, 2),
220
CONF_ITEM_TABLE(g_wbs_nv_117, 0, marlin3_pskey, 1),
221
CONF_ITEM_TABLE(g_wbs_nv_118, 0, marlin3_pskey, 1),
222
CONF_ITEM_TABLE(g_nbv_nv_117, 0, marlin3_pskey, 1),
223
CONF_ITEM_TABLE(g_nbv_nv_118, 0, marlin3_pskey, 1),
224
CONF_ITEM_TABLE(g_sys_sco_transmit_mode, 0, marlin3_pskey, 1),
225
CONF_ITEM_TABLE(audio_rfu_b1, 0, marlin3_pskey, 1),
226
CONF_ITEM_TABLE(audio_rfu_b2, 0, marlin3_pskey, 1),
227
CONF_ITEM_TABLE(audio_rfu_b3, 0, marlin3_pskey, 1),
228
CONF_ITEM_TABLE(audio_rfu_w, 0, marlin3_pskey, 2),
229
CONF_ITEM_TABLE(g_sys_sleep_in_standby_supported, 0, marlin3_pskey, 1),
230
CONF_ITEM_TABLE(g_sys_sleep_master_supported, 0, marlin3_pskey, 1),
231
CONF_ITEM_TABLE(g_sys_sleep_slave_supported, 0, marlin3_pskey, 1),
232
CONF_ITEM_TABLE(power_rfu_b1, 0, marlin3_pskey, 1),
233
CONF_ITEM_TABLE(power_rfu_w, 0, marlin3_pskey, 2),
234
CONF_ITEM_TABLE(win_ext, 0, marlin3_pskey, 1),
235
CONF_ITEM_TABLE(edr_tx_edr_delay, 0, marlin3_pskey, 1),
236
CONF_ITEM_TABLE(edr_rx_edr_delay, 0, marlin3_pskey, 1),
237
CONF_ITEM_TABLE(tx_delay, 0, marlin3_pskey, 1),
238
CONF_ITEM_TABLE(rx_delay, 0, marlin3_pskey, 1),
239
CONF_ITEM_TABLE(bb_rfu_w, 0, marlin3_pskey, 2),
240
CONF_ITEM_TABLE(agc_mode, 0, marlin3_pskey, 1),
241
CONF_ITEM_TABLE(diff_or_eq, 0, marlin3_pskey, 1),
242
CONF_ITEM_TABLE(ramp_mode, 0, marlin3_pskey, 1),
243
CONF_ITEM_TABLE(modem_rfu_b1, 0, marlin3_pskey, 1),
244
CONF_ITEM_TABLE(modem_rfu_w, 0, marlin3_pskey, 2),
245
CONF_ITEM_TABLE(BQB_BitMask_1, 0, marlin3_pskey, 1),
246
CONF_ITEM_TABLE(BQB_BitMask_2, 0, marlin3_pskey, 1),
247
CONF_ITEM_TABLE(bt_coex_threshold, 0, marlin3_pskey, 8),
248
CONF_ITEM_TABLE(other_rfu_w, 0, marlin3_pskey, 6),
249
{0, 0, 0, 0, 0}
250
};
251
252
static const conf_entry_t marlin3_rf_table[] = {
253
CONF_ITEM_TABLE(g_GainValue_A, 0, marlin3_rf_config, 6),
254
CONF_ITEM_TABLE(g_ClassicPowerValue_A, 0, marlin3_rf_config, 10),
255
CONF_ITEM_TABLE(g_LEPowerValue_A, 0, marlin3_rf_config, 16),
256
CONF_ITEM_TABLE(g_BRChannelpwrvalue_A, 0, marlin3_rf_config, 8),
257
CONF_ITEM_TABLE(g_EDRChannelpwrvalue_A, 0, marlin3_rf_config, 8),
258
CONF_ITEM_TABLE(g_LEChannelpwrvalue_A, 0, marlin3_rf_config, 8),
259
CONF_ITEM_TABLE(g_GainValue_B, 0, marlin3_rf_config, 6),
260
CONF_ITEM_TABLE(g_ClassicPowerValue_B, 0, marlin3_rf_config, 10),
261
CONF_ITEM_TABLE(g_LEPowerValue_B, 0, marlin3_rf_config, 16),
262
CONF_ITEM_TABLE(g_BRChannelpwrvalue_B, 0, marlin3_rf_config, 8),
263
CONF_ITEM_TABLE(g_EDRChannelpwrvalue_B, 0, marlin3_rf_config, 8),
264
CONF_ITEM_TABLE(g_LEChannelpwrvalue_B, 0, marlin3_rf_config, 8),
265
CONF_ITEM_TABLE(LE_fix_powerword, 0, marlin3_rf_config, 1),
266
CONF_ITEM_TABLE(Classic_pc_by_channel, 0, marlin3_rf_config, 1),
267
CONF_ITEM_TABLE(LE_pc_by_channel, 0, marlin3_rf_config, 1),
268
CONF_ITEM_TABLE(RF_switch_mode, 0, marlin3_rf_config, 1),
269
CONF_ITEM_TABLE(Data_Capture_Mode, 0, marlin3_rf_config, 1),
270
CONF_ITEM_TABLE(Analog_IQ_Debug_Mode, 0, marlin3_rf_config, 1),
271
CONF_ITEM_TABLE(RF_common_rfu_b3, 0, marlin3_rf_config, 1),
272
CONF_ITEM_TABLE(RF_common_rfu_w, 0, marlin3_rf_config, 5),
273
{0, 0, 0, 0, 0}
274
};
275
276
static void log_bin_to_hexstr(uint8_t *bin, uint8_t binsz, const char *log_tag)
277
{
278
SPRD_DBG("%s", log_tag);
279
SPRD_DUMP(bin, binsz);
280
}
281
282
static void parse_number(char *p_conf_name, char *p_conf_value, void *buf, int len, int size)
283
{
284
uint8_t *dest = (uint8_t *)buf;
285
char *sub_value, *p;
286
uint32_t value;
287
(void)p_conf_name;
288
sub_value = strtok_r(p_conf_value, CONF_VALUES_PARTITION, &p);
289
do {
290
if (sub_value == NULL)
291
break;
292
293
if (sub_value[0] == '0' && (sub_value[1] == 'x' || sub_value[1] == 'X'))
294
value = strtoul(sub_value, 0, 16) & 0xFFFFFFFF;
295
else
296
value = strtoul(sub_value, 0, 10) & 0xFFFFFFFF;
297
298
switch (size) {
299
case sizeof(uint8_t):
300
*dest = value & 0xFF;
301
dest += size;
302
break;
303
304
case sizeof(uint16_t):
305
*((uint16_t *)dest) = value & 0xFFFF;
306
dest += size;
307
break;
308
309
case sizeof(uint32_t):
310
*((uint32_t *)dest) = value & 0xFFFFFFFF;
311
dest += size;
312
break;
313
314
default:
315
break;
316
}
317
sub_value = strtok_r(NULL, CONF_VALUES_PARTITION, &p);
318
} while (--len);
319
}
320
321
static unsigned char compare_char(unsigned char ch)
322
{
323
unsigned char data = 0x0;
324
325
switch(ch)
326
{
327
case 0:
328
case '0':
329
data = 0x0;
330
break;
331
case 1:
332
case '1':
333
data = 0x1;
334
break;
335
case 2:
336
case '2':
337
data = 0x2;
338
break;
339
case 3:
340
case '3':
341
data = 0x3;
342
break;
343
case 4:
344
case '4':
345
data = 0x4;
346
break;
347
case 5:
348
case '5':
349
data = 0x5;
350
break;
351
case 6:
352
case '6':
353
data = 0x6;
354
break;
355
case 7:
356
case '7':
357
data = 0x7;
358
break;
359
case 8:
360
case '8':
361
data = 0x8;
362
break;
363
case 9:
364
case '9':
365
data = 0x9;
366
break;
367
case 10:
368
case 'a':
369
case 'A':
370
data = 0xA;
371
break;
372
case 11:
373
case 'b':
374
case 'B':
375
data = 0xB;
376
break;
377
case 12:
378
case 'c':
379
case 'C':
380
data = 0xC;
381
break;
382
case 13:
383
case 'd':
384
case 'D':
385
data = 0xD;
386
break;
387
case 14:
388
case 'e':
389
case 'E':
390
data = 0xE;
391
break;
392
case 15:
393
case 'f':
394
case 'F':
395
data = 0xF;
396
break;
397
}
398
return data;
399
}
400
401
static void set_mac_address(uint8_t *addr)
402
{
403
int i = 0;
404
405
FILE *fp = fopen("/sys/class/net/wlan0/address", "r");
406
unsigned char buff[255];
407
unsigned char tmp[5];
408
unsigned char str, str2;
409
410
SPRD_DBG("%s", __func__);
411
412
fscanf(fp, "%s", buff);
413
fclose(fp);
414
415
for (i=0; i<6; i++)
416
{
417
sprintf(tmp, "%c%c", buff[3*i], buff[3*i+1]);
418
str = compare_char(tmp[0]);
419
str2 = compare_char(tmp[1]);
420
local_bdaddr[i] = (str << 4) | str2;
421
}
422
423
for (i = 0; i < 6; i++)
424
addr[5-i] = (unsigned char)local_bdaddr[i];
425
426
addr[0] += 1;
427
addr[1] += 1;
428
}
429
430
static void vnd_load_configure(const char *p_path, const conf_entry_t *entry)
431
{
432
FILE *p_file;
433
char *p_name, *p_value, *p;
434
conf_entry_t *p_entry;
435
char line[CONF_MAX_LINE_LEN + 1]; /* add 1 for \0 char */
436
437
SPRD_DBG("Attempt to load conf from %s", p_path);
438
439
if ((p_file = fopen(p_path, "r")) != NULL) {
440
/* read line by line */
441
while (fgets(line, CONF_MAX_LINE_LEN + 1, p_file) != NULL) {
442
if (line[0] == CONF_COMMENT) continue;
443
444
p_name = strtok_r(line, CONF_DELIMITERS, &p);
445
446
if (NULL == p_name) {
447
continue;
448
}
449
450
p_value = strtok_r(NULL, CONF_VALUES_DELIMITERS, &p);
451
452
if (NULL == p_value) {
453
SPRD_DBG("vnd_load_conf: missing value for name: %s", p_name);
454
continue;
455
}
456
457
p_entry = (conf_entry_t*)entry;
458
459
while (p_entry->conf_entry != NULL) {
460
if (strcmp(p_entry->conf_entry, (const char *)p_name) == 0) {
461
if (p_entry->p_action) {
462
p_entry->p_action(p_name, p_value, p_entry->buf, p_entry->len,
463
p_entry->size);
464
} else {
465
SPRD_DBG("%s -> %s", p_name, p_value);
466
parse_number(p_name, p_value, p_entry->buf, p_entry->len,
467
p_entry->size);
468
}
469
break;
470
}
471
472
p_entry++;
473
}
474
}
475
476
fclose(p_file);
477
} else {
478
SPRD_DBG("vnd_load_conf file >%s< not found", p_path);
479
}
480
}
481
482
static size_t H4Protocol_Send(uint8_t type, const uint8_t* data, size_t length)
483
{
484
struct iovec iov[] = {
485
{&type, sizeof(type)},
486
{(uint8_t *)data, length}};
487
488
ssize_t ret = 0;
489
do {
490
ret = writev(s_bt_fd, iov, sizeof(iov) / sizeof(iov[0]));
491
} while (-1 == ret && EAGAIN == errno);
492
493
if (ret == -1) {
494
SPRD_ERR("%s error writing to UART (%s)", __func__, strerror(errno));
495
} else if (ret < length + 1) {
496
SPRD_ERR("%s: %d / %d bytes written - something went wrong...", __func__, ret, length + 1);
497
}
498
499
return ret;
500
}
501
502
static void *bt_vendor_alloc(int size)
503
{
504
void *p = (uint8_t *)malloc(size);
505
return p;
506
}
507
508
static void bt_vendor_free(void *buffer)
509
{
510
free(buffer);
511
}
512
513
static uint8_t bt_vendor_xmit(uint16_t opcode, void* buffer, hci_cback callback)
514
{
515
uint8_t type = HCI_PACKET_TYPE_COMMAND;
516
(void)opcode;
517
HC_BT_HDR* bt_hdr = (HC_BT_HDR *)buffer;
518
H4Protocol_Send(type, bt_hdr->data, bt_hdr->len);
519
return BT_VND_OP_RESULT_SUCCESS;
520
}
521
522
static uint8_t sprd_vnd_send_hci_vsc(uint16_t cmd, uint8_t *payload, uint8_t len, hci_cback cback)
523
{
524
HC_BT_HDR *p_buf;
525
uint8_t *p, ret;
526
527
p_buf = (HC_BT_HDR *)bt_vendor_alloc(
528
BT_HC_HDR_SIZE + HCI_CMD_PREAMBLE_SIZE + len);
529
if (p_buf) {
530
p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
531
p_buf->offset = 0;
532
p_buf->layer_specific = 0;
533
p_buf->len = HCI_CMD_PREAMBLE_SIZE + len;
534
p = (uint8_t *)(p_buf + 1);
535
536
UINT16_TO_STREAM(p, cmd);
537
*p++ = len;
538
memcpy(p, payload, len);
539
log_bin_to_hexstr((uint8_t *)(p_buf + 1), HCI_CMD_PREAMBLE_SIZE + len, __FUNCTION__);
540
ret = bt_vendor_xmit(cmd, p_buf, cback);
541
bt_vendor_free(p_buf);
542
return ret;
543
}
544
return BT_VND_OP_RESULT_FAIL;
545
}
546
547
static void hw_core_cback(void *p_mem)
548
{
549
uint8_t *p_evt_buf = (uint8_t *)p_mem;
550
uint8_t *p, status;
551
uint16_t opcode, mode;
552
553
p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPCODE;
554
STREAM_TO_UINT16(opcode,p);
555
STREAM_TO_UINT16(mode,p);
556
STREAM_TO_UINT8(status,p);
557
SPRD_DBG("%s hw_core_cback response: [0x%04X, 0x%04X, 0x%02X]", __func__, opcode, mode, status);
558
bt_vendor_free(p_evt_buf);
559
}
560
561
static void hw_core_enable(unsigned char enable)
562
{
563
uint8_t *p, msg_req[HCI_CMD_MAX_LEN];
564
p = msg_req;
565
UINT16_TO_STREAM(p, DUAL_MODE);
566
UINT8_TO_STREAM(p, enable ? ENABLE_BT : DISABLE_BT);
567
sprd_vnd_send_hci_vsc(HCI_VSC_ENABLE_COMMMAND, msg_req, (uint8_t)(p - msg_req), NULL);
568
}
569
570
static void hw_rf_cback(void *p_mem)
571
{
572
uint8_t *p_evt_buf = (uint8_t *)p_mem, len;
573
uint8_t *p, status;
574
uint16_t opcode, mode = 0;
575
576
p = (uint8_t *)(p_evt_buf + 1) + 1;
577
STREAM_TO_UINT8(len, p);
578
579
p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPCODE;
580
STREAM_TO_UINT16(opcode, p);
581
if (len == 6)
582
STREAM_TO_UINT16(mode, p);
583
584
STREAM_TO_UINT8(status, p);
585
586
SPRD_DBG("%s hw_rf_cback response: [0x%04X, 0x%04X, 0x%02X]", __func__, opcode, mode, status);
587
/* Must free the RX event buffer */
588
bt_vendor_free(p_evt_buf);
589
}
590
591
static int marlin3_rf_preload()
592
{
593
uint8_t *p, msg_req[HCI_CMD_MAX_LEN];
594
int i;
595
596
SPRD_DBG("yujian.qin %s", __FUNCTION__);
597
p = msg_req;
598
599
for (i = 0; i < 6; i++)
600
UINT16_TO_STREAM(p, marlin3_rf_config.g_GainValue_A[i]);
601
602
for (i = 0; i < 10; i++)
603
UINT16_TO_STREAM(p, marlin3_rf_config.g_ClassicPowerValue_A[i]);
604
605
for (i = 0; i < 16; i++)
606
UINT16_TO_STREAM(p, marlin3_rf_config.g_LEPowerValue_A[i]);
607
608
for (i = 0; i < 8; i++)
609
UINT16_TO_STREAM(p, marlin3_rf_config.g_BRChannelpwrvalue_A[i]);
610
611
for (i = 0; i < 8; i++)
612
UINT16_TO_STREAM(p, marlin3_rf_config.g_EDRChannelpwrvalue_A[i]);
613
614
for (i = 0; i < 8; i++)
615
UINT16_TO_STREAM(p, marlin3_rf_config.g_LEChannelpwrvalue_A[i]);
616
617
for (i = 0; i < 6; i++)
618
UINT16_TO_STREAM(p, marlin3_rf_config.g_GainValue_B[i]);
619
620
for (i = 0; i < 10; i++)
621
UINT16_TO_STREAM(p, marlin3_rf_config.g_ClassicPowerValue_B[i]);
622
623
for (i = 0; i < 16; i++)
624
UINT16_TO_STREAM(p, marlin3_rf_config.g_LEPowerValue_B[i]);
625
626
for (i = 0; i < 8; i++)
627
UINT16_TO_STREAM(p, marlin3_rf_config.g_BRChannelpwrvalue_B[i]);
628
629
for (i = 0; i < 8; i++)
630
UINT16_TO_STREAM(p, marlin3_rf_config.g_EDRChannelpwrvalue_B[i]);
631
632
for (i = 0; i < 8; i++)
633
UINT16_TO_STREAM(p, marlin3_rf_config.g_LEChannelpwrvalue_B[i]);
634
635
UINT16_TO_STREAM(p, marlin3_rf_config.LE_fix_powerword);
636
637
UINT8_TO_STREAM(p, marlin3_rf_config.Classic_pc_by_channel);
638
UINT8_TO_STREAM(p, marlin3_rf_config.LE_pc_by_channel);
639
UINT8_TO_STREAM(p, marlin3_rf_config.RF_switch_mode);
640
UINT8_TO_STREAM(p, marlin3_rf_config.Data_Capture_Mode);
641
UINT8_TO_STREAM(p, marlin3_rf_config.Analog_IQ_Debug_Mode);
642
UINT8_TO_STREAM(p, marlin3_rf_config.RF_common_rfu_b3);
643
644
for (i = 0; i < 5; i++)
645
UINT32_TO_STREAM(p, marlin3_rf_config.RF_common_rfu_w[i]);
646
647
sprd_vnd_send_hci_vsc(HCI_RF_PARA, msg_req, (uint8_t)(p - msg_req), NULL);
648
return 0;
649
}
650
651
static void marlin3_pskey_cback(void *p_mem)
652
{
653
uint8_t *p_evt_buf = (uint8_t *)p_mem;
654
655
uint16_t opcode, node, year;
656
uint8_t *p, month, day;
657
(void)opcode;
658
659
p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPCODE;
660
STREAM_TO_UINT16(opcode, p);
661
662
p = (uint8_t *)(p_evt_buf + 1) + FW_NODE_BYTE;
663
STREAM_TO_UINT16(node, p);
664
p = (uint8_t *)(p_evt_buf + 1) + FW_DATE_Y_BYTE;
665
STREAM_TO_UINT16(year, p);
666
p = (uint8_t *)(p_evt_buf + 1) + FW_DATE_M_BYTE;
667
STREAM_TO_UINT8(month, p);
668
p = (uint8_t *)(p_evt_buf + 1) + FW_DATE_D_BYTE;
669
STREAM_TO_UINT8(day, p);
670
671
SPRD_DBG("Bluetooth Firmware Node: %04X Date: %04x-%02x-%02x", node, year, month, day);
672
673
/* Must free the RX event buffer */
674
bt_vendor_free(p_evt_buf);
675
}
676
677
static int marlin3_pskey_preload(void *arg)
678
{
679
uint8_t *p, msg_req[HCI_CMD_MAX_LEN];
680
int i;
681
(void)arg;
682
683
SPRD_DBG("%s", __FUNCTION__);
684
p = msg_req;
685
UINT32_TO_STREAM(p, marlin3_pskey.device_class);
686
687
for (i = 0; i < 16; i++)
688
UINT8_TO_STREAM(p, marlin3_pskey.feature_set[i]);
689
690
for (i = 0; i < 6; i++)
691
UINT8_TO_STREAM(p, marlin3_pskey.device_addr[i]);
692
693
UINT16_TO_STREAM(p, marlin3_pskey.comp_id);
694
UINT8_TO_STREAM(p, marlin3_pskey.g_sys_uart0_communication_supported);
695
UINT8_TO_STREAM(p, marlin3_pskey.cp2_log_mode);
696
UINT8_TO_STREAM(p, marlin3_pskey.LogLevel);
697
UINT8_TO_STREAM(p, marlin3_pskey.g_central_or_perpheral);
698
699
UINT16_TO_STREAM(p, marlin3_pskey.Log_BitMask);
700
UINT8_TO_STREAM(p, marlin3_pskey.super_ssp_enable);
701
UINT8_TO_STREAM(p, marlin3_pskey.common_rfu_b3);
702
703
for (i = 0; i < 2; i++)
704
UINT32_TO_STREAM(p, marlin3_pskey.common_rfu_w[i]);
705
706
for (i = 0; i < 2; i++)
707
UINT32_TO_STREAM(p, marlin3_pskey.le_rfu_w[i]);
708
709
for (i = 0; i < 2; i++)
710
UINT32_TO_STREAM(p, marlin3_pskey.lmp_rfu_w[i]);
711
712
for (i = 0; i < 2; i++)
713
UINT32_TO_STREAM(p, marlin3_pskey.lc_rfu_w[i]);
714
715
UINT16_TO_STREAM(p, marlin3_pskey.g_wbs_nv_117);
716
UINT16_TO_STREAM(p, marlin3_pskey.g_wbs_nv_118);
717
UINT16_TO_STREAM(p, marlin3_pskey.g_nbv_nv_117);
718
UINT16_TO_STREAM(p, marlin3_pskey.g_nbv_nv_118);
719
720
UINT8_TO_STREAM(p, marlin3_pskey.g_sys_sco_transmit_mode);
721
UINT8_TO_STREAM(p, marlin3_pskey.audio_rfu_b1);
722
UINT8_TO_STREAM(p, marlin3_pskey.audio_rfu_b2);
723
UINT8_TO_STREAM(p, marlin3_pskey.audio_rfu_b3);
724
725
for (i = 0; i < 2; i++)
726
UINT32_TO_STREAM(p, marlin3_pskey.audio_rfu_w[i]);
727
728
UINT8_TO_STREAM(p, marlin3_pskey.g_sys_sleep_in_standby_supported);
729
UINT8_TO_STREAM(p, marlin3_pskey.g_sys_sleep_master_supported);
730
UINT8_TO_STREAM(p, marlin3_pskey.g_sys_sleep_slave_supported);
731
UINT8_TO_STREAM(p, marlin3_pskey.power_rfu_b1);
732
733
for (i = 0; i < 2; i++)
734
UINT32_TO_STREAM(p, marlin3_pskey.power_rfu_w[i]);
735
736
UINT32_TO_STREAM(p, marlin3_pskey.win_ext);
737
738
UINT8_TO_STREAM(p, marlin3_pskey.edr_tx_edr_delay);
739
UINT8_TO_STREAM(p, marlin3_pskey.edr_rx_edr_delay);
740
UINT8_TO_STREAM(p, marlin3_pskey.tx_delay);
741
UINT8_TO_STREAM(p, marlin3_pskey.rx_delay);
742
743
for (i = 0; i < 2; i++)
744
UINT32_TO_STREAM(p, marlin3_pskey.bb_rfu_w[i]);
745
746
UINT8_TO_STREAM(p, marlin3_pskey.agc_mode);
747
UINT8_TO_STREAM(p, marlin3_pskey.diff_or_eq);
748
UINT8_TO_STREAM(p, marlin3_pskey.ramp_mode);
749
UINT8_TO_STREAM(p, marlin3_pskey.modem_rfu_b1);
750
751
for (i = 0; i < 2; i++)
752
UINT32_TO_STREAM(p, marlin3_pskey.modem_rfu_w[i]);
753
754
UINT32_TO_STREAM(p, marlin3_pskey.BQB_BitMask_1);
755
UINT32_TO_STREAM(p, marlin3_pskey.BQB_BitMask_2);
756
for (i = 0; i < 8; i++)
757
UINT16_TO_STREAM(p, marlin3_pskey.bt_coex_threshold[i]);
758
759
for (i = 0; i < 6; i++)
760
UINT32_TO_STREAM(p, marlin3_pskey.other_rfu_w[i]);
761
762
sprd_vnd_send_hci_vsc(HCI_PSKEY, msg_req, (uint8_t)(p - msg_req), NULL);
763
return 0;
764
}
765
766
767
int sprd_config_init(int fd, struct uart_t *u, struct termios *ti)
768
{
769
uint8_t *recv = NULL;
770
int len = 0;
771
772
s_bt_fd = fd;
773
774
memset(&marlin3_pskey, 0, sizeof(marlin3_pskey));
775
memset(&marlin3_rf_config, 0, sizeof(marlin3_rf_config));
776
vnd_load_configure(BT_CONFIG_PATH "/bt_configure_pskey.ini", &marlin3_pksey_table[0]);
777
vnd_load_configure(BT_CONFIG_PATH "/bt_configure_rf.ini", &marlin3_rf_table[0]);
778
set_mac_address(marlin3_pskey.device_addr);
779
780
marlin3_pskey_preload(NULL);
781
recv = bt_vendor_alloc(RESPONSE_LENGTH);
782
len = read_hci_event(s_bt_fd, recv, RESPONSE_LENGTH);
783
SPRD_DBG("Received event, len: %d", len);
784
SPRD_DUMP(recv, len);
785
marlin3_pskey_cback(recv);
786
787
marlin3_rf_preload();
788
recv = bt_vendor_alloc(RESPONSE_LENGTH);
789
len = read_hci_event(s_bt_fd, recv, RESPONSE_LENGTH);
790
SPRD_DBG("Received event, len: %d", len);
791
SPRD_DUMP(recv, len);
792
hw_rf_cback(recv);
793
794
hw_core_enable(1);
795
recv = bt_vendor_alloc(RESPONSE_LENGTH);
796
len = read_hci_event(s_bt_fd, recv, RESPONSE_LENGTH);
797
SPRD_DBG("Received event, len: %d", len);
798
SPRD_DUMP(recv, len);
799
hw_core_cback(recv);
800
801
return 0;
802
}
803
804
int sprd_config_post(int fd, struct uart_t *u, struct termios *ti)
805
{
806
SPRD_DBG("Done setting line discpline");
807
return 0;
808
}
809
810
811