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