/* * Copyright (c) 2019 Actions Semiconductor Co., Ltd * * SPDX-License-Identifier: Apache-2.0 */ /** * @file hotplug manager interface */ #if defined(CONFIG_SYS_LOG) #define SYS_LOG_NO_NEWLINE #ifdef SYS_LOG_DOMAIN #undef SYS_LOG_DOMAIN #endif #define SYS_LOG_DOMAIN "hotpug_manager" #endif #include #include #include #include #include #include #ifdef CONFIG_TWS #include "bt_manager.h" #endif static struct hotplug_manager_context_t hotplug_manager_context; static struct hotplug_manager_context_t *hotplug_manager; int hotplug_device_register(const struct hotplug_device_t *device) { const struct hotplug_device_t *temp_device = NULL; int free_index = -1; for (int i = 0; i < MAX_HOTPLUG_DEVICE_NUM; i++) { temp_device = hotplug_manager->device[i]; if (temp_device && temp_device->type == device->type) { return -EEXIST; } else if (!temp_device) { free_index = i; break; } } if (free_index != -1 && free_index < MAX_HOTPLUG_DEVICE_NUM) { hotplug_manager->device[free_index] = device; hotplug_manager->device_num++; } return 0; } int hotplug_device_unregister(const struct hotplug_device_t *device) { const struct hotplug_device_t *temp_device = NULL; for (int i = 0; i < MAX_HOTPLUG_DEVICE_NUM; i++) { temp_device = hotplug_manager->device[i]; if (temp_device && temp_device->type == device->type) { hotplug_manager->device[i] = NULL; hotplug_manager->device_num--; } } return 0; } int hotplug_event_report(int device_type, int device_state) { struct app_msg msg = {0}; msg.type = MSG_HOTPLUG_EVENT; msg.cmd = device_type; msg.value = device_state; SYS_LOG_INF("type: %d state: %d\n", device_type, device_state); return send_async_msg("main", &msg); } static int _hotplug_manager_work_handle(void) { int state = HOTPLUG_NONE; const struct hotplug_device_t *device = NULL; /**slave not report hot plug*/ #ifdef CONFIG_TWS if (bt_manager_tws_get_dev_role() == BTSRV_TWS_SLAVE) { return 0; } #endif for (int i = 0; i < MAX_HOTPLUG_DEVICE_NUM; i++) { device = hotplug_manager->device[i]; if (!device) continue; if (device->hotplug_detect) { state = device->hotplug_detect(); } if (state != HOTPLUG_NONE) { if (device->fs_process) { if (device->fs_process(state)) { continue; } } if (device->get_type) { hotplug_event_report(device->get_type(), state); } else { hotplug_event_report(device->type, state); } } } return 0; } int hotplug_manager_get_state(int hotplug_device_type) { int state = HOTPLUG_NONE; const struct hotplug_device_t *device = NULL; for (int i = 0; i < MAX_HOTPLUG_DEVICE_NUM; i++) { device = hotplug_manager->device[i]; if (device->type == hotplug_device_type) { state = device->get_state(); break; } } return state; } int hotplug_manager_init(void) { if (hotplug_manager) return -EEXIST; hotplug_manager = &hotplug_manager_context; memset(hotplug_manager, 0, sizeof(struct hotplug_manager_context_t)); #ifdef CONFIG_LINEIN_HOTPLUG hotplug_linein_init(); #endif #ifdef CONFIG_CARD_HOTPLUG hotplug_sdcard_init(); #endif #if defined(CONFIG_USB_HOTPLUG) hotplug_usb_init(); #endif #ifdef CONFIG_CHARGER_HOTPLUG hotplug_charger_init(); #endif sys_monitor_add_work(_hotplug_manager_work_handle); return 0; }