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 outb(3, DSP_RESET);
870
871 udelay(10);
872 outb(0, DSP_RESET);
873 udelay(30);
874
875 for (loopc = 0; loopc < 1000 && !(inb(DSP_DATA_AVAIL) & 0x80); loopc++);
876
877 if (inb(DSP_READ) != 0xAA) {
878 DDB(printk("sb: No response to RESET\n"));
879 return 0;
880 }
881 ess_extended (devc);
882
883#ifdef FKS_LOGGING
884printk(KERN_INFO "FKS: dsp_reset 2\n");
885ess_show_mixerregs (devc);
886#endif
887
888 return 1;
889}
890
891static int ess_irq_bits (int irq)
892{
893 switch (irq) {
894 case 2:
895 case 9:
896 return 0;
897
898 case 5:
899 return 1;
900
901 case 7:
902 return 2;
903
904 case 10:
905 return 3;
906
907 default:
908 printk(KERN_ERR "ESS1688: Invalid IRQ %d\n", irq);
909 return -1;
910 }
911}
912
913
914
915
916static int ess_common_set_irq_hw (sb_devc * devc)
917{
918 int irq_bits;
919
920 if ((irq_bits = ess_irq_bits (devc->irq)) == -1) return 0;
921
922 if (!ess_write (devc, 0xb1, 0x50 | (irq_bits << 2))) {
923 printk(KERN_ERR "ES1688: Failed to write to IRQ config register\n");
924 return 0;
925 }
926 return 1;
927}
928
929
930
931
932
933
934
935
936static void ess_es1887_set_irq_hw (sb_devc * devc)
937{
938 int irq_bits;
939
940 if ((irq_bits = ess_irq_bits (devc->irq)) == -1) return;
941
942 ess_chgmixer (devc, 0x7f, 0x0f, 0x01 | ((irq_bits + 1) << 1));
943}
944
945static int ess_set_irq_hw (sb_devc * devc)
946{
947 if (devc->submodel == SUBMDL_ES1887) ess_es1887_set_irq_hw (devc);
948
949 return ess_common_set_irq_hw (devc);
950}
951
952#ifdef FKS_TEST
953
954
955
956
957
958
959
960
961
962
963static void FKS_test (sb_devc * devc)
964{
965 int val1, val2;
966 val1 = ess_getmixer (devc, 0x64);
967 ess_setmixer (devc, 0x64, ~val1);
968 val2 = ess_getmixer (devc, 0x64) ^ ~val1;
969 ess_setmixer (devc, 0x64, val1);
970 val1 ^= ess_getmixer (devc, 0x64);
971printk (KERN_INFO "FKS: FKS_test %02x, %02x\n", (val1 & 0x0ff), (val2 & 0x0ff));
972};
973#endif
974
975static unsigned int ess_identify (sb_devc * devc)
976{
977 unsigned int val;
978 unsigned long flags;
979
980 spin_lock_irqsave(&devc->lock, flags);
981 outb(((unsigned char) (0x40 & 0xff)), MIXER_ADDR);
982
983 udelay(20);
984 val = inb(MIXER_DATA) << 8;
985 udelay(20);
986 val |= inb(MIXER_DATA);
987 udelay(20);
988 spin_unlock_irqrestore(&devc->lock, flags);
989
990 return val;
991}
992
993
994
995
996
997
998
999
1000
1001static int ess_probe (sb_devc * devc, int reg, int xorval)
1002{
1003 int val1, val2, val3;
1004
1005 val1 = ess_getmixer (devc, reg);
1006 val2 = val1 ^ xorval;
1007 ess_setmixer (devc, reg, val2);
1008 val3 = ess_getmixer (devc, reg);
1009 ess_setmixer (devc, reg, val1);
1010
1011 return (val2 == val3);
1012}
1013
1014int ess_init(sb_devc * devc, struct address_info *hw_config)
1015{
1016 unsigned char cfg;
1017 int ess_major = 0, ess_minor = 0;
1018 int i;
1019 static char name[100], modelname[10];
1020
1021
1022
1023
1024
1025 sb_dsp_command(devc, 0xe7);
1026
1027 for (i = 1000; i; i--) {
1028 if (inb(DSP_DATA_AVAIL) & 0x80) {
1029 if (ess_major == 0) {
1030 ess_major = inb(DSP_READ);
1031 } else {
1032 ess_minor = inb(DSP_READ);
1033 break;
1034 }
1035 }
1036 }
1037
1038 if (ess_major == 0) return 0;
1039
1040 if (ess_major == 0x48 && (ess_minor & 0xf0) == 0x80) {
1041 sprintf(name, "ESS ES488 AudioDrive (rev %d)",
1042 ess_minor & 0x0f);
1043 hw_config->name = name;
1044 devc->model = MDL_SBPRO;
1045 return 1;
1046 }
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063 devc->model = MDL_ESS;
1064 devc->submodel = ess_minor & 0x0f;
1065
1066 if (ess_major == 0x68 && (ess_minor & 0xf0) == 0x80) {
1067 char *chip = NULL;
1068 int submodel = -1;
1069
1070 switch (devc->sbmo.esstype) {
1071 case ESSTYPE_DETECT:
1072 case ESSTYPE_LIKE20:
1073 break;
1074 case 688:
1075 submodel = 0x00;
1076 break;
1077 case 1688:
1078 submodel = 0x08;
1079 break;
1080 case 1868:
1081 submodel = SUBMDL_ES1868;
1082 break;
1083 case 1869:
1084 submodel = SUBMDL_ES1869;
1085 break;
1086 case 1788:
1087 submodel = SUBMDL_ES1788;
1088 break;
1089 case 1878:
1090 submodel = SUBMDL_ES1878;
1091 break;
1092 case 1879:
1093 submodel = SUBMDL_ES1879;
1094 break;
1095 case 1887:
1096 submodel = SUBMDL_ES1887;
1097 break;
1098 case 1888:
1099 submodel = SUBMDL_ES1888;
1100 break;
1101 default:
1102 printk (KERN_ERR "Invalid esstype=%d specified\n", devc->sbmo.esstype);
1103 return 0;
1104 }
1105 if (submodel != -1) {
1106 devc->submodel = submodel;
1107 sprintf (modelname, "ES%d", devc->sbmo.esstype);
1108 chip = modelname;
1109 }
1110 if (chip == NULL && (ess_minor & 0x0f) < 8) {
1111 chip = "ES688";
1112 }
1113#ifdef FKS_TEST
1114FKS_test (devc);
1115#endif
1116
1117
1118
1119
1120 if (chip == NULL && devc->sbmo.esstype == ESSTYPE_LIKE20) {
1121 chip = "ES1688";
1122 }
1123
1124 if (chip == NULL) {
1125 int type;
1126
1127 type = ess_identify (devc);
1128
1129 switch (type) {
1130 case 0x1868:
1131 chip = "ES1868";
1132 devc->submodel = SUBMDL_ES1868;
1133 break;
1134 case 0x1869:
1135 chip = "ES1869";
1136 devc->submodel = SUBMDL_ES1869;
1137 break;
1138 case 0x1878:
1139 chip = "ES1878";
1140 devc->submodel = SUBMDL_ES1878;
1141 break;
1142 case 0x1879:
1143 chip = "ES1879";
1144 devc->submodel = SUBMDL_ES1879;
1145 break;
1146 default:
1147 if ((type & 0x00ff) != ((type >> 8) & 0x00ff)) {
1148 printk ("ess_init: Unrecognized %04x\n", type);
1149 }
1150 }
1151 }
1152#if 0
1153
1154
1155
1156
1157
1158
1159
1160
1161 if (chip == NULL && !ess_probe(devc, 0x64, (1 << 4))) {
1162#endif
1163
1164
1165
1166
1167
1168
1169 if (chip == NULL && ess_probe(devc, 0x64, (1 << 2))) {
1170 if (ess_probe (devc, 0x70, 0x7f)) {
1171 if (ess_probe (devc, 0x64, (1 << 5))) {
1172 chip = "ES1887";
1173 devc->submodel = SUBMDL_ES1887;
1174 } else {
1175 chip = "ES1888";
1176 devc->submodel = SUBMDL_ES1888;
1177 }
1178 } else {
1179 chip = "ES1788";
1180 devc->submodel = SUBMDL_ES1788;
1181 }
1182 }
1183 if (chip == NULL) {
1184 chip = "ES1688";
1185 }
1186
1187 printk(KERN_INFO "ESS chip %s %s%s\n", chip,
1188 (devc->sbmo.esstype == ESSTYPE_DETECT ||
1189 devc->sbmo.esstype == ESSTYPE_LIKE20) ?
1190 "detected" : "specified",
1191 devc->sbmo.esstype == ESSTYPE_LIKE20 ?
1192 " (kernel 2.0 compatible)" : "");
1193
1194 sprintf(name,"ESS %s AudioDrive (rev %d)", chip, ess_minor & 0x0f);
1195 } else {
1196 strcpy(name, "Jazz16");
1197 }
1198
1199
1200 switch(devc->submodel) {
1201
1202
1203
1204
1205 case SUBMDL_ES1888:
1206 devc->caps |= SB_CAP_ES18XX_RATE;
1207 break;
1208 }
1209
1210 hw_config->name = name;
1211
1212 sb_dsp_reset(devc);
1213
1214
1215
1216
1217 cfg = ess_getmixer (devc, 0x40);
1218 ess_setmixer (devc, 0x40, cfg | 0x03);
1219 if (devc->submodel >= 8) {
1220 devc->caps |= SB_NO_MIDI;
1221 }
1222 sb_dsp_reset (devc);
1223
1224
1225
1226
1227
1228 return ess_set_irq_hw (devc);
1229}
1230
1231static int ess_set_dma_hw(sb_devc * devc)
1232{
1233 unsigned char cfg, dma_bits = 0, dma16_bits;
1234 int dma;
1235
1236#ifdef FKS_LOGGING
1237printk(KERN_INFO "ess_set_dma_hw: dma8=%d,dma16=%d,dup=%d\n"
1238, devc->dma8, devc->dma16, devc->duplex);
1239#endif
1240
1241
1242
1243
1244 dma = devc->dma8;
1245
1246 if (dma > 3 || dma < 0 || dma == 2) {
1247 dma_bits = 0;
1248 printk(KERN_ERR "ESS1688: Invalid DMA8 %d\n", dma);
1249 return 0;
1250 } else {
1251
1252 cfg = 0x50;
1253
1254 if (dma == 3) {
1255 dma_bits = 3;
1256 } else {
1257 dma_bits = dma + 1;
1258 }
1259 }
1260
1261 if (!ess_write (devc, 0xb2, cfg | (dma_bits << 2))) {
1262 printk(KERN_ERR "ESS1688: Failed to write to DMA config register\n");
1263 return 0;
1264 }
1265
1266 if (devc->duplex) {
1267 dma = devc->dma16;
1268 dma16_bits = 0;
1269
1270 if (dma >= 0) {
1271 switch (dma) {
1272 case 0:
1273 dma_bits = 0x04;
1274 break;
1275 case 1:
1276 dma_bits = 0x05;
1277 break;
1278 case 3:
1279 dma_bits = 0x06;
1280 break;
1281 case 5:
1282 dma_bits = 0x07;
1283 dma16_bits = 0x20;
1284 break;
1285 default:
1286 printk(KERN_ERR "ESS1887: Invalid DMA16 %d\n", dma);
1287 return 0;
1288 }
1289 ess_chgmixer (devc, 0x78, 0x20, dma16_bits);
1290 ess_chgmixer (devc, 0x7d, 0x07, dma_bits);
1291 }
1292 }
1293 return 1;
1294}
1295
1296
1297
1298
1299
1300
1301
1302
1303int ess_dsp_init (sb_devc *devc, struct address_info *hw_config)
1304{
1305
1306
1307
1308 if (devc->model != MDL_ESS) {
1309 printk (KERN_INFO "ess_dsp_init for non ESS chip\n");
1310 return 1;
1311 }
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321 if (devc->submodel == SUBMDL_ES1887) {
1322 if (hw_config->dma2 != -1) {
1323 devc->dma16 = hw_config->dma2;
1324 }
1325
1326
1327
1328
1329 if (devc->dma8 != devc->dma16 && devc->dma16 != -1) {
1330 devc->duplex = 1;
1331 }
1332 }
1333 if (!ess_set_dma_hw (devc)) {
1334 free_irq(devc->irq, devc);
1335 return 0;
1336 }
1337 return 1;
1338}
1339
1340
1341
1342
1343
1344
1345
1346#define ES688_RECORDING_DEVICES \
1347 ( SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD )
1348#define ES688_MIXER_DEVICES \
1349 ( SOUND_MASK_SYNTH | SOUND_MASK_PCM | SOUND_MASK_LINE \
1350 | SOUND_MASK_MIC | SOUND_MASK_CD | SOUND_MASK_VOLUME \
1351 | SOUND_MASK_LINE2 | SOUND_MASK_SPEAKER )
1352
1353#define ES1688_RECORDING_DEVICES \
1354 ( ES688_RECORDING_DEVICES )
1355#define ES1688_MIXER_DEVICES \
1356 ( ES688_MIXER_DEVICES | SOUND_MASK_RECLEV )
1357
1358#define ES1887_RECORDING_DEVICES \
1359 ( ES1688_RECORDING_DEVICES | SOUND_MASK_LINE2 | SOUND_MASK_SYNTH)
1360#define ES1887_MIXER_DEVICES \
1361 ( ES1688_MIXER_DEVICES )
1362
1363
1364
1365
1366
1367
1368
1369
1370#define ES_REC_MIXER_RECBASE (SOUND_MIXER_LINE3 + 1)
1371#define ES_REC_MIXER_RECDIFF (ES_REC_MIXER_RECBASE - SOUND_MIXER_SYNTH)
1372
1373#define ES_REC_MIXER_RECSYNTH (SOUND_MIXER_SYNTH + ES_REC_MIXER_RECDIFF)
1374#define ES_REC_MIXER_RECPCM (SOUND_MIXER_PCM + ES_REC_MIXER_RECDIFF)
1375#define ES_REC_MIXER_RECSPEAKER (SOUND_MIXER_SPEAKER + ES_REC_MIXER_RECDIFF)
1376#define ES_REC_MIXER_RECLINE (SOUND_MIXER_LINE + ES_REC_MIXER_RECDIFF)
1377#define ES_REC_MIXER_RECMIC (SOUND_MIXER_MIC + ES_REC_MIXER_RECDIFF)
1378#define ES_REC_MIXER_RECCD (SOUND_MIXER_CD + ES_REC_MIXER_RECDIFF)
1379#define ES_REC_MIXER_RECIMIX (SOUND_MIXER_IMIX + ES_REC_MIXER_RECDIFF)
1380#define ES_REC_MIXER_RECALTPCM (SOUND_MIXER_ALTPCM + ES_REC_MIXER_RECDIFF)
1381#define ES_REC_MIXER_RECRECLEV (SOUND_MIXER_RECLEV + ES_REC_MIXER_RECDIFF)
1382#define ES_REC_MIXER_RECIGAIN (SOUND_MIXER_IGAIN + ES_REC_MIXER_RECDIFF)
1383#define ES_REC_MIXER_RECOGAIN (SOUND_MIXER_OGAIN + ES_REC_MIXER_RECDIFF)
1384#define ES_REC_MIXER_RECLINE1 (SOUND_MIXER_LINE1 + ES_REC_MIXER_RECDIFF)
1385#define ES_REC_MIXER_RECLINE2 (SOUND_MIXER_LINE2 + ES_REC_MIXER_RECDIFF)
1386#define ES_REC_MIXER_RECLINE3 (SOUND_MIXER_LINE3 + ES_REC_MIXER_RECDIFF)
1387
1388static mixer_tab es688_mix = {
1389MIX_ENT(SOUND_MIXER_VOLUME, 0x32, 7, 4, 0x32, 3, 4),
1390MIX_ENT(SOUND_MIXER_BASS, 0x00, 0, 0, 0x00, 0, 0),
1391MIX_ENT(SOUND_MIXER_TREBLE, 0x00, 0, 0, 0x00, 0, 0),
1392MIX_ENT(SOUND_MIXER_SYNTH, 0x36, 7, 4, 0x36, 3, 4),
1393MIX_ENT(SOUND_MIXER_PCM, 0x14, 7, 4, 0x14, 3, 4),
1394MIX_ENT(SOUND_MIXER_SPEAKER, 0x3c, 2, 3, 0x00, 0, 0),
1395MIX_ENT(SOUND_MIXER_LINE, 0x3e, 7, 4, 0x3e, 3, 4),
1396MIX_ENT(SOUND_MIXER_MIC, 0x1a, 7, 4, 0x1a, 3, 4),
1397MIX_ENT(SOUND_MIXER_CD, 0x38, 7, 4, 0x38, 3, 4),
1398MIX_ENT(SOUND_MIXER_IMIX, 0x00, 0, 0, 0x00, 0, 0),
1399MIX_ENT(SOUND_MIXER_ALTPCM, 0x00, 0, 0, 0x00, 0, 0),
1400MIX_ENT(SOUND_MIXER_RECLEV, 0x00, 0, 0, 0x00, 0, 0),
1401MIX_ENT(SOUND_MIXER_IGAIN, 0x00, 0, 0, 0x00, 0, 0),
1402MIX_ENT(SOUND_MIXER_OGAIN, 0x00, 0, 0, 0x00, 0, 0),
1403MIX_ENT(SOUND_MIXER_LINE1, 0x00, 0, 0, 0x00, 0, 0),
1404MIX_ENT(SOUND_MIXER_LINE2, 0x3a, 7, 4, 0x3a, 3, 4),
1405MIX_ENT(SOUND_MIXER_LINE3, 0x00, 0, 0, 0x00, 0, 0)
1406};
1407
1408
1409
1410
1411
1412
1413
1414
1415static mixer_tab es1688_mix = {
1416MIX_ENT(SOUND_MIXER_VOLUME, 0x32, 7, 4, 0x32, 3, 4),
1417MIX_ENT(SOUND_MIXER_BASS, 0x00, 0, 0, 0x00, 0, 0),
1418MIX_ENT(SOUND_MIXER_TREBLE, 0x00, 0, 0, 0x00, 0, 0),
1419MIX_ENT(SOUND_MIXER_SYNTH, 0x36, 7, 4, 0x36, 3, 4),
1420MIX_ENT(SOUND_MIXER_PCM, 0x14, 7, 4, 0x14, 3, 4),
1421MIX_ENT(SOUND_MIXER_SPEAKER, 0x3c, 2, 3, 0x00, 0, 0),
1422MIX_ENT(SOUND_MIXER_LINE, 0x3e, 7, 4, 0x3e, 3, 4),
1423MIX_ENT(SOUND_MIXER_MIC, 0x1a, 7, 4, 0x1a, 3, 4),
1424MIX_ENT(SOUND_MIXER_CD, 0x38, 7, 4, 0x38, 3, 4),
1425MIX_ENT(SOUND_MIXER_IMIX, 0x00, 0, 0, 0x00, 0, 0),
1426MIX_ENT(SOUND_MIXER_ALTPCM, 0x00, 0, 0, 0x00, 0, 0),
1427MIX_ENT(SOUND_MIXER_RECLEV, 0xb4, 7, 4, 0xb4, 3, 4),
1428MIX_ENT(SOUND_MIXER_IGAIN, 0x00, 0, 0, 0x00, 0, 0),
1429MIX_ENT(SOUND_MIXER_OGAIN, 0x00, 0, 0, 0x00, 0, 0),
1430MIX_ENT(SOUND_MIXER_LINE1, 0x00, 0, 0, 0x00, 0, 0),
1431MIX_ENT(SOUND_MIXER_LINE2, 0x3a, 7, 4, 0x3a, 3, 4),
1432MIX_ENT(SOUND_MIXER_LINE3, 0x00, 0, 0, 0x00, 0, 0)
1433};
1434
1435static mixer_tab es1688later_mix = {
1436MIX_ENT(SOUND_MIXER_VOLUME, 0x60, 5, 6, 0x62, 5, 6),
1437MIX_ENT(SOUND_MIXER_BASS, 0x00, 0, 0, 0x00, 0, 0),
1438MIX_ENT(SOUND_MIXER_TREBLE, 0x00, 0, 0, 0x00, 0, 0),
1439MIX_ENT(SOUND_MIXER_SYNTH, 0x36, 7, 4, 0x36, 3, 4),
1440MIX_ENT(SOUND_MIXER_PCM, 0x14, 7, 4, 0x14, 3, 4),
1441MIX_ENT(SOUND_MIXER_SPEAKER, 0x3c, 2, 3, 0x00, 0, 0),
1442MIX_ENT(SOUND_MIXER_LINE, 0x3e, 7, 4, 0x3e, 3, 4),
1443MIX_ENT(SOUND_MIXER_MIC, 0x1a, 7, 4, 0x1a, 3, 4),
1444MIX_ENT(SOUND_MIXER_CD, 0x38, 7, 4, 0x38, 3, 4),
1445MIX_ENT(SOUND_MIXER_IMIX, 0x00, 0, 0, 0x00, 0, 0),
1446MIX_ENT(SOUND_MIXER_ALTPCM, 0x00, 0, 0, 0x00, 0, 0),
1447MIX_ENT(SOUND_MIXER_RECLEV, 0xb4, 7, 4, 0xb4, 3, 4),
1448MIX_ENT(SOUND_MIXER_IGAIN, 0x00, 0, 0, 0x00, 0, 0),
1449MIX_ENT(SOUND_MIXER_OGAIN, 0x00, 0, 0, 0x00, 0, 0),
1450MIX_ENT(SOUND_MIXER_LINE1, 0x00, 0, 0, 0x00, 0, 0),
1451MIX_ENT(SOUND_MIXER_LINE2, 0x3a, 7, 4, 0x3a, 3, 4),
1452MIX_ENT(SOUND_MIXER_LINE3, 0x00, 0, 0, 0x00, 0, 0)
1453};
1454
1455
1456
1457
1458
1459static mixer_tab es_rec_mix = {
1460MIX_ENT(SOUND_MIXER_VOLUME, 0x60, 5, 6, 0x62, 5, 6),
1461MIX_ENT(SOUND_MIXER_BASS, 0x00, 0, 0, 0x00, 0, 0),
1462MIX_ENT(SOUND_MIXER_TREBLE, 0x00, 0, 0, 0x00, 0, 0),
1463MIX_ENT(SOUND_MIXER_SYNTH, 0x36, 7, 4, 0x36, 3, 4),
1464MIX_ENT(SOUND_MIXER_PCM, 0x14, 7, 4, 0x14, 3, 4),
1465MIX_ENT(SOUND_MIXER_SPEAKER, 0x3c, 2, 3, 0x00, 0, 0),
1466MIX_ENT(SOUND_MIXER_LINE, 0x3e, 7, 4, 0x3e, 3, 4),
1467MIX_ENT(SOUND_MIXER_MIC, 0x1a, 7, 4, 0x1a, 3, 4),
1468MIX_ENT(SOUND_MIXER_CD, 0x38, 7, 4, 0x38, 3, 4),
1469MIX_ENT(SOUND_MIXER_IMIX, 0x00, 0, 0, 0x00, 0, 0),
1470MIX_ENT(SOUND_MIXER_ALTPCM, 0x00, 0, 0, 0x00, 0, 0),
1471MIX_ENT(SOUND_MIXER_RECLEV, 0xb4, 7, 4, 0xb4, 3, 4),
1472MIX_ENT(SOUND_MIXER_IGAIN, 0x00, 0, 0, 0x00, 0, 0),
1473MIX_ENT(SOUND_MIXER_OGAIN, 0x00, 0, 0, 0x00, 0, 0),
1474MIX_ENT(SOUND_MIXER_LINE1, 0x00, 0, 0, 0x00, 0, 0),
1475MIX_ENT(SOUND_MIXER_LINE2, 0x3a, 7, 4, 0x3a, 3, 4),
1476MIX_ENT(SOUND_MIXER_LINE3, 0x00, 0, 0, 0x00, 0, 0),
1477MIX_ENT(ES_REC_MIXER_RECSYNTH, 0x6b, 7, 4, 0x6b, 3, 4),
1478MIX_ENT(ES_REC_MIXER_RECPCM, 0x00, 0, 0, 0x00, 0, 0),
1479MIX_ENT(ES_REC_MIXER_RECSPEAKER, 0x00, 0, 0, 0x00, 0, 0),
1480MIX_ENT(ES_REC_MIXER_RECLINE, 0x6e, 7, 4, 0x6e, 3, 4),
1481MIX_ENT(ES_REC_MIXER_RECMIC, 0x68, 7, 4, 0x68, 3, 4),
1482MIX_ENT(ES_REC_MIXER_RECCD, 0x6a, 7, 4, 0x6a, 3, 4),
1483MIX_ENT(ES_REC_MIXER_RECIMIX, 0x00, 0, 0, 0x00, 0, 0),
1484MIX_ENT(ES_REC_MIXER_RECALTPCM, 0x00, 0, 0, 0x00, 0, 0),
1485MIX_ENT(ES_REC_MIXER_RECRECLEV, 0x00, 0, 0, 0x00, 0, 0),
1486MIX_ENT(ES_REC_MIXER_RECIGAIN, 0x00, 0, 0, 0x00, 0, 0),
1487MIX_ENT(ES_REC_MIXER_RECOGAIN, 0x00, 0, 0, 0x00, 0, 0),
1488MIX_ENT(ES_REC_MIXER_RECLINE1, 0x00, 0, 0, 0x00, 0, 0),
1489MIX_ENT(ES_REC_MIXER_RECLINE2, 0x6c, 7, 4, 0x6c, 3, 4),
1490MIX_ENT(ES_REC_MIXER_RECLINE3, 0x00, 0, 0, 0x00, 0, 0)
1491};
1492
1493
1494
1495
1496
1497
1498static mixer_tab es1887_mix = {
1499MIX_ENT(SOUND_MIXER_VOLUME, 0x60, 5, 6, 0x62, 5, 6),
1500MIX_ENT(SOUND_MIXER_BASS, 0x00, 0, 0, 0x00, 0, 0),
1501MIX_ENT(SOUND_MIXER_TREBLE, 0x00, 0, 0, 0x00, 0, 0),
1502MIX_ENT(SOUND_MIXER_SYNTH, 0x36, 7, 4, 0x36, 3, 4),
1503MIX_ENT(SOUND_MIXER_PCM, 0x7c, 7, 4, 0x7c, 3, 4),
1504MIX_ENT(SOUND_MIXER_SPEAKER, 0x3c, 2, 3, 0x00, 0, 0),
1505MIX_ENT(SOUND_MIXER_LINE, 0x3e, 7, 4, 0x3e, 3, 4),
1506MIX_ENT(SOUND_MIXER_MIC, 0x1a, 7, 4, 0x1a, 3, 4),
1507MIX_ENT(SOUND_MIXER_CD, 0x38, 7, 4, 0x38, 3, 4),
1508MIX_ENT(SOUND_MIXER_IMIX, 0x00, 0, 0, 0x00, 0, 0),
1509MIX_ENT(SOUND_MIXER_ALTPCM, 0x00, 0, 0, 0x00, 0, 0),
1510MIX_ENT(SOUND_MIXER_RECLEV, 0xb4, 7, 4, 0xb4, 3, 4),
1511MIX_ENT(SOUND_MIXER_IGAIN, 0x00, 0, 0, 0x00, 0, 0),
1512MIX_ENT(SOUND_MIXER_OGAIN, 0x00, 0, 0, 0x00, 0, 0),
1513MIX_ENT(SOUND_MIXER_LINE1, 0x00, 0, 0, 0x00, 0, 0),
1514MIX_ENT(SOUND_MIXER_LINE2, 0x3a, 7, 4, 0x3a, 3, 4),
1515MIX_ENT(SOUND_MIXER_LINE3, 0x00, 0, 0, 0x00, 0, 0),
1516MIX_ENT(ES_REC_MIXER_RECSYNTH, 0x6b, 7, 4, 0x6b, 3, 4),
1517MIX_ENT(ES_REC_MIXER_RECPCM, 0x00, 0, 0, 0x00, 0, 0),
1518MIX_ENT(ES_REC_MIXER_RECSPEAKER, 0x00, 0, 0, 0x00, 0, 0),
1519MIX_ENT(ES_REC_MIXER_RECLINE, 0x6e, 7, 4, 0x6e, 3, 4),
1520MIX_ENT(ES_REC_MIXER_RECMIC, 0x68, 7, 4, 0x68, 3, 4),
1521MIX_ENT(ES_REC_MIXER_RECCD, 0x6a, 7, 4, 0x6a, 3, 4),
1522MIX_ENT(ES_REC_MIXER_RECIMIX, 0x00, 0, 0, 0x00, 0, 0),
1523MIX_ENT(ES_REC_MIXER_RECALTPCM, 0x00, 0, 0, 0x00, 0, 0),
1524MIX_ENT(ES_REC_MIXER_RECRECLEV, 0x00, 0, 0, 0x00, 0, 0),
1525MIX_ENT(ES_REC_MIXER_RECIGAIN, 0x00, 0, 0, 0x00, 0, 0),
1526MIX_ENT(ES_REC_MIXER_RECOGAIN, 0x00, 0, 0, 0x00, 0, 0),
1527MIX_ENT(ES_REC_MIXER_RECLINE1, 0x00, 0, 0, 0x00, 0, 0),
1528MIX_ENT(ES_REC_MIXER_RECLINE2, 0x6c, 7, 4, 0x6c, 3, 4),
1529MIX_ENT(ES_REC_MIXER_RECLINE3, 0x00, 0, 0, 0x00, 0, 0)
1530};
1531
1532static int ess_has_rec_mixer (int submodel)
1533{
1534 switch (submodel) {
1535 case SUBMDL_ES1887:
1536 return 1;
1537 default:
1538 return 0;
1539 }
1540};
1541
1542#ifdef FKS_LOGGING
1543static int ess_mixer_mon_regs[]
1544 = { 0x70, 0x71, 0x72, 0x74, 0x76, 0x78, 0x7a, 0x7c, 0x7d, 0x7f
1545 , 0xa1, 0xa2, 0xa4, 0xa5, 0xa8, 0xa9
1546 , 0xb1, 0xb2, 0xb4, 0xb5, 0xb6, 0xb7, 0xb9
1547 , 0x00};
1548
1549static void ess_show_mixerregs (sb_devc *devc)
1550{
1551 int *mp = ess_mixer_mon_regs;
1552
1553return;
1554
1555 while (*mp != 0) {
1556 printk (KERN_INFO "res (%x)=%x\n", *mp, (int)(ess_getmixer (devc, *mp)));
1557 mp++;
1558 }
1559}
1560#endif
1561
1562void ess_setmixer (sb_devc * devc, unsigned int port, unsigned int value)
1563{
1564 unsigned long flags;
1565
1566#ifdef FKS_LOGGING
1567printk(KERN_INFO "FKS: write mixer %x: %x\n", port, value);
1568#endif
1569
1570 spin_lock_irqsave(&devc->lock, flags);
1571 if (port >= 0xa0) {
1572 ess_write (devc, port, value);
1573 } else {
1574 outb(((unsigned char) (port & 0xff)), MIXER_ADDR);
1575
1576 udelay(20);
1577 outb(((unsigned char) (value & 0xff)), MIXER_DATA);
1578 udelay(20);
1579 }
1580 spin_unlock_irqrestore(&devc->lock, flags);
1581}
1582
1583unsigned int ess_getmixer (sb_devc * devc, unsigned int port)
1584{
1585 unsigned int val;
1586 unsigned long flags;
1587
1588 spin_lock_irqsave(&devc->lock, flags);
1589
1590 if (port >= 0xa0) {
1591 val = ess_read (devc, port);
1592 } else {
1593 outb(((unsigned char) (port & 0xff)), MIXER_ADDR);
1594
1595 udelay(20);
1596 val = inb(MIXER_DATA);
1597 udelay(20);
1598 }
1599 spin_unlock_irqrestore(&devc->lock, flags);
1600
1601 return val;
1602}
1603
1604static void ess_chgmixer
1605 (sb_devc * devc, unsigned int reg, unsigned int mask, unsigned int val)
1606{
1607 int value;
1608
1609 value = ess_getmixer (devc, reg);
1610 value = (value & ~mask) | (val & mask);
1611 ess_setmixer (devc, reg, value);
1612}
1613
1614
1615
1616
1617void ess_mixer_init (sb_devc * devc)
1618{
1619 devc->mixer_caps = SOUND_CAP_EXCL_INPUT;
1620
1621
1622
1623
1624 switch (devc->submodel) {
1625 case SUBMDL_ES1887:
1626 devc->supported_devices = ES1887_MIXER_DEVICES;
1627 devc->supported_rec_devices = ES1887_RECORDING_DEVICES;
1628#ifdef FKS_LOGGING
1629printk (KERN_INFO "FKS: ess_mixer_init dup = %d\n", devc->duplex);
1630#endif
1631 if (devc->duplex) {
1632 devc->iomap = &es1887_mix;
1633 devc->iomap_sz = ARRAY_SIZE(es1887_mix);
1634 } else {
1635 devc->iomap = &es_rec_mix;
1636 devc->iomap_sz = ARRAY_SIZE(es_rec_mix);
1637 }
1638 break;
1639 default:
1640 if (devc->submodel < 8) {
1641 devc->supported_devices = ES688_MIXER_DEVICES;
1642 devc->supported_rec_devices = ES688_RECORDING_DEVICES;
1643 devc->iomap = &es688_mix;
1644 devc->iomap_sz = ARRAY_SIZE(es688_mix);
1645 } else {
1646
1647
1648
1649
1650 devc->supported_devices = ES1688_MIXER_DEVICES;
1651 devc->supported_rec_devices = ES1688_RECORDING_DEVICES;
1652 if (devc->submodel < 0x10) {
1653 devc->iomap = &es1688_mix;
1654 devc->iomap_sz = ARRAY_SIZE(es688_mix);
1655 } else {
1656 devc->iomap = &es1688later_mix;
1657 devc->iomap_sz = ARRAY_SIZE(es1688later_mix);
1658 }
1659 }
1660 }
1661}
1662
1663
1664
1665
1666
1667int ess_mixer_set(sb_devc *devc, int dev, int left, int right)
1668{
1669 if (ess_has_rec_mixer (devc->submodel) && (devc->recmask & (1 << dev))) {
1670 sb_common_mixer_set (devc, dev + ES_REC_MIXER_RECDIFF, left, right);
1671 }
1672 return sb_common_mixer_set (devc, dev, left, right);
1673}
1674
1675
1676
1677
1678
1679
1680void ess_mixer_reload (sb_devc *devc, int dev)
1681{
1682 int left, right, value;
1683
1684 value = devc->levels[dev];
1685 left = value & 0x000000ff;
1686 right = (value & 0x0000ff00) >> 8;
1687
1688 sb_common_mixer_set(devc, dev, left, right);
1689}
1690
1691static int es_rec_set_recmask(sb_devc * devc, int mask)
1692{
1693 int i, i_mask, cur_mask, diff_mask;
1694 int value, left, right;
1695
1696#ifdef FKS_LOGGING
1697printk (KERN_INFO "FKS: es_rec_set_recmask mask = %x\n", mask);
1698#endif
1699
1700
1701
1702
1703
1704
1705 cur_mask = devc->recmask;
1706 diff_mask = (cur_mask ^ mask);
1707
1708 for (i = 0; i < 32; i++) {
1709 i_mask = (1 << i);
1710 if (diff_mask & i_mask) {
1711 if (mask & i_mask) {
1712 value = devc->levels[i];
1713 left = value & 0x000000ff;
1714 right = (value & 0x0000ff00) >> 8;
1715 } else {
1716 left = 0;
1717 right = 0;
1718 }
1719 sb_common_mixer_set(devc, i + ES_REC_MIXER_RECDIFF, left, right);
1720 }
1721 }
1722 return mask;
1723}
1724
1725int ess_set_recmask(sb_devc * devc, int *mask)
1726{
1727
1728
1729 if (ess_has_rec_mixer (devc->submodel)) {
1730 *mask = es_rec_set_recmask (devc, *mask);
1731 return 1;
1732 } else {
1733 return 0;
1734 }
1735}
1736
1737
1738
1739
1740int ess_mixer_reset (sb_devc * devc)
1741{
1742
1743
1744
1745 if (ess_has_rec_mixer (devc->submodel)) {
1746 switch (devc->submodel) {
1747 case SUBMDL_ES1887:
1748
1749
1750
1751
1752
1753 ess_chgmixer(devc, 0x7a, 0x18, 0x08);
1754 ess_chgmixer(devc, 0x1c, 0x07, 0x07);
1755 break;
1756 }
1757
1758
1759
1760 devc->recmask = devc->supported_rec_devices;
1761 es_rec_set_recmask(devc, 0);
1762 devc->recmask = 0;
1763
1764 return 1;
1765 } else {
1766 return 0;
1767 }
1768}
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779int ess_midi_init(sb_devc * devc, struct address_info *hw_config)
1780{
1781 unsigned char cfg, tmp;
1782
1783 cfg = ess_getmixer (devc, 0x40) & 0x03;
1784
1785 if (devc->submodel < 8) {
1786 ess_setmixer (devc, 0x40, cfg | 0x03);
1787 return 0;
1788 }
1789 tmp = (hw_config->io_base & 0x0f0) >> 4;
1790
1791 if (tmp > 3) {
1792 ess_setmixer (devc, 0x40, cfg);
1793 return 0;
1794 }
1795 cfg |= tmp << 3;
1796
1797 tmp = 1;
1798
1799
1800
1801 switch (abs(hw_config->irq)) {
1802 case 9:
1803 tmp = 0x4;
1804 break;
1805 case 5:
1806 tmp = 0x5;
1807 break;
1808 case 7:
1809 tmp = 0x6;
1810 break;
1811 case 10:
1812 tmp = 0x7;
1813 break;
1814 default:
1815 return 0;
1816 }
1817
1818 cfg |= tmp << 5;
1819 ess_setmixer (devc, 0x40, cfg | 0x03);
1820
1821 return 1;
1822}
1823
1824