1982edd19a092114c479134cb16e0af54730edf1fPrashant Malani/*
2982edd19a092114c479134cb16e0af54730edf1fPrashant Malani *
3982edd19a092114c479134cb16e0af54730edf1fPrashant Malani *  Copyright (c) 2013, The Linux Foundation. All rights reserved.
4982edd19a092114c479134cb16e0af54730edf1fPrashant Malani *  Not a Contribution.
5982edd19a092114c479134cb16e0af54730edf1fPrashant Malani *
6982edd19a092114c479134cb16e0af54730edf1fPrashant Malani *  Copyright 2012 The Android Open Source Project
7982edd19a092114c479134cb16e0af54730edf1fPrashant Malani *
8982edd19a092114c479134cb16e0af54730edf1fPrashant Malani *  Licensed under the Apache License, Version 2.0 (the "License"); you
9982edd19a092114c479134cb16e0af54730edf1fPrashant Malani *  may not use this file except in compliance with the License. You may
10982edd19a092114c479134cb16e0af54730edf1fPrashant Malani *  obtain a copy of the License at
11982edd19a092114c479134cb16e0af54730edf1fPrashant Malani *
12982edd19a092114c479134cb16e0af54730edf1fPrashant Malani *  http://www.apache.org/licenses/LICENSE-2.0
13982edd19a092114c479134cb16e0af54730edf1fPrashant Malani *
14982edd19a092114c479134cb16e0af54730edf1fPrashant Malani *  Unless required by applicable law or agreed to in writing, software
15982edd19a092114c479134cb16e0af54730edf1fPrashant Malani *  distributed under the License is distributed on an "AS IS" BASIS,
16982edd19a092114c479134cb16e0af54730edf1fPrashant Malani *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
17982edd19a092114c479134cb16e0af54730edf1fPrashant Malani *  implied. See the License for the specific language governing
18982edd19a092114c479134cb16e0af54730edf1fPrashant Malani *  permissions and limitations under the License.
19982edd19a092114c479134cb16e0af54730edf1fPrashant Malani *
20982edd19a092114c479134cb16e0af54730edf1fPrashant Malani */
21982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
22982edd19a092114c479134cb16e0af54730edf1fPrashant Malani/******************************************************************************
23982edd19a092114c479134cb16e0af54730edf1fPrashant Malani *
24982edd19a092114c479134cb16e0af54730edf1fPrashant Malani *  Filename:      hw_ar3k.c
25982edd19a092114c479134cb16e0af54730edf1fPrashant Malani *
26982edd19a092114c479134cb16e0af54730edf1fPrashant Malani *  Description:   Contains controller-specific functions, like
27982edd19a092114c479134cb16e0af54730edf1fPrashant Malani *                      firmware patch download
28982edd19a092114c479134cb16e0af54730edf1fPrashant Malani *                      low power mode operations
29982edd19a092114c479134cb16e0af54730edf1fPrashant Malani *
30982edd19a092114c479134cb16e0af54730edf1fPrashant Malani ******************************************************************************/
31982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#ifdef __cplusplus
32982edd19a092114c479134cb16e0af54730edf1fPrashant Malaniextern "C" {
33982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#endif
34982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
35982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define LOG_TAG "bt_vendor"
36982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
37982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#include <sys/socket.h>
38982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#include <utils/Log.h>
39982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#include <sys/types.h>
40982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#include <sys/stat.h>
41982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#include <signal.h>
42982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#include <time.h>
43982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#include <errno.h>
44982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#include <fcntl.h>
45982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#include <dirent.h>
46982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#include <ctype.h>
47982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#include <cutils/properties.h>
48982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#include <stdlib.h>
49982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#include <termios.h>
50982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#include <string.h>
51982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
52982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#include "bt_hci_bdroid.h"
53982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#include "hci_uart.h"
54982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#include "hw_ar3k.h"
55982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
56982edd19a092114c479134cb16e0af54730edf1fPrashant Malani/******************************************************************************
57982edd19a092114c479134cb16e0af54730edf1fPrashant Malani**  Variables
58982edd19a092114c479134cb16e0af54730edf1fPrashant Malani******************************************************************************/
59982edd19a092114c479134cb16e0af54730edf1fPrashant Malaniint cbstat = 0;
60982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define PATCH_LOC_STRING_LEN   8
61982edd19a092114c479134cb16e0af54730edf1fPrashant Malanichar ARbyte[3];
62982edd19a092114c479134cb16e0af54730edf1fPrashant Malanichar ARptr[MAX_PATCH_CMD + 1];
63982edd19a092114c479134cb16e0af54730edf1fPrashant Malaniint byte_cnt;
64982edd19a092114c479134cb16e0af54730edf1fPrashant Malaniint patch_count = 0;
65982edd19a092114c479134cb16e0af54730edf1fPrashant Malanichar patch_loc[PATCH_LOC_STRING_LEN + 1];
66982edd19a092114c479134cb16e0af54730edf1fPrashant Malaniint PSCounter=0;
67982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
68982edd19a092114c479134cb16e0af54730edf1fPrashant Malaniuint32_t dev_type = 0;
69982edd19a092114c479134cb16e0af54730edf1fPrashant Malaniuint32_t rom_version = 0;
70982edd19a092114c479134cb16e0af54730edf1fPrashant Malaniuint32_t build_version = 0;
71982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
72982edd19a092114c479134cb16e0af54730edf1fPrashant Malanichar patch_file[PATH_MAX];
73982edd19a092114c479134cb16e0af54730edf1fPrashant Malanichar ps_file[PATH_MAX];
74982edd19a092114c479134cb16e0af54730edf1fPrashant MalaniFILE *stream;
75982edd19a092114c479134cb16e0af54730edf1fPrashant Malaniint tag_count=0;
76982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
77982edd19a092114c479134cb16e0af54730edf1fPrashant Malani/* for friendly debugging outpout string */
78982edd19a092114c479134cb16e0af54730edf1fPrashant Malanistatic char *lpm_mode[] = {
79982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    "UNKNOWN",
80982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    "disabled",
81982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    "enabled"
82982edd19a092114c479134cb16e0af54730edf1fPrashant Malani};
83982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
84982edd19a092114c479134cb16e0af54730edf1fPrashant Malanistatic char *lpm_state[] = {
85982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    "UNKNOWN",
86982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    "de-asserted",
87982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    "asserted"
88982edd19a092114c479134cb16e0af54730edf1fPrashant Malani};
89982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
90982edd19a092114c479134cb16e0af54730edf1fPrashant Malanistatic uint8_t upio_state[UPIO_MAX_COUNT];
91982edd19a092114c479134cb16e0af54730edf1fPrashant Malanistruct ps_cfg_entry ps_list[MAX_TAGS];
92982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
93982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define PS_EVENT_LEN 100
94982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
95982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#ifdef __cplusplus
96982edd19a092114c479134cb16e0af54730edf1fPrashant Malani}
97982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#endif
98982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
99982edd19a092114c479134cb16e0af54730edf1fPrashant Malani/*****************************************************************************
100982edd19a092114c479134cb16e0af54730edf1fPrashant Malani**   Functions
101982edd19a092114c479134cb16e0af54730edf1fPrashant Malani*****************************************************************************/
102982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
103982edd19a092114c479134cb16e0af54730edf1fPrashant Malaniint is_bt_soc_ath() {
104982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    int ret = 0;
105982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    char bt_soc_type[PROPERTY_VALUE_MAX];
106982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    ret = property_get("qcom.bluetooth.soc", bt_soc_type, NULL);
107982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (ret != 0) {
108982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        ALOGI("qcom.bluetooth.soc set to %s\n", bt_soc_type);
109982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        if (!strncasecmp(bt_soc_type, "ath3k", sizeof("ath3k")))
110982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            return 1;
111982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    } else {
112982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        ALOGI("qcom.bluetooth.soc not set, so using default.\n");
113982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    }
114982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
115982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    return 0;
116982edd19a092114c479134cb16e0af54730edf1fPrashant Malani}
117982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
118982edd19a092114c479134cb16e0af54730edf1fPrashant Malani/*
119982edd19a092114c479134cb16e0af54730edf1fPrashant Malani * Send HCI command and wait for command complete event.
120982edd19a092114c479134cb16e0af54730edf1fPrashant Malani * The event buffer has to be freed by the caller.
121982edd19a092114c479134cb16e0af54730edf1fPrashant Malani */
122982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
123982edd19a092114c479134cb16e0af54730edf1fPrashant Malanistatic int send_hci_cmd_sync(int dev, uint8_t *cmd, int len, uint8_t **event)
124982edd19a092114c479134cb16e0af54730edf1fPrashant Malani{
125982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    int err;
126982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    uint8_t *hci_event;
127982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    uint8_t pkt_type = HCI_COMMAND_PKT;
128982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
129982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (len == 0)
130982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    return len;
131982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
132982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (write(dev, &pkt_type, 1) != 1)
133982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        return -EILSEQ;
134982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (write(dev, (unsigned char *)cmd, len) != len)
135982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        return -EILSEQ;
136982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
137982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    hci_event = (uint8_t *)malloc(PS_EVENT_LEN);
138982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (!hci_event)
139982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        return -ENOMEM;
140982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
141982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    err = read_hci_event(dev, (unsigned char *)hci_event, PS_EVENT_LEN);
142982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (err > 0) {
143982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        *event = hci_event;
144982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    } else {
145982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        free(hci_event);
146982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        return -EILSEQ;
147982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    }
148982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
149982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    return len;
150982edd19a092114c479134cb16e0af54730edf1fPrashant Malani}
151982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
152982edd19a092114c479134cb16e0af54730edf1fPrashant Malanistatic void convert_bdaddr(char *str_bdaddr, char *bdaddr)
153982edd19a092114c479134cb16e0af54730edf1fPrashant Malani{
154982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    char bdbyte[3];
155982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    char *str_byte = str_bdaddr;
156982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    int i, j;
157982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    int colon_present = 0;
158982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
159982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (strstr(str_bdaddr, ":"))
160982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        colon_present = 1;
161982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
162982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    bdbyte[2] = '\0';
163982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
164982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    /* Reverse the BDADDR to LSB first */
165982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    for (i = 0, j = 5; i < 6; i++, j--) {
166982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        bdbyte[0] = str_byte[0];
167982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        bdbyte[1] = str_byte[1];
168982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        bdaddr[j] = strtol(bdbyte, NULL, 16);
169982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
170982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        if (colon_present == 1)
171982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            str_byte += 3;
172982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        else
173982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            str_byte += 2;
174982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    }
175982edd19a092114c479134cb16e0af54730edf1fPrashant Malani}
176982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
177982edd19a092114c479134cb16e0af54730edf1fPrashant Malanistatic int uart_speed(int s)
178982edd19a092114c479134cb16e0af54730edf1fPrashant Malani{
179982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    switch (s) {
180982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        case 9600:
181982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            return B9600;
182982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        case 19200:
183982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            return B19200;
184982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        case 38400:
185982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            return B38400;
186982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        case 57600:
187982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            return B57600;
188982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        case 115200:
189982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            return B115200;
190982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        case 230400:
191982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            return B230400;
192982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        case 460800:
193982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            return B460800;
194982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        case 500000:
195982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            return B500000;
196982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        case 576000:
197982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            return B576000;
198982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        case 921600:
199982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            return B921600;
200982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        case 1000000:
201982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            return B1000000;
202982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        case 1152000:
203982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            return B1152000;
204982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        case 1500000:
205982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            return B1500000;
206982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        case 2000000:
207982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            return B2000000;
208982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#ifdef B2500000
209982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        case 2500000:
210982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            return B2500000;
211982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#endif
212982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#ifdef B3000000
213982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        case 3000000:
214982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            return B3000000;
215982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#endif
216982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#ifdef B3500000
217982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        case 3500000:
218982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            return B3500000;
219982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#endif
220982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#ifdef B4000000
221982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        case 4000000:
222982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            return B4000000;
223982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#endif
224982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        default:
225982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            return B57600;
226982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    }
227982edd19a092114c479134cb16e0af54730edf1fPrashant Malani}
228982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
229982edd19a092114c479134cb16e0af54730edf1fPrashant Malaniint set_speed(int fd, struct termios *ti, int speed)
230982edd19a092114c479134cb16e0af54730edf1fPrashant Malani{
231982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (cfsetospeed(ti, uart_speed(speed)) < 0)
232982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        return -errno;
233982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
234982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (cfsetispeed(ti, uart_speed(speed)) < 0)
235982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        return -errno;
236982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
237982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (tcsetattr(fd, TCSANOW, ti) < 0)
238982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        return -errno;
239982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
240982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    return 0;
241982edd19a092114c479134cb16e0af54730edf1fPrashant Malani}
242982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
243982edd19a092114c479134cb16e0af54730edf1fPrashant Malanistatic void load_hci_ps_hdr(uint8_t *cmd, uint8_t ps_op, int len, int index)
244982edd19a092114c479134cb16e0af54730edf1fPrashant Malani{
245982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    hci_command_hdr *ch = (void *)cmd;
246982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
247982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    ch->opcode = htobs(cmd_opcode_pack(HCI_VENDOR_CMD_OGF,
248982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        HCI_PS_CMD_OCF));
249982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    ch->plen = len + PS_HDR_LEN;
250982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    cmd += HCI_COMMAND_HDR_SIZE;
251982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
252982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    cmd[0] = ps_op;
253982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    cmd[1] = index;
254982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    cmd[2] = index >> 8;
255982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    cmd[3] = len;
256982edd19a092114c479134cb16e0af54730edf1fPrashant Malani}
257982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
258982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
259982edd19a092114c479134cb16e0af54730edf1fPrashant Malanistatic int read_ps_event(uint8_t *event, uint16_t ocf)
260982edd19a092114c479134cb16e0af54730edf1fPrashant Malani{
261982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    hci_event_hdr *eh;
262982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    uint16_t opcode = htobs(cmd_opcode_pack(HCI_VENDOR_CMD_OGF, ocf));
263982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
264982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    event++;
265982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
266982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    eh = (void *)event;
267982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    event += HCI_EVENT_HDR_SIZE;
268982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
269982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (eh->evt == EVT_CMD_COMPLETE) {
270982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        evt_cmd_complete *cc = (void *)event;
271982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
272982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        event += EVT_CMD_COMPLETE_SIZE;
273982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
274982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        if (cc->opcode == opcode && event[0] == HCI_EV_SUCCESS)
275982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            return 0;
276982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        else
277982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            return -EILSEQ;
278982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    }
279982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
280982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    return -EILSEQ;
281982edd19a092114c479134cb16e0af54730edf1fPrashant Malani}
282982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
283982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define PS_WRITE           1
284982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define PS_RESET           2
285982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define WRITE_PATCH        8
286982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define ENABLE_PATCH       11
287982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
288982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define HCI_PS_CMD_HDR_LEN 7
289982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
290982edd19a092114c479134cb16e0af54730edf1fPrashant Malanistatic int write_cmd(int fd, uint8_t *buffer, int len)
291982edd19a092114c479134cb16e0af54730edf1fPrashant Malani{
292982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    uint8_t *event;
293982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    int err;
294982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
295982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    err = send_hci_cmd_sync(fd, buffer, len, &event);
296982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (err < 0)
297982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        return err;
298982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
299982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    err = read_ps_event(event, HCI_PS_CMD_OCF);
300982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
301982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    free(event);
302982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
303982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    return err;
304982edd19a092114c479134cb16e0af54730edf1fPrashant Malani}
305982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
306982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define PS_RESET_PARAM_LEN 6
307982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define PS_RESET_CMD_LEN   (HCI_PS_CMD_HDR_LEN + PS_RESET_PARAM_LEN)
308982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
309982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define PS_ID_MASK         0xFF
310982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
311982edd19a092114c479134cb16e0af54730edf1fPrashant Malani/* Sends PS commands using vendor specficic HCI commands */
312982edd19a092114c479134cb16e0af54730edf1fPrashant Malanistatic int write_ps_cmd(int fd, uint8_t opcode, uint32_t ps_param)
313982edd19a092114c479134cb16e0af54730edf1fPrashant Malani{
314982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    uint8_t cmd[HCI_MAX_CMD_SIZE];
315982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    uint32_t i;
316982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
317982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    switch (opcode) {
318982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        case ENABLE_PATCH:
319982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            load_hci_ps_hdr(cmd, opcode, 0, 0x00);
320982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
321982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            if (write_cmd(fd, cmd, HCI_PS_CMD_HDR_LEN) < 0)
322982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                return -EILSEQ;
323982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            break;
324982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
325982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        case PS_RESET:
326982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            load_hci_ps_hdr(cmd, opcode, PS_RESET_PARAM_LEN, 0x00);
327982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
328982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            cmd[7] = 0x00;
329982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            cmd[PS_RESET_CMD_LEN - 2] = ps_param & PS_ID_MASK;
330982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            cmd[PS_RESET_CMD_LEN - 1] = (ps_param >> 8) & PS_ID_MASK;
331982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
332982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            if (write_cmd(fd, cmd, PS_RESET_CMD_LEN) < 0)
333982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                return -EILSEQ;
334982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            break;
335982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
336982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        case PS_WRITE:
337982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            for (i = 0; i < ps_param; i++) {
338982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                load_hci_ps_hdr(cmd, opcode, ps_list[i].len,
339982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                ps_list[i].id);
340982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
341982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                memcpy(&cmd[HCI_PS_CMD_HDR_LEN], ps_list[i].data,
342982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                ps_list[i].len);
343982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
344982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                if (write_cmd(fd, cmd, ps_list[i].len +
345982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                    HCI_PS_CMD_HDR_LEN) < 0)
346982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                    return -EILSEQ;
347982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            }
348982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            break;
349982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    }
350982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
351982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    return 0;
352982edd19a092114c479134cb16e0af54730edf1fPrashant Malani}
353982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
354982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define PS_ASIC_FILE    "PS_ASIC.pst"
355982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define PS_FPGA_FILE    "PS_FPGA.pst"
356982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define MAXPATHLEN  4096
357982edd19a092114c479134cb16e0af54730edf1fPrashant Malanistatic void get_ps_file_name(uint32_t devtype, uint32_t rom_version,char *path)
358982edd19a092114c479134cb16e0af54730edf1fPrashant Malani{
359982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    char *filename;
360982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
361982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (devtype == 0xdeadc0de)
362982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        filename = PS_ASIC_FILE;
363982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    else
364982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        filename = PS_FPGA_FILE;
365982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
366982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    snprintf(path, MAXPATHLEN, "%s%x/%s", FW_PATH, rom_version, filename);
367982edd19a092114c479134cb16e0af54730edf1fPrashant Malani}
368982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
369982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define PATCH_FILE        "RamPatch.txt"
370982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define FPGA_ROM_VERSION  0x99999999
371982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define ROM_DEV_TYPE      0xdeadc0de
372982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
373982edd19a092114c479134cb16e0af54730edf1fPrashant Malanistatic void get_patch_file_name(uint32_t dev_type, uint32_t rom_version,
374982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    uint32_t build_version, char *path)
375982edd19a092114c479134cb16e0af54730edf1fPrashant Malani{
376982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (rom_version == FPGA_ROM_VERSION && dev_type != ROM_DEV_TYPE
377982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            &&dev_type != 0 && build_version == 1)
378982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        path[0] = '\0';
379982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    else
380982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        snprintf(path, MAXPATHLEN, "%s%x/%s", FW_PATH, rom_version, PATCH_FILE);
381982edd19a092114c479134cb16e0af54730edf1fPrashant Malani}
382982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
383982edd19a092114c479134cb16e0af54730edf1fPrashant Malanistatic int set_cntrlr_baud(int fd, int speed)
384982edd19a092114c479134cb16e0af54730edf1fPrashant Malani{
385982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    int baud;
386982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    struct timespec tm = { 0, 500000};
387982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    unsigned char cmd[MAX_CMD_LEN], rsp[HCI_MAX_EVENT_SIZE];
388982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    unsigned char *ptr = cmd + 1;
389982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    hci_command_hdr *ch = (void *)ptr;
390982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
391982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    cmd[0] = HCI_COMMAND_PKT;
392982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
393982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    /* set controller baud rate to user specified value */
394982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    ptr = cmd + 1;
395982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    ch->opcode = htobs(cmd_opcode_pack(HCI_VENDOR_CMD_OGF,
396982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    HCI_CHG_BAUD_CMD_OCF));
397982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    ch->plen = 2;
398982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    ptr += HCI_COMMAND_HDR_SIZE;
399982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
400982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    baud = speed/100;
401982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    ptr[0] = (char)baud;
402982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    ptr[1] = (char)(baud >> 8);
403982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
404982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (write(fd, cmd, WRITE_BAUD_CMD_LEN) != WRITE_BAUD_CMD_LEN) {
405982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        ALOGI("Failed to write change baud rate command");
406982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        return -ETIMEDOUT;
407982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    }
408982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
409982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    nanosleep(&tm, NULL);
410982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
411982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (read_hci_event(fd, rsp, sizeof(rsp)) < 0)
412982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        return -ETIMEDOUT;
413982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
414982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    return 0;
415982edd19a092114c479134cb16e0af54730edf1fPrashant Malani}
416982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
417982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define PS_UNDEF   0
418982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define PS_ID      1
419982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define PS_LEN     2
420982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define PS_DATA    3
421982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
422982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define PS_MAX_LEN         500
423982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define LINE_SIZE_MAX      (PS_MAX_LEN * 2)
424982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define ENTRY_PER_LINE     16
425982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
426982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define __check_comment(buf) (((buf)[0] == '/') && ((buf)[1] == '/'))
427982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define __skip_space(str)      while (*(str) == ' ') ((str)++)
428982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
429982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
430982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define __is_delim(ch) ((ch) == ':')
431982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define MAX_PREAMBLE_LEN 4
432982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
433982edd19a092114c479134cb16e0af54730edf1fPrashant Malani/* Parse PS entry preamble of format [X:X] for main type and subtype */
434982edd19a092114c479134cb16e0af54730edf1fPrashant Malanistatic int get_ps_type(char *ptr, int index, char *type, char *sub_type)
435982edd19a092114c479134cb16e0af54730edf1fPrashant Malani{
436982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    int i;
437982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    int delim = FALSE;
438982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
439982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (index > MAX_PREAMBLE_LEN)
440982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        return -EILSEQ;
441982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
442982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    for (i = 1; i < index; i++) {
443982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        if (__is_delim(ptr[i])) {
444982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            delim = TRUE;
445982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            continue;
446982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        }
447982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
448982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        if (isalpha(ptr[i])) {
449982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            if (delim == FALSE)
450982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                (*type) = toupper(ptr[i]);
451982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            else
452982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                (*sub_type)	= toupper(ptr[i]);
453982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        }
454982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    }
455982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
456982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    return 0;
457982edd19a092114c479134cb16e0af54730edf1fPrashant Malani}
458982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
459982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define ARRAY   'A'
460982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define STRING  'S'
461982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define DECIMAL 'D'
462982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define BINARY  'B'
463982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
464982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define PS_HEX           0
465982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define PS_DEC           1
466982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
467982edd19a092114c479134cb16e0af54730edf1fPrashant Malanistatic int get_input_format(char *buf, struct ps_entry_type *format)
468982edd19a092114c479134cb16e0af54730edf1fPrashant Malani{
469982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    char *ptr = NULL;
470982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    char type = '\0';
471982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    char sub_type = '\0';
472982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
473982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    format->type = PS_HEX;
474982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    format->array = TRUE;
475982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
476982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (strstr(buf, "[") != buf)
477982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        return 0;
478982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
479982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    ptr = strstr(buf, "]");
480982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (!ptr)
481982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        return -EILSEQ;
482982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
483982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (get_ps_type(buf, ptr - buf, &type, &sub_type) < 0)
484982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        return -EILSEQ;
485982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
486982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    /* Check is data type is of array */
487982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (type == ARRAY || sub_type == ARRAY)
488982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        format->array = TRUE;
489982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
490982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (type == STRING || sub_type == STRING)
491982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        format->array = FALSE;
492982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
493982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (type == DECIMAL || type == BINARY)
494982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        format->type = PS_DEC;
495982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    else
496982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        format->type = PS_HEX;
497982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
498982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    return 0;
499982edd19a092114c479134cb16e0af54730edf1fPrashant Malani}
500982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
501982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
502982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
503982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define UNDEFINED 0xFFFF
504982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
505982edd19a092114c479134cb16e0af54730edf1fPrashant Malanistatic unsigned int read_data_in_section(char *buf, struct ps_entry_type type)
506982edd19a092114c479134cb16e0af54730edf1fPrashant Malani{
507982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    char *ptr = buf;
508982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
509982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (!buf)
510982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        return UNDEFINED;
511982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
512982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (buf == strstr(buf, "[")) {
513982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        ptr = strstr(buf, "]");
514982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        if (!ptr)
515982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            return UNDEFINED;
516982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
517982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        ptr++;
518982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    }
519982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
520982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (type.type == PS_HEX && type.array != TRUE)
521982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        return strtol(ptr, NULL, 16);
522982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
523982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    return UNDEFINED;
524982edd19a092114c479134cb16e0af54730edf1fPrashant Malani}
525982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
526982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
527982edd19a092114c479134cb16e0af54730edf1fPrashant Malani/* Read PS entries as string, convert and add to Hex array */
528982edd19a092114c479134cb16e0af54730edf1fPrashant Malanistatic void update_tag_data(struct ps_cfg_entry *tag,
529982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    struct tag_info *info, const char *ptr)
530982edd19a092114c479134cb16e0af54730edf1fPrashant Malani{
531982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    char buf[3];
532982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
533982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    buf[2] = '\0';
534982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
535982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    strlcpy(buf, &ptr[info->char_cnt],sizeof(buf));
536982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    tag->data[info->byte_count] = strtol(buf, NULL, 16);
537982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    info->char_cnt += 3;
538982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    info->byte_count++;
539982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
540982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    strlcpy(buf, &ptr[info->char_cnt], sizeof(buf));
541982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    tag->data[info->byte_count] = strtol(buf, NULL, 16);
542982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    info->char_cnt += 3;
543982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    info->byte_count++;
544982edd19a092114c479134cb16e0af54730edf1fPrashant Malani}
545982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
546982edd19a092114c479134cb16e0af54730edf1fPrashant Malanistatic inline int update_char_count(const char *buf)
547982edd19a092114c479134cb16e0af54730edf1fPrashant Malani{
548982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    char *end_ptr;
549982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
550982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (strstr(buf, "[") == buf) {
551982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        end_ptr = strstr(buf, "]");
552982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        if (!end_ptr)
553982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            return 0;
554982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        else
555982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            return(end_ptr - buf) +	1;
556982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    }
557982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
558982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    return 0;
559982edd19a092114c479134cb16e0af54730edf1fPrashant Malani}
560982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
561982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define PS_HEX           0
562982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define PS_DEC           1
563982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
564982edd19a092114c479134cb16e0af54730edf1fPrashant Malanistatic int ath_parse_ps(FILE *stream)
565982edd19a092114c479134cb16e0af54730edf1fPrashant Malani{
566982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    char buf[LINE_SIZE_MAX + 1];
567982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    char *ptr;
568982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    uint8_t tag_cnt = 0;
569982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    int16_t byte_count = 0;
570982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    struct ps_entry_type format;
571982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    struct tag_info status = { 0, 0, 0, 0};
572982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
573982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    do {
574982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        int read_count;
575982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        struct ps_cfg_entry *tag;
576982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
577982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        ptr = fgets(buf, LINE_SIZE_MAX, stream);
578982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        if (!ptr)
579982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            break;
580982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
581982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        __skip_space(ptr);
582982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        if (__check_comment(ptr))
583982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            continue;
584982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
585982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        /* Lines with a '#' will be followed by new PS entry */
586982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        if (ptr == strstr(ptr, "#")) {
587982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            if (status.section != PS_UNDEF) {
588982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                return -EILSEQ;
589982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            } else {
590982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                status.section = PS_ID;
591982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                continue;
592982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            }
593982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        }
594982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
595982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        tag = &ps_list[tag_cnt];
596982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
597982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        switch (status.section) {
598982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            case PS_ID:
599982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                if (get_input_format(ptr, &format) < 0)
600982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                    return -EILSEQ;
601982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
602982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                tag->id = read_data_in_section(ptr, format);
603982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                status.section = PS_LEN;
604982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                break;
605982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
606982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            case PS_LEN:
607982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                if (get_input_format(ptr, &format) < 0)
608982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                    return -EILSEQ;
609982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
610982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                byte_count = read_data_in_section(ptr, format);
611982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                if (byte_count > PS_MAX_LEN)
612982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                    return -EILSEQ;
613982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
614982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                tag->len = byte_count;
615982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                tag->data = (uint8_t *)malloc(byte_count);
616982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
617982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                status.section = PS_DATA;
618982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                status.line_count = 0;
619982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                break;
620982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
621982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            case PS_DATA:
622982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            if (status.line_count == 0)
623982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                if (get_input_format(ptr, &format) < 0)
624982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                    return -EILSEQ;
625982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
626982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            __skip_space(ptr);
627982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
628982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            status.char_cnt = update_char_count(ptr);
629982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
630982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            read_count = (byte_count > ENTRY_PER_LINE) ?
631982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            ENTRY_PER_LINE : byte_count;
632982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
633982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            if (format.type == PS_HEX && format.array == TRUE) {
634982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                while (read_count > 0) {
635982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                    update_tag_data(tag, &status, ptr);
636982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                    read_count -= 2;
637982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                }
638982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
639982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                if (byte_count > ENTRY_PER_LINE)
640982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                    byte_count -= ENTRY_PER_LINE;
641982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                else
642982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                    byte_count = 0;
643982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            }
644982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
645982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            status.line_count++;
646982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
647982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            if (byte_count == 0)
648982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                memset(&status, 0x00, sizeof(struct tag_info));
649982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
650982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            if (status.section == PS_UNDEF)
651982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                tag_cnt++;
652982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
653982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            if (tag_cnt == MAX_TAGS)
654982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                return -EILSEQ;
655982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            break;
656982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        }
657982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    } while (ptr);
658982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
659982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    return tag_cnt;
660982edd19a092114c479134cb16e0af54730edf1fPrashant Malani}
661982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
662982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define PS_RAM_SIZE 2048
663982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
664982edd19a092114c479134cb16e0af54730edf1fPrashant Malanistatic int ps_config_download(int fd, int tag_count)
665982edd19a092114c479134cb16e0af54730edf1fPrashant Malani{
666982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (write_ps_cmd(fd, PS_RESET, PS_RAM_SIZE) < 0)
667982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        return -1;
668982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
669982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (tag_count > 0)
670982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        if (write_ps_cmd(fd, PS_WRITE, tag_count) < 0)
671982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            return -1;
672982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    return 0;
673982edd19a092114c479134cb16e0af54730edf1fPrashant Malani}
674982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
675982edd19a092114c479134cb16e0af54730edf1fPrashant Malanistatic int write_bdaddr(int pConfig, char *bdaddr)
676982edd19a092114c479134cb16e0af54730edf1fPrashant Malani{
677982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    uint8_t *event;
678982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    int err;
679982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    uint8_t cmd[13];
680982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    uint8_t *ptr = cmd;
681982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    hci_command_hdr *ch = (void *)cmd;
682982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
683982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    memset(cmd, 0, sizeof(cmd));
684982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
685982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    ch->opcode = htobs(cmd_opcode_pack(HCI_VENDOR_CMD_OGF,
686982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        HCI_PS_CMD_OCF));
687982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    ch->plen = 10;
688982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    ptr += HCI_COMMAND_HDR_SIZE;
689982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
690982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    ptr[0] = 0x01;
691982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    ptr[1] = 0x01;
692982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    ptr[2] = 0x00;
693982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    ptr[3] = 0x06;
694982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
695982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    convert_bdaddr(bdaddr, (char *)&ptr[4]);
696982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
697982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    err = send_hci_cmd_sync(pConfig, cmd, sizeof(cmd), &event);
698982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (err < 0)
699982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        return err;
700982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
701982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    err = read_ps_event(event, HCI_PS_CMD_OCF);
702982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
703982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    free(event);
704982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
705982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    return err;
706982edd19a092114c479134cb16e0af54730edf1fPrashant Malani}
707982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
708982edd19a092114c479134cb16e0af54730edf1fPrashant Malanistatic void write_bdaddr_from_file(int rom_version, int fd)
709982edd19a092114c479134cb16e0af54730edf1fPrashant Malani{
710982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    FILE *stream;
711982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    char bdaddr[PATH_MAX];
712982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    char bdaddr_file[PATH_MAX];
713982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
714982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    snprintf(bdaddr_file, MAXPATHLEN, "%s%x/%s",
715982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    FW_PATH, rom_version, BDADDR_FILE);
716982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
717982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    stream = fopen(bdaddr_file, "r");
718982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (!stream)
719982edd19a092114c479134cb16e0af54730edf1fPrashant Malani       return;
720982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
721982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (fgets(bdaddr, PATH_MAX - 1, stream))
722982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        write_bdaddr(fd, bdaddr);
723982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
724982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    fclose(stream);
725982edd19a092114c479134cb16e0af54730edf1fPrashant Malani}
726982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
727982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define HCI_EVT_CMD_CMPL_OPCODE                 3
728982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define HCI_EVT_CMD_CMPL_STATUS_RET_BYTE        5
729982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
730982edd19a092114c479134cb16e0af54730edf1fPrashant Malanivoid baswap(bdaddr_t *dst, const bdaddr_t *src)
731982edd19a092114c479134cb16e0af54730edf1fPrashant Malani{
732982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    register unsigned char *d = (unsigned char *) dst;
733982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    register const unsigned char *s = (const unsigned char *) src;
734982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    register int i;
735982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    for (i = 0; i < 6; i++)
736982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        d[i] = s[5-i];
737982edd19a092114c479134cb16e0af54730edf1fPrashant Malani}
738982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
739982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
740982edd19a092114c479134cb16e0af54730edf1fPrashant Malaniint str2ba(const char *str, bdaddr_t *ba)
741982edd19a092114c479134cb16e0af54730edf1fPrashant Malani{
742982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    uint8_t b[6];
743982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    const char *ptr = str;
744982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    int i;
745982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
746982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    for (i = 0; i < 6; i++) {
747982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        b[i] = (uint8_t) strtol(ptr, NULL, 16);
748982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        ptr = strchr(ptr, ':');
749982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        if (i != 5 && !ptr)
750982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            ptr = ":00:00:00:00:00";
751982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        ptr++;
752982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    }
753982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    baswap(ba, (bdaddr_t *) b);
754982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    return 0;
755982edd19a092114c479134cb16e0af54730edf1fPrashant Malani}
756982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
757982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define DEV_REGISTER      0x4FFC
758982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define GET_DEV_TYPE_OCF  0x05
759982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
760982edd19a092114c479134cb16e0af54730edf1fPrashant Malanistatic int get_device_type(int dev, uint32_t *code)
761982edd19a092114c479134cb16e0af54730edf1fPrashant Malani{
762982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    uint8_t cmd[8] = {0};
763982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    uint8_t *event;
764982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    uint32_t reg;
765982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    int err;
766982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    uint8_t *ptr = cmd;
767982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    hci_command_hdr *ch = (void *)cmd;
768982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
769982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    ch->opcode = htobs(cmd_opcode_pack(HCI_VENDOR_CMD_OGF,
770982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        GET_DEV_TYPE_OCF));
771982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    ch->plen = 5;
772982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    ptr += HCI_COMMAND_HDR_SIZE;
773982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
774982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    ptr[0] = (uint8_t)DEV_REGISTER;
775982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    ptr[1] = (uint8_t)DEV_REGISTER >> 8;
776982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    ptr[2] = (uint8_t)DEV_REGISTER >> 16;
777982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    ptr[3] = (uint8_t)DEV_REGISTER >> 24;
778982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    ptr[4] = 0x04;
779982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
780982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    err = send_hci_cmd_sync(dev, cmd, sizeof(cmd), &event);
781982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (err < 0)
782982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        return err;
783982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
784982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    err = read_ps_event(event, GET_DEV_TYPE_OCF);
785982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (err < 0)
786982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        goto cleanup;
787982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
788982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    reg = event[10];
789982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    reg = (reg << 8) | event[9];
790982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    reg = (reg << 8) | event[8];
791982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    reg = (reg << 8) | event[7];
792982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    *code = reg;
793982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
794982edd19a092114c479134cb16e0af54730edf1fPrashant Malanicleanup:
795982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    free(event);
796982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
797982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    return err;
798982edd19a092114c479134cb16e0af54730edf1fPrashant Malani}
799982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
800982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define GET_VERSION_OCF 0x1E
801982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
802982edd19a092114c479134cb16e0af54730edf1fPrashant Malanistatic int read_ath3k_version(int pConfig, uint32_t *rom_version,
803982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    uint32_t *build_version)
804982edd19a092114c479134cb16e0af54730edf1fPrashant Malani{
805982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    uint8_t cmd[3] = {0};
806982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    uint8_t *event;
807982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    int err;
808982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    int status;
809982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    hci_command_hdr *ch = (void *)cmd;
810982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
811982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    ch->opcode = htobs(cmd_opcode_pack(HCI_VENDOR_CMD_OGF,
812982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    GET_VERSION_OCF));
813982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    ch->plen = 0;
814982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
815982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    err = send_hci_cmd_sync(pConfig, cmd, sizeof(cmd), &event);
816982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (err < 0)
817982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        return err;
818982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
819982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    err = read_ps_event(event, GET_VERSION_OCF);
820982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (err < 0)
821982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        goto cleanup;
822982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
823982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    status = event[10];
824982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    status = (status << 8) | event[9];
825982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    status = (status << 8) | event[8];
826982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    status = (status << 8) | event[7];
827982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    *rom_version = status;
828982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
829982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    status = event[14];
830982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    status = (status << 8) | event[13];
831982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    status = (status << 8) | event[12];
832982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    status = (status << 8) | event[11];
833982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    *build_version = status;
834982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
835982edd19a092114c479134cb16e0af54730edf1fPrashant Malanicleanup:
836982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    free(event);
837982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
838982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    return err;
839982edd19a092114c479134cb16e0af54730edf1fPrashant Malani}
840982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
841982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define VERIFY_CRC   9
842982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define PS_REGION    1
843982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define PATCH_REGION 2
844982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
845982edd19a092114c479134cb16e0af54730edf1fPrashant Malanistatic int get_ath3k_crc(int dev)
846982edd19a092114c479134cb16e0af54730edf1fPrashant Malani{
847982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    uint8_t cmd[7] = {0};
848982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    uint8_t *event;
849982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    int err;
850982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
851982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    load_hci_ps_hdr(cmd, VERIFY_CRC, 0, PS_REGION | PATCH_REGION);
852982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
853982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    err = send_hci_cmd_sync(dev, cmd, sizeof(cmd), &event);
854982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (err < 0)
855982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        return err;
856982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    /* Send error code if CRC check patched */
857982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (read_ps_event(event, HCI_PS_CMD_OCF) >= 0)
858982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        err = -EILSEQ;
859982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
860982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    free(event);
861982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
862982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    return err;
863982edd19a092114c479134cb16e0af54730edf1fPrashant Malani}
864982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
865982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define SET_PATCH_RAM_ID        0x0D
866982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define SET_PATCH_RAM_CMD_SIZE  11
867982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define ADDRESS_LEN             4
868982edd19a092114c479134cb16e0af54730edf1fPrashant Malanistatic int set_patch_ram(int dev, char *patch_loc, int len)
869982edd19a092114c479134cb16e0af54730edf1fPrashant Malani{
870982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    int err;
871982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    uint8_t cmd[20] = {0};
872982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    int i, j;
873982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    char loc_byte[3];
874982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    uint8_t *event;
875982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    uint8_t *loc_ptr = &cmd[7];
876982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
877982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (!patch_loc)
878982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        return -1;
879982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
880982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    loc_byte[2] = '\0';
881982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
882982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    load_hci_ps_hdr(cmd, SET_PATCH_RAM_ID, ADDRESS_LEN, 0);
883982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
884982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    for (i = 0, j = 3; i < 4; i++, j--) {
885982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        loc_byte[0] = patch_loc[0];
886982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        loc_byte[1] = patch_loc[1];
887982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        loc_ptr[j] = strtol(loc_byte, NULL, 16);
888982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        patch_loc += 2;
889982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    }
890982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
891982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    err = send_hci_cmd_sync(dev, cmd, SET_PATCH_RAM_CMD_SIZE, &event);
892982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (err < 0)
893982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        return err;
894982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
895982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    err = read_ps_event(event, HCI_PS_CMD_OCF);
896982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
897982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    free(event);
898982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
899982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    return err;
900982edd19a092114c479134cb16e0af54730edf1fPrashant Malani}
901982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
902982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define PATCH_LOC_KEY    "DA:"
903982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define PATCH_LOC_STRING_LEN    8
904982edd19a092114c479134cb16e0af54730edf1fPrashant Malanistatic int ps_patch_download(int fd, FILE *stream)
905982edd19a092114c479134cb16e0af54730edf1fPrashant Malani{
906982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    char byte[3];
907982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    char ptr[MAX_PATCH_CMD + 1];
908982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    int byte_cnt;
909982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    int patch_count = 0;
910982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    char patch_loc[PATCH_LOC_STRING_LEN + 1];
911982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
912982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    byte[2] = '\0';
913982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
914982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    while (fgets(ptr, MAX_PATCH_CMD, stream)) {
915982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        if (strlen(ptr) <= 1)
916982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            continue;
917982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        else if (strstr(ptr, PATCH_LOC_KEY) == ptr) {
918982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            strlcpy(patch_loc, &ptr[sizeof(PATCH_LOC_KEY) - 1],
919982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                PATCH_LOC_STRING_LEN);
920982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            if (set_patch_ram(fd, patch_loc, sizeof(patch_loc)) < 0)
921982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                return -1;
922982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        } else if (isxdigit(ptr[0]))
923982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            break;
924982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        else
925982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        return -1;
926982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    }
927982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
928982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    byte_cnt = strtol(ptr, NULL, 16);
929982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
930982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    while (byte_cnt > 0) {
931982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        int i;
932982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        uint8_t cmd[HCI_MAX_CMD_SIZE] = {0};
933982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        struct patch_entry patch;
934982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
935982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        if (byte_cnt > MAX_PATCH_CMD)
936982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            patch.len = MAX_PATCH_CMD;
937982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        else
938982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            patch.len = byte_cnt;
939982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
940982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        for (i = 0; i < patch.len; i++) {
941982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            if (!fgets(byte, 3, stream))
942982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                return -1;
943982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
944982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            patch.data[i] = strtoul(byte, NULL, 16);
945982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        }
946982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
947982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        load_hci_ps_hdr(cmd, WRITE_PATCH, patch.len, patch_count);
948982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        memcpy(&cmd[HCI_PS_CMD_HDR_LEN], patch.data, patch.len);
949982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
950982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        if (write_cmd(fd, cmd, patch.len + HCI_PS_CMD_HDR_LEN) < 0)
951982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            return -1;
952982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
953982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        patch_count++;
954982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        byte_cnt = byte_cnt - MAX_PATCH_CMD;
955982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    }
956982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
957982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (write_ps_cmd(fd, ENABLE_PATCH, 0) < 0)
958982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        return -1;
959982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
960982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    return patch_count;
961982edd19a092114c479134cb16e0af54730edf1fPrashant Malani}
962982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
963982edd19a092114c479134cb16e0af54730edf1fPrashant Malanistatic int ath_ps_download(int fd)
964982edd19a092114c479134cb16e0af54730edf1fPrashant Malani{
965982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    int err = 0;
966982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    int tag_count;
967982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    int patch_count = 0;
968982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    uint32_t rom_version = 0;
969982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    uint32_t build_version = 0;
970982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    uint32_t dev_type = 0;
971982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    char patch_file[PATH_MAX];
972982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    char ps_file[PATH_MAX];
973982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    FILE *stream;
974982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
975982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    /*
976982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    * Verfiy firmware version. depending on it select the PS
977982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    * config file to download.
978982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    */
979982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (get_device_type(fd, &dev_type) < 0) {
980982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        err = -EILSEQ;
981982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        goto download_cmplete;
982982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    }
983982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
984982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (read_ath3k_version(fd, &rom_version, &build_version) < 0) {
985982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        err = -EILSEQ;
986982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        goto download_cmplete;
987982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    }
988982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
989982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    /* Do not download configuration if CRC passes */
990982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (get_ath3k_crc(fd) < 0) {
991982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        err = 0;
992982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        goto download_cmplete;
993982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    }
994982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
995982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    get_ps_file_name(dev_type, rom_version, ps_file);
996982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    get_patch_file_name(dev_type, rom_version, build_version, patch_file);
997982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
998982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    stream = fopen(ps_file, "r");
999982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (!stream) {
1000982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        ALOGI("firmware file open error:%s, ver:%x\n",ps_file, rom_version);
1001982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        if (rom_version == 0x1020201)
1002982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            err = 0;
1003982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        else
1004982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            err	= -EILSEQ;
1005982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        goto download_cmplete;
1006982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    }
1007982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    tag_count = ath_parse_ps(stream);
1008982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1009982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    fclose(stream);
1010982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1011982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (tag_count < 0) {
1012982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        err = -EILSEQ;
1013982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        goto download_cmplete;
1014982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    }
1015982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1016982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    /*
1017982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    * It is not necessary that Patch file be available,
1018982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    * continue with PS Operations if patch file is not available.
1019982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    */
1020982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (patch_file[0] == '\0')
1021982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        err = 0;
1022982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1023982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    stream = fopen(patch_file, "r");
1024982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (!stream)
1025982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        err = 0;
1026982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    else {
1027982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        patch_count = ps_patch_download(fd, stream);
1028982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        fclose(stream);
1029982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1030982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        if (patch_count < 0) {
1031982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            err = -EILSEQ;
1032982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            goto download_cmplete;
1033982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        }
1034982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    }
1035982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1036982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    err = ps_config_download(fd, tag_count);
1037982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1038982edd19a092114c479134cb16e0af54730edf1fPrashant Malanidownload_cmplete:
1039982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (!err)
1040982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        write_bdaddr_from_file(rom_version, fd);
1041982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1042982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    return err;
1043982edd19a092114c479134cb16e0af54730edf1fPrashant Malani}
1044982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1045982edd19a092114c479134cb16e0af54730edf1fPrashant Malaniint ath3k_init(int fd, int speed, int init_speed, char *bdaddr, struct termios *ti)
1046982edd19a092114c479134cb16e0af54730edf1fPrashant Malani{
1047982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    ALOGI(" %s ", __FUNCTION__);
1048982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1049982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    int r;
1050982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    int err = 0;
1051982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    struct timespec tm = { 0, 500000};
1052982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    unsigned char cmd[MAX_CMD_LEN] = {0};
1053982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    unsigned char rsp[HCI_MAX_EVENT_SIZE];
1054982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    unsigned char *ptr = cmd + 1;
1055982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    hci_command_hdr *ch = (void *)ptr;
1056982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    int flags = 0;
1057982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1058982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (ioctl(fd, TIOCMGET, &flags) < 0) {
1059982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        ALOGI("TIOCMGET failed in init\n");
1060982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        return -1;
1061982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    }
1062982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    flags |= TIOCM_RTS;
1063982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (ioctl(fd, TIOCMSET, &flags) < 0) {
1064982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        ALOGI("TIOCMSET failed in init: HW Flow-on error\n");
1065982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        return -1;
1066982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    }
1067982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1068982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    /* set both controller and host baud rate to maximum possible value */
1069982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    err = set_cntrlr_baud(fd, speed);
1070982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    ALOGI("set_cntrlr_baud : ret:%d \n", err);
1071982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (err < 0)
1072982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        return err;
1073982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1074982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    err = set_speed(fd, ti, speed);
1075982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (err < 0) {
1076982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        ALOGI("Can't set required baud rate");
1077982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        return err;
1078982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    }
1079982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1080982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    /* Download PS and patch */
1081982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    r = ath_ps_download(fd);
1082982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (r < 0) {
1083982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        ALOGI("Failed to Download configuration");
1084982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        err = -ETIMEDOUT;
1085982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        goto failed;
1086982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    }
1087982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1088982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    ALOGI("ath_ps_download is done\n");
1089982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1090982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    cmd[0] = HCI_COMMAND_PKT;
1091982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    /* Write BDADDR */
1092982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (bdaddr) {
1093982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        ch->opcode = htobs(cmd_opcode_pack(HCI_VENDOR_CMD_OGF,
1094982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        HCI_PS_CMD_OCF));
1095982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        ch->plen = 10;
1096982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        ptr += HCI_COMMAND_HDR_SIZE;
1097982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1098982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        ptr[0] = 0x01;
1099982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        ptr[1] = 0x01;
1100982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        ptr[2] = 0x00;
1101982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        ptr[3] = 0x06;
1102982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        str2ba(bdaddr, (bdaddr_t *)(ptr + 4));
1103982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1104982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        if (write(fd, cmd, WRITE_BDADDR_CMD_LEN) !=
1105982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                WRITE_BDADDR_CMD_LEN) {
1106982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            ALOGI("Failed to write BD_ADDR command\n");
1107982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            err = -ETIMEDOUT;
1108982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            goto failed;
1109982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        }
1110982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1111982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        if (read_hci_event(fd, rsp, sizeof(rsp)) < 0) {
1112982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            ALOGI("Failed to set BD_ADDR\n");
1113982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            err = -ETIMEDOUT;
1114982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            goto failed;
1115982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        }
1116982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    }
1117982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1118982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    /* Send HCI Reset */
1119982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    cmd[1] = 0x03;
1120982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    cmd[2] = 0x0C;
1121982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    cmd[3] = 0x00;
1122982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1123982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    r = write(fd, cmd, 4);
1124982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (r != 4) {
1125982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        err = -ETIMEDOUT;
1126982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        goto failed;
1127982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    }
1128982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1129982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    nanosleep(&tm, NULL);
1130982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (read_hci_event(fd, rsp, sizeof(rsp)) < 0) {
1131982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        err = -ETIMEDOUT;
1132982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        goto failed;
1133982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    }
1134982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1135982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    ALOGI("HCI Reset is done\n");
1136982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    err = set_cntrlr_baud(fd, speed);
1137982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (err < 0)
1138982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        ALOGI("set_cntrlr_baud0:%d,%d\n", speed, err);
1139982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1140982edd19a092114c479134cb16e0af54730edf1fPrashant Malanifailed:
1141982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (err < 0) {
1142982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        set_cntrlr_baud(fd, init_speed);
1143982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        set_speed(fd, ti, init_speed);
1144982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    }
1145982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1146982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    return err;
1147982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1148982edd19a092114c479134cb16e0af54730edf1fPrashant Malani}
1149982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define BTPROTO_HCI 1
1150982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1151982edd19a092114c479134cb16e0af54730edf1fPrashant Malani/* Open HCI device.
1152982edd19a092114c479134cb16e0af54730edf1fPrashant Malani * Returns device descriptor (dd). */
1153982edd19a092114c479134cb16e0af54730edf1fPrashant Malaniint hci_open_dev(int dev_id)
1154982edd19a092114c479134cb16e0af54730edf1fPrashant Malani{
1155982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    struct sockaddr_hci a;
1156982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    int dd, err;
1157982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1158982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    /* Create HCI socket */
1159982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    dd = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
1160982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (dd < 0)
1161982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        return dd;
1162982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1163982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    /* Bind socket to the HCI device */
1164982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    memset(&a, 0, sizeof(a));
1165982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    a.hci_family = AF_BLUETOOTH;
1166982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    a.hci_dev = dev_id;
1167982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (bind(dd, (struct sockaddr *) &a, sizeof(a)) < 0)
1168982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        goto failed;
1169982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1170982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    return dd;
1171982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1172982edd19a092114c479134cb16e0af54730edf1fPrashant Malanifailed:
1173982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    err = errno;
1174982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    close(dd);
1175982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    errno = err;
1176982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1177982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    return -1;
1178982edd19a092114c479134cb16e0af54730edf1fPrashant Malani}
1179982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1180982edd19a092114c479134cb16e0af54730edf1fPrashant Malaniint hci_close_dev(int dd)
1181982edd19a092114c479134cb16e0af54730edf1fPrashant Malani{
1182982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    return close(dd);
1183982edd19a092114c479134cb16e0af54730edf1fPrashant Malani}
1184982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1185982edd19a092114c479134cb16e0af54730edf1fPrashant Malani/* HCI functions that require open device
1186982edd19a092114c479134cb16e0af54730edf1fPrashant Malani * dd - Device descriptor returned by hci_open_dev. */
1187982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1188982edd19a092114c479134cb16e0af54730edf1fPrashant Malaniint hci_send_cmd(int dd, uint16_t ogf, uint16_t ocf, uint8_t plen, void *param)
1189982edd19a092114c479134cb16e0af54730edf1fPrashant Malani{
1190982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    uint8_t type = HCI_COMMAND_PKT;
1191982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    hci_command_hdr hc;
1192982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    struct iovec iv[3];
1193982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    int ivn;
1194982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1195982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    hc.opcode = htobs(cmd_opcode_pack(ogf, ocf));
1196982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    hc.plen= plen;
1197982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1198982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    iv[0].iov_base = &type;
1199982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    iv[0].iov_len  = 1;
1200982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    iv[1].iov_base = &hc;
1201982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    iv[1].iov_len  = HCI_COMMAND_HDR_SIZE;
1202982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    ivn = 2;
1203982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1204982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (plen) {
1205982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        iv[2].iov_base = param;
1206982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        iv[2].iov_len  = plen;
1207982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        ivn = 3;
1208982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    }
1209982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1210982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    while (writev(dd, iv, ivn) < 0) {
1211982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        if (errno == EAGAIN || errno == EINTR)
1212982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            continue;
1213982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        return -1;
1214982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    }
1215982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    return 0;
1216982edd19a092114c479134cb16e0af54730edf1fPrashant Malani}
1217982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1218982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define HCI_SLEEP_CMD_OCF     0x04
1219982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define TIOCSETD 0x5423
1220982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define HCIUARTSETFLAGS _IOW('U', 204, int)
1221982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define HCIUARTSETPROTO _IOW('U', 200, int)
1222982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define HCIUARTGETDEVICE _IOW('U', 202, int)
1223982edd19a092114c479134cb16e0af54730edf1fPrashant Malani/*
1224982edd19a092114c479134cb16e0af54730edf1fPrashant Malani * Atheros AR300x specific initialization post callback
1225982edd19a092114c479134cb16e0af54730edf1fPrashant Malani */
1226982edd19a092114c479134cb16e0af54730edf1fPrashant Malaniint ath3k_post(int fd, int pm)
1227982edd19a092114c479134cb16e0af54730edf1fPrashant Malani{
1228982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    int dev_id, dd;
1229982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    struct timespec tm = { 0, 50000};
1230982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1231982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    sleep(1);
1232982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1233982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    dev_id = ioctl(fd, HCIUARTGETDEVICE, 0);
1234982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (dev_id < 0) {
1235982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        perror("cannot get device id");
1236982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        return dev_id;
1237982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    }
1238982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1239982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    dd = hci_open_dev(dev_id);
1240982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (dd < 0) {
1241982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        perror("HCI device open failed");
1242982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        return dd;
1243982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    }
1244982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1245982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (ioctl(dd, HCIDEVUP, dev_id) < 0 && errno != EALREADY) {
1246982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        perror("hci down:Power management Disabled");
1247982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        hci_close_dev(dd);
1248982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        return -1;
1249982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    }
1250982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1251982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    /* send vendor specific command with Sleep feature Enabled */
1252982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (hci_send_cmd(dd, OGF_VENDOR_CMD, HCI_SLEEP_CMD_OCF, 1, &pm) < 0)
1253982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        perror("PM command failed, power management Disabled");
1254982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1255982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    nanosleep(&tm, NULL);
1256982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    hci_close_dev(dd);
1257982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1258982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    return 0;
1259982edd19a092114c479134cb16e0af54730edf1fPrashant Malani}
1260982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1261982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1262982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1263982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define FLOW_CTL    0x0001
1264982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define ENABLE_PM   1
1265982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#define DISABLE_PM  0
1266982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1267982edd19a092114c479134cb16e0af54730edf1fPrashant Malani/* Initialize UART driver */
1268982edd19a092114c479134cb16e0af54730edf1fPrashant Malanistatic int init_uart(char *dev, struct uart_t *u, int send_break, int raw)
1269982edd19a092114c479134cb16e0af54730edf1fPrashant Malani{
1270982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    ALOGI(" %s ", __FUNCTION__);
1271982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1272982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    struct termios ti;
1273982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1274982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    int i, fd;
1275982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    unsigned long flags = 0;
1276982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1277982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (raw)
1278982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        flags |= 1 << HCI_UART_RAW_DEVICE;
1279982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1280982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1281982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    fd = open(dev, O_RDWR | O_NOCTTY);
1282982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1283982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (fd < 0) {
1284982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        ALOGI("Can't open serial port");
1285982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        return -1;
1286982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    }
1287982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1288982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1289982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    tcflush(fd, TCIOFLUSH);
1290982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1291982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (tcgetattr(fd, &ti) < 0) {
1292982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        ALOGI("Can't get port settings: %d\n", errno);
1293982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        return -1;
1294982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    }
1295982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1296982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    cfmakeraw(&ti);
1297982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1298982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    ti.c_cflag |= CLOCAL;
1299982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (u->flags & FLOW_CTL)
1300982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        ti.c_cflag |= CRTSCTS;
1301982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    else
1302982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        ti.c_cflag &= ~CRTSCTS;
1303982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1304982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (tcsetattr(fd, TCSANOW, &ti) < 0) {
1305982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        ALOGI("Can't set port settings");
1306982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        return -1;
1307982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    }
1308982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1309982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (set_speed(fd, &ti, u->init_speed) < 0) {
1310982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        ALOGI("Can't set initial baud rate");
1311982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        return -1;
1312982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    }
1313982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1314982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    tcflush(fd, TCIOFLUSH);
1315982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1316982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (send_break) {
1317982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        tcsendbreak(fd, 0);
1318982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        usleep(500000);
1319982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    }
1320982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1321982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    ath3k_init(fd,u->speed,u->init_speed,u->bdaddr, &ti);
1322982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1323982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    ALOGI("Device setup complete\n");
1324982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1325982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1326982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    tcflush(fd, TCIOFLUSH);
1327982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1328982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    // Set actual baudrate
1329982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    /*
1330982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (set_speed(fd, &ti, u->speed) < 0) {
1331982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        perror("Can't set baud rate");
1332982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        return -1;
1333982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    }
1334982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1335982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    i = N_HCI;
1336982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (ioctl(fd, TIOCSETD, &i) < 0) {
1337982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        perror("Can't set line discipline");
1338982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        return -1;
1339982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    }
1340982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1341982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (flags && ioctl(fd, HCIUARTSETFLAGS, flags) < 0) {
1342982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        perror("Can't set UART flags");
1343982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        return -1;
1344982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    }
1345982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1346982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (ioctl(fd, HCIUARTSETPROTO, u->proto) < 0) {
1347982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        perror("Can't set device");
1348982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        return -1;
1349982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    }
1350982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1351982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#if !defined(SW_BOARD_HAVE_BLUETOOTH_RTK)
1352982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    ath3k_post(fd, u->pm);
1353982edd19a092114c479134cb16e0af54730edf1fPrashant Malani#endif
1354982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    */
1355982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1356982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    return fd;
1357982edd19a092114c479134cb16e0af54730edf1fPrashant Malani}
1358982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1359982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1360982edd19a092114c479134cb16e0af54730edf1fPrashant Malaniint hw_config_ath3k(char *port_name)
1361982edd19a092114c479134cb16e0af54730edf1fPrashant Malani{
1362982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    ALOGI(" %s ", __FUNCTION__);
1363982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    PSCounter=0;
1364982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    struct sigaction sa;
1365982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    struct uart_t u ;
1366982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    int n=0,send_break=0,raw=0;
1367982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1368982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    memset(&u, 0, sizeof(u));
1369982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    u.speed =3000000;
1370982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    u.init_speed =115200;
1371982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    u.flags |= FLOW_CTL;
1372982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    u.pm = DISABLE_PM;
1373982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1374982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    n = init_uart(port_name, &u, send_break, raw);
1375982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    if (n < 0) {
1376982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        ALOGI("Can't initialize device");
1377982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    }
1378982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1379982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    return n;
1380982edd19a092114c479134cb16e0af54730edf1fPrashant Malani}
1381982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1382982edd19a092114c479134cb16e0af54730edf1fPrashant Malanivoid lpm_set_ar3k(uint8_t pio, uint8_t action, uint8_t polarity)
1383982edd19a092114c479134cb16e0af54730edf1fPrashant Malani{
1384982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    int rc;
1385982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    int fd = -1;
1386982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    char buffer;
1387982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1388982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    ALOGI("lpm mode: %d  action: %d", pio, action);
1389982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1390982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    switch (pio)
1391982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    {
1392982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        case UPIO_LPM_MODE:
1393982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            if (upio_state[UPIO_LPM_MODE] == action)
1394982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            {
1395982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                ALOGI("LPM is %s already", lpm_mode[action]);
1396982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                return;
1397982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            }
1398982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1399982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            fd = open(VENDOR_LPM_PROC_NODE, O_WRONLY);
1400982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1401982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            if (fd < 0)
1402982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            {
1403982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                ALOGE("upio_set : open(%s) for write failed: %s (%d)",
1404982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                VENDOR_LPM_PROC_NODE, strerror(errno), errno);
1405982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                return;
1406982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            }
1407982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1408982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            if (action == UPIO_ASSERT)
1409982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            {
1410982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                buffer = '1';
1411982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            }
1412982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            else
1413982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            {
1414982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                buffer = '0';
1415982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            }
1416982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1417982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            if (write(fd, &buffer, 1) < 0)
1418982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            {
1419982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                ALOGE("upio_set : write(%s) failed: %s (%d)",
1420982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                VENDOR_LPM_PROC_NODE, strerror(errno),errno);
1421982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            }
1422982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            else
1423982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            {
1424982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                upio_state[UPIO_LPM_MODE] = action;
1425982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                ALOGI("LPM is set to %s", lpm_mode[action]);
1426982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            }
1427982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1428982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            if (fd >= 0)
1429982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                close(fd);
1430982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1431982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            break;
1432982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1433982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        case UPIO_BT_WAKE:
1434982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            /* UPIO_DEASSERT should be allowed because in Rx case assert occur
1435982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            * from the remote side where as deassert  will be initiated from Host
1436982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            */
1437982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            if ((action == UPIO_ASSERT) && (upio_state[UPIO_BT_WAKE] == action))
1438982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            {
1439982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                ALOGI("BT_WAKE is %s already", lpm_state[action]);
1440982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1441982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                return;
1442982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            }
1443982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1444982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            if (action == UPIO_DEASSERT)
1445982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                buffer = '0';
1446982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            else
1447982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                buffer = '1';
1448982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1449982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            fd = open(VENDOR_BTWRITE_PROC_NODE, O_WRONLY);
1450982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1451982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            if (fd < 0)
1452982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            {
1453982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                ALOGE("upio_set : open(%s) for write failed: %s (%d)",
1454982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                VENDOR_BTWRITE_PROC_NODE, strerror(errno), errno);
1455982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                return;
1456982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            }
1457982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1458982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            if (write(fd, &buffer, 1) < 0)
1459982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            {
1460982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                ALOGE("upio_set : write(%s) failed: %s (%d)",
1461982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                VENDOR_BTWRITE_PROC_NODE, strerror(errno),errno);
1462982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            }
1463982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            else
1464982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            {
1465982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                upio_state[UPIO_BT_WAKE] = action;
1466982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                ALOGI("BT_WAKE is set to %s", lpm_state[action]);
1467982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            }
1468982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1469982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            ALOGI("proc btwrite assertion");
1470982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1471982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            if (fd >= 0)
1472982edd19a092114c479134cb16e0af54730edf1fPrashant Malani                close(fd);
1473982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1474982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            break;
1475982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1476982edd19a092114c479134cb16e0af54730edf1fPrashant Malani        case UPIO_HOST_WAKE:
1477982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            ALOGI("upio_set: UPIO_HOST_WAKE");
1478982edd19a092114c479134cb16e0af54730edf1fPrashant Malani            break;
1479982edd19a092114c479134cb16e0af54730edf1fPrashant Malani    }
1480982edd19a092114c479134cb16e0af54730edf1fPrashant Malani
1481982edd19a092114c479134cb16e0af54730edf1fPrashant Malani}
1482