brintos

brintos / linux-shallow public Read only

0
0
Text · 51.3 KiB · 55af8ef Raw
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