18cc72361SWai Yew CHAY /** 28cc72361SWai Yew CHAY * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved. 38cc72361SWai Yew CHAY * 48cc72361SWai Yew CHAY * This source file is released under GPL v2 license (no other versions). 58cc72361SWai Yew CHAY * See the COPYING file included in the main directory of this source 68cc72361SWai Yew CHAY * distribution for the license terms and conditions. 78cc72361SWai Yew CHAY * 88cc72361SWai Yew CHAY * @File ctimap.c 98cc72361SWai Yew CHAY * 108cc72361SWai Yew CHAY * @Brief 118cc72361SWai Yew CHAY * This file contains the implementation of generic input mapper operations 128cc72361SWai Yew CHAY * for input mapper management. 138cc72361SWai Yew CHAY * 148cc72361SWai Yew CHAY * @Author Liu Chun 158cc72361SWai Yew CHAY * @Date May 23 2008 168cc72361SWai Yew CHAY * 178cc72361SWai Yew CHAY */ 188cc72361SWai Yew CHAY 198cc72361SWai Yew CHAY #include "ctimap.h" 208cc72361SWai Yew CHAY #include <linux/slab.h> 218cc72361SWai Yew CHAY 228cc72361SWai Yew CHAY int input_mapper_add(struct list_head *mappers, struct imapper *entry, 238cc72361SWai Yew CHAY int (*map_op)(void *, struct imapper *), void *data) 248cc72361SWai Yew CHAY { 258cc72361SWai Yew CHAY struct list_head *pos, *pre, *head; 268cc72361SWai Yew CHAY struct imapper *pre_ent, *pos_ent; 278cc72361SWai Yew CHAY 288cc72361SWai Yew CHAY head = mappers; 298cc72361SWai Yew CHAY 308cc72361SWai Yew CHAY if (list_empty(head)) { 318cc72361SWai Yew CHAY entry->next = entry->addr; 328cc72361SWai Yew CHAY map_op(data, entry); 338cc72361SWai Yew CHAY list_add(&entry->list, head); 348cc72361SWai Yew CHAY return 0; 358cc72361SWai Yew CHAY } 368cc72361SWai Yew CHAY 378cc72361SWai Yew CHAY list_for_each(pos, head) { 388cc72361SWai Yew CHAY pos_ent = list_entry(pos, struct imapper, list); 398cc72361SWai Yew CHAY if (pos_ent->slot > entry->slot) { 408cc72361SWai Yew CHAY /* found a position in list */ 418cc72361SWai Yew CHAY break; 428cc72361SWai Yew CHAY } 438cc72361SWai Yew CHAY } 448cc72361SWai Yew CHAY 458cc72361SWai Yew CHAY if (pos != head) { 468cc72361SWai Yew CHAY pre = pos->prev; 478cc72361SWai Yew CHAY if (pre == head) 488cc72361SWai Yew CHAY pre = head->prev; 498cc72361SWai Yew CHAY 508cc72361SWai Yew CHAY __list_add(&entry->list, pos->prev, pos); 518cc72361SWai Yew CHAY } else { 528cc72361SWai Yew CHAY pre = head->prev; 538cc72361SWai Yew CHAY pos = head->next; 548cc72361SWai Yew CHAY list_add_tail(&entry->list, head); 558cc72361SWai Yew CHAY } 568cc72361SWai Yew CHAY 578cc72361SWai Yew CHAY pre_ent = list_entry(pre, struct imapper, list); 588cc72361SWai Yew CHAY pos_ent = list_entry(pos, struct imapper, list); 598cc72361SWai Yew CHAY 608cc72361SWai Yew CHAY entry->next = pos_ent->addr; 618cc72361SWai Yew CHAY map_op(data, entry); 628cc72361SWai Yew CHAY pre_ent->next = entry->addr; 638cc72361SWai Yew CHAY map_op(data, pre_ent); 648cc72361SWai Yew CHAY 658cc72361SWai Yew CHAY return 0; 668cc72361SWai Yew CHAY } 678cc72361SWai Yew CHAY 688cc72361SWai Yew CHAY int input_mapper_delete(struct list_head *mappers, struct imapper *entry, 698cc72361SWai Yew CHAY int (*map_op)(void *, struct imapper *), void *data) 708cc72361SWai Yew CHAY { 718cc72361SWai Yew CHAY struct list_head *next, *pre, *head; 728cc72361SWai Yew CHAY struct imapper *pre_ent, *next_ent; 738cc72361SWai Yew CHAY 748cc72361SWai Yew CHAY head = mappers; 758cc72361SWai Yew CHAY 768cc72361SWai Yew CHAY if (list_empty(head)) 778cc72361SWai Yew CHAY return 0; 788cc72361SWai Yew CHAY 798cc72361SWai Yew CHAY pre = (entry->list.prev == head) ? head->prev : entry->list.prev; 808cc72361SWai Yew CHAY next = (entry->list.next == head) ? head->next : entry->list.next; 818cc72361SWai Yew CHAY 828cc72361SWai Yew CHAY if (pre == &entry->list) { 838cc72361SWai Yew CHAY /* entry is the only one node in mappers list */ 848cc72361SWai Yew CHAY entry->next = entry->addr = entry->user = entry->slot = 0; 858cc72361SWai Yew CHAY map_op(data, entry); 868cc72361SWai Yew CHAY list_del(&entry->list); 878cc72361SWai Yew CHAY return 0; 888cc72361SWai Yew CHAY } 898cc72361SWai Yew CHAY 908cc72361SWai Yew CHAY pre_ent = list_entry(pre, struct imapper, list); 918cc72361SWai Yew CHAY next_ent = list_entry(next, struct imapper, list); 928cc72361SWai Yew CHAY 938cc72361SWai Yew CHAY pre_ent->next = next_ent->addr; 948cc72361SWai Yew CHAY map_op(data, pre_ent); 958cc72361SWai Yew CHAY list_del(&entry->list); 968cc72361SWai Yew CHAY 978cc72361SWai Yew CHAY return 0; 988cc72361SWai Yew CHAY } 998cc72361SWai Yew CHAY 1008cc72361SWai Yew CHAY void free_input_mapper_list(struct list_head *head) 1018cc72361SWai Yew CHAY { 102*514eef9cSTakashi Iwai struct imapper *entry; 103*514eef9cSTakashi Iwai struct list_head *pos; 1048cc72361SWai Yew CHAY 1058cc72361SWai Yew CHAY while (!list_empty(head)) { 1068cc72361SWai Yew CHAY pos = head->next; 1078cc72361SWai Yew CHAY list_del(pos); 1088cc72361SWai Yew CHAY entry = list_entry(pos, struct imapper, list); 1098cc72361SWai Yew CHAY kfree(entry); 1108cc72361SWai Yew CHAY } 1118cc72361SWai Yew CHAY } 1128cc72361SWai Yew CHAY 113