1
2
3
4
5
6
7
8
9
10#include <linux/delay.h>
11#include <linux/device.h>
12#include <linux/firmware.h>
13#include <linux/mutex.h>
14#include <linux/io.h>
15
16#include <sound/core.h>
17#include <sound/control.h>
18#include <sound/tlv.h>
19#include "vx222.h"
20
21
22static const int vx2_reg_offset[VX_REG_MAX] = {
23 [VX_ICR] = 0x00,
24 [VX_CVR] = 0x04,
25 [VX_ISR] = 0x08,
26 [VX_IVR] = 0x0c,
27 [VX_RXH] = 0x14,
28 [VX_RXM] = 0x18,
29 [VX_RXL] = 0x1c,
30 [VX_DMA] = 0x10,
31 [VX_CDSP] = 0x20,
32 [VX_CFG] = 0x24,
33 [VX_RUER] = 0x28,
34 [VX_DATA] = 0x2c,
35 [VX_STATUS] = 0x30,
36 [VX_LOFREQ] = 0x34,
37 [VX_HIFREQ] = 0x38,
38 [VX_CSUER] = 0x3c,
39 [VX_SELMIC] = 0x40,
40 [VX_COMPOT] = 0x44,
41 [VX_SCOMPR] = 0x48,
42 [VX_GLIMIT] = 0x4c,
43 [VX_INTCSR] = 0x4c,
44 [VX_CNTRL] = 0x50,
45 [VX_GPIOC] = 0x54,
46};
47
48static const int vx2_reg_index[VX_REG_MAX] = {
49 [VX_ICR] = 1,
50 [VX_CVR] = 1,
51 [VX_ISR] = 1,
52 [VX_IVR] = 1,
53 [VX_RXH] = 1,
54 [VX_RXM] = 1,
55 [VX_RXL] = 1,
56 [VX_DMA] = 1,
57 [VX_CDSP] = 1,
58 [VX_CFG] = 1,
59 [VX_RUER] = 1,
60 [VX_DATA] = 1,
61 [VX_STATUS] = 1,
62 [VX_LOFREQ] = 1,
63 [VX_HIFREQ] = 1,
64 [VX_CSUER] = 1,
65 [VX_SELMIC] = 1,
66 [VX_COMPOT] = 1,
67 [VX_SCOMPR] = 1,
68 [VX_GLIMIT] = 1,
69 [VX_INTCSR] = 0,
70 [VX_CNTRL] = 0,
71 [VX_GPIOC] = 0,
72};
73
74static inline unsigned long vx2_reg_addr(struct vx_core *_chip, int reg)
75{
76 struct snd_vx222 *chip = to_vx222(_chip);
77 return chip->port[vx2_reg_index[reg]] + vx2_reg_offset[reg];
78}
79
80
81
82
83
84
85static unsigned char vx2_inb(struct vx_core *chip, int offset)
86{
87 return inb(vx2_reg_addr(chip, offset));
88}
89
90
91
92
93
94
95
96static void vx2_outb(struct vx_core *chip, int offset, unsigned char val)
97{
98 outb(val, vx2_reg_addr(chip, offset));
99
100
101
102}
103
104
105
106
107
108
109static unsigned int vx2_inl(struct vx_core *chip, int offset)
110{
111 return inl(vx2_reg_addr(chip, offset));
112}
113
114
115
116
117
118
119
120static void vx2_outl(struct vx_core *chip, int offset, unsigned int val)
121{
122
123
124
125 outl(val, vx2_reg_addr(chip, offset));
126}
127
128
129
130
131#undef vx_inb
132#define vx_inb(chip,reg) vx2_inb((struct vx_core*)(chip), VX_##reg)
133#undef vx_outb
134#define vx_outb(chip,reg,val) vx2_outb((struct vx_core*)(chip), VX_##reg, val)
135#undef vx_inl
136#define vx_inl(chip,reg) vx2_inl((struct vx_core*)(chip), VX_##reg)
137#undef vx_outl
138#define vx_outl(chip,reg,val) vx2_outl((struct vx_core*)(chip), VX_##reg, val)
139
140
141
142
143
144
145#define XX_DSP_RESET_WAIT_TIME 2
146
147static void vx2_reset_dsp(struct vx_core *_chip)
148{
149 struct snd_vx222 *chip = to_vx222(_chip);
150
151
152 vx_outl(chip, CDSP, chip->regCDSP & ~VX_CDSP_DSP_RESET_MASK);
153
154 mdelay(XX_DSP_RESET_WAIT_TIME);
155
156 chip->regCDSP |= VX_CDSP_DSP_RESET_MASK;
157
158 vx_outl(chip, CDSP, chip->regCDSP);
159}
160
161
162static int vx2_test_xilinx(struct vx_core *_chip)
163{
164 struct snd_vx222 *chip = to_vx222(_chip);
165 unsigned int data;
166
167 dev_dbg(_chip->card->dev, "testing xilinx...\n");
168
169
170
171
172
173 vx_outl(chip, CDSP, chip->regCDSP | VX_CDSP_TEST0_MASK);
174 vx_inl(chip, ISR);
175 data = vx_inl(chip, STATUS);
176 if ((data & VX_STATUS_VAL_TEST0_MASK) == VX_STATUS_VAL_TEST0_MASK) {
177 dev_dbg(_chip->card->dev, "bad!\n");
178 return -ENODEV;
179 }
180
181
182 vx_outl(chip, CDSP, chip->regCDSP & ~VX_CDSP_TEST0_MASK);
183 vx_inl(chip, ISR);
184 data = vx_inl(chip, STATUS);
185 if (! (data & VX_STATUS_VAL_TEST0_MASK)) {
186 dev_dbg(_chip->card->dev, "bad! #2\n");
187 return -ENODEV;
188 }
189
190 if (_chip->type == VX_TYPE_BOARD) {
191
192
193 vx_outl(chip, CDSP, chip->regCDSP | VX_CDSP_TEST1_MASK);
194 vx_inl(chip, ISR);
195 data = vx_inl(chip, STATUS);
196 if ((data & VX_STATUS_VAL_TEST1_MASK) == VX_STATUS_VAL_TEST1_MASK) {
197 dev_dbg(_chip->card->dev, "bad! #3\n");
198 return -ENODEV;
199 }
200
201
202 vx_outl(chip, CDSP, chip->regCDSP & ~VX_CDSP_TEST1_MASK);
203 vx_inl(chip, ISR);
204 data = vx_inl(chip, STATUS);
205 if (! (data & VX_STATUS_VAL_TEST1_MASK)) {
206 dev_dbg(_chip->card->dev, "bad! #4\n");
207 return -ENODEV;
208 }
209 }
210 dev_dbg(_chip->card->dev, "ok, xilinx fine.\n");
211 return 0;
212}
213
214
215
216
217
218
219
220static void vx2_setup_pseudo_dma(struct vx_core *chip, int do_write)
221{
222
223
224
225 vx_outl(chip, ICR, do_write ? ICR_TREQ : ICR_RREQ);
226
227
228
229
230 vx_outl(chip, RESET_DMA, 0);
231}
232
233
234
235
236static inline void vx2_release_pseudo_dma(struct vx_core *chip)
237{
238
239 vx_outl(chip, ICR, 0);
240}
241
242
243
244
245static void vx2_dma_write(struct vx_core *chip, struct snd_pcm_runtime *runtime,
246 struct vx_pipe *pipe, int count)
247{
248 unsigned long port = vx2_reg_addr(chip, VX_DMA);
249 int offset = pipe->hw_ptr;
250 u32 *addr = (u32 *)(runtime->dma_area + offset);
251
252 if (snd_BUG_ON(count % 4))
253 return;
254
255 vx2_setup_pseudo_dma(chip, 1);
256
257
258
259 if (offset + count >= pipe->buffer_bytes) {
260 int length = pipe->buffer_bytes - offset;
261 count -= length;
262 length >>= 2;
263
264 for (; length > 0; length--) {
265 outl(*addr, port);
266 addr++;
267 }
268 addr = (u32 *)runtime->dma_area;
269 pipe->hw_ptr = 0;
270 }
271 pipe->hw_ptr += count;
272 count >>= 2;
273
274 for (; count > 0; count--) {
275 outl(*addr, port);
276 addr++;
277 }
278
279 vx2_release_pseudo_dma(chip);
280}
281
282
283
284static void vx2_dma_read(struct vx_core *chip, struct snd_pcm_runtime *runtime,
285 struct vx_pipe *pipe, int count)
286{
287 int offset = pipe->hw_ptr;
288 u32 *addr = (u32 *)(runtime->dma_area + offset);
289 unsigned long port = vx2_reg_addr(chip, VX_DMA);
290
291 if (snd_BUG_ON(count % 4))
292 return;
293
294 vx2_setup_pseudo_dma(chip, 0);
295
296
297 if (offset + count >= pipe->buffer_bytes) {
298 int length = pipe->buffer_bytes - offset;
299 count -= length;
300 length >>= 2;
301
302 for (; length > 0; length--)
303 *addr++ = inl(port);
304 addr = (u32 *)runtime->dma_area;
305 pipe->hw_ptr = 0;
306 }
307 pipe->hw_ptr += count;
308 count >>= 2;
309
310 for (; count > 0; count--)
311 *addr++ = inl(port);
312
313 vx2_release_pseudo_dma(chip);
314}
315
316#define VX_XILINX_RESET_MASK 0x40000000
317#define VX_USERBIT0_MASK 0x00000004
318#define VX_USERBIT1_MASK 0x00000020
319#define VX_CNTRL_REGISTER_VALUE 0x00172012
320
321
322
323
324static int put_xilinx_data(struct vx_core *chip, unsigned int port, unsigned int counts, unsigned char data)
325{
326 unsigned int i;
327
328 for (i = 0; i < counts; i++) {
329 unsigned int val;
330
331
332 val = VX_CNTRL_REGISTER_VALUE & ~VX_USERBIT0_MASK;
333 vx2_outl(chip, port, val);
334 vx2_inl(chip, port);
335 udelay(1);
336
337 if (data & (1 << i))
338 val |= VX_USERBIT1_MASK;
339 else
340 val &= ~VX_USERBIT1_MASK;
341 vx2_outl(chip, port, val);
342 vx2_inl(chip, port);
343
344
345 val |= VX_USERBIT0_MASK;
346 vx2_outl(chip, port, val);
347 vx2_inl(chip, port);
348 udelay(1);
349 }
350 return 0;
351}
352
353
354
355
356static int vx2_load_xilinx_binary(struct vx_core *chip, const struct firmware *xilinx)
357{
358 unsigned int i;
359 unsigned int port;
360 const unsigned char *image;
361
362
363 vx_outl(chip, CNTRL, VX_CNTRL_REGISTER_VALUE | VX_XILINX_RESET_MASK);
364 vx_inl(chip, CNTRL);
365 msleep(10);
366 vx_outl(chip, CNTRL, VX_CNTRL_REGISTER_VALUE);
367 vx_inl(chip, CNTRL);
368 msleep(10);
369
370 if (chip->type == VX_TYPE_BOARD)
371 port = VX_CNTRL;
372 else
373 port = VX_GPIOC;
374
375 image = xilinx->data;
376 for (i = 0; i < xilinx->size; i++, image++) {
377 if (put_xilinx_data(chip, port, 8, *image) < 0)
378 return -EINVAL;
379
380 cond_resched();
381 }
382 put_xilinx_data(chip, port, 4, 0xff);
383
384 msleep(200);
385
386
387 if (chip->type != VX_TYPE_BOARD) {
388
389 i = vx_inl(chip, GPIOC);
390 if (i & 0x0100)
391 return 0;
392 dev_err(chip->card->dev,
393 "xilinx test failed after load, GPIOC=0x%x\n", i);
394 return -EINVAL;
395 }
396
397 return 0;
398}
399
400
401
402
403
404static int vx2_load_dsp(struct vx_core *vx, int index, const struct firmware *dsp)
405{
406 int err;
407
408 switch (index) {
409 case 1:
410
411 if ((err = vx2_load_xilinx_binary(vx, dsp)) < 0)
412 return err;
413 if ((err = vx2_test_xilinx(vx)) < 0)
414 return err;
415 return 0;
416 case 2:
417
418 return snd_vx_dsp_boot(vx, dsp);
419 case 3:
420
421 return snd_vx_dsp_load(vx, dsp);
422 default:
423 snd_BUG();
424 return -EINVAL;
425 }
426}
427
428
429
430
431
432
433
434
435
436static int vx2_test_and_ack(struct vx_core *chip)
437{
438
439 if (! (chip->chip_status & VX_STAT_XILINX_LOADED))
440 return -ENXIO;
441
442 if (! (vx_inl(chip, STATUS) & VX_STATUS_MEMIRQ_MASK))
443 return -EIO;
444
445
446
447 vx_outl(chip, STATUS, 0);
448
449
450
451 vx_inl(chip, STATUS);
452
453 vx_outl(chip, STATUS, VX_STATUS_MEMIRQ_MASK);
454
455
456 vx_inl(chip, STATUS);
457
458 vx_outl(chip, STATUS, 0);
459
460 return 0;
461}
462
463
464
465
466
467static void vx2_validate_irq(struct vx_core *_chip, int enable)
468{
469 struct snd_vx222 *chip = to_vx222(_chip);
470
471
472 if (enable) {
473
474 vx_outl(chip, INTCSR, VX_INTCSR_VALUE|VX_PCI_INTERRUPT_MASK);
475 chip->regCDSP |= VX_CDSP_VALID_IRQ_MASK;
476 } else {
477
478 vx_outl(chip, INTCSR, VX_INTCSR_VALUE&~VX_PCI_INTERRUPT_MASK);
479 chip->regCDSP &= ~VX_CDSP_VALID_IRQ_MASK;
480 }
481 vx_outl(chip, CDSP, chip->regCDSP);
482}
483
484
485
486
487
488static void vx2_write_codec_reg(struct vx_core *chip, unsigned int data)
489{
490 unsigned int i;
491
492 vx_inl(chip, HIFREQ);
493
494
495 for (i = 0; i < 24; i++, data <<= 1)
496 vx_outl(chip, DATA, ((data & 0x800000) ? VX_DATA_CODEC_MASK : 0));
497
498 vx_inl(chip, RUER);
499}
500
501
502#define AKM_CODEC_POWER_CONTROL_CMD 0xA007
503#define AKM_CODEC_RESET_ON_CMD 0xA100
504#define AKM_CODEC_RESET_OFF_CMD 0xA103
505#define AKM_CODEC_CLOCK_FORMAT_CMD 0xA240
506#define AKM_CODEC_MUTE_CMD 0xA38D
507#define AKM_CODEC_UNMUTE_CMD 0xA30D
508#define AKM_CODEC_LEFT_LEVEL_CMD 0xA400
509#define AKM_CODEC_RIGHT_LEVEL_CMD 0xA500
510
511static const u8 vx2_akm_gains_lut[VX2_AKM_LEVEL_MAX+1] = {
512 0x7f,
513 0x7d,
514 0x7c,
515 0x7a,
516 0x79,
517 0x77,
518 0x76,
519 0x75,
520 0x73,
521 0x72,
522 0x71,
523 0x70,
524 0x6f,
525 0x6d,
526 0x6c,
527 0x6a,
528 0x69,
529 0x67,
530 0x66,
531 0x65,
532 0x64,
533 0x62,
534 0x61,
535 0x60,
536 0x5f,
537 0x5e,
538 0x5c,
539 0x5b,
540 0x59,
541 0x58,
542 0x56,
543 0x55,
544 0x54,
545 0x53,
546 0x52,
547 0x51,
548 0x50,
549 0x4e,
550 0x4d,
551 0x4b,
552 0x4a,
553 0x48,
554 0x47,
555 0x46,
556 0x44,
557 0x43,
558 0x42,
559 0x41,
560 0x40,
561 0x3f,
562 0x3e,
563 0x3c,
564 0x3b,
565 0x39,
566 0x38,
567 0x37,
568 0x36,
569 0x34,
570 0x33,
571 0x32,
572 0x31,
573 0x31,
574 0x30,
575 0x2e,
576 0x2d,
577 0x2b,
578 0x2a,
579 0x29,
580 0x28,
581 0x27,
582 0x25,
583 0x24,
584 0x24,
585 0x23,
586 0x22,
587 0x21,
588 0x20,
589 0x1f,
590 0x1e,
591 0x1d,
592 0x1c,
593 0x1b,
594 0x1a,
595 0x19,
596 0x18,
597 0x17,
598 0x16,
599 0x15,
600 0x14,
601 0x14,
602 0x13,
603 0x12,
604 0x12,
605 0x11,
606 0x11,
607 0x10,
608 0x10,
609 0x0f,
610 0x0e,
611 0x0d,
612 0x0d,
613 0x0c,
614 0x0b,
615 0x0b,
616 0x0a,
617 0x0a,
618 0x09,
619 0x09,
620 0x08,
621 0x08,
622 0x07,
623 0x07,
624 0x06,
625 0x06,
626 0x06,
627 0x05,
628 0x05,
629 0x05,
630 0x05,
631 0x04,
632 0x04,
633 0x04,
634 0x04,
635 0x03,
636 0x03,
637 0x03,
638 0x03,
639 0x03,
640 0x03,
641 0x02,
642 0x02,
643 0x02,
644 0x02,
645 0x02,
646 0x02,
647 0x02,
648 0x02,
649 0x02,
650 0x02,
651 0x01,
652 0x01,
653 0x01,
654 0x01,
655 0x01,
656 0x01,
657 0x01,
658 0x01,
659 0x00};
660
661
662
663
664static void vx2_write_akm(struct vx_core *chip, int reg, unsigned int data)
665{
666 unsigned int val;
667
668 if (reg == XX_CODEC_DAC_CONTROL_REGISTER) {
669 vx2_write_codec_reg(chip, data ? AKM_CODEC_MUTE_CMD : AKM_CODEC_UNMUTE_CMD);
670 return;
671 }
672
673
674
675
676
677 if (snd_BUG_ON(data >= sizeof(vx2_akm_gains_lut)))
678 return;
679
680 switch (reg) {
681 case XX_CODEC_LEVEL_LEFT_REGISTER:
682 val = AKM_CODEC_LEFT_LEVEL_CMD;
683 break;
684 case XX_CODEC_LEVEL_RIGHT_REGISTER:
685 val = AKM_CODEC_RIGHT_LEVEL_CMD;
686 break;
687 default:
688 snd_BUG();
689 return;
690 }
691 val |= vx2_akm_gains_lut[data];
692
693 vx2_write_codec_reg(chip, val);
694}
695
696
697
698
699
700static void vx2_old_write_codec_bit(struct vx_core *chip, int codec, unsigned int data)
701{
702 int i;
703
704
705 vx_inl(chip, HIFREQ);
706
707 for (i = 0; i < 24; i++, data <<= 1)
708 vx_outl(chip, DATA, ((data & 0x800000) ? VX_DATA_CODEC_MASK : 0));
709
710
711 vx_inl(chip, RUER);
712}
713
714
715
716
717
718static void vx2_reset_codec(struct vx_core *_chip)
719{
720 struct snd_vx222 *chip = to_vx222(_chip);
721
722
723 vx_outl(chip, CDSP, chip->regCDSP &~ VX_CDSP_CODEC_RESET_MASK);
724 vx_inl(chip, CDSP);
725 msleep(10);
726
727 chip->regCDSP |= VX_CDSP_CODEC_RESET_MASK;
728 vx_outl(chip, CDSP, chip->regCDSP);
729 vx_inl(chip, CDSP);
730 if (_chip->type == VX_TYPE_BOARD) {
731 msleep(1);
732 return;
733 }
734
735 msleep(5);
736
737 vx2_write_codec_reg(_chip, AKM_CODEC_POWER_CONTROL_CMD);
738
739 vx2_write_codec_reg(_chip, AKM_CODEC_CLOCK_FORMAT_CMD);
740 vx2_write_codec_reg(_chip, AKM_CODEC_MUTE_CMD);
741 vx2_write_codec_reg(_chip, AKM_CODEC_RESET_OFF_CMD);
742
743 if (_chip->type == VX_TYPE_MIC) {
744
745 chip->regSELMIC = MICRO_SELECT_INPUT_NORM |
746 MICRO_SELECT_PREAMPLI_G_0 |
747 MICRO_SELECT_NOISE_T_52DB;
748
749
750 chip->regSELMIC &= ~MICRO_SELECT_PHANTOM_ALIM;
751
752 vx_outl(_chip, SELMIC, chip->regSELMIC);
753 }
754}
755
756
757
758
759
760static void vx2_change_audio_source(struct vx_core *_chip, int src)
761{
762 struct snd_vx222 *chip = to_vx222(_chip);
763
764 switch (src) {
765 case VX_AUDIO_SRC_DIGITAL:
766 chip->regCFG |= VX_CFG_DATAIN_SEL_MASK;
767 break;
768 default:
769 chip->regCFG &= ~VX_CFG_DATAIN_SEL_MASK;
770 break;
771 }
772 vx_outl(chip, CFG, chip->regCFG);
773}
774
775
776
777
778
779static void vx2_set_clock_source(struct vx_core *_chip, int source)
780{
781 struct snd_vx222 *chip = to_vx222(_chip);
782
783 if (source == INTERNAL_QUARTZ)
784 chip->regCFG &= ~VX_CFG_CLOCKIN_SEL_MASK;
785 else
786 chip->regCFG |= VX_CFG_CLOCKIN_SEL_MASK;
787 vx_outl(chip, CFG, chip->regCFG);
788}
789
790
791
792
793static void vx2_reset_board(struct vx_core *_chip, int cold_reset)
794{
795 struct snd_vx222 *chip = to_vx222(_chip);
796
797
798 chip->regCDSP = VX_CDSP_CODEC_RESET_MASK | VX_CDSP_DSP_RESET_MASK ;
799 chip->regCFG = 0;
800}
801
802
803
804
805
806
807
808
809
810
811
812#define V2_MICRO_LEVEL_RANGE (318 - 255)
813
814static void vx2_set_input_level(struct snd_vx222 *chip)
815{
816 int i, miclevel, preamp;
817 unsigned int data;
818
819 miclevel = chip->mic_level;
820 miclevel += V2_MICRO_LEVEL_RANGE;
821 preamp = 0;
822 while (miclevel > 210) {
823 preamp++;
824 miclevel -= (18 * 2);
825 }
826 if (snd_BUG_ON(preamp >= 4))
827 return;
828
829
830 chip->regSELMIC &= ~MICRO_SELECT_PREAMPLI_MASK;
831 chip->regSELMIC |= (preamp << MICRO_SELECT_PREAMPLI_OFFSET) & MICRO_SELECT_PREAMPLI_MASK;
832 vx_outl(chip, SELMIC, chip->regSELMIC);
833
834 data = (unsigned int)miclevel << 16 |
835 (unsigned int)chip->input_level[1] << 8 |
836 (unsigned int)chip->input_level[0];
837 vx_inl(chip, DATA);
838
839
840 for (i = 0; i < 32; i++, data <<= 1)
841 vx_outl(chip, DATA, ((data & 0x80000000) ? VX_DATA_CODEC_MASK : 0));
842
843 vx_inl(chip, RUER);
844}
845
846
847#define MIC_LEVEL_MAX 0xff
848
849static const DECLARE_TLV_DB_SCALE(db_scale_mic, -6450, 50, 0);
850
851
852
853
854
855
856static int vx_input_level_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
857{
858 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
859 uinfo->count = 2;
860 uinfo->value.integer.min = 0;
861 uinfo->value.integer.max = MIC_LEVEL_MAX;
862 return 0;
863}
864
865static int vx_input_level_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
866{
867 struct vx_core *_chip = snd_kcontrol_chip(kcontrol);
868 struct snd_vx222 *chip = to_vx222(_chip);
869 mutex_lock(&_chip->mixer_mutex);
870 ucontrol->value.integer.value[0] = chip->input_level[0];
871 ucontrol->value.integer.value[1] = chip->input_level[1];
872 mutex_unlock(&_chip->mixer_mutex);
873 return 0;
874}
875
876static int vx_input_level_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
877{
878 struct vx_core *_chip = snd_kcontrol_chip(kcontrol);
879 struct snd_vx222 *chip = to_vx222(_chip);
880 if (ucontrol->value.integer.value[0] < 0 ||
881 ucontrol->value.integer.value[0] > MIC_LEVEL_MAX)
882 return -EINVAL;
883 if (ucontrol->value.integer.value[1] < 0 ||
884 ucontrol->value.integer.value[1] > MIC_LEVEL_MAX)
885 return -EINVAL;
886 mutex_lock(&_chip->mixer_mutex);
887 if (chip->input_level[0] != ucontrol->value.integer.value[0] ||
888 chip->input_level[1] != ucontrol->value.integer.value[1]) {
889 chip->input_level[0] = ucontrol->value.integer.value[0];
890 chip->input_level[1] = ucontrol->value.integer.value[1];
891 vx2_set_input_level(chip);
892 mutex_unlock(&_chip->mixer_mutex);
893 return 1;
894 }
895 mutex_unlock(&_chip->mixer_mutex);
896 return 0;
897}
898
899
900static int vx_mic_level_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
901{
902 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
903 uinfo->count = 1;
904 uinfo->value.integer.min = 0;
905 uinfo->value.integer.max = MIC_LEVEL_MAX;
906 return 0;
907}
908
909static int vx_mic_level_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
910{
911 struct vx_core *_chip = snd_kcontrol_chip(kcontrol);
912 struct snd_vx222 *chip = to_vx222(_chip);
913 ucontrol->value.integer.value[0] = chip->mic_level;
914 return 0;
915}
916
917static int vx_mic_level_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
918{
919 struct vx_core *_chip = snd_kcontrol_chip(kcontrol);
920 struct snd_vx222 *chip = to_vx222(_chip);
921 if (ucontrol->value.integer.value[0] < 0 ||
922 ucontrol->value.integer.value[0] > MIC_LEVEL_MAX)
923 return -EINVAL;
924 mutex_lock(&_chip->mixer_mutex);
925 if (chip->mic_level != ucontrol->value.integer.value[0]) {
926 chip->mic_level = ucontrol->value.integer.value[0];
927 vx2_set_input_level(chip);
928 mutex_unlock(&_chip->mixer_mutex);
929 return 1;
930 }
931 mutex_unlock(&_chip->mixer_mutex);
932 return 0;
933}
934
935static const struct snd_kcontrol_new vx_control_input_level = {
936 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
937 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
938 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
939 .name = "Capture Volume",
940 .info = vx_input_level_info,
941 .get = vx_input_level_get,
942 .put = vx_input_level_put,
943 .tlv = { .p = db_scale_mic },
944};
945
946static const struct snd_kcontrol_new vx_control_mic_level = {
947 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
948 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
949 SNDRV_CTL_ELEM_ACCESS_TLV_READ),
950 .name = "Mic Capture Volume",
951 .info = vx_mic_level_info,
952 .get = vx_mic_level_get,
953 .put = vx_mic_level_put,
954 .tlv = { .p = db_scale_mic },
955};
956
957
958
959
960
961static int vx2_add_mic_controls(struct vx_core *_chip)
962{
963 struct snd_vx222 *chip = to_vx222(_chip);
964 int err;
965
966 if (_chip->type != VX_TYPE_MIC)
967 return 0;
968
969
970 chip->input_level[0] = chip->input_level[1] = 0;
971 chip->mic_level = 0;
972 vx2_set_input_level(chip);
973
974
975 if ((err = snd_ctl_add(_chip->card, snd_ctl_new1(&vx_control_input_level, chip))) < 0)
976 return err;
977 if ((err = snd_ctl_add(_chip->card, snd_ctl_new1(&vx_control_mic_level, chip))) < 0)
978 return err;
979
980 return 0;
981}
982
983
984
985
986
987const struct snd_vx_ops vx222_ops = {
988 .in8 = vx2_inb,
989 .in32 = vx2_inl,
990 .out8 = vx2_outb,
991 .out32 = vx2_outl,
992 .test_and_ack = vx2_test_and_ack,
993 .validate_irq = vx2_validate_irq,
994 .akm_write = vx2_write_akm,
995 .reset_codec = vx2_reset_codec,
996 .change_audio_source = vx2_change_audio_source,
997 .set_clock_source = vx2_set_clock_source,
998 .load_dsp = vx2_load_dsp,
999 .reset_dsp = vx2_reset_dsp,
1000 .reset_board = vx2_reset_board,
1001 .dma_write = vx2_dma_write,
1002 .dma_read = vx2_dma_read,
1003 .add_controls = vx2_add_mic_controls,
1004};
1005
1006
1007const struct snd_vx_ops vx222_old_ops = {
1008 .in8 = vx2_inb,
1009 .in32 = vx2_inl,
1010 .out8 = vx2_outb,
1011 .out32 = vx2_outl,
1012 .test_and_ack = vx2_test_and_ack,
1013 .validate_irq = vx2_validate_irq,
1014 .write_codec = vx2_old_write_codec_bit,
1015 .reset_codec = vx2_reset_codec,
1016 .change_audio_source = vx2_change_audio_source,
1017 .set_clock_source = vx2_set_clock_source,
1018 .load_dsp = vx2_load_dsp,
1019 .reset_dsp = vx2_reset_dsp,
1020 .reset_board = vx2_reset_board,
1021 .dma_write = vx2_dma_write,
1022 .dma_read = vx2_dma_read,
1023};
1024
1025