forked from Minki/linux
8cc7236148
The Sound Blaster X-Fi driver supports Creative solutions based on 20K1 and 20K2 chipsets. Supported hardware : Creative Sound Blaster X-Fi Titanium Fatal1ty® Champion Series Creative Sound Blaster X-Fi Titanium Fatal1ty Professional Series Creative Sound Blaster X-Fi Titanium Professional Audio Creative Sound Blaster X-Fi Titanium Creative Sound Blaster X-Fi Elite Pro Creative Sound Blaster X-Fi Platinum Creative Sound Blaster X-Fi Fatal1ty Creative Sound Blaster X-Fi XtremeGamer Creative Sound Blaster X-Fi XtremeMusic Current release features: * ALSA PCM Playback * ALSA Record * ALSA Mixer Note: * External I/O modules detection not included. Signed-off-by: Wai Yew CHAY <wychay@ctl.creative.com> Singed-off-by: Ryan RICHARDS <ryan_richards@creativelabs.com> Signed-off-by: Takashi Iwai <tiwai@suse.de>
113 lines
2.5 KiB
C
113 lines
2.5 KiB
C
/**
|
|
* Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
|
|
*
|
|
* This source file is released under GPL v2 license (no other versions).
|
|
* See the COPYING file included in the main directory of this source
|
|
* distribution for the license terms and conditions.
|
|
*
|
|
* @File ctimap.c
|
|
*
|
|
* @Brief
|
|
* This file contains the implementation of generic input mapper operations
|
|
* for input mapper management.
|
|
*
|
|
* @Author Liu Chun
|
|
* @Date May 23 2008
|
|
*
|
|
*/
|
|
|
|
#include "ctimap.h"
|
|
#include <linux/slab.h>
|
|
|
|
int input_mapper_add(struct list_head *mappers, struct imapper *entry,
|
|
int (*map_op)(void *, struct imapper *), void *data)
|
|
{
|
|
struct list_head *pos, *pre, *head;
|
|
struct imapper *pre_ent, *pos_ent;
|
|
|
|
head = mappers;
|
|
|
|
if (list_empty(head)) {
|
|
entry->next = entry->addr;
|
|
map_op(data, entry);
|
|
list_add(&entry->list, head);
|
|
return 0;
|
|
}
|
|
|
|
list_for_each(pos, head) {
|
|
pos_ent = list_entry(pos, struct imapper, list);
|
|
if (pos_ent->slot > entry->slot) {
|
|
/* found a position in list */
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (pos != head) {
|
|
pre = pos->prev;
|
|
if (pre == head)
|
|
pre = head->prev;
|
|
|
|
__list_add(&entry->list, pos->prev, pos);
|
|
} else {
|
|
pre = head->prev;
|
|
pos = head->next;
|
|
list_add_tail(&entry->list, head);
|
|
}
|
|
|
|
pre_ent = list_entry(pre, struct imapper, list);
|
|
pos_ent = list_entry(pos, struct imapper, list);
|
|
|
|
entry->next = pos_ent->addr;
|
|
map_op(data, entry);
|
|
pre_ent->next = entry->addr;
|
|
map_op(data, pre_ent);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int input_mapper_delete(struct list_head *mappers, struct imapper *entry,
|
|
int (*map_op)(void *, struct imapper *), void *data)
|
|
{
|
|
struct list_head *next, *pre, *head;
|
|
struct imapper *pre_ent, *next_ent;
|
|
|
|
head = mappers;
|
|
|
|
if (list_empty(head))
|
|
return 0;
|
|
|
|
pre = (entry->list.prev == head) ? head->prev : entry->list.prev;
|
|
next = (entry->list.next == head) ? head->next : entry->list.next;
|
|
|
|
if (pre == &entry->list) {
|
|
/* entry is the only one node in mappers list */
|
|
entry->next = entry->addr = entry->user = entry->slot = 0;
|
|
map_op(data, entry);
|
|
list_del(&entry->list);
|
|
return 0;
|
|
}
|
|
|
|
pre_ent = list_entry(pre, struct imapper, list);
|
|
next_ent = list_entry(next, struct imapper, list);
|
|
|
|
pre_ent->next = next_ent->addr;
|
|
map_op(data, pre_ent);
|
|
list_del(&entry->list);
|
|
|
|
return 0;
|
|
}
|
|
|
|
void free_input_mapper_list(struct list_head *head)
|
|
{
|
|
struct imapper *entry = NULL;
|
|
struct list_head *pos = NULL;
|
|
|
|
while (!list_empty(head)) {
|
|
pos = head->next;
|
|
list_del(pos);
|
|
entry = list_entry(pos, struct imapper, list);
|
|
kfree(entry);
|
|
}
|
|
}
|
|
|