1
2#undef FKS_LOGGING
3#undef FKS_TEST
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189#include <linux/delay.h>
190#include <linux/interrupt.h>
191#include <linux/spinlock.h>
192
193#include "sound_config.h"
194#include "sb_mixer.h"
195#include "sb.h"
196
197#include "sb_ess.h"
198
199#define ESSTYPE_LIKE20 -1
200#define ESSTYPE_DETECT 0
201
202#define SUBMDL_ES1788 0x10
203#define SUBMDL_ES1868 0x11
204#define SUBMDL_ES1869 0x12
205#define SUBMDL_ES1878 0x13
206#define SUBMDL_ES1879 0x16
207#define SUBMDL_ES1887 0x14
208#define SUBMDL_ES1888 0x15
209
210#define SB_CAP_ES18XX_RATE 0x100
211
212#define ES1688_CLOCK1 795444
213#define ES1688_CLOCK2 397722
214#define ES18XX_CLOCK1 793800
215#define ES18XX_CLOCK2 768000
216
217#ifdef FKS_LOGGING
218static void ess_show_mixerregs (sb_devc *devc);
219#endif
220static int ess_read (sb_devc * devc, unsigned char reg);
221static int ess_write (sb_devc * devc, unsigned char reg, unsigned char data);
222static void ess_chgmixer
223 (sb_devc * devc, unsigned int reg, unsigned int mask, unsigned int val);
224
225
226
227
228
229
230
231struct ess_command {short cmd; short data;};
232
233
234
235
236static struct ess_command ess_i08m[] =
237 { {0xb7, 0x51}, {0xb7, 0xd0}, {-1, 0} };
238static struct ess_command ess_i16m[] =
239 { {0xb7, 0x71}, {0xb7, 0xf4}, {-1, 0} };
240static struct ess_command ess_i08s[] =
241 { {0xb7, 0x51}, {0xb7, 0x98}, {-1, 0} };
242static struct ess_command ess_i16s[] =
243 { {0xb7, 0x71}, {0xb7, 0xbc}, {-1, 0} };
244
245static struct ess_command *ess_inp_cmds[] =
246 { ess_i08m, ess_i16m, ess_i08s, ess_i16s };
247
248
249
250
251
252static struct ess_command ess_o08m[] =
253 { {0xb6, 0x80}, {0xb7, 0x51}, {0xb7, 0xd0}, {-1, 0} };
254static struct ess_command ess_o16m[] =
255 { {0xb6, 0x00}, {0xb7, 0x71}, {0xb7, 0xf4}, {-1, 0} };
256static struct ess_command ess_o08s[] =
257 { {0xb6, 0x80}, {0xb7, 0x51}, {0xb7, 0x98}, {-1, 0} };
258static struct ess_command ess_o16s[] =
259 { {0xb6, 0x00}, {0xb7, 0x71}, {0xb7, 0xbc}, {-1, 0} };
260
261static struct ess_command *ess_out_cmds[] =
262 { ess_o08m, ess_o16m, ess_o08s, ess_o16s };
263
264static void ess_exec_commands
265 (sb_devc *devc, struct ess_command *cmdtab[])
266{
267 struct ess_command *cmd;
268
269 cmd = cmdtab [ ((devc->channels != 1) << 1) + (devc->bits != AFMT_U8) ];
270
271 while (cmd->cmd != -1) {
272 ess_write (devc, cmd->cmd, cmd->data);
273 cmd++;
274 }
275}
276
277static void ess_change
278 (sb_devc *devc, unsigned int reg, unsigned int mask, unsigned int val)
279{
280 int value;
281
282 value = ess_read (devc, reg);
283 value = (value & ~mask) | (val & mask);
284 ess_write (devc, reg, value);
285}
286
287static void ess_set_output_parms
288 (int dev, unsigned long buf, int nr_bytes, int intrflag)
289{
290 sb_devc *devc = audio_devs[dev]->devc;
291
292 if (devc->duplex) {
293 devc->trg_buf_16 = buf;
294 devc->trg_bytes_16 = nr_bytes;
295 devc->trg_intrflag_16 = intrflag;
296 devc->irq_mode_16 = IMODE_OUTPUT;
297 } else {
298 devc->trg_buf = buf;
299 devc->trg_bytes = nr_bytes;
300 devc->trg_intrflag = intrflag;
301 devc->irq_mode = IMODE_OUTPUT;
302 }
303}
304
305static void ess_set_input_parms
306 (int dev, unsigned long buf, int count, int intrflag)
307{
308 sb_devc *devc = audio_devs[dev]->devc;
309
310 devc->trg_buf = buf;
311 devc->trg_bytes = count;
312 devc->trg_intrflag = intrflag;
313 devc->irq_mode = IMODE_INPUT;
314}
315
316static int ess_calc_div (int clock, int revert, int *speedp, int *diffp)
317{
318 int divider;
319 int speed, diff;
320 int retval;
321
322 speed = *speedp;
323 divider = (clock + speed / 2) / speed;
324 retval = revert - divider;
325 if (retval > revert - 1) {
326 retval = revert - 1;
327 divider = revert - retval;
328 }
329
330
331
332
333 *speedp = clock / divider;
334 diff = speed - *speedp;
335 if (diff < 0) diff =-diff;
336 *diffp = diff;
337
338 return retval;
339}
340
341static int ess_calc_best_speed
342 (int clock1, int rev1, int clock2, int rev2, int *divp, int *speedp)
343{
344 int speed1 = *speedp, speed2 = *speedp;
345 int div1, div2;
346 int diff1, diff2;
347 int retval;
348
349 div1 = ess_calc_div (clock1, rev1, &speed1, &diff1);
350 div2 = ess_calc_div (clock2, rev2, &speed2, &diff2);
351
352 if (diff1 < diff2) {
353 *divp = div1;
354 *speedp = speed1;
355 retval = 1;
356 } else {
357
358 *divp = 0x80 | div2;
359 *speedp = speed2;
360 retval = 2;
361 }
362
363 return retval;
364}
365
366
367
368
369
370
371
372
373
374static void ess_common_speed (sb_devc *devc, int *speedp, int *divp)
375{
376 int diff = 0, div;
377
378 if (devc->duplex) {
379
380
381
382 if (devc->submodel == SUBMDL_ES1888) {
383 div = 0x80 | ess_calc_div (795500, 256, speedp, &diff);
384 } else {
385 div = 0x80 | ess_calc_div (795500, 128, speedp, &diff);
386 }
387 } else if(devc->caps & SB_CAP_ES18XX_RATE) {
388 if (devc->submodel == SUBMDL_ES1888) {
389 ess_calc_best_speed(397700, 128, 795500, 256,
390 &div, speedp);
391 } else {
392 ess_calc_best_speed(ES18XX_CLOCK1, 128, ES18XX_CLOCK2, 256,
393 &div, speedp);
394 }
395 } else {
396 if (*speedp > 22000) {
397 div = 0x80 | ess_calc_div (ES1688_CLOCK1, 256, speedp, &diff);
398 } else {
399 div = 0x00 | ess_calc_div (ES1688_CLOCK2, 128, speedp, &diff);
400 }
401 }
402 *divp = div;
403}
404
405static void ess_speed (sb_devc *devc, int audionum)
406{
407 int speed;
408 int div, div2;
409
410 ess_common_speed (devc, &(devc->speed), &div);
411
412#ifdef FKS_REG_LOGGING
413printk (KERN_INFO "FKS: ess_speed (%d) b speed = %d, div=%x\n", audionum, devc->speed, div);
414#endif
415
416
417 speed = (devc->speed * 9) / 20;
418
419 div2 = 256 - 7160000 / (speed * 82);
420
421 if (!devc->duplex) audionum = 1;
422
423 if (audionum == 1) {
424
425
426
427 ess_write (devc, 0xa1, div);
428 ess_write (devc, 0xa2, div2);
429 } else {
430 ess_setmixer (devc, 0x70, div);
431
432
433
434 ess_write (devc, 0xa2, div2);
435 ess_setmixer (devc, 0x72, div2);
436 }
437}
438
439static int ess_audio_prepare_for_input(int dev, int bsize, int bcount)
440{
441 sb_devc *devc = audio_devs[dev]->devc;
442
443 ess_speed(devc, 1);
444
445 sb_dsp_command(devc, DSP_CMD_SPKOFF);
446
447 ess_write (devc, 0xb8, 0x0e);
448 ess_change (devc, 0xa8, 0x03, 3 - devc->channels);
449 ess_write (devc, 0xb9, 2);
450
451 ess_exec_commands (devc, ess_inp_cmds);
452
453 ess_change (devc, 0xb1, 0xf0, 0x50);
454 ess_change (devc, 0xb2, 0xf0, 0x50);
455
456 devc->trigger_bits = 0;
457 return 0;
458}
459
460static int ess_audio_prepare_for_output_audio1 (int dev, int bsize, int bcount)
461{
462 sb_devc *devc = audio_devs[dev]->devc;
463
464 sb_dsp_reset(devc);
465 ess_speed(devc, 1);
466 ess_write (devc, 0xb8, 4);
467 ess_change (devc, 0xa8, 0x03, 3 - devc->channels);
468 ess_write (devc, 0xb9, 2);
469
470 ess_exec_commands (devc, ess_out_cmds);
471
472 ess_change (devc, 0xb1, 0xf0, 0x50);
473 ess_change (devc, 0xb2, 0xf0, 0x50);
474
475 sb_dsp_command(devc, DSP_CMD_SPKON);
476
477 devc->trigger_bits = 0;
478 return 0;
479}
480
481static int ess_audio_prepare_for_output_audio2 (int dev, int bsize, int bcount)
482{
483 sb_devc *devc = audio_devs[dev]->devc;
484 unsigned char bits;
485
486
487
488
489
490
491
492
493
494
495 ess_chgmixer (devc, 0x78, 0xd0, 0xd0);
496
497 ess_speed(devc, 2);
498
499
500 bits = ess_getmixer (devc, 0x7a) & 0x18;
501
502
503 if (devc->channels != 1) bits |= 0x02;
504
505
506 if (devc->bits != AFMT_U8) bits |= 0x05;
507
508
509 bits |= 0x60;
510
511 ess_setmixer (devc, 0x7a, bits);
512
513 ess_mixer_reload (devc, SOUND_MIXER_PCM);
514
515 devc->trigger_bits = 0;
516 return 0;
517}
518
519static int ess_audio_prepare_for_output(int dev, int bsize, int bcount)
520{
521 sb_devc *devc = audio_devs[dev]->devc;
522
523#ifdef FKS_REG_LOGGING
524printk(KERN_INFO "ess_audio_prepare_for_output: dma_out=%d,dma_in=%d\n"
525, audio_devs[dev]->dmap_out->dma, audio_devs[dev]->dmap_in->dma);
526#endif
527
528 if (devc->duplex) {
529 return ess_audio_prepare_for_output_audio2 (dev, bsize, bcount);
530 } else {
531 return ess_audio_prepare_for_output_audio1 (dev, bsize, bcount);
532 }
533}
534
535static void ess_audio_halt_xfer(int dev)
536{
537 unsigned long flags;
538 sb_devc *devc = audio_devs[dev]->devc;
539
540 spin_lock_irqsave(&devc->lock, flags);
541 sb_dsp_reset(devc);
542 spin_unlock_irqrestore(&devc->lock, flags);
543
544
545
546
547 if (devc->duplex) ess_chgmixer(devc, 0x78, 0x03, 0x00);
548}
549
550static void ess_audio_start_input
551 (int dev, unsigned long buf, int nr_bytes, int intrflag)
552{
553 int count = nr_bytes;
554 sb_devc *devc = audio_devs[dev]->devc;
555 short c = -nr_bytes;
556
557
558
559
560
561 if (audio_devs[dev]->dmap_in->dma > 3) count >>= 1;
562 count--;
563
564 devc->irq_mode = IMODE_INPUT;
565
566 ess_write (devc, 0xa4, (unsigned char) ((unsigned short) c & 0xff));
567 ess_write (devc, 0xa5, (unsigned char) (((unsigned short) c >> 8) & 0xff));
568
569 ess_change (devc, 0xb8, 0x0f, 0x0f);
570 devc->intr_active = 1;
571}
572
573static void ess_audio_output_block_audio1
574 (int dev, unsigned long buf, int nr_bytes, int intrflag)
575{
576 int count = nr_bytes;
577 sb_devc *devc = audio_devs[dev]->devc;
578 short c = -nr_bytes;
579
580 if (audio_devs[dev]->dmap_out->dma > 3)
581 count >>= 1;
582 count--;
583
584 devc->irq_mode = IMODE_OUTPUT;
585
586 ess_write (devc, 0xa4, (unsigned char) ((unsigned short) c & 0xff));
587 ess_write (devc, 0xa5, (unsigned char) (((unsigned short) c >> 8) & 0xff));
588
589 ess_change (devc, 0xb8, 0x05, 0x05);
590 devc->intr_active = 1;
591}
592
593static void ess_audio_output_block_audio2
594 (int dev, unsigned long buf, int nr_bytes, int intrflag)
595{
596 int count = nr_bytes;
597 sb_devc *devc = audio_devs[dev]->devc;
598 short c = -nr_bytes;
599
600 if (audio_devs[dev]->dmap_out->dma > 3) count >>= 1;
601 count--;
602
603 ess_setmixer (devc, 0x74, (unsigned char) ((unsigned short) c & 0xff));
604 ess_setmixer (devc, 0x76, (unsigned char) (((unsigned short) c >> 8) & 0xff));
605 ess_chgmixer (devc, 0x78, 0x03, 0x03);
606
607 devc->irq_mode_16 = IMODE_OUTPUT;
608 devc->intr_active_16 = 1;
609}
610
611static void ess_audio_output_block
612 (int dev, unsigned long buf, int nr_bytes, int intrflag)
613{
614 sb_devc *devc = audio_devs[dev]->devc;
615
616 if (devc->duplex) {
617 ess_audio_output_block_audio2 (dev, buf, nr_bytes, intrflag);
618 } else {
619 ess_audio_output_block_audio1 (dev, buf, nr_bytes, intrflag);
620 }
621}
622
623
624
625
626
627static void ess_audio_trigger(int dev, int bits)
628{
629 sb_devc *devc = audio_devs[dev]->devc;
630
631 int bits_16 = bits & devc->irq_mode_16;
632 bits &= devc->irq_mode;
633
634 if (!bits && !bits_16) {
635
636 sb_dsp_command(devc, 0xd0);
637 }
638
639 if (bits) {
640 switch (devc->irq_mode)
641 {
642 case IMODE_INPUT:
643 ess_audio_start_input(dev, devc->trg_buf, devc->trg_bytes,
644 devc->trg_intrflag);
645 break;
646
647 case IMODE_OUTPUT:
648 ess_audio_output_block(dev, devc->trg_buf, devc->trg_bytes,
649 devc->trg_intrflag);
650 break;
651 }
652 }
653
654 if (bits_16) {
655 switch (devc->irq_mode_16) {
656 case IMODE_INPUT:
657 ess_audio_start_input(dev, devc->trg_buf_16, devc->trg_bytes_16,
658 devc->trg_intrflag_16);
659 break;
660
661 case IMODE_OUTPUT:
662 ess_audio_output_block(dev, devc->trg_buf_16, devc->trg_bytes_16,
663 devc->trg_intrflag_16);
664 break;
665 }
666 }
667
668 devc->trigger_bits = bits | bits_16;
669}
670
671static int ess_audio_set_speed(int dev, int speed)
672{
673 sb_devc *devc = audio_devs[dev]->devc;
674 int minspeed, maxspeed, dummydiv;
675
676 if (speed > 0) {
677 minspeed = (devc->duplex ? 6215 : 5000 );
678 maxspeed = (devc->duplex ? 44100 : 48000);
679 if (speed < minspeed) speed = minspeed;
680 if (speed > maxspeed) speed = maxspeed;
681
682 ess_common_speed (devc, &speed, &dummydiv);
683
684 devc->speed = speed;
685 }
686 return devc->speed;
687}
688
689
690
691
692static unsigned int ess_audio_set_bits(int dev, unsigned int bits)
693{
694 sb_devc *devc = audio_devs[dev]->devc;
695
696 if (bits != 0) {
697 if (bits == AFMT_U8 || bits == AFMT_S16_LE) {
698 devc->bits = bits;
699 } else {
700 devc->bits = AFMT_U8;
701 }
702 }
703
704 return devc->bits;
705}
706
707
708
709
710
711static short ess_audio_set_channels(int dev, short channels)
712{
713 sb_devc *devc = audio_devs[dev]->devc;
714
715 if (channels == 1 || channels == 2) devc->channels = channels;
716
717 return devc->channels;
718}
719
720static struct audio_driver ess_audio_driver =
721{
722 .owner = THIS_MODULE,
723 .open = sb_audio_open,
724 .close = sb_audio_close,
725 .output_block = ess_set_output_parms,
726 .start_input = ess_set_input_parms,
727 .prepare_for_input = ess_audio_prepare_for_input,
728 .prepare_for_output = ess_audio_prepare_for_output,
729 .halt_io = ess_audio_halt_xfer,
730 .trigger = ess_audio_trigger,
731 .set_speed = ess_audio_set_speed,
732 .set_bits = ess_audio_set_bits,
733 .set_channels = ess_audio_set_channels
734};
735
736
737
738
739struct audio_driver *ess_audio_init
740 (sb_devc *devc, int *audio_flags, int *format_mask)
741{
742 *audio_flags = DMA_AUTOMODE;
743 *format_mask |= AFMT_S16_LE;
744
745 if (devc->duplex) {
746 int tmp_dma;
747
748
749
750
751 tmp_dma = devc->dma16;
752 devc->dma16 = devc->dma8;
753 devc->dma8 = tmp_dma;
754
755 *audio_flags |= DMA_DUPLEX;
756 }
757
758 return &ess_audio_driver;
759}
760
761
762
763
764
765
766static void ess_handle_channel
767 (char *channel, int dev, int intr_active, unsigned char flag, int irq_mode)
768{
769 if (!intr_active || !flag) return;
770#ifdef FKS_REG_LOGGING
771printk(KERN_INFO "FKS: ess_handle_channel %s irq_mode=%d\n", channel, irq_mode);
772#endif
773 switch (irq_mode) {
774 case IMODE_OUTPUT:
775 DMAbuf_outputintr (dev, 1);
776 break;
777
778 case IMODE_INPUT:
779 DMAbuf_inputintr (dev);
780 break;
781
782 case IMODE_INIT:
783 break;
784
785 default:;
786
787 }
788}
789
790
791
792
793
794
795
796void ess_intr (sb_devc *devc)
797{
798 int status;
799 unsigned char src;
800
801 if (devc->submodel == SUBMDL_ES1887) {
802 src = ess_getmixer (devc, 0x7f) >> 4;
803 } else {
804 src = 0xff;
805 }
806
807#ifdef FKS_REG_LOGGING
808printk(KERN_INFO "FKS: sbintr src=%x\n",(int)src);
809#endif
810 ess_handle_channel
811 ( "Audio 1"
812 , devc->dev, devc->intr_active , src & 0x01, devc->irq_mode );
813 ess_handle_channel
814 ( "Audio 2"
815 , devc->dev, devc->intr_active_16, src & 0x02, devc->irq_mode_16);
816
817
818
819 if (devc->submodel == SUBMDL_ES1887 && (src & 0x02)) {
820 ess_chgmixer (devc, 0x7a, 0x80, 0x00);
821 }
822
823 if (src & 0x01) {
824 status = inb(DSP_DATA_AVAIL);
825 }
826}
827
828static void ess_extended (sb_devc * devc)
829{
830
831
832 sb_dsp_command(devc, 0xc6);
833}
834
835static int ess_write (sb_devc * devc, unsigned char reg, unsigned char data)
836{
837#ifdef FKS_REG_LOGGING
838printk(KERN_INFO "FKS: write reg %x: %x\n", reg, data);
839#endif
840
841
842 if (!sb_dsp_command(devc, reg))
843 return 0;
844
845 return sb_dsp_command(devc, data);
846}
847
848static int ess_read (sb_devc * devc, unsigned char reg)
849{
850
851
852
853 if (!sb_dsp_command(devc, 0xc0)) return -1;
854
855 if (!sb_dsp_command(devc, reg )) return -1;
856
857 return sb_dsp_get_byte(devc);
858}
859
860int ess_dsp_reset(sb_devc * devc)
861{
862 int loopc;
863
864#ifdef FKS_REG_LOGGING
865printk(KERN_INFO "FKS: ess_dsp_reset 1\n");
866ess_show_mixerregs (devc);
867#endif
868
869 DEB(printk("Entered ess_dsp_reset()\n"));
870
871 outb(3, DSP_RESET);
872
873 udelay(10);
874 outb(0, DSP_RESET);
875 udelay(30);
876
877 for (loopc = 0; loopc < 1000 && !(inb(DSP_DATA_AVAIL) & 0x80); loopc++);
878
879 if (inb(DSP_READ) != 0xAA) {
880 DDB(printk("sb: No response to RESET\n"));
881 return 0;
882 }
883 ess_extended (devc);
884
885 DEB(printk("sb_dsp_reset() OK\n"));
886
887#ifdef FKS_LOGGING
888printk(KERN_INFO "FKS: dsp_reset 2\n");
889ess_show_mixerregs (devc);
890#endif
891
892 return 1;
893}
894
895static int ess_irq_bits (int irq)
896{
897 switch (irq) {
898 case 2:
899 case 9:
900 return 0;
901
902 case 5:
903 return 1;
904
905 case 7:
906 return 2;
907
908 case 10:
909 return 3;
910
911 default:
912 printk(KERN_ERR "ESS1688: Invalid IRQ %d\n", irq);
913 return -1;
914 }
915}
916
917
918
919
920static int ess_common_set_irq_hw (sb_devc * devc)
921{
922 int irq_bits;
923
924 if ((irq_bits = ess_irq_bits (devc->irq)) == -1) return 0;
925
926 if (!ess_write (devc, 0xb1, 0x50 | (irq_bits << 2))) {
927 printk(KERN_ERR "ES1688: Failed to write to IRQ config register\n");
928 return 0;
929 }
930 return 1;
931}
932
933
934
935
936
937
938
939
940static void ess_es1887_set_irq_hw (sb_devc * devc)
941{
942 int irq_bits;
943
944 if ((irq_bits = ess_irq_bits (devc->irq)) == -1) return;
945
946 ess_chgmixer (devc, 0x7f, 0x0f, 0x01 | ((irq_bits + 1) << 1));
947}
948
949static int ess_set_irq_hw (sb_devc * devc)
950{
951 if (devc->submodel == SUBMDL_ES1887) ess_es1887_set_irq_hw (devc);
952
953 return ess_common_set_irq_hw (devc);
954}
955
956#ifdef FKS_TEST
957
958
959
960
961
962
963
964
965
966
967static void FKS_test (sb_devc * devc)
968{
969 int val1, val2;
970 val1 = ess_getmixer (devc, 0x64);
971 ess_setmixer (devc, 0x64, ~val1);
972 val2 = ess_getmixer (devc, 0x64) ^ ~val1;
973 ess_setmixer (devc, 0x64, val1);
974 val1 ^= ess_getmixer (devc, 0x64);
975printk (KERN_INFO "FKS: FKS_test %02x, %02x\n", (val1 & 0x0ff), (val2 & 0x0ff));
976};
977#endif
978
979static unsigned int ess_identify (sb_devc * devc)
980{
981 unsigned int val;
982 unsigned long flags;
983
984 spin_lock_irqsave(&devc->lock, flags);
985 outb(((unsigned char) (0x40 & 0xff)), MIXER_ADDR);
986
987 udelay(20);
988 val = inb(MIXER_DATA) << 8;
989 udelay(20);
990 val |= inb(MIXER_DATA);
991 udelay(20);
992 spin_unlock_irqrestore(&devc->lock, flags);
993
994 return val;
995}
996
997
998
999
1000
1001
1002
1003
1004
1005static int ess_probe (sb_devc * devc, int reg, int xorval)
1006{
1007 int val1, val2, val3;
1008
1009 val1 = ess_getmixer (devc, reg);
1010 val2 = val1 ^ xorval;
1011 ess_setmixer (devc, reg, val2);
1012 val3 = ess_getmixer (devc, reg);
1013 ess_setmixer (devc, reg, val1);
1014
1015 return (val2 == val3);
1016}
1017
1018int ess_init(sb_devc * devc, struct address_info *hw_config)
1019{
1020 unsigned char cfg;
1021 int ess_major = 0, ess_minor = 0;
1022 int i;
1023 static char name[100], modelname[10];
1024
1025
1026
1027
1028
1029 sb_dsp_command(devc, 0xe7);
1030
1031 for (i = 1000; i; i--) {
1032 if (inb(DSP_DATA_AVAIL) & 0x80) {
1033 if (ess_major == 0) {
1034 ess_major = inb(DSP_READ);
1035 } else {
1036 ess_minor = inb(DSP_READ);
1037 break;
1038 }
1039 }
1040 }
1041
1042 if (ess_major == 0) return 0;
1043
1044 if (ess_major == 0x48 && (ess_minor & 0xf0) == 0x80) {
1045 sprintf(name, "ESS ES488 AudioDrive (rev %d)",
1046 ess_minor & 0x0f);
1047 hw_config->name = name;
1048 devc->model = MDL_SBPRO;
1049 return 1;
1050 }
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067 devc->model = MDL_ESS;
1068 devc->submodel = ess_minor & 0x0f;
1069
1070 if (ess_major == 0x68 && (ess_minor & 0xf0) == 0x80) {
1071 char *chip = NULL;
1072 int submodel = -1;
1073
1074 switch (devc->sbmo.esstype) {
1075 case ESSTYPE_DETECT:
1076 case ESSTYPE_LIKE20:
1077 break;
1078 case 688:
1079 submodel = 0x00;
1080 break;
1081 case 1688:
1082 submodel = 0x08;
1083 break;
1084 case 1868:
1085 submodel = SUBMDL_ES1868;
1086 break;
1087 case 1869:
1088 submodel = SUBMDL_ES1869;
1089 break;
1090 case 1788:
1091 submodel = SUBMDL_ES1788;
1092 break;
1093 case 1878:
1094 submodel = SUBMDL_ES1878;
1095 break;
1096 case 1879:
1097 submodel = SUBMDL_ES1879;
1098 break;
1099 case 1887:
1100 submodel = SUBMDL_ES1887;
1101 break;
1102 case 1888:
1103 submodel = SUBMDL_ES1888;
1104 break;
1105 default:
1106 printk (KERN_ERR "Invalid esstype=%d specified\n", devc->sbmo.esstype);
1107 return 0;
1108 }
1109 if (submodel != -1) {
1110 devc->submodel = submodel;
1111 sprintf (modelname, "ES%d", devc->sbmo.esstype);
1112 chip = modelname;
1113 }
1114 if (chip == NULL && (ess_minor & 0x0f) < 8) {
1115 chip = "ES688";
1116 }
1117#ifdef FKS_TEST
1118FKS_test (devc);
1119#endif
1120
1121
1122
1123
1124 if (chip == NULL && devc->sbmo.esstype == ESSTYPE_LIKE20) {
1125 chip = "ES1688";
1126 }
1127
1128 if (chip == NULL) {
1129 int type;
1130
1131 type = ess_identify (devc);
1132
1133 switch (type) {
1134 case 0x1868:
1135 chip = "ES1868";
1136 devc->submodel = SUBMDL_ES1868;
1137 break;
1138 case 0x1869:
1139 chip = "ES1869";
1140 devc->submodel = SUBMDL_ES1869;
1141 break;
1142 case 0x1878:
1143 chip = "ES1878";
1144 devc->submodel = SUBMDL_ES1878;
1145 break;
1146 case 0x1879:
1147 chip = "ES1879";
1148 devc->submodel = SUBMDL_ES1879;
1149 break;
1150 default:
1151 if ((type & 0x00ff) != ((type >> 8) & 0x00ff)) {
1152 printk ("ess_init: Unrecognized %04x\n", type);
1153 }
1154 }
1155 }
1156#if 0
1157
1158
1159
1160
1161
1162
1163
1164
1165 if (chip == NULL && !ess_probe(devc, 0x64, (1 << 4))) {
1166#endif
1167
1168
1169
1170
1171
1172
1173 if (chip == NULL && ess_probe(devc, 0x64, (1 << 2))) {
1174 if (ess_probe (devc, 0x70, 0x7f)) {
1175 if (ess_probe (devc, 0x64, (1 << 5))) {
1176 chip = "ES1887";
1177 devc->submodel = SUBMDL_ES1887;
1178 } else {
1179 chip = "ES1888";
1180 devc->submodel = SUBMDL_ES1888;
1181 }
1182 } else {
1183 chip = "ES1788";
1184 devc->submodel = SUBMDL_ES1788;
1185 }
1186 }
1187 if (chip == NULL) {
1188 chip = "ES1688";
1189 }
1190
1191 printk ( KERN_INFO "ESS chip %s %s%s\n"
1192 , chip
1193 , ( devc->sbmo.esstype == ESSTYPE_DETECT || devc->sbmo.esstype == ESSTYPE_LIKE20
1194 ? "detected"
1195 : "specified"
1196 )
1197 , ( devc->sbmo.esstype == ESSTYPE_LIKE20
1198 ? " (kernel 2.0 compatible)"
1199 : ""
1200 )
1201 );
1202
1203 sprintf(name,"ESS %s AudioDrive (rev %d)", chip, ess_minor & 0x0f);
1204 } else {
1205 strcpy(name, "Jazz16");
1206 }
1207
1208
1209 switch(devc->submodel) {
1210
1211
1212
1213
1214 case SUBMDL_ES1888:
1215 devc->caps |= SB_CAP_ES18XX_RATE;
1216 break;
1217 }
1218
1219 hw_config->name = name;
1220
1221 sb_dsp_reset(devc);
1222
1223
1224
1225
1226 cfg = ess_getmixer (devc, 0x40);
1227 ess_setmixer (devc, 0x40, cfg | 0x03);
1228 if (devc->submodel >= 8) {
1229 devc->caps |= SB_NO_MIDI;
1230 }
1231 sb_dsp_reset (devc);
1232
1233
1234
1235
1236
1237 return ess_set_irq_hw (devc);
1238}
1239
1240static int ess_set_dma_hw(sb_devc * devc)
1241{
1242 unsigned char cfg, dma_bits = 0, dma16_bits;
1243 int dma;
1244
1245#ifdef FKS_LOGGING
1246printk(KERN_INFO "ess_set_dma_hw: dma8=%d,dma16=%d,dup=%d\n"
1247, devc->dma8, devc->dma16, devc->duplex);
1248#endif
1249
1250
1251
1252
1253 dma = devc->dma8;
1254
1255 if (dma > 3 || dma < 0 || dma == 2) {
1256 dma_bits = 0;
1257 printk(KERN_ERR "ESS1688: Invalid DMA8 %d\n", dma);
1258 return 0;
1259 } else {
1260
1261 cfg = 0x50;
1262
1263 if (dma == 3) {
1264 dma_bits = 3;
1265 } else {
1266 dma_bits = dma + 1;
1267 }
1268 }
1269
1270 if (!ess_write (devc, 0xb2, cfg | (dma_bits << 2))) {
1271 printk(KERN_ERR "ESS1688: Failed to write to DMA config register\n");
1272 return 0;
1273 }
1274
1275 if (devc->duplex) {
1276 dma = devc->dma16;
1277 dma16_bits = 0;
1278
1279 if (dma >= 0) {
1280 switch (dma) {
1281 case 0:
1282 dma_bits = 0x04;
1283 break;
1284 case 1:
1285 dma_bits = 0x05;
1286 break;
1287 case 3:
1288 dma_bits = 0x06;
1289 break;
1290 case 5:
1291 dma_bits = 0x07;
1292 dma16_bits = 0x20;
1293 break;
1294 default:
1295 printk(KERN_ERR "ESS1887: Invalid DMA16 %d\n", dma);
1296 return 0;
1297 }
1298 ess_chgmixer (devc, 0x78, 0x20, dma16_bits);
1299 ess_chgmixer (devc, 0x7d, 0x07, dma_bits);
1300 }
1301 }
1302 return 1;
1303}
1304
1305
1306
1307
1308
1309
1310
1311
1312int ess_dsp_init (sb_devc *devc, struct address_info *hw_config)
1313{
1314
1315
1316
1317 if (devc->model != MDL_ESS) {
1318 printk (KERN_INFO "ess_dsp_init for non ESS chip\n");
1319 return 1;
1320 }
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330 if (devc->submodel == SUBMDL_ES1887) {
1331 if (hw_config->dma2 != -1) {
1332 devc->dma16 = hw_config->dma2;
1333 }
1334
1335
1336
1337
1338 if (devc->dma8 != devc->dma16 && devc->dma16 != -1) {
1339 devc->duplex = 1;
1340 }
1341 }
1342 if (!ess_set_dma_hw (devc)) {
1343 free_irq(devc->irq, devc);
1344 return 0;
1345 }
1346 return 1;
1347}
1348
1349
1350
1351
1352
1353
1354
1355#define ES688_RECORDING_DEVICES \
1356 ( SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD )
1357#define ES688_MIXER_DEVICES \
1358 ( SOUND_MASK_SYNTH | SOUND_MASK_PCM | SOUND_MASK_LINE \
1359 | SOUND_MASK_MIC | SOUND_MASK_CD | SOUND_MASK_VOLUME \
1360 | SOUND_MASK_LINE2 | SOUND_MASK_SPEAKER )
1361
1362#define ES1688_RECORDING_DEVICES \
1363 ( ES688_RECORDING_DEVICES )
1364#define ES1688_MIXER_DEVICES \
1365 ( ES688_MIXER_DEVICES | SOUND_MASK_RECLEV )
1366
1367#define ES1887_RECORDING_DEVICES \
1368 ( ES1688_RECORDING_DEVICES | SOUND_MASK_LINE2 | SOUND_MASK_SYNTH)
1369#define ES1887_MIXER_DEVICES \
1370 ( ES1688_MIXER_DEVICES )
1371
1372
1373
1374
1375
1376
1377
1378
1379#define ES_REC_MIXER_RECBASE (SOUND_MIXER_LINE3 + 1)
1380#define ES_REC_MIXER_RECDIFF (ES_REC_MIXER_RECBASE - SOUND_MIXER_SYNTH)
1381
1382#define ES_REC_MIXER_RECSYNTH (SOUND_MIXER_SYNTH + ES_REC_MIXER_RECDIFF)
1383#define ES_REC_MIXER_RECPCM (SOUND_MIXER_PCM + ES_REC_MIXER_RECDIFF)
1384#define ES_REC_MIXER_RECSPEAKER (SOUND_MIXER_SPEAKER + ES_REC_MIXER_RECDIFF)
1385#define ES_REC_MIXER_RECLINE (SOUND_MIXER_LINE + ES_REC_MIXER_RECDIFF)
1386#define ES_REC_MIXER_RECMIC (SOUND_MIXER_MIC + ES_REC_MIXER_RECDIFF)
1387#define ES_REC_MIXER_RECCD (SOUND_MIXER_CD + ES_REC_MIXER_RECDIFF)
1388#define ES_REC_MIXER_RECIMIX (SOUND_MIXER_IMIX + ES_REC_MIXER_RECDIFF)
1389#define ES_REC_MIXER_RECALTPCM (SOUND_MIXER_ALTPCM + ES_REC_MIXER_RECDIFF)
1390#define ES_REC_MIXER_RECRECLEV (SOUND_MIXER_RECLEV + ES_REC_MIXER_RECDIFF)
1391#define ES_REC_MIXER_RECIGAIN (SOUND_MIXER_IGAIN + ES_REC_MIXER_RECDIFF)
1392#define ES_REC_MIXER_RECOGAIN (SOUND_MIXER_OGAIN + ES_REC_MIXER_RECDIFF)
1393#define ES_REC_MIXER_RECLINE1 (SOUND_MIXER_LINE1 + ES_REC_MIXER_RECDIFF)
1394#define ES_REC_MIXER_RECLINE2 (SOUND_MIXER_LINE2 + ES_REC_MIXER_RECDIFF)
1395#define ES_REC_MIXER_RECLINE3 (SOUND_MIXER_LINE3 + ES_REC_MIXER_RECDIFF)
1396
1397static mixer_tab es688_mix = {
1398MIX_ENT(SOUND_MIXER_VOLUME, 0x32, 7, 4, 0x32, 3, 4),
1399MIX_ENT(SOUND_MIXER_BASS, 0x00, 0, 0, 0x00, 0, 0),
1400MIX_ENT(SOUND_MIXER_TREBLE, 0x00, 0, 0, 0x00, 0, 0),
1401MIX_ENT(SOUND_MIXER_SYNTH, 0x36, 7, 4, 0x36, 3, 4),
1402MIX_ENT(SOUND_MIXER_PCM, 0x14, 7, 4, 0x14, 3, 4),
1403MIX_ENT(SOUND_MIXER_SPEAKER, 0x3c, 2, 3, 0x00, 0, 0),
1404MIX_ENT(SOUND_MIXER_LINE, 0x3e, 7, 4, 0x3e, 3, 4),
1405MIX_ENT(SOUND_MIXER_MIC, 0x1a, 7, 4, 0x1a, 3, 4),
1406MIX_ENT(SOUND_MIXER_CD, 0x38, 7, 4, 0x38, 3, 4),
1407MIX_ENT(SOUND_MIXER_IMIX, 0x00, 0, 0, 0x00, 0, 0),
1408MIX_ENT(SOUND_MIXER_ALTPCM, 0x00, 0, 0, 0x00, 0, 0),
1409MIX_ENT(SOUND_MIXER_RECLEV, 0x00, 0, 0, 0x00, 0, 0),
1410MIX_ENT(SOUND_MIXER_IGAIN, 0x00, 0, 0, 0x00, 0, 0),
1411MIX_ENT(SOUND_MIXER_OGAIN, 0x00, 0, 0, 0x00, 0, 0),
1412MIX_ENT(SOUND_MIXER_LINE1, 0x00, 0, 0, 0x00, 0, 0),
1413MIX_ENT(SOUND_MIXER_LINE2, 0x3a, 7, 4, 0x3a, 3, 4),
1414MIX_ENT(SOUND_MIXER_LINE3, 0x00, 0, 0, 0x00, 0, 0)
1415};
1416
1417
1418
1419
1420
1421
1422
1423
1424static mixer_tab es1688_mix = {
1425MIX_ENT(SOUND_MIXER_VOLUME, 0x32, 7, 4, 0x32, 3, 4),
1426MIX_ENT(SOUND_MIXER_BASS, 0x00, 0, 0, 0x00, 0, 0),
1427MIX_ENT(SOUND_MIXER_TREBLE, 0x00, 0, 0, 0x00, 0, 0),
1428MIX_ENT(SOUND_MIXER_SYNTH, 0x36, 7, 4, 0x36, 3, 4),
1429MIX_ENT(SOUND_MIXER_PCM, 0x14, 7, 4, 0x14, 3, 4),
1430MIX_ENT(SOUND_MIXER_SPEAKER, 0x3c, 2, 3, 0x00, 0, 0),
1431MIX_ENT(SOUND_MIXER_LINE, 0x3e, 7, 4, 0x3e, 3, 4),
1432MIX_ENT(SOUND_MIXER_MIC, 0x1a, 7, 4, 0x1a, 3, 4),
1433MIX_ENT(SOUND_MIXER_CD, 0x38, 7, 4, 0x38, 3, 4),
1434MIX_ENT(SOUND_MIXER_IMIX, 0x00, 0, 0, 0x00, 0, 0),
1435MIX_ENT(SOUND_MIXER_ALTPCM, 0x00, 0, 0, 0x00, 0, 0),
1436MIX_ENT(SOUND_MIXER_RECLEV, 0xb4, 7, 4, 0xb4, 3, 4),
1437MIX_ENT(SOUND_MIXER_IGAIN, 0x00, 0, 0, 0x00, 0, 0),
1438MIX_ENT(SOUND_MIXER_OGAIN, 0x00, 0, 0, 0x00, 0, 0),
1439MIX_ENT(SOUND_MIXER_LINE1, 0x00, 0, 0, 0x00, 0, 0),
1440MIX_ENT(SOUND_MIXER_LINE2, 0x3a, 7, 4, 0x3a, 3, 4),
1441MIX_ENT(SOUND_MIXER_LINE3, 0x00, 0, 0, 0x00, 0, 0)
1442};
1443
1444static mixer_tab es1688later_mix = {
1445MIX_ENT(SOUND_MIXER_VOLUME, 0x60, 5, 6, 0x62, 5, 6),
1446MIX_ENT(SOUND_MIXER_BASS, 0x00, 0, 0, 0x00, 0, 0),
1447MIX_ENT(SOUND_MIXER_TREBLE, 0x00, 0, 0, 0x00, 0, 0),
1448MIX_ENT(SOUND_MIXER_SYNTH, 0x36, 7, 4, 0x36, 3, 4),
1449MIX_ENT(SOUND_MIXER_PCM, 0x14, 7, 4, 0x14, 3, 4),
1450MIX_ENT(SOUND_MIXER_SPEAKER, 0x3c, 2, 3, 0x00, 0, 0),
1451MIX_ENT(SOUND_MIXER_LINE, 0x3e, 7, 4, 0x3e, 3, 4),
1452MIX_ENT(SOUND_MIXER_MIC, 0x1a, 7, 4, 0x1a, 3, 4),
1453MIX_ENT(SOUND_MIXER_CD, 0x38, 7, 4, 0x38, 3, 4),
1454MIX_ENT(SOUND_MIXER_IMIX, 0x00, 0, 0, 0x00, 0, 0),
1455MIX_ENT(SOUND_MIXER_ALTPCM, 0x00, 0, 0, 0x00, 0, 0),
1456MIX_ENT(SOUND_MIXER_RECLEV, 0xb4, 7, 4, 0xb4, 3, 4),
1457MIX_ENT(SOUND_MIXER_IGAIN, 0x00, 0, 0, 0x00, 0, 0),
1458MIX_ENT(SOUND_MIXER_OGAIN, 0x00, 0, 0, 0x00, 0, 0),
1459MIX_ENT(SOUND_MIXER_LINE1, 0x00, 0, 0, 0x00, 0, 0),
1460MIX_ENT(SOUND_MIXER_LINE2, 0x3a, 7, 4, 0x3a, 3, 4),
1461MIX_ENT(SOUND_MIXER_LINE3, 0x00, 0, 0, 0x00, 0, 0)
1462};
1463
1464
1465
1466
1467
1468static mixer_tab es_rec_mix = {
1469MIX_ENT(SOUND_MIXER_VOLUME, 0x60, 5, 6, 0x62, 5, 6),
1470MIX_ENT(SOUND_MIXER_BASS, 0x00, 0, 0, 0x00, 0, 0),
1471MIX_ENT(SOUND_MIXER_TREBLE, 0x00, 0, 0, 0x00, 0, 0),
1472MIX_ENT(SOUND_MIXER_SYNTH, 0x36, 7, 4, 0x36, 3, 4),
1473MIX_ENT(SOUND_MIXER_PCM, 0x14, 7, 4, 0x14, 3, 4),
1474MIX_ENT(SOUND_MIXER_SPEAKER, 0x3c, 2, 3, 0x00, 0, 0),
1475MIX_ENT(SOUND_MIXER_LINE, 0x3e, 7, 4, 0x3e, 3, 4),
1476MIX_ENT(SOUND_MIXER_MIC, 0x1a, 7, 4, 0x1a, 3, 4),
1477MIX_ENT(SOUND_MIXER_CD, 0x38, 7, 4, 0x38, 3, 4),
1478MIX_ENT(SOUND_MIXER_IMIX, 0x00, 0, 0, 0x00, 0, 0),
1479MIX_ENT(SOUND_MIXER_ALTPCM, 0x00, 0, 0, 0x00, 0, 0),
1480MIX_ENT(SOUND_MIXER_RECLEV, 0xb4, 7, 4, 0xb4, 3, 4),
1481MIX_ENT(SOUND_MIXER_IGAIN, 0x00, 0, 0, 0x00, 0, 0),
1482MIX_ENT(SOUND_MIXER_OGAIN, 0x00, 0, 0, 0x00, 0, 0),
1483MIX_ENT(SOUND_MIXER_LINE1, 0x00, 0, 0, 0x00, 0, 0),
1484MIX_ENT(SOUND_MIXER_LINE2, 0x3a, 7, 4, 0x3a, 3, 4),
1485MIX_ENT(SOUND_MIXER_LINE3, 0x00, 0, 0, 0x00, 0, 0),
1486MIX_ENT(ES_REC_MIXER_RECSYNTH, 0x6b, 7, 4, 0x6b, 3, 4),
1487MIX_ENT(ES_REC_MIXER_RECPCM, 0x00, 0, 0, 0x00, 0, 0),
1488MIX_ENT(ES_REC_MIXER_RECSPEAKER, 0x00, 0, 0, 0x00, 0, 0),
1489MIX_ENT(ES_REC_MIXER_RECLINE, 0x6e, 7, 4, 0x6e, 3, 4),
1490MIX_ENT(ES_REC_MIXER_RECMIC, 0x68, 7, 4, 0x68, 3, 4),
1491MIX_ENT(ES_REC_MIXER_RECCD, 0x6a, 7, 4, 0x6a, 3, 4),
1492MIX_ENT(ES_REC_MIXER_RECIMIX, 0x00, 0, 0, 0x00, 0, 0),
1493MIX_ENT(ES_REC_MIXER_RECALTPCM, 0x00, 0, 0, 0x00, 0, 0),
1494MIX_ENT(ES_REC_MIXER_RECRECLEV, 0x00, 0, 0, 0x00, 0, 0),
1495MIX_ENT(ES_REC_MIXER_RECIGAIN, 0x00, 0, 0, 0x00, 0, 0),
1496MIX_ENT(ES_REC_MIXER_RECOGAIN, 0x00, 0, 0, 0x00, 0, 0),
1497MIX_ENT(ES_REC_MIXER_RECLINE1, 0x00, 0, 0, 0x00, 0, 0),
1498MIX_ENT(ES_REC_MIXER_RECLINE2, 0x6c, 7, 4, 0x6c, 3, 4),
1499MIX_ENT(ES_REC_MIXER_RECLINE3, 0x00, 0, 0, 0x00, 0, 0)
1500};
1501
1502
1503
1504
1505
1506
1507static mixer_tab es1887_mix = {
1508MIX_ENT(SOUND_MIXER_VOLUME, 0x60, 5, 6, 0x62, 5, 6),
1509MIX_ENT(SOUND_MIXER_BASS, 0x00, 0, 0, 0x00, 0, 0),
1510MIX_ENT(SOUND_MIXER_TREBLE, 0x00, 0, 0, 0x00, 0, 0),
1511MIX_ENT(SOUND_MIXER_SYNTH, 0x36, 7, 4, 0x36, 3, 4),
1512MIX_ENT(SOUND_MIXER_PCM, 0x7c, 7, 4, 0x7c, 3, 4),
1513MIX_ENT(SOUND_MIXER_SPEAKER, 0x3c, 2, 3, 0x00, 0, 0),
1514MIX_ENT(SOUND_MIXER_LINE, 0x3e, 7, 4, 0x3e, 3, 4),
1515MIX_ENT(SOUND_MIXER_MIC, 0x1a, 7, 4, 0x1a, 3, 4),
1516MIX_ENT(SOUND_MIXER_CD, 0x38, 7, 4, 0x38, 3, 4),
1517MIX_ENT(SOUND_MIXER_IMIX, 0x00, 0, 0, 0x00, 0, 0),
1518MIX_ENT(SOUND_MIXER_ALTPCM, 0x00, 0, 0, 0x00, 0, 0),
1519MIX_ENT(SOUND_MIXER_RECLEV, 0xb4, 7, 4, 0xb4, 3, 4),
1520MIX_ENT(SOUND_MIXER_IGAIN, 0x00, 0, 0, 0x00, 0, 0),
1521MIX_ENT(SOUND_MIXER_OGAIN, 0x00, 0, 0, 0x00, 0, 0),
1522MIX_ENT(SOUND_MIXER_LINE1, 0x00, 0, 0, 0x00, 0, 0),
1523MIX_ENT(SOUND_MIXER_LINE2, 0x3a, 7, 4, 0x3a, 3, 4),
1524MIX_ENT(SOUND_MIXER_LINE3, 0x00, 0, 0, 0x00, 0, 0),
1525MIX_ENT(ES_REC_MIXER_RECSYNTH, 0x6b, 7, 4, 0x6b, 3, 4),
1526MIX_ENT(ES_REC_MIXER_RECPCM, 0x00, 0, 0, 0x00, 0, 0),
1527MIX_ENT(ES_REC_MIXER_RECSPEAKER, 0x00, 0, 0, 0x00, 0, 0),
1528MIX_ENT(ES_REC_MIXER_RECLINE, 0x6e, 7, 4, 0x6e, 3, 4),
1529MIX_ENT(ES_REC_MIXER_RECMIC, 0x68, 7, 4, 0x68, 3, 4),
1530MIX_ENT(ES_REC_MIXER_RECCD, 0x6a, 7, 4, 0x6a, 3, 4),
1531MIX_ENT(ES_REC_MIXER_RECIMIX, 0x00, 0, 0, 0x00, 0, 0),
1532MIX_ENT(ES_REC_MIXER_RECALTPCM, 0x00, 0, 0, 0x00, 0, 0),
1533MIX_ENT(ES_REC_MIXER_RECRECLEV, 0x00, 0, 0, 0x00, 0, 0),
1534MIX_ENT(ES_REC_MIXER_RECIGAIN, 0x00, 0, 0, 0x00, 0, 0),
1535MIX_ENT(ES_REC_MIXER_RECOGAIN, 0x00, 0, 0, 0x00, 0, 0),
1536MIX_ENT(ES_REC_MIXER_RECLINE1, 0x00, 0, 0, 0x00, 0, 0),
1537MIX_ENT(ES_REC_MIXER_RECLINE2, 0x6c, 7, 4, 0x6c, 3, 4),
1538MIX_ENT(ES_REC_MIXER_RECLINE3, 0x00, 0, 0, 0x00, 0, 0)
1539};
1540
1541static int ess_has_rec_mixer (int submodel)
1542{
1543 switch (submodel) {
1544 case SUBMDL_ES1887:
1545 return 1;
1546 default:
1547 return 0;
1548 };
1549};
1550
1551#ifdef FKS_LOGGING
1552static int ess_mixer_mon_regs[]
1553 = { 0x70, 0x71, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7d, 0x7f
1554 , 0xa1, 0xa2, 0xa4, 0xa5, 0xa8, 0xa9
1555 , 0xb1, 0xb2, 0xb4, 0xb5, 0xb6, 0xb7, 0xb9
1556 , 0x00};
1557
1558static void ess_show_mixerregs (sb_devc *devc)
1559{
1560 int *mp = ess_mixer_mon_regs;
1561
1562return;
1563
1564 while (*mp != 0) {
1565 printk (KERN_INFO "res (%x)=%x\n", *mp, (int)(ess_getmixer (devc, *mp)));
1566 mp++;
1567 }
1568}
1569#endif
1570
1571void ess_setmixer (sb_devc * devc, unsigned int port, unsigned int value)
1572{
1573 unsigned long flags;
1574
1575#ifdef FKS_LOGGING
1576printk(KERN_INFO "FKS: write mixer %x: %x\n", port, value);
1577#endif
1578
1579 spin_lock_irqsave(&devc->lock, flags);
1580 if (port >= 0xa0) {
1581 ess_write (devc, port, value);
1582 } else {
1583 outb(((unsigned char) (port & 0xff)), MIXER_ADDR);
1584
1585 udelay(20);
1586 outb(((unsigned char) (value & 0xff)), MIXER_DATA);
1587 udelay(20);
1588 }
1589 spin_unlock_irqrestore(&devc->lock, flags);
1590}
1591
1592unsigned int ess_getmixer (sb_devc * devc, unsigned int port)
1593{
1594 unsigned int val;
1595 unsigned long flags;
1596
1597 spin_lock_irqsave(&devc->lock, flags);
1598
1599 if (port >= 0xa0) {
1600 val = ess_read (devc, port);
1601 } else {
1602 outb(((unsigned char) (port & 0xff)), MIXER_ADDR);
1603
1604 udelay(20);
1605 val = inb(MIXER_DATA);
1606 udelay(20);
1607 }
1608 spin_unlock_irqrestore(&devc->lock, flags);
1609
1610 return val;
1611}
1612
1613static void ess_chgmixer
1614 (sb_devc * devc, unsigned int reg, unsigned int mask, unsigned int val)
1615{
1616 int value;
1617
1618 value = ess_getmixer (devc, reg);
1619 value = (value & ~mask) | (val & mask);
1620 ess_setmixer (devc, reg, value);
1621}
1622
1623
1624
1625
1626void ess_mixer_init (sb_devc * devc)
1627{
1628 devc->mixer_caps = SOUND_CAP_EXCL_INPUT;
1629
1630
1631
1632
1633 switch (devc->submodel) {
1634 case SUBMDL_ES1887:
1635 devc->supported_devices = ES1887_MIXER_DEVICES;
1636 devc->supported_rec_devices = ES1887_RECORDING_DEVICES;
1637#ifdef FKS_LOGGING
1638printk (KERN_INFO "FKS: ess_mixer_init dup = %d\n", devc->duplex);
1639#endif
1640 if (devc->duplex) {
1641 devc->iomap = &es1887_mix;
1642 devc->iomap_sz = ARRAY_SIZE(es1887_mix);
1643 } else {
1644 devc->iomap = &es_rec_mix;
1645 devc->iomap_sz = ARRAY_SIZE(es_rec_mix);
1646 }
1647 break;
1648 default:
1649 if (devc->submodel < 8) {
1650 devc->supported_devices = ES688_MIXER_DEVICES;
1651 devc->supported_rec_devices = ES688_RECORDING_DEVICES;
1652 devc->iomap = &es688_mix;
1653 devc->iomap_sz = ARRAY_SIZE(es688_mix);
1654 } else {
1655
1656
1657
1658
1659 devc->supported_devices = ES1688_MIXER_DEVICES;
1660 devc->supported_rec_devices = ES1688_RECORDING_DEVICES;
1661 if (devc->submodel < 0x10) {
1662 devc->iomap = &es1688_mix;
1663 devc->iomap_sz = ARRAY_SIZE(es688_mix);
1664 } else {
1665 devc->iomap = &es1688later_mix;
1666 devc->iomap_sz = ARRAY_SIZE(es1688later_mix);
1667 }
1668 }
1669 }
1670}
1671
1672
1673
1674
1675
1676int ess_mixer_set(sb_devc *devc, int dev, int left, int right)
1677{
1678 if (ess_has_rec_mixer (devc->submodel) && (devc->recmask & (1 << dev))) {
1679 sb_common_mixer_set (devc, dev + ES_REC_MIXER_RECDIFF, left, right);
1680 }
1681 return sb_common_mixer_set (devc, dev, left, right);
1682}
1683
1684
1685
1686
1687
1688
1689void ess_mixer_reload (sb_devc *devc, int dev)
1690{
1691 int left, right, value;
1692
1693 value = devc->levels[dev];
1694 left = value & 0x000000ff;
1695 right = (value & 0x0000ff00) >> 8;
1696
1697 sb_common_mixer_set(devc, dev, left, right);
1698}
1699
1700static int es_rec_set_recmask(sb_devc * devc, int mask)
1701{
1702 int i, i_mask, cur_mask, diff_mask;
1703 int value, left, right;
1704
1705#ifdef FKS_LOGGING
1706printk (KERN_INFO "FKS: es_rec_set_recmask mask = %x\n", mask);
1707#endif
1708
1709
1710
1711
1712
1713
1714 cur_mask = devc->recmask;
1715 diff_mask = (cur_mask ^ mask);
1716
1717 for (i = 0; i < 32; i++) {
1718 i_mask = (1 << i);
1719 if (diff_mask & i_mask) {
1720 if (mask & i_mask) {
1721 value = devc->levels[i];
1722 left = value & 0x000000ff;
1723 right = (value & 0x0000ff00) >> 8;
1724 } else {
1725 left = 0;
1726 right = 0;
1727 }
1728 sb_common_mixer_set(devc, i + ES_REC_MIXER_RECDIFF, left, right);
1729 }
1730 }
1731 return mask;
1732}
1733
1734int ess_set_recmask(sb_devc * devc, int *mask)
1735{
1736
1737
1738 if (ess_has_rec_mixer (devc->submodel)) {
1739 *mask = es_rec_set_recmask (devc, *mask);
1740 return 1;
1741 } else {
1742 return 0;
1743 }
1744}
1745
1746
1747
1748
1749int ess_mixer_reset (sb_devc * devc)
1750{
1751
1752
1753
1754 if (ess_has_rec_mixer (devc->submodel)) {
1755 switch (devc->submodel) {
1756 case SUBMDL_ES1887:
1757
1758
1759
1760
1761
1762 ess_chgmixer(devc, 0x7a, 0x18, 0x08);
1763 ess_chgmixer(devc, 0x1c, 0x07, 0x07);
1764 break;
1765 }
1766
1767
1768
1769 devc->recmask = devc->supported_rec_devices;
1770 es_rec_set_recmask(devc, 0);
1771 devc->recmask = 0;
1772
1773 return 1;
1774 } else {
1775 return 0;
1776 }
1777}
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788int ess_midi_init(sb_devc * devc, struct address_info *hw_config)
1789{
1790 unsigned char cfg, tmp;
1791
1792 cfg = ess_getmixer (devc, 0x40) & 0x03;
1793
1794 if (devc->submodel < 8) {
1795 ess_setmixer (devc, 0x40, cfg | 0x03);
1796 return 0;
1797 }
1798 tmp = (hw_config->io_base & 0x0f0) >> 4;
1799
1800 if (tmp > 3) {
1801 ess_setmixer (devc, 0x40, cfg);
1802 return 0;
1803 }
1804 cfg |= tmp << 3;
1805
1806 tmp = 1;
1807
1808
1809
1810 switch (abs(hw_config->irq)) {
1811 case 9:
1812 tmp = 0x4;
1813 break;
1814 case 5:
1815 tmp = 0x5;
1816 break;
1817 case 7:
1818 tmp = 0x6;
1819 break;
1820 case 10:
1821 tmp = 0x7;
1822 break;
1823 default:
1824 return 0;
1825 }
1826
1827 cfg |= tmp << 5;
1828 ess_setmixer (devc, 0x40, cfg | 0x03);
1829
1830 return 1;
1831}
1832
1833