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