static int op(bt_vendor_opcode_t opcode, void *param) { int retval = 0; BTVNDDBG("op for %d", opcode); switch(opcode) { case BT_VND_OP_POWER_CTRL: { /* [operation] * Power on or off the BT Controller. * [input param] * A pointer to int type with content of bt_vendor_power_state_t. * Typecasting conversion: (int *) param. * [return] * 0 - default, don't care. * [callback] * None. */ int *state = (int *) param; if (*state == BT_VND_PWR_OFF) upio_set_bluetooth_power(UPIO_BT_POWER_OFF); else if (*state == BT_VND_PWR_ON) { upio_set_bluetooth_power(UPIO_BT_POWER_ON); if(vnd_userial.android_bt_fw_download_sdio != 0) { ms_delay(50); upio_set_bluetooth_power(UPIO_BT_FIRMWARE_DOWNLOAD); ms_delay(300); } } } break; case BT_VND_OP_FW_CFG: { /* [operation] * Perform any vendor specific initialization or configuration * on the BT Controller. This is called before stack initialization. * [input param] * None. * [return] * 0 - default, don't care. * [callback] * Must call fwcfg_cb to notify the stack of the completion of vendor * specific initialization once it has been done. */ ALOGI("Download bt firmware:Will config hw!!"); hw_config_start(); } break; case BT_VND_OP_SCO_CFG: { /* [operation] * Perform any vendor specific SCO/PCM configuration on the BT Controller. * This is called after stack initialization. * [input param] * None. * [return] * 0 - default, don't care. * [callback] * Must call scocfg_cb to notify the stack of the completion of vendor * specific SCO configuration once it has been done. */ #if (SCO_CFG_INCLUDED == TRUE) // for now we don't use SCO, in future we shall add SCO specific init here // TODO: add SCO bus specific initialization here //hw_sco_config(); bt_vendor_cbacks->scocfg_cb(BT_VND_OP_RESULT_SUCCESS); //dummy #else retval = -1; #endif } break; case BT_VND_OP_USERIAL_OPEN: { /* [operation] * Open UART port on where the BT Controller is attached. * This is called before stack initialization. * [input param] * A pointer to int array type for open file descriptors. * The mapping of HCI channel to fd slot in the int array is given in * bt_vendor_hci_channels_t. * And, it requires the vendor lib to fill up the content before returning * the call. * Typecasting conversion: (int (*)[]) param. * [return] * Numbers of opened file descriptors. * Valid number: * 1 - CMD/EVT/ACL-In/ACL-Out via the same fd (e.g. UART) * 2 - CMD/EVT on one fd, and ACL-In/ACL-Out on the other fd * 4 - CMD, EVT, ACL-In, ACL-Out are on their individual fd * [callback] * None. */ int (*fd_array)[] = (int (*)[]) param; int fd, idx; ALOGI("<Atmel> :open uart"); fd = userial_vendor_open((tUSERIAL_CFG *) &userial_init_cfg); if (fd != -1) { for (idx=0; idx < CH_MAX; idx++) (*fd_array)[idx] = fd; retval = 1; } /* retval contains numbers of open fd of HCI channels */ } break; case BT_VND_OP_USERIAL_CLOSE: { /* [operation] * Close the previously opened UART port. * [input param] * None. * [return] * 0 - default, don't care. * [callback] * None. */ ALOGI("<Atmel> :close uart"); userial_vendor_close(); } break; case BT_VND_OP_GET_LPM_IDLE_TIMEOUT: { /* [operation] * Get the LPM idle timeout in milliseconds. * The stack uses this information to launch a timer delay before it * attempts to de-assert LPM WAKE signal once downstream HCI packet * has been delivered. * [input param] * A pointer to uint32_t type which is passed in by the stack. And, it * requires the vendor lib to fill up the content before returning * the call. * Typecasting conversion: (uint32_t *) param. * [return] * 0 - default, don't care. * [callback] * None. */ uint32_t *timeout_ms = (uint32_t *) param; *timeout_ms = hw_lpm_get_idle_timeout(); ALOGI("<Atmel> :returning timeout of %d ms", *timeout_ms); } break; case BT_VND_OP_LPM_SET_MODE: { /* [operation] * Enable or disable LPM mode on BT Controller. * [input param] * A pointer to uint8_t type with content of bt_vendor_lpm_mode_t. * Typecasting conversion: (uint8_t *) param. * [return] * 0 - default, don't care. * [callback] * Must call lpm_cb to notify the stack of the completion of LPM * disable/enable process once it has been done. */ uint8_t *mode = (uint8_t *) param; retval = hw_lpm_enable(*mode); } break; case BT_VND_OP_LPM_WAKE_SET_STATE: { /* [operation] * Assert or Deassert LPM WAKE on BT Controller. * [input param] * A pointer to uint8_t type with content of bt_vendor_lpm_wake_state_t. * Typecasting conversion: (uint8_t *) param. * [return] * 0 - default, don't care. * [callback] * None. */ uint8_t *state = (uint8_t *) param; uint8_t wake_assert = (*state == BT_VND_LPM_WAKE_ASSERT) ? \ TRUE : FALSE; hw_lpm_set_wake_state(wake_assert); } break; case BT_VND_OP_EPILOG: { // reply for epilog to avoid making bluedroid wait for EPILOG_TIMEOUT_MS before cleaning // This will make exit faster // We can do any exit specific commands here before close is called. ALOGI("Atmel: BT_VND_OP_EPILOG"); // Set the UART parameters of the running FW to be same as bootrom if(vnd_userial.android_bt_fw_download_uart != 0) { if(vnd_userial.fw_op_baudrate != vnd_userial.bootrom_baudrate) { uart_close=1; hw_config_update_ctrl_baud_rate(vnd_userial.bootrom_baudrate , 0); break; } }else if(vnd_userial.fw_op_baudrate != FW_DEFAULT_BAUD_RATE || vnd_userial.flow_control == 1){ uart_close=1; hw_config_update_ctrl_baud_rate(FW_DEFAULT_BAUD_RATE , 0); break; } bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_SUCCESS); } break; } return retval; }
/** Requested operations */ static int op(bt_vendor_opcode_t opcode, void *param) { int retval = 0; BTVNDDBG("op for %d", opcode); switch(opcode) { case BT_VND_OP_POWER_CTRL: { int *state = (int *) param; if (*state == BT_VND_PWR_OFF) upio_set_bluetooth_power(UPIO_BT_POWER_OFF); else if (*state == BT_VND_PWR_ON) upio_set_bluetooth_power(UPIO_BT_POWER_ON); } break; case BT_VND_OP_FW_CFG: { hw_config_start(); } break; case BT_VND_OP_SCO_CFG: { #if (SCO_CFG_INCLUDED == TRUE) hw_sco_config(); #else retval = -1; #endif } break; case BT_VND_OP_USERIAL_OPEN: { int (*fd_array)[] = (int (*)[]) param; int fd, idx; fd = userial_vendor_open((tUSERIAL_CFG *) &userial_init_cfg); if (fd != -1) { for (idx=0; idx < CH_MAX; idx++) (*fd_array)[idx] = fd; retval = 1; } /* retval contains numbers of open fd of HCI channels */ } break; case BT_VND_OP_USERIAL_CLOSE: { userial_vendor_close(); } break; case BT_VND_OP_GET_LPM_IDLE_TIMEOUT: { uint32_t *timeout_ms = (uint32_t *) param; *timeout_ms = hw_lpm_get_idle_timeout(); } break; case BT_VND_OP_LPM_SET_MODE: { uint8_t *mode = (uint8_t *) param; retval = hw_lpm_enable(*mode); } break; case BT_VND_OP_LPM_WAKE_SET_STATE: { uint8_t *state = (uint8_t *) param; uint8_t wake_assert = (*state == BT_VND_LPM_WAKE_ASSERT) ? \ TRUE : FALSE; hw_lpm_set_wake_state(wake_assert); } break; case BT_VND_OP_EPILOG: { #if (HW_END_WITH_HCI_RESET == FALSE) if (bt_vendor_cbacks) { bt_vendor_cbacks->epilog_cb(BT_VND_OP_RESULT_SUCCESS); } #else hw_epilog_process(); #endif } break; } return retval; }