hiby: ability to add/remove input device

Required for dynamic inputs (like bluetooth).
Files are now opened with O_NONBLOCK, and inputs are automatically removed on poll errors.
Also added call to close all devices on power off.

Change-Id: I8991bdb881fdc00135d1fd5b01ac900c0b007aeb
This commit is contained in:
Roman Artiukhin 2026-04-11 18:30:34 +03:00 committed by Solomon Peachy
parent f4dc4d89dc
commit a496e01173
3 changed files with 75 additions and 22 deletions

View file

@ -21,6 +21,7 @@
****************************************************************************/
#include <poll.h>
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <linux/input.h>
@ -49,42 +50,60 @@
* Compute to angular velocity (degrees per second)
*/
#define NR_POLL_DESC 4
#define NR_POLL_DESC 5
static int num_devices = 0;
static struct pollfd poll_fds[NR_POLL_DESC];
void button_init_device(void)
void button_add_input_device(int i)
{
const char * const input_devs[NR_POLL_DESC] = {
"/dev/input/event0",
"/dev/input/event1",
"/dev/input/event2",
"/dev/input/event3",
};
for(int i = 0; i < NR_POLL_DESC; i++)
{
int fd = open(input_devs[i], O_RDONLY | O_CLOEXEC);
int fd = poll_fds[i].fd;
if (fd >= 0)
close(fd);
char path[32];
snprintf(path, sizeof(path), "/dev/input/event%d", i);
fd = open(path, O_RDONLY | O_CLOEXEC | O_NONBLOCK);
poll_fds[i].fd = fd >= 0 ? fd : -1;
if(fd >= 0)
{
poll_fds[num_devices].fd = fd;
poll_fds[num_devices].events = POLLIN;
poll_fds[num_devices].revents = 0;
num_devices++;
poll_fds[i].events = POLLIN;
poll_fds[i].revents = 0;
if (num_devices <= i)
num_devices = i + 1;
}
}
void button_init_device(void)
{
for(int i = 0; i < NR_POLL_DESC; i++)
{
poll_fds[i].fd = -1;
button_add_input_device(i);
}
}
void button_remove_input_device(int i)
{
int fd = poll_fds[i].fd;
if (fd < 0)
return;
if (i == num_devices - 1)
num_devices = i;
close(fd);
poll_fds[i].fd = -1;
}
void button_close_device(void)
{
/* close descriptors */
for(int i = 0; i < num_devices; i++)
{
close(poll_fds[i].fd);
}
num_devices = 0;
/* close descriptors */
for(int i = 0; i < NR_POLL_DESC; i++)
{
button_remove_input_device(i);
}
}
#ifdef BUTTON_DELAY_RELEASE
@ -261,6 +280,10 @@ int button_read_device(BDATA)
}
}
}
/* device was removed/disconnected — close it to stop poll returning POLLHUP forever */
else if (poll_fds[i].revents & (POLLERR | POLLHUP)) {
button_remove_input_device(i);
}
}
}

View file

@ -0,0 +1,28 @@
/***************************************************************************
* __________ __ ___
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
* Copyright (C) 2026 by Roman Artiukhin
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
****************************************************************************/
#ifndef __BUTTON_DEVINPUT_H__
#define __BUTTON_DEVINPUT_H__
void button_close_device(void);
void button_add_input_device(int i);
void button_remove_input_device(int i);
#endif

View file

@ -29,6 +29,7 @@
#include "font.h"
#include "power.h"
#include "button.h"
#include "button-devinput.h"
#include "backlight-target.h"
#include "lcd.h"
#include "filesystem-hosted.h"
@ -92,6 +93,7 @@ static void sig_handler(int sig, siginfo_t *siginfo, void *context)
void power_off(void)
{
backlight_hw_off();
button_close_device();
sync();
system("/sbin/poweroff");
while (1) {