Example #1
0
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;
}
/*******************************************************************************
**
** Function          op
**
** Description       This is interface for bluedroid stack to libbt. It exposes
**                   several functionality to bluedroid stack.
**
** Returns           0 or -1
**
*******************************************************************************/
static int op(bt_vendor_opcode_t opcode, void *param)
{
    int retval = BT_VND_OP_RESULT_SUCCESS;

    BTVNDDBG("op for %d named: %s", opcode,dump_vendor_op(opcode));
    switch(opcode)
    {
        case BT_VND_OP_POWER_CTRL:
            {
                int *state = (int *) param;
                if (*state == BT_VND_PWR_OFF)
                {
                    //moved to userial_vendor_close()since TL power control is done with IOCTL
                    //which required fd before release fd.
                }
                else if (*state == BT_VND_PWR_ON)
                {
                    //power on done after fd acquired through userial_vendor_open()
                }
            }
            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
                bt_vendor_cbacks->scocfg_cb(BT_VND_OP_RESULT_SUCCESS);
                retval = -1;
#endif
            }
            break;

        case BT_VND_OP_USERIAL_OPEN:
            {
                int (*fd_array)[] = (int (*)[]) param;
                int fd, idx;
                fd = userial_vendor_open();
#if (INTEL_HSB_PLATFORM == TRUE)
                userial_vendor_configure_serial((tUSERIAL_CFG *)&userial_init_cfg, userial_init_cfg.baud);
#endif
                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 */
                if(retval)
                {
                    if(0 < upio_set_bluetooth_power(UPIO_BT_POWER_ON))
                      retval = -1;
                    else
                      retval = 1;
                }
            }
            break;

        case BT_VND_OP_USERIAL_CONFIG:
            {
                int baud_rate = STANDARD_BAUD, rt = 0;
                bt_vendor_baud_config_t baud_config = STANDARD_BAUD;
                if (param)
                    baud_config = *((int*) param);
                if (baud_config == STANDARD_BAUD)
                    baud_rate = 115200;
                else if (baud_config == HIGHER_BAUD)
                    baud_rate = hw_operation_baud;
                rt = userial_vendor_configure_serial\
                               ((tUSERIAL_CFG *)&userial_init_cfg, \
                                        line_speed_to_userial_baud(baud_rate));

                if(rt == 0)
                {
                    BTVNDDBG("baudrate changed to :%d", baud_rate);
                }
                else
                {
                    BTVNDDBG("failed to change baudrate:%d", baud_rate);
                }
            }
            break;
#if (BT_EN_VIA_USERIAL_IOCTL == TRUE)
        case BT_VND_OP_FW_DL_COMPLETE:
            {
                unsigned long fw_cfg_result = FW_SUCCESS;
                userial_vendor_ioctl(USERIAL_OP_FW_CFG_CMPL, \
                                                    (void*)&fw_cfg_result);
            }
            break;
        case BT_VND_OP_FW_DL_STATUS:
            {
                int on = UPIO_BT_POWER_ON;
                retval = userial_vendor_ioctl(USERIAL_OP_BT_EN, &on);
                ms_delay(100);
            }
            break;
#endif
        case BT_VND_OP_USERIAL_CLOSE:
            {
                upio_set_bluetooth_power(UPIO_BT_POWER_OFF);
                userial_vendor_close();
#ifdef BT_FM_MITIGATION
                bt_fm_deinit();
#endif
            }
            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;
                hw_lpm_enable(((mode)? BT_VND_LPM_ENABLE : BT_VND_LPM_DISABLE));
            }
            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;
#if (INTEL_AG6XX_UART == TRUE)
                if(lpm_is_enabled)
                {
                    upio_set_bt_wake_state(wake_assert);
                }
#endif
            }
            break;
#if (LNP_LPM_ENABLED == TRUE)
        case BT_VND_OP_LPM_SET_IDLE_STATE:
            {
                if(lpm_is_enabled)
                {
                   userial_vendor_ioctl(USERIAL_OP_LPM_SET_IDLE_STATE,
                                                    (void*)param);
                }
            }
            break;
#endif
#if (HW_END_WITH_HCI_RESET == TRUE)
        case BT_VND_OP_EPILOG:
            hw_epilog_process();
            break;
#endif
#if (A2DP_OFFLOAD_INCLUDED == TRUE)
        case BT_VND_OP_A2DP_STREAM_CONFIG:
            BTVNDDBG("op: BT_VND_BT_VND_OP_A2DP_STREAM_CONFIG");
            a2dp_offload_send_stream_config((A2DP_OFFLOAD_STREAM_CFG_PARAMS *)param);
            break;
        case BT_VND_OP_A2DP_SET_STREAM_STATE:
            BTVNDDBG("op: BT_VND_OP_A2DP_SET_STREAM_STATE");
            uint8_t *state = (uint8_t *) param;
            a2dp_offload_set_stream_state(*state);
            break;
#endif
        case BT_VND_OP_SET_AUDIO_STATE:
            // do nothing
            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;
}