fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / sound / oss / dmasound / tas3004.c
1 /*
2  * Driver for the i2c/i2s based TA3004 sound chip used
3  * on some Apple hardware. Also known as "snapper".
4  *
5  * Tobias Sargeant <tobias.sargeant@bigpond.com>
6  * Based upon tas3001c.c by Christopher C. Chimelis <chris@debian.org>:
7  *
8  * Input support by Renzo Davoli <renzo@cs.unibo.it>
9  *
10  */
11
12 #include <linux/module.h>
13 #include <linux/slab.h>
14 #include <linux/proc_fs.h>
15 #include <linux/ioport.h>
16 #include <linux/sysctl.h>
17 #include <linux/types.h>
18 #include <linux/i2c.h>
19 #include <linux/init.h>
20 #include <linux/soundcard.h>
21 #include <linux/interrupt.h>
22 #include <linux/workqueue.h>
23
24 #include <asm/uaccess.h>
25 #include <asm/errno.h>
26 #include <asm/io.h>
27 #include <asm/prom.h>
28
29 #include "dmasound.h"
30 #include "tas_common.h"
31 #include "tas3004.h"
32
33 #include "tas_ioctl.h"
34
35 /* #define DEBUG_DRCE */
36
37 #define TAS3004_BIQUAD_FILTER_COUNT  7
38 #define TAS3004_BIQUAD_CHANNEL_COUNT 2
39
40 #define VOL_DEFAULT     (100 * 4 / 5)
41 #define INPUT_DEFAULT   (100 * 4 / 5)
42 #define BASS_DEFAULT    (100 / 2)
43 #define TREBLE_DEFAULT  (100 / 2)
44
45 struct tas3004_data_t {
46         struct tas_data_t super;
47         int device_id;
48         int output_id;
49         int speaker_id;
50         struct tas_drce_t drce_state;
51         struct work_struct change;
52 };
53
54 #define MAKE_TIME(sec,usec) (((sec)<<12) + (50000+(usec/10)*(1<<12))/100000)
55
56 #define MAKE_RATIO(i,f) (((i)<<8) + ((500+(f)*(1<<8))/1000))
57
58
59 static const union tas_biquad_t tas3004_eq_unity = {
60         .buf             = { 0x100000, 0x000000, 0x000000, 0x000000, 0x000000 },
61 };
62
63
64 static const struct tas_drce_t tas3004_drce_min = {
65         .enable         = 1,
66         .above          = { .val = MAKE_RATIO(16,0), .expand = 0 },
67         .below          = { .val = MAKE_RATIO(2,0), .expand = 0 },
68         .threshold      = -0x59a0,
69         .energy         = MAKE_TIME(0,  1700),
70         .attack         = MAKE_TIME(0,  1700),
71         .decay          = MAKE_TIME(0,  1700),
72 };
73
74
75 static const struct tas_drce_t tas3004_drce_max = {
76         .enable         = 1,
77         .above          = { .val = MAKE_RATIO(1,500), .expand = 1 },
78         .below          = { .val = MAKE_RATIO(2,0), .expand = 1 },
79         .threshold      = -0x0,
80         .energy         = MAKE_TIME(2,400000),
81         .attack         = MAKE_TIME(2,400000),
82         .decay          = MAKE_TIME(2,400000),
83 };
84
85
86 static const unsigned short time_constants[]={
87         MAKE_TIME(0,  1700),
88         MAKE_TIME(0,  3500),
89         MAKE_TIME(0,  6700),
90         MAKE_TIME(0, 13000),
91         MAKE_TIME(0, 26000),
92         MAKE_TIME(0, 53000),
93         MAKE_TIME(0,106000),
94         MAKE_TIME(0,212000),
95         MAKE_TIME(0,425000),
96         MAKE_TIME(0,850000),
97         MAKE_TIME(1,700000),
98         MAKE_TIME(2,400000),
99 };
100
101 static const unsigned short above_threshold_compression_ratio[]={
102         MAKE_RATIO( 1, 70),
103         MAKE_RATIO( 1,140),
104         MAKE_RATIO( 1,230),
105         MAKE_RATIO( 1,330),
106         MAKE_RATIO( 1,450),
107         MAKE_RATIO( 1,600),
108         MAKE_RATIO( 1,780),
109         MAKE_RATIO( 2,  0),
110         MAKE_RATIO( 2,290),
111         MAKE_RATIO( 2,670),
112         MAKE_RATIO( 3,200),
113         MAKE_RATIO( 4,  0),
114         MAKE_RATIO( 5,330),
115         MAKE_RATIO( 8,  0),
116         MAKE_RATIO(16,  0),
117 };
118
119 static const unsigned short above_threshold_expansion_ratio[]={
120         MAKE_RATIO(1, 60),
121         MAKE_RATIO(1,130),
122         MAKE_RATIO(1,190),
123         MAKE_RATIO(1,250),
124         MAKE_RATIO(1,310),
125         MAKE_RATIO(1,380),
126         MAKE_RATIO(1,440),
127         MAKE_RATIO(1,500)
128 };
129
130 static const unsigned short below_threshold_compression_ratio[]={
131         MAKE_RATIO(1, 70),
132         MAKE_RATIO(1,140),
133         MAKE_RATIO(1,230),
134         MAKE_RATIO(1,330),
135         MAKE_RATIO(1,450),
136         MAKE_RATIO(1,600),
137         MAKE_RATIO(1,780),
138         MAKE_RATIO(2,  0)
139 };
140
141 static const unsigned short below_threshold_expansion_ratio[]={
142         MAKE_RATIO(1, 60),
143         MAKE_RATIO(1,130),
144         MAKE_RATIO(1,190),
145         MAKE_RATIO(1,250),
146         MAKE_RATIO(1,310),
147         MAKE_RATIO(1,380),
148         MAKE_RATIO(1,440),
149         MAKE_RATIO(1,500),
150         MAKE_RATIO(1,560),
151         MAKE_RATIO(1,630),
152         MAKE_RATIO(1,690),
153         MAKE_RATIO(1,750),
154         MAKE_RATIO(1,810),
155         MAKE_RATIO(1,880),
156         MAKE_RATIO(1,940),
157         MAKE_RATIO(2,  0)
158 };
159
160 static inline int
161 search( unsigned short val,
162         const unsigned short *arr,
163         const int arrsize) {
164         /*
165          * This could be a binary search, but for small tables,
166          * a linear search is likely to be faster
167          */
168
169         int i;
170
171         for (i=0; i < arrsize; i++)
172                 if (arr[i] >= val)
173                         goto _1;
174         return arrsize-1;
175  _1:
176         if (i == 0)
177                 return 0;
178         return (arr[i]-val < val-arr[i-1]) ? i : i-1;
179 }
180
181 #define SEARCH(a, b) search(a, b, ARRAY_SIZE(b))
182
183 static inline int
184 time_index(unsigned short time)
185 {
186         return SEARCH(time, time_constants);
187 }
188
189
190 static inline int
191 above_threshold_compression_index(unsigned short ratio)
192 {
193         return SEARCH(ratio, above_threshold_compression_ratio);
194 }
195
196
197 static inline int
198 above_threshold_expansion_index(unsigned short ratio)
199 {
200         return SEARCH(ratio, above_threshold_expansion_ratio);
201 }
202
203
204 static inline int
205 below_threshold_compression_index(unsigned short ratio)
206 {
207         return SEARCH(ratio, below_threshold_compression_ratio);
208 }
209
210
211 static inline int
212 below_threshold_expansion_index(unsigned short ratio)
213 {
214         return SEARCH(ratio, below_threshold_expansion_ratio);
215 }
216
217 static inline unsigned char db_to_regval(short db) {
218         int r=0;
219
220         r=(db+0x59a0) / 0x60;
221
222         if (r < 0x91) return 0x91;
223         if (r > 0xef) return 0xef;
224         return r;
225 }
226
227 static inline short quantize_db(short db)
228 {
229         return db_to_regval(db) * 0x60 - 0x59a0;
230 }
231
232 static inline int
233 register_width(enum tas3004_reg_t r)
234 {
235         switch(r) {
236         case TAS3004_REG_MCR:
237         case TAS3004_REG_TREBLE:
238         case TAS3004_REG_BASS:
239         case TAS3004_REG_ANALOG_CTRL:
240         case TAS3004_REG_TEST1:
241         case TAS3004_REG_TEST2:
242         case TAS3004_REG_MCR2:
243                 return 1;
244
245         case TAS3004_REG_LEFT_LOUD_BIQUAD_GAIN:
246         case TAS3004_REG_RIGHT_LOUD_BIQUAD_GAIN:
247                 return 3;
248
249         case TAS3004_REG_DRC:
250         case TAS3004_REG_VOLUME:
251                 return 6;
252
253         case TAS3004_REG_LEFT_MIXER:
254         case TAS3004_REG_RIGHT_MIXER:
255                 return 9;
256
257         case TAS3004_REG_TEST:
258                 return 10;
259
260         case TAS3004_REG_LEFT_BIQUAD0:
261         case TAS3004_REG_LEFT_BIQUAD1:
262         case TAS3004_REG_LEFT_BIQUAD2:
263         case TAS3004_REG_LEFT_BIQUAD3:
264         case TAS3004_REG_LEFT_BIQUAD4:
265         case TAS3004_REG_LEFT_BIQUAD5:
266         case TAS3004_REG_LEFT_BIQUAD6:
267
268         case TAS3004_REG_RIGHT_BIQUAD0:
269         case TAS3004_REG_RIGHT_BIQUAD1:
270         case TAS3004_REG_RIGHT_BIQUAD2:
271         case TAS3004_REG_RIGHT_BIQUAD3:
272         case TAS3004_REG_RIGHT_BIQUAD4:
273         case TAS3004_REG_RIGHT_BIQUAD5:
274         case TAS3004_REG_RIGHT_BIQUAD6:
275
276         case TAS3004_REG_LEFT_LOUD_BIQUAD:
277         case TAS3004_REG_RIGHT_LOUD_BIQUAD:
278                 return 15;
279
280         default:
281                 return 0;
282         }
283 }
284
285 static int
286 tas3004_write_register( struct tas3004_data_t *self,
287                         enum tas3004_reg_t reg_num,
288                         char *data,
289                         uint write_mode)
290 {
291         if (reg_num==TAS3004_REG_MCR ||
292             reg_num==TAS3004_REG_BASS ||
293             reg_num==TAS3004_REG_TREBLE ||
294             reg_num==TAS3004_REG_ANALOG_CTRL) {
295                 return tas_write_byte_register(&self->super,
296                                                (uint)reg_num,
297                                                *data,
298                                                write_mode);
299         } else {
300                 return tas_write_register(&self->super,
301                                           (uint)reg_num,
302                                           register_width(reg_num),
303                                           data,
304                                           write_mode);
305         }
306 }
307
308 static int
309 tas3004_sync_register(  struct tas3004_data_t *self,
310                         enum tas3004_reg_t reg_num)
311 {
312         if (reg_num==TAS3004_REG_MCR ||
313             reg_num==TAS3004_REG_BASS ||
314             reg_num==TAS3004_REG_TREBLE ||
315             reg_num==TAS3004_REG_ANALOG_CTRL) {
316                 return tas_sync_byte_register(&self->super,
317                                               (uint)reg_num,
318                                               register_width(reg_num));
319         } else {
320                 return tas_sync_register(&self->super,
321                                          (uint)reg_num,
322                                          register_width(reg_num));
323         }
324 }
325
326 static int
327 tas3004_read_register(  struct tas3004_data_t *self,
328                         enum tas3004_reg_t reg_num,
329                         char *data,
330                         uint write_mode)
331 {
332         return tas_read_register(&self->super,
333                                  (uint)reg_num,
334                                  register_width(reg_num),
335                                  data);
336 }
337
338 static inline int
339 tas3004_fast_load(struct tas3004_data_t *self, int fast)
340 {
341         if (fast)
342                 self->super.shadow[TAS3004_REG_MCR][0] |= 0x80;
343         else
344                 self->super.shadow[TAS3004_REG_MCR][0] &= 0x7f;
345         return tas3004_sync_register(self,TAS3004_REG_MCR);
346 }
347
348 static uint
349 tas3004_supported_mixers(struct tas3004_data_t *self)
350 {
351         return SOUND_MASK_VOLUME |
352                 SOUND_MASK_PCM |
353                 SOUND_MASK_ALTPCM |
354                 SOUND_MASK_IMIX |
355                 SOUND_MASK_TREBLE |
356                 SOUND_MASK_BASS |
357                 SOUND_MASK_MIC |
358                 SOUND_MASK_LINE;
359 }
360
361 static int
362 tas3004_mixer_is_stereo(struct tas3004_data_t *self, int mixer)
363 {
364         switch(mixer) {
365         case SOUND_MIXER_VOLUME:
366         case SOUND_MIXER_PCM:
367         case SOUND_MIXER_ALTPCM:
368         case SOUND_MIXER_IMIX:
369                 return 1;
370         default:
371                 return 0;
372         }
373 }
374
375 static uint
376 tas3004_stereo_mixers(struct tas3004_data_t *self)
377 {
378         uint r = tas3004_supported_mixers(self);
379         uint i;
380         
381         for (i=1; i<SOUND_MIXER_NRDEVICES; i++)
382                 if (r&(1<<i) && !tas3004_mixer_is_stereo(self,i))
383                         r &= ~(1<<i);
384         return r;
385 }
386
387 static int
388 tas3004_get_mixer_level(struct tas3004_data_t *self, int mixer, uint *level)
389 {
390         if (!self)
391                 return -1;
392
393         *level = self->super.mixer[mixer];
394
395         return 0;
396 }
397
398 static int
399 tas3004_set_mixer_level(struct tas3004_data_t *self, int mixer, uint level)
400 {
401         int rc;
402         tas_shadow_t *shadow;
403         uint temp;
404         uint offset=0;
405
406         if (!self)
407                 return -1;
408
409         shadow = self->super.shadow;
410
411         if (!tas3004_mixer_is_stereo(self,mixer))
412                 level = tas_mono_to_stereo(level);
413         switch(mixer) {
414         case SOUND_MIXER_VOLUME:
415                 temp = tas3004_gain.master[level&0xff];
416                 SET_4_20(shadow[TAS3004_REG_VOLUME], 0, temp);
417                 temp = tas3004_gain.master[(level>>8)&0xff];
418                 SET_4_20(shadow[TAS3004_REG_VOLUME], 3, temp);
419                 rc = tas3004_sync_register(self,TAS3004_REG_VOLUME);
420                 break;
421         case SOUND_MIXER_IMIX:
422                 offset += 3;
423         case SOUND_MIXER_ALTPCM:
424                 offset += 3;
425         case SOUND_MIXER_PCM:
426                 /*
427                  * Don't load these in fast mode. The documentation
428                  * says it can be done in either mode, but testing it
429                  * shows that fast mode produces ugly clicking.
430                 */
431                 /* tas3004_fast_load(self,1); */
432                 temp = tas3004_gain.mixer[level&0xff];
433                 SET_4_20(shadow[TAS3004_REG_LEFT_MIXER], offset, temp);
434                 temp = tas3004_gain.mixer[(level>>8)&0xff];
435                 SET_4_20(shadow[TAS3004_REG_RIGHT_MIXER], offset, temp);
436                 rc = tas3004_sync_register(self,TAS3004_REG_LEFT_MIXER);
437                 if (rc == 0)
438                         rc=tas3004_sync_register(self,TAS3004_REG_RIGHT_MIXER);
439                 /* tas3004_fast_load(self,0); */
440                 break;
441         case SOUND_MIXER_TREBLE:
442                 temp = tas3004_gain.treble[level&0xff];
443                 shadow[TAS3004_REG_TREBLE][0]=temp&0xff;
444                 rc = tas3004_sync_register(self,TAS3004_REG_TREBLE);
445                 break;
446         case SOUND_MIXER_BASS:
447                 temp = tas3004_gain.bass[level&0xff];
448                 shadow[TAS3004_REG_BASS][0]=temp&0xff;
449                 rc = tas3004_sync_register(self,TAS3004_REG_BASS);
450                 break;
451         case SOUND_MIXER_MIC:
452                 if ((level&0xff)>0) {
453                         software_input_volume = SW_INPUT_VOLUME_SCALE * (level&0xff);
454                         if (self->super.mixer[mixer] == 0) {
455                                 self->super.mixer[SOUND_MIXER_LINE] = 0;
456                                 shadow[TAS3004_REG_ANALOG_CTRL][0]=0xc2;
457                                 rc = tas3004_sync_register(self,TAS3004_REG_ANALOG_CTRL);
458                         } else rc=0;
459                 } else {
460                         self->super.mixer[SOUND_MIXER_LINE] = SW_INPUT_VOLUME_DEFAULT;
461                         software_input_volume = SW_INPUT_VOLUME_SCALE *
462                                 (self->super.mixer[SOUND_MIXER_LINE]&0xff);
463                         shadow[TAS3004_REG_ANALOG_CTRL][0]=0x00;
464                         rc = tas3004_sync_register(self,TAS3004_REG_ANALOG_CTRL);
465                 }
466                 break;
467         case SOUND_MIXER_LINE:
468                 if (self->super.mixer[SOUND_MIXER_MIC] == 0) {
469                         software_input_volume = SW_INPUT_VOLUME_SCALE * (level&0xff);
470                         rc=0;
471                 }
472                 break;
473         default:
474                 rc = -1;
475                 break;
476         }
477         if (rc < 0)
478                 return rc;
479         self->super.mixer[mixer] = level;
480         
481         return 0;
482 }
483
484 static int
485 tas3004_leave_sleep(struct tas3004_data_t *self)
486 {
487         unsigned char mcr = (1<<6)+(2<<4)+(2<<2);
488
489         if (!self)
490                 return -1;
491
492         /* Make sure something answers on the i2c bus */
493         if (tas3004_write_register(self, TAS3004_REG_MCR, &mcr,
494             WRITE_NORMAL | FORCE_WRITE) < 0)
495                 return -1;
496
497         tas3004_fast_load(self, 1);
498
499         (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD0);
500         (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD1);
501         (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD2);
502         (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD3);
503         (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD4);
504         (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD5);
505         (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD6);
506
507         (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD0);
508         (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD1);
509         (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD2);
510         (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD3);
511         (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD4);
512         (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD5);
513         (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD6);
514
515         tas3004_fast_load(self, 0);
516
517         (void)tas3004_sync_register(self,TAS3004_REG_VOLUME);
518         (void)tas3004_sync_register(self,TAS3004_REG_LEFT_MIXER);
519         (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_MIXER);
520         (void)tas3004_sync_register(self,TAS3004_REG_TREBLE);
521         (void)tas3004_sync_register(self,TAS3004_REG_BASS);
522         (void)tas3004_sync_register(self,TAS3004_REG_ANALOG_CTRL);
523
524         return 0;
525 }
526
527 static int
528 tas3004_enter_sleep(struct tas3004_data_t *self)
529 {
530         if (!self)
531                 return -1; 
532         return 0;
533 }
534
535 static int
536 tas3004_sync_biquad(    struct tas3004_data_t *self,
537                         u_int channel,
538                         u_int filter)
539 {
540         enum tas3004_reg_t reg;
541
542         if (channel >= TAS3004_BIQUAD_CHANNEL_COUNT ||
543             filter  >= TAS3004_BIQUAD_FILTER_COUNT) return -EINVAL;
544
545         reg=( channel ? TAS3004_REG_RIGHT_BIQUAD0 : TAS3004_REG_LEFT_BIQUAD0 ) + filter;
546
547         return tas3004_sync_register(self,reg);
548 }
549
550 static int
551 tas3004_write_biquad_shadow(    struct tas3004_data_t *self,
552                                 u_int channel,
553                                 u_int filter,
554                                 const union tas_biquad_t *biquad)
555 {
556         tas_shadow_t *shadow=self->super.shadow;
557         enum tas3004_reg_t reg;
558
559         if (channel >= TAS3004_BIQUAD_CHANNEL_COUNT ||
560             filter  >= TAS3004_BIQUAD_FILTER_COUNT) return -EINVAL;
561
562         reg=( channel ? TAS3004_REG_RIGHT_BIQUAD0 : TAS3004_REG_LEFT_BIQUAD0 ) + filter;
563
564         SET_4_20(shadow[reg], 0,biquad->coeff.b0);
565         SET_4_20(shadow[reg], 3,biquad->coeff.b1);
566         SET_4_20(shadow[reg], 6,biquad->coeff.b2);
567         SET_4_20(shadow[reg], 9,biquad->coeff.a1);
568         SET_4_20(shadow[reg],12,biquad->coeff.a2);
569
570         return 0;
571 }
572
573 static int
574 tas3004_write_biquad(   struct tas3004_data_t *self,
575                         u_int channel,
576                         u_int filter,
577                         const union tas_biquad_t *biquad)
578 {
579         int rc;
580
581         rc=tas3004_write_biquad_shadow(self, channel, filter, biquad);
582         if (rc < 0) return rc;
583
584         return tas3004_sync_biquad(self, channel, filter);
585 }
586
587 static int
588 tas3004_write_biquad_list(      struct tas3004_data_t *self,
589                                 u_int filter_count,
590                                 u_int flags,
591                                 struct tas_biquad_ctrl_t *biquads)
592 {
593         int i;
594         int rc;
595
596         if (flags & TAS_BIQUAD_FAST_LOAD) tas3004_fast_load(self,1);
597
598         for (i=0; i<filter_count; i++) {
599                 rc=tas3004_write_biquad(self,
600                                         biquads[i].channel,
601                                         biquads[i].filter,
602                                         &biquads[i].data);
603                 if (rc < 0) break;
604         }
605
606         if (flags & TAS_BIQUAD_FAST_LOAD) tas3004_fast_load(self,0);
607
608         return rc;
609 }
610
611 static int
612 tas3004_read_biquad(    struct tas3004_data_t *self,
613                         u_int channel,
614                         u_int filter,
615                         union tas_biquad_t *biquad)
616 {
617         tas_shadow_t *shadow=self->super.shadow;
618         enum tas3004_reg_t reg;
619
620         if (channel >= TAS3004_BIQUAD_CHANNEL_COUNT ||
621             filter  >= TAS3004_BIQUAD_FILTER_COUNT) return -EINVAL;
622
623         reg=( channel ? TAS3004_REG_RIGHT_BIQUAD0 : TAS3004_REG_LEFT_BIQUAD0 ) + filter;
624
625         biquad->coeff.b0=GET_4_20(shadow[reg], 0);
626         biquad->coeff.b1=GET_4_20(shadow[reg], 3);
627         biquad->coeff.b2=GET_4_20(shadow[reg], 6);
628         biquad->coeff.a1=GET_4_20(shadow[reg], 9);
629         biquad->coeff.a2=GET_4_20(shadow[reg],12);
630         
631         return 0;       
632 }
633
634 static int
635 tas3004_eq_rw(  struct tas3004_data_t *self,
636                 u_int cmd,
637                 u_long arg)
638 {
639         void __user *argp = (void __user *)arg;
640         int rc;
641         struct tas_biquad_ctrl_t biquad;
642
643         if (copy_from_user((void *)&biquad, argp, sizeof(struct tas_biquad_ctrl_t))) {
644                 return -EFAULT;
645         }
646
647         if (cmd & SIOC_IN) {
648                 rc=tas3004_write_biquad(self, biquad.channel, biquad.filter, &biquad.data);
649                 if (rc != 0) return rc;
650         }
651
652         if (cmd & SIOC_OUT) {
653                 rc=tas3004_read_biquad(self, biquad.channel, biquad.filter, &biquad.data);
654                 if (rc != 0) return rc;
655
656                 if (copy_to_user(argp, &biquad, sizeof(struct tas_biquad_ctrl_t))) {
657                         return -EFAULT;
658                 }
659
660         }
661         return 0;
662 }
663
664 static int
665 tas3004_eq_list_rw(     struct tas3004_data_t *self,
666                         u_int cmd,
667                         u_long arg)
668 {
669         int rc = 0;
670         int filter_count;
671         int flags;
672         int i,j;
673         char sync_required[TAS3004_BIQUAD_CHANNEL_COUNT][TAS3004_BIQUAD_FILTER_COUNT];
674         struct tas_biquad_ctrl_t biquad;
675         struct tas_biquad_ctrl_list_t __user *argp = (void __user *)arg;
676
677         memset(sync_required,0,sizeof(sync_required));
678
679         if (copy_from_user(&filter_count, &argp->filter_count, sizeof(int)))
680                 return -EFAULT;
681
682         if (copy_from_user(&flags, &argp->flags, sizeof(int)))
683                 return -EFAULT;
684
685         if (cmd & SIOC_IN) {
686         }
687
688         for (i=0; i < filter_count; i++) {
689                 if (copy_from_user(&biquad, &argp->biquads[i],
690                                    sizeof(struct tas_biquad_ctrl_t))) {
691                         return -EFAULT;
692                 }
693
694                 if (cmd & SIOC_IN) {
695                         sync_required[biquad.channel][biquad.filter]=1;
696                         rc=tas3004_write_biquad_shadow(self, biquad.channel, biquad.filter, &biquad.data);
697                         if (rc != 0) return rc;
698                 }
699
700                 if (cmd & SIOC_OUT) {
701                         rc=tas3004_read_biquad(self, biquad.channel, biquad.filter, &biquad.data);
702                         if (rc != 0) return rc;
703
704                         if (copy_to_user(&argp->biquads[i], &biquad,
705                                          sizeof(struct tas_biquad_ctrl_t))) {
706                                 return -EFAULT;
707                         }
708                 }
709         }
710
711         if (cmd & SIOC_IN) {
712                 /*
713                  * This is OK for the tas3004. For the
714                  * tas3001c, going into fast load mode causes
715                  * the treble and bass to be reset to 0dB, and
716                  * volume controls to be muted.
717                  */
718                 if (flags & TAS_BIQUAD_FAST_LOAD) tas3004_fast_load(self,1);
719                 for (i=0; i<TAS3004_BIQUAD_CHANNEL_COUNT; i++) {
720                         for (j=0; j<TAS3004_BIQUAD_FILTER_COUNT; j++) {
721                                 if (sync_required[i][j]) {
722                                         rc=tas3004_sync_biquad(self, i, j);
723                                         if (rc < 0) goto out;
724                                 }
725                         }
726                 }
727         out:
728                 if (flags & TAS_BIQUAD_FAST_LOAD)
729                         tas3004_fast_load(self,0);
730         }
731
732         return rc;
733 }
734
735 static int
736 tas3004_update_drce(    struct tas3004_data_t *self,
737                         int flags,
738                         struct tas_drce_t *drce)
739 {
740         tas_shadow_t *shadow;
741         int i;
742         shadow=self->super.shadow;
743
744         if (flags & TAS_DRCE_ABOVE_RATIO) {
745                 self->drce_state.above.expand = drce->above.expand;
746                 if (drce->above.val == (1<<8)) {
747                         self->drce_state.above.val = 1<<8;
748                         shadow[TAS3004_REG_DRC][0] = 0x02;
749                                         
750                 } else if (drce->above.expand) {
751                         i=above_threshold_expansion_index(drce->above.val);
752                         self->drce_state.above.val=above_threshold_expansion_ratio[i];
753                         shadow[TAS3004_REG_DRC][0] = 0x0a + (i<<3);
754                 } else {
755                         i=above_threshold_compression_index(drce->above.val);
756                         self->drce_state.above.val=above_threshold_compression_ratio[i];
757                         shadow[TAS3004_REG_DRC][0] = 0x08 + (i<<3);
758                 }
759         }
760
761         if (flags & TAS_DRCE_BELOW_RATIO) {
762                 self->drce_state.below.expand = drce->below.expand;
763                 if (drce->below.val == (1<<8)) {
764                         self->drce_state.below.val = 1<<8;
765                         shadow[TAS3004_REG_DRC][1] = 0x02;
766                                         
767                 } else if (drce->below.expand) {
768                         i=below_threshold_expansion_index(drce->below.val);
769                         self->drce_state.below.val=below_threshold_expansion_ratio[i];
770                         shadow[TAS3004_REG_DRC][1] = 0x08 + (i<<3);
771                 } else {
772                         i=below_threshold_compression_index(drce->below.val);
773                         self->drce_state.below.val=below_threshold_compression_ratio[i];
774                         shadow[TAS3004_REG_DRC][1] = 0x0a + (i<<3);
775                 }
776         }
777
778         if (flags & TAS_DRCE_THRESHOLD) {
779                 self->drce_state.threshold=quantize_db(drce->threshold);
780                 shadow[TAS3004_REG_DRC][2] = db_to_regval(self->drce_state.threshold);
781         }
782
783         if (flags & TAS_DRCE_ENERGY) {
784                 i=time_index(drce->energy);
785                 self->drce_state.energy=time_constants[i];
786                 shadow[TAS3004_REG_DRC][3] = 0x40 + (i<<4);
787         }
788
789         if (flags & TAS_DRCE_ATTACK) {
790                 i=time_index(drce->attack);
791                 self->drce_state.attack=time_constants[i];
792                 shadow[TAS3004_REG_DRC][4] = 0x40 + (i<<4);
793         }
794
795         if (flags & TAS_DRCE_DECAY) {
796                 i=time_index(drce->decay);
797                 self->drce_state.decay=time_constants[i];
798                 shadow[TAS3004_REG_DRC][5] = 0x40 + (i<<4);
799         }
800
801         if (flags & TAS_DRCE_ENABLE) {
802                 self->drce_state.enable = drce->enable;
803         }
804
805         if (!self->drce_state.enable) {
806                 shadow[TAS3004_REG_DRC][0] |= 0x01;
807         }
808
809 #ifdef DEBUG_DRCE
810         printk("DRCE: set [ ENABLE:%x ABOVE:%x/%x BELOW:%x/%x THRESH:%x ENERGY:%x ATTACK:%x DECAY:%x\n",
811                self->drce_state.enable,
812                self->drce_state.above.expand,self->drce_state.above.val,
813                self->drce_state.below.expand,self->drce_state.below.val,
814                self->drce_state.threshold,
815                self->drce_state.energy,
816                self->drce_state.attack,
817                self->drce_state.decay);
818
819         printk("DRCE: reg [ %02x %02x %02x %02x %02x %02x ]\n",
820                (unsigned char)shadow[TAS3004_REG_DRC][0],
821                (unsigned char)shadow[TAS3004_REG_DRC][1],
822                (unsigned char)shadow[TAS3004_REG_DRC][2],
823                (unsigned char)shadow[TAS3004_REG_DRC][3],
824                (unsigned char)shadow[TAS3004_REG_DRC][4],
825                (unsigned char)shadow[TAS3004_REG_DRC][5]);
826 #endif
827
828         return tas3004_sync_register(self, TAS3004_REG_DRC);
829 }
830
831 static int
832 tas3004_drce_rw(        struct tas3004_data_t *self,
833                         u_int cmd,
834                         u_long arg)
835 {
836         int rc;
837         struct tas_drce_ctrl_t drce_ctrl;
838         void __user *argp = (void __user *)arg;
839
840         if (copy_from_user(&drce_ctrl, argp, sizeof(struct tas_drce_ctrl_t)))
841                 return -EFAULT;
842
843 #ifdef DEBUG_DRCE
844         printk("DRCE: input [ FLAGS:%x ENABLE:%x ABOVE:%x/%x BELOW:%x/%x THRESH:%x ENERGY:%x ATTACK:%x DECAY:%x\n",
845                drce_ctrl.flags,
846                drce_ctrl.data.enable,
847                drce_ctrl.data.above.expand,drce_ctrl.data.above.val,
848                drce_ctrl.data.below.expand,drce_ctrl.data.below.val,
849                drce_ctrl.data.threshold,
850                drce_ctrl.data.energy,
851                drce_ctrl.data.attack,
852                drce_ctrl.data.decay);
853 #endif
854
855         if (cmd & SIOC_IN) {
856                 rc = tas3004_update_drce(self, drce_ctrl.flags, &drce_ctrl.data);
857                 if (rc < 0) return rc;
858         }
859
860         if (cmd & SIOC_OUT) {
861                 if (drce_ctrl.flags & TAS_DRCE_ENABLE)
862                         drce_ctrl.data.enable = self->drce_state.enable;
863                 if (drce_ctrl.flags & TAS_DRCE_ABOVE_RATIO)
864                         drce_ctrl.data.above = self->drce_state.above;
865                 if (drce_ctrl.flags & TAS_DRCE_BELOW_RATIO)
866                         drce_ctrl.data.below = self->drce_state.below;
867                 if (drce_ctrl.flags & TAS_DRCE_THRESHOLD)
868                         drce_ctrl.data.threshold = self->drce_state.threshold;
869                 if (drce_ctrl.flags & TAS_DRCE_ENERGY)
870                         drce_ctrl.data.energy = self->drce_state.energy;
871                 if (drce_ctrl.flags & TAS_DRCE_ATTACK)
872                         drce_ctrl.data.attack = self->drce_state.attack;
873                 if (drce_ctrl.flags & TAS_DRCE_DECAY)
874                         drce_ctrl.data.decay = self->drce_state.decay;
875
876                 if (copy_to_user(argp, &drce_ctrl,
877                                  sizeof(struct tas_drce_ctrl_t))) {
878                         return -EFAULT;
879                 }
880         }
881
882         return 0;
883 }
884
885 static void
886 tas3004_update_device_parameters(struct tas3004_data_t *self)
887 {
888         char data;
889         int i;
890
891         if (!self) return;
892
893         if (self->output_id == TAS_OUTPUT_HEADPHONES) {
894                 /* turn on allPass when headphones are plugged in */
895                 data = 0x02;
896         } else {
897                 data = 0x00;
898         }
899
900         tas3004_write_register(self, TAS3004_REG_MCR2, &data, WRITE_NORMAL | FORCE_WRITE);
901
902         for (i=0; tas3004_eq_prefs[i]; i++) {
903                 struct tas_eq_pref_t *eq = tas3004_eq_prefs[i];
904
905                 if (eq->device_id == self->device_id &&
906                     (eq->output_id == 0 || eq->output_id == self->output_id) &&
907                     (eq->speaker_id == 0 || eq->speaker_id == self->speaker_id)) {
908
909                         tas3004_update_drce(self, TAS_DRCE_ALL, eq->drce);
910                         tas3004_write_biquad_list(self, eq->filter_count, TAS_BIQUAD_FAST_LOAD, eq->biquads);
911
912                         break;
913                 }
914         }
915 }
916
917 static void
918 tas3004_device_change_handler(struct work_struct *work)
919 {
920         struct tas3004_data_t *self;
921         self = container_of(work, struct tas3004_data_t, change);
922         tas3004_update_device_parameters(self);
923 }
924
925 static int
926 tas3004_output_device_change(   struct tas3004_data_t *self,
927                                 int device_id,
928                                 int output_id,
929                                 int speaker_id)
930 {
931         self->device_id=device_id;
932         self->output_id=output_id;
933         self->speaker_id=speaker_id;
934
935         schedule_work(&self->change);
936
937         return 0;
938 }
939
940 static int
941 tas3004_device_ioctl(   struct tas3004_data_t *self,
942                         u_int cmd,
943                         u_long arg)
944 {
945         uint __user *argp = (void __user *)arg;
946         switch (cmd) {
947         case TAS_READ_EQ:
948         case TAS_WRITE_EQ:
949                 return tas3004_eq_rw(self, cmd, arg);
950
951         case TAS_READ_EQ_LIST:
952         case TAS_WRITE_EQ_LIST:
953                 return tas3004_eq_list_rw(self, cmd, arg);
954
955         case TAS_READ_EQ_FILTER_COUNT:
956                 put_user(TAS3004_BIQUAD_FILTER_COUNT, argp);
957                 return 0;
958
959         case TAS_READ_EQ_CHANNEL_COUNT:
960                 put_user(TAS3004_BIQUAD_CHANNEL_COUNT, argp);
961                 return 0;
962
963         case TAS_READ_DRCE:
964         case TAS_WRITE_DRCE:
965                 return tas3004_drce_rw(self, cmd, arg);
966
967         case TAS_READ_DRCE_CAPS:
968                 put_user(TAS_DRCE_ENABLE         |
969                          TAS_DRCE_ABOVE_RATIO    |
970                          TAS_DRCE_BELOW_RATIO    |
971                          TAS_DRCE_THRESHOLD      |
972                          TAS_DRCE_ENERGY         |
973                          TAS_DRCE_ATTACK         |
974                          TAS_DRCE_DECAY,
975                          argp);
976                 return 0;
977
978         case TAS_READ_DRCE_MIN:
979         case TAS_READ_DRCE_MAX: {
980                 struct tas_drce_ctrl_t drce_ctrl;
981                 const struct tas_drce_t *drce_copy;
982
983                 if (copy_from_user(&drce_ctrl, argp,
984                                    sizeof(struct tas_drce_ctrl_t))) {
985                         return -EFAULT;
986                 }
987
988                 if (cmd == TAS_READ_DRCE_MIN) {
989                         drce_copy=&tas3004_drce_min;
990                 } else {
991                         drce_copy=&tas3004_drce_max;
992                 }
993
994                 if (drce_ctrl.flags & TAS_DRCE_ABOVE_RATIO) {
995                         drce_ctrl.data.above=drce_copy->above;
996                 }
997                 if (drce_ctrl.flags & TAS_DRCE_BELOW_RATIO) {
998                         drce_ctrl.data.below=drce_copy->below;
999                 }
1000                 if (drce_ctrl.flags & TAS_DRCE_THRESHOLD) {
1001                         drce_ctrl.data.threshold=drce_copy->threshold;
1002                 }
1003                 if (drce_ctrl.flags & TAS_DRCE_ENERGY) {
1004                         drce_ctrl.data.energy=drce_copy->energy;
1005                 }
1006                 if (drce_ctrl.flags & TAS_DRCE_ATTACK) {
1007                         drce_ctrl.data.attack=drce_copy->attack;
1008                 }
1009                 if (drce_ctrl.flags & TAS_DRCE_DECAY) {
1010                         drce_ctrl.data.decay=drce_copy->decay;
1011                 }
1012
1013                 if (copy_to_user(argp, &drce_ctrl,
1014                                  sizeof(struct tas_drce_ctrl_t))) {
1015                         return -EFAULT;
1016                 }
1017         }
1018         }
1019
1020         return -EINVAL;
1021 }
1022
1023 static int
1024 tas3004_init_mixer(struct tas3004_data_t *self)
1025 {
1026         unsigned char mcr = (1<<6)+(2<<4)+(2<<2);
1027
1028         /* Make sure something answers on the i2c bus */
1029         if (tas3004_write_register(self, TAS3004_REG_MCR, &mcr,
1030             WRITE_NORMAL | FORCE_WRITE) < 0)
1031                 return -1;
1032
1033         tas3004_fast_load(self, 1);
1034
1035         (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD0);
1036         (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD1);
1037         (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD2);
1038         (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD3);
1039         (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD4);
1040         (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD5);
1041         (void)tas3004_sync_register(self,TAS3004_REG_RIGHT_BIQUAD6);
1042
1043         (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD0);
1044         (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD1);
1045         (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD2);
1046         (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD3);
1047         (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD4);
1048         (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD5);
1049         (void)tas3004_sync_register(self,TAS3004_REG_LEFT_BIQUAD6);
1050
1051         tas3004_sync_register(self, TAS3004_REG_DRC);
1052
1053         tas3004_sync_register(self, TAS3004_REG_MCR2);
1054
1055         tas3004_fast_load(self, 0);
1056
1057         tas3004_set_mixer_level(self, SOUND_MIXER_VOLUME, VOL_DEFAULT<<8 | VOL_DEFAULT);
1058         tas3004_set_mixer_level(self, SOUND_MIXER_PCM, INPUT_DEFAULT<<8 | INPUT_DEFAULT);
1059         tas3004_set_mixer_level(self, SOUND_MIXER_ALTPCM, 0);
1060         tas3004_set_mixer_level(self, SOUND_MIXER_IMIX, 0);
1061
1062         tas3004_set_mixer_level(self, SOUND_MIXER_BASS, BASS_DEFAULT);
1063         tas3004_set_mixer_level(self, SOUND_MIXER_TREBLE, TREBLE_DEFAULT);
1064
1065         tas3004_set_mixer_level(self, SOUND_MIXER_LINE,SW_INPUT_VOLUME_DEFAULT);
1066
1067         return 0;
1068 }
1069
1070 static int
1071 tas3004_uninit_mixer(struct tas3004_data_t *self)
1072 {
1073         tas3004_set_mixer_level(self, SOUND_MIXER_VOLUME, 0);
1074         tas3004_set_mixer_level(self, SOUND_MIXER_PCM, 0);
1075         tas3004_set_mixer_level(self, SOUND_MIXER_ALTPCM, 0);
1076         tas3004_set_mixer_level(self, SOUND_MIXER_IMIX, 0);
1077
1078         tas3004_set_mixer_level(self, SOUND_MIXER_BASS, 0);
1079         tas3004_set_mixer_level(self, SOUND_MIXER_TREBLE, 0);
1080
1081         tas3004_set_mixer_level(self, SOUND_MIXER_LINE, 0);
1082
1083         return 0;
1084 }
1085
1086 static int
1087 tas3004_init(struct i2c_client *client)
1088 {
1089         struct tas3004_data_t *self;
1090         size_t sz = sizeof(*self) + (TAS3004_REG_MAX*sizeof(tas_shadow_t));
1091         char drce_init[] = { 0x69, 0x22, 0x9f, 0xb0, 0x60, 0xa0 };
1092         char mcr2 = 0;
1093         int i, j;
1094
1095         self = kmalloc(sz, GFP_KERNEL);
1096         if (!self)
1097                 return -ENOMEM;
1098         memset(self, 0, sz);
1099
1100         self->super.client = client;
1101         self->super.shadow = (tas_shadow_t *)(self+1);
1102         self->output_id = TAS_OUTPUT_HEADPHONES;
1103
1104         dev_set_drvdata(&client->dev, self);
1105
1106         for (i = 0; i < TAS3004_BIQUAD_CHANNEL_COUNT; i++)
1107                 for (j = 0; j<TAS3004_BIQUAD_FILTER_COUNT; j++)
1108                         tas3004_write_biquad_shadow(self, i, j,
1109                                         &tas3004_eq_unity);
1110
1111         tas3004_write_register(self, TAS3004_REG_MCR2, &mcr2, WRITE_SHADOW);
1112         tas3004_write_register(self, TAS3004_REG_DRC, drce_init, WRITE_SHADOW);
1113
1114         INIT_WORK(&self->change, tas3004_device_change_handler);
1115         return 0;
1116 }
1117
1118 static void 
1119 tas3004_uninit(struct tas3004_data_t *self)
1120 {
1121         tas3004_uninit_mixer(self);
1122         kfree(self);
1123 }
1124
1125
1126 struct tas_driver_hooks_t tas3004_hooks = {
1127         .init                   = (tas_hook_init_t)tas3004_init,
1128         .post_init              = (tas_hook_post_init_t)tas3004_init_mixer,
1129         .uninit                 = (tas_hook_uninit_t)tas3004_uninit,
1130         .get_mixer_level        = (tas_hook_get_mixer_level_t)tas3004_get_mixer_level,
1131         .set_mixer_level        = (tas_hook_set_mixer_level_t)tas3004_set_mixer_level,
1132         .enter_sleep            = (tas_hook_enter_sleep_t)tas3004_enter_sleep,
1133         .leave_sleep            = (tas_hook_leave_sleep_t)tas3004_leave_sleep,
1134         .supported_mixers       = (tas_hook_supported_mixers_t)tas3004_supported_mixers,
1135         .mixer_is_stereo        = (tas_hook_mixer_is_stereo_t)tas3004_mixer_is_stereo,
1136         .stereo_mixers          = (tas_hook_stereo_mixers_t)tas3004_stereo_mixers,
1137         .output_device_change   = (tas_hook_output_device_change_t)tas3004_output_device_change,
1138         .device_ioctl           = (tas_hook_device_ioctl_t)tas3004_device_ioctl
1139 };