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