5ec6813d39110e54192e1379c900159581a999e5
[linux-2.6.git] / sound / pci / ctxfi / cthardware.c
1 /**
2  * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
3  *
4  * This source file is released under GPL v2 license (no other versions).
5  * See the COPYING file included in the main directory of this source
6  * distribution for the license terms and conditions.
7  *
8  * @File        cthardware.c
9  *
10  * @Brief
11  * This file contains the implementation of hardware access methord.
12  *
13  * @Author      Liu Chun
14  * @Date        Jun 26 2008
15  *
16  */
17
18 #include "cthardware.h"
19 #include "cthw20k1.h"
20 #include "cthw20k2.h"
21 #include <linux/bug.h>
22
23 static enum CHIPTYP __devinitdata get_chip_type(struct hw *hw)
24 {
25         enum CHIPTYP type;
26
27         switch (hw->pci->device) {
28         case 0x0005:    /* 20k1 device */
29                 type = ATC20K1;
30                 break;
31         case 0x000B:    /* 20k2 device */
32                 type = ATC20K2;
33                 break;
34         default:
35                 type = ATCNONE;
36                 break;
37         }
38
39         return type;
40 }
41
42 int __devinit create_hw_obj(struct pci_dev *pci, struct hw **rhw)
43 {
44         int err;
45
46         switch (pci->device) {
47         case 0x0005:    /* 20k1 device */
48                 err = create_20k1_hw_obj(rhw);
49                 break;
50         case 0x000B:    /* 20k2 device */
51                 err = create_20k2_hw_obj(rhw);
52                 break;
53         default:
54                 err = -ENODEV;
55                 break;
56         }
57         if (err)
58                 return err;
59
60         (*rhw)->pci = pci;
61         (*rhw)->get_chip_type = get_chip_type;
62
63         return 0;
64 }
65
66 int destroy_hw_obj(struct hw *hw)
67 {
68         int err;
69
70         switch (hw->pci->device) {
71         case 0x0005:    /* 20k1 device */
72                 err = destroy_20k1_hw_obj(hw);
73                 break;
74         case 0x000B:    /* 20k2 device */
75                 err = destroy_20k2_hw_obj(hw);
76                 break;
77         default:
78                 err = -ENODEV;
79                 break;
80         }
81
82         return err;
83 }
84
85 unsigned int get_field(unsigned int data, unsigned int field)
86 {
87         int i;
88
89         BUG_ON(!field);
90         /* @field should always be greater than 0 */
91         for (i = 0; !(field & (1 << i)); )
92                 i++;
93
94         return (data & field) >> i;
95 }
96
97 void set_field(unsigned int *data, unsigned int field, unsigned int value)
98 {
99         int i;
100
101         BUG_ON(!field);
102         /* @field should always be greater than 0 */
103         for (i = 0; !(field & (1 << i)); )
104                 i++;
105
106         *data = (*data & (~field)) | ((value << i) & field);
107 }
108