diff options
Diffstat (limited to 'sound/pci/ctxfi/cthardware.c')
-rw-r--r-- | sound/pci/ctxfi/cthardware.c | 108 |
1 files changed, 108 insertions, 0 deletions
diff --git a/sound/pci/ctxfi/cthardware.c b/sound/pci/ctxfi/cthardware.c new file mode 100644 index 000000000000..8e58860f641c --- /dev/null +++ b/sound/pci/ctxfi/cthardware.c | |||
@@ -0,0 +1,108 @@ | |||
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 get_chip_type(struct hw *hw) | ||
24 | { | ||
25 | enum CHIPTYP type = ATCNONE; | ||
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 create_hw_obj(struct pci_dev *pci, struct hw **rhw) | ||
43 | { | ||
44 | int err = 0; | ||
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 = 0; | ||
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 | |||