Linux-2.6.12-rc2
[deliverable/linux.git] / sound / oss / dmasound / tas_common.h
1 #ifndef _TAS_COMMON_H_
2 #define _TAS_COMMON_H_
3
4 #include <linux/i2c.h>
5 #include <linux/soundcard.h>
6 #include <asm/string.h>
7
8 #define I2C_DRIVERID_TAS_BASE (0xFEBA)
9
10 #define SET_4_20(shadow, offset, val) \
11 do { \
12 (shadow)[(offset)+0] = ((val) >> 16) & 0xff; \
13 (shadow)[(offset)+1] = ((val) >> 8) & 0xff; \
14 (shadow)[(offset)+2] = ((val) >> 0) & 0xff; \
15 } while (0)
16
17 #define GET_4_20(shadow, offset) \
18 (((u_int)((shadow)[(offset)+0]) << 16) | \
19 ((u_int)((shadow)[(offset)+1]) << 8) | \
20 ((u_int)((shadow)[(offset)+2]) << 0))
21
22
23 #define TAS_BIQUAD_FAST_LOAD 0x01
24
25 #define TAS_DRCE_ENABLE 0x01
26 #define TAS_DRCE_ABOVE_RATIO 0x02
27 #define TAS_DRCE_BELOW_RATIO 0x04
28 #define TAS_DRCE_THRESHOLD 0x08
29 #define TAS_DRCE_ENERGY 0x10
30 #define TAS_DRCE_ATTACK 0x20
31 #define TAS_DRCE_DECAY 0x40
32
33 #define TAS_DRCE_ALL 0x7f
34
35
36 #define TAS_OUTPUT_HEADPHONES 0x00
37 #define TAS_OUTPUT_INTERNAL_SPKR 0x01
38 #define TAS_OUTPUT_EXTERNAL_SPKR 0x02
39
40
41 union tas_biquad_t {
42 struct {
43 int b0,b1,b2,a1,a2;
44 } coeff;
45 int buf[5];
46 };
47
48 struct tas_biquad_ctrl_t {
49 u_int channel:4;
50 u_int filter:4;
51
52 union tas_biquad_t data;
53 };
54
55 struct tas_biquad_ctrl_list_t {
56 int flags;
57 int filter_count;
58 struct tas_biquad_ctrl_t biquads[0];
59 };
60
61 struct tas_ratio_t {
62 unsigned short val; /* 8.8 */
63 unsigned short expand; /* 0 = compress, !0 = expand. */
64 };
65
66 struct tas_drce_t {
67 unsigned short enable;
68 struct tas_ratio_t above;
69 struct tas_ratio_t below;
70 short threshold; /* dB, 8.8 signed */
71 unsigned short energy; /* seconds, 4.12 unsigned */
72 unsigned short attack; /* seconds, 4.12 unsigned */
73 unsigned short decay; /* seconds, 4.12 unsigned */
74 };
75
76 struct tas_drce_ctrl_t {
77 uint flags;
78
79 struct tas_drce_t data;
80 };
81
82 struct tas_gain_t
83 {
84 unsigned int *master;
85 unsigned int *treble;
86 unsigned int *bass;
87 unsigned int *mixer;
88 };
89
90 typedef char tas_shadow_t[0x45];
91
92 struct tas_data_t
93 {
94 struct i2c_client *client;
95 tas_shadow_t *shadow;
96 uint mixer[SOUND_MIXER_NRDEVICES];
97 };
98
99 typedef int (*tas_hook_init_t)(struct i2c_client *);
100 typedef int (*tas_hook_post_init_t)(struct tas_data_t *);
101 typedef void (*tas_hook_uninit_t)(struct tas_data_t *);
102
103 typedef int (*tas_hook_get_mixer_level_t)(struct tas_data_t *,int,uint *);
104 typedef int (*tas_hook_set_mixer_level_t)(struct tas_data_t *,int,uint);
105
106 typedef int (*tas_hook_enter_sleep_t)(struct tas_data_t *);
107 typedef int (*tas_hook_leave_sleep_t)(struct tas_data_t *);
108
109 typedef int (*tas_hook_supported_mixers_t)(struct tas_data_t *);
110 typedef int (*tas_hook_mixer_is_stereo_t)(struct tas_data_t *,int);
111 typedef int (*tas_hook_stereo_mixers_t)(struct tas_data_t *);
112
113 typedef int (*tas_hook_output_device_change_t)(struct tas_data_t *,int,int,int);
114 typedef int (*tas_hook_device_ioctl_t)(struct tas_data_t *,u_int,u_long);
115
116 struct tas_driver_hooks_t {
117 /*
118 * All hardware initialisation must be performed in
119 * post_init(), as tas_dmasound_init() does a hardware reset.
120 *
121 * init() is called before tas_dmasound_init() so that
122 * ouput_device_change() is always called after i2c driver
123 * initialisation. The implication is that
124 * output_device_change() must cope with the fact that it
125 * may be called before post_init().
126 */
127
128 tas_hook_init_t init;
129 tas_hook_post_init_t post_init;
130 tas_hook_uninit_t uninit;
131
132 tas_hook_get_mixer_level_t get_mixer_level;
133 tas_hook_set_mixer_level_t set_mixer_level;
134
135 tas_hook_enter_sleep_t enter_sleep;
136 tas_hook_leave_sleep_t leave_sleep;
137
138 tas_hook_supported_mixers_t supported_mixers;
139 tas_hook_mixer_is_stereo_t mixer_is_stereo;
140 tas_hook_stereo_mixers_t stereo_mixers;
141
142 tas_hook_output_device_change_t output_device_change;
143 tas_hook_device_ioctl_t device_ioctl;
144 };
145
146 enum tas_write_mode_t {
147 WRITE_HW = 0x01,
148 WRITE_SHADOW = 0x02,
149 WRITE_NORMAL = 0x03,
150 FORCE_WRITE = 0x04
151 };
152
153 static inline uint
154 tas_mono_to_stereo(uint mono)
155 {
156 mono &=0xff;
157 return mono | (mono<<8);
158 }
159
160 /*
161 * Todo: make these functions a bit more efficient !
162 */
163 static inline int
164 tas_write_register( struct tas_data_t *self,
165 uint reg_num,
166 uint reg_width,
167 char *data,
168 uint write_mode)
169 {
170 int rc;
171
172 if (reg_width==0 || data==NULL || self==NULL)
173 return -EINVAL;
174 if (!(write_mode & FORCE_WRITE) &&
175 !memcmp(data,self->shadow[reg_num],reg_width))
176 return 0;
177
178 if (write_mode & WRITE_SHADOW)
179 memcpy(self->shadow[reg_num],data,reg_width);
180 if (write_mode & WRITE_HW) {
181 rc=i2c_smbus_write_block_data(self->client,
182 reg_num,
183 reg_width,
184 data);
185 if (rc < 0) {
186 printk("tas: I2C block write failed \n");
187 return rc;
188 }
189 }
190 return 0;
191 }
192
193 static inline int
194 tas_sync_register( struct tas_data_t *self,
195 uint reg_num,
196 uint reg_width)
197 {
198 int rc;
199
200 if (reg_width==0 || self==NULL)
201 return -EINVAL;
202 rc=i2c_smbus_write_block_data(self->client,
203 reg_num,
204 reg_width,
205 self->shadow[reg_num]);
206 if (rc < 0) {
207 printk("tas: I2C block write failed \n");
208 return rc;
209 }
210 return 0;
211 }
212
213 static inline int
214 tas_write_byte_register( struct tas_data_t *self,
215 uint reg_num,
216 char data,
217 uint write_mode)
218 {
219 if (self==NULL)
220 return -1;
221 if (!(write_mode & FORCE_WRITE) && data != self->shadow[reg_num][0])
222 return 0;
223 if (write_mode & WRITE_SHADOW)
224 self->shadow[reg_num][0]=data;
225 if (write_mode & WRITE_HW) {
226 if (i2c_smbus_write_byte_data(self->client, reg_num, data) < 0) {
227 printk("tas: I2C byte write failed \n");
228 return -1;
229 }
230 }
231 return 0;
232 }
233
234 static inline int
235 tas_sync_byte_register( struct tas_data_t *self,
236 uint reg_num,
237 uint reg_width)
238 {
239 if (reg_width==0 || self==NULL)
240 return -1;
241 if (i2c_smbus_write_byte_data(
242 self->client, reg_num, self->shadow[reg_num][0]) < 0) {
243 printk("tas: I2C byte write failed \n");
244 return -1;
245 }
246 return 0;
247 }
248
249 static inline int
250 tas_read_register( struct tas_data_t *self,
251 uint reg_num,
252 uint reg_width,
253 char *data)
254 {
255 if (reg_width==0 || data==NULL || self==NULL)
256 return -1;
257 memcpy(data,self->shadow[reg_num],reg_width);
258 return 0;
259 }
260
261 extern int tas_register_driver(struct tas_driver_hooks_t *hooks);
262
263 extern int tas_get_mixer_level(int mixer,uint *level);
264 extern int tas_set_mixer_level(int mixer,uint level);
265 extern int tas_enter_sleep(void);
266 extern int tas_leave_sleep(void);
267 extern int tas_supported_mixers(void);
268 extern int tas_mixer_is_stereo(int mixer);
269 extern int tas_stereo_mixers(void);
270 extern int tas_output_device_change(int,int,int);
271 extern int tas_device_ioctl(u_int, u_long);
272
273 extern void tas_cleanup(void);
274 extern int tas_init(int driver_id,const char *driver_name);
275 extern int tas_post_init(void);
276
277 #endif /* _TAS_COMMON_H_ */
278 /*
279 * Local Variables:
280 * tab-width: 8
281 * indent-tabs-mode: t
282 * c-basic-offset: 8
283 * End:
284 */
This page took 0.037147 seconds and 5 git commands to generate.