2347 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.4 *5 * @File cthw20k2.c6 *7 * @Brief8 * This file contains the implementation of hardware access method for 20k2.9 *10 * @Author Liu Chun11 * @Date May 14 200812 */13 14#include <linux/types.h>15#include <linux/slab.h>16#include <linux/pci.h>17#include <linux/io.h>18#include <linux/string.h>19#include <linux/kernel.h>20#include <linux/interrupt.h>21#include <linux/delay.h>22#include "cthw20k2.h"23#include "ct20k2reg.h"24 25struct hw20k2 {26 struct hw hw;27 /* for i2c */28 unsigned char dev_id;29 unsigned char addr_size;30 unsigned char data_size;31 32 int mic_source;33};34 35static u32 hw_read_20kx(struct hw *hw, u32 reg);36static void hw_write_20kx(struct hw *hw, u32 reg, u32 data);37 38/*39 * Type definition block.40 * The layout of control structures can be directly applied on 20k2 chip.41 */42 43/*44 * SRC control block definitions.45 */46 47/* SRC resource control block */48#define SRCCTL_STATE 0x0000000749#define SRCCTL_BM 0x0000000850#define SRCCTL_RSR 0x0000003051#define SRCCTL_SF 0x000001C052#define SRCCTL_WR 0x0000020053#define SRCCTL_PM 0x0000040054#define SRCCTL_ROM 0x0000180055#define SRCCTL_VO 0x0000200056#define SRCCTL_ST 0x0000400057#define SRCCTL_IE 0x0000800058#define SRCCTL_ILSZ 0x000F000059#define SRCCTL_BP 0x0010000060 61#define SRCCCR_CISZ 0x000007FF62#define SRCCCR_CWA 0x001FF80063#define SRCCCR_D 0x0020000064#define SRCCCR_RS 0x01C0000065#define SRCCCR_NAL 0x3E00000066#define SRCCCR_RA 0xC000000067 68#define SRCCA_CA 0x0FFFFFFF69#define SRCCA_RS 0xE000000070 71#define SRCSA_SA 0x0FFFFFFF72 73#define SRCLA_LA 0x0FFFFFFF74 75/* Mixer Parameter Ring ram Low and Hight register.76 * Fixed-point value in 8.24 format for parameter channel */77#define MPRLH_PITCH 0xFFFFFFFF78 79/* SRC resource register dirty flags */80union src_dirty {81 struct {82 u16 ctl:1;83 u16 ccr:1;84 u16 sa:1;85 u16 la:1;86 u16 ca:1;87 u16 mpr:1;88 u16 czbfs:1; /* Clear Z-Buffers */89 u16 rsv:9;90 } bf;91 u16 data;92};93 94struct src_rsc_ctrl_blk {95 unsigned int ctl;96 unsigned int ccr;97 unsigned int ca;98 unsigned int sa;99 unsigned int la;100 unsigned int mpr;101 union src_dirty dirty;102};103 104/* SRC manager control block */105union src_mgr_dirty {106 struct {107 u16 enb0:1;108 u16 enb1:1;109 u16 enb2:1;110 u16 enb3:1;111 u16 enb4:1;112 u16 enb5:1;113 u16 enb6:1;114 u16 enb7:1;115 u16 enbsa:1;116 u16 rsv:7;117 } bf;118 u16 data;119};120 121struct src_mgr_ctrl_blk {122 unsigned int enbsa;123 unsigned int enb[8];124 union src_mgr_dirty dirty;125};126 127/* SRCIMP manager control block */128#define SRCAIM_ARC 0x00000FFF129#define SRCAIM_NXT 0x00FF0000130#define SRCAIM_SRC 0xFF000000131 132struct srcimap {133 unsigned int srcaim;134 unsigned int idx;135};136 137/* SRCIMP manager register dirty flags */138union srcimp_mgr_dirty {139 struct {140 u16 srcimap:1;141 u16 rsv:15;142 } bf;143 u16 data;144};145 146struct srcimp_mgr_ctrl_blk {147 struct srcimap srcimap;148 union srcimp_mgr_dirty dirty;149};150 151/*152 * Function implementation block.153 */154 155static int src_get_rsc_ctrl_blk(void **rblk)156{157 struct src_rsc_ctrl_blk *blk;158 159 *rblk = NULL;160 blk = kzalloc(sizeof(*blk), GFP_KERNEL);161 if (!blk)162 return -ENOMEM;163 164 *rblk = blk;165 166 return 0;167}168 169static int src_put_rsc_ctrl_blk(void *blk)170{171 kfree(blk);172 173 return 0;174}175 176static int src_set_state(void *blk, unsigned int state)177{178 struct src_rsc_ctrl_blk *ctl = blk;179 180 set_field(&ctl->ctl, SRCCTL_STATE, state);181 ctl->dirty.bf.ctl = 1;182 return 0;183}184 185static int src_set_bm(void *blk, unsigned int bm)186{187 struct src_rsc_ctrl_blk *ctl = blk;188 189 set_field(&ctl->ctl, SRCCTL_BM, bm);190 ctl->dirty.bf.ctl = 1;191 return 0;192}193 194static int src_set_rsr(void *blk, unsigned int rsr)195{196 struct src_rsc_ctrl_blk *ctl = blk;197 198 set_field(&ctl->ctl, SRCCTL_RSR, rsr);199 ctl->dirty.bf.ctl = 1;200 return 0;201}202 203static int src_set_sf(void *blk, unsigned int sf)204{205 struct src_rsc_ctrl_blk *ctl = blk;206 207 set_field(&ctl->ctl, SRCCTL_SF, sf);208 ctl->dirty.bf.ctl = 1;209 return 0;210}211 212static int src_set_wr(void *blk, unsigned int wr)213{214 struct src_rsc_ctrl_blk *ctl = blk;215 216 set_field(&ctl->ctl, SRCCTL_WR, wr);217 ctl->dirty.bf.ctl = 1;218 return 0;219}220 221static int src_set_pm(void *blk, unsigned int pm)222{223 struct src_rsc_ctrl_blk *ctl = blk;224 225 set_field(&ctl->ctl, SRCCTL_PM, pm);226 ctl->dirty.bf.ctl = 1;227 return 0;228}229 230static int src_set_rom(void *blk, unsigned int rom)231{232 struct src_rsc_ctrl_blk *ctl = blk;233 234 set_field(&ctl->ctl, SRCCTL_ROM, rom);235 ctl->dirty.bf.ctl = 1;236 return 0;237}238 239static int src_set_vo(void *blk, unsigned int vo)240{241 struct src_rsc_ctrl_blk *ctl = blk;242 243 set_field(&ctl->ctl, SRCCTL_VO, vo);244 ctl->dirty.bf.ctl = 1;245 return 0;246}247 248static int src_set_st(void *blk, unsigned int st)249{250 struct src_rsc_ctrl_blk *ctl = blk;251 252 set_field(&ctl->ctl, SRCCTL_ST, st);253 ctl->dirty.bf.ctl = 1;254 return 0;255}256 257static int src_set_ie(void *blk, unsigned int ie)258{259 struct src_rsc_ctrl_blk *ctl = blk;260 261 set_field(&ctl->ctl, SRCCTL_IE, ie);262 ctl->dirty.bf.ctl = 1;263 return 0;264}265 266static int src_set_ilsz(void *blk, unsigned int ilsz)267{268 struct src_rsc_ctrl_blk *ctl = blk;269 270 set_field(&ctl->ctl, SRCCTL_ILSZ, ilsz);271 ctl->dirty.bf.ctl = 1;272 return 0;273}274 275static int src_set_bp(void *blk, unsigned int bp)276{277 struct src_rsc_ctrl_blk *ctl = blk;278 279 set_field(&ctl->ctl, SRCCTL_BP, bp);280 ctl->dirty.bf.ctl = 1;281 return 0;282}283 284static int src_set_cisz(void *blk, unsigned int cisz)285{286 struct src_rsc_ctrl_blk *ctl = blk;287 288 set_field(&ctl->ccr, SRCCCR_CISZ, cisz);289 ctl->dirty.bf.ccr = 1;290 return 0;291}292 293static int src_set_ca(void *blk, unsigned int ca)294{295 struct src_rsc_ctrl_blk *ctl = blk;296 297 set_field(&ctl->ca, SRCCA_CA, ca);298 ctl->dirty.bf.ca = 1;299 return 0;300}301 302static int src_set_sa(void *blk, unsigned int sa)303{304 struct src_rsc_ctrl_blk *ctl = blk;305 306 set_field(&ctl->sa, SRCSA_SA, sa);307 ctl->dirty.bf.sa = 1;308 return 0;309}310 311static int src_set_la(void *blk, unsigned int la)312{313 struct src_rsc_ctrl_blk *ctl = blk;314 315 set_field(&ctl->la, SRCLA_LA, la);316 ctl->dirty.bf.la = 1;317 return 0;318}319 320static int src_set_pitch(void *blk, unsigned int pitch)321{322 struct src_rsc_ctrl_blk *ctl = blk;323 324 set_field(&ctl->mpr, MPRLH_PITCH, pitch);325 ctl->dirty.bf.mpr = 1;326 return 0;327}328 329static int src_set_clear_zbufs(void *blk, unsigned int clear)330{331 ((struct src_rsc_ctrl_blk *)blk)->dirty.bf.czbfs = (clear ? 1 : 0);332 return 0;333}334 335static int src_set_dirty(void *blk, unsigned int flags)336{337 ((struct src_rsc_ctrl_blk *)blk)->dirty.data = (flags & 0xffff);338 return 0;339}340 341static int src_set_dirty_all(void *blk)342{343 ((struct src_rsc_ctrl_blk *)blk)->dirty.data = ~(0x0);344 return 0;345}346 347#define AR_SLOT_SIZE 4096348#define AR_SLOT_BLOCK_SIZE 16349#define AR_PTS_PITCH 6350#define AR_PARAM_SRC_OFFSET 0x60351 352static unsigned int src_param_pitch_mixer(unsigned int src_idx)353{354 return ((src_idx << 4) + AR_PTS_PITCH + AR_SLOT_SIZE355 - AR_PARAM_SRC_OFFSET) % AR_SLOT_SIZE;356 357}358 359static int src_commit_write(struct hw *hw, unsigned int idx, void *blk)360{361 struct src_rsc_ctrl_blk *ctl = blk;362 int i;363 364 if (ctl->dirty.bf.czbfs) {365 /* Clear Z-Buffer registers */366 for (i = 0; i < 8; i++)367 hw_write_20kx(hw, SRC_UPZ+idx*0x100+i*0x4, 0);368 369 for (i = 0; i < 4; i++)370 hw_write_20kx(hw, SRC_DN0Z+idx*0x100+i*0x4, 0);371 372 for (i = 0; i < 8; i++)373 hw_write_20kx(hw, SRC_DN1Z+idx*0x100+i*0x4, 0);374 375 ctl->dirty.bf.czbfs = 0;376 }377 if (ctl->dirty.bf.mpr) {378 /* Take the parameter mixer resource in the same group as that379 * the idx src is in for simplicity. Unlike src, all conjugate380 * parameter mixer resources must be programmed for381 * corresponding conjugate src resources. */382 unsigned int pm_idx = src_param_pitch_mixer(idx);383 hw_write_20kx(hw, MIXER_PRING_LO_HI+4*pm_idx, ctl->mpr);384 hw_write_20kx(hw, MIXER_PMOPLO+8*pm_idx, 0x3);385 hw_write_20kx(hw, MIXER_PMOPHI+8*pm_idx, 0x0);386 ctl->dirty.bf.mpr = 0;387 }388 if (ctl->dirty.bf.sa) {389 hw_write_20kx(hw, SRC_SA+idx*0x100, ctl->sa);390 ctl->dirty.bf.sa = 0;391 }392 if (ctl->dirty.bf.la) {393 hw_write_20kx(hw, SRC_LA+idx*0x100, ctl->la);394 ctl->dirty.bf.la = 0;395 }396 if (ctl->dirty.bf.ca) {397 hw_write_20kx(hw, SRC_CA+idx*0x100, ctl->ca);398 ctl->dirty.bf.ca = 0;399 }400 401 /* Write srccf register */402 hw_write_20kx(hw, SRC_CF+idx*0x100, 0x0);403 404 if (ctl->dirty.bf.ccr) {405 hw_write_20kx(hw, SRC_CCR+idx*0x100, ctl->ccr);406 ctl->dirty.bf.ccr = 0;407 }408 if (ctl->dirty.bf.ctl) {409 hw_write_20kx(hw, SRC_CTL+idx*0x100, ctl->ctl);410 ctl->dirty.bf.ctl = 0;411 }412 413 return 0;414}415 416static int src_get_ca(struct hw *hw, unsigned int idx, void *blk)417{418 struct src_rsc_ctrl_blk *ctl = blk;419 420 ctl->ca = hw_read_20kx(hw, SRC_CA+idx*0x100);421 ctl->dirty.bf.ca = 0;422 423 return get_field(ctl->ca, SRCCA_CA);424}425 426static unsigned int src_get_dirty(void *blk)427{428 return ((struct src_rsc_ctrl_blk *)blk)->dirty.data;429}430 431static unsigned int src_dirty_conj_mask(void)432{433 return 0x20;434}435 436static int src_mgr_enbs_src(void *blk, unsigned int idx)437{438 ((struct src_mgr_ctrl_blk *)blk)->enbsa |= (0x1 << ((idx%128)/4));439 ((struct src_mgr_ctrl_blk *)blk)->dirty.bf.enbsa = 1;440 ((struct src_mgr_ctrl_blk *)blk)->enb[idx/32] |= (0x1 << (idx%32));441 return 0;442}443 444static int src_mgr_enb_src(void *blk, unsigned int idx)445{446 ((struct src_mgr_ctrl_blk *)blk)->enb[idx/32] |= (0x1 << (idx%32));447 ((struct src_mgr_ctrl_blk *)blk)->dirty.data |= (0x1 << (idx/32));448 return 0;449}450 451static int src_mgr_dsb_src(void *blk, unsigned int idx)452{453 ((struct src_mgr_ctrl_blk *)blk)->enb[idx/32] &= ~(0x1 << (idx%32));454 ((struct src_mgr_ctrl_blk *)blk)->dirty.data |= (0x1 << (idx/32));455 return 0;456}457 458static int src_mgr_commit_write(struct hw *hw, void *blk)459{460 struct src_mgr_ctrl_blk *ctl = blk;461 int i;462 unsigned int ret;463 464 if (ctl->dirty.bf.enbsa) {465 do {466 ret = hw_read_20kx(hw, SRC_ENBSTAT);467 } while (ret & 0x1);468 hw_write_20kx(hw, SRC_ENBSA, ctl->enbsa);469 ctl->dirty.bf.enbsa = 0;470 }471 for (i = 0; i < 8; i++) {472 if ((ctl->dirty.data & (0x1 << i))) {473 hw_write_20kx(hw, SRC_ENB+(i*0x100), ctl->enb[i]);474 ctl->dirty.data &= ~(0x1 << i);475 }476 }477 478 return 0;479}480 481static int src_mgr_get_ctrl_blk(void **rblk)482{483 struct src_mgr_ctrl_blk *blk;484 485 *rblk = NULL;486 blk = kzalloc(sizeof(*blk), GFP_KERNEL);487 if (!blk)488 return -ENOMEM;489 490 *rblk = blk;491 492 return 0;493}494 495static int src_mgr_put_ctrl_blk(void *blk)496{497 kfree(blk);498 499 return 0;500}501 502static int srcimp_mgr_get_ctrl_blk(void **rblk)503{504 struct srcimp_mgr_ctrl_blk *blk;505 506 *rblk = NULL;507 blk = kzalloc(sizeof(*blk), GFP_KERNEL);508 if (!blk)509 return -ENOMEM;510 511 *rblk = blk;512 513 return 0;514}515 516static int srcimp_mgr_put_ctrl_blk(void *blk)517{518 kfree(blk);519 520 return 0;521}522 523static int srcimp_mgr_set_imaparc(void *blk, unsigned int slot)524{525 struct srcimp_mgr_ctrl_blk *ctl = blk;526 527 set_field(&ctl->srcimap.srcaim, SRCAIM_ARC, slot);528 ctl->dirty.bf.srcimap = 1;529 return 0;530}531 532static int srcimp_mgr_set_imapuser(void *blk, unsigned int user)533{534 struct srcimp_mgr_ctrl_blk *ctl = blk;535 536 set_field(&ctl->srcimap.srcaim, SRCAIM_SRC, user);537 ctl->dirty.bf.srcimap = 1;538 return 0;539}540 541static int srcimp_mgr_set_imapnxt(void *blk, unsigned int next)542{543 struct srcimp_mgr_ctrl_blk *ctl = blk;544 545 set_field(&ctl->srcimap.srcaim, SRCAIM_NXT, next);546 ctl->dirty.bf.srcimap = 1;547 return 0;548}549 550static int srcimp_mgr_set_imapaddr(void *blk, unsigned int addr)551{552 ((struct srcimp_mgr_ctrl_blk *)blk)->srcimap.idx = addr;553 ((struct srcimp_mgr_ctrl_blk *)blk)->dirty.bf.srcimap = 1;554 return 0;555}556 557static int srcimp_mgr_commit_write(struct hw *hw, void *blk)558{559 struct srcimp_mgr_ctrl_blk *ctl = blk;560 561 if (ctl->dirty.bf.srcimap) {562 hw_write_20kx(hw, SRC_IMAP+ctl->srcimap.idx*0x100,563 ctl->srcimap.srcaim);564 ctl->dirty.bf.srcimap = 0;565 }566 567 return 0;568}569 570/*571 * AMIXER control block definitions.572 */573 574#define AMOPLO_M 0x00000003575#define AMOPLO_IV 0x00000004576#define AMOPLO_X 0x0003FFF0577#define AMOPLO_Y 0xFFFC0000578 579#define AMOPHI_SADR 0x000000FF580#define AMOPHI_SE 0x80000000581 582/* AMIXER resource register dirty flags */583union amixer_dirty {584 struct {585 u16 amoplo:1;586 u16 amophi:1;587 u16 rsv:14;588 } bf;589 u16 data;590};591 592/* AMIXER resource control block */593struct amixer_rsc_ctrl_blk {594 unsigned int amoplo;595 unsigned int amophi;596 union amixer_dirty dirty;597};598 599static int amixer_set_mode(void *blk, unsigned int mode)600{601 struct amixer_rsc_ctrl_blk *ctl = blk;602 603 set_field(&ctl->amoplo, AMOPLO_M, mode);604 ctl->dirty.bf.amoplo = 1;605 return 0;606}607 608static int amixer_set_iv(void *blk, unsigned int iv)609{610 struct amixer_rsc_ctrl_blk *ctl = blk;611 612 set_field(&ctl->amoplo, AMOPLO_IV, iv);613 ctl->dirty.bf.amoplo = 1;614 return 0;615}616 617static int amixer_set_x(void *blk, unsigned int x)618{619 struct amixer_rsc_ctrl_blk *ctl = blk;620 621 set_field(&ctl->amoplo, AMOPLO_X, x);622 ctl->dirty.bf.amoplo = 1;623 return 0;624}625 626static int amixer_set_y(void *blk, unsigned int y)627{628 struct amixer_rsc_ctrl_blk *ctl = blk;629 630 set_field(&ctl->amoplo, AMOPLO_Y, y);631 ctl->dirty.bf.amoplo = 1;632 return 0;633}634 635static int amixer_set_sadr(void *blk, unsigned int sadr)636{637 struct amixer_rsc_ctrl_blk *ctl = blk;638 639 set_field(&ctl->amophi, AMOPHI_SADR, sadr);640 ctl->dirty.bf.amophi = 1;641 return 0;642}643 644static int amixer_set_se(void *blk, unsigned int se)645{646 struct amixer_rsc_ctrl_blk *ctl = blk;647 648 set_field(&ctl->amophi, AMOPHI_SE, se);649 ctl->dirty.bf.amophi = 1;650 return 0;651}652 653static int amixer_set_dirty(void *blk, unsigned int flags)654{655 ((struct amixer_rsc_ctrl_blk *)blk)->dirty.data = (flags & 0xffff);656 return 0;657}658 659static int amixer_set_dirty_all(void *blk)660{661 ((struct amixer_rsc_ctrl_blk *)blk)->dirty.data = ~(0x0);662 return 0;663}664 665static int amixer_commit_write(struct hw *hw, unsigned int idx, void *blk)666{667 struct amixer_rsc_ctrl_blk *ctl = blk;668 669 if (ctl->dirty.bf.amoplo || ctl->dirty.bf.amophi) {670 hw_write_20kx(hw, MIXER_AMOPLO+idx*8, ctl->amoplo);671 ctl->dirty.bf.amoplo = 0;672 hw_write_20kx(hw, MIXER_AMOPHI+idx*8, ctl->amophi);673 ctl->dirty.bf.amophi = 0;674 }675 676 return 0;677}678 679static int amixer_get_y(void *blk)680{681 struct amixer_rsc_ctrl_blk *ctl = blk;682 683 return get_field(ctl->amoplo, AMOPLO_Y);684}685 686static unsigned int amixer_get_dirty(void *blk)687{688 return ((struct amixer_rsc_ctrl_blk *)blk)->dirty.data;689}690 691static int amixer_rsc_get_ctrl_blk(void **rblk)692{693 struct amixer_rsc_ctrl_blk *blk;694 695 *rblk = NULL;696 blk = kzalloc(sizeof(*blk), GFP_KERNEL);697 if (!blk)698 return -ENOMEM;699 700 *rblk = blk;701 702 return 0;703}704 705static int amixer_rsc_put_ctrl_blk(void *blk)706{707 kfree(blk);708 709 return 0;710}711 712static int amixer_mgr_get_ctrl_blk(void **rblk)713{714 *rblk = NULL;715 716 return 0;717}718 719static int amixer_mgr_put_ctrl_blk(void *blk)720{721 return 0;722}723 724/*725 * DAIO control block definitions.726 */727 728/* Receiver Sample Rate Tracker Control register */729#define SRTCTL_SRCO 0x000000FF730#define SRTCTL_SRCM 0x0000FF00731#define SRTCTL_RSR 0x00030000732#define SRTCTL_DRAT 0x00300000733#define SRTCTL_EC 0x01000000734#define SRTCTL_ET 0x10000000735 736/* DAIO Receiver register dirty flags */737union dai_dirty {738 struct {739 u16 srt:1;740 u16 rsv:15;741 } bf;742 u16 data;743};744 745/* DAIO Receiver control block */746struct dai_ctrl_blk {747 unsigned int srt;748 union dai_dirty dirty;749};750 751/* Audio Input Mapper RAM */752#define AIM_ARC 0x00000FFF753#define AIM_NXT 0x007F0000754 755struct daoimap {756 unsigned int aim;757 unsigned int idx;758};759 760/* Audio Transmitter Control and Status register */761#define ATXCTL_EN 0x00000001762#define ATXCTL_MODE 0x00000010763#define ATXCTL_CD 0x00000020764#define ATXCTL_RAW 0x00000100765#define ATXCTL_MT 0x00000200766#define ATXCTL_NUC 0x00003000767#define ATXCTL_BEN 0x00010000768#define ATXCTL_BMUX 0x00700000769#define ATXCTL_B24 0x01000000770#define ATXCTL_CPF 0x02000000771#define ATXCTL_RIV 0x10000000772#define ATXCTL_LIV 0x20000000773#define ATXCTL_RSAT 0x40000000774#define ATXCTL_LSAT 0x80000000775 776/* XDIF Transmitter register dirty flags */777union dao_dirty {778 struct {779 u16 atxcsl:1;780 u16 rsv:15;781 } bf;782 u16 data;783};784 785/* XDIF Transmitter control block */786struct dao_ctrl_blk {787 /* XDIF Transmitter Channel Status Low Register */788 unsigned int atxcsl;789 union dao_dirty dirty;790};791 792/* Audio Receiver Control register */793#define ARXCTL_EN 0x00000001794 795/* DAIO manager register dirty flags */796union daio_mgr_dirty {797 struct {798 u32 atxctl:8;799 u32 arxctl:8;800 u32 daoimap:1;801 u32 rsv:15;802 } bf;803 u32 data;804};805 806/* DAIO manager control block */807struct daio_mgr_ctrl_blk {808 struct daoimap daoimap;809 unsigned int txctl[8];810 unsigned int rxctl[8];811 union daio_mgr_dirty dirty;812};813 814static int dai_srt_set_srco(void *blk, unsigned int src)815{816 struct dai_ctrl_blk *ctl = blk;817 818 set_field(&ctl->srt, SRTCTL_SRCO, src);819 ctl->dirty.bf.srt = 1;820 return 0;821}822 823static int dai_srt_set_srcm(void *blk, unsigned int src)824{825 struct dai_ctrl_blk *ctl = blk;826 827 set_field(&ctl->srt, SRTCTL_SRCM, src);828 ctl->dirty.bf.srt = 1;829 return 0;830}831 832static int dai_srt_set_rsr(void *blk, unsigned int rsr)833{834 struct dai_ctrl_blk *ctl = blk;835 836 set_field(&ctl->srt, SRTCTL_RSR, rsr);837 ctl->dirty.bf.srt = 1;838 return 0;839}840 841static int dai_srt_set_drat(void *blk, unsigned int drat)842{843 struct dai_ctrl_blk *ctl = blk;844 845 set_field(&ctl->srt, SRTCTL_DRAT, drat);846 ctl->dirty.bf.srt = 1;847 return 0;848}849 850static int dai_srt_set_ec(void *blk, unsigned int ec)851{852 struct dai_ctrl_blk *ctl = blk;853 854 set_field(&ctl->srt, SRTCTL_EC, ec ? 1 : 0);855 ctl->dirty.bf.srt = 1;856 return 0;857}858 859static int dai_srt_set_et(void *blk, unsigned int et)860{861 struct dai_ctrl_blk *ctl = blk;862 863 set_field(&ctl->srt, SRTCTL_ET, et ? 1 : 0);864 ctl->dirty.bf.srt = 1;865 return 0;866}867 868static int dai_commit_write(struct hw *hw, unsigned int idx, void *blk)869{870 struct dai_ctrl_blk *ctl = blk;871 872 if (ctl->dirty.bf.srt) {873 hw_write_20kx(hw, AUDIO_IO_RX_SRT_CTL+0x40*idx, ctl->srt);874 ctl->dirty.bf.srt = 0;875 }876 877 return 0;878}879 880static int dai_get_ctrl_blk(void **rblk)881{882 struct dai_ctrl_blk *blk;883 884 *rblk = NULL;885 blk = kzalloc(sizeof(*blk), GFP_KERNEL);886 if (!blk)887 return -ENOMEM;888 889 *rblk = blk;890 891 return 0;892}893 894static int dai_put_ctrl_blk(void *blk)895{896 kfree(blk);897 898 return 0;899}900 901static int dao_set_spos(void *blk, unsigned int spos)902{903 ((struct dao_ctrl_blk *)blk)->atxcsl = spos;904 ((struct dao_ctrl_blk *)blk)->dirty.bf.atxcsl = 1;905 return 0;906}907 908static int dao_commit_write(struct hw *hw, unsigned int idx, void *blk)909{910 struct dao_ctrl_blk *ctl = blk;911 912 if (ctl->dirty.bf.atxcsl) {913 if (idx < 4) {914 /* S/PDIF SPOSx */915 hw_write_20kx(hw, AUDIO_IO_TX_CSTAT_L+0x40*idx,916 ctl->atxcsl);917 }918 ctl->dirty.bf.atxcsl = 0;919 }920 921 return 0;922}923 924static int dao_get_spos(void *blk, unsigned int *spos)925{926 *spos = ((struct dao_ctrl_blk *)blk)->atxcsl;927 return 0;928}929 930static int dao_get_ctrl_blk(void **rblk)931{932 struct dao_ctrl_blk *blk;933 934 *rblk = NULL;935 blk = kzalloc(sizeof(*blk), GFP_KERNEL);936 if (!blk)937 return -ENOMEM;938 939 *rblk = blk;940 941 return 0;942}943 944static int dao_put_ctrl_blk(void *blk)945{946 kfree(blk);947 948 return 0;949}950 951static int daio_mgr_enb_dai(void *blk, unsigned int idx)952{953 struct daio_mgr_ctrl_blk *ctl = blk;954 955 set_field(&ctl->rxctl[idx], ARXCTL_EN, 1);956 ctl->dirty.bf.arxctl |= (0x1 << idx);957 return 0;958}959 960static int daio_mgr_dsb_dai(void *blk, unsigned int idx)961{962 struct daio_mgr_ctrl_blk *ctl = blk;963 964 set_field(&ctl->rxctl[idx], ARXCTL_EN, 0);965 966 ctl->dirty.bf.arxctl |= (0x1 << idx);967 return 0;968}969 970static int daio_mgr_enb_dao(void *blk, unsigned int idx)971{972 struct daio_mgr_ctrl_blk *ctl = blk;973 974 set_field(&ctl->txctl[idx], ATXCTL_EN, 1);975 ctl->dirty.bf.atxctl |= (0x1 << idx);976 return 0;977}978 979static int daio_mgr_dsb_dao(void *blk, unsigned int idx)980{981 struct daio_mgr_ctrl_blk *ctl = blk;982 983 set_field(&ctl->txctl[idx], ATXCTL_EN, 0);984 ctl->dirty.bf.atxctl |= (0x1 << idx);985 return 0;986}987 988static int daio_mgr_dao_init(void *blk, unsigned int idx, unsigned int conf)989{990 struct daio_mgr_ctrl_blk *ctl = blk;991 992 if (idx < 4) {993 /* S/PDIF output */994 switch ((conf & 0xf)) {995 case 1:996 set_field(&ctl->txctl[idx], ATXCTL_NUC, 0);997 break;998 case 2:999 set_field(&ctl->txctl[idx], ATXCTL_NUC, 1);1000 break;1001 case 4:1002 set_field(&ctl->txctl[idx], ATXCTL_NUC, 2);1003 break;1004 case 8:1005 set_field(&ctl->txctl[idx], ATXCTL_NUC, 3);1006 break;1007 default:1008 break;1009 }1010 /* CDIF */1011 set_field(&ctl->txctl[idx], ATXCTL_CD, (!(conf & 0x7)));1012 /* Non-audio */1013 set_field(&ctl->txctl[idx], ATXCTL_LIV, (conf >> 4) & 0x1);1014 /* Non-audio */1015 set_field(&ctl->txctl[idx], ATXCTL_RIV, (conf >> 4) & 0x1);1016 set_field(&ctl->txctl[idx], ATXCTL_RAW,1017 ((conf >> 3) & 0x1) ? 0 : 0);1018 ctl->dirty.bf.atxctl |= (0x1 << idx);1019 } else {1020 /* I2S output */1021 /*idx %= 4; */1022 }1023 return 0;1024}1025 1026static int daio_mgr_set_imaparc(void *blk, unsigned int slot)1027{1028 struct daio_mgr_ctrl_blk *ctl = blk;1029 1030 set_field(&ctl->daoimap.aim, AIM_ARC, slot);1031 ctl->dirty.bf.daoimap = 1;1032 return 0;1033}1034 1035static int daio_mgr_set_imapnxt(void *blk, unsigned int next)1036{1037 struct daio_mgr_ctrl_blk *ctl = blk;1038 1039 set_field(&ctl->daoimap.aim, AIM_NXT, next);1040 ctl->dirty.bf.daoimap = 1;1041 return 0;1042}1043 1044static int daio_mgr_set_imapaddr(void *blk, unsigned int addr)1045{1046 ((struct daio_mgr_ctrl_blk *)blk)->daoimap.idx = addr;1047 ((struct daio_mgr_ctrl_blk *)blk)->dirty.bf.daoimap = 1;1048 return 0;1049}1050 1051static int daio_mgr_commit_write(struct hw *hw, void *blk)1052{1053 struct daio_mgr_ctrl_blk *ctl = blk;1054 unsigned int data;1055 int i;1056 1057 for (i = 0; i < 8; i++) {1058 if ((ctl->dirty.bf.atxctl & (0x1 << i))) {1059 data = ctl->txctl[i];1060 hw_write_20kx(hw, (AUDIO_IO_TX_CTL+(0x40*i)), data);1061 ctl->dirty.bf.atxctl &= ~(0x1 << i);1062 mdelay(1);1063 }1064 if ((ctl->dirty.bf.arxctl & (0x1 << i))) {1065 data = ctl->rxctl[i];1066 hw_write_20kx(hw, (AUDIO_IO_RX_CTL+(0x40*i)), data);1067 ctl->dirty.bf.arxctl &= ~(0x1 << i);1068 mdelay(1);1069 }1070 }1071 if (ctl->dirty.bf.daoimap) {1072 hw_write_20kx(hw, AUDIO_IO_AIM+ctl->daoimap.idx*4,1073 ctl->daoimap.aim);1074 ctl->dirty.bf.daoimap = 0;1075 }1076 1077 return 0;1078}1079 1080static int daio_mgr_get_ctrl_blk(struct hw *hw, void **rblk)1081{1082 struct daio_mgr_ctrl_blk *blk;1083 int i;1084 1085 *rblk = NULL;1086 blk = kzalloc(sizeof(*blk), GFP_KERNEL);1087 if (!blk)1088 return -ENOMEM;1089 1090 for (i = 0; i < 8; i++) {1091 blk->txctl[i] = hw_read_20kx(hw, AUDIO_IO_TX_CTL+(0x40*i));1092 blk->rxctl[i] = hw_read_20kx(hw, AUDIO_IO_RX_CTL+(0x40*i));1093 }1094 1095 *rblk = blk;1096 1097 return 0;1098}1099 1100static int daio_mgr_put_ctrl_blk(void *blk)1101{1102 kfree(blk);1103 1104 return 0;1105}1106 1107/* Timer interrupt */1108static int set_timer_irq(struct hw *hw, int enable)1109{1110 hw_write_20kx(hw, GIE, enable ? IT_INT : 0);1111 return 0;1112}1113 1114static int set_timer_tick(struct hw *hw, unsigned int ticks)1115{1116 if (ticks)1117 ticks |= TIMR_IE | TIMR_IP;1118 hw_write_20kx(hw, TIMR, ticks);1119 return 0;1120}1121 1122static unsigned int get_wc(struct hw *hw)1123{1124 return hw_read_20kx(hw, WC);1125}1126 1127/* Card hardware initialization block */1128struct dac_conf {1129 unsigned int msr; /* master sample rate in rsrs */1130};1131 1132struct adc_conf {1133 unsigned int msr; /* master sample rate in rsrs */1134 unsigned char input; /* the input source of ADC */1135 unsigned char mic20db; /* boost mic by 20db if input is microphone */1136};1137 1138struct daio_conf {1139 unsigned int msr; /* master sample rate in rsrs */1140};1141 1142struct trn_conf {1143 unsigned long vm_pgt_phys;1144};1145 1146static int hw_daio_init(struct hw *hw, const struct daio_conf *info)1147{1148 u32 data;1149 int i;1150 1151 /* Program I2S with proper sample rate and enable the correct I2S1152 * channel. ED(0/8/16/24): Enable all I2S/I2X master clock output */1153 if (1 == info->msr) {1154 hw_write_20kx(hw, AUDIO_IO_MCLK, 0x01010101);1155 hw_write_20kx(hw, AUDIO_IO_TX_BLRCLK, 0x01010101);1156 hw_write_20kx(hw, AUDIO_IO_RX_BLRCLK, 0);1157 } else if (2 == info->msr) {1158 if (hw->model != CTSB1270) {1159 hw_write_20kx(hw, AUDIO_IO_MCLK, 0x11111111);1160 } else {1161 /* PCM4220 on Titanium HD is different. */1162 hw_write_20kx(hw, AUDIO_IO_MCLK, 0x11011111);1163 }1164 /* Specify all playing 96khz1165 * EA [0] - Enabled1166 * RTA [4:5] - 96kHz1167 * EB [8] - Enabled1168 * RTB [12:13] - 96kHz1169 * EC [16] - Enabled1170 * RTC [20:21] - 96kHz1171 * ED [24] - Enabled1172 * RTD [28:29] - 96kHz */1173 hw_write_20kx(hw, AUDIO_IO_TX_BLRCLK, 0x11111111);1174 hw_write_20kx(hw, AUDIO_IO_RX_BLRCLK, 0);1175 } else if ((4 == info->msr) && (hw->model == CTSB1270)) {1176 hw_write_20kx(hw, AUDIO_IO_MCLK, 0x21011111);1177 hw_write_20kx(hw, AUDIO_IO_TX_BLRCLK, 0x21212121);1178 hw_write_20kx(hw, AUDIO_IO_RX_BLRCLK, 0);1179 } else {1180 dev_alert(hw->card->dev,1181 "ERROR!!! Invalid sampling rate!!!\n");1182 return -EINVAL;1183 }1184 1185 for (i = 0; i < 8; i++) {1186 if (i <= 3) {1187 /* This comment looks wrong since loop is over 4 */1188 /* channels and emu20k2 supports 4 spdif IOs. */1189 /* 1st 3 channels are SPDIFs (SB0960) */1190 if (i == 3)1191 data = 0x1001001;1192 else1193 data = 0x1000001;1194 1195 hw_write_20kx(hw, (AUDIO_IO_TX_CTL+(0x40*i)), data);1196 hw_write_20kx(hw, (AUDIO_IO_RX_CTL+(0x40*i)), data);1197 1198 /* Initialize the SPDIF Out Channel status registers.1199 * The value specified here is based on the typical1200 * values provided in the specification, namely: Clock1201 * Accuracy of 1000ppm, Sample Rate of 48KHz,1202 * unspecified source number, Generation status = 1,1203 * Category code = 0x12 (Digital Signal Mixer),1204 * Mode = 0, Emph = 0, Copy Permitted, AN = 01205 * (indicating that we're transmitting digital audio,1206 * and the Professional Use bit is 0. */1207 1208 hw_write_20kx(hw, AUDIO_IO_TX_CSTAT_L+(0x40*i),1209 0x02109204); /* Default to 48kHz */1210 1211 hw_write_20kx(hw, AUDIO_IO_TX_CSTAT_H+(0x40*i), 0x0B);1212 } else {1213 /* Again, loop is over 4 channels not 5. */1214 /* Next 5 channels are I2S (SB0960) */1215 data = 0x11;1216 hw_write_20kx(hw, AUDIO_IO_RX_CTL+(0x40*i), data);1217 if (2 == info->msr) {1218 /* Four channels per sample period */1219 data |= 0x1000;1220 } else if (4 == info->msr) {1221 /* FIXME: check this against the chip spec */1222 data |= 0x2000;1223 }1224 hw_write_20kx(hw, AUDIO_IO_TX_CTL+(0x40*i), data);1225 }1226 }1227 1228 return 0;1229}1230 1231/* TRANSPORT operations */1232static int hw_trn_init(struct hw *hw, const struct trn_conf *info)1233{1234 u32 vmctl, data;1235 u32 ptp_phys_low, ptp_phys_high;1236 int i;1237 1238 /* Set up device page table */1239 if ((~0UL) == info->vm_pgt_phys) {1240 dev_alert(hw->card->dev,1241 "Wrong device page table page address!!!\n");1242 return -1;1243 }1244 1245 vmctl = 0x80000C0F; /* 32-bit, 4k-size page */1246 ptp_phys_low = (u32)info->vm_pgt_phys;1247 ptp_phys_high = upper_32_bits(info->vm_pgt_phys);1248 if (sizeof(void *) == 8) /* 64bit address */1249 vmctl |= (3 << 8);1250 /* Write page table physical address to all PTPAL registers */1251 for (i = 0; i < 64; i++) {1252 hw_write_20kx(hw, VMEM_PTPAL+(16*i), ptp_phys_low);1253 hw_write_20kx(hw, VMEM_PTPAH+(16*i), ptp_phys_high);1254 }1255 /* Enable virtual memory transfer */1256 hw_write_20kx(hw, VMEM_CTL, vmctl);1257 /* Enable transport bus master and queueing of request */1258 hw_write_20kx(hw, TRANSPORT_CTL, 0x03);1259 hw_write_20kx(hw, TRANSPORT_INT, 0x200c01);1260 /* Enable transport ring */1261 data = hw_read_20kx(hw, TRANSPORT_ENB);1262 hw_write_20kx(hw, TRANSPORT_ENB, (data | 0x03));1263 1264 return 0;1265}1266 1267/* Card initialization */1268#define GCTL_AIE 0x000000011269#define GCTL_UAA 0x000000021270#define GCTL_DPC 0x000000041271#define GCTL_DBP 0x000000081272#define GCTL_ABP 0x000000101273#define GCTL_TBP 0x000000201274#define GCTL_SBP 0x000000401275#define GCTL_FBP 0x000000801276#define GCTL_ME 0x000001001277#define GCTL_AID 0x000010001278 1279#define PLLCTL_SRC 0x000000071280#define PLLCTL_SPE 0x000000081281#define PLLCTL_RD 0x000000F01282#define PLLCTL_FD 0x0001FF001283#define PLLCTL_OD 0x000600001284#define PLLCTL_B 0x000800001285#define PLLCTL_AS 0x001000001286#define PLLCTL_LF 0x03E000001287#define PLLCTL_SPS 0x1C0000001288#define PLLCTL_AD 0x600000001289 1290#define PLLSTAT_CCS 0x000000071291#define PLLSTAT_SPL 0x000000081292#define PLLSTAT_CRD 0x000000F01293#define PLLSTAT_CFD 0x0001FF001294#define PLLSTAT_SL 0x000200001295#define PLLSTAT_FAS 0x000400001296#define PLLSTAT_B 0x000800001297#define PLLSTAT_PD 0x001000001298#define PLLSTAT_OCA 0x002000001299#define PLLSTAT_NCA 0x004000001300 1301static int hw_pll_init(struct hw *hw, unsigned int rsr)1302{1303 unsigned int pllenb;1304 unsigned int pllctl;1305 unsigned int pllstat;1306 int i;1307 1308 pllenb = 0xB;1309 hw_write_20kx(hw, PLL_ENB, pllenb);1310 pllctl = 0x20C00000;1311 set_field(&pllctl, PLLCTL_B, 0);1312 set_field(&pllctl, PLLCTL_FD, 48000 == rsr ? 16 - 4 : 147 - 4);1313 set_field(&pllctl, PLLCTL_RD, 48000 == rsr ? 1 - 1 : 10 - 1);1314 hw_write_20kx(hw, PLL_CTL, pllctl);1315 msleep(40);1316 1317 pllctl = hw_read_20kx(hw, PLL_CTL);1318 set_field(&pllctl, PLLCTL_FD, 48000 == rsr ? 16 - 2 : 147 - 2);1319 hw_write_20kx(hw, PLL_CTL, pllctl);1320 msleep(40);1321 1322 for (i = 0; i < 1000; i++) {1323 pllstat = hw_read_20kx(hw, PLL_STAT);1324 if (get_field(pllstat, PLLSTAT_PD))1325 continue;1326 1327 if (get_field(pllstat, PLLSTAT_B) !=1328 get_field(pllctl, PLLCTL_B))1329 continue;1330 1331 if (get_field(pllstat, PLLSTAT_CCS) !=1332 get_field(pllctl, PLLCTL_SRC))1333 continue;1334 1335 if (get_field(pllstat, PLLSTAT_CRD) !=1336 get_field(pllctl, PLLCTL_RD))1337 continue;1338 1339 if (get_field(pllstat, PLLSTAT_CFD) !=1340 get_field(pllctl, PLLCTL_FD))1341 continue;1342 1343 break;1344 }1345 if (i >= 1000) {1346 dev_alert(hw->card->dev,1347 "PLL initialization failed!!!\n");1348 return -EBUSY;1349 }1350 1351 return 0;1352}1353 1354static int hw_auto_init(struct hw *hw)1355{1356 unsigned int gctl;1357 int i;1358 1359 gctl = hw_read_20kx(hw, GLOBAL_CNTL_GCTL);1360 set_field(&gctl, GCTL_AIE, 0);1361 hw_write_20kx(hw, GLOBAL_CNTL_GCTL, gctl);1362 set_field(&gctl, GCTL_AIE, 1);1363 hw_write_20kx(hw, GLOBAL_CNTL_GCTL, gctl);1364 mdelay(10);1365 for (i = 0; i < 400000; i++) {1366 gctl = hw_read_20kx(hw, GLOBAL_CNTL_GCTL);1367 if (get_field(gctl, GCTL_AID))1368 break;1369 }1370 if (!get_field(gctl, GCTL_AID)) {1371 dev_alert(hw->card->dev, "Card Auto-init failed!!!\n");1372 return -EBUSY;1373 }1374 1375 return 0;1376}1377 1378/* DAC operations */1379 1380#define CS4382_MC1 0x11381#define CS4382_MC2 0x21382#define CS4382_MC3 0x31383#define CS4382_FC 0x41384#define CS4382_IC 0x51385#define CS4382_XC1 0x61386#define CS4382_VCA1 0x71387#define CS4382_VCB1 0x81388#define CS4382_XC2 0x91389#define CS4382_VCA2 0xA1390#define CS4382_VCB2 0xB1391#define CS4382_XC3 0xC1392#define CS4382_VCA3 0xD1393#define CS4382_VCB3 0xE1394#define CS4382_XC4 0xF1395#define CS4382_VCA4 0x101396#define CS4382_VCB4 0x111397#define CS4382_CREV 0x121398 1399/* I2C status */1400#define STATE_LOCKED 0x001401#define STATE_UNLOCKED 0xAA1402#define DATA_READY 0x800000 /* Used with I2C_IF_STATUS */1403#define DATA_ABORT 0x10000 /* Used with I2C_IF_STATUS */1404 1405#define I2C_STATUS_DCM 0x000000011406#define I2C_STATUS_BC 0x000000061407#define I2C_STATUS_APD 0x000000081408#define I2C_STATUS_AB 0x000100001409#define I2C_STATUS_DR 0x008000001410 1411#define I2C_ADDRESS_PTAD 0x0000FFFF1412#define I2C_ADDRESS_SLAD 0x007F00001413 1414struct regs_cs4382 {1415 u32 mode_control_1;1416 u32 mode_control_2;1417 u32 mode_control_3;1418 1419 u32 filter_control;1420 u32 invert_control;1421 1422 u32 mix_control_P1;1423 u32 vol_control_A1;1424 u32 vol_control_B1;1425 1426 u32 mix_control_P2;1427 u32 vol_control_A2;1428 u32 vol_control_B2;1429 1430 u32 mix_control_P3;1431 u32 vol_control_A3;1432 u32 vol_control_B3;1433 1434 u32 mix_control_P4;1435 u32 vol_control_A4;1436 u32 vol_control_B4;1437};1438 1439static int hw20k2_i2c_unlock_full_access(struct hw *hw)1440{1441 u8 UnlockKeySequence_FLASH_FULLACCESS_MODE[2] = {0xB3, 0xD4};1442 1443 /* Send keys for forced BIOS mode */1444 hw_write_20kx(hw, I2C_IF_WLOCK,1445 UnlockKeySequence_FLASH_FULLACCESS_MODE[0]);1446 hw_write_20kx(hw, I2C_IF_WLOCK,1447 UnlockKeySequence_FLASH_FULLACCESS_MODE[1]);1448 /* Check whether the chip is unlocked */1449 if (hw_read_20kx(hw, I2C_IF_WLOCK) == STATE_UNLOCKED)1450 return 0;1451 1452 return -1;1453}1454 1455static int hw20k2_i2c_lock_chip(struct hw *hw)1456{1457 /* Write twice */1458 hw_write_20kx(hw, I2C_IF_WLOCK, STATE_LOCKED);1459 hw_write_20kx(hw, I2C_IF_WLOCK, STATE_LOCKED);1460 if (hw_read_20kx(hw, I2C_IF_WLOCK) == STATE_LOCKED)1461 return 0;1462 1463 return -1;1464}1465 1466static int hw20k2_i2c_init(struct hw *hw, u8 dev_id, u8 addr_size, u8 data_size)1467{1468 struct hw20k2 *hw20k2 = (struct hw20k2 *)hw;1469 int err;1470 unsigned int i2c_status;1471 unsigned int i2c_addr;1472 1473 err = hw20k2_i2c_unlock_full_access(hw);1474 if (err < 0)1475 return err;1476 1477 hw20k2->addr_size = addr_size;1478 hw20k2->data_size = data_size;1479 hw20k2->dev_id = dev_id;1480 1481 i2c_addr = 0;1482 set_field(&i2c_addr, I2C_ADDRESS_SLAD, dev_id);1483 1484 hw_write_20kx(hw, I2C_IF_ADDRESS, i2c_addr);1485 1486 i2c_status = hw_read_20kx(hw, I2C_IF_STATUS);1487 1488 set_field(&i2c_status, I2C_STATUS_DCM, 1); /* Direct control mode */1489 1490 hw_write_20kx(hw, I2C_IF_STATUS, i2c_status);1491 1492 return 0;1493}1494 1495static int hw20k2_i2c_uninit(struct hw *hw)1496{1497 unsigned int i2c_status;1498 unsigned int i2c_addr;1499 1500 i2c_addr = 0;1501 set_field(&i2c_addr, I2C_ADDRESS_SLAD, 0x57); /* I2C id */1502 1503 hw_write_20kx(hw, I2C_IF_ADDRESS, i2c_addr);1504 1505 i2c_status = hw_read_20kx(hw, I2C_IF_STATUS);1506 1507 set_field(&i2c_status, I2C_STATUS_DCM, 0); /* I2C mode */1508 1509 hw_write_20kx(hw, I2C_IF_STATUS, i2c_status);1510 1511 return hw20k2_i2c_lock_chip(hw);1512}1513 1514static int hw20k2_i2c_wait_data_ready(struct hw *hw)1515{1516 int i = 0x400000;1517 unsigned int ret;1518 1519 do {1520 ret = hw_read_20kx(hw, I2C_IF_STATUS);1521 } while ((!(ret & DATA_READY)) && --i);1522 1523 return i;1524}1525 1526static int hw20k2_i2c_read(struct hw *hw, u16 addr, u32 *datap)1527{1528 struct hw20k2 *hw20k2 = (struct hw20k2 *)hw;1529 unsigned int i2c_status;1530 1531 i2c_status = hw_read_20kx(hw, I2C_IF_STATUS);1532 set_field(&i2c_status, I2C_STATUS_BC,1533 (4 == hw20k2->addr_size) ? 0 : hw20k2->addr_size);1534 hw_write_20kx(hw, I2C_IF_STATUS, i2c_status);1535 if (!hw20k2_i2c_wait_data_ready(hw))1536 return -1;1537 1538 hw_write_20kx(hw, I2C_IF_WDATA, addr);1539 if (!hw20k2_i2c_wait_data_ready(hw))1540 return -1;1541 1542 /* Force a read operation */1543 hw_write_20kx(hw, I2C_IF_RDATA, 0);1544 if (!hw20k2_i2c_wait_data_ready(hw))1545 return -1;1546 1547 *datap = hw_read_20kx(hw, I2C_IF_RDATA);1548 1549 return 0;1550}1551 1552static int hw20k2_i2c_write(struct hw *hw, u16 addr, u32 data)1553{1554 struct hw20k2 *hw20k2 = (struct hw20k2 *)hw;1555 unsigned int i2c_data = (data << (hw20k2->addr_size * 8)) | addr;1556 unsigned int i2c_status;1557 1558 i2c_status = hw_read_20kx(hw, I2C_IF_STATUS);1559 1560 set_field(&i2c_status, I2C_STATUS_BC,1561 (4 == (hw20k2->addr_size + hw20k2->data_size)) ?1562 0 : (hw20k2->addr_size + hw20k2->data_size));1563 1564 hw_write_20kx(hw, I2C_IF_STATUS, i2c_status);1565 hw20k2_i2c_wait_data_ready(hw);1566 /* Dummy write to trigger the write operation */1567 hw_write_20kx(hw, I2C_IF_WDATA, 0);1568 hw20k2_i2c_wait_data_ready(hw);1569 1570 /* This is the real data */1571 hw_write_20kx(hw, I2C_IF_WDATA, i2c_data);1572 hw20k2_i2c_wait_data_ready(hw);1573 1574 return 0;1575}1576 1577static void hw_dac_stop(struct hw *hw)1578{1579 u32 data;1580 data = hw_read_20kx(hw, GPIO_DATA);1581 data &= 0xFFFFFFFD;1582 hw_write_20kx(hw, GPIO_DATA, data);1583 usleep_range(10000, 11000);1584}1585 1586static void hw_dac_start(struct hw *hw)1587{1588 u32 data;1589 data = hw_read_20kx(hw, GPIO_DATA);1590 data |= 0x2;1591 hw_write_20kx(hw, GPIO_DATA, data);1592 msleep(50);1593}1594 1595static void hw_dac_reset(struct hw *hw)1596{1597 hw_dac_stop(hw);1598 hw_dac_start(hw);1599}1600 1601static int hw_dac_init(struct hw *hw, const struct dac_conf *info)1602{1603 int err;1604 u32 data;1605 int i;1606 struct regs_cs4382 cs_read = {0};1607 struct regs_cs4382 cs_def = {1608 .mode_control_1 = 0x00000001, /* Mode Control 1 */1609 .mode_control_2 = 0x00000000, /* Mode Control 2 */1610 .mode_control_3 = 0x00000084, /* Mode Control 3 */1611 .filter_control = 0x00000000, /* Filter Control */1612 .invert_control = 0x00000000, /* Invert Control */1613 .mix_control_P1 = 0x00000024, /* Mixing Control Pair 1 */1614 .vol_control_A1 = 0x00000000, /* Vol Control A1 */1615 .vol_control_B1 = 0x00000000, /* Vol Control B1 */1616 .mix_control_P2 = 0x00000024, /* Mixing Control Pair 2 */1617 .vol_control_A2 = 0x00000000, /* Vol Control A2 */1618 .vol_control_B2 = 0x00000000, /* Vol Control B2 */1619 .mix_control_P3 = 0x00000024, /* Mixing Control Pair 3 */1620 .vol_control_A3 = 0x00000000, /* Vol Control A3 */1621 .vol_control_B3 = 0x00000000, /* Vol Control B3 */1622 .mix_control_P4 = 0x00000024, /* Mixing Control Pair 4 */1623 .vol_control_A4 = 0x00000000, /* Vol Control A4 */1624 .vol_control_B4 = 0x00000000 /* Vol Control B4 */1625 };1626 1627 if (hw->model == CTSB1270) {1628 hw_dac_stop(hw);1629 data = hw_read_20kx(hw, GPIO_DATA);1630 data &= ~0x0600;1631 if (1 == info->msr)1632 data |= 0x0000; /* Single Speed Mode 0-50kHz */1633 else if (2 == info->msr)1634 data |= 0x0200; /* Double Speed Mode 50-100kHz */1635 else1636 data |= 0x0600; /* Quad Speed Mode 100-200kHz */1637 hw_write_20kx(hw, GPIO_DATA, data);1638 hw_dac_start(hw);1639 return 0;1640 }1641 1642 /* Set DAC reset bit as output */1643 data = hw_read_20kx(hw, GPIO_CTRL);1644 data |= 0x02;1645 hw_write_20kx(hw, GPIO_CTRL, data);1646 1647 err = hw20k2_i2c_init(hw, 0x18, 1, 1);1648 if (err < 0)1649 goto End;1650 1651 for (i = 0; i < 2; i++) {1652 /* Reset DAC twice just in-case the chip1653 * didn't initialized properly */1654 hw_dac_reset(hw);1655 hw_dac_reset(hw);1656 1657 if (hw20k2_i2c_read(hw, CS4382_MC1, &cs_read.mode_control_1))1658 continue;1659 1660 if (hw20k2_i2c_read(hw, CS4382_MC2, &cs_read.mode_control_2))1661 continue;1662 1663 if (hw20k2_i2c_read(hw, CS4382_MC3, &cs_read.mode_control_3))1664 continue;1665 1666 if (hw20k2_i2c_read(hw, CS4382_FC, &cs_read.filter_control))1667 continue;1668 1669 if (hw20k2_i2c_read(hw, CS4382_IC, &cs_read.invert_control))1670 continue;1671 1672 if (hw20k2_i2c_read(hw, CS4382_XC1, &cs_read.mix_control_P1))1673 continue;1674 1675 if (hw20k2_i2c_read(hw, CS4382_VCA1, &cs_read.vol_control_A1))1676 continue;1677 1678 if (hw20k2_i2c_read(hw, CS4382_VCB1, &cs_read.vol_control_B1))1679 continue;1680 1681 if (hw20k2_i2c_read(hw, CS4382_XC2, &cs_read.mix_control_P2))1682 continue;1683 1684 if (hw20k2_i2c_read(hw, CS4382_VCA2, &cs_read.vol_control_A2))1685 continue;1686 1687 if (hw20k2_i2c_read(hw, CS4382_VCB2, &cs_read.vol_control_B2))1688 continue;1689 1690 if (hw20k2_i2c_read(hw, CS4382_XC3, &cs_read.mix_control_P3))1691 continue;1692 1693 if (hw20k2_i2c_read(hw, CS4382_VCA3, &cs_read.vol_control_A3))1694 continue;1695 1696 if (hw20k2_i2c_read(hw, CS4382_VCB3, &cs_read.vol_control_B3))1697 continue;1698 1699 if (hw20k2_i2c_read(hw, CS4382_XC4, &cs_read.mix_control_P4))1700 continue;1701 1702 if (hw20k2_i2c_read(hw, CS4382_VCA4, &cs_read.vol_control_A4))1703 continue;1704 1705 if (hw20k2_i2c_read(hw, CS4382_VCB4, &cs_read.vol_control_B4))1706 continue;1707 1708 if (memcmp(&cs_read, &cs_def, sizeof(cs_read)))1709 continue;1710 else1711 break;1712 }1713 1714 if (i >= 2)1715 goto End;1716 1717 /* Note: Every I2C write must have some delay.1718 * This is not a requirement but the delay works here... */1719 hw20k2_i2c_write(hw, CS4382_MC1, 0x80);1720 hw20k2_i2c_write(hw, CS4382_MC2, 0x10);1721 if (1 == info->msr) {1722 hw20k2_i2c_write(hw, CS4382_XC1, 0x24);1723 hw20k2_i2c_write(hw, CS4382_XC2, 0x24);1724 hw20k2_i2c_write(hw, CS4382_XC3, 0x24);1725 hw20k2_i2c_write(hw, CS4382_XC4, 0x24);1726 } else if (2 == info->msr) {1727 hw20k2_i2c_write(hw, CS4382_XC1, 0x25);1728 hw20k2_i2c_write(hw, CS4382_XC2, 0x25);1729 hw20k2_i2c_write(hw, CS4382_XC3, 0x25);1730 hw20k2_i2c_write(hw, CS4382_XC4, 0x25);1731 } else {1732 hw20k2_i2c_write(hw, CS4382_XC1, 0x26);1733 hw20k2_i2c_write(hw, CS4382_XC2, 0x26);1734 hw20k2_i2c_write(hw, CS4382_XC3, 0x26);1735 hw20k2_i2c_write(hw, CS4382_XC4, 0x26);1736 }1737 1738 return 0;1739End:1740 1741 hw20k2_i2c_uninit(hw);1742 return -1;1743}1744 1745/* ADC operations */1746#define MAKE_WM8775_ADDR(addr, data) (u32)(((addr<<1)&0xFE)|((data>>8)&0x1))1747#define MAKE_WM8775_DATA(data) (u32)(data&0xFF)1748 1749#define WM8775_IC 0x0B1750#define WM8775_MMC 0x0C1751#define WM8775_AADCL 0x0E1752#define WM8775_AADCR 0x0F1753#define WM8775_ADCMC 0x151754#define WM8775_RESET 0x171755 1756static int hw_is_adc_input_selected(struct hw *hw, enum ADCSRC type)1757{1758 u32 data;1759 if (hw->model == CTSB1270) {1760 /* Titanium HD has two ADC chips, one for line in and one */1761 /* for MIC. We don't need to switch the ADC input. */1762 return 1;1763 }1764 data = hw_read_20kx(hw, GPIO_DATA);1765 switch (type) {1766 case ADC_MICIN:1767 data = (data & (0x1 << 14)) ? 1 : 0;1768 break;1769 case ADC_LINEIN:1770 data = (data & (0x1 << 14)) ? 0 : 1;1771 break;1772 default:1773 data = 0;1774 }1775 return data;1776}1777 1778#define MIC_BOOST_0DB 0xCF1779#define MIC_BOOST_STEPS_PER_DB 21780 1781static void hw_wm8775_input_select(struct hw *hw, u8 input, s8 gain_in_db)1782{1783 u32 adcmc, gain;1784 1785 if (input > 3)1786 input = 3;1787 1788 adcmc = ((u32)1 << input) | 0x100; /* Link L+R gain... */1789 1790 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_ADCMC, adcmc),1791 MAKE_WM8775_DATA(adcmc));1792 1793 if (gain_in_db < -103)1794 gain_in_db = -103;1795 if (gain_in_db > 24)1796 gain_in_db = 24;1797 1798 gain = gain_in_db * MIC_BOOST_STEPS_PER_DB + MIC_BOOST_0DB;1799 1800 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCL, gain),1801 MAKE_WM8775_DATA(gain));1802 /* ...so there should be no need for the following. */1803 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_AADCR, gain),1804 MAKE_WM8775_DATA(gain));1805}1806 1807static int hw_adc_input_select(struct hw *hw, enum ADCSRC type)1808{1809 u32 data;1810 data = hw_read_20kx(hw, GPIO_DATA);1811 switch (type) {1812 case ADC_MICIN:1813 data |= (0x1 << 14);1814 hw_write_20kx(hw, GPIO_DATA, data);1815 hw_wm8775_input_select(hw, 0, 20); /* Mic, 20dB */1816 break;1817 case ADC_LINEIN:1818 data &= ~(0x1 << 14);1819 hw_write_20kx(hw, GPIO_DATA, data);1820 hw_wm8775_input_select(hw, 1, 0); /* Line-in, 0dB */1821 break;1822 default:1823 break;1824 }1825 1826 return 0;1827}1828 1829static int hw_adc_init(struct hw *hw, const struct adc_conf *info)1830{1831 int err;1832 u32 data, ctl;1833 1834 /* Set ADC reset bit as output */1835 data = hw_read_20kx(hw, GPIO_CTRL);1836 data |= (0x1 << 15);1837 hw_write_20kx(hw, GPIO_CTRL, data);1838 1839 /* Initialize I2C */1840 err = hw20k2_i2c_init(hw, 0x1A, 1, 1);1841 if (err < 0) {1842 dev_alert(hw->card->dev, "Failure to acquire I2C!!!\n");1843 goto error;1844 }1845 1846 /* Reset the ADC (reset is active low). */1847 data = hw_read_20kx(hw, GPIO_DATA);1848 data &= ~(0x1 << 15);1849 hw_write_20kx(hw, GPIO_DATA, data);1850 1851 if (hw->model == CTSB1270) {1852 /* Set up the PCM4220 ADC on Titanium HD */1853 data &= ~0x0C;1854 if (1 == info->msr)1855 data |= 0x00; /* Single Speed Mode 32-50kHz */1856 else if (2 == info->msr)1857 data |= 0x08; /* Double Speed Mode 50-108kHz */1858 else1859 data |= 0x04; /* Quad Speed Mode 108kHz-216kHz */1860 hw_write_20kx(hw, GPIO_DATA, data);1861 }1862 1863 usleep_range(10000, 11000);1864 /* Return the ADC to normal operation. */1865 data |= (0x1 << 15);1866 hw_write_20kx(hw, GPIO_DATA, data);1867 msleep(50);1868 1869 /* I2C write to register offset 0x0B to set ADC LRCLK polarity */1870 /* invert bit, interface format to I2S, word length to 24-bit, */1871 /* enable ADC high pass filter. Fixes bug 5323? */1872 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_IC, 0x26),1873 MAKE_WM8775_DATA(0x26));1874 1875 /* Set the master mode (256fs) */1876 if (1 == info->msr) {1877 /* slave mode, 128x oversampling 256fs */1878 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_MMC, 0x02),1879 MAKE_WM8775_DATA(0x02));1880 } else if ((2 == info->msr) || (4 == info->msr)) {1881 /* slave mode, 64x oversampling, 256fs */1882 hw20k2_i2c_write(hw, MAKE_WM8775_ADDR(WM8775_MMC, 0x0A),1883 MAKE_WM8775_DATA(0x0A));1884 } else {1885 dev_alert(hw->card->dev,1886 "Invalid master sampling rate (msr %d)!!!\n",1887 info->msr);1888 err = -EINVAL;1889 goto error;1890 }1891 1892 if (hw->model != CTSB1270) {1893 /* Configure GPIO bit 14 change to line-in/mic-in */1894 ctl = hw_read_20kx(hw, GPIO_CTRL);1895 ctl |= 0x1 << 14;1896 hw_write_20kx(hw, GPIO_CTRL, ctl);1897 hw_adc_input_select(hw, ADC_LINEIN);1898 } else {1899 hw_wm8775_input_select(hw, 0, 0);1900 }1901 1902 return 0;1903error:1904 hw20k2_i2c_uninit(hw);1905 return err;1906}1907 1908static struct capabilities hw_capabilities(struct hw *hw)1909{1910 struct capabilities cap;1911 1912 cap.digit_io_switch = 0;1913 cap.dedicated_mic = hw->model == CTSB1270;1914 cap.output_switch = hw->model == CTSB1270;1915 cap.mic_source_switch = hw->model == CTSB1270;1916 1917 return cap;1918}1919 1920static int hw_output_switch_get(struct hw *hw)1921{1922 u32 data = hw_read_20kx(hw, GPIO_EXT_DATA);1923 1924 switch (data & 0x30) {1925 case 0x00:1926 return 0;1927 case 0x10:1928 return 1;1929 case 0x20:1930 return 2;1931 default:1932 return 3;1933 }1934}1935 1936static int hw_output_switch_put(struct hw *hw, int position)1937{1938 u32 data;1939 1940 if (position == hw_output_switch_get(hw))1941 return 0;1942 1943 /* Mute line and headphones (intended for anti-pop). */1944 data = hw_read_20kx(hw, GPIO_DATA);1945 data |= (0x03 << 11);1946 hw_write_20kx(hw, GPIO_DATA, data);1947 1948 data = hw_read_20kx(hw, GPIO_EXT_DATA) & ~0x30;1949 switch (position) {1950 case 0:1951 break;1952 case 1:1953 data |= 0x10;1954 break;1955 default:1956 data |= 0x20;1957 }1958 hw_write_20kx(hw, GPIO_EXT_DATA, data);1959 1960 /* Unmute line and headphones. */1961 data = hw_read_20kx(hw, GPIO_DATA);1962 data &= ~(0x03 << 11);1963 hw_write_20kx(hw, GPIO_DATA, data);1964 1965 return 1;1966}1967 1968static int hw_mic_source_switch_get(struct hw *hw)1969{1970 struct hw20k2 *hw20k2 = (struct hw20k2 *)hw;1971 1972 return hw20k2->mic_source;1973}1974 1975static int hw_mic_source_switch_put(struct hw *hw, int position)1976{1977 struct hw20k2 *hw20k2 = (struct hw20k2 *)hw;1978 1979 if (position == hw20k2->mic_source)1980 return 0;1981 1982 switch (position) {1983 case 0:1984 hw_wm8775_input_select(hw, 0, 0); /* Mic, 0dB */1985 break;1986 case 1:1987 hw_wm8775_input_select(hw, 1, 0); /* FP Mic, 0dB */1988 break;1989 case 2:1990 hw_wm8775_input_select(hw, 3, 0); /* Aux Ext, 0dB */1991 break;1992 default:1993 return 0;1994 }1995 1996 hw20k2->mic_source = position;1997 1998 return 1;1999}2000 2001static irqreturn_t ct_20k2_interrupt(int irq, void *dev_id)2002{2003 struct hw *hw = dev_id;2004 unsigned int status;2005 2006 status = hw_read_20kx(hw, GIP);2007 if (!status)2008 return IRQ_NONE;2009 2010 if (hw->irq_callback)2011 hw->irq_callback(hw->irq_callback_data, status);2012 2013 hw_write_20kx(hw, GIP, status);2014 return IRQ_HANDLED;2015}2016 2017static int hw_card_start(struct hw *hw)2018{2019 int err = 0;2020 struct pci_dev *pci = hw->pci;2021 unsigned int gctl;2022 const unsigned int dma_bits = BITS_PER_LONG;2023 2024 err = pci_enable_device(pci);2025 if (err < 0)2026 return err;2027 2028 /* Set DMA transfer mask */2029 if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(dma_bits)))2030 dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(32));2031 2032 if (!hw->io_base) {2033 err = pci_request_regions(pci, "XFi");2034 if (err < 0)2035 goto error1;2036 2037 hw->io_base = pci_resource_start(hw->pci, 2);2038 hw->mem_base = ioremap(hw->io_base,2039 pci_resource_len(hw->pci, 2));2040 if (!hw->mem_base) {2041 err = -ENOENT;2042 goto error2;2043 }2044 }2045 2046 /* Switch to 20k2 mode from UAA mode. */2047 gctl = hw_read_20kx(hw, GLOBAL_CNTL_GCTL);2048 set_field(&gctl, GCTL_UAA, 0);2049 hw_write_20kx(hw, GLOBAL_CNTL_GCTL, gctl);2050 2051 if (hw->irq < 0) {2052 err = request_irq(pci->irq, ct_20k2_interrupt, IRQF_SHARED,2053 KBUILD_MODNAME, hw);2054 if (err < 0) {2055 dev_err(hw->card->dev,2056 "XFi: Cannot get irq %d\n", pci->irq);2057 goto error2;2058 }2059 hw->irq = pci->irq;2060 hw->card->sync_irq = hw->irq;2061 }2062 2063 pci_set_master(pci);2064 2065 return 0;2066 2067/*error3:2068 iounmap((void *)hw->mem_base);2069 hw->mem_base = (unsigned long)NULL;*/2070error2:2071 pci_release_regions(pci);2072 hw->io_base = 0;2073error1:2074 pci_disable_device(pci);2075 return err;2076}2077 2078static int hw_card_stop(struct hw *hw)2079{2080 unsigned int data;2081 2082 /* disable transport bus master and queueing of request */2083 hw_write_20kx(hw, TRANSPORT_CTL, 0x00);2084 2085 /* disable pll */2086 data = hw_read_20kx(hw, PLL_ENB);2087 hw_write_20kx(hw, PLL_ENB, (data & (~0x07)));2088 2089 /* TODO: Disable interrupt and so on... */2090 return 0;2091}2092 2093static int hw_card_shutdown(struct hw *hw)2094{2095 if (hw->irq >= 0)2096 free_irq(hw->irq, hw);2097 2098 hw->irq = -1;2099 iounmap(hw->mem_base);2100 hw->mem_base = NULL;2101 2102 if (hw->io_base)2103 pci_release_regions(hw->pci);2104 2105 hw->io_base = 0;2106 2107 pci_disable_device(hw->pci);2108 2109 return 0;2110}2111 2112static int hw_card_init(struct hw *hw, struct card_conf *info)2113{2114 int err;2115 unsigned int gctl;2116 u32 data = 0;2117 struct dac_conf dac_info = {0};2118 struct adc_conf adc_info = {0};2119 struct daio_conf daio_info = {0};2120 struct trn_conf trn_info = {0};2121 2122 /* Get PCI io port/memory base address and2123 * do 20kx core switch if needed. */2124 err = hw_card_start(hw);2125 if (err)2126 return err;2127 2128 /* PLL init */2129 err = hw_pll_init(hw, info->rsr);2130 if (err < 0)2131 return err;2132 2133 /* kick off auto-init */2134 err = hw_auto_init(hw);2135 if (err < 0)2136 return err;2137 2138 gctl = hw_read_20kx(hw, GLOBAL_CNTL_GCTL);2139 set_field(&gctl, GCTL_DBP, 1);2140 set_field(&gctl, GCTL_TBP, 1);2141 set_field(&gctl, GCTL_FBP, 1);2142 set_field(&gctl, GCTL_DPC, 0);2143 hw_write_20kx(hw, GLOBAL_CNTL_GCTL, gctl);2144 2145 /* Reset all global pending interrupts */2146 hw_write_20kx(hw, GIE, 0);2147 /* Reset all SRC pending interrupts */2148 hw_write_20kx(hw, SRC_IP, 0);2149 2150 if (hw->model != CTSB1270) {2151 /* TODO: detect the card ID and configure GPIO accordingly. */2152 /* Configures GPIO (0xD802 0x98028) */2153 /*hw_write_20kx(hw, GPIO_CTRL, 0x7F07);*/2154 /* Configures GPIO (SB0880) */2155 /*hw_write_20kx(hw, GPIO_CTRL, 0xFF07);*/2156 hw_write_20kx(hw, GPIO_CTRL, 0xD802);2157 } else {2158 hw_write_20kx(hw, GPIO_CTRL, 0x9E5F);2159 }2160 /* Enable audio ring */2161 hw_write_20kx(hw, MIXER_AR_ENABLE, 0x01);2162 2163 trn_info.vm_pgt_phys = info->vm_pgt_phys;2164 err = hw_trn_init(hw, &trn_info);2165 if (err < 0)2166 return err;2167 2168 daio_info.msr = info->msr;2169 err = hw_daio_init(hw, &daio_info);2170 if (err < 0)2171 return err;2172 2173 dac_info.msr = info->msr;2174 err = hw_dac_init(hw, &dac_info);2175 if (err < 0)2176 return err;2177 2178 adc_info.msr = info->msr;2179 adc_info.input = ADC_LINEIN;2180 adc_info.mic20db = 0;2181 err = hw_adc_init(hw, &adc_info);2182 if (err < 0)2183 return err;2184 2185 data = hw_read_20kx(hw, SRC_MCTL);2186 data |= 0x1; /* Enables input from the audio ring */2187 hw_write_20kx(hw, SRC_MCTL, data);2188 2189 return 0;2190}2191 2192#ifdef CONFIG_PM_SLEEP2193static int hw_suspend(struct hw *hw)2194{2195 hw_card_stop(hw);2196 return 0;2197}2198 2199static int hw_resume(struct hw *hw, struct card_conf *info)2200{2201 /* Re-initialize card hardware. */2202 return hw_card_init(hw, info);2203}2204#endif2205 2206static u32 hw_read_20kx(struct hw *hw, u32 reg)2207{2208 return readl(hw->mem_base + reg);2209}2210 2211static void hw_write_20kx(struct hw *hw, u32 reg, u32 data)2212{2213 writel(data, hw->mem_base + reg);2214}2215 2216static const struct hw ct20k2_preset = {2217 .irq = -1,2218 2219 .card_init = hw_card_init,2220 .card_stop = hw_card_stop,2221 .pll_init = hw_pll_init,2222 .is_adc_source_selected = hw_is_adc_input_selected,2223 .select_adc_source = hw_adc_input_select,2224 .capabilities = hw_capabilities,2225 .output_switch_get = hw_output_switch_get,2226 .output_switch_put = hw_output_switch_put,2227 .mic_source_switch_get = hw_mic_source_switch_get,2228 .mic_source_switch_put = hw_mic_source_switch_put,2229#ifdef CONFIG_PM_SLEEP2230 .suspend = hw_suspend,2231 .resume = hw_resume,2232#endif2233 2234 .src_rsc_get_ctrl_blk = src_get_rsc_ctrl_blk,2235 .src_rsc_put_ctrl_blk = src_put_rsc_ctrl_blk,2236 .src_mgr_get_ctrl_blk = src_mgr_get_ctrl_blk,2237 .src_mgr_put_ctrl_blk = src_mgr_put_ctrl_blk,2238 .src_set_state = src_set_state,2239 .src_set_bm = src_set_bm,2240 .src_set_rsr = src_set_rsr,2241 .src_set_sf = src_set_sf,2242 .src_set_wr = src_set_wr,2243 .src_set_pm = src_set_pm,2244 .src_set_rom = src_set_rom,2245 .src_set_vo = src_set_vo,2246 .src_set_st = src_set_st,2247 .src_set_ie = src_set_ie,2248 .src_set_ilsz = src_set_ilsz,2249 .src_set_bp = src_set_bp,2250 .src_set_cisz = src_set_cisz,2251 .src_set_ca = src_set_ca,2252 .src_set_sa = src_set_sa,2253 .src_set_la = src_set_la,2254 .src_set_pitch = src_set_pitch,2255 .src_set_dirty = src_set_dirty,2256 .src_set_clear_zbufs = src_set_clear_zbufs,2257 .src_set_dirty_all = src_set_dirty_all,2258 .src_commit_write = src_commit_write,2259 .src_get_ca = src_get_ca,2260 .src_get_dirty = src_get_dirty,2261 .src_dirty_conj_mask = src_dirty_conj_mask,2262 .src_mgr_enbs_src = src_mgr_enbs_src,2263 .src_mgr_enb_src = src_mgr_enb_src,2264 .src_mgr_dsb_src = src_mgr_dsb_src,2265 .src_mgr_commit_write = src_mgr_commit_write,2266 2267 .srcimp_mgr_get_ctrl_blk = srcimp_mgr_get_ctrl_blk,2268 .srcimp_mgr_put_ctrl_blk = srcimp_mgr_put_ctrl_blk,2269 .srcimp_mgr_set_imaparc = srcimp_mgr_set_imaparc,2270 .srcimp_mgr_set_imapuser = srcimp_mgr_set_imapuser,2271 .srcimp_mgr_set_imapnxt = srcimp_mgr_set_imapnxt,2272 .srcimp_mgr_set_imapaddr = srcimp_mgr_set_imapaddr,2273 .srcimp_mgr_commit_write = srcimp_mgr_commit_write,2274 2275 .amixer_rsc_get_ctrl_blk = amixer_rsc_get_ctrl_blk,2276 .amixer_rsc_put_ctrl_blk = amixer_rsc_put_ctrl_blk,2277 .amixer_mgr_get_ctrl_blk = amixer_mgr_get_ctrl_blk,2278 .amixer_mgr_put_ctrl_blk = amixer_mgr_put_ctrl_blk,2279 .amixer_set_mode = amixer_set_mode,2280 .amixer_set_iv = amixer_set_iv,2281 .amixer_set_x = amixer_set_x,2282 .amixer_set_y = amixer_set_y,2283 .amixer_set_sadr = amixer_set_sadr,2284 .amixer_set_se = amixer_set_se,2285 .amixer_set_dirty = amixer_set_dirty,2286 .amixer_set_dirty_all = amixer_set_dirty_all,2287 .amixer_commit_write = amixer_commit_write,2288 .amixer_get_y = amixer_get_y,2289 .amixer_get_dirty = amixer_get_dirty,2290 2291 .dai_get_ctrl_blk = dai_get_ctrl_blk,2292 .dai_put_ctrl_blk = dai_put_ctrl_blk,2293 .dai_srt_set_srco = dai_srt_set_srco,2294 .dai_srt_set_srcm = dai_srt_set_srcm,2295 .dai_srt_set_rsr = dai_srt_set_rsr,2296 .dai_srt_set_drat = dai_srt_set_drat,2297 .dai_srt_set_ec = dai_srt_set_ec,2298 .dai_srt_set_et = dai_srt_set_et,2299 .dai_commit_write = dai_commit_write,2300 2301 .dao_get_ctrl_blk = dao_get_ctrl_blk,2302 .dao_put_ctrl_blk = dao_put_ctrl_blk,2303 .dao_set_spos = dao_set_spos,2304 .dao_commit_write = dao_commit_write,2305 .dao_get_spos = dao_get_spos,2306 2307 .daio_mgr_get_ctrl_blk = daio_mgr_get_ctrl_blk,2308 .daio_mgr_put_ctrl_blk = daio_mgr_put_ctrl_blk,2309 .daio_mgr_enb_dai = daio_mgr_enb_dai,2310 .daio_mgr_dsb_dai = daio_mgr_dsb_dai,2311 .daio_mgr_enb_dao = daio_mgr_enb_dao,2312 .daio_mgr_dsb_dao = daio_mgr_dsb_dao,2313 .daio_mgr_dao_init = daio_mgr_dao_init,2314 .daio_mgr_set_imaparc = daio_mgr_set_imaparc,2315 .daio_mgr_set_imapnxt = daio_mgr_set_imapnxt,2316 .daio_mgr_set_imapaddr = daio_mgr_set_imapaddr,2317 .daio_mgr_commit_write = daio_mgr_commit_write,2318 2319 .set_timer_irq = set_timer_irq,2320 .set_timer_tick = set_timer_tick,2321 .get_wc = get_wc,2322};2323 2324int create_20k2_hw_obj(struct hw **rhw)2325{2326 struct hw20k2 *hw20k2;2327 2328 *rhw = NULL;2329 hw20k2 = kzalloc(sizeof(*hw20k2), GFP_KERNEL);2330 if (!hw20k2)2331 return -ENOMEM;2332 2333 hw20k2->hw = ct20k2_preset;2334 *rhw = &hw20k2->hw;2335 2336 return 0;2337}2338 2339int destroy_20k2_hw_obj(struct hw *hw)2340{2341 if (hw->io_base)2342 hw_card_shutdown(hw);2343 2344 kfree(hw);2345 return 0;2346}2347