^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * @File ctimap.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * @Brief
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * This file contains the implementation of generic input mapper operations
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * for input mapper management.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * @Author Liu Chun
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * @Date May 23 2008
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "ctimap.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) int input_mapper_add(struct list_head *mappers, struct imapper *entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) int (*map_op)(void *, struct imapper *), void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) struct list_head *pos, *pre, *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) struct imapper *pre_ent, *pos_ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) head = mappers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) if (list_empty(head)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) entry->next = entry->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) map_op(data, entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) list_add(&entry->list, head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) list_for_each(pos, head) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) pos_ent = list_entry(pos, struct imapper, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) if (pos_ent->slot > entry->slot) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) /* found a position in list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) if (pos != head) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) pre = pos->prev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) if (pre == head)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) pre = head->prev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) __list_add(&entry->list, pos->prev, pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) pre = head->prev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) pos = head->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) list_add_tail(&entry->list, head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) pre_ent = list_entry(pre, struct imapper, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) pos_ent = list_entry(pos, struct imapper, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) entry->next = pos_ent->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) map_op(data, entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) pre_ent->next = entry->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) map_op(data, pre_ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) int input_mapper_delete(struct list_head *mappers, struct imapper *entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) int (*map_op)(void *, struct imapper *), void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) struct list_head *next, *pre, *head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) struct imapper *pre_ent, *next_ent;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) head = mappers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) if (list_empty(head))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) pre = (entry->list.prev == head) ? head->prev : entry->list.prev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) next = (entry->list.next == head) ? head->next : entry->list.next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) if (pre == &entry->list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) /* entry is the only one node in mappers list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) entry->next = entry->addr = entry->user = entry->slot = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) map_op(data, entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) list_del(&entry->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) pre_ent = list_entry(pre, struct imapper, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) next_ent = list_entry(next, struct imapper, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) pre_ent->next = next_ent->addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) map_op(data, pre_ent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) list_del(&entry->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) void free_input_mapper_list(struct list_head *head)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) struct imapper *entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct list_head *pos;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) while (!list_empty(head)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) pos = head->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) list_del(pos);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) entry = list_entry(pos, struct imapper, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) kfree(entry);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)