summaryrefslogtreecommitdiff
path: root/src/upio.c (plain)
blob: d32f334443616c0c6e84ae72c500cc44ac108e38
1/******************************************************************************
2 *
3 * Copyright (C) 2009-2012 Broadcom Corporation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19/******************************************************************************
20 *
21 * Filename: upio.c
22 *
23 * Description: Contains I/O functions, like
24 * rfkill control
25 * BT_WAKE/HOST_WAKE control
26 *
27 ******************************************************************************/
28
29#define LOG_TAG "bt_upio"
30
31#include <utils/Log.h>
32#include <fcntl.h>
33#include <errno.h>
34#include <cutils/properties.h>
35#include "bt_vendor_brcm.h"
36#include "upio.h"
37#include "userial_vendor.h"
38
39/******************************************************************************
40** Constants & Macros
41******************************************************************************/
42
43#ifndef UPIO_DBG
44#define UPIO_DBG FALSE
45#endif
46
47#if (UPIO_DBG == TRUE)
48#define UPIODBG(param, ...) {ALOGD(param, ## __VA_ARGS__);}
49#else
50#define UPIODBG(param, ...) {}
51#endif
52
53/******************************************************************************
54** Local type definitions
55******************************************************************************/
56
57/******************************************************************************
58** Static variables
59******************************************************************************/
60
61static uint8_t upio_state[UPIO_MAX_COUNT];
62static int rfkill_id = -1;
63static int bt_emul_enable = 0;
64static char *rfkill_state_path = NULL;
65
66/******************************************************************************
67** Static functions
68******************************************************************************/
69
70/* for friendly debugging outpout string */
71static char *lpm_state[] = {
72 "UNKNOWN",
73 "de-asserted",
74 "asserted"
75};
76
77/*****************************************************************************
78** Bluetooth On/Off Static Functions
79*****************************************************************************/
80static int is_emulator_context(void)
81{
82 char value[PROPERTY_VALUE_MAX];
83
84 property_get("ro.kernel.qemu", value, "0");
85 UPIODBG("is_emulator_context : %s", value);
86 if (strcmp(value, "1") == 0) {
87 return 1;
88 }
89 return 0;
90}
91
92static int is_rfkill_disabled(void)
93{
94 char value[PROPERTY_VALUE_MAX];
95
96 property_get("ro.rfkilldisabled", value, "0");
97 UPIODBG("is_rfkill_disabled ? [%s]", value);
98
99 if (strcmp(value, "1") == 0) {
100 return UPIO_BT_POWER_ON;
101 }
102
103 return UPIO_BT_POWER_OFF;
104}
105
106static int init_rfkill()
107{
108 char path[64];
109 char buf[16];
110 int fd, sz, id;
111
112 if (is_rfkill_disabled())
113 return -1;
114
115 for (id = 0; ; id++)
116 {
117 snprintf(path, sizeof(path), "/sys/class/rfkill/rfkill%d/type", id);
118 fd = open(path, O_RDONLY);
119 if (fd < 0)
120 {
121 ALOGE("init_rfkill : open(%s) failed: %s (%d)\n", \
122 path, strerror(errno), errno);
123 return -1;
124 }
125
126 sz = read(fd, &buf, sizeof(buf));
127 close(fd);
128
129 if (sz >= 9 && memcmp(buf, "bluetooth", 9) == 0)
130 {
131 rfkill_id = id;
132 break;
133 }
134 }
135
136 asprintf(&rfkill_state_path, "/sys/class/rfkill/rfkill%d/state", rfkill_id);
137 return 0;
138}
139
140/*****************************************************************************
141** LPM Static Functions
142*****************************************************************************/
143
144/*****************************************************************************
145** UPIO Interface Functions
146*****************************************************************************/
147
148/*******************************************************************************
149**
150** Function upio_init
151**
152** Description Initialization
153**
154** Returns None
155**
156*******************************************************************************/
157void upio_init(void)
158{
159 memset(upio_state, UPIO_UNKNOWN, UPIO_MAX_COUNT);
160}
161
162/*******************************************************************************
163**
164** Function upio_cleanup
165**
166** Description Clean up
167**
168** Returns None
169**
170*******************************************************************************/
171void upio_cleanup(void)
172{
173}
174
175/*******************************************************************************
176**
177** Function upio_set_bluetooth_power
178**
179** Description Interact with low layer driver to set Bluetooth power
180** on/off.
181**
182** Returns 0 : SUCCESS or Not-Applicable
183** <0 : ERROR
184**
185*******************************************************************************/
186int upio_set_bluetooth_power(int on)
187{
188 int sz;
189 int fd = -1;
190 int ret = -1;
191 char buffer = '0';
192
193 switch(on)
194 {
195 case UPIO_BT_POWER_OFF:
196 buffer = '0';
197 break;
198
199 case UPIO_BT_POWER_ON:
200 buffer = '1';
201 break;
202 }
203
204 if (is_emulator_context())
205 {
206 /* if new value is same as current, return -1 */
207 if (bt_emul_enable == on)
208 return ret;
209
210 UPIODBG("set_bluetooth_power [emul] %d", on);
211
212 bt_emul_enable = on;
213 return 0;
214 }
215
216 /* check if we have rfkill interface */
217 if (is_rfkill_disabled())
218 return 0;
219
220 if (rfkill_id == -1)
221 {
222 if (init_rfkill())
223 return ret;
224 }
225
226 fd = open(rfkill_state_path, O_WRONLY);
227
228 if (fd < 0)
229 {
230 ALOGE("set_bluetooth_power : open(%s) for write failed: %s (%d)",
231 rfkill_state_path, strerror(errno), errno);
232 return ret;
233 }
234
235 sz = write(fd, &buffer, 1);
236
237 if (sz < 0) {
238 ALOGE("set_bluetooth_power : write(%s) failed: %s (%d)",
239 rfkill_state_path, strerror(errno),errno);
240 }
241 else
242 ret = 0;
243
244 if (fd >= 0)
245 close(fd);
246
247 return ret;
248}
249
250
251/*******************************************************************************
252**
253** Function upio_set
254**
255** Description Set i/o based on polarity
256**
257** Returns None
258**
259*******************************************************************************/
260void upio_set(uint8_t pio, uint8_t action, uint8_t polarity)
261{
262 int rc;
263
264 switch (pio)
265 {
266 case UPIO_BT_WAKE:
267
268 if (upio_state[UPIO_BT_WAKE] == action)
269 {
270 UPIODBG("BT_WAKE is %s already", lpm_state[action]);
271 return;
272 }
273
274 upio_state[UPIO_BT_WAKE] = action;
275
276 /****************************************
277 * !!! TODO !!!
278 *
279 * === Custom Porting Required ===
280 *
281 * Platform dependent user-to-kernel
282 * interface is required to set output
283 * state of physical BT_WAKE pin.
284 ****************************************/
285#if (BT_WAKE_VIA_USERIAL_IOCTL == TRUE)
286 userial_vendor_ioctl( ( (action==UPIO_ASSERT) ? \
287 USERIAL_OP_ASSERT_BT_WAKE : USERIAL_OP_DEASSERT_BT_WAKE),\
288 NULL);
289#endif
290 break;
291
292 case UPIO_HOST_WAKE:
293 UPIODBG("upio_set: UPIO_HOST_WAKE");
294 break;
295 }
296}
297
298
299