Commit d4de578a authored by Benjamin Tissoires's avatar Benjamin Tissoires

Merge branch 'for-6.6/wacom' into for-linus

Battery fixes by Aaron Armstrong Skomra
parents d5c04a72 55ab9b2c
...@@ -150,6 +150,7 @@ struct wacom_remote { ...@@ -150,6 +150,7 @@ struct wacom_remote {
struct input_dev *input; struct input_dev *input;
bool registered; bool registered;
struct wacom_battery battery; struct wacom_battery battery;
ktime_t active_time;
} remotes[WACOM_MAX_REMOTES]; } remotes[WACOM_MAX_REMOTES];
}; };
......
...@@ -1997,7 +1997,7 @@ static int wacom_initialize_remotes(struct wacom *wacom) ...@@ -1997,7 +1997,7 @@ static int wacom_initialize_remotes(struct wacom *wacom)
spin_lock_init(&remote->remote_lock); spin_lock_init(&remote->remote_lock);
error = kfifo_alloc(&remote->remote_fifo, error = kfifo_alloc(&remote->remote_fifo,
5 * sizeof(struct wacom_remote_data), 5 * sizeof(struct wacom_remote_work_data),
GFP_KERNEL); GFP_KERNEL);
if (error) { if (error) {
hid_err(wacom->hdev, "failed allocating remote_fifo\n"); hid_err(wacom->hdev, "failed allocating remote_fifo\n");
...@@ -2523,6 +2523,18 @@ static void wacom_wireless_work(struct work_struct *work) ...@@ -2523,6 +2523,18 @@ static void wacom_wireless_work(struct work_struct *work)
return; return;
} }
static void wacom_remote_destroy_battery(struct wacom *wacom, int index)
{
struct wacom_remote *remote = wacom->remote;
if (remote->remotes[index].battery.battery) {
devres_release_group(&wacom->hdev->dev,
&remote->remotes[index].battery.bat_desc);
remote->remotes[index].battery.battery = NULL;
remote->remotes[index].active_time = 0;
}
}
static void wacom_remote_destroy_one(struct wacom *wacom, unsigned int index) static void wacom_remote_destroy_one(struct wacom *wacom, unsigned int index)
{ {
struct wacom_remote *remote = wacom->remote; struct wacom_remote *remote = wacom->remote;
...@@ -2537,9 +2549,7 @@ static void wacom_remote_destroy_one(struct wacom *wacom, unsigned int index) ...@@ -2537,9 +2549,7 @@ static void wacom_remote_destroy_one(struct wacom *wacom, unsigned int index)
remote->remotes[i].registered = false; remote->remotes[i].registered = false;
spin_unlock_irqrestore(&remote->remote_lock, flags); spin_unlock_irqrestore(&remote->remote_lock, flags);
if (remote->remotes[i].battery.battery) wacom_remote_destroy_battery(wacom, i);
devres_release_group(&wacom->hdev->dev,
&remote->remotes[i].battery.bat_desc);
if (remote->remotes[i].group.name) if (remote->remotes[i].group.name)
devres_release_group(&wacom->hdev->dev, devres_release_group(&wacom->hdev->dev,
...@@ -2547,7 +2557,6 @@ static void wacom_remote_destroy_one(struct wacom *wacom, unsigned int index) ...@@ -2547,7 +2557,6 @@ static void wacom_remote_destroy_one(struct wacom *wacom, unsigned int index)
remote->remotes[i].serial = 0; remote->remotes[i].serial = 0;
remote->remotes[i].group.name = NULL; remote->remotes[i].group.name = NULL;
remote->remotes[i].battery.battery = NULL;
wacom->led.groups[i].select = WACOM_STATUS_UNKNOWN; wacom->led.groups[i].select = WACOM_STATUS_UNKNOWN;
} }
} }
...@@ -2632,6 +2641,9 @@ static int wacom_remote_attach_battery(struct wacom *wacom, int index) ...@@ -2632,6 +2641,9 @@ static int wacom_remote_attach_battery(struct wacom *wacom, int index)
if (remote->remotes[index].battery.battery) if (remote->remotes[index].battery.battery)
return 0; return 0;
if (!remote->remotes[index].active_time)
return 0;
if (wacom->led.groups[index].select == WACOM_STATUS_UNKNOWN) if (wacom->led.groups[index].select == WACOM_STATUS_UNKNOWN)
return 0; return 0;
...@@ -2647,17 +2659,19 @@ static void wacom_remote_work(struct work_struct *work) ...@@ -2647,17 +2659,19 @@ static void wacom_remote_work(struct work_struct *work)
{ {
struct wacom *wacom = container_of(work, struct wacom, remote_work); struct wacom *wacom = container_of(work, struct wacom, remote_work);
struct wacom_remote *remote = wacom->remote; struct wacom_remote *remote = wacom->remote;
struct wacom_remote_data data; ktime_t kt = ktime_get();
struct wacom_remote_work_data remote_work_data;
unsigned long flags; unsigned long flags;
unsigned int count; unsigned int count;
u32 serial; u32 work_serial;
int i; int i;
spin_lock_irqsave(&remote->remote_lock, flags); spin_lock_irqsave(&remote->remote_lock, flags);
count = kfifo_out(&remote->remote_fifo, &data, sizeof(data)); count = kfifo_out(&remote->remote_fifo, &remote_work_data,
sizeof(remote_work_data));
if (count != sizeof(data)) { if (count != sizeof(remote_work_data)) {
hid_err(wacom->hdev, hid_err(wacom->hdev,
"workitem triggered without status available\n"); "workitem triggered without status available\n");
spin_unlock_irqrestore(&remote->remote_lock, flags); spin_unlock_irqrestore(&remote->remote_lock, flags);
...@@ -2670,10 +2684,14 @@ static void wacom_remote_work(struct work_struct *work) ...@@ -2670,10 +2684,14 @@ static void wacom_remote_work(struct work_struct *work)
spin_unlock_irqrestore(&remote->remote_lock, flags); spin_unlock_irqrestore(&remote->remote_lock, flags);
for (i = 0; i < WACOM_MAX_REMOTES; i++) { for (i = 0; i < WACOM_MAX_REMOTES; i++) {
serial = data.remote[i].serial; work_serial = remote_work_data.remote[i].serial;
if (data.remote[i].connected) { if (work_serial) {
if (kt - remote->remotes[i].active_time > WACOM_REMOTE_BATTERY_TIMEOUT
&& remote->remotes[i].active_time != 0)
wacom_remote_destroy_battery(wacom, i);
if (remote->remotes[i].serial == serial) { if (remote->remotes[i].serial == work_serial) {
wacom_remote_attach_battery(wacom, i); wacom_remote_attach_battery(wacom, i);
continue; continue;
} }
...@@ -2681,7 +2699,7 @@ static void wacom_remote_work(struct work_struct *work) ...@@ -2681,7 +2699,7 @@ static void wacom_remote_work(struct work_struct *work)
if (remote->remotes[i].serial) if (remote->remotes[i].serial)
wacom_remote_destroy_one(wacom, i); wacom_remote_destroy_one(wacom, i);
wacom_remote_create_one(wacom, serial, i); wacom_remote_create_one(wacom, work_serial, i);
} else if (remote->remotes[i].serial) { } else if (remote->remotes[i].serial) {
wacom_remote_destroy_one(wacom, i); wacom_remote_destroy_one(wacom, i);
......
...@@ -1134,6 +1134,7 @@ static int wacom_remote_irq(struct wacom_wac *wacom_wac, size_t len) ...@@ -1134,6 +1134,7 @@ static int wacom_remote_irq(struct wacom_wac *wacom_wac, size_t len)
if (index < 0 || !remote->remotes[index].registered) if (index < 0 || !remote->remotes[index].registered)
goto out; goto out;
remote->remotes[i].active_time = ktime_get();
input = remote->remotes[index].input; input = remote->remotes[index].input;
input_report_key(input, BTN_0, (data[9] & 0x01)); input_report_key(input, BTN_0, (data[9] & 0x01));
...@@ -1196,22 +1197,20 @@ static void wacom_remote_status_irq(struct wacom_wac *wacom_wac, size_t len) ...@@ -1196,22 +1197,20 @@ static void wacom_remote_status_irq(struct wacom_wac *wacom_wac, size_t len)
struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac); struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac);
unsigned char *data = wacom_wac->data; unsigned char *data = wacom_wac->data;
struct wacom_remote *remote = wacom->remote; struct wacom_remote *remote = wacom->remote;
struct wacom_remote_data remote_data; struct wacom_remote_work_data remote_data;
unsigned long flags; unsigned long flags;
int i, ret; int i, ret;
if (data[0] != WACOM_REPORT_DEVICE_LIST) if (data[0] != WACOM_REPORT_DEVICE_LIST)
return; return;
memset(&remote_data, 0, sizeof(struct wacom_remote_data)); memset(&remote_data, 0, sizeof(struct wacom_remote_work_data));
for (i = 0; i < WACOM_MAX_REMOTES; i++) { for (i = 0; i < WACOM_MAX_REMOTES; i++) {
int j = i * 6; int j = i * 6;
int serial = (data[j+6] << 16) + (data[j+5] << 8) + data[j+4]; int serial = (data[j+6] << 16) + (data[j+5] << 8) + data[j+4];
bool connected = data[j+2];
remote_data.remote[i].serial = serial; remote_data.remote[i].serial = serial;
remote_data.remote[i].connected = connected;
} }
spin_lock_irqsave(&remote->remote_lock, flags); spin_lock_irqsave(&remote->remote_lock, flags);
......
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
#define WACOM_NAME_MAX 64 #define WACOM_NAME_MAX 64
#define WACOM_MAX_REMOTES 5 #define WACOM_MAX_REMOTES 5
#define WACOM_STATUS_UNKNOWN 255 #define WACOM_STATUS_UNKNOWN 255
#define WACOM_REMOTE_BATTERY_TIMEOUT 21000000000ll
/* packet length for individual models */ /* packet length for individual models */
#define WACOM_PKGLEN_BBFUN 9 #define WACOM_PKGLEN_BBFUN 9
...@@ -327,10 +328,9 @@ struct hid_data { ...@@ -327,10 +328,9 @@ struct hid_data {
ktime_t time_delayed; ktime_t time_delayed;
}; };
struct wacom_remote_data { struct wacom_remote_work_data {
struct { struct {
u32 serial; u32 serial;
bool connected;
} remote[WACOM_MAX_REMOTES]; } remote[WACOM_MAX_REMOTES];
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment