1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#include <linux/types.h>
19#include <linux/slab.h>
20#include <linux/pci.h>
21#include <linux/io.h>
22#include <linux/string.h>
23#include <linux/kernel.h>
24#include <linux/interrupt.h>
25#include <linux/delay.h>
26#include "cthw20k2.h"
27#include "ct20k2reg.h"
28
29#if BITS_PER_LONG == 32
30#define CT_XFI_DMA_MASK DMA_BIT_MASK(32)
31#else
32#define CT_XFI_DMA_MASK DMA_BIT_MASK(64)
33#endif
34
35struct hw20k2 {
36 struct hw hw;
37
38 unsigned char dev_id;
39 unsigned char addr_size;
40 unsigned char data_size;
41};
42
43static u32 hw_read_20kx(struct hw *hw, u32 reg);
44static void hw_write_20kx(struct hw *hw, u32 reg, u32 data);
45
46
47
48
49
50
51
52
53
54
55
56#define SRCCTL_STATE 0x00000007
57#define SRCCTL_BM 0x00000008
58#define SRCCTL_RSR 0x00000030
59#define SRCCTL_SF 0x000001C0
60#define SRCCTL_WR 0x00000200
61#define SRCCTL_PM 0x00000400
62#define SRCCTL_ROM 0x00001800
63#define SRCCTL_VO 0x00002000
64#define SRCCTL_ST 0x00004000
65#define SRCCTL_IE 0x00008000
66#define SRCCTL_ILSZ 0x000F0000
67#define SRCCTL_BP 0x00100000
68
69#define SRCCCR_CISZ 0x000007FF
70#define SRCCCR_CWA 0x001FF800
71#define SRCCCR_D 0x00200000
72#define SRCCCR_RS 0x01C00000
73#define SRCCCR_NAL 0x3E000000
74#define SRCCCR_RA 0xC0000000
75
76#define SRCCA_CA 0x0FFFFFFF
77#define SRCCA_RS 0xE0000000
78
79#define SRCSA_SA 0x0FFFFFFF
80
81#define SRCLA_LA 0x0FFFFFFF
82
83
84
85#define MPRLH_PITCH 0xFFFFFFFF
86
87
88union src_dirty {
89 struct {
90 u16 ctl:1;
91 u16 ccr:1;
92 u16 sa:1;
93 u16 la:1;
94 u16 ca:1;
95 u16 mpr:1;
96 u16 czbfs:1;
97 u16 rsv:9;
98 } bf;
99 u16 data;
100};
101
102struct src_rsc_ctrl_blk {
103 unsigned int ctl;
104 unsigned int ccr;
105 unsigned int ca;
106 unsigned int sa;
107 unsigned int la;
108 unsigned int mpr;
109 union src_dirty dirty;
110};
111
112
113union src_mgr_dirty {
114 struct {
115 u16 enb0:1;
116 u16 enb1:1;
117 u16 enb2:1;
118 u16 enb3:1;
119 u16 enb4:1;
120 u16 enb5:1;
121 u16 enb6:1;
122 u16 enb7:1;
123 u16 enbsa:1;
124 u16 rsv:7;
125 } bf;
126 u16 data;
127};
128
129struct src_mgr_ctrl_blk {
130 unsigned int enbsa;
131 unsigned int enb[8];
132 union src_mgr_dirty dirty;
133};
134
135
136#define SRCAIM_ARC 0x00000FFF
137#define SRCAIM_NXT 0x00FF0000
138#define SRCAIM_SRC 0xFF000000
139
140struct srcimap {
141 unsigned int srcaim;
142 unsigned int idx;
143};
144
145
146union srcimp_mgr_dirty {
147 struct {
148 u16 srcimap:1;
149 u16 rsv:15;
150 } bf;
151 u16 data;
152};
153
154struct srcimp_mgr_ctrl_blk {
155 struct srcimap srcimap;
156 union srcimp_mgr_dirty dirty;
157};
158
159
160
161
162
163static int src_get_rsc_ctrl_blk(void **rblk)
164{
165 struct src_rsc_ctrl_blk *blk;
166
167 *rblk = NULL;
168 blk = kzalloc(sizeof(*blk), GFP_KERNEL);
169 if (!blk)
170 return -ENOMEM;
171
172 *rblk = blk;
173
174 return 0;
175}
176
177static int src_put_rsc_ctrl_blk(void *blk)
178{
179 kfree(blk);
180
181 return 0;
182}
183
184static int src_set_state(void *blk, unsigned int state)
185{
186 struct src_rsc_ctrl_blk *ctl = blk;
187
188 set_field(&ctl->ctl, SRCCTL_STATE, state);
189 ctl->dirty.bf.ctl = 1;
190 return 0;
191}
192
193static int src_set_bm(void *blk, unsigned int bm)
194{
195 struct src_rsc_ctrl_blk *ctl = blk;
196
197 set_field(&ctl->ctl, SRCCTL_BM, bm);
198 ctl->dirty.bf.ctl = 1;
199 return 0;
200}
201
202static int src_set_rsr(void *blk, unsigned int rsr)
203{
204 struct src_rsc_ctrl_blk *ctl = blk;
205
206 set_field(&ctl->ctl, SRCCTL_RSR, rsr);
207 ctl->dirty.bf.ctl = 1;
208 return 0;
209}
210
211static int src_set_sf(void *blk, unsigned int sf)
212{
213 struct src_rsc_ctrl_blk *ctl = blk;
214
215 set_field(&ctl->ctl, SRCCTL_SF, sf);
216 ctl->dirty.bf.ctl = 1;
217 return 0;
218}
219
220static int src_set_wr(void *blk, unsigned int wr)
221{
222 struct src_rsc_ctrl_blk *ctl = blk;
223
224 set_field(&ctl->ctl, SRCCTL_WR, wr);
225 ctl->dirty.bf.ctl = 1;
226 return 0;
227}
228
229static int src_set_pm(void *blk, unsigned int pm)
230{
231 struct src_rsc_ctrl_blk *ctl = blk;
232
233 set_field(&ctl->ctl, SRCCTL_PM, pm);
234 ctl->dirty.bf.ctl = 1;
235 return 0;
236}
237
238static int src_set_rom(void *blk, unsigned int rom)
239{
240 struct src_rsc_ctrl_blk *ctl = blk;
241
242 set_field(&ctl->ctl, SRCCTL_ROM, rom);
243 ctl->dirty.bf.ctl = 1;
244 return 0;
245}
246
247static int src_set_vo(void *blk, unsigned int vo)
248{
249 struct src_rsc_ctrl_blk *ctl = blk;
250
251 set_field(&ctl->ctl, SRCCTL_VO, vo);
252 ctl->dirty.bf.ctl = 1;
253 return 0;
254}
255
256static int src_set_st(void *blk, unsigned int st)
257{
258 struct src_rsc_ctrl_blk *ctl = blk;
259
260 set_field(&ctl->ctl, SRCCTL_ST, st);
261 ctl->dirty.bf.ctl = 1;
262 return 0;
263}
264
265static int src_set_ie(void *blk, unsigned int ie)
266{
267 struct src_rsc_ctrl_blk *ctl = blk;
268
269 set_field(&ctl->ctl, SRCCTL_IE, ie);
270 ctl->dirty.bf.ctl = 1;
271 return 0;
272}
273
274static int src_set_ilsz(void *blk, unsigned int ilsz)
275{
276 struct src_rsc_ctrl_blk *ctl = blk;
277
278 set_field(&ctl->ctl, SRCCTL_ILSZ, ilsz);
279 ctl->dirty.bf.ctl = 1;
280 return 0;
281}
282
283static int src_set_bp(void *blk, unsigned int bp)
284{
285 struct src_rsc_ctrl_blk *ctl = blk;
286
287 set_field(&ctl->ctl, SRCCTL_BP, bp);
288 ctl->dirty.bf.ctl = 1;
289 return 0;
290}
291
292static int src_set_cisz(void *blk, unsigned int cisz)
293{
294 struct src_rsc_ctrl_blk *ctl = blk;
295
296 set_field(&ctl->ccr, SRCCCR_CISZ, cisz);
297 ctl->dirty.bf.ccr = 1;
298 return 0;
299}
300
301static int src_set_ca(void *blk, unsigned int ca)
302{
303 struct src_rsc_ctrl_blk *ctl = blk;
304
305 set_field(&ctl->ca, SRCCA_CA, ca);
306 ctl->dirty.bf.ca = 1;
307 return 0;
308}
309
310static int src_set_sa(void *blk, unsigned int sa)
311{
312 struct src_rsc_ctrl_blk *ctl = blk;
313
314 set_field(&ctl->sa, SRCSA_SA, sa);
315 ctl->dirty.bf.sa = 1;
316 return 0;
317}
318
319static int src_set_la(void *blk, unsigned int la)
320{
321 struct src_rsc_ctrl_blk *ctl = blk;
322
323 set_field(&ctl->la, SRCLA_LA, la);
324 ctl->dirty.bf.la = 1;
325 return 0;
326}
327
328static int src_set_pitch(void *blk, unsigned int pitch)
329{
330 struct src_rsc_ctrl_blk *ctl = blk;
331
332 set_field(&ctl->mpr, MPRLH_PITCH, pitch);
333 ctl->dirty.bf.mpr = 1;
334 return 0;
335}
336
337static int src_set_clear_zbufs(void *blk, unsigned int clear)
338{
339 ((struct src_rsc_ctrl_blk *)blk)->dirty.bf.czbfs = (clear ? 1 : 0);
340 return 0;
341}
342
343static int src_set_dirty(void *blk, unsigned int flags)
344{
345 ((struct src_rsc_ctrl_blk *)blk)->dirty.data = (flags & 0xffff);
346 return 0;
347}
348
349static int src_set_dirty_all(void *blk)
350{
351 ((struct src_rsc_ctrl_blk *)blk)->dirty.data = ~(0x0);
352 return 0;
353}
354
355#define AR_SLOT_SIZE 4096
356#define AR_SLOT_BLOCK_SIZE 16
357#define AR_PTS_PITCH 6
358#define AR_PARAM_SRC_OFFSET 0x60
359
360static unsigned int src_param_pitch_mixer(unsigned int src_idx)
361{
362 return ((src_idx << 4) + AR_PTS_PITCH + AR_SLOT_SIZE
363 - AR_PARAM_SRC_OFFSET) % AR_SLOT_SIZE;
364
365}
366
367static int src_commit_write(struct hw *hw, unsigned int idx, void *blk)
368{
369 struct src_rsc_ctrl_blk *ctl = blk;
370 int i;
371
372 if (ctl->dirty.bf.czbfs) {
373
374 for (i = 0; i < 8; i++)
375 hw_write_20kx(hw, SRC_UPZ+idx*0x100+i*0x4, 0);
376
377 for (i = 0; i < 4; i++)
378 hw_write_20kx(hw, SRC_DN0Z+idx*0x100+i*0x4, 0);
379
380 for (i = 0; i < 8; i++)
381 hw_write_20kx(hw, SRC_DN1Z+idx*0x100+i*0x4, 0);
382
383 ctl->dirty.bf.czbfs = 0;
384 }
385 if (ctl->dirty.bf.mpr) {
386
387
388
389
390 unsigned int pm_idx = src_param_pitch_mixer(idx);
391 hw_write_20kx(hw, MIXER_PRING_LO_HI+4*pm_idx, ctl->mpr);
392 hw_write_20kx(hw, MIXER_PMOPLO+8*pm_idx, 0x3);
393 hw_write_20kx(hw, MIXER_PMOPHI+8*pm_idx, 0x0);
394 ctl->dirty.bf.mpr = 0;
395 }
396 if (ctl->dirty.bf.sa) {
397 hw_write_20kx(hw, SRC_SA+idx*0x100, ctl->sa);
398 ctl->dirty.bf.sa = 0;
399 }
400 if (ctl->dirty.bf.la) {
401 hw_write_20kx(hw, SRC_LA+idx*0x100, ctl->la);
402 ctl->dirty.bf.la = 0;
403 }
404 if (ctl->dirty.bf.ca) {
405 hw_write_20kx(hw, SRC_CA+idx*0x100, ctl->ca);
406 ctl->dirty.bf.ca = 0;
407 }
408
409
410 hw_write_20kx(hw, SRC_CF+idx*0x100, 0x0);
411
412 if (ctl->dirty.bf.ccr) {
413 hw_write_20kx(hw, SRC_CCR+idx*0x100, ctl->ccr);
414 ctl->dirty.bf.ccr = 0;
415 }
416 if (ctl->dirty.bf.ctl) {
417 hw_write_20kx(hw, SRC_CTL+idx*0x100, ctl->ctl);
418 ctl->dirty.bf.ctl = 0;
419 }
420
421 return 0;
422}
423
424static int src_get_ca(struct hw *hw, unsigned int idx, void *blk)
425{
426 struct src_rsc_ctrl_blk *ctl = blk;
427
428 ctl->ca = hw_read_20kx(hw, SRC_CA+idx*0x100);
429 ctl->dirty.bf.ca = 0;
430
431 return get_field(ctl->ca, SRCCA_CA);
432}
433
434static unsigned int src_get_dirty(void *blk)
435{
436 return ((struct src_rsc_ctrl_blk *)blk)->dirty.data;
437}
438
439static unsigned int src_dirty_conj_mask(void)
440{
441 return 0x20;
442}
443
444static int src_mgr_enbs_src(void *blk, unsigned int idx)
445{
446 ((struct src_mgr_ctrl_blk *)blk)->enbsa |= (0x1 << ((idx%128)/4));
447 ((struct src_mgr_ctrl_blk *)blk)->dirty.bf.enbsa = 1;
448 ((struct src_mgr_ctrl_blk *)blk)->enb[idx/32] |= (0x1 << (idx%32));
449 return 0;
450}
451
452static int src_mgr_enb_src(void *blk, unsigned int idx)
453{
454 ((struct src_mgr_ctrl_blk *)blk)->enb[idx/32] |= (0x1 << (idx%32));
455 ((struct src_mgr_ctrl_blk *)blk)->dirty.data |= (0x1 << (idx/32));
456 return 0;
457}
458
459static int src_mgr_dsb_src(void *blk, unsigned int idx)
460{
461 ((struct src_mgr_ctrl_blk *)blk)->enb[idx/32] &= ~(0x1 << (idx%32));
462 ((struct src_mgr_ctrl_blk *)blk)->dirty.data |= (0x1 << (idx/32));
463 return 0;
464}
465
466static int src_mgr_commit_write(struct hw *hw, void *blk)
467{
468 struct src_mgr_ctrl_blk *ctl = blk;
469 int i;
470 unsigned int ret;
471
472 if (ctl->dirty.bf.enbsa) {
473 do {
474 ret = hw_read_20kx(hw, SRC_ENBSTAT);
475 } while (ret & 0x1);
476 hw_write_20kx(hw, SRC_ENBSA, ctl->enbsa);
477 ctl->dirty.bf.enbsa = 0;
478 }
479 for (i = 0; i < 8; i++) {
480 if ((ctl->dirty.data & (0x1 << i))) {
481 hw_write_20kx(hw, SRC_ENB+(i*0x100), ctl->enb[i]);
482 ctl->dirty.data &= ~(0x1 << i);
483 }
484 }
485
486 return 0;
487}
488
489static int src_mgr_get_ctrl_blk(void **rblk)
490{
491 struct src_mgr_ctrl_blk *blk;
492
493 *rblk = NULL;
494 blk = kzalloc(sizeof(*blk), GFP_KERNEL);
495 if (!blk)
496 return -ENOMEM;
497
498 *rblk = blk;
499
500 return 0;
501}
502
503static int src_mgr_put_ctrl_blk(void *blk)
504{
505 kfree(blk);
506
507 return 0;
508}
509
510static int srcimp_mgr_get_ctrl_blk(void **rblk)
511{
512 struct srcimp_mgr_ctrl_blk *blk;
513
514 *rblk = NULL;
515 blk = kzalloc(sizeof(*blk), GFP_KERNEL);
516 if (!blk)
517 return -ENOMEM;
518
519 *rblk = blk;
520
521 return 0;
522}
523
524static int srcimp_mgr_put_ctrl_blk(void *blk)
525{
526 kfree(blk);
527
528 return 0;
529}
530
531static int srcimp_mgr_set_imaparc(void *blk, unsigned int slot)
532{
533 struct srcimp_mgr_ctrl_blk *ctl = blk;
534
535 set_field(&ctl->srcimap.srcaim, SRCAIM_ARC, slot);
536 ctl->dirty.bf.srcimap = 1;
537 return 0;
538}
539
540static int srcimp_mgr_set_imapuser(void *blk, unsigned int user)
541{
542 struct srcimp_mgr_ctrl_blk *ctl = blk;
543
544 set_field(&ctl->srcimap.srcaim, SRCAIM_SRC, user);
545 ctl->dirty.bf.srcimap = 1;
546 return 0;
547}
548
549static int srcimp_mgr_set_imapnxt(void *blk, unsigned int next)
550{
551 struct srcimp_mgr_ctrl_blk *ctl = blk;
552
553 set_field(&ctl->srcimap.srcaim, SRCAIM_NXT, next);
554 ctl->dirty.bf.srcimap = 1;
555 return 0;
556}
557
558static int srcimp_mgr_set_imapaddr(void *blk, unsigned int addr)
559{
560 ((struct srcimp_mgr_ctrl_blk *)blk)->srcimap.idx = addr;
561 ((struct srcimp_mgr_ctrl_blk *)blk)->dirty.bf.srcimap = 1;
562 return 0;
563}
564
565static int srcimp_mgr_commit_write(struct hw *hw, void *blk)
566{
567 struct srcimp_mgr_ctrl_blk *ctl = blk;
568
569 if (ctl->dirty.bf.srcimap) {
570 hw_write_20kx(hw, SRC_IMAP+ctl->srcimap.idx*0x100,
571 ctl->srcimap.srcaim);
572 ctl->dirty.bf.srcimap = 0;
573 }
574
575 return 0;
576}
577
578
579
580
581
582#define AMOPLO_M 0x00000003
583#define AMOPLO_IV 0x00000004
584#define AMOPLO_X 0x0003FFF0
585#define AMOPLO_Y 0xFFFC0000
586
587#define AMOPHI_SADR 0x000000FF
588#define AMOPHI_SE 0x80000000
589
590
591union amixer_dirty {
592 struct {
593 u16 amoplo:1;
594 u16 amophi:1;
595 u16 rsv:14;
596 } bf;
597 u16 data;
598};
599
600
601struct amixer_rsc_ctrl_blk {
602 unsigned int amoplo;
603 unsigned int amophi;
604 union amixer_dirty dirty;
605};
606
607static int amixer_set_mode(void *blk, unsigned int mode)
608{
609 struct amixer_rsc_ctrl_blk *ctl = blk;
610
611 set_field(&ctl->amoplo, AMOPLO_M, mode);
612 ctl->dirty.bf.amoplo = 1;
613 return 0;
614}
615
616static int amixer_set_iv(void *blk, unsigned int iv)
617{
618 struct amixer_rsc_ctrl_blk *ctl = blk;
619
620 set_field(&ctl->amoplo, AMOPLO_IV, iv);
621 ctl->dirty.bf.amoplo = 1;
622 return 0;
623}
624
625static int amixer_set_x(void *blk, unsigned int x)
626{
627 struct amixer_rsc_ctrl_blk *ctl = blk;
628
629 set_field(&ctl->amoplo, AMOPLO_X, x);
630 ctl->dirty.bf.amoplo = 1;
631 return 0;
632}
633
634static int amixer_set_y(void *blk, unsigned int y)
635{
636 struct amixer_rsc_ctrl_blk *ctl = blk;
637
638 set_field(&ctl->amoplo, AMOPLO_Y, y);
639 ctl->dirty.bf.amoplo = 1;
640 return 0;
641}
642
643static int amixer_set_sadr(void *blk, unsigned int sadr)
644{
645 struct amixer_rsc_ctrl_blk *ctl = blk;
646
647 set_field(&ctl->amophi, AMOPHI_SADR, sadr);
648 ctl->dirty.bf.amophi = 1;
649 return 0;
650}
651
652static int amixer_set_se(void *blk, unsigned int se)
653{
654 struct amixer_rsc_ctrl_blk *ctl = blk;
655
656 set_field(&ctl->amophi, AMOPHI_SE, se);
657 ctl->dirty.bf.amophi = 1;
658 return 0;
659}
660
661static int amixer_set_dirty(void *blk, unsigned int flags)
662{
663 ((struct amixer_rsc_ctrl_blk *)blk)->dirty.data = (flags & 0xffff);
664 return 0;
665}
666
667static int amixer_set_dirty_all(void *blk)
668{
669 ((struct amixer_rsc_ctrl_blk *)blk)->dirty.data = ~(0x0);
670 return 0;
671}
672
673static int amixer_commit_write(struct hw *hw, unsigned int idx, void *blk)
674{
675 struct amixer_rsc_ctrl_blk *ctl = blk;
676
677 if (ctl->dirty.bf.amoplo || ctl->dirty.bf.amophi) {
678 hw_write_20kx(hw, MIXER_AMOPLO+idx*8, ctl->amoplo);
679 ctl->dirty.bf.amoplo = 0;
680 hw_write_20kx(hw, MIXER_AMOPHI+idx*8, ctl->amophi);
681 ctl->dirty.bf.amophi = 0;
682 }
683
684 return 0;
685}
686
687static int amixer_get_y(void *blk)
688{
689 struct amixer_rsc_ctrl_blk *ctl = blk;
690
691 return get_field(ctl->amoplo, AMOPLO_Y);
692}
693
694static unsigned int amixer_get_dirty(void *blk)
695{
696 return ((struct amixer_rsc_ctrl_blk *)blk)->dirty.data;
697}
698
699static int amixer_rsc_get_ctrl_blk(void **rblk)
700{
701 struct amixer_rsc_ctrl_blk *blk;
702
703 *rblk = NULL;
704 blk = kzalloc(sizeof(*blk), GFP_KERNEL);
705 if (!blk)
706 return -ENOMEM;
707
708 *rblk = blk;
709
710 return 0;
711}
712
713static int amixer_rsc_put_ctrl_blk(void *blk)
714{
715 kfree(blk);
716
717 return 0;
718}
719
720static int amixer_mgr_get_ctrl_blk(void **rblk)
721{
722 *rblk = NULL;
723
724 return 0;
725}
726
727static int amixer_mgr_put_ctrl_blk(void *blk)
728{
729 return 0;
730}
731
732
733
734
735
736
737#define SRTCTL_SRCO 0x000000FF
738#define SRTCTL_SRCM 0x0000FF00
739#define SRTCTL_RSR 0x00030000
740#define SRTCTL_DRAT 0x00300000
741#define SRTCTL_EC 0x01000000
742#define SRTCTL_ET 0x10000000
743
744
745union dai_dirty {
746 struct {
747 u16 srt:1;
748 u16 rsv:15;
749 } bf;
750 u16 data;
751};
752
753
754struct dai_ctrl_blk {
755 unsigned int srt;
756 union dai_dirty dirty;
757};
758
759
760#define AIM_ARC 0x00000FFF
761#define AIM_NXT 0x007F0000
762
763struct daoimap {
764 unsigned int aim;
765 unsigned int idx;
766};
767
768
769#define ATXCTL_EN 0x00000001
770#define ATXCTL_MODE 0x00000010
771#define ATXCTL_CD 0x00000020
772#define ATXCTL_RAW 0x00000100
773#define ATXCTL_MT 0x00000200
774#define ATXCTL_NUC 0x00003000
775#define ATXCTL_BEN 0x00010000
776#define ATXCTL_BMUX 0x00700000
777#define ATXCTL_B24 0x01000000
778#define ATXCTL_CPF 0x02000000
779#define ATXCTL_RIV 0x10000000
780#define ATXCTL_LIV 0x20000000
781#define ATXCTL_RSAT 0x40000000
782#define ATXCTL_LSAT 0x80000000
783
784
785union dao_dirty {
786 struct {
787 u16 atxcsl:1;
788 u16 rsv:15;
789 } bf;
790 u16 data;
791};
792
793
794struct dao_ctrl_blk {
795
796 unsigned int atxcsl;
797 union dao_dirty dirty;
798};
799
800
801#define ARXCTL_EN 0x00000001
802
803
804union daio_mgr_dirty {
805 struct {
806 u32 atxctl:8;
807 u32 arxctl:8;
808 u32 daoimap:1;
809 u32 rsv:15;
810 } bf;
811 u32 data;
812};
813
814
815struct daio_mgr_ctrl_blk {
816 struct daoimap daoimap;
817 unsigned int txctl[8];
818 unsigned int rxctl[8];
819 union daio_mgr_dirty dirty;
820};
821
822static int dai_srt_set_srco(void *blk, unsigned int src)
823{
824 struct dai_ctrl_blk *ctl = blk;
825
826 set_field(&ctl->srt, SRTCTL_SRCO, src);
827 ctl->dirty.bf.srt = 1;
828 return 0;
829}
830
831static int dai_srt_set_srcm(void *blk, unsigned int src)
832{
833 struct dai_ctrl_blk *ctl = blk;
834
835 set_field(&ctl->srt, SRTCTL_SRCM, src);
836 ctl->dirty.bf.srt = 1;
837 return 0;
838}
839
840static int dai_srt_set_rsr(void *blk, unsigned int rsr)
841{
842 struct dai_ctrl_blk *ctl = blk;
843
844 set_field(&ctl->srt, SRTCTL_RSR, rsr);
845 ctl->dirty.bf.srt = 1;
846 return 0;
847}
848
849static int dai_srt_set_drat(void *blk, unsigned int drat)
850{
851 struct dai_ctrl_blk *ctl = blk;
852
853 set_field(&ctl->srt, SRTCTL_DRAT, drat);
854 ctl->dirty.bf.srt = 1;
855 return 0;
856}
857
858static int dai_srt_set_ec(void *blk, unsigned int ec)
859{
860 struct dai_ctrl_blk *ctl = blk;
861
862 set_field(&ctl->srt, SRTCTL_EC, ec ? 1 : 0);
863 ctl->dirty.bf.srt = 1;
864 return 0;
865}
866
867static int dai_srt_set_et(void *blk, unsigned int et)
868{
869 struct dai_ctrl_blk *ctl = blk;
870
871 set_field(&ctl->srt, SRTCTL_ET, et ? 1 : 0);
872 ctl->dirty.bf.srt = 1;
873 return 0;
874}
875
876static int dai_commit_write(struct hw *hw, unsigned int idx, void *blk)
877{
878 struct dai_ctrl_blk *ctl = blk;
879
880 if (ctl->dirty.bf.srt) {
881 hw_write_20kx(hw, AUDIO_IO_RX_SRT_CTL+0x40*idx, ctl->srt);
882 ctl->dirty.bf.srt = 0;
883 }
884
885 return 0;
886}
887
888static int dai_get_ctrl_blk(void **rblk)
889{
890 struct dai_ctrl_blk *blk;
891
892 *rblk = NULL;
893 blk = kzalloc(sizeof(*blk), GFP_KERNEL);
894 if (!blk)
895 return -ENOMEM;
896
897 *rblk = blk;
898
899 return 0;
900}
901
902static int dai_put_ctrl_blk(void *blk)
903{
904 kfree(blk);
905
906 return 0;
907}
908
909static int dao_set_spos(void *blk, unsigned int spos)
910{
911 ((struct dao_ctrl_blk *)blk)->atxcsl = spos;
912 ((struct dao_ctrl_blk *)blk)->dirty.bf.atxcsl = 1;
913 return 0;
914}
915
916static int dao_commit_write(struct hw *hw, unsigned int idx, void *blk)
917{
918 struct dao_ctrl_blk *ctl = blk;
919
920 if (ctl->dirty.bf.atxcsl) {
921 if (idx < 4) {
922
923 hw_write_20kx(hw, AUDIO_IO_TX_CSTAT_L+0x40*idx,
924 ctl->atxcsl);
925 }
926 ctl->dirty.bf.atxcsl = 0;
927 }
928
929 return 0;
930}
931
932static int dao_get_spos(void *blk, unsigned int *spos)
933{
934 *spos = ((struct dao_ctrl_blk *)blk)->atxcsl;
935 return 0;
936}
937
938static int dao_get_ctrl_blk(void **rblk)
939{
940 struct dao_ctrl_blk *blk;
941
942 *rblk = NULL;
943 blk = kzalloc(sizeof(*blk), GFP_KERNEL);
944 if (!blk)
945 return -ENOMEM;
946
947 *rblk = blk;
948
949 return 0;
950}
951
952static int dao_put_ctrl_blk(void *blk)
953{
954 kfree(blk);
955
956 return 0;
957}
958
959static int daio_mgr_enb_dai(void *blk, unsigned int idx)
960{
961 struct daio_mgr_ctrl_blk *ctl = blk;
962
963 set_field(&ctl->rxctl[idx], ARXCTL_EN, 1);
964 ctl->dirty.bf.arxctl |= (0x1 << idx);
965 return 0;
966}
967
968static int daio_mgr_dsb_dai(void *blk, unsigned int idx)
969{
970 struct daio_mgr_ctrl_blk *ctl = blk;
971
972 set_field(&ctl->rxctl[idx], ARXCTL_EN, 0);
973
974 ctl->dirty.bf.arxctl |= (0x1 << idx);
975 return 0;
976}
977
978static int daio_mgr_enb_dao(void *blk, unsigned int idx)
979{
980 struct daio_mgr_ctrl_blk *ctl = blk;
981
982 set_field(&ctl->txctl[idx], ATXCTL_EN, 1);
983 ctl->dirty.bf.atxctl |= (0x1 << idx);
984 return 0;
985}
986
987static int daio_mgr_dsb_dao(void *blk, unsigned int idx)
988{
989 struct daio_mgr_ctrl_blk *ctl = blk;
990
991 set_field(&ctl->txctl[idx], ATXCTL_EN, 0);
992 ctl->dirty.bf.atxctl |= (0x1 << idx);
993 return 0;
994}
995
996static int daio_mgr_dao_init(void *blk, unsigned int idx, unsigned int conf)
997{
998 struct daio_mgr_ctrl_blk *ctl = blk;
999
1000 if (idx < 4) {
1001
1002 switch ((conf & 0x7)) {
1003 case 1:
1004 set_field(&ctl->txctl[idx], ATXCTL_NUC, 0);
1005 break;
1006 case 2:
1007 set_field(&ctl->txctl[idx], ATXCTL_NUC, 1);
1008 break;
1009 case 4:
1010 set_field(&ctl->txctl[idx], ATXCTL_NUC, 2);
1011 break;
1012 case 8:
1013 set_field(&ctl->txctl[idx], ATXCTL_NUC, 3);
1014 break;
1015 default:
1016 break;
1017 }
1018
1019 set_field(&ctl->txctl[idx], ATXCTL_CD, (!(conf & 0x7)));
1020
1021 set_field(&ctl->txctl[idx], ATXCTL_LIV, (conf >> 4) & 0x1);
1022
1023 set_field(&ctl->txctl[idx], ATXCTL_RIV, (conf >> 4) & 0x1);
1024 set_field(&ctl->txctl[idx], ATXCTL_RAW,
1025 ((conf >> 3) & 0x1) ? 0 : 0);
1026 ctl->dirty.bf.atxctl |= (0x1 << idx);
1027 } else {
1028
1029
1030 }
1031 return 0;
1032}
1033
1034static int daio_mgr_set_imaparc(void *blk, unsigned int slot)
1035{
1036 struct daio_mgr_ctrl_blk *ctl = blk;
1037
1038 set_field(&ctl->daoimap.aim, AIM_ARC, slot);
1039 ctl->dirty.bf.daoimap = 1;
1040 return 0;
1041}
1042
1043static int daio_mgr_set_imapnxt(void *blk, unsigned int next)
1044{
1045 struct daio_mgr_ctrl_blk *ctl = blk;
1046
1047 set_field(&ctl->daoimap.aim, AIM_NXT, next);
1048 ctl->dirty.bf.daoimap = 1;
1049 return 0;
1050}
1051
1052static int daio_mgr_set_imapaddr(void *blk, unsigned int addr)
1053{
1054 ((struct daio_mgr_ctrl_blk *)blk)->daoimap.idx = addr;
1055 ((struct daio_mgr_ctrl_blk *)blk)->dirty.bf.daoimap = 1;
1056 return 0;
1057}
1058
1059static int daio_mgr_commit_write(struct hw *hw, void *blk)
1060{
1061 struct daio_mgr_ctrl_blk *ctl = blk;
1062 unsigned int data;
1063 int i;
1064
1065 for (i = 0; i < 8; i++) {
1066 if ((ctl->dirty.bf.atxctl & (0x1 << i))) {
1067 data = ctl->txctl[i];
1068 hw_write_20kx(hw, (AUDIO_IO_TX_CTL+(0x40*i)), data);
1069 ctl->dirty.bf.atxctl &= ~(0x1 << i);
1070 mdelay(1);
1071 }
1072 if ((ctl->dirty.bf.arxctl & (0x1 << i))) {
1073 data = ctl->rxctl[i];
1074 hw_write_20kx(hw, (AUDIO_IO_RX_CTL+(0x40*i)), data);
1075 ctl->dirty.bf.arxctl &= ~(0x1 << i);
1076 mdelay(1);
1077 }
1078 }
1079 if (ctl->dirty.bf.daoimap) {
1080 hw_write_20kx(hw, AUDIO_IO_AIM+ctl->daoimap.idx*4,
1081 ctl->daoimap.aim);
1082 ctl->dirty.bf.daoimap = 0;
1083 }
1084
1085 return 0;
1086}
1087
1088static int daio_mgr_get_ctrl_blk(struct hw *hw, void **rblk)
1089{
1090 struct daio_mgr_ctrl_blk *blk;
1091 int i;
1092
1093 *rblk = NULL;
1094 blk = kzalloc(sizeof(*blk), GFP_KERNEL);
1095 if (!blk)
1096 return -ENOMEM;
1097
1098 for (i = 0; i < 8; i++) {
1099 blk->txctl[i] = hw_read_20kx(hw, AUDIO_IO_TX_CTL+(0x40*i));
1100 blk->rxctl[i] = hw_read_20kx(hw, AUDIO_IO_RX_CTL+(0x40*i));
1101 }
1102
1103 *rblk = blk;
1104
1105 return 0;
1106}
1107
1108static int daio_mgr_put_ctrl_blk(void *blk)
1109{
1110 kfree(blk);
1111
1112 return 0;
1113}
1114
1115
1116static int set_timer_irq(struct hw *hw, int enable)
1117{
1118 hw_write_20kx(hw, GIE, enable ? IT_INT : 0);
1119 return 0;
1120}
1121
1122static int set_timer_tick(struct hw *hw, unsigned int ticks)
1123{
1124 if (ticks)
1125 ticks |= TIMR_IE | TIMR_IP;
1126 hw_write_20kx(hw, TIMR, ticks);
1127 return 0;
1128}
1129
1130static unsigned int get_wc(struct hw *hw)
1131{
1132 return hw_read_20kx(hw, WC);
1133}
1134
1135
1136struct dac_conf {
1137 unsigned int msr;
1138};
1139
1140struct adc_conf {
1141 unsigned int msr;
1142 unsigned char input;
1143 unsigned char mic20db;
1144};
1145
1146struct daio_conf {
1147 unsigned int msr;
1148};
1149
1150struct trn_conf {
1151 unsigned long vm_pgt_phys;
1152};
1153
1154static int hw_daio_init(struct hw *hw, const struct daio_conf *info)
1155{
1156 u32 data;
1157 int i;
1158
1159
1160
1161 if (1 == info->msr) {
1162 hw_write_20kx(hw, AUDIO_IO_MCLK, 0x01010101);
1163 hw_write_20kx(hw, AUDIO_IO_TX_BLRCLK, 0x01010101);
1164 hw_write_20kx(hw, AUDIO_IO_RX_BLRCLK, 0);
1165 } else if (2 == info->msr) {
1166 hw_write_20kx(hw, AUDIO_IO_MCLK, 0x11111111);
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176 hw_write_20kx(hw, AUDIO_IO_TX_BLRCLK, 0x11111111);
1177 hw_write_20kx(hw, AUDIO_IO_RX_BLRCLK, 0);
1178 } else {
1179 printk(KERN_ALERT "ctxfi: ERROR!!! Invalid sampling rate!!!\n");
1180 return -EINVAL;
1181 }
1182
1183 for (i = 0; i < 8; i++) {
1184 if (i <= 3) {
1185
1186 if (i == 3)
1187 data = 0x1001001;
1188 else
1189 data = 0x1000001;
1190
1191 hw_write_20kx(hw, (AUDIO_IO_TX_CTL+(0x40*i)), data);
1192 hw_write_20kx(hw, (AUDIO_IO_RX_CTL+(0x40*i)), data);
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204 hw_write_20kx(hw, AUDIO_IO_TX_CSTAT_L+(0x40*i),
1205 0x02109204);
1206
1207 hw_write_20kx(hw, AUDIO_IO_TX_CSTAT_H+(0x40*i), 0x0B);
1208 } else {
1209
1210 data = 0x11;
1211 hw_write_20kx(hw, AUDIO_IO_RX_CTL+(0x40*i), data);
1212 if (2 == info->msr) {
1213
1214 data |= 0x1000;
1215 }
1216 hw_write_20kx(hw, AUDIO_IO_TX_CTL+(0x40*i), data);
1217 }
1218 }
1219
1220 return 0;
1221}
1222
1223
1224static int hw_trn_init(struct hw *hw, const struct trn_conf *info)
1225{
1226 u32 vmctl, data;
1227 u32 ptp_phys_low, ptp_phys_high;
1228 int i;
1229
1230
1231 if ((~0UL) == info->vm_pgt_phys) {
1232 printk(KERN_ALERT "ctxfi: "
1233 "Wrong device page table page address!!!\n");
1234 return -1;
1235 }
1236
1237 vmctl = 0x80000C0F;
1238 ptp_phys_low = (u32)info->vm_pgt_phys;
1239 ptp_phys_high = upper_32_bits(info->vm_pgt_phys);
1240 if (sizeof(void *) == 8)
1241 vmctl |= (3 << 8);
1242
1243 for (i = 0; i < 64; i++) {
1244 hw_write_20kx(hw, VMEM_PTPAL+(16*i), ptp_phys_low);
1245 hw_write_20kx(hw, VMEM_PTPAH+(16*i), ptp_phys_high);
1246 }
1247
1248 hw_write_20kx(hw, VMEM_CTL, vmctl);
1249
1250 hw_write_20kx(hw, TRANSPORT_CTL, 0x03);
1251 hw_write_20kx(hw, TRANSPORT_INT, 0x200c01);
1252
1253 data = hw_read_20kx(hw, TRANSPORT_ENB);
1254 hw_write_20kx(hw, TRANSPORT_ENB, (data | 0x03));
1255
1256 return 0;
1257}
1258
1259
1260#define GCTL_AIE 0x00000001
1261#define GCTL_UAA 0x00000002
1262#define GCTL_DPC 0x00000004
1263#define GCTL_DBP 0x00000008
1264#define GCTL_ABP 0x00000010
1265#define GCTL_TBP 0x00000020
1266#define GCTL_SBP 0x00000040
1267#define GCTL_FBP 0x00000080
1268#define GCTL_ME 0x00000100
1269#define GCTL_AID 0x00001000
1270
1271#define PLLCTL_SRC 0x00000007
1272#define PLLCTL_SPE 0x00000008
1273#define PLLCTL_RD 0x000000F0
1274#define PLLCTL_FD 0x0001FF00
1275#define PLLCTL_OD 0x00060000
1276#define PLLCTL_B 0x00080000
1277#define PLLCTL_AS 0x00100000
1278#define PLLCTL_LF 0x03E00000
1279#define PLLCTL_SPS 0x1C000000
1280#define PLLCTL_AD 0x60000000
1281
1282#define PLLSTAT_CCS 0x00000007
1283#define PLLSTAT_SPL 0x00000008
1284#define PLLSTAT_CRD 0x000000F0
1285#define PLLSTAT_CFD 0x0001FF00
1286#define PLLSTAT_SL 0x00020000
1287#define PLLSTAT_FAS 0x00040000
1288#define PLLSTAT_B 0x00080000
1289#define PLLSTAT_PD 0x00100000
1290#define PLLSTAT_OCA 0x00200000
1291#define PLLSTAT_NCA 0x00400000
1292
1293static int hw_pll_init(struct hw *hw, unsigned int rsr)
1294{
1295 unsigned int pllenb;
1296 unsigned int pllctl;
1297 unsigned int pllstat;
1298 int i;
1299
1300 pllenb = 0xB;
1301 hw_write_20kx(hw, PLL_ENB, pllenb);
1302 pllctl = 0x20D00000;
1303 set_field(&pllctl, PLLCTL_FD, 16 - 4);
1304 hw_write_20kx(hw, PLL_CTL, pllctl);
1305 mdelay(40);
1306 pllctl = hw_read_20kx(hw, PLL_CTL);
1307 set_field(&pllctl, PLLCTL_B, 0);
1308 if (48000 == rsr) {
1309 set_field(&pllctl, PLLCTL_FD, 16 - 2);
1310 set_field(&pllctl, PLLCTL_RD, 1 - 1);
1311 } else {
1312 set_field(&pllctl, PLLCTL_FD, 147 - 2);
1313 set_field(&pllctl, PLLCTL_RD, 10 - 1);
1314 }
1315 hw_write_20kx(hw, PLL_CTL, pllctl);
1316 mdelay(40);
1317 for (i = 0; i < 1000; i++) {
1318 pllstat = hw_read_20kx(hw, PLL_STAT);
1319 if (get_field(pllstat, PLLSTAT_PD))
1320 continue;
1321
1322 if (get_field(pllstat, PLLSTAT_B) !=
1323 get_field(pllctl, PLLCTL_B))
1324 continue;
1325
1326 if (get_field(pllstat, PLLSTAT_CCS) !=
1327 get_field(pllctl, PLLCTL_SRC))
1328 continue;
1329
1330 if (get_field(pllstat, PLLSTAT_CRD) !=
1331 get_field(pllctl, PLLCTL_RD))
1332 continue;
1333
1334 if (get_field(pllstat, PLLSTAT_CFD) !=
1335 get_field(pllctl, PLLCTL_FD))
1336 continue;
1337
1338 break;
1339 }
1340 if (i >= 1000) {
1341 printk(KERN_ALERT "ctxfi: PLL initialization failed!!!\n");
1342 return -EBUSY;
1343 }
1344
1345 return 0;
1346}
1347
1348static int hw_auto_init(struct hw *hw)
1349{
1350 unsigned int gctl;
1351 int i;
1352
1353 gctl = hw_read_20kx(hw, GLOBAL_CNTL_GCTL);
1354 set_field(&gctl, GCTL_AIE, 0);
1355 hw_write_20kx(hw, GLOBAL_CNTL_GCTL, gctl);
1356 set_field(&gctl, GCTL_AIE, 1);
1357 hw_write_20kx(hw, GLOBAL_CNTL_GCTL, gctl);
1358 mdelay(10);
1359 for (i = 0; i < 400000; i++) {
1360 gctl = hw_read_20kx(hw, GLOBAL_CNTL_GCTL);
1361 if (get_field(gctl, GCTL_AID))
1362 break;
1363 }
1364 if (!get_field(gctl, GCTL_AID)) {
1365 printk(KERN_ALERT "ctxfi: Card Auto-init failed!!!\n");
1366 return -EBUSY;
1367 }
1368
1369 return 0;
1370}
1371
1372
1373
1374#define CS4382_MC1 0x1
1375#define CS4382_MC2 0x2
1376#define CS4382_MC3 0x3
1377#define CS4382_FC 0x4
1378#define CS4382_IC 0x5
1379#define CS4382_XC1 0x6
1380#define CS4382_VCA1 0x7
1381#define CS4382_VCB1 0x8
1382#define CS4382_XC2 0x9
1383#define CS4382_VCA2 0xA
1384#define CS4382_VCB2 0xB
1385#define CS4382_XC3 0xC
1386#define CS4382_VCA3 0xD
1387#define CS4382_VCB3 0xE
1388#define CS4382_XC4 0xF
1389#define CS4382_VCA4 0x10
1390#define CS4382_VCB4 0x11
1391#define CS4382_CREV 0x12
1392
1393
1394#define STATE_LOCKED 0x00
1395#define STATE_UNLOCKED 0xAA
1396#define DATA_READY 0x800000
1397#define DATA_ABORT 0x10000
1398
1399#define I2C_STATUS_DCM 0x00000001
1400#define I2C_STATUS_BC 0x00000006
1401#define I2C_STATUS_APD 0x00000008
1402#define I2C_STATUS_AB 0x00010000
1403#define I2C_STATUS_DR 0x00800000
1404
1405#define I2C_ADDRESS_PTAD 0x0000FFFF
1406#define I2C_ADDRESS_SLAD 0x007F0000
1407
1408struct regs_cs4382 {
1409 u32 mode_control_1;
1410 u32 mode_control_2;
1411 u32 mode_control_3;
1412
1413 u32 filter_control;
1414 u32 invert_control;
1415
1416 u32 mix_control_P1;
1417 u32 vol_control_A1;
1418 u32 vol_control_B1;
1419
1420 u32 mix_control_P2;
1421 u32 vol_control_A2;
1422 u32 vol_control_B2;
1423
1424 u32 mix_control_P3;
1425 u32 vol_control_A3;
1426 u32 vol_control_B3;
1427
1428 u32 mix_control_P4;
1429 u32 vol_control_A4;
1430 u32 vol_control_B4;
1431};
1432
1433static int hw20k2_i2c_unlock_full_access(struct hw *hw)
1434{
1435 u8 UnlockKeySequence_FLASH_FULLACCESS_MODE[2] = {0xB3, 0xD4};
1436
1437
1438 hw_write_20kx(hw, I2C_IF_WLOCK,
1439 UnlockKeySequence_FLASH_FULLACCESS_MODE[0]);
1440 hw_write_20kx(hw, I2C_IF_WLOCK,
1441 UnlockKeySequence_FLASH_FULLACCESS_MODE[1]);
1442
1443 if (hw_read_20kx(hw, I2C_IF_WLOCK) == STATE_UNLOCKED)
1444 return 0;
1445
1446 return -1;
1447}
1448
1449static int hw20k2_i2c_lock_chip(struct hw *hw)
1450{
1451
1452 hw_write_20kx(hw, I2C_IF_WLOCK, STATE_LOCKED);
1453 hw_write_20kx(hw, I2C_IF_WLOCK, STATE_LOCKED);
1454 if (hw_read_20kx(hw, I2C_IF_WLOCK) == STATE_LOCKED)
1455 return 0;
1456
1457 return -1;
1458}
1459
1460static int hw20k2_i2c_init(struct hw *hw, u8 dev_id, u8 addr_size, u8 data_size)
1461{
1462 struct hw20k2 *hw20k2 = (struct hw20k2 *)hw;
1463 int err;
1464 unsigned int i2c_status;
1465 unsigned int i2c_addr;
1466
1467 err = hw20k2_i2c_unlock_full_access(hw);
1468 if (err < 0)
1469 return err;
1470
1471 hw20k2->addr_size = addr_size;
1472 hw20k2->data_size = data_size;
1473 hw20k2->dev_id = dev_id;
1474
1475 i2c_addr = 0;
1476 set_field(&i2c_addr, I2C_ADDRESS_SLAD, dev_id);
1477
1478 hw_write_20kx(hw, I2C_IF_ADDRESS, i2c_addr);
1479
1480 i2c_status = hw_read_20kx(hw, I2C_IF_STATUS);
1481
1482 set_field(&i2c_status, I2C_STATUS_DCM, 1);
1483
1484 hw_write_20kx(hw, I2C_IF_STATUS, i2c_status);
1485
1486 return 0;
1487}
1488
1489static int hw20k2_i2c_uninit(struct hw *hw)
1490{
1491 unsigned int i2c_status;
1492 unsigned int i2c_addr;
1493
1494 i2c_addr = 0;
1495 set_field(&i2c_addr, I2C_ADDRESS_SLAD, 0x57);
1496
1497 hw_write_20kx(hw, I2C_IF_ADDRESS, i2c_addr);
1498
1499 i2c_status = hw_read_20kx(hw, I2C_IF_STATUS);
1500
1501 set_field(&i2c_status, I2C_STATUS_DCM, 0);
1502
1503 hw_write_20kx(hw, I2C_IF_STATUS, i2c_status);
1504
1505 return hw20k2_i2c_lock_chip(hw);
1506}
1507
1508static int hw20k2_i2c_wait_data_ready(struct hw *hw)
1509{
1510 int i = 0x400000;
1511 unsigned int ret;
1512
1513 do {
1514 ret = hw_read_20kx(hw, I2C_IF_STATUS);
1515 } while ((!(ret & DATA_READY)) && --i);
1516
1517 return i;
1518}
1519
1520static int hw20k2_i2c_read(struct hw *hw, u16 addr, u32 *datap)
1521{
1522 struct hw20k2 *hw20k2 = (struct hw20k2 *)hw;
1523 unsigned int i2c_status;
1524
1525 i2c_status = hw_read_20kx(hw, I2C_IF_STATUS);
1526 set_field(&i2c_status, I2C_STATUS_BC,
1527 (4 == hw20k2->addr_size) ? 0 : hw20k2->addr_size);
1528 hw_write_20kx(hw, I2C_IF_STATUS, i2c_status);
1529 if (!hw20k2_i2c_wait_data_ready(hw))
1530 return -1;
1531
1532 hw_write_20kx(hw, I2C_IF_WDATA, addr);
1533 if (!hw20k2_i2c_wait_data_ready(hw))
1534 return -1;
1535
1536
1537 hw_write_20kx(hw, I2C_IF_RDATA, 0);
1538 if (!hw20k2_i2c_wait_data_ready(hw))
1539 return -1;
1540
1541 *datap = hw_read_20kx(hw, I2C_IF_RDATA);
1542
1543 return 0;
1544}
1545
1546static int hw20k2_i2c_write(struct hw *hw, u16 addr, u32 data)
1547{
1548 struct hw20k2 *hw20k2 = (struct hw20k2 *)hw;
1549 unsigned int i2c_data = (data << (hw20k2->addr_size * 8)) | addr;
1550 unsigned int i2c_status;
1551
1552 i2c_status = hw_read_20kx(hw, I2C_IF_STATUS);
1553
1554 set_field(&i2c_status, I2C_STATUS_BC,
1555 (4 == (hw20k2->addr_size + hw20k2->data_size)) ?
1556 0 : (hw20k2->addr_size + hw20k2->data_size));
1557
1558 hw_write_20kx(hw, I2C_IF_STATUS, i2c_status);
1559 hw20k2_i2c_wait_data_ready(hw);
1560
1561 hw_write_20kx(hw, I2C_IF_WDATA, 0);
1562 hw20k2_i2c_wait_data_ready(hw);
1563
1564
1565 hw_write_20kx(hw, I2C_IF_WDATA, i2c_data);
1566 hw20k2_i2c_wait_data_ready(hw);
1567
1568 return 0;
1569}
1570
1571static int hw_dac_init(struct hw *hw, const struct dac_conf *info)
1572{
1573 int err;
1574 u32 data;
1575 int i;
1576 struct regs_cs4382 cs_read = {0};
1577 struct regs_cs4382 cs_def = {
1578 0x00000001,
1579 0x00000000,
1580 0x00000084,
1581 0x00000000,
1582 0x00000000,
1583 0x00000024,
1584 0x00000000,
1585 0x00000000,
1586 0x00000024,
1587 0x00000000,
1588 0x00000000,
1589 0x00000024,
1590 0x00000000,
1591 0x00000000,
1592 0x00000024,
1593 0x00000000,
1594 0x00000000
1595 };
1596
1597
1598 data = hw_read_20kx(hw, GPIO_CTRL);
1599 data |= 0x02;
1600 hw_write_20kx(hw, GPIO_CTRL, data);
1601
1602 err = hw20k2_i2c_init(hw, 0x18, 1, 1);
1603 if (err < 0)
1604 goto End;
1605
1606 for (i = 0; i < 2; i++) {
1607
1608
1609 data = hw_read_20kx(hw, GPIO_DATA);
1610
1611 data &= 0xFFFFFFFD;
1612 hw_write_20kx(hw, GPIO_DATA, data);
1613 mdelay(10);
1614 data |= 0x2;
1615 hw_write_20kx(hw, GPIO_DATA, data);
1616 mdelay(50);
1617
1618
1619 data &= 0xFFFFFFFD;
1620 hw_write_20kx(hw, GPIO_DATA, data);
1621 mdelay(10);
1622 data |= 0x2;
1623 hw_write_20kx(hw, GPIO_DATA, data);
1624 mdelay(50);
1625
1626 if (hw20k2_i2c_read(hw, CS4382_MC1, &cs_read.mode_control_1))
1627 continue;
1628
1629 if (hw20k2_i2c_read(hw, CS4382_MC2, &cs_read.mode_control_2))
1630 continue;
1631
1632 if (hw20k2_i2c_read(hw, CS4382_MC3, &cs_read.mode_control_3))
1633 continue;
1634
1635 if (hw20k2_i2c_read(hw, CS4382_FC, &cs_read.filter_control))
1636 continue;
1637
1638 if (hw20k2_i2c_read(hw, CS4382_IC, &cs_read.invert_control))
1639 continue;
1640
1641 if (hw20k2_i2c_read(hw, CS4382_XC1, &cs_read.mix_control_P1))
1642 continue;
1643
1644 if (hw20k2_i2c_read(hw, CS4382_VCA1, &cs_read.vol_control_A1))
1645 continue;
1646
1647 if (hw20k2_i2c_read(hw, CS4382_VCB1, &cs_read.vol_control_B1))
1648 continue;
1649
1650 if (hw20k2_i2c_read(hw, CS4382_XC2, &cs_read.mix_control_P2))
1651 continue;
1652
1653 if (hw20k2_i2c_read(hw, CS4382_VCA2, &cs_read.vol_control_A2))
1654 continue;
1655
1656 if (hw20k2_i2c_read(hw, CS4382_VCB2, &cs_read.vol_control_B2))
1657 continue;
1658
1659 if (hw20k2_i2c_read(hw, CS4382_XC3, &cs_read.mix_control_P3))
1660 continue;
1661
1662 if (hw20k2_i2c_read(hw, CS4382_VCA3, &cs_read.vol_control_A3))
1663 continue;
1664
1665 if (hw20k2_i2c_read(hw, CS4382_VCB3, &cs_read.vol_control_B3))
1666 continue;
1667
1668 if (hw20k2_i2c_read(hw, CS4382_XC4, &cs_read.mix_control_P4))
1669 continue;
1670
1671 if (hw20k2_i2c_read(hw, CS4382_VCA4, &cs_read.vol_control_A4))
1672 continue;
1673
1674 if (hw20k2_i2c_read(hw, CS4382_VCB4, &cs_read.vol_control_B4))
1675 continue;
1676
1677 if (memcmp(&cs_read, &cs_def, sizeof(cs_read)))
1678 continue;
1679 else
1680 break;
1681 }
1682
1683 if (i >= 2)
1684 goto End;
1685
1686
1687
1688 hw20k2_i2c_write(hw, CS4382_MC1, 0x80);
1689 hw20k2_i2c_write(hw, CS4382_MC2, 0x10);
1690 if (1 == info->msr) {
1691 hw20k2_i2c_write(hw, CS4382_XC1, 0x24);
1692 hw20k2_i2c_write(hw, CS4382_XC2, 0x24);
1693 hw20k2_i2c_write(hw, CS4382_XC3, 0x24);
1694 hw20k2_i2c_write(hw, CS4382_XC4, 0x24);
1695 } else if (2 == info->msr) {
1696 hw20k2_i2c_write(hw, CS4382_XC1, 0x25);
1697 hw20k2_i2c_write(hw, CS4382_XC2, 0x25);
1698 hw20k2_i2c_write(hw, CS4382_XC3, 0x25);
1699 hw20k2_i2c_write(hw, CS4382_XC4, 0x25);
1700 } else {
1701 hw20k2_i2c_write(hw, CS4382_XC1, 0x26);
1702 hw20k2_i2c_write(hw, CS4382_XC2, 0x26);
1703 hw20k2_i2c_write(hw, CS4382_XC3, 0x26);
1704 hw20k2_i2c_write(hw, CS4382_XC4, 0x26);
1705 }
1706
1707 return 0;
1708End:
1709
1710 hw20k2_i2c_uninit(hw);
1711 return -1;
1712}
1713
1714
1715#define MAKE_WM8775_ADDR(addr, data) (u32)(((addr<<1)&0xFE)|((data>>8)&0x1))
1716#define MAKE_WM8775_DATA(data) (u32)(data&0xFF)
1717
1718#define WM8775_IC 0x0B
1719#define WM8775_MMC 0x0C
1720#define WM8775_AADCL 0x0E
1721#define WM8775_AADCR 0x0F
1722#define WM8775_ADCMC 0x15
1723#define WM8775_RESET 0x17
1724
1725static int hw_is_adc_input_selected(struct hw *hw, enum ADCSRC type)
1726{
1727 u32 data;
1728
1729 data = hw_read_20kx(hw, GPIO_DATA);
1730 switch (type) {
1731 case ADC_MICIN:
1732 data = (data & (0x1 << 14)) ? 1 : 0;
1733 break;
1734 case ADC_LINEIN:
1735 data = (data & (0x1 << 14)) ? 0 : 1;
1736 break;
1737 default:
1738 data = 0;
1739 }
1740 return data;
1741}
1742
1743#define MIC_BOOST_0DB 0xCF
1744#define MIC_BOOST_STEPS_PER_DB 2
1745#define MIC_BOOST_20DB (MIC_BOOST_0DB + 20 * MIC_BOOST_STEPS_PER_DB)
1746
1747static int hw_adc_input_select(struct hw *hw, enum ADCSRC type)
1748{
1749 u32 data;
1750
1751 data = hw_read_20kx(hw, GPIO_DATA);
1752 switch (type) {
1753 case ADC_MICIN:
1754 data |= (0x1 << 14);
1755 hw_write_20kx(hw, GPIO_DATA, data);
1756 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_ADCMC, 0x101),
1757 MAKE_WM8775_DATA(0x101));
1758 hw20k2_i2c_write(hw,
1759 MAKE_WM8775_ADDR(WM8775_AADCL, MIC_BOOST_20DB),
1760 MAKE_WM8775_DATA(MIC_BOOST_20DB));
1761 hw20k2_i2c_write(hw,
1762 MAKE_WM8775_ADDR(WM8775_AADCR, MIC_BOOST_20DB),
1763 MAKE_WM8775_DATA(MIC_BOOST_20DB));
1764 break;
1765 case ADC_LINEIN:
1766 data &= ~(0x1 << 14);
1767 hw_write_20kx(hw, GPIO_DATA, data);
1768 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_ADCMC, 0x102),
1769 MAKE_WM8775_DATA(0x102));
1770 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCL, 0xCF),
1771 MAKE_WM8775_DATA(0xCF));
1772 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCR, 0xCF),
1773 MAKE_WM8775_DATA(0xCF));
1774 break;
1775 default:
1776 break;
1777 }
1778
1779 return 0;
1780}
1781
1782static int hw_adc_init(struct hw *hw, const struct adc_conf *info)
1783{
1784 int err;
1785 u32 mux = 2, data, ctl;
1786
1787
1788 data = hw_read_20kx(hw, GPIO_CTRL);
1789 data |= (0x1 << 15);
1790 hw_write_20kx(hw, GPIO_CTRL, data);
1791
1792
1793 err = hw20k2_i2c_init(hw, 0x1A, 1, 1);
1794 if (err < 0) {
1795 printk(KERN_ALERT "ctxfi: Failure to acquire I2C!!!\n");
1796 goto error;
1797 }
1798
1799
1800 data = hw_read_20kx(hw, GPIO_DATA);
1801 data &= ~(0x1 << 15);
1802 mdelay(10);
1803 data |= (0x1 << 15);
1804 hw_write_20kx(hw, GPIO_DATA, data);
1805 mdelay(50);
1806
1807
1808 if (1 == info->msr) {
1809 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_MMC, 0x02),
1810 MAKE_WM8775_DATA(0x02));
1811 } else if (2 == info->msr) {
1812 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_MMC, 0x0A),
1813 MAKE_WM8775_DATA(0x0A));
1814 } else {
1815 printk(KERN_ALERT "ctxfi: Invalid master sampling "
1816 "rate (msr %d)!!!\n", info->msr);
1817 err = -EINVAL;
1818 goto error;
1819 }
1820
1821
1822 ctl = hw_read_20kx(hw, GPIO_CTRL);
1823 ctl |= 0x1 << 14;
1824 hw_write_20kx(hw, GPIO_CTRL, ctl);
1825
1826
1827 data = hw_read_20kx(hw, GPIO_DATA);
1828
1829 if (mux == 1) {
1830
1831 data |= 0x1 << 14;
1832 hw_write_20kx(hw, GPIO_DATA, data);
1833
1834 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_ADCMC, 0x101),
1835 MAKE_WM8775_DATA(0x101));
1836 hw20k2_i2c_write(hw,
1837 MAKE_WM8775_ADDR(WM8775_AADCL, MIC_BOOST_20DB),
1838 MAKE_WM8775_DATA(MIC_BOOST_20DB));
1839 hw20k2_i2c_write(hw,
1840 MAKE_WM8775_ADDR(WM8775_AADCR, MIC_BOOST_20DB),
1841 MAKE_WM8775_DATA(MIC_BOOST_20DB));
1842 } else if (mux == 2) {
1843
1844 data &= ~(0x1 << 14);
1845 hw_write_20kx(hw, GPIO_DATA, data);
1846
1847
1848 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_ADCMC, 0x102),
1849 MAKE_WM8775_DATA(0x102));
1850 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCL, 0xCF),
1851 MAKE_WM8775_DATA(0xCF));
1852 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCR, 0xCF),
1853 MAKE_WM8775_DATA(0xCF));
1854 } else {
1855 printk(KERN_ALERT "ctxfi: ERROR!!! Invalid input mux!!!\n");
1856 err = -EINVAL;
1857 goto error;
1858 }
1859
1860 return 0;
1861
1862error:
1863 hw20k2_i2c_uninit(hw);
1864 return err;
1865}
1866
1867static int hw_have_digit_io_switch(struct hw *hw)
1868{
1869 return 0;
1870}
1871
1872static irqreturn_t ct_20k2_interrupt(int irq, void *dev_id)
1873{
1874 struct hw *hw = dev_id;
1875 unsigned int status;
1876
1877 status = hw_read_20kx(hw, GIP);
1878 if (!status)
1879 return IRQ_NONE;
1880
1881 if (hw->irq_callback)
1882 hw->irq_callback(hw->irq_callback_data, status);
1883
1884 hw_write_20kx(hw, GIP, status);
1885 return IRQ_HANDLED;
1886}
1887
1888static int hw_card_start(struct hw *hw)
1889{
1890 int err = 0;
1891 struct pci_dev *pci = hw->pci;
1892 unsigned int gctl;
1893
1894 err = pci_enable_device(pci);
1895 if (err < 0)
1896 return err;
1897
1898
1899 if (pci_set_dma_mask(pci, CT_XFI_DMA_MASK) < 0 ||
1900 pci_set_consistent_dma_mask(pci, CT_XFI_DMA_MASK) < 0) {
1901 printk(KERN_ERR "ctxfi: architecture does not support PCI "
1902 "busmaster DMA with mask 0x%llx\n", CT_XFI_DMA_MASK);
1903 err = -ENXIO;
1904 goto error1;
1905 }
1906
1907 if (!hw->io_base) {
1908 err = pci_request_regions(pci, "XFi");
1909 if (err < 0)
1910 goto error1;
1911
1912 hw->io_base = pci_resource_start(hw->pci, 2);
1913 hw->mem_base = (unsigned long)ioremap(hw->io_base,
1914 pci_resource_len(hw->pci, 2));
1915 if (!hw->mem_base) {
1916 err = -ENOENT;
1917 goto error2;
1918 }
1919 }
1920
1921
1922 gctl = hw_read_20kx(hw, GLOBAL_CNTL_GCTL);
1923 set_field(&gctl, GCTL_UAA, 0);
1924 hw_write_20kx(hw, GLOBAL_CNTL_GCTL, gctl);
1925
1926 if (hw->irq < 0) {
1927 err = request_irq(pci->irq, ct_20k2_interrupt, IRQF_SHARED,
1928 "ctxfi", hw);
1929 if (err < 0) {
1930 printk(KERN_ERR "XFi: Cannot get irq %d\n", pci->irq);
1931 goto error2;
1932 }
1933 hw->irq = pci->irq;
1934 }
1935
1936 pci_set_master(pci);
1937
1938 return 0;
1939
1940
1941
1942
1943error2:
1944 pci_release_regions(pci);
1945 hw->io_base = 0;
1946error1:
1947 pci_disable_device(pci);
1948 return err;
1949}
1950
1951static int hw_card_stop(struct hw *hw)
1952{
1953 unsigned int data;
1954
1955
1956 hw_write_20kx(hw, TRANSPORT_CTL, 0x00);
1957
1958
1959 data = hw_read_20kx(hw, PLL_ENB);
1960 hw_write_20kx(hw, PLL_ENB, (data & (~0x07)));
1961
1962
1963 return 0;
1964}
1965
1966static int hw_card_shutdown(struct hw *hw)
1967{
1968 if (hw->irq >= 0)
1969 free_irq(hw->irq, hw);
1970
1971 hw->irq = -1;
1972
1973 if (hw->mem_base)
1974 iounmap((void *)hw->mem_base);
1975
1976 hw->mem_base = (unsigned long)NULL;
1977
1978 if (hw->io_base)
1979 pci_release_regions(hw->pci);
1980
1981 hw->io_base = 0;
1982
1983 pci_disable_device(hw->pci);
1984
1985 return 0;
1986}
1987
1988static int hw_card_init(struct hw *hw, struct card_conf *info)
1989{
1990 int err;
1991 unsigned int gctl;
1992 u32 data = 0;
1993 struct dac_conf dac_info = {0};
1994 struct adc_conf adc_info = {0};
1995 struct daio_conf daio_info = {0};
1996 struct trn_conf trn_info = {0};
1997
1998
1999
2000 err = hw_card_start(hw);
2001 if (err)
2002 return err;
2003
2004
2005 err = hw_pll_init(hw, info->rsr);
2006 if (err < 0)
2007 return err;
2008
2009
2010 err = hw_auto_init(hw);
2011 if (err < 0)
2012 return err;
2013
2014 gctl = hw_read_20kx(hw, GLOBAL_CNTL_GCTL);
2015 set_field(&gctl, GCTL_DBP, 1);
2016 set_field(&gctl, GCTL_TBP, 1);
2017 set_field(&gctl, GCTL_FBP, 1);
2018 set_field(&gctl, GCTL_DPC, 0);
2019 hw_write_20kx(hw, GLOBAL_CNTL_GCTL, gctl);
2020
2021
2022 hw_write_20kx(hw, GIE, 0);
2023
2024 hw_write_20kx(hw, SRC_IP, 0);
2025
2026
2027
2028
2029
2030
2031 hw_write_20kx(hw, GPIO_CTRL, 0xD802);
2032
2033
2034 hw_write_20kx(hw, MIXER_AR_ENABLE, 0x01);
2035
2036 trn_info.vm_pgt_phys = info->vm_pgt_phys;
2037 err = hw_trn_init(hw, &trn_info);
2038 if (err < 0)
2039 return err;
2040
2041 daio_info.msr = info->msr;
2042 err = hw_daio_init(hw, &daio_info);
2043 if (err < 0)
2044 return err;
2045
2046 dac_info.msr = info->msr;
2047 err = hw_dac_init(hw, &dac_info);
2048 if (err < 0)
2049 return err;
2050
2051 adc_info.msr = info->msr;
2052 adc_info.input = ADC_LINEIN;
2053 adc_info.mic20db = 0;
2054 err = hw_adc_init(hw, &adc_info);
2055 if (err < 0)
2056 return err;
2057
2058 data = hw_read_20kx(hw, SRC_MCTL);
2059 data |= 0x1;
2060 hw_write_20kx(hw, SRC_MCTL, data);
2061
2062 return 0;
2063}
2064
2065#ifdef CONFIG_PM
2066static int hw_suspend(struct hw *hw, pm_message_t state)
2067{
2068 struct pci_dev *pci = hw->pci;
2069
2070 hw_card_stop(hw);
2071
2072 pci_disable_device(pci);
2073 pci_save_state(pci);
2074 pci_set_power_state(pci, pci_choose_state(pci, state));
2075
2076 return 0;
2077}
2078
2079static int hw_resume(struct hw *hw, struct card_conf *info)
2080{
2081 struct pci_dev *pci = hw->pci;
2082
2083 pci_set_power_state(pci, PCI_D0);
2084 pci_restore_state(pci);
2085
2086
2087 return hw_card_init(hw, info);
2088}
2089#endif
2090
2091static u32 hw_read_20kx(struct hw *hw, u32 reg)
2092{
2093 return readl((void *)(hw->mem_base + reg));
2094}
2095
2096static void hw_write_20kx(struct hw *hw, u32 reg, u32 data)
2097{
2098 writel(data, (void *)(hw->mem_base + reg));
2099}
2100
2101static struct hw ct20k2_preset __devinitdata = {
2102 .irq = -1,
2103
2104 .card_init = hw_card_init,
2105 .card_stop = hw_card_stop,
2106 .pll_init = hw_pll_init,
2107 .is_adc_source_selected = hw_is_adc_input_selected,
2108 .select_adc_source = hw_adc_input_select,
2109 .have_digit_io_switch = hw_have_digit_io_switch,
2110#ifdef CONFIG_PM
2111 .suspend = hw_suspend,
2112 .resume = hw_resume,
2113#endif
2114
2115 .src_rsc_get_ctrl_blk = src_get_rsc_ctrl_blk,
2116 .src_rsc_put_ctrl_blk = src_put_rsc_ctrl_blk,
2117 .src_mgr_get_ctrl_blk = src_mgr_get_ctrl_blk,
2118 .src_mgr_put_ctrl_blk = src_mgr_put_ctrl_blk,
2119 .src_set_state = src_set_state,
2120 .src_set_bm = src_set_bm,
2121 .src_set_rsr = src_set_rsr,
2122 .src_set_sf = src_set_sf,
2123 .src_set_wr = src_set_wr,
2124 .src_set_pm = src_set_pm,
2125 .src_set_rom = src_set_rom,
2126 .src_set_vo = src_set_vo,
2127 .src_set_st = src_set_st,
2128 .src_set_ie = src_set_ie,
2129 .src_set_ilsz = src_set_ilsz,
2130 .src_set_bp = src_set_bp,
2131 .src_set_cisz = src_set_cisz,
2132 .src_set_ca = src_set_ca,
2133 .src_set_sa = src_set_sa,
2134 .src_set_la = src_set_la,
2135 .src_set_pitch = src_set_pitch,
2136 .src_set_dirty = src_set_dirty,
2137 .src_set_clear_zbufs = src_set_clear_zbufs,
2138 .src_set_dirty_all = src_set_dirty_all,
2139 .src_commit_write = src_commit_write,
2140 .src_get_ca = src_get_ca,
2141 .src_get_dirty = src_get_dirty,
2142 .src_dirty_conj_mask = src_dirty_conj_mask,
2143 .src_mgr_enbs_src = src_mgr_enbs_src,
2144 .src_mgr_enb_src = src_mgr_enb_src,
2145 .src_mgr_dsb_src = src_mgr_dsb_src,
2146 .src_mgr_commit_write = src_mgr_commit_write,
2147
2148 .srcimp_mgr_get_ctrl_blk = srcimp_mgr_get_ctrl_blk,
2149 .srcimp_mgr_put_ctrl_blk = srcimp_mgr_put_ctrl_blk,
2150 .srcimp_mgr_set_imaparc = srcimp_mgr_set_imaparc,
2151 .srcimp_mgr_set_imapuser = srcimp_mgr_set_imapuser,
2152 .srcimp_mgr_set_imapnxt = srcimp_mgr_set_imapnxt,
2153 .srcimp_mgr_set_imapaddr = srcimp_mgr_set_imapaddr,
2154 .srcimp_mgr_commit_write = srcimp_mgr_commit_write,
2155
2156 .amixer_rsc_get_ctrl_blk = amixer_rsc_get_ctrl_blk,
2157 .amixer_rsc_put_ctrl_blk = amixer_rsc_put_ctrl_blk,
2158 .amixer_mgr_get_ctrl_blk = amixer_mgr_get_ctrl_blk,
2159 .amixer_mgr_put_ctrl_blk = amixer_mgr_put_ctrl_blk,
2160 .amixer_set_mode = amixer_set_mode,
2161 .amixer_set_iv = amixer_set_iv,
2162 .amixer_set_x = amixer_set_x,
2163 .amixer_set_y = amixer_set_y,
2164 .amixer_set_sadr = amixer_set_sadr,
2165 .amixer_set_se = amixer_set_se,
2166 .amixer_set_dirty = amixer_set_dirty,
2167 .amixer_set_dirty_all = amixer_set_dirty_all,
2168 .amixer_commit_write = amixer_commit_write,
2169 .amixer_get_y = amixer_get_y,
2170 .amixer_get_dirty = amixer_get_dirty,
2171
2172 .dai_get_ctrl_blk = dai_get_ctrl_blk,
2173 .dai_put_ctrl_blk = dai_put_ctrl_blk,
2174 .dai_srt_set_srco = dai_srt_set_srco,
2175 .dai_srt_set_srcm = dai_srt_set_srcm,
2176 .dai_srt_set_rsr = dai_srt_set_rsr,
2177 .dai_srt_set_drat = dai_srt_set_drat,
2178 .dai_srt_set_ec = dai_srt_set_ec,
2179 .dai_srt_set_et = dai_srt_set_et,
2180 .dai_commit_write = dai_commit_write,
2181
2182 .dao_get_ctrl_blk = dao_get_ctrl_blk,
2183 .dao_put_ctrl_blk = dao_put_ctrl_blk,
2184 .dao_set_spos = dao_set_spos,
2185 .dao_commit_write = dao_commit_write,
2186 .dao_get_spos = dao_get_spos,
2187
2188 .daio_mgr_get_ctrl_blk = daio_mgr_get_ctrl_blk,
2189 .daio_mgr_put_ctrl_blk = daio_mgr_put_ctrl_blk,
2190 .daio_mgr_enb_dai = daio_mgr_enb_dai,
2191 .daio_mgr_dsb_dai = daio_mgr_dsb_dai,
2192 .daio_mgr_enb_dao = daio_mgr_enb_dao,
2193 .daio_mgr_dsb_dao = daio_mgr_dsb_dao,
2194 .daio_mgr_dao_init = daio_mgr_dao_init,
2195 .daio_mgr_set_imaparc = daio_mgr_set_imaparc,
2196 .daio_mgr_set_imapnxt = daio_mgr_set_imapnxt,
2197 .daio_mgr_set_imapaddr = daio_mgr_set_imapaddr,
2198 .daio_mgr_commit_write = daio_mgr_commit_write,
2199
2200 .set_timer_irq = set_timer_irq,
2201 .set_timer_tick = set_timer_tick,
2202 .get_wc = get_wc,
2203};
2204
2205int __devinit create_20k2_hw_obj(struct hw **rhw)
2206{
2207 struct hw20k2 *hw20k2;
2208
2209 *rhw = NULL;
2210 hw20k2 = kzalloc(sizeof(*hw20k2), GFP_KERNEL);
2211 if (!hw20k2)
2212 return -ENOMEM;
2213
2214 hw20k2->hw = ct20k2_preset;
2215 *rhw = &hw20k2->hw;
2216
2217 return 0;
2218}
2219
2220int destroy_20k2_hw_obj(struct hw *hw)
2221{
2222 if (hw->io_base)
2223 hw_card_shutdown(hw);
2224
2225 kfree(hw);
2226 return 0;
2227}
2228