#include #include #include #include #include #include #include #include #include #include "devices/detect.h" #include "devices/tab5_headphone_detect.h" #include "devices/tab5_keyboard.h" #include "devices/tab5_power_control.h" #include "devices/tab_5_camera.h" constexpr auto* TAG = "Tab5"; // PI4IOE5V6408-0 (0x43) bit 1 constexpr auto GPIO_EXP0_PIN_SPEAKER_ENABLE = 1; // PI4IOE5V6408-0 (0x43) bit 7 constexpr auto GPIO_EXP0_PIN_HEADPHONE_DETECT = 7; static void tab5_init_expander0(Device* io_expander0) { // Speaker and heapdhone pins are managed at runtime, so we can't have them as a hog in the dts file // We have to init them manually. auto* speaker_enable_pin = gpio_descriptor_acquire(io_expander0, GPIO_EXP0_PIN_SPEAKER_ENABLE, GPIO_FLAG_DIRECTION_OUTPUT, GPIO_OWNER_GPIO); check(speaker_enable_pin); auto* headphone_detect_pin = gpio_descriptor_acquire(io_expander0, GPIO_EXP0_PIN_HEADPHONE_DETECT, GPIO_FLAG_DIRECTION_INPUT, GPIO_OWNER_GPIO); check(headphone_detect_pin); gpio_descriptor_set_level(speaker_enable_pin, false); gpio_descriptor_release(speaker_enable_pin); gpio_descriptor_release(headphone_detect_pin); } static void tab5_enable_speaker_amp(Device* io_expander0) { auto* speaker_enable_pin = gpio_descriptor_acquire(io_expander0, GPIO_EXP0_PIN_SPEAKER_ENABLE, GPIO_FLAG_DIRECTION_OUTPUT, GPIO_OWNER_GPIO); check(speaker_enable_pin, "Failed to acquire speaker enable pin"); error_t error = gpio_descriptor_set_level(speaker_enable_pin, true); gpio_descriptor_release(speaker_enable_pin); if (error != ERROR_NONE) { LOG_E(TAG, "Failed to enable amplifier: %s", error_to_string(error)); } } // Fires for every device's start/stop in the system; initializes io_expander0's pins and enables // the speaker amplifier once io_expander0 itself has started. static void on_io_expander0_started(Device* device, DeviceEvent event, void* context) { (void)context; static bool did_init = false; if (did_init || event != DEVICE_EVENT_STARTED || strcmp(device->name, "io_expander0") != 0) { return; } did_init = true; tab5_init_expander0(device); tab5_enable_speaker_amp(device); } extern "C" { static error_t start() { tab5_detect_start(); tab5_camera_init(); device_listener_add(on_io_expander0_started, nullptr); tab5_headphone_detect_start(); return ERROR_NONE; } static error_t stop() { tab5_headphone_detect_stop(); device_listener_remove(on_io_expander0_started); tab5_detect_stop(); return ERROR_NONE; } static Driver* const tab5_drivers[] = { &tab5_keyboard_driver, &tab5_power_control_driver, nullptr }; Module m5stack_tab5_module = { .name = "m5stack-tab5", .start = start, .stop = stop, .drivers = tab5_drivers }; }